Welcome to the Builder Academy

Question I broke corpses somehow

More
15 Aug 2025 12: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.

Just a guy coding a mud at home for no reason but the challenge.

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

More
16 Aug 2025 12: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.

Just a guy coding a mud at home for no reason but the challenge.

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

More
16 Aug 2025 19: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?

Just a guy coding a mud at home for no reason but the challenge.

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

More
17 Aug 2025 22:52 - 17 Aug 2025 22: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 22:55 by thomas.

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

More
20 Aug 2025 01: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 */

Just a guy coding a mud at home for no reason but the challenge.

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

Time to create page: 0.187 seconds