01 Jul, 2009, triskaledia wrote in the 1st comment:
I typically try to stray away from tables and arrays, 1) I never got that far into my study, and 2) When i look at it I go what the fuck…
Anyway, I've decided that I need to learn how to use them properly, 1) It is how all the stats are setup to do their respective abilities, and 2) I got to start stepping outside of my coding boundaries…
So, this is the magic missile I have setup…

void spell_magic_missile( int sn, int level, CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = //Inside the brackets I could set a number to set a max on the following numbers allowed?
{ //So 10 would make it so only 10 numbers could be included?
0,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
35, 35, 35, 35, 35, 40, 40, 40, 40, 40,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
50, 50, 50, 50, 50, 50, 50, 50, 50, 100
};
int dam,i;

level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
level = UMAX(0, level);

for(i = 1 + (ch->level / 10) ; i > 0; i–)
{
dam= number_range( dam_each[level], dam_each[level] * 2 ); //Is this pulling a random number from the dam_each table where the
if ( saves_spell( level, victim,DAM_ENERGY) ) //random number is defined "players level" to "players level * 2"
dam /= 2; //and if I wanted to pull a number from the table = to the players level
damage( ch, victim, dam, sn, DAM_ENERGY ,TRUE); //I would have to go back and define numbers until I get 100 setup?
} //Then I would just do dam = dam_each[level]?
return;
}

I didn't write this, it was a snippet…

Running ROM 2.4 QuickMUD

–Silence Tyire of Reanimation
01 Jul, 2009, Justice wrote in the 2nd comment:
Basically the loop initializes i to a starting point using the player's level, and then decrements it until it reaches 0. This is the total # of hits that you will receive.

Within the loop it generates an arbitrary value using the "level" to lookup a value from the array. It simply doubles this value to get the range of possible values.

Yes you can simply pull out a constant value from the array if you want.
01 Jul, 2009, quixadhal wrote in the 3rd comment:
No, number_range() generates a random number between the lower and upper bound. If you use the constant value from the array, you get dam_each[level]d1+0 as your damage formula, which is pretty boring. Of course, I think the way that's done is daft too, but that's another fish.

The ways I prefer to hand things are to either code your damage function to actually take dice parameters (XdY+Z) so you can emulate the damage formulas of AD&D, which is where this stuff originated…. or work out a math function that returns an appropriate value along a slope (or curve), thus eliminating the need to worry about changing all those arrays if you decide to change how many levels your game has.
01 Jul, 2009, triskaledia wrote in the 4th comment:
For that AD&D stuff… I don't like the way the dice works… it's quite trivial to me. 1) As I never did AD&D, and 2) The number is always so off from what I'm looking for. Most of my damage values are concrete or use the number_range() to setup a number that I like.

But back to the topic at hand. So, if I wanted to setup damage values based upon a character level, I could setup 100 numbers within that array
and set level = ch->level and it would pull the designated number from the array?

–Silence Tyire
01 Jul, 2009, Davion wrote in the 5th comment:
triskaledia said:
So, if I wanted to setup damage values based upon a character level, I could setup 100 numbers within that array
and set level = ch->level and it would pull the designated number from the array?

Yes, but make sure to set the size of the array to 101 to account for zero or use level-1
02 Jul, 2009, triskaledia wrote in the 6th comment:
Davion said:
triskaledia said:
So, if I wanted to setup damage values based upon a character level, I could setup 100 numbers within that array
and set level = ch->level and it would pull the designated number from the array?

Yes, but make sure to set the size of the array to 101 to account for zero or use level-1

But would it really be necessary to account for 0 or do level -1 if you start at level 1?
02 Jul, 2009, Davion wrote in the 7th comment:
Arrays first index is 0. If you want to use the players level as an index, like say, 100. You'd have to set the array to 101 because you wont be using the 0 index. If you set the array size to 100, then you have to use level-1, because you'd be using the 0 index.
02 Jul, 2009, triskaledia wrote in the 8th comment:
So, just like in most coding, the starting number is always 0, then increments from there.
Thanks for all the help.
–Silence Tyire
12 Jul, 2009, triskaledia wrote in the 9th comment:
Alright, I believe I have tables down for numbers, but now I'm having an issue with attempting to make a table with string values.

{
/***/

OBJ_DATA *gem;
// char buf[512];

static const sh_int gem_num[] =
{
0,
1,
};

static const char gem_name[] =
{
"amethyst" "etc etc",
};

static const char gem_short[] =
{
"small amethyst gem" "small etc etc",
};

static const char gem_long[] =
{
"A small amethyst beautifully glowing" "A small etc etc beautifully glowing",
};

int gnum = number_range(gem_num[0], gem_num[1]);

gem = create_object (get_obj_index (OBJ_VNUM_RGEM), 0);
gem->name = gem_name[gnum];
gem->short_descr = gem_short[gnum];
gem->description = gem_long[gnum];
gem->timer = -1;
gem->cost = number_range(100, 500);
gem->weight = number_range(1,3);
gem->level = ch->level;

obj_to_char (gem, ch);
/***/
return;
}

I get these warnings:
fight.c:4776: warning: assignment makes pointer from integer without a cast
fight.c:4777: warning: assignment makes pointer from integer without a cast
fight.c:4778: warning: assignment makes pointer from integer without a cast

Those warnings come from where the name/short/long are setup.
Right now, it appears to load the object to the char, because it crashes the mud on quit/reboot/copyover.
I'm assuming because the warnings are actually errors.
As always, any help is always appreciated.

–Silence Tyire
12 Jul, 2009, bbailey wrote in the 10th comment:
triskaledia said:
Alright, I believe I have tables down for numbers, but now I'm having an issue with attempting to make a table with string values.

static const char gem_name[] =
{
"amethyst" "etc etc",
};

static const char gem_short[] =
{
"small amethyst gem" "small etc etc",
};

static const char gem_long[] =
{
"A small amethyst beautifully glowing" "A small etc etc beautifully glowing",
};

Those warnings come from where the name/short/long are setup.
Right now, it appears to load the object to the char, because it crashes the mud on quit/reboot/copyover.
I'm assuming because the warnings are actually errors.
As always, any help is always appreciated.

–Silence Tyire

`static const char aString[] = "This is a constant static string.";static const char *arrayOfStrings[] = {  "This is an array of constant static strings.",  "Another string.",  "Yet another string."};`
12 Jul, 2009, triskaledia wrote in the 11th comment:
Alright, that loads the proper gem, with all the proper values and doesn't cause a crash. Thank you.
Is there a set reason why there has to be an asterix besides the char name to make the table work properly?

I do get these warnings:
fight.c:4776: warning: assignment discards qualifiers from pointer target type
fight.c:4777: warning: assignment discards qualifiers from pointer target type
fight.c:4778: warning: assignment discards qualifiers from pointer target type

–Silence Tyire
12 Jul, 2009, bbailey wrote in the 12th comment:
triskaledia said:
Alright, that loads the proper gem, with all the proper values and doesn't cause a crash. Thank you.
Is there a set reason why there has to be an asterix besides the char name to make the table work properly?

–Silence Tyire

The asterisk denotes that it is a pointer. In C, a string is an array of characters. Strings are frequently accessed through pointers to a character which point to the memory location of a character in the array.

You may create a string by explicitly initializing an array of characters.
`char myString[] = "some string";`

You can also implicitly create an array of characters by initializing a pointer to a character with that string.

`char *myString = "some string";`

When you do this, you are still creating an array of characters, and the pointer is initialized to point to the address of the first character in the array.

`char myString[] = "some string"; // Explicitly create an array of characterschar *stringPointer = &myString[0]; // Make stringPointer point to the first character in myStringchar *stringPointerTwo = "some string";  // Implicitly create an array of characters and make stringPointerTwo point to the first character// stringPointer and strPointerTwo now each point to a different character array// containing "some string" and will show as equal when comparing with string functions, e.g., strcmp()`

For your tables, you were creating an array of strings, which are themselves arrays. So you need to either do that explicitly:

`static const char myArraryOfCharacterArrays[][] = {   "String1",   "String2",   "String3'}`

or implicitly using character pointers:

`static const char *myArrayOfStringPointers[] = {   "String1",   "String2",   "String3"}`

Understanding the relationship between characters, character pointers, and character arrays is crucial to properly manipulating strings in C.
12 Jul, 2009, triskaledia wrote in the 13th comment:
Alright, getting a little better at this whole array/table thing. I've managed to pull the following arrays out of my function gem_load in fight.c, and got them placed inside of tables.c so that I can call them from any part of the code.
const sh_int gem_num[] =
{
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10,
};

const char *gem_name[] =
{
"aquamarine gem", "diamond gem", "emerald gem",
"opal gem", "pearl gem", "ruby gem",
"sapphire gem", "spinel gem", "topaz gem",
"skull", "bones",
};

const char *gem_short[] =
{
"a small aquamarine", "a small diamond", "a small emerald",
"a small opal", "a small pearl", "a small ruby",
"a small sapphire", "a small spinel", "a small topaz",
"a small skull", "a small set of bones",
};

const char *gem_long[] =
{
"A small aquamarine beautifully glowing", "A small diamond beautifully glowing", "A small emerald beautifully glowing",
"A small opal beautifully glowing", "A small pearl beautifully glowing", "A small ruby beautifully glowing",
"A small sapphire beautifully glowing", "A small spinel beautifully glowing", "A small topaz beautifully glowing",
"A small skull glowing faintly", "A small set of bones",
};

Now, I'm looking to remove the warnings I get when setting the gem->name, gem->short_descr, and gem->description:
warning: assignment makes pointer from integer without a cast
I did some searching on google to see what the error meant. Only found one site that helped and it described the warning as me places a value different than what the variable calls for… I understood it to say since I'm calling sh_int gem_num to setup all the char values of gem-> that it's calling a warning.
int gnum = number_range(gem_num[0], gem_num[10]);
gem->name = gem_name[gnum];
gem->short_descr = gem_short[gnum];
gem->description = gem_long[gnum];
That's how I have it coded… Is there anyway to remove this warning, or as the rest of my warnings that don't seem to really ruin any part of my code, am I stuck with it forever? Also, is the way I have it setup bad coding?
–Silence Tyire
13 Jul, 2009, bbailey wrote in the 14th comment:
triskaledia said:
Now, I'm looking to remove the warnings I get when setting the gem->name, gem->short_descr, and gem->description:
warning: assignment makes pointer from integer without a cast
I did some searching on google to see what the error meant. Only found one site that helped and it described the warning as me places a value different than what the variable calls for… I understood it to say since I'm calling sh_int gem_num to setup all the char values of gem-> that it's calling a warning.
int gnum = number_range(gem_num[0], gem_num[10]);
gem->name = gem_name[gnum];
gem->short_descr = gem_short[gnum];
gem->description = gem_long[gnum];
That's how I have it coded… Is there anyway to remove this warning, or as the rest of my warnings that don't seem to really ruin any part of my code, am I stuck with it forever? Also, is the way I have it setup bad coding?
–Silence Tyire

First, I'd check to make sure you're following the convention for assigning strings in your codebase. Most assign some sort of copy (using strdup, str_dup, or some other function or macro) rather than just assigning the strings directly to name/short_descr/description. E.g., most ROM derivatives would do "gem->name = str_dup(gem_name[gnum]);"

If you're still having trouble after checking on that and sorting it out, then it would be helpful to post the exact error/warning messages and the specific lines of code referenced by those messages. Typically you see that warning when trying to assign a string to a character.

`bobby@dev1:~\$ cat test.cint main(void) {   char *myString = "a string";   char myChar = '\0';   myChar = myString;    // Can't assign a string (character array) to a character.   return 0;}bobby@dev1:~\$ gcc test.ctest.c: In function 'main':test.c:4: warning: assignment makes integer from pointer without a castbobby@dev1:~\$`
13 Jul, 2009, Kline wrote in the 15th comment:
triskaledia said:
const sh_int gem_num[] =
{
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10,
};

Not related to your string issues: but why a table of sequential ints? I'm not certain I understand the use. If you're using it solely for that number_range call, you could more easily use two defines of GEM_MIN and GEM_MAX as 0 and 10 respectively.
14 Jul, 2009, triskaledia wrote in the 16th comment:
Kline said:
Not related to your string issues: but why a table of sequential ints? I'm not certain I understand the use. If you're using it solely for that number_range call, you could more easily use two defines of GEM_MIN and GEM_MAX as 0 and 10 respectively.

Good question. I wasn't really sure how I wanted to set the array up to call a min/max number in the setup of the gems (first attempt at setting up an array). I saw that I was going to be defining an array for the name/short/long and figured I'd just use a table to show that I'd be using # for each of them I setup. I guess in all retrospect I hadn't even thought to define a min/max because I was more concerned with attempting my first array.
–Silence Tyire
14 Jul, 2009, kiasyn wrote in the 17th comment:
Another way of doing this would be:

`struct gem_data{	const char *name;	const char *short;	const char *long;};#define NUM_GEMS 2const struct gem_data gem_list[NUM_GEMS] ={	{ "amethyst", "small amethyst gem", "A small amethyst beautifully glowing" },	{ "etc etc", "small etc etc", "A small etc etc beautifully glowing" }};`

`int gnum = number_range( 0, NUM_GEMS );    gem = create_object (get_obj_index (OBJ_VNUM_RGEM), 0);    gem->name = gem_list[gnum].name;    gem->short_descr = gem_list[gnum].short;    gem->description = gem_list[gnum].long;`

(Code not tested)
15 Jul, 2009, triskaledia wrote in the 18th comment: