final_realms_fluffos_v1/
final_realms_fluffos_v1/bin/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/ChangeLog.old/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/Win32/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/simuls/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/clone/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/command/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/data/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/etc/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/master/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/log/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/compiler/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/efuns/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/operators/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/u/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/tmp/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/windows/
final_realms_fluffos_v1/lib/baseobs/guilds/
final_realms_fluffos_v1/lib/baseobs/misc/
final_realms_fluffos_v1/lib/baseobs/races/shadows/
final_realms_fluffos_v1/lib/cmds/god/
final_realms_fluffos_v1/lib/cmds/handlers/
final_realms_fluffos_v1/lib/cmds/handlers/cmds/
final_realms_fluffos_v1/lib/d/heaven/
final_realms_fluffos_v1/lib/d/heaven/heaven/ave/
final_realms_fluffos_v1/lib/d/mudlib/
final_realms_fluffos_v1/lib/d/newbie/
final_realms_fluffos_v1/lib/d/newbie/docs/
final_realms_fluffos_v1/lib/d/newbie/drow/armour/
final_realms_fluffos_v1/lib/d/newbie/drow/items/
final_realms_fluffos_v1/lib/d/newbie/drow/mobs/
final_realms_fluffos_v1/lib/d/newbie/drow/oldmobs/
final_realms_fluffos_v1/lib/d/newbie/drow/weapons/
final_realms_fluffos_v1/lib/d/newbie/duergar/weapons/
final_realms_fluffos_v1/lib/d/newbie/dwarf/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/cafe/
final_realms_fluffos_v1/lib/d/newbie/elf/chars/equip/
final_realms_fluffos_v1/lib/d/newbie/elf/items/armours/
final_realms_fluffos_v1/lib/d/newbie/elf/items/obj/
final_realms_fluffos_v1/lib/d/newbie/elf/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/quick_fix/
final_realms_fluffos_v1/lib/d/newbie/gnome/armour/
final_realms_fluffos_v1/lib/d/newbie/gnome/buildings/
final_realms_fluffos_v1/lib/d/newbie/gnome/items/
final_realms_fluffos_v1/lib/d/newbie/gnome/npcs/clones/
final_realms_fluffos_v1/lib/d/newbie/gnome/rooms/northrooms/
final_realms_fluffos_v1/lib/d/newbie/gnome/weapons/
final_realms_fluffos_v1/lib/d/newbie/goblin/armour/
final_realms_fluffos_v1/lib/d/newbie/goblin/items/
final_realms_fluffos_v1/lib/d/newbie/grads/log/
final_realms_fluffos_v1/lib/d/newbie/grads/npcs/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/cave1/
final_realms_fluffos_v1/lib/d/newbie/grads/temp/
final_realms_fluffos_v1/lib/d/newbie/guests/weapons/
final_realms_fluffos_v1/lib/d/newbie/half-elf/items/
final_realms_fluffos_v1/lib/d/newbie/half-elf/newroomss/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/castle/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/drows/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/savannah/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/secret/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/town/
final_realms_fluffos_v1/lib/d/newbie/halfling/
final_realms_fluffos_v1/lib/d/newbie/halfling/misc/
final_realms_fluffos_v1/lib/d/newbie/halfling/rooms/cave/
final_realms_fluffos_v1/lib/d/newbie/human/
final_realms_fluffos_v1/lib/d/newbie/human/armour/
final_realms_fluffos_v1/lib/d/newbie/human/monsters/
final_realms_fluffos_v1/lib/d/newbie/human/obj/
final_realms_fluffos_v1/lib/d/newbie/human/weapons/
final_realms_fluffos_v1/lib/d/newbie/lizard/armour/
final_realms_fluffos_v1/lib/d/newbie/lizard/items/
final_realms_fluffos_v1/lib/d/newbie/lizard/underwater/
final_realms_fluffos_v1/lib/d/newbie/lizard/weapons/
final_realms_fluffos_v1/lib/d/newbie/logs/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/rooms/
final_realms_fluffos_v1/lib/d/newbie/newelf/
final_realms_fluffos_v1/lib/d/newbie/newelf/chars/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/recopied/
final_realms_fluffos_v1/lib/d/newbie/newelf/obj/
final_realms_fluffos_v1/lib/d/newbie/newelf/quest_docs./
final_realms_fluffos_v1/lib/d/newbie/newken/
final_realms_fluffos_v1/lib/d/newbie/newken/chars/
final_realms_fluffos_v1/lib/d/newbie/newken/misc/
final_realms_fluffos_v1/lib/d/newbie/newken/npcs/
final_realms_fluffos_v1/lib/d/newbie/newken/obj/
final_realms_fluffos_v1/lib/d/newbie/newliz/
final_realms_fluffos_v1/lib/d/newbie/newliz/cave/
final_realms_fluffos_v1/lib/d/newbie/newliz/npcs/
final_realms_fluffos_v1/lib/d/newbie/orc/items/misc/
final_realms_fluffos_v1/lib/d/newbie/orc/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/orc/tower/
final_realms_fluffos_v1/lib/d/vehicle/
final_realms_fluffos_v1/lib/doc/
final_realms_fluffos_v1/lib/doc/driver/
final_realms_fluffos_v1/lib/doc/driver/concepts/
final_realms_fluffos_v1/lib/doc/driver/driver/
final_realms_fluffos_v1/lib/doc/driver/efuns/arrays/
final_realms_fluffos_v1/lib/doc/driver/efuns/bitstrings/
final_realms_fluffos_v1/lib/doc/driver/efuns/communication/
final_realms_fluffos_v1/lib/doc/driver/efuns/core/
final_realms_fluffos_v1/lib/doc/driver/efuns/debugging/
final_realms_fluffos_v1/lib/doc/driver/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/driver/efuns/interactive/
final_realms_fluffos_v1/lib/doc/driver/efuns/mappings/
final_realms_fluffos_v1/lib/doc/driver/efuns/objects/
final_realms_fluffos_v1/lib/doc/driver/efuns/security/
final_realms_fluffos_v1/lib/doc/driver/efuns/strings/
final_realms_fluffos_v1/lib/doc/driver/efuns/system/
final_realms_fluffos_v1/lib/doc/driver/efuns/types/
final_realms_fluffos_v1/lib/doc/driver/lpc/constructs/
final_realms_fluffos_v1/lib/doc/driver/lpc/types/
final_realms_fluffos_v1/lib/doc/driver/platforms/
final_realms_fluffos_v1/lib/doc/lpc/
final_realms_fluffos_v1/lib/doc/mail/
final_realms_fluffos_v1/lib/doc/man/
final_realms_fluffos_v1/lib/doc/man/html/
final_realms_fluffos_v1/lib/doc/man/html/applies/
final_realms_fluffos_v1/lib/doc/man/html/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/html/driver/
final_realms_fluffos_v1/lib/doc/man/html/efuns/
final_realms_fluffos_v1/lib/doc/man/html/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/html/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/html/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/html/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/html/efuns/general/
final_realms_fluffos_v1/lib/doc/man/html/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/
final_realms_fluffos_v1/lib/doc/man/local/applies/
final_realms_fluffos_v1/lib/doc/man/local/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/local/applies/master/
final_realms_fluffos_v1/lib/doc/man/local/concepts/
final_realms_fluffos_v1/lib/doc/man/local/defines/
final_realms_fluffos_v1/lib/doc/man/local/driver/
final_realms_fluffos_v1/lib/doc/man/local/efuns/
final_realms_fluffos_v1/lib/doc/man/local/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/local/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/local/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/local/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/local/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/local/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/local/efuns/general/
final_realms_fluffos_v1/lib/doc/man/local/efuns/interactive/
final_realms_fluffos_v1/lib/doc/man/local/efuns/internals/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/local/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/objects/
final_realms_fluffos_v1/lib/doc/man/local/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/efuns/sockets/
final_realms_fluffos_v1/lib/doc/man/local/efuns/strings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/system/
final_realms_fluffos_v1/lib/doc/man/local/historical/
final_realms_fluffos_v1/lib/doc/man/local/lfun/QC/
final_realms_fluffos_v1/lib/doc/man/local/lfun/events/
final_realms_fluffos_v1/lib/doc/man/local/lfun/monster/
final_realms_fluffos_v1/lib/doc/man/local/lfun/properties/
final_realms_fluffos_v1/lib/doc/man/local/lpc/
final_realms_fluffos_v1/lib/doc/man/local/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/local/lpc/types/
final_realms_fluffos_v1/lib/doc/man/local/standards/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/basic/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/intermediate/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/concepts/
final_realms_fluffos_v1/lib/doc/man/mudos/driver/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/general/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mixed/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/types/
final_realms_fluffos_v1/lib/doc/races/
final_realms_fluffos_v1/lib/doc/races/old_race/
final_realms_fluffos_v1/lib/global/virtual/
final_realms_fluffos_v1/lib/global/wiz_backup/
final_realms_fluffos_v1/lib/net/config/
final_realms_fluffos_v1/lib/net/daemon/chars/
final_realms_fluffos_v1/lib/net/inherit/
final_realms_fluffos_v1/lib/net/intermud3/
final_realms_fluffos_v1/lib/net/intermud3/cmds/
final_realms_fluffos_v1/lib/net/intermud3/save/
final_realms_fluffos_v1/lib/net/intermud3/services/
final_realms_fluffos_v1/lib/net/obj/
final_realms_fluffos_v1/lib/net/old/
final_realms_fluffos_v1/lib/net/old/intermud/
final_realms_fluffos_v1/lib/net/old/intermud/adm/
final_realms_fluffos_v1/lib/net/old/intermud/services/
final_realms_fluffos_v1/lib/net/old/intermud/udp/
final_realms_fluffos_v1/lib/net/virtual/
final_realms_fluffos_v1/lib/obj/b_day/
final_realms_fluffos_v1/lib/obj/chars/
final_realms_fluffos_v1/lib/obj/handlers/lists/
final_realms_fluffos_v1/lib/obj/handlers/useless/
final_realms_fluffos_v1/lib/obj/monsters/
final_realms_fluffos_v1/lib/obj/roomgen/
final_realms_fluffos_v1/lib/obj/soul/
final_realms_fluffos_v1/lib/obj/vegetation/
final_realms_fluffos_v1/lib/obj/weapons/oldsys/
final_realms_fluffos_v1/lib/open/
final_realms_fluffos_v1/lib/players/g/
final_realms_fluffos_v1/lib/releasefiles/d/heaven/
final_realms_fluffos_v1/lib/releasefiles/d/mudlib/
final_realms_fluffos_v1/lib/releasefiles/d/newbie/
final_realms_fluffos_v1/lib/releasefiles/doc/
final_realms_fluffos_v1/lib/releasefiles/players/g/
final_realms_fluffos_v1/lib/releasefiles/save/
final_realms_fluffos_v1/lib/releasefiles/save/environ/
final_realms_fluffos_v1/lib/releasefiles/save/roomgen/
final_realms_fluffos_v1/lib/releasefiles/secure/
final_realms_fluffos_v1/lib/releasefiles/w/
final_realms_fluffos_v1/lib/releasefiles/w/god/
final_realms_fluffos_v1/lib/room/
final_realms_fluffos_v1/lib/save/
final_realms_fluffos_v1/lib/save/environ/
final_realms_fluffos_v1/lib/save/roomgen/
final_realms_fluffos_v1/lib/scripts/
final_realms_fluffos_v1/lib/secure/crerem/
final_realms_fluffos_v1/lib/secure/dom/
final_realms_fluffos_v1/lib/secure/log/
final_realms_fluffos_v1/lib/secure/misc/
final_realms_fluffos_v1/lib/std/adnd/
final_realms_fluffos_v1/lib/std/commands/shadows/
final_realms_fluffos_v1/lib/std/creator/
final_realms_fluffos_v1/lib/std/curses/
final_realms_fluffos_v1/lib/std/curses/old_sys/
final_realms_fluffos_v1/lib/std/curses/shadows/
final_realms_fluffos_v1/lib/std/dom/
final_realms_fluffos_v1/lib/std/effects/
final_realms_fluffos_v1/lib/std/effects/healing/
final_realms_fluffos_v1/lib/std/effects/other/
final_realms_fluffos_v1/lib/std/effects/poisons/
final_realms_fluffos_v1/lib/std/environ/
final_realms_fluffos_v1/lib/std/guilds/
final_realms_fluffos_v1/lib/std/guilds/priests/samples/
final_realms_fluffos_v1/lib/std/guilds/wizards/
final_realms_fluffos_v1/lib/std/living/baldy/
final_realms_fluffos_v1/lib/std/living/divstuff/
final_realms_fluffos_v1/lib/std/paran/
final_realms_fluffos_v1/lib/std/poisons/
final_realms_fluffos_v1/lib/std/poisons/shadows/
final_realms_fluffos_v1/lib/std/poisons/weapons/
final_realms_fluffos_v1/lib/std/race_groups/
final_realms_fluffos_v1/lib/std/room/
final_realms_fluffos_v1/lib/std/room/old/
final_realms_fluffos_v1/lib/std/rooms/
final_realms_fluffos_v1/lib/std/shadows/
final_realms_fluffos_v1/lib/std/shadows/test_shad/
final_realms_fluffos_v1/lib/std/socket/
final_realms_fluffos_v1/lib/std/spells/
final_realms_fluffos_v1/lib/std/vaults/
final_realms_fluffos_v1/lib/tmp/
final_realms_fluffos_v1/lib/w/
final_realms_fluffos_v1/lib/w/god/
final_realms_fluffos_v1/old/
final_realms_fluffos_v1/win32/
/*
 * quick summary of routines
 * skill_bonus(string)         - gives the bonus...
 * skill_lvl(string)           - gives the raw level, with out stat bonus etc
 * modify_skill(string, int)   - modifies the skills level by int.
 * calc_bonus(int, string)     - given the skill lvl, stat bonus str cals bonus
 * calc_lvl(string *)          - calculate number of lvls in the path
 * add_skill_lvl(...)          - horror recursive skill adder. arghh
 * teach_skill(objct *,string) - Used to teach skills to other people.
  skill_commands()            - all the skill add_actioned commands.
 */
 
#include "skills2.h"
#include "tune.h"

int calc_bonus(int lvl, string skill);
mixed recursive_skill_add(mixed skil, string *path, int avr, int lvl, int exp,
                           mixed standard);

/*
 * Should be a mapping, it's mixed so that the
 * old skills array can be read in (and then converted).
 * It _must_ be converted before any skills referencing can be done...
 */
/*mapping*/mixed skills;
 
private static int delta;
static mapping bonus_cache,
               level_cache,
               teach_offer;

/*
 * The code to convert between the old and the new skill formats...
 */
#include "/std/living/convert_skills.c"

void skill_commands() {
  add_action("do_learn", "learn");
} /* skill_command() */
 
mapping query_skills() { return skills; }
void set_skills(mapping value) { skills = value; }
int calc_level(string *path);

void create() {
  bonus_cache = ([ ]);
  level_cache = ([ ]);
  teach_offer = ([ ]);
  skills = ([ ]);
} /* create() */

mapping query_bonus_cache() { return bonus_cache; }
mapping query_level_cache() { return level_cache; }

/*
 * This is most probably the code you wish to call when doing skil
 * checks.  It returns the skill + all its bonsues for stats/whatever.
 *  It first checks to see if the skill is in it's cache. 
 */
int query_skill_bonus(string skill) {
  string *path;
  object guild,
         race;
  int tmp, lvl;

  if (!stringp(skill) || !strlen(skill)) return 0;
  if (!skills) skills = ([ ]); /* Why? */
  if (skill[0] == '.') skill = skill[1..strlen(skill)];
  if (bonus_cache[skill]) return bonus_cache[skill]; 
  path = (string *)SKILL_OB->query_skill_path(skill);
  if (!path) return 0;
  if (level_cache[skill])
    lvl = level_cache[skill];
  else
    level_cache[skill] = lvl = calc_level(path);
  guild = (object)this_object()->query_guild_ob();
  race = (object)this_object()->query_race_ob();
  tmp = 0;
  if (race) tmp += (int)race->query_skill_bonus(lvl, skill);
  if (guild) tmp += (int)guild->query_skill_bonus(lvl, skill);
  return bonus_cache[skill] = calc_bonus(lvl + tmp, skill);
} /* query_skill_bonus() */

/*
 * This returns just the skill level.  Used a lot to determine if you
 * can use/teach/whatever a skill.
 * This also uses a cache.
 */ 
mixed query_skill(string skill) {
  string *path;

  if (level_cache[skill]) return level_cache[skill]; 
  if (!skills) skills = ([ ]);
  if (skill[0] == '.') skill = skill[1..strlen(skill)];
  path = (string *)SKILL_OB->query_skill_path(skill);
  if (!path) return 0;
  return (level_cache[skill] = calc_level(path));
} /* query_skill() */
 
int add_skill_level(string skill, int lvl, int exp) {
  string *path;
 
  if (!skills) skills = STD_SKILLS;
  if (!lvl) return 0;
  delta = 0;
  path = (string *)SKILL_OB->query_skill_path(skill);
  if (!path) return 0;
  bonus_cache = ([ ]);
  level_cache = ([ ]);
  skills = recursive_skill_add(skills, path, 0, lvl, exp,
                                SKILL_OB->query_skills());
  return 1;
} /* add_skill_level() */
 
int calc_level(string *path) {
  mixed cur;
  int i;
  int lvl;
 
  lvl = 0;
  cur = skills;
  for (i=0;i<sizeof(path);i++)
    if (!cur[path[i]])
      return lvl;
    else {
      lvl = cur[path[i]][SKILL_LVL];
      cur = cur[path[i]][SKILL_BIT];
    }
  return lvl;
} /* calc_level() */

mapping add_to_all(mapping skil, int lvl) {
  int i;
  string *skil_i;

  skil_i = m_indices(skil);
  if (!sizeof(skil_i)) return ([ ]);
  for (i=0; i<sizeof(skil_i); i++) {
    skil[skil_i[i]][SKILL_LVL] += lvl;
    skil[skil_i[i]][SKILL_BIT] = add_to_all(skil[skil_i[i]][SKILL_BIT], lvl);
  }
  return skil;
} /* add_to_all() */
 
mapping recursive_skill_add(mapping skil, string *path, int avr, int lvl,
                            int exp, mapping standard) {
  int i, tmp;
  mapping bit;
  string *star_i;

  if (!skil[path[0]]) {
    skil[path[0]] = ({ avr, 0, ([ ]) });
    star_i = m_indices(standard) - m_indices(skil);
    for (i=0; i<sizeof(star_i); i++)
      if (!skil[star_i[i]])
        skil[star_i[i]] = ({ avr, 0, ([ ]) });
  }
  if (!standard[path[0]]) standard = ([ path[0] : ({ 0, 0, ([ ]) }) ]);
  if (1 == sizeof(path)) {
    skil[path[0]][SKILL_LVL] += lvl;
    skil[path[0]][SKILL_BIT] = add_to_all(skil[path[0]][SKILL_BIT], lvl);
    skil[path[0]][SKILL_EXP] += exp;
    return skil;
  }
  avr = skil[path[0]][SKILL_LVL];
  skil[path[0]][SKILL_BIT] = recursive_skill_add(skil[path[0]][SKILL_BIT], path,
                               avr, lvl, exp, standard[path[0]][SKILL_BIT]);
  bit = skil[path[0]][SKILL_BIT];
  star_i = m_indices(bit);
  if (sizeof(star_i)) {
    for (i=0; i<sizeof(star_i); i++) tmp += bit[star_i[i]][SKILL_LVL];
/* Average the levels of the lower tree */
    skil[path[0]][SKILL_LVL] = tmp / sizeof(star_i);
/* Averageing error fixing.  I dont think we need it now.
    if (tmp % sizeof(star_i)) skil[path[0]][SKILL_LVL] += 1;
 */
  }
  return skil;
} /* recursive_skill_add() */
 
int calc_bonus(int lvl, string skill) {
  int bonus, stat, i;
  string stat_bonus;

  stat_bonus = (string)SKILL_OB->query_skill_stat(skill);
  for (i = strlen(stat_bonus); i--; ) {
    switch(stat_bonus[i]) {
      case 'C' : stat = (int)this_object()->query_con();
                 break;
      case 'S' : stat = (int)this_object()->query_str();
                 break;
      case 'D' : stat = (int)this_object()->query_dex();
                 break;
      case 'W' : stat = (int)this_object()->query_wis();
                 break;
      case 'I' : stat = (int)this_object()->query_int();
                 break;
    }
    bonus += (stat - 13) * 3;
  }
  if (lvl > 60)
    lvl = 170 + ((lvl-60) >> 1);
  else if (lvl > 40)
    lvl = 150 + (lvl-40);
  else if (lvl > 20)
    lvl = 100 + ( ((lvl-20)*5) >> 1);
  else
    lvl = lvl * 5;
  if (strlen(stat_bonus))
    return lvl + ( (lvl * bonus) / (strlen(stat_bonus) * 60) );
  return lvl;
} /* calc_bonus() */

int query_skill_successful(string str, int mod) {
  return (query_skill_bonus(str) + mod >= random(200));
} /* query_skill_successful */

int teach_skill(object *obs, string str) {
  int num, lvl, my_lvl;
  object *ok, *cannot, *too_little, *too_low;
  string skill;
  mixed *bits;
  int i, j, cost, total;

  if (sscanf(str, "%d levels of %s", num, skill) != 2)
    if (sscanf(str, "%d %s", num, skill) != 2) {
      num = 1;
      skill = str;
    }
  if (num > 50) {
    write("You can only teach a maximun of 50 levels at one time.\n");
    return 1;
  }
/* Make sure its a valid skill */
  bits = explode(implode(explode(skill, " "), "."), ".");
  if (!(skill = (string)SKILL_OB->query_skill(bits)))
    return 0;
/*
 * We don't do the teaching here.  Figure out how much xp it will cost
 * to go up the levels, and inform the person we are teaching...
 */
  my_lvl = query_skill(skill);
  too_low = ok = cannot = too_little = ({ });
  for (i=0;i<sizeof(obs);i++) {
    lvl = (int)obs[i]->query_skill(skill);
    if (lvl+j >= my_lvl && obs[i] != this_object()) {
      cannot += ({ obs[i] });
      continue;
    }
    if ((sizeof(explode(skill, "."))-1)*5 > lvl) {
      too_low += ({ obs[i] });
      continue;
    }
    cost = DEFAULT_COST;
    cost *= (int)SKILL_OB->query_skill_cost(skill);
    cost *= STD_COST/5;
    total = 0;
    for (j=0;j<num;j++) {
      int k;

      if (lvl+j <= my_lvl/2)
        total += cost*(((lvl+j)/LEVEL_DIV)+1);
      else
        total += cost*(((lvl+j)/LEVEL_DIV)*(k=((2*(lvl+j))/(my_lvl))))*k;
    }
    if (total > (int)obs[i]->query_xp()) {
      write("Would have cost "+total+" xp to teach "+num+" levels of "+
            skill+" to "+obs[i]->query_cap_name()+".\n");
      too_little += ({ obs[i] });
      continue;
    }
    if (obs[i] != this_object()) {
      tell_object(obs[i], this_object()->query_cap_name()+" offers to teach "
                          "you "+num+" level"+(num>1?"s":"")+" of "+skill+
                          " for "+total+" xp.\nUse 'learn' to learn the "
                          "skill.\n");
      ok += ({ obs[i] });
    } else
      write("You can teach yourself "+num+" level"+(num>1?"s":"")+" of "+
            skill+" for "+total+" xp.\nUse 'learn' to leanr the skill.\n");
    obs[i]->add_teach_offer(this_object(), skill, num, lvl, total);
  }
  if (sizeof(cannot))
    write("You are too low a level to teach "+query_multiple_short(cannot)+
          " "+num+" levels of "+skill+".\n");
  if (sizeof(too_low))
    write(capitalize(query_multiple_short(too_low))+" is not high enough "
          "level in the outer skills to learn "+num+" levels of "+skill+".\n");
/*
  if (sizeof(too_little))
    write(capitalize(query_multiple_short(too_little))+" does not have "
          "enough xp to learn "+num+" levels of "+skill+".\n");
 */
  if (sizeof(ok))
    write("You offer teach "+query_multiple_short(ok)+" "+num+" levels of "+
          skill+".\n");
  return 1;
} /* teach_skill() */

int add_teach_offer(object ob, string skill, int num, int lvl, int xp) {
  teach_offer[ob] = ({ skill, num, lvl, xp });
} /* add_teach_offer() */

mapping query_teach_offer() { return teach_offer + ([ ]); }

int do_learn(string str) {
  object *obs, *diff_lvl, *no_xp, *not_offer, *ok;
  int i, lvl;
  string skill, *bits;
  mixed *bing;

  notify_fail("Syntax: learn <skill> from <person>\nIf they have to have "
              "offered to teach you to use this.\n");
  if (!str) return 0;
  if (sscanf(str, "%s from %s", skill, str) != 2) return 0;
  obs = find_match(str, environment());
  if (!sizeof(obs)) {
    notify_fail("I am sorry "+str+" is not here.\n");
    return 0;
  }
  bits = explode(replace(skill, " ", "."), ".");
  if (!(skill = (string)SKILL_OB->query_skill(bits))) {
    notify_fail("The skill '"+implode(bits, ".")+"' is invalid.\n");
    return 0;
  }
  ok = not_offer = no_xp = diff_lvl = ({ });
  for (i=0;i<sizeof(obs);i++) {
    if (!(bing = teach_offer[obs[i]])) {
      not_offer += ({ obs[i] });
      continue;
    }
    if (skill != bing[O_SKILL]) {
      not_offer += ({ obs[i] });
      continue;
    }
    if ((int)this_object()->query_xp() < bing[O_XP]) {
      no_xp += ({ obs[i] });
      continue;
    }
    if (query_skill(bing[O_SKILL]) != bing[O_LVL]) {
      diff_lvl += ({ obs[i] });
      continue;
    }
    obs[i]->adjust_xp(bing[O_XP]/10);
    if (obs[i] != this_object()) {
      write("You let "+obs[i]->query_cap_name()+" teach you "+bing[O_NUM]+
            " levels of "+bing[O_SKILL]+" for "+bing[O_XP]+" xp.\n");
      tell_object(obs[i], "You teach "+this_player()->query_cap_name()+
                  " "+bing[O_NUM]+" levels in "+bing[O_SKILL]+
                  " and gain yourself "+(bing[O_XP]/10)+" xp.\n");
      ok += ({ obs[i] });
    } else {
      write("You teach yourself "+bing[O_NUM]+" levels in "+bing[O_SKILL]+
            "for "+bing[O_XP]+".\n");
      say(this_player()->query_cap_name()+" teaches themselves some skills.\n");
    }
    this_object()->adjust_xp(-bing[O_XP]);
    add_skill_level(bing[O_SKILL], bing[O_NUM], bing[O_XP]);
    teach_offer = m_delete(teach_offer, obs[i]);
  }
  if (sizeof(not_offer))
    write(capitalize(query_multiple_short(not_offer))+" is not offering to "
          "teach you "+skill+" at your current level in it.\n");
  if (sizeof(no_xp))
    write("You do not have enough xp to learn "+skill+" from "+
          query_multiple_short(no_xp)+".\n");
  if (sizeof(diff_lvl))
    write("You are a different level in "+skill+" when "+
          query_multiple_short(diff_lvl)+" offered to teach you.\n");
  if (sizeof(ok))
    say(this_player()->query_cap_name()+" learns some skills from "+
        query_multiple_short(ok)+".\n", ok);
  return 1;
} /* do_learn() */