Welcome to the Builder Academy

Question I broke corpses somehow

More
15 Aug 2025 11:56 #10862 by wlessard1
While testing, I found out that somehow I broke player corpses.
They all now come closed and locked apparently.

Where might I find the problem? Where I changed something?
I have a spec_proc mob for corpse retrieval.
I have a do_retrieve to pass corpses to the player

And here is the make_corpse in fight.c
Code:
static void make_corpse(struct char_data *ch) {   char buf2[MAX_NAME_LENGTH + 64];   struct obj_data *corpse, *o;   struct obj_data *money;   int i, x, y;     corpse = create_obj();   corpse->item_number = NOTHING;   IN_ROOM(corpse) = NOWHERE;   snprintf(buf2, sizeof(buf2), "corpse %s", GET_NAME(ch));   corpse->name = strdup(buf2);   snprintf(buf2, sizeof(buf2), "The corpse of %s is lying here.", GET_NAME(ch));   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);   GET_OBJ_VAL(corpse, 0) = 0; /* Can't store stuff */   GET_OBJ_VAL(corpse, 3) = 1; /* Corpse Identifier */   SET_BIT(GET_OBJ_VAL(corpse, 3), CONT_CORPSE); /* Set CONT_CORPSE flag */   GET_OBJ_VAL(corpse, 1) = IS_NPC(ch) ? 0 : GET_IDNUM(ch); /* Set owner ID */   GET_OBJ_WEIGHT(corpse) = 1 + IS_CARRYING_W(ch); /* Set weight: 1 + carried items */   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 inventory */   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 equipment */   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) {     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;   if (IS_NPC(ch))     obj_to_room(corpse, IN_ROOM(ch));    /* Apply radiation affect if in wasteland zone       if (ZONE_FLAGGED(GET_ROOM_ZONE(IN_ROOM(corpse)), ZONE_WASTELAND)) {       SET_BIT_AR(GET_OBJ_AFFECT(corpse), AFF_RADIATION);       log("If this isn't here then aff_radiation wont be");       } */   else     obj_to_room(corpse, real_room(3068));   if (CONFIG_DEBUG_MODE) {     log("MAKE_CORPSE: Created corpse '%s' (type %d, value[3] %d, value[1] %d, weight %d) for %s in room %d",         corpse->name, GET_OBJ_TYPE(corpse), GET_OBJ_VAL(corpse, 3), GET_OBJ_VAL(corpse, 1), GET_OBJ_WEIGHT(corpse), GET_NAME(ch), GET_ROOM_VNUM(real_room(3068)));   } }
I have some funky corpse issues if I apply the radiation to the corpse so I am putting that on hold until I figure out why my corpses come out.

Name: 'the corpse of Groo', Keywords: corpse Groo
VNum: [65535], RNum: [65535], Idnum: [30000005], Type: CONTAINER, SpecProc: None
L-Desc: 'The corpse of Groo is lying here.'
A-Desc: '<None>'
Can be worn on: TAKE
Set char bits : NOBITS
Extra flags  : NO_DONATE
Weight: 1, Value: 0, Cost/day: 100000, Timer: 0, Min level: 0
In room: 65535 (Nowhere), In object: None, Carried by: Bramage, Worn by: Nobody
Weight capacity: 0, Lock Type: CLOSED LOCKED UNDEFINED UNDEFINED , Key Num: 0, Corpse: YES
Affections: None
Triggers:
  None.

Please Log in or Create an account to join the conversation.

More
16 Aug 2025 11:06 #10863 by wlessard1
Replied by wlessard1 on topic I broke corpses somehow
This will probably help as well. My retrieve code for corpses.
Code:
/* do corpse retrieve code by Bramage */ ACMD(do_retrieve) { /*  struct obj_data *corpse, *obj, *next_obj; */   struct obj_data *corpse, *next_obj;   char corpse_name[MAX_NAME_LENGTH + 32];   int found = FALSE;   /* Check if player is in the corpse room (3068) */   if (GET_ROOM_VNUM(IN_ROOM(ch)) != 3068) {     send_to_char(ch, "You must be in the room above the Questmaster in Midgaard to retrieve your corpse.\r\n");     return;   }   /* Construct corpse name (e.g., "the corpse of Groo") */   snprintf(corpse_name, sizeof(corpse_name), "the corpse of %s", GET_NAME(ch));   /* Debug all objects in the room */   if (CONFIG_DEBUG_MODE) {     log("RETRIEVE: Scanning objects in room 3068 for %s's corpse", GET_NAME(ch));     for (corpse = world[IN_ROOM(ch)].contents; corpse; corpse = corpse->next_content) {       log("RETRIEVE: Checking object '%s' (type %d, value[3] %d, value[1] %d, keywords '%s')",           corpse->short_description, GET_OBJ_TYPE(corpse), GET_OBJ_VAL(corpse, 3), GET_OBJ_VAL(corpse, 1), corpse->name);     }   }   /* Search for the player's corpse */   for (corpse = world[IN_ROOM(ch)].contents; corpse; corpse = next_obj) {     next_obj = corpse->next_content;     if (GET_OBJ_TYPE(corpse) == ITEM_CONTAINER && IS_SET(GET_OBJ_VAL(corpse, 3), CONT_CORPSE) &&         isname(GET_NAME(ch), corpse->name) && GET_OBJ_VAL(corpse, 1) == GET_IDNUM(ch)) {       found = TRUE;       break;     }   }   if (!found) {     send_to_char(ch, "No corpse of yours lies within this chamber.\r\n");     if (CONFIG_DEBUG_MODE) {       log("RETRIEVE: No corpse found for %s in room 3068, searched for '%s' (keywords 'corpse')",           GET_NAME(ch), corpse_name);     }     return;   }   /* Move corpse to player's inventory */   obj_from_room(corpse);   obj_to_char(corpse, ch);   /* Thematic messaging */   send_to_char(ch, "A blast of colors envelops the corpse of %s as it is restored to you by the Gods of Chaos.\r\n", GET_NAME(ch));   act("$n retrieves $p, guided by the Winds of Chaos.", FALSE, ch, corpse, 0, TO_ROOM);   /* Debug log */   if (CONFIG_DEBUG_MODE) {     log("RETRIEVE: %s retrieved corpse '%s' in room 3068", GET_NAME(ch), corpse_name);   } }

I use a play and code port, willing to bet most muds do. At least this is on the code port.

I am just unsure of what I might lose if I copy back the play port. I try and update weekly.

Just wish I had at least some pointers to where it might be making the corpse locked and closed.

Just some idiot puttering around in mud code.

Please Log in or Create an account to join the conversation.

More
16 Aug 2025 18:44 #10864 by wlessard1
Replied by wlessard1 on topic I broke corpses somehow
Well been chasing it as best I can.
I used DIFF to check the files between my code port and my play port.
Then I checked the exact changes on the files that were different and still can't find where a player corpse is ending up locked and closed.

Is it possible that 65535 is somehow corrupt in the system? Somewhere outside of src?

Please Log in or Create an account to join the conversation.

More
17 Aug 2025 21:52 - 17 Aug 2025 21:55 #10865 by thomas
Replied by thomas on topic I broke corpses somehow
When such a thing happens, look to what is checked when containers are locked:
Code:
CONTAINER: (Type Flag 15) value 0: Capacity (max containable weight) of container value 1: Container flag bitvector (MUST be a numeric bitvector) 1 CLOSEABLE Container can be closed and locked. 2 PICKPROOF Lock on container can’t be picked. 4 CLOSED Container is closed when loaded. 8 LOCKED Container is locked when loaded. value 2: The vnum of the key object that opens this container. -1 if it has no key. value 3: Unused

You are setting it like this:
Code:
  GET_OBJ_VAL(corpse, 0) = 0; /* Can't store stuff */   GET_OBJ_VAL(corpse, 3) = 1; /* Corpse Identifier */   SET_BIT(GET_OBJ_VAL(corpse, 3), CONT_CORPSE); /* Set CONT_CORPSE flag */   GET_OBJ_VAL(corpse, 1) = IS_NPC(ch) ? 0 : GET_IDNUM(ch); /* Set owner ID */
Note that GET_OBJ_VAL(x, 1) -> the lock bitvector. So, when you set it to GET_IDNUM(ch), the bits in this number gets set, resulting in this output:
Code:
Weight capacity: 0, Lock Type: CLOSED LOCKED UNDEFINED UNDEFINED , Key Num: 0, Corpse: YES
So, either, everywhere you check if you can take from something, first check if it's a corpse or switch a little on the values.
I'd suggest moving the CONT_CORPSE flag to the GET_OBJ_VAL(x, 1) bitvector (there's plenty of room) and then using the whole unused GET_OBJ_VAL(x, 3) for the idnum of the player.
Code:
#define CONT_CORPSE (1 << 5) #define IS_CORPSE(cont) IS_SET(GET_OBJ_VAL(1, CONT_CORPSE)) SET_BIT(GET_OBJ_VAL(corpse, 1), CONT_CORPSE); /* set the corpse flag */ GET_OBJ_VAL(corpse, 3) = IS_NPC(ch) ? 0 : GET_IDNUM(ch); /* Set owner ID */
Last edit: 17 Aug 2025 21:55 by thomas.

Please Log in or Create an account to join the conversation.

More
Today 00:38 #10868 by wlessard1
Replied by wlessard1 on topic I broke corpses somehow
I found exactly where I had the issue. I commented out the line and now I can open and close.

The idea was to lock the corpse to the person. Not sure if I had to but in testing, someone else could pick up the corpse and I was trying to think ahead.

/* GET_OBJ_VAL(corpse, 1) = IS_NPC(ch) ? 0 : GET_IDNUM(ch); Set owner ID */

Please Log in or Create an account to join the conversation.

Time to create page: 0.212 seconds