Merge branch 'next' into udmf-next

# Conflicts:
#	src/p_saveg.c
#	src/p_slopes.c
#	src/p_spec.c
This commit is contained in:
MascaraSnake 2020-05-01 12:44:39 +02:00
commit 5c8b50ca8b
15 changed files with 842 additions and 1074 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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
{

View File

@ -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

View File

@ -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 = &sectors[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 = &sectors[secnum];

View File

@ -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 = &sectors[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 = &sectors[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 = &sectors[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 = &sectors[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(&sectors[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 = &sectors[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 = &sectors[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 = &sectors[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(&sectors[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 = &sectors[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 = &sectors[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 = &sectors[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;

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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 <graue@oceanbase.org>
*/
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 = &sectors[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 <http://www.ssntails.org>
*/
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 <http://www.ssntails.org>
*/
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 <http://www.ssntails.org>
*/
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 = &sectors[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(&sectors[sec], &sectors[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(&sectors[sec], &sectors[s], &lines[i]);
P_AddThwompThinker(&sectors[sec], lines[i].tag, &lines[i], crushspeed, retractspeed, sound);
P_AddFakeFloor(&sectors[s], &sectors[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(&sectors[s], &sectors[sec], lines + i, secthinkers);
for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;)
EV_AddLaserThinker(&sectors[s], &sectors[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(&sectors[sec], &sectors[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(&sectors[sec], &sectors[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(&sectors[sec], &sectors[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(&sectors[sec], &sectors[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(&sectors[s], &sectors[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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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.