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 ➜ SMAUG ➜ SMAUG coding ➜ Adding Multiclass to Mud.h (is this not possible?)

Adding Multiclass to Mud.h (is this not possible?)

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


Posted by Zedethar   (17 posts)  Bio
Date Thu 25 Feb 2021 03:01 PM (UTC)

Amended on Thu 25 Feb 2021 03:07 PM (UTC) by Zedethar

Message
Hey everyone,

As I am trying to add an old multiclass code from Lost Prophecy files. To the 1.9.3 smaug mud.h file I notice that I cannot find the exact location of the first changes.

It states:
in mud.h

to char_data below

sh_int class;
add
sh_int dualclass;

Add to your defines:
#define IS_DUAL(ch) ((ch)->dualclass > -1)

change IS_VAMPIRE

#define IS_VAMPIRE(ch) (!IS_NPC(ch) \
&& ((ch)->class==CLASS_VAMPIRE \
|| (ch)->dualclass==CLASS_VAMPIRE))

Add the following prototypes in:

bool DUAL_SKILL args((CHAR_DATA *ch, int sn));
int dual_adept args((CHAR_DATA *ch, int sn));
int find_skill_level args((CHAR_DATA *ch, int sn));
int hp_max args((CHAR_DATA *ch));
int hp_min args((CHAR_DATA *ch));
bool use_mana args((CHAR_DATA *ch));


When I look in mud.h I do not see a reference that looks like:

sh_int class;
under a char_data field. Is it possible to still add
multiclass to the new version or am I not seeing where the proper field is?

If anyone has attempted this recently and can give info it would help me greatly.

-------
Could this be referring to the this section of mud.h

struct char_data
{
CHAR_DATA *next;
CHAR_DATA *prev;
CHAR_DATA *next_in_room;
CHAR_DATA *prev_in_room;
CHAR_DATA *master;
CHAR_DATA *leader;
FIGHT_DATA *fighting;
CHAR_DATA *reply;
CHAR_DATA *retell;
CHAR_DATA *switched;
CHAR_DATA *mount;
HHF_DATA *hunting;
HHF_DATA *fearing;
HHF_DATA *hating;
VARIABLE_DATA *variables;
SPEC_FUN *spec_fun;
const char *spec_funname;
MPROG_ACT_LIST *mpact;
int mpactnum;
unsigned short mpscriptpos;
MOB_INDEX_DATA *pIndexData;
DESCRIPTOR_DATA *desc;
AFFECT_DATA *first_affect;
AFFECT_DATA *last_affect;
NOTE_DATA *pnote;
NOTE_DATA *comments;
OBJ_DATA *first_carrying;
OBJ_DATA *last_carrying;
ROOM_INDEX_DATA *in_room;
ROOM_INDEX_DATA *was_in_room;
PC_DATA *pcdata;
DO_FUN *last_cmd;
DO_FUN *prev_cmd; /* mapping */
void *dest_buf; /* This one is to assign to differen things */
const char *alloc_ptr; /* Must str_dup and free this one */
void *spare_ptr;
int tempnum;
EDITOR_DATA *editor;
TIMER *first_timer;
TIMER *last_timer;
CHAR_MORPH *morph;
const char *name;
const char *short_descr;
const char *long_descr;
const char *description;
short num_fighting;
short substate;
short sex;
short Class;
short race;
short level;
short trust;
int played;
time_t logon;
time_t save_time;
short timer;
short wait;
short hit;
short max_hit;
short mana;
short max_mana;
short move;
short max_move;
short practice;
short numattacks;
int gold;
int exp;
EXT_BV act;
EXT_BV affected_by;
EXT_BV no_affected_by;
int carry_weight;
int carry_number;
int xflags;
int no_immune;
int no_resistant;
int no_susceptible;
int immune;
int resistant;
int susceptible;
EXT_BV attacks;
EXT_BV defenses;
int speaks;
int speaking;
short saving_poison_death;
short saving_wand;
short saving_para_petri;
short saving_breath;
short saving_spell_staff;
short alignment;
short barenumdie;
short baresizedie;
short mobthac0;
short hitroll;
short damroll;
short hitplus;
short damplus;
short position;
short defposition;
short style;
short height;
short weight;
short armor;
short wimpy;
int deaf;
short perm_str;
short perm_int;
short perm_wis;
short perm_dex;
short perm_con;
short perm_cha;
short perm_lck;
short mod_str;
short mod_int;
short mod_wis;
short mod_dex;
short mod_con;
short mod_cha;
short mod_lck;
short mental_state; /* simplified */
short emotional_state; /* simplified */
int retran;
int regoto;
short mobinvis; /* Mobinvis level SB */
short colors[MAX_COLORS];
int home_vnum; /* hotboot tracker */
int resetvnum;
int resetnum;
bool loadedself; /* Used to see if mpmloaded self, if so skip changing the reset for it currently */



---
If anyone has any information on this please let me know.

Thanks
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #1 on Thu 25 Feb 2021 08:37 PM (UTC)

Amended on Thu 25 Feb 2021 08:38 PM (UTC) by Nick Gammon

Message

In the Github version at line 2163 there is a “short Class” field which is what they would be referring to:

https://github.com/Arthmoor/SmaugFUSS/blob/master/src/mud.h#L2163

The instructions you found must have had “sh_int” (short integer) as a typedef. “short” is more normal.

Note that “class” is a reserved word in C++ which is why it is capitalized as “Class” unlike most of the other variable names.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,533 posts)  Bio   Global Moderator
Date Reply #2 on Thu 25 Feb 2021 10:53 PM (UTC)

Amended on Thu 25 Feb 2021 11:02 PM (UTC) by Fiendish

Message

Yeah, it looks like they changed from C to C++ in 1.6 and renamed a bunch of things because of that:

https://github.com/Arthmoor/SmaugFUSS/commit/187e5d7f19ec31719b030296f3bd479f06502d9a#diff-0bdc8797a7da6e7e9d8e1713622c827ad00b5e33c9f820a5169d0ee3a72e2794R2145

Like Nick says, start with just replacing all instances of “sh_int” with “short” and “class” with “Class” in your instructions and in the code you want to add.


https://github.com/fiendish/aardwolfclientpackage
Top

Posted by Zedethar   (17 posts)  Bio
Date Reply #3 on Fri 26 Feb 2021 03:33 AM (UTC)

Amended on Fri 26 Feb 2021 04:08 AM (UTC) by Zedethar

Message
Ok I made it past a few of the steps with no problem so far.. This would seems like it is written differently though. What are your thoughts about this - looking at my version it seems something has changed.

In update.c, within advance_level find and change:

add_hp = con_app[get_curr_con(ch)].hitp + number_range(
class_table[ch->class]->hp_min,
class_table[ch->class]->hp_max );
add_mana = class_table[ch->class]->fMana
? number_range(2, (2*get_curr_int(ch)+get_curr_wis(ch))/8)
: 0;

Into:


add_hp = con_app[get_curr_con(ch)].hitp + number_range(
hp_min(ch),
hp_max(ch) );
add_mana = use_mana(ch) ?
? number_range(2, (2*get_curr_int(ch)+get_curr_wis(ch))/8)
: 0;



-------
MY VERSION:

void advance_level( CHAR_DATA * ch )
{
char buf[MAX_STRING_LENGTH];
int add_hp, add_mana, add_move, add_prac;

snprintf( buf, MAX_STRING_LENGTH, "the %s", title_table[ch->Class][ch->level][ch->sex == SEX_FEMALE ? 1 : 0] );
set_title( ch, buf );

add_hp = con_app[get_curr_con( ch )].hitp + number_range( class_table[ch->Class]->hp_min, class_table[ch->Class]->hp_max );
add_mana = class_table[ch->Class]->fMana ? number_range( 2, ( 2 * get_curr_int( ch ) + get_curr_wis( ch ) ) / 8 ) : 0;
add_move = number_range( 5, ( get_curr_con( ch ) + get_curr_dex( ch ) ) / 4 );
add_prac = wis_app[get_curr_wis( ch )].practice;

add_hp = UMAX( 1, add_hp );
add_mana = UMAX( 0, add_mana );
add_move = UMAX( 10, add_move );



---- Ok I might understand it now.. looks like they cut the lines short when they wrote it? It should be as long as the ones in mud.h
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #4 on Fri 26 Feb 2021 04:45 AM (UTC)
Message
It looks like your instructions wrap the lines in a weird way. It should compile though because, by and large, extra newlines don't matter in C. (It would in a #define).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zedethar   (17 posts)  Bio
Date Reply #5 on Fri 26 Feb 2021 08:35 AM (UTC)
Message
Thanks for the support guys. You guys are great. I am going to try to finish the rest of it when I get home from work. I know I still have to make a multiclass command in game as well. Will let you know how it goes.

Thanks
Top

Posted by Zedethar   (17 posts)  Bio
Date Reply #6 on Sat 27 Feb 2021 02:50 AM (UTC)
Message
Another step that doesn't look like it exists in 1.9.3 act_info.c

inside act_info.c inside do_practice find:

change

if ( ch->level < skill_table[sn]->skill_level[ch->class]
|| (!IS_IMMORTAL(ch) && skill_table[sn]->skill_level[ch->class] == 0) )
continue;

into:

if (( ch->level < skill_table[sn]->skill_level[ch->class]
&& !DUAL_SKILL(ch, sn) )
|| (!IS_IMMORTAL(ch) && skill_table[sn]->skill_level[ch->class] == 0
&& !DUAL_SKILL(ch, sn) ) )
continue;

---- I've been unable to find the mentioned line, I know
they are wrapped sentence i'll unwrap if i can just find what they are saying lol. My act_info.c looks like:

void do_practice( CHAR_DATA* ch, const char* argument)
{
CHAR_DATA *mob;
char buf[MAX_STRING_LENGTH];
int sn;

if( IS_NPC( ch ) )
return;

for( mob = ch->in_room->first_person; mob; mob = mob->next_in_room )
if( IS_NPC( mob ) && xIS_SET( mob->act, ACT_PRACTICE ) )
break;

if( argument[0] == '\0' )
{
int col;
short lasttype, cnt;
bool is_ok;

col = cnt = 0;
lasttype = SKILL_SPELL;
set_pager_color( AT_MAGIC, ch );

for( sn = 0; sn < num_skills; ++sn )
{
const SKILLTYPE *skill;
int normalSn;

// the first num_sorted_skills are sorted by type, so we don't want
// to index into skill_table -- that is sorted alphabetically -- so
// we need to do the following dance to check if we are in the
// sorted section or the unsorted section.
if( sn < num_sorted_skills )
{
skill = skill_table_bytype[sn];

// we are looping over the skills sorted by type.
// So, we need to get the normal sn as well.
normalSn = skill_lookup( skill->name );
}
else
{
skill = skill_table[sn];
normalSn = sn;
}

if( !skill || !skill->name || skill->name[0] == '\0' )
continue;

if ( strcmp( skill_table[sn]->name, "reserved" ) == 0 && ( IS_IMMORTAL( ch ) || DUAL_SKILL(ch, sn) ) )
{
if( col % 3 != 0 )
send_to_pager( "\r\n", ch );
set_pager_color( AT_MAGIC, ch );
send_to_pager_color( " ----------------------------------[&CSpells&B]----------------------------------\r\n",
ch );
col = 0;
}

if( skill->type != lasttype )
{
if( !cnt )
send_to_pager( " (none)\r\n", ch );
else if( col % 3 != 0 )
send_to_pager( "\r\n", ch );
set_pager_color( AT_MAGIC, ch );
pager_printf_color( ch,
" ----------------------------------&C%ss&B----------------------------------\r\n",
skill_tname[skill->type] );
col = cnt = 0;
}
lasttype = skill->type;

if( !IS_IMMORTAL( ch )
&& ( skill->guild != CLASS_NONE && ( !IS_GUILDED( ch ) || ( ch->pcdata->clan->Class != skill->guild ) ) ) )
continue;

The next half mentions mobs...
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #7 on Sat 27 Feb 2021 05:28 AM (UTC)
Message
Template:codetag To make your code more readable please use [code] tags as described here.


Your posted code looks pretty rough if you don't do that.


Your problem is that a posting that says "change line X to read Y" for code that is years old probably won't work. The code base will have been updated, improved, and things moved around.

Your best bet would be to read the intention of the changes, and then replicate them as best you can.

Alternatively, just work out what you want to happen and just code it. So you want multiclass? What will that mean to the player? Will they get spells/skills from both classes? You would need to try to (say) use a spell from the second class, and then see what error message you get. Find that part of the code and change it to allow for the second class. And so on.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zedethar   (17 posts)  Bio
Date Reply #8 on Thu 11 Mar 2021 04:18 PM (UTC)

Amended on Thu 11 Mar 2021 04:27 PM (UTC) by Zedethar

Message
Ok I've tried my best to get through this whole multiclass implement. There is only one snag that I can't seem to get by. I managed to re-write all of them to make it work except for the ones for magic.c

This is the compiling error below:
magic.c: In function ‘int bsearch_skill_prefix(const char*, int, int)’:
magic.c:228:7: error: ‘ch’ was not declared in this scope
228 | && ch->pcdata->learned[sn] > 0

(I need to define this CH?)
I haven't figured out how to do this yet.


This is the line I have been instructed to change to in magic.c below:

if (!str_cmp(name, skill_table[sn]->name) && ch->pcdata->learned[sn] > 0 && (ch->level >= skill_table[sn]->skill_level[ch->Class] || DUAL_SKILL(ch, sn) ) )

Does anyone know where or how I can define this? I am just trying to get a 2 class system going where people can get skills from both classes and I think that would be good enough for now. Maybe these old codes aren't going to work and may not be worth trying? Do you think there is a better mud than Smaug that has multiclass built in already?
Top

Posted by Fiendish   USA  (2,533 posts)  Bio   Global Moderator
Date Reply #9 on Thu 11 Mar 2021 06:06 PM (UTC)

Amended on Thu 11 Mar 2021 06:15 PM (UTC) by Fiendish

Message
Quote:
This is the line I have been instructed to change to in magic.c below:

But you don't tell us where you've been instructed to put that or why.

Quote:
In function ‘int bsearch_skill_prefix(const char*, int, int)’:

bsearch_skill_prefix is for matching skill number to skill name. You should not be doing anything there, because it has nothing to do with characters. This incidentally is why there's no ch in that function.

Code isn't just line numbers and symbols. It has meaning. If you just put some symbols on some line without paying attention to what the code means, you're going to corrupt things. Following what Nick said is not optional here.

Nick Gammon said:

Your problem is that a posting that says "change line X to read Y" for code that is years old probably won't work. The code base will have been updated, improved, and things moved around.

Your best bet would be to read the intention of the changes, and then replicate them as best you can.


You have to look at what the code looked like when those instructions were written because the code has changed since then. Things are in different places now. So look at what _was_, compare to what _is_, and adjust the instructions accordingly based on the meaning.

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #10 on Thu 11 Mar 2021 09:21 PM (UTC)
Message
Judging by the snippet you posted, the function in question now has a "ch" argument (probably of type CHAR_DATA*).

So, to make "ch" exist inside that function you would need to pass it, eg.


int bsearch_skill_prefix(const char*, int, int, CHAR_DATA* ch)


(They are clearly using the old-fashioned way of declaring functions, so it might not be exactly that.

Now that function will compile, but every time you call bsearch_skill_prefix you would need to pass down the current character pointer. However I may be wrong about that, I'm just going off the information you provided.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,533 posts)  Bio   Global Moderator
Date Reply #11 on Thu 11 Mar 2021 10:19 PM (UTC)

Amended on Thu 11 Mar 2021 10:37 PM (UTC) by Fiendish

Message
I don't see any reason for bsearch_skill_prefix to ever have char data passed to it given what it does. I'm 100% sure without even looking up the old code that Zedethar is editing the wrong function.

Note that there used to be a similar function ch_bsearch_skill_prefix elsewhere in the file that did care about the character but that function was renamed in https://github.com/Arthmoor/SmaugFUSS/commit/11d830587627511173496deeb017e013ddaa277e#diff-2ff6e41d9ca72e4855bcc83f75c232711fcf956ec163e9e07e0285b795419771R62

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by Zedethar   (17 posts)  Bio
Date Reply #12 on Fri 12 Mar 2021 05:10 AM (UTC)
Message
Nick your suggestion actually worked and got me last that section in magic.c but soon after in their dualclass.c file
It shows many errors as well. I appreciate the help guys, I learned alot from this experience at least. I am going to drop this old multiclass code since it's having this many issues and search some sites for an experienced coder for hire that wants to collaborate with a new mud creation. I believe making a multiclass code for 1.9.3 or newer will be an easier route.

Cheers
Top

Posted by Fiendish   USA  (2,533 posts)  Bio   Global Moderator
Date Reply #13 on Sat 13 Mar 2021 11:50 PM (UTC)

Amended on Sat 13 Mar 2021 11:53 PM (UTC) by Fiendish

Message
Quote:
an experienced coder for hire

How much are you willing to pay to adapt the instructions you have to the current codebase?

https://github.com/fiendish/aardwolfclientpackage
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.


28,397 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.