Преглед на файлове

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.

aleos89 преди 9 години
родител
ревизия
952b072468
променени са 8 файла, в които са добавени 43 реда и са изтрити 21 реда
  1. 3 1
      doc/item_bonus.txt
  2. 5 5
      src/map/battle.c
  3. 3 2
      src/map/map.h
  4. 10 2
      src/map/pc.c
  5. 2 1
      src/map/pc.h
  6. 3 1
      src/map/script_constants.h
  7. 16 8
      src/map/status.c
  8. 1 1
      src/map/status.h

+ 3 - 1
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

+ 5 - 5
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;
 		}
 	}
 

+ 3 - 2
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 {

+ 10 - 2
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);

+ 2 - 1
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.
 

+ 3 - 1
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);

+ 16 - 8
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;

+ 1 - 1
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