21 Feb, 2009, boblinski wrote in the 1st comment:
Hi there,

I've got a new skill called "read thoughts" it's an automatic skill, and I want it to be successful in reading peoples "thinks" the amount of their skill % minus 10 percent..

this is what I have:

Quote

But it seems not to take into account the '-10' and seems to work simply the the skill% alone.
21 Feb, 2009, David Haley wrote in the 2nd comment:
The condition you have written will be true when the skill value is greater than 1d100-10. It's unclear to me from what you wrote if that's what you wanted. By adding -10, you've made the check easier, because there is a greater chance that the skill value will be higher than the die roll.
21 Feb, 2009, Skol wrote in the 3rd comment:
bob, there's a technique you can use to 'see' what comes out, it's spammy, but will tell you the values that are coming up.

`char buf[MAX_STRING_LENGTH];int skill, percent;skill = get_skill (ch, gsn_read_thoughts);percent = number_percent();// I added returns to the next part just so it's more readable.sprintf (buf, "Your read thoughts skill is %d, percent was %d (-10 = %d). ""You %s the check.\r\n", skill, percent, percent - 10, skill >= percent - 10 ? "passed" : "failed");send_to_char (buf, ch);// The actual code to DO whatever read thoughts does goes hereif (skill >= percent - 10){  // Do the success stuff}else{  // The fail stuff here}`

Sometimes it's helpful to 'see' the checks. The above is just doing the computations, but saving them as int's first and showing you the computation (and what the skill/rolled percentage was).
21 Feb, 2009, boblinski wrote in the 4th comment:
`void do_think (CHAR_DATA *ch, char *argument){	DESCRIPTOR_DATA *d;     CHAR_DATA *vch;    char buf[MAX_STRING_LENGTH];    if (argument[0] == '\0')    {        send_to_char ("What are you thinking?\n\r", ch);        return;    }    sprintf(buf, "{6%s thinks '{7%s{6'{x\n\r", ch->name, argument);	for(d = descriptor_list; d != NULL; d = d->next)	{	    if(  d->connected == CON_PLAYING	    && IS_IMMORTAL(d->character) )	   {      	    send_to_char(buf, d->character);	   }	}	for(vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)     { 		 if (vch->level < 52			 && vch->name != ch->name)		 {		 if(get_skill(vch, gsn_read_thoughts) > 1 			 && get_curr_stat(vch, STAT_INT) >= get_curr_stat(ch, STAT_INT) 			 && get_skill(vch, gsn_read_thoughts) > number_percent()			 && vch->level+2 >= ch->level)        { 			 send_to_char(buf, vch);			 check_improve (vch, gsn_read_thoughts, TRUE, 2);			         }		}		    }			act ("{6You think '{7\$T{6'{x", ch, NULL, argument, TO_CHAR);return;}`

Thats the whole segment..

will this mean that a Max_level with the skill at 100% be successful 100% of the time?

What I want is to make it that you can only ever be successful at "read_thoughts" 90% of the time..
21 Feb, 2009, David Haley wrote in the 5th comment:
Break this down to figure out what you need to do.

If my skill is 100, and I'm checking that against 1d100 – can I fail?
If my skill is 90, and I'm checking that against 1d100 – can I fail?
If my skill is 100, and I'm checking that against 1d100-10 – can I fail?
If my skill is 90, and I'm checking that against 1d100-10 – can I fail?

Think of the skill as a probability of success, and the roll as a check against that probability. If you add to or subtract from the probability of success, what happens? If you add to or subtract from the roll, what happens?
22 Feb, 2009, boblinski wrote in the 6th comment:
This might sound silly, but I'm not quite sure what you mean by '1d100'…

If I want a skill to work -the skill %- minus ten.. how do I write that?
22 Feb, 2009, David Haley wrote in the 7th comment:
1d100 means roll one 100-sided die. (Obviously you have not played pen-and-paper RPGs! :tongue:)
1d100-10 means roll the 100-sided and subtract 10 from the result.

The answer to your question lies in the questions I asked you :smile: Just work through them…
22 Feb, 2009, Sharmair wrote in the 8th comment:
1d100 comes from table top games like D&D that use dice of different number of sides
for things. It is saying to throw a 100 sided dice one time, so the range is 1 to 100
(note that your number_percent() probably gives that, though I have seen some give
0 to 99).

I would say if you want the chance to be 10% less than your skill%, you would modify
your chance threshold by subtracting 10 from the skill term:
`get_skill(vch, gsn_read_thoughts)-10 >= number_percent()`

Note this assumes your number_percent() is 1 - 100, if it is 0 - 99 replace the >=
with >.
22 Feb, 2009, boblinski wrote in the 9th comment:
`&& get_skill(vch, gsn_read_thoughts) > number_percent()`

So what exactly is this line doing/saying?
22 Feb, 2009, Kline wrote in the 10th comment:
It is calling get_skill() to retrieve the skill of vch for read_thoughts.
`get_skill(vch,gsn_read_thoughts)`
Then it is comparing this number to see if it is > than
`number_percent()`
which generates a random number from 1-100.

So -> Is victim's skill of read_thoughts greater than a random number between 1 and 100?
21 May, 2009, boblinski wrote in the 11th comment:
Well, I have another issue with how I am writing my code… figured I'd just add to this old post, rather then spam out the forum with yet another topic from Bob!

Anyway.. what I'm trying to do.. is check to see if a player is a certain class, and if so.. do something..

This is how I attempted to do it..
(I don't think it matters, but this code is in my scan.c file under do_scan()
`if (*class_table[ch->class].name == ranger		&& ch->in_room->sector_type == SECT_FOREST)       /*line 73*/	{		if (ch->level < 13)		{			shallow = 2;		}		else if (ch->level < 26)		{			shallow = 3;		}		else if (ch->level < 39)		{			shallow = 4;		}		else			shallow = 5;	}`

This is the error I'm getting:
Quote
gcc -Wall -O -ggdb -DNOCRYPT -DQMFIXES -c -o obj/scan.o scan.c
scan.c: In function `do_scan':
scan.c:73: error: `ranger' undeclared (first use in this function)
scan.c:73: error: (Each undeclared identifier is reported only once
scan.c:73: error: for each function it appears in.)
make: *** [obj/scan.o] Error 1

I think it's because it's looking for a number (int) ?
21 May, 2009, Sandi wrote in the 12th comment:
A couple of suggestions:

Get a book on C coding. I didn't, and it took WAY longer for me to develop my MUD than it would otherwise. It should be obvious to you by now that C isn't something you can learn from context.

When modifying ROM, stick to the conventions that are already there. Use the macros and functions that exist. They are well designed, and will save you from errors that you might make taking shortcuts.

In that short little command I wrote for you in the other thread, I think the only lines I actually wrote were 'int sn;' and 'done = TRUE'. Everything else was cut and paste.

Now, having said that, my suggestion for fixing your problem is to expand the macro sets in merc.h with two they obviously missed: races and classes. That is, find a nice spot in merc.h, like near the top where they '#define' other stuff, and add your races and classes, defined as their integer value. From then on, you never have to remember the numbers or stand on your head to match the names.

Then, you can simply do: if ( ch->class == RANGER …..
21 May, 2009, Davion wrote in the 13th comment:
Sandi's most definitely right on all accounts :). All I can add is the reason your code failed to compile. (Please read my whole post before touching your code :P)

`if (*class_table[ch->class].name == ranger && ch->in_room->sector_type == SECT_FOREST)      /*line 73`

In that code, you have 'ranger' standing all by itself. What you're saying is if the name is equal to the variable 'ranger'. Seeing as no such variable exists, the compiler is looking at this going *guh* ;). The way to get this to compile would be to change ranger from a variable, to a literal by surrounding it with quotation marks, and remove the dereferencing *.

`if (class_table[ch->class].name == "ranger" && ch->in_room->sector_type == SECT_FOREST)      /*line 73`

This is still technically not correct. C has no way to compare entire strings with a simple operator like == (as a string in C is simply just an array). You'd have to use one of the built in comparing functions with C, such as strcmp or strcasecmp. So! Assuming you actually want to do it this way (there are instances, I'm sure), the correct way would be
`if( !strcasecmp(class_table[ch->class].name, "ranger") && ch->in_room->sector_type == SECT_FOREST)`
21 May, 2009, Hades_Kane wrote in the 14th comment:
But yeah, I agree with Sandi, the easiest way for class and race checks are using macros.

I have them defined in my code like:

`#define IS_PRIEST(ch)	(  ch->class == 17 )#define IS_BERSERKER(ch)(  ch->class == 18 )#define IS_MFIGHTER(ch)	(  ch->class == 19 )#define IS_DRAGOON(ch)	(  ch->class == 20 )#define IS_KENSAI(ch)	(  ch->class == 21 )#define IS_HUMAN(ch)		(ch->race == 1)#define IS_GUADO(ch)		(ch->race == 2)#define IS_CETRA(ch)		(ch->race == 3)#define IS_MOOGLE(ch)		(ch->race == 4)#define IS_ROBOT(ch)		(ch->race == 5)#define IS_RONSO(ch)		(ch->race == 6)#define IS_BEAST(ch)		(ch->race == 7)#define IS_REPTITE(ch)		(ch->race == 8)#define IS_DWARF(ch)		(ch->race == 9)`

Now, rather than having to remember numbers or do string comparisons, I could just go:

`#  if (IS_RANGER(ch) && ch->in_room->sector_type == SECT_FOREST)      /*line 73*/`

See how much less confusing and easier that is?

I highly recommend you get used to using macros and add ones as you think of things that would be easier that way. It's much easier to remember them, and if for some reason a class or race value changes or something, its much easier to change one number in merc.h than it is to crawl through your code changing everything that affects.

Also, when you are trying to do something, try really hard to think of something that already works that way or similar in the code, and if you can find something, stare at the function for a while and see if you can't figure out what is going on and how that relates to what you are trying to do. I've found in my days of basically "teaching myself" how to code for a ROM MUD, that most of the answers I seek are found somewhere in the code, I just have to find where.
21 May, 2009, David Haley wrote in the 15th comment:
boblinski said:
`if (ch->level < 13)		{			shallow = 2;		}		else if (ch->level < 26)		{			shallow = 3;		}		else if (ch->level < 39)		{			shallow = 4;		}		else			shallow = 5;`

shallow = MIN((ch->level / 13) + 2, 5);
21 May, 2009, KaVir wrote in the 16th comment:
Davion said:
C has no way to compare entire strings with a simple operator like == (as a string in C is simply just an array).

It's worth noting that class_table[ch->class].name == "ranger" will probably work, as long as you originally initialised it to a literal constant, because both will usually end up referencing the same address in the data segment.

Suffice to say this is a bad idea. But it can be a useful trick for fast string comparisons if you decide to implement a shared string library.
21 May, 2009, David Haley wrote in the 17th comment:
There is sometimes a fine line between truth and evil; I think that this might have crossed it. :rolleyes:
21 May, 2009, Brigan wrote in the 18th comment:
Something that I didn't see mentioned here is that ROM already has a class_lookup function that can be used to compare a character's class to a string.

So this code:

`if (*class_table[ch->class].name == ranger    && ch->in_room->sector_type == SECT_FOREST)`

Could just be changed to:

`if (ch->class == class_lookup("ranger"))    && ch->in_room->sector_type == SECT_FOREST)`

Might not be as beneficial as adding in the class defines, but it is already coded and would work just fine.

Best of luck.

- Brigan
21 May, 2009, Skol wrote in the 19th comment:
Yeah, bob, do IS_RANGER as the last one Brigan posted, so your macro would be like #define IS_RANGER (ch->class == class_lookup ("ranger"); blah blah blah etc.

Quote
Get a book on C coding. I didn't, and it took WAY longer for me to develop my MUD than it would otherwise. It should be obvious to you by now that C isn't something you can learn from context.

When modifying ROM, stick to the conventions that are already there. Use the macros and functions that exist. They are well designed, and will save you from errors that you might make taking shortcuts.
21 May, 2009, David Haley wrote in the 20th comment: