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.
This commit is contained in:
aleos89 2015-02-10 12:13:08 -05:00
parent fe3fccee73
commit 083cf5d962
11 changed files with 256 additions and 161 deletions

View File

@ -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 ========================

View File

@ -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

View File

@ -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 ========================

View File

@ -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]
};

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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);