diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3603bb20d..f7755c148 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -85,6 +85,10 @@ tic_t jointimeout = (10*TICRATE); static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? +// Incremented by cv_joindelay when a client joins, decremented each tic. +// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled. +static tic_t joindelay = 0; + UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. @@ -3077,6 +3081,8 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_joindelay = {"joindelay", "10", CV_SAVE, joindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3164,6 +3170,8 @@ void SV_ResetServer(void) neededtic = maketic; tictoclear = maketic; + joindelay = 0; + for (i = 0; i < MAXNETNODES; i++) ResetNode(i); @@ -3613,6 +3621,9 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, M_GetText("No players from\nthis node.")); else if (luafiletransfers) SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); + else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE) + SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), + (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); else { #ifndef NONET @@ -3670,6 +3681,7 @@ static void HandleConnect(SINT8 node) DEBFILE("send savegame\n"); } SV_AddWaitingPlayers(names[0], names[1]); + joindelay += cv_joindelay.value * TICRATE; player_joining = true; } #else @@ -5038,12 +5050,21 @@ void NetUpdate(void) hu_resynching = true; } } + Net_AckTicker(); + // Handle timeouts to prevent definitive freezes from happenning if (server) + { for (i = 1; i < MAXNETNODES; i++) if (nodeingame[i] && freezetimeout[i] < I_GetTime()) Net_ConnectionTimeout(i); + + // In case the cvar value was lowered + if (joindelay) + joindelay = min(joindelay - 1, 3 * cv_joindelay.value * TICRATE); + } + nowtime /= NEWTICRATERATIO; if (nowtime > resptime) { @@ -5051,6 +5072,7 @@ void NetUpdate(void) M_Ticker(); CON_Ticker(); } + SV_FileSendTicker(); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 7e5061ff2..463240a2a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -515,7 +515,7 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; -extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout; +extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1fd53499a..dfc7351f5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -573,6 +573,7 @@ void D_RegisterServerCommands(void) // d_clisrv CV_RegisterVar(&cv_maxplayers); + CV_RegisterVar(&cv_joindelay); CV_RegisterVar(&cv_rejointimeout); CV_RegisterVar(&cv_resynchattempts); CV_RegisterVar(&cv_maxsend); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 818e760c9..703b924bb 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -412,9 +412,9 @@ static int libd_cachePatch(lua_State *L) HUDONLY luapat = patchinfohead; - lumpnum = W_CheckNumForName(luaL_checkstring(L, 1)); + lumpnum = W_CheckNumForLongName(luaL_checkstring(L, 1)); if (lumpnum == LUMPERROR) - lumpnum = W_GetNumForName("MISSING"); + lumpnum = W_GetNumForLongName("MISSING"); for (i = 0; i < numluapatches; i++) { @@ -454,7 +454,7 @@ static int libd_cachePatch(lua_State *L) numluapatches++; #else HUDONLY - LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); + LUA_PushUserdata(L, W_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); #endif return 1; } diff --git a/src/lua_script.c b/src/lua_script.c index c7ff4d4c3..50b729b25 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1013,16 +1013,8 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) if (!rover) WRITEUINT8(save_p, ARCH_NULL); else { - ffloor_t *r2; - UINT16 i = 0; - // search for id - for (r2 = rover->target->ffloors; r2; r2 = r2->next) - { - if (r2 == rover) - break; - i++; - } - if (!r2) + UINT16 i = P_GetFFloorID(rover); + if (i == UINT16_MAX) // invalid ID WRITEUINT8(save_p, ARCH_NULL); else { diff --git a/src/m_menu.c b/src/m_menu.c index 1069f0f30..c5f10b2bd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1583,7 +1583,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "General", NULL, 0}, #ifndef NONET {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server name", &cv_servername, 7}, + NULL, "Server name", &cv_servername, 7}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, @@ -1628,8 +1628,9 @@ static menuitem_t OP_ServerOptionsMenu[] = #ifndef NONET {IT_HEADER, NULL, "Advanced", NULL, 225}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, + {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251}, #endif }; @@ -10822,7 +10823,8 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins + OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -10834,6 +10836,7 @@ static void M_ServerOptions(INT32 choice) ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR | IT_CV_STRING)); OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR; } #endif diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 31a4895ba..3c3c507cd 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -395,7 +395,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; @@ -615,7 +615,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; diff --git a/src/p_floor.c b/src/p_floor.c index 179cf73c7..d6ffb95bf 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -757,7 +757,7 @@ void T_BounceCheese(bouncecheese_t *bouncer) // T_StartCrumble //////////////////////////////// ////////////////////////////////////////////////// // Crumbling platform Tails 03-11-2002 -void T_StartCrumble(elevator_t *elevator) +void T_StartCrumble(crumble_t *crumble) { ffloor_t *rover; sector_t *sector; @@ -765,84 +765,96 @@ void T_StartCrumble(elevator_t *elevator) // Once done, the no-return thinker just sits there, // constantly 'returning'... kind of an oxymoron, isn't it? - if (((elevator->floordestheight == 1 && elevator->direction == -1) - || (elevator->floordestheight == 0 && elevator->direction == 1)) - && elevator->type == elevateContinuous) // No return crumbler + if ((((crumble->flags & CF_REVERSE) && crumble->direction == -1) + || (!(crumble->flags & CF_REVERSE) && crumble->direction == 1)) + && !(crumble->flags & CF_RETURN)) { - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } - if (elevator->distance != 0) + if (crumble->timer != 0) { - if (elevator->distance > 0) // Count down the timer + if (crumble->timer > 0) // Count down the timer { - elevator->distance--; - if (elevator->distance <= 0) - elevator->distance = -15*TICRATE; // Timer until platform returns to original position. + if (--crumble->timer <= 0) + crumble->timer = -15*TICRATE; // Timer until platform returns to original position. else { // Timer isn't up yet, so just keep waiting. - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } } - else if (++elevator->distance == 0) // Reposition back to original spot + else if (++crumble->timer == 0) // Reposition back to original spot { - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; for (rover = sector->ffloors; rover; rover = rover->next) { - if (rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == elevator->sourceline) - { - rover->alpha = elevator->origspeed; + if (!(rover->flags & FF_CRUMBLE)) + continue; - if (rover->alpha == 0xff) - rover->flags &= ~FF_TRANSLUCENT; - } + if (!(rover->flags & FF_FLOATBOB)) + continue; + + if (rover->master != crumble->sourceline) + continue; + + rover->alpha = crumble->origalpha; + + if (rover->alpha == 0xff) + rover->flags &= ~FF_TRANSLUCENT; } } // Up! - if (elevator->floordestheight == 1) - elevator->direction = -1; + if (crumble->flags & CF_REVERSE) + crumble->direction = -1; else - elevator->direction = 1; + crumble->direction = 1; - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } // Flash to indicate that the platform is about to return. - if (elevator->distance > -224 && (leveltime % ((abs(elevator->distance)/8) + 1) == 0)) + if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0)) { - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_NORETURN) && rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == elevator->sourceline) - { - if (rover->alpha == elevator->origspeed) - { - rover->flags |= FF_TRANSLUCENT; - rover->alpha = 0x00; - } - else - { - if (elevator->origspeed == 0xff) - rover->flags &= ~FF_TRANSLUCENT; + if (rover->flags & FF_NORETURN) + continue; - rover->alpha = elevator->origspeed; - } + if (!(rover->flags & FF_CRUMBLE)) + continue; + + if (!(rover->flags & FF_FLOATBOB)) + continue; + + if (rover->master != crumble->sourceline) + continue; + + if (rover->alpha == crumble->origalpha) + { + rover->flags |= FF_TRANSLUCENT; + rover->alpha = 0x00; + } + else + { + rover->alpha = crumble->origalpha; + + if (rover->alpha == 0xff) + rover->flags &= ~FF_TRANSLUCENT; } } } @@ -851,74 +863,62 @@ void T_StartCrumble(elevator_t *elevator) // We're about to go back to the original position, // so set this to let other thinkers know what is // about to happen. - if (elevator->distance < 0 && elevator->distance > -3) - elevator->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself + if (crumble->timer < 0 && crumble->timer > -3) + crumble->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself } - if ((elevator->floordestheight == 0 && elevator->direction == -1) - || (elevator->floordestheight == 1 && elevator->direction == 1)) // Down + if ((!(crumble->flags & CF_REVERSE) && crumble->direction == -1) + || ((crumble->flags & CF_REVERSE) && crumble->direction == 1)) // Down { - elevator->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. + crumble->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. // Only fall like this if it isn't meant to float on water - if (elevator->high != 42) + if (!(crumble->flags & CF_FLOATBOB)) { - elevator->speed += gravity; // Gain more and more speed + crumble->speed += gravity; // Gain more and more speed - if ((elevator->floordestheight == 0 && !(elevator->sector->ceilingheight < -16384*FRACUNIT)) - || (elevator->floordestheight == 1 && !(elevator->sector->ceilingheight > 16384*FRACUNIT))) + if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT) + || ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT)) { - fixed_t dest; - - if (elevator->floordestheight == 1) - dest = elevator->sector->ceilingheight + (elevator->speed*2); - else - dest = elevator->sector->ceilingheight - (elevator->speed*2); - T_MovePlane //jff 4/7/98 reverse order of ceiling/floor ( - elevator->sector, - elevator->speed, - dest, + crumble->sector, + crumble->speed, + crumble->sector->ceilingheight + crumble->direction*crumble->speed*2, false, true, // move ceiling - elevator->direction + crumble->direction ); - if (elevator->floordestheight == 1) - dest = elevator->sector->floorheight + (elevator->speed*2); - else - dest = elevator->sector->floorheight - (elevator->speed*2); - - T_MovePlane - ( - elevator->sector, - elevator->speed, - dest, - false, - false, // move floor - elevator->direction + T_MovePlane + ( + crumble->sector, + crumble->speed, + crumble->sector->floorheight + crumble->direction*crumble->speed*2, + false, + false, // move floor + crumble->direction ); - elevator->sector->ceilspeed = 42; - elevator->sector->floorspeed = elevator->speed*elevator->direction; + crumble->sector->ceilspeed = 42; + crumble->sector->floorspeed = crumble->speed*crumble->direction; } } } else // Up (restore to original position) { - elevator->sector->crumblestate = CRUMBLE_WAIT; - elevator->sector->ceilingheight = elevator->ceilingwasheight; - elevator->sector->floorheight = elevator->floorwasheight; - elevator->sector->floordata = NULL; - elevator->sector->ceilingdata = NULL; - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; - elevator->sector->moved = true; - P_RemoveThinker(&elevator->thinker); + crumble->sector->crumblestate = CRUMBLE_WAIT; + crumble->sector->ceilingheight = crumble->ceilingwasheight; + crumble->sector->floorheight = crumble->floorwasheight; + crumble->sector->floordata = NULL; + crumble->sector->ceilingdata = NULL; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; + crumble->sector->moved = true; + P_RemoveThinker(&crumble->thinker); } - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; sector->moved = true; @@ -1284,7 +1284,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) INT32 secnum = -1; boolean FOFsector = false; - while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(nobaddies->sourceline->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -1300,7 +1300,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) FOFsector = true; - while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) + while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0) { if (T_SectorHasEnemies(§ors[targetsecnum])) return; @@ -1395,7 +1395,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) eachtime->playersOnArea[i] = false; } - while ((secnum = P_FindSectorFromLineTag(eachtime->sourceline, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(eachtime->sourceline->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -1418,7 +1418,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) FOFsector = true; - while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) + while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0) { targetsec = §ors[targetsecnum]; @@ -1556,7 +1556,7 @@ void T_RaiseSector(raise_t *raise) if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata) return; - for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;) { sector = §ors[i]; @@ -1683,7 +1683,7 @@ void T_RaiseSector(raise_t *raise) raise->sector->ceilspeed = 42; raise->sector->floorspeed = speed*direction; - for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;) P_RecalcPrecipInSector(§ors[i]); } @@ -1801,7 +1801,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) sector_t *sec; floormove_t *dofloor; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -2017,7 +2017,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) elevator_t *elevator; // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; @@ -2309,7 +2309,7 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn) { - elevator_t *elevator; + crumble_t *crumble; sector_t *foundsec; INT32 i; @@ -2320,55 +2320,45 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, if (sec->crumblestate >= CRUMBLE_ACTIVATED) return 0; - // create and initialize new elevator thinker - elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(THINK_MAIN, &elevator->thinker); - elevator->thinker.function.acp1 = (actionf_p1)T_StartCrumble; + // create and initialize new crumble thinker + crumble = Z_Calloc(sizeof (*crumble), PU_LEVSPEC, NULL); + P_AddThinker(THINK_MAIN, &crumble->thinker); + crumble->thinker.function.acp1 = (actionf_p1)T_StartCrumble; - // Does this crumbler return? - if (crumblereturn) - elevator->type = elevateBounce; - else - elevator->type = elevateContinuous; - - // set up the fields according to the type of elevator action - elevator->sector = sec; - elevator->speed = 0; + // set up the fields + crumble->sector = sec; + crumble->speed = 0; if (player && player->mo && (player->mo->eflags & MFE_VERTICALFLIP)) { - elevator->direction = 1; // Up - elevator->floordestheight = 1; + crumble->direction = 1; // Up + crumble->flags |= CF_REVERSE; } else - { - elevator->direction = -1; // Down - elevator->floordestheight = 0; - } + crumble->direction = -1; // Down - elevator->floorwasheight = elevator->sector->floorheight; - elevator->ceilingwasheight = elevator->sector->ceilingheight; - elevator->distance = TICRATE; // Used for delay time - elevator->low = 0; - elevator->player = player; - elevator->origspeed = origalpha; + crumble->floorwasheight = crumble->sector->floorheight; + crumble->ceilingwasheight = crumble->sector->ceilingheight; + crumble->timer = TICRATE; + crumble->player = player; + crumble->origalpha = origalpha; - elevator->sourceline = rover->master; + crumble->sourceline = rover->master; - sec->floordata = elevator; + sec->floordata = crumble; + if (crumblereturn) + crumble->flags |= CF_RETURN; if (floating) - elevator->high = 42; - else - elevator->high = 0; + crumble->flags |= CF_FLOATBOB; - elevator->sector->crumblestate = CRUMBLE_ACTIVATED; + crumble->sector->crumblestate = CRUMBLE_ACTIVATED; - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { foundsec = §ors[i]; - P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, elevator->direction == 1 ? elevator->sector->floorheight : elevator->sector->ceilingheight, MT_CRUMBLEOBJ); + P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, crumble->direction == 1 ? crumble->sector->floorheight : crumble->sector->ceilingheight, MT_CRUMBLEOBJ); } return 1; diff --git a/src/p_map.c b/src/p_map.c index accc52836..0c21e3e69 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4223,21 +4223,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) { //If the thing was crushed by a crumbling FOF, reward the player who made it crumble! thinker_t *think; - elevator_t *crumbler; + crumble_t *crumbler; for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)T_StartCrumble) continue; - crumbler = (elevator_t *)think; + crumbler = (crumble_t *)think; if (crumbler->player && crumbler->player->mo && crumbler->player->mo != thing && crumbler->actionsector == thing->subsector->sector - && crumbler->sector == rover->master->frontsector - && (crumbler->type == elevateBounce - || crumbler->type == elevateContinuous)) + && crumbler->sector == rover->master->frontsector) { killer = crumbler->player->mo; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 8932f0bf3..1e2b74c3c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -59,9 +59,6 @@ typedef enum DRONE = 0x80, } player_saveflags; -// -// P_ArchivePlayer -// static inline void P_ArchivePlayer(void) { const player_t *player = &players[consoleplayer]; @@ -77,9 +74,6 @@ static inline void P_ArchivePlayer(void) WRITEINT32(save_p, player->continues); } -// -// P_UnArchivePlayer -// static inline void P_UnArchivePlayer(void) { INT16 skininfo = READUINT16(save_p); @@ -92,9 +86,6 @@ static inline void P_UnArchivePlayer(void) savedata.continues = READINT32(save_p); } -// -// P_NetArchivePlayers -// static void P_NetArchivePlayers(void) { INT32 i, j; @@ -300,9 +291,6 @@ static void P_NetArchivePlayers(void) } } -// -// P_NetUnArchivePlayers -// static void P_NetUnArchivePlayers(void) { INT32 i, j; @@ -799,29 +787,102 @@ static boolean P_AreStringArgsEqual(const line_t *li, const line_t *spawnli) return true; } -// -// P_NetArchiveWorld -// -static void P_NetArchiveWorld(void) +#define FD_FLAGS 0x01 +#define FD_ALPHA 0x02 + +// Check if any of the sector's FOFs differ from how they spawned +static boolean CheckFFloorDiff(const sector_t *ss) +{ + ffloor_t *rover; + + for (rover = ss->ffloors; rover; rover = rover->next) + { + if (rover->flags != rover->spawnflags + || rover->alpha != rover->spawnalpha) + { + return true; // we found an FOF that changed! + // don't bother checking for more, we do that later + } + } + return false; +} + +// Special case: save the stats of all modified ffloors along with their ffloor "number"s +// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed +static void ArchiveFFloors(const sector_t *ss) +{ + size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc + ffloor_t *rover; + UINT8 fflr_diff; + for (rover = ss->ffloors; rover; rover = rover->next) + { + fflr_diff = 0; // reset diff flags + if (rover->flags != rover->spawnflags) + fflr_diff |= FD_FLAGS; + if (rover->alpha != rover->spawnalpha) + fflr_diff |= FD_ALPHA; + + if (fflr_diff) + { + WRITEUINT16(save_p, j); // save ffloor "number" + WRITEUINT8(save_p, fflr_diff); + if (fflr_diff & FD_FLAGS) + WRITEUINT32(save_p, rover->flags); + if (fflr_diff & FD_ALPHA) + WRITEINT16(save_p, rover->alpha); + } + j++; + } + WRITEUINT16(save_p, 0xffff); +} + +static void UnArchiveFFloors(const sector_t *ss) +{ + UINT16 j = 0; // number of current ffloor in loop + UINT16 fflr_i; // saved ffloor "number" of next modified ffloor + UINT16 fflr_diff; // saved ffloor diff + ffloor_t *rover; + + rover = ss->ffloors; + if (!rover) // it is assumed sectors[i].ffloors actually exists, but just in case... + I_Error("Sector does not have any ffloors!"); + + fflr_i = READUINT16(save_p); // get first modified ffloor's number ready + for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here? + { + if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already + break; + // should NEVER need to be checked + //if (rover == NULL) + //break; + if (j != fflr_i) // this ffloor was not modified + { + j++; + rover = rover->next; + continue; + } + + fflr_diff = READUINT8(save_p); + + if (fflr_diff & FD_FLAGS) + rover->flags = READUINT32(save_p); + if (fflr_diff & FD_ALPHA) + rover->alpha = READINT16(save_p); + + fflr_i = READUINT16(save_p); // get next ffloor "number" ready + + j++; + rover = rover->next; + } +} + +static void ArchiveSectors(void) { size_t i; - INT32 statsec = 0, statline = 0; - const line_t *li = lines; - const line_t *spawnli = spawnlines; - const side_t *si; - const side_t *spawnsi; - UINT8 *put; - const sector_t *ss = sectors; const sector_t *spawnss = spawnsectors; UINT8 diff, diff2, diff3; - // initialize colormap vars because paranoia - ClearNetColormaps(); - - WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); - put = save_p; - for (i = 0; i < numsectors; i++, ss++, spawnss++) { diff = diff2 = diff3 = 0; @@ -865,20 +926,8 @@ static void P_NetArchiveWorld(void) if (ss->crumblestate) diff3 |= SD_CRUMBLESTATE; - // Check if any of the sector's FOFs differ from how they spawned - if (ss->ffloors) - { - ffloor_t *rover; - for (rover = ss->ffloors; rover; rover = rover->next) - { - if (rover->flags != rover->spawnflags - || rover->alpha != rover->spawnalpha) - { - diff |= SD_FFLOORS; // we found an FOF that changed! - break; // don't bother checking for more, we do that later - } - } - } + if (ss->ffloors && CheckFFloorDiff(ss)) + diff |= SD_FFLOORS; if (diff3) diff2 |= SD_DIFF3; @@ -888,89 +937,142 @@ static void P_NetArchiveWorld(void) if (diff) { - statsec++; - - WRITEUINT16(put, i); - WRITEUINT8(put, diff); + WRITEUINT16(save_p, i); + WRITEUINT8(save_p, diff); if (diff & SD_DIFF2) - WRITEUINT8(put, diff2); + WRITEUINT8(save_p, diff2); if (diff2 & SD_DIFF3) - WRITEUINT8(put, diff3); + WRITEUINT8(save_p, diff3); if (diff & SD_FLOORHT) - WRITEFIXED(put, ss->floorheight); + WRITEFIXED(save_p, ss->floorheight); if (diff & SD_CEILHT) - WRITEFIXED(put, ss->ceilingheight); + WRITEFIXED(save_p, ss->ceilingheight); if (diff & SD_FLOORPIC) - WRITEMEM(put, levelflats[ss->floorpic].name, 8); + WRITEMEM(save_p, levelflats[ss->floorpic].name, 8); if (diff & SD_CEILPIC) - WRITEMEM(put, levelflats[ss->ceilingpic].name, 8); + WRITEMEM(save_p, levelflats[ss->ceilingpic].name, 8); if (diff & SD_LIGHT) - WRITEINT16(put, ss->lightlevel); + WRITEINT16(save_p, ss->lightlevel); if (diff & SD_SPECIAL) - WRITEINT16(put, ss->special); + WRITEINT16(save_p, ss->special); if (diff2 & SD_FXOFFS) - WRITEFIXED(put, ss->floor_xoffs); + WRITEFIXED(save_p, ss->floor_xoffs); if (diff2 & SD_FYOFFS) - WRITEFIXED(put, ss->floor_yoffs); + WRITEFIXED(save_p, ss->floor_yoffs); if (diff2 & SD_CXOFFS) - WRITEFIXED(put, ss->ceiling_xoffs); + WRITEFIXED(save_p, ss->ceiling_xoffs); if (diff2 & SD_CYOFFS) - WRITEFIXED(put, ss->ceiling_yoffs); + WRITEFIXED(save_p, ss->ceiling_yoffs); if (diff2 & SD_FLOORANG) - WRITEANGLE(put, ss->floorpic_angle); + WRITEANGLE(save_p, ss->floorpic_angle); if (diff2 & SD_CEILANG) - WRITEANGLE(put, ss->ceilingpic_angle); + WRITEANGLE(save_p, ss->ceilingpic_angle); if (diff2 & SD_TAG) // save only the tag - WRITEINT16(put, ss->tag); + WRITEINT16(save_p, ss->tag); if (diff3 & SD_TAGLIST) // save both firsttag and nexttag { // either of these could be changed even if tag isn't - WRITEINT32(put, ss->firsttag); - WRITEINT32(put, ss->nexttag); + WRITEINT32(save_p, ss->firsttag); + WRITEINT32(save_p, ss->nexttag); } if (diff3 & SD_COLORMAP) - WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap)); + WRITEUINT32(save_p, CheckAddNetColormapToList(ss->extra_colormap)); // returns existing index if already added, or appends to net_colormaps and returns new index if (diff3 & SD_CRUMBLESTATE) - WRITEINT32(put, ss->crumblestate); - - // Special case: save the stats of all modified ffloors along with their ffloor "number"s - // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed + WRITEINT32(save_p, ss->crumblestate); if (diff & SD_FFLOORS) - { - size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc - ffloor_t *rover; - UINT8 fflr_diff; - for (rover = ss->ffloors; rover; rover = rover->next) - { - fflr_diff = 0; // reset diff flags - if (rover->flags != rover->spawnflags) - fflr_diff |= 1; - if (rover->alpha != rover->spawnalpha) - fflr_diff |= 2; - - if (fflr_diff) - { - WRITEUINT16(put, j); // save ffloor "number" - WRITEUINT8(put, fflr_diff); - if (fflr_diff & 1) - WRITEUINT32(put, rover->flags); - if (fflr_diff & 2) - WRITEINT16(put, rover->alpha); - } - j++; - } - WRITEUINT16(put, 0xffff); - } + ArchiveFFloors(ss); } } - WRITEUINT16(put, 0xffff); + WRITEUINT16(save_p, 0xffff); +} + +static void UnArchiveSectors(void) +{ + UINT16 i; + UINT8 diff, diff2, diff3; + for (;;) + { + i = READUINT16(save_p); + + if (i == 0xffff) + break; + + if (i > numsectors) + I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors)); + + diff = READUINT8(save_p); + if (diff & SD_DIFF2) + diff2 = READUINT8(save_p); + else + diff2 = 0; + if (diff2 & SD_DIFF3) + diff3 = READUINT8(save_p); + else + diff3 = 0; + + if (diff & SD_FLOORHT) + sectors[i].floorheight = READFIXED(save_p); + if (diff & SD_CEILHT) + sectors[i].ceilingheight = READFIXED(save_p); + if (diff & SD_FLOORPIC) + { + sectors[i].floorpic = P_AddLevelFlatRuntime((char *)save_p); + save_p += 8; + } + if (diff & SD_CEILPIC) + { + sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)save_p); + save_p += 8; + } + if (diff & SD_LIGHT) + sectors[i].lightlevel = READINT16(save_p); + if (diff & SD_SPECIAL) + sectors[i].special = READINT16(save_p); + + if (diff2 & SD_FXOFFS) + sectors[i].floor_xoffs = READFIXED(save_p); + if (diff2 & SD_FYOFFS) + sectors[i].floor_yoffs = READFIXED(save_p); + if (diff2 & SD_CXOFFS) + sectors[i].ceiling_xoffs = READFIXED(save_p); + if (diff2 & SD_CYOFFS) + sectors[i].ceiling_yoffs = READFIXED(save_p); + if (diff2 & SD_FLOORANG) + sectors[i].floorpic_angle = READANGLE(save_p); + if (diff2 & SD_CEILANG) + sectors[i].ceilingpic_angle = READANGLE(save_p); + if (diff2 & SD_TAG) + sectors[i].tag = READINT16(save_p); // DON'T use P_ChangeSectorTag + if (diff3 & SD_TAGLIST) + { + sectors[i].firsttag = READINT32(save_p); + sectors[i].nexttag = READINT32(save_p); + } + + if (diff3 & SD_COLORMAP) + sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p)); + if (diff3 & SD_CRUMBLESTATE) + sectors[i].crumblestate = READINT32(save_p); + + if (diff & SD_FFLOORS) + UnArchiveFFloors(§ors[i]); + } +} + +static void ArchiveLines(void) +{ + size_t i; + const line_t *li = lines; + const line_t *spawnli = spawnlines; + const side_t *si; + const side_t *spawnsi; + UINT8 diff, diff2; // no diff3 - // do lines for (i = 0; i < numlines; i++, spawnli++, li++) { - diff = diff2 = diff3 = 0; + diff = diff2 = 0; if (li->special != spawnli->special) diff |= LD_SPECIAL; @@ -1017,42 +1119,41 @@ static void P_NetArchiveWorld(void) if (diff) { - statline++; - WRITEINT16(put, i); - WRITEUINT8(put, diff); + WRITEINT16(save_p, i); + WRITEUINT8(save_p, diff); if (diff & LD_DIFF2) - WRITEUINT8(put, diff2); + WRITEUINT8(save_p, diff2); if (diff & LD_FLAG) - WRITEINT16(put, li->flags); + WRITEINT16(save_p, li->flags); if (diff & LD_SPECIAL) - WRITEINT16(put, li->special); + WRITEINT16(save_p, li->special); if (diff & LD_CLLCOUNT) - WRITEINT16(put, li->callcount); + WRITEINT16(save_p, li->callcount); si = &sides[li->sidenum[0]]; if (diff & LD_S1TEXOFF) - WRITEFIXED(put, si->textureoffset); + WRITEFIXED(save_p, si->textureoffset); if (diff & LD_S1TOPTEX) - WRITEINT32(put, si->toptexture); + WRITEINT32(save_p, si->toptexture); if (diff & LD_S1BOTTEX) - WRITEINT32(put, si->bottomtexture); + WRITEINT32(save_p, si->bottomtexture); if (diff & LD_S1MIDTEX) - WRITEINT32(put, si->midtexture); + WRITEINT32(save_p, si->midtexture); si = &sides[li->sidenum[1]]; if (diff2 & LD_S2TEXOFF) - WRITEFIXED(put, si->textureoffset); + WRITEFIXED(save_p, si->textureoffset); if (diff2 & LD_S2TOPTEX) - WRITEINT32(put, si->toptexture); + WRITEINT32(save_p, si->toptexture); if (diff2 & LD_S2BOTTEX) - WRITEINT32(put, si->bottomtexture); + WRITEINT32(save_p, si->bottomtexture); if (diff2 & LD_S2MIDTEX) - WRITEINT32(put, si->midtexture); + WRITEINT32(save_p, si->midtexture); if (diff2 & LD_ARGS) { UINT8 j; for (j = 0; j < NUMLINEARGS; j++) - WRITEINT32(put, li->args[j]); + WRITEINT32(save_p, li->args[j]); } if (diff2 & LD_STRINGARGS) { @@ -1063,34 +1164,116 @@ static void P_NetArchiveWorld(void) if (!li->stringargs[j]) { - WRITEINT32(put, 0); + WRITEINT32(save_p, 0); continue; } len = strlen(li->stringargs[j]); - WRITEINT32(put, len); + WRITEINT32(save_p, len); for (k = 0; k < len; k++) - WRITECHAR(put, li->stringargs[j][k]); + WRITECHAR(save_p, li->stringargs[j][k]); } } } } - WRITEUINT16(put, 0xffff); - R_ClearTextureNumCache(false); - - save_p = put; + WRITEUINT16(save_p, 0xffff); } -// -// P_NetUnArchiveWorld -// -static void P_NetUnArchiveWorld(void) +static void UnArchiveLines(void) { UINT16 i; line_t *li; side_t *si; - UINT8 *get; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2; // no diff3 + + for (;;) + { + i = READUINT16(save_p); + + if (i == 0xffff) + break; + if (i > numlines) + I_Error("Invalid line number %u from server", i); + + diff = READUINT8(save_p); + li = &lines[i]; + + if (diff & LD_DIFF2) + diff2 = READUINT8(save_p); + else + diff2 = 0; + + if (diff & LD_FLAG) + li->flags = READINT16(save_p); + if (diff & LD_SPECIAL) + li->special = READINT16(save_p); + if (diff & LD_CLLCOUNT) + li->callcount = READINT16(save_p); + + si = &sides[li->sidenum[0]]; + if (diff & LD_S1TEXOFF) + si->textureoffset = READFIXED(save_p); + if (diff & LD_S1TOPTEX) + si->toptexture = READINT32(save_p); + if (diff & LD_S1BOTTEX) + si->bottomtexture = READINT32(save_p); + if (diff & LD_S1MIDTEX) + si->midtexture = READINT32(save_p); + + si = &sides[li->sidenum[1]]; + if (diff2 & LD_S2TEXOFF) + si->textureoffset = READFIXED(save_p); + if (diff2 & LD_S2TOPTEX) + si->toptexture = READINT32(save_p); + if (diff2 & LD_S2BOTTEX) + si->bottomtexture = READINT32(save_p); + if (diff2 & LD_S2MIDTEX) + si->midtexture = READINT32(save_p); + if (diff2 & LD_ARGS) + { + UINT8 j; + for (j = 0; j < NUMLINEARGS; j++) + li->args[j] = READINT32(save_p); + } + if (diff2 & LD_STRINGARGS) + { + UINT8 j; + for (j = 0; j < NUMLINESTRINGARGS; j++) + { + size_t len = READINT32(save_p); + size_t k; + + if (!len) + { + Z_Free(li->stringargs[j]); + li->stringargs[j] = NULL; + continue; + } + + li->stringargs[j] = Z_Realloc(li->stringargs[j], len + 1, PU_LEVEL, NULL); + for (k = 0; k < len; k++) + li->stringargs[j][k] = READCHAR(save_p); + li->stringargs[j][len] = '\0'; + } + } + } +} + +static void P_NetArchiveWorld(void) +{ + // initialize colormap vars because paranoia + ClearNetColormaps(); + + WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); + + ArchiveSectors(); + ArchiveLines(); + R_ClearTextureNumCache(false); +} + +static void P_NetUnArchiveWorld(void) +{ + UINT16 i; if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD) I_Error("Bad $$$.sav at archive block World"); @@ -1106,188 +1289,8 @@ static void P_NetUnArchiveWorld(void) num_ffloors++; } - get = save_p; - - for (;;) - { - i = READUINT16(get); - - if (i == 0xffff) - break; - - if (i > numsectors) - I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors)); - - diff = READUINT8(get); - if (diff & SD_DIFF2) - diff2 = READUINT8(get); - else - diff2 = 0; - if (diff2 & SD_DIFF3) - diff3 = READUINT8(get); - else - diff3 = 0; - - if (diff & SD_FLOORHT) - sectors[i].floorheight = READFIXED(get); - if (diff & SD_CEILHT) - sectors[i].ceilingheight = READFIXED(get); - if (diff & SD_FLOORPIC) - { - sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get); - get += 8; - } - if (diff & SD_CEILPIC) - { - sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get); - get += 8; - } - if (diff & SD_LIGHT) - sectors[i].lightlevel = READINT16(get); - if (diff & SD_SPECIAL) - sectors[i].special = READINT16(get); - - if (diff2 & SD_FXOFFS) - sectors[i].floor_xoffs = READFIXED(get); - if (diff2 & SD_FYOFFS) - sectors[i].floor_yoffs = READFIXED(get); - if (diff2 & SD_CXOFFS) - sectors[i].ceiling_xoffs = READFIXED(get); - if (diff2 & SD_CYOFFS) - sectors[i].ceiling_yoffs = READFIXED(get); - if (diff2 & SD_FLOORANG) - sectors[i].floorpic_angle = READANGLE(get); - if (diff2 & SD_CEILANG) - sectors[i].ceilingpic_angle = READANGLE(get); - if (diff2 & SD_TAG) - sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag - if (diff3 & SD_TAGLIST) - { - sectors[i].firsttag = READINT32(get); - sectors[i].nexttag = READINT32(get); - } - - if (diff3 & SD_COLORMAP) - sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get)); - if (diff3 & SD_CRUMBLESTATE) - sectors[i].crumblestate = READINT32(get); - - if (diff & SD_FFLOORS) - { - UINT16 j = 0; // number of current ffloor in loop - UINT16 fflr_i; // saved ffloor "number" of next modified ffloor - UINT16 fflr_diff; // saved ffloor diff - ffloor_t *rover; - - rover = sectors[i].ffloors; - if (!rover) // it is assumed sectors[i].ffloors actually exists, but just in case... - I_Error("Sector does not have any ffloors!"); - - fflr_i = READUINT16(get); // get first modified ffloor's number ready - for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here? - { - if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already - break; - // should NEVER need to be checked - //if (rover == NULL) - //break; - if (j != fflr_i) // this ffloor was not modified - { - j++; - rover = rover->next; - continue; - } - - fflr_diff = READUINT8(get); - - if (fflr_diff & 1) - rover->flags = READUINT32(get); - if (fflr_diff & 2) - rover->alpha = READINT16(get); - - fflr_i = READUINT16(get); // get next ffloor "number" ready - - j++; - rover = rover->next; - } - } - } - - for (;;) - { - i = READUINT16(get); - - if (i == 0xffff) - break; - if (i > numlines) - I_Error("Invalid line number %u from server", i); - - diff = READUINT8(get); - li = &lines[i]; - - if (diff & LD_DIFF2) - diff2 = READUINT8(get); - else - diff2 = 0; - - diff3 = 0; - - if (diff & LD_FLAG) - li->flags = READINT16(get); - if (diff & LD_SPECIAL) - li->special = READINT16(get); - if (diff & LD_CLLCOUNT) - li->callcount = READINT16(get); - - si = &sides[li->sidenum[0]]; - if (diff & LD_S1TEXOFF) - si->textureoffset = READFIXED(get); - if (diff & LD_S1TOPTEX) - si->toptexture = READINT32(get); - if (diff & LD_S1BOTTEX) - si->bottomtexture = READINT32(get); - if (diff & LD_S1MIDTEX) - si->midtexture = READINT32(get); - - si = &sides[li->sidenum[1]]; - if (diff2 & LD_S2TEXOFF) - si->textureoffset = READFIXED(get); - if (diff2 & LD_S2TOPTEX) - si->toptexture = READINT32(get); - if (diff2 & LD_S2BOTTEX) - si->bottomtexture = READINT32(get); - if (diff2 & LD_S2MIDTEX) - si->midtexture = READINT32(get); - if (diff2 & LD_ARGS) - { - UINT8 j; - for (j = 0; j < NUMLINEARGS; j++) - li->args[j] = READINT32(get); - } - if (diff2 & LD_STRINGARGS) - { - UINT8 j; - for (j = 0; j < NUMLINESTRINGARGS; j++) - { - size_t len = READINT32(get); - size_t k; - - if (!len) - { - Z_Free(li->stringargs[j]); - li->stringargs[j] = NULL; - continue; - } - - li->stringargs[j] = Z_Realloc(li->stringargs[j], len + 1, PU_LEVEL, NULL); - for (k = 0; k < len; k++) - li->stringargs[j][k] = READCHAR(get); - li->stringargs[j][len] = '\0'; - } - } - } - - save_p = get; + UnArchiveSectors(); + UnArchiveLines(); } // @@ -1427,11 +1430,6 @@ static UINT32 SaveSlope(const pslope_t *slope) return 0xFFFFFFFF; } -// -// SaveMobjThinker -// -// Saves a mobj_t thinker -// static void SaveMobjThinker(const thinker_t *th, const UINT8 type) { const mobj_t *mobj = (const mobj_t *)th; @@ -1585,42 +1583,14 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (diff2 & MD2_FLOORROVER) { - ffloor_t *rover; - size_t i = 0; - UINT32 roverindex = 0; - - for (rover = mobj->floorrover->target->ffloors; rover; rover = rover->next) - { - if (rover == mobj->floorrover) - { - roverindex = i; - break; - } - i++; - } - - WRITEUINT32(save_p, (UINT32)(mobj->floorrover->target - sectors)); - WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref + WRITEUINT32(save_p, SaveSector(mobj->floorrover->target)); + WRITEUINT16(save_p, P_GetFFloorID(mobj->floorrover)); } if (diff2 & MD2_CEILINGROVER) { - ffloor_t *rover; - size_t i = 0; - UINT32 roverindex = 0; - - for (rover = mobj->ceilingrover->target->ffloors; rover; rover = rover->next) - { - if (rover == mobj->ceilingrover) - { - roverindex = i; - break; - } - i++; - } - - WRITEUINT32(save_p, (UINT32)(mobj->ceilingrover->target - sectors)); - WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref + WRITEUINT32(save_p, SaveSector(mobj->ceilingrover->target)); + WRITEUINT16(save_p, P_GetFFloorID(mobj->ceilingrover)); } if (diff & MD_SPAWNPOINT) @@ -1736,11 +1706,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->mobjnum); } -// -// SaveNoEnemiesThinker -// -// Saves a noenemies_t thinker -// static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) { const noenemies_t *ht = (const void *)th; @@ -1748,11 +1713,6 @@ static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveBounceCheeseThinker -// -// Saves a bouncecheese_t thinker -// static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) { const bouncecheese_t *ht = (const void *)th; @@ -1766,11 +1726,6 @@ static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) WRITECHAR(save_p, ht->low); } -// -// SaveContinuousFallThinker -// -// Saves a continuousfall_t thinker -// static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) { const continuousfall_t *ht = (const void *)th; @@ -1783,11 +1738,6 @@ static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->destheight); } -// -// SaveMarioBlockThinker -// -// Saves a mariothink_t thinker -// static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) { const mariothink_t *ht = (const void *)th; @@ -1800,11 +1750,6 @@ static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } -// -// SaveMarioCheckThinker -// -// Saves a mariocheck_t thinker -// static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) { const mariocheck_t *ht = (const void *)th; @@ -1813,11 +1758,6 @@ static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } -// -// SaveThwompThinker -// -// Saves a thwomp_t thinker -// static void SaveThwompThinker(const thinker_t *th, const UINT8 type) { const thwomp_t *ht = (const void *)th; @@ -1834,11 +1774,6 @@ static void SaveThwompThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, ht->sound); } -// -// SaveFloatThinker -// -// Saves a floatthink_t thinker -// static void SaveFloatThinker(const thinker_t *th, const UINT8 type) { const floatthink_t *ht = (const void *)th; @@ -1848,10 +1783,6 @@ static void SaveFloatThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } -// SaveEachTimeThinker -// -// Loads a eachtime_t from a save game -// static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) { const eachtime_t *ht = (const void *)th; @@ -1866,15 +1797,11 @@ static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) WRITECHAR(save_p, ht->triggerOnExit); } -// SaveRaiseThinker -// -// Saves a raise_t thinker -// static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) { const raise_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEINT16(save_p, ht->tag); WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEFIXED(save_p, ht->ceilingbottom); WRITEFIXED(save_p, ht->ceilingtop); @@ -1884,11 +1811,6 @@ static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->flags); } -// -// SaveCeilingThinker -// -// Saves a ceiling_t thinker -// static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) { const ceiling_t *ht = (const void *)th; @@ -1910,11 +1832,6 @@ static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->sourceline); } -// -// SaveFloormoveThinker -// -// Saves a floormove_t thinker -// static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) { const floormove_t *ht = (const void *)th; @@ -1931,11 +1848,6 @@ static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->delaytimer); } -// -// SaveLightflashThinker -// -// Saves a lightflash_t thinker -// static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) { const lightflash_t *ht = (const void *)th; @@ -1945,11 +1857,6 @@ static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->minlight); } -// -// SaveStrobeThinker -// -// Saves a strobe_t thinker -// static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) { const strobe_t *ht = (const void *)th; @@ -1962,11 +1869,6 @@ static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->brighttime); } -// -// SaveGlowThinker -// -// Saves a glow_t thinker -// static void SaveGlowThinker(const thinker_t *th, const UINT8 type) { const glow_t *ht = (const void *)th; @@ -1977,11 +1879,7 @@ static void SaveGlowThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->direction); WRITEINT32(save_p, ht->speed); } -// -// SaveFireflickerThinker -// -// Saves a fireflicker_t thinker -// + static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) { const fireflicker_t *ht = (const void *)th; @@ -1992,11 +1890,7 @@ static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->maxlight); WRITEINT32(save_p, ht->minlight); } -// -// SaveElevatorThinker -// -// Saves a elevator_t thinker -// + static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) { const elevator_t *ht = (const void *)th; @@ -2016,15 +1910,26 @@ static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->delaytimer); WRITEFIXED(save_p, ht->floorwasheight); WRITEFIXED(save_p, ht->ceilingwasheight); - WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveScrollThinker -// -// Saves a scroll_t thinker -// +static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type) +{ + const crumble_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEUINT32(save_p, SaveSector(ht->actionsector)); + WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy + WRITEINT32(save_p, ht->direction); + WRITEINT32(save_p, ht->origalpha); + WRITEINT32(save_p, ht->timer); + WRITEFIXED(save_p, ht->speed); + WRITEFIXED(save_p, ht->floorwasheight); + WRITEFIXED(save_p, ht->ceilingwasheight); + WRITEUINT8(save_p, ht->flags); +} + static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type) { const scroll_t *ht = (const void *)th; @@ -2041,11 +1946,6 @@ static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -// -// SaveFrictionThinker -// -// Saves a friction_t thinker -// static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) { const friction_t *ht = (const void *)th; @@ -2057,11 +1957,6 @@ static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->roverfriction); } -// -// SavePusherThinker -// -// Saves a pusher_t thinker -// static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) { const pusher_t *ht = (const void *)th; @@ -2081,11 +1976,6 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->slider); } -// -// SaveLaserThinker -// -// Saves a laserthink_t thinker -// static void SaveLaserThinker(const thinker_t *th, const UINT8 type) { const laserthink_t *ht = (const void *)th; @@ -2093,13 +1983,9 @@ static void SaveLaserThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEUINT32(save_p, SaveSector(ht->sec)); WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT8(save_p, ht->nobosses); } -// -// SaveLightlevelThinker -// -// Saves a lightlevel_t thinker -// static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) { const lightlevel_t *ht = (const void *)th; @@ -2112,11 +1998,6 @@ static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SaveExecutorThinker -// -// Saves a executor_t thinker -// static void SaveExecutorThinker(const thinker_t *th, const UINT8 type) { const executor_t *ht = (const void *)th; @@ -2127,11 +2008,6 @@ static void SaveExecutorThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SaveDisappearThinker -// -// Saves a disappear_t thinker -// static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) { const disappear_t *ht = (const void *)th; @@ -2145,11 +2021,6 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->exists); } -// -// SaveFadeThinker -// -// Saves a fade_t thinker -// static void SaveFadeThinker(const thinker_t *th, const UINT8 type) { const fade_t *ht = (const void *)th; @@ -2173,11 +2044,6 @@ static void SaveFadeThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->exactalpha); } -// -// SaveFadeColormapThinker -// -// Saves a fadecolormap_t thinker -// static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) { const fadecolormap_t *ht = (const void *)th; @@ -2190,11 +2056,6 @@ static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SavePlaneDisplaceThinker -// -// Saves a planedisplace_t thinker -// static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) { const planedisplace_t *ht = (const void *)th; @@ -2206,7 +2067,6 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -/// Save a dynamic slope thinker. static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type) { const dynplanethink_t* ht = (const void*)th; @@ -2222,12 +2082,6 @@ static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type } #ifdef POLYOBJECTS - -// -// SavePolyrotateThinker -// -// Saves a polyrotate_t thinker -// static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) { const polyrotate_t *ht = (const void *)th; @@ -2237,11 +2091,6 @@ static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->distance); } -// -// SavePolymoveThinker -// -// Saves a polymovet_t thinker -// static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) { const polymove_t *ht = (const void *)th; @@ -2254,11 +2103,6 @@ static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) WRITEANGLE(save_p, ht->angle); } -// -// SavePolywaypointThinker -// -// Saves a polywaypoint_t thinker -// static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) { const polywaypoint_t *ht = (const void *)th; @@ -2278,11 +2122,6 @@ static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) WRITEUINT32(save_p, SaveMobjnum(ht->target)); } -// -// SavePolyslidedoorThinker -// -// Saves a polyslidedoor_t thinker -// static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) { const polyslidedoor_t *ht = (const void *)th; @@ -2302,11 +2141,6 @@ static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->closing); } -// -// SavePolyswingdoorThinker -// -// Saves a polyswingdoor_t thinker -// static void SavePolyswingdoorThinker(const thinker_t *th, const UINT8 type) { const polyswingdoor_t *ht = (const void *)th; @@ -2356,25 +2190,8 @@ static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->duration); WRITEINT32(save_p, ht->timer); } - #endif -/* -// -// SaveWhatThinker -// -// Saves a what_t thinker -// -static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type) -{ - const what_t *ht = (const void *)th; - WRITEUINT8(save_p, type); -} -*/ -// -// P_NetArchiveThinkers -// -// static void P_NetArchiveThinkers(void) { const thinker_t *th; @@ -2492,7 +2309,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_StartCrumble) { - SaveElevatorThinker(th, tc_startcrumble); + SaveCrumbleThinker(th, tc_startcrumble); continue; } else if (th->function.acp1 == (actionf_p1)T_MarioBlock) @@ -2674,11 +2491,6 @@ static inline pslope_t *LoadSlope(UINT32 slopeid) return NULL; } -// -// LoadMobjThinker -// -// Loads a mobj_t from a save game -// static thinker_t* LoadMobjThinker(actionf_p1 thinker) { thinker_t *next; @@ -2703,34 +2515,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_FLOORROVER) { - size_t floor_sectornum = (size_t)READUINT32(save_p); - size_t floor_rovernum = (size_t)READUINT32(save_p); - ffloor_t *rover = NULL; - size_t rovernum = 0; - - for (rover = sectors[floor_sectornum].ffloors; rover; rover = rover->next) - { - if (rovernum == floor_rovernum) - break; - rovernum++; - } - floorrover = rover; + sector_t *sec = LoadSector(READUINT32(save_p)); + UINT16 id = READUINT16(save_p); + floorrover = P_GetFFloorByID(sec, id); } if (diff2 & MD2_CEILINGROVER) { - size_t ceiling_sectornum = (size_t)READUINT32(save_p); - size_t ceiling_rovernum = (size_t)READUINT32(save_p); - ffloor_t *rover = NULL; - size_t rovernum = 0; - - for (rover = sectors[ceiling_sectornum].ffloors; rover; rover = rover->next) - { - if (rovernum == ceiling_rovernum) - break; - rovernum++; - } - ceilingrover = rover; + sector_t *sec = LoadSector(READUINT32(save_p)); + UINT16 id = READUINT16(save_p); + ceilingrover = P_GetFFloorByID(sec, id); } if (diff & MD_SPAWNPOINT) @@ -2959,10 +2753,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) return &mobj->thinker; } -// LoadNoEnemiesThinker -// -// Loads a noenemies_t from a save game -// static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) { noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2971,10 +2761,6 @@ static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadBounceCheeseThinker -// -// Loads a bouncecheese_t from a save game -// static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) { bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2986,13 +2772,13 @@ static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) ht->floorwasheight = READFIXED(save_p); ht->ceilingwasheight = READFIXED(save_p); ht->low = READCHAR(save_p); + + if (ht->sector) + ht->sector->ceilingdata = ht; + return &ht->thinker; } -// LoadContinuousFallThinker -// -// Loads a continuousfall_t from a save game -// static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) { continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3003,13 +2789,16 @@ static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) ht->floorstartheight = READFIXED(save_p); ht->ceilingstartheight = READFIXED(save_p); ht->destheight = READFIXED(save_p); + + if (ht->sector) + { + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; + } + return &ht->thinker; } -// LoadMarioBlockThinker -// -// Loads a mariothink_t from a save game -// static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) { mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3020,13 +2809,16 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) ht->floorstartheight = READFIXED(save_p); ht->ceilingstartheight = READFIXED(save_p); ht->tag = READINT16(save_p); + + if (ht->sector) + { + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; + } + return &ht->thinker; } -// LoadMarioCheckThinker -// -// Loads a mariocheck_t from a save game -// static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) { mariocheck_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3036,10 +2828,6 @@ static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadThwompThinker -// -// Loads a thwomp_t from a save game -// static thinker_t* LoadThwompThinker(actionf_p1 thinker) { thwomp_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3054,13 +2842,16 @@ static thinker_t* LoadThwompThinker(actionf_p1 thinker) ht->delay = READINT32(save_p); ht->tag = READINT16(save_p); ht->sound = READUINT16(save_p); + + if (ht->sector) + { + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; + } + return &ht->thinker; } -// LoadFloatThinker -// -// Loads a floatthink_t from a save game -// static thinker_t* LoadFloatThinker(actionf_p1 thinker) { floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3071,10 +2862,6 @@ static thinker_t* LoadFloatThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadEachTimeThinker -// -// Loads a eachtime_t from a save game -// static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) { size_t i; @@ -3090,15 +2877,11 @@ static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadRaiseThinker -// -// Loads a raise_t from a save game -// static thinker_t* LoadRaiseThinker(actionf_p1 thinker) { raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; - ht->sourceline = LoadLine(READUINT32(save_p)); + ht->tag = READINT16(save_p); ht->sector = LoadSector(READUINT32(save_p)); ht->ceilingbottom = READFIXED(save_p); ht->ceilingtop = READFIXED(save_p); @@ -3109,11 +2892,6 @@ static thinker_t* LoadRaiseThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadCeilingThinker -// -// Loads a ceiling_t from a save game -// static thinker_t* LoadCeilingThinker(actionf_p1 thinker) { ceiling_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3138,11 +2916,6 @@ static thinker_t* LoadCeilingThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFloormoveThinker -// -// Loads a floormove_t from a save game -// static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) { floormove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3162,11 +2935,6 @@ static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLightflashThinker -// -// Loads a lightflash_t from a save game -// static thinker_t* LoadLightflashThinker(actionf_p1 thinker) { lightflash_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3179,11 +2947,6 @@ static thinker_t* LoadLightflashThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadStrobeThinker -// -// Loads a strobe_t from a save game -// static thinker_t* LoadStrobeThinker(actionf_p1 thinker) { strobe_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3199,11 +2962,6 @@ static thinker_t* LoadStrobeThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadGlowThinker -// -// Loads a glow_t from a save game -// static thinker_t* LoadGlowThinker(actionf_p1 thinker) { glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3217,11 +2975,7 @@ static thinker_t* LoadGlowThinker(actionf_p1 thinker) ht->sector->lightingdata = ht; return &ht->thinker; } -// -// LoadFireflickerThinker -// -// Loads a fireflicker_t from a save game -// + static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) { fireflicker_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3235,12 +2989,8 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) ht->sector->lightingdata = ht; return &ht->thinker; } -// -// LoadElevatorThinker -// -// Loads a elevator_t from a save game -// -static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) + +static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata) { elevator_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3259,25 +3009,39 @@ static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) ht->delaytimer = READFIXED(save_p); ht->floorwasheight = READFIXED(save_p); ht->ceilingwasheight = READFIXED(save_p); - ht->player = LoadPlayer(READUINT32(save_p)); // was dummy ht->sourceline = LoadLine(READUINT32(save_p)); - if (ht->sector) + if (ht->sector && setplanedata) { - if (floorOrCeiling & 2) - ht->sector->ceilingdata = ht; - if (floorOrCeiling & 1) - ht->sector->floordata = ht; + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; } return &ht->thinker; } -// -// LoadScrollThinker -// -// Loads a scroll_t from a save game -// +static thinker_t* LoadCrumbleThinker(actionf_p1 thinker) +{ + crumble_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + ht->actionsector = LoadSector(READUINT32(save_p)); + ht->player = LoadPlayer(READUINT32(save_p)); + ht->direction = READINT32(save_p); + ht->origalpha = READINT32(save_p); + ht->timer = READINT32(save_p); + ht->speed = READFIXED(save_p); + ht->floorwasheight = READFIXED(save_p); + ht->ceilingwasheight = READFIXED(save_p); + ht->flags = READUINT8(save_p); + + if (ht->sector) + ht->sector->floordata = ht; + + return &ht->thinker; +} + static thinker_t* LoadScrollThinker(actionf_p1 thinker) { scroll_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3295,11 +3059,6 @@ static thinker_t* LoadScrollThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFrictionThinker -// -// Loads a friction_t from a save game -// static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) { friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3312,11 +3071,6 @@ static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPusherThinker -// -// Loads a pusher_t from a save game -// static thinker_t* LoadPusherThinker(actionf_p1 thinker) { pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3338,11 +3092,6 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLaserThinker -// -// Loads a laserthink_t from a save game -// static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3351,6 +3100,7 @@ static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) ht->sector = LoadSector(READUINT32(save_p)); ht->sec = LoadSector(READUINT32(save_p)); ht->sourceline = LoadLine(READUINT32(save_p)); + ht->nobosses = READUINT8(save_p); for (rover = ht->sector->ffloors; rover; rover = rover->next) if (rover->secnum == (size_t)(ht->sec - sectors) && rover->master == ht->sourceline) @@ -3358,11 +3108,6 @@ static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLightlevelThinker -// -// Loads a lightlevel_t from a save game -// static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) { lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3378,11 +3123,6 @@ static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadExecutorThinker -// -// Loads a executor_t from a save game -// static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) { executor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3394,11 +3134,6 @@ static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadDisappearThinker -// -// Loads a disappear_t thinker -// static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) { disappear_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3413,11 +3148,6 @@ static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFadeThinker -// -// Loads a fade_t thinker -// static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) { sector_t *ss; @@ -3460,10 +3190,6 @@ static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadFadeColormapThinker -// -// Loads a fadecolormap_t from a save game -// static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) { fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3479,11 +3205,6 @@ static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPlaneDisplaceThinker -// -// Loads a planedisplace_t thinker -// static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) { planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3497,7 +3218,6 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -/// Save a dynamic slope thinker. static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) { dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); @@ -3513,12 +3233,6 @@ static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) } #ifdef POLYOBJECTS - -// -// LoadPolyrotateThinker -// -// Loads a polyrotate_t thinker -// static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) { polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3529,11 +3243,6 @@ static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolymoveThinker -// -// Loads a polymovet_t thinker -// static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) { polymove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3547,11 +3256,6 @@ static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolywaypointThinker -// -// Loads a polywaypoint_t thinker -// static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) { polywaypoint_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3572,11 +3276,6 @@ static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyslidedoorThinker -// -// loads a polyslidedoor_t thinker -// static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) { polyslidedoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3597,11 +3296,6 @@ static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyswingdoorThinker -// -// Loads a polyswingdoor_t thinker -// static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) { polyswingdoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3617,11 +3311,6 @@ static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolydisplaceThinker -// -// Loads a polydisplace_t thinker -// static inline thinker_t* LoadPolydisplaceThinker(actionf_p1 thinker) { polydisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3646,11 +3335,6 @@ static inline thinker_t* LoadPolyrotdisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyfadeThinker -// -// Loads a polyfadet_t thinker -// static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) { polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3667,22 +3351,6 @@ static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) } #endif -/* -// -// LoadWhatThinker -// -// load a what_t thinker -// -static inline void LoadWhatThinker(actionf_p1 thinker) -{ - what_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - ht->thinker.function.acp1 = thinker; -} -*/ - -// -// P_NetUnArchiveThinkers -// static void P_NetUnArchiveThinkers(void) { thinker_t *currentthinker; @@ -3767,7 +3435,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_elevator: - th = LoadElevatorThinker((actionf_p1)T_MoveElevator, 3); + th = LoadElevatorThinker((actionf_p1)T_MoveElevator, true); break; case tc_continuousfalling: @@ -3790,10 +3458,8 @@ static void P_NetUnArchiveThinkers(void) th = LoadRaiseThinker((actionf_p1)T_RaiseSector); 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); + th = LoadElevatorThinker((actionf_p1)T_CameraScanner, false); break; case tc_bouncecheese: @@ -3801,7 +3467,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_startcrumble: - th = LoadElevatorThinker((actionf_p1)T_StartCrumble, 1); + th = LoadCrumbleThinker((actionf_p1)T_StartCrumble); break; case tc_marioblock: @@ -4033,9 +3699,7 @@ static inline void P_UnArchivePolyObjects(void) P_UnArchivePolyObj(&PolyObjects[i]); } #endif -// -// P_FinishMobjs -// + static inline void P_FinishMobjs(void) { thinker_t *currentthinker; @@ -4144,9 +3808,6 @@ static void P_RelinkPointers(void) } } -// -// P_NetArchiveSpecials -// static inline void P_NetArchiveSpecials(void) { size_t i, z; @@ -4187,9 +3848,6 @@ static inline void P_NetArchiveSpecials(void) WRITEUINT8(save_p, 0x00); } -// -// P_NetUnArchiveSpecials -// static void P_NetUnArchiveSpecials(void) { size_t i; diff --git a/src/p_spec.c b/src/p_spec.c index f1f8adef2..6d2345d9f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -987,42 +987,12 @@ static sector_t *P_FindModelCeilingSector(fixed_t ceildestheight, INT32 secnum) } #endif -/** Searches the tag lists for the next sector tagged to a line. - * - * \param line Tagged line used as a reference. - * \param start -1 to start at the beginning, or the result of a previous call - * to keep searching. - * \return Number of the next tagged sector found. - * \sa P_FindSectorFromTag, P_FindLineFromLineTag - */ -INT32 P_FindSectorFromLineTag(line_t *line, INT32 start) -{ - if (line->tag == -1) - { - start++; - - if (start >= (INT32)numsectors) - return -1; - - return start; - } - else - { - start = start >= 0 ? sectors[start].nexttag : - sectors[(unsigned)line->tag % numsectors].firsttag; - while (start >= 0 && sectors[start].tag != line->tag) - start = sectors[start].nexttag; - return start; - } -} - /** Searches the tag lists for the next sector with a given tag. * * \param tag Tag number to look for. * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of the next tagged sector found. - * \sa P_FindSectorFromLineTag */ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) { @@ -1045,42 +1015,12 @@ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) } } -/** Searches the tag lists for the next line tagged to a line. - * - * \param line Tagged line used as a reference. - * \param start -1 to start anew, or the result of a previous call to keep - * searching. - * \return Number of the next tagged line found. - * \sa P_FindSectorFromLineTag - */ -static INT32 P_FindLineFromLineTag(const line_t *line, INT32 start) -{ - if (line->tag == -1) - { - start++; - - if (start >= (INT32)numlines) - return -1; - - return start; - } - else - { - start = start >= 0 ? lines[start].nexttag : - lines[(unsigned)line->tag % numlines].firsttag; - while (start >= 0 && lines[start].tag != line->tag) - start = lines[start].nexttag; - return start; - } -} -#if 0 /** Searches the tag lists for the next line with a given tag and special. * * \param tag Tag number. * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of next suitable line found. - * \sa P_FindLineFromLineTag * \author Graue */ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) @@ -1089,7 +1029,7 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) { start++; - if (start >= numlines) + if (start >= (INT32)numlines) return -1; return start; @@ -1103,7 +1043,7 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) return start; } } -#endif + // // P_FindSpecialLineFromTag // @@ -2500,7 +2440,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) newceilinglightsec = line->frontsector->ceilinglightsec; // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (sectors[secnum].lightingdata) { @@ -2555,7 +2495,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 409: // Change tagged sectors' tag // (formerly "Change calling sectors' tag", but behavior was changed) { - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) P_ChangeSectorTag(secnum,(INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); break; } @@ -2565,7 +2505,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 411: // Stop floor/ceiling movement in tagged sector(s) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (sectors[secnum].floordata) { @@ -2635,7 +2575,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } else { - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; dest = P_GetObjectTypeInSectorNum(MT_TELEPORTMAN, secnum); @@ -2750,7 +2690,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Additionally play the sound from tagged sectors' soundorgs sector_t *sec; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { sec = §ors[secnum]; S_StartSound(&sec->soundorg, sfxnum); @@ -2865,7 +2805,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 416: // Spawn adjustable fire flicker - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2899,7 +2839,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 417: // Spawn adjustable glowing light - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2933,7 +2873,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 418: // Spawn adjustable strobe flash (unsynchronized) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2967,7 +2907,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 419: // Spawn adjustable strobe flash (synchronized) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -3015,7 +2955,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 421: // Stop lighting effect in tagged sectors - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) if (sectors[secnum].lightingdata) { P_RemoveThinker(&((elevator_t *)sectors[secnum].lightingdata)->thinker); @@ -3030,7 +2970,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if ((!mo || !mo->player) && !titlemapinaction) // only players have views, and title screens return; - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; altview = P_GetObjectTypeInSectorNum(MT_ALTVIEWMAN, secnum); @@ -3349,7 +3289,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->sidenum[1] != 0xffff) state = (statenum_t)sides[line->sidenum[1]].toptexture; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { boolean tryagain; sec = sectors + secnum; @@ -3953,7 +3893,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) boolean persist = (line->flags & ML_EFFECT2); mobj_t *anchormo; - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); @@ -5696,6 +5636,35 @@ void P_UpdateSpecials(void) } } +// +// Floor over floors (FOFs), 3Dfloors, 3Dblocks, fake floors (ffloors), rovers, or whatever you want to call them +// + +/** Gets the ID number for a 3Dfloor in its target sector. + * + * \param fflr The 3Dfloor we want an ID for. + * \return ID of 3Dfloor in target sector. Note that the first FOF's ID is 0. UINT16_MAX is given if invalid. + * \sa P_GetFFloorByID + */ +UINT16 P_GetFFloorID(ffloor_t *fflr) +{ + ffloor_t *rover; + sector_t *sec; + UINT16 i = 0; + + if (!fflr) + return UINT16_MAX; + + sec = fflr->target; + + if (!sec->ffloors) + return UINT16_MAX; + for (rover = sec->ffloors; rover; rover = rover->next, i++) + if (rover == fflr) + return i; + return UINT16_MAX; +} + /** Gets a 3Dfloor by control sector. * * \param sec Target sector. @@ -5720,7 +5689,7 @@ static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2) * \param sec Target sector. * \param id ID of 3Dfloor in target sector. Note that the first FOF's ID is 0. * \return Pointer to found 3Dfloor, or NULL. - * \sa P_GetFFloorBySec + * \sa P_GetFFloorBySec, P_GetFFloorID */ ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id) { @@ -6026,12 +5995,10 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) * there already. * * \param sec Control sector. - * \param actionsector Target sector. - * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_RaiseSector * \author SSNTails */ -static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, boolean spindash) +static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t ceilingtop, fixed_t ceilingbottom, boolean lower, boolean spindash) { raise_t *raise; @@ -6040,13 +6007,13 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - raise->sourceline = sourceline; + raise->tag = tag; raise->sector = sec; - raise->ceilingtop = P_FindHighestCeilingSurrounding(sec); - raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec); + raise->ceilingtop = ceilingtop; + raise->ceilingbottom = ceilingbottom; - raise->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT); + raise->basespeed = speed; if (lower) raise->flags |= RF_REVERSE; @@ -6054,7 +6021,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, raise->flags |= RF_SPINDASH; } -static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) +static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) { raise_t *airbob; @@ -6063,7 +6030,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - airbob->sourceline = sourceline; + airbob->tag = tag; airbob->sector = sec; airbob->ceilingtop = sec->ceilingheight; @@ -6083,12 +6050,10 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean * Even thwomps need to think! * * \param sec Control sector. - * \param actionsector Target sector. - * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_ThwompSector * \author SSNTails */ -static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline) +static inline void P_AddThwompThinker(sector_t *sec, INT16 tag, line_t *sourceline, fixed_t crushspeed, fixed_t retractspeed, UINT16 sound) { thwomp_t *thwomp; @@ -6106,14 +6071,14 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin // set up the fields according to the type of elevator action thwomp->sourceline = sourceline; thwomp->sector = sec; - thwomp->crushspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dy >> 3 : 10*FRACUNIT; - thwomp->retractspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dx >> 3 : 2*FRACUNIT; + thwomp->crushspeed = crushspeed; + thwomp->retractspeed = retractspeed; thwomp->direction = 0; thwomp->floorstartheight = sec->floorheight; thwomp->ceilingstartheight = sec->ceilingheight; thwomp->delay = 1; - thwomp->tag = actionsector->tag; - thwomp->sound = (sourceline->flags & ML_EFFECT4) ? sides[sourceline->sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + thwomp->tag = tag; + thwomp->sound = sound; sec->floordata = thwomp; sec->ceilingdata = thwomp; @@ -6174,6 +6139,8 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto { elevator_t *elevator; // Why not? LOL + CONS_Alert(CONS_WARNING, M_GetText("Detected a camera scanner effect (linedef type 5). This effect is deprecated and will be removed in the future!\n")); + // create and initialize new elevator thinker elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &elevator->thinker); @@ -6228,8 +6195,7 @@ void T_LaserFlash(laserthink_t *flash) { thing = node->m_thing; - if ((fflr->master->flags & ML_EFFECT1) - && thing->flags & MF_BOSS) + if (flash->nobosses && thing->flags & MF_BOSS) continue; // Don't hurt bosses // Don't endlessly kill egg guard shields (or anything else for that matter) @@ -6258,7 +6224,7 @@ void T_LaserFlash(laserthink_t *flash) * \sa T_LaserFlash * \author SSNTails */ -static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers) +static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers, boolean nobosses) { laserthink_t *flash; ffloor_t *fflr = P_AddFakeFloor(sec, sec2, line, laserflags, secthinkers); @@ -6275,6 +6241,7 @@ static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *lin flash->sector = sec; // For finding mobjs flash->sec = sec2; flash->sourceline = line; + flash->nobosses = nobosses; } // @@ -6495,7 +6462,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 1: // Definable gravity per sector sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { sectors[s].gravity = §ors[sec].floorheight; // This allows it to change in realtime! @@ -6519,7 +6486,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 5: // Change camera info sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddCameraScanner(§ors[sec], §ors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y)); break; @@ -6546,7 +6513,7 @@ void P_SpawnSpecials(boolean fromnetsave) P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); else { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0;) P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); } } @@ -6557,7 +6524,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 8: // Sector Parameters - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { if (lines[i].flags & ML_NOCLIMB) { @@ -6585,7 +6552,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 10: // Vertical culling plane for sprites and FOFs sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].cullheight = &lines[i]; // This allows it to change in realtime! break; @@ -6646,18 +6613,18 @@ void P_SpawnSpecials(boolean fromnetsave) case 63: // support for drawn heights coming from different sector sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].heightsec = (INT32)sec; break; case 64: // Appearing/Disappearing FOF option if (lines[i].flags & ML_BLOCKMONSTERS) { // Find FOFs by control sector tag - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) for (j = 0; (unsigned)j < sectors[s].linecount; j++) if (sectors[s].lines[j]->special >= 100 && sectors[s].lines[j]->special < 300) Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), (INT32)(sectors[s].lines[j]-lines), (INT32)i); } else // Find FOFs by effect sector tag - for (s = -1; (s = P_FindLineFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindLineFromTag(lines[i].tag, s)) >= 0 ;) { if ((size_t)s == i) continue; @@ -6667,15 +6634,15 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 66: // Displace floor by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 67: // Displace ceiling by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 68: // Displace both floor AND ceiling by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; @@ -6872,16 +6839,16 @@ void P_SpawnSpecials(boolean fromnetsave) { fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); break; } case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); + P_AddAirbob(lines[i].frontsector, lines[i].tag, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; case 160: // Float/bob platform @@ -6931,13 +6898,13 @@ void P_SpawnSpecials(boolean fromnetsave) case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 177: // Air bobbing platform that will crumble and bob on // the water when it falls and hits, then never return P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 178: // Crumbling platform that will float when it hits water @@ -6950,48 +6917,36 @@ void P_SpawnSpecials(boolean fromnetsave) case 180: // Air bobbing platform that will crumble P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 190: // Rising Platform FOF (solid, opaque, shadows) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 191: // Rising Platform FOF (solid, opaque, no shadows) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 192: // Rising Platform TL block: FOF (solid, translucent) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 193: // Rising Platform FOF (solid, invisible) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 194: // Rising Platform 'Platform' - You can jump up through it - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 195: // Rising Platform Translucent "platform" - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_TRANSLUCENT|FF_BOTHPLANES|FF_ALLSIDES|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; + { + fixed_t speed = FixedDiv(P_AproxDistance(lines[i].dx, lines[i].dy), 4*FRACUNIT); + fixed_t ceilingtop = P_FindHighestCeilingSurrounding(lines[i].frontsector); + fixed_t ceilingbottom = P_FindLowestCeilingSurrounding(lines[i].frontsector); + ffloorflags = FF_EXISTS|FF_SOLID; + if (lines[i].special != 193) + ffloorflags |= FF_RENDERALL; + if (lines[i].special <= 191) + ffloorflags |= FF_CUTLEVEL; + if (lines[i].special == 192 || lines[i].special == 195) + ffloorflags |= FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA; + if (lines[i].special >= 194) + ffloorflags |= FF_PLATFORM|FF_BOTHPLANES|FF_ALLSIDES; + if (lines[i].special != 190 && (lines[i].special <= 193 || lines[i].flags & ML_NOCLIMB)) + ffloorflags |= FF_NOSHADE; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); + + P_AddRaiseThinker(lines[i].frontsector, lines[i].tag, speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; + } case 200: // Double light effect P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers); @@ -7047,14 +7002,20 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 251: // A THWOMP! + { + fixed_t crushspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dy >> 3 : 10*FRACUNIT; + fixed_t retractspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dx >> 3 : 2*FRACUNIT; + UINT16 sound = (lines[i].flags & ML_EFFECT4) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { - P_AddThwompThinker(§ors[sec], §ors[s], &lines[i]); + P_AddThwompThinker(§ors[sec], lines[i].tag, &lines[i], crushspeed, retractspeed, sound); P_AddFakeFloor(§ors[s], §ors[sec], lines + i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); } break; + } case 252: // Shatter block (breaks when touched) ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER; @@ -7096,8 +7057,8 @@ void P_SpawnSpecials(boolean fromnetsave) sec = sides[*lines[i].sidenum].sector - sectors; // No longer totally disrupts netgames - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers); + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) + EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers, !!(lines[i].flags & ML_EFFECT1)); break; case 259: // Custom FOF @@ -7283,40 +7244,40 @@ void P_SpawnSpecials(boolean fromnetsave) case 600: // floor lighting independently (e.g. lava) sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].floorlightsec = (INT32)sec; break; case 601: // ceiling lighting independently sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].ceilinglightsec = (INT32)sec; break; case 602: // Adjustable pulsating light sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableGlowingLight(§ors[sec], §ors[s], P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 604: // Adjustable Blinking Light (unsynchronized) sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, false); break; case 605: // Adjustable Blinking Light (synchronized) sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, true); break; @@ -7401,7 +7362,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker INT32 s; size_t sec = sides[*lines[line].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines+line, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[line].tag, s)) >= 0 ;) P_AddFakeFloor(§ors[s], §ors[sec], lines+line, ffloorflags, secthinkers); } @@ -7763,7 +7724,7 @@ static void P_SpawnScrollers(void) case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; @@ -7772,13 +7733,13 @@ static void P_SpawnScrollers(void) case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; case 510: // scroll effect floor case 530: // scroll and carry objects on floor - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; @@ -7787,14 +7748,14 @@ static void P_SpawnScrollers(void) case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; // scroll wall according to linedef // (same direction and speed as scrolling floors) case 502: - for (s = -1; (s = P_FindLineFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) if (s != (INT32)i) Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); break; @@ -7864,7 +7825,7 @@ void T_Disappear(disappear_t *d) ffloor_t *rover; register INT32 s; - for (s = -1; (s = P_FindSectorFromLineTag(&lines[d->affectee], s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[d->affectee].tag, s)) >= 0 ;) { for (rover = sectors[s].ffloors; rover; rover = rover->next) { @@ -8621,7 +8582,7 @@ static void P_SpawnFriction(void) else movefactor = FRACUNIT; - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Friction(friction, movefactor, s, -1); } } @@ -9156,15 +9117,15 @@ static void P_SpawnPushers(void) switch (l->special) { case 541: // wind - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 544: // current - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 547: // push/pull - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) { thing = P_GetPushThing(s); if (thing) // No MT_P* means no effect @@ -9172,19 +9133,19 @@ static void P_SpawnPushers(void) } break; case 545: // current up - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 546: // current down - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 542: // wind up - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 543: // wind down - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; } diff --git a/src/p_spec.h b/src/p_spec.h index e243e3a61..0228f8a02 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -55,7 +55,6 @@ fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight); fixed_t P_FindLowestCeilingSurrounding(sector_t *sec); fixed_t P_FindHighestCeilingSurrounding(sector_t *sec); -INT32 P_FindSectorFromLineTag(line_t *line, INT32 start); INT32 P_FindSectorFromTag(INT16 tag, INT32 start); INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); @@ -74,6 +73,7 @@ void P_RunDeNightserizeExecutors(mobj_t *actor); void P_RunNightsLapExecutors(mobj_t *actor); void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres); +UINT16 P_GetFFloorID(ffloor_t *fflr); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); // @@ -108,6 +108,7 @@ typedef struct sector_t *sector; ///< Sector in which the effect takes place. sector_t *sec; line_t *sourceline; + UINT8 nobosses; } laserthink_t; /** Strobe light action structure.. @@ -307,10 +308,32 @@ typedef struct fixed_t delaytimer; fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at - player_t *player; // Player who initiated the thinker (used for airbob) line_t *sourceline; } elevator_t; +typedef enum +{ + CF_RETURN = 1, // Return after crumbling + CF_FLOATBOB = 1<<1, // Float on water + CF_REVERSE = 1<<2, // Reverse gravity +} crumbleflag_t; + +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; + sector_t *actionsector; // The sector the rover action is taking place in. + player_t *player; // Player who initiated the thinker (used for airbob) + INT32 direction; + INT32 origalpha; + INT32 timer; + fixed_t speed; + fixed_t floorwasheight; // Height the floor WAS at + fixed_t ceilingwasheight; // Height the ceiling WAS at + UINT8 flags; +} crumble_t; + typedef struct { thinker_t thinker; @@ -400,7 +423,7 @@ typedef enum typedef struct { thinker_t thinker; - line_t *sourceline; + INT16 tag; sector_t *sector; fixed_t ceilingbottom; fixed_t ceilingtop; @@ -440,7 +463,7 @@ void T_MoveFloor(floormove_t *movefloor); void T_MoveElevator(elevator_t *elevator); void T_ContinuousFalling(continuousfall_t *faller); void T_BounceCheese(bouncecheese_t *bouncer); -void T_StartCrumble(elevator_t *elevator); +void T_StartCrumble(crumble_t *crumble); void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(mariocheck_t *block); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c042d141c..ec7bfc1c4 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -372,7 +372,9 @@ static boolean IgnoreMouse(void) return false; if (menuactive) return !M_MouseNeeded(); - if (paused || con_destlines || chat_on || gamestate != GS_LEVEL) + if (paused || con_destlines || chat_on) + return true; + if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && gamestate != GS_CUTSCENE) return true; return false; } diff --git a/src/w_wad.c b/src/w_wad.c index f273753c8..a81132354 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -920,6 +920,40 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum) // 'startlump' is the lump number to start the search // UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) +{ + UINT16 i; + static char uname[8 + 1]; + + if (!TestValidLump(wad,0)) + return INT16_MAX; + + strlcpy(uname, name, sizeof uname); + strupr(uname); + + // + // scan forward + // start at 'startlump', useful parameter when there are multiple + // resources with the same name + // + if (startlump < wadfiles[wad]->numlumps) + { + lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) + if (!strncmp(lump_p->name, uname, sizeof(uname) - 1)) + return i; + } + + // not found. + return INT16_MAX; +} + +// +// Like W_CheckNumForNamePwad, but can find entries with long names +// +// Should be the only version, but that's not possible until we fix +// all the instances of non null-terminated strings in the codebase... +// +UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump) { UINT16 i; static char uname[256 + 1]; @@ -1025,7 +1059,8 @@ lumpnum_t W_CheckNumForName(const char *name) // most recent entries first for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) { - if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) + if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8] + && strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0) { lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); return lumpnumcache[lumpnumcacheindex].lumpnum; @@ -1045,13 +1080,63 @@ lumpnum_t W_CheckNumForName(const char *name) { // Update the cache. lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); - strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); + memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); + strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8); lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check; return lumpnumcache[lumpnumcacheindex].lumpnum; } } +// +// Like W_CheckNumForName, but can find entries with long names +// +// Should be the only version, but that's not possible until we fix +// all the instances of non null-terminated strings in the codebase... +// +lumpnum_t W_CheckNumForLongName(const char *name) +{ + INT32 i; + lumpnum_t check = INT16_MAX; + + if (!*name) // some doofus gave us an empty string? + return LUMPERROR; + + // Check the lumpnumcache first. Loop backwards so that we check + // most recent entries first + for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) + { + if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) + { + lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); + return lumpnumcache[lumpnumcacheindex].lumpnum; + } + } + + // scan wad files backwards so patch lump files take precedence + for (i = numwadfiles - 1; i >= 0; i--) + { + check = W_CheckNumForLongNamePwad(name,(UINT16)i,0); + if (check != INT16_MAX) + break; //found it + } + + if (check == INT16_MAX) return LUMPERROR; + else + { + if (strlen(name) < 32) + { + // Update the cache. + lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); + memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); + strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); + lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check; + } + + return (i << 16) + check; + } +} + // Look for valid map data through all added files in descendant order. // Get a map marker for WADs, and a standalone WAD file lump inside PK3s. // TODO: Make it search through cache first, maybe...? @@ -1100,6 +1185,24 @@ lumpnum_t W_GetNumForName(const char *name) return i; } +// +// Like W_GetNumForName, but can find entries with long names +// +// Should be the only version, but that's not possible until we fix +// all the instances of non null-terminated strings in the codebase... +// +lumpnum_t W_GetNumForLongName(const char *name) +{ + lumpnum_t i; + + i = W_CheckNumForLongName(name); + + if (i == LUMPERROR) + I_Error("W_GetNumForLongName: %s not found!\n", name); + + return i; +} + // // W_CheckNumForNameInBlock // Checks only in blocks from blockstart lump to blockend lump @@ -1139,7 +1242,7 @@ UINT8 W_LumpExists(const char *name) { lumpinfo_t *lump_p = wadfiles[i]->lumpinfo; for (j = 0; j < wadfiles[i]->numlumps; ++j, ++lump_p) - if (fastcmp(lump_p->name,name)) + if (fastcmp(lump_p->longname, name)) return true; } return false; @@ -1680,6 +1783,17 @@ void *W_CachePatchName(const char *name, INT32 tag) return W_CachePatchNum(W_GetNumForName("MISSING"), tag); return W_CachePatchNum(num, tag); } + +void *W_CachePatchLongName(const char *name, INT32 tag) +{ + lumpnum_t num; + + num = W_CheckNumForLongName(name); + + if (num == LUMPERROR) + return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag); + return W_CachePatchNum(num, tag); +} #ifndef NOMD5 #define MD5_LEN 16 diff --git a/src/w_wad.h b/src/w_wad.h index 3af6148f4..88b542fca 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -156,6 +156,7 @@ const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad +UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump); /* Find the first lump after F_START for instance. */ UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump); @@ -166,7 +167,9 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) lumpnum_t W_CheckNumForMap(const char *name); lumpnum_t W_CheckNumForName(const char *name); +lumpnum_t W_CheckNumForLongName(const char *name); lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR +lumpnum_t W_GetNumForLongName(const char *name); lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend); UINT8 W_LumpExists(const char *name); // Lua uses this. @@ -194,6 +197,7 @@ boolean W_IsPatchCached(lumpnum_t lump, void *ptr); void *W_CacheLumpName(const char *name, INT32 tag); void *W_CachePatchName(const char *name, INT32 tag); +void *W_CachePatchLongName(const char *name, INT32 tag); // Returns either a Software patch, or an OpenGL patch. // Performs any necessary conversions from PNG images.