01 Dec, 2009, Mudder wrote in the 1st comment:
Votes: 0
I cannot seem to decipher where in this function it separates the skills from the spells list. I was attempting to make a do_skills function and use the former as a guide. Not working for me.

void Character::do_spells( std::string argument )
{
char buf[MAX_STRING_LENGTH];

std::string buf1;

if ( ( !is_npc( ) && !class_table[klass].fMana ) || is_npc( ) )
{
send_to_char( "You do not know how to cast spells!\r\n" );
return;
}

int col = 0;

for ( int sn = 0; sn < MAX_SKILL; sn++ )
{
if ( skill_table[sn].name == NULL )
break;
if ( ( level < skill_table[sn].skill_level[klass] )
@@ || ( skill_table[sn].skill_level[klass] > LEVEL_HERO ) )
continue;

snprintf( buf, sizeof buf, "%18s %3dpts ", skill_table[sn].name,
mana_cost( sn ) );
buf1.append( buf );
if ( ++col % 3 == 0 )
buf1.append( "\r\n" );
}

if ( col % 3 != 0 )
buf1.append( "\r\n" );

send_to_char( buf1 );
return;

}
01 Dec, 2009, David Haley wrote in the 2nd comment:
Votes: 0
Doesn't it just separate itself naturally? Presumably, the spells come first in the list of spells/skills/etc. When it hits a value for sn such that skill_table[sn].name is null, it stops, and therefore never prints the skills.

This code would be wrong, naturally, if you filled up the spells section of the global skill list. (This is revelatory of what is frankly rather cheesy overall design, but eh.)
01 Dec, 2009, Mudder wrote in the 3rd comment:
Votes: 0
I went back and highlighted the part of the code that separates the skills from the spells, but I'm not sure why, or how to reverse it. :(
01 Dec, 2009, David Haley wrote in the 4th comment:
Votes: 0
Well, apparently Merc/Murk++ uses a somewhat arcane way of separating skills and spells, so you'll have to figure out which values of level denote skills and which denote spells, and then test on that.
01 Dec, 2009, Mudder wrote in the 5th comment:
Votes: 0
Some example spells

{"reserved", {99, 99, 99, 99},
NULL, TAR_IGNORE, POS_STANDING,
0, 0, "", ""},
@@ {"acid blast", {20, 37, 37, 37},
&Character::spell_acid_blast, TAR_CHAR_OFFENSIVE, POS_FIGHTING,
20, 12, "acid blast", "!Acid Blast!"},
{"armor", {5, 1, 37, 37},
&Character::spell_armor, TAR_CHAR_DEFENSIVE, POS_STANDING,
5, 12, "", "You feel less protected."},
{"bless", {37, 5, 37, 37},
&Character::spell_bless, TAR_CHAR_DEFENSIVE, POS_STANDING,
5, 12, "", "You feel less righteous."},
{"blindness", {8, 5, 37, 37},
&Character::spell_blindness, TAR_CHAR_OFFENSIVE, POS_FIGHTING,
5, 12, "", "You can see again."},


Some example skills

@@    {"backstab", {37, 37, 1, 37},
&Character::spell_null, TAR_IGNORE, POS_STANDING,
0, 24, "backstab", "!Backstab!"},
{"disarm", {37, 37, 10, 37},
&Character::spell_null, TAR_IGNORE, POS_FIGHTING,
0, 24, "", "!Disarm!"},
{"dodge", {37, 37, 1, 37},
&Character::spell_null, TAR_IGNORE, POS_FIGHTING,
0, 0, "", "!Dodge!"},
{"enhanced damage", {37, 37, 37, 1},
&Character::spell_null, TAR_IGNORE, POS_FIGHTING,
0, 0, "", "!Enhanced Damage!"},
01 Dec, 2009, David Haley wrote in the 6th comment:
Votes: 0
Which field is the level?
01 Dec, 2009, David Haley wrote in the 7th comment:
Votes: 0
Here's what I posted to IMC… I'm too lazy to re-write it into forum speak, so here's a direct quote.

Quote
[Mon Nov 30 20:51:56 2009] [Server01:ichat] DavidHaley@MW: ok here's my theory… this works "by accident". there is no separation between skills and spells.
[Mon Nov 30 20:52:08 2009] [Server01:ichat] DavidHaley@MW: the line that tests against LEVEL_HERO is not testing if it's a skill or spell – it's testing if you have that available
[Mon Nov 30 20:52:31 2009] [Server01:ichat] DavidHaley@MW: so as I suspected earlier (which is why I was skeptical of the claim that that line was deliberately testing skill vs. spell) that line is not actually differentiating skills from spells
[Mon Nov 30 20:53:03 2009] [Server01:ichat] DavidHaley@MW: rather, it is simply seeing if your character's level is within the necessary range for that skill/spell
[Mon Nov 30 20:53:14 2009] [Server01:ichat] DavidHaley@MW: it so happens that spell casters do not get any of the "skill" skills
[Mon Nov 30 20:53:22 2009] [Server01:ichat] DavidHaley@MW: you can verify this yourself by looking at the skill list
[Mon Nov 30 20:53:37 2009] [Server01:ichat] DavidHaley@MW: it also so happens that the non-spell-casters do not get the "spell" skills – you can also verify this
[Mon Nov 30 20:54:22 2009] [Server01:ichat] DavidHaley@MW: therefore when you commented out that line, you basically started displaying everything
01 Dec, 2009, quixadhal wrote in the 8th comment:
Votes: 0
You have your answer in the snippet you posted :)

Note that all spells have a pointer to aCharacter::spell_foo, whereas all skills have aCharacter::spell_null in that position. Sooo, if the pointer is null (or in this case, points to spell_null), it's a skill.
01 Dec, 2009, Mudder wrote in the 9th comment:
Votes: 0
That's how I am used to doing things with ROM, but it wasn't and I thought they were actually being sorted, not some weird scheme of never giving a skill or spell to a non-fighter or non-mage respectively.

Currently I'm checking against null and seeing if it's working. Though I'm getting warnings about NULL being used in arithmetic.
01 Dec, 2009, Twisol wrote in the 10th comment:
Votes: 0
I'm not seeing any reference to spell_foo in the original code, though. I believe Mudder tested David's theory and it seemed to be correct - the function isn't sorting at all, it's just a lucky coincidence.
01 Dec, 2009, Tyche wrote in the 11th comment:
Votes: 0
Yes. In Merc, spells and skills share the same table. If a mage/cleric could have skills they'd show up.
A do skills command would have to change the check at the top of the code…

if ( ( !is_npc( ) && !class_table[klass].fMana ) || is_npc( ) )


and probably change the output.

snprintf( buf, sizeof buf, "%18s %3dpts ", skill_table[sn].name,
mana_cost( sn ) );

since mana cost isn't meaningful.
01 Dec, 2009, Mudder wrote in the 12th comment:
Votes: 0
For my do_skills I simply added a check to do_spells

if ( ( level < skill_table[sn].skill_level[klass] )
|| ( skill_table[sn].skill_level[klass] > LEVEL_HERO )
@@ || ( !skill_table[sn].spell_fun == NULL ) )
continue;


But in order for that to work I had to change the skills in skill_table like this

{"disarm", {1, 1, 10, 1},
@@ &Character::spell_null, TAR_IGNORE, POS_FIGHTING,
0, 24, "", "!Disarm!"},
{"dodge", {37, 37, 1, 37},
NULL, TAR_IGNORE, POS_FIGHTING,
@@ 0, 0, "", "!Dodge!"},


Changing &Character::spell_null to simply NULL. I wasn't able to compare it the way I was attempting until I did that. Would that cause issues down the road?
01 Dec, 2009, Twisol wrote in the 13th comment:
Votes: 0
I might be missing something, but couldn't you test '== &Character::spell_null' instead of '== NULL'?
01 Dec, 2009, Mudder wrote in the 14th comment:
Votes: 0
I tried using == spell_null; and == &Character::spell_null; it wouldn't even compile.
01 Dec, 2009, Twisol wrote in the 15th comment:
Votes: 0
What sort of errors were they? I'm curious.
01 Dec, 2009, Mudder wrote in the 16th comment:
Votes: 0
I'll re-create them for ya.

if ( ( level < skill_table[sn].skill_level[klass] )
|| ( skill_table[sn].skill_level[klass] > LEVEL_HERO )
|| ( !skill_table[sn].spell_fun == spell_null ) )
continue;

Gives:

commands.cpp: In member function 'void Character::do_skills<std::string>":
commands.cpp:3184: error: invalid use of member (did you forget the '&' ?)
make: *** [commands.o] Error 1


if ( ( level < skill_table[sn].skill_level[klass] )
|| ( skill_table[sn].skill_level[klass] > LEVEL_HERO )
|| ( !skill_table[sn].spell_fun == &Character::spell_null ) )
continue;

Gives:

commands.cpp: In member function 'void Character::do_skills<std::string>':
commands.cpp:3184: error: invalid operands of types 'bool' and 'void (Character::*)(int, int, void*)' to binary 'operator=='
make: *** [commands.o] Error 1
01 Dec, 2009, Tyche wrote in the 17th comment:
Votes: 0
Mudder said:
Changing &Character::spell_null to simply NULL. I wasn't able to compare it the way I was attempting until I did that. Would that cause issues down the road?


Try "cast steal" and see.
01 Dec, 2009, Mudder wrote in the 18th comment:
Votes: 0
<45hp 77m 120mv> cast 'backstab'
You lost your concentration.

Damn!
01 Dec, 2009, Twisol wrote in the 19th comment:
Votes: 0
The first change (where you left out &Character::) I wouldn't expect to compile, because it doesn't know what spell_null is at that point. The second… *scratch* I was definitely not expecting a function pointer.
01 Dec, 2009, Tyche wrote in the 20th comment:
Votes: 0
if ( ( level < skill_table[sn].skill_level[klass] )
|| ( skill_table[sn].skill_level[klass] > LEVEL_HERO )
|| ( skill_table[sn].spell_fun != &Character::spell_null ) )
continue;


If that's what you really mean…

!skill_table[sn].spell_fun is an operation that results in a boolean
Random Picks
0.0/23