
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5429 54d463be-8e91-2dee-dedb-b68131a5f0ec
534 lines
14 KiB
Plaintext
534 lines
14 KiB
Plaintext
//===== eAthena Script =======================================
|
|
//= Kafra Express - Job Changing Module
|
|
//===== By: ==================================================
|
|
//= Skotlex
|
|
//===== Current Version: =====================================
|
|
//= 3.5
|
|
//===== Compatible With: =====================================
|
|
//= eAthena SVN R3579+
|
|
//===== Description: =========================================
|
|
//= Part of the Kafra Express Script Package.
|
|
//= Enables job changing through the class trees.
|
|
//= Novice -> 1st Class, 1st Class -> 2nd Class, rebirths, etc
|
|
//===== Additional Comments: =================================
|
|
//= See config.txt for configuration.
|
|
//= When using Upper Job policy, previous jobs are stored in
|
|
//= the server wide variables kej_class1 and kej_class2
|
|
//============================================================
|
|
|
|
- script keInit_jobchange {
|
|
OnInit: //Load Config
|
|
donpcevent "keConfig::OnLoadJobChange";
|
|
end;
|
|
}
|
|
|
|
function script F_keJobChange {
|
|
|
|
function SF_to1stJob;
|
|
function SF_to2ndJob;
|
|
function SF_getJobNames;
|
|
function SF_testChangeJob;
|
|
function SF_changeJob;
|
|
|
|
set @job, callfunc("GF_getJobLevel", class);
|
|
set @upper, Upper; //Because it is changed when rebirthing
|
|
set @reset, 0; //Base Level is reset only on rebirths
|
|
switch (@job) {
|
|
case 0: //Novices
|
|
if ($@kejc_skipNovice)
|
|
set @jobLv, 0; //jobLv is used again when checking for S.Novice's base level restriction.
|
|
else
|
|
set @jobLv, 10;
|
|
if (SF_testChangeJob(0,0,@jobLv))
|
|
SF_to1stJob(0);
|
|
break;
|
|
case 1: //First Classes
|
|
if (SF_testChangeJob($@kejc_cost2ND,$@kejc_base2ND,$@kejc_job2ND))
|
|
SF_to2ndJob();
|
|
break;
|
|
case 2: //Second Classes
|
|
if (Upper == 0 && BaseClass != Job_Taekwon) {
|
|
if (SF_testChangeJob($@kejc_costRebirth,$@kejc_baseRebirth,$@kejc_jobRebirth)) {
|
|
set @upper, 1;
|
|
if ($@kejc_skipNovice)
|
|
SF_to1stJob(1);
|
|
else
|
|
SF_changeJob @job,Upper,Job_Novice,1,0,0,$@kejc_costRebirth,1,$@kejc_rebirthReset;
|
|
}
|
|
break;
|
|
}
|
|
default: //Dead End
|
|
callfunc "F_keIntro", e_swt2, "I cannot change you from your current job.";
|
|
break;
|
|
}
|
|
return;
|
|
|
|
//Handles changing to 1st job.
|
|
function SF_to1stJob {
|
|
do {
|
|
set @submenu, 1;
|
|
if (@upper == 1 && $@kejc_upperPolicy && kej_class1) {
|
|
switch (kej_class1) {
|
|
case Job_Acolyte:
|
|
set @submenu, 2;
|
|
break;
|
|
case Job_Archer:
|
|
set @submenu, 3;
|
|
break;
|
|
case Job_Mage:
|
|
set @submenu, 4;
|
|
break;
|
|
case Job_Merchant:
|
|
set @submenu, 5;
|
|
break;
|
|
case Job_Swordman:
|
|
set @submenu, 6;
|
|
break;
|
|
case Job_Thief:
|
|
set @submenu, 7;
|
|
break;
|
|
case Job_Taekwon:
|
|
set @submenu, 8;
|
|
break;
|
|
}
|
|
}
|
|
if (@submenu == 1) {
|
|
SF_getJobNames 8,Job_Acolyte,Job_Archer,Job_Mage,Job_Merchant,Job_Swordman,Job_Thief,Job_Taekwon,Job_SuperNovice;
|
|
switch (@upper) {
|
|
case 0: //All
|
|
set @submenu, select(
|
|
"- Cancel job change",
|
|
"- "+@name1$,
|
|
"- "+@name2$,
|
|
"- "+@name3$,
|
|
"- "+@name4$,
|
|
"- "+@name5$,
|
|
"- "+@name6$,
|
|
"- "+@name7$,
|
|
"- "+@name8$
|
|
);
|
|
break;
|
|
case 1: //No Taekwon/S.Novice
|
|
set @submenu, select(
|
|
"- Cancel job change",
|
|
"- "+@name1$,
|
|
"- "+@name2$,
|
|
"- "+@name3$,
|
|
"- "+@name4$,
|
|
"- "+@name5$,
|
|
"- "+@name6$
|
|
);
|
|
break;
|
|
case 2: //No Taekwon
|
|
set @submenu, select(
|
|
"- Cancel job change",
|
|
"- "+@name1$,
|
|
"- "+@name2$,
|
|
"- "+@name3$,
|
|
"- "+@name4$,
|
|
"- "+@name5$,
|
|
"- "+@name6$,
|
|
"- "+@name8$
|
|
);
|
|
if (@submenu == 8)
|
|
set @submenu, 9;
|
|
break;
|
|
}
|
|
}
|
|
switch (@submenu) {
|
|
case 2: //Acolyte
|
|
set @newJob,Job_Acolyte;
|
|
set @weapon, $@kejc_wAcolyte;
|
|
break;
|
|
case 3: //Archer
|
|
set @newJob,Job_Archer;
|
|
set @weapon, $@kejc_wArcher;
|
|
break;
|
|
case 4: //Mage
|
|
set @newJob,Job_Mage;
|
|
set @weapon, $@kejc_wMage;
|
|
break;
|
|
case 5: //Merchant
|
|
set @newJob,Job_Merchant;
|
|
set @weapon, $@kejc_wMerchant;
|
|
break;
|
|
case 6: //Swordman
|
|
set @newJob,Job_Swordman;
|
|
set @weapon, $@kejc_wSwordman;
|
|
break;
|
|
case 7: //Thief
|
|
set @newJob,Job_Thief;
|
|
set @weapon, $@kejc_wThief;
|
|
break;
|
|
case 8: //Taekwon
|
|
set @newJob,Job_Taekwon;
|
|
set @weapon, $@kejc_wTaekwon;
|
|
break;
|
|
case 9: //S. Novice
|
|
set @newJob,Job_SuperNovice;
|
|
set @weapon, $@kejc_wSuperNovice;
|
|
if (SF_testChangeJob(0,$@kejc_baseSN,@jobLv) == 0)
|
|
return;
|
|
break;
|
|
}
|
|
if (@submenu > 1) {
|
|
if (getarg(0)) { //Skipping High Novice, charge rebirth costs.
|
|
if (SF_changeJob(@job,Upper,@newJob,1,@weapon,0,$@kejc_costRebirth,2,$@kejc_rebirthReset))
|
|
return;
|
|
} else {
|
|
if (SF_changeJob(@job,Upper,@newJob,@upper,@weapon,0,0,2,0))
|
|
return;
|
|
}
|
|
}
|
|
} while (@submenu > 1);
|
|
}
|
|
|
|
function SF_to2ndJob {
|
|
do {
|
|
set @submenu, 1;
|
|
if (@upper == 1 && $@kejc_upperPolicy && kej_class2) {
|
|
switch (kej_class2) {
|
|
case Job_Priest:
|
|
case Job_Hunter:
|
|
case Job_Wizard:
|
|
case Job_Blacksmith:
|
|
case Job_Knight:
|
|
case Job_Knight2:
|
|
case Job_Assassin:
|
|
case Job_Star_Gladiator:
|
|
case Job_Star_Gladiator2:
|
|
set @submenu, 2;
|
|
break;
|
|
case Job_Monk:
|
|
case Job_Bard:
|
|
case Job_Dancer:
|
|
case Job_Sage:
|
|
case Job_Alchem:
|
|
case Job_Crusader:
|
|
case Job_Crusader2:
|
|
case Job_Rogue:
|
|
case Job_Soul_Linker:
|
|
set @submenu, 3;
|
|
break;
|
|
}
|
|
}
|
|
if (@submenu == 1) { //Fetch from menu.
|
|
switch (BaseClass) {
|
|
case Job_Acolyte:
|
|
SF_getJobNames 2,Job_Priest,Job_Monk;
|
|
break;
|
|
case Job_Archer:
|
|
SF_getJobNames 3,Job_Hunter,Job_Bard,Job_Dancer;
|
|
if (sex == 0)
|
|
set @name2$, @name3$;
|
|
break;
|
|
case Job_Mage:
|
|
SF_getJobNames 2,Job_Wizard,Job_Sage;
|
|
break;
|
|
case Job_Merchant:
|
|
SF_getJobNames 2,Job_Blacksmith,Job_Alchem;
|
|
break;
|
|
case Job_Swordman:
|
|
SF_getJobNames 2,Job_Knight,Job_Crusader;
|
|
break;
|
|
case Job_Thief:
|
|
SF_getJobNames 2,Job_Assassin,Job_Rogue;
|
|
break;
|
|
case Job_Taekwon:
|
|
SF_getJobNames 2,Job_Star_Gladiator,Job_Soul_Linker;
|
|
break;
|
|
default:
|
|
callfunc "F_keIntro", e_swt2, "I don't know how to change you from your current job.";
|
|
return;
|
|
}
|
|
set @submenu, select(
|
|
"- Cancel job change",
|
|
"- "+@name1$,
|
|
"- "+@name2$
|
|
);
|
|
}
|
|
switch (BaseClass) {
|
|
case Job_Acolyte:
|
|
switch (@submenu) {
|
|
case 2: //Priest
|
|
set @newJob,Job_Priest;
|
|
set @weapon,$@kejc_wPriest;
|
|
set @weapon2,$@kejc_w2Priest;
|
|
break;
|
|
case 3: //Monk
|
|
set @newJob,Job_Monk;
|
|
set @weapon,$@kejc_wMonk;
|
|
set @weapon2,$@kejc_w2Monk;
|
|
break;
|
|
}
|
|
break;
|
|
case Job_Archer:
|
|
switch (@submenu) {
|
|
case 2: //Hunter
|
|
set @newJob,Job_Hunter;
|
|
set @weapon,$@kejc_wHunter;
|
|
set @weapon2,$@kejc_w2Hunter;
|
|
break;
|
|
case 3: //Bard/Dancer
|
|
if (sex == 1) { //Bard
|
|
set @newJob,Job_Bard;
|
|
set @weapon,$@kejc_wBard;
|
|
set @weapon2,$@kejc_w2Bard;
|
|
} else { //Dancer
|
|
set @newJob,Job_Dancer;
|
|
set @weapon,$@kejc_wDancer;
|
|
set @weapon2,$@kejc_w2Dancer;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case Job_Mage:
|
|
switch (@submenu) {
|
|
case 2: //Wizard
|
|
set @newJob,Job_Wizard;
|
|
set @weapon,$@kejc_wWizard;
|
|
set @weapon2,$@kejc_w2Wizard;
|
|
break;
|
|
case 3: //Sage
|
|
set @newJob,Job_Sage;
|
|
set @weapon,$@kejc_wSage;
|
|
set @weapon2,$@kejc_w2Sage;
|
|
break;
|
|
}
|
|
break;
|
|
case Job_Merchant:
|
|
switch (@submenu) {
|
|
case 2: //Blacksmith
|
|
set @newJob,Job_Blacksmith;
|
|
set @weapon,$@kejc_wBlacksmith;
|
|
set @weapon2,$@kejc_w2Blacksmith;
|
|
break;
|
|
case 3: //Alchemist
|
|
set @newJob,Job_Alchem;
|
|
set @weapon,$@kejc_wAlchemist;
|
|
set @weapon2,$@kejc_w2Alchemist;
|
|
break;
|
|
}
|
|
break;
|
|
case Job_Swordman:
|
|
switch (@submenu) {
|
|
case 2: //Knight
|
|
set @newJob,Job_Knight;
|
|
set @weapon,$@kejc_wKnight;
|
|
set @weapon2,$@kejc_w2Knight;
|
|
break;
|
|
case 3: //Crusader
|
|
set @newJob,Job_Crusader;
|
|
set @weapon,$@kejc_wCrusader;
|
|
set @weapon2,$@kejc_w2Crusader;
|
|
break;
|
|
default:
|
|
mes "uh oh";
|
|
break;
|
|
}
|
|
break;
|
|
case Job_Thief:
|
|
switch (@submenu) {
|
|
case 2: //Assassin
|
|
set @newJob,Job_Assassin;
|
|
set @weapon,$@kejc_wAssassin;
|
|
set @weapon2,$@kejc_w2Assassin;
|
|
break;
|
|
case 3: //Rogue
|
|
set @newJob,Job_Rogue;
|
|
set @weapon,$@kejc_wRogue;
|
|
set @weapon2,$@kejc_w2Rogue;
|
|
break;
|
|
}
|
|
break;
|
|
case Job_Taekwon:
|
|
switch (@submenu) {
|
|
case 2: //Star Gladiator
|
|
set @newJob,Job_Star_Gladiator;
|
|
set @weapon,$@kejc_wStarGladiator;
|
|
set @weapon2,$@kejc_w2StarGladiator;
|
|
break;
|
|
case 3: //Soul Linker
|
|
set @newJob,Job_Soul_Linker;
|
|
set @weapon,$@kejc_wSoulLinker;
|
|
set @weapon2,$@kejc_w2SoulLinker;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
if (@submenu > 1) {
|
|
if (SF_changeJob(@job,Upper,@newJob,@upper,@weapon,@weapon2,$@kejc_cost2ND,0,0))
|
|
return;
|
|
}
|
|
} while (@submenu > 1);
|
|
}
|
|
|
|
//SubFunction: SF_testChangeJob(Zeny, BaseLv, JobLv)
|
|
//Function that checks if the player qualifies for job changing.
|
|
function SF_testChangeJob {
|
|
set @fail, 0;
|
|
if (Zeny < getarg(0))
|
|
set @fail, 1;
|
|
if (BaseLevel < getarg(1))
|
|
set @fail, @fail+2;
|
|
if (JobLevel < getarg(2))
|
|
set @fail, @fail+4;
|
|
if (@fail > 0) {
|
|
if (@fail&1)
|
|
mes "You need "+getarg(0)+"z for the conversion process.";
|
|
if (@fail&2)
|
|
mes "You need to be at least Lv "+getarg(1)+".";
|
|
if (@fail&4)
|
|
mes "You need at least job Lv "+getarg(2)+".";
|
|
callfunc "F_keIntro", e_pif, "Sorry, you don't qualify for a job change yet.";
|
|
return 0;
|
|
}
|
|
|
|
if (SkillPoint > 0 && $@kejc_skillsPolicy == 0) {
|
|
callfunc "F_keIntro", e_dots, "Sorry, use your remaining Skill points before being able to change class.";
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//SubFunction: SF_changeJob (CurrentJobLv, CurrentJobType, NewJobBase, NewJobType
|
|
//Weapon, Weapon2, Zeny, WipeSkills, ResetLv)
|
|
//Attempts to change to the Jobgiven.
|
|
//CurrentJobLv is 0-3 (novice, 1st class, 2nd class, s.novice)
|
|
//Type is 0-2 (Normal, Advanced Class, Baby)
|
|
//Weapon is the ID of the weapon to grant
|
|
//Weapon2 is the alternative weapon granted when your job level is above $@kejc_wBonusLv
|
|
//Zeny is the money required (if negative, it is money awarded)
|
|
//WipeSkills if 1, indicates that skills should be wiped,
|
|
//if 2, it means basic skills have to be given back
|
|
//Reset Level indicates the base lv must be reset to 1.
|
|
//Note: Zeny/Base/Job requirements should had been checked with SF_testChangeJob already!
|
|
function SF_changeJob {
|
|
set @newjob,getarg(2);
|
|
set @newtype,getarg(3);
|
|
set @weapon,getarg(4);
|
|
set @weapon2,getarg(5);
|
|
set @cost,getarg(6);
|
|
set @wipeSkill,getarg(7);
|
|
set @resetLv,getarg(8);
|
|
|
|
set @jobStr$, callfunc("GF_getJobName2",@newjob, @newtype);
|
|
if (@wipeSkill == 0 && SkillPoint > 0 && $@kejc_skillsPolicy == 1) {
|
|
set @selection, select(
|
|
"- Do not change yet",
|
|
"- Change to "+@jobStr$+" (skill points lost)",
|
|
"- View details"
|
|
);
|
|
} else {
|
|
set @selection, select(
|
|
"- Cancel",
|
|
"- Change to "+@jobStr$,
|
|
"- View details"
|
|
);
|
|
}
|
|
switch (@selection) {
|
|
case 3: //Details
|
|
mes "Okay.. listen up:";
|
|
next;
|
|
mes "["+@name$+"]";
|
|
mes "Changing to "+@jobStr$+" now means:";
|
|
if (@wipeSkill == 0 && SkillPoint > 0 && $@kejc_skillsPolicy == 1)
|
|
mes "- You will lose your "+SkillPoint+" unused skill points.";
|
|
else if (@wipeSkill == 1)
|
|
mes "- You will lose all your skills.";
|
|
if (@resetLv)
|
|
mes "- Your base level will be reset to 1.";
|
|
if (@cost > 0)
|
|
mes "- You will be charged "+@cost+"z.";
|
|
else if (@cost < 0)
|
|
mes "- You will be aided with "+(0-@cost)+"z.";
|
|
if (@weapon > 0) {
|
|
if (@weapon2 > 0 && $@kejc_wBonusLv) {
|
|
if (JobLevel < $@kejc_wBonusLv) {
|
|
mes "- You will receive a "+getitemname(@weapon)+"["+getitemslots(@weapon)+"].";
|
|
mes "- If you wait until Job Lv"+$@kejc_wBonusLv+", you can receive instead a "+getitemname(@weapon2)+"["+getitemslots(@weapon)+"].";
|
|
} else {
|
|
mes "- You will receive a "+getitemname(@weapon2)+"["+getitemslots(@weapon)+"] for reaching Job Lv"+$@kejc_wBonusLv+".";
|
|
}
|
|
} else
|
|
mes "- You will receive a "+getitemname(@weapon)+".";
|
|
}
|
|
mes "So... will you change?";
|
|
if (select(
|
|
"- Cancel",
|
|
"- Change to "+@jobStr$
|
|
) != 2) {
|
|
callfunc "F_keIntro", e_dots, "...alright.";
|
|
return 0;
|
|
}
|
|
callfunc "F_keIntro", -1, "Enjoy your new Job.";
|
|
case 2: //Change
|
|
//Set/Unset job path variables as needed.
|
|
if($@kejc_upperPolicy) {
|
|
set @class,getarg(0);
|
|
set @type, getarg(1);
|
|
if(@class == 1 && @type == 0)
|
|
set kej_class1,class; //Advancing to second class, so...
|
|
if(@class == 2)
|
|
set kej_class2,class; //Only way of being here is by doing a rebirth
|
|
if(@type > 0)
|
|
set kej_class1,0; //Clear when one is a high class
|
|
if(@type > 0 && @class == 1)
|
|
set kej_class2,0; //Clear when leaving high 1st class
|
|
}
|
|
if (@resetLv) {
|
|
jobchange Job_Novice_High; //Done to give players those 100 points from High classes
|
|
resetlvl(1);
|
|
}
|
|
if (@wipeSkill) {
|
|
resetskill;
|
|
setoption(0);
|
|
set SkillPoint,0;
|
|
} else if ($@kejc_skillsPolicy == 1)
|
|
set SkillPoint,0;
|
|
if (@wipeSkill>1)
|
|
skill 1,9,0;
|
|
if($@kejc_resetDye)
|
|
setlook 7,0;
|
|
jobchange @newjob, @newtype;
|
|
if ($@kejc_announce)
|
|
announce strcharinfo(0)+" has been promoted to "+@jobStr$+"!",8;
|
|
set Zeny,Zeny-@cost;
|
|
if ($@kejc_weaponPolicy && @weapon > 0) {
|
|
if ($@kejc_wBonusLv && @weapon2 > 0) {
|
|
if (JobLevel < $@kejc_wBonusLv)
|
|
getitem @weapon,1;
|
|
else
|
|
getitem @weapon2,1;
|
|
} else
|
|
getitem @weapon,1;
|
|
}
|
|
emotion e_grat;
|
|
return 1;
|
|
default: //Cancel...
|
|
callfunc "F_keIntro", e_dots, "...alright.";
|
|
return 0;
|
|
}
|
|
}
|
|
//SubFunction: SF_getJobNames(Qty, Jobid1, Jobid2,...)
|
|
//Workaround until eA gets a fix for the bug where you can't use callfunc or
|
|
//callsub within a menu
|
|
function SF_getJobNames {
|
|
switch (getarg(0)) {
|
|
case 8:
|
|
set @name8$, callfunc("GF_getJobName2",getarg(8),@upper);
|
|
set @name7$, callfunc("GF_getJobName2",getarg(7),@upper);
|
|
set @name6$, callfunc("GF_getJobName2",getarg(6),@upper);
|
|
set @name5$, callfunc("GF_getJobName2",getarg(5),@upper);
|
|
set @name4$, callfunc("GF_getJobName2",getarg(4),@upper);
|
|
case 3:
|
|
set @name3$, callfunc("GF_getJobName2",getarg(3),@upper);
|
|
case 2:
|
|
set @name2$, callfunc("GF_getJobName2",getarg(2),@upper);
|
|
set @name1$, callfunc("GF_getJobName2",getarg(1),@upper);
|
|
}
|
|
return;
|
|
}
|
|
|
|
}
|