From 952b072468f399d84eed6143870a96ff1757512c Mon Sep 17 00:00:00 2001 From: aleos89 Date: Wed, 11 May 2016 13:36:59 -0400 Subject: [PATCH] Implemented item bonuses bWeaponAtkRate and bWeaponMatkRate (fixes #1161) * Increases an equipped weapon's ATK/MATK by given rate. * bWeaponMatkRate does not work in pre-renewal as there is no MATK for weapons in pre-renewal. * Renamed 'bonus2 bWeaponAtkRate' to 'bonus2 bWeaponDamageRate'. - Seems to be unused in the current item database. - Damage fits the bonus name better as it increased the final damage, not the weapon's attack specifically. --- doc/item_bonus.txt | 4 +++- src/map/battle.c | 10 +++++----- src/map/map.h | 5 +++-- src/map/pc.c | 12 ++++++++++-- src/map/pc.h | 3 ++- src/map/script_constants.h | 4 +++- src/map/status.c | 24 ++++++++++++++++-------- src/map/status.h | 2 +- 8 files changed, 43 insertions(+), 21 deletions(-) diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index 0f1faa628b..a699b79caa 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -109,8 +109,10 @@ bonus bBaseAtk,n; Basic attack power + n bonus bAtk,n; ATK + n (unofficial) bonus bAtk2,n; ATK2 + n bonus bAtkRate,n; Attack power + n% +bonus bWeaponAtkRate,n; Weapon ATK + n% bonus bMatk,n; Magical attack power + n bonus bMatkRate,n; Magical attack power + n% +bonus bWeaponMatkRate,n; Weapon Magical ATK + n% (renewal mode only) bonus bDef,n; Equipment DEF + n bonus bDefRate,n; Equipment DEF + n% bonus bDef2,n; VIT based DEF + n @@ -166,7 +168,7 @@ bonus bLongAtkRate,n; Increases damage of ranged attacks by n% bonus bCritAtkRate,n; Increases critical damage by +n% bonus bCriticalDef,n; Decreases the chance of being hit by critical hits by n% bonus2 bWeaponAtk,w,n; Adds n ATK when weapon of type w is equipped -bonus2 bWeaponAtkRate,w,n; Adds n% damage to normal attacks when weapon of type w is equipped +bonus2 bWeaponDamageRate,w,n; Adds n% damage to normal attacks when weapon of type w is equipped bonus bNearAtkDef,n; Adds n% damage reduction against melee physical attacks bonus bLongAtkDef,n; Adds n% damage reduction against ranged physical attacks diff --git a/src/map/battle.c b/src/map/battle.c index a9fd40342c..29d6c05c53 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1942,18 +1942,18 @@ static int64 battle_calc_base_damage(struct status_data *status, struct weapon_a damage += status->batk; //rodatazone says that Overrefine bonuses are part of baseatk - //Here we also apply the weapon_atk_rate bonus so it is correctly applied on left/right hands. + //Here we also apply the weapon_damage_rate bonus so it is correctly applied on left/right hands. if(sd) { if (type == EQI_HAND_L) { if(sd->left_weapon.overrefine) damage += rnd()%sd->left_weapon.overrefine+1; - if (sd->weapon_atk_rate[sd->weapontype2]) - damage += damage * sd->weapon_atk_rate[sd->weapontype2] / 100; + if (sd->weapon_damage_rate[sd->weapontype2]) + damage += damage * sd->weapon_damage_rate[sd->weapontype2] / 100; } else { //Right hand if(sd->right_weapon.overrefine) damage += rnd()%sd->right_weapon.overrefine+1; - if (sd->weapon_atk_rate[sd->weapontype1]) - damage += damage * sd->weapon_atk_rate[sd->weapontype1] / 100; + if (sd->weapon_damage_rate[sd->weapontype1]) + damage += damage * sd->weapon_damage_rate[sd->weapontype1] / 100; } } diff --git a/src/map/map.h b/src/map/map.h index 41a11da0a1..b60a67cd14 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -439,7 +439,7 @@ enum _sp { SP_MAGIC_DAMAGE_RETURN,SP_ALL_STATS=1073,SP_AGI_VIT,SP_AGI_DEX_STR,SP_PERFECT_HIDE, // 1071-1076 SP_NO_KNOCKBACK,SP_CLASSCHANGE, // 1077-1078 SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080 - SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082 + SP_WEAPON_ATK,SP_WEAPON_DAMAGE_RATE, // 1081-1082 SP_DELAYRATE,SP_HP_DRAIN_VALUE_RACE, SP_SP_DRAIN_VALUE_RACE, // 1083-1085 SP_IGNORE_MDEF_RACE_RATE,SP_IGNORE_DEF_RACE_RATE,SP_SKILL_HEAL2,SP_ADDEFF_ONSKILL, //1086-1089 SP_ADD_HEAL_RATE,SP_ADD_HEAL2_RATE, SP_EQUIP_ATK, //1090-1092 @@ -465,7 +465,8 @@ enum _sp { SP_WEAPON_COMA_CLASS, SP_IGNORE_MDEF_CLASS_RATE, SP_EXP_ADDCLASS, SP_ADD_CLASS_DROP_ITEM, //2067-2070 SP_ADD_CLASS_DROP_ITEMGROUP, SP_ADDMAXWEIGHT, SP_ADD_ITEMGROUP_HEAL_RATE, // 2071-2073 SP_HP_VANISH_RACE_RATE, SP_SP_VANISH_RACE_RATE, SP_ABSORB_DMG_MAXHP, SP_SUB_SKILL, SP_SUBDEF_ELE, // 2074-2078 - SP_STATE_NORECOVER_RACE, SP_CRITICAL_RANGEATK, SP_MAGIC_ADDRACE2, SP_IGNORE_MDEF_RACE2_RATE // 2079-2082 + SP_STATE_NORECOVER_RACE, SP_CRITICAL_RANGEATK, SP_MAGIC_ADDRACE2, SP_IGNORE_MDEF_RACE2_RATE, // 2079-2082 + SP_WEAPON_ATK_RATE, SP_WEAPON_MATK_RATE, // 2083-2084 }; enum _look { diff --git a/src/map/pc.c b/src/map/pc.c index 74bb7451f0..6d36949e32 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3036,6 +3036,14 @@ void pc_bonus(struct map_session_data *sd,int type,int val) else sd->bonus.arrow_cri += val*10; break; + case SP_WEAPON_ATK_RATE: + if (sd->state.lr_flag != 2) + sd->bonus.weapon_atk_rate += val; + break; + case SP_WEAPON_MATK_RATE: + if (sd->state.lr_flag != 2) + sd->bonus.weapon_matk_rate += val; + break; default: ShowWarning("pc_bonus: unknown type %d %d !\n",type,val); break; @@ -3292,9 +3300,9 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) if(sd->state.lr_flag != 2) sd->weapon_atk[type2]+=val; break; - case SP_WEAPON_ATK_RATE: // bonus2 bWeaponAtkRate,w,n; + case SP_WEAPON_DAMAGE_RATE: // bonus2 bWeaponDamageRate,w,n; if(sd->state.lr_flag != 2) - sd->weapon_atk_rate[type2]+=val; + sd->weapon_damage_rate[type2]+=val; break; case SP_CRITICAL_ADDRACE: // bonus2 bCriticalAddRace,r,n; PC_BONUS_CHK_RACE(type2,SP_CRITICAL_ADDRACE); diff --git a/src/map/pc.h b/src/map/pc.h index c06ccd5b93..611cd7bf98 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -348,7 +348,7 @@ struct map_session_data { short weapon_coma_race[RC_MAX]; short weapon_coma_class[CLASS_MAX]; int weapon_atk[16]; - int weapon_atk_rate[16]; + int weapon_damage_rate[16]; int arrow_addele[ELE_MAX]; int arrow_addrace[RC_MAX]; int arrow_addclass[CLASS_MAX]; @@ -458,6 +458,7 @@ struct map_session_data { int eatk; // atk bonus from equipment uint8 absorb_dmg_maxhp; // [Cydh] short critical_rangeatk; + short weapon_atk_rate, weapon_matk_rate; } bonus; // zeroed vars end here. diff --git a/src/map/script_constants.h b/src/map/script_constants.h index 9b1ca83bd5..63592d03cc 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -509,9 +509,11 @@ script_set_constant("bDoubleAddRate",SP_DOUBLE_ADD_RATE,false); script_set_constant("bSkillHeal",SP_SKILL_HEAL,false); script_set_constant("bMatkRate",SP_MATK_RATE,false); + script_set_constant("bWeaponMatkRate",SP_WEAPON_MATK_RATE,false); script_set_constant("bIgnoreDefEle",SP_IGNORE_DEF_ELE,false); script_set_constant("bIgnoreDefRace",SP_IGNORE_DEF_RACE,false); script_set_constant("bAtkRate",SP_ATK_RATE,false); + script_set_constant("bWeaponAtkRate",SP_WEAPON_ATK_RATE,false); script_set_constant("bSpeedAddRate",SP_SPEED_ADDRATE,false); script_set_constant("bSPRegenRate",SP_SP_REGEN_RATE,false); script_set_constant("bMagicAtkDef",SP_MAGIC_ATK_DEF,false); @@ -564,7 +566,7 @@ script_set_constant("bHPDrainValue",SP_HP_DRAIN_VALUE,false); script_set_constant("bSPDrainValue",SP_SP_DRAIN_VALUE,false); script_set_constant("bWeaponAtk",SP_WEAPON_ATK,false); - script_set_constant("bWeaponAtkRate",SP_WEAPON_ATK_RATE,false); + script_set_constant("bWeaponDamageRate",SP_WEAPON_DAMAGE_RATE,false); script_set_constant("bDelayrate",SP_DELAYRATE,false); script_set_constant("bHPDrainValueRace",SP_HP_DRAIN_VALUE_RACE,false); script_set_constant("bSPDrainValueRace",SP_SP_DRAIN_VALUE_RACE,false); diff --git a/src/map/status.c b/src/map/status.c index fe52f958ab..eee2d20f24 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2303,13 +2303,17 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_ * @param status: Player status * @return weapon attack */ -unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status) +unsigned int status_weapon_atk(struct weapon_atk wa, struct map_session_data *sd) { - float str = status->str; + float str = sd->base_status.str; + int weapon_atk_bonus = 0; + if (wa.range > 3) - str = status->dex; - // wa.at2 = refinement, wa.atk = base equip atk, wa.atk*str/200 = bonus str - return wa.atk + wa.atk2 + (int)(wa.atk * (str/200)); + str = sd->base_status.dex; + if (sd->bonus.weapon_atk_rate) + weapon_atk_bonus = wa.atk * sd->bonus.weapon_atk_rate / 100; + // wa.atk2 = refinement, wa.atk = base equip atk, wa.atk*str/200 = bonus str + return wa.atk + wa.atk2 + (int)(wa.atk * (str/200) + weapon_atk_bonus); } #endif @@ -3097,7 +3101,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) + sizeof(sd->weapon_coma_race) + sizeof(sd->weapon_coma_class) + sizeof(sd->weapon_atk) - + sizeof(sd->weapon_atk_rate) + + sizeof(sd->weapon_damage_rate) + sizeof(sd->arrow_addele) + sizeof(sd->arrow_addrace) + sizeof(sd->arrow_addclass) @@ -3246,6 +3250,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) wa->atk2 = refine_info[wlv].bonus[r-1] / 100; #ifdef RENEWAL wa->matk += sd->inventory_data[index]->matk; + if (sd->bonus.weapon_matk_rate) + wa->matk += sd->inventory_data[index]->matk * sd->bonus.weapon_matk_rate / 100; wa->wlv = wlv; if(r && sd->weapontype1 != W_BOW) // Renewal magic attack refine bonus wa->matk += refine_info[wlv].bonus[r-1] / 100; @@ -3496,8 +3502,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) if((skill=pc_checkskill(sd,BS_HILTBINDING))>0) base_status->batk += 4; #else - base_status->watk = status_weapon_atk(base_status->rhw, base_status); - base_status->watk2 = status_weapon_atk(base_status->lhw, base_status); + base_status->watk = status_weapon_atk(base_status->rhw, sd); + base_status->watk2 = status_weapon_atk(base_status->lhw, sd); base_status->eatk = max(sd->bonus.eatk,0); #endif @@ -4468,6 +4474,8 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) if (!sd) // Should not affect weapon refine bonus status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2); + if (sd && sd->bonus.weapon_atk_rate) + status->rhw.atk += status->rhw.atk * sd->bonus.weapon_atk_rate / 100; if(b_status->lhw.atk) { if (sd) { sd->state.lr_flag = 1; diff --git a/src/map/status.h b/src/map/status.h index ffbd76b51a..2e3a130e4a 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2250,7 +2250,7 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ unsigned short status_base_matk_min(const struct status_data* status); 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 int status_weapon_atk(struct weapon_atk wa, struct map_session_data *sd); unsigned short status_base_matk(struct block_list *bl, const struct status_data* status, int level); #endif