Merge remote-tracking branch 'origin/master' into next

This commit is contained in:
yellowtd 2014-08-28 19:18:46 -04:00
commit 4c6d26117b
25 changed files with 532 additions and 379 deletions

View file

@ -1,4 +1,4 @@
Here it is! SRB2 v2.1.10 source code!
Here it is! SRB2 v2.1.11 source code!
(why do we keep the version number up to date
when everything else in this file is hilariously old?
- Inuyasha)

View file

@ -1320,14 +1320,6 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
if (!var || !var->string || !value || !stricmp(var->string, value))
return; // no changes
// Don't allow skin/color changes in single player
if ((var == &cv_skin || var == &cv_playercolor) &&
!(cv_debug || devparm) && !(multiplayer || netgame)
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION))
{
return;
}
if (var->flags & CV_NETVAR)
{
// send the value of the variable

View file

@ -79,8 +79,6 @@ char motd[254], server_context[8]; // Message of the Day, Unique Context (even w
// server specific vars
UINT8 playernode[MAXPLAYERS];
UINT8 consfailcount[MAXPLAYERS];
UINT8 consfailstatus[MAXPLAYERS];
#ifdef NEWPING
UINT16 pingmeasurecount = 1;
@ -944,6 +942,14 @@ static void SV_SendResynch(INT32 node)
{
INT32 i, j;
if (!nodeingame[node])
{
// player left during resynch
// so obviously we don't need to do any of this anymore
resynch_inprogress[node] = false;
return;
}
// resynched?
if (!resynch_status[node])
{
@ -2213,6 +2219,9 @@ static void CL_RemovePlayer(INT32 playernum)
playerpernode[node]--;
if (playerpernode[node] <= 0)
{
// If a resynch was in progress, well, it no longer needs to be.
SV_InitResynchVars(playernode[playernum]);
nodeingame[playernode[playernum]] = false;
Net_CloseConnection(playernode[playernum]);
ResetNode(node);
@ -2270,9 +2279,6 @@ static void CL_RemovePlayer(INT32 playernum)
if (playernum == displayplayer)
displayplayer = consoleplayer; // don't look through someone's view who isn't there
consfailcount[playernum] = 0;
consfailstatus[playernum] = 0;
#ifdef HAVE_BLUA
LUA_InvalidatePlayer(&players[playernum]);
#endif
@ -2753,8 +2759,13 @@ void SV_ResetServer(void)
tictoclear = maketic;
for (i = 0; i < MAXNETNODES; i++)
{
ResetNode(i);
// Make sure resynch status doesn't get carried over!
SV_InitResynchVars(i);
}
for (i = 0; i < MAXPLAYERS; i++)
{
#ifdef HAVE_BLUA

View file

@ -496,7 +496,6 @@ SINT8 nametonum(const char *name);
extern char motd[254], server_context[8];
extern UINT8 playernode[MAXPLAYERS];
extern UINT8 consfailcount[MAXPLAYERS];
INT32 D_NumPlayers(void);
void D_ResetTiccmds(void);

View file

@ -1091,10 +1091,10 @@ void D_SRB2Main(void)
// Check MD5s of autoloaded files
W_VerifyFileMD5(0, "ac309fb3c7d4b5b685e2cd26beccf0e8"); // srb2.srb/srb2.wad
W_VerifyFileMD5(1, "e956466eff2c79f7b1cdefad24761bce"); // zones.dta
W_VerifyFileMD5(2, "95a4cdbed287323dd361243f357a5fd2"); // player.dta
W_VerifyFileMD5(1, "f39b6c849295e3c81875726e8cc0e2c7"); // zones.dta
W_VerifyFileMD5(2, "cfca0f1c73023cbbd8f844f45480f799"); // player.dta
W_VerifyFileMD5(3, "85901ad4bf94637e5753d2ac2c03ea26"); // rings.dta
W_VerifyFileMD5(4, "01735733412bf68c42f4669e964fc952"); // patch.dta
W_VerifyFileMD5(4, "3d6cfc185fd7c195eb934ce593b0248f"); // patch.dta
// don't check music.dta because people like to modify it, and it doesn't matter if they do
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#endif
@ -1146,7 +1146,6 @@ void D_SRB2Main(void)
wipegamestate = gamestate;
P_InitMapHeaders();
savedata.lives = 0; // flag this as not-used
//------------------------------------------------ COMMAND LINE PARAMS

View file

@ -3177,15 +3177,16 @@ static void Command_ListWADS_f(void)
INT32 i = numwadfiles;
char *tempname;
CONS_Printf(M_GetText("There are %d wads loaded:\n"),numwadfiles);
for (i--; i; i--)
for (i--; i >= 0; i--)
{
nameonly(tempname = va("%s", wadfiles[i]->filename));
if (i >= mainwads)
CONS_Printf(" %.2d: %s\n", i, tempname);
if (!i)
CONS_Printf("\x82 IWAD\x80: %s\n", tempname);
else if (i <= mainwads)
CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname);
else
CONS_Printf("* %.2d: %s\n", i, tempname);
CONS_Printf(" %.2d: %s\n", i, tempname);
}
CONS_Printf(" IWAD: %s\n", wadfiles[0]->filename);
}
// =========================================================================
@ -4032,6 +4033,16 @@ static void Name2_OnChange(void)
*/
static void Skin_OnChange(void)
{
if (!Playing())
return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING))
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
SendNameAndColor();
else
@ -4048,6 +4059,9 @@ static void Skin_OnChange(void)
*/
static void Skin2_OnChange(void)
{
if (!Playing() || !splitscreen)
return; // do whatever you want
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
SendNameAndColor2();
else
@ -4063,6 +4077,16 @@ static void Skin2_OnChange(void)
*/
static void Color_OnChange(void)
{
if (!Playing())
return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING))
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
if (!P_PlayerMoving(consoleplayer))
{
// Color change menu scrolling fix is no longer necessary
@ -4082,6 +4106,9 @@ static void Color_OnChange(void)
*/
static void Color2_OnChange(void)
{
if (!Playing() || !splitscreen)
return; // do whatever you want
if (!P_PlayerMoving(secondarydisplayplayer))
{
// Color change menu scrolling fix is no longer necessary

View file

@ -144,8 +144,8 @@ extern FILE *logstream;
#define VERSIONSTRING "Trunk"
#else
#define VERSION 201 // Game version
#define SUBVERSION 10 // more precise version number
#define VERSIONSTRING "v2.1.10"
#define SUBVERSION 11 // more precise version number
#define VERSIONSTRING "v2.1.11"
#endif
// Modification options
@ -201,7 +201,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 15
#define MODVERSION 16

View file

@ -148,8 +148,8 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
}
fm.xscale = FixedDiv(fm.width<<FRACBITS, vid.width<<FRACBITS);
fm.yscale = FixedDiv(fm.height<<FRACBITS, vid.height<<FRACBITS);
fm.xscale = FixedDiv(vid.width<<FRACBITS, fm.width<<FRACBITS);
fm.yscale = FixedDiv(vid.height<<FRACBITS, fm.height<<FRACBITS);
return &fm;
// Landing point for freeing data -- do this instead of just returning NULL
@ -172,13 +172,6 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
*/
static void F_DoWipe(fademask_t *fademask)
{
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
UINT8 transval;
INT32 x = 0, y = 0;
#ifdef HWRENDER
/// \todo Mask wipes for OpenGL
if(rendermode != render_soft)
@ -187,29 +180,99 @@ static void F_DoWipe(fademask_t *fademask)
return;
}
#endif
// Software mask wipe
do
{
if (*s != *e)
{
transval = fademask->mask[ // y*width + x
(FixedMul(y<<FRACBITS,fademask->yscale)>>FRACBITS)*fademask->width
+ (FixedMul(x<<FRACBITS,fademask->xscale)>>FRACBITS)
];
if (transval == 0)
*w = *s;
else if (transval == 10)
*w = *e;
else
*w = transtables[(*e<<8) + *s + ((9 - transval)<<FF_TRANSSHIFT)];
}
if (++x >= vid.width)
// Software mask wipe -- optimized; though it might not look like it!
// Okay, to save you wondering *how* this is more optimized than the simpler
// version that came before it...
// ---
// The previous code did two FixedMul calls for every single pixel on the
// screen, of which there are hundreds of thousands -- if not millions -- of.
// This worked fine for smaller screen sizes, but with excessively large
// (1920x1200) screens that meant 4 million+ calls out to FixedMul, and that
// would take /just/ long enough that fades would start to noticably lag.
// ---
// This code iterates over the fade mask's pixels instead of the screen's,
// and deals with drawing over each rectangular area before it moves on to
// the next pixel in the fade mask. As a result, it's more complex (and might
// look a little messy; sorry!) but it simultaneously runs at twice the speed.
// In addition, we precalculate all the X and Y positions that we need to draw
// from and to, so it uses a little extra memory, but again, helps it run faster.
{
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
// first pixel for each screen
UINT8 *w_base = w;
const UINT8 *s_base = s;
const UINT8 *e_base = e;
// mask data, end
UINT8 *transtbl;
const UINT8 *mask = fademask->mask;
const UINT8 *maskend = mask + fademask->size;
// rectangle draw hints
UINT32 draw_linestart, draw_rowstart;
UINT32 draw_lineend, draw_rowend;
UINT32 draw_linestogo, draw_rowstogo;
// rectangle coordinates, etc.
UINT16 scrxpos[fademask->width + 1];
UINT16 scrypos[fademask->height + 1];
UINT16 maskx, masky;
UINT32 relativepos;
// ---
// Screw it, we do the fixed point math ourselves up front.
scrxpos[0] = 0;
for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx)
scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS;
scrxpos[fademask->width] = vid.width;
scrypos[0] = 0;
for (relativepos = 0, masky = 1; masky < fademask->height; ++masky)
scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS;
scrypos[fademask->height] = vid.height;
// ---
maskx = masky = 0;
do
{
x = 0;
++y;
}
} while (++w && ++s && ++e && w < wipe_scr + vid.width*vid.height);
// pointer to transtable that this mask would use
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
// (ignore that it goes out of bounds if *mask is 0 or 10 --
// it wouldn't be used in those cases anyway)
draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
// DRAWING LOOP
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
while (draw_linestogo--)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
{
if (*s != *e)
*w = ((*mask == 0) ? *s : (*mask == 10) ? *e : transtbl[(*e<<8) + *s]);
++w, ++s, ++e;
}
relativepos += vid.width;
}
// END DRAWING LOOP
if (++maskx >= fademask->width)
++masky, maskx = 0;
} while (++mask < maskend);
}
}
#endif

View file

@ -3376,7 +3376,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
sSurf.FlatColor.s.blue = 0x00;
sSurf.FlatColor.s.green = 0x00;
if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
/*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
{
sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = sector->lightlevel;
@ -3406,15 +3406,25 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
else
sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
}*/
// shadow is always half as translucent as the sprite itself
if (spr->mobj->flags2 & MF2_SHADOW)
sSurf.FlatColor.s.alpha = 0x20;
else if (spr->mobj->frame & FF_TRANSMASK)
{
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
sSurf.FlatColor.s.alpha /= 2; //cut alpha in half!
}
Surf.FlatColor.rgba = NORMALFOG;
else
sSurf.FlatColor.s.alpha = 0x80; // default
/// \todo do the test earlier
if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f) || (md2_models[spr->mobj->sprite].notfound = true) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound = true))
{
if (0x80 > floorheight/4)
if (sSurf.FlatColor.s.alpha > floorheight/4)
{
sSurf.FlatColor.s.alpha = (UINT8)(0x80 - floorheight/4);
sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4);
HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
}
}
@ -4460,6 +4470,12 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
{
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
FTransform stransform;
postimg_t *type;
if (splitscreen && player == &players[secondarydisplayplayer])
type = &postimgtype2;
else
type = &postimgtype;
{
// do we really need to save player (is it not the same)?
@ -4508,7 +4524,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
if (postimgtype == postimg_flip)
if (*type == postimg_flip)
atransform.flip = true;
else
atransform.flip = false;
@ -4527,7 +4543,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
stransform.anglex = 0.0f;
stransform.angley = -270.0f;
if (postimgtype == postimg_flip)
if (*type == postimg_flip)
stransform.flip = true;
else
stransform.flip = false;
@ -4669,11 +4685,17 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
{
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
FTransform stransform;
postimg_t *type;
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
FRGBAFloat ClearColor;
if (splitscreen && player == &players[secondarydisplayplayer])
type = &postimgtype2;
else
type = &postimgtype;
ClearColor.red = 0.0f;
ClearColor.green = 0.0f;
ClearColor.blue = 0.0f;
@ -4732,7 +4754,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
if (postimgtype == postimg_flip)
if (*type == postimg_flip)
atransform.flip = true;
else
atransform.flip = false;
@ -4751,7 +4773,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
stransform.anglex = 0.0f;
stransform.angley = -270.0f;
if (postimgtype == postimg_flip)
if (*type == postimg_flip)
stransform.flip = true;
else
stransform.flip = false;
@ -5298,6 +5320,13 @@ INT32 HWR_GetTextureUsed(void)
void HWR_DoPostProcessor(player_t *player)
{
postimg_t *type;
if (splitscreen && player == &players[secondarydisplayplayer])
type = &postimgtype2;
else
type = &postimgtype;
// Armageddon Blast Flash!
// Could this even be considered postprocessor?
if (player->flashcount)
@ -5332,7 +5361,7 @@ void HWR_DoPostProcessor(player_t *player)
#ifdef SHUFFLE
// Drunken vision! WooOOooo~
if (postimgtype == postimg_water || postimgtype == postimg_heat)
if (*type == postimg_water || *type == postimg_heat)
{
// 10 by 10 grid. 2 coordinates (xy)
float v[SCREENVERTS][SCREENVERTS][2];
@ -5343,7 +5372,7 @@ void HWR_DoPostProcessor(player_t *player)
INT32 FREQUENCY;
// Modifies the wave.
if (postimgtype == postimg_water)
if (*type == postimg_water)
{
WAVELENGTH = 20; // Lower is longer
AMPLITUDE = 20; // Lower is bigger

View file

@ -165,12 +165,11 @@ static const char *const camera_opt[] = {
static int lib_getHudInfo(lua_State *L)
{
// arg 1 is empty table with this metatable set
lua_Integer mindex = luaL_checkinteger(L,2);
hudinfo_t **userdata = lua_newuserdata(L, sizeof(hudinfo_t *));
luaL_getmetatable(L, META_HUDINFO);
lua_setmetatable(L, -2);
*userdata = &hudinfo[mindex];
UINT32 i;
lua_remove(L, 1);
i = luaL_checkinteger(L, 1);
LUA_PushUserdata(L, &hudinfo[i], META_HUDINFO);
return 1;
}

View file

@ -635,7 +635,7 @@ static int power_set(lua_State *L)
if (hud_running)
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
powers[p] = i;
return 1;
return 0;
}
// #powers -> NUMPOWERS

View file

@ -512,9 +512,9 @@ emblem_t emblemlocations[MAXEMBLEMS] =
// FLOODED COVE
// ---
{0, -1888, -1440, 2448, 52, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0},
{0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0},
// CAVERN FORTRESS

View file

@ -4452,8 +4452,6 @@ static void M_ReadSavegameInfo(UINT32 slot)
savegameinfo[slot].skincolor = READUINT8(save_p);
CHECKPOS
savegameinfo[slot].skinnum = READUINT8(save_p);
strcpy(savegameinfo[slot].playername,
skins[savegameinfo[slot].skinnum].name);
CHECKPOS
(void)READINT32(save_p); // Score
@ -4463,18 +4461,27 @@ static void M_ReadSavegameInfo(UINT32 slot)
CHECKPOS
savegameinfo[slot].continues = READINT32(save_p); // continues
if (fake & (1<<10)) {
if (fake & (1<<10))
{
CHECKPOS
savegameinfo[slot].botskin = READUINT8(save_p);
if (savegameinfo[slot].botskin-1 < numskins)
snprintf(savegameinfo[slot].playername, 24, "%s & %s", savegameinfo[slot].playername, skins[savegameinfo[slot].botskin-1].name);
else
if (savegameinfo[slot].botskin-1 >= numskins)
savegameinfo[slot].botskin = 0;
CHECKPOS
savegameinfo[slot].botcolor = READUINT8(save_p); // because why not.
} else
}
else
savegameinfo[slot].botskin = 0;
if (savegameinfo[slot].botskin)
snprintf(savegameinfo[slot].playername, 32, "%s & %s",
skins[savegameinfo[slot].skinnum].realname,
skins[savegameinfo[slot].botskin-1].realname);
else
strcpy(savegameinfo[slot].playername, skins[savegameinfo[slot].skinnum].realname);
savegameinfo[slot].playername[31] = 0;
// File end marker check
CHECKPOS
if (READUINT8(save_p) != 0x1d) BADSAVE;

View file

@ -190,7 +190,7 @@ typedef struct
// savegame struct for save game menu
typedef struct
{
char playername[24];
char playername[32];
char levelname[32];
UINT8 actnum;
UINT8 skincolor;

View file

@ -2118,6 +2118,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
case MT_JETTGUNNER:
case MT_CRAWLACOMMANDER:
case MT_REDBUZZ:
case MT_DETON:
item = MT_MOUSE;
break;

View file

@ -888,6 +888,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height + tmthing->momz >= thing->z
&& tmthing->z + tmthing->height + tmthing->momz < thing->z + thing->height
&& P_IsObjectOnGround(thing)
&& !P_IsObjectOnGround(tmthing) // Don't crush if the monitor is on the ground...
&& (tmthing->flags & MF_SOLID))
{
if (tmthing->flags & (MF_MONITOR|MF_PUSHABLE))
@ -941,6 +942,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->momz <= thing->z + thing->height
&& tmthing->z + tmthing->momz > thing->z
&& P_IsObjectOnGround(thing)
&& !P_IsObjectOnGround(tmthing) // Don't crush if the monitor is on the ground...
&& (tmthing->flags & MF_SOLID))
{
if (tmthing->flags & (MF_MONITOR|MF_PUSHABLE))
@ -1084,6 +1086,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
return false;
}
/*
else if ((thing->flags & (MF_SOLID|MF_NOCLIP|MF_PUSHABLE)) == MF_SOLID)
return false; // this fixes both monitors and non-pushable solids being walked through on bobbing FOFs... for now!
*/
}
}

View file

@ -672,6 +672,9 @@ void P_ExplodeMissile(mobj_t *mo)
explodemo->momx -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_cybdth);
// Hack: Release an animal.
P_DamageMobj(mo, NULL, NULL, 10000);
}
mo->flags &= ~MF_MISSILE;

View file

@ -161,7 +161,7 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
/** Clears the data from a single map header.
*
* \param i Map number to clear header for.
* \sa P_ClearMapHeaderInfo, P_LoadMapHeader
* \sa P_ClearMapHeaderInfo
*/
static void P_ClearSingleMapHeaderInfo(INT16 i)
{
@ -241,62 +241,6 @@ void P_AllocMapHeader(INT16 i)
P_ClearSingleMapHeaderInfo(i + 1);
}
/** Initializes the map headers.
* Only new, Dehacked format map headers (MAPxxD) are loaded here. Old map
* headers (MAPxxN) are no longer supported.
*
* \sa P_ClearMapHeaderInfo, P_LoadMapHeader
*/
void P_InitMapHeaders(void)
{
char mapheader[7];
lumpnum_t lumpnum;
INT32 mapnum;
// Make sure that the map header is valid for the
// initial value of gamemap
if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
for (mapnum = 1; mapnum <= NUMMAPS; mapnum++)
{
strncpy(mapheader, G_BuildMapName(mapnum), 5);
mapheader[5] = 'D'; // New header
mapheader[6] = '\0';
lumpnum = W_CheckNumForName(mapheader);
if (!(lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0))
DEH_LoadDehackedLump(lumpnum);
}
}
/** Sets up the data in a single map header.
*
* \param mapnum Map number to load header for.
* \sa P_ClearSingleMapHeaderInfo, P_InitMapHeaders
*/
static inline void P_LoadMapHeader(INT16 mapnum)
{
char mapheader[7];
lumpnum_t lumpnum;
strncpy(mapheader, G_BuildMapName(mapnum), 5);
mapheader[5] = 'D'; // New header
mapheader[6] = '\0';
lumpnum = W_CheckNumForName(mapheader);
if (!(lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0))
{
DEH_LoadDehackedLump(lumpnum);
return;
}
}
/** NiGHTS Grades are a special structure,
* we initialize them here.
*
@ -1418,53 +1362,38 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
{
col = msd->toptexture;
sec->extra_colormap->rgba =
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
// alpha
if (msd->toptexture[7])
{
sec->extra_colormap->rgba =
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16) +
(ALPHA2INT(col[7]) << 24);
}
sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24);
else
{
sec->extra_colormap->rgba =
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16) +
(25 << 24);
}
sec->extra_colormap->rgba += (25 << 24);
}
else
{
sec->extra_colormap->rgba = 0;
}
if (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])
{
col = msd->bottomtexture;
sec->extra_colormap->fadergba =
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
// alpha
if (msd->bottomtexture[7])
{
sec->extra_colormap->fadergba =
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16) +
(ALPHA2INT(col[7]) << 24);
}
sec->extra_colormap->fadergba += (ALPHA2INT(col[7]) << 24);
else
{
sec->extra_colormap->fadergba =
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16) +
(25 << 24);
}
sec->extra_colormap->fadergba += (25 << 24);
}
else
{
sec->extra_colormap->fadergba = 0x19000000;
}
#undef ALPHA2INT
#undef HEX2INT
}
@ -2278,6 +2207,140 @@ static void P_MakeMapMD5(lumpnum_t maplumpnum, void *dest)
M_Memcpy(dest, &resmd5, 16);
}
static void P_RunLevelScript(const char *scriptname)
{
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_SCRIPTISFILE))
{
lumpnum_t lumpnum;
char newname[9];
strncpy(newname, scriptname, 8);
newname[8] = '\0';
lumpnum = W_CheckNumForName(newname);
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
{
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
return;
}
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
}
else
{
COM_BufAddText(va("exec %s\n", scriptname));
}
COM_BufExecute(); // Run it!
}
static void P_ForceCharacter(const char *forcecharskin)
{
if (netgame)
{
char skincmd[33];
if (splitscreen)
{
sprintf(skincmd, "skin2 %s\n", forcecharskin);
CV_Set(&cv_skin2, forcecharskin);
}
sprintf(skincmd, "skin %s\n", forcecharskin);
COM_BufAddText(skincmd);
}
else
{
if (splitscreen)
{
SetPlayerSkin(secondarydisplayplayer, forcecharskin);
if ((unsigned)cv_playercolor2.value != skins[players[secondarydisplayplayer].skin].prefcolor)
{
CV_StealthSetValue(&cv_playercolor2, skins[players[secondarydisplayplayer].skin].prefcolor);
players[secondarydisplayplayer].skincolor = skins[players[secondarydisplayplayer].skin].prefcolor;
}
}
SetPlayerSkin(consoleplayer, forcecharskin);
// normal player colors in single player
if ((unsigned)cv_playercolor.value != skins[players[consoleplayer].skin].prefcolor)
{
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
players[consoleplayer].skincolor = skins[players[consoleplayer].skin].prefcolor;
}
}
}
static void P_LoadRecordGhosts(void)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath = malloc(glen);
INT32 i;
if (!gpath)
return;
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
// Best Score ghost
if (cv_ghost_bestscore.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name));
}
}
// Best Time ghost
if (cv_ghost_besttime.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name));
}
}
// Best Rings ghost
if (cv_ghost_bestrings.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_bestrings.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-rings-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-rings-best.lmp", gpath, skins[i].name));
}
}
// Last ghost
if (cv_ghost_last.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name));
}
}
// Guest ghost
if (cv_ghost_guest.value && FIL_FileExists(va("%s-guest.lmp", gpath)))
G_AddGhost(va("%s-guest.lmp", gpath));
free(gpath);
}
/** Loads a level from a lump or external wad.
*
* \param skipprecip If true, don't spawn precipitation.
@ -2329,33 +2392,7 @@ boolean P_SetupLevel(boolean skipprecip)
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#')
{
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_SCRIPTISFILE))
{
lumpnum_t lumpnum;
char newname[9];
strncpy(newname, mapheaderinfo[gamemap-1]->scriptname, 8);
newname[8] = '\0';
lumpnum = W_CheckNumForName(newname);
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
{
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
goto noscript;
}
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
}
else
{
COM_BufAddText(va("exec %s\n", mapheaderinfo[gamemap-1]->scriptname));
}
COM_BufExecute(); // Run it!
}
noscript:
P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname);
P_LevelInitStuff();
@ -2363,40 +2400,7 @@ noscript:
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
{
if (netgame)
{
char skincmd[33];
if (splitscreen)
{
sprintf(skincmd, "skin2 %s\n", mapheaderinfo[gamemap-1]->forcecharacter);
CV_Set(&cv_skin2, mapheaderinfo[gamemap-1]->forcecharacter);
}
sprintf(skincmd, "skin %s\n", mapheaderinfo[gamemap-1]->forcecharacter);
COM_BufAddText(skincmd);
}
else
{
if (splitscreen)
{
SetPlayerSkin(secondarydisplayplayer, mapheaderinfo[gamemap-1]->forcecharacter);
if ((unsigned)cv_playercolor2.value != skins[players[secondarydisplayplayer].skin].prefcolor)
{
CV_StealthSetValue(&cv_playercolor2, skins[players[secondarydisplayplayer].skin].prefcolor);
players[secondarydisplayplayer].skincolor = skins[players[secondarydisplayplayer].skin].prefcolor;
}
}
SetPlayerSkin(consoleplayer, mapheaderinfo[gamemap-1]->forcecharacter);
// normal player colors in single player
if ((unsigned)cv_playercolor.value != skins[players[consoleplayer].skin].prefcolor)
{
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
players[consoleplayer].skincolor = skins[players[consoleplayer].skin].prefcolor;
}
}
}
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
// chasecam on in chaos, race, coop
// chasecam off in match, tag, capture the flag
@ -2408,11 +2412,7 @@ noscript:
if (!dedicated)
{
if (maptol & TOL_2D)
{
CV_SetValue(&cv_cam_speed, 0);
}
else if (!cv_cam_speed.changed && !(maptol & TOL_2D))
if (!cv_cam_speed.changed)
CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);
if (!cv_chasecam.changed)
@ -2601,72 +2601,7 @@ noscript:
}
if (modeattacking == ATTACKING_RECORD && !demoplayback)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath = malloc(glen);
if (gpath)
{
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
// Best Score ghost
if (cv_ghost_bestscore.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name));
}
}
// Best Time ghost
if (cv_ghost_besttime.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name));
}
}
// Best Rings ghost
if (cv_ghost_bestrings.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_bestrings.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-rings-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-rings-best.lmp", gpath, skins[i].name));
}
}
// Last ghost
if (cv_ghost_last.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name));
}
}
// Guest ghost
if (cv_ghost_guest.value && FIL_FileExists(va("%s-guest.lmp", gpath)))
G_AddGhost(va("%s-guest.lmp", gpath));
free(gpath);
}
}
P_LoadRecordGhosts();
if (G_TagGametype())
{
@ -2988,17 +2923,14 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{
if (name[5]!='\0')
continue;
num = (INT16)M_MapNumber(name[3], name[4]);
//If you replaced the map you're on, end the level when done.
if (num == gamemap)
replacedcurrentmap = true;
if (name[5] == 'D')
P_LoadMapHeader(num);
else if (name[5]!='\0')
continue;
CONS_Printf("%s\n", name);
}

View file

@ -64,7 +64,6 @@ boolean P_DelWadFile(void);
boolean P_RunSOC(const char *socfilename);
void P_WriteThings(lumpnum_t lump);
size_t P_PrecacheLevelFlats(void);
void P_InitMapHeaders(void);
void P_AllocMapHeader(INT16 i);
// Needed for NiGHTS

View file

@ -1852,18 +1852,17 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
}
}
// Special type 308, 307, 302, 304, 315, 318, and 320 only work once
if (specialtype == 302 || specialtype == 304 || specialtype == 307 || specialtype == 308 || specialtype == 315 || specialtype == 318 || specialtype == 320)
{
// These special types work only once
if (specialtype == 302 // Once
|| specialtype == 304 // Ring count - Once
|| specialtype == 307 // Character ability - Once
|| specialtype == 308 // Race only - Once
|| specialtype == 315 // No of pushables - Once
|| specialtype == 318 // Unlockable trigger - Once
|| specialtype == 320 // Unlockable - Once
|| specialtype == 399) // Level Load
triggerline->special = 0; // Clear it out
// Hmm, I'm thinking that we shouldn't touch the sector special, incase
// we have continuous executors associated with it, too?
/*
if (caller && (GETSECSPECIAL(caller->special, 2) >= 1 && GETSECSPECIAL(caller->special, 2) <= 7))
caller->special = (UINT16)(caller->special-(GETSECSPECIAL(caller->special, 2) << 4)); // Only remove the relevant section
*/
}
return true;
}
@ -1893,13 +1892,14 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
if (lines[masterline].tag != tag)
continue;
// "No More Enemies" takes care of itself.
// "No More Enemies" and "Level Load" take care of themselves.
if (lines[masterline].special == 313
// Each-time exectors handle themselves, too
|| lines[masterline].special == 301
|| lines[masterline].special == 306
|| lines[masterline].special == 310
|| lines[masterline].special == 312)
|| lines[masterline].special == 399
// Each-time executors handle themselves, too
|| lines[masterline].special == 301 // Each time
|| lines[masterline].special == 306 // Character ability - Each time
|| lines[masterline].special == 310 // CTF Red team - Each time
|| lines[masterline].special == 312) // CTF Blue team - Each time
continue;
if (lines[masterline].special < 300
@ -3323,12 +3323,79 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
}
//
// P_ShouldObjectBeDamaged
// P_ThingIsOnThe3DFloor
//
// Checks for conditions that a mobj should be damaged by
// floor touch/anywhere-in-FOF damage specials.
// This checks whether the mobj is on/in the FOF we want it to be at
// Needed for the "All players" trigger sector specials only
//
#define P_ShouldObjectBeDamaged(mo,roversector) (roversector || P_IsObjectOnGround(mo))
static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec)
{
ffloor_t *rover;
if (!mo->player) // should NEVER happen
return false;
if (!targetsec->ffloors) // also should NEVER happen
return false;
for (rover = targetsec->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector != sector)
continue;
// we're assuming the FOF existed when the first player touched it
//if (!(rover->flags & FF_EXISTS))
// return false;
// Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER)
{
// Thing must be on top of the floor to be affected...
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight)
return false;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(mo->eflags & MFE_VERTICALFLIP)
|| mo->z + mo->height != *rover->bottomheight)
return false;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight)
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight)))
return false;
}
}
else
{
// Water and intangible FOFs
if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight)
return false;
}
return true;
}
return false;
}
//
// P_MobjReadyToTrigger
//
// Is player standing on the sector's "ground"?
//
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
{
if (mo->eflags & MFE_VERTICALFLIP)
return (mo->z+mo->height == sec->ceilingheight);
else
return (mo->z == sec->floorheight);
}
/** Applies a sector special to a player.
*
@ -3370,19 +3437,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
switch (special)
{
case 1: // Damage (Generic)
if (P_ShouldObjectBeDamaged(player->mo, roversector))
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 1);
break;
case 2: // Damage (Water)
if (P_ShouldObjectBeDamaged(player->mo, roversector) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_underwater] || player->pflags & PF_NIGHTSMODE) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
P_DamageMobj(player->mo, NULL, NULL, 1);
break;
case 3: // Damage (Fire)
if (P_ShouldObjectBeDamaged(player->mo, roversector) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ELEMENTAL)
P_DamageMobj(player->mo, NULL, NULL, 1);
break;
case 4: // Damage (Electrical)
if (P_ShouldObjectBeDamaged(player->mo, roversector) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT)
if ((roversector || P_MobjReadyToTrigger(player->mo, sector)) && (player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT)
P_DamageMobj(player->mo, NULL, NULL, 1);
break;
case 5: // Spikes
@ -3390,7 +3457,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
break;
case 6: // Death Pit (Camera Mod)
case 7: // Death Pit (No Camera Mod)
if (P_ShouldObjectBeDamaged(player->mo, roversector))
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
P_DamageMobj(player->mo, NULL, NULL, 10000);
break;
case 8: // Instant Kill
@ -3451,10 +3518,26 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
break;
case 2: // Linedef executor requires all players present+doesn't require touching floor
case 3: // Linedef executor requires all players present
/// \todo take FOFs into account (+continues for proper splitscreen support?)
/// \todo check continues for proper splitscreen support?
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && !players[i].bot && players[i].mo && (gametype != GT_COOP || players[i].lives > 0) && !(P_PlayerTouchingSectorSpecial(&players[i], 2, 3) == sector || P_PlayerTouchingSectorSpecial(&players[i], 2, 2) == sector))
goto DoneSection2;
if (playeringame[i] && !players[i].bot && players[i].mo && (gametype != GT_COOP || players[i].lives > 0))
{
if (roversector)
{
if (players[i].mo->subsector->sector != roversector)
goto DoneSection2;
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
goto DoneSection2;
}
else
{
if (players[i].mo->subsector->sector != sector)
goto DoneSection2;
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
goto DoneSection2;
}
}
case 4: // Linedef executor that doesn't require touching floor
case 5: // Linedef executor
case 6: // Linedef executor (7 Emeralds)
@ -5280,7 +5363,7 @@ static void P_RunLevelLoadExecutors(void)
for (i = 0; i < numlines; i++)
{
if (lines[i].special == 399)
P_LinedefExecute(lines[i].tag, NULL, NULL);
P_RunTriggerLinedef(&lines[i], NULL, NULL);
}
}

View file

@ -168,7 +168,8 @@ void Command_CountMobjs_f(void)
count++;
}
CONS_Printf(" * %d: %d\n", i, count);
if (count > 0) // Don't bother displaying if there are none of this type!
CONS_Printf(" * %d: %d\n", i, count);
}
}

View file

@ -988,8 +988,8 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
{
player->powers[pw_extralife] = 0;
player->powers[pw_invulnerability] = 0;
player->powers[pw_sneakers] = 0;
}
player->powers[pw_sneakers] = 0;
if (gametype != GT_COOP)
{
@ -3790,24 +3790,20 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
case CA_JUMPTHOK: // Credit goes to CZ64 and Sryder13 for the original
// Now it's Sonic's abilities turn!
// THOK!
if (!(player->pflags & PF_THOKKED) || ((player->charability2 == CA2_MULTIABILITY) /*&& (!(player->charability == CA_JUMPTHOK))*/))
if (!(player->pflags & PF_THOKKED) || (player->charability2 == CA2_MULTIABILITY))
{
// Catapult the player
fixed_t actionspd = player->actionspd;
if (player->mo->eflags & MFE_UNDERWATER)
actionspd >>= 1;
if (player->charability == CA_JUMPTHOK)
if ((player->charability == CA_JUMPTHOK) && !(player->pflags & PF_THOKKED))
{
// Enforcing an arbitrary limit, even on just the default setting, is bad; it encourages bad WADmaking practice and disables use of that particular action speed.
// Instead, see the speed limit in 2D with the added condition below! I think that works much better, and is more consistent. -Red
//if ((actionspd == 60*FRACUNIT) && (actionspd > player->normalspeed)) //Limit only at default
//actionspd = player->normalspeed;
player->pflags &= ~PF_JUMPED;
P_DoJump(player, false);
}
P_InstaThrust(player->mo, player->mo->angle, FixedMul(actionspd, player->mo->scale));
if ((maptol & TOL_2D) || (player->charability == CA_JUMPTHOK))
if (maptol & TOL_2D)
{
player->mo->momx /= 2;
player->mo->momy /= 2;
@ -4013,7 +4009,7 @@ static boolean P_AnalogMove(player_t *player)
//
// Determines if the player is pressing in the direction they are moving
//
// 0 = no controls pressed
// 0 = no controls pressed/no movement
// 1 = pressing in the direction of movement
// 2 = pressing in the opposite direction of movement
//
@ -4034,7 +4030,19 @@ INT32 P_GetPlayerControlDirection(player_t *player)
if (!cmd->forwardmove && !cmd->sidemove)
return 0;
if (P_AnalogMove(player) && thiscam->chase)
if (!player->mo->momx && !player->mo->momy)
return 0;
if (twodlevel || player->mo->flags2 & MF2_TWOD)
{
if (!cmd->sidemove)
return 0;
if (!player->mo->momx)
return 0;
origtempangle = tempangle = 0; // relative to the axis rather than the player!
controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
}
else if (P_AnalogMove(player) && thiscam->chase)
{
if (player->awayviewtics)
origtempangle = tempangle = player->awayviewmobj->angle;
@ -4051,11 +4059,14 @@ INT32 P_GetPlayerControlDirection(player_t *player)
// Calculate the angle at which the controls are pointing
// to figure out the proper mforward and mbackward.
tempangle >>= ANGLETOFINESHIFT;
tempx += FixedMul(cmd->forwardmove*FRACUNIT,FINECOSINE(tempangle));
tempy += FixedMul(cmd->forwardmove*FRACUNIT,FINESINE(tempangle));
if (!(twodlevel || player->mo->flags2 & MF2_TWOD)) // in 2d mode, sidemove is treated as the forwards/backwards direction
{
tempx += FixedMul(cmd->forwardmove*FRACUNIT,FINECOSINE(tempangle));
tempy += FixedMul(cmd->forwardmove*FRACUNIT,FINESINE(tempangle));
tempangle = origtempangle-ANGLE_90;
tempangle >>= ANGLETOFINESHIFT;
tempangle = origtempangle-ANGLE_90;
tempangle >>= ANGLETOFINESHIFT;
}
tempx += FixedMul(cmd->sidemove*FRACUNIT,FINECOSINE(tempangle));
tempy += FixedMul(cmd->sidemove*FRACUNIT,FINESINE(tempangle));
@ -8729,10 +8740,7 @@ void P_PlayerThink(player_t *player)
if (!(player->pflags & PF_NIGHTSMODE))
{
if (cmd->buttons & BT_USE)
{
if (!(player->pflags & PF_USEDOWN))
player->pflags |= PF_USEDOWN;
}
player->pflags |= PF_USEDOWN;
else
player->pflags &= ~PF_USEDOWN;
}
@ -9030,8 +9038,7 @@ void P_PlayerAfterThink(player_t *player)
}
}
if (!(cmd->buttons & BT_WEAPONNEXT) && !(cmd->buttons & BT_WEAPONPREV)
&& !(cmd->buttons & BT_WEAPONMASK))
if (!(cmd->buttons & (BT_WEAPONNEXT|BT_WEAPONPREV|BT_WEAPONMASK)))
player->pflags &= ~PF_WPNDOWN;
// Weapon cycling if out of ammo for a certain weapon
@ -9068,7 +9075,7 @@ void P_PlayerAfterThink(player_t *player)
&& player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
if ((player->pflags & PF_CARRIED) && player->mo->tracer)
if (player->pflags & PF_CARRIED && player->mo->tracer)
{
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
@ -9157,7 +9164,7 @@ void P_PlayerAfterThink(player_t *player)
}
}
}
else if ((player->pflags & PF_MACESPIN) && player->mo->tracer && player->mo->tracer->target)
else if (player->pflags & PF_MACESPIN && player->mo->tracer && player->mo->tracer->target)
{
player->mo->height = P_GetPlayerSpinHeight(player);
// tracer is what you're hanging onto....
@ -9187,9 +9194,9 @@ void P_PlayerAfterThink(player_t *player)
}
}
if (((splitscreen && player == &players[secondarydisplayplayer]) || player == &players[displayplayer]))
if ((splitscreen && player == &players[secondarydisplayplayer]) || player == &players[displayplayer])
{
if (!(thiscam->chase)) // bob view only if looking through the player's eyes
if (!thiscam->chase) // bob view only if looking through the player's eyes
{
P_CalcHeight(player);
P_CalcPostImg(player);

View file

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.10;
CURRENT_PROJECT_VERSION = 2.1.11;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.10;
CURRENT_PROJECT_VERSION = 2.1.11;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View file

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.10;
CURRENT_PROJECT_VERSION = 2.1.11;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.10;
CURRENT_PROJECT_VERSION = 2.1.11;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View file

@ -479,14 +479,11 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
deststart = desttop;
destend = desttop + SHORT(patch->width) * dupx;
for (col = 0; (col>>FRACBITS) < SHORT(patch->width); col += colfrac, desttop++)
for (col = 0; (col>>FRACBITS) < SHORT(patch->width); col += colfrac, ++x, desttop++)
{
INT32 topdelta, prevdelta = -1;
if (x < 0)
{ // don't draw off the left of the screen (WRAP PREVENTION)
x++;
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
}
if (x > vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[col>>FRACBITS]));
@ -594,13 +591,11 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
}
}
for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, desttop++)
for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++)
{
INT32 topdelta, prevdelta = -1;
if (x < 0) { // don't draw off the left of the screen (WRAP PREVENTION)
x++;
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
}
if (x > vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[col>>FRACBITS]));