Skip to content

Commit

Permalink
Fixed numerous original Heretic kludges which used mobj_t->health for…
Browse files Browse the repository at this point in the history
… various purposes other than the intended use (e.g. life time of whirlwinds and mace ball bounce state). Instead these now use mobj_t->special3 and saved games are adjusted/interpreted accordingly.
  • Loading branch information
danij committed Aug 24, 2008
1 parent 4321f13 commit 1b14645
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 34 deletions.
35 changes: 35 additions & 0 deletions doomsday/plugins/common/src/p_saveg.c
Expand Up @@ -82,6 +82,7 @@
#include "p_door.h"
#include "p_floor.h"
#include "p_plat.h"
#include "hu_msg.h"

// MACROS ------------------------------------------------------------------

Expand Down Expand Up @@ -1404,6 +1405,8 @@ static void SV_ReadPlayer(player_t *p)

#if __JHEXEN__
# define MOBJ_SAVEVERSION 6
#elif __JHEREITC__
# define MOBJ_SAVEVERSION 8
#else
# define MOBJ_SAVEVERSION 7
#endif
Expand Down Expand Up @@ -1438,6 +1441,9 @@ static void SV_WriteMobj(mobj_t *original)
// 6: Added damage
// 7: Added generator in jHeretic
// 7: Added flags3
//
// JHERETIC
// 8: Added special3
SV_WriteByte(MOBJ_SAVEVERSION);

#if !__JHEXEN__
Expand Down Expand Up @@ -1566,6 +1572,7 @@ static void SV_WriteMobj(mobj_t *original)
# ifdef __JHERETIC__
SV_WriteLong(mo->special1);
SV_WriteLong(mo->special2);
SV_WriteLong(mo->special3);
# endif

SV_WriteByte(mo->translucency);
Expand Down Expand Up @@ -1838,6 +1845,31 @@ static int SV_ReadMobj(thinker_t *th)
#endif

mo->health = SV_ReadLong();
#if __JHERETIC__
if(ver < 8)
{
// Fix a bunch of kludges in the original Heretic.
switch(mo->type)
{
case MT_MACEFX1:
case MT_MACEFX2:
case MT_MACEFX3:
case MT_HORNRODFX2:
case MT_HEADFX3:
case MT_WHIRLWIND:
case MT_TELEGLITTER:
case MT_TELEGLITTER2:
mo->special3 = mo->health;
if(mo->type == MT_HORNRODFX2 && mo->special3 > 16)
mo->special3 = 16;
mo->health = mobjInfo[mo->type].spawnHealth;
break;

default:
break;
}
}
#endif

// Movement direction, movement generation (zig-zagging).
mo->moveDir = SV_ReadLong(); // 0-7
Expand Down Expand Up @@ -1923,6 +1955,8 @@ static int SV_ReadMobj(thinker_t *th)
#elif __JHERETIC__
mo->special1 = SV_ReadLong();
mo->special2 = SV_ReadLong();
if(ver >= 8)
mo->special3 = SV_ReadLong();
#endif

#if __JHEXEN__
Expand Down Expand Up @@ -1959,6 +1993,7 @@ static int SV_ReadMobj(thinker_t *th)

// Restore! (unmangle)
RestoreMobj(mo, ver);

return false;
}

Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/jheretic/defs/objects.ded
Expand Up @@ -1956,7 +1956,7 @@ Thing {
Death sound = "ramphit";
Active sound = "None";
Reaction time = 8;
Spawn health = 140;
Spawn health = 1000;
Speed = 22;
Radius = 12;
Height = 8;
Expand Down
1 change: 1 addition & 0 deletions doomsday/plugins/jheretic/include/p_mobj.h
Expand Up @@ -195,6 +195,7 @@ typedef struct mobj_s {
int flags3;
int special1; // Special info
int special2; // Special info
int special3; // Special info
int health;
int moveDir; // 0-7
int moveCount; // when 0, select a new dir
Expand Down
50 changes: 27 additions & 23 deletions doomsday/plugins/jheretic/src/p_enemy.c
Expand Up @@ -1652,7 +1652,7 @@ void C_DECL A_HeadAttack(mobj_t *actor)
fire->mom[MY] = baseFire->mom[MY];
fire->mom[MZ] = baseFire->mom[MZ];
fire->damage = 0;
fire->health = (i + 1) * 2;
fire->special3 = (i + 1) * 2;

P_CheckMissileSpawn(fire);
}
Expand All @@ -1668,7 +1668,7 @@ void C_DECL A_HeadAttack(mobj_t *actor)
mo->tracer = target;
mo->special1 = 60;
mo->special2 = 50; // Timer for active sound.
mo->health = 20 * TICSPERSEC; // Duration.
mo->special3 = 20 * TICSPERSEC; // Duration.

S_StartSound(SFX_HEDAT3, actor);
}
Expand All @@ -1677,8 +1677,8 @@ void C_DECL A_HeadAttack(mobj_t *actor)

void C_DECL A_WhirlwindSeek(mobj_t *actor)
{
actor->health -= 3;
if(actor->health < 0)
actor->special3 -= 3;
if(actor->special3 < 0)
{
actor->mom[MX] = actor->mom[MY] = actor->mom[MZ] = 0;
P_MobjChangeState(actor, mobjInfo[actor->type].deathState);
Expand Down Expand Up @@ -1723,10 +1723,10 @@ void C_DECL A_HeadIceImpact(mobj_t *ice)

void C_DECL A_HeadFireGrow(mobj_t *fire)
{
fire->health--;
fire->special3--;
fire->pos[VZ] += 9;

if(fire->health == 0)
if(fire->special3 == 0)
{
fire->damage = fire->info->damage;
P_MobjChangeState(fire, S_HEADFX3_4);
Expand Down Expand Up @@ -1862,12 +1862,12 @@ void C_DECL A_Scream(mobj_t *actor)
}
}

void P_DropItem(mobj_t *source, mobjtype_t type, int special, int chance)
mobj_t* P_DropItem(mobjtype_t type, mobj_t* source, int special, int chance)
{
mobj_t *mo;
mobj_t* mo;

if(P_Random() > chance)
return;
return NULL;

mo = P_SpawnMobj3f(type, source->pos[VX], source->pos[VY],
source->pos[VZ] + source->height / 2, source->angle);
Expand All @@ -1877,6 +1877,8 @@ void P_DropItem(mobj_t *source, mobjtype_t type, int special, int chance)

mo->flags |= MF_DROPPED;
mo->health = special;

return mo;
}

void C_DECL A_NoBlocking(mobj_t *actor)
Expand All @@ -1890,49 +1892,49 @@ void C_DECL A_NoBlocking(mobj_t *actor)
case MT_MUMMYLEADER:
case MT_MUMMYGHOST:
case MT_MUMMYLEADERGHOST:
P_DropItem(actor, MT_AMGWNDWIMPY, 3, 84);
P_DropItem(MT_AMGWNDWIMPY, actor, 3, 84);
break;

case MT_KNIGHT:
case MT_KNIGHTGHOST:
P_DropItem(actor, MT_AMCBOWWIMPY, 5, 84);
P_DropItem(MT_AMCBOWWIMPY, actor, 5, 84);
break;

case MT_WIZARD:
P_DropItem(actor, MT_AMBLSRWIMPY, 10, 84);
P_DropItem(actor, MT_ARTITOMEOFPOWER, 0, 4);
P_DropItem(MT_AMBLSRWIMPY, actor, 10, 84);
P_DropItem(MT_ARTITOMEOFPOWER, actor, 0, 4);
break;

case MT_HEAD:
P_DropItem(actor, MT_AMBLSRWIMPY, 10, 84);
P_DropItem(actor, MT_ARTIEGG, 0, 51);
P_DropItem(MT_AMBLSRWIMPY, actor, 10, 84);
P_DropItem(MT_ARTIEGG, actor, 0, 51);
break;

case MT_BEAST:
P_DropItem(actor, MT_AMCBOWWIMPY, 10, 84);
P_DropItem(MT_AMCBOWWIMPY, actor, 10, 84);
break;

case MT_CLINK:
P_DropItem(actor, MT_AMSKRDWIMPY, 20, 84);
P_DropItem(MT_AMSKRDWIMPY, actor, 20, 84);
break;

case MT_SNAKE:
P_DropItem(actor, MT_AMPHRDWIMPY, 5, 84);
P_DropItem(MT_AMPHRDWIMPY, actor, 5, 84);
break;

case MT_MINOTAUR:
P_DropItem(actor, MT_ARTISUPERHEAL, 0, 51);
P_DropItem(actor, MT_AMPHRDWIMPY, 10, 84);
P_DropItem(MT_ARTISUPERHEAL, actor, 0, 51);
P_DropItem(MT_AMPHRDWIMPY, actor, 10, 84);
break;

default:
break;
}
}

void C_DECL A_Explode(mobj_t *actor)
void C_DECL A_Explode(mobj_t* actor)
{
int damage;
int damage;

damage = 128;
switch(actor->type)
Expand Down Expand Up @@ -2156,6 +2158,7 @@ void C_DECL A_SpawnTeleGlitter(mobj_t *actor)
P_Random() << 24);

mo->mom[MZ] = 1.0f / 4;
mo->special3 = 1000;
}

void C_DECL A_SpawnTeleGlitter2(mobj_t *actor)
Expand All @@ -2169,11 +2172,12 @@ void C_DECL A_SpawnTeleGlitter2(mobj_t *actor)
P_Random() << 24);

mo->mom[MZ] = 1.0f / 4;
mo->special3 = 1000;
}

void C_DECL A_AccTeleGlitter(mobj_t *actor)
{
if(++actor->health > 35)
if(++actor->special3 > 35)
actor->mom[MZ] += actor->mom[MZ] / 2;
}

Expand Down
6 changes: 5 additions & 1 deletion doomsday/plugins/jheretic/src/p_mobj.c
Expand Up @@ -1053,7 +1053,7 @@ void P_MobjThinker(mobj_t *mobj)
/**
* Spawns a mobj of "type" at the specified position.
*/
mobj_t *P_SpawnMobj3f(mobjtype_t type, float x, float y, float z,
mobj_t* P_SpawnMobj3f(mobjtype_t type, float x, float y, float z,
angle_t angle)
{
mobj_t *mo;
Expand Down Expand Up @@ -1092,6 +1092,10 @@ mobj_t *P_SpawnMobj3f(mobjtype_t type, float x, float y, float z,
// Must link before setting state (ID assigned for the mo).
P_MobjSetState(mo, info->spawnState);

if(mo->type == MT_MACEFX1 || mo->type == MT_MACEFX2 ||
mo->type == MT_MACEFX3)
mo->special3 = 1000;

// Set subsector and/or block links.
P_MobjSetPosition(mo);

Expand Down
20 changes: 20 additions & 0 deletions doomsday/plugins/jheretic/src/p_oldsvg.c
Expand Up @@ -302,6 +302,26 @@ static void SV_v13_ReadMobj(void)
mo->special1 = SV_v13_ReadLong();
mo->special2 = SV_v13_ReadLong();
mo->health = SV_v13_ReadLong();

// Fix a bunch of kludges in the original Heretic.
switch(mo->type)
{
case MT_MACEFX1:
case MT_MACEFX2:
case MT_MACEFX3:
case MT_HORNRODFX2:
case MT_HEADFX3:
case MT_WHIRLWIND:
case MT_TELEGLITTER:
case MT_TELEGLITTER2:
mo->special3 = mo->health;
mo->health = mobjInfo[mo->type].spawnHealth;
break;

default:
break;
}

mo->moveDir = SV_v13_ReadLong();
mo->moveCount = SV_v13_ReadLong();
SV_v13_ReadLong(); // target
Expand Down
23 changes: 14 additions & 9 deletions doomsday/plugins/jheretic/src/p_pspr.c
Expand Up @@ -1336,10 +1336,10 @@ void C_DECL A_MaceBallImpact(mobj_t *ball)
return;
}

if(ball->health != MAGIC_JUNK && ball->pos[VZ] <= ball->floorZ &&
if(ball->special3 != MAGIC_JUNK && ball->pos[VZ] <= ball->floorZ &&
ball->mom[MZ] != 0)
{ // Bounce.
ball->health = MAGIC_JUNK;
ball->special3 = MAGIC_JUNK;
ball->mom[MZ] = FIX2FLT(FLT2FIX(ball->mom[MZ] * 192) >> 8);
ball->flags2 &= ~MF2_FLOORBOUNCE;
P_MobjChangeState(ball, ball->info->spawnState);
Expand Down Expand Up @@ -1578,11 +1578,16 @@ void C_DECL A_FireSkullRodPL1(player_t *player, pspdef_t *psp)
*/
void C_DECL A_FireSkullRodPL2(player_t *player, pspdef_t *psp)
{
mobj_t* mo;

P_ShotAmmo(player);
if(IS_CLIENT)
return;

P_SpawnMissile(MT_HORNRODFX2, player->plr->mo, NULL);
mo = P_SpawnMissile(MT_HORNRODFX2, player->plr->mo, NULL);
if(mo)
mo->special3 = 140;

// Use MissileMobj instead of the return value from
// P_SpawnMissile because we need to give info to the mobj
// even if it exploded immediately.
Expand Down Expand Up @@ -1625,19 +1630,19 @@ void C_DECL A_AddPlayerRain(mobj_t *actor)

if(player->rain1 && player->rain2)
{ // Terminate an active rain.
if(player->rain1->health < player->rain2->health)
if(player->rain1->special3 < player->rain2->special3)
{
if(player->rain1->health > 16)
if(player->rain1->special3 > 16)
{
player->rain1->health = 16;
player->rain1->special3 = 16;
}
player->rain1 = NULL;
}
else
{
if(player->rain2->health > 16)
if(player->rain2->special3 > 16)
{
player->rain2->health = 16;
player->rain2->special3 = 16;
}
player->rain2 = NULL;
}
Expand All @@ -1661,7 +1666,7 @@ void C_DECL A_SkullRodStorm(mobj_t *actor)
int playerNum;
player_t *player;

if(actor->health-- == 0)
if(actor->special3-- == 0)
{
P_MobjChangeState(actor, S_NULL);
playerNum = (IS_NETGAME ? actor->special2 : 0);
Expand Down

0 comments on commit 1b14645

Please sign in to comment.