/**************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefiting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* Brian Moore (zump@rom.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
***************************************************************************
* 1stMud ROM Derivative (c) 2001-2004 by Markanth *
* http://www.firstmud.com/ <markanth@firstmud.com> *
* By using this code you have agreed to follow the term of *
* the 1stMud license in ../doc/1stMud/LICENSE *
***************************************************************************/
#include "merc.h"
#include "interp.h"
#include "magic.h"
#include "recycle.h"
Do_Fun (do_gain)
{
char arg[MAX_INPUT_LENGTH];
CharData *trainer;
int gn = 0, sn = 0, val;
int mult;
if (IsNPC (ch))
return;
for (trainer = ch->in_room->person_first; trainer != NULL;
trainer = trainer->next_in_room)
if (IsNPC (trainer) && IsSet (trainer->act, ACT_GAIN))
break;
if (trainer == NULL || !can_see (ch, trainer))
{
chprintln (ch, "You can't do that here.");
return;
}
mult = mult_argument (argument, arg);
if (NullStr (arg))
{
do_function (trainer, &do_say, "Pardon me?");
return;
}
if (!str_prefix (arg, "list"))
{
Buffer *output;
Column *Cd;
Cd = new_column ();
output = new_buf ();
set_cols (Cd, ch, 3, COLS_BUF, output);
cols_header (Cd, "{w%-18s Cost ", "Group");
for (gn = 0; gn < top_group; gn++)
{
if (!ch->pcdata->group_known[gn]
&& (val = group_rating (ch, gn)) > 0)
{
print_cols (Cd, "%-18s %-4d ", group_table[gn].name, val);
}
}
cols_nl (Cd);
bprintln (output, NULL);
set_cols (Cd, ch, 3, COLS_BUF, output);
cols_header (Cd, "{w%-15s %-4s Lev ", "Skill", "Cost");
for (sn = 0; sn < top_skill; sn++)
{
if (!ch->pcdata->learned[sn] &&
(val = skill_rating (ch, sn)) > 0 &&
skill_table[sn].spell_fun == spell_null)
{
print_cols (Cd, "%-16s %-3d %-3d ",
skill_table[sn].name, val, skill_level (ch, sn));
}
}
cols_nl (Cd);
bprintlnf (output, "You have %s left.", intstr (ch->train, "train"));
bprintlnf (output,
"Use 'grlist' to see what skills are within a group.");
sendpage (ch, buf_string (output));
free_buf (output);
free_column (Cd);
return;
}
if (!str_prefix (arg, "convert"))
{
if (ch->practice < 10 * mult)
{
act ("$N tells you 'You are not yet ready.'", ch, NULL,
trainer, TO_CHAR);
return;
}
act ("$N helps you apply your practice to training", ch, NULL,
trainer, TO_CHAR);
ch->practice -= 10 * mult;
ch->train += mult;
return;
}
if (!str_prefix (arg, "points"))
{
int xp;
if (ch->train < 2)
{
act ("$N tells you 'You are not yet ready.'", ch, NULL,
trainer, TO_CHAR);
return;
}
if (ch->pcdata->points <= 40)
{
act ("$N tells you 'There would be no point in that.'",
ch, NULL, trainer, TO_CHAR);
return;
}
act ("$N trains you, and you feel more at ease with your skills.",
ch, NULL, trainer, TO_CHAR);
ch->train -= 2;
xp = ch->exp - (ch->level * exp_per_level (ch, ch->pcdata->points));
ch->pcdata->points -= 1;
ch->exp = exp_per_level (ch, ch->pcdata->points) * ch->level;
ch->exp += xp;
return;
}
gn = group_lookup (argument);
if (gn >= 0 && gn < top_group)
{
if (ch->pcdata->group_known[gn])
{
act ("$N tells you 'You already know that group!'", ch,
NULL, trainer, TO_CHAR);
return;
}
if ((val = group_rating (ch, gn)) < 1)
{
act ("$N tells you 'That group is beyond your powers.'",
ch, NULL, trainer, TO_CHAR);
return;
}
if (ch->train < val)
{
act ("$N tells you 'You are not yet ready for that group.'",
ch, NULL, trainer, TO_CHAR);
return;
}
gn_add (ch, gn);
act ("$N trains you in the art of $t", ch, group_table[gn].name,
trainer, TO_CHAR);
ch->train -= val;
return;
}
sn = skill_lookup (argument);
if (sn > -1 && sn < top_skill)
{
if (skill_table[sn].spell_fun != spell_null)
{
act ("$N tells you 'You must learn the full group.'", ch,
NULL, trainer, TO_CHAR);
return;
}
if (ch->pcdata->learned[sn])
{
act ("$N tells you 'You already know that skill!'", ch,
NULL, trainer, TO_CHAR);
return;
}
if ((val = skill_rating (ch, sn)) < 1)
{
act ("$N tells you 'That skill is beyond your powers.'",
ch, NULL, trainer, TO_CHAR);
return;
}
if (ch->train < skill_rating (ch, sn))
{
act ("$N tells you 'You are not yet ready for that skill.'",
ch, NULL, trainer, TO_CHAR);
return;
}
ch->pcdata->learned[sn] = 1;
act ("$N trains you in the art of $t", ch, skill_table[sn].name,
trainer, TO_CHAR);
ch->train -= val;
return;
}
act ("$N tells you 'I do not understand...'", ch, NULL, trainer, TO_CHAR);
}
Do_Fun (do_spells)
{
Buffer *buffer;
char arg[MAX_INPUT_LENGTH];
char spell_list[MAX_MORTAL_LEVEL + 1][MAX_STRING_LENGTH];
char spell_columns[MAX_MORTAL_LEVEL + 1];
int sn, level, min_lev = 1, max_lev = MAX_MORTAL_LEVEL, mana;
bool fAll = false, found = false;
char buf[MAX_STRING_LENGTH];
if (IsNPC (ch))
return;
if (!NullStr (argument))
{
fAll = true;
if (str_prefix (argument, "all"))
{
argument = one_argument (argument, arg);
if (!is_number (arg))
{
chprintln (ch, "Arguments must be numerical or all.");
return;
}
max_lev = atoi (arg);
if (max_lev < 1 || max_lev > MAX_MORTAL_LEVEL)
{
chprintlnf (ch, "Levels must be between 1 and %d.",
MAX_MORTAL_LEVEL);
return;
}
if (!NullStr (argument))
{
argument = one_argument (argument, arg);
if (!is_number (arg))
{
chprintln (ch, "Arguments must be numerical or all.");
return;
}
min_lev = max_lev;
max_lev = atoi (arg);
if (max_lev < 1 || max_lev > MAX_MORTAL_LEVEL)
{
chprintlnf (ch,
"Levels must be between 1 and %d.",
MAX_MORTAL_LEVEL);
return;
}
if (min_lev > max_lev)
{
chprintln (ch, "That would be silly.");
return;
}
}
}
}
for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
{
spell_columns[level] = 0;
spell_list[level][0] = '\0';
}
for (sn = 0; sn < top_skill; sn++)
{
if ((level = skill_level (ch, sn)) < MAX_MORTAL_LEVEL + 1 &&
(fAll || level <= ch->level) && level >= min_lev &&
level <= max_lev && skill_table[sn].spell_fun != spell_null &&
ch->pcdata->learned[sn] > 0)
{
found = true;
level = skill_level (ch, sn);
if (ch->level < level)
sprintf (buf, "%-18s n/a ", skill_table[sn].name);
else
{
mana =
Max (skill_table[sn].min_mana, 100 / (2 + ch->level - level));
sprintf (buf, "%-18s %3d mana ", skill_table[sn].name, mana);
}
if (spell_list[level][0] == '\0')
sprintf (spell_list[level], NEWLINE "Level %2d: %s", level, buf);
else
{
if (++spell_columns[level] % 2 == 0)
strcat (spell_list[level], NEWLINE " ");
strcat (spell_list[level], buf);
}
}
}
if (!found)
{
chprintln (ch, "No spells found.");
return;
}
buffer = new_buf ();
for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
if (spell_list[level][0] != '\0')
bprint (buffer, spell_list[level]);
bprintln (buffer, NULL);
sendpage (ch, buf_string (buffer));
free_buf (buffer);
}
Do_Fun (do_skills)
{
Buffer *buffer;
char arg[MAX_INPUT_LENGTH];
char skill_list[MAX_MORTAL_LEVEL + 1][MAX_STRING_LENGTH];
char skill_columns[MAX_MORTAL_LEVEL + 1];
int sn, level, min_lev = 1, max_lev = MAX_MORTAL_LEVEL;
bool fAll = false, found = false;
char buf[MAX_STRING_LENGTH];
if (IsNPC (ch))
return;
if (!NullStr (argument))
{
fAll = true;
if (str_prefix (argument, "all"))
{
argument = one_argument (argument, arg);
if (!is_number (arg))
{
chprintln (ch, "Arguments must be numerical or all.");
return;
}
max_lev = atoi (arg);
if (max_lev < 1 || max_lev > MAX_MORTAL_LEVEL)
{
chprintlnf (ch, "Levels must be between 1 and %d.",
MAX_MORTAL_LEVEL);
return;
}
if (!NullStr (argument))
{
argument = one_argument (argument, arg);
if (!is_number (arg))
{
chprintln (ch, "Arguments must be numerical or all.");
return;
}
min_lev = max_lev;
max_lev = atoi (arg);
if (max_lev < 1 || max_lev > MAX_MORTAL_LEVEL)
{
chprintlnf (ch,
"Levels must be between 1 and %d.",
MAX_MORTAL_LEVEL);
return;
}
if (min_lev > max_lev)
{
chprintln (ch, "That would be silly.");
return;
}
}
}
}
for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
{
skill_columns[level] = 0;
skill_list[level][0] = '\0';
}
for (sn = 0; sn < top_skill; sn++)
{
if ((level = skill_level (ch, sn)) < MAX_MORTAL_LEVEL + 1 &&
(fAll || level <= ch->level) && level >= min_lev &&
level <= max_lev && skill_table[sn].spell_fun == spell_null &&
ch->pcdata->learned[sn] > 0)
{
found = true;
level = skill_level (ch, sn);
if (ch->level < level)
sprintf (buf, "{c%-18s n/a ", skill_table[sn].name);
else
sprintf (buf, "{c%-18s {W%3d%% ",
skill_table[sn].name, ch->pcdata->learned[sn]);
if (skill_list[level][0] == '\0')
sprintf (skill_list[level], NEWLINE "{cLevel {W%2d{c: %s{x",
level, buf);
else
{
if (++skill_columns[level] % 2 == 0)
strcat (skill_list[level], NEWLINE "{x ");
strcat (skill_list[level], buf);
}
}
}
if (!found)
{
chprintln (ch, "{cNo skills found.{x");
return;
}
buffer = new_buf ();
for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
if (skill_list[level][0] != '\0')
bprint (buffer, skill_list[level]);
bprintln (buffer, NULL);
sendpage (ch, buf_string (buffer));
free_buf (buffer);
}
void
list_group_costs (CharData * ch)
{
int gn, sn, val;
Buffer *output;
Column *Cd;
if (IsNPC (ch))
return;
output = new_buf ();
Cd = new_column ();
set_cols (Cd, ch, 3, COLS_BUF, output);
bprintlnf (output, "{c%s", draw_line (ch, NULL, 0));
cols_header (Cd, "{w%-18s CP ", "Group");
for (gn = 0; gn < top_group; gn++)
{
if (!ch->gen_data->group_chosen[gn]
&& !ch->pcdata->group_known[gn]
&& (val = group_rating (ch, gn)) > 0)
{
print_cols (Cd, "{c%-18s {W%-2d ", group_table[gn].name, val);
}
}
cols_nl (Cd);
bprintlnf (output, "{c%s", draw_line (ch, NULL, 0));
set_cols (Cd, ch, 2, COLS_BUF, output);
cols_header (Cd, "{w%-18s %-2s Lev ", "Skill", "CP");
for (sn = 0; sn < top_skill; sn++)
{
if (!ch->gen_data->skill_chosen[sn]
&& ch->pcdata->learned[sn] == 0
&& skill_table[sn].spell_fun == spell_null
&& (val = skill_rating (ch, sn)) > 0)
{
print_cols (Cd, "{c%-18s {W%-2d %-3d ",
skill_table[sn].name, val, skill_level (ch, sn));
}
}
cols_nl (Cd);
bprintlnf (output, "{c%s", draw_line (ch, NULL, 0));
bprintln (output, NULL);
bprintlnf (output, "{cCreation points: {W%d{x", ch->pcdata->points);
bprintlnf (output, "{cExperience per level: {W%d{x",
exp_per_level (ch,
Max (ch->gen_data->points_chosen,
ch->pcdata->points)));
sendpage (ch, buf_string (output));
free_buf (output);
free_column (Cd);
return;
}
void
list_group_chosen (CharData * ch)
{
int gn, sn, val;
Buffer *output;
Column *Cd;
if (IsNPC (ch))
return;
output = new_buf ();
Cd = new_column ();
set_cols (Cd, ch, 3, COLS_BUF, output);
bprintlnf (output, "{c%s", draw_line (ch, NULL, 0));
print_cols (Cd, "{w%-18s CP ", "Group");
for (gn = 0; gn < top_group; gn++)
{
if (ch->gen_data->group_chosen[gn] && (val = group_rating (ch, gn)) > 0)
{
print_cols (Cd, "{c%-18s {W%-2d ", group_table[gn].name, val);
}
}
cols_nl (Cd);
bprintlnf (output, "{c%s", draw_line (ch, NULL, 0));
set_cols (Cd, ch, 2, COLS_BUF, output);
cols_header (Cd, "{w%-18s %-2s Lev", "Skill", "CP");
for (sn = 0; sn < top_skill; sn++)
{
if (ch->gen_data->skill_chosen[sn] && (val = skill_rating (ch, sn)) > 0)
{
print_cols (Cd, "{c%-18s {W%-2d %-3d ", skill_table[sn].name,
val, skill_level (ch, sn));
}
}
cols_nl (Cd);
bprintlnf (output, "{c%s", draw_line (ch, NULL, 0));
bprintlnf (output, "{cCreation points: {W%d{x",
ch->gen_data->points_chosen);
bprintlnf (output, "{cExperience per level: {W%d{x",
exp_per_level (ch, ch->gen_data->points_chosen));
sendpage (ch, buf_string (output));
free_buf (output);
free_column (Cd);
return;
}
int
exp_per_level (CharData * ch, int points)
{
int expl, inc;
if (IsNPC (ch))
return 1000;
expl = 1000;
inc = 500;
if (points >= mud_info.max_points)
{
points -= mud_info.max_points;
while (points >= 10)
{
expl += inc;
points -= 10;
if (points >= 10)
{
expl += inc;
inc *= 2;
points -= 10;
}
}
expl += points * inc / 10;
}
expl *= class_mult (ch);
expl /= 100;
return expl;
}
bool
parse_gen_groups (CharData * ch, const char *argument)
{
char arg[MAX_INPUT_LENGTH];
int gn, sn, i;
if (NullStr (argument))
return false;
argument = one_argument (argument, arg);
if (!str_prefix (arg, "help"))
{
if (NullStr (argument))
{
chprintln (ch, "{cThe following commands are available:{x");
chprintln (ch,
"{clist display all groups and skills not yet bought{x");
chprintln (ch,
"{clearned show all groups and skills bought {x");
chprintln (ch,
"{cpremise brief explanation of creation points and skill groups{x");
chprintln (ch, "{cadd <name> buy a skill or group{x");
chprintln (ch, "{cdrop <name> discard a skill or group{x");
chprintln (ch,
"{cinfo <name> list the skills or spells contained within a group{x");
chprintln (ch, "{clookup <name> show class levels for skill{x");
chprintln (ch,
"{chelp <name> help on skills and groups, or other help topics{x");
chprintln (ch,
"{cdone exit the character generation process{x");
return true;
}
chprint (ch, "{c");
do_function (ch, &do_oldhelp, argument);
chprint (ch, "{x");
return true;
}
if (!str_prefix (arg, "add"))
{
int val;
if (NullStr (argument))
{
chprintln (ch, "{cYou must provide a skill name.{x");
return true;
}
gn = group_lookup (argument);
if (gn != -1)
{
if (ch->gen_data->group_chosen[gn] || ch->pcdata->group_known[gn])
{
chprintln (ch, "{cYou already know that group!{x");
return true;
}
if ((val = group_rating (ch, gn)) < 1)
{
chprintln (ch, "{cThat group is not available.{x");
return true;
}
if (ch->gen_data->points_chosen + val > 300)
{
chprintln (ch,
"{cYou cannot take more than 300 creation points.{x");
return true;
}
chprintlnf (ch, "{W%s{c group added.{x",
Upper (group_table[gn].name));
ch->gen_data->group_chosen[gn] = true;
ch->gen_data->points_chosen += val;
gn_add (ch, gn);
ch->pcdata->points += val;
return true;
}
sn = skill_lookup (argument);
if (sn != -1)
{
if (ch->gen_data->skill_chosen[sn] || ch->pcdata->learned[sn] > 0)
{
chprintln (ch, "{cYou already know that skill!{x");
return true;
}
if ((val = skill_rating (ch, sn)) < 1 ||
skill_table[sn].spell_fun != spell_null)
{
chprintln (ch, "{cThat skill is not available.{x");
return true;
}
if (ch->gen_data->points_chosen + val > 300)
{
chprintln (ch,
"{cYou cannot take more than 300 creation points.{x");
return true;
}
chprintlnf (ch, "{W%s{c skill added.{x",
Upper (skill_table[sn].name));
ch->gen_data->skill_chosen[sn] = true;
ch->gen_data->points_chosen += val;
ch->pcdata->learned[sn] = 1;
ch->pcdata->points += val;
return true;
}
chprintln (ch, "{cNo skills or groups by that name...{x");
return true;
}
if (!str_cmp (arg, "drop"))
{
int val;
if (NullStr (argument))
{
chprintln (ch, "{cYou must provide a skill to drop.{x");
return true;
}
gn = group_lookup (argument);
if (gn != -1 && ch->gen_data->group_chosen[gn])
{
chprintlnf (ch, "{W%s{c group dropped.",
Upper (group_table[gn].name));
ch->gen_data->group_chosen[gn] = false;
val = group_rating (ch, gn);
ch->gen_data->points_chosen -= val;
gn_remove (ch, gn);
for (i = 0; i < top_group; i++)
{
if (ch->gen_data->group_chosen[gn])
gn_add (ch, gn);
}
ch->pcdata->points -= val;
return true;
}
sn = skill_lookup (argument);
if (sn != -1 && ch->gen_data->skill_chosen[sn])
{
chprintlnf (ch, "{W%s{c skill dropped.",
Upper (skill_table[sn].name));
ch->gen_data->skill_chosen[sn] = false;
val = skill_rating (ch, sn);
ch->gen_data->points_chosen -= val;
ch->pcdata->learned[sn] = 0;
ch->pcdata->points -= val;
return true;
}
chprintln (ch, "{cYou haven't bought any such skill or group.{x");
return true;
}
if (!str_prefix (arg, "premise"))
{
chprint (ch, "{c");
do_function (ch, &do_oldhelp, "premise");
chprint (ch, "{x");
return true;
}
if (!str_prefix (arg, "list"))
{
list_group_costs (ch);
return true;
}
if (!str_prefix (arg, "learned"))
{
list_group_chosen (ch);
return true;
}
if (!str_prefix (arg, "info"))
{
do_grlist ("info", ch, argument);
return true;
}
if (!str_prefix (arg, "lookup"))
{
do_slist ("lookup", ch, argument);
return true;
}
return false;
}
void
check_improve (CharData * ch, int sn, bool success, int multiplier)
{
int chance;
if (IsNPC (ch))
return;
if (!can_use_skpell (ch, sn)
|| skill_rating (ch, sn) < 1 ||
ch->pcdata->learned[sn] == 0 || ch->pcdata->learned[sn] == 100)
return;
chance = 10 * int_app[get_curr_stat (ch, STAT_INT)].learn;
chance /= (multiplier * skill_rating (ch, sn) * 4);
chance += ch->level;
if (number_range (1, 1000) > chance)
return;
if (success)
{
chance = Range (5, 100 - ch->pcdata->learned[sn], 95);
if (number_percent () < chance)
{
chprintlnf (ch, "You have become better at %s!",
skill_table[sn].name);
ch->pcdata->learned[sn]++;
gain_exp (ch, 2 * skill_rating (ch, sn));
}
}
else
{
chance = Range (5, ch->pcdata->learned[sn] / 2, 30);
if (number_percent () < chance)
{
chprintlnf (ch,
"You learn from your mistakes, and your %s skill improves.",
skill_table[sn].name);
ch->pcdata->learned[sn] += number_range (1, 3);
ch->pcdata->learned[sn] = Min (ch->pcdata->learned[sn], 100);
gain_exp (ch, 2 * skill_rating (ch, sn));
}
}
if (ch->pcdata->learned[sn] == 100)
{
chprintlnf (ch, "{GYou have now mastered the '%s' %s!",
skill_table[sn].name,
skill_table[sn].spell_fun ? "spell" : "skill");
}
}
Lookup_Fun (group_lookup)
{
int gn;
for (gn = 0; gn < top_group; gn++)
{
if (tolower (name[0]) == tolower (group_table[gn].name[0]) &&
!str_prefix (name, group_table[gn].name))
return gn;
}
return -1;
}
void
gn_add (CharData * ch, int gn)
{
int i;
if (IsNPC (ch) || gn >= top_group || gn < 0)
return;
ch->pcdata->group_known[gn] = true;
for (i = 0; i < MAX_IN_GROUP; i++)
{
if (group_table[gn].spells[i] == NULL)
break;
group_add (ch, group_table[gn].spells[i], false);
}
}
void
gn_remove (CharData * ch, int gn)
{
int i;
if (IsNPC (ch) || gn >= top_group || gn < 0)
return;
if (check_base_group (ch, gn))
return;
ch->pcdata->group_known[gn] = false;
for (i = 0; i < MAX_IN_GROUP; i++)
{
if (group_table[gn].spells[i] == NULL)
break;
group_remove (ch, group_table[gn].spells[i]);
}
}
void
group_add (CharData * ch, const char *name, bool deduct)
{
int sn, gn;
if (IsNPC (ch))
return;
sn = skill_lookup (name);
if (sn != -1)
{
if (ch->pcdata->learned[sn] == 0)
{
ch->pcdata->learned[sn] = 1;
if (deduct)
ch->pcdata->points += skill_rating (ch, sn);
}
return;
}
gn = group_lookup (name);
if (gn != -1)
{
if (ch->pcdata->group_known[gn] == false)
{
ch->pcdata->group_known[gn] = true;
if (deduct)
ch->pcdata->points += group_rating (ch, gn);
}
gn_add (ch, gn);
}
}
void
group_remove (CharData * ch, const char *name)
{
int sn, gn;
sn = skill_lookup (name);
if (sn != -1)
{
if (!is_base_skill (ch, sn))
ch->pcdata->learned[sn] = 0;
return;
}
gn = group_lookup (name);
if (gn != -1 && ch->pcdata->group_known[gn] == true)
{
ch->pcdata->group_known[gn] = false;
gn_remove (ch, gn);
}
}
Do_Fun (do_slist)
{
int sn, clas;
bool found = false;
if (NullStr (argument))
{
cmd_syntax (ch, NULL, n_fun, "<skill>", "<spell>", "<class>", NULL);
return;
}
else if ((clas = class_lookup (argument)) != -1)
{
char buf[MSL];
Buffer *buffer;
char skill_list[MAX_MORTAL_LEVEL + 1][5000];
int skill_columns[MAX_MORTAL_LEVEL + 1];
int level;
for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
{
skill_columns[level] = 0;
skill_list[level][0] = NUL;
}
for (sn = 0; sn < top_skill; sn++)
{
if ((level = skill_table[sn].skill_level[clas]) <= MAX_MORTAL_LEVEL)
{
found = true;
sprintf (buf, "{c%-18s ", skill_table[sn].name);
if (skill_list[level][0] == NUL)
sprintf (skill_list[level],
NEWLINE "{cLevel {W%3d{c: %s{x", level, buf);
else
{
if (++skill_columns[level] % 2 == 0)
strcat (skill_list[level], NEWLINE "{x ");
strcat (skill_list[level], buf);
}
}
}
buffer = new_buf ();
for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
{
if (skill_list[level][0] != NUL)
bprint (buffer, skill_list[level]);
}
bprintln (buffer, NULL);
sendpage (ch, buf_string (buffer));
free_buf (buffer);
return;
}
else if ((sn = skill_lookup (argument)) != -1)
{
int x;
chprintf (ch, NEWLINE "{c%s: [ ", capitalize (skill_table[sn].name));
for (x = 0; x < top_class; x++)
{
if (skill_table[sn].skill_level[x] > MAX_MORTAL_LEVEL)
chprintf (ch, "{W%.3s: %3s{c ", ClassName (ch, x), "n/a");
else
chprintf (ch, "{W%.3s: %03d{c ", ClassName (ch, x),
skill_table[sn].skill_level[x]);
}
chprintln (ch, "]{x");
return;
}
else
{
do_slist (n_fun, ch, "");
return;
}
}
int
spell_avail (CharData * ch, const char *name)
{
int sn;
sn = skill_lookup (name);
if (sn != -1 && skill_level (ch, sn) > MAX_MORTAL_LEVEL)
return -1;
return sn;
}
Do_Fun (do_grlist)
{
int gn, sn, tn;
bool found = false;
Column *Cd;
if (!ch || IsNPC (ch))
return;
Cd = new_column ();
set_cols (Cd, ch, 4, COLS_CHAR, ch);
if (NullStr (argument))
{
for (gn = 0; gn < top_group; gn++)
{
if (ch->pcdata->group_known[gn])
{
if (!found)
{
chprintln (ch, "{cGroups you currently have:");
chprintln (ch, draw_line (ch, NULL, 0));
}
print_cols (Cd, "{W%s", group_table[gn].name);
found = true;
}
}
if (!found)
chprintln (ch, "{cYou know no groups.{x");
else
cols_nl (Cd);
chprintlnf (ch, "{cCreation points: {W%d{x", ch->pcdata->points);
}
else if (!str_cmp (argument, "all"))
{
for (gn = 0; gn < top_group; gn++)
{
if (IsImmortal (ch) || group_rating (ch, gn) > 0)
{
if (!found)
{
chprintln (ch, "{cGroups available to you:");
chprintln (ch, draw_line (ch, NULL, 0));
}
print_cols (Cd, "{W%s", group_table[gn].name);
found = true;
}
}
if (!found)
chprintln (ch, "{cNo groups are available to you.{x");
else
cols_nl (Cd);
}
else if ((tn = class_lookup (argument)) != -1)
{
for (gn = 0; gn < top_group; gn++)
{
if (group_table[gn].rating[tn] <= 0)
continue;
if (!found)
{
chprintlnf (ch, "{cGroups available for the {W%s{c"
" class:", class_table[tn].name[0]);
chprintln (ch, draw_line (ch, NULL, 0));
}
print_cols (Cd, "{W%s", group_table[gn].name);
found = true;
}
if (!found)
chprintlnf (ch, "{cThere are no groups available to the {W%s{c"
" class.{x", class_table[tn].name[0]);
else
cols_nl (Cd);
}
else if ((gn = group_lookup (argument)) != -1)
{
for (sn = 0; sn < MAX_IN_GROUP; sn++)
{
if (group_table[gn].spells[sn] == NULL)
break;
if ((tn = spell_avail (ch, group_table[gn].spells[sn])) >= 0)
{
if (!found)
{
chprintlnf (ch, "{cSpells available in {W%s{c:{x",
group_table[gn].name);
cols_header (Cd, "{cLevel {WSpell{x");
chprintlnf (ch, "{c%s{x", draw_line (ch, NULL, 0));
}
print_cols (Cd, "{c%-5d {W%s{x", skill_level (ch, tn),
group_table[gn].spells[sn]);
found = true;
}
}
if (!found)
chprintlnf (ch, "{cNo spells available in the {W%s{c group.{x",
group_table[gn].name);
else
cols_nl (Cd);
}
else if ((sn = skill_lookup (argument)) != -1)
{
for (gn = 0; gn < top_group; gn++)
{
for (tn = 0; tn < MAX_IN_GROUP; tn++)
{
if (group_table[gn].spells[tn] == NULL)
break;
if (skill_lookup (group_table[gn].spells[tn]) != sn)
continue;
if (!found)
{
chprintlnf (ch, "{W%s{c is in the following groups:{x",
skill_table[sn].name);
chprintlnf (ch, "{c%s{x", draw_line (ch, NULL, 0));
}
print_cols (Cd, "{W%s", group_table[gn].name);
found = true;
}
}
if (!found)
chprintlnf (ch, "{W%s{c can't be found in any groups.{x",
skill_table[sn].name);
else
cols_nl (Cd);
}
else
{
cmd_syntax (ch, NULL, n_fun,
" -list your current groups",
"all -list all available groups",
"<group> -list all spells in a group",
"<skill> -list all groups a skill is in",
"<class> -list all groups available to a class", NULL);
}
free_column (Cd);
}