|
1. switch case help
|
|
Sun Jul 29, 2007 [10:23 PM]
|
whpsh
Email not supplied
member since: Jul 21, 2007
|
Reply
|
|
CircleMUD (not really important, but for referance)
In a function I'm getting a case not matching up with a passed variable. I've included an output string and the numbers are equal ... here's the code (minus irrelevant stuff). The CLASS_XX are defined elsewhere as 0,1,2,3 (respectively). My problem child is class_num
byte saving_throws(int class_num, int type, int level) { /* snip */ switch (class_num) { case CLASS_MAGIC_USER: /*defined as 0*/ /*doing some stuff*/ break; case CLASS_CLERIC: /*defined as 1*/ /*doing some stuff*/ break; case CLASS_THIEF: /*defined as 2*/ /*doing some stuff*/ break; case CLASS_WARRIOR: /*defined as 3*/ /*doing some stuff*/ break; default: /*The error message I'm getting*/ break; }
After some work, I've got the error message to output the value of class_num (3) and the value of CLASS_WARRIOR (3). I've even tried changing the CLASS_XX to straight integers and it still doesn't match up. The switch statement I'm replacing uses these exact same variables and defines in the exact same way ...
What the heck am I missing??
|
|
|
|
|
2. the function doing the calling, in case it is important
|
|
Sun Jul 29, 2007 [10:29 PM]
|
whpsh
Email not supplied
member since: Jul 21, 2007
|
In Reply To
Reply
|
|
int mag_savingthrow(struct char_data *ch, int type, int modifier) { /* NPCs use warrior tables according to some book */ int class_sav = CLASS_WARRIOR; int save;
if (!IS_NPC(ch)) class_sav = GET_CLASS(ch);
save = saving_throws(class_sav, type, GET_LEVEL(ch)); save += GET_SAVE(ch, type); save += modifier;
/* Throwing a 0 is always a failure. */ if (MAX(1, save) < rand_number(0, 99)) return (TRUE);
/* Oops, failed. Sorry. */ return (FALSE); }
|
|
|
|
|
3. RE: the function doing the calling, in case it is important
|
|
Sun Jul 29, 2007 [11:12 PM]
|
Lobotomy
Email not supplied
member since: May 25, 2007
|
In Reply To
Reply
|
|
int mag_savingthrow(struct char_data *ch, int type, int modifier)
Just a question of curiosity, why are you using the struct keyword in a function define when you can just define it elsewhere and simply call char_data *ch by itself? I'm just perplexed by that, is all.
Anyways, wagering a guess based on what you've posted, I'd say your problem might lie in the GET_CLASS function. Check it and make sure it isn't using number ranges different from those you've defined, or that it isn't doing anything else you don't want it to do.
|
|
|
|
|
4. RE: switch case help
|
|
Mon Jul 30, 2007 [5:04 AM]
|
brakai
Email not supplied
member since: Aug 2, 2004
|
In Reply To
Reply
|
It's often useful to test your code in an isolated environment. For example, here's a test prog:
#include <stdio.h>
#define CLASS_MAGIC_USER 0
#define CLASS_CLERIC 1
#define CLASS_THIEF 2
#define CLASS_WARRIOR 3
void saving_throws( int class_num )
{
printf( "saving_throws: received %d\n", class_num );
switch( class_num )
{
case CLASS_MAGIC_USER:
printf( "saving_throws: inside CLASS_MAGIC_USER\n" );
break;
case CLASS_CLERIC:
printf( "saving_throws: inside CLASS_CLERIC\n" );
break;
case CLASS_THIEF:
printf( "saving_throws: inside CLASS_THIEF\n" );
break;
case CLASS_WARRIOR:
printf( "saving_throws: inside CLASS_WARRIOR\n" );
break;
default:
printf( "saving_throw: Error, invalid parameter: %d!\n", class_num );
break;
}
}
int main( int argc, char *argv[] )
{
printf( "Main: Starting tests.\n---------------------\n" );
int n = 0;
for( n = 0; n < 5; ++n )
{
printf( "Main: passing value %d\n", n );
saving_throws( n );
}
printf( "--------------------\nMain: all done. Bye!\n" );
return 0;
}
Running it yields the following output:
Main: Starting tests.
---------------------
Main: passing value 0
saving_throws: received 0
saving_throws: inside CLASS_MAGIC_USER
Main: passing value 1
saving_throws: received 1
saving_throws: inside CLASS_CLERIC
Main: passing value 2
saving_throws: received 2
saving_throws: inside CLASS_THIEF
Main: passing value 3
saving_throws: received 3
saving_throws: inside CLASS_WARRIOR
Main: passing value 4
saving_throws: received 4
saving_throw: Error, invalid parameter: 4!
--------------------
Main: all done. Bye!
As you can see all values match up as they're passed. So I must agree that the GET_CLASS macro is the problem, unless some variables are changed in sections that you've snippet away.
|
|
|
|
|
5. RE: switch case help
|
|
Mon Jul 30, 2007 [8:08 AM]
|
whpsh
Email not supplied
member since: Jul 21, 2007
|
In Reply To
Reply
|
|
First, thanks for the quick replies ... I love this place!
I followed your advice and added the variables received by the function into the error message.
When I cast a spell, I get the following error message in the logs:
SYSERR: Class is undefined.33
where the first 3 is class_num and the second 3 is the integer equivalent of CLASS_WARRIOR.
I tracked down GET_CLASS(ch) and it is: #define GET_CLASS(ch) ((ch)->player.chclass)
Complete function follows:
byte saving_throws(int class_num, int type, int level) { char save_strength; save_strength = 'w';
/* Error Catching code */ char strMessage[75]; strMessage = "SYSERR: Class is undefined."; strMessage[28] = class_num + '0'; strMessage[29] = CLASS_WARRIOR + '0'; /* End Error Catching */
switch (class_num) { case CLASS_MAGIC_USER: /* Defined as 0 */ switch (type) { case SAVING_PARA: /* Fortitude Save */ save_strength = 'w'; break; case SAVING_ROD: /* Reflex Save */ save_strength = 'w'; break; case SAVING_PETRI: /* Will save */ save_strength = 's'; break; case SAVING_BREATH: /* To be deleted */ save_strength = 'w'; break; case SAVING_SPELL: /* To be deleted */ save_strength = 'w'; break; default: log ("SYSERR: Save undefined for CLASS_MAGIC_USER."); break; } case CLASS_CLERIC: /* Defined as 1 */ switch (type) { case SAVING_PARA: /* Fortitude Save */ save_strength = 's'; break; case SAVING_ROD: /* Reflex Save */ save_strength = 'w'; break; case SAVING_PETRI: /* Will Save */ save_strength = 's'; break; case SAVING_BREATH: /* To be deleted */ save_strength = 'w'; break; case SAVING_SPELL: /* To be deleted */ save_strength = 'w'; break; default: log ("SYSERR: Save undefined for CLASS_CLERIC."); break; } case CLASS_THIEF: /* Defined as 2 */ switch (type) { case SAVING_PARA: /* Fortitude Save */ save_strength = 'w'; break; case SAVING_ROD: /* Reflex Save */ save_strength = 's'; break; case SAVING_PETRI: /* Will Save */ save_strength = 'w'; break; case SAVING_BREATH: /* To be deleted */ save_strength = 'w'; break; case SAVING_SPELL: /* To be deleted */ save_strength = 'w'; break; default: log ("SYSERR: Save undefined for CLASS_THIEF."); break; } case CLASS_WARRIOR: /* Defined as 3 */ switch (type) { case SAVING_PARA: /* Fortitude Save */ save_strength = 's'; break; case SAVING_ROD: /* Reflex Save */ save_strength = 'w'; break; case SAVING_PETRI: /* Will Save */ save_strength = 'w'; break; case SAVING_BREATH: /* To be deleted */ save_strength = 'w'; break; case SAVING_SPELL: /* To be deleted */ save_strength = 'w'; break; default: log ("SYSERR: Save undefined for CLASS_WARRIOR"); break; } default: log (strMessage); break; }
switch (save_strength) { case 'w': /* Weak Saving Throw Progression */ switch (level) { case 0: return 90; case 1: return 70; case 2: return 69; /* snipped out levels */ case 39: return 0; case 40: return 0; default: log ("SYSERR: Missing level for weak saving throw progression."); break; } case 's': /* Strong Saving Throw Progression */ switch (level) { case 0: return 90; case 1: return 55; case 2: return 53; /* snipped out levels */ case 39: return 0; case 40: return 0; default: log ("SYSERR: Missing level for strong saving throw progression."); break; } default: log ("SYSERR: Unable to determine saving throw strength."); break; } /* End of switch (save_strength) */
/* if this entry is found in the log then this function is not exiting like it should */ log ("SYSERR: byte saving_throws is not functioning properly."); return 90;
} /* Close of saving_throws *
|
|
|
|
|
6. switch case fixed ... sort of
|
|
Mon Jul 30, 2007 [9:27 AM]
|
whpsh
Email not supplied
member since: Jul 21, 2007
|
In Reply To
Reply
|
|
I don't like it but by replacing the switch case with a series of if statements, I've fixed the bug.
I can't see it, but it might be that the switch case was executing properly but it sent out one of the error messages anyway (*shrug*)
Anyway, if anyone can figure out what happened, please let me know. I'd really like to put a switch case back in (easier for adding new classes later)
Thanks for all the help
|
|
|
|
|
7. RE: switch case help
|
|
Mon Jul 30, 2007 [12:27 PM]
|
Vopisk
Email not supplied
member since: Jul 25, 2003
|
In Reply To
Reply
|
I tracked down GET_CLASS(ch) and it is: #define GET_CLASS(ch) ((ch)->player.chclass) Is it possible that in the character/player structure chclass uses a different enumeration than you're trying to use in this function? Or perhaps your CLASS_WARRIOR define is somehow not being properly terminated? It would seem to me that case CLASS_WARRIOR is obviously not identifying as case 3, as it should, and you're bleeding through to your default. You logging tells us that you are in fact getting a 3 passed into the function so... Yeah, as near as I can figure, you're looking at an issue with the define of CLASS_WARRIOR, if I had to guess.
|
|
|
|
|
8. RE: switch case help
|
|
Mon Jul 30, 2007 [3:44 PM]
|
TDM_2
Email not supplied
member since: Jul 30, 2007
|
In Reply To
Reply
|
|
The answer to your question is quite simple - you don't have a break; command after your case CLASS_WARRIOR. For that matter, you don't have them after any of the cases in your primary switch. The switch statements nested inside your class CLASS_WHATEVER's are all constructed properly, but you forgot to put a break after each one. This means that you should be getting the correct saving throw values for your warriors, but you'll also get the error message at the end. As a matter of fact, since you don't have breaks after any of those cases, each class is going to be using the warrior saving throw progressions, since that's the last assignment that the code will fall through to.
|
|
|
|
|
9. Son of a goat ...
|
|
Mon Jul 30, 2007 [4:17 PM]
|
whpsh
Email not supplied
member since: Jul 21, 2007
|
In Reply To
Reply
|
|
Thanks TDM_2()
If it was a snake, it would've bit me.
I'll give it a go as soon as I get home.
|
|
|
|
|