/* do we use this one ? */
/* it's just a version of guild.c */
inherit "/std/room";
#include "skills.h"
#include "tune.h"
#include "money.h"
string our_guild,
guild_path,
*spec;
mixed *spells,
*memspells,
*commands;
object teaching_person;
void check_spells_commands(string *sk, int lvl);
int query_specialization(string name);
void create() {
spells = ({ });
spec = ({ });
memspells = ({ });
commands = ({ });
::create();
} /* create() */
void init() {
::init();
add_action("do_advance", "advance");
add_action("do_join", "join");
add_action("do_info", "info");
add_action("do_cost", "cost");
add_action("do_specialize", "specialize");
} /* init() */
void set_guild(string str) { our_guild = "/std/guilds/"+str; }
int do_advance()
{
string skill;
string *bits;
int cost, i, xp, lvl, total_xp, p_val;
string guild;
lvl = (int)this_player()->query_level();
guild=this_player()->query_guild_ob();
if (!guild) /* Have we joined any guild at all ? */
{
notify_fail("If you 'join' you can advance here.\n");
return 0;
}
/***** Remember to add path for specializing!!!! *******/
/* If so, is it this_guild ? */
if (guild != our_guild && !query_specialization(guild))
{
write(guild+" = guild AND "+our_guild+" = our_guild.\n");
notify_fail("You cannot advance here! Go to your own guild.\n");
return 0;
}
/* The following bit is removed awaiting code from Dan. He'll produce code
* to compute the actual computing of raising in skill-levels. I've declared
* string *bits; for dividing up the skill-bits, but can do no more since I
* honestly don't know how it'll work.
* 7.1.93: Put back so that we can test other things while waiting.
*/
xp = (int)this_player()->query_xp_cost(); /* How much xp/lvl it will cost */
if((int)this_player()->query_xp() < xp*(lvl+1))
{
notify_fail("Your lack of experience prevents you from advancing.\n");
return 0;
}
/* Checks for racial max levels not yet implemented *************
max_lvl = (int)my_race_ob->query_max_level(guild);
if (lvl == max_lvl)
{
notify_fail("You can advance higher than "+lvl+" because you're a "+
my_race+".\n");
return 0;
}
*/
/* Monetary payment to advance in level */
cost = (int)our_guild->query_advance_cost();
/* Default cost if not defined. Thought 500 GP/level was OK */
cost *= lvl; /* Total monetary cost of advancing */
p_val = (int)this_player()->query_value(); /* How much money do we have */
if (cost > p_val) /* What happens if we can't pay */
{
notify_fail("Due to your sad lack of money the guild refuses to train "
"you. It would have cost you "+
MONEY_HAND->money_value_string(cost)+".\n");
return 0;
}
this_player()->pay_money(MONEY_HAND->create_money_array(cost));
this_player()->set_level(++lvl);
this_player()->reset_all();
/* event(this_object(), "guild_advance", bits, lvl, lvl+1); */
this_player()->reset_all();
write("You advance to level "+lvl+" for "+
MONEY_HAND->money_value_string(cost)+".\n");
say(this_player()->query_cap_name()+" advances "+
this_player()->query_possessive()+" level.\n");
return 1;
} /* do_advance() */
/* Some of the code I planned to use for proficiencies. Just left some of
* it here in case it's of any use to Dank
*/
int train(string str)
{
string skill_name, sk, guild;
int cost, lvl;
if (!(skill_name = (string)SKILL_OB->query_skill(sk)))
{
notify_fail("I am sorry but the " + sk + " skill does not exist.\n");
return 0;
}
if ((guild=(string)this_player()->query_guild_ob()) != our_guild && guild)
{
notify_fail("You cannot train here! Go to your own guild.\n");
return 0;
}
if(!str)
{
notify_fail("Syntax: train <skill>.\n");
return 0;
}
if(!guild)
cost = DEFAULT_COST; /* Cheaper training in skill for members. */
else
cost = (int)our_guild->query_skill_cost(skill_name);
cost *= (int)SKILL_OB->query_skill_cost(skill_name);
} /* Will be used for proficiencies */
int do_join(string str)
{
string guild;
string race;
guild = (string)this_player()->query_guild_ob();
race = (string)this_player()->query_race();
if(guild == our_guild)
{
notify_fail("You're already in this guild.\n");
return 0;
}
if(guild)
{
notify_fail("You cannot join a guild while a member of another.\n");
return 0;
}
if(!our_guild->query_legal_race(race))
{
notify_fail("Sorry, but a "+race+" can't become a "+
our_guild->query_name()+".\n");
return 0;
}
write("You will only ever get to join one guild. Are you sure? ");
input_to("join2");
return 1;
} /* do_join() */
/* Not quite finished converting this. Waiting for Dank's skills system */
int join2(string str) {
mixed skills;
int i;
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);
this_player()->race_guild_commands();
write("You are now a member of the "+our_guild->query_cap_name()+"'s guild.\n");
say(this_player()->query_cap_name()+" 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(), "join");
skills = (mixed *)this_player()->query_skills();
for (i=0;i<sizeof(skills);i+=SKILL_ARR_SIZE) {
/* This will only set up the outer skill-bits (str, dec, con etc.) */
check_spells_commands(skills[i+SKILL_NAM..i+SKILL_NAM],
skills[i+SKILL_LVL]);
}
this_player()->set_level(1);
return 1;
} /* join2() */
/* This is not supposed to be possible until we allow for dual-classes.
* I moved the leave code here since I felt you should have to be in the
* room of your guild when you leave. It's easily moved back to the guild-
* object if most of you prefer it that way.
*/
int do_leave(string str)
{
if(str != "guild") {
notify_fail("Syntax : leave guild\n");
return 0;
}
if ((string)this_player()->query_guild_ob() != our_guild) {
notify_fail("How can you leave a guild if you aren't in it.\n");
return 0;
}
if ((int)this_player()->query_level() > 5) {
notify_fail("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("You left your guild.\n");
call_other(our_guild, "leaving_guild");
this_player()->set_guild_ob(0);
this_player()->set_guild_data(0);
this_player()->guild_commands();
this_player()->save_me();
} /* confirm_leave() */
/* Will have to be rewritten a lot if we choose tell players how much xp
* they'll need to advance in each skill/subskill
*/
int do_cost()
{
string guild, cost;
int xp_cost, lvl;
guild = (string)this_player()->query_guild_ob();
xp_cost = (int)our_guild->query_xp_cost();
cost = MONEY_HAND->money_value_string((int)our_guild->query_advance_cost());
lvl = this_player()->query_level();
if(!guild)
{
notify_fail("If you join this guild you will have to earn "+
xp_cost+" XP, and expect to pay "+cost+" to reach 2nd level.\n");
return 0;
}
if (guild != our_guild)
{
notify_fail("You are not a member of this guild.\n");
return 0;
}
/* Checks for racial max levels not yet implemented *************
max_lvl = (int)my_race_ob->query_max_level(guild);
if (lvl == max_lvl)
{
notify_fail("You can advance higher than "+lvl+" because you're a "+
my_race+".\n");
return 0;
}
*/
write("You will need "+xp_cost*lvl+" XP and "+cost+
" to advance to level "+(lvl+1)+".\n");
return 1;
} /* do_cost() */
/* The same goes for do_info() as for do_cost() of course */
int do_info()
{
write(our_guild->long());
do_cost();
return 1;
} /* do_info() */
/*
* From here on are the changes to make level gaining hopefully more
* realistic... (Note the more :)
*/
void add_spell(string name, string *path, int lvl) {
spells += ({ name, path, lvl });
} /* add_spell() */
void add_command(string name, string *path, int lvl) {
commands += ({ name, path, lvl });
} /* add_command() */
int query_specialization(string name)
{
if(member_array(name,spec) != -1)
return 1;
return 0;
}
void add_specialization(string name)
{
spec += ({ name });
} /* add_specialization() */
int do_specialize(string name)
{
string path;
if((string)this_player()->query_guild_ob() != our_guild)
{
notify_fail("You can't specialize in this guild since you're not a "
"member.\n");
return 0;
}
if((int)this_player()->query_level() != 1)
{
notify_fail("You can't specialize after you've already advanced in "
"level.\n");
return 0;
}
if (query_specialization(name))
{
path = "/std/race"->query_guild_path(name);
tell_room(this_player(), this_player()->query_cap_name()+" specialices "
"and becomes a "+name+".\n", this_player());
write("You're accepted as a "+name+" specialist. CONGRATULATIONS!!!\n");
this_player()->set_guild_ob(path);
return 1;
}
notify_fail("That's not a valid specialization.\n");
return 0;
} /* do_specialize() */
void set_teaching_person(object ob) { teaching_person = ob; }
object query_teaching_person() { return teaching_person; }
void check_spells_commands(string *path, int lvl) {
int i, j;
if (!teaching_person || member_array(this_player(),
(object *)teaching_person->query_attacker_list()) != -1)
return ;
for (i=0;i<sizeof(spells);i+=3)
for (j=0;j<sizeof(spells[i+1]);j++)
if (j >= sizeof(path)) { /* got through the skill path ok */
if (spells[i+2] <= lvl)
teaching_person->init_command("teach "+spells[i]+" to "+
this_player()->query_name());
} else
if (spells[i+1][j] != path[j])
break;
for (i=0;i<sizeof(commands);i+=3)
for (j=0;j<sizeof(commands[i+1]);j++)
if (j >= sizeof(path)) { /* got through the skill path ok */
if (commands[i+2] <= lvl)
teaching_person->init_command("teach "+commands[i]+" to "+
this_player()->query_name());
} else
if (commands[i+1][j] != path[j])
break;
} /* check_spell_commands() */
mixed * query_spells() { return spells + ({ }); }
mixed * query_commands() { return commands + ({ }); }
/* This is not pretty, but I added it in case Dank feel like giving the players
* some info of how much xp it will cost to advance in skills.
*/
string rec_cost_old(mixed *arr, string path, int depth) {
int i;
int cost;
string str, lpath;
str = "";
for (i=0;i<sizeof(arr);i+=SKILL_ARR_SIZE) {
lpath = path + "." + arr[i];
cost = (int)SKILL_OB->query_skill_cost((lpath)[1..500]);
cost *= (int)our_guild->query_skill_cost((lpath)[1..500]);
str += sprintf("%*'| 's%-*'.'s costs %d xp.\n", (depth-1)*2, "",
20-(depth-1)*2, arr[i],
cost*STD_COST*(((int)this_player()->query_skill(lpath)
/LEVEL_DIV)+1));
if (this_player()->query_skill(lpath) >= depth*5)
str += rec_cost_old(arr[i+SKILL_BIT], path+"."+arr[i], depth+1);
}
return str;
} /* rec_cost_old() */
string rec_cost(mixed *arr, string path, int depth, string g_o)
{ /* use lots of variables...so we only work things out minimum times */
int i, depth_gap, ndots;
int cost, lvl, max_lvl;
string str, lpath;
str = "";
depth_gap = (depth - 1) * 2;
ndots = 18 - depth_gap;
for (i=0;i<sizeof(arr);i+=SKILL_ARR_SIZE) {
if (path != "")
lpath = path + "." + arr[i];
else
lpath = arr[i];
lvl = (int)this_player()->query_skill(lpath);
if (!g_o)
max_lvl = 5;
else
max_lvl = (int)g_o->query_skill_max_level(lpath);
if(lvl >= max_lvl) {
str += sprintf("%*'| 's%-*'.'s %3d/%3d mastered\n", depth_gap, "",
ndots, arr[i], lvl, max_lvl);
} else {
if (!g_o)
cost = DEFAULT_COST;
else
cost = (int)g_o->query_skill_cost(lpath);
cost *= (int)SKILL_OB->query_skill_cost(lpath);
cost *= (STD_COST/5)*((lvl/LEVEL_DIV)+1);
str += sprintf("%*'| 's%-*'.'s %3d/%3d %6d xp\n", depth_gap, "",
ndots, arr[i], lvl, max_lvl, cost);
}
if (lvl >= depth*5)
str += rec_cost(arr[i+SKILL_BIT], lpath, depth+1, g_o);
}
return str;
} /* rec_cost() */