diff options
Diffstat (limited to 'src/map/pc.c')
-rw-r--r-- | src/map/pc.c | 149 |
1 files changed, 92 insertions, 57 deletions
diff --git a/src/map/pc.c b/src/map/pc.c index 6c4ebe149..31a38372a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -72,7 +72,7 @@ struct map_session_data* pc_get_dummy_sd(void) { struct map_session_data *dummy_sd; CREATE(dummy_sd, struct map_session_data, 1); - dummy_sd->group = pc_group_get_dummy_group(); // map_session_data.group is expected to be non-NULL at all times + dummy_sd->group = pcg->get_dummy_group(); // map_session_data.group is expected to be non-NULL at all times return dummy_sd; } @@ -82,7 +82,7 @@ struct map_session_data* pc_get_dummy_sd(void) */ int pc_get_group_level(struct map_session_data *sd) { - return pc_group_get_level(sd->group); + return pcg->get_level(sd->group); } /** @@ -93,7 +93,7 @@ int pc_get_group_level(struct map_session_data *sd) */ int pc_set_group(struct map_session_data *sd, int group_id) { - GroupSettings *group = pc_group_id2group(group_id); + GroupSettings *group = pcg->id2group(group_id); if (group == NULL) return 1; sd->group_id = group_id; @@ -104,9 +104,9 @@ int pc_set_group(struct map_session_data *sd, int group_id) /** * Checks if player has permission to perform action. */ -bool pc_has_permission(struct map_session_data *sd, enum e_pc_permission permission) +bool pc_has_permission(struct map_session_data *sd, unsigned int permission) { - return ((sd->extra_temp_permissions&permission) != 0 || pc_group_has_permission(sd->group, permission)); + return ((sd->extra_temp_permissions&permission) != 0 || pcg->has_permission(sd->group, permission)); } /** @@ -114,7 +114,7 @@ bool pc_has_permission(struct map_session_data *sd, enum e_pc_permission permiss */ bool pc_should_log_commands(struct map_session_data *sd) { - return pc_group_should_log_commands(sd->group); + return pcg->should_log_commands(sd->group); } int pc_invincible_timer(int tid, int64 tick, int id, intptr_t data) { @@ -1340,7 +1340,7 @@ int pc_reg_received(struct map_session_data *sd) pc->load_combo(sd); - status_calc_pc(sd,1); + status_calc_pc(sd,SCO_FIRST|SCO_FORCE); chrif->scdata_request(sd->status.account_id, sd->status.char_id); intif->Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox @@ -2048,7 +2048,7 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus) autobonus->active = timer->add(timer->gettick()+autobonus->duration, pc->endautobonus, sd->bl.id, (intptr_t)autobonus); sd->state.autobonus |= autobonus->pos; - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); return 0; } @@ -2062,7 +2062,7 @@ int pc_endautobonus(int tid, int64 tick, int id, intptr_t data) { autobonus->active = INVALID_TIMER; sd->state.autobonus &= ~autobonus->pos; - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); return 0; } @@ -3569,7 +3569,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { } else clif->addskill(sd,id); if( !skill->db[index].inf ) //Only recalculate for passive skills. - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); break; case 1: //Item bonus skill. if( sd->status.skill[index].id == id ) { @@ -3603,7 +3603,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { } else clif->addskill(sd,id); if( !skill->db[index].inf ) //Only recalculate for passive skills. - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); break; default: //Unknown flag? return 0; @@ -5827,13 +5827,13 @@ int pc_checkbaselevelup(struct map_session_data *sd) { } while ((next=pc->nextbaseexp(sd)) > 0 && sd->status.base_exp >= next); if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level - status_calc_pet(sd->pd,0); + status_calc_pet(sd->pd,SCO_NONE); clif->updatestatus(sd,SP_STATUSPOINT); clif->updatestatus(sd,SP_BASELEVEL); clif->updatestatus(sd,SP_BASEEXP); clif->updatestatus(sd,SP_NEXTBASEEXP); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); status_percent_heal(&sd->bl,100,100); if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) { @@ -5893,7 +5893,7 @@ int pc_checkjoblevelup(struct map_session_data *sd) clif->updatestatus(sd,SP_JOBEXP); clif->updatestatus(sd,SP_NEXTJOBEXP); clif->updatestatus(sd,SP_SKILLPOINT); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); clif->misceffect(&sd->bl,1); if (pc->checkskill(sd, SG_DEVIL) && !pc->nextjobexp(sd)) clif->status_change(&sd->bl,SI_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL. @@ -5927,6 +5927,12 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX); + if( sd->status.mod_exp != 100 ) { + *base_exp = (unsigned int) cap_value((double)*base_exp * sd->status.mod_exp/100., 1, UINT_MAX); + *job_exp = (unsigned int) cap_value((double)*job_exp * sd->status.mod_exp/100., 1, UINT_MAX); + + } + return; } /*========================================== @@ -6181,7 +6187,7 @@ int pc_statusup(struct map_session_data* sd, int type) val = pc->setstat(sd, type, pc->getstat(sd,type) + 1); sd->status.status_point -= need; - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); // update increase cost indicator if( need != pc->need_status_point(sd,type,1) ) @@ -6221,7 +6227,7 @@ int pc_statusup2(struct map_session_data* sd, int type, int val) max = pc_maxparameter(sd); val = pc->setstat(sd, type, cap_value(pc->getstat(sd,type) + val, 1, max)); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); // update increase cost indicator if( need != pc->need_status_point(sd,type,1) ) @@ -6264,7 +6270,7 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) { sd->status.skill[index].lv++; sd->status.skill_point--; if( !skill->db[index].inf ) - status_calc_pc(sd,0); // Only recalculate for passive skills. + status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills. else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) ) pc->calc_skilltree(sd); // Required to grant all TK Ranger skills. else @@ -6337,7 +6343,7 @@ int pc_allskillup(struct map_session_data *sd) sd->status.skill[idx].lv = skill->tree_get_max(id, sd->status.class_); // celest } } - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); //Required because if you could level up all skills previously, //the update will not be sent as only the lv variable changes. clif->skillinfoblock(sd); @@ -6427,7 +6433,7 @@ int pc_resetlvl(struct map_session_data* sd,int type) if ((type == 1 || type == 2 || type == 3) && sd->status.party_id) party->send_levelup(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); clif->skillinfoblock(sd); return 0; @@ -6492,7 +6498,7 @@ int pc_resetstate(struct map_session_data* sd) pc_setglobalreg(sd,"TK_MISSION_ID", 0); } - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); return 1; } @@ -6603,7 +6609,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) if( flag&1 ) { clif->updatestatus(sd,SP_SKILLPOINT); clif->skillinfoblock(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); } return skill_point; @@ -6857,7 +6863,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { ) { // monster level up [Valaris] clif->misceffect(&md->bl,0); md->level++; - status_calc_mob(md, 0); + status_calc_mob(md, SCO_NONE); status_percent_heal(src,10,0); if( battle_config.show_mob_info&4 ) @@ -6949,47 +6955,55 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { // changed penalty options, added death by player if pk_mode [Valaris] if( battle_config.death_penalty_type - && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty - && !map->list[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m) - && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY] - ) { - unsigned int base_penalty =0; + && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty + && !map->list[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m) + && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY] + ) { + unsigned int base_penalty = 0; if (battle_config.death_penalty_base > 0) { + switch (battle_config.death_penalty_type) { case 1: base_penalty = (unsigned int) ((double)pc->nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000); - break; + break; case 2: base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000); - break; + break; } + if(base_penalty) { if (battle_config.pk_mode && src && src->type==BL_PC) base_penalty*=2; + if( sd->status.mod_death != 100 ) + base_penalty = base_penalty * sd->status.mod_death / 100; sd->status.base_exp -= min(sd->status.base_exp, base_penalty); clif->updatestatus(sd,SP_BASEEXP); } } - if(battle_config.death_penalty_job > 0) - { + + if(battle_config.death_penalty_job > 0) { base_penalty = 0; + switch (battle_config.death_penalty_type) { case 1: base_penalty = (unsigned int) ((double)pc->nextjobexp(sd) * (double)battle_config.death_penalty_job/10000); - break; + break; case 2: base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000); - break; + break; } + if(base_penalty) { if (battle_config.pk_mode && src && src->type==BL_PC) base_penalty*=2; + if( sd->status.mod_death != 100 ) + base_penalty = base_penalty * sd->status.mod_death / 100; sd->status.job_exp -= min(sd->status.job_exp, base_penalty); clif->updatestatus(sd,SP_JOBEXP); } } - if(battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) - { + + if(battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) { base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.); if(base_penalty) pc->payzeny(sd, base_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL); @@ -7141,6 +7155,9 @@ int pc_readparam(struct map_session_data* sd,int type) case SP_KILLEDRID: val = sd->killedrid; break; case SP_SLOTCHANGE: val = sd->status.slotchange; break; case SP_CHARRENAME: val = sd->status.rename; break; + case SP_MOD_EXP: val = sd->status.mod_exp; break; + case SP_MOD_DROP: val = sd->status.mod_drop; break; + case SP_MOD_DEATH: val = sd->status.mod_death; break; case SP_CRITICAL: val = sd->battle_status.cri/10; break; case SP_ASPD: val = (2000-sd->battle_status.amotion)/10; break; case SP_BASE_ATK: val = sd->battle_status.batk; break; @@ -7273,7 +7290,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val) clif->updatestatus(sd, SP_NEXTBASEEXP); clif->updatestatus(sd, SP_STATUSPOINT); clif->updatestatus(sd, SP_BASEEXP); - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); if(sd->status.party_id) { party->send_levelup(sd); @@ -7290,7 +7307,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val) // clif->updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom clif->updatestatus(sd, SP_NEXTJOBEXP); clif->updatestatus(sd, SP_JOBEXP); - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); break; case SP_SKILLPOINT: sd->status.skill_point = val; @@ -7388,6 +7405,15 @@ int pc_setparam(struct map_session_data *sd,int type,int val) case SP_CHARRENAME: sd->status.rename = val; return 1; + case SP_MOD_EXP: + sd->status.mod_exp = val; + return 1; + case SP_MOD_DROP: + sd->status.mod_drop = val; + return 1; + case SP_MOD_DEATH: + sd->status.mod_death = val; + return 1; default: ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type); return 0; @@ -7700,7 +7726,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) if(sd->status.manner < 0) clif->changestatus(sd,SP_MANNER,sd->status.manner); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); pc->checkallowskill(sd); pc->equiplookall(sd); @@ -7823,11 +7849,11 @@ int pc_setoption(struct map_session_data *sd,int type) if( (type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc->checkskill(sd,RK_DRAGONTRAINING) > 0) ) { // Mounting clif->sc_load(&sd->bl,sd->bl.id,AREA,SI_RIDING, 0, 0, 0); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } else if( (!(type&OPTION_RIDING) && p_type&OPTION_RIDING) || (!(type&OPTION_DRAGON) && p_type&OPTION_DRAGON) ) { // Dismount clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_RIDING); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } #ifndef NEW_CARTS @@ -7835,11 +7861,11 @@ int pc_setoption(struct map_session_data *sd,int type) clif->cartlist(sd); clif->updatestatus(sd, SP_CARTINFO); if(pc->checkskill(sd, MC_PUSHCART) < 10) - status_calc_pc(sd,0); //Apply speed penalty. + status_calc_pc(sd,SCO_NONE); //Apply speed penalty. } else if( !( type&OPTION_CART ) && p_type&OPTION_CART ){ //Cart Off clif->clearcart(sd->fd); if(pc->checkskill(sd, MC_PUSHCART) < 10) - status_calc_pc(sd,0); //Remove speed penalty. + status_calc_pc(sd,SCO_NONE); //Remove speed penalty. } #endif @@ -7851,18 +7877,18 @@ int pc_setoption(struct map_session_data *sd,int type) if( (sd->class_&MAPID_THIRDMASK) == MAPID_RANGER ) { if( type&OPTION_WUGRIDER && !(p_type&OPTION_WUGRIDER) ) { // Mounting clif->sc_load(&sd->bl,sd->bl.id,AREA,SI_WUGRIDER, 0, 0, 0); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } else if( !(type&OPTION_WUGRIDER) && p_type&OPTION_WUGRIDER ) { // Dismount clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_WUGRIDER); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } } if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) { int i; if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) ) - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); for( i = 0; i < SC_MAX; i++ ){ if ( !sd->sc.data[i] || !status->get_sc_type(i) ) continue; @@ -7941,7 +7967,7 @@ int pc_setcart(struct map_session_data *sd,int type) { } if(pc->checkskill(sd, MC_PUSHCART) < 10) - status_calc_pc(sd,0); //Recalc speed penalty. + status_calc_pc(sd,SCO_NONE); //Recalc speed penalty. #else // Update option option = sd->sc.option; @@ -8193,7 +8219,7 @@ int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type) i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE); sd->die_counter = val; if( i ) - status_calc_pc(sd,0); // Lost the bonus. + status_calc_pc(sd,SCO_NONE); // Lost the bonus. } else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val ) { @@ -8797,7 +8823,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) } } - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); if (flag) //Update skill data clif->skillinfoblock(sd); @@ -8962,7 +8988,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { if(flag&1 || status_cacl) { pc->checkallowskill(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } if(sd->sc.data[SC_CRUCIS] && !battle->check_undead(sd->battle_status.race,sd->battle_status.def_ele)) @@ -9067,7 +9093,7 @@ int pc_checkitem(struct map_session_data *sd) if( calc_flag && sd->state.active ) { pc->checkallowskill(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } return 0; @@ -9452,10 +9478,16 @@ void pc_overheat(struct map_session_data *sd, int val) { */ bool pc_isautolooting(struct map_session_data *sd, int nameid) { - int i; - if( !sd->state.autolooting ) + int i = 0; + + if (sd->state.autoloottype && sd->state.autoloottype&(1<<itemdb_type(nameid))) + return true; + + if (!sd->state.autolooting) return false; + ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == nameid); + return (i != AUTOLOOTITEM_SIZE); } @@ -10232,6 +10264,7 @@ void pc_bank_withdraw(struct map_session_data *sd, int money) { /* status change data arrived from char-server */ void pc_scdata_received(struct map_session_data *sd) { pc->inventory_rentals(sd); + clif->show_modifiers(sd); } /*========================================== @@ -10241,13 +10274,15 @@ void do_final_pc(void) { db_destroy(pc->itemcd_db); - do_final_pc_groups(); + pcg->final(); ers_destroy(pc->sc_display_ers); return; } -void do_init_pc(void) { +void do_init_pc(bool minimal) { + if (minimal) + return; pc->itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA); @@ -10279,7 +10314,7 @@ void do_init_pc(void) { pc->night_timer_tid = timer->add_interval(timer->gettick() + day_duration + (map->night_flag ? night_duration : 0), pc->map_night_timer, 0, 0, day_duration + night_duration); } - do_init_pc_groups(); + pcg->init(); pc->sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:sc_display_ers", ERS_OPT_NONE); } @@ -10295,7 +10330,7 @@ void pc_defaults(void) { { SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon }, { SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star } }; - 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_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO}; + unsigned int 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_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO, EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L }; pc = &pc_s; |