From 147815b87cfa21030371da9c58213046cc8fc86b Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 16 Jul 2019 00:07:55 -0400 Subject: [PATCH 001/130] menu stuff --- src/f_finale.c | 8 +++--- src/m_menu.c | 66 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 1cae457a2..666ccfb67 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1420,12 +1420,12 @@ void F_InitMenuPresValues(void) curfadevalue = 16; curhidepics = hidetitlepics; curbgcolor = -1; - curbgxspeed = titlescrollxspeed; - curbgyspeed = titlescrollyspeed; - curbghide = true; + curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; + curbgyspeed = (gamestate == GS_TIMEATTACK) ? 22 : titlescrollyspeed; + curbghide = (gamestate == GS_TIMEATTACK) ? false : true; // Find current presentation values - M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY"); + M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY"); M_SetMenuCurFadeValue(16); M_SetMenuCurHideTitlePics(); } diff --git a/src/m_menu.c b/src/m_menu.c index dca2e552d..e12a8a20e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -159,6 +159,7 @@ static INT32 vidm_previousmode; static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; +tic_t recfgtimer = 0; // // PROTOTYPES @@ -1601,24 +1602,24 @@ menu_t SP_LevelStatsDef = menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), - "M_ATTACK", SP_TimeAttackLevelSelectMenu); + NULL, SP_TimeAttackLevelSelectMenu); static menu_t SP_TimeAttackDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), - "M_ATTACK", + NULL, sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. SP_TimeAttackMenu, M_DrawTimeAttackMenu, - 32, 40, + 32, 28, 0, NULL }; static menu_t SP_ReplayDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), - "M_ATTACK", + NULL, sizeof(SP_ReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, SP_ReplayMenu, @@ -1630,7 +1631,7 @@ static menu_t SP_ReplayDef = static menu_t SP_GuestReplayDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), - "M_ATTACK", + NULL, sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, SP_GuestReplayMenu, @@ -1642,7 +1643,7 @@ static menu_t SP_GuestReplayDef = static menu_t SP_GhostDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), - "M_ATTACK", + NULL, sizeof(SP_GhostMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, SP_GhostMenu, @@ -2467,16 +2468,16 @@ static void M_HandleMenuPresState(menu_t *newMenu) curfadevalue = 16; curhidepics = hidetitlepics; curbgcolor = -1; - curbgxspeed = titlescrollxspeed; - curbgyspeed = titlescrollyspeed; - curbghide = true; + curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; + curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed; + curbghide = (gamestate == GS_TIMEATTACK) ? false : true; // don't do the below during the in-game menus if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) return; // Find current presentation values - M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY"); + M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY"); M_SetMenuCurFadeValue(16); M_SetMenuCurHideTitlePics(); @@ -5043,6 +5044,10 @@ static void M_DrawLevelPlatterMenu(void) if (gamestate == GS_TIMEATTACK) { + curbgxspeed = 0; + curbgyspeed = 18; + curbghide = false; + strncpy(curbgname, "RECATTBG", 8); if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) @@ -8056,8 +8061,15 @@ void M_DrawTimeAttackMenu(void) INT32 i, x, y, cursory = 0; UINT16 dispstatus; patch_t *PictureOfUrFace; + patch_t *menufg; + curbgxspeed = 0; + curbgyspeed = 18; + curbghide = false; + + strncpy(curbgname, "RECATTBG", 8); M_ChangeMenuMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback + menufg = W_CachePatchName("RECATFG", PU_CACHE); if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); @@ -8066,6 +8078,12 @@ void M_DrawTimeAttackMenu(void) if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); + // Draw and animate foreground + V_DrawSciencePatch(0, -(130<score) sprintf(beststr, "(none)"); else sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); - V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 32+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); + V_DrawRightAlignedString(104+72, 32+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) sprintf(beststr, "(none)"); @@ -8159,16 +8177,16 @@ void M_DrawTimeAttackMenu(void) G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 40+lsheadingheight/2, V_YELLOWMAP, "TIME:"); + V_DrawRightAlignedString(104+72, 40+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) sprintf(beststr, "(none)"); else sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); - V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); + V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); // Draw record emblems. em = M_GetLevelEmblems(cv_nextmap.value); @@ -8176,9 +8194,9 @@ void M_DrawTimeAttackMenu(void) { switch (em->type) { - case ET_SCORE: yHeight = 48; break; - case ET_TIME: yHeight = 58; break; - case ET_RINGS: yHeight = 68; break; + case ET_SCORE: yHeight = 32; break; + case ET_TIME: yHeight = 40; break; + case ET_RINGS: yHeight = 48; break; default: goto skipThisOne; } @@ -8208,6 +8226,10 @@ void M_DrawTimeAttackMenu(void) V_DrawString(x, y + SP_TimeAttackMenu[taplayer].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[taplayer].text); V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), y + SP_TimeAttackMenu[taplayer].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); } + + // Draw press ESC to exit string on main record attack menu + if (currentMenu == &SP_TimeAttackDef) + V_DrawString(104-72, 170, V_TRANSLUCENT, M_GetText("Press ESC to exit")); } static void M_TimeAttackLevelSelect(INT32 choice) From e8caa8538d6ace6f60862fa5f03074c9a722b70b Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 1 Aug 2019 18:36:42 -0400 Subject: [PATCH 002/130] Merge branch 'master' into newmenus --- src/d_clisrv.c | 8 +- src/d_netcmd.c | 3 +- src/dehacked.c | 18 +- src/f_finale.c | 3 + src/g_game.c | 13 +- src/hardware/hw_light.c | 93 ++++-- src/info.c | 142 ++++++++-- src/info.h | 18 +- src/lua_baselib.c | 2 +- src/lua_blockmaplib.c | 2 + src/lua_mobjlib.c | 11 +- src/lua_playerlib.c | 21 +- src/lua_script.c | 30 +- src/m_cheat.c | 11 +- src/m_menu.c | 49 +++- src/p_enemy.c | 52 +++- src/p_floor.c | 31 +- src/p_inter.c | 51 +++- src/p_local.h | 4 +- src/p_maputl.c | 3 + src/p_mobj.c | 141 ++++++---- src/p_polyobj.c | 174 +++++++----- src/p_saveg.c | 53 ++-- src/p_setup.c | 24 +- src/p_spec.c | 78 ++++-- src/p_tick.c | 86 +++--- src/p_tick.h | 2 +- src/p_user.c | 374 +++++++++++++++---------- src/r_data.c | 3 +- src/r_things.c | 6 +- src/s_sound.c | 4 +- src/sdl/Srb2SDL-vc10.vcxproj | 2 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 7 + src/sdl/mixer_sound.c | 74 +++-- src/st_stuff.c | 30 +- src/win32/Srb2win-vc10.vcxproj | 2 + src/win32/Srb2win-vc10.vcxproj.filters | 8 + 37 files changed, 1066 insertions(+), 567 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index bd9158468..74b3339fc 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4270,13 +4270,11 @@ static INT16 Consistancy(void) ret += P_GetRandSeed(); #ifdef MOBJCONSISTANCY - if (!thlist[THINK_MOBJ].next) - { - DEBFILE(va("Consistancy = %u\n", ret)); - return ret; - } for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)th; if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5e070dcd7..e6f5244f0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4261,7 +4261,8 @@ static void Command_Archivetest_f(void) // assign mobjnum i = 1; for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - ((mobj_t *)th)->mobjnum = i++; + if (th->function.acp1 != (actionf_p1)P_RemoveThinkerDelayed) + ((mobj_t *)th)->mobjnum = i++; // allocate buffer buf = save_p = ZZ_Alloc(1024); diff --git a/src/dehacked.c b/src/dehacked.c index 31c17f188..01e2b0bde 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5699,7 +5699,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CEZFLOWER", "S_CEZPOLE", - "S_CEZBANNER", + "S_CEZBANNER1", + "S_CEZBANNER2", "S_PINETREE", "S_CEZBUSH1", "S_CEZBUSH2", @@ -5708,7 +5709,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FLAMEHOLDER", "S_FIRETORCH", "S_WAVINGFLAG", - "S_WAVINGFLAGSEG", + "S_WAVINGFLAGSEG1", + "S_WAVINGFLAGSEG2", "S_CRAWLASTATUE", "S_FACESTABBERSTATUE", "S_SUSPICIOUSFACESTABBERSTATUE_WAIT", @@ -7514,8 +7516,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SMALLFIREBAR", // Small Firebar "MT_BIGFIREBAR", // Big Firebar "MT_CEZFLOWER", // Flower - "MT_CEZPOLE", // Pole - "MT_CEZBANNER", // Banner + "MT_CEZPOLE1", // Pole (with red banner) + "MT_CEZPOLE2", // Pole (with blue banner) + "MT_CEZBANNER1", // Banner (red) + "MT_CEZBANNER2", // Banner (blue) "MT_PINETREE", // Pine Tree "MT_CEZBUSH1", // Bush 1 "MT_CEZBUSH2", // Bush 2 @@ -7523,8 +7527,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_CANDLEPRICKET", // Candle pricket "MT_FLAMEHOLDER", // Flame holder "MT_FIRETORCH", // Fire torch - "MT_WAVINGFLAG", // Waving flag - "MT_WAVINGFLAGSEG", // Waving flag segment + "MT_WAVINGFLAG1", // Waving flag (red) + "MT_WAVINGFLAG2", // Waving flag (blue) + "MT_WAVINGFLAGSEG1", // Waving flag segment (red) + "MT_WAVINGFLAGSEG2", // Waving flag segment (blue) "MT_CRAWLASTATUE", // Crawla statue "MT_FACESTABBERSTATUE", // Facestabber statue "MT_SUSPICIOUSFACESTABBERSTATUE", // :eggthinking: diff --git a/src/f_finale.c b/src/f_finale.c index 666ccfb67..21a604b04 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1695,6 +1695,9 @@ void F_TitleScreenTicker(boolean run) { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (!mo2) diff --git a/src/g_game.c b/src/g_game.c index f963cae35..95cc2288d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2567,6 +2567,9 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) // scan all thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (!(mo2->flags & MF_MISSILE)) @@ -4466,12 +4469,13 @@ void G_ConsGhostTic(void) mobj = NULL; for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; mobj = (mobj_t *)th; if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) break; - mobj = NULL; // wasn't this one, keep searching. } - if (mobj && mobj->health != health) // Wasn't damaged?! This is desync! Fix it! + if (th != &thlist[THINK_MOBJ] && mobj->health != health) // Wasn't damaged?! This is desync! Fix it! { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); @@ -5860,13 +5864,16 @@ void G_DoPlayMetal(void) // find metal sonic for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)th; if (mo->type != MT_METALSONIC_RACE) continue; break; } - if (!mo) + if (th == &thlist[THINK_MOBJ]) { CONS_Alert(CONS_ERROR, M_GetText("Failed to find bot entity.\n")); Z_Free(metalbuffer); diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index b87fe65de..a52d72869 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -804,6 +804,14 @@ void HWR_WallLighting(FOutVector *wlVerts) FSurfaceInfo Surf; float dist_p2d, d[4], s; + if (!dynlights->mo[j]) + continue; + if (P_MobjWasRemoved(dynlights->mo[j])) + { + P_SetTarget(&dynlights->mo[j], NULL); + continue; + } + // check bounding box first if (SphereTouchBBox3D(&wlVerts[2], &wlVerts[0], &LIGHT_POS(j), DL_RADIUS(j))==false) continue; @@ -854,8 +862,6 @@ void HWR_WallLighting(FOutVector *wlVerts) #ifdef DL_HIGH_QUALITY Surf.FlatColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha); #endif - if (!dynlights->mo[j]->state) - return; // next state is null so fade out with alpha if (dynlights->mo[j]->state->nextstate == S_NULL) Surf.FlatColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); @@ -886,6 +892,14 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts) FSurfaceInfo Surf; float dist_p2d, s; + if (!dynlights->mo[j]) + continue; + if (P_MobjWasRemoved(dynlights->mo[j])) + { + P_SetTarget(&dynlights->mo[j], NULL); + continue; + } + // BP: The kickass Optimization: check if light touch bounding box if (SphereTouchBBox3D(&p1, &p2, &dynlights->position[j], DL_RADIUS(j))==false) continue; @@ -917,8 +931,6 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts) #ifdef DL_HIGH_QUALITY Surf.FlatColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha); #endif - if (!dynlights->mo[j]->state) - return; // next state is null so fade out with alpha if ((dynlights->mo[j]->state->nextstate == S_NULL)) Surf.FlatColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); @@ -1049,6 +1061,14 @@ void HWR_DrawCoronas(void) if (!(p_lspr->type & CORONA_SPR)) continue; + if (!dynlights->mo[j]) + continue; + if (P_MobjWasRemoved(dynlights->mo[j])) + { + P_SetTarget(&dynlights->mo[j], NULL); + continue; + } + transform(&cx,&cy,&cz); // more realistique corona ! @@ -1110,7 +1130,8 @@ void HWR_DrawCoronas(void) // -------------------------------------------------------------------------- void HWR_ResetLights(void) { - dynlights->nb = 0; + while (dynlights->nb) + P_SetTarget(&dynlights->mo[--dynlights->nb], NULL); } // -------------------------------------------------------------------------- @@ -1141,24 +1162,25 @@ void HWR_DL_AddLight(gr_vissprite_t *spr, GLPatch_t *patch) return; #endif + if (dynlights->nb >= DL_MAX_LIGHT) + return; + // check if sprite contain dynamic light p_lspr = t_lspr[spr->mobj->sprite]; - if ((p_lspr->type&DYNLIGHT_SPR) - && ((p_lspr->type != LIGHT_SPR) || cv_grstaticlighting.value) - && (dynlights->nb < DL_MAX_LIGHT) + if (!(p_lspr->type & DYNLIGHT_SPR)) + return; + if ((p_lspr->type != LIGHT_SPR) || cv_grstaticlighting.value) + return; - && spr->mobj->state) - { - LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(spr->mobj->x); - LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(spr->mobj->z)+FIXED_TO_FLOAT(spr->mobj->height>>1)+p_lspr->light_yoffset; - LIGHT_POS(dynlights->nb).z = FIXED_TO_FLOAT(spr->mobj->y); + LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(spr->mobj->x); + LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(spr->mobj->z)+FIXED_TO_FLOAT(spr->mobj->height>>1)+p_lspr->light_yoffset; + LIGHT_POS(dynlights->nb).z = FIXED_TO_FLOAT(spr->mobj->y); - P_SetTarget(&dynlights->mo[dynlights->nb], spr->mobj); + P_SetTarget(&dynlights->mo[dynlights->nb], spr->mobj); - dynlights->p_lspr[dynlights->nb] = p_lspr; + dynlights->p_lspr[dynlights->nb] = p_lspr; - dynlights->nb++; - } + dynlights->nb++; } static GLPatch_t lightmappatch; @@ -1312,6 +1334,14 @@ static void HWR_CheckSubsector(size_t num, fixed_t *bbox) // if (CircleTouchBBox(&p1, &p2, &LIGHT_POS(lightnum), DL_RADIUS(lightnum))==false) // continue; + if (!dynlights->mo[lightnum]) + continue; + if (P_MobjWasRemoved(dynlights->mo[lightnum])) + { + P_SetTarget(&dynlights->mo[lightnum], NULL); + continue; + } + count = sub->numlines; // how many linedefs line = &segs[sub->firstline]; // first line seg while (count--) @@ -1329,18 +1359,20 @@ static void HWR_CheckSubsector(size_t num, fixed_t *bbox) // -------------------------------------------------------------------------- static void HWR_AddMobjLights(mobj_t *thing) { - if (t_lspr[thing->sprite]->type & CORONA_SPR) - { - LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(thing->x); - LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(thing->z) + t_lspr[thing->sprite]->light_yoffset; - LIGHT_POS(dynlights->nb).z = FIXED_TO_FLOAT(thing->y); + if (dynlights->nb >= DL_MAX_LIGHT) + return; + if (!(t_lspr[thing->sprite]->type & CORONA_SPR)) + return; - dynlights->p_lspr[dynlights->nb] = t_lspr[thing->sprite]; + LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(thing->x); + LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(thing->z) + t_lspr[thing->sprite]->light_yoffset; + LIGHT_POS(dynlights->nb).z = FIXED_TO_FLOAT(thing->y); - dynlights->nb++; - if (dynlights->nb > DL_MAX_LIGHT) - dynlights->nb = DL_MAX_LIGHT; - } + P_SetTarget(&dynlights->mo[dynlights->nb], thing); + + dynlights->p_lspr[dynlights->nb] = t_lspr[thing->sprite]; + + dynlights->nb++; } //Hurdler: The goal of this function is to walk through all the bsp starting @@ -1367,7 +1399,8 @@ static void HWR_SearchLightsInMobjs(void) // search in the list of thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - HWR_AddMobjLights((mobj_t *)th); + if (th->function.acp1 != (actionf_p1)P_RemoveThinkerDelayed) + HWR_AddMobjLights((mobj_t *)th); } #endif @@ -1379,7 +1412,7 @@ void HWR_CreateStaticLightmaps(int bspnum) #ifdef STATICLIGHT CONS_Debug(DBG_RENDER, "HWR_CreateStaticLightmaps\n"); - dynlights->nb = 0; + HWR_ResetLights(); // First: Searching for lights // BP: if i was you, I will make it in create mobj since mobj can be create @@ -1390,8 +1423,6 @@ void HWR_CreateStaticLightmaps(int bspnum) // Second: Build all lightmap for walls covered by lights validcount++; // to be sure HWR_ComputeLightMapsInBSPNode(bspnum, NULL); - - dynlights->nb = 0; #else (void)bspnum; #endif diff --git a/src/info.c b/src/info.c index 631f40cdc..a4446d657 100644 --- a/src/info.c +++ b/src/info.c @@ -2322,9 +2322,10 @@ state_t states[NUMSTATES] = {SPR_BFBR, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_BIGFIREBAR1}, // S_BIGFIREBAR16 {SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER - {SPR_BANR, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CEZPOLE + {SPR_BANR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZPOLE - {SPR_BANR, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER + {SPR_BANR, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER1 + {SPR_BANR, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER2 {SPR_PINE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_PINETREE {SPR_CEZB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBUSH1 @@ -2338,7 +2339,8 @@ state_t states[NUMSTATES] = {SPR_CTRC, FF_FULLBRIGHT|FF_ANIMATE, 8*3, {A_FlameParticle}, 3, 3, S_FIRETORCH}, // S_FIRETORCH {SPR_CFLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAG - {SPR_CFLG, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG + {SPR_CFLG, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG1 + {SPR_CFLG, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG2 {SPR_CSTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CRAWLASTATUE @@ -7492,7 +7494,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 0, // painchance sfx_s3k64, // painsound - S_NULL, // meleestate + S_WALLSPIKE4, // meleestate S_NULL, // missilestate S_WALLSPIKED1, // deathstate S_WALLSPIKED2, // xdeathstate @@ -11018,7 +11020,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_CEZPOLE + { // MT_CEZPOLE1 1117, // doomednum S_CEZPOLE, // spawnstate 1000, // spawnhealth @@ -11045,9 +11047,63 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_CEZBANNER + { // MT_CEZPOLE2 + 1118, // doomednum + S_CEZPOLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 40*FRACUNIT, // radius + 224*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_CEZBANNER1 -1, // doomednum - S_CEZBANNER, // spawnstate + S_CEZBANNER1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 40*FRACUNIT, // radius + 224*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_CEZBANNER2 + -1, // doomednum + S_CEZBANNER2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11261,8 +11317,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_WAVINGFLAG - 1118, // doomednum + { // MT_WAVINGFLAG1 + 1128, // doomednum S_WAVINGFLAG, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11278,8 +11334,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 4*FRACUNIT, // radius - 104*FRACUNIT, // height + 8*FRACUNIT, // radius + 208*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -11288,9 +11344,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_WAVINGFLAGSEG - -1, // doomednum - S_WAVINGFLAGSEG, // spawnstate + { // MT_WAVINGFLAG2 + 1129, // doomednum + S_WAVINGFLAG, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11305,7 +11361,61 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 4*FRACUNIT, // radius + 8*FRACUNIT, // radius + 208*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID, // flags + S_NULL // raisestate + }, + + { // MT_WAVINGFLAGSEG1 + -1, // doomednum + S_WAVINGFLAGSEG1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 1, // height -- this is not a typo + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_WAVINGFLAGSEG2 + -1, // doomednum + S_WAVINGFLAGSEG2, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius 1, // height -- this is not a typo 0, // display offset 100, // mass @@ -19642,7 +19752,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 0, // damage - sfx_None, // activesound + sfx_wbreak, // activesound MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 44f08a4e9..a9a0321ec 100644 --- a/src/info.h +++ b/src/info.h @@ -2458,7 +2458,8 @@ typedef enum state S_CEZFLOWER, S_CEZPOLE, - S_CEZBANNER, + S_CEZBANNER1, + S_CEZBANNER2, S_PINETREE, S_CEZBUSH1, S_CEZBUSH2, @@ -2467,7 +2468,8 @@ typedef enum state S_FLAMEHOLDER, S_FIRETORCH, S_WAVINGFLAG, - S_WAVINGFLAGSEG, + S_WAVINGFLAGSEG1, + S_WAVINGFLAGSEG2, S_CRAWLASTATUE, S_FACESTABBERSTATUE, S_SUSPICIOUSFACESTABBERSTATUE_WAIT, @@ -4295,8 +4297,10 @@ typedef enum mobj_type MT_SMALLFIREBAR, // Small Firebar MT_BIGFIREBAR, // Big Firebar MT_CEZFLOWER, // Flower - MT_CEZPOLE, // Pole - MT_CEZBANNER, // Banner + MT_CEZPOLE1, // Pole (with red banner) + MT_CEZPOLE2, // Pole (with blue banner) + MT_CEZBANNER1, // Banner (red) + MT_CEZBANNER2, // Banner (blue) MT_PINETREE, // Pine Tree MT_CEZBUSH1, // Bush 1 MT_CEZBUSH2, // Bush 2 @@ -4304,8 +4308,10 @@ typedef enum mobj_type MT_CANDLEPRICKET, // Candle pricket MT_FLAMEHOLDER, // Flame holder MT_FIRETORCH, // Fire torch - MT_WAVINGFLAG, // Waving flag - MT_WAVINGFLAGSEG, // Waving flag segment + MT_WAVINGFLAG1, // Waving flag (red) + MT_WAVINGFLAG2, // Waving flag (blue) + MT_WAVINGFLAGSEG1, // Waving flag segment (red) + MT_WAVINGFLAGSEG2, // Waving flag segment (blue) MT_CRAWLASTATUE, // Crawla statue MT_FACESTABBERSTATUE, // Facestabber statue MT_SUSPICIOUSFACESTABBERSTATUE, // :eggthinking: diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 81a17ef20..1d69b238b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -539,7 +539,7 @@ static int lib_pSpawnLockOn(lua_State *L) if (P_IsLocalPlayer(player)) // Only display it on your own view. { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - visual->target = lockon; + P_SetTarget(&visual->target, lockon); visual->flags2 |= MF2_DONTDRAW; P_SetMobjStateNF(visual, state); } diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index dabbdd9f6..2383bb32e 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -54,10 +54,12 @@ static UINT8 lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t * CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); blockfuncerror = true; + P_SetTarget(&bnext, NULL); return 0; // *shrugs* } if (!lua_isnil(gL, -1)) { // if nil, continue + P_SetTarget(&bnext, NULL); if (lua_toboolean(gL, -1)) return 2; // stop whole search else diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 0a3d356c9..8bbbebe1d 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -274,10 +274,19 @@ static int mobj_get(lua_State *L) // bprev -- same deal as sprev above, but for the blockmap. return UNIMPLEMENTED; case mobj_hnext: + if (mo->hnext && P_MobjWasRemoved(mo->hnext)) + { // don't put invalid mobj back into Lua. + P_SetTarget(&mo->hnext, NULL); + return 0; + } LUA_PushUserdata(L, mo->hnext, META_MOBJ); break; case mobj_hprev: - // implimented differently from sprev and bprev because SSNTails. + if (mo->hprev && P_MobjWasRemoved(mo->hprev)) + { // don't put invalid mobj back into Lua. + P_SetTarget(&mo->hprev, NULL); + return 0; + } LUA_PushUserdata(L, mo->hprev, META_MOBJ); break; case mobj_type: diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f3eb978f6..700dab211 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -476,7 +476,12 @@ static int player_set(lua_State *L) else if (fastcmp(field,"followitem")) plr->followitem = luaL_checkinteger(L, 3); else if (fastcmp(field,"followmobj")) - P_SetTarget(&plr->followmobj, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ))); + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->followmobj, mo); + } else if (fastcmp(field,"actionspd")) plr->actionspd = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"mindash")) @@ -560,9 +565,19 @@ static int player_set(lua_State *L) else if (fastcmp(field,"old_angle_pos")) plr->old_angle_pos = luaL_checkangle(L, 3); else if (fastcmp(field,"axis1")) - P_SetTarget(&plr->axis1, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ))); + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->axis1, mo); + } else if (fastcmp(field,"axis2")) - P_SetTarget(&plr->axis2, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ))); + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->axis2, mo); + } else if (fastcmp(field,"bumpertime")) plr->bumpertime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"flyangle")) diff --git a/src/lua_script.c b/src/lua_script.c index 85b9c4038..deb644dc0 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1127,14 +1127,15 @@ void LUA_Archive(void) ArchiveExtVars(&players[i], "player"); } - for (i = 0; i < NUM_THINKERLISTS; i++) - for (th = thlist[i].next; th != &thlist[i]; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - { - // archive function will determine when to skip mobjs, - // and write mobjnum in otherwise. - ArchiveExtVars(th, "mobj"); - } + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + // archive function will determine when to skip mobjs, + // and write mobjnum in otherwise. + ArchiveExtVars(th, "mobj"); + } WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. @@ -1163,11 +1164,14 @@ void LUA_UnArchive(void) do { mobjnum = READUINT32(save_p); // read a mobjnum - for (i = 0; i < NUM_THINKERLISTS; i++) - for (th = thlist[i].next; th != &thlist[i]; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker - && ((mobj_t *)th)->mobjnum == mobjnum) // find matching mobj - UnArchiveExtVars(th); // apply variables + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj + continue; + UnArchiveExtVars(th); // apply variables + } } while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker. LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode diff --git a/src/m_cheat.c b/src/m_cheat.c index 734a7ae18..29e8c8a02 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -579,6 +579,9 @@ void Command_Teleport_f(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_STARPOST) @@ -1068,10 +1071,14 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)th; // get offset from mt, which points to old mapthings, then add new location - if (mo->spawnpoint) - mo->spawnpoint = (mo->spawnpoint - mt) + mapthings; + if (!mo->spawnpoint) + continue; + mo->spawnpoint = (mo->spawnpoint - mt) + mapthings; } } diff --git a/src/m_menu.c b/src/m_menu.c index e12a8a20e..5e164ecb9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2289,23 +2289,26 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, (void)retval; (void)fromoldest; + if (!menutype) // if there's nothing in this level, do nothing + return false; + if (menupres[menutype].bgcolor >= 0) { curbgcolor = menupres[menutype].bgcolor; return true; } - else if (menupres[menutype].bgname[0] && (!menupres[menutype].bghide || !titlemapinaction)) + else if (menupres[menutype].bghide && titlemapinaction) // hide the background + { + curbghide = true; + return true; + } + else if (menupres[menutype].bgname[0]) { strncpy(curbgname, menupres[menutype].bgname, 8); curbgxspeed = menupres[menutype].titlescrollxspeed != INT32_MAX ? menupres[menutype].titlescrollxspeed : titlescrollxspeed; curbgyspeed = menupres[menutype].titlescrollyspeed != INT32_MAX ? menupres[menutype].titlescrollyspeed : titlescrollyspeed; return true; } - else if (menupres[menutype].bghide && titlemapinaction) // hide the background - { - curbghide = true; - return true; - } else if (!level) { if (M_GetYoungestChildMenu() == MN_SP_PLAYER || !defaultname || !defaultname[0]) @@ -2329,6 +2332,9 @@ static boolean MIT_ChangeMusic(UINT32 menutype, INT32 level, INT32 *retval, void (void)retval; (void)fromoldest; + if (!menutype) // if there's nothing in this level, do nothing + return false; + if (menupres[menutype].musname[0]) { S_ChangeMusic(menupres[menutype].musname, menupres[menutype].mustrack, menupres[menutype].muslooping); @@ -2353,6 +2359,9 @@ static boolean MIT_SetCurFadeValue(UINT32 menutype, INT32 level, INT32 *retval, (void)retval; (void)fromoldest; + if (!menutype) // if there's nothing in this level, do nothing + return false; + if (menupres[menutype].fadestrength >= 0) { curfadevalue = (menupres[menutype].fadestrength % 32); @@ -2369,6 +2378,9 @@ static boolean MIT_SetCurHideTitlePics(UINT32 menutype, INT32 level, INT32 *retv (void)retval; (void)fromoldest; + if (!menutype) // if there's nothing in this level, do nothing + return false; + if (menupres[menutype].hidetitlepics >= 0) { curhidepics = menupres[menutype].hidetitlepics; @@ -2470,7 +2482,7 @@ static void M_HandleMenuPresState(menu_t *newMenu) curbgcolor = -1; curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed; - curbghide = (gamestate == GS_TIMEATTACK) ? false : true; + curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus // don't do the below during the in-game menus if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) @@ -5054,6 +5066,14 @@ static void M_DrawLevelPlatterMenu(void) F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); + + // Draw and animate foreground + if (!curbghide || !titlemapinaction) + { + V_DrawSciencePatch(0, -(130<= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); @@ -8079,11 +8097,12 @@ void M_DrawTimeAttackMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - V_DrawSciencePatch(0, -(130<angle = actor->angle; - new->target = actor->target; + P_SetTarget(&new->target, actor->target); if (locvar2) P_SetMobjState(new, (statenum_t)locvar2); S_StartSound(new, new->info->attacksound); @@ -2155,7 +2155,7 @@ void A_CrushclawLaunch(mobj_t *actor) for (i = 0; (i < CSEGS); i++) { mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate); - prevchain->target = newchain; + P_SetTarget(&prevchain->target, newchain); prevchain = newchain; } actor->target->angle = R_PointToAngle2(actor->target->x, actor->target->y, crab->target->x, crab->target->y); @@ -3088,7 +3088,7 @@ void A_Boss1Laser(mobj_t *actor) if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) { point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); - point->target = actor; + P_SetTarget(&point->target, actor); point->destscale = 3*FRACUNIT; point->scalespeed = FRACUNIT>>2; point->fuse = TICRATE; @@ -3488,9 +3488,11 @@ void A_1upThinker(mobj_t *actor) if (closestplayer == -1 || skins[players[closestplayer].skin].sprites[SPR2_LIFE].numframes == 0) { // Closest player not found (no players in game?? may be empty dedicated server!), or does not have correct sprite. - if (actor->tracer) { - P_RemoveMobj(actor->tracer); - actor->tracer = NULL; + if (actor->tracer) + { + mobj_t *tracer = actor->tracer; + P_SetTarget(&actor->tracer, NULL); + P_RemoveMobj(tracer); } return; } @@ -3786,6 +3788,9 @@ void A_BossDeath(mobj_t *mo) // if all bosses are dead for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2 != mo && (mo2->flags & MF_BOSS) && mo2->health > 0) goto bossjustdie; // other boss not dead - just go straight to dying! @@ -3884,6 +3889,9 @@ bossjustdie: // scan the thinkers to find the runaway point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_BOSSFLYPOINT) @@ -6137,6 +6145,9 @@ void A_RingExplode(mobj_t *actor) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2 == actor) // Don't explode yourself! Endless loop! @@ -7263,7 +7274,7 @@ void A_Boss2PogoTarget(mobj_t *actor) if (actor->info->missilestate) // spawn the pogo stick collision box { mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, (mobjtype_t)actor->info->missilestate); - pogo->target = actor; + P_SetTarget(&pogo->target, actor); } actor->reactiontime = 1; @@ -7835,6 +7846,9 @@ void A_Boss3Path(mobj_t *actor) // the number for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_BOSS3WAYPOINT) continue; @@ -8227,6 +8241,9 @@ void A_FindTarget(mobj_t *actor) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)locvar1) @@ -8289,6 +8306,9 @@ void A_FindTracer(mobj_t *actor) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)locvar1) @@ -8873,6 +8893,9 @@ void A_RemoteAction(mobj_t *actor) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)locvar1) @@ -9136,6 +9159,9 @@ void A_SetObjectTypeState(mobj_t *actor) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)loc2lw) @@ -9771,6 +9797,9 @@ void A_CheckThingCount(mobj_t *actor) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)loc1up) @@ -13061,9 +13090,10 @@ static boolean PIT_TNTExplode(mobj_t *nearby) if (barrel->target == nearby) { mobj_t *tar = barrel->target; // temporarily store barrel's target - barrel->target = NULL; + P_SetTarget(&barrel->target, NULL); P_DamageMobj(nearby, barrel, NULL, 1, 0); - barrel->target = tar; + if (!P_MobjWasRemoved(barrel)) + P_SetTarget(&barrel->target, tar); } else { @@ -13565,7 +13595,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) door->extravalue2 = 0; // Origin door - door->tracer = actor; + P_SetTarget(&door->tracer, actor); //Back door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR); @@ -13578,7 +13608,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) door->extravalue2 = 0; // Origin door - door->tracer = actor; + P_SetTarget(&door->tracer, actor); } // Function: A_MinecartSparkThink diff --git a/src/p_floor.c b/src/p_floor.c index ed2afd13d..c01e568d0 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1975,22 +1975,27 @@ void T_ThwompSector(levelspecthink_t *thwomp) } else // Not going anywhere, so look for players. { - thinker_t *th; - mobj_t *mo; - if (!rover || (rover->flags & FF_EXISTS)) { - // scan the thinkers to find players! - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + UINT8 i; + // scan the players to find victims! + for (i = 0; i < MAXPLAYERS; i++) { - mo = (mobj_t *)th; - if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator - && mo->z <= thwomp->sector->ceilingheight - && P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT) - { - thwomp->direction = -1; - break; - } + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; + if (!players[i].mo) + continue; + if (!players[i].mo->health) + continue; + if (players[i].mo->z > thwomp->sector->ceilingheight) + continue; + if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96 * FRACUNIT) + continue; + + thwomp->direction = -1; + break; } } diff --git a/src/p_inter.c b/src/p_inter.c index bdf88ff44..abf33429f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -99,6 +99,9 @@ void P_ClearStarPost(INT32 postnum) // scan the thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_STARPOST) @@ -125,10 +128,15 @@ void P_ResetStarposts(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + post = (mobj_t *)th; - if (post->type == MT_STARPOST) - P_SetMobjState(post, post->info->spawnstate); + if (post->type != MT_STARPOST) + continue; + + P_SetMobjState(post, post->info->spawnstate); } } @@ -828,19 +836,22 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // scan the thinkers to find the corresponding anchorpoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_IDEYAANCHOR) - { - if (mo2->health == toucher->tracer->health) // do ideya numberes match? - anchorpoint = mo2; - else if (toucher->tracer->hnext && mo2->health == toucher->tracer->hnext->health) - anchorpoint2 = mo2; + if (mo2->type != MT_IDEYAANCHOR) + continue; - if ((!toucher->tracer->hnext && anchorpoint) - || (toucher->tracer->hnext && anchorpoint && anchorpoint2)) - break; - } + if (mo2->health == toucher->tracer->health) // do ideya numberes match? + anchorpoint = mo2; + else if (toucher->tracer->hnext && mo2->health == toucher->tracer->hnext->health) + anchorpoint2 = mo2; + + if ((!toucher->tracer->hnext && anchorpoint) + || (toucher->tracer->hnext && anchorpoint && anchorpoint2)) + break; } if (anchorpoint) @@ -919,6 +930,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // scan the remaining thinkers for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2 == special) @@ -966,6 +980,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // in from the paraloop. Isn't this just so efficient? for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) @@ -1337,6 +1354,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // scan the remaining thinkers to find koopa for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_KOOPA) @@ -1434,6 +1454,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_STARPOST) @@ -2572,9 +2595,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget UINT32 i = 0; // to check how many clones we've removed // scan the thinkers to make sure all the old pinch dummies are gone on death - // this can happen if the boss was hurt earlier than expected for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)th; if (mo->type != (mobjtype_t)target->info->mass) continue; diff --git a/src/p_local.h b/src/p_local.h index 5216286c0..cb8f95533 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -61,8 +61,8 @@ #define P_GetPlayerHeight(player) FixedMul(player->height, player->mo->scale) #define P_GetPlayerSpinHeight(player) FixedMul(player->spinheight, player->mo->scale) -typedef enum{ - THINK_LIMBO, +typedef enum +{ THINK_POLYOBJ, THINK_MAIN, THINK_MOBJ, diff --git a/src/p_maputl.c b/src/p_maputl.c index 1be57399c..0ca84096a 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -1093,7 +1093,10 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *)) { P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed! if (!func(mobj)) + { + P_SetTarget(&bnext, NULL); return false; + } if (P_MobjWasRemoved(tmthing) // func just popped our tmthing, cannot continue. || (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue. { diff --git a/src/p_mobj.c b/src/p_mobj.c index a57998ea0..1cb7f742d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -716,6 +716,9 @@ void P_EmeraldManager(void) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)think; if (mo->type == MT_EMERALDSPAWN) @@ -3694,6 +3697,9 @@ void P_DestroyRobots(void) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)think; if (mo->health <= 0 || !(mo->flags & (MF_ENEMY|MF_BOSS))) continue; // not a valid enemy @@ -4426,6 +4432,9 @@ static void P_Boss3Thinker(mobj_t *mobj) // this can happen if the boss was hurt earlier than expected for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != (mobjtype_t)mobj->info->mass) continue; @@ -4524,6 +4533,9 @@ static void P_Boss3Thinker(mobj_t *mobj) // the number for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_BOSS3WAYPOINT) continue; @@ -4662,7 +4674,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz) } dz /= 9; - + while ((base = base->tracer)) // there are 10 per spoke, remember that { dx = (originx + P_ReturnThrustX(mobj, angle, (9*132)<x)/9; @@ -4832,8 +4844,8 @@ static void P_Boss4Thinker(mobj_t *mobj) P_SetTarget(&seg->target, mobj); for (i = 0; i < 9; i++) { - seg->hnext = P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE); - seg->hnext->hprev = seg; + P_SetTarget(&seg->hnext, P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE)); + P_SetTarget(&seg->hnext->hprev, seg); seg = seg->hnext; } } @@ -5245,6 +5257,9 @@ static void P_Boss7Thinker(mobj_t *mobj) // Find waypoint he is closest to for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint) { @@ -5297,6 +5312,9 @@ static void P_Boss7Thinker(mobj_t *mobj) // the waypoint to use for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && (mo2->spawnpoint->options & 7) == waypointNum) { @@ -5427,14 +5445,17 @@ static void P_Boss9Thinker(mobj_t *mobj) // Build a hoop linked list of 'em! for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS9GATHERPOINT) { if (last) - last->hnext = mo2; + P_SetTarget(&last->hnext, mo2); else - mobj->hnext = mo2; - mo2->hprev = last; + P_SetTarget(&mobj->hnext, mo2); + P_SetTarget(&mo2->hprev, last); last = mo2; } } @@ -6072,6 +6093,9 @@ mobj_t *P_GetClosestAxis(mobj_t *source) // scan the thinkers to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == MT_AXIS) @@ -6841,12 +6865,14 @@ static void P_RemoveOverlay(mobj_t *thing) { mobj_t *mo; for (mo = overlaycap; mo; mo = mo->hnext) - if (mo->hnext == thing) - { - P_SetTarget(&mo->hnext, thing->hnext); - P_SetTarget(&thing->hnext, NULL); - return; - } + { + if (mo->hnext != thing) + continue; + + P_SetTarget(&mo->hnext, thing->hnext); + P_SetTarget(&thing->hnext, NULL); + return; + } } void A_BossDeath(mobj_t *mo); @@ -8046,7 +8072,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->tracer->z += mobj->height; } break; - case MT_WAVINGFLAG: + case MT_WAVINGFLAG1: + case MT_WAVINGFLAG2: { fixed_t base = (leveltime<<(FRACBITS+1)); mobj_t *seg = mobj->tracer, *prev = mobj; @@ -9649,15 +9676,14 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BIGMINE: mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS; break; - case MT_WAVINGFLAG: + case MT_WAVINGFLAG1: + case MT_WAVINGFLAG2: { mobj_t *prev = mobj, *cur; UINT8 i; - mobj->destscale <<= 2; - P_SetScale(mobj, mobj->destscale); for (i = 0; i <= 16; i++) // probably should be < but staying authentic to the Lua version { - cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_WAVINGFLAGSEG); + cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, ((mobj->type == MT_WAVINGFLAG1) ? MT_WAVINGFLAGSEG1 : MT_WAVINGFLAGSEG2));; P_SetTarget(&prev->tracer, cur); cur->extravalue1 = i; prev = cur; @@ -9751,7 +9777,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->momx = 1; //stack hack break; case MT_MINECARTEND: - mobj->tracer = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID); + P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID)); mobj->tracer->angle = mobj->angle + ANGLE_90; break; default: @@ -9960,37 +9986,28 @@ void P_RemoveMobj(mobj_t *mobj) P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); - // free block // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. - if (mobj->flags & MF_NOTHINK && !mobj->thinker.next) +#ifdef SCRAMBLE_REMOVED + // Invalidate mobj_t data to cause crashes if accessed! + memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); +#endif + + // free block + if (!mobj->thinker.next) { // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through! + INT32 prevreferences; if (!mobj->thinker.references) { -#ifdef SCRAMBLE_REMOVED - // Invalidate mobj_t data to cause crashes if accessed! - memset(mobj, 0xff, sizeof(mobj_t)); -#endif - Z_Free(mobj); // No refrences? Can be removed immediately! :D - } - else - { // Add thinker just to delay removing it until refrences are gone. - mobj->flags &= ~MF_NOTHINK; - P_AddThinker(THINK_MOBJ, (thinker_t *)mobj); -#ifdef SCRAMBLE_REMOVED - // Invalidate mobj_t data to cause crashes if accessed! - memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); -#endif - P_RemoveThinker((thinker_t *)mobj); + Z_Free(mobj); // No refrrences? Can be removed immediately! :D + return; } + + prevreferences = mobj->thinker.references; + P_AddThinker(THINK_MOBJ, (thinker_t *)mobj); + mobj->thinker.references = prevreferences; } - else - { -#ifdef SCRAMBLE_REMOVED - // Invalidate mobj_t data to cause crashes if accessed! - memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); -#endif - P_RemoveThinker((thinker_t *)mobj); - } + + P_RemoveThinker((thinker_t *)mobj); } // This does not need to be added to Lua. @@ -11737,13 +11754,14 @@ ML_EFFECT5 : Don't stop thinking when too far away P_SpawnMobjFromMobj(mobj, -1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; } break; - case MT_CEZPOLE: + case MT_CEZPOLE1: + case MT_CEZPOLE2: { // Spawn the banner angle_t mobjangle = FixedAngle(mthing->angle<angle = mobjangle + ANGLE_90; + 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; } break; case MT_HHZTREE_TOP: @@ -11821,6 +11839,9 @@ ML_EFFECT5 : Don't stop thinking when too far away // See if other starposts exist in this level that have the same value. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2 == mobj) @@ -12124,11 +12145,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) // Link all the sprites in the hoop together if (nextmobj) { - mobj->hprev = nextmobj; - mobj->hprev->hnext = mobj; + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); } else - mobj->hprev = mobj->hnext = NULL; + P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL)); nextmobj = mobj; } @@ -12154,9 +12175,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) mobj->z -= mobj->height/2; // Link all the collision sprites together. - mobj->hnext = NULL; - mobj->hprev = nextmobj; - mobj->hprev->hnext = mobj; + P_SetTarget(&mobj->hnext, NULL); + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); nextmobj = mobj; } @@ -12181,9 +12202,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) mobj->z -= mobj->height/2; // Link all the collision sprites together. - mobj->hnext = NULL; - mobj->hprev = nextmobj; - mobj->hprev->hnext = mobj; + P_SetTarget(&mobj->hnext, NULL); + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); nextmobj = mobj; } @@ -12266,11 +12287,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) // Link all the sprites in the hoop together if (nextmobj) { - mobj->hprev = nextmobj; - mobj->hprev->hnext = mobj; + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); } else - mobj->hprev = mobj->hnext = NULL; + P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL)); nextmobj = mobj; } @@ -12307,9 +12328,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) mobj->z -= mobj->height/2; // Link all the collision sprites together. - mobj->hnext = NULL; - mobj->hprev = nextmobj; - mobj->hprev->hnext = mobj; + P_SetTarget(&mobj->hnext, NULL); + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); nextmobj = mobj; } diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 09d449b39..475fa41b7 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1495,6 +1495,7 @@ void Polyobj_InitLevel(void) mqueue_t anchorqueue; mobjqitem_t *qitem; INT32 i, numAnchors = 0; + mobj_t *mo; M_QueueInit(&spawnqueue); M_QueueInit(&anchorqueue); @@ -1510,7 +1511,10 @@ void Polyobj_InitLevel(void) // the mobj_t pointers on a queue for use below. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - mobj_t *mo = (mobj_t *)th; + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM || mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM) @@ -1815,6 +1819,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th) // We redo this each tic to make savegame compatibility easier. for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { + if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -1893,28 +1900,31 @@ void T_PolyObjWaypoint(polywaypoint_t *th) // Find next waypoint for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { + if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == th->sequence) + if (mo2->threshold != th->sequence) + continue; + + if (th->direction == -1) { - if (th->direction == -1) + if (mo2->health == target->health - 1) { - if (mo2->health == target->health - 1) - { - waypoint = mo2; - break; - } + waypoint = mo2; + break; } - else + } + else + { + if (mo2->health == target->health + 1) { - if (mo2->health == target->health + 1) - { - waypoint = mo2; - break; - } + waypoint = mo2; + break; } } } @@ -1929,27 +1939,30 @@ void T_PolyObjWaypoint(polywaypoint_t *th) for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { + if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == th->sequence) + if (mo2->threshold != th->sequence) + continue; + + if (th->direction == -1) { - if (th->direction == -1) + if (waypoint == NULL) + waypoint = mo2; + else if (mo2->health > waypoint->health) + waypoint = mo2; + } + else + { + if (mo2->health == 0) { - if (waypoint == NULL) - waypoint = mo2; - else if (mo2->health > waypoint->health) - waypoint = mo2; - } - else - { - if (mo2->health == 0) - { - waypoint = mo2; - break; - } + waypoint = mo2; + break; } } } @@ -1963,28 +1976,31 @@ void T_PolyObjWaypoint(polywaypoint_t *th) for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { + if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == th->sequence) + if (mo2->threshold != th->sequence) + continue; + + if (th->direction == -1) { - if (th->direction == -1) + if (mo2->health == target->health - 1) { - if (mo2->health == target->health - 1) - { - waypoint = mo2; - break; - } + waypoint = mo2; + break; } - else + } + else + { + if (mo2->health == target->health + 1) { - if (mo2->health == target->health + 1) - { - waypoint = mo2; - break; - } + waypoint = mo2; + break; } } } @@ -2511,36 +2527,39 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // Find the first waypoint we need to use for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { + if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == th->sequence) + if (mo2->threshold != th->sequence) + continue; + + if (th->direction == -1) // highest waypoint # { - if (th->direction == -1) // highest waypoint # + if (mo2->health == 0) + last = mo2; + else { - if (mo2->health == 0) - last = mo2; - else - { - if (first == NULL) - first = mo2; - else if (mo2->health > first->health) - first = mo2; - } - } - else // waypoint 0 - { - if (mo2->health == 0) + if (first == NULL) first = mo2; - else - { - if (last == NULL) - last = mo2; - else if (mo2->health > last->health) - last = mo2; - } + else if (mo2->health > first->health) + first = mo2; + } + } + else // waypoint 0 + { + if (mo2->health == 0) + first = mo2; + else + { + if (last == NULL) + last = mo2; + else if (mo2->health > last->health) + last = mo2; } } } @@ -2579,28 +2598,31 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) target = first; /*for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { + if (wp->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == th->sequence) + if (mo2->threshold != th->sequence) + continue; + + if (th->direction == -1) // highest waypoint # { - if (th->direction == -1) // highest waypoint # + if (mo2->health == first->health - 1) { - if (mo2->health == first->health - 1) - { - target = mo2; - break; - } + target = mo2; + break; } - else // waypoint 0 + } + else // waypoint 0 + { + if (mo2->health == first->health + 1) { - if (mo2->health == first->health + 1) - { - target = mo2; - break; - } + target = mo2; + break; } } }*/ diff --git a/src/p_saveg.c b/src/p_saveg.c index 06baa9528..09df38eb0 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2174,7 +2174,6 @@ static void P_NetArchiveThinkers(void) for (i = 0; i < NUM_THINKERLISTS; i++) { UINT32 numsaved = 0; - // save off the current thinkers for (th = thlist[i].next; th != &thlist[i]; th = th->next) { @@ -2405,12 +2404,12 @@ static void P_NetArchiveThinkers(void) } #endif // ESLOPE #ifdef PARANOIA - else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection + else if (th->function.acp1 != P_RemoveThinkerDelayed) // wait garbage collection I_Error("unknown thinker type %p", th->function.acp1); #endif } - CONS_Debug(DBG_NETPLAY, "%u thinkers saved\n", numsaved); + CONS_Debug(DBG_NETPLAY, "%u thinkers saved in list %d\n", numsaved, i); WRITEUINT8(save_p, tc_end); } @@ -2427,9 +2426,14 @@ mobj_t *P_FindNewPosition(UINT32 oldposition) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mobj = (mobj_t *)th; - if (mobj->mobjnum == oldposition) - return mobj; + if (mobj->mobjnum != oldposition) + continue; + + return mobj; } CONS_Debug(DBG_GAMELOGIC, "mobj not found\n"); return NULL; @@ -3404,7 +3408,7 @@ static void P_NetUnArchiveThinkers(void) { for (;;) { - thinker_t* th; + thinker_t* th = NULL; tclass = READUINT8(save_p); if (tclass == tc_end) @@ -3597,22 +3601,22 @@ static void P_NetUnArchiveThinkers(void) P_AddThinker(i, th); } - CONS_Debug(DBG_NETPLAY, "%u thinkers loaded\n", numloaded); + CONS_Debug(DBG_NETPLAY, "%u thinkers loaded in list %d\n", numloaded, i); + } - if (restoreNum) + if (restoreNum) + { + executor_t *delay = NULL; + UINT32 mobjnum; + for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; + currentthinker = currentthinker->next) { - executor_t *delay = NULL; - UINT32 mobjnum; - for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; - currentthinker = currentthinker->next) - { - if (currentthinker->function.acp1 == (actionf_p1)T_ExecutorDelay) - { - delay = (void *)currentthinker; - if ((mobjnum = (UINT32)(size_t)delay->caller)) - delay->caller = P_FindNewPosition(mobjnum); - } - } + if (currentthinker->function.acp1 != (actionf_p1)T_ExecutorDelay) + continue; + delay = (void *)currentthinker; + if (!(mobjnum = (UINT32)(size_t)delay->caller)) + continue; + delay->caller = P_FindNewPosition(mobjnum); } } } @@ -3723,6 +3727,9 @@ static inline void P_FinishMobjs(void) for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; currentthinker = currentthinker->next) { + if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mobj = (mobj_t *)currentthinker; mobj->info = &mobjinfo[mobj->type]; } @@ -3738,6 +3745,9 @@ static void P_RelinkPointers(void) for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; currentthinker = currentthinker->next) { + if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mobj = (mobj_t *)currentthinker; if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) @@ -4115,6 +4125,9 @@ void P_SaveNetGame(void) // Assign the mobjnumber for pointer tracking for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mobj = (mobj_t *)th; if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) continue; diff --git a/src/p_setup.c b/src/p_setup.c index 7aaad233d..c0aa7ffa3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -817,6 +817,9 @@ void P_ReloadRings(void) // scan the thinkers to find rings/spheres/hoops to unset for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)th; if (mo->type == MT_HOOPCENTER) @@ -883,6 +886,9 @@ void P_SwitchSpheresBonusMode(boolean bonustime) // scan the thinkers to find spheres to switch for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)th; if (mo->type != MT_BLUESPHERE && mo->type != MT_NIGHTSCHIP @@ -2284,7 +2290,6 @@ static void P_LevelInitStuff(void) void P_LoadThingsOnly(void) { // Search through all the thinkers. - mobj_t *mo; thinker_t *think; INT32 i, viewid = -1, centerid = -1; // for skyboxes @@ -2301,10 +2306,9 @@ void P_LoadThingsOnly(void) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - mo = (mobj_t *)think; - - if (mo) - P_RemoveMobj(mo); + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + P_RemoveMobj((mobj_t *)think); } P_LevelInitStuff(); @@ -2864,7 +2868,10 @@ boolean P_SetupLevel(boolean skipprecip) // reset the player starts for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = NULL; + playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; + + for (i = 0; i < MAX_DM_STARTS; i++) + deathmatchstarts[i] = NULL; for (i = 0; i < 2; i++) skyboxmo[i] = NULL; @@ -2900,7 +2907,10 @@ boolean P_SetupLevel(boolean skipprecip) // reset the player starts for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = NULL; + playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; + + for (i = 0; i < MAX_DM_STARTS; i++) + deathmatchstarts[i] = NULL; for (i = 0; i < 2; i++) skyboxmo[i] = NULL; diff --git a/src/p_spec.c b/src/p_spec.c index 4a7ec59e9..3cd0461e2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2260,7 +2260,7 @@ void P_SwitchWeather(INT32 weathernum) thinker_t *think; precipmobj_t *precipmobj; - for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) + for (think = thlist[THINK_PRECIP].next; think != &thlist[THINK_PRECIP]; think = think->next) { if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker @@ -2276,7 +2276,7 @@ void P_SwitchWeather(INT32 weathernum) precipmobj_t *precipmobj; state_t *st; - for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) + for (think = thlist[THINK_PRECIP].next; think != &thlist[THINK_PRECIP]; think = think->next) { if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker @@ -3992,6 +3992,9 @@ void P_SetupSignExit(player_t *player) // spin all signposts in the level then. for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + thing = (mobj_t *)think; if (thing->type != MT_SIGN) continue; @@ -4017,20 +4020,18 @@ boolean P_IsFlagAtBase(mobjtype_t flag) { thinker_t *think; mobj_t *mo; - INT32 specialnum = 0; + INT32 specialnum = (flag == MT_REDFLAG) ? 3 : 4; for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)think; if (mo->type != flag) continue; - if (mo->type == MT_REDFLAG) - specialnum = 3; - else if (mo->type == MT_BLUEFLAG) - specialnum = 4; - if (GETSECSPECIAL(mo->subsector->sector->special, 4) == specialnum) return true; else if (mo->subsector->sector->ffloors) // Check the 3D floors @@ -4045,9 +4046,11 @@ boolean P_IsFlagAtBase(mobjtype_t flag) if (GETSECSPECIAL(rover->master->frontsector->special, 4) != specialnum) continue; - if (mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector) - && mo->z >= P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector)) - return true; + if (!(mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector) + && mo->z >= P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))) + continue; + + return true; } } } @@ -4451,9 +4454,12 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers // The chimps are my friends.. heeheeheheehehee..... - LouisJM for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; mo2 = (mobj_t *)th; - if (mo2->type == MT_EGGTRAP) - P_KillMobj(mo2, NULL, player->mo, 0); + if (mo2->type != MT_EGGTRAP) + continue; + P_KillMobj(mo2, NULL, player->mo, 0); } // clear the special so you can't push the button twice. @@ -4754,14 +4760,20 @@ DoneSection2: // to find the first waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_TUBEWAYPOINT && mo2->threshold == sequence - && mo2->health == 0) - { - waypoint = mo2; - break; - } + if (mo2->type != MT_TUBEWAYPOINT) + continue; + if (mo2->threshold != sequence) + continue; + if (mo2->health != 0) + continue; + + waypoint = mo2; + break; } if (!waypoint) @@ -4830,15 +4842,20 @@ DoneSection2: // to find the last waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_TUBEWAYPOINT && mo2->threshold == sequence) - { - if (!waypoint) - waypoint = mo2; - else if (mo2->health > waypoint->health) - waypoint = mo2; - } + if (mo2->type != MT_TUBEWAYPOINT) + continue; + if (mo2->threshold != sequence) + continue; + + if (!waypoint) + waypoint = mo2; + else if (mo2->health > waypoint->health) + waypoint = mo2; } if (!waypoint) @@ -4979,6 +4996,9 @@ DoneSection2: // to find the first waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -5014,6 +5034,9 @@ DoneSection2: // Find waypoint before this one (waypointlow) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -5038,6 +5061,9 @@ DoneSection2: // Find waypoint after this one (waypointhigh) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) diff --git a/src/p_tick.c b/src/p_tick.c index 56f91d820..a0f6edef9 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -44,6 +44,9 @@ void Command_Numthinkers_f(void) INT32 count = 0; actionf_p1 action; thinker_t *think; + thinklistnum_t start = 0; + thinklistnum_t end = NUM_THINKERLISTS - 1; + thinklistnum_t i; if (gamestate != GS_LEVEL) { @@ -70,6 +73,7 @@ void Command_Numthinkers_f(void) switch (num) { case 1: + start = end = THINK_MOBJ; action = (actionf_p1)P_MobjThinker; CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker"); break; @@ -82,14 +86,17 @@ void Command_Numthinkers_f(void) CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker"); break;*/ case 2: + start = end = THINK_PRECIP; action = (actionf_p1)P_NullPrecipThinker; CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker"); break; case 3: + start = end = THINK_MAIN; action = (actionf_p1)T_Friction; CONS_Printf(M_GetText("Number of %s: "), "T_Friction"); break; case 4: + start = end = THINK_MAIN; action = (actionf_p1)T_Pusher; CONS_Printf(M_GetText("Number of %s: "), "T_Pusher"); break; @@ -102,12 +109,15 @@ void Command_Numthinkers_f(void) return; } - for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) + for (i = start; i <= end; i++) { - if (think->function.acp1 != action) - continue; + for (think = thlist[i].next; think != &thlist[i]; think = think->next) + { + if (think->function.acp1 != action) + continue; - count++; + count++; + } } CONS_Printf("%d\n", count); @@ -141,6 +151,9 @@ void Command_CountMobjs_f(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + if (((mobj_t *)th)->type == i) count++; } @@ -158,6 +171,9 @@ void Command_CountMobjs_f(void) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + if (((mobj_t *)th)->type == i) count++; } @@ -180,6 +196,10 @@ void P_InitThinkers(void) // Adds a new thinker at the end of the list. void P_AddThinker(const thinklistnum_t n, thinker_t *thinker) { +#ifdef PARANOIA + I_Assert(n >= 0 && n < NUM_THINKERLISTS); +#endif + thlist[n].prev->next = thinker; thinker->next = &thlist[n]; thinker->prev = thlist[n].prev; @@ -206,22 +226,33 @@ static thinker_t *currentthinker; // remove it, and set currentthinker to one node preceeding it, so // that the next step in P_RunThinkers() will get its successor. // -void P_RemoveThinkerDelayed(void *pthinker) +void P_RemoveThinkerDelayed(thinker_t *thinker) { - thinker_t *thinker = pthinker; - if (!thinker->references) + thinker_t *next; +#ifdef PARANOIA +#define BEENAROUNDBIT (0x40000000) // has to be sufficiently high that it's unlikely to happen in regular gameplay. If you change this, pay attention to the bit pattern of INT32_MIN. + if (thinker->references & ~BEENAROUNDBIT) { - { - /* Remove from main thinker list */ - thinker_t *next = thinker->next; - /* Note that currentthinker is guaranteed to point to us, - * and since we're freeing our memory, we had better change that. So - * point it to thinker->prev, so the iterator will correctly move on to - * thinker->prev->next = thinker->next */ - (next->prev = currentthinker = thinker->prev)->next = next; - } - Z_Free(thinker); + if (thinker->references & BEENAROUNDBIT) // Usually gets cleared up in one frame; what's going on here, then? + CONS_Printf("Number of potentially faulty references: %d\n", (thinker->references & ~BEENAROUNDBIT)); + thinker->references |= BEENAROUNDBIT; + return; } +#undef BEENAROUNDBIT +#else + if (thinker->references) + return; +#endif + + /* Remove from main thinker list */ + next = thinker->next; + /* Note that currentthinker is guaranteed to point to us, + * and since we're freeing our memory, we had better change that. So + * point it to thinker->prev, so the iterator will correctly move on to + * thinker->prev->next = thinker->next */ + (next->prev = currentthinker = thinker->prev)->next = next; + + Z_Free(thinker); } // @@ -238,23 +269,10 @@ void P_RemoveThinkerDelayed(void *pthinker) // void P_RemoveThinker(thinker_t *thinker) { - thinker_t *next = thinker->next; #ifdef HAVE_BLUA LUA_InvalidateUserdata(thinker); #endif - thinker->function.acp1 = P_RemoveThinkerDelayed; - - if (currentthinker == thinker) - currentthinker = thinker->prev; - - // Remove thinker from its current list. - (next->prev = thinker->prev)->next = next; - - // Now add it to the limbo list - thlist[THINK_LIMBO].prev->next = thinker; - thinker->next = &thlist[THINK_LIMBO]; - thinker->prev = thlist[THINK_LIMBO].prev; - thlist[THINK_LIMBO].prev = thinker; + thinker->function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; } /* @@ -307,8 +325,10 @@ static inline void P_RunThinkers(void) { for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next) { - if (currentthinker->function.acp1) - currentthinker->function.acp1(currentthinker); +#ifdef PARANOIA + I_Assert(currentthinker->function.acp1 != NULL) +#endif + currentthinker->function.acp1(currentthinker); } } diff --git a/src/p_tick.h b/src/p_tick.h index 169c54c8e..8551ccc76 100644 --- a/src/p_tick.h +++ b/src/p_tick.h @@ -27,7 +27,7 @@ void Command_CountMobjs_f(void); void P_Ticker(boolean run); void P_PreTicker(INT32 frames); void P_DoTeamscrambling(void); -void P_RemoveThinkerDelayed(void *pthinker); //killed +void P_RemoveThinkerDelayed(thinker_t *thinker); //killed mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98 #endif diff --git a/src/p_user.c b/src/p_user.c index 79a726fe6..b758cebe4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -345,9 +345,16 @@ UINT8 P_FindLowestMare(void) // to find the egg capsule with the lowest mare for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_EGGCAPSULE && mo2->health > 0) + if (mo2->type != MT_EGGCAPSULE) + continue; + if (mo2->health <= 0) + continue; + { const UINT8 threshold = (UINT8)mo2->threshold; if (mare == 255) @@ -391,29 +398,32 @@ boolean P_TransferToNextMare(player_t *player) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_AXIS) - { - if (mo2->threshold == mare) - { - if (closestaxis == NULL) - { - closestaxis = mo2; - lowestaxisnum = mo2->health; - dist2 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y)-mo2->radius; - } - else if (mo2->health < lowestaxisnum) - { - dist1 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y)-mo2->radius; + if (mo2->type != MT_AXIS) + continue; - if (dist1 < dist2) - { - closestaxis = mo2; - lowestaxisnum = mo2->health; - dist2 = dist1; - } - } + if (mo2->threshold != mare) + continue; + + if (closestaxis == NULL) + { + closestaxis = mo2; + lowestaxisnum = mo2->health; + dist2 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y) - mo2->radius; + } + else if (mo2->health < lowestaxisnum) + { + dist1 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y) - mo2->radius; + + if (dist1 < dist2) + { + closestaxis = mo2; + lowestaxisnum = mo2->health; + dist2 = dist1; } } } @@ -439,17 +449,22 @@ static mobj_t *P_FindAxis(INT32 mare, INT32 axisnum) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; // Axis things are only at beginning of list. if (!(mo2->flags2 & MF2_AXIS)) return NULL; - if (mo2->type == MT_AXIS) - { - if (mo2->health == axisnum && mo2->threshold == mare) - return mo2; - } + if (mo2->type != MT_AXIS) + continue; + if (mo2->health != axisnum) + continue; + if (mo2->threshold != mare) + continue; + return mo2; } return NULL; @@ -469,17 +484,22 @@ static mobj_t *P_FindAxisTransfer(INT32 mare, INT32 axisnum, mobjtype_t type) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; // Axis things are only at beginning of list. if (!(mo2->flags2 & MF2_AXIS)) return NULL; - if (mo2->type == type) - { - if (mo2->health == axisnum && mo2->threshold == mare) - return mo2; - } + if (mo2->type != type) + continue; + if (mo2->health != axisnum) + continue; + if (mo2->threshold != mare) + continue; + return mo2; } return NULL; @@ -505,27 +525,31 @@ void P_TransferToAxis(player_t *player, INT32 axisnum) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_AXIS) - { - if (mo2->health == axisnum && mo2->threshold == mare) - { - if (closestaxis == NULL) - { - closestaxis = mo2; - dist2 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y)-mo2->radius; - } - else - { - dist1 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y)-mo2->radius; + if (mo2->type != MT_AXIS) + continue; + if (mo2->health != axisnum) + continue; + if (mo2->threshold != mare) + continue; - if (dist1 < dist2) - { - closestaxis = mo2; - dist2 = dist1; - } - } + if (closestaxis == NULL) + { + closestaxis = mo2; + dist2 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y) - mo2->radius; + } + else + { + dist1 = R_PointToDist2(player->mo->x, player->mo->y, mo2->x, mo2->y) - mo2->radius; + + if (dist1 < dist2) + { + closestaxis = mo2; + dist2 = dist1; } } } @@ -602,6 +626,9 @@ static void P_DeNightserizePlayer(player_t *player) // Check to see if the player should be killed. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (!(mo2->type == MT_NIGHTSDRONE)) continue; @@ -1617,6 +1644,9 @@ void P_SpawnShieldOrb(player_t *player) // blaze through the thinkers to see if an orb already exists! for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + shieldobj = (mobj_t *)th; if (shieldobj->type == orbtype && shieldobj->target == player->mo) @@ -2019,7 +2049,7 @@ boolean P_PlayerHitFloor(player_t *player) fixed_t mu = FixedMul(player->maxdash, player->mo->scale); fixed_t mu2 = FixedHypot(player->mo->momx, player->mo->momy); fixed_t ev; - mobj_t *missile; + mobj_t *missile = NULL; if (mu2 < mu) mu2 = mu; ev = (50*FRACUNIT - (mu/25))/50; @@ -3625,7 +3655,8 @@ static void P_DoTeeter(player_t *player) if (teeter) // only bother with objects as a last resort if you were already teetering { mobj_t *oldtmthing = tmthing; - tmthing = teeterer = player->mo; + teeterer = player->mo; + P_SetTarget(&tmthing, teeterer); teeterxl = teeterxh = player->mo->x; teeteryl = teeteryh = player->mo->y; couldteeter = false; @@ -3639,7 +3670,7 @@ static void P_DoTeeter(player_t *player) } teeterdone: teeter = solidteeter; - tmthing = oldtmthing; // restore old tmthing, goodness knows what the game does with this before mobj thinkers + P_SetTarget(&tmthing, oldtmthing); // restore old tmthing, goodness knows what the game does with this before mobj thinkers } } if (teeter) @@ -4314,7 +4345,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (P_IsLocalPlayer(player)) // Only display it on your own view. { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - visual->target = lockon; + P_SetTarget(&visual->target, lockon); } } if ((cmd->buttons & BT_USE) && !(player->pflags & PF_USEDOWN)) @@ -4589,6 +4620,9 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2 == player->mo) @@ -4637,7 +4671,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (P_IsLocalPlayer(player)) // Only display it on your own view. { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - visual->target = lockon; + P_SetTarget(&visual->target, lockon); } } @@ -5783,29 +5817,32 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad // Find next waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; // Axis things are only at beginning of list. if (!(mo2->flags2 & MF2_AXIS)) break; + if (!(mo2->type == MT_AXISTRANSFER || mo2->type == MT_AXISTRANSFERLINE)) + continue; + if (mo2->threshold != sequence) + continue; - if ((mo2->type == MT_AXISTRANSFER || mo2->type == MT_AXISTRANSFERLINE) - && mo2->threshold == sequence) + if (player->pflags & PF_TRANSFERTOCLOSEST) { - if (player->pflags & PF_TRANSFERTOCLOSEST) - { - if (mo2->health == player->axis1->health) - transfer1 = mo2; - else if (mo2->health == player->axis2->health) - transfer2 = mo2; - } - else - { - if (mo2->health == player->mo->target->health) - transfer1 = mo2; - else if (mo2->health == player->mo->target->health + 1) - transfer2 = mo2; - } + if (mo2->health == player->axis1->health) + transfer1 = mo2; + else if (mo2->health == player->axis2->health) + transfer2 = mo2; + } + else + { + if (mo2->health == player->mo->target->health) + transfer1 = mo2; + else if (mo2->health == player->mo->target->health + 1) + transfer2 = mo2; } } @@ -5816,24 +5853,28 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; // Axis things are only at beginning of list. if (!(mo2->flags2 & MF2_AXIS)) break; + if (!(mo2->type == MT_AXISTRANSFER || mo2->type == MT_AXISTRANSFERLINE)) + continue; + if (mo2->threshold != sequence) + continue; - if (mo2->threshold == sequence && (mo2->type == MT_AXISTRANSFER || mo2->type == MT_AXISTRANSFERLINE)) + if (!transfer1) { - if (!transfer1) - { - transfer1 = mo2; - transfer1last = true; - } - else if (mo2->health > transfer1->health) - { - transfer1 = mo2; - transfer1last = true; - } + transfer1 = mo2; + transfer1last = true; + } + else if (mo2->health > transfer1->health) + { + transfer1 = mo2; + transfer1last = true; } } } @@ -5841,24 +5882,28 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; // Axis things are only at beginning of list. if (!(mo2->flags2 & MF2_AXIS)) break; + if (!(mo2->type == MT_AXISTRANSFER || mo2->type == MT_AXISTRANSFERLINE)) + continue; + if (mo2->threshold != sequence) + continue; - if (mo2->threshold == sequence && (mo2->type == MT_AXISTRANSFER || mo2->type == MT_AXISTRANSFERLINE)) + if (!transfer2) { - if (!transfer2) - { - transfer2 = mo2; - transfer2last = true; - } - else if (mo2->health > transfer2->health) - { - transfer2 = mo2; - transfer2last = true; - } + transfer2 = mo2; + transfer2last = true; + } + else if (mo2->health > transfer2->health) + { + transfer2 = mo2; + transfer2last = true; } } } @@ -6545,31 +6590,32 @@ static void P_NiGHTSMovement(player_t *player) // to find the closest axis point for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_AXIS) - { - if (mo2->threshold == player->mare) - { - if (closestaxis == NULL) - { - closestaxis = mo2; - dist2 = R_PointToDist2(newx, newy, mo2->x, mo2->y)-mo2->radius; - } - else - { - dist1 = R_PointToDist2(newx, newy, mo2->x, mo2->y)-mo2->radius; + if (mo2->type != MT_AXIS) + continue; + if (mo2->threshold != player->mare) + continue; - if (dist1 < dist2) - { - closestaxis = mo2; - dist2 = dist1; - } - } + if (closestaxis == NULL) + { + closestaxis = mo2; + dist2 = R_PointToDist2(newx, newy, mo2->x, mo2->y) - mo2->radius; + } + else + { + dist1 = R_PointToDist2(newx, newy, mo2->x, mo2->y) - mo2->radius; + + if (dist1 < dist2) + { + closestaxis = mo2; + dist2 = dist1; } } } - P_SetTarget(&player->mo->target, closestaxis); } @@ -7352,6 +7398,9 @@ static void P_MovePlayer(player_t *player) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == MT_EGGCAPSULE @@ -7855,7 +7904,7 @@ static void P_MovePlayer(player_t *player) if (P_IsLocalPlayer(player)) // Only display it on your own view. { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker - visual->target = lockon; + P_SetTarget(&visual->target, lockon); P_SetMobjStateNF(visual, visual->info->spawnstate+1); } } @@ -8256,20 +8305,25 @@ static void P_DoZoomTube(player_t *player) // Find next waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == sequence) - { - if ((reverse && mo2->health == player->mo->tracer->health - 1) - || (!reverse && mo2->health == player->mo->tracer->health + 1)) - { - waypoint = mo2; - break; - } - } + if (mo2->threshold != sequence) + continue; + + if (reverse && mo2->health != player->mo->tracer->health - 1) + continue; + + if (!reverse && mo2->health != player->mo->tracer->health + 1) + continue; + + waypoint = mo2; + break; } if (waypoint) @@ -8387,19 +8441,22 @@ static void P_DoRopeHang(player_t *player) // Find next waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == sequence) - { - if (mo2->health == player->mo->tracer->health + 1) - { - waypoint = mo2; - break; - } - } + if (mo2->threshold != sequence) + continue; + + if (mo2->health != player->mo->tracer->health + 1) + continue; + + waypoint = mo2; + break; } if (!(player->mo->tracer->flags & MF_SLIDEME) && !waypoint) @@ -8409,19 +8466,22 @@ static void P_DoRopeHang(player_t *player) // Wrap around back to first waypoint for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) continue; - if (mo2->threshold == sequence) - { - if (mo2->health == 0) - { - waypoint = mo2; - break; - } - } + if (mo2->threshold != sequence) + continue; + + if (mo2->health != 0) + continue; + + waypoint = mo2; + break; } } @@ -8468,22 +8528,22 @@ static void P_DoRopeHang(player_t *player) static void P_NukeAllPlayers(player_t *player) { mobj_t *mo; - thinker_t *think; + UINT8 i; - for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + for (i = 0; i < MAXPLAYERS; i++) { - mo = (mobj_t *)think; - - if (!mo->player) + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; + if (!players[i].mo) + continue; + if (players[i].mo == player->mo) + continue; + if (players[i].mo->health <= 0) continue; - if (mo->health <= 0) // dead - continue; - - if (mo == player->mo) - continue; - - P_DamageMobj(mo, player->mo, player->mo, 1, 0); + P_DamageMobj(players[i].mo, player->mo, player->mo, 1, 0); } CONS_Printf(M_GetText("%s caused a world of pain.\n"), player_names[player-players]); @@ -8517,6 +8577,9 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)think; if (!(mo->flags & MF_SHOOTABLE) && !(mo->type == MT_EGGGUARD || mo->type == MT_MINUS)) @@ -8565,6 +8628,9 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo = (mobj_t *)think; if (!((mo->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (mo->flags & MF_SHOOTABLE)) || (mo->flags & MF_SPRING)) == !(mo->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag continue; // not a valid target @@ -8706,6 +8772,9 @@ void P_FindEmerald(void) // to find all emeralds for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (mo2->type == MT_EMERHUNT) { @@ -9931,6 +10000,9 @@ static mobj_t *P_GetAxis(INT32 num) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mobj = (mobj_t *)th; // NiGHTS axes spawn before anything else. If this mobj doesn't have MF2_AXIS, it means we reached the axes' end. @@ -9943,6 +10015,7 @@ static mobj_t *P_GetAxis(INT32 num) return mobj; } + CONS_Alert(CONS_WARNING, "P_GetAxis: Track segment %d is missing!\n", num); return NULL; } @@ -10569,6 +10642,9 @@ void P_PlayerThink(player_t *player) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; if (!(mo2->type == MT_RING || mo2->type == MT_COIN diff --git a/src/r_data.c b/src/r_data.c index c490cc7da..6889bddde 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2276,7 +2276,8 @@ void R_PrecacheLevel(void) if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "R_PrecacheLevel"); for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - spritepresent[((mobj_t *)th)->sprite] = 1; + if (th->function.acp1 != (actionf_p1)P_RemoveThinkerDelayed) + spritepresent[((mobj_t *)th)->sprite] = 1; spritememory = 0; for (i = 0; i < numsprites; i++) diff --git a/src/r_things.c b/src/r_things.c index 4b1586455..c791571ac 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2446,9 +2446,11 @@ static void R_DrawMaskedList (drawnode_t* head) void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) { - drawnode_t heads[nummasks]; /**< Drawnode lists; as many as number of views/portals. */ + drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */ SINT8 i; + heads = calloc(nummasks, sizeof(drawnode_t)); + for (i = 0; i < nummasks; i++) { heads[i].next = heads[i].prev = &heads[i]; @@ -2474,6 +2476,8 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) R_DrawMaskedList(&heads[nummasks - 1]); R_ClearDrawNodes(&heads[nummasks - 1]); } + + free(heads); } // ========================================================================== diff --git a/src/s_sound.c b/src/s_sound.c index 2db8392d7..66b5d4f72 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1988,8 +1988,10 @@ void GameMIDIMusic_OnChange(void) } } +#ifdef HAVE_OPENMPT void ModFilter_OnChange(void) { if (openmpt_mhandle) openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index d05a0d324..72c38b3dc 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -277,6 +277,7 @@ + @@ -430,6 +431,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index ca6bd38d2..9e442000f 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -453,6 +453,9 @@ Hw_Hardware + + R_Rend + @@ -894,6 +897,10 @@ Hw_Hardware + + + R_Rend + diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 3932d23d3..7bf67559c 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -108,14 +108,16 @@ static UINT16 current_track; #endif #ifdef HAVE_OPENMPT -int mod_err = OPENMPT_ERROR_OK; +static int mod_err = OPENMPT_ERROR_OK; static const char *mod_err_str; static UINT16 current_subsong; +static size_t probesize; +static int result; #endif static void var_cleanup(void) { - loop_point = song_length = 0.0f; + song_length = loop_point = 0.0f; music_bytes = fading_source = fading_target =\ fading_timer = fading_duration = 0; @@ -388,7 +390,7 @@ void *I_GetSfx(sfxinfo_t *sfx) gme_track_info(emu, &info, 0); len = (info->play_length * 441 / 10) << 2; - mem = malloc(len); + mem = Z_Malloc(len, PU_SOUND, 0); gme_play(emu, len >> 1, mem); gme_free_info(info); gme_delete(emu); @@ -461,7 +463,7 @@ void *I_GetSfx(sfxinfo_t *sfx) gme_track_info(emu, &info, 0); len = (info->play_length * 441 / 10) << 2; - mem = malloc(len); + mem = Z_Malloc(len, PU_SOUND, 0); gme_play(emu, len >> 1, mem); gme_free_info(info); gme_delete(emu); @@ -1112,6 +1114,36 @@ boolean I_LoadSong(char *data, size_t len) } #endif +#ifdef HAVE_OPENMPT + /* + If the size of the data to be checked is bigger than the recommended size (> 2048) + Let's just set the probe size to the recommended size + Otherwise let's give it the full data size + */ + + if (len > openmpt_probe_file_header_get_recommended_size()) + probesize = openmpt_probe_file_header_get_recommended_size(); + else + probesize = len; + + result = openmpt_probe_file_header(OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT, data, probesize, len, NULL, NULL, NULL, NULL, NULL, NULL); + + if (result == OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS) // We only cared if it succeeded, continue on if not. + { + openmpt_mhandle = openmpt_module_create_from_memory2(data, len, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (!openmpt_mhandle) // Failed to create module handle? Show error and return! + { + mod_err = openmpt_module_error_get_last(openmpt_mhandle); + mod_err_str = openmpt_error_string(mod_err); + CONS_Alert(CONS_ERROR, "openmpt_module_create_from_memory2: %s\n", mod_err_str); + return false; + } + else + return true; // All good and we're ready for music playback! + } +#endif + + // Let's see if Mixer is able to load this. rw = SDL_RWFromMem(data, len); if (rw != NULL) { @@ -1123,40 +1155,6 @@ boolean I_LoadSong(char *data, size_t len) return false; } -#ifdef HAVE_OPENMPT - switch(Mix_GetMusicType(music)) - { - case MUS_MODPLUG: - case MUS_MOD: - openmpt_mhandle = openmpt_module_create_from_memory2(data, len, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (!openmpt_mhandle) - { - mod_err = openmpt_module_error_get_last(openmpt_mhandle); - mod_err_str = openmpt_error_string(mod_err); - CONS_Alert(CONS_ERROR, "openmpt_module_create_from_memory2: %s\n", mod_err_str); - Mix_FreeMusic(music); - music = NULL; - return false; - } - else - { - Mix_FreeMusic(music); - music = NULL; - return true; - } - break; - case MUS_WAV: - case MUS_MID: - case MUS_OGG: - case MUS_MP3: - case MUS_FLAC: - Mix_HookMusic(NULL, NULL); - break; - default: - break; - } -#endif - // Find the OGG loop point. loop_point = 0.0f; song_length = 0.0f; diff --git a/src/st_stuff.c b/src/st_stuff.c index 132eada06..4122793ad 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2308,27 +2308,31 @@ static void ST_doItemFinderIconsAndSound(void) // Scan thinkers to find emblem mobj with these ids for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; - if (mo2->type == MT_EMBLEM) + if (mo2->type != MT_EMBLEM) + continue; + + if (!(mo2->flags & MF_SPECIAL)) + continue; + + for (i = 0; i < stemblems; ++i) { - if (!(mo2->flags & MF_SPECIAL)) - continue; - - for (i = 0; i < stemblems; ++i) + if (mo2->health == emblems[i] + 1) { - if (mo2->health == emblems[i]+1) - { - soffset = (i * 20) - ((stemblems-1) * 10); + soffset = (i * 20) - ((stemblems - 1) * 10); - newinterval = ST_drawEmeraldHuntIcon(mo2, itemhoming, soffset); - if (newinterval && (!interval || newinterval < interval)) - interval = newinterval; + newinterval = ST_drawEmeraldHuntIcon(mo2, itemhoming, soffset); + if (newinterval && (!interval || newinterval < interval)) + interval = newinterval; - break; - } + break; } } + } if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0) diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index acab2507a..c0fe8eda9 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -293,6 +293,7 @@ + @@ -443,6 +444,7 @@ + diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index c21cedb8a..93806e395 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -456,6 +456,10 @@ Hw_Hardware + + + R_Rend + @@ -857,6 +861,10 @@ Hw_Hardware + + + R_Rend + From 9ea7a6dfca96ec8df153b02db9e157d6836cf87c Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 3 Aug 2019 17:30:51 -0400 Subject: [PATCH 003/130] Work on menus --- src/g_game.h | 2 ++ src/m_menu.c | 82 ++++++++++++++++++++++++++++++--------------------- src/p_inter.c | 5 ++-- src/p_setup.c | 6 +++- src/p_tick.c | 4 +++ 5 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/g_game.h b/src/g_game.h index 3cbde9a3c..dd0058e70 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -31,6 +31,8 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern player_t players[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS]; +extern boolean gameovermus; + // ====================================== // DEMO playback/recording related stuff. // ====================================== diff --git a/src/m_menu.c b/src/m_menu.c index 5e164ecb9..a2206771a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2480,16 +2480,14 @@ static void M_HandleMenuPresState(menu_t *newMenu) curfadevalue = 16; curhidepics = hidetitlepics; curbgcolor = -1; - curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; - curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed; + curbgxspeed = titlescrollxspeed; + curbgyspeed = titlescrollyspeed; curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus // don't do the below during the in-game menus if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) return; - // Find current presentation values - M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY"); M_SetMenuCurFadeValue(16); M_SetMenuCurHideTitlePics(); @@ -4820,31 +4818,33 @@ static void M_HandleLevelPlatter(INT32 choice) if (!(levellistmode == LLM_CREATESERVER && !lsrow)) { ifselectvalnextmapnobrace(lscol) - lsoffs[0] = lsoffs[1] = 0; - S_StartSound(NULL,sfx_menu1); - if (gamestate == GS_TIMEATTACK) - M_SetupNextMenu(currentMenu->prevMenu); - else if (currentMenu == &MISC_ChangeLevelDef) - { - if (currentMenu->prevMenu && currentMenu->prevMenu != &MPauseDef) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ChangeLevel(0); - Z_Free(levelselect.rows); - levelselect.rows = NULL; - } - else - M_LevelSelectWarp(0); - Nextmap_OnChange(); - } - else if (!lsoffs[0]) // prevent sound spam + lsoffs[0] = lsoffs[1] = 0; + S_StartSound(NULL,sfx_menu1); + + if (gamestate == GS_TIMEATTACK) + M_SetupNextMenu(currentMenu->prevMenu); + else if (currentMenu == &MISC_ChangeLevelDef) { - lsoffs[0] = -8; - S_StartSound(NULL,sfx_s3kb2); + if (currentMenu->prevMenu && currentMenu->prevMenu != &MPauseDef) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ChangeLevel(0); + Z_Free(levelselect.rows); + levelselect.rows = NULL; } - break; + else + M_LevelSelectWarp(0); + Nextmap_OnChange(); } + } + else if (!lsoffs[0]) + { + lsoffs[0] = -8; + S_StartSound(NULL,sfx_s3kb2); + } + break; /* FALLTHRU */ + case KEY_RIGHTARROW: if (levellistmode == LLM_CREATESERVER && !lsrow) { @@ -4906,7 +4906,6 @@ static void M_HandleLevelPlatter(INT32 choice) case KEY_ESCAPE: exitmenu = true; break; - default: break; } @@ -5054,12 +5053,13 @@ static void M_DrawLevelPlatterMenu(void) INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow); const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation)); - if (gamestate == GS_TIMEATTACK) + if (currentMenu->prevMenu == &SP_TimeAttackDef) { + M_SetMenuCurBackground("RECATTBG"); + curbgxspeed = 0; curbgyspeed = 18; - curbghide = false; - strncpy(curbgname, "RECATTBG", 8); + if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) @@ -5068,14 +5068,27 @@ static void M_DrawLevelPlatterMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - if (!curbghide || !titlemapinaction) + if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) { V_DrawSciencePatch(0, -(130<prevMenu == &SP_NightsAttackDef) + { + M_SetMenuCurBackground("SRB2BACK"); + + if (curbgcolor >= 0) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); + else if (!curbghide || !titlemapinaction) + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + if (curfadevalue) + V_DrawFadeScreen(0xFF00, curfadevalue); + } + // finds row at top of the screen while (y > -8) { @@ -8082,11 +8095,11 @@ void M_DrawTimeAttackMenu(void) UINT16 dispstatus; patch_t *PictureOfUrFace; + M_SetMenuCurBackground("RECATTBG"); + curbgxspeed = 0; curbgyspeed = 18; - curbghide = false; - strncpy(curbgname, "RECATTBG", 8); M_ChangeMenuMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback if (curbgcolor >= 0) @@ -8097,10 +8110,11 @@ void M_DrawTimeAttackMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - if (!curbghide || !titlemapinaction) + if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) { V_DrawSciencePatch(0, -(130<= 0) diff --git a/src/p_inter.c b/src/p_inter.c index abf33429f..e66cf4a6c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2445,7 +2445,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { - boolean gameovermus = false; + gameovermus = false; if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1)) { INT32 i; @@ -2465,8 +2465,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (gameovermus) { - S_StopMusic(); // Stop the Music! Tails 03-14-2000 - S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000 + S_FadeOutStopMusic(1000); // Stop the Music! Tails 03-14-2000 } if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers) diff --git a/src/p_setup.c b/src/p_setup.c index c0aa7ffa3..f47cccf25 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -81,6 +81,10 @@ #include "p_slopes.h" #endif +// Game over stuff +boolean gameovermus; +INT32 fadetogameovermus; + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -2619,7 +2623,7 @@ boolean P_SetupLevel(boolean skipprecip) boolean loadedbm = false; sector_t *ss; boolean chase; - + gameovermus = false; levelloading = true; // This is needed. Don't touch. diff --git a/src/p_tick.c b/src/p_tick.c index a0f6edef9..388245be5 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -24,6 +24,7 @@ // Object place #include "m_cheat.h" +boolean gameovermus; tic_t leveltime; @@ -724,6 +725,9 @@ void P_Ticker(boolean run) P_MapEnd(); + if ((leveltime % (TICRATE * 2) == 0) && gameovermus) + S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000 + // Z_CheckMemCleanup(); } From 00b73e2209c56ecfe1ead844994b585ea2645e29 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 3 Aug 2019 21:21:01 -0400 Subject: [PATCH 004/130] Stuff --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index a2206771a..bef8b0923 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -159,7 +159,7 @@ static INT32 vidm_previousmode; static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; -tic_t recfgtimer = 0; +INT32 recfgtimer = 0; // // PROTOTYPES @@ -8114,7 +8114,7 @@ void M_DrawTimeAttackMenu(void) { V_DrawSciencePatch(0, -(130< Date: Sun, 4 Aug 2019 13:26:25 -0400 Subject: [PATCH 005/130] More menu stuff --- src/g_game.h | 1 + src/m_menu.c | 25 +++++++++++++++++++------ src/p_inter.c | 4 +--- src/p_setup.c | 1 + src/p_tick.c | 8 +++++++- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/g_game.h b/src/g_game.h index dd0058e70..409226423 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -31,6 +31,7 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern player_t players[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS]; +extern INT32 fadetogameovermus; extern boolean gameovermus; // ====================================== diff --git a/src/m_menu.c b/src/m_menu.c index bef8b0923..079e07685 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -159,7 +159,7 @@ static INT32 vidm_previousmode; static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; -INT32 recfgtimer = 0; +tic_t recfgtimer = 0; // // PROTOTYPES @@ -1710,7 +1710,7 @@ static menu_t SP_NightsGhostDef = menu_t SP_PlayerDef = { MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), - "M_PICKP", + NULL, sizeof (SP_PlayerMenu)/sizeof (menuitem_t), &SP_MainDef, SP_PlayerMenu, @@ -5052,6 +5052,7 @@ static void M_DrawLevelPlatterMenu(void) UINT8 iter = lsrow, sizeselect = (lswide(lsrow) ? 1 : 0); INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow); const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation)); + angle_t fa; if (currentMenu->prevMenu == &SP_TimeAttackDef) { @@ -5070,9 +5071,10 @@ static void M_DrawLevelPlatterMenu(void) // Draw and animate foreground if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) { + fa = (FixedAngle(((recfgtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawSciencePatch(0, -(130<= 0) @@ -7709,8 +7713,10 @@ static void M_DrawSetupChoosePlayerMenu(void) if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); + M_SetMenuCurBackground("CHARBG"); + // Character select profile images!1 - M_DrawTextBox(0, my, 16, 20); + //M_DrawTextBox(0, my, 16, 20); if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); @@ -7727,6 +7733,11 @@ static void M_DrawSetupChoosePlayerMenu(void) else i = char_on; + charskin = &skins[i]; + col = (charskin->prefcolor - 1)*2; + col = Color_Index[Color_Opposite[col]-1][Color_Opposite[col+1]]; + V_DrawMappedPatch(0, 0, 0, W_CachePatchName("CHARBG", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE)); + // Get prev character... prev = description[i].prev; @@ -7779,7 +7790,7 @@ static void M_DrawSetupChoosePlayerMenu(void) M_DrawMenuTitle(); // Character description - M_DrawTextBox(136, my, 21, 20); + //M_DrawTextBox(136, my, 21, 20); V_DrawString(146, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); } @@ -8094,6 +8105,7 @@ void M_DrawTimeAttackMenu(void) INT32 i, x, y, cursory = 0; UINT16 dispstatus; patch_t *PictureOfUrFace; + angle_t fa; M_SetMenuCurBackground("RECATTBG"); @@ -8112,9 +8124,10 @@ void M_DrawTimeAttackMenu(void) // Draw and animate foreground if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) { + fa = (FixedAngle(((recfgtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawSciencePatch(0, -(130< 0) + fadetogameovermus--; + + CONS_Printf("%d\n", fadetogameovermus); + + if (fadetogameovermus == 150 && gameovermus) S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000 // Z_CheckMemCleanup(); From 59cdfa8e272a670ad6bd7e11966dec9b89e7ca67 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 18 Aug 2019 17:32:52 -0400 Subject: [PATCH 006/130] New music for record attack and nights attack menus --- src/m_menu.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 815b7bcbb..63002e44a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2243,8 +2243,10 @@ void M_InitMenuPresTables(void) { menupres[i].muslooping = true; } - if (i == MN_SP_TIMEATTACK || i == MN_SP_NIGHTSATTACK) - strncpy(menupres[i].musname, "_inter", 7); + if (i == MN_SP_TIMEATTACK) + strncpy(menupres[i].musname, "recatk", 7); + else if (i == MN_SP_NIGHTSATTACK) + strncpy(menupres[i].musname, "nitatk", 7); else if (i == MN_SP_PLAYER) strncpy(menupres[i].musname, "_chsel", 7); } @@ -8159,7 +8161,7 @@ void M_DrawTimeAttackMenu(void) curbgxspeed = 0; curbgyspeed = 18; - M_ChangeMenuMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback + M_ChangeMenuMusic("recatk", true); // Eww, but needed for when user hits escape during demo playback if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); @@ -8174,7 +8176,7 @@ void M_DrawTimeAttackMenu(void) fa = (FixedAngle(((recfgtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawSciencePatch(0, -(130<= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); From 778461028e5123344412cc4df46135897798f59a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 18 Aug 2019 19:34:54 -0300 Subject: [PATCH 007/130] Character select WIP --- src/m_menu.c | 177 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 148 insertions(+), 29 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 815b7bcbb..c2dc64479 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -159,7 +159,14 @@ static INT32 vidm_previousmode; static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; -tic_t recfgtimer = 0; + +// new menus +static tic_t charseltimer = 0; +static tic_t charselscrollx = 0; +static tic_t recfgtimer = 0; + +#define charscrollamt 128*FRACUNIT +#define charselfadescrollamt 128*FRACUNIT // // PROTOTYPES @@ -7186,6 +7193,9 @@ skiplife: } } } + + if (currentMenu == &SP_LoadDef && (charseltimer > 0)) + M_DrawSetupChoosePlayerMenu(); } static void M_DrawLoad(void) @@ -7657,6 +7667,10 @@ static void M_SetupChoosePlayer(INT32 choice) if (Playing() == false) M_ChangeMenuMusic("_chsel", true); + charseltimer = 0; + charselscrollx = charselfadescrollamt; + //wipegamestate = -1; + SP_PlayerDef.prevMenu = currentMenu; M_SetupNextMenu(&SP_PlayerDef); if (!allowed) @@ -7684,6 +7698,12 @@ static void M_HandleChoosePlayerMenu(INT32 choice) boolean exitmenu = false; // exit to previous menu INT32 selectval; + // How do I detect key hold events? + if (char_scroll) + return; + else if (charselscrollx) + return; + switch (choice) { case KEY_DOWNARROW: @@ -7691,7 +7711,7 @@ static void M_HandleChoosePlayerMenu(INT32 choice) { S_StartSound(NULL,sfx_s3kb7); char_on = selectval; - char_scroll = -128*FRACUNIT; + char_scroll = -charscrollamt; Z_Free(char_notes); char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); } @@ -7707,7 +7727,7 @@ static void M_HandleChoosePlayerMenu(INT32 choice) { S_StartSound(NULL,sfx_s3kb7); char_on = selectval; - char_scroll = 128*FRACUNIT; + char_scroll = charscrollamt; Z_Free(char_notes); char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); } @@ -7733,6 +7753,9 @@ static void M_HandleChoosePlayerMenu(INT32 choice) if (exitmenu) { + // Is this a hack? + charselscrollx = charselfadescrollamt; + charseltimer = TICRATE/4; if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); else @@ -7741,25 +7764,38 @@ static void M_HandleChoosePlayerMenu(INT32 choice) } // Draw the choose player setup menu, had some fun with player anim +static INT32 getskinfromdescription(INT32 desc) +{ + char *and = strchr(description[desc].skinname, '&'); + if (and) + { + char firstskin[SKINNAMESIZE]; + strncpy(firstskin, description[desc].skinname, and - (description[desc].skinname)); + return R_SkinAvailable(firstskin); + } + return R_SkinAvailable(description[desc].skinname); +} + static void M_DrawSetupChoosePlayerMenu(void) { - const INT32 my = 24; - patch_t *patch; - INT32 i, o; - UINT8 prev, next; + const INT32 my = 16; + //patch_t *patch; + INT32 i; + //UINT8 prev, next; UINT16 col; UINT8 *colormap = NULL; - skin_t *charskin = NULL; + skin_t *charskin = &skins[0]; + INT32 skinnum = 0; + INT32 fade = FixedInt(FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT))), fade2; + INT32 xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselscrollx, charselfadescrollamt))); + boolean thismenu = (currentMenu == &SP_PlayerDef); - // Black BG - if (curbgcolor >= 0) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); - else if (!curbghide || !titlemapinaction) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); - if (curfadevalue) - V_DrawFadeScreen(0xFF00, curfadevalue); + if (!thismenu) + xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselfadescrollamt-charselscrollx, charselfadescrollamt))); - M_SetMenuCurBackground("CHARBG"); + fade2 = fade< 9) + fade2 = 0; // Character select profile images!1 //M_DrawTextBox(0, my, 16, 20); @@ -7769,7 +7805,12 @@ static void M_DrawSetupChoosePlayerMenu(void) else // close enough. char_scroll = 0; // just be exact now. - o = (char_scroll >> FRACBITS) + 16; + if (abs(charselscrollx) > FRACUNIT) + charselscrollx -= (charselscrollx>>2); + else // close enough. + charselscrollx = 0; // just be exact now. + + /*o = (char_scroll >> FRACBITS) + 16; if (o < 0) // A little hacky... { @@ -7777,18 +7818,57 @@ static void M_DrawSetupChoosePlayerMenu(void) o += 128; } else - i = char_on; + i = char_on;*/ - charskin = &skins[i]; - col = SKINCOLOR_GREEN; - //col = Color_Index[Color_Opposite[col]-1][Color_Opposite[col+1]]; - colormap = R_GetTranslationColormap(i, col, 0); - V_DrawMappedPatch(0, 0, 0, W_CachePatchName("CHARBG", PU_CACHE), colormap); + skinnum = getskinfromdescription(char_on); + if (skinnum != -1) + charskin = &skins[skinnum]; - // Get prev character... - prev = description[i].prev; + col = Color_Opposite[(charskin->prefcolor - 1)*2]; + colormap = R_GetTranslationColormap(skinnum, col, 0); - if (prev != i) // If there's more than one character available... + // Yes. + if (thismenu) + { + M_DrawLoadGameData(); + charseltimer++; + } + else if (charseltimer > 0) + charseltimer--; + + // CHARBG + // 101 + if (fade > 0) + { + if (fade > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, colormap[101]); + else + V_DrawFadeScreen(colormap[101], fade); + } + // 106 + if (thismenu) + { + INT32 sw = (BASEVIDWIDTH * vid.dupx); + INT32 bw = (vid.width - sw) / 2; + col = colormap[106]; + if (bw) + { + V_DrawFill(0, 0, bw, vid.height, V_NOSCALESTART|col); + V_DrawFill(bw+sw, 0, bw, vid.height, V_NOSCALESTART|col); + } + } + for (i = -12; i < (BASEVIDHEIGHT/32) + 12; i++) + { + INT32 oy = (i*32), y; + if (!thismenu) + break; + y = oy - (32 - (charseltimer%32)); + V_DrawFixedPatch(0, y<width), SHORT(patch->height) - (o-32)); } - W_UnlockCachedPatch(patch); + W_UnlockCachedPatch(patch);*/ + + // Needs to be character select pictures instead of a tall image + V_DrawScaledPatch(8-xsh, my - ((128 * char_on) - 16) - FixedInt(char_scroll), 0, W_CachePatchName("ROULETTE", PU_CACHE)); + + { + INT32 ox = 32, x, y; + INT32 oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; + patch_t *curpatch, *prevpatch, *nextpatch; + + // Needs to be SPR2 bullshit + // Or even better, make a font for it + const char *patchformat = "CHRNME%02d"; + + curpatch = W_CachePatchName(va(patchformat, char_on), PU_CACHE); + prevpatch = W_CachePatchName(va(patchformat, char_on-1), PU_CACHE); + nextpatch = W_CachePatchName(va(patchformat, char_on+1), PU_CACHE); + y = my + (128 + 16); + + if (!xsh) + { + // prev + txsh = oxsh; + x = ox - txsh - 128; + V_DrawScaledPatch(x-xsh, y, fade2< Date: Sun, 18 Aug 2019 19:46:55 -0300 Subject: [PATCH 008/130] how do i code --- src/m_menu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index c932f8687..1256f3a95 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7529,6 +7529,9 @@ static void M_HandleLoadSave(INT32 choice) } if (exitmenu) { + // Is this a hack? + charselscrollx = 0; + charseltimer = 0; if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); else @@ -7936,7 +7939,7 @@ static void M_DrawSetupChoosePlayerMenu(void) { // prev txsh = oxsh; - x = ox - txsh - 128; + x = ox - txsh - (128*2); V_DrawScaledPatch(x-xsh, y, fade2< Date: Sun, 18 Aug 2019 20:35:16 -0300 Subject: [PATCH 009/130] Tweak Record Attack screen just a little bit --- src/m_menu.c | 66 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1256f3a95..6f2209096 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5090,12 +5090,31 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) } } +static void M_DrawRecordAttackBackground(void) +{ + patch_t *fg = W_CachePatchName("RECATFG", PU_CACHE); + angle_t fa; + + INT32 i; + INT32 height = (fg->height/2); + for (i = -12; i < (BASEVIDHEIGHT/height) + 12; i++) + { + INT32 y = ((i*height) - (height - ((recfgtimer*2)%height))); + V_DrawFixedPatch(0, y<>ANGLETOFINESHIFT) & FINEMASK; + V_DrawSciencePatch(160<prevMenu == &SP_TimeAttackDef) { @@ -5113,13 +5132,7 @@ static void M_DrawLevelPlatterMenu(void) // Draw and animate foreground if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) - { - fa = (FixedAngle(((recfgtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; - V_DrawSciencePatch(0, -(130<prevMenu == &SP_NightsAttackDef) @@ -7794,6 +7807,10 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 fade = FixedInt(FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT))), fade2; INT32 xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselscrollx, charselfadescrollamt))); boolean thismenu = (currentMenu == &SP_PlayerDef); + patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); + patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); + INT32 bgheight = charbg->height; + INT32 fgheight = charfg->height; if (!thismenu) xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselfadescrollamt-charselscrollx, charselfadescrollamt))); @@ -7862,15 +7879,21 @@ static void M_DrawSetupChoosePlayerMenu(void) V_DrawFill(bw+sw, 0, bw, vid.height, V_NOSCALESTART|col); } } - for (i = -12; i < (BASEVIDHEIGHT/32) + 12; i++) + + if (thismenu) { - INT32 oy = (i*32), y; - if (!thismenu) - break; - y = oy - (32 - (charseltimer%32)); - V_DrawFixedPatch(0, y<>ANGLETOFINESHIFT) & FINEMASK; - V_DrawSciencePatch(0, -(130< Date: Sun, 18 Aug 2019 22:26:52 -0300 Subject: [PATCH 010/130] More character select work --- src/dehacked.c | 11 +++- src/m_menu.c | 163 +++++++++++++++++++++---------------------------- src/m_menu.h | 2 + 3 files changed, 81 insertions(+), 95 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 2f28a74cf..3af635e0e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -313,7 +313,9 @@ static boolean findFreeSlot(INT32 *num) if (*num >= MAXSKINS) return false; - description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) + // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) + description[*num].picname[0] = '\0'; + description[*num].nametag[0] = '\0'; // Found one! ^_^ return (description[*num].used = true); @@ -400,6 +402,13 @@ static void readPlayer(MYFILE *f, INT32 num) strncpy(description[num].picname, word2, 8); } + else if (fastcmp(word, "NAMETAG")) + { + if (!slotfound && (slotfound = findFreeSlot(&num)) == false) + goto done; + + strncpy(description[num].nametag, word2, 8); + } else if (fastcmp(word, "STATUS")) { /* diff --git a/src/m_menu.c b/src/m_menu.c index 6f2209096..666174b7b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7660,6 +7660,20 @@ static void M_SetupChoosePlayer(INT32 choice) } else description[i].pic = W_CachePatchName(description[i].picname, PU_CACHE); + + if (!(description[i].nametag[0])) + { + if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 6) + { + spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; + spriteframe_t *sprframe = &sprdef->spriteframes[5]; + description[i].namepic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + } + else + description[i].namepic = W_CachePatchName("MISSING", PU_CACHE); + } + else + description[i].namepic = W_CachePatchName(description[i].nametag, PU_CACHE); } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. Z_Free(name); @@ -7796,21 +7810,23 @@ static INT32 getskinfromdescription(INT32 desc) static void M_DrawSetupChoosePlayerMenu(void) { + boolean thismenu = (currentMenu == &SP_PlayerDef); + + INT32 xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselscrollx, charselfadescrollamt))); const INT32 my = 16; - //patch_t *patch; - INT32 i; - //UINT8 prev, next; - UINT16 col; - UINT8 *colormap = NULL; + skin_t *charskin = &skins[0]; INT32 skinnum = 0; + UINT16 col; + UINT8 *colormap = NULL; + INT32 prev = -1, next = -1; + INT32 fade = FixedInt(FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT))), fade2; - INT32 xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselscrollx, charselfadescrollamt))); - boolean thismenu = (currentMenu == &SP_PlayerDef); patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); INT32 bgheight = charbg->height; INT32 fgheight = charfg->height; + INT32 i; if (!thismenu) xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselfadescrollamt-charselscrollx, charselfadescrollamt))); @@ -7819,9 +7835,6 @@ static void M_DrawSetupChoosePlayerMenu(void) if (fade > 9) fade2 = 0; - // Character select profile images!1 - //M_DrawTextBox(0, my, 16, 20); - if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); else // close enough. @@ -7832,20 +7845,20 @@ static void M_DrawSetupChoosePlayerMenu(void) else // close enough. charselscrollx = 0; // just be exact now. - /*o = (char_scroll >> FRACBITS) + 16; - - if (o < 0) // A little hacky... - { - i = description[char_on].prev; - o += 128; - } - else - i = char_on;*/ - skinnum = getskinfromdescription(char_on); if (skinnum != -1) charskin = &skins[skinnum]; + // Get prev character... + prev = description[char_on].prev; + // If there's more than one character available... + if (prev != char_on) + // Let's get the next character now. + next = description[char_on].next; + else + // No there isn't. + prev = -1; + col = Color_Opposite[(charskin->prefcolor - 1)*2]; colormap = R_GetTranslationColormap(skinnum, col, 0); @@ -7896,93 +7909,55 @@ static void M_DrawSetupChoosePlayerMenu(void) } } - /*if (prev != i) // If there's more than one character available... + // Character select pictures + V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll), 0, description[char_on].pic); + if (prev != -1) + V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) - 144, 0, description[prev].pic); + if (next != -1) + V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) + 144, 0, description[next].pic); + + // Character description + V_DrawString(146+xsh, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); + + // Name tags! { - // Let's get the next character now. - next = description[i].next; - - // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two - if (o < 32) - { - patch = description[prev].pic; - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<height) + 2*(o-32), SHORT(patch->width), 64 - 2*o); - else - V_DrawCroppedPatch(8<height) + o - 32, SHORT(patch->width), 32 - o); - W_UnlockCachedPatch(patch); - } - - // Draw next character if it's visible and its number isn't less than the current one or there's more than two - if (o < 128) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. - { - patch = description[next].pic; - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), 2*o); - else - V_DrawCroppedPatch(8<width), o); - W_UnlockCachedPatch(patch); - } - } - - patch = description[i].pic; - if (o >= 0 && o <= 32) - { - if (SHORT(patch->width) >= 256) - V_DrawSmallScaledPatch(8, my + 40 - o, 0, patch); - else - V_DrawScaledPatch(8, my + 40 - o, 0, patch); - } - else - { - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), SHORT(patch->height) - 2*(o-32)); - else - V_DrawCroppedPatch(8<width), SHORT(patch->height) - (o-32)); - } - W_UnlockCachedPatch(patch);*/ - - // Needs to be character select pictures instead of a tall image - V_DrawScaledPatch(8-xsh, my - ((128 * char_on) - 16) - FixedInt(char_scroll), 0, W_CachePatchName("ROULETTE", PU_CACHE)); - - { - INT32 ox = 32, x, y; + INT32 ox, x, y; INT32 oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; - patch_t *curpatch, *prevpatch, *nextpatch; + patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL; - // Needs to be SPR2 bullshit - // Or even better, make a font for it - const char *patchformat = "CHRNME%02d"; + // Name tag patches + curpatch = description[char_on].namepic; + if (prev != -1) prevpatch = description[prev].namepic; + if (next != -1) nextpatch = description[next].namepic; - curpatch = W_CachePatchName(va(patchformat, char_on), PU_CACHE); - prevpatch = W_CachePatchName(va(patchformat, char_on-1), PU_CACHE); - nextpatch = W_CachePatchName(va(patchformat, char_on+1), PU_CACHE); - y = my + (128 + 16); + txsh = oxsh; + ox = (8-xsh) + (description[char_on].pic)->width/2; + ox -= (curpatch->width/2); + y = my + 144; - if (!xsh) + if (char_scroll && (!xsh)) { // prev - txsh = oxsh; - x = ox - txsh - (128*2); - V_DrawScaledPatch(x-xsh, y, fade2< 0) + { + x = (ox - txsh) + BASEVIDWIDTH; + if (x < BASEVIDWIDTH) + V_DrawScaledPatch(x-xsh, y, fade2< Date: Mon, 19 Aug 2019 14:23:03 -0300 Subject: [PATCH 011/130] did The Thing --- src/dehacked.c | 2 +- src/f_finale.c | 8 ++++---- src/info.h | 6 ++++++ src/m_menu.c | 48 ++++++++++++++++++++++++++++++++---------------- src/m_menu.h | 2 +- src/st_stuff.c | 2 +- 6 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3af635e0e..2cbe953e6 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -402,7 +402,7 @@ static void readPlayer(MYFILE *f, INT32 num) strncpy(description[num].picname, word2, 8); } - else if (fastcmp(word, "NAMETAG")) + else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) { if (!slotfound && (slotfound = findFreeSlot(&num)) == false) goto done; diff --git a/src/f_finale.c b/src/f_finale.c index fedc08234..4dee32e96 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1584,15 +1584,15 @@ void F_StartEnding(void) UINT8 skinnum = players[consoleplayer].skin; spritedef_t *sprdef; spriteframe_t *sprframe; - if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 5) + if (skins[skinnum].sprites[SPR2_XTRA].numframes >= (XTRA_ENDING+2)+1) { sprdef = &skins[skinnum].sprites[SPR2_XTRA]; // character head, skin specific - sprframe = &sprdef->spriteframes[2]; + sprframe = &sprdef->spriteframes[XTRA_ENDING]; endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); - sprframe = &sprdef->spriteframes[3]; + sprframe = &sprdef->spriteframes[XTRA_ENDING+1]; endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); - sprframe = &sprdef->spriteframes[4]; + sprframe = &sprdef->spriteframes[XTRA_ENDING+2]; endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); } else // eh, yknow what? too lazy to put MISSINGs here. eggman wins if you don't give your character an ending firework display. diff --git a/src/info.h b/src/info.h index bb27ac3e3..f8eab3631 100644 --- a/src/info.h +++ b/src/info.h @@ -842,6 +842,12 @@ typedef enum playersprite NUMPLAYERSPRITES } playersprite_t; +// SPR2_XTRA +#define XTRA_LIFEPIC 0 // Life icon patch +#define XTRA_CHARSEL 1 // Character select picture +#define XTRA_NAMETAG 2 // Character select nametag +#define XTRA_ENDING 3 // Ending finale patches + typedef enum state { S_NULL, diff --git a/src/m_menu.c b/src/m_menu.c index 666174b7b..3daf1185c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3552,7 +3552,8 @@ void M_InitCharacterTables(void) strcpy(description[i].picname, ""); strcpy(description[i].skinname, ""); description[i].prev = description[i].next = 0; - description[i].pic = NULL; + description[i].charpic = NULL; + description[i].namepic = NULL; } } @@ -7630,6 +7631,7 @@ static void M_SetupChoosePlayer(INT32 choice) { if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. { + char *botskin = strchr(description[i].skinname, '&'); name = strtok(Z_StrDup(description[i].skinname), "&"); skinnum = R_SkinAvailable(name); if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) @@ -7649,31 +7651,44 @@ static void M_SetupChoosePlayer(INT32 choice) if (!(description[i].picname[0])) { - if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 2) + if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1) { spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[1]; - description[i].pic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; + description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); } else - description[i].pic = W_CachePatchName("MISSING", PU_CACHE); + description[i].charpic = W_CachePatchName("MISSING", PU_CACHE); } else - description[i].pic = W_CachePatchName(description[i].picname, PU_CACHE); + description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE); - if (!(description[i].nametag[0])) + if (!(description[i].nametag[0]) && (!botskin)) { - if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 6) + if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_NAMETAG+1) { spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[5]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_NAMETAG]; description[i].namepic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); } else - description[i].namepic = W_CachePatchName("MISSING", PU_CACHE); + { + // If no name tag patch was provided, + // the character select screen + // will simply not draw anything. + description[i].namepic = NULL; + } } else - description[i].namepic = W_CachePatchName(description[i].nametag, PU_CACHE); + { + const char *nametag = description[i].nametag; + // If no name tag patch was provided, + // the character select screen + // will simply not draw anything. + description[i].namepic = NULL; + if (W_LumpExists(nametag)) + description[i].namepic = W_CachePatchName(nametag, PU_CACHE); + } } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. Z_Free(name); @@ -7910,11 +7925,11 @@ static void M_DrawSetupChoosePlayerMenu(void) } // Character select pictures - V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll), 0, description[char_on].pic); + V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll), 0, description[char_on].charpic); if (prev != -1) - V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) - 144, 0, description[prev].pic); + V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) - 144, 0, description[prev].charpic); if (next != -1) - V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) + 144, 0, description[next].pic); + V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) + 144, 0, description[next].charpic); // Character description V_DrawString(146+xsh, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); @@ -7931,8 +7946,9 @@ static void M_DrawSetupChoosePlayerMenu(void) if (next != -1) nextpatch = description[next].namepic; txsh = oxsh; - ox = (8-xsh) + (description[char_on].pic)->width/2; - ox -= (curpatch->width/2); + ox = (8-xsh) + (description[char_on].charpic)->width/2; + if (curpatch) + ox -= (curpatch->width/2); y = my + 144; if (char_scroll && (!xsh)) diff --git a/src/m_menu.h b/src/m_menu.h index de1ba5010..2050f9952 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -317,7 +317,7 @@ typedef struct char picname[8]; char nametag[8]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 - patch_t *pic; + patch_t *charpic; patch_t *namepic; UINT8 prev; UINT8 next; diff --git a/src/st_stuff.c b/src/st_stuff.c index aefb4c53c..c1a6d5add 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -348,7 +348,7 @@ void ST_LoadFaceGraphics(INT32 skinnum) if (skins[skinnum].sprites[SPR2_XTRA].numframes) { spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[0]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_LIFEPIC]; faceprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX); if (skins[skinnum].sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes) { From 29dc1119e5450d3ad9f140e987a161883b3243c9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 19 Aug 2019 14:43:48 -0300 Subject: [PATCH 012/130] uh --- src/d_main.c | 2 +- src/f_finale.c | 1 + src/f_finale.h | 1 + src/m_menu.c | 26 ++++++++++++++++++++------ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index eaeae4b10..3838f168d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -358,7 +358,7 @@ static void D_Display(void) // clean up border stuff // see if the border needs to be initially drawn - if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide)) + if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))) { // draw the view directly diff --git a/src/f_finale.c b/src/f_finale.c index 4dee32e96..d2fc7a1e7 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -75,6 +75,7 @@ INT32 curbgcolor; INT32 curbgxspeed; INT32 curbgyspeed; boolean curbghide; +boolean hidetitlemap; // WARNING: set to false by M_SetupNextMenu and M_ClearMenus static UINT8 curDemo = 0; static UINT32 demoDelayLeft; diff --git a/src/f_finale.h b/src/f_finale.h index d640abc8a..58c492c3d 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -94,6 +94,7 @@ extern INT32 curbgcolor; extern INT32 curbgxspeed; extern INT32 curbgyspeed; extern boolean curbghide; +extern boolean hidetitlemap; #define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0]) diff --git a/src/m_menu.c b/src/m_menu.c index 3daf1185c..90d0791c0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3418,6 +3418,7 @@ void M_ClearMenus(boolean callexitmenufunc) if (currentMenu == &MessageDef) // Oh sod off! currentMenu = &MainDef; // Not like it matters menuactive = false; + hidetitlemap = false; } // @@ -3456,6 +3457,8 @@ void M_SetupNextMenu(menu_t *menudef) } } } + + hidetitlemap = false; } // @@ -7714,10 +7717,6 @@ static void M_SetupChoosePlayer(INT32 choice) if (Playing() == false) M_ChangeMenuMusic("_chsel", true); - charseltimer = 0; - charselscrollx = charselfadescrollamt; - //wipegamestate = -1; - SP_PlayerDef.prevMenu = currentMenu; M_SetupNextMenu(&SP_PlayerDef); if (!allowed) @@ -7730,7 +7729,12 @@ static void M_SetupChoosePlayer(INT32 choice) char_on = description[char_on].next; } } - char_scroll = 0; // finish scrolling the menu + + // finish scrolling the menu + char_scroll = 0; + charseltimer = 0; + charselscrollx = charselfadescrollamt; + Z_Free(char_notes); char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); } @@ -7880,7 +7884,17 @@ static void M_DrawSetupChoosePlayerMenu(void) // Yes. if (thismenu) { - M_DrawLoadGameData(); + if (charselscrollx) + { + // Don't hide the title map yet + hidetitlemap = false; + M_DrawLoadGameData(); + } + else + { + // Okay, fine, now you can + hidetitlemap = true; + } charseltimer++; } else if (charseltimer > 0) From 94e21c7b0328b3ad1746a726c6e87556bc4eac27 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 19 Aug 2019 15:27:20 -0300 Subject: [PATCH 013/130] slight cleanup --- src/m_menu.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 90d0791c0..5f52ec816 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7831,7 +7831,7 @@ static void M_DrawSetupChoosePlayerMenu(void) { boolean thismenu = (currentMenu == &SP_PlayerDef); - INT32 xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselscrollx, charselfadescrollamt))); + INT32 xsh = 0; const INT32 my = 16; skin_t *charskin = &skins[0]; @@ -7840,19 +7840,37 @@ static void M_DrawSetupChoosePlayerMenu(void) UINT8 *colormap = NULL; INT32 prev = -1, next = -1; - INT32 fade = FixedInt(FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT))), fade2; + INT32 fade = 0, fade2 = 0; patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); INT32 bgheight = charbg->height; INT32 fgheight = charfg->height; INT32 i; + // Fading out from menu if (!thismenu) - xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(charselfadescrollamt-charselscrollx, charselfadescrollamt))); + xsh = (charselfadescrollamt-charselscrollx); + // Fading in to menu + else if (charselscrollx) + xsh = charselscrollx; - fade2 = fade< 9) + // Calculate x-shift value + if (xsh) + xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(xsh, charselfadescrollamt))); + + // No fade for this frame + if (charseltimer >= TICRATE) + { + fade = 10; fade2 = 0; + } + // Fading in, or out + // Calculate the fade amount (0-9) + else + { + fade = FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT)) >> FRACBITS; + fade2 = (fade <= 9) ? fade< FRACUNIT) char_scroll -= (char_scroll>>2); From 15957bf13faccf2e1a3b7ade0be982a3976dfd0d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 19 Aug 2019 15:34:12 -0300 Subject: [PATCH 014/130] hghdfhdjhdhkdlfh --- src/m_menu.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5f52ec816..80ecfb15e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7840,7 +7840,7 @@ static void M_DrawSetupChoosePlayerMenu(void) UINT8 *colormap = NULL; INT32 prev = -1, next = -1; - INT32 fade = 0, fade2 = 0; + INT32 fade = 0; patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); INT32 bgheight = charbg->height; @@ -7860,17 +7860,11 @@ static void M_DrawSetupChoosePlayerMenu(void) // No fade for this frame if (charseltimer >= TICRATE) - { fade = 10; - fade2 = 0; - } // Fading in, or out // Calculate the fade amount (0-9) else - { fade = FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT)) >> FRACBITS; - fade2 = (fade <= 9) ? fade< FRACUNIT) char_scroll -= (char_scroll>>2); @@ -7946,13 +7940,13 @@ static void M_DrawSetupChoosePlayerMenu(void) { INT32 oy = (i*bgheight), y; y = oy - (bgheight - (charseltimer%bgheight)); - V_DrawFixedPatch(0, y< 0) { x = (ox - txsh) + BASEVIDWIDTH; if (x < BASEVIDWIDTH) - V_DrawScaledPatch(x-xsh, y, fade2< Date: Mon, 19 Aug 2019 16:19:25 -0300 Subject: [PATCH 015/130] Cool defines --- src/m_menu.c | 53 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 80ecfb15e..aaae35240 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5100,7 +5100,7 @@ static void M_DrawRecordAttackBackground(void) angle_t fa; INT32 i; - INT32 height = (fg->height/2); + INT32 height = (SHORT(fg->height)/2); for (i = -12; i < (BASEVIDHEIGHT/height) + 12; i++) { INT32 y = ((i*height) - (height - ((recfgtimer*2)%height))); @@ -7815,6 +7815,11 @@ static void M_HandleChoosePlayerMenu(INT32 choice) } // Draw the choose player setup menu, had some fun with player anim +#define CHOOSEPLAYER_USECHARCOLOUR +#define CHOOSEPLAYER_OPPOSITECOLOUR +//#define CHOOSEPLAYER_DRAWHEADER + +#ifdef CHOOSEPLAYER_USECHARCOLOUR static INT32 getskinfromdescription(INT32 desc) { char *and = strchr(description[desc].skinname, '&'); @@ -7826,6 +7831,7 @@ static INT32 getskinfromdescription(INT32 desc) } return R_SkinAvailable(description[desc].skinname); } +#endif // CHOOSEPLAYER_USECHARCOLOUR static void M_DrawSetupChoosePlayerMenu(void) { @@ -7834,17 +7840,19 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 xsh = 0; const INT32 my = 16; +#ifdef CHOOSEPLAYER_USECHARCOLOUR skin_t *charskin = &skins[0]; INT32 skinnum = 0; - UINT16 col; +#endif // CHOOSEPLAYER_USECHARCOLOUR + UINT8 col; UINT8 *colormap = NULL; INT32 prev = -1, next = -1; INT32 fade = 0; patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); - INT32 bgheight = charbg->height; - INT32 fgheight = charfg->height; + INT16 bgheight = SHORT(charbg->height); + INT16 fgheight = SHORT(charfg->height); INT32 i; // Fading out from menu @@ -7876,10 +7884,6 @@ static void M_DrawSetupChoosePlayerMenu(void) else // close enough. charselscrollx = 0; // just be exact now. - skinnum = getskinfromdescription(char_on); - if (skinnum != -1) - charskin = &skins[skinnum]; - // Get prev character... prev = description[char_on].prev; // If there's more than one character available... @@ -7890,8 +7894,25 @@ static void M_DrawSetupChoosePlayerMenu(void) // No there isn't. prev = -1; - col = Color_Opposite[(charskin->prefcolor - 1)*2]; +#ifdef CHOOSEPLAYER_USECHARCOLOUR + // Find skin number from description[] + skinnum = getskinfromdescription(char_on); + if (skinnum != -1) + charskin = &skins[skinnum]; + + // Use the character's skincolour + col = charskin->prefcolor; +#ifdef CHOOSEPLAYER_OPPOSITECOLOUR + // Use the OPPOSITE of the character's skincolour + col = Color_Opposite[(col - 1)*2]; +#endif // CHOOSEPLAYER_OPPOSITECOLOUR + + // Make the translation colourmap colormap = R_GetTranslationColormap(skinnum, col, 0); +#else + // Dark blue translation colourmap + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_COBALT, 0); +#endif // CHOOSEPLAYER_USECHARCOLOUR // Yes. if (thismenu) @@ -7972,9 +7993,9 @@ static void M_DrawSetupChoosePlayerMenu(void) if (next != -1) nextpatch = description[next].namepic; txsh = oxsh; - ox = (8-xsh) + (description[char_on].charpic)->width/2; + ox = (8-xsh) + SHORT((description[char_on].charpic)->width)/2; if (curpatch) - ox -= (curpatch->width/2); + ox -= (SHORT(curpatch->width)/2); y = my + 144; if (char_scroll && (!xsh)) @@ -8000,6 +8021,16 @@ static void M_DrawSetupChoosePlayerMenu(void) if (curpatch) V_DrawScaledPatch(x-xsh, y, 0, curpatch); } + + // Menu header +#ifdef CHOOSEPLAYER_DRAWHEADER + { + patch_t *header = W_CachePatchName("M_PICKP", PU_CACHE); + INT32 xtitle = 146; + INT32 ytitle = (35 - SHORT(header->height))/2; + V_DrawFixedPatch((xtitle+xsh)< Date: Mon, 19 Aug 2019 18:49:23 -0300 Subject: [PATCH 016/130] Fix character description text rendering. --- src/m_menu.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index aaae35240..cde73ab9e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7972,14 +7972,84 @@ static void M_DrawSetupChoosePlayerMenu(void) } // Character select pictures - V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll), 0, description[char_on].charpic); - if (prev != -1) - V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) - 144, 0, description[prev].charpic); - if (next != -1) - V_DrawScaledPatch(8-xsh, (my+16) - FixedInt(char_scroll) + 144, 0, description[next].charpic); + { + INT32 x = 8 - xsh; + INT32 y = (my+16) - FixedInt(char_scroll); + V_DrawScaledPatch(x, y, 0, description[char_on].charpic); + if (prev != -1) + V_DrawScaledPatch(x, y - 144, 0, description[prev].charpic); + if (next != -1) + V_DrawScaledPatch(x, y + 144, 0, description[next].charpic); + } // Character description - V_DrawString(146+xsh, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); + // No, I can't use strtok. + // Put two line break characters next to each other to see why. + { + char *text = char_notes; + char *first_token = text; + char *last_token = strchr(text, '\n'); + INT32 x = 146 + xsh; + INT32 y = my + 9; + INT32 flags = V_ALLOWLOWERCASE; + + // No line breaks? + // Draw entire string + if (!last_token) + V_DrawString(x, y, flags, char_notes); + // Split string by the line break character + else + { + char *string = NULL; + INT32 len; + while (true) + { + // There are still lines left do draw + if (last_token) + { + size_t shift = 0; + // Free this line + if (string) + Z_Free(string); + // Find string length, do a malloc... + len = (last_token-first_token)+1; + string = ZZ_Alloc(len); + // Copy the line + strncpy(string, first_token, len-1); + string[len-1] = '\0'; + // Don't leave a line break character + // at the start of the string! + if ((strlen(string) >= 2) && (string[0] == '\n') && (string[1] != '\n')) + shift++; + // Then draw it + V_DrawString(x, y, flags, string+shift); + } + // No line break character was found + else + { + // Don't leave a line break character + // at the start of the string! + if ((strlen(first_token) >= 2) && (first_token[0] == '\n') && (first_token[1] != '\n')) + first_token++; + V_DrawString(x, y, flags, first_token); + break; + } + + // Next line + y += 8; // V_RETURN8 + if ((last_token-text)+1 >= strlen(text)) + last_token = NULL; + else + { + first_token = last_token; + last_token = strchr(first_token+1, '\n'); + } + } + // Free this line + if (string) + Z_Free(string); + } + } // Name tags! { From 15b363773fbaeeb8e7c7ca032c48eb5072ea34d2 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 19 Aug 2019 22:10:52 -0400 Subject: [PATCH 017/130] Fix record attack foreground not appearing. I'm not sure why it suddenly broke when the same condition worked before. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index aaae35240..88ed6d571 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5135,7 +5135,7 @@ static void M_DrawLevelPlatterMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) + if (!curbghide && stricmp("RECATTBG", curbgname) < 0) M_DrawRecordAttackBackground(); } @@ -8363,7 +8363,7 @@ void M_DrawTimeAttackMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) + if (!curbghide && stricmp("RECATTBG", curbgname) < 0) M_DrawRecordAttackBackground(); M_DrawMenuTitle(); From 61866f326a2852413203765c9cc74192c38dbc84 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 20 Aug 2019 00:12:22 -0300 Subject: [PATCH 018/130] New Record Attack menu. --- src/m_menu.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 214 insertions(+), 22 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index cde73ab9e..726a5c861 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -161,9 +161,11 @@ static INT32 vidm_nummodes; static INT32 vidm_column_size; // new menus +static tic_t recatkdrawtimer = 0; +static tic_t ntsatkdrawtimer = 0; + static tic_t charseltimer = 0; static tic_t charselscrollx = 0; -static tic_t recfgtimer = 0; #define charscrollamt 128*FRACUNIT #define charselfadescrollamt 128*FRACUNIT @@ -5094,24 +5096,210 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) } } +// new menus static void M_DrawRecordAttackBackground(void) { - patch_t *fg = W_CachePatchName("RECATFG", PU_CACHE); + patch_t *fg = W_CachePatchName("RECATKFG", PU_CACHE); angle_t fa; INT32 i; INT32 height = (SHORT(fg->height)/2); for (i = -12; i < (BASEVIDHEIGHT/height) + 12; i++) { - INT32 y = ((i*height) - (height - ((recfgtimer*2)%height))); + INT32 y = ((i*height) - (height - ((recatkdrawtimer*2)%height))); V_DrawFixedPatch(0, y<>ANGLETOFINESHIFT) & FINEMASK; + fa = (FixedAngle(((recatkdrawtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawSciencePatch(160<width); + + y = (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + for (i = 0; i < (vid.width/bgwidth) + 1; i++) + { + x = ((i*(bgwidth*dupx)) + ((FixedInt(bgscrollx)%bgwidth)*dupx)); + V_DrawFixedPatch(x< 0) + { + // top border + V_DrawFill(0, 0, vid.width, border_height, V_NOSCALESTART|158); + // bottom border + V_DrawFill(0, border_height + scaled_height, vid.width, border_height, V_NOSCALESTART|31); + } + } + + // Unlock cached patch. + W_UnlockCachedPatch(background); +} + +// NiGHTS Attack foreground. +// (Yeah, I know.) +// Calls M_DrawNightsAttackMountains for the background. + +static void M_DrawNightsAttackBackground(void) +{ + INT32 x, y, snapy = 0; + INT32 dupx = vid.dupx; + INT32 dupy = vid.dupy; + INT32 i, j; + + // top + patch_t *backtopfg = W_CachePatchName("NTSATKT1", PU_CACHE); + patch_t *fronttopfg = W_CachePatchName("NTSATKT2", PU_CACHE); + INT32 backtopwidth = SHORT(backtopfg->width); + INT32 fronttopwidth = SHORT(fronttopfg->width); + + // bottom + patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_CACHE); + patch_t *frontbottomfg = W_CachePatchName("NTSATKB2", PU_CACHE); + INT32 backbottomwidth = SHORT(backbottomfg->width); + INT32 frontbottomwidth = SHORT(frontbottomfg->width); + + // top border + patch_t *topborder = W_CachePatchName("NTSATKBD", PU_CACHE); + INT32 topborderwidth = SHORT(topborder->width); + INT32 topborderheight = SHORT(topborder->height); + + // Snap patches to bottom + INT32 backbottomheight = SHORT(backbottomfg->height); + INT32 frontbottomheight = SHORT(frontbottomfg->height); + + // only use one dup, to avoid stretching (har har) + dupx = dupy = (dupx < dupy ? dupx : dupy); + + // background + M_DrawNightsAttackMountains(); + + // Center patches vertically + snapy = (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + y = snapy; + + // back top foreground patch + for (i = 0; i < (vid.width/backtopwidth) + 1; i++) + { + x = ((i*backtopwidth) - (ntsatkdrawtimer%backtopwidth)); + x *= dupx; + V_DrawFixedPatch(x< 0) + { + // top border + y = border_height - ((topborderheight-5) * vid.dupy); + for (i = 0; i < (vid.height/border_height) + 1; i++) + { + for (j = 0; j < (vid.width/topborderwidth); j++) + { + x = ((j*frontbottomwidth) - ((ntsatkdrawtimer*2)%frontbottomwidth)); + x *= dupx; + V_DrawFixedPatch(x<> 1 ) % 9) - 4); + colormap = R_GetTranslationColormap(TC_DEFAULT, super_colour, GTC_CACHE); + + fa = (FixedAngle(((ntsatkdrawtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; + + // Cache and draw patch. + supersonic_patch = W_CachePatchName(va(supersonic, timer+1), PU_CACHE); + V_DrawFixedPatch(235<prevMenu == &SP_TimeAttackDef) { - M_SetMenuCurBackground("RECATTBG"); + M_SetMenuCurBackground("RECATKBG"); curbgxspeed = 0; curbgyspeed = 18; @@ -5135,18 +5323,18 @@ static void M_DrawLevelPlatterMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) + if ((!curbghide || !titlemapinaction) && !stricmp("RECATKBG", curbgname)) M_DrawRecordAttackBackground(); } if (currentMenu->prevMenu == &SP_NightsAttackDef) { - M_SetMenuCurBackground("SRB2BACK"); + M_SetMenuCurBackground("NTSATKBG"); if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + M_DrawNightsAttackMountains(); if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); } @@ -5355,7 +5543,12 @@ static void M_DrawMessageMenu(void) if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + { + if (levellistmode == LLM_NIGHTSATTACK) + M_DrawNightsAttackMountains(); + else + F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + } if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); } @@ -8418,7 +8611,7 @@ void M_DrawTimeAttackMenu(void) UINT16 dispstatus; patch_t *PictureOfUrFace; // my WHAT - M_SetMenuCurBackground("RECATTBG"); + M_SetMenuCurBackground("RECATKBG"); curbgxspeed = 0; curbgyspeed = 18; @@ -8433,7 +8626,7 @@ void M_DrawTimeAttackMenu(void) V_DrawFadeScreen(0xFF00, curfadevalue); // Draw and animate foreground - if ((!curbghide || !titlemapinaction) && !stricmp("RECATTBG", curbgname)) + if ((!curbghide || !titlemapinaction) && !stricmp("RECATKBG", curbgname)) M_DrawRecordAttackBackground(); M_DrawMenuTitle(); @@ -8630,14 +8823,11 @@ void M_DrawNightsAttackMenu(void) INT32 i, x, y, cursory = 0; UINT16 dispstatus; - M_SetMenuCurBackground("SRB2BACK"); + M_SetMenuCurBackground("NTSATKBG"); M_ChangeMenuMusic("nitatk", true); // Eww, but needed for when user hits escape during demo playback - if (curbgcolor >= 0) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); - else if (!curbghide || !titlemapinaction) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + M_DrawNightsAttackBackground(); if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); @@ -8695,7 +8885,7 @@ void M_DrawNightsAttackMenu(void) lumpnum_t lumpnum; char beststr[40]; - UINT8 bestoverall = G_GetBestNightsGrade(cv_nextmap.value, 0); + //UINT8 bestoverall = G_GetBestNightsGrade(cv_nextmap.value, 0); UINT8 bestgrade = G_GetBestNightsGrade(cv_nextmap.value, cv_dummymares.value); UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value); tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value); @@ -8714,8 +8904,10 @@ void M_DrawNightsAttackMenu(void) V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); - if (P_HasGrades(cv_nextmap.value, 0)) - V_DrawScaledPatch(235, 135, 0, ngradeletters[bestoverall]); + // Super Sonic + M_DrawNightsAttackSuperSonic(); + //if (P_HasGrades(cv_nextmap.value, 0)) + // V_DrawScaledPatch(235 - (SHORT((ngradeletters[bestoverall])->width)*3)/2, 135, 0, ngradeletters[bestoverall]); if (P_HasGrades(cv_nextmap.value, cv_dummymares.value)) {//make bigger again @@ -8757,10 +8949,10 @@ void M_DrawNightsAttackMenu(void) } if (em->collected) - V_DrawSmallMappedPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), + V_DrawSmallMappedPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else - V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); skipThisOne: em = M_GetLevelEmblems(-1); From e4e3af7be0cbfc0fc06e6102ce909b8e968cf445 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 20 Aug 2019 00:18:34 -0300 Subject: [PATCH 019/130] Remove new character select screen transitions. I should not have implemented it in the first place. --- src/m_menu.c | 79 +++++++++------------------------------------------- 1 file changed, 13 insertions(+), 66 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 726a5c861..3c1948551 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -120,7 +120,6 @@ const char *quitmsg[NUM_QUITMESSAGES]; description_t description[MAXSKINS]; INT16 char_on = -1, startchar = 1; static char *char_notes = NULL; -static fixed_t char_scroll = 0; boolean menuactive = false; boolean fromlevelselect = false; @@ -165,10 +164,8 @@ static tic_t recatkdrawtimer = 0; static tic_t ntsatkdrawtimer = 0; static tic_t charseltimer = 0; -static tic_t charselscrollx = 0; - +static fixed_t char_scroll = 0; #define charscrollamt 128*FRACUNIT -#define charselfadescrollamt 128*FRACUNIT // // PROTOTYPES @@ -7405,9 +7402,6 @@ skiplife: } } } - - if (currentMenu == &SP_LoadDef && (charseltimer > 0)) - M_DrawSetupChoosePlayerMenu(); } static void M_DrawLoad(void) @@ -7740,7 +7734,6 @@ static void M_HandleLoadSave(INT32 choice) if (exitmenu) { // Is this a hack? - charselscrollx = 0; charseltimer = 0; if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); @@ -7926,7 +7919,6 @@ static void M_SetupChoosePlayer(INT32 choice) // finish scrolling the menu char_scroll = 0; charseltimer = 0; - charselscrollx = charselfadescrollamt; Z_Free(char_notes); char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[char_on].notes); @@ -7945,8 +7937,6 @@ static void M_HandleChoosePlayerMenu(INT32 choice) // How do I detect key hold events? if (char_scroll) return; - else if (charselscrollx) - return; switch (choice) { @@ -7998,8 +7988,7 @@ static void M_HandleChoosePlayerMenu(INT32 choice) if (exitmenu) { // Is this a hack? - charselscrollx = charselfadescrollamt; - charseltimer = TICRATE/4; + charseltimer = 0; if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); else @@ -8030,7 +8019,6 @@ static void M_DrawSetupChoosePlayerMenu(void) { boolean thismenu = (currentMenu == &SP_PlayerDef); - INT32 xsh = 0; const INT32 my = 16; #ifdef CHOOSEPLAYER_USECHARCOLOUR @@ -8041,42 +8029,17 @@ static void M_DrawSetupChoosePlayerMenu(void) UINT8 *colormap = NULL; INT32 prev = -1, next = -1; - INT32 fade = 0; patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); INT16 bgheight = SHORT(charbg->height); INT16 fgheight = SHORT(charfg->height); INT32 i; - // Fading out from menu - if (!thismenu) - xsh = (charselfadescrollamt-charselscrollx); - // Fading in to menu - else if (charselscrollx) - xsh = charselscrollx; - - // Calculate x-shift value - if (xsh) - xsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(xsh, charselfadescrollamt))); - - // No fade for this frame - if (charseltimer >= TICRATE) - fade = 10; - // Fading in, or out - // Calculate the fade amount (0-9) - else - fade = FixedMul(10*FRACUNIT, FixedDiv((charseltimer*4) * FRACUNIT, TICRATE * FRACUNIT)) >> FRACBITS; - if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); else // close enough. char_scroll = 0; // just be exact now. - if (abs(charselscrollx) > FRACUNIT) - charselscrollx -= (charselscrollx>>2); - else // close enough. - charselscrollx = 0; // just be exact now. - // Get prev character... prev = description[char_on].prev; // If there's more than one character available... @@ -8110,17 +8073,8 @@ static void M_DrawSetupChoosePlayerMenu(void) // Yes. if (thismenu) { - if (charselscrollx) - { - // Don't hide the title map yet - hidetitlemap = false; - M_DrawLoadGameData(); - } - else - { - // Okay, fine, now you can - hidetitlemap = true; - } + // Don't render the title map. + hidetitlemap = true; charseltimer++; } else if (charseltimer > 0) @@ -8128,13 +8082,7 @@ static void M_DrawSetupChoosePlayerMenu(void) // CHARBG // 101 - if (fade > 0) - { - if (fade > 9) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, colormap[101]); - else - V_DrawFadeScreen(colormap[101], fade); - } + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, colormap[101]); // 106 if (thismenu) { @@ -8166,7 +8114,7 @@ static void M_DrawSetupChoosePlayerMenu(void) // Character select pictures { - INT32 x = 8 - xsh; + INT32 x = 8; INT32 y = (my+16) - FixedInt(char_scroll); V_DrawScaledPatch(x, y, 0, description[char_on].charpic); if (prev != -1) @@ -8182,7 +8130,7 @@ static void M_DrawSetupChoosePlayerMenu(void) char *text = char_notes; char *first_token = text; char *last_token = strchr(text, '\n'); - INT32 x = 146 + xsh; + INT32 x = 146; INT32 y = my + 9; INT32 flags = V_ALLOWLOWERCASE; @@ -8256,33 +8204,33 @@ static void M_DrawSetupChoosePlayerMenu(void) if (next != -1) nextpatch = description[next].namepic; txsh = oxsh; - ox = (8-xsh) + SHORT((description[char_on].charpic)->width)/2; + ox = 8 + SHORT((description[char_on].charpic)->width)/2; if (curpatch) ox -= (SHORT(curpatch->width)/2); y = my + 144; - if (char_scroll && (!xsh)) + if (char_scroll) { // prev if (prevpatch && char_scroll < 0) { // Why does this work? x = (ox - txsh) - BASEVIDWIDTH; - V_DrawScaledPatch(x-xsh, y, 0, prevpatch); + V_DrawScaledPatch(x, y, 0, prevpatch); } // next else if (nextpatch && char_scroll > 0) { x = (ox - txsh) + BASEVIDWIDTH; if (x < BASEVIDWIDTH) - V_DrawScaledPatch(x-xsh, y, 0, nextpatch); + V_DrawScaledPatch(x, y, 0, nextpatch); } } // cur x = ox - txsh; if (curpatch) - V_DrawScaledPatch(x-xsh, y, 0, curpatch); + V_DrawScaledPatch(x, y, 0, curpatch); } // Menu header @@ -8291,7 +8239,7 @@ static void M_DrawSetupChoosePlayerMenu(void) patch_t *header = W_CachePatchName("M_PICKP", PU_CACHE); INT32 xtitle = 146; INT32 ytitle = (35 - SHORT(header->height))/2; - V_DrawFixedPatch((xtitle+xsh)< Date: Tue, 20 Aug 2019 00:41:06 -0300 Subject: [PATCH 020/130] Unlock all cached patches, fix accidental merge conflict. --- src/m_menu.c | 54 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 51c13d5b3..1714e53a8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5094,9 +5094,10 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) } // new menus -static void M_DrawRecordAttackBackground(void) +static void M_DrawRecordAttackForeground(void) { patch_t *fg = W_CachePatchName("RECATKFG", PU_CACHE); + patch_t *clock = W_CachePatchName("RECCLOCK", PU_CACHE); angle_t fa; INT32 i; @@ -5109,9 +5110,14 @@ static void M_DrawRecordAttackBackground(void) } fa = (FixedAngle(((recatkdrawtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; - V_DrawSciencePatch(160<= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) + { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + // Draw and animate foreground + if (!strncmp("RECATKBG", curbgname, 8)) + M_DrawRecordAttackForeground(); + } + if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); - - // Draw and animate foreground -<<<<<<< HEAD - if ((!curbghide || !titlemapinaction) && !stricmp("RECATKBG", curbgname)) -======= - if (!curbghide && stricmp("RECATTBG", curbgname) < 0) ->>>>>>> 15b363773fbaeeb8e7c7ca032c48eb5072ea34d2 - M_DrawRecordAttackBackground(); } if (currentMenu->prevMenu == &SP_NightsAttackDef) @@ -5548,7 +5563,14 @@ static void M_DrawMessageMenu(void) if (levellistmode == LLM_NIGHTSATTACK) M_DrawNightsAttackMountains(); else + { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + // Draw and animate foreground here, if desired. + // Check if (curbgname == "RECATKBG"), and if true, + // call the M_DrawRecordAttackForeground function. + // String check generally done with a strncmp. + // Can also draw the clock here. + } } if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); @@ -8572,17 +8594,15 @@ void M_DrawTimeAttackMenu(void) if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) + { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + // Draw and animate foreground + if (!strncmp("RECATKBG", curbgname, 8)) + M_DrawRecordAttackForeground(); + } if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); - // Draw and animate foreground -<<<<<<< HEAD - if ((!curbghide || !titlemapinaction) && !stricmp("RECATKBG", curbgname)) -======= - if (!curbghide && stricmp("RECATTBG", curbgname) < 0) ->>>>>>> 15b363773fbaeeb8e7c7ca032c48eb5072ea34d2 - M_DrawRecordAttackBackground(); M_DrawMenuTitle(); // draw menu (everything else goes on top of it) From 5ef4b938be90b7f3b6852629816cda3943524a04 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 20 Aug 2019 00:15:35 -0400 Subject: [PATCH 021/130] Draw record attack foreground even if a message is currently on-screen. --- src/m_menu.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1714e53a8..986ae1f03 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5565,11 +5565,8 @@ static void M_DrawMessageMenu(void) else { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); - // Draw and animate foreground here, if desired. - // Check if (curbgname == "RECATKBG"), and if true, - // call the M_DrawRecordAttackForeground function. - // String check generally done with a strncmp. - // Can also draw the clock here. + if (!strncmp("RECATKBG", curbgname, 8)) + M_DrawRecordAttackForeground(); } } if (curfadevalue) From 1a1f4136e8b3b5778bf7499296029f8c72e86cb9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 20 Aug 2019 19:08:45 -0300 Subject: [PATCH 022/130] Fix character select menu to use the new Color_Opposite array. --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 11d17e0a8..5f71c7837 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8083,7 +8083,7 @@ static void M_DrawSetupChoosePlayerMenu(void) col = charskin->prefcolor; #ifdef CHOOSEPLAYER_OPPOSITECOLOUR // Use the OPPOSITE of the character's skincolour - col = Color_Opposite[(col - 1)*2]; + col = Color_Opposite[col - 1][0]; #endif // CHOOSEPLAYER_OPPOSITECOLOUR // Make the translation colourmap From c6c0a9dd1abed7dc998563bbcd69e3b7b41b7aa1 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 20 Aug 2019 16:33:39 -0700 Subject: [PATCH 023/130] Old string drawing functions are dumb --- src/m_menu.c | 64 ++------------------------------------------------- src/v_video.c | 12 +++++----- 2 files changed, 8 insertions(+), 68 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5f71c7837..b41d8bbcb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8147,72 +8147,12 @@ static void M_DrawSetupChoosePlayerMenu(void) } // Character description - // No, I can't use strtok. - // Put two line break characters next to each other to see why. { - char *text = char_notes; - char *first_token = text; - char *last_token = strchr(text, '\n'); INT32 x = 146; INT32 y = my + 9; - INT32 flags = V_ALLOWLOWERCASE; + INT32 flags = V_ALLOWLOWERCASE|V_RETURN8; - // No line breaks? - // Draw entire string - if (!last_token) - V_DrawString(x, y, flags, char_notes); - // Split string by the line break character - else - { - char *string = NULL; - INT32 len; - while (true) - { - // There are still lines left do draw - if (last_token) - { - size_t shift = 0; - // Free this line - if (string) - Z_Free(string); - // Find string length, do a malloc... - len = (last_token-first_token)+1; - string = ZZ_Alloc(len); - // Copy the line - strncpy(string, first_token, len-1); - string[len-1] = '\0'; - // Don't leave a line break character - // at the start of the string! - if ((strlen(string) >= 2) && (string[0] == '\n') && (string[1] != '\n')) - shift++; - // Then draw it - V_DrawString(x, y, flags, string+shift); - } - // No line break character was found - else - { - // Don't leave a line break character - // at the start of the string! - if ((strlen(first_token) >= 2) && (first_token[0] == '\n') && (first_token[1] != '\n')) - first_token++; - V_DrawString(x, y, flags, first_token); - break; - } - - // Next line - y += 8; // V_RETURN8 - if ((last_token-text)+1 >= strlen(text)) - last_token = NULL; - else - { - first_token = last_token; - last_token = strchr(first_token+1, '\n'); - } - } - // Free this line - if (string) - Z_Free(string); - } + V_DrawString(x, y, flags, char_notes); } // Name tags! diff --git a/src/v_video.c b/src/v_video.c index 2ec06a787..996c159bf 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2184,7 +2184,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) w = SHORT(hu_font[c]->width) * dupx; if (cx > scrwidth) - break; + continue; if (cx+left + w < 0) //left boundary check { cx += w; @@ -2298,7 +2298,7 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) w = SHORT(hu_font[c]->width) * dupx / 2; if (cx > scrwidth) - break; + continue; if (cx+left + w < 0) //left boundary check { cx += w; @@ -2403,7 +2403,7 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) w = (SHORT(tny_font[c]->width) * dupx); if (cx > scrwidth) - break; + continue; if (cx+left + w < 0) //left boundary check { cx += w; @@ -2501,7 +2501,7 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) w = SHORT(hu_font[c]->width) * dupx; if ((cx>>FRACBITS) > scrwidth) - break; + continue; if ((cx>>FRACBITS)+left + w < 0) //left boundary check { cx += w<width) * dupx; if ((cx>>FRACBITS) > scrwidth) - break; + continue; V_DrawSciencePatch(cx, cy, option, cred_font[c], FRACUNIT); cx += w<width) * dupx; if (cx > scrwidth) - break; + continue; if (cx+left + w < 0) //left boundary check { cx += w; From f90a6540d64265df533a7c34c690729262614c4c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 20 Aug 2019 21:45:55 -0300 Subject: [PATCH 024/130] NiGHTS Attack menu: Let patch offsets control the alignment of the top border. --- src/m_menu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index b41d8bbcb..f498d894c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5261,7 +5261,9 @@ static void M_DrawNightsAttackBackground(void) if (border_height > 0) { // top border - y = border_height - ((topborderheight-5) * vid.dupy); + INT16 yoffset = SHORT(topborder->topoffset); + y = border_height - ((topborderheight - yoffset) * vid.dupy); + y += (yoffset * dupy); for (i = 0; i < (vid.height/border_height) + 1; i++) { for (j = 0; j < (vid.width/topborderwidth); j++) From 015216b9acb45952763939a4a224585d320c951d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 26 Aug 2019 20:49:04 -0300 Subject: [PATCH 025/130] Don't draw borders or patches if not necessary. --- src/m_menu.c | 88 ++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f498d894c..4926fa7a2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5094,6 +5094,9 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) } // new menus +#define TILEX(w) max(FixedCeil(FixedDiv(vid.width, w * dupx)) >> FRACBITS, 1)+2 +#define TILEY(h) max(FixedCeil(FixedDiv(vid.height, h * dupy)) >> FRACBITS, 1)+2 + static void M_DrawRecordAttackForeground(void) { patch_t *fg = W_CachePatchName("RECATKFG", PU_CACHE); @@ -5102,28 +5105,38 @@ static void M_DrawRecordAttackForeground(void) INT32 i; INT32 height = (SHORT(fg->height)/2); + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); + for (i = -12; i < (BASEVIDHEIGHT/height) + 12; i++) { INT32 y = ((i*height) - (height - ((recatkdrawtimer*2)%height))); + // don't draw above the screen + { + INT32 sy = FixedMul(y, dupz<> FRACBITS; + if (vid.height != BASEVIDHEIGHT * dupz) + sy += (vid.height - (BASEVIDHEIGHT * dupz)) / 2; + if ((sy+height) < 0) + continue; + } V_DrawFixedPatch(0, y< vid.height) + break; } + // draw clock fa = (FixedAngle(((recatkdrawtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawSciencePatch(160< 0) + V_DrawFill(0, border_height + scaled_height, vid.width, border_height, V_NOSCALESTART|31); + } + // Cache and draw patch. background = W_CachePatchName(curbgname, PU_CACHE); bgwidth = SHORT(background->width); @@ -5152,23 +5177,6 @@ static void M_DrawNightsAttackMountains(void) // scroll background to left bgscrollx -= (FRACUNIT/2); - - // draw borders - { - INT32 scaled_height = BASEVIDHEIGHT * vid.dupy; - INT32 border_height = (vid.height - scaled_height) / 2; - - if (border_height > 0) - { - // top border - V_DrawFill(0, 0, vid.width, border_height, V_NOSCALESTART|158); - // bottom border - V_DrawFill(0, border_height + scaled_height, vid.width, border_height, V_NOSCALESTART|31); - } - } - - // Unlock cached patch. - W_UnlockCachedPatch(background); } // NiGHTS Attack foreground. @@ -5207,14 +5215,14 @@ static void M_DrawNightsAttackBackground(void) dupx = dupy = (dupx < dupy ? dupx : dupy); // background - M_DrawNightsAttackMountains(); + M_DrawNightsAttackMountains(false); // Center patches vertically snapy = (vid.height - (BASEVIDHEIGHT * dupy)) / 2; y = snapy; // back top foreground patch - for (i = 0; i < (vid.width/backtopwidth) + 1; i++) + for (i = 0; i < TILEX(backtopwidth); i++) { x = ((i*backtopwidth) - (ntsatkdrawtimer%backtopwidth)); x *= dupx; @@ -5222,7 +5230,7 @@ static void M_DrawNightsAttackBackground(void) } // front top foreground patch - for (i = 0; i < (vid.width/fronttopwidth) + 1; i++) + for (i = 0; i < TILEX(fronttopwidth) + 1; i++) { x = ((i*fronttopwidth) - ((ntsatkdrawtimer*2)%backtopwidth)); x *= dupx; @@ -5234,7 +5242,7 @@ static void M_DrawNightsAttackBackground(void) y += FixedInt(FixedMul((BASEVIDHEIGHT - backbottomheight)*FRACUNIT, dupy<topoffset); - y = border_height - ((topborderheight - yoffset) * vid.dupy); + y = border_height - ((topborderheight - yoffset) * dupy); y += (yoffset * dupy); - for (i = 0; i < (vid.height/border_height) + 1; i++) + for (i = 0; i < TILEY(border_height) + 1; i++) { - for (j = 0; j < (vid.width/topborderwidth); j++) + for (j = 0; j < TILEX(topborderwidth); j++) { x = ((j*frontbottomwidth) - ((ntsatkdrawtimer*2)%frontbottomwidth)); x *= dupx; @@ -5281,15 +5290,6 @@ static void M_DrawNightsAttackBackground(void) // Increment timer. ntsatkdrawtimer++; - - // Unlock cached patches. - W_UnlockCachedPatch(backtopfg); - W_UnlockCachedPatch(fronttopfg); - - W_UnlockCachedPatch(backbottomfg); - W_UnlockCachedPatch(frontbottomfg); - - W_UnlockCachedPatch(topborder); } // NiGHTS Attack floating Super Sonic. @@ -5313,11 +5313,11 @@ static void M_DrawNightsAttackSuperSonic(void) // Cache and draw patch. supersonic_patch = W_CachePatchName(va(supersonic, timer+1), PU_CACHE); V_DrawFixedPatch(235<= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) - M_DrawNightsAttackMountains(); + M_DrawNightsAttackMountains(true); if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); } @@ -5563,7 +5563,7 @@ static void M_DrawMessageMenu(void) else if (!curbghide || !titlemapinaction) { if (levellistmode == LLM_NIGHTSATTACK) - M_DrawNightsAttackMountains(); + M_DrawNightsAttackMountains(true); else { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); From 56abc63c29ca6334c57f32663216244490b06069 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 6 Sep 2019 15:25:11 -0300 Subject: [PATCH 026/130] Ignore key held events. --- src/m_menu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 4926fa7a2..d6c22bb6f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -167,6 +167,8 @@ static tic_t charseltimer = 0; static fixed_t char_scroll = 0; #define charscrollamt 128*FRACUNIT +static tic_t keydown = 0; + // // PROTOTYPES // @@ -2864,6 +2866,7 @@ boolean M_Responder(event_t *ev) { if (ev->type == ev_keydown) { + keydown++; ch = ev->data1; // added 5-2-98 remap virtual keys (mouse & joystick buttons) @@ -2970,6 +2973,8 @@ boolean M_Responder(event_t *ev) pmousex = lastx += 30; } } + else if (ev->type == ev_keyup) // Preserve event for other responders + keydown = 0; } else if (ev->type == ev_keydown) // Preserve event for other responders ch = ev->data1; @@ -7959,8 +7964,7 @@ static void M_HandleChoosePlayerMenu(INT32 choice) boolean exitmenu = false; // exit to previous menu INT32 selectval; - // How do I detect key hold events? - if (char_scroll) + if (keydown > 1) return; switch (choice) From f3cf3ca4530397a69bab10ac311e31cc09fc14e7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 6 Sep 2019 16:05:46 -0300 Subject: [PATCH 027/130] Cleanup. --- src/m_menu.c | 69 +++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 49 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index d6c22bb6f..583aaa529 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8026,11 +8026,8 @@ static void M_HandleChoosePlayerMenu(INT32 choice) } // Draw the choose player setup menu, had some fun with player anim -#define CHOOSEPLAYER_USECHARCOLOUR -#define CHOOSEPLAYER_OPPOSITECOLOUR //#define CHOOSEPLAYER_DRAWHEADER -#ifdef CHOOSEPLAYER_USECHARCOLOUR static INT32 getskinfromdescription(INT32 desc) { char *and = strchr(description[desc].skinname, '&'); @@ -8042,18 +8039,13 @@ static INT32 getskinfromdescription(INT32 desc) } return R_SkinAvailable(description[desc].skinname); } -#endif // CHOOSEPLAYER_USECHARCOLOUR static void M_DrawSetupChoosePlayerMenu(void) { - boolean thismenu = (currentMenu == &SP_PlayerDef); - const INT32 my = 16; -#ifdef CHOOSEPLAYER_USECHARCOLOUR skin_t *charskin = &skins[0]; INT32 skinnum = 0; -#endif // CHOOSEPLAYER_USECHARCOLOUR UINT8 col; UINT8 *colormap = NULL; INT32 prev = -1, next = -1; @@ -8079,41 +8071,23 @@ static void M_DrawSetupChoosePlayerMenu(void) // No there isn't. prev = -1; -#ifdef CHOOSEPLAYER_USECHARCOLOUR // Find skin number from description[] skinnum = getskinfromdescription(char_on); if (skinnum != -1) charskin = &skins[skinnum]; - // Use the character's skincolour - col = charskin->prefcolor; -#ifdef CHOOSEPLAYER_OPPOSITECOLOUR - // Use the OPPOSITE of the character's skincolour - col = Color_Opposite[col - 1][0]; -#endif // CHOOSEPLAYER_OPPOSITECOLOUR + // Use the opposite of the character's skincolor + col = Color_Opposite[charskin->prefcolor - 1][0]; - // Make the translation colourmap + // Make the translation colormap colormap = R_GetTranslationColormap(skinnum, col, 0); -#else - // Dark blue translation colourmap - colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_COBALT, 0); -#endif // CHOOSEPLAYER_USECHARCOLOUR - // Yes. - if (thismenu) - { - // Don't render the title map. - hidetitlemap = true; - charseltimer++; - } - else if (charseltimer > 0) - charseltimer--; + // Don't render the title map + hidetitlemap = true; + charseltimer++; - // CHARBG - // 101 + // Background and borders V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, colormap[101]); - // 106 - if (thismenu) { INT32 sw = (BASEVIDWIDTH * vid.dupx); INT32 bw = (vid.width - sw) / 2; @@ -8125,23 +8099,21 @@ static void M_DrawSetupChoosePlayerMenu(void) } } - if (thismenu) + // Foreground + for (i = -12; i < (BASEVIDHEIGHT/bgheight) + 12; i++) { - for (i = -12; i < (BASEVIDHEIGHT/bgheight) + 12; i++) - { - INT32 oy = (i*bgheight), y; - y = oy - (bgheight - (charseltimer%bgheight)); - V_DrawFixedPatch(0, y< Date: Sat, 7 Sep 2019 23:40:00 -0300 Subject: [PATCH 028/130] Make nametags compatible with current player.dta --- src/info.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/info.h b/src/info.h index 3ac4cdd4b..034c91f73 100644 --- a/src/info.h +++ b/src/info.h @@ -843,10 +843,10 @@ typedef enum playersprite } playersprite_t; // SPR2_XTRA -#define XTRA_LIFEPIC 0 // Life icon patch -#define XTRA_CHARSEL 1 // Character select picture -#define XTRA_NAMETAG 2 // Character select nametag -#define XTRA_ENDING 3 // Ending finale patches +#define XTRA_LIFEPIC 0 // Life icon patch +#define XTRA_CHARSEL 1 // Character select picture +#define XTRA_ENDING 2 // Ending finale patches +#define XTRA_NAMETAG (XTRA_ENDING+3) // Character select nametag typedef enum state { From 807614d02ddf45efa08cc725e1b260524f1c5d64 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 7 Sep 2019 22:57:20 -0400 Subject: [PATCH 029/130] Add _ to the record and nights attack tracks for organization --- src/m_menu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 583aaa529..964e3d0bc 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2252,9 +2252,9 @@ void M_InitMenuPresTables(void) menupres[i].muslooping = true; } if (i == MN_SP_TIMEATTACK) - strncpy(menupres[i].musname, "recatk", 7); + strncpy(menupres[i].musname, "_recat", 7); else if (i == MN_SP_NIGHTSATTACK) - strncpy(menupres[i].musname, "nitatk", 7); + strncpy(menupres[i].musname, "_nitat", 7); else if (i == MN_SP_PLAYER) strncpy(menupres[i].musname, "_chsel", 7); } @@ -8503,7 +8503,7 @@ void M_DrawTimeAttackMenu(void) curbgxspeed = 0; curbgyspeed = 18; - M_ChangeMenuMusic("recatk", true); // Eww, but needed for when user hits escape during demo playback + M_ChangeMenuMusic("_recat", true); // Eww, but needed for when user hits escape during demo playback if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); @@ -8714,7 +8714,7 @@ void M_DrawNightsAttackMenu(void) M_SetMenuCurBackground("NTSATKBG"); - M_ChangeMenuMusic("nitatk", true); // Eww, but needed for when user hits escape during demo playback + M_ChangeMenuMusic("_nitat", true); // Eww, but needed for when user hits escape during demo playback M_DrawNightsAttackBackground(); if (curfadevalue) From 9b0e2b89911fa8314b95fbb96347d9b3ad7f41c7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Sep 2019 22:18:03 -0300 Subject: [PATCH 030/130] Make nametags compatible with current player.dta (again) --- src/info.h | 5 +++-- src/m_menu.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/info.h b/src/info.h index 188859bb8..f731784af 100644 --- a/src/info.h +++ b/src/info.h @@ -844,8 +844,9 @@ typedef enum playersprite // SPR2_XTRA #define XTRA_LIFEPIC 0 // Life icon patch #define XTRA_CHARSEL 1 // Character select picture -#define XTRA_ENDING 2 // Ending finale patches -#define XTRA_NAMETAG (XTRA_ENDING+3) // Character select nametag +#define XTRA_NAMETAG 2 // Character select nametag +#define XTRA_CONTINUE 3 // Continue icon +#define XTRA_ENDING 4 // Ending finale patches typedef enum state { diff --git a/src/m_menu.c b/src/m_menu.c index cac050021..0bcccbfac 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8574,10 +8574,10 @@ void M_DrawTimeAttackMenu(void) // Character face! { - if (skins[cv_chooseskin.value-1].sprites[SPR2_XTRA].numframes >= 2) + if (skins[cv_chooseskin.value-1].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1) { spritedef_t *sprdef = &skins[cv_chooseskin.value-1].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[1]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; PictureOfUrFace = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); } else From 75ee3193f42524b80a8ebd26dee4d801a8106053 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 25 Sep 2019 20:27:41 +0100 Subject: [PATCH 031/130] Write a new hack for getting sector->linecount from sector->lines in Lua, to put my mind at rest about it at last. 1) In sector_get, actually push the memory address of the lines array within sector_t, rather than push the value of "lines" itself (essentially, we we want a pointer to a double pointer, or rather a TRIPLE pointer haha) 2) In the sectorlines_* functions, use offsetof to shift the memory address so we can obtain the value of linecount within the sector_t struct, and dereference the result to obtain the value of linecount itself 3) ??? profit Untested and uncompiled atm, but I have some confidence this might work --- src/lua_maplib.c | 55 ++++++++++++++++++++++++++++++------------------ src/lua_script.c | 2 +- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index dbb69b7e2..1da232efa 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -411,37 +411,53 @@ static int sector_iterate(lua_State *L) // sector.lines, i -> sector.lines[i] // sector.lines.valid, for validity checking +// +// 25/9/19 Monster Iestyn +// Modified this and _num to use triple pointers, to allow for a new hack of mine involving offsetof +// this way we don't need to check frontsector or backsector of line #0 in the array +// static int sectorlines_get(lua_State *L) { - line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES)); + line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES)); size_t i; size_t numoflines = 0; lua_settop(L, 2); if (!lua_isnumber(L, 2)) { int field = luaL_checkoption(L, 2, NULL, valid_opt); - if (!seclines) + if (!seclines || !(*seclines)) { if (field == 0) { lua_pushboolean(L, 0); return 1; } - return luaL_error(L, "accessed sector_t doesn't exist anymore."); + return luaL_error(L, "accessed sector_t.lines doesn't exist anymore."); } else if (field == 0) { lua_pushboolean(L, 1); return 1; } } +/* a snip from sector_t struct in r_defs.h, for reference + size_t linecount; + struct line_s **lines; // [linecount] size +*/ + // get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result + // we need this to determine the array's actual size, and therefore also the maximum value allowed as an index + // this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy + numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); + +/* OLD HACK // check first linedef to figure which of its sectors owns this sector->lines pointer // then check that sector's linecount to get a maximum index - //if (!seclines[0]) + //if (!(*seclines)[0]) //return luaL_error(L, "no lines found!"); // no first linedef????? - if (seclines[0]->frontsector->lines == seclines) - numoflines = seclines[0]->frontsector->linecount; - else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first - numoflines = seclines[0]->backsector->linecount; + if ((*seclines)[0]->frontsector->lines == *seclines) + numoflines = (*seclines)[0]->frontsector->linecount; + else if ((*seclines)[0]->backsector && *seclines[0]->backsector->lines == *seclines) // check backsector exists first + numoflines = (*seclines)[0]->backsector->linecount; //if neither sector has it then ??? +*/ if (!numoflines) return luaL_error(L, "no lines found!"); @@ -449,23 +465,21 @@ static int sectorlines_get(lua_State *L) i = (size_t)lua_tointeger(L, 2); if (i >= numoflines) return 0; - LUA_PushUserdata(L, seclines[i], META_LINE); + LUA_PushUserdata(L, (*seclines)[i], META_LINE); return 1; } +// #(sector.lines) -> sector.linecount static int sectorlines_num(lua_State *L) { - line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES)); + line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES)); size_t numoflines = 0; - // check first linedef to figure which of its sectors owns this sector->lines pointer - // then check that sector's linecount to get a maximum index - //if (!seclines[0]) - //return luaL_error(L, "no lines found!"); // no first linedef????? - if (seclines[0]->frontsector->lines == seclines) - numoflines = seclines[0]->frontsector->linecount; - else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first - numoflines = seclines[0]->backsector->linecount; - //if neither sector has it then ??? + + if (!seclines || !(*seclines)) + return luaL_error(L, "accessed sector_t.lines doesn't exist anymore."); + + // see comments in the _get function above + numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); lua_pushinteger(L, numoflines); return 1; } @@ -543,7 +557,7 @@ static int sector_get(lua_State *L) LUA_PushUserdata(L, §ors[sector->camsec], META_SECTOR); return 1; case sector_lines: // lines - LUA_PushUserdata(L, sector->lines, META_SECTORLINES); + LUA_PushUserdata(L, §or->lines, META_SECTORLINES); // push the address of the "lines" member in the struct, to allow our hacks in sectorlines_get/_num to work return 1; case sector_ffloors: // ffloors lua_pushcfunction(L, lib_iterateSectorFFloors); @@ -579,6 +593,7 @@ static int sector_set(lua_State *L) case sector_thinglist: // thinglist case sector_heightsec: // heightsec case sector_camsec: // camsec + case sector_lines: // lines case sector_ffloors: // ffloors #ifdef ESLOPE case sector_fslope: // f_slope diff --git a/src/lua_script.c b/src/lua_script.c index deb644dc0..a161368b8 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -431,7 +431,7 @@ void LUA_InvalidateLevel(void) for (i = 0; i < numsectors; i++) { LUA_InvalidateUserdata(§ors[i]); - LUA_InvalidateUserdata(sectors[i].lines); + LUA_InvalidateUserdata(§ors[i].lines); if (sectors[i].ffloors) { for (rover = sectors[i].ffloors; rover; rover = rover->next) From 240aa34794864b6af6170f2322ba7805f3af99b5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Sep 2019 21:16:11 +0100 Subject: [PATCH 032/130] Added consoleplayer, displayplayer and secondarydisplayplayer, by popular request --- src/dehacked.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 8334de61a..87afa08d0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9932,6 +9932,23 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"mapmusposition")) { lua_pushinteger(L, mapmusposition); return 1; + // local player variables, by popular request + } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) + if (!playeringame[consoleplayer]) + return 0; + LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1) + if (!playeringame[displayplayer]) + return 0; + LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen + if (!splitscreen || !playeringame[secondarydisplayplayer]) + return 0; + LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); + return 1; + // end local player variables } else if (fastcmp(word,"server")) { if ((!multiplayer || !netgame) && !playeringame[serverplayer]) return 0; From fa444a37eb9cd063b0ab735edce96dcae9d288a1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Sep 2019 23:15:38 +0100 Subject: [PATCH 033/130] Added < 0 checks to all three variables added in last commit (no point checking >= MAXPLAYERS tbh, there's no reason the game would even set those values that I can think of offhand) --- src/dehacked.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 87afa08d0..25f1dac65 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9934,17 +9934,17 @@ static inline int lib_getenum(lua_State *L) return 1; // local player variables, by popular request } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) - if (!playeringame[consoleplayer]) + if (consoleplayer < 0 || !playeringame[consoleplayer]) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); return 1; } else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1) - if (!playeringame[displayplayer]) + if (displayplayer < 0 || !playeringame[displayplayer]) return 0; LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); return 1; } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen - if (!splitscreen || !playeringame[secondarydisplayplayer]) + if (!splitscreen || secondarydisplayplayer < 0 || consoleplayer >= MAXPLAYERS || !playeringame[secondarydisplayplayer]) return 0; LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); return 1; From 52562c4125a745efd2851323896630d2df3f5727 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 28 Sep 2019 20:45:44 +0100 Subject: [PATCH 034/130] whoops, didn't mean to include this --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 25f1dac65..aff9e8617 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9944,7 +9944,7 @@ static inline int lib_getenum(lua_State *L) LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); return 1; } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen - if (!splitscreen || secondarydisplayplayer < 0 || consoleplayer >= MAXPLAYERS || !playeringame[secondarydisplayplayer]) + if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer]) return 0; LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); return 1; From 625de1f4f6ce3773082a5cbf6c7bf3c37ea406a9 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 1 Oct 2019 23:40:59 -0400 Subject: [PATCH 035/130] Some changes. Restore the menu headers for record attack and character select menu. Attempt to optimize the NiGHTS mode menu. (Help getting the scrolling to work in an efficient way would be nice). --- src/m_menu.c | 64 ++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 877857e8b..1b6d9b04b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1679,24 +1679,24 @@ menu_t SP_LevelStatsDef = menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), - NULL, SP_TimeAttackLevelSelectMenu); + "M_ATTACK", SP_TimeAttackLevelSelectMenu); static menu_t SP_TimeAttackDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), - NULL, + "M_ATTACK", sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. SP_TimeAttackMenu, M_DrawTimeAttackMenu, - 32, 28, + 32, 40, 0, NULL }; static menu_t SP_ReplayDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), - NULL, + "M_ATTACK", sizeof(SP_ReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, SP_ReplayMenu, @@ -1708,7 +1708,7 @@ static menu_t SP_ReplayDef = static menu_t SP_GuestReplayDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), - NULL, + "M_ATTACK", sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, SP_GuestReplayMenu, @@ -1720,7 +1720,7 @@ static menu_t SP_GuestReplayDef = static menu_t SP_GhostDef = { MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), - NULL, + "M_ATTACK", sizeof(SP_GhostMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, SP_GhostMenu, @@ -1787,7 +1787,7 @@ static menu_t SP_NightsGhostDef = menu_t SP_PlayerDef = { MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), - NULL, + "M_PICKP", sizeof (SP_PlayerMenu)/sizeof (menuitem_t), &SP_MainDef, SP_PlayerMenu, @@ -5314,20 +5314,12 @@ static void M_DrawNightsAttackBackground(void) y = snapy; // back top foreground patch - for (i = 0; i < TILEX(backtopwidth); i++) - { - x = ((i*backtopwidth) - (ntsatkdrawtimer%backtopwidth)); - x *= dupx; - V_DrawFixedPatch(x<score) sprintf(beststr, "(none)"); else sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); - V_DrawString(104-72, 32+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(104+72, 32+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); + V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) sprintf(beststr, "(none)"); @@ -8743,16 +8737,16 @@ void M_DrawTimeAttackMenu(void) G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - V_DrawString(104-72, 40+lsheadingheight/2, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(104+72, 40+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:"); + V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) sprintf(beststr, "(none)"); else sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); - V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); + V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); // Draw record emblems. em = M_GetLevelEmblems(cv_nextmap.value); @@ -8760,9 +8754,9 @@ void M_DrawTimeAttackMenu(void) { switch (em->type) { - case ET_SCORE: yHeight = 32; break; - case ET_TIME: yHeight = 40; break; - case ET_RINGS: yHeight = 48; break; + case ET_SCORE: yHeight = 48; break; + case ET_TIME: yHeight = 58; break; + case ET_RINGS: yHeight = 68; break; default: goto skipThisOne; } @@ -8795,7 +8789,7 @@ void M_DrawTimeAttackMenu(void) // Draw press ESC to exit string on main record attack menu if (currentMenu == &SP_TimeAttackDef) - V_DrawString(104-72, 170, V_TRANSLUCENT, M_GetText("Press ESC to exit")); + V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); } static void M_TimeAttackLevelSelect(INT32 choice) From 6a8539c8f10044795f69a3f6a0bd38d31e00d137 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 2 Oct 2019 20:00:43 -0300 Subject: [PATCH 036/130] test --- src/m_menu.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1b6d9b04b..8aa907027 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5289,9 +5289,9 @@ static void M_DrawNightsAttackBackground(void) INT32 fronttopwidth = SHORT(fronttopfg->width); // bottom - patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_CACHE); + //patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_CACHE); patch_t *frontbottomfg = W_CachePatchName("NTSATKB2", PU_CACHE); - INT32 backbottomwidth = SHORT(backbottomfg->width); + //INT32 backbottomwidth = SHORT(backbottomfg->width); INT32 frontbottomwidth = SHORT(frontbottomfg->width); // top border @@ -5300,8 +5300,8 @@ static void M_DrawNightsAttackBackground(void) INT32 topborderheight = SHORT(topborder->height); // Snap patches to bottom - INT32 backbottomheight = SHORT(backbottomfg->height); - INT32 frontbottomheight = SHORT(frontbottomfg->height); + //INT32 backbottomheight = SHORT(backbottomfg->height); + //INT32 frontbottomheight = SHORT(frontbottomfg->height); // only use one dup, to avoid stretching (har har) dupx = dupy = (dupx < dupy ? dupx : dupy); @@ -5314,15 +5314,29 @@ static void M_DrawNightsAttackBackground(void) y = snapy; // back top foreground patch - x -= (ntsatkdrawtimer%backtopwidth); + x = -(ntsatkdrawtimer%backtopwidth); + x *= dupx; V_DrawFixedPatch(x< Date: Wed, 2 Oct 2019 21:28:02 -0300 Subject: [PATCH 037/130] test --- src/m_menu.c | 203 +++++++++++++++------------------------------------ 1 file changed, 59 insertions(+), 144 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8aa907027..8f43327da 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5186,9 +5186,6 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) } // new menus -#define TILEX(w) max(FixedCeil(FixedDiv(vid.width, w * dupx)) >> FRACBITS, 1)+2 -#define TILEY(h) max(FixedCeil(FixedDiv(vid.height, h * dupy)) >> FRACBITS, 1)+2 - static void M_DrawRecordAttackForeground(void) { patch_t *fg = W_CachePatchName("RECATKFG", PU_CACHE); @@ -5226,164 +5223,89 @@ static void M_DrawRecordAttackForeground(void) } // NiGHTS Attack background. -// The patch name is "NTSATKBG". - -static void M_DrawNightsAttackMountains(boolean border) +static void M_DrawNightsAttackMountains(void) { - INT32 x, y = 0; - INT32 dupx = vid.dupx; - INT32 dupy = vid.dupy; - INT32 i; - - patch_t *background; - INT32 bgwidth; - - // scroll amount static INT32 bgscrollx; - - // only use one dup, to avoid stretching (har har) - dupx = dupy = (dupx < dupy ? dupx : dupy); - - // draw borders - if (border) - { - INT32 scaled_height = BASEVIDHEIGHT * vid.dupy; - INT32 border_height = (vid.height - scaled_height) / 2; - // top border - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 158); - // bottom border - if (border_height > 0) - V_DrawFill(0, border_height + scaled_height, vid.width, border_height, V_NOSCALESTART|31); - } - - // Cache and draw patch. - background = W_CachePatchName(curbgname, PU_CACHE); - bgwidth = SHORT(background->width); - - y = (vid.height - (BASEVIDHEIGHT * dupy)) / 2; - for (i = 0; i < (vid.width/bgwidth) + 1; i++) - { - x = ((i*(bgwidth*dupx)) + ((FixedInt(bgscrollx)%bgwidth)*dupx)); - V_DrawFixedPatch(x<width); + INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2; + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background); + x += SHORT(background->width); + if (x < BASEVIDWIDTH) + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background); + V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31); bgscrollx -= (FRACUNIT/2); } // NiGHTS Attack foreground. -// (Yeah, I know.) -// Calls M_DrawNightsAttackMountains for the background. - static void M_DrawNightsAttackBackground(void) { - INT32 x, y, snapy = 0; - INT32 dupx = vid.dupx; - INT32 dupy = vid.dupy; - INT32 i, j; + INT32 x, y = 0; + INT32 i; // top patch_t *backtopfg = W_CachePatchName("NTSATKT1", PU_CACHE); patch_t *fronttopfg = W_CachePatchName("NTSATKT2", PU_CACHE); INT32 backtopwidth = SHORT(backtopfg->width); + //INT32 backtopheight = SHORT(backtopfg->height); INT32 fronttopwidth = SHORT(fronttopfg->width); + //INT32 fronttopheight = SHORT(fronttopfg->height); // bottom - //patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_CACHE); + patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_CACHE); patch_t *frontbottomfg = W_CachePatchName("NTSATKB2", PU_CACHE); - //INT32 backbottomwidth = SHORT(backbottomfg->width); + INT32 backbottomwidth = SHORT(backbottomfg->width); + INT32 backbottomheight = SHORT(backbottomfg->height); INT32 frontbottomwidth = SHORT(frontbottomfg->width); - - // top border - patch_t *topborder = W_CachePatchName("NTSATKBD", PU_CACHE); - INT32 topborderwidth = SHORT(topborder->width); - INT32 topborderheight = SHORT(topborder->height); - - // Snap patches to bottom - //INT32 backbottomheight = SHORT(backbottomfg->height); - //INT32 frontbottomheight = SHORT(frontbottomfg->height); - - // only use one dup, to avoid stretching (har har) - dupx = dupy = (dupx < dupy ? dupx : dupy); + INT32 frontbottomheight = SHORT(frontbottomfg->height); // background - M_DrawNightsAttackMountains(false); - - // Center patches vertically - snapy = (vid.height - (BASEVIDHEIGHT * dupy)) / 2; - y = snapy; + M_DrawNightsAttackMountains(); // back top foreground patch x = -(ntsatkdrawtimer%backtopwidth); - x *= dupx; - V_DrawFixedPatch(x<= vid.width) + break; + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, backtopfg); } // front top foreground patch x = -((ntsatkdrawtimer*2)%fronttopwidth); - x *= dupx; - V_DrawFixedPatch(x<= vid.width) + break; + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, fronttopfg); } - // Snap patches to bottom - /*y = snapy; - y += FixedInt(FixedMul((BASEVIDHEIGHT - backbottomheight)*FRACUNIT, dupy<= vid.width) + break; + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, backbottomfg); } - // Snap patches to bottom - y = snapy; - y += FixedInt(FixedMul((BASEVIDHEIGHT - frontbottomheight)*FRACUNIT, dupy< 0) - { - // top border - INT16 yoffset = SHORT(topborder->topoffset); - y = border_height - ((topborderheight - yoffset) * dupy); - y += (yoffset * dupy); - for (i = 0; i < TILEY(border_height) + 1; i++) - { - for (j = 0; j < TILEX(topborderwidth); j++) - { - x = ((j*frontbottomwidth) - ((ntsatkdrawtimer*2)%frontbottomwidth)); - x *= dupx; - V_DrawFixedPatch(x<= vid.width) + break; + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, frontbottomfg); } // Increment timer. @@ -5391,31 +5313,15 @@ static void M_DrawNightsAttackBackground(void) } // NiGHTS Attack floating Super Sonic. -// Two frames of animation. - +static patch_t *ntssupersonic[2]; static void M_DrawNightsAttackSuperSonic(void) { - const char *supersonic = "NTSSONC%d"; - patch_t *supersonic_patch; - UINT8 *colormap = NULL; - UINT8 super_colour; + const UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_YELLOW, GTC_CACHE); INT32 timer = (ntsatkdrawtimer/4) % 2; - angle_t fa; - - super_colour = SKINCOLOR_SUPERGOLD1; - super_colour += abs( ( (signed)( (unsigned)ntsatkdrawtimer >> 1 ) % 9) - 4); - colormap = R_GetTranslationColormap(TC_DEFAULT, super_colour, GTC_CACHE); - - fa = (FixedAngle(((ntsatkdrawtimer * 4) % 360)<>ANGLETOFINESHIFT) & FINEMASK; - - // Cache and draw patch. - supersonic_patch = W_CachePatchName(va(supersonic, timer+1), PU_CACHE); - V_DrawFixedPatch(235<>ANGLETOFINESHIFT) & FINEMASK; + V_DrawFixedPatch(235<= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) - M_DrawNightsAttackMountains(true); + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 158); + M_DrawNightsAttackMountains(); + } if (curfadevalue) V_DrawFadeScreen(0xFF00, curfadevalue); } @@ -5661,7 +5570,10 @@ static void M_DrawMessageMenu(void) else if (!curbghide || !titlemapinaction) { if (levellistmode == LLM_NIGHTSATTACK) - M_DrawNightsAttackMountains(true); + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 158); + M_DrawNightsAttackMountains(); + } else { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); @@ -9011,6 +8923,9 @@ static void M_NightsAttack(INT32 choice) // This is really just to make sure Sonic is the played character, just in case M_PatchSkinNameTable(); + ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_CACHE); + ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_CACHE); + G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please M_SetupNextMenu(&SP_NightsAttackDef); From a7dcf534cad832731716e4b9279049368db08b7a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 2 Oct 2019 21:57:04 -0300 Subject: [PATCH 038/130] character select --- src/m_menu.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8f43327da..5d7803cc5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8098,7 +8098,9 @@ static void M_DrawSetupChoosePlayerMenu(void) patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); INT16 bgheight = SHORT(charbg->height); INT16 fgheight = SHORT(charfg->height); - INT32 i; + INT16 bgwidth = SHORT(charbg->width); + INT16 fgwidth = SHORT(charfg->width); + INT32 y; if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); @@ -8131,31 +8133,22 @@ static void M_DrawSetupChoosePlayerMenu(void) charseltimer++; // Background and borders - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, colormap[101]); + V_DrawFill(0, 0, bgwidth, vid.height, V_SNAPTOTOP|colormap[101]); { INT32 sw = (BASEVIDWIDTH * vid.dupx); INT32 bw = (vid.width - sw) / 2; col = colormap[106]; if (bw) - { V_DrawFill(0, 0, bw, vid.height, V_NOSCALESTART|col); - V_DrawFill(bw+sw, 0, bw, vid.height, V_NOSCALESTART|col); - } } - // Foreground - for (i = -12; i < (BASEVIDHEIGHT/bgheight) + 12; i++) - { - INT32 oy = (i*bgheight), y; - y = oy - (bgheight - (charseltimer%bgheight)); - V_DrawFixedPatch(0, y< Date: Wed, 2 Oct 2019 22:02:13 -0300 Subject: [PATCH 039/130] nights attack --- src/m_menu.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5d7803cc5..ed6cd5bd9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5226,14 +5226,20 @@ static void M_DrawRecordAttackForeground(void) static void M_DrawNightsAttackMountains(void) { static INT32 bgscrollx; + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); patch_t *background = W_CachePatchName(curbgname, PU_CACHE); INT32 x = FixedInt(bgscrollx) % SHORT(background->width); INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2; + + if (vid.height != BASEVIDHEIGHT * dupz) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 158); + V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31); + V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background); x += SHORT(background->width); if (x < BASEVIDWIDTH) V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background); - V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31); + bgscrollx -= (FRACUNIT/2); } @@ -5264,48 +5270,48 @@ static void M_DrawNightsAttackBackground(void) // back top foreground patch x = -(ntsatkdrawtimer%backtopwidth); - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, backtopfg); + V_DrawScaledPatch(x, y, V_SNAPTOTOP|V_SNAPTOLEFT, backtopfg); for (i = 0; i < 3; i++) { x += (backtopwidth); if (x >= vid.width) break; - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, backtopfg); + V_DrawScaledPatch(x, y, V_SNAPTOTOP|V_SNAPTOLEFT, backtopfg); } // front top foreground patch x = -((ntsatkdrawtimer*2)%fronttopwidth); - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, fronttopfg); + V_DrawScaledPatch(x, y, V_SNAPTOTOP|V_SNAPTOLEFT, fronttopfg); for (i = 0; i < 3; i++) { x += (fronttopwidth); if (x >= vid.width) break; - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, fronttopfg); + V_DrawScaledPatch(x, y, V_SNAPTOTOP|V_SNAPTOLEFT, fronttopfg); } // back bottom foreground patch x = -(ntsatkdrawtimer%backbottomwidth); y = BASEVIDHEIGHT - backbottomheight; - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, backbottomfg); + V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM|V_SNAPTOLEFT, backbottomfg); for (i = 0; i < 3; i++) { x += (backbottomwidth); if (x >= vid.width) break; - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, backbottomfg); + V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM|V_SNAPTOLEFT, backbottomfg); } // front bottom foreground patch x = -((ntsatkdrawtimer*2)%frontbottomwidth); y = BASEVIDHEIGHT - frontbottomheight; - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, frontbottomfg); + V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM|V_SNAPTOLEFT, frontbottomfg); for (i = 0; i < 3; i++) { x += (frontbottomwidth); if (x >= vid.width) break; - V_DrawScaledPatch(x, y, V_SNAPTOLEFT, frontbottomfg); + V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM|V_SNAPTOLEFT, frontbottomfg); } // Increment timer. From 18bf8aa6e4bd0c796799f1e5cc2f103c96684267 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 9 Oct 2019 00:28:01 -0400 Subject: [PATCH 040/130] WIP: New character select name font --- src/hu_stuff.c | 16 ++++++++++++++ src/hu_stuff.h | 6 ++++++ src/m_menu.c | 13 ++++++++---- src/v_video.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/v_video.h | 4 ++++ 5 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3bc643c3c..5a4f35a7a 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -71,6 +71,9 @@ patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; patch_t *ttlnum[20]; // act numbers (0-19) +// Character name font +patch_t *chrn_font[CHRN_FONTSIZE]; + static player_t *plr; boolean chat_on; // entering a chat message? static char w_chat[HU_MAXMSGLEN]; @@ -246,6 +249,19 @@ void HU_LoadGraphics(void) ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } + // cache the character name font for entire game execution + j = CHRN_FONTSTART; + for (i = 0; i < CHRN_FONTSIZE; i++) + { + sprintf(buffer, "CHFNT%.3d", j); + j++; + + if (W_CheckNumForName(buffer) == LUMPERROR) + chrn_font[i] = NULL; + else + chrn_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + } + // cache the crosshairs, don't bother to know which one is being used, // just cache all 3, they're so small anyway. for (i = 0; i < HU_CROSSHAIRS; i++) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index ab77e67b6..ed56bad05 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -35,6 +35,11 @@ #define CRED_FONTEND 'Z' // the last font character #define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1) +// Character name font +#define CHRN_FONTSTART '!' // the first font character +#define CHRN_FONTEND 'Z' // the last font character +#define CHRN_FONTSIZE (CHRN_FONTEND - CHRN_FONTSTART + 1) + #define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init(); extern char *shiftxform; // english translation shift table @@ -77,6 +82,7 @@ extern patch_t *tallnum[10]; extern patch_t *nightsnum[10]; extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; +extern patch_t *chrn_font[CHRN_FONTSIZE]; extern patch_t *ttlnum[20]; extern patch_t *emeraldpics[3][8]; extern patch_t *rflagico; diff --git a/src/m_menu.c b/src/m_menu.c index ed6cd5bd9..2113882ea 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2399,7 +2399,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, } else if (menupres[menutype].bgname[0]) { - strncpy(curbgname, menupres[menutype].bgname, 9); + strncpy(curbgname, menupres[menutype].bgname, 8); curbgxspeed = menupres[menutype].titlescrollxspeed != INT32_MAX ? menupres[menutype].titlescrollxspeed : titlescrollxspeed; curbgyspeed = menupres[menutype].titlescrollyspeed != INT32_MAX ? menupres[menutype].titlescrollyspeed : titlescrollyspeed; return true; @@ -2517,7 +2517,7 @@ void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping) void M_SetMenuCurBackground(const char *defaultname) { - char name[8]; + char name[9]; strncpy(name, defaultname, 8); M_IterateMenuTree(MIT_SetCurBackground, &name); } @@ -8212,8 +8212,13 @@ static void M_DrawSetupChoosePlayerMenu(void) // cur x = ox - txsh; - if (curpatch) - V_DrawScaledPatch(x, y, 0, curpatch); + //if (curpatch) + // V_DrawScaledPatch(x, y, 0, curpatch); + + col = Color_Opposite[charskin->prefcolor - 1][0]; + + // Dummy string to be removed when finalized + V_DrawCharacterName(x, y, col, "Sonic\n&Tails"); } // Alternative menu header diff --git a/src/v_video.c b/src/v_video.c index 78a9ca8dc..358a65e4d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2627,6 +2627,63 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string) } } +// Draw a string using the chrn_font +void V_DrawCharacterName(INT32 x, INT32 y, UINT8 color, const char *string) +{ + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; + const char *ch = string; + INT32 spacewidth = 4; + const UINT8 *colormap = NULL; + + dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + scrwidth -= left; + + if (!color) + colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GREEN, 0); + else + colormap = R_GetTranslationColormap(TC_DEFAULT, color, 0); + + for (;;ch++) + { + if (!*ch) + break; + if (*ch == '\n') + { + cx = x; + cy += 17*dupy; + + continue; + } + + c = *ch; + c = toupper(c); + c -= CHRN_FONTSTART; + + // character does not exist or is a space + if (c < 0 || c >= CHRN_FONTSIZE || !chrn_font[c]) + { + cx += spacewidth * dupx; + continue; + } + + w = SHORT(chrn_font[c]->width) * dupx; + + if (cx > scrwidth) + continue; + if (cx+left + w < 0) //left boundary check + { + cx += w; + continue; + } + + V_DrawFixedPatch((cx)< Date: Thu, 10 Oct 2019 01:56:48 -0400 Subject: [PATCH 041/130] Basic outline color support. This is a huge hack as it requires another font set, with each character's offset manually being set using SLADE. --- src/hu_stuff.c | 30 ++++++++++++++++++++++-------- src/hu_stuff.h | 12 +++++++----- src/m_menu.c | 7 ++----- src/v_video.c | 42 ++++++++++++++++++++++++++++-------------- src/v_video.h | 4 ++-- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 5a4f35a7a..428656bf2 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -71,8 +71,9 @@ patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; patch_t *ttlnum[20]; // act numbers (0-19) -// Character name font -patch_t *chrn_font[CHRN_FONTSIZE]; +// Name tag fonts +patch_t *ntb_font[NT_FONTSIZE]; +patch_t *nto_font[NT_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? @@ -249,17 +250,30 @@ void HU_LoadGraphics(void) ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } - // cache the character name font for entire game execution - j = CHRN_FONTSTART; - for (i = 0; i < CHRN_FONTSIZE; i++) + // cache the base name tag font for entire game execution + j = NT_FONTSTART; + for (i = 0; i < NT_FONTSIZE; i++) { - sprintf(buffer, "CHFNT%.3d", j); + sprintf(buffer, "NTFNT%.3d", j); j++; if (W_CheckNumForName(buffer) == LUMPERROR) - chrn_font[i] = NULL; + ntb_font[i] = NULL; else - chrn_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + ntb_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); + } + + // cache the outline name tag font for entire game execution + j = NT_FONTSTART; + for (i = 0; i < NT_FONTSIZE; i++) + { + sprintf(buffer, "NTFNO%.3d", j); + j++; + + if (W_CheckNumForName(buffer) == LUMPERROR) + nto_font[i] = NULL; + else + nto_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } // cache the crosshairs, don't bother to know which one is being used, diff --git a/src/hu_stuff.h b/src/hu_stuff.h index ed56bad05..55b61d4b7 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -35,10 +35,11 @@ #define CRED_FONTEND 'Z' // the last font character #define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1) -// Character name font -#define CHRN_FONTSTART '!' // the first font character -#define CHRN_FONTEND 'Z' // the last font character -#define CHRN_FONTSIZE (CHRN_FONTEND - CHRN_FONTSTART + 1) +// Name tag font +// Used by base and outline font set +#define NT_FONTSTART '!' // the first font character +#define NT_FONTEND 'Z' // the last font character +#define NT_FONTSIZE (NT_FONTEND - NT_FONTSTART + 1) #define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init(); @@ -82,7 +83,8 @@ extern patch_t *tallnum[10]; extern patch_t *nightsnum[10]; extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; -extern patch_t *chrn_font[CHRN_FONTSIZE]; +extern patch_t *ntb_font[NT_FONTSIZE]; +extern patch_t *nto_font[NT_FONTSIZE]; extern patch_t *ttlnum[20]; extern patch_t *emeraldpics[3][8]; extern patch_t *rflagico; diff --git a/src/m_menu.c b/src/m_menu.c index 2113882ea..7cd998330 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7980,8 +7980,7 @@ static void M_SetupChoosePlayer(INT32 choice) return; } - if (Playing() == false) - M_ChangeMenuMusic("_chsel", true); + M_ChangeMenuMusic("_chsel", true); SP_PlayerDef.prevMenu = currentMenu; M_SetupNextMenu(&SP_PlayerDef); @@ -8215,10 +8214,8 @@ static void M_DrawSetupChoosePlayerMenu(void) //if (curpatch) // V_DrawScaledPatch(x, y, 0, curpatch); - col = Color_Opposite[charskin->prefcolor - 1][0]; - // Dummy string to be removed when finalized - V_DrawCharacterName(x, y, col, "Sonic\n&Tails"); + V_DrawNameTag(x, y, 0, R_GetTranslationColormap(skinnum, SKINCOLOR_BLUE, 0), R_GetTranslationColormap(skinnum, SKINCOLOR_YELLOW, 0), "Sonic\n&Tails."); } // Alternative menu header diff --git a/src/v_video.c b/src/v_video.c index 358a65e4d..a6e8398bb 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2627,24 +2627,21 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string) } } -// Draw a string using the chrn_font -void V_DrawCharacterName(INT32 x, INT32 y, UINT8 color, const char *string) +// Draw a string using the nt_font +// Note that the outline is a seperate font set +void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; + INT32 w, w2, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; const char *ch = string; INT32 spacewidth = 4; - const UINT8 *colormap = NULL; + INT32 lowercase = (option & V_ALLOWLOWERCASE); + option &= ~V_FLIP; // which is also shared with V_ALLOWLOWERCASE... dupx = dupy = 1; scrwidth = vid.width/vid.dupx; left = (scrwidth - BASEVIDWIDTH)/2; scrwidth -= left; - if (!color) - colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GREEN, 0); - else - colormap = R_GetTranslationColormap(TC_DEFAULT, color, 0); - for (;;ch++) { if (!*ch) @@ -2658,17 +2655,34 @@ void V_DrawCharacterName(INT32 x, INT32 y, UINT8 color, const char *string) } c = *ch; - c = toupper(c); - c -= CHRN_FONTSTART; + if (!lowercase) + c = toupper(c); + c -= NT_FONTSTART; // character does not exist or is a space - if (c < 0 || c >= CHRN_FONTSIZE || !chrn_font[c]) + if (c < 0 || c >= NT_FONTSIZE || !ntb_font[c] || !nto_font[c]) { cx += spacewidth * dupx; continue; } - w = SHORT(chrn_font[c]->width) * dupx; + // Outline + w2 = SHORT(nto_font[c]->width) * dupx; + + if (cx > scrwidth) + continue; + if (cx+left + w2 < 0) //left boundary check + { + cx += w2; + continue; + } + + V_DrawFixedPatch((cx)<width) * dupx; if (cx > scrwidth) continue; @@ -2678,7 +2692,7 @@ void V_DrawCharacterName(INT32 x, INT32 y, UINT8 color, const char *string) continue; } - V_DrawFixedPatch((cx)< Date: Thu, 10 Oct 2019 15:50:06 -0400 Subject: [PATCH 042/130] Attempt to fix the offset issues. Better than the previous commit, but not quite there yet. --- src/v_video.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index a6e8398bb..dd72cb65f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2631,7 +2631,7 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string) // Note that the outline is a seperate font set void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string) { - INT32 w, w2, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; const char *ch = string; INT32 spacewidth = 4; INT32 lowercase = (option & V_ALLOWLOWERCASE); @@ -2666,23 +2666,7 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *o continue; } - // Outline - w2 = SHORT(nto_font[c]->width) * dupx; - - if (cx > scrwidth) - continue; - if (cx+left + w2 < 0) //left boundary check - { - cx += w2; - continue; - } - - V_DrawFixedPatch((cx)<width) * dupx; + w = (SHORT(nto_font[c]->width) + SHORT(ntb_font[c]->width)) * dupx; if (cx > scrwidth) continue; @@ -2692,7 +2676,8 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *o continue; } - V_DrawFixedPatch((cx)< Date: Sat, 12 Oct 2019 04:23:11 +0800 Subject: [PATCH 043/130] Create new linedef special type 153: Dynamically Sinking Platform --- src/p_floor.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- src/p_spec.c | 19 +++++++++++++------ 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 19b7611b8..40bd6a6b2 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2425,7 +2425,7 @@ void T_RaiseSector(levelspecthink_t *raise) mobj_t *thing; sector_t *sector; INT32 i; - boolean playeronme = false; + boolean playeronme = false, active = false; fixed_t ceilingdestination, floordestination; result_e res = 0; @@ -2459,8 +2459,49 @@ void T_RaiseSector(levelspecthink_t *raise) break; } } + + if (raise->vars[9]) // Dynamically Sinking Platform^tm + { + tic_t shaketime = 10; + if (raise->vars[11] > shaketime) // State: moving + { + if (playeronme) // If player is standing on the platform, accelerate + { + raise->vars[10] += (FRACUNIT >> 5); + } + else // otherwise, decelerate until inflection + { + raise->vars[10] -= FRACUNIT >> 3; + if (raise->vars[10] <= 0) // inflection! + { + raise->vars[10] = 0; + raise->vars[11] = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese) + } + } + active = raise->vars[10] > 0; + } + else // State: shaking + { + if (playeronme || raise->vars[11]) + { + active = true; + raise->vars[11]++; + if (raise->vars[11] > shaketime) + { + if (playeronme) + raise->vars[10] = FRACUNIT >> 5; + else + raise->vars[10] = FRACUNIT << 1; + } + else + raise->vars[10] = 2*(shaketime/2 - raise->vars[11]) << FRACBITS; + } + } + } + else // Air bobbing platform (not a Dynamically Sinking Platform^tm) + active = playeronme; - if (playeronme) + if (active) { raise->vars[3] = raise->vars[2]; @@ -2553,6 +2594,8 @@ void T_RaiseSector(levelspecthink_t *raise) else if (raise->vars[3] > origspeed) raise->vars[3] = origspeed; } + + raise->vars[3] += raise->vars[10]; res = T_MovePlane ( diff --git a/src/p_spec.c b/src/p_spec.c index 256ca3453..26c4250d5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6132,7 +6132,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) } // Function to maintain backwards compatibility -static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust) +static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic) { levelspecthink_t *airbob; @@ -6169,6 +6169,8 @@ static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust) airbob->vars[5] = sec->ceilingheight; airbob->vars[4] = airbob->vars[5] - (sec->ceilingheight - sec->floorheight); + + airbob->vars[9] = dynamic ? 1 : 0; airbob->sourceline = sourceline; } @@ -6987,11 +6989,16 @@ void P_SpawnSpecials(INT32 fromnetsave) case 151: // Adjustable air bobbing platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151)); + P_AddOldAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false); break; case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddOldAirbob(lines[i].frontsector, lines + i, true); + P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); + break; + case 153: // Dynamic Sinking Platform + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); + lines[i].flags |= ML_BLOCKMONSTERS; + P_AddOldAirbob(lines[i].frontsector, lines + i, false, true); break; case 160: // Float/bob platform @@ -7042,14 +7049,14 @@ void P_SpawnSpecials(INT32 fromnetsave) case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, true); + P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); break; case 177: // Air bobbing platform that will crumble and bob on // the water when it falls and hits, then never return P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, true); + P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); break; case 178: // Crumbling platform that will float when it hits water @@ -7063,7 +7070,7 @@ void P_SpawnSpecials(INT32 fromnetsave) case 180: // Air bobbing platform that will crumble P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, true); + P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); break; case 190: // Rising Platform FOF (solid, opaque, shadows) From bf75a4c29f1d089f5d023795799a233e01209890 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 13 Oct 2019 20:04:45 -0400 Subject: [PATCH 044/130] New -port command line paramater --- src/i_tcp.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index f2b4336dc..da92f2767 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -776,6 +776,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen #endif #endif mysockaddr_t straddr; + struct sockaddr_in sin; + socklen_t len = sizeof(sin); if (s == (SOCKET_TYPE)ERRSOCKET) return (SOCKET_TYPE)ERRSOCKET; @@ -869,12 +871,16 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10); } + if (getsockname(s, (struct sockaddr *)&sin, &len) == -1) + CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n")); + else + current_port = (UINT16)ntohs(sin.sin_port); + return s; } static boolean UDP_Socket(void) { - const char *sock_port = NULL; size_t s; struct my_addrinfo *ai, *runp, hints; int gaie; @@ -896,20 +902,11 @@ static boolean UDP_Socket(void) hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; - if (M_CheckParm("-clientport")) - { - if (!M_IsNextParm()) - I_Error("syntax: -clientport "); - sock_port = M_GetNextParm(); - } - else - sock_port = port_name; - if (M_CheckParm("-bindaddr")) { while (M_IsNextParm()) { - gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai); + gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai); if (gaie == 0) { runp = ai; @@ -930,7 +927,7 @@ static boolean UDP_Socket(void) } else { - gaie = I_getaddrinfo("0.0.0.0", sock_port, &hints, &ai); + gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai); if (gaie == 0) { runp = ai; @@ -945,8 +942,8 @@ static boolean UDP_Socket(void) #ifdef HAVE_MINIUPNPC if (UPNP_support) { - I_UPnP_rem(sock_port, "UDP"); - I_UPnP_add(NULL, sock_port, "UDP"); + I_UPnP_rem(port_name, "UDP"); + I_UPnP_add(NULL, port_name, "UDP"); } #endif } @@ -963,7 +960,7 @@ static boolean UDP_Socket(void) { while (M_IsNextParm()) { - gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai); + gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai); if (gaie == 0) { runp = ai; @@ -984,7 +981,7 @@ static boolean UDP_Socket(void) } else { - gaie = I_getaddrinfo("::", sock_port, &hints, &ai); + gaie = I_getaddrinfo("::", port_name, &hints, &ai); if (gaie == 0) { runp = ai; @@ -1260,7 +1257,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) int gaie; if (!port || !port[0]) - port = port_name; + port = DEFAULTPORT; DEBFILE(va("Creating new node: %s@%s\n", address, port)); @@ -1424,14 +1421,15 @@ boolean I_InitTcpNetwork(void) if (!I_InitTcpDriver()) return false; - if (M_CheckParm("-udpport")) + if (M_CheckParm("-port")) + // Combined -udpport and -clientport into -port + // As it was really redundant having two seperate parms that does the same thing { if (M_IsNextParm()) strcpy(port_name, M_GetNextParm()); else strcpy(port_name, "0"); } - current_port = (UINT16)atoi(port_name); // parse network game options, if (M_CheckParm("-server") || dedicated) From cb228c49380c2f29a69ff3d39bb784d452e305fd Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 13 Oct 2019 20:12:28 -0400 Subject: [PATCH 045/130] Undo this --- src/v_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index dd72cb65f..854224bd5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2666,7 +2666,7 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *o continue; } - w = (SHORT(nto_font[c]->width) + SHORT(ntb_font[c]->width)) * dupx; + w = SHORT(ntb_font[c]->width)+4 * dupx; if (cx > scrwidth) continue; From 0f7939675705dceeeb1c7c844d477d8b39dfaf42 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 13 Oct 2019 20:50:46 -0400 Subject: [PATCH 046/130] New intermission thinker hook --- src/lua_hook.h | 2 ++ src/lua_hooklib.c | 22 ++++++++++++++++++++++ src/y_inter.c | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index 45e116c34..37b1f3e06 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -50,6 +50,7 @@ enum hook { hook_FollowMobj, hook_PlayerCanDamage, hook_PlayerQuit, + hook_IntermissionThinker, hook_MAX // last hook }; @@ -91,5 +92,6 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnM boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting +void LUAh_IntermissionThinker(void); // Hook for Y_Ticker #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 7f7e8adc6..ffc5cf990 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -61,6 +61,7 @@ const char *const hookNames[hook_MAX+1] = { "FollowMobj", "PlayerCanDamage", "PlayerQuit", + "IntermissionThinker", NULL }; @@ -1322,4 +1323,25 @@ void LUAh_PlayerQuit(player_t *plr, int reason) lua_settop(gL, 0); } +// Hook for Y_Ticker +void LUAh_IntermissionThinker(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_IntermissionThinker) + { + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } +} + #endif diff --git a/src/y_inter.c b/src/y_inter.c index 0d6a3d03c..81532dd7f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -35,6 +35,7 @@ #include "p_local.h" #include "m_cond.h" // condition sets +#include "lua_hook.h" // IntermissionThinker hook #ifdef HWRENDER #include "hardware/hw_main.h" @@ -802,6 +803,10 @@ void Y_Ticker(void) if (paused || P_AutoPause()) return; +#ifdef HAVE_BLUA + LUAh_IntermissionThinker(); +#endif + intertic++; // Team scramble code for team match and CTF. From edd016690dc7fde6409545995d5e690e6a11a119 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 14 Oct 2019 02:24:44 -0300 Subject: [PATCH 047/130] A bunch of stuff --- src/dehacked.c | 81 +++++++++++++++++---- src/lua_hudlib.c | 72 +++++++++++++++++++ src/m_menu.c | 146 +++++++++++++++++++++++++++++-------- src/m_menu.h | 10 ++- src/v_video.c | 183 +++++++++++++++++++++++++++++++++++++++++------ src/v_video.h | 8 ++- 6 files changed, 434 insertions(+), 66 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index d4f27b61c..463a71253 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -316,6 +316,10 @@ static boolean findFreeSlot(INT32 *num) // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) description[*num].picname[0] = '\0'; description[*num].nametag[0] = '\0'; + description[*num].displayname[0] = '\0'; + description[*num].oppositecolor = SKINCOLOR_NONE; + description[*num].tagtextcolor = SKINCOLOR_NONE; + description[*num].tagoutlinecolor = SKINCOLOR_NONE; // Found one! ^_^ return (description[*num].used = true); @@ -328,9 +332,16 @@ static void readPlayer(MYFILE *f, INT32 num) char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word; char *word2; + char *displayname = ZZ_Alloc(MAXLINELEN+1); INT32 i; boolean slotfound = false; + #define SLOTFOUND \ + if (!slotfound && (slotfound = findFreeSlot(&num)) == false) \ + goto done; + + displayname[MAXLINELEN] = '\0'; + do { if (myfgets(s, MAXLINELEN, f)) @@ -338,6 +349,17 @@ static void readPlayer(MYFILE *f, INT32 num) if (s[0] == '\n') break; + for (i = 0; i < MAXLINELEN-3; i++) + { + char *tmp; + if (s[i] == '=') + { + tmp = &s[i+2]; + strncpy(displayname, tmp, SKINNAMESIZE); + break; + } + } + word = strtok(s, " "); if (word) strupr(word); @@ -348,8 +370,7 @@ static void readPlayer(MYFILE *f, INT32 num) { char *playertext = NULL; - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) - goto done; + SLOTFOUND for (i = 0; i < MAXLINELEN-3; i++) { @@ -397,18 +418,54 @@ static void readPlayer(MYFILE *f, INT32 num) if (fastcmp(word, "PICNAME")) { - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) - goto done; - + SLOTFOUND strncpy(description[num].picname, word2, 8); } + // new character select + else if (fastcmp(word, "DISPLAYNAME")) + { + SLOTFOUND + // replace '#' with line breaks + // (also remove any '\n') + { + char *cur = NULL; + + // remove '\n' + cur = strchr(displayname, '\n'); + if (cur) + *cur = '\0'; + + // turn '#' into '\n' + cur = strchr(displayname, '#'); + while (cur) + { + *cur = '\n'; + cur = strchr(cur, '#'); + } + } + // copy final string + strncpy(description[num].displayname, displayname, SKINNAMESIZE); + } + else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR")) + { + SLOTFOUND + description[num].oppositecolor = (UINT8)get_number(word2); + } else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) { - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) - goto done; - + SLOTFOUND strncpy(description[num].nametag, word2, 8); } + else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR")) + { + SLOTFOUND + description[num].tagtextcolor = (UINT8)get_number(word2); + } + else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR")) + { + SLOTFOUND + description[num].tagoutlinecolor = (UINT8)get_number(word2); + } else if (fastcmp(word, "STATUS")) { /* @@ -426,9 +483,7 @@ static void readPlayer(MYFILE *f, INT32 num) else if (fastcmp(word, "SKINNAME")) { // Send to free slot. - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) - goto done; - + SLOTFOUND strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlwr(description[num].skinname); } @@ -436,8 +491,9 @@ static void readPlayer(MYFILE *f, INT32 num) deh_warning("readPlayer %d: unknown word '%s'", num, word); } } while (!myfeof(f)); // finish when the line is empty - + #undef SLOTFOUND done: + Z_Free(displayname); Z_Free(s); } @@ -9057,6 +9113,7 @@ struct { {"V_OFFSET",V_OFFSET}, {"V_ALLOWLOWERCASE",V_ALLOWLOWERCASE}, {"V_FLIP",V_FLIP}, + {"V_CENTERNAMETAG",V_CENTERNAMETAG}, {"V_SNAPTOTOP",V_SNAPTOTOP}, {"V_SNAPTOBOTTOM",V_SNAPTOBOTTOM}, {"V_SNAPTOLEFT",V_SNAPTOLEFT}, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 8c1134bca..865b61e8f 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -637,6 +637,68 @@ static int libd_drawString(lua_State *L) return 0; } +static int libd_drawNameTag(lua_State *L) +{ + INT32 x; + INT32 y; + const char *str; + INT32 flags; + UINT8 basecolor; + UINT8 outlinecolor; + UINT8 *basecolormap = NULL; + UINT8 *outlinecolormap = NULL; + + HUDONLY + + x = luaL_checkinteger(L, 1); + y = luaL_checkinteger(L, 2); + str = luaL_checkstring(L, 3); + flags = luaL_optinteger(L, 4, 0); + basecolor = luaL_optinteger(L, 5, SKINCOLOR_BLUE); + outlinecolor = luaL_optinteger(L, 6, SKINCOLOR_ORANGE); + if (basecolor != SKINCOLOR_NONE) + basecolormap = R_GetTranslationColormap(TC_DEFAULT, basecolor, GTC_CACHE); + if (outlinecolor != SKINCOLOR_NONE) + outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE); + + flags &= ~V_PARAMMASK; // Don't let crashes happen. + V_DrawNameTag(x, y, flags, FRACUNIT, basecolormap, outlinecolormap, str); + return 0; +} + +static int libd_drawScaledNameTag(lua_State *L) +{ + fixed_t x; + fixed_t y; + const char *str; + INT32 flags; + fixed_t scale; + UINT8 basecolor; + UINT8 outlinecolor; + UINT8 *basecolormap = NULL; + UINT8 *outlinecolormap = NULL; + + HUDONLY + + x = luaL_checkfixed(L, 1); + y = luaL_checkfixed(L, 2); + str = luaL_checkstring(L, 3); + flags = luaL_optinteger(L, 4, 0); + scale = luaL_optinteger(L, 5, FRACUNIT); + if (scale < 0) + return luaL_error(L, "negative scale"); + basecolor = luaL_optinteger(L, 6, SKINCOLOR_BLUE); + outlinecolor = luaL_optinteger(L, 7, SKINCOLOR_ORANGE); + if (basecolor != SKINCOLOR_NONE) + basecolormap = R_GetTranslationColormap(TC_DEFAULT, basecolor, GTC_CACHE); + if (outlinecolor != SKINCOLOR_NONE) + outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE); + + flags &= ~V_PARAMMASK; // Don't let crashes happen. + V_DrawNameTag(FixedInt(x), FixedInt(y), flags, scale, basecolormap, outlinecolormap, str); + return 0; +} + static int libd_stringWidth(lua_State *L) { const char *str = luaL_checkstring(L, 1); @@ -659,6 +721,13 @@ static int libd_stringWidth(lua_State *L) return 1; } +static int libd_nameTagWidth(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, V_NameTagWidth(luaL_checkstring(L, 1))); + return 1; +} + static int libd_getColormap(lua_State *L) { INT32 skinnum = TC_DEFAULT; @@ -837,9 +906,12 @@ static luaL_Reg lib_draw[] = { {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, {"drawString", libd_drawString}, + {"drawNameTag", libd_drawNameTag}, + {"drawScaledNameTag", libd_drawScaledNameTag}, {"fadeScreen", libd_fadeScreen}, // misc {"stringWidth", libd_stringWidth}, + {"nameTagWidth", libd_nameTagWidth}, // m_random {"RandomFixed",libd_RandomFixed}, {"RandomByte",libd_RandomByte}, diff --git a/src/m_menu.c b/src/m_menu.c index 894b2956c..958efaaa2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3637,10 +3637,13 @@ void M_InitCharacterTables(void) description[i].used = false; strcpy(description[i].notes, "???"); strcpy(description[i].picname, ""); + strcpy(description[i].nametag, ""); strcpy(description[i].skinname, ""); + strcpy(description[i].displayname, ""); description[i].prev = description[i].next = 0; description[i].charpic = NULL; description[i].namepic = NULL; + description[i].oppositecolor = description[i].tagtextcolor = description[i].tagoutlinecolor = 0; } } @@ -7942,19 +7945,11 @@ static void M_SetupChoosePlayer(INT32 choice) description[i].namepic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); } else - { - // If no name tag patch was provided, - // the character select screen - // will simply not draw anything. description[i].namepic = NULL; - } } - else + else if (description[i].nametag[0]) { const char *nametag = description[i].nametag; - // If no name tag patch was provided, - // the character select screen - // will simply not draw anything. description[i].namepic = NULL; if (W_LumpExists(nametag)) description[i].namepic = W_CachePatchName(nametag, PU_CACHE); @@ -8129,7 +8124,9 @@ static void M_DrawSetupChoosePlayerMenu(void) charskin = &skins[skinnum]; // Use the opposite of the character's skincolor - col = Color_Opposite[charskin->prefcolor - 1][0]; + col = description[char_on].oppositecolor; + if (!col) + col = Color_Opposite[charskin->prefcolor - 1][0]; // Make the translation colormap colormap = R_GetTranslationColormap(skinnum, col, 0); @@ -8180,43 +8177,136 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 ox, x, y; INT32 oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL; + const char *curtext = NULL, *prevtext = NULL, *nexttext = NULL; + UINT8 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; + UINT8 curoutlinecolor = 0, prevoutlinecolor = 0, nextoutlinecolor = 0; - // Name tag patches - curpatch = description[char_on].namepic; - if (prev != -1) prevpatch = description[prev].namepic; - if (next != -1) nextpatch = description[next].namepic; + // Name tag + curtext = description[char_on].displayname; + curtextcolor = description[char_on].tagtextcolor; + curoutlinecolor = description[char_on].tagoutlinecolor; + if (curtext[0] == '\0') + curpatch = description[char_on].namepic; + if (skinnum != -1) + { + if (!curtextcolor) + curtextcolor = charskin->prefcolor; + if (!curoutlinecolor) + curoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + } + + // previous character + if (prev != -1) + { + prevtext = description[prev].displayname; + prevtextcolor = description[prev].tagtextcolor; + prevoutlinecolor = description[prev].tagoutlinecolor; + if (prevtext[0] == '\0') + prevpatch = description[prev].namepic; + // Find skin number from description[] + skinnum = getskinfromdescription(prev); + if (skinnum != -1) + { + charskin = &skins[skinnum]; + if (!prevtextcolor) + prevtextcolor = charskin->prefcolor; + if (!prevoutlinecolor) + prevoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + } + } + + // next character + if (next != -1) + { + nexttext = description[next].displayname; + nexttextcolor = description[next].tagtextcolor; + nextoutlinecolor = description[next].tagoutlinecolor; + if (nexttext[0] == '\0') + nextpatch = description[next].namepic; + // Find skin number from description[] + skinnum = getskinfromdescription(next); + if (skinnum != -1) + { + charskin = &skins[skinnum]; + if (!nexttextcolor) + nexttextcolor = charskin->prefcolor; + if (!nextoutlinecolor) + nextoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + } + } txsh = oxsh; ox = 8 + SHORT((description[char_on].charpic)->width)/2; - if (curpatch) - ox -= (SHORT(curpatch->width)/2); y = my + 144; if (char_scroll) { // prev - if (prevpatch && char_scroll < 0) + if ((prev != -1) && char_scroll < 0) { + INT32 ox2 = ox; + if (prevpatch) + ox2 -= (SHORT(prevpatch->width)/2); // Why does this work? - x = (ox - txsh) - BASEVIDWIDTH; - V_DrawScaledPatch(x, y, 0, prevpatch); + x = (ox2 - txsh) - BASEVIDWIDTH; + if (prevtext[0] != '\0') + { + skinnum = getskinfromdescription(prev); + V_DrawNameTag( + x, y, V_CENTERNAMETAG, FRACUNIT, + R_GetTranslationColormap(skinnum, prevtextcolor, 0), + R_GetTranslationColormap(skinnum, prevoutlinecolor, 0), + prevtext + ); + } + else if (prevpatch) + V_DrawScaledPatch(x, y, 0, prevpatch); } // next - else if (nextpatch && char_scroll > 0) + else if ((next != -1) && char_scroll > 0) { - x = (ox - txsh) + BASEVIDWIDTH; + INT32 ox2 = ox; + if (nextpatch) + ox2 -= (SHORT(nextpatch->width)/2); + x = (ox2 - txsh) + BASEVIDWIDTH; if (x < BASEVIDWIDTH) - V_DrawScaledPatch(x, y, 0, nextpatch); + { + if (nexttext[0] != '\0') + { + skinnum = getskinfromdescription(next); + V_DrawNameTag( + x, y, V_CENTERNAMETAG, FRACUNIT, + R_GetTranslationColormap(skinnum, nexttextcolor, 0), + R_GetTranslationColormap(skinnum, nextoutlinecolor, 0), + nexttext + ); + } + else if (nextpatch) + V_DrawScaledPatch(x, y, 0, nextpatch); + } } } // cur - x = ox - txsh; - //if (curpatch) - // V_DrawScaledPatch(x, y, 0, curpatch); - - // Dummy string to be removed when finalized - V_DrawNameTag(x, y, 0, R_GetTranslationColormap(skinnum, SKINCOLOR_BLUE, 0), R_GetTranslationColormap(skinnum, SKINCOLOR_YELLOW, 0), "Sonic\n&Tails."); + skinnum = getskinfromdescription(next); + if (skinnum != -1) + { + INT32 ox2 = ox; + if (curpatch) + ox2 -= (SHORT(curpatch->width)/2); + x = ox2 - txsh; + if (curtext[0] != '\0') + { + V_DrawNameTag( + x, y, V_CENTERNAMETAG, FRACUNIT, + R_GetTranslationColormap(skinnum, curtextcolor, 0), + R_GetTranslationColormap(skinnum, curoutlinecolor, 0), + curtext + ); + } + else if (curpatch) + V_DrawScaledPatch(x, y, 0, curpatch); + } } // Alternative menu header diff --git a/src/m_menu.h b/src/m_menu.h index 409ef4e08..ad29cf2e7 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -322,12 +322,18 @@ typedef struct boolean used; char notes[441]; char picname[8]; - char nametag[8]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 patch_t *charpic; - patch_t *namepic; UINT8 prev; UINT8 next; + + // new character select + char displayname[SKINNAMESIZE+1]; + UINT8 oppositecolor; + char nametag[8]; + patch_t *namepic; + UINT8 tagtextcolor; + UINT8 tagoutlinecolor; } description_t; // level select platter diff --git a/src/v_video.c b/src/v_video.c index c39f708ee..8f44ca8cd 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2630,18 +2630,32 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string) // Draw a string using the nt_font // Note that the outline is a seperate font set -void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string) +static void V_DrawNameTagLine(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; + fixed_t cx, cy, w; + INT32 c, dupx, dupy, scrwidth, left = 0; const char *ch = string; - INT32 spacewidth = 4; - INT32 lowercase = (option & V_ALLOWLOWERCASE); - option &= ~V_FLIP; // which is also shared with V_ALLOWLOWERCASE... - dupx = dupy = 1; - scrwidth = vid.width/vid.dupx; - left = (scrwidth - BASEVIDWIDTH)/2; - scrwidth -= left; + if (option & V_CENTERNAMETAG) + x -= FixedInt(FixedMul((V_NameTagWidth(string)/2)*FRACUNIT, scale)); + option &= ~V_CENTERNAMETAG; // which is also shared with V_ALLOWLOWERCASE... + + cx = x<= NT_FONTSIZE || !ntb_font[c] || !nto_font[c]) { - cx += spacewidth * dupx; + cx += FixedMul((4 * dupx)*FRACUNIT, scale); continue; } - w = SHORT(ntb_font[c]->width)+4 * dupx; + w = FixedMul((SHORT(ntb_font[c]->width)+2 * dupx) * FRACUNIT, scale); - if (cx > scrwidth) + if (FixedInt(cx) > scrwidth) continue; - if (cx+left + w < 0) //left boundary check + if (cx+(left*FRACUNIT) + w < 0) // left boundary check { cx += w; continue; } - V_DrawFixedPatch((cx)<= 2) && (string[0] == '\n') && (string[1] != '\n')) + shift++; + // Then draw it + V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, string+shift); + } + // No line break character was found + else + { + // Don't leave a line break character + // at the start of the string! + if ((strlen(first_token) >= 2) && (first_token[0] == '\n') && (first_token[1] != '\n')) + first_token++; + // Then draw it + V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, first_token); + break; + } + + // Next line + y += FixedInt(FixedMul(lbreakheight*FRACUNIT, scale)); + if ((last_token-text)+1 >= strlen(text)) + last_token = NULL; + else + { + first_token = last_token; + last_token = strchr(first_token+1, '\n'); + } + } + // Free this line + if (string) + Z_Free(string); + } +} + +// Count the amount of lines in name tag string +INT32 V_CountNameTagLines(const char *string) +{ + INT32 lines = 1; + char *text = (char *)string; + char *first_token = text; + char *last_token = strchr(text, '\n'); + + // No line breaks? + if (!last_token) + return lines; + // Split string by the line break character + else + { + while (true) + { + if (last_token) + lines++; + // No line break character was found + else + break; + + // Next line + if ((last_token-text)+1 >= strlen(text)) + last_token = NULL; + else + { + first_token = last_token; + last_token = strchr(first_token+1, '\n'); + } + } + } + return lines; +} + +INT32 V_NameTagWidth(const char *string) +{ + INT32 c, w = 0; + size_t i; + + // It's possible for string to be a null pointer + if (!string) + return 0; + + for (i = 0; i < strlen(string); i++) + { + c = toupper(string[i]) - NT_FONTSTART; + if (c < 0 || c >= NT_FONTSIZE || !ntb_font[c] || !nto_font[c]) + w += 4; + else + w += SHORT(ntb_font[c]->width)+2; + } + + return w; +} + // Find string width from cred_font chars // INT32 V_CreditStringWidth(const char *string) diff --git a/src/v_video.h b/src/v_video.h index ad1454cb7..01d50cd57 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -112,6 +112,7 @@ extern RGBA_t *pMasterPalette; #define V_OFFSET 0x00400000 // account for offsets in patches #define V_ALLOWLOWERCASE 0x00800000 // (strings only) allow fonts that have lowercase letters to use them #define V_FLIP 0x00800000 // (patches only) Horizontal flip +#define V_CENTERNAMETAG 0x00800000 // (nametag only) center nametag lines #define V_SNAPTOTOP 0x01000000 // for centering #define V_SNAPTOBOTTOM 0x02000000 // for centering @@ -203,11 +204,12 @@ INT32 V_LevelNameHeight(const char *string); INT32 V_LevelActNumWidth(INT32 num); // act number width void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); +INT32 V_CreditStringWidth(const char *string); // Draw a string using the nt_font -void V_DrawNameTag(INT32 x, INT32 y, INT32 option, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string); - -INT32 V_CreditStringWidth(const char *string); +void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string); +INT32 V_CountNameTagLines(const char *string); +INT32 V_NameTagWidth(const char *string); // Find string width from hu_font chars INT32 V_StringWidth(const char *string, INT32 option); From c935797a342ff4832149dbee74233f0ba9c07c77 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 14 Oct 2019 16:30:20 +0200 Subject: [PATCH 048/130] Encapsulate the second behavior branch into an else. When a tag is provided, the tagged sector-related branch is run exclusively now. This prevents playing the same sound again from the caller object's origin and other unwanted behaviors. Signed-off-by: Nev3r --- src/p_spec.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 256ca3453..45fd9e4f0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2718,6 +2718,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum); return; } + if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set { if (line->flags & ML_EFFECT5) // Repeat Midtexture @@ -2758,30 +2759,32 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) return; } } - - if (line->flags & ML_NOCLIMB) + else { - // play the sound from nowhere, but only if display player triggered it - if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer])) + if (line->flags & ML_NOCLIMB) + { + // play the sound from nowhere, but only if display player triggered it + if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer])) + S_StartSound(NULL, sfxnum); + } + else if (line->flags & ML_EFFECT4) + { + // play the sound from nowhere S_StartSound(NULL, sfxnum); - } - else if (line->flags & ML_EFFECT4) - { - // play the sound from nowhere - S_StartSound(NULL, sfxnum); - } - else if (line->flags & ML_BLOCKMONSTERS) - { - // play the sound from calling sector's soundorg - if (callsec) - S_StartSound(&callsec->soundorg, sfxnum); + } + else if (line->flags & ML_BLOCKMONSTERS) + { + // play the sound from calling sector's soundorg + if (callsec) + S_StartSound(&callsec->soundorg, sfxnum); + else if (mo) + S_StartSound(&mo->subsector->sector->soundorg, sfxnum); + } else if (mo) - S_StartSound(&mo->subsector->sector->soundorg, sfxnum); - } - else if (mo) - { - // play the sound from mobj that triggered it - S_StartSound(mo, sfxnum); + { + // play the sound from mobj that triggered it + S_StartSound(mo, sfxnum); + } } } break; From 5007abee23e1528ed1f20be9c051179419a68a4a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 14 Oct 2019 13:22:33 -0700 Subject: [PATCH 049/130] Collide with walls of FOF if both planes are intangible --- src/p_maputl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 22998c60e..6ba8f1d59 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -674,7 +674,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF + if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF { if (bottomheight < opentop) { opentop = bottomheight; @@ -687,7 +687,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = bottomheight; } - if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF + if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF { if (topheight > openbottom) { openbottom = topheight; From 597949f370950690021f88b79aae5b6cce91606f Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 14 Oct 2019 21:47:20 -0400 Subject: [PATCH 050/130] Change this for consistency. --- src/lua_hooklib.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ffc5cf990..03c7ce911 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1331,17 +1331,19 @@ void LUAh_IntermissionThinker(void) return; for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_IntermissionThinker) - { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); - if (lua_pcall(gL, 0, 0, 0)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } + { + if (hookp->type != hook_IntermissionThinker) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; } + } } #endif From 37101f826eca9138447042987c0b06172fa9bc36 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 14 Oct 2019 22:12:26 -0400 Subject: [PATCH 051/130] Allow access to players userdata outside levels. In exchange for preventing access to any mobj_t userdata outside levels, including player's own mobj_t. --- src/lua_mobjlib.c | 2 ++ src/lua_playerlib.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 063158b26..2cb9dc329 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -160,6 +160,7 @@ static const char *const mobj_opt[] = { static int mobj_get(lua_State *L) { + INLEVEL mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); enum mobj_e field = Lua_optoption(L, 2, NULL, mobj_opt); lua_settop(L, 2); @@ -405,6 +406,7 @@ static int mobj_get(lua_State *L) #define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_TeleportMove") " instead.", mobj_opt[field]) static int mobj_set(lua_State *L) { + INLEVEL mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt); lua_settop(L, 3); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index dd9959afb..b1222ce67 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -25,7 +25,6 @@ static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; - INLEVEL if (lua_gettop(L) < 2) { //return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do end'."); @@ -52,7 +51,6 @@ static int lib_getPlayer(lua_State *L) { const char *field; // i -> players[i] - INLEVEL if (lua_type(L, 2) == LUA_TNUMBER) { lua_Integer i = luaL_checkinteger(L, 2); From 313b534911ddf9b26091c7a2bbb7eee6b862293e Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 15 Oct 2019 01:55:50 -0400 Subject: [PATCH 052/130] More record attack stuff. Show emblem requirements. Committed because I need sleep... --- src/m_menu.c | 76 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 958efaaa2..fea662942 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8725,6 +8725,7 @@ void M_DrawTimeAttackMenu(void) patch_t *PictureOfLevel; lumpnum_t lumpnum; char beststr[40]; + char reqscore[40], reqtime[40], reqrings[40]; M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false); @@ -8749,43 +8750,26 @@ void M_DrawTimeAttackMenu(void) '\x1D' | V_YELLOWMAP, false); } - V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); - - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); - - V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); - - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(mainrecords[cv_nextmap.value-1]->time, true), - G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), - G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - - V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); - - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) - sprintf(beststr, "(none)"); - else - sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); - - V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); - - // Draw record emblems. em = M_GetLevelEmblems(cv_nextmap.value); + // Draw record emblems. while (em) { switch (em->type) { - case ET_SCORE: yHeight = 48; break; - case ET_TIME: yHeight = 58; break; - case ET_RINGS: yHeight = 68; break; + case ET_SCORE: + yHeight = 48; + sprintf(reqscore, "%u", em->var); + break; + case ET_TIME: + yHeight = 58; + sprintf(reqtime, "%i:%02i.%02i", G_TicsToMinutes((tic_t)em->var, true), + G_TicsToSeconds((tic_t)em->var), + G_TicsToCentiseconds((tic_t)em->var)); + break; + case ET_RINGS: + yHeight = 68; + sprintf(reqrings, "%u", em->var); + break; default: goto skipThisOne; } @@ -8799,6 +8783,34 @@ void M_DrawTimeAttackMenu(void) skipThisOne: em = M_GetLevelEmblems(-1); } + + V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); + + if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score) + sprintf(beststr, "(none)"); + else + sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); + + V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); + V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqscore)); + + if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) + sprintf(beststr, "(none)"); + else + sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(mainrecords[cv_nextmap.value-1]->time, true), + G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), + G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); + + V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:"); + V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqtime)); + + if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) + sprintf(beststr, "(none)"); + else + sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); + + V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); + V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqrings)); } // ALWAYS DRAW level and skin even when not on this menu! From 911fd9576b51faaf5d7447f55e66bb5dea32e35c Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 15 Oct 2019 11:02:19 +0100 Subject: [PATCH 053/130] Rework min/max cvars to allow for "named" values outside their range! Kart-port round 3, with the original commit written by me, toaster. --- src/command.c | 74 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/src/command.c b/src/command.c index cfb36f02f..114b37489 100644 --- a/src/command.c +++ b/src/command.c @@ -1123,32 +1123,42 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) if (var->PossibleValue[0].strvalue && !stricmp(var->PossibleValue[0].strvalue, "MIN")) // bounded cvar { +#define MINVAL 0 +#define MAXVAL 1 INT32 i; - // search for maximum - for (i = 1; var->PossibleValue[i].strvalue; i++) - if (!stricmp(var->PossibleValue[i].strvalue, "MAX")) - break; #ifdef PARANOIA - if (!var->PossibleValue[i].strvalue) + if (!var->PossibleValue[MAXVAL].strvalue) I_Error("Bounded cvar \"%s\" without maximum!\n", var->name); #endif - if ((v != INT32_MIN && v < var->PossibleValue[0].value) || !stricmp(valstr, "MIN")) + // search for other + for (i = MAXVAL+1; var->PossibleValue[i].strvalue; i++) + if (v == var->PossibleValue[i].value || !stricmp(var->PossibleValue[i].strvalue, valstr)) + { + var->value = var->PossibleValue[i].value; + var->string = var->PossibleValue[i].strvalue; + goto finish; + } + + + if ((v != INT32_MIN && v < var->PossibleValue[MINVAL].value) || !stricmp(valstr, "MIN")) { - v = var->PossibleValue[0].value; - valstr = var->PossibleValue[0].strvalue; + v = var->PossibleValue[MINVAL].value; + valstr = var->PossibleValue[MINVAL].strvalue; override = true; overrideval = v; } - else if ((v != INT32_MIN && v > var->PossibleValue[i].value) || !stricmp(valstr, "MAX")) + else if ((v != INT32_MIN && v > var->PossibleValue[MAXVAL].value) || !stricmp(valstr, "MAX")) { - v = var->PossibleValue[i].value; - valstr = var->PossibleValue[i].strvalue; + v = var->PossibleValue[MAXVAL].value; + valstr = var->PossibleValue[MAXVAL].strvalue; override = true; overrideval = v; } if (v == INT32_MIN) goto badinput; +#undef MINVAL +#undef MAXVAL } else { @@ -1538,7 +1548,6 @@ void CV_AddValue(consvar_t *var, INT32 increment) if (var->PossibleValue) { -#define MINVAL 0 if (var == &cv_nextmap) { // Special case for the nextmap variable, used only directly from the menu @@ -1575,21 +1584,40 @@ void CV_AddValue(consvar_t *var, INT32 increment) return; } } +#define MINVAL 0 +#define MAXVAL 1 else if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN")) { - // search the next to last - for (max = 0; var->PossibleValue[max+1].strvalue; max++) - ; +#ifdef PARANOIA + if (!var->PossibleValue[MAXVAL].strvalue) + I_Error("Bounded cvar \"%s\" without maximum!\n", var->name); +#endif - if (newvalue < var->PossibleValue[MINVAL].value) // add the max+1 - newvalue += var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1; + if (newvalue < var->PossibleValue[MINVAL].value || newvalue > var->PossibleValue[MAXVAL].value) + { + INT32 currentindice = -1, newindice; + for (max = MAXVAL+1; var->PossibleValue[max].strvalue; max++) + if (var->PossibleValue[max].value == var->value) + currentindice = max; - newvalue = var->PossibleValue[MINVAL].value + (newvalue - var->PossibleValue[MINVAL].value) - % (var->PossibleValue[max].value - var->PossibleValue[MINVAL].value + 1); + if (currentindice == -1 && max != MAXVAL+1) + newindice = ((increment > 0) ? MAXVAL : max) + increment; + else + newindice = currentindice + increment; - CV_SetValue(var, newvalue); -#undef MINVAL + if (newindice >= max || newindice <= MAXVAL) + { + newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value; + CV_SetValue(var, newvalue); + } + else + CV_Set(var, var->PossibleValue[newindice].strvalue); + } + else + CV_SetValue(var, newvalue); } +#undef MINVAL +#undef MAXVAL else { INT32 currentindice = -1, newindice; @@ -1599,8 +1627,6 @@ void CV_AddValue(consvar_t *var, INT32 increment) if (var->PossibleValue[max].value == var->value) currentindice = max; - max--; - if (var == &cv_chooseskin) { // Special case for the chooseskin variable, used only directly from the menu @@ -1632,7 +1658,7 @@ void CV_AddValue(consvar_t *var, INT32 increment) var->value); #endif - newindice = (currentindice + increment + max + 1) % (max+1); + newindice = (currentindice + increment + max) % max; CV_Set(var, var->PossibleValue[newindice].strvalue); } } From 910df54fb58851bff52688ec8fed99b56b13c3d5 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 15 Oct 2019 11:49:37 +0100 Subject: [PATCH 054/130] Added some examples of cvars that can use named values. * Pandora's box now has infinite lives show up as "Infinite" instead of "-1". * `pointlimit None` * `timelimit None` * Ported `basenumlaps` (with "Map default" value) from Kart to replace `usemaplaps`, for if Circuit ever gets shown any love ever again. * `respawndelay Off` * `resynchattempts Don't` --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 29 +++++++++++++++++++++-------- src/d_netcmd.h | 2 +- src/m_menu.c | 9 +++++---- src/p_setup.c | 7 +++++-- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 476bb1a1e..0ea4ec83f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2969,7 +2969,7 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, N consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "Don't"}, {0, NULL}}; consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1e69d371e..f7a2bdeb7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -74,6 +74,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum); static void PointLimit_OnChange(void); static void TimeLimit_OnChange(void); static void NumLaps_OnChange(void); +static void BaseNumLaps_OnChange(void); static void Mute_OnChange(void); static void Hidetime_OnChange(void); @@ -210,7 +211,7 @@ consvar_t cv_allowteamchange = {"allowteamchange", "Yes", CV_NETVAR, CV_YesNo, N consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}}; consvar_t cv_respawntime = {"respawndelay", "3", CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_competitionboxes = {"competitionboxes", "Mystery", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -315,16 +316,17 @@ consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0, static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; -consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, +static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {999999990, "MAX"}, {0, "None"}, {0, NULL}}; +consvar_t cv_pointlimit = {"pointlimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; -consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, +static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; +consvar_t cv_timelimit = {"timelimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {50, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; +consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -497,7 +499,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_friendlyfire); CV_RegisterVar(&cv_pointlimit); CV_RegisterVar(&cv_numlaps); - CV_RegisterVar(&cv_usemapnumlaps); + CV_RegisterVar(&cv_basenumlaps); CV_RegisterVar(&cv_hazardlog); @@ -4465,3 +4467,14 @@ static void Command_ShowTime_f(void) CONS_Printf(M_GetText("The current time is %f.\nThe timelimit is %f\n"), (double)leveltime/TICRATE, (double)timelimitintics/TICRATE); } + +static void BaseNumLaps_OnChange(void) +{ + if (gametype == GT_RACE) + { + if (cv_basenumlaps.value) + CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n")); + else + CONS_Printf(M_GetText("Number of laps will be changed to %d next round.\n"), cv_basenumlaps.value); + } +} diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 5076c8afa..3e3c61112 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -66,7 +66,7 @@ extern consvar_t cv_friendlyfire; extern consvar_t cv_pointlimit; extern consvar_t cv_timelimit; extern consvar_t cv_numlaps; -extern consvar_t cv_usemapnumlaps; +extern consvar_t cv_basenumlaps; extern UINT32 timelimitintics; extern consvar_t cv_allowexitlevel; diff --git a/src/m_menu.c b/src/m_menu.c index fb276f77d..66f7cf3ba 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -434,7 +434,8 @@ consvar_t cv_ghost_guest = {"ghost_guest", "Show", CV_SAVE, ghost2_cons_ static CV_PossibleValue_t dummyteam_cons_t[] = {{0, "Spectator"}, {1, "Red"}, {2, "Blue"}, {0, NULL}}; static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}, {0, NULL}}; static CV_PossibleValue_t ringlimit_cons_t[] = {{0, "MIN"}, {9999, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t liveslimit_cons_t[] = {{-1, "MIN"}, {99, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t liveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {-1, "Infinite"}, {0, NULL}}; +static CV_PossibleValue_t contlimit_cons_t[] = {{0, "MIN"}, {99, "MAX"}, {0, NULL}}; static CV_PossibleValue_t dummymares_cons_t[] = { {-1, "END"}, {0,"Overall"}, {1,"Mare 1"}, {2,"Mare 2"}, {3,"Mare 3"}, {4,"Mare 4"}, {5,"Mare 5"}, {6,"Mare 6"}, {7,"Mare 7"}, {8,"Mare 8"}, {0,NULL} }; @@ -443,7 +444,7 @@ static consvar_t cv_dummyteam = {"dummyteam", "Spectator", CV_HIDEN, dummyteam_c static consvar_t cv_dummyscramble = {"dummyscramble", "Random", CV_HIDEN, dummyscramble_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_dummyrings = {"dummyrings", "0", CV_HIDEN, ringlimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_dummylives = {"dummylives", "0", CV_HIDEN, liveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static consvar_t cv_dummycontinues = {"dummycontinues", "0", CV_HIDEN, liveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static consvar_t cv_dummycontinues = {"dummycontinues", "0", CV_HIDEN, contlimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dummymares_cons_t, Dummymares_OnChange, 0, NULL, NULL, 0, 0, NULL}; // ========================================================================== @@ -6081,9 +6082,9 @@ static void M_PandorasBox(INT32 choice) else CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); if (players[consoleplayer].lives == INFLIVES) - CV_StealthSetValue(&cv_dummylives, -1); + CV_StealthSet(&cv_dummylives, "Infinite"); else - CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); + CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1)); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); SR_PandorasBox[6].status = ((players[consoleplayer].charflags & SF_SUPER) #ifndef DEVELOP diff --git a/src/p_setup.c b/src/p_setup.c index c83c8cd5c..a362d2ec1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3047,8 +3047,11 @@ boolean P_SetupLevel(boolean skipprecip) CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n")); } - else if (gametype == GT_RACE && server && cv_usemapnumlaps.value) - CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps); + else if (gametype == GT_RACE && server) + CV_StealthSetValue(&cv_numlaps, + (cv_basenumlaps.value) + ? cv_basenumlaps.value + : mapheaderinfo[gamemap - 1]->numlaps); // =========== // landing point for netgames. From 3185a661915c5134a05e7c3d518469e49de3c2ed Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 15 Oct 2019 11:55:40 +0100 Subject: [PATCH 055/130] Quick macro substitution to make sure MAXSCORE is consistent. --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f7a2bdeb7..d39c289cc 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -316,7 +316,7 @@ consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0, static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {999999990, "MAX"}, {0, "None"}, {0, NULL}}; +static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}}; consvar_t cv_pointlimit = {"pointlimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; From aa9bc574da314d21e9f8a854698235dc9c7aab19 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 15 Oct 2019 12:24:31 +0100 Subject: [PATCH 056/130] * Fix cv_pointlimit's weird behaviour in match mode by standardising the switching between "named" and "range" values in CV_AddValue. * Optimise M_ChangeCvar. --- src/command.c | 46 +++++++++++++++++++++++++++++++++------------- src/m_menu.c | 22 +++++----------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/command.c b/src/command.c index 114b37489..b3181bd05 100644 --- a/src/command.c +++ b/src/command.c @@ -1525,6 +1525,9 @@ void CV_AddValue(consvar_t *var, INT32 increment) { INT32 newvalue, max; + if (!increment) + return; + // count pointlimit better if (var == &cv_pointlimit && (gametype == GT_MATCH)) increment *= 50; @@ -1553,7 +1556,6 @@ void CV_AddValue(consvar_t *var, INT32 increment) // Special case for the nextmap variable, used only directly from the menu INT32 oldvalue = var->value - 1, gt; gt = cv_newgametype.value; - if (increment != 0) // Going up! { newvalue = var->value - 1; do @@ -1597,21 +1599,39 @@ void CV_AddValue(consvar_t *var, INT32 increment) { INT32 currentindice = -1, newindice; for (max = MAXVAL+1; var->PossibleValue[max].strvalue; max++) - if (var->PossibleValue[max].value == var->value) - currentindice = max; - - if (currentindice == -1 && max != MAXVAL+1) - newindice = ((increment > 0) ? MAXVAL : max) + increment; - else - newindice = currentindice + increment; - - if (newindice >= max || newindice <= MAXVAL) { - newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value; - CV_SetValue(var, newvalue); + if (var->PossibleValue[max].value == newvalue) + { + increment = 0; + currentindice = max; + } + else if (var->PossibleValue[max].value == var->value) + currentindice = max; + } + + if (increment) + { + increment = (increment > 0) ? 1 : -1; + if (currentindice == -1 && max != MAXVAL+1) + newindice = ((increment > 0) ? MAXVAL : max) + increment; + else + newindice = currentindice + increment; + + if (newindice >= max || newindice <= MAXVAL) + { + if (var == &cv_pointlimit && (gametype == GT_MATCH) && increment > 0) + CV_SetValue(var, 50); + else + { + newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value; + CV_SetValue(var, newvalue); + } + } + else + CV_Set(var, var->PossibleValue[newindice].strvalue); } else - CV_Set(var, var->PossibleValue[newindice].strvalue); + CV_Set(var, var->PossibleValue[currentindice].strvalue); } else CV_SetValue(var, newvalue); diff --git a/src/m_menu.c b/src/m_menu.c index 66f7cf3ba..1935c76c6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2788,31 +2788,19 @@ static void M_ChangeCvar(INT32 choice) choice = (choice<<1) - 1; - if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER) - ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER) - ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD)) + if (cv->flags & CV_FLOAT) { - if (cv->flags & CV_FLOAT && (currentMenu->menuitems[itemOn].status & IT_CV_FLOATSLIDER) == IT_CV_FLOATSLIDER) + if (((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_SLIDER) + ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER) + ||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD) + || !(currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP)) { char s[20]; sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f)); CV_Set(cv,s); } else - CV_SetValue(cv,cv->value+(choice)); - } - else if (cv->flags & CV_FLOAT) - { - if (currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP) - { CV_SetValue(cv,FIXED_TO_FLOAT(cv->value)+(choice)); - } - else - { - char s[20]; - sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f)); - CV_Set(cv,s); - } } else CV_AddValue(cv,choice); From 8f3e59b43d1129c9eed910281da827024580be9e Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 15 Oct 2019 13:36:04 +0100 Subject: [PATCH 057/130] Improved "HELP" command! Ported from Kart, original commit also by me (toaster). --- src/command.c | 120 ++++++++++++++++++++++++++++++++++++------------- src/console.c | 6 +-- src/d_netcmd.c | 28 ++++++------ src/d_netcmd.h | 2 +- src/m_menu.c | 17 ++++--- 5 files changed, 118 insertions(+), 55 deletions(-) diff --git a/src/command.c b/src/command.c index b3181bd05..6bdd6e7d3 100644 --- a/src/command.c +++ b/src/command.c @@ -709,15 +709,21 @@ static void COM_Help_f(void) if (COM_Argc() > 1) { - cvar = CV_FindVar(COM_Argv(1)); + const char *help = COM_Argv(1); + cvar = CV_FindVar(help); if (cvar) { - CONS_Printf(M_GetText("Variable %s:\n"), cvar->name); + boolean floatmode = false; + const char *cvalue = NULL; + CONS_Printf("\x82""Variable %s:\n", cvar->name); CONS_Printf(M_GetText(" flags :")); if (cvar->flags & CV_SAVE) CONS_Printf("AUTOSAVE "); if (cvar->flags & CV_FLOAT) + { CONS_Printf("FLOAT "); + floatmode = true; + } if (cvar->flags & CV_NETVAR) CONS_Printf("NETVAR "); if (cvar->flags & CV_CALL) @@ -727,59 +733,109 @@ static void COM_Help_f(void) CONS_Printf("\n"); if (cvar->PossibleValue) { - if (stricmp(cvar->PossibleValue[0].strvalue, "MIN") == 0) - { - for (i = 1; cvar->PossibleValue[i].strvalue != NULL; i++) - if (!stricmp(cvar->PossibleValue[i].strvalue, "MAX")) - break; - CONS_Printf(M_GetText(" range from %d to %d\n"), cvar->PossibleValue[0].value, - cvar->PossibleValue[i].value); - CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value); - } + CONS_Printf(" Possible values:\n"); + if (cvar->PossibleValue == CV_YesNo) + CONS_Printf(" Yes or No (On or Off, 1 or 0)\n"); + else if (cvar->PossibleValue == CV_OnOff) + CONS_Printf(" On or Off (Yes or No, 1 or 0)\n"); else { - const char *cvalue = NULL; - CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name); + if (!stricmp(cvar->PossibleValue[0].strvalue, "MIN") && !stricmp(cvar->PossibleValue[1].strvalue, "MAX")) + { + if (floatmode) + CONS_Printf(" range from %f to %f\n", FIXED_TO_FLOAT(cvar->PossibleValue[0].value), + FIXED_TO_FLOAT(cvar->PossibleValue[1].value)); + else + CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[0].value, + cvar->PossibleValue[1].value); + i = 2; + } + + //CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name); while (cvar->PossibleValue[i].strvalue) { - CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value, - cvar->PossibleValue[i].strvalue); + if (floatmode) + CONS_Printf(" %-2f : %s\n", FIXED_TO_FLOAT(cvar->PossibleValue[i].value), + cvar->PossibleValue[i].strvalue); + else + CONS_Printf(" %-2d : %s\n", cvar->PossibleValue[i].value, + cvar->PossibleValue[i].strvalue); if (cvar->PossibleValue[i].value == cvar->value) cvalue = cvar->PossibleValue[i].strvalue; i++; } - if (cvalue) - CONS_Printf(M_GetText(" Current value: %s\n"), cvalue); - else - CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value); } } + + if (cvalue) + CONS_Printf(" Current value: %s\n", cvalue); + else if (cvar->string) + CONS_Printf(" Current value: %s\n", cvar->string); else - CONS_Printf(M_GetText(" Current value: %d\n"), cvar->value); + CONS_Printf(" Current value: %d\n", cvar->value); } else - CONS_Printf(M_GetText("No help for this command/variable\n")); + { + for (cmd = com_commands; cmd; cmd = cmd->next) + { + if (strcmp(cmd->name, help)) + continue; + + CONS_Printf("\x82""Command %s:\n", cmd->name); + CONS_Printf(" help is not available for commands"); + CONS_Printf("\x82""\nCheck wiki.srb2.org for more or try typing without arguments\n"); + return; + } + + CONS_Printf("No exact match, searching...\n"); + + // variables + CONS_Printf("\x82""Variables:\n"); + for (cvar = consvar_vars; cvar; cvar = cvar->next) + { + if ((cvar->flags & CV_NOSHOWHELP) || (!strstr(cvar->name, help))) + continue; + CONS_Printf("%s ", cvar->name); + i++; + } + + // commands + CONS_Printf("\x82""\nCommands:\n"); + for (cmd = com_commands; cmd; cmd = cmd->next) + { + if (!strstr(cmd->name, help)) + continue; + CONS_Printf("%s ",cmd->name); + i++; + } + + CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help \n"); + + CONS_Debug(DBG_GAMELOGIC, "\x87Total : %d\n", i); + } + return; } else { + // variables + CONS_Printf("\x82""Variables:\n"); + for (cvar = consvar_vars; cvar; cvar = cvar->next) + { + if (cvar->flags & CV_NOSHOWHELP) + continue; + CONS_Printf("%s ", cvar->name); + i++; + } + // commands - CONS_Printf("\x82%s", M_GetText("Commands\n")); + CONS_Printf("\x82""\nCommands:\n"); for (cmd = com_commands; cmd; cmd = cmd->next) { CONS_Printf("%s ",cmd->name); i++; } - // variables - CONS_Printf("\n\x82%s", M_GetText("Variables\n")); - for (cvar = consvar_vars; cvar; cvar = cvar->next) - { - if (!(cvar->flags & CV_NOSHOWHELP)) - CONS_Printf("%s ", cvar->name); - i++; - } - - CONS_Printf("\n\x82%s", M_GetText("Read help file for more or type help \n")); + CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help \n"); CONS_Debug(DBG_GAMELOGIC, "\x82Total : %d\n", i); } diff --git a/src/console.c b/src/console.c index 09a6cab45..11e236696 100644 --- a/src/console.c +++ b/src/console.c @@ -175,11 +175,11 @@ static void CONS_Clear_f(void) // Choose english keymap // -static void CONS_English_f(void) +/*static void CONS_English_f(void) { shiftxform = english_shiftxform; CONS_Printf(M_GetText("%s keymap.\n"), M_GetText("English")); -} +}*/ static char *bindtable[NUMINPUTS]; @@ -394,7 +394,7 @@ void CON_Init(void) // register our commands // COM_AddCommand("cls", CONS_Clear_f); - COM_AddCommand("english", CONS_English_f); + //COM_AddCommand("english", CONS_English_f); // set console full screen for game startup MAKE SURE VID_Init() done !!! con_destlines = vid.height; con_curlines = vid.height; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d39c289cc..b897aafd6 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -65,7 +65,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); static void Got_Addfilecmd(UINT8 **cp, INT32 playernum); static void Got_Pause(UINT8 **cp, INT32 playernum); -static void Got_Suicide(UINT8 **cp, INT32 playernum); +static void Got_Respawn(UINT8 **cp, INT32 playernum); static void Got_RandomSeed(UINT8 **cp, INT32 playernum); static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum); static void Got_Teamchange(UINT8 **cp, INT32 playernum); @@ -117,7 +117,7 @@ static void Command_Addfile(void); static void Command_ListWADS_f(void); static void Command_RunSOC(void); static void Command_Pause(void); -static void Command_Suicide(void); +static void Command_Respawn(void); static void Command_Version_f(void); #ifdef UPDATE_ALERT @@ -394,7 +394,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "REQADDFILE", "DELFILE", // replace next time we add an XD "SETMOTD", - "SUICIDE", + "RESPAWN", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -429,7 +429,7 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); RegisterNetXCmd(XD_REQADDFILE, Got_RequestAddfilecmd); RegisterNetXCmd(XD_PAUSE, Got_Pause); - RegisterNetXCmd(XD_SUICIDE, Got_Suicide); + RegisterNetXCmd(XD_RESPAWN, Got_Respawn); RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd); #ifdef HAVE_BLUA RegisterNetXCmd(XD_LUACMD, Got_Luacmd); @@ -464,7 +464,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("runsoc", Command_RunSOC); COM_AddCommand("pause", Command_Pause); - COM_AddCommand("suicide", Command_Suicide); + COM_AddCommand("respawn", Command_Respawn); COM_AddCommand("gametype", Command_ShowGametype_f); COM_AddCommand("version", Command_Version_f); @@ -2029,7 +2029,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) } // Command for stuck characters in netgames, griefing, etc. -static void Command_Suicide(void) +static void Command_Respawn(void) { UINT8 buf[4]; UINT8 *cp = buf; @@ -2055,17 +2055,17 @@ static void Command_Suicide(void) return; } - SendNetXCmd(XD_SUICIDE, &buf, 4); + SendNetXCmd(XD_RESPAWN, &buf, 4); } -static void Got_Suicide(UINT8 **cp, INT32 playernum) +static void Got_Respawn(UINT8 **cp, INT32 playernum) { - INT32 suicideplayer = READINT32(*cp); + INT32 respawnplayer = READINT32(*cp); - // You can't suicide someone else. Nice try, there. - if (suicideplayer != playernum || (!G_PlatformGametype())) + // You can't respawn someone else. Nice try, there. + if (respawnplayer != playernum || (!G_PlatformGametype())) { - CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); + CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]); if (server) { UINT8 buf[2]; @@ -2077,8 +2077,8 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum) return; } - if (players[suicideplayer].mo) - P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 1, DMG_INSTAKILL); + if (players[respawnplayer].mo) + P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 1, DMG_INSTAKILL); } /** Deals with an ::XD_RANDOMSEED message in a netgame. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 3e3c61112..22e5ffc60 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -136,7 +136,7 @@ typedef enum XD_REQADDFILE, // 17 XD_DELFILE, // 18 - replace next time we add an XD XD_SETMOTD, // 19 - XD_SUICIDE, // 20 + XD_RESPAWN, // 20 XD_DEMOTED, // 21 #ifdef HAVE_BLUA XD_LUACMD, // 22 diff --git a/src/m_menu.c b/src/m_menu.c index 1935c76c6..f87c5c37d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2885,6 +2885,15 @@ static void M_PrevOpt(void) // (in other words -- stop bullshit happening by mashing buttons in fades) static boolean noFurtherInput = false; +static void Command_Manual_f(void) +{ + if (modeattacking) + return; + M_StartControlPanel(); + currentMenu = &MISC_HelpDef; + itemOn = 0; +} + // // M_Responder // @@ -3035,11 +3044,7 @@ boolean M_Responder(event_t *ev) switch (ch) { case KEY_F1: // Help key - if (modeattacking) - return true; - M_StartControlPanel(); - currentMenu = &MISC_HelpDef; - itemOn = 0; + Command_Manual_f(); return true; case KEY_F2: // Empty @@ -3536,6 +3541,8 @@ void M_Init(void) { int i; + COM_AddCommand("manual", Command_Manual_f); + CV_RegisterVar(&cv_nextmap); CV_RegisterVar(&cv_newgametype); CV_RegisterVar(&cv_chooseskin); From 360ae45994c86b7fd0a94a10f9b46bb799184047 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 15 Oct 2019 13:46:45 +0100 Subject: [PATCH 058/130] Make use of MINVAL and MAXVAL consistent in COM_Help_f. --- src/command.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/command.c b/src/command.c index 6bdd6e7d3..464bf5216 100644 --- a/src/command.c +++ b/src/command.c @@ -740,16 +740,20 @@ static void COM_Help_f(void) CONS_Printf(" On or Off (Yes or No, 1 or 0)\n"); else { - if (!stricmp(cvar->PossibleValue[0].strvalue, "MIN") && !stricmp(cvar->PossibleValue[1].strvalue, "MAX")) +#define MINVAL 0 +#define MAXVAL 1 + if (!stricmp(cvar->PossibleValue[MINVAL].strvalue, "MIN")) { if (floatmode) - CONS_Printf(" range from %f to %f\n", FIXED_TO_FLOAT(cvar->PossibleValue[0].value), - FIXED_TO_FLOAT(cvar->PossibleValue[1].value)); + CONS_Printf(" range from %f to %f\n", FIXED_TO_FLOAT(cvar->PossibleValue[MINVAL].value), + FIXED_TO_FLOAT(cvar->PossibleValue[MAXVAL].value)); else - CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[0].value, - cvar->PossibleValue[1].value); - i = 2; + CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[MINVAL].value, + cvar->PossibleValue[MAXVAL].value); + i = MAXVAL+1; } +#undef MINVAL +#undef MAXVAL //CONS_Printf(M_GetText(" possible value : %s\n"), cvar->name); while (cvar->PossibleValue[i].strvalue) From 9c33f160a6d4f77560f6f39c6fa0fc9d55108fbf Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 15 Oct 2019 22:54:21 -0400 Subject: [PATCH 059/130] Lots of changes * Show emblem requirement on record attack menu * Use bigger emblems on the menu. * Display your best number of collected rings in yellow if reached perfect bonus. * Adjusted XTRA frames (again) --- src/doomstat.h | 3 +- src/g_game.c | 7 ++++ src/info.h | 5 ++- src/m_cond.c | 32 ++++++++++++++---- src/m_cond.h | 4 +-- src/m_menu.c | 88 ++++++++++++++++++++++++++++---------------------- src/v_video.c | 2 +- src/y_inter.c | 3 ++ 8 files changed, 93 insertions(+), 51 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 57e37f72d..7d06f03e2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -327,7 +327,7 @@ typedef struct // Music stuff. UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds char musintername[7]; ///< Intermission screen music. - + char muspostbossname[7]; ///< Post-bossdeath music. UINT16 muspostbosstrack; ///< Post-bossdeath track. UINT32 muspostbosspos; ///< Post-bossdeath position @@ -433,6 +433,7 @@ typedef struct tic_t time; ///< Time in which the level was finished. UINT32 score; ///< Score when the level was finished. UINT16 rings; ///< Rings when the level was finished. + boolean gotperfect; ///< Got perfect bonus? } recorddata_t; /** Setup for one NiGHTS map. diff --git a/src/g_game.c b/src/g_game.c index 6c31ce9e3..fc5055bab 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3341,6 +3341,7 @@ void G_LoadGameData(void) UINT32 recscore; tic_t rectime; UINT16 recrings; + boolean gotperf; UINT8 recmares; INT32 curmare; @@ -3433,6 +3434,7 @@ void G_LoadGameData(void) recscore = READUINT32(save_p); rectime = (tic_t)READUINT32(save_p); recrings = READUINT16(save_p); + gotperf = (boolean)READUINT8(save_p); if (recrings > 10000 || recscore > MAXSCORE) goto datacorrupt; @@ -3444,6 +3446,9 @@ void G_LoadGameData(void) mainrecords[i]->time = rectime; mainrecords[i]->rings = recrings; } + + if (gotperf) + mainrecords[i]->gotperfect = gotperf; } // Nights records @@ -3575,12 +3580,14 @@ void G_SaveGameData(void) WRITEUINT32(save_p, mainrecords[i]->score); WRITEUINT32(save_p, mainrecords[i]->time); WRITEUINT16(save_p, mainrecords[i]->rings); + WRITEUINT8(save_p, mainrecords[i]->gotperfect); } else { WRITEUINT32(save_p, 0); WRITEUINT32(save_p, 0); WRITEUINT16(save_p, 0); + WRITEUINT8(save_p, 0); } } diff --git a/src/info.h b/src/info.h index 1e7652557..38e6276ab 100644 --- a/src/info.h +++ b/src/info.h @@ -874,9 +874,8 @@ typedef enum playersprite // SPR2_XTRA #define XTRA_LIFEPIC 0 // Life icon patch #define XTRA_CHARSEL 1 // Character select picture -#define XTRA_NAMETAG 2 // Character select nametag -#define XTRA_CONTINUE 3 // Continue icon -#define XTRA_ENDING 4 // Ending finale patches +#define XTRA_CONTINUE 2 // Continue icon +#define XTRA_ENDING 3 // Ending finale patches typedef enum state { diff --git a/src/m_cond.c b/src/m_cond.c index 539c6d1f6..b7520aba7 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -528,12 +528,22 @@ skincolors_t M_GetEmblemColor(emblem_t *em) return em->color; } -const char *M_GetEmblemPatch(emblem_t *em) +const char *M_GetEmblemPatch(emblem_t *em, boolean big) { - static char pnamebuf[7] = "GOTITn"; + static char pnamebuf[7]; + + if (!big) + strcpy(pnamebuf, "GOTITn"); + else + strcpy(pnamebuf, "EMBMn0"); I_Assert(em->sprite >= 'A' && em->sprite <= 'Z'); - pnamebuf[5] = em->sprite; + + if (!big) + pnamebuf[5] = em->sprite; + else + pnamebuf[4] = em->sprite; + return pnamebuf; } @@ -544,11 +554,21 @@ skincolors_t M_GetExtraEmblemColor(extraemblem_t *em) return em->color; } -const char *M_GetExtraEmblemPatch(extraemblem_t *em) +const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big) { - static char pnamebuf[7] = "GOTITn"; + static char pnamebuf[7]; + + if (!big) + strcpy(pnamebuf, "GOTITn"); + else + strcpy(pnamebuf, "EMBMn0"); I_Assert(em->sprite >= 'A' && em->sprite <= 'Z'); - pnamebuf[5] = em->sprite; + + if (!big) + pnamebuf[5] = em->sprite; + else + pnamebuf[4] = em->sprite; + return pnamebuf; } diff --git a/src/m_cond.h b/src/m_cond.h index f82e49372..e9859cf11 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -171,9 +171,9 @@ INT32 M_CountEmblems(void); // Emblem shit emblem_t *M_GetLevelEmblems(INT32 mapnum); skincolors_t M_GetEmblemColor(emblem_t *em); -const char *M_GetEmblemPatch(emblem_t *em); +const char *M_GetEmblemPatch(emblem_t *em, boolean big); skincolors_t M_GetExtraEmblemColor(extraemblem_t *em); -const char *M_GetExtraEmblemPatch(extraemblem_t *em); +const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big); // If you're looking to compare stats for unlocks or what not, use these // They stop checking upon reaching the target number so they diff --git a/src/m_menu.c b/src/m_menu.c index fea662942..2a028834d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -753,8 +753,8 @@ static menuitem_t SP_TimeAttackLevelSelectMenu[] = // Single Player Time Attack static menuitem_t SP_TimeAttackMenu[] = { - {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", M_HandleTimeAttackLevelSelect, 52}, - {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62}, + {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", M_HandleTimeAttackLevelSelect, 62}, + {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 72}, {IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100}, {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110}, @@ -3906,7 +3906,7 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y) lasttype = curtype; if (emblem->collected) - V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), + V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); else V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); @@ -4345,7 +4345,7 @@ static void M_DrawPauseMenu(void) continue; if (emblem->collected) - V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), + V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); else V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE)); @@ -6866,7 +6866,7 @@ static void M_DrawEmblemHints(void) if (emblem->collected) { collected = V_GREENMAP; - V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE), + V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); } else @@ -8487,7 +8487,7 @@ static void M_DrawStatsMaps(int location) exemblem = &extraemblems[i]; if (exemblem->collected) - V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE), + V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem, false), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE)); else V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); @@ -8632,9 +8632,10 @@ static void M_HandleLevelStats(INT32 choice) // Drawing function for Time Attack void M_DrawTimeAttackMenu(void) { - INT32 i, x, y, cursory = 0; + INT32 i, x, y, empatx, empaty, cursory = 0; UINT16 dispstatus; patch_t *PictureOfUrFace; // my WHAT + patch_t *empatch; M_SetMenuCurBackground("RECATKBG"); @@ -8738,16 +8739,22 @@ void M_DrawTimeAttackMenu(void) PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); y = 32+lsheadingheight; - V_DrawSmallScaledPatch(208, y, 0, PictureOfLevel); + V_DrawSmallScaledPatch(216, y, 0, PictureOfLevel); - if (itemOn == talevel) + + if (currentMenu == &SP_TimeAttackDef) { - /* Draw arrows !! */ - y = y + 25 - 4; - V_DrawCharacter(208 - 10 - (skullAnimCounter/5), y, - '\x1C' | V_YELLOWMAP, false); - V_DrawCharacter(208 + 80 + 2 + (skullAnimCounter/5), y, - '\x1D' | V_YELLOWMAP, false); + if (itemOn == talevel) + { + /* Draw arrows !! */ + y = y + 25 - 4; + V_DrawCharacter(216 - 10 - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(216 + 80 + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + // Draw press ESC to exit string on main record attack menu + V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); } em = M_GetLevelEmblems(cv_nextmap.value); @@ -8757,42 +8764,46 @@ void M_DrawTimeAttackMenu(void) switch (em->type) { case ET_SCORE: - yHeight = 48; - sprintf(reqscore, "%u", em->var); + yHeight = 33; + sprintf(reqscore, "(%u)", em->var); break; case ET_TIME: - yHeight = 58; - sprintf(reqtime, "%i:%02i.%02i", G_TicsToMinutes((tic_t)em->var, true), + yHeight = 53; + sprintf(reqtime, "(%i:%02i.%02i)", G_TicsToMinutes((tic_t)em->var, true), G_TicsToSeconds((tic_t)em->var), G_TicsToCentiseconds((tic_t)em->var)); break; case ET_RINGS: - yHeight = 68; - sprintf(reqrings, "%u", em->var); + yHeight = 73; + sprintf(reqrings, "(%u)", em->var); break; default: goto skipThisOne; } + empatch = W_CachePatchName(M_GetEmblemPatch(em, true), PU_CACHE); + + empatx = SHORT(empatch->leftoffset)/2; + empaty = SHORT(empatch->topoffset)/2; + if (em->collected) - V_DrawSmallMappedPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), + V_DrawSmallMappedPatch(104+76+empatx, yHeight+lsheadingheight/2+empaty, 0, empatch, R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else - V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDITL", PU_CACHE)); skipThisOne: em = M_GetLevelEmblems(-1); } - V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score) sprintf(beststr, "(none)"); else sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); - V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); - V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqscore)); + V_DrawString(104-72, 33+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); + V_DrawRightAlignedString(104+64, 33+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawRightAlignedString(104+72, 43+lsheadingheight/2, V_ALLOWLOWERCASE, reqscore); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) sprintf(beststr, "(none)"); @@ -8801,16 +8812,23 @@ void M_DrawTimeAttackMenu(void) G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); - V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:"); - V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqtime)); + V_DrawString(104-72, 53+lsheadingheight/2, V_YELLOWMAP, "TIME:"); + V_DrawRightAlignedString(104+64, 53+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + V_DrawRightAlignedString(104+72, 63+lsheadingheight/2, V_ALLOWLOWERCASE, reqtime); if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) sprintf(beststr, "(none)"); else sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); - V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqrings)); + V_DrawString(104-72, 73+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); + + if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->gotperfect) + V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); + else + V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|V_YELLOWMAP, beststr); + + V_DrawRightAlignedString(104+72, 83+lsheadingheight/2, V_ALLOWLOWERCASE, reqrings); } // ALWAYS DRAW level and skin even when not on this menu! @@ -8827,10 +8845,6 @@ void M_DrawTimeAttackMenu(void) V_DrawString(x, y + SP_TimeAttackMenu[taplayer].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[taplayer].text); V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), y + SP_TimeAttackMenu[taplayer].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string); } - - // Draw press ESC to exit string on main record attack menu - if (currentMenu == &SP_TimeAttackDef) - V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); } static void M_HandleTimeAttackLevelSelect(INT32 choice) @@ -8985,8 +8999,6 @@ void M_DrawNightsAttackMenu(void) V_DrawSmallScaledPatch(208, 32+lsheadingheight, 0, PictureOfLevel); - V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *"); - // Super Sonic M_DrawNightsAttackSuperSonic(); //if (P_HasGrades(cv_nextmap.value, 0)) @@ -9032,7 +9044,7 @@ void M_DrawNightsAttackMenu(void) } if (em->collected) - V_DrawSmallMappedPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE), + V_DrawSmallMappedPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else V_DrawSmallScaledPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); diff --git a/src/v_video.c b/src/v_video.c index 8f44ca8cd..51c9cf56b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1074,7 +1074,7 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4) { spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[3]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CONTINUE]; patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); diff --git a/src/y_inter.c b/src/y_inter.c index 0d6a3d03c..9eea4837e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1047,6 +1047,9 @@ static void Y_UpdateRecordReplays(void) if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings) mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); + if (data.coop.gotperfbonus) + mainrecords[gamemap-1]->gotperfect = true; + // Save demo! bestdemo[255] = '\0'; lastdemo[255] = '\0'; From 58ef85d5916132ec570eded453b276021a4a385d Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 15 Oct 2019 23:41:01 -0400 Subject: [PATCH 060/130] Make nametag SPR2 frame be the last frame of SPR_XTRA --- src/info.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/info.h b/src/info.h index 38e6276ab..dd94677a7 100644 --- a/src/info.h +++ b/src/info.h @@ -876,6 +876,7 @@ typedef enum playersprite #define XTRA_CHARSEL 1 // Character select picture #define XTRA_CONTINUE 2 // Continue icon #define XTRA_ENDING 3 // Ending finale patches +#define XTRA_NAMETAG 6 // Character select nametag typedef enum state { From 38d044e47584fbcc98d98aec0da4f63dfc6ddd35 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 16 Oct 2019 00:22:05 -0400 Subject: [PATCH 061/130] Seperate name tag sprite into SPR2_NTAG --- src/info.c | 2 ++ src/info.h | 1 + src/m_menu.c | 6 +++--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index dd5338ef0..28cdb6cf2 100644 --- a/src/info.c +++ b/src/info.c @@ -599,6 +599,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "LIFE", "XTRA", + "NTAG", }; playersprite_t free_spr2 = SPR2_FIRSTFREESLOT; @@ -702,6 +703,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { 0, // SPR2_LIFE, 0, // SPR2_XTRA (should never be referenced) + 0, // SPR2_NTAG }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) diff --git a/src/info.h b/src/info.h index dd94677a7..46d57042f 100644 --- a/src/info.h +++ b/src/info.h @@ -865,6 +865,7 @@ typedef enum playersprite SPR2_LIFE, // life monitor icon SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?" + SPR2_NTAG, // Character name tag SPR2_FIRSTFREESLOT, SPR2_LASTFREESLOT = 0x7f, diff --git a/src/m_menu.c b/src/m_menu.c index 2a028834d..f39b0f449 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7938,10 +7938,10 @@ static void M_SetupChoosePlayer(INT32 choice) if (!(description[i].nametag[0]) && (!botskin)) { - if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_NAMETAG+1) + if (skins[skinnum].sprites[SPR2_NTAG].numframes >= 1) { - spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_NAMETAG]; + spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_NTAG]; + spriteframe_t *sprframe = &sprdef->spriteframes[0]; description[i].namepic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); } else From 45e5f70eb8f1e758775c58964f425d12462841b2 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 16 Oct 2019 11:38:09 +0100 Subject: [PATCH 062/130] Merge `retry` and `respawn` into one command, `respawn`. --- src/d_netcmd.c | 20 +++++++++++++++----- src/d_netcmd.h | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b897aafd6..9c25305f7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -454,7 +454,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("map", Command_Map_f); COM_AddCommand("exitgame", Command_ExitGame_f); - COM_AddCommand("retry", Command_Retry_f); + //COM_AddCommand("retry", Command_Retry_f); COM_AddCommand("exitlevel", Command_ExitLevel_f); COM_AddCommand("showmap", Command_Showmap_f); COM_AddCommand("mapmd5", Command_Mapmd5_f); @@ -2034,8 +2034,6 @@ static void Command_Respawn(void) UINT8 buf[4]; UINT8 *cp = buf; - WRITEINT32(cp, consoleplayer); - if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) { CONS_Printf(M_GetText("You must be in a level to use this.\n")); @@ -2048,13 +2046,22 @@ static void Command_Respawn(void) return; } - // Retry is quicker. Probably should force people to use it. + // Retry is quicker. if (!(netgame || multiplayer)) { - CONS_Printf(M_GetText("You can't use this in Single Player! Use \"retry\" instead.\n")); + if (!&players[consoleplayer] || players[consoleplayer].lives <= 1) + CONS_Printf(M_GetText("You can't use this without any lives remaining!\n")); + else if (G_IsSpecialStage(gamemap)) + CONS_Printf(M_GetText("You can't retry special stages!\n")); + else + { + M_ClearMenus(true); + G_SetRetryFlag(); + } return; } + WRITEINT32(cp, consoleplayer); SendNetXCmd(XD_RESPAWN, &buf, 4); } @@ -4119,6 +4126,8 @@ void Command_ExitGame_f(void) D_StartTitle(); } +// see Command_Respawn() +#if 0 void Command_Retry_f(void) { if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) @@ -4135,6 +4144,7 @@ void Command_Retry_f(void) G_SetRetryFlag(); } } +#endif #ifdef NETGAME_DEVMODE // Allow the use of devmode in netgames. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 22e5ffc60..728b27680 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -192,7 +192,7 @@ void D_RegisterServerCommands(void); void D_RegisterClientCommands(void); void D_SendPlayerConfig(void); void Command_ExitGame_f(void); -void Command_Retry_f(void); +//void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); boolean IsPlayerAdmin(INT32 playernum); From 77160ae37bea27185c1f5ad900a81b40806aa87d Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 16 Oct 2019 17:31:10 +0100 Subject: [PATCH 063/130] Just revert the `respawn`, `retry` and `suicide` stuff cuz it's apparently contentious. Who knew? --- src/d_netcmd.c | 43 ++++++++++++++++--------------------------- src/d_netcmd.h | 4 ++-- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9c25305f7..52e2e3271 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -65,7 +65,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); static void Got_Addfilecmd(UINT8 **cp, INT32 playernum); static void Got_Pause(UINT8 **cp, INT32 playernum); -static void Got_Respawn(UINT8 **cp, INT32 playernum); +static void Got_Suicide(UINT8 **cp, INT32 playernum); static void Got_RandomSeed(UINT8 **cp, INT32 playernum); static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum); static void Got_Teamchange(UINT8 **cp, INT32 playernum); @@ -117,7 +117,7 @@ static void Command_Addfile(void); static void Command_ListWADS_f(void); static void Command_RunSOC(void); static void Command_Pause(void); -static void Command_Respawn(void); +static void Command_Suicide(void); static void Command_Version_f(void); #ifdef UPDATE_ALERT @@ -394,7 +394,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "REQADDFILE", "DELFILE", // replace next time we add an XD "SETMOTD", - "RESPAWN", + "SUICIDE", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -429,7 +429,7 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); RegisterNetXCmd(XD_REQADDFILE, Got_RequestAddfilecmd); RegisterNetXCmd(XD_PAUSE, Got_Pause); - RegisterNetXCmd(XD_RESPAWN, Got_Respawn); + RegisterNetXCmd(XD_SUICIDE, Got_Suicide); RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd); #ifdef HAVE_BLUA RegisterNetXCmd(XD_LUACMD, Got_Luacmd); @@ -454,7 +454,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("map", Command_Map_f); COM_AddCommand("exitgame", Command_ExitGame_f); - //COM_AddCommand("retry", Command_Retry_f); + COM_AddCommand("retry", Command_Retry_f); COM_AddCommand("exitlevel", Command_ExitLevel_f); COM_AddCommand("showmap", Command_Showmap_f); COM_AddCommand("mapmd5", Command_Mapmd5_f); @@ -464,7 +464,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("runsoc", Command_RunSOC); COM_AddCommand("pause", Command_Pause); - COM_AddCommand("respawn", Command_Respawn); + COM_AddCommand("suicide", Command_Suicide); COM_AddCommand("gametype", Command_ShowGametype_f); COM_AddCommand("version", Command_Version_f); @@ -2029,7 +2029,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) } // Command for stuck characters in netgames, griefing, etc. -static void Command_Respawn(void) +static void Command_Suicide(void) { UINT8 buf[4]; UINT8 *cp = buf; @@ -2046,33 +2046,25 @@ static void Command_Respawn(void) return; } - // Retry is quicker. + // Retry is quicker. Probably should force people to use it. if (!(netgame || multiplayer)) { - if (!&players[consoleplayer] || players[consoleplayer].lives <= 1) - CONS_Printf(M_GetText("You can't use this without any lives remaining!\n")); - else if (G_IsSpecialStage(gamemap)) - CONS_Printf(M_GetText("You can't retry special stages!\n")); - else - { - M_ClearMenus(true); - G_SetRetryFlag(); - } + CONS_Printf(M_GetText("You can't use this in Single Player! Use \"retry\" instead.\n")); return; } WRITEINT32(cp, consoleplayer); - SendNetXCmd(XD_RESPAWN, &buf, 4); + SendNetXCmd(XD_SUICIDE, &buf, 4); } -static void Got_Respawn(UINT8 **cp, INT32 playernum) +static void Got_Suicide(UINT8 **cp, INT32 playernum) { - INT32 respawnplayer = READINT32(*cp); + INT32 suicideplayer = READINT32(*cp); - // You can't respawn someone else. Nice try, there. + // You can't suicide someone else. Nice try, there. if (respawnplayer != playernum || (!G_PlatformGametype())) { - CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]); + CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); if (server) { UINT8 buf[2]; @@ -2084,8 +2076,8 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum) return; } - if (players[respawnplayer].mo) - P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 1, DMG_INSTAKILL); + if (players[suicideplayer].mo) + P_DamageMobj(players[suicideplayer].mo, NULL, NULL, 1, DMG_INSTAKILL); } /** Deals with an ::XD_RANDOMSEED message in a netgame. @@ -4126,8 +4118,6 @@ void Command_ExitGame_f(void) D_StartTitle(); } -// see Command_Respawn() -#if 0 void Command_Retry_f(void) { if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) @@ -4144,7 +4134,6 @@ void Command_Retry_f(void) G_SetRetryFlag(); } } -#endif #ifdef NETGAME_DEVMODE // Allow the use of devmode in netgames. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 728b27680..3e3c61112 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -136,7 +136,7 @@ typedef enum XD_REQADDFILE, // 17 XD_DELFILE, // 18 - replace next time we add an XD XD_SETMOTD, // 19 - XD_RESPAWN, // 20 + XD_SUICIDE, // 20 XD_DEMOTED, // 21 #ifdef HAVE_BLUA XD_LUACMD, // 22 @@ -192,7 +192,7 @@ void D_RegisterServerCommands(void); void D_RegisterClientCommands(void); void D_SendPlayerConfig(void); void Command_ExitGame_f(void); -//void Command_Retry_f(void); +void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); boolean IsPlayerAdmin(INT32 playernum); From e3e87d7655cd5cf6d1a68b32ed9d244f341bff69 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 16 Oct 2019 17:39:38 +0100 Subject: [PATCH 064/130] Compile fix. --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 52e2e3271..5aea32f8f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2062,7 +2062,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum) INT32 suicideplayer = READINT32(*cp); // You can't suicide someone else. Nice try, there. - if (respawnplayer != playernum || (!G_PlatformGametype())) + if (suicideplayer != playernum || (!G_PlatformGametype())) { CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]); if (server) From 42de16b9042e31775b06362aadda2a6ea8926fd9 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 16 Oct 2019 21:12:04 +0200 Subject: [PATCH 065/130] Make the maces and related objects normally placeable. --- src/info.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/info.c b/src/info.c index dd5338ef0..655664f9b 100644 --- a/src/info.c +++ b/src/info.c @@ -11104,7 +11104,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SMALLMACE - -1, // doomednum + 1130, // doomednum S_SMALLMACE, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11131,7 +11131,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGMACE - -1, // doomednum + 1131, // doomednum S_BIGMACE, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11158,7 +11158,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SMALLGRABCHAIN - -1, // doomednum + 1132, // doomednum S_SMALLGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11185,8 +11185,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGGRABCHAIN - -1, // doomednum - S_BIGGRABCHAIN, // spawnstate + 1133, // doomednum + S_BIGGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -11212,7 +11212,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_YELLOWSPRINGBALL - -1, // doomednum + 1134, // doomednum S_YELLOWSPRINGBALL, // spawnstate 1000, // spawnhealth S_YELLOWSPRINGBALL2, // seestate @@ -11239,7 +11239,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_REDSPRINGBALL - -1, // doomednum + 1135, // doomednum S_REDSPRINGBALL, // spawnstate 1000, // spawnhealth S_REDSPRINGBALL2, // seestate @@ -11266,7 +11266,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SMALLFIREBAR - -1, // doomednum + 1136, // doomednum S_SMALLFIREBAR1, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11293,7 +11293,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGFIREBAR - -1, // doomednum + 1137, // doomednum S_BIGFIREBAR1, // spawnstate 1000, // spawnhealth S_NULL, // seestate From b58b043a5e141d4d093b410d09a62320b3cf26e0 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 16 Oct 2019 21:20:49 +0200 Subject: [PATCH 066/130] Add normally placeable maces to the ZB config. --- extras/conf/SRB2-22.cfg | 60 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index d936721b6..606b8af68 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -2175,7 +2175,7 @@ linedeftypes title = "Award Rings"; prefix = "(460)"; } - + 461 { title = "Spawn Object"; @@ -5038,6 +5038,62 @@ thingtypes width = 8; height = 208; } + 1130 + { + title = "Small Mace"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1131 + { + title = "Big Mace"; + sprite = "BMCEA0"; + width = 34; + height = 68; + } + 1132 + { + title = "Small Grabbable Chain"; + sprite = "SMCHA0"; + width = 17; + height = 34; + } + 1133 + { + title = "Big Grabbable Chain"; + sprite = "BMCHA0"; + width = 17; + height = 34; + } + 1134 + { + title = "Yellow Spring Ball"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1135 + { + title = "Red Spring Ball"; + sprite = "RSPBA0"; + width = 34; + height = 68; + } + 1136 + { + title = "Small Fireball"; + sprite = "SFBRA0"; + width = 17; + height = 34; + } + 1136 + { + title = "Large Fireball"; + sprite = "BFBRA0"; + width = 17; + height = 34; + } } aridcanyon @@ -6416,4 +6472,4 @@ thingsfilters } } -} \ No newline at end of file +} From 124716b8dd79cbfc43e31820fddf6810ac584d8d Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 16 Oct 2019 22:30:52 +0200 Subject: [PATCH 067/130] Correct some ZB config errors & remove grabbable chains. --- extras/conf/SRB2-22.cfg | 112 ++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 63 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 606b8af68..41e8a30ea 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -4141,6 +4141,34 @@ thingtypes angletext = "Retraction interval"; parametertext = "Initial delay"; } + 1130 + { + title = "Small Mace"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1131 + { + title = "Big Mace"; + sprite = "BMCEA0"; + width = 34; + height = 68; + } + 1136 + { + title = "Small Fireball"; + sprite = "SFBRA0"; + width = 17; + height = 34; + } + 1137 + { + title = "Large Fireball"; + sprite = "BFBRA0"; + width = 34; + height = 68; + } } springs @@ -4248,6 +4276,20 @@ thingtypes width = 16; height = 32; } + 1134 + { + title = "Yellow Spring Ball"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1135 + { + title = "Red Spring Ball"; + sprite = "RSPBA0"; + width = 17; + height = 34; + } } patterns @@ -4828,7 +4870,7 @@ thingtypes } 1104 { - title = "Mace"; + title = "Mace Spawnpoint"; sprite = "SMCEA0"; width = 17; height = 34; @@ -4838,7 +4880,7 @@ thingtypes } 1105 { - title = "Chain & Maces"; + title = "Chain with Maces Spawnpoint"; sprite = "SMCEA0"; width = 17; height = 34; @@ -4848,7 +4890,7 @@ thingtypes } 1106 { - title = "Chained Spring"; + title = "Chained Spring Spawnpoint"; sprite = "YSPBA0"; width = 17; height = 34; @@ -4858,7 +4900,7 @@ thingtypes } 1107 { - title = "Chain"; + title = "Chain Spawnpoint"; sprite = "BMCHA0"; width = 17; height = 34; @@ -4868,7 +4910,7 @@ thingtypes 1108 { arrow = 1; - title = "Chain (Hidden)"; + title = "Hidden Chain Spawnpoint"; sprite = "internal:chain3"; width = 17; height = 34; @@ -4876,7 +4918,7 @@ thingtypes } 1109 { - title = "Firebar"; + title = "Firebar Spawnpoint"; sprite = "BFBRA0"; width = 17; height = 34; @@ -4886,7 +4928,7 @@ thingtypes } 1110 { - title = "Custom Mace"; + title = "Custom Mace Spawnpoint"; sprite = "SMCEA0"; width = 17; height = 34; @@ -5038,62 +5080,6 @@ thingtypes width = 8; height = 208; } - 1130 - { - title = "Small Mace"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1131 - { - title = "Big Mace"; - sprite = "BMCEA0"; - width = 34; - height = 68; - } - 1132 - { - title = "Small Grabbable Chain"; - sprite = "SMCHA0"; - width = 17; - height = 34; - } - 1133 - { - title = "Big Grabbable Chain"; - sprite = "BMCHA0"; - width = 17; - height = 34; - } - 1134 - { - title = "Yellow Spring Ball"; - sprite = "YSPBA0"; - width = 17; - height = 34; - } - 1135 - { - title = "Red Spring Ball"; - sprite = "RSPBA0"; - width = 34; - height = 68; - } - 1136 - { - title = "Small Fireball"; - sprite = "SFBRA0"; - width = 17; - height = 34; - } - 1136 - { - title = "Large Fireball"; - sprite = "BFBRA0"; - width = 17; - height = 34; - } } aridcanyon From 2cc129c5c0e1e1dafbbc93fe50a0f19660fa8b13 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 16 Oct 2019 22:31:57 +0200 Subject: [PATCH 068/130] Undo grabbable chains being placeable for now, since they're bugged. --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 655664f9b..33340876e 100644 --- a/src/info.c +++ b/src/info.c @@ -11158,7 +11158,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SMALLGRABCHAIN - 1132, // doomednum + -1, // doomednum S_SMALLGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11185,7 +11185,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGGRABCHAIN - 1133, // doomednum + -1, // doomednum S_BIGGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate From dc0a1899ec00fa3152a4a00290f3ae2f8c72d2f1 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 16 Oct 2019 17:49:21 -0400 Subject: [PATCH 069/130] Fix ifselectvalnextmapnobrace indentation --- src/m_menu.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f39b0f449..c3a09cbed 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4960,33 +4960,31 @@ static void M_HandleLevelPlatter(INT32 choice) if (!(levellistmode == LLM_CREATESERVER && !lsrow)) { ifselectvalnextmapnobrace(lscol) - lsoffs[0] = lsoffs[1] = 0; - S_StartSound(NULL,sfx_menu1); - - if (gamestate == GS_TIMEATTACK) - M_SetupNextMenu(currentMenu->prevMenu); - else if (currentMenu == &MISC_ChangeLevelDef) - { - if (currentMenu->prevMenu && currentMenu->prevMenu != &MPauseDef) + lsoffs[0] = lsoffs[1] = 0; + S_StartSound(NULL,sfx_menu1); + if (gamestate == GS_TIMEATTACK) M_SetupNextMenu(currentMenu->prevMenu); + else if (currentMenu == &MISC_ChangeLevelDef) + { + if (currentMenu->prevMenu && currentMenu->prevMenu != &MPauseDef) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ChangeLevel(0); + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } else - M_ChangeLevel(0); - Z_Free(levelselect.rows); - levelselect.rows = NULL; + M_LevelSelectWarp(0); + Nextmap_OnChange(); } - else - M_LevelSelectWarp(0); - Nextmap_OnChange(); + else if (!lsoffs[0]) // prevent sound spam + { + lsoffs[0] = -8; + S_StartSound(NULL,sfx_s3kb2); + } + break; } - } - else if (!lsoffs[0]) - { - lsoffs[0] = -8; - S_StartSound(NULL,sfx_s3kb2); - } - break; /* FALLTHRU */ - case KEY_RIGHTARROW: if (levellistmode == LLM_CREATESERVER && !lsrow) { @@ -5048,6 +5046,7 @@ static void M_HandleLevelPlatter(INT32 choice) case KEY_ESCAPE: exitmenu = true; break; + default: break; } From edea290b0fff0604fa02c77e2fa07e04bce2dbda Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 16 Oct 2019 18:00:54 -0400 Subject: [PATCH 070/130] Show "Press ESC to exit" string on NiGHTS Attack menu too --- src/m_menu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index c3a09cbed..613f1b65c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9054,6 +9054,10 @@ void M_DrawNightsAttackMenu(void) } } + // Draw press ESC to exit string on main nights attack menu + if (currentMenu == &SP_NightsAttackDef) + V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); + // ALWAYS DRAW level even when not on this menu! if (currentMenu != &SP_NightsAttackDef) V_DrawString(SP_NightsAttackDef.x, SP_NightsAttackDef.y + SP_TimeAttackMenu[nalevel].alphaKey, V_TRANSLUCENT, SP_NightsAttackMenu[nalevel].text); From 28607a81b58b856b09473057c9a14b84a6b9e591 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 16 Oct 2019 18:25:20 -0400 Subject: [PATCH 071/130] Kill off SPR2_NTAG --- src/info.c | 1 - src/info.h | 2 -- src/m_menu.c | 14 +------------- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/info.c b/src/info.c index 28cdb6cf2..930b079e9 100644 --- a/src/info.c +++ b/src/info.c @@ -599,7 +599,6 @@ char spr2names[NUMPLAYERSPRITES][5] = "LIFE", "XTRA", - "NTAG", }; playersprite_t free_spr2 = SPR2_FIRSTFREESLOT; diff --git a/src/info.h b/src/info.h index 46d57042f..38e6276ab 100644 --- a/src/info.h +++ b/src/info.h @@ -865,7 +865,6 @@ typedef enum playersprite SPR2_LIFE, // life monitor icon SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?" - SPR2_NTAG, // Character name tag SPR2_FIRSTFREESLOT, SPR2_LASTFREESLOT = 0x7f, @@ -877,7 +876,6 @@ typedef enum playersprite #define XTRA_CHARSEL 1 // Character select picture #define XTRA_CONTINUE 2 // Continue icon #define XTRA_ENDING 3 // Ending finale patches -#define XTRA_NAMETAG 6 // Character select nametag typedef enum state { diff --git a/src/m_menu.c b/src/m_menu.c index 613f1b65c..bd9aaa092 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7903,7 +7903,6 @@ static void M_SetupChoosePlayer(INT32 choice) { if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. { - char *botskin = strchr(description[i].skinname, '&'); name = strtok(Z_StrDup(description[i].skinname), "&"); skinnum = R_SkinAvailable(name); if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) @@ -7935,18 +7934,7 @@ static void M_SetupChoosePlayer(INT32 choice) else description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE); - if (!(description[i].nametag[0]) && (!botskin)) - { - if (skins[skinnum].sprites[SPR2_NTAG].numframes >= 1) - { - spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_NTAG]; - spriteframe_t *sprframe = &sprdef->spriteframes[0]; - description[i].namepic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); - } - else - description[i].namepic = NULL; - } - else if (description[i].nametag[0]) + if (description[i].nametag[0]) { const char *nametag = description[i].nametag; description[i].namepic = NULL; From 26fed7767138bc6570aceacef5d969061d42a06a Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 17 Oct 2019 01:01:40 +0200 Subject: [PATCH 072/130] Fix standalone hangable chains being broken, thanks to toaster. --- src/info.c | 4 ++-- src/p_user.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index 33340876e..655664f9b 100644 --- a/src/info.c +++ b/src/info.c @@ -11158,7 +11158,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SMALLGRABCHAIN - -1, // doomednum + 1132, // doomednum S_SMALLGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11185,7 +11185,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGGRABCHAIN - -1, // doomednum + 1133, // doomednum S_BIGGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate diff --git a/src/p_user.c b/src/p_user.c index 33f84e2db..a67274d79 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4345,7 +4345,6 @@ void P_DoJump(player_t *player, boolean soundandstate) { player->mo->momz = 9*FRACUNIT; player->powers[pw_carry] = CR_NONE; - player->mo->tracer->flags |= MF_PUSHABLE; P_SetTarget(&player->mo->tracer->target, NULL); P_SetTarget(&player->mo->tracer, NULL); } @@ -12057,7 +12056,7 @@ void P_PlayerAfterThink(player_t *player) mo->momx = rock->momx; mo->momy = rock->momy; mo->momz = 0; - + if (player->panim == PA_IDLE && (mo->momx || mo->momy)) { P_SetPlayerMobjState(player->mo, S_PLAY_WALK); From ad09f2603da9b5ae55e0b0beb6422ebad69f0dc1 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 17 Oct 2019 21:50:26 +0100 Subject: [PATCH 073/130] * New object types! * Red and yellow Boost panels! * Added because SUBARASHII and KIMOKAWAIII had several levels using them, and I wanted to make them look better. * https://cdn.discordapp.com/attachments/359091121789468672/634486669202161674/srb20015.gif * Uses the mapthingnums of Glaber's SOC resource boosters, but absolutely nothing else - not even the magnitudes. * Apply MF_AMBUSH to force the player into a spin - even if they don't have a spin ability! * Banpyura! * A Crushstacean with a spring instead of a crushclaw. * https://cdn.discordapp.com/attachments/428262628893261828/634432099306176512/srb20019.gif * Wanted this for a while, finally added it. * Improved springs. * Add pw_noautobrake to disable autobrake for half a second when touching yellow horizontal springs, and a second when touching red ones, even on the ground. * Add pw_justsprung to disable directionchar for a few tics while touching any springs with a horizontal component to their velocity. * Add the diagonal spring flag options Red and Yellow Diagonal Springs have to the Blue Diagonal Spring as well. * Started but decided against a tip of the hat to the CD spring spin, hidden behind #define SPRINGSPIN. * Make directionchar "lag behind" a little bit in waterslides. * Improved flame jets. * They now use new sprites for having their flames move upwards and sideways, instead of having them always face downwards like in 2.1! * Fixed a mixed declaration and code error in A_RolloutRock. (Sorry Lach!) * Make the Amy Cameo only spawn in SP, Record Attack, or Co-op unless it's the Clone Mode. * Improved ZB config. * Add above new types. * Add Blue Diagonal Spring, which existed in the source but not the config. * Re-order enemies in ZB config by zone (but keep them in the Enemies section only). --- extras/conf/SRB2-22.cfg | 243 +++++++++++++++++++++++----------------- src/d_player.h | 2 + src/dehacked.c | 38 +++++++ src/info.c | 203 ++++++++++++++++++++++++++++++++- src/info.h | 43 +++++++ src/p_enemy.c | 14 +-- src/p_inter.c | 8 ++ src/p_map.c | 56 ++++++++- src/p_mobj.c | 91 ++++++++++++++- src/p_user.c | 29 ++++- src/sounds.c | 2 +- 11 files changed, 601 insertions(+), 128 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index d936721b6..095af340a 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3302,36 +3302,6 @@ thingtypes height = 40; flags8text = "[8] Cannot move"; } - 124 - { - title = "AquaBuzz"; - sprite = "BBUZA1"; - width = 20; - height = 24; - } - 105 - { - title = "Jetty-Syn Bomber"; - sprite = "JETBB1"; - width = 20; - height = 50; - flags8text = "[8] Cannot move"; - } - 106 - { - title = "Jetty-Syn Gunner"; - sprite = "JETGB1"; - width = 20; - height = 48; - flags8text = "[8] Cannot move"; - } - 107 - { - title = "Crawla Commander"; - sprite = "CCOMA1"; - width = 16; - height = 32; - } 108 { title = "Deton"; @@ -3339,13 +3309,6 @@ thingtypes width = 20; height = 32; } - 109 - { - title = "Skim"; - sprite = "SKIMA1"; - width = 16; - height = 24; - } 110 { title = "Turret"; @@ -3361,10 +3324,24 @@ thingtypes height = 64; angletext = "Firing delay"; } - 112 + 122 { - title = "Spincushion"; - sprite = "SHRPA1"; + title = "Spring Shell (Green)"; + sprite = "SSHLA1"; + width = 24; + height = 40; + } + 125 + { + title = "Spring Shell (Yellow)"; + sprite = "SSHLI1"; + width = 24; + height = 40; + } + 109 + { + title = "Skim"; + sprite = "SKIMA1"; width = 16; height = 24; } @@ -3375,26 +3352,21 @@ thingtypes width = 12; height = 20; } - 114 + 126 { - title = "Snailer"; - sprite = "SNLRA3A7"; + title = "Crushstacean"; + sprite = "CRABA0"; width = 24; - height = 48; + height = 32; + flags8text = "[8] Move left from spawn"; } - 115 + 136 { - title = "Bird Aircraft Strike Hazard"; - sprite = "VLTRF1"; - width = 12; - height = 24; - } - 116 - { - title = "Pointy"; - sprite = "PNTYA1"; - width = 8; - height = 16; + title = "Banpyura"; + sprite = "CR2BA0"; + width = 24; + height = 32; + flags8text = "[8] Move left from spawn"; } 117 { @@ -3427,6 +3399,13 @@ thingtypes flags4text = "[4] 90 degrees clockwise"; flags8text = "[8] Double speed"; } + 115 + { + title = "Bird Aircraft Strike Hazard"; + sprite = "VLTRF1"; + width = 12; + height = 24; + } 120 { title = "Green Snapper"; @@ -3441,19 +3420,13 @@ thingtypes width = 24; height = 32; } - 122 + 134 { - title = "Spring Shell (Green)"; - sprite = "SSHLA1"; - width = 24; - height = 40; - } - 125 - { - title = "Spring Shell (Yellow)"; - sprite = "SSHLI1"; - width = 24; - height = 40; + title = "Canarivore"; + sprite = "CANAA0"; + width = 12; + height = 80; + hangs = 1; } 123 { @@ -3462,28 +3435,51 @@ thingtypes width = 18; height = 36; } - 126 + 135 { - title = "Crushstacean"; - sprite = "CRABA0"; - width = 24; - height = 32; - flags8text = "[8] Move left from spawn"; - } - 127 - { - title = "Hive Elemental"; - sprite = "HIVEA0"; - width = 32; - height = 80; - parametertext = "No. bees"; - } - 128 - { - title = "Bumble Bore"; - sprite = "BUMBA1"; + title = "Pterabyte Spawner"; + sprite = "PTERA2A8"; width = 16; - height = 32; + height = 16; + parametertext = "No. Pterabytes"; + } + 136 + { + title = "Pyre Fly"; + sprite = "PYREA0"; + width = 24; + height = 34; + flags8text = "[8] Start on fire"; + } + 105 + { + title = "Jetty-Syn Bomber"; + sprite = "JETBB1"; + width = 20; + height = 50; + flags8text = "[8] Cannot move"; + } + 106 + { + title = "Jetty-Syn Gunner"; + sprite = "JETGB1"; + width = 20; + height = 48; + flags8text = "[8] Cannot move"; + } + 112 + { + title = "Spincushion"; + sprite = "SHRPA1"; + width = 16; + height = 24; + } + 114 + { + title = "Snailer"; + sprite = "SNLRA3A7"; + width = 24; + height = 48; } 129 { @@ -3499,6 +3495,13 @@ thingtypes width = 24; height = 32; } + 107 + { + title = "Crawla Commander"; + sprite = "CCOMA1"; + width = 16; + height = 32; + } 131 { title = "Spinbobert"; @@ -3522,29 +3525,34 @@ thingtypes height = 24; hangs = 1; } - 134 + 127 { - title = "Canarivore"; - sprite = "CANAA0"; - width = 12; + title = "Hive Elemental"; + sprite = "HIVEA0"; + width = 32; height = 80; - hangs = 1; + parametertext = "No. bees"; } - 135 + 128 { - title = "Pterabyte Spawner"; - sprite = "PTERA2A8"; + title = "Bumblebore"; + sprite = "BUMBA1"; width = 16; - height = 16; - parametertext = "No. Pterabytes"; + height = 32; } - 136 + 124 { - title = "Pyre Fly"; - sprite = "PYREA0"; - width = 24; - height = 34; - flags8text = "[8] Start on fire"; + title = "AquaBuzz"; + sprite = "BBUZA1"; + width = 20; + height = 24; + } + 116 + { + title = "Pointy"; + sprite = "PNTYA1"; + width = 8; + height = 16; } } @@ -4218,6 +4226,15 @@ thingtypes flags4text = "[4] Ignore gravity"; flags8text = "[8] Rotate 22.5° CCW"; } + 557 + { + arrow = 1; + title = "Diagonal Blue Spring"; + sprite = "BSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } 558 { arrow = 1; @@ -4248,6 +4265,24 @@ thingtypes width = 16; height = 32; } + 2045 + { + arrow = 1; + title = "Yellow Boost Panel"; + sprite = "BSTYA0"; + flags8text = "[8] Force spin"; + width = 28; + height = 2; + } + 2046 + { + arrow = 1; + title = "Red Boost Panel"; + sprite = "BSTRA0"; + flags8text = "[8] Force spin"; + width = 28; + height = 2; + } } patterns diff --git a/src/d_player.h b/src/d_player.h index ff8c31203..90098917f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -252,6 +252,8 @@ typedef enum pw_spacetime, // In space, no one can hear you spin! pw_extralife, // Extra Life timer pw_pushing, + pw_justsprung, + pw_noautobrake, pw_super, // Are you super? pw_gravityboots, // gravity boots diff --git a/src/dehacked.c b/src/dehacked.c index 8d240326d..b5dabaaf4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4440,6 +4440,21 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CRUSHCLAW_WAIT", "S_CRUSHCHAIN", + // Banpyura + "S_BANPYURA_ROAM1", + "S_BANPYURA_ROAM2", + "S_BANPYURA_ROAM3", + "S_BANPYURA_ROAM4", + "S_BANPYURA_ROAMPAUSE", + "S_CDIAG1", + "S_CDIAG2", + "S_CDIAG3", + "S_CDIAG4", + "S_CDIAG5", + "S_CDIAG6", + "S_CDIAG7", + "S_CDIAG8", + // Jet Jaw "S_JETJAW_ROAM1", "S_JETJAW_ROAM2", @@ -5906,6 +5921,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FLAMEJETFLAME1", "S_FLAMEJETFLAME2", "S_FLAMEJETFLAME3", + "S_FLAMEJETFLAME4", + "S_FLAMEJETFLAME5", + "S_FLAMEJETFLAME6", + "S_FLAMEJETFLAME7", + "S_FLAMEJETFLAME8", + "S_FLAMEJETFLAME9", // Spinning flame jets "S_FJSPINAXISA1", // Counter-clockwise @@ -6660,6 +6681,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BHORIZ7", "S_BHORIZ8", + "S_BOOSTERSOUND", + "S_YELLOWBOOSTERROLLER", + "S_YELLOWBOOSTERSEG_LEFT", + "S_YELLOWBOOSTERSEG_RIGHT", + "S_YELLOWBOOSTERSEG_FACE", + "S_REDBOOSTERROLLER", + "S_REDBOOSTERSEG_LEFT", + "S_REDBOOSTERSEG_RIGHT", + "S_REDBOOSTERSEG_FACE", + // Rain "S_RAIN1", "S_RAINRETURN", @@ -7449,6 +7480,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_REDHORIZ", "MT_BLUEHORIZ", + "MT_BOOSTERSEG", + "MT_BOOSTERROLLER", + "MT_YELLOWBOOSTER", + "MT_REDBOOSTER", + // Interactive Objects "MT_BUBBLES", // Bubble source "MT_SIGN", // Level end sign @@ -8352,6 +8388,8 @@ static const char *const POWERS_LIST[] = { "SPACETIME", // In space, no one can hear you spin! "EXTRALIFE", // Extra Life timer "PUSHING", + "JUSTSPRUNG", + "NOAUTOBRAKE", "SUPER", // Are you super? "GRAVITYBOOTS", // gravity boots diff --git a/src/info.c b/src/info.c index dd5338ef0..9b19cdec3 100644 --- a/src/info.c +++ b/src/info.c @@ -50,6 +50,8 @@ char sprnames[NUMSPRITES + 1][5] = "TURR", // Pop-Up Turret "SHRP", // Sharp "CRAB", // Crushstacean + "CR2B", // Banpyura + "CSPR", // Banpyura spring "JJAW", // Jet Jaw "SNLR", // Snailer "VLTR", // BASH @@ -372,6 +374,8 @@ char sprnames[NUMSPRITES + 1][5] = "SSWY", // Yellow Side Spring "SSWR", // Red Side Spring "SSWB", // Blue Side Spring + "BSTY", // Yellow Booster + "BSTR", // Red Booster // Environmental Effects "RAIN", // Rain @@ -1005,6 +1009,22 @@ state_t states[NUMSTATES] = {SPR_CRAB, 3, 37, {NULL}, 0, 0, S_CRUSHCLAW_AIM}, // S_CRUSHCLAW_WAIT {SPR_CRAB, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CRUSHCHAIN + // Banpyura + {SPR_CR2B, 0, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM2}, // S_BANPYURA_ROAM1 + {SPR_CR2B, 1, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM3}, // S_BANPYURA_ROAM2 + {SPR_CR2B, 0, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM4}, // S_BANPYURA_ROAM3 + {SPR_CR2B, 2, 3, {A_CrushstaceanWalk}, 0, S_BANPYURA_ROAMPAUSE, S_BANPYURA_ROAM1}, // S_BANPYURA_ROAM4 + {SPR_CR2B, 0, 40, {NULL}, 0, 0, S_BANPYURA_ROAM1}, // S_BANPYURA_ROAMPAUSE + + {SPR_CSPR, 0, 1, {A_CrushclawAim}, 50, 20, S_CDIAG1}, // S_CDIAG1 + {SPR_CSPR, 1, 1, {A_Pain}, 0, 0, S_CDIAG3}, // S_CDIAG2 + {SPR_CSPR, 2, 1, {A_CrushclawAim}, 50, 20, S_CDIAG4}, // S_CDIAG3 + {SPR_CSPR, 3, 1, {A_CrushclawAim}, 50, 20, S_CDIAG5}, // S_CDIAG4 + {SPR_CSPR, 4, 1, {A_CrushclawAim}, 50, 20, S_CDIAG6}, // S_CDIAG5 + {SPR_CSPR, 3, 1, {A_CrushclawAim}, 50, 20, S_CDIAG7}, // S_CDIAG6 + {SPR_CSPR, 2, 1, {A_CrushclawAim}, 50, 20, S_CDIAG8}, // S_CDIAG7 + {SPR_CSPR, 1, 1, {A_CrushclawAim}, 50, 20, S_CDIAG1}, // S_CDIAG8 + // Jet Jaw {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM2}, // S_JETJAW_ROAM1 {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM3}, // S_JETJAW_ROAM2 @@ -2508,6 +2528,12 @@ state_t states[NUMSTATES] = {SPR_FLME, FF_FULLBRIGHT , 4, {NULL}, 0, 0, S_FLAMEJETFLAME2}, // S_FLAMEJETFLAME1 {SPR_FLME, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_FLAMEJETFLAME3}, // S_FLAMEJETFLAME2 {SPR_FLME, FF_FULLBRIGHT|2, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME3 + {SPR_FLME, FF_FULLBRIGHT|3, 4, {NULL}, 0, 0, S_FLAMEJETFLAME5}, // S_FLAMEJETFLAME4 + {SPR_FLME, FF_FULLBRIGHT|4, 5, {NULL}, 0, 0, S_FLAMEJETFLAME6}, // S_FLAMEJETFLAME5 + {SPR_FLME, FF_FULLBRIGHT|5, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME6 + {SPR_FLME, FF_FULLBRIGHT|6, 4, {NULL}, 0, 0, S_FLAMEJETFLAME8}, // S_FLAMEJETFLAME7 + {SPR_FLME, FF_FULLBRIGHT|7, 5, {NULL}, 0, 0, S_FLAMEJETFLAME9}, // S_FLAMEJETFLAME8 + {SPR_FLME, FF_FULLBRIGHT|8, 11, {NULL}, 0, 0, S_NULL}, // S_FLAMEJETFLAME9 // Spinning flame jets // A: Counter-clockwise @@ -3272,6 +3298,17 @@ state_t states[NUMSTATES] = {SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ8}, // S_BHORIZ7 {SPR_SSWB, 1, 1, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ8 + // Boosters + {SPR_NULL, 0, 1, {A_Pain}, 0, 0, S_INVISIBLE}, // S_BOOSTERSOUND + {SPR_BSTY, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_YELLOWBOOSTERROLLER + {SPR_BSTY, 3|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_YELLOWBOOSTERSEG_LEFT + {SPR_BSTY, 6|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_YELLOWBOOSTERSEG_RIGHT + {SPR_BSTY, 9|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWBOOSTERSEG_FACE + {SPR_BSTR, FF_ANIMATE, -1, {NULL}, 2, 1, S_NULL}, // S_REDBOOSTERROLLER + {SPR_BSTR, 3|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_REDBOOSTERSEG_LEFT + {SPR_BSTR, 6|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_REDBOOSTERSEG_RIGHT + {SPR_BSTR, 9|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_REDBOOSTERSEG_FACE + // Rain {SPR_RAIN, FF_FULLBRIGHT|FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 {SPR_RAIN, FF_FULLBRIGHT|FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN @@ -4483,7 +4520,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_XPLD1, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 1, // speed + 600, // speed 22*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset @@ -4521,6 +4558,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BANPYURA + 138, // doomednum + S_BANPYURA_ROAM1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 8, // speed + 24*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_BAMPSPRING + -1, // doomednum + S_CDIAG1, // spawnstate + 1, // spawnhealth + S_CDIAG2, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_cdfm08, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD1, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 300, // speed + 22*FRACUNIT, // radius + 22*FRACUNIT, // height + 0, // display offset + 11*FRACUNIT, // mass + 11*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_CDIAG2 // raisestate + }, + { // MT_JETJAW 113, // doomednum S_JETJAW_ROAM1, // spawnstate @@ -7560,12 +7651,120 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 32*FRACUNIT, // height 0, // display offset 0, // mass - 1*FRACUNIT, // damage + 11*FRACUNIT, // damage sfx_None, // activesound MF_SPRING|MF_NOGRAVITY, // flags S_BHORIZ2 // raisestate }, + { // MT_BOOSTERSEG + -1, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 28*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_BOOSTERROLLER + -1, // doomednum + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 14*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_YELLOWBOOSTER + 2045, // doomednum -- Matched to Glaber's resource, otherwise custom-built. + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 3, // painchance + sfx_cdfm62, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 28*FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 0, // mass + 36*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_BOOSTERSOUND // raisestate + }, + + { // MT_REDBOOSTER + 2046, // doomednum -- Matched to Glaber's resource, otherwise custom-built. + S_INVISIBLE, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 3, // painchance + sfx_cdfm62, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 28*FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 0, // mass + 72*FRACUNIT, // damage + sfx_None, // activesound + MF_SPRING|MF_NOGRAVITY, // flags + S_BOOSTERSOUND // raisestate + }, + { // MT_BUBBLES 500, // doomednum S_BUBBLES1, // spawnstate diff --git a/src/info.h b/src/info.h index 0502fd095..b930244fb 100644 --- a/src/info.h +++ b/src/info.h @@ -306,6 +306,8 @@ typedef enum sprite SPR_TURR, // Pop-Up Turret SPR_SHRP, // Sharp SPR_CRAB, // Crushstacean + SPR_CR2B, // Banpyura + SPR_CSPR, // Banpyura spring SPR_JJAW, // Jet Jaw SPR_SNLR, // Snailer SPR_VLTR, // BASH @@ -628,6 +630,8 @@ typedef enum sprite SPR_SSWY, // Yellow Side Spring SPR_SSWR, // Red Side Spring SPR_SSWB, // Blue Side Spring + SPR_BSTY, // Yellow Booster + SPR_BSTR, // Red Booster // Environmental Effects SPR_RAIN, // Rain @@ -1164,6 +1168,21 @@ typedef enum state S_CRUSHCLAW_WAIT, S_CRUSHCHAIN, + // Banpyura + S_BANPYURA_ROAM1, + S_BANPYURA_ROAM2, + S_BANPYURA_ROAM3, + S_BANPYURA_ROAM4, + S_BANPYURA_ROAMPAUSE, + S_CDIAG1, + S_CDIAG2, + S_CDIAG3, + S_CDIAG4, + S_CDIAG5, + S_CDIAG6, + S_CDIAG7, + S_CDIAG8, + // Jet Jaw S_JETJAW_ROAM1, S_JETJAW_ROAM2, @@ -2630,6 +2649,12 @@ typedef enum state S_FLAMEJETFLAME1, S_FLAMEJETFLAME2, S_FLAMEJETFLAME3, + S_FLAMEJETFLAME4, + S_FLAMEJETFLAME5, + S_FLAMEJETFLAME6, + S_FLAMEJETFLAME7, + S_FLAMEJETFLAME8, + S_FLAMEJETFLAME9, // Spinning flame jets S_FJSPINAXISA1, // Counter-clockwise @@ -3384,6 +3409,17 @@ typedef enum state S_BHORIZ7, S_BHORIZ8, + // Booster + S_BOOSTERSOUND, + S_YELLOWBOOSTERROLLER, + S_YELLOWBOOSTERSEG_LEFT, + S_YELLOWBOOSTERSEG_RIGHT, + S_YELLOWBOOSTERSEG_FACE, + S_REDBOOSTERROLLER, + S_REDBOOSTERSEG_LEFT, + S_REDBOOSTERSEG_RIGHT, + S_REDBOOSTERSEG_FACE, + // Rain S_RAIN1, S_RAINRETURN, @@ -4058,6 +4094,8 @@ typedef enum mobj_type MT_CRUSHSTACEAN, // Crushstacean MT_CRUSHCLAW, // Big meaty claw MT_CRUSHCHAIN, // Chain + MT_BANPYURA, // Banpyura + MT_BAMPSPRING, // Banpyura spring MT_JETJAW, // Jet Jaw MT_SNAILER, // Snailer MT_VULTURE, // BASH @@ -4195,6 +4233,11 @@ typedef enum mobj_type MT_REDHORIZ, MT_BLUEHORIZ, + MT_BOOSTERSEG, + MT_BOOSTERROLLER, + MT_YELLOWBOOSTER, + MT_REDBOOSTER, + // Interactive Objects MT_BUBBLES, // Bubble source MT_SIGN, // Level end sign diff --git a/src/p_enemy.c b/src/p_enemy.c index 314e97606..7e3bebc3a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2027,6 +2027,7 @@ void A_CrushstaceanWalk(mobj_t *actor) || (actor->reactiontime-- <= 0)) { actor->flags2 ^= MF2_AMBUSH; + P_SetTarget(&actor->target, NULL); P_SetMobjState(actor, locvar2); actor->reactiontime = actor->info->reactiontime; } @@ -2087,7 +2088,7 @@ void A_CrushclawAim(mobj_t *actor) return; // there is only one step and it is crab } - if (crab->target || P_LookForPlayers(crab, true, false, 600*crab->scale)) + if (crab->target || P_LookForPlayers(crab, true, false, actor->info->speed*crab->scale)) ang = R_PointToAngle2(crab->x, crab->y, crab->target->x, crab->target->y); else ang = crab->angle + ((crab->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270); @@ -14214,18 +14215,17 @@ void A_RolloutRock(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_RolloutRock", actor)) - return; -#endif - UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through fixed_t pi = (22*FRACUNIT/7); fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER); +#ifdef HAVE_BLUA + if (LUA_CallAction("A_RolloutRock", actor)) + return; +#endif + actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves if (actor->threshold) diff --git a/src/p_inter.c b/src/p_inter.c index cce9df91b..f4c92bfc9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2613,6 +2613,14 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } break; + case MT_BANPYURA: + if (target->tracer) + { + S_StopSound(target->tracer); + P_KillMobj(target->tracer, inflictor, source, damagetype); + } + break; + case MT_EGGSHIELD: P_SetObjectMomZ(target, 4*target->scale, false); P_InstaThrust(target, target->angle, 3*target->scale); diff --git a/src/p_map.c b/src/p_map.c index 810d85e34..19ea55192 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -124,6 +124,7 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) // Positive spring modes are minor variants of vanilla spring behaviour. // 1 = launch players in jump // 2 = don't modify player at all, just add momentum +// 3 = speed-booster mode (force onto ground, MF_AMBUSH causes auto-spin) // Negative spring modes are mildly-related gimmicks with customisation. // -1 = pinball bumper // Any other spring mode defaults to standard vanilla spring behaviour, @@ -286,7 +287,27 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->info->painchance != 2) { if (object->player) + { object->player->pflags &= ~PF_APPLYAUTOBRAKE; +#ifndef SPRINGSPIN + object->player->powers[pw_justsprung] = 5; + if (horizspeed) + object->player->powers[pw_noautobrake] = ((horizspeed*TICRATE)>>(FRACBITS+3))/9; // TICRATE at 72*FRACUNIT + else if (P_MobjFlip(object) == P_MobjFlip(spring)) + object->player->powers[pw_justsprung] |= (1<<15); +#else + object->player->powers[pw_justsprung] = 15; + if (horizspeed) + object->player->powers[pw_noautobrake] = ((horizspeed*TICRATE)>>(FRACBITS+3))/9; // TICRATE at 72*FRACUNIT + else + { + if (abs(object->player->rmomx) > object->scale || abs(object->player->rmomy) > object->scale) + object->player->drawangle = R_PointToAngle2(0, 0, object->player->rmomx, object->player->rmomy); + if (P_MobjFlip(object) == P_MobjFlip(spring)) + object->player->powers[pw_justsprung] |= (1<<15); + } +#endif + } if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA { @@ -321,6 +342,14 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) // Set position! P_TryMove(object, spring->x + offx, spring->y + offy, true); + + if ((spring->info->painchance == 3)) + { + object->z = spring->z; + if (spring->eflags & MFE_VERTICALFLIP) + object->z -= object->height; + object->momz = 0; + } } } @@ -344,8 +373,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (horizspeed) { - object->player->drawangle = spring->angle; - object->angle = spring->angle; + object->angle = object->player->drawangle = spring->angle; if (!demoplayback || P_AnalogMove(object->player)) { @@ -356,11 +384,25 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } } - pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these. - secondjump = object->player->secondjump; - washoming = object->player->homing; if (object->player->pflags & PF_GLIDING) P_SetPlayerMobjState(object, S_PLAY_FALL); + if ((spring->info->painchance == 3)) + { + if (!(pflags = (object->player->pflags & PF_SPINNING)) && + (((object->player->charability2 == CA2_SPINDASH) && (object->player->cmd.buttons & BT_USE)) + || (spring->flags2 & MF2_AMBUSH))) + { + pflags = PF_SPINNING; + P_SetPlayerMobjState(object, S_PLAY_ROLL); + S_StartSound(object, sfx_spin); + } + else + P_SetPlayerMobjState(object, S_PLAY_ROLL); + } + else + pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these. + secondjump = object->player->secondjump; + washoming = object->player->homing; P_ResetPlayer(object->player); if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities. @@ -382,6 +424,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->pflags |= pflags; object->player->secondjump = secondjump; } + else if (object->player->dashmode >= 3*TICRATE) + P_SetPlayerMobjState(object, S_PLAY_DASH); + else if (P_IsObjectOnGround(object) && horizspeed >= FixedMul(object->player->runspeed, object->scale)) + P_SetPlayerMobjState(object, S_PLAY_RUN); else P_SetPlayerMobjState(object, S_PLAY_WALK); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 7fa51111d..bf6f6263d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7552,6 +7552,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->fuse -= 2; flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + P_SetMobjState(flame, S_FLAMEJETFLAME4); flame->angle = mobj->angle; @@ -7596,7 +7597,10 @@ void P_MobjThinker(mobj_t *mobj) flame->momz = -strength; } else + { flame->momz = strength; + P_SetMobjState(flame, S_FLAMEJETFLAME7); + } P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT,3*FRACUNIT)); S_StartSound(flame, sfx_fire); } @@ -10283,6 +10287,15 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->reactiontime >>= 1; } break; + case MT_BANPYURA: + { + mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BAMPSPRING); + bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; + P_SetTarget(&mobj->tracer, bigmeatyclaw); + P_SetTarget(&bigmeatyclaw->tracer, mobj); + mobj->reactiontime >>= 1; + } + break; case MT_BIGMINE: mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS; break; @@ -11558,7 +11571,9 @@ You should think about modifying the deathmatch starts to take full advantage of if (i == MT_ROSY) { - if (mariomode) + if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA))) + return; // she doesn't hang out here + else if (mariomode) i = MT_TOAD; // don't remove on penalty of death else if (!(netgame || multiplayer) && players[consoleplayer].skin == 5) return; // no doubles @@ -12484,6 +12499,76 @@ ML_EFFECT5 : Don't stop thinking when too far away } break; } + case MT_REDBOOSTER: + { + angle_t angle = FixedAngle(mthing->angle << FRACBITS); + fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); + + mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); + seg->angle = angle-ANGLE_90; + P_SetMobjState(seg, S_REDBOOSTERSEG_FACE); + seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); + seg->angle = angle+ANGLE_90; + P_SetMobjState(seg, S_REDBOOSTERSEG_FACE); + seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); + seg->angle = angle; + P_SetMobjState(seg, S_REDBOOSTERSEG_LEFT); + seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); + seg->angle = angle; + P_SetMobjState(seg, S_REDBOOSTERSEG_RIGHT); + + seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_REDBOOSTERROLLER); + seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_REDBOOSTERROLLER); + seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_REDBOOSTERROLLER); + seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_REDBOOSTERROLLER); + break; + } + case MT_YELLOWBOOSTER: + { + angle_t angle = FixedAngle(mthing->angle << FRACBITS); + fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); + + mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); + seg->angle = angle-ANGLE_90; + P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE); + seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); + seg->angle = angle+ANGLE_90; + P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE); + seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); + seg->angle = angle; + P_SetMobjState(seg, S_YELLOWBOOSTERSEG_LEFT); + seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); + seg->angle = angle; + P_SetMobjState(seg, S_YELLOWBOOSTERSEG_RIGHT); + + seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); + seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); + seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); + seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); + break; + } default: break; } @@ -12682,7 +12767,7 @@ ML_EFFECT5 : Don't stop thinking when too far away { if (mthing->options & MTF_AMBUSH) { - if (i == MT_YELLOWDIAG || i == MT_REDDIAG) + if (i == MT_YELLOWDIAG || i == MT_REDDIAG || i == MT_BLUEDIAG) mobj->angle += ANGLE_22h; if (i == MT_YELLOWHORIZ || i == MT_REDHORIZ || i == MT_BLUEHORIZ) @@ -12721,7 +12806,7 @@ ML_EFFECT5 : Don't stop thinking when too far away if (mthing->options & MTF_OBJECTSPECIAL) { - if (i == MT_YELLOWDIAG || i == MT_REDDIAG) + if (i == MT_YELLOWDIAG || i == MT_REDDIAG || i == MT_BLUEDIAG) mobj->flags |= MF_NOGRAVITY; if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) diff --git a/src/p_user.c b/src/p_user.c index 33f84e2db..29c01c7a8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11323,6 +11323,13 @@ void P_PlayerThink(player_t *player) break; } } + else if (player->powers[pw_justsprung]) + { +#ifdef SPRINGSPIN + if (player->powers[pw_justsprung] & (1<<15)) + player->drawangle += (player->powers[pw_justsprung] & ~(1<<15))*(ANG2+ANG1); +#endif + } else if ((player->skidtime > (TICRATE/2 - 2) || ((player->pflags & (PF_SPINNING|PF_STARTDASH)) == PF_SPINNING)) && (abs(player->rmomx) > 5*player->mo->scale || abs(player->rmomy) > 5*player->mo->scale)) // spin/skid force player->drawangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); else if (((player->charability2 == CA2_GUNSLINGER || player->charability2 == CA2_MELEE) && player->panim == PA_ABILITY2) || player->pflags & PF_STASIS || player->skidtime) @@ -11335,7 +11342,7 @@ void P_PlayerThink(player_t *player) if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3) { diff = (player->mo->angle - player->drawangle); - factor = 4; + factor = 32; } else { @@ -11344,7 +11351,7 @@ void P_PlayerThink(player_t *player) } #else diff = (player->mo->angle - player->drawangle); - factor = 4; + factor = 32; #endif } else if (player->pflags & PF_STARTDASH) @@ -11379,7 +11386,9 @@ void P_PlayerThink(player_t *player) { boolean currentlyonground = P_IsObjectOnGround(player->mo); - if (!player->powers[pw_carry] && !player->powers[pw_nocontrol] + if (player->powers[pw_noautobrake]) + ; + else if (!player->powers[pw_carry] && !player->powers[pw_nocontrol] && ((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE|PF_STASIS)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) && !(cmd->forwardmove || cmd->sidemove) && (player->rmomx || player->rmomy) @@ -11421,9 +11430,6 @@ void P_PlayerThink(player_t *player) } } - if (player->powers[pw_pushing]) - player->powers[pw_pushing]--; - player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. // Unset statis flags after moving. @@ -11503,6 +11509,17 @@ void P_PlayerThink(player_t *player) if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM) // tails fly counter player->powers[pw_tailsfly]--; + if (player->powers[pw_pushing] && player->powers[pw_pushing] < UINT16_MAX) + player->powers[pw_pushing]--; + + if (player->powers[pw_justsprung] & ((1<<15)-1) && player->powers[pw_justsprung] < UINT16_MAX) + player->powers[pw_justsprung]--; + else + player->powers[pw_justsprung] = 0; + + if (player->powers[pw_pushing] && player->powers[pw_pushing] < UINT16_MAX) + player->powers[pw_pushing]--; + if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER))) { if (player->powers[pw_underwater] <= 12*TICRATE+1) diff --git a/src/sounds.c b/src/sounds.c index e5dfeec8a..8dc97b1e6 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -715,7 +715,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speed boost"}, {"cdfm63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From 8e9ada10935d2bf8c9115e2f8334b520d100790a Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 18 Oct 2019 20:32:35 +0100 Subject: [PATCH 074/130] * Add `MT_BANPYURA` and `MT_BANPSPRING` to `dehacked.c`. * Correct spelling of `MT_BANPSPRING`. --- src/dehacked.c | 2 ++ src/info.c | 2 +- src/info.h | 2 +- src/p_mobj.c | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b5dabaaf4..2de68cfaa 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7343,6 +7343,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_CRUSHSTACEAN", // Crushstacean "MT_CRUSHCLAW", // Big meaty claw "MT_CRUSHCHAIN", // Chain + "MT_BANPYURA", // Banpyura + "MT_BANPSPRING", // Banpyura spring "MT_JETJAW", // Jet Jaw "MT_SNAILER", // Snailer "MT_VULTURE", // BASH diff --git a/src/info.c b/src/info.c index 9b19cdec3..6c3512930 100644 --- a/src/info.c +++ b/src/info.c @@ -4585,7 +4585,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BAMPSPRING + { // MT_BANPSPRING -1, // doomednum S_CDIAG1, // spawnstate 1, // spawnhealth diff --git a/src/info.h b/src/info.h index b930244fb..9711dd548 100644 --- a/src/info.h +++ b/src/info.h @@ -4095,7 +4095,7 @@ typedef enum mobj_type MT_CRUSHCLAW, // Big meaty claw MT_CRUSHCHAIN, // Chain MT_BANPYURA, // Banpyura - MT_BAMPSPRING, // Banpyura spring + MT_BANPSPRING, // Banpyura spring MT_JETJAW, // Jet Jaw MT_SNAILER, // Snailer MT_VULTURE, // BASH diff --git a/src/p_mobj.c b/src/p_mobj.c index bf6f6263d..1cb02aa41 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10289,7 +10289,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_BANPYURA: { - mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BAMPSPRING); + mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING); bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; P_SetTarget(&mobj->tracer, bigmeatyclaw); P_SetTarget(&bigmeatyclaw->tracer, mobj); From f2bbf53c0dece71d7a7e6656a143f6845a18081b Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 19 Oct 2019 14:32:15 +0100 Subject: [PATCH 075/130] Change boost panel thing numbers per MS's request. --- extras/conf/SRB2-22.cfg | 4 ++-- src/info.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 095af340a..2237c35be 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -4265,7 +4265,7 @@ thingtypes width = 16; height = 32; } - 2045 + 544 { arrow = 1; title = "Yellow Boost Panel"; @@ -4274,7 +4274,7 @@ thingtypes width = 28; height = 2; } - 2046 + 545 { arrow = 1; title = "Red Boost Panel"; diff --git a/src/info.c b/src/info.c index 6c3512930..494763dc8 100644 --- a/src/info.c +++ b/src/info.c @@ -7712,7 +7712,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_YELLOWBOOSTER - 2045, // doomednum -- Matched to Glaber's resource, otherwise custom-built. + 544, // doomednum S_INVISIBLE, // spawnstate 1, // spawnhealth S_NULL, // seestate @@ -7739,7 +7739,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_REDBOOSTER - 2046, // doomednum -- Matched to Glaber's resource, otherwise custom-built. + 545, // doomednum S_INVISIBLE, // spawnstate 1, // spawnhealth S_NULL, // seestate From 7f26b90113bc4c145b9371e81bef8fae45682300 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 19 Oct 2019 14:32:34 +0100 Subject: [PATCH 076/130] Decrease drag on directionchar in waterslides on sphere's request. --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 29c01c7a8..bfd4b0bbb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11342,7 +11342,7 @@ void P_PlayerThink(player_t *player) if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3) { diff = (player->mo->angle - player->drawangle); - factor = 32; + factor = 16; } else { @@ -11351,7 +11351,7 @@ void P_PlayerThink(player_t *player) } #else diff = (player->mo->angle - player->drawangle); - factor = 32; + factor = 16; #endif } else if (player->pflags & PF_STARTDASH) From e549de392fd4a37fe4fa8b63624f52148edeb8e8 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 19 Oct 2019 14:46:14 +0100 Subject: [PATCH 077/130] Prevent CA2_MELEE, CA_TWINSPIN and CA_BOUNCE from fucking up boosters. --- src/p_map.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 19ea55192..7267d65ba 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -152,7 +152,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (object->player) { - if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY) + if (spring->info->painchance == 3) + ; + else if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY) strong = 1; else if (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2) strong = 2; @@ -410,7 +412,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->pflags |= P_GetJumpFlags(object->player); P_SetPlayerMobjState(object, S_PLAY_JUMP); } - else if ((spring->info->painchance == 2) || (pflags & PF_BOUNCING)) // Adding momentum only. + else if ((spring->info->painchance == 2) || ((spring->info->painchance != 3) && (pflags & PF_BOUNCING))) // Adding momentum only. { object->player->pflags |= (pflags &~ PF_STARTJUMP); object->player->secondjump = secondjump; From dfd6c5b9d2c993016ae652ac6c76f3824afcd446 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 19 Oct 2019 15:50:06 +0100 Subject: [PATCH 078/130] Fix hw_light.c list (not gonna make an exe for this) --- src/hardware/hw_light.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index f4637ff7f..dc5ef7895 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -162,6 +162,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_TURR &lspr[NOLIGHT], // SPR_SHRP &lspr[NOLIGHT], // SPR_CRAB + &lspr[NOLIGHT], // SPR_CR2B + &lspr[NOLIGHT], // SPR_CSPR &lspr[NOLIGHT], // SPR_JJAW &lspr[NOLIGHT], // SPR_SNLR &lspr[NOLIGHT], // SPR_VLTR @@ -478,6 +480,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_SSWY &lspr[NOLIGHT], // SPR_SSWR &lspr[NOLIGHT], // SPR_SSWB + &lspr[NOLIGHT], // SPR_BSTY + &lspr[NOLIGHT], // SPR_BSTR // Environmental Effects &lspr[NOLIGHT], // SPR_RAIN From 88d239ac36f9d9a64a730a81995cf507a6ecc0ce Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 19 Oct 2019 17:09:18 +0200 Subject: [PATCH 079/130] Set the player's name as soon as they enter the game --- src/d_clisrv.c | 37 +++++++++++++++++++++++++++++-------- src/d_clisrv.h | 2 ++ src/d_netcmd.c | 10 +++++----- src/d_netcmd.h | 1 + 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3234bc756..922079849 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1253,7 +1253,8 @@ static boolean CL_SendJoin(void) netbuffer->u.clientcfg.localplayers = localplayers; netbuffer->u.clientcfg.version = VERSION; netbuffer->u.clientcfg.subversion = SUBVERSION; - + strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); + strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); } @@ -3199,6 +3200,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (!splitscreen && !botingame) CL_ClearPlayer(newplayernum); playeringame[newplayernum] = true; + READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME); G_AddPlayer(newplayernum); if (newplayernum+1 > doomcom->numslots) doomcom->numslots = (INT16)(newplayernum+1); @@ -3231,10 +3233,10 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) { const char *address; if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL) - HU_AddChatText(va("\x82*Player %d has joined the game (node %d) (%s)", newplayernum+1, node, address), false); // merge join notification + IP to avoid clogging console/chat. + HU_AddChatText(va("\x82*%s has joined the game (node %d) (%s)", player_names[newplayernum], node, address), false); // merge join notification + IP to avoid clogging console/chat. } else - HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false); // if you don't wanna see the join address. + HU_AddChatText(va("\x82*%s has joined the game (node %d)", player_names[newplayernum], node), false); // if you don't wanna see the join address. } if (server && multiplayer && motd[0] != '\0') @@ -3245,10 +3247,11 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) #endif } -static boolean SV_AddWaitingPlayers(void) +static boolean SV_AddWaitingPlayers(const char *name, const char *name2) { INT32 node, n, newplayer = false; - UINT8 buf[2]; + UINT8 buf[2 + MAXPLAYERNAME]; + UINT8 *p; UINT8 newplayernum = 0; // What is the reason for this? Why can't newplayernum always be 0? @@ -3331,18 +3334,23 @@ static boolean SV_AddWaitingPlayers(void) playernode[newplayernum] = (UINT8)node; + p = buf + 2; buf[0] = (UINT8)node; buf[1] = newplayernum; if (playerpernode[node] < 1) + { nodetoplayer[node] = newplayernum; + WRITESTRINGN(p, name, MAXPLAYERNAME); + } else { nodetoplayer2[node] = newplayernum; buf[1] |= 0x80; + WRITESTRINGN(p, name2, MAXPLAYERNAME); } playerpernode[node]++; - SendNetXCmd(XD_ADDPLAYER, &buf, 2); + SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); // use the next free slot (we can't put playeringame[newplayernum] = true here) @@ -3404,7 +3412,7 @@ boolean SV_SpawnServer(void) else doomcom->numslots = 1; } - return SV_AddWaitingPlayers(); + return SV_AddWaitingPlayers(cv_playername.zstring, cv_playername2.zstring); } void SV_StopServer(void) @@ -3475,6 +3483,9 @@ static size_t TotalTextCmdPerTic(tic_t tic) */ static void HandleConnect(SINT8 node) { + char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; + INT32 i; + if (bannednode && bannednode[node]) SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); else if (netbuffer->u.clientcfg.version != VERSION @@ -3494,6 +3505,16 @@ static void HandleConnect(SINT8 node) boolean newnode = false; #endif + for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++) + { + strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); + if (!EnsurePlayerNameIsGood(names[i], -1)) + { + SV_SendRefuse(node, "Bad player name"); + return; + } + } + // client authorised to join nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); if (!nodeingame[node]) @@ -3534,7 +3555,7 @@ static void HandleConnect(SINT8 node) SV_SendSaveGame(node); // send a complete game state DEBFILE("send savegame\n"); } - SV_AddWaitingPlayers(); + SV_AddWaitingPlayers(names[0], names[1]); player_joining = true; } #else diff --git a/src/d_clisrv.h b/src/d_clisrv.h index d09d2aa48..38556bac5 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -15,6 +15,7 @@ #include "d_ticcmd.h" #include "d_netcmd.h" +#include "d_net.h" #include "tables.h" #include "d_player.h" @@ -322,6 +323,7 @@ typedef struct UINT8 subversion; // Contains build version UINT8 localplayers; UINT8 mode; + char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; } ATTRPACK clientconfig_pak; #define MAXSERVERNAME 32 diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1e69d371e..a983d9df5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -879,7 +879,7 @@ void D_RegisterClientCommands(void) * \sa CleanupPlayerName, SetPlayerName, Got_NameAndColor * \author Graue */ -static boolean IsNameGood(char *name, INT32 playernum) +boolean EnsurePlayerNameIsGood(char *name, INT32 playernum) { INT32 ix; @@ -920,14 +920,14 @@ static boolean IsNameGood(char *name, INT32 playernum) if (len > 1) { name[len-1] = '\0'; - if (!IsNameGood (name, playernum)) + if (!EnsurePlayerNameIsGood (name, playernum)) return false; } else if (len == 1) // Agh! { // Last ditch effort... sprintf(name, "%d", M_RandomKey(10)); - if (!IsNameGood (name, playernum)) + if (!EnsurePlayerNameIsGood (name, playernum)) return false; } else @@ -1056,12 +1056,12 @@ static void CleanupPlayerName(INT32 playernum, const char *newname) * \param newname New name for that player. Should be good, but won't * necessarily be if the client is maliciously modified or * buggy. - * \sa CleanupPlayerName, IsNameGood + * \sa CleanupPlayerName, EnsurePlayerNameIsGood * \author Graue */ static void SetPlayerName(INT32 playernum, char *newname) { - if (IsNameGood(newname, playernum)) + if (EnsurePlayerNameIsGood(newname, playernum)) { if (strcasecmp(newname, player_names[playernum]) != 0) { diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 5076c8afa..be861e944 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -190,6 +190,7 @@ typedef union { // add game commands, needs cleanup void D_RegisterServerCommands(void); void D_RegisterClientCommands(void); +boolean EnsurePlayerNameIsGood(char *name, INT32 playernum); void D_SendPlayerConfig(void); void Command_ExitGame_f(void); void Command_Retry_f(void); From bf761a26d662cc6d962fda0f4e38ebcfc29f68f0 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 19 Oct 2019 18:15:54 +0100 Subject: [PATCH 080/130] * Implement fixes/tweaks as written on the gitlab. * `SPR2_NTAG` last vestiges removal. * Removed need for `getskinfromdescription()` by calculating it once, at Menu load, and storing in `description_t`. * Fixed nametag colour issues. * Support widescreen with nametags. * Fix a metric SHITTON of compiler errors. * Redefining `x` and `y` within scope of previous `x` and `y` (`M_DrawSetupChoosePlayerMenu`) * GCC straight up will not let you cast a `const char*` to a `char` (`V_DrawNameTag`) * Redefining `lines` within the scope of the global. * Redefining `string` within the function-specific `string`. * It would be recommended for y'alls to turn ERRORMODE on! --- src/info.c | 1 - src/m_menu.c | 233 +++++++++++++++++++++----------------------------- src/m_menu.h | 1 + src/v_video.c | 46 +++++----- 4 files changed, 121 insertions(+), 160 deletions(-) diff --git a/src/info.c b/src/info.c index 930b079e9..dd5338ef0 100644 --- a/src/info.c +++ b/src/info.c @@ -702,7 +702,6 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { 0, // SPR2_LIFE, 0, // SPR2_XTRA (should never be referenced) - 0, // SPR2_NTAG }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) diff --git a/src/m_menu.c b/src/m_menu.c index bd9aaa092..feb0f1b84 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7894,7 +7894,7 @@ static void M_SetupChoosePlayer(INT32 choice) UINT8 firstvalid = 255; UINT8 lastvalid = 0; boolean allowed = false; - char *name; + char *and; (void)choice; SP_PlayerMenu[0].status &= ~IT_DYBIGSPACE; // Correcting a hack that may be made below. @@ -7903,8 +7903,21 @@ static void M_SetupChoosePlayer(INT32 choice) { if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it. { - name = strtok(Z_StrDup(description[i].skinname), "&"); - skinnum = R_SkinAvailable(name); + and = strchr(description[i].skinname, '&'); + if (and) + { + char firstskin[SKINNAMESIZE+1]; + strncpy(firstskin, description[i].skinname, (and - description[i].skinname)); + firstskin[(and - description[i].skinname)] = '\0'; + description[i].skinnum[0] = R_SkinAvailable(firstskin); + description[i].skinnum[1] = R_SkinAvailable(and+1); + } + else + { + description[i].skinnum[0] = R_SkinAvailable(description[i].skinname); + description[i].skinnum[1] = -1; + } + skinnum = description[i].skinnum[0]; if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) { // Handling order. @@ -7943,7 +7956,6 @@ static void M_SetupChoosePlayer(INT32 choice) } } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. - Z_Free(name); } } @@ -8060,18 +8072,6 @@ static void M_HandleChoosePlayerMenu(INT32 choice) // Draw the choose player setup menu, had some fun with player anim //define CHOOSEPLAYER_DRAWHEADER -static INT32 getskinfromdescription(INT32 desc) -{ - char *and = strchr(description[desc].skinname, '&'); - if (and) - { - char firstskin[SKINNAMESIZE]; - strncpy(firstskin, description[desc].skinname, and - (description[desc].skinname)); - return R_SkinAvailable(firstskin); - } - return R_SkinAvailable(description[desc].skinname); -} - static void M_DrawSetupChoosePlayerMenu(void) { const INT32 my = 16; @@ -8088,7 +8088,8 @@ static void M_DrawSetupChoosePlayerMenu(void) INT16 fgheight = SHORT(charfg->height); INT16 bgwidth = SHORT(charbg->width); INT16 fgwidth = SHORT(charfg->width); - INT32 y; + INT32 x, y; + INT32 w = (vid.width/vid.dupx); if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); @@ -8106,9 +8107,8 @@ static void M_DrawSetupChoosePlayerMenu(void) prev = -1; // Find skin number from description[] - skinnum = getskinfromdescription(char_on); - if (skinnum != -1) - charskin = &skins[skinnum]; + skinnum = description[char_on].skinnum[0]; + charskin = &skins[skinnum]; // Use the opposite of the character's skincolor col = description[char_on].oppositecolor; @@ -8116,7 +8116,7 @@ static void M_DrawSetupChoosePlayerMenu(void) col = Color_Opposite[charskin->prefcolor - 1][0]; // Make the translation colormap - colormap = R_GetTranslationColormap(skinnum, col, 0); + colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0); // Don't render the title map hidetitlemap = true; @@ -8142,8 +8142,8 @@ static void M_DrawSetupChoosePlayerMenu(void) // Character pictures { - INT32 x = 8; - INT32 y = (my+16) - FixedInt(char_scroll); + x = 8; + y = (my+16) - FixedInt(char_scroll); V_DrawScaledPatch(x, y, 0, description[char_on].charpic); if (prev != -1) V_DrawScaledPatch(x, y - 144, 0, description[prev].charpic); @@ -8153,16 +8153,15 @@ static void M_DrawSetupChoosePlayerMenu(void) // Character description { - INT32 x = 146; - INT32 y = my + 9; INT32 flags = V_ALLOWLOWERCASE|V_RETURN8; + x = 146; + y = my + 9; V_DrawString(x, y, flags, char_notes); } // Name tags { - INT32 ox, x, y; - INT32 oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; + INT32 ox, oxsh = FixedInt(FixedMul(BASEVIDWIDTH*FRACUNIT, FixedDiv(char_scroll, 128*FRACUNIT))), txsh; patch_t *curpatch = NULL, *prevpatch = NULL, *nextpatch = NULL; const char *curtext = NULL, *prevtext = NULL, *nexttext = NULL; UINT8 curtextcolor = 0, prevtextcolor = 0, nexttextcolor = 0; @@ -8174,75 +8173,60 @@ static void M_DrawSetupChoosePlayerMenu(void) curoutlinecolor = description[char_on].tagoutlinecolor; if (curtext[0] == '\0') curpatch = description[char_on].namepic; - if (skinnum != -1) - { - if (!curtextcolor) - curtextcolor = charskin->prefcolor; - if (!curoutlinecolor) - curoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; - } - - // previous character - if (prev != -1) - { - prevtext = description[prev].displayname; - prevtextcolor = description[prev].tagtextcolor; - prevoutlinecolor = description[prev].tagoutlinecolor; - if (prevtext[0] == '\0') - prevpatch = description[prev].namepic; - // Find skin number from description[] - skinnum = getskinfromdescription(prev); - if (skinnum != -1) - { - charskin = &skins[skinnum]; - if (!prevtextcolor) - prevtextcolor = charskin->prefcolor; - if (!prevoutlinecolor) - prevoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; - } - } - - // next character - if (next != -1) - { - nexttext = description[next].displayname; - nexttextcolor = description[next].tagtextcolor; - nextoutlinecolor = description[next].tagoutlinecolor; - if (nexttext[0] == '\0') - nextpatch = description[next].namepic; - // Find skin number from description[] - skinnum = getskinfromdescription(next); - if (skinnum != -1) - { - charskin = &skins[skinnum]; - if (!nexttextcolor) - nexttextcolor = charskin->prefcolor; - if (!nextoutlinecolor) - nextoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; - } - } + if (!curtextcolor) + curtextcolor = charskin->prefcolor; + if (!curoutlinecolor) + curoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; txsh = oxsh; ox = 8 + SHORT((description[char_on].charpic)->width)/2; y = my + 144; + // cur + { + x = ox - txsh; + if (curpatch) + x -= (SHORT(curpatch->width)/2); + + if (curtext[0] != '\0') + { + V_DrawNameTag( + x, y, V_CENTERNAMETAG, FRACUNIT, + R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0), + R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0), + curtext + ); + } + else if (curpatch) + V_DrawScaledPatch(x, y, 0, curpatch); + } + if (char_scroll) { // prev if ((prev != -1) && char_scroll < 0) { - INT32 ox2 = ox; + prevtext = description[prev].displayname; + prevtextcolor = description[prev].tagtextcolor; + prevoutlinecolor = description[prev].tagoutlinecolor; + if (prevtext[0] == '\0') + prevpatch = description[prev].namepic; + charskin = &skins[description[prev].skinnum[0]]; + if (!prevtextcolor) + prevtextcolor = charskin->prefcolor; + if (!prevoutlinecolor) + prevoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; + + x = (ox - txsh) - w; if (prevpatch) - ox2 -= (SHORT(prevpatch->width)/2); - // Why does this work? - x = (ox2 - txsh) - BASEVIDWIDTH; + x -= (SHORT(prevpatch->width)/2); + if (prevtext[0] != '\0') { - skinnum = getskinfromdescription(prev); V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(skinnum, prevtextcolor, 0), - R_GetTranslationColormap(skinnum, prevoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0), + R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0), prevtext ); } @@ -8252,47 +8236,33 @@ static void M_DrawSetupChoosePlayerMenu(void) // next else if ((next != -1) && char_scroll > 0) { - INT32 ox2 = ox; - if (nextpatch) - ox2 -= (SHORT(nextpatch->width)/2); - x = (ox2 - txsh) + BASEVIDWIDTH; - if (x < BASEVIDWIDTH) - { - if (nexttext[0] != '\0') - { - skinnum = getskinfromdescription(next); - V_DrawNameTag( - x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(skinnum, nexttextcolor, 0), - R_GetTranslationColormap(skinnum, nextoutlinecolor, 0), - nexttext - ); - } - else if (nextpatch) - V_DrawScaledPatch(x, y, 0, nextpatch); - } - } - } + nexttext = description[next].displayname; + nexttextcolor = description[next].tagtextcolor; + nextoutlinecolor = description[next].tagoutlinecolor; + if (nexttext[0] == '\0') + nextpatch = description[next].namepic; + charskin = &skins[description[next].skinnum[0]]; + if (!nexttextcolor) + nexttextcolor = charskin->prefcolor; + if (!nextoutlinecolor) + nextoutlinecolor = Color_Opposite[charskin->prefcolor - 1][0]; - // cur - skinnum = getskinfromdescription(next); - if (skinnum != -1) - { - INT32 ox2 = ox; - if (curpatch) - ox2 -= (SHORT(curpatch->width)/2); - x = ox2 - txsh; - if (curtext[0] != '\0') - { - V_DrawNameTag( - x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(skinnum, curtextcolor, 0), - R_GetTranslationColormap(skinnum, curoutlinecolor, 0), - curtext - ); + x = (ox - txsh) + w; + if (nextpatch) + x -= (SHORT(nextpatch->width)/2); + + if (nexttext[0] != '\0') + { + V_DrawNameTag( + x, y, V_CENTERNAMETAG, FRACUNIT, + R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0), + R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0), + nexttext + ); + } + else if (nextpatch) + V_DrawScaledPatch(x, y, 0, nextpatch); } - else if (curpatch) - V_DrawScaledPatch(x, y, 0, curpatch); } } @@ -8312,8 +8282,6 @@ static void M_DrawSetupChoosePlayerMenu(void) // Chose the player you want to use Tails 03-02-2002 static void M_ChoosePlayer(INT32 choice) { - char *skin1,*skin2; - INT32 skinnum; boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); // skip this if forcecharacter or no characters available @@ -8327,21 +8295,14 @@ static void M_ChoosePlayer(INT32 choice) } M_ClearMenus(true); - skin1 = strtok(description[choice].skinname, "&"); - skin2 = strtok(NULL, "&"); - - if (skin2) { + if (description[choice].skinnum[1] != -1) { // this character has a second skin - skinnum = R_SkinAvailable(skin1); - botskin = (UINT8)(R_SkinAvailable(skin2)+1); botingame = true; - - botcolor = skins[botskin-1].prefcolor; - - // undo the strtok - description[choice].skinname[strlen(skin1)] = '&'; - } else { - skinnum = R_SkinAvailable(description[choice].skinname); + botskin = (UINT8)(description[choice].skinnum[1]+1); + botcolor = skins[description[choice].skinnum[1]].prefcolor; + } + else + { botingame = false; botskin = 0; botcolor = 0; @@ -8353,7 +8314,7 @@ static void M_ChoosePlayer(INT32 choice) //lastmapsaved = 0; gamecomplete = false; - G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)skinnum, false, fromlevelselect); + G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)description[choice].skinnum[0], false, fromlevelselect); COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this if (levelselect.rows) diff --git a/src/m_menu.h b/src/m_menu.h index ad29cf2e7..7099df8d2 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -329,6 +329,7 @@ typedef struct // new character select char displayname[SKINNAMESIZE+1]; + SINT8 skinnum[2]; UINT8 oppositecolor; char nametag[8]; patch_t *namepic; diff --git a/src/v_video.c b/src/v_video.c index 51c9cf56b..34d64cb04 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2698,16 +2698,16 @@ static void V_DrawNameTagLine(INT32 x, INT32 y, INT32 option, fixed_t scale, UIN // Looks familiar. void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecolormap, UINT8 *outlinecolormap, const char *string) { - char *text = (char *)string; - char *first_token = text; + const char *text = string; + const char *first_token = text; char *last_token = strchr(text, '\n'); const INT32 lbreakheight = 21; - INT32 lines; + INT32 ntlines; if (option & V_CENTERNAMETAG) { - lines = V_CountNameTagLines(string); - y -= FixedInt(FixedMul(((lbreakheight/2) * (lines-1))*FRACUNIT, scale)); + ntlines = V_CountNameTagLines(string); + y -= FixedInt(FixedMul(((lbreakheight/2) * (ntlines-1))*FRACUNIT, scale)); } // No line breaks? @@ -2717,7 +2717,7 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecol // Split string by the line break character else { - char *string = NULL; + char *str = NULL; INT32 len; while (true) { @@ -2726,20 +2726,20 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecol { size_t shift = 0; // Free this line - if (string) - Z_Free(string); + if (str) + Z_Free(str); // Find string length, do a malloc... len = (last_token-first_token)+1; - string = ZZ_Alloc(len); + str = ZZ_Alloc(len); // Copy the line - strncpy(string, first_token, len-1); - string[len-1] = '\0'; + strncpy(str, first_token, len-1); + str[len-1] = '\0'; // Don't leave a line break character // at the start of the string! - if ((strlen(string) >= 2) && (string[0] == '\n') && (string[1] != '\n')) + if ((strlen(str) >= 2) && (string[0] == '\n') && (string[1] != '\n')) shift++; // Then draw it - V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, string+shift); + V_DrawNameTagLine(x, y, option, scale, basecolormap, outlinecolormap, str+shift); } // No line break character was found else @@ -2755,7 +2755,7 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecol // Next line y += FixedInt(FixedMul(lbreakheight*FRACUNIT, scale)); - if ((last_token-text)+1 >= strlen(text)) + if ((last_token-text)+1 >= (signed)strlen(text)) last_token = NULL; else { @@ -2764,35 +2764,35 @@ void V_DrawNameTag(INT32 x, INT32 y, INT32 option, fixed_t scale, UINT8 *basecol } } // Free this line - if (string) - Z_Free(string); + if (str) + Z_Free(str); } } // Count the amount of lines in name tag string INT32 V_CountNameTagLines(const char *string) { - INT32 lines = 1; - char *text = (char *)string; - char *first_token = text; + INT32 ntlines = 1; + const char *text = string; + const char *first_token = text; char *last_token = strchr(text, '\n'); // No line breaks? if (!last_token) - return lines; + return ntlines; // Split string by the line break character else { while (true) { if (last_token) - lines++; + ntlines++; // No line break character was found else break; // Next line - if ((last_token-text)+1 >= strlen(text)) + if ((last_token-text)+1 >= (signed)strlen(text)) last_token = NULL; else { @@ -2801,7 +2801,7 @@ INT32 V_CountNameTagLines(const char *string) } } } - return lines; + return ntlines; } INT32 V_NameTagWidth(const char *string) From c8629c2aab0d70598aba3e62877e6754480ab811 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 19 Oct 2019 18:16:52 +0100 Subject: [PATCH 081/130] Adjust hardcoded skin numbers for character-related events, to fit with the re-ordered skins. --- src/p_mobj.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7fa51111d..c3c7a23b9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7735,7 +7735,7 @@ void P_MobjThinker(mobj_t *mobj) actualwork = work = FixedHypot(mobj->x-players[i].mo->x, mobj->y-players[i].mo->y); if (player) { - if (players[i].skin == 0 || players[i].skin == 3) + if (players[i].skin == 0 || players[i].skin == 5) work = (2*work)/3; if (work >= pdist) continue; @@ -7773,7 +7773,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->target != player->mo) P_SetTarget(&mobj->target, player->mo); targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN)); - love = (player->skin == 0 || player->skin == 3); + love = (player->skin == 0 || player->skin == 5); switch (stat) { @@ -10366,13 +10366,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_METALSONIC_BATTLE: case MT_METALSONIC_RACE: - sc = 3; + sc = 5; break; case MT_FANG: sc = 4; break; case MT_ROSY: - sc = 5; + sc = 3; break; case MT_CORK: mobj->flags2 |= MF2_SUPERFIRE; @@ -11560,7 +11560,7 @@ You should think about modifying the deathmatch starts to take full advantage of { if (mariomode) i = MT_TOAD; // don't remove on penalty of death - else if (!(netgame || multiplayer) && players[consoleplayer].skin == 5) + else if (!(netgame || multiplayer) && players[consoleplayer].skin == 3) return; // no doubles } From 3e0a9cf742cf707da57e4f56c0c0e67cf9b71096 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 19 Oct 2019 14:36:30 -0400 Subject: [PATCH 082/130] Revert my old attempt of making the level music fade out before game over jingle --- src/g_game.h | 3 --- src/m_menu.c | 2 +- src/p_inter.c | 2 +- src/p_setup.c | 6 ------ src/p_tick.c | 2 -- 5 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/g_game.h b/src/g_game.h index bebfaf514..df1301dd7 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -31,9 +31,6 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern player_t players[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS]; -extern INT32 fadetogameovermus; -extern boolean gameovermus; - // ====================================== // DEMO playback/recording related stuff. // ====================================== diff --git a/src/m_menu.c b/src/m_menu.c index feb0f1b84..9132c8d7d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8267,7 +8267,7 @@ static void M_DrawSetupChoosePlayerMenu(void) } // Alternative menu header -#ifdef CHOOSEPLAYER_DRAWHEADER // +#ifdef CHOOSEPLAYER_DRAWHEADER { patch_t *header = W_CachePatchName("M_PICKP", PU_CACHE); INT32 xtitle = 146; diff --git a/src/p_inter.c b/src/p_inter.c index c94a0b7f9..cce9df91b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2477,7 +2477,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { - gameovermus = false; + boolean gameovermus = false; if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1)) { INT32 i; diff --git a/src/p_setup.c b/src/p_setup.c index 23794a869..519226a3d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -81,10 +81,6 @@ #include "p_slopes.h" #endif -// Game over stuff -boolean gameovermus; -INT32 fadetogameovermus; - // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -2610,8 +2606,6 @@ boolean P_SetupLevel(boolean skipprecip) boolean loadedbm = false; sector_t *ss; boolean chase; - gameovermus = false; - fadetogameovermus = 0; levelloading = true; // This is needed. Don't touch. diff --git a/src/p_tick.c b/src/p_tick.c index 0a14d5fbd..6b5c7980c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -24,8 +24,6 @@ // Object place #include "m_cheat.h" -boolean gameovermus; -INT32 fadetogameovermus; tic_t leveltime; From 25d8b7d5eae35555360c927a61b3848acd4fd1bc Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 19 Oct 2019 12:25:02 -0700 Subject: [PATCH 083/130] Don't fade to Server Options --- src/m_menu.c | 6 ++++++ src/m_menu.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 9132c8d7d..a64c3c70f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9820,6 +9820,12 @@ static void M_ServerOptions(INT32 choice) } #endif + /* Disable fading because of different menu head. */ + if (currentMenu == &OP_MainDef)/* from Options menu */ + OP_ServerOptionsDef.menuid = MN_OP_MAIN + ( MN_OP_SERVER << 6 ); + else/* from Multiplayer menu */ + OP_ServerOptionsDef.menuid = MN_MP_MAIN + ( MN_MP_SERVER_OPTIONS << 6 ); + OP_ServerOptionsDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_ServerOptionsDef); } diff --git a/src/m_menu.h b/src/m_menu.h index 7099df8d2..ba545771e 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -63,6 +63,7 @@ typedef enum MN_MP_CONNECT, MN_MP_ROOM, MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + MN_MP_SERVER_OPTIONS, // Options MN_OP_MAIN, From dfdbc0afe3ad92e116f494b663afab07b73f8192 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 19 Oct 2019 12:42:53 -0700 Subject: [PATCH 084/130] Don't fade to character select from secret level select --- src/m_menu.c | 15 +++++++++++++++ src/m_menu.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index a64c3c70f..c09538f1a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7977,6 +7977,21 @@ static void M_SetupChoosePlayer(INT32 choice) M_ChangeMenuMusic("_chsel", true); + /* the menus suck -James */ + if (currentMenu == &SP_LoadDef)/* from save states */ + { + SP_PlayerDef.menuid = + MN_SP_MAIN + + ( MN_SP_LOAD << 6 ) + + ( MN_SP_PLAYER << 12 ); + } + else/* from Secret level select */ + { + SP_PlayerDef.menuid = + MN_SR_MAIN + + ( MN_SR_PLAYER << 6 ); + } + SP_PlayerDef.prevMenu = currentMenu; M_SetupNextMenu(&SP_PlayerDef); if (!allowed) diff --git a/src/m_menu.h b/src/m_menu.h index ba545771e..14b3e0902 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -104,6 +104,7 @@ typedef enum MN_SR_LEVELSELECT, MN_SR_UNLOCKCHECKLIST, MN_SR_EMBLEMHINT, + MN_SR_PLAYER, // Addons (Part of MISC, but let's make it our own) MN_AD_MAIN, From 4a15e2d1d811ce470b5582d07f9e3fd58d5f7724 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 19 Oct 2019 13:01:06 -0700 Subject: [PATCH 085/130] Fix "You must specify an IP address" message returning to title instead of MP menu --- src/m_menu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index c09538f1a..f08182147 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9905,6 +9905,8 @@ static void M_ConnectIP(INT32 choice) return; } + M_ClearMenus(true); + COM_BufAddText(va("connect \"%s\"\n", setupm_ip)); // A little "please wait" message. @@ -9936,7 +9938,6 @@ static void M_HandleConnectIP(INT32 choice) case KEY_ENTER: S_StartSound(NULL,sfx_menu1); // Tails - M_ClearMenus(true); M_ConnectIP(1); break; From fc97ccd7d4dc35d7ae97f181ac0813ff9ddc5e78 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 19 Oct 2019 13:07:20 -0700 Subject: [PATCH 086/130] Fix item selection not returning to "Specify IPv4 Address" --- src/m_menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menu.c b/src/m_menu.c index f08182147..55b68e1c8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9987,6 +9987,7 @@ static void M_HandleConnectIP(INT32 choice) if (exitmenu) { + currentMenu->lastOn = itemOn; if (currentMenu->prevMenu) M_SetupNextMenu (currentMenu->prevMenu); else From 1604e4d439030fd47d860bae82d093713ffdf7da Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 19 Oct 2019 22:20:48 +0200 Subject: [PATCH 087/130] Make spinbust behavior consistent with other bustable blocks and rename FF_ONLYKNUX to FF_STRONGBUST --- extras/conf/SRB2-22.cfg | 2 +- src/dehacked.c | 6 ++--- src/p_spec.c | 2 +- src/p_user.c | 53 ++++++++++++++++++++++------------------- src/r_defs.h | 6 ++--- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index d936721b6..2fd84d279 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -1527,7 +1527,7 @@ linedeftypes title = "Bustable Block"; prefix = "(254)"; flags8text = "[3] Slope skew sides"; - flags64text = "[6] Only bustable by Knuckles"; + flags64text = "[6] Reinforced"; flags128text = "[7] Only block non-players"; flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; diff --git a/src/dehacked.c b/src/dehacked.c index 8d240326d..c0d71e1ae 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8915,9 +8915,9 @@ struct { {"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top. {"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity. {"FF_INTANGABLEFLATS",FF_INTANGABLEFLATS}, ///< Both flats are intangable, but the sides are still solid. - {"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles. - {"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball. - {"FF_ONLYKNUX",FF_ONLYKNUX}, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock. + {"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch. + {"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames. + {"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). {"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. diff --git a/src/p_spec.c b/src/p_spec.c index ebee50a45..f4aeba3e4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7089,7 +7089,7 @@ void P_SpawnSpecials(INT32 fromnetsave) case 254: // Bustable block ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP; if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_ONLYKNUX; + ffloorflags |= FF_STRONGBUST; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; diff --git a/src/p_user.c b/src/p_user.c index 33f84e2db..9ba432689 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2456,39 +2456,42 @@ static void P_CheckBustableBlocks(player_t *player) if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/) { - // If it's an FF_SPINBUST, you have to either be jumping, or coming down - // onto the top from a spin. - if (rover->flags & FF_SPINBUST && ((!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING) && !(player->pflags & PF_BOUNCING)) || (player->pflags & PF_STARTDASH))) + // If it's an FF_SHATTER, you can break it just by touching it. + if (rover->flags & FF_SHATTER) + goto bust; + + // If it's an FF_SPINBUST, you can break it if you are in your spinning frames + // (either from jumping or spindashing). + if (rover->flags & FF_SPINBUST + && (((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH)) + || (player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE)))) + goto bust; + + // You can always break it if you have CA_GLIDEANDCLIMB + // or if you are bouncing on it + // or you are using CA_TWINSPIN/CA2_MELEE. + if (player->charability == CA_GLIDEANDCLIMB + || (player->pflags & PF_BOUNCING) + || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + goto bust; + + if (rover->flags & FF_STRONGBUST) continue; - // if it's not an FF_SHATTER, you must be spinning (and not jumping) - // or be super - // or have CA_GLIDEANDCLIMB - // or be in dashmode with SF_DASHMODE - // or be using CA_TWINSPIN - // or be using CA2_MELEE - // or are drilling in NiGHTS - // or are recording for Metal Sonic - if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST) - && !((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) + // If it's not an FF_STRONGBUST, you can break if you are spinning (and not jumping) + // or you are super + // or you are in dashmode with SF_DASHMODE + // or you are drilling in NiGHTS + // or you are recording for Metal Sonic + if (!((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) && !(player->powers[pw_super]) - && !(player->charability == CA_GLIDEANDCLIMB) - && !(player->pflags & PF_BOUNCING) && !((player->charflags & SF_DASHMODE) && (player->dashmode >= 3*TICRATE)) - && !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) && !(player->pflags & PF_DRILLING) && !metalrecording) continue; - // Only players with CA_GLIDEANDCLIMB, or CA_TWINSPIN/CA2_MELEE users can break this rock... - if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) - && !(player->charability == CA_GLIDEANDCLIMB - || (player->pflags & PF_BOUNCING) - || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))) - continue; - + bust: topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); diff --git a/src/r_defs.h b/src/r_defs.h index 6aeb0671c..4a5c38410 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -139,9 +139,9 @@ typedef enum FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top. FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity. FF_INTANGABLEFLATS = 0x6000000, ///< Both flats are intangable, but the sides are still solid. - FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles. - FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball. - FF_ONLYKNUX = 0x20000000, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock. + FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch. + FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames. + FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). FF_RIPPLE = 0x40000000, ///< Ripple the flats FF_COLORMAPONLY = 0x80000000, ///< Only copy the colormap, not the lightlevel FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. From b219be6f5e1ee1c9820ffd0352c175508c40ca45 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 19 Oct 2019 21:37:03 -0400 Subject: [PATCH 088/130] Remove level select restrictions in Multiplayer --- src/m_menu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fb276f77d..56f757470 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4546,12 +4546,10 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum) if (!(mapheaderinfo[mapnum]->typeoflevel & TOL_COOP)) return true; - if (mapvisited[mapnum]) // MV_MP - return true; - if (mapnum+1 == spstage_start) return true; + return true; /* FALLTHRU */ case LLM_RECORDATTACK: case LLM_NIGHTSATTACK: From 0a321b96d3fca05ef92f2ff2a19adb22f0ffe499 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 20 Oct 2019 12:28:30 +0200 Subject: [PATCH 089/130] Clarified description of "strong" bustable blocks in the ZB config --- extras/conf/SRB2-22.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 2fd84d279..5a36caaf0 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -1527,7 +1527,7 @@ linedeftypes title = "Bustable Block"; prefix = "(254)"; flags8text = "[3] Slope skew sides"; - flags64text = "[6] Reinforced"; + flags64text = "[6] Strong characters only"; flags128text = "[7] Only block non-players"; flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; From 9d425b21e2830e84a2a6b98298b87c2e5c605bec Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 20 Oct 2019 19:13:46 +0100 Subject: [PATCH 090/130] Modify initial platform sink to be more natural, while still toeing the line between "forgiving" and "punishing". --- src/p_floor.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 40bd6a6b2..1360375a7 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2462,7 +2462,7 @@ void T_RaiseSector(levelspecthink_t *raise) if (raise->vars[9]) // Dynamically Sinking Platform^tm { - tic_t shaketime = 10; +#define shaketime 10 if (raise->vars[11] > shaketime) // State: moving { if (playeronme) // If player is standing on the platform, accelerate @@ -2485,8 +2485,7 @@ void T_RaiseSector(levelspecthink_t *raise) if (playeronme || raise->vars[11]) { active = true; - raise->vars[11]++; - if (raise->vars[11] > shaketime) + if (++raise->vars[11] > shaketime) { if (playeronme) raise->vars[10] = FRACUNIT >> 5; @@ -2494,9 +2493,14 @@ void T_RaiseSector(levelspecthink_t *raise) raise->vars[10] = FRACUNIT << 1; } else - raise->vars[10] = 2*(shaketime/2 - raise->vars[11]) << FRACBITS; + { + raise->vars[10] = ((shaketime/2) - raise->vars[11]) << FRACBITS; + if (raise->vars[10] < -raise->vars[2]/2) + raise->vars[10] = -raise->vars[2]/2; + } } } +#undef shaketime } else // Air bobbing platform (not a Dynamically Sinking Platform^tm) active = playeronme; @@ -2594,7 +2598,7 @@ void T_RaiseSector(levelspecthink_t *raise) else if (raise->vars[3] > origspeed) raise->vars[3] = origspeed; } - + raise->vars[3] += raise->vars[10]; res = T_MovePlane From c52ee364f57052a0bdd463d181aaacd87834b48c Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 21 Oct 2019 12:49:12 +0800 Subject: [PATCH 091/130] Only allow landing in the melee ability mid-twinspin if jump or spin is held --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 33f84e2db..37061f87e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2260,7 +2260,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) else if (!player->skidtime) player->pflags &= ~PF_GLIDING; } - else if (player->charability2 == CA2_MELEE && ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) + else if (player->charability2 == CA2_MELEE + && ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY && player->cmd.buttons & (BT_JUMP|BT_USE)))) { if (player->mo->state-states != S_PLAY_MELEE_LANDING) { From d6411b954917fb1fbe17be7e643e6e5645591c59 Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 21 Oct 2019 13:43:02 +0800 Subject: [PATCH 092/130] Add new ATZ gargoyle sprites --- src/hardware/hw_light.c | 5 ++++- src/info.c | 49 ++++++++++++++++++++++------------------- src/info.h | 5 ++++- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index f4637ff7f..08a5dcc10 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -404,6 +404,10 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_HHPL &lspr[NOLIGHT], // SPR_SHRM &lspr[NOLIGHT], // SPR_HHZM + + // Azure Temple Scenery + &lspr[NOLIGHT], // SPR_BGAR + &lspr[NOLIGHT], // SPR_RCRY // Botanic Serenity Scenery &lspr[NOLIGHT], // SPR_BSZ1 @@ -424,7 +428,6 @@ light_t *t_lspr[NUMSPRITES] = // Misc Scenery &lspr[NOLIGHT], // SPR_STLG &lspr[NOLIGHT], // SPR_DBAL - &lspr[NOLIGHT], // SPR_RCRY // Powerup Indicators &lspr[NOLIGHT], // SPR_ARMA diff --git a/src/info.c b/src/info.c index dd5338ef0..576a250fe 100644 --- a/src/info.c +++ b/src/info.c @@ -298,6 +298,10 @@ char sprnames[NUMSPRITES + 1][5] = "HHPL", // Dr Seuss Trees "SHRM", // Mushroom "HHZM", // Misc + + // Azure Temple Scenery + "BGAR", // ATZ Gargoyles + "RCRY", // ATZ Red Crystal (Target) // Botanic Serenity Scenery "BSZ1", // Tall flowers @@ -318,7 +322,6 @@ char sprnames[NUMSPRITES + 1][5] = // Misc Scenery "STLG", // Stalagmites "DBAL", // Disco - "RCRY", // ATZ Red Crystal (Target) // Powerup Indicators "ARMA", // Armageddon Shield Orb @@ -2546,31 +2549,31 @@ state_t states[NUMSTATES] = {SPR_WVIN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_WALLVINE_SHORT // Trapgoyles - {SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE - {SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLE_FIRE1}, // S_TRAPGOYLE_CHECK - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE2}, // S_TRAPGOYLE_FIRE1 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE3}, // S_TRAPGOYLE_FIRE2 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE}, // S_TRAPGOYLE_FIRE3 + {SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE + {SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLE_FIRE1}, // S_TRAPGOYLE_CHECK + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE2}, // S_TRAPGOYLE_FIRE1 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE3}, // S_TRAPGOYLE_FIRE2 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE}, // S_TRAPGOYLE_FIRE3 - {SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEUP_CHECK}, // S_TRAPGOYLEUP - {SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEUP_FIRE1}, // S_TRAPGOYLEUP_CHECK - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE2}, // S_TRAPGOYLEUP_FIRE1 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE3}, // S_TRAPGOYLEUP_FIRE2 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP}, // S_TRAPGOYLEUP_FIRE3 + {SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEUP_CHECK}, // S_TRAPGOYLEUP + {SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEUP_FIRE1}, // S_TRAPGOYLEUP_CHECK + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE2}, // S_TRAPGOYLEUP_FIRE1 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE3}, // S_TRAPGOYLEUP_FIRE2 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP}, // S_TRAPGOYLEUP_FIRE3 - {SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEDOWN_CHECK}, // S_TRAPGOYLEDOWN - {SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEDOWN_FIRE1}, // S_TRAPGOYLEDOWN_CHECK - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE2}, // S_TRAPGOYLEDOWN_FIRE1 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE3}, // S_TRAPGOYLEDOWN_FIRE2 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN}, // S_TRAPGOYLEDOWN_FIRE3 + {SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEDOWN_CHECK}, // S_TRAPGOYLEDOWN + {SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEDOWN_FIRE1}, // S_TRAPGOYLEDOWN_CHECK + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE2}, // S_TRAPGOYLEDOWN_FIRE1 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE3}, // S_TRAPGOYLEDOWN_FIRE2 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN}, // S_TRAPGOYLEDOWN_FIRE3 - {SPR_GARG, 0, 135, {NULL}, 0, 0, S_TRAPGOYLELONG_CHECK}, // S_TRAPGOYLELONG - {SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLELONG_FIRE1}, // S_TRAPGOYLELONG_CHECK - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE2}, // S_TRAPGOYLELONG_FIRE1 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE3}, // S_TRAPGOYLELONG_FIRE2 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE4}, // S_TRAPGOYLELONG_FIRE3 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE5}, // S_TRAPGOYLELONG_FIRE4 - {SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG}, // S_TRAPGOYLELONG_FIRE5 + {SPR_BGAR, 0, 135, {NULL}, 0, 0, S_TRAPGOYLELONG_CHECK}, // S_TRAPGOYLELONG + {SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLELONG_FIRE1}, // S_TRAPGOYLELONG_CHECK + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE2}, // S_TRAPGOYLELONG_FIRE1 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE3}, // S_TRAPGOYLELONG_FIRE2 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE4}, // S_TRAPGOYLELONG_FIRE3 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE5}, // S_TRAPGOYLELONG_FIRE4 + {SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG}, // S_TRAPGOYLELONG_FIRE5 // Target/Red Crystal {SPR_RCRY, 0, -1, {NULL}, 0, 0, S_TARGET_IDLE}, // S_TARGET_IDLE diff --git a/src/info.h b/src/info.h index 0502fd095..74ca5b141 100644 --- a/src/info.h +++ b/src/info.h @@ -554,6 +554,10 @@ typedef enum sprite SPR_HHPL, // Dr Seuss Trees SPR_SHRM, // Mushroom SPR_HHZM, // Misc + + // Azure Temple Scenery + SPR_BGAR, // ATZ Gargoyles + SPR_RCRY, // ATZ Red Crystal (Target) // Botanic Serenity Scenery SPR_BSZ1, // Tall flowers @@ -574,7 +578,6 @@ typedef enum sprite // Misc Scenery SPR_STLG, // Stalagmites SPR_DBAL, // Disco - SPR_RCRY, // ATZ Red Crystal (Target) // Powerup Indicators SPR_ARMA, // Armageddon Shield Orb From 3a3122e2554c1c285afc610d1b89537b010fffa3 Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 21 Oct 2019 16:22:20 +0800 Subject: [PATCH 093/130] Add green flame sprites, state, and object --- src/dehacked.c | 4 ++++ src/hardware/hw_light.c | 3 ++- src/info.c | 33 ++++++++++++++++++++++++++++++++- src/info.h | 5 +++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8d240326d..68da8b022 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5971,6 +5971,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TARGET_RESPAWN", "S_TARGET_ALLDONE", + // ATZ's green flame + "S_GREENFLAME", + // Stalagmites "S_STG0", "S_STG1", @@ -7707,6 +7710,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_TRAPGOYLEDOWN", "MT_TRAPGOYLELONG", "MT_TARGET", + "MT_GREENFLAME", // Stalagmites "MT_STALAGMITE0", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 08a5dcc10..58bd37da0 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -199,7 +199,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_EGGO &lspr[NOLIGHT], // SPR_SEBH &lspr[NOLIGHT], // SPR_FAKE - &lspr[NOLIGHT], // SPR_SHCK + &lspr[LBLUESHINE_L],// SPR_SHCK // Boss 4 (Castle Eggman) &lspr[NOLIGHT], // SPR_EGGP @@ -408,6 +408,7 @@ light_t *t_lspr[NUMSPRITES] = // Azure Temple Scenery &lspr[NOLIGHT], // SPR_BGAR &lspr[NOLIGHT], // SPR_RCRY + &lspr[GREENBALL_L], // SPR_CFLM // Botanic Serenity Scenery &lspr[NOLIGHT], // SPR_BSZ1 diff --git a/src/info.c b/src/info.c index 576a250fe..7c67c7b57 100644 --- a/src/info.c +++ b/src/info.c @@ -298,10 +298,11 @@ char sprnames[NUMSPRITES + 1][5] = "HHPL", // Dr Seuss Trees "SHRM", // Mushroom "HHZM", // Misc - + // Azure Temple Scenery "BGAR", // ATZ Gargoyles "RCRY", // ATZ Red Crystal (Target) + "CFLM", // Green torch flame // Botanic Serenity Scenery "BSZ1", // Tall flowers @@ -2582,6 +2583,9 @@ state_t states[NUMSTATES] = {SPR_RCRY, 1, 0, {A_SpawnObjectRelative}, 0, MT_TARGET, S_NULL}, // S_TARGET_RESPAWN {SPR_RCRY, FF_FULLBRIGHT|1, -1, {A_SetObjectFlags}, MF_PUSHABLE, 1, S_TARGET_ALLDONE}, // S_TARGET_ALLDONE + // Green flame + {SPR_CFLM, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 3, S_GREENFLAME}, // S_GREENFLAME + // Stalagmites {SPR_STLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_STG0 {SPR_STLG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_STG1 @@ -13482,6 +13486,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_GREENFLAME + 1505, // doomednum + S_GREENFLAME, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_NULL, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_PAIN, // flags + S_NULL // raisestate + }, + { // MT_STALAGMITE0 1900, // doomednum S_STG0, // spawnstate diff --git a/src/info.h b/src/info.h index 74ca5b141..562fbb582 100644 --- a/src/info.h +++ b/src/info.h @@ -558,6 +558,7 @@ typedef enum sprite // Azure Temple Scenery SPR_BGAR, // ATZ Gargoyles SPR_RCRY, // ATZ Red Crystal (Target) + SPR_CFLM, // Green torch flame // Botanic Serenity Scenery SPR_BSZ1, // Tall flowers @@ -2698,6 +2699,9 @@ typedef enum state S_TARGET_RESPAWN, S_TARGET_ALLDONE, + // ATZ's green flame + S_GREENFLAME, + // Stalagmites S_STG0, S_STG1, @@ -4456,6 +4460,7 @@ typedef enum mobj_type MT_TRAPGOYLEDOWN, MT_TRAPGOYLELONG, MT_TARGET, // AKA Red Crystal + MT_GREENFLAME, // Stalagmites MT_STALAGMITE0, From 8c5c2a7e4b42788a50b2af3e01cde5a5f9f4215a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Oct 2019 12:42:04 -0700 Subject: [PATCH 094/130] Flatb --- tools/flatb/Makefile | 9 + tools/flatb/flatb.c | 566 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 575 insertions(+) create mode 100644 tools/flatb/Makefile create mode 100644 tools/flatb/flatb.c diff --git a/tools/flatb/Makefile b/tools/flatb/Makefile new file mode 100644 index 000000000..2134973e6 --- /dev/null +++ b/tools/flatb/Makefile @@ -0,0 +1,9 @@ +.PHONY : all clean + +all : flatb + +flatb.exe : flatb.c + i686-w64-mingw32-gcc $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $< + +clean : + $(RM) flatb flatb.exe diff --git a/tools/flatb/flatb.c b/tools/flatb/flatb.c new file mode 100644 index 000000000..edc089232 --- /dev/null +++ b/tools/flatb/flatb.c @@ -0,0 +1,566 @@ +#define HELP \ +"Usage: flatb WAD-file list-file" "\n"\ +"Replace flats and textures by name in a DOOM WAD." "\n"\ +"\n"\ +"list-file may have the following format:" "\n"\ +"\n"\ +"GFZFLR01 GFZFLR02" "\n"\ +"# Comment" "\n"\ +"GFZROCK GFZBLOCK" "\n"\ +"\n"\ +"The first name and second name may be delimited by any whitespace." "\n"\ +"\n"\ +"Copyright 2019 James R." "\n"\ +"All rights reserved." "\n" + +/* +Copyright 2019 James R. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include +#include + +#define cchar const char +#define cvoid const void + +#define LONG int32_t + +#define va_inline( __ap,__last, ... )\ +(\ + va_start (__ap,__last),\ + __VA_ARGS__,\ + va_end (__ap)\ +) + +#define DELIM "\t\n\r " + +typedef struct +{ + FILE * fp; + cchar * filename; +} +File; + +int (*le32)(cvoid *); + +void +Pexit (int c, cchar *s, ...) +{ + va_list ap; + va_inline (ap, s, + + vfprintf(stderr, s, ap) + + ); + exit(c); +} + +void +Prexit (cchar *pr, ...) +{ + va_list ap; + va_inline (ap, pr, + + vfprintf(stderr, pr, ap) + + ); + perror(""); + exit(-1); +} + +void +Fopen (File *f, cchar *filename, const char *mode) +{ + FILE *fp; + if (!( fp = fopen(filename, mode) )) + Prexit("%s", filename); + f->filename = filename; + f->fp = fp; +} + +void +Ferr (File *f) +{ + if (ferror(f->fp)) + Prexit("%s", f->filename); +} + +char * +Fgets (File *f, int b, char *p) +{ + if (!( p = fgets(p, b, f->fp) )) + Ferr(f); + return p; +} + +void +Fread (File *f, int b, void *p) +{ + if (fread(p, 1, b, f->fp) < b) + Ferr(f); +} + +void +Fwrite (File *f, int b, cvoid *s) +{ + if (fwrite(s, 1, b, f->fp) < b) + Ferr(f); +} + +void +Fseek (File *f, long o) +{ + if (fseek(f->fp, o, SEEK_SET) == -1) + Prexit("%s", f->filename); +} + +void * +Malloc (int b) +{ + void *p; + if (!( p = malloc(b) )) + Prexit("%d", b); + return p; +} + +void * +Calloc (int c, int b) +{ + void *p; + if (!( p = calloc(c, b) )) + Prexit("(%d)%d", c, b); + return p; +} + +void +Reallocp (void *pp, int b) +{ + void *p; + if (!( p = realloc((*(void **)pp), b) )) + Prexit("%d", b); + (*(void **)pp) = p; +} + +void +strucpy (char *p, cchar *s, int n) +{ + int c; + int i; + for (i = 0; i < n && ( c = s[i] ); ++i) + p[i] = toupper(c); +} + +int +e32 (cvoid *s) +{ + unsigned int c; + c = *(LONG *)s; + return ( + ( c >> 24 ) | + (( c >> 8 )& 0x00FF00 )| + (( c << 8 )& 0xFF0000 )| + ( c << 24 ) + ); +} + +int +n32 (cvoid *s) +{ + return *(LONG *)s; +} + +void +Ie () +{ + int c; + c = 1; + if (*(char *)&c == 1) + le32 = n32; + else + le32 = e32; +} + +File wad_file; +File list_file; + +int list_c; +char *** list_v; + +char * directory; +char * lump; +int lumpsize; + +char * sectors; +int sectors_c; + +char * sides; +int sides_c; + +int st_floors; +int st_ceilings; +int st_sectors; + +int st_sides; +int st_uppers; +int st_mids; +int st_lowers; + +/* this is horseshit */ +char * old; +char * new; +int did; + +void +Itable () +{ + char a[1024]; + + char ***ttt; + char ***ppp; + + char **pp; + + int c; + + while (Fgets(&list_file, sizeof a, a)) + { + c = a[0]; + if (!( + c == '\n' || + c == '#' + )) + { + list_c++; + } + } + + rewind(list_file.fp); + + list_v = Calloc(list_c, sizeof (char **)); + for ( + ttt = ( ppp = list_v ) + list_c; + ppp < ttt; + ++ppp + ) + { + (*ppp) = pp = Calloc(2, sizeof (char *)); + pp[0] = Malloc(9); + pp[1] = Malloc(9); + } +} + +void +Iwad () +{ + char buf[12]; + + char * t; + char * p; + int map; + + char *sector_p; + char * side_p; + + int n; + int h; + + Fread(&wad_file, 12, buf); + if ( + memcmp(buf, "IWAD", 4) != 0 && + memcmp(buf, "PWAD", 4) != 0 + ) + { + Pexit(-1,"%s: Not a WAD\n", wad_file.filename); + } + + Fseek(&wad_file, (*le32)(&buf[8])); + + n = (*le32)(&buf[4]) * 8; + h = n / 9; + n *= 2; + directory = Malloc(n); + /* minimum number of lumps for a map */ + sectors = Malloc(h); + sides = Malloc(h); + + Fread(&wad_file, n, directory); + + sector_p = sectors; + side_p = sides; + map = 3; + for (t = ( p = directory ) + n; p < t; p += 16) + { + /* looking for SECTORS? Hopefully order doesn't matter in real world. */ + /* also search for fucking SIDES MY SIDES AAAAAAAAAA */ + switch (map) + { + case 0: + case 2: + if (strncmp(&p[8], "SECTORS", 8) == 0) + { + /* copy file offset and size */ + memcpy(sector_p, p, 8); + sector_p += 8; + sectors_c++; + map |= 1; + } + case 1: + if (strncmp(&p[8], "SIDEDEFS", 8) == 0) + { + memcpy(side_p, p, 8); + side_p += 8; + sides_c++; + map |= 2; + } + } + if (map == 3) + { + /* MAP marker */ + if (p[13] == '\0' && strncmp(&p[8], "MAP", 3) == 0) + map = 0; + } + } +} + +void +Fuckyou (char *p, int f, int *st) +{ + if (strncmp(p, old, 8) == 0) + { + strncpy(p, new, 8); + (*st)++; + did |= f; + } +} + +void +Epic (char *p, char *t) +{ + char *top; + char *bot; + int i; + /* oh hi magic number! */ + for (; p < t; p += 26) + { + bot = &p [4]; + top = &p[12]; + did = 0; + for (i = 0; i < list_c; ++i) + { + old = list_v[i][0]; + new = list_v[i][1]; + switch (did) + { + case 0: + case 2: + Fuckyou(bot, 1, &st_floors); + case 1: + Fuckyou(top, 2, &st_ceilings); + } + if (did == 3) + break; + } + if (did) + st_sectors++; + } +} + +void +Epic2 (char *p, char *t) +{ + char *top; + char *mid; + char *bot; + int i; + for (; p < t; p += 30) + { + top = &p [4]; + bot = &p[12]; + mid = &p[20]; + did = 0; + for (i = 0; i < list_c; ++i) + { + old = list_v[i][0]; + new = list_v[i][1]; + switch (did) + { + case 0: + case 2: + case 4: + case 6: + Fuckyou(top, 1, &st_uppers); + case 1: + case 5: + Fuckyou(mid, 2, &st_mids); + case 3: + Fuckyou(bot, 4, &st_lowers); + } + if (did == 7) + break; + } + if (did) + st_sides++; + } +} + +void +Fuck (char *p, int c, void (*fn)(char *,char *)) +{ + char *t; + int offs; + int size; + for (t = p + c * 8; p < t; p += 8) + { + offs = (*le32)(p); + size = (*le32)(p + 4); + if (lumpsize < size) + { + Reallocp(&lump, size); + lumpsize = size; + } + Fseek(&wad_file, offs); + Fread(&wad_file, size, lump); + (*fn)(lump, lump + size); + Fseek(&wad_file, offs); + Fwrite(&wad_file, size, lump); + } +} + +void +Awad () +{ + Fuck (sectors, sectors_c, Epic); + Fuck (sides, sides_c, Epic2); +} + +void +Readtable () +{ + char a[1024]; + + int s; + char *old; + char *new; + + int c; + + s = 0; + + while (Fgets(&list_file, sizeof a, a)) + { + c = a[0]; + if (!( + c == '\n' || + c == '#' + )) + { + if ( + ( old = strtok(a, DELIM) ) && + ( new = strtok(0, DELIM) ) + ) + { + strucpy(list_v[s][0], old, 8); + strucpy(list_v[s][1], new, 8); + ++s; + } + } + } +} + +void +Cleanup () +{ + char ***ttt; + char ***ppp; + + char **pp; + + free(lump); + free(sides); + free(sectors); + free(directory); + + if (list_v) + { + for ( + ttt = ( ppp = list_v ) + list_c; + ppp < ttt && ( pp = (*ppp) ); + ++ppp + ) + { + free(pp[0]); + free(pp[1]); + free(pp); + } + free(list_v); + } +} + +int +main (int ac, char **av) +{ + int n; + + if (ac < 3) + Pexit(0,HELP); + + Fopen (& wad_file, av[1], "rb+"); + Fopen (&list_file, av[2], "r"); + + if (atexit(Cleanup) != 0) + Pexit(-1,"Failed to register cleanup function.\n"); + + Itable(); + Readtable(); + + Ie(); + + Iwad(); + Awad(); + + printf( + "%5d sectors changed.\n" + "%5d floors.\n" + "%5d ceilings.\n" + "\n" + "%5d sides.\n" + "%5d upper textures.\n" + "%5d mid textures.\n" + "%5d lower textures.\n", + + st_sectors, + + st_floors, + st_ceilings, + + st_sides, + + st_uppers, + st_mids, + st_lowers); + + return 0; +} From acd28c001ed48003986f1978df4977da087f1e16 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Oct 2019 14:44:16 -0700 Subject: [PATCH 095/130] lmao I forgot the backside FOF --- src/p_maputl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 6ba8f1d59..111103294 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -720,7 +720,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF + if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF { if (bottomheight < opentop) { opentop = bottomheight; @@ -733,7 +733,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = bottomheight; } - if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF + if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF { if (topheight > openbottom) { openbottom = topheight; From 57a8af1557fdb81c0553181a3f9e271428c7a485 Mon Sep 17 00:00:00 2001 From: sphere Date: Tue, 22 Oct 2019 02:29:34 +0200 Subject: [PATCH 096/130] Disable standalone hangable chains, since they're not a good mechanic. --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 655664f9b..33340876e 100644 --- a/src/info.c +++ b/src/info.c @@ -11158,7 +11158,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_SMALLGRABCHAIN - 1132, // doomednum + -1, // doomednum S_SMALLGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate @@ -11185,7 +11185,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BIGGRABCHAIN - 1133, // doomednum + -1, // doomednum S_BIGGRABCHAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate From 520deac658a532d74acd0cae4551cbab42bc0813 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 22 Oct 2019 16:39:44 +0100 Subject: [PATCH 097/130] remove last few specks of Windows CE code I missed years ago --- src/m_misc.c | 2 +- src/r_data.c | 2 +- src/screen.h | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index aaaf30d67..f7d5cf961 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -197,7 +197,7 @@ INT32 M_MapNumber(char first, char second) // ========================================================================== // some libcs has no access function, make our own -#if defined (_WIN32_WCE) +#if 0 int access(const char *path, int amode) { int accesshandle = -1; diff --git a/src/r_data.c b/src/r_data.c index f1d19a219..524baad15 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -35,7 +35,7 @@ #endif // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog -#ifdef _WIN32_WCE +#if 0 #define AVOID_ERRNO #else #include diff --git a/src/screen.h b/src/screen.h index 3554b5520..79f21e8e4 100644 --- a/src/screen.h +++ b/src/screen.h @@ -39,13 +39,8 @@ // we try to re-allocate a minimum of buffers for stability of the memory, // so all the small-enough tables based on screen size, are allocated once // and for all at the maximum size. -#if defined (_WIN32_WCE) -#define MAXVIDWIDTH 320 -#define MAXVIDHEIGHT 200 -#else #define MAXVIDWIDTH 1920 // don't set this too high because actually #define MAXVIDHEIGHT 1200 // lots of tables are allocated with the MAX size. -#endif #define BASEVIDWIDTH 320 // NEVER CHANGE THIS! This is the original #define BASEVIDHEIGHT 200 // resolution of the graphics. From d62674c18436eefbb21b3c5de33bd7aaebf651eb Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 22 Oct 2019 19:18:56 -0700 Subject: [PATCH 098/130] Clang warnings --- src/info.c | 8 ++++---- src/p_enemy.c | 2 +- src/p_user.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/info.c b/src/info.c index 33340876e..23ba67f37 100644 --- a/src/info.c +++ b/src/info.c @@ -4059,7 +4059,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_THOK, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE, // flags - MT_NULL // raisestate + (statenum_t)MT_NULL// raisestate }, { // MT_TAILSOVERLAY @@ -4491,7 +4491,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_s3kd2l, // activesound MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags - MT_CRUSHCHAIN // raisestate + (statenum_t)MT_CRUSHCHAIN// raisestate }, { // MT_CRUSHCHAIN @@ -11829,7 +11829,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags - MT_ROCKCRUMBLE3 // raisestate + (statenum_t)MT_ROCKCRUMBLE3// raisestate }, { // MT_BRAMBLES @@ -12531,7 +12531,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_s3k76, // activesound MF_PUSHABLE, // flags - MT_MINECARTSIDEMARK // raisestate + (statenum_t)MT_MINECARTSIDEMARK// raisestate }, { // MT_MINECARTSEG diff --git a/src/p_enemy.c b/src/p_enemy.c index f67d7d194..06544392d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2170,7 +2170,7 @@ void A_CrushclawLaunch(mobj_t *actor) UINT8 i = 0; for (i = 0; (i < CSEGS); i++) { - mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate); + mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, (mobjtype_t)actor->info->raisestate); P_SetTarget(&prevchain->target, newchain); prevchain = newchain; } diff --git a/src/p_user.c b/src/p_user.c index a67274d79..3f4d08222 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10456,7 +10456,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target //Axes must be directly parallel or antiparallel, give or take 5 degrees. if (angdiff < ANG10) { - mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate); + mark = P_SpawnMobj(nx, ny, nz, (mobjtype_t)mobj->info->raisestate); return mark; } } From 29a5999a446c9094b653f2fec2fc865f8350bd4b Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 8 Apr 2019 15:48:20 -0700 Subject: [PATCH 099/130] "NEWPING" might as well be the only ping --- src/d_clisrv.c | 12 --------- src/d_clisrv.h | 8 ------ src/d_net.c | 66 ++++---------------------------------------------- src/d_netcmd.c | 4 --- src/d_netcmd.h | 2 -- src/doomdef.h | 3 --- 6 files changed, 5 insertions(+), 90 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a4416b1dc..99d0eff71 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -83,11 +83,9 @@ tic_t jointimeout = (10*TICRATE); static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? -#ifdef NEWPING UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. -#endif SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen @@ -2883,12 +2881,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false); kickreason = KR_KICK; break; -#ifdef NEWPING case KICK_MSG_PING_HIGH: HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false); kickreason = KR_PINGLIMIT; break; -#endif case KICK_MSG_CON_FAIL: HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false); kickreason = KR_SYNCH; @@ -2961,10 +2957,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) D_StartTitle(); if (msg == KICK_MSG_CON_FAIL) M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING); -#ifdef NEWPING else if (msg == KICK_MSG_PING_HIGH) M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING); -#endif else if (msg == KICK_MSG_BANNED) M_StartMessage(M_GetText("You have been banned by the server\n\nPress ESC\n"), NULL, MM_NOTHING); else if (msg == KICK_MSG_CUSTOM_KICK) @@ -4188,7 +4182,6 @@ static void HandlePacketFromPlayer(SINT8 node) resynch_local_inprogress = true; CL_AcknowledgeResynch(&netbuffer->u.resynchpak); break; -#ifdef NEWPING case PT_PING: // Only accept PT_PING from the server. if (node != servernode) @@ -4216,7 +4209,6 @@ static void HandlePacketFromPlayer(SINT8 node) } break; -#endif case PT_SERVERCFG: break; case PT_FILEFRAGMENT: @@ -4730,7 +4722,6 @@ void TryRunTics(tic_t realtics) } } -#ifdef NEWPING static inline void PingUpdate(void) { INT32 i; @@ -4788,7 +4779,6 @@ static inline void PingUpdate(void) pingmeasurecount = 1; //Reset count } -#endif void NetUpdate(void) { @@ -4813,7 +4803,6 @@ void NetUpdate(void) gametime = nowtime; -#ifdef NEWPING if (server) { if (netgame && !(gametime % 255)) @@ -4824,7 +4813,6 @@ void NetUpdate(void) realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); pingmeasurecount++; } -#endif if (client) maketic = neededtic; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 52ca1701d..1656b8e8a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -73,9 +73,7 @@ typedef enum PT_LOGIN, // Login attempt from the client. -#ifdef NEWPING PT_PING, // Packet sent to tell clients the other client's latency to server. -#endif NUMPACKETTYPE } packettype_t; @@ -425,9 +423,7 @@ typedef struct msaskinfo_pak msaskinfo; // 22 bytes plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38) plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE) -#ifdef NEWPING UINT32 pingtable[MAXPLAYERS]; // 128 bytes -#endif } u; // This is needed to pack diff packet types data together } ATTRPACK doomdata_t; @@ -461,9 +457,7 @@ extern consvar_t cv_playbackspeed; #define KICK_MSG_PLAYER_QUIT 3 #define KICK_MSG_TIMEOUT 4 #define KICK_MSG_BANNED 5 -#ifdef NEWPING #define KICK_MSG_PING_HIGH 6 -#endif #define KICK_MSG_CUSTOM_KICK 7 #define KICK_MSG_CUSTOM_BAN 8 @@ -488,11 +482,9 @@ extern SINT8 servernode; void Command_Ping_f(void); extern tic_t connectiontimeout; extern tic_t jointimeout; -#ifdef NEWPING extern UINT16 pingmeasurecount; extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; -#endif extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed; diff --git a/src/d_net.c b/src/d_net.c index 9f68c187c..347474f52 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -185,22 +185,10 @@ typedef struct UINT8 nextacknum; UINT8 flags; -#ifndef NEWPING - // jacobson tcp timeout evaluation algorithm (Karn variation) - fixed_t ping; - fixed_t varping; - INT32 timeout; // computed with ping and varping -#endif } node_t; static node_t nodes[MAXNETNODES]; -#ifndef NEWPING -#define PINGDEFAULT ((200*TICRATE*FRACUNIT)/1000) -#define VARPINGDEFAULT ((50*TICRATE*FRACUNIT)/1000) -#define TIMEOUT(p,v) (p+4*v+FRACUNIT/2)>>FRACBITS; -#else -#define NODETIMEOUT 14 //What the above boiled down to... -#endif +#define NODETIMEOUT 14 #ifndef NONET // return <0 if a < b (mod 256) @@ -320,19 +308,7 @@ static UINT8 GetAcktosend(INT32 node) static void RemoveAck(INT32 i) { INT32 node = ackpak[i].destinationnode; -#ifndef NEWPING - fixed_t trueping = (I_GetTime() - ackpak[i].senttime)<>FRACBITS,(double)FIXED_TO_FLOAT(nodes[node].ping),(double)FIXED_TO_FLOAT(nodes[node].varping),nodes[node].timeout)); -#else DEBFILE(va("Remove ack %d\n",ackpak[i].acknum)); -#endif ackpak[i].acknum = 0; if (nodes[node].flags & NF_CLOSE) Net_CloseConnection(node); @@ -519,11 +495,7 @@ void Net_AckTicker(void) { const INT32 nodei = ackpak[i].destinationnode; node_t *node = &nodes[nodei]; -#ifdef NEWPING if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime()) -#else - if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime()) -#endif { if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE)) { @@ -534,13 +506,8 @@ void Net_AckTicker(void) ackpak[i].acknum = 0; continue; } -#ifdef NEWPING DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime, NODETIMEOUT, I_GetTime())); -#else - DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime, - node->timeout, I_GetTime())); -#endif M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length); ackpak[i].senttime = I_GetTime(); ackpak[i].resentnum++; @@ -658,11 +625,6 @@ void Net_WaitAllAckReceived(UINT32 timeout) static void InitNode(node_t *node) { node->acktosend_head = node->acktosend_tail = 0; -#ifndef NEWPING - node->ping = PINGDEFAULT; - node->varping = VARPINGDEFAULT; - node->timeout = TIMEOUT(node->ping, node->varping); -#endif node->firstacktosend = 0; node->nextacknum = 1; node->remotefirstack = 0; @@ -843,9 +805,7 @@ static const char *packettypename[NUMPACKETTYPE] = "CLIENTJOIN", "NODETIMEOUT", "RESYNCHING", -#ifdef NEWPING "PING" -#endif }; static void DebugPrintpacket(const char *header) @@ -1386,28 +1346,12 @@ boolean D_CheckNetGame(void) void Command_Ping_f(void) { -#ifndef NEWPING - if(server) + INT32 i; + for (i = 0; i < MAXPLAYERS;i++) { -#endif - INT32 i; - for (i = 0; i < MAXPLAYERS;i++) - { -#ifndef NEWPING - const INT32 node = playernode[i]; - if (playeringame[i] && node != 0) - CONS_Printf(M_GetText("%.2d : %s\n %d tics, %d ms.\n"), i, player_names[i], - GetLag(node), G_TicsToMilliseconds(GetLag(node))); -#else - if (playeringame[i] && i != 0) - CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]); -#endif - } -#ifndef NEWPING + if (playeringame[i] && i != 0) + CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]); } - else - CONS_Printf(M_GetText("Only the server can use this.\n")); -#endif } void D_CloseConnection(void) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1e69d371e..4fb309600 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -340,9 +340,7 @@ static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#ifdef NEWPING consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -573,9 +571,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_skipmapcheck); CV_RegisterVar(&cv_sleep); -#ifdef NEWPING CV_RegisterVar(&cv_maxping); -#endif #ifdef SEENAMES CV_RegisterVar(&cv_allowseenames); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 5076c8afa..01858dee6 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -107,9 +107,7 @@ extern consvar_t cv_ringslinger, cv_soundtest; extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes; -#ifdef NEWPING extern consvar_t cv_maxping; -#endif extern consvar_t cv_skipmapcheck; diff --git a/src/doomdef.h b/src/doomdef.h index 8d44d0896..1085e350e 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -561,9 +561,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Polyobject fake flat code #define POLYOBJECTS_PLANES -/// Improved way of dealing with ping values and a ping limit. -#define NEWPING - /// See name of player in your crosshair #define SEENAMES From 3ffa84a77b552d109c177996ccf530fce973d8c1 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 8 Apr 2019 15:57:23 -0700 Subject: [PATCH 100/130] Replace ping command with a condensed and sorted version --- src/d_net.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/src/d_net.c b/src/d_net.c index 347474f52..cbfef7726 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -1344,13 +1344,72 @@ boolean D_CheckNetGame(void) return ret; } +struct pingcell +{ + INT32 num; + INT32 ms; +}; + +static int pingcellcmp(const void *va, const void *vb) +{ + const struct pingcell *a, *b; + a = va; + b = vb; + return ( a->ms - b->ms ); +} + +/* +New ping command formatted nicely to present ping in +ascending order. And with equally spaced columns. +The caller's ping is presented at the bottom too, for +convenience. +*/ + void Command_Ping_f(void) { + struct pingcell pingv[MAXPLAYERS]; + INT32 pingc; + + int name_width = 0; + int ms_width = 0; + + int n; INT32 i; - for (i = 0; i < MAXPLAYERS;i++) + + pingc = 0; + for (i = 1; i < MAXPLAYERS; ++i) + if (playeringame[i]) { - if (playeringame[i] && i != 0) - CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]); + n = strlen(player_names[i]); + if (n > name_width) + name_width = n; + + n = playerpingtable[i]; + if (n > ms_width) + ms_width = n; + + pingv[pingc].num = i; + pingv[pingc].ms = playerpingtable[i]; + pingc++; + } + + if (ms_width < 10) ms_width = 1; + else if (ms_width < 100) ms_width = 2; + else ms_width = 3; + + qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp); + + for (i = 0; i < pingc; ++i) + { + CONS_Printf("%02d : %-*s %*d ms\n", + pingv[i].num, + name_width, player_names[pingv[i].num], + ms_width, pingv[i].ms); + } + + if (!server && playeringame[consoleplayer]) + { + CONS_Printf("\nYour ping is %d ms\n", playerpingtable[consoleplayer]); } } From 602c66d173d6ae1b50bf2bfc0d7f64d128beb420 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 29 Mar 2019 22:00:47 -0700 Subject: [PATCH 101/130] Grab mouse on window focus Window focus does not necessarily imply mouse movement. --- src/sdl/i_video.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index f5c7e3714..b90b5c868 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -357,6 +357,14 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) return 0; } +static void SDLdoGrabMouse(void) +{ + SDL_ShowCursor(SDL_DISABLE); + SDL_SetWindowGrab(window, SDL_TRUE); + if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful + wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore? +} + static void SDLdoUngrabMouse(void) { SDL_ShowCursor(SDL_ENABLE); @@ -579,6 +587,9 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) if (cv_usemouse.value) I_StartupMouse(); } //else firsttimeonmouse = SDL_FALSE; + + if (USE_MOUSEINPUT) + SDLdoGrabMouse(); } else if (!mousefocus && !kbfocus) { @@ -655,9 +666,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) // -- Monster Iestyn if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window) { - SDL_SetWindowGrab(window, SDL_TRUE); - if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful - wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore? + SDLdoGrabMouse(); } } } @@ -1056,7 +1065,7 @@ void I_StartupMouse(void) else firsttimeonmouse = SDL_FALSE; if (cv_usemouse.value) - return; + SDLdoGrabMouse(); else SDLdoUngrabMouse(); } From 135619af8b4e98d8d434d7a7c64827b6e6b1186c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 18 Apr 2019 23:42:28 -0700 Subject: [PATCH 102/130] Add a command to increment cvars --- src/command.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/command.c b/src/command.c index cfb36f02f..c23f0e8f3 100644 --- a/src/command.c +++ b/src/command.c @@ -49,6 +49,7 @@ static void COM_Exec_f(void); static void COM_Wait_f(void); static void COM_Help_f(void); static void COM_Toggle_f(void); +static void COM_Add_f(void); static void CV_EnforceExecVersion(void); static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); @@ -291,6 +292,7 @@ void COM_Init(void) COM_AddCommand("wait", COM_Wait_f); COM_AddCommand("help", COM_Help_f); COM_AddCommand("toggle", COM_Toggle_f); + COM_AddCommand("add", COM_Add_f); RegisterNetXCmd(XD_NETVAR, Got_NetVar); } @@ -816,6 +818,27 @@ static void COM_Toggle_f(void) CV_AddValue(cvar, +1); } +/** Command variant of CV_AddValue + */ +static void COM_Add_f(void) +{ + consvar_t *cvar; + + if (COM_Argc() != 3) + { + CONS_Printf(M_GetText("Add : Add to the value of a cvar. Negative values work too!\n")); + return; + } + cvar = CV_FindVar(COM_Argv(1)); + if (!cvar) + { + CONS_Alert(CONS_NOTICE, M_GetText("%s is not a cvar\n"), COM_Argv(1)); + return; + } + + CV_AddValue(cvar, atoi(COM_Argv(2))); +} + // ========================================================================= // VARIABLE SIZE BUFFERS // ========================================================================= From f0ee901160f1752f2d731181dcaa68c8d651135c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 4 Jul 2019 17:48:17 -0700 Subject: [PATCH 103/130] Support adding to CV_FLOAT cvars with the Add command --- src/command.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index c23f0e8f3..a54735389 100644 --- a/src/command.c +++ b/src/command.c @@ -836,7 +836,10 @@ static void COM_Add_f(void) return; } - CV_AddValue(cvar, atoi(COM_Argv(2))); + if (( cvar->flags & CV_FLOAT )) + CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2)))); + else + CV_AddValue(cvar, atoi(COM_Argv(2))); } // ========================================================================= From a24814c2fca51adedc1c562ce2464ab6cccf2f9e Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 18 Apr 2019 23:50:29 -0700 Subject: [PATCH 104/130] Add a "-noaudio" parm to cover "-nomusic" and "-nosound" --- src/d_main.c | 26 +++++++++++++++++++------- src/s_sound.c | 6 +++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 37637edd6..68eb7cc77 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1248,16 +1248,28 @@ void D_SRB2Main(void) { CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); } - if (M_CheckParm("-nosound")) + if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic + { sound_disabled = true; - if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic - midi_disabled = digital_disabled = true; + digital_disabled = true; + midi_disabled = true; + } else { - if (M_CheckParm("-nomidimusic")) - midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound - if (M_CheckParm("-nodigmusic")) - digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound + if (M_CheckParm("-nosound")) + sound_disabled = true; + if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic + { + digital_disabled = true; + midi_disabled = true; + } + else + { + if (M_CheckParm("-nomidimusic")) + midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound + if (M_CheckParm("-nodigmusic")) + digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound + } } I_StartupSound(); I_InitMusic(); diff --git a/src/s_sound.c b/src/s_sound.c index 299e4b889..1a719d972 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2202,7 +2202,7 @@ static void Command_RestartAudio_f(void) void GameSounds_OnChange(void) { - if (M_CheckParm("-nosound")) + if (M_CheckParm("-nosound") || M_CheckParm("-noaudio")) return; if (sound_disabled) @@ -2220,7 +2220,7 @@ void GameSounds_OnChange(void) void GameDigiMusic_OnChange(void) { - if (M_CheckParm("-nomusic")) + if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio")) return; else if (M_CheckParm("-nodigmusic")) return; @@ -2262,7 +2262,7 @@ void GameDigiMusic_OnChange(void) void GameMIDIMusic_OnChange(void) { - if (M_CheckParm("-nomusic")) + if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio")) return; else if (M_CheckParm("-nomidimusic")) return; From 43ca2c1b30b5cea8b131c4e8caa36d6e52f9f34f Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 14 Apr 2019 21:14:01 -0700 Subject: [PATCH 105/130] Support splitscreen PLAYERINFO and don't expose clients' IP addresses --- src/d_clisrv.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 99d0eff71..7e9be993e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1323,33 +1323,13 @@ static void SV_SendPlayerInfo(INT32 node) continue; } - netbuffer->u.playerinfo[i].node = (UINT8)playernode[i]; + netbuffer->u.playerinfo[i].node = i; strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1); netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0'; //fetch IP address - { - const char *claddress; - UINT32 numericaddress[4]; - - memset(netbuffer->u.playerinfo[i].address, 0, 4); - if (playernode[i] == 0) - { - //127.0.0.1 - netbuffer->u.playerinfo[i].address[0] = 127; - netbuffer->u.playerinfo[i].address[3] = 1; - } - else if (playernode[i] > 0 && I_GetNodeAddress && (claddress = I_GetNodeAddress(playernode[i])) != NULL) - { - if (sscanf(claddress, "%d.%d.%d.%d", &numericaddress[0], &numericaddress[1], &numericaddress[2], &numericaddress[3]) < 4) - goto badaddress; - netbuffer->u.playerinfo[i].address[0] = (UINT8)numericaddress[0]; - netbuffer->u.playerinfo[i].address[1] = (UINT8)numericaddress[1]; - netbuffer->u.playerinfo[i].address[2] = (UINT8)numericaddress[2]; - netbuffer->u.playerinfo[i].address[3] = (UINT8)numericaddress[3]; - } - } - badaddress: + //No, don't do that, you fuckface. + memset(netbuffer->u.playerinfo[i].address, 0, 4); if (G_GametypeHasTeams()) { From 12540dca320659a5f5169b4dcea94bf97791e7ca Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 11 Mar 2019 12:50:01 -0700 Subject: [PATCH 106/130] Make "Focus lost" HUD overlay optional --- src/m_menu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index c0b02a5b7..8d3dad741 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -387,6 +387,8 @@ static void Dummymares_OnChange(void); // CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE. // ========================================================================== +consvar_t cv_showfocuslost = {"showfocuslost", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL }; + static CV_PossibleValue_t map_cons_t[] = { {1,"MIN"}, {NUMMAPS, "MAX"} @@ -1230,6 +1232,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_HEADER, NULL, "Diagnostic", NULL, 180}, {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 186}, {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 191}, + {IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 196}, }; static menuitem_t OP_VideoModeMenu[] = @@ -3322,7 +3325,7 @@ void M_Drawer(void) } // focus lost notification goes on top of everything, even the former everything - if (window_notinfocus) + if (window_notinfocus && cv_showfocuslost.value) { M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) @@ -3547,6 +3550,8 @@ void M_Init(void) { int i; + CV_RegisterVar(&cv_showfocuslost); + CV_RegisterVar(&cv_nextmap); CV_RegisterVar(&cv_newgametype); CV_RegisterVar(&cv_chooseskin); From 5ac8a26814bb43c5e91ab77af9a2e546b0ef50e4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 11 Mar 2019 14:57:11 -0700 Subject: [PATCH 107/130] Miscellaneous window de-focus options Music pausing is now optional. Sounds may be paused--on by default. The game itself being paused in off-line mode is now optional. (showfocuslost now loads from config.) --- src/d_netcmd.c | 2 ++ src/g_game.c | 2 ++ src/g_game.h | 2 ++ src/m_menu.c | 42 +++++++++++++------------------- src/m_menu.h | 1 + src/p_user.c | 2 +- src/s_sound.c | 62 +++++++++++++++++++++++++++++++++++++++++------ src/s_sound.h | 6 +++++ src/sdl/i_video.c | 9 ++++++- 9 files changed, 94 insertions(+), 34 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4fb309600..bbe6b28d2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -736,6 +736,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_chasefreelook); CV_RegisterVar(&cv_chasefreelook2); CV_RegisterVar(&cv_tutorialprompt); + CV_RegisterVar(&cv_showfocuslost); + CV_RegisterVar(&cv_pauseifunfocused); // g_input.c CV_RegisterVar(&cv_sideaxis); diff --git a/src/g_game.c b/src/g_game.c index 6c31ce9e3..92b8de96e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -361,6 +361,8 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}}; consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +// Pause game upon window losing focus +consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_game.h b/src/g_game.h index df1301dd7..198cbc396 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -59,6 +59,8 @@ extern boolean pausebreakkey; extern boolean promptactive; +extern consvar_t cv_pauseifunfocused; + // used in game menu extern consvar_t cv_tutorialprompt; extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard; diff --git a/src/m_menu.c b/src/m_menu.c index 8d3dad741..13e5bfc4f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1326,22 +1326,25 @@ static menuitem_t OP_OpenGLColorMenu[] = static menuitem_t OP_SoundOptionsMenu[] = { - {IT_HEADER, NULL, "Game Audio", NULL, 0}, // 0 // ScrollMenu offsets - {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 13}, // 6 - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 23}, // 11 + {IT_HEADER, NULL, "Game Audio", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 6}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 11}, - {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 43}, // 21 - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 53}, // 26 + {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 21}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 26}, - {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 73}, // 36 - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 83}, // 41 + {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41}, - {IT_HEADER, NULL, "Accessibility", NULL, 103}, // 50 - {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 115}, // 56 - {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 125}, // 62 + {IT_HEADER, NULL, "Accessibility", NULL, 50}, + {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 56}, + {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 61}, + + {IT_STRING | IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 71}, + {IT_STRING | IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 76}, #ifdef HAVE_MIXERX - {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 143}, + {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 86}, #endif }; @@ -1964,18 +1967,9 @@ menu_t OP_ColorOptionsDef = 0, NULL }; -menu_t OP_SoundOptionsDef = -{ - MN_OP_MAIN + (MN_OP_SOUND << 6), - "M_SOUND", - sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t), - &OP_MainDef, - OP_SoundOptionsMenu, - M_DrawGenericMenu, - 30, 30, - 0, - NULL -}; +menu_t OP_SoundOptionsDef = DEFAULTSCROLLMENUSTYLE( + MN_OP_MAIN + (MN_OP_SOUND << 6), + "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); #ifdef HAVE_MIXERX menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); #endif @@ -3550,8 +3544,6 @@ void M_Init(void) { int i; - CV_RegisterVar(&cv_showfocuslost); - CV_RegisterVar(&cv_nextmap); CV_RegisterVar(&cv_newgametype); CV_RegisterVar(&cv_chooseskin); diff --git a/src/m_menu.h b/src/m_menu.h index 05962d2b1..d568a1b53 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -374,6 +374,7 @@ typedef struct extern description_t description[MAXSKINS]; +extern consvar_t cv_showfocuslost; extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; extern CV_PossibleValue_t gametype_cons_t[]; diff --git a/src/p_user.c b/src/p_user.c index 3f4d08222..c65d7b6cc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -191,7 +191,7 @@ boolean P_AutoPause(void) if (netgame || modeattacking || gamestate == GS_TITLESCREEN) return false; - return (menuactive || window_notinfocus); + return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value )); } // diff --git a/src/s_sound.c b/src/s_sound.c index 1a719d972..e68a25ec9 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -60,6 +60,9 @@ static void GameMIDIMusic_OnChange(void); static void GameSounds_OnChange(void); static void GameDigiMusic_OnChange(void); +static void PlayMusicIfUnfocused_OnChange(void); +static void PlaySoundIfUnfocused_OnChange(void); + static void ModFilter_OnChange(void); static lumpnum_t S_GetMusicLumpNum(const char *mname); @@ -117,6 +120,9 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlayMusicIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlaySoundIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL}; + #ifdef HAVE_OPENMPT static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -290,6 +296,9 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_miditimiditypath); #endif + CV_RegisterVar(&cv_playmusicifunfocused); + CV_RegisterVar(&cv_playsoundifunfocused); + COM_AddCommand("tunes", Command_Tunes_f); COM_AddCommand("restartaudio", Command_RestartAudio_f); @@ -2018,6 +2027,24 @@ void S_ResumeAudio(void) S_AdjustMusicStackTics(); } +void S_DisableSound(void) +{ + if (sound_started && !sound_disabled) + { + sound_disabled = true; + S_StopSounds(); + } +} + +void S_EnableSound(void) +{ + if (sound_started && sound_disabled) + { + sound_disabled = false; + S_InitSfxChannels(cv_soundvolume.value); + } +} + void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) { if (digvolume < 0) @@ -2207,15 +2234,11 @@ void GameSounds_OnChange(void) if (sound_disabled) { - sound_disabled = false; - S_InitSfxChannels(cv_soundvolume.value); - S_StartSound(NULL, sfx_strpst); + if (!( cv_playsoundifunfocused.value && window_notinfocus )) + S_EnableSound(); } else - { - sound_disabled = true; - S_StopSounds(); - } + S_DisableSound(); } void GameDigiMusic_OnChange(void) @@ -2308,3 +2331,28 @@ void ModFilter_OnChange(void) openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); } #endif + +static void PlayMusicIfUnfocused_OnChange(void) +{ + if (window_notinfocus) + { + if (cv_playmusicifunfocused.value) + S_PauseAudio(); + else + S_ResumeAudio(); + } +} + +static void PlaySoundIfUnfocused_OnChange(void) +{ + if (!cv_gamesounds.value) + return; + + if (window_notinfocus) + { + if (cv_playsoundifunfocused.value) + S_DisableSound(); + else + S_EnableSound(); + } +} diff --git a/src/s_sound.h b/src/s_sound.h index 48128527c..f4a986585 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -44,6 +44,8 @@ extern consvar_t cv_resetmusicbyheader; extern consvar_t cv_gamedigimusic; extern consvar_t cv_gamemidimusic; extern consvar_t cv_gamesounds; +extern consvar_t cv_playmusicifunfocused; +extern consvar_t cv_playsoundifunfocused; #ifdef HAVE_OPENMPT extern consvar_t cv_modfilter; @@ -244,6 +246,10 @@ void S_StopMusic(void); void S_PauseAudio(void); void S_ResumeAudio(void); +// Enable and disable sound effects +void S_EnableSound(void); +void S_DisableSound(void); + // // Music Fading // diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b90b5c868..f760e79bd 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -580,7 +580,11 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we got focus back, resume music if necessary window_notinfocus = false; if (!paused) + { S_ResumeAudio(); //resume it + if (cv_gamesounds.value) + S_EnableSound(); + } if (!firsttimeonmouse) { @@ -595,7 +599,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { // Tell game we lost focus, pause music window_notinfocus = true; - S_PauseAudio(); + if (!cv_playmusicifunfocused.value) + S_PauseAudio(); + if (!cv_playsoundifunfocused.value) + S_DisableSound(); if (!disable_mouse) { From 923f43f88707cd46a7b84a87f24fadd59fd01e30 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 16 Mar 2019 15:42:18 -0700 Subject: [PATCH 108/130] Move change viewpoint control checking so it doesn't take precedence Notably over chat. --- src/g_game.c | 118 +++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 92b8de96e..246fb965a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1715,65 +1715,6 @@ static INT32 camtoggledelay, camtoggledelay2 = 0; // boolean G_Responder(event_t *ev) { - // allow spy mode changes even during the demo - if (gamestate == GS_LEVEL && ev->type == ev_keydown - && (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) - { - if (splitscreen || !netgame) - displayplayer = consoleplayer; - else - { - // spy mode - do - { - displayplayer++; - if (displayplayer == MAXPLAYERS) - displayplayer = 0; - - if (!playeringame[displayplayer]) - continue; - - if (players[displayplayer].spectator) - continue; - - if (G_GametypeHasTeams()) - { - if (players[consoleplayer].ctfteam - && players[displayplayer].ctfteam != players[consoleplayer].ctfteam) - continue; - } - else if (gametype == GT_HIDEANDSEEK) - { - if (players[consoleplayer].pflags & PF_TAGIT) - continue; - } - // Other Tag-based gametypes? - else if (G_TagGametype()) - { - if (!players[consoleplayer].spectator - && (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT)) - continue; - } - else if (G_GametypeHasSpectators() && G_RingSlingerGametype()) - { - if (!players[consoleplayer].spectator) - continue; - } - - break; - } while (displayplayer != consoleplayer); - - // change statusbar also if playing back demo - if (singledemo) - ST_changeDemoView(); - - // tell who's the view - CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]); - - return true; - } - } - // any other key pops up menu if in demos if (gameaction == ga_nothing && !singledemo && ((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN)) @@ -1850,6 +1791,65 @@ boolean G_Responder(event_t *ev) if (HU_Responder(ev)) return true; // chat ate the event + // allow spy mode changes even during the demo + if (gamestate == GS_LEVEL && ev->type == ev_keydown + && (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) + { + if (splitscreen || !netgame) + displayplayer = consoleplayer; + else + { + // spy mode + do + { + displayplayer++; + if (displayplayer == MAXPLAYERS) + displayplayer = 0; + + if (!playeringame[displayplayer]) + continue; + + if (players[displayplayer].spectator) + continue; + + if (G_GametypeHasTeams()) + { + if (players[consoleplayer].ctfteam + && players[displayplayer].ctfteam != players[consoleplayer].ctfteam) + continue; + } + else if (gametype == GT_HIDEANDSEEK) + { + if (players[consoleplayer].pflags & PF_TAGIT) + continue; + } + // Other Tag-based gametypes? + else if (G_TagGametype()) + { + if (!players[consoleplayer].spectator + && (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT)) + continue; + } + else if (G_GametypeHasSpectators() && G_RingSlingerGametype()) + { + if (!players[consoleplayer].spectator) + continue; + } + + break; + } while (displayplayer != consoleplayer); + + // change statusbar also if playing back demo + if (singledemo) + ST_changeDemoView(); + + // tell who's the view + CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]); + + return true; + } + } + // update keys current state G_MapEventsToControls(ev); From 39baca89d3707077aa243f4f66c30cf0a2b4cfea Mon Sep 17 00:00:00 2001 From: james Date: Wed, 6 Feb 2019 17:24:13 -0800 Subject: [PATCH 109/130] Do not start sound system when disabled --- src/d_main.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 68eb7cc77..41fa98408 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1244,10 +1244,6 @@ void D_SRB2Main(void) sound_disabled = true; midi_disabled = digital_disabled = true; } - else - { - CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); - } if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic { sound_disabled = true; @@ -1271,9 +1267,17 @@ void D_SRB2Main(void) digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound } } - I_StartupSound(); - I_InitMusic(); - S_InitSfxChannels(cv_soundvolume.value); + if (!( sound_disabled && digital_disabled +#ifndef NO_MIDI + && midi_disabled +#endif + )) + { + CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); + I_StartupSound(); + I_InitMusic(); + S_InitSfxChannels(cv_soundvolume.value); + } CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); From aa9f19512cf54edbf6275993c0a75e12009d7dd9 Mon Sep 17 00:00:00 2001 From: james Date: Sat, 9 Feb 2019 18:10:54 -0800 Subject: [PATCH 110/130] Use less confusing player sorting key names --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 13e5bfc4f..cb33105d9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -409,7 +409,7 @@ static CV_PossibleValue_t serversort_cons_t[] = { {1,"Modified State"}, {2,"Most Players"}, {3,"Least Players"}, - {4,"Max Players"}, + {4,"Max Player Slots"}, {5,"Gametype"}, {0,NULL} }; From 0b314a82bb13e675f6d3fdf93184cece63ed7dbd Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 2 Mar 2019 15:56:44 -0800 Subject: [PATCH 111/130] Use long double suffix --- src/doomdef.h | 6 +++++- src/hardware/hw_bsp.c | 2 +- src/hardware/hw_dll.h | 3 --- src/r_plane.c | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 1085e350e..676c86e0d 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -509,13 +509,17 @@ INT32 I_GetKey(void); // Max gamepad/joysticks that can be detected/used. #define MAX_JOYSTICKS 4 +#ifndef M_PIl +#define M_PIl 3.1415926535897932384626433832795029L +#endif + // Floating point comparison epsilons from float.h #ifndef FLT_EPSILON #define FLT_EPSILON 1.1920928955078125e-7f #endif #ifndef DBL_EPSILON -#define DBL_EPSILON 2.2204460492503131e-16 +#define DBL_EPSILON 2.2204460492503131e-16l #endif // An assert-type mechanism. diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 483932492..9e454bcd5 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -201,7 +201,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1, // (do not accept hit with the extensions) num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx; frac = num / den; - if (frac < 0.0 || frac > 1.0) + if (frac < 0.0l || frac > 1.0l) return NULL; // now get the frac along the BSP line diff --git a/src/hardware/hw_dll.h b/src/hardware/hw_dll.h index 452e9037c..3fa5852d8 100644 --- a/src/hardware/hw_dll.h +++ b/src/hardware/hw_dll.h @@ -61,9 +61,6 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR; // ========================================================================== // Constants -#ifndef M_PIl -#define M_PIl 3.1415926535897932384626433832795029L -#endif #define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360 void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/; diff --git a/src/r_plane.c b/src/r_plane.c index 34debeea7..619ade89d 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1102,7 +1102,7 @@ void R_DrawSinglePlane(visplane_t *pl) temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy); zeroheight = FIXED_TO_FLOAT(temp); -#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180) +#define ANG2RAD(angle) ((float)((angle)*M_PIl)/ANGLE_180) // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in From d86be51472723992efbd2d7e130f382e3569621a Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Aug 2019 12:32:57 -0700 Subject: [PATCH 112/130] Toggle ping and FPS counters with HUD --- src/sdl/i_video.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index f760e79bd..ed371d349 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1180,8 +1180,11 @@ void I_FinishUpdate(void) if (cv_closedcaptioning.value) SCR_ClosedCaptions(); - if (cv_ticrate.value) - SCR_DisplayTicRate(); + if (st_overlay) + { + if (cv_ticrate.value) + SCR_DisplayTicRate(); + } if (rendermode == render_soft && screens[0]) { From 52c5d492154af3e8dad14fa524058aba0974b1fc Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Aug 2019 12:35:06 -0700 Subject: [PATCH 113/130] Apply HUD translucency to ping and FPS counters --- src/screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index 547036a60..9939aff93 100644 --- a/src/screen.c +++ b/src/screen.c @@ -421,9 +421,9 @@ void SCR_DisplayTicRate(void) else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; V_DrawString(vid.width-(72*vid.dupx), h, - V_YELLOWMAP|V_NOSCALESTART, "FPS:"); + V_YELLOWMAP|V_NOSCALESTART|V_HUDTRANS, "FPS:"); V_DrawString(vid.width-(40*vid.dupx), h, - ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE)); + ticcntcolor|V_NOSCALESTART|V_HUDTRANS, va("%02d/%02u", totaltics, TICRATE)); lasttic = ontic; } From bfce75d5cd2bf76bdf48e11605ef5faf5fa66bbf Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 23 Oct 2019 16:29:50 -0400 Subject: [PATCH 114/130] Disable restriction for ``DEVELOP`` builds only --- src/m_menu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 56f757470..894b19e60 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4549,7 +4549,11 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum) if (mapnum+1 == spstage_start) return true; - return true; +#ifndef DEVELOP + if (mapvisited[mapnum]) // MV_MP +#endif + return true; + /* FALLTHRU */ case LLM_RECORDATTACK: case LLM_NIGHTSATTACK: From 9162ba87cc49db03f565be85fcece5c305cfb6e0 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 23 Oct 2019 15:24:34 -0700 Subject: [PATCH 115/130] Revert sound and music window focus related toggles This partially reverts commit 5ac8a26814bb43c5e91ab77af9a2e546b0ef50e4. --- src/m_menu.c | 40 +++++++++++++++++------------- src/s_sound.c | 62 ++++++----------------------------------------- src/s_sound.h | 6 ----- src/sdl/i_video.c | 9 +------ 4 files changed, 31 insertions(+), 86 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index cb33105d9..42f92daee 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1326,25 +1326,22 @@ static menuitem_t OP_OpenGLColorMenu[] = static menuitem_t OP_SoundOptionsMenu[] = { - {IT_HEADER, NULL, "Game Audio", NULL, 0}, - {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 6}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 11}, + {IT_HEADER, NULL, "Game Audio", NULL, 0}, // 0 // ScrollMenu offsets + {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 13}, // 6 + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 23}, // 11 - {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 21}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 26}, + {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 43}, // 21 + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 53}, // 26 - {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41}, + {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 73}, // 36 + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 83}, // 41 - {IT_HEADER, NULL, "Accessibility", NULL, 50}, - {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 56}, - {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 61}, - - {IT_STRING | IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 71}, - {IT_STRING | IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 76}, + {IT_HEADER, NULL, "Accessibility", NULL, 103}, // 50 + {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 115}, // 56 + {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 125}, // 62 #ifdef HAVE_MIXERX - {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 86}, + {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 143}, #endif }; @@ -1967,9 +1964,18 @@ menu_t OP_ColorOptionsDef = 0, NULL }; -menu_t OP_SoundOptionsDef = DEFAULTSCROLLMENUSTYLE( - MN_OP_MAIN + (MN_OP_SOUND << 6), - "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); +menu_t OP_SoundOptionsDef = +{ + MN_OP_MAIN + (MN_OP_SOUND << 6), + "M_SOUND", + sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t), + &OP_MainDef, + OP_SoundOptionsMenu, + M_DrawGenericMenu, + 30, 30, + 0, + NULL +}; #ifdef HAVE_MIXERX menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); #endif diff --git a/src/s_sound.c b/src/s_sound.c index e68a25ec9..1a719d972 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -60,9 +60,6 @@ static void GameMIDIMusic_OnChange(void); static void GameSounds_OnChange(void); static void GameDigiMusic_OnChange(void); -static void PlayMusicIfUnfocused_OnChange(void); -static void PlaySoundIfUnfocused_OnChange(void); - static void ModFilter_OnChange(void); static lumpnum_t S_GetMusicLumpNum(const char *mname); @@ -120,9 +117,6 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlayMusicIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlaySoundIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL}; - #ifdef HAVE_OPENMPT static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -296,9 +290,6 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_miditimiditypath); #endif - CV_RegisterVar(&cv_playmusicifunfocused); - CV_RegisterVar(&cv_playsoundifunfocused); - COM_AddCommand("tunes", Command_Tunes_f); COM_AddCommand("restartaudio", Command_RestartAudio_f); @@ -2027,24 +2018,6 @@ void S_ResumeAudio(void) S_AdjustMusicStackTics(); } -void S_DisableSound(void) -{ - if (sound_started && !sound_disabled) - { - sound_disabled = true; - S_StopSounds(); - } -} - -void S_EnableSound(void) -{ - if (sound_started && sound_disabled) - { - sound_disabled = false; - S_InitSfxChannels(cv_soundvolume.value); - } -} - void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) { if (digvolume < 0) @@ -2234,11 +2207,15 @@ void GameSounds_OnChange(void) if (sound_disabled) { - if (!( cv_playsoundifunfocused.value && window_notinfocus )) - S_EnableSound(); + sound_disabled = false; + S_InitSfxChannels(cv_soundvolume.value); + S_StartSound(NULL, sfx_strpst); } else - S_DisableSound(); + { + sound_disabled = true; + S_StopSounds(); + } } void GameDigiMusic_OnChange(void) @@ -2331,28 +2308,3 @@ void ModFilter_OnChange(void) openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); } #endif - -static void PlayMusicIfUnfocused_OnChange(void) -{ - if (window_notinfocus) - { - if (cv_playmusicifunfocused.value) - S_PauseAudio(); - else - S_ResumeAudio(); - } -} - -static void PlaySoundIfUnfocused_OnChange(void) -{ - if (!cv_gamesounds.value) - return; - - if (window_notinfocus) - { - if (cv_playsoundifunfocused.value) - S_DisableSound(); - else - S_EnableSound(); - } -} diff --git a/src/s_sound.h b/src/s_sound.h index f4a986585..48128527c 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -44,8 +44,6 @@ extern consvar_t cv_resetmusicbyheader; extern consvar_t cv_gamedigimusic; extern consvar_t cv_gamemidimusic; extern consvar_t cv_gamesounds; -extern consvar_t cv_playmusicifunfocused; -extern consvar_t cv_playsoundifunfocused; #ifdef HAVE_OPENMPT extern consvar_t cv_modfilter; @@ -246,10 +244,6 @@ void S_StopMusic(void); void S_PauseAudio(void); void S_ResumeAudio(void); -// Enable and disable sound effects -void S_EnableSound(void); -void S_DisableSound(void); - // // Music Fading // diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ed371d349..be6017aa9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -580,11 +580,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we got focus back, resume music if necessary window_notinfocus = false; if (!paused) - { S_ResumeAudio(); //resume it - if (cv_gamesounds.value) - S_EnableSound(); - } if (!firsttimeonmouse) { @@ -599,10 +595,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { // Tell game we lost focus, pause music window_notinfocus = true; - if (!cv_playmusicifunfocused.value) - S_PauseAudio(); - if (!cv_playsoundifunfocused.value) - S_DisableSound(); + S_PauseAudio(); if (!disable_mouse) { From cd252eb4687873f191816b49fc0e4cfb505f75ad Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 23 Oct 2019 17:21:09 -0700 Subject: [PATCH 116/130] Console variables to toggle music/sound playing when the window is unfocused Playsoundsifunfocused and playmusicifunfocused. "No" by default. --- src/s_sound.c | 36 ++++++++++++++++++++++++++++++++++-- src/s_sound.h | 10 ++++++++++ src/sdl/i_video.c | 5 ++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 299e4b889..26f1e3291 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -117,6 +117,10 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// Window focus sound sytem toggles +consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo}; +consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo}; + #ifdef HAVE_OPENMPT static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -278,6 +282,8 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_samplerate); CV_RegisterVar(&cv_resetmusic); CV_RegisterVar(&cv_resetmusicbyheader); + CV_RegisterVar(&cv_playsoundsifunfocused); + CV_RegisterVar(&cv_playmusicifunfocused); CV_RegisterVar(&cv_gamesounds); CV_RegisterVar(&cv_gamedigimusic); CV_RegisterVar(&cv_gamemidimusic); @@ -373,6 +379,18 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx) return W_GetNumForName("dsthok"); } +// +// Sound Status +// + +boolean S_SoundDisabled(void) +{ + return ( + sound_disabled || + ( window_notinfocus && ! cv_playsoundsifunfocused.value ) + ); +} + // Stop all sounds, load level info, THEN start sounds. void S_StopSounds(void) { @@ -540,7 +558,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) mobj_t *listenmobj = players[displayplayer].mo; mobj_t *listenmobj2 = NULL; - if (sound_disabled || !sound_started) + if (S_SoundDisabled() || !sound_started) return; // Don't want a sound? Okay then... @@ -730,7 +748,7 @@ dontplay: void S_StartSound(const void *origin, sfxenum_t sfx_id) { - if (sound_disabled) + if (S_SoundDisabled()) return; if (mariomode) // Sounds change in Mario mode! @@ -1434,6 +1452,13 @@ boolean S_MusicPaused(void) return I_SongPaused(); } +boolean S_MusicNotInFocus(void) +{ + return ( + ( window_notinfocus && ! cv_playmusicifunfocused.value ) + ); +} + musictype_t S_MusicType(void) { return I_SongType(); @@ -1867,6 +1892,10 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) } S_InitMusicVolume(); // switch between digi and sequence volume + + if (S_MusicNotInFocus()) + S_PauseAudio(); + return true; } @@ -2009,6 +2038,9 @@ void S_PauseAudio(void) void S_ResumeAudio(void) { + if (S_MusicNotInFocus()) + return; + if (I_SongPlaying() && I_SongPaused()) I_ResumeSong(); diff --git a/src/s_sound.h b/src/s_sound.h index 48128527c..20b2489a5 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -45,6 +45,9 @@ extern consvar_t cv_gamedigimusic; extern consvar_t cv_gamemidimusic; extern consvar_t cv_gamesounds; +extern consvar_t cv_playmusicifunfocused; +extern consvar_t cv_playsoundsifunfocused; + #ifdef HAVE_OPENMPT extern consvar_t cv_modfilter; #endif @@ -144,6 +147,12 @@ void S_StartEx(boolean reset); // lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx); +// +// Sound Status +// + +boolean S_SoundDisabled(void); + // // Start sound for thing at using from sounds.h // @@ -164,6 +173,7 @@ boolean S_MIDIMusicDisabled(void); boolean S_MusicDisabled(void); boolean S_MusicPlaying(void); boolean S_MusicPaused(void); +boolean S_MusicNotInFocus(void); musictype_t S_MusicType(void); const char *S_MusicName(void); boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index f5c7e3714..5d7a1d7b8 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -584,7 +584,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { // Tell game we lost focus, pause music window_notinfocus = true; - S_PauseAudio(); + if (! cv_playmusicifunfocused.value) + S_PauseAudio(); + if (! cv_playsoundsifunfocused.value) + S_StopSounds(); if (!disable_mouse) { From 48173beb3543b36efc0e8bc666e2619472b8d2db Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 23 Oct 2019 17:31:10 -0700 Subject: [PATCH 117/130] Menu options --- src/m_menu.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index c0b02a5b7..a0340c9d1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1323,22 +1323,25 @@ static menuitem_t OP_OpenGLColorMenu[] = static menuitem_t OP_SoundOptionsMenu[] = { - {IT_HEADER, NULL, "Game Audio", NULL, 0}, // 0 // ScrollMenu offsets - {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 13}, // 6 - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 23}, // 11 + {IT_HEADER, NULL, "Game Audio", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 6}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 11}, - {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 43}, // 21 - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 53}, // 26 + {IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 21}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 26}, - {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 73}, // 36 - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 83}, // 41 + {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41}, - {IT_HEADER, NULL, "Accessibility", NULL, 103}, // 50 - {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 115}, // 56 - {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 125}, // 62 + {IT_HEADER, NULL, "Accessibility", NULL, 50}, + {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 56}, + {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 61}, + + {IT_STRING | IT_CVAR, NULL, "Play Sound Effects if Unfocused", &cv_playsoundsifunfocused, 71}, + {IT_STRING | IT_CVAR, NULL, "Play Music if Unfocused", &cv_playmusicifunfocused, 76}, #ifdef HAVE_MIXERX - {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 143}, + {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 94}, #endif }; @@ -1961,18 +1964,9 @@ menu_t OP_ColorOptionsDef = 0, NULL }; -menu_t OP_SoundOptionsDef = -{ +menu_t OP_SoundOptionsDef = DEFAULTSCROLLMENUSTYLE( MN_OP_MAIN + (MN_OP_SOUND << 6), - "M_SOUND", - sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t), - &OP_MainDef, - OP_SoundOptionsMenu, - M_DrawGenericMenu, - 30, 30, - 0, - NULL -}; + "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); #ifdef HAVE_MIXERX menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); #endif From c970911ac253b1fbbf377589df8dd13d23d26202 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 23 Oct 2019 17:37:09 -0700 Subject: [PATCH 118/130] The console sucks, so "Don't" becomes "No" :lancer: --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0ea4ec83f..37c4a72b1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2969,7 +2969,7 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, N consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "Don't"}, {0, NULL}}; +static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}}; consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; From a215eeabf06ec8f66e352590bf002c84bef32e87 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 18:51:12 +0100 Subject: [PATCH 119/130] * Fix Super players who die being eternally super. * Fix music stack corruption in multiplayer where a super player dies and it's not you. * Fix players in minecarts having their state eternally set to S_PLAY_STND (bug discovered/evident while super, so goes in this branch). Resolves #259. --- src/p_inter.c | 22 ++++++++++++++++++++++ src/p_user.c | 22 ++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index cce9df91b..c960ae31a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2468,6 +2468,28 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; P_SetThingPosition(target); + if (target->player->powers[pw_super]) + { + target->player->powers[pw_super] = 0; + if (P_IsLocalPlayer(target->player)) + { + music_stack_noposition = true; // HACK: Do not reposition next music + music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music + } + P_RestoreMusic(target->player); + + if (gametype != GT_COOP) + { + HU_SetCEchoFlags(0); + HU_SetCEchoDuration(5); + HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[target->player-players])); + } + } + + target->color = target->player->skincolor; + target->colorized = false; + G_GhostAddColor(GHC_NORMAL); + if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0)) ; else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != INFLIVES) diff --git a/src/p_user.c b/src/p_user.c index e572e771b..62f797c46 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4156,8 +4156,11 @@ static void P_DoSuperStuff(player_t *player) { player->powers[pw_super] = 0; P_SetPlayerMobjState(player->mo, S_PLAY_STND); - music_stack_noposition = true; // HACK: Do not reposition next music - music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music + if (P_IsLocalPlayer(player)) + { + music_stack_noposition = true; // HACK: Do not reposition next music + music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music + } P_RestoreMusic(player); P_SpawnShieldOrb(player); @@ -4226,7 +4229,7 @@ static void P_DoSuperStuff(player_t *player) if (gametype != GT_COOP) player->powers[pw_flashing] = flashingtics-1; - if ((player->mo->health > 0) && (player->mo->sprite2 & FF_SPR2SUPER)) + if (player->mo->sprite2 & FF_SPR2SUPER) P_SetPlayerMobjState(player->mo, player->mo->state-states); // Inform the netgame that the champion has fallen in the heat of battle. @@ -4239,8 +4242,11 @@ static void P_DoSuperStuff(player_t *player) } // Resume normal music if you're the console player - music_stack_noposition = true; // HACK: Do not reposition next music - music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music + if (P_IsLocalPlayer(player)) + { + music_stack_noposition = true; // HACK: Do not reposition next music + music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music + } P_RestoreMusic(player); // If you had a shield, restore its visual significance. @@ -10674,7 +10680,11 @@ static void P_MinecartThink(player_t *player) } } - P_SetPlayerMobjState(player->mo, S_PLAY_STND); + if (player->mo->state-states != S_PLAY_STND) + { + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + player->mo->tics = -1; + } // Move player to minecart. P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT); From 989e089e0af5ce8de1e8e722e40d314bf5b2c60c Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 19:00:54 +0100 Subject: [PATCH 120/130] resolve #263 (this is going into master because it's literally just the line being present twice) --- src/p_inter.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index cce9df91b..80140d49d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1493,8 +1493,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetMobjState(mo2, mo2->info->painstate); } } - - S_StartSound(toucher, special->info->painsound); return; case MT_FAKEMOBILE: From 527254584d6859b68b09dff72849c1eca783093d Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 19:16:53 +0100 Subject: [PATCH 121/130] Disable tailsbot in NiGHTS maps, not just Special Stages. (Resolves #261) --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1e69d371e..385e2295d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1692,7 +1692,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese // Kick bot from special stages if (botskin) { - if (G_IsSpecialStage(mapnum)) + if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS))) { if (botingame) { From ea0fe50f5a7923bf8683daa4e73f0a84a771c074 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 19:33:03 +0100 Subject: [PATCH 122/130] Fix CEZ3's first phase being cheated by Fang. --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index f1dc5d760..650d0f561 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4929,6 +4929,7 @@ static void P_Boss4Thinker(mobj_t *mobj) mobj->movecount += mobj->threshold; if (mobj->movecount <= 0) { + mobj->flags2 &= ~MF2_INVERTAIMABLE; mobj->movecount = 0; mobj->movedir++; // Initialization complete, next phase! } @@ -10308,6 +10309,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->movefactor = -512*FRACUNIT; mobj->flags2 |= MF2_CLASSICPUSH; break; + case MT_EGGMOBILE4: + mobj->flags2 |= MF2_INVERTAIMABLE; + break; case MT_FLICKY_08: mobj->color = (P_RandomChance(FRACUNIT/2) ? SKINCOLOR_RED : SKINCOLOR_AQUA); break; From 4ff46d14dd936e5a997ee48b4ac284e9371c86f3 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 19:55:02 +0100 Subject: [PATCH 123/130] Added an experiment with an alternate CEZ3 pinch behaviour (but keep it disabled because it was kind of boring). --- src/p_mobj.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 650d0f561..d612bbbec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4716,13 +4716,17 @@ static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz) } } +#define CEZ3TILT + // Pull them closer. static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz) { INT32 s; mobj_t *base = mobj, *seg; - fixed_t originx, originy, workx, worky, dx, dy, bz = mobj->watertop+(8<watertop+(8<spawnpoint) { originx = mobj->spawnpoint->x << FRACBITS; @@ -4733,13 +4737,25 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz) originx = mobj->x; originy = mobj->y; } +#else + if (mobj->spawnpoint) + { + rad -= R_PointToDist2(mobj->x, mobj->y, + (mobj->spawnpoint->x<spawnpoint->y<tracer)) // there are 10 per spoke, remember that { - dx = (originx + P_ReturnThrustX(mobj, angle, (9*132)<x)/9; - dy = (originy + P_ReturnThrustY(mobj, angle, (9*132)<y)/9; +#ifdef CEZ3TILT + dx = (originx + P_ReturnThrustX(mobj, angle, rad) - mobj->x)/9; + dy = (originy + P_ReturnThrustY(mobj, angle, rad) - mobj->y)/9; +#else + dx = P_ReturnThrustX(mobj, angle, rad)/9; + dy = P_ReturnThrustY(mobj, angle, rad)/9; +#endif workx = mobj->x + P_ReturnThrustX(mobj, angle, (112)<y + P_ReturnThrustY(mobj, angle, (112)<hnext, --s) From d89d8acc59f530ddbbd3839492dffd80937d453c Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 20:40:03 +0100 Subject: [PATCH 124/130] I can't figure out how to make this consistent at all, so in order to have the water look good in levels designed for it, I think it's necessary to effectively revert everything with SHITPLANESPARENCY to a roughly 2.1-equivalent behaviour. --- src/r_plane.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/r_plane.c b/src/r_plane.c index 34debeea7..481af3913 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -44,6 +44,9 @@ // Quincunx antialiasing of flats! //#define QUINCUNX +// good night sweet prince +#define SHITPLANESPARENCY + //SoM: 3/23/2000: Use Boom visplane hashing. visplane_t *visplanes[MAXVISPLANES]; @@ -868,7 +871,11 @@ void R_DrawSinglePlane(visplane_t *pl) else // Opaque, but allow transparent flat pixels spanfunc = splatfunc; +#ifdef SHITPLANESPARENCY + if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4))) +#else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) +#endif light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = LIGHTLEVELS-1; @@ -922,7 +929,11 @@ void R_DrawSinglePlane(visplane_t *pl) else // Opaque, but allow transparent flat pixels spanfunc = splatfunc; +#ifdef SHITPLANESPARENCY + if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4))) +#else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) +#endif light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = LIGHTLEVELS-1; From 630bdaa876991d1aecab8de59f3b706335d3d463 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 24 Oct 2019 21:14:51 +0100 Subject: [PATCH 125/130] Move INLEVEL macros for mobj_get and mobj_set to prevent mixed code/declaration errors. --- src/lua_mobjlib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 2cb9dc329..30026da49 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -160,11 +160,12 @@ static const char *const mobj_opt[] = { static int mobj_get(lua_State *L) { - INLEVEL mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); enum mobj_e field = Lua_optoption(L, 2, NULL, mobj_opt); lua_settop(L, 2); + INLEVEL + if (!mo) { if (field == mobj_valid) { lua_pushboolean(L, 0); @@ -406,11 +407,12 @@ static int mobj_get(lua_State *L) #define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_TeleportMove") " instead.", mobj_opt[field]) static int mobj_set(lua_State *L) { - INLEVEL mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt); lua_settop(L, 3); + INLEVEL + if (!mo) return LUA_ErrInvalid(L, "mobj_t"); From d5b1467e79330301cd9394da5199e3b994da5d56 Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 25 Oct 2019 18:48:40 +0800 Subject: [PATCH 126/130] Put player in jump state after spinning during a wall transfer --- src/p_mobj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index f1dc5d760..60ba7ed2d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1990,6 +1990,8 @@ void P_XYMovement(mobj_t *mo) { mo->momz = transfermomz; mo->standingslope = NULL; + if (player->pflags & PF_SPINNING) + player->pflags = (player->pflags & ~PF_SPINNING) | (P_GetJumpFlags(player) | PF_THOKKED); } } #endif From 2d458059c87a52c6d207dad4a18d842a6451dadb Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 25 Oct 2019 18:51:41 +0800 Subject: [PATCH 127/130] Don't fuck nojumpspin characters who are capable of rolling --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 60ba7ed2d..1c6e3a7b4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1991,7 +1991,7 @@ void P_XYMovement(mobj_t *mo) mo->momz = transfermomz; mo->standingslope = NULL; if (player->pflags & PF_SPINNING) - player->pflags = (player->pflags & ~PF_SPINNING) | (P_GetJumpFlags(player) | PF_THOKKED); + player->pflags = (player->pflags & ~PF_SPINNING) | (PF_JUMPED | PF_THOKKED); } } #endif From 863101824aefc0799b9b32f7ad1c8dc9f29e1393 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 25 Oct 2019 20:17:50 +0200 Subject: [PATCH 128/130] Removed palm tree trunks from the ZB config. They no longer exist as mapthings. --- extras/conf/SRB2-22.cfg | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index edd5be442..f1e8481eb 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -5622,13 +5622,6 @@ thingtypes title = "BSZ Clover"; sprite = "BSZ8B0"; } - 1472 - { - title = "Palm Tree Trunk (Big)"; - width = 16; - height = 160; - sprite = "BSZ8C0"; - } 1473 { title = "Palm Tree Leaves (Big)"; @@ -5636,13 +5629,6 @@ thingtypes height = 160; sprite = "BSZ8D0"; } - 1474 - { - title = "Palm Tree Trunk (Small)"; - width = 8; - height = 80; - sprite = "BSZ8E0"; - } 1475 { title = "Palm Tree Leaves (Small)"; From 53ac815334e1970b81001b5397644eedd4cc4c15 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 25 Oct 2019 20:48:51 +0200 Subject: [PATCH 129/130] ...and also rename the palm tree leaves accordingly --- extras/conf/SRB2-22.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index f1e8481eb..a06b1a29d 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -5624,14 +5624,14 @@ thingtypes } 1473 { - title = "Palm Tree Leaves (Big)"; + title = "Palm Tree (Big)"; width = 16; height = 160; sprite = "BSZ8D0"; } 1475 { - title = "Palm Tree Leaves (Small)"; + title = "Palm Tree (Small)"; width = 16; height = 80; sprite = "BSZ8F0"; From 46d105dd53197812129e10b628dd15611fd4d7ac Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 25 Oct 2019 22:55:10 +0200 Subject: [PATCH 130/130] Some basic code hygiene: Remove references to the air bob code being "old" or "outdated" --- src/p_spec.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 1ec1c3021..2a138f42a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5984,8 +5984,6 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) * to the lowest nearby height if not * there already. * - * Replaces the old "AirBob". - * * \param sec Control sector. * \param actionsector Target sector. * \param sourceline Control linedef. @@ -6030,8 +6028,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) raise->sourceline = sourceline; } -// Function to maintain backwards compatibility -static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic) +static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic) { levelspecthink_t *airbob; @@ -6893,16 +6890,16 @@ void P_SpawnSpecials(INT32 fromnetsave) case 151: // Adjustable air bobbing platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false); + P_AddAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false); break; case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, true, false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, false, true); + P_AddAirbob(lines[i].frontsector, lines + i, false, true); break; case 160: // Float/bob platform @@ -6953,14 +6950,14 @@ void P_SpawnSpecials(INT32 fromnetsave) case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, true, false); break; case 177: // Air bobbing platform that will crumble and bob on // the water when it falls and hits, then never return P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, true, false); break; case 178: // Crumbling platform that will float when it hits water @@ -6974,7 +6971,7 @@ void P_SpawnSpecials(INT32 fromnetsave) case 180: // Air bobbing platform that will crumble P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddOldAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, true, false); break; case 190: // Rising Platform FOF (solid, opaque, shadows)