Code:
static void make_corpse(struct char_data *ch, int attacktype)
{
  char buf2[MAX_NAME_LENGTH + 64], spec_desc[255];
  char buf3[MAX_NAME_LENGTH + 64];
  struct obj_data *corpse, *o;
  struct obj_data *money;
  struct obj_data *head;
  int i, x, y;
  head = create_obj();
  head->item_number = NOTHING;
  IN_ROOM(head) = NOWHERE;
  if (!(GET_CLASS(ch) == CLASS_NPC_UNDEAD)) {
  if ((GET_HIT(ch) < -30) && (attacktype == TYPE_SLASH || attacktype == TYPE_BITE)) {
  head->name = strdup("head");
  snprintf(buf3, sizeof(buf3), "the severed head of %s is lying here.", GET_NAME(ch));
  head->description = strdup(buf3);
  snprintf(buf3, sizeof(buf3), "severed head of %s", GET_NAME(ch));
  head->short_description = strdup(buf3);
  GET_OBJ_TYPE(head) = ITEM_CONTAINER;
  for(x = y = 0; x < EF_ARRAY_MAX || y < TW_ARRAY_MAX; x++, y++) {
    if (x < EF_ARRAY_MAX)
      GET_OBJ_EXTRA_AR(head, x) = 0;
    if (y < TW_ARRAY_MAX)
      head->obj_flags.wear_flags[y] = 0;
  }
  SET_BIT_AR(GET_OBJ_WEAR(head), ITEM_WEAR_TAKE);
  SET_BIT_AR(GET_OBJ_EXTRA(head), ITEM_NODONATE);
  GET_OBJ_VAL(head, 0) = 0;
  GET_OBJ_VAL(head, 3) = 1;
  GET_OBJ_WEIGHT(head) = GET_WEIGHT(ch) + IS_CARRYING_W(ch);
  GET_OBJ_RENT(head) = 100000;
  if (IS_NPC(ch))
    GET_OBJ_TIMER(head) = CONFIG_MAX_NPC_CORPSE_TIME+2;
  else
    GET_OBJ_TIMER(head) = CONFIG_MAX_PC_CORPSE_TIME+3;
  obj_to_room(head, IN_ROOM(ch));
 }
}
  switch (attacktype) {
  case  SPELL_FIRESHIELD:
  case  SPELL_FIREBALL:sprintf(spec_desc,"smoldering remains of %s are",
                        (IS_NPC(ch) ? ch->player.short_descr : GET_NAME(ch)));
                        break;
  case  SPELL_CHILL_TOUCH:
  case  SPELL_FROST_BOLT:sprintf(spec_desc,"frozen corpse of %s is",
                        (IS_NPC(ch) ? ch->player.short_descr : GET_NAME(ch)));
                        break;
  default:sprintf(spec_desc,"corpse of %s is",
                (IS_NPC(ch) ? ch->player.short_descr : GET_NAME(ch)));
                break;
  }
  corpse = create_obj();
  corpse->item_number = NOTHING;
  IN_ROOM(corpse) = NOWHERE;
  if (GET_CLASS(ch) == CLASS_NPC_UNDEAD) {
  corpse->name = strdup("dust pile bones");
  snprintf(buf2, sizeof(buf2), "A pile of dust and bones is here.");
  corpse->description = strdup(buf2);
  snprintf(buf2, sizeof(buf2), "a pile of dust and bones");
  corpse->short_description = strdup(buf2);
 } else {
  snprintf(buf2, sizeof(buf2), "corpse %s", spec_desc);
  corpse->name = strdup(buf2);
  snprintf(buf2, sizeof(buf2), "The %s lying here.", spec_desc);
  corpse->description = strdup(buf2);
  snprintf(buf2, sizeof(buf2), "the corpse of %s", GET_NAME(ch));
  corpse->short_description = strdup(buf2);
}
  GET_OBJ_TYPE(corpse) = ITEM_CONTAINER;
  for(x = y = 0; x < EF_ARRAY_MAX || y < TW_ARRAY_MAX; x++, y++) {
    if (x < EF_ARRAY_MAX)
      GET_OBJ_EXTRA_AR(corpse, x) = 0;
    if (y < TW_ARRAY_MAX)
      corpse->obj_flags.wear_flags[y] = 0;
  }
  SET_BIT_AR(GET_OBJ_WEAR(corpse), ITEM_WEAR_TAKE);
  SET_BIT_AR(GET_OBJ_EXTRA(corpse), ITEM_NODONATE);
  if (!(GET_CLASS(ch) == CLASS_NPC_UNDEAD))
  SET_BIT_AR(GET_OBJ_EXTRA(corpse), ITEM_TANNABLE);
  GET_OBJ_VAL(corpse, 0) = 0;   /* You can't store stuff in a corpse */
  GET_OBJ_VAL(corpse, 3) = 1;   /* corpse identifier */
  GET_OBJ_WEIGHT(corpse) = GET_WEIGHT(ch) + IS_CARRYING_W(ch);
  GET_OBJ_RENT(corpse) = 100000;
  if (IS_NPC(ch))
    GET_OBJ_TIMER(corpse) = CONFIG_MAX_NPC_CORPSE_TIME;
  else
    GET_OBJ_TIMER(corpse) = CONFIG_MAX_PC_CORPSE_TIME;
  /* transfer character's inventory to the corpse */
  corpse->contains = ch->carrying;
  for (o = corpse->contains; o != NULL; o = o->next_content)
    o->in_obj = corpse;
  object_list_new_owner(corpse, NULL);
  /* transfer character's equipment to the corpse */
  for (i = 0; i < NUM_WEARS; i++)
    if (GET_EQ(ch, i)) {
      remove_otrigger(GET_EQ(ch, i), ch);
      obj_to_obj(unequip_char(ch, i), corpse);
    }
  /* transfer gold */
  if (GET_GOLD(ch) > 0) {
    /* following 'if' clause added to fix gold duplication loophole. The above
     * line apparently refers to the old "partially log in, kill the game
     * character, then finish login sequence" duping bug. The duplication has
     * been fixed (knock on wood) but the test below shall live on, for a
     * while. -gg 3/3/2002 */
    if (IS_NPC(ch) || ch->desc) {
      money = create_money(GET_GOLD(ch));
      obj_to_obj(money, corpse);
    }
    GET_GOLD(ch) = 0;
  }
  ch->carrying = NULL;
  IS_CARRYING_N(ch) = 0;
  IS_CARRYING_W(ch) = 0;
  obj_to_room(corpse, IN_ROOM(ch));
}