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 ➜ Necromancer's Raise Dead

Necromancer's Raise Dead

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


Posted by Celestine   (29 posts)  Bio
Date Wed 25 Jun 2003 08:49 PM (UTC)
Message
I decided to add a necromancer class, and I realized that the entire point of being a necromancer would be to raise a dead corpse. Glancing over the spell creation data, I discovered that spells only affect certain properties of some character/object or another. To raise the corpse, I would need to make it a command. Knowing that, I decided to go ahead and make a raise dead function which looks like the code below. I have successfully added all the necessary amendments to make it a command. However, executing this command from within the game crashes the server.

Basically I have two questions. First, is it possile to make this a spell? Second, what exactly is wrong with the spell right now (example, I typed in raise crawler to raise a carrion crawler)? The code is as follows:

void do_raise_dead( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *corpse;
OBJ_DATA *obj;
MOB_INDEX_DATA *pMobIndex;
CHAR_DATA *victim;
sh_int vnum;
char arg2[MAX_INPUT_LENGTH];
char temp[MAX_INPUT_LENGTH];
char target[MAX_INPUT_LENGTH];
char cname[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
char *ptr;
int hash, cnt, count;
ptr = cname;

if ( ch->class != 13 )
{
send_to_char( "You are not a necromancer!" , ch );
return;
}
if ( argument[0] == '\0' )
{
send_to_char( "Which corpse do you want to raise?" , ch );
return;
}
if ( ( obj = get_obj_here( ch, argument ) ) == NULL )
{
send_to_char( "You do not see that here.\n\r", ch );
return;
}

corpse = get_obj_here( ch , argument );
strcpy(cname,corpse->name);
ptr = one_argument( ptr , temp);
ptr = one_argument( ptr , target);

//from the minvoke code in act_wiz.c
count = number_argument( corpse->name, arg2 );
for ( hash = cnt = 0; hash < MAX_KEY_HASH; hash++ )
for ( pMobIndex = mob_index_hash[hash];
pMobIndex;
pMobIndex = pMobIndex->next )
if ( nifty_is_name( arg2, pMobIndex->player_name )
&& ++cnt == count )
{
vnum = pMobIndex->vnum;
break;
}
victim = create_mobile( pMobIndex );
//players can't raise corpses of other players after pkill
if (!IS_NPC(victim))
{
send_to_char( "You cannot raise that corpse." , ch );
do_purge(ch,victim->name);
return;
}

//renames newly raised creature and basically makes it a pet.
sprintf( buf, "%sA neck tag says 'I belong to %s'.\n\r", victim->description, ch->name );
STRFREE( victim->description );
victim->description = STRALLOC( buf );

char_to_room( victim, ch->in_room );
add_follower( victim, ch );
ch_printf( ch , "The corpse of %s, which you have just risen, now follows you.\n\r", victim->name );
return;
}

Top

Posted by Meerclar   USA  (733 posts)  Bio
Date Reply #1 on Wed 25 Jun 2003 10:25 PM (UTC)
Message
Actually, the usual method is to make this a spell rather than a command for various reasons. I have a raise dead spell you'd probably be able to port with minor alterations :) I'll have to find it so it may be a few hours.

Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
Top

Posted by Meerclar   USA  (733 posts)  Bio
Date Reply #2 on Wed 25 Jun 2003 10:43 PM (UTC)
Message
Ok, I found it but its really too long to post here so email me and I'll send it to ya :)


Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
Top

Posted by Celestine   (29 posts)  Bio
Date Reply #3 on Fri 27 Jun 2003 10:21 PM (UTC)
Message
I put in the code, following the directions, but I was unable to find where to put the below code in. const.c didn't have a skill_table, and I grepped but found nothing. When compiling without it, I get a conflicting types error (magic.c, 6375) and a previously defined error (mud.h, 4270). The conflicting types is just a function declaration, and the mud.h error is a declare_spell_fun line. The skill_table requirement is displayed below. Does anyone know where this should go? I'm using basically the stock smaug.

In const.c, in the skill_table:

{
"resurrect", { 53, 53, 53, 53 }, { 1, 1, 2, 2},
spell_resurrect, TAR_IGNORE, POS_STANDING,
NULL, SLOT(xxx), 100, 15,
"", "!Resurrect!", "",
},

Of course, you will want to lower the levels and change SLOT(xxx) to a
free spell slot.
Top

Posted by Meerclar   USA  (733 posts)  Bio
Date Reply #4 on Sat 28 Jun 2003 06:35 AM (UTC)
Message
Sounds like theres already an animate dead spell in the standard SMAUG dist. Wouldn't really surprise me if there was actually, there are usually at least a few unused spells in any codebase for various reasons. Nick or another coder with SMAUG source would need to confirm this since I don't work with SMAUG.

Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #5 on Sat 28 Jun 2003 07:46 AM (UTC)
Message
I don't know if your code still crashes, but I did find a problem with it that would cause a crash. In the lines:

victim = create_mobile( pMobIndex );
//players can't raise corpses of other players after pkill
if (!IS_NPC(victim))
{
send_to_char( "You cannot raise that corpse." , ch );
do_purge(ch,victim->name);
return;
}

You assume that create_mobile actually returns a valid mobile, because pMobIndex actually contains something valid. However, if the search routine above finds nothing, the last state of pMobIndex will be null (and the inner forloop will break, causing the outer forloop to start again until it breaks...) So, if the game can't find the mobile prototype pMobIndex, it will return null and set victim to null. And then, if you try to check IS_NPC, THAT will crash the MUD, since you'll be deferencing a null pointer.

Generally, it's always a good idea to check if a pointer is null before using it, unless you can be 100% certain that it is not null. For instance, you checked if argument[0] == '\0', but you might also want to check if argument == NULL (unless the interpret function always gives an argument pointer - even if it's empty. I'm not sure about that.)

As for the skill_table, I don't really know about that. My code base is derived from SMAUG 1.0 - and that was a long time ago, and SMAUG has evolved a lot since then. It wouldn't surprise me if this part has changed... but in any case back then when you added a skill, you added entries to tables.c (or table.c...), which should be fairly self-explanatory once you open the file, and then you add a DECLARE_SPELL_FUN declaration to mud.h (why everything is in one giant header file is a little beyond me, but anyways), and then all the other parameters are set in-game. Like I said this information might be totally out of date now, since it comes from 1.0 and you're probably on 1.4, but it's worth a try.

Whether or not you make it a do_ command or a spell_ command won't really change a whole lot in the net effect, but it will change how the player accesses it and some of the surrounding behavior. For example, a do command is entered directly, but a spell command needs to be cast. Also, do_cast is a wrapper function for all spells, and handles nifty things like spell failure messages, and whatnot.


I hope that something in all that is useful to you :)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.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.


17,786 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.