diff --git a/readme.txt b/readme.txt index 2a34380bb..f96d3823c 100644 --- a/readme.txt +++ b/readme.txt @@ -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) diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 1ea96df92..e4f9290c6 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -386,7 +386,7 @@ OBJDUMP_OPTS?=--wide --source --line-numbers LD=$(CC) ifdef SDL - INTERFACE=sdl + INTERFACE=sdl2 OBJDIR:=$(OBJDIR)/SDL endif diff --git a/src/command.c b/src/command.c index 14c5faae8..baf97cbd1 100644 --- a/src/command.c +++ b/src/command.c @@ -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 diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3adba9efd..659dac1d0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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 diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 700fb5f67..6bc06f13a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -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); diff --git a/src/d_main.c b/src/d_main.c index 42799b7d3..bf1bc7330 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -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 diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 13cf2fed9..5e81a5a55 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); } // ========================================================================= @@ -4026,6 +4027,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 @@ -4042,6 +4053,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 @@ -4057,6 +4071,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 @@ -4076,6 +4100,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 diff --git a/src/doomdef.h b/src/doomdef.h index 06f6ba121..a978e047b 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -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 diff --git a/src/f_wipe.c b/src/f_wipe.c index 64d5cfeed..4b4ecd7e3 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -148,8 +148,8 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { *mask++ = FixedDiv((pcolor->s.red+1)<>FRACBITS; } - fm.xscale = FixedDiv(fm.width<mask[ // y*width + x - (FixedMul(y<yscale)>>FRACBITS)*fademask->width - + (FixedMul(x<xscale)>>FRACBITS) - ]; - if (transval == 0) - *w = *s; - else if (transval == 10) - *w = *e; - else - *w = transtables[(*e<<8) + *s + ((9 - transval)<= 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)<= fademask->width) + ++masky, maskx = 0; + } while (++mask < maskend); + } } #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9cc4f5625..b9977968e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -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 diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index f388a1ff4..6800a2f98 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -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; } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 2686aed97..7f64fff62 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -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 diff --git a/src/m_cond.c b/src/m_cond.c index 40f39d663..17f755120 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -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 diff --git a/src/m_menu.c b/src/m_menu.c index 605096465..830b26443 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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; diff --git a/src/m_menu.h b/src/m_menu.h index 302a7fade..ccb1c1102 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -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; diff --git a/src/p_inter.c b/src/p_inter.c index f66bf12f3..5044b5b81 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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; diff --git a/src/p_map.c b/src/p_map.c index fa8b9ed7d..be59af0a8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -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! +*/ } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 9241e559f..1ee30fbc7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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; diff --git a/src/p_setup.c b/src/p_setup.c index bd2b0a478..b3e85966a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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); } diff --git a/src/p_setup.h b/src/p_setup.h index 9cb323360..49df2fc5b 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -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 diff --git a/src/p_spec.c b/src/p_spec.c index ad0b397e0..3c9af246d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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); } } diff --git a/src/p_tick.c b/src/p_tick.c index c2610680d..9a0f80165 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -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); } } diff --git a/src/p_user.c b/src/p_user.c index 69d30cf67..a31666c9f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -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); diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 93da46bc1..c34690b3b 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -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 = ( diff --git a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj index 93da46bc1..c34690b3b 100644 --- a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -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 = ( diff --git a/src/v_video.c b/src/v_video.c index 52fefe4c6..926107ff2 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -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) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, desttop++) + for (col = sx<>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]));