diff --git a/src/console.c b/src/console.c index b9a01492f..c1c5557b9 100644 --- a/src/console.c +++ b/src/console.c @@ -127,8 +127,6 @@ static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"} // whether to use console background picture, or translucent mode static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -// \todo SRB2-CHAT 2.1 colors -- pending translation to 2.2 palette indexes -#if 0 static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, {2, "Sepia"}, {3, "Brown"}, {4, "Pink"}, {5, "Raspberry"}, {6, "Red"}, {7, "Creamsicle"}, {8, "Orange"}, @@ -137,13 +135,7 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, { {15,"Periwinkle"}, {16,"Blue"}, {17,"Purple"}, {18,"Lavender"}, {0, NULL}}; -#else -static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, "Brown"}, - {3, "Red"}, {4, "Orange"}, {5, "Yellow"}, - {6, "Green"}, {7, "Blue"}, {8, "Purple"}, - {9, "Magenta"}, {10, "Aqua"}, - {0, NULL}}; -#endif + consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; @@ -256,50 +248,30 @@ void CON_SetupBackColormapEx(INT32 color, boolean prompt) shift = 6; // 12 colors -- shift of 7 means 6 colors - // \todo SRB2-CHAT colors, pending translation to 2.2 palette indexes -#if 0 switch (color) { case 0: palindex = 15; break; // White - case 1: palindex = 31; break; // Gray - case 2: palindex = 47; break; // Sepia - case 3: palindex = 63; break; // Brown - case 4: palindex = 150; shift = 7; break; // Pink - case 5: palindex = 127; shift = 7; break; // Raspberry - case 6: palindex = 143; break; // Red - case 7: palindex = 86; shift = 7; break; // Creamsicle - case 8: palindex = 95; break; // Orange - case 9: palindex = 119; shift = 7; break; // Gold - case 10: palindex = 111; break; // Yellow - case 11: palindex = 191; shift = 7; break; // Emerald - case 12: palindex = 175; break; // Green - case 13: palindex = 219; break; // Cyan - case 14: palindex = 207; shift = 7; break; // Steel - case 15: palindex = 230; shift = 7; break; // Periwinkle - case 16: palindex = 239; break; // Blue - case 17: palindex = 199; shift = 7; break; // Purple - case 18: palindex = 255; shift = 7; break; // Lavender + case 1: palindex = 31; break; // Black + case 2: palindex = 251; break; // Sepia + case 3: palindex = 239; break; // Brown + case 4: palindex = 215; shift = 7; break; // Pink + case 5: palindex = 37; shift = 7; break; // Raspberry + case 6: palindex = 47; shift = 7; break; // Red + case 7: palindex = 53; shift = 7; break; // Creamsicle + case 8: palindex = 63; break; // Orange + case 9: palindex = 56; shift = 7; break; // Gold + case 10: palindex = 79; shift = 7; break; // Yellow + case 11: palindex = 119; shift = 7; break; // Emerald + case 12: palindex = 111; break; // Green + case 13: palindex = 136; shift = 7; break; // Cyan + case 14: palindex = 175; shift = 7; break; // Steel + case 15: palindex = 166; shift = 7; break; // Periwinkle + case 16: palindex = 159; break; // Blue + case 17: palindex = 187; shift = 7; break; // Purple + case 18: palindex = 199; shift = 7; break; // Lavender // Default green - default: palindex = 175; break; + default: palindex = 111; break; } -#else - switch (color) - { - case 0: palindex = 15; break; // White - case 1: palindex = 31; break; // Gray - case 2: palindex = 239; break; // Brown - case 3: palindex = 47; break; // Red - case 4: palindex = 63; break; // Orange - case 5: palindex = 79; shift = 7; break; // Yellow - case 6: palindex = 111; break; // Green - case 7: palindex = 159; break; // Blue - case 8: palindex = 199; shift = 7; break; // Purple - case 9: palindex = 187; break; // Magenta - case 10: palindex = 139; break; // Aqua - // Default green - default: palindex = 175; color = 11; break; - } -#endif if (prompt) { diff --git a/src/d_clisrv.c b/src/d_clisrv.c index dbf70d33a..bd9158468 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4270,16 +4270,13 @@ static INT16 Consistancy(void) ret += P_GetRandSeed(); #ifdef MOBJCONSISTANCY - if (!thinkercap.next) + if (!thlist[THINK_MOBJ].next) { DEBFILE(va("Consistancy = %u\n", ret)); return ret; } - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - 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 fbdf60bae..5e070dcd7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4260,9 +4260,8 @@ static void Command_Archivetest_f(void) // assign mobjnum i = 1; - for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - ((mobj_t *)th)->mobjnum = i++; + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + ((mobj_t *)th)->mobjnum = i++; // allocate buffer buf = save_p = ZZ_Alloc(1024); diff --git a/src/dehacked.c b/src/dehacked.c index f532bde68..3cce03c6b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1793,15 +1793,23 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) if (i == 0 || fastcmp(word2, "WHITE")) backcolor = 0; else if (i == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY") || fastcmp(word2, "BLACK")) backcolor = 1; - else if (i == 2 || fastcmp(word2, "BROWN")) backcolor = 2; - else if (i == 3 || fastcmp(word2, "RED")) backcolor = 3; - else if (i == 4 || fastcmp(word2, "ORANGE")) backcolor = 4; - else if (i == 5 || fastcmp(word2, "YELLOW")) backcolor = 5; - else if (i == 6 || fastcmp(word2, "GREEN")) backcolor = 6; - else if (i == 7 || fastcmp(word2, "BLUE")) backcolor = 7; - else if (i == 8 || fastcmp(word2, "PURPLE")) backcolor = 8; - else if (i == 9 || fastcmp(word2, "MAGENTA")) backcolor = 9; - else if (i == 10 || fastcmp(word2, "AQUA")) backcolor = 10; + else if (i == 2 || fastcmp(word2, "SEPIA")) backcolor = 2; + else if (i == 3 || fastcmp(word2, "BROWN")) backcolor = 3; + else if (i == 4 || fastcmp(word2, "PINK")) backcolor = 4; + else if (i == 5 || fastcmp(word2, "RASPBERRY")) backcolor = 5; + else if (i == 6 || fastcmp(word2, "RED")) backcolor = 6; + else if (i == 7 || fastcmp(word2, "CREAMSICLE")) backcolor = 7; + else if (i == 8 || fastcmp(word2, "ORANGE")) backcolor = 8; + else if (i == 9 || fastcmp(word2, "GOLD")) backcolor = 9; + else if (i == 10 || fastcmp(word2, "YELLOW")) backcolor = 10; + else if (i == 11 || fastcmp(word2, "EMERALD")) backcolor = 11; + else if (i == 12 || fastcmp(word2, "GREEN")) backcolor = 12; + else if (i == 13 || fastcmp(word2, "CYAN") || fastcmp(word2, "AQUA")) backcolor = 13; + else if (i == 14 || fastcmp(word2, "STEEL")) backcolor = 14; + else if (i == 15 || fastcmp(word2, "PERIWINKLE")) backcolor = 15; + else if (i == 16 || fastcmp(word2, "BLUE")) backcolor = 16; + else if (i == 17 || fastcmp(word2, "PURPLE")) backcolor = 17; + else if (i == 18 || fastcmp(word2, "LAVENDER")) backcolor = 18; else if (i < 0) backcolor = INT32_MAX; // CONS_BACKCOLOR user-configured else backcolor = 1; // default gray textprompts[num]->page[pagenum].backcolor = backcolor; @@ -8766,10 +8774,8 @@ struct { #endif #ifdef ESLOPE // Slope flags - {"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope - {"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it - {"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position - {"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things + {"SL_NOPHYSICS",SL_NOPHYSICS}, + {"SL_DYNAMIC",SL_DYNAMIC}, #endif // Angles diff --git a/src/doomstat.h b/src/doomstat.h index 06dfcca0b..87b98ab40 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -146,6 +146,7 @@ extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor extern tic_t countdowntimer; extern boolean countdowntimeup; +extern boolean exitfadestarted; typedef struct { diff --git a/src/f_finale.c b/src/f_finale.c index df8d7b683..5b21ad95a 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1421,7 +1421,7 @@ void F_InitMenuPresValues(void) curbgcolor = -1; curbgxspeed = titlescrollxspeed; curbgyspeed = titlescrollyspeed; - curbghide = false; + curbghide = true; // Find current presentation values M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "SRB2BACK" : "TITLESKY"); @@ -1692,11 +1692,8 @@ void F_TitleScreenTicker(boolean run) // If there's a Line 422 Switch Cut-Away view, don't force us. if (!titlemapcameraref || titlemapcameraref->type != MT_ALTVIEWMAN) { - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; if (!mo2) diff --git a/src/g_game.c b/src/g_game.c index 632e33009..f963cae35 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -146,6 +146,7 @@ UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; tic_t countdowntimer = 0; boolean countdowntimeup = false; +boolean exitfadestarted = false; cutscene_t *cutscenes[128]; textprompt_t *textprompts[MAX_PROMPTS]; @@ -2564,11 +2565,8 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) I_Assert((oldmo != NULL) && (newmo != NULL)); // scan all thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (!(mo2->flags & MF_MISSILE)) @@ -3877,7 +3875,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean { // Clear a bunch of variables numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; - countdown = countdown2 = 0; + countdown = countdown2 = exitfadestarted = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -4466,10 +4464,8 @@ void G_ConsGhostTic(void) demo_p += sizeof(angle_t); // angle, unnecessary for cons. mobj = NULL; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; mobj = (mobj_t *)th; if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) break; @@ -5862,11 +5858,8 @@ void G_DoPlayMetal(void) metalbuffer = metal_p = W_CacheLumpNum(l, PU_STATIC); // find metal sonic - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo = (mobj_t *)th; if (mo->type != MT_METALSONIC_RACE) continue; diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index d59821595..77b29a9c0 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1362,12 +1362,8 @@ static void HWR_SearchLightsInMobjs(void) //mobj_t * mobj; // search in the list of thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) - { - // a mobj ? - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - HWR_AddMobjLights((mobj_t *)th); - } + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + HWR_AddMobjLights((mobj_t *)th); } #endif diff --git a/src/info.c b/src/info.c index 477c3f372..ed990f8b9 100644 --- a/src/info.c +++ b/src/info.c @@ -19515,7 +19515,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/lua_maplib.c b/src/lua_maplib.c index c5555009f..ded90daf0 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -292,8 +292,6 @@ enum slope_e { slope_normal, slope_zangle, slope_xydirection, - slope_sourceline, - slope_refpos, slope_flags }; @@ -305,8 +303,6 @@ static const char *const slope_opt[] = { "normal", "zangle", "xydirection", - "sourceline", - "refpos", "flags", NULL}; @@ -1831,12 +1827,6 @@ static int slope_get(lua_State *L) case slope_xydirection: // xydirection lua_pushangle(L, slope->xydirection); return 1; - case slope_sourceline: // source linedef - LUA_PushUserdata(L, slope->sourceline, META_LINE); - return 1; - case slope_refpos: // refpos - lua_pushinteger(L, slope->refpos); - return 1; case slope_flags: // flags lua_pushinteger(L, slope->flags); return 1; @@ -1858,11 +1848,9 @@ static int slope_set(lua_State *L) switch(field) // todo: reorganize this shit { case slope_valid: // valid - case slope_sourceline: // sourceline case slope_d: // d case slope_flags: // flags case slope_normal: // normal - case slope_refpos: // refpos default: return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]); case slope_o: { // o diff --git a/src/lua_script.c b/src/lua_script.c index 04aa55cf0..85b9c4038 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -420,9 +420,9 @@ void LUA_InvalidateLevel(void) ffloor_t *rover = NULL; if (!gL) return; - - for (th = thinkercap.next; th && th != &thinkercap; th = th->next) - LUA_InvalidateUserdata(th); + for (i = 0; i < NUM_THINKERLISTS; i++) + for (th = thlist[i].next; th && th != &thlist[i]; th = th->next) + LUA_InvalidateUserdata(th); LUA_InvalidateMapthings(); @@ -1127,13 +1127,15 @@ void LUA_Archive(void) ArchiveExtVars(&players[i], "player"); } - for (th = thinkercap.next; th != &thinkercap; 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 (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"); + } + WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. LUAh_NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode @@ -1161,9 +1163,10 @@ void LUA_UnArchive(void) do { mobjnum = READUINT32(save_p); // read a mobjnum - for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker - && ((mobj_t *)th)->mobjnum == mobjnum) // find matching mobj + 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 } while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker. diff --git a/src/lua_thinkerlib.c b/src/lua_thinkerlib.c index ae648613a..63eb15846 100644 --- a/src/lua_thinkerlib.c +++ b/src/lua_thinkerlib.c @@ -18,7 +18,7 @@ #define META_ITERATIONSTATE "iteration state" -static const char *const iter_opt[] = { +/*static const char *const iter_opt[] = { "all", "mobj", NULL}; @@ -26,7 +26,7 @@ static const char *const iter_opt[] = { static const actionf_p1 iter_funcs[] = { NULL, (actionf_p1)P_MobjThinker -}; +};*/ struct iterationState { actionf_p1 filter; @@ -64,7 +64,7 @@ static int lib_iterateThinkers(lua_State *L) lua_settop(L, 2); if (lua_isnil(L, 2)) - th = &thinkercap; + th = &thlist[THINK_MOBJ]; else if (lua_isuserdata(L, 2)) { if (lua_islightuserdata(L, 2)) @@ -94,11 +94,11 @@ static int lib_iterateThinkers(lua_State *L) if (!next) return luaL_error(L, "next thinker invalidated during iteration"); - for (; next != &thinkercap; next = next->next) + for (; next != &thlist[THINK_MOBJ]; next = next->next) if (!it->filter || next->function.acp1 == it->filter) { push_thinker(next); - if (next->next != &thinkercap) + if (next->next != &thlist[THINK_MOBJ]) { push_thinker(next->next); it->next = luaL_ref(L, LUA_REGISTRYINDEX); @@ -120,7 +120,7 @@ static int lib_startIterate(lua_State *L) luaL_getmetatable(L, META_ITERATIONSTATE); lua_setmetatable(L, -2); - it->filter = iter_funcs[luaL_checkoption(L, 1, "mobj", iter_opt)]; + it->filter = (actionf_p1)P_MobjThinker; //iter_funcs[luaL_checkoption(L, 1, "mobj", iter_opt)]; it->next = LUA_REFNIL; return 2; } @@ -138,7 +138,7 @@ int LUA_ThinkerLib(lua_State *L) lua_pushcfunction(L, lib_iterateThinkers); lua_pushcclosure(L, lib_startIterate, 1); lua_setfield(L, -2, "iterate"); - lua_setglobal(L, "thinkers"); + lua_setglobal(L, "mobjs"); return 0; } diff --git a/src/m_cheat.c b/src/m_cheat.c index bee60087f..734a7ae18 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -577,11 +577,8 @@ void Command_Teleport_f(void) INT32 starpostmax = 0; intz = starpostpath; // variable reuse - counting down for selection purposes - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_STARPOST) @@ -600,7 +597,7 @@ void Command_Teleport_f(void) break; } - if (th == &thinkercap) + if (th == &thlist[THINK_MOBJ]) { if (intz == starpostpath) CONS_Alert(CONS_NOTICE, M_GetText("No starpost of position %d found (%d max).\n"), starpostnum, starpostmax); @@ -1069,11 +1066,8 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c thinker_t *th; mobj_t *mo; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo = (mobj_t *)th; // get offset from mt, which points to old mapthings, then add new location if (mo->spawnpoint) diff --git a/src/m_menu.c b/src/m_menu.c index 230e0590d..cebdd1bbd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2200,6 +2200,7 @@ void M_InitMenuPresTables(void) menupres[i].bgcolor = -1; menupres[i].titlescrollxspeed = INT32_MAX; menupres[i].titlescrollyspeed = INT32_MAX; + menupres[i].bghide = true; // default true menupres[i].enterbubble = true; menupres[i].exitbubble = true; @@ -2468,7 +2469,7 @@ static void M_HandleMenuPresState(menu_t *newMenu) curbgcolor = -1; curbgxspeed = titlescrollxspeed; curbgyspeed = titlescrollyspeed; - curbghide = false; + curbghide = true; // don't do the below during the in-game menus if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 757edebae..5395f618c 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -409,7 +409,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) // new door thinker rtn = 1; ceiling = Z_Calloc(sizeof (*ceiling), PU_LEVSPEC, NULL); - P_AddThinker(&ceiling->thinker); + P_AddThinker(THINK_MAIN, &ceiling->thinker); sec->ceilingdata = ceiling; ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; ceiling->sector = sec; @@ -629,7 +629,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type) // new door thinker rtn = 1; ceiling = Z_Calloc(sizeof (*ceiling), PU_LEVSPEC, NULL); - P_AddThinker(&ceiling->thinker); + P_AddThinker(THINK_MAIN, &ceiling->thinker); sec->ceilingdata = ceiling; ceiling->thinker.function.acp1 = (actionf_p1)T_CrushCeiling; ceiling->sector = sec; diff --git a/src/p_enemy.c b/src/p_enemy.c index 23c9b88fc..f49d60f0d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3766,11 +3766,8 @@ void A_BossDeath(mobj_t *mo) // scan the remaining thinkers to see // if all bosses are dead - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - 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! @@ -3867,11 +3864,8 @@ bossjustdie: // Flee! Flee! Find a point to escape to! If none, just shoot upward! // scan the thinkers to find the runaway point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_BOSSFLYPOINT) @@ -6123,11 +6117,8 @@ void A_RingExplode(mobj_t *actor) S_StartSound(actor, sfx_prloop); - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2 == actor) // Don't explode yourself! Endless loop! @@ -7819,11 +7810,8 @@ void A_Boss3Path(mobj_t *actor) // scan the thinkers // to find a point that matches // the number - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && mo2->spawnpoint->angle == actor->threshold) { @@ -8212,11 +8200,8 @@ void A_FindTarget(mobj_t *actor) CONS_Debug(DBG_GAMELOGIC, "A_FindTarget called from object type %d, var1: %d, var2: %d\n", actor->type, locvar1, locvar2); // scan the thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)locvar1) @@ -8277,11 +8262,8 @@ void A_FindTracer(mobj_t *actor) CONS_Debug(DBG_GAMELOGIC, "A_FindTracer called from object type %d, var1: %d, var2: %d\n", actor->type, locvar1, locvar2); // scan the thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)locvar1) @@ -8840,11 +8822,8 @@ void A_RemoteAction(mobj_t *actor) fixed_t dist1 = 0, dist2 = 0; // scan the thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)locvar1) @@ -9106,11 +9085,8 @@ void A_SetObjectTypeState(mobj_t *actor) return; #endif - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)loc2lw) @@ -9744,11 +9720,8 @@ void A_CheckThingCount(mobj_t *actor) return; #endif - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)loc1up) @@ -13023,7 +12996,14 @@ static boolean PIT_TNTExplode(mobj_t *nearby) nearby->momx = FixedMul(FixedDiv(dx, dm), explodethrust); nearby->momy = FixedMul(FixedDiv(dy, dm), explodethrust); nearby->momz = FixedMul(FixedDiv(dz, dm), explodethrust); + P_UnsetThingPosition(nearby); + if (sector_list) + { + P_DelSeclist(sector_list); + sector_list = NULL; + } nearby->flags = MF_NOBLOCKMAP|MF_MISSILE; + P_SetThingPosition(nearby); P_SetMobjState(nearby, nearby->info->missilestate); } } @@ -13067,8 +13047,14 @@ void A_TNTExplode(mobj_t *actor) if (LUA_CallAction("A_TNTExplode", actor)) return; #endif - + P_UnsetThingPosition(actor); + if (sector_list) + { + P_DelSeclist(sector_list); + sector_list = NULL; + } actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; + P_SetThingPosition(actor); actor->flags2 = MF2_EXPLOSION; if (actor->info->deathsound) S_StartSound(actor, actor->info->deathsound); diff --git a/src/p_floor.c b/src/p_floor.c index a1b1c45fc..4a03f70c0 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1981,11 +1981,8 @@ void T_ThwompSector(levelspecthink_t *thwomp) if (!rover || (rover->flags & FF_EXISTS)) { // scan the thinkers to find players! - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo = (mobj_t *)th; if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator && mo->z <= thwomp->sector->ceilingheight @@ -2701,7 +2698,7 @@ INT32 EV_DoFloor(line_t *line, floor_e floortype) // new floor thinker rtn = 1; dofloor = Z_Calloc(sizeof (*dofloor), PU_LEVSPEC, NULL); - P_AddThinker(&dofloor->thinker); + P_AddThinker(THINK_MAIN, &dofloor->thinker); // make sure another floor thinker won't get started over this one sec->floordata = dofloor; @@ -2922,7 +2919,7 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) // create and initialize new elevator thinker rtn = 1; elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(&elevator->thinker); + P_AddThinker(THINK_MAIN, &elevator->thinker); sec->floordata = elevator; sec->ceilingdata = elevator; elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator; @@ -3149,7 +3146,7 @@ INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) return 0; bouncer = Z_Calloc(sizeof (*bouncer), PU_LEVSPEC, NULL); - P_AddThinker(&bouncer->thinker); + P_AddThinker(THINK_MAIN, &bouncer->thinker); sec->ceilingdata = bouncer; bouncer->thinker.function.acp1 = (actionf_p1)T_BounceCheese; @@ -3183,7 +3180,7 @@ INT32 EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, bool // create and initialize new thinker faller = Z_Calloc(sizeof (*faller), PU_LEVSPEC, NULL); - P_AddThinker(&faller->thinker); + P_AddThinker(THINK_MAIN, &faller->thinker); faller->thinker.function.acp1 = (actionf_p1)T_ContinuousFalling; // set up the fields @@ -3232,7 +3229,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, // create and initialize new elevator thinker elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(&elevator->thinker); + P_AddThinker(THINK_MAIN, &elevator->thinker); elevator->thinker.function.acp1 = (actionf_p1)T_StartCrumble; // Does this crumbler return? @@ -3311,7 +3308,7 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) // create and initialize new elevator thinker block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); - P_AddThinker(&block->thinker); + P_AddThinker(THINK_MAIN, &block->thinker); roversec->floordata = block; roversec->ceilingdata = block; block->thinker.function.acp1 = (actionf_p1)T_MarioBlock; diff --git a/src/p_inter.c b/src/p_inter.c index 3348696c0..cf2efe54d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -97,11 +97,8 @@ void P_ClearStarPost(INT32 postnum) mobj_t *mo2; // scan the thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_STARPOST) @@ -126,11 +123,8 @@ void P_ResetStarposts(void) thinker_t *th; mobj_t *post; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - post = (mobj_t *)th; if (post->type == MT_STARPOST) @@ -833,11 +827,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // The player might have two Ideyas: toucher->tracer and toucher->tracer->hnext // so handle their anchorpoints accordingly. // scan the thinkers to find the corresponding anchorpoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_IDEYAANCHOR) @@ -927,11 +918,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) count = 1; // scan the remaining thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2 == special) @@ -977,11 +965,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Now we RE-scan all the thinkers to find close objects to pull // in from the paraloop. Isn't this just so efficient? - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) @@ -1351,11 +1336,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) EV_DoElevator(&junk, bridgeFall, false); // scan the remaining thinkers to find koopa - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_KOOPA) @@ -1451,11 +1433,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) thinker_t *th; mobj_t *mo2; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_STARPOST) @@ -1690,6 +1669,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_CANARIVORE_GAS: // if player and gas touch, attach gas to player (overriding any gas that already attached) and apply slowdown effect + special->flags |= MF_NOGRAVITY|MF_NOCLIPHEIGHT; P_UnsetThingPosition(special); special->x = toucher->x - toucher->momx/2; special->y = toucher->y - toucher->momy/2; @@ -2555,11 +2535,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // 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 = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo = (mobj_t *)th; if (mo->type == (mobjtype_t)target->info->mass && mo->tracer == target) { diff --git a/src/p_lights.c b/src/p_lights.c index 67ec55e80..8459d9ea0 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -76,7 +76,7 @@ fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxse P_RemoveLighting(maxsector); // out with the old, in with the new flick = Z_Calloc(sizeof (*flick), PU_LEVSPEC, NULL); - P_AddThinker(&flick->thinker); + P_AddThinker(THINK_MAIN, &flick->thinker); flick->thinker.function.acp1 = (actionf_p1)T_FireFlicker; flick->sector = maxsector; @@ -155,7 +155,7 @@ void P_SpawnLightningFlash(sector_t *sector) flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); - P_AddThinker(&flash->thinker); + P_AddThinker(THINK_MAIN, &flash->thinker); flash->thinker.function.acp1 = (actionf_p1)T_LightningFlash; flash->sector = sector; @@ -214,7 +214,7 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, P_RemoveLighting(maxsector); // out with the old, in with the new flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); - P_AddThinker(&flash->thinker); + P_AddThinker(THINK_MAIN, &flash->thinker); flash->sector = maxsector; flash->darktime = darktime; @@ -289,7 +289,7 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, P_RemoveLighting(maxsector); // out with the old, in with the new g = Z_Calloc(sizeof (*g), PU_LEVSPEC, NULL); - P_AddThinker(&g->thinker); + P_AddThinker(THINK_MAIN, &g->thinker); g->sector = maxsector; g->minlight = minsector->lightlevel; @@ -349,7 +349,7 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ll->thinker.function.acp1 = (actionf_p1)T_LightFade; sector->lightingdata = ll; // set it to the lightlevel_t - P_AddThinker(&ll->thinker); // add thinker + P_AddThinker(THINK_MAIN, &ll->thinker); // add thinker ll->sector = sector; ll->sourcelevel = sector->lightlevel; diff --git a/src/p_local.h b/src/p_local.h index 8aeddf162..bda6133d5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -61,15 +61,21 @@ #define P_GetPlayerHeight(player) FixedMul(player->height, player->mo->scale) #define P_GetPlayerSpinHeight(player) FixedMul(player->spinheight, player->mo->scale) -// -// P_TICK -// - -// both the head and tail of the thinker list -extern thinker_t thinkercap; +typedef enum{ + THINK_LIMBO, + THINK_POLYOBJ, + THINK_MAIN, + THINK_MOBJ, +#ifdef ESLOPE + THINK_DYNSLOPE, +#endif + THINK_PRECIP, + NUM_THINKERLISTS +} thinklistnum_t; /**< Thinker lists. */ +extern thinker_t thlist[]; void P_InitThinkers(void); -void P_AddThinker(thinker_t *thinker); +void P_AddThinker(const thinklistnum_t n, thinker_t *thinker); void P_RemoveThinker(thinker_t *thinker); // diff --git a/src/p_map.c b/src/p_map.c index 76b6535b5..2364e8107 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4012,7 +4012,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) thinker_t *think; elevator_t *crumbler; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)T_StartCrumble) continue; diff --git a/src/p_mobj.c b/src/p_mobj.c index 70017546c..c9dcff210 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -714,11 +714,8 @@ void P_EmeraldManager(void) spawnpoints[i] = NULL; } - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (mo->type == MT_EMERALDSPAWN) @@ -3695,11 +3692,8 @@ void P_DestroyRobots(void) mobj_t *mo; thinker_t *think; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (mo->health <= 0 || !(mo->flags & (MF_ENEMY|MF_BOSS))) continue; // not a valid enemy @@ -4480,11 +4474,8 @@ static void P_Boss3Thinker(mobj_t *mobj) // scan the thinkers to make sure all the old pinch dummies are gone before making new ones // this can happen if the boss was hurt earlier than expected - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == (mobjtype_t)mobj->info->mass && mo2->tracer == mobj) { @@ -4571,11 +4562,8 @@ static void P_Boss3Thinker(mobj_t *mobj) // scan the thinkers // to find a point that matches // the number - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && mo2->spawnpoint->angle == mobj->threshold) { @@ -5233,11 +5221,8 @@ static void P_Boss7Thinker(mobj_t *mobj) closestdist = INT32_MAX; // Just in case... // Find waypoint he is closest to - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint) { @@ -5288,11 +5273,8 @@ static void P_Boss7Thinker(mobj_t *mobj) // scan the thinkers to find // the waypoint to use - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && (mo2->spawnpoint->options & 7) == waypointNum) { @@ -5420,11 +5402,8 @@ static void P_Boss9Thinker(mobj_t *mobj) // Run through the thinkers ONCE and find all of the MT_BOSS9GATHERPOINT in the map. // Build a hoop linked list of 'em! - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_BOSS9GATHERPOINT) { @@ -5882,11 +5861,8 @@ mobj_t *P_GetClosestAxis(mobj_t *source) fixed_t dist1, dist2 = 0; // scan the thinkers to find the closest axis point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_AXIS) @@ -6583,7 +6559,7 @@ void P_RunOverlays(void) { angle_t viewingangle; - if (players[displayplayer].awayviewtics) + if (players[displayplayer].awayviewtics && players[displayplayer].awayviewmobj != NULL && !P_MobjWasRemoved(players[displayplayer].awayviewmobj)) viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y); else if (!camera.chase && players[displayplayer].mo) viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y); @@ -7327,6 +7303,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_ROCKCRUMBLE14: case MT_ROCKCRUMBLE15: case MT_ROCKCRUMBLE16: + case MT_WOODDEBRIS: if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) && mobj->state != &states[mobj->info->deathstate]) { @@ -8522,7 +8499,6 @@ void P_MobjThinker(mobj_t *mobj) momz = abs(mobj->momz); if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); - mobj->flags |= MF_NOGRAVITY|MF_NOCLIPHEIGHT; mobj->flags2 |= MF2_AMBUSH; break; } @@ -9382,7 +9358,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } if (!(mobj->flags & MF_NOTHINK)) - P_AddThinker(&mobj->thinker); + P_AddThinker(THINK_MOBJ, &mobj->thinker); // Call action functions when the state is set if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC)) @@ -9457,7 +9433,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->momz = mobjinfo[type].speed; mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker; - P_AddThinker(&mobj->thinker); + P_AddThinker(THINK_PRECIP, &mobj->thinker); CalculatePrecipFloor(mobj); @@ -9581,7 +9557,7 @@ void P_RemoveMobj(mobj_t *mobj) else { // Add thinker just to delay removing it until refrences are gone. mobj->flags &= ~MF_NOTHINK; - P_AddThinker((thinker_t *)mobj); + 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)); @@ -9651,7 +9627,7 @@ consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, void P_SpawnPrecipitation(void) { - INT32 i, /*j,*/ mrand; + INT32 i /*, j*/, mrand; fixed_t basex, basey, x, y, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11425,11 +11401,8 @@ ML_EFFECT5 : Don't stop thinking when too far away mobj->health = (mthing->angle / 360) + 1; // See if other starposts exist in this level that have the same value. - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2 == mobj) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index dfa9906ba..09d449b39 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -146,16 +146,6 @@ FUNCINLINE static ATTRINLINE void Polyobj_vecSub2(vertex_t *dst, vertex_t *v1, v dst->y = v1->y - v2->y; } -// Add the polyobject's thinker to the thinker list -// Unlike P_AddThinker, this adds it to the front of the list instead of the back, so that carrying physics can work right. -Red -FUNCINLINE static ATTRINLINE void PolyObj_AddThinker(thinker_t *th) -{ - thinkercap.next->prev = th; - th->next = thinkercap.next; - th->prev = &thinkercap; - thinkercap.next = th; -} - // // P_PointInsidePolyobj // @@ -1518,31 +1508,28 @@ void Polyobj_InitLevel(void) // run down the thinker list, count the number of spawn points, and save // the mobj_t pointers on a queue for use below. - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_MobjThinker) + mobj_t *mo = (mobj_t *)th; + + if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM || + mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM) { - mobj_t *mo = (mobj_t *)th; + ++numPolyObjects; - if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM || - mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM) - { - ++numPolyObjects; + qitem = malloc(sizeof(mobjqitem_t)); + memset(qitem, 0, sizeof(mobjqitem_t)); + qitem->mo = mo; + M_QueueInsert(&(qitem->mqitem), &spawnqueue); + } + else if (mo->info->doomednum == POLYOBJ_ANCHOR_DOOMEDNUM) + { + ++numAnchors; - qitem = malloc(sizeof(mobjqitem_t)); - memset(qitem, 0, sizeof(mobjqitem_t)); - qitem->mo = mo; - M_QueueInsert(&(qitem->mqitem), &spawnqueue); - } - else if (mo->info->doomednum == POLYOBJ_ANCHOR_DOOMEDNUM) - { - ++numAnchors; - - qitem = malloc(sizeof(mobjqitem_t)); - memset(qitem, 0, sizeof(mobjqitem_t)); - qitem->mo = mo; - M_QueueInsert(&(qitem->mqitem), &anchorqueue); - } + qitem = malloc(sizeof(mobjqitem_t)); + memset(qitem, 0, sizeof(mobjqitem_t)); + qitem->mo = mo; + M_QueueInsert(&(qitem->mqitem), &anchorqueue); } } @@ -1657,7 +1644,7 @@ void T_PolyObjRotate(polyrotate_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotate: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -1742,7 +1729,7 @@ void T_PolyObjMove(polymove_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjMove: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -1815,7 +1802,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjWaypoint: thinker with invalid id %d removed.", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -1826,11 +1813,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th) // Find out target first. // We redo this each tic to make savegame compatibility easier. - for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next) + for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { - if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -1907,11 +1891,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th) CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n"); // Find next waypoint - for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next) + for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { - if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -1946,11 +1927,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th) th->stophere = true; } - for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next) + for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { - if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -1983,11 +1961,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th) if (!th->continuous) th->comeback = false; - for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next) + for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { - if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -2089,7 +2064,7 @@ void T_PolyDoorSlide(polyslidedoor_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSlide: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -2194,7 +2169,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -2293,7 +2268,7 @@ void T_PolyObjDisplace(polydisplace_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -2333,7 +2308,7 @@ void T_PolyObjRotDisplace(polyrotdisplace_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -2390,7 +2365,7 @@ INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) // create a new thinker th = Z_Malloc(sizeof(polyrotate_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotate; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields @@ -2455,7 +2430,7 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) // create a new thinker th = Z_Malloc(sizeof(polymove_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjMove; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields @@ -2516,7 +2491,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // create a new thinker th = Z_Malloc(sizeof(polywaypoint_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjWaypoint; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields @@ -2534,11 +2509,8 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) th->stophere = false; // Find the first waypoint we need to use - for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next) + for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { - if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -2605,11 +2577,8 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // Find the actual target movement waypoint target = first; - /*for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next) + /*for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) { - if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)wp; if (mo2->type != MT_TUBEWAYPOINT) @@ -2662,7 +2631,7 @@ static void Polyobj_doSlideDoor(polyobj_t *po, polydoordata_t *doordata) // allocate and add a new slide door thinker th = Z_Malloc(sizeof(polyslidedoor_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyDoorSlide; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); // point the polyobject to this thinker po->thinker = &th->thinker; @@ -2710,7 +2679,7 @@ static void Polyobj_doSwingDoor(polyobj_t *po, polydoordata_t *doordata) // allocate and add a new swing door thinker th = Z_Malloc(sizeof(polyswingdoor_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyDoorSwing; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); // point the polyobject to this thinker po->thinker = &th->thinker; @@ -2792,7 +2761,7 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) // create a new thinker th = Z_Malloc(sizeof(polydisplace_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjDisplace; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields @@ -2838,7 +2807,7 @@ INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) // create a new thinker th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotDisplace; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields @@ -2875,7 +2844,7 @@ void T_PolyObjFlag(polymove_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjFlag: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -2939,7 +2908,7 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) // create a new thinker th = Z_Malloc(sizeof(polymove_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjFlag; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields @@ -2978,7 +2947,7 @@ void T_PolyObjFade(polyfade_t *th) #else { CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum); - P_RemoveThinkerDelayed(&th->thinker); + P_RemoveThinker(&th->thinker); return; } #endif @@ -3089,7 +3058,7 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) // create a new thinker th = Z_Malloc(sizeof(polyfade_t), PU_LEVSPEC, NULL); th->thinker.function.acp1 = (actionf_p1)T_PolyObjFade; - PolyObj_AddThinker(&th->thinker); + P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; // set fields diff --git a/src/p_saveg.c b/src/p_saveg.c index d587cba17..06baa9528 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1303,6 +1303,10 @@ typedef enum tc_fade, tc_fadecolormap, tc_planedisplace, +#ifdef ESLOPE + tc_dynslopeline, + tc_dynslopevert, +#endif // ESLOPE #ifdef POLYOBJECTS tc_polyrotate, // haleyjd 03/26/06: polyobjects tc_polymove, @@ -1341,6 +1345,14 @@ static inline UINT32 SavePlayer(const player_t *player) return 0xFFFFFFFF; } +#ifdef ESLOPE +static UINT32 SaveSlope(const pslope_t *slope) +{ + if (slope) return (UINT32)(slope->id); + return 0xFFFFFFFF; +} +#endif // ESLOPE + // // SaveMobjThinker // @@ -1982,6 +1994,23 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->speed); WRITEUINT8(save_p, ht->type); } +#ifdef ESLOPE +/// Save a dynamic slope thinker. +static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type) +{ + const dynplanethink_t* ht = (const void*)th; + + WRITEUINT8(save_p, type); + WRITEUINT8(save_p, ht->type); + WRITEUINT32(save_p, SaveSlope(ht->slope)); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEFIXED(save_p, ht->extent); + + WRITEMEM(save_p, ht->tags, sizeof(ht->tags)); + WRITEMEM(save_p, ht->vex, sizeof(ht->vex)); +} +#endif // ESLOPE + #ifdef POLYOBJECTS // @@ -2138,236 +2167,253 @@ static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type) static void P_NetArchiveThinkers(void) { const thinker_t *th; - UINT32 numsaved = 0; + UINT32 i; WRITEUINT32(save_p, ARCHIVEBLOCK_THINKERS); - // save off the current thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (i = 0; i < NUM_THINKERLISTS; i++) { - if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed - || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) - numsaved++; + UINT32 numsaved = 0; - if (th->function.acp1 == (actionf_p1)P_MobjThinker) + // save off the current thinkers + for (th = thlist[i].next; th != &thlist[i]; th = th->next) { - SaveMobjThinker(th, tc_mobj); - continue; - } -#ifdef PARANOIA - else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker); -#endif - else if (th->function.acp1 == (actionf_p1)T_MoveCeiling) - { - SaveCeilingThinker(th, tc_ceiling); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_CrushCeiling) - { - SaveCeilingThinker(th, tc_crushceiling); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_MoveFloor) - { - SaveFloormoveThinker(th, tc_floor); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_LightningFlash) - { - SaveLightflashThinker(th, tc_flash); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_StrobeFlash) - { - SaveStrobeThinker(th, tc_strobe); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_Glow) - { - SaveGlowThinker(th, tc_glow); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_FireFlicker) - { - SaveFireflickerThinker(th, tc_fireflicker); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_MoveElevator) - { - SaveElevatorThinker(th, tc_elevator); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling) - { - SaveSpecialLevelThinker(th, tc_continuousfalling); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_ThwompSector) - { - SaveSpecialLevelThinker(th, tc_thwomp); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector) - { - SaveSpecialLevelThinker(th, tc_noenemies); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker) - { - SaveSpecialLevelThinker(th, tc_eachtime); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_RaiseSector) - { - SaveSpecialLevelThinker(th, tc_raisesector); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_CameraScanner) - { - SaveElevatorThinker(th, tc_camerascanner); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_Scroll) - { - SaveScrollThinker(th, tc_scroll); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_Friction) - { - SaveFrictionThinker(th, tc_friction); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_Pusher) - { - SavePusherThinker(th, tc_pusher); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_BounceCheese) - { - SaveSpecialLevelThinker(th, tc_bouncecheese); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_StartCrumble) - { - SaveElevatorThinker(th, tc_startcrumble); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_MarioBlock) - { - SaveSpecialLevelThinker(th, tc_marioblock); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker) - { - SaveSpecialLevelThinker(th, tc_marioblockchecker); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_SpikeSector) - { - SaveSpecialLevelThinker(th, tc_spikesector); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_FloatSector) - { - SaveSpecialLevelThinker(th, tc_floatsector); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_BridgeThinker) - { - SaveSpecialLevelThinker(th, tc_bridgethinker); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_LaserFlash) - { - SaveLaserThinker(th, tc_laserflash); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_LightFade) - { - SaveLightlevelThinker(th, tc_lightfade); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_ExecutorDelay) - { - SaveExecutorThinker(th, tc_executor); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_Disappear) - { - SaveDisappearThinker(th, tc_disappear); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_Fade) - { - SaveFadeThinker(th, tc_fade); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_FadeColormap) - { - SaveFadeColormapThinker(th, tc_fadecolormap); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace) - { - SavePlaneDisplaceThinker(th, tc_planedisplace); - continue; - } + if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed + || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) + numsaved++; + + if (th->function.acp1 == (actionf_p1)P_MobjThinker) + { + SaveMobjThinker(th, tc_mobj); + continue; + } + #ifdef PARANOIA + else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker); + #endif + else if (th->function.acp1 == (actionf_p1)T_MoveCeiling) + { + SaveCeilingThinker(th, tc_ceiling); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_CrushCeiling) + { + SaveCeilingThinker(th, tc_crushceiling); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_MoveFloor) + { + SaveFloormoveThinker(th, tc_floor); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_LightningFlash) + { + SaveLightflashThinker(th, tc_flash); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_StrobeFlash) + { + SaveStrobeThinker(th, tc_strobe); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_Glow) + { + SaveGlowThinker(th, tc_glow); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_FireFlicker) + { + SaveFireflickerThinker(th, tc_fireflicker); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_MoveElevator) + { + SaveElevatorThinker(th, tc_elevator); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling) + { + SaveSpecialLevelThinker(th, tc_continuousfalling); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_ThwompSector) + { + SaveSpecialLevelThinker(th, tc_thwomp); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector) + { + SaveSpecialLevelThinker(th, tc_noenemies); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker) + { + SaveSpecialLevelThinker(th, tc_eachtime); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_RaiseSector) + { + SaveSpecialLevelThinker(th, tc_raisesector); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_CameraScanner) + { + SaveElevatorThinker(th, tc_camerascanner); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_Scroll) + { + SaveScrollThinker(th, tc_scroll); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_Friction) + { + SaveFrictionThinker(th, tc_friction); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_Pusher) + { + SavePusherThinker(th, tc_pusher); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_BounceCheese) + { + SaveSpecialLevelThinker(th, tc_bouncecheese); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_StartCrumble) + { + SaveElevatorThinker(th, tc_startcrumble); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_MarioBlock) + { + SaveSpecialLevelThinker(th, tc_marioblock); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker) + { + SaveSpecialLevelThinker(th, tc_marioblockchecker); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_SpikeSector) + { + SaveSpecialLevelThinker(th, tc_spikesector); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_FloatSector) + { + SaveSpecialLevelThinker(th, tc_floatsector); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_BridgeThinker) + { + SaveSpecialLevelThinker(th, tc_bridgethinker); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_LaserFlash) + { + SaveLaserThinker(th, tc_laserflash); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_LightFade) + { + SaveLightlevelThinker(th, tc_lightfade); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_ExecutorDelay) + { + SaveExecutorThinker(th, tc_executor); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_Disappear) + { + SaveDisappearThinker(th, tc_disappear); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_Fade) + { + SaveFadeThinker(th, tc_fade); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_FadeColormap) + { + SaveFadeColormapThinker(th, tc_fadecolormap); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace) + { + SavePlaneDisplaceThinker(th, tc_planedisplace); + continue; + } #ifdef POLYOBJECTS - else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) - { - SavePolyrotatetThinker(th, tc_polyrotate); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyObjMove) - { - SavePolymoveThinker(th, tc_polymove); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyObjWaypoint) - { - SavePolywaypointThinker(th, tc_polywaypoint); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyDoorSlide) - { - SavePolyslidedoorThinker(th, tc_polyslidedoor); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyDoorSwing) - { - SavePolyswingdoorThinker(th, tc_polyswingdoor); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyObjFlag) - { - SavePolymoveThinker(th, tc_polyflag); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyObjDisplace) - { - SavePolydisplaceThinker(th, tc_polydisplace); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyObjRotDisplace) - { - SavePolyrotdisplaceThinker(th, tc_polyrotdisplace); - continue; - } - else if (th->function.acp1 == (actionf_p1)T_PolyObjFade) - { - SavePolyfadeThinker(th, tc_polyfade); - continue; - } + else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) + { + SavePolyrotatetThinker(th, tc_polyrotate); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjMove) + { + SavePolymoveThinker(th, tc_polymove); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjWaypoint) + { + SavePolywaypointThinker(th, tc_polywaypoint); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyDoorSlide) + { + SavePolyslidedoorThinker(th, tc_polyslidedoor); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyDoorSwing) + { + SavePolyswingdoorThinker(th, tc_polyswingdoor); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjFlag) + { + SavePolymoveThinker(th, tc_polyflag); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjDisplace) + { + SavePolydisplaceThinker(th, tc_polydisplace); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjRotDisplace) + { + SavePolyrotdisplaceThinker(th, tc_polyrotdisplace); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_PolyObjFade) + { + SavePolyfadeThinker(th, tc_polyfade); + continue; + } #endif +#ifdef ESLOPE + else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine) + { + SaveDynamicSlopeThinker(th, tc_dynslopeline); + continue; + } + else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeVert) + { + SaveDynamicSlopeThinker(th, tc_dynslopevert); + continue; + } +#endif // ESLOPE #ifdef PARANOIA - else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection - I_Error("unknown thinker type %p", th->function.acp1); + else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection + I_Error("unknown thinker type %p", th->function.acp1); #endif + } + + CONS_Debug(DBG_NETPLAY, "%u thinkers saved\n", numsaved); + + WRITEUINT8(save_p, tc_end); } - - CONS_Debug(DBG_NETPLAY, "%u thinkers saved\n", numsaved); - - WRITEUINT8(save_p, tc_end); } // Now save the pointers, tracer and target, but at load time we must @@ -2379,11 +2425,8 @@ mobj_t *P_FindNewPosition(UINT32 oldposition) thinker_t *th; mobj_t *mobj; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mobj = (mobj_t *)th; if (mobj->mobjnum == oldposition) return mobj; @@ -2416,12 +2459,26 @@ static inline player_t *LoadPlayer(UINT32 player) return &players[player]; } +#ifdef ESLOPE +static inline pslope_t *LoadSlope(UINT32 slopeid) +{ + pslope_t *p = slopelist; + if (slopeid > slopecount) return NULL; + do + { + if (p->id == slopeid) + return p; + } while ((p = p->next)); + return NULL; +} +#endif // ESLOPE + // // LoadMobjThinker // // Loads a mobj_t from a save game // -static void LoadMobjThinker(actionf_p1 thinker) +static thinker_t* LoadMobjThinker(actionf_p1 thinker) { thinker_t *next; mobj_t *mobj; @@ -2482,7 +2539,7 @@ static void LoadMobjThinker(actionf_p1 thinker) if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case { P_SpawnHoopsAndRings(&mapthings[spawnpointnum], false); - return; + return NULL; } mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); @@ -2690,9 +2747,9 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->player->viewz = mobj->player->mo->z + mobj->player->viewheight; } - P_AddThinker(&mobj->thinker); - mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function + + return &mobj->thinker; } // @@ -2706,7 +2763,7 @@ static void LoadMobjThinker(actionf_p1 thinker) // 2 - Ceiling Only // 3 - Both // -static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling) +static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling) { levelspecthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); size_t i; @@ -2727,7 +2784,7 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling) ht->sector->floordata = ht; } - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2735,7 +2792,7 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling) // // Loads a ceiling_t from a save game // -static void LoadCeilingThinker(actionf_p1 thinker) +static thinker_t* LoadCeilingThinker(actionf_p1 thinker) { ceiling_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2756,7 +2813,7 @@ static void LoadCeilingThinker(actionf_p1 thinker) ht->sourceline = READFIXED(save_p); if (ht->sector) ht->sector->ceilingdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2764,7 +2821,7 @@ static void LoadCeilingThinker(actionf_p1 thinker) // // Loads a floormove_t from a save game // -static void LoadFloormoveThinker(actionf_p1 thinker) +static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) { floormove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2780,7 +2837,7 @@ static void LoadFloormoveThinker(actionf_p1 thinker) ht->delaytimer = READFIXED(save_p); if (ht->sector) ht->sector->floordata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2788,7 +2845,7 @@ static void LoadFloormoveThinker(actionf_p1 thinker) // // Loads a lightflash_t from a save game // -static void LoadLightflashThinker(actionf_p1 thinker) +static thinker_t* LoadLightflashThinker(actionf_p1 thinker) { lightflash_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2797,7 +2854,7 @@ static void LoadLightflashThinker(actionf_p1 thinker) ht->minlight = READINT32(save_p); if (ht->sector) ht->sector->lightingdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2805,7 +2862,7 @@ static void LoadLightflashThinker(actionf_p1 thinker) // // Loads a strobe_t from a save game // -static void LoadStrobeThinker(actionf_p1 thinker) +static thinker_t* LoadStrobeThinker(actionf_p1 thinker) { strobe_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2817,7 +2874,7 @@ static void LoadStrobeThinker(actionf_p1 thinker) ht->brighttime = READINT32(save_p); if (ht->sector) ht->sector->lightingdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2825,7 +2882,7 @@ static void LoadStrobeThinker(actionf_p1 thinker) // // Loads a glow_t from a save game // -static void LoadGlowThinker(actionf_p1 thinker) +static thinker_t* LoadGlowThinker(actionf_p1 thinker) { glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2836,14 +2893,14 @@ static void LoadGlowThinker(actionf_p1 thinker) ht->speed = READINT32(save_p); if (ht->sector) ht->sector->lightingdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // // LoadFireflickerThinker // // Loads a fireflicker_t from a save game // -static void LoadFireflickerThinker(actionf_p1 thinker) +static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) { fireflicker_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2854,14 +2911,14 @@ static void LoadFireflickerThinker(actionf_p1 thinker) ht->minlight = READINT32(save_p); if (ht->sector) ht->sector->lightingdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // // LoadElevatorThinker // // Loads a elevator_t from a save game // -static void LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) +static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) { elevator_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2891,7 +2948,7 @@ static void LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) ht->sector->floordata = ht; } - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2899,7 +2956,7 @@ static void LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) // // Loads a scroll_t from a save game // -static void LoadScrollThinker(actionf_p1 thinker) +static thinker_t* LoadScrollThinker(actionf_p1 thinker) { scroll_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2913,7 +2970,7 @@ static void LoadScrollThinker(actionf_p1 thinker) ht->accel = READINT32(save_p); ht->exclusive = READINT32(save_p); ht->type = READUINT8(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2921,7 +2978,7 @@ static void LoadScrollThinker(actionf_p1 thinker) // // Loads a friction_t from a save game // -static inline void LoadFrictionThinker(actionf_p1 thinker) +static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) { friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2930,7 +2987,7 @@ static inline void LoadFrictionThinker(actionf_p1 thinker) ht->affectee = READINT32(save_p); ht->referrer = READINT32(save_p); ht->roverfriction = READUINT8(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2938,7 +2995,7 @@ static inline void LoadFrictionThinker(actionf_p1 thinker) // // Loads a pusher_t from a save game // -static void LoadPusherThinker(actionf_p1 thinker) +static thinker_t* LoadPusherThinker(actionf_p1 thinker) { pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2956,7 +3013,7 @@ static void LoadPusherThinker(actionf_p1 thinker) ht->exclusive = READINT32(save_p); ht->slider = READINT32(save_p); ht->source = P_GetPushThing(ht->affectee); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2964,7 +3021,7 @@ static void LoadPusherThinker(actionf_p1 thinker) // // Loads a laserthink_t from a save game // -static inline void LoadLaserThinker(actionf_p1 thinker) +static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ffloor_t *rover = NULL; @@ -2976,7 +3033,7 @@ static inline void LoadLaserThinker(actionf_p1 thinker) if (rover->secnum == (size_t)(ht->sec - sectors) && rover->master == ht->sourceline) ht->ffloor = rover; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -2984,7 +3041,7 @@ static inline void LoadLaserThinker(actionf_p1 thinker) // // Loads a lightlevel_t from a save game // -static inline void LoadLightlevelThinker(actionf_p1 thinker) +static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) { lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -2996,7 +3053,7 @@ static inline void LoadLightlevelThinker(actionf_p1 thinker) ht->timer = READINT32(save_p); if (ht->sector) ht->sector->lightingdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3004,7 +3061,7 @@ static inline void LoadLightlevelThinker(actionf_p1 thinker) // // Loads a executor_t from a save game // -static inline void LoadExecutorThinker(actionf_p1 thinker) +static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) { executor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3012,7 +3069,7 @@ static inline void LoadExecutorThinker(actionf_p1 thinker) ht->caller = LoadMobj(READUINT32(save_p)); ht->sector = LoadSector(READUINT32(save_p)); ht->timer = READINT32(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3020,7 +3077,7 @@ static inline void LoadExecutorThinker(actionf_p1 thinker) // // Loads a disappear_t thinker // -static inline void LoadDisappearThinker(actionf_p1 thinker) +static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) { disappear_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3031,7 +3088,7 @@ static inline void LoadDisappearThinker(actionf_p1 thinker) ht->affectee = READINT32(save_p); ht->sourceline = READINT32(save_p); ht->exists = READINT32(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3039,7 +3096,7 @@ static inline void LoadDisappearThinker(actionf_p1 thinker) // // Loads a fade_t thinker // -static inline void LoadFadeThinker(actionf_p1 thinker) +static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) { sector_t *ss; fade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3078,14 +3135,14 @@ static inline void LoadFadeThinker(actionf_p1 thinker) j++; } } - P_AddThinker(&ht->thinker); + return &ht->thinker; } // LoadFadeColormapThinker // // Loads a fadecolormap_t from a save game // -static inline void LoadFadeColormapThinker(actionf_p1 thinker) +static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) { fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3097,7 +3154,7 @@ static inline void LoadFadeColormapThinker(actionf_p1 thinker) ht->timer = READINT32(save_p); if (ht->sector) ht->sector->fadecolormapdata = ht; - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3105,18 +3162,36 @@ static inline void LoadFadeColormapThinker(actionf_p1 thinker) // // Loads a planedisplace_t thinker // -static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker) +static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) { planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; + ht->affectee = READINT32(save_p); ht->control = READINT32(save_p); ht->last_height = READFIXED(save_p); ht->speed = READFIXED(save_p); ht->type = READUINT8(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } +#ifdef ESLOPE +/// Save a dynamic slope thinker. +static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) +{ + dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + + ht->type = READUINT8(save_p); + ht->slope = LoadSlope(READUINT32(save_p)); + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->extent = READFIXED(save_p); + READMEM(save_p, ht->tags, sizeof(ht->tags)); + READMEM(save_p, ht->vex, sizeof(ht->vex)); + return &ht->thinker; +} +#endif // ESLOPE + #ifdef POLYOBJECTS // @@ -3124,14 +3199,14 @@ static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker) // // Loads a polyrotate_t thinker // -static inline void LoadPolyrotatetThinker(actionf_p1 thinker) +static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) { polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save_p); ht->speed = READINT32(save_p); ht->distance = READINT32(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3139,7 +3214,7 @@ static inline void LoadPolyrotatetThinker(actionf_p1 thinker) // // Loads a polymovet_t thinker // -static void LoadPolymoveThinker(actionf_p1 thinker) +static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) { polymove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3149,7 +3224,7 @@ static void LoadPolymoveThinker(actionf_p1 thinker) ht->momy = READFIXED(save_p); ht->distance = READINT32(save_p); ht->angle = READANGLE(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3157,7 +3232,7 @@ static void LoadPolymoveThinker(actionf_p1 thinker) // // Loads a polywaypoint_t thinker // -static inline void LoadPolywaypointThinker(actionf_p1 thinker) +static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) { polywaypoint_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3173,7 +3248,7 @@ static inline void LoadPolywaypointThinker(actionf_p1 thinker) ht->diffx = READFIXED(save_p); ht->diffy = READFIXED(save_p); ht->diffz = READFIXED(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3181,7 +3256,7 @@ static inline void LoadPolywaypointThinker(actionf_p1 thinker) // // loads a polyslidedoor_t thinker // -static inline void LoadPolyslidedoorThinker(actionf_p1 thinker) +static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) { polyslidedoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3198,7 +3273,7 @@ static inline void LoadPolyslidedoorThinker(actionf_p1 thinker) ht->momx = READFIXED(save_p); ht->momy = READFIXED(save_p); ht->closing = READUINT8(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3206,7 +3281,7 @@ static inline void LoadPolyslidedoorThinker(actionf_p1 thinker) // // Loads a polyswingdoor_t thinker // -static inline void LoadPolyswingdoorThinker(actionf_p1 thinker) +static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) { polyswingdoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3218,7 +3293,7 @@ static inline void LoadPolyswingdoorThinker(actionf_p1 thinker) ht->initDistance = READINT32(save_p); ht->distance = READINT32(save_p); ht->closing = READUINT8(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3226,7 +3301,7 @@ static inline void LoadPolyswingdoorThinker(actionf_p1 thinker) // // Loads a polydisplace_t thinker // -static inline void LoadPolydisplaceThinker(actionf_p1 thinker) +static inline thinker_t* LoadPolydisplaceThinker(actionf_p1 thinker) { polydisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3235,10 +3310,10 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker) ht->dx = READFIXED(save_p); ht->dy = READFIXED(save_p); ht->oldHeights = READFIXED(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } -static inline void LoadPolyrotdisplaceThinker(actionf_p1 thinker) +static inline thinker_t* LoadPolyrotdisplaceThinker(actionf_p1 thinker) { polyrotdisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3247,7 +3322,7 @@ static inline void LoadPolyrotdisplaceThinker(actionf_p1 thinker) ht->rotscale = READFIXED(save_p); ht->turnobjs = READUINT8(save_p); ht->oldHeights = READFIXED(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } // @@ -3255,7 +3330,7 @@ static inline void LoadPolyrotdisplaceThinker(actionf_p1 thinker) // // Loads a polyfadet_t thinker // -static void LoadPolyfadeThinker(actionf_p1 thinker) +static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) { polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3267,7 +3342,7 @@ static void LoadPolyfadeThinker(actionf_p1 thinker) ht->ticbased = (boolean)READUINT8(save_p); ht->duration = READINT32(save_p); ht->timer = READINT32(save_p); - P_AddThinker(&ht->thinker); + return &ht->thinker; } #endif @@ -3300,15 +3375,18 @@ static void P_NetUnArchiveThinkers(void) I_Error("Bad $$$.sav at archive block Thinkers"); // remove all the current thinkers - currentthinker = thinkercap.next; - for (currentthinker = thinkercap.next; currentthinker != &thinkercap; currentthinker = next) + for (i = 0; i < NUM_THINKERLISTS; i++) { - next = currentthinker->next; + currentthinker = thlist[i].next; + for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = next) + { + next = currentthinker->next; - if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) - P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it - else - Z_Free(currentthinker); + if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) + P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it + else + Z_Free(currentthinker); + } } // we don't want the removed mobjs to come back @@ -3322,202 +3400,218 @@ static void P_NetUnArchiveThinkers(void) } // read in saved thinkers - for (;;) + for (i = 0; i < NUM_THINKERLISTS; i++) { - tclass = READUINT8(save_p); - - if (tclass == tc_end) - break; // leave the saved thinker reading loop - numloaded++; - - switch (tclass) + for (;;) { - case tc_mobj: - LoadMobjThinker((actionf_p1)P_MobjThinker); - break; + thinker_t* th; + tclass = READUINT8(save_p); - case tc_ceiling: - LoadCeilingThinker((actionf_p1)T_MoveCeiling); - break; + if (tclass == tc_end) + break; // leave the saved thinker reading loop + numloaded++; - case tc_crushceiling: - LoadCeilingThinker((actionf_p1)T_CrushCeiling); - break; - - case tc_floor: - LoadFloormoveThinker((actionf_p1)T_MoveFloor); - break; - - case tc_flash: - LoadLightflashThinker((actionf_p1)T_LightningFlash); - break; - - case tc_strobe: - LoadStrobeThinker((actionf_p1)T_StrobeFlash); - break; - - case tc_glow: - LoadGlowThinker((actionf_p1)T_Glow); - break; - - case tc_fireflicker: - LoadFireflickerThinker((actionf_p1)T_FireFlicker); - break; - - case tc_elevator: - LoadElevatorThinker((actionf_p1)T_MoveElevator, 3); - break; - - case tc_continuousfalling: - LoadSpecialLevelThinker((actionf_p1)T_ContinuousFalling, 3); - break; - - case tc_thwomp: - LoadSpecialLevelThinker((actionf_p1)T_ThwompSector, 3); - break; - - case tc_noenemies: - LoadSpecialLevelThinker((actionf_p1)T_NoEnemiesSector, 0); - break; - - case tc_eachtime: - LoadSpecialLevelThinker((actionf_p1)T_EachTimeThinker, 0); - break; - - case tc_raisesector: - LoadSpecialLevelThinker((actionf_p1)T_RaiseSector, 0); - break; - - /// \todo rewrite all the code that uses an elevator_t but isn't an elevator - /// \note working on it! - case tc_camerascanner: - LoadElevatorThinker((actionf_p1)T_CameraScanner, 0); - break; - - case tc_bouncecheese: - LoadSpecialLevelThinker((actionf_p1)T_BounceCheese, 2); - break; - - case tc_startcrumble: - LoadElevatorThinker((actionf_p1)T_StartCrumble, 1); - break; - - case tc_marioblock: - LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3); - break; - - case tc_marioblockchecker: - LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0); - break; - - case tc_spikesector: - LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0); - break; - - case tc_floatsector: - LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0); - break; - - case tc_bridgethinker: - LoadSpecialLevelThinker((actionf_p1)T_BridgeThinker, 3); - break; - - case tc_laserflash: - LoadLaserThinker((actionf_p1)T_LaserFlash); - break; - - case tc_lightfade: - LoadLightlevelThinker((actionf_p1)T_LightFade); - break; - - case tc_executor: - LoadExecutorThinker((actionf_p1)T_ExecutorDelay); - restoreNum = true; - break; - - case tc_disappear: - LoadDisappearThinker((actionf_p1)T_Disappear); - break; - - case tc_fade: - LoadFadeThinker((actionf_p1)T_Fade); - break; - - case tc_fadecolormap: - LoadFadeColormapThinker((actionf_p1)T_FadeColormap); - break; - - case tc_planedisplace: - LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace); - break; -#ifdef POLYOBJECTS - case tc_polyrotate: - LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate); - break; - - case tc_polymove: - LoadPolymoveThinker((actionf_p1)T_PolyObjMove); - break; - - case tc_polywaypoint: - LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint); - break; - - case tc_polyslidedoor: - LoadPolyslidedoorThinker((actionf_p1)T_PolyDoorSlide); - break; - - case tc_polyswingdoor: - LoadPolyswingdoorThinker((actionf_p1)T_PolyDoorSwing); - break; - - case tc_polyflag: - LoadPolymoveThinker((actionf_p1)T_PolyObjFlag); - break; - - case tc_polydisplace: - LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace); - break; - - case tc_polyrotdisplace: - LoadPolyrotdisplaceThinker((actionf_p1)T_PolyObjRotDisplace); - break; - - case tc_polyfade: - LoadPolyfadeThinker((actionf_p1)T_PolyObjFade); - break; -#endif - case tc_scroll: - LoadScrollThinker((actionf_p1)T_Scroll); - break; - - case tc_friction: - LoadFrictionThinker((actionf_p1)T_Friction); - break; - - case tc_pusher: - LoadPusherThinker((actionf_p1)T_Pusher); - break; - - default: - I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass); - } - } - - CONS_Debug(DBG_NETPLAY, "%u thinkers loaded\n", numloaded); - - if (restoreNum) - { - executor_t *delay = NULL; - UINT32 mobjnum; - for (currentthinker = thinkercap.next; currentthinker != &thinkercap; - currentthinker = currentthinker->next) - { - if (currentthinker->function.acp1 == (actionf_p1)T_ExecutorDelay) + switch (tclass) { - delay = (void *)currentthinker; - if ((mobjnum = (UINT32)(size_t)delay->caller)) - delay->caller = P_FindNewPosition(mobjnum); + case tc_mobj: + th = LoadMobjThinker((actionf_p1)P_MobjThinker); + break; + + case tc_ceiling: + th = LoadCeilingThinker((actionf_p1)T_MoveCeiling); + break; + + case tc_crushceiling: + th = LoadCeilingThinker((actionf_p1)T_CrushCeiling); + break; + + case tc_floor: + th = LoadFloormoveThinker((actionf_p1)T_MoveFloor); + break; + + case tc_flash: + th = LoadLightflashThinker((actionf_p1)T_LightningFlash); + break; + + case tc_strobe: + th = LoadStrobeThinker((actionf_p1)T_StrobeFlash); + break; + + case tc_glow: + th = LoadGlowThinker((actionf_p1)T_Glow); + break; + + case tc_fireflicker: + th = LoadFireflickerThinker((actionf_p1)T_FireFlicker); + break; + + case tc_elevator: + th = LoadElevatorThinker((actionf_p1)T_MoveElevator, 3); + break; + + case tc_continuousfalling: + th = LoadSpecialLevelThinker((actionf_p1)T_ContinuousFalling, 3); + break; + + case tc_thwomp: + th = LoadSpecialLevelThinker((actionf_p1)T_ThwompSector, 3); + break; + + case tc_noenemies: + th = LoadSpecialLevelThinker((actionf_p1)T_NoEnemiesSector, 0); + break; + + case tc_eachtime: + th = LoadSpecialLevelThinker((actionf_p1)T_EachTimeThinker, 0); + break; + + case tc_raisesector: + th = LoadSpecialLevelThinker((actionf_p1)T_RaiseSector, 0); + break; + + /// \todo rewrite all the code that uses an elevator_t but isn't an elevator + /// \note working on it! + case tc_camerascanner: + th = LoadElevatorThinker((actionf_p1)T_CameraScanner, 0); + break; + + case tc_bouncecheese: + th = LoadSpecialLevelThinker((actionf_p1)T_BounceCheese, 2); + break; + + case tc_startcrumble: + th = LoadElevatorThinker((actionf_p1)T_StartCrumble, 1); + break; + + case tc_marioblock: + th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3); + break; + + case tc_marioblockchecker: + th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0); + break; + + case tc_spikesector: + th = LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0); + break; + + case tc_floatsector: + th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0); + break; + + case tc_bridgethinker: + th = LoadSpecialLevelThinker((actionf_p1)T_BridgeThinker, 3); + break; + + case tc_laserflash: + th = LoadLaserThinker((actionf_p1)T_LaserFlash); + break; + + case tc_lightfade: + th = LoadLightlevelThinker((actionf_p1)T_LightFade); + break; + + case tc_executor: + th = LoadExecutorThinker((actionf_p1)T_ExecutorDelay); + restoreNum = true; + break; + + case tc_disappear: + th = LoadDisappearThinker((actionf_p1)T_Disappear); + break; + + case tc_fade: + th = LoadFadeThinker((actionf_p1)T_Fade); + break; + + case tc_fadecolormap: + th = LoadFadeColormapThinker((actionf_p1)T_FadeColormap); + break; + + case tc_planedisplace: + th = LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace); + break; +#ifdef POLYOBJECTS + case tc_polyrotate: + th = LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate); + break; + + case tc_polymove: + th = LoadPolymoveThinker((actionf_p1)T_PolyObjMove); + break; + + case tc_polywaypoint: + th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint); + break; + + case tc_polyslidedoor: + th = LoadPolyslidedoorThinker((actionf_p1)T_PolyDoorSlide); + break; + + case tc_polyswingdoor: + th = LoadPolyswingdoorThinker((actionf_p1)T_PolyDoorSwing); + break; + + case tc_polyflag: + th = LoadPolymoveThinker((actionf_p1)T_PolyObjFlag); + break; + + case tc_polydisplace: + th = LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace); + break; + + case tc_polyrotdisplace: + th = LoadPolyrotdisplaceThinker((actionf_p1)T_PolyObjRotDisplace); + break; + + case tc_polyfade: + th = LoadPolyfadeThinker((actionf_p1)T_PolyObjFade); + break; +#endif +#ifdef ESLOPE + case tc_dynslopeline: + th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeLine); + break; + + case tc_dynslopevert: + th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeVert); + break; +#endif // ESLOPE + + case tc_scroll: + th = LoadScrollThinker((actionf_p1)T_Scroll); + break; + + case tc_friction: + th = LoadFrictionThinker((actionf_p1)T_Friction); + break; + + case tc_pusher: + th = LoadPusherThinker((actionf_p1)T_Pusher); + break; + + default: + I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass); + } + if (th) + P_AddThinker(i, th); + } + + CONS_Debug(DBG_NETPLAY, "%u thinkers loaded\n", numloaded); + + if (restoreNum) + { + 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); + } } } } @@ -3626,14 +3720,11 @@ static inline void P_FinishMobjs(void) mobj_t *mobj; // put info field there real value - for (currentthinker = thinkercap.next; currentthinker != &thinkercap; + for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; currentthinker = currentthinker->next) { - if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) - { - mobj = (mobj_t *)currentthinker; - mobj->info = &mobjinfo[mobj->type]; - } + mobj = (mobj_t *)currentthinker; + mobj->info = &mobjinfo[mobj->type]; } } @@ -3644,86 +3735,83 @@ static void P_RelinkPointers(void) UINT32 temp; // use info field (value = oldposition) to relink mobjs - for (currentthinker = thinkercap.next; currentthinker != &thinkercap; + for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; currentthinker = currentthinker->next) { - if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) + mobj = (mobj_t *)currentthinker; + + if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) + continue; + + if (mobj->tracer) { - mobj = (mobj_t *)currentthinker; - - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) - continue; - - if (mobj->tracer) - { - temp = (UINT32)(size_t)mobj->tracer; - mobj->tracer = NULL; - if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type); - } - if (mobj->target) - { - temp = (UINT32)(size_t)mobj->target; - mobj->target = NULL; - if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type); - } - if (mobj->hnext) - { - temp = (UINT32)(size_t)mobj->hnext; - mobj->hnext = NULL; - if (!(mobj->hnext = P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type); - } - if (mobj->hprev) - { - temp = (UINT32)(size_t)mobj->hprev; - mobj->hprev = NULL; - if (!(mobj->hprev = P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type); - } - if (mobj->player && mobj->player->capsule) - { - temp = (UINT32)(size_t)mobj->player->capsule; - mobj->player->capsule = NULL; - if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type); - } - if (mobj->player && mobj->player->axis1) - { - temp = (UINT32)(size_t)mobj->player->axis1; - mobj->player->axis1 = NULL; - if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type); - } - if (mobj->player && mobj->player->axis2) - { - temp = (UINT32)(size_t)mobj->player->axis2; - mobj->player->axis2 = NULL; - if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type); - } - if (mobj->player && mobj->player->awayviewmobj) - { - temp = (UINT32)(size_t)mobj->player->awayviewmobj; - mobj->player->awayviewmobj = NULL; - if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type); - } - if (mobj->player && mobj->player->followmobj) - { - temp = (UINT32)(size_t)mobj->player->followmobj; - mobj->player->followmobj = NULL; - if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); - } - if (mobj->player && mobj->player->drone) - { - temp = (UINT32)(size_t)mobj->player->drone; - mobj->player->drone = NULL; - if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp))) - CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type); - } + temp = (UINT32)(size_t)mobj->tracer; + mobj->tracer = NULL; + if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type); + } + if (mobj->target) + { + temp = (UINT32)(size_t)mobj->target; + mobj->target = NULL; + if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type); + } + if (mobj->hnext) + { + temp = (UINT32)(size_t)mobj->hnext; + mobj->hnext = NULL; + if (!(mobj->hnext = P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type); + } + if (mobj->hprev) + { + temp = (UINT32)(size_t)mobj->hprev; + mobj->hprev = NULL; + if (!(mobj->hprev = P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->capsule) + { + temp = (UINT32)(size_t)mobj->player->capsule; + mobj->player->capsule = NULL; + if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->axis1) + { + temp = (UINT32)(size_t)mobj->player->axis1; + mobj->player->axis1 = NULL; + if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->axis2) + { + temp = (UINT32)(size_t)mobj->player->axis2; + mobj->player->axis2 = NULL; + if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->awayviewmobj) + { + temp = (UINT32)(size_t)mobj->player->awayviewmobj; + mobj->player->awayviewmobj = NULL; + if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->followmobj) + { + temp = (UINT32)(size_t)mobj->player->followmobj; + mobj->player->followmobj = NULL; + if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); + } + if (mobj->player && mobj->player->drone) + { + temp = (UINT32)(size_t)mobj->player->drone; + mobj->player->drone = NULL; + if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type); } } } @@ -4025,15 +4113,12 @@ void P_SaveNetGame(void) P_NetArchiveMisc(); // Assign the mobjnumber for pointer tracking - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - { - mobj = (mobj_t *)th; - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) - continue; - mobj->mobjnum = i++; - } + mobj = (mobj_t *)th; + if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) + continue; + mobj->mobjnum = i++; } P_NetArchivePlayers(); diff --git a/src/p_setup.c b/src/p_setup.c index 585da2149..e7dc271a4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -815,11 +815,8 @@ void P_ReloadRings(void) mapthing_t *mt = mapthings; // scan the thinkers to find rings/spheres/hoops to unset - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo = (mobj_t *)th; if (mo->type == MT_HOOPCENTER) @@ -884,11 +881,8 @@ void P_SwitchSpheresBonusMode(boolean bonustime) #endif // scan the thinkers to find spheres to switch - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo = (mobj_t *)th; if (mo->type != MT_BLUESPHERE && mo->type != MT_NIGHTSCHIP @@ -2228,7 +2222,7 @@ static void P_LevelInitStuff(void) } } - countdown = countdown2 = 0; + countdown = countdown2 = exitfadestarted = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -2299,11 +2293,8 @@ void P_LoadThingsOnly(void) } - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (mo) @@ -2921,7 +2912,7 @@ boolean P_SetupLevel(boolean skipprecip) P_InitSpecials(); #ifdef ESLOPE - P_ResetDynamicSlopes(); + P_ResetDynamicSlopes(fromnetsave); #endif P_LoadThings(loademblems); diff --git a/src/p_slopes.c b/src/p_slopes.c index 3cdbd687e..8f9489100 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -25,68 +25,66 @@ #ifdef ESLOPE -static pslope_t *slopelist = NULL; -static UINT16 slopecount = 0; +pslope_t *slopelist = NULL; +UINT16 slopecount = 0; // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); - slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); - slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); + slope->normal.x = FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); + slope->normal.y = FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); } -// With a vertex slope that has its vertices set, configure relevant slope info -static void P_ReconfigureVertexSlope(pslope_t *slope) +/// Setup slope via 3 vertexes. +static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3) { vector3_t vec1, vec2; - // Set slope normal - vec1.x = (slope->vertices[1]->x - slope->vertices[0]->x) << FRACBITS; - vec1.y = (slope->vertices[1]->y - slope->vertices[0]->y) << FRACBITS; - vec1.z = (slope->vertices[1]->z - slope->vertices[0]->z) << FRACBITS; + // Set origin. + FV3_Copy(&slope->o, &v1); - vec2.x = (slope->vertices[2]->x - slope->vertices[0]->x) << FRACBITS; - vec2.y = (slope->vertices[2]->y - slope->vertices[0]->y) << FRACBITS; - vec2.z = (slope->vertices[2]->z - slope->vertices[0]->z) << FRACBITS; + // Get slope's normal. + FV3_SubEx(&v2, &v1, &vec1); + FV3_SubEx(&v3, &v1, &vec2); - // ugggggggh fixed-point maaaaaaath - slope->extent = max( - max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)), - max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z)) - ) >> (FRACBITS+5); - vec1.x /= slope->extent; - vec1.y /= slope->extent; - vec1.z /= slope->extent; - vec2.x /= slope->extent; - vec2.y /= slope->extent; - vec2.z /= slope->extent; + // Set some defaults for a non-sloped "slope" + if (vec1.z == 0 && vec2.z == 0) + { + /// \todo Fix fully flat cases. - FV3_Cross(&vec1, &vec2, &slope->normal); - - slope->extent = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z); - if (slope->normal.z < 0) - slope->extent = -slope->extent; - - slope->normal.x = FixedDiv(slope->normal.x, slope->extent); - slope->normal.y = FixedDiv(slope->normal.y, slope->extent); - slope->normal.z = FixedDiv(slope->normal.z, slope->extent); - - // Set origin - slope->o.x = slope->vertices[0]->x << FRACBITS; - slope->o.y = slope->vertices[0]->y << FRACBITS; - slope->o.z = slope->vertices[0]->z << FRACBITS; - - if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope" slope->zangle = slope->xydirection = 0; slope->zdelta = slope->d.x = slope->d.y = 0; - } else { + } + else + { + /// \note Using fixed point for vectorial products easily leads to overflows so we work around by downscaling them. + fixed_t m = max( + max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)), + max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z)) + ) >> 5; // shifting right by 5 is good enough. + + FV3_Cross( + FV3_Divide(&vec1, m), + FV3_Divide(&vec2, m), + &slope->normal + ); + + // NOTE: FV3_Magnitude() doesn't work properly in some cases, and chaining FixedHypot() seems to give worse results. + m = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z); + + // Invert normal if it's facing down. + if (slope->normal.z < 0) + m = -m; + + FV3_Divide(&slope->normal, m); + // Get direction vector - slope->extent = R_PointToDist2(0, 0, slope->normal.x, slope->normal.y); - slope->d.x = -FixedDiv(slope->normal.x, slope->extent); - slope->d.y = -FixedDiv(slope->normal.y, slope->extent); + m = FixedHypot(slope->normal.x, slope->normal.y); + slope->d.x = -FixedDiv(slope->normal.x, m); + slope->d.y = -FixedDiv(slope->normal.y, m); // Z delta - slope->zdelta = FixedDiv(slope->extent, slope->normal.z); + slope->zdelta = FixedDiv(m, slope->normal.z); // Get angles slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; @@ -94,88 +92,95 @@ static void P_ReconfigureVertexSlope(pslope_t *slope) } } -// Recalculate dynamic slopes -void P_RunDynamicSlopes(void) { - pslope_t *slope; +/// Recalculate dynamic slopes. +void T_DynamicSlopeLine (dynplanethink_t* th) +{ + pslope_t* slope = th->slope; + line_t* srcline = th->sourceline; - for (slope = slopelist; slope; slope = slope->next) { - fixed_t zdelta; + fixed_t zdelta; - if (slope->flags & SL_NODYNAMIC) - continue; + switch(th->type) { + case DP_FRONTFLOOR: + zdelta = srcline->backsector->floorheight - srcline->frontsector->floorheight; + slope->o.z = srcline->frontsector->floorheight; + break; - switch(slope->refpos) { - case 1: // front floor - zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; - slope->o.z = slope->sourceline->frontsector->floorheight; - break; - case 2: // front ceiling - zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight; - slope->o.z = slope->sourceline->frontsector->ceilingheight; - break; - case 3: // back floor - zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight; - slope->o.z = slope->sourceline->backsector->floorheight; - break; - case 4: // back ceiling - zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; - slope->o.z = slope->sourceline->backsector->ceilingheight; - break; - case 5: // vertices - { - mapthing_t *mt; - size_t i; - INT32 l; - line_t *line; + case DP_FRONTCEIL: + zdelta = srcline->backsector->ceilingheight - srcline->frontsector->ceilingheight; + slope->o.z = srcline->frontsector->ceilingheight; + break; - for (i = 0; i < 3; i++) { - mt = slope->vertices[i]; - l = P_FindSpecialLineFromTag(799, mt->angle, -1); - if (l != -1) { - line = &lines[l]; - mt->z = line->frontsector->floorheight >> FRACBITS; - } - } + case DP_BACKFLOOR: + zdelta = srcline->frontsector->floorheight - srcline->backsector->floorheight; + slope->o.z = srcline->backsector->floorheight; + break; - P_ReconfigureVertexSlope(slope); - } - continue; // TODO + case DP_BACKCEIL: + zdelta = srcline->frontsector->ceilingheight - srcline->backsector->ceilingheight; + slope->o.z = srcline->backsector->ceilingheight; + break; - default: - I_Error("P_RunDynamicSlopes: slope has invalid type!"); - } + default: + return; + } - if (slope->zdelta != FixedDiv(zdelta, slope->extent)) { - slope->zdelta = FixedDiv(zdelta, slope->extent); - slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta); - P_CalculateSlopeNormal(slope); - } + if (slope->zdelta != FixedDiv(zdelta, th->extent)) { + slope->zdelta = FixedDiv(zdelta, th->extent); + slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta); + P_CalculateSlopeNormal(slope); } } -// -// P_MakeSlope -// -// Alocates and fill the contents of a slope structure. -// -static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, - const fixed_t zdelta, UINT8 flags) +/// Mapthing-defined +void T_DynamicSlopeVert (dynplanethink_t* th) { - pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); - memset(ret, 0, sizeof(*ret)); + pslope_t* slope = th->slope; - ret->o.x = o->x; - ret->o.y = o->y; - ret->o.z = o->z; + size_t i; + INT32 l; - ret->d.x = d->x; - ret->d.y = d->y; + for (i = 0; i < 3; i++) { + l = P_FindSpecialLineFromTag(799, th->tags[i], -1); + if (l != -1) { + th->vex[i].z = lines[l].frontsector->floorheight; + } + else + th->vex[i].z = 0; + } - ret->zdelta = zdelta; + ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]); +} +static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3]) +{ + dynplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL); + switch (type) + { + case DP_VERTEX: + th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert; + memcpy(th->tags, tags, sizeof(th->tags)); + memcpy(th->vex, vx, sizeof(th->vex)); + break; + default: + th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine; + th->sourceline = sourceline; + th->extent = extent; + } + + th->slope = slope; + th->type = type; + + P_AddThinker(THINK_DYNSLOPE, &th->thinker); +} + + +/// Create a new slope and add it to the slope list. +static inline pslope_t* Slope_Add (const UINT8 flags) +{ + pslope_t *ret = Z_Calloc(sizeof(pslope_t), PU_LEVEL, NULL); ret->flags = flags; - // Add to the slope list ret->next = slopelist; slopelist = ret; @@ -185,13 +190,24 @@ static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, return ret; } -// -// P_GetExtent -// -// Returns the distance to the first line within the sector that -// is intersected by a line parallel to the plane normal with the point (ox, oy) -// -static fixed_t P_GetExtent(sector_t *sector, line_t *line) +/// Alocates and fill the contents of a slope structure. +static pslope_t *MakeViaVectors(const vector3_t *o, const vector2_t *d, + const fixed_t zdelta, UINT8 flags) +{ + pslope_t *ret = Slope_Add(flags); + + FV3_Copy(&ret->o, o); + FV2_Copy(&ret->d, d); + + ret->zdelta = zdelta; + + ret->flags = flags; + + return ret; +} + +/// Get furthest perpendicular distance from all vertexes in a sector for a given line. +static fixed_t GetExtent(sector_t *sector, line_t *line) { // ZDoom code reference: v3float_t = vertex_t fixed_t fardist = -FRACUNIT; @@ -224,14 +240,8 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line) return fardist; } - -// -// P_SpawnSlope_Line -// -// Creates one or more slopes based on the given line type and front/back -// sectors. -// -void P_SpawnSlope_Line(int linenum) +/// Creates one or more slopes based on the given line type and front/back sectors. +static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) { // With dynamic slopes, it's fine to just leave this function as normal, // because checking to see if a slope had changed will waste more memory than @@ -251,10 +261,8 @@ void P_SpawnSlope_Line(int linenum) UINT8 flags = 0; // Slope flags if (line->flags & ML_NOSONIC) flags |= SL_NOPHYSICS; - if (!(line->flags & ML_NOTAILS)) - flags |= SL_NODYNAMIC; - if (line->flags & ML_NOKNUX) - flags |= SL_ANCHORVERTEX; + if (line->flags & ML_NOTAILS) + flags |= SL_DYNAMIC; if(!frontfloor && !backfloor && !frontceil && !backceil) { @@ -274,6 +282,7 @@ void P_SpawnSlope_Line(int linenum) ny = -FixedDiv(line->dx, len); } + // Set origin to line's center. origin.x = line->v1->x + (line->v2->x - line->v1->x)/2; origin.y = line->v1->y + (line->v2->y - line->v1->y)/2; @@ -286,7 +295,7 @@ void P_SpawnSlope_Line(int linenum) direction.x = nx; direction.y = ny; - extent = P_GetExtent(line->frontsector, line); + extent = GetExtent(line->frontsector, line); if(extent < 0) { @@ -304,104 +313,43 @@ void P_SpawnSlope_Line(int linenum) if(frontfloor) { - fixed_t highest, lowest; - size_t l; point.z = line->frontsector->floorheight; // Startz dz = FixedDiv(origin.z - point.z, extent); // Destinationz // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef fslope = line->frontsector->f_slope = - P_MakeSlope(&point, &direction, dz, flags); - - // Set up some shit - fslope->extent = extent; - fslope->refpos = 1; + MakeViaVectors(&point, &direction, dz, flags); // Now remember that f_slope IS a vector // fslope->o = origin 3D point 1 of the vector // fslope->d = destination 3D point 2 of the vector // fslope->normal is a 3D line perpendicular to the 3D vector - // Sync the linedata of the line that started this slope - // TODO: Anything special for control sector based slopes later? - fslope->sourceline = line; - - // To find the real highz/lowz of a slope, you need to check all the vertexes - // in the slope's sector with P_GetZAt to get the REAL lowz & highz - // Although these slopes are set by floorheights the ANGLE is what a slope is, - // so technically any slope can extend on forever (they are just bound by sectors) - // *You can use sourceline as a reference to see if two slopes really are the same - - // Default points for high and low - highest = point.z > origin.z ? point.z : origin.z; - lowest = point.z < origin.z ? point.z : origin.z; - - // Now check to see what the REAL high and low points of the slope inside the sector - // TODO: Is this really needed outside of FOFs? -Red - - for (l = 0; l < line->frontsector->linecount; l++) - { - fixed_t height = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); - - if (height > highest) - highest = height; - - if (height < lowest) - lowest = height; - } - - // Sets extra clipping data for the frontsector's slope - fslope->highz = highest; - fslope->lowz = lowest; - fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); P_CalculateSlopeNormal(fslope); + + if (spawnthinker && (flags & SL_DYNAMIC)) + P_AddDynSlopeThinker(fslope, DP_FRONTFLOOR, line, extent, NULL, NULL); } if(frontceil) { - fixed_t highest, lowest; - size_t l; origin.z = line->backsector->ceilingheight; point.z = line->frontsector->ceilingheight; dz = FixedDiv(origin.z - point.z, extent); cslope = line->frontsector->c_slope = - P_MakeSlope(&point, &direction, dz, flags); - - // Set up some shit - cslope->extent = extent; - cslope->refpos = 2; - - // Sync the linedata of the line that started this slope - // TODO: Anything special for control sector based slopes later? - cslope->sourceline = line; - - // Remember the way the slope is formed - highest = point.z > origin.z ? point.z : origin.z; - lowest = point.z < origin.z ? point.z : origin.z; - - for (l = 0; l < line->frontsector->linecount; l++) - { - fixed_t height = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); - - if (height > highest) - highest = height; - - if (height < lowest) - lowest = height; - } - - // This line special sets extra clipping data for the frontsector's slope - cslope->highz = highest; - cslope->lowz = lowest; + MakeViaVectors(&point, &direction, dz, flags); cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); P_CalculateSlopeNormal(cslope); + + if (spawnthinker && (flags & SL_DYNAMIC)) + P_AddDynSlopeThinker(cslope, DP_FRONTCEIL, line, extent, NULL, NULL); } } if(backfloor || backceil) @@ -413,7 +361,7 @@ void P_SpawnSlope_Line(int linenum) direction.x = -nx; direction.y = -ny; - extent = P_GetExtent(line->backsector, line); + extent = GetExtent(line->backsector, line); if(extent < 0) { @@ -429,88 +377,36 @@ void P_SpawnSlope_Line(int linenum) if(backfloor) { - fixed_t highest, lowest; - size_t l; point.z = line->backsector->floorheight; dz = FixedDiv(origin.z - point.z, extent); fslope = line->backsector->f_slope = - P_MakeSlope(&point, &direction, dz, flags); - - // Set up some shit - fslope->extent = extent; - fslope->refpos = 3; - - // Sync the linedata of the line that started this slope - // TODO: Anything special for control sector based slopes later? - fslope->sourceline = line; - - // Remember the way the slope is formed - highest = point.z > origin.z ? point.z : origin.z; - lowest = point.z < origin.z ? point.z : origin.z; - - for (l = 0; l < line->backsector->linecount; l++) - { - fixed_t height = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); - - if (height > highest) - highest = height; - - if (height < lowest) - lowest = height; - } - - // This line special sets extra clipping data for the frontsector's slope - fslope->highz = highest; - fslope->lowz = lowest; + MakeViaVectors(&point, &direction, dz, flags); fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); P_CalculateSlopeNormal(fslope); + + if (spawnthinker && (flags & SL_DYNAMIC)) + P_AddDynSlopeThinker(fslope, DP_BACKFLOOR, line, extent, NULL, NULL); } if(backceil) { - fixed_t highest, lowest; - size_t l; origin.z = line->frontsector->ceilingheight; point.z = line->backsector->ceilingheight; dz = FixedDiv(origin.z - point.z, extent); cslope = line->backsector->c_slope = - P_MakeSlope(&point, &direction, dz, flags); - - // Set up some shit - cslope->extent = extent; - cslope->refpos = 4; - - // Sync the linedata of the line that started this slope - // TODO: Anything special for control sector based slopes later? - cslope->sourceline = line; - - // Remember the way the slope is formed - highest = point.z > origin.z ? point.z : origin.z; - lowest = point.z < origin.z ? point.z : origin.z; - - for (l = 0; l < line->backsector->linecount; l++) - { - fixed_t height = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); - - if (height > highest) - highest = height; - - if (height < lowest) - lowest = height; - } - - // This line special sets extra clipping data for the backsector's slope - cslope->highz = highest; - cslope->lowz = lowest; + MakeViaVectors(&point, &direction, dz, flags); cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); P_CalculateSlopeNormal(cslope); + + if (spawnthinker && (flags & SL_DYNAMIC)) + P_AddDynSlopeThinker(cslope, DP_BACKCEIL, line, extent, NULL, NULL); } } @@ -518,63 +414,99 @@ void P_SpawnSlope_Line(int linenum) return; } -// -// P_NewVertexSlope -// -// Creates a new slope from three vertices with the specified IDs -// -static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags) +/// Creates a new slope from three mapthings with the specified IDs +static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags, const boolean spawnthinker) { size_t i; - mapthing_t *mt = mapthings; + mapthing_t* mt = mapthings; + mapthing_t* vertices[3] = {0}; + INT16 tags[3] = {tag1, tag2, tag3}; - pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); - memset(ret, 0, sizeof(*ret)); - - // Start by setting flags - ret->flags = flags; - - // Now set up the vertex list - ret->vertices = Z_Malloc(3*sizeof(mapthing_t), PU_LEVEL, NULL); - memset(ret->vertices, 0, 3*sizeof(mapthing_t)); + vector3_t vx[3]; + pslope_t* ret = Slope_Add(flags); // And... look for the vertices in question. for (i = 0; i < nummapthings; i++, mt++) { if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something! continue; - if (!ret->vertices[0] && mt->angle == tag1) - ret->vertices[0] = mt; - else if (!ret->vertices[1] && mt->angle == tag2) - ret->vertices[1] = mt; - else if (!ret->vertices[2] && mt->angle == tag3) - ret->vertices[2] = mt; + if (!vertices[0] && mt->angle == tag1) + vertices[0] = mt; + else if (!vertices[1] && mt->angle == tag2) + vertices[1] = mt; + else if (!vertices[2] && mt->angle == tag3) + vertices[2] = mt; } // Now set heights for each vertex, because they haven't been set yet for (i = 0; i < 3; i++) { - mt = ret->vertices[i]; + mt = vertices[i]; if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?) - I_Error("P_NewVertexSlope: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1); + I_Error("MakeViaMapthings: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1); + vx[i].x = mt->x << FRACBITS; + vx[i].y = mt->y << FRACBITS; if (mt->extrainfo) - mt->z = mt->options; + vx[i].z = mt->options << FRACBITS; else - mt->z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight >> FRACBITS) + (mt->options >> ZSHIFT); + vx[i].z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight) + ((mt->options >> ZSHIFT) << FRACBITS); } - P_ReconfigureVertexSlope(ret); - ret->refpos = 5; + ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]); - // Add to the slope list - ret->next = slopelist; - slopelist = ret; - - slopecount++; - ret->id = slopecount; + if (spawnthinker && (flags & SL_DYNAMIC)) + P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx); return ret; } +/// Create vertex based slopes. +static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) +{ + line_t *line = lines + linenum; + side_t *side; + pslope_t **slopetoset; + UINT16 tag1, tag2, tag3; + + UINT8 flags = 0; + if (line->flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (line->flags & ML_NOTAILS) + flags |= SL_DYNAMIC; + + switch(line->special) + { + case 704: + slopetoset = &line->frontsector->f_slope; + side = &sides[line->sidenum[0]]; + break; + case 705: + slopetoset = &line->frontsector->c_slope; + side = &sides[line->sidenum[0]]; + break; + case 714: + slopetoset = &line->backsector->f_slope; + side = &sides[line->sidenum[1]]; + break; + case 715: + slopetoset = &line->backsector->c_slope; + side = &sides[line->sidenum[1]]; + default: + return; + } + + if (line->flags & ML_NOKNUX) + { + tag1 = line->tag; + tag2 = side->textureoffset >> FRACBITS; + tag3 = side->rowoffset >> FRACBITS; + } + else + tag1 = tag2 = tag3 = line->tag; + + *slopetoset = MakeViaMapthings(tag1, tag2, tag3, flags, spawnthinker); + + side->sector->hasslope = true; +} // @@ -620,56 +552,20 @@ pslope_t *P_SlopeById(UINT16 id) return ret; } -// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes -void P_ResetDynamicSlopes(void) { +/// Reset slopes and read them from special lines. +void P_ResetDynamicSlopes(const UINT32 fromsave) { size_t i; -#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning - boolean warned = false; -#endif + + boolean spawnthinkers = !(boolean)fromsave; slopelist = NULL; slopecount = 0; - // We'll handle copy slopes later, after all the tag lists have been made. - // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you. + /// Generates line special-defined slopes. for (i = 0; i < numlines; i++) { switch (lines[i].special) { -#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning -#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");} - case 386: - case 387: - case 388: - lines[i].special += 700-386; - WARNME - P_SpawnSlope_Line(i); - break; - - case 389: - case 390: - case 391: - case 392: - lines[i].special += 710-389; - WARNME - P_SpawnSlope_Line(i); - break; - - case 393: - lines[i].special = 703; - WARNME - P_SpawnSlope_Line(i); - break; - - case 394: - case 395: - case 396: - lines[i].special += 720-394; - WARNME - break; - -#endif - case 700: case 701: case 702: @@ -678,63 +574,35 @@ void P_ResetDynamicSlopes(void) { case 711: case 712: case 713: - P_SpawnSlope_Line(i); + line_SpawnViaLine(i, spawnthinkers); break; case 704: case 705: case 714: case 715: - { - pslope_t **slopetoset; - size_t which = lines[i].special; - - UINT8 flags = SL_VERTEXSLOPE; - if (lines[i].flags & ML_NOSONIC) - flags |= SL_NOPHYSICS; - if (!(lines[i].flags & ML_NOTAILS)) - flags |= SL_NODYNAMIC; - - if (which == 704) - { - slopetoset = &lines[i].frontsector->f_slope; - which = 0; - } - else if (which == 705) - { - slopetoset = &lines[i].frontsector->c_slope; - which = 0; - } - else if (which == 714) - { - slopetoset = &lines[i].backsector->f_slope; - which = 1; - } - else // 715 - { - slopetoset = &lines[i].backsector->c_slope; - which = 1; - } - - if (lines[i].flags & ML_NOKNUX) - *slopetoset = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[which]].textureoffset >> FRACBITS, - sides[lines[i].sidenum[which]].rowoffset >> FRACBITS, flags); - else - *slopetoset = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags); - - sides[lines[i].sidenum[which]].sector->hasslope = true; - } + line_SpawnViaVertexes(i, spawnthinkers); break; default: break; } } + + /// Copies slopes from tagged sectors via line specials. + /// \note Doesn't actually copy, but instead they share the same pointers. + for (i = 0; i < numlines; i++) + switch (lines[i].special) + { + case 720: + case 721: + case 722: + P_CopySectorSlope(&lines[i]); + default: + break; + } } - - - // ============================================================================ // // Various utilities related to slopes diff --git a/src/p_slopes.h b/src/p_slopes.h index b802ec25f..8f9e7d61e 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -13,14 +13,17 @@ #ifndef P_SLOPES_H__ #define P_SLOPES_H__ +#include "m_fixed.h" // Vectors + #ifdef ESLOPE + +extern pslope_t *slopelist; +extern UINT16 slopecount; + +void P_LinkSlopeThinkers (void); + void P_CalculateSlopeNormal(pslope_t *slope); -void P_ResetDynamicSlopes(void); -void P_RunDynamicSlopes(void); -// P_SpawnSlope_Line -// Creates one or more slopes based on the given line type and front/back -// sectors. -void P_SpawnSlope_Line(int linenum); +void P_ResetDynamicSlopes(const UINT32 fromsave); // // P_CopySectorSlope @@ -42,7 +45,34 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); -#endif -// EOF +/// Dynamic plane type enum for the thinker. Will have a different functionality depending on this. +typedef enum { + DP_FRONTFLOOR, + DP_FRONTCEIL, + DP_BACKFLOOR, + DP_BACKCEIL, + DP_VERTEX +} dynplanetype_t; + +/// Permit slopes to be dynamically altered through a thinker. +typedef struct +{ + thinker_t thinker; + + pslope_t* slope; + dynplanetype_t type; + + // Used by line slopes. + line_t* sourceline; + fixed_t extent; + + // Used by mapthing vertex slopes. + INT16 tags[3]; + vector3_t vex[3]; +} dynplanethink_t; + +void T_DynamicSlopeLine (dynplanethink_t* th); +void T_DynamicSlopeVert (dynplanethink_t* th); #endif // #ifdef ESLOPE +#endif // #ifndef P_SLOPES_H__ diff --git a/src/p_spec.c b/src/p_spec.c index 4bb03ca1a..c6679e190 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1644,7 +1644,7 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector) e->sector = sector; e->timer = (line->backsector->ceilingheight>>FRACBITS)+(line->backsector->floorheight>>FRACBITS); P_SetTarget(&e->caller, mobj); // Use P_SetTarget to make sure the mobj doesn't get freed while we're delaying. - P_AddThinker(&e->thinker); + P_AddThinker(THINK_MAIN, &e->thinker); } /** Used by P_RunTriggerLinedef to check a NiGHTS trigger linedef's conditions @@ -2253,7 +2253,7 @@ void P_SwitchWeather(INT32 weathernum) thinker_t *think; precipmobj_t *precipmobj; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker @@ -2269,7 +2269,7 @@ void P_SwitchWeather(INT32 weathernum) precipmobj_t *precipmobj; state_t *st; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker @@ -3144,7 +3144,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) scroll_t *scroller; thinker_t *th; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next) { if (th->function.acp1 != (actionf_p1)T_Scroll) continue; @@ -3980,11 +3980,8 @@ void P_SetupSignExit(player_t *player) // didn't find any signposts in the exit sector. // spin all signposts in the level then. - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - thing = (mobj_t *)think; if (thing->type != MT_SIGN) continue; @@ -4012,11 +4009,8 @@ boolean P_IsFlagAtBase(mobjtype_t flag) mobj_t *mo; INT32 specialnum = 0; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (mo->type != flag) @@ -4445,11 +4439,8 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers // Find the center of the Eggtrap and release all the pretty animals! // The chimps are my friends.. heeheeheheehehee..... - LouisJM - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_EGGTRAP) P_KillMobj(mo2, NULL, player->mo, 0); @@ -4751,11 +4742,8 @@ DoneSection2: // scan the thinkers // to find the first waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_TUBEWAYPOINT && mo2->threshold == sequence @@ -4830,11 +4818,8 @@ DoneSection2: // scan the thinkers // to find the last waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_TUBEWAYPOINT && mo2->threshold == sequence) @@ -4982,11 +4967,8 @@ DoneSection2: // scan the thinkers // to find the first waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -5020,11 +5002,8 @@ DoneSection2: } // Find waypoint before this one (waypointlow) - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -5047,11 +5026,8 @@ DoneSection2: } // Find waypoint after this one (waypointhigh) - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -5566,11 +5542,6 @@ void P_UpdateSpecials(void) // POINT LIMIT P_CheckPointLimit(); -#ifdef ESLOPE - // Dynamic slopeness - P_RunDynamicSlopes(); -#endif - // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) { @@ -5770,7 +5741,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f // Just initialise both of these to placate the compiler. i = 0; - th = thinkercap.next; + th = thlist[THINK_MAIN].next; for(;;) { @@ -5780,7 +5751,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f th = secthinkers[sec2num].thinkers[i]; else break; } - else if (th == &thinkercap) + else if (th == &thlist[THINK_MAIN]) break; // Should this FOF have spikeness? @@ -5870,7 +5841,7 @@ static void P_AddSpikeThinker(sector_t *sec, INT32 referrer) // create and initialize new thinker spikes = Z_Calloc(sizeof (*spikes), PU_LEVSPEC, NULL); - P_AddThinker(&spikes->thinker); + P_AddThinker(THINK_MAIN, &spikes->thinker); spikes->thinker.function.acp1 = (actionf_p1)T_SpikeSector; @@ -5892,7 +5863,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline) // create and initialize new thinker floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL); - P_AddThinker(&floater->thinker); + P_AddThinker(THINK_MAIN, &floater->thinker); floater->thinker.function.acp1 = (actionf_p1)T_FloatSector; @@ -5916,7 +5887,7 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec) // create an initialize new thinker bridge = Z_Calloc(sizeof (*bridge), PU_LEVSPEC, NULL); - P_AddThinker(&bridge->thinker); + P_AddThinker(THINK_MAIN, &bridge->thinker); bridge->thinker.function.acp1 = (actionf_p1)T_BridgeThinker; @@ -5952,7 +5923,7 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, // create and initialize new displacement thinker displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL); - P_AddThinker(&displace->thinker); + P_AddThinker(THINK_MAIN, &displace->thinker); displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace; displace->affectee = affectee; @@ -5979,7 +5950,7 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) // create and initialize new elevator thinker block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); - P_AddThinker(&block->thinker); + P_AddThinker(THINK_MAIN, &block->thinker); block->thinker.function.acp1 = (actionf_p1)T_MarioBlockChecker; block->sourceline = sourceline; @@ -6008,7 +5979,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) levelspecthink_t *raise; raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL); - P_AddThinker(&raise->thinker); + P_AddThinker(THINK_MAIN, &raise->thinker); raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; @@ -6047,7 +6018,7 @@ static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust) levelspecthink_t *airbob; airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL); - P_AddThinker(&airbob->thinker); + P_AddThinker(THINK_MAIN, &airbob->thinker); airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; @@ -6108,7 +6079,7 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin // create and initialize new elevator thinker thwomp = Z_Calloc(sizeof (*thwomp), PU_LEVSPEC, NULL); - P_AddThinker(&thwomp->thinker); + P_AddThinker(THINK_MAIN, &thwomp->thinker); thwomp->thinker.function.acp1 = (actionf_p1)T_ThwompSector; @@ -6144,7 +6115,7 @@ static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline) // create and initialize new thinker nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL); - P_AddThinker(&nobaddies->thinker); + P_AddThinker(THINK_MAIN, &nobaddies->thinker); nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector; @@ -6166,7 +6137,7 @@ static inline void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline) // create and initialize new thinker eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL); - P_AddThinker(&eachtime->thinker); + P_AddThinker(THINK_MAIN, &eachtime->thinker); eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker; @@ -6188,7 +6159,7 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto // create and initialize new elevator thinker elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(&elevator->thinker); + P_AddThinker(THINK_MAIN, &elevator->thinker); elevator->thinker.function.acp1 = (actionf_p1)T_CameraScanner; elevator->type = elevateBounce; @@ -6284,7 +6255,7 @@ static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *lin flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); - P_AddThinker(&flash->thinker); + P_AddThinker(THINK_MAIN, &flash->thinker); flash->thinker.function.acp1 = (actionf_p1)T_LaserFlash; flash->ffloor = ffloor; @@ -6453,7 +6424,7 @@ void P_SpawnSpecials(INT32 fromnetsave) secthinkers = Z_Calloc(numsectors * sizeof(thinkerlist_t), PU_STATIC, NULL); // Firstly, find out how many there are in each sector - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next) { if (th->function.acp1 == (actionf_p1)T_SpikeSector) secthinkers[((levelspecthink_t *)th)->sector - sectors].count++; @@ -6473,7 +6444,7 @@ void P_SpawnSpecials(INT32 fromnetsave) } // Finally, populate the lists. - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next) { size_t secnum = (size_t)-1; @@ -7368,14 +7339,6 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data; break; -#ifdef ESLOPE // Slope copy specials. Handled here for sanity. - case 720: - case 721: - case 722: - P_CopySectorSlope(&lines[i]); - break; -#endif - default: break; } @@ -7735,7 +7698,7 @@ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT3 if ((s->control = control) != -1) s->last_height = sectors[control].floorheight + sectors[control].ceilingheight; s->affectee = affectee; - P_AddThinker(&s->thinker); + P_AddThinker(THINK_MAIN, &s->thinker); } /** Initializes the scrollers. @@ -7869,7 +7832,7 @@ static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t o d->exists = true; d->timer = 1; - P_AddThinker(&d->thinker); + P_AddThinker(THINK_MAIN, &d->thinker); } /** Makes a FOF appear/disappear @@ -8358,7 +8321,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT); } - P_AddThinker(&d->thinker); + P_AddThinker(THINK_MAIN, &d->thinker); } /** Makes a FOF fade @@ -8428,7 +8391,7 @@ static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, ext } sector->fadecolormapdata = d; - P_AddThinker(&d->thinker); // add thinker + P_AddThinker(THINK_MAIN, &d->thinker); } void T_FadeColormap(fadecolormap_t *d) @@ -8547,7 +8510,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 else f->roverfriction = false; - P_AddThinker(&f->thinker); + P_AddThinker(THINK_MAIN, &f->thinker); } /** Applies friction to all things in a sector. @@ -8713,7 +8676,7 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t * p->z = p->source->z; } p->affectee = affectee; - P_AddThinker(&p->thinker); + P_AddThinker(THINK_MAIN, &p->thinker); } diff --git a/src/p_tick.c b/src/p_tick.c index 6f7c96ead..56f91d820 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -35,8 +35,8 @@ tic_t leveltime; // but the first element must be thinker_t. // -// Both the head and tail of the thinker list. -thinker_t thinkercap; +// The entries will behave like both the head and tail of the lists. +thinker_t thlist[NUM_THINKERLISTS]; void Command_Numthinkers_f(void) { @@ -102,7 +102,7 @@ void Command_Numthinkers_f(void) return; } - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != action) continue; @@ -139,11 +139,8 @@ void Command_CountMobjs_f(void) count = 0; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - if (((mobj_t *)th)->type == i) count++; } @@ -159,11 +156,8 @@ void Command_CountMobjs_f(void) { count = 0; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - if (((mobj_t *)th)->type == i) count++; } @@ -178,19 +172,18 @@ void Command_CountMobjs_f(void) // void P_InitThinkers(void) { - thinkercap.prev = thinkercap.next = &thinkercap; + UINT8 i; + for (i = 0; i < NUM_THINKERLISTS; i++) + thlist[i].prev = thlist[i].next = &thlist[i]; } -// -// P_AddThinker // Adds a new thinker at the end of the list. -// -void P_AddThinker(thinker_t *thinker) +void P_AddThinker(const thinklistnum_t n, thinker_t *thinker) { - thinkercap.prev->next = thinker; - thinker->next = &thinkercap; - thinker->prev = thinkercap.prev; - thinkercap.prev = thinker; + thlist[n].prev->next = thinker; + thinker->next = &thlist[n]; + thinker->prev = thlist[n].prev; + thlist[n].prev = thinker; thinker->references = 0; // killough 11/98: init reference counter to 0 } @@ -245,10 +238,23 @@ 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; } /* @@ -296,11 +302,16 @@ if ((*mop = targ) != NULL) // Set new target and if non-NULL, increase its count // static inline void P_RunThinkers(void) { - for (currentthinker = thinkercap.next; currentthinker != &thinkercap; currentthinker = currentthinker->next) + size_t i; + for (i = 0; i < NUM_THINKERLISTS; i++) { - if (currentthinker->function.acp1) - currentthinker->function.acp1(currentthinker); + for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next) + { + if (currentthinker->function.acp1) + currentthinker->function.acp1(currentthinker); + } } + } // diff --git a/src/p_user.c b/src/p_user.c index ac951a8fa..1294b27d9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -343,11 +343,8 @@ UINT8 P_FindLowestMare(void) // scan the thinkers // to find the egg capsule with the lowest mare - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_EGGCAPSULE && mo2->health > 0) @@ -392,11 +389,8 @@ boolean P_TransferToNextMare(player_t *player) // scan the thinkers // to find the closest axis point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_AXIS) @@ -443,11 +437,8 @@ static mobj_t *P_FindAxis(INT32 mare, INT32 axisnum) // scan the thinkers // to find the closest axis point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; // Axis things are only at beginning of list. @@ -476,11 +467,8 @@ static mobj_t *P_FindAxisTransfer(INT32 mare, INT32 axisnum, mobjtype_t type) // scan the thinkers // to find the closest axis point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; // Axis things are only at beginning of list. @@ -515,11 +503,8 @@ void P_TransferToAxis(player_t *player, INT32 axisnum) // scan the thinkers // to find the closest axis point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_AXIS) @@ -615,11 +600,8 @@ static void P_DeNightserizePlayer(player_t *player) } // Check to see if the player should be killed. - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (!(mo2->type == MT_NIGHTSDRONE)) continue; @@ -1630,11 +1612,8 @@ void P_SpawnShieldOrb(player_t *player) } // blaze through the thinkers to see if an orb already exists! - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - shieldobj = (mobj_t *)th; if (shieldobj->type == orbtype && shieldobj->target == player->mo) @@ -3168,7 +3147,7 @@ static void P_DoClimbing(player_t *player) angle_t sideangle; fixed_t dx, dy; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)T_Scroll) continue; @@ -4604,11 +4583,8 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) if (player->powers[pw_super]) // increase range when super range *= 2; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2 == player->mo) @@ -5801,11 +5777,8 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad fixed_t truexspeed = xspeed*(!(player->pflags & PF_TRANSFERTOCLOSEST) && player->mo->target->flags2 & MF2_AMBUSH ? -1 : 1); // Find next waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; // Axis things are only at beginning of list. @@ -5837,11 +5810,8 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad // Look for a wrapper point. if (!transfer1) { - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; // Axis things are only at beginning of list. @@ -5865,11 +5835,8 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad } if (!transfer2) { - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; // Axis things are only at beginning of list. @@ -6572,11 +6539,8 @@ static void P_NiGHTSMovement(player_t *player) // scan the thinkers // to find the closest axis point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_AXIS) @@ -7382,11 +7346,8 @@ static void P_MovePlayer(player_t *player) thinker_t *th; mobj_t *mo2; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_EGGCAPSULE @@ -8291,11 +8252,8 @@ static void P_DoZoomTube(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); // Find next waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -8425,11 +8383,8 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); // Find next waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -8450,11 +8405,8 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, wrapping to start...\n"); // Wrap around back to first waypoint - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker - continue; - mo2 = (mobj_t *)th; if (mo2->type != MT_TUBEWAYPOINT) @@ -8516,11 +8468,8 @@ static void P_NukeAllPlayers(player_t *player) mobj_t *mo; thinker_t *think; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (!mo->player) @@ -8564,11 +8513,8 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) } } - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (!(mo->flags & MF_SHOOTABLE) && !(mo->type == MT_EGGGUARD || mo->type == MT_MINUS)) @@ -8615,11 +8561,8 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) const angle_t span = (bullet ? ANG30 : ANGLE_90); fixed_t dist, closestdist = 0; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { - if (think->function.acp1 != (actionf_p1)P_MobjThinker) - continue; // not a mobj thinker - mo = (mobj_t *)think; if (!(mo->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR|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 @@ -8754,11 +8697,8 @@ void P_FindEmerald(void) // scan the remaining thinkers // to find all emeralds - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (mo2->type == MT_EMERHUNT) { @@ -9982,11 +9922,8 @@ static mobj_t *P_GetAxis(INT32 num) thinker_t *th; mobj_t *mobj; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - 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. @@ -10399,14 +10336,8 @@ void P_PlayerThink(player_t *player) if (player->flashcount) player->flashcount--; - // Re-fixed by Jimita (11-12-2018) - if (player->awayviewtics) - { + if (player->awayviewtics && player->awayviewtics != -1) player->awayviewtics--; - if (!player->awayviewtics) - player->awayviewtics = -1; - // The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1. - } /// \note do this in the cheat code if (player->pflags & PF_NOCLIP) @@ -10479,6 +10410,44 @@ void P_PlayerThink(player_t *player) if (player->exiting && countdown2) player->exiting = 5; + // Same check as below, just at 1 second before + // so we can fade music + if (!exitfadestarted && + player->exiting > 0 && player->exiting <= 1*TICRATE && + (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && + // don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop + (gametype == GT_RACE || gametype == GT_COMPETITION ? countdown2 == 0 : true) && // don't fade on timeout + player->lives > 0 && // don't fade on game over (competition) + P_IsLocalPlayer(player)) + { + if (cv_playersforexit.value) + { + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || players[i].bot) + continue; + if (players[i].lives <= 0) + continue; + + if (!players[i].exiting || players[i].exiting > 1*TICRATE) + break; + } + + if (i == MAXPLAYERS) + { + exitfadestarted = true; + S_FadeOutStopMusic(1*MUSICRATE); + } + } + else + { + exitfadestarted = true; + S_FadeOutStopMusic(1*MUSICRATE); + } + } + if (player->exiting == 2 || countdown2 == 2) { if (cv_playersforexit.value) // Count to be sure everyone's exited @@ -10591,11 +10560,8 @@ void P_PlayerThink(player_t *player) fixed_t y = player->mo->y; fixed_t z = player->mo->z; - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - mo2 = (mobj_t *)th; if (!(mo2->type == MT_RING || mo2->type == MT_COIN @@ -11398,9 +11364,6 @@ void P_PlayerAfterThink(player_t *player) } } - if (player->awayviewtics < 0) - player->awayviewtics = 0; - // spectator invisibility and nogravity. if ((netgame || multiplayer) && player->spectator) { diff --git a/src/r_data.c b/src/r_data.c index 838bc160c..c490cc7da 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -578,16 +578,7 @@ void R_LoadTextures(void) // but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures. for (w = 0, numtextures = 0; w < numwadfiles; w++) { - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); - } + // Count the textures from TEXTURES lumps texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); while (texturesLumpPos != INT16_MAX) @@ -596,18 +587,43 @@ void R_LoadTextures(void) texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); } - // Add all the textures between TX_START and TX_END - if (texstart != INT16_MAX && texend != INT16_MAX) + // Count single-patch textures + + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + } + + if (texstart == INT16_MAX || texend == INT16_MAX) + continue; + + texstart++; // Do not count the first marker + + // PK3s have subfolders, so we can't just make a simple sum + if (wadfiles[w]->type == RET_PK3) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + numtextures++; + } + } + else // Add all the textures between TX_START and TX_END { numtextures += (UINT32)(texend - texstart); } - - // If no textures found by this point, bomb out - if (!numtextures && w == (numwadfiles - 1)) - { - I_Error("No textures detected in any WADs!\n"); - } } + + // If no textures found by this point, bomb out + if (!numtextures) + I_Error("No textures detected in any WADs!\n"); + // Allocate memory and initialize to 0 for all the textures we are initialising. // There are actually 5 buffers allocated in one for convenience. textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); @@ -642,7 +658,7 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) @@ -652,9 +668,16 @@ void R_LoadTextures(void) if (texstart == INT16_MAX || texend == INT16_MAX) continue; + texstart++; // Do not count the first marker + // Work through each lump between the markers in the WAD. - for (j = 0; j < (texend - texstart); i++, j++) + for (j = 0; j < (texend - texstart); j++) { + if (wadfiles[w]->type == RET_PK3) + { + if (W_IsLumpFolder((UINT16)w, texstart + j)) // Check if lump is a folder + continue; // If it is then SKIP IT + } patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); @@ -684,6 +707,7 @@ void R_LoadTextures(void) texturewidthmask[i] = k - 1; textureheight[i] = texture->height << FRACBITS; + i++; } } } @@ -1293,14 +1317,23 @@ void R_ReInitColormaps(UINT16 num) { char colormap[9] = "COLORMAP"; lumpnum_t lump; + const lumpnum_t basecolormaplump = W_GetNumForName(colormap); if (num > 0 && num <= 10000) snprintf(colormap, 8, "CLM%04u", num-1); // Load in the light tables, now 64k aligned for smokie... lump = W_GetNumForName(colormap); if (lump == LUMPERROR) - lump = W_GetNumForName("COLORMAP"); - W_ReadLump(lump, colormaps); + lump = basecolormaplump; + else + { + if (W_LumpLength(lump) != W_LumpLength(basecolormaplump)) + { + CONS_Alert(CONS_WARNING, "%s lump size does not match COLORMAP, results may be unexpected.\n", colormap); + } + } + + W_ReadLumpHeader(lump, colormaps, W_LumpLength(basecolormaplump), 0U); // Init Boom colormaps. R_ClearColormaps(); @@ -2242,9 +2275,8 @@ void R_PrecacheLevel(void) spritepresent = calloc(numsprites, sizeof (*spritepresent)); if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "R_PrecacheLevel"); - for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - spritepresent[((mobj_t *)th)->sprite] = 1; + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + spritepresent[((mobj_t *)th)->sprite] = 1; spritememory = 0; for (i = 0; i < numsprites; i++) diff --git a/src/r_defs.h b/src/r_defs.h index e7315b35c..def7b46f3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -237,46 +237,27 @@ typedef struct linechain_s // Slopes #ifdef ESLOPE typedef enum { - SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope - SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it - SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position - SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things + SL_NOPHYSICS = 1, /// This plane will have no physics applied besides the positioning. + SL_DYNAMIC = 1<<1, /// This plane slope will be assigned a thinker to make it dynamic. } slopeflags_t; typedef struct pslope_s { UINT16 id; // The number of the slope, mostly used for netgame syncing purposes + struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later - // --- Information used in clipping/projection --- - // Origin vector for the plane - vector3_t o; + // The plane's definition. + vector3_t o; /// Plane origin. + vector3_t normal; /// Plane normal. - // 2-Dimentional vector (x, y) normalized. Used to determine distance from - // the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle) - vector2_t d; - - // The rate at which z changes based on distance from the origin plane. - fixed_t zdelta; - - // The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red - vector3_t normal; - - // For comparing when a slope should be rendered - fixed_t lowz; - fixed_t highz; + vector2_t d; /// Precomputed normalized projection of the normal over XY. + fixed_t zdelta; /// Precomputed Z unit increase per XY unit. // This values only check and must be updated if the slope itself is modified - angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees) - angle_t xydirection; // The direction the slope is facing (north, west, south, etc.) - - struct line_s *sourceline; // The line that generated the slope - fixed_t extent; // Distance value used for recalculating zdelta - UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) + angle_t zangle; /// Precomputed angle of the plane going up from the ground (not measured in degrees). + angle_t xydirection;/// Precomputed angle of the normal's projection on the XY plane. UINT8 flags; // Slope options - mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor - - struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later } pslope_t; #endif diff --git a/src/st_stuff.c b/src/st_stuff.c index 1cf221bc9..132eada06 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2306,10 +2306,8 @@ static void ST_doItemFinderIconsAndSound(void) return; // Scan thinkers to find emblem mobj with these ids - for (th = thinkercap.next; th != &thinkercap; th = th->next) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; mo2 = (mobj_t *)th; if (mo2->type == MT_EMBLEM) diff --git a/src/v_video.c b/src/v_video.c index 29e5ecd6b..df342e74b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1322,7 +1322,7 @@ static UINT32 V_GetHWConsBackColor(void) switch (cons_backcolor.value) { case 0: hwcolor = 0xffffff00; break; // White - case 1: hwcolor = 0x80808000; break; // Gray + case 1: hwcolor = 0x80808000; break; // Black case 2: hwcolor = 0xdeb88700; break; // Sepia case 3: hwcolor = 0x40201000; break; // Brown case 4: hwcolor = 0xfa807200; break; // Pink @@ -1633,15 +1633,25 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color) UINT32 hwcolor; switch (color) { - case 0: hwcolor = 0xffffff00; break; // White - case 1: hwcolor = 0x00000000; break; // Gray // Note this is different from V_DrawFadeConsBack - case 2: hwcolor = 0x40201000; break; // Brown - case 3: hwcolor = 0xff000000; break; // Red - case 4: hwcolor = 0xff800000; break; // Orange - case 5: hwcolor = 0x80800000; break; // Yellow - case 6: hwcolor = 0x00800000; break; // Green - case 7: hwcolor = 0x0000ff00; break; // Blue - case 8: hwcolor = 0x4080ff00; break; // Cyan + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x00000000; break; // Black // Note this is different from V_DrawFadeConsBack + case 2: hwcolor = 0xdeb88700; break; // Sepia + case 3: hwcolor = 0x40201000; break; // Brown + case 4: hwcolor = 0xfa807200; break; // Pink + case 5: hwcolor = 0xff69b400; break; // Raspberry + case 6: hwcolor = 0xff000000; break; // Red + case 7: hwcolor = 0xffd68300; break; // Creamsicle + case 8: hwcolor = 0xff800000; break; // Orange + case 9: hwcolor = 0xdaa52000; break; // Gold + case 10: hwcolor = 0x80800000; break; // Yellow + case 11: hwcolor = 0x00ff0000; break; // Emerald + case 12: hwcolor = 0x00800000; break; // Green + case 13: hwcolor = 0x4080ff00; break; // Cyan + case 14: hwcolor = 0x4682b400; break; // Steel + case 15: hwcolor = 0x1e90ff00; break; // Periwinkle + case 16: hwcolor = 0x0000ff00; break; // Blue + case 17: hwcolor = 0xff00ff00; break; // Purple + case 18: hwcolor = 0xee82ee00; break; // Lavender // Default green default: hwcolor = 0x00800000; break; } diff --git a/src/w_wad.c b/src/w_wad.c index 82ef21d7f..d02ce9ce6 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -162,9 +162,15 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) { FILE *handle; - strncpy(filenamebuf, *filename, MAX_WADPATH); - filenamebuf[MAX_WADPATH - 1] = '\0'; - *filename = filenamebuf; + // Officially, strncpy should not have overlapping buffers, since W_VerifyNMUSlumps is called after this, and it + // changes filename to point at filenamebuf, it would technically be doing that. I doubt any issue will occur since + // they point to the same location, but it's better to be safe and this is a simple change. + if (filenamebuf != *filename) + { + strncpy(filenamebuf, *filename, MAX_WADPATH); + filenamebuf[MAX_WADPATH - 1] = '\0'; + *filename = filenamebuf; + } // open wad file if ((handle = fopen(*filename, "rb")) == NULL) @@ -1133,6 +1139,22 @@ boolean W_IsLumpWad(lumpnum_t lumpnum) return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned } +// +// W_IsLumpFolder +// Is the lump a folder? (in a PK3 obviously) +// +boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) +{ + if (wadfiles[wad]->type == RET_PK3) + { + const char *name = wadfiles[wad]->lumpinfo[lump].name2; + + return (name[strlen(name)-1] == '/'); // folders end in '/' + } + + return false; // non-PK3s don't have folders +} + #ifdef HAVE_ZLIB /* report a zlib or i/o error */ void zerr(int ret) diff --git a/src/w_wad.h b/src/w_wad.h index 8ffcc1d03..651738850 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -151,6 +151,7 @@ size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump); size_t W_LumpLength(lumpnum_t lumpnum); boolean W_IsLumpWad(lumpnum_t lumpnum); // for loading maps from WADs in PK3s +boolean W_IsLumpFolder(UINT16 wad, UINT16 lump); // for detecting folder "lumps" #ifdef HAVE_ZLIB void zerr(int ret); // zlib error checking