root/npc/custom/eAAC_Scripts/kafraExpress/ke_jobchange.txt

Revision 1, 11.2 kB (checked in by jinshiro, 17 years ago)
Line 
1//===== eAthena Script =======================================
2//= Kafra Express - Job Changing Module
3//===== By: ==================================================
4//= Skotlex
5//===== Current Version: =====================================
6//= 4.0
7//===== Compatible With: =====================================
8//= eAthena SVN R8840+
9//===== Description: =========================================
10//= Part of the Kafra Express Script Package.
11//= Enables job changing through the class trees.
12//= Novice -> 1st Class, 1st Class -> 2nd Class, rebirths, etc
13//===== Additional Comments: =================================
14//= See config.txt for configuration.
15//= When using Upper Job policy, previous jobs are stored in
16//= the permanent variables kej_class1 and kej_class2
17//============================================================
18
19-       script  keInit_jobchange        -1,{
20OnInit: //Load Config
21        donpcevent "keConfig::OnLoadJobChange";
22        end;
23}
24
25function        script  F_keJobChange   {
26       
27        function SF_to1stJob;
28        function SF_to2ndJob;
29        function SF_getJobIndex;
30        function SF_getJobNames;
31        function SF_testChangeJob;
32        function SF_changeJob;
33
34        set @job, eaClass(class);
35        set @type, @job&~EAJ_UPPERMASK; //Because it is changed when rebirthing
36        set @reset, 0;  //Base Level is reset only on rebirths
37        if ((@job&EAJ_BASEMASK) == EAJ_NOVICE)
38        {       //Novices
39                if (@job&EAJL_2) //S. Novices
40                        goto L_FAIL;
41                if ($@kejc_skipNovice)
42                        set @jobLv, 0; //jobLv is used again when checking for S.Novice's base level restriction.
43                else
44                        set @jobLv, 10;
45                if (SF_testChangeJob(0,0,@jobLv))
46                        SF_to1stJob(0);
47        } else
48        if(@job&EAJL_2){
49                //Second classes
50                if (@job&~EAJ_UPPERMASK) //rebirth/baby
51                        goto L_FAIL;
52                if (SF_testChangeJob($@kejc_costRebirth,$@kejc_baseRebirth,$@kejc_jobRebirth)) {
53                        set @type, EAJL_UPPER;
54                        if ($@kejc_skipNovice)
55                                SF_to1stJob(1);
56                        else
57                                SF_changeJob @job,EAJ_NOVICE_HIGH,0,0,$@kejc_costRebirth,1,$@kejc_rebirthReset;
58                }
59        } else {
60                //First classes
61                if (SF_testChangeJob($@kejc_cost2ND,$@kejc_base2ND,$@kejc_job2ND))
62                        SF_to2ndJob();
63        }
64        return;
65L_FAIL:
66        //Dead End
67        callfunc "F_keIntro", e_swt2, "I cannot change you from your current job.";
68        return;
69
70//Handles changing to 1st job.
71function SF_to1stJob {
72        setarray @classes[0],
73                EAJ_Acolyte|@type,
74                EAJ_Archer|@type,
75                EAJ_Mage|@type,
76                EAJ_Merchant|@type,
77                EAJ_Swordman|@type,
78                EAJ_Thief|@type,
79                EAJ_Taekwon|@type,
80                EAJ_Super_Novice|@type,
81                EAJ_GunSlinger|@type,
82                EAJ_Ninja|@type;
83
84        do {
85                set @newjob, -1;
86                if (@type == EAJL_UPPER && $@kejc_upperPolicy && kej_class1) {
87                        set @newjob, eaclass(kej_class1);
88                        set @newjob, (@newjob&EAJ_UPPERMASK)|@type;
89                        if (roclass(@newjob) == -1)
90                                set @newjob, -1;
91                        set @submenu, 1;
92                }
93                if (@newjob == -1) {
94                        SF_getJobNames getarraysize(@classes);
95                        if (@type&EAJL_UPPER || $@kejc_disable&1)
96                                set @names$[7], ""; //No S.Novice
97       
98                        if (@type&~EAJ_UPPERMASK)
99                        {       //No TK/NJ/GS for Baby/Advanced
100                                set @names$[6], "";
101                                set @names$[8], "";
102                                set @names$[9], "";
103                        } else {
104                                if ($@kejc_disable&2) //No TK
105                                        set @names$[6], "";
106                                if ($@kejc_disable&4) //No GS
107                                        set @names$[8], "";
108                                if ($@kejc_disable&8) //No NJ
109                                        set @names$[9], "";
110                        }
111
112                        set @submenu, select(
113                                "- Cancel job change",
114                                @names$[0], @names$[1], @names$[2],
115                                @names$[3], @names$[4], @names$[5],
116                                @names$[6], @names$[7], @names$[8],
117                                @names$[9]
118                                );
119
120                        if (@submenu > 1) {
121                                if (@submenu == 9 && //S. Novice's own change check.
122                                        SF_testChangeJob(0,$@kejc_baseSN,@jobLv) == 0)
123                                        return;
124                                set @newjob, @classes[@submenu-2];
125                        }
126                }
127
128                if (@newjob > -1) {
129                        set @i, SF_getJobIndex(@newjob);
130                        if (@i > -1)
131                                set @weapon, $@kejc_weapon1[@i];
132                        else
133                                set @weapon, 0;
134                        if (getarg(0)) { //Skipping High Novice, charge rebirth costs.
135                                if (SF_changeJob(@job,@newJob,@weapon,0,$@kejc_costRebirth,2,$@kejc_rebirthReset))
136                                        return;
137                        } else {
138                                if (SF_changeJob(@job,@newJob,@weapon,0,0,2,0))
139                                        return;
140                        }
141                }
142        } while (@submenu > 1);
143}
144
145function SF_to2ndJob {
146        do {
147                set @newjob, -1;       
148                if (@type == EAJL_UPPER && $@kejc_upperPolicy && kej_class2) {
149                        set @newjob, eaclass(kej_class2);
150                        set @newjob, (@newjob&EAJ_UPPERMASK)|@type;
151                        if (roclass(@newjob) == -1)
152                                set @newjob, -1; //Invalid class.
153                        else
154                        if ((@newjob&EAJ_BASEMASK) != (@job&EAJ_BASEMASK))
155                                set @newjob, -1; //Saved next job does not corresponds to current 1st!
156                }
157                if (@newjob == -1) { //Fetch from menu.
158                        setarray @classes[0],
159                        (@job&EAJ_UPPERMASK)|@type|EAJL_2_1,
160                        (@job&EAJ_UPPERMASK)|@type|EAJL_2_2;
161
162                        if (roclass(@classes[0]) == -1)
163                        {       //Can't upgrade?
164                                callfunc "F_keIntro", e_swt2, "I cant' change you from your current job.";
165                                return;
166                        }
167
168                        SF_getJobNames 2;
169                        set @submenu, select(
170                                "- Cancel job change",
171                                @names$[0],@names$[1]
172                        );
173                        if (@submenu > 1)
174                                set @newjob, @classes[@submenu-2];
175                }
176                if (@newjob > -1) {
177                        set @i, SF_getJobIndex(@newjob);
178                        if (@i > -1) {
179                                if (@newjob&EAJL_2_2) { //2-2 classes
180                                        set @weapon, $@kejc_weapon_22[@i];
181                                        set @weapon2,$@kejc_weapon2_22[@i];
182                                } else { //2-1 classes
183                                        set @weapon, $@kejc_weapon_21[@i];
184                                        set @weapon2,$@kejc_weapon2_21[@i];
185                                }
186                        } else {
187                                set @weapon, 0;
188                                set @weapon2, 0;
189                        }
190                        if (SF_changeJob(@job,@newJob,@weapon,@weapon2,$@kejc_cost2ND,0,0))
191                                return;
192                }
193        } while (@submenu > 1);
194}
195
196//SubFunction: SF_testChangeJob(Zeny, BaseLv, JobLv)
197//Function that checks if the player qualifies for job changing.
198function SF_testChangeJob {
199        set @fail, 0;
200        if (Zeny < getarg(0))
201                set @fail, 1;
202        if (BaseLevel < getarg(1))
203                set @fail, @fail|2;
204        if (JobLevel < getarg(2))
205                set @fail, @fail|4;     
206        if (@fail > 0) {
207                if (@fail&1)
208                        mes "You need "+getarg(0)+"z for the conversion process.";
209                if (@fail&2)
210                        mes "You need to be at least Lv "+getarg(1)+".";
211                if (@fail&4)
212                        mes "You need at least job Lv "+getarg(2)+".";
213                callfunc "F_keIntro", e_pif, "Sorry, you don't qualify for a job change yet.";
214                return 0;
215        }
216
217        if (SkillPoint > 0 && $@kejc_skillsPolicy == 0) {
218                callfunc "F_keIntro", e_dots, "Sorry, use your remaining Skill points before being able to change class.";
219                return 0;
220        }
221        return 1;
222}
223
224//SubFunction: SF_changeJob (CurrentJob, NewJob, Weapon, Weapon2,
225// Zeny, WipeSkills, ResetLv)
226//Attempts to change to the Jobgiven.
227//CurrentJob is actual job in eA format.
228//NewJob is job to change to in eA format.
229//Weapon is the ID of the weapon to grant
230//Weapon2 is the alternative weapon granted when your job level is above $@kejc_wBonusLv
231//Zeny is the money required (if negative, it is money awarded)
232//WipeSkills if 1, indicates that skills should be wiped,
233//if 2, it means basic skills have to be given back
234//Reset Level indicates the base lv must be reset to 1.
235//Note: Zeny/Base/Job requirements should had been checked with SF_testChangeJob already!
236function SF_changeJob {
237        set @job, getarg(0);
238        set @newjob,getarg(1);
239        set @weapon,getarg(2);
240        set @weapon2,getarg(3);
241        set @cost,getarg(4);
242        set @wipeSkill,getarg(5);
243        set @resetLv,getarg(6);
244
245        if (roclass(@newjob) == -1) { //Invalid job?
246                callfunc "F_keIntro", -1, "I can't change you to this job...";
247                return 0;
248        }
249
250        set @jobStr$, jobname(roclass(@newjob));
251        if (@wipeSkill == 0 && SkillPoint > 0 && $@kejc_skillsPolicy == 1) {
252                set @selection, select(
253                        "- Do not change yet.",
254                        "- Change to "+@jobStr$+" (skill points lost)",
255                        "- View details"
256                );
257        } else {
258                set @selection, select(
259                        "- Cancel",
260                        "- Change to "+@jobStr$,
261                        "- View details"
262                );
263        }
264        switch (@selection) {
265                case 3: //Details
266                        mes "Okay.. listen up:";
267                        next;
268                        mes "["+@name$+"]";
269                        mes "Changing to "+@jobStr$+" now means:";
270                        if (@wipeSkill == 0 && SkillPoint > 0 && $@kejc_skillsPolicy == 1)
271                                mes "- You will lose your "+SkillPoint+" unused skill points.";
272                        else if (@wipeSkill == 1)
273                                mes "- You will lose all your skills.";
274                        if (@resetLv)
275                                mes "- Your base level will be reset to 1.";
276                        if (@cost > 0)
277                                mes "- You will be charged "+@cost+"z.";
278                        else if (@cost < 0)
279                                mes "- You will be awarded with "+(0-@cost)+"z.";
280                        if (@weapon > 0) {
281                                if (@weapon2 > 0 && $@kejc_wBonusLv) {
282                                        if (JobLevel < $@kejc_wBonusLv) {
283                                                mes "- You will receive a "+getitemname(@weapon)+"["+getitemslots(@weapon)+"].";
284                                                mes "- If you wait until Job Lv"+$@kejc_wBonusLv+", you can receive instead a "+getitemname(@weapon2)+"["+getitemslots(@weapon2)+"].";
285                                        } else {
286                                                mes "- You will receive a "+getitemname(@weapon2)+"["+getitemslots(@weapon2)+"] for reaching Job Lv"+$@kejc_wBonusLv+".";
287                                        }
288                                } else
289                                        mes "- You will receive a "+getitemname(@weapon)+".";
290                        }
291                        mes "So... will you change?";
292                        if (select(
293                                "- Cancel",
294                                "- Change to "+@jobStr$
295                        ) != 2) {
296                                callfunc "F_keIntro", e_dots, "...alright.";
297                                return 0;
298                        }
299                        callfunc "F_keIntro", -1, "Enjoy your new Job.";
300                case 2: //Change
301                        //Set/Unset job path variables as needed.
302                        if($@kejc_upperPolicy) {
303                                if((@job&EAJ_BASEMASK) == @job && @job != EAJ_NOVICE)
304                                        set kej_class1,class; //Advancing to second class, so...
305                                if(@job&EAJL_2)
306                                        set kej_class2,class; //Only way of being here is by doing a rebirth
307                                if(@job&~EAJ_UPPERMASK) {
308                                        set kej_class1,0;       //Clear when one is a high class
309                                        if(@job&~EAJL_2 && @job&EAJ_BASEMASK != EAJ_NOVICE)
310                                                set kej_class2,0;       //Clear when leaving high 1st class
311                                }
312                        }
313                        if (@resetLv) {
314                                jobchange Job_Novice_High; //Done to give players those 100 points from High classes
315                                resetlvl(1);
316                        }
317                        if (@wipeSkill) {
318                                resetskill;
319                                setoption(0);
320                                set SkillPoint,0;
321                        } else if ($@kejc_skillsPolicy == 1)
322                                set SkillPoint,0;
323                        if (@wipeSkill>1)
324                                skill 1,9,0;
325                        if($@kejc_resetDye)
326                                setlook 7,0;
327                        if ($@kejc_weaponPolicy && @weapon > 0) {
328                                if ($@kejc_wBonusLv && @weapon2 > 0 && JobLevel >= $@kejc_wBonusLv)
329                                        getitem @weapon2,1;
330                                else
331                                        getitem @weapon,1;
332                        }
333                        jobchange roclass(@newjob);
334                        if ($@kejc_announce)
335                                announce strcharinfo(0)+" has been promoted to "+@jobStr$+"!",8;
336                        set Zeny,Zeny-@cost;
337                        emotion e_grat;
338                        return 1;
339                default: //Cancel...
340                        return 0;       
341        }
342}
343
344//SubFunction: SF_getJobIndex(Job)
345//Given a job in eA format, retrieves the basic index which is used for the
346//config arrays.
347function SF_getJobIndex {
348        set @i, getarg(0);
349        set @i, @i&EAJ_BASEMASK;
350        switch (@i) {
351                case EAJ_ACOLYTE:
352                        return 0;
353                case EAJ_ARCHER:
354                        return 1;
355                case EAJ_MAGE:
356                        return 2;
357                case EAJ_MERCHANT:
358                        return 3;
359                case EAJ_SWORDMAN:
360                        return 4;
361                case EAJ_THIEF:
362                        return 5;
363                case EAJ_TAEKWON:
364                        return 6;
365                case EAJ_NOVICE: //Super Novice, actually
366                        return 7;
367                case EAJ_GUNSLINGER:
368                        return 8;
369                case EAJ_NINJA:
370                        return 9;
371                default:
372                        return -1;
373        }
374}
375
376//SubFunction: SF_getJobNames(Qty)
377//Fills an array @names$ with the job names taken from the array "classes",
378// making each entry start with "- " followed by the job name.
379function SF_getJobNames {
380        set @size, getarg(0);
381        for (set @i, 0; @i < @size; set @i, @i+1)
382                setd "@names$["+@i+"]", "- "+jobname(roclass(@classes[@i]));
383}
384
385}
Note: See TracBrowser for help on using the browser.