
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11646 54d463be-8e91-2dee-dedb-b68131a5f0ec
386 lines
11 KiB
Plaintext
386 lines
11 KiB
Plaintext
//===== eAthena Script =======================================
|
|
//= Kafra Express - Job Changing Module
|
|
//===== By: ==================================================
|
|
//= Skotlex
|
|
//===== Current Version: =====================================
|
|
//= 4.0
|
|
//===== Compatible With: =====================================
|
|
//= eAthena SVN R8840+
|
|
//===== 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 permanent variables kej_class1 and kej_class2
|
|
//============================================================
|
|
|
|
- script keInit_jobchange -1,{
|
|
OnInit: //Load Config
|
|
donpcevent "keConfig::OnLoadJobChange";
|
|
end;
|
|
}
|
|
|
|
function script F_keJobChange {
|
|
|
|
function SF_to1stJob;
|
|
function SF_to2ndJob;
|
|
function SF_getJobIndex;
|
|
function SF_getJobNames;
|
|
function SF_testChangeJob;
|
|
function SF_changeJob;
|
|
|
|
set @job, eaClass(class);
|
|
set @type, @job&~EAJ_UPPERMASK; //Because it is changed when rebirthing
|
|
set @reset, 0; //Base Level is reset only on rebirths
|
|
if ((@job&EAJ_BASEMASK) == EAJ_NOVICE)
|
|
{ //Novices
|
|
if (@job&EAJL_2) //S. Novices
|
|
goto L_FAIL;
|
|
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);
|
|
} else
|
|
if(@job&EAJL_2){
|
|
//Second classes
|
|
if (@job&~EAJ_UPPERMASK) //rebirth/baby
|
|
goto L_FAIL;
|
|
if (SF_testChangeJob($@kejc_costRebirth,$@kejc_baseRebirth,$@kejc_jobRebirth)) {
|
|
set @type, EAJL_UPPER;
|
|
if ($@kejc_skipNovice)
|
|
SF_to1stJob(1);
|
|
else
|
|
SF_changeJob @job,EAJ_NOVICE_HIGH,0,0,$@kejc_costRebirth,1,$@kejc_rebirthReset;
|
|
}
|
|
} else {
|
|
//First classes
|
|
if (SF_testChangeJob($@kejc_cost2ND,$@kejc_base2ND,$@kejc_job2ND))
|
|
SF_to2ndJob();
|
|
}
|
|
return;
|
|
L_FAIL:
|
|
//Dead End
|
|
callfunc "F_keIntro", e_swt2, "I cannot change you from your current job.";
|
|
return;
|
|
|
|
//Handles changing to 1st job.
|
|
function SF_to1stJob {
|
|
setarray @classes[0],
|
|
EAJ_Acolyte|@type,
|
|
EAJ_Archer|@type,
|
|
EAJ_Mage|@type,
|
|
EAJ_Merchant|@type,
|
|
EAJ_Swordman|@type,
|
|
EAJ_Thief|@type,
|
|
EAJ_Taekwon|@type,
|
|
EAJ_Super_Novice|@type,
|
|
EAJ_GunSlinger|@type,
|
|
EAJ_Ninja|@type;
|
|
|
|
do {
|
|
set @newjob, -1;
|
|
if (@type == EAJL_UPPER && $@kejc_upperPolicy && kej_class1) {
|
|
set @newjob, eaclass(kej_class1);
|
|
set @newjob, (@newjob&EAJ_UPPERMASK)|@type;
|
|
if (roclass(@newjob) == -1)
|
|
set @newjob, -1;
|
|
set @submenu, 1;
|
|
}
|
|
if (@newjob == -1) {
|
|
SF_getJobNames getarraysize(@classes);
|
|
if (@type&EAJL_UPPER || $@kejc_disable&1)
|
|
set @names$[7], ""; //No S.Novice
|
|
|
|
if (@type&~EAJ_UPPERMASK)
|
|
{ //No TK/NJ/GS for Baby/Advanced
|
|
set @names$[6], "";
|
|
set @names$[8], "";
|
|
set @names$[9], "";
|
|
} else {
|
|
if ($@kejc_disable&2) //No TK
|
|
set @names$[6], "";
|
|
if ($@kejc_disable&4) //No GS
|
|
set @names$[8], "";
|
|
if ($@kejc_disable&8) //No NJ
|
|
set @names$[9], "";
|
|
}
|
|
|
|
set @submenu, select(
|
|
"- Cancel job change",
|
|
@names$[0], @names$[1], @names$[2],
|
|
@names$[3], @names$[4], @names$[5],
|
|
@names$[6], @names$[7], @names$[8],
|
|
@names$[9]
|
|
);
|
|
|
|
if (@submenu > 1) {
|
|
if (@submenu == 9 && //S. Novice's own change check.
|
|
SF_testChangeJob(0,$@kejc_baseSN,@jobLv) == 0)
|
|
return;
|
|
set @newjob, @classes[@submenu-2];
|
|
}
|
|
}
|
|
|
|
if (@newjob > -1) {
|
|
set @i, SF_getJobIndex(@newjob);
|
|
if (@i > -1)
|
|
set @weapon, $@kejc_weapon1[@i];
|
|
else
|
|
set @weapon, 0;
|
|
if (getarg(0)) { //Skipping High Novice, charge rebirth costs.
|
|
if (SF_changeJob(@job,@newJob,@weapon,0,$@kejc_costRebirth,2,$@kejc_rebirthReset))
|
|
return;
|
|
} else {
|
|
if (SF_changeJob(@job,@newJob,@weapon,0,0,2,0))
|
|
return;
|
|
}
|
|
}
|
|
} while (@submenu > 1);
|
|
}
|
|
|
|
function SF_to2ndJob {
|
|
do {
|
|
set @newjob, -1;
|
|
if (@type == EAJL_UPPER && $@kejc_upperPolicy && kej_class2) {
|
|
set @newjob, eaclass(kej_class2);
|
|
set @newjob, (@newjob&EAJ_UPPERMASK)|@type;
|
|
if (roclass(@newjob) == -1)
|
|
set @newjob, -1; //Invalid class.
|
|
else
|
|
if ((@newjob&EAJ_BASEMASK) != (@job&EAJ_BASEMASK))
|
|
set @newjob, -1; //Saved next job does not corresponds to current 1st!
|
|
}
|
|
if (@newjob == -1) { //Fetch from menu.
|
|
setarray @classes[0],
|
|
(@job&EAJ_UPPERMASK)|@type|EAJL_2_1,
|
|
(@job&EAJ_UPPERMASK)|@type|EAJL_2_2;
|
|
|
|
if (roclass(@classes[0]) == -1)
|
|
{ //Can't upgrade?
|
|
callfunc "F_keIntro", e_swt2, "I cant' change you from your current job.";
|
|
return;
|
|
}
|
|
|
|
SF_getJobNames 2;
|
|
set @submenu, select(
|
|
"- Cancel job change",
|
|
@names$[0],@names$[1]
|
|
);
|
|
if (@submenu > 1)
|
|
set @newjob, @classes[@submenu-2];
|
|
}
|
|
if (@newjob > -1) {
|
|
set @i, SF_getJobIndex(@newjob);
|
|
if (@i > -1) {
|
|
if (@newjob&EAJL_2_2) { //2-2 classes
|
|
set @weapon, $@kejc_weapon_22[@i];
|
|
set @weapon2,$@kejc_weapon2_22[@i];
|
|
} else { //2-1 classes
|
|
set @weapon, $@kejc_weapon_21[@i];
|
|
set @weapon2,$@kejc_weapon2_21[@i];
|
|
}
|
|
} else {
|
|
set @weapon, 0;
|
|
set @weapon2, 0;
|
|
}
|
|
if (SF_changeJob(@job,@newJob,@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 (CurrentJob, NewJob, Weapon, Weapon2,
|
|
// Zeny, WipeSkills, ResetLv)
|
|
//Attempts to change to the Jobgiven.
|
|
//CurrentJob is actual job in eA format.
|
|
//NewJob is job to change to in eA format.
|
|
//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 @job, getarg(0);
|
|
set @newjob,getarg(1);
|
|
set @weapon,getarg(2);
|
|
set @weapon2,getarg(3);
|
|
set @cost,getarg(4);
|
|
set @wipeSkill,getarg(5);
|
|
set @resetLv,getarg(6);
|
|
|
|
if (roclass(@newjob) == -1) { //Invalid job?
|
|
callfunc "F_keIntro", -1, "I can't change you to this job...";
|
|
return 0;
|
|
}
|
|
|
|
set @jobStr$, jobname(roclass(@newjob));
|
|
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 awarded 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(@weapon2)+"].";
|
|
} else {
|
|
mes "- You will receive a "+getitemname(@weapon2)+"["+getitemslots(@weapon2)+"] 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) {
|
|
if((@job&EAJ_BASEMASK) == @job && @job != EAJ_NOVICE)
|
|
set kej_class1,class; //Advancing to second class, so...
|
|
if(@job&EAJL_2)
|
|
set kej_class2,class; //Only way of being here is by doing a rebirth
|
|
if(@job&~EAJ_UPPERMASK) {
|
|
set kej_class1,0; //Clear when one is a high class
|
|
if(@job&~EAJL_2 && @job&EAJ_BASEMASK != EAJ_NOVICE)
|
|
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;
|
|
if ($@kejc_weaponPolicy && @weapon > 0) {
|
|
if ($@kejc_wBonusLv && @weapon2 > 0 && JobLevel >= $@kejc_wBonusLv)
|
|
getitem @weapon2,1;
|
|
else
|
|
getitem @weapon,1;
|
|
}
|
|
jobchange roclass(@newjob);
|
|
if ($@kejc_announce)
|
|
announce strcharinfo(0)+" has been promoted to "+@jobStr$+"!",8;
|
|
set Zeny,Zeny-@cost;
|
|
emotion e_grat;
|
|
return 1;
|
|
default: //Cancel...
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//SubFunction: SF_getJobIndex(Job)
|
|
//Given a job in eA format, retrieves the basic index which is used for the
|
|
//config arrays.
|
|
function SF_getJobIndex {
|
|
set @i, getarg(0);
|
|
set @i, @i&EAJ_BASEMASK;
|
|
switch (@i) {
|
|
case EAJ_ACOLYTE:
|
|
return 0;
|
|
case EAJ_ARCHER:
|
|
return 1;
|
|
case EAJ_MAGE:
|
|
return 2;
|
|
case EAJ_MERCHANT:
|
|
return 3;
|
|
case EAJ_SWORDMAN:
|
|
return 4;
|
|
case EAJ_THIEF:
|
|
return 5;
|
|
case EAJ_TAEKWON:
|
|
return 6;
|
|
case EAJ_NOVICE: //Super Novice, actually
|
|
return 7;
|
|
case EAJ_GUNSLINGER:
|
|
return 8;
|
|
case EAJ_NINJA:
|
|
return 9;
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
//SubFunction: SF_getJobNames(Qty)
|
|
//Fills an array @names$ with the job names taken from the array "classes",
|
|
// making each entry start with "- " followed by the job name.
|
|
function SF_getJobNames {
|
|
set @size, getarg(0);
|
|
for (set @i, 0; @i < @size; set @i, @i+1)
|
|
setd "@names$["+@i+"]", "- "+jobname(roclass(@classes[@i]));
|
|
}
|
|
|
|
}
|