|
@@ -1146,6 +1146,8 @@ void initChangeTables(void)
|
|
|
StatusIconChangeTable[SC_SPL_MATK] = EFST_SPL_MATK;
|
|
|
StatusIconChangeTable[SC_ATKPOTION] = EFST_PLUSATTACKPOWER;
|
|
|
StatusIconChangeTable[SC_MATKPOTION] = EFST_PLUSMAGICPOWER;
|
|
|
+ StatusIconChangeTable[SC_INCREASE_MAXHP] = EFST_ATKER_ASPD;
|
|
|
+ StatusIconChangeTable[SC_INCREASE_MAXSP] = EFST_ATKER_MOVESPEED;
|
|
|
|
|
|
/* Cash Items */
|
|
|
StatusIconChangeTable[SC_FOOD_STR_CASH] = EFST_FOOD_STR_CASH;
|
|
@@ -1436,6 +1438,8 @@ void initChangeTables(void)
|
|
|
StatusChangeFlagTable[SC_GEFFEN_MAGIC1] |= SCB_ALL;
|
|
|
StatusChangeFlagTable[SC_GEFFEN_MAGIC2] |= SCB_ALL;
|
|
|
StatusChangeFlagTable[SC_GEFFEN_MAGIC3] |= SCB_ALL;
|
|
|
+ StatusChangeFlagTable[SC_INCREASE_MAXHP] |= SCB_MAXHP|SCB_REGEN;
|
|
|
+ StatusChangeFlagTable[SC_INCREASE_MAXSP] |= SCB_MAXSP|SCB_REGEN;
|
|
|
|
|
|
/* Cash Items */
|
|
|
StatusChangeFlagTable[SC_FOOD_STR_CASH] |= SCB_STR;
|
|
@@ -3353,13 +3357,6 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
} else if (type == STATUS_BONUS_RATE) {
|
|
|
struct status_change *sc = status_get_sc(bl);
|
|
|
|
|
|
- //Only for BL_PC
|
|
|
- if (bl->type == BL_PC) {
|
|
|
- struct map_session_data *sd = map_id2sd(bl->id);
|
|
|
- bonus += sd->hprate;
|
|
|
- bonus -= 100; //Default hprate is 100, so it should be add 0%
|
|
|
- }
|
|
|
-
|
|
|
//Bonus by SC
|
|
|
if (sc) {
|
|
|
//Increasing
|
|
@@ -3385,8 +3382,6 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
bonus += (2 + sc->data[SC_RAISINGDRAGON]->val1);
|
|
|
if(sc->data[SC_GT_REVITALIZE])
|
|
|
bonus += sc->data[SC_GT_REVITALIZE]->val2;
|
|
|
- if(sc->data[SC_MUSTLE_M])
|
|
|
- bonus += sc->data[SC_MUSTLE_M]->val1;
|
|
|
if(sc->data[SC_ANGRIFFS_MODUS])
|
|
|
bonus += (5 * sc->data[SC_ANGRIFFS_MODUS]->val1);
|
|
|
if(sc->data[SC_PETROLOGY_OPTION])
|
|
@@ -3413,8 +3408,6 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
bonus -= sc->data[SC_BEYONDOFWARCRY]->val4;
|
|
|
if(sc->data[SC__WEAKNESS])
|
|
|
bonus -= sc->data[SC__WEAKNESS]->val2;
|
|
|
- if(sc->data[SC_MYSTERIOUS_POWDER])
|
|
|
- bonus -= sc->data[SC_MYSTERIOUS_POWDER]->val1;
|
|
|
if(sc->data[SC_EQC])
|
|
|
bonus -= sc->data[SC_EQC]->val3;
|
|
|
}
|
|
@@ -3425,6 +3418,40 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
return min(bonus,INT_MAX);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+* HP bonus rate from equipment
|
|
|
+*/
|
|
|
+static int status_get_hpbonus_equip(TBL_PC *sd) {
|
|
|
+ int bonus = 0;
|
|
|
+
|
|
|
+ bonus += sd->hprate;
|
|
|
+
|
|
|
+ return bonus -= 100; //Default hprate is 100, so it should be add 0%
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+* HP bonus rate from usable items
|
|
|
+*/
|
|
|
+static int status_get_hpbonus_item(block_list *bl) {
|
|
|
+ int bonus = 0;
|
|
|
+
|
|
|
+ struct status_change *sc = status_get_sc(bl);
|
|
|
+
|
|
|
+ //Bonus by SC
|
|
|
+ if (sc) {
|
|
|
+ if (sc->data[SC_INCREASE_MAXHP])
|
|
|
+ bonus += sc->data[SC_INCREASE_MAXHP]->val1;
|
|
|
+ if (sc->data[SC_MUSTLE_M])
|
|
|
+ bonus += sc->data[SC_MUSTLE_M]->val1;
|
|
|
+
|
|
|
+ if (sc->data[SC_MYSTERIOUS_POWDER])
|
|
|
+ bonus -= sc->data[SC_MYSTERIOUS_POWDER]->val1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Max rate reduce is -100%
|
|
|
+ return cap_value(bonus, -100, INT_MAX);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Get SP bonus modifiers
|
|
|
* @param bl: block_list that will be checked
|
|
@@ -3487,9 +3514,6 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
struct map_session_data *sd = map_id2sd(bl->id);
|
|
|
uint8 i;
|
|
|
|
|
|
- bonus += sd->sprate;
|
|
|
- bonus -= 100; //Default sprate is 100, so it should be add 0%
|
|
|
-
|
|
|
if((i = pc_checkskill(sd,HP_MEDITATIO)) > 0)
|
|
|
bonus += i;
|
|
|
if((i = pc_checkskill(sd,HW_SOULDRAIN)) > 0)
|
|
@@ -3512,12 +3536,6 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
bonus += sc->data[SC_SERVICE4U]->val2;
|
|
|
if(sc->data[SC_MERC_SPUP])
|
|
|
bonus += sc->data[SC_MERC_SPUP]->val2;
|
|
|
- if(sc->data[SC_LIFE_FORCE_F])
|
|
|
- bonus += sc->data[SC_LIFE_FORCE_F]->val1;
|
|
|
- if(sc->data[SC_VITATA_500])
|
|
|
- bonus += sc->data[SC_VITATA_500]->val2;
|
|
|
- if (sc->data[SC_ENERGY_DRINK_RESERCH])
|
|
|
- bonus += sc->data[SC_ENERGY_DRINK_RESERCH]->val3;
|
|
|
}
|
|
|
// Max rate reduce is -100%
|
|
|
bonus = cap_value(bonus,-100,INT_MAX);
|
|
@@ -3526,6 +3544,41 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
|
|
|
return min(bonus,INT_MAX);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+* SP bonus rate from equipment
|
|
|
+*/
|
|
|
+static int status_get_spbonus_equip(TBL_PC *sd) {
|
|
|
+ int bonus = 0;
|
|
|
+
|
|
|
+ bonus += sd->sprate;
|
|
|
+
|
|
|
+ return bonus -= 100; //Default sprate is 100, so it should be add 0%
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+* SP bonus rate from usable items
|
|
|
+*/
|
|
|
+static int status_get_spbonus_item(block_list *bl) {
|
|
|
+ int bonus = 0;
|
|
|
+
|
|
|
+ struct status_change *sc = status_get_sc(bl);
|
|
|
+
|
|
|
+ //Bonus by SC
|
|
|
+ if (sc) {
|
|
|
+ if (sc->data[SC_INCREASE_MAXSP])
|
|
|
+ bonus += sc->data[SC_INCREASE_MAXSP]->val1;
|
|
|
+ if (sc->data[SC_LIFE_FORCE_F])
|
|
|
+ bonus += sc->data[SC_LIFE_FORCE_F]->val1;
|
|
|
+ if (sc->data[SC_VITATA_500])
|
|
|
+ bonus += sc->data[SC_VITATA_500]->val2;
|
|
|
+ if (sc->data[SC_ENERGY_DRINK_RESERCH])
|
|
|
+ bonus += sc->data[SC_ENERGY_DRINK_RESERCH]->val3;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Max rate reduce is -100%
|
|
|
+ return cap_value(bonus, -100, INT_MAX);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Get final MaxHP or MaxSP for player. References: http://irowiki.org/wiki/Max_HP and http://irowiki.org/wiki/Max_SP
|
|
|
* The calculation needs base_level, base_status/battle_status (vit or int), additive modifier, and multiplicative modifier
|
|
@@ -3545,13 +3598,21 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
|
|
|
level = umax(sd->status.base_level,1);
|
|
|
|
|
|
if (isHP) { //Calculates MaxHP
|
|
|
+ double equip_bonus = 0, item_bonus = 0;
|
|
|
dmax = job_info[idx].base_hp[level-1] * (1 + (umax(stat,1) * 0.01)) * ((sd->class_&JOBL_UPPER)?1.25:(pc_is_taekwon_ranker(sd))?3:1);
|
|
|
dmax += status_get_hpbonus(&sd->bl,STATUS_BONUS_FIX);
|
|
|
+ equip_bonus = (dmax * status_get_hpbonus_equip(sd) / 100);
|
|
|
+ item_bonus = (dmax * status_get_hpbonus_item(&sd->bl) / 100);
|
|
|
+ dmax += equip_bonus + item_bonus;
|
|
|
dmax += (int64)(dmax * status_get_hpbonus(&sd->bl,STATUS_BONUS_RATE) / 100); //Aegis accuracy
|
|
|
}
|
|
|
else { //Calculates MaxSP
|
|
|
+ double equip_bonus = 0, item_bonus = 0;
|
|
|
dmax = job_info[idx].base_sp[level-1] * (1 + (umax(stat,1) * 0.01)) * ((sd->class_&JOBL_UPPER)?1.25:(pc_is_taekwon_ranker(sd))?3:1);
|
|
|
dmax += status_get_spbonus(&sd->bl,STATUS_BONUS_FIX);
|
|
|
+ equip_bonus = (dmax * status_get_spbonus_equip(sd) / 100);
|
|
|
+ item_bonus = (dmax * status_get_spbonus_item(&sd->bl) / 100);
|
|
|
+ dmax += equip_bonus + item_bonus;
|
|
|
dmax += (int64)(dmax * status_get_spbonus(&sd->bl,STATUS_BONUS_RATE) / 100); //Aegis accuracy
|
|
|
}
|
|
|
|
|
@@ -4888,6 +4949,12 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
|
|
|
val = 0;
|
|
|
if( (skill=pc_checkskill(sd,SM_RECOVERY)) > 0 )
|
|
|
val += skill*5 + skill*status->max_hp/500;
|
|
|
+
|
|
|
+ if (sc && sc->count) {
|
|
|
+ if (sc->data[SC_INCREASE_MAXHP])
|
|
|
+ val += val * sc->data[SC_INCREASE_MAXHP]->val2 / 100;
|
|
|
+ }
|
|
|
+
|
|
|
sregen->hp = cap_value(val, 0, SHRT_MAX);
|
|
|
|
|
|
val = 0;
|
|
@@ -4903,6 +4970,8 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
|
|
|
val *= 150 / 100;
|
|
|
if (sc->data[SC_ANCILLA])
|
|
|
val += sc->data[SC_ANCILLA]->val2 / 100;
|
|
|
+ if (sc->data[SC_INCREASE_MAXSP])
|
|
|
+ val += val * sc->data[SC_INCREASE_MAXSP]->val2 / 100;
|
|
|
}
|
|
|
|
|
|
sregen->sp = cap_value(val, 0, SHRT_MAX);
|