root/src/map/pc.c @ 19

Revision 19, 217.1 kB (checked in by jinshiro, 17 years ago)

Now Compiles with Cygwin GCC

Line 
1// Copyright (c) Athena Dev Teams - Licensed under GNU GPL =D
2// For more information, see LICENCE in the main folder
3
4#include "../common/cbasetypes.h"
5#include "../common/core.h" // get_svn_revision()
6#include "../common/malloc.h"
7#include "../common/nullpo.h"
8#include "../common/showmsg.h"
9#include "../common/socket.h" // RFIFO*()
10#include "../common/strlib.h" // safestrncpy()
11#include "../common/timer.h"
12#include "../common/utils.h"
13
14#include "atcommand.h" // get_atcommand_level()
15#include "battle.h" // battle_config
16#include "chrif.h"
17#include "clif.h"
18#include "date.h" // is_day_of_*()
19#include "intif.h"
20#include "itemdb.h"
21#include "log.h"
22#include "mail.h"
23#include "map.h"
24#include "path.h"
25#include "mercenary.h" // merc_is_hom_active()
26#include "mob.h" // MAX_MOB_RACE_DB
27#include "npc.h" // fake_nd
28#include "pet.h" // pet_unlocktarget()
29#include "party.h" // party_search()
30#include "guild.h" // guild_search(), guild_request_info()
31#include "script.h" // script_config
32#include "skill.h"
33#include "status.h" // struct status_data
34#include "vending.h" // vending_closevending()
35#include "pc.h"
36#include "quest.h"
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <time.h>
42
43
44#define PVP_CALCRANK_INTERVAL 1000      // PVP‡ˆÊŒvŽZ‚ÌŠÔŠu
45static unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL];
46static unsigned int max_level[CLASS_COUNT][2];
47static short statp[MAX_LEVEL+1];
48
49// h-files are for declarations, not for implementations... [Shinomori]
50struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
51// timer for night.day implementation
52int day_timer_tid;
53int night_timer_tid;
54
55struct fame_list smith_fame_list[MAX_FAME_LIST];
56struct fame_list chemist_fame_list[MAX_FAME_LIST];
57struct fame_list taekwon_fame_list[MAX_FAME_LIST];
58
59static unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_AMMO};
60
61static struct gm_account *gm_account = NULL;
62static int GM_num = 0;
63
64#define MOTD_LINE_SIZE 128
65char motd_text[MOTD_LINE_SIZE][256]; // Message of the day buffer [Valaris]
66
67struct duel duel_list[MAX_DUEL];
68int duel_count = 0;
69
70//Links related info to the sd->hate_mob[]/sd->feel_map[] entries
71const struct sg_data sg_info[3] = {
72                { SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun },
73                { SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon },
74                { SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
75        };
76
77//Converts a class to its array index for CLASS_COUNT defined arrays.
78//Note that it does not do a validity check for speed purposes, where parsing
79//player input make sure to use a pcdb_checkid first!
80int pc_class2idx(int class_) {
81        if (class_ >= JOB_NOVICE_HIGH)
82                return class_- JOB_NOVICE_HIGH+JOB_MAX_BASIC;
83        return class_;
84}
85
86int pc_isGM(struct map_session_data* sd)
87{
88        int i;
89        nullpo_retr(0, sd);
90
91        if( sd->bl.type != BL_PC )
92                return 99;
93
94        ARR_FIND( 0, GM_num, i, gm_account[i].account_id == sd->status.account_id );
95        return ( i < GM_num ) ? gm_account[i].level : 0;
96}
97
98int pc_set_gm_level(int account_id, int level)
99{
100    int i;
101
102        ARR_FIND( 0, GM_num, i, account_id == gm_account[i].account_id );
103        if( i < GM_num )
104        {
105                gm_account[i].level = level;
106        }
107        else
108        {
109            gm_account = (struct gm_account *) aRealloc(gm_account, (GM_num + 1) * sizeof(struct gm_account));
110            gm_account[GM_num].account_id = account_id;
111            gm_account[GM_num].level = level;
112            GM_num++;
113        }
114
115        return 0;
116}
117
118static int pc_invincible_timer(int tid, unsigned int tick, int id, intptr data)
119{
120        struct map_session_data *sd;
121
122        if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
123                return 1;
124
125        if(sd->invincible_timer != tid){
126                ShowError("invincible_timer %d != %d\n",sd->invincible_timer,tid);
127                return 0;
128        }
129        sd->invincible_timer=-1;
130        skill_unit_move(&sd->bl,tick,1);
131
132        return 0;
133}
134
135void pc_setinvincibletimer(struct map_session_data* sd, int val)
136{
137        nullpo_retv(sd);
138
139        if( sd->invincible_timer != INVALID_TIMER )
140                delete_timer(sd->invincible_timer,pc_invincible_timer);
141        sd->invincible_timer = add_timer(gettick()+val,pc_invincible_timer,sd->bl.id,0);
142}
143
144void pc_delinvincibletimer(struct map_session_data* sd)
145{
146        nullpo_retv(sd);
147
148        if( sd->invincible_timer != INVALID_TIMER )
149        {
150                delete_timer(sd->invincible_timer,pc_invincible_timer);
151                sd->invincible_timer = INVALID_TIMER;
152                skill_unit_move(&sd->bl,gettick(),1);
153        }
154}
155
156static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr data)
157{
158        struct map_session_data *sd;
159
160        if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
161                return 1;
162
163        if(sd->spirit_timer[0] != tid){
164                ShowError("spirit_timer %d != %d\n",sd->spirit_timer[0],tid);
165                return 0;
166        }
167
168        if(sd->spiritball <= 0) {
169                ShowError("Spiritballs are already 0 when pc_spiritball_timer gets called");
170                sd->spiritball = 0;
171                return 0;
172        }
173
174        sd->spiritball--;
175        // I leave this here as bad example [Shinomori]
176        //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * sd->spiritball );
177        memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball)*sizeof(int) );
178        sd->spirit_timer[sd->spiritball]=-1;
179
180        clif_spiritball(sd);
181
182        return 0;
183}
184
185int pc_addspiritball(struct map_session_data *sd,int interval,int max)
186{
187        nullpo_retr(0, sd);
188
189        if(max > MAX_SKILL_LEVEL)
190                max = MAX_SKILL_LEVEL;
191        if(sd->spiritball < 0)
192                sd->spiritball = 0;
193
194        if(sd->spiritball >= max) {
195                if(sd->spirit_timer[0] != -1)
196                        delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
197                // I leave this here as bad example [Shinomori]
198                //memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * (sd->spiritball - 1));
199                memmove( sd->spirit_timer+0, sd->spirit_timer+1, (sd->spiritball - 1)*sizeof(int) );
200                //sd->spirit_timer[sd->spiritball-1] = -1; // intentionally, but will be overwritten
201        } else
202                sd->spiritball++;
203
204        sd->spirit_timer[sd->spiritball-1] = add_timer(gettick()+interval,pc_spiritball_timer,sd->bl.id,0);
205        clif_spiritball(sd);
206
207        return 0;
208}
209
210int pc_delspiritball(struct map_session_data *sd,int count,int type)
211{
212        int i;
213
214        nullpo_retr(0, sd);
215
216        if(sd->spiritball <= 0) {
217                sd->spiritball = 0;
218                return 0;
219        }
220
221        if(count > sd->spiritball)
222                count = sd->spiritball;
223        sd->spiritball -= count;
224        if(count > MAX_SKILL_LEVEL)
225                count = MAX_SKILL_LEVEL;
226
227        for(i=0;i<count;i++) {
228                if(sd->spirit_timer[i] != -1) {
229                        delete_timer(sd->spirit_timer[i],pc_spiritball_timer);
230                        sd->spirit_timer[i] = -1;
231                }
232        }
233        for(i=count;i<MAX_SKILL_LEVEL;i++) {
234                sd->spirit_timer[i-count] = sd->spirit_timer[i];
235                sd->spirit_timer[i] = -1;
236        }
237
238        if(!type)
239                clif_spiritball(sd);
240
241        return 0;
242}
243
244// Increases a player's fame points and displays a notice to him
245void pc_addfame(struct map_session_data *sd,int count)
246{
247        nullpo_retv(sd);
248        sd->status.fame += count;
249        if(sd->status.fame > MAX_FAME)
250                sd->status.fame = MAX_FAME;
251        switch(sd->class_&MAPID_UPPERMASK){
252                case MAPID_BLACKSMITH: // Blacksmith
253                        clif_fame_blacksmith(sd,count);
254                        break;
255                case MAPID_ALCHEMIST: // Alchemist
256                        clif_fame_alchemist(sd,count);
257                        break;
258                case MAPID_TAEKWON: // Taekwon
259                        clif_fame_taekwon(sd,count);
260                        break;
261        }
262        chrif_updatefamelist(sd);
263}
264
265// Check whether a player ID is in the fame rankers' list of its job, returns his/her position if so, 0 else
266unsigned char pc_famerank(int char_id, int job)
267{
268        int i;
269
270        switch(job){
271                case MAPID_BLACKSMITH: // Blacksmith
272                    for(i = 0; i < MAX_FAME_LIST; i++){
273                                if(smith_fame_list[i].id == char_id)
274                                    return i + 1;
275                        }
276                        break;
277                case MAPID_ALCHEMIST: // Alchemist
278                        for(i = 0; i < MAX_FAME_LIST; i++){
279                                if(chemist_fame_list[i].id == char_id)
280                                        return i + 1;
281                        }
282                        break;
283                case MAPID_TAEKWON: // Taekwon
284                        for(i = 0; i < MAX_FAME_LIST; i++){
285                                if(taekwon_fame_list[i].id == char_id)
286                                        return i + 1;
287                        }
288                        break;
289        }
290
291        return 0;
292}
293
294int pc_setrestartvalue(struct map_session_data *sd,int type)
295{
296        struct status_data *status, *b_status;
297        nullpo_retr(0, sd);
298
299        b_status = &sd->base_status;
300        status = &sd->battle_status;
301
302        if (type&1)
303        {       //Normal resurrection
304                status->hp = 1; //Otherwise status_heal may fail if dead.
305                status_heal(&sd->bl, b_status->hp, b_status->sp>status->sp?b_status->sp-status->sp:0, 1);
306        } else { //Just for saving on the char-server (with values as if respawned)
307                sd->status.hp = b_status->hp;
308                sd->status.sp = (status->sp < b_status->sp)?b_status->sp:status->sp;
309        }
310        return 0;
311}
312
313/*==========================================
314        Determines if the GM can give / drop / trade / vend items
315    Args: GM Level (current player GM level)
316 *------------------------------------------*/
317bool pc_can_give_items(int level)
318{
319        return( level < battle_config.gm_cant_drop_min_lv || level > battle_config.gm_cant_drop_max_lv );
320}
321
322/*==========================================
323 * prepares character for saving.
324 *------------------------------------------*/
325int pc_makesavestatus(struct map_session_data *sd)
326{
327        nullpo_retr(0, sd);
328
329        if(!battle_config.save_clothcolor)
330                sd->status.clothes_color=0;
331
332        //Only copy the Cart/Peco/Falcon options, the rest are handled via
333        //status change load/saving. [Skotlex]
334        sd->status.option = sd->sc.option&(OPTION_CART|OPTION_FALCON|OPTION_RIDING);
335
336        if (sd->sc.data[SC_JAILED])
337        {       //When Jailed, do not move last point.
338                if(pc_isdead(sd)){
339                        pc_setrestartvalue(sd,0);
340                } else {
341                        sd->status.hp = sd->battle_status.hp;
342                        sd->status.sp = sd->battle_status.sp;
343                }
344                sd->status.last_point.map = sd->mapindex;
345                sd->status.last_point.x = sd->bl.x;
346                sd->status.last_point.y = sd->bl.y;
347                return 0;
348        }
349
350        if(pc_isdead(sd)){
351                pc_setrestartvalue(sd,0);
352                memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
353        } else {
354                sd->status.hp = sd->battle_status.hp;
355                sd->status.sp = sd->battle_status.sp;
356                sd->status.last_point.map = sd->mapindex;
357                sd->status.last_point.x = sd->bl.x;
358                sd->status.last_point.y = sd->bl.y;
359        }
360
361        if(map[sd->bl.m].flag.nosave){
362                struct map_data *m=&map[sd->bl.m];
363                if(m->save.map)
364                        memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
365                else
366                        memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
367        }
368
369        return 0;
370}
371
372/*==========================================
373 * Ú?Žb̏‰Šú‰»
374 *------------------------------------------*/
375int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, unsigned int client_tick, int sex, int fd)
376{
377        nullpo_retr(0, sd);
378
379        sd->bl.id        = account_id;
380        sd->status.account_id   = account_id;
381        sd->status.char_id      = char_id;
382        sd->status.sex   = sex;
383        sd->login_id1    = login_id1;
384        sd->login_id2    = 0; // at this point, we can not know the value :(
385        sd->client_tick  = client_tick;
386        sd->state.active = 0; //to be set to 1 after player is fully authed and loaded.
387        sd->bl.type      = BL_PC;
388        sd->canlog_tick  = gettick();
389        //Required to prevent homunculus copuing a base speed of 0.
390        sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED;
391        return 0;
392}
393
394int pc_equippoint(struct map_session_data *sd,int n)
395{
396        int ep = 0;
397
398        nullpo_retr(0, sd);
399
400        if(!sd->inventory_data[n])
401                return 0;
402
403        if (!itemdb_isequip2(sd->inventory_data[n]))
404                return 0; //Not equippable by players.
405
406        ep = sd->inventory_data[n]->equip;
407        if(sd->inventory_data[n]->look == W_DAGGER      ||
408                sd->inventory_data[n]->look == W_1HSWORD ||
409                sd->inventory_data[n]->look == W_1HAXE) {
410                if(ep == EQP_HAND_R && (pc_checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN))
411                        return EQP_ARMS;
412        }
413        return ep;
414}
415
416int pc_setinventorydata(struct map_session_data *sd)
417{
418        int i,id;
419
420        nullpo_retr(0, sd);
421
422        for(i=0;i<MAX_INVENTORY;i++) {
423                id = sd->status.inventory[i].nameid;
424                sd->inventory_data[i] = id?itemdb_search(id):NULL;
425        }
426        return 0;
427}
428
429int pc_calcweapontype(struct map_session_data *sd)
430{
431        nullpo_retr(0, sd);
432
433        // single-hand
434        if(sd->weapontype2 == W_FIST) {
435                sd->status.weapon = sd->weapontype1;
436                return 1;
437        }
438        if(sd->weapontype1 == W_FIST) {
439                sd->status.weapon = sd->weapontype2;
440                return 1;
441        }
442        // dual-wield
443        sd->status.weapon = 0;
444        switch (sd->weapontype1){
445        case W_DAGGER:
446                switch (sd->weapontype2) {
447                case W_DAGGER:  sd->status.weapon = W_DOUBLE_DD; break;
448                case W_1HSWORD: sd->status.weapon = W_DOUBLE_DS; break;
449                case W_1HAXE:   sd->status.weapon = W_DOUBLE_DA; break;
450                }
451                break;
452        case W_1HSWORD:
453                switch (sd->weapontype2) {
454                case W_DAGGER:  sd->status.weapon = W_DOUBLE_DS; break;
455                case W_1HSWORD: sd->status.weapon = W_DOUBLE_SS; break;
456                case W_1HAXE:   sd->status.weapon = W_DOUBLE_SA; break;
457                }
458                break;
459        case W_1HAXE:
460                switch (sd->weapontype2) {
461                case W_DAGGER:  sd->status.weapon = W_DOUBLE_DA; break;
462                case W_1HSWORD: sd->status.weapon = W_DOUBLE_SA; break;
463                case W_1HAXE:   sd->status.weapon = W_DOUBLE_AA; break;
464                }
465        }
466        // unknown, default to right hand type
467        if (!sd->status.weapon)
468                sd->status.weapon = sd->weapontype1;
469
470        return 2;
471}
472
473int pc_setequipindex(struct map_session_data *sd)
474{
475        int i,j;
476
477        nullpo_retr(0, sd);
478
479        for(i=0;i<EQI_MAX;i++)
480                sd->equip_index[i] = -1;
481
482        for(i=0;i<MAX_INVENTORY;i++) {
483                if(sd->status.inventory[i].nameid <= 0)
484                        continue;
485                if(sd->status.inventory[i].equip) {
486                        for(j=0;j<EQI_MAX;j++)
487                                if(sd->status.inventory[i].equip & equip_pos[j])
488                                        sd->equip_index[j] = i;
489
490                        if(sd->status.inventory[i].equip & EQP_HAND_R)
491                        {
492                                if(sd->inventory_data[i])
493                                        sd->weapontype1 = sd->inventory_data[i]->look;
494                                else
495                                        sd->weapontype1 = 0;
496                        }
497
498                        if( sd->status.inventory[i].equip & EQP_HAND_L )
499                        {
500                                if( sd->inventory_data[i] && sd->inventory_data[i]->type == 4 )
501                                        sd->weapontype2 = sd->inventory_data[i]->look;
502                                else
503                                        sd->weapontype2 = 0;
504                        }
505                }
506        }
507        pc_calcweapontype(sd);
508
509        return 0;
510}
511
512static int pc_isAllowedCardOn(struct map_session_data *sd,int s,int eqindex,int flag)
513{
514        int i;
515        struct item *item = &sd->status.inventory[eqindex];
516        struct item_data *data;
517        //Crafted/made/hatched items.
518        if (itemdb_isspecial(item->card[0]))
519                return 1;
520
521        ARR_FIND( 0, s, i, item->card[i] && (data = itemdb_exists(item->card[i])) != NULL && data->flag.no_equip&flag );
522        return( i < s ) ? 0 : 1;
523}
524
525bool pc_isequipped(struct map_session_data *sd, int nameid)
526{
527        int i, j, index;
528
529        for( i = 0; i < EQI_MAX; i++ )
530        {
531                index = sd->equip_index[i];
532                if( index < 0 ) continue;
533
534                if( i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index ) continue;
535                if( i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index ) continue;
536                if( i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index) ) continue;
537
538                if( !sd->inventory_data[index] ) continue;
539
540                if( sd->inventory_data[index]->nameid == nameid )
541                        return true;
542
543                for( j = 0; j < sd->inventory_data[index]->slot; j++ )
544                        if( sd->status.inventory[index].card[j] == nameid )
545                                return true;
546        }
547
548        return false;
549}
550
551bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd )
552{
553        if( !p1_sd || !p2_sd || !b_sd )
554                return false;
555
556        if( b_sd->status.father || b_sd->status.mother || b_sd->adopt_invite )
557                return false; // already adopted baby / in adopt request
558
559        if( !p1_sd->status.partner_id || !p1_sd->status.party_id || p1_sd->status.party_id != b_sd->status.party_id )
560                return false; // You need to be married and in party with baby to adopt
561
562        if( p1_sd->status.partner_id != p2_sd->status.char_id || p2_sd->status.partner_id != p1_sd->status.char_id )
563                return false; // Not married, wrong married
564
565        if( p2_sd->status.party_id != p1_sd->status.party_id )
566                return false; // Both parents need to be in the same party
567
568        // Parents need to have their ring equipped
569        if( !pc_isequipped(p1_sd, WEDDING_RING_M) && !pc_isequipped(p1_sd, WEDDING_RING_F) )
570                return false;
571
572        if( !pc_isequipped(p2_sd, WEDDING_RING_M) && !pc_isequipped(p2_sd, WEDDING_RING_F) )
573                return false;
574
575        // Already adopted a baby
576        if( p1_sd->status.child || p2_sd->status.child ) {
577                clif_Adopt_reply(p1_sd, 0);
578                return false;
579        }
580
581        // Parents need at least lvl 70 to adopt
582        if( p1_sd->status.base_level < 70 || p2_sd->status.base_level < 70 ) {
583                clif_Adopt_reply(p1_sd, 1);
584                return false;
585        }
586
587        if( b_sd->status.partner_id ) {
588                clif_Adopt_reply(p1_sd, 2);
589                return false;
590        }
591
592        if( !(b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF) )
593                return false;
594
595        return true;
596}
597
598/*==========================================
599 * Adoption Process
600 *------------------------------------------*/
601bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd)
602{
603        int job, joblevel;
604        unsigned int jobexp;
605
606        if( !pc_can_Adopt(p1_sd, p2_sd, b_sd) )
607                return false;
608
609        // Preserve current job levels and progress
610        joblevel = b_sd->status.job_level;
611        jobexp = b_sd->status.job_exp;
612
613        job = pc_mapid2jobid(b_sd->class_|JOBL_BABY, b_sd->status.sex);
614        if( job != -1 && !pc_jobchange(b_sd, job, 0) )
615        { // Success, proceed to configure parents and baby skills
616                p1_sd->status.child = b_sd->status.char_id;
617                p2_sd->status.child = b_sd->status.char_id;
618                b_sd->status.father = p1_sd->status.char_id;
619                b_sd->status.mother = p2_sd->status.char_id;
620
621                // Restore progress
622                b_sd->status.job_level = joblevel;
623                clif_updatestatus(b_sd, SP_JOBLEVEL);
624                b_sd->status.job_exp = jobexp;
625                clif_updatestatus(b_sd, SP_JOBEXP);
626
627                // Baby Skills
628                pc_skill(b_sd, WE_BABY, 1, 0);
629                pc_skill(b_sd, WE_CALLPARENT, 1, 0);
630
631                // Parents Skills
632                pc_skill(p1_sd, WE_CALLBABY, 1, 0);
633                pc_skill(p2_sd, WE_CALLBABY, 1, 0);
634
635                return true;
636        }
637
638        return false; // Job Change Fail
639}
640
641int pc_isequip(struct map_session_data *sd,int n)
642{
643        struct item_data *item;
644        //?¶‚â—{Žq‚̏ꍇ‚ÌŒ³‚̐E‹Æ‚ðŽZo‚·‚é
645
646        nullpo_retr(0, sd);
647
648        item = sd->inventory_data[n];
649
650        if( battle_config.gm_allequip>0 && pc_isGM(sd)>=battle_config.gm_allequip )
651                return 1;
652
653        if(item == NULL)
654                return 0;
655        if(item->elv && sd->status.base_level < (unsigned int)item->elv)
656                return 0;
657        if(item->sex != 2 && sd->status.sex != item->sex)
658                return 0;
659        if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
660                return 0;
661        if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
662                return 0;
663        if(map[sd->bl.m].flag.restricted)
664        {
665                int flag =map[sd->bl.m].zone;
666                if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag))
667                        return 0;
668        }
669
670        if (sd->sc.count) {
671
672                if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
673                        return 0;
674                if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD])
675                        return 0;
676                if(item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR])
677                        return 0;
678                if(item->equip & EQP_HELM && sd->sc.data[SC_STRIPHELM])
679                        return 0;
680
681                if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SUPERNOVICE) {
682                        //Spirit of Super Novice equip bonuses. [Skotlex]
683                        if (sd->status.base_level > 90 && item->equip & EQP_HELM)
684                                return 1; //Can equip all helms
685
686                        if (sd->status.base_level > 96 && item->equip & EQP_ARMS && item->type == IT_WEAPON)
687                                switch(item->look) { //In weapons, the look determines type of weapon.
688                                        case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess?
689                                        case W_1HSWORD: //All 1H swords
690                                        case W_1HAXE: //All 1H Axes
691                                        case W_MACE: //All 1H Maces
692                                        case W_STAFF: //All 1H Staves
693                                                return 1;
694                                }
695                }
696        }
697        //Not equipable by class. [Skotlex]
698        if (!(1<<(sd->class_&MAPID_BASEMASK)&item->class_base[(sd->class_&JOBL_2_1)?1:((sd->class_&JOBL_2_2)?2:0)]))
699                return 0;
700
701        //Not equipable by upper class. [Skotlex]
702        if(!(1<<((sd->class_&JOBL_UPPER)?1:((sd->class_&JOBL_BABY)?2:0))&item->class_upper))
703                return 0;
704
705        return 1;
706}
707
708/*==========================================
709 * session id‚É–â‘è–³‚µ
710 * charŽI‚©‚ç‘—‚ç‚ê‚Ä‚«‚œƒXƒe?ƒ^ƒX‚ðÝ’è
711 *------------------------------------------*/
712bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, struct mmo_charstatus *st)
713{
714        int i;
715        unsigned long tick = gettick();
716
717        sd->login_id2 = login_id2;
718        memcpy(&sd->status, st, sizeof(*st));
719
720        if (st->sex != sd->status.sex) {
721                clif_authfail_fd(sd->fd, 0);
722                return false;
723        }
724
725        //Set the map-server used job id. [Skotlex]
726        i = pc_jobid2mapid(sd->status.class_);
727        if (i == -1) { //Invalid class?
728                ShowError("pc_authok: Invalid class %d for player %s (%d:%d). Class was changed to novice.\n", sd->status.class_, sd->status.name, sd->status.account_id, sd->status.char_id);
729                sd->status.class_ = JOB_NOVICE;
730                sd->class_ = MAPID_NOVICE;
731        } else
732                sd->class_ = i;
733        //Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation.
734        if(!sd->status.hp) pc_setdead(sd);
735        sd->state.connect_new = 1;
736
737        sd->followtimer = -1; // [MouseJstr]
738        sd->invincible_timer = -1;
739        sd->npc_timer_id = -1;
740        sd->pvp_timer = -1;
741
742        sd->canuseitem_tick = tick;
743        sd->cantalk_tick = tick;
744        sd->cansendmail_tick = tick;
745
746        for(i = 0; i < MAX_SKILL_LEVEL; i++)
747                sd->spirit_timer[i] = -1;
748
749        if (battle_config.item_auto_get)
750                sd->state.autoloot = 10000;
751
752        if (battle_config.disp_experience)
753                sd->state.showexp = 1;
754        if (battle_config.disp_zeny)
755                sd->state.showzeny = 1;
756<<<<<<< .mine
757        //Vanaheim settings [Brainstorm]
758        if (battle_config.disp_summon_stats) // Battle Flag to Show Summoned Monster Stats [Brain]
759        sd->state.showsummon = 1;
760
761=======
762        //Custom Job (blackmagick)     
763        //Vanaheim settings [Brainstorm]
764        if (battle_config.disp_summon_stats) // Battle Flag to Show Summoned Monster Stats [Brain]
765                sd->state.showsummon = 1;
766       
767>>>>>>> .r18
768        if (!(battle_config.display_skill_fail&2))
769                sd->state.showdelay = 1;
770
771        // ƒAƒCƒeƒ€ƒ`ƒFƒbƒN
772        pc_setinventorydata(sd);
773        pc_checkitem(sd);
774
775        status_change_init(&sd->bl);
776        if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level(atcommand_hide)))
777                sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
778        else
779                sd->status.option &= OPTION_MASK;
780
781        sd->sc.option = sd->status.option; //This is the actual option used in battle.
782        //Set here because we need the inventory data for weapon sprite parsing.
783        status_set_viewdata(&sd->bl, sd->status.class_);
784        unit_dataset(&sd->bl);
785
786        sd->guild_x = -1;
787        sd->guild_y = -1;
788
789        // ƒCƒxƒ“ƒg?ŒW‚̏‰Šú‰»
790        for(i = 0; i < MAX_EVENTTIMER; i++)
791                sd->eventtimer[i] = -1;
792
793        for (i = 0; i < 3; i++)
794                sd->hate_mob[i] = -1;
795
796        // ˆÊ’u‚̐ݒè
797        if ((i=pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, 0)) != 0) {
798                ShowError ("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i);
799
800                // try warping to a default map instead (church graveyard)
801                if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, 0) != 0) {
802                        // if we fail again
803                        clif_authfail_fd(sd->fd, 0);
804                        return false;
805                }
806        }
807
808        clif_authok(sd);
809
810        //Prevent S. Novices from getting the no-death bonus just yet. [Skotlex]
811        sd->die_counter=-1;
812
813        {       //Add IP field
814                uint32 ip = session[sd->fd]->client_addr;
815                if (pc_isGM(sd))
816                        ShowInfo("GM '"CL_WHITE"%s"CL_RESET"' logged in."
817                                " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
818                                " Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"',"
819                                " GM Level '"CL_WHITE"%d"CL_RESET"').\n",
820                                sd->status.name, sd->status.account_id, sd->status.char_id,
821                                sd->packet_ver, CONVIP(ip), pc_isGM(sd));
822                else
823                        ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in."
824                                " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
825                                " Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"').\n",
826                                sd->status.name, sd->status.account_id, sd->status.char_id,
827                                sd->packet_ver, CONVIP(ip));
828        }
829
830        // Send friends list
831        clif_friendslist_send(sd);
832
833        if (battle_config.display_version == 1){
834                char buf[256];
835                sprintf(buf, "eAthena SVN version: %s", get_svn_revision());
836                clif_displaymessage(sd->fd, buf);
837        }
838
839        // Message of the Day [Valaris]
840        for(i=0; motd_text[i][0] && i < MOTD_LINE_SIZE; i++) {
841                if (battle_config.motd_type)
842                        clif_disp_onlyself(sd,motd_text[i],strlen(motd_text[i]));
843                else
844                        clif_displaymessage(sd->fd, motd_text[i]);
845        }
846
847        // message of the limited time of the account
848        if (expiration_time != 0) { // don't display if it's unlimited or unknow value
849                char tmpstr[1024];
850                strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&expiration_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
851                clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
852        }
853
854        //Night message
855        if (night_flag)
856        {
857                char tmpstr[1024];
858                strcpy(tmpstr, msg_txt(500)); // Actually, it's the night...
859                clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
860        }
861
862        // Request all registries (auth is considered completed whence they arrive)
863        intif_request_registry(sd,7);
864        return true;
865}
866
867/*==========================================
868 * Closes a connection because it failed to be authenticated from the char server.
869 *------------------------------------------*/
870void pc_authfail(struct map_session_data *sd)
871{
872        clif_authfail_fd(sd->fd, 0);
873        return;
874}
875
876//Attempts to set a mob.
877int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
878{
879        int class_;
880        if (!sd || !bl || pos < 0 || pos > 2)
881                return 0;
882        if (sd->hate_mob[pos] != -1)
883        {       //Can't change hate targets.
884                clif_hate_info(sd, pos, sd->hate_mob[pos], 0); //Display current
885                return 0;
886        }
887
888        class_ = status_get_class(bl);
889        if (!pcdb_checkid(class_)) {
890                unsigned int max_hp = status_get_max_hp(bl);
891                if ((pos == 1 && max_hp < 6000) || (pos == 2 && max_hp < 20000))
892                        return 0;
893                if (pos != status_get_size(bl))
894                        return 0; //Wrong size
895        }
896        sd->hate_mob[pos] = class_;
897        pc_setglobalreg(sd,sg_info[pos].hate_var,class_+1);
898        clif_hate_info(sd, pos, class_, 1);
899        return 1;
900}
901
902/*==========================================
903 * Invoked once after the char/account/account2 registry variables are received. [Skotlex]
904 *------------------------------------------*/
905int pc_reg_received(struct map_session_data *sd)
906{
907        int i,j;
908
909        sd->change_level = pc_readglobalreg(sd,"jobchange_level");
910        sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
911
912        // Cash shop
913        sd->cashPoints = pc_readaccountreg(sd,"#CASHPOINTS");
914        sd->kafraPoints = pc_readaccountreg(sd,"#KAFRAPOINTS");
915
916        if ((sd->class_&MAPID_BASEMASK)==MAPID_TAEKWON)
917        {       //Better check for class rather than skill to prevent "skill resets" from unsetting this
918                sd->mission_mobid = pc_readglobalreg(sd,"TK_MISSION_ID");
919                sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT");
920        }
921
922        //SG map and mob read [Komurka]
923        for(i=0;i<3;i++) //for now - someone need to make reading from txt/sql
924        {
925                if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) {
926                        sd->feel_map[i].index = j;
927                        sd->feel_map[i].m = map_mapindex2mapid(j);
928                } else {
929                        sd->feel_map[i].index = 0;
930                        sd->feel_map[i].m = -1;
931                }
932                sd->hate_mob[i] = pc_readglobalreg(sd,sg_info[i].hate_var)-1;
933        }
934
935        if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) {
936                sd->cloneskill_id = pc_readglobalreg(sd,"CLONE_SKILL");
937                if (sd->cloneskill_id > 0) {
938                        sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id;
939                        sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV");
940                        if (i < sd->status.skill[sd->cloneskill_id].lv)
941                                sd->status.skill[sd->cloneskill_id].lv = i;
942                        sd->status.skill[sd->cloneskill_id].flag = 13;  //cloneskill flag
943                }
944        }
945
946        //Weird... maybe registries were reloaded?
947        if (sd->state.active)
948                return 0;
949        sd->state.active = 1;
950
951        if (sd->status.party_id)
952                party_member_joined(sd);
953        if (sd->status.guild_id)
954                guild_member_joined(sd);
955
956        // pet
957        if (sd->status.pet_id > 0)
958                intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
959
960        // Homunculus [albator]
961        if (sd->status.hom_id > 0)
962                intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
963
964        map_addiddb(&sd->bl);
965        map_delnickdb(sd->status.char_id, sd->status.name);
966        if (!chrif_auth_finished(sd))
967                ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
968
969        status_calc_pc(sd,1);
970        chrif_scdata_request(sd->status.account_id, sd->status.char_id);
971
972#ifndef TXT_ONLY
973        intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
974        intif_request_questlog(sd);
975#endif
976
977        if (!sd->state.connect_new && sd->fd)
978        {       //Character already loaded map! Gotta trigger LoadEndAck manually.
979                sd->state.connect_new = 1;
980                clif_parse_LoadEndAck(sd->fd, sd);
981        }
982        return 1;
983}
984
985static int pc_calc_skillpoint(struct map_session_data* sd)
986{
987        int  i,skill,inf2,skill_point=0;
988
989        nullpo_retr(0, sd);
990
991        for(i=1;i<MAX_SKILL;i++){
992                if( (skill = pc_checkskill(sd,i)) > 0) {
993                        inf2 = skill_get_inf2(i);
994                        if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
995                                !(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
996                                ) {
997                                if(!sd->status.skill[i].flag)
998                                        skill_point += skill;
999                                else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) {
1000                                        skill_point += (sd->status.skill[i].flag - 2);
1001                                }
1002                        }
1003                }
1004        }
1005
1006        return skill_point;
1007}
1008
1009
1010/*==========================================
1011 * ?‚Š‚ç‚ê‚éƒXƒLƒ‹‚ÌŒvŽZ
1012 *------------------------------------------*/
1013int pc_calc_skilltree(struct map_session_data *sd)
1014{
1015        int i,id=0,flag;
1016        int c=0;
1017
1018        nullpo_retr(0, sd);
1019        i = pc_calc_skilltree_normalize_job(sd);
1020        c = pc_mapid2jobid(i, sd->status.sex);
1021        if (c == -1) { //Unable to normalize job??
1022                ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
1023                return 1;
1024        }
1025        c = pc_class2idx(c);
1026        for(i=0;i<MAX_SKILL;i++){
1027                if (sd->status.skill[i].flag != 13) //Don't touch plagiarized skills
1028                        sd->status.skill[i].id=0; //First clear skills.
1029        }
1030
1031        for(i=0;i<MAX_SKILL;i++){
1032                if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ //Restore original level of skills after deleting earned skills.
1033                        sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2;
1034                        sd->status.skill[i].flag=0;
1035                }
1036                if(sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU)
1037                { //Enable Bard/Dancer spirit linked skills.
1038                        if (sd->status.sex) { //Link dancer skills to bard.
1039                                sd->status.skill[i].id=i;
1040                                sd->status.skill[i].lv=sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
1041                                sd->status.skill[i].flag=1; // Tag it as a non-savable, non-uppable, bonus skill
1042                        } else { //Link bard skills to dancer.
1043                                sd->status.skill[i-8].id=i-8;
1044                                sd->status.skill[i-8].lv=sd->status.skill[i].lv; // Set the level to the same as the linking skill
1045                                sd->status.skill[i-8].flag=1; // Tag it as a non-savable, non-uppable, bonus skill
1046                        }
1047                }
1048        }
1049
1050        if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){
1051                for(i=0;i<MAX_SKILL;i++){
1052                        if (skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) //Only skills you can't have are npc/guild ones
1053                                continue;
1054                        if (skill_get_max(i) > 0)
1055                                sd->status.skill[i].id=i;
1056                }
1057                return 0;
1058        }
1059
1060        do {
1061                flag = 0;
1062                for(i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++) {
1063                        int j, f, k, inf2;
1064
1065                        if(sd->status.skill[id].id)
1066                                continue; //Skill already known.
1067
1068                        f = 1;
1069                        if(!battle_config.skillfree) {
1070                                for(j = 0; j < 5; j++) {
1071                                        if((k=skill_tree[c][i].need[j].id))
1072                                        {
1073                                                if (!sd->status.skill[k].id || sd->status.skill[k].flag == 13)
1074                                                        k = 0; //Not learned.
1075                                                else if (sd->status.skill[k].flag) //Real lerned level
1076                                                        k = sd->status.skill[skill_tree[c][i].need[j].id].flag-2;
1077                                                else
1078                                                        k = pc_checkskill(sd,k);
1079                                                if (k < skill_tree[c][i].need[j].lv)
1080                                                {
1081                                                        f=0;
1082                                                        break;
1083                                                }
1084                                        }
1085                                }
1086                                if (sd->status.job_level < skill_tree[c][i].joblv)
1087                                        f = 0; // job level requirement wasn't satisfied
1088                        }
1089
1090                        if (f) {
1091                                inf2 = skill_get_inf2(id);
1092
1093                                if(!sd->status.skill[id].lv && (
1094                                        (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
1095                                        inf2&INF2_WEDDING_SKILL ||
1096                                        (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
1097                                ))
1098                                        continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
1099
1100                                sd->status.skill[id].id = id;
1101
1102                                if(inf2&INF2_SPIRIT_SKILL)
1103                                {       //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
1104                                        sd->status.skill[id].lv = 1; // need to manually specify a skill level
1105                                        sd->status.skill[id].flag = 1; //So it is not saved, and tagged as a "bonus" skill.
1106                                }
1107                                flag = 1; // skill list has changed, perform another pass
1108                        }
1109                }
1110        } while(flag);
1111
1112        if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON)) {
1113                //Grant all Taekwon Tree, but only as bonus skills in case they drop from ranking. [Skotlex]
1114                for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0;i++){
1115                        if ((skill_get_inf2(id)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)))
1116                                continue; //Do not include Quest/Wedding skills.
1117                        if(sd->status.skill[id].id==0 ){
1118                                sd->status.skill[id].id=id;
1119                                sd->status.skill[id].flag=1; //So it is not saved, and tagged as a "bonus" skill.
1120                        } else
1121                                sd->status.skill[id].flag=sd->status.skill[id].lv+2;
1122                        sd->status.skill[id].lv= skill_tree_get_max(id, sd->status.class_);
1123                }
1124        }
1125
1126        return 0;
1127}
1128
1129//Checks if you can learn a new skill after having leveled up a skill.
1130static void pc_check_skilltree(struct map_session_data *sd, int skill)
1131{
1132        int i,id=0,flag;
1133        int c=0;
1134
1135        if(battle_config.skillfree)
1136                return; //Function serves no purpose if this is set
1137
1138        i = pc_calc_skilltree_normalize_job(sd);
1139        c = pc_mapid2jobid(i, sd->status.sex);
1140        if (c == -1) { //Unable to normalize job??
1141                ShowError("pc_check_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
1142                return;
1143        }
1144        c = pc_class2idx(c);
1145        do {
1146                flag=0;
1147                for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0;i++){
1148                        int j,f=1, k;
1149
1150                        if(sd->status.skill[id].id) //Already learned
1151                                continue;
1152
1153                        for(j=0;j<5;j++) {
1154                                if((k=skill_tree[c][i].need[j].id))
1155                                {
1156                                        if (!sd->status.skill[k].id || sd->status.skill[k].flag == 13)
1157                                                k = 0; //Not learned.
1158                                        else if (sd->status.skill[k].flag) //Real lerned level
1159                                                k = sd->status.skill[skill_tree[c][i].need[j].id].flag-2;
1160                                        else
1161                                                k = pc_checkskill(sd,k);
1162                                        if (k < skill_tree[c][i].need[j].lv)
1163                                        {
1164                                                f=0;
1165                                                break;
1166                                        }
1167                                }
1168                        }
1169                        if (!f)
1170                                continue;
1171                        if (sd->status.job_level < skill_tree[c][i].joblv)
1172                                continue;
1173
1174                        j = skill_get_inf2(id);
1175                        if(!sd->status.skill[id].lv && (
1176                                (j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
1177                                j&INF2_WEDDING_SKILL ||
1178                                (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
1179                        ))
1180                                continue; //Cannot be learned via normal means.
1181
1182                        sd->status.skill[id].id=id;
1183                        flag=1;
1184                }
1185        } while(flag);
1186}
1187
1188// Make sure all the skills are in the correct condition
1189// before persisting to the backend.. [MouseJstr]
1190int pc_clean_skilltree(struct map_session_data *sd)
1191{
1192        int i;
1193        for (i = 0; i < MAX_SKILL; i++){
1194                if (sd->status.skill[i].flag == 13 || sd->status.skill[i].flag == 1)
1195                {
1196                        sd->status.skill[i].id = 0;
1197                        sd->status.skill[i].lv = 0;
1198                        sd->status.skill[i].flag = 0;
1199                } else if (sd->status.skill[i].flag){
1200                        sd->status.skill[i].lv = sd->status.skill[i].flag-2;
1201                        sd->status.skill[i].flag = 0;
1202                }
1203        }
1204
1205        return 0;
1206}
1207
1208int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
1209{
1210        int skill_point;
1211        int c = sd->class_;
1212
1213        if (!battle_config.skillup_limit)
1214                return c;
1215
1216        skill_point = pc_calc_skillpoint(sd);
1217        if(pc_checkskill(sd, NV_BASIC) < 9) //Consider Novice Tree when you don't have NV_BASIC maxed.
1218                c = MAPID_NOVICE;
1219        else
1220        //Do not send S. Novices to first class (Novice)
1221        if ((sd->class_&JOBL_2) && (sd->class_&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE &&
1222                sd->status.skill_point >= (int)sd->status.job_level &&
1223                ((sd->change_level > 0 && skill_point < sd->change_level+8) || skill_point < 58)) {
1224                //Send it to first class.
1225                c &= MAPID_BASEMASK;
1226        }
1227        if (sd->class_&JOBL_UPPER) //Convert to Upper
1228                c |= JOBL_UPPER;
1229        else if (sd->class_&JOBL_BABY) //Convert to Baby
1230                c |= JOBL_BABY;
1231
1232        return c;
1233}
1234
1235/*==========================================
1236 * Updates the weight status
1237 *------------------------------------------
1238 * 1: overweight 50%
1239 * 2: overweight 90%
1240 * It's assumed that SC_WEIGHT50 and SC_WEIGHT90 are only started/stopped here.
1241 */
1242int pc_updateweightstatus(struct map_session_data *sd)
1243{
1244        int old_overweight;
1245        int new_overweight;
1246
1247        nullpo_retr(1, sd);
1248
1249        old_overweight = (sd->sc.data[SC_WEIGHT90]) ? 2 : (sd->sc.data[SC_WEIGHT50]) ? 1 : 0;
1250        new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is50overweight(sd)) ? 1 : 0;
1251
1252        if( old_overweight == new_overweight )
1253                return 0; // no change
1254
1255        // stop old status change
1256        if( old_overweight == 1 )
1257                status_change_end(&sd->bl, SC_WEIGHT50, -1);
1258        else if( old_overweight == 2 )
1259                status_change_end(&sd->bl, SC_WEIGHT90, -1);
1260
1261        // start new status change
1262        if( new_overweight == 1 )
1263                sc_start(&sd->bl, SC_WEIGHT50, 100, 0, 0);
1264        else if( new_overweight == 2 )
1265                sc_start(&sd->bl, SC_WEIGHT90, 100, 0, 0);
1266
1267        // update overweight status
1268        sd->regen.state.overweight = new_overweight;
1269
1270        return 0;
1271}
1272
1273int pc_disguise(struct map_session_data *sd, int class_)
1274{
1275        if (!class_ && !sd->disguise)
1276                return 0;
1277        if (class_ && sd->disguise == class_)
1278                return 0;
1279
1280        if(sd->sc.option&OPTION_INVISIBLE)
1281        {       //Character is invisible. Stealth class-change. [Skotlex]
1282                sd->disguise = class_; //viewdata is set on uncloaking.
1283                return 2;
1284        }
1285
1286        if (sd->bl.prev != NULL) {
1287                pc_stop_walking(sd, 0);
1288                clif_clearunit_area(&sd->bl, 0);
1289        }
1290
1291        if (!class_) {
1292                sd->disguise = 0;
1293                class_ = sd->status.class_;
1294        } else
1295                sd->disguise=class_;
1296
1297        status_set_viewdata(&sd->bl, class_);
1298        clif_changeoption(&sd->bl);
1299
1300        if (sd->bl.prev != NULL) {
1301                clif_spawn(&sd->bl);
1302                if (class_ == sd->status.class_ && pc_iscarton(sd))
1303                {       //It seems the cart info is lost on undisguise.
1304                        clif_cartlist(sd);
1305                        clif_updatestatus(sd,SP_CARTINFO);
1306                }
1307        }
1308        return 1;
1309}
1310
1311int pc_autoscript_add(struct s_autoscript *scripts, int max, short rate, short flag, struct script_code *script)
1312{
1313        int i;
1314        ARR_FIND(0, max, i, scripts[i].script == NULL);
1315        if (i == max) {
1316                ShowWarning("pc_autoscript_bonus: Reached max (%d) number of autoscripts per character!\n", max);
1317                return 0;
1318        }
1319        scripts[i].script = script;
1320        scripts[i].rate = rate;
1321        //Auto-update flag value.
1322        if (!(flag&BF_RANGEMASK)) flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
1323        if (!(flag&BF_WEAPONMASK)) flag|=BF_WEAPON; //No attack type defined? Use weapon.
1324        if (!(flag&BF_SKILLMASK)) {
1325                if (flag&(BF_MAGIC|BF_MISC)) flag|=BF_SKILL; //These two would never trigger without BF_SKILL
1326                if (flag&BF_WEAPON) flag|=BF_NORMAL;
1327        }
1328        scripts[i].flag = flag;
1329        return 1;
1330}
1331
1332void pc_autoscript_clear(struct s_autoscript *scripts, int max)
1333{
1334        int i;
1335        for (i = 0; i < max && scripts[i].script; i++)
1336                script_free_code(scripts[i].script);
1337        memset(scripts, 0, i*sizeof(struct s_autoscript));
1338}
1339
1340static int pc_bonus_autospell_del(struct s_autospell* spell, int max, short id, short lv, short rate, short card_id)
1341{
1342        int i, j;
1343        for(i=max-1; i>=0 && !spell[i].id; i--);
1344        if (i<0) return 0; //Nothing to substract from.
1345
1346        j = i;
1347        for(; i>=0 && rate>0; i--)
1348        {
1349                if (spell[i].id != id || spell[i].lv != lv) continue;
1350                if (rate >= spell[i].rate) {
1351                        rate-= spell[i].rate;
1352                        spell[i].rate = 0;
1353                        memmove(&spell[i], &spell[j], sizeof(struct s_autospell));
1354                        memset(&spell[j], 0, sizeof(struct s_autospell));
1355                        j--;
1356                } else {
1357                        spell[i].rate -= rate;
1358                        rate = 0;
1359                }
1360        }
1361        if (rate > 0 && ++j < max)
1362        {        //Tag this as "pending" autospell to remove.
1363                spell[j].id = id;
1364                spell[j].lv = lv;
1365                spell[j].rate = -rate;
1366                spell[j].card_id = card_id;
1367        }
1368        return rate;
1369}
1370
1371static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id)
1372{
1373        int i;
1374        if (rate < 0) return //Remove the autobonus.
1375                pc_bonus_autospell_del(spell, max, id, lv, -rate, card_id);
1376
1377        for (i = 0; i < max && spell[i].id; i++) {
1378                if ((spell[i].card_id == card_id || spell[i].rate < 0) &&
1379                        spell[i].id == id && spell[i].lv == lv)
1380                {
1381                        if (!battle_config.autospell_stacking && spell[i].rate > 0)
1382                                return 0;
1383                        rate += spell[i].rate;
1384                        break;
1385                }
1386        }
1387        if (i == max) {
1388                ShowWarning("pc_bonus: Reached max (%d) number of autospells per character!\n", max);
1389                return 0;
1390        }
1391        spell[i].id = id;
1392        spell[i].lv = lv;
1393        spell[i].rate = rate;
1394        //Auto-update flag value.
1395        if (!(flag&BF_RANGEMASK)) flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
1396        if (!(flag&BF_WEAPONMASK)) flag|=BF_WEAPON; //No attack type defined? Use weapon.
1397        if (!(flag&BF_SKILLMASK)) {
1398                if (flag&(BF_MAGIC|BF_MISC)) flag|=BF_SKILL; //These two would never trigger without BF_SKILL
1399                if (flag&BF_WEAPON) flag|=BF_NORMAL; //By default autospells should only trigger on normal weapon attacks.
1400        }
1401        spell[i].flag|= flag;
1402        spell[i].card_id = card_id;
1403        return 1;
1404}
1405
1406static int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag)
1407{
1408        int i;
1409        if (!(flag&(ATF_SHORT|ATF_LONG)))
1410                flag|=ATF_SHORT|ATF_LONG; //Default range: both
1411        if (!(flag&(ATF_TARGET|ATF_SELF)))
1412                flag|=ATF_TARGET; //Default target: enemy.
1413
1414        for (i = 0; i < max && effect[i].flag; i++) {
1415                if (effect[i].id == id && effect[i].flag == flag)
1416                {
1417                        effect[i].rate += rate;
1418                        effect[i].arrow_rate += arrow_rate;
1419                        return 1;
1420                }
1421        }
1422        if (i == max) {
1423                ShowWarning("pc_bonus: Reached max (%d) number of add effects per character!\n", max);
1424                return 0;
1425        }
1426        effect[i].id = id;
1427        effect[i].rate = rate;
1428        effect[i].arrow_rate = arrow_rate;
1429        effect[i].flag = flag;
1430        return 1;
1431}
1432
1433static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int race, int rate)
1434{
1435        int i;
1436        //Apply config rate adjustment settings.
1437        if (rate >= 0) { //Absolute drop.
1438                if (battle_config.item_rate_adddrop != 100)
1439                        rate = rate*battle_config.item_rate_adddrop/100;
1440                if (rate < battle_config.item_drop_adddrop_min)
1441                        rate = battle_config.item_drop_adddrop_min;
1442                else if (rate > battle_config.item_drop_adddrop_max)
1443                        rate = battle_config.item_drop_adddrop_max;
1444        } else { //Relative drop, max/min limits are applied at drop time.
1445                if (battle_config.item_rate_adddrop != 100)
1446                        rate = rate*battle_config.item_rate_adddrop/100;
1447                if (rate > -1)
1448                        rate = -1;
1449        }
1450        for(i = 0; i < max && (drop[i].id || drop[i].group); i++) {
1451                if(
1452                        (id && drop[i].id == id) ||
1453                        (group && drop[i].group == group)
1454                ) {
1455                        drop[i].race |= race;
1456                        if(drop[i].rate > 0 && rate > 0)
1457                        {       //Both are absolute rates.
1458                                if (drop[i].rate < rate)
1459                                        drop[i].rate = rate;
1460                        } else
1461                        if(drop[i].rate < 0 && rate < 0) {
1462                                //Both are relative rates.
1463                                if (drop[i].rate > rate)
1464                                        drop[i].rate = rate;
1465                        } else if (rate < 0) //Give preference to relative rate.
1466                                        drop[i].rate = rate;
1467                        return 1;
1468                }
1469        }
1470        if(i == max) {
1471                ShowWarning("pc_bonus: Reached max (%d) number of added drops per character!\n", max);
1472                return 0;
1473        }
1474        drop[i].id = id;
1475        drop[i].group = group;
1476        drop[i].race |= race;
1477        drop[i].rate = rate;
1478        return 1;
1479}
1480
1481/*==========================================
1482 * ? ”õ•i‚É‚æ‚é”\—Í“™‚̃{?ƒiƒXÝ’è
1483 *------------------------------------------*/
1484int pc_bonus(struct map_session_data *sd,int type,int val)
1485{
1486        struct status_data *status;
1487        int bonus;
1488        nullpo_retr(0, sd);
1489
1490        status = &sd->base_status;
1491
1492        switch(type){
1493        case SP_STR:
1494        case SP_AGI:
1495        case SP_VIT:
1496        case SP_INT:
1497        case SP_DEX:
1498        case SP_LUK:
1499                if(sd->state.lr_flag != 2)
1500                        sd->param_bonus[type-SP_STR]+=val;
1501                break;
1502        case SP_ATK1:
1503                if(!sd->state.lr_flag) {
1504                        bonus = status->rhw.atk + val;
1505                        status->rhw.atk = cap_value(bonus, 0, USHRT_MAX);
1506                }
1507                else if(sd->state.lr_flag == 1) {
1508                        bonus = status->lhw.atk + val;
1509                        status->lhw.atk =  cap_value(bonus, 0, USHRT_MAX);
1510                }
1511                break;
1512        case SP_ATK2:
1513                if(!sd->state.lr_flag) {
1514                        bonus = status->rhw.atk2 + val;
1515                        status->rhw.atk2 = cap_value(bonus, 0, USHRT_MAX);
1516                }
1517                else if(sd->state.lr_flag == 1) {
1518                        bonus = status->lhw.atk2 + val;
1519                        status->lhw.atk2 =  cap_value(bonus, 0, USHRT_MAX);
1520                }
1521                break;
1522        case SP_BASE_ATK:
1523                if(sd->state.lr_flag != 2) {
1524                        bonus = status->batk + val;
1525                        status->batk = cap_value(bonus, 0, USHRT_MAX);
1526                }
1527                break;
1528        case SP_DEF1:
1529                if(sd->state.lr_flag != 2) {
1530                        bonus = status->def + val;
1531                        status->def = cap_value(bonus, CHAR_MIN, CHAR_MAX);
1532                }
1533                break;
1534        case SP_DEF2:
1535                if(sd->state.lr_flag != 2) {
1536                        bonus = status->def2 + val;
1537                        status->def2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
1538                }
1539                break;
1540        case SP_MDEF1:
1541                if(sd->state.lr_flag != 2) {
1542                        bonus = status->mdef + val;
1543                        status->mdef = cap_value(bonus, CHAR_MIN, CHAR_MAX);
1544                }
1545                break;
1546        case SP_MDEF2:
1547                if(sd->state.lr_flag != 2) {
1548                        bonus = status->mdef2 + val;
1549                        status->mdef2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
1550                }
1551                break;
1552        case SP_HIT:
1553                if(sd->state.lr_flag != 2) {
1554                        bonus = status->hit + val;
1555                        status->hit = cap_value(bonus, SHRT_MIN, SHRT_MAX);
1556                } else
1557                        sd->arrow_hit+=val;
1558                break;
1559        case SP_FLEE1:
1560                if(sd->state.lr_flag != 2) {
1561                        bonus = status->flee + val;
1562                        status->flee = cap_value(bonus, SHRT_MIN, SHRT_MAX);
1563                }
1564                break;
1565        case SP_FLEE2:
1566                if(sd->state.lr_flag != 2) {
1567                        bonus = status->flee2 + val*10;
1568                        status->flee2 = cap_value(bonus, SHRT_MIN, SHRT_MAX);
1569                }
1570                break;
1571        case SP_CRITICAL:
1572                if(sd->state.lr_flag != 2) {
1573                        bonus = status->cri + val*10;
1574                        status->cri = cap_value(bonus, SHRT_MIN, SHRT_MAX);
1575                } else
1576                        sd->arrow_cri += val*10;
1577                break;
1578        case SP_ATKELE:
1579                if(val >= ELE_MAX) {
1580                        ShowError("pc_bonus: SP_ATKELE: Invalid element %d\n", val);
1581                        break;
1582                }
1583                switch (sd->state.lr_flag)
1584                {
1585                case 2:
1586                        switch (sd->status.weapon) {
1587                                case W_BOW:
1588                                case W_REVOLVER:
1589                                case W_RIFLE:
1590                                case W_GATLING:
1591                                case W_SHOTGUN:
1592                                case W_GRENADE:
1593                                        //Become weapon element.
1594                                        status->rhw.ele=val;
1595                                        break;
1596                                default: //Become arrow element.
1597                                        sd->arrow_ele=val;
1598                                        break;
1599                        }
1600                        break;
1601                case 1:
1602                        status->lhw.ele=val;
1603                        break;
1604                default:
1605                        status->rhw.ele=val;
1606                        break;
1607                }
1608                break;
1609        case SP_DEFELE:
1610                if(val >= ELE_MAX) {
1611                        ShowError("pc_bonus: SP_DEFELE: Invalid element %d\n", val);
1612                        break;
1613                }
1614                if(sd->state.lr_flag != 2)
1615                        status->def_ele=val;
1616                break;
1617        case SP_MAXHP:
1618                if(sd->state.lr_flag == 2)
1619                        break;
1620                val += (int)status->max_hp;
1621                //Negative bonuses will underflow, this will be handled in status_calc_pc through casting
1622                //If this is called outside of status_calc_pc, you'd better pray they do not underflow and end with UINT_MAX max_hp.
1623                status->max_hp = (unsigned int)val;
1624                break;
1625        case SP_MAXSP:
1626                if(sd->state.lr_flag == 2)
1627                        break;
1628                val += (int)status->max_sp;
1629                status->max_sp = (unsigned int)val;
1630                break;
1631        case SP_CASTRATE:
1632                if(sd->state.lr_flag != 2)
1633                        sd->castrate+=val;
1634                break;
1635        case SP_MAXHPRATE:
1636                if(sd->state.lr_flag != 2)
1637                        sd->hprate+=val;
1638                break;
1639        case SP_MAXSPRATE:
1640                if(sd->state.lr_flag != 2)
1641                        sd->sprate+=val;
1642                break;
1643        case SP_SPRATE:
1644                if(sd->state.lr_flag != 2)
1645                        sd->dsprate+=val;
1646                break;
1647        case SP_ATTACKRANGE:
1648                switch (sd->state.lr_flag) {
1649                case 2:
1650                        switch (sd->status.weapon) {
1651                                case W_BOW:
1652                                case W_REVOLVER:
1653                                case W_RIFLE:
1654                                case W_GATLING:
1655                                case W_SHOTGUN:
1656                                case W_GRENADE:
1657                                        status->rhw.range += val;
1658                        }
1659                        break;
1660                case 1:
1661                        status->lhw.range += val;
1662                        break;
1663                default:
1664                        status->rhw.range += val;
1665                        break;
1666                }
1667                break;
1668        case SP_ADD_SPEED:      //Raw increase
1669                if(sd->state.lr_flag != 2) {
1670                        bonus = status->speed - val;
1671                        status->speed = cap_value(bonus, 0, USHRT_MAX);
1672                }
1673                break;
1674        case SP_SPEED_RATE:     //Non stackable increase
1675                if(sd->state.lr_flag != 2 && sd->speed_rate > 100-val)
1676                        sd->speed_rate = 100-val;
1677                break;
1678        case SP_SPEED_ADDRATE:  //Stackable increase
1679                if(sd->state.lr_flag != 2)
1680                        sd->speed_add_rate -= val;
1681                break;
1682        case SP_ASPD:   //Raw increase
1683                if(sd->state.lr_flag != 2)
1684                        sd->aspd_add -= 10*val;
1685                break;
1686        case SP_ASPD_RATE:      //Stackable increase - Made it linear as per rodatazone
1687                if(sd->state.lr_flag != 2)
1688                        status->aspd_rate -= 10*val;
1689                break;
1690        case SP_HP_RECOV_RATE:
1691                if(sd->state.lr_flag != 2)
1692                        sd->hprecov_rate += val;
1693                break;
1694        case SP_SP_RECOV_RATE:
1695                if(sd->state.lr_flag != 2)
1696                        sd->sprecov_rate += val;
1697                break;
1698        case SP_CRITICAL_DEF:
1699                if(sd->state.lr_flag != 2)
1700                        sd->critical_def += val;
1701                break;
1702        case SP_NEAR_ATK_DEF:
1703                if(sd->state.lr_flag != 2)
1704                        sd->near_attack_def_rate += val;
1705                break;
1706        case SP_LONG_ATK_DEF:
1707                if(sd->state.lr_flag != 2)
1708                        sd->long_attack_def_rate += val;
1709                break;
1710        case SP_DOUBLE_RATE:
1711                if(sd->state.lr_flag == 0 && sd->double_rate < val)
1712                        sd->double_rate = val;
1713                break;
1714        case SP_DOUBLE_ADD_RATE:
1715                if(sd->state.lr_flag == 0)
1716                        sd->double_add_rate += val;
1717                break;
1718        case SP_MATK_RATE:
1719                if(sd->state.lr_flag != 2)
1720                        sd->matk_rate += val;
1721                break;
1722        case SP_IGNORE_DEF_ELE:
1723                if(val >= ELE_MAX) {
1724                        ShowError("pc_bonus: SP_IGNORE_DEF_ELE: Invalid element %d\n", val);
1725                        break;
1726                }
1727                if(!sd->state.lr_flag)
1728                        sd->right_weapon.ignore_def_ele |= 1<<val;
1729                else if(sd->state.lr_flag == 1)
1730                        sd->left_weapon.ignore_def_ele |= 1<<val;
1731                break;
1732        case SP_IGNORE_DEF_RACE:
1733                if(!sd->state.lr_flag)
1734                        sd->right_weapon.ignore_def_race |= 1<<val;
1735                else if(sd->state.lr_flag == 1)
1736                        sd->left_weapon.ignore_def_race |= 1<<val;
1737                break;
1738        case SP_ATK_RATE:
1739                if(sd->state.lr_flag != 2)
1740                        sd->atk_rate += val;
1741                break;
1742        case SP_MAGIC_ATK_DEF:
1743                if(sd->state.lr_flag != 2)
1744                        sd->magic_def_rate += val;
1745                break;
1746        case SP_MISC_ATK_DEF:
1747                if(sd->state.lr_flag != 2)
1748                        sd->misc_def_rate += val;
1749                break;
1750        case SP_IGNORE_MDEF_RATE:
1751                if(sd->state.lr_flag != 2) {
1752                        sd->ignore_mdef[RC_NONBOSS] += val;
1753                        sd->ignore_mdef[RC_BOSS] += val;
1754                }
1755                break;
1756        case SP_IGNORE_MDEF_ELE:
1757                if(val >= ELE_MAX) {
1758                        ShowError("pc_bonus: SP_IGNORE_MDEF_ELE: Invalid element %d\n", val);
1759                        break;
1760                }
1761                if(sd->state.lr_flag != 2)
1762                        sd->ignore_mdef_ele |= 1<<val;
1763                break;
1764        case SP_IGNORE_MDEF_RACE:
1765                if(sd->state.lr_flag != 2)
1766                        sd->ignore_mdef_race |= 1<<val;
1767                break;
1768        case SP_PERFECT_HIT_RATE:
1769                if(sd->state.lr_flag != 2 && sd->perfect_hit < val)
1770                        sd->perfect_hit = val;
1771                break;
1772        case SP_PERFECT_HIT_ADD_RATE:
1773                if(sd->state.lr_flag != 2)
1774                        sd->perfect_hit_add += val;
1775                break;
1776        case SP_CRITICAL_RATE:
1777                if(sd->state.lr_flag != 2)
1778                        sd->critical_rate+=val;
1779                break;
1780        case SP_DEF_RATIO_ATK_ELE:
1781                if(val >= ELE_MAX) {
1782                        ShowError("pc_bonus: SP_DEF_RATIO_ATK_ELE: Invalid element %d\n", val);
1783                        break;
1784                }
1785                if(!sd->state.lr_flag)
1786                        sd->right_weapon.def_ratio_atk_ele |= 1<<val;
1787                else if(sd->state.lr_flag == 1)
1788                        sd->left_weapon.def_ratio_atk_ele |= 1<<val;
1789                break;
1790        case SP_DEF_RATIO_ATK_RACE:
1791                if(val >= RC_MAX) {
1792                        ShowError("pc_bonus: SP_DEF_RATIO_ATK_RACE: Invalid race %d\n", val);
1793                        break;
1794                }
1795                if(!sd->state.lr_flag)
1796                        sd->right_weapon.def_ratio_atk_race |= 1<<val;
1797                else if(sd->state.lr_flag == 1)
1798                        sd->left_weapon.def_ratio_atk_race |= 1<<val;
1799                break;
1800        case SP_HIT_RATE:
1801                if(sd->state.lr_flag != 2)
1802                        sd->hit_rate += val;
1803                break;
1804        case SP_FLEE_RATE:
1805                if(sd->state.lr_flag != 2)
1806                        sd->flee_rate += val;
1807                break;
1808        case SP_FLEE2_RATE:
1809                if(sd->state.lr_flag != 2)
1810                        sd->flee2_rate += val;
1811                break;
1812        case SP_DEF_RATE:
1813                if(sd->state.lr_flag != 2)
1814                        sd->def_rate += val;
1815                break;
1816        case SP_DEF2_RATE:
1817                if(sd->state.lr_flag != 2)
1818                        sd->def2_rate += val;
1819                break;
1820        case SP_MDEF_RATE:
1821                if(sd->state.lr_flag != 2)
1822                        sd->mdef_rate += val;
1823                break;
1824        case SP_MDEF2_RATE:
1825                if(sd->state.lr_flag != 2)
1826                        sd->mdef2_rate += val;
1827                break;
1828        case SP_RESTART_FULL_RECOVER:
1829                if(sd->state.lr_flag != 2)
1830                        sd->special_state.restart_full_recover = 1;
1831                break;
1832        case SP_NO_CASTCANCEL:
1833                if(sd->state.lr_flag != 2)
1834                        sd->special_state.no_castcancel = 1;
1835                break;
1836        case SP_NO_CASTCANCEL2:
1837                if(sd->state.lr_flag != 2)
1838                        sd->special_state.no_castcancel2 = 1;
1839                break;
1840        case SP_NO_SIZEFIX:
1841                if(sd->state.lr_flag != 2)
1842                        sd->special_state.no_sizefix = 1;
1843                break;
1844        case SP_NO_MAGIC_DAMAGE:
1845                if(sd->state.lr_flag == 2)
1846                        break;
1847                val+= sd->special_state.no_magic_damage;
1848                sd->special_state.no_magic_damage = cap_value(val,0,100);
1849                break;
1850        case SP_NO_WEAPON_DAMAGE:
1851                if(sd->state.lr_flag == 2)
1852                        break;
1853                val+= sd->special_state.no_weapon_damage;
1854                sd->special_state.no_weapon_damage = cap_value(val,0,100);
1855                break;
1856        case SP_NO_MISC_DAMAGE:
1857                if(sd->state.lr_flag == 2)
1858                        break;
1859                val+= sd->special_state.no_misc_damage;
1860                sd->special_state.no_misc_damage = cap_value(val,0,100);
1861                break;
1862        case SP_NO_GEMSTONE:
1863                if(sd->state.lr_flag != 2)
1864                        sd->special_state.no_gemstone = 1;
1865                break;
1866        case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
1867                if(sd->state.lr_flag != 2) {
1868                        sd->special_state.intravision = 1;
1869                        clif_status_load(&sd->bl, SI_INTRAVISION, 1);
1870                }
1871                break;
1872        case SP_NO_KNOCKBACK:
1873                if(sd->state.lr_flag != 2)
1874                        sd->special_state.no_knockback = 1;
1875                break;
1876        case SP_SPLASH_RANGE:
1877                if(sd->state.lr_flag != 2 && sd->splash_range < val)
1878                        sd->splash_range = val;
1879                break;
1880        case SP_SPLASH_ADD_RANGE:
1881                if(sd->state.lr_flag != 2)
1882                        sd->splash_add_range += val;
1883                break;
1884        case SP_SHORT_WEAPON_DAMAGE_RETURN:
1885                if(sd->state.lr_flag != 2)
1886                        sd->short_weapon_damage_return += val;
1887                break;
1888        case SP_LONG_WEAPON_DAMAGE_RETURN:
1889                if(sd->state.lr_flag != 2)
1890                        sd->long_weapon_damage_return += val;
1891                break;
1892        case SP_MAGIC_DAMAGE_RETURN: //AppleGirl Was Here
1893                if(sd->state.lr_flag != 2)
1894                        sd->magic_damage_return += val;
1895                break;
1896        case SP_ALL_STATS:      // [Valaris]
1897                if(sd->state.lr_flag!=2) {
1898                        sd->param_bonus[SP_STR-SP_STR]+=val;
1899                        sd->param_bonus[SP_AGI-SP_STR]+=val;
1900                        sd->param_bonus[SP_VIT-SP_STR]+=val;
1901                        sd->param_bonus[SP_INT-SP_STR]+=val;
1902                        sd->param_bonus[SP_DEX-SP_STR]+=val;
1903                        sd->param_bonus[SP_LUK-SP_STR]+=val;
1904                }
1905                break;
1906        case SP_AGI_VIT:        // [Valaris]
1907                if(sd->state.lr_flag!=2) {
1908                        sd->param_bonus[SP_AGI-SP_STR]+=val;
1909                        sd->param_bonus[SP_VIT-SP_STR]+=val;
1910                }
1911                break;
1912        case SP_AGI_DEX_STR:    // [Valaris]
1913                if(sd->state.lr_flag!=2) {
1914                        sd->param_bonus[SP_AGI-SP_STR]+=val;
1915                        sd->param_bonus[SP_DEX-SP_STR]+=val;
1916                        sd->param_bonus[SP_STR-SP_STR]+=val;
1917                }
1918                break;
1919        case SP_PERFECT_HIDE: // [Valaris]
1920                if(sd->state.lr_flag!=2)
1921                        sd->special_state.perfect_hiding=1;
1922                break;
1923        case SP_UNBREAKABLE:
1924                if(sd->state.lr_flag!=2)
1925                        sd->unbreakable += val;
1926                break;
1927        case SP_UNBREAKABLE_WEAPON:
1928                if(sd->state.lr_flag != 2)
1929                        sd->unbreakable_equip |= EQP_WEAPON;
1930                break;
1931        case SP_UNBREAKABLE_ARMOR:
1932                if(sd->state.lr_flag != 2)
1933                        sd->unbreakable_equip |= EQP_ARMOR;
1934                break;
1935        case SP_UNBREAKABLE_HELM:
1936                if(sd->state.lr_flag != 2)
1937                        sd->unbreakable_equip |= EQP_HELM;
1938                break;
1939        case SP_UNBREAKABLE_SHIELD:
1940                if(sd->state.lr_flag != 2)
1941                        sd->unbreakable_equip |= EQP_SHIELD;
1942                break;
1943        case SP_CLASSCHANGE: // [Valaris]
1944                if(sd->state.lr_flag !=2)
1945                        sd->classchange=val;
1946                break;
1947        case SP_LONG_ATK_RATE:
1948                if(sd->state.lr_flag != 2)      //[Lupus] it should stack, too. As any other cards rate bonuses
1949                        sd->long_attack_atk_rate+=val;
1950                break;
1951        case SP_BREAK_WEAPON_RATE:
1952                if(sd->state.lr_flag != 2)
1953                        sd->break_weapon_rate+=val;
1954                break;
1955        case SP_BREAK_ARMOR_RATE:
1956                if(sd->state.lr_flag != 2)
1957                        sd->break_armor_rate+=val;
1958                break;
1959        case SP_ADD_STEAL_RATE:
1960                if(sd->state.lr_flag != 2)
1961                        sd->add_steal_rate+=val;
1962                break;
1963        case SP_DELAYRATE:
1964                if(sd->state.lr_flag != 2)
1965                        sd->delayrate+=val;
1966                break;
1967        case SP_CRIT_ATK_RATE:
1968                if(sd->state.lr_flag != 2)
1969                        sd->crit_atk_rate += val;
1970                break;
1971        case SP_NO_REGEN:
1972                if(sd->state.lr_flag != 2)
1973                        sd->regen.state.block|=val;
1974                break;
1975        case SP_UNSTRIPABLE_WEAPON:
1976                if(sd->state.lr_flag != 2)
1977                        sd->unstripable_equip |= EQP_WEAPON;
1978                break;
1979        case SP_UNSTRIPABLE:
1980        case SP_UNSTRIPABLE_ARMOR:
1981                if(sd->state.lr_flag != 2)
1982                        sd->unstripable_equip |= EQP_ARMOR;
1983                break;
1984        case SP_UNSTRIPABLE_HELM:
1985                if(sd->state.lr_flag != 2)
1986                        sd->unstripable_equip |= EQP_HELM;
1987                break;
1988        case SP_UNSTRIPABLE_SHIELD:
1989                if(sd->state.lr_flag != 2)
1990                        sd->unstripable_equip |= EQP_SHIELD;
1991                break;
1992        case SP_HP_DRAIN_VALUE:
1993                if(!sd->state.lr_flag) {
1994                        sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
1995                        sd->right_weapon.hp_drain[RC_BOSS].value += val;
1996                }
1997                else if(sd->state.lr_flag == 1) {
1998                        sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
1999                        sd->right_weapon.hp_drain[RC_BOSS].value += val;
2000                }
2001                break;
2002        case SP_SP_DRAIN_VALUE:
2003                if(!sd->state.lr_flag) {
2004                        sd->right_weapon.sp_drain[RC_NONBOSS].value += val;
2005                        sd->right_weapon.sp_drain[RC_BOSS].value += val;
2006                }
2007                else if(sd->state.lr_flag == 1) {
2008                        sd->left_weapon.sp_drain[RC_NONBOSS].value += val;
2009                        sd->left_weapon.sp_drain[RC_BOSS].value += val;
2010                }
2011                break;
2012        case SP_SP_GAIN_VALUE:
2013                if(!sd->state.lr_flag)
2014                        sd->sp_gain_value += val;
2015                break;
2016        case SP_HP_GAIN_VALUE:
2017                if(!sd->state.lr_flag)
2018                        sd->hp_gain_value += val;
2019                break;
2020        default:
2021                ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
2022                break;
2023        }
2024        return 0;
2025}
2026
2027/*==========================================
2028 * ? ”õ•i‚É‚æ‚é”\—Í“™‚̃{?ƒiƒXÝ’è
2029 *------------------------------------------*/
2030int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
2031{
2032        int i;
2033
2034        nullpo_retr(0, sd);
2035
2036        switch(type){
2037        case SP_ADDELE:
2038                if(type2 >= ELE_MAX) {
2039                        ShowError("pc_bonus2: SP_ADDELE: Invalid element %d\n", type2);
2040                        break;
2041                }
2042                if(!sd->state.lr_flag)
2043                        sd->right_weapon.addele[type2]+=val;
2044                else if(sd->state.lr_flag == 1)
2045                        sd->left_weapon.addele[type2]+=val;
2046                else if(sd->state.lr_flag == 2)
2047                        sd->arrow_addele[type2]+=val;
2048                break;
2049        case SP_ADDRACE:
2050                if(!sd->state.lr_flag)
2051                        sd->right_weapon.addrace[type2]+=val;
2052                else if(sd->state.lr_flag == 1)
2053                        sd->left_weapon.addrace[type2]+=val;
2054                else if(sd->state.lr_flag == 2)
2055                        sd->arrow_addrace[type2]+=val;
2056                break;
2057        case SP_ADDSIZE:
2058                if(!sd->state.lr_flag)
2059                        sd->right_weapon.addsize[type2]+=val;
2060                else if(sd->state.lr_flag == 1)
2061                        sd->left_weapon.addsize[type2]+=val;
2062                else if(sd->state.lr_flag == 2)
2063                        sd->arrow_addsize[type2]+=val;
2064                break;
2065        case SP_SUBELE:
2066                if(type2 >= ELE_MAX) {
2067                        ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2);
2068                        break;
2069                }
2070                if(sd->state.lr_flag != 2)
2071                        sd->subele[type2]+=val;
2072                break;
2073        case SP_SUBRACE:
2074                if(sd->state.lr_flag != 2)
2075                        sd->subrace[type2]+=val;
2076                break;
2077        case SP_ADDEFF:
2078                if (type2 > SC_MAX) {
2079                        ShowWarning("pc_bonus2 (Add Effect): %d is not supported.\n", type2);
2080                        break;
2081                }
2082                pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
2083                        sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
2084                break;
2085        case SP_ADDEFF2:
2086                if (type2 > SC_MAX) {
2087                        ShowWarning("pc_bonus2 (Add Effect2): %d is not supported.\n", type2);
2088                        break;
2089                }
2090                pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
2091                        sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
2092                break;
2093        case SP_RESEFF:
2094                if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
2095                        ShowWarning("pc_bonus2 (Resist Effect): %d is not supported.\n", type2);
2096                        break;
2097                }
2098                if(sd->state.lr_flag == 2)
2099                        break;
2100                i = sd->reseff[type2-SC_COMMON_MIN]+val;
2101                sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000);
2102                break;
2103        case SP_MAGIC_ADDELE:
2104                if(type2 >= ELE_MAX) {
2105                        ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2);
2106                        break;
2107                }
2108                if(sd->state.lr_flag != 2)
2109                        sd->magic_addele[type2]+=val;
2110                break;
2111        case SP_MAGIC_ADDRACE:
2112                if(sd->state.lr_flag != 2)
2113                        sd->magic_addrace[type2]+=val;
2114                break;
2115        case SP_MAGIC_ADDSIZE:
2116                if(sd->state.lr_flag != 2)
2117                        sd->magic_addsize[type2]+=val;
2118                break;
2119        case SP_ADD_DAMAGE_CLASS:
2120                switch (sd->state.lr_flag) {
2121                case 0: //Right hand
2122                        ARR_FIND(0, ARRAYLENGTH(sd->right_weapon.add_dmg), i, sd->right_weapon.add_dmg[i].rate == 0 || sd->right_weapon.add_dmg[i].class_ == type2);
2123                        if (i == ARRAYLENGTH(sd->right_weapon.add_dmg))
2124                        {
2125                                ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->right_weapon.add_dmg));
2126                                break;
2127                        }
2128                        sd->right_weapon.add_dmg[i].class_ = type2;
2129                        sd->right_weapon.add_dmg[i].rate += val;
2130                        if (!sd->right_weapon.add_dmg[i].rate) //Shift the rest of elements up.
2131                                memmove(&sd->right_weapon.add_dmg[i], &sd->right_weapon.add_dmg[i+1], sizeof(sd->right_weapon.add_dmg) - (i+1)*sizeof(sd->right_weapon.add_dmg[0]));
2132                        break;
2133                case 1: //Left hand
2134                        ARR_FIND(0, ARRAYLENGTH(sd->left_weapon.add_dmg), i, sd->left_weapon.add_dmg[i].rate == 0 || sd->left_weapon.add_dmg[i].class_ == type2);
2135                        if (i == ARRAYLENGTH(sd->left_weapon.add_dmg))
2136                        {
2137                                ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->left_weapon.add_dmg));
2138                                break;
2139                        }
2140                        sd->left_weapon.add_dmg[i].class_ = type2;
2141                        sd->left_weapon.add_dmg[i].rate += val;
2142                        if (!sd->left_weapon.add_dmg[i].rate) //Shift the rest of elements up.
2143                                memmove(&sd->left_weapon.add_dmg[i], &sd->left_weapon.add_dmg[i+1], sizeof(sd->left_weapon.add_dmg) - (i+1)*sizeof(sd->left_weapon.add_dmg[0]));
2144                        break;
2145                }
2146                break;
2147        case SP_ADD_MAGIC_DAMAGE_CLASS:
2148                if(sd->state.lr_flag == 2)
2149                        break;
2150                ARR_FIND(0, ARRAYLENGTH(sd->add_mdmg), i, sd->add_mdmg[i].rate == 0 || sd->add_mdmg[i].class_ == type2);
2151                if (i == ARRAYLENGTH(sd->add_mdmg))
2152                {
2153                        ShowWarning("pc_bonus2: Reached max (%d) number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
2154                        break;
2155                }
2156                sd->add_mdmg[i].class_ = type2;
2157                sd->add_mdmg[i].rate += val;
2158                if (!sd->add_mdmg[i].rate) //Shift the rest of elements up.
2159                        memmove(&sd->add_mdmg[i], &sd->add_mdmg[i+1], sizeof(sd->add_mdmg) - (i+1)*sizeof(sd->add_mdmg[0]));
2160                break;
2161        case SP_ADD_DEF_CLASS:
2162                if(sd->state.lr_flag == 2)
2163                        break;
2164                ARR_FIND(0, ARRAYLENGTH(sd->add_def), i, sd->add_def[i].rate == 0 || sd->add_def[i].class_ == type2);
2165                if (i == ARRAYLENGTH(sd->add_def))
2166                {
2167                        ShowWarning("pc_bonus2: Reached max (%d) number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
2168                        break;
2169                }
2170                sd->add_def[i].class_ = type2;
2171                sd->add_def[i].rate += val;
2172                if (!sd->add_def[i].rate) //Shift the rest of elements up.
2173                        memmove(&sd->add_def[i], &sd->add_def[i+1], sizeof(sd->add_def) - (i+1)*sizeof(sd->add_def[0]));
2174                break;
2175        case SP_ADD_MDEF_CLASS:
2176                if(sd->state.lr_flag == 2)
2177                        break;
2178                ARR_FIND(0, ARRAYLENGTH(sd->add_mdef), i, sd->add_mdef[i].rate == 0 || sd->add_mdef[i].class_ == type2);
2179                if (i == ARRAYLENGTH(sd->add_mdef))
2180                {
2181                        ShowWarning("pc_bonus2: Reached max (%d) number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
2182                        break;
2183                }
2184                sd->add_mdef[i].class_ = type2;
2185                sd->add_mdef[i].rate += val;
2186                if (!sd->add_mdef[i].rate) //Shift the rest of elements up.
2187                        memmove(&sd->add_mdef[i], &sd->add_mdef[i+1], sizeof(sd->add_mdef) - (i+1)*sizeof(sd->add_mdef[0]));
2188                break;
2189        case SP_HP_DRAIN_RATE:
2190                if(!sd->state.lr_flag) {
2191                        sd->right_weapon.hp_drain[RC_NONBOSS].rate += type2;
2192                        sd->right_weapon.hp_drain[RC_NONBOSS].per += val;
2193                        sd->right_weapon.hp_drain[RC_BOSS].rate += type2;
2194                        sd->right_weapon.hp_drain[RC_BOSS].per += val;
2195                }
2196                else if(sd->state.lr_flag == 1) {
2197                        sd->left_weapon.hp_drain[RC_NONBOSS].rate += type2;
2198                        sd->left_weapon.hp_drain[RC_NONBOSS].per += val;
2199                        sd->left_weapon.hp_drain[RC_BOSS].rate += type2;
2200                        sd->left_weapon.hp_drain[RC_BOSS].per += val;
2201                }
2202                break;
2203        case SP_HP_DRAIN_VALUE:
2204                if(!sd->state.lr_flag) {
2205                        sd->right_weapon.hp_drain[RC_NONBOSS].value += type2;
2206                        sd->right_weapon.hp_drain[RC_NONBOSS].type = val;
2207                        sd->right_weapon.hp_drain[RC_BOSS].value += type2;
2208                        sd->right_weapon.hp_drain[RC_BOSS].type = val;
2209                }
2210                else if(sd->state.lr_flag == 1) {
2211                        sd->left_weapon.hp_drain[RC_NONBOSS].value += type2;
2212                        sd->left_weapon.hp_drain[RC_NONBOSS].type = val;
2213                        sd->left_weapon.hp_drain[RC_BOSS].value += type2;
2214                        sd->left_weapon.hp_drain[RC_BOSS].type = val;
2215                }
2216                break;
2217        case SP_SP_DRAIN_RATE:
2218                if(!sd->state.lr_flag) {
2219                        sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
2220                        sd->right_weapon.sp_drain[RC_NONBOSS].per += val;
2221                        sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
2222                        sd->right_weapon.sp_drain[RC_BOSS].per += val;
2223                }
2224                else if(sd->state.lr_flag == 1) {
2225                        sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
2226                        sd->left_weapon.sp_drain[RC_NONBOSS].per += val;
2227                        sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
2228                        sd->left_weapon.sp_drain[RC_BOSS].per += val;
2229                }
2230                break;
2231        case SP_SP_DRAIN_VALUE:
2232                if(!sd->state.lr_flag) {
2233                        sd->right_weapon.sp_drain[RC_NONBOSS].value += type2;
2234                        sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
2235                        sd->right_weapon.sp_drain[RC_BOSS].value += type2;
2236                        sd->right_weapon.sp_drain[RC_BOSS].type = val;
2237                }
2238                else if(sd->state.lr_flag == 1) {
2239                        sd->left_weapon.sp_drain[RC_NONBOSS].value += type2;
2240                        sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
2241                        sd->left_weapon.sp_drain[RC_BOSS].value += type2;
2242                        sd->left_weapon.sp_drain[RC_BOSS].type = val;
2243                }
2244                break;
2245        case SP_SP_VANISH_RATE:
2246                if(sd->state.lr_flag != 2) {
2247                        sd->sp_vanish_rate += type2;
2248                        sd->sp_vanish_per += val;
2249                }
2250                break;
2251        case SP_GET_ZENY_NUM:
2252                if(sd->state.lr_flag != 2 && sd->get_zeny_rate < val)
2253                {
2254                        sd->get_zeny_rate = val;
2255                        sd->get_zeny_num = type2;
2256                }
2257                break;
2258        case SP_ADD_GET_ZENY_NUM:
2259                if(sd->state.lr_flag != 2)
2260                {
2261                        sd->get_zeny_rate += val;
2262                        sd->get_zeny_num += type2;
2263                }
2264                break;
2265        case SP_WEAPON_COMA_ELE:
2266                if(type2 >= ELE_MAX) {
2267                        ShowError("pc_bonus2: SP_WEAPON_COMA_ELE: Invalid element %d\n", type2);
2268                        break;
2269                }
2270                if(sd->state.lr_flag == 2)
2271                        break;
2272                sd->weapon_coma_ele[type2] += val;
2273                sd->special_state.bonus_coma = 1;
2274                break;
2275        case SP_WEAPON_COMA_RACE:
2276                if(sd->state.lr_flag == 2)
2277                        break;
2278                sd->weapon_coma_race[type2] += val;
2279                sd->special_state.bonus_coma = 1;
2280                break;
2281        case SP_RANDOM_ATTACK_INCREASE: // [Valaris]
2282                if(sd->state.lr_flag !=2){
2283                        sd->random_attack_increase_add = type2;
2284                        sd->random_attack_increase_per += val;
2285                }
2286                break;
2287        case SP_WEAPON_ATK:
2288                if(sd->state.lr_flag != 2)
2289                        sd->weapon_atk[type2]+=val;
2290                break;
2291        case SP_WEAPON_ATK_RATE:
2292                if(sd->state.lr_flag != 2)
2293                        sd->weapon_atk_rate[type2]+=val;
2294                break;
2295        case SP_CRITICAL_ADDRACE:
2296                if(sd->state.lr_flag != 2)
2297                        sd->critaddrace[type2] += val*10;
2298                break;
2299        case SP_ADDEFF_WHENHIT:
2300                if (type2 > SC_MAX) {
2301                        ShowWarning("pc_bonus2 (Add Effect when hit): %d is not supported.\n", type2);
2302                        break;
2303                }
2304                if(sd->state.lr_flag != 2)
2305                        pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
2306                break;
2307        case SP_SKILL_ATK:
2308                if(sd->state.lr_flag == 2)
2309                        break;
2310                ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == 0 || sd->skillatk[i].id == type2);
2311                if (i == ARRAYLENGTH(sd->skillatk))
2312                {       //Better mention this so the array length can be updated. [Skotlex]
2313                        ShowDebug("run_script: bonus2 bSkillAtk reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillatk), type2, val);
2314                        break;
2315                }
2316                if (sd->skillatk[i].id == type2)
2317                        sd->skillatk[i].val += val;
2318                else {
2319                        sd->skillatk[i].id = type2;
2320                        sd->skillatk[i].val = val;
2321                }
2322                break;
2323        case SP_SKILL_HEAL:
2324                if(sd->state.lr_flag == 2)
2325                        break;
2326                ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
2327                if (i == ARRAYLENGTH(sd->skillheal))
2328                {       //Better mention this so the array length can be updated. [Skotlex]
2329                        ShowDebug("run_script: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val);
2330                        break;
2331                }
2332                if (sd->skillheal[i].id == type2)
2333                        sd->skillheal[i].val += val;
2334                else {
2335                        sd->skillheal[i].id = type2;
2336                        sd->skillheal[i].val = val;
2337                }
2338                break;
2339        case SP_ADD_SKILL_BLOW:
2340                if(sd->state.lr_flag == 2)
2341                        break;
2342                ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
2343                if (i == ARRAYLENGTH(sd->skillblown))
2344                {       //Better mention this so the array length can be updated. [Skotlex]
2345                        ShowDebug("run_script: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
2346                        break;
2347                }
2348                if(sd->skillblown[i].id == type2)
2349                        sd->skillblown[i].val += val;
2350                else {
2351                        sd->skillblown[i].id = type2;
2352                        sd->skillblown[i].val = val;
2353                }
2354                break;
2355
2356        case SP_CASTRATE:
2357                if(sd->state.lr_flag == 2)
2358                        break;
2359                ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
2360                if (i == ARRAYLENGTH(sd->skillcast))
2361                {       //Better mention this so the array length can be updated. [Skotlex]
2362                        ShowDebug("run_script: bonus2 bCastRate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcast), type2, val);
2363                        break;
2364                }
2365                if(sd->skillcast[i].id == type2)
2366                        sd->skillcast[i].val += val;
2367                else {
2368                        sd->skillcast[i].id = type2;
2369                        sd->skillcast[i].val = val;
2370                }
2371                break;
2372
2373        case SP_HP_LOSS_RATE:
2374                if(sd->state.lr_flag != 2) {
2375                        sd->hp_loss.value = type2;
2376                        sd->hp_loss.rate = val;
2377                }
2378                break;
2379        case SP_HP_REGEN_RATE:
2380                if(sd->state.lr_flag != 2) {
2381                        sd->hp_regen.value = type2;
2382                        sd->hp_regen.rate = val;
2383                }
2384                break;
2385        case SP_ADDRACE2:
2386                if (!(type2 > 0 && type2 < MAX_MOB_RACE_DB))
2387                        break;
2388                if(sd->state.lr_flag != 2)
2389                        sd->right_weapon.addrace2[type2] += val;
2390                else
2391                        sd->left_weapon.addrace2[type2] += val;
2392                break;
2393        case SP_SUBSIZE:
2394                if(sd->state.lr_flag != 2)
2395                        sd->subsize[type2]+=val;
2396                break;
2397        case SP_SUBRACE2:
2398                if(sd->state.lr_flag != 2)
2399                        sd->subrace2[type2]+=val;
2400                break;
2401        case SP_ADD_ITEM_HEAL_RATE:
2402                if(sd->state.lr_flag == 2)
2403                        break;
2404                if (type2 < MAX_ITEMGROUP) {    //Group bonus
2405                        sd->itemgrouphealrate[type2] += val;
2406                        break;
2407                }
2408                //Standard item bonus.
2409                for(i=0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid && sd->itemhealrate[i].nameid != type2; i++);
2410                if(i == ARRAYLENGTH(sd->itemhealrate)) {
2411                        ShowWarning("pc_bonus2: Reached max (%d) number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
2412                        break;
2413                }
2414                sd->itemhealrate[i].nameid = type2;
2415                sd->itemhealrate[i].rate += val;
2416                break;
2417        case SP_EXP_ADDRACE:
2418                if(sd->state.lr_flag != 2)
2419                        sd->expaddrace[type2]+=val;
2420                break;
2421        case SP_SP_GAIN_RACE:
2422                if(sd->state.lr_flag != 2)
2423                        sd->sp_gain_race[type2]+=val;
2424                break;
2425        case SP_ADD_MONSTER_DROP_ITEM:
2426                if (sd->state.lr_flag != 2)
2427                        pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
2428                break;
2429        case SP_ADD_MONSTER_DROP_ITEMGROUP:
2430                if (sd->state.lr_flag != 2)
2431                        pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
2432                break;
2433        case SP_SP_LOSS_RATE:
2434                if(sd->state.lr_flag != 2) {
2435                        sd->sp_loss.value = type2;
2436                        sd->sp_loss.rate = val;
2437                }
2438                break;
2439        case SP_SP_REGEN_RATE:
2440                if(sd->state.lr_flag != 2) {
2441                        sd->sp_regen.value = type2;
2442                        sd->sp_regen.rate = val;
2443                }
2444                break;
2445        case SP_HP_DRAIN_VALUE_RACE:
2446                if(!sd->state.lr_flag) {
2447                        sd->right_weapon.hp_drain[type2].value += val;
2448                }
2449                else if(sd->state.lr_flag == 1) {
2450                        sd->left_weapon.hp_drain[type2].value += val;
2451                }
2452                break;
2453        case SP_SP_DRAIN_VALUE_RACE:
2454                if(!sd->state.lr_flag) {
2455                        sd->right_weapon.sp_drain[type2].value += val;
2456                }
2457                else if(sd->state.lr_flag == 1) {
2458                        sd->left_weapon.sp_drain[type2].value += val;
2459                }
2460                break;
2461        case SP_IGNORE_MDEF_RATE:
2462                if(sd->state.lr_flag != 2)
2463                        sd->ignore_mdef[type2] += val;
2464                break;
2465
2466        default:
2467                ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
2468                break;
2469        }
2470        return 0;
2471}
2472
2473int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
2474{
2475        nullpo_retr(0, sd);
2476
2477        switch(type){
2478        case SP_ADD_MONSTER_DROP_ITEM:
2479                if(sd->state.lr_flag != 2)
2480                        pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, 1<<type3, val);
2481                break;
2482        case SP_AUTOSPELL:
2483                if(sd->state.lr_flag != 2)
2484                {
2485                        int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
2486                        target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
2487                        pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell),
2488                                target?-type2:type2, type3, val, 0, current_equip_card_id);
2489                }
2490                break;
2491        case SP_AUTOSPELL_WHENHIT:
2492                if(sd->state.lr_flag != 2)
2493                {
2494                        int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
2495                        target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF));
2496                        pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2),
2497                                target?-type2:type2, type3, val, 0, current_equip_card_id);
2498                }
2499                break;
2500        case SP_SP_DRAIN_RATE:
2501                if(!sd->state.lr_flag) {
2502                        sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
2503                        sd->right_weapon.sp_drain[RC_NONBOSS].per += type3;
2504                        sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
2505                        sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
2506                        sd->right_weapon.sp_drain[RC_BOSS].per += type3;
2507                        sd->right_weapon.sp_drain[RC_BOSS].type = val;
2508
2509                }
2510                else if(sd->state.lr_flag == 1) {
2511                        sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
2512                        sd->left_weapon.sp_drain[RC_NONBOSS].per += type3;
2513                        sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
2514                        sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
2515                        sd->left_weapon.sp_drain[RC_BOSS].per += type3;
2516                        sd->left_weapon.sp_drain[RC_BOSS].type = val;
2517                }
2518                break;
2519        case SP_HP_DRAIN_RATE_RACE:
2520                if(!sd->state.lr_flag) {
2521                        sd->right_weapon.hp_drain[type2].rate += type3;
2522                        sd->right_weapon.hp_drain[type2].per += val;
2523                }
2524                else if(sd->state.lr_flag == 1) {
2525                        sd->left_weapon.hp_drain[type2].rate += type3;
2526                        sd->left_weapon.hp_drain[type2].per += val;
2527                }
2528                break;
2529        case SP_SP_DRAIN_RATE_RACE:
2530                if(!sd->state.lr_flag) {
2531                        sd->right_weapon.sp_drain[type2].rate += type3;
2532                        sd->right_weapon.sp_drain[type2].per += val;
2533                }
2534                else if(sd->state.lr_flag == 1) {
2535                        sd->left_weapon.sp_drain[type2].rate += type3;
2536                        sd->left_weapon.sp_drain[type2].per += val;
2537                }
2538                break;
2539        case SP_ADD_MONSTER_DROP_ITEMGROUP:
2540                if (sd->state.lr_flag != 2)
2541                        pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, 1<<type3, val);
2542                break;
2543
2544        case SP_ADDEFF:
2545                if (type2 > SC_MAX) {
2546                        ShowWarning("pc_bonus3 (Add Effect): %d is not supported.\n", type2);
2547                        break;
2548                }
2549                pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
2550                        sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
2551                break;
2552
2553        case SP_ADDEFF_WHENHIT:
2554                if (type2 > SC_MAX) {
2555                        ShowWarning("pc_bonus3 (Add Effect when hit): %d is not supported.\n", type2);
2556                        break;
2557                }
2558                if(sd->state.lr_flag != 2)
2559                        pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
2560                break;
2561
2562        default:
2563                ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
2564                break;
2565        }
2566
2567        return 0;
2568}
2569
2570int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val)
2571{
2572        nullpo_retr(0, sd);
2573
2574        switch(type){
2575        case SP_AUTOSPELL:
2576                if(sd->state.lr_flag != 2)
2577                        pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, 0, current_equip_card_id);
2578                break;
2579
2580        case SP_AUTOSPELL_WHENHIT:
2581                if(sd->state.lr_flag != 2)
2582                        pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, 0, current_equip_card_id);
2583                break;
2584        default:
2585                ShowWarning("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val);
2586                break;
2587        }
2588
2589        return 0;
2590}
2591
2592int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4,int type5,int val)
2593{
2594        nullpo_retr(0, sd);
2595
2596        switch(type){
2597        case SP_AUTOSPELL:
2598                if(sd->state.lr_flag != 2)
2599                        pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
2600                break;
2601
2602        case SP_AUTOSPELL_WHENHIT:
2603                if(sd->state.lr_flag != 2)
2604                        pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
2605                break;
2606        default:
2607                ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
2608                break;
2609        }
2610
2611        return 0;
2612}
2613
2614/*==========================================
2615 *      Grants a player a given skill. Flag values are:
2616 *      0 - Grant skill unconditionally and forever (only this one invokes status_calc_pc,
2617 *          as the other two are assumed to be invoked from within it)
2618 *      1 - Grant an item skill (temporary)
2619 *      2 - Like 1, except the level granted can stack with previously learned level.
2620 *------------------------------------------*/
2621int pc_skill(TBL_PC* sd, int id, int level, int flag)
2622{
2623        nullpo_retr(0, sd);
2624
2625        if( id <= 0 || id >= MAX_SKILL || skill_db[id].name == NULL) {
2626                ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", id);
2627                return 0;
2628        }
2629        if( level > MAX_SKILL_LEVEL ) {
2630                ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL);
2631                return 0;
2632        }
2633
2634        switch( flag ){
2635        case 0: //Set skill data overwriting whatever was there before.
2636                sd->status.skill[id].id   = id;
2637                sd->status.skill[id].lv   = level;
2638                sd->status.skill[id].flag = 0;
2639                if( !level ) //Remove skill.
2640                        sd->status.skill[id].id = 0;
2641                if( !skill_get_inf(id) ) //Only recalculate for passive skills.
2642                        status_calc_pc(sd, 0);
2643                clif_skillinfoblock(sd);
2644        break;
2645        case 2: //Add skill bonus on top of what you had.
2646                if( sd->status.skill[id].id == id ){
2647                        if( !sd->status.skill[id].flag ) // Store previous level.
2648                                sd->status.skill[id].flag = sd->status.skill[id].lv + 2;
2649                } else {
2650                        sd->status.skill[id].id   = id;
2651                        sd->status.skill[id].flag = 1; //Set that this is a bonus skill.
2652                }
2653                sd->status.skill[id].lv += level;
2654        break;
2655        case 1: //Item bonus skill.
2656                if( sd->status.skill[id].lv >= level )
2657                        return 0;
2658                if( sd->status.skill[id].id == id ){
2659                        if( !sd->status.skill[id].flag ) //Non-granted skill, store it's level.
2660                                sd->status.skill[id].flag = sd->status.skill[id].lv + 2;
2661                } else {
2662                        sd->status.skill[id].id   = id;
2663                        sd->status.skill[id].flag = 1;
2664                }
2665                sd->status.skill[id].lv = level;
2666        break;
2667        default: //Unknown flag?
2668                return 0;
2669        }
2670        return 1;
2671}
2672/*==========================================
2673 * ƒJ?ƒh?“ü
2674 *------------------------------------------*/
2675int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip)
2676{
2677        int i, ep;
2678        int nameid, cardid;
2679
2680        nullpo_retr(0, sd);
2681
2682        if(idx_card < 0 || idx_card >= MAX_INVENTORY || !sd->inventory_data[idx_card])
2683                return 0; //Invalid card index.
2684
2685        if(idx_equip < 0 || idx_equip >= MAX_INVENTORY || !sd->inventory_data[idx_equip])
2686                return 0; //Invalid item index.
2687
2688        nameid=sd->status.inventory[idx_equip].nameid;
2689        cardid=sd->status.inventory[idx_card].nameid;
2690        ep=sd->inventory_data[idx_card]->equip;
2691
2692        //Check validity
2693        if( nameid <= 0 || cardid <= 0 ||
2694                sd->status.inventory[idx_equip].amount < 1 || //These two should never be required due to pc_delitem zero'ing the data.
2695                sd->status.inventory[idx_card].amount < 1 ||
2696                (sd->inventory_data[idx_equip]->type!=IT_WEAPON && sd->inventory_data[idx_equip]->type!=IT_ARMOR)||
2697                sd->inventory_data[idx_card]->type!=IT_CARD || // Prevent Hack [Ancyker]
2698                sd->status.inventory[idx_equip].identify==0 ||
2699                itemdb_isspecial(sd->status.inventory[idx_equip].card[0]) ||
2700                !(sd->inventory_data[idx_equip]->equip&ep) ||
2701                (sd->inventory_data[idx_equip]->type==IT_WEAPON && ep==EQP_SHIELD) || //Card shield attempted to place on left-hand weapon.
2702                sd->status.inventory[idx_equip].equip){
2703
2704                clif_insert_card(sd,idx_equip,idx_card,1);
2705                return 0;
2706        }
2707        for(i=0;i<sd->inventory_data[idx_equip]->slot;i++){
2708                if( sd->status.inventory[idx_equip].card[i] == 0)
2709                {       //Free slot found.
2710                        sd->status.inventory[idx_equip].card[i]=cardid;
2711                        clif_insert_card(sd,idx_equip,idx_card,0);
2712                        pc_delitem(sd,idx_card,1,1);
2713                        return 0;
2714                }
2715        }
2716        clif_insert_card(sd,idx_equip,idx_card,1);
2717        return 0;
2718}
2719
2720//
2721// ƒAƒCƒeƒ€•š
2722//
2723
2724/*==========================================
2725 * ƒXƒLƒ‹‚É‚æ‚锃‚¢’lC³
2726 *------------------------------------------*/
2727int pc_modifybuyvalue(struct map_session_data *sd,int orig_value)
2728{
2729        int skill,val = orig_value,rate1 = 0,rate2 = 0;
2730        if((skill=pc_checkskill(sd,MC_DISCOUNT))>0)     // ƒfƒBƒXƒJƒEƒ“ƒg
2731                rate1 = 5+skill*2-((skill==10)? 1:0);
2732        if((skill=pc_checkskill(sd,RG_COMPULSION))>0)   // ƒRƒ€ƒpƒ‹ƒVƒ‡ƒ“ƒfƒBƒXƒJƒEƒ“ƒg
2733                rate2 = 5+skill*4;
2734        if(rate1 < rate2) rate1 = rate2;
2735        if(rate1)
2736                val = (int)((double)orig_value*(double)(100-rate1)/100.);
2737        if(val < 0) val = 0;
2738        if(orig_value > 0 && val < 1) val = 1;
2739
2740        return val;
2741}
2742
2743/*==========================================
2744 * ƒXƒLƒ‹‚É‚æ‚é?‚è’lC³
2745 *------------------------------------------*/
2746int pc_modifysellvalue(struct map_session_data *sd,int orig_value)
2747{
2748        int skill,val = orig_value,rate = 0;
2749        if((skill=pc_checkskill(sd,MC_OVERCHARGE))>0)   // ƒI?ƒo?ƒ`ƒƒ?ƒW
2750                rate = 5+skill*2-((skill==10)? 1:0);
2751        if(rate)
2752                val = (int)((double)orig_value*(double)(100+rate)/100.);
2753        if(val < 0) val = 0;
2754        if(orig_value > 0 && val < 1) val = 1;
2755
2756        return val;
2757}
2758
2759/*==========================================
2760 * ƒAƒCƒeƒ€‚𔃂Á‚œŽbɁAV‚µ‚¢ƒAƒCƒeƒ€—“‚ðŽg‚€‚©A
2761 * 3–œŒÂ§ŒÀ‚É‚©‚©‚é‚©Šm”F
2762 *------------------------------------------*/
2763int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
2764{
2765        int i;
2766
2767        nullpo_retr(0, sd);
2768
2769        if(!itemdb_isstackable(nameid))
2770                return ADDITEM_NEW;
2771
2772        for(i=0;i<MAX_INVENTORY;i++){
2773                if(sd->status.inventory[i].nameid==nameid){
2774                        if(sd->status.inventory[i].amount+amount > MAX_AMOUNT)
2775                                return ADDITEM_OVERAMOUNT;
2776                        return ADDITEM_EXIST;
2777                }
2778        }
2779
2780        if(amount > MAX_AMOUNT)
2781                return ADDITEM_OVERAMOUNT;
2782        return ADDITEM_NEW;
2783}
2784
2785/*==========================================
2786 * ‹ó‚«ƒAƒCƒeƒ€—“‚ÌŒÂ?
2787 *------------------------------------------*/
2788int pc_inventoryblank(struct map_session_data *sd)
2789{
2790        int i,b;
2791
2792        nullpo_retr(0, sd);
2793
2794        for(i=0,b=0;i<MAX_INVENTORY;i++){
2795                if(sd->status.inventory[i].nameid==0)
2796                        b++;
2797        }
2798
2799        return b;
2800}
2801
2802/*==========================================
2803 * ‚š‹à‚ð?‚€
2804 *------------------------------------------*/
2805int pc_payzeny(struct map_session_data *sd,int zeny)
2806{
2807        nullpo_retr(0, sd);
2808
2809        if( zeny < 0 )
2810                return pc_getzeny(sd, -zeny);
2811
2812        if( sd->status.zeny < zeny )
2813                return 1; //Not enough.
2814
2815        sd->status.zeny -= zeny;
2816        clif_updatestatus(sd,SP_ZENY);
2817
2818        return 0;
2819}
2820/*==========================================
2821 * Cash Shop
2822 *------------------------------------------*/
2823
2824void pc_paycash(struct map_session_data *sd, int price, int points)
2825{
2826        char output[128];
2827        int cash = price - points;
2828        nullpo_retv(sd);
2829
2830        pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints - cash);
2831        pc_setaccountreg(sd,"#KAFRAPOINTS",sd->kafraPoints - points);
2832        sprintf(output, "Used %d kafra points and %d cash points. %d kafra and %d cash points remaining.", points, cash, sd->kafraPoints, sd->cashPoints);
2833        clif_disp_onlyself(sd, output, strlen(output));
2834}
2835
2836void pc_getcash(struct map_session_data *sd, int cash, int points)
2837{
2838        char output[128];
2839        nullpo_retv(sd);
2840
2841        if( cash > 0 )
2842        {
2843                pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints + cash);
2844
2845                sprintf(output, "Gained %d cash points. Total %d points", cash, sd->cashPoints);
2846                clif_disp_onlyself(sd, output, strlen(output));
2847        }
2848
2849        if( points > 0 )
2850        {
2851                pc_setaccountreg(sd,"#KAFRAPOINTS",sd->kafraPoints + points);
2852
2853                sprintf(output, "Gained %d kafra points. Total %d points", points, sd->kafraPoints);
2854                clif_disp_onlyself(sd, output, strlen(output));
2855        }
2856}
2857
2858/*==========================================
2859 * ‚š‹à‚𓟂é
2860 *------------------------------------------*/
2861int pc_getzeny(struct map_session_data *sd,int zeny)
2862{
2863        nullpo_retr(0, sd);
2864
2865        if( zeny < 0 )
2866                return pc_payzeny(sd, -zeny);
2867
2868        if( zeny > MAX_ZENY - sd->status.zeny )
2869                zeny = MAX_ZENY - sd->status.zeny;
2870
2871        sd->status.zeny += zeny;
2872        clif_updatestatus(sd,SP_ZENY);
2873
2874        if( zeny > 0 && sd->state.showzeny )
2875        {
2876                char output[255];
2877                sprintf(output, "Gained %dz.", zeny);
2878                clif_disp_onlyself(sd,output,strlen(output));
2879        }
2880
2881        return 0;
2882}
2883
2884/*==========================================
2885 * ƒAƒCƒeƒ€‚ð’T‚µ‚āAƒCƒ“ƒfƒbƒNƒX‚ð•Ô‚·
2886 *------------------------------------------*/
2887int pc_search_inventory(struct map_session_data *sd,int item_id)
2888{
2889        int i;
2890        nullpo_retr(-1, sd);
2891
2892        ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0) );
2893        return ( i < MAX_INVENTORY ) ? i : -1;
2894}
2895
2896/*==========================================
2897 * ƒAƒCƒeƒ€’ljÁBŒÂ?‚Ì‚Ýitem\‘¢?‚Ì?Žš‚𖳎‹
2898 *------------------------------------------*/
2899int pc_additem(struct map_session_data *sd,struct item *item_data,int amount)
2900{
2901        struct item_data *data;
2902        int i;
2903        unsigned int w;
2904
2905        nullpo_retr(1, sd);
2906        nullpo_retr(1, item_data);
2907
2908        if(item_data->nameid <= 0 || amount <= 0)
2909                return 1;
2910        if(amount > MAX_AMOUNT)
2911                return 5;
2912
2913        data = itemdb_search(item_data->nameid);
2914        w = data->weight*amount;
2915        if(sd->weight + w > sd->max_weight)
2916                return 2;
2917
2918        i = MAX_INVENTORY;
2919
2920        if (itemdb_isstackable2(data))
2921        { //Stackable
2922                for (i = 0; i < MAX_INVENTORY; i++)
2923                {
2924                        if(sd->status.inventory[i].nameid == item_data->nameid &&
2925                                memcmp(&sd->status.inventory[i].card,&item_data->card,
2926                                        sizeof(item_data->card))==0)
2927                        {
2928                                if (amount > MAX_AMOUNT - sd->status.inventory[i].amount)
2929                                        return 5;
2930                                sd->status.inventory[i].amount += amount;
2931                                clif_additem(sd,i,amount,0);
2932                                break;
2933                        }
2934                }
2935        }
2936        if (i >= MAX_INVENTORY){
2937                i = pc_search_inventory(sd,0);
2938                if(i<0) return 4;
2939                memcpy(&sd->status.inventory[i], item_data, sizeof(sd->status.inventory[0]));
2940                // clear equips field first, just in case
2941                if (item_data->equip)
2942                        sd->status.inventory[i].equip = 0;
2943
2944                sd->status.inventory[i].amount = amount;
2945                sd->inventory_data[i] = data;
2946                clif_additem(sd,i,amount,0);
2947        }
2948
2949        sd->weight += w;
2950        clif_updatestatus(sd,SP_WEIGHT);
2951        //Auto-equip
2952        if(data->flag.autoequip) pc_equipitem(sd, i, data->equip);
2953        return 0;
2954}
2955
2956/*==========================================
2957 * ƒAƒCƒeƒ€‚ðŒž‚ç‚·
2958 *------------------------------------------*/
2959int pc_delitem(struct map_session_data *sd,int n,int amount,int type)
2960{
2961        nullpo_retr(1, sd);
2962
2963        if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL)
2964                return 1;
2965
2966        sd->status.inventory[n].amount -= amount;
2967        sd->weight -= sd->inventory_data[n]->weight*amount ;
2968        if(sd->status.inventory[n].amount<=0){
2969                if(sd->status.inventory[n].equip)
2970                        pc_unequipitem(sd,n,3);
2971                memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
2972                sd->inventory_data[n] = NULL;
2973        }
2974        if(!(type&1))
2975                clif_delitem(sd,n,amount);
2976        if(!(type&2))
2977                clif_updatestatus(sd,SP_WEIGHT);
2978
2979        return 0;
2980}
2981
2982/*==========================================
2983 * ƒAƒCƒeƒ€‚ð—Ž‚·
2984 *------------------------------------------*/
2985int pc_dropitem(struct map_session_data *sd,int n,int amount)
2986{
2987        nullpo_retr(1, sd);
2988
2989        if(n < 0 || n >= MAX_INVENTORY)
2990                return 0;
2991
2992        if(amount <= 0)
2993                return 0;
2994
2995        if(sd->status.inventory[n].nameid <= 0 ||
2996                sd->status.inventory[n].amount <= 0 ||
2997                sd->status.inventory[n].amount < amount ||
2998                sd->state.trading || sd->vender_id != 0 ||
2999                !sd->inventory_data[n] //pc_delitem would fail on this case.
3000                )
3001                return 0;
3002
3003        if (map[sd->bl.m].flag.nodrop) {
3004                clif_displaymessage (sd->fd, msg_txt(271));
3005                return 0; //Can't drop items in nodrop mapflag maps.
3006        }
3007
3008        if (!pc_candrop(sd,&sd->status.inventory[n])) {
3009                clif_displaymessage (sd->fd, msg_txt(263));
3010                return 0;
3011        }
3012
3013        //Logs items, dropped by (P)layers [Lupus]
3014        if(log_config.enable_logs&0x8)
3015                log_pick_pc(sd, "P", sd->status.inventory[n].nameid, -amount, (struct item*)&sd->status.inventory[n]);
3016        //Logs
3017
3018        if (!map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2))
3019                return 0;
3020
3021        pc_delitem(sd, n, amount, 0);
3022        return 1;
3023}
3024
3025/*==========================================
3026 * ƒAƒCƒeƒ€‚ðE‚€
3027 *------------------------------------------*/
3028int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
3029{
3030        int flag=0;
3031        unsigned int tick = gettick();
3032        struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL;
3033        struct party_data *p=NULL;
3034
3035        nullpo_retr(0, sd);
3036        nullpo_retr(0, fitem);
3037
3038        if(!check_distance_bl(&fitem->bl, &sd->bl, 2) && sd->ud.skillid!=BS_GREED)
3039                return 0;       // ‹——£‚ª‰“‚¢
3040
3041        if (sd->status.party_id)
3042                p = party_search(sd->status.party_id);
3043
3044        if(fitem->first_get_charid > 0 && fitem->first_get_charid != sd->status.char_id)
3045        {
3046                first_sd = map_charid2sd(fitem->first_get_charid);
3047                if(DIFF_TICK(tick,fitem->first_get_tick) < 0) {
3048                        if (!(p && p->party.item&1 &&
3049                                first_sd && first_sd->status.party_id == sd->status.party_id
3050                        ))
3051                                return 0;
3052                }
3053                else
3054                if(fitem->second_get_charid > 0 && fitem->second_get_charid != sd->status.char_id)
3055                {
3056                        second_sd = map_charid2sd(fitem->second_get_charid);
3057                        if(DIFF_TICK(tick, fitem->second_get_tick) < 0) {
3058                                if(!(p && p->party.item&1 &&
3059                                        ((first_sd && first_sd->status.party_id == sd->status.party_id) ||
3060                                        (second_sd && second_sd->status.party_id == sd->status.party_id))
3061                                ))
3062                                        return 0;
3063                        }
3064                        else
3065                        if(fitem->third_get_charid > 0 && fitem->third_get_charid != sd->status.char_id)
3066                        {
3067                                third_sd = map_charid2sd(fitem->third_get_charid);
3068                                if(DIFF_TICK(tick,fitem->third_get_tick) < 0) {
3069                                        if(!(p && p->party.item&1 &&
3070                                                ((first_sd && first_sd->status.party_id == sd->status.party_id) ||
3071                                                (second_sd && second_sd->status.party_id == sd->status.party_id) ||
3072                                                (third_sd && third_sd->status.party_id == sd->status.party_id))
3073                                        ))
3074                                                return 0;
3075                                }
3076                        }
3077                }
3078        }
3079
3080        //This function takes care of giving the item to whoever should have it, considering party-share options.
3081        if ((flag = party_share_loot(p,sd,&fitem->item_data, fitem->first_get_charid))) {
3082                clif_additem(sd,0,0,flag);
3083                return 1;
3084        }
3085
3086        //Display pickup animation.
3087        pc_stop_attack(sd);
3088        clif_takeitem(&sd->bl,&fitem->bl);
3089        map_clearflooritem(fitem->bl.id);
3090        return 1;
3091}
3092
3093int pc_isUseitem(struct map_session_data *sd,int n)
3094{
3095        struct item_data *item;
3096        int nameid;
3097
3098        nullpo_retr(0, sd);
3099
3100        item = sd->inventory_data[n];
3101        nameid = sd->status.inventory[n].nameid;
3102
3103        if(item == NULL)
3104                return 0;
3105        //Not consumable item
3106        if(item->type != IT_HEALING && item->type != IT_USABLE)
3107                return 0;
3108        if(!item->script) //if it has no script, you can't really consume it!
3109                return 0;
3110        //Anodyne (can't use Anodyne's Endure at GVG)
3111        if(nameid == 605 && map_flag_gvg(sd->bl.m))
3112                return 0;
3113        //Fly Wing/Giant Fly Wing (can't use at GVG and when noteleport flag is on)
3114        if((nameid == 601 || nameid == 12212) && (map[sd->bl.m].flag.noteleport || map_flag_gvg(sd->bl.m))) {
3115                clif_skill_teleportmessage(sd,0);
3116                return 0;
3117        }
3118        //Fly Wing/Butterfly Wing/Giant Fly Wing (can't use when you in duel) [LuzZza]
3119        if((nameid == 601 || nameid == 602 || nameid == 12212) && (!battle_config.duel_allow_teleport && sd->duel_group)) {
3120                clif_displaymessage(sd->fd, "Duel: Can't use this item in duel.");
3121                return 0;
3122        }
3123        //Butterfly Wing (can't use noreturn flag is on)
3124        if(nameid == 602 && map[sd->bl.m].flag.noreturn)
3125                return 0;
3126        //Dead Branch & Red Pouch & Bloody Branch & Poring Box (can't use at GVG and when nobranch flag is on)
3127        if((nameid == 604 || nameid == 12024 || nameid == 12103 || nameid == 12109) && (map[sd->bl.m].flag.nobranch || map_flag_gvg(sd->bl.m)))
3128                return 0;
3129
3130        //Anodyne/Aleovera not usable while sitting.
3131        if ((nameid == 605 || nameid == 606) && pc_issit(sd))
3132                return 0;
3133
3134        //added item_noequip.txt items check by Maya&[Lupus]
3135        if (
3136                (map[sd->bl.m].flag.pvp && item->flag.no_equip&1) || // PVP
3137                (map_flag_gvg(sd->bl.m) && item->flag.no_equip&2) || // GVG
3138                (map[sd->bl.m].flag.restricted && item->flag.no_equip&map[sd->bl.m].zone) // Zone restriction
3139        )
3140                return 0;
3141
3142        //Gender check
3143        if(item->sex != 2 && sd->status.sex != item->sex)
3144                return 0;
3145        //Required level check
3146        if(item->elv && sd->status.base_level < (unsigned int)item->elv)
3147                return 0;
3148
3149        //Not equipable by class. [Skotlex]
3150        if (!(
3151                (1<<(sd->class_&MAPID_BASEMASK)) &
3152                (item->class_base[sd->class_&JOBL_2_1?1:(sd->class_&JOBL_2_2?2:0)])
3153        ))
3154                return 0;
3155
3156        //Not usable by upper class. [Skotlex]
3157        if(!(
3158                (1<<(sd->class_&JOBL_UPPER?1:(sd->class_&JOBL_BABY?2:0))) &
3159                item->class_upper
3160        ))
3161                return 0;
3162
3163        //Dead Branch & Bloody Branch & Porings Box
3164        if((log_config.branch > 0) && (nameid == 604 || nameid == 12103 || nameid == 12109))
3165                log_branch(sd);
3166
3167        return 1;
3168}
3169
3170/*==========================================
3171 * ƒAƒCƒeƒ€‚ðŽg‚€
3172 *------------------------------------------*/
3173int pc_useitem(struct map_session_data *sd,int n)
3174{
3175        unsigned int tick = gettick();
3176        int amount;
3177        struct script_code *script;
3178
3179        nullpo_retr(0, sd);
3180
3181        if(sd->status.inventory[n].nameid <= 0 ||
3182                sd->status.inventory[n].amount <= 0)
3183                return 0;
3184
3185        if(!pc_isUseitem(sd,n))
3186                return 0;
3187
3188         //Prevent mass item usage. [Skotlex]
3189        if(DIFF_TICK(sd->canuseitem_tick, tick) > 0)
3190                return 0;
3191
3192        if (sd->sc.count && (
3193                sd->sc.data[SC_BERSERK] ||
3194                sd->sc.data[SC_MARIONETTE] ||
3195                (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) ||
3196                sd->sc.data[SC_TRICKDEAD] ||
3197                sd->sc.data[SC_BLADESTOP] ||
3198                sd->sc.data[SC_HIDING] ||
3199                (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
3200        ))
3201                return 0;
3202
3203        //Since most delay-consume items involve using a "skill-type" target cursor,
3204        //perform a skill-use check before going through. [Skotlex]
3205        //resurrection was picked as testing skill, as a non-offensive, generic skill, it will do.
3206        if (sd->inventory_data[n]->flag.delay_consume && (
3207                sd->ud.skilltimer != -1 ||
3208                DIFF_TICK(tick, sd->ud.canact_tick) < 0 ||
3209                !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)))
3210                return 0;
3211
3212        sd->itemid = sd->status.inventory[n].nameid;
3213        sd->itemindex = n;
3214        if(sd->catch_target_class != -1) //Abort pet catching.
3215                sd->catch_target_class = -1;
3216
3217        amount = sd->status.inventory[n].amount;
3218        script = sd->inventory_data[n]->script;
3219        //Check if the item is to be consumed immediately [Skotlex]
3220        if (sd->inventory_data[n]->flag.delay_consume)
3221                clif_useitemack(sd,n,amount,1);
3222        else {
3223                clif_useitemack(sd,n,amount-1,1);
3224                //Logs (C)onsumable items [Lupus]
3225                if(log_config.enable_logs&0x100)
3226                        log_pick_pc(sd, "C", sd->status.inventory[n].nameid, -1, &sd->status.inventory[n]);
3227                //Logs
3228                pc_delitem(sd,n,1,1);
3229        }
3230        if(sd->status.inventory[n].card[0]==CARD0_CREATE &&
3231                pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST))
3232        {
3233            potion_flag = 2; // Famous player's potions have 50% more efficiency
3234                 if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE)
3235                         potion_flag = 3; //Even more effective potions.
3236        }
3237
3238        sd->canuseitem_tick= tick + battle_config.item_use_interval; //Update item use time.
3239        run_script(script,0,sd->bl.id,fake_nd->bl.id);
3240        potion_flag = 0;
3241        return 1;
3242}
3243
3244/*==========================================
3245 * ƒJ?ƒgƒAƒCƒeƒ€’ljÁBŒÂ?‚Ì‚Ýitem\‘¢?‚Ì?Žš‚𖳎‹
3246 *------------------------------------------*/
3247int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount)
3248{
3249        struct item_data *data;
3250        int i,w;
3251
3252        nullpo_retr(1, sd);
3253        nullpo_retr(1, item_data);
3254
3255        if(item_data->nameid <= 0 || amount <= 0)
3256                return 1;
3257        data = itemdb_search(item_data->nameid);
3258
3259        if(!itemdb_cancartstore(item_data, pc_isGM(sd)))
3260        {       //Check item trade restrictions [Skotlex]
3261                clif_displaymessage (sd->fd, msg_txt(264));
3262                return 1;
3263        }
3264
3265        if((w=data->weight*amount) + sd->cart_weight > battle_config.max_cart_weight)
3266                return 1;
3267
3268        i=MAX_CART;
3269        if(itemdb_isstackable2(data))
3270        {
3271                ARR_FIND( 0, MAX_CART, i,
3272                        sd->status.cart[i].nameid == item_data->nameid &&
3273                        sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] &&
3274                        sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3] );
3275        };
3276
3277        if( i < MAX_CART )
3278        {// item already in cart, stack it
3279                if(sd->status.cart[i].amount+amount > MAX_AMOUNT)
3280                        return 1; // no room
3281
3282                sd->status.cart[i].amount+=amount;
3283                clif_cart_additem(sd,i,amount,0);
3284        }
3285        else
3286        {// item not stackable or not present, add it
3287                ARR_FIND( 0, MAX_CART, i, sd->status.cart[i].nameid == 0 );
3288                if( i == MAX_CART )
3289                        return 1; // no room
3290
3291                memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0]));
3292                sd->status.cart[i].amount=amount;
3293                sd->cart_num++;
3294                clif_cart_additem(sd,i,amount,0);
3295        }
3296
3297        sd->cart_weight += w;
3298        clif_updatestatus(sd,SP_CARTINFO);
3299
3300        return 0;
3301}
3302
3303/*==========================================
3304 * ƒJ?ƒgƒAƒCƒeƒ€‚ðŒž‚ç‚·
3305 *------------------------------------------*/
3306int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type)
3307{
3308        nullpo_retr(1, sd);
3309
3310        if(sd->status.cart[n].nameid==0 ||
3311           sd->status.cart[n].amount<amount)
3312                return 1;
3313
3314        sd->status.cart[n].amount -= amount;
3315        sd->cart_weight -= itemdb_weight(sd->status.cart[n].nameid)*amount ;
3316        if(sd->status.cart[n].amount <= 0){
3317                memset(&sd->status.cart[n],0,sizeof(sd->status.cart[0]));
3318                sd->cart_num--;
3319        }
3320        if(!type) {
3321                clif_cart_delitem(sd,n,amount);
3322                clif_updatestatus(sd,SP_CARTINFO);
3323        }
3324
3325        return 0;
3326}
3327
3328/*==========================================
3329 * ƒJ?ƒg‚ÖƒAƒCƒeƒ€ˆÚ“®
3330 *------------------------------------------*/
3331int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
3332{
3333        struct item *item_data;
3334
3335        nullpo_retr(0, sd);
3336
3337        if (idx < 0 || idx >= MAX_INVENTORY) //Invalid index check [Skotlex]
3338                return 1;
3339
3340        item_data = &sd->status.inventory[idx];
3341
3342        if (item_data->nameid==0 || amount < 1 || item_data->amount<amount || sd->vender_id)
3343                return 1;
3344
3345        if (pc_cart_additem(sd,item_data,amount) == 0)
3346                return pc_delitem(sd,idx,amount,0);
3347
3348        return 1;
3349}
3350
3351/*==========================================
3352 * ƒJ?ƒg?‚̃AƒCƒeƒ€?Šm”F(ŒÂ?‚̍·•ª‚ð•Ô‚·)
3353 *------------------------------------------*/
3354int pc_cartitem_amount(struct map_session_data* sd, int idx, int amount)
3355{
3356        struct item* item_data;
3357
3358        nullpo_retr(-1, sd);
3359
3360        item_data = &sd->status.cart[idx];
3361        if( item_data->nameid == 0 || item_data->amount == 0 )
3362                return -1;
3363
3364        return item_data->amount - amount;
3365}
3366
3367/*==========================================
3368 * ƒJ?ƒg‚©‚çƒAƒCƒeƒ€ˆÚ“®
3369 *------------------------------------------*/
3370int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
3371{
3372        struct item *item_data;
3373        int flag;
3374
3375        nullpo_retr(0, sd);
3376
3377        if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex]
3378                return 1;
3379
3380        item_data=&sd->status.cart[idx];
3381
3382        if(item_data->nameid==0 || amount < 1 || item_data->amount<amount || sd->vender_id )
3383                return 1;
3384        if((flag = pc_additem(sd,item_data,amount)) == 0)
3385                return pc_cart_delitem(sd,idx,amount,0);
3386
3387        clif_additem(sd,0,0,flag);
3388        return 1;
3389}
3390
3391/*==========================================
3392 * ƒXƒeƒBƒ‹•iŒöŠJ
3393 *------------------------------------------*/
3394int pc_show_steal(struct block_list *bl,va_list ap)
3395{
3396        struct map_session_data *sd;
3397        int itemid;
3398
3399        struct item_data *item=NULL;
3400        char output[100];
3401
3402        sd=va_arg(ap,struct map_session_data *);
3403        itemid=va_arg(ap,int);
3404
3405        if((item=itemdb_exists(itemid))==NULL)
3406                sprintf(output,"%s stole an Unknown Item (id: %i).",sd->status.name, itemid);
3407        else
3408                sprintf(output,"%s stole %s.",sd->status.name,item->jname);
3409        clif_displaymessage( ((struct map_session_data *)bl)->fd, output);
3410
3411        return 0;
3412}
3413/*==========================================
3414 *
3415 *------------------------------------------*/
3416int pc_steal_item(struct map_session_data *sd,struct block_list *bl, int lv)
3417{
3418        int i,itemid,flag;
3419        double rate;
3420        struct status_data *sd_status, *md_status;
3421        struct mob_data *md;
3422        struct item tmp_item;
3423
3424        if(!sd || !bl || bl->type!=BL_MOB)
3425                return 0;
3426
3427        md = (TBL_MOB *)bl;
3428
3429        if(md->state.steal_flag == UCHAR_MAX || md->sc.opt1) //already stolen from / status change check
3430                return 0;
3431
3432        sd_status= status_get_status_data(&sd->bl);
3433        md_status= status_get_status_data(bl);
3434
3435        if(md->master_id || md_status->mode&MD_BOSS ||
3436                (md->class_>=1324 && md->class_<1364) || // prevent stealing from treasure boxes [Valaris]
3437                map[bl->m].flag.nomobloot || // check noloot map flag [Lorky]
3438                (battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus]
3439                        md->state.steal_flag++ >= battle_config.skill_steal_max_tries)
3440        ) { //Can't steal from
3441                md->state.steal_flag = UCHAR_MAX;
3442                return 0;
3443        }
3444
3445        // base skill success chance (percentual)
3446        rate = (sd_status->dex - md_status->dex)/2 + lv*6 + 4;
3447        rate += sd->add_steal_rate;
3448
3449        if( rate < 1 )
3450                return 0;
3451
3452        // Try dropping one item, in the order from first to last possible slot.
3453        // Droprate is affected by the skill success rate.
3454        for( i = 0; i < MAX_STEAL_DROP; i++ )
3455                if( md->db->dropitem[i].nameid > 0 && itemdb_exists(md->db->dropitem[i].nameid) && rand() % 10000 < md->db->dropitem[i].p * rate/100. )
3456                        break;
3457        if( i == MAX_STEAL_DROP )
3458                return 0;
3459
3460        itemid = md->db->dropitem[i].nameid;
3461        memset(&tmp_item,0,sizeof(tmp_item));
3462        tmp_item.nameid = itemid;
3463        tmp_item.amount = 1;
3464        tmp_item.identify = itemdb_isidentified(itemid);
3465        flag = pc_additem(sd,&tmp_item,1);
3466
3467        //TODO: Should we disable stealing when the item you stole couldn't be added to your inventory? Perhaps players will figure out a way to exploit this behaviour otherwise?
3468        md->state.steal_flag = UCHAR_MAX; //you can't steal from this mob any more
3469
3470        if(flag) { //Failed to steal due to overweight
3471                clif_additem(sd,0,0,flag);
3472                return 0;
3473        }
3474
3475        if(battle_config.show_steal_in_same_party)
3476                party_foreachsamemap(pc_show_steal,sd,AREA_SIZE,sd,tmp_item.nameid);
3477
3478        //Logs items, Stolen from mobs [Lupus]
3479        if(log_config.enable_logs&0x80) {
3480                log_pick_mob(md, "M", itemid, -1, NULL);
3481                log_pick_pc(sd, "P", itemid, 1, NULL);
3482        }
3483
3484        //A Rare Steal Global Announce by Lupus
3485        if(md->db->dropitem[i].p<=battle_config.rare_drop_announce) {
3486                struct item_data *i_data;
3487                char message[128];
3488                i_data = itemdb_search(itemid);
3489                sprintf (message, msg_txt(542), (sd->status.name != NULL)?sd->status.name :"GM", md->db->jname, i_data->jname, (float)md->db->dropitem[i].p/100);
3490                //MSG: "'%s' stole %s's %s (chance: %0.02f%%)"
3491                intif_GMmessage(message,strlen(message)+1,0);
3492        }
3493        return 1;
3494}
3495
3496/*==========================================
3497 *
3498 *------------------------------------------*/
3499int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
3500{
3501        int rate,skill;
3502        struct mob_data *md;
3503        if(!sd || !target || target->type != BL_MOB)
3504                return 0;
3505
3506        md = (TBL_MOB*)target;
3507        if(md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE])
3508                return 0;
3509
3510        if (md->class_>=1324 && md->class_<1364)
3511                return 0;
3512
3513        skill = pc_checkskill(sd,RG_STEALCOIN)*10;
3514        rate = skill + (sd->status.base_level - md->level)*3 + sd->battle_status.dex*2 + sd->battle_status.luk*2;
3515        if(rand()%1000 < rate) {
3516                pc_getzeny(sd,md->level*10 + rand()%100);
3517                md->state.steal_coin_flag = 1;
3518                return 1;
3519        }
3520        return 0;
3521}
3522
3523/*==========================================
3524 * Set's a player position.
3525 * Return values:
3526 * 0 - Success.
3527 * 1 - Invalid map index.
3528 * 2 - Map not in this map-server, and failed to locate alternate map-server.
3529 *------------------------------------------*/
3530int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, uint8 clrtype)
3531{
3532        int m;
3533
3534        nullpo_retr(0, sd);
3535
3536        if (!mapindex || !mapindex_id2name(mapindex)) {
3537                ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex);
3538                return 1;
3539        }
3540
3541        sd->state.changemap = (sd->mapindex != mapindex);
3542        if( sd->state.changemap )
3543        {       //Misc map-changing settings
3544                if (sd->sc.count)
3545                { //Cancel some map related stuff.
3546                        if (sd->sc.data[SC_JAILED])
3547                                return 1; //You may not get out!
3548                        if (sd->sc.data[SC_WARM])
3549                                status_change_end(&sd->bl,SC_WARM,-1);
3550                        if (sd->sc.data[SC_SUN_COMFORT])
3551                                status_change_end(&sd->bl,SC_SUN_COMFORT,-1);
3552                        if (sd->sc.data[SC_MOON_COMFORT])
3553                                status_change_end(&sd->bl,SC_MOON_COMFORT,-1);
3554                        if (sd->sc.data[SC_STAR_COMFORT])
3555                                status_change_end(&sd->bl,SC_STAR_COMFORT,-1);
3556                        if (sd->sc.data[SC_KNOWLEDGE]) {
3557                                struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE];
3558                                if (sce->timer != -1)
3559                                        delete_timer(sce->timer, status_change_timer);
3560                                sce->timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sce->val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE);
3561                        }
3562                }
3563                if (battle_config.clear_unit_onwarp&BL_PC)
3564                        skill_clear_unitgroup(&sd->bl);
3565                party_send_dot_remove(sd); //minimap dot fix [Kevin]
3566                guild_send_dot_remove(sd);
3567                if (sd->regen.state.gc)
3568                        sd->regen.state.gc = 0;
3569        }
3570
3571        m=map_mapindex2mapid(mapindex);
3572        if(m<0) {
3573                uint32 ip;
3574                uint16 port;
3575                //if can't find any map-servers, just abort setting position.
3576                if(!sd->mapindex || map_mapname2ipport(mapindex,&ip,&port))
3577                        return 2;
3578
3579                //remove from map, THEN change x/y coordinates
3580                unit_remove_map_pc(sd,clrtype);
3581                sd->mapindex = mapindex;
3582                sd->bl.x=x;
3583                sd->bl.y=y;
3584                pc_clean_skilltree(sd);
3585                chrif_save(sd,2);
3586                chrif_changemapserver(sd, ip, (short)port);
3587
3588                //Free session data from this map server [Kevin]
3589                unit_free_pc(sd);
3590
3591                return 0;
3592        }
3593
3594        if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys )
3595        {
3596                ShowError("pc_setpos: attempt to place player %s (%d:%d) on invalid coordinates (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex),x,y);
3597                x = y = 0; // make it random
3598        }
3599
3600        if( x == 0 && y == 0 )
3601        {// pick a random walkable cell
3602                do {
3603                        x=rand()%(map[m].xs-2)+1;
3604                        y=rand()%(map[m].ys-2)+1;
3605                } while(map_getcell(m,x,y,CELL_CHKNOPASS));
3606        }
3607
3608        if(sd->bl.prev != NULL){
3609                unit_remove_map_pc(sd,clrtype);
3610                clif_changemap(sd,map[m].index,x,y); // [MouseJstr]
3611        } else if(sd->state.active)
3612                //Tag player for rewarping after map-loading is done. [Skotlex]
3613                sd->state.rewarp = 1;
3614
3615        sd->mapindex =  mapindex;
3616        sd->bl.m = m;
3617        sd->bl.x = sd->ud.to_x = x;
3618        sd->bl.y = sd->ud.to_y = y;
3619
3620        if (sd->status.guild_id > 0 && map[m].flag.gvg_castle)
3621        {       // Increased guild castle regen [Valaris]
3622                struct guild_castle *gc = guild_mapindex2gc(sd->mapindex);
3623                if(gc && gc->guild_id == sd->status.guild_id)
3624                        sd->regen.state.gc = 1;
3625        }
3626
3627        if(sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0) {
3628                sd->pd->bl.m = m;
3629                sd->pd->bl.x = sd->pd->ud.to_x = x;
3630                sd->pd->bl.y = sd->pd->ud.to_y = y;
3631                sd->pd->ud.dir = sd->ud.dir;
3632        }
3633
3634        if(merc_is_hom_active(sd->hd)) {        //orn
3635                sd->hd->bl.m = m;
3636                sd->hd->bl.x = sd->hd->ud.to_x = x;
3637                sd->hd->bl.y = sd->hd->ud.to_y = y;
3638                sd->hd->ud.dir = sd->ud.dir;
3639        }
3640
3641        return 0;
3642}
3643
3644/*==========================================
3645 * PC‚̃‰ƒ“ƒ_ƒ€ƒ?ƒv
3646 *------------------------------------------*/
3647int pc_randomwarp(struct map_session_data *sd, int type)
3648{
3649        int x,y,i=0;
3650        int m;
3651
3652        nullpo_retr(0, sd);
3653
3654        m=sd->bl.m;
3655
3656        if (map[sd->bl.m].flag.noteleport)      // ƒeƒŒƒ|?ƒg‹ÖŽ~
3657                return 0;
3658
3659        do{
3660                x=rand()%(map[m].xs-2)+1;
3661                y=rand()%(map[m].ys-2)+1;
3662        }while(map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000 );
3663
3664        if (i < 1000)
3665                return pc_setpos(sd,map[sd->bl.m].index,x,y,type);
3666
3667        return 0;
3668}
3669
3670/*==========================================
3671 * Records a memo point at sd's current position
3672 * pos - entry to replace, (-1: shift oldest entry out)
3673 *------------------------------------------*/
3674int pc_memo(struct map_session_data* sd, int pos)
3675{
3676        int skill;
3677
3678        nullpo_retr(0, sd);
3679
3680        // check mapflags
3681        if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && battle_config.any_warp_GM_min_level > pc_isGM(sd) ) {
3682                clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized."
3683                return 0;
3684        }
3685
3686        // check inputs
3687        if( pos < -1 || pos >= MAX_MEMOPOINTS )
3688                return 0; // invalid input
3689
3690        // check required skill level
3691        skill = pc_checkskill(sd, AL_WARP);
3692        if( skill < 1 ) {
3693                clif_skill_memomessage(sd,2); // "You haven't learned Warp."
3694                return 0;
3695        }
3696        if( skill < 2 || skill - 2 < pos ) {
3697                clif_skill_memomessage(sd,1); // "Skill Level is not high enough."
3698                return 0;
3699        }
3700
3701        if( pos == -1 )
3702        {
3703                int i;
3704                // prevent memo-ing the same map multiple times
3705                ARR_FIND( 0, MAX_MEMOPOINTS, i, sd->status.memo_point[i].map == map_id2index(sd->bl.m) );
3706                memmove(&sd->status.memo_point[1], &sd->status.memo_point[0], (min(i,MAX_MEMOPOINTS-1))*sizeof(struct point));
3707                pos = 0;
3708        }
3709
3710        sd->status.memo_point[pos].map = map_id2index(sd->bl.m);
3711        sd->status.memo_point[pos].x = sd->bl.x;
3712        sd->status.memo_point[pos].y = sd->bl.y;
3713
3714        clif_skill_memomessage(sd, 0);
3715
3716        return 1;
3717}
3718
3719//
3720// •Ší??
3721//
3722/*==========================================
3723 * ƒXƒLƒ‹‚Ì?õ Š—L‚µ‚Ä‚¢‚œê‡Lv‚ª•Ô‚é
3724 *------------------------------------------*/
3725int pc_checkskill(struct map_session_data *sd,int skill_id)
3726{
3727        if(sd == NULL) return 0;
3728        if( skill_id>=GD_SKILLBASE){
3729                struct guild *g;
3730                if( sd->status.guild_id>0 && (g=guild_search(sd->status.guild_id))!=NULL)
3731                        return guild_checkskill(g,skill_id);
3732                return 0;
3733        }
3734
3735        if(sd->status.skill[skill_id].id == skill_id)
3736                return (sd->status.skill[skill_id].lv);
3737
3738        return 0;
3739}
3740
3741/*==========================================
3742 * •Ší?X‚É‚æ‚éƒXƒLƒ‹‚Ì??ƒ`ƒFƒbƒN
3743 * ˆø?F
3744 *   struct map_session_data *sd        ƒZƒbƒVƒ‡ƒ“ƒf?ƒ^
3745 *   int nameid                                         ?”õ•iID
3746 * •Ô‚è’lF
3747 *   0          ?X‚È‚µ
3748 *   -1         ƒXƒLƒ‹‚ð‰ðœ
3749 *------------------------------------------*/
3750int pc_checkallowskill(struct map_session_data *sd)
3751{
3752        const enum sc_type scw_list[] = {
3753                SC_TWOHANDQUICKEN,
3754                SC_ONEHAND,
3755                SC_AURABLADE,
3756                SC_PARRYING,
3757                SC_SPEARQUICKEN,
3758                SC_ADRENALINE,
3759                SC_ADRENALINE2,
3760                SC_GATLINGFEVER
3761        };
3762        const enum sc_type scs_list[] = {
3763                SC_AUTOGUARD,
3764                SC_DEFENDER,
3765                SC_REFLECTSHIELD
3766        };
3767        int i;
3768        nullpo_retr(0, sd);
3769
3770        if(!sd->sc.count)
3771                return 0;
3772
3773        for (i = 0; i < ARRAYLENGTH(scw_list); i++)
3774        {       // Skills requiring specific weapon types
3775                if(sd->sc.data[scw_list[i]] &&
3776                        !pc_check_weapontype(sd,skill_get_weapontype(status_sc2skill(scw_list[i]))))
3777                        status_change_end(&sd->bl,scw_list[i],-1);
3778        }
3779
3780        if(sd->sc.data[SC_SPURT] && sd->status.weapon)
3781                // Spurt requires bare hands (feet, in fact xD)
3782                status_change_end(&sd->bl,SC_SPURT,-1);
3783
3784        if(sd->status.shield <= 0) { // Skills requiring a shield
3785                for (i = 0; i < ARRAYLENGTH(scs_list); i++)
3786                        if(sd->sc.data[scs_list[i]])
3787                                status_change_end(&sd->bl,scs_list[i],-1);
3788        }
3789        return 0;
3790}
3791
3792/*==========================================
3793 * ? ”õ•i‚̃`ƒFƒbƒN
3794 *------------------------------------------*/
3795int pc_checkequip(struct map_session_data *sd,int pos)
3796{
3797        int i;
3798
3799        nullpo_retr(-1, sd);
3800
3801        for(i=0;i<EQI_MAX;i++){
3802                if(pos & equip_pos[i])
3803                        return sd->equip_index[i];
3804        }
3805
3806        return -1;
3807}
3808
3809/*==========================================
3810 * Convert's from the client's lame Job ID system
3811 * to the map server's 'makes sense' system. [Skotlex]
3812 *------------------------------------------*/
3813int pc_jobid2mapid(unsigned short b_class)
3814{
3815        int class_ = 0;
3816        if (b_class >= JOB_BABY && b_class <= JOB_SUPER_BABY)
3817        {
3818                if (b_class == JOB_SUPER_BABY)
3819                        b_class = JOB_SUPER_NOVICE;
3820                else
3821                        b_class -= JOB_BABY;
3822                class_|= JOBL_BABY;
3823        }
3824        else if (b_class >= JOB_NOVICE_HIGH && b_class <= JOB_PALADIN2)
3825        {
3826                b_class -= JOB_NOVICE_HIGH;
3827                class_|= JOBL_UPPER;
3828        }
3829        if (b_class >= JOB_KNIGHT && b_class <= JOB_KNIGHT2)
3830                class_|= JOBL_2_1;
3831        else if (b_class >= JOB_CRUSADER && b_class <= JOB_CRUSADER2)
3832                class_|= JOBL_2_2;
3833        switch (b_class)
3834        {
3835                case JOB_NOVICE:
3836                case JOB_SWORDMAN:
3837                case JOB_MAGE:
3838                case JOB_ARCHER:
3839                case JOB_ACOLYTE:
3840                case JOB_MERCHANT:
3841                case JOB_THIEF:
3842                        class_ |= b_class;
3843                        break;
3844                case JOB_KNIGHT:
3845                case JOB_KNIGHT2:
3846                case JOB_CRUSADER:
3847                case JOB_CRUSADER2:
3848                        class_ |= MAPID_SWORDMAN;
3849                        break;
3850                case JOB_PRIEST:
3851                case JOB_MONK:
3852                        class_ |= MAPID_ACOLYTE;
3853                        break;
3854                case JOB_WIZARD:
3855                case JOB_SAGE:
3856                        class_ |= MAPID_MAGE;
3857                        break;
3858                case JOB_BLACKSMITH:
3859                case JOB_ALCHEMIST:
3860                        class_ |= MAPID_MERCHANT;
3861                        break;
3862                case JOB_HUNTER:
3863                case JOB_BARD:
3864                case JOB_DANCER:
3865                        class_ |= MAPID_ARCHER;
3866                        break;
3867                case JOB_ASSASSIN:
3868                case JOB_ROGUE:
3869                        class_ |= MAPID_THIEF;
3870                        break;
3871
3872                case JOB_STAR_GLADIATOR:
3873                case JOB_STAR_GLADIATOR2:
3874                        class_ |= JOBL_2_1;
3875                        class_ |= MAPID_TAEKWON;
3876                        break;
3877                case JOB_SOUL_LINKER:
3878                        class_ |= JOBL_2_2;
3879                case JOB_TAEKWON:
3880                        class_ |= MAPID_TAEKWON;
3881                        break;
3882                case JOB_WEDDING:
3883                        class_ = MAPID_WEDDING;
3884                        break;
3885                case JOB_SUPER_NOVICE: //Super Novices are considered 2-1 novices. [Skotlex]
3886                        class_ |= JOBL_2_1;
3887                        break;
3888                case JOB_GUNSLINGER:
3889                        class_ |= MAPID_GUNSLINGER;
3890                        break;
3891                case JOB_NINJA:
3892                        class_ |= MAPID_NINJA;
3893                        break;
3894                case JOB_XMAS:
3895                        class_ = MAPID_XMAS;
3896                        break;
3897                case JOB_SUMMER:
3898                        class_ = MAPID_SUMMER;
3899                        break;
3900<<<<<<< .mine
3901                        //Possible to be in the wrong spot?
3902                case JOB_NECROMANCER: // Necromancer [Brain]
3903                        class_ |= JOBL_2_1;
3904                        class_ |= MAPID_ADEPT;
3905=======
3906                        //Custom Jobs (blackmagic)
3907                        +               case JOB_NECROMANCER: // Necromancer [Brain]
3908                        class_ |= JOBL_2_1;
3909                        class_ |= MAPID_ADEPT;
3910                        break; 
3911                case JOB_WARLOCK: // Warlock [Brain]
3912                        class_ |= JOBL_2_2;
3913                case JOB_ADEPT: // Adept [Brain]
3914                        class_ |= MAPID_ADEPT;
3915>>>>>>> .r18
3916                        break;
3917                case JOB_WARLOCK: // Warlock [Brain]
3918                        class_ |= JOBL_2_2;
3919                case JOB_ADEPT: // Adept [Brain]
3920                        class_ |= MAPID_ADEPT;
3921                        break;
3922                default:
3923                        return -1;
3924        }
3925        return class_;
3926}
3927
3928//Reverts the map-style class id to the client-style one.
3929int pc_mapid2jobid(unsigned short class_, int sex)
3930{
3931        switch(class_) {
3932                case MAPID_NOVICE:          return JOB_NOVICE;
3933                case MAPID_SWORDMAN:        return JOB_SWORDMAN;
3934                case MAPID_MAGE:            return JOB_MAGE;
3935                case MAPID_ARCHER:          return JOB_ARCHER;
3936                case MAPID_ACOLYTE:         return JOB_ACOLYTE;
3937                case MAPID_MERCHANT:        return JOB_MERCHANT;
3938                case MAPID_THIEF:           return JOB_THIEF;
3939                case MAPID_TAEKWON:         return JOB_TAEKWON;
3940                case MAPID_WEDDING:         return JOB_WEDDING;
3941                case MAPID_GUNSLINGER:      return JOB_GUNSLINGER;
3942                case MAPID_NINJA:           return JOB_NINJA;
3943                case MAPID_XMAS:            return JOB_XMAS;
3944                case MAPID_SUMMER:          return JOB_SUMMER;
3945                case MAPID_ADEPT:                       return JOB_ADEPT; // Adept [Brain]
3946        //2_1 classes
3947                case MAPID_SUPER_NOVICE:    return JOB_SUPER_NOVICE;
3948                case MAPID_KNIGHT:          return JOB_KNIGHT;
3949                case MAPID_WIZARD:          return JOB_WIZARD;
3950                case MAPID_HUNTER:          return JOB_HUNTER;
3951                case MAPID_PRIEST:          return JOB_PRIEST;
3952                case MAPID_BLACKSMITH:      return JOB_BLACKSMITH;
3953                case MAPID_ASSASSIN:        return JOB_ASSASSIN;
3954                case MAPID_STAR_GLADIATOR:  return JOB_STAR_GLADIATOR;
3955                case MAPID_NECROMANCER:         return JOB_NECROMANCER; // Necromancer [Brain]
3956        //2_2 classes
3957                case MAPID_CRUSADER:        return JOB_CRUSADER;
3958                case MAPID_SAGE:            return JOB_SAGE;
3959                case MAPID_BARDDANCER:      return sex?JOB_BARD:JOB_DANCER;
3960                case MAPID_MONK:            return JOB_MONK;
3961                case MAPID_ALCHEMIST:       return JOB_ALCHEMIST;
3962                case MAPID_ROGUE:           return JOB_ROGUE;
3963                case MAPID_SOUL_LINKER:     return JOB_SOUL_LINKER;
3964                case MAPID_WARLOCK:                     return JOB_WARLOCK; // Warlock [Brain]
3965        //1-1: advanced
3966                case MAPID_NOVICE_HIGH:     return JOB_NOVICE_HIGH;
3967                case MAPID_SWORDMAN_HIGH:   return JOB_SWORDMAN_HIGH;
3968                case MAPID_MAGE_HIGH:       return JOB_MAGE_HIGH;
3969                case MAPID_ARCHER_HIGH:     return JOB_ARCHER_HIGH;
3970                case MAPID_ACOLYTE_HIGH:    return JOB_ACOLYTE_HIGH;
3971                case MAPID_MERCHANT_HIGH:   return JOB_MERCHANT_HIGH;
3972                case MAPID_THIEF_HIGH:      return JOB_THIEF_HIGH;
3973        //2_1 advanced
3974                case MAPID_LORD_KNIGHT:     return JOB_LORD_KNIGHT;
3975                case MAPID_HIGH_WIZARD:     return JOB_HIGH_WIZARD;
3976                case MAPID_SNIPER:          return JOB_SNIPER;
3977                case MAPID_HIGH_PRIEST:     return JOB_HIGH_PRIEST;
3978                case MAPID_WHITESMITH:      return JOB_WHITESMITH;
3979                case MAPID_ASSASSIN_CROSS:  return JOB_ASSASSIN_CROSS;
3980        //2_2 advanced
3981                case MAPID_PALADIN:         return JOB_PALADIN;
3982                case MAPID_PROFESSOR:       return JOB_PROFESSOR;
3983                case MAPID_CLOWNGYPSY:      return sex?JOB_CLOWN:JOB_GYPSY;
3984                case MAPID_CHAMPION:        return JOB_CHAMPION;
3985                case MAPID_CREATOR:         return JOB_CREATOR;
3986                case MAPID_STALKER:         return JOB_STALKER;
3987        //1-1 baby
3988                case MAPID_BABY:            return JOB_BABY;
3989                case MAPID_BABY_SWORDMAN:   return JOB_BABY_SWORDMAN;
3990                case MAPID_BABY_MAGE:       return JOB_BABY_MAGE;
3991                case MAPID_BABY_ARCHER:     return JOB_BABY_ARCHER;
3992                case MAPID_BABY_ACOLYTE:    return JOB_BABY_ACOLYTE;
3993                case MAPID_BABY_MERCHANT:   return JOB_BABY_MERCHANT;
3994                case MAPID_BABY_THIEF:      return JOB_BABY_THIEF;
3995        //2_1 baby
3996                case MAPID_SUPER_BABY:      return JOB_SUPER_BABY;
3997                case MAPID_BABY_KNIGHT:     return JOB_BABY_KNIGHT;
3998                case MAPID_BABY_WIZARD:     return JOB_BABY_WIZARD;
3999                case MAPID_BABY_HUNTER:     return JOB_BABY_HUNTER;
4000                case MAPID_BABY_PRIEST:     return JOB_BABY_PRIEST;
4001                case MAPID_BABY_BLACKSMITH: return JOB_BABY_BLACKSMITH;
4002                case MAPID_BABY_ASSASSIN:   return JOB_BABY_ASSASSIN;
4003        //2_2 baby
4004                case MAPID_BABY_CRUSADER:   return JOB_BABY_CRUSADER;
4005                case MAPID_BABY_SAGE:       return JOB_BABY_SAGE;
4006                case MAPID_BABY_BARDDANCER: return sex?JOB_BABY_BARD:JOB_BABY_DANCER;
4007                case MAPID_BABY_MONK:       return JOB_BABY_MONK;
4008                case MAPID_BABY_ALCHEMIST:  return JOB_BABY_ALCHEMIST;
4009                case MAPID_BABY_ROGUE:      return JOB_BABY_ROGUE;
4010                default:
4011                        return -1;
4012        }
4013}
4014
4015/*====================================================
4016 * This function return the name of the job (by [Yor])
4017 *----------------------------------------------------*/
4018char* job_name(int class_)
4019{
4020        switch (class_) {
4021        case JOB_NOVICE:
4022        case JOB_SWORDMAN:
4023        case JOB_MAGE:
4024        case JOB_ARCHER:
4025        case JOB_ACOLYTE:
4026        case JOB_MERCHANT:
4027        case JOB_THIEF:
4028                return msg_txt(550 - JOB_NOVICE+class_);
4029
4030        case JOB_KNIGHT:
4031        case JOB_PRIEST:
4032        case JOB_WIZARD:
4033        case JOB_BLACKSMITH:
4034        case JOB_HUNTER:
4035        case JOB_ASSASSIN:
4036                return msg_txt(557 - JOB_KNIGHT+class_);
4037
4038        case JOB_KNIGHT2:
4039                return msg_txt(557);
4040
4041        case JOB_CRUSADER:
4042        case JOB_MONK:
4043        case JOB_SAGE:
4044        case JOB_ROGUE:
4045        case JOB_ALCHEMIST:
4046        case JOB_BARD:
4047        case JOB_DANCER:
4048                return msg_txt(563 - JOB_CRUSADER+class_);
4049
4050        case JOB_CRUSADER2:
4051                return msg_txt(563);
4052
4053        case JOB_WEDDING:
4054        case JOB_SUPER_NOVICE:
4055
4056        case JOB_XMAS:
4057                return msg_txt(570 - JOB_WEDDING+class_);
4058
4059        case JOB_SUMMER:
4060                return msg_txt(621);
4061
4062        case JOB_NOVICE_HIGH:
4063        case JOB_SWORDMAN_HIGH:
4064        case JOB_MAGE_HIGH:
4065        case JOB_ARCHER_HIGH:
4066        case JOB_ACOLYTE_HIGH:
4067        case JOB_MERCHANT_HIGH:
4068        case JOB_THIEF_HIGH:
4069                return msg_txt(575 - JOB_NOVICE_HIGH+class_);
4070
4071        case JOB_LORD_KNIGHT:
4072        case JOB_HIGH_PRIEST:
4073        case JOB_HIGH_WIZARD:
4074        case JOB_WHITESMITH:
4075        case JOB_SNIPER:
4076        case JOB_ASSASSIN_CROSS:
4077                return msg_txt(582 - JOB_LORD_KNIGHT+class_);
4078
4079        case JOB_LORD_KNIGHT2:
4080                return msg_txt(582);
4081
4082        case JOB_PALADIN:
4083        case JOB_CHAMPION:
4084        case JOB_PROFESSOR:
4085        case JOB_STALKER:
4086        case JOB_CREATOR:
4087        case JOB_CLOWN:
4088        case JOB_GYPSY:
4089                return msg_txt(588 - JOB_PALADIN + class_);
4090
4091        case JOB_PALADIN2:
4092                return msg_txt(588);
4093
4094        case JOB_BABY:
4095        case JOB_BABY_SWORDMAN:
4096        case JOB_BABY_MAGE:
4097        case JOB_BABY_ARCHER:
4098        case JOB_BABY_ACOLYTE:
4099        case JOB_BABY_MERCHANT:
4100        case JOB_BABY_THIEF:
4101                return msg_txt(595 - JOB_BABY + class_);
4102
4103        case JOB_BABY_KNIGHT:
4104        case JOB_BABY_PRIEST:
4105        case JOB_BABY_WIZARD:
4106        case JOB_BABY_BLACKSMITH:
4107        case JOB_BABY_HUNTER:
4108        case JOB_BABY_ASSASSIN:
4109                return msg_txt(602 - JOB_BABY_KNIGHT + class_);
4110
4111        case JOB_BABY_KNIGHT2:
4112                return msg_txt(602);
4113
4114        case JOB_BABY_CRUSADER:
4115        case JOB_BABY_MONK:
4116        case JOB_BABY_SAGE:
4117        case JOB_BABY_ROGUE:
4118        case JOB_BABY_ALCHEMIST:
4119        case JOB_BABY_BARD:
4120        case JOB_BABY_DANCER:
4121                return msg_txt(608 - JOB_BABY_CRUSADER +class_);
4122
4123        case JOB_BABY_CRUSADER2:
4124                return msg_txt(608);
4125
4126        case JOB_SUPER_BABY:
4127                return msg_txt(615);
4128
4129        case JOB_TAEKWON:
4130                return msg_txt(616);
4131        case JOB_STAR_GLADIATOR:
4132        case JOB_STAR_GLADIATOR2:
4133                return msg_txt(617);
4134        case JOB_SOUL_LINKER:
4135                return msg_txt(618);
4136
4137        case JOB_GUNSLINGER:
4138                return msg_txt(619);
4139        case JOB_NINJA:
4140                return msg_txt(620);
4141<<<<<<< .mine
4142        case JOB_ADEPT: // Adept [Brain]
4143                return msg_txt(1000);
4144        case JOB_NECROMANCER: // Necromancer [Brain]
4145                return msg_txt(1001);
4146        case JOB_WARLOCK: // Warlock [Flavio]
4147=======
4148        //Custom Jobs (blackmagic)
4149        case JOB_ADEPT: // Adept [Brain]
4150                return msg_txt(1000);
4151        case JOB_NECROMANCER: // Necromancer [Brain]
4152                return msg_txt(1001);
4153        case JOB_WARLOCK: // Warlock [Flavio]
4154>>>>>>> .r18
4155                return msg_txt(1002);
4156
4157        default:
4158                return msg_txt(650);
4159        }
4160}
4161
4162int pc_follow_timer(int tid, unsigned int tick, int id, intptr data)
4163{
4164        struct map_session_data *sd;
4165        struct block_list *tbl;
4166
4167        sd = map_id2sd(id);
4168        nullpo_retr(0, sd);
4169
4170        if (sd->followtimer != tid){
4171                ShowError("pc_follow_timer %d != %d\n",sd->followtimer,tid);
4172                sd->followtimer = -1;
4173                return 0;
4174        }
4175
4176        sd->followtimer = -1;
4177        if (pc_isdead(sd))
4178                return 0;
4179
4180        if ((tbl = map_id2bl(sd->followtarget)) == NULL)
4181                return 0;
4182
4183        if(status_isdead(tbl))
4184                return 0;
4185
4186        // either player or target is currently detached from map blocks (could be teleporting),
4187        // but still connected to this map, so we'll just increment the timer and check back later
4188        if (sd->bl.prev != NULL && tbl->prev != NULL &&
4189                sd->ud.skilltimer == -1 && sd->ud.attacktimer == -1 && sd->ud.walktimer == -1)
4190        {
4191                if((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) {
4192                        if (!check_distance_bl(&sd->bl, tbl, 5))
4193                                unit_walktobl(&sd->bl, tbl, 5, 0);
4194                } else
4195                        pc_setpos(sd, map_id2index(tbl->m), tbl->x, tbl->y, 3);
4196        }
4197        sd->followtimer = add_timer(
4198                tick + 1000,    // increase time a bit to loosen up map's load
4199                pc_follow_timer, sd->bl.id, 0);
4200        return 0;
4201}
4202
4203int pc_stop_following (struct map_session_data *sd)
4204{
4205        nullpo_retr(0, sd);
4206
4207        if (sd->followtimer != -1) {
4208                delete_timer(sd->followtimer,pc_follow_timer);
4209                sd->followtimer = -1;
4210        }
4211        sd->followtarget = -1;
4212
4213        return 0;
4214}
4215
4216int pc_follow(struct map_session_data *sd,int target_id)
4217{
4218        struct block_list *bl = map_id2bl(target_id);
4219        if (bl == NULL /*|| bl->type != BL_PC*/)
4220                return 1;
4221        if (sd->followtimer != -1)
4222                pc_stop_following(sd);
4223
4224        sd->followtarget = target_id;
4225        pc_follow_timer(-1,gettick(),sd->bl.id,0);
4226
4227        return 0;
4228}
4229
4230int pc_checkbaselevelup(struct map_session_data *sd)
4231{
4232        unsigned int next = pc_nextbaseexp(sd);
4233
4234        if (!next || sd->status.base_exp < next)
4235                return 0;
4236        do {
4237                sd->status.base_exp -= next;
4238                //Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
4239                if(!battle_config.multi_level_up && sd->status.base_exp > next-1)
4240                        sd->status.base_exp = next-1;
4241
4242                sd->status.base_level ++;
4243
4244                if (battle_config.use_statpoint_table)
4245                        next = statp[sd->status.base_level] - statp[sd->status.base_level-1];
4246                else //Estimated way.
4247                        next = (sd->status.base_level+14) / 5 ;
4248                if (sd->status.status_point > USHRT_MAX - next)
4249                        sd->status.status_point = USHRT_MAX;
4250                else
4251                        sd->status.status_point += next;
4252
4253        } while ((next=pc_nextbaseexp(sd)) > 0 && sd->status.base_exp >= next);
4254
4255        if (battle_config.pet_lv_rate && sd->pd)        //<Skotlex> update pet's level
4256                status_calc_pet(sd->pd,0);
4257
4258        clif_updatestatus(sd,SP_STATUSPOINT);
4259        clif_updatestatus(sd,SP_BASELEVEL);
4260        clif_updatestatus(sd,SP_NEXTBASEEXP);
4261        status_calc_pc(sd,0);
4262        status_percent_heal(&sd->bl,100,100);
4263
4264        if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE)
4265        {
4266                sc_start(&sd->bl,status_skill2sc(PR_KYRIE),100,1,skill_get_time(PR_KYRIE,1));
4267                sc_start(&sd->bl,status_skill2sc(PR_IMPOSITIO),100,1,skill_get_time(PR_IMPOSITIO,1));
4268                sc_start(&sd->bl,status_skill2sc(PR_MAGNIFICAT),100,1,skill_get_time(PR_MAGNIFICAT,1));
4269                sc_start(&sd->bl,status_skill2sc(PR_GLORIA),100,1,skill_get_time(PR_GLORIA,1));
4270                sc_start(&sd->bl,status_skill2sc(PR_SUFFRAGIUM),100,1,skill_get_time(PR_SUFFRAGIUM,1));
4271                if (sd->state.snovice_dead_flag)
4272                        sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead.
4273        } else
4274        if((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON || (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR)
4275        {
4276                sc_start(&sd->bl,status_skill2sc(AL_INCAGI),100,10,600000);
4277                sc_start(&sd->bl,status_skill2sc(AL_BLESSING),100,10,600000);
4278        }
4279        clif_misceffect(&sd->bl,0);
4280        npc_script_event(sd, NPCE_BASELVUP); //LORDALFA - LVLUPEVENT
4281
4282        if(sd->status.party_id)
4283                party_send_levelup(sd);
4284        return 1;
4285}
4286
4287int pc_checkjoblevelup(struct map_session_data *sd)
4288{
4289        unsigned int next = pc_nextjobexp(sd);
4290
4291        nullpo_retr(0, sd);
4292        if(!next || sd->status.job_exp < next)
4293                return 0;
4294
4295        do {
4296                sd->status.job_exp -= next;
4297                //Kyoki pointed out that the max overcarry exp is the exp needed for the previous level -1. [Skotlex]
4298                if(!battle_config.multi_level_up && sd->status.job_exp > next-1)
4299                        sd->status.job_exp = next-1;
4300
4301                sd->status.job_level ++;
4302                sd->status.skill_point ++;
4303
4304        } while ((next=pc_nextjobexp(sd)) > 0 && sd->status.job_exp >= next);
4305
4306        clif_updatestatus(sd,SP_JOBLEVEL);
4307        clif_updatestatus(sd,SP_NEXTJOBEXP);
4308        clif_updatestatus(sd,SP_SKILLPOINT);
4309        status_calc_pc(sd,0);
4310        clif_misceffect(&sd->bl,1);
4311        if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
4312                clif_status_change(&sd->bl,SI_DEVIL, 1); //Permanent blind effect from SG_DEVIL.
4313
4314        npc_script_event(sd, NPCE_JOBLVUP);
4315        return 1;
4316}
4317
4318/*==========================================
4319 * Alters experienced based on self bonuses that do not get even shared to the party.
4320 *------------------------------------------*/
4321static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src)
4322{
4323        int bonus = 0;
4324        struct status_data *status = status_get_status_data(src);
4325
4326        if (sd->expaddrace[status->race])
4327                bonus += sd->expaddrace[status->race];
4328        bonus += sd->expaddrace[status->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
4329
4330        if (battle_config.pk_mode &&
4331                (int)(status_get_lv(src) - sd->status.base_level) >= 20)
4332                bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
4333
4334        if (sd->sc.data[SC_EXPBOOST])
4335                bonus += sd->sc.data[SC_EXPBOOST]->val1;
4336
4337        if (!bonus)
4338                return;
4339
4340        *base_exp += (unsigned int) cap_value((double)*base_exp * bonus/100., 1, UINT_MAX);
4341        *job_exp += (unsigned int) cap_value((double)*job_exp * bonus/100., 1, UINT_MAX);
4342
4343        return;
4344}
4345/*==========================================
4346 * ??’lŽæ“Ÿ
4347 *------------------------------------------*/
4348int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp,unsigned int job_exp)
4349{
4350        char output[256];
4351        float nextbp=0, nextjp=0;
4352        unsigned int nextb=0, nextj=0;
4353        nullpo_retr(0, sd);
4354
4355        if(sd->bl.prev == NULL || pc_isdead(sd))
4356                return 0;
4357
4358        if(!battle_config.pvp_exp && map[sd->bl.m].flag.pvp)  // [MouseJstr]
4359                return 0; // no exp on pvp maps
4360
4361        if(sd->status.guild_id>0)
4362                base_exp-=guild_payexp(sd,base_exp);
4363
4364        if(src) pc_calcexp(sd, &base_exp, &job_exp, src);
4365
4366        nextb = pc_nextbaseexp(sd);
4367        nextj = pc_nextjobexp(sd);
4368
4369        if(sd->state.showexp || battle_config.max_exp_gain_rate){
4370                if (nextb > 0)
4371                        nextbp = (float) base_exp / (float) nextb;
4372                if (nextj > 0)
4373                        nextjp = (float) job_exp / (float) nextj;
4374
4375                if(battle_config.max_exp_gain_rate) {
4376                        if (nextbp > battle_config.max_exp_gain_rate/1000.) {
4377                                //Note that this value should never be greater than the original
4378                                //base_exp, therefore no overflow checks are needed. [Skotlex]
4379                                base_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextb);
4380                                if (sd->state.showexp)
4381                                        nextbp = (float) base_exp / (float) nextb;
4382                        }
4383                        if (nextjp > battle_config.max_exp_gain_rate/1000.) {
4384                                job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj);
4385                                if (sd->state.showexp)
4386                                        nextjp = (float) job_exp / (float) nextj;
4387                        }
4388                }
4389        }
4390
4391        //Cap exp to the level up requirement of the previous level when you are at max level, otherwise cap at UINT_MAX (this is required for some S. Novice bonuses). [Skotlex]
4392        if (base_exp) {
4393                nextb = nextb?UINT_MAX:pc_thisbaseexp(sd);
4394                if(sd->status.base_exp > nextb - base_exp)
4395                        sd->status.base_exp = nextb;
4396                else
4397                        sd->status.base_exp += base_exp;
4398                pc_checkbaselevelup(sd);
4399                clif_updatestatus(sd,SP_BASEEXP);
4400        }
4401
4402        if (job_exp) {
4403                nextj = nextj?UINT_MAX:pc_thisjobexp(sd);
4404                if(sd->status.job_exp > nextj - job_exp)
4405                        sd->status.job_exp = nextj;
4406                else
4407                        sd->status.job_exp += job_exp;
4408                pc_checkjoblevelup(sd);
4409                clif_updatestatus(sd,SP_JOBEXP);
4410        }
4411
4412        if(sd->state.showexp){
4413                sprintf(output,
4414                        "Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
4415                clif_disp_onlyself(sd,output,strlen(output));
4416        }
4417
4418        return 1;
4419}
4420
4421/*==========================================
4422 * Returns max level for this character.
4423 *------------------------------------------*/
4424unsigned int pc_maxbaselv(struct map_session_data *sd)
4425{
4426        return max_level[pc_class2idx(sd->status.class_)][0];
4427};
4428
4429unsigned int pc_maxjoblv(struct map_session_data *sd)
4430{
4431        return max_level[pc_class2idx(sd->status.class_)][1];
4432};
4433
4434/*==========================================
4435 * base level‘€•K—v??’lŒvŽZ
4436 *------------------------------------------*/
4437unsigned int pc_nextbaseexp(struct map_session_data *sd)
4438{
4439        nullpo_retr(0, sd);
4440
4441        if(sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0)
4442                return 0;
4443
4444        return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-1];
4445}
4446
4447unsigned int pc_thisbaseexp(struct map_session_data *sd)
4448{
4449        if(sd->status.base_level>pc_maxbaselv(sd) || sd->status.base_level<=1)
4450                return 0;
4451
4452        return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-2];
4453}
4454
4455
4456/*==========================================
4457 * job level‘€•K—v??’lŒvŽZ
4458 *------------------------------------------*/
4459unsigned int pc_nextjobexp(struct map_session_data *sd)
4460{
4461        nullpo_retr(0, sd);
4462
4463        if(sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0)
4464                return 0;
4465        return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-1];
4466}
4467
4468unsigned int pc_thisjobexp(struct map_session_data *sd)
4469{
4470        if(sd->status.job_level>pc_maxjoblv(sd) || sd->status.job_level<=1)
4471                return 0;
4472        return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-2];
4473}
4474
4475static int pc_getstat(struct map_session_data* sd, int type)
4476{
4477        nullpo_retr(-1, sd);
4478        switch( type ) {
4479        case SP_STR: return sd->status.str;
4480        case SP_AGI: return sd->status.agi;
4481        case SP_VIT: return sd->status.vit;
4482        case SP_INT: return sd->status.int_;
4483        case SP_DEX: return sd->status.dex;
4484        case SP_LUK: return sd->status.luk;
4485        default:
4486                return -1;
4487        }
4488}
4489
4490/*==========================================
4491 * •K—vƒXƒe?ƒ^ƒXƒ|ƒCƒ“ƒgŒvŽZ
4492 *------------------------------------------*/
4493int pc_need_status_point(struct map_session_data *sd,int type)
4494{
4495        nullpo_retr(-1, sd);
4496        if( type < SP_STR || type > SP_LUK )
4497                return -1;
4498        return ( 1 + (pc_getstat(sd,type) + 9) / 10 );
4499}
4500
4501/*==========================================
4502 * ”\—Í’l¬’·
4503 *------------------------------------------*/
4504int pc_statusup(struct map_session_data *sd,int type)
4505{
4506        int max, need,val = 0;
4507
4508        nullpo_retr(0, sd);
4509
4510        // check conditions
4511        need = pc_need_status_point(sd,type);
4512        if( type < SP_STR || type > SP_LUK || need < 0 || need > sd->status.status_point )
4513        {
4514                clif_statusupack(sd,type,0,0);
4515                return 1;
4516        }
4517
4518        // check limits
4519        max = pc_maxparameter(sd);
4520        if( pc_getstat(sd,type) >= max )
4521        {
4522                clif_statusupack(sd,type,0,0);
4523                return 1;
4524        }
4525
4526        switch(type){
4527        case SP_STR: val= ++sd->status.str; break;
4528        case SP_AGI: val= ++sd->status.agi; break;
4529        case SP_VIT: val= ++sd->status.vit; break;
4530        case SP_INT: val= ++sd->status.int_; break;
4531        case SP_DEX: val= ++sd->status.dex; break;
4532        case SP_LUK: val= ++sd->status.luk; break;
4533        }
4534
4535        sd->status.status_point-=need;
4536        status_calc_pc(sd,0);
4537
4538        if( need != pc_need_status_point(sd,type) )
4539                clif_updatestatus(sd,type-SP_STR+SP_USTR);
4540        clif_updatestatus(sd,SP_STATUSPOINT);
4541        clif_statusupack(sd,type,1,val);
4542        clif_updatestatus(sd,type); // send after the 'ack' to override the value
4543
4544        return 0;
4545}
4546
4547/*==========================================
4548 * ”\—Í’l¬’·
4549 *------------------------------------------*/
4550int pc_statusup2(struct map_session_data *sd,int type,int val)
4551{
4552        int max;
4553        nullpo_retr(0, sd);
4554
4555        max = pc_maxparameter(sd);
4556
4557        switch(type){
4558        case SP_STR: sd->status.str = cap_value(sd->status.str + val, 1, max); break;
4559        case SP_AGI: sd->status.agi = cap_value(sd->status.agi + val, 1, max); break;
4560        case SP_VIT: sd->status.vit = cap_value(sd->status.vit + val, 1, max); break;
4561        case SP_INT: sd->status.int_= cap_value(sd->status.int_+ val, 1, max); break;
4562        case SP_DEX: sd->status.dex = cap_value(sd->status.dex + val, 1, max); break;
4563        case SP_LUK: sd->status.luk = cap_value(sd->status.luk + val, 1, max); break;
4564        default:
4565                clif_statusupack(sd,type,0,0);
4566                return 1;
4567        }
4568
4569        status_calc_pc(sd,0);
4570        clif_statusupack(sd,type,1,val);
4571
4572        return 0;
4573}
4574
4575/*==========================================
4576 * ƒXƒLƒ‹ƒ|ƒCƒ“ƒgŠ„‚èU‚è
4577 *------------------------------------------*/
4578int pc_skillup(struct map_session_data *sd,int skill_num)
4579{
4580        nullpo_retr(0, sd);
4581
4582        if(skill_num >= GD_SKILLBASE && skill_num < GD_SKILLBASE+MAX_GUILDSKILL){
4583                guild_skillup(sd, skill_num);
4584                return 0;
4585        }
4586
4587        if(skill_num >= HM_SKILLBASE && skill_num < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd){
4588                merc_hom_skillup(sd->hd, skill_num);
4589                return 0;
4590        }
4591
4592        if (skill_num < 0 || skill_num >= MAX_SKILL)
4593                return 0;
4594
4595        if(sd->status.skill_point>0 &&
4596                sd->status.skill[skill_num].id &&
4597                sd->status.skill[skill_num].flag==0 && //Don't allow raising while you have granted skills. [Skotlex]
4598                sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) )
4599        {
4600                sd->status.skill[skill_num].lv++;
4601                sd->status.skill_point--;
4602                if (!skill_get_inf(skill_num)) //Only recalculate for passive skills.
4603                        status_calc_pc(sd,0);
4604                else
4605                        pc_check_skilltree(sd, skill_num);
4606                clif_skillup(sd,skill_num);
4607                clif_updatestatus(sd,SP_SKILLPOINT);
4608                clif_skillinfoblock(sd);
4609        }
4610
4611        return 0;
4612}
4613
4614/*==========================================
4615 * /allskill
4616 *------------------------------------------*/
4617int pc_allskillup(struct map_session_data *sd)
4618{
4619        int i,id;
4620
4621        nullpo_retr(0, sd);
4622
4623        for(i=0;i<MAX_SKILL;i++){
4624                if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){
4625                        sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2;
4626                        sd->status.skill[i].flag=0;
4627                        if (!sd->status.skill[i].lv)
4628                                sd->status.skill[i].id=0;
4629                }
4630        }
4631
4632        //pc_calc_skilltree takes care of setting the ID to valid skills. [Skotlex]
4633        if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill)
4634        {       //Get ALL skills except npc/guild ones. [Skotlex]
4635                //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
4636                for(i=0;i<MAX_SKILL;i++){
4637                        if(!(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) && i!=SG_DEVIL && i!=MO_TRIPLEATTACK && i!=RG_SNATCHER)
4638                                sd->status.skill[i].lv=skill_get_max(i); //Nonexistant skills should return a max of 0 anyway.
4639                }
4640        }
4641        else
4642        {
4643                int inf2;
4644                for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0;i++){
4645                        inf2 = skill_get_inf2(id);
4646                        if (
4647                                (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
4648                                (inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) ||
4649                                id==SG_DEVIL
4650                        )
4651                                continue; //Cannot be learned normally.
4652                        sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_);    // celest
4653                }
4654        }
4655        status_calc_pc(sd,0);
4656        //Required because if you could level up all skills previously,
4657        //the update will not be sent as only the lv variable changes.
4658        clif_skillinfoblock(sd);
4659        return 0;
4660}
4661
4662/*==========================================
4663 * /resetlvl
4664 *------------------------------------------*/
4665int pc_resetlvl(struct map_session_data* sd,int type)
4666{
4667        int  i;
4668
4669        nullpo_retr(0, sd);
4670
4671        if (type != 3) //Also reset skills
4672                pc_resetskill(sd, 0);
4673
4674        if(type == 1){
4675        sd->status.skill_point=0;
4676        sd->status.base_level=1;
4677        sd->status.job_level=1;
4678        sd->status.base_exp=sd->status.base_exp=0;
4679        sd->status.job_exp=sd->status.job_exp=0;
4680        if(sd->sc.option !=0)
4681                sd->sc.option = 0;
4682
4683        sd->status.str=1;
4684        sd->status.agi=1;
4685        sd->status.vit=1;
4686        sd->status.int_=1;
4687        sd->status.dex=1;
4688        sd->status.luk=1;
4689        if(sd->status.class_ == JOB_NOVICE_HIGH)
4690                sd->status.status_point=100;    // not 88 [celest]
4691                // give platinum skills upon changing
4692                pc_skill(sd,142,1,0);
4693                pc_skill(sd,143,1,0);
4694        }
4695
4696        if(type == 2){
4697                sd->status.skill_point=0;
4698                sd->status.base_level=1;
4699                sd->status.job_level=1;
4700                sd->status.base_exp=0;
4701                sd->status.job_exp=0;
4702        }
4703        if(type == 3){
4704                sd->status.base_level=1;
4705                sd->status.base_exp=0;
4706        }
4707        if(type == 4){
4708                sd->status.job_level=1;
4709                sd->status.job_exp=0;
4710        }
4711
4712        clif_updatestatus(sd,SP_STATUSPOINT);
4713        clif_updatestatus(sd,SP_STR);
4714        clif_updatestatus(sd,SP_AGI);
4715        clif_updatestatus(sd,SP_VIT);
4716        clif_updatestatus(sd,SP_INT);
4717        clif_updatestatus(sd,SP_DEX);
4718        clif_updatestatus(sd,SP_LUK);
4719        clif_updatestatus(sd,SP_BASELEVEL);
4720        clif_updatestatus(sd,SP_JOBLEVEL);
4721        clif_updatestatus(sd,SP_STATUSPOINT);
4722        clif_updatestatus(sd,SP_NEXTBASEEXP);
4723        clif_updatestatus(sd,SP_NEXTJOBEXP);
4724        clif_updatestatus(sd,SP_SKILLPOINT);
4725
4726        clif_updatestatus(sd,SP_USTR);  // Updates needed stat points - Valaris
4727        clif_updatestatus(sd,SP_UAGI);
4728        clif_updatestatus(sd,SP_UVIT);
4729        clif_updatestatus(sd,SP_UINT);
4730        clif_updatestatus(sd,SP_UDEX);
4731        clif_updatestatus(sd,SP_ULUK);  // End Addition
4732
4733        for(i=0;i<EQI_MAX;i++) { // unequip items that can't be equipped by base 1 [Valaris]
4734                if(sd->equip_index[i] >= 0)
4735                        if(!pc_isequip(sd,sd->equip_index[i]))
4736                                pc_unequipitem(sd,sd->equip_index[i],2);
4737        }
4738
4739        if ((type == 1 || type == 2 || type == 3) && sd->status.party_id)
4740                party_send_levelup(sd);
4741
4742        status_calc_pc(sd,0);
4743        clif_skillinfoblock(sd);
4744
4745        return 0;
4746}
4747/*==========================================
4748 * /resetstate
4749 *------------------------------------------*/
4750int pc_resetstate(struct map_session_data* sd)
4751{
4752        nullpo_retr(0, sd);
4753
4754        if (battle_config.use_statpoint_table)
4755        {       // New statpoint table used here - Dexity
4756                int stat;
4757                if (sd->status.base_level > MAX_LEVEL)
4758                {       //statp[] goes out of bounds, can't reset!
4759                        ShowError("pc_resetstate: Can't reset stats of %d:%d, the base level (%d) is greater than the max level supported (%d)\n",
4760                                sd->status.account_id, sd->status.char_id, sd->status.base_level, MAX_LEVEL);
4761                        return 0;
4762                }
4763                stat = statp[sd->status.base_level];
4764                if (sd->class_&JOBL_UPPER)
4765                        stat+=52;       // extra 52+48=100 stat points
4766
4767                if (stat > USHRT_MAX)
4768                        sd->status.status_point = USHRT_MAX;
4769                else
4770                        sd->status.status_point = stat;
4771        } else { //Use new stat-calculating equation [Skotlex]
4772#define sumsp(a) (((a-1)/10 +2)*(5*((a-1)/10 +1) + (a-1)%10) -10)
4773                int add=0;
4774                add += sumsp(sd->status.str);
4775                add += sumsp(sd->status.agi);
4776                add += sumsp(sd->status.vit);
4777                add += sumsp(sd->status.int_);
4778                add += sumsp(sd->status.dex);
4779                add += sumsp(sd->status.luk);
4780                if (add > USHRT_MAX - sd->status.status_point)
4781                        sd->status.status_point = USHRT_MAX;
4782                else
4783                        sd->status.status_point+=add;
4784        }
4785
4786        sd->status.str=1;
4787        sd->status.agi=1;
4788        sd->status.vit=1;
4789        sd->status.int_=1;
4790        sd->status.dex=1;
4791        sd->status.luk=1;
4792
4793        clif_updatestatus(sd,SP_STR);
4794        clif_updatestatus(sd,SP_AGI);
4795        clif_updatestatus(sd,SP_VIT);
4796        clif_updatestatus(sd,SP_INT);
4797        clif_updatestatus(sd,SP_DEX);
4798        clif_updatestatus(sd,SP_LUK);
4799
4800        clif_updatestatus(sd,SP_USTR);  // Updates needed stat points - Valaris
4801        clif_updatestatus(sd,SP_UAGI);
4802        clif_updatestatus(sd,SP_UVIT);
4803        clif_updatestatus(sd,SP_UINT);
4804        clif_updatestatus(sd,SP_UDEX);
4805        clif_updatestatus(sd,SP_ULUK);  // End Addition
4806
4807        clif_updatestatus(sd,SP_STATUSPOINT);
4808        status_calc_pc(sd,0);
4809
4810        return 1;
4811}
4812
4813/*==========================================
4814 * /resetskill
4815 * if flag&1, perform block resync and status_calc call.
4816 * if flag&2, just count total amount of skill points used by player, do not really reset.
4817 *------------------------------------------*/
4818int pc_resetskill(struct map_session_data* sd, int flag)
4819{
4820        int i, lv, inf2, skill_point=0;
4821        nullpo_retr(0, sd);
4822
4823        if(!(flag&2))
4824        {       //Remove stuff lost when resetting skills.
4825                if (pc_checkskill(sd, SG_DEVIL) &&  !pc_nextjobexp(sd))
4826                        clif_status_load(&sd->bl, SI_DEVIL, 0); //Remove perma blindness due to skill-reset. [Skotlex]
4827                i = sd->sc.option;
4828                if (i&OPTION_RIDING && pc_checkskill(sd, KN_RIDING))
4829                i&=~OPTION_RIDING;
4830                if(i&OPTION_CART && pc_checkskill(sd, MC_PUSHCART))
4831                        i&=~OPTION_CART;
4832                if(i&OPTION_FALCON && pc_checkskill(sd, HT_FALCON))
4833                        i&=~OPTION_FALCON;
4834
4835                if(i != sd->sc.option)
4836                        pc_setoption(sd, i);
4837
4838                if(merc_is_hom_active(sd->hd) && pc_checkskill(sd, AM_CALLHOMUN))
4839                        merc_hom_vaporize(sd, 0);
4840        }
4841
4842        for (i = 1; i < MAX_SKILL; i++) {
4843                lv= sd->status.skill[i].lv;
4844                if (lv < 1) continue;
4845
4846                inf2 = skill_get_inf2(i);
4847
4848                if(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Avoid reseting wedding/linker skills.
4849                        continue;
4850
4851                if (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn)
4852                {       //Only handle quest skills in a special way when you can't learn them manually
4853                        if (battle_config.quest_skill_reset && !(flag&2))
4854                        {       //Wipe them
4855                                sd->status.skill[i].lv = 0;
4856                                sd->status.skill[i].flag = 0;
4857                        }
4858                        continue;
4859                }
4860                if (!sd->status.skill[i].flag)
4861                        skill_point += lv;
4862                else if (sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13)
4863                        skill_point += (sd->status.skill[i].flag - 2);
4864
4865                if (!(flag&2)) {
4866                        sd->status.skill[i].lv = 0;
4867                        sd->status.skill[i].flag = 0;
4868                }
4869        }
4870
4871        if (flag&2 || !skill_point) return skill_point;
4872
4873        if (sd->status.skill_point > USHRT_MAX - skill_point)
4874                sd->status.skill_point = USHRT_MAX;
4875        else
4876                sd->status.skill_point += skill_point;
4877
4878        if (flag&1) {
4879                clif_updatestatus(sd,SP_SKILLPOINT);
4880                clif_skillinfoblock(sd);
4881                status_calc_pc(sd,0);
4882        }
4883        return skill_point;
4884}
4885
4886/*==========================================
4887 * /resetfeel [Komurka]
4888 *------------------------------------------*/
4889int pc_resetfeel(struct map_session_data* sd)
4890{
4891        int i;
4892        nullpo_retr(0, sd);
4893
4894        for (i=0; i<3; i++)
4895        {
4896                sd->feel_map[i].m = -1;
4897                sd->feel_map[i].index = 0;
4898                pc_setglobalreg(sd,sg_info[i].feel_var,0);
4899        }
4900
4901        return 0;
4902}
4903
4904int pc_resethate(struct map_session_data* sd)
4905{
4906        int i;
4907        nullpo_retr(0, sd);
4908
4909        for (i=0; i<3; i++)
4910        {
4911                sd->hate_mob[i] = -1;
4912                pc_setglobalreg(sd,sg_info[i].hate_var,0);
4913        }
4914        return 0;
4915}
4916
4917int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
4918{
4919        int i;
4920        for (i = 0; i < ARRAYLENGTH(sd->skillatk) && sd->skillatk[i].id; i++)
4921        {
4922                if (sd->skillatk[i].id == skill_num)
4923                        return sd->skillatk[i].val;
4924        }
4925        return 0;
4926}
4927
4928int pc_skillheal_bonus(struct map_session_data *sd, int skill_num)
4929{
4930        int i;
4931        for (i = 0; i < ARRAYLENGTH(sd->skillheal) && sd->skillheal[i].id; i++)
4932        {
4933                if (sd->skillheal[i].id == skill_num)
4934                        return sd->skillheal[i].val;
4935        }
4936        return 0;
4937}
4938
4939void pc_respawn(struct map_session_data* sd, uint8 clrtype)
4940{
4941        if( !pc_isdead(sd) )
4942                return; // not applicable
4943
4944        pc_setstand(sd);
4945        pc_setrestartvalue(sd,3);
4946        if(pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype))
4947                clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
4948}
4949
4950static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr data)
4951{
4952        struct map_session_data *sd = map_id2sd(id);
4953        if( sd != NULL )
4954                pc_respawn(sd,0);
4955
4956        return 0;
4957}
4958
4959/*==========================================
4960 * Invoked when a player has received damage
4961 *------------------------------------------*/
4962void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int hp, unsigned int sp)
4963{
4964        if (sp) clif_updatestatus(sd,SP_SP);
4965        if (!hp) return;
4966
4967        if(pc_issit(sd)) {
4968                pc_setstand(sd);
4969                skill_sit(sd,0);
4970        }
4971
4972        clif_updatestatus(sd,SP_HP);
4973
4974        if(!src || src == &sd->bl)
4975                return;
4976
4977        if(sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support)
4978                pet_target_check(sd,src,1);
4979
4980        sd->canlog_tick = gettick();
4981        return;
4982}
4983
4984int pc_dead(struct map_session_data *sd,struct block_list *src)
4985{
4986        int i=0,j=0,k=0;
4987        unsigned int tick = gettick();
4988
4989        if(sd->vender_id)
4990                vending_closevending(sd);
4991
4992        for(k = 0; k < 5; k++)
4993        if (sd->devotion[k]){
4994                struct map_session_data *devsd = map_id2sd(sd->devotion[k]);
4995                if (devsd) status_change_end(&devsd->bl,SC_DEVOTION,-1);
4996                sd->devotion[k] = 0;
4997        }
4998
4999        if(sd->status.pet_id > 0 && sd->pd)
5000        {
5001                struct s_pet *pet = &sd->pd->pet;
5002                if(!map[sd->bl.m].flag.noexppenalty){
5003                        pet->intimate -= sd->pd->petDB->die;
5004                        if(pet->intimate < 0)
5005                                pet->intimate = 0;
5006                        clif_send_petdata(sd,sd->pd,1,pet->intimate);
5007                }
5008                if(sd->pd->target_id) // Unlock all targets...
5009                        pet_unlocktarget(sd->pd);
5010        }
5011
5012        if(sd->status.hom_id > 0)       //orn
5013                merc_hom_vaporize(sd, 0);
5014
5015        // Leave duel if you die [LuzZza]
5016        if(battle_config.duel_autoleave_when_die) {
5017                if(sd->duel_group > 0)
5018                        duel_leave(sd->duel_group, sd);
5019                if(sd->duel_invite > 0)
5020                        duel_reject(sd->duel_invite, sd);
5021        }
5022
5023        pc_setdead(sd);
5024        //Reset menu skills/item skills
5025        if (sd->skillitem)
5026                sd->skillitem = sd->skillitemlv = 0;
5027        if (sd->menuskill_id)
5028                sd->menuskill_id = sd->menuskill_val = 0;
5029        //Reset ticks.
5030        sd->hp_loss.tick = sd->sp_loss.tick = sd->hp_regen.tick = sd->sp_regen.tick = 0;
5031
5032        pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1);
5033        pc_setglobalreg(sd,"killerrid",src?src->id:0);
5034        npc_script_event(sd,NPCE_DIE);
5035
5036        if ( sd && sd->spiritball && (sd->class_&MAPID_BASEMASK)==MAPID_GUNSLINGER ) // maybe also monks' spiritballs ?
5037                pc_delspiritball(sd,sd->spiritball,0);
5038
5039        if (src)
5040        switch (src->type) {
5041        case BL_MOB:
5042        {
5043                struct mob_data *md=(struct mob_data *)src;
5044                if(md->target_id==sd->bl.id)
5045                        mob_unlocktarget(md,tick);
5046                if(battle_config.mobs_level_up && md->status.hp &&
5047                        (unsigned int)md->level < pc_maxbaselv(sd) &&
5048                        !md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex]
5049                ) {     // monster level up [Valaris]
5050                        clif_misceffect(&md->bl,0);
5051                        md->level++;
5052                        status_calc_mob(md, 0);
5053                        status_percent_heal(src,10,0);
5054                }
5055                if(md->nd)
5056                        mob_script_callback(md, &sd->bl, CALLBACK_KILL);
5057        }
5058        break;
5059        case BL_PET: //Pass on to master...
5060                src = &((TBL_PET*)src)->msd->bl;
5061        break;
5062        case BL_HOM:
5063                src = &((TBL_HOM*)src)->master->bl;
5064        break;
5065        }
5066
5067        if (src && src->type == BL_PC)
5068        {
5069                struct map_session_data *ssd = (struct map_session_data *)src;
5070                pc_setglobalreg(ssd, "killedrid", sd->bl.id);
5071                npc_script_event(ssd, NPCE_KILLPC);
5072
5073                if (battle_config.pk_mode&2) {
5074                        ssd->status.manner -= 5;
5075                        if(ssd->status.manner < 0)
5076                                sc_start(src,SC_NOCHAT,100,0,0);
5077#if 0
5078                        // PK/Karma system code (not enabled yet) [celest]
5079                        // originally from Kade Online, so i don't know if any of these is correct ^^;
5080                        // note: karma is measured REVERSE, so more karma = more 'evil' / less honourable,
5081                        // karma going down = more 'good' / more honourable.
5082                        // The Karma System way...
5083
5084                        if (sd->status.karma > ssd->status.karma) {     // If player killed was more evil
5085                                sd->status.karma--;
5086                                ssd->status.karma--;
5087                        }
5088                        else if (sd->status.karma < ssd->status.karma)  // If player killed was more good
5089                                ssd->status.karma++;
5090
5091
5092                        // or the PK System way...
5093
5094                        if (sd->status.karma > 0)       // player killed is dishonourable?
5095                                ssd->status.karma--; // honour points earned
5096                        sd->status.karma++;     // honour points lost
5097
5098                        // To-do: Receive exp on certain occasions
5099#endif
5100                }
5101        }
5102
5103        if(battle_config.bone_drop==2
5104                || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp))
5105        {
5106                struct item item_tmp;
5107                memset(&item_tmp,0,sizeof(item_tmp));
5108                item_tmp.nameid=7420; //PVP Skull item ID
5109                item_tmp.identify=1;
5110                item_tmp.card[0]=CARD0_CREATE;
5111                item_tmp.card[1]=0;
5112                item_tmp.card[2]=GetWord(sd->status.char_id,0); // CharId
5113                item_tmp.card[3]=GetWord(sd->status.char_id,1);
5114                map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
5115        }
5116
5117        // activate Steel body if a super novice dies at 99+% exp [celest]
5118        if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag)
5119        {
5120                unsigned int next = pc_nextbaseexp(sd);
5121                if( next == 0 ) next = pc_thisbaseexp(sd);
5122                if( get_percentage(sd->status.base_exp,next) >= 99 && !map_flag_gvg(sd->bl.m) )
5123                {
5124                        sd->state.snovice_dead_flag = 1;
5125                        pc_setstand(sd);
5126                        status_percent_heal(&sd->bl, 100, 100);
5127                        clif_resurrection(&sd->bl, 1);
5128                        if(battle_config.pc_invincible_time)
5129                                pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
5130                        sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1));
5131                        if(map_flag_gvg(sd->bl.m))
5132                                pc_respawn_timer(-1, gettick(), sd->bl.id, 0);
5133                        return 0;
5134                }
5135        }
5136
5137        // changed penalty options, added death by player if pk_mode [Valaris]
5138        if(battle_config.death_penalty_type
5139                && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
5140                && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
5141                && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
5142        {
5143                unsigned int base_penalty =0;
5144                if (battle_config.death_penalty_base > 0) {
5145                        switch (battle_config.death_penalty_type) {
5146                                case 1:
5147                                        base_penalty = (unsigned int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
5148                                break;
5149                                case 2:
5150                                        base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
5151                                break;
5152                        }
5153                        if(base_penalty) {
5154                                if (battle_config.pk_mode && src && src->type==BL_PC)
5155                                        base_penalty*=2;
5156                                if(sd->status.base_exp < base_penalty)
5157                                        sd->status.base_exp = 0;
5158                                else
5159                                        sd->status.base_exp -= base_penalty;
5160                                clif_updatestatus(sd,SP_BASEEXP);
5161                        }
5162                }
5163                if(battle_config.death_penalty_job > 0)
5164                {
5165                        base_penalty = 0;
5166                        switch (battle_config.death_penalty_type) {
5167                                case 1:
5168                                        base_penalty = (unsigned int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
5169                                break;
5170                                case 2:
5171                                        base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
5172                                break;
5173                        }
5174                        if(base_penalty) {
5175                                if (battle_config.pk_mode && src && src->type==BL_PC)
5176                                        base_penalty*=2;
5177                                if(sd->status.job_exp < base_penalty)
5178                                        sd->status.job_exp = 0;
5179                                else
5180                                        sd->status.job_exp -= base_penalty;
5181                                clif_updatestatus(sd,SP_JOBEXP);
5182                        }
5183                }
5184                if(battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty)
5185                {
5186                        base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
5187                        if(base_penalty)
5188                                pc_payzeny(sd, base_penalty);
5189                }
5190        }
5191
5192        if(map[sd->bl.m].flag.pvp_nightmaredrop)
5193        { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
5194                for(j=0;j<MAX_DROP_PER_MAP;j++){
5195                        int id = map[sd->bl.m].drop_list[j].drop_id;
5196                        int type = map[sd->bl.m].drop_list[j].drop_type;
5197                        int per = map[sd->bl.m].drop_list[j].drop_per;
5198                        if(id == 0)
5199                                continue;
5200                        if(id == -1){
5201                                int eq_num=0,eq_n[MAX_INVENTORY];
5202                                memset(eq_n,0,sizeof(eq_n));
5203                                for(i=0;i<MAX_INVENTORY;i++){
5204                                        int k;
5205                                        if( (type == 1 && !sd->status.inventory[i].equip)
5206                                                || (type == 2 && sd->status.inventory[i].equip)
5207                                                ||  type == 3)
5208                                        {
5209                                                ARR_FIND( 0, MAX_INVENTORY, k, eq_n[k] <= 0 );
5210                                                if( k < MAX_INVENTORY )
5211                                                        eq_n[k] = i;
5212
5213                                                eq_num++;
5214                                        }
5215                                }
5216                                if(eq_num > 0){
5217                                        int n = eq_n[rand()%eq_num];
5218                                        if(rand()%10000 < per){
5219                                                if(sd->status.inventory[n].equip)
5220                                                        pc_unequipitem(sd,n,3);
5221                                                pc_dropitem(sd,n,1);
5222                                        }
5223                                }
5224                        }
5225                        else if(id > 0){
5226                                for(i=0;i<MAX_INVENTORY;i++){
5227                                        if(sd->status.inventory[i].nameid == id
5228                                                && rand()%10000 < per
5229                                                && ((type == 1 && !sd->status.inventory[i].equip)
5230                                                        || (type == 2 && sd->status.inventory[i].equip)
5231                                                        || type == 3) ){
5232                                                if(sd->status.inventory[i].equip)
5233                                                        pc_unequipitem(sd,i,3);
5234                                                pc_dropitem(sd,i,1);
5235                                                break;
5236                                        }
5237                                }
5238                        }
5239                }
5240        }
5241        // pvp
5242        // disable certain pvp functions on pk_mode [Valaris]
5243        if (map[sd->bl.m].flag.gvg_dungeon ||
5244                (map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank))
5245        {       //Pvp points always take effect on gvg_dungeon maps.
5246                sd->pvp_point -= 5;
5247                sd->pvp_lost++;
5248                if (src && src->type == BL_PC) {
5249                        struct map_session_data *ssd = (struct map_session_data *)src;
5250                        ssd->pvp_point++;
5251                        ssd->pvp_won++;
5252                }
5253                if( sd->pvp_point < 0 ){
5254                        sd->pvp_point=0;
5255                        add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0);
5256                        return 1|8;
5257                }
5258        }
5259        //GvG
5260        if(map_flag_gvg(sd->bl.m)){
5261                add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0);
5262                return 1|8;
5263        }
5264
5265        //Reset "can log out" tick.
5266        if (battle_config.prevent_logout)
5267                sd->canlog_tick = gettick() - battle_config.prevent_logout;
5268        return 1;
5269}
5270
5271void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp)
5272{
5273        if(hp) clif_updatestatus(sd,SP_HP);
5274        if(sp) clif_updatestatus(sd,SP_SP);
5275
5276        pc_setstand(sd);
5277        if(battle_config.pc_invincible_time > 0)
5278                pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
5279}
5280// script? ˜A
5281//
5282/*==========================================
5283 * script—pPCƒXƒe?ƒ^ƒX?‚ݏo‚µ
5284 *------------------------------------------*/
5285int pc_readparam(struct map_session_data* sd,int type)
5286{
5287        int val = 0;
5288
5289        nullpo_retr(0, sd);
5290
5291        switch(type) {
5292        case SP_SKILLPOINT:  val = sd->status.skill_point; break;
5293        case SP_STATUSPOINT: val = sd->status.status_point; break;
5294        case SP_ZENY:        val = sd->status.zeny; break;
5295        case SP_BASELEVEL:   val = sd->status.base_level; break;
5296        case SP_JOBLEVEL:    val = sd->status.job_level; break;
5297        case SP_CLASS:       val = sd->status.class_; break;
5298        case SP_BASEJOB:     val = pc_mapid2jobid(sd->class_&MAPID_UPPERMASK, sd->status.sex); break; //Base job, extracting upper type.
5299        case SP_UPPER:       val = sd->class_&JOBL_UPPER?1:(sd->class_&JOBL_BABY?2:0); break;
5300        case SP_BASECLASS:   val = pc_mapid2jobid(sd->class_&MAPID_BASEMASK, sd->status.sex); break; //Extract base class tree. [Skotlex]
5301        case SP_SEX:         val = sd->status.sex; break;
5302        case SP_WEIGHT:      val = sd->weight; break;
5303        case SP_MAXWEIGHT:   val = sd->max_weight; break;
5304        case SP_BASEEXP:     val = sd->status.base_exp; break;
5305        case SP_JOBEXP:      val = sd->status.job_exp; break;
5306        case SP_NEXTBASEEXP: val = pc_nextbaseexp(sd); break;
5307        case SP_NEXTJOBEXP:  val = pc_nextjobexp(sd); break;
5308        case SP_HP:          val = sd->battle_status.hp; break;
5309        case SP_MAXHP:       val = sd->battle_status.max_hp; break;
5310        case SP_SP:          val = sd->battle_status.sp; break;
5311        case SP_MAXSP:       val = sd->battle_status.max_sp; break;
5312        case SP_STR:         val = sd->status.str; break;
5313        case SP_AGI:         val = sd->status.agi; break;
5314        case SP_VIT:         val = sd->status.vit; break;
5315        case SP_INT:         val = sd->status.int_; break;
5316        case SP_DEX:         val = sd->status.dex; break;
5317        case SP_LUK:         val = sd->status.luk; break;
5318        case SP_KARMA:       val = sd->status.karma; break;
5319        case SP_MANNER:      val = sd->status.manner; break;
5320        case SP_FAME:        val = sd->status.fame; break;
5321        }
5322
5323        return val;
5324}
5325
5326/*==========================================
5327 * script—pPCƒXƒe?ƒ^ƒXÝ’è
5328 *------------------------------------------*/
5329int pc_setparam(struct map_session_data *sd,int type,int val)
5330{
5331        int i = 0;
5332
5333        nullpo_retr(0, sd);
5334
5335        switch(type){
5336        case SP_BASELEVEL:
5337                if ((unsigned int)val > pc_maxbaselv(sd)) //Capping to max
5338                        val = pc_maxbaselv(sd);
5339                if ((unsigned int)val > sd->status.base_level) {
5340                        int stat=0;
5341                        for (i = 1; i <= (int)((unsigned int)val - sd->status.base_level); i++)
5342                                stat += (sd->status.base_level + i + 14) / 5 ;
5343                        if (sd->status.status_point > USHRT_MAX - stat)
5344
5345                                sd->status.status_point = USHRT_MAX;
5346                        else
5347                                sd->status.status_point += stat;
5348                }
5349                sd->status.base_level = (unsigned int)val;
5350                sd->status.base_exp = 0;
5351                clif_updatestatus(sd, SP_BASELEVEL);
5352                clif_updatestatus(sd, SP_NEXTBASEEXP);
5353                clif_updatestatus(sd, SP_STATUSPOINT);
5354                clif_updatestatus(sd, SP_BASEEXP);
5355                status_calc_pc(sd, 0);
5356                break;
5357        case SP_JOBLEVEL:
5358                if ((unsigned int)val >= sd->status.job_level) {
5359                        if ((unsigned int)val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd);
5360                        if (sd->status.skill_point > USHRT_MAX - val + sd->status.job_level)
5361                                sd->status.skill_point = USHRT_MAX;
5362                        else
5363                                sd->status.skill_point += val-sd->status.job_level;
5364                        clif_updatestatus(sd, SP_SKILLPOINT);
5365                }
5366                sd->status.job_level = (unsigned int)val;
5367                sd->status.job_exp = 0;
5368                clif_updatestatus(sd, SP_JOBLEVEL);
5369                clif_updatestatus(sd, SP_NEXTJOBEXP);
5370                clif_updatestatus(sd, SP_JOBEXP);
5371                status_calc_pc(sd, 0);
5372                clif_updatestatus(sd,type);
5373                break;
5374        case SP_SKILLPOINT:
5375                sd->status.skill_point = val;
5376                break;
5377        case SP_STATUSPOINT:
5378                sd->status.status_point = val;
5379                break;
5380        case SP_ZENY:
5381                sd->status.zeny = cap_value(val, 0, MAX_ZENY);
5382                break;
5383        case SP_BASEEXP:
5384                if(pc_nextbaseexp(sd) > 0) {
5385                        sd->status.base_exp = val;
5386                        pc_checkbaselevelup(sd);
5387                }
5388                break;
5389        case SP_JOBEXP:
5390                if(pc_nextjobexp(sd) > 0) {
5391                        sd->status.job_exp = val;
5392                        pc_checkjoblevelup(sd);
5393                }
5394                break;
5395        case SP_SEX:
5396                sd->status.sex = val;
5397                break;
5398        case SP_WEIGHT:
5399                sd->weight = val;
5400                break;
5401        case SP_MAXWEIGHT:
5402                sd->max_weight = val;
5403                break;
5404        case SP_HP:
5405                sd->battle_status.hp = val;
5406                break;
5407        case SP_MAXHP:
5408                sd->battle_status.max_hp = val;
5409                break;
5410        case SP_SP:
5411                sd->battle_status.sp = val;
5412                break;
5413        case SP_MAXSP:
5414                sd->battle_status.max_sp = val;
5415                break;
5416        case SP_STR:
5417                sd->status.str = val;
5418                break;
5419        case SP_AGI:
5420                sd->status.agi = val;
5421                break;
5422        case SP_VIT:
5423                sd->status.vit = val;
5424                break;
5425        case SP_INT:
5426                sd->status.int_ = val;
5427                break;
5428        case SP_DEX:
5429                sd->status.dex = val;
5430                break;
5431        case SP_LUK:
5432                sd->status.luk = val;
5433                break;
5434        case SP_KARMA:
5435                sd->status.karma = val;
5436                break;
5437        case SP_MANNER:
5438                sd->status.manner = val;
5439                break;
5440        case SP_FAME:
5441                sd->status.fame = val;
5442                break;
5443        }
5444        clif_updatestatus(sd,type);
5445
5446        return 1;
5447}
5448
5449/*==========================================
5450 * HP/SP Healing. If flag is passed, the heal type is through clif_heal, otherwise update status.
5451 *------------------------------------------*/
5452void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int type)
5453{
5454        if (type) {
5455                if (hp)
5456                        clif_heal(sd->fd,SP_HP,hp);
5457                if (sp)
5458                        clif_heal(sd->fd,SP_SP,sp);
5459        } else {
5460                if(hp)
5461                        clif_updatestatus(sd,SP_HP);
5462                if(sp)
5463                        clif_updatestatus(sd,SP_SP);
5464        }
5465        return;
5466}
5467
5468/*==========================================
5469 * HP/SP‰ñ•œ
5470 *------------------------------------------*/
5471int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
5472{
5473        int i, bonus;
5474
5475        if(hp) {
5476                bonus = 100 + (sd->battle_status.vit<<1)
5477                        + pc_checkskill(sd,SM_RECOVERY)*10
5478                        + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
5479                // A potion produced by an Alchemist in the Fame Top 10 gets +50% effect [DracoRPG]
5480                if (potion_flag > 1)
5481                        bonus += bonus*(potion_flag-1)*50/100;
5482                //Item Group bonuses
5483                bonus += bonus*itemdb_group_bonus(sd, itemid)/100;
5484                //Individual item bonuses.
5485                for(i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++)
5486                {
5487                        if (sd->itemhealrate[i].nameid == itemid) {
5488                                bonus += bonus*sd->itemhealrate[i].rate/100;
5489                                break;
5490                        }
5491                }
5492                if(bonus!=100)
5493                        hp = hp * bonus / 100;
5494
5495                // Recovery Potion
5496                if( sd->sc.data[SC_INCHEALRATE] )
5497                        hp += (int)(hp * sd->sc.data[SC_INCHEALRATE]->val1/100.);
5498        }
5499        if(sp) {
5500                bonus = 100 + (sd->battle_status.int_<<1)
5501                        + pc_checkskill(sd,MG_SRECOVERY)*10
5502                        + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
5503                if (potion_flag > 1)
5504                        bonus += bonus*(potion_flag-1)*50/100;
5505                if(bonus != 100)
5506                        sp = sp * bonus / 100;
5507        }
5508
5509        if (sd->sc.data[SC_CRITICALWOUND])
5510        {
5511                hp -= hp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
5512                sp -= sp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
5513        }
5514
5515        return status_heal(&sd->bl, hp, sp, 1);
5516}
5517
5518/*==========================================
5519 * HP/SP‰ñ•œ
5520 *------------------------------------------*/
5521int pc_percentheal(struct map_session_data *sd,int hp,int sp)
5522{
5523        nullpo_retr(0, sd);
5524
5525        if(hp > 100) hp = 100;
5526        else
5527        if(hp <-100) hp =-100;
5528
5529        if(sp > 100) sp = 100;
5530        else
5531        if(sp <-100) sp =-100;
5532
5533        if(hp >= 0 && sp >= 0) //Heal
5534                return status_percent_heal(&sd->bl, hp, sp);
5535
5536        if(hp <= 0 && sp <= 0) //Damage (negative rates indicate % of max rather than current), and only kill target IF the specified amount is 100%
5537                return status_percent_damage(NULL, &sd->bl, hp, sp, hp==-100);
5538
5539        //Crossed signs
5540        if(hp) {
5541                if(hp > 0)
5542                        status_percent_heal(&sd->bl, hp, 0);
5543                else
5544                        status_percent_damage(NULL, &sd->bl, hp, 0, hp==-100);
5545        }
5546
5547        if(sp) {
5548                if(sp > 0)
5549                        status_percent_heal(&sd->bl, 0, sp);
5550                else
5551                        status_percent_damage(NULL, &sd->bl, 0, sp, false);
5552        }
5553        return 0;
5554}
5555
5556/*==========================================
5557 * E?X
5558 * ˆø?  job E‹Æ 0`23
5559 *              upper ’ʏí 0, ?¶ 1, —{Žq 2, ‚»‚Ì‚Ü‚Ü -1
5560 * Rewrote to make it tidider [Celest]
5561 *------------------------------------------*/
5562int pc_jobchange(struct map_session_data *sd,int job, int upper)
5563{
5564        int i, fame_flag=0;
5565        int b_class;
5566
5567        nullpo_retr(0, sd);
5568
5569        if (job < 0)
5570                return 1;
5571
5572        //Normalize job.
5573        b_class = pc_jobid2mapid(job);
5574        if (b_class == -1)
5575                return 1;
5576        switch (upper) {
5577                case 1:
5578                        b_class|= JOBL_UPPER;
5579                        break;
5580                case 2:
5581                        b_class|= JOBL_BABY;
5582                        break;
5583        }
5584        //This will automatically adjust bard/dancer classes to the correct gender
5585        //That is, if you try to jobchange into dancer, it will turn you to bard.
5586        job = pc_mapid2jobid(b_class, sd->status.sex);
5587        if (job == -1)
5588                return 1;
5589
5590        if ((unsigned short)b_class == sd->class_)
5591                return 1; //Nothing to change.
5592        // check if we are changing from 1st to 2nd job
5593        if (b_class&JOBL_2) {
5594                if (!(sd->class_&JOBL_2))
5595                        sd->change_level = sd->status.job_level;
5596                else if (!sd->change_level)
5597                        sd->change_level = 40; //Assume 40?
5598                pc_setglobalreg (sd, "jobchange_level", sd->change_level);
5599        }
5600
5601        if(sd->cloneskill_id) {
5602                sd->cloneskill_id = 0;
5603                pc_setglobalreg(sd, "CLONE_SKILL", 0);
5604                pc_setglobalreg(sd, "CLONE_SKILL_LV", 0);
5605        }
5606        if ((b_class&&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK))
5607        { //Things to remove when changing class tree.
5608                const int class_ = pc_class2idx(sd->status.class_);
5609                short id;
5610                for(i = 0; i < MAX_SKILL_TREE && (id = skill_tree[class_][i].id) > 0; i++) {
5611                        //Remove status specific to your current tree skills.
5612                        enum sc_type sc = status_skill2sc(id);
5613                        if (sc > SC_COMMON_MAX && sd->sc.data[sc])
5614                                status_change_end(&sd->bl, sc, -1);
5615                }
5616        }
5617
5618        sd->status.class_ = job;
5619        fame_flag = pc_famerank(sd->status.char_id,sd->class_&MAPID_UPPERMASK);
5620        sd->class_ = (unsigned short)b_class;
5621        sd->status.job_level=1;
5622        sd->status.job_exp=0;
5623        clif_updatestatus(sd,SP_JOBLEVEL);
5624        clif_updatestatus(sd,SP_JOBEXP);
5625        clif_updatestatus(sd,SP_NEXTJOBEXP);
5626
5627        for(i=0;i<EQI_MAX;i++) {
5628                if(sd->equip_index[i] >= 0)
5629                        if(!pc_isequip(sd,sd->equip_index[i]))
5630                                pc_unequipitem(sd,sd->equip_index[i],2);        // ?”õŠO‚µ
5631        }
5632
5633        //Change look, if disguised, you need to undisguise
5634        //to correctly calculate new job sprite without
5635        if (sd->disguise)
5636                pc_disguise(sd, 0);
5637
5638        status_set_viewdata(&sd->bl, job);
5639        clif_changelook(&sd->bl,LOOK_BASE,sd->vd.class_); // move sprite update to prevent client crashes with incompatible equipment [Valaris]
5640        if(sd->vd.cloth_color)
5641                clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
5642
5643        //Update skill tree.
5644        pc_calc_skilltree(sd);
5645        clif_skillinfoblock(sd);
5646
5647        //Remove peco/cart/falcon
5648        i = sd->sc.option;
5649        if(i&OPTION_RIDING && !pc_checkskill(sd, KN_RIDING))
5650                i&=~OPTION_RIDING;
5651        if(i&OPTION_CART && !pc_checkskill(sd, MC_PUSHCART))
5652                i&=~OPTION_CART;
5653        if(i&OPTION_FALCON && !pc_checkskill(sd, HT_FALCON))
5654                i&=~OPTION_FALCON;
5655
5656        if(i != sd->sc.option)
5657                pc_setoption(sd, i);
5658
5659        if(merc_is_hom_active(sd->hd) && !pc_checkskill(sd, AM_CALLHOMUN))
5660                merc_hom_vaporize(sd, 0);
5661
5662        if(sd->status.manner < 0)
5663                clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
5664
5665        status_calc_pc(sd,0);
5666        pc_checkallowskill(sd);
5667        pc_equiplookall(sd);
5668
5669        //if you were previously famous, not anymore.
5670        if (fame_flag) {
5671                chrif_save(sd,0);
5672                chrif_buildfamelist();
5673        } else if (sd->status.fame > 0) {
5674                //It may be that now they are famous?
5675                switch (sd->class_&MAPID_UPPERMASK) {
5676                        case MAPID_BLACKSMITH:
5677                        case MAPID_ALCHEMIST:
5678                        case MAPID_TAEKWON:
5679                                chrif_save(sd,0);
5680                                chrif_buildfamelist();
5681                        break;
5682                }
5683        }
5684
5685        return 0;
5686}
5687
5688/*==========================================
5689 * Œ©‚œ–Ú?X
5690 *------------------------------------------*/
5691int pc_equiplookall(struct map_session_data *sd)
5692{
5693        nullpo_retr(0, sd);
5694
5695#if PACKETVER < 4
5696        clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
5697        clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
5698#else
5699        clif_changelook(&sd->bl,LOOK_WEAPON,0);
5700        clif_changelook(&sd->bl,LOOK_SHOES,0);
5701#endif
5702        clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
5703        clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
5704        clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
5705
5706        return 0;
5707}
5708
5709/*==========================================
5710 * Œ©‚œ–Ú?X
5711 *------------------------------------------*/
5712int pc_changelook(struct map_session_data *sd,int type,int val)
5713{
5714        nullpo_retr(0, sd);
5715
5716        switch(type){
5717        case LOOK_HAIR: //Use the battle_config limits! [Skotlex]
5718                if (val < battle_config.min_hair_style)
5719                        val = battle_config.min_hair_style;
5720                else if (val > battle_config.max_hair_style)
5721                        val = battle_config.max_hair_style;
5722                if (sd->status.hair != val)
5723                {
5724                        sd->status.hair=val;
5725                        if (sd->status.guild_id) //Update Guild Window. [Skotlex]
5726                                intif_guild_change_memberinfo(sd->status.guild_id,sd->status.account_id,sd->status.char_id,
5727                                GMI_HAIR,&sd->status.hair,sizeof(sd->status.hair));
5728                }
5729                break;
5730        case LOOK_WEAPON:
5731                sd->status.weapon=val;
5732                break;
5733        case LOOK_HEAD_BOTTOM:
5734                sd->status.head_bottom=val;
5735                break;
5736        case LOOK_HEAD_TOP:
5737                sd->status.head_top=val;
5738                break;
5739        case LOOK_HEAD_MID:
5740                sd->status.head_mid=val;
5741                break;
5742        case LOOK_HAIR_COLOR:   //Use the battle_config limits! [Skotlex]
5743                if (val < battle_config.min_hair_color)
5744                        val = battle_config.min_hair_color;
5745                else if (val > battle_config.max_hair_color)
5746                        val = battle_config.max_hair_color;
5747                if (sd->status.hair_color != val)
5748                {
5749                        sd->status.hair_color=val;
5750                        if (sd->status.guild_id) //Update Guild Window. [Skotlex]
5751                                intif_guild_change_memberinfo(sd->status.guild_id,sd->status.account_id,sd->status.char_id,
5752                                GMI_HAIR_COLOR,&sd->status.hair_color,sizeof(sd->status.hair_color));
5753                }
5754                break;
5755        case LOOK_CLOTHES_COLOR:        //Use the battle_config limits! [Skotlex]
5756                if (val < battle_config.min_cloth_color)
5757                        val = battle_config.min_cloth_color;
5758                else if (val > battle_config.max_cloth_color)
5759                        val = battle_config.max_cloth_color;
5760                sd->status.clothes_color=val;
5761                break;
5762        case LOOK_SHIELD:
5763                sd->status.shield=val;
5764                break;
5765        case LOOK_SHOES:
5766                break;
5767        }
5768        clif_changelook(&sd->bl,type,val);
5769        return 0;
5770}
5771
5772/*==========================================
5773 * •t?•i(‘é,ƒyƒR,ƒJ?ƒg)Ý’è
5774 *------------------------------------------*/
5775int pc_setoption(struct map_session_data *sd,int type)
5776{
5777        int p_type, new_look=0;
5778        nullpo_retr(0, sd);
5779        p_type = sd->sc.option;
5780
5781        //Option has to be changed client-side before the class sprite or it won't always work (eg: Wedding sprite) [Skotlex]
5782        sd->sc.option=type;
5783        clif_changeoption(&sd->bl);
5784
5785        if (type&OPTION_RIDING && !(p_type&OPTION_RIDING) && (sd->class_&MAPID_BASEMASK) == MAPID_SWORDMAN)
5786        {       //We are going to mount. [Skotlex]
5787                new_look = -1;
5788                clif_status_load(&sd->bl,SI_RIDING,1);
5789                status_calc_pc(sd,0); //Mounting/Umounting affects walk and attack speeds.
5790        }
5791        else if (!(type&OPTION_RIDING) && p_type&OPTION_RIDING && (sd->class_&MAPID_BASEMASK) == MAPID_SWORDMAN)
5792        {       //We are going to dismount.
5793                new_look = -1;
5794                clif_status_load(&sd->bl,SI_RIDING,0);
5795                status_calc_pc(sd,0); //Mounting/Umounting affects walk and attack speeds.
5796        }
5797        if(type&OPTION_CART && !(p_type&OPTION_CART))
5798        { //Cart On
5799                clif_cartlist(sd);
5800                clif_updatestatus(sd, SP_CARTINFO);
5801                if(pc_checkskill(sd, MC_PUSHCART) < 10)
5802                        status_calc_pc(sd,0); //Apply speed penalty.
5803        } else
5804        if(!(type&OPTION_CART) && p_type&OPTION_CART)
5805        { //Cart Off
5806                clif_clearcart(sd->fd);
5807                if(pc_checkskill(sd, MC_PUSHCART) < 10)
5808                        status_calc_pc(sd,0); //Remove speed penalty.
5809        }
5810
5811        if (type&OPTION_FALCON && !(p_type&OPTION_FALCON)) //Falcon ON
5812                clif_status_load(&sd->bl,SI_FALCON,1);
5813        else if (!(type&OPTION_FALCON) && p_type&OPTION_FALCON) //Falcon OFF
5814                clif_status_load(&sd->bl,SI_FALCON,0);
5815
5816        if (type&OPTION_FLYING && !(p_type&OPTION_FLYING))
5817                new_look = JOB_STAR_GLADIATOR2;
5818        else if (!(type&OPTION_FLYING) && p_type&OPTION_FLYING)
5819                new_look = -1;
5820
5821        if (type&OPTION_WEDDING && !(p_type&OPTION_WEDDING))
5822                new_look = JOB_WEDDING;
5823        else if (!(type&OPTION_WEDDING) && p_type&OPTION_WEDDING)
5824                new_look = -1;
5825
5826        if (type&OPTION_XMAS && !(p_type&OPTION_XMAS))
5827                new_look = JOB_XMAS;
5828        else if (!(type&OPTION_XMAS) && p_type&OPTION_XMAS)
5829                new_look = -1;
5830
5831        if (type&OPTION_SUMMER && !(p_type&OPTION_SUMMER))
5832                new_look = JOB_SUMMER;
5833        else if (!(type&OPTION_SUMMER) && p_type&OPTION_SUMMER)
5834                new_look = -1;
5835
5836        if (sd->disguise)
5837                return 0; //Disguises break sprite changes
5838
5839        if (new_look < 0) { //Restore normal look.
5840                status_set_viewdata(&sd->bl, sd->status.class_);
5841                new_look = sd->vd.class_;
5842        }
5843        if (new_look) {
5844                //Stop attacking on new view change (to prevent wedding/santa attacks.
5845                pc_stop_attack(sd);
5846                clif_changelook(&sd->bl,LOOK_BASE,new_look);
5847                if (sd->vd.cloth_color)
5848                        clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
5849        }
5850        return 0;
5851}
5852
5853/*==========================================
5854 * ƒJ?ƒgÝ’è
5855 *------------------------------------------*/
5856int pc_setcart(struct map_session_data *sd,int type)
5857{
5858        int cart[6] = {0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
5859        int option;
5860
5861        nullpo_retr(0, sd);
5862
5863        if( type < 0 || type > 5 )
5864                return 1;// Never trust the values sent by the client! [Skotlex]
5865
5866        if( pc_checkskill(sd,MC_PUSHCART) <= 0 )
5867                return 1;// Push cart is required
5868
5869        // Update option
5870        option = sd->sc.option;
5871        option &= ~OPTION_CART;// clear cart bits
5872        option |= cart[type]; // set cart
5873        pc_setoption(sd, option);
5874
5875        return 0;
5876}
5877
5878/*==========================================
5879 * ‘éÝ’è
5880 *------------------------------------------*/
5881int pc_setfalcon(TBL_PC* sd, int flag)
5882{
5883        if( flag ){
5884                if( pc_checkskill(sd,HT_FALCON)>0 )     // ƒtƒ@ƒ‹ƒRƒ“ƒ}ƒXƒ^ƒŠ?ƒXƒLƒ‹ŠŽ
5885                        pc_setoption(sd,sd->sc.option|OPTION_FALCON);
5886        } else if( pc_isfalcon(sd) ){
5887                pc_setoption(sd,sd->sc.option&~OPTION_FALCON); // remove falcon
5888        }
5889
5890        return 0;
5891}
5892
5893/*==========================================
5894 * ƒyƒRƒyƒRÝ’è
5895 *------------------------------------------*/
5896int pc_setriding(TBL_PC* sd, int flag)
5897{
5898        if( flag ){
5899                if( pc_checkskill(sd,KN_RIDING) > 0 ) // ƒ‰ƒCƒfƒBƒ“ƒOƒXƒLƒ‹ŠŽ
5900                        pc_setoption(sd, sd->sc.option|OPTION_RIDING);
5901        } else if( pc_isriding(sd) ){
5902                pc_setoption(sd, sd->sc.option&~OPTION_RIDING);
5903        }
5904
5905        return 0;
5906}
5907
5908/*==========================================
5909 * ƒAƒCƒeƒ€ƒhƒƒbƒv‰Â•s‰Â”»’è
5910 *------------------------------------------*/
5911int pc_candrop(struct map_session_data *sd,struct item *item)
5912{
5913        int level = pc_isGM(sd);
5914        if ( !pc_can_give_items(level) ) //check if this GM level can drop items
5915                return 0;
5916        return (itemdb_isdropable(item, level));
5917}
5918
5919/*==========================================
5920 * script—p??‚Ì’l‚ð?‚Þ
5921 *------------------------------------------*/
5922int pc_readreg(struct map_session_data* sd, int reg)
5923{
5924        int i;
5925
5926        nullpo_retr(0, sd);
5927
5928        ARR_FIND( 0, sd->reg_num, i,  sd->reg[i].index == reg );
5929        return ( i < sd->reg_num ) ? sd->reg[i].data : 0;
5930}
5931/*==========================================
5932 * script—p??‚Ì’l‚ðÝ’è
5933 *------------------------------------------*/
5934int pc_setreg(struct map_session_data* sd, int reg, int val)
5935{
5936        int i;
5937
5938        nullpo_retr(0, sd);
5939
5940        ARR_FIND( 0, sd->reg_num, i, sd->reg[i].index == reg );
5941        if( i < sd->reg_num )
5942        {// overwrite existing entry
5943                sd->reg[i].data = val;
5944                return 1;
5945        }
5946
5947        ARR_FIND( 0, sd->reg_num, i, sd->reg[i].data == 0 );
5948        if( i == sd->reg_num )
5949        {// nothing free, increase size
5950                sd->reg_num++;
5951                RECREATE(sd->reg, struct script_reg, sd->reg_num);
5952        }
5953        sd->reg[i].index = reg;
5954        sd->reg[i].data = val;
5955
5956        return 1;
5957}
5958
5959/*==========================================
5960 * script—p•¶Žš—ñ??‚Ì’l‚ð?‚Þ
5961 *------------------------------------------*/
5962char* pc_readregstr(struct map_session_data* sd, int reg)
5963{
5964        int i;
5965
5966        nullpo_retr(0, sd);
5967
5968        ARR_FIND( 0, sd->regstr_num, i,  sd->regstr[i].index == reg );
5969        return ( i < sd->regstr_num ) ? sd->regstr[i].data : NULL;
5970}
5971/*==========================================
5972 * script—p•¶Žš—ñ??‚Ì’l‚ðÝ’è
5973 *------------------------------------------*/
5974int pc_setregstr(struct map_session_data* sd, int reg, const char* str)
5975{
5976        int i;
5977
5978        nullpo_retr(0, sd);
5979
5980        ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].index == reg );
5981        if( i < sd->regstr_num )
5982        {// found entry, update
5983                if( str == NULL || *str == '\0' )
5984                {// empty string
5985                        if( sd->regstr[i].data != NULL )
5986                                aFree(sd->regstr[i].data);
5987                        sd->regstr[i].data = NULL;
5988                }
5989                else if( sd->regstr[i].data )
5990                {// recreate
5991                        size_t len = strlen(str)+1;
5992                        RECREATE(sd->regstr[i].data, char, len);
5993                        memcpy(sd->regstr[i].data, str, len*sizeof(char));
5994                }
5995                else
5996                {// create
5997                        sd->regstr[i].data = aStrdup(str);
5998                }
5999                return 1;
6000        }
6001
6002        if( str == NULL || *str == '\0' )
6003                return 1;// nothing to add, empty string
6004
6005        ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].data == NULL );
6006        if( i == sd->regstr_num )
6007        {// nothing free, increase size
6008                sd->regstr_num++;
6009                RECREATE(sd->regstr, struct script_regstr, sd->regstr_num);
6010        }
6011        sd->regstr[i].index = reg;
6012        sd->regstr[i].data = aStrdup(str);
6013
6014        return 1;
6015}
6016
6017int pc_readregistry(struct map_session_data *sd,const char *reg,int type)
6018{
6019        struct global_reg *sd_reg;
6020        int i,max;
6021
6022        nullpo_retr(0, sd);
6023        switch (type) {
6024        case 3: //Char reg
6025                sd_reg = sd->save_reg.global;
6026                max = sd->save_reg.global_num;
6027        break;
6028        case 2: //Account reg
6029                sd_reg = sd->save_reg.account;
6030                max = sd->save_reg.account_num;
6031        break;
6032        case 1: //Account2 reg
6033                sd_reg = sd->save_reg.account2;
6034                max = sd->save_reg.account2_num;
6035        break;
6036        default:
6037                return 0;
6038        }
6039        if (max == -1) {
6040                ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
6041                //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
6042                intif_request_registry(sd,type==3?4:type);
6043                return 0;
6044        }
6045
6046        ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 );
6047        return ( i < max ) ? atoi(sd_reg[i].value) : 0;
6048}
6049
6050char* pc_readregistry_str(struct map_session_data *sd,char *reg,int type)
6051{
6052        struct global_reg *sd_reg;
6053        int i,max;
6054
6055        nullpo_retr(0, sd);
6056        switch (type) {
6057        case 3: //Char reg
6058                sd_reg = sd->save_reg.global;
6059                max = sd->save_reg.global_num;
6060        break;
6061        case 2: //Account reg
6062                sd_reg = sd->save_reg.account;
6063                max = sd->save_reg.account_num;
6064        break;
6065        case 1: //Account2 reg
6066                sd_reg = sd->save_reg.account2;
6067                max = sd->save_reg.account2_num;
6068        break;
6069        default:
6070                return NULL;
6071        }
6072        if (max == -1) {
6073                ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type);
6074                //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again.
6075                intif_request_registry(sd,type==3?4:type);
6076                return NULL;
6077        }
6078
6079        ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 );
6080        return ( i < max ) ? sd_reg[i].value : NULL;
6081}
6082
6083int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type)
6084{
6085        struct global_reg *sd_reg;
6086        int i,*max, regmax;
6087
6088        nullpo_retr(0, sd);
6089
6090        switch( type )
6091        {
6092        case 3: //Char reg
6093                if( !strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val )
6094                {
6095                        i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE);
6096                        sd->die_counter = val;
6097                        if( i )
6098                                status_calc_pc(sd,0); // Lost the bonus.
6099                }
6100                sd_reg = sd->save_reg.global;
6101                max = &sd->save_reg.global_num;
6102                regmax = GLOBAL_REG_NUM;
6103        break;
6104        case 2: //Account reg
6105                if( !strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val )
6106                {
6107                        val = cap_value(val, 0, MAX_ZENY);
6108                        sd->cashPoints = val;
6109                }
6110                else if( !strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val )
6111                {
6112                        val = cap_value(val, 0, MAX_ZENY);
6113                        sd->kafraPoints = val;
6114                }
6115                sd_reg = sd->save_reg.account;
6116                max = &sd->save_reg.account_num;
6117                regmax = ACCOUNT_REG_NUM;
6118        break;
6119        case 1: //Account2 reg
6120                sd_reg = sd->save_reg.account2;
6121                max = &sd->save_reg.account2_num;
6122                regmax = ACCOUNT_REG2_NUM;
6123        break;
6124        default:
6125                return 0;
6126        }
6127        if (*max == -1) {
6128                ShowError("pc_setregistry : refusing to set %s (type %d) until vars are received.\n", reg, type);
6129                return 1;
6130        }
6131
6132        // delete reg
6133        if (val == 0) {
6134                ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
6135                if( i < *max )
6136                {
6137                        if (i != *max - 1)
6138                                memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
6139                        memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
6140                        (*max)--;
6141                        sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
6142                }
6143                return 1;
6144        }
6145        // change value if found
6146        ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
6147        if( i < *max )
6148        {
6149                safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
6150                sd->state.reg_dirty |= 1<<(type-1);
6151                return 1;
6152        }
6153
6154        // add value if not found
6155        if (i < regmax) {
6156                memset(&sd_reg[i], 0, sizeof(struct global_reg));
6157                safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
6158                safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val);
6159                (*max)++;
6160                sd->state.reg_dirty |= 1<<(type-1);
6161                return 1;
6162        }
6163
6164        ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
6165
6166        return 0;
6167}
6168
6169int pc_setregistry_str(struct map_session_data *sd,char *reg,const char *val,int type)
6170{
6171        struct global_reg *sd_reg;
6172        int i,*max, regmax;
6173
6174        nullpo_retr(0, sd);
6175        if (reg[strlen(reg)-1] != '$') {
6176                ShowError("pc_setregistry_str : reg %s must be string (end in '$') to use this!\n", reg);
6177                return 0;
6178        }
6179
6180        switch (type) {
6181        case 3: //Char reg
6182                sd_reg = sd->save_reg.global;
6183                max = &sd->save_reg.global_num;
6184                regmax = GLOBAL_REG_NUM;
6185        break;
6186        case 2: //Account reg
6187                sd_reg = sd->save_reg.account;
6188                max = &sd->save_reg.account_num;
6189                regmax = ACCOUNT_REG_NUM;
6190        break;
6191        case 1: //Account2 reg
6192                sd_reg = sd->save_reg.account2;
6193                max = &sd->save_reg.account2_num;
6194                regmax = ACCOUNT_REG2_NUM;
6195        break;
6196        default:
6197                return 0;
6198        }
6199        if (*max == -1) {
6200                ShowError("pc_setregistry_str : refusing to set %s (type %d) until vars are received.\n", reg, type);
6201                return 0;
6202        }
6203
6204        // delete reg
6205        if (!val || strcmp(val,"")==0)
6206        {
6207                ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
6208                if( i < *max )
6209                {
6210                        if (i != *max - 1)
6211                                memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg));
6212                        memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg));
6213                        (*max)--;
6214                        sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
6215                        if (type!=3) intif_saveregistry(sd,type);
6216                }
6217                return 1;
6218        }
6219
6220        // change value if found
6221        ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 );
6222        if( i < *max )
6223        {
6224                safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
6225                sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
6226                if (type!=3) intif_saveregistry(sd,type);
6227                return 1;
6228        }
6229
6230        // add value if not found
6231        if (i < regmax) {
6232                memset(&sd_reg[i], 0, sizeof(struct global_reg));
6233                safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str));
6234                safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value));
6235                (*max)++;
6236                sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
6237                if (type!=3) intif_saveregistry(sd,type);
6238                return 1;
6239        }
6240
6241        ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
6242
6243        return 0;
6244}
6245
6246/*==========================================
6247 * ƒCƒxƒ“ƒgƒ^ƒCƒ}??—
6248 *------------------------------------------*/
6249static int pc_eventtimer(int tid, unsigned int tick, int id, intptr data)
6250{
6251        struct map_session_data *sd=map_id2sd(id);
6252        char *p = (char *)data;
6253        int i;
6254        if(sd==NULL)
6255                return 0;
6256
6257        ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == tid );
6258        if( i < MAX_EVENTTIMER )
6259        {
6260                sd->eventtimer[i] = -1;
6261                sd->eventcount--;
6262                npc_event(sd,p,0);
6263        }
6264        else
6265                ShowError("pc_eventtimer: no such event timer\n");
6266
6267        if (p) aFree(p);
6268        return 0;
6269}
6270
6271/*==========================================
6272 * ƒCƒxƒ“ƒgƒ^ƒCƒ}?’ljÁ
6273 *------------------------------------------*/
6274int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
6275{
6276        int i;
6277        nullpo_retr(0, sd);
6278
6279        ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == -1 );
6280        if( i == MAX_EVENTTIMER )
6281                return 0;
6282
6283        sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (int)aStrdup(name));
6284        sd->eventcount++;
6285
6286        return 1;
6287}
6288
6289/*==========================================
6290 * ƒCƒxƒ“ƒgƒ^ƒCƒ}?íœ
6291 *------------------------------------------*/
6292int pc_deleventtimer(struct map_session_data *sd,const char *name)
6293{
6294        char* p = NULL;
6295        int i;
6296
6297        nullpo_retr(0, sd);
6298
6299        if (sd->eventcount <= 0)
6300                return 0;
6301
6302        // find the named event timer
6303        ARR_FIND( 0, MAX_EVENTTIMER, i,
6304                sd->eventtimer[i] != -1 &&
6305                (p = (char *)(get_timer(sd->eventtimer[i])->data)) != NULL &&
6306                strcmp(p, name) == 0
6307        );
6308        if( i == MAX_EVENTTIMER )
6309                return 0; // not found
6310
6311        delete_timer(sd->eventtimer[i],pc_eventtimer);
6312        sd->eventtimer[i]=-1;
6313        sd->eventcount--;
6314        aFree(p);
6315
6316        return 1;
6317}
6318
6319/*==========================================
6320 * ƒCƒxƒ“ƒgƒ^ƒCƒ}?ƒJƒEƒ“ƒg’l’ljÁ
6321 *------------------------------------------*/
6322int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
6323{
6324        int i;
6325
6326        nullpo_retr(0, sd);
6327
6328        for(i=0;i<MAX_EVENTTIMER;i++)
6329                if( sd->eventtimer[i]!=-1 && strcmp(
6330                        (char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){
6331                                addtick_timer(sd->eventtimer[i],tick);
6332                                break;
6333                }
6334
6335        return 0;
6336}
6337
6338/*==========================================
6339 * ƒCƒxƒ“ƒgƒ^ƒCƒ}?‘Síœ
6340 *------------------------------------------*/
6341int pc_cleareventtimer(struct map_session_data *sd)
6342{
6343        int i;
6344
6345        nullpo_retr(0, sd);
6346
6347        if (sd->eventcount <= 0)
6348                return 0;
6349
6350        for(i=0;i<MAX_EVENTTIMER;i++)
6351                if( sd->eventtimer[i]!=-1 ){
6352                        char *p = (char *)(get_timer(sd->eventtimer[i])->data);
6353                        delete_timer(sd->eventtimer[i],pc_eventtimer);
6354                        sd->eventtimer[i]=-1;
6355                        sd->eventcount--;
6356                        if (p) aFree(p);
6357                }
6358        return 0;
6359}
6360
6361//
6362// ? ”õ•š
6363//
6364/*==========================================
6365 * ƒAƒCƒeƒ€‚ð?”õ‚·‚é
6366 *------------------------------------------*/
6367int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
6368{
6369        int i,pos,flag=0;
6370        struct item_data *id;
6371
6372        nullpo_retr(0, sd);
6373
6374        if( n < 0 || n >= MAX_INVENTORY ) {
6375                clif_equipitemack(sd,0,0,0);
6376                return 0;
6377        }
6378
6379        id = sd->inventory_data[n];
6380        pos = pc_equippoint(sd,n); //With a few exceptions, item should go in all specified slots.
6381
6382        if(battle_config.battle_log)
6383                ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id->equip,req_pos);
6384        if(!pc_isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].attribute==1 ) { // [Valaris]
6385                clif_equipitemack(sd,n,0,0);    // fail
6386                return 0;
6387        }
6388
6389        if(sd->sc.data[SC_BERSERK] || sd->sc.data[SC_BLADESTOP])
6390        {
6391                clif_equipitemack(sd,n,0,0);    // fail
6392                return 0;
6393        }
6394
6395        if(pos == EQP_ACC) { //Accesories should only go in one of the two,
6396                pos = req_pos&EQP_ACC;
6397                if (pos == EQP_ACC) //User specified both slots..
6398                        pos = sd->equip_index[EQI_ACC_R] >= 0 ? EQP_ACC_L : EQP_ACC_R;
6399        }
6400
6401        if(pos == EQP_ARMS && id->equip == EQP_HAND_R)
6402        {       //Dual wield capable weapon.
6403                pos = (req_pos&EQP_ARMS);
6404                if (pos == EQP_ARMS) //User specified both slots, pick one for them.
6405                        pos = sd->equip_index[EQI_HAND_R] >= 0 ? EQP_HAND_L : EQP_HAND_R;
6406        }
6407
6408        if (pos&EQP_HAND_R && battle_config.use_weapon_skill_range&BL_PC)
6409        {       //Update skill-block range database when weapon range changes. [Skotlex]
6410                i = sd->equip_index[EQI_HAND_R];
6411                if (i < 0 || !sd->inventory_data[i]) //No data, or no weapon equipped
6412                        flag = 1;
6413                else
6414                        flag = id->range != sd->inventory_data[i]->range;
6415        }
6416
6417        for(i=0;i<EQI_MAX;i++) {
6418                if(pos & equip_pos[i]) {
6419                        if(sd->equip_index[i] >= 0) //Slot taken, remove item from there.
6420                                pc_unequipitem(sd,sd->equip_index[i],2);
6421
6422                        sd->equip_index[i] = n;
6423                }
6424        }
6425
6426        if(pos==EQP_AMMO){
6427                clif_arrowequip(sd,n);
6428                clif_arrow_fail(sd,3);
6429        }
6430        else
6431                clif_equipitemack(sd,n,pos,1);
6432
6433        sd->status.inventory[n].equip=pos;
6434
6435        if(pos & EQP_HAND_R) {
6436                if(id)
6437                        sd->weapontype1 = id->look;
6438                else
6439                        sd->weapontype1 = 0;
6440                pc_calcweapontype(sd);
6441                clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
6442        }
6443        if(pos & EQP_HAND_L) {
6444                if(id) {
6445                        if(id->type == IT_WEAPON) {
6446                                sd->status.shield = 0;
6447                                if(sd->status.inventory[n].equip == EQP_HAND_L)
6448                                        sd->weapontype2 = id->look;
6449                                else
6450                                        sd->weapontype2 = 0;
6451                        }
6452                        else
6453                        if(id->type == IT_ARMOR) {
6454                                sd->status.shield = id->look;
6455                                sd->weapontype2 = 0;
6456                        }
6457                }
6458                else
6459                        sd->status.shield = sd->weapontype2 = 0;
6460                pc_calcweapontype(sd);
6461                clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
6462        }
6463        //Added check to prevent sending the same look on multiple slots ->
6464        //causes client to redraw item on top of itself. (suggested by Lupus)
6465        if(pos & EQP_HEAD_LOW) {
6466                if(id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
6467                        sd->status.head_bottom = id->look;
6468                else
6469                        sd->status.head_bottom = 0;
6470                clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
6471        }
6472        if(pos & EQP_HEAD_TOP) {
6473                if(id)
6474                        sd->status.head_top = id->look;
6475                else
6476                        sd->status.head_top = 0;
6477                clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
6478        }
6479        if(pos & EQP_HEAD_MID) {
6480                if(id && !(pos&EQP_HEAD_TOP))
6481                        sd->status.head_mid = id->look;
6482                else
6483                        sd->status.head_mid = 0;
6484                clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
6485        }
6486        if(pos & EQP_SHOES)
6487                clif_changelook(&sd->bl,LOOK_SHOES,0);
6488
6489        pc_checkallowskill(sd); //Check if status changes should be halted.
6490
6491
6492        status_calc_pc(sd,0);
6493        if (flag) //Update skill data
6494                clif_skillinfoblock(sd);
6495
6496        //OnEquip script [Skotlex]
6497        if (id) {
6498                int i;
6499                struct item_data *data;
6500                if (id->equip_script)
6501                        run_script(id->equip_script,0,sd->bl.id,fake_nd->bl.id);
6502                if(itemdb_isspecial(sd->status.inventory[n].card[0]))
6503                        ; //No cards
6504                else
6505                for(i=0;i<id->slot; i++)
6506                {
6507                        if (!sd->status.inventory[n].card[i])
6508                                continue;
6509                        data = itemdb_exists(sd->status.inventory[n].card[i]);
6510                        if (data && data->equip_script)
6511                                run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id);
6512                }
6513        }
6514        return 0;
6515}
6516
6517/*==========================================
6518 * ? ”õ‚µ‚œ•š‚ðŠO‚·
6519 * type:
6520 * 0 - only unequip
6521 * 1 - calculate status after unequipping
6522 * 2 - force unequip
6523 *------------------------------------------*/
6524int pc_unequipitem(struct map_session_data *sd,int n,int flag)
6525{
6526        int i;
6527        nullpo_retr(0, sd);
6528
6529        if( n < 0 || n >= MAX_INVENTORY ) {
6530                clif_unequipitemack(sd,0,0,0);
6531                return 0;
6532        }
6533
6534        // if player is berserk then cannot unequip
6535        if(!(flag&2) && sd->sc.count && (sd->sc.data[SC_BLADESTOP] || sd->sc.data[SC_BERSERK])){
6536                clif_unequipitemack(sd,n,0,0);
6537                return 0;
6538        }
6539
6540        if(battle_config.battle_log)
6541                ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip);
6542
6543        if(!sd->status.inventory[n].equip){ //Nothing to unequip
6544                clif_unequipitemack(sd,n,0,0);
6545                return 0;
6546        }
6547        for(i=0;i<EQI_MAX;i++) {
6548                if(sd->status.inventory[n].equip & equip_pos[i])
6549                        sd->equip_index[i] = -1;
6550        }
6551
6552        if(sd->status.inventory[n].equip & EQP_HAND_R) {
6553                sd->weapontype1 = 0;
6554                sd->status.weapon = sd->weapontype2;
6555                pc_calcweapontype(sd);
6556                clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
6557                if(sd->sc.data[SC_DANCING]) //When unequipping, stop dancing. [Skotlex]
6558                        skill_stop_dancing(&sd->bl);
6559        }
6560        if(sd->status.inventory[n].equip & EQP_HAND_L) {
6561                sd->status.shield = sd->weapontype2 = 0;
6562                pc_calcweapontype(sd);
6563                clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
6564        }
6565        if(sd->status.inventory[n].equip & EQP_HEAD_LOW) {
6566                sd->status.head_bottom = 0;
6567                clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
6568        }
6569        if(sd->status.inventory[n].equip & EQP_HEAD_TOP) {
6570                sd->status.head_top = 0;
6571                clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
6572        }
6573        if(sd->status.inventory[n].equip & EQP_HEAD_MID) {
6574                sd->status.head_mid = 0;
6575                clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
6576        }
6577        if(sd->status.inventory[n].equip & EQP_SHOES)
6578                clif_changelook(&sd->bl,LOOK_SHOES,0);
6579
6580        clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
6581
6582        if((sd->status.inventory[n].equip & EQP_ARMS) &&
6583                sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
6584                skill_enchant_elemental_end(&sd->bl,-1);
6585
6586        if(sd->status.inventory[n].equip & EQP_ARMOR) {
6587                // On Armor Change...
6588                if( sd->sc.data[SC_BENEDICTIO] )
6589                        status_change_end(&sd->bl, SC_BENEDICTIO, -1);
6590                if( sd->sc.data[SC_ARMOR_RESIST] )
6591                        status_change_end(&sd->bl, SC_ARMOR_RESIST, -1);
6592        }
6593
6594        sd->status.inventory[n].equip=0;
6595
6596        if(flag&1) {
6597                pc_checkallowskill(sd);
6598                status_calc_pc(sd,0);
6599        }
6600
6601        if(sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
6602                status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
6603
6604        //OnUnEquip script [Skotlex]
6605        if (sd->inventory_data[n]) {
6606                struct item_data *data;
6607                if (sd->inventory_data[n]->unequip_script)
6608                        run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,fake_nd->bl.id);
6609                if(itemdb_isspecial(sd->status.inventory[n].card[0]))
6610                        ; //No cards
6611                else
6612                for(i=0;i<sd->inventory_data[n]->slot; i++)
6613                {
6614                        if (!sd->status.inventory[n].card[i])
6615                                continue;
6616                        data = itemdb_exists(sd->status.inventory[n].card[i]);
6617                        if (data && data->unequip_script)
6618                                run_script(data->unequip_script,0,sd->bl.id,fake_nd->bl.id);
6619                }
6620        }
6621
6622        return 0;
6623}
6624
6625/*==========================================
6626 * ƒAƒCƒeƒ€‚Ìindex”Ô?‚ð‹l‚ß‚œ‚è
6627 * ? ”õ•i‚Ì?”õ‰Â”\ƒ`ƒFƒbƒN‚ðs‚È‚€
6628 *------------------------------------------*/
6629int pc_checkitem(struct map_session_data *sd)
6630{
6631        int i,j,k,id,calc_flag = 0;
6632        struct item_data *it=NULL;
6633
6634        nullpo_retr(0, sd);
6635
6636        if (sd->vender_id) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
6637                return 0;
6638
6639        // ŠŽ•i‹ó‚«‹l‚ß
6640        for(i=j=0;i<MAX_INVENTORY;i++){
6641                if( (id=sd->status.inventory[i].nameid)==0)
6642                        continue;
6643                if( battle_config.item_check && !itemdb_available(id) ){
6644                        ShowWarning("illegal item id %d in %d[%s] inventory.\n",id,sd->bl.id,sd->status.name);
6645                        pc_delitem(sd,i,sd->status.inventory[i].amount,3);
6646                        continue;
6647                }
6648                if(i>j){
6649                        memcpy(&sd->status.inventory[j],&sd->status.inventory[i],sizeof(struct item));
6650                        sd->inventory_data[j] = sd->inventory_data[i];
6651                }
6652                j++;
6653        }
6654        if(j < MAX_INVENTORY)
6655                memset(&sd->status.inventory[j],0,sizeof(struct item)*(MAX_INVENTORY-j));
6656        for(k=j;k<MAX_INVENTORY;k++)
6657                sd->inventory_data[k] = NULL;
6658
6659        // ƒJ?ƒg?‹ó‚«‹l‚ß
6660        for(i=j=0;i<MAX_CART;i++){
6661                if( (id=sd->status.cart[i].nameid)==0 )
6662                        continue;
6663                if( battle_config.item_check &&  !itemdb_available(id) ){
6664                        ShowWarning("illegal item id %d in %d[%s] cart.\n",id,sd->bl.id,sd->status.name);
6665                        pc_cart_delitem(sd,i,sd->status.cart[i].amount,1);
6666                        continue;
6667                }
6668                if(i>j){
6669                        memcpy(&sd->status.cart[j],&sd->status.cart[i],sizeof(struct item));
6670                }
6671                j++;
6672        }
6673        if(j < MAX_CART)
6674                memset(&sd->status.cart[j],0,sizeof(struct item)*(MAX_CART-j));
6675
6676        // ? ”õˆÊ’uƒ`ƒFƒbƒN
6677
6678        for(i=0;i<MAX_INVENTORY;i++){
6679
6680                it=sd->inventory_data[i];
6681
6682                if(sd->status.inventory[i].nameid==0)
6683                        continue;
6684
6685                if(!sd->status.inventory[i].equip)
6686                        continue;
6687
6688                if(sd->status.inventory[i].equip&~pc_equippoint(sd,i)) {
6689                        sd->status.inventory[i].equip=0;
6690                        calc_flag = 1;
6691                        continue;
6692                }
6693                if(it) {
6694                        //check for forbiden items.
6695                        int flag =
6696                                        (map[sd->bl.m].flag.restricted?map[sd->bl.m].zone:0)
6697                                        | (map[sd->bl.m].flag.pvp?1:0)
6698                                        | (map_flag_gvg(sd->bl.m)?2:0);
6699                        if (flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag)))
6700                        {
6701                                sd->status.inventory[i].equip=0;
6702                                calc_flag = 1;
6703                        }
6704                }
6705        }
6706
6707        pc_setequipindex(sd);
6708        if(calc_flag && sd->state.active)
6709        {
6710                status_calc_pc(sd,0);
6711                pc_equiplookall(sd);
6712        }
6713        return 0;
6714}
6715
6716/*==========================================
6717 * PVP‡ˆÊŒvŽZ—p(foreachinarea)
6718 *------------------------------------------*/
6719int pc_calc_pvprank_sub(struct block_list *bl,va_list ap)
6720{
6721        struct map_session_data *sd1,*sd2=NULL;
6722
6723        sd1=(struct map_session_data *)bl;
6724        sd2=va_arg(ap,struct map_session_data *);
6725
6726        if( sd1->pvp_point > sd2->pvp_point )
6727                sd2->pvp_rank++;
6728        return 0;
6729}
6730/*==========================================
6731 * PVP‡ˆÊŒvŽZ
6732 *------------------------------------------*/
6733int pc_calc_pvprank(struct map_session_data *sd)
6734{
6735        int old;
6736        struct map_data *m;
6737        m=&map[sd->bl.m];
6738        old=sd->pvp_rank;
6739        sd->pvp_rank=1;
6740        map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd);
6741        if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users)
6742                clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users,0);
6743        return sd->pvp_rank;
6744}
6745/*==========================================
6746 * PVP‡ˆÊŒvŽZ(timer)
6747 *------------------------------------------*/
6748int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr data)
6749{
6750        struct map_session_data *sd=NULL;
6751
6752        sd=map_id2sd(id);
6753        if(sd==NULL)
6754                return 0;
6755        sd->pvp_timer = -1;
6756        if( pc_calc_pvprank(sd) > 0 )
6757                sd->pvp_timer = add_timer(gettick()+PVP_CALCRANK_INTERVAL,pc_calc_pvprank_timer,id,data);
6758        return 0;
6759}
6760
6761/*==========================================
6762 * sd‚ÍŒ‹¥‚µ‚Ä‚¢‚é‚©(?¥‚̏ꍇ‚Í‘Š•û‚Ìchar_id‚ð•Ô‚·)
6763 *------------------------------------------*/
6764int pc_ismarried(struct map_session_data *sd)
6765{
6766        if(sd == NULL)
6767                return -1;
6768        if(sd->status.partner_id > 0)
6769                return sd->status.partner_id;
6770        else
6771                return 0;
6772}
6773/*==========================================
6774 * sd‚ªdstsd‚ÆŒ‹¥(dstsdšsd‚ÌŒ‹¥?—‚à“¯Žbɍs‚€)
6775 *------------------------------------------*/
6776int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
6777{
6778        if(sd == NULL || dstsd == NULL ||
6779                sd->status.partner_id > 0 || dstsd->status.partner_id > 0 ||
6780                sd->class_&JOBL_BABY)
6781                return -1;
6782        sd->status.partner_id = dstsd->status.char_id;
6783        dstsd->status.partner_id = sd->status.char_id;
6784        return 0;
6785}
6786
6787/*==========================================
6788 * Divorce sd from its partner
6789 *------------------------------------------*/
6790int pc_divorce(struct map_session_data *sd)
6791{
6792        struct map_session_data *p_sd;
6793        int i;
6794
6795        if( sd == NULL || !pc_ismarried(sd) )
6796                return -1;
6797
6798        if( !sd->status.partner_id )
6799                return -1; // Char is not married
6800
6801        if( (p_sd = map_charid2sd(sd->status.partner_id)) == NULL )
6802        { // Lets char server do the divorce
6803#ifndef TXT_ONLY
6804                if( chrif_divorce(sd->status.char_id, sd->status.partner_id) )
6805                        return -1; // No char server connected
6806
6807                return 0;
6808#else
6809                ShowError("pc_divorce: p_sd nullpo\n");
6810                return -1;
6811#endif
6812        }
6813
6814        // Both players online, lets do the divorce manually
6815        sd->status.partner_id = 0;
6816        p_sd->status.partner_id = 0;
6817        for( i = 0; i < MAX_INVENTORY; i++ )
6818        {
6819                if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F )
6820                        pc_delitem(sd, i, 1, 0);
6821                if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F )
6822                        pc_delitem(p_sd, i, 1, 0);
6823        }
6824
6825        clif_divorced(sd, p_sd->status.name);
6826        clif_divorced(p_sd, sd->status.name);
6827
6828        return 0;
6829}
6830
6831/*==========================================
6832 * sd‚Ì‘Š•û‚Ìmap_session_data‚ð•Ô‚·
6833 *------------------------------------------*/
6834struct map_session_data *pc_get_partner(struct map_session_data *sd)
6835{
6836        if (sd && pc_ismarried(sd))
6837                // charid2sd returns NULL if not found
6838                return map_charid2sd(sd->status.partner_id);
6839
6840        return NULL;
6841}
6842
6843struct map_session_data *pc_get_father (struct map_session_data *sd)
6844{
6845        if (sd && sd->class_&JOBL_BABY && sd->status.father > 0)
6846                // charid2sd returns NULL if not found
6847                return map_charid2sd(sd->status.father);
6848
6849        return NULL;
6850}
6851
6852struct map_session_data *pc_get_mother (struct map_session_data *sd)
6853{
6854        if (sd && sd->class_&JOBL_BABY && sd->status.mother > 0)
6855                // charid2sd returns NULL if not found
6856                return map_charid2sd(sd->status.mother);
6857
6858        return NULL;
6859}
6860
6861struct map_session_data *pc_get_child (struct map_session_data *sd)
6862{
6863        if (sd && pc_ismarried(sd) && sd->status.child > 0)
6864                // charid2sd returns NULL if not found
6865                return map_charid2sd(sd->status.child);
6866
6867        return NULL;
6868}
6869
6870void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick)
6871{
6872        int hp = 0, sp = 0;
6873
6874        if (sd->hp_loss.value) {
6875                sd->hp_loss.tick += diff_tick;
6876                while (sd->hp_loss.tick >= sd->hp_loss.rate) {
6877                        hp += sd->hp_loss.value;
6878                        sd->hp_loss.tick -= sd->hp_loss.rate;
6879                }
6880                if(hp >= sd->battle_status.hp)
6881                        hp = sd->battle_status.hp-1; //Script drains cannot kill you.
6882        }
6883
6884        if (sd->sp_loss.value) {
6885                sd->sp_loss.tick += diff_tick;
6886                while (sd->sp_loss.tick >= sd->sp_loss.rate) {
6887                        sp += sd->sp_loss.value;
6888                        sd->sp_loss.tick -= sd->sp_loss.rate;
6889                }
6890        }
6891
6892        if (hp > 0 || sp > 0)
6893                status_zap(&sd->bl, hp, sp);
6894
6895        return;
6896}
6897
6898//Character regen. Flag is used to know which types of regen can take place.
6899//&1: HP regen
6900//&2: SP regen
6901void pc_regen (struct map_session_data *sd, unsigned int diff_tick)
6902{
6903        int hp = 0, sp = 0;
6904
6905        if (sd->hp_regen.value) {
6906                sd->hp_regen.tick += diff_tick;
6907                while (sd->hp_regen.tick >= sd->hp_regen.rate) {
6908                        hp += sd->hp_regen.value;
6909                        sd->hp_regen.tick -= sd->hp_regen.rate;
6910                }
6911        }
6912
6913        if (sd->sp_regen.value) {
6914                sd->sp_regen.tick += diff_tick;
6915                while (sd->sp_regen.tick >= sd->sp_regen.rate) {
6916                        sp += sd->sp_regen.value;
6917                        sd->sp_regen.tick -= sd->sp_regen.rate;
6918                }
6919        }
6920
6921        if (hp > 0 || sp > 0)
6922                status_heal(&sd->bl, hp, sp, 0);
6923
6924        return;
6925}
6926
6927/*==========================================
6928 * ƒZ?ƒuƒ|ƒCƒ“ƒg‚̕ۑ¶
6929 *------------------------------------------*/
6930int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
6931{
6932        nullpo_retr(0, sd);
6933
6934        sd->status.save_point.map = mapindex;
6935        sd->status.save_point.x = x;
6936        sd->status.save_point.y = y;
6937
6938        return 0;
6939}
6940
6941/*==========================================
6942 * Ž©“®ƒZ?ƒu (timer??)
6943 *------------------------------------------*/
6944int pc_autosave(int tid, unsigned int tick, int id, intptr data)
6945{
6946        int interval;
6947        struct s_mapiterator* iter;
6948        struct map_session_data* sd;
6949        static int last_save_id = 0, save_flag = 0;
6950
6951        if(save_flag == 2) //Someone was saved on last call, normal cycle
6952                save_flag = 0;
6953        else
6954                save_flag = 1; //Noone was saved, so save first found char.
6955
6956        iter = mapit_getallusers();
6957        for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
6958        {
6959                if(sd->bl.id == last_save_id && save_flag != 1) {
6960                        save_flag = 1;
6961                        continue;
6962                }
6963
6964                if(save_flag != 1) //Not our turn to save yet.
6965                        continue;
6966
6967                //Save char.
6968                last_save_id = sd->bl.id;
6969                save_flag = 2;
6970
6971                chrif_save(sd,0);
6972        }
6973        mapit_free(iter);
6974
6975        interval = autosave_interval/(map_usercount()+1);
6976        if(interval < minsave_interval)
6977                interval = minsave_interval;
6978        add_timer(gettick()+interval,pc_autosave,0,0);
6979
6980        return 0;
6981}
6982
6983int pc_read_gm_account(int fd)
6984{
6985        //FIXME: this implementation is a total failure (direct reading from RFIFO) [ultramage]
6986        int i = 0;
6987        if (gm_account != NULL)
6988                aFree(gm_account);
6989        GM_num = 0;
6990        gm_account = (struct gm_account *) aMallocA(((RFIFOW(fd,2) - 4) / 5)*sizeof(struct gm_account));
6991        for (i = 4; i < RFIFOW(fd,2); i += 5) {
6992                gm_account[GM_num].account_id = RFIFOL(fd,i);
6993                gm_account[GM_num].level = (int)RFIFOB(fd,i+4);
6994                GM_num++;
6995        }
6996        return GM_num;
6997}
6998static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
6999{
7000        if (sd->state.night != night_flag && map[sd->bl.m].flag.nightenabled)
7001        {       //Night/day state does not match.
7002                clif_status_load(&sd->bl, SI_NIGHT, night_flag); //New night effect by dynamix [Skotlex]
7003                sd->state.night = night_flag;
7004                return 1;
7005        }
7006        return 0;
7007}
7008/*================================================
7009 * timer to do the day [Yor]
7010 * data: 0 = called by timer, 1 = gmcommand/script
7011 *------------------------------------------------*/
7012int map_day_timer(int tid, unsigned int tick, int id, intptr data)
7013{
7014        char tmp_soutput[1024];
7015
7016        if (data == 0 && battle_config.day_duration <= 0)       // if we want a day
7017                return 0;
7018
7019        if (!night_flag)
7020                return 0; //Already day.
7021
7022        night_flag = 0; // 0=day, 1=night [Yor]
7023        map_foreachpc(pc_daynight_timer_sub);
7024        strcpy(tmp_soutput, (data == 0) ? msg_txt(502) : msg_txt(60)); // The day has arrived!
7025        intif_GMmessage(tmp_soutput, strlen(tmp_soutput) + 1, 0);
7026        return 0;
7027}
7028
7029/*================================================
7030 * timer to do the night [Yor]
7031 * data: 0 = called by timer, 1 = gmcommand/script
7032 *------------------------------------------------*/
7033int map_night_timer(int tid, unsigned int tick, int id, intptr data)
7034{
7035        char tmp_soutput[1024];
7036
7037        if (data == 0 && battle_config.night_duration <= 0)     // if we want a night
7038                return 0;
7039
7040        if (night_flag)
7041                return 0; //Already nigth.
7042
7043        night_flag = 1; // 0=day, 1=night [Yor]
7044        map_foreachpc(pc_daynight_timer_sub);
7045        strcpy(tmp_soutput, (data == 0) ? msg_txt(503) : msg_txt(59)); // The night has fallen...
7046        intif_GMmessage(tmp_soutput, strlen(tmp_soutput) + 1, 0);
7047        return 0;
7048}
7049
7050void pc_setstand(struct map_session_data *sd){
7051        nullpo_retv(sd);
7052
7053        if(sd->sc.data[SC_TENSIONRELAX])
7054                status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
7055
7056        //Reset sitting tick.
7057        sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
7058        sd->state.dead_sit = sd->vd.dead_sit = 0;
7059}
7060
7061/*==========================================
7062 * Duel organizing functions [LuzZza]
7063 *------------------------------------------*/
7064void duel_savetime(struct map_session_data* sd)
7065{
7066        time_t timer;
7067        struct tm *t;
7068
7069        time(&timer);
7070        t = localtime(&timer);
7071
7072        pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
7073        return;
7074}
7075
7076int duel_checktime(struct map_session_data* sd)
7077{
7078        int diff;
7079        time_t timer;
7080        struct tm *t;
7081
7082        time(&timer);
7083    t = localtime(&timer);
7084
7085        diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
7086
7087        return !(diff >= 0 && diff < battle_config.duel_time_interval);
7088}
7089static int duel_showinfo_sub(struct map_session_data* sd, va_list va)
7090{
7091        struct map_session_data *ssd = va_arg(va, struct map_session_data*);
7092        int *p = va_arg(va, int*);
7093        char output[256];
7094
7095        if (sd->duel_group != ssd->duel_group) return 0;
7096
7097        sprintf(output, "      %d. %s", ++(*p), sd->status.name);
7098        clif_disp_onlyself(ssd, output, strlen(output));
7099        return 1;
7100}
7101
7102int duel_showinfo(const unsigned int did, struct map_session_data* sd)
7103{
7104        int p=0;
7105        char output[256];
7106
7107        if(duel_list[did].max_players_limit > 0)
7108                sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
7109                        did, duel_count,
7110                        duel_list[did].members_count,
7111                        duel_list[did].members_count + duel_list[did].invites_count,
7112                        duel_list[did].max_players_limit);
7113        else
7114                sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
7115                        did, duel_count,
7116                        duel_list[did].members_count,
7117                        duel_list[did].members_count + duel_list[did].invites_count);
7118
7119        clif_disp_onlyself(sd, output, strlen(output));
7120        map_foreachpc(duel_showinfo_sub, sd, &p);
7121        return 0;
7122}
7123
7124int duel_create(struct map_session_data* sd, const unsigned int maxpl)
7125{
7126        int i=1;
7127        char output[256];
7128
7129        while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
7130        if(i == MAX_DUEL) return 0;
7131
7132        duel_count++;
7133        sd->duel_group = i;
7134        duel_list[i].members_count++;
7135        duel_list[i].invites_count = 0;
7136        duel_list[i].max_players_limit = maxpl;
7137
7138        strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
7139        clif_disp_onlyself(sd, output, strlen(output));
7140
7141        clif_set0199(sd, 1);
7142        //clif_misceffect2(&sd->bl, 159);
7143        return i;
7144}
7145
7146int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd)
7147{
7148        char output[256];
7149
7150        // " -- Player %s invites %s to duel --"
7151        sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name);
7152        clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
7153
7154        target_sd->duel_invite = did;
7155        duel_list[did].invites_count++;
7156
7157        // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
7158        sprintf(output, msg_txt(374), sd->status.name);
7159        clif_GMmessage((struct block_list *)target_sd, output, strlen(output)+1, 3);
7160        return 0;
7161}
7162
7163static int duel_leave_sub(struct map_session_data* sd, va_list va)
7164{
7165        int did = va_arg(va, int);
7166        if (sd->duel_invite == did)
7167                sd->duel_invite = 0;
7168        return 0;
7169}
7170
7171int duel_leave(const unsigned int did, struct map_session_data* sd)
7172{
7173        char output[256];
7174
7175        // " <- Player %s has left duel --"
7176        sprintf(output, msg_txt(375), sd->status.name);
7177        clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
7178
7179        duel_list[did].members_count--;
7180
7181        if(duel_list[did].members_count == 0) {
7182                map_foreachpc(duel_leave_sub, did);
7183                duel_count--;
7184        }
7185
7186        sd->duel_group = 0;
7187        duel_savetime(sd);
7188        clif_set0199(sd, 0);
7189        return 0;
7190}
7191
7192int duel_accept(const unsigned int did, struct map_session_data* sd)
7193{
7194        char output[256];
7195
7196        duel_list[did].members_count++;
7197        sd->duel_group = sd->duel_invite;
7198        duel_list[did].invites_count--;
7199        sd->duel_invite = 0;
7200
7201        // " -> Player %s has accepted duel --"
7202        sprintf(output, msg_txt(376), sd->status.name);
7203        clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
7204
7205        clif_set0199(sd, 1);
7206        //clif_misceffect2(&sd->bl, 159);
7207        return 0;
7208}
7209
7210int duel_reject(const unsigned int did, struct map_session_data* sd)
7211{
7212        char output[256];
7213
7214        // " -- Player %s has rejected duel --"
7215        sprintf(output, msg_txt(377), sd->status.name);
7216        clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
7217
7218        duel_list[did].invites_count--;
7219        sd->duel_invite = 0;
7220        return 0;
7221}
7222
7223int pc_split_str(char *str,char **val,int num)
7224{
7225        int i;
7226
7227        for (i=0; i<num && str; i++){
7228                val[i] = str;
7229                str = strchr(str,',');
7230                if (str && i<num-1) //Do not remove a trailing comma.
7231                        *str++=0;
7232        }
7233        return i;
7234}
7235
7236int pc_split_atoi(char* str, int* val, char sep, int max)
7237{
7238        int i,j;
7239        for (i=0; i<max; i++) {
7240                if (!str) break;
7241                val[i] = atoi(str);
7242                str = strchr(str,sep);
7243                if (str)
7244                        *str++=0;
7245        }
7246        //Zero up the remaining.
7247        for(j=i; j < max; j++)
7248                val[j] = 0;
7249        return i;
7250}
7251
7252int pc_split_atoui(char* str, unsigned int* val, char sep, int max)
7253{
7254        static int warning=0;
7255        int i,j;
7256        double f;
7257        for (i=0; i<max; i++) {
7258                if (!str) break;
7259                f = atof(str);
7260                if (f < 0)
7261                        val[i] = 0;
7262                else if (f > UINT_MAX) {
7263                        val[i] = UINT_MAX;
7264                        if (!warning) {
7265                                warning = 1;
7266                                ShowWarning("pc_readdb (exp.txt): Required exp per level is capped to %u\n", UINT_MAX);
7267                        }
7268                } else
7269                        val[i] = (unsigned int)f;
7270                str = strchr(str,sep);
7271                if (str)
7272                        *str++=0;
7273        }
7274        //Zero up the remaining.
7275        for(j=i; j < max; j++)
7276                val[j] = 0;
7277        return i;
7278}
7279
7280/*==========================================
7281 * DB reading.
7282 * exp.txt        - required experience values
7283 * job_db1.txt    - weight, hp, sp, aspd
7284 * job_db2.txt    - job level stat bonuses
7285 * skill_tree.txt - skill tree for every class
7286 * attr_fix.txt   - elemental adjustment table
7287 * size_fix.txt   - size adjustment table for weapons
7288 * refine_db.txt  - refining data table
7289 *------------------------------------------*/
7290int pc_readdb(void)
7291{
7292        int i,j,k;
7293        FILE *fp;
7294        char line[24000],*p;
7295
7296        // •K—v??’l?‚Ý?‚Ý
7297        memset(exp_table,0,sizeof(exp_table));
7298        memset(max_level,0,sizeof(max_level));
7299        sprintf(line, "%s/exp.txt", db_path);
7300        fp=fopen(line, "r");
7301        if(fp==NULL){
7302                ShowError("can't read %s\n", line);
7303                return 1;
7304        }
7305        while(fgets(line, sizeof(line), fp))
7306        {
7307                int jobs[CLASS_COUNT], job_count, job, job_id;
7308                int type;
7309                unsigned int ui,maxlv;
7310                char *split[4];
7311                if(line[0]=='/' && line[1]=='/')
7312                        continue;
7313                if (pc_split_str(line,split,4) < 4)
7314                        continue;
7315
7316                job_count = pc_split_atoi(split[1],jobs,':',CLASS_COUNT);
7317                if (job_count < 1)
7318                        continue;
7319                job_id = jobs[0];
7320                if (!pcdb_checkid(job_id)) {
7321                        ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
7322                        continue;
7323                }
7324                type = atoi(split[2]);
7325                if (type < 0 || type > 1) {
7326                        ShowError("pc_readdb: Invalid type %d (must be 0 for base levels, 1 for job levels).\n", type);
7327                        continue;
7328                }
7329                maxlv = atoi(split[0]);
7330                if (maxlv > MAX_LEVEL) {
7331                        ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%u).\n ", maxlv, job_id, MAX_LEVEL);
7332                        maxlv = MAX_LEVEL;
7333                }
7334
7335                job = jobs[0] = pc_class2idx(job_id);
7336                //We send one less and then one more because the last entry in the exp array should hold 0.
7337                max_level[job][type] = pc_split_atoui(split[3], exp_table[job][type],',',maxlv-1)+1;
7338                //Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
7339                //The reasoning behind the -2 is this... if the max level is 5, then the array
7340                //should look like this:
7341           //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
7342                while ((ui = max_level[job][type]) >= 2 && exp_table[job][type][ui-2] <= 0)
7343                        max_level[job][type]--;
7344                if (max_level[job][type] < maxlv) {
7345                        ShowWarning("pc_readdb: Specified max %u for job %d, but that job's exp table only goes up to level %u.\n", maxlv, job_id, max_level[job][type]);
7346                        ShowInfo("Filling the missing values with the last exp entry.\n");
7347                        //Fill the requested values with the last entry.
7348                        ui = (max_level[job][type] <= 2? 0: max_level[job][type]-2);
7349                        for (; ui+2 < maxlv; ui++)
7350                                exp_table[job][type][ui] = exp_table[job][type][ui-1];
7351                        max_level[job][type] = maxlv;
7352                }
7353//              ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job_id, max_level[job][type]);
7354                for (i = 1; i < job_count; i++) {
7355                        job_id = jobs[i];
7356                        if (!pcdb_checkid(job_id)) {
7357                                ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
7358                                continue;
7359                        }
7360                        job = pc_class2idx(job_id);
7361                        memcpy(exp_table[job][type], exp_table[jobs[0]][type], sizeof(exp_table[0][0]));
7362                        max_level[job][type] = maxlv;
7363//                      ShowDebug("%s - Class %d: %u\n", type?"Job":"Base", job_id, max_level[job][type]);
7364                }
7365        }
7366        fclose(fp);
7367        for (i = 0; i < JOB_MAX; i++) {
7368                if (!pcdb_checkid(i)) continue;
7369                if (i == JOB_WEDDING || i == JOB_XMAS || i == JOB_SUMMER)
7370                        continue; //Classes that do not need exp tables.
7371                j = pc_class2idx(i);
7372                if (!max_level[j][0])
7373                        ShowWarning("Class %s (%d) does not has a base exp table.\n", job_name(i), i);
7374                if (!max_level[j][1])
7375                        ShowWarning("Class %s (%d) does not has a job exp table.\n", job_name(i), i);
7376        }
7377        ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","exp.txt");
7378
7379        // ƒXƒLƒ‹ƒcƒŠ?
7380        memset(skill_tree,0,sizeof(skill_tree));
7381        sprintf(line, "%s/skill_tree.txt", db_path);
7382        fp=fopen(line,"r");
7383        if(fp==NULL){
7384                ShowError("can't read %s\n", line);
7385                return 1;
7386        }
7387
7388        while(fgets(line, sizeof(line), fp))
7389        {
7390                char *split[50];
7391                int f=0, m=3, idx;
7392                if(line[0]=='/' && line[1]=='/')
7393                        continue;
7394                for(j=0,p=line;j<14 && p;j++){
7395                        split[j]=p;
7396                        p=strchr(p,',');
7397                        if(p) *p++=0;
7398                }
7399                if(j<13)
7400                        continue;
7401                if (j == 14) {
7402                        f=1;    // MinJobLvl has been added
7403                        m++;
7404                }
7405                // check for bounds [celest]
7406                idx = atoi(split[0]);
7407                if(!pcdb_checkid(idx))
7408                        continue;
7409                idx = pc_class2idx(idx);
7410                k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
7411                ARR_FIND( 0, MAX_SKILL_TREE, j, skill_tree[idx][j].id == 0 || skill_tree[idx][j].id == k );
7412                if( j == MAX_SKILL_TREE )
7413                {
7414                        ShowWarning("Unable to load skill %d into job %d's tree. Maximum number of skills per class has been reached.\n", k, atoi(split[0]));
7415                        continue;
7416                }
7417                skill_tree[idx][j].id=k;
7418                skill_tree[idx][j].max=atoi(split[2]);
7419                if (f) skill_tree[idx][j].joblv=atoi(split[3]);
7420
7421                for(k=0;k<5;k++){
7422                        skill_tree[idx][j].need[k].id=atoi(split[k*2+m]);
7423                        skill_tree[idx][j].need[k].lv=atoi(split[k*2+m+1]);
7424                }
7425        }
7426        fclose(fp);
7427        ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","skill_tree.txt");
7428
7429        // ?«C³ƒe?ƒuƒ‹
7430        for(i=0;i<4;i++)
7431                for(j=0;j<ELE_MAX;j++)
7432                        for(k=0;k<ELE_MAX;k++)
7433                                attr_fix_table[i][j][k]=100;
7434
7435        sprintf(line, "%s/attr_fix.txt", db_path);
7436        fp=fopen(line,"r");
7437        if(fp==NULL){
7438                ShowError("can't read %s\n", line);
7439                return 1;
7440        }
7441        while(fgets(line, sizeof(line), fp))
7442        {
7443                char *split[10];
7444                int lv,n;
7445                if(line[0]=='/' && line[1]=='/')
7446                        continue;
7447                for(j=0,p=line;j<3 && p;j++){
7448                        split[j]=p;
7449                        p=strchr(p,',');
7450                        if(p) *p++=0;
7451                }
7452                lv=atoi(split[0]);
7453                n=atoi(split[1]);
7454
7455                for(i=0;i<n && i<ELE_MAX;){
7456                        if( !fgets(line, sizeof(line), fp) )
7457                                break;
7458                        if(line[0]=='/' && line[1]=='/')
7459                                continue;
7460
7461                        for(j=0,p=line;j<n && j<ELE_MAX && p;j++){
7462                                while(*p==32 && *p>0)
7463                                        p++;
7464                                attr_fix_table[lv-1][i][j]=atoi(p);
7465                                if(battle_config.attr_recover == 0 && attr_fix_table[lv-1][i][j] < 0)
7466                                        attr_fix_table[lv-1][i][j] = 0;
7467                                p=strchr(p,',');
7468                                if(p) *p++=0;
7469                        }
7470
7471                        i++;
7472                }
7473        }
7474        fclose(fp);
7475        ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","attr_fix.txt");
7476
7477        // ƒXƒLƒ‹ƒcƒŠ?
7478        memset(statp,0,sizeof(statp));
7479        i=1;
7480        j=45;   // base points
7481        sprintf(line, "%s/statpoint.txt", db_path);
7482        fp=fopen(line,"r");
7483        if(fp == NULL){
7484                ShowStatus("Can't read '"CL_WHITE"%s"CL_RESET"'... Generating DB.\n",line);
7485                //return 1;
7486        } else {
7487                while(fgets(line, sizeof(line), fp))
7488                {
7489                        if(line[0]=='/' && line[1]=='/')
7490                                continue;
7491                        if ((j=atoi(line))<0)
7492                                j=0;
7493                        if (i > MAX_LEVEL)
7494                                break;
7495                        statp[i]=j;
7496                        i++;
7497                }
7498                fclose(fp);
7499                ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","statpoint.txt");
7500        }
7501        // generate the remaining parts of the db if necessary
7502        for (; i <= MAX_LEVEL; i++) {
7503                j += (i+15)/5;
7504                statp[i] = j;
7505        }
7506
7507        return 0;
7508}
7509
7510// Read MOTD on startup. [Valaris]
7511int pc_read_motd(void)
7512{
7513        FILE *fp;
7514        int ln=0,i=0;
7515
7516        memset(motd_text,0,sizeof(motd_text));
7517        if ((fp = fopen(motd_txt, "r")) != NULL) {
7518                while ((ln < MOTD_LINE_SIZE) && fgets(motd_text[ln], sizeof(motd_text[ln])-1, fp) != NULL) {
7519                        if(motd_text[ln][0] == '/' && motd_text[ln][1] == '/')
7520                                continue;
7521                        for(i=0; motd_text[ln][i]; i++) {
7522                                if (motd_text[ln][i] == '\r' || motd_text[ln][i]== '\n') {
7523                                        if(i)
7524                                                motd_text[ln][i]=0;
7525                                        else
7526                                                motd_text[ln][0]=' ';
7527                                        ln++;
7528                                        break;
7529                                }
7530                        }
7531                }
7532                fclose(fp);
7533        }
7534        else
7535                ShowWarning("In function pc_read_motd() -> File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
7536
7537        return 0;
7538}
7539
7540/*==========================================
7541 * pc? ŒW‰Šú‰»
7542 *------------------------------------------*/
7543void do_final_pc(void)
7544{
7545        if (gm_account)
7546                aFree(gm_account);
7547        return;
7548}
7549
7550int do_init_pc(void)
7551{
7552        pc_readdb();
7553        pc_read_motd(); // Read MOTD [Valaris]
7554
7555        memset(&duel_list[0], 0, sizeof(duel_list));
7556
7557        add_timer_func_list(pc_invincible_timer, "pc_invincible_timer");
7558        add_timer_func_list(pc_eventtimer, "pc_eventtimer");
7559        add_timer_func_list(pc_calc_pvprank_timer, "pc_calc_pvprank_timer");
7560        add_timer_func_list(pc_autosave, "pc_autosave");
7561        add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
7562        add_timer_func_list(pc_follow_timer, "pc_follow_timer");
7563
7564        add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
7565
7566        if (battle_config.day_duration > 0 && battle_config.night_duration > 0) {
7567                int day_duration = battle_config.day_duration;
7568                int night_duration = battle_config.night_duration;
7569                // add night/day timer (by [yor])
7570                add_timer_func_list(map_day_timer, "map_day_timer"); // by [yor]
7571                add_timer_func_list(map_night_timer, "map_night_timer"); // by [yor]
7572
7573                if (!battle_config.night_at_start) {
7574                        night_flag = 0; // 0=day, 1=night [Yor]
7575                        day_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
7576                        night_timer_tid = add_timer_interval(gettick() + day_duration, map_night_timer, 0, 0, day_duration + night_duration);
7577                } else {
7578                        night_flag = 1; // 0=day, 1=night [Yor]
7579                        day_timer_tid = add_timer_interval(gettick() + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
7580                        night_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_night_timer, 0, 0, day_duration + night_duration);
7581                }
7582        }
7583
7584        return 0;
7585}
Note: See TracBrowser for help on using the browser.