Saving spells with slots rather than sn's

Posted by Orik on Mon 02 Jul 2007 04:20 AM — 43 posts, 135,644 views.

USA #0
Ok, I have put in a spell memorization system in my code. It all works fine and dandy but the one problem is that it saves the sn's of the spells to the pfile. This works great until I add a new skill/spell and it resorts the sn's. So when my next character that had a spell memorized logs in, he'll have a different spell in his memory because the new spell bumped that spell out of it's old sn.

Example:

I mem heal which is sn #90. 

I see heal when I type mem to show memorized list. 

I log off and have sn 90 saved in my pfile. 

A new spell named "haver" is made, and sorted. I hotboot mud, skill table is resorted haver goes into sn 90, pushing heal to 91.

I log back in my player and type mem to show list and it now says haver instead of heal.


Here's where it's saving as sn:


int
set_spell_mem(CHAR_DATA * ch, int sn)
{
     int i;

     for (i = 0, i < MAX_MEM_SPELLS; i++)
          if (ch->pcdata->memorizing[ i] == 0)
          {
             ch->pcdata->memorizing[ i] = sn;
             return TRUE;
          }
     return FALSE;
}


so it's setting ch->pcdata->memorizing[ i] to sn and I want it set to the slot number. I tried this:

ch->pcdata->memorizing[ i] = skill_table[sn]->slot;

but it didn't work. Any thoughts? The problem is I'm converting this from a envy codebase where there is no sorting on the skills/spells so it never took that into consideration when it saved sn's.
Amended on Mon 02 Jul 2007 04:27 AM by Orik
USA #1
My suggestion would be to save the actual spell name rather than the spell number. You'd need to rework the code a bit to read and store the spell name from input instead of the sn table.
USA #2
I had thought of that. But I didn't know if I'd be able to figure it all out. How would I set up the for loops to pick out the name rather than the sn?

***********EDIT**************

Also what about spells with two or more words?

IE quantum spike or protection from scrying
Amended on Mon 02 Jul 2007 05:07 AM by Orik
USA #3
I'd rather just go with slots numbers. I'm not using any stock spells, so I'm just starting with my own new spells and I can easily put in slot numbers when I add new spells in.

I think it would be easiest to just have it save slot numbers. Save space in pfiles as well. I just need to figure out how to get it to find the slot number through the sn of the spell.
USA #4
They wont have more than 1 word as the function name so thats one option. You could also use a char * value for storage and read the spell input as one arg with ' delimiters since players have to use them for spells with more than 1 word anyway.
USA #5
I would also recommend going with spell names because it is more robust in the long run.

But if you really want to use slots, to find a slot from an sn, isn't there a 'slot' field in the skill structure?
USA #6
I don't have my code in front of me, but I'm guessing I could do something like

ch->pcdata->memorizing[ i] = skill->slot;

What would I do about the sn? Whenever it's called it's like

set_spell_mem(ch, sn)

could I put it

set_spell_mem(ch, skill->slot)

or I could put skill->slot = sn?

*******EDIT********

If I go by names, how would I set it up to look for the arguments? If that's the better way then I'll do it like that.
Amended on Mon 02 Jul 2007 02:14 PM by Orik
USA #7
Well, you'd have to be very careful to use SNs anywhere the code expects an SN. I think there is a function called slot_lookup that will translate from slot to SN, which is what you'd want to use. You would set up your data representation and functions however you want, but when you talk to the rest of the code you would need to use the conventions they have. Basically, pick an internal convention and stick with it, and then make sure you do the right thing when talking to the existing functions.

One problem of slots and skill numbers is that they aren't type-safe. Meaning that they can be used interchangeably by accident, even though they really aren't interchangeable at all.

Quote:
If I go by names, how would I set it up to look for the arguments?


I'm not sure I understand what you mean. :-)
USA #8
You said it'd be better to use spell names. How would I set up a char * to be able to use the names to write the names to files? Would it be something like


struct char * ch

for (sn = 0, sn < max_skill, sn++)
  sn = skill_table[sn]->name;
return skill_table[sn]->name;


Thats not real, just a psuedo code, but I'm not really sure how to set it to read and write the names to memorization.
USA #9
No, you would use sn's in memory, but save/load the spell names. It's like how spell effects work currently on, e.g., pfiles: you store names, and convert them to numbers when you read.
USA #10
Ok, here's the fwrite_char in save.c


   for( sn = 1; sn < top_sn; sn++ )
   {
      if( skill_table[sn]->name && ch->pcdata->learned[sn] > 0 )
         switch ( skill_table[sn]->type )
         {
            default:
               fprintf( fp, "Skill        %d '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name );
               break;
            case SKILL_SPELL:
               fprintf( fp, "Spell        %d '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name );
               break;
            case SKILL_WEAPON:
               fprintf( fp, "Weapon       %d '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name );
               break;
            case SKILL_TONGUE:
               fprintf( fp, "Tongue       %d '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name );
               break;
         }
   }


Here's fread_char


if( !strcmp( word, "Spell" ) )
            {
               int sn, value;

               if( preload )
                  word = "End";
               else
               {
                  value = fread_number( fp );

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if( sn < 0 )
                     bug( "%s", "Fread_char: unknown spell." );
                  else
                  {
                     ch->pcdata->learned[sn] = value;
                     if( ch->level < LEVEL_IMMORTAL )
                        if( skill_table[sn]->skill_level[ch->Class] >= LEVEL_IMMORTAL )
                        {
                           ch->pcdata->learned[sn] = 0;
                           ch->practice++;
                        }
                  }
                  fMatch = TRUE;
                  break;
               }
            }


So I need to go off this. I'll think on it a minute and then repost something.
USA #11
Here's how I save my spells in fwrite and fread char


                /* Spell Memorization */
        fprintf( fp, "Memtime     %d\n",
        ch->mem_time);

    fprintf( fp, "Memorized     ");
    for (j = 0; j < MAX_MEM_SPELLS; j++)
        {
        fprintf(fp, " %d",ch->pcdata->memorized[j]);
        }
    fprintf(fp, "\n");

    fprintf( fp, "Memorizing    ");    
for (j = 0; j < MAX_MEM_SPELLS; j++)
        {
        fprintf(fp, " %d",ch->pcdata->memorizing[j]);
        }
   fprintf(fp, "\n");



fread:


                if (!str_cmp(word,"Memorized"))
                {
                for (j = 0; j < MAX_MEM_SPELLS; j++)
                        ch->pcdata->memorized[j] = fread_number(fp);
                fMatch   = TRUE;
                break;
                }
                if (!str_cmp(word,"Memorizing"))
                {
                for (j = 0; j < MAX_MEM_SPELLS; j++)
                        ch->pcdata->memorizing[j] = fread_number(fp);
                fMatch   = TRUE;
                break;
                }


Here's in mud.h

        int                     memorized               [ MAX_MEM_SPELLS ];
    int                     memorizing              [ MAX_MEM_SPELLS ];


********EDIT********

So it saves like this in the pfile:


Memorized      165 0 0 52 0 90 90 90 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Memorizing     90 90 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


So what you're memorizing gets put up into memorized after your done meming it, onc eyou cast it goes back to memorizing and have to remem it.


Amended on Mon 02 Jul 2007 11:44 PM by Orik
USA #12
Some questions:

- You are using numbers. Are they slot numbers or skill numbers? If they are skill numbers, how are you accounting for the fact that they might change when you add skills and reboot?

- Where do you initialize the memory arrays? You might want to set them all to zero to avoid getting garbage the first time you save (and hence subsequent times you load).

- You might want to only write out elements that actually exist, but that will mean you have to adapt your load function.
USA #13
Quote:

You are using numbers. Are they slot numbers or skill numbers? If they are skill numbers, how are you accounting for the fact that they might change when you add skills and reboot?


That's why I'd rather save them by something else. They are saving as skill numbers right now. The reason being once I added a new skill/spell all numbers would be off in the mem list.

Quote:

Where do you initialize the memory arrays? You might want to set them all to zero to avoid getting garbage the first time you save (and hence subsequent times you load).


I believe it just writes out 100 0's when you first create your character

Quote:

You might want to only write out elements that actually exist, but that will mean you have to adapt your load function.


I'd like to do this. It would probably be smoother.
USA #14
When you save I believe this is what writes out the 100 0's because max_mem_spell is 100, they can't mem anymore then that.


                /* Spell Memorization */
        fprintf( fp, "Memtime     %d\n",
        ch->mem_time);

    fprintf( fp, "Memorized     ");
    for (j = 0; j < MAX_MEM_SPELLS; j++)
        {
        fprintf(fp, " %d",ch->pcdata->memorized[j]);
        }
    fprintf(fp, "\n");

    fprintf( fp, "Memorizing    ");    
for (j = 0; j < MAX_MEM_SPELLS; j++)
        {
        fprintf(fp, " %d",ch->pcdata->memorizing[j]);
        }
   fprintf(fp, "\n");


USA #15
Quote:
That's why I'd rather save them by something else. They are saving as skill numbers right now. The reason being once I added a new skill/spell all numbers would be off in the mem list.

So, you are writing out skill numbers, BUT you would rather save them as spell names?
In that case, you can just emulate the code you posted from character reading/saving that translates from names to numbers etc.

Quote:
When you save I believe this is what writes out the 100 0's because max_mem_spell is 100, they can't mem anymore then that.

No, that just writes whatever is in those arrays. If you don't set them to zero explicitly when you create the character structure, you will be writing out whatever contents of memory happen to be in that array. (Arrays are not initialized to zero when you create them.)
USA #16
Quote:

So, you are writing out skill numbers, BUT you would rather save them as spell names?
In that case, you can just emulate the code you posted from character reading/saving that translates from names to numbers etc.


yes, I would rather change them to names. So I might need a little help figuring out how to emulate the skill fread/fwrite. I'll work on that and see if I can come up with something and post it.

Quote:

No, that just writes whatever is in those arrays. If you don't set them to zero explicitly when you create the character structure, you will be writing out whatever contents of memory happen to be in that array. (Arrays are not initialized to zero when you create them.)


Not sure. I never get any bugs when I create a new character. I'll have to look into it more. When I ported it over from Envy it was late at night and a blur...lol.

**********EDIT *********

I'm not sure how I can write and read the mems. Everything I try isn't right.
Amended on Tue 03 Jul 2007 12:36 AM by Orik
USA #17
How bout this:


for (j = 0; j < MAX_MEM_SPELLS; j++)
  for (sn =1; sn < top_sn; sn++)
    if( skill_table[sn]->name > 0)
       fprintf(fp, "Memorized: %d '%s'\n", j, skill_table[sn]->name );

for (j = 0; j < MAX_MEM_SPELLS; j++)
  for (sn =1; sn < top_sn; sn++)
    if( skill_table[sn]->name > 0)
       fprintf(fp, "Memorizing: %d '%s'\n", j, skill_table[sn]->name );


*****edit *****
That didn't work. It wrote out every skill/spell 100 times...lol

***************************
2nd attempt
***************************

for (j = 0; j < MAX_MEM_SPELLS; j++)
  for (sn =1; sn < top_sn; sn++)
    if( skill_table[sn]->name && ch->pcdata->memorized[j])
       fprintf(fp, "Memorized: %d '%s'\n", j, skill_table[sn]->name );

for (j = 0; j < MAX_MEM_SPELLS; j++)
  for (sn =1; sn < top_sn; sn++)
    if( skill_table[sn]->name && ch->pcdata->memorized[j])
       fprintf(fp, "Memorizing: %d '%s'\n", j, skill_table[sn]->name );


This is a no go. It just wrote out all skills for 0. So it didn't get to go back through the first for loop.


***************************
3rd attempt
***************************

for (j = 0; j < MAX_MEM_SPELLS; j++)
  for (sn =1; sn < top_sn; sn++)
    if( skill_table[sn]->name && ch->pcdata->memorized[j] && ch->pcdata->learned[sn] > 0 && skill_table[sn]->type == SKILL_SPELL)
       fprintf(fp, "Memorized: %d '%s'\n", j, skill_table[sn]->name );

for (j = 0; j < MAX_MEM_SPELLS; j++)
  for (sn =1; sn < top_sn; sn++)
    if( skill_table[sn]->name && ch->pcdata->memorized[j] && ch->pcdata->learned[sn] > 0 && skill_table[sn]->type == SKILL_SPELL)
       fprintf(fp, "Memorizing: %d '%s'\n", j, skill_table[sn]->name );


This one prints out each spell for each j loop.

IE: I type
mem heal
mem dispel magic
mem vitality

it saves as

Memorized: 0 'heal'
Memorized: 0 'dispel magic'
Memorized: 0 'vitality'
Memorized: 1 'heal'
Memorized: 1 'dispel magic'
Memorized: 1 'vitality'
Memorized: 2 'heal'
Memorized: 2 'dispel magic'
Memorized: 2 'vitality'

So it's not going through the for loop correctly. It should read:

Memorized: 0 'heal'
Memorized: 1 'dispel magic'
Memorized: 2 'Vitality'
Amended on Tue 03 Jul 2007 01:25 AM by Orik
USA #18
I haven't tried this, but this is closer to what you want:


for (j = 0; j < MAX_MEM_SPELLS; j++)
{
  int sn = ch->memorized[j];
  if( skill_table[sn]->name != 0)
    fprintf(fp, "Memorized: %d '%s'\n", j, skill_table[sn]->name );
}

for (j = 0; j < MAX_MEM_SPELLS; j++)
{
  int sn = ch->memorizing[j];
  if( skill_table[sn]->name != 0)
    fprintf(fp, "Memorizing: %d '%s'\n", j, skill_table[sn]->name );
}
USA #19
Ok, that works, but it's showing all the 0 sn's as reserved.

Example:

I memed heal, dispel magic, and vitality

Pfile looks like this:

Memorized: 0 'heal'
Memorized: 1 'dispel magic'
Memorized: 2 'vitality'
Memorized: 3 'reserved'
Memorized: 4 'reserved'
Memorized: 5 'reserved'
Memorized: 6 'reserved'
...
Memorized: 99 'reserved'
Memorizing: 0 reserved
Memorizing: 1 reservedmagic'
Memorizing: 2 reserved
Memorizing: 3 'reserved'
Memorizing: 4 'reserved'
Memorizing: 5 'reserved'
Memorizing: 6 'reserved'
...
Memorizing: 99 'reserved'
USA #20
Ok, added the && ch->pcdata->learned[sn] > 0 to it and it works perfect now.


Now for the fread part. Be back in a minute for an update on that.


if( !strcmp( word, "Memorized" ) )
            {
               int sn, value;

               if( preload )
                  word = "End";
               else
               {
                  value = fread_number( fp );

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if( sn < 0 )
                     bug( "%s", "Fread_char: unknown spell." );
                  else
                  {
                     ch->pcdata->learned[sn] = value;
                     if( ch->level < LEVEL_IMMORTAL )
                        if( skill_table[sn]->skill_level[ch->Class] >= LEVEL_IMMORTAL )
                        {
                           ch->pcdata->learned[sn] = 0;
                           ch->practice++;
                        }
                  }
                  fMatch = TRUE;
                  break;
               }
            }
if( !strcmp( word, "Memorizing" ) )
            {
               int sn, value;

               if( preload )
                  word = "End";
               else
               {
                  value = fread_number( fp );

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if( sn < 0 )
                     bug( "%s", "Fread_char: unknown spell." );
                  else
                  {
                     ch->pcdata->learned[sn] = value;
                     if( ch->level < LEVEL_IMMORTAL )
                        if( skill_table[sn]->skill_level[ch->Class] >= LEVEL_IMMORTAL )
                        {
                           ch->pcdata->learned[sn] = 0;
                           ch->practice++;
                        }
                  }
                  fMatch = TRUE;
                  break;
               }
            }



What exactly does that preload mean?

********EDIT********
The above code isn't working. It's bugging out and won't read the pfile correctly. Will try again with something else soon.
********************
I believe it's the

               if( preload )
                  word = "End";


that's causing the problem. Here's the bug:


FILE: ../player/g/Greg LINE: 50
BUG: fread_char: no match: End

and it does that for all three spells I memed.


*********************
3rd attempt
*********************

I took out the if (preload) statement. I didn't get any errors but it always deleted my memorized spells so I'd mem the spells, log out, log back in and have nothing.
Amended on Tue 03 Jul 2007 02:30 AM by Orik
USA #21
Ok, I'm down to this:


if( !strcmp( word, "Memorized" ) )
            {
               int sn;

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if( sn < 0 )
                     bug( "%s", "Fread_char: unknown spell." );
                  fMatch = TRUE;
                  break;
               }
            }
if( !strcmp( word, "Memorizing" ) )
            {
               int sn;

                sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if( sn < 0 )
                     bug( "%s", "Fread_char: unknown spell." );
                  fMatch = TRUE;
                  break;
               }
            }



I get this bug:

FILE: ../player/g/Greg LINE: 50
BUG: Fread_char: unknown spell.
FILE: ../player/g/Greg LINE: 50
BUG: Fread_char: no match: heal

I get that in both preloading and loading player data


*****************
EDit
*****************

I know I have to get the for loop in there of max mem spells. I'm not sure how to fit it in.

*****************
EDIT 2
*****************
Then again, the spell fread didn't have any for loops in it. I'm just trying to convert the spell into an sn right now. hmm....
Amended on Tue 03 Jul 2007 03:08 AM by Orik
USA #22
Anyone have any thoughts on this? I'm stumped.

This has got to be the line that's the culprit:


sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );


It must not be reading it properly.
USA #23
I'm not sure that's the problem. I think that by trying to abort too early on preload, you might be mixing up the reading function. I would try to get things to work for now, and only try to be clever and optimize later.
USA #24
So what do you suggest? What does it mean to preload or abort to early?
************************************
Quote:

I'm not sure that's the problem. I think that by trying to abort too early on preload, you might be mixing up the reading function. I would try to get things to work for now, and only try to be clever and optimize later.


I am trying to get this to work. I don't know how to optimize lol. Just trying to get it to work and trying everything possible. Been at this forever.
Amended on Tue 03 Jul 2007 05:32 AM by Orik
USA #25
What about something like this:


if ( @strcmp( word, "Memorized" ))
 { 
   int sn;
   char *sname;

   if( preload )
    {
      fMatch = TRUE;
      fread_to_eol( fp );
      break;
    }
    
   if (sn = skill_lookup(sname)) < 0)
    {
      bug( "Fread_char: unknown spell %s.", sname );
    }
   fMatch = TRUE;
   break;
 }


This doesn't work but am I on the right track? or should I go with what I had and figure that our more?
Australia Forum Administrator #26
Quote:


if( !strcmp( word, "Memorized" ) )
            {
               int sn;

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );



I don't see how this is going to work, seeing as you had a number before the spell name.

Remember, gdb is your friend. Try putting a breakpoint on that part of the function and seeing what it is doing.
USA #27
aha! So if I take out that first number to begin with then it should read the word with fread_word? I don't really need that number anyways, it was more for testing purposes.

****EDIT****

and if I did want to keep that number in there, I'd put something like:

int value;

value = fread_number(fp)

and that would read the number first, then put the bsearch after that and that would read the word second?
Amended on Tue 03 Jul 2007 04:40 PM by Orik
USA #28
Yes, if you have the number there you would need to remove it one way or the other, either by not writing it or by reading it.
USA #29
awesome. I'll get home and try this after work. Thanks David and Nick.
USA #30
Ok, it successfully reads and writes the spells, now my problem lies in my do_memorize function. I mem heal, save and quit. Log back in and check pfile, heal is still in pfile as memorized. I use the command memorize and it shows that I have memmed no spells. I save and then check pfile again and it shows no memorized spells.

Here's part of my memorize function. I'm guessing I have to figure out how to call it to read words like in the save.c section:

do_memorize

    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;
                    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;
                     }
             }
       }

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

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

                if (ch->pcdata->memorizing[0] != 0)
                                {
                mudstrlcpy(buf, "", MAX_STRING_LENGTH);
        strcat(buf, "And you are currently memorizing the following spells:\r\n");
                        time_memming = ch->mem_time;
                        for (i = 0; i < MAX_MEM_SPELLS; i++)
                                                {
                                if (ch->pcdata->memorizing[ i] != 0)
                                                                {
                                        sprintf(buf, "%s %4d seconds (%2d) %s.\r\n",
                                                buf,
                                                time_memming,
                                        skill_table[ch->pcdata->memorizing[ i]]->spell_level,
                                                                                skill_table[ch->pcdata->memorizing[ i]]->name);


I'm guessing it has to do with the for loops and memorized[ i] parts needing to be called by skill_table[sn]->name again.
Amended on Tue 03 Jul 2007 10:25 PM by Orik
USA #31
Maybe I didn't quite fully fix the fread and fwrite.

I log in, mem heal
save
log out
log back in
check pfile, everything is in there
type mem, nothing in memorize function
save
check pfile, no memorized spells anymore
mem heal again
cast heal on self and it works just fine.

So there's still something wrong with it not reading the sn correctly to show the spell.
USA #32
Woah, something really weird happened to your indenting there. :-P It's pretty hard to read when it goes all over the place like that...
USA #33
Here's fwrite_char:


for (j = 0; j < MAX_MEM_SPELLS; j++)
 { 
   int sn = ch->memorized[j];
     if( skill_table[sn]->name != 0)
      fprintf(fp, "Memorized '%s'\n", skill_table[sn]->name ); 
}
 for (j = 0; j < MAX_MEM_SPELLS; j++)
  {
     int sn = ch->memorizing[j]; 
      if( skill_table[sn]->name != 0) 
     fprintf(fp, "Memorizing '%s'\n", skill_table[sn]->name );
 } 


Here's my fread code:


if( !strcmp( word, "Memorized" ) )
            {
               int sn;

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if(sn < 0 )
                    bug ("%s", "Fread_char: unknown spell." );
                 fMatch = TRUE;
                  break;
            }
if( !strcmp( word, "Memorizing" ) )
            {
               int sn;

                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if(sn < 0 )
                    bug ("%s", "Fread_char: unknown spell." );
                 fMatch = TRUE;
                  break;
            }
Amended on Tue 03 Jul 2007 10:46 PM by Orik
USA #34
There, tried to make it better to read. Hope that helps.
USA #35
Ah, much better, thank you.

You know, it occurs to me that you are writing our "Memorized:" with a colon, but I don't think the colons are skipped when you read in the data -- I could be wrong about that, I really don't remember. It might be worth trying to write without the colon and see what happens.
USA #36
actually, I do have them without the colons in my code. So that's not the problem.

********EXIT***********

Could the problem be that I'm not setting the sn to ch->pcdata->memorized[i] in the fread portion?
Amended on Tue 03 Jul 2007 10:59 PM by Orik
USA #37
Well, yes, you would have to update the memorized array with the skill you just read... :-)
USA #38
I came up with this:


if( !strcmp( word, "Memorized" ) )
            {
               int sn, j, i;
                 j = fread_number(fp);
                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if(sn < 0 )
                    bug ("%s", "Fread_char: unknown spell." );
                  ch->pcdata->memorized[ i] = sn;
                 fMatch = TRUE;
                  break;
            }
if( !strcmp( word, "Memorizing" ) )
            {
               int sn, j, i;
                 j = fread_number(fp);
                  sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill - 1 );
                  if(sn < 0 )
                    bug ("%s", "Fread_char: unknown spell." );
                  ch->pcdata->memorizing[ i] = sn;
                 fMatch = TRUE;
                  break;
            }



Which it doesn't really work that well. It will remember the last spell I memorized. I mem spells, they all mem just fine, I save and log off, log back in and I have the last spell I memed in my memory.


How do I update the memorized array? What's the array? It is this right:

memorizing [ i ]
or
memorized [ i ]

How would I update it?
Amended on Wed 04 Jul 2007 01:36 AM by Orik
USA #39
There are a few problems here. You're using the variable i, but you never set it to anything, nor do you ever update it. You will want to initialize it to zero somewhere, and every time you make an assignment you want to update it.

But since you have memorized and memorizing, you actually need two variables. I suggest calling them something other than i, like numMemorized.
USA #40
Ok, so I have it working...I believe.

What I did was, since I was counting the j in the fwrite I set it as the value in the fread. Then I changed the i to a j and since it was counting for every memed spell already, I just used that.

So far, I've been troubleshooting it, but it seems to be working. FINALLY!!! heh.
USA #41
Good news, it works. Bad news is somehow, I have no idea how, sset save skill table doesn't save through reboot or hotboot now. I tried it on my backup that i made before I switched spell memorization. It worked fine through reboot and hotboot.

I see that's it's saving in the class file, but when I hotboot/reboot, the level goes back up to 101 as if I never saved it. It shows minlevel in skills.dat as the level that I chose it, but it doesn't change in slookup.

i did a diff on tables.c, skills.c and save.c.

SKills.c had onthing, tables.c had nothing, save.c just had the changes to spell memorization.

bah, I thought I had it, now this is going to stump me.


*******EDIT*******

I just put those four changes into my backup folder and now everything works fine. For what I can tell anyways :)
Amended on Wed 04 Jul 2007 03:50 AM by Orik
#42
Been watching this with interest -- glad you have it figured out.
Any chance you might be willing to post your memorization system as a snippet? I've looked about for memorization for Smaug with no success.
Either way, glad you got it working.
Regards,
Gadush