/************************************************************************** * 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); }