summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c617
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/clif.c8
-rw-r--r--src/map/map.h6
-rw-r--r--src/map/pc.c12
-rw-r--r--src/map/pc.h6
-rw-r--r--src/map/skill.c60
-rw-r--r--src/map/status.c154
-rw-r--r--src/map/status.h21
9 files changed, 483 insertions, 402 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 07f3b1359..21649228b 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -418,6 +418,316 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
}
return damage*ratio/100;
}
+/*==========================================
+ * Calculates card bonuses damage adjustments.
+ *------------------------------------------*/
+int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int left, int flag){
+ struct map_session_data *sd, *tsd;
+ short cardfix = 1000, t_class, s_class, s_race2, t_race2;
+ struct status_data *sstatus, *tstatus;
+ int i;
+
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
+ t_class = status_get_class(target);
+ s_class = status_get_class(src);
+ sstatus = status_get_status_data(src);
+ tstatus = status_get_status_data(target);
+ s_race2 = status_get_race2(src);
+ t_race2 = status_get_race2(target);
+
+ if( !damage )
+ return 0;
+
+ switch(attack_type){
+ case BF_MAGIC:
+ if ( sd && !(nk&NK_NO_CARDFIX_ATK) ) {
+ cardfix=cardfix*(100+sd->magic_addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX))
+ cardfix=cardfix*(100+sd->magic_addele[tstatus->def_ele])/100;
+ cardfix=cardfix*(100+sd->magic_addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ for(i=0; i< ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate;i++) {
+ if(sd->add_mdmg[i].class_ == t_class) {
+ cardfix=cardfix*(100+sd->add_mdmg[i].rate)/100;
+ continue;
+ }
+ }
+ if (cardfix != 1000)
+ damage = damage * cardfix / 1000;
+ }
+
+ if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
+ { // Target cards.
+ if (!(nk&NK_NO_ELEFIX))
+ {
+ int ele_fix = tsd->subele[s_ele];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ }
+ cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
+ cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+ cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+ if( sstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+
+ for(i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate;i++) {
+ if(tsd->add_mdef[i].class_ == s_class) {
+ cardfix=cardfix*(100-tsd->add_mdef[i].rate)/100;
+ break;
+ }
+ }
+ //It was discovered that ranged defense also counts vs magic! [Skotlex]
+ if ( flag&BF_SHORT )
+ cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+ else
+ cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+
+ cardfix = cardfix * ( 100 - tsd->bonus.magic_def_rate ) / 100;
+
+ if( tsd->sc.data[SC_MDEF_RATE] )
+ cardfix = cardfix * ( 100 - tsd->sc.data[SC_MDEF_RATE]->val1 ) / 100;
+
+ if (cardfix != 1000)
+ damage = damage * cardfix / 1000;
+ }
+ break;
+ case BF_WEAPON:
+ if( sd && !(nk&NK_NO_CARDFIX_ATK) )
+ {
+ short cardfix_ = 1000;
+ if(sd->state.arrow_atk)
+ {
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX))
+ {
+ int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->right_weapon.addele2[i].rate;
+ }
+ cardfix=cardfix*(100+ele_fix)/100;
+ }
+ cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN])/100;
+ }
+ else
+ { // Melee attack
+ if( !battle_config.left_cardfix_to_right )
+ {
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX)) {
+ int ele_fix = sd->right_weapon.addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->right_weapon.addele2[i].rate;
+ }
+ cardfix=cardfix*(100+ele_fix)/100;
+ }
+ cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN])/100;
+
+ if( left )
+ {
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
+ if (!(nk&NK_NO_ELEFIX)) {
+ int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
+ if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->left_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
+ sd->left_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
+ sd->left_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix_lh += sd->left_weapon.addele2[i].rate;
+ }
+ cardfix=cardfix*(100+ele_fix_lh)/100;
+ }
+ cardfix_=cardfix_*(100+sd->left_weapon.addsize[tstatus->size])/100;
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace2[t_race2])/100;
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
+ }
+ }
+ else
+ {
+ int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->right_weapon.addele2[i].rate;
+ }
+ for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
+ if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
+ if(!(sd->left_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
+ sd->left_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
+ sd->left_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += sd->left_weapon.addele2[i].rate;
+ }
+
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->left_weapon.addrace[tstatus->race])/100;
+ cardfix=cardfix*(100+ele_fix)/100;
+ cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->left_weapon.addsize[tstatus->size])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2]+sd->left_weapon.addrace2[t_race2])/100;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
+ if( tstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
+ }
+ }
+ for( i = 0; i < ARRAYLENGTH(sd->right_weapon.add_dmg) && sd->right_weapon.add_dmg[i].rate; i++ )
+ {
+ if( sd->right_weapon.add_dmg[i].class_ == t_class )
+ {
+ cardfix=cardfix*(100+sd->right_weapon.add_dmg[i].rate)/100;
+ break;
+ }
+ }
+
+ if( left )
+ {
+ for( i = 0; i < ARRAYLENGTH(sd->left_weapon.add_dmg) && sd->left_weapon.add_dmg[i].rate; i++ )
+ {
+ if( sd->left_weapon.add_dmg[i].class_ == t_class )
+ {
+ cardfix_=cardfix_*(100+sd->left_weapon.add_dmg[i].rate)/100;
+ break;
+ }
+ }
+ }
+
+ if( flag&BF_LONG )
+ cardfix = cardfix * ( 100 + sd->bonus.long_attack_atk_rate ) / 100;
+#ifdef RENEWAL_EDP
+ if( sd->sc.data[SC_EDP] ){
+ cardfix = cardfix * (100 + sd->sc.data[SC_EDP]->val1 * 60 ) / 100;
+ cardfix_ = cardfix_ * (100 + sd->sc.data[SC_EDP]->val1 * 60 ) / 100;
+ }
+#endif
+ if( left && cardfix_ != 1000 )
+ damage = damage * cardfix_ / 1000;
+ else if( cardfix != 1000 )
+ damage = damage * cardfix / 1000;
+
+ }else if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
+ if( !(nk&NK_NO_ELEFIX) )
+ {
+ int ele_fix = tsd->subele[s_ele];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ if( left && s_ele_ != s_ele )
+ {
+ int ele_fix_lh = tsd->subele[s_ele_];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele_) continue;
+ if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix_lh += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix_lh)/100;
+ }
+ }
+ cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
+ cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+ cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+ if( sstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+
+ for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ) {
+ if( tsd->add_def[i].class_ == s_class ) {
+ cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
+ break;
+ }
+ }
+
+ if( flag&BF_SHORT )
+ cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+ else // BF_LONG (there's no other choice)
+ cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+
+ if( tsd->sc.data[SC_DEF_RATE] )
+ cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
+
+ if( cardfix != 1000 )
+ damage = damage * cardfix / 1000;
+ }
+ break;
+ case BF_MISC:
+ if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
+ // misc damage reduction from equipment
+ if (!(nk&NK_NO_ELEFIX))
+ {
+ int ele_fix = tsd->subele[s_ele];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&flag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ continue;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ }
+ cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
+ cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+ cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+ if( sstatus->race != RC_DEMIHUMAN )
+ cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+
+ cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
+ if( flag&BF_SHORT )
+ cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+ else // BF_LONG (there's no other choice)
+ cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+
+ if (cardfix != 10000)
+ damage = (int)( (int64)damage * cardfix / 1000);
+ }
+ break;
+ }
+
+ return damage;
+}
/*==========================================
* Check dammage trough status.
@@ -3001,126 +3311,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
//Card Fix, sd side
- if ((wd.damage || wd.damage2) && !(nk&NK_NO_CARDFIX_ATK)) {
- int cardfix = 1000, cardfix_ = 1000;
- int t_race2 = status_get_race2(target);
- if (sd->state.arrow_atk) {
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
- if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if (!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->right_weapon.addele2[i].rate;
- }
- cardfix=cardfix*(100+ele_fix)/100;
- }
- cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if (tstatus->race != RC_DEMIHUMAN)
- cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN])/100;
- } else {
- // Melee attack
- if (!battle_config.left_cardfix_to_right) {
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix = sd->right_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
- if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if (!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->right_weapon.addele2[i].rate;
- }
- cardfix=cardfix*(100+ele_fix)/100;
- }
- cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if (tstatus->race != RC_DEMIHUMAN)
- cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN])/100;
-
- if (flag.lh) {
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
- if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if (!(sd->left_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
- sd->left_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
- sd->left_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix_lh += sd->left_weapon.addele2[i].rate;
- }
- cardfix=cardfix*(100+ele_fix_lh)/100;
- }
- cardfix_=cardfix_*(100+sd->left_weapon.addsize[tstatus->size])/100;
- cardfix_=cardfix_*(100+sd->left_weapon.addrace2[t_race2])/100;
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if (tstatus->race != RC_DEMIHUMAN)
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
- }
- } else {
- int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
- if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if (!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->right_weapon.addele2[i].rate;
- }
- for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
- if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if (!(sd->left_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK &&
- sd->left_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK &&
- sd->left_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix += sd->left_weapon.addele2[i].rate;
- }
-
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->left_weapon.addrace[tstatus->race])/100;
- cardfix=cardfix*(100+ele_fix)/100;
- cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->left_weapon.addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2]+sd->left_weapon.addrace2[t_race2])/100;
- cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- if (tstatus->race != RC_DEMIHUMAN)
- cardfix=cardfix*(100+sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
- }
- }
-
- for (i = 0; i < ARRAYLENGTH(sd->right_weapon.add_dmg) && sd->right_weapon.add_dmg[i].rate; i++) {
- if (sd->right_weapon.add_dmg[i].class_ == t_class) {
- cardfix=cardfix*(100+sd->right_weapon.add_dmg[i].rate)/100;
- break;
- }
- }
-
- if (flag.lh) {
- for (i = 0; i < ARRAYLENGTH(sd->left_weapon.add_dmg) && sd->left_weapon.add_dmg[i].rate; i++) {
- if (sd->left_weapon.add_dmg[i].class_ == t_class) {
- cardfix_=cardfix_*(100+sd->left_weapon.add_dmg[i].rate)/100;
- break;
- }
- }
- }
-
- if (wd.flag&BF_LONG)
- cardfix = cardfix * (100 + sd->bonus.long_attack_atk_rate) / 100;
-#ifdef RENEWAL_EDP
- if (sc && sc->data[SC_EDP]) {
- cardfix = cardfix * (100 + sc->data[SC_EDP]->val1 * 60) / 100;
- cardfix_ = cardfix_ * (100 + sc->data[SC_EDP]->val1 * 60) / 100;
- }
-#endif
- if (cardfix != 1000 || cardfix_ != 1000)
- ATK_RATE2(cardfix/10, cardfix_/10); //What happens if you use right-to-left and there's no right weapon, only left?
- }
+ wd.damage = battle_calc_cardfix(BF_WEAPON, src, (tsd?NULL:target), nk, s_ele, s_ele_, wd.damage, 0, wd.flag);
+ if( flag.lh )
+ wd.damage2 = battle_calc_cardfix(BF_WEAPON, src, (tsd?NULL:target), nk, s_ele, s_ele_, wd.damage2, 1, wd.flag);
if (skill_num == CR_SHIELDBOOMERANG || skill_num == PA_SHIELDCHAIN) {
//Refine bonus applies after cards and elements.
@@ -3131,62 +3324,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
} //if (sd)
//Card Fix, tsd sid
- if (tsd && !(nk &NK_NO_CARDFIX_DEF)) {
- short s_race2,s_class;
- short cardfix=1000;
-
- s_race2 = status_get_race2(src);
- s_class = status_get_class(src);
-
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) {
- if (tsd->subele2[i].ele != s_ele) continue;
- if (!(tsd->subele2[i].flag&wd.flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&wd.flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- if (flag.lh && s_ele_ != s_ele) {
- int ele_fix_lh = tsd->subele[s_ele_];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) {
- if (tsd->subele2[i].ele != s_ele_) continue;
- if (!(tsd->subele2[i].flag&wd.flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&wd.flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&wd.flag&BF_SKILLMASK))
- continue;
- ele_fix_lh += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix_lh)/100;
- }
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
- cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
- cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
- if (sstatus->race != RC_DEMIHUMAN)
- cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
-
- for (i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate; i++) {
- if (tsd->add_def[i].class_ == s_class) {
- cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
- break;
- }
- }
-
- if (wd.flag&BF_SHORT)
- cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
- else // BF_LONG (there's no other choice)
- cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
-
- if (tsd->sc.data[SC_DEF_RATE])
- cardfix = cardfix * (100 - tsd->sc.data[SC_DEF_RATE]->val1) / 100;
-
- if (cardfix != 1000)
- ATK_RATE(cardfix / 10);
- }
+ if(tsd)
+ wd.damage = battle_calc_cardfix(BF_WEAPON, (sd?NULL:src), target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
if (flag.infdef) {
//Plants receive 1 damage when hit
@@ -3350,7 +3489,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
return ad;
}
//Initial Values
- ad.damage = 1;
ad.div_=skill_get_num(skill_num,skill_lv);
ad.amotion=skill_get_inf(skill_num) &INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
ad.dmotion=tstatus->dmotion;
@@ -3464,7 +3602,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
ad.damage = tstatus->hp;
else {
#ifdef RENEWAL
- ad.damage = skill_lv * (sstatus->matk_min + sstatus->matk_max);
+ if (sstatus->matk_max > sstatus->matk_min) {
+ MATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
+ } else {
+ MATK_ADD(sstatus->matk_min);
+ }
+ MATK_RATE(skill_lv);
#else
ad.damage = status_get_lv(src) + sstatus->int_ + skill_lv * 10;
#endif
@@ -3481,22 +3624,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
ad.damage = (int)((15 * status_get_lv(src)) + (1.5 * sstatus->int_));
break;
default: {
-#ifdef RENEWAL //Renewal MATK Appliance according to doddler (?title=Renewal_Changes#Upgrade_MATK)
- /**
- * min: (weaponMATK+upgradeMATK) * 2 + 1.5 * statusMATK
- * max: [weaponMATK+upgradeMATK+(wMatk*wLvl)/10] * 2 + 1.5 * statusMATK
- * yes this formula MATCHES their site: matk_max already holds weaponmatk+upgradematk, and
- * -> statusMATK holds the %Matk modifier stuff from earlier and lastly:
- * -> the mdef part is not applied at this point, but later.
- **/ //1:bugreport:5101 //1:bugreport:5101
- MATK_ADD((1+sstatus->matk_max) * 2 + 15/10 * sstatus->matk_min + rnd()% (sstatus->matk_max + (1 + (sstatus->matk_max*sstatus->wlv) / 10 * 2 + 10/15 * sstatus->matk_min)));
-#else //Ancient MATK Appliance
if (sstatus->matk_max > sstatus->matk_min) {
- MATK_ADD(sstatus->matk_min+rnd()%(1+sstatus->matk_max-sstatus->matk_min));
+ MATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
} else {
MATK_ADD(sstatus->matk_min);
}
-#endif
+
if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
if (mflag>0)
ad.damage/= mflag;
@@ -3901,7 +4034,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
MATK_ADD(50);
}
}
-
+#ifdef RENEWAL
+ ad.damage = battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+#endif
if (sd) {
//Damage bonuses
if ((i = pc_skillatk_bonus(sd, skill_num)))
@@ -3971,70 +4106,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
}
- if (sd && !(nk&NK_NO_CARDFIX_ATK)) {
- short t_class = status_get_class(target);
- short cardfix=1000;
-
- cardfix=cardfix*(100+sd->magic_addrace[tstatus->race])/100;
- if (!(nk&NK_NO_ELEFIX))
- cardfix=cardfix*(100+sd->magic_addele[tstatus->def_ele])/100;
- cardfix=cardfix*(100+sd->magic_addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- for (i=0; i< ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate; i++) {
- if (sd->add_mdmg[i].class_ == t_class) {
- cardfix=cardfix*(100+sd->add_mdmg[i].rate)/100;
- continue;
- }
- }
- if (cardfix != 1000)
- MATK_RATE(cardfix/10);
- }
-
- if (tsd && !(nk&NK_NO_CARDFIX_DEF)) {
- // Target cards.
- short s_race2 = status_get_race2(src);
- short s_class= status_get_class(src);
- int cardfix=1000;
-
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) {
- if (tsd->subele2[i].ele != s_ele) continue;
- if (!(tsd->subele2[i].flag&ad.flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&ad.flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&ad.flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
- cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
- cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
- if (sstatus->race != RC_DEMIHUMAN)
- cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
-
- for (i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate; i++) {
- if (tsd->add_mdef[i].class_ == s_class) {
- cardfix=cardfix*(100-tsd->add_mdef[i].rate)/100;
- break;
- }
- }
- //It was discovered that ranged defense also counts vs magic! [Skotlex]
- if (ad.flag&BF_SHORT)
- cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
- else
- cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
-
- cardfix = cardfix * (100 - tsd->bonus.magic_def_rate) / 100;
-
- if (tsd->sc.data[SC_MDEF_RATE])
- cardfix = cardfix * (100 - tsd->sc.data[SC_MDEF_RATE]->val1) / 100;
-
- if (cardfix != 1000)
- MATK_RATE(cardfix / 10);
- }
+#ifndef RENEWAL
+ ad.damage = battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+#endif
}
damage_div_fix(ad.damage, ad.div_);
@@ -4306,38 +4380,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
}
- if (md.damage && tsd && !(nk &NK_NO_CARDFIX_DEF)) {
- // misc damage reduction from equipment
- int cardfix = 10000;
- int race2 = status_get_race2(src);
- if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) {
- if (tsd->subele2[i].ele != s_ele) continue;
- if (!(tsd->subele2[i].flag&md.flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&md.flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&md.flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- cardfix=cardfix*(100-tsd->subrace2[race2])/100;
- cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
- cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
- if (sstatus->race != RC_DEMIHUMAN)
- cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
-
- cardfix = cardfix * (100 - tsd->bonus.misc_def_rate) / 100;
- if (md.flag&BF_SHORT)
- cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
- else // BF_LONG (there's no other choice)
- cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
-
- if (cardfix != 10000)
- md.damage= (int)((int64)md.damage * cardfix / 10000);
- }
+ md.damage = battle_calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
if (sd && (i = pc_skillatk_bonus(sd, skill_num)))
md.damage += md.damage *i/100;
diff --git a/src/map/battle.h b/src/map/battle.h
index 4ec68c399..17d7bd28e 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -41,6 +41,7 @@ void battle_drain(struct map_session_data *sd, struct block_list *tbl, int rdama
int battle_attr_ratio(int atk_elem,int def_type, int def_lv);
int battle_attr_fix(struct block_list *src, struct block_list *target, int damage,int atk_elem,int def_type, int def_lv);
+int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int left, int flag);
// Final calculation Damage
int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int damage,int skill_num,int skill_lv);
diff --git a/src/map/clif.c b/src/map/clif.c
index 18a37d034..b3dc2318b 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -2798,10 +2798,10 @@ void clif_updatestatus(struct map_session_data *sd,int type)
WFIFOL(fd,4)=sd->battle_status.cri/10;
break;
case SP_MATK1:
- WFIFOL(fd,4)=sd->battle_status.matk_max;
+ WFIFOL(fd,4)=pc_rightside_matk(sd);
break;
case SP_MATK2:
- WFIFOL(fd,4)=sd->battle_status.matk_min;
+ WFIFOL(fd,4)=pc_leftside_matk(sd);
break;
@@ -3126,8 +3126,8 @@ void clif_initialstatus(struct map_session_data *sd)
WBUFW(buf,16) = pc_leftside_atk(sd);
WBUFW(buf,18) = pc_rightside_atk(sd);
- WBUFW(buf,20) = sd->battle_status.matk_max;
- WBUFW(buf,22) = sd->battle_status.matk_min;
+ WBUFW(buf,20) = pc_rightside_matk(sd);
+ WBUFW(buf,22) = pc_leftside_matk(sd);
WBUFW(buf,24) = pc_leftside_def(sd);
WBUFW(buf,26) = pc_rightside_def(sd);
WBUFW(buf,28) = pc_leftside_mdef(sd);
diff --git a/src/map/map.h b/src/map/map.h
index 46b7c69d4..e8c95ed35 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -403,9 +403,9 @@ enum _sp {
SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037
SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
- SP_WEAPON_MATK, SP_BASE_MATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2050
- SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2051-2055
- SP_SKILL_USE_SP //2056
+ SP_EMATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2049
+ SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2050-2054
+ SP_SKILL_USE_SP //2055
};
enum _look {
diff --git a/src/map/pc.c b/src/map/pc.c
index 83f1395a3..4bc7f0811 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -2533,14 +2533,10 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
if (sd->state.lr_flag != 2)
sd->bonus.itemhealrate2 += val;
break;
- case SP_WEAPON_MATK:
- if (sd->state.lr_flag != 2)
- sd->bonus.sp_weapon_matk += val;
- break;
- case SP_BASE_MATK:
- if (sd->state.lr_flag != 2)
- sd->bonus.sp_base_matk += val;
- break;
+ case SP_EMATK:
+ if(sd->state.lr_flag != 2)
+ sd->bonus.ematk += val;
+ break;
case SP_FIXCASTRATE:
if (sd->state.lr_flag != 2)
sd->bonus.fixcastrate -= val;
diff --git a/src/map/pc.h b/src/map/pc.h
index 7414dc3e4..8d74b8953 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -314,11 +314,11 @@ struct map_session_data {
short sp_gain_value, hp_gain_value, magic_sp_gain_value, magic_hp_gain_value;
short sp_vanish_rate;
short sp_vanish_per;
- short sp_weapon_matk,sp_base_matk;
unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest]
unsigned short unbreakable_equip; //100% break resistance on certain equipment
unsigned short unstripable_equip;
int fixcastrate,varcastrate;
+ int ematk; // matk bonus from equipment
} bonus;
// zeroed vars end here.
@@ -645,6 +645,8 @@ enum equip_index {
#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)->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)
@@ -652,6 +654,8 @@ enum equip_index {
#define pc_rightside_def(sd) ((sd)->battle_status.def2)
#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef)
#define pc_rightside_mdef(sd) ( (sd)->battle_status.mdef2 - ((sd)->battle_status.vit>>1) )
+#define pc_leftside_matk(sd) ((sd)->battle_status.matk_min)
+#define pc_rightside_matk(sd) ((sd)->battle_status.matk_max)
#endif
int pc_class2idx(int class_);
diff --git a/src/map/skill.c b/src/map/skill.c
index 63f4af5e4..7815bbe5e 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -532,12 +532,10 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, int skill
return battle_config.max_heal;
#ifdef RENEWAL
/**
- * Renewal Heal Formula (from Doddler)
- * TODO: whats that( 1+ %Modifier / 100 ) ? currently using 'x1' (100/100) until found out
- * - Min = ( [ ( BaseLvl + INT ) / 5 ] * 30 ) * (1+( %Modifier / 100)) * (HealLvl * 0.1) + StatusMATK + EquipMATK - [(WeaponMATK * WeaponLvl) / 10]
- * - Max = ( [ ( BaseLvl + INT ) / 5 ] * 30 ) * (1+( %Modifier / 100)) * (HealLvl * 0.1) + StatusMATK + EquipMATK + [(WeaponMATK * WeaponLvl) / 10]
+ * Renewal Heal Formula
+ * Formula: ( [(Base Level + INT) / 5] × 30 ) × (Heal Level / 10) × (Modifiers) + MATK
**/
- hp = ((((status_get_lv(src) + status_get_int(src)) / 5) * 3) * skill_lv + status_get_matk_min(src) + status_get_matk_max(src) - ((status_get_matk_max(src) * status_get_wlv(src)) / 10)) + rnd()%((((status_get_lv(src) + status_get_int(src)) / 5) * 3) * skill_lv + status_get_matk_min(src) + status_get_matk_max(src) + ((status_get_matk_max(src) * status_get_wlv(src)) / 10));
+ hp = (status_get_lv(src) + status_get_int(src)) / 5 * 30 * skill_lv / 10;
#else
hp = (status_get_lv(src) + status_get_int(src)) / 8 * (4 + (skill_id == AB_HIGHNESSHEAL ? (sd ? pc_checkskill(sd,AL_HEAL) : 10) : skill_lv) * 8);
#endif
@@ -568,7 +566,41 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, int skill
if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
hp += hp / 10;
}
-
+
+#ifdef RENEWAL
+ // MATK part of the RE heal formula [malufett]
+ // Note: in this part matk bonuses from items or skills are not applied
+ switch( skill_id ) {
+ case BA_APPLEIDUN: case PR_SANCTUARY:
+ case NPC_EVILLAND: break;
+ default:
+ {
+ struct status_data *status = status_get_status_data(src);
+ int min, max, wMatk, variance;
+
+ min = max = status_base_matk(status, status_get_lv(src));
+ if( status->rhw.matk > 0 ){
+ wMatk = status->rhw.matk;
+ variance = wMatk * status->rhw.wlv / 10;
+ min += wMatk - variance;
+ max += wMatk + variance;
+ }
+
+ if( sc && sc->data[SC_RECOGNIZEDSPELL] )
+ min = max;
+
+ if( sd && sd->right_weapon.overrefine > 0 ){
+ min++;
+ max += sd->right_weapon.overrefine - 1;
+ }
+
+ if(max > min)
+ hp += min+rnd()%(max-min);
+ else
+ hp += min;
+ }
+ }
+#endif
return hp;
}
@@ -7523,7 +7555,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, int
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
status_heal(bl,heal,0,1);
- status_change_clear_buffs(bl,6);
+ status_change_clear_buffs(bl,4);
}
break;
@@ -8714,10 +8746,22 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, int
case SO_EL_ACTION:
if (sd) {
+ int duration = 3000;
if (!sd->ed)
break;
elemental_action(sd->ed, bl, tick);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ switch(sd->ed->db->class_){
+ case 2115:case 2124:
+ case 2118:case 2121:
+ duration = 6000;
+ break;
+ case 2116:case 2119:
+ case 2122:case 2125:
+ duration = 9000;
+ break;
+ }
+ skill_blockpc_start(sd, skillid, duration);
}
break;
@@ -11564,7 +11608,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, unsi
status_heal(bl,heal,0,0);
break;
case 1: // End all negative status
- status_change_clear_buffs(bl,2);
+ status_change_clear_buffs(bl,6);
if (tsd) clif_gospel_info(tsd, 0x15);
break;
case 2: // Immunity to all status
diff --git a/src/map/status.c b/src/map/status.c
index f01bce10c..7bca41572 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -587,7 +587,7 @@ void initChangeTables(void)
add_sc(WL_WHITEIMPRISON , SC_WHITEIMPRISON);
set_sc_with_vfx(WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2);
set_sc(WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF);
- set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_NONE);
+ set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_MATK);
set_sc(WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE);
/**
* Ranger
@@ -1942,29 +1942,12 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
return cap_value(str, 0, USHRT_MAX);
}
-
-static inline unsigned short status_base_matk_max(const struct status_data *status)
-{
-#ifdef RENEWAL
- return status->matk_max; // in RE maximum MATK signs weapon matk, which we store in this var
-#else
- return status->int_+(status->int_/5)*(status->int_/5);
-#endif
-}
-
-#ifdef RENEWAL
-static inline unsigned short status_base_matk_min(const struct status_data *status, int lvl)
+#ifndef RENEWAL
+static inline unsigned short status_base_matk_min(const struct status_data* status){ return status->int_+(status->int_/7)*(status->int_/7); }
+static inline unsigned short status_base_matk_max(const struct status_data* status){ return status->int_+(status->int_/5)*(status->int_/5); }
#else
-static inline unsigned short status_base_matk_min(const struct status_data *status)
+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
-{
-#ifdef RENEWAL
- return status->int_+(status->int_/2)+(status->dex/5)+(status->luk/3)+(lvl/4);
-#else
- return status->int_+(status->int_/7)*(status->int_/7);
-#endif
-}
-
//Fills in the misc data that can be calculated from the other status info (except for level)
void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
@@ -1975,19 +1958,16 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
status->hit = status->flee =
status->def2 = status->mdef2 =
status->cri = status->flee2 = 0;
-#ifdef RENEWAL
- status->matk_min = status_base_matk_min(status, level);
-#else
- status->matk_min = status_base_matk_min(status);
-#endif
- status->matk_max = status_base_matk_max(status);
#ifdef RENEWAL // renewal formulas
+ status->matk_min = status->matk_max = status_base_matk(status, level);
status->hit += level + status->dex + status->luk/3 + 175; //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
status->flee += level + status->agi + status->luk/5 + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
status->def2 += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
status->mdef2 += (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)
#else
+ status->matk_min = status_base_matk_min(status);
+ status->matk_max = status_base_matk_max(status);
status->hit += level + status->dex;
status->flee += level + status->agi;
status->def2 += status->vit;
@@ -2527,16 +2507,10 @@ int status_calc_pc_(struct map_session_data *sd, bool first)
wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
#ifdef RENEWAL
- // in renewal max MATK is the weapon MATK
- status->matk_max += sd->inventory_data[index]->matk;
-
- if (r) {
- // renewal magic attack refine bonus
- status->matk_max += refine_info[wlv].bonus[r-1] / 100;
- }
-
- // record the weapon level for future usage
- status->wlv = wlv;
+ wa->matk += sd->inventory_data[index]->matk;
+ wa->wlv = wlv;
+ if( r ) // renewal magic attack refine bonus
+ wa->matk += refine_info[wlv].bonus[r-1] / 100;
#endif
//Overrefine bonus.
@@ -2609,11 +2583,6 @@ int status_calc_pc_(struct map_session_data *sd, bool first)
status->def += (refinedef+50)/100;
-#ifdef RENEWAL
- // increment the weapon ATK using the MATK max value
- status->matk_max += sd->bonus.sp_weapon_matk;
-#endif
-
//Parse Cards
for (i=0; i<EQI_MAX-1; i++) {
current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
@@ -3807,32 +3776,47 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
}
if (flag&SCB_MATK) {
-#ifdef RENEWAL
- status->matk_min = status_base_matk_min(status,status_get_lv(bl));
- if (sd)
- status->matk_min += sd->bonus.sp_base_matk;
+#ifndef RENEWAL
+ status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
+ status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
#else
- status->matk_min = status_base_matk_min(status);
+ /**
+ * 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 ){
+ if( sd->bonus.ematk > 0 ){
+ status->matk_max += sd->bonus.ematk;
+ status->matk_min += sd->bonus.ematk;
+ }
+ if( status->rhw.matk > 0 ){
+ int wMatk = status->rhw.matk;
+ int variance = wMatk * status->rhw.wlv / 10;
+ status->matk_min += wMatk - variance;
+ status->matk_max += wMatk + variance;
+ }
+ }
#endif
- status->matk_max = status_base_matk_max(status);
-
if (bl->type&BL_PC && sd->matk_rate != 100) {
- //Bonuses from previous matk
-#ifndef RENEWAL // only changed in non-renewal [Ind]
status->matk_max = status->matk_max * sd->matk_rate/100;
-#endif
status->matk_min = status->matk_min * sd->matk_rate/100;
}
status->matk_min = status_calc_matk(bl, sc, status->matk_min);
-
-#ifndef RENEWAL // only changed in non-renewal [Ind]
status->matk_max = status_calc_matk(bl, sc, status->matk_max);
-#endif
- if (bl->type&BL_HOM && battle_config.hom_setting&0x20) //Hom Min Matk is always the same as Max Matk
+ if (bl->type&BL_HOM && battle_config.hom_setting&0x20 //Hom Min Matk is always the same as Max Matk
+ || ( sc && sc->data[SC_RECOGNIZEDSPELL] ))
status->matk_min = status->matk_max;
+#ifdef RENEWAL
+ if( sd && sd->right_weapon.overrefine > 0){
+ status->matk_min++;
+ status->matk_max += sd->right_weapon.overrefine - 1;
+ }
+#endif
+
}
if (flag&SCB_ASPD) {
@@ -4018,10 +4002,17 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first)
clif_updatestatus(sd,SP_FLEE2);
if (b_status.cri != status->cri)
clif_updatestatus(sd,SP_CRITICAL);
+#ifndef RENEWAL
if (b_status.matk_max != status->matk_max)
clif_updatestatus(sd,SP_MATK1);
if (b_status.matk_min != status->matk_min)
clif_updatestatus(sd,SP_MATK2);
+#else
+ if(b_status.matk_max != status->matk_max || b_status.matk_min != status->matk_min){
+ clif_updatestatus(sd,SP_MATK2);
+ clif_updatestatus(sd,SP_MATK1);
+ }
+#endif
if (b_status.mdef != status->mdef) {
clif_updatestatus(sd,SP_MDEF1);
#ifdef RENEWAL
@@ -6214,6 +6205,14 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//No defense against it (buff).
rate -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100; // Lineal Reduction of Rate
break;
+ case SC_MARSHOFABYSS:
+ //5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second }
+ tick -= (status->int_ + status->luk) / 20 * 1000;
+ break;
+ case SC_STASIS:
+ //5 second (fixed) + { Stasis Skill level * 5 - (Target’s VIT + DEX) / 20 }
+ tick -= (status->vit + status->dex) / 20 * 1000;
+ break;
case SC_WHITEIMPRISON:
if (tick == 5000) // 100% on caster
break;
@@ -10556,7 +10555,7 @@ int status_change_timer_sub(struct block_list *bl, va_list ap)
/*==========================================
* Clears buffs/debuffs of a character.
- * type&1 -> buffs, type&2 -> debuffs
+ * type&1 -> buffs, type&2 -> debuffs
* type&4 -> especific debuffs(implemented with refresh)
*------------------------------------------*/
int status_change_clear_buffs(struct block_list *bl, int type)
@@ -10567,16 +10566,9 @@ int status_change_clear_buffs(struct block_list *bl, int type)
if (!sc || !sc->count)
return 0;
- if (type&2) //Debuffs
- for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) {
- if(sc->data[i])
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
- }
- if(type&4) //Toxins
- for (i = SC_TOXIN; i <= SC_LEECHESEND; ++i) {
- if (sc->data[i])
- status_change_end(bl, (sc_type)i, INVALID_TIMER);
- }
+ if (type&6) //Debuffs
+ for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
for (i = SC_COMMON_MAX+1; i < SC_MAX; i++) {
if (!sc->data[i])
@@ -10637,22 +10629,28 @@ int status_change_clear_buffs(struct block_list *bl, int type)
case SC_CURSEDCIRCLE_TARGET:
continue;
- //Debuffs that can be removed.
- case SC_CRYSTALIZE:
+ //Debuffs that can be removed.
case SC_DEEPSLEEP:
- case SC_MANDRAGORA:
+ case SC_BURNING:
+ case SC_FREEZING:
+ case SC_CRYSTALIZE:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
case SC_MARSHOFABYSS:
+ case SC_MANDRAGORA:
if(!(type&4))
continue;
break;
- case SC_QUAGMIRE:
- case SC_DECREASEAGI:
- case SC_BURNING:
- if(!(type&2))
- continue;
- break;
case SC_HALLUCINATION:
+ case SC_QUAGMIRE:
case SC_SIGNUMCRUCIS:
+ case SC_DECREASEAGI:
case SC_SLOWDOWN:
case SC_MINDBREAKER:
case SC_WINKCHARM:
@@ -10668,7 +10666,7 @@ int status_change_clear_buffs(struct block_list *bl, int type)
case SC_FEAR:
case SC_MAGNETICFIELD:
case SC_NETHERWORLD:
- if (!(type&2) || type == 6) //RK_Refresh is not supposed to remove these
+ if (!(type&2))
continue;
break;
//The rest are buffs that can be removed.
diff --git a/src/map/status.h b/src/map/status.h
index 9343b4f78..130b858e0 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1563,6 +1563,9 @@ struct weapon_atk {
unsigned short atk, atk2;
unsigned short range;
unsigned char ele;
+#ifdef RENEWAL
+ unsigned short matk, wlv;
+#endif
};
@@ -1592,13 +1595,7 @@ struct status_data {
unsigned char
def_ele, ele_lv,
-#ifdef RENEWAL
- /**
- * in RE weapon level is used in several areas, keeping it here saves performance
- **/
- wlv,
-#endif
- size, race;
+ size, race;
struct weapon_atk rhw, lhw; //Right Hand/Left Hand Weapon.
};
@@ -1748,12 +1745,6 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
#define status_get_race(bl) status_get_status_data(bl)->race
#define status_get_size(bl) status_get_status_data(bl)->size
#define status_get_mode(bl) status_get_status_data(bl)->mode
-#ifdef RENEWAL
-/**
- * in RE weapon level is used in several areas, keeping it here saves performance
- **/
-#define status_get_wlv(bl) status_get_status_data(bl)->wlv
-#endif
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);
@@ -1808,6 +1799,10 @@ int status_check_visibility(struct block_list *src, struct block_list *target);
int status_change_spread(struct block_list *src, struct block_list *bl);
+#ifdef RENEWAL
+unsigned short status_base_matk(const struct status_data* status, int level);
+#endif
+
int status_readdb(void);
int do_init_status(void);
void do_final_status(void);