A little trouble

Posted by Ithildin on Sat 04 Dec 2004 03:51 AM — 8 posts, 26,014 views.

USA #0
Ok, I'm having a small problem that crashes the mud. For lack of knowledge about the "For" loops, I'm not sure what is going on.

Here's the code:


for (level = 9; level > 0; level--) 
  {
  marker = FALSE;
  for (sn = 1; sn < MAX_SKILL; sn++)
    {
    if (skill_table[sn]->spell_level != level)    <---trouble line
      continue;
    total = 0;
    for (i = 0; i < MAX_MEM_SPELLS; i++)
      {
      if ((ch->pcdata->memorized[i] != 0)
        && (ch->pcdata->memorized[i] == sn))
        {
        total++;
        none = 0;
        }
      }
    if (total == 0)
      continue;
    if (marker) 
      {
      if (total < 2)
        sprintf(buf, "%s            %s\r\n", buf,
                skill_table[sn]->name);
      else
        sprintf(buf, "%s            %s (x%d)\r\n",buf,
                skill_table[sn]->name, total);
      } 
    else 
      {
      if (total < 2)
        sprintf(buf, "%s (level %2d) %s\r\n", buf,
                skill_table[sn]->spell_level,
                skill_table[sn]->name);
      else
        sprintf(buf, "%s (level %2d) %s (x%d)\r\n",buf,
                skill_table[sn]->spell_level,
                skill_table[sn]->name, total);
      marker = TRUE;
      }
    }
  }


I have 9 spell levels for my spells. The output should look like this when done correctly:


You have memorized the following spells:
 (level  5) blindness (x2)
 
 
And you are currently memorizing the following spells:
    1 seconds ( 5) blindness.
   21 seconds ( 5) blindness.
   25 seconds ( 1) armor.
   29 seconds ( 1) armor.
 
You can memorize, 10 1st, 9 2nd, 8 3rd, 8 4th, 3 5th, 6 6th, 6 7th, 6 8th, 5 9th level spell(s).


The problem is the line:


 if (skill_table[sn]->spell_level != level)


This is what crashes the mud. if I comment it out, it works, but I do not get the desired affect. I get this:


You have memorized the following spells:
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 
And you are currently memorizing the following spells:
    1 seconds ( 5) blindness.
   21 seconds ( 5) blindness.
   25 seconds ( 1) armor.
   29 seconds ( 1) armor.
 
You can memorize, 10 1st, 9 2nd, 8 3rd, 8 4th, 3 5th, 6 6th, 6 7th, 6 8th, 5 9th level spell(s).


Any thoughts on what if statement is doing wrong?

I'm guessin


Amended on Sat 04 Dec 2004 05:07 AM by Nick Gammon
USA #1
What if skill_table[sn] is null? (-1) Then it may crash. Make a ifcheck for that.
USA #2
like this?


 if (skill_table[sn]->spell_level != level || skill_table[sn]->spell_level == NULL)


or make a completely new ifcheck like this:


if (skill_table[sn]->spell_level == NULL)
continue;
if (skill_table[sn]->spell_level != level)
continue;

what it's lookin for is how many times to print it out(or something like that) 


You have memorized the following spells:
 (level  5) blindness (x2)
 
instead of


You have memorized the following spells:
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)
 (level  5) blindness (x2)



EDIT
__________________________

Those ifchecks didn't work right.
Amended on Sat 04 Dec 2004 05:14 AM by Ithildin
USA #3
Hmm, no like...
if ( !skill_table[sn] || skill_table[sn] == -1 )


That should do it, if that is the problem.
USA #4
nope, that's not the problem. the problem is that it's seeing if the skill_table[sn]->spell_level is not equal to level, and level is that FOR statement. I have 9 levels of spells that the player gets as he gets higher.

I'm not really sure how to explain it better. It's printing out 9 spells in the output, instead of just printing out one.


what I'm wanting...

Your have memorized the following spells:
 (level  4) flamestrike
            virtue
 (level  1) ballistic attack


You can memorize, 11 1st, 9 2nd, 8 3rd, 6 4th, 7 5th, 6 6th, 6 7th, 6 8th, 5 9th level spell(s).


what I'm getting...

Your have memorized the following spells:
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike
 (level  4) flamestrike


You can memorize, 11 1st, 9 2nd, 8 3rd, 6 4th, 7 5th, 6 6th, 6 7th, 6 8th, 5 9th level spell(s).

i've come so far on this...i just......have....too......finish......it.....
Amended on Sat 04 Dec 2004 06:37 AM by Ithildin
USA #5
Try:

for (level = 9; level > 0; level--) 
  {
  marker = FALSE;
  for (sn = 1; sn < MAX_SKILL; sn++)
    {
    if ( !skill_table[sn] || skill_table[sn]->spell_level != level )
      continue;
    ...


You need to first check if there is no skill at that table entry, and then check to see if the skill has the right level.

Indeed, if you count the output lines, the spell is printed out 9 times: one for each level in the foor loop. (9, 8, 7, 6, 5, 4, 3, 2, 1) So, you need that level check, but before you can make it, you need to check to see that you're not accessing an invalid skill entry.

If you want to split it you can, but you have to do it like this:
if (skill_table[sn] == NULL)
  continue;
if (skill_table[sn]->spell_level != level)
  continue;

Note that we're not checking for a null spell_level, but for a null pointer to a skill structure.
USA #6
Ok, that worked, but i'm getting an messed up output. This has been doing this since i've put it in, figured it might go away after i fixed that if statement. The first output is what happens when i first type mem, but the second output is when i type mem again.


You have memorized the following spells:
 (level  5) blindness (x2)
 
And you are currently memorizing the following spells:
    1 seconds ( 5) blindness.
   21 seconds ( 5) blindness.
   25 seconds ( 1) armor.
   29 seconds ( 1) armor.
 
You can memorize, 10 1st, 9 2nd, 8 3rd, 8 4th, 3 5th, 6 6th, 6 7th, 6 8th, 5 9th level spell(s).
 
<1007hp 507m 1240mv> 
<   > mem
You have memorized the following spells:
 
You can memorize, 10 1st, 9 2nd, 8 312408 4txÍ" (level  5) blindness (x2)
 
And you are currently memorizing the following spells:
    1 seconds ( 5) blindness.
   21 seconds ( 5) blindness.
   25 seconds ( 1) armor.
   29 seconds ( 1) armor.
 
You can memorize, 10 1st, 9 2nd, 8 3rd, 8 4th, 3 5th, 6 6th, 6 7th, 6 8th, 5 9th level spell(s).


Here's the code for that part.


                if (none)
                        sprintf(buf, "%sNone.\r\n\r\n", buf);
                else

				sprintf(buf, "%s\r\n", buf);
                send_to_char(buf, ch);

                if (ch->pcdata->memorizing[0] != 0) 
				{
                        strcpy(buf, "");
        sprintf(buf, "%sAnd you are currently memorizing the following spells:\r\n", buf);
                        time_memming = ch->mem_time;
                        for (i = 0; i < MAX_MEM_SPELLS; i++) 
						{
                                if (ch->pcdata->memorizing != 0) 
								{
                                        sprintf(buf, "%s %4d seconds (%2d) %s.\r\n",
                                                buf,
                                                time_memming,
                                        skill_table[ch->pcdata->memorizing]->spell_level,
										skill_table[ch->pcdata->memorizing]->name);
                                        
										if (ch->pcdata->memorizing[i + 1] != 0)
                time_memming += skill_table[ch->pcdata->memorizing[i + 1]]->spell_level * 4;
                                }
                        }
                        send_to_char(buf, ch);
                }
                strcpy(buf, "");
				sprintf(buf, "%s\r\n&wYou can memorize", buf);
                if (can_mem(ch, 1))
                        sprintf(buf, "%s, %d 1st", buf, free_spells(ch, 1));
                if (can_mem(ch, 2))
                        sprintf(buf, "%s, %d 2nd", buf, free_spells(ch, 2));
                if (can_mem(ch, 3))
                        sprintf(buf, "%s, %d 3rd", buf, free_spells(ch, 3));
                if (can_mem(ch, 4))
                        sprintf(buf, "%s, %d 4th", buf, free_spells(ch, 4));
                if (can_mem(ch, 5))
                        sprintf(buf, "%s, %d 5th", buf, free_spells(ch, 5));
                if (can_mem(ch, 6))
                        sprintf(buf, "%s, %d 6th", buf, free_spells(ch, 6));
                if (can_mem(ch, 7))
                        sprintf(buf, "%s, %d 7th", buf, free_spells(ch, 7));
                if (can_mem(ch, 8))
                        sprintf(buf, "%s, %d 8th", buf, free_spells(ch, 8));
                if (can_mem(ch, 9))
                        sprintf(buf, "%s, %d 9th", buf, free_spells(ch, 9));
                sprintf(buf, "%s level spell(s).\r\n", buf);
                send_to_char(buf, ch);

if ((ch->position == POS_RESTING) && (ch->mem_time > 0) && (!xIS_SET(ch->act, PLR_MEMING))) {
                        send_to_char("You continue memorizing.\r\n", ch);
                        xSET_BIT(ch->act, PLR_MEMING);
                }
                return;


Any thoughts? I figure there's an extra buf somewhere in there.
USA #7
There are a few things to look for:

- make sure your buffer is big enough
- make sure that you empty it whenever you want to start a new one (e.g. strcpy(buf, ""); )

Also, I noticed that you do a lot of things like this:
sprintf(buf, "%s level spell(s).\r\n", buf);
What you actually should be doing is this:
strcat(buf, " level spell(s).\r\n");

If you want to just concatenate, you should be using the strcat function - it shouldn't be a problem with sprintf, but one never knows, and besides strcat is clearer anyhow.