root/src/map/pc.c @ 22

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