Skill rewrites w/out changing the SPELLO macro

CAVNESS@utxvms.cc.utexas.edu
Date: 08/04/94


I did the skill rewrite without changing the SPELLO macro... here it is:

int skill(char *arg, char *abbv, int skill, int max_perc, struct char_data *ch,
int level)
{
  char buf2[MAX_STRING_LENGTH];
  int percent = 0;
  extern struct int_app_type int_app[26];

  if (is_abbrev(arg, abbv)) 
  {
    if (GET_SKILL(ch, skill) >= max_perc)
      sprintf(buf2, "You have already mastered this skill.\n\r");
    else 
    {
      if(GET_LEVEL(ch) >= level)
      {
        sprintf(buf2, "You practice a while...\n\r");
        percent = GET_SKILL(ch, skill) + MIN(int_app[GET_INT(ch)].learn, 12);
        SET_SKILL(ch, skill, MIN(max_perc, percent));
        SPELLS_TO_LEARN(ch)--;
        if (GET_SKILL(ch, skill) >= max_perc)
          strcat(buf2, "You are now learned in this area.\n\r");
      }
      else strcat(buf2, "You do not know of this skill.");
   send_to_char(buf2, ch);
   return(TRUE);
    }
  }
 else return(FALSE);
}

char *print_skill_name(char *name, int skill, struct char_data *ch, int level)
{
 char buf2[MAX_STRING_LENGTH];

 strcpy(buf2, "");
 if (GET_LEVEL(ch) >= level) 
  sprintf(buf2, "%-20s %s\n\r", name,
          how_good(GET_SKILL(ch, skill)));
 return(buf2);
}  


Those are the two main functions for skills that I used. Now, you need to go 
into SPECIAL(guild) and make these constants:

static char *w_skills[] = {}  /* here you will put ALL warrior skill names */
static char *t_skills[] = {}  /* here you will put ALL thief skill names */

unsigned int w_skill_info[][3] = 
   {SKILL_define, min_level, max_practice_percent}
unsigned int t_skill_info[][3] = 
   {SKILL_define, min_level, mad_practice_percent}

Now, these constants make it take 2 lines of code to add any new skill to the
spec procs, as all you have to do is add to them...here's the way StrangeMUD
does w_skills[] and w_skill_info[][3]


static char *w_skills[] = {
      "shield parry",
      "headbutt",
      "track",
      "uppercut",
      "second attack",
      "hitall",
      "compare",
      "kick",
      "bash",
      "rescue",
      "disarm",
      "\n"
      };
**** note the \n at the end...this lets the for loop you'll see in a bit know
that it's the end of the loop ****

  unsigned int w_skill_info[][3] = 
    { 
     { SKILL_SHIELDPARRY,  5,  85 },
     { SKILL_HEADBUTT,     10, 85 },
     { SKILL_TRACK,        5,  90 },
     { SKILL_UPPERCUT,     15, 85 },
     { SKILL_SECOND_ATTACK,20, 85 },
     { SKILL_HITALL,       0,  90 },
     { SKILL_COMPARE,      0,  95 },
     { SKILL_KICK,         0,  80 },
     { SKILL_BASH,         0,  80 },
     { SKILL_RESCUE,       0,  80 },
     { SKILL_DISARM,       10,  75 },
     { TYPE_UNDEFINED,     0,   0 },  
};

*** note the TYPE_UNDEFINED, 0, 0 section...this is the way the for loop you'll
see in a bit will know it's the end of the loop ***


Now, in: case CLASS_THIEF you will REPLACE EVERYTHING with the following:

   case CLASS_THIEF:
      if (!*arg) 
      {
         sprintf(buf, "You have got %d practice sessions left.\n\r"
             "You can practice any of these skills:\n\r",
             SPELLS_TO_LEARN(ch));

         for (index = 0; *t_skills[index] != '\n'; index++)
           strcat(buf, 
                        print_skill_name(t_skills[index], 
                                         t_skill_info[index][0], 
                                         ch, 
                                         t_skill_info[index][1]));
   
         send_to_char(buf, ch);
         return(TRUE);
      }

      if (SPELLS_TO_LEARN(ch) <= 0) {
         send_to_char("You do not seem to be able to practice now.\n\r", ch);
         return(TRUE);
      }

    
     for (index=0;t_skill_info[index][0]!=TYPE_UNDEFINED; index++)
     {
       if(!skill(arg, 
                 t_skills[index], 
                 t_skill_info[index][0],
                 t_skill_info[index][2],
                 ch, 
                 t_skill_info[index][1])) continue;
       else return(TRUE);
    }  
   
      break;


and in case CLASS_WARRIOR you will REPLACE EVERYTHING with:

     if (!*arg) 
       {
         sprintf(buf, "You have %d practice sessions left.\n\r"
             "You can practice any of these skills:\n\r",
             SPELLS_TO_LEARN(ch));
                  
         for(index=0;*w_skills[index] != '\n'; index++)
           strcat(buf, print_skill_name(w_skills[index], 
                                        w_skill_info[index][0],
                                        ch, 
                                        w_skill_info[index][1]));

         send_to_char(buf, ch);
        return(TRUE);
       }


      if (SPELLS_TO_LEARN(ch) <= 0) 
      {
         send_to_char("You do not seem to be able to practice now.\n\r", ch);
         return(TRUE);
       }

      for(index = 0; w_skill_info[index][0]!=TYPE_UNDEFINED; index++)
      {
        if(!skill(arg,
                    w_skills[index],
                    w_skill_info[index][0],
                    w_skill_info[index][2],
                    ch,
                    w_skill_info[index][1])) continue;
        else return(TRUE);
      }

   break;





So, for example, to make the new skill BEARHUG for warriors,(minimum level can
use or practice: level 13, max percent of skill you can learn: 66)
you would do the following:


1. In spells.h, add:
   #define SKILL_BEARHUG your#here
2. Make a ACMD(do_bearhug) in act.offensive.c that has the actual code for the
   skill.
3. In interpreter.c, add the ACMD() to the prototype list,
   command to the command[] constant and also add the
   appropriate COMMANDO() --btw, you usually want to use POSITION_FIGHTING...why
   this is different from all the other commandos I will NEVER know, but owell.
4. In spec_procs.c, add the following lines:
   to w_skills[]:
   "bearhug",

   to w_skill_info[][3]:
   { SKILL_BEARHUG, 13, 66 },

   and you're done!!!!


There are, no doubt, much better ways to code this, but I personally like
having to add only 2 more lines per skill code that I make :) It also gets
rid of the MAJOR spaghetti code for skills(Though it doesn't begin to get
rid of the spaghetti code for spells, I can only do one thing at a time :) )

Most of us don't have the coding skills that Mr. Fink does :)

******* NOTE: You MUST put the string in w_skills[] and the string in
w_skill_info[][3] in the SAME PLACE in the code(ie, corresponding lines) ******

I.E. if you put "bearhug" in the 4th slot of w_skills, you have to put hte
  {SKILL_BEARHUG, 13, 66} into the 4th slot of w_skill_info[][3] :)

Well, there you go. Coding the Strange(tm) way. 



This juicy tidbit has been brought to you by the letter "K" and the number
"69".





~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cavness@utxvms.cc.utexas.edu        |       The Great Holy Star Goat
Kenneth G. Cavness                  |          is with all of us,
"Supreme Diva"                      |         braised be Its name.
"I'm pro-choice--please don't       |
shoot me in the back."              |     Braise the name of Our Lard!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    



This archive was generated by hypermail 2b30 : 12/07/00 PST