Merge remote-tracking branch 'origin/next' into gametype-clownery
This commit is contained in:
commit
89b4a558a8
|
@ -13614,12 +13614,12 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //Player on the top of the tornado.
|
{ //Player on the top of the tornado.
|
||||||
|
P_ResetPlayer(player);
|
||||||
thing->z = dustdevil->z + dustdevil->height;
|
thing->z = dustdevil->z + dustdevil->height;
|
||||||
thrust = 20 * FRACUNIT;
|
thrust = 20 * FRACUNIT;
|
||||||
player->powers[pw_nocontrol] = 0;
|
player->powers[pw_nocontrol] = 0;
|
||||||
S_StartSound(thing, sfx_wdjump);
|
S_StartSound(thing, sfx_wdjump);
|
||||||
P_SetPlayerMobjState(thing, S_PLAY_FALL);
|
P_SetPlayerMobjState(thing, S_PLAY_FALL);
|
||||||
player->pflags &= ~PF_JUMPED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thing->momz = thrust;
|
thing->momz = thrust;
|
||||||
|
|
868
src/p_mobj.c
868
src/p_mobj.c
|
@ -11598,13 +11598,21 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t*
|
||||||
case MT_EMERALDSPAWN:
|
case MT_EMERALDSPAWN:
|
||||||
case MT_TOKEN:
|
case MT_TOKEN:
|
||||||
case MT_EMBLEM:
|
case MT_EMBLEM:
|
||||||
|
case MT_RING:
|
||||||
|
case MT_REDTEAMRING:
|
||||||
|
case MT_BLUETEAMRING:
|
||||||
|
case MT_COIN:
|
||||||
|
case MT_BLUESPHERE:
|
||||||
|
case MT_BOMBSPHERE:
|
||||||
|
case MT_NIGHTSCHIP:
|
||||||
|
case MT_NIGHTSSTAR:
|
||||||
offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0;
|
offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Remaining objects.
|
// Remaining objects.
|
||||||
default:
|
default:
|
||||||
if (P_WeaponOrPanel(mobjtype))
|
if (P_WeaponOrPanel(mobjtype))
|
||||||
offset += mthing->options & MTF_AMBUSH ? 24 * FRACUNIT : 0;
|
offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!offset) // Snap to the surfaces when there's no offset set.
|
if (!offset) // Snap to the surfaces when there's no offset set.
|
||||||
|
@ -13061,557 +13069,208 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
||||||
mthing->mobj = mobj;
|
mthing->mobj = mobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
|
static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, sector_t* sec, INT32 hoopsize, fixed_t sizefactor)
|
||||||
{
|
{
|
||||||
mobjtype_t ringthing = MT_RING;
|
|
||||||
mobj_t *mobj = NULL;
|
mobj_t *mobj = NULL;
|
||||||
INT32 r, i;
|
mobj_t *nextmobj = NULL;
|
||||||
fixed_t x, y, z, finalx, finaly, finalz;
|
mobj_t *hoopcenter;
|
||||||
sector_t *sec;
|
TMatrix *pitchmatrix, *yawmatrix;
|
||||||
|
fixed_t radius = hoopsize*sizefactor;
|
||||||
|
INT32 i;
|
||||||
|
angle_t fa;
|
||||||
TVector v, *res;
|
TVector v, *res;
|
||||||
angle_t closestangle, fa;
|
|
||||||
boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap));
|
|
||||||
|
|
||||||
x = mthing->x << FRACBITS;
|
z +=
|
||||||
y = mthing->y << FRACBITS;
|
|
||||||
|
|
||||||
sec = R_PointInSubsector(x, y)->sector;
|
|
||||||
|
|
||||||
// NiGHTS hoop!
|
|
||||||
if (mthing->type == 1705)
|
|
||||||
{
|
|
||||||
mobj_t *nextmobj = NULL;
|
|
||||||
mobj_t *hoopcenter;
|
|
||||||
INT16 spewangle;
|
|
||||||
|
|
||||||
z = mthing->z << FRACBITS;
|
|
||||||
|
|
||||||
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
|
|
||||||
|
|
||||||
hoopcenter->spawnpoint = mthing;
|
|
||||||
|
|
||||||
// Screw these damn hoops, I need this thinker.
|
|
||||||
//hoopcenter->flags |= MF_NOTHINK;
|
|
||||||
|
|
||||||
z +=
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
||||||
#endif
|
#endif
|
||||||
sec->floorheight;
|
sec->floorheight;
|
||||||
|
|
||||||
hoopcenter->z = z - hoopcenter->height/2;
|
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
|
||||||
|
hoopcenter->spawnpoint = mthing;
|
||||||
|
hoopcenter->z -= hoopcenter->height/2;
|
||||||
|
|
||||||
P_UnsetThingPosition(hoopcenter);
|
P_UnsetThingPosition(hoopcenter);
|
||||||
hoopcenter->x = x;
|
hoopcenter->x = x;
|
||||||
hoopcenter->y = y;
|
hoopcenter->y = y;
|
||||||
P_SetThingPosition(hoopcenter);
|
P_SetThingPosition(hoopcenter);
|
||||||
|
|
||||||
// Scale 0-255 to 0-359 =(
|
// Scale 0-255 to 0-359 =(
|
||||||
closestangle = FixedAngle(FixedMul((mthing->angle>>8)*FRACUNIT,
|
hoopcenter->movedir = ((mthing->angle & 255)*360)/256; // Pitch
|
||||||
360*(FRACUNIT/256)));
|
pitchmatrix = RotateXMatrix(FixedAngle(hoopcenter->movedir << FRACBITS));
|
||||||
|
hoopcenter->movecount = (((UINT16)mthing->angle >> 8)*360)/256; // Yaw
|
||||||
|
yawmatrix = RotateZMatrix(FixedAngle(hoopcenter->movecount << FRACBITS));
|
||||||
|
|
||||||
hoopcenter->movedir = FixedInt(FixedMul((mthing->angle&255)*FRACUNIT,
|
// For the hoop when it flies away
|
||||||
360*(FRACUNIT/256)));
|
hoopcenter->extravalue1 = hoopsize;
|
||||||
hoopcenter->movecount = FixedInt(AngleFixed(closestangle));
|
hoopcenter->extravalue2 = radius/12;
|
||||||
|
|
||||||
// For the hoop when it flies away
|
// Create the hoop!
|
||||||
hoopcenter->extravalue1 = 32;
|
for (i = 0; i < hoopsize; i++)
|
||||||
hoopcenter->extravalue2 = 8 * FRACUNIT;
|
{
|
||||||
|
fa = i*(FINEANGLES/hoopsize);
|
||||||
|
v[0] = FixedMul(FINECOSINE(fa), radius);
|
||||||
|
v[1] = 0;
|
||||||
|
v[2] = FixedMul(FINESINE(fa), radius);
|
||||||
|
v[3] = FRACUNIT;
|
||||||
|
|
||||||
spewangle = (INT16)hoopcenter->movedir;
|
res = VectorMatrixMultiply(v, *pitchmatrix);
|
||||||
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
|
res = VectorMatrixMultiply(v, *yawmatrix);
|
||||||
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
|
|
||||||
// Create the hoop!
|
mobj = P_SpawnMobj(x + v[0], y + v[1], z + v[2], MT_HOOP);
|
||||||
for (i = 0; i < 32; i++)
|
mobj->z -= mobj->height/2;
|
||||||
|
|
||||||
|
if (maptol & TOL_XMAS)
|
||||||
|
P_SetMobjState(mobj, mobj->info->seestate + (i & 1));
|
||||||
|
|
||||||
|
P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center.
|
||||||
|
mobj->fuse = 0;
|
||||||
|
|
||||||
|
// Link all the sprites in the hoop together
|
||||||
|
if (nextmobj)
|
||||||
{
|
{
|
||||||
fa = i*(FINEANGLES/32);
|
|
||||||
v[0] = FixedMul(FINECOSINE(fa),96*FRACUNIT);
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = FixedMul(FINESINE(fa),96*FRACUNIT);
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT)));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
|
|
||||||
finalx = x + v[0];
|
|
||||||
finaly = y + v[1];
|
|
||||||
finalz = z + v[2];
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP);
|
|
||||||
|
|
||||||
if (maptol & TOL_XMAS)
|
|
||||||
P_SetMobjState(mobj, mobj->info->seestate + (i & 1));
|
|
||||||
|
|
||||||
mobj->z -= mobj->height/2;
|
|
||||||
P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center.
|
|
||||||
mobj->fuse = 0;
|
|
||||||
|
|
||||||
// Link all the sprites in the hoop together
|
|
||||||
if (nextmobj)
|
|
||||||
{
|
|
||||||
P_SetTarget(&mobj->hprev, nextmobj);
|
|
||||||
P_SetTarget(&mobj->hprev->hnext, mobj);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL));
|
|
||||||
|
|
||||||
nextmobj = mobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the collision detectors!
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
fa = i*FINEANGLES/16;
|
|
||||||
v[0] = FixedMul(FINECOSINE(fa),32*FRACUNIT);
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = FixedMul(FINESINE(fa),32*FRACUNIT);
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT)));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
|
|
||||||
finalx = x + v[0];
|
|
||||||
finaly = y + v[1];
|
|
||||||
finalz = z + v[2];
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOPCOLLIDE);
|
|
||||||
mobj->z -= mobj->height/2;
|
|
||||||
|
|
||||||
// Link all the collision sprites together.
|
|
||||||
P_SetTarget(&mobj->hnext, NULL);
|
|
||||||
P_SetTarget(&mobj->hprev, nextmobj);
|
P_SetTarget(&mobj->hprev, nextmobj);
|
||||||
P_SetTarget(&mobj->hprev->hnext, mobj);
|
P_SetTarget(&mobj->hprev->hnext, mobj);
|
||||||
|
|
||||||
nextmobj = mobj;
|
|
||||||
}
|
}
|
||||||
// Create the collision detectors!
|
else
|
||||||
for (i = 0; i < 16; i++)
|
P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL));
|
||||||
{
|
|
||||||
fa = i*FINEANGLES/16;
|
|
||||||
v[0] = FixedMul(FINECOSINE(fa),64*FRACUNIT);
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = FixedMul(FINESINE(fa),64*FRACUNIT);
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT)));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
|
|
||||||
finalx = x + v[0];
|
nextmobj = mobj;
|
||||||
finaly = y + v[1];
|
|
||||||
finalz = z + v[2];
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOPCOLLIDE);
|
|
||||||
mobj->z -= mobj->height/2;
|
|
||||||
|
|
||||||
// Link all the collision sprites together.
|
|
||||||
P_SetTarget(&mobj->hnext, NULL);
|
|
||||||
P_SetTarget(&mobj->hprev, nextmobj);
|
|
||||||
P_SetTarget(&mobj->hprev->hnext, mobj);
|
|
||||||
|
|
||||||
nextmobj = mobj;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// CUSTOMIZABLE NiGHTS hoop!
|
|
||||||
else if (mthing->type == 1713)
|
// Create the collision detectors!
|
||||||
|
// Create them until the size is less than 8
|
||||||
|
// But always create at least ONE set of collision detectors
|
||||||
|
do
|
||||||
{
|
{
|
||||||
mobj_t *nextmobj = NULL;
|
if (hoopsize >= 32)
|
||||||
mobj_t *hoopcenter;
|
hoopsize -= 16;
|
||||||
INT16 spewangle;
|
else
|
||||||
INT32 hoopsize;
|
hoopsize /= 2;
|
||||||
INT32 hoopplacement;
|
|
||||||
|
|
||||||
z = mthing->z << FRACBITS;
|
radius = hoopsize*sizefactor;
|
||||||
|
|
||||||
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
|
|
||||||
hoopcenter->spawnpoint = mthing;
|
|
||||||
|
|
||||||
z +=
|
|
||||||
#ifdef ESLOPE
|
|
||||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
|
||||||
#endif
|
|
||||||
sec->floorheight;
|
|
||||||
hoopcenter->z = z - hoopcenter->height/2;
|
|
||||||
|
|
||||||
P_UnsetThingPosition(hoopcenter);
|
|
||||||
hoopcenter->x = x;
|
|
||||||
hoopcenter->y = y;
|
|
||||||
P_SetThingPosition(hoopcenter);
|
|
||||||
|
|
||||||
// Scale 0-255 to 0-359 =(
|
|
||||||
closestangle = FixedAngle(FixedMul((mthing->angle>>8)*FRACUNIT,
|
|
||||||
360*(FRACUNIT/256)));
|
|
||||||
|
|
||||||
hoopcenter->movedir = FixedInt(FixedMul((mthing->angle&255)*FRACUNIT,
|
|
||||||
360*(FRACUNIT/256)));
|
|
||||||
hoopcenter->movecount = FixedInt(AngleFixed(closestangle));
|
|
||||||
|
|
||||||
spewangle = (INT16)hoopcenter->movedir;
|
|
||||||
|
|
||||||
// Super happy fun time
|
|
||||||
// For each flag add 4 fracunits to the size
|
|
||||||
// Default (0 flags) is 8 fracunits
|
|
||||||
hoopsize = 8 + (4 * (mthing->options & 0xF));
|
|
||||||
hoopplacement = hoopsize * (4*FRACUNIT);
|
|
||||||
|
|
||||||
// For the hoop when it flies away
|
|
||||||
hoopcenter->extravalue1 = hoopsize;
|
|
||||||
hoopcenter->extravalue2 = FixedDiv(hoopplacement, 12*FRACUNIT);
|
|
||||||
|
|
||||||
// Create the hoop!
|
|
||||||
for (i = 0; i < hoopsize; i++)
|
for (i = 0; i < hoopsize; i++)
|
||||||
{
|
{
|
||||||
fa = i*(FINEANGLES/hoopsize);
|
fa = i*(FINEANGLES/hoopsize);
|
||||||
v[0] = FixedMul(FINECOSINE(fa), hoopplacement);
|
v[0] = FixedMul(FINECOSINE(fa), radius);
|
||||||
v[1] = 0;
|
v[1] = 0;
|
||||||
v[2] = FixedMul(FINESINE(fa), hoopplacement);
|
v[2] = FixedMul(FINESINE(fa), radius);
|
||||||
v[3] = FRACUNIT;
|
v[3] = FRACUNIT;
|
||||||
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT)));
|
res = VectorMatrixMultiply(v, *pitchmatrix);
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
res = VectorMatrixMultiply(v, *yawmatrix);
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
|
|
||||||
finalx = x + v[0];
|
|
||||||
finaly = y + v[1];
|
|
||||||
finalz = z + v[2];
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP);
|
|
||||||
|
|
||||||
if (maptol & TOL_XMAS)
|
|
||||||
P_SetMobjState(mobj, mobj->info->seestate + (i & 1));
|
|
||||||
|
|
||||||
|
mobj = P_SpawnMobj(x + v[0], y + v[1], z + v[2], MT_HOOPCOLLIDE);
|
||||||
mobj->z -= mobj->height/2;
|
mobj->z -= mobj->height/2;
|
||||||
P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center.
|
|
||||||
mobj->fuse = 0;
|
|
||||||
|
|
||||||
// Link all the sprites in the hoop together
|
// Link all the collision sprites together.
|
||||||
if (nextmobj)
|
P_SetTarget(&mobj->hnext, NULL);
|
||||||
{
|
P_SetTarget(&mobj->hprev, nextmobj);
|
||||||
P_SetTarget(&mobj->hprev, nextmobj);
|
P_SetTarget(&mobj->hprev->hnext, mobj);
|
||||||
P_SetTarget(&mobj->hprev->hnext, mobj);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL));
|
|
||||||
|
|
||||||
nextmobj = mobj;
|
nextmobj = mobj;
|
||||||
}
|
}
|
||||||
|
} while (hoopsize >= 8);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the collision detectors!
|
static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bonustime, boolean nightsreplace)
|
||||||
// Create them until the size is less than 8
|
{
|
||||||
// But always create at least ONE set of collision detectors
|
mobjtype_t ringthing = MT_RING;
|
||||||
do
|
mobj_t *mobj = NULL;
|
||||||
{
|
fixed_t z;
|
||||||
if (hoopsize >= 32)
|
|
||||||
hoopsize -= 16;
|
|
||||||
else
|
|
||||||
hoopsize /= 2;
|
|
||||||
|
|
||||||
hoopplacement = hoopsize * (4*FRACUNIT);
|
// Which ringthing to use
|
||||||
|
if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
|
||||||
for (i = 0; i < hoopsize; i++)
|
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
|
||||||
{
|
else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum)
|
||||||
fa = i*FINEANGLES/hoopsize;
|
ringthing = MT_BOMBSPHERE;
|
||||||
v[0] = FixedMul(FINECOSINE(fa), hoopplacement);
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = FixedMul(FINESINE(fa), hoopplacement);
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT)));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
|
|
||||||
finalx = x + v[0];
|
|
||||||
finaly = y + v[1];
|
|
||||||
finalz = z + v[2];
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOPCOLLIDE);
|
|
||||||
mobj->z -= mobj->height/2;
|
|
||||||
|
|
||||||
// Link all the collision sprites together.
|
|
||||||
P_SetTarget(&mobj->hnext, NULL);
|
|
||||||
P_SetTarget(&mobj->hprev, nextmobj);
|
|
||||||
P_SetTarget(&mobj->hprev->hnext, mobj);
|
|
||||||
|
|
||||||
nextmobj = mobj;
|
|
||||||
}
|
|
||||||
} while (hoopsize >= 8);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// ***
|
|
||||||
// Special placement patterns
|
|
||||||
// ***
|
|
||||||
|
|
||||||
// Vertical Rings - Stack of 5 (handles both red and yellow)
|
|
||||||
else if (mthing->type == 600 || mthing->type == 601)
|
|
||||||
{
|
|
||||||
INT32 dist = 64*FRACUNIT;
|
|
||||||
if (mthing->type == 601)
|
|
||||||
dist = 128*FRACUNIT;
|
|
||||||
|
|
||||||
if (ultimatemode)
|
|
||||||
return; // No rings in Ultimate!
|
|
||||||
|
|
||||||
if (nightsreplace)
|
|
||||||
ringthing = MT_NIGHTSSTAR;
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
{
|
|
||||||
z = (
|
|
||||||
#ifdef ESLOPE
|
|
||||||
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
|
||||||
#endif
|
|
||||||
sec->ceilingheight) - mobjinfo[ringthing].height;
|
|
||||||
if (mthing->z)
|
|
||||||
z -= (mthing->z << FRACBITS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
z = (
|
|
||||||
#ifdef ESLOPE
|
|
||||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
|
||||||
#endif
|
|
||||||
sec->floorheight);
|
|
||||||
if (mthing->z)
|
|
||||||
z += (mthing->z << FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (r = 1; r <= 5; r++)
|
|
||||||
{
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
z -= dist;
|
|
||||||
else
|
|
||||||
z += dist;
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(x, y, z, ringthing);
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
{
|
|
||||||
mobj->eflags |= MFE_VERTICALFLIP;
|
|
||||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
|
||||||
if (mthing->options & MTF_AMBUSH)
|
|
||||||
mobj->flags2 |= MF2_AMBUSH;
|
|
||||||
|
|
||||||
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
|
|
||||||
P_SetMobjState(mobj, mobj->info->seestate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Diagonal rings (handles both types)
|
|
||||||
else if (mthing->type == 602 || mthing->type == 603) // Diagonal rings (5)
|
|
||||||
{
|
|
||||||
INT32 iterations = 5;
|
|
||||||
if (mthing->type == 603)
|
|
||||||
iterations = 10;
|
|
||||||
|
|
||||||
if (ultimatemode)
|
|
||||||
return; // No rings in Ultimate!
|
|
||||||
|
|
||||||
if (nightsreplace)
|
|
||||||
ringthing = MT_NIGHTSSTAR;
|
|
||||||
|
|
||||||
closestangle = FixedAngle(mthing->angle*FRACUNIT);
|
|
||||||
fa = (closestangle >> ANGLETOFINESHIFT);
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
{
|
|
||||||
z = (
|
|
||||||
#ifdef ESLOPE
|
|
||||||
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
|
||||||
#endif
|
|
||||||
sec->ceilingheight) - mobjinfo[ringthing].height;
|
|
||||||
if (mthing->z)
|
|
||||||
z -= (mthing->z << FRACBITS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
z = (
|
|
||||||
#ifdef ESLOPE
|
|
||||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
|
||||||
#endif
|
|
||||||
sec->floorheight);
|
|
||||||
if (mthing->z)
|
|
||||||
z += (mthing->z << FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (r = 1; r <= iterations; r++)
|
|
||||||
{
|
|
||||||
x += FixedMul(64*FRACUNIT, FINECOSINE(fa));
|
|
||||||
y += FixedMul(64*FRACUNIT, FINESINE(fa));
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
z -= 64*FRACUNIT;
|
|
||||||
else
|
|
||||||
z += 64*FRACUNIT;
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(x, y, z, ringthing);
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
{
|
|
||||||
mobj->eflags |= MFE_VERTICALFLIP;
|
|
||||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
mobj->angle = closestangle;
|
|
||||||
if (mthing->options & MTF_AMBUSH)
|
|
||||||
mobj->flags2 |= MF2_AMBUSH;
|
|
||||||
|
|
||||||
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
|
|
||||||
P_SetMobjState(mobj, mobj->info->seestate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rings of items (all six of them)
|
|
||||||
else if (mthing->type >= 604 && mthing->type <= 609)
|
|
||||||
{
|
|
||||||
INT32 numitems = 8;
|
|
||||||
INT32 size = 96*FRACUNIT;
|
|
||||||
|
|
||||||
if (mthing->type & 1)
|
|
||||||
{
|
|
||||||
numitems = 16;
|
|
||||||
size = 192*FRACUNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
z =
|
|
||||||
#ifdef ESLOPE
|
|
||||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
|
||||||
#endif
|
|
||||||
sec->floorheight;
|
|
||||||
if (mthing->z)
|
|
||||||
z += (mthing->z << FRACBITS);
|
|
||||||
|
|
||||||
closestangle = FixedAngle(mthing->angle*FRACUNIT);
|
|
||||||
|
|
||||||
switch (mthing->type)
|
|
||||||
{
|
|
||||||
case 604:
|
|
||||||
case 605:
|
|
||||||
if (ultimatemode)
|
|
||||||
return; // No rings in Ultimate!
|
|
||||||
if (nightsreplace)
|
|
||||||
ringthing = MT_NIGHTSSTAR;
|
|
||||||
break;
|
|
||||||
case 608:
|
|
||||||
case 609:
|
|
||||||
/*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere
|
|
||||||
break;*/
|
|
||||||
case 606:
|
|
||||||
case 607:
|
|
||||||
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the hoop!
|
|
||||||
for (i = 0; i < numitems; i++)
|
|
||||||
{
|
|
||||||
if (mthing->type == 608 || mthing->type == 609)
|
|
||||||
{
|
|
||||||
if (i & 1)
|
|
||||||
{
|
|
||||||
if (ultimatemode)
|
|
||||||
continue; // No rings in Ultimate!
|
|
||||||
ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fa = i*FINEANGLES/numitems;
|
|
||||||
v[0] = FixedMul(FINECOSINE(fa),size);
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = FixedMul(FINESINE(fa),size);
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
|
||||||
M_Memcpy(&v, res, sizeof (v));
|
|
||||||
|
|
||||||
finalx = x + v[0];
|
|
||||||
finaly = y + v[1];
|
|
||||||
finalz = z + v[2];
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing);
|
|
||||||
mobj->z -= mobj->height/2;
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
{
|
|
||||||
mobj->eflags |= MFE_VERTICALFLIP;
|
|
||||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
mobj->angle = closestangle;
|
|
||||||
if (mthing->options & MTF_AMBUSH)
|
|
||||||
mobj->flags2 |= MF2_AMBUSH;
|
|
||||||
|
|
||||||
if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP))
|
|
||||||
P_SetMobjState(mobj, mobj->info->raisestate);
|
|
||||||
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
|
|
||||||
P_SetMobjState(mobj, mobj->info->seestate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// All manners of rings and coins
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (ultimatemode)
|
||||||
|
return; // No rings in Ultimate!
|
||||||
|
|
||||||
// Which ringthing to use
|
if (nightsreplace)
|
||||||
if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
|
ringthing = MT_NIGHTSSTAR;
|
||||||
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
|
else if (mthing->type == mobjinfo[MT_COIN].doomednum)
|
||||||
else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum)
|
ringthing = MT_COIN;
|
||||||
ringthing = MT_BOMBSPHERE;
|
else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF
|
||||||
else
|
ringthing = (gametyperules & GTR_TEAMFLAGS) ? MT_REDTEAMRING : MT_RING;
|
||||||
{
|
else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto
|
||||||
if (ultimatemode)
|
ringthing = (gametyperules & GTR_TEAMFLAGS) ? MT_BLUETEAMRING : MT_RING;
|
||||||
return; // No rings in Ultimate!
|
}
|
||||||
|
|
||||||
if (nightsreplace)
|
z = P_GetMobjSpawnHeight(ringthing, mthing, x, y);
|
||||||
ringthing = MT_NIGHTSSTAR;
|
mobj = P_SpawnMobj(x, y, z, ringthing);
|
||||||
else if (mthing->type == mobjinfo[MT_COIN].doomednum)
|
mobj->spawnpoint = mthing;
|
||||||
ringthing = MT_COIN;
|
|
||||||
else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF
|
|
||||||
ringthing = (gametyperules & GTR_TEAMFLAGS) ? MT_REDTEAMRING : MT_RING;
|
|
||||||
else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto
|
|
||||||
ringthing = (gametyperules & GTR_TEAMFLAGS) ? MT_BLUETEAMRING : MT_RING;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set proper height
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
{
|
||||||
{
|
mobj->eflags |= MFE_VERTICALFLIP;
|
||||||
z = (
|
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
mobj->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||||
|
mthing->mobj = mobj;
|
||||||
|
if (mthing->options & MTF_AMBUSH)
|
||||||
|
mobj->flags2 |= MF2_AMBUSH;
|
||||||
|
|
||||||
|
if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP))
|
||||||
|
P_SetMobjState(mobj, mobj->info->raisestate);
|
||||||
|
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
|
||||||
|
P_SetMobjState(mobj, mobj->info->seestate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, sector_t* sec, boolean nightsreplace)
|
||||||
|
{
|
||||||
|
mobjtype_t ringthing = MT_RING;
|
||||||
|
mobj_t* mobj = NULL;
|
||||||
|
fixed_t z;
|
||||||
|
INT32 r;
|
||||||
|
|
||||||
|
INT32 dist = 64*FRACUNIT;
|
||||||
|
if (mthing->type == 601)
|
||||||
|
dist = 128*FRACUNIT;
|
||||||
|
|
||||||
|
if (ultimatemode)
|
||||||
|
return; // No rings in Ultimate!
|
||||||
|
|
||||||
|
if (nightsreplace)
|
||||||
|
ringthing = MT_NIGHTSSTAR;
|
||||||
|
|
||||||
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
|
{
|
||||||
|
z = (
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
||||||
#endif
|
#endif
|
||||||
sec->ceilingheight) - mobjinfo[ringthing].height;
|
sec->ceilingheight) - mobjinfo[ringthing].height;
|
||||||
if (mthing->z)
|
if (mthing->z)
|
||||||
z -= (mthing->z << FRACBITS);
|
z -= (mthing->z << FRACBITS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
z =
|
z = (
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
||||||
#endif
|
#endif
|
||||||
sec->floorheight;
|
sec->floorheight);
|
||||||
if (mthing->z)
|
if (mthing->z)
|
||||||
z += (mthing->z << FRACBITS);
|
z += (mthing->z << FRACBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mthing->options & MTF_AMBUSH) // Special flag for rings
|
for (r = 1; r <= 5; r++)
|
||||||
{
|
{
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
z -= 24*FRACUNIT;
|
z -= dist;
|
||||||
else
|
else
|
||||||
z += 24*FRACUNIT;
|
z += dist;
|
||||||
}
|
|
||||||
|
|
||||||
mobj = P_SpawnMobj(x, y, z, ringthing);
|
mobj = P_SpawnMobj(x, y, z, ringthing);
|
||||||
mobj->spawnpoint = mthing;
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
{
|
{
|
||||||
|
@ -13619,8 +13278,170 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
|
||||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
mobj->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||||
mthing->mobj = mobj;
|
if (mthing->options & MTF_AMBUSH)
|
||||||
|
mobj->flags2 |= MF2_AMBUSH;
|
||||||
|
|
||||||
|
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
|
||||||
|
P_SetMobjState(mobj, mobj->info->seestate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t* sec, boolean nightsreplace)
|
||||||
|
{
|
||||||
|
mobjtype_t ringthing = MT_RING;
|
||||||
|
mobj_t *mobj = NULL;
|
||||||
|
fixed_t z;
|
||||||
|
INT32 r;
|
||||||
|
angle_t closestangle, fa;
|
||||||
|
|
||||||
|
INT32 iterations = 5;
|
||||||
|
if (mthing->type == 603)
|
||||||
|
iterations = 10;
|
||||||
|
|
||||||
|
if (ultimatemode)
|
||||||
|
return; // No rings in Ultimate!
|
||||||
|
|
||||||
|
if (nightsreplace)
|
||||||
|
ringthing = MT_NIGHTSSTAR;
|
||||||
|
|
||||||
|
closestangle = FixedAngle(mthing->angle << FRACBITS);
|
||||||
|
fa = (closestangle >> ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
|
{
|
||||||
|
z = (
|
||||||
|
#ifdef ESLOPE
|
||||||
|
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
||||||
|
#endif
|
||||||
|
sec->ceilingheight) - mobjinfo[ringthing].height;
|
||||||
|
if (mthing->z)
|
||||||
|
z -= (mthing->z << FRACBITS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = (
|
||||||
|
#ifdef ESLOPE
|
||||||
|
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
||||||
|
#endif
|
||||||
|
sec->floorheight);
|
||||||
|
if (mthing->z)
|
||||||
|
z += (mthing->z << FRACBITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (r = 1; r <= iterations; r++)
|
||||||
|
{
|
||||||
|
x += FixedMul(64*FRACUNIT, FINECOSINE(fa));
|
||||||
|
y += FixedMul(64*FRACUNIT, FINESINE(fa));
|
||||||
|
|
||||||
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
|
z -= 64*FRACUNIT;
|
||||||
|
else
|
||||||
|
z += 64*FRACUNIT;
|
||||||
|
|
||||||
|
mobj = P_SpawnMobj(x, y, z, ringthing);
|
||||||
|
|
||||||
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
|
{
|
||||||
|
mobj->eflags |= MFE_VERTICALFLIP;
|
||||||
|
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
mobj->angle = closestangle;
|
||||||
|
if (mthing->options & MTF_AMBUSH)
|
||||||
|
mobj->flags2 |= MF2_AMBUSH;
|
||||||
|
|
||||||
|
if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
|
||||||
|
P_SetMobjState(mobj, mobj->info->seestate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t* sec, boolean bonustime, boolean nightsreplace)
|
||||||
|
{
|
||||||
|
mobjtype_t ringthing = MT_RING;
|
||||||
|
mobj_t *mobj = NULL;
|
||||||
|
fixed_t z, finalx, finaly, finalz;
|
||||||
|
angle_t closestangle, fa;
|
||||||
|
INT32 i;
|
||||||
|
TVector v, *res;
|
||||||
|
INT32 numitems = 8;
|
||||||
|
INT32 size = 96*FRACUNIT;
|
||||||
|
|
||||||
|
if (mthing->type & 1)
|
||||||
|
{
|
||||||
|
numitems = 16;
|
||||||
|
size = 192*FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
z =
|
||||||
|
#ifdef ESLOPE
|
||||||
|
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
||||||
|
#endif
|
||||||
|
sec->floorheight;
|
||||||
|
if (mthing->z)
|
||||||
|
z += (mthing->z << FRACBITS);
|
||||||
|
|
||||||
|
closestangle = FixedAngle(mthing->angle << FRACBITS);
|
||||||
|
|
||||||
|
switch (mthing->type)
|
||||||
|
{
|
||||||
|
case 604:
|
||||||
|
case 605:
|
||||||
|
if (ultimatemode)
|
||||||
|
return; // No rings in Ultimate!
|
||||||
|
if (nightsreplace)
|
||||||
|
ringthing = MT_NIGHTSSTAR;
|
||||||
|
break;
|
||||||
|
case 608:
|
||||||
|
case 609:
|
||||||
|
/*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere
|
||||||
|
break;*/
|
||||||
|
case 606:
|
||||||
|
case 607:
|
||||||
|
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the hoop!
|
||||||
|
for (i = 0; i < numitems; i++)
|
||||||
|
{
|
||||||
|
if (mthing->type == 608 || mthing->type == 609)
|
||||||
|
{
|
||||||
|
if (i & 1)
|
||||||
|
{
|
||||||
|
if (ultimatemode)
|
||||||
|
continue; // No rings in Ultimate!
|
||||||
|
ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fa = i * FINEANGLES/numitems;
|
||||||
|
v[0] = FixedMul(FINECOSINE(fa), size);
|
||||||
|
v[1] = 0;
|
||||||
|
v[2] = FixedMul(FINESINE(fa), size);
|
||||||
|
v[3] = FRACUNIT;
|
||||||
|
|
||||||
|
res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle));
|
||||||
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
|
|
||||||
|
finalx = x + v[0];
|
||||||
|
finaly = y + v[1];
|
||||||
|
finalz = z + v[2];
|
||||||
|
|
||||||
|
mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing);
|
||||||
|
mobj->z -= mobj->height/2;
|
||||||
|
|
||||||
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
|
{
|
||||||
|
mobj->eflags |= MFE_VERTICALFLIP;
|
||||||
|
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
mobj->angle = closestangle;
|
||||||
if (mthing->options & MTF_AMBUSH)
|
if (mthing->options & MTF_AMBUSH)
|
||||||
mobj->flags2 |= MF2_AMBUSH;
|
mobj->flags2 |= MF2_AMBUSH;
|
||||||
|
|
||||||
|
@ -13631,6 +13452,47 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
|
||||||
|
{
|
||||||
|
fixed_t x = mthing->x << FRACBITS;
|
||||||
|
fixed_t y = mthing->y << FRACBITS;
|
||||||
|
fixed_t z = mthing->z << FRACBITS;
|
||||||
|
sector_t *sec = R_PointInSubsector(x, y)->sector;
|
||||||
|
boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap));
|
||||||
|
|
||||||
|
switch (mthing->type)
|
||||||
|
{
|
||||||
|
// Special placement patterns
|
||||||
|
case 600: // 5 vertical rings (yellow spring)
|
||||||
|
case 601: // 5 vertical rings (red spring)
|
||||||
|
P_SpawnVerticalSpringRings(mthing, x, y, sec, nightsreplace);
|
||||||
|
return;
|
||||||
|
case 602: // 5 diagonal rings (yellow spring)
|
||||||
|
case 603: // 10 diagonal rings (red spring)
|
||||||
|
P_SpawnDiagonalSpringRings(mthing, x, y, sec, nightsreplace);
|
||||||
|
return;
|
||||||
|
case 604: // Circle of rings (8 items)
|
||||||
|
case 605: // Circle of rings (16 bits)
|
||||||
|
case 606: // Circle of blue spheres (8 items)
|
||||||
|
case 607: // Circle of blue spheres (16 items)
|
||||||
|
case 608: // Circle of rings and blue spheres (8 items)
|
||||||
|
case 609: // Circle of rings and blue spheres (16 items)
|
||||||
|
P_SpawnItemCircle(mthing, x, y, sec, bonustime, nightsreplace);
|
||||||
|
return;
|
||||||
|
// Hoops
|
||||||
|
case 1705: // Generic NiGHTS hoop
|
||||||
|
P_SpawnHoop(mthing, x, y, z, sec, 24, 4*FRACUNIT);
|
||||||
|
return;
|
||||||
|
case 1713: // Customizable NiGHTS hoop
|
||||||
|
// For each flag add 16 fracunits to the size
|
||||||
|
// Default (0 flags) is 32 fracunits
|
||||||
|
P_SpawnHoop(mthing, x, y, z, sec, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT);
|
||||||
|
return;
|
||||||
|
default: // All manners of rings and coins
|
||||||
|
P_SpawnRingItem(mthing, x, y, bonustime, nightsreplace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_CheckMissileSpawn
|
// P_CheckMissileSpawn
|
||||||
// Moves the missile forward a bit and possibly explodes it right there.
|
// Moves the missile forward a bit and possibly explodes it right there.
|
||||||
|
|
|
@ -777,14 +777,13 @@ static void P_NetArchiveWorld(void)
|
||||||
size_t i;
|
size_t i;
|
||||||
INT32 statsec = 0, statline = 0;
|
INT32 statsec = 0, statline = 0;
|
||||||
const line_t *li = lines;
|
const line_t *li = lines;
|
||||||
|
const line_t *spawnli = spawnlines;
|
||||||
const side_t *si;
|
const side_t *si;
|
||||||
|
const side_t *spawnsi;
|
||||||
UINT8 *put;
|
UINT8 *put;
|
||||||
|
|
||||||
// reload the map just to see difference
|
|
||||||
mapsector_t *ms;
|
|
||||||
mapsidedef_t *msd;
|
|
||||||
maplinedef_t *mld;
|
|
||||||
const sector_t *ss = sectors;
|
const sector_t *ss = sectors;
|
||||||
|
const sector_t *spawnss = spawnsectors;
|
||||||
UINT8 diff, diff2, diff3;
|
UINT8 diff, diff2, diff3;
|
||||||
|
|
||||||
// initialize colormap vars because paranoia
|
// initialize colormap vars because paranoia
|
||||||
|
@ -793,65 +792,45 @@ static void P_NetArchiveWorld(void)
|
||||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||||
put = save_p;
|
put = save_p;
|
||||||
|
|
||||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
for (i = 0; i < numsectors; i++, ss++, spawnss++)
|
||||||
{ // HACK: Open wad file rather quickly so we can get the data from the relevant lumps
|
|
||||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
|
||||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
|
||||||
#define retrieve_mapdata(d, f)\
|
|
||||||
d = Z_Malloc((f)->size, PU_CACHE, NULL); \
|
|
||||||
M_Memcpy(d, wadData + (f)->filepos, (f)->size)
|
|
||||||
retrieve_mapdata(ms, fileinfo + ML_SECTORS);
|
|
||||||
retrieve_mapdata(mld, fileinfo + ML_LINEDEFS);
|
|
||||||
retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS);
|
|
||||||
#undef retrieve_mapdata
|
|
||||||
Z_Free(wadData); // we're done with this now
|
|
||||||
}
|
|
||||||
else // phew it's just a WAD
|
|
||||||
{
|
|
||||||
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
|
|
||||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
|
||||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
|
||||||
{
|
{
|
||||||
diff = diff2 = diff3 = 0;
|
diff = diff2 = diff3 = 0;
|
||||||
if (ss->floorheight != SHORT(ms->floorheight)<<FRACBITS)
|
if (ss->floorheight != spawnss->floorheight)
|
||||||
diff |= SD_FLOORHT;
|
diff |= SD_FLOORHT;
|
||||||
if (ss->ceilingheight != SHORT(ms->ceilingheight)<<FRACBITS)
|
if (ss->ceilingheight != spawnss->ceilingheight)
|
||||||
diff |= SD_CEILHT;
|
diff |= SD_CEILHT;
|
||||||
//
|
//
|
||||||
// flats
|
// flats
|
||||||
//
|
//
|
||||||
if (ss->floorpic != P_CheckLevelFlat(ms->floorpic))
|
if (ss->floorpic != spawnss->floorpic)
|
||||||
diff |= SD_FLOORPIC;
|
diff |= SD_FLOORPIC;
|
||||||
if (ss->ceilingpic != P_CheckLevelFlat(ms->ceilingpic))
|
if (ss->ceilingpic != spawnss->ceilingpic)
|
||||||
diff |= SD_CEILPIC;
|
diff |= SD_CEILPIC;
|
||||||
|
|
||||||
if (ss->lightlevel != SHORT(ms->lightlevel))
|
if (ss->lightlevel != spawnss->lightlevel)
|
||||||
diff |= SD_LIGHT;
|
diff |= SD_LIGHT;
|
||||||
if (ss->special != SHORT(ms->special))
|
if (ss->special != spawnss->special)
|
||||||
diff |= SD_SPECIAL;
|
diff |= SD_SPECIAL;
|
||||||
|
|
||||||
if (ss->floor_xoffs != ss->spawn_flr_xoffs)
|
if (ss->floor_xoffs != spawnss->floor_xoffs)
|
||||||
diff2 |= SD_FXOFFS;
|
diff2 |= SD_FXOFFS;
|
||||||
if (ss->floor_yoffs != ss->spawn_flr_yoffs)
|
if (ss->floor_yoffs != spawnss->floor_yoffs)
|
||||||
diff2 |= SD_FYOFFS;
|
diff2 |= SD_FYOFFS;
|
||||||
if (ss->ceiling_xoffs != ss->spawn_ceil_xoffs)
|
if (ss->ceiling_xoffs != spawnss->ceiling_xoffs)
|
||||||
diff2 |= SD_CXOFFS;
|
diff2 |= SD_CXOFFS;
|
||||||
if (ss->ceiling_yoffs != ss->spawn_ceil_yoffs)
|
if (ss->ceiling_yoffs != spawnss->ceiling_yoffs)
|
||||||
diff2 |= SD_CYOFFS;
|
diff2 |= SD_CYOFFS;
|
||||||
if (ss->floorpic_angle != ss->spawn_flrpic_angle)
|
if (ss->floorpic_angle != spawnss->floorpic_angle)
|
||||||
diff2 |= SD_FLOORANG;
|
diff2 |= SD_FLOORANG;
|
||||||
if (ss->ceilingpic_angle != ss->spawn_flrpic_angle)
|
if (ss->ceilingpic_angle != spawnss->ceilingpic_angle)
|
||||||
diff2 |= SD_CEILANG;
|
diff2 |= SD_CEILANG;
|
||||||
|
|
||||||
if (ss->tag != SHORT(ms->tag))
|
if (ss->tag != spawnss->tag)
|
||||||
diff2 |= SD_TAG;
|
diff2 |= SD_TAG;
|
||||||
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
|
if (ss->nexttag != spawnss->nexttag || ss->firsttag != spawnss->firsttag)
|
||||||
diff3 |= SD_TAGLIST;
|
diff3 |= SD_TAGLIST;
|
||||||
|
|
||||||
if (ss->extra_colormap != ss->spawn_extra_colormap)
|
if (ss->extra_colormap != spawnss->extra_colormap)
|
||||||
diff3 |= SD_COLORMAP;
|
diff3 |= SD_COLORMAP;
|
||||||
|
|
||||||
// Check if any of the sector's FOFs differ from how they spawned
|
// Check if any of the sector's FOFs differ from how they spawned
|
||||||
|
@ -955,45 +934,41 @@ static void P_NetArchiveWorld(void)
|
||||||
WRITEUINT16(put, 0xffff);
|
WRITEUINT16(put, 0xffff);
|
||||||
|
|
||||||
// do lines
|
// do lines
|
||||||
for (i = 0; i < numlines; i++, mld++, li++)
|
for (i = 0; i < numlines; i++, spawnli++, li++)
|
||||||
{
|
{
|
||||||
diff = diff2 = diff3 = 0;
|
diff = diff2 = diff3 = 0;
|
||||||
|
|
||||||
if (li->special != SHORT(mld->special))
|
if (li->special != spawnli->special)
|
||||||
diff |= LD_SPECIAL;
|
diff |= LD_SPECIAL;
|
||||||
|
|
||||||
if (SHORT(mld->special) == 321 || SHORT(mld->special) == 322) // only reason li->callcount would be non-zero is if either of these are involved
|
if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved
|
||||||
diff |= LD_CLLCOUNT;
|
diff |= LD_CLLCOUNT;
|
||||||
|
|
||||||
if (li->sidenum[0] != 0xffff)
|
if (li->sidenum[0] != 0xffff)
|
||||||
{
|
{
|
||||||
si = &sides[li->sidenum[0]];
|
si = &sides[li->sidenum[0]];
|
||||||
if (si->textureoffset != SHORT(msd[li->sidenum[0]].textureoffset)<<FRACBITS)
|
spawnsi = &spawnsides[li->sidenum[0]];
|
||||||
|
if (si->textureoffset != spawnsi->textureoffset)
|
||||||
diff |= LD_S1TEXOFF;
|
diff |= LD_S1TEXOFF;
|
||||||
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
|
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
|
||||||
if (R_CheckTextureNumForName(msd[li->sidenum[0]].toptexture) != -1
|
if (si->toptexture != spawnsi->toptexture)
|
||||||
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture))
|
|
||||||
diff |= LD_S1TOPTEX;
|
diff |= LD_S1TOPTEX;
|
||||||
if (R_CheckTextureNumForName(msd[li->sidenum[0]].bottomtexture) != -1
|
if (si->bottomtexture != spawnsi->bottomtexture)
|
||||||
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture))
|
|
||||||
diff |= LD_S1BOTTEX;
|
diff |= LD_S1BOTTEX;
|
||||||
if (R_CheckTextureNumForName(msd[li->sidenum[0]].midtexture) != -1
|
if (si->midtexture != spawnsi->midtexture)
|
||||||
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture))
|
|
||||||
diff |= LD_S1MIDTEX;
|
diff |= LD_S1MIDTEX;
|
||||||
}
|
}
|
||||||
if (li->sidenum[1] != 0xffff)
|
if (li->sidenum[1] != 0xffff)
|
||||||
{
|
{
|
||||||
si = &sides[li->sidenum[1]];
|
si = &sides[li->sidenum[1]];
|
||||||
if (si->textureoffset != SHORT(msd[li->sidenum[1]].textureoffset)<<FRACBITS)
|
spawnsi = &spawnsides[li->sidenum[1]];
|
||||||
|
if (si->textureoffset != spawnsi->textureoffset)
|
||||||
diff2 |= LD_S2TEXOFF;
|
diff2 |= LD_S2TEXOFF;
|
||||||
if (R_CheckTextureNumForName(msd[li->sidenum[1]].toptexture) != -1
|
if (si->toptexture != spawnsi->toptexture)
|
||||||
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture))
|
|
||||||
diff2 |= LD_S2TOPTEX;
|
diff2 |= LD_S2TOPTEX;
|
||||||
if (R_CheckTextureNumForName(msd[li->sidenum[1]].bottomtexture) != -1
|
if (si->bottomtexture != spawnsi->bottomtexture)
|
||||||
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture))
|
|
||||||
diff2 |= LD_S2BOTTEX;
|
diff2 |= LD_S2BOTTEX;
|
||||||
if (R_CheckTextureNumForName(msd[li->sidenum[1]].midtexture) != -1
|
if (si->midtexture != spawnsi->midtexture)
|
||||||
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture))
|
|
||||||
diff2 |= LD_S2MIDTEX;
|
diff2 |= LD_S2MIDTEX;
|
||||||
if (diff2)
|
if (diff2)
|
||||||
diff |= LD_DIFF2;
|
diff |= LD_DIFF2;
|
||||||
|
|
652
src/p_setup.c
652
src/p_setup.c
|
@ -103,6 +103,9 @@ node_t *nodes;
|
||||||
line_t *lines;
|
line_t *lines;
|
||||||
side_t *sides;
|
side_t *sides;
|
||||||
mapthing_t *mapthings;
|
mapthing_t *mapthings;
|
||||||
|
sector_t *spawnsectors;
|
||||||
|
line_t *spawnlines;
|
||||||
|
side_t *spawnsides;
|
||||||
INT32 numstarposts;
|
INT32 numstarposts;
|
||||||
UINT16 bossdisabled;
|
UINT16 bossdisabled;
|
||||||
boolean stoppedclock;
|
boolean stoppedclock;
|
||||||
|
@ -367,27 +370,12 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade)
|
||||||
return mapheaderinfo[map-1]->grades[mare].grade[grade-1];
|
return mapheaderinfo[map-1]->grades[mare].grade[grade-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads the vertexes for a level.
|
// Loads the vertexes for a level.
|
||||||
*
|
static inline void P_LoadRawVertexes(UINT8 *data)
|
||||||
* \param lump VERTEXES lump number.
|
|
||||||
* \sa ML_VERTEXES
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void P_LoadRawVertexes(UINT8 *data, size_t i)
|
|
||||||
{
|
{
|
||||||
mapvertex_t *ml;
|
mapvertex_t *ml = (mapvertex_t *)data;
|
||||||
vertex_t *li;
|
vertex_t *li = vertexes;
|
||||||
|
size_t i;
|
||||||
numvertexes = i / sizeof (mapvertex_t);
|
|
||||||
|
|
||||||
if (numvertexes <= 0)
|
|
||||||
I_Error("Level has no vertices"); // instead of crashing
|
|
||||||
|
|
||||||
// Allocate zone memory for buffer.
|
|
||||||
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
ml = (mapvertex_t *)data;
|
|
||||||
li = vertexes;
|
|
||||||
|
|
||||||
// Copy and convert vertex coordinates, internal representation as fixed.
|
// Copy and convert vertex coordinates, internal representation as fixed.
|
||||||
for (i = 0; i < numvertexes; i++, li++, ml++)
|
for (i = 0; i < numvertexes; i++, li++, ml++)
|
||||||
|
@ -397,13 +385,6 @@ static inline void P_LoadRawVertexes(UINT8 *data, size_t i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_LoadRawVertexes(data, W_LumpLength(lumpnum));
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Computes the length of a seg in fracunits.
|
/** Computes the length of a seg in fracunits.
|
||||||
*
|
*
|
||||||
* \param seg Seg to compute length for.
|
* \param seg Seg to compute length for.
|
||||||
|
@ -435,25 +416,15 @@ static inline float P_SegLengthFloat(seg_t *seg)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Loads the SEGS resource from a level.
|
// Loads the SEGS resource from a level.
|
||||||
*
|
static void P_LoadRawSegs(UINT8 *data)
|
||||||
* \param lump Lump number of the SEGS resource.
|
|
||||||
* \sa ::ML_SEGS
|
|
||||||
*/
|
|
||||||
static void P_LoadRawSegs(UINT8 *data, size_t i)
|
|
||||||
{
|
{
|
||||||
INT32 linedef, side;
|
INT32 linedef, side;
|
||||||
mapseg_t *ml;
|
mapseg_t *ml = (mapseg_t*)data;
|
||||||
seg_t *li;
|
seg_t *li = segs;
|
||||||
line_t *ldef;
|
line_t *ldef;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
numsegs = i / sizeof (mapseg_t);
|
|
||||||
if (numsegs <= 0)
|
|
||||||
I_Error("Level has no segs"); // instead of crashing
|
|
||||||
segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
ml = (mapseg_t *)data;
|
|
||||||
li = segs;
|
|
||||||
for (i = 0; i < numsegs; i++, li++, ml++)
|
for (i = 0; i < numsegs; i++, li++, ml++)
|
||||||
{
|
{
|
||||||
li->v1 = &vertexes[SHORT(ml->v1)];
|
li->v1 = &vertexes[SHORT(ml->v1)];
|
||||||
|
@ -478,7 +449,7 @@ static void P_LoadRawSegs(UINT8 *data, size_t i)
|
||||||
li->side = side = SHORT(ml->side);
|
li->side = side = SHORT(ml->side);
|
||||||
li->sidedef = &sides[ldef->sidenum[side]];
|
li->sidedef = &sides[ldef->sidenum[side]];
|
||||||
li->frontsector = sides[ldef->sidenum[side]].sector;
|
li->frontsector = sides[ldef->sidenum[side]].sector;
|
||||||
if (ldef-> flags & ML_TWOSIDED)
|
if (ldef->flags & ML_TWOSIDED)
|
||||||
li->backsector = sides[ldef->sidenum[side^1]].sector;
|
li->backsector = sides[ldef->sidenum[side^1]].sector;
|
||||||
else
|
else
|
||||||
li->backsector = 0;
|
li->backsector = 0;
|
||||||
|
@ -488,30 +459,12 @@ static void P_LoadRawSegs(UINT8 *data, size_t i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadSegs(lumpnum_t lumpnum)
|
// Loads the SSECTORS resource from a level.
|
||||||
|
static inline void P_LoadRawSubsectors(void *data)
|
||||||
{
|
{
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
mapsubsector_t *ms = (mapsubsector_t*)data;
|
||||||
P_LoadRawSegs(data, W_LumpLength(lumpnum));
|
subsector_t *ss = subsectors;
|
||||||
Z_Free(data);
|
size_t i;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Loads the SSECTORS resource from a level.
|
|
||||||
*
|
|
||||||
* \param lump Lump number of the SSECTORS resource.
|
|
||||||
* \sa ::ML_SSECTORS
|
|
||||||
*/
|
|
||||||
static inline void P_LoadRawSubsectors(void *data, size_t i)
|
|
||||||
{
|
|
||||||
mapsubsector_t *ms;
|
|
||||||
subsector_t *ss;
|
|
||||||
|
|
||||||
numsubsectors = i / sizeof (mapsubsector_t);
|
|
||||||
if (numsubsectors <= 0)
|
|
||||||
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
|
|
||||||
ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
ms = (mapsubsector_t *)data;
|
|
||||||
|
|
||||||
for (i = 0; i < numsubsectors; i++, ss++, ms++)
|
for (i = 0; i < numsubsectors; i++, ss++, ms++)
|
||||||
{
|
{
|
||||||
|
@ -525,13 +478,6 @@ static inline void P_LoadRawSubsectors(void *data, size_t i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadSubsectors(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_LoadRawSubsectors(data, W_LumpLength(lumpnum));
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// levelflats
|
// levelflats
|
||||||
//
|
//
|
||||||
|
@ -698,20 +644,12 @@ INT32 P_CheckLevelFlat(const char *flatname)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up the ingame sectors structures.
|
// Sets up the ingame sectors structures.
|
||||||
// Lumpnum is the lumpnum of a SECTORS lump.
|
static void P_LoadRawSectors(UINT8 *data)
|
||||||
static void P_LoadRawSectors(UINT8 *data, size_t i)
|
|
||||||
{
|
{
|
||||||
mapsector_t *ms;
|
mapsector_t *ms = (mapsector_t *)data;
|
||||||
sector_t *ss;
|
sector_t *ss = sectors;
|
||||||
levelflat_t *foundflats;
|
levelflat_t *foundflats;
|
||||||
|
size_t i;
|
||||||
// We count how many sectors we got.
|
|
||||||
numsectors = i / sizeof (mapsector_t);
|
|
||||||
if (numsectors <= 0)
|
|
||||||
I_Error("Level has no sectors");
|
|
||||||
|
|
||||||
// Allocate as much memory as we need into the global sectors table.
|
|
||||||
sectors = Z_Calloc(numsectors*sizeof (*sectors), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
// Allocate a big chunk of memory as big as our MAXLEVELFLATS limit.
|
// Allocate a big chunk of memory as big as our MAXLEVELFLATS limit.
|
||||||
//Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty
|
//Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty
|
||||||
|
@ -722,8 +660,6 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
numlevelflats = 0;
|
numlevelflats = 0;
|
||||||
|
|
||||||
// For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss.
|
// For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss.
|
||||||
ms = (mapsector_t *)data;
|
|
||||||
ss = sectors;
|
|
||||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||||
{
|
{
|
||||||
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
||||||
|
@ -733,11 +669,9 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
||||||
|
|
||||||
ss->lightlevel = SHORT(ms->lightlevel);
|
ss->lightlevel = SHORT(ms->lightlevel);
|
||||||
ss->spawn_lightlevel = SHORT(ms->lightlevel);
|
|
||||||
ss->special = SHORT(ms->special);
|
ss->special = SHORT(ms->special);
|
||||||
ss->tag = SHORT(ms->tag);
|
ss->tag = SHORT(ms->tag);
|
||||||
ss->nexttag = ss->firsttag = -1;
|
ss->nexttag = ss->firsttag = -1;
|
||||||
ss->spawn_nexttag = ss->spawn_firsttag = -1;
|
|
||||||
|
|
||||||
memset(&ss->soundorg, 0, sizeof(ss->soundorg));
|
memset(&ss->soundorg, 0, sizeof(ss->soundorg));
|
||||||
ss->validcount = 0;
|
ss->validcount = 0;
|
||||||
|
@ -772,9 +706,7 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
ss->spawn_extra_colormap = NULL;
|
ss->spawn_extra_colormap = NULL;
|
||||||
|
|
||||||
ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0;
|
ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0;
|
||||||
ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0;
|
|
||||||
ss->floorpic_angle = ss->ceilingpic_angle = 0;
|
ss->floorpic_angle = ss->ceilingpic_angle = 0;
|
||||||
ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0;
|
|
||||||
ss->gravity = NULL;
|
ss->gravity = NULL;
|
||||||
ss->cullheight = NULL;
|
ss->cullheight = NULL;
|
||||||
ss->verticalflip = false;
|
ss->verticalflip = false;
|
||||||
|
@ -805,29 +737,15 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
P_SetupLevelFlatAnims();
|
P_SetupLevelFlatAnims();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadSectors(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_LoadRawSectors(data, W_LumpLength(lumpnum));
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_LoadNodes
|
// P_LoadNodes
|
||||||
//
|
//
|
||||||
static void P_LoadRawNodes(UINT8 *data, size_t i)
|
static void P_LoadRawNodes(UINT8 *data)
|
||||||
{
|
{
|
||||||
UINT8 j, k;
|
UINT8 j, k;
|
||||||
mapnode_t *mn;
|
mapnode_t *mn = (mapnode_t*)data;
|
||||||
node_t *no;
|
node_t *no = nodes;
|
||||||
|
size_t i;
|
||||||
numnodes = i / sizeof (mapnode_t);
|
|
||||||
if (numnodes <= 0)
|
|
||||||
I_Error("Level has no nodes");
|
|
||||||
nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
mn = (mapnode_t *)data;
|
|
||||||
no = nodes;
|
|
||||||
|
|
||||||
for (i = 0; i < numnodes; i++, no++, mn++)
|
for (i = 0; i < numnodes; i++, no++, mn++)
|
||||||
{
|
{
|
||||||
|
@ -844,13 +762,6 @@ static void P_LoadRawNodes(UINT8 *data, size_t i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadNodes(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_LoadRawNodes(data, W_LumpLength(lumpnum));
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_ReloadRings
|
// P_ReloadRings
|
||||||
// Used by NiGHTS, clears all ring/wing/etc items and respawns them
|
// Used by NiGHTS, clears all ring/wing/etc items and respawns them
|
||||||
|
@ -1002,12 +913,10 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void P_PrepareRawThings(UINT8 *data, size_t i)
|
static void P_PrepareRawThings(UINT8 *data)
|
||||||
{
|
{
|
||||||
mapthing_t *mt;
|
mapthing_t *mt;
|
||||||
|
size_t i;
|
||||||
nummapthings = i / (5 * sizeof (INT16));
|
|
||||||
mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
|
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
|
||||||
{
|
{
|
||||||
|
@ -1028,13 +937,6 @@ static void P_PrepareRawThings(UINT8 *data, size_t i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_PrepareThings(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_PrepareRawThings(data, W_LumpLength(lumpnum));
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void P_SpawnEmeraldHunt(void)
|
static void P_SpawnEmeraldHunt(void)
|
||||||
{
|
{
|
||||||
INT32 emer1, emer2, emer3;
|
INT32 emer1, emer2, emer3;
|
||||||
|
@ -1085,7 +987,7 @@ static void P_LoadThings(boolean loademblems)
|
||||||
size_t i;
|
size_t i;
|
||||||
mapthing_t *mt;
|
mapthing_t *mt;
|
||||||
|
|
||||||
// Spawn axis points first so they are at the front of the list for fast searching.
|
// Spawn axis points first so they are at the front of the list for fast searching.
|
||||||
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
|
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
|
||||||
{
|
{
|
||||||
switch (mt->type)
|
switch (mt->type)
|
||||||
|
@ -1183,33 +1085,46 @@ void P_WriteThings(lumpnum_t lumpnum)
|
||||||
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadRawLineDefs(UINT8 *data, size_t i)
|
static void P_LoadRawLineDefs(UINT8 *data)
|
||||||
{
|
{
|
||||||
maplinedef_t *mld;
|
maplinedef_t *mld = (maplinedef_t *)data;
|
||||||
line_t *ld;
|
line_t *ld = lines;
|
||||||
vertex_t *v1, *v2;
|
size_t i;
|
||||||
|
|
||||||
numlines = i / sizeof (maplinedef_t);
|
|
||||||
if (numlines <= 0)
|
|
||||||
I_Error("Level has no linedefs");
|
|
||||||
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
mld = (maplinedef_t *)data;
|
|
||||||
ld = lines;
|
|
||||||
for (i = 0; i < numlines; i++, mld++, ld++)
|
for (i = 0; i < numlines; i++, mld++, ld++)
|
||||||
{
|
{
|
||||||
ld->flags = SHORT(mld->flags);
|
ld->flags = SHORT(mld->flags);
|
||||||
ld->special = SHORT(mld->special);
|
ld->special = SHORT(mld->special);
|
||||||
ld->tag = SHORT(mld->tag);
|
ld->tag = SHORT(mld->tag);
|
||||||
v1 = ld->v1 = &vertexes[SHORT(mld->v1)];
|
ld->v1 = &vertexes[SHORT(mld->v1)];
|
||||||
v2 = ld->v2 = &vertexes[SHORT(mld->v2)];
|
ld->v2 = &vertexes[SHORT(mld->v2)];
|
||||||
ld->dx = v2->x - v1->x;
|
|
||||||
ld->dy = v2->y - v1->y;
|
ld->sidenum[0] = SHORT(mld->sidenum[0]);
|
||||||
|
ld->sidenum[1] = SHORT(mld->sidenum[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_SetupLines(void)
|
||||||
|
{
|
||||||
|
line_t *ld = lines;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < numlines; i++, ld++)
|
||||||
|
{
|
||||||
|
vertex_t *v1 = ld->v1;
|
||||||
|
vertex_t *v2 = ld->v2;
|
||||||
|
|
||||||
#ifdef WALLSPLATS
|
#ifdef WALLSPLATS
|
||||||
ld->splats = NULL;
|
ld->splats = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
ld->polyobj = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ld->dx = v2->x - v1->x;
|
||||||
|
ld->dy = v2->y - v1->y;
|
||||||
|
|
||||||
if (!ld->dx)
|
if (!ld->dx)
|
||||||
ld->slopetype = ST_VERTICAL;
|
ld->slopetype = ST_VERTICAL;
|
||||||
else if (!ld->dy)
|
else if (!ld->dy)
|
||||||
|
@ -1241,62 +1156,46 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i)
|
||||||
ld->bbox[BOXTOP] = v1->y;
|
ld->bbox[BOXTOP] = v1->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
ld->sidenum[0] = SHORT(mld->sidenum[0]);
|
|
||||||
ld->sidenum[1] = SHORT(mld->sidenum[1]);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// cph 2006/09/30 - fix sidedef errors right away.
|
// cph 2006/09/30 - fix sidedef errors right away.
|
||||||
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
|
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
|
||||||
UINT8 j;
|
UINT8 j;
|
||||||
|
|
||||||
for (j=0; j < 2; j++)
|
for (j=0; j < 2; j++)
|
||||||
{
|
|
||||||
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
||||||
{
|
{
|
||||||
ld->sidenum[j] = 0xffff;
|
ld->sidenum[j] = 0xffff;
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1));
|
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ld->frontsector = ld->backsector = NULL;
|
ld->frontsector = ld->backsector = NULL;
|
||||||
ld->validcount = 0;
|
ld->validcount = 0;
|
||||||
ld->firsttag = ld->nexttag = -1;
|
ld->firsttag = ld->nexttag = -1;
|
||||||
ld->callcount = 0;
|
ld->callcount = 0;
|
||||||
// killough 11/98: fix common wad errors (missing sidedefs):
|
|
||||||
|
|
||||||
|
// killough 11/98: fix common wad errors (missing sidedefs):
|
||||||
if (ld->sidenum[0] == 0xffff)
|
if (ld->sidenum[0] == 0xffff)
|
||||||
{
|
{
|
||||||
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
||||||
// cph - print a warning about the bug
|
// cph - print a warning about the bug
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1));
|
CONS_Debug(DBG_SETUP, "Linedef %s missing first sidedef\n", sizeu1(numlines-i-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
||||||
{
|
{
|
||||||
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
||||||
// cph - print a warning about the bug
|
// cph - print a warning about the bug
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1));
|
CONS_Debug(DBG_SETUP, "Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ld->sidenum[0] != 0xffff && ld->special)
|
if (ld->sidenum[0] != 0xffff && ld->special)
|
||||||
sides[ld->sidenum[0]].special = ld->special;
|
sides[ld->sidenum[0]].special = ld->special;
|
||||||
if (ld->sidenum[1] != 0xffff && ld->special)
|
if (ld->sidenum[1] != 0xffff && ld->special)
|
||||||
sides[ld->sidenum[1]].special = ld->special;
|
sides[ld->sidenum[1]].special = ld->special;
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
|
||||||
ld->polyobj = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_LoadRawLineDefs(data, W_LumpLength(lumpnum));
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void P_LoadLineDefs2(void)
|
static void P_LoadLineDefs2(void)
|
||||||
{
|
{
|
||||||
size_t i = numlines;
|
size_t i = numlines;
|
||||||
|
@ -1399,22 +1298,6 @@ static void P_LoadLineDefs2(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline void P_LoadRawSideDefs(size_t i)
|
|
||||||
{
|
|
||||||
numsides = i / sizeof (mapsidedef_t);
|
|
||||||
if (numsides <= 0)
|
|
||||||
I_Error("Level has no sidedefs");
|
|
||||||
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
P_LoadRawSideDefs(W_LumpLength(lumpnum));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void P_LoadRawSideDefs2(void *data)
|
static void P_LoadRawSideDefs2(void *data)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
|
@ -1575,15 +1458,6 @@ static void P_LoadRawSideDefs2(void *data)
|
||||||
R_ClearTextureNumCache(true);
|
R_ClearTextureNumCache(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay loading texture names until after loaded linedefs.
|
|
||||||
static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
P_LoadRawSideDefs2(data);
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1)
|
static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1)
|
||||||
{
|
{
|
||||||
fixed_t bbox[4];
|
fixed_t bbox[4];
|
||||||
|
@ -1863,84 +1737,11 @@ static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_LoadBlockMap
|
|
||||||
//
|
|
||||||
// Levels might not have a blockmap, so if one does not exist
|
|
||||||
// this should return false.
|
|
||||||
static boolean P_LoadBlockMap(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
(void)lumpnum;
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
size_t count;
|
|
||||||
const char *lumpname = W_CheckNameForNum(lumpnum);
|
|
||||||
|
|
||||||
// Check if the lump exists, and if it's named "BLOCKMAP"
|
|
||||||
if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = W_LumpLength(lumpnum);
|
|
||||||
|
|
||||||
if (!count || count >= 0x20000)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
{
|
|
||||||
INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL);
|
|
||||||
if (!wadblockmaplump)
|
|
||||||
return false;
|
|
||||||
W_ReadLump(lumpnum, wadblockmaplump);
|
|
||||||
count /= 2;
|
|
||||||
P_ReadBlockMapLump(wadblockmaplump, count);
|
|
||||||
free(wadblockmaplump);
|
|
||||||
}
|
|
||||||
|
|
||||||
bmaporgx = blockmaplump[0]<<FRACBITS;
|
|
||||||
bmaporgy = blockmaplump[1]<<FRACBITS;
|
|
||||||
bmapwidth = blockmaplump[2];
|
|
||||||
bmapheight = blockmaplump[3];
|
|
||||||
|
|
||||||
// clear out mobj chains
|
|
||||||
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
|
|
||||||
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
|
||||||
blockmap = blockmaplump+4;
|
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
|
||||||
// haleyjd 2/22/06: setup polyobject blockmap
|
|
||||||
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
|
|
||||||
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
/* Original
|
|
||||||
blockmaplump = W_CacheLumpNum(lump, PU_LEVEL);
|
|
||||||
blockmap = blockmaplump+4;
|
|
||||||
count = W_LumpLength (lump)/2;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
blockmaplump[i] = SHORT(blockmaplump[i]);
|
|
||||||
|
|
||||||
bmaporgx = blockmaplump[0]<<FRACBITS;
|
|
||||||
bmaporgy = blockmaplump[1]<<FRACBITS;
|
|
||||||
bmapwidth = blockmaplump[2];
|
|
||||||
bmapheight = blockmaplump[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear out mobj chains
|
|
||||||
count = sizeof (*blocklinks)*bmapwidth*bmapheight;
|
|
||||||
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
|
|
||||||
return true;
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// This needs to be a separate function
|
// This needs to be a separate function
|
||||||
// because making both the WAD and PK3 loading code use
|
// because making both the WAD and PK3 loading code use
|
||||||
// the same functions is trickier than it looks for blockmap
|
// the same functions is trickier than it looks for blockmap
|
||||||
// -- Monster Iestyn 09/01/18
|
// -- Monster Iestyn 09/01/18
|
||||||
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname)
|
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -1948,12 +1749,6 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname
|
||||||
(void)lumpname;
|
(void)lumpname;
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
// Check if the lump is named "BLOCKMAP"
|
|
||||||
if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0)
|
|
||||||
{
|
|
||||||
CONS_Printf("No blockmap lump found for pk3!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!count || count >= 0x20000)
|
if (!count || count >= 0x20000)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2079,47 +1874,10 @@ static void P_GroupLines(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_LoadReject
|
|
||||||
//
|
|
||||||
// Detect if the REJECT lump is valid,
|
|
||||||
// if not, rejectmatrix will be NULL
|
|
||||||
static void P_LoadReject(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
size_t count;
|
|
||||||
const char *lumpname = W_CheckNameForNum(lumpnum);
|
|
||||||
|
|
||||||
// Check if the lump exists, and if it's named "REJECT"
|
|
||||||
if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0)
|
|
||||||
{
|
|
||||||
rejectmatrix = NULL;
|
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadReject: No valid REJECT lump found\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = W_LumpLength(lumpnum);
|
|
||||||
|
|
||||||
if (!count) // zero length, someone probably used ZDBSP
|
|
||||||
{
|
|
||||||
rejectmatrix = NULL;
|
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadReject: REJECT lump has size 0, will not be loaded\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PK3 version
|
// PK3 version
|
||||||
// -- Monster Iestyn 09/01/18
|
// -- Monster Iestyn 09/01/18
|
||||||
static void P_LoadRawReject(UINT8 *data, size_t count, const char *lumpname)
|
static void P_LoadRawReject(UINT8 *data, size_t count)
|
||||||
{
|
{
|
||||||
// Check if the lump is named "REJECT"
|
|
||||||
if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0)
|
|
||||||
{
|
|
||||||
rejectmatrix = NULL;
|
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadRawReject: No valid REJECT lump found\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!count) // zero length, someone probably used ZDBSP
|
if (!count) // zero length, someone probably used ZDBSP
|
||||||
{
|
{
|
||||||
rejectmatrix = NULL;
|
rejectmatrix = NULL;
|
||||||
|
@ -2132,6 +1890,126 @@ static void P_LoadRawReject(UINT8 *data, size_t count, const char *lumpname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void P_LoadMapBSP(const virtres_t* virt)
|
||||||
|
{
|
||||||
|
virtlump_t* virtssectors = vres_Find(virt, "SSECTORS");
|
||||||
|
virtlump_t* virtsegs = vres_Find(virt, "SEGS");
|
||||||
|
virtlump_t* virtnodes = vres_Find(virt, "NODES");
|
||||||
|
|
||||||
|
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
|
||||||
|
numnodes = virtnodes->size / sizeof(mapnode_t);
|
||||||
|
numsegs = virtsegs->size / sizeof(mapseg_t);
|
||||||
|
|
||||||
|
if (numsubsectors <= 0)
|
||||||
|
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
|
||||||
|
if (numnodes <= 0)
|
||||||
|
I_Error("Level has no nodes");
|
||||||
|
if (numsegs <= 0)
|
||||||
|
I_Error("Level has no segs");
|
||||||
|
|
||||||
|
subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL);
|
||||||
|
nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL);
|
||||||
|
segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
// Nodes
|
||||||
|
P_LoadRawSubsectors(virtssectors->data);
|
||||||
|
P_LoadRawNodes(virtnodes->data);
|
||||||
|
P_LoadRawSegs(virtsegs->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_LoadMapLUT(const virtres_t* virt)
|
||||||
|
{
|
||||||
|
virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP");
|
||||||
|
virtlump_t* virtreject = vres_Find(virt, "REJECT");
|
||||||
|
|
||||||
|
// Lookup tables
|
||||||
|
if (virtreject)
|
||||||
|
P_LoadRawReject(virtreject->data, virtreject->size);
|
||||||
|
else
|
||||||
|
rejectmatrix = NULL;
|
||||||
|
|
||||||
|
if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size)))
|
||||||
|
P_CreateBlockMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_LoadMapData(const virtres_t* virt)
|
||||||
|
{
|
||||||
|
virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL;
|
||||||
|
#ifdef UDMF
|
||||||
|
virtlump_t* textmap = vres_Find(virt, "TEXTMAP");
|
||||||
|
|
||||||
|
// Count map data.
|
||||||
|
if (textmap)
|
||||||
|
{
|
||||||
|
nummapthings = 0;
|
||||||
|
numlines = 0;
|
||||||
|
numsides = 0;
|
||||||
|
numvertexes = 0;
|
||||||
|
numsectors = 0;
|
||||||
|
|
||||||
|
// Count how many entries for each type we got in textmap.
|
||||||
|
//TextmapCount(vtextmap->data, vtextmap->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
virtthings = vres_Find(virt, "THINGS");
|
||||||
|
virtvertexes = vres_Find(virt, "VERTEXES");
|
||||||
|
virtsectors = vres_Find(virt, "SECTORS");
|
||||||
|
virtsidedefs = vres_Find(virt, "SIDEDEFS");
|
||||||
|
virtlinedefs = vres_Find(virt, "LINEDEFS");
|
||||||
|
|
||||||
|
if (!virtthings)
|
||||||
|
I_Error("THINGS lump not found");
|
||||||
|
if (!virtvertexes)
|
||||||
|
I_Error("VERTEXES lump not found");
|
||||||
|
if (!virtsectors)
|
||||||
|
I_Error("SECTORS lump not found");
|
||||||
|
if (!virtsidedefs)
|
||||||
|
I_Error("SIDEDEFS lump not found");
|
||||||
|
if (!virtlinedefs)
|
||||||
|
I_Error("LINEDEFS lump not found");
|
||||||
|
|
||||||
|
// Traditional doom map format just assumes the number of elements from the lump sizes.
|
||||||
|
numvertexes = virtvertexes->size / sizeof (mapvertex_t);
|
||||||
|
numsectors = virtsectors->size / sizeof (mapsector_t);
|
||||||
|
numsides = virtsidedefs->size / sizeof (mapsidedef_t);
|
||||||
|
numlines = virtlinedefs->size / sizeof (maplinedef_t);
|
||||||
|
nummapthings = virtthings->size / (5 * sizeof (INT16));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numvertexes <= 0)
|
||||||
|
I_Error("Level has no vertices");
|
||||||
|
if (numsectors <= 0)
|
||||||
|
I_Error("Level has no sectors");
|
||||||
|
if (numsides <= 0)
|
||||||
|
I_Error("Level has no sidedefs");
|
||||||
|
if (numlines <= 0)
|
||||||
|
I_Error("Level has no linedefs");
|
||||||
|
|
||||||
|
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
||||||
|
sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL);
|
||||||
|
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
||||||
|
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
||||||
|
mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
#ifdef UDMF
|
||||||
|
if (textmap)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Strict map data
|
||||||
|
P_LoadRawVertexes(virtvertexes->data);
|
||||||
|
P_LoadRawSectors(virtsectors->data);
|
||||||
|
P_LoadRawLineDefs(virtlinedefs->data);
|
||||||
|
P_SetupLines();
|
||||||
|
P_LoadRawSideDefs2(virtsidedefs->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static char *levellumps[] =
|
static char *levellumps[] =
|
||||||
{
|
{
|
||||||
|
@ -2307,6 +2185,8 @@ void P_LoadThingsOnly(void)
|
||||||
// Search through all the thinkers.
|
// Search through all the thinkers.
|
||||||
thinker_t *think;
|
thinker_t *think;
|
||||||
INT32 i, viewid = -1, centerid = -1; // for skyboxes
|
INT32 i, viewid = -1, centerid = -1; // for skyboxes
|
||||||
|
virtres_t* virt = vres_GetMap(lastloadedmaplumpnum);
|
||||||
|
virtlump_t* vth = vres_Find(virt, "THINGS");
|
||||||
|
|
||||||
// check if these are any of the normal viewpoint/centerpoint mobjs in the level or not
|
// check if these are any of the normal viewpoint/centerpoint mobjs in the level or not
|
||||||
if (skyboxmo[0] || skyboxmo[1])
|
if (skyboxmo[0] || skyboxmo[1])
|
||||||
|
@ -2318,7 +2198,6 @@ void P_LoadThingsOnly(void)
|
||||||
centerid = i; // save id just in case
|
centerid = i; // save id just in case
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
|
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
|
||||||
{
|
{
|
||||||
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||||
|
@ -2328,18 +2207,11 @@ void P_LoadThingsOnly(void)
|
||||||
|
|
||||||
P_LevelInitStuff();
|
P_LevelInitStuff();
|
||||||
|
|
||||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
P_PrepareRawThings(vth->data);
|
||||||
{ // HACK: Open wad file rather quickly so we can use the things lump
|
|
||||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
|
||||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
|
||||||
fileinfo += ML_THINGS; // we only need the THINGS lump
|
|
||||||
P_PrepareRawThings(wadData + fileinfo->filepos, fileinfo->size);
|
|
||||||
Z_Free(wadData); // we're done with this now
|
|
||||||
}
|
|
||||||
else // phew it's just a WAD
|
|
||||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
|
||||||
P_LoadThings(true);
|
P_LoadThings(true);
|
||||||
|
|
||||||
|
vres_Free(virt);
|
||||||
|
|
||||||
// restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that
|
// restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that
|
||||||
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
|
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
|
||||||
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
|
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
|
||||||
|
@ -2371,7 +2243,7 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_MakeMapMD5(lumpnum_t maplumpnum, void *dest)
|
static void P_MakeMapMD5(virtres_t* virt, void *dest)
|
||||||
{
|
{
|
||||||
unsigned char linemd5[16];
|
unsigned char linemd5[16];
|
||||||
unsigned char sectormd5[16];
|
unsigned char sectormd5[16];
|
||||||
|
@ -2382,20 +2254,15 @@ static void P_MakeMapMD5(lumpnum_t maplumpnum, void *dest)
|
||||||
|
|
||||||
// Create a hash for the current map
|
// Create a hash for the current map
|
||||||
// get the actual lumps!
|
// get the actual lumps!
|
||||||
UINT8 *datalines = W_CacheLumpNum(maplumpnum + ML_LINEDEFS, PU_CACHE);
|
virtlump_t* virtlines = vres_Find(virt, "LINEDEFS");
|
||||||
UINT8 *datasectors = W_CacheLumpNum(maplumpnum + ML_SECTORS, PU_CACHE);
|
virtlump_t* virtsectors = vres_Find(virt, "SECTORS");
|
||||||
UINT8 *datathings = W_CacheLumpNum(maplumpnum + ML_THINGS, PU_CACHE);
|
virtlump_t* virtmthings = vres_Find(virt, "THINGS");
|
||||||
UINT8 *datasides = W_CacheLumpNum(maplumpnum + ML_SIDEDEFS, PU_CACHE);
|
virtlump_t* virtsides = vres_Find(virt, "SIDEDEFS");
|
||||||
|
|
||||||
P_MakeBufferMD5((char*)datalines, W_LumpLength(maplumpnum + ML_LINEDEFS), linemd5);
|
P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5);
|
||||||
P_MakeBufferMD5((char*)datasectors, W_LumpLength(maplumpnum + ML_SECTORS), sectormd5);
|
P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5);
|
||||||
P_MakeBufferMD5((char*)datathings, W_LumpLength(maplumpnum + ML_THINGS), thingmd5);
|
P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5);
|
||||||
P_MakeBufferMD5((char*)datasides, W_LumpLength(maplumpnum + ML_SIDEDEFS), sidedefmd5);
|
P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5);
|
||||||
|
|
||||||
Z_Free(datalines);
|
|
||||||
Z_Free(datasectors);
|
|
||||||
Z_Free(datathings);
|
|
||||||
Z_Free(datasides);
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF;
|
resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF;
|
||||||
|
@ -2631,7 +2498,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
INT32 i, loadprecip = 1, ranspecialwipe = 0;
|
INT32 i, loadprecip = 1, ranspecialwipe = 0;
|
||||||
INT32 loademblems = 1;
|
INT32 loademblems = 1;
|
||||||
INT32 fromnetsave = 0;
|
INT32 fromnetsave = 0;
|
||||||
boolean loadedbm = false;
|
|
||||||
sector_t *ss;
|
sector_t *ss;
|
||||||
boolean chase;
|
boolean chase;
|
||||||
levelloading = true;
|
levelloading = true;
|
||||||
|
@ -2879,110 +2745,48 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
// SRB2 determines the sky texture to be used depending on the map header.
|
// SRB2 determines the sky texture to be used depending on the map header.
|
||||||
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
|
P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true);
|
||||||
|
|
||||||
P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
|
||||||
// HACK ALERT: Cache the WAD, get the map data into the tables, free memory.
|
// reset the player starts
|
||||||
// As it is implemented right now, we're assuming an uncompressed WAD.
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
// (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.)
|
playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL;
|
||||||
// We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error.
|
|
||||||
if (W_IsLumpWad(lastloadedmaplumpnum))
|
for (i = 0; i < MAX_DM_STARTS; i++)
|
||||||
|
deathmatchstarts[i] = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
skyboxmo[i] = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
|
||||||
|
|
||||||
|
P_MapStart();
|
||||||
|
|
||||||
|
if (lastloadedmaplumpnum)
|
||||||
{
|
{
|
||||||
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
|
virtres_t* virt = vres_GetMap(lastloadedmaplumpnum);
|
||||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
|
||||||
//filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs;
|
|
||||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
|
||||||
UINT32 numlumps = ((wadinfo_t *)wadData)->numlumps;
|
|
||||||
|
|
||||||
if (numlumps < ML_REJECT) // at least 9 lumps should be in the wad for a map to be loaded
|
P_LoadMapData(virt);
|
||||||
{
|
P_LoadMapBSP(virt);
|
||||||
I_Error("Bad WAD file for map %s!\n", maplumpname);
|
P_LoadMapLUT(virt);
|
||||||
}
|
|
||||||
|
|
||||||
if (numlumps > ML_BLOCKMAP) // enough room for a BLOCKMAP lump at least
|
|
||||||
{
|
|
||||||
loadedbm = P_LoadRawBlockMap(
|
|
||||||
wadData + (fileinfo + ML_BLOCKMAP)->filepos,
|
|
||||||
(fileinfo + ML_BLOCKMAP)->size,
|
|
||||||
(fileinfo + ML_BLOCKMAP)->name);
|
|
||||||
}
|
|
||||||
P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size);
|
|
||||||
P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size);
|
|
||||||
P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size);
|
|
||||||
P_LoadRawLineDefs(wadData + (fileinfo + ML_LINEDEFS)->filepos, (fileinfo + ML_LINEDEFS)->size);
|
|
||||||
P_LoadRawSideDefs2(wadData + (fileinfo + ML_SIDEDEFS)->filepos);
|
|
||||||
P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size);
|
|
||||||
P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size);
|
|
||||||
P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size);
|
|
||||||
if (numlumps > ML_REJECT) // enough room for a REJECT lump at least
|
|
||||||
{
|
|
||||||
P_LoadRawReject(
|
|
||||||
wadData + (fileinfo + ML_REJECT)->filepos,
|
|
||||||
(fileinfo + ML_REJECT)->size,
|
|
||||||
(fileinfo + ML_REJECT)->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Important: take care of the ordering of the next functions.
|
|
||||||
if (!loadedbm)
|
|
||||||
P_CreateBlockMap(); // Graue 02-29-2004
|
|
||||||
P_LoadLineDefs2();
|
P_LoadLineDefs2();
|
||||||
P_GroupLines();
|
P_GroupLines();
|
||||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
|
||||||
|
|
||||||
// reset the player starts
|
// Copy relevant map data for NetArchive purposes.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL);
|
||||||
playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL;
|
spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
||||||
|
spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
||||||
|
|
||||||
for (i = 0; i < MAX_DM_STARTS; i++)
|
memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors));
|
||||||
deathmatchstarts[i] = NULL;
|
memcpy(spawnlines, lines, numlines * sizeof (*lines));
|
||||||
|
memcpy(spawnsides, sides, numsides * sizeof (*sides));
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
P_PrepareRawThings(vres_Find(virt, "THINGS")->data);
|
||||||
skyboxmo[i] = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
P_MakeMapMD5(virt, &mapmd5);
|
||||||
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
|
|
||||||
|
|
||||||
P_MapStart();
|
vres_Free(virt);
|
||||||
|
|
||||||
P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size);
|
|
||||||
Z_Free(wadData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Important: take care of the ordering of the next functions.
|
|
||||||
loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP);
|
|
||||||
P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES);
|
|
||||||
P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS);
|
|
||||||
P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS);
|
|
||||||
P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS);
|
|
||||||
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
|
|
||||||
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
|
|
||||||
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
|
|
||||||
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
|
|
||||||
P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
|
|
||||||
|
|
||||||
// Important: take care of the ordering of the next functions.
|
|
||||||
if (!loadedbm)
|
|
||||||
P_CreateBlockMap(); // Graue 02-29-2004
|
|
||||||
P_LoadLineDefs2();
|
|
||||||
P_GroupLines();
|
|
||||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
|
||||||
|
|
||||||
// reset the player starts
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_DM_STARTS; i++)
|
|
||||||
deathmatchstarts[i] = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
skyboxmo[i] = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
|
|
||||||
|
|
||||||
P_MapStart();
|
|
||||||
|
|
||||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// init gravity, tag lists,
|
// init gravity, tag lists,
|
||||||
|
|
33
src/p_spec.c
33
src/p_spec.c
|
@ -1603,8 +1603,6 @@ static inline void P_InitTagLists(void)
|
||||||
size_t j = (unsigned)sectors[i].tag % numsectors;
|
size_t j = (unsigned)sectors[i].tag % numsectors;
|
||||||
sectors[i].nexttag = sectors[j].firsttag;
|
sectors[i].nexttag = sectors[j].firsttag;
|
||||||
sectors[j].firsttag = (INT32)i;
|
sectors[j].firsttag = (INT32)i;
|
||||||
sectors[i].spawn_nexttag = sectors[i].nexttag;
|
|
||||||
sectors[j].spawn_firsttag = sectors[j].firsttag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = numlines - 1; i != (size_t)-1; i--)
|
for (i = numlines - 1; i != (size_t)-1; i--)
|
||||||
|
@ -6405,22 +6403,16 @@ static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flata
|
||||||
{
|
{
|
||||||
if (!(master->flags & ML_NETONLY)) // Modify floor flat alignment unless ML_NETONLY flag is set
|
if (!(master->flags & ML_NETONLY)) // Modify floor flat alignment unless ML_NETONLY flag is set
|
||||||
{
|
{
|
||||||
sector->spawn_flrpic_angle = sector->floorpic_angle = flatangle;
|
sector->floorpic_angle = flatangle;
|
||||||
sector->floor_xoffs += xoffs;
|
sector->floor_xoffs += xoffs;
|
||||||
sector->floor_yoffs += yoffs;
|
sector->floor_yoffs += yoffs;
|
||||||
// saved for netgames
|
|
||||||
sector->spawn_flr_xoffs = sector->floor_xoffs;
|
|
||||||
sector->spawn_flr_yoffs = sector->floor_yoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(master->flags & ML_NONET)) // Modify ceiling flat alignment unless ML_NONET flag is set
|
if (!(master->flags & ML_NONET)) // Modify ceiling flat alignment unless ML_NONET flag is set
|
||||||
{
|
{
|
||||||
sector->spawn_ceilpic_angle = sector->ceilingpic_angle = flatangle;
|
sector->ceilingpic_angle = flatangle;
|
||||||
sector->ceiling_xoffs += xoffs;
|
sector->ceiling_xoffs += xoffs;
|
||||||
sector->ceiling_yoffs += yoffs;
|
sector->ceiling_yoffs += yoffs;
|
||||||
// saved for netgames
|
|
||||||
sector->spawn_ceil_xoffs = sector->ceiling_xoffs;
|
|
||||||
sector->spawn_ceil_yoffs = sector->ceiling_yoffs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6441,7 +6433,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
INT32 j;
|
INT32 j;
|
||||||
thinkerlist_t *secthinkers;
|
thinkerlist_t *secthinkers;
|
||||||
thinker_t *th;
|
thinker_t *th;
|
||||||
|
virtres_t* virt = NULL;
|
||||||
// This used to be used, and *should* be used in the future,
|
// This used to be used, and *should* be used in the future,
|
||||||
// but currently isn't.
|
// but currently isn't.
|
||||||
(void)fromnetsave;
|
(void)fromnetsave;
|
||||||
|
@ -7193,17 +7185,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
UINT8 *data;
|
UINT8 *data;
|
||||||
UINT16 b;
|
UINT16 b;
|
||||||
|
|
||||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
if (!virt)
|
||||||
{ // HACK: Open wad file rather quickly so we can get the data from the sidedefs lump
|
virt = vres_GetMap(lastloadedmaplumpnum);
|
||||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
|
||||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
data = (UINT8*) vres_Find(virt, "SIDEDEFS")->data;
|
||||||
fileinfo += ML_SIDEDEFS; // we only need the SIDEDEFS lump
|
|
||||||
data = Z_Malloc(fileinfo->size, PU_STATIC, NULL);
|
|
||||||
M_Memcpy(data, wadData + fileinfo->filepos, fileinfo->size); // copy data
|
|
||||||
Z_Free(wadData); // we're done with this now
|
|
||||||
}
|
|
||||||
else // phew it's just a WAD
|
|
||||||
data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC);
|
|
||||||
|
|
||||||
for (b = 0; b < (INT16)numsides; b++)
|
for (b = 0; b < (INT16)numsides; b++)
|
||||||
{
|
{
|
||||||
|
@ -7223,7 +7208,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
I_Error("Make-Your-Own-FOF (tag %d) needs a value in the linedef's second side upper texture field.", lines[i].tag);
|
I_Error("Make-Your-Own-FOF (tag %d) needs a value in the linedef's second side upper texture field.", lines[i].tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Z_Free(data);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
I_Error("Make-Your-Own FOF (tag %d) found without a 2nd linedef side!", lines[i].tag);
|
I_Error("Make-Your-Own FOF (tag %d) found without a 2nd linedef side!", lines[i].tag);
|
||||||
|
@ -7449,6 +7433,9 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virt)
|
||||||
|
vres_Free(virt);
|
||||||
|
|
||||||
// Allocate each list
|
// Allocate each list
|
||||||
for (i = 0; i < numsectors; i++)
|
for (i = 0; i < numsectors; i++)
|
||||||
if(secthinkers[i].thinkers)
|
if(secthinkers[i].thinkers)
|
||||||
|
|
|
@ -1600,7 +1600,7 @@ void P_RestoreMusic(player_t *player)
|
||||||
P_PlayJingle(player, JT_SUPER);
|
P_PlayJingle(player, JT_SUPER);
|
||||||
|
|
||||||
// Invulnerability
|
// Invulnerability
|
||||||
else if (player->powers[pw_invulnerability] > 1)
|
else if (player->powers[pw_invulnerability] > 1 && !player->powers[pw_super])
|
||||||
{
|
{
|
||||||
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
|
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
|
||||||
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
|
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
|
||||||
|
@ -5128,11 +5128,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
||||||
boolean elem = ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL);
|
boolean elem = ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL);
|
||||||
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
|
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
|
||||||
if (elem)
|
if (elem)
|
||||||
{
|
|
||||||
player->pflags |= PF_NOJUMPDAMAGE;
|
|
||||||
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
|
|
||||||
S_StartSound(player->mo, sfx_s3k43);
|
S_StartSound(player->mo, sfx_s3k43);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player->pflags &= ~PF_NOJUMPDAMAGE;
|
player->pflags &= ~PF_NOJUMPDAMAGE;
|
||||||
|
|
11
src/r_defs.h
11
src/r_defs.h
|
@ -384,17 +384,6 @@ typedef struct sector_s
|
||||||
// for fade thinker
|
// for fade thinker
|
||||||
INT16 spawn_lightlevel;
|
INT16 spawn_lightlevel;
|
||||||
|
|
||||||
// these are saved for netgames, so do not let Lua touch these!
|
|
||||||
INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed
|
|
||||||
|
|
||||||
// offsets sector spawned with (via linedef type 7)
|
|
||||||
fixed_t spawn_flr_xoffs, spawn_flr_yoffs;
|
|
||||||
fixed_t spawn_ceil_xoffs, spawn_ceil_yoffs;
|
|
||||||
|
|
||||||
// flag angles sector spawned with (via linedef type 7)
|
|
||||||
angle_t spawn_flrpic_angle;
|
|
||||||
angle_t spawn_ceilpic_angle;
|
|
||||||
|
|
||||||
// colormap structure
|
// colormap structure
|
||||||
extracolormap_t *spawn_extra_colormap;
|
extracolormap_t *spawn_extra_colormap;
|
||||||
} sector_t;
|
} sector_t;
|
||||||
|
|
|
@ -63,6 +63,7 @@ extern seg_t *segs;
|
||||||
|
|
||||||
extern size_t numsectors;
|
extern size_t numsectors;
|
||||||
extern sector_t *sectors;
|
extern sector_t *sectors;
|
||||||
|
extern sector_t *spawnsectors;
|
||||||
|
|
||||||
extern size_t numsubsectors;
|
extern size_t numsubsectors;
|
||||||
extern subsector_t *subsectors;
|
extern subsector_t *subsectors;
|
||||||
|
@ -72,9 +73,11 @@ extern node_t *nodes;
|
||||||
|
|
||||||
extern size_t numlines;
|
extern size_t numlines;
|
||||||
extern line_t *lines;
|
extern line_t *lines;
|
||||||
|
extern line_t *spawnlines;
|
||||||
|
|
||||||
extern size_t numsides;
|
extern size_t numsides;
|
||||||
extern side_t *sides;
|
extern side_t *sides;
|
||||||
|
extern side_t *spawnsides;
|
||||||
|
|
||||||
//
|
//
|
||||||
// POV data.
|
// POV data.
|
||||||
|
|
98
src/w_wad.c
98
src/w_wad.c
|
@ -1888,3 +1888,101 @@ int W_VerifyNMUSlumps(const char *filename)
|
||||||
};
|
};
|
||||||
return W_VerifyFile(filename, NMUSlist, false);
|
return W_VerifyFile(filename, NMUSlist, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Generates a virtual resource used for level data loading.
|
||||||
|
*
|
||||||
|
* \param lumpnum_t reference
|
||||||
|
* \return Virtual resource
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT32 i;
|
||||||
|
virtres_t* vres = NULL;
|
||||||
|
virtlump_t* vlumps = NULL;
|
||||||
|
size_t numlumps = 0;
|
||||||
|
|
||||||
|
if (W_IsLumpWad(lumpnum))
|
||||||
|
{
|
||||||
|
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
|
||||||
|
UINT8 *wadData = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||||
|
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||||
|
numlumps = ((wadinfo_t *)wadData)->numlumps;
|
||||||
|
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
// Build the lumps.
|
||||||
|
for (i = 0; i < numlumps; i++)
|
||||||
|
{
|
||||||
|
vlumps[i].size = (size_t)(((filelump_t *)(fileinfo + i))->size);
|
||||||
|
// Play it safe with the name in this case.
|
||||||
|
memcpy(vlumps[i].name, (fileinfo + i)->name, 8);
|
||||||
|
vlumps[i].name[8] = '\0';
|
||||||
|
vlumps[i].data = Z_Malloc(vlumps[i].size, PU_LEVEL, NULL); // This is memory inefficient, sorry about that.
|
||||||
|
memcpy(vlumps[i].data, wadData + (fileinfo + i)->filepos, vlumps[i].size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(wadData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Count number of lumps until the end of resource OR up until next "MAPXX" lump.
|
||||||
|
lumpnum_t lumppos = lumpnum + 1;
|
||||||
|
for (i = LUMPNUM(lumppos); i < wadfiles[WADFILENUM(lumpnum)]->numlumps; i++, lumppos++, numlumps++)
|
||||||
|
if (memcmp(W_CheckNameForNum(lumppos), "MAP", 3) == 0)
|
||||||
|
break;
|
||||||
|
numlumps++;
|
||||||
|
|
||||||
|
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||||
|
for (i = 0; i < numlumps; i++, lumpnum++)
|
||||||
|
{
|
||||||
|
vlumps[i].size = W_LumpLength(lumpnum);
|
||||||
|
memcpy(vlumps[i].name, W_CheckNameForNum(lumpnum), 8);
|
||||||
|
vlumps[i].name[8] = '\0';
|
||||||
|
vlumps[i].data = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vres = Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL);
|
||||||
|
vres->vlumps = vlumps;
|
||||||
|
vres->numlumps = numlumps;
|
||||||
|
|
||||||
|
return vres;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief Frees zone memory for a given virtual resource.
|
||||||
|
*
|
||||||
|
* \param Virtual resource
|
||||||
|
*/
|
||||||
|
void vres_Free(virtres_t* vres)
|
||||||
|
{
|
||||||
|
while (vres->numlumps--)
|
||||||
|
Z_Free(vres->vlumps[vres->numlumps].data);
|
||||||
|
Z_Free(vres->vlumps);
|
||||||
|
Z_Free(vres);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** (Debug) Prints lumps from a virtual resource into console.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
static void vres_Diag(const virtres_t* vres)
|
||||||
|
{
|
||||||
|
UINT32 i;
|
||||||
|
for (i = 0; i < vres->numlumps; i++)
|
||||||
|
CONS_Printf("%s\n", vres->vlumps[i].name);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \brief Finds a lump in a given virtual resource.
|
||||||
|
*
|
||||||
|
* \param Virtual resource
|
||||||
|
* \param Lump name to look for
|
||||||
|
* \return Virtual lump if found, NULL otherwise
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtlump_t* vres_Find(const virtres_t* vres, const char* name)
|
||||||
|
{
|
||||||
|
UINT32 i;
|
||||||
|
for (i = 0; i < vres->numlumps; i++)
|
||||||
|
if (fastcmp(name, vres->vlumps[i].name))
|
||||||
|
return &vres->vlumps[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
19
src/w_wad.h
19
src/w_wad.h
|
@ -72,6 +72,25 @@ typedef struct
|
||||||
compmethod compression; // lump compression method
|
compmethod compression; // lump compression method
|
||||||
} lumpinfo_t;
|
} lumpinfo_t;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 'VIRTUAL' RESOURCES
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[9];
|
||||||
|
UINT8* data;
|
||||||
|
size_t size;
|
||||||
|
} virtlump_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t numlumps;
|
||||||
|
virtlump_t* vlumps;
|
||||||
|
} virtres_t;
|
||||||
|
|
||||||
|
virtres_t* vres_GetMap(lumpnum_t);
|
||||||
|
void vres_Free(virtres_t*);
|
||||||
|
virtlump_t* vres_Find(const virtres_t*, const char*);
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// DYNAMIC WAD LOADING
|
// DYNAMIC WAD LOADING
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
Loading…
Reference in New Issue