mteach and mskillset [by Xual]
Snippet Posted Saturday, March 6th @ 03:57:53 PM, by George Greer in the Mobiles dept.
Xual writes "This snippet is intended for use with DG Scripts, although you could probably use it with mobprogs as well. It will give you 2 new mob commands, mskillset and mteach, which will allow your mobs to act as guildmasters, teaching and/or setting whatever skills and spells you like."
	This snippet will give you 2 new script commands, to allow your mobs
to teach and set whatever skills/spells you like.  Note that the commands
don't send any messages to the players except upon error, the script should
deal with these.  

Here we go...

In interpreter.h:

/* do_mskillset */
#define SCMD_SKILLSET   0
#define SCMD_TEACH      1

In interpreter.c:

  { "mskillset", POS_RESTING , do_mskillset, -1, SCMD_SKILLSET },
  { "mteach",    POS_RESTING , do_mskillset, -1, SCMD_TEACH },
  
Somewhere (I put it in class.c):

#define MOB_OR_IMPL(ch) \
  (IS_NPC(ch) && (!(ch)->desc || GET_LEVEL((ch)->desc->original)>=LVL_IMPL))

ACMD(do_mskillset)
{
  struct char_data *vict;
  char name[MAX_INPUT_LENGTH],
       skill_name[MAX_INPUT_LENGTH],
       arg3[MAX_INPUT_LENGTH];
  int skill_num, percent, curr, qend;

  argument = one_argument(argument, name);

  if (!*name) {
    script_log("Too few arguments to mskillset");
    return;
  }

  if (!MOB_OR_IMPL(ch)) {
    send_to_char("Huh?!?\r\n", ch);
    return;
  }
  if (!(vict = get_char_room_vis(ch, name)))
    return;

  skip_spaces(&argument);

  if (!*argument) {
    script_log("Too few arguments to mskillset");
    return;
  }
  if (*argument != '\'') {
    script_log("Skill name not enclosed in 's in mskillset");
    return;
  }

  for (qend = 1; *(argument + qend) && (*(argument + qend) != '\''); qend++)
    *(argument + qend) = LOWER(*(argument + qend));

  if (*(argument + qend) != '\'') {
    script_log("Skill name not enclosed in 's in mskillset");
    return;
  }

  strcpy(skill_name, (argument + 1));
  skill_name[qend -1] = '\0';

  /* The script should do the checking for skills, or else the player
     will be able to practice any skill here. But just in case its not,
     we'll log errors at least */

  if ((skill_num = find_skill_num(skill_name)) <= 0) {
    script_log("Invalid skill to mskillset");
    send_to_char("Invalid skill\r\n", ch);
    return;
  }

  argument += qend + 1;         /* skip to next parameter */
  argument = one_argument(argument, arg3);

  if (!*arg3) {
    script_log("Too few arguments to mskillset");
    return;
  }

  percent = atoi(arg3);

  if (percent < 0) {
    script_log("Negative number to mskillset.\r\n");
    return;
  }
  if (percent > 100) {
    script_log("Learned level exceeding 100 in mskillset.\r\n");
    return;
  }
  if (IS_NPC(vict)) {
    return;
  }

  if (subcmd == SCMD_SKILLSET) {
    sprintf(buf2, "%s changed %s's %s to %d.", GET_NAME(ch), GET_NAME(vict),
            spells[skill_num], percent);
    mudlog(buf2, BRF, LVL_GRGOD, TRUE);

    SET_SKILL(vict, skill_num, percent);
    return;
  }

  else if (subcmd == SCMD_TEACH) {
    if (GET_SKILL(vict, skill_num) >= 80) {
      send_to_char("You are already learned in that area.\r\n", vict);
      return;
    }
    if (GET_PRACTICES(vict) <= 0) {
      send_to_char("You can't practice any more this level.\r\n", vict);
      return;
    }

    curr = GET_SKILL(vict, skill_num);
    curr += percent;
    if (curr >= 100)
      curr = 100;
    SET_SKILL(vict, skill_num, curr);
    GET_PRACTICES(vict)--;
  }
}

In spec_procs.c  list_skills():
Search for:

if (GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) {

And change it to:

if ((GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) ||
    ((GET_SKILL(ch, i) && str_cmp(spells[i], "!UNUSED!")))) {

This will allow the players to view all the skills they have, not just the
ones they're supposed to know (based on class/level)  

The str_cmp(spells[i], "!UNUSED!") bit is to prevent spam to immortals, who
by default have all skills, including the !UNUSED! ones.

And finally, a sample script:

Trigger Intended Assignment: Mobiles
Trigger Type: Command , Numeric Arg: 100, Arg list: practice
Commands:
   if (%arg% == magic missile)
     set spell_name magic missile
   elseif (%arg% == burning hands)
     set spell_name burning hands
   elseif (%arg% == armor)
     set spell_name armor
   else
   tell %actor.name% I don't teach that spell.
     halt
   end
     mteach %actor.name% '%spell_name%' 5
   unset spell_name
   end


	I'm not really concerned with credit, if you feel the urge to
include me in your credits file, go right ahead.  I would however appreciate
an email with your opinions/criticism/ideas.

Xual
xual@danathara.dhs.org
telnet://danathara.dhs.org:4000

<< Compression support | Reply | View as text | Flattened | NPC Classes and Races >>

 


Related Links
  Xual
Related Articles
More by greerga
 
 

CircleMUD Snippets
 
Note: Not all of these snippets will work perfectly with your version of code, so be prepared to fix one or two bugs that may arise, and please let me know what you needed to do to fix it. Sending a corrected version is always welcome.
Finally, if you wish to use any of the snippets from this page, you are more than welcome, just mention the authors in your credits. If you wish to release any of these snippets to the public on another site, contact me FIRST.