/*
************************************************************************
* File: class.c Part of CircleMUD *
* Usage: Source file for class-specific code *
* *
* All rights reserved. See license.doc for complete information. *
* *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
************************************************************************ */
/*
* This file attempts to concentrate most of the code which must be changed
* in order for new classes to be added. If you're adding a new class,
* you should go through this entire file from beginning to end and add
* the appropriate new special cases for your new class.
*/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "buffer.h"
#include "db.h"
#include "utils.h"
#include "spells.h"
#include "interpreter.h"
#include "comm.h"
extern long r_mortal_start_room[NUM_STARTROOMS + 1];
/* Names first */
const char *class_abbrevs[] =
{
"Mu",
"Cl",
"Th",
"Wa",
"Ar",
"\n"
};
const char *pc_class_types[] =
{
"Magic User",
"Cleric",
"Thief",
"Warrior",
"Artisan",
"\n"
};
/* The menu for choosing a class in interpreter.c: */
const char *class_menu =
"\r\n"
"&YSelect a class&n&R:&n\r\n"
" &c[&na&c]&n Cleric - religious and holy people who use defensive magic.\r\n"
" &c[&nb&c]&n Thief - stealthy and dexterous rogues, considered cunning.\r\n"
" &c[&nc&c]&n Warrior - strong and powerful fighters, weapon masters.\r\n"
" &c[&nd&c]&n Mage - wise and intelligent, and use offensive spells.\r\n"
" &c[&ne&c]&n Artisan - well adjusted, excellent item makers and traders.\r\n";
/*
* The code to interpret a class letter -- used in interpreter.c when a
* new character is selecting a class and by 'set class' in act.wizard.c.
*/
int
parse_class (char arg)
{
arg = LOWER (arg);
switch (arg)
{
case 'd':
return CLASS_MAGIC_USER;
break;
case 'a':
return CLASS_CLERIC;
break;
case 'c':
return CLASS_WARRIOR;
break;
case 'b':
return CLASS_THIEF;
break;
case 'e':
return CLASS_ARTISAN;
break;
default:
return CLASS_UNDEFINED;
break;
}
}
const char *town_menu =
"\r\n"
"&YSelect your home&n&R:&n\r\n"
" &c[&na&c]&n Bah - capitol of the Kingdom of Anacreon\r\n"
" &c[&nb&c]&n Bah - an Elven town of magic &r(&Rexpert&r)&n\r\n"
" &c[&nc&c]&n Bah - a human town of mystery &r(&Rexpert&r)&n\r\n";
int
parse_town (char arg)
{
arg = LOWER (arg);
switch (arg)
{
case 'a':
return 1;
break;
case 'b':
return 2;
break;
case 'c':
return 3;
break;
default:
return TOWN_UNDEFINED;
break;
}
}
/*
* bitvectors (i.e., powers of two) for each class, mainly for use in
* do_who and do_users. Add new classes at the end so that all classes
* use sequential powers of two (1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4,
* 1 << 5, etc.
*/
long
find_class_bitvector (char arg)
{
arg = LOWER (arg);
switch (arg)
{
case 'd':
return (1 << 0);
break;
case 'a':
return (1 << 1);
break;
case 'c':
return (1 << 2);
break;
case 'b':
return (1 << 3);
break;
case 'e':
return (1 << 4);
break;
default:
return 0;
break;
}
}
/*
* These are definitions which control the guildmasters for each class.
*
* The first field (top line) controls the highest percentage skill level
* a character of the class is allowed to attain in any skill. (After
* this level, attempts to practice will say "You are already learned in
* this area."
*
* The second line controls the maximum percent gain in learnedness a
* character is allowed per practice -- in other words, if the random
* die throw comes out higher than this number, the gain will only be
* this number instead.
*
* The third line controls the minimu percent gain in learnedness a
* character is allowed per practice -- in other words, if the random
* die throw comes out below this number, the gain will be set up to
* this number.
*
* The fourth line simply sets whether the character knows 'spells'
* or 'skills'. This does not affect anything except the message given
* to the character when trying to practice (i.e. "You know of the
* following spells" vs. "You know of the following skills"
*/
#define SPELL 0
#define SKILL 1
/* #define LEARNED_LEVEL 0 % known which is considered "learned" */
/* #define MAX_PER_PRAC 1 max percent gain in skill per practice */
/* #define MIN_PER_PRAC 2 min percent gain in skill per practice */
/* #define PRAC_TYPE 3 should it say 'spell' or 'skill'? */
int prac_params[4][NUM_CLASSES] =
{
/* MAG CLE THE WAR ART */
{95, 95, 85, 80, 90}, /* learned level */
{100, 100, 12, 12, 40}, /* max per prac */
{25, 25, 0, 0, 10}, /* min per pac */
{SPELL, SPELL, SKILL, SKILL, SKILL} /* prac name */
};
/*
* ...And the appropriate rooms for each guildmaster/guildguard; controls
* which types of people the various guildguards let through. i.e., the
* first line shows that from room 3017, only MAGIC_USERS are allowed
* to go south.
*/
int guild_info[][3] =
{
/* Midgaard */
{CLASS_MAGIC_USER, 3017, SCMD_SOUTH},
{CLASS_CLERIC, 3004, SCMD_NORTH},
{CLASS_THIEF, 3027, SCMD_EAST},
{CLASS_WARRIOR, 3021, SCMD_EAST},
/* Brass Dragon */
{-999 /* all */ , 5065, SCMD_WEST},
/* this must go last -- add new guards above! */
{-1, -1, -1}};
/* THAC0 for classes and levels. (To Hit Armor Class 0) */
/* Quick and dirty I'm afraid, would have taken hours to work out a
balanced Thac0 table for each class. Will write a formula later.
--Raf 18/1/98 */
/*
* Roll the 6 stats for a character... each stat is made of the sum of
* the best 3 out of 4 rolls of a 6-sided die. Each class then decides
* which priority will be given for the best to worst stats.
*/
int stat_table[9][12] = {
/* Str Int Wis Dex Con Cha */
/* Human */ {6, 16, 6, 16, 6, 16, 6, 16, 6, 16, 6, 16},
/* Elf */ {4, 15, 8, 17, 3, 16, 7, 19, 6, 14, 8, 15},
/* Gnome */ {6, 16, 7, 15, 5, 17, 5, 16, 8, 17, 5, 15},
/* Dwarf */ {9, 18, 4, 14, 4, 16, 4, 15, 12, 18, 3, 15},
/* Troll */ {12,19, 4, 15, 5, 15, 5, 16, 6, 18, 3, 15},
/* Goblin */ {7, 17, 7, 16, 5, 15, 6, 18, 8, 17, 3, 13},
/* Drow */ {4, 15, 8, 17, 3, 16, 7, 19, 6, 14, 8, 15},
/* Orc */ {7, 18, 5, 17, 3, 15, 4, 15, 13, 19, 4, 12},
/* Minotaur */ {8, 18, 5, 15, 6, 15, 6, 17, 8, 19, 3, 12}
};
void roll_real_abils (struct char_data *ch) {
int sa=0, ia=0, wa=0, da=0, ca=0;
ch->real_abils.str_add = 0;
switch (GET_CLASS (ch)) {
case CLASS_MAGIC_USER:
ia=number(2,3);
wa=number(2,3);
break;
case CLASS_CLERIC:
wa=number(2,3);
ca=number(2,3);
break;
case CLASS_THIEF:
da=number(2,3);
ia=number(2,3);
break;
case CLASS_WARRIOR:
sa=number(2,3);
ca=number(2,3);
break;
case CLASS_ARTISAN:
sa=number(2,3);
ia=number(2,3);
break;
}
ch->real_abils.str = MIN(number(GET_RACE_MIN(GET_RACE(ch), 1), GET_RACE_MAX(GET_RACE(ch), 1)) + sa, GET_RACE_MAX(GET_RACE(ch), 1));
ch->real_abils.intel = MIN(number(GET_RACE_MIN(GET_RACE(ch), 2), GET_RACE_MAX(GET_RACE(ch), 2)) + ia, GET_RACE_MAX(GET_RACE(ch), 2));
ch->real_abils.wis = MIN(number(GET_RACE_MIN(GET_RACE(ch), 3), GET_RACE_MAX(GET_RACE(ch), 3)) + wa, GET_RACE_MAX(GET_RACE(ch), 3));
ch->real_abils.dex = MIN(number(GET_RACE_MIN(GET_RACE(ch), 4), GET_RACE_MAX(GET_RACE(ch), 4)) + da, GET_RACE_MAX(GET_RACE(ch), 4));
ch->real_abils.con = MIN(number(GET_RACE_MIN(GET_RACE(ch), 5), GET_RACE_MAX(GET_RACE(ch), 5)) + ca, GET_RACE_MAX(GET_RACE(ch), 5));
ch->real_abils.cha = MIN(number(GET_RACE_MIN(GET_RACE(ch), 6), GET_RACE_MAX(GET_RACE(ch), 6)), GET_RACE_MAX(GET_RACE(ch), 6));
if (ch->real_abils.str == 18)
ch->real_abils.str_add = number (0, 100);
ch->aff_abils = ch->real_abils;
}
/* void roll_real_abils (struct char_data *ch)
{
int i, j, k, temp;
ubyte table[6];
ubyte rolls[4];
for (i = 0; i < 6; i++)
table[i] = 0;
for (i = 0; i < 6; i++)
{
for (j = 0; j < 4; j++)
rolls[j] = number (1, 6);
temp = rolls[0] + rolls[1] + rolls[2] + rolls[3] -
MIN (rolls[0], MIN (rolls[1], MIN (rolls[2], rolls[3])));
for (k = 0; k < 6; k++)
if (table[k] < temp)
{
temp ^= table[k];
table[k] ^= temp;
temp ^= table[k];
}
}
ch->real_abils.str_add = 0;
switch (GET_CLASS (ch))
{
case CLASS_MAGIC_USER:
ch->real_abils.intel = table[0];
ch->real_abils.wis = table[1];
ch->real_abils.dex = table[2];
ch->real_abils.str = table[3];
ch->real_abils.con = table[4];
ch->real_abils.cha = table[5];
break;
case CLASS_CLERIC:
ch->real_abils.wis = table[0];
ch->real_abils.intel = table[1];
ch->real_abils.str = table[2];
ch->real_abils.dex = table[3];
ch->real_abils.con = table[4];
ch->real_abils.cha = table[5];
break;
case CLASS_THIEF:
ch->real_abils.dex = table[0];
ch->real_abils.str = table[1];
ch->real_abils.con = table[2];
ch->real_abils.intel = table[3];
ch->real_abils.wis = table[4];
ch->real_abils.cha = table[5];
break;
case CLASS_WARRIOR:
ch->real_abils.str = table[0];
ch->real_abils.dex = table[1];
ch->real_abils.con = table[2];
ch->real_abils.wis = table[3];
ch->real_abils.intel = table[4];
ch->real_abils.cha = table[5];
if (ch->real_abils.str == 18)
ch->real_abils.str_add = number (0, 100);
break;
case CLASS_ARTISAN:
ch->real_abils.con = table[0];
ch->real_abils.wis = table[1];
ch->real_abils.intel = table[2];
ch->real_abils.cha = table[3];
ch->real_abils.str = table[4];
ch->real_abils.dex = table[5];
break;
}
ch->aff_abils = ch->real_abils;
switch (GET_RACE (ch))
{
case RACE_HUMAN:
break;
case RACE_ELF:
ch->real_abils.dex += 8;
ch->real_abils.intel += 8;
ch->real_abils.con -= 5;
ch->real_abils.str -= 10;
break;
case RACE_GNOME:
ch->real_abils.intel += 5;
ch->real_abils.wis -= 5;
break;
case RACE_DWARF:
ch->real_abils.con += 10;
ch->real_abils.intel -= 4;
ch->real_abils.cha -= 6;
break;
case RACE_TROLL:
ch->real_abils.str += 8;
ch->real_abils.intel -= 10;
ch->real_abils.dex -= 5;
break;
case RACE_GOBLIN:
ch->real_abils.str += 4;
ch->real_abils.dex += 4;
ch->real_abils.intel += 4;
ch->real_abils.wis -= 12;
break;
case RACE_MINOTAUR:
ch->real_abils.str += 5;
ch->real_abils.con += 5;
ch->real_abils.wis -= 8;
ch->real_abils.intel -= 8;
break;
case RACE_ORC:
ch->real_abils.str -= 2;
ch->real_abils.con += 2;
ch->real_abils.wis -= 5;
ch->real_abils.intel += 2;
break;
case RACE_DROW:
ch->real_abils.str += 1;
ch->real_abils.wis += 1;
ch->real_abils.intel += 1;
ch->real_abils.con += 2;
ch->real_abils.dex -= 8;
break;
default:
break;
}
}
*/
/* Some initializations for characters, including initial skills */
void
do_start (struct char_data *ch)
{
void advance_level (struct char_data *ch);
GET_LEVEL (ch) = 1;
GET_TRUST_LEVEL (ch) = 1;
GET_EXP (ch) = 1;
set_title (ch, NULL);
/* roll_real_abils(ch); *//* not needed anymore */
ch->points.max_hit = 10;
switch (GET_CLASS (ch))
{
case CLASS_MAGIC_USER:
break;
case CLASS_CLERIC:
break;
case CLASS_THIEF:
SET_SKILL (ch, SKILL_SNEAK, 10);
SET_SKILL (ch, SKILL_HIDE, 5);
SET_SKILL (ch, SKILL_STEAL, 15);
SET_SKILL (ch, SKILL_BACKSTAB, 10);
SET_SKILL (ch, SKILL_PICK_LOCK, 10);
SET_SKILL (ch, SKILL_TRACK, 10);
SET_SKILL (ch, SKILL_SCAN, 1);
break;
case CLASS_WARRIOR:
SET_SKILL (ch, SKILL_SCAN, 1);
break;
case CLASS_ARTISAN:
break;
}
advance_level (ch);
GET_HIT (ch) = GET_MAX_HIT (ch);
GET_MANA (ch) = GET_MAX_MANA (ch);
GET_MOVE (ch) = GET_MAX_MOVE (ch);
GET_COND (ch, THIRST) = 24;
GET_COND (ch, FULL) = 24;
GET_COND (ch, DRUNK) = 0;
ch->player.time.played = 0;
ch->player.time.logon = time (0);
}
/*
* This function controls the change to maxmove, maxmana, and maxhp for
* each class every time they gain a level.
*/
void
advance_level (struct char_data *ch)
{
int add_hp = 0, add_mana = 0, add_move = 0, add_practices = 0, i;
extern struct wis_app_type wis_app[];
extern struct con_app_type con_app[];
extern int training_pts[LVL_IMMORT];
add_hp = con_app[GET_CON (ch)].hitp;
switch (GET_CLASS (ch))
{
case CLASS_MAGIC_USER:
add_hp += number (3, 8);
add_mana = number (GET_LEVEL (ch), (int) (1.5 * GET_LEVEL (ch)));
add_mana = MIN (add_mana, 10);
add_move = number (0, 2);
break;
case CLASS_CLERIC:
add_hp += number (5, 10);
add_mana = number (GET_LEVEL (ch), (int) (1.5 * GET_LEVEL (ch)));
add_mana = MIN (add_mana, 10);
add_move = number (0, 2);
break;
case CLASS_THIEF:
add_hp += number (7, 13);
add_mana = 0;
add_move = number (1, 3);
break;
case CLASS_ARTISAN:
add_hp += number (8, 14);
add_mana = number (GET_LEVEL (ch), (int) (1.5 * GET_LEVEL (ch)));
add_mana = MIN (add_mana, 10);
add_move = number (3, 6);
break;
case CLASS_WARRIOR:
add_hp += number (10, 15);
add_mana = 0;
add_move = number (1, 3);
break;
}
ch->points.max_hit += MAX (1, add_hp);
ch->points.max_move += MAX (1, add_move);
if (GET_LEVEL (ch) > 1)
ch->points.max_mana += add_mana;
if (GET_CLASS (ch) == CLASS_MAGIC_USER || GET_CLASS (ch) == CLASS_CLERIC)
add_practices = MAX (2, wis_app[GET_WIS (ch)].bonus);
else
add_practices = MIN (2, MAX (1, wis_app[GET_WIS (ch)].bonus));
GET_PRACTICES (ch) += add_practices;
if (GET_LEVEL (ch) >= LVL_IMMORT)
{
for (i = 0; i < 3; i++)
GET_COND (ch, i) = (char) -100;
SET_BIT (PRF_FLAGS (ch), PRF_HOLYLIGHT);
}
if (GET_LEVEL (ch) > 1)
{
ch->player_specials->saved.newbie = 0;
}
GET_TRUST_LEVEL(ch) = GET_LEVEL(ch);
GET_TRAINING(ch) += training_pts[(int)GET_LEVEL(ch)];
sprintf(buf, "You've gained %d hp, %d mp, %d mv, %d practices, "
"and %d training sessions.\r\n",
MAX (1, add_hp), add_mana, MAX (1, add_move),
add_practices, training_pts[(int)GET_LEVEL(ch)]);
send_to_char(buf, ch);
save_char (ch, NOWHERE);
sprintf (buf, "%s advanced to level %d", GET_NAME (ch), GET_LEVEL (ch));
mudlog (buf, BRF, MAX (LVL_IMMORT, GET_INVIS_LEV (ch)), TRUE);
}
/*
* This simply calculates the backstab multiplier based on a character's
* level. This used to be an array, but was changed to be a function so
* that it would be easier to add more levels to your MUD. This doesn't
* really create a big performance hit because it's not used very often.
*/
int
backstab_mult (int level)
{
if (level <= 0)
return 1; /* level 0 */
else if (level <= 7)
return 2; /* level 1 - 7 */
else if (level <= 13)
return 3; /* level 8 - 13 */
else if (level <= 20)
return 4; /* level 14 - 20 */
else if (level <= 28)
return 5; /* level 21 - 28 */
else if (level <= 36)
return 6;
else if (level <= 44)
return 7;
else if (level <= 52)
return 8;
else if (level <= 60)
return 9;
else if (level <= 68)
return 10;
else if (level <= 76)
return 11;
else if (level <= 84)
return 12;
else if (level < LVL_IMMORT)
return 13; /* all remaining mortal levels */
else
return 20; /* immortals */
}
/*
* invalid_class is used by handler.c to determine if a piece of equipment is
* usable by a particular class, based on the ITEM_ANTI_{class} bitvectors.
*/
int
invalid_class (struct char_data *ch, struct obj_data *obj)
{
if ((IS_OBJ_STAT (obj, ITEM_ANTI_MAGIC_USER) && IS_MAGIC_USER (ch)) ||
(IS_OBJ_STAT (obj, ITEM_ANTI_CLERIC) && IS_CLERIC (ch)) ||
(IS_OBJ_STAT (obj, ITEM_ANTI_WARRIOR) && IS_WARRIOR (ch)) ||
(IS_OBJ_STAT (obj, ITEM_ANTI_THIEF) && IS_THIEF (ch)) ||
(IS_OBJ_STAT (obj, ITEM_ANTI_ARTISAN) && IS_ARTISAN (ch))
return 1;
else
return 0;
}
/*
* SPELLS AND SKILLS. This area defines which spells are assigned to
* which classes, and the minimum level the character must be to use
* the spell or skill.
*/
void
init_spell_levels (void)
{
/* MAGES */
spell_level (SKILL_MOUNT, CLASS_MAGIC_USER, 2);
spell_level (SKILL_RIDING, CLASS_MAGIC_USER, 3);
spell_level (SPELL_DETECT_INVIS, CLASS_MAGIC_USER, 4);
spell_level (SPELL_DETECT_MAGIC, CLASS_MAGIC_USER, 5);
spell_level (SPELL_INFRAVISION, CLASS_MAGIC_USER, 8);
spell_level (SPELL_INVISIBLE, CLASS_MAGIC_USER, 9);
spell_level (SPELL_ARMOR, CLASS_MAGIC_USER, 10);
spell_level (SPELL_LOCATE_OBJECT, CLASS_MAGIC_USER, 13);
spell_level (SPELL_STRENGTH, CLASS_MAGIC_USER, 15);
spell_level (SKILL_MEDITATE, CLASS_MAGIC_USER, 17);
spell_level (SPELL_SLEEP, CLASS_MAGIC_USER, 19);
spell_level (SKILL_TAME, CLASS_MAGIC_USER, 21);
spell_level (SPELL_BLINDNESS, CLASS_MAGIC_USER, 23);
spell_level (SPELL_DETECT_POISON, CLASS_MAGIC_USER, 24);
spell_level (SPELL_CURSE, CLASS_MAGIC_USER, 27);
spell_level (SPELL_POISON, CLASS_MAGIC_USER, 29);
spell_level (SPELL_CHARM, CLASS_MAGIC_USER, 33);
spell_level (SPELL_SENSE_LIFE, CLASS_MAGIC_USER, 34);
spell_level (SPELL_ENCHANT_WEAPON, CLASS_MAGIC_USER, 35);
spell_level (SPELL_STONE_SKIN, CLASS_MAGIC_USER, 37);
spell_level (SPELL_FEAR, CLASS_MAGIC_USER, 29);
spell_level (SPELL_CLONE, CLASS_MAGIC_USER, 31);
spell_level (SPELL_RECHARGE, CLASS_MAGIC_USER, 33);
spell_level (SPELL_PORTAL, CLASS_MAGIC_USER, 35);
spell_level (SPELL_GROUP_STONE_SKIN, CLASS_MAGIC_USER, 40);
spell_level (SKILL_DODGE, CLASS_MAGIC_USER, 42);
spell_level (SPELL_AUTUS, CLASS_MAGIC_USER, 75);
spell_level (SPELL_CONVERGENCE, CLASS_MAGIC_USER, 80);
spell_level (SPELL_RESIST_PORTAL, CLASS_MAGIC_USER, 85);
spell_level (SPELL_HOME, CLASS_MAGIC_USER, 90);
spell_level (SPELL_WATERWALK, CLASS_MAGIC_USER, 95);
spell_level (SPELL_REDIRECT_CHARGE, CLASS_MAGIC_USER, 60);
/* CLERICS */
spell_level (SPELL_CURE_LIGHT, CLASS_CLERIC, 1);
spell_level (SPELL_ARMOR, CLASS_CLERIC, 3);
spell_level (SKILL_MOUNT, CLASS_CLERIC, 5);
spell_level (SKILL_RIDING, CLASS_CLERIC, 7);
spell_level (SPELL_CREATE_FOOD, CLASS_CLERIC, 9);
spell_level (SPELL_CREATE_WATER, CLASS_CLERIC, 11);
spell_level (SPELL_DETECT_POISON, CLASS_CLERIC, 13);
spell_level (SPELL_DETECT_ALIGN, CLASS_CLERIC, 15);
spell_level (SPELL_CURE_BLIND, CLASS_CLERIC, 17);
spell_level (SPELL_BLESS, CLASS_CLERIC, 19);
spell_level (SPELL_SENSE_LIFE, CLASS_CLERIC, 21);
spell_level (SPELL_DETECT_INVIS, CLASS_CLERIC, 23);
spell_level (SKILL_MEDITATE, CLASS_CLERIC, 25);
spell_level (SPELL_BLINDNESS, CLASS_CLERIC, 27);
spell_level (SPELL_INFRAVISION, CLASS_CLERIC, 29);
spell_level (SKILL_TAME, CLASS_CLERIC, 33);
spell_level (SPELL_POISON, CLASS_CLERIC, 35);
spell_level (SPELL_GROUP_ARMOR, CLASS_CLERIC, 37);
spell_level (SPELL_CURE_CRITIC, CLASS_CLERIC, 39);
spell_level (SPELL_SUMMON, CLASS_CLERIC, 41);
spell_level (SPELL_REMOVE_POISON, CLASS_CLERIC, 43);
spell_level (SPELL_WORD_OF_RECALL, CLASS_CLERIC, 45);
spell_level (SPELL_EARTHQUAKE, CLASS_CLERIC, 47);
spell_level (SPELL_SANCTUARY, CLASS_CLERIC, 53);
spell_level (SPELL_HEAL, CLASS_CLERIC, 57);
spell_level (SPELL_CONTROL_WEATHER, CLASS_CLERIC, 59);
spell_level (SPELL_GROUP_HEAL, CLASS_CLERIC, 63);
spell_level (SKILL_DODGE, CLASS_CLERIC, 65);
spell_level (SPELL_REMOVE_CURSE, CLASS_CLERIC, 67);
spell_level (SPELL_ANIMATE_DEAD, CLASS_CLERIC, 69);
spell_level (SPELL_STONE_SKIN, CLASS_CLERIC, 71);
spell_level (SPELL_GROUP_STONE_SKIN, CLASS_CLERIC, 73);
spell_level (SPELL_PORTAL, CLASS_CLERIC, 77);
spell_level (SPELL_RECHARGE, CLASS_CLERIC, 79);
spell_level (SPELL_LOCATE_TARGET, CLASS_CLERIC, 85);
spell_level (SPELL_REGEN_MANA, CLASS_CLERIC, 91);
spell_level (SPELL_WATERWALK, CLASS_CLERIC, 93);
spell_level (SPELL_WORD_OF_RETREAT, CLASS_CLERIC, 95);
/* THIEVES */
spell_level (SKILL_SNEAK, CLASS_THIEF, 1);
spell_level (SKILL_MOUNT, CLASS_THIEF, 3);
spell_level (SKILL_RIDING, CLASS_THIEF, 5);
spell_level (SKILL_PICK_LOCK, CLASS_THIEF, 7);
spell_level (SKILL_BACKSTAB, CLASS_THIEF, 9);
spell_level (SKILL_STEAL, CLASS_THIEF, 11);
spell_level (SKILL_HIDE, CLASS_THIEF, 13);
spell_level (SKILL_TRACK, CLASS_THIEF, 15);
spell_level (SKILL_TAME, CLASS_THIEF, 17);
spell_level (SKILL_SECOND_ATTACK, CLASS_THIEF, 19);
spell_level (SKILL_LISTEN, CLASS_THIEF, 21);
spell_level (SKILL_FORAGE, CLASS_THIEF, 23);
spell_level (SKILL_SCAN, CLASS_THIEF, 25);
spell_level (SKILL_CAMOUFLAGE, CLASS_THIEF, 27);
spell_level (SKILL_BLANKET, CLASS_THIEF, 29);
spell_level (SKILL_CIRCLE, CLASS_THIEF, 31);
spell_level (SKILL_TRIP, CLASS_THIEF, 33);
spell_level (SKILL_DISARM, CLASS_THIEF, 35);
spell_level (SKILL_TARGET, CLASS_THIEF, 37);
spell_level (SKILL_AVOID, CLASS_THIEF, 39);
/* WARRIORS */
spell_level (SKILL_KICK, CLASS_WARRIOR, 1);
spell_level (SKILL_MOUNT, CLASS_WARRIOR, 3);
spell_level (SKILL_RIDING, CLASS_WARRIOR, 5);
spell_level (SKILL_RESCUE, CLASS_WARRIOR, 7);
spell_level (SKILL_TAME, CLASS_WARRIOR, 9);
spell_level (SKILL_TRACK, CLASS_WARRIOR, 11);
spell_level (SKILL_SECOND_ATTACK, CLASS_WARRIOR, 13);
spell_level (SKILL_BASH, CLASS_WARRIOR, 15);
spell_level (SKILL_FORAGE, CLASS_WARRIOR, 17);
spell_level (SKILL_SCAN, CLASS_WARRIOR, 19);
spell_level (SKILL_ADRENALINE, CLASS_WARRIOR, 20);
spell_level (SKILL_THIRD_ATTACK, CLASS_WARRIOR, 21);
spell_level (SKILL_RIPOSTE, CLASS_WARRIOR, 23);
spell_level (SKILL_SPEED, CLASS_WARRIOR, 25);
spell_level (SKILL_BERSERK, CLASS_WARRIOR, 27);
spell_level (SKILL_RAM_DOOR, CLASS_WARRIOR, 29);
spell_level (SKILL_PARRY, CLASS_WARRIOR, 31);
spell_level (SKILL_CHAIN_FOOTING, CLASS_WARRIOR, 50);
spell_level (SKILL_BLOODLUST, CLASS_WARRIOR, 60);
spell_level (SKILL_CARNALRAGE, CLASS_WARRIOR, 75);
/* ARTISAN */
spell_level(SKILL_MOUNT, CLASS_ARTISAN, 1);
spell_level(SKILL_RIDING, CLASS_ARTISAN, 3);
spell_level(SKILL_SCRIBE, CLASS_ARTISAN, 5);
spell_level(SKILL_TAME, CLASS_ARTISAN, 7);
spell_level(SKILL_BREW, CLASS_ARTISAN, 11);
spell_level(SKILL_REPAIR, CLASS_ARTISAN, 21);
spell_level(SKILL_TAN, CLASS_ARTISAN, 25);
spell_level(SKILL_FILLET, CLASS_ARTISAN, 31);
spell_level(SKILL_CARVE, CLASS_ARTISAN, 33);
spell_level(SKILL_FORGE, CLASS_ARTISAN, 35);
spell_level(SKILL_DODGE, CLASS_ARTISAN, 37);
}
int train_params[6][NUM_CLASSES] = {
/* MAG CLE THE WAR ART */
{ 14, 15, 16, MAX_PLAYER_STAT, 16 }, /* Strength */
{ 14, 15, 16, MAX_PLAYER_STAT, 17 }, /* Constitution */
{ MAX_PLAYER_STAT, MAX_PLAYER_STAT, 14, 15, 16 }, /* Wisdom */
{ MAX_PLAYER_STAT, 17, 17, 15, 16 }, /* Intelligence */
{ 16, 14, MAX_PLAYER_STAT, 17, 15 }, /* Dexterity */
{ 16, 17, MAX_PLAYER_STAT, 15, MAX_PLAYER_STAT } /* Charisma */
};