Trying to add a skill, details inside

Posted by Kisuke on Wed 21 Mar 2007 12:49 AM — 18 posts, 65,073 views.

#0
Hi there. I'm using FUSS SMAUG 1.7 as a base right now and I am trying to add in a series of interelated skills. Basically, a player will use a skill and create a weapon (instance of an already existing weapon in game) and the weapon is edited with a new name/short desc according to a string saved in the pfile of the char. The other skills are similar, but check if the char is wielding the weapon made with the original skill and, if so, removes it and extracts it

Anywho. That all works. The problem I am having is that it doesn't seem to be saving the equipment properly. i can go back and forth between the weapons that are made with each skill, but if the player quits, the mud crashes and if an autosave occurs and the player tries to replace one of the weapons with the other skill, the mud crashes.

I know this may sound confusing, but I could really use some help. PM me or whatever if you have any insight or would be willing to help but need more info.
USA #1
Use gdb to debug it, and if you need help post the gdb here.
#2

GNU gdb Red Hat Linux (6.3.0.0-1.132.EL3rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

Core was generated by `../src/smaug 7600'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x001832f8 in _int_free () from /lib/tls/libc.so.6
#3
I think that's the right dump. I'm not too solid on how to use gdb.
USA #4
See Nick's guide on this site:
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3653

What we need is information at the point of crash. We'd need to see a backtrace, and the code at the crashing line (by typing e.g. 'list').
#5
This is everything, I think. Used bt full and this is what it gave me.

GNU gdb Red Hat Linux (6.3.0.0-1.132.EL3rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

Core was generated by `../src/smaug 7600'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x006da2f8 in _int_free () from /lib/tls/libc.so.6
(gdb) bt full
bt full
#0  0x006da2f8 in _int_free () from /lib/tls/libc.so.6
No symbol table info available.
#1  0x006d9278 in free () from /lib/tls/libc.so.6
No symbol table info available.
#2  0x0811f27b in free_obj (obj=0xa0dcf10) at handler.c:3846
        paf = (AFFECT_DATA *) 0x0
        paf_next = (AFFECT_DATA *) 0xa0dc816
        ed = (EXTRA_DESCR_DATA *) 0x0
        ed_next = (EXTRA_DESCR_DATA *) 0x3fb
        RQueue = (REL_DATA *) 0x0
        rq_next = (REL_DATA *) 0x79dab8
        mpact = (MPROG_ACT_LIST *) 0x0
        mpact_next = (MPROG_ACT_LIST *) 0x0
#3  0x0811f2b8 in free_obj (obj=0xbfffaaf5) at handler.c:3847
        paf = (AFFECT_DATA *) 0xa0dcf10
        paf_next = (AFFECT_DATA *) 0x0
        ed = (EXTRA_DESCR_DATA *) 0x81a0c3f
        ed_next = (EXTRA_DESCR_DATA *) 0xbfffaab8
        RQueue = (REL_DATA *) 0xa0dc411
        rq_next = (REL_DATA *) 0xa0dcf10
        mpact = (MPROG_ACT_LIST *) 0x811f2b8
        mpact_next = (MPROG_ACT_LIST *) 0xbfffaa98
#4  0x081a0c7b in update_handler () at update.c:2023
        pulse_area = 96
        pulse_mobile = 12
        pulse_violence = 4
        pulse_point = 280
        pulse_second = 4
        sttime = {tv_sec = 168676432, tv_usec = 136484556}
        etime = {tv_sec = -1073762552, tv_usec = 135175440}
#5  0x080e9d5a in game_loop () at comm.c:946
        last_time = {tv_sec = 1174441352, tv_usec = 450129}
        cmdline = "quit\000i\000o\000éy\000àéy\000àéy\000úéy\000ÿÿÿéy\000ÿÿÿ, '\0' <repeats 20 times>, "Ыÿ", '\0' <repeats 16 times>, "\001\000\000\000°«ÿ#¼o\000j\017y\000ÿÿÿ217­ÿ", '\0' <repeats 12 times>, "j\017y", '\0' <repeats 13 times>, "(»o\000H6Õ\t(0Õ\tÌ%m\000\003\000\000\000àÀy\000\000\000\000\000Ù\001\000\000¸Úy\000àéy\000Ì\226\"\b´«ÿÝPk\000àéy\000àÁx\000Ä«ÿ¸Úy\000è«ÿý©o\000àéy\000àÁx\000Ïÿ\000$\000y\000\024"...
        d = (DESCRIPTOR_DATA *) 0x0
#6  0x080e8e2b in main (argc=2, argv=0xbfffafb4) at comm.c:550
        now_time = {tv_sec = 1174440831, tv_usec = 124163}
        fCopyOver = 0 '\0'
        imcsocket = -1
(gdb) 
Amended on Wed 21 Mar 2007 02:38 AM by Kisuke
USA #6
Like I said, you need to go to the line where it's crashing in your code, and show us what's around it (e.g. using 'list'). It would also help to describe precisely what you did, maybe showing us your additions if they're relatively short. The backtrace is only helpful if we see the code it's referring to.

Oh, and you should also use the [code] or [mono] tags to make the gdb output more readable.
#7

void do_zanpakutoh( CHAR_DATA * ch, char *argument )
{
   OBJ_DATA *obj, *tmpobj;
   OBJ_INDEX_DATA *pObjIndex;
   char arg1[MAX_INPUT_LENGTH];
   int iClassZ;
   
   argument = one_argument( argument, arg1 );
   
   iClassZ = atoi( arg1 );
   
   pObjIndex = get_obj_index( 4 );
   if( argument[0] == '\0' && ch->zname )
   {
       for( tmpobj = ch->first_carrying; tmpobj; tmpobj = tmpobj->next_content )
            if( tmpobj->pIndexData->vnum == 4 )
            {    
                unequip_char( ch, tmpobj );
                obj_from_char( tmpobj );
                extract_obj( tmpobj );
                ch_printf( ch, "&zYou release your Zanpakutoh...\n\r" );
                ch->current_reiatsu = ch->base_reiatsu;
	            xREMOVE_BIT( ch->act, PLR_POWERUP );
                return;
            }
            else if( tmpobj->pIndexData->vnum == 5 )
            {
                 unequip_char( ch, tmpobj );
                 obj_from_char( tmpobj );
                 extract_obj( tmpobj );
                 ch_printf( ch, "&zYou return your zanpakutoh to it's shikai state.\r\n&g&w" );
                 obj = create_object( pObjIndex, ch->level );
                 obj->name = str_dup( ch->zname );
                 obj->short_descr = str_dup( ch->zname );
                 obj = obj_to_char( obj, ch );
                 equip_char( ch, obj, WEAR_WIELD );
                 ch->current_reiatsu = ch->base_reiatsu * 7.5;
                 return;
            }
       obj = create_object( pObjIndex, ch->level );
       obj->name = str_dup( ch->zname);
       obj->short_descr = str_dup( ch->zname);
       obj = obj_to_char( obj, ch );
       equip_char( ch, obj, WEAR_WIELD );
       ch->current_reiatsu = ch->base_reiatsu * 7.5;
       xSET_BIT( ch->act, PLR_POWERUP );
       ch_printf( ch, "You call forth %s!\r\n", ch->zname );
       act( AT_ACTION, "$n calls forth $s zanpakutoh.\r\n", ch, NULL, NULL, TO_ROOM );
       return;
   }
   else if( ch->zname )
   {
      ch_printf( ch, "Type 'zanpakutoh' by itself to call forth your zanpakutoh\r\n" );
      return;
   }
   else if( iClassZ < 1 || iClassZ > 4 || !is_number( arg1 ) )
   {
      ch_printf( ch, "&WInvalid class choice.\r\n" );
      ch_printf( ch, "&WSyntax: zanpakutoh <class #> <name of zanpakutoh>\r\n\n" );
      ch_printf( ch, "&WClasses&z: &Oearth - 1&W,&B ice - 2&W, &Ylightning - 3&W, &RFire - 4\r\n" );
      ch_printf( ch, "&WBe sure to use the number of the class, not the name.\r\n" );
      return;
   }
   else
   {
      ch->Class = iClassZ;
      ch->zname = argument;
      obj = create_object( pObjIndex, ch->level );
      obj->name = str_dup( ch->zname );
      obj->short_descr = str_dup( ch->zname );
      obj = obj_to_char( obj, ch );
      ch_printf( ch, "You call forth %s for the first time!\r\n", ch->zname );
      act( AT_ACTION, "$n calls forth $s zanpakutoh.\r\n", ch, NULL, NULL, TO_ROOM );
      equip_char( ch, obj, WEAR_WIELD );
      ch->current_reiatsu = ch->base_reiatsu * 7.5;
      xSET_BIT( ch->act, PLR_POWERUP );
      return;
   }
}
Amended on Wed 21 Mar 2007 02:34 AM by Kisuke
#8

void do_bankai( CHAR_DATA * ch, char *argument )
{    
     OBJ_DATA *obj, *tmpobj;
     OBJ_INDEX_DATA *pObjIndex;
     
     char arg1[MAX_INPUT_LENGTH];
     
     argument = one_argument( argument, arg1 );  
     
     if( ch->bBankaiLearned && argument[0] == '\0' )
     {
         for( tmpobj = ch->first_carrying; tmpobj; tmpobj = tmpobj->next_content )
         {
            if( tmpobj->pIndexData->vnum == 5 )
            {
                 unequip_char( ch, tmpobj );
                 obj_from_char( tmpobj );
                 extract_obj( tmpobj );
                 ch_printf( ch, "&zYou suppress your bankai...\n\r" );
                 ch->current_reiatsu = ch->base_reiatsu;
                 xREMOVE_BIT( ch->act, PLR_POWERUP );
                 return;
            }
            else if( tmpobj->pIndexData->vnum == 4 )
            {
                 unequip_char( ch, tmpobj );
                 obj_from_char( tmpobj );
                 extract_obj( tmpobj );
                 xREMOVE_BIT( ch->act, PLR_POWERUP );
            }
         }
         pObjIndex = get_obj_index( 5 );
         obj = create_object( pObjIndex, ch->level );
         obj->name = str_dup( ch->bname );
         obj->short_descr = str_dup( ch->bname );
         obj = obj_to_char( obj, ch );
         ch_printf( ch, "You release %s!\r\n", ch->bname );
         act( AT_ACTION, "$n releases the awesome power of $s bankai!\r\n", ch, NULL, NULL, TO_ROOM );
         equip_char( ch, obj, WEAR_WIELD );
         ch->current_reiatsu = ch->base_reiatsu * 10;
         xSET_BIT( ch->act, PLR_POWERUP );
         return;
     }     
     else if( !ch->bBankaiLearned )
     {
          if( !ch->zname )
          {
              ch_printf( ch, "&RYou must have a zanpakutoh first...&g&w\r\n" );
              return;
          }
          if( !str_cmp( arg1, "str" ) )
          {
              ch->mod_str = 10;
          }
          else if( !str_cmp( arg1, "dex" ) )
          {
              ch->mod_dex = 10;
          }
          else if( !str_cmp( arg1, "int" ) )
          {
              ch->mod_int = 10;
          }
          else if( !str_cmp( arg1, "con" ) )
          {
              ch->mod_con = 10;
          }
          else if( !str_cmp( arg1, "lck" ) )
          {
              ch->mod_lck = 10;
          }
          else if( !str_cmp( arg1, "hit" ) )
          {
              ch->max_hit += 500;
          }
          else if( !str_cmp( arg1, "mana" ) )
          {
              ch->max_mana += 1000;
          }
          else if( !str_cmp( arg1, "hitroll" ) )
          {
              ch->hitroll += 8;
          }
          else if( !str_cmp( arg1, "damroll" ) )
          {
              ch->damroll += 8;
          }
          else
          {
              ch_printf( ch, "Please choose a valid upgrade choice.  Use the word contained in ' '.\r\n" );
              ch_printf( ch, "Syntax: bankai < upgrade choice > < bankai name >\r\n" );
              ch_printf( ch, "Example: bankai str Tenka Zangetsu\r\n\n" );      
              return;
          }
          if( argument[0] == '\0' )
          {
              ch_printf( ch, "You must name your bankai!\r\n" );
              return;
          }
          for( tmpobj = ch->first_carrying; tmpobj; tmpobj = tmpobj->next_content )
          {
            if( tmpobj->pIndexData->vnum == 4 )
            {
                 unequip_char( ch, tmpobj );
                 obj_from_char( tmpobj );
                 extract_obj( tmpobj );
            }
          }
          ch->bname = argument;
          ch->bBankaiLearned = 1;
          pObjIndex = get_obj_index( 5 );
          obj = create_object( pObjIndex, ch->level );
          obj->name = str_dup( ch->bname );
          obj->short_descr = str_dup( ch->bname );
          obj = obj_to_char( obj, ch );
          ch_printf( ch, "You call forth %s for the first time!\r\n", ch->bname );
          act( AT_ACTION, "$n releases the awesome power of $s bankai!\r\n", ch, NULL, NULL, TO_ROOM );
          equip_char( ch, obj, WEAR_WIELD );
          ch->current_reiatsu = ch->base_reiatsu * 10;
          xSET_BIT( ch->act, PLR_POWERUP );
          return;
     }
     else
     {
         ch_printf( ch, "Syntax: bankai < letter upgrade choice > < bankai name >\r\n\n" );      
         ch_printf( ch, "Upgrades:\r\n" );
         ch_printf( ch, "-------------------------------------\r\n" );
         ch_printf( ch, "'str' - +10 strength\r\n" );
         ch_printf( ch, "'int' - +10 intelligence\r\n" );
         ch_printf( ch, "'dex' - +10 dexterity\r\n" );
         ch_printf( ch, "'con' - +10 constitution\r\n" );
         ch_printf( ch, "'lck' - +10 luck\r\n" );
         ch_printf( ch, "'damroll' - +8 damroll\r\n" );
         ch_printf( ch, "'hitroll' - +8 hitroll\r\n" );
         ch_printf( ch, "'mana' - +1000 mana\r\n" );
         ch_printf( ch, "'hp' - +500 hp\r\n" );
         ch_printf( ch, "\n\n**Note: Type 'bankai' by itself to recall your bankai if you've already made it once\r\n" );
         return;
     }
}                
Amended on Wed 21 Mar 2007 02:36 AM by Kisuke
#9
The above two posts are the code for the skills I added. Sorry if I am being frustrating. I'm not a very experienced coder.
USA #10
(Please use the code tags to make the code easier to read.)
#11
I'm not sure what you mean. This is straight from the .c file. not gdb output
USA #12
Edit your forum post and enclose the pasted code in tags, e.g.

[code]
foo
...
bar
[/code]
#13
Done.
USA #14
Have you added any new vars to objects? Seems like they are not being properly freed, or were not properly coded in.
USA #15
These lines might also be problematic:
       obj->name = str_dup( ch->zname);
       obj->short_descr = str_dup( ch->zname);

The problem is that those are supposed to be hashed strings, so when free_obj comes along it'll be calling STRFREE -- but then it'll get really confused because you allocated them as normal strings using str_dup. You should use STRALLOC instead, or the more efficient QUICKLINK when you're just copying.)


(This is why I really hate the string hashing system, and wrote my own self-managing hashed strings instead. They're announced in the general programming section of this forum. They're in C++, though.)
#16
I didn't add anything to objects. I added bname and zname as pointers to strings( char *zname, *bname ) in the char_data structure. Maybe this will help though. I've found two more issues, they may be related. One: when I try to log after logging out with one of the weapons wielded, it crashes the game. two: when i create the bankai for the first time and initialize bname in a char file, it also changes zname. again, i'm not sure why.


at this point, i'm thinking of reloading a fresh copy of fuss smaug and adding my changes over again, that way i can redo the zanpakutoh/bankai code from scratch.
Amended on Wed 21 Mar 2007 12:52 PM by Kisuke
USA #17
That might be a good idea. If you do that, you should also keep a careful record of what you changed. One way to do that is to maintain a clean copy in parallel with your normal copy, and then, when you want to know what is different, you can just run the diff command.