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
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 622-teamlives-hud
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • alien-breed-3d
  • appveyor
  • bbox
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bosszero
  • bustablemobjzfix
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • cmake-clang-tidy
  • cmake-enable-cxx
  • cmake-valgrind
  • crawlacommander-sprites
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • few-kart-lua-changes
  • ffloorclip
  • fix-cvar-conflicts
  • fix-opengl-shear-roll
  • flipfuncpointers
  • floorsprite-and-shadow-fake-planes-fix
  • fof-lightlist-fixes
  • font-FUCK
  • font_drawer
  • frictionrefactor
  • fuck-macros-1
  • fullscreen-toggle
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-packet-tics
  • increasemaxunlockables
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-command-netids
  • lua-local
  • lua-minmax-plus-bruh-moments
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • master
  • menu-edits
  • mobj-dispoffset
  • models-plus-final
  • more-cleanup
  • multithread
  • musicdef-lua
  • net-test
  • netcode-refactor
  • netcode-tests
  • netxcmd-refactor
  • next
  • next-test
  • next-test-2021-7-11
  • nextmapspecialoverride
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
139 results

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
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results
Show changes
......@@ -618,7 +618,7 @@ static int sector_get(lua_State *L)
return 1;
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++)
if (!levelflat->name[i])
break;
......@@ -627,7 +627,7 @@ static int sector_get(lua_State *L)
}
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++)
if (!levelflat->name[i])
break;
......@@ -767,10 +767,10 @@ static int sector_set(lua_State *L)
break;
}
case sector_floorpic:
sector->floorpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
sector->floorpic = P_AddLevelFlatForWorld(sector->world, luaL_checkstring(L, 3));
break;
case sector_ceilingpic:
sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
sector->ceilingpic = P_AddLevelFlatForWorld(sector->world, luaL_checkstring(L, 3));
break;
case sector_lightlevel:
sector->lightlevel = (INT16)luaL_checkinteger(L, 3);
......@@ -1959,7 +1959,7 @@ static int ffloor_get(lua_State *L)
lua_pushfixed(L, *ffloor->topheight);
return 1;
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++)
if (!levelflat->name[i])
break;
......@@ -1973,7 +1973,7 @@ static int ffloor_get(lua_State *L)
lua_pushfixed(L, *ffloor->bottomheight);
return 1;
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++)
if (!levelflat->name[i])
break;
......@@ -2158,7 +2158,7 @@ static int ffloor_set(lua_State *L)
break;
}
case ffloor_toppic:
*ffloor->toppic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
*ffloor->toppic = P_AddLevelFlatForWorld(*ffloor->world, luaL_checkstring(L, 3));
break;
case ffloor_toplightlevel:
*ffloor->toplightlevel = (INT16)luaL_checkinteger(L, 3);
......@@ -2179,7 +2179,7 @@ static int ffloor_set(lua_State *L)
break;
}
case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
*ffloor->bottompic = P_AddLevelFlatForWorld(*ffloor->world, luaL_checkstring(L, 3));
break;
case ffloor_fofflags: {
ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags
......@@ -2854,7 +2854,7 @@ int LUA_MapLib(lua_State *L)
lib_iterateSectors,
lib_getSector,
lib_numsectors,
tags_sectors,
&tags_sectors,
&numsectors, &sectors,
sizeof (sector_t), META_SECTOR);
......@@ -2872,7 +2872,7 @@ int LUA_MapLib(lua_State *L)
lib_iterateLines,
lib_getLine,
lib_numlines,
tags_lines,
&tags_lines,
&numlines, &lines,
sizeof (line_t), META_LINE);
......
......@@ -1151,7 +1151,7 @@ int LUA_MobjLib(lua_State *L)
lib_iterateMapthings,
lib_getMapthing,
lib_nummapthings,
tags_mapthings,
&tags_mapthings,
&nummapthings, &mapthings,
sizeof (mapthing_t), META_MAPTHING);
......
......@@ -368,7 +368,7 @@ static int polyobj_num(lua_State *L)
polyobj_t *polyobj = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
if (!polyobj)
return luaL_error(L, "accessed polyobj_t doesn't exist anymore.");
lua_pushinteger(L, polyobj-PolyObjects);
lua_pushinteger(L, polyobj-world->PolyObjects);
return 1;
}
......@@ -388,10 +388,10 @@ static int lib_iteratePolyObjects(lua_State *L)
lua_settop(L, 2);
lua_remove(L, 1); // state is unused.
if (!lua_isnil(L, 1))
i = (INT32)(*((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)) - PolyObjects);
for (i++; i < numPolyObjects; i++)
i = (INT32)(*((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)) - world->PolyObjects);
for (i++; i < world->numPolyObjects; i++)
{
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ);
LUA_PushUserdata(L, &world->PolyObjects[i], META_POLYOBJ);
return 1;
}
return 0;
......@@ -401,7 +401,7 @@ static int lib_PolyObject_getfornum(lua_State *L)
{
INT32 id = (INT32)luaL_checkinteger(L, 1);
if (!numPolyObjects)
if (!world->numPolyObjects)
return 0; // if there's no PolyObjects then bail out here
LUA_PushUserdata(L, Polyobj_GetForNum(id), META_POLYOBJ);
......@@ -417,9 +417,9 @@ static int lib_getPolyObject(lua_State *L)
if (lua_type(L, 2) == LUA_TNUMBER)
{
i = luaL_checkinteger(L, 2);
if (i < 0 || i >= numPolyObjects)
return luaL_error(L, "polyobjects[] index %d out of range (0 - %d)", i, numPolyObjects-1);
LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ);
if (i < 0 || i >= world->numPolyObjects)
return luaL_error(L, "polyobjects[] index %d out of range (0 - %d)", i, world->numPolyObjects-1);
LUA_PushUserdata(L, &world->PolyObjects[i], META_POLYOBJ);
return 1;
}
......@@ -441,7 +441,7 @@ static int lib_getPolyObject(lua_State *L)
static int lib_numPolyObjects(lua_State *L)
{
lua_pushinteger(L, numPolyObjects);
lua_pushinteger(L, world->numPolyObjects);
return 1;
}
......
......@@ -334,13 +334,13 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, curWeather);
return 1;
} else if (fastcmp(word,"globalweather")) {
lua_pushinteger(L, globalweather);
lua_pushinteger(L, (localworld ? localworld->weather : PRECIP_NONE));
return 1;
} else if (fastcmp(word,"levelskynum")) {
lua_pushinteger(L, levelskynum);
return 1;
} else if (fastcmp(word,"globallevelskynum")) {
lua_pushinteger(L, globallevelskynum);
lua_pushinteger(L, (localworld ? localworld->skynum : 0));
return 1;
} else if (fastcmp(word,"mapmusname")) {
lua_pushstring(L, mapmusname);
......@@ -383,7 +383,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, emeralds);
return 1;
} else if (fastcmp(word,"gravity")) {
lua_pushinteger(L, gravity);
lua_pushinteger(L, world->gravity);
return 1;
} else if (fastcmp(word,"VERSION")) {
lua_pushinteger(L, VERSION);
......@@ -441,7 +441,7 @@ int LUA_CheckGlobals(lua_State *L, const char *word)
else if (fastcmp(word, "token"))
token = (UINT32)luaL_checkinteger(L, 2);
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"))
stoppedclock = luaL_checkboolean(L, 2);
else if (fastcmp(word, "displayplayer"))
......@@ -846,7 +846,7 @@ void LUA_InvalidateUserdata(void *data)
}
// Invalidate level data arrays
void LUA_InvalidateLevel(void)
void LUA_InvalidateLevel(world_t *w)
{
thinker_t *th;
size_t i;
......@@ -854,43 +854,43 @@ void LUA_InvalidateLevel(void)
if (!gL)
return;
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_InvalidateMapthings();
LUA_InvalidateMapthings(w);
for (i = 0; i < numsubsectors; i++)
LUA_InvalidateUserdata(&subsectors[i]);
for (i = 0; i < numsectors; i++)
for (i = 0; i < w->numsubsectors; i++)
LUA_InvalidateUserdata(&w->subsectors[i]);
for (i = 0; i < w->numsectors; i++)
{
LUA_InvalidateUserdata(&sectors[i]);
LUA_InvalidateUserdata(&sectors[i].lines);
LUA_InvalidateUserdata(&sectors[i].tags);
if (sectors[i].ffloors)
LUA_InvalidateUserdata(&w->sectors[i]);
LUA_InvalidateUserdata(&w->sectors[i].lines);
LUA_InvalidateUserdata(&w->sectors[i].tags);
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);
}
}
for (i = 0; i < numlines; i++)
for (i = 0; i < w->numlines; i++)
{
LUA_InvalidateUserdata(&lines[i]);
LUA_InvalidateUserdata(&lines[i].tags);
LUA_InvalidateUserdata(lines[i].args);
LUA_InvalidateUserdata(lines[i].stringargs);
LUA_InvalidateUserdata(lines[i].sidenum);
LUA_InvalidateUserdata(&w->lines[i]);
LUA_InvalidateUserdata(&w->lines[i].tags);
LUA_InvalidateUserdata(w->lines[i].args);
LUA_InvalidateUserdata(w->lines[i].stringargs);
LUA_InvalidateUserdata(w->lines[i].sidenum);
}
for (i = 0; i < numsides; i++)
LUA_InvalidateUserdata(&sides[i]);
for (i = 0; i < numvertexes; i++)
LUA_InvalidateUserdata(&vertexes[i]);
for (i = 0; i < (size_t)numPolyObjects; i++)
for (i = 0; i < w->numsides; i++)
LUA_InvalidateUserdata(&w->sides[i]);
for (i = 0; i < w->numvertexes; i++)
LUA_InvalidateUserdata(&w->vertexes[i]);
for (i = 0; i < (size_t)w->numPolyObjects; i++)
{
LUA_InvalidateUserdata(&PolyObjects[i]);
LUA_InvalidateUserdata(&PolyObjects[i].vertices);
LUA_InvalidateUserdata(&PolyObjects[i].lines);
LUA_InvalidateUserdata(&w->PolyObjects[i]);
LUA_InvalidateUserdata(&w->PolyObjects[i].vertices);
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->normal);
......@@ -898,29 +898,29 @@ void LUA_InvalidateLevel(void)
LUA_InvalidateUserdata(&slope->d);
}
#ifdef HAVE_LUA_SEGS
for (i = 0; i < numsegs; i++)
LUA_InvalidateUserdata(&segs[i]);
for (i = 0; i < numnodes; i++)
for (i = 0; i < w->numsegs; i++)
LUA_InvalidateUserdata(&w->segs[i]);
for (i = 0; i < w->numnodes; i++)
{
LUA_InvalidateUserdata(&nodes[i]);
LUA_InvalidateUserdata(nodes[i].bbox);
LUA_InvalidateUserdata(nodes[i].children);
LUA_InvalidateUserdata(&w->nodes[i]);
LUA_InvalidateUserdata(w->nodes[i].bbox);
LUA_InvalidateUserdata(w->nodes[i].children);
}
#endif
}
void LUA_InvalidateMapthings(void)
void LUA_InvalidateMapthings(world_t *w)
{
size_t i;
if (!gL)
return;
for (i = 0; i < nummapthings; i++)
for (i = 0; i < w->nummapthings; i++)
{
LUA_InvalidateUserdata(&mapthings[i]);
LUA_InvalidateUserdata(&mapthings[i].tags);
LUA_InvalidateUserdata(mapthings[i].args);
LUA_InvalidateUserdata(mapthings[i].stringargs);
LUA_InvalidateUserdata(&w->mapthings[i]);
LUA_InvalidateUserdata(&w->mapthings[i].tags);
LUA_InvalidateUserdata(w->mapthings[i].args);
LUA_InvalidateUserdata(w->mapthings[i].stringargs);
}
}
......@@ -1274,7 +1274,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, ARCH_NULL);
else {
WRITEUINT8(save_p, ARCH_POLYOBJ);
WRITEUINT16(save_p, polyobj-PolyObjects);
WRITEUINT16(save_p, polyobj-archiveworld->PolyObjects);
}
break;
}
......@@ -1505,40 +1505,40 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
LUA_PushUserdata(gL, &states[READUINT16(save_p)], META_STATE);
break;
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;
case ARCH_PLAYER:
LUA_PushUserdata(gL, &players[READUINT8(save_p)], META_PLAYER);
break;
case ARCH_MAPTHING:
LUA_PushUserdata(gL, &mapthings[READUINT16(save_p)], META_MAPTHING);
LUA_PushUserdata(gL, &archiveworld->mapthings[READUINT16(save_p)], META_MAPTHING);
break;
case ARCH_VERTEX:
LUA_PushUserdata(gL, &vertexes[READUINT16(save_p)], META_VERTEX);
LUA_PushUserdata(gL, &archiveworld->vertexes[READUINT16(save_p)], META_VERTEX);
break;
case ARCH_LINE:
LUA_PushUserdata(gL, &lines[READUINT16(save_p)], META_LINE);
LUA_PushUserdata(gL, &archiveworld->lines[READUINT16(save_p)], META_LINE);
break;
case ARCH_SIDE:
LUA_PushUserdata(gL, &sides[READUINT16(save_p)], META_SIDE);
LUA_PushUserdata(gL, &archiveworld->sides[READUINT16(save_p)], META_SIDE);
break;
case ARCH_SUBSECTOR:
LUA_PushUserdata(gL, &subsectors[READUINT16(save_p)], META_SUBSECTOR);
LUA_PushUserdata(gL, &archiveworld->subsectors[READUINT16(save_p)], META_SUBSECTOR);
break;
case ARCH_SECTOR:
LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_SECTOR);
LUA_PushUserdata(gL, &archiveworld->sectors[READUINT16(save_p)], META_SECTOR);
break;
#ifdef HAVE_LUA_SEGS
case ARCH_SEG:
LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG);
LUA_PushUserdata(gL, &archiveworld->segs[READUINT16(save_p)], META_SEG);
break;
case ARCH_NODE:
LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE);
LUA_PushUserdata(gL, &archiveworld->nodes[READUINT16(save_p)], META_NODE);
break;
#endif
case ARCH_FFLOOR:
{
sector_t *sector = &sectors[READUINT16(save_p)];
sector_t *sector = &archiveworld->sectors[READUINT16(save_p)];
UINT16 id = READUINT16(save_p);
ffloor_t *rover = P_GetFFloorByID(sector, id);
if (rover)
......@@ -1546,10 +1546,10 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
break;
}
case ARCH_POLYOBJ:
LUA_PushUserdata(gL, &PolyObjects[READUINT16(save_p)], META_POLYOBJ);
LUA_PushUserdata(gL, &archiveworld->PolyObjects[READUINT16(save_p)], META_POLYOBJ);
break;
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;
case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
......@@ -1768,7 +1768,7 @@ void LUA_PushTaggableObjectArray
lua_CFunction iterator,
lua_CFunction indexer,
lua_CFunction counter,
taggroup_t *garray[],
taggroup_t **garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
......
......@@ -17,6 +17,7 @@
#include "doomtype.h"
#include "d_player.h"
#include "g_state.h"
#include "p_world.h"
#include "taglist.h"
#include "blua/lua.h"
......@@ -67,7 +68,7 @@ void LUA_PushTaggableObjectArray
lua_CFunction iterator,
lua_CFunction indexer,
lua_CFunction counter,
taggroup_t *garray[],
taggroup_t **garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
......@@ -75,7 +76,7 @@ void LUA_PushTaggableObjectArray
void LUA_InsertTaggroupIterator
( lua_State *L,
taggroup_t *garray[],
taggroup_t **garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
......@@ -92,8 +93,8 @@ lpushed_t LUA_RawPushUserdata(lua_State *L, void *data);
void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);
void LUA_InvalidateMapthings(void);
void LUA_InvalidateLevel(world_t *w);
void LUA_InvalidateMapthings(world_t *w);
void LUA_InvalidatePlayer(player_t *player);
// Console wrapper
......
......@@ -334,13 +334,13 @@ static const char *const sprites_opt[] = {
// skin.sprites[i] -> sprites[i]
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);
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);
LUA_PushUserdata(L, &sprites[i], META_SKINSPRITESLIST);
LUA_PushUserdata(L, &skinsprites[i], META_SKINSPRITESLIST);
return 1;
}
......
......@@ -29,7 +29,7 @@ static int tag_iterator(lua_State *L)
if (++tag >= MAXTAGS)
return 0;
}
while (! in_bit_array(tags_available, tag)) ;
while (! in_bit_array(world->tags_available, tag)) ;
lua_pushnumber(L, tag);
return 1;
}
......@@ -46,9 +46,9 @@ enum {
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);
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)
......@@ -95,7 +95,7 @@ static int lib_iterateTags(lua_State *L)
static int lib_numTags(lua_State *L)
{
lua_pushnumber(L, num_tags);
lua_pushnumber(L, world->num_tags);
return 1;
}
......@@ -150,8 +150,8 @@ static int lib_numTaggroupElements(lua_State *L)
lua_pushnumber(L, *(size_t *)lua_touserdata(L, up_max_elements));
else
{
const taggroup_t ** garray = lua_touserdata(L, up_garray);
lua_pushnumber(L, Taggroup_Count(garray[tag]));
const taggroup_t *** garray = lua_touserdata(L, up_garray);
lua_pushnumber(L, Taggroup_Count((*garray)[tag]));
}
return 1;
}
......@@ -313,7 +313,7 @@ static int taglist_add(lua_State *L)
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);
}
......@@ -337,7 +337,7 @@ static int taglist_remove(lua_State *L)
(list->count - 1 - i) * sizeof (mtag_t));
list->tags = Z_Realloc(list->tags,
(--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 */
Tag_SectorFSet(sector_of_taglist(list), 0);
......@@ -351,7 +351,7 @@ static int taglist_remove(lua_State *L)
void LUA_InsertTaggroupIterator
( lua_State *L,
taggroup_t *garray[],
taggroup_t **garray[],
size_t * max_elements,
void * element_array,
size_t sizeof_element,
......
......@@ -513,13 +513,13 @@ void Command_Teleport_f(void)
mapthing_t *mt;
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;
}
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;
inty = mt->y<<FRACBITS;
offset = mt->z<<FRACBITS;
......@@ -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)
{
mapthing_t *mt = mapthings;
mapthing_t *mt = world->mapthings;
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
// the spawnpoints of any objects that have them to the new location
if (mt != mapthings)
if (mt != world->mapthings)
{
thinker_t *th;
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)
continue;
......@@ -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
if (!mo->spawnpoint)
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->x = (INT16)(player->mo->x>>FRACBITS);
......
......@@ -4716,10 +4716,10 @@ static void M_DrawPauseMenu(void)
// Draw any and all emblems at the top.
M_DrawMapEmblems(gamemap, 272, 28, true);
if (mapheaderinfo[gamemap-1]->actnum != 0)
V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum));
if (curmapheader->actnum != 0)
V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", curmapheader->lvlttl, curmapheader->actnum));
else
V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl);
V_DrawString(40, 28, V_YELLOWMAP, curmapheader->lvlttl);
// 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
else
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",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : "");
worldmapheader->lvlttl,
(worldmapheader->levelflags & LF_NOZONE) ? "" : " Zone",
(worldmapheader->actnum > 0) ? va(" %d", worldmapheader->actnum) : "");
else
snprintf(lvlttltext, 48, "Unknown");
......
......@@ -756,6 +756,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
if (player->quittime)
continue; // Ignore uncontrolled bodies
if (P_GetPlayerWorld(player) != actor->world)
continue; // Different world
if (dist > 0
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
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
actor->momx = FixedMul(FixedDiv(x, dh), speed);
actor->momy = FixedMul(FixedDiv(y, dh), speed);
if (!gravity)
if (!world->gravity)
return;
dh = FixedDiv(FixedMul(dh, gravity), speed);
dh = FixedDiv(FixedMul(dh, world->gravity), speed);
actor->momz = (dh>>1) + FixedDiv(z, dh<<1);
}
......@@ -2728,7 +2731,7 @@ void A_LobShot(mobj_t *actor)
dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y);
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->momy = FixedMul(horizontal, FINESINE(an));
......@@ -2750,7 +2753,7 @@ void A_LobShot(mobj_t *actor)
CONS_Debug(DBG_GAMELOGIC, "orig: %d\n", (orig)>>FRACBITS);
horizontal = dist / airtime;
vertical = (gravity*airtime)/2;
vertical = (world->gravity*airtime)/2;
}
dist -= orig;
shot->momx = FixedMul(horizontal, FINECOSINE(an));
......@@ -3964,26 +3967,26 @@ static void P_DoBossVictory(mobj_t *mo)
EV_DoElevator(LE_CAPSULE2, NULL, elevateHighest);
}
if (mapheaderinfo[gamemap-1]->muspostbossname[0] &&
S_MusicExists(mapheaderinfo[gamemap-1]->muspostbossname, !midi_disabled, !digital_disabled))
if (worldmapheader->muspostbossname[0] &&
S_MusicExists(worldmapheader->muspostbossname, !midi_disabled, !digital_disabled))
{
// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
// 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).
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7);
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7))
boolean changed = strnicmp(worldmapheader->musname, S_MusicName(), 7);
if (!strnicmp(worldmapheader->musname, mapmusname, 7))
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
strncpy(mapmusname, worldmapheader->muspostbossname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos;
mapmusflags = (worldmapheader->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
mapmusposition = worldmapheader->muspostbosspos;
}
// 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
if (!changed)
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)
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);
else
P_PlayJingle(player, JT_SHOES);
......@@ -11588,7 +11591,7 @@ void A_BrakLobShot(mobj_t *actor)
return; // Don't even bother if we've got nothing to aim at.
// 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
x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y);
......@@ -11703,7 +11706,7 @@ void A_NapalmScatter(mobj_t *actor)
airtime = 16<<FRACBITS;
// 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 = FixedMul(g,(airtime-(1<<FRACBITS)))>>1;
......@@ -11758,12 +11761,12 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
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;
else
{
INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numFlickies);
flickytype = mapheaderinfo[gamemap-1]->flickies[prandom];
INT32 prandom = P_RandomKey(worldmapheader->numFlickies);
flickytype = worldmapheader->flickies[prandom];
}
}
......@@ -12413,7 +12416,7 @@ void A_Boss5Jump(mobj_t *actor)
return; // Don't even bother if we've got nothing to aim at.
// 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
x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y);
......@@ -12516,10 +12519,10 @@ void A_MineExplode(mobj_t *actor)
A_Scream(actor);
actor->flags = MF_NOGRAVITY|MF_NOCLIP;
quake.epicenter = NULL;
quake.radius = 512*FRACUNIT;
quake.intensity = 8*FRACUNIT;
quake.time = TICRATE/3;
world->quake.epicenter = NULL;
world->quake.radius = 512*FRACUNIT;
world->quake.intensity = 8*FRACUNIT;
world->quake.time = TICRATE/3;
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF, true);
P_MobjCheckWater(actor);
......@@ -12937,7 +12940,7 @@ void A_Boss5FindWaypoint(mobj_t *actor)
}
// 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;
// now find them again and add them to the table!
......@@ -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_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
quake.intensity = 9*actor->scale;
quake.time = TICRATE/6;
world->quake.intensity = 9*actor->scale;
world->quake.time = TICRATE/6;
// 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};
quake.epicenter = &q_epicenter;
world->quake.epicenter = &q_epicenter;
}
quake.radius = 20*actor->radius;
world->quake.radius = 20*actor->radius;
}
static mobj_t *dustdevil;
......@@ -13782,10 +13785,10 @@ void A_TNTExplode(mobj_t *actor)
epicenter.x = actor->x;
epicenter.y = actor->y;
epicenter.z = actor->z;
quake.intensity = 9*FRACUNIT;
quake.time = TICRATE/6;
quake.epicenter = &epicenter;
quake.radius = 512*FRACUNIT;
world->quake.intensity = 9*FRACUNIT;
world->quake.time = TICRATE/6;
world->quake.epicenter = &epicenter;
world->quake.radius = 512*FRACUNIT;
if (locvar1)
{
......
......@@ -525,7 +525,7 @@ void T_ContinuousFalling(continuousfall_t *faller)
faller->sector->ceilingheight = faller->ceilingstartheight;
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
......@@ -689,7 +689,7 @@ void T_BounceCheese(bouncecheese_t *bouncer)
}
else if (bouncer->sector->ceilingheight > bouncer->ceilingwasheight) // Up
{
bouncer->speed += gravity;
bouncer->speed += world->gravity;
}
if (abs(bouncer->speed) < 2*FRACUNIT
......@@ -838,7 +838,7 @@ void T_StartCrumble(crumble_t *crumble)
// Only fall like this if it isn't meant to float on water
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)
|| ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT))
......
......@@ -725,18 +725,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
break;
// Emerald Hunt
case MT_EMERHUNT:
case MT_EMERHUNT: {
unsigned remaining_emeralds = 0;
if (player->bot && player->bot != BOT_MPAI)
return;
if (hunt1 == special)
hunt1 = NULL;
else if (hunt2 == special)
hunt2 = NULL;
else if (hunt3 == special)
hunt3 = NULL;
for (i = 0; i < NUM_EMERALD_HUNT_LOCATIONS; i++)
{
if (world->emerald_hunt_locations[i])
{
if (world->emerald_hunt_locations[i] == special)
P_SetTarget(&world->emerald_hunt_locations[i], NULL);
else
remaining_emeralds++;
}
}
if (!hunt1 && !hunt2 && !hunt3)
if (!remaining_emeralds)
{
for (i = 0; i < MAXPLAYERS; i++)
{
......@@ -748,7 +754,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
//S_StartSound(NULL, sfx_lvpass);
}
break;
}
// Collectible emeralds
case MT_EMERALD1:
case MT_EMERALD2:
......@@ -1678,9 +1684,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetObjectMomZ(toucher, FixedDiv(69*FRACUNIT,10*FRACUNIT), false);
if (P_IsLocalPlayer(player))
{
quake.intensity = 9*FRACUNIT;
quake.time = TICRATE/2;
quake.epicenter = NULL;
world->quake.intensity = 9*FRACUNIT;
world->quake.time = TICRATE/2;
world->quake.epicenter = NULL;
}
#if 0 // camera redirection - deemed unnecessary
......@@ -3149,7 +3155,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)
{
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if ((worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
#ifdef _WIN32
// win32 MIDI volume hack means we cannot fade down the music
&& S_MusicType() != MU_MID
......@@ -3605,7 +3611,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)
{
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if (worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
{
S_FadeMusic(0, 10*MUSICRATE);
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.
......
......@@ -22,6 +22,8 @@
#include "p_tick.h"
#include "r_defs.h"
#include "p_maputl.h"
#include "p_setup.h"
#include "p_world.h"
#define FLOATSPEED (FRACUNIT*4)
......@@ -70,11 +72,13 @@ typedef enum
THINK_PRECIP,
NUM_THINKERLISTS
} 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_RemoveThinker(thinker_t *thinker);
void P_MoveThinkerToWorld(world_t *w, const thinklistnum_t n, thinker_t *thinker);
//
// P_USER
......@@ -205,8 +209,8 @@ boolean P_SuperReady(player_t *player);
void P_DoJump(player_t *player, boolean soundandstate);
#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG)
boolean P_TransferToNextMare(player_t *player);
UINT8 P_FindLowestMare(void);
void P_FindEmerald(void);
UINT8 P_FindLowestMare(world_t *w);
void P_FindEmerald(world_t *w);
void P_TransferToAxis(player_t *player, INT32 axisnum);
boolean P_PlayerMoving(INT32 pnum);
void P_SpawnThokMobj(player_t *player);
......@@ -269,31 +273,24 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b
#define ONFLOORZ INT32_MIN
#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;
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);
void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void);
void P_PrecipitationEffects(world_t *w);
void P_RemoveMobj(mobj_t *th);
boolean P_MobjWasRemoved(mobj_t *th);
void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void);
void P_RunOverlays(void);
void P_RunShields(world_t *w);
void P_RunOverlays(world_t *w);
void P_HandleMinecartSegments(mobj_t *mobj);
void P_MobjThinker(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
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_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_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, 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, 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_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_CameraCeilingZ(camera_t *mobj, 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_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, 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_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
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 *cam, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_CameraGetFloorZ(cam, sector, x, y, line) P_CameraFloorZ(cam, sector, NULL, x, y, line, false, false)
#define P_CameraGetCeilingZ(cam, sector, x, y, line) P_CameraCeilingZ(cam, sector, NULL, x, y, line, true, 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(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_CheckDeathPitCollide(mobj_t *mo);
......@@ -339,6 +336,8 @@ FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
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);
mobj_t *P_GetClosestAxis(mobj_t *source);
......
......@@ -3388,7 +3388,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
floorclimb = true;
if ((floorz > mo->z)
&& glidesector->floorpic == skyflatnum)
&& glidesector->floorpic == world->skyflatnum)
return false;
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)
floorclimb = true;
if ((ceilingz < mo->z+mo->height)
&& glidesector->ceilingpic == skyflatnum)
&& glidesector->ceilingpic == world->skyflatnum)
return false;
if ((mo->z + FixedMul(16*FRACUNIT,mo->scale) < floorz)
......
......@@ -19,6 +19,7 @@
#include "hu_stuff.h"
#include "p_local.h"
#include "p_setup.h"
#include "p_world.h"
#include "r_fps.h"
#include "r_main.h"
#include "r_skins.h"
......@@ -40,43 +41,6 @@
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);
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
//
......@@ -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
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)
{
if (!mo->player)
......@@ -1465,7 +1437,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
if (!gravsector) // If there is no 3D floor gravity, check sector's gravity
gravsector = mo->subsector->sector;
gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(gravsector));
gravityadd = -FixedMul(world->gravity, P_GetSectorGravityFactor(gravsector));
if ((gravsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0)
{
......@@ -1756,9 +1728,9 @@ bustupdone:
static boolean P_CheckSkyHit(mobj_t *mo)
{
if (ceilingline && ceilingline->backsector
&& ceilingline->backsector->ceilingpic == skyflatnum
&& ceilingline->backsector->ceilingpic == world->skyflatnum
&& ceilingline->frontsector
&& ceilingline->frontsector->ceilingpic == skyflatnum
&& ceilingline->frontsector->ceilingpic == world->skyflatnum
&& (mo->z >= ceilingline->frontsector->ceilingheight
|| mo->z >= ceilingline->backsector->ceilingheight))
return true;
......@@ -2599,11 +2571,11 @@ boolean P_ZMovement(mobj_t *mo)
{
// Don't explode on the sky!
if (!(mo->eflags & MFE_VERTICALFLIP)
&& mo->subsector->sector->floorpic == skyflatnum
&& mo->subsector->sector->floorpic == world->skyflatnum
&& mo->subsector->sector->floorheight == mo->floorz)
P_RemoveMobj(mo);
else if (mo->eflags & MFE_VERTICALFLIP
&& mo->subsector->sector->ceilingpic == skyflatnum
&& mo->subsector->sector->ceilingpic == world->skyflatnum
&& mo->subsector->sector->ceilingheight == mo->ceilingz)
P_RemoveMobj(mo);
else
......@@ -2747,11 +2719,11 @@ boolean P_ZMovement(mobj_t *mo)
{
// Don't explode on the sky!
if (!(mo->eflags & MFE_VERTICALFLIP)
&& mo->subsector->sector->ceilingpic == skyflatnum
&& mo->subsector->sector->ceilingpic == world->skyflatnum
&& mo->subsector->sector->ceilingheight == mo->ceilingz)
P_RemoveMobj(mo);
else if (mo->eflags & MFE_VERTICALFLIP
&& mo->subsector->sector->floorpic == skyflatnum
&& mo->subsector->sector->floorpic == world->skyflatnum
&& mo->subsector->sector->floorheight == mo->floorz)
P_RemoveMobj(mo);
else
......@@ -3240,8 +3212,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|| ((rover->fofflags & FOF_BLOCKOTHERS) && !mobj->player)))
continue;
topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, sector);
bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, sector);
topheight = P_GetSpecialTopZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, sector);
bottomheight = P_GetSpecialBottomZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, sector);
if (mobj->eflags & MFE_VERTICALFLIP)
{
......@@ -3656,6 +3628,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
{ // Never fails for 2D mode.
mobj_t dummy;
dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker;
dummy.world = thiscam->subsector->sector->world;
dummy.subsector = thiscam->subsector;
dummy.x = thiscam->x;
dummy.y = thiscam->y;
......@@ -3761,12 +3734,12 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj)
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;
}
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;
}
......@@ -4192,6 +4165,9 @@ boolean P_SupermanLook4Players(mobj_t *actor)
if (players[c].mo->health <= 0)
continue; // dead
if (players[c].world != actor->world)
continue; // Different world
playersinthegame[stop] = &players[c];
stop++;
}
......@@ -5352,7 +5328,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y);
horizontal = dist / airtime;
vertical = (gravity*airtime)/2;
vertical = (world->gravity*airtime)/2;
mobj->momx = FixedMul(horizontal, FINECOSINE(an));
mobj->momy = FixedMul(horizontal, FINESINE(an));
......@@ -5480,7 +5456,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
{
P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT);
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))
{
mobj->watertop = mobj->floorz + 32*FRACUNIT;
......@@ -6756,21 +6732,16 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
return true;
}
mobj_t *shields[MAXPLAYERS*2];
INT32 numshields = 0;
void P_RunShields(void)
void P_RunShields(world_t *w)
{
INT32 i;
// run shields
for (i = 0; i < numshields; i++)
for (INT32 i = 0; i < w->numshields; i++)
{
if (!P_MobjWasRemoved(shields[i]))
P_ShieldLook(shields[i], shields[i]->threshold);
P_SetTarget(&shields[i], NULL);
if (!P_MobjWasRemoved(w->shields[i]))
P_ShieldLook(w->shields[i], w->shields[i]->threshold);
P_SetTarget(&w->shields[i], NULL);
}
numshields = 0;
w->numshields = 0;
}
static boolean P_AddShield(mobj_t *thing)
......@@ -6800,20 +6771,20 @@ static boolean P_AddShield(mobj_t *thing)
}
// Queue has been hit... why?!?
if (numshields >= MAXPLAYERS*2)
if (world->numshields >= MAXPLAYERS*2)
return P_ShieldLook(thing, thing->info->speed);
P_SetTarget(&shields[numshields++], thing);
P_SetTarget(&world->shields[world->numshields++], thing);
return true;
}
void P_RunOverlays(void)
void P_RunOverlays(world_t *w)
{
// run overlays
mobj_t *mo, *next = NULL;
fixed_t destx,desty,zoffs;
for (mo = overlaycap; mo; mo = next)
for (mo = w->overlaycap; mo; mo = next)
{
I_Assert(!P_MobjWasRemoved(mo));
......@@ -6878,7 +6849,7 @@ void P_RunOverlays(void)
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
}
P_SetTarget(&overlaycap, NULL);
P_SetTarget(&w->overlaycap, NULL);
}
// Called only when MT_OVERLAY thinks.
......@@ -6886,11 +6857,11 @@ static void P_AddOverlay(mobj_t *thing)
{
I_Assert(thing != NULL);
if (overlaycap == NULL)
P_SetTarget(&overlaycap, thing);
if (world->overlaycap == NULL)
P_SetTarget(&world->overlaycap, thing);
else {
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);
......@@ -6906,14 +6877,14 @@ static void P_AddOverlay(mobj_t *thing)
static void P_RemoveOverlay(mobj_t *thing)
{
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);
return;
}
for (mo = overlaycap; mo; mo = mo->hnext)
for (mo = world->overlaycap; mo; mo = mo->hnext)
{
if (mo->hnext != thing)
continue;
......@@ -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
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)
{
P_RemoveMobj(mobj);
......@@ -10158,13 +10129,13 @@ void P_MobjThinker(mobj_t *mobj)
return;
// Remove dead target/tracer.
if (mobj->target && P_MobjWasRemoved(mobj->target))
if (!P_MobjIsConnected(mobj, mobj->target))
P_SetTarget(&mobj->target, NULL);
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
if (!P_MobjIsConnected(mobj, mobj->tracer))
P_SetTarget(&mobj->tracer, NULL);
if (mobj->hnext && P_MobjWasRemoved(mobj->hnext))
if (!P_MobjIsConnected(mobj, mobj->hnext))
P_SetTarget(&mobj->hnext, NULL);
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
if (!P_MobjIsConnected(mobj, mobj->hprev))
P_SetTarget(&mobj->hprev, NULL);
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)
mobj->x = x;
mobj->y = y;
mobj->world = world;
mobj->radius = info->radius;
mobj->height = info->height;
mobj->flags = info->flags;
......@@ -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
if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC))
{
if (levelloading)
if (world->loading)
{
// Cache actions in a linked list
// with function pointer, and
// var1 & var2, which will be executed
// when the level finishes loading.
P_AddCachedAction(mobj, mobj->info->spawnstate);
P_AddCachedAction(world, mobj, mobj->info->spawnstate);
}
else
{
......@@ -11008,6 +10981,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->x = x;
mobj->y = y;
mobj->flags = mobjinfo[type].flags;
mobj->world = world;
// do not set the state with P_SetMobjState,
// 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
mobj->precipflags |= PCF_FOF;
else if (mobj->subsector->sector->damagetype == SD_DEATHPITNOTILT
|| mobj->subsector->sector->damagetype == SD_DEATHPITTILT
|| mobj->subsector->sector->floorpic == skyflatnum)
|| mobj->subsector->sector->floorpic == world->skyflatnum)
mobj->precipflags |= PCF_PIT;
R_ResetPrecipitationMobjInterpolationState(mobj);
......@@ -11082,9 +11056,6 @@ void P_RemoveFloorSpriteSlope(mobj_t *mobj)
//
// P_RemoveMobj
//
mapthing_t *itemrespawnque[ITEMQUESIZE];
tic_t itemrespawntime[ITEMQUESIZE];
size_t iquehead, iquetail;
#ifdef PARANOIA
#define SCRAMBLE_REMOVED // Force debug build to crash when Removed mobj is accessed
......@@ -11109,12 +11080,12 @@ void P_RemoveMobj(mobj_t *mobj)
|| P_WeaponOrPanel(mobj->type))
&& !(mobj->flags2 & MF2_DONTRESPAWN))
{
itemrespawnque[iquehead] = mobj->spawnpoint;
itemrespawntime[iquehead] = leveltime;
iquehead = (iquehead+1)&(ITEMQUESIZE-1);
world->itemrespawnque[world->iquehead] = mobj->spawnpoint;
world->itemrespawntime[world->iquehead] = leveltime;
world->iquehead = (world->iquehead+1)&(ITEMQUESIZE-1);
// lose one off the end?
if (iquehead == iquetail)
iquetail = (iquetail+1)&(ITEMQUESIZE-1);
if (world->iquehead == world->iquetail)
world->iquetail = (world->iquetail+1)&(ITEMQUESIZE-1);
}
if (mobj->type == MT_OVERLAY)
......@@ -11158,14 +11129,14 @@ void P_RemoveMobj(mobj_t *mobj)
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.
#ifdef SCRAMBLE_REMOVED
// Invalidate mobj_t data to cause crashes if accessed!
memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t));
#endif
R_RemoveMobjInterpolator(mobj);
// free block
if (!mobj->thinker.next)
{ // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through!
......@@ -11291,7 +11262,7 @@ void P_SpawnPrecipitation(void)
if (curWeather == PRECIP_SNOW)
{
// 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;
rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE);
......@@ -11304,7 +11275,7 @@ void P_SpawnPrecipitation(void)
else // everything else.
{
// 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;
rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN);
......@@ -11321,7 +11292,7 @@ void P_SpawnPrecipitation(void)
//
// P_PrecipitationEffects
//
void P_PrecipitationEffects(void)
void P_PrecipitationEffects(world_t *w)
{
INT16 thunderchance = INT16_MAX;
INT32 volume;
......@@ -11338,8 +11309,8 @@ void P_PrecipitationEffects(void)
// with global rain and switched players to anything else ...
// If the global weather has lightning strikes,
// EVERYONE gets them at the SAME time!
else if (globalweather == PRECIP_STORM
|| globalweather == PRECIP_STORM_NORAIN)
else if (w->weather == PRECIP_STORM
|| w->weather == PRECIP_STORM_NORAIN)
thunderchance = (P_RandomKey(8192));
// But on the other hand, if the global weather is ANYTHING ELSE,
// don't sync lightning strikes.
......@@ -11374,8 +11345,8 @@ void P_PrecipitationEffects(void)
{
sector_t *ss = sectors;
for (i = 0; i < numsectors; i++, ss++)
if (ss->ceilingpic == skyflatnum) // Only for the sky.
for (i = 0; i < w->numsectors; i++, ss++)
if (ss->ceilingpic == w->skyflatnum) // Only for the sky.
P_SpawnLightningFlash(ss); // Spawn a quick flash thinker
}
......@@ -11387,7 +11358,7 @@ void P_PrecipitationEffects(void)
if (sound_disabled)
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.
else
{
......@@ -11403,7 +11374,7 @@ void P_PrecipitationEffects(void)
for (y = yl; y <= yh; y += 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);
if (newdist < closedist)
......@@ -11456,7 +11427,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype)
//
// P_RespawnSpecials
//
void P_RespawnSpecials(void)
void P_RespawnSpecials(world_t *w)
{
mapthing_t *mthing = NULL;
......@@ -11471,15 +11442,15 @@ void P_RespawnSpecials(void)
return;
// nothing left to respawn?
if (iquehead == iquetail)
if (w->iquehead == w->iquetail)
return;
// the first item in the queue is the first to respawn
// 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;
mthing = itemrespawnque[iquetail];
mthing = w->itemrespawnque[w->iquetail];
#ifdef PARANOIA
if (!mthing)
......@@ -11490,7 +11461,7 @@ void P_RespawnSpecials(void)
P_SpawnMapThing(mthing);
// 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)
void P_SpawnPlayer(INT32 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)
G_PlayerReborn(playernum, false);
......@@ -11569,7 +11543,8 @@ void P_SpawnPlayer(INT32 playernum)
if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS))
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->angle = 0;
......@@ -11633,6 +11608,9 @@ void P_SpawnPlayer(INT32 playernum)
// Spawn with a pity shield if necessary.
P_DoPityCheck(p);
// Restore the current world
P_SetWorld(curworld);
}
void P_AfterPlayerSpawn(INT32 playernum)
......@@ -11908,42 +11886,42 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
{
// save spots for respawning in network games
if (!metalrecording)
playerstarts[mthing->type - 1] = mthing;
world->playerstarts[mthing->type - 1] = mthing;
return true;
}
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;
numdmstarts++;
world->numdmstarts++;
}
return true;
}
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;
numredctfstarts++;
world->numredctfstarts++;
}
return true;
}
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;
numbluectfstarts++;
world->numbluectfstarts++;
}
return true;
}
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.
playerstarts[0] = mthing;
world->playerstarts[0] = mthing;
return true;
}
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
}
if (mthing->args[0])
skyboxcenterpnts[tag] = mobj;
world->skyboxcenterpnts[tag] = mobj;
else
skyboxviewpnts[tag] = mobj;
world->skyboxviewpnts[tag] = mobj;
break;
}
case MT_EGGSTATUE:
......@@ -14107,6 +14085,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
if (!newmobj)
return NULL;
newmobj->world = mobj->world;
if (mobj->eflags & MFE_VERTICALFLIP)
{
fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale);
......
......@@ -310,6 +310,8 @@ typedef struct mobj_s
struct subsector_s *subsector; // Subsector the mobj resides in.
void *world; // current world
// The closest interval over all contacted sectors (or things).
fixed_t floorz; // Nearest floor below.
fixed_t ceilingz; // Nearest ceiling above.
......@@ -376,7 +378,9 @@ typedef struct mobj_s
fixed_t watertop; // top 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 old_scale; // interpolation
......@@ -447,6 +451,8 @@ typedef struct precipmobj_s
struct subsector_s *subsector; // Subsector the mobj resides in.
void *world; // current world
// The closest interval over all contacted sectors (or things).
fixed_t floorz; // Nearest floor below.
fixed_t ceilingz; // Nearest ceiling above.
......@@ -466,20 +472,6 @@ typedef struct precipmobj_s
INT32 flags; // flags from mobjinfo tables
} 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
void P_MobjCheckWater(mobj_t *mobj);
......
......@@ -87,22 +87,9 @@
// Globals
//
// The Polyobjects
polyobj_t *PolyObjects;
INT32 numPolyObjects;
// Polyobject Blockmap -- initialized in P_LoadBlockMap
polymaplink_t **polyblocklinks;
//
// Static Data
//
// Polyobject Blockmap
static polymaplink_t *bmap_freelist; // free list of blockmap links
//
// Static Functions
//
......@@ -470,7 +457,7 @@ newseg:
static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
{
size_t i;
polyobj_t *po = &PolyObjects[num];
polyobj_t *po = &world->PolyObjects[num];
// don't spawn a polyobject more than once
if (po->segCount)
......@@ -542,9 +529,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
}
else
{
INT32 hashkey = po->id % numPolyObjects;
po->next = PolyObjects[hashkey].first;
PolyObjects[hashkey].first = num;
INT32 hashkey = po->id % world->numPolyObjects;
po->next = world->PolyObjects[hashkey].first;
world->PolyObjects[hashkey].first = num;
}
}
......@@ -651,10 +638,10 @@ static polymaplink_t *Polyobj_getLink(void)
{
polymaplink_t *l;
if (bmap_freelist)
if (world->po_bmap_freelist)
{
l = bmap_freelist;
bmap_freelist = (polymaplink_t *)(l->link.next);
l = world->po_bmap_freelist;
world->po_bmap_freelist = (polymaplink_t *)(l->link.next);
}
else
{
......@@ -669,8 +656,8 @@ static polymaplink_t *Polyobj_getLink(void)
static void Polyobj_putLink(polymaplink_t *l)
{
memset(l, 0, sizeof(*l));
l->link.next = (mdllistitem_t *)bmap_freelist;
bmap_freelist = l;
l->link.next = (mdllistitem_t *)world->po_bmap_freelist;
world->po_bmap_freelist = l;
}
// 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
// Returns NULL if no such polyobject exists.
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)
curidx = PolyObjects[curidx].next;
while (curidx != world->numPolyObjects && world->PolyObjects[curidx].id != id)
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)
// sorta like P_FindSectorSpecialFromTag.
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)
return &PolyObjects[(*start)++];
if (world->PolyObjects[*start].parent == po->id)
return &world->PolyObjects[(*start)++];
}
return NULL;
......@@ -1298,9 +1285,9 @@ void Polyobj_InitLevel(void)
// get rid of values from previous level
// note: as with msecnodes, it is very important to clear out the blockmap
// node freelist, otherwise it may contain dangling pointers to old objects
PolyObjects = NULL;
numPolyObjects = 0;
bmap_freelist = NULL;
world->PolyObjects = NULL;
world->numPolyObjects = 0;
world->po_bmap_freelist = NULL;
// run down the thinker list, count the number of spawn points, and save
// the mobj_t pointers on a queue for use below.
......@@ -1313,7 +1300,7 @@ void Polyobj_InitLevel(void)
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM)
{
++numPolyObjects;
++world->numPolyObjects;
qitem = malloc(sizeof(mobjqitem_t));
memset(qitem, 0, sizeof(mobjqitem_t));
......@@ -1331,18 +1318,18 @@ void Polyobj_InitLevel(void)
}
}
if (numPolyObjects)
if (world->numPolyObjects)
{
// allocate the PolyObjects array
PolyObjects = Z_Calloc(numPolyObjects * sizeof(polyobj_t),
world->PolyObjects = Z_Calloc(world->numPolyObjects * sizeof(polyobj_t),
PU_LEVEL, NULL);
// setup hash fields
for (i = 0; i < numPolyObjects; ++i)
PolyObjects[i].first = PolyObjects[i].next = numPolyObjects;
for (i = 0; i < world->numPolyObjects; ++i)
world->PolyObjects[i].first = world->PolyObjects[i].next = world->numPolyObjects;
// setup polyobjects
for (i = 0; i < numPolyObjects; ++i)
for (i = 0; i < world->numPolyObjects; ++i)
{
qitem = (mobjqitem_t *)M_QueueIterator(&spawnqueue);
......@@ -1358,17 +1345,17 @@ void Polyobj_InitLevel(void)
}
// setup polyobject clipping
for (i = 0; i < numPolyObjects; ++i)
Polyobj_linkToBlockmap(&PolyObjects[i]);
for (i = 0; i < world->numPolyObjects; ++i)
Polyobj_linkToBlockmap(&world->PolyObjects[i]);
}
#if 0
// haleyjd 02/22/06: temporary debug
printf("DEBUG: numPolyObjects = %d\n", numPolyObjects);
for (i = 0; i < numPolyObjects; ++i)
for (i = 0; i < world->numPolyObjects; ++i)
{
INT32 j;
polyobj_t *po = &PolyObjects[i];
polyobj_t *po = &world->PolyObjects[i];
printf("polyobj %d:\n", i);
printf("id = %d, first = %d, next = %d\n", po->id, po->first, po->next);
......@@ -1615,7 +1602,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
if (!po->thinker)
po->thinker = &th->thinker;
target = waypoints[th->sequence][th->pointnum];
target = world->waypoints[th->sequence][th->pointnum];
if (!target)
{
......
......@@ -407,8 +407,6 @@ boolean EV_DoPolyObjFade(polyfadedata_t *);
// External Variables
//
extern polyobj_t *PolyObjects;
extern INT32 numPolyObjects;
extern polymaplink_t **polyblocklinks; // polyobject blockmap
#endif
......
......@@ -21,6 +21,7 @@
#include "p_local.h"
#include "p_setup.h"
#include "p_saveg.h"
#include "p_world.h"
#include "r_data.h"
#include "r_fps.h"
#include "r_textures.h"
......@@ -39,11 +40,15 @@
savedata_t savedata;
UINT8 *save_p;
world_t *archiveworld;
world_t *unarchiveworld;
// Block UINT32s to attempt to ensure that the correct data is
// being sent and received
#define ARCHIVEBLOCK_MISC 0x7FEEDEED
#define ARCHIVEBLOCK_PLAYERS 0x7F448008
#define ARCHIVEBLOCK_WORLD 0x7F8C08C0
#define ARCHIVEBLOCK_MAP 0x7F8C08C0
#define ARCHIVEBLOCK_WORLD 0x7F9F47A3
#define ARCHIVEBLOCK_POBJS 0x7F928546
#define ARCHIVEBLOCK_THINKERS 0x7F37037C
#define ARCHIVEBLOCK_SPECIALS 0x7F228378
......@@ -129,7 +134,6 @@ static void P_NetArchivePlayers(void)
{
INT32 i, j;
UINT16 flags;
// size_t q;
WRITEUINT32(save_p, ARCHIVEBLOCK_PLAYERS);
......@@ -145,6 +149,7 @@ static void P_NetArchivePlayers(void)
// no longer send ticcmds
WRITESTRINGN(save_p, player_names[i], MAXPLAYERNAME);
WRITEINT32(save_p, players[i].worldnum);
WRITEINT16(save_p, players[i].angleturn);
WRITEINT16(save_p, players[i].oldrelangleturn);
WRITEANGLE(save_p, players[i].aiming);
......@@ -372,6 +377,7 @@ static void P_NetUnArchivePlayers(void)
// NOTE: sending tics should (hopefully) no longer be necessary
READSTRINGN(save_p, player_names[i], MAXPLAYERNAME);
players[i].worldnum = READINT32(save_p);
players[i].angleturn = READINT16(save_p);
players[i].oldrelangleturn = READINT16(save_p);
players[i].aiming = READANGLE(save_p);
......@@ -803,9 +809,9 @@ static void P_NetArchiveWaypoints(void)
for (i = 0; i < NUMWAYPOINTSEQUENCES; i++)
{
WRITEUINT16(save_p, numwaypoints[i]);
for (j = 0; j < numwaypoints[i]; j++)
WRITEUINT32(save_p, waypoints[i][j] ? waypoints[i][j]->mobjnum : 0);
WRITEUINT16(save_p, archiveworld->numwaypoints[i]);
for (j = 0; j < archiveworld->numwaypoints[i]; j++)
WRITEUINT32(save_p, archiveworld->waypoints[i][j] ? archiveworld->waypoints[i][j]->mobjnum : 0);
}
}
......@@ -816,11 +822,11 @@ static void P_NetUnArchiveWaypoints(void)
for (i = 0; i < NUMWAYPOINTSEQUENCES; i++)
{
numwaypoints[i] = READUINT16(save_p);
for (j = 0; j < numwaypoints[i]; j++)
unarchiveworld->numwaypoints[i] = READUINT16(save_p);
for (j = 0; j < unarchiveworld->numwaypoints[i]; j++)
{
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)
static void ArchiveSectors(void)
{
size_t i, j;
const sector_t *ss = sectors;
const sector_t *spawnss = spawnsectors;
const sector_t *ss = archiveworld->sectors;
const sector_t *spawnss = archiveworld->spawnsectors;
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;
if (ss->floorheight != spawnss->floorheight)
......@@ -1088,9 +1094,9 @@ static void ArchiveSectors(void)
if (diff & SD_CEILHT)
WRITEFIXED(save_p, ss->ceilingheight);
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)
WRITEMEM(save_p, levelflats[ss->ceilingpic].name, 8);
WRITEMEM(save_p, archiveworld->flats[ss->ceilingpic].name, 8);
if (diff & SD_LIGHT)
WRITEINT16(save_p, ss->lightlevel);
if (diff & SD_SPECIAL)
......@@ -1160,8 +1166,8 @@ static void UnArchiveSectors(void)
if (i == 0xffff)
break;
if (i > numsectors)
I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors));
if (i > unarchiveworld->numsectors)
I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(unarchiveworld->numsectors));
diff = READUINT8(save_p);
if (diff & SD_DIFF2)
......@@ -1178,105 +1184,105 @@ static void UnArchiveSectors(void)
diff4 = 0;
if (diff & SD_FLOORHT)
sectors[i].floorheight = READFIXED(save_p);
unarchiveworld->sectors[i].floorheight = READFIXED(save_p);
if (diff & SD_CEILHT)
sectors[i].ceilingheight = READFIXED(save_p);
unarchiveworld->sectors[i].ceilingheight = READFIXED(save_p);
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;
}
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;
}
if (diff & SD_LIGHT)
sectors[i].lightlevel = READINT16(save_p);
unarchiveworld->sectors[i].lightlevel = READINT16(save_p);
if (diff & SD_SPECIAL)
sectors[i].special = READINT16(save_p);
unarchiveworld->sectors[i].special = READINT16(save_p);
if (diff2 & SD_FXOFFS)
sectors[i].floor_xoffs = READFIXED(save_p);
unarchiveworld->sectors[i].floor_xoffs = READFIXED(save_p);
if (diff2 & SD_FYOFFS)
sectors[i].floor_yoffs = READFIXED(save_p);
unarchiveworld->sectors[i].floor_yoffs = READFIXED(save_p);
if (diff2 & SD_CXOFFS)
sectors[i].ceiling_xoffs = READFIXED(save_p);
unarchiveworld->sectors[i].ceiling_xoffs = READFIXED(save_p);
if (diff2 & SD_CYOFFS)
sectors[i].ceiling_yoffs = READFIXED(save_p);
unarchiveworld->sectors[i].ceiling_yoffs = READFIXED(save_p);
if (diff2 & SD_FLOORANG)
sectors[i].floorpic_angle = READANGLE(save_p);
unarchiveworld->sectors[i].floorpic_angle = READANGLE(save_p);
if (diff2 & SD_CEILANG)
sectors[i].ceilingpic_angle = READANGLE(save_p);
unarchiveworld->sectors[i].ceilingpic_angle = READANGLE(save_p);
if (diff2 & SD_TAG)
{
size_t ncount = READUINT32(save_p);
// Remove entries from global lists.
for (j = 0; j < sectors[i].tags.count; j++)
Taggroup_Remove(tags_sectors, sectors[i].tags.tags[j], i);
for (j = 0; j < unarchiveworld->sectors[i].tags.count; j++)
Taggroup_Remove(unarchiveworld->tags_sectors, unarchiveworld->sectors[i].tags.tags[j], i);
// Reallocate if size differs.
if (ncount != sectors[i].tags.count)
{
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.count = ncount;
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++)
sectors[i].tags.tags[j] = READINT16(save_p);
unarchiveworld->sectors[i].tags.tags[j] = READINT16(save_p);
// Add new entries.
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)
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p));
unarchiveworld->sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p));
if (diff3 & SD_CRUMBLESTATE)
sectors[i].crumblestate = READINT32(save_p);
unarchiveworld->sectors[i].crumblestate = READINT32(save_p);
if (diff3 & SD_FLOORLIGHT)
{
sectors[i].floorlightlevel = READINT16(save_p);
sectors[i].floorlightabsolute = READUINT8(save_p);
unarchiveworld->sectors[i].floorlightlevel = READINT16(save_p);
unarchiveworld->sectors[i].floorlightabsolute = READUINT8(save_p);
}
if (diff3 & SD_CEILLIGHT)
{
sectors[i].ceilinglightlevel = READINT16(save_p);
sectors[i].ceilinglightabsolute = READUINT8(save_p);
unarchiveworld->sectors[i].ceilinglightlevel = READINT16(save_p);
unarchiveworld->sectors[i].ceilinglightabsolute = READUINT8(save_p);
}
if (diff3 & SD_FLAG)
{
sectors[i].flags = READUINT32(save_p);
CheckForReverseGravity |= (sectors[i].flags & MSF_GRAVITYFLIP);
unarchiveworld->sectors[i].flags = READUINT32(save_p);
CheckForReverseGravity |= (unarchiveworld->sectors[i].flags & MSF_GRAVITYFLIP);
}
if (diff3 & SD_SPECIALFLAG)
sectors[i].specialflags = READUINT32(save_p);
unarchiveworld->sectors[i].specialflags = READUINT32(save_p);
if (diff4 & SD_DAMAGETYPE)
sectors[i].damagetype = READUINT8(save_p);
unarchiveworld->sectors[i].damagetype = READUINT8(save_p);
if (diff4 & SD_TRIGGERTAG)
sectors[i].triggertag = READINT16(save_p);
unarchiveworld->sectors[i].triggertag = READINT16(save_p);
if (diff4 & SD_TRIGGERER)
sectors[i].triggerer = READUINT8(save_p);
unarchiveworld->sectors[i].triggerer = READUINT8(save_p);
if (diff4 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p);
unarchiveworld->sectors[i].gravity = READFIXED(save_p);
if (diff & SD_FFLOORS)
UnArchiveFFloors(&sectors[i]);
UnArchiveFFloors(&unarchiveworld->sectors[i]);
}
}
static void ArchiveLines(void)
{
size_t i;
const line_t *li = lines;
const line_t *spawnli = spawnlines;
const line_t *li = archiveworld->lines;
const line_t *spawnli = archiveworld->spawnlines;
const side_t *si;
const side_t *spawnsi;
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;
......@@ -1297,8 +1303,8 @@ static void ArchiveLines(void)
if (li->sidenum[0] != 0xffff)
{
si = &sides[li->sidenum[0]];
spawnsi = &spawnsides[li->sidenum[0]];
si = &archiveworld->sides[li->sidenum[0]];
spawnsi = &archiveworld->spawnsides[li->sidenum[0]];
if (si->textureoffset != spawnsi->textureoffset)
diff |= LD_S1TEXOFF;
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
......@@ -1311,8 +1317,8 @@ static void ArchiveLines(void)
}
if (li->sidenum[1] != 0xffff)
{
si = &sides[li->sidenum[1]];
spawnsi = &spawnsides[li->sidenum[1]];
si = &archiveworld->sides[li->sidenum[1]];
spawnsi = &archiveworld->spawnsides[li->sidenum[1]];
if (si->textureoffset != spawnsi->textureoffset)
diff2 |= LD_S2TEXOFF;
if (si->toptexture != spawnsi->toptexture)
......@@ -1339,7 +1345,7 @@ static void ArchiveLines(void)
if (diff & LD_CLLCOUNT)
WRITEINT16(save_p, li->callcount);
si = &sides[li->sidenum[0]];
si = &archiveworld->sides[li->sidenum[0]];
if (diff & LD_S1TEXOFF)
WRITEFIXED(save_p, si->textureoffset);
if (diff & LD_S1TOPTEX)
......@@ -1349,7 +1355,7 @@ static void ArchiveLines(void)
if (diff & LD_S1MIDTEX)
WRITEINT32(save_p, si->midtexture);
si = &sides[li->sidenum[1]];
si = &archiveworld->sides[li->sidenum[1]];
if (diff2 & LD_S2TEXOFF)
WRITEFIXED(save_p, si->textureoffset);
if (diff2 & LD_S2TOPTEX)
......@@ -1403,11 +1409,11 @@ static void UnArchiveLines(void)
if (i == 0xffff)
break;
if (i > numlines)
if (i > unarchiveworld->numlines)
I_Error("Invalid line number %u from server", i);
diff = READUINT8(save_p);
li = &lines[i];
li = &unarchiveworld->lines[i];
if (diff & LD_DIFF2)
diff2 = READUINT8(save_p);
......@@ -1473,27 +1479,19 @@ static void UnArchiveLines(void)
}
}
static void P_NetArchiveWorld(void)
static void P_NetArchiveMap(void)
{
// initialize colormap vars because paranoia
ClearNetColormaps();
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
WRITEUINT32(save_p, ARCHIVEBLOCK_MAP);
ArchiveSectors();
ArchiveLines();
R_ClearTextureNumCache(false);
}
static void P_NetUnArchiveWorld(void)
static void P_NetUnArchiveMap(void)
{
UINT16 i;
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
I_Error("Bad $$$.sav at archive block World");
// initialize colormap vars because paranoia
ClearNetColormaps();
if (READUINT32(save_p) != ARCHIVEBLOCK_MAP)
I_Error("Bad $$$.sav at archive block Map");
// count the level's ffloors so that colormap loading can have an upper limit
for (i = 0; i < numsectors; i++)
......@@ -1629,13 +1627,13 @@ static inline UINT32 SaveMobjnum(const mobj_t *mobj)
static UINT32 SaveSector(const sector_t *sector)
{
if (sector) return (UINT32)(sector - sectors);
if (sector) return (UINT32)(sector - archiveworld->sectors);
return 0xFFFFFFFF;
}
static UINT32 SaveLine(const line_t *line)
{
if (line) return (UINT32)(line - lines);
if (line) return (UINT32)(line - archiveworld->lines);
return 0xFFFFFFFF;
}
......@@ -1845,8 +1843,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
{
size_t z;
for (z = 0; z < nummapthings; z++)
if (&mapthings[z] == mobj->spawnpoint)
for (z = 0; z < archiveworld->nummapthings; z++)
if (&archiveworld->mapthings[z] == mobj->spawnpoint)
WRITEUINT16(save_p, z);
if (mobj->type == MT_HOOPCENTER)
return;
......@@ -1988,6 +1986,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, mobj->dispoffset);
WRITEUINT32(save_p, mobj->mobjnum);
WRITEUINT32(save_p, mobj->worldnum);
}
static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type)
......@@ -2487,7 +2486,7 @@ static void P_NetArchiveThinkers(void)
{
UINT32 numsaved = 0;
// 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
|| th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
......@@ -2717,12 +2716,12 @@ static void P_NetArchiveThinkers(void)
// relink to this; the savegame contains the old position in the pointer
// field copyed in the info field temporarily, but finally we just search
// 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;
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)
continue;
......@@ -2745,14 +2744,14 @@ static inline mobj_t *LoadMobj(UINT32 mobjnum)
static sector_t *LoadSector(UINT32 sector)
{
if (sector >= numsectors) return NULL;
return &sectors[sector];
if (sector >= unarchiveworld->numsectors) return NULL;
return &unarchiveworld->sectors[sector];
}
static line_t *LoadLine(UINT32 line)
{
if (line >= numlines) return NULL;
return &lines[line];
if (line >= unarchiveworld->numlines) return NULL;
return &unarchiveworld->lines[line];
}
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)
{
pslope_t *p = slopelist;
if (slopeid > slopecount) return NULL;
pslope_t *p = unarchiveworld->slopelist;
if (slopeid > unarchiveworld->slopecount) return NULL;
do
{
if (p->id == slopeid)
......@@ -2813,16 +2812,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
{
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;
}
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
mobj->spawnpoint = &mapthings[spawnpointnum];
mapthings[spawnpointnum].mobj = mobj;
mobj->spawnpoint = &unarchiveworld->mapthings[spawnpointnum];
unarchiveworld->mapthings[spawnpointnum].mobj = mobj;
}
else
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
......@@ -2994,7 +2993,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_SLOPE)
mobj->standingslope = P_SlopeById(READUINT16(save_p));
mobj->standingslope = P_SlopeById(unarchiveworld->slopelist, READUINT16(save_p));
if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p);
if (diff2 & MD2_MIRRORED)
......@@ -3061,6 +3060,11 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
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->eflags & MFE_VERTICALFLIP)
......@@ -3075,16 +3079,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
if (tag >= 0 && tag <= 15)
{
if (mobj->spawnpoint->args[0])
skyboxcenterpnts[tag] = mobj;
unarchiveworld->skyboxcenterpnts[tag] = mobj;
else
skyboxviewpnts[tag] = mobj;
unarchiveworld->skyboxviewpnts[tag] = mobj;
}
}
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
R_AddMobjInterpolator(mobj);
return &mobj->thinker;
}
......@@ -3697,8 +3699,8 @@ static void P_NetUnArchiveThinkers(void)
// remove all the current thinkers
for (i = 0; i < NUM_THINKERLISTS; i++)
{
currentthinker = thlist[i].next;
for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = next)
currentthinker = unarchiveworld->thlist[i].next;
for (currentthinker = unarchiveworld->thlist[i].next; currentthinker != &unarchiveworld->thlist[i]; currentthinker = next)
{
next = currentthinker->next;
......@@ -3707,20 +3709,23 @@ static void P_NetUnArchiveThinkers(void)
else
{
(next->prev = currentthinker->prev)->next = next;
R_DestroyLevelInterpolators(currentthinker);
R_DestroyLevelInterpolators(unarchiveworld, currentthinker);
Z_Free(currentthinker);
}
}
}
// we don't want the removed mobjs to come back
iquetail = iquehead = 0;
P_InitThinkers();
unarchiveworld->iquetail = unarchiveworld->iquehead = 0;
P_InitThinkers(unarchiveworld);
// clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity
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
......@@ -3912,8 +3917,8 @@ static void P_NetUnArchiveThinkers(void)
}
// Set each skyboxmo to the first skybox (or NULL)
skyboxmo[0] = skyboxviewpnts[0];
skyboxmo[1] = skyboxcenterpnts[0];
unarchiveworld->skyboxmo[0] = unarchiveworld->skyboxviewpnts[0];
unarchiveworld->skyboxmo[1] = unarchiveworld->skyboxcenterpnts[0];
if (restoreNum)
{
......@@ -3926,7 +3931,7 @@ static void P_NetUnArchiveThinkers(void)
delay = (void *)currentthinker;
if (!(mobjnum = (UINT32)(size_t)delay->caller))
continue;
delay->caller = P_FindNewPosition(mobjnum);
delay->caller = P_FindNewPosition(unarchiveworld, mobjnum);
}
}
}
......@@ -3995,20 +4000,20 @@ static inline void P_UnArchivePolyObj(polyobj_t *po)
Polyobj_MoveOnLoad(po, angle, x, y);
}
static inline void P_ArchivePolyObjects(void)
static inline void P_NetArchivePolyObjects(void)
{
INT32 i;
WRITEUINT32(save_p, ARCHIVEBLOCK_POBJS);
// save number of polyobjects
WRITEINT32(save_p, numPolyObjects);
WRITEINT32(save_p, archiveworld->numPolyObjects);
for (i = 0; i < numPolyObjects; ++i)
P_ArchivePolyObj(&PolyObjects[i]);
for (i = 0; i < archiveworld->numPolyObjects; ++i)
P_ArchivePolyObj(&archiveworld->PolyObjects[i]);
}
static inline void P_UnArchivePolyObjects(void)
static inline void P_NetUnArchivePolyObjects(void)
{
INT32 i, numSavedPolys;
......@@ -4017,11 +4022,11 @@ static inline void P_UnArchivePolyObjects(void)
numSavedPolys = READINT32(save_p);
if (numSavedPolys != numPolyObjects)
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency\n");
if (numSavedPolys != world->numPolyObjects)
I_Error("P_NetUnArchivePolyObjects: polyobj count inconsistency\n");
for (i = 0; i < numSavedPolys; ++i)
P_UnArchivePolyObj(&PolyObjects[i]);
P_UnArchivePolyObj(&world->PolyObjects[i]);
}
static inline void P_FinishMobjs(void)
......@@ -4048,7 +4053,8 @@ static void P_RelinkPointers(void)
UINT32 temp;
// 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)
{
if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
......@@ -4063,70 +4069,70 @@ static void P_RelinkPointers(void)
{
temp = (UINT32)(size_t)mobj->tracer;
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);
}
if (mobj->target)
{
temp = (UINT32)(size_t)mobj->target;
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);
}
if (mobj->hnext)
{
temp = (UINT32)(size_t)mobj->hnext;
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);
}
if (mobj->hprev)
{
temp = (UINT32)(size_t)mobj->hprev;
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);
}
if (mobj->player && mobj->player->capsule)
{
temp = (UINT32)(size_t)mobj->player->capsule;
mobj->player->capsule = NULL;
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp)))
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->axis1)
{
temp = (UINT32)(size_t)mobj->player->axis1;
mobj->player->axis1 = NULL;
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp)))
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->axis2)
{
temp = (UINT32)(size_t)mobj->player->axis2;
mobj->player->axis2 = NULL;
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp)))
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->awayviewmobj)
{
temp = (UINT32)(size_t)mobj->player->awayviewmobj;
mobj->player->awayviewmobj = NULL;
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp)))
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->followmobj)
{
temp = (UINT32)(size_t)mobj->player->followmobj;
mobj->player->followmobj = NULL;
if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp)))
if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type);
}
if (mobj->player && mobj->player->drone)
{
temp = (UINT32)(size_t)mobj->player->drone;
mobj->player->drone = NULL;
if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp)))
if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(unarchiveworld, temp)))
CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type);
}
}
......@@ -4139,18 +4145,18 @@ static inline void P_NetArchiveSpecials(void)
WRITEUINT32(save_p, ARCHIVEBLOCK_SPECIALS);
// itemrespawn queue for deathmatch
i = iquetail;
while (iquehead != i)
i = archiveworld->iquetail;
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);
break;
}
}
WRITEUINT32(save_p, itemrespawntime[i]);
WRITEUINT32(save_p, archiveworld->itemrespawntime[i]);
i = (i + 1) & (ITEMQUESIZE-1);
}
......@@ -4158,10 +4164,13 @@ static inline void P_NetArchiveSpecials(void)
WRITEUINT32(save_p, 0xffffffff);
// Sky number
WRITEINT32(save_p, globallevelskynum);
WRITEINT32(save_p, archiveworld->skynum);
// Gravity
WRITEFIXED(save_p, archiveworld->gravity);
// Current global weather type
WRITEUINT8(save_p, globalweather);
WRITEUINT8(save_p, archiveworld->weather);
if (metalplayback) // Is metal sonic running?
{
......@@ -4181,30 +4190,31 @@ static void P_NetUnArchiveSpecials(void)
I_Error("Bad $$$.sav at archive block Specials");
// BP: added save itemrespawn queue for deathmatch
iquetail = iquehead = 0;
unarchiveworld->iquetail = unarchiveworld->iquehead = 0;
while ((i = READUINT32(save_p)) != 0xffffffff)
{
itemrespawnque[iquehead] = &mapthings[i];
itemrespawntime[iquehead++] = READINT32(save_p);
unarchiveworld->itemrespawnque[unarchiveworld->iquehead] = &unarchiveworld->mapthings[i];
unarchiveworld->itemrespawntime[unarchiveworld->iquehead++] = READINT32(save_p);
}
j = READINT32(save_p);
if (j != globallevelskynum)
P_SetupLevelSky(j, true);
P_SetupLevelSky(j, false); // Don't call P_SetupWorldSky from there
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;
P_SwitchWeather(globalweather);
P_SwitchWeather(world->weather);
}
else // PRECIP_NONE
{
if (curWeather != PRECIP_NONE)
P_SwitchWeather(globalweather);
P_SwitchWeather(world->weather);
}
if (READUINT8(save_p) == 0x01) // metal sonic
......@@ -4246,7 +4256,8 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
//lastmapsaved = gamemap;
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
lastmaploaded = gamemap;
tokenlist = 0;
......@@ -4276,7 +4287,7 @@ static void P_NetArchiveMisc(boolean resending)
if (resending)
WRITEUINT32(save_p, gametic);
WRITEINT16(save_p, gamemap);
WRITEINT16(save_p, baseworld->gamemap);
WRITEINT16(save_p, gamestate);
WRITEINT16(save_p, gametype);
......@@ -4333,8 +4344,6 @@ static void P_NetArchiveMisc(boolean resending)
WRITEUINT32(save_p, countdown);
WRITEUINT32(save_p, countdown2);
WRITEFIXED(save_p, gravity);
WRITEUINT32(save_p, countdowntimer);
WRITEUINT8(save_p, countdowntimeup);
......@@ -4356,6 +4365,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
I_Error("Bad $$$.sav at archive block Misc");
World_UnloadAll();
if (reloading)
gametic = READUINT32(save_p);
......@@ -4366,6 +4376,9 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
if(!mapheaderinfo[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
// normally sets this flag
mapmusflags |= MUSIC_RELOADRESET;
......@@ -4433,8 +4446,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
countdown = READUINT32(save_p);
countdown2 = READUINT32(save_p);
gravity = READFIXED(save_p);
countdowntimer = (tic_t)READUINT32(save_p);
countdowntimeup = (boolean)READUINT8(save_p);
......@@ -4722,38 +4733,83 @@ void P_SaveGame(INT16 mapnum)
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)
{
thinker_t *th;
mobj_t *mobj;
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
INT32 i;
CV_SaveNetVars(&save_p);
P_NetArchiveMisc(resending);
P_NetArchiveEmblems();
// 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)
continue;
mobj = (mobj_t *)th;
mobj_t *mobj = (mobj_t *)th;
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
continue;
mobj->mobjnum = i++;
mobj->mobjnum = mobjnum++;
mobj->worldnum = (UINT32)i;
}
}
P_NetArchivePlayers();
if (gamestate == GS_LEVEL)
// Assign world numbers to players
for (i = 0; i < MAXPLAYERS; i++)
{
P_NetArchiveWorld();
P_ArchivePolyObjects();
P_NetArchiveThinkers();
P_NetArchiveSpecials();
P_NetArchiveColormaps();
P_NetArchiveWaypoints();
if (!playeringame[i])
continue;
player_t *player = &players[i];
player->worldnum = -1;
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();
P_ArchiveLuabanksAndConsistency();
......@@ -4778,6 +4834,118 @@ boolean P_LoadGame(INT16 mapoverride)
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)
{
CV_LoadNetVars(&save_p);
......@@ -4786,16 +4954,7 @@ boolean P_LoadNetGame(boolean reloading)
P_NetUnArchiveEmblems();
P_NetUnArchivePlayers();
if (gamestate == GS_LEVEL)
{
P_NetUnArchiveWorld();
P_UnArchivePolyObjects();
P_NetUnArchiveThinkers();
P_NetUnArchiveSpecials();
P_NetUnArchiveColormaps();
P_NetUnArchiveWaypoints();
P_RelinkPointers();
P_FinishMobjs();
}
P_NetUnArchiveWorlds();
LUA_UnArchive();
// This is stupid and hacky, but maybe it'll work!
......