2006-04-13 20:47:06 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
2010-05-25 10:56:00 +00:00
|
|
|
Copyright (C) 2010 EDuke32 developers and contributors
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2010-05-25 10:56:00 +00:00
|
|
|
This file is part of EDuke32.
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
EDuke32 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
|
2014-07-20 08:55:56 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2006-04-13 20:47:06 +00:00
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
2016-01-08 01:33:35 +00:00
|
|
|
#define sector_c_
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
#include "duke3d.h"
|
2012-06-03 16:11:22 +00:00
|
|
|
#include "input.h"
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
// PRIMITIVE
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
static int g_haltSoundHack = 0;
|
2007-01-30 09:03:51 +00:00
|
|
|
|
2017-01-01 13:23:29 +00:00
|
|
|
int S_FindMusicSFX(int sectNum, int *sndptr)
|
2014-05-23 20:25:29 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t SPRITES_OF_SECT(sectNum, spriteNum))
|
2014-05-23 20:25:29 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
const int32_t snd = sprite[spriteNum].lotag;
|
2014-05-23 20:25:29 +00:00
|
|
|
EDUKE32_STATIC_ASSERT(MAXSOUNDS >= 1000);
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (PN(spriteNum) == MUSICANDSFX && (unsigned)snd < 1000) // XXX: in other places, 999
|
2014-05-23 20:25:29 +00:00
|
|
|
{
|
|
|
|
*sndptr = snd;
|
2016-08-27 01:42:01 +00:00
|
|
|
return spriteNum;
|
2014-05-23 20:25:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*sndptr = -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
// this function activates a sector's MUSICANDSFX sprite
|
2016-08-27 01:42:01 +00:00
|
|
|
int A_CallSound(int sectNum, int spriteNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2009-01-10 07:38:50 +00:00
|
|
|
if (g_haltSoundHack)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2009-01-10 07:38:50 +00:00
|
|
|
g_haltSoundHack = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2012-05-29 20:01:48 +00:00
|
|
|
|
2017-01-01 13:23:29 +00:00
|
|
|
int soundNum;
|
2016-08-27 01:42:01 +00:00
|
|
|
int const SFXsprite = S_FindMusicSFX(sectNum, &soundNum);
|
2014-05-23 20:25:29 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (SFXsprite >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (spriteNum == -1)
|
|
|
|
spriteNum = SFXsprite;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (T1(SFXsprite) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((g_sounds[soundNum].m & SF_GLOBAL) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (soundNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
A_PlaySound(soundNum, spriteNum);
|
|
|
|
|
|
|
|
if (SHT(SFXsprite) && soundNum != SHT(SFXsprite) && SHT(SFXsprite) < MAXSOUNDS)
|
|
|
|
S_StopEnvSound(SHT(SFXsprite),T6(SFXsprite));
|
|
|
|
|
|
|
|
T6(SFXsprite) = spriteNum;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((sector[SECT(SFXsprite)].lotag&0xff) != ST_22_SPLITTING_DOOR)
|
|
|
|
T1(SFXsprite) = 1;
|
2014-05-23 20:25:29 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
else if (SHT(SFXsprite) < MAXSOUNDS)
|
2014-05-23 20:25:29 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (SHT(SFXsprite))
|
|
|
|
A_PlaySound(SHT(SFXsprite), spriteNum);
|
|
|
|
|
|
|
|
if ((g_sounds[soundNum].m & SF_LOOP) || (SHT(SFXsprite) && SHT(SFXsprite) != soundNum))
|
|
|
|
S_StopEnvSound(soundNum, T6(SFXsprite));
|
|
|
|
|
|
|
|
T6(SFXsprite) = spriteNum;
|
|
|
|
T1(SFXsprite) = 0;
|
2014-05-23 20:25:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
return soundNum;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int G_CheckActivatorMotion(int lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int spriteNum = headspritestat[STAT_ACTIVATOR];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
while (spriteNum >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (sprite[spriteNum].lotag == lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
spritetype *const pSprite = &sprite[spriteNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t j = g_animateCnt - 1; j >= 0; j--)
|
|
|
|
if (pSprite->sectnum == g_animateSect[j])
|
2016-06-21 00:34:41 +00:00
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int sectorEffector = headspritestat[STAT_EFFECTOR];
|
|
|
|
|
|
|
|
while (sectorEffector >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (pSprite->sectnum == sprite[sectorEffector].sectnum)
|
|
|
|
{
|
|
|
|
switch (sprite[sectorEffector].lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
case SE_11_SWINGING_DOOR:
|
|
|
|
case SE_30_TWO_WAY_TRAIN:
|
|
|
|
if (actor[sectorEffector].t_data[4])
|
|
|
|
return 1;
|
|
|
|
break;
|
|
|
|
case SE_20_STRETCH_BRIDGE:
|
|
|
|
case SE_31_FLOOR_RISE_FALL:
|
|
|
|
case SE_32_CEILING_RISE_FALL:
|
|
|
|
case SE_18_INCREMENTAL_SECTOR_RISE_FALL:
|
|
|
|
if (actor[sectorEffector].t_data[0])
|
|
|
|
return 1;
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
sectorEffector = nextspritestat[sectorEffector];
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
spriteNum = nextspritestat[spriteNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-06-21 00:34:41 +00:00
|
|
|
return 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-04-04 21:06:07 +00:00
|
|
|
int CheckDoorTile(int tileNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(tileNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
case DOORTILE1__STATIC:
|
|
|
|
case DOORTILE2__STATIC:
|
|
|
|
case DOORTILE3__STATIC:
|
|
|
|
case DOORTILE4__STATIC:
|
|
|
|
case DOORTILE5__STATIC:
|
|
|
|
case DOORTILE6__STATIC:
|
|
|
|
case DOORTILE7__STATIC:
|
|
|
|
case DOORTILE8__STATIC:
|
|
|
|
case DOORTILE9__STATIC:
|
|
|
|
case DOORTILE10__STATIC:
|
|
|
|
case DOORTILE11__STATIC:
|
|
|
|
case DOORTILE12__STATIC:
|
|
|
|
case DOORTILE14__STATIC:
|
|
|
|
case DOORTILE15__STATIC:
|
|
|
|
case DOORTILE16__STATIC:
|
|
|
|
case DOORTILE17__STATIC:
|
|
|
|
case DOORTILE18__STATIC:
|
|
|
|
case DOORTILE19__STATIC:
|
|
|
|
case DOORTILE20__STATIC:
|
|
|
|
case DOORTILE21__STATIC:
|
|
|
|
case DOORTILE22__STATIC:
|
|
|
|
case DOORTILE23__STATIC:
|
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2018-04-04 21:06:07 +00:00
|
|
|
#else
|
|
|
|
UNREFERENCED_PARAMETER(tileNum);
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int isanunderoperator(int lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (lotag & 0xff)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
case ST_15_WARP_ELEVATOR:
|
|
|
|
case ST_16_PLATFORM_DOWN:
|
|
|
|
case ST_17_PLATFORM_UP:
|
|
|
|
case ST_18_ELEVATOR_DOWN:
|
|
|
|
case ST_19_ELEVATOR_UP:
|
|
|
|
case ST_22_SPLITTING_DOOR:
|
|
|
|
case ST_26_SPLITTING_ST_DOOR:
|
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int isanearoperator(int lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (lotag & 0xff)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
case ST_9_SLIDING_ST_DOOR:
|
|
|
|
case ST_15_WARP_ELEVATOR:
|
|
|
|
case ST_16_PLATFORM_DOWN:
|
|
|
|
case ST_17_PLATFORM_UP:
|
|
|
|
case ST_18_ELEVATOR_DOWN:
|
|
|
|
case ST_19_ELEVATOR_UP:
|
|
|
|
case ST_20_CEILING_DOOR:
|
|
|
|
case ST_21_FLOOR_DOOR:
|
|
|
|
case ST_22_SPLITTING_DOOR:
|
|
|
|
case ST_23_SWINGING_DOOR:
|
|
|
|
case ST_25_SLIDING_DOOR:
|
|
|
|
case ST_26_SPLITTING_ST_DOOR:
|
|
|
|
case ST_29_TEETH_DOOR:
|
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
static inline int32_t A_FP_ManhattanDist(const DukePlayer_t *pPlayer, const spritetype *pSprite)
|
2012-09-02 14:04:16 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
return klabs(pPlayer->opos.x - pSprite->x)
|
|
|
|
+ klabs(pPlayer->opos.y - pSprite->y)
|
|
|
|
+ ((klabs(pPlayer->opos.z - pSprite->z + (28 << 8))) >> 4);
|
2012-09-02 14:04:16 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int __fastcall A_FindPlayer(const spritetype *pSprite, int32_t *dist)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-10-14 22:16:07 +00:00
|
|
|
if (!g_netServer && ud.multimode < 2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
DukePlayer_t *const pPlayer = g_player[myconnectindex].ps;
|
|
|
|
|
|
|
|
if (dist)
|
|
|
|
*dist = A_FP_ManhattanDist(pPlayer, pSprite);
|
2013-04-15 10:48:09 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
return myconnectindex;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int closestPlayer = 0;
|
|
|
|
int32_t closestPlayerDist = INT32_MAX;
|
|
|
|
|
|
|
|
for (bssize_t TRAVERSE_CONNECT(j))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
DukePlayer_t *const pPlayer = g_player[j].ps;
|
|
|
|
int32_t playerDist = A_FP_ManhattanDist(pPlayer, pSprite);
|
2009-01-02 01:03:41 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (playerDist < closestPlayerDist && sprite[pPlayer->i].extra > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
closestPlayer = j;
|
|
|
|
closestPlayerDist = playerDist;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2009-01-02 01:03:41 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
|
|
|
|
if (dist)
|
|
|
|
*dist = closestPlayerDist;
|
|
|
|
|
|
|
|
return closestPlayer;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
void G_DoSectorAnimations(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t animNum=g_animateCnt-1; animNum>=0; animNum--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int animPos = *g_animatePtr[animNum];
|
|
|
|
int const animVel = g_animateVel[animNum] * TICSPERFRAME;
|
|
|
|
int const animSect = g_animateSect[animNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (animPos == g_animateGoal[animNum])
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
G_StopInterpolation(g_animatePtr[animNum]);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2008-09-28 11:00:59 +00:00
|
|
|
// This fixes a bug where wall or floor sprites contained in
|
|
|
|
// elevator sectors (ST 16-19) would jitter vertically after the
|
|
|
|
// elevator had stopped.
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_animatePtr[animNum] == §or[g_animateSect[animNum]].floorz)
|
|
|
|
{
|
|
|
|
for (bssize_t j=headspritesect[animSect]; j>=0; j=nextspritesect[j])
|
|
|
|
{
|
2011-08-18 22:01:01 +00:00
|
|
|
if (sprite[j].statnum != STAT_EFFECTOR)
|
2012-12-23 14:00:08 +00:00
|
|
|
actor[j].bpos.z = sprite[j].z;
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_animateCnt--;
|
2008-09-26 09:48:35 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
g_animatePtr[animNum] = g_animatePtr[g_animateCnt];
|
|
|
|
g_animateGoal[animNum] = g_animateGoal[g_animateCnt];
|
|
|
|
g_animateVel[animNum] = g_animateVel[g_animateCnt];
|
|
|
|
g_animateSect[animNum] = g_animateSect[g_animateCnt];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if ((sector[g_animateSect[animNum]].lotag == ST_18_ELEVATOR_DOWN || sector[g_animateSect[animNum]].lotag == ST_19_ELEVATOR_UP)
|
|
|
|
&& (g_animatePtr[animNum] == §or[g_animateSect[animNum]].ceilingz))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((sector[animSect].lotag&0xff) != ST_22_SPLITTING_DOOR)
|
|
|
|
A_CallSound(animSect,-1);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
animPos = (animVel > 0) ? min(animPos + animVel, g_animateGoal[animNum])
|
|
|
|
: max(animPos + animVel, g_animateGoal[animNum]);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_animatePtr[animNum] == §or[g_animateSect[animNum]].floorz)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t TRAVERSE_CONNECT(playerNum))
|
|
|
|
{
|
|
|
|
if ((g_player[playerNum].ps->cursectnum == animSect)
|
|
|
|
&& ((sector[animSect].floorz - g_player[playerNum].ps->pos.z) < (64 << 8))
|
|
|
|
&& (sprite[g_player[playerNum].ps->i].owner >= 0))
|
|
|
|
{
|
|
|
|
g_player[playerNum].ps->pos.z += animVel;
|
|
|
|
g_player[playerNum].ps->vel.z = 0;
|
|
|
|
/*
|
|
|
|
if (p == myconnectindex)
|
|
|
|
{
|
|
|
|
my.z += v;
|
|
|
|
myvel.z = 0;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t j=headspritesect[animSect]; j>=0; j=nextspritesect[j])
|
|
|
|
{
|
2012-10-14 20:41:21 +00:00
|
|
|
if (sprite[j].statnum != STAT_EFFECTOR)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-12-23 14:00:08 +00:00
|
|
|
actor[j].bpos.z = sprite[j].z;
|
2016-08-27 01:42:01 +00:00
|
|
|
sprite[j].z += animVel;
|
|
|
|
actor[j].floorz = sector[animSect].floorz+animVel;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
*g_animatePtr[animNum] = animPos;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int GetAnimationGoal(const int32_t *animPtr)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t i = 0; i < g_animateCnt; i++)
|
|
|
|
if (animPtr == g_animatePtr[i])
|
2010-07-26 22:36:45 +00:00
|
|
|
return i;
|
|
|
|
return -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int SetAnimation(int sectNum, int32_t *animPtr, int goalVal, int animVel)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_animateCnt >= MAXANIMATES)
|
2014-01-31 21:12:55 +00:00
|
|
|
return -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int animNum = g_animateCnt;
|
|
|
|
|
|
|
|
for (bssize_t i = 0; i < g_animateCnt; i++)
|
|
|
|
{
|
|
|
|
if (animPtr == g_animatePtr[i])
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
animNum = i;
|
2006-04-13 20:47:06 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
g_animateSect[animNum] = sectNum;
|
|
|
|
g_animatePtr[animNum] = animPtr;
|
|
|
|
g_animateGoal[animNum] = goalVal;
|
|
|
|
g_animateVel[animNum] = (goalVal >= *animPtr) ? animVel : -animVel;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (animNum == g_animateCnt)
|
|
|
|
g_animateCnt++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
G_SetInterpolation(animPtr);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
return animNum;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
static void G_SetupCamTile(int spriteNum, int tileNum, int smoothRatio)
|
2014-10-25 03:35:21 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
vec3_t const camera = G_GetCameraPosition(spriteNum, smoothRatio);
|
|
|
|
int const saveMirror = display_mirror;
|
2014-12-27 17:17:52 +00:00
|
|
|
|
2014-10-25 03:35:21 +00:00
|
|
|
//if (waloff[wn] == 0) loadtile(wn);
|
2018-04-12 21:03:47 +00:00
|
|
|
renderSetTarget(tileNum, tilesiz[tileNum].y, tilesiz[tileNum].x);
|
2014-10-25 03:35:21 +00:00
|
|
|
|
|
|
|
yax_preparedrawrooms();
|
2016-08-27 01:42:01 +00:00
|
|
|
drawrooms(camera.x, camera.y, camera.z, SA(spriteNum), 100 + sprite[spriteNum].shade, SECT(spriteNum));
|
|
|
|
yax_drawrooms(G_DoSpriteAnimations, SECT(spriteNum), 0, smoothRatio);
|
2014-10-25 03:35:21 +00:00
|
|
|
|
|
|
|
display_mirror = 3;
|
2016-08-27 01:42:01 +00:00
|
|
|
G_DoSpriteAnimations(camera.x, camera.y, SA(spriteNum), smoothRatio);
|
|
|
|
display_mirror = saveMirror;
|
2018-04-12 21:03:47 +00:00
|
|
|
renderDrawMasks();
|
2014-10-25 03:35:21 +00:00
|
|
|
|
2018-04-12 21:03:47 +00:00
|
|
|
renderRestoreTarget();
|
2016-08-27 01:42:01 +00:00
|
|
|
squarerotatetile(tileNum);
|
2018-04-12 21:03:47 +00:00
|
|
|
tileInvalidate(tileNum, -1, 255);
|
2014-10-25 03:35:21 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
void G_AnimateCamSprite(int smoothRatio)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-02-12 13:47:33 +00:00
|
|
|
#ifdef DEBUG_VALGRIND_NO_SMC
|
|
|
|
return;
|
|
|
|
#endif
|
2016-08-27 01:42:01 +00:00
|
|
|
|
2013-12-26 19:45:12 +00:00
|
|
|
if (g_curViewscreen < 0)
|
2012-05-26 21:58:21 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int const spriteNum = g_curViewscreen;
|
|
|
|
|
|
|
|
if (totalclock >= T1(spriteNum) + ud.camera_time)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
DukePlayer_t const *const pPlayer = g_player[screenpeek].ps;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (pPlayer->newowner >= 0)
|
|
|
|
OW(spriteNum) = pPlayer->newowner;
|
2014-10-25 03:35:21 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (OW(spriteNum) >= 0 && dist(&sprite[pPlayer->i], &sprite[spriteNum]) < VIEWSCREEN_ACTIVE_DISTANCE)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const viewscrShift = G_GetViewscreenSizeShift((const uspritetype *)&sprite[spriteNum]);
|
|
|
|
int const viewscrTile = TILE_VIEWSCR - viewscrShift;
|
2015-07-25 17:23:22 +00:00
|
|
|
|
|
|
|
if (waloff[viewscrTile] == 0)
|
2018-04-12 21:03:30 +00:00
|
|
|
tileCreate(viewscrTile, tilesiz[PN(spriteNum)].x << viewscrShift, tilesiz[PN(spriteNum)].y << viewscrShift);
|
2013-12-26 19:45:12 +00:00
|
|
|
else
|
2015-07-25 17:23:22 +00:00
|
|
|
walock[viewscrTile] = 255;
|
2013-12-26 19:45:12 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
G_SetupCamTile(OW(spriteNum), viewscrTile, smoothRatio);
|
2011-09-15 17:03:08 +00:00
|
|
|
#ifdef POLYMER
|
2014-02-08 14:37:52 +00:00
|
|
|
// Force texture update on viewscreen sprite in Polymer!
|
2018-04-12 21:03:12 +00:00
|
|
|
if (videoGetRenderMode() == REND_POLYMER)
|
2016-08-27 01:42:01 +00:00
|
|
|
polymer_invalidatesprite(spriteNum);
|
2011-09-15 17:03:08 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-04-17 20:00:24 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
T1(spriteNum) = totalclock;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
void G_AnimateWalls(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t animwallNum = g_animWallCnt-1; animwallNum>=0; animwallNum--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const wallNum = animwall[animwallNum].wallnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
switch (DYNAMICTILEMAP(wall[wallNum].picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-16 03:02:42 +00:00
|
|
|
case SCREENBREAK1__STATIC:
|
|
|
|
case SCREENBREAK2__STATIC:
|
|
|
|
case SCREENBREAK3__STATIC:
|
|
|
|
case SCREENBREAK4__STATIC:
|
|
|
|
case SCREENBREAK5__STATIC:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case SCREENBREAK9__STATIC:
|
|
|
|
case SCREENBREAK10__STATIC:
|
|
|
|
case SCREENBREAK11__STATIC:
|
|
|
|
case SCREENBREAK12__STATIC:
|
|
|
|
case SCREENBREAK13__STATIC:
|
|
|
|
case SCREENBREAK14__STATIC:
|
|
|
|
case SCREENBREAK15__STATIC:
|
|
|
|
case SCREENBREAK16__STATIC:
|
|
|
|
case SCREENBREAK17__STATIC:
|
|
|
|
case SCREENBREAK18__STATIC:
|
|
|
|
case SCREENBREAK19__STATIC:
|
2008-11-20 14:06:36 +00:00
|
|
|
if ((krand()&255) < 16)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
animwall[animwallNum].tag = wall[wallNum].picnum;
|
2016-08-27 01:41:46 +00:00
|
|
|
wall[wallNum].picnum = SCREENBREAK6;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case SCREENBREAK6__STATIC:
|
|
|
|
case SCREENBREAK7__STATIC:
|
|
|
|
case SCREENBREAK8__STATIC:
|
2016-08-27 01:42:01 +00:00
|
|
|
if (animwall[animwallNum].tag >= 0 && wall[wallNum].extra != FEMPIC2 && wall[wallNum].extra != FEMPIC3)
|
|
|
|
wall[wallNum].picnum = animwall[animwallNum].tag;
|
2006-11-16 03:02:42 +00:00
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:41:46 +00:00
|
|
|
wall[wallNum].picnum++;
|
|
|
|
if (wall[wallNum].picnum == (SCREENBREAK6+3))
|
|
|
|
wall[wallNum].picnum = SCREENBREAK6;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
continue;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
if ((wall[wallNum].cstat&16) && G_GetForcefieldPicnum(wallNum)==W_FORCEFIELD)
|
2013-12-26 19:45:14 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const wallTag = animwall[animwallNum].tag;
|
2013-12-26 19:45:14 +00:00
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
if (wall[wallNum].cstat&254)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:46 +00:00
|
|
|
wall[wallNum].xpanning -= wallTag>>10; // sintable[(t+512)&2047]>>12;
|
|
|
|
wall[wallNum].ypanning -= wallTag>>10; // sintable[t&2047]>>12;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
if (wall[wallNum].extra == 1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:46 +00:00
|
|
|
wall[wallNum].extra = 0;
|
2016-08-27 01:42:01 +00:00
|
|
|
animwall[animwallNum].tag = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
else animwall[animwallNum].tag += 128;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (animwall[animwallNum].tag < (128 << 4))
|
2013-12-26 19:45:14 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
wall[wallNum].overpicnum = (animwall[animwallNum].tag & 128) ? W_FORCEFIELD : W_FORCEFIELD + 1;
|
2013-12-26 19:45:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((krand()&255) < 32)
|
2016-08-27 01:42:01 +00:00
|
|
|
animwall[animwallNum].tag = 128<<(krand()&3);
|
2016-08-27 01:41:46 +00:00
|
|
|
else wall[wallNum].overpicnum = W_FORCEFIELD+1;
|
2013-12-26 19:45:14 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2013-12-26 19:45:14 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int G_ActivateWarpElevators(int spriteNum, int warpDir)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
bssize_t i;
|
|
|
|
int const sectNum = sprite[spriteNum].sectnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:42:01 +00:00
|
|
|
if (SLT(i) == SE_17_WARP_ELEVATOR && SHT(i) == sprite[spriteNum].hitag)
|
2014-01-31 21:12:56 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (klabs(sector[sectNum].floorz - actor[spriteNum].t_data[2]) > SP(i) ||
|
|
|
|
sector[SECT(i)].hitag == sector[sectNum].hitag - warpDir)
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
break;
|
2014-01-31 21:12:56 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
if (i == -1)
|
2006-04-13 20:47:06 +00:00
|
|
|
return 1; // No find
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
A_PlaySound(warpDir ? ELEVATOR_ON : ELEVATOR_OFF, spriteNum);
|
2014-01-31 21:12:56 +00:00
|
|
|
|
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:42:01 +00:00
|
|
|
if (SLT(i) == SE_17_WARP_ELEVATOR && SHT(i) == sprite[spriteNum].hitag)
|
|
|
|
T1(i) = T2(i) = warpDir; //Make all check warp
|
Patch from Hendricks266 and whatever changes happened to be in my tree. I hope they work ;)
"The most noticeable change is the addition of the "includedefault" CON and DEF command, which will attempt to include eduke.con (or nam.con, or ww2gi.con), then game.con, or duke3d.def, or nam.def, or ww2gi.def. This is useful for TCs like my add-ons, where for my pseudo-mutators I currently say "include EDUKE.CON", but I also have to juggle this terrible order of paths, so that I can have an EDUKE.CON file in my HRP which says "include GAME.CON" to allow the mainline game to actually run, but also allow DukePlus to load its EDUKE.CON file (since it uses that and not an -x switch), and also allow any custom EDUKE.CON files in the root to be used."
git-svn-id: https://svn.eduke32.com/eduke32@1909 1a8010ca-5511-0410-912e-c29ae57300e0
2011-06-19 00:11:52 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
void G_OperateSectors(int sectNum, int spriteNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int32_t j=0;
|
2009-01-09 09:29:17 +00:00
|
|
|
int32_t i;
|
2016-08-27 01:40:35 +00:00
|
|
|
sectortype *const pSector = §or[sectNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
switch (pSector->lotag & (uint16_t)~49152u)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_30_ROTATE_RISE_BRIDGE:
|
2016-08-27 01:40:35 +00:00
|
|
|
j = sector[sectNum].hitag;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
|
|
|
if (E_SpriteIsValid(j))
|
|
|
|
{
|
|
|
|
if (actor[j].tempang == 0 || actor[j].tempang == 256)
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum,spriteNum);
|
2014-01-31 21:12:56 +00:00
|
|
|
sprite[j].extra = (sprite[j].extra == 1) ? 3 : 1;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_31_TWO_WAY_TRAIN:
|
2016-08-27 01:40:35 +00:00
|
|
|
j = sector[sectNum].hitag;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
if (E_SpriteIsValid(j))
|
|
|
|
{
|
|
|
|
if (actor[j].t_data[4] == 0)
|
|
|
|
actor[j].t_data[4] = 1;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum,spriteNum);
|
2014-01-31 21:12:56 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-11-13 23:12:47 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_26_SPLITTING_ST_DOOR: //The split doors
|
2016-08-27 01:40:06 +00:00
|
|
|
if (GetAnimationGoal(&pSector->ceilingz) == -1) //if the door has stopped
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2009-01-10 07:38:50 +00:00
|
|
|
g_haltSoundHack = 1;
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag &= 0xFF00u;
|
2016-08-27 01:40:06 +00:00
|
|
|
pSector->lotag |= ST_22_SPLITTING_DOOR;
|
2016-08-27 01:40:35 +00:00
|
|
|
G_OperateSectors(sectNum,spriteNum);
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag &= 0xFF00u;
|
2016-08-27 01:40:06 +00:00
|
|
|
pSector->lotag |= ST_9_SLIDING_ST_DOOR;
|
2016-08-27 01:40:35 +00:00
|
|
|
G_OperateSectors(sectNum,spriteNum);
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag &= 0xFF00u;
|
2016-08-27 01:40:06 +00:00
|
|
|
pSector->lotag |= ST_26_SPLITTING_ST_DOOR;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
2012-09-08 22:18:44 +00:00
|
|
|
case ST_9_SLIDING_ST_DOOR:
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const startWall = pSector->wallptr;
|
|
|
|
int const endWall = startWall + pSector->wallnum - 1;
|
|
|
|
int const doorSpeed = pSector->extra >> 4;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
//first find center point by averaging all points
|
2016-08-27 01:40:06 +00:00
|
|
|
|
|
|
|
vec2_t vect = { 0, 0 };
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
for (i = startWall; i <= endWall; i++)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
vect.x += wall[i].x;
|
|
|
|
vect.y += wall[i].y;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2014-10-25 03:29:21 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
vect.x = tabledivide32_noinline(vect.x, (endWall-startWall+1));
|
|
|
|
vect.y = tabledivide32_noinline(vect.y, (endWall-startWall+1));
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
//find any points with either same x or same y coordinate
|
|
|
|
// as center (dax, day) - should be 2 points found.
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int wallfind[2] = { -1, -1 };
|
|
|
|
|
|
|
|
for (i = startWall; i <= endWall; i++)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
if (wall[i].x == vect.x || wall[i].y == vect.y)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-16 03:02:42 +00:00
|
|
|
if (wallfind[0] == -1)
|
|
|
|
wallfind[0] = i;
|
2016-08-27 01:40:06 +00:00
|
|
|
else
|
|
|
|
wallfind[1] = i;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2013-12-20 18:31:24 +00:00
|
|
|
if (wallfind[1] == -1)
|
|
|
|
return;
|
|
|
|
|
2009-02-19 16:47:54 +00:00
|
|
|
for (j=0; j<2; j++)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const foundWall = wallfind[j];
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
i = foundWall - 1;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (i < startWall)
|
|
|
|
i = endWall;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
vec2_t vect2 = { ((wall[i].x + wall[wall[foundWall].point2].x) >> 1) - wall[foundWall].x,
|
|
|
|
((wall[i].y + wall[wall[foundWall].point2].y) >> 1) - wall[foundWall].y };
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (wall[foundWall].x == vect.x && wall[foundWall].y == vect.y)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
|
|
|
//find what direction door should open by averaging the
|
|
|
|
// 2 neighboring points of wallfind[0] & wallfind[1].
|
2016-08-27 01:40:06 +00:00
|
|
|
if (vect2.x != 0)
|
2006-11-13 23:12:47 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
vect2.x = wall[wall[wall[foundWall].point2].point2].x;
|
|
|
|
vect2.x -= wall[wall[foundWall].point2].x;
|
|
|
|
SetAnimation(sectNum, &wall[foundWall].x, wall[foundWall].x + vect2.x, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[i].x, wall[i].x + vect2.x, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[wall[foundWall].point2].x, wall[wall[foundWall].point2].x + vect2.x, doorSpeed);
|
|
|
|
A_CallSound(sectNum, spriteNum);
|
2006-11-13 23:12:47 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (vect2.y != 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
vect2.y = wall[wall[wall[foundWall].point2].point2].y;
|
|
|
|
vect2.y -= wall[wall[foundWall].point2].y;
|
|
|
|
SetAnimation(sectNum, &wall[foundWall].y, wall[foundWall].y + vect2.y, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[i].y, wall[i].y + vect2.y, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[wall[foundWall].point2].y, wall[wall[foundWall].point2].y + vect2.y, doorSpeed);
|
|
|
|
A_CallSound(sectNum, spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (vect2.x != 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
SetAnimation(sectNum, &wall[foundWall].x, vect.x, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[i].x, vect.x + vect2.x, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[wall[foundWall].point2].x, vect.x + vect2.x, doorSpeed);
|
|
|
|
A_CallSound(sectNum, spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (vect2.y != 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
SetAnimation(sectNum, &wall[foundWall].y, vect.y, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[i].y, vect.y + vect2.y, doorSpeed);
|
|
|
|
SetAnimation(sectNum, &wall[wall[foundWall].point2].y, vect.y + vect2.y, doorSpeed);
|
|
|
|
A_CallSound(sectNum, spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_15_WARP_ELEVATOR://Warping elevators
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].picnum != APLAYER)
|
2014-01-31 21:12:55 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
for (SPRITES_OF_SECT(sectNum, i))
|
|
|
|
if (PN(i)==SECTOREFFECTOR && SLT(i) == SE_17_WARP_ELEVATOR)
|
2014-01-31 21:12:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (i < 0)
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].sectnum == sectNum)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2008-11-20 14:06:36 +00:00
|
|
|
if (G_ActivateWarpElevators(i,-1))
|
|
|
|
G_ActivateWarpElevators(i,1);
|
|
|
|
else if (G_ActivateWarpElevators(i,1))
|
|
|
|
G_ActivateWarpElevators(i,-1);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pSector->floorz > SZ(i))
|
2008-11-20 14:06:36 +00:00
|
|
|
G_ActivateWarpElevators(i,-1);
|
2006-11-16 03:02:42 +00:00
|
|
|
else
|
2008-11-20 14:06:36 +00:00
|
|
|
G_ActivateWarpElevators(i,1);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-08 22:18:44 +00:00
|
|
|
case ST_16_PLATFORM_DOWN:
|
|
|
|
case ST_17_PLATFORM_UP:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
i = GetAnimationGoal(&pSector->floorz);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
if (i == -1)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
i = nextsectorneighborz(sectNum,pSector->floorz,1,1);
|
2006-11-14 21:35:50 +00:00
|
|
|
if (i == -1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
i = nextsectorneighborz(sectNum,pSector->floorz,1,-1);
|
2006-11-16 03:02:42 +00:00
|
|
|
if (i == -1) return;
|
|
|
|
j = sector[i].floorz;
|
2016-08-27 01:40:35 +00:00
|
|
|
SetAnimation(sectNum,&pSector->floorz,j,pSector->extra);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
j = sector[i].floorz;
|
2016-08-27 01:40:35 +00:00
|
|
|
SetAnimation(sectNum,&pSector->floorz,j,pSector->extra);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-08 22:18:44 +00:00
|
|
|
case ST_18_ELEVATOR_DOWN:
|
|
|
|
case ST_19_ELEVATOR_UP:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
i = GetAnimationGoal(&pSector->floorz);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
if (i==-1)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
i = nextsectorneighborz(sectNum, pSector->floorz, 1, -1);
|
2016-08-27 01:40:06 +00:00
|
|
|
|
|
|
|
if (i == -1)
|
2016-08-27 01:40:35 +00:00
|
|
|
i = nextsectorneighborz(sectNum, pSector->floorz, 1, 1);
|
2016-08-27 01:40:06 +00:00
|
|
|
|
|
|
|
if (i == -1)
|
|
|
|
return;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
j = sector[i].floorz;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int const sectorExtra = pSector->extra;
|
|
|
|
int const zDiff = pSector->ceilingz - pSector->floorz;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
SetAnimation(sectNum, &pSector->floorz, j, sectorExtra);
|
|
|
|
SetAnimation(sectNum, &pSector->ceilingz, j + zDiff, sectorExtra);
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum, spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_29_TEETH_DOOR:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SLT(i) == SE_22_TEETH_DOOR && SHT(i) == pSector->hitag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
sector[SECT(i)].extra = -sector[SECT(i)].extra;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
T1(i) = sectNum;
|
|
|
|
T2(i) = 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum, spriteNum);
|
2010-06-07 09:03:16 +00:00
|
|
|
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag ^= 0x8000u;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
if (pSector->lotag & 0x8000u)
|
2010-06-07 09:03:16 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
j = nextsectorneighborz(sectNum,pSector->ceilingz,-1,-1);
|
|
|
|
if (j == -1) j = nextsectorneighborz(sectNum,pSector->ceilingz,1,1);
|
2010-06-07 09:03:16 +00:00
|
|
|
if (j == -1)
|
|
|
|
{
|
|
|
|
OSD_Printf("WARNING: ST29: null sector!\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
j = sector[j].ceilingz;
|
|
|
|
}
|
|
|
|
else
|
2010-08-02 08:13:51 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
j = nextsectorneighborz(sectNum,pSector->ceilingz,1,1);
|
|
|
|
if (j == -1) j = nextsectorneighborz(sectNum,pSector->ceilingz,-1,-1);
|
2010-06-07 09:03:16 +00:00
|
|
|
if (j == -1)
|
|
|
|
{
|
|
|
|
OSD_Printf("WARNING: ST29: null sector!\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
j = sector[j].floorz;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
SetAnimation(sectNum,&pSector->ceilingz,j,pSector->extra);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_20_CEILING_DOOR:
|
2006-04-13 20:47:06 +00:00
|
|
|
REDODOOR:
|
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
if (pSector->lotag & 0x8000u)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
for (SPRITES_OF_SECT(sectNum, i))
|
|
|
|
if (sprite[i].statnum == STAT_EFFECTOR && SLT(i)==SE_9_DOWN_OPEN_DOOR_LIGHTS)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
j = SZ(i);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
if (i==-1)
|
2016-08-27 01:40:06 +00:00
|
|
|
j = pSector->floorz;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
j = nextsectorneighborz(sectNum,pSector->ceilingz,-1,-1);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
|
|
|
if (j >= 0) j = sector[j].ceilingz;
|
2006-04-13 20:47:06 +00:00
|
|
|
else
|
|
|
|
{
|
2018-01-28 04:30:34 +00:00
|
|
|
pSector->lotag |= 32768u;
|
2006-11-16 03:02:42 +00:00
|
|
|
goto REDODOOR;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag ^= 0x8000u;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
SetAnimation(sectNum,&pSector->ceilingz,j,pSector->extra);
|
|
|
|
A_CallSound(sectNum,spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_21_FLOOR_DOOR:
|
2016-08-27 01:40:06 +00:00
|
|
|
i = GetAnimationGoal(&pSector->floorz);
|
2006-11-16 03:02:42 +00:00
|
|
|
if (i >= 0)
|
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (g_animateGoal[sectNum] == pSector->ceilingz)
|
|
|
|
g_animateGoal[i] = sector[nextsectorneighborz(sectNum,pSector->ceilingz,1,1)].floorz;
|
|
|
|
else g_animateGoal[i] = pSector->ceilingz;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pSector->ceilingz == pSector->floorz)
|
2016-08-27 01:40:35 +00:00
|
|
|
j = sector[nextsectorneighborz(sectNum,pSector->ceilingz,1,1)].floorz;
|
2016-08-27 01:40:06 +00:00
|
|
|
else j = pSector->ceilingz;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag ^= 0x8000u;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SetAnimation(sectNum,&pSector->floorz,j,pSector->extra) >= 0)
|
|
|
|
A_CallSound(sectNum,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_22_SPLITTING_DOOR:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
if (pSector->lotag & 0x8000u)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const q = (pSector->ceilingz + pSector->floorz) >> 1;
|
2018-10-16 06:09:42 +00:00
|
|
|
SetAnimation(sectNum, &pSector->floorz, q, pSector->extra);
|
|
|
|
SetAnimation(sectNum, &pSector->ceilingz, q, pSector->extra);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const floorNeighbor = nextsectorneighborz(sectNum, pSector->floorz, 1, 1);
|
|
|
|
int const ceilingNeighbor = nextsectorneighborz(sectNum, pSector->ceilingz, -1, -1);
|
2010-12-17 14:22:15 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (floorNeighbor>=0 && ceilingNeighbor>=0)
|
2010-12-17 14:22:15 +00:00
|
|
|
{
|
2018-10-16 06:09:42 +00:00
|
|
|
SetAnimation(sectNum, &pSector->floorz, sector[floorNeighbor].floorz, pSector->extra);
|
|
|
|
SetAnimation(sectNum, &pSector->ceilingz, sector[ceilingNeighbor].ceilingz, pSector->extra);
|
2010-12-17 14:22:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-05-17 05:46:52 +00:00
|
|
|
OSD_Printf("WARNING: ST_22_SPLITTING_DOOR: null sector: floor neighbor=%d, ceiling neighbor=%d!\n",
|
2016-08-27 01:42:01 +00:00
|
|
|
floorNeighbor, ceilingNeighbor);
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag ^= 0x8000u;
|
2010-12-17 14:22:15 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-01-28 04:30:38 +00:00
|
|
|
pSector->lotag ^= 0x8000u;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum,spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-08 22:18:44 +00:00
|
|
|
case ST_23_SWINGING_DOOR: //Swingdoor
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
j = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SLT(i) == SE_11_SWINGING_DOOR && SECT(i) == sectNum && !T5(i))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
j = i;
|
|
|
|
break;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (i < 0)
|
|
|
|
return;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
uint16_t const tag = sector[SECT(i)].lotag & 0x8000u;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (j >= 0)
|
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int soundPlayed = 0;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:42:01 +00:00
|
|
|
{
|
2018-01-28 04:30:42 +00:00
|
|
|
if (tag == (sector[SECT(i)].lotag & 0x8000u) && SLT(i) == SE_11_SWINGING_DOOR && sprite[j].hitag == SHT(i) && !T5(i))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2018-01-28 04:30:42 +00:00
|
|
|
if (sector[SECT(i)].lotag & 0x8000u) sector[SECT(i)].lotag &= 0x7fff;
|
2018-01-28 04:30:38 +00:00
|
|
|
else sector[SECT(i)].lotag |= 0x8000u;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
T5(i) = 1;
|
|
|
|
T4(i) = -T4(i);
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (!soundPlayed)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum, i);
|
2016-08-27 01:42:01 +00:00
|
|
|
soundPlayed = 1;
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-08 22:18:44 +00:00
|
|
|
case ST_25_SLIDING_DOOR: //Subway type sliding doors
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, j))
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[j].lotag == SE_15_SLIDING_DOOR && sprite[j].sectnum == sectNum)
|
2006-11-16 03:02:42 +00:00
|
|
|
break; //Found the sectoreffector.
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
if (j < 0)
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SHT(i)==sprite[j].hitag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SLT(i) == SE_15_SLIDING_DOOR)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-01-28 04:30:38 +00:00
|
|
|
sector[SECT(i)].lotag ^= 0x8000u; // Toggle the open or close
|
2016-08-27 01:40:35 +00:00
|
|
|
SA(i) += 1024;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (T5(i))
|
|
|
|
A_CallSound(SECT(i),i);
|
|
|
|
A_CallSound(SECT(i),i);
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
T5(i) = (sector[SECT(i)].lotag & 0x8000u) ? 1 : 2;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-09-08 22:18:44 +00:00
|
|
|
case ST_27_STRETCH_BRIDGE: //Extended bridge
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
for (SPRITES_OF(STAT_EFFECTOR, j))
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((sprite[j].lotag&0xff)==SE_20_STRETCH_BRIDGE && sprite[j].sectnum == sectNum) //Bridge
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-01-28 04:30:38 +00:00
|
|
|
sector[sectNum].lotag ^= 0x8000u;
|
2014-01-31 21:12:56 +00:00
|
|
|
// Highest bit now set means we're opening.
|
|
|
|
|
2018-01-28 04:30:42 +00:00
|
|
|
actor[j].t_data[0] = (sector[sectNum].lotag & 0x8000u) ? 1 : 2;
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2014-01-31 21:12:56 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-26 22:16:08 +00:00
|
|
|
case ST_28_DROP_FLOOR:
|
2006-11-16 03:02:42 +00:00
|
|
|
//activate the rest of them
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
for (SPRITES_OF_SECT(sectNum, j))
|
2012-08-26 22:16:08 +00:00
|
|
|
if (sprite[j].statnum==STAT_EFFECTOR && (sprite[j].lotag&0xff)==SE_21_DROP_FLOOR)
|
2014-01-31 21:12:56 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-02-21 19:32:55 +00:00
|
|
|
if (j >= 0) // PK: The matching SE21 might have gone, see SE_21_KILLIT in actors.c
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2012-02-21 19:32:55 +00:00
|
|
|
j = sprite[j].hitag;
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, l))
|
2012-02-21 19:32:55 +00:00
|
|
|
{
|
2012-08-26 22:16:08 +00:00
|
|
|
if ((sprite[l].lotag&0xff)==SE_21_DROP_FLOOR && !actor[l].t_data[0] &&
|
2014-01-31 21:12:56 +00:00
|
|
|
sprite[l].hitag == j)
|
2012-02-21 19:32:55 +00:00
|
|
|
actor[l].t_data[0] = 1;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CallSound(sectNum,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
void G_OperateRespawns(int lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t nextSprite, SPRITES_OF_STAT_SAFE(STAT_FX, spriteNum, nextSprite))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
spritetype * const pSprite = &sprite[spriteNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (pSprite->lotag == lotag && pSprite->picnum == RESPAWN)
|
2014-01-29 18:32:51 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (!ud.monsters_off || !A_CheckEnemyTile(pSprite->hitag))
|
2014-01-29 18:32:51 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int const j = A_Spawn(spriteNum, TRANSPORTERSTAR);
|
2016-08-27 01:40:56 +00:00
|
|
|
sprite[j].z -= ZOFFSET5;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2014-01-29 18:32:51 +00:00
|
|
|
// Just a way to killit (see G_MoveFX(): RESPAWN__STATIC)
|
2016-08-27 01:42:01 +00:00
|
|
|
pSprite->extra = 66-12;
|
2014-01-29 18:32:51 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
void G_OperateActivators(int lotag, int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t spriteNum=g_cyclerCnt-1; spriteNum>=0; spriteNum--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int16_t *const pCycler = &g_cyclers[spriteNum][0];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
if (pCycler[4] == lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
pCycler[5] = !pCycler[5];
|
|
|
|
sector[pCycler[0]].floorshade = pCycler[3];
|
|
|
|
sector[pCycler[0]].ceilingshade = pCycler[3];
|
|
|
|
walltype *pWall = &wall[sector[pCycler[0]].wallptr];
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bsize_t j = sector[pCycler[0]].wallnum; j > 0; j--, pWall++)
|
2016-08-27 01:41:46 +00:00
|
|
|
pWall->shade = pCycler[3];
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int soundPlayed = -1;
|
2009-08-28 23:08:00 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t nextSprite, SPRITES_OF_STAT_SAFE(STAT_ACTIVATOR, spriteNum, nextSprite))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (sprite[spriteNum].lotag == lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (sprite[spriteNum].picnum == ACTIVATORLOCKED)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
sector[SECT(spriteNum)].lotag ^= 16384;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (playerNum >= 0 && playerNum < ud.multimode)
|
2016-08-27 01:42:01 +00:00
|
|
|
P_DoQuote((sector[SECT(spriteNum)].lotag & 16384) ? QUOTE_LOCKED : QUOTE_UNLOCKED, g_player[playerNum].ps);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (SHT(spriteNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
case 1:
|
2016-08-27 01:42:01 +00:00
|
|
|
if (sector[SECT(spriteNum)].floorz != sector[SECT(spriteNum)].ceilingz)
|
2016-08-27 01:40:06 +00:00
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
case 2:
|
2016-08-27 01:42:01 +00:00
|
|
|
if (sector[SECT(spriteNum)].floorz == sector[SECT(spriteNum)].ceilingz)
|
2016-08-27 01:40:06 +00:00
|
|
|
continue;
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2012-10-14 20:41:21 +00:00
|
|
|
// ST_2_UNDERWATER
|
2016-08-27 01:42:01 +00:00
|
|
|
if (sector[sprite[spriteNum].sectnum].lotag < 3)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t SPRITES_OF_SECT(sprite[spriteNum].sectnum, foundSprite))
|
|
|
|
{
|
|
|
|
if (sprite[foundSprite].statnum == STAT_EFFECTOR)
|
|
|
|
{
|
|
|
|
switch (sprite[foundSprite].lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
case SE_36_PROJ_SHOOTER:
|
|
|
|
case SE_31_FLOOR_RISE_FALL:
|
|
|
|
case SE_32_CEILING_RISE_FALL:
|
|
|
|
case SE_18_INCREMENTAL_SECTOR_RISE_FALL:
|
2016-08-27 01:42:01 +00:00
|
|
|
actor[foundSprite].t_data[0] = 1 - actor[foundSprite].t_data[0];
|
|
|
|
A_CallSound(SECT(spriteNum), foundSprite);
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (soundPlayed == -1 && (sector[SECT(spriteNum)].lotag&0xff) == ST_22_SPLITTING_DOOR)
|
|
|
|
soundPlayed = A_CallSound(SECT(spriteNum),spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
G_OperateSectors(SECT(spriteNum),spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
G_OperateRespawns(lotag);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
void G_OperateMasterSwitches(int lotag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_STANDABLE, i))
|
2016-08-27 01:41:46 +00:00
|
|
|
if (PN(i) == MASTERSWITCH && SLT(i) == lotag && SP(i) == 0)
|
2016-08-27 01:40:35 +00:00
|
|
|
SP(i) = 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
void G_OperateForceFields(int spriteNum, int wallTag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t animwallNum = 0; animwallNum < g_animWallCnt; ++animwallNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int const wallNum = animwall[animwallNum].wallnum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
if ((wallTag == wall[wallNum].lotag || wallTag == -1)
|
|
|
|
&& (G_GetForcefieldPicnum(wallNum) == W_FORCEFIELD || (wall[wallNum].overpicnum == BIGFORCE)))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
animwall[animwallNum].tag = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (wall[wallNum].cstat)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
wall[wallNum].cstat = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (spriteNum >= 0 && sprite[spriteNum].picnum == SECTOREFFECTOR && sprite[spriteNum].lotag == SE_30_TWO_WAY_TRAIN)
|
|
|
|
wall[wallNum].lotag = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
wall[wallNum].cstat = FORCEFIELD_CSTAT;
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-31 21:12:58 +00:00
|
|
|
// List of switches that function like dip (combination lock) switches.
|
2016-08-27 01:40:35 +00:00
|
|
|
#define DIPSWITCH_LIKE_CASES \
|
|
|
|
DIPSWITCH__STATIC: \
|
|
|
|
case TECHSWITCH__STATIC: \
|
2014-01-31 21:12:58 +00:00
|
|
|
case ALIENSWITCH__STATIC
|
|
|
|
|
|
|
|
// List of access switches.
|
2016-08-27 01:40:35 +00:00
|
|
|
#define ACCESSSWITCH_CASES \
|
|
|
|
ACCESSSWITCH__STATIC: \
|
2014-01-31 21:12:58 +00:00
|
|
|
case ACCESSSWITCH2__STATIC
|
|
|
|
|
|
|
|
// List of switches that don't fit the two preceding categories, and are not
|
|
|
|
// the MULTISWITCH. 13 cases.
|
2016-08-27 01:40:35 +00:00
|
|
|
#define REST_SWITCH_CASES \
|
|
|
|
DIPSWITCH2__STATIC: \
|
|
|
|
case DIPSWITCH3__STATIC: \
|
|
|
|
case FRANKENSTINESWITCH__STATIC: \
|
|
|
|
case HANDSWITCH__STATIC: \
|
|
|
|
case LIGHTSWITCH2__STATIC: \
|
|
|
|
case LIGHTSWITCH__STATIC: \
|
|
|
|
case LOCKSWITCH1__STATIC: \
|
|
|
|
case POWERSWITCH1__STATIC: \
|
|
|
|
case POWERSWITCH2__STATIC: \
|
|
|
|
case PULLSWITCH__STATIC: \
|
|
|
|
case SLOTDOOR__STATIC: \
|
|
|
|
case SPACEDOORSWITCH__STATIC: \
|
2014-01-31 21:12:58 +00:00
|
|
|
case SPACELIGHTSWITCH__STATIC
|
|
|
|
|
|
|
|
// Returns:
|
|
|
|
// 0: is not a dipswitch-like switch
|
|
|
|
// 1: is one, off
|
|
|
|
// 2: is one, on
|
2016-08-27 01:40:35 +00:00
|
|
|
static int G_IsLikeDipswitch(int switchPic)
|
2014-01-31 21:12:58 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i=0; i<2; i++)
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchPic == DIPSWITCH+i || switchPic == TECHSWITCH+i || switchPic == ALIENSWITCH+i)
|
2014-01-31 21:12:58 +00:00
|
|
|
return 1+i;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get base (unpressed) tile number for switch.
|
2016-08-27 01:40:35 +00:00
|
|
|
static int G_GetBaseSwitch(int switchPic)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchPic > MULTISWITCH && switchPic <= MULTISWITCH+3)
|
2014-01-31 21:12:58 +00:00
|
|
|
return MULTISWITCH;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return (switchPic == DIPSWITCH + 1 || switchPic == DIPSWITCH2 + 1 || switchPic == DIPSWITCH3 + 1 ||
|
|
|
|
switchPic == TECHSWITCH + 1 || switchPic == ALIENSWITCH + 1 || switchPic == PULLSWITCH + 1 ||
|
|
|
|
switchPic == HANDSWITCH + 1 || switchPic == SLOTDOOR + 1 || switchPic == SPACEDOORSWITCH + 1 ||
|
|
|
|
switchPic == SPACELIGHTSWITCH + 1 || switchPic == LIGHTSWITCH + 1 || switchPic == LIGHTSWITCH2 + 1 ||
|
|
|
|
switchPic == FRANKENSTINESWITCH + 1 || switchPic == POWERSWITCH1 + 1 || switchPic == POWERSWITCH2 + 1 ||
|
|
|
|
switchPic == LOCKSWITCH1 + 1) ?
|
|
|
|
switchPic-1 : switchPic;
|
2014-01-31 21:12:58 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
enum { SWITCH_WALL, SWITCH_SPRITE };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int P_ActivateSwitch(int playerNum, int wallOrSprite, int switchType)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (wallOrSprite < 0)
|
2014-01-31 21:12:58 +00:00
|
|
|
return 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
vec3_t davector;
|
2018-01-15 23:13:50 +00:00
|
|
|
int16_t lotag, hitag;
|
|
|
|
int16_t nSwitchPicnum;
|
|
|
|
uint8_t nSwitchPal;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchType == SWITCH_SPRITE) // A wall sprite
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-23 04:32:23 +00:00
|
|
|
if (actor[wallOrSprite].lasttransport == (totalclock & UINT8_MAX))
|
2014-01-31 21:12:58 +00:00
|
|
|
return 0;
|
|
|
|
|
2017-06-23 04:32:23 +00:00
|
|
|
actor[wallOrSprite].lasttransport = (totalclock & UINT8_MAX);
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[wallOrSprite].lotag == 0)
|
2014-01-31 21:12:58 +00:00
|
|
|
return 0;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
lotag = sprite[wallOrSprite].lotag;
|
|
|
|
hitag = sprite[wallOrSprite].hitag;
|
|
|
|
davector = *(vec3_t *)&sprite[wallOrSprite];
|
|
|
|
nSwitchPicnum = sprite[wallOrSprite].picnum;
|
|
|
|
nSwitchPal = sprite[wallOrSprite].pal;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (wall[wallOrSprite].lotag == 0)
|
2014-01-31 21:12:58 +00:00
|
|
|
return 0;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
lotag = wall[wallOrSprite].lotag;
|
|
|
|
hitag = wall[wallOrSprite].hitag;
|
|
|
|
davector = *(vec3_t *)&wall[wallOrSprite];
|
|
|
|
davector.z = g_player[playerNum].ps->pos.z;
|
|
|
|
nSwitchPicnum = wall[wallOrSprite].picnum;
|
|
|
|
nSwitchPal = wall[wallOrSprite].pal;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
// initprintf("P_ActivateSwitch called picnum=%i switchissprite=%i\n",picnum,switchissprite);
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int basePicnum = G_GetBaseSwitch(nSwitchPicnum);
|
|
|
|
int correctDips = 1;
|
|
|
|
int numDips = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(basePicnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2014-01-31 21:12:58 +00:00
|
|
|
case DIPSWITCH_LIKE_CASES:
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
|
|
|
case ACCESSSWITCH_CASES:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (g_player[playerNum].ps->access_incs == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
static const int32_t key_switchpal[3] = { 0, 21, 23 };
|
|
|
|
static const int32_t need_key_quote[3] = { QUOTE_NEED_BLUE_KEY, QUOTE_NEED_RED_KEY, QUOTE_NEED_YELLOW_KEY };
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t nKeyPal = 0; nKeyPal < 3; nKeyPal++)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
if (nSwitchPal == key_switchpal[nKeyPal])
|
2014-01-31 21:12:58 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (g_player[playerNum].ps->got_access & (1 << nKeyPal))
|
|
|
|
g_player[playerNum].ps->access_incs = 1;
|
2014-01-31 21:12:58 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
P_DoQuote(need_key_quote[nKeyPal], g_player[playerNum].ps);
|
2014-01-31 21:12:58 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (g_player[playerNum].ps->access_incs == 1)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchType == SWITCH_WALL)
|
|
|
|
g_player[playerNum].ps->access_wallnum = wallOrSprite;
|
2006-11-16 03:02:42 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
g_player[playerNum].ps->access_spritenum = wallOrSprite;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2006-11-16 03:02:42 +00:00
|
|
|
case MULTISWITCH__STATIC:
|
2014-01-31 21:12:58 +00:00
|
|
|
case REST_SWITCH_CASES:
|
|
|
|
if (G_CheckActivatorMotion(lotag))
|
|
|
|
return 0;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
default:
|
2016-08-27 01:40:06 +00:00
|
|
|
if (CheckDoorTile(nSwitchPicnum) == 0)
|
2014-01-31 21:12:58 +00:00
|
|
|
return 0;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_DEFAULT, spriteNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (lotag == SLT(spriteNum))
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2014-01-31 21:12:58 +00:00
|
|
|
// Put the tile number into a variable so later switches don't
|
|
|
|
// trigger on the result of changes:
|
2016-08-27 01:42:01 +00:00
|
|
|
int const spritePic = PN(spriteNum);
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (spritePic >= MULTISWITCH && spritePic <= MULTISWITCH+3)
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[spriteNum].picnum++;
|
|
|
|
if (sprite[spriteNum].picnum > MULTISWITCH+3)
|
|
|
|
sprite[spriteNum].picnum = MULTISWITCH;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(spritePic))
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2014-01-31 21:12:58 +00:00
|
|
|
case DIPSWITCH_LIKE_CASES:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchType == SWITCH_SPRITE && wallOrSprite == spriteNum)
|
|
|
|
PN(spriteNum)++;
|
|
|
|
else if (SHT(spriteNum) == 0)
|
2016-08-27 01:42:01 +00:00
|
|
|
correctDips++;
|
|
|
|
numDips++;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
|
|
|
case ACCESSSWITCH_CASES:
|
|
|
|
case REST_SWITCH_CASES:
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[spriteNum].picnum++;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
default:
|
2016-08-27 01:42:01 +00:00
|
|
|
if (spritePic <= 0) // oob safety
|
2011-12-11 13:26:39 +00:00
|
|
|
break;
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(spritePic - 1))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
case DIPSWITCH_LIKE_CASES:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchType == SWITCH_SPRITE && wallOrSprite == spriteNum)
|
|
|
|
PN(spriteNum)--;
|
|
|
|
else if (SHT(spriteNum) == 1)
|
2016-08-27 01:42:01 +00:00
|
|
|
correctDips++;
|
|
|
|
numDips++;
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case REST_SWITCH_CASES:
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[spriteNum].picnum--;
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
for (bssize_t wallNum=numwalls-1; wallNum>=0; wallNum--)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
if (lotag == wall[wallNum].lotag)
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
if (wall[wallNum].picnum >= MULTISWITCH && wall[wallNum].picnum <= MULTISWITCH+3)
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
wall[wallNum].picnum++;
|
|
|
|
if (wall[wallNum].picnum > MULTISWITCH+3)
|
|
|
|
wall[wallNum].picnum = MULTISWITCH;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2011-12-11 13:26:39 +00:00
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
switch (DYNAMICTILEMAP(wall[wallNum].picnum))
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2014-01-31 21:12:58 +00:00
|
|
|
case DIPSWITCH_LIKE_CASES:
|
2016-08-27 01:41:33 +00:00
|
|
|
if (switchType == SWITCH_WALL && wallNum == wallOrSprite)
|
|
|
|
wall[wallNum].picnum++;
|
|
|
|
else if (wall[wallNum].hitag == 0)
|
2016-08-27 01:42:01 +00:00
|
|
|
correctDips++;
|
|
|
|
numDips++;
|
2006-04-13 20:47:06 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case ACCESSSWITCH_CASES:
|
2014-01-31 21:12:58 +00:00
|
|
|
case REST_SWITCH_CASES:
|
2016-08-27 01:41:33 +00:00
|
|
|
wall[wallNum].picnum++;
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2016-08-27 01:41:33 +00:00
|
|
|
if (wall[wallNum].picnum <= 0) // oob safety
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
switch (DYNAMICTILEMAP(wall[wallNum].picnum - 1))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
case DIPSWITCH_LIKE_CASES:
|
2016-08-27 01:41:33 +00:00
|
|
|
if (switchType == SWITCH_WALL && wallNum == wallOrSprite)
|
|
|
|
wall[wallNum].picnum--;
|
|
|
|
else if (wall[wallNum].hitag == 1)
|
2016-08-27 01:42:01 +00:00
|
|
|
correctDips++;
|
|
|
|
numDips++;
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case REST_SWITCH_CASES:
|
2016-08-27 01:41:33 +00:00
|
|
|
wall[wallNum].picnum--;
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-15 23:13:50 +00:00
|
|
|
if ((uint16_t)lotag == UINT16_MAX)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2015-12-04 11:52:51 +00:00
|
|
|
P_EndLevel();
|
2014-01-31 21:12:55 +00:00
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
basePicnum = G_GetBaseSwitch(nSwitchPicnum);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(basePicnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
default:
|
|
|
|
if (CheckDoorTile(nSwitchPicnum) == 0)
|
|
|
|
break;
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2016-08-27 01:40:06 +00:00
|
|
|
case DIPSWITCH_LIKE_CASES:
|
|
|
|
if (G_IsLikeDipswitch(nSwitchPicnum))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
S_PlaySound3D((nSwitchPicnum == ALIENSWITCH || nSwitchPicnum == ALIENSWITCH + 1) ? ALIEN_SWITCH1 : SWITCH_ON,
|
2016-08-27 01:40:35 +00:00
|
|
|
(switchType == SWITCH_SPRITE) ? wallOrSprite : g_player[playerNum].ps->i, &davector);
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (numDips != correctDips)
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
S_PlaySound3D(END_OF_LEVEL_WARN, g_player[playerNum].ps->i, &davector);
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2016-08-27 01:40:06 +00:00
|
|
|
case ACCESSSWITCH_CASES:
|
|
|
|
case MULTISWITCH__STATIC:
|
|
|
|
case REST_SWITCH_CASES:
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (nSwitchPicnum >= MULTISWITCH && nSwitchPicnum <= MULTISWITCH + 3)
|
|
|
|
lotag += nSwitchPicnum - MULTISWITCH;
|
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, spriteNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].hitag == lotag)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
switch (sprite[spriteNum].lotag)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
case SE_12_LIGHT_SWITCH:
|
2016-08-27 01:40:35 +00:00
|
|
|
sector[sprite[spriteNum].sectnum].floorpal = 0;
|
|
|
|
actor[spriteNum].t_data[0]++;
|
|
|
|
if (actor[spriteNum].t_data[0] == 2)
|
|
|
|
actor[spriteNum].t_data[0]++;
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case SE_24_CONVEYOR:
|
|
|
|
case SE_34:
|
|
|
|
case SE_25_PISTON:
|
2016-08-27 01:40:35 +00:00
|
|
|
actor[spriteNum].t_data[4] = !actor[spriteNum].t_data[4];
|
|
|
|
P_DoQuote(actor[spriteNum].t_data[4] ? QUOTE_DEACTIVATED : QUOTE_ACTIVATED, g_player[playerNum].ps);
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case SE_21_DROP_FLOOR:
|
|
|
|
P_DoQuote(QUOTE_ACTIVATED, g_player[screenpeek].ps);
|
|
|
|
break;
|
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
G_OperateActivators(lotag, playerNum);
|
|
|
|
G_OperateForceFields(g_player[playerNum].ps->i, lotag);
|
2016-08-27 01:40:06 +00:00
|
|
|
G_OperateMasterSwitches(lotag);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (G_IsLikeDipswitch(nSwitchPicnum))
|
|
|
|
return 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (!hitag && CheckDoorTile(nSwitchPicnum) == 0)
|
2016-08-27 01:40:35 +00:00
|
|
|
S_PlaySound3D(SWITCH_ON, (switchType == SWITCH_SPRITE) ? wallOrSprite : g_player[playerNum].ps->i, &davector);
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (hitag)
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (switchType == SWITCH_SPRITE && (g_sounds[hitag].m & SF_TALK) == 0)
|
|
|
|
S_PlaySound3D(hitag, wallOrSprite, &davector);
|
2016-08-27 01:40:06 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(hitag, g_player[playerNum].ps->i);
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2014-01-31 21:12:58 +00:00
|
|
|
}
|
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
void G_ActivateBySector(int sectNum, int spriteNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int activatedSectors = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF_SECT(sectNum, i))
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PN(i) == ACTIVATOR)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
G_OperateActivators(SLT(i),-1);
|
2016-08-27 01:42:01 +00:00
|
|
|
++activatedSectors;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (!activatedSectors)
|
2016-08-27 01:40:35 +00:00
|
|
|
G_OperateSectors(sectNum, spriteNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:41:33 +00:00
|
|
|
static void G_BreakWall(int tileNum, int spriteNum, int wallNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:33 +00:00
|
|
|
wall[wallNum].picnum = tileNum;
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(VENT_BUST,spriteNum);
|
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnWallGlass(spriteNum,wallNum,10);
|
2018-06-09 20:36:31 +00:00
|
|
|
#else
|
|
|
|
UNREFERENCED_PARAMETER(spriteNum);
|
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-04-04 20:47:48 +00:00
|
|
|
void A_DamageWall_Internal(int spriteNum, int wallNum, const vec3_t *vPos, int weaponNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int16_t sectNum = -1;
|
2016-08-27 01:41:33 +00:00
|
|
|
walltype *pWall = &wall[wallNum];
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
if ((g_tile[pWall->overpicnum].flags & SFLAG_DAMAGEEVENT) || (g_tile[pWall->picnum].flags & SFLAG_DAMAGEEVENT))
|
|
|
|
{
|
|
|
|
if (VM_OnEventWithReturn(EVENT_DAMAGEWALL, spriteNum, -1, wallNum) < 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->overpicnum == MIRROR && pWall->pal != 4 &&
|
2016-08-27 01:40:35 +00:00
|
|
|
A_CheckSpriteFlags(spriteNum, SFLAG_PROJECTILE) &&
|
|
|
|
(SpriteProjectile[spriteNum].workslike & PROJECTILE_RPG))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->nextwall == -1 || wall[pWall->nextwall].pal != 4)
|
2008-10-11 09:20:04 +00:00
|
|
|
{
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnWallGlass(spriteNum, wallNum, 70);
|
2018-06-09 20:36:31 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK, spriteNum);
|
|
|
|
#endif
|
2016-08-27 01:40:06 +00:00
|
|
|
pWall->cstat &= ~16;
|
|
|
|
pWall->overpicnum = MIRRORBROKE;
|
2008-10-11 09:20:04 +00:00
|
|
|
return;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->overpicnum == MIRROR && pWall->pal != 4)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
switch (DYNAMICTILEMAP(weaponNum))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
|
|
|
case RADIUSEXPLOSION__STATIC:
|
2018-04-02 22:00:44 +00:00
|
|
|
case SEENINE__STATIC:
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
case HEAVYHBOMB__STATIC:
|
2016-08-27 01:40:06 +00:00
|
|
|
case RPG__STATIC:
|
|
|
|
case HYDRENT__STATIC:
|
|
|
|
case OOZFILTER__STATIC:
|
|
|
|
case EXPLODINGBARREL__STATIC:
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->nextwall == -1 || wall[pWall->nextwall].pal != 4)
|
|
|
|
{
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnWallGlass(spriteNum, wallNum, 70);
|
2018-06-09 20:36:31 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK, spriteNum);
|
|
|
|
#endif
|
2016-08-27 01:40:06 +00:00
|
|
|
pWall->cstat &= ~16;
|
|
|
|
pWall->overpicnum = MIRRORBROKE;
|
|
|
|
return;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if ((((pWall->cstat & 16) || pWall->overpicnum == BIGFORCE) && pWall->nextsector >= 0) &&
|
|
|
|
(sector[pWall->nextsector].floorz > vPos->z) &&
|
|
|
|
(sector[pWall->nextsector].floorz != sector[pWall->nextsector].ceilingz))
|
|
|
|
{
|
2016-08-27 01:41:46 +00:00
|
|
|
int const switchPic = G_GetForcefieldPicnum(wallNum);
|
2013-12-26 19:45:14 +00:00
|
|
|
|
2016-08-27 01:41:46 +00:00
|
|
|
switch (DYNAMICTILEMAP(switchPic))
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2018-04-04 20:47:48 +00:00
|
|
|
case FANSPRITE__STATIC:
|
|
|
|
pWall->overpicnum = FANSPRITEBROKE;
|
|
|
|
pWall->cstat &= 65535 - 65;
|
|
|
|
if (pWall->nextwall >= 0)
|
|
|
|
{
|
|
|
|
wall[pWall->nextwall].overpicnum = FANSPRITEBROKE;
|
|
|
|
wall[pWall->nextwall].cstat &= 65535 - 65;
|
|
|
|
}
|
|
|
|
A_PlaySound(VENT_BUST, spriteNum);
|
|
|
|
A_PlaySound(GLASS_BREAKING, spriteNum);
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_FORCEFIELD__STATIC:
|
|
|
|
pWall->extra = 1; // tell the forces to animate
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2016-08-27 01:40:06 +00:00
|
|
|
case BIGFORCE__STATIC:
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
updatesector(vPos->x, vPos->y, §Num);
|
|
|
|
if (sectNum < 0)
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int xRepeat = 32;
|
|
|
|
int yRepeat = 32;
|
2013-12-26 19:45:14 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (weaponNum == -1)
|
2016-08-27 01:42:01 +00:00
|
|
|
xRepeat = yRepeat = 8;
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (weaponNum == CHAINGUN)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
xRepeat = 16 + sprite[spriteNum].xrepeat;
|
|
|
|
yRepeat = 16 + sprite[spriteNum].yrepeat;
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2013-12-26 19:45:14 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int const i = A_InsertSprite(sectNum, vPos->x, vPos->y, vPos->z, FORCERIPPLE, -127, xRepeat, yRepeat, 0,
|
2016-08-27 01:40:35 +00:00
|
|
|
0, 0, spriteNum, 5);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
CS(i) |= 18 + 128;
|
|
|
|
SA(i) = getangle(pWall->x - wall[pWall->point2].x, pWall->y - wall[pWall->point2].y) - 512;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
A_PlaySound(SOMETHINGHITFORCE, i);
|
|
|
|
}
|
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case GLASS__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
updatesector(vPos->x, vPos->y, §Num);
|
|
|
|
if (sectNum < 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2016-08-27 01:40:06 +00:00
|
|
|
pWall->overpicnum = GLASS2;
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnWallGlass(spriteNum, wallNum, 10);
|
2016-08-27 01:40:06 +00:00
|
|
|
pWall->cstat = 0;
|
|
|
|
|
|
|
|
if (pWall->nextwall >= 0)
|
|
|
|
wall[pWall->nextwall].cstat = 0;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
{
|
|
|
|
int const i = A_InsertSprite(sectNum, vPos->x, vPos->y, vPos->z, SECTOREFFECTOR, 0, 0, 0,
|
2018-03-07 04:21:18 +00:00
|
|
|
fix16_to_int(g_player[0].ps->q16ang), 0, 0, spriteNum, 3);
|
2016-08-27 01:40:35 +00:00
|
|
|
SLT(i) = 128;
|
|
|
|
T2(i) = 5;
|
2016-08-27 01:41:33 +00:00
|
|
|
T3(i) = wallNum;
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_BREAKING, i);
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2013-12-26 19:45:14 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case STAINGLASS1__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
updatesector(vPos->x, vPos->y, §Num);
|
|
|
|
if (sectNum < 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnRandomGlass(spriteNum, wallNum, 80);
|
2016-08-27 01:40:06 +00:00
|
|
|
pWall->cstat = 0;
|
|
|
|
if (pWall->nextwall >= 0)
|
|
|
|
wall[pWall->nextwall].cstat = 0;
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(VENT_BUST, spriteNum);
|
|
|
|
A_PlaySound(GLASS_BREAKING, spriteNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2018-04-04 20:47:48 +00:00
|
|
|
#endif
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2017-06-23 09:16:33 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
switch (DYNAMICTILEMAP(pWall->picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
case COLAMACHINE__STATIC:
|
|
|
|
case VENDMACHINE__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(pWall->picnum + 2, spriteNum, wallNum);
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(VENT_BUST, spriteNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case OJ__STATIC:
|
|
|
|
case FEMPIC2__STATIC:
|
|
|
|
case FEMPIC3__STATIC:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case SCREENBREAK6__STATIC:
|
|
|
|
case SCREENBREAK7__STATIC:
|
|
|
|
case SCREENBREAK8__STATIC:
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case SCREENBREAK1__STATIC:
|
|
|
|
case SCREENBREAK2__STATIC:
|
|
|
|
case SCREENBREAK3__STATIC:
|
|
|
|
case SCREENBREAK4__STATIC:
|
|
|
|
case SCREENBREAK5__STATIC:
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case SCREENBREAK9__STATIC:
|
|
|
|
case SCREENBREAK10__STATIC:
|
|
|
|
case SCREENBREAK11__STATIC:
|
|
|
|
case SCREENBREAK12__STATIC:
|
|
|
|
case SCREENBREAK13__STATIC:
|
|
|
|
case SCREENBREAK14__STATIC:
|
|
|
|
case SCREENBREAK15__STATIC:
|
|
|
|
case SCREENBREAK16__STATIC:
|
|
|
|
case SCREENBREAK17__STATIC:
|
|
|
|
case SCREENBREAK18__STATIC:
|
|
|
|
case SCREENBREAK19__STATIC:
|
|
|
|
case BORNTOBEWILDSCREEN__STATIC:
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnWallGlass(spriteNum, wallNum, 30);
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK, spriteNum);
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
|
|
|
pWall->picnum = W_SCREENBREAK + (krand() % 3);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_TECHWALL5__STATIC:
|
|
|
|
case W_TECHWALL6__STATIC:
|
|
|
|
case W_TECHWALL7__STATIC:
|
|
|
|
case W_TECHWALL8__STATIC:
|
|
|
|
case W_TECHWALL9__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(pWall->picnum + 1, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_MILKSHELF__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_MILKSHELFBROKE, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_TECHWALL10__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL10, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_TECHWALL1__STATIC:
|
|
|
|
case W_TECHWALL11__STATIC:
|
|
|
|
case W_TECHWALL12__STATIC:
|
|
|
|
case W_TECHWALL13__STATIC:
|
|
|
|
case W_TECHWALL14__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL1, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_TECHWALL15__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL15, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_TECHWALL16__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL16, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case W_TECHWALL2__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL2, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case W_TECHWALL3__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL3, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case W_TECHWALL4__STATIC:
|
2016-08-27 01:41:33 +00:00
|
|
|
G_BreakWall(W_HITTECHWALL4, spriteNum, wallNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case ATM__STATIC:
|
|
|
|
pWall->picnum = ATMBROKE;
|
2016-08-27 01:40:35 +00:00
|
|
|
A_SpawnMultiple(spriteNum, MONEY, 1 + (krand() & 7));
|
|
|
|
A_PlaySound(GLASS_HEAVYBREAK, spriteNum);
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
case WALLLIGHT1__STATIC:
|
|
|
|
case WALLLIGHT2__STATIC:
|
|
|
|
case WALLLIGHT3__STATIC:
|
|
|
|
case WALLLIGHT4__STATIC:
|
|
|
|
case TECHLIGHT2__STATIC:
|
|
|
|
case TECHLIGHT4__STATIC:
|
|
|
|
{
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(rnd(128) ? GLASS_HEAVYBREAK : GLASS_BREAKING, spriteNum);
|
2016-08-27 01:41:33 +00:00
|
|
|
A_SpawnWallGlass(spriteNum, wallNum, 30);
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->picnum == WALLLIGHT1)
|
|
|
|
pWall->picnum = WALLLIGHTBUST1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->picnum == WALLLIGHT2)
|
|
|
|
pWall->picnum = WALLLIGHTBUST2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->picnum == WALLLIGHT3)
|
|
|
|
pWall->picnum = WALLLIGHTBUST3;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->picnum == WALLLIGHT4)
|
|
|
|
pWall->picnum = WALLLIGHTBUST4;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->picnum == TECHLIGHT2)
|
|
|
|
pWall->picnum = TECHLIGHTBUST2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->picnum == TECHLIGHT4)
|
|
|
|
pWall->picnum = TECHLIGHTBUST4;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pWall->lotag == 0)
|
|
|
|
return;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
sectNum = pWall->nextsector;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sectNum < 0)
|
2016-08-27 01:40:06 +00:00
|
|
|
return;
|
2013-12-12 19:22:16 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int darkestWall = 0;
|
2013-12-12 19:22:16 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pWall = &wall[sector[sectNum].wallptr];
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t i = sector[sectNum].wallnum; i > 0; i--, pWall++)
|
2016-08-27 01:42:01 +00:00
|
|
|
if (pWall->shade > darkestWall)
|
|
|
|
darkestWall = pWall->shade;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int const random = krand() & 1;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, i))
|
2016-08-27 01:41:33 +00:00
|
|
|
if (SHT(i) == wall[wallNum].lotag && SLT(i) == SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
T3(i) = random;
|
|
|
|
T4(i) = darkestWall;
|
2016-08-27 01:40:35 +00:00
|
|
|
T5(i) = 1;
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
void A_DamageWall(int spriteNum, int wallNum, const vec3_t *vPos, int weaponNum)
|
|
|
|
{
|
|
|
|
ud.returnvar[0] = -1;
|
|
|
|
A_DamageWall_Internal(spriteNum, wallNum, vPos, weaponNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sect_DamageFloor_Internal(int const spriteNum, int const sectNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-03-17 03:26:10 +00:00
|
|
|
int16_t tileNum = sector[sectNum].floorpicnum;
|
|
|
|
if (g_tile[tileNum].flags & SFLAG_DAMAGEEVENT)
|
|
|
|
{
|
|
|
|
if (VM_OnEventWithReturn(EVENT_DAMAGEFLOOR, spriteNum, -1, sectNum) < 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:44:14 +00:00
|
|
|
// NOTE: pass RETURN in the dist argument, too.
|
2018-03-17 03:26:10 +00:00
|
|
|
int const RETURN_in = 131072 + sectNum;
|
|
|
|
/* int32_t const returnValue = */ VM_OnEventWithBoth(EVENT_DAMAGEHPLANE, -1, -1, RETURN_in, RETURN_in);
|
2013-12-20 18:31:33 +00:00
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
#if 0
|
|
|
|
// No hard-coded floor damage effects.
|
2016-08-27 01:40:35 +00:00
|
|
|
if (returnValue < 0)
|
2018-03-17 03:26:10 +00:00
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
}
|
2013-12-20 18:31:33 +00:00
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
void Sect_DamageFloor(int const spriteNum, int const sectNum)
|
|
|
|
{
|
|
|
|
ud.returnvar[0] = -1;
|
|
|
|
Sect_DamageFloor_Internal(spriteNum, sectNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sect_DamageCeiling_Internal(int const spriteNum, int const sectNum)
|
|
|
|
{
|
|
|
|
int16_t tileNum = sector[sectNum].ceilingpicnum;
|
|
|
|
if (g_tile[tileNum].flags & SFLAG_DAMAGEEVENT)
|
|
|
|
{
|
|
|
|
if (VM_OnEventWithReturn(EVENT_DAMAGECEILING, spriteNum, -1, sectNum) < 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: pass RETURN in the dist argument, too.
|
|
|
|
int const RETURN_in = 65536 + sectNum;
|
|
|
|
int32_t const returnValue = VM_OnEventWithBoth(EVENT_DAMAGEHPLANE, -1, -1, RETURN_in, RETURN_in);
|
|
|
|
|
|
|
|
if (returnValue < 0)
|
|
|
|
return;
|
2016-12-26 06:01:18 +00:00
|
|
|
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-12-26 06:01:18 +00:00
|
|
|
int16_t * const pPicnum = §or[sectNum].ceilingpicnum;
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2013-12-20 18:31:29 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (returnValue == (1<<20))
|
2013-12-20 18:31:33 +00:00
|
|
|
{
|
|
|
|
// Execute the hard-coded stuff without changing picnum (expected to
|
|
|
|
// have been done by the event).
|
|
|
|
goto GLASSBREAK_CODE;
|
|
|
|
}
|
|
|
|
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:06 +00:00
|
|
|
switch (DYNAMICTILEMAP(*pPicnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-12-26 06:01:18 +00:00
|
|
|
case WALLLIGHT1__STATIC: *pPicnum = WALLLIGHTBUST1; goto GLASSBREAK_CODE;
|
|
|
|
case WALLLIGHT2__STATIC: *pPicnum = WALLLIGHTBUST2; goto GLASSBREAK_CODE;
|
|
|
|
case WALLLIGHT3__STATIC: *pPicnum = WALLLIGHTBUST3; goto GLASSBREAK_CODE;
|
|
|
|
case WALLLIGHT4__STATIC: *pPicnum = WALLLIGHTBUST4; goto GLASSBREAK_CODE;
|
|
|
|
case TECHLIGHT2__STATIC: *pPicnum = TECHLIGHTBUST2; goto GLASSBREAK_CODE;
|
|
|
|
case TECHLIGHT4__STATIC: *pPicnum = TECHLIGHTBUST4;
|
2018-04-02 22:00:44 +00:00
|
|
|
#else
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
#endif
|
2018-06-09 20:36:31 +00:00
|
|
|
GLASSBREAK_CODE:
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
2016-08-27 01:40:35 +00:00
|
|
|
A_SpawnCeilingGlass(g_player[myconnectindex].ps->i, sectNum, 10);
|
2016-08-27 01:40:06 +00:00
|
|
|
A_PlaySound(GLASS_BREAKING, g_player[screenpeek].ps->i);
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sector[sectNum].hitag == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF_SECT(sectNum, i))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PN(i) == SECTOREFFECTOR && SLT(i) == SE_12_LIGHT_SWITCH)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, j))
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[j].hitag == SHT(i))
|
2016-08-27 01:40:06 +00:00
|
|
|
actor[j].t_data[3] = 1;
|
|
|
|
break;
|
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
int j = krand() & 1;
|
2013-12-12 19:22:16 +00:00
|
|
|
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, i))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SHT(i) == sector[sectNum].hitag && SLT(i) == SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT)
|
2016-08-27 01:40:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
T3(i) = j;
|
|
|
|
T5(i) = 1;
|
2016-08-27 01:40:06 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2018-03-17 03:26:10 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
void Sect_DamageCeiling(int const spriteNum, int const sectNum)
|
|
|
|
{
|
|
|
|
ud.returnvar[0] = -1;
|
|
|
|
Sect_DamageCeiling_Internal(spriteNum, sectNum);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2008-11-20 14:06:36 +00:00
|
|
|
// hard coded props... :(
|
2018-03-17 03:26:10 +00:00
|
|
|
void A_DamageObject_Internal(int spriteNum, int const dmgSrc)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2012-12-12 02:53:13 +00:00
|
|
|
if (g_netClient)
|
|
|
|
return;
|
2017-06-23 09:16:33 +00:00
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
if (A_CheckSpriteFlags(spriteNum, SFLAG_DAMAGEEVENT))
|
|
|
|
{
|
|
|
|
if (VM_OnEventWithReturn(EVENT_DAMAGESPRITE, dmgSrc, -1, spriteNum) < 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-12-12 02:53:13 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
spriteNum &= (MAXSPRITES-1);
|
2018-04-02 22:00:44 +00:00
|
|
|
|
|
|
|
#ifndef EDUKE32_STANDALONE
|
|
|
|
int radiusDamage = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-23 09:16:33 +00:00
|
|
|
if (A_CheckSpriteFlags(dmgSrc,SFLAG_PROJECTILE))
|
|
|
|
if (SpriteProjectile[dmgSrc].workslike & PROJECTILE_RPG)
|
|
|
|
radiusDamage = 1;
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
switch (DYNAMICTILEMAP(PN(spriteNum)))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-04-04 20:47:48 +00:00
|
|
|
case GRATE1__STATIC:
|
|
|
|
PN(spriteNum) = BGRATE1;
|
|
|
|
CS(spriteNum) &= (65535-256-1);
|
|
|
|
A_PlaySound(VENT_BUST, spriteNum);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FANSPRITE__STATIC:
|
|
|
|
PN(spriteNum) = FANSPRITEBROKE;
|
|
|
|
CS(spriteNum) &= (65535-257);
|
|
|
|
if (sector[SECT(spriteNum)].floorpicnum == FANSHADOW)
|
|
|
|
sector[SECT(spriteNum)].floorpicnum = FANSHADOWBROKE;
|
|
|
|
|
2018-06-09 20:36:31 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2018-04-04 20:47:48 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK, spriteNum);
|
|
|
|
|
|
|
|
for (bssize_t j=16; j>0; j--)
|
|
|
|
{
|
|
|
|
spritetype * const pSprite = &sprite[spriteNum];
|
|
|
|
RANDOMSCRAP(pSprite, spriteNum);
|
|
|
|
}
|
2018-06-09 20:36:31 +00:00
|
|
|
#endif
|
2018-04-04 20:47:48 +00:00
|
|
|
break;
|
|
|
|
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2006-11-16 03:02:42 +00:00
|
|
|
case OCEANSPRITE1__STATIC:
|
|
|
|
case OCEANSPRITE2__STATIC:
|
|
|
|
case OCEANSPRITE3__STATIC:
|
|
|
|
case OCEANSPRITE4__STATIC:
|
|
|
|
case OCEANSPRITE5__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
A_Spawn(spriteNum,SMALLSMOKE);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case QUEBALL__STATIC:
|
|
|
|
case STRIPEBALL__STATIC:
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[dmgSrc].picnum == QUEBALL || sprite[dmgSrc].picnum == STRIPEBALL)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2017-06-23 09:16:33 +00:00
|
|
|
sprite[dmgSrc].xvel = (sprite[spriteNum].xvel>>1)+(sprite[spriteNum].xvel>>2);
|
|
|
|
sprite[dmgSrc].ang -= (SA(spriteNum)<<1)+1024;
|
|
|
|
SA(spriteNum) = getangle(SX(spriteNum)-sprite[dmgSrc].x,SY(spriteNum)-sprite[dmgSrc].y)-512;
|
2018-10-25 23:32:29 +00:00
|
|
|
if (g_sounds[POOLBALLHIT].num < 2)
|
|
|
|
A_PlaySound(POOLBALLHIT, spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-11-20 14:06:36 +00:00
|
|
|
if (krand()&3)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[spriteNum].xvel = 164;
|
2017-06-23 09:16:33 +00:00
|
|
|
sprite[spriteNum].ang = sprite[dmgSrc].ang;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_SpawnWallGlass(spriteNum,-1,3);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-13 23:12:47 +00:00
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case TREE1__STATIC:
|
|
|
|
case TREE2__STATIC:
|
|
|
|
case TIRE__STATIC:
|
|
|
|
case CONE__STATIC:
|
|
|
|
case BOX__STATIC:
|
|
|
|
{
|
2017-06-23 09:16:33 +00:00
|
|
|
switch (DYNAMICTILEMAP(sprite[dmgSrc].picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-16 03:02:42 +00:00
|
|
|
case RADIUSEXPLOSION__STATIC:
|
|
|
|
case RPG__STATIC:
|
|
|
|
case FIRELASER__STATIC:
|
|
|
|
case HYDRENT__STATIC:
|
|
|
|
case HEAVYHBOMB__STATIC:
|
2017-06-23 09:16:33 +00:00
|
|
|
radiusDamage = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (radiusDamage == 1)
|
2016-08-27 01:40:35 +00:00
|
|
|
if (T1(spriteNum) == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
CS(spriteNum) &= ~257;
|
|
|
|
T1(spriteNum) = 1;
|
|
|
|
A_Spawn(spriteNum,BURNING);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case CACTUS__STATIC:
|
|
|
|
{
|
2017-06-23 09:16:33 +00:00
|
|
|
switch (DYNAMICTILEMAP(sprite[dmgSrc].picnum))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
|
|
|
case RADIUSEXPLOSION__STATIC:
|
|
|
|
case RPG__STATIC:
|
|
|
|
case FIRELASER__STATIC:
|
|
|
|
case HYDRENT__STATIC:
|
|
|
|
case HEAVYHBOMB__STATIC:
|
2017-06-23 09:16:33 +00:00
|
|
|
radiusDamage = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (radiusDamage == 1)
|
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t k=64; k>0; k--)
|
2006-11-13 23:12:47 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int newSprite =
|
2017-06-23 09:16:33 +00:00
|
|
|
A_InsertSprite(SECT(spriteNum), SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (krand() % (48 << 8)), SCRAP3 + (krand() & 3), -8, 48, 48,
|
|
|
|
krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (sprite[spriteNum].zvel >> 2), spriteNum, 5);
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[newSprite].pal = 8;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2017-06-23 09:16:33 +00:00
|
|
|
// case CACTUSBROKE:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PN(spriteNum) == CACTUS)
|
|
|
|
PN(spriteNum) = CACTUSBROKE;
|
|
|
|
CS(spriteNum) &= ~257;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2014-01-31 21:12:58 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case HANGLIGHT__STATIC:
|
|
|
|
case GENERICPOLE2__STATIC:
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t k=6; k>0; k--)
|
2016-08-27 01:40:35 +00:00
|
|
|
A_InsertSprite(SECT(spriteNum),SX(spriteNum),SY(spriteNum),SZ(spriteNum)-ZOFFSET3,SCRAP1+(krand()&15),-8,48,48,krand()&2047,(krand()&63)+64,-(krand()&4095)-(sprite[spriteNum].zvel>>2),spriteNum,5);
|
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WATERFOUNTAIN__STATIC:
|
|
|
|
// case WATERFOUNTAIN+1:
|
|
|
|
// case WATERFOUNTAIN+2:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = WATERFOUNTAINBROKE;
|
|
|
|
A_Spawn(spriteNum,TOILETWATER);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case SATELITE__STATIC:
|
|
|
|
case FUELPOD__STATIC:
|
|
|
|
case SOLARPANNEL__STATIC:
|
|
|
|
case ANTENNA__STATIC:
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[dmgSrc].extra != G_DefaultActorHealth(SHOTSPARK1))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j=15; j>0; j--)
|
2016-08-27 01:40:35 +00:00
|
|
|
A_InsertSprite(SECT(spriteNum),SX(spriteNum),SY(spriteNum),sector[SECT(spriteNum)].floorz-ZOFFSET4-(j<<9),SCRAP1+(krand()&15),-8,64,64,
|
|
|
|
krand()&2047,(krand()&127)+64,-(krand()&511)-256,spriteNum,5);
|
|
|
|
A_Spawn(spriteNum,EXPLOSION2);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case BOTTLE1__STATIC:
|
|
|
|
case BOTTLE2__STATIC:
|
|
|
|
case BOTTLE3__STATIC:
|
|
|
|
case BOTTLE4__STATIC:
|
|
|
|
case BOTTLE5__STATIC:
|
|
|
|
case BOTTLE6__STATIC:
|
|
|
|
case BOTTLE8__STATIC:
|
|
|
|
case BOTTLE10__STATIC:
|
|
|
|
case BOTTLE11__STATIC:
|
|
|
|
case BOTTLE12__STATIC:
|
|
|
|
case BOTTLE13__STATIC:
|
|
|
|
case BOTTLE14__STATIC:
|
|
|
|
case BOTTLE15__STATIC:
|
|
|
|
case BOTTLE16__STATIC:
|
|
|
|
case BOTTLE17__STATIC:
|
|
|
|
case BOTTLE18__STATIC:
|
|
|
|
case BOTTLE19__STATIC:
|
|
|
|
case WATERFOUNTAINBROKE__STATIC:
|
|
|
|
case DOMELITE__STATIC:
|
|
|
|
case SUSHIPLATE1__STATIC:
|
|
|
|
case SUSHIPLATE2__STATIC:
|
|
|
|
case SUSHIPLATE3__STATIC:
|
|
|
|
case SUSHIPLATE4__STATIC:
|
|
|
|
case SUSHIPLATE5__STATIC:
|
|
|
|
case WAITTOBESEATED__STATIC:
|
|
|
|
case VASE__STATIC:
|
|
|
|
case STATUEFLASH__STATIC:
|
|
|
|
case STATUE__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PN(spriteNum) == BOTTLE10)
|
|
|
|
A_SpawnMultiple(spriteNum, MONEY, 4+(krand()&3));
|
|
|
|
else if (PN(spriteNum) == STATUE || PN(spriteNum) == STATUEFLASH)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_SpawnRandomGlass(spriteNum,-1,40);
|
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (PN(spriteNum) == VASE)
|
|
|
|
A_SpawnWallGlass(spriteNum,-1,40);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_BREAKING,spriteNum);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_SpawnWallGlass(spriteNum,-1,8);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case FETUS__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = FETUSBROKE;
|
|
|
|
A_PlaySound(GLASS_BREAKING,spriteNum);
|
|
|
|
A_SpawnWallGlass(spriteNum,-1,10);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case FETUSBROKE__STATIC:
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j=48; j>0; j--)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_Shoot(spriteNum,BLOODSPLAT1);
|
|
|
|
SA(spriteNum) += 333;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
|
|
|
A_PlaySound(SQUISHED,spriteNum);
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2006-11-16 03:02:42 +00:00
|
|
|
case BOTTLE7__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_BREAKING,spriteNum);
|
|
|
|
A_SpawnWallGlass(spriteNum,-1,10);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case HYDROPLANT__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = BROKEHYDROPLANT;
|
|
|
|
A_PlaySound(GLASS_BREAKING,spriteNum);
|
|
|
|
A_SpawnWallGlass(spriteNum,-1,10);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FORCESPHERE__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[spriteNum].xrepeat = 0;
|
|
|
|
actor[OW(spriteNum)].t_data[0] = 32;
|
|
|
|
actor[OW(spriteNum)].t_data[1] = !actor[OW(spriteNum)].t_data[1];
|
|
|
|
actor[OW(spriteNum)].t_data[2] ++;
|
|
|
|
A_Spawn(spriteNum,EXPLOSION2);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BROKEHYDROPLANT__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_BREAKING,spriteNum);
|
|
|
|
A_SpawnWallGlass(spriteNum,-1,5);
|
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TOILET__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = TOILETBROKE;
|
|
|
|
CS(spriteNum) |= (krand()&1)<<2;
|
|
|
|
CS(spriteNum) &= ~257;
|
|
|
|
A_Spawn(spriteNum,TOILETWATER);
|
|
|
|
A_PlaySound(GLASS_BREAKING,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case STALL__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = STALLBROKE;
|
|
|
|
CS(spriteNum) |= (krand()&1)<<2;
|
|
|
|
CS(spriteNum) &= ~257;
|
|
|
|
A_Spawn(spriteNum,TOILETWATER);
|
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case HYDRENT__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = BROKEFIREHYDRENT;
|
|
|
|
A_Spawn(spriteNum,TOILETWATER);
|
2006-11-16 03:02:42 +00:00
|
|
|
|
|
|
|
// for(k=0;k<5;k++)
|
|
|
|
// {
|
2008-11-20 14:06:36 +00:00
|
|
|
// j = A_InsertSprite(SECT,SX,SY,SZ-(krand()%(48<<8)),SCRAP3+(krand()&3),-8,48,48,krand()&2047,(krand()&63)+64,-(krand()&4095)-(sprite[i].zvel>>2),i,5);
|
2006-11-16 03:02:42 +00:00
|
|
|
// sprite[j].pal = 2;
|
|
|
|
// }
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CIRCLEPANNEL__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = CIRCLEPANNELBROKE;
|
|
|
|
CS(spriteNum) &= (65535-256-1);
|
|
|
|
A_PlaySound(VENT_BUST,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case PANNEL1__STATIC:
|
|
|
|
case PANNEL2__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = BPANNEL1;
|
|
|
|
CS(spriteNum) &= (65535-256-1);
|
|
|
|
A_PlaySound(VENT_BUST,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case PANNEL3__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = BPANNEL3;
|
|
|
|
CS(spriteNum) &= (65535-256-1);
|
|
|
|
A_PlaySound(VENT_BUST,spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case PIPE1__STATIC:
|
|
|
|
case PIPE2__STATIC:
|
|
|
|
case PIPE3__STATIC:
|
|
|
|
case PIPE4__STATIC:
|
|
|
|
case PIPE5__STATIC:
|
|
|
|
case PIPE6__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
{
|
|
|
|
switch (DYNAMICTILEMAP(PN(spriteNum)))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2006-11-13 23:12:47 +00:00
|
|
|
case PIPE1__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum)=PIPE1B;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-11-13 23:12:47 +00:00
|
|
|
case PIPE2__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum)=PIPE2B;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-11-13 23:12:47 +00:00
|
|
|
case PIPE3__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum)=PIPE3B;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-11-13 23:12:47 +00:00
|
|
|
case PIPE4__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum)=PIPE4B;
|
2006-11-15 01:16:55 +00:00
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
case PIPE5__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum)=PIPE5B;
|
2006-11-15 01:16:55 +00:00
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
case PIPE6__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum)=PIPE6B;
|
2006-11-15 01:16:55 +00:00
|
|
|
break;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int newSprite = A_Spawn(spriteNum, STEAM);
|
2016-08-27 01:40:56 +00:00
|
|
|
sprite[newSprite].z = sector[SECT(spriteNum)].floorz-ZOFFSET5;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2016-08-27 01:40:35 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
|
|
|
|
case MONK__STATIC:
|
|
|
|
case LUKE__STATIC:
|
|
|
|
case INDY__STATIC:
|
|
|
|
case JURYGUY__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(SLT(spriteNum),spriteNum);
|
|
|
|
A_Spawn(spriteNum,SHT(spriteNum));
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2006-11-16 03:02:42 +00:00
|
|
|
case SPACEMARINE__STATIC:
|
2017-06-23 09:16:33 +00:00
|
|
|
sprite[spriteNum].extra -= sprite[dmgSrc].extra;
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].extra > 0) break;
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT1);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT2);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT3);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT4);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT1);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT2);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT3);
|
|
|
|
SA(spriteNum) = krand()&2047;
|
|
|
|
A_Shoot(spriteNum,BLOODSPLAT4);
|
|
|
|
A_DoGuts(spriteNum,JIBS1,1);
|
|
|
|
A_DoGuts(spriteNum,JIBS2,2);
|
|
|
|
A_DoGuts(spriteNum,JIBS3,3);
|
|
|
|
A_DoGuts(spriteNum,JIBS4,4);
|
|
|
|
A_DoGuts(spriteNum,JIBS5,1);
|
|
|
|
A_DoGuts(spriteNum,JIBS3,6);
|
2008-11-20 14:06:36 +00:00
|
|
|
S_PlaySound(SQUISHED);
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case CHAIR1__STATIC:
|
|
|
|
case CHAIR2__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
PN(spriteNum) = BROKENCHAIR;
|
|
|
|
CS(spriteNum) = 0;
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case CHAIR3__STATIC:
|
|
|
|
case MOVIECAMERA__STATIC:
|
|
|
|
case SCALE__STATIC:
|
|
|
|
case VACUUM__STATIC:
|
|
|
|
case CAMERALIGHT__STATIC:
|
|
|
|
case IVUNIT__STATIC:
|
|
|
|
case POT1__STATIC:
|
|
|
|
case POT2__STATIC:
|
|
|
|
case POT3__STATIC:
|
|
|
|
case TRIPODCAMERA__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(GLASS_HEAVYBREAK,spriteNum);
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t j=16; j>0; j--)
|
2018-04-02 22:00:44 +00:00
|
|
|
{
|
|
|
|
spritetype * const pSprite = &sprite[spriteNum];
|
2016-08-27 01:40:35 +00:00
|
|
|
RANDOMSCRAP(pSprite, spriteNum);
|
2018-04-02 22:00:44 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
A_DeleteSprite(spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif // EDUKE32_STANDALONE
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case PLAYERONWATER__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
spriteNum = OW(spriteNum);
|
2018-09-04 05:57:41 +00:00
|
|
|
fallthrough__;
|
2006-11-16 03:02:42 +00:00
|
|
|
default:
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((sprite[spriteNum].cstat&16) && SHT(spriteNum) == 0 && SLT(spriteNum) == 0 && sprite[spriteNum].statnum == STAT_DEFAULT)
|
2006-04-13 20:47:06 +00:00
|
|
|
break;
|
|
|
|
|
2017-06-23 09:16:33 +00:00
|
|
|
if ((sprite[dmgSrc].picnum == FREEZEBLAST || sprite[dmgSrc].owner != spriteNum) && sprite[spriteNum].statnum != STAT_PROJECTILE)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckEnemySprite(&sprite[spriteNum]) == 1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[dmgSrc].picnum == RPG)
|
|
|
|
sprite[dmgSrc].extra <<= 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((PN(spriteNum) != DRONE) && (PN(spriteNum) != ROTATEGUN) && (PN(spriteNum) != COMMANDER) && (PN(spriteNum) < GREENSLIME || PN(spriteNum) > GREENSLIME+7))
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[dmgSrc].picnum != FREEZEBLAST)
|
2016-08-27 01:40:35 +00:00
|
|
|
if (!A_CheckSpriteFlags(spriteNum, SFLAG_BADGUY) || A_CheckSpriteFlags(spriteNum, SFLAG_HURTSPAWNBLOOD))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2017-06-23 09:16:33 +00:00
|
|
|
int const newSprite = A_Spawn(dmgSrc, JIBS6);
|
2016-08-27 01:41:04 +00:00
|
|
|
sprite[newSprite].z += ZOFFSET6;
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[dmgSrc].pal == 6)
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[newSprite].pal = 6;
|
|
|
|
sprite[newSprite].xvel = 16;
|
|
|
|
sprite[newSprite].xrepeat = sprite[newSprite].yrepeat = 24;
|
|
|
|
sprite[newSprite].ang += 32 - (krand() & 63);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 09:16:33 +00:00
|
|
|
int const damageOwner = sprite[dmgSrc].owner;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (damageOwner >= 0 && sprite[damageOwner].picnum == APLAYER && PN(spriteNum) != ROTATEGUN && PN(spriteNum) != DRONE)
|
|
|
|
if (g_player[P_Get(damageOwner)].ps->curr_weapon == SHOTGUN_WEAPON)
|
|
|
|
if (!A_CheckSpriteFlags(spriteNum, SFLAG_BADGUY) || A_CheckSpriteFlags(spriteNum, SFLAG_HURTSPAWNBLOOD))
|
2015-05-27 08:45:59 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_Shoot(spriteNum, BLOODSPLAT3);
|
|
|
|
A_Shoot(spriteNum, BLOODSPLAT1);
|
|
|
|
A_Shoot(spriteNum, BLOODSPLAT2);
|
|
|
|
A_Shoot(spriteNum, BLOODSPLAT4);
|
2015-05-27 08:45:59 +00:00
|
|
|
}
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (!A_CheckSpriteFlags(spriteNum, SFLAG_NODAMAGEPUSH))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].extra > 0)
|
2008-12-01 10:44:18 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((sprite[spriteNum].cstat & 48) == 0)
|
2017-06-23 09:16:33 +00:00
|
|
|
SA(spriteNum) = (sprite[dmgSrc].ang + 1024) & 2047;
|
|
|
|
sprite[spriteNum].xvel = -(sprite[dmgSrc].extra << 2);
|
2016-08-27 01:40:35 +00:00
|
|
|
int16_t sectNum = SECT(spriteNum);
|
|
|
|
pushmove((vec3_t *)&sprite[spriteNum], §Num, 128L, (4L << 8), (4L << 8), CLIPMASK0);
|
|
|
|
if (sectNum != SECT(spriteNum) && (unsigned)sectNum < MAXSECTORS)
|
|
|
|
changespritesect(spriteNum, sectNum);
|
2008-12-01 10:44:18 +00:00
|
|
|
}
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].statnum == STAT_ZOMBIEACTOR)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
changespritestat(spriteNum, STAT_ACTOR);
|
|
|
|
actor[spriteNum].timetosleep = SLEEPTIME;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2017-06-23 09:16:33 +00:00
|
|
|
if ((sprite[spriteNum].xrepeat < 24 || PN(spriteNum) == SHARK) && sprite[dmgSrc].picnum == SHRINKSPARK)
|
2012-05-05 22:23:44 +00:00
|
|
|
return;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].statnum != STAT_ZOMBIEACTOR)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[dmgSrc].picnum == FREEZEBLAST && ((PN(spriteNum) == APLAYER && sprite[spriteNum].pal == 1) || (g_freezerSelfDamage == 0 && sprite[dmgSrc].owner == spriteNum)))
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2017-06-23 09:16:33 +00:00
|
|
|
actor[spriteNum].picnum = sprite[dmgSrc].picnum;
|
|
|
|
actor[spriteNum].extra += sprite[dmgSrc].extra;
|
|
|
|
actor[spriteNum].ang = sprite[dmgSrc].ang;
|
|
|
|
actor[spriteNum].owner = sprite[dmgSrc].owner;
|
2018-03-17 03:26:10 +00:00
|
|
|
|
|
|
|
if(A_CheckSpriteFlags(spriteNum, SFLAG_DAMAGEEVENT))
|
|
|
|
VM_OnEventWithReturn(EVENT_POSTDAMAGESPRITE, dmgSrc, -1, spriteNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].statnum == STAT_PLAYER)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
DukePlayer_t *ps = g_player[P_Get(spriteNum)].ps;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-08-02 10:52:13 +00:00
|
|
|
if (ps->newowner >= 0)
|
|
|
|
G_ClearCameraView(ps);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2017-06-23 09:16:33 +00:00
|
|
|
if (sprite[spriteNum].xrepeat < 24 && sprite[dmgSrc].picnum == SHRINKSPARK)
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[actor[spriteNum].owner].picnum != APLAYER)
|
2006-11-16 03:02:42 +00:00
|
|
|
if (ud.player_skill >= 3)
|
2017-06-23 09:16:33 +00:00
|
|
|
sprite[dmgSrc].extra += (sprite[dmgSrc].extra>>1);
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-17 03:26:10 +00:00
|
|
|
void A_DamageObject(int spriteNum, int const dmgSrc)
|
|
|
|
{
|
|
|
|
ud.returnvar[0] = -1;
|
|
|
|
A_DamageObject_Internal(spriteNum, dmgSrc);
|
|
|
|
}
|
|
|
|
|
2012-09-12 09:45:14 +00:00
|
|
|
void G_AlignWarpElevators(void)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, i))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (SLT(i) == SE_17_WARP_ELEVATOR && SS(i) > 16)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_EFFECTOR, j))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (i != j && sprite[j].lotag == SE_17_WARP_ELEVATOR && SHT(i) == sprite[j].hitag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
sector[sprite[j].sectnum].floorz = sector[SECT(i)].floorz;
|
|
|
|
sector[sprite[j].sectnum].ceilingz = sector[SECT(i)].ceilingz;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-08 08:03:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
static int P_CheckDetonatorSpecialCase(DukePlayer_t *const pPlayer, int weaponNum)
|
2015-02-08 08:03:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (weaponNum == HANDBOMB_WEAPON && pPlayer->ammo_amount[HANDBOMB_WEAPON] == 0)
|
2015-02-08 08:03:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int spriteNum = headspritestat[STAT_ACTOR];
|
2016-08-27 01:40:35 +00:00
|
|
|
|
|
|
|
while (spriteNum >= 0)
|
2015-02-08 08:03:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (sprite[spriteNum].picnum == HEAVYHBOMB && sprite[spriteNum].owner == pPlayer->i)
|
2015-02-08 08:03:06 +00:00
|
|
|
return 1;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
spriteNum = nextspritestat[spriteNum];
|
2015-02-08 08:03:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
void P_HandleSharedKeys(int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
DukePlayer_t *const pPlayer = g_player[playerNum].ps;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
|
|
|
if (pPlayer->cheat_phase == 1) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
uint32_t playerBits = g_player[playerNum].inputBits->bits, weaponNum;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
// 1<<0 = jump
|
|
|
|
// 1<<1 = crouch
|
|
|
|
// 1<<2 = fire
|
|
|
|
// 1<<3 = aim up
|
|
|
|
// 1<<4 = aim down
|
|
|
|
// 1<<5 = run
|
|
|
|
// 1<<6 = look left
|
|
|
|
// 1<<7 = look right
|
|
|
|
// 15<<8 = !weapon selection (bits 8-11)
|
|
|
|
// 1<<12 = !steroids
|
|
|
|
// 1<<13 = look up
|
|
|
|
// 1<<14 = look down
|
|
|
|
// 1<<15 = !nightvis
|
|
|
|
// 1<<16 = !medkit
|
|
|
|
// 1<<17 = (multiflag==1) ? changes meaning of bits 18 and 19
|
|
|
|
// 1<<18 = centre view
|
|
|
|
// 1<<19 = !holster weapon
|
|
|
|
// 1<<20 = !inventory left
|
|
|
|
// 1<<21 = !pause
|
|
|
|
// 1<<22 = !quick kick
|
|
|
|
// 1<<23 = aim mode
|
|
|
|
// 1<<24 = !holoduke
|
|
|
|
// 1<<25 = !jetpack
|
2008-11-20 14:06:36 +00:00
|
|
|
// 1<<26 = g_gameQuit
|
2006-04-13 20:47:06 +00:00
|
|
|
// 1<<27 = !inventory right
|
|
|
|
// 1<<28 = !turn around
|
|
|
|
// 1<<29 = !open
|
|
|
|
// 1<<30 = !inventory
|
|
|
|
// 1<<31 = !escape
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int const aimMode = pPlayer->aim_mode;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->aim_mode = (playerBits>>SK_AIMMODE)&1;
|
|
|
|
if (pPlayer->aim_mode < aimMode)
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->return_to_center = 9;
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_QUICK_KICK) && pPlayer->quick_kick == 0)
|
|
|
|
if (PWEAPON(playerNum, pPlayer->curr_weapon, WorksLike) != KNEE_WEAPON || pPlayer->kickback_pic == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_QUICKKICK,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->quick_kick = 14;
|
|
|
|
if (pPlayer->fta == 0 || pPlayer->ftq == 80)
|
|
|
|
P_DoQuote(QUOTE_MIGHTY_FOOT,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = playerBits & ((15u<<SK_WEAPON_BITS)|BIT(SK_STEROIDS)|BIT(SK_NIGHTVISION)|BIT(SK_MEDKIT)|BIT(SK_QUICK_KICK)| \
|
2008-11-20 14:06:36 +00:00
|
|
|
BIT(SK_HOLSTER)|BIT(SK_INV_LEFT)|BIT(SK_PAUSE)|BIT(SK_HOLODUKE)|BIT(SK_JETPACK)|BIT(SK_INV_RIGHT)| \
|
|
|
|
BIT(SK_TURNAROUND)|BIT(SK_OPEN)|BIT(SK_INVENTORY)|BIT(SK_ESCAPE));
|
2018-11-18 18:07:38 +00:00
|
|
|
playerBits = weaponNum & ~pPlayer->interface_toggle;
|
|
|
|
pPlayer->interface_toggle |= playerBits | ((playerBits&0xf00)?0xf00:0);
|
|
|
|
pPlayer->interface_toggle &= weaponNum | ((weaponNum&0xf00)?0xf00:0);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (playerBits && TEST_SYNC_KEY(playerBits, SK_MULTIFLAG) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_PAUSE))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-14 21:35:50 +00:00
|
|
|
KB_ClearKeyDown(sc_Pause);
|
2006-11-13 23:12:47 +00:00
|
|
|
if (ud.pause_on)
|
2006-04-19 05:48:44 +00:00
|
|
|
ud.pause_on = 0;
|
|
|
|
else ud.pause_on = 1+SHIFTS_IS_PRESSED;
|
2006-11-13 23:12:47 +00:00
|
|
|
if (ud.pause_on)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-10-25 23:32:29 +00:00
|
|
|
S_PauseMusic(true);
|
|
|
|
S_PauseSounds(true);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-25 23:32:29 +00:00
|
|
|
if (ud.config.MusicToggle) S_PauseMusic(false);
|
2016-02-02 06:39:22 +00:00
|
|
|
|
2018-10-25 23:32:29 +00:00
|
|
|
S_PauseSounds(false);
|
2016-02-02 06:39:22 +00:00
|
|
|
|
2006-04-13 20:47:06 +00:00
|
|
|
pub = NUMPAGES;
|
|
|
|
pus = NUMPAGES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-13 23:12:47 +00:00
|
|
|
if (ud.pause_on) return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (sprite[pPlayer->i].extra <= 0) return; // if dead...
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_INVENTORY) && pPlayer->newowner == -1) // inventory button generates event for selected item
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_INVENTORY,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
switch (pPlayer->inven_icon)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
case ICON_JETPACK: playerBits |= BIT(SK_JETPACK); break;
|
|
|
|
case ICON_HOLODUKE: playerBits |= BIT(SK_HOLODUKE); break;
|
|
|
|
case ICON_HEATS: playerBits |= BIT(SK_NIGHTVISION); break;
|
|
|
|
case ICON_FIRSTAID: playerBits |= BIT(SK_MEDKIT); break;
|
|
|
|
case ICON_STEROIDS: playerBits |= BIT(SK_STEROIDS); break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_NIGHTVISION))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_USENIGHTVISION,g_player[playerNum].ps->i,playerNum) == 0
|
2016-08-27 01:40:06 +00:00
|
|
|
&& pPlayer->inv_amount[GET_HEATS] > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->heat_on = !pPlayer->heat_on;
|
|
|
|
P_UpdateScreenPal(pPlayer);
|
|
|
|
pPlayer->inven_icon = ICON_HEATS;
|
|
|
|
A_PlaySound(NITEVISION_ONOFF,pPlayer->i);
|
|
|
|
P_DoQuote(QUOTE_NVG_OFF-!!pPlayer->heat_on,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_STEROIDS))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_USESTEROIDS,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->inv_amount[GET_STEROIDS] == 400)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->inv_amount[GET_STEROIDS]--;
|
|
|
|
A_PlaySound(DUKE_TAKEPILLS,pPlayer->i);
|
|
|
|
P_DoQuote(QUOTE_USED_STEROIDS,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->inv_amount[GET_STEROIDS] > 0)
|
|
|
|
pPlayer->inven_icon = ICON_STEROIDS;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
return; // is there significance to returning?
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pPlayer->newowner == -1 && (TEST_SYNC_KEY(playerBits, SK_INV_LEFT) || TEST_SYNC_KEY(playerBits, SK_INV_RIGHT)))
|
2012-05-15 23:39:48 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->invdisptime = GAMETICSPERSEC*2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int const inventoryRight = !!(TEST_SYNC_KEY(playerBits, SK_INV_RIGHT));
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int32_t inventoryIcon = pPlayer->inven_icon;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
int i = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2012-05-15 23:39:48 +00:00
|
|
|
CHECKINV1:
|
|
|
|
if (i < 9)
|
|
|
|
{
|
|
|
|
i++;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
switch (inventoryIcon)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
case ICON_JETPACK:
|
|
|
|
case ICON_SCUBA:
|
|
|
|
case ICON_STEROIDS:
|
|
|
|
case ICON_HOLODUKE:
|
|
|
|
case ICON_HEATS:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pPlayer->inv_amount[icon_to_inv[inventoryIcon]] > 0 && i > 1)
|
2016-08-27 01:40:06 +00:00
|
|
|
break;
|
2016-08-27 01:42:01 +00:00
|
|
|
if (inventoryRight)
|
2016-08-27 01:40:35 +00:00
|
|
|
inventoryIcon++;
|
2016-08-27 01:40:06 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
inventoryIcon--;
|
2016-08-27 01:40:06 +00:00
|
|
|
goto CHECKINV1;
|
|
|
|
case ICON_NONE:
|
|
|
|
case ICON_FIRSTAID:
|
|
|
|
if (pPlayer->inv_amount[GET_FIRSTAID] > 0 && i > 1)
|
|
|
|
break;
|
2016-08-27 01:42:01 +00:00
|
|
|
inventoryIcon = inventoryRight ? 2 : 7;
|
2016-08-27 01:40:06 +00:00
|
|
|
goto CHECKINV1;
|
|
|
|
case ICON_BOOTS:
|
|
|
|
if (pPlayer->inv_amount[GET_BOOTS] > 0 && i > 1)
|
|
|
|
break;
|
2016-08-27 01:42:01 +00:00
|
|
|
inventoryIcon = inventoryRight ? 1 : 6;
|
2016-08-27 01:40:06 +00:00
|
|
|
goto CHECKINV1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2012-05-15 23:39:48 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else inventoryIcon = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_INV_LEFT)) // Inventory_Left
|
2012-05-15 23:39:48 +00:00
|
|
|
{
|
|
|
|
/*Gv_SetVar(g_iReturnVarID,dainv,g_player[snum].ps->i,snum);*/
|
2016-08-27 01:40:35 +00:00
|
|
|
inventoryIcon = VM_OnEventWithReturn(EVENT_INVENTORYLEFT,g_player[playerNum].ps->i,playerNum, inventoryIcon);
|
2012-05-15 23:39:48 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (TEST_SYNC_KEY(playerBits, SK_INV_RIGHT)) // Inventory_Right
|
2012-05-15 23:39:48 +00:00
|
|
|
{
|
|
|
|
/*Gv_SetVar(g_iReturnVarID,dainv,g_player[snum].ps->i,snum);*/
|
2016-08-27 01:40:35 +00:00
|
|
|
inventoryIcon = VM_OnEventWithReturn(EVENT_INVENTORYRIGHT,g_player[playerNum].ps->i,playerNum, inventoryIcon);
|
2012-05-15 23:39:48 +00:00
|
|
|
}
|
2009-08-06 10:12:13 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (inventoryIcon >= 1)
|
2012-05-15 23:39:48 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->inven_icon = inventoryIcon;
|
2012-05-15 23:39:48 +00:00
|
|
|
|
2018-10-25 23:29:38 +00:00
|
|
|
static const int32_t invQuotes[8] = { QUOTE_MEDKIT, QUOTE_STEROIDS, QUOTE_HOLODUKE,
|
|
|
|
QUOTE_JETPACK, QUOTE_NVG, QUOTE_SCUBA, QUOTE_BOOTS, 0 };
|
|
|
|
|
|
|
|
if (inventoryIcon-1 < ARRAY_SSIZE(invQuotes))
|
|
|
|
P_DoQuote(invQuotes[inventoryIcon-1], pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2012-05-15 23:39:48 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = ((playerBits&(15<<SK_WEAPON_BITS))>>SK_WEAPON_BITS) - 1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
switch ((int32_t)weaponNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2011-03-24 16:55:44 +00:00
|
|
|
case -1:
|
|
|
|
break;
|
2010-05-02 23:27:30 +00:00
|
|
|
default:
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = VM_OnEventWithReturn(EVENT_WEAPKEY1+weaponNum,pPlayer->i,playerNum, weaponNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case 10:
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = VM_OnEventWithReturn(EVENT_PREVIOUSWEAPON,pPlayer->i,playerNum, weaponNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case 11:
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = VM_OnEventWithReturn(EVENT_NEXTWEAPON,pPlayer->i,playerNum, weaponNum);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2018-01-26 04:35:23 +00:00
|
|
|
case 12:
|
|
|
|
weaponNum = VM_OnEventWithReturn(EVENT_ALTWEAPON,pPlayer->i,playerNum, weaponNum);
|
|
|
|
break;
|
2018-03-08 03:54:54 +00:00
|
|
|
case 13:
|
|
|
|
weaponNum = VM_OnEventWithReturn(EVENT_LASTWEAPON,pPlayer->i,playerNum, weaponNum);
|
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2013-11-28 21:18:05 +00:00
|
|
|
// NOTE: it is assumed that the above events return either -1 or a
|
|
|
|
// valid weapon index. Presumably, neither other negative numbers nor
|
|
|
|
// positive ones >= MAX_WEAPONS are allowed. However, the code below is
|
|
|
|
// a bit inconsistent in checking "j".
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->reloading == 1)
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = -1;
|
|
|
|
else if ((uint32_t)weaponNum < MAX_WEAPONS && pPlayer->kickback_pic == 1 && pPlayer->weapon_pos == 1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->wantweaponfire = weaponNum;
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->kickback_pic = 0;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2013-11-28 21:18:05 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((int32_t)weaponNum != -1 && pPlayer->last_pissed_time <= (GAMETICSPERSEC * 218) && pPlayer->show_empty_weapon == 0 &&
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->kickback_pic == 0 && pPlayer->quick_kick == 0 && sprite[pPlayer->i].xrepeat > 32 && pPlayer->access_incs == 0 &&
|
|
|
|
pPlayer->knee_incs == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2013-06-27 23:04:57 +00:00
|
|
|
// if( ( p->weapon_pos == 0 || ( p->holster_weapon && p->weapon_pos == WEAPON_POS_LOWER ) ))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (weaponNum == 10 || weaponNum == 11)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int currentWeapon = pPlayer->curr_weapon;
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = (weaponNum == 10 ? -1 : 1); // JBF: prev (-1) or next (1) weapon choice
|
|
|
|
int i = currentWeapon;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
while ((currentWeapon >= 0 && currentWeapon < 11) || (PLUTOPAK && currentWeapon == GROW_WEAPON))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2015-01-25 12:16:22 +00:00
|
|
|
// this accounts for the expander when handling next/previous
|
2014-10-29 17:08:03 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
switch (currentWeapon)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2014-10-29 17:08:03 +00:00
|
|
|
case DEVISTATOR_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((int32_t) weaponNum == -1)
|
2014-10-29 17:08:03 +00:00
|
|
|
{
|
2015-01-25 12:16:22 +00:00
|
|
|
if (PLUTOPAK)
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon = GROW_WEAPON;
|
2014-10-29 17:08:03 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon--;
|
2014-10-29 17:08:03 +00:00
|
|
|
}
|
2015-01-25 12:16:22 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon++;
|
2014-10-29 17:08:03 +00:00
|
|
|
break;
|
2015-01-25 12:16:22 +00:00
|
|
|
|
2014-10-29 17:08:03 +00:00
|
|
|
case GROW_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon = ((int32_t) weaponNum == -1) ? SHRINKER_WEAPON : DEVISTATOR_WEAPON;
|
2014-10-29 17:08:03 +00:00
|
|
|
break;
|
2015-01-25 12:16:22 +00:00
|
|
|
|
2014-10-29 17:08:03 +00:00
|
|
|
case SHRINKER_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((int32_t)weaponNum == 1)
|
2014-10-29 17:08:03 +00:00
|
|
|
{
|
2015-01-25 12:16:22 +00:00
|
|
|
if (PLUTOPAK)
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon = GROW_WEAPON;
|
2014-10-29 17:08:03 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon++;
|
2014-10-29 17:08:03 +00:00
|
|
|
}
|
2015-01-25 12:16:22 +00:00
|
|
|
else
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon--;
|
2015-01-25 12:16:22 +00:00
|
|
|
break;
|
|
|
|
|
2015-01-25 12:27:52 +00:00
|
|
|
case HANDREMOTE_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
i = currentWeapon = HANDBOMB_WEAPON;
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2015-01-25 12:16:22 +00:00
|
|
|
default:
|
2016-08-27 01:40:35 +00:00
|
|
|
currentWeapon += weaponNum;
|
2014-10-29 17:08:03 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (currentWeapon == -1) currentWeapon = FREEZE_WEAPON;
|
|
|
|
else if (currentWeapon == 10) currentWeapon = KNEE_WEAPON;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (((pPlayer->gotweapon & (1<<currentWeapon)) && pPlayer->ammo_amount[currentWeapon] > 0) || P_CheckDetonatorSpecialCase(pPlayer, currentWeapon))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = currentWeapon;
|
2006-04-13 20:47:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (i == currentWeapon) // absolutely no weapons, so use foot
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = KNEE_WEAPON;
|
2006-04-13 20:47:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-01-25 12:16:22 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (weaponNum == SHRINKER_WEAPON)
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->subweapon &= ~(1 << GROW_WEAPON);
|
2016-08-27 01:40:35 +00:00
|
|
|
else if (weaponNum == GROW_WEAPON)
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->subweapon |= (1<<GROW_WEAPON);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2018-03-08 03:54:54 +00:00
|
|
|
// last used weapon will depend on subweapon
|
|
|
|
if (weaponNum >= 12) // alt weapon, last used weapon
|
2018-01-26 04:35:23 +00:00
|
|
|
{
|
2018-03-08 03:54:54 +00:00
|
|
|
uint32_t const weaponNumSwitch = weaponNum == 13 ? pPlayer->last_used_weapon : pPlayer->curr_weapon;
|
|
|
|
switch (weaponNumSwitch)
|
2018-01-26 04:35:23 +00:00
|
|
|
{
|
|
|
|
case HANDREMOTE_WEAPON:
|
|
|
|
weaponNum = HANDBOMB_WEAPON;
|
|
|
|
break;
|
|
|
|
case GROW_WEAPON:
|
|
|
|
weaponNum = SHRINKER_WEAPON;
|
|
|
|
break;
|
|
|
|
default:
|
2018-03-08 03:54:54 +00:00
|
|
|
weaponNum = weaponNumSwitch;
|
2018-01-26 04:35:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
P_SetWeaponGamevars(playerNum, pPlayer);
|
2010-05-29 05:03:02 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = VM_OnEventWithReturn(EVENT_SELECTWEAPON,pPlayer->i,playerNum, weaponNum);
|
2010-05-29 05:03:02 +00:00
|
|
|
|
2013-11-28 21:18:05 +00:00
|
|
|
// XXX: any signifcance to "<= MAX_WEAPONS" instead of "<"?
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((int32_t)weaponNum != -1 && weaponNum <= MAX_WEAPONS)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (P_CheckDetonatorSpecialCase(pPlayer, weaponNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->gotweapon |= (1<<HANDBOMB_WEAPON);
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = HANDREMOTE_WEAPON;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (weaponNum == SHRINKER_WEAPON && PLUTOPAK) // JBF 20040116: so we don't select the grower with v1.3d
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (screenpeek == playerNum) pus = NUMPAGES;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->curr_weapon != GROW_WEAPON && pPlayer->curr_weapon != SHRINKER_WEAPON)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->ammo_amount[GROW_WEAPON] > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if ((pPlayer->subweapon&(1<<GROW_WEAPON)) == (1<<GROW_WEAPON))
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = GROW_WEAPON;
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (pPlayer->ammo_amount[SHRINKER_WEAPON] == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = GROW_WEAPON;
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->subweapon |= (1<<GROW_WEAPON);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (pPlayer->ammo_amount[SHRINKER_WEAPON] > 0)
|
|
|
|
pPlayer->subweapon &= ~(1<<GROW_WEAPON);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (pPlayer->curr_weapon == SHRINKER_WEAPON)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->subweapon |= (1<<GROW_WEAPON);
|
2016-08-27 01:40:35 +00:00
|
|
|
weaponNum = GROW_WEAPON;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->subweapon &= ~(1<<GROW_WEAPON);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->holster_weapon)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
playerBits |= BIT(SK_HOLSTER);
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->weapon_pos = WEAPON_POS_LOWER;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
else if ((uint32_t)weaponNum < MAX_WEAPONS && (pPlayer->gotweapon & (1<<weaponNum)) && (uint32_t)pPlayer->curr_weapon != weaponNum)
|
|
|
|
switch (weaponNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2006-11-16 03:02:42 +00:00
|
|
|
case PISTOL_WEAPON:
|
|
|
|
case SHOTGUN_WEAPON:
|
|
|
|
case CHAINGUN_WEAPON:
|
|
|
|
case RPG_WEAPON:
|
|
|
|
case DEVISTATOR_WEAPON:
|
|
|
|
case FREEZE_WEAPON:
|
|
|
|
case GROW_WEAPON:
|
|
|
|
case SHRINKER_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pPlayer->ammo_amount[weaponNum] == 0 && pPlayer->show_empty_weapon == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->last_full_weapon = pPlayer->curr_weapon;
|
|
|
|
pPlayer->show_empty_weapon = 32;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2017-07-18 20:53:41 +00:00
|
|
|
fallthrough__;
|
2009-07-24 02:31:34 +00:00
|
|
|
case KNEE_WEAPON:
|
2006-11-16 03:02:42 +00:00
|
|
|
case HANDREMOTE_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
P_AddWeapon(pPlayer, weaponNum, 1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
|
|
|
case HANDBOMB_WEAPON:
|
|
|
|
case TRIPBOMB_WEAPON:
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pPlayer->ammo_amount[weaponNum] > 0 && (pPlayer->gotweapon & (1<<weaponNum)))
|
|
|
|
P_AddWeapon(pPlayer, weaponNum, 1);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_HOLODUKE) && (pPlayer->newowner == -1 || pPlayer->holoduke_on != -1))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->holoduke_on == -1)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_HOLODUKEON,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->inv_amount[GET_HOLODUKE] > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->inven_icon = ICON_HOLODUKE;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->cursectnum > -1)
|
2008-07-29 09:57:09 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
int const i = A_InsertSprite(pPlayer->cursectnum, pPlayer->pos.x, pPlayer->pos.y,
|
2018-03-07 04:21:18 +00:00
|
|
|
pPlayer->pos.z+(30<<8), APLAYER, -64, 0, 0, fix16_to_int(pPlayer->q16ang), 0, 0, -1, 10);
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->holoduke_on = i;
|
2016-08-27 01:40:35 +00:00
|
|
|
T4(i) = T5(i) = 0;
|
|
|
|
sprite[i].yvel = playerNum;
|
2008-07-29 09:57:09 +00:00
|
|
|
sprite[i].extra = 0;
|
2016-08-27 01:40:06 +00:00
|
|
|
P_DoQuote(QUOTE_HOLODUKE_ON,pPlayer);
|
|
|
|
A_PlaySound(TELEPORTER,pPlayer->holoduke_on);
|
2008-07-29 09:57:09 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else P_DoQuote(QUOTE_HOLODUKE_NOT_FOUND,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_HOLODUKEOFF,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
A_PlaySound(TELEPORTER,pPlayer->holoduke_on);
|
|
|
|
pPlayer->holoduke_on = -1;
|
|
|
|
P_DoQuote(QUOTE_HOLODUKE_OFF,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_MEDKIT))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_USEMEDKIT,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->inv_amount[GET_FIRSTAID] > 0 && sprite[pPlayer->i].extra < pPlayer->max_player_health)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
int healthDiff = pPlayer->max_player_health-sprite[pPlayer->i].extra;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (pPlayer->inv_amount[GET_FIRSTAID] > healthDiff)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->inv_amount[GET_FIRSTAID] -= healthDiff;
|
2016-08-27 01:40:06 +00:00
|
|
|
sprite[pPlayer->i].extra = pPlayer->max_player_health;
|
|
|
|
pPlayer->inven_icon = ICON_FIRSTAID;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
sprite[pPlayer->i].extra += pPlayer->inv_amount[GET_FIRSTAID];
|
|
|
|
pPlayer->inv_amount[GET_FIRSTAID] = 0;
|
|
|
|
P_SelectNextInvItem(pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
A_PlaySound(DUKE_USEMEDKIT,pPlayer->i);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if ((pPlayer->newowner == -1 || pPlayer->jetpack_on) && TEST_SYNC_KEY(playerBits, SK_JETPACK))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_USEJETPACK,g_player[playerNum].ps->i,playerNum) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->inv_amount[GET_JETPACK] > 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->jetpack_on = !pPlayer->jetpack_on;
|
|
|
|
if (pPlayer->jetpack_on)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->inven_icon = ICON_JETPACK;
|
|
|
|
if (pPlayer->scream_voice > FX_Ok)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
FX_StopSound(pPlayer->scream_voice);
|
|
|
|
pPlayer->scream_voice = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
A_PlaySound(DUKE_JETPACK_ON,pPlayer->i);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
P_DoQuote(QUOTE_JETPACK_ON,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->hard_landing = 0;
|
|
|
|
pPlayer->vel.z = 0;
|
|
|
|
A_PlaySound(DUKE_JETPACK_OFF,pPlayer->i);
|
|
|
|
S_StopEnvSound(DUKE_JETPACK_IDLE,pPlayer->i);
|
|
|
|
S_StopEnvSound(DUKE_JETPACK_ON,pPlayer->i);
|
|
|
|
P_DoQuote(QUOTE_JETPACK_OFF,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else P_DoQuote(QUOTE_JETPACK_NOT_FOUND,pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (TEST_SYNC_KEY(playerBits, SK_TURNAROUND) && pPlayer->one_eighty_count == 0)
|
|
|
|
if (VM_OnEvent(EVENT_TURNAROUND,pPlayer->i,playerNum) == 0)
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->one_eighty_count = -1024;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int A_CheckHitSprite(int spriteNum, int16_t *hitSprite)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
hitdata_t hitData;
|
|
|
|
int32_t zOffset = 0;
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (A_CheckEnemySprite(&sprite[spriteNum]))
|
|
|
|
zOffset = (42 << 8);
|
|
|
|
else if (PN(spriteNum) == APLAYER)
|
|
|
|
zOffset = (39 << 8);
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
SZ(spriteNum) -= zOffset;
|
|
|
|
hitscan((const vec3_t *)&sprite[spriteNum], SECT(spriteNum), sintable[(SA(spriteNum) + 512) & 2047],
|
|
|
|
sintable[SA(spriteNum) & 2047], 0, &hitData, CLIPMASK1);
|
|
|
|
SZ(spriteNum) += zOffset;
|
2009-08-28 23:08:00 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (hitSprite)
|
|
|
|
*hitSprite = hitData.sprite;
|
2011-02-25 21:50:19 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (hitData.wall >= 0 && (wall[hitData.wall].cstat&16) && A_CheckEnemySprite( &sprite[spriteNum]))
|
2013-04-15 10:48:09 +00:00
|
|
|
return 1<<30;
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return FindDistance2D(hitData.pos.x-SX(spriteNum),hitData.pos.y-SY(spriteNum));
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
static int P_FindWall(DukePlayer_t *pPlayer, int *hitWall)
|
2006-12-10 06:49:01 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
hitdata_t hitData;
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
hitscan((const vec3_t *)pPlayer, pPlayer->cursectnum, sintable[(fix16_to_int(pPlayer->q16ang) + 512) & 2047],
|
|
|
|
sintable[fix16_to_int(pPlayer->q16ang) & 2047], 0, &hitData, CLIPMASK0);
|
2016-08-27 01:40:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
*hitWall = hitData.wall;
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (hitData.wall < 0)
|
2012-02-14 23:14:07 +00:00
|
|
|
return INT32_MAX;
|
2009-01-13 12:23:18 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
return FindDistance2D(hitData.pos.x - pPlayer->pos.x, hitData.pos.y - pPlayer->pos.y);
|
2006-12-10 06:49:01 +00:00
|
|
|
}
|
|
|
|
|
2012-02-20 19:54:24 +00:00
|
|
|
// returns 1 if sprite i should not be considered by neartag
|
2017-01-01 13:23:29 +00:00
|
|
|
static int32_t our_neartag_blacklist(int32_t spriteNum)
|
2012-02-20 19:54:24 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
return sprite[spriteNum].picnum >= SECTOREFFECTOR__STATIC && sprite[spriteNum].picnum <= GPSPEED__STATIC;
|
2012-02-20 19:54:24 +00:00
|
|
|
}
|
2006-12-10 06:49:01 +00:00
|
|
|
|
2014-01-31 21:12:59 +00:00
|
|
|
static void G_ClearCameras(DukePlayer_t *p)
|
|
|
|
{
|
|
|
|
G_ClearCameraView(p);
|
|
|
|
|
|
|
|
if (I_EscapeTrigger())
|
|
|
|
I_EscapeTriggerClear();
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
void P_CheckSectors(int playerNum)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
DukePlayer_t *const pPlayer = g_player[playerNum].ps;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->cursectnum > -1)
|
2016-08-27 01:40:35 +00:00
|
|
|
{
|
|
|
|
sectortype *const pSector = §or[pPlayer->cursectnum];
|
2018-01-15 23:13:50 +00:00
|
|
|
switch ((uint16_t)pSector->lotag)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
case 32767:
|
|
|
|
pSector->lotag = 0;
|
|
|
|
P_DoQuote(QUOTE_FOUND_SECRET, pPlayer);
|
|
|
|
pPlayer->secret_rooms++;
|
|
|
|
return;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
case UINT16_MAX:
|
|
|
|
pSector->lotag = 0;
|
|
|
|
P_EndLevel();
|
|
|
|
return;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
case UINT16_MAX-1:
|
|
|
|
pSector->lotag = 0;
|
|
|
|
pPlayer->timebeforeexit = GAMETICSPERSEC * 8;
|
|
|
|
pPlayer->customexitsound = pSector->hitag;
|
|
|
|
return;
|
2014-01-31 21:12:55 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
default:
|
|
|
|
if (pSector->lotag >= 10000 && pSector->lotag < 16383)
|
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (playerNum == screenpeek || (g_gametypeFlags[ud.coop] & GAMETYPE_COOPSOUND))
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(pSector->lotag - 10000, pPlayer->i);
|
|
|
|
pSector->lotag = 0;
|
|
|
|
}
|
|
|
|
break;
|
2008-07-30 02:51:32 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
|
|
|
//After this point the the player effects the map with space
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->gm &MODE_TYPE || sprite[pPlayer->i].extra <= 0)
|
2014-01-31 21:12:55 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_OPEN))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (VM_OnEvent(EVENT_USE, pPlayer->i, playerNum) != 0)
|
2016-08-27 01:40:46 +00:00
|
|
|
g_player[playerNum].inputBits->bits &= ~BIT(SK_OPEN);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (ud.cashman && TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_OPEN))
|
2016-08-27 01:40:06 +00:00
|
|
|
A_SpawnMultiple(pPlayer->i, MONEY, 2);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->newowner >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:46 +00:00
|
|
|
if (klabs(g_player[playerNum].inputBits->svel) > 768 || klabs(g_player[playerNum].inputBits->fvel) > 768)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
G_ClearCameras(pPlayer);
|
2014-01-31 21:12:59 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (!TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_OPEN) && !TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_ESCAPE))
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->toggle_key_flag = 0;
|
|
|
|
else if (!pPlayer->toggle_key_flag)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int foundWall;
|
2014-01-31 21:12:59 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int16_t nearSector, nearWall, nearSprite;
|
|
|
|
int32_t nearDist;
|
2014-01-31 21:13:00 +00:00
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_ESCAPE))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->newowner >= 0)
|
|
|
|
G_ClearCameras(pPlayer);
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
nearSprite = -1;
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->toggle_key_flag = 1;
|
2016-08-27 01:42:01 +00:00
|
|
|
foundWall = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
int wallDist = P_FindWall(pPlayer, &foundWall);
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (foundWall >= 0 && wallDist < 1280 && wall[foundWall].overpicnum == MIRROR)
|
|
|
|
if (wall[foundWall].lotag > 0 && !A_CheckSoundPlaying(pPlayer->i,wall[foundWall].lotag) && playerNum == screenpeek)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
A_PlaySound(wall[foundWall].lotag,pPlayer->i);
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (foundWall >= 0 && (wall[foundWall].cstat&16))
|
|
|
|
if (wall[foundWall].lotag)
|
2014-01-31 21:12:56 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2018-03-07 04:21:18 +00:00
|
|
|
int const intang = fix16_to_int(pPlayer->oq16ang);
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->newowner >= 0)
|
2018-03-07 04:21:18 +00:00
|
|
|
neartag(pPlayer->opos.x, pPlayer->opos.y, pPlayer->opos.z, sprite[pPlayer->i].sectnum, intang, &nearSector,
|
2016-08-27 01:42:01 +00:00
|
|
|
&nearWall, &nearSprite, &nearDist, 1280, 1, our_neartag_blacklist);
|
2006-04-13 20:47:06 +00:00
|
|
|
else
|
|
|
|
{
|
2018-03-07 04:21:18 +00:00
|
|
|
neartag(pPlayer->pos.x, pPlayer->pos.y, pPlayer->pos.z, sprite[pPlayer->i].sectnum, intang, &nearSector,
|
2016-08-27 01:42:01 +00:00
|
|
|
&nearWall, &nearSprite, &nearDist, 1280, 1, our_neartag_blacklist);
|
|
|
|
if (nearSprite == -1 && nearWall == -1 && nearSector == -1)
|
2018-03-07 04:21:18 +00:00
|
|
|
neartag(pPlayer->pos.x, pPlayer->pos.y, pPlayer->pos.z+ZOFFSET3, sprite[pPlayer->i].sectnum, intang, &nearSector,
|
2016-08-27 01:42:01 +00:00
|
|
|
&nearWall, &nearSprite, &nearDist, 1280, 1, our_neartag_blacklist);
|
|
|
|
if (nearSprite == -1 && nearWall == -1 && nearSector == -1)
|
2018-03-07 04:21:18 +00:00
|
|
|
neartag(pPlayer->pos.x, pPlayer->pos.y, pPlayer->pos.z+ZOFFSET2, sprite[pPlayer->i].sectnum, intang, &nearSector,
|
2016-08-27 01:42:01 +00:00
|
|
|
&nearWall, &nearSprite, &nearDist, 1280, 1, our_neartag_blacklist);
|
|
|
|
if (nearSprite == -1 && nearWall == -1 && nearSector == -1)
|
|
|
|
{
|
2018-03-07 04:21:18 +00:00
|
|
|
neartag(pPlayer->pos.x, pPlayer->pos.y, pPlayer->pos.z+ZOFFSET2, sprite[pPlayer->i].sectnum, intang, &nearSector,
|
2016-08-27 01:42:01 +00:00
|
|
|
&nearWall, &nearSprite, &nearDist, 1280, 3, our_neartag_blacklist);
|
|
|
|
if (nearSprite >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(sprite[nearSprite].picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
case FEM1__STATIC:
|
|
|
|
case FEM2__STATIC:
|
|
|
|
case FEM3__STATIC:
|
|
|
|
case FEM4__STATIC:
|
|
|
|
case FEM5__STATIC:
|
|
|
|
case FEM6__STATIC:
|
|
|
|
case FEM7__STATIC:
|
|
|
|
case FEM8__STATIC:
|
|
|
|
case FEM9__STATIC:
|
|
|
|
case FEM10__STATIC:
|
|
|
|
case PODFEM1__STATIC:
|
|
|
|
case NAKED1__STATIC:
|
|
|
|
case STATUE__STATIC:
|
|
|
|
case TOUGHGAL__STATIC: return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
nearSprite = -1;
|
|
|
|
nearWall = -1;
|
|
|
|
nearSector = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (pPlayer->newowner == -1 && nearSprite == -1 && nearSector == -1 && nearWall == -1)
|
2016-08-27 01:40:35 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (isanunderoperator(sector[sprite[pPlayer->i].sectnum].lotag))
|
2016-08-27 01:42:01 +00:00
|
|
|
nearSector = sprite[pPlayer->i].sectnum;
|
2016-08-27 01:40:35 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (nearSector >= 0 && (sector[nearSector].lotag&16384))
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (nearSprite == -1 && nearWall == -1)
|
2016-08-27 01:40:35 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->cursectnum >= 0 && sector[pPlayer->cursectnum].lotag == 2)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (A_CheckHitSprite(pPlayer->i, &nearSprite) > 1280)
|
|
|
|
nearSprite = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (nearSprite >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (P_ActivateSwitch(playerNum, nearSprite, 1))
|
2014-01-31 21:12:55 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
switch (DYNAMICTILEMAP(sprite[nearSprite].picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2018-04-02 22:00:44 +00:00
|
|
|
#ifndef EDUKE32_STANDALONE
|
2006-11-16 03:02:42 +00:00
|
|
|
case TOILET__STATIC:
|
|
|
|
case STALL__STATIC:
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->last_pissed_time == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (ud.lockout == 0)
|
|
|
|
A_PlaySound(DUKE_URINATE, pPlayer->i);
|
|
|
|
|
|
|
|
pPlayer->last_pissed_time = GAMETICSPERSEC * 220;
|
|
|
|
pPlayer->transporter_hold = 29 * 2;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->holster_weapon == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->holster_weapon = 1;
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->weapon_pos = -1;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
|
|
|
|
if (sprite[pPlayer->i].extra <= (pPlayer->max_player_health - (pPlayer->max_player_health / 10)))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
sprite[pPlayer->i].extra += pPlayer->max_player_health / 10;
|
2016-08-27 01:40:06 +00:00
|
|
|
pPlayer->last_extra = sprite[pPlayer->i].extra;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if (sprite[pPlayer->i].extra < pPlayer->max_player_health)
|
|
|
|
sprite[pPlayer->i].extra = pPlayer->max_player_health;
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
else if (!A_CheckSoundPlaying(nearSprite,FLUSH_TOILET))
|
|
|
|
A_PlaySound(FLUSH_TOILET,nearSprite);
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case NUKEBUTTON__STATIC:
|
2014-01-31 21:12:56 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
int wallNum;
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
P_FindWall(pPlayer, &wallNum);
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
if (wallNum >= 0 && wall[wallNum].overpicnum == 0)
|
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (actor[nearSprite].t_data[0] == 0)
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2010-01-16 23:08:17 +00:00
|
|
|
if (ud.noexits && (g_netServer || ud.multimode > 1))
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2009-08-28 23:08:00 +00:00
|
|
|
// NUKEBUTTON frags the player
|
2016-08-27 01:40:06 +00:00
|
|
|
actor[pPlayer->i].picnum = NUKEBUTTON;
|
2016-08-27 01:40:35 +00:00
|
|
|
actor[pPlayer->i].extra = 250;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
else
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
actor[nearSprite].t_data[0] = 1;
|
|
|
|
sprite[nearSprite].owner = pPlayer->i;
|
2018-10-10 19:15:01 +00:00
|
|
|
// assignment of buttonpalette here is not a bug
|
2010-05-02 23:27:30 +00:00
|
|
|
ud.secretlevel =
|
2016-08-27 01:42:01 +00:00
|
|
|
(pPlayer->buttonpalette = sprite[nearSprite].pal) ? sprite[nearSprite].lotag : 0;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
}
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2014-01-31 21:12:56 +00:00
|
|
|
}
|
2009-08-28 23:08:00 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case WATERFOUNTAIN__STATIC:
|
2016-08-27 01:42:01 +00:00
|
|
|
if (actor[nearSprite].t_data[0] != 1)
|
2006-11-13 23:12:47 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
actor[nearSprite].t_data[0] = 1;
|
|
|
|
sprite[nearSprite].owner = pPlayer->i;
|
2006-11-15 01:16:55 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (sprite[pPlayer->i].extra < pPlayer->max_player_health)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
sprite[pPlayer->i].extra++;
|
|
|
|
A_PlaySound(DUKE_DRINKING,pPlayer->i);
|
2006-11-16 03:02:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
2009-08-28 23:08:00 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case PLUG__STATIC:
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(SHORT_CIRCUIT, pPlayer->i);
|
2016-08-27 01:40:06 +00:00
|
|
|
sprite[pPlayer->i].extra -= 2+(krand()&3);
|
2012-05-05 22:24:50 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
P_PalFrom(pPlayer, 32, 48,48,64);
|
2006-11-16 03:02:42 +00:00
|
|
|
break;
|
2018-04-02 22:00:44 +00:00
|
|
|
#endif
|
2009-08-28 23:08:00 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
case VIEWSCREEN__STATIC:
|
|
|
|
case VIEWSCREEN2__STATIC:
|
2012-11-10 14:11:07 +00:00
|
|
|
// Try to find a camera sprite for the viewscreen.
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF(STAT_ACTOR, spriteNum))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (PN(spriteNum) == CAMERA1 && SP(spriteNum) == 0 && sprite[nearSprite].hitag == SLT(spriteNum))
|
2006-11-16 03:02:42 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
sprite[spriteNum].yvel = 1; // Using this camera
|
|
|
|
A_PlaySound(MONITOR_ACTIVE, pPlayer->i);
|
|
|
|
sprite[nearSprite].owner = spriteNum;
|
|
|
|
sprite[nearSprite].yvel = 1; // VIEWSCREEN_YVEL
|
|
|
|
g_curViewscreen = nearSprite;
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:40:35 +00:00
|
|
|
int const playerSectnum = pPlayer->cursectnum;
|
|
|
|
pPlayer->cursectnum = SECT(spriteNum);
|
2018-10-10 19:15:33 +00:00
|
|
|
P_UpdateScreenPal(pPlayer);
|
2016-08-27 01:40:35 +00:00
|
|
|
pPlayer->cursectnum = playerSectnum;
|
|
|
|
pPlayer->newowner = spriteNum;
|
2012-11-10 14:11:07 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
P_UpdatePosWhenViewingCam(pPlayer);
|
2012-11-10 14:11:07 +00:00
|
|
|
|
2006-11-16 03:02:42 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
G_ClearCameras(pPlayer);
|
2014-01-31 21:12:59 +00:00
|
|
|
return;
|
2014-01-31 21:12:55 +00:00
|
|
|
} // switch
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
|
2016-08-27 01:40:46 +00:00
|
|
|
if (TEST_SYNC_KEY(g_player[playerNum].inputBits->bits, SK_OPEN) == 0)
|
2014-01-31 21:12:56 +00:00
|
|
|
return;
|
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
if (pPlayer->newowner >= 0)
|
2006-11-15 01:16:55 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
G_ClearCameras(pPlayer);
|
2014-01-31 21:12:59 +00:00
|
|
|
return;
|
2006-11-15 01:16:55 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (nearWall == -1 && nearSector == -1 && nearSprite == -1)
|
2016-08-27 01:40:35 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (klabs(A_GetHitscanRange(pPlayer->i)) < 512)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
A_PlaySound(((krand()&255) < 16) ? DUKE_SEARCH2 : DUKE_SEARCH, pPlayer->i);
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-08-27 01:40:35 +00:00
|
|
|
}
|
2006-04-13 20:47:06 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (nearWall >= 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (wall[nearWall].lotag > 0 && CheckDoorTile(wall[nearWall].picnum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
if (foundWall == nearWall || foundWall == -1)
|
|
|
|
P_ActivateSwitch(playerNum,nearWall,0);
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
if (nearSector >= 0 && (sector[nearSector].lotag&16384) == 0 &&
|
|
|
|
isanearoperator(sector[nearSector].lotag))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:42:01 +00:00
|
|
|
for (bssize_t SPRITES_OF_SECT(nearSector, spriteNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PN(spriteNum) == ACTIVATOR || PN(spriteNum) == MASTERSWITCH)
|
2006-04-13 20:47:06 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:42:01 +00:00
|
|
|
G_OperateSectors(nearSector,pPlayer->i);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:40:06 +00:00
|
|
|
else if ((sector[sprite[pPlayer->i].sectnum].lotag&16384) == 0)
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:06 +00:00
|
|
|
if (isanunderoperator(sector[sprite[pPlayer->i].sectnum].lotag))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:41:21 +00:00
|
|
|
for (bssize_t SPRITES_OF_SECT(sprite[pPlayer->i].sectnum, spriteNum))
|
2006-04-13 20:47:06 +00:00
|
|
|
{
|
2016-08-27 01:40:35 +00:00
|
|
|
if (PN(spriteNum) == ACTIVATOR || PN(spriteNum) == MASTERSWITCH)
|
2014-01-31 21:12:56 +00:00
|
|
|
return;
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2014-01-31 21:12:56 +00:00
|
|
|
|
2016-08-27 01:40:06 +00:00
|
|
|
G_OperateSectors(sprite[pPlayer->i].sectnum,pPlayer->i);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
2016-08-27 01:42:01 +00:00
|
|
|
else P_ActivateSwitch(playerNum,nearWall,0);
|
2006-04-13 20:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|