/**************************************************************
* FFTacticsMUD : jobs.cpp *
**************************************************************
* (c) 2002 Damien Dailidenas (Trenton). All rights reserved. *
**************************************************************/
#include "main.h"
#include <mysql/mysql.h>
#include <strstream>
const struct job_type job_table[] = {
{},
{ "Squire", "Basic Skill", 4.0, 3.0, 3.6, 3.2, 4.0, 4, 3, 5, 11, 15, 60, 50, 100 },
{ "Chemist", "Item", 3.2, 3.0, 3.0, 3.2, 4.0, 3, 3, 5, 12, 16, 75, 50, 100 },
{ "Knight", "Battle Skill", 4.8, 3.2, 4.8, 3.2, 4.0, 3, 3, 10, 10, 15, 40, 50, 100 },
{ "Archer", "Charge", 4.0, 2.6, 4.4, 3.2, 4.0, 3, 3, 10, 11, 16, 45, 50, 100 },
{ "Monk", "Punch Art", 5.4, 3.2, 5.1, 3.2, 4.4, 3, 4, 20, 9, 13, 48, 50, 100 },
{ "Priest", "White Magic", 3.2, 4.8, 3.6, 4.4, 4.4, 3, 3, 5, 10, 10, 50, 50, 100 },
{ "Wizard", "Black Magic", 3.0, 4.8, 2.4, 6.0, 4.0, 3, 3, 5, 12, 9, 60, 50, 100 },
{ "Time Mage", "Time Magic", 3.0, 4.8, 2.0, 5.2, 4.0, 3, 3, 5, 12, 10, 65, 50, 100 },
{ "Summoner", "Summon Magic", 2.8, 5.0, 2.0, 5.0, 3.6, 3, 3, 5, 13, 8, 70, 50, 100 },
{ "Thief", "Steal", 3.6, 2.0, 4.0, 2.4, 4.4, 4, 4, 25, 11, 16, 50, 50, 90 },
{ "Mediator", "Talk Skill", 3.2, 2.8, 3.0, 3.0, 4.0, 3, 3, 5, 11, 18, 55, 50, 100 },
{ "Oracle", "Yin-Yang Magic", 3.0, 4.4, 2.0, 4.8, 4.0, 3, 3, 5, 12, 10, 60, 50, 100 },
{ "Geomancer", "Elemental", 4.4, 3.8, 4.4, 4.2, 4.0, 4, 3, 10, 10, 11, 45, 50, 100 },
{ "Lancer", "Jump", 4.8, 2.0, 4.8, 2.0, 4.0, 4, 3, 15, 10, 15, 40, 50, 100 },
{ "Samurai", "Draw Out", 3.0, 3.0, 5.1, 3.6, 4.0, 3, 3, 20, 12, 14, 45, 50, 100 },
{ "Ninja", "Throw", 2.8, 2.0, 4.8, 3.0, 4.8, 4, 4, 30, 12, 13, 43, 50, 80 },
{ "Calculator", "Math Skill", 2.6, 3.2, 2.0, 2.8, 2.0, 3, 3, 5, 14, 10, 70, 50, 100 },
{ "Bard", "Sing", 2.2, 2.0, 1.2, 4.6, 4.0, 3, 3, 5, 20, 20, 80, 50, 100 },
{ "Dancer", "Dance", 2.4, 2.0, 4.4, 3.8, 4.0, 3, 3, 5, 20, 20, 50, 50, 100 },
{ "Mime", "", 5.6, 2.0, 4.8, 4.6, 4.8, 4, 4, 5, 6, 30, 35, 40, 100 },
{ "Chocobo", "", 4.32, 4.00, 3.88, 3.76, 4.76, 6, 5, 15, 8, 30, 34, 6, 75, { do_chococure, do_chocoesuna, do_chocoattack }},
{ "Black Chocobo", "", 3.20, 6.00, 6.00, 4.20, 3.90, 6, 5, 25, 7, 30, 39, 7, 85, { do_chocoesuna, do_chocoattack, do_chocoball, do_chocometeor }},
{ "Red Chocobo", "", 3.64, 3.60, 5.20, 3.96, 5.44, 6, 5, 10, 4, 30, 39, 7, 85, { do_chococure, do_chocoattack, do_chocoball, do_chocometeor }},
{ "Goblin", "", 4.68, 1.60, 3.92, 3.40, 4.20, 3, 3, 18, 7, 30, 39, 7, 85, { do_tackle, do_eyegouge, do_goblinpunch }},
{ "Black Goblin", "", 3.44, 1.40, 4.12, 3.48, 4.56, 3, 3, 19, 6, 30, 39, 7, 85, { do_tackle, do_turnpunch, do_goblinpunch }},
{ "Gobbledeguck", "", 3.92, 3.00, 4.60, 3.68, 5.12, 3, 3, 20, 6, 30, 39, 7, 85, { do_tackle, do_eyegouge, do_goblinpunch, do_mutilate }},
{ "Bomb", "", 3.40, 0.80, 4.00, 3.72, 4.16, 3, 3, 10, 7, 30, 39, 7, 90, { do_bite, do_selfdestruct, do_smallbomb }},
{ "Grenade", "", 3.48, 1.20, 3.40, 3.76, 4.60, 3, 3, 11, 7, 30, 39, 7, 90, { do_bite, do_smallbomb, do_selfdestruct }},
{ "Explosive", "", 4.96, 1.60, 4.64, 3.84, 4.00, 3, 3, 12, 7, 30, 39, 7, 90, { do_bite, do_selfdestruct, do_spark, do_smallbomb }},
{ "Red Panther", "", 4.64, 2.00, 3.92, 3.64, 4.64, 4, 4, 23, 6, 30, 39, 7, 85, { do_catkick, do_poisonnail, do_scratch }},
{ "Cuar", "", 3.64, 2.40, 4.64, 4.20, 5.16, 4, 4, 26, 6, 30, 39, 7, 85, { do_scratch, do_catkick, do_poisonnail, do_blaster }},
{ "Vampire", "", 3.96, 2.80, 5.28, 3.40, 5.36, 4, 4, 24, 6, 30, 39, 7, 85, { do_scratch, do_catkick, do_blaster, do_bloodsuck }},
{ "Pisco Demon", "", 4.32, 4.80, 3.60, 3.84, 4.44, 3, 3, 8, 7, 30, 39, 7, 85, { do_tentacle, do_blackink }},
{ "Squidlarkin", "", 4.60, 4.60, 4.04, 3.84, 4.04, 3, 3, 9, 7, 30, 39, 7, 85, { do_tentacle, do_blackink, do_oddsoundwave, do_mindblast }},
{ "Mindflare", "", 3.68, 6.40, 5.08, 3.68, 4.48, 3, 3, 10, 7, 30, 39, 7, 85, { do_tentacle, do_blackink, do_mindblast, do_levelblast }},
{ "Skeleton", "", 4.60, 2.00, 4.32, 3.40, 4.80, 3, 4, 11, 5, 30, 39, 7, 85, { do_knifehand, do_thundersoul, do_aquasoul }},
{ "Bone Snatch", "", 3.60, 1.60, 4.92, 3.48, 4.24, 3, 4, 12, 5, 30, 39, 7, 85, { do_knifehand, do_aquasoul, do_icesoul }},
{ "Living Bone", "", 4.04, 1.20, 5.00, 3.52, 4.08, 3, 4, 13, 5, 30, 39, 7, 85, { do_knifehand, do_icesoul, do_windsoul }},
{ "Ghoul", "", 3.32, 4.96, 3.60, 4.20, 4.12, 4, 4, 26, 7, 30, 39, 7, 85, { do_throwspirit, do_sleeptouch, do_greasetouch }},
{ "Gust", "", 3.28, 3.84, 3.72, 4.24, 4.40, 4, 4, 27, 7, 30, 39, 7, 85, { do_throwspirit, do_greasetouch, do_draintouch }},
{ "Revenant", "", 3.72, 2.56, 3.88, 4.40, 4.84, 5, 4, 28, 7, 30, 39, 7, 85, { do_throwspirit, do_draintouch, do_zombietouch }},
{ "Floatiball", "", 3.20, 3.20, 3.60, 3.56, 4.16, 5, 5, 12, 6, 30, 40, 7, 85, { do_wingattack, do_lookoffright }},
{ "Ahriman", "", 3.00, 3.80, 5.60, 3.80, 3.80, 5, 5, 13, 6, 30, 40, 7, 85, { do_wingattack, do_lookofdevil, do_lookoffright, do_deathsentence }},
{ "Plague", "", 3.08, 5.60, 5.04, 4.80, 4.32, 5, 5, 11, 6, 30, 40, 7, 85, { do_wingattack, do_lookofdevil, do_deathsentence, do_circle }},
{ "Juravis", "", 3.60, 1.60, 4.20, 3.40, 4.52, 6, 6, 30, 7, 30, 39, 7, 85, { do_scratchup, do_featherbomb }},
{ "Steel Hawk", "", 3.40, 2.40, 4.32, 3.60, 5.24, 6, 6, 28, 7, 30, 39, 7, 85, { do_scratchup, do_shinelover, do_beak }},
{ "Cockatoris", "", 4.04, 0.40, 6.08, 4.00, 5.40, 6, 6, 33, 7, 30, 39, 7, 85, { do_scratchup, do_beak, do_featherbomb, do_beaking }},
{ "Uribo", "", 2.76, 0.04, 2.80, 4.40, 5.60, 3, 3, 42, 9, 30, 39, 7, 85, { do_straightdash, do_oink }},
{ "Porky", "", 3.32, 0.04, 3.20, 4.40, 5.56, 3, 3, 36, 9, 30, 39, 7, 85, { do_straightdash, do_pooh, do_nosebreath }},
{ "Wildbow", "", 3.08, 0.04, 6.40, 4.40, 5.52, 3, 3, 39, 9, 30, 39, 7, 85, { do_straightdash, do_nosebreath, do_pleaseeat }},
{ "Woodman", "", 6.00, 6.40, 4.08, 4.00, 3.96, 3, 3, 0, 7, 30, 39, 7, 90, { do_leafdance, do_protectspirit }},
{ "Trent", "", 5.20, 7.20, 3.56, 3.80, 3.84, 3, 3, 0, 7, 30, 39, 7, 90, { do_leafdance, do_spiritoflife, do_calmspirit }},
{ "Taiju", "", 7.00, 6.00, 3.88, 3.96, 3.76, 3, 3, 0, 7, 30, 39, 7, 90, { do_leafdance, do_protectspirit, do_calmspirit, do_magicspirit }},
{ "Bull Demon", "", 5.40, 0.20, 4.80, 4.00, 4.28, 3, 3, 11, 6, 30, 39, 7, 85, { do_shakeoff, do_gatherpower }},
{ "Minitaurus", "", 6.40, 0.32, 6.08, 4.00, 4.32, 4, 3, 15, 6, 30, 39, 7, 85, { do_shakeoff, do_wavearound, do_blowfire }},
{ "Sacred", "", 6.04, 0.40, 6.92, 4.00, 4.88, 3, 3, 12, 6, 30, 39, 7, 85, { do_shakeoff, do_mimictitan, do_gatherpower, do_blowfire }},
{ "Morbol", "", 7.00, 0.60, 4.20, 3.96, 3.88, 3, 3, 0, 8, 30, 38, 30, 90, { do_tentacle, do_lick, do_badbreath }},
{ "Ochu", "", 5.80, 0.60, 4.40, 4.40, 3.80, 3, 3, 0, 8, 30, 39, 27, 90, { do_tentacle, do_goo, do_lick }},
{ "Great Morbol", "", 7.24, 0.40, 3.92, 3.80, 3.72, 3, 3, 0, 8, 30, 39, 24, 88, { do_tentacle, do_badbreath, do_moldballvirus }},
{ "Behemoth", "", 5.60, 4.80, 5.36, 4.20, 4.68, 4, 3, 13, 5, 30, 36, 7, 85, { do_stabup, do_suddencry, do_gigaflare }},
{ "King Behemoth", "", 6.00, 5.60, 5.96, 4.00, 4.92, 4, 3, 13, 5, 30, 35, 7, 85, { do_stabup, do_suddencry, do_hurricane }},
{ "Dark Behemoth", "", 6.44, 6.40, 8.00, 3.80, 5.00, 4, 3, 18, 5, 30, 34, 6, 85, { do_stabup, do_suddencry, do_ulmaguest }},
{ "Dragon", "", 5.32, 3.00, 5.44, 4.00, 4.72, 5, 3, 5, 6, 30, 39, 7, 85, { do_dash, do_tailswing }},
{ "Blue Dragon", "", 5.40, 4.40, 5.20, 4.20, 4.96, 5, 3, 9, 6, 30, 39, 7, 85, { do_dash, do_icebreath, do_thunderbreath }},
{ "Red Dragon", "", 6.28, 4.60, 5.88, 4.00, 5.28, 5, 3, 8, 6, 30, 39, 6, 85, { do_dash, do_thunderbreath, do_firebreath }},
{ "Hyudra", "", 3.20, 2.00, 5.32, 4.00, 5.04, 4, 4, 0, 3, 30, 39, 34, 85, { do_tripleattack, do_triplebreath }},
{ "Hydra", "", 4.00, 6.40, 6.04, 4.00, 5.32, 4, 4, 0, 3, 30, 39, 31, 85, { do_tripleattack, do_tripleflame, do_triplethunder }},
{ "Tiamat", "", 4.48, 3.60, 7.00, 4.80, 5.48, 4, 4, 0, 3, 30, 39, 29, 85, { do_triplebreath, do_triplethunder, do_tripleflame, do_darkwhisper }},
{}
};
void CH::set_job(const short id) {
short level = lvl, x, locs[5];
OBJ *temp_objects[5];
for(x = 0; x < 5; ++x)
temp_objects[x] = NULL;
x = 0;
for(OBJ *obj = objects; obj; obj = obj->next) {
if(obj->equipped) {
temp_objects[x] = obj;
locs[x] = obj->loc;
remove(obj);
++x;
}
}
HP[1] = (short)(HPP * job_table[id].HPMult);
MP[1] = (short)(MPP * job_table[id].MPMult);
Sp = (short)(SpP * job_table[id].SpMult);
PA = (short)(PAP * job_table[id].PAMult);
MA = (short)(MAP * job_table[id].MAMult);
Mv = (short)(job_table[id].Mv);
Ju = (short)(job_table[id].Ju);
Ev = (short)(job_table[id].Ev);
cjob = id;
if(lvl > 1) {
lvl = 0;
while(level--)
level_up(true);
}
for(x = 0; temp_objects[x]; ++x)
if(can_equip(temp_objects[x], locs[x]))
equip(temp_objects[x], locs[x]);
restore();
return;
}
bool CH::can_be_job(const short id) {
switch(id) {
case JOB_SQUIRE:
case JOB_CHEMIST:
return true;
case JOB_KNIGHT:
case JOB_ARCHER:
if(job[JOB_SQUIRE].lvl >= 2)
return true;
break;
case JOB_MONK:
if(job[JOB_KNIGHT].lvl >= 2)
return true;
break;
case JOB_THIEF:
if(job[JOB_ARCHER].lvl >= 2)
return true;
break;
case JOB_GEOMANCER:
if(job[JOB_MONK].lvl >= 3)
return true;
break;
case JOB_LANCER:
if(job[JOB_THIEF].lvl >= 3)
return true;
break;
case JOB_DANCER:
if(sex && job[JOB_GEOMANCER].lvl >= 4 && job[JOB_LANCER].lvl >= 4)
return true;
break;
case JOB_PRIEST:
case JOB_WIZARD:
if(job[JOB_CHEMIST].lvl >= 2)
return true;
break;
case JOB_ORACLE:
if(job[JOB_PRIEST].lvl >= 2)
return true;
break;
case JOB_TIMEMAGE:
if(job[JOB_WIZARD].lvl >= 2)
return true;
break;
case JOB_MEDIATOR:
if(job[JOB_ORACLE].lvl >= 2)
return true;
break;
case JOB_SUMMONER:
if(job[JOB_TIMEMAGE].lvl >= 2)
return true;
break;
case JOB_BARD:
if(!sex && job[JOB_MEDIATOR].lvl >= 4 && job[JOB_SUMMONER].lvl >= 4)
return true;
break;
case JOB_SAMURAI:
if(job[JOB_KNIGHT].lvl >= 3 && job[JOB_MONK].lvl >= 4 && job[JOB_LANCER].lvl >= 2)
return true;
break;
case JOB_NINJA:
if(job[JOB_ARCHER].lvl >= 3 && job[JOB_THIEF].lvl >= 4 && job[JOB_GEOMANCER].lvl >= 2)
return true;
break;
case JOB_CALCULATOR:
if(job[JOB_PRIEST].lvl >= 4 && job[JOB_WIZARD].lvl >= 4 && job[JOB_TIMEMAGE].lvl >= 3 && job[JOB_ORACLE].lvl >= 3)
return true;
break;
case JOB_MIME:
if(job[JOB_SQUIRE].lvl >= 8 && job[JOB_CHEMIST].lvl >= 8 && job[JOB_GEOMANCER].lvl >= 4 && job[JOB_LANCER].lvl >= 4 && job[JOB_MEDIATOR].lvl >= 4 && job[JOB_SUMMONER].lvl >= 4)
return true;
break;
}
return false;
}
short get_job_id(const string argument) {
for(short x = 1; !job_table[x].skill[0]; ++x)
if(find(argument, job_table[x].name))
return x;
return 0;
}
void do_setjob(CH *ch, string argument="") {
short id = 0;
if(argument.empty() || !(id = get_job_id(argument)) || !ch->can_be_job(id)) {
ch->printf("Usage: set job [job]\n\r");
ch->printf("{3+--{0Job{3--------------------{0Lv.{3--{0Total{3--{0Next{3---{0Jp{3--+\n\r");
ch->printf("+------------------------------------------------+{0\n\r");
for(short x = 1; !job_table[x].skill[0]; ++x) {
if((ch->job[x].lvl || ch->can_be_job(x))) {
if(!ch->job[x].lvl)
ch->job[x].lvl = 1;
ch->printf(" %-20s %3d / %04d %04d %04d\n\r", job_table[x].name, ch->job[x].lvl, 250 * (ch->job[x].lvl - 1) + ch->job[x].exp, ch->job[x].lvl >= 8 ? 0000 : (ch->job[x].lvl) * 250, ch->job[x].JP);
}
}
return;
}
ch->printf("Job set to \"%s\".\n\r", job_table[id].name);
ch->set_job(id);
return;
}
void CH::load_jobs() {
MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;
mysql_init(&mysql);
if(!mysql_real_connect(&mysql, DB_LOC, DB_USER, DB_PASS, DB_NAME, 0, NULL, 0))
return;
ostrstream ost;
ost << "SELECT * FROM job_data WHERE player='" << name << "'" << ends;
mysql_query(&mysql, ost.str());
res = mysql_store_result(&mysql);
while((row = mysql_fetch_row(res))) {
short id = atoi(row[1]);
job[id].lvl = atoi(row[2]);
job[id].JP = atoi(row[3]);
job[id].exp = atoi(row[4]);
job[id].subjob = atoi(row[5]);
job[id].reaction = atoi(row[6]);
job[id].support = atoi(row[7]);
job[id].move = atoi(row[8]);
}
mysql_free_result(res);
mysql_close(&mysql);
return;
}