Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
Show changes
...@@ -618,7 +618,7 @@ static int sector_get(lua_State *L) ...@@ -618,7 +618,7 @@ static int sector_get(lua_State *L)
return 1; return 1;
case sector_floorpic: // floorpic case sector_floorpic: // floorpic
{ {
levelflat_t *levelflat = &levelflats[sector->floorpic]; levelflat_t *levelflat = &((world_t *)sector->world)->flats[sector->floorpic];
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
if (!levelflat->name[i]) if (!levelflat->name[i])
break; break;
...@@ -627,7 +627,7 @@ static int sector_get(lua_State *L) ...@@ -627,7 +627,7 @@ static int sector_get(lua_State *L)
} }
case sector_ceilingpic: // ceilingpic case sector_ceilingpic: // ceilingpic
{ {
levelflat_t *levelflat = &levelflats[sector->ceilingpic]; levelflat_t *levelflat = &((world_t *)sector->world)->flats[sector->ceilingpic];
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
if (!levelflat->name[i]) if (!levelflat->name[i])
break; break;
...@@ -767,10 +767,10 @@ static int sector_set(lua_State *L) ...@@ -767,10 +767,10 @@ static int sector_set(lua_State *L)
break; break;
} }
case sector_floorpic: case sector_floorpic:
sector->floorpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); sector->floorpic = P_AddLevelFlatForWorld(sector->world, luaL_checkstring(L, 3));
break; break;
case sector_ceilingpic: case sector_ceilingpic:
sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); sector->ceilingpic = P_AddLevelFlatForWorld(sector->world, luaL_checkstring(L, 3));
break; break;
case sector_lightlevel: case sector_lightlevel:
sector->lightlevel = (INT16)luaL_checkinteger(L, 3); sector->lightlevel = (INT16)luaL_checkinteger(L, 3);
...@@ -1959,7 +1959,7 @@ static int ffloor_get(lua_State *L) ...@@ -1959,7 +1959,7 @@ static int ffloor_get(lua_State *L)
lua_pushfixed(L, *ffloor->topheight); lua_pushfixed(L, *ffloor->topheight);
return 1; return 1;
case ffloor_toppic: { // toppic case ffloor_toppic: { // toppic
levelflat_t *levelflat = &levelflats[*ffloor->toppic]; levelflat_t *levelflat = &(*(world_t **)ffloor->world)->flats[*ffloor->toppic];
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
if (!levelflat->name[i]) if (!levelflat->name[i])
break; break;
...@@ -1973,7 +1973,7 @@ static int ffloor_get(lua_State *L) ...@@ -1973,7 +1973,7 @@ static int ffloor_get(lua_State *L)
lua_pushfixed(L, *ffloor->bottomheight); lua_pushfixed(L, *ffloor->bottomheight);
return 1; return 1;
case ffloor_bottompic: { // bottompic case ffloor_bottompic: { // bottompic
levelflat_t *levelflat = &levelflats[*ffloor->bottompic]; levelflat_t *levelflat = &(*(world_t **)ffloor->world)->flats[*ffloor->bottompic];
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
if (!levelflat->name[i]) if (!levelflat->name[i])
break; break;
...@@ -2158,7 +2158,7 @@ static int ffloor_set(lua_State *L) ...@@ -2158,7 +2158,7 @@ static int ffloor_set(lua_State *L)
break; break;
} }
case ffloor_toppic: case ffloor_toppic:
*ffloor->toppic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); *ffloor->toppic = P_AddLevelFlatForWorld(*ffloor->world, luaL_checkstring(L, 3));
break; break;
case ffloor_toplightlevel: case ffloor_toplightlevel:
*ffloor->toplightlevel = (INT16)luaL_checkinteger(L, 3); *ffloor->toplightlevel = (INT16)luaL_checkinteger(L, 3);
...@@ -2179,7 +2179,7 @@ static int ffloor_set(lua_State *L) ...@@ -2179,7 +2179,7 @@ static int ffloor_set(lua_State *L)
break; break;
} }
case ffloor_bottompic: case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); *ffloor->bottompic = P_AddLevelFlatForWorld(*ffloor->world, luaL_checkstring(L, 3));
break; break;
case ffloor_fofflags: { case ffloor_fofflags: {
ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags
...@@ -2854,7 +2854,7 @@ int LUA_MapLib(lua_State *L) ...@@ -2854,7 +2854,7 @@ int LUA_MapLib(lua_State *L)
lib_iterateSectors, lib_iterateSectors,
lib_getSector, lib_getSector,
lib_numsectors, lib_numsectors,
tags_sectors, &tags_sectors,
&numsectors, &sectors, &numsectors, &sectors,
sizeof (sector_t), META_SECTOR); sizeof (sector_t), META_SECTOR);
...@@ -2872,7 +2872,7 @@ int LUA_MapLib(lua_State *L) ...@@ -2872,7 +2872,7 @@ int LUA_MapLib(lua_State *L)
lib_iterateLines, lib_iterateLines,
lib_getLine, lib_getLine,
lib_numlines, lib_numlines,
tags_lines, &tags_lines,
&numlines, &lines, &numlines, &lines,
sizeof (line_t), META_LINE); sizeof (line_t), META_LINE);
......
...@@ -1151,7 +1151,7 @@ int LUA_MobjLib(lua_State *L) ...@@ -1151,7 +1151,7 @@ int LUA_MobjLib(lua_State *L)
lib_iterateMapthings, lib_iterateMapthings,
lib_getMapthing, lib_getMapthing,
lib_nummapthings, lib_nummapthings,
tags_mapthings, &tags_mapthings,
&nummapthings, &mapthings, &nummapthings, &mapthings,
sizeof (mapthing_t), META_MAPTHING); sizeof (mapthing_t), META_MAPTHING);
......
...@@ -368,7 +368,7 @@ static int polyobj_num(lua_State *L) ...@@ -368,7 +368,7 @@ static int polyobj_num(lua_State *L)
polyobj_t *polyobj = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)); polyobj_t *polyobj = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
if (!polyobj) if (!polyobj)
return luaL_error(L, "accessed polyobj_t doesn't exist anymore."); return luaL_error(L, "accessed polyobj_t doesn't exist anymore.");
lua_pushinteger(L, polyobj-PolyObjects); lua_pushinteger(L, polyobj-world->PolyObjects);
return 1; return 1;
} }
...@@ -388,10 +388,10 @@ static int lib_iteratePolyObjects(lua_State *L) ...@@ -388,10 +388,10 @@ static int lib_iteratePolyObjects(lua_State *L)
lua_settop(L, 2); lua_settop(L, 2);
lua_remove(L, 1); // state is unused. lua_remove(L, 1); // state is unused.
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
i = (INT32)(*((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)) - PolyObjects); i = (INT32)(*((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)) - world->PolyObjects);
for (i++; i < numPolyObjects; i++) for (i++; i < world->numPolyObjects; i++)
{ {
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ); LUA_PushUserdata(L, &world->PolyObjects[i], META_POLYOBJ);
return 1; return 1;
} }
return 0; return 0;
...@@ -401,7 +401,7 @@ static int lib_PolyObject_getfornum(lua_State *L) ...@@ -401,7 +401,7 @@ static int lib_PolyObject_getfornum(lua_State *L)
{ {
INT32 id = (INT32)luaL_checkinteger(L, 1); INT32 id = (INT32)luaL_checkinteger(L, 1);
if (!numPolyObjects) if (!world->numPolyObjects)
return 0; // if there's no PolyObjects then bail out here return 0; // if there's no PolyObjects then bail out here
LUA_PushUserdata(L, Polyobj_GetForNum(id), META_POLYOBJ); LUA_PushUserdata(L, Polyobj_GetForNum(id), META_POLYOBJ);
...@@ -417,9 +417,9 @@ static int lib_getPolyObject(lua_State *L) ...@@ -417,9 +417,9 @@ static int lib_getPolyObject(lua_State *L)
if (lua_type(L, 2) == LUA_TNUMBER) if (lua_type(L, 2) == LUA_TNUMBER)
{ {
i = luaL_checkinteger(L, 2); i = luaL_checkinteger(L, 2);
if (i < 0 || i >= numPolyObjects) if (i < 0 || i >= world->numPolyObjects)
return luaL_error(L, "polyobjects[] index %d out of range (0 - %d)", i, numPolyObjects-1); return luaL_error(L, "polyobjects[] index %d out of range (0 - %d)", i, world->numPolyObjects-1);
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ); LUA_PushUserdata(L, &world->PolyObjects[i], META_POLYOBJ);
return 1; return 1;
} }
...@@ -441,7 +441,7 @@ static int lib_getPolyObject(lua_State *L) ...@@ -441,7 +441,7 @@ static int lib_getPolyObject(lua_State *L)
static int lib_numPolyObjects(lua_State *L) static int lib_numPolyObjects(lua_State *L)
{ {
lua_pushinteger(L, numPolyObjects); lua_pushinteger(L, world->numPolyObjects);
return 1; return 1;
} }
......
...@@ -334,13 +334,13 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -334,13 +334,13 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, curWeather); lua_pushinteger(L, curWeather);
return 1; return 1;
} else if (fastcmp(word,"globalweather")) { } else if (fastcmp(word,"globalweather")) {
lua_pushinteger(L, globalweather); lua_pushinteger(L, (localworld ? localworld->weather : PRECIP_NONE));
return 1; return 1;
} else if (fastcmp(word,"levelskynum")) { } else if (fastcmp(word,"levelskynum")) {
lua_pushinteger(L, levelskynum); lua_pushinteger(L, levelskynum);
return 1; return 1;
} else if (fastcmp(word,"globallevelskynum")) { } else if (fastcmp(word,"globallevelskynum")) {
lua_pushinteger(L, globallevelskynum); lua_pushinteger(L, (localworld ? localworld->skynum : 0));
return 1; return 1;
} else if (fastcmp(word,"mapmusname")) { } else if (fastcmp(word,"mapmusname")) {
lua_pushstring(L, mapmusname); lua_pushstring(L, mapmusname);
...@@ -383,7 +383,7 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -383,7 +383,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, emeralds); lua_pushinteger(L, emeralds);
return 1; return 1;
} else if (fastcmp(word,"gravity")) { } else if (fastcmp(word,"gravity")) {
lua_pushinteger(L, gravity); lua_pushinteger(L, world->gravity);
return 1; return 1;
} else if (fastcmp(word,"VERSION")) { } else if (fastcmp(word,"VERSION")) {
lua_pushinteger(L, VERSION); lua_pushinteger(L, VERSION);
...@@ -441,7 +441,7 @@ int LUA_CheckGlobals(lua_State *L, const char *word) ...@@ -441,7 +441,7 @@ int LUA_CheckGlobals(lua_State *L, const char *word)
else if (fastcmp(word, "token")) else if (fastcmp(word, "token"))
token = (UINT32)luaL_checkinteger(L, 2); token = (UINT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "gravity")) else if (fastcmp(word, "gravity"))
gravity = (fixed_t)luaL_checkinteger(L, 2); world->gravity = (fixed_t)luaL_checkinteger(L, 2);
else if (fastcmp(word, "stoppedclock")) else if (fastcmp(word, "stoppedclock"))
stoppedclock = luaL_checkboolean(L, 2); stoppedclock = luaL_checkboolean(L, 2);
else if (fastcmp(word, "displayplayer")) else if (fastcmp(word, "displayplayer"))
...@@ -846,7 +846,7 @@ void LUA_InvalidateUserdata(void *data) ...@@ -846,7 +846,7 @@ void LUA_InvalidateUserdata(void *data)
} }
// Invalidate level data arrays // Invalidate level data arrays
void LUA_InvalidateLevel(void) void LUA_InvalidateLevel(world_t *w)
{ {
thinker_t *th; thinker_t *th;
size_t i; size_t i;
...@@ -854,43 +854,43 @@ void LUA_InvalidateLevel(void) ...@@ -854,43 +854,43 @@ void LUA_InvalidateLevel(void)
if (!gL) if (!gL)
return; return;
for (i = 0; i < NUM_THINKERLISTS; i++) for (i = 0; i < NUM_THINKERLISTS; i++)
for (th = thlist[i].next; th && th != &thlist[i]; th = th->next) for (th = w->thlist[i].next; th && th != &w->thlist[i]; th = th->next)
LUA_InvalidateUserdata(th); LUA_InvalidateUserdata(th);
LUA_InvalidateMapthings(); LUA_InvalidateMapthings(w);
for (i = 0; i < numsubsectors; i++) for (i = 0; i < w->numsubsectors; i++)
LUA_InvalidateUserdata(&subsectors[i]); LUA_InvalidateUserdata(&w->subsectors[i]);
for (i = 0; i < numsectors; i++) for (i = 0; i < w->numsectors; i++)
{ {
LUA_InvalidateUserdata(&sectors[i]); LUA_InvalidateUserdata(&w->sectors[i]);
LUA_InvalidateUserdata(&sectors[i].lines); LUA_InvalidateUserdata(&w->sectors[i].lines);
LUA_InvalidateUserdata(&sectors[i].tags); LUA_InvalidateUserdata(&w->sectors[i].tags);
if (sectors[i].ffloors) if (w->sectors[i].ffloors)
{ {
for (rover = sectors[i].ffloors; rover; rover = rover->next) for (rover = w->sectors[i].ffloors; rover; rover = rover->next)
LUA_InvalidateUserdata(rover); LUA_InvalidateUserdata(rover);
} }
} }
for (i = 0; i < numlines; i++) for (i = 0; i < w->numlines; i++)
{ {
LUA_InvalidateUserdata(&lines[i]); LUA_InvalidateUserdata(&w->lines[i]);
LUA_InvalidateUserdata(&lines[i].tags); LUA_InvalidateUserdata(&w->lines[i].tags);
LUA_InvalidateUserdata(lines[i].args); LUA_InvalidateUserdata(w->lines[i].args);
LUA_InvalidateUserdata(lines[i].stringargs); LUA_InvalidateUserdata(w->lines[i].stringargs);
LUA_InvalidateUserdata(lines[i].sidenum); LUA_InvalidateUserdata(w->lines[i].sidenum);
} }
for (i = 0; i < numsides; i++) for (i = 0; i < w->numsides; i++)
LUA_InvalidateUserdata(&sides[i]); LUA_InvalidateUserdata(&w->sides[i]);
for (i = 0; i < numvertexes; i++) for (i = 0; i < w->numvertexes; i++)
LUA_InvalidateUserdata(&vertexes[i]); LUA_InvalidateUserdata(&w->vertexes[i]);
for (i = 0; i < (size_t)numPolyObjects; i++) for (i = 0; i < (size_t)w->numPolyObjects; i++)
{ {
LUA_InvalidateUserdata(&PolyObjects[i]); LUA_InvalidateUserdata(&w->PolyObjects[i]);
LUA_InvalidateUserdata(&PolyObjects[i].vertices); LUA_InvalidateUserdata(&w->PolyObjects[i].vertices);
LUA_InvalidateUserdata(&PolyObjects[i].lines); LUA_InvalidateUserdata(&w->PolyObjects[i].lines);
} }
for (pslope_t *slope = slopelist; slope; slope = slope->next) for (pslope_t *slope = w->slopelist; slope; slope = slope->next)
{ {
LUA_InvalidateUserdata(slope); LUA_InvalidateUserdata(slope);
LUA_InvalidateUserdata(&slope->normal); LUA_InvalidateUserdata(&slope->normal);
...@@ -898,29 +898,29 @@ void LUA_InvalidateLevel(void) ...@@ -898,29 +898,29 @@ void LUA_InvalidateLevel(void)
LUA_InvalidateUserdata(&slope->d); LUA_InvalidateUserdata(&slope->d);
} }
#ifdef HAVE_LUA_SEGS #ifdef HAVE_LUA_SEGS
for (i = 0; i < numsegs; i++) for (i = 0; i < w->numsegs; i++)
LUA_InvalidateUserdata(&segs[i]); LUA_InvalidateUserdata(&w->segs[i]);
for (i = 0; i < numnodes; i++) for (i = 0; i < w->numnodes; i++)
{ {
LUA_InvalidateUserdata(&nodes[i]); LUA_InvalidateUserdata(&w->nodes[i]);
LUA_InvalidateUserdata(nodes[i].bbox); LUA_InvalidateUserdata(w->nodes[i].bbox);
LUA_InvalidateUserdata(nodes[i].children); LUA_InvalidateUserdata(w->nodes[i].children);
} }
#endif #endif
} }
void LUA_InvalidateMapthings(void) void LUA_InvalidateMapthings(world_t *w)
{ {
size_t i; size_t i;
if (!gL) if (!gL)
return; return;
for (i = 0; i < nummapthings; i++) for (i = 0; i < w->nummapthings; i++)
{ {
LUA_InvalidateUserdata(&mapthings[i]); LUA_InvalidateUserdata(&w->mapthings[i]);
LUA_InvalidateUserdata(&mapthings[i].tags); LUA_InvalidateUserdata(&w->mapthings[i].tags);
LUA_InvalidateUserdata(mapthings[i].args); LUA_InvalidateUserdata(w->mapthings[i].args);
LUA_InvalidateUserdata(mapthings[i].stringargs); LUA_InvalidateUserdata(w->mapthings[i].stringargs);
} }
} }
...@@ -1274,7 +1274,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) ...@@ -1274,7 +1274,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, ARCH_NULL); WRITEUINT8(save_p, ARCH_NULL);
else { else {
WRITEUINT8(save_p, ARCH_POLYOBJ); WRITEUINT8(save_p, ARCH_POLYOBJ);
WRITEUINT16(save_p, polyobj-PolyObjects); WRITEUINT16(save_p, polyobj-archiveworld->PolyObjects);
} }
break; break;
} }
...@@ -1505,40 +1505,40 @@ static UINT8 UnArchiveValue(int TABLESINDEX) ...@@ -1505,40 +1505,40 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
LUA_PushUserdata(gL, &states[READUINT16(save_p)], META_STATE); LUA_PushUserdata(gL, &states[READUINT16(save_p)], META_STATE);
break; break;
case ARCH_MOBJ: case ARCH_MOBJ:
LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(save_p)), META_MOBJ); LUA_PushUserdata(gL, P_FindNewPosition(archiveworld, READUINT32(save_p)), META_MOBJ);
break; break;
case ARCH_PLAYER: case ARCH_PLAYER:
LUA_PushUserdata(gL, &players[READUINT8(save_p)], META_PLAYER); LUA_PushUserdata(gL, &players[READUINT8(save_p)], META_PLAYER);
break; break;
case ARCH_MAPTHING: case ARCH_MAPTHING:
LUA_PushUserdata(gL, &mapthings[READUINT16(save_p)], META_MAPTHING); LUA_PushUserdata(gL, &archiveworld->mapthings[READUINT16(save_p)], META_MAPTHING);
break; break;
case ARCH_VERTEX: case ARCH_VERTEX:
LUA_PushUserdata(gL, &vertexes[READUINT16(save_p)], META_VERTEX); LUA_PushUserdata(gL, &archiveworld->vertexes[READUINT16(save_p)], META_VERTEX);
break; break;
case ARCH_LINE: case ARCH_LINE:
LUA_PushUserdata(gL, &lines[READUINT16(save_p)], META_LINE); LUA_PushUserdata(gL, &archiveworld->lines[READUINT16(save_p)], META_LINE);
break; break;
case ARCH_SIDE: case ARCH_SIDE:
LUA_PushUserdata(gL, &sides[READUINT16(save_p)], META_SIDE); LUA_PushUserdata(gL, &archiveworld->sides[READUINT16(save_p)], META_SIDE);
break; break;
case ARCH_SUBSECTOR: case ARCH_SUBSECTOR:
LUA_PushUserdata(gL, &subsectors[READUINT16(save_p)], META_SUBSECTOR); LUA_PushUserdata(gL, &archiveworld->subsectors[READUINT16(save_p)], META_SUBSECTOR);
break; break;
case ARCH_SECTOR: case ARCH_SECTOR:
LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_SECTOR); LUA_PushUserdata(gL, &archiveworld->sectors[READUINT16(save_p)], META_SECTOR);
break; break;
#ifdef HAVE_LUA_SEGS #ifdef HAVE_LUA_SEGS
case ARCH_SEG: case ARCH_SEG:
LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG); LUA_PushUserdata(gL, &archiveworld->segs[READUINT16(save_p)], META_SEG);
break; break;
case ARCH_NODE: case ARCH_NODE:
LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE); LUA_PushUserdata(gL, &archiveworld->nodes[READUINT16(save_p)], META_NODE);
break; break;
#endif #endif
case ARCH_FFLOOR: case ARCH_FFLOOR:
{ {
sector_t *sector = &sectors[READUINT16(save_p)]; sector_t *sector = &archiveworld->sectors[READUINT16(save_p)];
UINT16 id = READUINT16(save_p); UINT16 id = READUINT16(save_p);
ffloor_t *rover = P_GetFFloorByID(sector, id); ffloor_t *rover = P_GetFFloorByID(sector, id);
if (rover) if (rover)
...@@ -1546,10 +1546,10 @@ static UINT8 UnArchiveValue(int TABLESINDEX) ...@@ -1546,10 +1546,10 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
break; break;
} }
case ARCH_POLYOBJ: case ARCH_POLYOBJ:
LUA_PushUserdata(gL, &PolyObjects[READUINT16(save_p)], META_POLYOBJ); LUA_PushUserdata(gL, &archiveworld->PolyObjects[READUINT16(save_p)], META_POLYOBJ);
break; break;
case ARCH_SLOPE: case ARCH_SLOPE:
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE); LUA_PushUserdata(gL, P_SlopeById(archiveworld->slopelist, READUINT16(save_p)), META_SLOPE);
break; break;
case ARCH_MAPHEADER: case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
...@@ -1768,7 +1768,7 @@ void LUA_PushTaggableObjectArray ...@@ -1768,7 +1768,7 @@ void LUA_PushTaggableObjectArray
lua_CFunction iterator, lua_CFunction iterator,
lua_CFunction indexer, lua_CFunction indexer,
lua_CFunction counter, lua_CFunction counter,
taggroup_t *garray[], taggroup_t **garray[],
size_t * max_elements, size_t * max_elements,
void * element_array, void * element_array,
size_t sizeof_element, size_t sizeof_element,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "doomtype.h" #include "doomtype.h"
#include "d_player.h" #include "d_player.h"
#include "g_state.h" #include "g_state.h"
#include "p_world.h"
#include "taglist.h" #include "taglist.h"
#include "blua/lua.h" #include "blua/lua.h"
...@@ -67,7 +68,7 @@ void LUA_PushTaggableObjectArray ...@@ -67,7 +68,7 @@ void LUA_PushTaggableObjectArray
lua_CFunction iterator, lua_CFunction iterator,
lua_CFunction indexer, lua_CFunction indexer,
lua_CFunction counter, lua_CFunction counter,
taggroup_t *garray[], taggroup_t **garray[],
size_t * max_elements, size_t * max_elements,
void * element_array, void * element_array,
size_t sizeof_element, size_t sizeof_element,
...@@ -75,7 +76,7 @@ void LUA_PushTaggableObjectArray ...@@ -75,7 +76,7 @@ void LUA_PushTaggableObjectArray
void LUA_InsertTaggroupIterator void LUA_InsertTaggroupIterator
( lua_State *L, ( lua_State *L,
taggroup_t *garray[], taggroup_t **garray[],
size_t * max_elements, size_t * max_elements,
void * element_array, void * element_array,
size_t sizeof_element, size_t sizeof_element,
...@@ -92,8 +93,8 @@ lpushed_t LUA_RawPushUserdata(lua_State *L, void *data); ...@@ -92,8 +93,8 @@ lpushed_t LUA_RawPushUserdata(lua_State *L, void *data);
void LUA_InvalidateUserdata(void *data); void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void); void LUA_InvalidateLevel(world_t *w);
void LUA_InvalidateMapthings(void); void LUA_InvalidateMapthings(world_t *w);
void LUA_InvalidatePlayer(player_t *player); void LUA_InvalidatePlayer(player_t *player);
// Console wrapper // Console wrapper
......
...@@ -334,13 +334,13 @@ static const char *const sprites_opt[] = { ...@@ -334,13 +334,13 @@ static const char *const sprites_opt[] = {
// skin.sprites[i] -> sprites[i] // skin.sprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L) static int lib_getSkinSprite(lua_State *L)
{ {
spritedef_t *sprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES); spritedef_t *skinsprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2); playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES*2) if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1); return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushUserdata(L, &sprites[i], META_SKINSPRITESLIST); LUA_PushUserdata(L, &skinsprites[i], META_SKINSPRITESLIST);
return 1; return 1;
} }
......
...@@ -29,7 +29,7 @@ static int tag_iterator(lua_State *L) ...@@ -29,7 +29,7 @@ static int tag_iterator(lua_State *L)
if (++tag >= MAXTAGS) if (++tag >= MAXTAGS)
return 0; return 0;
} }
while (! in_bit_array(tags_available, tag)) ; while (! in_bit_array(world->tags_available, tag)) ;
lua_pushnumber(L, tag); lua_pushnumber(L, tag);
return 1; return 1;
} }
...@@ -46,9 +46,9 @@ enum { ...@@ -46,9 +46,9 @@ enum {
static INT32 next_element(lua_State *L, const mtag_t tag, const size_t p) static INT32 next_element(lua_State *L, const mtag_t tag, const size_t p)
{ {
taggroup_t ** garray = lua_touserdata(L, up_garray); taggroup_t *** garray = lua_touserdata(L, up_garray);
const size_t * max_elements = lua_touserdata(L, up_max_elements); const size_t * max_elements = lua_touserdata(L, up_max_elements);
return Taggroup_Iterate(garray, *max_elements, tag, p); return Taggroup_Iterate(*garray, *max_elements, tag, p);
} }
static void push_element(lua_State *L, void *element) static void push_element(lua_State *L, void *element)
...@@ -95,7 +95,7 @@ static int lib_iterateTags(lua_State *L) ...@@ -95,7 +95,7 @@ static int lib_iterateTags(lua_State *L)
static int lib_numTags(lua_State *L) static int lib_numTags(lua_State *L)
{ {
lua_pushnumber(L, num_tags); lua_pushnumber(L, world->num_tags);
return 1; return 1;
} }
...@@ -150,8 +150,8 @@ static int lib_numTaggroupElements(lua_State *L) ...@@ -150,8 +150,8 @@ static int lib_numTaggroupElements(lua_State *L)
lua_pushnumber(L, *(size_t *)lua_touserdata(L, up_max_elements)); lua_pushnumber(L, *(size_t *)lua_touserdata(L, up_max_elements));
else else
{ {
const taggroup_t ** garray = lua_touserdata(L, up_garray); const taggroup_t *** garray = lua_touserdata(L, up_garray);
lua_pushnumber(L, Taggroup_Count(garray[tag])); lua_pushnumber(L, Taggroup_Count((*garray)[tag]));
} }
return 1; return 1;
} }
...@@ -313,7 +313,7 @@ static int taglist_add(lua_State *L) ...@@ -313,7 +313,7 @@ static int taglist_add(lua_State *L)
if (! Tag_Find(list, tag)) if (! Tag_Find(list, tag))
{ {
Taggroup_Add(tags_sectors, tag, sector_of_taglist(list)); Taggroup_Add(world->tags_sectors, tag, sector_of_taglist(list));
Tag_Add(list, tag); Tag_Add(list, tag);
} }
...@@ -337,7 +337,7 @@ static int taglist_remove(lua_State *L) ...@@ -337,7 +337,7 @@ static int taglist_remove(lua_State *L)
(list->count - 1 - i) * sizeof (mtag_t)); (list->count - 1 - i) * sizeof (mtag_t));
list->tags = Z_Realloc(list->tags, list->tags = Z_Realloc(list->tags,
(--list->count) * sizeof (mtag_t), PU_LEVEL, NULL); (--list->count) * sizeof (mtag_t), PU_LEVEL, NULL);
Taggroup_Remove(tags_sectors, tag, sector_of_taglist(list)); Taggroup_Remove(world->tags_sectors, tag, sector_of_taglist(list));
} }
else/* reset to default tag */ else/* reset to default tag */
Tag_SectorFSet(sector_of_taglist(list), 0); Tag_SectorFSet(sector_of_taglist(list), 0);
...@@ -351,7 +351,7 @@ static int taglist_remove(lua_State *L) ...@@ -351,7 +351,7 @@ static int taglist_remove(lua_State *L)
void LUA_InsertTaggroupIterator void LUA_InsertTaggroupIterator
( lua_State *L, ( lua_State *L,
taggroup_t *garray[], taggroup_t **garray[],
size_t * max_elements, size_t * max_elements,
void * element_array, void * element_array,
size_t sizeof_element, size_t sizeof_element,
......
...@@ -513,13 +513,13 @@ void Command_Teleport_f(void) ...@@ -513,13 +513,13 @@ void Command_Teleport_f(void)
mapthing_t *mt; mapthing_t *mt;
fixed_t offset; fixed_t offset;
if (starpostpath >= numcoopstarts) if (starpostpath >= world->numcoopstarts)
{ {
CONS_Alert(CONS_NOTICE, M_GetText("Player %d spawnpoint not found (%d max).\n"), starpostpath+1, numcoopstarts-1); CONS_Alert(CONS_NOTICE, M_GetText("Player %d spawnpoint not found (%d max).\n"), starpostpath+1, world->numcoopstarts-1);
return; return;
} }
mt = playerstarts[starpostpath]; // Given above check, should never be NULL. mt = world->playerstarts[starpostpath]; // Given above check, should never be NULL.
intx = mt->x<<FRACBITS; intx = mt->x<<FRACBITS;
inty = mt->y<<FRACBITS; inty = mt->y<<FRACBITS;
offset = mt->z<<FRACBITS; offset = mt->z<<FRACBITS;
...@@ -1056,21 +1056,24 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) ...@@ -1056,21 +1056,24 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling) static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling)
{ {
mapthing_t *mt = mapthings; mapthing_t *mt = world->mapthings;
sector_t *sec = player->mo->subsector->sector; sector_t *sec = player->mo->subsector->sector;
LUA_InvalidateMapthings(); LUA_InvalidateMapthings(world);
mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); world->mapthings = Z_Realloc(world->mapthings, ++world->nummapthings * sizeof (*world->mapthings), PU_LEVEL, NULL);
mapthings = world->mapthings;
nummapthings = world->nummapthings;
// as Z_Realloc can relocate mapthings, quickly go through thinker list and correct // as Z_Realloc can relocate mapthings, quickly go through thinker list and correct
// the spawnpoints of any objects that have them to the new location // the spawnpoints of any objects that have them to the new location
if (mt != mapthings) if (mt != world->mapthings)
{ {
thinker_t *th; thinker_t *th;
mobj_t *mo; mobj_t *mo;
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = world->thlist[THINK_MOBJ].next; th != &world->thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue; continue;
...@@ -1079,11 +1082,11 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c ...@@ -1079,11 +1082,11 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
// get offset from mt, which points to old mapthings, then add new location // get offset from mt, which points to old mapthings, then add new location
if (!mo->spawnpoint) if (!mo->spawnpoint)
continue; continue;
mo->spawnpoint = (mo->spawnpoint - mt) + mapthings; mo->spawnpoint = (mo->spawnpoint - mt) + world->mapthings;
} }
} }
mt = (mapthings+nummapthings-1); mt = (world->mapthings+world->nummapthings-1);
mt->type = type; mt->type = type;
mt->x = (INT16)(player->mo->x>>FRACBITS); mt->x = (INT16)(player->mo->x>>FRACBITS);
......
...@@ -4716,10 +4716,10 @@ static void M_DrawPauseMenu(void) ...@@ -4716,10 +4716,10 @@ static void M_DrawPauseMenu(void)
// Draw any and all emblems at the top. // Draw any and all emblems at the top.
M_DrawMapEmblems(gamemap, 272, 28, true); M_DrawMapEmblems(gamemap, 272, 28, true);
if (mapheaderinfo[gamemap-1]->actnum != 0) if (curmapheader->actnum != 0)
V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", curmapheader->lvlttl, curmapheader->actnum));
else else
V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl); V_DrawString(40, 28, V_YELLOWMAP, curmapheader->lvlttl);
// Set up the detail boxes. // Set up the detail boxes.
{ {
......
...@@ -830,11 +830,11 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png ...@@ -830,11 +830,11 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
else else
snprintf(maptext, 8, "Unknown"); snprintf(maptext, 8, "Unknown");
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0') if (gamestate == GS_LEVEL && worldmapheader->lvlttl[0] != '\0')
snprintf(lvlttltext, 48, "%s%s%s", snprintf(lvlttltext, 48, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl, worldmapheader->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone", (worldmapheader->levelflags & LF_NOZONE) ? "" : " Zone",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : ""); (worldmapheader->actnum > 0) ? va(" %d", worldmapheader->actnum) : "");
else else
snprintf(lvlttltext, 48, "Unknown"); snprintf(lvlttltext, 48, "Unknown");
......
...@@ -756,6 +756,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed ...@@ -756,6 +756,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
if (player->quittime) if (player->quittime)
continue; // Ignore uncontrolled bodies continue; // Ignore uncontrolled bodies
if (P_GetPlayerWorld(player) != actor->world)
continue; // Different world
if (dist > 0 if (dist > 0
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
continue; // Too far away continue; // Too far away
...@@ -1661,10 +1664,10 @@ static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixe ...@@ -1661,10 +1664,10 @@ static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixe
actor->momx = FixedMul(FixedDiv(x, dh), speed); actor->momx = FixedMul(FixedDiv(x, dh), speed);
actor->momy = FixedMul(FixedDiv(y, dh), speed); actor->momy = FixedMul(FixedDiv(y, dh), speed);
if (!gravity) if (!world->gravity)
return; return;
dh = FixedDiv(FixedMul(dh, gravity), speed); dh = FixedDiv(FixedMul(dh, world->gravity), speed);
actor->momz = (dh>>1) + FixedDiv(z, dh<<1); actor->momz = (dh>>1) + FixedDiv(z, dh<<1);
} }
...@@ -2728,7 +2731,7 @@ void A_LobShot(mobj_t *actor) ...@@ -2728,7 +2731,7 @@ void A_LobShot(mobj_t *actor)
dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y); dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y);
horizontal = dist / airtime; horizontal = dist / airtime;
vertical = FixedMul((gravity*airtime)/2, shot->scale); vertical = FixedMul((world->gravity*airtime)/2, shot->scale);
shot->momx = FixedMul(horizontal, FINECOSINE(an)); shot->momx = FixedMul(horizontal, FINECOSINE(an));
shot->momy = FixedMul(horizontal, FINESINE(an)); shot->momy = FixedMul(horizontal, FINESINE(an));
...@@ -2750,7 +2753,7 @@ void A_LobShot(mobj_t *actor) ...@@ -2750,7 +2753,7 @@ void A_LobShot(mobj_t *actor)
CONS_Debug(DBG_GAMELOGIC, "orig: %d\n", (orig)>>FRACBITS); CONS_Debug(DBG_GAMELOGIC, "orig: %d\n", (orig)>>FRACBITS);
horizontal = dist / airtime; horizontal = dist / airtime;
vertical = (gravity*airtime)/2; vertical = (world->gravity*airtime)/2;
} }
dist -= orig; dist -= orig;
shot->momx = FixedMul(horizontal, FINECOSINE(an)); shot->momx = FixedMul(horizontal, FINECOSINE(an));
...@@ -3964,26 +3967,26 @@ static void P_DoBossVictory(mobj_t *mo) ...@@ -3964,26 +3967,26 @@ static void P_DoBossVictory(mobj_t *mo)
EV_DoElevator(LE_CAPSULE2, NULL, elevateHighest); EV_DoElevator(LE_CAPSULE2, NULL, elevateHighest);
} }
if (mapheaderinfo[gamemap-1]->muspostbossname[0] && if (worldmapheader->muspostbossname[0] &&
S_MusicExists(mapheaderinfo[gamemap-1]->muspostbossname, !midi_disabled, !digital_disabled)) S_MusicExists(worldmapheader->muspostbossname, !midi_disabled, !digital_disabled))
{ {
// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic. // Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
// So just park ourselves in the mapmus variables. // So just park ourselves in the mapmus variables.
// But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES). // But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES).
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7); boolean changed = strnicmp(worldmapheader->musname, S_MusicName(), 7);
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7)) if (!strnicmp(worldmapheader->musname, mapmusname, 7))
{ {
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7); strncpy(mapmusname, worldmapheader->muspostbossname, 7);
mapmusname[6] = 0; mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET; mapmusflags = (worldmapheader->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos; mapmusposition = worldmapheader->muspostbosspos;
} }
// don't change if we're in another tune // don't change if we're in another tune
// but in case we're in jingle, use our parked mapmus variables so the correct track restores // but in case we're in jingle, use our parked mapmus variables so the correct track restores
if (!changed) if (!changed)
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, (1*MUSICRATE)+(MUSICRATE/2), S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, (1*MUSICRATE)+(MUSICRATE/2),
mapheaderinfo[gamemap-1]->muspostbossfadein); worldmapheader->muspostbossfadein);
} }
} }
} }
...@@ -4409,7 +4412,7 @@ void A_SuperSneakers(mobj_t *actor) ...@@ -4409,7 +4412,7 @@ void A_SuperSneakers(mobj_t *actor)
if (P_IsLocalPlayer(player) && !player->powers[pw_super]) if (P_IsLocalPlayer(player) && !player->powers[pw_super])
{ {
if (S_SpeedMusic(0.0f) && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)) if (S_SpeedMusic(0.0f) && (worldmapheader->levelflags & LF_SPEEDMUSIC))
S_SpeedMusic(1.4f); S_SpeedMusic(1.4f);
else else
P_PlayJingle(player, JT_SHOES); P_PlayJingle(player, JT_SHOES);
...@@ -11588,7 +11591,7 @@ void A_BrakLobShot(mobj_t *actor) ...@@ -11588,7 +11591,7 @@ void A_BrakLobShot(mobj_t *actor)
return; // Don't even bother if we've got nothing to aim at. return; // Don't even bother if we've got nothing to aim at.
// Look up actor's current gravity situation // Look up actor's current gravity situation
g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); g = FixedMul(world->gravity, P_GetSectorGravityFactor(actor->subsector->sector));
// Look up distance between actor and its target // Look up distance between actor and its target
x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y);
...@@ -11703,7 +11706,7 @@ void A_NapalmScatter(mobj_t *actor) ...@@ -11703,7 +11706,7 @@ void A_NapalmScatter(mobj_t *actor)
airtime = 16<<FRACBITS; airtime = 16<<FRACBITS;
// Look up actor's current gravity situation // Look up actor's current gravity situation
g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); g = FixedMul(world->gravity, P_GetSectorGravityFactor(actor->subsector->sector));
// vy = (g*(airtime-1))/2 // vy = (g*(airtime-1))/2
vy = FixedMul(g,(airtime-(1<<FRACBITS)))>>1; vy = FixedMul(g,(airtime-(1<<FRACBITS)))>>1;
...@@ -11758,12 +11761,12 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz ...@@ -11758,12 +11761,12 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
if (!flickytype) if (!flickytype)
{ {
if (!mapheaderinfo[gamemap-1] || !mapheaderinfo[gamemap-1]->numFlickies) // No mapheader, no shoes, no service. if (!worldmapheader || !worldmapheader->numFlickies) // No mapheader, no shoes, no service.
return NULL; return NULL;
else else
{ {
INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numFlickies); INT32 prandom = P_RandomKey(worldmapheader->numFlickies);
flickytype = mapheaderinfo[gamemap-1]->flickies[prandom]; flickytype = worldmapheader->flickies[prandom];
} }
} }
...@@ -12413,7 +12416,7 @@ void A_Boss5Jump(mobj_t *actor) ...@@ -12413,7 +12416,7 @@ void A_Boss5Jump(mobj_t *actor)
return; // Don't even bother if we've got nothing to aim at. return; // Don't even bother if we've got nothing to aim at.
// Look up actor's current gravity situation // Look up actor's current gravity situation
g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); g = FixedMul(world->gravity, P_GetSectorGravityFactor(actor->subsector->sector));
// Look up distance between actor and its tracer // Look up distance between actor and its tracer
x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y);
...@@ -12516,10 +12519,10 @@ void A_MineExplode(mobj_t *actor) ...@@ -12516,10 +12519,10 @@ void A_MineExplode(mobj_t *actor)
A_Scream(actor); A_Scream(actor);
actor->flags = MF_NOGRAVITY|MF_NOCLIP; actor->flags = MF_NOGRAVITY|MF_NOCLIP;
quake.epicenter = NULL; world->quake.epicenter = NULL;
quake.radius = 512*FRACUNIT; world->quake.radius = 512*FRACUNIT;
quake.intensity = 8*FRACUNIT; world->quake.intensity = 8*FRACUNIT;
quake.time = TICRATE/3; world->quake.time = TICRATE/3;
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF, true); P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF, true);
P_MobjCheckWater(actor); P_MobjCheckWater(actor);
...@@ -12937,7 +12940,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) ...@@ -12937,7 +12940,7 @@ void A_Boss5FindWaypoint(mobj_t *actor)
} }
// allocate the table and reset count to zero // allocate the table and reset count to zero
fangwaypoints = Z_Calloc(sizeof(*waypoints)*numfangwaypoints, PU_STATIC, NULL); fangwaypoints = Z_Calloc(sizeof(*world->waypoints)*numfangwaypoints, PU_STATIC, NULL);
numfangwaypoints = 0; numfangwaypoints = 0;
// now find them again and add them to the table! // now find them again and add them to the table!
...@@ -13502,14 +13505,14 @@ void A_Boss5BombExplode(mobj_t *actor) ...@@ -13502,14 +13505,14 @@ void A_Boss5BombExplode(mobj_t *actor)
P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale); P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale);
//P_StartQuake(9*actor->scale, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius); //P_StartQuake(9*actor->scale, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius);
// the above does not exist, so we set the quake values directly instead // the above does not exist, so we set the quake values directly instead
quake.intensity = 9*actor->scale; world->quake.intensity = 9*actor->scale;
quake.time = TICRATE/6; world->quake.time = TICRATE/6;
// the following quake values have no effect atm? ah well, may as well set them anyway // the following quake values have no effect atm? ah well, may as well set them anyway
{ {
mappoint_t q_epicenter = {actor->x, actor->y, actor->z}; mappoint_t q_epicenter = {actor->x, actor->y, actor->z};
quake.epicenter = &q_epicenter; world->quake.epicenter = &q_epicenter;
} }
quake.radius = 20*actor->radius; world->quake.radius = 20*actor->radius;
} }
static mobj_t *dustdevil; static mobj_t *dustdevil;
...@@ -13782,10 +13785,10 @@ void A_TNTExplode(mobj_t *actor) ...@@ -13782,10 +13785,10 @@ void A_TNTExplode(mobj_t *actor)
epicenter.x = actor->x; epicenter.x = actor->x;
epicenter.y = actor->y; epicenter.y = actor->y;
epicenter.z = actor->z; epicenter.z = actor->z;
quake.intensity = 9*FRACUNIT; world->quake.intensity = 9*FRACUNIT;
quake.time = TICRATE/6; world->quake.time = TICRATE/6;
quake.epicenter = &epicenter; world->quake.epicenter = &epicenter;
quake.radius = 512*FRACUNIT; world->quake.radius = 512*FRACUNIT;
if (locvar1) if (locvar1)
{ {
......
...@@ -525,7 +525,7 @@ void T_ContinuousFalling(continuousfall_t *faller) ...@@ -525,7 +525,7 @@ void T_ContinuousFalling(continuousfall_t *faller)
faller->sector->ceilingheight = faller->ceilingstartheight; faller->sector->ceilingheight = faller->ceilingstartheight;
faller->sector->floorheight = faller->floorstartheight; faller->sector->floorheight = faller->floorstartheight;
R_ClearLevelInterpolatorState(&faller->thinker); R_ClearLevelInterpolatorState(world, &faller->thinker);
} }
P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong
...@@ -689,7 +689,7 @@ void T_BounceCheese(bouncecheese_t *bouncer) ...@@ -689,7 +689,7 @@ void T_BounceCheese(bouncecheese_t *bouncer)
} }
else if (bouncer->sector->ceilingheight > bouncer->ceilingwasheight) // Up else if (bouncer->sector->ceilingheight > bouncer->ceilingwasheight) // Up
{ {
bouncer->speed += gravity; bouncer->speed += world->gravity;
} }
if (abs(bouncer->speed) < 2*FRACUNIT if (abs(bouncer->speed) < 2*FRACUNIT
...@@ -838,7 +838,7 @@ void T_StartCrumble(crumble_t *crumble) ...@@ -838,7 +838,7 @@ void T_StartCrumble(crumble_t *crumble)
// Only fall like this if it isn't meant to float on water // Only fall like this if it isn't meant to float on water
if (!(crumble->flags & CF_FLOATBOB)) if (!(crumble->flags & CF_FLOATBOB))
{ {
crumble->speed += gravity; // Gain more and more speed crumble->speed += world->gravity; // Gain more and more speed
if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT) if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT)
|| ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT)) || ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT))
......
...@@ -725,18 +725,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -725,18 +725,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
break; break;
// Emerald Hunt // Emerald Hunt
case MT_EMERHUNT: case MT_EMERHUNT: {
unsigned remaining_emeralds = 0;
if (player->bot && player->bot != BOT_MPAI) if (player->bot && player->bot != BOT_MPAI)
return; return;
if (hunt1 == special) for (i = 0; i < NUM_EMERALD_HUNT_LOCATIONS; i++)
hunt1 = NULL; {
else if (hunt2 == special) if (world->emerald_hunt_locations[i])
hunt2 = NULL; {
else if (hunt3 == special) if (world->emerald_hunt_locations[i] == special)
hunt3 = NULL; P_SetTarget(&world->emerald_hunt_locations[i], NULL);
else
remaining_emeralds++;
}
}
if (!hunt1 && !hunt2 && !hunt3) if (!remaining_emeralds)
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
...@@ -748,7 +754,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -748,7 +754,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
//S_StartSound(NULL, sfx_lvpass); //S_StartSound(NULL, sfx_lvpass);
} }
break; break;
}
// Collectible emeralds // Collectible emeralds
case MT_EMERALD1: case MT_EMERALD1:
case MT_EMERALD2: case MT_EMERALD2:
...@@ -1678,9 +1684,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ...@@ -1678,9 +1684,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetObjectMomZ(toucher, FixedDiv(69*FRACUNIT,10*FRACUNIT), false); P_SetObjectMomZ(toucher, FixedDiv(69*FRACUNIT,10*FRACUNIT), false);
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
{ {
quake.intensity = 9*FRACUNIT; world->quake.intensity = 9*FRACUNIT;
quake.time = TICRATE/2; world->quake.time = TICRATE/2;
quake.epicenter = NULL; world->quake.epicenter = NULL;
} }
#if 0 // camera redirection - deemed unnecessary #if 0 // camera redirection - deemed unnecessary
...@@ -3149,7 +3155,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source) ...@@ -3149,7 +3155,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
if (oldnightstime > 10*TICRATE if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE) && player->nightstime < 10*TICRATE)
{ {
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) if ((worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
#ifdef _WIN32 #ifdef _WIN32
// win32 MIDI volume hack means we cannot fade down the music // win32 MIDI volume hack means we cannot fade down the music
&& S_MusicType() != MU_MID && S_MusicType() != MU_MID
...@@ -3605,7 +3611,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) ...@@ -3605,7 +3611,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
if (oldnightstime > 10*TICRATE if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE) && player->nightstime < 10*TICRATE)
{ {
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) if (worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
{ {
S_FadeMusic(0, 10*MUSICRATE); S_FadeMusic(0, 10*MUSICRATE);
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "p_tick.h" #include "p_tick.h"
#include "r_defs.h" #include "r_defs.h"
#include "p_maputl.h" #include "p_maputl.h"
#include "p_setup.h"
#include "p_world.h"
#define FLOATSPEED (FRACUNIT*4) #define FLOATSPEED (FRACUNIT*4)
...@@ -70,11 +72,13 @@ typedef enum ...@@ -70,11 +72,13 @@ typedef enum
THINK_PRECIP, THINK_PRECIP,
NUM_THINKERLISTS NUM_THINKERLISTS
} thinklistnum_t; /**< Thinker lists. */ } thinklistnum_t; /**< Thinker lists. */
extern thinker_t thlist[];
void P_InitThinkers(void); extern thinker_t *thlist; // the current thinker list
void P_InitThinkers(world_t *w);
void P_AddThinker(const thinklistnum_t n, thinker_t *thinker); void P_AddThinker(const thinklistnum_t n, thinker_t *thinker);
void P_RemoveThinker(thinker_t *thinker); void P_RemoveThinker(thinker_t *thinker);
void P_MoveThinkerToWorld(world_t *w, const thinklistnum_t n, thinker_t *thinker);
// //
// P_USER // P_USER
...@@ -205,8 +209,8 @@ boolean P_SuperReady(player_t *player); ...@@ -205,8 +209,8 @@ boolean P_SuperReady(player_t *player);
void P_DoJump(player_t *player, boolean soundandstate); void P_DoJump(player_t *player, boolean soundandstate);
#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG)
boolean P_TransferToNextMare(player_t *player); boolean P_TransferToNextMare(player_t *player);
UINT8 P_FindLowestMare(void); UINT8 P_FindLowestMare(world_t *w);
void P_FindEmerald(void); void P_FindEmerald(world_t *w);
void P_TransferToAxis(player_t *player, INT32 axisnum); void P_TransferToAxis(player_t *player, INT32 axisnum);
boolean P_PlayerMoving(INT32 pnum); boolean P_PlayerMoving(INT32 pnum);
void P_SpawnThokMobj(player_t *player); void P_SpawnThokMobj(player_t *player);
...@@ -269,31 +273,24 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b ...@@ -269,31 +273,24 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b
#define ONFLOORZ INT32_MIN #define ONFLOORZ INT32_MIN
#define ONCEILINGZ INT32_MAX #define ONCEILINGZ INT32_MAX
// Time interval for item respawning.
// WARNING MUST be a power of 2
#define ITEMQUESIZE 1024
extern mapthing_t *itemrespawnque[ITEMQUESIZE];
extern tic_t itemrespawntime[ITEMQUESIZE];
extern size_t iquehead, iquetail;
extern consvar_t cv_gravity, cv_movebob; extern consvar_t cv_gravity, cv_movebob;
mobjtype_t P_GetMobjtype(UINT16 mthingtype); mobjtype_t P_GetMobjtype(UINT16 mthingtype);
void P_RespawnSpecials(void); void P_RespawnSpecials(world_t *w);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
void P_RecalcPrecipInSector(sector_t *sector); void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void); void P_PrecipitationEffects(world_t *w);
void P_RemoveMobj(mobj_t *th); void P_RemoveMobj(mobj_t *th);
boolean P_MobjWasRemoved(mobj_t *th); boolean P_MobjWasRemoved(mobj_t *th);
void P_RemoveSavegameMobj(mobj_t *th); void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void); void P_RunShields(world_t *w);
void P_RunOverlays(void); void P_RunOverlays(world_t *w);
void P_HandleMinecartSegments(mobj_t *mobj); void P_HandleMinecartSegments(mobj_t *mobj);
void P_MobjThinker(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj);
boolean P_RailThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj);
...@@ -305,17 +302,17 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t ...@@ -305,17 +302,17 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false) #define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false) #define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false)
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) #define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, P_GetMobjWorld(mobj)->sectors + fof->secnum, sector, x, y, line, false, false)
#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) #define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, P_GetMobjWorld(mobj)->sectors + fof->secnum, sector, x, y, line, true, false)
#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true) #define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true)
#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true) #define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true)
fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); fixed_t P_CameraFloorZ(camera_t *cam, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); fixed_t P_CameraCeilingZ(camera_t *cam, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false) #define P_CameraGetFloorZ(cam, sector, x, y, line) P_CameraFloorZ(cam, sector, NULL, x, y, line, false, false)
#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false) #define P_CameraGetCeilingZ(cam, sector, x, y, line) P_CameraCeilingZ(cam, sector, NULL, x, y, line, true, false)
#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) #define P_CameraGetFOFTopZ(cam, sector, fof, x, y, line) P_CameraCeilingZ(cam, P_GetCameraWorld(cam)->sectors + fof->secnum, sector, x, y, line, false, false)
#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) #define P_CameraGetFOFBottomZ(cam, sector, fof, x, y, line) P_CameraFloorZ(cam, P_GetCameraWorld(cam)->sectors + fof->secnum, sector, x, y, line, true, false)
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckDeathPitCollide(mobj_t *mo);
...@@ -339,6 +336,8 @@ FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type); ...@@ -339,6 +336,8 @@ FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
void P_CalcChasePostImg(player_t *player, camera_t *thiscam); void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled);
world_t *P_GetCameraWorld(camera_t *cam);
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab); void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
mobj_t *P_GetClosestAxis(mobj_t *source); mobj_t *P_GetClosestAxis(mobj_t *source);
......
...@@ -3388,7 +3388,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) ...@@ -3388,7 +3388,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
floorclimb = true; floorclimb = true;
if ((floorz > mo->z) if ((floorz > mo->z)
&& glidesector->floorpic == skyflatnum) && glidesector->floorpic == world->skyflatnum)
return false; return false;
if ((mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale) > ceilingz) if ((mo->z + mo->height - FixedMul(16*FRACUNIT,mo->scale) > ceilingz)
...@@ -3402,7 +3402,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) ...@@ -3402,7 +3402,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
floorclimb = true; floorclimb = true;
if ((ceilingz < mo->z+mo->height) if ((ceilingz < mo->z+mo->height)
&& glidesector->ceilingpic == skyflatnum) && glidesector->ceilingpic == world->skyflatnum)
return false; return false;
if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz) if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "hu_stuff.h" #include "hu_stuff.h"
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" #include "p_setup.h"
#include "p_world.h"
#include "r_fps.h" #include "r_fps.h"
#include "r_main.h" #include "r_main.h"
#include "r_skins.h" #include "r_skins.h"
...@@ -40,43 +41,6 @@ ...@@ -40,43 +41,6 @@
static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL);
actioncache_t actioncachehead;
static mobj_t *overlaycap = NULL;
void P_InitCachedActions(void)
{
actioncachehead.prev = actioncachehead.next = &actioncachehead;
}
void P_RunCachedActions(void)
{
actioncache_t *ac;
actioncache_t *next;
for (ac = actioncachehead.next; ac != &actioncachehead; ac = next)
{
var1 = states[ac->statenum].var1;
var2 = states[ac->statenum].var2;
astate = &states[ac->statenum];
if (ac->mobj && !P_MobjWasRemoved(ac->mobj)) // just in case...
states[ac->statenum].action.acp1(ac->mobj);
next = ac->next;
Z_Free(ac);
}
}
void P_AddCachedAction(mobj_t *mobj, INT32 statenum)
{
actioncache_t *newaction = Z_Calloc(sizeof(actioncache_t), PU_LEVEL, NULL);
newaction->mobj = mobj;
newaction->statenum = statenum;
actioncachehead.prev->next = newaction;
newaction->next = &actioncachehead;
newaction->prev = actioncachehead.prev;
actioncachehead.prev = newaction;
}
// //
// P_SetupStateAnimation // P_SetupStateAnimation
// //
...@@ -1387,6 +1351,14 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f ...@@ -1387,6 +1351,14 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
} else // Well, that makes it easy. Just get the ceiling height } else // Well, that makes it easy. Just get the ceiling height
return sector->ceilingheight; return sector->ceilingheight;
} }
world_t *P_GetCameraWorld(camera_t *cam)
{
if (cam->subsector == NULL)
return NULL;
return (world_t *)cam->subsector->sector->world;
}
static void P_PlayerFlip(mobj_t *mo) static void P_PlayerFlip(mobj_t *mo)
{ {
if (!mo->player) if (!mo->player)
...@@ -1465,7 +1437,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) ...@@ -1465,7 +1437,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
if (!gravsector) // If there is no 3D floor gravity, check sector's gravity if (!gravsector) // If there is no 3D floor gravity, check sector's gravity
gravsector = mo->subsector->sector; gravsector = mo->subsector->sector;
gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(gravsector)); gravityadd = -FixedMul(world->gravity, P_GetSectorGravityFactor(gravsector));
if ((gravsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) if ((gravsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0)
{ {
...@@ -1756,9 +1728,9 @@ bustupdone: ...@@ -1756,9 +1728,9 @@ bustupdone:
static boolean P_CheckSkyHit(mobj_t *mo) static boolean P_CheckSkyHit(mobj_t *mo)
{ {
if (ceilingline && ceilingline->backsector if (ceilingline && ceilingline->backsector
&& ceilingline->backsector->ceilingpic == skyflatnum && ceilingline->backsector->ceilingpic == world->skyflatnum
&& ceilingline->frontsector && ceilingline->frontsector
&& ceilingline->frontsector->ceilingpic == skyflatnum && ceilingline->frontsector->ceilingpic == world->skyflatnum
&& (mo->z >= ceilingline->frontsector->ceilingheight && (mo->z >= ceilingline->frontsector->ceilingheight
|| mo->z >= ceilingline->backsector->ceilingheight)) || mo->z >= ceilingline->backsector->ceilingheight))
return true; return true;
...@@ -2599,11 +2571,11 @@ boolean P_ZMovement(mobj_t *mo) ...@@ -2599,11 +2571,11 @@ boolean P_ZMovement(mobj_t *mo)
{ {
// Don't explode on the sky! // Don't explode on the sky!
if (!(mo->eflags & MFE_VERTICALFLIP) if (!(mo->eflags & MFE_VERTICALFLIP)
&& mo->subsector->sector->floorpic == skyflatnum && mo->subsector->sector->floorpic == world->skyflatnum
&& mo->subsector->sector->floorheight == mo->floorz) && mo->subsector->sector->floorheight == mo->floorz)
P_RemoveMobj(mo); P_RemoveMobj(mo);
else if (mo->eflags & MFE_VERTICALFLIP else if (mo->eflags & MFE_VERTICALFLIP
&& mo->subsector->sector->ceilingpic == skyflatnum && mo->subsector->sector->ceilingpic == world->skyflatnum
&& mo->subsector->sector->ceilingheight == mo->ceilingz) && mo->subsector->sector->ceilingheight == mo->ceilingz)
P_RemoveMobj(mo); P_RemoveMobj(mo);
else else
...@@ -2747,11 +2719,11 @@ boolean P_ZMovement(mobj_t *mo) ...@@ -2747,11 +2719,11 @@ boolean P_ZMovement(mobj_t *mo)
{ {
// Don't explode on the sky! // Don't explode on the sky!
if (!(mo->eflags & MFE_VERTICALFLIP) if (!(mo->eflags & MFE_VERTICALFLIP)
&& mo->subsector->sector->ceilingpic == skyflatnum && mo->subsector->sector->ceilingpic == world->skyflatnum
&& mo->subsector->sector->ceilingheight == mo->ceilingz) && mo->subsector->sector->ceilingheight == mo->ceilingz)
P_RemoveMobj(mo); P_RemoveMobj(mo);
else if (mo->eflags & MFE_VERTICALFLIP else if (mo->eflags & MFE_VERTICALFLIP
&& mo->subsector->sector->floorpic == skyflatnum && mo->subsector->sector->floorpic == world->skyflatnum
&& mo->subsector->sector->floorheight == mo->floorz) && mo->subsector->sector->floorheight == mo->floorz)
P_RemoveMobj(mo); P_RemoveMobj(mo);
else else
...@@ -3240,8 +3212,8 @@ void P_MobjCheckWater(mobj_t *mobj) ...@@ -3240,8 +3212,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|| ((rover->fofflags & FOF_BLOCKOTHERS) && !mobj->player))) || ((rover->fofflags & FOF_BLOCKOTHERS) && !mobj->player)))
continue; continue;
topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, sector); topheight = P_GetSpecialTopZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, sector);
bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, sector); bottomheight = P_GetSpecialBottomZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, sector);
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
...@@ -3656,6 +3628,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled ...@@ -3656,6 +3628,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
{ // Never fails for 2D mode. { // Never fails for 2D mode.
mobj_t dummy; mobj_t dummy;
dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker; dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker;
dummy.world = thiscam->subsector->sector->world;
dummy.subsector = thiscam->subsector; dummy.subsector = thiscam->subsector;
dummy.x = thiscam->x; dummy.x = thiscam->x;
dummy.y = thiscam->y; dummy.y = thiscam->y;
...@@ -3761,12 +3734,12 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj) ...@@ -3761,12 +3734,12 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj)
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
if (P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z + mobj->height) if (P_GetSpecialBottomZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, node->m_sector) != mobj->z + mobj->height)
continue; continue;
} }
else else
{ {
if (P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z) if (P_GetSpecialTopZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, node->m_sector) != mobj->z)
continue; continue;
} }
...@@ -4192,6 +4165,9 @@ boolean P_SupermanLook4Players(mobj_t *actor) ...@@ -4192,6 +4165,9 @@ boolean P_SupermanLook4Players(mobj_t *actor)
if (players[c].mo->health <= 0) if (players[c].mo->health <= 0)
continue; // dead continue; // dead
if (players[c].world != actor->world)
continue; // Different world
playersinthegame[stop] = &players[c]; playersinthegame[stop] = &players[c];
stop++; stop++;
} }
...@@ -5352,7 +5328,7 @@ static void P_Boss7Thinker(mobj_t *mobj) ...@@ -5352,7 +5328,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y); dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y);
horizontal = dist / airtime; horizontal = dist / airtime;
vertical = (gravity*airtime)/2; vertical = (world->gravity*airtime)/2;
mobj->momx = FixedMul(horizontal, FINECOSINE(an)); mobj->momx = FixedMul(horizontal, FINECOSINE(an));
mobj->momy = FixedMul(horizontal, FINESINE(an)); mobj->momy = FixedMul(horizontal, FINESINE(an));
...@@ -5480,7 +5456,7 @@ static void P_Boss9Thinker(mobj_t *mobj) ...@@ -5480,7 +5456,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
{ {
P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT); P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT);
P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true); P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true);
mobj->momz -= gravity; mobj->momz -= world->gravity;
if (mobj->z < mobj->watertop || mobj->z < (mobj->floorz + 16*FRACUNIT)) if (mobj->z < mobj->watertop || mobj->z < (mobj->floorz + 16*FRACUNIT))
{ {
mobj->watertop = mobj->floorz + 32*FRACUNIT; mobj->watertop = mobj->floorz + 32*FRACUNIT;
...@@ -6756,21 +6732,16 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) ...@@ -6756,21 +6732,16 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
return true; return true;
} }
mobj_t *shields[MAXPLAYERS*2]; void P_RunShields(world_t *w)
INT32 numshields = 0;
void P_RunShields(void)
{ {
INT32 i; for (INT32 i = 0; i < w->numshields; i++)
// run shields
for (i = 0; i < numshields; i++)
{ {
if (!P_MobjWasRemoved(shields[i])) if (!P_MobjWasRemoved(w->shields[i]))
P_ShieldLook(shields[i], shields[i]->threshold); P_ShieldLook(w->shields[i], w->shields[i]->threshold);
P_SetTarget(&shields[i], NULL); P_SetTarget(&w->shields[i], NULL);
} }
numshields = 0;
w->numshields = 0;
} }
static boolean P_AddShield(mobj_t *thing) static boolean P_AddShield(mobj_t *thing)
...@@ -6800,20 +6771,20 @@ static boolean P_AddShield(mobj_t *thing) ...@@ -6800,20 +6771,20 @@ static boolean P_AddShield(mobj_t *thing)
} }
// Queue has been hit... why?!? // Queue has been hit... why?!?
if (numshields >= MAXPLAYERS*2) if (world->numshields >= MAXPLAYERS*2)
return P_ShieldLook(thing, thing->info->speed); return P_ShieldLook(thing, thing->info->speed);
P_SetTarget(&shields[numshields++], thing); P_SetTarget(&world->shields[world->numshields++], thing);
return true; return true;
} }
void P_RunOverlays(void) void P_RunOverlays(world_t *w)
{ {
// run overlays // run overlays
mobj_t *mo, *next = NULL; mobj_t *mo, *next = NULL;
fixed_t destx,desty,zoffs; fixed_t destx,desty,zoffs;
for (mo = overlaycap; mo; mo = next) for (mo = w->overlaycap; mo; mo = next)
{ {
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
...@@ -6878,7 +6849,7 @@ void P_RunOverlays(void) ...@@ -6878,7 +6849,7 @@ void P_RunOverlays(void)
P_SetThingPosition(mo); P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y); P_CheckPosition(mo, mo->x, mo->y);
} }
P_SetTarget(&overlaycap, NULL); P_SetTarget(&w->overlaycap, NULL);
} }
// Called only when MT_OVERLAY thinks. // Called only when MT_OVERLAY thinks.
...@@ -6886,11 +6857,11 @@ static void P_AddOverlay(mobj_t *thing) ...@@ -6886,11 +6857,11 @@ static void P_AddOverlay(mobj_t *thing)
{ {
I_Assert(thing != NULL); I_Assert(thing != NULL);
if (overlaycap == NULL) if (world->overlaycap == NULL)
P_SetTarget(&overlaycap, thing); P_SetTarget(&world->overlaycap, thing);
else { else {
mobj_t *mo; mobj_t *mo;
for (mo = overlaycap; mo && mo->hnext; mo = mo->hnext) for (mo = world->overlaycap; mo && mo->hnext; mo = mo->hnext)
; ;
I_Assert(mo != NULL); I_Assert(mo != NULL);
...@@ -6906,14 +6877,14 @@ static void P_AddOverlay(mobj_t *thing) ...@@ -6906,14 +6877,14 @@ static void P_AddOverlay(mobj_t *thing)
static void P_RemoveOverlay(mobj_t *thing) static void P_RemoveOverlay(mobj_t *thing)
{ {
mobj_t *mo; mobj_t *mo;
if (overlaycap == thing) if (world->overlaycap == thing)
{ {
P_SetTarget(&overlaycap, thing->hnext); P_SetTarget(&world->overlaycap, thing->hnext);
P_SetTarget(&thing->hnext, NULL); P_SetTarget(&thing->hnext, NULL);
return; return;
} }
for (mo = overlaycap; mo; mo = mo->hnext) for (mo = world->overlaycap; mo; mo = mo->hnext)
{ {
if (mo->hnext != thing) if (mo->hnext != thing)
continue; continue;
...@@ -8451,7 +8422,7 @@ static boolean P_HangsterThink(mobj_t *mobj) ...@@ -8451,7 +8422,7 @@ static boolean P_HangsterThink(mobj_t *mobj)
//should you roost on a ceiling with F_SKY1 as its flat, disappear forever //should you roost on a ceiling with F_SKY1 as its flat, disappear forever
if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height) if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height)
&& mobj->subsector->sector->ceilingpic == skyflatnum && mobj->subsector->sector->ceilingpic == world->skyflatnum
&& mobj->subsector->sector->ceilingheight == mobj->ceilingz) && mobj->subsector->sector->ceilingheight == mobj->ceilingz)
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
...@@ -10158,13 +10129,13 @@ void P_MobjThinker(mobj_t *mobj) ...@@ -10158,13 +10129,13 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
// Remove dead target/tracer. // Remove dead target/tracer.
if (mobj->target && P_MobjWasRemoved(mobj->target)) if (!P_MobjIsConnected(mobj, mobj->target))
P_SetTarget(&mobj->target, NULL); P_SetTarget(&mobj->target, NULL);
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) if (!P_MobjIsConnected(mobj, mobj->tracer))
P_SetTarget(&mobj->tracer, NULL); P_SetTarget(&mobj->tracer, NULL);
if (mobj->hnext && P_MobjWasRemoved(mobj->hnext)) if (!P_MobjIsConnected(mobj, mobj->hnext))
P_SetTarget(&mobj->hnext, NULL); P_SetTarget(&mobj->hnext, NULL);
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) if (!P_MobjIsConnected(mobj, mobj->hprev))
P_SetTarget(&mobj->hprev, NULL); P_SetTarget(&mobj->hprev, NULL);
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG); mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
...@@ -10621,6 +10592,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) ...@@ -10621,6 +10592,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->x = x; mobj->x = x;
mobj->y = y; mobj->y = y;
mobj->world = world;
mobj->radius = info->radius; mobj->radius = info->radius;
mobj->height = info->height; mobj->height = info->height;
mobj->flags = info->flags; mobj->flags = info->flags;
...@@ -10970,13 +10943,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) ...@@ -10970,13 +10943,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// Call action functions when the state is set // Call action functions when the state is set
if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC)) if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC))
{ {
if (levelloading) if (world->loading)
{ {
// Cache actions in a linked list // Cache actions in a linked list
// with function pointer, and // with function pointer, and
// var1 & var2, which will be executed // var1 & var2, which will be executed
// when the level finishes loading. // when the level finishes loading.
P_AddCachedAction(mobj, mobj->info->spawnstate); P_AddCachedAction(world, mobj, mobj->info->spawnstate);
} }
else else
{ {
...@@ -11008,6 +10981,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype ...@@ -11008,6 +10981,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->x = x; mobj->x = x;
mobj->y = y; mobj->y = y;
mobj->flags = mobjinfo[type].flags; mobj->flags = mobjinfo[type].flags;
mobj->world = world;
// do not set the state with P_SetMobjState, // do not set the state with P_SetMobjState,
// because action routines can not be called yet // because action routines can not be called yet
...@@ -11040,7 +11014,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype ...@@ -11040,7 +11014,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->precipflags |= PCF_FOF; mobj->precipflags |= PCF_FOF;
else if (mobj->subsector->sector->damagetype == SD_DEATHPITNOTILT else if (mobj->subsector->sector->damagetype == SD_DEATHPITNOTILT
|| mobj->subsector->sector->damagetype == SD_DEATHPITTILT || mobj->subsector->sector->damagetype == SD_DEATHPITTILT
|| mobj->subsector->sector->floorpic == skyflatnum) || mobj->subsector->sector->floorpic == world->skyflatnum)
mobj->precipflags |= PCF_PIT; mobj->precipflags |= PCF_PIT;
R_ResetPrecipitationMobjInterpolationState(mobj); R_ResetPrecipitationMobjInterpolationState(mobj);
...@@ -11082,9 +11056,6 @@ void P_RemoveFloorSpriteSlope(mobj_t *mobj) ...@@ -11082,9 +11056,6 @@ void P_RemoveFloorSpriteSlope(mobj_t *mobj)
// //
// P_RemoveMobj // P_RemoveMobj
// //
mapthing_t *itemrespawnque[ITEMQUESIZE];
tic_t itemrespawntime[ITEMQUESIZE];
size_t iquehead, iquetail;
#ifdef PARANOIA #ifdef PARANOIA
#define SCRAMBLE_REMOVED // Force debug build to crash when Removed mobj is accessed #define SCRAMBLE_REMOVED // Force debug build to crash when Removed mobj is accessed
...@@ -11109,12 +11080,12 @@ void P_RemoveMobj(mobj_t *mobj) ...@@ -11109,12 +11080,12 @@ void P_RemoveMobj(mobj_t *mobj)
|| P_WeaponOrPanel(mobj->type)) || P_WeaponOrPanel(mobj->type))
&& !(mobj->flags2 & MF2_DONTRESPAWN)) && !(mobj->flags2 & MF2_DONTRESPAWN))
{ {
itemrespawnque[iquehead] = mobj->spawnpoint; world->itemrespawnque[world->iquehead] = mobj->spawnpoint;
itemrespawntime[iquehead] = leveltime; world->itemrespawntime[world->iquehead] = leveltime;
iquehead = (iquehead+1)&(ITEMQUESIZE-1); world->iquehead = (world->iquehead+1)&(ITEMQUESIZE-1);
// lose one off the end? // lose one off the end?
if (iquehead == iquetail) if (world->iquehead == world->iquetail)
iquetail = (iquetail+1)&(ITEMQUESIZE-1); world->iquetail = (world->iquetail+1)&(ITEMQUESIZE-1);
} }
if (mobj->type == MT_OVERLAY) if (mobj->type == MT_OVERLAY)
...@@ -11158,14 +11129,14 @@ void P_RemoveMobj(mobj_t *mobj) ...@@ -11158,14 +11129,14 @@ void P_RemoveMobj(mobj_t *mobj)
P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL));
R_RemoveMobjInterpolator(mobj);
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
#ifdef SCRAMBLE_REMOVED #ifdef SCRAMBLE_REMOVED
// Invalidate mobj_t data to cause crashes if accessed! // Invalidate mobj_t data to cause crashes if accessed!
memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t));
#endif #endif
R_RemoveMobjInterpolator(mobj);
// free block // free block
if (!mobj->thinker.next) if (!mobj->thinker.next)
{ // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through! { // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through!
...@@ -11291,7 +11262,7 @@ void P_SpawnPrecipitation(void) ...@@ -11291,7 +11262,7 @@ void P_SpawnPrecipitation(void)
if (curWeather == PRECIP_SNOW) if (curWeather == PRECIP_SNOW)
{ {
// Not in a sector with visible sky -- exception for NiGHTS. // Not in a sector with visible sky -- exception for NiGHTS.
if ((!(maptol & TOL_NIGHTS) && (precipsector->sector->ceilingpic != skyflatnum)) == !(precipsector->sector->flags & MSF_INVERTPRECIP)) if ((!(maptol & TOL_NIGHTS) && (precipsector->sector->ceilingpic != world->skyflatnum)) == !(precipsector->sector->flags & MSF_INVERTPRECIP))
continue; continue;
rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE);
...@@ -11304,7 +11275,7 @@ void P_SpawnPrecipitation(void) ...@@ -11304,7 +11275,7 @@ void P_SpawnPrecipitation(void)
else // everything else. else // everything else.
{ {
// Not in a sector with visible sky. // Not in a sector with visible sky.
if ((precipsector->sector->ceilingpic != skyflatnum) == !(precipsector->sector->flags & MSF_INVERTPRECIP)) if ((precipsector->sector->ceilingpic != world->skyflatnum) == !(precipsector->sector->flags & MSF_INVERTPRECIP))
continue; continue;
rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN); rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN);
...@@ -11321,7 +11292,7 @@ void P_SpawnPrecipitation(void) ...@@ -11321,7 +11292,7 @@ void P_SpawnPrecipitation(void)
// //
// P_PrecipitationEffects // P_PrecipitationEffects
// //
void P_PrecipitationEffects(void) void P_PrecipitationEffects(world_t *w)
{ {
INT16 thunderchance = INT16_MAX; INT16 thunderchance = INT16_MAX;
INT32 volume; INT32 volume;
...@@ -11338,8 +11309,8 @@ void P_PrecipitationEffects(void) ...@@ -11338,8 +11309,8 @@ void P_PrecipitationEffects(void)
// with global rain and switched players to anything else ... // with global rain and switched players to anything else ...
// If the global weather has lightning strikes, // If the global weather has lightning strikes,
// EVERYONE gets them at the SAME time! // EVERYONE gets them at the SAME time!
else if (globalweather == PRECIP_STORM else if (w->weather == PRECIP_STORM
|| globalweather == PRECIP_STORM_NORAIN) || w->weather == PRECIP_STORM_NORAIN)
thunderchance = (P_RandomKey(8192)); thunderchance = (P_RandomKey(8192));
// But on the other hand, if the global weather is ANYTHING ELSE, // But on the other hand, if the global weather is ANYTHING ELSE,
// don't sync lightning strikes. // don't sync lightning strikes.
...@@ -11374,8 +11345,8 @@ void P_PrecipitationEffects(void) ...@@ -11374,8 +11345,8 @@ void P_PrecipitationEffects(void)
{ {
sector_t *ss = sectors; sector_t *ss = sectors;
for (i = 0; i < numsectors; i++, ss++) for (i = 0; i < w->numsectors; i++, ss++)
if (ss->ceilingpic == skyflatnum) // Only for the sky. if (ss->ceilingpic == w->skyflatnum) // Only for the sky.
P_SpawnLightningFlash(ss); // Spawn a quick flash thinker P_SpawnLightningFlash(ss); // Spawn a quick flash thinker
} }
...@@ -11387,7 +11358,7 @@ void P_PrecipitationEffects(void) ...@@ -11387,7 +11358,7 @@ void P_PrecipitationEffects(void)
if (sound_disabled) if (sound_disabled)
return; // Sound off? D'aw, no fun. return; // Sound off? D'aw, no fun.
if (players[displayplayer].mo->subsector->sector->ceilingpic == skyflatnum) if (players[displayplayer].mo->subsector->sector->ceilingpic == w->skyflatnum)
volume = 255; // Sky above? We get it full blast. volume = 255; // Sky above? We get it full blast.
else else
{ {
...@@ -11403,7 +11374,7 @@ void P_PrecipitationEffects(void) ...@@ -11403,7 +11374,7 @@ void P_PrecipitationEffects(void)
for (y = yl; y <= yh; y += FRACUNIT*64) for (y = yl; y <= yh; y += FRACUNIT*64)
for (x = xl; x <= xh; x += FRACUNIT*64) for (x = xl; x <= xh; x += FRACUNIT*64)
{ {
if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) // Found the outdoors! if (R_PointInWorldSubsector(w, x, y)->sector->ceilingpic == w->skyflatnum) // Found the outdoors!
{ {
newdist = S_CalculateSoundDistance(players[displayplayer].mo->x, players[displayplayer].mo->y, 0, x, y, 0); newdist = S_CalculateSoundDistance(players[displayplayer].mo->x, players[displayplayer].mo->y, 0, x, y, 0);
if (newdist < closedist) if (newdist < closedist)
...@@ -11456,7 +11427,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype) ...@@ -11456,7 +11427,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype)
// //
// P_RespawnSpecials // P_RespawnSpecials
// //
void P_RespawnSpecials(void) void P_RespawnSpecials(world_t *w)
{ {
mapthing_t *mthing = NULL; mapthing_t *mthing = NULL;
...@@ -11471,15 +11442,15 @@ void P_RespawnSpecials(void) ...@@ -11471,15 +11442,15 @@ void P_RespawnSpecials(void)
return; return;
// nothing left to respawn? // nothing left to respawn?
if (iquehead == iquetail) if (w->iquehead == w->iquetail)
return; return;
// the first item in the queue is the first to respawn // the first item in the queue is the first to respawn
// wait at least 30 seconds // wait at least 30 seconds
if (leveltime - itemrespawntime[iquetail] < (tic_t)cv_itemrespawntime.value*TICRATE) if (leveltime - w->itemrespawntime[w->iquetail] < (tic_t)cv_itemrespawntime.value*TICRATE)
return; return;
mthing = itemrespawnque[iquetail]; mthing = w->itemrespawnque[w->iquetail];
#ifdef PARANOIA #ifdef PARANOIA
if (!mthing) if (!mthing)
...@@ -11490,7 +11461,7 @@ void P_RespawnSpecials(void) ...@@ -11490,7 +11461,7 @@ void P_RespawnSpecials(void)
P_SpawnMapThing(mthing); P_SpawnMapThing(mthing);
// pull it from the que // pull it from the que
iquetail = (iquetail+1)&(ITEMQUESIZE-1); w->iquetail = (w->iquetail+1)&(ITEMQUESIZE-1);
} }
// //
...@@ -11501,7 +11472,10 @@ void P_RespawnSpecials(void) ...@@ -11501,7 +11472,10 @@ void P_RespawnSpecials(void)
void P_SpawnPlayer(INT32 playernum) void P_SpawnPlayer(INT32 playernum)
{ {
player_t *p = &players[playernum]; player_t *p = &players[playernum];
mobj_t *mobj; world_t *curworld = world;
// We're going to spawn the player in the world THEY are in
P_SetWorld(P_GetPlayerWorld(p));
if (p->playerstate == PST_REBORN) if (p->playerstate == PST_REBORN)
G_PlayerReborn(playernum, false); G_PlayerReborn(playernum, false);
...@@ -11569,7 +11543,8 @@ void P_SpawnPlayer(INT32 playernum) ...@@ -11569,7 +11543,8 @@ void P_SpawnPlayer(INT32 playernum)
if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS)) if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS))
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); mobj_t *mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
mobj->world = p->world;
(mobj->player = p)->mo = mobj; (mobj->player = p)->mo = mobj;
mobj->angle = 0; mobj->angle = 0;
...@@ -11633,6 +11608,9 @@ void P_SpawnPlayer(INT32 playernum) ...@@ -11633,6 +11608,9 @@ void P_SpawnPlayer(INT32 playernum)
// Spawn with a pity shield if necessary. // Spawn with a pity shield if necessary.
P_DoPityCheck(p); P_DoPityCheck(p);
// Restore the current world
P_SetWorld(curworld);
} }
void P_AfterPlayerSpawn(INT32 playernum) void P_AfterPlayerSpawn(INT32 playernum)
...@@ -11908,42 +11886,42 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) ...@@ -11908,42 +11886,42 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
{ {
// save spots for respawning in network games // save spots for respawning in network games
if (!metalrecording) if (!metalrecording)
playerstarts[mthing->type - 1] = mthing; world->playerstarts[mthing->type - 1] = mthing;
return true; return true;
} }
else if (mthing->type == 33) // Match starts else if (mthing->type == 33) // Match starts
{ {
if (numdmstarts < MAX_DM_STARTS) if (world->numdmstarts < MAX_DM_STARTS)
{ {
deathmatchstarts[numdmstarts] = mthing; world->deathmatchstarts[world->numdmstarts] = mthing;
mthing->type = 0; mthing->type = 0;
numdmstarts++; world->numdmstarts++;
} }
return true; return true;
} }
else if (mthing->type == 34) // Red CTF starts else if (mthing->type == 34) // Red CTF starts
{ {
if (numredctfstarts < MAXPLAYERS) if (world->numredctfstarts < MAXPLAYERS)
{ {
redctfstarts[numredctfstarts] = mthing; world->redctfstarts[world->numredctfstarts] = mthing;
mthing->type = 0; mthing->type = 0;
numredctfstarts++; world->numredctfstarts++;
} }
return true; return true;
} }
else if (mthing->type == 35) // Blue CTF starts else if (mthing->type == 35) // Blue CTF starts
{ {
if (numbluectfstarts < MAXPLAYERS) if (world->numbluectfstarts < MAXPLAYERS)
{ {
bluectfstarts[numbluectfstarts] = mthing; world->bluectfstarts[world->numbluectfstarts] = mthing;
mthing->type = 0; mthing->type = 0;
numbluectfstarts++; world->numbluectfstarts++;
} }
return true; return true;
} }
else if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum) else if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum)
{ // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. { // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints.
playerstarts[0] = mthing; world->playerstarts[0] = mthing;
return true; return true;
} }
else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn) else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn)
...@@ -12765,9 +12743,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean ...@@ -12765,9 +12743,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
} }
if (mthing->args[0]) if (mthing->args[0])
skyboxcenterpnts[tag] = mobj; world->skyboxcenterpnts[tag] = mobj;
else else
skyboxviewpnts[tag] = mobj; world->skyboxviewpnts[tag] = mobj;
break; break;
} }
case MT_EGGSTATUE: case MT_EGGSTATUE:
...@@ -14107,6 +14085,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo ...@@ -14107,6 +14085,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
if (!newmobj) if (!newmobj)
return NULL; return NULL;
newmobj->world = mobj->world;
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale); fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale);
......
...@@ -310,6 +310,8 @@ typedef struct mobj_s ...@@ -310,6 +310,8 @@ typedef struct mobj_s
struct subsector_s *subsector; // Subsector the mobj resides in. struct subsector_s *subsector; // Subsector the mobj resides in.
void *world; // current world
// The closest interval over all contacted sectors (or things). // The closest interval over all contacted sectors (or things).
fixed_t floorz; // Nearest floor below. fixed_t floorz; // Nearest floor below.
fixed_t ceilingz; // Nearest ceiling above. fixed_t ceilingz; // Nearest ceiling above.
...@@ -376,7 +378,9 @@ typedef struct mobj_s ...@@ -376,7 +378,9 @@ typedef struct mobj_s
fixed_t watertop; // top of the water FOF the mobj is in fixed_t watertop; // top of the water FOF the mobj is in
fixed_t waterbottom; // bottom of the water FOF the mobj is in fixed_t waterbottom; // bottom of the water FOF the mobj is in
UINT32 mobjnum; // A unique number for this mobj. Used for restoring pointers on save games. // Used for restoring pointers on save games.
UINT32 mobjnum; // A unique number for this mobj.
UINT32 worldnum; // The world number for this mobj.
fixed_t scale; fixed_t scale;
fixed_t old_scale; // interpolation fixed_t old_scale; // interpolation
...@@ -447,6 +451,8 @@ typedef struct precipmobj_s ...@@ -447,6 +451,8 @@ typedef struct precipmobj_s
struct subsector_s *subsector; // Subsector the mobj resides in. struct subsector_s *subsector; // Subsector the mobj resides in.
void *world; // current world
// The closest interval over all contacted sectors (or things). // The closest interval over all contacted sectors (or things).
fixed_t floorz; // Nearest floor below. fixed_t floorz; // Nearest floor below.
fixed_t ceilingz; // Nearest ceiling above. fixed_t ceilingz; // Nearest ceiling above.
...@@ -466,20 +472,6 @@ typedef struct precipmobj_s ...@@ -466,20 +472,6 @@ typedef struct precipmobj_s
INT32 flags; // flags from mobjinfo tables INT32 flags; // flags from mobjinfo tables
} precipmobj_t; } precipmobj_t;
typedef struct actioncache_s
{
struct actioncache_s *next;
struct actioncache_s *prev;
struct mobj_s *mobj;
INT32 statenum;
} actioncache_t;
extern actioncache_t actioncachehead;
void P_InitCachedActions(void);
void P_RunCachedActions(void);
void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
// check mobj against water content, before movement code // check mobj against water content, before movement code
void P_MobjCheckWater(mobj_t *mobj); void P_MobjCheckWater(mobj_t *mobj);
......
...@@ -87,22 +87,9 @@ ...@@ -87,22 +87,9 @@
// Globals // Globals
// //
// The Polyobjects
polyobj_t *PolyObjects;
INT32 numPolyObjects;
// Polyobject Blockmap -- initialized in P_LoadBlockMap // Polyobject Blockmap -- initialized in P_LoadBlockMap
polymaplink_t **polyblocklinks; polymaplink_t **polyblocklinks;
//
// Static Data
//
// Polyobject Blockmap
static polymaplink_t *bmap_freelist; // free list of blockmap links
// //
// Static Functions // Static Functions
// //
...@@ -470,7 +457,7 @@ newseg: ...@@ -470,7 +457,7 @@ newseg:
static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
{ {
size_t i; size_t i;
polyobj_t *po = &PolyObjects[num]; polyobj_t *po = &world->PolyObjects[num];
// don't spawn a polyobject more than once // don't spawn a polyobject more than once
if (po->segCount) if (po->segCount)
...@@ -542,9 +529,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) ...@@ -542,9 +529,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
} }
else else
{ {
INT32 hashkey = po->id % numPolyObjects; INT32 hashkey = po->id % world->numPolyObjects;
po->next = PolyObjects[hashkey].first; po->next = world->PolyObjects[hashkey].first;
PolyObjects[hashkey].first = num; world->PolyObjects[hashkey].first = num;
} }
} }
...@@ -651,10 +638,10 @@ static polymaplink_t *Polyobj_getLink(void) ...@@ -651,10 +638,10 @@ static polymaplink_t *Polyobj_getLink(void)
{ {
polymaplink_t *l; polymaplink_t *l;
if (bmap_freelist) if (world->po_bmap_freelist)
{ {
l = bmap_freelist; l = world->po_bmap_freelist;
bmap_freelist = (polymaplink_t *)(l->link.next); world->po_bmap_freelist = (polymaplink_t *)(l->link.next);
} }
else else
{ {
...@@ -669,8 +656,8 @@ static polymaplink_t *Polyobj_getLink(void) ...@@ -669,8 +656,8 @@ static polymaplink_t *Polyobj_getLink(void)
static void Polyobj_putLink(polymaplink_t *l) static void Polyobj_putLink(polymaplink_t *l)
{ {
memset(l, 0, sizeof(*l)); memset(l, 0, sizeof(*l));
l->link.next = (mdllistitem_t *)bmap_freelist; l->link.next = (mdllistitem_t *)world->po_bmap_freelist;
bmap_freelist = l; world->po_bmap_freelist = l;
} }
// Inserts a polyobject into the polyobject blockmap. Unlike, mobj_t's, // Inserts a polyobject into the polyobject blockmap. Unlike, mobj_t's,
...@@ -1243,12 +1230,12 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolea ...@@ -1243,12 +1230,12 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolea
// Returns NULL if no such polyobject exists. // Returns NULL if no such polyobject exists.
polyobj_t *Polyobj_GetForNum(INT32 id) polyobj_t *Polyobj_GetForNum(INT32 id)
{ {
INT32 curidx = PolyObjects[id % numPolyObjects].first; INT32 curidx = world->PolyObjects[id % world->numPolyObjects].first;
while (curidx != numPolyObjects && PolyObjects[curidx].id != id) while (curidx != world->numPolyObjects && world->PolyObjects[curidx].id != id)
curidx = PolyObjects[curidx].next; curidx = world->PolyObjects[curidx].next;
return curidx == numPolyObjects ? NULL : &PolyObjects[curidx]; return curidx == world->numPolyObjects ? NULL : &world->PolyObjects[curidx];
} }
...@@ -1265,10 +1252,10 @@ static polyobj_t *Polyobj_GetParent(polyobj_t *po) ...@@ -1265,10 +1252,10 @@ static polyobj_t *Polyobj_GetParent(polyobj_t *po)
// sorta like P_FindSectorSpecialFromTag. // sorta like P_FindSectorSpecialFromTag.
static polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start) static polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start)
{ {
for (; *start < numPolyObjects; (*start)++) for (; *start < world->numPolyObjects; (*start)++)
{ {
if (PolyObjects[*start].parent == po->id) if (world->PolyObjects[*start].parent == po->id)
return &PolyObjects[(*start)++]; return &world->PolyObjects[(*start)++];
} }
return NULL; return NULL;
...@@ -1298,9 +1285,9 @@ void Polyobj_InitLevel(void) ...@@ -1298,9 +1285,9 @@ void Polyobj_InitLevel(void)
// get rid of values from previous level // get rid of values from previous level
// note: as with msecnodes, it is very important to clear out the blockmap // note: as with msecnodes, it is very important to clear out the blockmap
// node freelist, otherwise it may contain dangling pointers to old objects // node freelist, otherwise it may contain dangling pointers to old objects
PolyObjects = NULL; world->PolyObjects = NULL;
numPolyObjects = 0; world->numPolyObjects = 0;
bmap_freelist = NULL; world->po_bmap_freelist = NULL;
// run down the thinker list, count the number of spawn points, and save // run down the thinker list, count the number of spawn points, and save
// the mobj_t pointers on a queue for use below. // the mobj_t pointers on a queue for use below.
...@@ -1313,7 +1300,7 @@ void Polyobj_InitLevel(void) ...@@ -1313,7 +1300,7 @@ void Polyobj_InitLevel(void)
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM) if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM)
{ {
++numPolyObjects; ++world->numPolyObjects;
qitem = malloc(sizeof(mobjqitem_t)); qitem = malloc(sizeof(mobjqitem_t));
memset(qitem, 0, sizeof(mobjqitem_t)); memset(qitem, 0, sizeof(mobjqitem_t));
...@@ -1331,18 +1318,18 @@ void Polyobj_InitLevel(void) ...@@ -1331,18 +1318,18 @@ void Polyobj_InitLevel(void)
} }
} }
if (numPolyObjects) if (world->numPolyObjects)
{ {
// allocate the PolyObjects array // allocate the PolyObjects array
PolyObjects = Z_Calloc(numPolyObjects * sizeof(polyobj_t), world->PolyObjects = Z_Calloc(world->numPolyObjects * sizeof(polyobj_t),
PU_LEVEL, NULL); PU_LEVEL, NULL);
// setup hash fields // setup hash fields
for (i = 0; i < numPolyObjects; ++i) for (i = 0; i < world->numPolyObjects; ++i)
PolyObjects[i].first = PolyObjects[i].next = numPolyObjects; world->PolyObjects[i].first = world->PolyObjects[i].next = world->numPolyObjects;
// setup polyobjects // setup polyobjects
for (i = 0; i < numPolyObjects; ++i) for (i = 0; i < world->numPolyObjects; ++i)
{ {
qitem = (mobjqitem_t *)M_QueueIterator(&spawnqueue); qitem = (mobjqitem_t *)M_QueueIterator(&spawnqueue);
...@@ -1358,17 +1345,17 @@ void Polyobj_InitLevel(void) ...@@ -1358,17 +1345,17 @@ void Polyobj_InitLevel(void)
} }
// setup polyobject clipping // setup polyobject clipping
for (i = 0; i < numPolyObjects; ++i) for (i = 0; i < world->numPolyObjects; ++i)
Polyobj_linkToBlockmap(&PolyObjects[i]); Polyobj_linkToBlockmap(&world->PolyObjects[i]);
} }
#if 0 #if 0
// haleyjd 02/22/06: temporary debug // haleyjd 02/22/06: temporary debug
printf("DEBUG: numPolyObjects = %d\n", numPolyObjects); printf("DEBUG: numPolyObjects = %d\n", numPolyObjects);
for (i = 0; i < numPolyObjects; ++i) for (i = 0; i < world->numPolyObjects; ++i)
{ {
INT32 j; INT32 j;
polyobj_t *po = &PolyObjects[i]; polyobj_t *po = &world->PolyObjects[i];
printf("polyobj %d:\n", i); printf("polyobj %d:\n", i);
printf("id = %d, first = %d, next = %d\n", po->id, po->first, po->next); printf("id = %d, first = %d, next = %d\n", po->id, po->first, po->next);
...@@ -1615,7 +1602,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) ...@@ -1615,7 +1602,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
if (!po->thinker) if (!po->thinker)
po->thinker = &th->thinker; po->thinker = &th->thinker;
target = waypoints[th->sequence][th->pointnum]; target = world->waypoints[th->sequence][th->pointnum];
if (!target) if (!target)
{ {
......
...@@ -407,8 +407,6 @@ boolean EV_DoPolyObjFade(polyfadedata_t *); ...@@ -407,8 +407,6 @@ boolean EV_DoPolyObjFade(polyfadedata_t *);
// External Variables // External Variables
// //
extern polyobj_t *PolyObjects;
extern INT32 numPolyObjects;
extern polymaplink_t **polyblocklinks; // polyobject blockmap extern polymaplink_t **polyblocklinks; // polyobject blockmap
#endif #endif
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "p_local.h" #include "p_local.h"
#include "p_setup.h" #include "p_setup.h"
#include "p_saveg.h" #include "p_saveg.h"
#include "p_world.h"
#include "r_data.h" #include "r_data.h"
#include "r_fps.h" #include "r_fps.h"
#include "r_textures.h" #include "r_textures.h"
...@@ -39,11 +40,15 @@ ...@@ -39,11 +40,15 @@
savedata_t savedata; savedata_t savedata;
UINT8 *save_p; UINT8 *save_p;
world_t *archiveworld;
world_t *unarchiveworld;
// Block UINT32s to attempt to ensure that the correct data is // Block UINT32s to attempt to ensure that the correct data is
// being sent and received // being sent and received
#define ARCHIVEBLOCK_MISC 0x7FEEDEED #define ARCHIVEBLOCK_MISC 0x7FEEDEED
#define ARCHIVEBLOCK_PLAYERS 0x7F448008 #define ARCHIVEBLOCK_PLAYERS 0x7F448008
#define ARCHIVEBLOCK_WORLD 0x7F8C08C0 #define ARCHIVEBLOCK_MAP 0x7F8C08C0
#define ARCHIVEBLOCK_WORLD 0x7F9F47A3
#define ARCHIVEBLOCK_POBJS 0x7F928546 #define ARCHIVEBLOCK_POBJS 0x7F928546
#define ARCHIVEBLOCK_THINKERS 0x7F37037C #define ARCHIVEBLOCK_THINKERS 0x7F37037C
#define ARCHIVEBLOCK_SPECIALS 0x7F228378 #define ARCHIVEBLOCK_SPECIALS 0x7F228378
...@@ -129,7 +134,6 @@ static void P_NetArchivePlayers(void) ...@@ -129,7 +134,6 @@ static void P_NetArchivePlayers(void)
{ {
INT32 i, j; INT32 i, j;
UINT16 flags; UINT16 flags;
// size_t q;
WRITEUINT32(save_p, ARCHIVEBLOCK_PLAYERS); WRITEUINT32(save_p, ARCHIVEBLOCK_PLAYERS);
...@@ -145,6 +149,7 @@ static void P_NetArchivePlayers(void) ...@@ -145,6 +149,7 @@ static void P_NetArchivePlayers(void)
// no longer send ticcmds // no longer send ticcmds
WRITESTRINGN(save_p, player_names[i], MAXPLAYERNAME); WRITESTRINGN(save_p, player_names[i], MAXPLAYERNAME);
WRITEINT32(save_p, players[i].worldnum);
WRITEINT16(save_p, players[i].angleturn); WRITEINT16(save_p, players[i].angleturn);
WRITEINT16(save_p, players[i].oldrelangleturn); WRITEINT16(save_p, players[i].oldrelangleturn);
WRITEANGLE(save_p, players[i].aiming); WRITEANGLE(save_p, players[i].aiming);
...@@ -372,6 +377,7 @@ static void P_NetUnArchivePlayers(void) ...@@ -372,6 +377,7 @@ static void P_NetUnArchivePlayers(void)
// NOTE: sending tics should (hopefully) no longer be necessary // NOTE: sending tics should (hopefully) no longer be necessary
READSTRINGN(save_p, player_names[i], MAXPLAYERNAME); READSTRINGN(save_p, player_names[i], MAXPLAYERNAME);
players[i].worldnum = READINT32(save_p);
players[i].angleturn = READINT16(save_p); players[i].angleturn = READINT16(save_p);
players[i].oldrelangleturn = READINT16(save_p); players[i].oldrelangleturn = READINT16(save_p);
players[i].aiming = READANGLE(save_p); players[i].aiming = READANGLE(save_p);
...@@ -803,9 +809,9 @@ static void P_NetArchiveWaypoints(void) ...@@ -803,9 +809,9 @@ static void P_NetArchiveWaypoints(void)
for (i = 0; i < NUMWAYPOINTSEQUENCES; i++) for (i = 0; i < NUMWAYPOINTSEQUENCES; i++)
{ {
WRITEUINT16(save_p, numwaypoints[i]); WRITEUINT16(save_p, archiveworld->numwaypoints[i]);
for (j = 0; j < numwaypoints[i]; j++) for (j = 0; j < archiveworld->numwaypoints[i]; j++)
WRITEUINT32(save_p, waypoints[i][j] ? waypoints[i][j]->mobjnum : 0); WRITEUINT32(save_p, archiveworld->waypoints[i][j] ? archiveworld->waypoints[i][j]->mobjnum : 0);
} }
} }
...@@ -816,11 +822,11 @@ static void P_NetUnArchiveWaypoints(void) ...@@ -816,11 +822,11 @@ static void P_NetUnArchiveWaypoints(void)
for (i = 0; i < NUMWAYPOINTSEQUENCES; i++) for (i = 0; i < NUMWAYPOINTSEQUENCES; i++)
{ {
numwaypoints[i] = READUINT16(save_p); unarchiveworld->numwaypoints[i] = READUINT16(save_p);
for (j = 0; j < numwaypoints[i]; j++) for (j = 0; j < unarchiveworld->numwaypoints[i]; j++)
{ {
mobjnum = READUINT32(save_p); mobjnum = READUINT32(save_p);
waypoints[i][j] = (mobjnum == 0) ? NULL : P_FindNewPosition(mobjnum); unarchiveworld->waypoints[i][j] = (mobjnum == 0) ? NULL : P_FindNewPosition(unarchiveworld, mobjnum);
} }
} }
} }
...@@ -999,11 +1005,11 @@ static void UnArchiveFFloors(const sector_t *ss) ...@@ -999,11 +1005,11 @@ static void UnArchiveFFloors(const sector_t *ss)
static void ArchiveSectors(void) static void ArchiveSectors(void)
{ {
size_t i, j; size_t i, j;
const sector_t *ss = sectors; const sector_t *ss = archiveworld->sectors;
const sector_t *spawnss = spawnsectors; const sector_t *spawnss = archiveworld->spawnsectors;
UINT8 diff, diff2, diff3, diff4; UINT8 diff, diff2, diff3, diff4;
for (i = 0; i < numsectors; i++, ss++, spawnss++) for (i = 0; i < archiveworld->numsectors; i++, ss++, spawnss++)
{ {
diff = diff2 = diff3 = diff4 = 0; diff = diff2 = diff3 = diff4 = 0;
if (ss->floorheight != spawnss->floorheight) if (ss->floorheight != spawnss->floorheight)
...@@ -1088,9 +1094,9 @@ static void ArchiveSectors(void) ...@@ -1088,9 +1094,9 @@ static void ArchiveSectors(void)
if (diff & SD_CEILHT) if (diff & SD_CEILHT)
WRITEFIXED(save_p, ss->ceilingheight); WRITEFIXED(save_p, ss->ceilingheight);
if (diff & SD_FLOORPIC) if (diff & SD_FLOORPIC)
WRITEMEM(save_p, levelflats[ss->floorpic].name, 8); WRITEMEM(save_p, archiveworld->flats[ss->floorpic].name, 8);
if (diff & SD_CEILPIC) if (diff & SD_CEILPIC)
WRITEMEM(save_p, levelflats[ss->ceilingpic].name, 8); WRITEMEM(save_p, archiveworld->flats[ss->ceilingpic].name, 8);
if (diff & SD_LIGHT) if (diff & SD_LIGHT)
WRITEINT16(save_p, ss->lightlevel); WRITEINT16(save_p, ss->lightlevel);
if (diff & SD_SPECIAL) if (diff & SD_SPECIAL)
...@@ -1160,8 +1166,8 @@ static void UnArchiveSectors(void) ...@@ -1160,8 +1166,8 @@ static void UnArchiveSectors(void)
if (i == 0xffff) if (i == 0xffff)
break; break;
if (i > numsectors) if (i > unarchiveworld->numsectors)
I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors)); I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(unarchiveworld->numsectors));
diff = READUINT8(save_p); diff = READUINT8(save_p);
if (diff & SD_DIFF2) if (diff & SD_DIFF2)
...@@ -1178,105 +1184,105 @@ static void UnArchiveSectors(void) ...@@ -1178,105 +1184,105 @@ static void UnArchiveSectors(void)
diff4 = 0; diff4 = 0;
if (diff & SD_FLOORHT) if (diff & SD_FLOORHT)
sectors[i].floorheight = READFIXED(save_p); unarchiveworld->sectors[i].floorheight = READFIXED(save_p);
if (diff & SD_CEILHT) if (diff & SD_CEILHT)
sectors[i].ceilingheight = READFIXED(save_p); unarchiveworld->sectors[i].ceilingheight = READFIXED(save_p);
if (diff & SD_FLOORPIC) if (diff & SD_FLOORPIC)
{ {
sectors[i].floorpic = P_AddLevelFlatRuntime((char *)save_p); unarchiveworld->sectors[i].floorpic = P_AddLevelFlatForWorld(unarchiveworld, (char *)save_p);
save_p += 8; save_p += 8;
} }
if (diff & SD_CEILPIC) if (diff & SD_CEILPIC)
{ {
sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)save_p); unarchiveworld->sectors[i].ceilingpic = P_AddLevelFlatForWorld(unarchiveworld, (char *)save_p);
save_p += 8; save_p += 8;
} }
if (diff & SD_LIGHT) if (diff & SD_LIGHT)
sectors[i].lightlevel = READINT16(save_p); unarchiveworld->sectors[i].lightlevel = READINT16(save_p);
if (diff & SD_SPECIAL) if (diff & SD_SPECIAL)
sectors[i].special = READINT16(save_p); unarchiveworld->sectors[i].special = READINT16(save_p);
if (diff2 & SD_FXOFFS) if (diff2 & SD_FXOFFS)
sectors[i].floor_xoffs = READFIXED(save_p); unarchiveworld->sectors[i].floor_xoffs = READFIXED(save_p);
if (diff2 & SD_FYOFFS) if (diff2 & SD_FYOFFS)
sectors[i].floor_yoffs = READFIXED(save_p); unarchiveworld->sectors[i].floor_yoffs = READFIXED(save_p);
if (diff2 & SD_CXOFFS) if (diff2 & SD_CXOFFS)
sectors[i].ceiling_xoffs = READFIXED(save_p); unarchiveworld->sectors[i].ceiling_xoffs = READFIXED(save_p);
if (diff2 & SD_CYOFFS) if (diff2 & SD_CYOFFS)
sectors[i].ceiling_yoffs = READFIXED(save_p); unarchiveworld->sectors[i].ceiling_yoffs = READFIXED(save_p);
if (diff2 & SD_FLOORANG) if (diff2 & SD_FLOORANG)
sectors[i].floorpic_angle = READANGLE(save_p); unarchiveworld->sectors[i].floorpic_angle = READANGLE(save_p);
if (diff2 & SD_CEILANG) if (diff2 & SD_CEILANG)
sectors[i].ceilingpic_angle = READANGLE(save_p); unarchiveworld->sectors[i].ceilingpic_angle = READANGLE(save_p);
if (diff2 & SD_TAG) if (diff2 & SD_TAG)
{ {
size_t ncount = READUINT32(save_p); size_t ncount = READUINT32(save_p);
// Remove entries from global lists. // Remove entries from global lists.
for (j = 0; j < sectors[i].tags.count; j++) for (j = 0; j < unarchiveworld->sectors[i].tags.count; j++)
Taggroup_Remove(tags_sectors, sectors[i].tags.tags[j], i); Taggroup_Remove(unarchiveworld->tags_sectors, unarchiveworld->sectors[i].tags.tags[j], i);
// Reallocate if size differs. // Reallocate if size differs.
if (ncount != sectors[i].tags.count) if (ncount != sectors[i].tags.count)
{ {
sectors[i].tags.count = ncount; unarchiveworld->sectors[i].tags.count = ncount;
sectors[i].tags.tags = Z_Realloc(sectors[i].tags.tags, ncount*sizeof(mtag_t), PU_LEVEL, NULL); unarchiveworld->sectors[i].tags.tags = Z_Realloc(unarchiveworld->sectors[i].tags.tags, ncount*sizeof(mtag_t), PU_LEVEL, NULL);
} }
for (j = 0; j < ncount; j++) for (j = 0; j < ncount; j++)
sectors[i].tags.tags[j] = READINT16(save_p); unarchiveworld->sectors[i].tags.tags[j] = READINT16(save_p);
// Add new entries. // Add new entries.
for (j = 0; j < sectors[i].tags.count; j++) for (j = 0; j < sectors[i].tags.count; j++)
Taggroup_Remove(tags_sectors, sectors[i].tags.tags[j], i); Taggroup_Remove(unarchiveworld->tags_sectors, unarchiveworld->sectors[i].tags.tags[j], i);
} }
if (diff3 & SD_COLORMAP) if (diff3 & SD_COLORMAP)
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p)); unarchiveworld->sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p));
if (diff3 & SD_CRUMBLESTATE) if (diff3 & SD_CRUMBLESTATE)
sectors[i].crumblestate = READINT32(save_p); unarchiveworld->sectors[i].crumblestate = READINT32(save_p);
if (diff3 & SD_FLOORLIGHT) if (diff3 & SD_FLOORLIGHT)
{ {
sectors[i].floorlightlevel = READINT16(save_p); unarchiveworld->sectors[i].floorlightlevel = READINT16(save_p);
sectors[i].floorlightabsolute = READUINT8(save_p); unarchiveworld->sectors[i].floorlightabsolute = READUINT8(save_p);
} }
if (diff3 & SD_CEILLIGHT) if (diff3 & SD_CEILLIGHT)
{ {
sectors[i].ceilinglightlevel = READINT16(save_p); unarchiveworld->sectors[i].ceilinglightlevel = READINT16(save_p);
sectors[i].ceilinglightabsolute = READUINT8(save_p); unarchiveworld->sectors[i].ceilinglightabsolute = READUINT8(save_p);
} }
if (diff3 & SD_FLAG) if (diff3 & SD_FLAG)
{ {
sectors[i].flags = READUINT32(save_p); unarchiveworld->sectors[i].flags = READUINT32(save_p);
CheckForReverseGravity |= (sectors[i].flags & MSF_GRAVITYFLIP); CheckForReverseGravity |= (unarchiveworld->sectors[i].flags & MSF_GRAVITYFLIP);
} }
if (diff3 & SD_SPECIALFLAG) if (diff3 & SD_SPECIALFLAG)
sectors[i].specialflags = READUINT32(save_p); unarchiveworld->sectors[i].specialflags = READUINT32(save_p);
if (diff4 & SD_DAMAGETYPE) if (diff4 & SD_DAMAGETYPE)
sectors[i].damagetype = READUINT8(save_p); unarchiveworld->sectors[i].damagetype = READUINT8(save_p);
if (diff4 & SD_TRIGGERTAG) if (diff4 & SD_TRIGGERTAG)
sectors[i].triggertag = READINT16(save_p); unarchiveworld->sectors[i].triggertag = READINT16(save_p);
if (diff4 & SD_TRIGGERER) if (diff4 & SD_TRIGGERER)
sectors[i].triggerer = READUINT8(save_p); unarchiveworld->sectors[i].triggerer = READUINT8(save_p);
if (diff4 & SD_GRAVITY) if (diff4 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p); unarchiveworld->sectors[i].gravity = READFIXED(save_p);
if (diff & SD_FFLOORS) if (diff & SD_FFLOORS)
UnArchiveFFloors(&sectors[i]); UnArchiveFFloors(&unarchiveworld->sectors[i]);
} }
} }
static void ArchiveLines(void) static void ArchiveLines(void)
{ {
size_t i; size_t i;
const line_t *li = lines; const line_t *li = archiveworld->lines;
const line_t *spawnli = spawnlines; const line_t *spawnli = archiveworld->spawnlines;
const side_t *si; const side_t *si;
const side_t *spawnsi; const side_t *spawnsi;
UINT8 diff, diff2; // no diff3 UINT8 diff, diff2; // no diff3
for (i = 0; i < numlines; i++, spawnli++, li++) for (i = 0; i < archiveworld->numlines; i++, spawnli++, li++)
{ {
diff = diff2 = 0; diff = diff2 = 0;
...@@ -1297,8 +1303,8 @@ static void ArchiveLines(void) ...@@ -1297,8 +1303,8 @@ static void ArchiveLines(void)
if (li->sidenum[0] != 0xffff) if (li->sidenum[0] != 0xffff)
{ {
si = &sides[li->sidenum[0]]; si = &archiveworld->sides[li->sidenum[0]];
spawnsi = &spawnsides[li->sidenum[0]]; spawnsi = &archiveworld->spawnsides[li->sidenum[0]];
if (si->textureoffset != spawnsi->textureoffset) if (si->textureoffset != spawnsi->textureoffset)
diff |= LD_S1TEXOFF; diff |= LD_S1TEXOFF;
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures. //SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
...@@ -1311,8 +1317,8 @@ static void ArchiveLines(void) ...@@ -1311,8 +1317,8 @@ static void ArchiveLines(void)
} }
if (li->sidenum[1] != 0xffff) if (li->sidenum[1] != 0xffff)
{ {
si = &sides[li->sidenum[1]]; si = &archiveworld->sides[li->sidenum[1]];
spawnsi = &spawnsides[li->sidenum[1]]; spawnsi = &archiveworld->spawnsides[li->sidenum[1]];
if (si->textureoffset != spawnsi->textureoffset) if (si->textureoffset != spawnsi->textureoffset)
diff2 |= LD_S2TEXOFF; diff2 |= LD_S2TEXOFF;
if (si->toptexture != spawnsi->toptexture) if (si->toptexture != spawnsi->toptexture)
...@@ -1339,7 +1345,7 @@ static void ArchiveLines(void) ...@@ -1339,7 +1345,7 @@ static void ArchiveLines(void)
if (diff & LD_CLLCOUNT) if (diff & LD_CLLCOUNT)
WRITEINT16(save_p, li->callcount); WRITEINT16(save_p, li->callcount);
si = &sides[li->sidenum[0]]; si = &archiveworld->sides[li->sidenum[0]];
if (diff & LD_S1TEXOFF) if (diff & LD_S1TEXOFF)
WRITEFIXED(save_p, si->textureoffset); WRITEFIXED(save_p, si->textureoffset);
if (diff & LD_S1TOPTEX) if (diff & LD_S1TOPTEX)
...@@ -1349,7 +1355,7 @@ static void ArchiveLines(void) ...@@ -1349,7 +1355,7 @@ static void ArchiveLines(void)
if (diff & LD_S1MIDTEX) if (diff & LD_S1MIDTEX)
WRITEINT32(save_p, si->midtexture); WRITEINT32(save_p, si->midtexture);
si = &sides[li->sidenum[1]]; si = &archiveworld->sides[li->sidenum[1]];
if (diff2 & LD_S2TEXOFF) if (diff2 & LD_S2TEXOFF)
WRITEFIXED(save_p, si->textureoffset); WRITEFIXED(save_p, si->textureoffset);
if (diff2 & LD_S2TOPTEX) if (diff2 & LD_S2TOPTEX)
...@@ -1403,11 +1409,11 @@ static void UnArchiveLines(void) ...@@ -1403,11 +1409,11 @@ static void UnArchiveLines(void)
if (i == 0xffff) if (i == 0xffff)
break; break;
if (i > numlines) if (i > unarchiveworld->numlines)
I_Error("Invalid line number %u from server", i); I_Error("Invalid line number %u from server", i);
diff = READUINT8(save_p); diff = READUINT8(save_p);
li = &lines[i]; li = &unarchiveworld->lines[i];
if (diff & LD_DIFF2) if (diff & LD_DIFF2)
diff2 = READUINT8(save_p); diff2 = READUINT8(save_p);
...@@ -1473,27 +1479,19 @@ static void UnArchiveLines(void) ...@@ -1473,27 +1479,19 @@ static void UnArchiveLines(void)
} }
} }
static void P_NetArchiveWorld(void) static void P_NetArchiveMap(void)
{ {
// initialize colormap vars because paranoia WRITEUINT32(save_p, ARCHIVEBLOCK_MAP);
ClearNetColormaps();
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
ArchiveSectors(); ArchiveSectors();
ArchiveLines(); ArchiveLines();
R_ClearTextureNumCache(false);
} }
static void P_NetUnArchiveWorld(void) static void P_NetUnArchiveMap(void)
{ {
UINT16 i; UINT16 i;
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD) if (READUINT32(save_p) != ARCHIVEBLOCK_MAP)
I_Error("Bad $$$.sav at archive block World"); I_Error("Bad $$$.sav at archive block Map");
// initialize colormap vars because paranoia
ClearNetColormaps();
// count the level's ffloors so that colormap loading can have an upper limit // count the level's ffloors so that colormap loading can have an upper limit
for (i = 0; i < numsectors; i++) for (i = 0; i < numsectors; i++)
...@@ -1629,13 +1627,13 @@ static inline UINT32 SaveMobjnum(const mobj_t *mobj) ...@@ -1629,13 +1627,13 @@ static inline UINT32 SaveMobjnum(const mobj_t *mobj)
static UINT32 SaveSector(const sector_t *sector) static UINT32 SaveSector(const sector_t *sector)
{ {
if (sector) return (UINT32)(sector - sectors); if (sector) return (UINT32)(sector - archiveworld->sectors);
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
static UINT32 SaveLine(const line_t *line) static UINT32 SaveLine(const line_t *line)
{ {
if (line) return (UINT32)(line - lines); if (line) return (UINT32)(line - archiveworld->lines);
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
...@@ -1845,8 +1843,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) ...@@ -1845,8 +1843,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
{ {
size_t z; size_t z;
for (z = 0; z < nummapthings; z++) for (z = 0; z < archiveworld->nummapthings; z++)
if (&mapthings[z] == mobj->spawnpoint) if (&archiveworld->mapthings[z] == mobj->spawnpoint)
WRITEUINT16(save_p, z); WRITEUINT16(save_p, z);
if (mobj->type == MT_HOOPCENTER) if (mobj->type == MT_HOOPCENTER)
return; return;
...@@ -1988,6 +1986,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) ...@@ -1988,6 +1986,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, mobj->dispoffset); WRITEINT32(save_p, mobj->dispoffset);
WRITEUINT32(save_p, mobj->mobjnum); WRITEUINT32(save_p, mobj->mobjnum);
WRITEUINT32(save_p, mobj->worldnum);
} }
static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type)
...@@ -2487,7 +2486,7 @@ static void P_NetArchiveThinkers(void) ...@@ -2487,7 +2486,7 @@ static void P_NetArchiveThinkers(void)
{ {
UINT32 numsaved = 0; UINT32 numsaved = 0;
// save off the current thinkers // save off the current thinkers
for (th = thlist[i].next; th != &thlist[i]; th = th->next) for (th = archiveworld->thlist[i].next; th != &archiveworld->thlist[i]; th = th->next)
{ {
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|| th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) || th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
...@@ -2717,12 +2716,12 @@ static void P_NetArchiveThinkers(void) ...@@ -2717,12 +2716,12 @@ static void P_NetArchiveThinkers(void)
// relink to this; the savegame contains the old position in the pointer // relink to this; the savegame contains the old position in the pointer
// field copyed in the info field temporarily, but finally we just search // field copyed in the info field temporarily, but finally we just search
// for the old position and relink to it. // for the old position and relink to it.
mobj_t *P_FindNewPosition(UINT32 oldposition) mobj_t *P_FindNewPosition(world_t *w, UINT32 oldposition)
{ {
thinker_t *th; thinker_t *th;
mobj_t *mobj; mobj_t *mobj;
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = w->thlist[THINK_MOBJ].next; th != &w->thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue; continue;
...@@ -2745,14 +2744,14 @@ static inline mobj_t *LoadMobj(UINT32 mobjnum) ...@@ -2745,14 +2744,14 @@ static inline mobj_t *LoadMobj(UINT32 mobjnum)
static sector_t *LoadSector(UINT32 sector) static sector_t *LoadSector(UINT32 sector)
{ {
if (sector >= numsectors) return NULL; if (sector >= unarchiveworld->numsectors) return NULL;
return &sectors[sector]; return &unarchiveworld->sectors[sector];
} }
static line_t *LoadLine(UINT32 line) static line_t *LoadLine(UINT32 line)
{ {
if (line >= numlines) return NULL; if (line >= unarchiveworld->numlines) return NULL;
return &lines[line]; return &unarchiveworld->lines[line];
} }
static inline player_t *LoadPlayer(UINT32 player) static inline player_t *LoadPlayer(UINT32 player)
...@@ -2763,8 +2762,8 @@ static inline player_t *LoadPlayer(UINT32 player) ...@@ -2763,8 +2762,8 @@ static inline player_t *LoadPlayer(UINT32 player)
static inline pslope_t *LoadSlope(UINT32 slopeid) static inline pslope_t *LoadSlope(UINT32 slopeid)
{ {
pslope_t *p = slopelist; pslope_t *p = unarchiveworld->slopelist;
if (slopeid > slopecount) return NULL; if (slopeid > unarchiveworld->slopecount) return NULL;
do do
{ {
if (p->id == slopeid) if (p->id == slopeid)
...@@ -2813,16 +2812,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) ...@@ -2813,16 +2812,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
{ {
UINT16 spawnpointnum = READUINT16(save_p); UINT16 spawnpointnum = READUINT16(save_p);
if (mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case if (unarchiveworld->mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
{ {
P_SpawnHoop(&mapthings[spawnpointnum]); P_SpawnHoop(&unarchiveworld->mapthings[spawnpointnum]);
return NULL; return NULL;
} }
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
mobj->spawnpoint = &mapthings[spawnpointnum]; mobj->spawnpoint = &unarchiveworld->mapthings[spawnpointnum];
mapthings[spawnpointnum].mobj = mobj; unarchiveworld->mapthings[spawnpointnum].mobj = mobj;
} }
else else
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
...@@ -2994,7 +2993,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) ...@@ -2994,7 +2993,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_SLOPE) if (diff2 & MD2_SLOPE)
mobj->standingslope = P_SlopeById(READUINT16(save_p)); mobj->standingslope = P_SlopeById(unarchiveworld->slopelist, READUINT16(save_p));
if (diff2 & MD2_COLORIZED) if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p); mobj->colorized = READUINT8(save_p);
if (diff2 & MD2_MIRRORED) if (diff2 & MD2_MIRRORED)
...@@ -3061,6 +3060,11 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) ...@@ -3061,6 +3060,11 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->mobjnum = READUINT32(save_p); mobj->mobjnum = READUINT32(save_p);
// Unarchive world number
mobj->worldnum = READUINT32(save_p);
if (mobj->worldnum == 0xFFFFFFFF)
I_Error("Unknown world");
if (mobj->player) if (mobj->player)
{ {
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
...@@ -3075,16 +3079,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) ...@@ -3075,16 +3079,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (tag >= 0 && tag <= 15) if (tag >= 0 && tag <= 15)
{ {
if (mobj->spawnpoint->args[0]) if (mobj->spawnpoint->args[0])
skyboxcenterpnts[tag] = mobj; unarchiveworld->skyboxcenterpnts[tag] = mobj;
else else
skyboxviewpnts[tag] = mobj; unarchiveworld->skyboxviewpnts[tag] = mobj;
} }
} }
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
R_AddMobjInterpolator(mobj);
return &mobj->thinker; return &mobj->thinker;
} }
...@@ -3697,8 +3699,8 @@ static void P_NetUnArchiveThinkers(void) ...@@ -3697,8 +3699,8 @@ static void P_NetUnArchiveThinkers(void)
// remove all the current thinkers // remove all the current thinkers
for (i = 0; i < NUM_THINKERLISTS; i++) for (i = 0; i < NUM_THINKERLISTS; i++)
{ {
currentthinker = thlist[i].next; currentthinker = unarchiveworld->thlist[i].next;
for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = next) for (currentthinker = unarchiveworld->thlist[i].next; currentthinker != &unarchiveworld->thlist[i]; currentthinker = next)
{ {
next = currentthinker->next; next = currentthinker->next;
...@@ -3707,20 +3709,23 @@ static void P_NetUnArchiveThinkers(void) ...@@ -3707,20 +3709,23 @@ static void P_NetUnArchiveThinkers(void)
else else
{ {
(next->prev = currentthinker->prev)->next = next; (next->prev = currentthinker->prev)->next = next;
R_DestroyLevelInterpolators(currentthinker); R_DestroyLevelInterpolators(unarchiveworld, currentthinker);
Z_Free(currentthinker); Z_Free(currentthinker);
} }
} }
} }
// we don't want the removed mobjs to come back // we don't want the removed mobjs to come back
iquetail = iquehead = 0; unarchiveworld->iquetail = unarchiveworld->iquehead = 0;
P_InitThinkers(); P_InitThinkers(unarchiveworld);
// clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity // clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity
for (i = 0; i < numsectors; i++) for (i = 0; i < numsectors; i++)
{ {
sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = sectors[i].fadecolormapdata = NULL; unarchiveworld->sectors[i].floordata = NULL;
unarchiveworld->sectors[i].ceilingdata = NULL;
unarchiveworld->sectors[i].lightingdata = NULL;
unarchiveworld->sectors[i].fadecolormapdata = NULL;
} }
// read in saved thinkers // read in saved thinkers
...@@ -3912,8 +3917,8 @@ static void P_NetUnArchiveThinkers(void) ...@@ -3912,8 +3917,8 @@ static void P_NetUnArchiveThinkers(void)
} }
// Set each skyboxmo to the first skybox (or NULL) // Set each skyboxmo to the first skybox (or NULL)
skyboxmo[0] = skyboxviewpnts[0]; unarchiveworld->skyboxmo[0] = unarchiveworld->skyboxviewpnts[0];
skyboxmo[1] = skyboxcenterpnts[0]; unarchiveworld->skyboxmo[1] = unarchiveworld->skyboxcenterpnts[0];
if (restoreNum) if (restoreNum)
{ {
...@@ -3926,7 +3931,7 @@ static void P_NetUnArchiveThinkers(void) ...@@ -3926,7 +3931,7 @@ static void P_NetUnArchiveThinkers(void)
delay = (void *)currentthinker; delay = (void *)currentthinker;
if (!(mobjnum = (UINT32)(size_t)delay->caller)) if (!(mobjnum = (UINT32)(size_t)delay->caller))
continue; continue;
delay->caller = P_FindNewPosition(mobjnum); delay->caller = P_FindNewPosition(unarchiveworld, mobjnum);
} }
} }
} }
...@@ -3995,20 +4000,20 @@ static inline void P_UnArchivePolyObj(polyobj_t *po) ...@@ -3995,20 +4000,20 @@ static inline void P_UnArchivePolyObj(polyobj_t *po)
Polyobj_MoveOnLoad(po, angle, x, y); Polyobj_MoveOnLoad(po, angle, x, y);
} }
static inline void P_ArchivePolyObjects(void) static inline void P_NetArchivePolyObjects(void)
{ {
INT32 i; INT32 i;
WRITEUINT32(save_p, ARCHIVEBLOCK_POBJS); WRITEUINT32(save_p, ARCHIVEBLOCK_POBJS);
// save number of polyobjects // save number of polyobjects
WRITEINT32(save_p, numPolyObjects); WRITEINT32(save_p, archiveworld->numPolyObjects);
for (i = 0; i < numPolyObjects; ++i) for (i = 0; i < archiveworld->numPolyObjects; ++i)
P_ArchivePolyObj(&PolyObjects[i]); P_ArchivePolyObj(&archiveworld->PolyObjects[i]);
} }
static inline void P_UnArchivePolyObjects(void) static inline void P_NetUnArchivePolyObjects(void)
{ {
INT32 i, numSavedPolys; INT32 i, numSavedPolys;
...@@ -4017,11 +4022,11 @@ static inline void P_UnArchivePolyObjects(void) ...@@ -4017,11 +4022,11 @@ static inline void P_UnArchivePolyObjects(void)
numSavedPolys = READINT32(save_p); numSavedPolys = READINT32(save_p);
if (numSavedPolys != numPolyObjects) if (numSavedPolys != world->numPolyObjects)
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency\n"); I_Error("P_NetUnArchivePolyObjects: polyobj count inconsistency\n");
for (i = 0; i < numSavedPolys; ++i) for (i = 0; i < numSavedPolys; ++i)
P_UnArchivePolyObj(&PolyObjects[i]); P_UnArchivePolyObj(&world->PolyObjects[i]);
} }
static inline void P_FinishMobjs(void) static inline void P_FinishMobjs(void)
...@@ -4048,7 +4053,8 @@ static void P_RelinkPointers(void) ...@@ -4048,7 +4053,8 @@ static void P_RelinkPointers(void)
UINT32 temp; UINT32 temp;
// use info field (value = oldposition) to relink mobjs // use info field (value = oldposition) to relink mobjs
for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ]; for (currentthinker = unarchiveworld->thlist[THINK_MOBJ].next;
currentthinker != &unarchiveworld->thlist[THINK_MOBJ];
currentthinker = currentthinker->next) currentthinker = currentthinker->next)
{ {
if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
...@@ -4063,70 +4069,70 @@ static void P_RelinkPointers(void) ...@@ -4063,70 +4069,70 @@ static void P_RelinkPointers(void)
{ {
temp = (UINT32)(size_t)mobj->tracer; temp = (UINT32)(size_t)mobj->tracer;
mobj->tracer = NULL; mobj->tracer = NULL;
if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type);
} }
if (mobj->target) if (mobj->target)
{ {
temp = (UINT32)(size_t)mobj->target; temp = (UINT32)(size_t)mobj->target;
mobj->target = NULL; mobj->target = NULL;
if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->target, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type);
} }
if (mobj->hnext) if (mobj->hnext)
{ {
temp = (UINT32)(size_t)mobj->hnext; temp = (UINT32)(size_t)mobj->hnext;
mobj->hnext = NULL; mobj->hnext = NULL;
if (!(mobj->hnext = P_FindNewPosition(temp))) if (!(mobj->hnext = P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type);
} }
if (mobj->hprev) if (mobj->hprev)
{ {
temp = (UINT32)(size_t)mobj->hprev; temp = (UINT32)(size_t)mobj->hprev;
mobj->hprev = NULL; mobj->hprev = NULL;
if (!(mobj->hprev = P_FindNewPosition(temp))) if (!(mobj->hprev = P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
} }
if (mobj->player && mobj->player->capsule) if (mobj->player && mobj->player->capsule)
{ {
temp = (UINT32)(size_t)mobj->player->capsule; temp = (UINT32)(size_t)mobj->player->capsule;
mobj->player->capsule = NULL; mobj->player->capsule = NULL;
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
} }
if (mobj->player && mobj->player->axis1) if (mobj->player && mobj->player->axis1)
{ {
temp = (UINT32)(size_t)mobj->player->axis1; temp = (UINT32)(size_t)mobj->player->axis1;
mobj->player->axis1 = NULL; mobj->player->axis1 = NULL;
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
} }
if (mobj->player && mobj->player->axis2) if (mobj->player && mobj->player->axis2)
{ {
temp = (UINT32)(size_t)mobj->player->axis2; temp = (UINT32)(size_t)mobj->player->axis2;
mobj->player->axis2 = NULL; mobj->player->axis2 = NULL;
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
} }
if (mobj->player && mobj->player->awayviewmobj) if (mobj->player && mobj->player->awayviewmobj)
{ {
temp = (UINT32)(size_t)mobj->player->awayviewmobj; temp = (UINT32)(size_t)mobj->player->awayviewmobj;
mobj->player->awayviewmobj = NULL; mobj->player->awayviewmobj = NULL;
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
} }
if (mobj->player && mobj->player->followmobj) if (mobj->player && mobj->player->followmobj)
{ {
temp = (UINT32)(size_t)mobj->player->followmobj; temp = (UINT32)(size_t)mobj->player->followmobj;
mobj->player->followmobj = NULL; mobj->player->followmobj = NULL;
if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type);
} }
if (mobj->player && mobj->player->drone) if (mobj->player && mobj->player->drone)
{ {
temp = (UINT32)(size_t)mobj->player->drone; temp = (UINT32)(size_t)mobj->player->drone;
mobj->player->drone = NULL; mobj->player->drone = NULL;
if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp))) if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type); CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type);
} }
} }
...@@ -4139,18 +4145,18 @@ static inline void P_NetArchiveSpecials(void) ...@@ -4139,18 +4145,18 @@ static inline void P_NetArchiveSpecials(void)
WRITEUINT32(save_p, ARCHIVEBLOCK_SPECIALS); WRITEUINT32(save_p, ARCHIVEBLOCK_SPECIALS);
// itemrespawn queue for deathmatch // itemrespawn queue for deathmatch
i = iquetail; i = archiveworld->iquetail;
while (iquehead != i) while (archiveworld->iquehead != i)
{ {
for (z = 0; z < nummapthings; z++) for (z = 0; z < archiveworld->nummapthings; z++)
{ {
if (&mapthings[z] == itemrespawnque[i]) if (&archiveworld->mapthings[z] == archiveworld->itemrespawnque[i])
{ {
WRITEUINT32(save_p, z); WRITEUINT32(save_p, z);
break; break;
} }
} }
WRITEUINT32(save_p, itemrespawntime[i]); WRITEUINT32(save_p, archiveworld->itemrespawntime[i]);
i = (i + 1) & (ITEMQUESIZE-1); i = (i + 1) & (ITEMQUESIZE-1);
} }
...@@ -4158,10 +4164,13 @@ static inline void P_NetArchiveSpecials(void) ...@@ -4158,10 +4164,13 @@ static inline void P_NetArchiveSpecials(void)
WRITEUINT32(save_p, 0xffffffff); WRITEUINT32(save_p, 0xffffffff);
// Sky number // Sky number
WRITEINT32(save_p, globallevelskynum); WRITEINT32(save_p, archiveworld->skynum);
// Gravity
WRITEFIXED(save_p, archiveworld->gravity);
// Current global weather type // Current global weather type
WRITEUINT8(save_p, globalweather); WRITEUINT8(save_p, archiveworld->weather);
if (metalplayback) // Is metal sonic running? if (metalplayback) // Is metal sonic running?
{ {
...@@ -4181,30 +4190,31 @@ static void P_NetUnArchiveSpecials(void) ...@@ -4181,30 +4190,31 @@ static void P_NetUnArchiveSpecials(void)
I_Error("Bad $$$.sav at archive block Specials"); I_Error("Bad $$$.sav at archive block Specials");
// BP: added save itemrespawn queue for deathmatch // BP: added save itemrespawn queue for deathmatch
iquetail = iquehead = 0; unarchiveworld->iquetail = unarchiveworld->iquehead = 0;
while ((i = READUINT32(save_p)) != 0xffffffff) while ((i = READUINT32(save_p)) != 0xffffffff)
{ {
itemrespawnque[iquehead] = &mapthings[i]; unarchiveworld->itemrespawnque[unarchiveworld->iquehead] = &unarchiveworld->mapthings[i];
itemrespawntime[iquehead++] = READINT32(save_p); unarchiveworld->itemrespawntime[unarchiveworld->iquehead++] = READINT32(save_p);
} }
j = READINT32(save_p); j = READINT32(save_p);
if (j != globallevelskynum) P_SetupLevelSky(j, false); // Don't call P_SetupWorldSky from there
P_SetupLevelSky(j, true); P_SetupWorldSky(j, unarchiveworld);
globalweather = READUINT8(save_p); unarchiveworld->gravity = READFIXED(save_p);
unarchiveworld->weather = READUINT8(save_p);
if (globalweather) if (world->weather)
{ {
if (curWeather == globalweather) if (curWeather == world->weather)
curWeather = PRECIP_NONE; curWeather = PRECIP_NONE;
P_SwitchWeather(globalweather); P_SwitchWeather(world->weather);
} }
else // PRECIP_NONE else // PRECIP_NONE
{ {
if (curWeather != PRECIP_NONE) if (curWeather != PRECIP_NONE)
P_SwitchWeather(globalweather); P_SwitchWeather(world->weather);
} }
if (READUINT8(save_p) == 0x01) // metal sonic if (READUINT8(save_p) == 0x01) // metal sonic
...@@ -4246,7 +4256,8 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride) ...@@ -4246,7 +4256,8 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
if(!mapheaderinfo[gamemap-1]) if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1); P_AllocMapHeader(gamemap-1);
//lastmapsaved = gamemap; curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
lastmaploaded = gamemap; lastmaploaded = gamemap;
tokenlist = 0; tokenlist = 0;
...@@ -4276,7 +4287,7 @@ static void P_NetArchiveMisc(boolean resending) ...@@ -4276,7 +4287,7 @@ static void P_NetArchiveMisc(boolean resending)
if (resending) if (resending)
WRITEUINT32(save_p, gametic); WRITEUINT32(save_p, gametic);
WRITEINT16(save_p, gamemap); WRITEINT16(save_p, baseworld->gamemap);
WRITEINT16(save_p, gamestate); WRITEINT16(save_p, gamestate);
WRITEINT16(save_p, gametype); WRITEINT16(save_p, gametype);
...@@ -4333,8 +4344,6 @@ static void P_NetArchiveMisc(boolean resending) ...@@ -4333,8 +4344,6 @@ static void P_NetArchiveMisc(boolean resending)
WRITEUINT32(save_p, countdown); WRITEUINT32(save_p, countdown);
WRITEUINT32(save_p, countdown2); WRITEUINT32(save_p, countdown2);
WRITEFIXED(save_p, gravity);
WRITEUINT32(save_p, countdowntimer); WRITEUINT32(save_p, countdowntimer);
WRITEUINT8(save_p, countdowntimeup); WRITEUINT8(save_p, countdowntimeup);
...@@ -4356,6 +4365,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) ...@@ -4356,6 +4365,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
if (READUINT32(save_p) != ARCHIVEBLOCK_MISC) if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
I_Error("Bad $$$.sav at archive block Misc"); I_Error("Bad $$$.sav at archive block Misc");
World_UnloadAll();
if (reloading) if (reloading)
gametic = READUINT32(save_p); gametic = READUINT32(save_p);
...@@ -4366,6 +4376,9 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) ...@@ -4366,6 +4376,9 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
if(!mapheaderinfo[gamemap-1]) if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1); P_AllocMapHeader(gamemap-1);
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
// tell the sound code to reset the music since we're skipping what // tell the sound code to reset the music since we're skipping what
// normally sets this flag // normally sets this flag
mapmusflags |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
...@@ -4433,8 +4446,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) ...@@ -4433,8 +4446,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
countdown = READUINT32(save_p); countdown = READUINT32(save_p);
countdown2 = READUINT32(save_p); countdown2 = READUINT32(save_p);
gravity = READFIXED(save_p);
countdowntimer = (tic_t)READUINT32(save_p); countdowntimer = (tic_t)READUINT32(save_p);
countdowntimeup = (boolean)READUINT8(save_p); countdowntimeup = (boolean)READUINT8(save_p);
...@@ -4722,38 +4733,83 @@ void P_SaveGame(INT16 mapnum) ...@@ -4722,38 +4733,83 @@ void P_SaveGame(INT16 mapnum)
P_ArchiveLuabanksAndConsistency(); P_ArchiveLuabanksAndConsistency();
} }
static void P_NetArchiveWorlds(void)
{
INT32 i;
// initialize colormap vars because paranoia
ClearNetColormaps();
R_ClearTextureNumCache(false);
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
WRITEINT32(save_p, numworlds);
for (i = 0; i < numworlds; i++)
{
archiveworld = worldlist[i];
WRITEINT16(save_p, archiveworld->gamemap);
WRITEUINT8(save_p, archiveworld->players);
P_NetArchiveMap();
P_NetArchivePolyObjects();
P_NetArchiveThinkers();
P_NetArchiveSpecials();
P_NetArchiveWaypoints();
}
P_NetArchiveColormaps();
}
void P_SaveNetGame(boolean resending) void P_SaveNetGame(boolean resending)
{ {
thinker_t *th; INT32 i;
mobj_t *mobj;
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
CV_SaveNetVars(&save_p); CV_SaveNetVars(&save_p);
P_NetArchiveMisc(resending); P_NetArchiveMisc(resending);
P_NetArchiveEmblems(); P_NetArchiveEmblems();
// Assign the mobjnumber for pointer tracking // Assign the mobjnumber for pointer tracking
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
INT32 mobjnum = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
for (thinker_t *th = w->thlist[THINK_MOBJ].next; th != &w->thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue; continue;
mobj = (mobj_t *)th; mobj_t *mobj = (mobj_t *)th;
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
continue; continue;
mobj->mobjnum = i++; mobj->mobjnum = mobjnum++;
mobj->worldnum = (UINT32)i;
}
} }
P_NetArchivePlayers(); // Assign world numbers to players
if (gamestate == GS_LEVEL) for (i = 0; i < MAXPLAYERS; i++)
{ {
P_NetArchiveWorld(); if (!playeringame[i])
P_ArchivePolyObjects(); continue;
P_NetArchiveThinkers();
P_NetArchiveSpecials(); player_t *player = &players[i];
P_NetArchiveColormaps(); player->worldnum = -1;
P_NetArchiveWaypoints();
for (INT32 w = 0; w < numworlds; w++)
{
if (P_GetPlayerWorld(player) == worldlist[w])
{
player->worldnum = w;
break;
}
} }
}
P_NetArchivePlayers();
if (gamestate == GS_LEVEL)
P_NetArchiveWorlds();
LUA_Archive(); LUA_Archive();
P_ArchiveLuabanksAndConsistency(); P_ArchiveLuabanksAndConsistency();
...@@ -4778,6 +4834,118 @@ boolean P_LoadGame(INT16 mapoverride) ...@@ -4778,6 +4834,118 @@ boolean P_LoadGame(INT16 mapoverride)
return true; return true;
} }
static void UnArchiveWorld(void)
{
unarchiveworld->players = READUINT8(save_p);
P_NetUnArchiveMap();
P_NetUnArchivePolyObjects();
P_NetUnArchiveThinkers();
P_NetUnArchiveSpecials();
P_NetUnArchiveWaypoints();
P_RelinkPointers();
P_FinishMobjs();
}
static void RelinkWorldsToEntities(void)
{
thinker_t *th;
mobj_t *mo;
INT32 i;
for (i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
for (th = w->thlist[THINK_MOBJ].next; th != &w->thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mo = (mobj_t *)th;
if ((INT32)mo->worldnum >= numworlds)
I_Error("RelinkWorldsToEntities: Mobj type %d has unknown world %d", mo->type, mo->worldnum);
if ((INT32)mo->worldnum != i)
I_Error("RelinkWorldsToEntities: Mobj type %d has a world mismatch (mobj: %d, set: %d)", mo->type, mo->worldnum, i);
mo->world = worldlist[mo->worldnum];
R_AddMobjInterpolator(mo);
}
}
// Relink players to their worlds
// This is also done for their mobjs.
for (i = 0; i < MAXPLAYERS; i++)
{
world_t *w;
player_t *player;
if (!playeringame[i])
continue;
player = &players[i];
if (player->worldnum == -1 || player->worldnum >= numworlds)
I_Error("RelinkWorldsToEntities: Player %d (%s) has unknown world %d", i, player_names[i], player->worldnum);
w = worldlist[player->worldnum];
player->world = w;
if (player->mo)
{
player->mo->world = w;
R_AddMobjInterpolator(player->mo);
}
}
}
static void SetUnArchiveWorld(world_t *w)
{
P_SetWorld(w);
unarchiveworld = baseworld = localworld = world;
}
static void P_NetUnArchiveWorlds(void)
{
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
I_Error("Bad $$$.sav at archive block World");
INT32 worldcount = READINT32(save_p);
// initialize colormap vars because paranoia
ClearNetColormaps();
// Unarchive each world
for (INT32 i = 0; i < worldcount; i++)
{
INT16 mapnum = READINT16(save_p);
// Don't load the first world (because it already is loaded at this point)
if (i != 0)
{
if (!P_LoadWorld(mapnum, true))
I_Error("P_NetUnArchiveWorlds: failed loading world");
}
SetUnArchiveWorld(worldlist[i]);
UnArchiveWorld();
}
P_SetWorld(worldlist[0]);
baseworld = localworld = worldlist[0];
curmapheader = nextmapheader = worldmapheader;
P_NetUnArchiveColormaps();
RelinkWorldsToEntities();
// Send a command to switch this player to the first world
// For every other client, the player is on that world, but not for the joiner
if (worldcount > 1)
SendWorldSwitch(0, NULL, true);
}
boolean P_LoadNetGame(boolean reloading) boolean P_LoadNetGame(boolean reloading)
{ {
CV_LoadNetVars(&save_p); CV_LoadNetVars(&save_p);
...@@ -4786,16 +4954,7 @@ boolean P_LoadNetGame(boolean reloading) ...@@ -4786,16 +4954,7 @@ boolean P_LoadNetGame(boolean reloading)
P_NetUnArchiveEmblems(); P_NetUnArchiveEmblems();
P_NetUnArchivePlayers(); P_NetUnArchivePlayers();
if (gamestate == GS_LEVEL) if (gamestate == GS_LEVEL)
{ P_NetUnArchiveWorlds();
P_NetUnArchiveWorld();
P_UnArchivePolyObjects();
P_NetUnArchiveThinkers();
P_NetUnArchiveSpecials();
P_NetUnArchiveColormaps();
P_NetUnArchiveWaypoints();
P_RelinkPointers();
P_FinishMobjs();
}
LUA_UnArchive(); LUA_UnArchive();
// This is stupid and hacky, but maybe it'll work! // This is stupid and hacky, but maybe it'll work!
......