26 Feb, 2010, Bojack wrote in the 1st comment:
Votes: 0
I need some help here, either im not seeing how to write this or just not thinking clearly. Im adding onto scan.c code to find an obj either on a person rooms away, or in a room rooms away. I rather not give away my idea because this is only going to be specific to our mud to make it more unique but basically how scan works is it searches the nearest people to you and will give you "a powerlevel of xxxx is nearby to the north", itll even go 4 rooms deep. What im adding on is the ability to search for an object the same way. My problem is it works fine when someone is holding the object, but when its in a room itll go into an infinite loop. Here's what I got:

Info send part:
if (rch != NULL)
{
if ( (obj = get_obj_wear(rch, "radar", TRUE)) != NULL)
{
scan_room = rch->in_room;
scan_list(scan_room, rch, 0, -1, obj);
for (door = 0; door < 6; door++)
if ( (pExit = scan_room->exit[door]) != NULL)
{
for (depth = 1; depth < MAX_DEPTH; depth++)
if ( (pExit = scan_room->exit[door]) != NULL)
{
scan_room = pExit->u1.to_room;
scan_list(pExit->u1.to_room, rch, depth, door, obj);
}
}
}
}

The Call:
void scan_list (ROOM_INDEX_DATA * scan_room, CHAR_DATA * ch, sh_int depth,
sh_int door, OBJ_DATA *obj)
{
CHAR_DATA *rch;
OBJ_DATA *obj2, *obj3;

if (scan_room == NULL)
return;

if (obj == NULL) //Not searching for item
{
for (rch = scan_room->people; rch != NULL; rch = rch->next_in_room)
{
if (rch == ch)
continue;
if ((!IS_NPC (rch) && rch->invis_level > ch->level)
|| (race_lookup("android") == rch->race && !IS_IMMORTAL(ch)))
continue;
if (can_see (ch, rch))
scan_char (rch, ch, depth, door, NULL);
}
}

if (obj != NULL) //Is searching for item
{
//If player is holding item
for (rch = scan_room->people; rch != NULL; rch = rch->next_in_room)
{
if (rch == ch)
continue;
if ( (!IS_NPC (rch) && rch->invis_level > ch->level)
|| (race_lookup("android") == rch->race && !IS_IMMORTAL(ch)) )
continue;
if (can_see (ch, rch) )
{
if ( (obj2 = get_obj_here(rch, NULL, "xxx")) != NULL
&& !is_name ("radar", obj2->name) && obj2->carried_by != ch)
scan_char (rch, ch, depth, door, obj);
}
}
//If player is in a room
/*
for (obj3 = scan_room->contents; obj3 != NULL; obj3 = obj3->next_content)
{
if (can_see_obj(ch, obj3) )
{
if (is_name ("xxx", obj3->name)
&& !is_name ("radar", obj3->name) )
scan_obj (ch, depth, door);
}
}
*/
}
return;
}

The comment part is the problem. Anyone have any ideas?
26 Feb, 2010, David Haley wrote in the 2nd comment:
Votes: 0
What does "scan_obj" do?
A guess is that you don't actually prevent it from scanning more than "depth" rooms away.
Have you tried running this through gdb to see what it's doing?
Even putting print statements at the beginning of each function to print the state will give you hints as to where it's looping.
27 Feb, 2010, Bojack wrote in the 3rd comment:
Votes: 0
Scan_obj and scan_char are just a sprintf printout sent to the char, thats all it does. I did try running it through gdb and I got nothing, although I didnt try break points cuz im not good at using it correctly. I did use print statements though and the commented out part is where the problem is. Its just that section. The only thing I can think of it being the problem is resetting it back to scan_room = ch->in_room; in the call part. Btw what I mean by call part is its the gather info part.
27 Feb, 2010, David Haley wrote in the 4th comment:
Votes: 0
Well a lot of things don't make sense here. For starters you have this 'obj' pointer and it's unclear where it points. You're testing on the names "xxx" and "radar" although you were talking about searching for an object. Also, if scan_obj is really doing what you say it is, then there's no reason for that to loop forever. It will never be resetting scan_room in the code you commented out, because you say that scan_obj just prints stuff – it's not the "gather info" part.

If it's just that section, then put in print statements before the loop, after the loop, and then at the beginning of each loop iteration. Print out which room content is being examined. Then see if the loop terminates. For now, you still need to provide more information for it to become apparent where the loop is happening, because again the code you showed wouldn't be looping forever.
27 Feb, 2010, Bojack wrote in the 5th comment:
Votes: 0
It turns out the reason it was looping is because of the door loop, not the object contents. I cut out the scan_room->contents part because get_obj_here does that already, it looks for in room, in inventory or being worn. I tested all that with just a simple door loop
scan_room = rch->in_room;
scan_list(scan_room, rch, 0, -1, obj);
for (door = 0; door < 6; door++)
{
if ((pExit = scan_room->exit[door]) != NULL)
scan_list(pExit->u1.to_room, rch, 1, door, obj);
}

which everything works just fine, its when I add the depth loop that it messes up. I got to figure out a better way to reset the scan_room define. Scan_obj doesnt do anything but this:
void scan_obj (CHAR_DATA *ch, sh_int depth, sh_int door)
{
extern char *const dir_name[];
extern char *const distance[];
char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];

buf[0] = '\0';

sendch ("{*", ch);
sprintf (buf, "The radar has found a dragonball");
strcat (buf, " ");
if (depth == 0)
sprintf (buf2, distance[1]);
else
sprintf (buf2, distance[depth], dir_name[door]);
strcat (buf, buf2);
strcat (buf, "\n\r");

sendch (buf, ch);
return;
}
27 Feb, 2010, David Haley wrote in the 6th comment:
Votes: 0
Store the original scan room before changing it, and when you're done with the new one, revert to the old one.
28 Feb, 2010, Bojack wrote in the 7th comment:
Votes: 0
I came up with this but the problem is up or down isnt working.
scan_room = rch->in_room;
scan_list (scan_room, rch, 0, -1, obj);
for (door = 0; door < 6; door++)
{
if ( (pExit = rch->in_room->exit[door]) != NULL)
{
for (depth = 1; depth < MAX_DEPTH; depth++)
{
if ((pExit1 = scan_room->exit[door]) != NULL)
{
scan_room = pExit1->u1.to_room;
scan_list (scan_room, rch, depth, door, obj);
}
}
}
}
28 Feb, 2010, Davion wrote in the 8th comment:
Votes: 0
Bojack said:
I came up with this but the problem is up or down isnt working.
scan_room = rch->in_room;
scan_list (scan_room, rch, 0, -1, obj);
for (door = 0; door < 6; door++)
{
if ( (pExit = rch->in_room->exit[door]) != NULL)
{
for (depth = 1; depth < MAX_DEPTH; depth++)
{
if ((pExit1 = scan_room->exit[door]) != NULL)
{
scan_room = pExit1->u1.to_room;
scan_list (scan_room, rch, depth, door, obj);
}
}
}
}


Do you have more than the normal (neswud) exits? Could be 6 isn't doing it. Should be a variable called MAX_DIR or MAX_DOOR, pretty sure it's the former though. Should probably use that anyways.
28 Feb, 2010, Bojack wrote in the 9th comment:
Votes: 0
Nah I dont, its the same directions and 0 - 5 are the doors and MAX_DIR is used. Its something to do with combining these two loops:
for (door = 0; door < 6; door++)
{
if ((pExit = ch->in_room->exit[door]) != NULL)
scan_list (pExit->u1.to_room, ch, 1, door, NULL);
}


scan_room = ch->in_room;
for (depth = 1; depth < 4; depth++)
{
if ((pExit = scan_room->exit[door]) != NULL)
{
scan_room = pExit->u1.to_room;
scan_list (pExit->u1.to_room, ch, depth, door, NULL);
}
}

Seperately they work just fine all directions, btw the second one the door is defined by the player saying "scan south" or "scan north".
04 Mar, 2010, Bojack wrote in the 10th comment:
Votes: 0
I finally figured it out, scan_room = rch->in_room; should be right after for (door = 0; door < 6; door++)
0.0/10