Picking your brains

Posted by Syriac on Fri 30 Jul 2010 09:53 AM — 10 posts, 29,955 views.

#0
I implemented a limited object flag in my MUD to control super objects from popping too frequently, here is what I have in my reset.c
--

Under case 'G' and case 'e' in reset.c

      if (!IS_OBJ_STAT(obj, ITEM_LIMITED)) {
        get_objvalue(obj);
      obj = obj_to_char(obj, mob);
      if ( pReset->command == 'E' )
  	do_wear(mob, obj->name);
      }
 
      if (IS_OBJ_STAT(obj, ITEM_LIMITED)) {
 
        if (number_percent() <= 40) {
                get_objvalue(obj);
                sysdata.limitedobjpops++;
                sprintf(buf, "> > Limited item pop (%s) on %s. %s", obj->short_descr, mob->short_descr, (char *) ctime( &current_time ) );
                log_string_plus( buf, LOG_NORMAL, LEVEL_GREATER);

                obj = obj_to_char(obj, mob);
                save_char_obj(mob);
                do_wear(mob, obj->name);
                //save_char_obj(mob);
        }
        else
                do_wear(mob, "All");
      }

      lastobj = obj;
      break;
      break;



It doesn't do it all the time but sometimes this happens...

> reset area
Ibeilwyn wears a flowing black cloak about his body.
Ibeilwyn fits a black metal breastplate on his body.
Log: > > Limited item pop (a bloody spiked war helm) on Ibeilwyn. Fri Jul 30 02:52:48 2010

Ibeilwyn dons a bloody spiked war helm upon his head.
Done.


> l ib
Ibeilwyn stands before you, neither live nor dead. He stands perfectly still,
the only sign that he is not fake is the sound of his deep and raspy
breathing. About his body he wears a flowing black cloak that covers up
everything with the exception of his face and the hand that holds a massive
and deadly looking sword. Upon his head is a spiked helm, blood stains are
painfully visible on it. His frosted over eyes have no pupils. An intense red
aura surrounds him.
Ibeilwyn is in perfect health.

Ibeilwyn is using:
<worn on body> (Token Magic) a black metal breastplate
<worn about body> (Moderate Magic) a flowing black cloak

Mobile #3505 'Ibeilwyn' is a level 49 undead mage.

You peek at his inventory:
Nothing.



Notice he's not actually wearing the helm. Somehow it vanished. Any thoughts on what could be happening here? It happens maybe 10% of the time, the other 90% of the time it works as expected.
Amended on Fri 30 Jul 2010 06:08 PM by Syriac
Australia Forum Administrator #1
Is this all the same snippet? Looks to me like you are wearing it twice. Try putting a breakpoint at the start and seeing if the pointers etc. are what you expect them to be.
#2
You've lost me... :-/

Do_wear is called once per condition, it shouldn't be called more than once... I modified the code but still have the same issue..


      if (!IS_OBJ_STAT(obj, ITEM_LIMITED))
      {
                get_objvalue(obj);
                obj = obj_to_char(obj, mob);
                if ( pReset->command == 'E' )
                        do_wear(mob, obj->name);
      }

      if (IS_OBJ_STAT(obj, ITEM_LIMITED)) {
        if (number_percent() <= 40) {
                popped = TRUE; }
        if (popped == TRUE) {
                get_objvalue(obj);
                sysdata.limitedobjpops++;
                sprintf(buf, "> > Limited item pop (%s) on %s. %s", obj->short_descr, mob->short_descr, (char *) ctime( &current_time ) );
                log_string_plus( buf, LOG_NORMAL, LEVEL_GREATER);

                obj = obj_to_char(obj, mob);
                if ( pReset->command == 'E' ) {
                        do_wear(mob, obj->name); }
                save_char_obj(mob);
        }
        if ( popped == FALSE ) {
                extract_obj( obj );
                do_wear(mob, "All");
                //sprintf(buf, "> > Limited item supressed (%s) on %s. %s", obj->short_descr, mob->short_descr, (char *) ctime( &current_time ) );
                //log_string_plus( buf, LOG_NORMAL, LEVEL_GREATER);
      }  }

Australia Forum Administrator #3
Oh OK, I didn't look too closely. But if you have this:


      if (!IS_OBJ_STAT(obj, ITEM_LIMITED))
      {
          // yadda yadda
      }

      if (IS_OBJ_STAT(obj, ITEM_LIMITED)) 
      {
         // blah blah
      }



It looks a bit clearer as:



      if (!IS_OBJ_STAT(obj, ITEM_LIMITED))
       {
           // yadda yadda
        }
      else
        {
         // blah blah
        }



Then it is clearer that only one path is taken.

Ditto for:


if (popped == TRUE)
      {
      }

if (popped == FALSE ) 
      {
      } 


Depending on the declaration of popped (eg. is it an int?) it could be neither TRUE nor FALSE. Also in the code there I see you setting popped to TRUE, but never to FALSE.
Amended on Sun 01 Aug 2010 11:05 AM by Nick Gammon
#4
Nah its declared bool popped = FALSE; in the function.
#5
Trying the brackets though :)
#6
Hrm... same issue. I tried using the equip_char function and do wear. For some reason the object goes to them, but vanishes when it hits equip_char (since do_wear just ends up calling to it anyway) here's another look

> reset area
Ibeilwyn wears a flowing black cloak about his body.
Ibeilwyn fits a black metal breastplate on his body.
Log: > > Limited item pop (the Deadly Blade of Ibeilwyn) on Ibeilwyn. Sun Aug 1 13:46:37 2010

Right here we see him put on the item---> Ibeilwyn wields the Deadly Blade of Ibeilwyn.
Done.

<24485/24485hp 25130/25130m 25000/25000mv (1494900tnl) [1174136gp]>

> l ib
Ibeilwyn stands before you, neither live nor dead. He stands perfectly still,
the only sign that he is not fake is the sound of his deep and raspy
breathing. About his body he wears a flowing black cloak that covers up
everything with the exception of his face and the hand that holds a massive
and deadly looking sword. Upon his head is a spiked helm, blood stains are
painfully visible on it. His frosted over eyes have no pupils. An intense red
aura surrounds him.
Ibeilwyn is in perfect health.

Ibeilwyn is using:
----> Item isn't here :-/
<worn on body> (Token Magic) a black metal breastplate
<worn about body> (Moderate Magic) a flowing black cloak

Mobile #3505 'Ibeilwyn' is a level 50 undead mage.

You peek at his inventory:
Nothing.
Australia Forum Administrator #7
I would use gdb and put a breakpoint on the line where it wears the item. do_where is designed to be called by a player and may be sending an error (eg. "You do not have that item") or something, which you won't see as you aren't the mob.

I see you have the line "Ibeilwyn wields the Deadly Blade of Ibeilwyn." - that seems to indicate he wore it, but maybe something went wrong afterwards (like he dropped it for some reason).

The sort of thing you can do once the first breakpoint fires (ie you are hitting the problem code) is install other breakpoints to see (eg. in places where it might be removed) if it gets un-worn a moment later.
#8
I'll try the break points. Its weird because sometimes he does actually get it and wear it. If it gave the "you don't have it" type message I would assume it would be in his inventory but it isn't :-/
#9
Okay I figured it out - the code I pasted was fine it was something else I did with the flag in another file years ago I completely had forgotten *blush*