Fixed #141 & Changed regen rate value from 1 to 100

* 1 = 1%, 100 = 100%... previously 1 = 100%
* Increase calculation accuracy. Example for previous calculation of Concentrated_White_Potion_Z (12428) bonus to add 20% HP recovery rate always be fail, since "1*20/100" always be round down to 0, didn't add 20%!
* Vitata_500 (12436) has incomplete vals for SC

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-12-01 19:55:53 +07:00
parent e4663e99e1
commit 071cb76bc3
4 changed files with 91 additions and 81 deletions

View File

@ -6253,7 +6253,7 @@
12433,Drosera_Herb_Salad,Drosera Herb Salad,2,,,50,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_DROCERA_HERB_STEAMED,300000,20; },{},{}
12434,Petite_Tail_Noodles,Petite Tail Noodles,2,,,50,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_PUTTI_TAILS_NOODLES,300000,20; },{},{}
12435,Black_Mass,Black Mass,2,,,50,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_STOMACHACHE,60000,rand(5,10); },{},{}
12436,Vitata_500,Vitata 500,0,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_VITATA_500,500000,0; itemheal 0,200; },{},{}
12436,Vitata_500,Vitata 500,0,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start2 SC_VITATA_500,500000,20,5; itemheal 0,200; },{},{}
12437,Concentrated_Ceromain_Soup,Concentrated Ceromain Soup,2,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_EXTRACT_SALAMINE_JUICE,500000,10; },{},{}
12438,F_Giant_Fly_Wing,F Giant Fly Wing,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{}
12439,F_Battle_Manual,F Old Battle Manual,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{}

View File

@ -6284,7 +6284,7 @@ REPLACE INTO `item_db_re` VALUES (12432,'Siroma_Iced_Tea','Siroma Iced Tea',2,NU
REPLACE INTO `item_db_re` VALUES (12433,'Drosera_Herb_Salad','Drosera Herb Salad',2,NULL,NULL,50,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_DROCERA_HERB_STEAMED,300000,20;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12434,'Petite_Tail_Noodles','Petite Tail Noodles',2,NULL,NULL,50,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_PUTTI_TAILS_NOODLES,300000,20;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12435,'Black_Mass','Black Mass',2,NULL,NULL,50,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_STOMACHACHE,60000,rand(5,10);',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12436,'Vitata_500','Vitata 500',0,10,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_VITATA_500,500000,0; itemheal 0,200;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12436,'Vitata_500','Vitata 500',0,10,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start2 SC_VITATA_500,500000,20,5; itemheal 0,200;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12437,'Concentrated_Ceromain_Soup','Concentrated Ceromain Soup',2,10,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_EXTRACT_SALAMINE_JUICE,500000,10;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12438,'F_Giant_Fly_Wing','F Giant Fly Wing',2,2,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (12439,'F_Battle_Manual','F Old Battle Manual',2,2,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View File

@ -42,10 +42,11 @@
// Regen related flags.
enum e_regen {
RGN_HP = 0x01,
RGN_SP = 0x02,
RGN_SHP = 0x04,
RGN_SSP = 0x08,
RGN_NONE = 0x00,
RGN_HP = 0x01,
RGN_SP = 0x02,
RGN_SHP = 0x04,
RGN_SSP = 0x08,
};
// Bonus values and upgrade chances for refining equipment
@ -937,7 +938,6 @@ void initChangeTables(void)
StatusIconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
StatusIconChangeTable[SC__BLOODYLUST] = SI_BLOODYLUST;
StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
StatusIconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
StatusIconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
StatusIconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
@ -950,15 +950,15 @@ void initChangeTables(void)
StatusIconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
StatusIconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
StatusIconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] = SI_EXTRACT_WHITE_POTION_Z;
StatusIconChangeTable[SC_VITATA_500] = SI_VITATA_500;
StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] = SI_EXTRACT_SALAMINE_JUICE;
StatusIconChangeTable[SC_BOOST500] = SI_BOOST500;
StatusIconChangeTable[SC_FULL_SWING_K] = SI_FULL_SWING_K;
StatusIconChangeTable[SC_MANA_PLUS] = SI_MANA_PLUS;
StatusIconChangeTable[SC_MUSTLE_M] = SI_MUSTLE_M;
StatusIconChangeTable[SC_LIFE_FORCE_F] = SI_LIFE_FORCE_F;
StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] = SI_EXTRACT_WHITE_POTION_Z;
StatusIconChangeTable[SC_VITATA_500] = SI_VITATA_500;
StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] = SI_EXTRACT_SALAMINE_JUICE;
/* Elemental Spirit's 'side' status change icons */
StatusIconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
@ -1092,7 +1092,7 @@ void initChangeTables(void)
StatusChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN|SCB_MAXSP;
StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
StatusChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN;
StatusChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2;
@ -1587,7 +1587,8 @@ int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
sc = NULL;
if (hp < 0) {
if (hp == INT_MIN) hp++; // -INT_MIN == INT_MIN in some architectures!
if (hp == INT_MIN) // -INT_MIN == INT_MIN in some architectures!
hp++;
status_damage(NULL, bl, -hp, 0, 0, 1);
hp = 0;
}
@ -1605,7 +1606,8 @@ int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
}
if(sp < 0) {
if (sp==INT_MIN) sp++;
if (sp == INT_MIN)
sp++;
status_damage(NULL, bl, 0, -sp, 0, 1);
sp = 0;
}
@ -1615,10 +1617,11 @@ int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
sp = status->max_sp - status->sp;
}
if(!sp && !hp) return 0;
if(!sp && !hp)
return 0;
status->hp+= hp;
status->sp+= sp;
status->hp += hp;
status->sp += sp;
if(hp && sc &&
sc->data[SC_AUTOBERSERK] &&
@ -2742,6 +2745,8 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
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;
}
// Max rate reduce is -100%
bonus = cap_value(bonus,-100,INT_MAX);
@ -3965,25 +3970,26 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
regen->flag = RGN_HP|RGN_SP;
if(regen->sregen) {
if (regen->sregen->hp)
regen->flag|=RGN_SHP;
regen->flag |= RGN_SHP;
if (regen->sregen->sp)
regen->flag|=RGN_SSP;
regen->sregen->rate.hp = regen->sregen->rate.sp = 1;
regen->flag |= RGN_SSP;
regen->sregen->rate.hp = regen->sregen->rate.sp = 100;
}
if (regen->ssregen) {
if (regen->ssregen->hp)
regen->flag|=RGN_SHP;
regen->flag |= RGN_SHP;
if (regen->ssregen->sp)
regen->flag|=RGN_SSP;
regen->ssregen->rate.hp = regen->ssregen->rate.sp = 1;
regen->flag |= RGN_SSP;
regen->ssregen->rate.hp = regen->ssregen->rate.sp = 100;
}
regen->rate.hp = regen->rate.sp = 1;
regen->rate.hp = regen->rate.sp = 100;
if (!sc || !sc->count)
return;
// No HP or SP regen
if ((sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
|| (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
|| sc->data[SC_BERSERK]
@ -3992,8 +3998,9 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|| sc->data[SC_MAGICMUSHROOM]
|| sc->data[SC_SATURDAYNIGHTFEVER]
|| sc->data[SC_REBOUND])
regen->flag = 0; // No HP or SP regen
regen->flag = RGN_NONE;
// No natural SP regen
if (sc->data[SC_DANCING] ||
#ifdef RENEWAL
sc->data[SC_MAXIMIZEPOWER] ||
@ -4006,38 +4013,38 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
sc->data[SC_EXTREMITYFIST] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)) ||
#endif
sc->data[SC_OBLIVIONCURSE] || sc->data[SC_VITALITYACTIVATION])
regen->flag &= ~RGN_SP; // No natural SP regen
regen->flag &= ~RGN_SP;
if(sc->data[SC_TENSIONRELAX]) {
regen->rate.hp += 2;
regen->rate.hp += 200;
if (regen->sregen)
regen->sregen->rate.hp += 3;
regen->sregen->rate.hp += 300;
}
if (sc->data[SC_MAGNIFICAT]) {
regen->rate.hp += 1;
regen->rate.sp += 1;
regen->rate.hp += 100;
regen->rate.sp += 100;
}
if (sc->data[SC_REGENERATION]) {
const struct status_change_entry *sce = sc->data[SC_REGENERATION];
if (!sce->val4) {
regen->rate.hp += sce->val2;
regen->rate.sp += sce->val3;
regen->rate.hp += (sce->val2*100);
regen->rate.sp += (sce->val3*100);
} else
regen->flag&=~sce->val4; // Remove regen as specified by val4
regen->flag &= ~sce->val4; // Remove regen as specified by val4
}
if(sc->data[SC_GT_REVITALIZE]) {
regen->hp += cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
regen->hp += cap_value(regen->hp * sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
regen->state.walk = 1;
}
if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) // If insignia lvl 1
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
regen->rate.hp *= 2;
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
regen->rate.hp *= 2;
if (sc->data[SC_EXTRACT_WHITE_POTION_Z])
regen->rate.hp += regen->rate.hp * sc->data[SC_EXTRACT_WHITE_POTION_Z]->val1 / 100;
regen->rate.hp += (unsigned short)(regen->rate.hp * sc->data[SC_EXTRACT_WHITE_POTION_Z]->val1 / 100.);
if (sc->data[SC_VITATA_500])
regen->rate.sp += regen->rate.sp * sc->data[SC_VITATA_500]->val1 / 100;
regen->rate.sp += (unsigned short)(regen->rate.sp * sc->data[SC_VITATA_500]->val1 / 100.);
}
/**
@ -12572,10 +12579,11 @@ static int status_natural_heal(struct block_list* bl, va_list args)
struct view_data *vd = NULL;
struct regen_data_sub *sregen;
struct map_session_data *sd;
int val,rate,bonus = 0,flag;
int rate, bonus = 0,flag;
regen = status_get_regen_data(bl);
if (!regen) return 0;
if (!regen)
return 0;
status = status_get_status_data(bl);
sc = status_get_sc(bl);
if (sc && !sc->count)
@ -12584,15 +12592,15 @@ static int status_natural_heal(struct block_list* bl, va_list args)
flag = regen->flag;
if (flag&RGN_HP && (status->hp >= status->max_hp || regen->state.block&1))
flag&=~(RGN_HP|RGN_SHP);
flag &= ~(RGN_HP|RGN_SHP);
if (flag&RGN_SP && (status->sp >= status->max_sp || regen->state.block&2))
flag&=~(RGN_SP|RGN_SSP);
flag &= ~(RGN_SP|RGN_SSP);
if (flag && (
status_isdead(bl) ||
(sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || sc->data[SC__INVISIBILITY]))
))
flag=0;
flag = RGN_NONE;
if (sd) {
if (sd->hp_loss.value || sd->sp_loss.value)
@ -12602,30 +12610,31 @@ static int status_natural_heal(struct block_list* bl, va_list args)
}
if(flag&(RGN_SHP|RGN_SSP) && regen->ssregen &&
(vd = status_get_viewdata(bl)) && vd->dead_sit == 2) { // Apply sitting regen bonus.
(vd = status_get_viewdata(bl)) && vd->dead_sit == 2)
{ // Apply sitting regen bonus.
sregen = regen->ssregen;
if(flag&(RGN_SHP)) { // Sitting HP regen
val = natural_heal_diff_tick * sregen->rate.hp;
rate = (int)(natural_heal_diff_tick * (sregen->rate.hp / 100.));
if (regen->state.overweight)
val>>=1; // Half as fast when overweight.
sregen->tick.hp += val;
rate >>= 1; // Half as fast when overweight.
sregen->tick.hp += rate;
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp) { // Full
flag&=~(RGN_HP|RGN_SHP);
flag &= ~(RGN_HP|RGN_SHP);
break;
}
}
}
if(flag&(RGN_SSP)) { // Sitting SP regen
val = natural_heal_diff_tick * sregen->rate.sp;
rate = (int)(natural_heal_diff_tick * (sregen->rate.sp / 100.));
if (regen->state.overweight)
val>>=1; // Half as fast when overweight.
sregen->tick.sp += val;
rate >>= 1; // Half as fast when overweight.
sregen->tick.sp += rate;
while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
if(status_heal(bl, 0, sregen->sp, 3) < sregen->sp) { // Full
flag&=~(RGN_SP|RGN_SSP);
flag &= ~(RGN_SP|RGN_SSP);
break;
}
}
@ -12633,53 +12642,56 @@ static int status_natural_heal(struct block_list* bl, va_list args)
}
if (flag && regen->state.overweight)
flag=0;
flag = RGN_NONE;
ud = unit_bl2ud(bl);
if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER) {
flag&=~(RGN_SHP|RGN_SSP);
flag &= ~(RGN_SHP|RGN_SSP);
if(!regen->state.walk)
flag&=~RGN_HP;
flag &= ~RGN_HP;
}
if (!flag)
return 0;
if (flag&(RGN_HP|RGN_SP)) {
if(!vd) vd = status_get_viewdata(bl);
if(!vd)
vd = status_get_viewdata(bl);
if(vd && vd->dead_sit == 2)
bonus++;
bonus += 100;
if(regen->state.gc)
bonus++;
bonus += 100;
}
// Natural Hp regen
if (flag&RGN_HP) {
rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
rate = (int)(natural_heal_diff_tick * (regen->rate.hp/100. + bonus/100.));
if (ud && ud->walktimer != INVALID_TIMER)
rate/=2;
rate /= 2;
// Homun HP regen fix (they should regen as if they were sitting (twice as fast)
if(bl->type==BL_HOM) rate *=2;
if(bl->type == BL_HOM)
rate *= 2;
regen->tick.hp += rate;
if(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval) {
val = 0;
int val = 0;
do {
val += regen->hp;
regen->tick.hp -= battle_config.natural_healhp_interval;
} while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
if (status_heal(bl, val, 0, 1) < val)
flag&=~RGN_SHP; // Full.
flag &= ~RGN_SHP; // Full.
}
}
// Natural SP regen
if(flag&RGN_SP) {
rate = natural_heal_diff_tick*(regen->rate.sp+bonus);
rate = (int)(natural_heal_diff_tick * (regen->rate.sp/100. + bonus/100.));
// Homun SP regen fix (they should regen as if they were sitting (twice as fast)
if(bl->type==BL_HOM) rate *=2;
if(bl->type==BL_HOM)
rate *= 2;
#ifdef RENEWAL
if (bl->type == BL_PC && (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
sc && sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK))
@ -12688,13 +12700,13 @@ static int status_natural_heal(struct block_list* bl, va_list args)
regen->tick.sp += rate;
if(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval) {
val = 0;
int val = 0;
do {
val += regen->sp;
regen->tick.sp -= battle_config.natural_healsp_interval;
} while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
if (status_heal(bl, 0, val, 1) < val)
flag&=~RGN_SSP; // full.
flag &= ~RGN_SSP; // full.
}
}
@ -12705,7 +12717,7 @@ static int status_natural_heal(struct block_list* bl, va_list args)
sregen = regen->sregen;
if(flag&RGN_SHP) { // Skill HP regen
sregen->tick.hp += natural_heal_diff_tick * sregen->rate.hp;
sregen->tick.hp += (int)(natural_heal_diff_tick * (sregen->rate.hp / 100.));
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
@ -12714,11 +12726,11 @@ static int status_natural_heal(struct block_list* bl, va_list args)
}
}
if(flag&RGN_SSP) { // Skill SP regen
sregen->tick.sp += natural_heal_diff_tick * sregen->rate.sp;
sregen->tick.sp += (int)(natural_heal_diff_tick * (sregen->rate.sp /100.));
while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
val = sregen->sp;
int val = sregen->sp;
if (sd && sd->state.doridori) {
val*=2;
val *= 2;
sd->state.doridori = 0;
if ((rate = pc_checkskill(sd,TK_SPTIME)))
sc_start(bl,bl,status_skill2sc(TK_SPTIME),

View File

@ -1846,27 +1846,25 @@ struct regen_data_sub {
unsigned int hp,sp;
} tick;
//Regen rates (where every 1 means +100% regen)
//Regen rates. n/100
struct {
unsigned char hp,sp;
unsigned short hp,sp;
} rate;
};
///Regen data
struct regen_data {
unsigned short flag; //Marks what stuff you may heal or not.
unsigned short
hp,sp,shp,ssp;
unsigned char flag; //Marks what stuff you may heal or not.
unsigned short hp,sp,shp,ssp;
//tick accumulation before healing.
struct {
unsigned int hp,sp,shp,ssp;
} tick;
//Regen rates (where every 1 means +100% regen)
//Regen rates. n/100
struct {
unsigned char
hp,sp,shp,ssp;
unsigned short hp, sp, shp, ssp;
} rate;
struct {