/* * The class howto part 2 * * If you haven't read the first part, go do that. * * By Jobo, coder for the Godwars mud Dystopia. */ In this howto I plan on covering the subject of class channels, weapon skill levels and adding a nicer look to the 'powers' command (the one that lists the classpowers a player can use). I will also mention how to add more than the 15'ish class limit Dystopia currenly has. First let's see how we add a talkchannel for our Titan class. For this we need a basic command like do_sign (for drows sign channel), this should be coded like any other class power, though it should probably be added as useable as POS_DEAD in interp.c since we want the player to use the channel even though he is stunned, sleeping or mortally wounded. we should add this function to act_comm.c since it contains most communication. void do_titantalk(CHAR_DATA *ch, char *argument) { /* * Titans and Immortals only. We want immortals to use it as well, since they might * need to tell all the Titans something. IS_IMMORTAL is a macro to decide whether * a player is a god (you still need to check for NPC's though). */ if (IS_NPC(ch)) return; if (!IS_IMMORTAL(ch) && !IS_CLASS(ch, CLASS_TITAN)) { send_to_char("Huh?\n\r",ch); return; } /* * Before we go any futher, we need to define a channel for out Titans called CHANNEL_TITAN, * and it must be defined as a bitvector, since players have the option of turning channels * on/off. Open merc.h and find the place where the old channels are defined (ie. CHANNEL_SIGN) * then add CHANNEL_TITAN to the list (remember to double the value of the last defined). * * Now we call the talk_channel() function, which takes care of almost all communication between * players. We tell it which player (ch) that's talking, what he is talking (argument) and what * channel he is talking on (CHANNEL_TITAN). The last string ("titantalk") is only used for * error messages, should the player try to titantalk an empty string, he would get the * error message "titantalk what ??". */ talk_channel(ch, argument, CHANNEL_TITAN, "titantalk"); /* * Done. */ return; } Now it's time to edit the function talk_channel() which is also located in act_comm.c, since it needs to know what to do with the CHANNEL_TITAN. Scroll down in the function till you reach a series of cases which looks something like this : case CHANNEL_ANGEL: sprintf( buf, "#0[#7%s#0]#C '$t'.#n",ch->name ); position = ch->position; ch->position = POS_STANDING; act( buf, ch, argument, NULL, TO_CHAR ); ch->position = position; break; We need to add one for our CHANNEL_TITAN, so lets do that : case CHANNEL_TITAN : /* * We use the function sprintf to do this, remember how it works ? * If not, read the class powers howto. The $t variable isn't used * in sprintf, so it will just get passed on as $t. We will use it * later in a call to act(). */ sprintf(buf, "(X)%s(X) '$t'.", ch->name); /* * Now for something silly, we let the player stand, then call act(), and * then return the player to his previous position. I doubt theres any * reason to do this, feel free to leave it out, and see what happens. * Just remember the act() call :) */ position = ch->position; ch->position = POS_STANDING; act( buf, ch, argument, NULL, TO_CHAR ); ch->position = position; break; With the message well parsed, we just need to send it to everyone else on the mud. The player himself have already gotten the message (our call to act()). Scroll down and locate a series of if's that look like this : if (channel == CHANNEL_SIGN && (!IS_NPC(och) && !IS_CLASS(och, CLASS_DROW) && !IS_IMMORTAL(och))) continue; This simply makes sure that only those who are either of the correct class or an immortal get's the message, so let's add one for Titans. if (channel == CHANNEL_TITAN && (!IS_NPC(och) && !IS_CLASS(och, CLASS_TITAN) && !IS_IMMORTAL(och))) continue; We are done. talk_channel() will take care of the rest, parsing our buf variable and sending it to all the players that match our demands (Titans and immortals). Just use some nifty symbols and colors for your channel - defined in that call to sprintf(). Now let's look at interp.c - when a player types 'powers' we list all the possibly class powers, but you might have noticed that the screen looks something like this : (using drows). -=[**]=-=[**]=-=[**]=-=[**]=-=[**] Powers [**]=-=[**]=-=[**]=-=[**]=-=[**]=- Drow Abilities : sign grant drowsight drowshield drowfire drowhate drowpowers darkness lloth shadowwalk drowcreate heal garotte spiderform chaosblast dgarotte glamour confuse darktendrils fightdance -=[**]=-=[**]=-=[**]=-=[**]=-=[**]=-=[***]=-=[**]=-=[**]=-=[**]=-=[**]=-=[**]=- The thing to notice is the "Drow Abilities" string. Unless we define something similar for our Titan class, we will just get a boring looking powers list. So lets open interp.c and edit the function do_racecommands(), scroll down a short bit, and locate the series of cases that looks a bit like this : switch (ch->class) { case 1 : sprintf(buf, " %15s : ", "Demon Kind");break; case 2 : sprintf(buf, " %15s : ", "Magi");break; case 4 : sprintf(buf, " %15s : ", "Innate"); break; case 8 : sprintf(buf, " %15s : ", "Innate");break; case 16: sprintf(buf, " %15s : ", "Weaponsmaster");break; case 32: sprintf(buf, " %15s : ", "Drow Abilities");break; case 64: sprintf(buf, " %15s : ", "Monk Abilities");break; We should add our Titan class to this list (it was defined as class 16384 if I remember correct), so let's add the line case 16384: springtf(buf, " %15s : ", "Titan Powers");break; Now the titans powers list will be a bit more fancy looking. Now let's look at the weaponskill limit for Titans. If we don't define one, it will be 200, which is the base for all classes. But since Titans are so big, we want them to have a limit at 300 in all weaponskills (you can change stance and spell limits in much the same way). Open the file kav_fight.c and edit the function improve_wpn(), theres a list of classes, giving each class a different level, so let's add one for Titans. else if (IS_CLASS(ch, CLASS_TITAN)) max_skl = 300; Now our Titans can get all their weapons to level 300 before maxing out. Let's finish up part two with learning how to extend the amount of classes we can define. Currently the released dystopia code has 'class' defined as a short integer, allowing for 15 different classes, we need to extend this by editing merc.h and the structure for char_data. The structure should look something like this : /* * One character (PC or NPC). */ struct char_data { /* * Contains the structfore for a mobile/player, we should look for the line * that looks like sh_int class; * * and change it to : * int class; * * Now recompile the _entire_ code by deleting all .o files (rm *.o) and type make. * Now you can define more classes :) */ } Good luck Jobo