root/src/map/pc.c @ 5

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