dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
#include <money.h>
#include <skills.h>
#include <tune.h>
#include <config.h>

private int cost_div;
private int cost_mult;
private string our_guild;
private string start_pos;
private mapping spells;
private mapping commands;
private object teaching_person;

void check_spells_commands(string *sk, int lvl);
int do_cost_primaries();
int do_cost_all(int brief);
int do_cost_to(string skill, int level);
int do_cost_by(string skill, int level);
int do_cost(string skill);

int do_advance(string skill);
int do_advance_to(string skill, int num);
int do_advance_by(string skill, int num);

void create()
{
   cost_div = COST_DIV;
   cost_mult = 100;
   spells = ([ ]);
   commands = ([ ]);
   this_object()->add_help_file("guild");
} /* create() */


void init()
{
   this_player()->add_command("advance", this_object(),
                              "<string>", (: do_advance($4[0]) :));
   this_player()->add_command("advance", this_object(),
                              "<string> to <number>",
                              (: do_advance_to($4[0], $4[1]) :));
   this_player()->add_command("advance", this_object(),
                              "<string> by <number>",
                              (: do_advance_by($4[0], $4[1]) :));
   this_player()->add_command("join", this_object(), "");
   this_player()->add_command("info", this_object(), "");
   this_player()->add_command("cost", this_object(),
                              "primaries", (: do_cost_primaries() :));
   this_player()->add_command("cost", this_object(),
                              "all", (: do_cost_all(0) :));
   this_player()->add_command("cost", this_object(),
                              "all brief", (: do_cost_all(1) :));
   this_player()->add_command("cost", this_object(),
                              "<string>", (: do_cost($4[0]) :));
   this_player()->add_command("cost", this_object(),
                              "<string> to <number>",
                              (: do_cost_to($4[0], $4[1]) :));
   this_player()->add_command("cost", this_object(), "<string> by <number>",
                              (: do_cost_by($4[0], $4[1]) :));
   if ((string) this_player()->query_guild_ob() == our_guild) {
      if (stringp(start_pos) && !clonep(this_object())) {
         this_player()->add_start(file_name(this_object()), start_pos);
      }
   }
} /* init() */


varargs void set_guild(string word1, string word2)
{
   our_guild = word1;
   start_pos = word2;
} /* set_guild() */


void set_cost_div(int number)
{
   cost_div = number;
/*
 * Points of interest:
 *    cost_div -> zero      gives cost_mult = 10
 *    cost_div = COST_DIV   gives cost_mult = 100
 *    cost_div -> infinity  gives cost_mult = 1000
 */
   if (!cost_div)               /* stands in for infinity */
      cost_mult = 1000;
   else
      cost_mult = 10 + (990 * cost_div) / (10 * COST_DIV + cost_div);
} /* set_cost_div() */


int query_skill_cost(string skill, int offset)
{
   int i;
   int total;
   string *next;

   next = (string *) SKILL_OB->query_immediate_children(skill);
   if (!sizeof(next)) {
      if (!this_player()->query_guild_ob())
         total = DEFAULT_COST;
      else
         total = (int) our_guild->query_skill_cost(skill);
      total *= (STD_COST * cost_mult) / 500;
      total *= ((int) this_player()->query_skill(skill) + offset) /
         LEVEL_DIV + 1;
      // this is the new, increased skill cost.
      total = to_int(total * exp((this_player()->query_skill(skill) +
                                  offset) / 150.0));

      return total;
   }
   for (i = 0; i < sizeof(next); i++)
      total += query_skill_cost(next[i], offset);
   return total;

} /* query_skill_cost() */


int do_advance_internal(string skill, int to, int by)
{
   string *bits;
   string skill_name;
   string outer_name;
   string place;
   int lvl;
   int max_lvl;
   int tmp;
   int total_xp;
   int total_cost;
   int tmp_cost;
   int p_val;
   int i, j;
   int round_value;

   if ((string) this_player()->query_guild_ob() != our_guild) {
      add_failed_mess("You cannot advance here!  Go to your own guild.\n");
      return 0;
   }
   place = this_object()->query_property("place");
   if (!place)
      place = "default";
   bits = explode(implode(explode(skill, " "), "."), ".");
   if (!(skill_name = (string) SKILL_OB->query_skill(bits))) {
      add_failed_mess("The skill " + skill + " does not exist.\n");
      return 0;
   }

   bits = SKILL_OB->query_inactive_skills();
   for(j=0; j<sizeof(bits); j++)
     if(strsrch(skill, bits[j]) != -1)
       return add_failed_mess("The skill " + skill + " is inactive at "
                              "present and cannot be taught.\n");
   
   lvl = (int) this_player()->query_skill(skill_name);
   if (!by && to)
      by = to - lvl;
   if (by <= 0) {
      if (by == 0) {
         add_failed_mess("You are already at level " + lvl + " at " +
                         skill_name + ".\n");
      } else {
         add_failed_mess("You cannot regress below your current "
                         "skill level!\n");
      }
      return 0;
   }
   if (SKILL_OB->query_only_leaf(skill_name)) {
      if (sizeof((mixed *)SKILL_OB->query_immediate_children(skill_name))) {
         add_failed_mess("You can only advance the outer skills "
                         "(eg: other.movement.riding.horse), "
                         "not the internal "
                         "skills (eg: other.movement.riding, or other).\n");
         return 0;
      }
   } else {
      bits = explode(skill_name, ".");
      if (sizeof(bits) > 1) {
         outer_name = implode(bits[0..<2], ".");
         if (((sizeof(bits) - 1) * 5) >
             (int) this_player()->query_skill(outer_name)) {
            add_failed_mess("You are not at a high enough level in " +
                            outer_name +
                            " to advance " + skill_name + " yet.\n");
            return 0;
         }
      }
   }

   if (!SKILL_OB->query_allowed_to_teach(skill_name)) {
      add_failed_mess("You cannot learn '" + skill_name +
                      "' from your guild.\n");
      return 0;
   }

   max_lvl = (int) our_guild->query_skill_max_level(skill_name);
   if (lvl >= max_lvl) {
      add_failed_mess("You cannot advance in " + skill_name +
                      " any further here.\n");
      return 0;
   }

   p_val = (int) this_player()->query_value_in(place);
   if (place != "default") {
      p_val += (int) this_player()->query_value_in("default");
   }

   round_value = MONEY_HAND->query_smallest_value_in(place);
   total_cost = 0;

   for (i = 0; i < by; i++) {
      tmp = query_skill_cost(skill_name, i);

      if ((int) this_player()->query_xp() < tmp + total_xp) {
         if (!i) {
            add_failed_mess("Your lack of experience prevents you improving "
                            + skill_name + ".\n");
            return 0;
         } else {
            write("Your lack of experience prevents you taking all the "
                  "advancement you requested in " + skill_name + ".  You are "
                  "only trained up to level " + (i + lvl) + ".\n");
         }
         break;
      }
      if ((lvl + i) >= max_lvl) {
         write("Your guild hasn't the resources to train you as far as " +
               "you requested in " + skill_name +
               ".  It trains you to level " + max_lvl + ".\n");
         break;
      }
      if (cost_div) {
         tmp_cost = ( total_xp + tmp ) / cost_div;
         if ( tmp_cost + ( tmp_cost % round_value ) > p_val ) {
            if (!i) {
               add_failed_mess
                  ("Due to your lack of money, the guild cannot train " +
                   "you in " + skill_name + ": it would have cost you " +
                   MONEY_HAND->money_value_string( tmp_cost +
                     ( tmp_cost % round_value ), place ) + ".\n" );
               return 0;
            } else {
               write("Due to your sad lack of money the guild cannot train " +
                     "you in " + skill_name + " to level " + (by + lvl) +
                     ".  It trains you to level " + (i + lvl) + " instead.\n");
            }
            break;
         }
      }
      total_xp += tmp;
      total_cost = tmp_cost;
   }

   total_cost += total_cost % round_value;

   if (!total_xp) {
      return add_failed_mess("Oops, something has gone wrong.\n");
   }

   this_player()->adjust_xp(-total_xp);
   if (total_cost) {
      this_player()->pay_money((mixed *) MONEY_HAND->
                               create_money_array(total_cost, place), place);
   }
   this_player()->add_skill_level(skill_name, i, total_xp);
   this_player()->reset_all();
   this_player()->dest_hide_shadow();
   event(this_object(), "guild_advance", bits, lvl, lvl + i);
   check_spells_commands(bits, lvl + i);
   write("You advance your skill in " + skill_name + " from " + lvl + " to " +
         (lvl + i) + " for " + total_xp + " xp" + (total_cost ? " and " +
                                                   (string) MONEY_HAND->
                                                   money_value_string
                                                   (total_cost,
                                                    place) : "") + ".\n");
   say((string) this_player()->one_short() + " $V$0=advances,advance$V$ " +
       "$V$0=" + this_player()->query_possessive() + ",their$V$ skills.\n");
   return 1;
} /* do_advance_internal() */

int do_advance(string skill)
{
   return do_advance_internal(skill, 0, 1);
} /* do_advance() */

int do_advance_by(string skill,
                  int num)
{
   return do_advance_internal(skill, 0, num);
} /* do_advance_by() */

int do_advance_to(string skill,
                  int num)
{
   return do_advance_internal(skill, num, 0);
} /* do_advance_to() */


int do_join(string str)
{
   if ((string) this_player()->query_guild_ob() == our_guild) {
      add_failed_mess("You're already in this guild.\n");
      return 0;
   }
   if (this_player()->query_guild_ob()) {
      add_failed_mess("You cannot join a guild while a member of another.\n");
      return 0;
   }
   write("You will only ever get to join one guild.  Are you sure? ");
   input_to("join2");
   return 1;
} /* do_join() */


int join2(string str)
{

   str = lower_case(str);

   if (str[0] != 'n' && str[0] != 'y') {
      write("I do not understand.  Yes or no? ");
      input_to("join2");
      return 1;
   }
   if (str[0] == 'n') {
      write("Ok, not joining the " + our_guild->query_name() + " guild.\n");
      return 1;
   }
   this_player()->set_guild_ob(our_guild);
   if (stringp(start_pos) && !clonep(environment(this_player())))
      this_player()->add_start(file_name(environment(this_player())),
                               start_pos);
   this_player()->race_guild_commands();
   write("You are now a member of the " + our_guild->query_name() +
         " guild.\n");
   say(this_player()->one_short() + " joins the " + our_guild->query_name() +
       " guild.\n");
   event(this_object(), "guild_join");
   event(users(), "inform",
         this_player()->query_cap_name() + " is now a member " + "of " +
         our_guild->query_name(), "guild");
   return 1;
} /* join2() */


int do_leave(string str)
{
   if (str != "guild") {
      add_failed_mess("Syntax : leave guild\n");
      return 0;
   }
   if ((string) this_player()->query_guild_ob() != our_guild) {
      add_failed_mess("How can you leave a guild if you aren't in it.\n");
      return 0;
   }
   if ((int) this_player()->query_level() > 5) {
      add_failed_mess("You are too high a level to leave this guild.\n");
      return 0;
   }
   write("Are you sure you want to leave the guild (Y/N) : ");
   input_to("confirm_leave");
   return 1;
} /* do_leave() */


void confirm_leave(string str)
{
   str = lower_case(str);
   if (str != "y") {
      write("You are still in the guild.\n");
      return;
   }
   write("Goodbye.\n");
   call_other(our_guild, "leaving_guild");
   this_player()->set_start_pos(CONFIG_START_LOCATION);
   this_player()->set_guild_ob(0);
   this_player()->set_guild_data(0);
   this_player()->guild_commands();
   this_player()->save_me();
} /* confirm_leave() */


int check_primaries(string lpath, string g_o)
{
   int i;
   string dummy,
    *primaries;

   primaries = (string *) g_o->query_skills();
   if (member_array(lpath, primaries) != -1)
      return 1;
   for (i = 0; i < sizeof(primaries); i++)
      if (sscanf(primaries[i], lpath + ".%s", dummy))
         return 1;
   return 0;
} /* check_primaries() */


/*
 * The purpose of this function is to build an array in the same
 * format as what you get from SKILL_OB->query_skills, but only
 * containing the data for the primaries in this guild.
 */
mixed *filter_primaries(mixed *tmp_skills, string skill_path,
                        string *primaries)
{
   int i;
   string test_skill;

   for (i = 0; i < sizeof(tmp_skills); i += SKILL_ARR_SIZE)  {
      test_skill = skill_path + tmp_skills[i];
      if (sizeof(tmp_skills[i + SKILL_BIT]) != 0) /* not a leaf skill */
         tmp_skills[i + SKILL_BIT] =
            filter_primaries(tmp_skills[i + SKILL_BIT], test_skill + ".",
                             primaries);
      if (member_array(test_skill, primaries) == -1  &&
          sizeof(tmp_skills[i + SKILL_BIT]) == 0)
      {
         tmp_skills = tmp_skills[0 .. (i - 1)] +
                      tmp_skills[(i + SKILL_ARR_SIZE) .. ];
         i -= SKILL_ARR_SIZE;
      }
   }
   return tmp_skills;

} /* filter_primaries() */


private string rec_cost(mixed *arr, string path, int depth, string guild,
                        int brief)
{
   /* use lots of variables...so we only work things out minimum times */
   int i;
   int depth_gap;
   int ndots;
   int lvl;
   int max_lvl;
   int only_leaf;
   int tmp;
   string str;
   string sub_str;
   string lpath;

   str = "";
   depth_gap = (depth - 1) * 2;
   ndots = 19 - depth_gap;

   for (i = 0; i < sizeof(arr); i += SKILL_ARR_SIZE) {
      lpath = path + arr[i];
      lvl = this_player()->query_skill(lpath);
      if (!guild) {
         max_lvl = 5;
      } else {
         max_lvl = guild->query_skill_max_level(lpath);
      }

      only_leaf = SKILL_OB->query_only_leaf(lpath);

      /* If this is a "lead-only" skill and it's not bottom level... */
      if (only_leaf  &&  sizeof(arr[i + SKILL_BIT]) > 0)  {
         sub_str = rec_cost(arr[i + SKILL_BIT], lpath + ".", depth + 1,
                            guild, brief);
         /* And if there are subskills to print under this skill... */
         if (sub_str != "")  {
            /*
             * Print a row of dots for this skill, then print the
             * subskill info and skip to the next skill
             */
            str += sprintf("%*'| 's%-*'.'s\n", depth_gap, "",
                           ndots + 18, arr[i]) + sub_str;
            continue;
         }
      }
      /* If we're over the guild max in this skill... */
      else if (lvl >= max_lvl)  {
         /* And we're in brief mode... */
         if (brief)  {
            sub_str = rec_cost(arr[i + SKILL_BIT], lpath + ".", depth + 1,
                               guild, brief);
            /* And if there are subskills to print under this skill... */
            if (sub_str != "")  {
               /*
                * Print a row of dots for this skill, then print the
                * subskill info and skip to the next skill
                */
               str += sprintf("%*'| 's%-*'.'s\n", depth_gap, "",
                              ndots + 18, arr[i]) + sub_str;
               continue;
            }
         }
         /* But if we're not in brief mode, print the 'mastered' thingy */
         else str += sprintf("%*'| 's%-*'.'s%4d/%3d  mastered\n", depth_gap,
                             "", ndots, arr[i], lvl, max_lvl);
      }
      /*
       * Otherwise, we're not over the max level, AND it is actually a
       * learnable skill, so print the cost info
       */
      else {
         tmp = query_skill_cost(lpath, 0);
         str += sprintf("%*'| 's%-*'.'s%4d/%3d %6d xp\n", depth_gap, "",
                        ndots, arr[i], lvl, max_lvl, tmp);
      }

      /*
       *If we're capable of learning subskills for this skill, or if this
       * is a leaf-only skill, then go down one more level
       */
      if (lvl >= depth * 5  ||  only_leaf) {
         reset_eval_cost();
         str += rec_cost(arr[i + SKILL_BIT], lpath + ".", depth + 1, guild,
                         brief);
      }
   }
   return str;

} /* rec_cost() */


int do_cost_all(int brief)
{
   mixed *arr;
   string list;

   if ((string) this_player()->query_guild_ob() != our_guild) {
      add_failed_mess("You are not a member of this guild.\n");
      return 0;
   }
   arr = (mixed *) SKILL_OB->query_skills();
   if (!arr) {
      add_failed_mess("Hmmm, we appear to have an error here.\n");
      return 0;
   }
   list = sprintf("%-*'='s\n", (int) this_player()->query_cols(),
                  "======SKILLS=======Cur/Max==For Next");
   list += sprintf("%#*-s\n", (int) this_player()->query_cols() + 1,
                   rec_cost(arr, "", 1, our_guild, brief));
   list += sprintf("%*'='|s\n", (int) this_player()->query_cols(),
                   "> You have " + (int) this_player()->query_xp() +
                   " points to spend <");
   this_player()->more_string(list, "All", 1);
   return 1;

} /* do_cost_all() */


int do_cost_primaries()
{
   mixed *arr;
   string list;
   string *primaries;

   if ((string) this_player()->query_guild_ob() != our_guild) {
      add_failed_mess("You are not a member of this guild.\n");
      return 0;
   }
   arr = copy((mixed *)SKILL_OB->query_skills());
   if (!arr) {
      add_failed_mess("Hmmm, we appear to have an error here.\n");
      return 0;
   }

   primaries = our_guild->query_skills();
   arr = filter_primaries(arr, "", primaries);

   list = sprintf("%-*'='s\n", (int) this_player()->query_cols() - 1,
                  "======SKILLS=======Cur/Max==For Next");
   list += sprintf("%#*-s\n", (int) this_player()->query_cols(),
                   rec_cost(arr, "", 1, our_guild, 0));
   list += sprintf("%*'='|s\n", (int) this_player()->query_cols() - 1,
                   "> You have " + (int) this_player()->query_xp() +
                   " points to spend <");
   this_player()->more_string(list, "Primaries", 1);
   return 1;

} /* do_cost_primaries() */


int do_cost_internal(string skill, int to, int by)  {
   string *bits;
   string skill_name;
   string outer_name;
   string place;
   string cost_str;
   int lvl;
   int max_lvl;
   int i;
   int tmp;
   int cost;

   if ((string) this_player()->query_guild_ob() != our_guild) {
      add_failed_mess("You are not a member of this guild.\n");
      return 0;
   }

   bits = explode(implode(explode(skill, " "), "."), ".");
   if (!(skill_name = (string) SKILL_OB->query_skill(bits))) {
      add_failed_mess("There is no such skill as " + skill + ".\n");
      return 0;
   }

   lvl = (int) this_player()->query_skill(skill_name);
   if (!by && to)
      by = to - lvl;
   if (by == 0) {
      add_failed_mess
         ("It won't cost you anything to stay at the same level!\n");
      return 0;
   }
   if (by < 0) {
      add_failed_mess("We can't give refund xp for regressing skills!\n");
      return 0;
   }

   bits = explode(skill_name, ".");
   if (sizeof(bits) > 1  &&  !SKILL_OB->query_only_leaf(skill_name)) {
      outer_name = implode(bits[0 .. <2], ".");
      if (((sizeof(bits) - 1) * 5) >
          this_player()->query_skill(outer_name))
      {
         add_failed_mess("You are not at a high enough level in " +
                         outer_name + " to advance " + skill_name +
                         " yet.\n");
         return 0;
      }
   }

   if (!SKILL_OB->query_allowed_to_teach(skill_name)) {
      add_failed_mess("You cannot learn '" + skill_name +
                      "' from your guild.\n");
      return 0;
   }

   max_lvl = (int) our_guild->query_skill_max_level(skill_name);
   if (lvl >= max_lvl) {
      add_failed_mess("Your guild prevents you even considering advancing " +
                      skill_name + " above level " + max_lvl + ".\n");
      return 0;
   }

   for (i = 0; i < by; i++) {
      if ((lvl + i) >= max_lvl) {
         write("Your guild prevents you considering all the advancement you "
               + "requested.  You can only advance up to level " + max_lvl +
               " in " + skill_name + " here.\n");
         break;
      }
      tmp += query_skill_cost(skill_name, i);

   }

   // Now work out the monetary cost if any.
   place = this_object()->query_property("place");
   if (!place)
      place = "default";
   cost_str = "";
   if (cost_div) {
      cost = tmp / cost_div;
      cost += cost % MONEY_HAND->query_smallest_value_in(place);
      if (cost)
         cost_str = " and " + MONEY_HAND->money_value_string(cost, place);
   }

   printf("It would cost you %d xp%s to raise %s from level %d to %d.\n",
          tmp, cost_str, skill_name, lvl, (lvl + i));
   return 1;

} /* do_cost_internal() */


int do_cost(string skill)
{
   mixed *arr;
   int i;
   int depth;
   string list;
   string exp_skill;
   string *sub_skills;
   int only_leaf;

   if ((string) this_player()->query_guild_ob() != our_guild) {
      add_failed_mess("You are not a member of this guild.\n");
      return 0;
   }
   arr = (mixed *) SKILL_OB->query_skills();
   if (!arr) {
      add_failed_mess("Hmmm, we appear to have an error here.\n");
      return 0;
   }

   exp_skill =
      SKILL_OB->query_skill(explode(implode(explode(skill, " "), "."), "."));
   if (!exp_skill)  {
      add_failed_mess("There is no such skill as " + skill + ".\n");
      return 0;
   }

   i = member_array(exp_skill, arr);
   only_leaf = SKILL_OB->query_only_leaf(exp_skill);
   if (only_leaf)  {
      sub_skills = explode(exp_skill, ".");
      foreach (skill in sub_skills[0 .. < 2])  {
         i = member_array(skill, arr);
         arr = arr[i + 3];
      }
      i = member_array(sub_skills[<1], arr);
      depth = sizeof(sub_skills) + 1;
   }
   else depth = 2;
   if (sizeof(arr[i + 3]) > 0)  {
      list = sprintf("%-*'='s\n", (int) this_player()->query_cols() - 1,
                     "======SKILLS=======Cur/Max==For Next") +
             sprintf("%#*-s\n", (int) this_player()->query_cols(),
                      rec_cost(arr[i + SKILL_BIT], exp_skill + ".", depth,
                      our_guild, 0)) +
             sprintf("%*'='|s\n", (int) this_player()->query_cols() - 1,
                      "> You have " + (int) this_player()->query_xp() +
                      " points to spend <");
      this_player()->more_string(list, capitalize(exp_skill), 1);
      return 1;
   }
   return do_cost_internal(exp_skill, 0, 1);

} /* do_cost() */


int do_cost_to(string skill, int num)
{
   return do_cost_internal(skill, num, 0);
} /* do_cost_to() */

int do_cost_by(string skill, int num)
{
   return do_cost_internal(skill, 0, num);
} /* do_cost_to() */


int do_info()
{
   mixed *arr;
   string *primaries;

   write(our_guild->long() +
         "\nThis guild's primary skills and costs are:\n");
   arr = copy((mixed *)SKILL_OB->query_skills());
   if (!arr) {
      add_failed_mess("Hmmm, we appear to have an error here.\n");
      return 0;
   }
   primaries = our_guild->query_skills();
   arr = filter_primaries(arr, "", primaries);
   printf("%-*'='s\n", this_player()->query_cols() - 1,
          "======SKILLS=======Cur/Max==For Next");
   printf("%#*-s\n", this_player()->query_cols(),
          rec_cost(arr, "", 1, our_guild, 0));
   printf("%*'='|s\n", this_player()->query_cols() - 1, "> You have " +
          this_player()->query_xp() + " points to spend <");
   return 1;

} /* do_info() */


void set_teaching_person(object ob)
{
   teaching_person = ob;
}

object query_teaching_person()
{
   return teaching_person;
}


void add_spell(string name, string *blue, int lvl)
{
   string path;

   path = implode(blue, ".");
   if (!spells[path])
      spells[path] = ({ name, lvl });
   else
      spells[path] += ({ name, lvl });
} /* add_spell() */


void add_command(string name, string *blue, int lvl)
{
   string path;

   path = implode(blue, ".");

   if (!commands)
      commands = ([ ]);
   if (!commands[path])
      commands[path] = ({ name, lvl });
   else
      commands[path] += ({ name, lvl });

} /* add_command() */


void check_spells_commands(string *sk, int lvl)
{
   string *bits;
   int val;

   int i;
   int j;

   if (!teaching_person)
      return;
   bits = keys(spells);
   for (i = 0; i < sizeof(bits); i++) {
      val = this_player()->query_skill(bits[i]);
      for (j = 0; j < sizeof(spells[bits[i]]); j += 2)
         if ((spells[bits[i]][j + 1] < val) &&
             !(this_player()->query_spell(spells[bits[i]][j])))
            teaching_person->init_command("teach " + spells[bits[i]][j] +
                                          " to " +
                                          this_player()->query_name());
   }
   bits = keys(commands);
   for (i = 0; i < sizeof(bits); i++) {
      val = this_player()->query_skill(bits[i]);
      for (j = 0; j < sizeof(commands[bits[i]]); j += 2)
         if ((commands[bits[i]][j + 1] < val) &&
             !(this_player()->query_known_command(commands[bits[i]][j])))
            teaching_person->init_command("teach " + commands[bits[i]][j] +
                                          " to " +
                                          this_player()->query_name());
   }
} /* check_spell_commands() */


mapping query_spells()
{
   return spells + ([ ]);
}

mapping query_commands()
{
   return commands + ([ ]);
}

string query_start_pos()
{
   return start_pos;
}

string query_our_guild()
{
   return our_guild;
}