Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
Quasar

Reversed precise behavior of Heretic 1.0 mace spots

Recommended Posts

A while back some people asked me to reverse-engineer the precise behavior of the mace spots as they functioned in Heretic 1.0, and I completed that tonight during some spare time.

int MaceTypes[] =
{
   0,         // unused, bumps array up by 1 for gameepisode
   MT_WIZARD, // episode 1
   MT_BEAST,  // episode 2
   MT_SNAKE,  // episode 3
};

void P_CloseWeapons(void)
{
   int spot, i;

   if(!MaceSpotCount)
      return;

   spot = P_Random() % MaceSpotCount;
   
   if(!deathmatch && P_Random() < 64)
      spot = -1;

   for(i = 0; i < MaceSpotCount; ++i)
   {
      if(i == spot)
         P_SpawnMobj(MaceSpots[i].x, MaceSpots[i].y, ONFLOORZ, MT_MACE);
      else if(!nomonsters)
      {
         P_SpawnMobj(MaceSpots[i].x, MaceSpots[i].y, ONFLOORZ, MaceTypes[gameepisode]);
         ++totalkills;
      }
   }
}
Note that the array used by this routine is only 4 integers in length. This means that when playing E4M1, the array is accessed out of bounds. The next item in memory is a dummy ambient sound sequence called AmbSndSeqInit, which contains a single command, afxcmd_end, with the value 0x05. 5 as an mobj type number is the Shadowsphere.

The other routines involved in mace spot tracking were mostly identical, except that P_RepositionMace is missing calls to P_(Un)SetThingPosition, meaning that it effectively corrupts the blockmap by leaving dangling links to the object in an incorrect cell. I do not know what version of Heretic that was fixed in for certain.

Note: Anyone can use this code in a Heretic port, but please give explicit credit to me in a comment along with it :)

Share this post


Link to post

Actually the behavior description already on the wiki matches what I found in the binary more or less exactly, except that it assumes through lack of information that the spawning of Shadowspheres on episode 4 maps is an intentional feature, when it's actually the result of undefined behavior :)

There weren't any real surprises here other than that, though.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×