Where in the source code is the stuff for sacrificing corpses? I.E. messages like "Your deity appreciates your offer and may accept it later." and "Thoric gives you one gold coin for your sacrifice." Obviously, I want to change it from 'Thoric' to 'Kris'. I searched the entire src directory, but couldn't find any specific references to sacrificing.
Source Code
Posted by Kris on Tue 13 Mar 2001 04:45 PM — 74 posts, 206,906 views.
Here is how to find such things. Use grep, which searches files, like this:
This shows that the relevant code is in act_obj.c.
If you edit that file, at around line 2220 you will see:
You can see where the word Thoric comes from - just change that and recompile.
That code was in a function "do_sacrifice". If you had done a grep on "sacrifice" you would have found that too.
$ grep 'your sacrifice' *.c
act_obj.c: sprintf( buf, "%s gives you one gold coin for your sacrifice.\n\r"
, name );
This shows that the relevant code is in act_obj.c.
If you edit that file, at around line 2220 you will see:
strcpy( name, "Thoric" );
}
ch->gold += 1;
if ( obj->item_type == ITEM_CORPSE_NPC
|| obj->item_type == ITEM_CORPSE_PC )
adjust_favor( ch, 5, 1 );
sprintf( buf, "%s gives you one gold coin for your sacrifice.\n\r", name );
You can see where the word Thoric comes from - just change that and recompile.
That code was in a function "do_sacrifice". If you had done a grep on "sacrifice" you would have found that too.
Ya know how when you're invissed, you show up as "Someone" from another person's perspective? I want to change "Someone" to "A shadow". However, virtually every source file has the word "Someone" in it, and, in many cases, it's all over the place! I thought I had it, but when I compiled and ran it, it still showed up as someone. What source file should I edit for this, and, if possible, could you tell me what line of code it is as well? Thanks :)
Search for "someone" (in quotes). I found only 25 of these, which you probably need to change all of them, otherwise it will change in some spots but not others.
If you are using Cygwin, you can use "grep" to do this. Put the "someone" into single quotes (ie. double quotes inside single quotes, like in the example):
There are only about 4 different files here, just use your editor to do a "change all" once you have edited each one.
The "-i" says "case insensitive".
Also there are 23 in the list below, another 2 are in the file mud.h.
If you are using Cygwin, you can use "grep" to do this. Put the "someone" into single quotes (ie. double quotes inside single quotes, like in the example):
There are only about 4 different files here, just use your editor to do a "change all" once you have edited each one.
The "-i" says "case insensitive".
Also there are 23 in the list below, another 2 are in the file mud.h.
$ grep '"someone"' *.c -i
imc-mercbase.c: : (chdata->wizi ? "A Mystical Being" : "someone");
imc-mercbase.c: return imc_visible(imc_getdata(ch),vict) ? imc_nameof(name) :
"someone";
imc-mercbase.c: (imc_getdata(ch))->wizi ? "A Mystical Being" : "someone",
mud);
magic.c: strcpy( buf, "Someone" );
misc.c: const char *iroom = "Someone";
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: strcpy( t, "someone" );
mud_prog.c: : strcpy( t, "someone" );
mud_prog.c: : strcpy( t, "someone" );
mud_prog.c: : strcpy( t, "someone" );
mud_prog.c: : strcpy( t, "someone" );
mud_prog.c: : strcpy( t, "someone" );
mud_prog.c: : strcpy( t, "someone" );
Ok, I just did that, and changed every reference of "someone" to "a shadow" and recompiled. I then did the grep command again, and it returned nothing, which confirms that I got it all. However, it still shows up as "Someone" instead of "A shadow"! I.e. "Someone says 'test'", "Someone waves" instead of "A shadow says 'test'", "A shadow waves". I then tried broadening the grep search, thinking that perhaps the 'someone' isn't alone in the quotes. So I removed the double quotes, i.e. typing:
grep 'someone' *.c -i > grep.txt
This is the list I recieved:
act_comm.c: send_to_char( "You cannot disband a group if you're following someone.\n\r", ch );
act_comm.c: send_to_char( "But you are following someone else!\n\r", ch );
act_info.c:/* Had to add unknowns because someone added new positions and didn't
act_info.c: strcat( buf, "someone who left??" );
act_info.c: strcat( buf, "someone who left??" );
act_info.c: * spamming someone and then logging off quickly to evade
act_info.c: /* Prevent someone from ignoring themself... */
act_obj.c: send_to_char( "That's someone else's corpse.\n\r", ch );
act_obj.c: send_to_char( "Someone tells you, 'No littering here!'\n\r", ch );
act_wiz.c: /* Oops someone forgot to clear up the memory --Shaddai */
act_wiz.c: write_to_descriptor( victim->desc->descriptor, "\n\rYou feel like someone is watching your every move...\n\r", 0 );
act_wiz.c: /*You can demote yourself but not someone else at your own trust.-- Narn*/
act_wiz.c: send_to_char( "Try taking it out on someone else first.\n\r", ch );
act_wiz.c: /* p_next = p->next; */ /* In case someone DOES try to AT MOBS SLAY # */
act_wiz.c: /* Just a security precaution so you don't rename someone you don't mean
clans.c: send_to_char("You cannot shove someone into a death trap.\n\r", ch);
clans.c: send_to_char("You cannot drag someone into a death trap.\n\r", ch);
clans.c: send_to_char("You cannot do that to someone who is standing.\n\r", ch);
comm.c: sprintf( buf, "\n\rMake sure to use a password that won't be easily guessed by someone else."
comm.c:/* if ( is_name( name, "all auto immortal self someone god demigod dog guard cat ass fuck shit piss crap quit" ) )
comments.c: /* Put in to prevent crashing when someone issues a comment command
fight.c: * See if we got a pointer to someone who recently died...
fight.c: * want to show why you can't kill someone you can't turn it off. This is
fight.c: msg = "You hear someone's death cry.";
grub.c: * this function. F.Y.I - if an object is not "carried_by" someone,
grub.c: * in a container carried by someone - or in a container on the ground.
ice.c:/* see if someone can talk on a channel - lots of string stuff here! */
ice.c: /* Private channel - can only hear if someone with the right mud name is
imc-config.c:/* find ignore data on someone */
imc-mercbase.c: sprintf(buf, "someone@%s", mud);
imc-mercbase.c: /* just check for deny, since you can rtell someone < IMC_LEVEL_RTELL */
interp.c: sprintf ( cmd_flag_buf, "You can't %s while you are possessing someone!\n\r",
magic.c: ? victim->desc->original->name : "someone else");
magic.c: ? victim->name : "someone else");
magic.c: sprintf( buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name );
misc.c: send_to_char( "That's someone else's corpse.\n\r", ch );
misc.c: act( AT_ACTION, "Someone raps loudly from the other side of the $d.",
misc.c: send_to_char( "Someone tells you, 'No littering here!'\n\r", ch );
mud_comm.c: act( AT_TELL, "$n tells you, 'Sorry... you must seek someone more powerful than I.'",
mud_comm.c:/* hey... if an immortal's following someone, they should go with a mortal
mud_comm.c:/* lets the mobile force someone to do something. must be mortal level
polymorph.c: send_to_char ("Someone deleted your morph!\n\r", ch);
services.c:// someone calls ControlService in reference to our service.
skills.c: * if someone gouged you in the eye.
skills.c: send_to_char( "You can't backstab someone who is in combat.\n\r", ch );
skills.c: /* can't properly target someone heavily in battle */
special.c:/* if a spell casting mob is hating someone... try and summon them */
update.c: sprintf( buf, "Someone save me from %s!", rch->name );
update.c: act( AT_ACTION, "Someone should fetch a healer for $n.", ch, NULL, NULL, TO_ROOM );
update.c: case 9: t = "You hear someone call your name in the distance...\n\r"; break;
None of this appears to be even -remotely- relevant. Many are just part of comments. Also, I noticed that imc-mercbase.c doesn't generate an object file, and thus doesn't compile with everything else. Normally I have to delete its object file, otherwise cygwin doesn't know that the .c file has been updated. That would only be relevant here if the coding I needed to change was contained in imc-mercbase.c. Any other ideas perhaps? This is kinda amusing, but I want to get Someone outa hiding so I can make him A shadow :P =)
Thanks for your help in the chase.
grep 'someone' *.c -i > grep.txt
This is the list I recieved:
act_comm.c: send_to_char( "You cannot disband a group if you're following someone.\n\r", ch );
act_comm.c: send_to_char( "But you are following someone else!\n\r", ch );
act_info.c:/* Had to add unknowns because someone added new positions and didn't
act_info.c: strcat( buf, "someone who left??" );
act_info.c: strcat( buf, "someone who left??" );
act_info.c: * spamming someone and then logging off quickly to evade
act_info.c: /* Prevent someone from ignoring themself... */
act_obj.c: send_to_char( "That's someone else's corpse.\n\r", ch );
act_obj.c: send_to_char( "Someone tells you, 'No littering here!'\n\r", ch );
act_wiz.c: /* Oops someone forgot to clear up the memory --Shaddai */
act_wiz.c: write_to_descriptor( victim->desc->descriptor, "\n\rYou feel like someone is watching your every move...\n\r", 0 );
act_wiz.c: /*You can demote yourself but not someone else at your own trust.-- Narn*/
act_wiz.c: send_to_char( "Try taking it out on someone else first.\n\r", ch );
act_wiz.c: /* p_next = p->next; */ /* In case someone DOES try to AT MOBS SLAY # */
act_wiz.c: /* Just a security precaution so you don't rename someone you don't mean
clans.c: send_to_char("You cannot shove someone into a death trap.\n\r", ch);
clans.c: send_to_char("You cannot drag someone into a death trap.\n\r", ch);
clans.c: send_to_char("You cannot do that to someone who is standing.\n\r", ch);
comm.c: sprintf( buf, "\n\rMake sure to use a password that won't be easily guessed by someone else."
comm.c:/* if ( is_name( name, "all auto immortal self someone god demigod dog guard cat ass fuck shit piss crap quit" ) )
comments.c: /* Put in to prevent crashing when someone issues a comment command
fight.c: * See if we got a pointer to someone who recently died...
fight.c: * want to show why you can't kill someone you can't turn it off. This is
fight.c: msg = "You hear someone's death cry.";
grub.c: * this function. F.Y.I - if an object is not "carried_by" someone,
grub.c: * in a container carried by someone - or in a container on the ground.
ice.c:/* see if someone can talk on a channel - lots of string stuff here! */
ice.c: /* Private channel - can only hear if someone with the right mud name is
imc-config.c:/* find ignore data on someone */
imc-mercbase.c: sprintf(buf, "someone@%s", mud);
imc-mercbase.c: /* just check for deny, since you can rtell someone < IMC_LEVEL_RTELL */
interp.c: sprintf ( cmd_flag_buf, "You can't %s while you are possessing someone!\n\r",
magic.c: ? victim->desc->original->name : "someone else");
magic.c: ? victim->name : "someone else");
magic.c: sprintf( buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name );
misc.c: send_to_char( "That's someone else's corpse.\n\r", ch );
misc.c: act( AT_ACTION, "Someone raps loudly from the other side of the $d.",
misc.c: send_to_char( "Someone tells you, 'No littering here!'\n\r", ch );
mud_comm.c: act( AT_TELL, "$n tells you, 'Sorry... you must seek someone more powerful than I.'",
mud_comm.c:/* hey... if an immortal's following someone, they should go with a mortal
mud_comm.c:/* lets the mobile force someone to do something. must be mortal level
polymorph.c: send_to_char ("Someone deleted your morph!\n\r", ch);
services.c:// someone calls ControlService in reference to our service.
skills.c: * if someone gouged you in the eye.
skills.c: send_to_char( "You can't backstab someone who is in combat.\n\r", ch );
skills.c: /* can't properly target someone heavily in battle */
special.c:/* if a spell casting mob is hating someone... try and summon them */
update.c: sprintf( buf, "Someone save me from %s!", rch->name );
update.c: act( AT_ACTION, "Someone should fetch a healer for $n.", ch, NULL, NULL, TO_ROOM );
update.c: case 9: t = "You hear someone call your name in the distance...\n\r"; break;
None of this appears to be even -remotely- relevant. Many are just part of comments. Also, I noticed that imc-mercbase.c doesn't generate an object file, and thus doesn't compile with everything else. Normally I have to delete its object file, otherwise cygwin doesn't know that the .c file has been updated. That would only be relevant here if the coding I needed to change was contained in imc-mercbase.c. Any other ideas perhaps? This is kinda amusing, but I want to get Someone outa hiding so I can make him A shadow :P =)
Thanks for your help in the chase.
Did you do mud.h as well? That won't be found by grep of *.c.
I did the following, and it worked:
* changed the two references there
* did: rm *.o
* did: make
This is the code I changed:
You need to remove the .o files because it won't notice the change to mud.h otherwise.
Then I tested by logging in and doing a wave - see log below.
The other places should probably be changed also, but obviously the one in mud.h was important.
I did the following, and it worked:
* changed the two references there
* did: rm *.o
* did: make
This is the code I changed:
/*
* Description macros.
*/
#define PERS(ch, looker) ( can_see( (looker), (ch) ) ? \
( IS_NPC(ch) ? (ch)->short_descr \
: (ch)->name ) : "someone" )
#define MORPHPERS(ch, looker) ( can_see( (looker), (ch) ) ? \
(ch)->morph->morph->short_desc \
: "someone" )
You need to remove the .o files because it won't notice the change to mud.h otherwise.
Then I tested by logging in and doing a wave - see log below.
The other places should probably be changed also, but obviously the one in mud.h was important.
... Please leave north to experience the Darkhaven Academy.
... You may now "save" to make your character permanent.
<Type HELP START>
A shadow waves happily.
<Type HELP START><Type HELP START>
I want to make it so that everyone connected to the mud can see when a player quits and enters the mud. With a little guessing, I did added the following line in act_comm.c after the line act( AT_SAY, "A strange voice says, 'We await your return, $n...'", ch, NULL, NULL, TO_CHAR );
--------------------------------------------------------
echo_to_all( AT_IMMORT, "$n has left Aethia.", ECHOTAR_ALL);
The result is that it ends up showing to everyone who's connected as "$n as left Aethia." --literally (i.e. it shows $n instead of the player's name). How do I fix that?
--------------------------------------------------------
echo_to_all( AT_IMMORT, "$n has left Aethia.", ECHOTAR_ALL);
The result is that it ends up showing to everyone who's connected as "$n as left Aethia." --literally (i.e. it shows $n instead of the player's name). How do I fix that?
Do something like the following excerpt from act_wiz.c.
You need to construct a string with the player name in it, and then echo that string.
You need to construct a string with the player name in it, and then echo that string.
char buf[MAX_STRING_LENGTH];
sprintf( buf, "Balzhur screams, 'You are MINE %s!!!'", victim->name );
echo_to_all( AT_IMMORT, buf, ECHOTAR_ALL );
You know how when you're posting on a board, it cuts you off and returns (long line trimmed) after typing more than 79 characters? My admins have been screaming at me to fix this, as it is extremely annoying, especially when trying to post via telnet. I found the code responsible in build.c:
if ( strlen(argument) > 79 )
{
strncpy( buf, argument, 79 );
buf[79] = 0;
send_to_char( "(Long line trimmed)\n\r> ", ch );
}
I then tried changing the '79' to '160', just as a test. Like so:
if ( strlen(argument) > 160 )
{
strncpy( buf, argument, 160 );
buf[160] = 0;
send_to_char( "(Long line trimmed)\n\r> ", ch );
}
It would work just fine, and wouldn't trim the line until after it went over 160 chars. However, when I try to save the post, the server locks up and I have to manually shut it down. I just spent about 2 hours sifting through the source code, tinkering here and there, but every time I try to increase the limit, it crashes. What should I change? (Ideally, we'd like to have no limit on the number of chars in a line, or just a really high limit so we wouldn't have to walk on ice and hit 'enter' all the time to avoid being cut-off).
if ( strlen(argument) > 79 )
{
strncpy( buf, argument, 79 );
buf[79] = 0;
send_to_char( "(Long line trimmed)\n\r> ", ch );
}
I then tried changing the '79' to '160', just as a test. Like so:
if ( strlen(argument) > 160 )
{
strncpy( buf, argument, 160 );
buf[160] = 0;
send_to_char( "(Long line trimmed)\n\r> ", ch );
}
It would work just fine, and wouldn't trim the line until after it went over 160 chars. However, when I try to save the post, the server locks up and I have to manually shut it down. I just spent about 2 hours sifting through the source code, tinkering here and there, but every time I try to increase the limit, it crashes. What should I change? (Ideally, we'd like to have no limit on the number of chars in a line, or just a really high limit so we wouldn't have to walk on ice and hit 'enter' all the time to avoid being cut-off).
Oh and I couldn't get the code you mentioned earlier to work. It said that victim was undefined, so I looked at how it was defined in act_wiz.c, and mimicked it:
void do_quit( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
At the beginning of the file is where I put the declaration for buf. The rest of the code I inserted as follows:
act( AT_SAY, "A strange voice says, 'We await your return, $n...'", ch, NULL, NULL, TO_CHAR );
sprintf( buf, "<FYI> %s has left Aethia.", victim->name );
echo_to_all( AT_IMMORT, buf, ECHOTAR_ALL );
act( AT_BYE, "$n has left the game.", ch, NULL, NULL, TO_CANSEE );
Now, whenever I quit, the hard drive makes a brief, ugly buzzing noise and all my chars get disconnected from the server. What did I do wrong? (sorry bout not posting this sooner; I haven't been on recently)
void do_quit( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
At the beginning of the file is where I put the declaration for buf. The rest of the code I inserted as follows:
act( AT_SAY, "A strange voice says, 'We await your return, $n...'", ch, NULL, NULL, TO_CHAR );
sprintf( buf, "<FYI> %s has left Aethia.", victim->name );
echo_to_all( AT_IMMORT, buf, ECHOTAR_ALL );
act( AT_BYE, "$n has left the game.", ch, NULL, NULL, TO_CANSEE );
Now, whenever I quit, the hard drive makes a brief, ugly buzzing noise and all my chars get disconnected from the server. What did I do wrong? (sorry bout not posting this sooner; I haven't been on recently)
First, the board problem. They put the test for 79 characters there for a reason, and the reason can be found in mud.h:
As you can see the "line" allows for 49 lines of 80 characters (plus 1 for the null at the end). Thus, if you want 160 character lines I would make the "81" into "161" or maybe "162".
They probably did it that way because SMAUG normally has a maximum of 79 character lines (so they don't wrap in an ugly way on an 80-character screen).
What is wrong with just using the 49 lines to put in a lengthy message rather than trying to make the lines really long?
struct editor_data
{
sh_int numlines;
sh_int on_line;
sh_int size;
char line[49][81];
};
As you can see the "line" allows for 49 lines of 80 characters (plus 1 for the null at the end). Thus, if you want 160 character lines I would make the "81" into "161" or maybe "162".
They probably did it that way because SMAUG normally has a maximum of 79 character lines (so they don't wrap in an ugly way on an 80-character screen).
What is wrong with just using the 49 lines to put in a lengthy message rather than trying to make the lines really long?
As for the crash with the victim name, you can't get away with just adding an uninitialised variable like that. You got rid of the compile error but swapped it for a runtime error.
The example I gave was from somewhere that "victim" was a valid pointer to a victim's character.
In the context you are doing it, you just want the character itself, eg. change this line:
In this function "ch" is defined, as it is passed down to the function, and that is the name of the person you want to broadcast anyway.
The example I gave was from somewhere that "victim" was a valid pointer to a victim's character.
In the context you are doing it, you just want the character itself, eg. change this line:
sprintf( buf, "<FYI> %s has left Aethia.", ch->name );
In this function "ch" is defined, as it is passed down to the function, and that is the name of the person you want to broadcast anyway.
The <FYI> thing works beautifully now =)... however, the problem with the (long line trimmed) thing was unaffected by the changes I made to mud.h. The thing is, we're used to muds that line-wrap as you type, so you don't have to hit enter all the time. Everyone's complaining to me about it, and I can't say I blame them really. Is there anything else I should try?
I attempted to change the 'whois' information today. Basically, I just made it more like a table type format, and more condusive to some planned additions later on (i.e. kingdom, guild, and email listing). I don't get any compile errors on it. However, when I attempt to use the whois command on the mud, the hard drive buzzes briefly and disconnects everyone from the server, giving no error messages whatsoever.
In act_info.c, after the line:
set_pager_color( AT_GREY, ch );
I put the old code in comment tags, and inserted the new code:
Sorry bout the length of this, but I don't even know what the error is, let alone what's causing it. Thanks for your help on this =)
In act_info.c, after the line:
set_pager_color( AT_GREY, ch );
I put the old code in comment tags, and inserted the new code:
pager_printf(ch, "\n\n\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-WHOIS %s-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n", victim->name);
pager_printf(ch, "| Name: | %s *************************************** | Gender: | %s \n",
victim->name,
victim->sex == SEX_MALE ? "Male" :
victim->sex == SEX_FEMALE ? "Female" : "Neutral"
);
pager_printf(ch, "| Level: | %s ******************************************** | Race: | %s \n",
victim->level,
capitalize(race_table[victim->race]->race_name)
);
pager_printf(ch, "| Class: | %s *************************************** | Age: | %s \n",
class_table[victim->class]->who_name,
get_age(victim)
);
pager_printf(ch, "| Kingdom: | None *************************************** | Guild: | None \n");
pager_printf(ch, "----------------------------------------------------------------------------------\n");
if(victim->pcdata->homepage && victim->pcdata->homepage[0] != '\0')
pager_printf(ch, "| Webpage: | %s\n",
show_tilde( victim->pcdata->homepage ) );
else
pager_printf(ch, "| Webpage: | Unlisted\n");
pager_printf(ch, "| Email: | Unlisted\n");
pager_printf(ch, "--------------------------------------AUTOBIOGRAPHY-------------------------------\n");
if(victim->pcdata->bio && victim->pcdata->bio[0] != '\0')
pager_printf(ch, "\n%s\n\n",
victim->pcdata->bio);
else
pager_printf(ch, "\nNo biographical information available for %s at this time.\n\n",
victim->name );
if(IS_IMMORTAL(ch))
{
pager_printf(ch, "############################## -INFO FOR IMMORTALS- ############################\n");
pager_printf(ch, "| Mob Kills: | %s **************************** | Mob-Caused Deaths: | %s \n",
victim->pcdata->mkills,
victim->pcdata->mdeaths
);
pager_printf(ch, "| Player Kills: | %s ********************** | Player-Caused Deaths: | %s \n",
victim->pcdata->pkills,
victim->pcdata->pdeaths
);
if(xIS_SET(victim->act, PLR_SILENCE) || xIS_SET(victim->act, PLR_NO_EMOTE)
|| xIS_SET(victim->act, PLR_NO_TELL) || xIS_SET(victim->act, PLR_THIEF)
|| xIS_SET(victim->act, PLR_KILLER) )
{
pager_printf(ch, "----------------------------------------------------------------------------------\n");
sprintf(buf2, "This player has the following flags set:");
if(xIS_SET(victim->act, PLR_SILENCE))
strcat(buf2, " silence");
if(xIS_SET(victim->act, PLR_NO_EMOTE))
strcat(buf2, " noemote");
if(xIS_SET(victim->act, PLR_NO_TELL) )
strcat(buf2, " notell");
if(xIS_SET(victim->act, PLR_THIEF) )
strcat(buf2, " thief");
if(xIS_SET(victim->act, PLR_KILLER) )
strcat(buf2, " killer");
strcat(buf2, ".\n\r");
send_to_pager(buf2, ch);
pager_printf(ch, "----------------------------------------------------------------------------------\n");
}
if ( victim->desc && victim->desc->host[0]!='\0' )
{
pager_printf(ch, "----------------------------------------------------------------------------------\n");
sprintf (buf2, "%s's IP info: %s ", victim->name, victim->desc->host);
if (get_trust(ch) >= LEVEL_GOD)
strcat (buf2, victim->desc->user);
strcat (buf2, "\n\r");
send_to_pager(buf2, ch);
}
}
pager_printf(ch, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-WHOIS %s-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n", victim->name);
}
Sorry bout the length of this, but I don't even know what the error is, let alone what's causing it. Thanks for your help on this =)
You have to be careful when using %d and %s inside the printf.
Here is one problem line:
The level is a number not a string, thus you must use %d and not %s. At runtime it will try to interpret the level number as a string and very probably crash.
You have similar problems further down with:
All these will be numbers, not strings.
Here is one problem line:
pager_printf(ch, "| Level: | %s ******************************************** | Race: | %s \n",
victim->level,
capitalize(race_table[victim->race]->race_name)
);
The level is a number not a string, thus you must use %d and not %s. At runtime it will try to interpret the level number as a string and very probably crash.
You have similar problems further down with:
victim->pcdata->mkills,
victim->pcdata->mdeaths
victim->pcdata->pkills,
victim->pcdata->pdeaths
All these will be numbers, not strings.
I've created a new invis command (krisinvis), which emulates invis, but automatically sets my invis level to 20000, and is available only to myself. Basically, I intend to use it so as to keep tabs on my other immortals. Lack of production alarms me, so I intend to 'spy' on them to see what they're doing with all their time when I'm not there (i.e. goofing off). Surprisingly, I was totally successful on my own, except for one thing. In act_wiz.c, in the function do_users, how can I get it so that someone doesn't show up on 'users' when affected by krisinvis? Instead of ch->pcdata->wizinvis, it's ch->pcdata->krisinvis, and instead of PLR_WIZINVIS, it's PLR_KRISINVIS. Using either of those variables, how do I perform a successful ifcheck in the do_users function which will prevent someone under krisinvis from showing up? Thanks for your help :)
In do_users, add these lines after the loop through each character:
for ( d = first_descriptor; d; d = d->next )
{
// skip krisinvis characters
if (d->character->pcdata->krisinvis)
continue;
... rest of stuff here ....
} // end of loop
It worked like a charm; thanks :)
I was also wondering: How do I get it to where it doesn't log my actions while krisinvissed? I.e.
"Build: Kris: Reset Area" would probably tip someone off that I'm online. Or "Log: Kris: force mob report" etc. I'm sure the same ifcheck would work, but where exactly do I put it?
I was also wondering: How do I get it to where it doesn't log my actions while krisinvissed? I.e.
"Build: Kris: Reset Area" would probably tip someone off that I'm online. Or "Log: Kris: force mob report" etc. I'm sure the same ifcheck would work, but where exactly do I put it?
I think you'll have to look for instances of the words "log_string_plus" which seems to be used to log lots of things.
Also, commands have a log level (log) in the command table. I would find out where that gets used.
You'll need to use grep to find such things.
Also, commands have a log level (log) in the command table. I would find out where that gets used.
You'll need to use grep to find such things.
I went to every instance of log_string_plus and put in an ifcheck at the appropriate instances, basically checking to see if the person is krisinvissed or not. However, despite all the changes I made, there are still many more commands and such that log anyways. The 'order' command and such don't log, but reset area does, log does, etc. Is there any one piece of coding I can change to accomodate everything that logs as a log, build, comm, or whatever?
I couldn't see it. The problem is that a lot of commands do logging *but* they don't pass down to the log routine the pointer to the character.
In other words, the logging routine doesn't know *who* is logging, and thus a simple test in one place doesn't seem possible.
In other words, the logging routine doesn't know *who* is logging, and thus a simple test in one place doesn't seem possible.
I'm trying to create a quest race. Well, I've already created the race and everything, including its language and all that, but now I'm trying to make a mpcommand that will transform the player into the race (in this case, a cat). After all, that seems the best route to having an automated quest. I successfully created a new mpcommand (mptransformcat), using mpadvance as a template. It worked fine, and I made sure it was calling up the function and all that, which it was. But then I tried to get it to actually transform the player's race.... I took some code from the nanny function of comm.c. My hope was to change not only the person's race, but everything from skill\stat bonuses, to native language, to height and weight. However, when I tested it, the mud did its little buzzing of the hard drive thing, and disconnected everyone. (I hate how it doesn't even return an error message when that happens) Here is the function that I created:
/* allow a mobile to transform a player into a different race (cat); use only for special quests */
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
/* Now that we're done with some standard ifchecks, let's get to the transformation coding */
send_to_char( "You start to feel a strange sensation in your body....", victim );
WAIT_STATE( victim, 2 * PULSE_VIOLENCE );
send_to_char( "What the bloody hell?!", victim );
/* Blahblahblah some fancy-schmancy stuff, then the actual transformation */
ch->race = RACE_CAT;
ch->perm_str += race_table[ch->race]->str_plus;
ch->perm_int += race_table[ch->race]->int_plus;
ch->perm_wis += race_table[ch->race]->wis_plus;
ch->perm_dex += race_table[ch->race]->dex_plus;
ch->perm_con += race_table[ch->race]->con_plus;
ch->perm_cha += race_table[ch->race]->cha_plus;
ch->affected_by = race_table[ch->race]->affected;
ch->perm_lck += race_table[ch->race]->lck_plus;
ch->armor += race_table[ch->race]->ac_plus;
ch->alignment += race_table[ch->race]->alignment;
ch->attacks = race_table[ch->race]->attacks;
ch->defenses = race_table[ch->race]->defenses;
ch->saving_poison_death = race_table[ch->race]->saving_poison_death;
ch->saving_wand = race_table[ch->race]->saving_wand;
ch->saving_para_petri = race_table[ch->race]->saving_para_petri;
ch->saving_breath = race_table[ch->race]->saving_breath;
ch->saving_spell_staff = race_table[ch->race]->saving_spell_staff;
ch->height = number_range(race_table[ch->race]->height *.9, race_table[ch->race]->height *1.1);
ch->weight = number_range(race_table[ch->race]->weight *.9, race_table[ch->race]->weight *1.1);
if ( (iLang = skill_lookup( "common" )) < 0 )
bug( "Nanny: cannot find common language." );
else
ch->pcdata->learned[iLang] = 100;
for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ )
if ( lang_array[iLang] == race_table[ch->race]->language )
break;
if ( lang_array[iLang] == LANG_UNKNOWN )
bug( "Nanny: invalid racial language." );
else
{
if ( (iLang = skill_lookup( lang_names[iLang] )) < 0 )
bug( "Nanny: cannot find racial language." );
else
ch->pcdata->learned[iLang] = 100;
}
ch->level += 1;
ch->exp += 5000;
ch->max_hit += race_table[ch->race]->hit;
ch->max_mana += race_table[ch->race]->mana;
send_to_char( "You have been transformed into a CAT!!", victim );
return;
}
If you could tell me what I did wrong and need to fix, I would be very greatful. Thank you =)
(p.s. Sorry bout all the source code junk I'm posting today)
/* allow a mobile to transform a player into a different race (cat); use only for special quests */
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
/* Now that we're done with some standard ifchecks, let's get to the transformation coding */
send_to_char( "You start to feel a strange sensation in your body....", victim );
WAIT_STATE( victim, 2 * PULSE_VIOLENCE );
send_to_char( "What the bloody hell?!", victim );
/* Blahblahblah some fancy-schmancy stuff, then the actual transformation */
ch->race = RACE_CAT;
ch->perm_str += race_table[ch->race]->str_plus;
ch->perm_int += race_table[ch->race]->int_plus;
ch->perm_wis += race_table[ch->race]->wis_plus;
ch->perm_dex += race_table[ch->race]->dex_plus;
ch->perm_con += race_table[ch->race]->con_plus;
ch->perm_cha += race_table[ch->race]->cha_plus;
ch->affected_by = race_table[ch->race]->affected;
ch->perm_lck += race_table[ch->race]->lck_plus;
ch->armor += race_table[ch->race]->ac_plus;
ch->alignment += race_table[ch->race]->alignment;
ch->attacks = race_table[ch->race]->attacks;
ch->defenses = race_table[ch->race]->defenses;
ch->saving_poison_death = race_table[ch->race]->saving_poison_death;
ch->saving_wand = race_table[ch->race]->saving_wand;
ch->saving_para_petri = race_table[ch->race]->saving_para_petri;
ch->saving_breath = race_table[ch->race]->saving_breath;
ch->saving_spell_staff = race_table[ch->race]->saving_spell_staff;
ch->height = number_range(race_table[ch->race]->height *.9, race_table[ch->race]->height *1.1);
ch->weight = number_range(race_table[ch->race]->weight *.9, race_table[ch->race]->weight *1.1);
if ( (iLang = skill_lookup( "common" )) < 0 )
bug( "Nanny: cannot find common language." );
else
ch->pcdata->learned[iLang] = 100;
for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ )
if ( lang_array[iLang] == race_table[ch->race]->language )
break;
if ( lang_array[iLang] == LANG_UNKNOWN )
bug( "Nanny: invalid racial language." );
else
{
if ( (iLang = skill_lookup( lang_names[iLang] )) < 0 )
bug( "Nanny: cannot find racial language." );
else
ch->pcdata->learned[iLang] = 100;
}
ch->level += 1;
ch->exp += 5000;
ch->max_hit += race_table[ch->race]->hit;
ch->max_mana += race_table[ch->race]->mana;
send_to_char( "You have been transformed into a CAT!!", victim );
return;
}
If you could tell me what I did wrong and need to fix, I would be very greatful. Thank you =)
(p.s. Sorry bout all the source code junk I'm posting today)
One thing that strikes me is that you are changing "ch" which I think is the mobile doing the mptransformcat, and not the victim, who is the player you want to affect. In other words, instead of:
you want:
... and so on.
ch->race = RACE_CAT;
ch->perm_str += race_table[ch->race]->str_plus;
you want:
victim->race = RACE_CAT;
victim->perm_str += race_table[victim->race]->str_plus;
... and so on.
uhhmmmm.... oops....
btw It works now; that's what I get for copying and pasting code without paying attention.... *smacks his forehead*
Thanks =)
btw It works now; that's what I get for copying and pasting code without paying attention.... *smacks his forehead*
Thanks =)
Okay, this is just more of an aesthetic thing, but I'm trying to have some text (a small storyline) appear to the character, but I don't want the bloody thing to spam it up all at once. I tried using WAIT_STATE from do_delay function, but it's having no effect. I tried every variation of the delay time, please note, and 80 is just my latest futile attempt. Here's the relevant code:
/* Now that we're done with some standard ifchecks, let's get to the transformation coding */
send_to_char( "You start to feel a strange sensation in your body....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nWhat the bloody hell?!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYou are standing in this field....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYour ears perk-up, your eyes focus, and you crouch down low in the grass....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nPatience is a virtue.... You wait calmly....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\nYou *LEAP* out of your hiding place, and land upon your unsuspecting victim!!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYour prey tries to escape, but to no avail!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe helpless mouse struggles as you bat it around playfully....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\nThe rodent bolts!\n", victim );
send_to_char( "\nYour spring-loaded legs ZIP into action! The chase is on....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYour superior dexterity is no match for the mouse, and you swiftly overtake it!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nWith a quick bite to the neck, you kill your prey.\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYou take your catch deep into the woods, where hundreds of cats are waiting for your arrival....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\nAn orange-yellow tabby steps forth from the group.\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYou open your mouth and let the mouse fall upon the ground for the tabby to see....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby nods approvingly.\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby says: You came to know our ways and our tongue. You have found much more than that. You have the heart of a tiger within you.... You are one of us.... We shall always be with you, my friend.... My brother....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby purrs. Soon, the rest of the group starts purring as well.... The sound resonates your ears, and your heart....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby lovingly rubs his cheek against yours, and disappears, along with the rest of the vision....\n", victim );
victim->race = RACE_CAT;
/* Then back to the same code as before */
I'm calling it up the same exact way it's called in other functions, at least as far as I can tell. *sigh* What am I doing wrong with this one? =)
/* Now that we're done with some standard ifchecks, let's get to the transformation coding */
send_to_char( "You start to feel a strange sensation in your body....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nWhat the bloody hell?!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYou are standing in this field....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYour ears perk-up, your eyes focus, and you crouch down low in the grass....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nPatience is a virtue.... You wait calmly....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\nYou *LEAP* out of your hiding place, and land upon your unsuspecting victim!!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYour prey tries to escape, but to no avail!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe helpless mouse struggles as you bat it around playfully....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\nThe rodent bolts!\n", victim );
send_to_char( "\nYour spring-loaded legs ZIP into action! The chase is on....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYour superior dexterity is no match for the mouse, and you swiftly overtake it!\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nWith a quick bite to the neck, you kill your prey.\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYou take your catch deep into the woods, where hundreds of cats are waiting for your arrival....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\n\nAn orange-yellow tabby steps forth from the group.\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nYou open your mouth and let the mouse fall upon the ground for the tabby to see....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby nods approvingly.\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby says: You came to know our ways and our tongue. You have found much more than that. You have the heart of a tiger within you.... You are one of us.... We shall always be with you, my friend.... My brother....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby purrs. Soon, the rest of the group starts purring as well.... The sound resonates your ears, and your heart....\n", victim );
WAIT_STATE( victim, 80 );
send_to_char( "\nThe tabby lovingly rubs his cheek against yours, and disappears, along with the rest of the vision....\n", victim );
victim->race = RACE_CAT;
/* Then back to the same code as before */
I'm calling it up the same exact way it's called in other functions, at least as far as I can tell. *sigh* What am I doing wrong with this one? =)
Does anybody know? It's been almost a week and I still can't figure this one out :\
It's not particularly easy to do that. If you look in mud.h you can see what WAIT_STATE does.
For one thing it only seems to apply to characters with the "nuisance" flag set. Also what it does is make that character wait in the main loop, what you have done is only set up, many times, a single 80-second wait.
The thing is, you can't afford to have all those 80-second pauses for that one character, between each message, like that. Imagine what will happen to everyone else on the server. As the program makes its way slowly through the list, they all have to wait 80 seconds per message as well.
The only way you can do something like that is:
1. Send the first message
2. Mark the character as having to wait (say) 10 seconds, doing something similar to what WAIT_STATE does (basically sets the "wait" variable).
3. Remember where you are in the list of messages
4. When the time is up send the next message.
5. Go back to (2).
It's not easy, but it could be done.
/* Addition to make people with nuisance flag have more wait */
#define WAIT_STATE(ch, npulse) ((ch)->wait=(!IS_NPC(ch)&&ch->pcdata->nuisance&&\
(ch->pcdata->nuisance->flags>4))?UMAX((ch)->wait,\
(npulse+((ch)->pcdata->nuisance->flags-4)+ \
ch->pcdata->nuisance->power)): \
UMAX((ch)->wait, (npulse)))
For one thing it only seems to apply to characters with the "nuisance" flag set. Also what it does is make that character wait in the main loop, what you have done is only set up, many times, a single 80-second wait.
The thing is, you can't afford to have all those 80-second pauses for that one character, between each message, like that. Imagine what will happen to everyone else on the server. As the program makes its way slowly through the list, they all have to wait 80 seconds per message as well.
The only way you can do something like that is:
1. Send the first message
2. Mark the character as having to wait (say) 10 seconds, doing something similar to what WAIT_STATE does (basically sets the "wait" variable).
3. Remember where you are in the list of messages
4. When the time is up send the next message.
5. Go back to (2).
It's not easy, but it could be done.
It would help a bit if I understood more about where the "main loop" is, and such. If I were to create a new function, perhaps set another variable to remember the place in the mud_comm function, where would I put the function calls? I can't just hold-up in a delay function without delaying the mud, so I have to let it do the main loop and have it call the delay function back or something like that..... I'm not sure. I understand what you're saying, but is there any more details you could give me, like some run-down on what the main loop function(s) is? My question is vague I know, but I really don't know how exactly to ask it. I hope you can understand what I'm asking, even though I don't totally understand myself =)
Thank you for your help and patience =)
Thank you for your help and patience =)
In file comm.c is a function called "game_loop".
A few lines into that function is a comment:
So there it is, even labelled "main loop".
This loop:
A few lines into that function is a comment:
/* Main loop */
So there it is, even labelled "main loop".
This loop:
- Checks for timeouts
- Checks for comms errors
- Accepts player input (read_from_buffer) and handles the login sequence (nanny), interprets their commands (interpret) or handles editing (edit_buffer)
- Does autonomous motion, eg. mobs moving around (update_handler)
- Sends any new output to players
I think I got the right premise, but I'm having a few small technical problems. For the purposes of the delay, I duplicated WAIT_STATE in mud.h as TEMPWAIT_STATE, using the variable tempwait instead of wait. As follows:
#define TEMPWAIT_STATE(ch, npulse) ((ch)->tempwait=(!IS_NPC(ch)&&ch->pcdata->nuisance&&\
(ch->pcdata->nuisance->flags>4))?UMAX((ch)->tempwait,\
(npulse+((ch)->pcdata->nuisance->flags-4)+ \
ch->pcdata->nuisance->power)): \
UMAX((ch)->tempwait, (npulse)))
No problems there as I can see. At approximately 2277 in mud.h, I added the following:
sh_int tempwait;
sh_int tempwaitb;
sh_int tempwaitc;
Tempwaitb is used to remember where in the message sequence it is, and tempwaitc is used to rembember what function to call once the tempwait variable reaches zero. As follows:
*in comm.c*
if ( d->character && d->character->tempwait > 0 )
{
--d->character->tempwait;
if (d->character->tempwait == 0)
{
if (tempwaitc == 1)
do_mptransformcat(ch, d->character); /* Problem 1: I can't figure out how to call this function, having it remember ch and victim */
}
continue;
}
The rest is in the next post; too many characters in this.
#define TEMPWAIT_STATE(ch, npulse) ((ch)->tempwait=(!IS_NPC(ch)&&ch->pcdata->nuisance&&\
(ch->pcdata->nuisance->flags>4))?UMAX((ch)->tempwait,\
(npulse+((ch)->pcdata->nuisance->flags-4)+ \
ch->pcdata->nuisance->power)): \
UMAX((ch)->tempwait, (npulse)))
No problems there as I can see. At approximately 2277 in mud.h, I added the following:
sh_int tempwait;
sh_int tempwaitb;
sh_int tempwaitc;
Tempwaitb is used to remember where in the message sequence it is, and tempwaitc is used to rembember what function to call once the tempwait variable reaches zero. As follows:
*in comm.c*
if ( d->character && d->character->tempwait > 0 )
{
--d->character->tempwait;
if (d->character->tempwait == 0)
{
if (tempwaitc == 1)
do_mptransformcat(ch, d->character); /* Problem 1: I can't figure out how to call this function, having it remember ch and victim */
}
continue;
}
The rest is in the next post; too many characters in this.
*continued from last post*
*in mud_comm.c, the entirety of do_mptransformcat as it is now*
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
int tempwaitb;
int tempwaitc;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
/* To remember where in the message sequence the player is; part of the institution of a delay
Please excuse the spaghetti code =) --Kris */
victim = arg;
if ( tempwaitb == 1 )
goto cat_a;
if ( tempwaitb == 2 )
goto cat_b;
if ( tempwaitb == 3 )
goto cat_c;
if ( tempwaitb == 4 )
goto cat_d;
if ( tempwaitb == 5 )
goto cat_e;
if ( tempwaitb == 6 )
goto cat_f;
if ( tempwaitb == 7 )
goto cat_g;
if ( tempwaitb == 8 )
goto cat_h;
if ( tempwaitb == 9 )
goto cat_i;
if ( tempwaitb == 10 )
goto cat_j;
if ( tempwaitb == 11 )
goto cat_k;
if ( tempwaitb == 12 )
goto cat_l;
if ( tempwaitb == 13 )
goto cat_m;
if ( tempwaitb == 14 )
goto cat_n;
if ( tempwaitb == 15 )
goto cat_o;
if ( tempwaitb == 16 )
goto cat_p;
if ( tempwaitb == 17 )
goto cat_q;
if ( tempwaitb == 18 )
goto cat_r;
if ( tempwaitb == 19 )
goto cat_s;
if ( tempwaitb == 20 )
goto cat_t;
if ( tempwaitb == 21 )
goto cat_u;
if ( tempwaitb == 22 )
goto cat_v;
if ( tempwaitb == 23 )
goto cat_w;
if ( victim->race == RACE_CAT )
{
send_to_char( "A mystical voice says: You're already a cat, you mook!", victim );
return;
}
/* Now that we're done with some standard ifchecks, let's get to the transformation coding */
send_to_char( "You start to feel a strange sensation in your body....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 1;
tempwaitc = 1;
return;
cat_a:
send_to_char( "\nWhat the bloody hell?!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 2;
tempwaitc = 1;
return;
cat_b:
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 3;
tempwaitc = 1;
return;
cat_c:
send_to_char( "\nYou are standing in this field....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 4;
tempwaitc = 1;
return;
cat_d:
send_to_char( "\nYour ears perk-up, your eyes focus, and you crouch down low in the grass....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 5;
tempwaitc = 1;
return;
cat_e:
send_to_char( "\nPatience is a virtue.... You wait calmly....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 6;
tempwaitc = 1;
return;
cat_f:
send_to_char( "\n\nYou *LEAP* out of your hiding place, and land upon your unsuspecting victim!!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 7;
tempwaitc = 1;
return;
cat_g:
send_to_char( "\nYour prey tries to escape, but to no avail!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 8;
tempwaitc = 1;
return;
cat_h:
send_to_char( "\nThe helpless mouse struggles as you bat it around playfully....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 9;
tempwaitc = 1;
return;
cat_i:
send_to_char( "\n\nThe rodent bolts!\n", victim );
send_to_char( "\nYour spring-loaded legs ZIP into action! The chase is on....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 10;
tempwaitc = 1;
return;
Another post to go... sorry bout the lengthyness
*in mud_comm.c, the entirety of do_mptransformcat as it is now*
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
int tempwaitb;
int tempwaitc;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
/* To remember where in the message sequence the player is; part of the institution of a delay
Please excuse the spaghetti code =) --Kris */
victim = arg;
if ( tempwaitb == 1 )
goto cat_a;
if ( tempwaitb == 2 )
goto cat_b;
if ( tempwaitb == 3 )
goto cat_c;
if ( tempwaitb == 4 )
goto cat_d;
if ( tempwaitb == 5 )
goto cat_e;
if ( tempwaitb == 6 )
goto cat_f;
if ( tempwaitb == 7 )
goto cat_g;
if ( tempwaitb == 8 )
goto cat_h;
if ( tempwaitb == 9 )
goto cat_i;
if ( tempwaitb == 10 )
goto cat_j;
if ( tempwaitb == 11 )
goto cat_k;
if ( tempwaitb == 12 )
goto cat_l;
if ( tempwaitb == 13 )
goto cat_m;
if ( tempwaitb == 14 )
goto cat_n;
if ( tempwaitb == 15 )
goto cat_o;
if ( tempwaitb == 16 )
goto cat_p;
if ( tempwaitb == 17 )
goto cat_q;
if ( tempwaitb == 18 )
goto cat_r;
if ( tempwaitb == 19 )
goto cat_s;
if ( tempwaitb == 20 )
goto cat_t;
if ( tempwaitb == 21 )
goto cat_u;
if ( tempwaitb == 22 )
goto cat_v;
if ( tempwaitb == 23 )
goto cat_w;
if ( victim->race == RACE_CAT )
{
send_to_char( "A mystical voice says: You're already a cat, you mook!", victim );
return;
}
/* Now that we're done with some standard ifchecks, let's get to the transformation coding */
send_to_char( "You start to feel a strange sensation in your body....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 1;
tempwaitc = 1;
return;
cat_a:
send_to_char( "\nWhat the bloody hell?!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 2;
tempwaitc = 1;
return;
cat_b:
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 3;
tempwaitc = 1;
return;
cat_c:
send_to_char( "\nYou are standing in this field....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 4;
tempwaitc = 1;
return;
cat_d:
send_to_char( "\nYour ears perk-up, your eyes focus, and you crouch down low in the grass....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 5;
tempwaitc = 1;
return;
cat_e:
send_to_char( "\nPatience is a virtue.... You wait calmly....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 6;
tempwaitc = 1;
return;
cat_f:
send_to_char( "\n\nYou *LEAP* out of your hiding place, and land upon your unsuspecting victim!!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 7;
tempwaitc = 1;
return;
cat_g:
send_to_char( "\nYour prey tries to escape, but to no avail!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 8;
tempwaitc = 1;
return;
cat_h:
send_to_char( "\nThe helpless mouse struggles as you bat it around playfully....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 9;
tempwaitc = 1;
return;
cat_i:
send_to_char( "\n\nThe rodent bolts!\n", victim );
send_to_char( "\nYour spring-loaded legs ZIP into action! The chase is on....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 10;
tempwaitc = 1;
return;
Another post to go... sorry bout the lengthyness
*continued from last post*
cat_j:
send_to_char( "\nYour superior dexterity is no match for the mouse, and you swiftly overtake it!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 11;
tempwaitc = 1;
return;
cat_k:
send_to_char( "\nWith a quick bite to the neck, you kill your prey.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 12;
tempwaitc = 1;
return;
cat_l:
send_to_char( "\nYou take your catch deep into the woods, where hundreds of cats are waiting for your arrival....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 13;
tempwaitc = 1;
return;
cat_m:
send_to_char( "\n\nAn orange-yellow tabby steps forth from the group.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 14;
tempwaitc = 1;
return;
cat_n:
send_to_char( "\nYou open your mouth and let the mouse fall upon the ground for the tabby to see....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 15;
tempwaitc = 1;
return;
cat_o:
send_to_char( "\nThe tabby nods approvingly.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 16;
tempwaitc = 1;
return;
cat_p:
send_to_char( "\nThe tabby says: You came to know our ways and our tongue. You have found much more than that. You have the heart of a tiger within you.... You are one of us.... We shall always be with you, my friend.... My brother....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 17;
tempwaitc = 1;
return;
cat_q:
send_to_char( "\nThe tabby purrs. Soon, the rest of the group starts purring as well.... The sound resonates your ears, and your heart....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 18;
tempwaitc = 1;
return;
cat_r:
send_to_char( "\nThe tabby lovingly rubs his cheek against yours, and disappears, along with the rest of the vision....\n", victim );
victim->race = RACE_CAT;
victim->perm_str += race_table[victim->race]->str_plus;
victim->perm_int += race_table[victim->race]->int_plus;
victim->perm_wis += race_table[victim->race]->wis_plus;
victim->perm_dex += race_table[victim->race]->dex_plus;
victim->perm_con += race_table[victim->race]->con_plus;
victim->perm_cha += race_table[victim->race]->cha_plus;
victim->affected_by = race_table[victim->race]->affected;
victim->perm_lck += race_table[victim->race]->lck_plus;
victim->armor += race_table[victim->race]->ac_plus;
victim->alignment += race_table[victim->race]->alignment;
victim->attacks = race_table[victim->race]->attacks;
victim->defenses = race_table[victim->race]->defenses;
victim->saving_poison_death = race_table[victim->race]->saving_poison_death;
victim->saving_wand = race_table[victim->race]->saving_wand;
victim->saving_para_petri = race_table[victim->race]->saving_para_petri;
victim->saving_breath = race_table[victim->race]->saving_breath;
victim->saving_spell_staff = race_table[victim->race]->saving_spell_staff;
victim->height = number_range(race_table[victim->race]->height *.9, race_table[victim->race]->height *1.1);
victim->weight = number_range(race_table[victim->race]->weight *.9, race_table[victim->race]->weight *1.1);
if ( (iLang = skill_lookup( "common" )) < 0 )
bug( "Nanny: cannot find common language." );
else
victim->pcdata->learned[iLang] = 100;
for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ )
if ( lang_array[iLang] == race_table[victim->race]->language )
break;
if ( lang_array[iLang] == LANG_UNKNOWN )
bug( "Nanny: invalid racial language." );
else
{
if ( (iLang = skill_lookup( lang_names[iLang] )) < 0 )
bug( "Nanny: cannot find racial language." );
else
victim->pcdata->learned[iLang] = 100;
}
victim->level += 1;
victim->exp += 5000;
victim->max_hit += race_table[victim->race]->hit;
victim->max_mana += race_table[victim->race]->mana;
TEMPWAIT_STATE(victim, 20);
tempwaitb = 19;
tempwaitc = 1;
return;
cat_s:
send_to_char( "\nBut wait a minute....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 20;
tempwaitc = 1;
return;
cat_t:
send_to_char( "\nWhy are you standing on all fours?......\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 21;
tempwaitc = 1;
return;
cat_u:
send_to_char( "\nOh my....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 22;
tempwaitc = 1;
return;
cat_v:
send_to_char( "\n\nYou have been transformed into a CAT!!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 23;
tempwaitc = 1;
return;
cat_w:
tempwaitb = 0;
tempwaitc = 0;
return;
}
*that's it*
Now, I know it's probably a lot sloppier and more redundant than it needs to be. I think I have the premise right, but I'm having trouble with the function declaration in comm.c, and with some variables. I assumed that by putting tempwaitb and tempwaitc in mud.h, it would remember those variables' values between functions, but I'm not sure. I hope I've provided enough information for you to be able to get me past this obstacle. Thank you for your time and help =)
cat_j:
send_to_char( "\nYour superior dexterity is no match for the mouse, and you swiftly overtake it!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 11;
tempwaitc = 1;
return;
cat_k:
send_to_char( "\nWith a quick bite to the neck, you kill your prey.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 12;
tempwaitc = 1;
return;
cat_l:
send_to_char( "\nYou take your catch deep into the woods, where hundreds of cats are waiting for your arrival....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 13;
tempwaitc = 1;
return;
cat_m:
send_to_char( "\n\nAn orange-yellow tabby steps forth from the group.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 14;
tempwaitc = 1;
return;
cat_n:
send_to_char( "\nYou open your mouth and let the mouse fall upon the ground for the tabby to see....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 15;
tempwaitc = 1;
return;
cat_o:
send_to_char( "\nThe tabby nods approvingly.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 16;
tempwaitc = 1;
return;
cat_p:
send_to_char( "\nThe tabby says: You came to know our ways and our tongue. You have found much more than that. You have the heart of a tiger within you.... You are one of us.... We shall always be with you, my friend.... My brother....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 17;
tempwaitc = 1;
return;
cat_q:
send_to_char( "\nThe tabby purrs. Soon, the rest of the group starts purring as well.... The sound resonates your ears, and your heart....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 18;
tempwaitc = 1;
return;
cat_r:
send_to_char( "\nThe tabby lovingly rubs his cheek against yours, and disappears, along with the rest of the vision....\n", victim );
victim->race = RACE_CAT;
victim->perm_str += race_table[victim->race]->str_plus;
victim->perm_int += race_table[victim->race]->int_plus;
victim->perm_wis += race_table[victim->race]->wis_plus;
victim->perm_dex += race_table[victim->race]->dex_plus;
victim->perm_con += race_table[victim->race]->con_plus;
victim->perm_cha += race_table[victim->race]->cha_plus;
victim->affected_by = race_table[victim->race]->affected;
victim->perm_lck += race_table[victim->race]->lck_plus;
victim->armor += race_table[victim->race]->ac_plus;
victim->alignment += race_table[victim->race]->alignment;
victim->attacks = race_table[victim->race]->attacks;
victim->defenses = race_table[victim->race]->defenses;
victim->saving_poison_death = race_table[victim->race]->saving_poison_death;
victim->saving_wand = race_table[victim->race]->saving_wand;
victim->saving_para_petri = race_table[victim->race]->saving_para_petri;
victim->saving_breath = race_table[victim->race]->saving_breath;
victim->saving_spell_staff = race_table[victim->race]->saving_spell_staff;
victim->height = number_range(race_table[victim->race]->height *.9, race_table[victim->race]->height *1.1);
victim->weight = number_range(race_table[victim->race]->weight *.9, race_table[victim->race]->weight *1.1);
if ( (iLang = skill_lookup( "common" )) < 0 )
bug( "Nanny: cannot find common language." );
else
victim->pcdata->learned[iLang] = 100;
for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ )
if ( lang_array[iLang] == race_table[victim->race]->language )
break;
if ( lang_array[iLang] == LANG_UNKNOWN )
bug( "Nanny: invalid racial language." );
else
{
if ( (iLang = skill_lookup( lang_names[iLang] )) < 0 )
bug( "Nanny: cannot find racial language." );
else
victim->pcdata->learned[iLang] = 100;
}
victim->level += 1;
victim->exp += 5000;
victim->max_hit += race_table[victim->race]->hit;
victim->max_mana += race_table[victim->race]->mana;
TEMPWAIT_STATE(victim, 20);
tempwaitb = 19;
tempwaitc = 1;
return;
cat_s:
send_to_char( "\nBut wait a minute....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 20;
tempwaitc = 1;
return;
cat_t:
send_to_char( "\nWhy are you standing on all fours?......\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 21;
tempwaitc = 1;
return;
cat_u:
send_to_char( "\nOh my....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 22;
tempwaitc = 1;
return;
cat_v:
send_to_char( "\n\nYou have been transformed into a CAT!!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 23;
tempwaitc = 1;
return;
cat_w:
tempwaitb = 0;
tempwaitc = 0;
return;
}
*that's it*
Now, I know it's probably a lot sloppier and more redundant than it needs to be. I think I have the premise right, but I'm having trouble with the function declaration in comm.c, and with some variables. I assumed that by putting tempwaitb and tempwaitc in mud.h, it would remember those variables' values between functions, but I'm not sure. I hope I've provided enough information for you to be able to get me past this obstacle. Thank you for your time and help =)
You are correct, if variables are declared outside of a function, that makes them global, which means their values won't change from function to function, and all functions can see them. Another way to accomplish the same thing is to declare them in your function as static.....for
example
some_function(){
static int blah=0;
blah++;
}
Now this will set blah to 0 the FIRST time the function is called, the second time blah will be 1, third 2 and so on.If that variable doesn't change elsewhere in the code, this is a better way to do the code. I havent looked through the rest of the code, just answering your question ;)
example
some_function(){
static int blah=0;
blah++;
}
Now this will set blah to 0 the FIRST time the function is called, the second time blah will be 1, third 2 and so on.If that variable doesn't change elsewhere in the code, this is a better way to do the code. I havent looked through the rest of the code, just answering your question ;)
Another problem is that these variables, by being in the code itself, are going to be shared between players. Thus if two of them are having this message sent to them at once, they will get out of sequence. Remembering things relevant to players can't really be done in static variables.
Another thing you might want to read up on is the switch statement. Your use of "goto" is unnecessary and confusing. You also have a lot of repeated code. Instead of:
do this:
Another thing you might want to read up on is the switch statement. Your use of "goto" is unnecessary and confusing. You also have a lot of repeated code. Instead of:
if ( tempwaitb == 1 )
goto cat_a;
if ( tempwaitb == 2 )
goto cat_b;
if ( tempwaitb == 3 )
goto cat_c;
if ( tempwaitb == 4 )
goto cat_d;
do this:
if (tempwaitb >= 1 && tempwaitb <= 17)
{
switch (tempwaitb)
{
case 1:
send_to_char( "\nWhat the bloody hell?!\n", victim );
break;
case 2:
send_to_char
( "\n\n\nA vast, open field flashes before your eyes....\n",
victim );
break;
case 3:
send_to_char
( "\nYou are standing in this field....\n",
victim );
break;
/* ... and so on ... */
} /* end of switch */
tempwaitb++;
tempwaitc = 1;
return;
} /* end of tempwaitb in range 1 to 17 */
Now, I'm just having to fix the function call to do_mptransformcat in comm.c. I took your advice, and made tempwaitb and tempwaitc as specific to the character (i.e. victim->tempwaitb instead of just tempwaitb). Those variables are successfully being remembered between functions :)
However, ch and victim still aren't being remembered between functions. So, in comm.c, I have no bloody idea what to put down for ch and victim when calling do_mptransformcat. I tried using the same premise as I did with tempwaitb and tempwaitc, i.e. assigning a temporary value to the victim, so it would be remembered. I think my premise is sound, and I'm not recieving any compile or runtime errors, and some debugging did confirm that it is in fact making it to the function call.... however, the function is either not being called, or the variables it's recieving are wrong, because after the delay, nothing happens. If I activate the mobprogram again (by saying 'catme' for lack of anything better), then it performs the next message in the sequence, does the delay, then nothing, as if I'm not making the call back into mptransformcat. Here is the relevant code (more concise this time):
*mud.h*
struct char_data
{
CHAR_DATA * next;
CHAR_DATA * prev;
char * tempvictim;
CHAR_DATA * tempch;
*the beginning of do_mptransformcat*
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
victim->tempch = ch;
victim->tempvictim = argument;
*and comm.c*
if ( d->character && d->character->wait > 0 )
{
--d->character->wait;
continue;
}
if ( d->character && d->character->tempwait > 0 )
{
--d->character->tempwait;
if (d->character->tempwait == 0)
{
write_to_descriptor( d->descriptor,
"debug1.\n\r", 0 );
/* Right here is where I'm stuck */ do_mptransformcat(d->character->tempch, d->character->tempvictim);
}
continue;
}
*that's it*
I feel I'm close, but I'm still stumped on this part. Thanks for all your help and, above all, your patience =)
However, ch and victim still aren't being remembered between functions. So, in comm.c, I have no bloody idea what to put down for ch and victim when calling do_mptransformcat. I tried using the same premise as I did with tempwaitb and tempwaitc, i.e. assigning a temporary value to the victim, so it would be remembered. I think my premise is sound, and I'm not recieving any compile or runtime errors, and some debugging did confirm that it is in fact making it to the function call.... however, the function is either not being called, or the variables it's recieving are wrong, because after the delay, nothing happens. If I activate the mobprogram again (by saying 'catme' for lack of anything better), then it performs the next message in the sequence, does the delay, then nothing, as if I'm not making the call back into mptransformcat. Here is the relevant code (more concise this time):
*mud.h*
struct char_data
{
CHAR_DATA * next;
CHAR_DATA * prev;
char * tempvictim;
CHAR_DATA * tempch;
*the beginning of do_mptransformcat*
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
victim->tempch = ch;
victim->tempvictim = argument;
*and comm.c*
if ( d->character && d->character->wait > 0 )
{
--d->character->wait;
continue;
}
if ( d->character && d->character->tempwait > 0 )
{
--d->character->tempwait;
if (d->character->tempwait == 0)
{
write_to_descriptor( d->descriptor,
"debug1.\n\r", 0 );
/* Right here is where I'm stuck */ do_mptransformcat(d->character->tempch, d->character->tempvictim);
}
continue;
}
*that's it*
I feel I'm close, but I'm still stumped on this part. Thanks for all your help and, above all, your patience =)
Oops, I forgot to mention. After the delay, when it makes the call back to do_mptransformcat, I get the following bug message:
Log: [*****] BUG: Mptransform - Bad syntax, Mob #20107.
Log: [*****] BUG: Mptransform - Bad syntax, Mob #20107.
Does anybody have any insights as to how to accurately make that function call and what type I should initialize the variables as in mud.h? No combination I've tried has yielded progressive results since the last post.
I would like to make a suggestion. You are obviously having trouble getting this to work, and I think you are getting focussed on one minor area - namely getting messages to appear slowly, when there is a whole lot more stuff that SMAUG can do.
You said yourself in an earlier post "this is just more of an aesthetic thing" - how about leaving it for now and doing something else?
Even if you get this "delayed message" thing to work that won't be the end of your problems.
For example, you have these messages:
There are a whole lot of problems here for a start.
I think you are best of letting this idea rest for a while. If you really want the delayed message thing, there is another codebase I am investigating that has that built in, so you can achieve that effect (desirable or not) with a minimum amount of effort.
Meanwhile, I suggest concentrating on designing the rooms and areas in general, and making a fantastic MUD. :)
You said yourself in an earlier post "this is just more of an aesthetic thing" - how about leaving it for now and doing something else?
Even if you get this "delayed message" thing to work that won't be the end of your problems.
For example, you have these messages:
A vast, open field flashes before your eyes....
You are standing in this field....
Your ears perk-up, your eyes focus, and you crouch down low in the grass....
Patience is a virtue.... You wait calmly....
You *LEAP* out of your hiding place, and land upon your unsuspecting victim!!
Your prey tries to escape, but to no avail!
The helpless mouse struggles as you bat it around playfully....
The rodent bolts!
Your spring-loaded legs ZIP into action! The chase is on....
Your superior dexterity is no match for the mouse, and you swiftly overtake it!
With a quick bite to the neck, you kill your prey.
You take your catch deep into the woods, where hundreds of cats are waiting for your arrival....
There are a whole lot of problems here for a start.
- What if, halfway through the messages, the player goes to another room, recalls, goes into a town? Are they really "standing in this field" any more? No, and it will look silly to say so.
- You are effectively controlling the player, telling him what he is doing. What if he doesn't "wait calmly" but walks away? It will look silly to say "you wait calmly" when he is running from room to room.
- What if the player doesn't want to kill the mouse?
- Does he get experience points for killing it?
I think you are best of letting this idea rest for a while. If you really want the delayed message thing, there is another codebase I am investigating that has that built in, so you can achieve that effect (desirable or not) with a minimum amount of effort.
Meanwhile, I suggest concentrating on designing the rooms and areas in general, and making a fantastic MUD. :)
it's not actual actions. It's a vision he's recieving in his mind.
I just need to know how to call that function while preserving the ch and victim variables from function-to-function; my other admins are focusing on socials and areas while I'm revamping through the source code.
I just need to know how to call that function while preserving the ch and victim variables from function-to-function; my other admins are focusing on socials and areas while I'm revamping through the source code.
In comm.c, this is how I'm making the function call:
do_mptransformcat(d->character->tempch, d->character->tempvictim);
in mud.h, tempch is defined as CHAR_DATA *
and tempvictim is defined as char *
Tempch is working perfectly. However, tempvictim is working -somtimes-, but randomly not working. There is no pattern to this, but sometimes when the function is called, I get the bug: Log: [*****] BUG: Mptransform - Bad syntax, Mob #20107.
or the bug: Log: [*****] BUG: Mptransform - Victim not there, Mob #20107.
Both suggest that tempvictim is sometimes not being the same as the initial argument. This is how I set it in mud_comm.c:
CHAR_DATA *tempchb;
char *tempvictimb;
/* these are used to capture argument and ch, before argument is altered, as follows */
if ( ( tempchb != ch ) || ( tempvictimb != argument ) )
{
tempchb = ch;
tempvictimb = argument;
}
argument = one_argument( argument, arg );
So now, tempchb should be same as ch, and tempvictimb should be same as argument. Then the next ifchecks:
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
This is self-explanatory. Sometimes it fires, sometimes it doesn't. I've done a lot of debugging, and haven't been able to determine any pattern; it's just randomly working or not working, which makes no sense to me whatsoever. Also, the second ifcheck serves to set the victim variable for that function. Now here comes the crucial lines:
if ( ( victim->tempch != tempchb ) || ( victim->tempvictim != tempvictimb ) )
{
victim->tempch = tempchb;
victim->tempvictim = tempvictimb;
}
This states that, if victim->tempch or victim->tempvictim are not what they're supposed to be, then it sets them to what they should be. This is all the relevant code to this attempt to carry the variables globally, while having it specific to each character. Since the character is delayed, and at least at the moment there's no worry about teleports or anything (I can worry bout that later on), there's no way the character will leave the room, which he isn't. Sometimes this bug will fire after 1 or 2 messages, and sometimes it'll take like 15 messages before it fires; I can find no pattern whatsoever.
Could someone PLEASE give me some guidance with this? I've been banging my head over it for weeks, and I can't release the next backup until this coding is done, like I promised. I'm sure Nick is weary of my nagging on this problem, so if anyone else (i.e. Nivek or whomever) could help me with this, that'd prolly be best. =) Thank you :)
do_mptransformcat(d->character->tempch, d->character->tempvictim);
in mud.h, tempch is defined as CHAR_DATA *
and tempvictim is defined as char *
Tempch is working perfectly. However, tempvictim is working -somtimes-, but randomly not working. There is no pattern to this, but sometimes when the function is called, I get the bug: Log: [*****] BUG: Mptransform - Bad syntax, Mob #20107.
or the bug: Log: [*****] BUG: Mptransform - Victim not there, Mob #20107.
Both suggest that tempvictim is sometimes not being the same as the initial argument. This is how I set it in mud_comm.c:
CHAR_DATA *tempchb;
char *tempvictimb;
/* these are used to capture argument and ch, before argument is altered, as follows */
if ( ( tempchb != ch ) || ( tempvictimb != argument ) )
{
tempchb = ch;
tempvictimb = argument;
}
argument = one_argument( argument, arg );
So now, tempchb should be same as ch, and tempvictimb should be same as argument. Then the next ifchecks:
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
This is self-explanatory. Sometimes it fires, sometimes it doesn't. I've done a lot of debugging, and haven't been able to determine any pattern; it's just randomly working or not working, which makes no sense to me whatsoever. Also, the second ifcheck serves to set the victim variable for that function. Now here comes the crucial lines:
if ( ( victim->tempch != tempchb ) || ( victim->tempvictim != tempvictimb ) )
{
victim->tempch = tempchb;
victim->tempvictim = tempvictimb;
}
This states that, if victim->tempch or victim->tempvictim are not what they're supposed to be, then it sets them to what they should be. This is all the relevant code to this attempt to carry the variables globally, while having it specific to each character. Since the character is delayed, and at least at the moment there's no worry about teleports or anything (I can worry bout that later on), there's no way the character will leave the room, which he isn't. Sometimes this bug will fire after 1 or 2 messages, and sometimes it'll take like 15 messages before it fires; I can find no pattern whatsoever.
Could someone PLEASE give me some guidance with this? I've been banging my head over it for weeks, and I can't release the next backup until this coding is done, like I promised. I'm sure Nick is weary of my nagging on this problem, so if anyone else (i.e. Nivek or whomever) could help me with this, that'd prolly be best. =) Thank you :)
Also, I'm not sure if it's relevant, but I should prolly mention it: When compiling, I get the following Warning error for mud_comm.c:
mud_comm.c:1278: warning: 'tempvictimb' might be uninitialized in this function
I'm not sure why it's saying this, because it is initialized. Yet it's saying something that may shed a light on why this isn't working, I'm not sure.
mud_comm.c:1278: warning: 'tempvictimb' might be uninitialized in this function
I'm not sure why it's saying this, because it is initialized. Yet it's saying something that may shed a light on why this isn't working, I'm not sure.
CHAR_DATA *tempchb;
char *tempvictimb;
/* these are used to capture argument and ch, before argument is altered, as follows */
if ( ( tempchb != ch ) || ( tempvictimb != argument ) )
{
tempchb = ch;
tempvictimb = argument;
}
The if statement is fairly meaningless, because as the compiler points out, you are testing tempvictimb but tempvictimb does not have any value assigned to it - it is just what happens to be on the stack at the time.
You assign something to tempvictimb *after* testing its value. The same remark applies to tempchb.
You say:
Quote:
This states that, if victim->tempch or victim->tempvictim are not what they're supposed to be, then it sets them to what they should be.
This states that, if victim->tempch or victim->tempvictim are not what they're supposed to be, then it sets them to what they should be.
Well, why not make sure they have the right value, like this:
CHAR_DATA *tempchb = ch;
har *tempvictimb = argument;
I eliminated the ifcheck and did as you suggested instead. Now, the compile warning error is gone :)
However, I'm -STILL- getting that bug I described earlier, whereas for some reason, at seemingly random occurances, victim is not transferring over correctly.
Do you have any other ideas that may solve this? If nothing else, you're helping me make my code a lot cleaner =)
Eventually perhaps we'll end up hitting the root of the problem. I thank you for your continued help with this extremely perplexing matter :)
However, I'm -STILL- getting that bug I described earlier, whereas for some reason, at seemingly random occurances, victim is not transferring over correctly.
Do you have any other ideas that may solve this? If nothing else, you're helping me make my code a lot cleaner =)
Eventually perhaps we'll end up hitting the root of the problem. I thank you for your continued help with this extremely perplexing matter :)
Can anyone please help me with this? I've been trying almost 2 months now, and still can't get this bloody thing to work! Read the previous few posts if you don't know what I'm talking about. Thank you whomever decides to help me fix this once and for all :)
Probably this is the reason it wasn't put there by the original developers.
Here is one potential problem, you have saved a victim pointer, and are sending this victim messages every second or so (quite a lot of messages, thus quite a lot of seconds).
What if the victim logs out? Then the pointer is invalid.
I still think the idea of sending messages like:
... while the player has gone back to town and is sleeping in the inn, or buying provision in the shop, is going to look silly. I know you say it is a vision he has in his mind, but it is a strange vision.
Here is one potential problem, you have saved a victim pointer, and are sending this victim messages every second or so (quite a lot of messages, thus quite a lot of seconds).
What if the victim logs out? Then the pointer is invalid.
I still think the idea of sending messages like:
The rodent bolts!
Your spring-loaded legs ZIP into action! The chase is on....
Your superior dexterity is no match for the mouse, and you swiftly overtake it!
... while the player has gone back to town and is sleeping in the inn, or buying provision in the shop, is going to look silly. I know you say it is a vision he has in his mind, but it is a strange vision.
I realize that, but at very worst, if the player disconnects and the pointer thus becomes invalid, it'll just show the immortals a BUG; the same bug I'm getting right now. I could also put in an ifcheck to ensure the player is connected before it makes any attempt.
This is just one use of this coding I'm trying to set up. If successful, we can also create bards, as well as other things that would require some sort of paced message. I.e. on many muds, when a bard sings, he sings in several verses (in this case, wait_state wouldn't be used btw). Now, it looks really stupid if the bard sings 4 verses of a song in just a fraction of a second; not to mention it makes it very difficult for other players to follow. Wouldn't a delay- the exact type of delay I'm trying to add- be nice in that case? That wouldn't work, however, if it couldn't leave the function without forgetting/screwing-up the victim variable, making it impossible to send the next message in the sequence.
I apologize if the example of my attempt seems silly and pointless, but there are -many- other potential uses for this, if I can get it set up. That's why I'm being so persistent; there's a lot of things I want to do that I can't, simply because I can't get this bloody thing to work. Is there anybody out there who would have some sort of idea as to how I can fix this apparently-complex problem? Thanks for your patience and help :)
This is just one use of this coding I'm trying to set up. If successful, we can also create bards, as well as other things that would require some sort of paced message. I.e. on many muds, when a bard sings, he sings in several verses (in this case, wait_state wouldn't be used btw). Now, it looks really stupid if the bard sings 4 verses of a song in just a fraction of a second; not to mention it makes it very difficult for other players to follow. Wouldn't a delay- the exact type of delay I'm trying to add- be nice in that case? That wouldn't work, however, if it couldn't leave the function without forgetting/screwing-up the victim variable, making it impossible to send the next message in the sequence.
I apologize if the example of my attempt seems silly and pointless, but there are -many- other potential uses for this, if I can get it set up. That's why I'm being so persistent; there's a lot of things I want to do that I can't, simply because I can't get this bloody thing to work. Is there anybody out there who would have some sort of idea as to how I can fix this apparently-complex problem? Thanks for your patience and help :)
I'm sorry to keep persisting, but this problem is still the 'public enemy #1' in our source code, and I have been at a loss to fix it for some time. If -anyone- could help me, give me some fresh ideas, etc, I would be more than greatful. The last several posts about this describe everything in detail. Please, PLEASE read through it if you know anything descent about C programming; we really need an answer, and I cannot provide any. Thank you for your help :)
How bad is my coding? Where have I gone wrong? Is the problem so complex that nobody who is proficient in C programming can determine the problem, let alone help solve it? Or is my question somehow offending or annoying anyone? If so, please tell me, so I can stop making a fool out of myself by posting here. I just want some technical help with this vital (I cannot stress how vital) code. If I can get this to work, that will open the door to so many possibilities, and enable work on many other things I've got planned. Aside from an opinion as to why this is or is not good for my mud, does *anybody* have *anything* to offer that could help me fix this? I'm beyond stumped, and for all I know, it's a simple C syntax error. It makes no sense; I really need a step in the right direction from someone who has experience with this. Somebody, if you're out there, please help us! Thanks for your time :)
Email me your C files - the ones you have changed, not the whole lot, and any relevant .h files, and I'll take a look. It is very hard to debug without running the code. You can tell from the date modified which files have changed, and you ought to know anyway which ones they are.
OK, now that Kris has sent me the code, I'll comment here on what happened, so it will hopefully help others as well as Kris.
What he had done was put the messages into do_mptransformcat like this:
The problem with this is that do_mptransformcat is only called once by the mob, and thus that the sequence of messages won't be displayed.
However he tried to work around this by re-calling do_mptransformcat from the main game_loop ...
I can see what he is trying to do here, but I think that this approach is doomed to failure, particularly when do_mptransformcat is recalled from the game loop, because he has had to "dummy up" the arguments to do_mptransformcat, which then eventually gives the error messages that he reported.
My approach would be to split the delayed messages into a totally different routine, because you are really doing two things here:
Thus, I have only the following code in do_mptransformcat:
Basically I deleted all the message stuff (and pasted elsewhere) - the only thing left, to initiate the messages to the player, is setting the tempwait flag to 1 (shown in bold), which means that message number 1 is due to be shown to the player.
Now we make another function "special_messages" that will display the messages in sequence (adding 1 to tempwait each time). When we get to the end of the sequence we set tempwait to zero to indicate that we have finished.
The remaining trick is to call this function each second, which can be easily done by following what game_loop does. Amongst other things, it calls "update_handler", which calls "char_check" every second.
Some way into char_check, after deciding that we have a player and not a mob, we add a couple of lines:
Finally, we need to zero out ch->tempwait when a player connects, otherwise if it happened to have a non-zero value when a player connected, they might start seeing messages about turning into a cat ...
I will send the complete changes to Kris as a patchfile, hopefully he will be able to get his messages working, and the technique could be used for other muds as well.
What he had done was put the messages into do_mptransformcat like this:
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
CHAR_DATA *tempchb=ch;
char *tempvictimb=argument;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}
if ( ( victim->tempch != tempchb ) || ( victim->tempvictim != tempvictimb )
)
{
victim->tempch = tempchb;
victim->tempvictim = tempvictimb;
}
/*
To remember where in the message sequence the player is; part of the institution
of a delay
--Kris
*/
if ( victim->tempwaitb >=1 && victim->tempwaitb <=23 )
{
switch ( victim->tempwaitb )
{
case 1:
send_to_char( "\nWhat the bloody hell?!\n", victim );
TEMPWAIT_STATE(victim, 20);
break;
case 2:
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n",
victim );
TEMPWAIT_STATE(victim, 20);
break;
case 3:
send_to_char( "\nYou are standing in this field....\n", victim );
TEMPWAIT_STATE(victim, 20);
break;
case 4:
send_to_char( "\nYour ears perk-up, your eyes focus, and you crouch down
low in the grass....\n", victim );
TEMPWAIT_STATE(victim, 20);
break;
... and so on ...
if ( victim->race == RACE_CAT )
{
send_to_char( "A mystical voice says: You're already a cat, you mook!\n",
victim );
return;
}
send_to_char( "\n\nYou start to feel a strange sensation in your body....\n"
, victim );
TEMPWAIT_STATE(victim, 20);
victim->tempwaitb = 1;
victim->tempwaitc = 1;
return;
}
The problem with this is that do_mptransformcat is only called once by the mob, and thus that the sequence of messages won't be displayed.
However he tried to work around this by re-calling do_mptransformcat from the main game_loop ...
if ( FD_ISSET( d->descriptor, &in_set ) )
{
d->idle = 0;
if ( d->character )
d->character->timer = 0;
if ( !read_from_descriptor( d ) )
{
FD_CLR( d->descriptor, &out_set );
if ( d->character
&& ( d->connected == CON_PLAYING
|| d->connected == CON_EDITING ) )
save_char_obj( d->character );
d->outtop = 0;
close_socket( d, FALSE );
continue;
}
}
if ( d->character && d->character->wait > 0 )
{
--d->character->wait;
continue;
}
if ( d->character && d->character->tempwait > 0 )
{
--d->character->tempwait;
write_to_descriptor( d->descriptor,
"debug1.\n\r", 0 );
if (d->character->tempwait < 1)
{
write_to_descriptor( d->descriptor,
"debug2.\n\r", 0 );
/* if (d->character->tempwaitc == 1) */
do_mptransformcat(d->character->tempch, d->character->tempvictim);
}
continue;
}
read_from_buffer( d );
I can see what he is trying to do here, but I think that this approach is doomed to failure, particularly when do_mptransformcat is recalled from the game loop, because he has had to "dummy up" the arguments to do_mptransformcat, which then eventually gives the error messages that he reported.
My approach would be to split the delayed messages into a totally different routine, because you are really doing two things here:
- Initiating the transformation into a cat
- Displaying a message to the player every second or so
Thus, I have only the following code in do_mptransformcat:
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
progbug( "Mptransformcat - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransformcat - Victim not there", ch );
return;
}
if ( IS_NPC(victim) )
{
progbug( "Mptransformcat - Victim is NPC", ch );
return;
}
if ( victim->race == RACE_CAT )
{
send_to_char( "A mystical voice says: You're already a cat, you mook!\n", victim );
return;
}
send_to_char( "\n\nYou start to feel a strange sensation in your body....\n", victim );
victim->tempwait = 1; /* initiate message sequence */
}
Basically I deleted all the message stuff (and pasted elsewhere) - the only thing left, to initiate the messages to the player, is setting the tempwait flag to 1 (shown in bold), which means that message number 1 is due to be shown to the player.
Now we make another function "special_messages" that will display the messages in sequence (adding 1 to tempwait each time). When we get to the end of the sequence we set tempwait to zero to indicate that we have finished.
void special_messages (CHAR_DATA *ch)
{
int iLang;
switch ( ch->tempwait++ )
{
case 1:
send_to_char( "\nWhat the bloody hell?!\n", ch );
break;
case 2:
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n", ch );
break;
case 3:
send_to_char( "\nYou are standing in this field....\n", ch );
break;
... and so on ...
case 22:
send_to_char( "\n\nYou have been transformed into a CAT!!\n", ch );
ch->tempwait = 0; /* no more messages */
break;
} /* end of switch */
}
The remaining trick is to call this function each second, which can be easily done by following what game_loop does. Amongst other things, it calls "update_handler", which calls "char_check" every second.
Some way into char_check, after deciding that we have a player and not a mob, we add a couple of lines:
if (ch->tempwait)
special_messages (ch); /* extra messages for Kris */
Finally, we need to zero out ch->tempwait when a player connects, otherwise if it happened to have a non-zero value when a player connected, they might start seeing messages about turning into a cat ...
add_char( ch );
d->connected = CON_PLAYING;
ch->tempwait = 0;
I will send the complete changes to Kris as a patchfile, hopefully he will be able to get his messages working, and the technique could be used for other muds as well.
I should point out that you could use this same technique to implement things like the bard's songs Kris mentioned in earlier messages. After all, only 'wait' states 1 to 22 are used at present. You could use, say, 30 to 40, for the lines of a song.
You could also implement multi-second delays by having a second field (seconds_to_go for example). You could set this at (say) 3, and when going into the special_messages function subtract 1 from it, and when it reached zero display the message, otherwise do nothing.
Also, a more general implementation would read the messages from a file, rather than hard coding them in. You could have a file of messages, with a number in front of each one, and then read them into an array, or linked list, at mud startup time. That way you can change the messages without having to recompile every time.
You could also implement multi-second delays by having a second field (seconds_to_go for example). You could set this at (say) 3, and when going into the special_messages function subtract 1 from it, and when it reached zero display the message, otherwise do nothing.
Also, a more general implementation would read the messages from a file, rather than hard coding them in. You could have a file of messages, with a number in front of each one, and then read them into an array, or linked list, at mud startup time. That way you can change the messages without having to recompile every time.
Heyas. I've been revamping the time structure (i.e. months, years, hours, etc) on the mud. Among other things, I wanted to make it so that I could set the current year from a seperate .dat file (in case some large quest or whatever demanded that we return to a year 1 or something like that), rather than having it determined by time_info.year. The year (variable is int 'newyear') would go up by 1 whenever the month resets to 1. I haven't had any problems with this. My problem is something really basic; something a more seasoned C programmer would probably be able to do in his sleep. Basically, how do I read in the number from the next file as a number, not as a string? Obviously I can't read it in as a string; it'd display just fine, but I wouldn't be able to have the number go up when month 17 is past. So I tried doing it in db.c, and I put the following code right below the line that loads the wizlist:
log_string("Loading Current Year");
if ( ( fp = fopen( NEWYEAR_FILE, "r" ) ) != NULL )
{
top_sn = 0;
newyear = fread_number( fp );
fclose( fp );
}
else
{
bug( "Cannot open current_year.dat", 0 );
exit(0);
}
And yes, NEWYEAR_FILE is defined correctly in mud.h, as is the newyear variable. However, when the mud boots up, I get a stackdump error message when it's loading newgate.are. When I comment the code above, the mud boots up just fine. The line "newyear = fread_number( fp );" is what I'm thinking the problem is, but I'm not sure. And yes, I defined FILE *fp; at the top of the function.
Any idea what I'm doing wrong, and how I can fix it? Thanks fer the help :)
log_string("Loading Current Year");
if ( ( fp = fopen( NEWYEAR_FILE, "r" ) ) != NULL )
{
top_sn = 0;
newyear = fread_number( fp );
fclose( fp );
}
else
{
bug( "Cannot open current_year.dat", 0 );
exit(0);
}
And yes, NEWYEAR_FILE is defined correctly in mud.h, as is the newyear variable. However, when the mud boots up, I get a stackdump error message when it's loading newgate.are. When I comment the code above, the mud boots up just fine. The line "newyear = fread_number( fp );" is what I'm thinking the problem is, but I'm not sure. And yes, I defined FILE *fp; at the top of the function.
Any idea what I'm doing wrong, and how I can fix it? Thanks fer the help :)
Looks OK to me - I would run it under gdb to see exactly what line it is crashing on.
Not quite sure what you mean by that; I tried running gdb from cygwin, but all it appeared to be was a text viewer, with line #s on the left.
Anyways, these are the details about the errors. No compile errors. When aethia is booted up, it works just fine until it tries to read-in newgate.are (seems to be totally unrelated to what I'm doing!). This is the error as it displays:
[*****] FILE: newgate.are LINE: 533
[*****] BUG: Slot_lookup: bad slot 32.
0 [sig] AETHIA 890121 open_stackdumpfile: Dumping stack trace to AETHIA.EXE.stackdump
After that, aethia.exe terminates. And no, at least so far as I recall, I haven't made any changes to newgate.are. When I comment out the little block of code in db.c I listed above, this error does not occur. Heh I don't even know where to begin with this one; the syntax looks perfectly ok to me as well, and yet....
Anyways, these are the details about the errors. No compile errors. When aethia is booted up, it works just fine until it tries to read-in newgate.are (seems to be totally unrelated to what I'm doing!). This is the error as it displays:
[*****] FILE: newgate.are LINE: 533
[*****] BUG: Slot_lookup: bad slot 32.
0 [sig] AETHIA 890121 open_stackdumpfile: Dumping stack trace to AETHIA.EXE.stackdump
After that, aethia.exe terminates. And no, at least so far as I recall, I haven't made any changes to newgate.are. When I comment out the little block of code in db.c I listed above, this error does not occur. Heh I don't even know where to begin with this one; the syntax looks perfectly ok to me as well, and yet....
OK, I've worked it out. The problem is the line:
Why did you have that there? It wasn't relevant to what you were trying to do. You could almost guess what would happen.
Things like spells, skills and herbs use a "slot". In the previous few lines the spells etc. were loaded.
Then however you set "top_sn" (top slot number) to zero.
Your error message was: "Slot_lookup: bad slot 32".
In other words, by setting top_sn to zero, you "deleted" all spells, skills, etc. Thus the areas could not load.
Simply delete that line.
top_sn = 0;
Why did you have that there? It wasn't relevant to what you were trying to do. You could almost guess what would happen.
Things like spells, skills and herbs use a "slot". In the previous few lines the spells etc. were loaded.
Then however you set "top_sn" (top slot number) to zero.
Your error message was: "Slot_lookup: bad slot 32".
In other words, by setting top_sn to zero, you "deleted" all spells, skills, etc. Thus the areas could not load.
Simply delete that line.
Okay. Not extremely good at coding and know a few things and in reply to the wait thing to display messages wouldn't it be easier to display two to three lines then set a timer for so long when it runs out it prints up two to three or four more lines that are seperate from the first set of lines?
Creep
May not work but if it did I would think that'd be more sensible way to go about it, but then might be more coding... SHRUG.
Creep
May not work but if it did I would think that'd be more sensible way to go about it, but then might be more coding... SHRUG.
Depends what you mean by "set a timer". If you mean just have the server wait a couple of seconds, then all other players would freeze while the server waited for the timer to finish.
The tricky thing about timers in a server with lots of players is knowing what to do to whom when the timer expires.
The tricky thing about timers in a server with lots of players is knowing what to do to whom when the timer expires.
Would it be possible to have the first few lines done then have it check the time add so much to it then stick it somewhere that when that time comes up it does the next few lines or whatever else you have in the code?
Creep
I'm just wondering if it's possible coding wise or if it'd be efficient, not asking how to do it. Just so you know...
Creep
I'm just wondering if it's possible coding wise or if it'd be efficient, not asking how to do it. Just so you know...
It is efficient enough if you do it the way that was described earlier on in this thread.
I'm trying to make it so that a player can connect to a seperate port for telnet/java telnet. The obvious reason for this is that telnet and java, as well as some other clients, don't display large chunks of text too well. I.e. my graphic greeting screens show up as a jumbled mess of text on telnet and java, and whois also jumbles up like crap. Msp would also seem kinda weird with !!SOUND things popping up on the screen for the telnet folks.
The logical solution is to have a seperate port for telnet that players would connect to (like 4100 instead of 4000). Then, I could have an ifcheck in various places that display 'jumbled' text. This ifcheck would have it display a more concise, 'less pretty', form of text/title screen which would display correctly on java and telnet, whereas the more jumbled stuff could still be displayed on clients like zmud that show them correctly.
I looked in comm.c, and examined the init_socket and accept_new functions. However, I wasn't able to determine a reliable ifcheck from that. Could you look at that and tell me how you think that could be accomplished? Thanks :)
The logical solution is to have a seperate port for telnet that players would connect to (like 4100 instead of 4000). Then, I could have an ifcheck in various places that display 'jumbled' text. This ifcheck would have it display a more concise, 'less pretty', form of text/title screen which would display correctly on java and telnet, whereas the more jumbled stuff could still be displayed on clients like zmud that show them correctly.
I looked in comm.c, and examined the init_socket and accept_new functions. However, I wasn't able to determine a reliable ifcheck from that. Could you look at that and tell me how you think that could be accomplished? Thanks :)
There is already code that distinguishes, so I would pass a flag down.
eg.
Current code:
New code:
And then modify "accept_new" accordingly to take the extra argument, and store the "connection type" as part of the player's descriptor.
eg.
Current code:
/* Main loop */
while ( !mud_down )
{
accept_new( control );
accept_new( control2 );
accept_new( conclient);
accept_new( conjava );
New code:
// near the top ....
#define CONNECT_CONTROL 1
#define CONNECT_CONTROL2 2
#define CONNECT_CLIENT 3
#define CONNECT_JAVA 4
// .... and later on ....
/* Main loop */
while ( !mud_down )
{
accept_new( control, CONNECT_CONTROL );
accept_new( control2, CONNECT_CONTROL2 );
accept_new( conclient, CONNECT_CLIENT );
accept_new( conjava, CONNECT_JAVA );
And then modify "accept_new" accordingly to take the extra argument, and store the "connection type" as part of the player's descriptor.
I got everything except the last part. How would I go about storing the connect type as part of the descriptor?
You would modify the descriptor structure, and then store the flag in it. In mud.h, this is what it currently looks like, and I would add the line in bold:
/*
* Descriptor (channel) structure.
*/
struct descriptor_data
{
DESCRIPTOR_DATA * next;
DESCRIPTOR_DATA * prev;
DESCRIPTOR_DATA * snoop_by;
CHAR_DATA * character;
CHAR_DATA * original;
char * host;
int port;
int descriptor;
sh_int connected;
sh_int idle;
sh_int lines;
sh_int scrlen;
sh_int mxp;
sh_int connect_type;
bool fcommand;
char inbuf [MAX_INBUF_SIZE];
char incomm [MAX_INPUT_LENGTH];
char inlast [MAX_INPUT_LENGTH];
int repeat;
char * outbuf;
unsigned long outsize;
int outtop;
char * pagebuf;
unsigned long pagesize;
int pagetop;
char * pagepoint;
char pagecmd;
char pagecolor;
char * user;
int newstate;
unsigned char prevcolor;
};
In accept_new, how to I set the connect_type variable (as in ch->desc->connect_type) to the connect_type being passed into the function from the main loop? I.e. I'm guessing it'd be something like d->descriptor->connect_type = connect_type, but I'm not sure about that, and I'm also not sure where in accept_new to put it.
First you would need to change the argument list, as you are now passing another argument, so it would look like this:
Then it looks like the descriptor isn't allocated there, so you need to pass it further. So near the end you would change it to:
Similarly in new_descriptor you would change the argument list:
And further down once the descriptor was allocated you could set that variable:
You probably need to change some function prototypes in .h files, and look out for other references to new_descriptor.
void
accept_new (int ctrl , int connect_type)
{
Then it looks like the descriptor isn't allocated there, so you need to pass it further. So near the end you would change it to:
new_descriptor (newdesc , connect_type);
Similarly in new_descriptor you would change the argument list:
void
new_descriptor (int new_desc, int connect_type))
{
And further down once the descriptor was allocated you could set that variable:
CREATE (dnew, DESCRIPTOR_DATA, 1);
dnew->next = NULL;
dnew->descriptor = desc;
dnew->connect_type = connect_type;
You probably need to change some function prototypes in .h files, and look out for other references to new_descriptor.
I've recently been approached by someone trying to setup a smaug server. I pointed him to your site to download the win32 ported version (since he uses cygwin on a windows machine like I do). He described some problems with compiling the source, however, and I eventually had him upload the source to me. I had the same problems. I then downloaded the source from the website myself, and still the same problems.
Basically, the problem errors, which occur in several different functions, tend to run as follows: implicit declaration of function 'RENAME', implicit declaration of function 're_exec', implicit declaration of function 'crypt', (on the same line as the crypt error) assignment makes pointer from integer without a cast.
These are all warning errors, but once it tries to link together the object files, those errors come back again, this time aborting the compile. This is the same version of cygwin I've always had, and this didn't happen when I first downloaded and compiled smaug from your site back in febuary 2001. Also, I don't get any of these warning errors in my mud's source, which is the same I downloaded from your site back then, only heavily modified by me in the 14 months or so since then.
I just wanted to let ya know about that. Perhaps you may wanna try compiling the dist on your site with cygwin yourself and see if you get the same errors? It's either bugged, or cygwin has decided to play favorites for me and the person I was offering assistance to. Thanks for taking a look at this for me :)
Basically, the problem errors, which occur in several different functions, tend to run as follows: implicit declaration of function 'RENAME', implicit declaration of function 're_exec', implicit declaration of function 'crypt', (on the same line as the crypt error) assignment makes pointer from integer without a cast.
These are all warning errors, but once it tries to link together the object files, those errors come back again, this time aborting the compile. This is the same version of cygwin I've always had, and this didn't happen when I first downloaded and compiled smaug from your site back in febuary 2001. Also, I don't get any of these warning errors in my mud's source, which is the same I downloaded from your site back then, only heavily modified by me in the 14 months or so since then.
I just wanted to let ya know about that. Perhaps you may wanna try compiling the dist on your site with cygwin yourself and see if you get the same errors? It's either bugged, or cygwin has decided to play favorites for me and the person I was offering assistance to. Thanks for taking a look at this for me :)
I seem to recall going over this a few times before. Did you search for re_exec on the forum? Anyway, it will compile OK, I have it running here. Check out the "makefile" for what to comment in/out.
Failing that, the only place in the entire code re_exec is used is in this small function:
It is only for checking for profanities, and in the WIN32 version I just commented out the re_exec anyway. So, to get it to compile and link just delete the lines between #ifndef and #endif.
Failing that, the only place in the entire code re_exec is used is in this small function:
int is_profane (char *what)
{
#ifndef WIN32
int ret;
ret = re_exec(what);
if (ret==1)
return(1);
#endif
return(0);
}
It is only for checking for profanities, and in the WIN32 version I just commented out the re_exec anyway. So, to get it to compile and link just delete the lines between #ifndef and #endif.
I uncommented the part of makefile about the crypt thing, and commented out the ifdef part of is_profane. However, the implicit declaration of crypt error, and the implicit declaration of RENAME error are still popping up. I reviewed the forum as you suggested, and found some posts describing the same problem. However, there was a whole jumble of replies and replies to those replies; in short, I can't even figure out if anyone came up with a fix there or not. The re_exec thing is fixed, but what do I do about the crypt and RENAME thing? If I get it fixed and working, you may wanna consider putting the fixed version of the dist on the site, so other ppl using cygwin can compile it.
Exactly which SMAUG download did you compile? My notes about "compiling" which use SMAUG (with MXP) were done with Cygwin, and I did it from start to finish, without errors. Check out that page.
This was the source-only download without MXP. I could try the one with MXP, but it may be a good idea to be sure that the non-MXP one is compilable as well, since someone may bor whatever reason want one without it.
Try the MXP one - the only real difference, apart from the MXP stuff, is a slightly different Makefile. Or at least, copy the makefile.cgywin and use that. The difference between the old Makefile and the Cygwin one are:
17c17
< #NEED_REG = -lgnuregex
---
> NEED_REG = -lregex
20c20
< #NEED_CRYPT = -lcrypt
---
> NEED_CRYPT = -lcrypt
29c29
< L_FLAGS = $(OPT_FLAG) $(PROF) $(SOLARIS_LINK) $(NEED_CRYPT)
---
> L_FLAGS = $(OPT_FLAG) $(PROF) $(SOLARIS_LINK) $(NEED_CRYPT) $(NEED_REG)
65,66c65,66
< chmod g+w smaug
< chmod a+x smaug
---
> chmod g+w smaug.exe
> chmod a+x smaug.exe
I tried making the changes you suggested, and no effect. I then tried using the makefile.cygwin file instead, and still no effect. Still having the problems with crypt and RENAME.
Search the forum for posts about crypt. I think a while ago the crypt library had to be moved or something.
I don't want to get too bogged down about this. The source I posted compiles using a recent version of Cygwin. You may need to tweak makefile settings or make sure you have installed a full Cygwin, but after that, you need to do a bit of searching to work out the problem.
I don't want to get too bogged down about this. The source I posted compiles using a recent version of Cygwin. You may need to tweak makefile settings or make sure you have installed a full Cygwin, but after that, you need to do a bit of searching to work out the problem.
It might be good to start a new subject on the forum next time. This one is already 5 pages which makes it hard for people to just quickly browse it.