02 Feb, 2008, Nash wrote in the 1st comment:
Votes: 0
I've been having a problem where… if in code I have
damage(ch,victim,10,sn,DAM_SLASH,true);
damage(ch,victim,10,sn,DAM_BASH,true);

and the first damage kills the victim, one of two things will happen:
1) PC: The second damage will jump across the world and kill him again
2)NPC: The victim will supposedly be extracted, but the second damage will still try and hit it, but since it's in a null room, the mud will crash when it tries to do any "to room" action.

does this sound more like a bug in free_char or raw_kill or.. something?
02 Feb, 2008, Tommi wrote in the 2nd comment:
Votes: 0
A better and safer way to do what your doing is to use the return codes that damage will give back, so you can check to see if you have a valid victim before calling damage again, what i think is happening is that your function does no know that the victim is no longer valid and is calling damage again using the data it has. The code below only calls damage the 2nd time if the victim is not dead.

retcode = damage( ch, victim, dam, sn );
if (retcode != rCHAR_DIED)
damage( ch, victim, dam, sn );
return;
02 Feb, 2008, Hades_Kane wrote in the 3rd comment:
Votes: 0
Hmm, you could try adding this at the top of your bool damage function in fight.c…

if(victim == NULL)
return FALSE;

if ((victim = get_char_room(ch,NULL,arg)) == NULL)
return FALSE;


It sounds like there might be something else going on, as I don't have either of those at the top of mine and I don't have any problems. So something else might be going on, but that might work as a fail-safe for now until you can find what else might be wrong.
03 Feb, 2008, Nash wrote in the 4th comment:
Votes: 0
The more pressing concern is that the victim is in a null room, but still exists with all its stats, victim == NULL fails because for some reason the victim is still floating in nullspace. I shouldn't have to trap for null room because the victim shouldn't even be there, if that makes any sense?
03 Feb, 2008, David Haley wrote in the 5th comment:
Votes: 0
The code as written has no way of knowing that the victim died in between the two attacks. You need to do something like what Tommi suggested and check if the character died before applying the second attack. This is not a bug in raw_kill etc. – those functions will not set the 'victim' pointer to NULL if the victim dies.
03 Feb, 2008, kiasyn wrote in the 6th comment:
Votes: 0
Tommi said:
A better and safer way to do what your doing is to use the return codes that damage will give back, so you can check to see if you have a valid victim before calling damage again, what i think is happening is that your function does no know that the victim is no longer valid and is calling damage again using the data it has. The code below only calls damage the 2nd time if the victim is not dead.

retcode = damage( ch, victim, dam, sn );
if (retcode != rCHAR_DIED)
damage( ch, victim, dam, sn );
return;


wouldnt that be
retcode = damage( ch, victim, dam, sn );
if (retcode != rVICT_DIED)
damage( ch, victim, dam, sn );
return;


?
03 Feb, 2008, Tommi wrote in the 7th comment:
Votes: 0
LOL yeah your right, you know i looked over that 10 times before i noticed what i had done wrong.
04 Feb, 2008, Nash wrote in the 8th comment:
Votes: 0
Is there any downside to making the mud just… NULL the victim if it's a dead npc?
04 Feb, 2008, David Haley wrote in the 9th comment:
Votes: 0
You need to define what it means for the MUD to "just NULL the victim". If you are talking about doing that in raw_kill, that will not be sufficient, because you are not changing the victim pointer in the calling function.
04 Feb, 2008, Nash wrote in the 10th comment:
Votes: 0
I meant in extract_char doing victim = NULL, Am I not understanding how pointers work? It seems like if I'm passing the pointer to victim it'll nuke it totally?
04 Feb, 2008, David Haley wrote in the 11th comment:
Votes: 0
A pointer is like a postal address written on a piece of paper. If you accept the analogy of creating and destroying postal addresses, then just by tearing up the piece of paper, you are not destroying anything other than your local copy of that piece of paper.

In this case, you have this code:
damage(ch,victim,10,sn,DAM_SLASH,true);
damage(ch,victim,10,sn,DAM_BASH,true);


This code has its own "piece of paper" for writing down victim's address. When you call damage, you photocopy that paper and give the copy to the damage function.

Now, if damage tears up that paper – or in more concrete terms, sets the pointer to NULL – all it's doing is losing its own local information. The function that called damage hasn't had any change to its local information.

More dangerously, even if extract_char destroys the character and sets its pointer to NULL, you still haven't done anything in the calling function and now you have an address to a bogus character.

Pointers are pretty tricky business. It's very important to distinguish between the pointer itself, which is just an address, and the data being pointed to. I think it's a fairly safe statement that a very considerable majority of programming errors in C are due to handling pointers incorrectly, if that's any comfort. :smile:
0.0/11