Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ For loop on obj and extract_obj specify

For loop on obj and extract_obj specify

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Zeno   USA  (2,871 posts)  Bio
Date Wed 19 May 2004 02:05 AM (UTC)
Message
Eh, two things that I can't seem to figure out/remember how to do.

First, how would I do a for loop to check through all the players items, and containers? I know how do all items, just not through the containers.

Second, how would I specify what item extract_obj would extract? I did a for loop:

    for (shard = ch->first_carrying; shard; shard = shard->next_content)
    {
      if (shard->pIndexData->vnum == 91)
      {
        if ( arg[0] == '\0' )
          {
             send_to_char( "Where?\n\r", ch );
             return;
          }
      }


But when this is done:

extract_obj( shard );

It extracts the first obj in a players inven, instead of the item with vnum 91.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #1 on Wed 19 May 2004 02:22 AM (UTC)
Message
You can't do it in a single loop. Well, you technically could, but you would need to use a stack or something. It's easier to do it recursively.

When are you calling extract_obj? You're probably not breaking out of the loop at the right spot or something like that.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #2 on Wed 19 May 2004 03:52 AM (UTC)
Message
Think you could provide an example on the container loop, I've never done containers before. (I'll look over the structure though)

Uh, the for loop ending bracket at the end of the function.

    }
        send_to_char( Don't have any!\n\r", ch );
        return;
}

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #3 on Wed 19 May 2004 03:58 AM (UTC)
Message
Could you give the whole code for the for loop so I can be sure exactly what I'm looking at?


How to write the recursive function depends on what you're trying to do... are you trying to find a given item?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #4 on Wed 19 May 2004 04:05 AM (UTC)

Amended on Wed 19 May 2004 04:06 AM (UTC) by Zeno

Message
Yeah, the full function would probably help, heh.

void do_embed( CHAR_DATA *ch, char *argument )
{
    char arg  [MAX_INPUT_LENGTH];
    OBJ_DATA *shard;
    char buf[MAX_STRING_LENGTH];

    one_argument( argument, arg );

    if ( IS_NPC(ch))
        return;

    for (shard = ch->first_carrying; shard; shard = shard->next_content)
    {
      if (shard->pIndexData->vnum == 91)
      {
        if ( arg[0] == '\0' )
          {
             send_to_char( "&wEmbed the Shikon Shard where?\n\r(arm, leg, head, neck, foot, hand, torso, shoulder)\n\r ", ch$
             return;
          }
      }

    if ( !str_cmp( arg, "arm" ) )
    {
          send_to_char( "&PYou embed a shard into your arm.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s arm.", ch, NULL, NULL, TO_CANSEE);
          ch->arm_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their arm", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "leg" ) )
        {
          send_to_char( "&PYou embed a shard into your leg.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s leg.", ch, NULL, NULL, TO_CANSEE);
          ch->leg_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their leg", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "head" ) )
        {
          send_to_char( "&PYou embed a shard into your head.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s head.", ch, NULL, NULL, TO_CANSEE);
          ch->head_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their head", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "neck" ) )
        {
          send_to_char( "&PYou embed a shard into your neck.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s neck.", ch, NULL, NULL, TO_CANSEE);
          ch->neck_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their neck", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "foot" ) )
        {
          send_to_char( "&PYou embed a shard into your foot.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s foot.", ch, NULL, NULL, TO_CANSEE);
          ch->feet_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their foot", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "hand" ) )
        {
          send_to_char( "&PYou embed a shard into your hand.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s hand.", ch, NULL, NULL, TO_CANSEE);
          ch->hand_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their hand", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "torso" ) )
        {
          send_to_char( "&PYou embed a shard into your torso.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s torso.", ch, NULL, NULL, TO_CANSEE);
          ch->torso_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their torso", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        if ( !str_cmp( arg, "shoulder" ) )
        {
          send_to_char( "&PYou embed a shard into your shoulder.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s shoulder.", ch, NULL, NULL, TO_CANSEE);
          ch->shoulder_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their shoulder", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }
        else
        {
        send_to_char( "&wThat is not a body part!\n\r", ch );
        return;
        }
    }
        send_to_char( "&wYou don't have any Shikon Shards!\n\r", ch );
        return;
}

(I'll probably redo this as a switch/case code)

And yes, I want to find a specific item on the player.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #5 on Wed 19 May 2004 04:24 AM (UTC)
Message
OK... here's your problem:

for (shard = ch->first_carrying; shard; shard = shard->next_content)
    {
      if (shard->pIndexData->vnum == 91)
      {
        if ( arg[0] == '\0' )
          {
             send_to_char( "&wEmbed the Shikon Shard where?\n\r(arm, leg, head, neck, foot, hand, torso, shoulder)\n\r ", ch$
             return;
          }
      }<---------

    if ( !str_cmp( arg, "arm" ) )
    {
          send_to_char( "&PYou embed a shard into your arm.\n\r", ch );
          act(AT_GREY,"&P$n embeds a shard into $s arm.", ch, NULL, NULL, TO_CANSEE);
          ch->arm_shards++;
          ch->hit -= ch->hit * 0.01;
          separate_obj ( shard );
          obj_from_char( shard );
          sprintf(buf, "%s embeded a shard into their arm", ch->name );
          to_channel( buf, CHANNEL_SHARDMONITOR, "ShardMonitor", LEVEL_IMMORTAL );
          extract_obj( shard );
          return;
        }


As you can see, your vnum check only checks the argument. When you then check for location, you are outside the vnum check and therefore are operating on whichever object it is.

Do you know how recursion works? It can be fairly complicated. For a simple example, you could check out get_obj_weight() (which is recursive if I remember correctly.) I'll write a recursive example to do this when I have a little more time... :)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #6 on Wed 19 May 2004 04:35 AM (UTC)
Message
Fixed the first part, thanks.


int get_obj_weight( OBJ_DATA *obj )
{
    int weight;

    weight = obj->count * obj->weight;

    /* magic containers */
    if ( obj->item_type != ITEM_CONTAINER || !IS_OBJ_STAT(obj, ITEM_MAGIC) )
        for ( obj = obj->first_content; obj; obj = obj->next_content )
            weight += get_obj_weight(obj);

    return weight;
}

Although I've actually never done recursion, I can do it. But I don't want to count the number of objs, I want to show where the obj is, too.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #7 on Wed 19 May 2004 04:42 AM (UTC)
Message
When you say where it is, you mean the tree path of containers followed to get there? Ungh... if only you were in C++. :)

Depending on why you need to know where it is, this might get a lot easier or a lot harder...

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #8 on Wed 19 May 2004 10:58 AM (UTC)
Message
Eh, all I really meant was where the obj is. Bah, I'll just explain what I want to do. I want to make a command that does this:
Quote:

"jstat zeno"
Zeno is carrying 4 objs
2 in their inventory
1 in small bag worn on hand
1 held


Heh, I do plan on creating a custom-codebase MUD in C++ sometime in the future.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #9 on Wed 19 May 2004 09:58 PM (UTC)
Message
Ripped some stuff, looks like a workable model. I doubt its the most efficient way to do it, but hey, w/e
NOTE: THIS IS NOT TESTED

void do_jstat( CHAR_DATA *ch, char *argument )
{
  CHAR_DATA *victim;
  OBJECT_DATA *obj;
  OBJECT_DATA *container;
  char buf[MAX_STRING_LENGTH];
  int count, inventory, ammount;

   if ( !ch->desc )
   {
        send_to_char( "You have no descriptor\n\r", ch );
        return;
   }

   if ( ( victim = get_char_world( ch, argument ) ) == NULL )
   {
       send_to_char( "They aren't here.\n\r", ch );
       return;
   }

   for ( obj = victim->first_carrying; obj; obj = obj->next_content)
    count++;

   sprintf( buf, "%s is carrying %d object%s\n\r", victim->name, count, count == 1 ? "" : "s" );
   send_to_char( buf, ch );

  obj = NULL;
  inventory = 0;

  for ( obj = victim->first_carrying; obj; obj = obj->next_content )
    inventory++;

   sprintf( buf, "%d in their inventory\n\r", inventory );
   send_to_char( buf, ch );

  obj = NULL;
  ammount = 0;

 for ( obj = victim->first_carrying; obj; obj = obj->next_content )
   if ( obj->item_type == ITEM_CONTAINER )
   {
     ammount = 0;

     for ( container = obj->first_content; container; container = container->next_content ) 
      ammount++;

   sprintf( buf, "%d in %s\n\r", ammount, obj->short_descr  );
   send_to_char( buf, ch );
   }

 return;
}


Hoped that helpped.
~Odis

~Nick Cash
http://www.nick-cash.com
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #10 on Thu 20 May 2004 12:49 AM (UTC)
Message
No, that only goes one level deep, you need an arbitrary depth of recursion.

Let me explain the basic idea of what you're doing:

- you are traversing the tree of objects in a player's inventory
- at every level, you are counting how many objects there are
- you are printing a summary of results


The recursive function is, in pseudo-code:

int CountObjects(object * first-one)
{
   if ( !first-one )
       return 0;
   int count = 0;
   for every element object in list first-one
   {
      count++;
      for every child of object
         count += CountObjects(child);
   }
   return count;
}


That's pseudo-code off the top of my head. I think that should do it, but I'll add a little disclaimer about how I may be slightly off. :)

That count will count how many objects are on a given level. It acts on one sub-level at a time. You call it on person->first_carrying and it returns how many objects they have.

However things become more complicated if you want to print out the subresults as well. You need to pass around some more variables: a string to store the results (that you *must make sure* is large enough) and either the player's char_data* or the player's name. You just add those and that should do the trick.

Recusion is a very poweful but sometimes very complicated tool. :)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #11 on Thu 20 May 2004 01:16 AM (UTC)
Message
Indeed. :)

~Nick Cash
http://www.nick-cash.com
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #12 on Thu 20 May 2004 01:18 AM (UTC)
Message
Hmm, a little more complicated then I expected. All I thought I needed to do was another loop. Well, I'll work some things over. Thanks.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


26,071 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.