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