Need help with a Snippet

Posted by Toy on Wed 04 Feb 2004 05:58 PM — 6 posts, 22,069 views.

#0

ch_ret spell_familiar( int sn, int level, CHAR_DATA *ch, void *vo )
{
    MOB_INDEX_DATA *pMobIndex;
    CHAR_DATA *mount;
	SKILLTYPE *skill = get_skilltype(sn);

   if ( ch->pcdata->pet != NULL )
   {
       send_to_char("You already have a companion.\n\r",ch);
	   failed_casting( skill, ch, NULL, NULL );
       return rSPELL_FAILED;
   }
   if(ch->position == POS_FIGHTING)
   {
      send_to_char("You can't study the ritual while in combat!\n\r",ch);
	  failed_casting( skill, ch, NULL, NULL );
      return rSPELL_FAILED;
   }
    
   if ( ( pMobIndex = get_mob_index(MOB_VNUM_FAMILIAR) ) == NULL )
   {
       send_to_char( "The familiar mob doesn't exist.\n\r", ch );
       return rSPELL_FAILED;
   }
    /* can't cast the spell in these sectors */
    if(ch->in_room->sector_type == SECT_INSIDE
    || ch->in_room->sector_type == SECT_WATER_SWIM 
    || ch->in_room->sector_type == SECT_WATER_NOSWIM
    || ch->in_room->sector_type == SECT_DUNNO
    || ch->in_room->sector_type == SECT_AIR )
    {
       send_to_char("There is not enough magical energy here.\n\r",ch);
	   failed_casting( skill, ch, NULL, NULL );
       return rSPELL_FAILED;
    }
     	
    mount = create_mobile( pMobIndex );
    
    mount->level = number_fuzzy((ch->level+ch->mod_cha) / 2); // charisma bonus added by G
    mount->mana = mount->max_mana = 0;
    mount->hit = mount->max_hit = number_fuzzy((ch->max_hit / 2)+ch->mod_cha);
    mount->armor = number_fuzzy(ch->armor - 10);
    mount->hitroll = number_fuzzy(ch->level / 30);
    mount->damroll = number_fuzzy(ch->level / 30);
    
    /* free up the old mob names */ 
    STRFREE(mount->description);
    STRFREE(mount->name);
    STRFREE(mount->short_descr);
    STRFREE(mount->long_descr);
    
    /* terrain */
    switch(ch->in_room->sector_type)
    {
	case(SECT_CITY): /* rat */
	case(SECT_FIELD):
	    mount->description = 
	        str_dup("You see a large furry rat.  Long whiskers hang down from it's nose.\n\r"
	                  "You can feel the dirt and disease crawling off this beast.\n\r");
	    mount->short_descr = str_dup("large rat");
	    mount->long_descr = str_dup("A large furry rodent is here.\n\r");
	    mount->name = str_dup("familiar rat");
		xSET_BIT(mount->attacks,DAM_PIERCE);
	    break;
	case(SECT_FOREST):  /* falcon */
	case(SECT_HILLS):
	    mount->description = 
	          str_dup("You see a large falcon.  Golden brown feathers frame powerful\n\r"
	                  "wings.  Long talons grasp at nothingness in vain attempts at\n\r"
	                  "getting some rabbit or rodent for dinner.\n\r");
	    mount->short_descr = str_dup("large falcon");
	    mount->long_descr = str_dup("A large falcon screams here.\n\r");
	    mount->name = str_dup("familiar falcon");
		xSET_BIT(mount->attacks,DAM_SLASH);
	    break;
	case(SECT_MOUNTAIN): /* mountain lion */
	    mount->description = 
	          str_dup("You see a very large mountain lion.  One wrong look and it could\n\r"
	                  "have your head lying at your feet.  You should think better than\n\r"
	                  "cross this beast especial if you have a weapon in your hand.\n\r");
	    mount->short_descr = str_dup("large mountain lion");
	    mount->long_descr = str_dup("A large mountain lion claws the ground here.\n\r");
	    mount->name = str_dup("familiar mountain lion");
		xSET_BIT(mount->attacks,DAM_PIERCE);
	    break;
	case(SECT_UNDERGROUND): /* carrion crawler */
	    mount->description = 
	          str_dup("You see a large carrion crawler slowly crawling along the wall.\n\r"
	                  "It's tough-looking hide makes it look a formidable foe. Perhaps\n\r"
	                  "the crawler's toughness will make up for it's intelligence.\n\r");
	    mount->short_descr = str_dup("crawler");
	    mount->long_descr = str_dup("A carrion crawler wriggles along the wall here.\n\r");
	    mount->name = str_dup("familiar crawler");
		xSET_BIT(mount->attacks,DAM_CRUSH);
	    break;
     
	case(SECT_UNDERWATER): /* grey shark */
      case(SECT_OCEANFLOOR):
	    mount->description = 
	          str_dup("You see a very large grey shark.  A merciless killer, this shark\n\r"
	                  "could easily swallow you in one swift bite.  It's rows of teeth\n\r"
	                  "send a chill through you.\n\r");
	    mount->short_descr = str_dup("large grey shark");
	    mount->long_descr = str_dup("A large shark swims dangeroulsy close by here.\n\r");
	    mount->name = str_dup("familiar shark");
		xSET_BIT(mount->attacks,DAM_PIERCE);
	    break;
	case(SECT_DESERT): /* sandworm */
	    mount->description = 
	          str_dup("You see a large white sandworm wiggling in the light.\n\r"
	                  "A red spot on one end makes you guess it is a mouth.\n\r"
	                  "A loud moan comes from the direction of that red spot.\n\r");
	    mount->short_descr = str_dup("sandworm");
	    mount->long_descr = str_dup("A white sandworm wiggles on the ground here.\n\r");
	    mount->name = str_dup("familiar sandworm");
		xSET_BIT(mount->attacks,DAM_CRUSH);
	    break;
    }
    /* player seen stuff here */
    do_sit(ch,"");
    char_to_room( mount, ch->in_room );
    act( AT_MAGIC,"You begin to chant and call to a $N!.",ch,NULL,mount,TO_CHAR);
    act( AT_MAGIC,"$n begins to chant and calls to a $N!", ch, NULL, mount, TO_ROOM );
    WAIT_STATE(ch, 2 * PULSE_MOBILE);
    add_follower( mount, ch );
    mount->leader = ch;
    ch->pcdata->pet = mount;
    do_stand(ch,"");

    xSET_BIT(mount->act, ACT_PET);
    xSET_BIT(mount->affected_by, AFF_CHARM);
    ch->move -= (mount->level / 2);  /* physically draining lose of move */
    return rNONE;
}


Having problems with this snippet

Edited by Nick to enable "forum codes" and to "quote" backslashes and square brackets.
Amended on Wed 04 Feb 2004 08:51 PM by Nick Gammon
#1
Here's the problem: whenever a player kills their familiar, it'll drop the mud core. Now, mobs can kill the familiars just fine, but if I switch into a mob and kill the familiar I created.. poof goes the core. Any thoughts?

-Toy
#2
Even more problems now: I loaded a character named Test, gave him the proper skills and level and had him cast the spell. With my Immortal character I killed the rat off, and it was fine. I quit with Test, and another Immortal tried to log in and the mud crashed. I was curious, so I tried this: Did everything the same as before, yet I kept the player Test on. the Imm logged in and everything was fine... I'm all boggled.

-Toy
Canada #3
I see the problem you are having when it is killed. The issue here seems to be mismatched STRALLOC and str_dup. You have used STRALLOC to free the info(like it should be), but you are using str_dup to reassign it. When the familiar gets killed, it will call free_char, which uses STRFREE, and trying to STRFREE a str_dup line can cause memory leaks. Try changing all the str_dup's to STALLOCs. That should help, if not clear up the problem entirely.
Amended on Wed 04 Feb 2004 07:08 PM by Greven
#4
Thanks. Everything works the way it's supposed to now. Changed the str_dups to STRALLOCs and got it working once I realized that the last line of your post had a typo in it. Kept trying to use STALLOC. ;p

But I do have a question now about memory leaks. Is there any way you can check your mud to see if there are leaks? IE is there any commands in Cygwin that'd show you possible memory leaks?

-Toy
Canada #5
I only wish there was something that said: "This is whats wrong". However, there are some options: The one I recommend is valgrind. You use it in a similiar fashion as you would gdb to boot your game, and from there you run the mud. As you progress, should it find any leaks, it will report them to you. This only works in certain circumstances, as it cannot find all problems. Another method with a specific command is the "memory hash" command. This only works for things that use STRALLOC, but it can be useful to make sure that appropriate commands are clearing the memory. I'll give you an example. Player data is one of the biggest problems I used to have.

To test the data is being assigned through STRALLOC and cleared properly, I would check "memory hash" first. This is what was shown.
Quote:
Affects 266 Areas 43
ExtDes 287 Exits 12189
Helps 817 Resets 2896
IdxMobs 712 Mobs 1716
IdxObjs 1089 Objs 1874 (1859)
Rooms 7459 VRooms 0
Shops 94 RepShps 4
CurOq's 0 CurCq's 0
MaxEver time recorded at: Tue Aug 5 20:00:58 2003
Hash statistics:
Hash strings allocated: 13416 Total links : 77516
String bytes allocated: 1473976 Bytes saved : 1020111
Unique (wasted) links : 9449 Hi-Link count: 39012

Then, I would use loadup on a character, and force the quit, like this:
Quote:

[||||||||||]
loadup erflink
Log: Greven: loadup erflink
Comm: Loading player data for: Erflink (9K)
Player Erflink loaded from room 100.
Done.

[||||||||||]
force erflink quit
Erflink has left the game.
[INFO] Erflink has left Dark Warriors
Comm: Erflink has quit.
Ok.
Then, I check the "memory hash again".
Quote:
Affects 266 Areas 43
ExtDes 287 Exits 12189
Helps 817 Resets 2896
IdxMobs 712 Mobs 1716
IdxObjs 1089 Objs 1874 (1859)
Rooms 7459 VRooms 0
Shops 94 RepShps 4
CurOq's 0 CurCq's 0
MaxEver time recorded at: Tue Aug 5 20:00:58 2003
Hash statistics:
Hash strings allocated: 13416 Total links : 77516
String bytes allocated: 1473977 Bytes saved : 1020124
Unique (wasted) links : 9449 Hi-Link count: 39012


Now, you can see that the numbers are different. This is a BAD thing. It means that things are being read in, and not cleared. So, I go look in free_char, and make sure that everything is being cleared properly( at the time, I had added some fields and not freed them, before I knew this had to be done). I compile, copyover, and try again. This time, the numbers match, and that means that there is no problem with that one.

I hope this helps as a simple(though not very helpful) method to test for memory leaks. If your going to use the valgind method, I can help with some links that would give some help, though valgrind ( and most memory programs, from what I understand) will not work with cygwin, you'd need *nix access.

P.S. Sorry about the typo, heh.