mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-28 15:11:55 +00:00
Merge branch 'next' into udmf-next
# Conflicts: # src/p_mobj.c # src/r_segs.c
This commit is contained in:
commit
3170f2b8c3
19 changed files with 1106 additions and 1268 deletions
|
@ -3900,6 +3900,8 @@ thingtypes
|
||||||
{
|
{
|
||||||
title = "Emerald Hunt Location";
|
title = "Emerald Hunt Location";
|
||||||
sprite = "SHRDA0";
|
sprite = "SHRDA0";
|
||||||
|
flags8height = 24;
|
||||||
|
flags8text = "[8] Float";
|
||||||
}
|
}
|
||||||
321
|
321
|
||||||
{
|
{
|
||||||
|
|
|
@ -1631,7 +1631,6 @@ int LUA_InfoLib(lua_State *L)
|
||||||
lua_pushcfunction(L, lib_spriteinfolen);
|
lua_pushcfunction(L, lib_spriteinfolen);
|
||||||
lua_setfield(L, -2, "__len");
|
lua_setfield(L, -2, "__len");
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
lua_pushvalue(L, -1);
|
|
||||||
lua_setglobal(L, "spriteinfo");
|
lua_setglobal(L, "spriteinfo");
|
||||||
|
|
||||||
luaL_newmetatable(L, META_LUABANKS);
|
luaL_newmetatable(L, META_LUABANKS);
|
||||||
|
|
|
@ -463,6 +463,7 @@ static int mobj_set(lua_State *L)
|
||||||
localangle = mo->angle;
|
localangle = mo->angle;
|
||||||
else if (mo->player == &players[secondarydisplayplayer])
|
else if (mo->player == &players[secondarydisplayplayer])
|
||||||
localangle2 = mo->angle;
|
localangle2 = mo->angle;
|
||||||
|
break;
|
||||||
case mobj_pitch:
|
case mobj_pitch:
|
||||||
mo->pitch = luaL_checkangle(L, 3);
|
mo->pitch = luaL_checkangle(L, 3);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -444,9 +444,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
||||||
else // If it's not a .lua file, copy the lump name in too.
|
else // If it's not a .lua file, copy the lump name in too.
|
||||||
{
|
{
|
||||||
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
||||||
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||||
name = malloc(len+1);
|
name = malloc(len+1);
|
||||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
|
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
|
||||||
name[len] = '\0';
|
name[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
|
||||||
case 0: // IN STASIS
|
case 0: // IN STASIS
|
||||||
break;
|
break;
|
||||||
case 1: // UP
|
case 1: // UP
|
||||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false,
|
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
|
||||||
1, ceiling->direction);
|
|
||||||
|
|
||||||
if (ceiling->type == bounceCeiling)
|
if (ceiling->type == bounceCeiling)
|
||||||
{
|
{
|
||||||
|
@ -159,8 +158,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1: // DOWN
|
case -1: // DOWN
|
||||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
|
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
|
||||||
ceiling->crush, 1, ceiling->direction);
|
|
||||||
|
|
||||||
if (ceiling->type == bounceCeiling)
|
if (ceiling->type == bounceCeiling)
|
||||||
{
|
{
|
||||||
|
@ -314,11 +312,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
|
||||||
if (ceiling->type == crushBothOnce)
|
if (ceiling->type == crushBothOnce)
|
||||||
{
|
{
|
||||||
// Move the floor
|
// Move the floor
|
||||||
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, 0, -ceiling->direction);
|
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, false, -ceiling->direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight,
|
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
|
||||||
false, 1, ceiling->direction);
|
|
||||||
|
|
||||||
if (res == pastdest)
|
if (res == pastdest)
|
||||||
{
|
{
|
||||||
|
@ -357,11 +354,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
|
||||||
if (ceiling->type == crushBothOnce)
|
if (ceiling->type == crushBothOnce)
|
||||||
{
|
{
|
||||||
// Move the floor
|
// Move the floor
|
||||||
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 0, -ceiling->direction);
|
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, false, -ceiling->direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
|
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
|
||||||
ceiling->crush, 1, ceiling->direction);
|
|
||||||
|
|
||||||
if (res == pastdest)
|
if (res == pastdest)
|
||||||
{
|
{
|
||||||
|
|
1241
src/p_floor.c
1241
src/p_floor.c
File diff suppressed because it is too large
Load diff
|
@ -1691,7 +1691,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
|
||||||
// Needs ML_EFFECT4 flag for pushables to break it
|
// Needs ML_EFFECT4 flag for pushables to break it
|
||||||
if (!(rover->master->flags & ML_EFFECT4)) continue;
|
if (!(rover->master->flags & ML_EFFECT4)) continue;
|
||||||
|
|
||||||
if (!rover->master->frontsector->crumblestate)
|
if (rover->master->frontsector->crumblestate == CRUMBLE_NONE)
|
||||||
{
|
{
|
||||||
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
||||||
bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
|
||||||
|
@ -11616,7 +11616,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
||||||
mapthing_t *huntemeralds[MAXHUNTEMERALDS];
|
mapthing_t *huntemeralds[MAXHUNTEMERALDS];
|
||||||
INT32 numhuntemeralds;
|
INT32 numhuntemeralds;
|
||||||
|
|
||||||
static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale)
|
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale)
|
||||||
{
|
{
|
||||||
const subsector_t *ss = R_PointInSubsector(x, y);
|
const subsector_t *ss = R_PointInSubsector(x, y);
|
||||||
|
|
||||||
|
@ -11633,7 +11633,7 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x,
|
||||||
+ FixedMul(scale, offset);
|
+ FixedMul(scale, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
|
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
|
||||||
{
|
{
|
||||||
fixed_t offset = mthing->z << FRACBITS;
|
fixed_t offset = mthing->z << FRACBITS;
|
||||||
boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
|
boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
|
||||||
|
@ -11673,6 +11673,7 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin
|
||||||
|
|
||||||
// Ring-like items, may float additional units with MTF_AMBUSH.
|
// Ring-like items, may float additional units with MTF_AMBUSH.
|
||||||
case MT_SPIKEBALL:
|
case MT_SPIKEBALL:
|
||||||
|
case MT_EMERHUNT:
|
||||||
case MT_EMERALDSPAWN:
|
case MT_EMERALDSPAWN:
|
||||||
case MT_TOKEN:
|
case MT_TOKEN:
|
||||||
case MT_EMBLEM:
|
case MT_EMBLEM:
|
||||||
|
|
|
@ -451,6 +451,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
|
||||||
void P_MovePlayerToStarpost(INT32 playernum);
|
void P_MovePlayerToStarpost(INT32 playernum);
|
||||||
void P_AfterPlayerSpawn(INT32 playernum);
|
void P_AfterPlayerSpawn(INT32 playernum);
|
||||||
|
|
||||||
|
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip, const fixed_t scale);
|
||||||
|
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y);
|
||||||
|
|
||||||
mobj_t *P_SpawnMapThing(mapthing_t *mthing);
|
mobj_t *P_SpawnMapThing(mapthing_t *mthing);
|
||||||
void P_SpawnHoop(mapthing_t *mthing);
|
void P_SpawnHoop(mapthing_t *mthing);
|
||||||
void P_SetBonusTime(mobj_t *mobj);
|
void P_SetBonusTime(mobj_t *mobj);
|
||||||
|
|
361
src/p_saveg.c
361
src/p_saveg.c
|
@ -755,6 +755,7 @@ static void P_NetUnArchiveColormaps(void)
|
||||||
// diff3 flags
|
// diff3 flags
|
||||||
#define SD_TAGLIST 0x01
|
#define SD_TAGLIST 0x01
|
||||||
#define SD_COLORMAP 0x02
|
#define SD_COLORMAP 0x02
|
||||||
|
#define SD_CRUMBLESTATE 0x04
|
||||||
|
|
||||||
#define LD_FLAG 0x01
|
#define LD_FLAG 0x01
|
||||||
#define LD_SPECIAL 0x02
|
#define LD_SPECIAL 0x02
|
||||||
|
@ -861,6 +862,8 @@ static void P_NetArchiveWorld(void)
|
||||||
|
|
||||||
if (ss->extra_colormap != spawnss->extra_colormap)
|
if (ss->extra_colormap != spawnss->extra_colormap)
|
||||||
diff3 |= SD_COLORMAP;
|
diff3 |= SD_COLORMAP;
|
||||||
|
if (ss->crumblestate)
|
||||||
|
diff3 |= SD_CRUMBLESTATE;
|
||||||
|
|
||||||
// Check if any of the sector's FOFs differ from how they spawned
|
// Check if any of the sector's FOFs differ from how they spawned
|
||||||
if (ss->ffloors)
|
if (ss->ffloors)
|
||||||
|
@ -928,6 +931,8 @@ static void P_NetArchiveWorld(void)
|
||||||
if (diff3 & SD_COLORMAP)
|
if (diff3 & SD_COLORMAP)
|
||||||
WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap));
|
WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap));
|
||||||
// returns existing index if already added, or appends to net_colormaps and returns new index
|
// 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
|
// 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
|
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
|
||||||
|
@ -1164,6 +1169,8 @@ static void P_NetUnArchiveWorld(void)
|
||||||
|
|
||||||
if (diff3 & SD_COLORMAP)
|
if (diff3 & SD_COLORMAP)
|
||||||
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get));
|
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get));
|
||||||
|
if (diff3 & SD_CRUMBLESTATE)
|
||||||
|
sectors[i].crumblestate = READINT32(get);
|
||||||
|
|
||||||
if (diff & SD_FFLOORS)
|
if (diff & SD_FFLOORS)
|
||||||
{
|
{
|
||||||
|
@ -1359,7 +1366,6 @@ typedef enum
|
||||||
tc_startcrumble,
|
tc_startcrumble,
|
||||||
tc_marioblock,
|
tc_marioblock,
|
||||||
tc_marioblockchecker,
|
tc_marioblockchecker,
|
||||||
tc_spikesector,
|
|
||||||
tc_floatsector,
|
tc_floatsector,
|
||||||
tc_crushceiling,
|
tc_crushceiling,
|
||||||
tc_scroll,
|
tc_scroll,
|
||||||
|
@ -1731,22 +1737,151 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SaveSpecialLevelThinker
|
// SaveNoEnemiesThinker
|
||||||
//
|
//
|
||||||
// Saves a levelspecthink_t thinker
|
// Saves a noenemies_t thinker
|
||||||
//
|
//
|
||||||
static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
|
static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type)
|
||||||
{
|
{
|
||||||
const levelspecthink_t *ht = (const void *)th;
|
const noenemies_t *ht = (const void *)th;
|
||||||
size_t i;
|
WRITEUINT8(save_p, 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;
|
||||||
WRITEUINT8(save_p, type);
|
WRITEUINT8(save_p, type);
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
|
||||||
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
|
|
||||||
}
|
|
||||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
WRITEFIXED(save_p, ht->speed);
|
||||||
|
WRITEFIXED(save_p, ht->distance);
|
||||||
|
WRITEFIXED(save_p, ht->floorwasheight);
|
||||||
|
WRITEFIXED(save_p, ht->ceilingwasheight);
|
||||||
|
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;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
WRITEFIXED(save_p, ht->speed);
|
||||||
|
WRITEINT32(save_p, ht->direction);
|
||||||
|
WRITEFIXED(save_p, ht->floorstartheight);
|
||||||
|
WRITEFIXED(save_p, ht->ceilingstartheight);
|
||||||
|
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;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
WRITEFIXED(save_p, ht->speed);
|
||||||
|
WRITEINT32(save_p, ht->direction);
|
||||||
|
WRITEFIXED(save_p, ht->floorstartheight);
|
||||||
|
WRITEFIXED(save_p, ht->ceilingstartheight);
|
||||||
|
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;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
|
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;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
WRITEFIXED(save_p, ht->crushspeed);
|
||||||
|
WRITEFIXED(save_p, ht->retractspeed);
|
||||||
|
WRITEINT32(save_p, ht->direction);
|
||||||
|
WRITEFIXED(save_p, ht->floorstartheight);
|
||||||
|
WRITEFIXED(save_p, ht->ceilingstartheight);
|
||||||
|
WRITEINT32(save_p, ht->delay);
|
||||||
|
WRITEINT16(save_p, ht->tag);
|
||||||
|
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;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
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;
|
||||||
|
size_t i;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
WRITECHAR(save_p, ht->playersInArea[i]);
|
||||||
|
WRITECHAR(save_p, ht->playersOnArea[i]);
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
WRITEFIXED(save_p, ht->ceilingbottom);
|
||||||
|
WRITEFIXED(save_p, ht->ceilingtop);
|
||||||
|
WRITEFIXED(save_p, ht->basespeed);
|
||||||
|
WRITEFIXED(save_p, ht->extraspeed);
|
||||||
|
WRITEUINT8(save_p, ht->shaketimer);
|
||||||
|
WRITEUINT8(save_p, ht->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2307,27 +2442,27 @@ static void P_NetArchiveThinkers(void)
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling)
|
else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_continuousfalling);
|
SaveContinuousFallThinker(th, tc_continuousfalling);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_ThwompSector)
|
else if (th->function.acp1 == (actionf_p1)T_ThwompSector)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_thwomp);
|
SaveThwompThinker(th, tc_thwomp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector)
|
else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_noenemies);
|
SaveNoEnemiesThinker(th, tc_noenemies);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker)
|
else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_eachtime);
|
SaveEachTimeThinker(th, tc_eachtime);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_RaiseSector)
|
else if (th->function.acp1 == (actionf_p1)T_RaiseSector)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_raisesector);
|
SaveRaiseThinker(th, tc_raisesector);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_CameraScanner)
|
else if (th->function.acp1 == (actionf_p1)T_CameraScanner)
|
||||||
|
@ -2352,7 +2487,7 @@ static void P_NetArchiveThinkers(void)
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
|
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_bouncecheese);
|
SaveBounceCheeseThinker(th, tc_bouncecheese);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_StartCrumble)
|
else if (th->function.acp1 == (actionf_p1)T_StartCrumble)
|
||||||
|
@ -2362,22 +2497,17 @@ static void P_NetArchiveThinkers(void)
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_MarioBlock)
|
else if (th->function.acp1 == (actionf_p1)T_MarioBlock)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_marioblock);
|
SaveMarioBlockThinker(th, tc_marioblock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_marioblockchecker);
|
SaveMarioCheckThinker(th, tc_marioblockchecker);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
|
||||||
{
|
|
||||||
SaveSpecialLevelThinker(th, tc_spikesector);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_FloatSector)
|
else if (th->function.acp1 == (actionf_p1)T_FloatSector)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_floatsector);
|
SaveFloatThinker(th, tc_floatsector);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
|
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
|
||||||
|
@ -2829,38 +2959,153 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
||||||
return &mobj->thinker;
|
return &mobj->thinker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadNoEnemiesThinker
|
||||||
//
|
//
|
||||||
// LoadSpecialLevelThinker
|
// Loads a noenemies_t from a save game
|
||||||
//
|
//
|
||||||
// Loads a levelspecthink_t from a save game
|
static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker)
|
||||||
//
|
|
||||||
// floorOrCeiling:
|
|
||||||
// 0 - Don't set
|
|
||||||
// 1 - Floor Only
|
|
||||||
// 2 - Ceiling Only
|
|
||||||
// 3 - Both
|
|
||||||
//
|
|
||||||
static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
|
|
||||||
{
|
{
|
||||||
levelspecthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
size_t i;
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
|
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);
|
||||||
ht->thinker.function.acp1 = thinker;
|
ht->thinker.function.acp1 = thinker;
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
ht->vars[i] = READFIXED(save_p); //var[16]
|
|
||||||
ht->var2s[i] = READFIXED(save_p); //var[16]
|
|
||||||
}
|
|
||||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
ht->sector = LoadSector(READUINT32(save_p));
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->speed = READFIXED(save_p);
|
||||||
|
ht->distance = READFIXED(save_p);
|
||||||
|
ht->floorwasheight = READFIXED(save_p);
|
||||||
|
ht->ceilingwasheight = READFIXED(save_p);
|
||||||
|
ht->low = READCHAR(save_p);
|
||||||
|
return &ht->thinker;
|
||||||
|
}
|
||||||
|
|
||||||
if (ht->sector)
|
// 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);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->speed = READFIXED(save_p);
|
||||||
|
ht->direction = READINT32(save_p);
|
||||||
|
ht->floorstartheight = READFIXED(save_p);
|
||||||
|
ht->ceilingstartheight = READFIXED(save_p);
|
||||||
|
ht->destheight = READFIXED(save_p);
|
||||||
|
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);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->speed = READFIXED(save_p);
|
||||||
|
ht->direction = READINT32(save_p);
|
||||||
|
ht->floorstartheight = READFIXED(save_p);
|
||||||
|
ht->ceilingstartheight = READFIXED(save_p);
|
||||||
|
ht->tag = READINT16(save_p);
|
||||||
|
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);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
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);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->crushspeed = READFIXED(save_p);
|
||||||
|
ht->retractspeed = READFIXED(save_p);
|
||||||
|
ht->direction = READINT32(save_p);
|
||||||
|
ht->floorstartheight = READFIXED(save_p);
|
||||||
|
ht->ceilingstartheight = READFIXED(save_p);
|
||||||
|
ht->delay = READINT32(save_p);
|
||||||
|
ht->tag = READINT16(save_p);
|
||||||
|
ht->sound = READUINT16(save_p);
|
||||||
|
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);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->tag = READINT16(save_p);
|
||||||
|
return &ht->thinker;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadEachTimeThinker
|
||||||
|
//
|
||||||
|
// Loads a eachtime_t from a save game
|
||||||
|
//
|
||||||
|
static thinker_t* LoadEachTimeThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
eachtime_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (floorOrCeiling & 2)
|
ht->playersInArea[i] = READCHAR(save_p);
|
||||||
ht->sector->ceilingdata = ht;
|
ht->playersOnArea[i] = READCHAR(save_p);
|
||||||
if (floorOrCeiling & 1)
|
|
||||||
ht->sector->floordata = ht;
|
|
||||||
}
|
}
|
||||||
|
ht->triggerOnExit = READCHAR(save_p);
|
||||||
|
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->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->ceilingbottom = READFIXED(save_p);
|
||||||
|
ht->ceilingtop = READFIXED(save_p);
|
||||||
|
ht->basespeed = READFIXED(save_p);
|
||||||
|
ht->extraspeed = READFIXED(save_p);
|
||||||
|
ht->shaketimer = READUINT8(save_p);
|
||||||
|
ht->flags = READUINT8(save_p);
|
||||||
return &ht->thinker;
|
return &ht->thinker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3526,23 +3771,23 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_continuousfalling:
|
case tc_continuousfalling:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_ContinuousFalling, 3);
|
th = LoadContinuousFallThinker((actionf_p1)T_ContinuousFalling);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_thwomp:
|
case tc_thwomp:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_ThwompSector, 3);
|
th = LoadThwompThinker((actionf_p1)T_ThwompSector);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_noenemies:
|
case tc_noenemies:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_NoEnemiesSector, 0);
|
th = LoadNoEnemiesThinker((actionf_p1)T_NoEnemiesSector);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_eachtime:
|
case tc_eachtime:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_EachTimeThinker, 0);
|
th = LoadEachTimeThinker((actionf_p1)T_EachTimeThinker);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_raisesector:
|
case tc_raisesector:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_RaiseSector, 0);
|
th = LoadRaiseThinker((actionf_p1)T_RaiseSector);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/// \todo rewrite all the code that uses an elevator_t but isn't an elevator
|
/// \todo rewrite all the code that uses an elevator_t but isn't an elevator
|
||||||
|
@ -3552,7 +3797,7 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_bouncecheese:
|
case tc_bouncecheese:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_BounceCheese, 2);
|
th = LoadBounceCheeseThinker((actionf_p1)T_BounceCheese);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_startcrumble:
|
case tc_startcrumble:
|
||||||
|
@ -3560,19 +3805,15 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_marioblock:
|
case tc_marioblock:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
th = LoadMarioBlockThinker((actionf_p1)T_MarioBlock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_marioblockchecker:
|
case tc_marioblockchecker:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
|
th = LoadMarioCheckThinker((actionf_p1)T_MarioBlockChecker);
|
||||||
break;
|
|
||||||
|
|
||||||
case tc_spikesector:
|
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_floatsector:
|
case tc_floatsector:
|
||||||
th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0);
|
th = LoadFloatThinker((actionf_p1)T_FloatSector);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_laserflash:
|
case tc_laserflash:
|
||||||
|
|
|
@ -694,47 +694,27 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
||||||
|
|
||||||
static void P_SpawnEmeraldHunt(void)
|
static void P_SpawnEmeraldHunt(void)
|
||||||
{
|
{
|
||||||
INT32 emer1, emer2, emer3;
|
INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey;
|
||||||
INT32 timeout = 0; // keeps from getting stuck
|
fixed_t x, y, z;
|
||||||
|
|
||||||
emer1 = emer2 = emer3 = 0;
|
for (i = 0; i < numhuntemeralds; i++)
|
||||||
|
num[i] = i;
|
||||||
|
|
||||||
//increment spawn numbers because zero is valid.
|
for (i = 0; i < 3; i++)
|
||||||
emer1 = (P_RandomKey(numhuntemeralds)) + 1;
|
|
||||||
while (timeout++ < 100)
|
|
||||||
{
|
{
|
||||||
emer2 = (P_RandomKey(numhuntemeralds)) + 1;
|
// generate random index, shuffle afterwards
|
||||||
|
randomkey = P_RandomKey(numhuntemeralds--);
|
||||||
|
emer[i] = num[randomkey];
|
||||||
|
num[randomkey] = num[numhuntemeralds];
|
||||||
|
num[numhuntemeralds] = emer[i];
|
||||||
|
|
||||||
if (emer2 != emer1)
|
// spawn emerald
|
||||||
break;
|
x = huntemeralds[emer[i]]->x<<FRACBITS;
|
||||||
|
y = huntemeralds[emer[i]]->y<<FRACBITS;
|
||||||
|
z = P_GetMapThingSpawnHeight(MT_EMERHUNT, huntemeralds[emer[i]], x, y);
|
||||||
|
P_SetMobjStateNF(P_SpawnMobj(x, y, z, MT_EMERHUNT),
|
||||||
|
mobjinfo[MT_EMERHUNT].spawnstate+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = 0;
|
|
||||||
while (timeout++ < 100)
|
|
||||||
{
|
|
||||||
emer3 = (P_RandomKey(numhuntemeralds)) + 1;
|
|
||||||
|
|
||||||
if (emer3 != emer2 && emer3 != emer1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//decrement spawn values to the actual number because zero is valid.
|
|
||||||
if (emer1--)
|
|
||||||
P_SpawnMobj(huntemeralds[emer1]->x<<FRACBITS,
|
|
||||||
huntemeralds[emer1]->y<<FRACBITS,
|
|
||||||
huntemeralds[emer1]->z<<FRACBITS, MT_EMERHUNT);
|
|
||||||
|
|
||||||
if (emer2--)
|
|
||||||
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer2]->x<<FRACBITS,
|
|
||||||
huntemeralds[emer2]->y<<FRACBITS,
|
|
||||||
huntemeralds[emer2]->z<<FRACBITS, MT_EMERHUNT),
|
|
||||||
mobjinfo[MT_EMERHUNT].spawnstate+1);
|
|
||||||
|
|
||||||
if (emer3--)
|
|
||||||
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer3]->x<<FRACBITS,
|
|
||||||
huntemeralds[emer3]->y<<FRACBITS,
|
|
||||||
huntemeralds[emer3]->z<<FRACBITS, MT_EMERHUNT),
|
|
||||||
mobjinfo[MT_EMERHUNT].spawnstate+2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_SpawnMapThings(boolean spawnemblems)
|
static void P_SpawnMapThings(boolean spawnemblems)
|
||||||
|
@ -867,7 +847,7 @@ static void P_InitializeSector(sector_t *ss)
|
||||||
ss->camsec = -1;
|
ss->camsec = -1;
|
||||||
|
|
||||||
ss->floorlightsec = ss->ceilinglightsec = -1;
|
ss->floorlightsec = ss->ceilinglightsec = -1;
|
||||||
ss->crumblestate = 0;
|
ss->crumblestate = CRUMBLE_NONE;
|
||||||
|
|
||||||
ss->touching_thinglist = NULL;
|
ss->touching_thinglist = NULL;
|
||||||
|
|
||||||
|
@ -4129,12 +4109,12 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
|
||||||
{
|
{
|
||||||
UINT16 numlumps = *pnumlumps;
|
UINT16 numlumps = *pnumlumps;
|
||||||
size_t i = *pi;
|
size_t i = *pi;
|
||||||
if (!stricmp(lumpinfo->name2, folName))
|
if (!stricmp(lumpinfo->fullname, folName))
|
||||||
{
|
{
|
||||||
lumpinfo++;
|
lumpinfo++;
|
||||||
*start = ++i;
|
*start = ++i;
|
||||||
for (; i < numlumps; i++, lumpinfo++)
|
for (; i < numlumps; i++, lumpinfo++)
|
||||||
if (strnicmp(lumpinfo->name2, folName, strlen(folName)))
|
if (strnicmp(lumpinfo->fullname, folName, strlen(folName)))
|
||||||
break;
|
break;
|
||||||
lumpinfo--;
|
lumpinfo--;
|
||||||
*end = i-- - *start;
|
*end = i-- - *start;
|
||||||
|
|
230
src/p_spec.c
230
src/p_spec.c
|
@ -114,12 +114,11 @@ static void P_ResetColormapFader(sector_t *sector);
|
||||||
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
|
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
|
||||||
boolean ticbased, INT32 duration);
|
boolean ticbased, INT32 duration);
|
||||||
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
|
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
|
||||||
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline);
|
static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline);
|
||||||
//static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
|
//static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
|
||||||
static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers);
|
static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers);
|
||||||
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
||||||
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
||||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
|
|
||||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse);
|
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse);
|
||||||
|
|
||||||
|
|
||||||
|
@ -4468,7 +4467,8 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC);
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC);
|
||||||
break;
|
break;
|
||||||
case 5: // Spikes
|
case 5: // Spikes
|
||||||
// Don't do anything. In Soviet Russia, spikes find you.
|
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||||
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPIKE);
|
||||||
break;
|
break;
|
||||||
case 6: // Death Pit (Camera Mod)
|
case 6: // Death Pit (Camera Mod)
|
||||||
case 7: // Death Pit (No Camera Mod)
|
case 7: // Death Pit (No Camera Mod)
|
||||||
|
@ -5776,7 +5776,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
||||||
thinker_t *th;
|
thinker_t *th;
|
||||||
friction_t *f;
|
friction_t *f;
|
||||||
pusher_t *p;
|
pusher_t *p;
|
||||||
levelspecthink_t *lst;
|
|
||||||
size_t sec2num;
|
size_t sec2num;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -5877,16 +5876,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
||||||
else if (th == &thlist[THINK_MAIN])
|
else if (th == &thlist[THINK_MAIN])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Should this FOF have spikeness?
|
|
||||||
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
|
||||||
{
|
|
||||||
lst = (levelspecthink_t *)th;
|
|
||||||
|
|
||||||
if (lst->sector == sec2)
|
|
||||||
P_AddSpikeThinker(sec, (INT32)sec2num);
|
|
||||||
}
|
|
||||||
// Should this FOF have friction?
|
// Should this FOF have friction?
|
||||||
else if(th->function.acp1 == (actionf_p1)T_Friction)
|
if(th->function.acp1 == (actionf_p1)T_Friction)
|
||||||
{
|
{
|
||||||
f = (friction_t *)th;
|
f = (friction_t *)th;
|
||||||
|
|
||||||
|
@ -5933,7 +5924,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & FF_CRUMBLE))
|
if ((flags & FF_CRUMBLE))
|
||||||
sec2->crumblestate = 1;
|
sec2->crumblestate = CRUMBLE_WAIT;
|
||||||
|
|
||||||
if ((flags & FF_FLOATBOB))
|
if ((flags & FF_FLOATBOB))
|
||||||
{
|
{
|
||||||
|
@ -5950,28 +5941,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
||||||
// SPECIAL SPAWNING
|
// SPECIAL SPAWNING
|
||||||
//
|
//
|
||||||
|
|
||||||
/** Adds a spike thinker.
|
|
||||||
* Sector type Section1:5 will result in this effect.
|
|
||||||
*
|
|
||||||
* \param sec Sector in which to add the thinker.
|
|
||||||
* \param referrer If != sec, then we're dealing with a FOF
|
|
||||||
* \sa P_SpawnSpecials, T_SpikeSector
|
|
||||||
* \author SSNTails <http://www.ssntails.org>
|
|
||||||
*/
|
|
||||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer)
|
|
||||||
{
|
|
||||||
levelspecthink_t *spikes;
|
|
||||||
|
|
||||||
// create and initialize new thinker
|
|
||||||
spikes = Z_Calloc(sizeof (*spikes), PU_LEVSPEC, NULL);
|
|
||||||
P_AddThinker(THINK_MAIN, &spikes->thinker);
|
|
||||||
|
|
||||||
spikes->thinker.function.acp1 = (actionf_p1)T_SpikeSector;
|
|
||||||
|
|
||||||
spikes->sector = sec;
|
|
||||||
spikes->vars[0] = referrer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a float thinker.
|
/** Adds a float thinker.
|
||||||
* Float thinkers cause solid 3Dfloors to float on water.
|
* Float thinkers cause solid 3Dfloors to float on water.
|
||||||
*
|
*
|
||||||
|
@ -5980,9 +5949,9 @@ static void P_AddSpikeThinker(sector_t *sec, INT32 referrer)
|
||||||
* \sa P_SpawnSpecials, T_FloatSector
|
* \sa P_SpawnSpecials, T_FloatSector
|
||||||
* \author SSNTails <http://www.ssntails.org>
|
* \author SSNTails <http://www.ssntails.org>
|
||||||
*/
|
*/
|
||||||
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
|
static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline)
|
||||||
{
|
{
|
||||||
levelspecthink_t *floater;
|
floatthink_t *floater;
|
||||||
|
|
||||||
// create and initialize new thinker
|
// create and initialize new thinker
|
||||||
floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL);
|
floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL);
|
||||||
|
@ -5991,7 +5960,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
|
||||||
floater->thinker.function.acp1 = (actionf_p1)T_FloatSector;
|
floater->thinker.function.acp1 = (actionf_p1)T_FloatSector;
|
||||||
|
|
||||||
floater->sector = sec;
|
floater->sector = sec;
|
||||||
floater->vars[0] = tag;
|
floater->tag = (INT16)tag;
|
||||||
floater->sourceline = sourceline;
|
floater->sourceline = sourceline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6036,7 +6005,7 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control,
|
||||||
*/
|
*/
|
||||||
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
|
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
|
||||||
{
|
{
|
||||||
levelspecthink_t *block;
|
mariocheck_t *block;
|
||||||
|
|
||||||
// create and initialize new elevator thinker
|
// create and initialize new elevator thinker
|
||||||
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
|
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
|
||||||
|
@ -6062,85 +6031,52 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline)
|
||||||
* \sa P_SpawnSpecials, T_RaiseSector
|
* \sa P_SpawnSpecials, T_RaiseSector
|
||||||
* \author SSNTails <http://www.ssntails.org>
|
* \author SSNTails <http://www.ssntails.org>
|
||||||
*/
|
*/
|
||||||
static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline)
|
static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, boolean spindash)
|
||||||
{
|
{
|
||||||
levelspecthink_t *raise;
|
raise_t *raise;
|
||||||
|
|
||||||
raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL);
|
raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL);
|
||||||
P_AddThinker(THINK_MAIN, &raise->thinker);
|
P_AddThinker(THINK_MAIN, &raise->thinker);
|
||||||
|
|
||||||
raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
|
raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
|
||||||
|
|
||||||
if (sourceline->flags & ML_BLOCKMONSTERS)
|
raise->sourceline = sourceline;
|
||||||
raise->vars[0] = 1;
|
|
||||||
else
|
|
||||||
raise->vars[0] = 0;
|
|
||||||
|
|
||||||
// set up the fields
|
|
||||||
raise->sector = sec;
|
raise->sector = sec;
|
||||||
|
|
||||||
// Require a spindash to activate
|
raise->ceilingtop = P_FindHighestCeilingSurrounding(sec);
|
||||||
if (sourceline->flags & ML_NOCLIMB)
|
raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec);
|
||||||
raise->vars[1] = 1;
|
|
||||||
else
|
|
||||||
raise->vars[1] = 0;
|
|
||||||
|
|
||||||
raise->vars[2] = P_AproxDistance(sourceline->dx, sourceline->dy);
|
raise->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT);
|
||||||
raise->vars[2] = FixedDiv(raise->vars[2], 4*FRACUNIT);
|
|
||||||
raise->vars[3] = raise->vars[2];
|
|
||||||
|
|
||||||
raise->vars[5] = P_FindHighestCeilingSurrounding(sec);
|
if (lower)
|
||||||
raise->vars[4] = raise->vars[5]
|
raise->flags |= RF_REVERSE;
|
||||||
- (sec->ceilingheight - sec->floorheight);
|
if (spindash)
|
||||||
|
raise->flags |= RF_SPINDASH;
|
||||||
raise->vars[7] = P_FindLowestCeilingSurrounding(sec);
|
|
||||||
raise->vars[6] = raise->vars[7]
|
|
||||||
- (sec->ceilingheight - sec->floorheight);
|
|
||||||
|
|
||||||
raise->sourceline = sourceline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic)
|
static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic)
|
||||||
{
|
{
|
||||||
levelspecthink_t *airbob;
|
raise_t *airbob;
|
||||||
|
|
||||||
airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL);
|
airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL);
|
||||||
P_AddThinker(THINK_MAIN, &airbob->thinker);
|
P_AddThinker(THINK_MAIN, &airbob->thinker);
|
||||||
|
|
||||||
airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
|
airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector;
|
||||||
|
|
||||||
// set up the fields
|
airbob->sourceline = sourceline;
|
||||||
airbob->sector = sec;
|
airbob->sector = sec;
|
||||||
|
|
||||||
// Require a spindash to activate
|
airbob->ceilingtop = sec->ceilingheight;
|
||||||
if (sourceline->flags & ML_NOCLIMB)
|
airbob->ceilingbottom = sec->ceilingheight - dist;
|
||||||
airbob->vars[1] = 1;
|
|
||||||
else
|
|
||||||
airbob->vars[1] = 0;
|
|
||||||
|
|
||||||
airbob->vars[2] = FRACUNIT;
|
airbob->basespeed = FRACUNIT;
|
||||||
|
|
||||||
if (noadjust)
|
if (!raise)
|
||||||
airbob->vars[7] = airbob->sector->ceilingheight-16*FRACUNIT;
|
airbob->flags |= RF_REVERSE;
|
||||||
else
|
if (spindash)
|
||||||
airbob->vars[7] = airbob->sector->ceilingheight - P_AproxDistance(sourceline->dx, sourceline->dy);
|
airbob->flags |= RF_SPINDASH;
|
||||||
airbob->vars[6] = airbob->vars[7]
|
if (dynamic)
|
||||||
- (sec->ceilingheight - sec->floorheight);
|
airbob->flags |= RF_DYNAMIC;
|
||||||
|
|
||||||
airbob->vars[3] = airbob->vars[2];
|
|
||||||
|
|
||||||
if (sourceline->flags & ML_BLOCKMONSTERS)
|
|
||||||
airbob->vars[0] = 1;
|
|
||||||
else
|
|
||||||
airbob->vars[0] = 0;
|
|
||||||
|
|
||||||
airbob->vars[5] = sec->ceilingheight;
|
|
||||||
airbob->vars[4] = airbob->vars[5]
|
|
||||||
- (sec->ceilingheight - sec->floorheight);
|
|
||||||
|
|
||||||
airbob->vars[9] = dynamic ? 1 : 0;
|
|
||||||
|
|
||||||
airbob->sourceline = sourceline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a thwomp thinker.
|
/** Adds a thwomp thinker.
|
||||||
|
@ -6154,12 +6090,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boo
|
||||||
*/
|
*/
|
||||||
static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline)
|
static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline)
|
||||||
{
|
{
|
||||||
#define speed vars[1]
|
thwomp_t *thwomp;
|
||||||
#define direction vars[2]
|
|
||||||
#define distance vars[3]
|
|
||||||
#define floorwasheight vars[4]
|
|
||||||
#define ceilingwasheight vars[5]
|
|
||||||
levelspecthink_t *thwomp;
|
|
||||||
|
|
||||||
// You *probably* already have a thwomp in this sector. If you've combined it with something
|
// You *probably* already have a thwomp in this sector. If you've combined it with something
|
||||||
// else that uses the floordata/ceilingdata, you must be weird.
|
// else that uses the floordata/ceilingdata, you must be weird.
|
||||||
|
@ -6173,34 +6104,33 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin
|
||||||
thwomp->thinker.function.acp1 = (actionf_p1)T_ThwompSector;
|
thwomp->thinker.function.acp1 = (actionf_p1)T_ThwompSector;
|
||||||
|
|
||||||
// set up the fields according to the type of elevator action
|
// set up the fields according to the type of elevator action
|
||||||
thwomp->sector = sec;
|
|
||||||
thwomp->vars[0] = actionsector->tag;
|
|
||||||
thwomp->floorwasheight = thwomp->sector->floorheight;
|
|
||||||
thwomp->ceilingwasheight = thwomp->sector->ceilingheight;
|
|
||||||
thwomp->direction = 0;
|
|
||||||
thwomp->distance = 1;
|
|
||||||
thwomp->sourceline = sourceline;
|
thwomp->sourceline = sourceline;
|
||||||
thwomp->sector->floordata = thwomp;
|
thwomp->sector = sec;
|
||||||
thwomp->sector->ceilingdata = thwomp;
|
thwomp->crushspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dy >> 3 : 10*FRACUNIT;
|
||||||
return;
|
thwomp->retractspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dx >> 3 : 2*FRACUNIT;
|
||||||
#undef speed
|
thwomp->direction = 0;
|
||||||
#undef direction
|
thwomp->floorstartheight = sec->floorheight;
|
||||||
#undef distance
|
thwomp->ceilingstartheight = sec->ceilingheight;
|
||||||
#undef floorwasheight
|
thwomp->delay = 1;
|
||||||
#undef ceilingwasheight
|
thwomp->tag = actionsector->tag;
|
||||||
|
thwomp->sound = (sourceline->flags & ML_EFFECT4) ? sides[sourceline->sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp;
|
||||||
|
|
||||||
|
sec->floordata = thwomp;
|
||||||
|
sec->ceilingdata = thwomp;
|
||||||
|
// Start with 'resting' texture
|
||||||
|
sides[sourceline->sidenum[0]].midtexture = sides[sourceline->sidenum[0]].bottomtexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area.
|
/** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area.
|
||||||
* If not, a linedef executor is run once.
|
* If not, a linedef executor is run once.
|
||||||
*
|
*
|
||||||
* \param sec Control sector.
|
|
||||||
* \param sourceline Control linedef.
|
* \param sourceline Control linedef.
|
||||||
* \sa P_SpawnSpecials, T_NoEnemiesSector
|
* \sa P_SpawnSpecials, T_NoEnemiesSector
|
||||||
* \author SSNTails <http://www.ssntails.org>
|
* \author SSNTails <http://www.ssntails.org>
|
||||||
*/
|
*/
|
||||||
static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline)
|
static inline void P_AddNoEnemiesThinker(line_t *sourceline)
|
||||||
{
|
{
|
||||||
levelspecthink_t *nobaddies;
|
noenemies_t *nobaddies;
|
||||||
|
|
||||||
// create and initialize new thinker
|
// create and initialize new thinker
|
||||||
nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL);
|
nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL);
|
||||||
|
@ -6208,21 +6138,19 @@ static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline)
|
||||||
|
|
||||||
nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector;
|
nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector;
|
||||||
|
|
||||||
nobaddies->sector = sec;
|
|
||||||
nobaddies->sourceline = sourceline;
|
nobaddies->sourceline = sourceline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a thinker for Each-Time linedef executors. A linedef executor is run
|
/** Adds a thinker for Each-Time linedef executors. A linedef executor is run
|
||||||
* only when a player enters the area and doesn't run again until they re-enter.
|
* only when a player enters the area and doesn't run again until they re-enter.
|
||||||
*
|
*
|
||||||
* \param sec Control sector that contains the lines of executors we will want to run.
|
|
||||||
* \param sourceline Control linedef.
|
* \param sourceline Control linedef.
|
||||||
* \sa P_SpawnSpecials, T_EachTimeThinker
|
* \sa P_SpawnSpecials, T_EachTimeThinker
|
||||||
* \author SSNTails <http://www.ssntails.org>
|
* \author SSNTails <http://www.ssntails.org>
|
||||||
*/
|
*/
|
||||||
static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline)
|
static void P_AddEachTimeThinker(line_t *sourceline)
|
||||||
{
|
{
|
||||||
levelspecthink_t *eachtime;
|
eachtime_t *eachtime;
|
||||||
|
|
||||||
// create and initialize new thinker
|
// create and initialize new thinker
|
||||||
eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL);
|
eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL);
|
||||||
|
@ -6230,8 +6158,8 @@ static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline)
|
||||||
|
|
||||||
eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker;
|
eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker;
|
||||||
|
|
||||||
eachtime->sector = sec;
|
|
||||||
eachtime->sourceline = sourceline;
|
eachtime->sourceline = sourceline;
|
||||||
|
eachtime->triggerOnExit = !!(sourceline->flags & ML_BOUNCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a camera scanner.
|
/** Adds a camera scanner.
|
||||||
|
@ -6458,9 +6386,11 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
switch(GETSECSPECIAL(sector->special, 1))
|
switch(GETSECSPECIAL(sector->special, 1))
|
||||||
{
|
{
|
||||||
case 5: // Spikes
|
case 5: // Spikes
|
||||||
P_AddSpikeThinker(sector, (INT32)(sector-sectors));
|
//Terrible hack to replace an even worse hack:
|
||||||
|
//Spike damage automatically sets SF_TRIGGERSPECIAL_TOUCH.
|
||||||
|
//Yes, this also affects other specials on the same sector. Sorry.
|
||||||
|
sector->flags |= SF_TRIGGERSPECIAL_TOUCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 15: // Bouncy sector
|
case 15: // Bouncy sector
|
||||||
CheckForBouncySector = true;
|
CheckForBouncySector = true;
|
||||||
break;
|
break;
|
||||||
|
@ -6506,9 +6436,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
// Firstly, find out how many there are in each sector
|
// Firstly, find out how many there are in each sector
|
||||||
for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next)
|
for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next)
|
||||||
{
|
{
|
||||||
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
if (th->function.acp1 == (actionf_p1)T_Friction)
|
||||||
secthinkers[((levelspecthink_t *)th)->sector - sectors].count++;
|
|
||||||
else if (th->function.acp1 == (actionf_p1)T_Friction)
|
|
||||||
secthinkers[((friction_t *)th)->affectee].count++;
|
secthinkers[((friction_t *)th)->affectee].count++;
|
||||||
else if (th->function.acp1 == (actionf_p1)T_Pusher)
|
else if (th->function.acp1 == (actionf_p1)T_Pusher)
|
||||||
secthinkers[((pusher_t *)th)->affectee].count++;
|
secthinkers[((pusher_t *)th)->affectee].count++;
|
||||||
|
@ -6528,9 +6456,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
{
|
{
|
||||||
size_t secnum = (size_t)-1;
|
size_t secnum = (size_t)-1;
|
||||||
|
|
||||||
if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
if (th->function.acp1 == (actionf_p1)T_Friction)
|
||||||
secnum = ((levelspecthink_t *)th)->sector - sectors;
|
|
||||||
else if (th->function.acp1 == (actionf_p1)T_Friction)
|
|
||||||
secnum = ((friction_t *)th)->affectee;
|
secnum = ((friction_t *)th)->affectee;
|
||||||
else if (th->function.acp1 == (actionf_p1)T_Pusher)
|
else if (th->function.acp1 == (actionf_p1)T_Pusher)
|
||||||
secnum = ((pusher_t *)th)->affectee;
|
secnum = ((pusher_t *)th)->affectee;
|
||||||
|
@ -6943,18 +6869,20 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
|
|
||||||
case 150: // Air bobbing platform
|
case 150: // Air bobbing platform
|
||||||
case 151: // Adjustable air bobbing platform
|
case 151: // Adjustable air bobbing platform
|
||||||
|
{
|
||||||
|
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_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false);
|
||||||
P_AddAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false);
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 152: // Adjustable air bobbing platform in reverse
|
case 152: // Adjustable air bobbing platform in reverse
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false);
|
||||||
break;
|
break;
|
||||||
case 153: // Dynamic Sinking Platform
|
case 153: // Dynamic Sinking Platform
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
lines[i].flags |= ML_BLOCKMONSTERS;
|
||||||
P_AddAirbob(lines[i].frontsector, lines + i, false, true);
|
P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 160: // Float/bob platform
|
case 160: // Float/bob platform
|
||||||
|
@ -7004,15 +6932,13 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
|
|
||||||
case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits
|
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_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers);
|
||||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false);
|
||||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 177: // Air bobbing platform that will crumble and bob on
|
case 177: // Air bobbing platform that will crumble and bob on
|
||||||
// the water when it falls and hits, then never return
|
// 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_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers);
|
||||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false);
|
||||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 178: // Crumbling platform that will float when it hits water
|
case 178: // Crumbling platform that will float when it hits water
|
||||||
|
@ -7025,28 +6951,27 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
|
|
||||||
case 180: // Air bobbing platform that will crumble
|
case 180: // Air bobbing platform that will crumble
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers);
|
||||||
lines[i].flags |= ML_BLOCKMONSTERS;
|
P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false);
|
||||||
P_AddAirbob(lines[i].frontsector, lines + i, true, false);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 190: // Rising Platform FOF (solid, opaque, shadows)
|
case 190: // Rising Platform FOF (solid, opaque, shadows)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||||
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
|
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 191: // Rising Platform FOF (solid, opaque, no shadows)
|
case 191: // Rising Platform FOF (solid, opaque, no shadows)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers);
|
||||||
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
|
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 192: // Rising Platform TL block: FOF (solid, translucent)
|
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_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA, secthinkers);
|
||||||
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
|
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 193: // Rising Platform FOF (solid, invisible)
|
case 193: // Rising Platform FOF (solid, invisible)
|
||||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers);
|
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers);
|
||||||
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
|
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 194: // Rising Platform 'Platform' - You can jump up through it
|
case 194: // Rising Platform 'Platform' - You can jump up through it
|
||||||
|
@ -7056,7 +6981,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
ffloorflags |= FF_NOSHADE;
|
ffloorflags |= FF_NOSHADE;
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
|
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 195: // Rising Platform Translucent "platform"
|
case 195: // Rising Platform Translucent "platform"
|
||||||
|
@ -7066,7 +6991,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
ffloorflags |= FF_NOSHADE;
|
ffloorflags |= FF_NOSHADE;
|
||||||
|
|
||||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||||
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
|
P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 200: // Double light effect
|
case 200: // Double light effect
|
||||||
|
@ -7215,14 +7140,12 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
case 312:
|
case 312:
|
||||||
case 332:
|
case 332:
|
||||||
case 335:
|
case 335:
|
||||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
P_AddEachTimeThinker(&lines[i]);
|
||||||
P_AddEachTimeThinker(§ors[sec], &lines[i]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// No More Enemies Linedef Exec
|
// No More Enemies Linedef Exec
|
||||||
case 313:
|
case 313:
|
||||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
P_AddNoEnemiesThinker(&lines[i]);
|
||||||
P_AddNoEnemiesThinker(§ors[sec], &lines[i]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Pushable linedef executors (count # of pushables)
|
// Pushable linedef executors (count # of pushables)
|
||||||
|
@ -7246,10 +7169,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
||||||
else
|
else
|
||||||
lines[i].callcount = sides[lines[i].sidenum[0]].textureoffset>>FRACBITS;
|
lines[i].callcount = sides[lines[i].sidenum[0]].textureoffset>>FRACBITS;
|
||||||
if (lines[i].special == 322) // Each time
|
if (lines[i].special == 322) // Each time
|
||||||
{
|
P_AddEachTimeThinker(&lines[i]);
|
||||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
|
||||||
P_AddEachTimeThinker(§ors[sec], &lines[i]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// NiGHTS trigger executors
|
// NiGHTS trigger executors
|
||||||
|
|
129
src/p_spec.h
129
src/p_spec.h
|
@ -314,11 +314,101 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
thinker_t thinker;
|
thinker_t thinker;
|
||||||
fixed_t vars[16]; // Misc. variables
|
|
||||||
fixed_t var2s[16]; // Second misc variables buffer.
|
|
||||||
line_t *sourceline; // Source line of the thinker
|
line_t *sourceline; // Source line of the thinker
|
||||||
sector_t *sector; // Sector the thinker is from
|
} noenemies_t;
|
||||||
} levelspecthink_t;
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
sector_t *sector;
|
||||||
|
fixed_t speed;
|
||||||
|
INT32 direction;
|
||||||
|
fixed_t floorstartheight;
|
||||||
|
fixed_t ceilingstartheight;
|
||||||
|
fixed_t destheight;
|
||||||
|
} continuousfall_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
line_t *sourceline;
|
||||||
|
sector_t *sector;
|
||||||
|
fixed_t speed;
|
||||||
|
fixed_t distance;
|
||||||
|
fixed_t floorwasheight;
|
||||||
|
fixed_t ceilingwasheight;
|
||||||
|
boolean low;
|
||||||
|
} bouncecheese_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
sector_t *sector;
|
||||||
|
fixed_t speed;
|
||||||
|
INT32 direction;
|
||||||
|
fixed_t floorstartheight;
|
||||||
|
fixed_t ceilingstartheight;
|
||||||
|
INT16 tag;
|
||||||
|
} mariothink_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
line_t *sourceline;
|
||||||
|
sector_t *sector;
|
||||||
|
} mariocheck_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
line_t *sourceline;
|
||||||
|
sector_t *sector;
|
||||||
|
fixed_t crushspeed;
|
||||||
|
fixed_t retractspeed;
|
||||||
|
INT32 direction;
|
||||||
|
fixed_t floorstartheight;
|
||||||
|
fixed_t ceilingstartheight;
|
||||||
|
INT32 delay;
|
||||||
|
INT16 tag;
|
||||||
|
UINT16 sound;
|
||||||
|
} thwomp_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
line_t *sourceline;
|
||||||
|
sector_t *sector;
|
||||||
|
INT16 tag;
|
||||||
|
} floatthink_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
line_t *sourceline; // Source line of the thinker
|
||||||
|
boolean playersInArea[MAXPLAYERS];
|
||||||
|
boolean playersOnArea[MAXPLAYERS];
|
||||||
|
boolean triggerOnExit;
|
||||||
|
} eachtime_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RF_REVERSE = 1, //Lower when stood on
|
||||||
|
RF_SPINDASH = 1<<1, //Require spindash to move
|
||||||
|
RF_DYNAMIC = 1<<2, //Dynamically sinking platform
|
||||||
|
} raiseflag_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
line_t *sourceline;
|
||||||
|
sector_t *sector;
|
||||||
|
fixed_t ceilingbottom;
|
||||||
|
fixed_t ceilingtop;
|
||||||
|
fixed_t basespeed;
|
||||||
|
fixed_t extraspeed; //For dynamically sinking platform
|
||||||
|
UINT8 shaketimer; //For dynamically sinking platform
|
||||||
|
UINT8 flags;
|
||||||
|
} raise_t;
|
||||||
|
|
||||||
#define ELEVATORSPEED (FRACUNIT*4)
|
#define ELEVATORSPEED (FRACUNIT*4)
|
||||||
#define FLOORSPEED (FRACUNIT)
|
#define FLOORSPEED (FRACUNIT)
|
||||||
|
@ -331,35 +421,34 @@ typedef enum
|
||||||
} result_e;
|
} result_e;
|
||||||
|
|
||||||
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
|
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
|
||||||
INT32 floorOrCeiling, INT32 direction);
|
boolean ceiling, INT32 direction);
|
||||||
INT32 EV_DoFloor(line_t *line, floor_e floortype);
|
void EV_DoFloor(line_t *line, floor_e floortype);
|
||||||
INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
|
void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
|
||||||
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
|
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
|
||||||
INT32 EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
|
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
|
||||||
|
|
||||||
// Some other special 3dfloor types
|
// Some other special 3dfloor types
|
||||||
INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
|
INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
|
||||||
boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
|
boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
|
||||||
|
|
||||||
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
|
void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards);
|
||||||
|
|
||||||
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
|
void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
|
||||||
|
|
||||||
void T_MoveFloor(floormove_t *movefloor);
|
void T_MoveFloor(floormove_t *movefloor);
|
||||||
|
|
||||||
void T_MoveElevator(elevator_t *elevator);
|
void T_MoveElevator(elevator_t *elevator);
|
||||||
void T_ContinuousFalling(levelspecthink_t *faller);
|
void T_ContinuousFalling(continuousfall_t *faller);
|
||||||
void T_BounceCheese(levelspecthink_t *bouncer);
|
void T_BounceCheese(bouncecheese_t *bouncer);
|
||||||
void T_StartCrumble(elevator_t *elevator);
|
void T_StartCrumble(elevator_t *elevator);
|
||||||
void T_MarioBlock(levelspecthink_t *block);
|
void T_MarioBlock(mariothink_t *block);
|
||||||
void T_SpikeSector(levelspecthink_t *spikes);
|
void T_FloatSector(floatthink_t *floater);
|
||||||
void T_FloatSector(levelspecthink_t *floater);
|
void T_MarioBlockChecker(mariocheck_t *block);
|
||||||
void T_MarioBlockChecker(levelspecthink_t *block);
|
void T_ThwompSector(thwomp_t *thwomp);
|
||||||
void T_ThwompSector(levelspecthink_t *thwomp);
|
void T_NoEnemiesSector(noenemies_t *nobaddies);
|
||||||
void T_NoEnemiesSector(levelspecthink_t *nobaddies);
|
void T_EachTimeThinker(eachtime_t *eachtime);
|
||||||
void T_EachTimeThinker(levelspecthink_t *eachtime);
|
|
||||||
void T_CameraScanner(elevator_t *elevator);
|
void T_CameraScanner(elevator_t *elevator);
|
||||||
void T_RaiseSector(levelspecthink_t *sraise);
|
void T_RaiseSector(raise_t *raise);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -2566,7 +2566,7 @@ static void P_CheckBustableBlocks(player_t *player)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS)) continue;
|
if (!(rover->flags & FF_EXISTS)) continue;
|
||||||
|
|
||||||
if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/)
|
if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/)
|
||||||
{
|
{
|
||||||
// If it's an FF_SHATTER, you can break it just by touching it.
|
// If it's an FF_SHATTER, you can break it just by touching it.
|
||||||
if (rover->flags & FF_SHATTER)
|
if (rover->flags & FF_SHATTER)
|
||||||
|
|
10
src/r_defs.h
10
src/r_defs.h
|
@ -277,6 +277,16 @@ typedef enum
|
||||||
SF_INVERTPRECIP = 1<<4,
|
SF_INVERTPRECIP = 1<<4,
|
||||||
} sectorflags_t;
|
} sectorflags_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CRUMBLE_NONE, // No crumble thinker
|
||||||
|
CRUMBLE_WAIT, // Don't float on water because this is supposed to wait for a crumble
|
||||||
|
CRUMBLE_ACTIVATED, // Crumble thinker activated, but hasn't fallen yet
|
||||||
|
CRUMBLE_FALL, // Crumble thinker is falling
|
||||||
|
CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position
|
||||||
|
} crumblestate_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The SECTORS record, at runtime.
|
// The SECTORS record, at runtime.
|
||||||
// Stores things/mobjs.
|
// Stores things/mobjs.
|
||||||
|
|
22
src/r_segs.c
22
src/r_segs.c
|
@ -236,14 +236,13 @@ static void R_DrawWallSplats(void)
|
||||||
// way we don't have to store extra post_t info with each column for
|
// way we don't have to store extra post_t info with each column for
|
||||||
// multi-patch textures. They are not normally needed as multi-patch
|
// multi-patch textures. They are not normally needed as multi-patch
|
||||||
// textures don't have holes in it. At least not for now.
|
// textures don't have holes in it. At least not for now.
|
||||||
static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height
|
|
||||||
|
|
||||||
static void R_Render2sidedMultiPatchColumn(column_t *column)
|
static void R_Render2sidedMultiPatchColumn(column_t *column)
|
||||||
{
|
{
|
||||||
INT32 topscreen, bottomscreen;
|
INT32 topscreen, bottomscreen;
|
||||||
|
|
||||||
topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
|
topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
|
||||||
bottomscreen = topscreen + spryscale * column2s_length;
|
bottomscreen = topscreen + spryscale * lengthcol;
|
||||||
|
|
||||||
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
||||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||||
|
@ -275,13 +274,6 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value
|
|
||||||
// uses column2s_length for texture->height as above
|
|
||||||
static void R_DrawFlippedMaskedSegColumn(column_t *column)
|
|
||||||
{
|
|
||||||
R_DrawFlippedMaskedColumn(column, column2s_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
||||||
{
|
{
|
||||||
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||||
|
@ -354,8 +346,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||||
{
|
{
|
||||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||||
{
|
{
|
||||||
colfunc_2s = R_DrawFlippedMaskedSegColumn;
|
colfunc_2s = R_DrawFlippedMaskedColumn;
|
||||||
column2s_length = textures[texnum]->height;
|
lengthcol = textures[texnum]->height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||||
|
@ -363,7 +355,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
|
colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
|
||||||
column2s_length = textures[texnum]->height;
|
lengthcol = textures[texnum]->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup lighting based on the presence/lack-of 3D floors.
|
// Setup lighting based on the presence/lack-of 3D floors.
|
||||||
|
@ -693,7 +685,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col)
|
||||||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
|
static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
R_DrawFlippedMaskedColumn(col, column2s_length);
|
R_DrawFlippedMaskedColumn(col);
|
||||||
sprtopscreen += dc_texheight*spryscale;
|
sprtopscreen += dc_texheight*spryscale;
|
||||||
} while (sprtopscreen < sprbotscreen);
|
} while (sprtopscreen < sprbotscreen);
|
||||||
}
|
}
|
||||||
|
@ -988,7 +980,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||||
{
|
{
|
||||||
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
|
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
|
||||||
column2s_length = textures[texnum]->height;
|
lengthcol = textures[texnum]->height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
|
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||||
|
@ -996,7 +988,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
|
colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
|
||||||
column2s_length = textures[texnum]->height;
|
lengthcol = textures[texnum]->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set heights according to plane, or slope, whichever
|
// Set heights according to plane, or slope, whichever
|
||||||
|
|
|
@ -639,10 +639,10 @@ void R_DrawMaskedColumn(column_t *column)
|
||||||
dc_yl = mceilingclip[dc_x]+1;
|
dc_yl = mceilingclip[dc_x]+1;
|
||||||
if (dc_yl < 0)
|
if (dc_yl < 0)
|
||||||
dc_yl = 0;
|
dc_yl = 0;
|
||||||
if (dc_yh >= vid.height)
|
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||||
dc_yh = vid.height - 1;
|
dc_yh = vid.height - 1;
|
||||||
|
|
||||||
if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0)
|
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||||
{
|
{
|
||||||
dc_source = (UINT8 *)column + 3;
|
dc_source = (UINT8 *)column + 3;
|
||||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||||
|
@ -653,15 +653,10 @@ void R_DrawMaskedColumn(column_t *column)
|
||||||
// quick fix... something more proper should be done!!!
|
// quick fix... something more proper should be done!!!
|
||||||
if (ylookup[dc_yl])
|
if (ylookup[dc_yl])
|
||||||
colfunc();
|
colfunc();
|
||||||
else if (colfunc == colfuncs[COLDRAWFUNC_BASE])
|
#ifdef PARANOIA
|
||||||
{
|
else
|
||||||
static INT32 first = 1;
|
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||||
if (first)
|
#endif
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||||
}
|
}
|
||||||
|
@ -669,7 +664,9 @@ void R_DrawMaskedColumn(column_t *column)
|
||||||
dc_texturemid = basetexturemid;
|
dc_texturemid = basetexturemid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
|
||||||
|
|
||||||
|
void R_DrawFlippedMaskedColumn(column_t *column)
|
||||||
{
|
{
|
||||||
INT32 topscreen;
|
INT32 topscreen;
|
||||||
INT32 bottomscreen;
|
INT32 bottomscreen;
|
||||||
|
@ -685,7 +682,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
||||||
if (topdelta <= prevdelta)
|
if (topdelta <= prevdelta)
|
||||||
topdelta += prevdelta;
|
topdelta += prevdelta;
|
||||||
prevdelta = topdelta;
|
prevdelta = topdelta;
|
||||||
topdelta = texheight-column->length-topdelta;
|
topdelta = lengthcol-column->length-topdelta;
|
||||||
topscreen = sprtopscreen + spryscale*topdelta;
|
topscreen = sprtopscreen + spryscale*topdelta;
|
||||||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
|
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
|
||||||
: sprbotscreen + spryscale*column->length;
|
: sprbotscreen + spryscale*column->length;
|
||||||
|
@ -707,10 +704,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
||||||
dc_yl = mceilingclip[dc_x]+1;
|
dc_yl = mceilingclip[dc_x]+1;
|
||||||
if (dc_yl < 0)
|
if (dc_yl < 0)
|
||||||
dc_yl = 0;
|
dc_yl = 0;
|
||||||
if (dc_yh >= vid.height)
|
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||||
dc_yh = vid.height - 1;
|
dc_yh = vid.height - 1;
|
||||||
|
|
||||||
if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0)
|
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||||
{
|
{
|
||||||
dc_source = ZZ_Alloc(column->length);
|
dc_source = ZZ_Alloc(column->length);
|
||||||
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
||||||
|
@ -720,15 +717,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
||||||
// Still drawn by R_DrawColumn.
|
// Still drawn by R_DrawColumn.
|
||||||
if (ylookup[dc_yl])
|
if (ylookup[dc_yl])
|
||||||
colfunc();
|
colfunc();
|
||||||
else if (colfunc == colfuncs[COLDRAWFUNC_BASE])
|
#ifdef PARANOIA
|
||||||
{
|
else
|
||||||
static INT32 first = 1;
|
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||||
if (first)
|
#endif
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__);
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z_Free(dc_source);
|
Z_Free(dc_source);
|
||||||
}
|
}
|
||||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||||
|
@ -744,7 +736,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
||||||
static void R_DrawVisSprite(vissprite_t *vis)
|
static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
{
|
{
|
||||||
column_t *column;
|
column_t *column;
|
||||||
|
void (*localcolfunc)(column_t *);
|
||||||
INT32 texturecolumn;
|
INT32 texturecolumn;
|
||||||
|
INT32 pwidth;
|
||||||
fixed_t frac;
|
fixed_t frac;
|
||||||
patch_t *patch = vis->patch;
|
patch_t *patch = vis->patch;
|
||||||
fixed_t this_scale = vis->mobj->scale;
|
fixed_t this_scale = vis->mobj->scale;
|
||||||
|
@ -893,50 +887,52 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
if (vis->x2 >= vid.width)
|
if (vis->x2 >= vid.width)
|
||||||
vis->x2 = vid.width-1;
|
vis->x2 = vid.width-1;
|
||||||
|
|
||||||
|
localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn;
|
||||||
|
lengthcol = patch->height;
|
||||||
|
|
||||||
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
|
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
|
||||||
if (vis->scalestep)
|
if (vis->scalestep)
|
||||||
{
|
{
|
||||||
// Papersprite drawing loop
|
pwidth = SHORT(patch->width);
|
||||||
|
|
||||||
|
// Papersprite drawing loop
|
||||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
|
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
|
||||||
{
|
{
|
||||||
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||||
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
|
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
|
||||||
|
|
||||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (vis->xiscale < 0) // Flipped sprite
|
if (vis->xiscale < 0) // Flipped sprite
|
||||||
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
|
texturecolumn = pwidth - 1 - texturecolumn;
|
||||||
|
|
||||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||||
|
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||||
|
|
||||||
if (vis->cut & SC_VFLIP)
|
localcolfunc (column);
|
||||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
|
||||||
else
|
|
||||||
R_DrawMaskedColumn(column);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
pwidth = SHORT(patch->width);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Non-paper drawing loop
|
// Non-paper drawing loop
|
||||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||||
{
|
{
|
||||||
#ifdef RANGECHECK
|
#ifdef RANGECHECK
|
||||||
texturecolumn = frac>>FRACBITS;
|
texturecolumn = frac>>FRACBITS;
|
||||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||||
#else
|
#else
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||||
#endif
|
#endif
|
||||||
if (vis->cut & SC_VFLIP)
|
localcolfunc (column);
|
||||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
|
||||||
else
|
|
||||||
R_DrawMaskedColumn(column);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,10 @@ extern fixed_t sprtopscreen;
|
||||||
extern fixed_t sprbotscreen;
|
extern fixed_t sprbotscreen;
|
||||||
extern fixed_t windowtop;
|
extern fixed_t windowtop;
|
||||||
extern fixed_t windowbottom;
|
extern fixed_t windowbottom;
|
||||||
|
extern INT32 lengthcol;
|
||||||
|
|
||||||
void R_DrawMaskedColumn(column_t *column);
|
void R_DrawMaskedColumn(column_t *column);
|
||||||
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
|
void R_DrawFlippedMaskedColumn(column_t *column);
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
// SPRITE RENDERING
|
// SPRITE RENDERING
|
||||||
|
|
95
src/w_wad.c
95
src/w_wad.c
|
@ -92,7 +92,7 @@ typedef struct
|
||||||
|
|
||||||
typedef struct lumpnum_cache_s
|
typedef struct lumpnum_cache_s
|
||||||
{
|
{
|
||||||
char lumpname[8];
|
char lumpname[32];
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
} lumpnum_cache_t;
|
} lumpnum_cache_t;
|
||||||
|
|
||||||
|
@ -114,13 +114,18 @@ void W_Shutdown(void)
|
||||||
{
|
{
|
||||||
while (numwadfiles--)
|
while (numwadfiles--)
|
||||||
{
|
{
|
||||||
fclose(wadfiles[numwadfiles]->handle);
|
wadfile_t *wad = wadfiles[numwadfiles];
|
||||||
Z_Free(wadfiles[numwadfiles]->filename);
|
|
||||||
while (wadfiles[numwadfiles]->numlumps--)
|
|
||||||
Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2);
|
|
||||||
|
|
||||||
Z_Free(wadfiles[numwadfiles]->lumpinfo);
|
fclose(wad->handle);
|
||||||
Z_Free(wadfiles[numwadfiles]);
|
Z_Free(wad->filename);
|
||||||
|
while (wad->numlumps--)
|
||||||
|
{
|
||||||
|
Z_Free(wad->lumpinfo[wad->numlumps].longname);
|
||||||
|
Z_Free(wad->lumpinfo[wad->numlumps].fullname);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(wad->lumpinfo);
|
||||||
|
Z_Free(wad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,9 +211,9 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
|
||||||
for(; posStart < posEnd; posStart++)
|
for(; posStart < posEnd; posStart++)
|
||||||
{
|
{
|
||||||
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
|
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
|
||||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||||
char *name = malloc(length + 1);
|
char *name = malloc(length + 1);
|
||||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
|
||||||
name[length] = '\0';
|
name[length] = '\0';
|
||||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
||||||
DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile);
|
DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile);
|
||||||
|
@ -235,9 +240,9 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
|
||||||
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
||||||
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
|
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
|
||||||
{ // shameless copy+paste of code from LUA_LoadLump
|
{ // shameless copy+paste of code from LUA_LoadLump
|
||||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||||
char *name = malloc(length + 1);
|
char *name = malloc(length + 1);
|
||||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
|
||||||
name[length] = '\0';
|
name[length] = '\0';
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
||||||
|
@ -339,10 +344,17 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
|
||||||
lumpinfo->size = ftell(handle);
|
lumpinfo->size = ftell(handle);
|
||||||
fseek(handle, 0, SEEK_SET);
|
fseek(handle, 0, SEEK_SET);
|
||||||
strcpy(lumpinfo->name, lumpname);
|
strcpy(lumpinfo->name, lumpname);
|
||||||
|
|
||||||
|
// Allocate the lump's long name.
|
||||||
|
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
|
strcpy(lumpinfo->longname, lumpname);
|
||||||
|
lumpinfo->longname[8] = '\0';
|
||||||
|
|
||||||
// Allocate the lump's full name.
|
// Allocate the lump's full name.
|
||||||
lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
lumpinfo->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
strcpy(lumpinfo->name2, lumpname);
|
strcpy(lumpinfo->fullname, lumpname);
|
||||||
lumpinfo->name2[8] = '\0';
|
lumpinfo->fullname[8] = '\0';
|
||||||
|
|
||||||
*numlumps = 1;
|
*numlumps = 1;
|
||||||
return lumpinfo;
|
return lumpinfo;
|
||||||
}
|
}
|
||||||
|
@ -429,10 +441,16 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
||||||
lump_p->compression = CM_NOCOMPRESSION;
|
lump_p->compression = CM_NOCOMPRESSION;
|
||||||
memset(lump_p->name, 0x00, 9);
|
memset(lump_p->name, 0x00, 9);
|
||||||
strncpy(lump_p->name, fileinfo->name, 8);
|
strncpy(lump_p->name, fileinfo->name, 8);
|
||||||
|
|
||||||
|
// Allocate the lump's long name.
|
||||||
|
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
|
strncpy(lump_p->longname, fileinfo->name, 8);
|
||||||
|
lump_p->longname[8] = '\0';
|
||||||
|
|
||||||
// Allocate the lump's full name.
|
// Allocate the lump's full name.
|
||||||
lump_p->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
strncpy(lump_p->name2, fileinfo->name, 8);
|
strncpy(lump_p->fullname, fileinfo->name, 8);
|
||||||
lump_p->name2[8] = '\0';
|
lump_p->fullname[8] = '\0';
|
||||||
}
|
}
|
||||||
free(fileinfov);
|
free(fileinfov);
|
||||||
*nlmp = numlumps;
|
*nlmp = numlumps;
|
||||||
|
@ -598,8 +616,11 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
||||||
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||||
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
|
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
|
||||||
|
|
||||||
lump_p->name2 = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
|
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
|
||||||
strncpy(lump_p->name2, fullname, zentry.namelen);
|
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
||||||
|
|
||||||
|
lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
|
||||||
|
strncpy(lump_p->fullname, fullname, zentry.namelen);
|
||||||
|
|
||||||
free(fullname);
|
free(fullname);
|
||||||
|
|
||||||
|
@ -637,7 +658,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
||||||
// skip and ignore comments/extra fields
|
// skip and ignore comments/extra fields
|
||||||
if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t)))
|
if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t)))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->name2);
|
CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->fullname);
|
||||||
Z_Free(lumpinfo);
|
Z_Free(lumpinfo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -901,16 +922,14 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum)
|
||||||
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
static char uname[9];
|
static char uname[256 + 1];
|
||||||
|
|
||||||
memset(uname, 0x00, sizeof uname);
|
|
||||||
strncpy(uname, name, 8);
|
|
||||||
uname[8] = 0;
|
|
||||||
strupr(uname);
|
|
||||||
|
|
||||||
if (!TestValidLump(wad,0))
|
if (!TestValidLump(wad,0))
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
|
|
||||||
|
strlcpy(uname, name, sizeof uname);
|
||||||
|
strupr(uname);
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan forward
|
// scan forward
|
||||||
// start at 'startlump', useful parameter when there are multiple
|
// start at 'startlump', useful parameter when there are multiple
|
||||||
|
@ -920,7 +939,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
{
|
{
|
||||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
if (memcmp(lump_p->name,uname,8) == 0)
|
if (!strcmp(lump_p->longname, uname))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,10 +966,10 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum
|
||||||
name_length = strlen(name);
|
name_length = strlen(name);
|
||||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
{
|
{
|
||||||
if (strnicmp(name, lump_p->name2, name_length) == 0)
|
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||||
{
|
{
|
||||||
/* SLADE is special and puts a single directory entry. Skip that. */
|
/* SLADE is special and puts a single directory entry. Skip that. */
|
||||||
if (strlen(lump_p->name2) == name_length)
|
if (strlen(lump_p->fullname) == name_length)
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -967,7 +986,7 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
{
|
{
|
||||||
if (strnicmp(name, lump_p->name2, strlen(name)))
|
if (strnicmp(name, lump_p->fullname, strlen(name)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
@ -981,7 +1000,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
{
|
{
|
||||||
if (!strnicmp(name, lump_p->name2, strlen(name)))
|
if (!strnicmp(name, lump_p->fullname, strlen(name)))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +1025,7 @@ lumpnum_t W_CheckNumForName(const char *name)
|
||||||
// most recent entries first
|
// most recent entries first
|
||||||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||||
{
|
{
|
||||||
if (strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
|
if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
||||||
{
|
{
|
||||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||||
|
@ -1026,7 +1045,7 @@ lumpnum_t W_CheckNumForName(const char *name)
|
||||||
{
|
{
|
||||||
// Update the cache.
|
// Update the cache.
|
||||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
||||||
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
|
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
|
||||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
|
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
|
||||||
|
|
||||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||||
|
@ -1151,7 +1170,7 @@ boolean W_IsLumpWad(lumpnum_t lumpnum)
|
||||||
{
|
{
|
||||||
if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3)
|
if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3)
|
||||||
{
|
{
|
||||||
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->name2;
|
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->fullname;
|
||||||
|
|
||||||
if (strlen(lumpfullName) < 4)
|
if (strlen(lumpfullName) < 4)
|
||||||
return false; // can't possibly be a WAD can it?
|
return false; // can't possibly be a WAD can it?
|
||||||
|
@ -1169,7 +1188,7 @@ boolean W_IsLumpFolder(UINT16 wad, UINT16 lump)
|
||||||
{
|
{
|
||||||
if (wadfiles[wad]->type == RET_PK3)
|
if (wadfiles[wad]->type == RET_PK3)
|
||||||
{
|
{
|
||||||
const char *name = wadfiles[wad]->lumpinfo[lump].name2;
|
const char *name = wadfiles[wad]->lumpinfo[lump].fullname;
|
||||||
|
|
||||||
return (name[strlen(name)-1] == '/'); // folders end in '/'
|
return (name[strlen(name)-1] == '/'); // folders end in '/'
|
||||||
}
|
}
|
||||||
|
@ -1247,7 +1266,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
{
|
{
|
||||||
size_t bytesread = fread(dest, 1, size, handle);
|
size_t bytesread = fread(dest, 1, size, handle);
|
||||||
if (R_IsLumpPNG((UINT8 *)dest, bytesread))
|
if (R_IsLumpPNG((UINT8 *)dest, bytesread))
|
||||||
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
|
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||||
return bytesread;
|
return bytesread;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -1289,7 +1308,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
Z_Free(decData);
|
Z_Free(decData);
|
||||||
#ifdef NO_PNG_LUMPS
|
#ifdef NO_PNG_LUMPS
|
||||||
if (R_IsLumpPNG((UINT8 *)dest, size))
|
if (R_IsLumpPNG((UINT8 *)dest, size))
|
||||||
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
|
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||||
#endif
|
#endif
|
||||||
return size;
|
return size;
|
||||||
#else
|
#else
|
||||||
|
@ -1352,7 +1371,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
|
|
||||||
#ifdef NO_PNG_LUMPS
|
#ifdef NO_PNG_LUMPS
|
||||||
if (R_IsLumpPNG((UINT8 *)dest, size))
|
if (R_IsLumpPNG((UINT8 *)dest, size))
|
||||||
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
|
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||||
#endif
|
#endif
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,9 @@ typedef struct
|
||||||
{
|
{
|
||||||
unsigned long position; // filelump_t filepos
|
unsigned long position; // filelump_t filepos
|
||||||
unsigned long disksize; // filelump_t size
|
unsigned long disksize; // filelump_t size
|
||||||
char name[9]; // filelump_t name[]
|
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
||||||
char *name2; // Used by PK3s. Dynamically allocated name.
|
char *longname; // e.g. "LongEntryName"
|
||||||
|
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
||||||
size_t size; // real (uncompressed) size
|
size_t size; // real (uncompressed) size
|
||||||
compmethod compression; // lump compression method
|
compmethod compression; // lump compression method
|
||||||
} lumpinfo_t;
|
} lumpinfo_t;
|
||||||
|
|
Loading…
Reference in a new issue