I'm testing a fix tonight that is working so far. I'm sure it's not the proper way to go but it is keeping the spawnlist and map clean.

src/spawnshell.cpp:
Code:
void SpawnShell::removeSpawn(const uint8_t* data, size_t len, uint8_t dir)
{
  if(dir==DIR_Client)
    return;
  const removeSpawnStruct* rmSpawn = (const removeSpawnStruct*)data;
#ifdef SPAWNSHELL_DIAG
  seqDebug("SpawnShell::removeSpawn(id=%d)", rmSpawn->spawnId);
#endif

  Item *item;

  if(len==sizeof(removeSpawnStruct))
  {
    // Hack to fix corpse clean-up change
    deleteItem(tSpawn, rmSpawn->spawnId);
    // End Hack
    
    if(!rmSpawn->removeSpawn)
    {
      // Remove a spawn from outside the update radius
      if(showeq_params->useUpdateRadius)
      {
        // Remove it
        deleteItem(tSpawn, rmSpawn->spawnId);
      }
      else
      {
        // Set flag to change its icon
        if((item=m_spawns.find(rmSpawn->spawnId)))
        {
          Spawn *s=(Spawn*)item;
          s->setNotUpdated(true);
        }
      }
    }
  }
  else if((len+1)!=sizeof(removeSpawnStruct))
  {
    seqWarn("OP_RemoveSpawn (dataLen: %d) doesn't match: sizeof(removeSpawnStruct): %d",
            len,sizeof(removeSpawnStruct));
  }
}
Also, some zone opcode changes if anyone wants to try out the changes on Test. I'm sure there's some others but they are minor ones.

zoneopcodes.xml:
Code:
    <opcode id="5D24" name="OP_NpcMoveUpdate" updated="01/26/11">
        <comment>Position updates</comment>
        <payload dir="server" typename="uint8_t" sizechecktype="none"/>
    </opcode>

    <opcode id="1D85" name="OP_DeleteSpawn" updated="01/26/11">
        <comment>old DeleteSpawnCode</comment>
        <payload dir="both" typename="deleteSpawnStruct" sizechecktype="match"/>
    </opcode>