diff options
Diffstat (limited to 'src/map/pc.c')
-rw-r--r-- | src/map/pc.c | 189 |
1 files changed, 113 insertions, 76 deletions
diff --git a/src/map/pc.c b/src/map/pc.c index 2dfd9519b..e958f32b6 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -539,7 +539,7 @@ void pc_rental_expire(struct map_session_data *sd, int i) { } clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid); - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_RENTAL); } void pc_inventory_rentals(struct map_session_data *sd) { @@ -676,6 +676,7 @@ int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int lo //Required to prevent homunculus copuing a base speed of 0. sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED; sd->state.warp_clean = 1; + sd->catch_target_class = -1; return 0; } @@ -998,7 +999,7 @@ int pc_isequip(struct map_session_data *sd,int n) } } //Not equipable by class. [Skotlex] - if (!(1<<(sd->class_&MAPID_BASEMASK)&item->class_base[(sd->class_&JOBL_2_1)?1:((sd->class_&JOBL_2_2)?2:0)])) + if (!(1ULL<<(sd->class_&MAPID_BASEMASK)&item->class_base[(sd->class_&JOBL_2_1)?1:((sd->class_&JOBL_2_2)?2:0)])) return 0; //Not usable by upper class. [Inkfish] while( 1 ) { @@ -1033,7 +1034,8 @@ int pc_isequip(struct map_session_data *sd,int n) * No problem with the session id * set the status that has been sent from char server *------------------------------------------*/ -bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) { +bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, const struct mmo_charstatus *st, bool changing_mapservers) +{ int i; int64 tick = timer->gettick(); uint32 ip = sockt->session[sd->fd]->client_addr; @@ -1212,7 +1214,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim //display login notice ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in." " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"'," - " IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'," + " IP: '"CL_WHITE"%u.%u.%u.%u"CL_RESET"'," " Group '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id, sd->status.char_id, CONVIP(ip), sd->group_id); @@ -2883,6 +2885,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) { break; default: ShowWarning("pc_bonus: unknown type %d %d !\n",type,val); + Assert_report(0); break; } return 0; @@ -3675,6 +3678,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) #endif default: ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); + Assert_report(0); break; } return 0; @@ -3847,6 +3851,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) default: ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val); + Assert_report(0); break; } @@ -3941,6 +3946,7 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 default: ShowWarning("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val); + Assert_report(0); break; } @@ -3968,6 +3974,7 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4 default: ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val); + Assert_report(0); break; } @@ -4129,7 +4136,7 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip) // remember the card id to insert nameid = sd->status.inventory[idx_card].nameid; - if( pc->delitem(sd, idx_card, 1, 1, DELITEM_NORMAL, LOG_TYPE_OTHER) == 1 ) + if( pc->delitem(sd, idx_card, 1, 1, DELITEM_NORMAL, LOG_TYPE_CARD) == 1 ) {// failed clif->insert_card(sd,idx_equip,idx_card,1); } @@ -4139,9 +4146,9 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip) ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0); if (i == sd->inventory_data[idx_equip]->slot) return 0; // no free slots - logs->pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]); + logs->pick_pc(sd, LOG_TYPE_CARD, -1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]); sd->status.inventory[idx_equip].card[i] = nameid; - logs->pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]); + logs->pick_pc(sd, LOG_TYPE_CARD, 1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]); clif->insert_card(sd,idx_equip,idx_card,0); return 1; } @@ -4156,34 +4163,39 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip) /*========================================== * Update buying value by skills *------------------------------------------*/ -int pc_modifybuyvalue(struct map_session_data *sd,int orig_value) { - int skill_lv,val = orig_value,rate1 = 0,rate2 = 0; - if((skill_lv=pc->checkskill(sd,MC_DISCOUNT))>0) // merchant discount +int pc_modifybuyvalue(struct map_session_data *sd, int orig_value) +{ + int skill_lv, rate1 = 0, rate2 = 0; + if (orig_value <= 0) + return 0; + if ((skill_lv=pc->checkskill(sd,MC_DISCOUNT)) > 0) // merchant discount rate1 = 5+skill_lv*2-((skill_lv==10)? 1:0); - if((skill_lv=pc->checkskill(sd,RG_COMPULSION))>0) // rogue discount + if ((skill_lv=pc->checkskill(sd,RG_COMPULSION)) > 0) // rogue discount rate2 = 5+skill_lv*4; - if(rate1 < rate2) rate1 = rate2; - if(rate1) - val = (int)((double)orig_value*(double)(100-rate1)/100.); - if(val < 0) val = 0; - if(orig_value > 0 && val < 1) val = 1; - - return val; + if (rate1 < rate2) + rate1 = rate2; + if (rate1 != 0) + orig_value = apply_percentrate(orig_value, 100-rate1, 100); + if (orig_value < 1) + orig_value = 1; + return orig_value; } /*========================================== * Update selling value by skills *------------------------------------------*/ -int pc_modifysellvalue(struct map_session_data *sd,int orig_value) { - int skill_lv,val = orig_value,rate = 0; - if((skill_lv=pc->checkskill(sd,MC_OVERCHARGE))>0) //OverCharge +int pc_modifysellvalue(struct map_session_data *sd, int orig_value) +{ + int skill_lv, rate = 0; + if (orig_value <= 0) + return 0; + if ((skill_lv=pc->checkskill(sd,MC_OVERCHARGE)) > 0) //OverCharge rate = 5+skill_lv*2-((skill_lv==10)? 1:0); - if(rate) - val = (int)((double)orig_value*(double)(100+rate)/100.); - if(val < 0) val = 0; - if(orig_value > 0 && val < 1) val = 1; - - return val; + if (rate != 0) + orig_value = apply_percentrate(orig_value, 100+rate, 100); + if (orig_value < 1) + orig_value = 1; + return orig_value; } /*========================================== @@ -4837,7 +4849,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) //Not equipable by class. [Skotlex] if (!( - (1<<(sd->class_&MAPID_BASEMASK)) & + (1ULL<<(sd->class_&MAPID_BASEMASK)) & (item->class_base[(sd->class_&JOBL_2_1) ? 1 : ((sd->class_&JOBL_2_2) ? 2 : 0)]) )) return 0; @@ -5259,7 +5271,7 @@ int pc_show_steal(struct block_list *bl,va_list ap) int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skill_lv) { int i,itemid,flag; - double rate; + int rate; struct status_data *sd_status, *md_status; struct mob_data *md = BL_CAST(BL_MOB, bl); struct item tmp_item; @@ -5284,18 +5296,22 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil } // base skill success chance (percentual) - rate = (sd_status->dex - md_status->dex)/2 + skill_lv*6 + 4; - rate += sd->bonus.add_steal_rate; + rate = (sd_status->dex - md_status->dex)/2 + skill_lv*6 + 4 + sd->bonus.add_steal_rate; if( rate < 1 ) return 0; // Try dropping one item, in the order from first to last possible slot. // Droprate is affected by the skill success rate. - for( i = 0; i < MAX_STEAL_DROP; i++ ) - if (md->db->dropitem[i].nameid > 0 && (data = itemdb->exists(md->db->dropitem[i].nameid)) != NULL && rnd() % 10000 < md->db->dropitem[i].p * rate/100.) + for (i = 0; i < MAX_STEAL_DROP; i++) { + if (md->db->dropitem[i].nameid == 0) + continue; + if ((data = itemdb->exists(md->db->dropitem[i].nameid)) == NULL) + continue; + if (rnd() % 10000 < apply_percentrate(md->db->dropitem[i].p, rate, 100)) break; - if( i == MAX_STEAL_DROP ) + } + if (i == MAX_STEAL_DROP) return 0; itemid = md->db->dropitem[i].nameid; @@ -6612,16 +6628,16 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in if (sd->sc.data[SC_OVERLAPEXPUP]) bonus += sd->sc.data[SC_OVERLAPEXPUP]->val1; - *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX); + *base_exp = (unsigned int) cap_value(*base_exp + apply_percentrate64(*base_exp, bonus, 100), 1, UINT_MAX); if (sd->sc.data[SC_CASH_PLUSONLYJOBEXP]) bonus += sd->sc.data[SC_CASH_PLUSONLYJOBEXP]->val1; - *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX); + *job_exp = (unsigned int) cap_value(*job_exp + apply_percentrate64(*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); + if (sd->status.mod_exp != 100) { + *base_exp = (unsigned int) cap_value(apply_percentrate64(*base_exp, sd->status.mod_exp, 100), 1, UINT_MAX); + *job_exp = (unsigned int) cap_value(apply_percentrate64(*job_exp, sd->status.mod_exp, 100), 1, UINT_MAX); } } @@ -7187,7 +7203,7 @@ int pc_resetstate(struct map_session_data* sd) // New statpoint table used here - Dexity if (sd->status.base_level > MAX_LEVEL) { //pc->statp[] goes out of bounds, can't reset! - ShowError("pc_resetstate: Can't reset stats of %d:%d, the base level (%d) is greater than the max level supported (%d)\n", + ShowError("pc_resetstate: Can't reset stats of %d:%d, the base level (%u) is greater than the max level supported (%d)\n", sd->status.account_id, sd->status.char_id, sd->status.base_level, MAX_LEVEL); return 0; } @@ -7713,18 +7729,18 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { && !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) { + unsigned int base_penalty = 0; switch (battle_config.death_penalty_type) { case 1: - base_penalty = (unsigned int) ((double)pc->nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000); + base_penalty = (unsigned int) apply_percentrate64(pc->nextbaseexp(sd), battle_config.death_penalty_base, 10000); break; case 2: - base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000); + base_penalty = (unsigned int) apply_percentrate64(sd->status.base_exp, battle_config.death_penalty_base, 10000); break; } - if(base_penalty) { + if (base_penalty != 0) { if (battle_config.pk_mode && src && src->type==BL_PC) base_penalty*=2; if( sd->status.mod_death != 100 ) @@ -7735,31 +7751,31 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { } if(battle_config.death_penalty_job > 0) { - base_penalty = 0; + unsigned int job_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); + job_penalty = (unsigned int) apply_percentrate64(pc->nextjobexp(sd), battle_config.death_penalty_job, 10000); break; case 2: - base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000); + job_penalty = (unsigned int) apply_percentrate64(sd->status.job_exp, battle_config.death_penalty_job, 10000); break; } - if(base_penalty) { + if (job_penalty != 0) { if (battle_config.pk_mode && src && src->type==BL_PC) - base_penalty*=2; + job_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); + job_penalty = job_penalty * sd->status.mod_death / 100; + sd->status.job_exp -= min(sd->status.job_exp, job_penalty); clif->updatestatus(sd,SP_JOBEXP); } } - 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); + if (battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) { + int zeny_penalty = apply_percentrate(sd->status.zeny, battle_config.zeny_penalty, 10000); + if (zeny_penalty != 0) + pc->payzeny(sd, zeny_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL); } } @@ -9556,7 +9572,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) pos = pc->equippoint(sd,n); //With a few exceptions, item should go in all specified slots. if(battle_config.battle_log) - ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos); + ShowInfo("equip %d(%d) %x:%x\n", sd->status.inventory[n].nameid, n, (unsigned int)(id ? id->equip : 0), (unsigned int)req_pos); if(!pc->isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris] // FIXME: pc->isequip: equip level failure uses 2 instead of 0 clif->equipitemack(sd,n,0,EIA_FAIL); // fail @@ -9764,7 +9780,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) } if(battle_config.battle_log) - ShowInfo("unequip %d %x:%x\n",n,pc->equippoint(sd,n),sd->status.inventory[n].equip); + ShowInfo("unequip %d %x:%x\n", n, (unsigned int)(pc->equippoint(sd, n)), sd->status.inventory[n].equip); if(!sd->status.inventory[n].equip){ //Nothing to unequip clif->unequipitemack(sd,n,0,UIA_FAIL); @@ -9889,7 +9905,7 @@ int pc_checkitem(struct map_session_data *sd) if (!itemdb_available(id)) { ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id); - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_INV_INVALID); continue; } @@ -9905,7 +9921,7 @@ int pc_checkitem(struct map_session_data *sd) if( !itemdb_available(id) ) { ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id); - pc->cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER); + pc->cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_CART_INVALID); continue; } @@ -10123,9 +10139,9 @@ int pc_divorce(struct map_session_data *sd) for( i = 0; i < MAX_INVENTORY; i++ ) { if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F ) - pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_DIVORCE); if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F ) - pc->delitem(p_sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); + pc->delitem(p_sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_DIVORCE); } clif->divorced(sd, p_sd->status.name); @@ -10529,11 +10545,18 @@ void pc_del_charm(struct map_session_data *sd, int count, int type) clif->spiritcharm(sd); } -/*========================================== - * Renewal EXP/Itemdrop rate modifier base on level penalty - * 1=exp 2=itemdrop - *------------------------------------------*/ -int pc_level_penalty_mod(int diff, unsigned char race, unsigned short mode, int type) { + +/** + * Renewal EXP/Itemdrop rate modifier base on level penalty. + * + * @param diff Level difference. + * @param race Monster race. + * @param mode Monster mode. + * @param type Modifier type (1=exp 2=itemdrop) + * @return The percent rate modifier (100 = 100%) + */ +int pc_level_penalty_mod(int diff, unsigned char race, uint32 mode, int type) +{ #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) int rate = 100, i; @@ -10633,8 +10656,8 @@ int pc_split_atoui(char* str, unsigned int* val, char sep, int max) */ void pc_read_skill_tree(void) { - config_t skill_tree_conf; - config_setting_t *skt = NULL; + struct config_t skill_tree_conf; + struct config_setting_t *skt = NULL; char config_filename[128]; int i = 0; struct s_mapiterator *iter; @@ -10642,14 +10665,12 @@ void pc_read_skill_tree(void) bool loaded[CLASS_COUNT] = { false }; safesnprintf(config_filename, sizeof(config_filename), "%s/"DBPATH"skill_tree.conf", map->db_path); - if (libconfig->read_file(&skill_tree_conf, config_filename)) { - ShowError("can't read %s\n", config_filename); + if (!libconfig->load_file(&skill_tree_conf, config_filename)) return; - } // Foreach job while ((skt = libconfig->setting_get_elem(skill_tree_conf.root, i++))) { - config_setting_t *t = NULL; + struct config_setting_t *t = NULL; int job_idx; const char *job_name = config_setting_name(skt); int job_id = pc->check_job_name(job_name); @@ -10739,11 +10760,11 @@ void pc_read_skill_tree(void) } if ((t = libconfig->setting_get_member(skt, "skills")) != NULL) { int j = 0; - config_setting_t *sk = NULL; + struct config_setting_t *sk = NULL; // Foreach skill while ((sk = libconfig->setting_get_elem(t, j++)) != NULL) { int skill_id, sk_idx; - config_setting_t *rsk = NULL; + struct config_setting_t *rsk = NULL; const char *sk_name = config_setting_name(sk); struct skill_tree_entry *tree_entry = NULL; @@ -10920,7 +10941,7 @@ int pc_readdb(void) { } maxlv = atoi(split[0]); if (maxlv > MAX_LEVEL) { - ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%u).\n ", maxlv, job_id, MAX_LEVEL); + ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%d).\n ", maxlv, job_id, MAX_LEVEL); maxlv = MAX_LEVEL; } count++; @@ -11346,7 +11367,7 @@ void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update if( sd->vending[i].amount == 0 ) continue; - if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`char_id`,`itemkey`,`amount`,`price`) VALUES ('%d','%d','%d','%d')", + if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`char_id`,`itemkey`,`amount`,`price`) VALUES ('%d','%d','%d','%u')", map->autotrade_data_db, sd->status.char_id, sd->status.cart[sd->vending[i].index].id, @@ -11479,6 +11500,20 @@ bool pc_db_checkid(unsigned int class_) || (class_ >= JOB_REBELLION && class_ < JOB_MAX ); } +/** + * checks if player have any kind of magnifier in inventory + * @param sd map_session_data of Player + * @return index of magnifer, INDEX_NOT_FOUND if it is not found + */ +int pc_have_magnifier(struct map_session_data *sd) +{ + int n; + n = pc->search_inventory(sd, ITEMID_MAGNIFIER); + if (n == INDEX_NOT_FOUND) + n = pc->search_inventory(sd, ITEMID_NOVICE_MAGNIFIER); + return n; +} + void do_final_pc(void) { db_destroy(pc->itemcd_db); pc->at_db->destroy(pc->at_db,pc->autotrade_final); @@ -11846,4 +11881,6 @@ void pc_defaults(void) { pc->check_job_name = pc_check_job_name; pc->update_idle_time = pc_update_idle_time; + + pc->have_magnifier = pc_have_magnifier; } |