From 083cf5d9626b7aafd9856f406d3f9d2a98e19cbe Mon Sep 17 00:00:00 2001 From: aleos89 Date: Tue, 10 Feb 2015 12:13:08 -0500 Subject: [PATCH] Bug Fixes * Fixed Severe Rainstorm not being able to be copied by Reproduce. (bugreport:9361) * Fixed #137 - Updated Homunculus S Race and Element values to official. * Fixed #163 - Proper renewal calculations for Homunculus. Merge from HerculesWS/Hercules@8faef4f * Fixed #254 - Corrected King's Grace cooldown to be 60 seconds. * +20 Foods cannot be dispelled or removed by death. --- db/pre-re/skill_cast_db.txt | 2 +- db/re/homunculus_db.txt | 10 +- db/re/skill_cast_db.txt | 2 +- src/common/mmo.h | 19 ++- src/map/clif.c | 36 +++-- src/map/homunculus.c | 2 + src/map/homunculus.h | 11 ++ src/map/pc.h | 4 +- src/map/skill.c | 20 +-- src/map/status.c | 299 +++++++++++++++++++++--------------- src/map/status.h | 12 +- 11 files changed, 256 insertions(+), 161 deletions(-) diff --git a/db/pre-re/skill_cast_db.txt b/db/pre-re/skill_cast_db.txt index 873ddaeea8..739114f0c6 100644 --- a/db/pre-re/skill_cast_db.txt +++ b/db/pre-re/skill_cast_db.txt @@ -1410,7 +1410,7 @@ 2325,2000,2000,0,30000:45000:60000:75000:90000,0,540000:480000:420000:360000:300000 //-- LG_KINGS_GRACE -5013,1000,0,0,5000,0,0 +5013,1000,0,0,5000,0,60000 //========================================== //===== Sura Skills ======================== diff --git a/db/re/homunculus_db.txt b/db/re/homunculus_db.txt index 103da634a0..d0be7c5a67 100644 --- a/db/re/homunculus_db.txt +++ b/db/re/homunculus_db.txt @@ -26,8 +26,8 @@ 6006,6014,Amistr,912,60000,0,1,2,0,700,320,10,20,17,35,11,24,12,80,130,1,4,8,20,4,20,4,20,1,10,3,19,3,19,1600,3600,120,360,20,50,10,30,20,50,20,50,10,30,10,30 6007,6015,Filir,910,60000,0,1,2,0,700,90,25,29,35,9,8,30,9,45,75,3,6,4,20,8,20,1,10,3,19,4,20,3,19,1200,3200,200,400,20,50,10,30,20,50,20,50,10,30,10,30 6008,6016,Vanilmirth,911,60000,0,1,0,0,700,80,11,11,11,11,11,11,11,30,150,0,7,1,30,1,30,1,30,1,30,1,30,1,30,1200,4800,480,640,10,30,10,30,10,30,20,50,10,50,10,100 -6048,6048,Eira,6098,60000,1,1,7,0,700,150,40,17,20,15,35,24,12,40,160,20,42,13,39,28,42,15,25,14,48,16,36,9,18,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 -6049,6049,Bayeri,6112,60000,1,1,2,0,700,320,10,20,17,35,11,24,12,90,360,48,52,18,36,8,36,16,32,22,44,12,24,20,36,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 -6050,6050,Sera,6108,60000,1,1,4,0,700,90,25,29,35,9,8,30,9,60,240,36,64,10,25,16,32,5,25,7,35,28,40,20,40,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 -6051,6051,Dieter,6104,60000,1,1,0,0,700,80,11,11,11,11,11,11,11,240,480,40,120,20,40,13,26,18,36,15,40,16,32,4,16,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 -6052,6052,Eleanor,6115,60000,1,1,2,0,700,320,10,20,17,35,11,24,12,60,300,10,20,20,40,10,50,24,48,5,15,12,36,2,10,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 +6048,6048,Eira,6098,60000,1,1,8,4,700,150,40,17,20,15,35,24,12,40,160,20,42,13,39,28,42,15,25,14,48,16,36,9,18,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 +6049,6049,Bayeri,6112,60000,1,1,2,6,700,320,10,20,17,35,11,24,12,90,360,48,52,18,36,8,36,16,32,22,44,12,24,20,36,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 +6050,6050,Sera,6108,60000,1,1,4,2,700,90,25,29,35,9,8,30,9,60,240,36,64,10,25,16,32,5,25,7,35,28,40,20,40,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 +6051,6051,Dieter,6104,60000,1,1,0,3,700,80,11,11,11,11,11,11,11,240,480,40,120,20,40,13,26,18,36,15,40,16,32,4,16,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 +6052,6052,Eleanor,6115,60000,1,1,7,5,700,320,10,20,17,35,11,24,12,60,300,10,20,20,40,10,50,24,48,5,15,12,36,2,10,1000,2000,10,200,1,10,1,10,1,10,1,10,1,10,1,10 diff --git a/db/re/skill_cast_db.txt b/db/re/skill_cast_db.txt index 5e4fd7cb1a..a202cb3ed3 100644 --- a/db/re/skill_cast_db.txt +++ b/db/re/skill_cast_db.txt @@ -1411,7 +1411,7 @@ //-- LG_INSPIRATION 2325,2000,2000,0,30000:45000:60000:75000:90000,0,540000:480000:420000:360000:300000,1000 //-- LG_KINGS_GRACE -5013,1000,0,0,5000,0,0,-1 +5013,1000,0,0,5000,0,60000,-1 //========================================== //===== Sura Skills ======================== diff --git a/src/common/mmo.h b/src/common/mmo.h index 375e86dd5a..b76de1a899 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -317,12 +317,19 @@ struct s_homunculus { //[orn] unsigned int exp; short rename_flag; short vaporize; //albator - int str ; - int agi ; - int vit ; - int int_ ; - int dex ; - int luk ; + int str; + int agi; + int vit; + int int_; + int dex; + int luk; + + int str_value; + int agi_value; + int vit_value; + int int_value; + int dex_value; + int luk_value; char spiritball; //for homun S [lighta] }; diff --git a/src/map/clif.c b/src/map/clif.c index f121a50fbb..9f16c8bc73 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1411,15 +1411,24 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag) WBUFW(buf,29)=hd->homunculus.hunger; WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ; WBUFW(buf,33)=0; // equip id +#ifdef RENEWAL + WBUFW(buf,35)=cap_value(status->rhw.atk2, 0, INT16_MAX); +#else WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, INT16_MAX); +#endif WBUFW(buf,37)=min(status->matk_max, INT16_MAX); //FIXME capping to INT16 here is too late WBUFW(buf,39)=status->hit; if (battle_config.hom_setting&HOMSET_DISPLAY_LUK) WBUFW(buf,41)=status->luk/3 + 1; //crit is a +1 decimal value! Just display purpose.[Vicious] else WBUFW(buf,41)=status->cri/10; - WBUFW(buf,43)=status->def + status->vit ; +#ifdef RENEWAL + WBUFW(buf,43)=status->def + status->def2; + WBUFW(buf,45)=status->mdef + status->mdef2; +#else + WBUFW(buf,43)=status->def + status->vit; WBUFW(buf,45)=status->mdef; +#endif WBUFW(buf,47)=status->flee; WBUFW(buf,49)=(flag)?0:status->amotion; if (status->max_hp > INT16_MAX) { @@ -2904,7 +2913,6 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOL(fd,4)=pc_leftside_matk(sd); break; - case SP_ZENY: WFIFOW(fd,0)=0xb1; WFIFOL(fd,4)=sd->status.zeny; @@ -11257,16 +11265,20 @@ static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_sess if( !hd ) return; - if( skill_isNotOk_hom(skill_id, hd) ) + if( skill_isNotOk_hom(skill_id, hd) ) { + clif_emotion(&hd->bl, E_DOTS); return; + } if( hd->bl.id != target_id && skill_get_inf(skill_id)&INF_SELF_SKILL ) target_id = hd->bl.id; - if( hd->ud.skilltimer != INVALID_TIMER ) - { + if( hd->ud.skilltimer != INVALID_TIMER ) { if( skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST ) return; - } - else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 ) + } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 ) { + clif_emotion(&hd->bl, E_DOTS); + if (hd->master) + clif_skill_fail(hd->master, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0); return; + } lv = hom_checkskill(hd, skill_id); if( skill_lv > lv ) @@ -11280,12 +11292,18 @@ static void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_ses int lv; if( !hd ) return; - if( skill_isNotOk_hom(skill_id, hd) ) + if( skill_isNotOk_hom(skill_id, hd) ) { + clif_emotion(&hd->bl, E_DOTS); return; + } if( hd->ud.skilltimer != INVALID_TIMER ) { if( skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST ) return; - } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 ) + } else if( DIFF_TICK(tick, hd->ud.canact_tick) < 0 ) { + clif_emotion(&hd->bl, E_DOTS); + if (hd->master) + clif_skill_fail(hd->master, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0); return; + } if( hd->sc.data[SC_BASILICA] ) return; diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 2577959fed..1556b66f32 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -471,6 +471,8 @@ int hom_levelup(struct homun_data *hd) hom->int_+= growth_int; hom->luk += growth_luk; + APPLY_HOMUN_LEVEL_STATWEIGHT(); + if ( battle_config.homunculus_show_growth ) { char output[256] ; sprintf(output, diff --git a/src/map/homunculus.h b/src/map/homunculus.h index f764dba5d6..79fddc13fc 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -7,6 +7,17 @@ #include "status.h" // struct status_data, struct status_change #include "unit.h" // struct unit_data +#ifdef RENEWAL + #define HOMUN_LEVEL_STATWEIGHT_VALUE 0 + #define APPLY_HOMUN_LEVEL_STATWEIGHT()( \ + hom->str_value = hom->agi_value = \ + hom->vit_value = hom->int_value = \ + hom->dex_value = hom->luk_value = hom->level / 10 - HOMUN_LEVEL_STATWEIGHT_VALUE \ + ) +#else + #define APPLY_HOMUN_LEVEL_STATWEIGHT() +#endif + struct h_stats { unsigned int HP, SP; unsigned short str, agi, vit, int_, dex, luk; diff --git a/src/map/pc.h b/src/map/pc.h index 3032717c78..908a1d6a75 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -800,8 +800,8 @@ short pc_maxaspd(struct map_session_data *sd); #define pc_rightside_def(sd) ((sd)->battle_status.def) #define pc_leftside_mdef(sd) ((sd)->battle_status.mdef2) #define pc_rightside_mdef(sd) ((sd)->battle_status.mdef) -#define pc_leftside_matk(sd) (status_base_matk(status_get_status_data(&(sd)->bl), (sd)->status.base_level)) -#define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk) + #define pc_leftside_matk(sd) (status_base_matk(&(sd)->bl, status_get_status_data(&(sd)->bl), (sd)->status.base_level)) + #define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk) #else #define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk) #define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2) diff --git a/src/map/skill.c b/src/map/skill.c index fad7c7b6a7..4877881638 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -420,7 +420,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk struct status_data *status = status_get_status_data(src); int min, max; - min = max = status_base_matk(status, status_get_lv(src)); + min = max = status_base_matk(src, status, status_get_lv(src)); if( status->rhw.matk > 0 ){ int wMatk, variance; wMatk = status->rhw.matk; @@ -1631,8 +1631,8 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: case SC_SEVENWIND: case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: case SC_INCHEALRATE: case SC_ELECTRICSHOCKER: case SC__STRIPACCESSORY: - //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ: - //case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: + case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ: + case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD: case SC_GIANTGROWTH: case SC_MILLENNIUMSHIELD: case SC_REFRESH: case SC_STONEHARDSKIN: case SC_VITALITYACTIVATION: @@ -3138,7 +3138,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list * dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5); break; case WM_SEVERE_RAINSTORM_MELEE: - dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,6); + dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,5); break; case WM_REVERBERATION_MELEE: case WM_REVERBERATION_MAGIC: @@ -7347,8 +7347,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: case SC_SEVENWIND: case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: case SC_INCHEALRATE: case SC_ELECTRICSHOCKER: case SC__STRIPACCESSORY: - //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ: - //case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: + case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ: + case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD: case SC_GIANTGROWTH: case SC_MILLENNIUMSHIELD: case SC_REFRESH: case SC_STONEHARDSKIN: case SC_VITALITYACTIVATION: @@ -8828,9 +8828,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_FOOD_LUK_CASH: case SC_ELECTRICSHOCKER: case SC_BITE: case SC__STRIPACCESSORY: case SC__ENERVATION: case SC__GROOMY: case SC__IGNORANCE: case SC__LAZINESS: case SC__UNLUCKY: - case SC__WEAKNESS: //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: - case SC_MAGNETICFIELD://case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA: - //case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: + case SC__WEAKNESS: case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: + case SC_MAGNETICFIELD: case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA: + case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD: case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD: @@ -10120,7 +10120,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { int heal = 5 * status_get_lv(&hd->bl) + #ifdef RENEWAL - status_base_matk(&hd->battle_status, status_get_lv(&hd->bl)); + status_base_matk(bl, &hd->battle_status, status_get_lv(&hd->bl)); #else status_base_matk_min(&hd->battle_status); #endif diff --git a/src/map/status.c b/src/map/status.c index bc3eb34d21..4a79555e06 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2078,7 +2078,7 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat * @return base attack * Note: Function only calculates Homunculus bATK in RENEWAL */ -static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status) +unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status) { int flag = 0, str, dex, #ifdef RENEWAL @@ -2086,7 +2086,6 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct #endif dstr; - if(!(bl->type&battle_config.enable_baseatk)) return 0; @@ -2121,7 +2120,7 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct **/ #ifdef RENEWAL if (bl->type == BL_HOM) - str = (int)(floor((rstr + dex + status->luk) / 3) + floor(((TBL_HOM*)bl)->homunculus.level / 10)); + str = 2 * ((((TBL_HOM*)bl)->homunculus.level) + status_get_homstr(bl)); #endif dstr = str/10; str += dstr*dstr; @@ -2155,10 +2154,25 @@ unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status) #ifndef RENEWAL unsigned short status_base_matk_min(const struct status_data* status) { return status->int_ + (status->int_ / 7) * (status->int_ / 7); } unsigned short status_base_matk_max(const struct status_data* status) { return status->int_ + (status->int_ / 5) * (status->int_ / 5); } -#else - unsigned short status_base_matk(const struct status_data* status, int level) { return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4); } #endif +unsigned short status_base_matk(struct block_list *bl, const struct status_data* status, int level) +{ +#ifdef RENEWAL + switch (bl->type) { + case BL_MOB: + return status->int_ + level; + case BL_HOM: + return status_get_homint(bl) + level; + case BL_PC: + default: + return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4); + } +#else + return 0; +#endif +} + /** * Fills in the misc data that can be calculated from the other status info (except for level) * @param bl: Object to calculate status on [PC|MOB|PET|HOM|MERC|ELEM] @@ -2175,73 +2189,84 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev status->cri = status->flee2 = 0; #ifdef RENEWAL // Renewal formulas - if (bl->type == BL_MOB) { - //Hit - stat = status->hit; - stat += level + status->dex + 175; - status->hit = cap_value(stat,1,SHRT_MAX); - //Flee - stat = status->flee; - stat += level + status->agi + 100; - status->flee = cap_value(stat,1,SHRT_MAX); - } else if (bl->type == BL_HOM) { - status->hit = cap_value(level + status->dex + 150,1,SHRT_MAX); // base level + dex + 150 - status->flee = cap_value(level + status->agi + level/10,1,SHRT_MAX); // base level + agi + base level/10 + if (bl->type == BL_HOM) { + // Def2 + stat = status_get_homvit(bl) + status_get_homagi(bl) / 2; + status->def2 = cap_value(stat, 0, SHRT_MAX); + // Mdef2 + stat = (status_get_homvit(bl) + status_get_homint(bl)) / 2; + status->mdef2 = cap_value(stat, 0, SHRT_MAX); + // Def + stat = status->def; + stat += status_get_homvit(bl) + level / 2; + status->def = cap_value(stat, 0, SHRT_MAX); + // Mdef + stat = (int)(((float)status_get_homvit(bl) + level) / 4 + (float)status_get_homint(bl) / 2); + status->mdef = cap_value(stat, 0, SHRT_MAX); + // Hit + stat = level + status->dex + 150; + status->hit = cap_value(stat, 1, SHRT_MAX); + // Flee + stat = level + status_get_homagi(bl); + status->flee = cap_value(stat, 1, SHRT_MAX); + // Atk + stat = (status_get_homstr(bl) + status_get_homdex(bl)) / 5; + status->rhw.atk = cap_value(stat, 0, SHRT_MAX); + // Atk2 + stat = (status_get_homluk(bl) + status_get_homstr(bl) + status_get_homdex(bl)) / 3; + status->rhw.atk2 = cap_value(stat, 0, SHRT_MAX); } else { - //Hit + // Hit stat = status->hit; - stat += level + status->dex + status->luk/3 + 175; // base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175 - status->hit = cap_value(stat,1,SHRT_MAX); - //Flee + stat += level + status->dex + (bl->type == BL_PC ? status->luk / 3 + 175 : 150); //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175 + status->hit = cap_value(stat, 1, SHRT_MAX); + // Flee stat = status->flee; - stat += level + status->agi + status->luk/5 + 100; // base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100 - status->flee = cap_value(stat,1,SHRT_MAX); + stat += level + status->agi + (bl->type == BL_PC ? status->luk / 5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100 + status->flee = cap_value(stat, 1, SHRT_MAX); + // Def2 + stat = status->def2; + stat += (int)(((float)level + status->vit) / 2 + (bl->type == BL_PC ? ((float)status->agi / 5) : 0)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def) + status->def2 = cap_value(stat, 0, SHRT_MAX); + // Mdef2 + stat = status->mdef2; + stat += (int)(bl->type == BL_PC ? (status->int_ + ((float)level / 4) + ((float)(status->dex + status->vit) / 5)) : ((float)(status->int_ + level) / 4)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef) + status->mdef2 = cap_value(stat, 0, SHRT_MAX); } - status->matk_min = status->matk_max = status_base_matk(status, level); - //Def2 - stat = status->def2; - stat += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); // base level + (every 2 vit = +1 def) + (every 5 agi = +1 def) - status->def2 = cap_value(stat,0,SHRT_MAX); - //MDef2 - stat = status->mdef2; - stat += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); // (every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef) - status->mdef2 = cap_value(stat,0,SHRT_MAX); #else status->matk_min = status_base_matk_min(status); status->matk_max = status_base_matk_max(status); - //Hit + // Hit stat = status->hit; stat += level + status->dex; - status->hit = cap_value(stat,1,SHRT_MAX); - //Flee + status->hit = cap_value(stat, 1, SHRT_MAX); + // Flee stat = status->flee; stat += level + status->agi; - status->flee = cap_value(stat,1,SHRT_MAX); - //Def2 + status->flee = cap_value(stat, 1, SHRT_MAX); + // Def2 stat = status->def2; stat += status->vit; - status->def2 = cap_value(stat,0,SHRT_MAX); - //MDef2 + status->def2 = cap_value(stat, 0, SHRT_MAX); + // Mdef2 stat = status->mdef2; stat += status->int_ + (status->vit>>1); - status->mdef2 = cap_value(stat,0,SHRT_MAX); + status->mdef2 = cap_value(stat, 0, SHRT_MAX); #endif //Critical if( bl->type&battle_config.enable_critical ) { stat = status->cri; stat += 10 + (status->luk*10/3); // (every 1 luk = +0.3 critical) - status->cri = cap_value(stat,1,SHRT_MAX); - } - else + status->cri = cap_value(stat, 1, SHRT_MAX); + } else status->cri = 0; if (bl->type&battle_config.enable_perfect_flee) { stat = status->flee2; stat += status->luk + 10; // (every 10 luk = +1 perfect flee) - status->flee2 = cap_value(stat,0,SHRT_MAX); - } - else + status->flee2 = cap_value(stat, 0, SHRT_MAX); + } else status->flee2 = 0; if (status->batk) { @@ -2249,22 +2274,24 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev status->batk = cap_value(temp, 0, USHRT_MAX); } else status->batk = status_base_atk(bl, status); - if (status->cri) - switch (bl->type) { - case BL_MOB: - if(battle_config.mob_critical_rate != 100) - status->cri = cap_value(status->cri*battle_config.mob_critical_rate/100,1,SHRT_MAX); - if(!status->cri && battle_config.mob_critical_rate) - status->cri = 10; - break; - case BL_PC: - // Players don't have a critical adjustment setting as of yet. - break; - default: - if(battle_config.critical_rate != 100) - status->cri = cap_value(status->cri*battle_config.critical_rate/100,1,SHRT_MAX); - if (!status->cri && battle_config.critical_rate) - status->cri = 10; + + if (status->cri) { + switch (bl->type) { + case BL_MOB: + if(battle_config.mob_critical_rate != 100) + status->cri = cap_value(status->cri*battle_config.mob_critical_rate/100,1,SHRT_MAX); + if(!status->cri && battle_config.mob_critical_rate) + status->cri = 10; + break; + case BL_PC: + // Players don't have a critical adjustment setting as of yet. + break; + default: + if(battle_config.critical_rate != 100) + status->cri = cap_value(status->cri*battle_config.critical_rate/100,1,SHRT_MAX); + if (!status->cri && battle_config.critical_rate) + status->cri = 10; + } } if(bl->type&BL_REGEN) status_calc_regen(bl, status, status_get_regen_data(bl)); @@ -3651,7 +3678,7 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) { struct status_data *status = &hd->base_status; struct s_homunculus *hom = &hd->homunculus; - int skill; + int skill_lv; int amotion; status->str = hom->str / 10; @@ -3661,13 +3688,15 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) status->int_ = hom->int_ / 10; status->luk = hom->luk / 10; + APPLY_HOMUN_LEVEL_STATWEIGHT(); + if (opt&SCO_FIRST) { const struct s_homunculus_db *db = hd->homunculusDB; - status->def_ele = db->element; + status->def_ele = db->element; status->ele_lv = 1; status->race = db->race; status->class_ = CLASS_NORMAL; - status->size = (hom->class_ == db->evo_class)?db->evo_size:db->base_size; + status->size = (hom->class_ == db->evo_class) ? db->evo_size : db->base_size; status->rhw.range = 1 + status->size; status->mode = MD_CANMOVE|MD_CANATTACK; status->speed = DEFAULT_WALK_SPEED; @@ -3681,45 +3710,43 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) status->aspd_rate = 1000; #ifdef RENEWAL - status->def = (status->vit + (hom->level / 10)) + ((status->agi + (hom->level / 10)) / 2); - status->mdef = status->int_ + ((status->int_ + status->dex + status->luk) / 3) + (hom->level / 10) * 2; - - amotion = (1000 -2*status->agi -status->dex) * hd->homunculusDB->baseASPD/1000; + amotion = hd->homunculusDB->baseASPD; + amotion = amotion - amotion * (status->dex + hom->dex_value) / 1000 - (status->agi + hom->agi_value) * amotion / 250; #else - skill = hom->level/10 + status->vit/5; - status->def = cap_value(skill, 0, 99); + skill_lv = hom->level / 10 + status->vit / 5; + status->def = cap_value(skill_lv, 0, 99); - skill = hom->level/10 + status->int_/5; - status->mdef = cap_value(skill, 0, 99); + skill_lv = hom->level / 10 + status->int_ / 5; + status->mdef = cap_value(skill_lv, 0, 99); - amotion = (1000 -4*status->agi -status->dex) * hd->homunculusDB->baseASPD/1000; + amotion = (1000 - 4 * status->agi - status->dex) * hd->homunculusDB->baseASPD / 1000; #endif - status->amotion = cap_value(amotion,battle_config.max_aspd,2000); - status->adelay = status->amotion; /// It seems adelay = amotion for Homunculus. + status->amotion = cap_value(amotion, battle_config.max_aspd, 2000); + status->adelay = status->amotion; //It seems adelay = amotion for Homunculus. - status->max_hp = hom->max_hp ; - status->max_sp = hom->max_sp ; + status->max_hp = hom->max_hp; + status->max_sp = hom->max_sp; hom_calc_skilltree(hd, 0); - if((skill=hom_checkskill(hd,HAMI_SKIN)) > 0) - status->def += skill * 4; + if((skill_lv = hom_checkskill(hd, HAMI_SKIN)) > 0) + status->def += skill_lv * 4; - if((skill = hom_checkskill(hd,HVAN_INSTRUCT)) > 0) { - status->int_ += 1 +skill/2 +skill/4 +skill/5; - status->str += 1 +skill/3 +skill/3 +skill/4; + if((skill_lv = hom_checkskill(hd, HVAN_INSTRUCT)) > 0) { + status->int_ += 1 + skill_lv / 2 + skill_lv / 4 + skill_lv / 5; + status->str += 1 + skill_lv / 3 + skill_lv / 3 + skill_lv / 4; } - if((skill=hom_checkskill(hd,HAMI_SKIN)) > 0) - status->max_hp += skill * 2 * status->max_hp / 100; + if((skill_lv = hom_checkskill(hd, HAMI_SKIN)) > 0) + status->max_hp += skill_lv * 2 * status->max_hp / 100; - if((skill = hom_checkskill(hd,HLIF_BRAIN)) > 0) - status->max_sp += (1 +skill/2 -skill/4 +skill/5) * status->max_sp / 100 ; + if((skill_lv = hom_checkskill(hd, HLIF_BRAIN)) > 0) + status->max_sp += (1 + skill_lv / 2 - skill_lv / 4 + skill_lv / 5) * status->max_sp / 100; if (opt&SCO_FIRST) { - hd->battle_status.hp = hom->hp ; - hd->battle_status.sp = hom->sp ; + hd->battle_status.hp = hom->hp; + hd->battle_status.sp = hom->sp; if(hom->class_ == 6052) // Eleanor sc_start(&hd->bl,&hd->bl, SC_STYLE_CHANGE, 100, MH_MD_FIGHTING, -1); } @@ -3731,10 +3758,6 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) status_calc_misc(&hd->bl, status, hom->level); -#ifdef RENEWAL - status->matk_max = status->matk_min; -#endif - status_cpy(&hd->battle_status, status); return 1; } @@ -4409,13 +4432,14 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) * RE MATK Formula (from irowiki:http:// irowiki.org/wiki/MATK) * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers **/ - status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl)); - if( bl->type&BL_PC ) { + status->matk_min = status->matk_max = status_base_matk(bl, status, status_get_lv(bl)); + switch( bl->type ) { + case BL_PC: { int wMatk = 0; int variance = 0; // Any +MATK you get from skills and cards, including cards in weapon, is added here. - if( sd->bonus.ematk > 0 ) { + if (sd->bonus.ematk > 0) { status->matk_max += sd->bonus.ematk; status->matk_min += sd->bonus.ematk; } @@ -4423,7 +4447,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) status->matk_max = status_calc_ematk(bl, sc, status->matk_max); // This is the only portion in MATK that varies depending on the weapon level and refinement rate. - if(b_status->lhw.matk) { + if (b_status->lhw.matk) { if (sd) { //sd->state.lr_flag = 1; //?? why was that set here status->lhw.matk = b_status->lhw.matk; @@ -4433,22 +4457,44 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) } } - if(b_status->rhw.matk) { + if (b_status->rhw.matk) { status->rhw.matk = b_status->rhw.matk; } - if(status->rhw.matk) { + if (status->rhw.matk) { wMatk += status->rhw.matk; variance += wMatk * status->rhw.wlv / 10; } - if(status->lhw.matk) { + if (status->lhw.matk) { wMatk += status->lhw.matk; variance += status->lhw.matk * status->lhw.wlv / 10; } status->matk_min += wMatk - variance; status->matk_max += wMatk + variance; + } + break; + + case BL_HOM: + if ((bl->type&BL_HOM && battle_config.hom_setting&HOMSET_SAME_MATK) /// Hom Min Matk is always the same as Max Matk + || (sc && sc->data[SC_RECOGNIZEDSPELL])) + status->matk_min = status->matk_max; + else + status->matk_min += (status_get_homint(bl) + status_get_homdex(bl)) / 5; + + status->matk_max += (status_get_homluk(bl) + status_get_homint(bl) + status_get_homdex(bl)) / 3; + break; + + case BL_MOB: + status->matk_min += 70 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100; + status->matk_max += 130 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100; + break; + + default: + status->matk_max = status_calc_matk(bl, sc, status->matk_max); + status->matk_min = status_calc_matk(bl, sc, status->matk_min); + break; } #endif if (bl->type&BL_PC && sd->matk_rate != 100) { @@ -4456,15 +4502,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) status->matk_min = status->matk_min * sd->matk_rate/100; } - - status->matk_max = status_calc_matk(bl, sc, status->matk_max); - - if ((bl->type&BL_HOM && battle_config.hom_setting&HOMSET_SAME_MATK) /// Hom Min Matk is always the same as Max Matk - || (sc && sc->data[SC_RECOGNIZEDSPELL])) - status->matk_min = status->matk_max; - else - status->matk_min = status_calc_matk(bl, sc, status->matk_min); - #ifdef RENEWAL if( sd && sd->right_weapon.overrefine > 0) { status->matk_min++; @@ -4475,7 +4512,25 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) if(flag&SCB_ASPD) { int amotion; - if( bl->type&BL_PC ) { + if ( bl->type&BL_HOM ) { +#ifdef RENEWAL + amotion = ((TBL_HOM*)bl)->homunculusDB->baseASPD; + amotion = amotion - amotion * status_get_homdex(bl) / 1000 - status_get_homagi(bl) * amotion / 250; + amotion = (amotion * status_calc_aspd(bl, sc, 1) + status_calc_aspd(bl, sc, 2)) / - 100 + amotion; +#else + amotion = (1000 - 4 * status->agi - status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD / 1000; + + amotion = status_calc_aspd_rate(bl, sc, b_status->aspd_rate); + + if (status->aspd_rate != 1000) + amotion = amotion * status->aspd_rate / 1000; +#endif + + amotion = status_calc_fix_aspd(bl, sc, amotion); + status->amotion = cap_value(amotion, battle_config.max_aspd, 2000); + + status->adelay = status->amotion; + } else if ( bl->type&BL_PC ) { amotion = status_base_amotion_pc(sd,status); #ifndef RENEWAL_ASPD status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate); @@ -4497,21 +4552,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) status->amotion = cap_value(amotion,pc_maxaspd(sd),2000); status->adelay = 2*status->amotion; - } else if( bl->type&BL_HOM ) { -#ifdef RENEWAL - amotion = (1000 -2*status->agi -status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000; -#else - amotion = (1000 -4*status->agi -status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000; -#endif - status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate); - - if(status->aspd_rate != 1000) - amotion = amotion*status->aspd_rate/1000; - - amotion = status_calc_fix_aspd(bl, sc, amotion); - status->amotion = cap_value(amotion,battle_config.max_aspd,2000); - - status->adelay = status->amotion; } else { // Mercenary and mobs amotion = b_status->amotion; status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate); @@ -4544,8 +4584,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) dmotion = 800-status->agi*4; status->dmotion = cap_value(dmotion, 400, 800); status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion); - } else // Mercenary and mobs + } else { // Mercenary and mobs status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion); + } } if(flag&(SCB_VIT|SCB_MAXHP|SCB_INT|SCB_MAXSP) && bl->type&BL_REGEN) @@ -10457,6 +10498,12 @@ int status_change_clear(struct block_list* bl, int type) case SC_FOOD_DEX_CASH: case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: + case SC_SAVAGE_STEAK: + case SC_COCKTAIL_WARG_BLOOD: + case SC_MINOR_BBQ: + case SC_SIROMA_ICE_TEA: + case SC_DROCERA_HERB_STEAMED: + case SC_PUTTI_TAILS_NOODLES: case SC_DEF_RATE: case SC_MDEF_RATE: case SC_INCHEALRATE: diff --git a/src/map/status.h b/src/map/status.h index 0a986796f2..b0242674f8 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1992,6 +1992,14 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch #define status_get_class_(bl) status_get_status_data(bl)->class_ #define status_get_size(bl) status_get_status_data(bl)->size #define status_get_mode(bl) status_get_status_data(bl)->mode + +#define status_get_homstr(bl) (status->str + ((TBL_HOM*)bl)->homunculus.str_value) +#define status_get_homagi(bl) (status->agi + ((TBL_HOM*)bl)->homunculus.agi_value) +#define status_get_homvit(bl) (status->vit + ((TBL_HOM*)bl)->homunculus.vit_value) +#define status_get_homint(bl) (status->int_ + ((TBL_HOM*)bl)->homunculus.int_value) +#define status_get_homdex(bl) (status->dex + ((TBL_HOM*)bl)->homunculus.dex_value) +#define status_get_homluk(bl) (status->luk + ((TBL_HOM*)bl)->homunculus.luk_value) + int status_get_party_id(struct block_list *bl); int status_get_guild_id(struct block_list *bl); int status_get_emblem_id(struct block_list *bl); @@ -2052,9 +2060,11 @@ int status_change_spread( struct block_list *src, struct block_list *bl ); unsigned short status_base_matk_max(const struct status_data* status); #else unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status); - unsigned short status_base_matk(const struct status_data* status, int level); #endif +unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status); +unsigned short status_base_matk(struct block_list *bl, const struct status_data* status, int level); + int status_readdb(void); int do_init_status(void); void do_final_status(void);