diff options
Diffstat (limited to 'src/map/pc.c')
-rw-r--r-- | src/map/pc.c | 192 |
1 files changed, 116 insertions, 76 deletions
diff --git a/src/map/pc.c b/src/map/pc.c index b6c354189..e29ef343f 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -196,7 +196,7 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max) sd->spirit_timer[i] = tid; sd->spiritball++; if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD ) - clif->millenniumshield(sd,sd->spiritball); + clif->millenniumshield(&sd->bl,sd->spiritball); else clif->spiritball(&sd->bl); @@ -235,7 +235,7 @@ int pc_delspiritball(struct map_session_data *sd,int count,int type) if(!type) { if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD ) - clif->millenniumshield(sd,sd->spiritball); + clif->millenniumshield(&sd->bl,sd->spiritball); else clif->spiritball(&sd->bl); } @@ -3957,12 +3957,13 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l i = MAX_INVENTORY; - if( itemdb->isstackable2(data) && item_data->expire_time == 0 ) - { // Stackable | Non Rental - for( i = 0; i < MAX_INVENTORY; i++ ) - { - if( sd->status.inventory[i].nameid == item_data->nameid && sd->status.inventory[i].bound == item_data->bound && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) - { + // Stackable | Non Rental + if( itemdb->isstackable2(data) && item_data->expire_time == 0 ) { + for( i = 0; i < MAX_INVENTORY; i++ ) { + if( sd->status.inventory[i].nameid == item_data->nameid && + sd->status.inventory[i].bound == item_data->bound && + sd->status.inventory[i].expire_time == 0 && + memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) { if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) ) return 5; sd->status.inventory[i].amount += amount; @@ -5205,7 +5206,8 @@ int pc_checkallowskill(struct map_session_data *sd) SC_LKCONCENTRATION, SC_EDP, #endif - SC_FEARBREEZE + SC_FEARBREEZE, + SC_EXEEDBREAK, }; const enum sc_type scs_list[] = { SC_AUTOGUARD, @@ -6174,52 +6176,88 @@ int pc_need_status_point(struct map_session_data* sd, int type, int val) return sp; } -/// Raises a stat by 1. -/// Obeys max_parameter limits. -/// Subtracts stat points. -/// -/// @param type The stat to change (see enum _sp) -int pc_statusup(struct map_session_data* sd, int type) -{ - int max, need, val; +/** + * Returns the value the specified stat can be increased by with the current + * amount of available status points for the current character's class. + * + * @param sd The target character. + * @param type Stat to verify. + * @return Maximum value the stat could grow by. + */ +int pc_maxparameterincrease(struct map_session_data* sd, int type) { + int base, final, status_points = sd->status.status_point; + + base = final = pc->getstat(sd, type); + + while (final <= pc_maxparameter(sd) && status_points >= 0) { +#ifdef RENEWAL // renewal status point cost formula + status_points -= (final < 100) ? (2 + (final - 1) / 10) : (16 + 4 * ((final - 100) / 5)); +#else + status_points -= ( 1 + (final + 9) / 10 ); +#endif + final++; + } + final--; + + return final > base ? final-base : 0; +} + +/** + * Raises a stat by the specified amount. + * Obeys max_parameter limits. + * Subtracts stat points. + * + * @param sd The target character. + * @param type The stat to change (see enum _sp) + * @param increase The stat increase amount. + * @return true if the stat was increased by any amount, false if there were no + * changes. + */ +bool pc_statusup(struct map_session_data* sd, int type, int increase) { + int max_increase = 0, current = 0, needed_points = 0, final_value = 0; nullpo_ret(sd); // check conditions - need = pc->need_status_point(sd,type,1); - if( type < SP_STR || type > SP_LUK || need < 0 || need > sd->status.status_point ) - { - clif->statusupack(sd,type,0,0); - return 1; + if (type < SP_STR || type > SP_LUK || increase <= 0) { + clif->statusupack(sd, type, 0, 0); + return false; } // check limits - max = pc_maxparameter(sd); - if( pc->getstat(sd,type) >= max ) - { - clif->statusupack(sd,type,0,0); - return 1; + current = pc->getstat(sd, type); + max_increase = pc->maxparameterincrease(sd, type); + increase = cap_value(increase, 0, max_increase); // cap to the maximum status points available + if (increase <= 0 || current + increase > pc_maxparameter(sd)) { + clif->statusupack(sd, type, 0, 0); + return false; + } + + // check status points + needed_points = pc->need_status_point(sd, type, increase); + if (needed_points < 0 || needed_points > sd->status.status_point) { // Sanity check + clif->statusupack(sd, type, 0, 0); + return false; } // set new values - val = pc->setstat(sd, type, pc->getstat(sd,type) + 1); - sd->status.status_point -= need; + final_value = pc->setstat(sd, type, current + increase); + sd->status.status_point -= needed_points; - status_calc_pc(sd,SCO_NONE); + status_calc_pc(sd, SCO_NONE); // update increase cost indicator - if( need != pc->need_status_point(sd,type,1) ) - clif->updatestatus(sd, SP_USTR + type-SP_STR); + clif->updatestatus(sd, SP_USTR + type-SP_STR); // update statpoint count - clif->updatestatus(sd,SP_STATUSPOINT); + clif->updatestatus(sd, SP_STATUSPOINT); // update stat value - clif->statusupack(sd,type,1,val); // required - if( val > 255 ) - clif->updatestatus(sd,type); // send after the 'ack' to override the truncated value + clif->statusupack(sd, type, 1, final_value); // required + if (final_value > 255) + clif->updatestatus(sd, type); // send after the 'ack' to override the truncated value - return 0; + return true; } /// Raises a stat by the specified amount. @@ -8410,17 +8448,19 @@ int pc_cleareventtimer(struct map_session_data *sd) /* called when a item with combo is worn */ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { int i, j, k, z; - int index, idx, success = 0; + int index, success = 0; + struct pc_combos *combo; for( i = 0; i < data->combos_count; i++ ) { /* ensure this isn't a duplicate combo */ - if( sd->combos.bonus != NULL ) { + if( sd->combos != NULL ) { int x; - ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id ); + + ARR_FIND( 0, sd->combo_count, x, sd->combos[x].id == data->combos[i]->id ); /* found a match, skip this combo */ - if( x < sd->combos.count ) + if( x < sd->combo_count ) continue; } @@ -8437,7 +8477,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { if(!sd->inventory_data[index]) continue; - + if ( itemdb_type(id) != IT_CARD ) { if ( sd->inventory_data[index]->nameid != id ) continue; @@ -8471,22 +8511,13 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { /* we got here, means all items in the combo are matching */ - idx = sd->combos.count; - - if( sd->combos.bonus == NULL ) { - CREATE(sd->combos.bonus, struct script_code *, 1); - CREATE(sd->combos.id, unsigned short, 1); - sd->combos.count = 1; - } else { - RECREATE(sd->combos.bonus, struct script_code *, ++sd->combos.count); - RECREATE(sd->combos.id, unsigned short, sd->combos.count); - } - - /* we simply copy the pointer */ - sd->combos.bonus[idx] = data->combos[i]->script; - /* save this combo's id */ - sd->combos.id[idx] = data->combos[i]->id; - + RECREATE(sd->combos, struct pc_combos, ++sd->combo_count); + + combo = &sd->combos[sd->combo_count - 1]; + + combo->bonus = data->combos[i]->script; + combo->id = data->combos[i]->id; + success++; } return success; @@ -8496,26 +8527,30 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { int pc_removecombo(struct map_session_data *sd, struct item_data *data ) { int i, retval = 0; - if( sd->combos.bonus == NULL ) + if( !sd->combos ) return 0;/* nothing to do here, player has no combos */ + for( i = 0; i < data->combos_count; i++ ) { /* check if this combo exists in this user */ int x = 0, cursor = 0, j; - ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id ); + + ARR_FIND( 0, sd->combo_count, x, sd->combos[x].id == data->combos[i]->id ); /* no match, skip this combo */ - if( !(x < sd->combos.count) ) + if( !(x < sd->combo_count) ) continue; - sd->combos.bonus[x] = NULL; - sd->combos.id[x] = 0; + sd->combos[x].bonus = NULL; + sd->combos[x].id = 0; + retval++; - for( j = 0, cursor = 0; j < sd->combos.count; j++ ) { - if( sd->combos.bonus[j] == NULL ) + + for( j = 0, cursor = 0; j < sd->combo_count; j++ ) { + if( sd->combos[j].bonus == NULL ) continue; if( cursor != j ) { - sd->combos.bonus[cursor] = sd->combos.bonus[j]; - sd->combos.id[cursor] = sd->combos.id[j]; + sd->combos[cursor].bonus = sd->combos[j].bonus; + sd->combos[cursor].id = sd->combos[j].id; } cursor++; @@ -8526,11 +8561,10 @@ int pc_removecombo(struct map_session_data *sd, struct item_data *data ) { continue; /* it's empty, we can clear all the memory */ - if( (sd->combos.count = cursor) == 0 ) { - aFree(sd->combos.bonus); - aFree(sd->combos.id); - sd->combos.bonus = NULL; - sd->combos.id = NULL; + if( (sd->combo_count = cursor) == 0 ) { + aFree(sd->combos); + sd->combos = NULL; + return retval; /* we also can return at this point for we have no more combos to check */ } @@ -8953,7 +8987,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { *------------------------------------------*/ int pc_checkitem(struct map_session_data *sd) { - int i,id,calc_flag = 0; + int i, id, calc_flag = 0; nullpo_ret(sd); @@ -9019,7 +9053,7 @@ int pc_checkitem(struct map_session_data *sd) } } - + if( calc_flag && sd->state.active ) { pc->checkallowskill(sd); status_calc_pc(sd,SCO_NONE); @@ -10359,15 +10393,20 @@ void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' LIMIT 1",map->autotrade_merchants_db,sd->status.char_id)) Sql_ShowDebug(map->mysql_handle); break; - case PAUC_START: + case PAUC_START: { + char title[MESSAGE_SIZE*2+1]; + + SQL->EscapeStringLen(map->mysql_handle, title, sd->message, strnlen(sd->message, MESSAGE_SIZE)); + if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`account_id`,`char_id`,`sex`,`title`) VALUES ('%d','%d','%d','%s')", map->autotrade_merchants_db, sd->status.account_id, sd->status.char_id, sd->status.sex, - sd->message + title )) Sql_ShowDebug(map->mysql_handle); + } /* yes we want it to fall */ case PAUC_REFRESH: for( i = 0; i < sd->vend_num; i++ ) { @@ -10674,6 +10713,7 @@ void pc_defaults(void) { pc->thisjobexp = pc_thisjobexp; pc->gets_status_point = pc_gets_status_point; pc->need_status_point = pc_need_status_point; + pc->maxparameterincrease = pc_maxparameterincrease; pc->statusup = pc_statusup; pc->statusup2 = pc_statusup2; pc->skillup = pc_skillup; |