skills and stuff

From: The Chronicler (ACCMCM@vaxc.hofstra.edu)
Date: 08/02/94


Hey all you circle guys and gals.

This is my SKILL/SPELL documentation withsource code included.

One thing..there may be bugs...see im using a much later version of this
so multiple classes work.  Also in my new system...i no longer have just mage and
cleric allowed to use spells....

this is older code...i think all the bugs are out....but maybe not.


ok here we go....


im sure a better coder, such as jermey..could develop or help you better but
here's my attempt.


PS: this is long..i would individual mail it....but enough seem interested.
all who arent...delete and ignore.


		/****** SOURCE CODE *****/


		/* SPELLS.H */

#define SKILL_BACKSTAB               500 /* Reserved Skill[] DO NOTCHANGE */
#define SKILL_STEAL                  501 /* Reserved Skill[] DO NOT CHANGE */
#define SKILL_SNEAK                  502 /* Reserved Skill[] DO NOT CHANGE */
#define SKILL_PICK_LOCK              503 /* Reserved Skill[] DO NOT CHANGE */
#define SKILL_HIDE                   504/* Reserved Skill[] DO NOT CHANGE */
#define SKILL_PEEK                   505
#define SKILL_CIRCLE                 506
#define SKILL_TUMBLE                 507
#define SKILL_APPRAISE               508
#define SKILL_RETREAT                509

#define SKILL_KICK                   550 /* Reserved Skill[] DO NOT CHANGE */
#define SKILL_BASH                   551 /* Reserved Skill[] DO NOT CHANGE */
#define SKILL_RESCUE                 552
#define SKILL_POUND                  553
#define SKILL_DOUBLE_HIT             554
#define SKILL_BLOCK                  555
#define SKILL_BERSERK                556
#define SKILL_PUMMEL                 557
#define SKILL_TRIPLE_HIT             558
#define SKILL_THROW                  559
#define SKILL_PARRY                  560
#define SKILL_SLAM                   561
/* END OF SKILL RESERVED "NO TOUCH" NUMBERS */


/* NEW SPELLS are to be inserted here */
#define SPELL_IDENTIFY               53
#define SPELL_ANIMATE_DEAD           54 /* EXAMPLE */
#define SPELL_FEAR                   55 /* EXAMPLE */
#define SPELL_FIRE_BREATH            56
#define SPELL_GAS_BREATH             57
#define SPELL_FROST_BREATH           58
#define SPELL_ACID_BREATH            59
#define SPELL_LIGHTNING_BREATH       60
#define SPELL_INFRAVISION            61
#define SPELL_STONESKIN              62
#define SPELL_TSUNAMI                63
#define SPELL_SLAY                   64


/* as you can see the numbers between warrior and thief skills are in order
leaving enough for a fair ammount of skills/spells. */

/* SPEC_PROCS.C */


SPECIAL(guild)
{
   int	number, i, percent;

   extern char	*spells[];
   extern struct spell_info_type spell_info[MAX_SPL_LIST];
   extern struct int_app_type int_app[26];

   static char	*w_skills[] = {
      "kick",  /* No. 550 */
      "bash",
      "rescue",
      "pound",
      "block",
      "berserk",
      "pummel",
      "double hit",
      "throw",
      "parry",
      "triple hit",
      "slam",
      "\n"
   };

   static int	w_skill_levels[] = {
      1,
      3,
      5,
      7,
      9,
      12,
      15,
      18,
      23,
      25,
      28,
      30,
      0
   };

   static char	*t_skills[] = {
      "backstab",
      "steal",
      "sneak",
      "pick",
      "hide",
      "peek",
      "circle",
      "tumble",
      "appraise",
      "retreat",
      "\n"
   };

   static int	t_skill_levels[] = {
      1,
      1,
      3,
      6,
      9,
      12,
      15,
      18,
      21,
      23,
      0
   };

   if (IS_NPC(ch) || ((cmd != 164) && (cmd != 170)))
      return(FALSE);

   for (; *arg == ' '; arg++)
      ;

   if (GET_LEVEL(ch) >= LEVEL_IMMORT)
   {
   if (!*arg) {
	 sprintf(buf, "You have got %d practice sessions left.\n\r"
	     "You can practice any of these spells:\n\r",
	     SPELLS_TO_LEARN(ch));
	 for (i = 0; *spells[i] != '\n'; i++) {
	    if (spell_info[i+1].spell_pointer && (spell_info[i+1].min_level_magic <= GET_LEVEL(ch))) {
	       sprintf(buf2, "(%2d) %-20s %s\n\r",
		   spell_info[i+1].min_level_magic, spells[i],
		   how_good(GET_SKILL(ch, i + 1)));
	       strcat(buf, buf2);
	    }
	 }
	 for (i = 0; *w_skills[i] != '\n'; i++) {
	    sprintf(buf2, "(%2d) %-20s %s\n\r", w_skill_levels[i], w_skills[i],
		how_good(GET_SKILL(ch, i + SKILL_KICK)));
	    strcat(buf, buf2);
	 }
	 for (i = 0; *t_skills[i] != '\n'; i++) {
	    sprintf(buf2, "(%2d) %-20s %s\n\r", t_skill_levels[i], t_skills[i],
		how_good(GET_SKILL(ch, i + SKILL_SNEAK)));
	    strcat(buf, buf2);
	 }
	 send_to_char(buf, ch);
	 return(TRUE);
   }
   send_to_char("As an immortal, please be restored to learn new skills!!!\n\r", ch);
}
  switch (GET_CLASS(ch)) {
      case CLASS_MAGIC_USER :
      if (!*arg) {
	 sprintf(buf, "You have got %d practice sessions left.\n\r"
	     "You can practice any of these spells:\n\r",
	     SPELLS_TO_LEARN(ch));
	 for (i = 0; *spells[i] != '\n'; i++)
	    if (spell_info[i+1].spell_pointer &&
		(spell_info[i+1].min_level_magic <= GET_LEVEL(ch))) {
	       sprintf(buf2, "(%2d) %-20s %s\n\r",
		   spell_info[i+1].min_level_magic, spells[i],
		   how_good(GET_SKILL(ch, i + 1)));
	       strcat(buf, buf2);
	    }
	 send_to_char(buf, ch);
	 return(TRUE);
      }

      number = old_search_block(arg, 0, strlen(arg), spells, FALSE);
      if (number == -1) {
	 send_to_char("You do not know of this spell...\n\r", ch);
	 return(TRUE);
      }
      if (GET_LEVEL(ch) < spell_info[number].min_level_magic) {
	 send_to_char("You do not know of this spell...\n\r", 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);
      }
      if (GET_SKILL(ch, number) >= MAX_LEARN) {
	 send_to_char("You are already learned in this area.\n\r", ch);
	 return(TRUE);
      }

      send_to_char("You Practice for a while...\n\r", ch);
      SPELLS_TO_LEARN(ch)--;

      percent = GET_SKILL(ch, number) + MAX(25, int_app[GET_INT(ch)].learn);
      SET_SKILL(ch, number, MIN(MAX_LEARN, percent));

      if (GET_SKILL(ch, number) >= MAX_LEARN) {
	 send_to_char("You are now learned in this area.\n\r", ch);
	 return(TRUE);
      }

      break;

   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 (i = 0; *t_skills[i] != '\n'; i++) {
	    sprintf(buf2, "(%2d) %-20s %s\n\r", t_skill_levels[i], t_skills[i],
		how_good(GET_SKILL(ch, i + SKILL_SNEAK)));
	    strcat(buf, buf2);
	 }
	 send_to_char(buf, ch);
	 return(TRUE);
      }

      number = search_block(arg, t_skills, FALSE);
      if (number == -1) {
	 send_to_char("You do not know of this skill...\n\r", ch);
	 return(TRUE);
      }
      if (GET_LEVEL(ch) < t_skill_levels[number]) {
	 send_to_char("You do not know of this spell...\n\r", 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);
      }
      if (GET_SKILL(ch, number + SKILL_SNEAK) >= MAX_LEARN) {
	 send_to_char("You are already learned in this area.\n\r", ch);
	 return(TRUE);
      }
      send_to_char("You Practice for a while...\n\r", ch);
      SPELLS_TO_LEARN(ch)--;

      percent = GET_SKILL(ch, number + SKILL_SNEAK) + MIN(int_app[GET_INT(ch)].learn, 12);
      SET_SKILL(ch, number + SKILL_SNEAK, MIN(MAX_LEARN, percent));

      if (GET_SKILL(ch, number + SKILL_SNEAK) >= MAX_LEARN) {
	 send_to_char("You are now learned in this area.\n\r", ch);
	 return(TRUE);
      }

      break;

   case CLASS_CLERIC     :
      if (!*arg) {
	 sprintf(buf, "You have got %d practice sessions left.\n\r"
	     "You can practice any of these spells:\n\r",
	     SPELLS_TO_LEARN(ch));
	 for (i = 0; *spells[i] != '\n'; i++)
	    if (spell_info[i+1].spell_pointer &&
		(spell_info[i+1].min_level_cleric <= GET_LEVEL(ch))) {
	       sprintf(buf2, "(%2d) %-20s %s\n\r",
		   spell_info[i+1].min_level_cleric, spells[i],
		   how_good(GET_SKILL(ch, i + 1)));
	       strcat(buf, buf2);
	    }
	 send_to_char(buf, ch);
	 return(TRUE);
      }
      number = old_search_block(arg, 0, strlen(arg), spells, FALSE);
      if (number == -1) {
	 send_to_char("You do not know of this spell...\n\r", ch);
	 return(TRUE);
      }
      if (GET_LEVEL(ch) < spell_info[number].min_level_cleric) {
	 send_to_char("You do not know of this spell...\n\r", 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);
      }
      if (GET_SKILL(ch, number) >= MAX_LEARN) {
	 send_to_char("You are already learned in this area.\n\r", ch);
	 return(TRUE);
      }
      send_to_char("You Practice for a while...\n\r", ch);
      SPELLS_TO_LEARN(ch)--;

      percent = GET_SKILL(ch, number) + MAX(25, int_app[GET_INT(ch)].learn);
      SET_SKILL(ch, number, MIN(MAX_LEARN, percent));

      if (GET_SKILL(ch, number) >= MAX_LEARN) {
	 send_to_char("You are now learned in this area.\n\r", ch);
	 return(TRUE);
      }

      break;

   case CLASS_WARRIOR:
      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 (i = 0; *w_skills[i] != '\n'; i++) {
	    sprintf(buf2, "(%2d) %-20s %s\n\r", w_skill_levels[i], w_skills[i],
		how_good(GET_SKILL(ch, i + SKILL_KICK)));
	    strcat(buf, buf2);
	 }
	 send_to_char(buf, ch);
	 return(TRUE);
      }
      number = search_block(arg, w_skills, FALSE);
      if (number == -1) {
	 send_to_char("You do not have ability to practice this skill!\n\r", ch);
	 return(TRUE);
      }
      if (GET_LEVEL(ch) < w_skill_levels[number]) {
	 send_to_char("You do not know of this spell...\n\r", 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);
      }
      if (GET_SKILL(ch, number + SKILL_KICK) >= MAX_LEARN) {
	 send_to_char("You are already learned in this area.\n\r", ch);
	 return(TRUE);
      }
      send_to_char("You Practice for a while...\n\r", ch);
      SPELLS_TO_LEARN(ch)--;

      percent = GET_SKILL(ch, number + SKILL_KICK) + MIN(12, int_app[GET_INT(ch)].learn);
      SET_SKILL(ch, number + SKILL_KICK, MIN(MAX_LEARN, percent));

      if (GET_SKILL(ch, number + SKILL_KICK) >= MAX_LEARN) {
	 send_to_char("You are now learned in this area.\n\r", ch);
	 return(TRUE);
      }
      break;
   }


   return (TRUE);
}


/* ok some notes.......

    1.  You may notice MAX_LEARN.  Never liked it that some skills could
    be learned to 80, other 85, 95 etc...so in structs.h i made a
    #define MAX_LEARN ## (personal preference..im also stickler for
    easy to change...for all the thinges like titles..i have
    titles[MAX_LEVEL + 1][MAX_CLASSES] so when youchange things you dont
    have to find every instance.  anyway...

    also you may notice prac is doubled with lots of repitiotion...easiest
    though not most code effecient way of doing it so if immortal ALL skills
    are shown...scrolls like mad though :-)

    2. the war_ and thief stuff.
	it was a semi easy way of adding stuff with easy to practice and add
	levels.  Some side points...iit gets annoying though if you want
	to add classes....for you have one for class_paladin, class_ranger...
	etc....but i liked it..for a while.

    NOW...say you want to add a skill.... SKILL_STUN
    put you ACMD(do_stun) in act.offensive.c (or at least..that where i would
    think it would go.

    either have it warrior or thief... if youwant both you need a #define
    for both..maybe #define SKILL_WSTUN, and SKILL_TSTUN
    put the numbers in sequentially in each section.

    next you edit this GUILD spec_proc.

    by putting in the skill name to practice...and the level they get it at...
    everything should work.

    (of course in interperter.c you have to do the commando thing....)


    heres an example.....

ACMD(do_berserk)
{
   struct char_data *tmp_victim, *temp;
   byte percent, prob;

   if ((GET_CLASS(ch) != CLASS_WARRIOR) && (GET_LEVEL(ch) < LEVEL_IMMORT))  {
      send_to_char("You'd better leave all the martial arts to the fighting classes.\n\r", ch);
      return;
   }


   if (GET_MOVE(ch) < 20) {
      send_to_char("You're too exhausted!\n\r", ch);
      return;
   }
   GET_MOVE(ch) -= 20;

   if (ch->specials.fighting) {
      percent=number(1, 101);
      prob=GET_SKILL(ch, SKILL_BERSERK);
   } else {
      percent=number(1, 101);
      prob=GET_SKILL(ch, SKILL_BERSERK);
   }
   if (percent > prob) {
      send_to_char("You trip while trying to go BERSERK!\n\r", ch);
      act("$n trips while trying to go BERSERK!", FALSE, ch, 0, 0,
	 TO_NOTVICT);
      return;
   }

   send_to_char("You go BERSERK!!!\n\r", ch);
   act("$n goes BERSERK!!!", FALSE, ch, 0, 0, TO_NOTVICT);

   for(tmp_victim = character_list; tmp_victim; tmp_victim = temp) {
      temp = tmp_victim->next;
      if ((ch->in_room == tmp_victim->in_room) && (ch != tmp_victim) && (tmp_victim->master != ch)) {
	 hit(ch, tmp_victim, TYPE_UNDEFINED);
      }

     if ((ch->in_room == tmp_victim->in_room) && (ch != tmp_victim) && (ch->master != tmp_victim)) {
	 hit(tmp_victim, ch, TYPE_UNDEFINED);
      }


   }
   WAIT_STATE(ch, PULSE_VIOLENCE * 3);

}

*/



/* Now for spells. */

/*  To do spells..its easier...but more annoying.
	1.  In magic.c you have to define what the spell does.


ASPELL(spell_slay)
{
   int	dam;


   assert(victim && ch);
   assert((level >= 11) && (level <= LEVEL_IMPL));

   dam = dice(2 * level, 3) + 200;

   if ( saves_spell(victim, SAVING_SPELL) )
      dam >>= 1;

   damage(ch, victim, dam, SPELL_SLAY);
}

in either spells1.c or spells2.c you have to go through the cases...pretty simple...just
look at another.

in spell_parser.c you have to do all this:

give it a "slay",

give it a SPELLO(with all the levels, mana, and TAR_'s).

also...in case you havnet alreqady...in the original circle you get a highest
spell thatit will search for...not sure exact line
but it should look like this.

if ((spl > 0) && (spl <= 53) && spell_info[spl].spell_pointer) {

the 53 i could be mistaken about..cause i changed it to 999 so id not have to worr about it
again....it has to be higher than your highest spell.

also in spells.h dont forget to define SPELL_
and have the ACAST and ASPELL in it as well.

so you would have #define SPELL_SLAY ##
ACAST(spell_slay);
ASPELL(spell_slay);



this should work...bet im fogetting something..but not sure what.

 PS..anyone wants to share skills...im willing to give up some of my code that
 is compatable with straight unmodified circle 2.2



 Sagar@MirtosMud  .....

 PPS: loook for mirtos mud with all original areas...with cities bigger than all of
 the original circle area combined..coming soon */



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