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.
This commit is contained in:
aleos89 2016-05-11 13:36:59 -04:00
parent af8524aa7d
commit 952b072468
8 changed files with 43 additions and 21 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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