Skip to content

Commit

Permalink
Fixed: "Heretic Gargoyles not spawning correctly" (see here http://so…
Browse files Browse the repository at this point in the history
…urceforge.net/tracker/?func=detail&aid=2724939&group_id=74815&atid=542099).

I decided to fix all such problems for good by unifying the way we interpret z heights for spawnspots across DOOM, Heretic and Hexen. All games now have a z coordinate for spawnspots and a set of flags which control how that value is interpreted game-side. dpwadmapconverter contains logic which adjusts these properties according to the map format.

jDOOM64 remains to be updated accordingly.
  • Loading branch information
danij committed May 3, 2009
1 parent 886461d commit f28004d
Show file tree
Hide file tree
Showing 43 changed files with 584 additions and 520 deletions.
6 changes: 3 additions & 3 deletions doomsday/plugins/common/src/p_map.c
Expand Up @@ -497,7 +497,7 @@ boolean PIT_CheckThing(mobj_t* thing, void* data)
if(P_Random() < 128)
{
P_SpawnMobj3fv(MT_HOLY_PUFF, tmThing->pos,
P_Random() << 24);
P_Random() << 24, 0);
S_StartSound(SFX_SPIRIT_ATTACK, tmThing);
if((thing->flags & MF_COUNTKILL) && P_Random() < 128 &&
!S_IsPlaying(SFX_PUPPYBEAT, thing))
Expand Down Expand Up @@ -1680,7 +1680,7 @@ if(lineWasHit)
if(puffType == MT_BLASTERPUFF1)
{ // Make blaster big puff.
mobj_t* mo =
P_SpawnMobj3fv(MT_BLASTERPUFF2, pos, P_Random() << 24);
P_SpawnMobj3fv(MT_BLASTERPUFF2, pos, P_Random() << 24, 0);

S_StartSound(SFX_BLSHIT, mo);
}
Expand Down Expand Up @@ -2581,7 +2581,7 @@ boolean PIT_ChangeSector(mobj_t* thing, void* data)
// Spray blood in a random direction.
mo = P_SpawnMobj3f(MT_BLOOD, thing->pos[VX], thing->pos[VY],
thing->pos[VZ] + (thing->height /2),
P_Random() << 24);
P_Random() << 24, 0);

mo->mom[MX] = FIX2FLT((P_Random() - P_Random()) << 12);
mo->mom[MY] = FIX2FLT((P_Random() - P_Random()) << 12);
Expand Down
8 changes: 3 additions & 5 deletions doomsday/plugins/common/src/p_mapsetup.c
Expand Up @@ -337,9 +337,8 @@ static void P_LoadMapObjs(void)

th->pos[VX] = P_GetGMOFloat(MO_THING, i, MO_X);
th->pos[VY] = P_GetGMOFloat(MO_THING, i, MO_Y);
#if __JDOOM64__
th->pos[VZ] = P_GetGMOFloat(MO_THING, i, MO_Z);
#endif

th->type = P_GetGMOInt(MO_THING, i, MO_TYPE);
th->flags = P_GetGMOInt(MO_THING, i, MO_FLAGS);

Expand All @@ -348,15 +347,14 @@ static void P_LoadMapObjs(void)
* in the angle field in THINGS. Thus, we cannot translate the angle
* until we know whether it is a polyobject type or not.
*/
#if __JHEXEN__ || __JSTRIFE__
#if __JHEXEN__
th->angle = P_GetGMOShort(MO_THING, i, MO_ANGLE);
#else
th->angle = ANG45 * (P_GetGMOShort(MO_THING, i, MO_ANGLE) / 45);
#endif

#if __JHEXEN__ || __JSTRIFE__
#if __JHEXEN__
th->tid = P_GetGMOShort(MO_THING, i, MO_ID);
th->height = P_GetGMOShort(MO_THING, i, MO_Z);
th->special = P_GetGMOByte(MO_THING, i, MO_SPECIAL);
th->arg1 = P_GetGMOByte(MO_THING, i, MO_ARG0);
th->arg2 = P_GetGMOByte(MO_THING, i, MO_ARG1);
Expand Down
9 changes: 6 additions & 3 deletions doomsday/plugins/common/src/p_player.c
Expand Up @@ -1122,6 +1122,7 @@ DEFCC(CCmdSpawnMobj)
float pos[3];
mobj_t* mo;
angle_t angle;
int spawnFlags;

if(argc != 5 && argc != 6)
{
Expand Down Expand Up @@ -1152,10 +1153,12 @@ DEFCC(CCmdSpawnMobj)
// The coordinates.
pos[VX] = strtod(argv[2], 0);
pos[VY] = strtod(argv[3], 0);
pos[VZ] = 0;

if(!stricmp(argv[4], "floor"))
pos[VZ] = ONFLOORZ;
spawnFlags |= MTF_Z_FLOOR;
else if(!stricmp(argv[4], "ceil"))
pos[VZ] = ONCEILINGZ;
spawnFlags |= MTF_Z_CEIL;
else
{
pos[VZ] = strtod(argv[4], 0) +
Expand All @@ -1168,7 +1171,7 @@ DEFCC(CCmdSpawnMobj)
else
angle = 0;

mo = P_SpawnMobj3fv(type, pos, angle);
mo = P_SpawnMobj3fv(type, pos, angle, spawnFlags);
if(mo)
{

Expand Down
19 changes: 16 additions & 3 deletions doomsday/plugins/common/src/p_saveg.c
Expand Up @@ -1408,9 +1408,9 @@ static void SV_ReadPlayer(player_t* p)
#if __JHEXEN__
# define MOBJ_SAVEVERSION 7
#elif __JHERETIC__
# define MOBJ_SAVEVERSION 8
# define MOBJ_SAVEVERSION 9
#else
# define MOBJ_SAVEVERSION 7
# define MOBJ_SAVEVERSION 9
#endif

static void SV_WriteMobj(const mobj_t* original)
Expand Down Expand Up @@ -1444,8 +1444,12 @@ static void SV_WriteMobj(const mobj_t* original)
// 7: Added generator in jHeretic
// 7: Added flags3
//
// JDOOM
// 9: Revised spawnspot flag interpretation
//
// JHERETIC
// 8: Added special3
// 9: Revised spawnspot flag interpretation
//
// JHEXEN
// 7: Removed superfluous info ptr
Expand Down Expand Up @@ -1668,6 +1672,15 @@ void SV_UpdateReadMobjFlags(mobj_t *mo, int ver)
}
#endif

#if __JDOOM__ || __JHERETIC__
if(ver < 9)
{
mo->spawnSpot.flags &= ~MASK_UNKNOWN_THING_FLAGS;
// Spawn on the floor by default unless the mobjtype flags override.
mo->spawnSpot.flags |= MTF_Z_FLOOR;
}
#endif

#if __JHEXEN__
if(ver < 5)
#else
Expand Down Expand Up @@ -1913,7 +1926,7 @@ static int SV_ReadMobj(thinker_t *th)
{
mo->spawnSpot.pos[VX] = (float) SV_ReadShort();
mo->spawnSpot.pos[VY] = (float) SV_ReadShort();
mo->spawnSpot.pos[VZ] = ONFLOORZ;
mo->spawnSpot.pos[VZ] = 0; // Initialize with "something".
mo->spawnSpot.angle = (angle_t) (ANG45 * (SV_ReadShort() / 45));
mo->spawnSpot.type = (int) SV_ReadShort();
mo->spawnSpot.flags = (int) SV_ReadShort();
Expand Down
7 changes: 3 additions & 4 deletions doomsday/plugins/common/src/p_start.c
Expand Up @@ -454,8 +454,8 @@ void P_SpawnThings(void)
{
spot = P_Random() % maceSpotCount;
P_SpawnMobj3f(MT_WMACE,
maceSpots[spot].pos[VX], maceSpots[spot].pos[VY],
ONFLOORZ, maceSpots[spot].angle);
maceSpots[spot].pos[VX], maceSpots[spot].pos[VY], 0,
maceSpots[spot].angle, MTF_Z_FLOOR);
}
}
#endif
Expand Down Expand Up @@ -557,8 +557,7 @@ void G_DummySpawnPlayer(int playernum)
{
spawnspot_t faraway;

faraway.pos[VX] = faraway.pos[VY] = 0;
faraway.angle = 0;
memset(&faraway, 0, sizeof(faraway));
P_SpawnPlayer(&faraway, playernum);
}

Expand Down
10 changes: 5 additions & 5 deletions doomsday/plugins/common/src/p_user.c
Expand Up @@ -738,15 +738,15 @@ boolean P_UndoPlayerMorph(player_t *player)
playerNum = P_GetPlayerNum(player);
# if __JHEXEN__
mo = P_SpawnMobj3fv(PCLASS_INFO(cfg.playerClass[playerNum])->mobjType,
pos, angle);
pos, angle, 0);
# else
mo = P_SpawnMobj3fv(MT_PLAYER, pos, angle);
mo = P_SpawnMobj3fv(MT_PLAYER, pos, angle, 0);
# endif

if(P_TestMobjLocation(mo) == false)
{ // Didn't fit
P_MobjRemove(mo, false);
mo = P_SpawnMobj3fv(oldBeast, pos, angle);
mo = P_SpawnMobj3fv(oldBeast, pos, angle, 0);

mo->health = player->health;
mo->special1 = weapon;
Expand Down Expand Up @@ -803,7 +803,7 @@ boolean P_UndoPlayerMorph(player_t *player)
fog = P_SpawnMobj3f(MT_TFOG,
pos[VX] + 20 * FIX2FLT(finecosine[an]),
pos[VY] + 20 * FIX2FLT(finesine[an]),
pos[VZ] + TELEFOGHEIGHT, angle + ANG180);
pos[VZ] + TELEFOGHEIGHT, angle + ANG180, 0);
# if __JHERETIC__
S_StartSound(SFX_TELEPT, fog);
# else
Expand Down Expand Up @@ -1109,7 +1109,7 @@ void P_PlayerThinkMove(player_t *player)
int playerNum;

speedMo = P_SpawnMobj3fv(MT_PLAYER_SPEED, plrmo->pos,
plrmo->angle);
plrmo->angle, 0);
if(speedMo)
{
playerNum = P_GetPlayerNum(player);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/src/p_xgline.c
Expand Up @@ -1623,7 +1623,7 @@ int C_DECL XLTrav_LineTeleport(linedef_t* newLine, boolean dummy,
// Spawn flash at the old position?
if(info->iparm[2])
{
flash = P_SpawnMobj3fv(MT_TFOG, mobj->pos, mobj->angle + ANG180);
flash = P_SpawnMobj3fv(MT_TFOG, mobj->pos, mobj->angle + ANG180, 0);

// Play a sound?
if(info->iparm[3])
Expand Down Expand Up @@ -1745,7 +1745,7 @@ int C_DECL XLTrav_LineTeleport(linedef_t* newLine, boolean dummy,
flash = P_SpawnMobj3f(MT_TFOG,
mobj->pos[VX] + 24 * FIX2FLT(finecosine[an]),
mobj->pos[VY] + 24 * FIX2FLT(finesine[an]),
mobj->pos[VZ], mobj->angle + ANG180);
mobj->pos[VZ], mobj->angle + ANG180, 0);

// Play a sound?
if(info->iparm[3])
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/src/p_xgsec.c
Expand Up @@ -2247,7 +2247,7 @@ int C_DECL XSTrav_Teleport(sector_t* sector, boolean ceiling, void* context,
fogDelta = ((thing->flags & MF_MISSILE)? 0 : TELEFOGHEIGHT);
#endif
flash = P_SpawnMobj3f(MT_TFOG, oldpos[VX], oldpos[VY],
oldpos[VZ] + fogDelta, oldAngle + ANG180);
oldpos[VZ] + fogDelta, oldAngle + ANG180, 0);
// Play a sound?
if(info->iparm[3])
S_StartSound(info->iparm[3], flash);
Expand All @@ -2262,7 +2262,7 @@ int C_DECL XSTrav_Teleport(sector_t* sector, boolean ceiling, void* context,
flash = P_SpawnMobj3f(MT_TFOG,
mo->pos[VX] + 20 * FIX2FLT(finecosine[an]),
mo->pos[VY] + 20 * FIX2FLT(finesine[an]),
mo->pos[VZ] + fogDelta, mo->angle);
mo->pos[VZ] + fogDelta, mo->angle, 0);
// Play a sound?
if(info->iparm[3])
S_StartSound(info->iparm[3], flash);
Expand Down
4 changes: 0 additions & 4 deletions doomsday/plugins/jdoom/include/p_local.h
Expand Up @@ -77,10 +77,6 @@
#define FRICTION_FLY (0.91796875f)
#define FRICTION_HIGH (0.5f)

#define ONFLOORZ (DDMINFLOAT)
#define ONCEILINGZ (DDMAXFLOAT)
#define FLOATRANDZ (DDMAXFLOAT-1)

#define OPENRANGE (*(float*) DD_GetVariable(DD_OPENRANGE))
#define OPENTOP (*(float*) DD_GetVariable(DD_OPENTOP))
#define OPENBOTTOM (*(float*) DD_GetVariable(DD_OPENBOTTOM))
Expand Down
29 changes: 19 additions & 10 deletions doomsday/plugins/jdoom/include/p_mobj.h
Expand Up @@ -43,14 +43,22 @@
/**
* (Re)Spawn flags:
*/
#define MTF_EASY 1 // Can be spawned in Easy skill modes.
#define MTF_MEDIUM 2 // Can be spawned in Medium skill modes.
#define MTF_HARD 4 // Can be spawned in Hard skill modes.
#define MTF_DEAF 8 // Mobj will be deaf spawned deaf.
#define MTF_NOTSINGLE 16 // Can not be spawned in single player gamemodes.
#define MTF_NOTDM 32 // Can not be spawned in the Deathmatch gameMode.
#define MTF_NOTCOOP 64 // Can not be spawned in the Co-op gameMode.
#define MTF_DORMANT 512 // Mobj will be spawned invulnerble and inert.
#define MTF_EASY 0x00000001 // Can be spawned in Easy skill modes.
#define MTF_MEDIUM 0x00000002 // Can be spawned in Medium skill modes.
#define MTF_HARD 0x00000004 // Can be spawned in Hard skill modes.
#define MTF_DEAF 0x00000008 // Mobj will be deaf spawned deaf.
#define MTF_NOTSINGLE 0x00000010 // (BOOM) Can not be spawned in single player gamemodes.
#define MTF_NOTDM 0x00000020 // (BOOM) Can not be spawned in the Deathmatch gameMode.
#define MTF_NOTCOOP 0x00000040 // (BOOM) Can not be spawned in the Co-op gameMode.
#define MTF_FRIENDLY 0x00000080 // (BOOM) friendly monster.

#define MASK_UNKNOWN_THING_FLAGS (0xffffffff \
^ (MTF_EASY|MTF_MEDIUM|MTF_HARD|MTF_DEAF|MTF_NOTSINGLE|MTF_NOTDM|MTF_NOTCOOP|MTF_FRIENDLY))

// New flags:
#define MTF_Z_FLOOR 0x20000000 // Spawn relative to floor height.
#define MTF_Z_CEIL 0x40000000 // Spawn relative to ceiling height (minus thing height).
#define MTF_Z_RANDOM 0x80000000 // Random point between floor and ceiling.

typedef struct spawnspot_s {
float pos[3];
Expand Down Expand Up @@ -240,8 +248,9 @@ void P_CheckRespawnQueue(void);
void P_EmptyRespawnQueue(void);

mobj_t* P_SpawnMobj3f(mobjtype_t type, float x, float y, float z,
angle_t angle);
mobj_t* P_SpawnMobj3fv(mobjtype_t type, float pos[3], angle_t angle);
angle_t angle, int spawnFlags);
mobj_t* P_SpawnMobj3fv(mobjtype_t type, float pos[3], angle_t angle,
int spawnFlags);

mobj_t* P_SpawnCustomPuff(mobjtype_t type, float x, float y, float z,
angle_t angle);
Expand Down
1 change: 1 addition & 0 deletions doomsday/plugins/jdoom/include/p_setup.h
Expand Up @@ -41,6 +41,7 @@ enum {
MO_XSECTOR,
MO_X,
MO_Y,
MO_Z,
MO_ANGLE,
MO_TYPE,
MO_FLAGS,
Expand Down
2 changes: 0 additions & 2 deletions doomsday/plugins/jdoom/include/p_telept.h
Expand Up @@ -34,8 +34,6 @@

#include "doomsday.h"

#define TELEFOGHEIGHT 0

int EV_Teleport(linedef_t* line, int side, mobj_t* mo,
boolean spawnFog);
#endif
16 changes: 8 additions & 8 deletions doomsday/plugins/jdoom/src/p_enemy.c
Expand Up @@ -1051,7 +1051,7 @@ void C_DECL A_Tracer(mobj_t *actor)
th = P_SpawnMobj3f(MT_SMOKE,
actor->pos[VX] - actor->mom[MX],
actor->pos[VY] - actor->mom[MY],
actor->pos[VZ], actor->angle + ANG180);
actor->pos[VZ], actor->angle + ANG180, 0);

th->mom[MZ] = 1;
th->tics -= P_Random() & 3;
Expand Down Expand Up @@ -1304,7 +1304,7 @@ void C_DECL A_VileTarget(mobj_t *actor)
A_FaceTarget(actor);

fog = P_SpawnMobj3fv(MT_FIRE, actor->target->pos,
actor->target->angle + ANG180);
actor->target->angle + ANG180, 0);

actor->tracer = fog;
fog->target = actor;
Expand Down Expand Up @@ -1495,7 +1495,7 @@ void C_DECL A_PainShootSkull(mobj_t* actor, angle_t angle)
if(P_CheckSides(actor, pos[VX], pos[VY]))
return;

newmobj = P_SpawnMobj3fv(MT_SKULL, pos, angle);
newmobj = P_SpawnMobj3fv(MT_SKULL, pos, angle, 0);
sec = P_GetPtrp(newmobj->subsector, DMU_SECTOR);

// Check to see if the new Lost Soul's z value is above the
Expand All @@ -1511,7 +1511,7 @@ void C_DECL A_PainShootSkull(mobj_t* actor, angle_t angle)
}
else
{ // Use the original DOOM method.
newmobj = P_SpawnMobj3fv(MT_SKULL, pos, angle);
newmobj = P_SpawnMobj3fv(MT_SKULL, pos, angle, 0);
}

// Check for movements, $dropoff_fix.
Expand Down Expand Up @@ -1829,7 +1829,7 @@ void C_DECL A_BrainScream(mobj_t *mo)
pos[VY] = mo->pos[VY] - 320;
pos[VZ] = 128 + (P_Random() * 2);

th = P_SpawnMobj3fv(MT_ROCKET, pos, P_Random() << 24);
th = P_SpawnMobj3fv(MT_ROCKET, pos, P_Random() << 24, 0);
th->mom[MZ] = FIX2FLT(P_Random() * 512);

P_MobjChangeState(th, S_BRAINEXPLODE1);
Expand All @@ -1851,7 +1851,7 @@ void C_DECL A_BrainExplode(mobj_t *mo)
pos[VY] = mo->pos[VY];
pos[VZ] = 128 + (P_Random() * 2);

th = P_SpawnMobj3fv(MT_ROCKET, pos, P_Random() << 24);
th = P_SpawnMobj3fv(MT_ROCKET, pos, P_Random() << 24, 0);
th->mom[MZ] = FIX2FLT(P_Random() * 512);

P_MobjChangeState(th, S_BRAINEXPLODE1);
Expand Down Expand Up @@ -1917,7 +1917,7 @@ void C_DECL A_SpawnFly(mobj_t *mo)
targ = mo->target;

// First spawn teleport fog.
fog = P_SpawnMobj3fv(MT_SPAWNFIRE, targ->pos, targ->angle + ANG180);
fog = P_SpawnMobj3fv(MT_SPAWNFIRE, targ->pos, targ->angle + ANG180, 0);
S_StartSound(SFX_TELEPT, fog);

// Randomly select monster to spawn.
Expand Down Expand Up @@ -1947,7 +1947,7 @@ void C_DECL A_SpawnFly(mobj_t *mo)
else
type = MT_BRUISER;

newmobj = P_SpawnMobj3fv(type, targ->pos, P_Random() << 24);
newmobj = P_SpawnMobj3fv(type, targ->pos, P_Random() << 24, 0);

if(lookForPlayers(newmobj, true))
P_MobjChangeState(newmobj, P_GetState(newmobj->type, SN_SEE));
Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/jdoom/src/p_inter.c
Expand Up @@ -931,7 +931,7 @@ void P_KillMobj(mobj_t *source, mobj_t *target, boolean stomping)
mo = P_SpawnMobj3f(item,
target->pos[VX] + 3 * FIX2FLT(finecosine[an]),
target->pos[VY] + 3 * FIX2FLT(finesine[an]),
ONFLOORZ, angle);
0, angle, MTF_Z_FLOOR);
mo->flags |= MF_DROPPED; // Special versions of items.
}

Expand Down

0 comments on commit f28004d

Please sign in to comment.