Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
Development
Nov 28, 2018, 10:10 am
By Keirath
First Immortal
Oct 12, 2018, 12:02 pm
By GatewaySysop
Bug in do_climb( )
Jun 5, 2018, 5:31 pm
By joeyfogas
question on overland code
May 31, 2018, 10:03 am
By joeyfogas
KaVir's Protocol Snip
May 15, 2018, 7:57 pm
By joeyfogas
tintin++ ogg sound player script for linux
Author: Robert Smith
Submitted by: Vladaar
6Dragons ogg Soundpack
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.4
Author: Vladaar
Submitted by: Vladaar
LoP 1.46
Author: Remcon
Submitted by: Remcon
LOP 1.45
Author: Remcon
Submitted by: Remcon
Users Online
CommonCrawl, Yandex

Members: 0
Guests: 10
Stats
Files
Topics
Posts
Members
Newest Member
481
3,740
19,397
632
ClarenceKe
Today's Birthdays
There are no member birthdays today.
Related Links
» SmaugMuds.org » General » Coding » Array of Structures within a ...
Forum Rules | Mark all | Recent Posts

Array of Structures within a Structure
< Newer Topic :: Older Topic > How to?

Pages:<< prev 1 next >>
Post is unread #1 May 30, 2004, 11:15 am   Last edited Nov 24, 2007, 2:50 pm by Samson
Go to the top of the page
Go to the bottom of the page

cynshard

GroupMembers
Posts95
JoinedNov 19, 2003

I am moving from a classed system to a classless system( one universal class actually ). I'm also remaking the skill system to be a set of trees. I'm having a problem with accessing elements in an array of structures within a structure. For example:
struct skill_tree
{
	char *name;                   // Name of skill tree                          
	sh_int   skill[MAX_SKILL];    // The skills                                  
	S_PREREQ *prereq[MAX_SKILL];  // Which PreRequisites the skill requires      
        S_DECAY  *decay[MAX_SKILL];   // Decay: percentile per day and minimum decay 
	sh_int align_restrict;        // Alignments allowed                          
	sh_int race_restrict;         // Races allowed                               
	sh_int type;                  // Spells or Skills                            
	sh_int num_skills;            // Number of Skills, doesn't save              
};


This is my skill tree structure. i need to access both prereq and decay to update those values online. One operation I am providing is the insertion of new skills into the tree. You have to provide the skill name or sn, the decay rate, and the minimum level of decay. Here is the code segment illustrating my implementation:
  Tree->skill[Tree->num_skills] = snF;
  Tree->decay[Tree->num_skills]->rate = rate;
  Tree->decay[Tree->num_skills]->min  = min;
  Tree->num_skills++;

Tree is a pointer to a skill_tree structure. and Tree->num_skills is a non-saved integer that keeps track of how many skills are saved within the skill tree. snF is equal to the sn of the selected skill to insert. rate and min are both arguments taken from the user and converted to integers with atoi( they were also validated to fit within a specific range ).

If I attempt to insert a new skill into any tree I get the following gdb output:
0x0815ae72 in do_settree (ch=0x88188b8, argument=0xc ) at skills.c:1618
1618                    Tree->decay[Tree->num_skills]->rate = rate;


Has anyone ever tried to have an array of structures within a structure before? Is there a better way to do what I'm trying to do maybe?

Thanks
Cynshard
       
Post is unread #2 May 31, 2004, 2:25 pm
Go to the top of the page
Go to the bottom of the page

Odis

GroupMembers
Posts46
JoinedMar 8, 2005

Hmm, I'm not really sure what the problem is, however, this is a perfectly plausible idea. I believe the class system of SMAUG uses the idea as well. I myself have used it within many different situations.

The only thing that worries me about this is that you got this:
argument=0xc

Could you show us your entire do_settree function?
       
Post is unread #3 May 31, 2004, 8:17 pm   Last edited Nov 24, 2007, 2:53 pm by Samson
Go to the top of the page
Go to the bottom of the page

cynshard

GroupMembers
Posts95
JoinedNov 19, 2003

Odis said:

Could you show us your entire do_settree function?

Certainly. Although it's getting kind of long.

CMDF do_settree( CHAR_DATA *ch, char *argument )
{
    char arg1[MIL], arg2[MIL], arg3[MIL], arg4[MIL];
    SKILL_TREE *Tree;
    int tr, race, rate, min;

    smash_tilde( argument );
    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );

    if( arg1[0] == '\0' )
    {
  send_to_char( "&[plain]", ch );
  send_to_char( "Syntax: settree\r\n", ch );
  	send_to_char( "Syntax: settree  create\r\n",  ch );
  send_to_char( "Syntax: settree  insert\r\n", ch );
  send_to_char( "\r\nField being one of:\r\n", 	ch );
  send_to_char( "  name race align skill insert\r\n", ch );
  return;
    }

	if( is_number(arg1) && ( tr = atoi( arg1 ) ) >= 0 && tr < MAX_SKILL_TREE )
  Tree = skill_tree_table[tr];
    else
    {
  Tree = NULL;
  for ( tr = 0; tr name )
    continue;
  	if ( !str_cmp( skill_tree_table[tr]->name, arg1 ) )
  	{
    Tree = skill_tree_table[tr];
    break;
  	}
  }
    }
    if ( !str_cmp( arg2, "create" ) && Tree )
    {
      send_to_char( "That skill tree already exists!\r\n", ch );
  	return;
    }

    if ( !Tree && str_cmp( arg2, "create" ) )
    {
  send_to_char( "No such tree.\r\n", ch );
  return;
    }

	if ( !str_cmp( arg2, "create" ) )
    {
  if ( MAX_SKTREE >= MAX_SKILL_TREE )
  {
  	send_to_char("You need to up MAX_SKILL_TREE in mud and make clean.\r\n",ch);
    return;
  }

  if( ( Tree = create_new_skill_tree( arg1 ) ) == NULL )
  {
      	send_to_char( "Couldn't create a new skill tree.\r\n", ch );
    return;
  }

  save_skill_trees();

  ch_printf( ch, "The skill tree "&[iface1]%s&[plain]" was created sucessfully.\r\n", Tree->name );
  return;
	}

	/*
  *  Add a skill to the tree.
  *  Must choose level, with a decay rate and min...
  *  ....... ...... arg2   arg3    arg4     argument;
  *  settree  insert   
  */
	if( !str_cmp( arg2, "insert" ) || !str_cmp( arg2, "i" ) )
	{
  int i, sn, snF = -1;
  bool sFound = false;
  char *sName;
  
  argument = one_argument( argument, arg3);
  argument = one_argument( argument, arg4);
  
  if( !arg3 )
  {
  	send_to_char( "You must supply a skill or spell.\r\n", ch );
  	return;
  }
  
  if( !arg4 )
  {
  	send_to_char( "You must supply a decay rate.\r\n", ch );
  	return;
  }
  if( !argument || argument[0] == '\0' )
  {
  	send_to_char( "You must supply a decay minimum.\r\n", ch );
  	return;
  }
  if( is_number( arg4 ) )
  {
  	rate = atoi( arg4 );
  	if( rate  75 )
  	{
    send_to_char( "Decay rate must be between 0% and 75%.\r\n", ch );
    return;
  	}
  }
  else
  {
  	send_to_char( "Decay rate must be a number.\r\n", ch );
  	return;
  }
  
  if( is_number( argument ) )
  {
  	min = atoi( argument );
  	if( min  100 )
  	{
    send_to_char( "Decay minimum must be between 0% and 100%.\r\n", ch );
    return;
  	}
  }
  else
  {
  	send_to_char( "Decay minimum must be a number.\r\n", ch );
  	return;
  }


  if( is_number( arg3 ) )
  	sn = atoi( arg3 );
  else
  {
  	for ( sn = 0; sn name; sn++ )
    if( !str_cmp( skill_table[sn]->name, arg3 ) )
    {
    	sFound = true;
    	snF = sn;
    }

  	if( !sFound )
  	{
    ch_printf( ch, "The spell, %s, does not exist.\r\n", arg3 );
    return;
  	}
  }

  if( sn  top_sn )
  {
  	ch_printf( ch, "That sn: %d does not exist.\r\n", sn );
  	return;
  }

  sName = ( skill_table[snF]->name != NULL ) ? skill_table[snF]->name : arg3;

  for( i = 0; i skill[i] == snF )
  	{
    ch_printf( ch, "The skill, %s[%d] is already in this tree.\r\n", sName, snF );
    return;
  	}
  }
  
  Tree->skill[Tree->num_skills] = snF;
log_printf( "Tree->num_skills = %d, MAX_SKILL = %d, sizeof array decay = %d", Tree->num_skills, MAX_SKILL, sizeof( decay ) 
  Tree->decay[Tree->num_skills]->rate = rate;
  Tree->decay[Tree->num_skills]->min  = min;
  Tree->num_skills++;
  
  ch_printf( ch, "The skill, %s[%d], has been added to the tree.\r\n", sName, snF );
  save_skill_trees();
  return;
	}

	if( !str_cmp( arg2, "race" ) || !str_cmp( arg2, "r" ) )
	{
  if( ( race = get_pc_race( argument ) ) > MAX_PC_RACE || race race_restrict = race;
  	save_skill_trees();

  	ch_printf( ch, "Selection of race, %s, is successful.\r\n", argument );
  	return;
  }
	}

	if( !str_cmp( arg2, "align" ) || !str_cmp( arg2, "a" ) )
	{
  if( !str_cmp( argument, "good" ) || !str_cmp( argument, "g" ) )
  	Tree->align_restrict = TREE_ALIGN_GOOD;
  else if( !str_cmp( argument, "evil" ) || !str_cmp( argument, "e" ) )
  	Tree->align_restrict = TREE_ALIGN_EVIL;
  else if( !str_cmp( argument, "neutral" ) || !str_cmp( argument, "n" ) )
  	Tree->align_restrict = TREE_ALIGN_GOOD;
  else if( !str_cmp( argument, "none" ) || !str_cmp( argument, "z" ) )
  	Tree->align_restrict = TREE_ALIGN_NONE;
  else
  {
  	ch_printf( ch, "Invalid align type, "%s", chosen.\r\nChoices are: good, neutral, evil, or none.\r\n", argument );
  	return;
  }
  
  save_skill_trees();
  ch_printf( ch, "Selection of alignment, %s, is successful.\r\n", argument );
  return;
	}
}


For testing purposes I added a log statement to print out some useful values and here is what I receive:
Mon May 31, 2004 10:12:10 PM CDT :: Tree->num_skills = 0, MAX_SKILL = 500, sizeof array decay = 2000


Thanks,
Cynshard
       
Post is unread #4 Jun 1, 2004, 10:29 pm
Go to the top of the page
Go to the bottom of the page

Odis

GroupMembers
Posts46
JoinedMar 8, 2005

A few more questions. What is CMDF defined as? Also, can you show me how you declared skill_tree_table in mud.h? Another point of interest might be your decay structure. Or maybe I'm requesting stuff becaue I'm sleep and have no clue what I'm saying?
       
Post is unread #5 Jun 2, 2004, 12:23 am   Last edited Nov 24, 2007, 2:53 pm by Samson
Go to the top of the page
Go to the bottom of the page

cynshard

GroupMembers
Posts95
JoinedNov 19, 2003

Here are the typedefs...
typedef struct  skill_tree          SKILL_TREE; /* Skill Trees --Cynshard */
typedef struct  s_prereq            S_PREREQ;    /* skill/spell pre-req */
typedef struct  s_decay             S_DECAY;    /* skill/spell decay   */

#if !defined(__cplusplus)
   #define CMDF void
   #define SPELLF ch_ret
   #define SPECF bool
#else
   #define CMDF extern "C" void
   #define SPELLF extern "C" ch_ret
   #define SPECF extern "C" bool
#endif


I'm assuming that since I'm using g++ to compile CMDF is equal to void.

Here is the skill tree structure as it appears in mud.h
struct skill_tree
{
	char *name;                   // Name of skill tree                          
	sh_int   skill[MAX_SKILL];    // The skills                                  
	S_PREREQ *prereq[MAX_SKILL];  // Which PreRequisites the skill requires      
        S_DECAY  *decay[MAX_SKILL];   // Decay: percentile per day and minimum decay 
	sh_int align_restrict;        // Alignments allowed                          
	sh_int race_restrict;         // Races allowed                               
	sh_int type;                  // Spells or Skills                            
	sh_int num_skills;            // Number of Skills, doesn't save              
};


here is the decay structure as it appears in mud.h
struct s_decay
{
	sh_int rate; /* Percent per day */
	sh_int min;  /* Minimum percent for a spell */
};


I'm pretty tired so I might have left some stuff out.

Thanks,
Cynshard
       
Post is unread #6 Jun 2, 2004, 11:29 pm
Go to the top of the page
Go to the bottom of the page

Odis

GroupMembers
Posts46
JoinedMar 8, 2005

Hmm, strange. All looks ok to me. What exactly is your error again? Like, is it just creating a new skill in the tree that crashes your MUD, or what? I think I need to visit here during the day instead of past midnight. Lol.
       
Post is unread #7 Jun 3, 2004, 12:18 am   Last edited Nov 24, 2007, 2:53 pm by Samson
Go to the top of the page
Go to the bottom of the page

Odis

GroupMembers
Posts46
JoinedMar 8, 2005

Lol, not sure why I didnt spot this before. Have you actually used CREATE for your decay structures somewhere? Perhaps change that section of code to:

S_DECAY *decay;

CREATE( decay, S_DECAY, 1 );

decay->rate = rate;
decay->min = min;
Tree->decay[Tree->num_skills] = decay;
Tree->skill[Tree->num_skills] = snF;
Tree->num_skills++;
       
Post is unread #8 Jun 3, 2004, 7:23 am   Last edited Nov 24, 2007, 2:54 pm by Samson
Go to the top of the page
Go to the bottom of the page

cynshard

GroupMembers
Posts95
JoinedNov 19, 2003

The only time I allocate memory is here:
SKILL_TREE *create_new_skill_tree( char *argument )
{
	int i;
	SKILL_TREE *skill_tree;

	if( top_skill_tree >= MAX_SKILL_TREE )
  return NULL;

	CREATE( skill_tree, SKILL_TREE, 1 );
	
	skill_tree_table[top_skill_tree++] = skill_tree;

	STRFREE( skill_tree->name );
	if( argument && argument[0] != '\0' )
  argument[0] = UPPER( argument[0] );
	skill_tree->name = STRALLOC( argument );
	skill_tree->align_restrict = 0;
	skill_tree->race_restrict = 0;
	skill_tree->num_skills = 0;
	for( i = 0; i skills[i] = 0;
	return skill_tree;
}


I never thought to use create again for the other structures.
Anyhow this fixes my problem . Here is my final code for this segment:

CREATE( Tree->decay[Tree->num_skills], S_DECAY, 1 );
Tree->decay[Tree->num_skills]->rate = rate;
  Tree->decay[Tree->num_skills]->min  = min;
  Tree->num_skills++;


Thanks for the help
       
Post is unread #9 Jun 3, 2004, 12:43 pm
Go to the top of the page
Go to the bottom of the page

Odis

GroupMembers
Posts46
JoinedMar 8, 2005

Happy to have your problem fixed. Sorry, if I had looked at that during the light of day I most likely would have spotted that very quickly. Sorry for making you post so much of your code.

Anyways, I like your tree system. Good luck, it looks like it will be very nice.
       
Post is unread #10 Jun 3, 2004, 6:41 pm
Go to the top of the page
Go to the bottom of the page

cynshard

GroupMembers
Posts95
JoinedNov 19, 2003

Thanks for the help. I really don't mind posting code, hopefully other people will find it and it'll help them also.

Cynshard
       
Pages:<< prev 1 next >>