Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUDs ➜ General ➜ Reading one struct from another

Reading one struct from another

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Zeno   USA  (2,871 posts)  Bio
Date Thu 19 Aug 2004 02:35 AM (UTC)

Amended on Thu 19 Aug 2004 02:38 AM (UTC) by Zeno

Message
Alright, I've got the character struct working, so now I'm trying to link a skill/attack struct to the character struct.

In the load_character function:

      case 'A':
        SREAD( "Attack0", character->attacks[0]->name );


Reads an attack file:

ATTACK *load_attack(char *argument)
{
  FILE *fp;
  ATTACK *attack = NULL;
  char afile[256];
  char aName[20];
  int size, i;
  char *word;
  bool done = FALSE, found;

  aName[0] = toupper(argument[0]);
  size = strlen(argument);
  for (i = 1; i < size; i++)
    aName[i] = tolower(argument[i]);
  aName[i] = '\0';


  sprintf(afile, "../attacks/%s.atk", aName);
  if ((fp = fopen(afile, "r")) == NULL)
    return NULL;

    if ((attack = malloc(sizeof(*attack))) == NULL)
    {
      bug("Load_attack: Cannot allocate memory.");
      abort();
    }

  word = fread_word(fp);
  while (!done)
  {
    found = FALSE;
    switch (word[0])
    {
      case 'C':
        SREAD( "Cmd", attack->cmd );
        break;
      case 'N':
        SREAD( "Name", attack->name );
        break;
      case 'P':
        SREAD( "PreAttack", attack->preattack );
        break;
      case 'E':
        if (compares(word, "EOF")) {done = TRUE; found = TRUE; break;}
        break;
    }
    if (!found)
    {
      bug("Load_attack: unexpected '%s' in %s's afile.", word, argument);
      return NULL;
    }

    if (!done) word = fread_word(fp);
  }

  fclose(fp);
  return attack;
}


main.h

typedef struct  attack_data   ATTACK;

In char struct:

  ATTACK          * attacks[20];


struct attack_data
{
  char          * name;
  char          * cmd;
  char          * preattack;
};

Attack part of a char:

Attacks0       Slash~


The struct for attacks work, I can display the file in a cmd.

But when loading a char with an attack, it crashes, with this debug:


#0  0x0804edee in load_character (argument=0x805aae1 "cloud") at save.c:307
#1  0x0804d8f4 in cmd_showchar (dMob=0x805b0a0, arg=0x811db58 "Slash") at commands.c:706
#2  0x0804b823 in handle_cmd_input (dsock=0x811db58, arg=0x805aae1 "cloud") at interpret.c:33
#3  0x0804943f in game_loop (control=3) at socket.c:175
#4  0x0804925c in main (argc=3, argv=0xbffff954) at socket.c:77
#5  0x42015967 in __libc_start_main () from /lib/i686/libc.so.6


The character loads fine until it gets to attack.


302       {
303         found = FALSE;
304         switch (word[0])
305         {
306           case 'A':
307             SREAD( "Attack0", character->attacks[0]->name );
308             SREAD( "AfterAKill1", character->afterakill1 );
309             break;
310           case 'B':
311             SREAD( "BlockFail",  character->blockfail  );


character->attacks[0] is not loading, because its null.

Why is it not reading correctly?

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #1 on Thu 19 Aug 2004 06:18 AM (UTC)

Amended on Thu 19 Aug 2004 06:20 AM (UTC) by Nick Cash

Message
Did you allocate space for attack? It may be easier to do this:

{
 char *var;
 SREAD( "Attack0", var );
 character->attack[0] = lookup_attack( var );
}

And have lookup_attack return a pointer to the right allocated attack structure with the name that matches var. Make sure you read in the attacks when the mud starts however.

Think of it this way. You used smaug. When a person connected, they start as a descriptor. The descriptor_data struct has a CHAR_DATA *char variable (or something similar), however, before its used you need to load the char. It is then assigned.

What you are trying to do is assign data to space that isnt there. You could probably accomplish the same affect by just allocating space for character->attack when you allocate for a character.

I think thats right, maybe I've got myself all switched around. Try it, see what happens.

Btw, you'll need a linked list or table of pointers to allocated attacks, if you dont have one.

EDIT:

Actually, SREAD allocates data since it uses fread_string instead of fread_word, so perhaps allocating for attack is your best bet?

~Nick Cash
http://www.nick-cash.com
Top

Posted by Greven   Canada  (835 posts)  Bio
Date Reply #2 on Thu 19 Aug 2004 06:28 AM (UTC)
Message
Are you sure that you have the same thing for aName after it uppers and lowers it when you do it manually as when its in a players file? That part returns null with no bug if it can't find the file, so there might be a slight difference in what argument is.

Nobody ever expects the spanish inquisition!

darkwarriors.net:4848
http://darkwarriors.net
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #3 on Thu 19 Aug 2004 07:04 AM (UTC)
Message
Whiteknight, oddly enough, thats what I tried first.

Although your way worked.

Now, its appearing null on a char. (At least its not crashing anymore)

Characters and skills aren't to be saved though, er that is, written to file.

Here's my debug while loading a char:

[LOG: SREAD: Attack0, temp]
[LOG: Temp: …À‰Á…Àˆw[]
[LOG: load_attack...]
[LOG: aName: …À‰Á…Àˆw[]
[LOG: SREAD: Attack0, temp]

Moves:
(null)



        dprintf(dMob, "%s", chara->attacks[0] );


If its attacks[0]->name, it crashes.

Do I really need a linked list?

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #4 on Thu 19 Aug 2004 07:45 PM (UTC)

Amended on Thu 19 Aug 2004 07:54 PM (UTC) by Nick Cash

Message
Well, if your loading attacks from a file then you might as well as just throw them in a linked list and reference to them that way. No need in wasting space by loading them one time for each character. Just make a master list, and then when you load from characters just do as you did. Have the name, and look it up and just assign the value.

An alternative to a linked list would be a table. If you have SWR, just go into const.c and look at the race table. This might be a good alternative since you dont have to load any files to have it work correctly. Then it simplies everything. character_data's attack var would turn to int attack[20], and instead of all of this work with pointers and allocating you just do this:

IREAD( "Attack0", character->attacks[0] );

And then when you want to loop through their attacks, you do this:

for ( i = 0; i < 20; i++ )
{
  if ( attack_table[i]->name == something )
   do soemthing here;
}

If you dont want to deal with loading files and crap, table's are generally a good way to do it.

~Nick Cash
http://www.nick-cash.com
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #5 on Thu 19 Aug 2004 08:15 PM (UTC)
Message
Oh, I guess I forgot to mention that.

I already have an attack.lst and char.lst, but I don't have a table of any sort.

Whats the cause for crashing then, if I already have a linked list?

Cloud.char has Slash.atk in his file, I can read the file with showattack, but the char can't load it, it turns out to be null. Both list files are correct.

Anyways, I'll double check the list after I get back from buying Tales of Symphonia. ;)

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #6 on Fri 27 Aug 2004 02:05 AM (UTC)
Message
Okay, did some debugging, here's the results: (showattack displays the attack file, example, Slash.atk)

showattack slash

[LOG: load_attack started, arg: slash]
[LOG: load_attack, aName: Slash]
[LOG: load_attack, fopen: ../attacks/Slash.atk]
[LOG: load_attack: file found: ../attacks/Slash.atk]
[LOG: load_attack: Could allocate memory.]
Name: Slash
Cmd: slash
PreAttack: $n goes to slash...


showchar cloud

[LOG: load_char: attack0: ¯¢Õ£t¤¾¥+¥Program starting.]
[LOG: load_attack started, arg: ¯¢Õ£t¤¾¥+¥Program starting.]
[LOG: load_attack, aName: ¯¢Õ£t¤¾¥+¥program starting.]
[LOG: load_attack, fopen: ../attacks/¯¢Õ£t¤¾¥+¥program star../attacks/.atk]
(Char data here)
Moves:
(null)
Accounts using this char: 


So load_char is the problem.

  char *temp;
...
307      case 'A':
308        SREAD( "Attack0", temp );
309        bug( "load_char: attack0: %s", temp );
310        character->attacks[0] = load_attack( temp );
311        SREAD( "AfterAKill1", character->afterakill1 );
312        break;


Only problem is if I make it ATTACK *temp, then it crashes because:

save.c:308: warning: assignment from incompatible pointer type
save.c:310: warning: passing arg 1 of `load_attack' from incompatible pointer type


Yeah, in the Cloud character, Attack0 is "Slash".

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #7 on Fri 27 Aug 2004 03:24 AM (UTC)
Message
I cant belive I didn't see it before. If you examine SREAD in mud.h it actually has break; in there, which would mess everything up how you have it.
Quote:

Only problem is if I make it ATTACK *temp, then it crashes because:

save.c:308: warning: assignment from incompatible pointer type
save.c:310: warning: passing arg 1 of `load_attack' from incompatible pointer type

Well, that makes perfect sense. Look at what you are trying to do. SREAD is a macro specifically designed to load in strings. If you use anything but a char variable, it is likely to produce a crash.

Quote:

307 case 'A':
308 SREAD( "Attack0", temp );
309 bug( "load_char: attack0: %s", temp );
310 character->attacks[0] = load_attack( temp );
311 SREAD( "AfterAKill1", character->afterakill1 );
312 break;

Try this:

      case 'A':
        if ( compares( "Attack0", word ) )
        {
         temp = fread_string(fp);

         bug( "load_char: attack0: %s", temp );
         character->attacks[0] = load_attack( temp );

         found = TRUE;
         break;
        }
        SREAD( "AfterAKill1", character->afterakill1 );
        break;

That SHOULD fix the problem. I think....

~Nick Cash
http://www.nick-cash.com
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #8 on Fri 27 Aug 2004 03:34 AM (UTC)

Amended on Fri 27 Aug 2004 03:35 AM (UTC) by Zeno

Message
Yep, it did. Thanks.

As for the crash, I wasn't really asking why or how to fix that, just stating. Didn't say the reason for the crash, because it was obvious.

Now to figure out how to interpret the account->character->attack->cmdname as a command that can be used.

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


21,924 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.