29 Nov, 2009, JohnnyHawk wrote in the 1st comment:
Votes: 0
Got a 'ch' might be used uninitialized in this function error for is safe and is safe spell because to fit certain needs
I decided to only have it check if the victim was safe, as in all cases it is the victim being attacked etc. Now of
course I do CHAR_DATA * ch; at the start of is safe and is safe spell and it all compiles etc but with the uninitialized
errors in those two. I can post it if you want, but its just the regular bool is_safe with just (CHAR_DATA * victim)
and the CHAR_DATA * ch; is called inside, the rest is mostly stock cept at the end I added to see if victm->violent
but when i ran it just to see no one is ever safe… basically :P If someone would help me i can PM you the code if
this is too vague, I just didnt wanna post all that in here as its mainly stock. Im starving to death and super tired
so hopefully this is something silly I can fix.
29 Nov, 2009, kiasyn wrote in the 2nd comment:
Votes: 0
Try declaring it as CHAR_DATA *ch = NULL;
29 Nov, 2009, JohnnyHawk wrote in the 3rd comment:
Votes: 0
I did and it crashed upon attacking another character.
29 Nov, 2009, Runter wrote in the 4th comment:
Votes: 0
Post some code. Pastebin it or just post it here.
29 Nov, 2009, JohnnyHawk wrote in the 5th comment:
Votes: 0
bool is_safe (CHAR_DATA * victim)
{
CHAR_DATA * ch;
if (victim->in_room == NULL || ch->in_room == NULL)
return TRUE;

if (victim->fighting == ch || victim == ch)
return FALSE;

if (IS_IMMORTAL (ch) && ch->level > LEVEL_IMMORTAL)
return FALSE;

/* killing mobiles */
if (IS_NPC (victim))
{

/* safe room? */
if (IS_SET (victim->in_room->room_flags, ROOM_SAFE))
{
send_to_char ("Not in this room.\n\r", ch);
return TRUE;
}

if (victim->pIndexData->pShop != NULL)
{
send_to_char ("The shopkeeper wouldn't like that.\n\r", ch);
return TRUE;
}

/* no killing healers, trainers, etc */
if (IS_SET (victim->act, ACT_TRAIN)
|| IS_SET (victim->act, ACT_IS_HEALER)
|| IS_SET (victim->act, ACT_IS_CHANGER))
{
send_to_char ("I don't think Mota would approve.\n\r", ch);
return TRUE;
}

if (!IS_NPC (ch))
{
/* no pets */
if (IS_SET (victim->act, ACT_PET))
{
act ("But $N looks so cute and cuddly…",
ch, NULL, victim, TO_CHAR);
return TRUE;
}

/* no charmed creatures unless owner */
if (IS_AFFECTED (victim, AFF_CHARM) && ch != victim->master)
{
send_to_char ("You don't own that monster.\n\r", ch);
return TRUE;
}
}
}
/* killing players */
else
{
/* NPC doing the killing */
if (IS_NPC (ch))
{
/* safe room check */
if (IS_SET (victim->in_room->room_flags, ROOM_SAFE))
{
send_to_char ("Not in this room.\n\r", ch);
return TRUE;
}

/* charmed mobs and pets cannot attack players while owned */
if (IS_AFFECTED (ch, AFF_CHARM) && ch->master != NULL
&& ch->master->fighting != victim)
{
send_to_char ("Players are your friends!\n\r", ch);
return TRUE;
}
}
/* player doing the killing */
else
{
if (IS_SET (victim->in_room->room_flags, ROOM_SAFE))
{
if (IS_SET (victim->act, PLR_KILLER)
|| IS_SET (victim->act, PLR_THIEF)
|| IS_SET (victim->act, PLR_VIOLENT))
return FALSE;
else
{
send_to_char ("Not in this room.\n\r", ch);
return TRUE;
}
}

if (ch->level > victim->level + 8)
{
send_to_char ("Pick on someone your own size.\n\r", ch);
return TRUE;
}
}
}
return FALSE;
}


Edit by kiasyn for code tags.
29 Nov, 2009, Mudder wrote in the 6th comment:
Votes: 0
You should use the code tags and for big chunks of code, pastebin is usually best.
29 Nov, 2009, JohnnyHawk wrote in the 7th comment:
Votes: 0
Sorry about that, any clue though? I code in wordpad so its becoming increasingly difficult to troubleshoot certain things but this one seems like an easy one.
29 Nov, 2009, kiasyn wrote in the 8th comment:
Votes: 0
You need to be passing CHAR_DATA *ch as an argument, ie

bool is_safe (CHAR_DATA *ch, CHAR_DATA * victim)
29 Nov, 2009, JohnnyHawk wrote in the 9th comment:
Votes: 0
Ive removed ch from the is_safe so that now all it checks is is_safe(victim), its been removed from every spot possible. Now Just need to initialize ch as the Ch doing w/e and have it check if the victim is safe. This possible?
29 Nov, 2009, Sharmair wrote in the 10th comment:
Votes: 0
If you took ch out of is_safe, there should NOT be any uses in is_safe, so you should not have to initialize
ch as it is not there. The code you posted still has alot of uses of ch, so take them out if for whatever
reason, you don't want to pass the attacker as you really should (the only reason to not pass ch (attacker)
is if your is_safe only looks at things relating to victim, and therefor again, ALL the uses of ch should be
removed).

Also, it would be nice if you could see the () in that code (or any code with the new coloring).
29 Nov, 2009, Mudder wrote in the 11th comment:
Votes: 0
The problem I see is that the ch is necessary for a lot of the comparisons. I tried to put this into my code to see exactly where your problems were, but I wasn't willing to sort through all my code to remove the first argument.

You should remove all references to ch. Currently is_safe does its checks surrounding ch, you'll want to re-write it to focus on the victim instead.

Also, download notepad++ it's amazing. Or TED notepad if you want something crappy and tiny. ANYTHING but notepad. You poor, poor soul!
29 Nov, 2009, JohnnyHawk wrote in the 12th comment:
Votes: 0
It checks originally to see if ch and victim are both safe but i only wanna see if victim is safe. However, how else can i make it check that the player attacking isnt imm and all that? Just has to be there i guess?
29 Nov, 2009, Mudder wrote in the 13th comment:
Votes: 0
I decided to remove all references to ch for you. This will now work, however, PK ranges are gone. Because you only get ranges when comparing the attacker to the victim.

Why did you want to remove the attacker from this function anyway?

bool is_safe (CHAR_DATA * victim)
{
if ( victim->in_room == NULL )
return TRUE;

@@ if ( IS_IMMORTAL( victim ) ) //<— I assume you have that defined?
return TRUE;

/* killing mobiles */
if ( IS_NPC( victim ) )
{

/* safe room? */
if ( IS_SET( victim->in_room->room_flags, ROOM_SAFE ) )
{
// send_to_char ( "Not in this room.\r\n", ch );
return TRUE;
}

if ( victim->pIndexData->pShop != NULL )
{
// send_to_char ( "The shopkeeper wouldn't like that.\r\n", ch );
return TRUE;
}

/* no killing healers, trainers, etc */
if ( IS_SET( victim->act, ACT_TRAIN )
|| IS_SET( victim->act, ACT_IS_HEALER )
|| IS_SET( victim->act, ACT_IS_CHANGER ) )
{
// send_to_char ( "I don't think Mota would approve.\r\n", ch );
return TRUE;
}
}
/* killing players */
else
{
if ( IS_SET( victim->in_room->room_flags, ROOM_SAFE ) )
{
if ( IS_SET ( victim->act, PLR_KILLER )
|| IS_SET ( victim->act, PLR_THIEF )
|| IS_SET ( victim->act, PLR_VIOLENT ) )
return FALSE;
else
{
// send_to_char ( "Not in this room.\r\n", ch );
return TRUE;
}
}
}
return FALSE;
}


EDIT: Also, I rearranged the \n\r to \r\n, apparently the latter is more correct. Might aswell stick to that one. :blues:
29 Nov, 2009, Sharmair wrote in the 14th comment:
Votes: 0
You should then pass it in the call, as then you are in fact still having the attacker have some
bearing on the outcome of is_safe. You really can't easily find the attacker from just the victim
(ok, if really is not that hard, but has issues that would require you to change how things worked
more then really needed) unless you loop through the characters in the room and look for who
they are fighting (there might be more then one attacker too). Even then, depending on how
your code works, on some first hits, the attacker might not be flagged as fighting yet.
29 Nov, 2009, JohnnyHawk wrote in the 15th comment:
Votes: 0
I dont want the outcome of if they're safe to be ch dependent, but then it cant check if attacker is ch to make victim not safe and all that random stuff, though i dont need imms killing morts anyhow. Ill try this out ty Mudder if this works out :P
29 Nov, 2009, Mudder wrote in the 16th comment:
Votes: 0
I fixed some mistakes. Check to be sure you have the updated copy. :)
29 Nov, 2009, Sharmair wrote in the 17th comment:
Votes: 0
Seems those send_to_char calls probably should be removed too, as they currently go to ch.
29 Nov, 2009, Mudder wrote in the 18th comment:
Votes: 0
Whoops! Good call. I didn't even think to check that.

EDIT: Those send_to_chars could be replaced with act( "message", NULL, NULL, NULL, TO_ROOM );

That should send the message to the whole room, I'm sure there are better ways to do that but I'm not sure what you have. Is this QuickMUD?
29 Nov, 2009, JohnnyHawk wrote in the 19th comment:
Votes: 0
Checked it all out fresh to my git branch, ty for tryin guys ill chalk this up to beyond me :P
29 Nov, 2009, Kayle wrote in the 20th comment:
Votes: 0
You can't pass only victim to a function, and then expect to check against ch. It's not going to work. If you want to check against ch, you're going to either have to pass it as an argument, or not check against it AT ALL.

The reason the compiler was telling you it was uninitialized was because it was. You never assigned a value to ch before checking against it. A little illustration:

JohnnyHawk said:
bool is_safe (CHAR_DATA * victim)
{
CHAR_DATA * ch; //See here? ch is defined, but nothing is assigned to it, and there's no way to.
if (victim->in_room == NULL || ch->in_room == NULL) //Uh oh. ch->in_room is NULL. because ch is NULL.
return TRUE;

if (victim->fighting == ch || victim == ch) //This isn't going to work either, because again, ch is NULL.
return FALSE;

if (IS_IMMORTAL (ch) && ch->level > LEVEL_IMMORTAL) //Yep, more checking against a NULL value.
return FALSE;

/* killing mobiles */
if (IS_NPC (victim))
{

/* safe room? */
if (IS_SET (victim->in_room->room_flags, ROOM_SAFE))
{
send_to_char ("Not in this room.\n\r", ch); //sending the message to ch?
return TRUE;
}

if (victim->pIndexData->pShop != NULL)
{
send_to_char ("The shopkeeper wouldn't like that.\n\r", ch); //Again with the sending to ch…
return TRUE;
}

/* no killing healers, trainers, etc */
if (IS_SET (victim->act, ACT_TRAIN)
|| IS_SET (victim->act, ACT_IS_HEALER)
|| IS_SET (victim->act, ACT_IS_CHANGER))
{
send_to_char ("I don't think Mota would approve.\n\r", ch); //Again…
return TRUE;
}

if (!IS_NPC (ch)) //Yep, this isn't going to work either. ch doesn't have a value.
{
/* no pets */
if (IS_SET (victim->act, ACT_PET))
{
act ("But $N looks so cute and cuddly…",
ch, NULL, victim, TO_CHAR);
return TRUE;
}

/* no charmed creatures unless owner */
if (IS_AFFECTED (victim, AFF_CHARM) && ch != victim->master) //Again…
{
send_to_char ("You don't own that monster.\n\r", ch); //And again…
return TRUE;
}
}
}
/* killing players */
else
{
/* NPC doing the killing */
if (IS_NPC (ch)) //Nope, not gonna work here either.
{
/* safe room check */
if (IS_SET (victim->in_room->room_flags, ROOM_SAFE))
{
send_to_char ("Not in this room.\n\r", ch); //I suppose this works if you don't want anyone to ever see it…
return TRUE;
}

/* charmed mobs and pets cannot attack players while owned */
if (IS_AFFECTED (ch, AFF_CHARM) && ch->master != NULL
&& ch->master->fighting != victim) //Yeah.. about that… There is no ch.
{
send_to_char ("Players are your friends!\n\r", ch);
return TRUE;
}
}
/* player doing the killing */
else
{
if (IS_SET (victim->in_room->room_flags, ROOM_SAFE))
{
if (IS_SET (victim->act, PLR_KILLER)
|| IS_SET (victim->act, PLR_THIEF)
|| IS_SET (victim->act, PLR_VIOLENT))
return FALSE;
else
{
send_to_char ("Not in this room.\n\r", ch);
return TRUE;
}
}

if (ch->level > victim->level + 8)
{
send_to_char ("Pick on someone your own size.\n\r", ch);
return TRUE;
}
}
}
return FALSE;
}


Alright, I think you get the picture now. Or so I would hope.

The ONLY way this would work the way it's written is if this was a member function of CHAR_DATA. But I doubt that's the case.

To put it simply, you're going to HAVE to pass CHAR_DATA *ch into the function.
0.0/22