Преглед изворни кода

Official Renewal battle support and major battle calculation engine refactoring! Giant thanks to Baaberith for the initial refactoring work and Akinari for beating me over the head to get this finished xP
Please visit http://rathena.org/board/topic/84568-r17402-major-battleskill-system-overhaul-and-renewal-support/ for a complete and updated log of changes

General
* Forced neutral behavior documented and implemented. Weapon element does affect the following skills, but final damage is treated neutral for resistances. End result is endows do boost skill damage as expected given elemental weaknesses or resistances, but forced neutral skills will always miss on Ghost 3/4 mobs as the damage is "forced" back to neutral type after bonuses are applied but before resistances.
* The following skills are considered "forced neutral"
Merchant "Cart Revolution"
Creator "Acid Demonstration"
Genetic "Cart Cannon" (damage is forced to element of cannon ball, either neutral or holy or ghost)
* Weapon calculation engine has been rewritten to better emulate official behaviors and "quirks", the following changes have been documented and implemented:
Double attack takes priority over criticals when determining which effect activates
VITDEF (status or sDEF) is applied on every hit on multi-hit skills, rather than a flat reduction on the final damage total
Skills such as Spiral Pierce that differ when used by monsters modified to match official calculation methods
* Weapon element behavior adjusted to match official behavior, endows override any innate weapon element, including elemental arrows
* Renewal - weapon element only applies bonus damage to "weapon" ATK, ATK from status and equipment is considered neutral and ATK from mastery skills are considered non-elemental

Archer:
* Renewal - Owl's Eye still gives +1 HIT per skill level but the HIT bonus does not show up in the status window anymore

Hunter:
* Renewal - Claymore, freeze trap and landmine adjusted to apply full damage to "plant" type mobs (monsters that only take 1 damage on every hit)

Thief:
* Double attack gives a hidden +1 HIT per skill level on attacks that activate the double attack effect
* Envenom gives a flat +15 ATK per skill level when used, it is considered a mastery type damage and has no element

Rogue:
* Renewal - Owl's Eye still gives +1 HIT per skill level but the HIT bonus does not show up in the status window anymore

Assassin Cross
* Renewal - Soul Breaker formula for renewal implemented
((ATK + MATK) * (3 + (.5 * skill level)) - (eDEF + sDEF + eMDEF + sMDEF)
* Renewal - Soul Breaker no longer misses, it will always do full damage regardless of target's FLEE
* Renewal - Soul Breaker no longer gains DEF piercing or ignore DEF effect from weapons such as Combat Knife and Ice Pick
* Renewal - Enchant Deadly Poison for renewal implemented
Weapon ATK multiplied by (1 + (EDP level * .8))
Equipment ATK multiplied by (1 + (EDP level * .6))
* Renewal - EDP adds half modifiers (base damage/2) but otherwise functions as above with the following skills:
Sonic Blow
Soul Breaker
Counter Slash
Cross Impact

Creator
* Renewal - Acid Demonstration formula for renewal implemented
7 * ((ATK + MATK) / skill level) * VIT / 100 )
* Acid Demonstration adjusted to match "forced neutral" behavior on official
For example, Acid Demonstration used on a water-type mob with a wind endowed weapon will do bonus damage, but will miss on a Ghost 3/4 monster regardless of endow.

Swordsman
* Magnum break bonus damage gives +20% ATK fire damage on physical attack (so 100% ATK normal + 20% ATK fire)

Lord Knight
* Renewal - Spiral Pierce formula for renewal implemented
(ATK + (weapon weight / 2)) * (100 + (50 * skill level))%
* Renewal - Mastery skills such as spear mastery no longer add any bonus damage to Spiral Pierce
* Renewal - Spiral Pierce no longer ignores DEF

Ninja
* Renewal - Final Strike formula for renewal implemented
base damage = current hp + ((ATK * current hp * skill lvl) / max hp)
final damage = base damage + ((mirror image count + 1) / 5 * base damage) - (eDEF + sDEF)
* Final Strike will MISS on plant-type mobs (mobs that only take 1 damage per hit from all sources)
* Mirror Image cast over itself will override and reset current Mirror Image count

Genetic
* Cart Cannon "forced element" behavior implemented, damage is "forced" to the element of the cannon ball.
Ex. Cart Cannon fitted with a standard cannon ball and a fire elemental weapon will do bonus damage against earth targets, and a Cart Cannon fitted with a holy cannon ball will do bonus damage against shadow, but total damage is forced back to element of cannon ball and resistances applied against it. Neutral cannon balls will miss on Ghost 3/4 but holy/ghost/shadow will not.

Gunslinger
* Gunslinger Mine skill formula and behavior matched to official
Fixed 500 damage, ignores DEF and is affected by +% ATK weapon cards only

Warlock
* Tetra Vortex behavior modified to match official
First 4 spirit spheres are used for calculating element of each hit, but if 5 are present all 5 are consumed


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17402 54d463be-8e91-2dee-dedb-b68131a5f0ec

hipsterfont пре 12 година
родитељ
комит
f926d8750a
9 измењених фајлова са 820 додато и 407 уклоњено
  1. 6 6
      db/re/skill_db.txt
  2. 702 378
      src/map/battle.c
  3. 4 0
      src/map/battle.h
  4. 3 2
      src/map/map.h
  5. 4 4
      src/map/pc.c
  6. 3 3
      src/map/pc.h
  7. 44 6
      src/map/skill.c
  8. 49 8
      src/map/status.c
  9. 5 0
      src/map/status.h

+ 6 - 6
db/re/skill_db.txt

@@ -105,7 +105,7 @@
 58,-4,6,1,-1,0x2,0,10,1,no,0,0,0,weapon,6,	KN_SPEARSTAB,Spear Stab
 59,3:5:7:9:11,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,	KN_SPEARBOOMERANG,Spear Boomerang
 60,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0,		KN_TWOHANDQUICKEN,Twohand Quicken
-61,0,6,4,-1,0x20,0,5,1,no,0,0,0,weapon,0,	KN_AUTOCOUNTER,Counter Attack
+61,0,6,4,-1,0,0,5,1,no,0,0,0,weapon,0,	KN_AUTOCOUNTER,Counter Attack
 62,-2,6,1,-1,0x2,1,10,1,no,0,0,0,weapon,1,	KN_BOWLINGBASH,Bowling Bash
 63,0,0,0,0,0,0,1,0,no,0,0,0,weapon,0,		KN_RIDING,Peco Peco Riding
 64,0,0,0,0,0,0,5,0,no,0,0,0,weapon,0,		KN_CAVALIERMASTERY,Cavalier Mastery
@@ -422,7 +422,7 @@
 376,0,0,0,0,0x1,0,5,1,no,0,0,0,weapon,0,		ASC_KATAR,Advanced Katar Mastery
 //377,0,0,4,0,0x1,0,10,1,no,0,0,0,misc,0,	ASC_HALLUCINATION,Hallucination Walk
 378,0,6,4,5,0x1,0,5,1,no,0,0,0,weapon,0,		ASC_EDP,Enchant Deadly Poison
-379,7,6,1,-1,0x8,0,10,1,yes,0,0,0,weapon,0,	ASC_BREAKER,Soul Destroyer
+379,7,6,1,-1,0x68,0,10,1,yes,0,0,0,misc,0,	ASC_BREAKER,Soul Destroyer
 380,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0,	SN_SIGHT,Falcon Eyes
 381,5,8,1,0,0x40,0,5,1,yes,0,0,0,misc,0,		SN_FALCONASSAULT,Falcon Assault
 382,9,8,1,-1,0,2,5,1,yes,0,0,13,weapon,0,	SN_SHARPSHOOTING,Focused Arrow Strike
@@ -440,7 +440,7 @@
 394,9,8,1,-1,0,0,10,-9,yes,0,0,0,weapon,0,	CG_ARROWVULCAN,Vulcan Arrow
 395,0,0,4,0,0x1,3,1,1,yes,0,0x40,0,misc,2,	CG_MOONLIT,Sheltering Bliss
 396,1,6,16,0,0x1,0,1,1,yes,0,0x600,0,none,0,	CG_MARIONETTE,Marionette Control
-397,5,8,1,-1,0x20,0,5,5,no,0,0,0,weapon,0,	LK_SPIRALPIERCE,Spiral Pierce
+397,5,8,1,-1,0,0,5,5,no,0,0,0,weapon,0,	LK_SPIRALPIERCE,Spiral Pierce
 398,4,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,		LK_HEADCRUSH,Traumatic Blow
 399,4,6,1,-1,0,0,10,1,no,0,0,0,weapon,0,		LK_JOINTBEAT,Vital Strike
 400,9,8,1,8,0x6,1,5,1:2:3:4:5,yes,0,0,0,magic,0,	HW_NAPALMVULCAN,Napalm Vulcan
@@ -533,7 +533,7 @@
 487,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,		CG_LONGINGFREEDOM,Longing for Freedom
 488,0,6,4,0,0x1,1,5,1,no,0,0x40,0,misc,0,	CG_HERMODE,Wand of Hermode
 489,9,6,1,0,0x41,0,5,1,no,0,0,0,misc,0,		CG_TAROTCARD,Tarot Card of Fate
-490,9,8,1,0,0x40,0,10,1:2:3:4:5:6:7:8:9:10,yes,0,0,0,misc,0,	CR_ACIDDEMONSTRATION,Acid Demonstration
+490,9,8,1,-1,0x60,0,10,1:2:3:4:5:6:7:8:9:10,yes,0,0,0,misc,0,	CR_ACIDDEMONSTRATION,Acid Demonstration
 491,1,6,2,0,0x1,0,2,1,no,0,0,0,none,0,		CR_CULTIVATION,Plant Cultivation
 492,0,6,4,0:1:2:3:4:5:6:7:8:9,0x1,0,10,1,no,0,0x2,0,none,0,	ITEM_ENCHANTARMS,Weapon Enchantment
 493,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0,		TK_MISSION,Taekwon Mission
@@ -564,7 +564,7 @@
 518,2,6,1,-1,0,0,10,1,no,0,0,0,weapon,5,		GS_DUST,Dust
 519,-9,6,1,-1,0,0,10,1,yes,0,0,0,weapon,0,	GS_FULLBUSTER,Full Buster
 520,-9,6,1,-1,0x2,1:1:1:2:2:2:3:3:3:4,10,1,no,0,0,0,weapon,0,	GS_SPREADATTACK,Spread Attack
-521,-9,6,2,-1,0x40,1,10,1,no,0,0,0,weapon,3,	GS_GROUNDDRIFT,Ground Drift
+521,-9,6,2,-1,0x60,1,10,1,no,0,0,0,misc,3,	GS_GROUNDDRIFT,Ground Drift
 522,0,0,0,0,0,0,10,1,no,0,0,0,weapon,0,		NJ_TOBIDOUGU,Shuriken Training
 523,9,6,1,-1,0x40,0,10,1,no,0,0,0,weapon,0,	NJ_SYURIKEN,Throw Shuriken
 524,9,8,1,-1,0x40,0,5,3,no,0,0,0,weapon,0,	NJ_KUNAI,Throw Kunai
@@ -587,7 +587,7 @@
 541,9,6,2,4,0x2,2:2:3:3:4,5,1,yes,0,0,0,magic,0,	NJ_RAIGEKISAI,Lightning Strike of Destruction
 542,9,8,1,4,0,3,5,1,yes,0,0,5:6:7:8:9,magic,0,	NJ_KAMAITACHI,Kamaitachi
 543,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,		NJ_NEN,Soul
-544,-5,8,1,0,0x40,0,10,1,no,0,0,0,weapon,0,	NJ_ISSEN,Final Strike
+544,-5,8,1,0,0x40,0,10,1,no,0,0,0,misc,0,	NJ_ISSEN,Final Strike
 
 // Additional NPC Skills (Episode 11.3)
 653,0,8,4,0,0x6,5:7:9:11:13:5:7:9:11:13,10,1,no,0,0x2,0,magic,0,	NPC_EARTHQUAKE,Earthquake

Разлика између датотеке није приказан због своје велике величине
+ 702 - 378
src/map/battle.c


+ 4 - 0
src/map/battle.h

@@ -16,11 +16,15 @@ typedef enum damage_lv {
 
 // dammage structure
 struct Damage {
+#ifdef RENEWAL
+	int statusAtk, statusAtk2, weaponAtk, weaponAtk2, equipAtk, equipAtk2, masteryAtk, masteryAtk2;
+#endif
 	int damage,damage2; //right, left dmg
 	int type,div_; //chk clif_damage for type @TODO add an enum ? ;  nb of hit
 	int amotion,dmotion;
 	int blewcount; //nb of knockback
 	int flag; //chk BF_* flag, (enum below)
+	int miscflag; //
 	enum damage_lv dmg_lv;	//ATK_LUCKY,ATK_FLEE,ATK_DEF
 };
 

+ 3 - 2
src/map/map.h

@@ -301,7 +301,8 @@ enum {
 	ELE_DARK,
 	ELE_GHOST,
 	ELE_UNDEAD,
-	ELE_MAX
+	ELE_MAX,
+	ELE_NONE
 };
 
 enum mob_ai {
@@ -407,7 +408,7 @@ enum _sp {
 	SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082
 	SP_DELAYRATE,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085
 	SP_IGNORE_MDEF_RATE,SP_IGNORE_DEF_RATE,SP_SKILL_HEAL2,SP_ADDEFF_ONSKILL, //1086-1089
-	SP_ADD_HEAL_RATE,SP_ADD_HEAL2_RATE, //1090-1091
+	SP_ADD_HEAL_RATE,SP_ADD_HEAL2_RATE, SP_EQUIP_ATK, //1090-1092
 
 	SP_RESTART_FULL_RECOVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005
 	SP_NO_CASTCANCEL2,SP_NO_MISC_DAMAGE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010

+ 4 - 4
src/map/pc.c

@@ -2094,12 +2094,12 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
 			break;
 		case SP_BASE_ATK:
 			if(sd->state.lr_flag != 2) {
-	//#ifdef RENEWAL
-	//            sd->bonus.eatk += val;
-	//#else
+	#ifdef RENEWAL
+	            sd->bonus.eatk += val;
+	#else
 				bonus = status->batk + val;
 				status->batk = cap_value(bonus, 0, USHRT_MAX);
-	//#endif
+	#endif
 			}
 			break;
 		case SP_DEF1:

+ 3 - 3
src/map/pc.h

@@ -356,7 +356,7 @@ struct map_session_data {
 		int fixcastrate,varcastrate;
 		int add_fixcast,add_varcast;
 		int ematk; // matk bonus from equipment
-//		int eatk; // atk bonus from equipment
+		int eatk; // atk bonus from equipment
 	} bonus;
 
 	// zeroed vars end here.
@@ -694,13 +694,13 @@ struct {
 // clientside display macros (values to the left/right of the "+")
 #ifdef RENEWAL
 	#define pc_leftside_atk(sd) ((sd)->battle_status.batk)
-	#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk + (sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
+	#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk + (sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2 + (sd)->battle_status.eatk)
 	#define pc_leftside_def(sd) ((sd)->battle_status.def2)
 	#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)
+#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)

+ 44 - 6
src/map/skill.c

@@ -2378,7 +2378,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 	 //Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here.
 	if (sc && sc->data[SC_TRICKDEAD])
 		return 0;
-
+	
 	dmg = battle_calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF);
 
 	//Skotlex: Adjusted to the new system
@@ -3646,7 +3646,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case GS_FULLBUSTER:
 	case NJ_SYURIKEN:
 	case NJ_KUNAI:
+#ifndef RENEWAL
 	case ASC_BREAKER:
+#endif
 	case HFLI_MOON:	//[orn]
 	case HFLI_SBR44:	//[orn]
 	case NPC_BLEEDING:
@@ -3808,9 +3810,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 		status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
 		break;
 
+#ifndef RENEWAL
 	case NJ_ISSEN:
 		status_change_end(src, SC_NEN, INVALID_TIMER);
 		status_change_end(src, SC_HIDING, INVALID_TIMER);
+#endif
 		// fall through
 	case MO_EXTREMITYFIST:
 		{
@@ -4199,6 +4203,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case PA_PRESSURE:
 	case CR_ACIDDEMONSTRATION:
 	case TF_THROWSTONE:
+#ifdef RENEWAL
+	case ASC_BREAKER:
+#endif
 	case NPC_SMOKING:
 	case GS_FLING:
 	case NJ_ZENYNAGE:
@@ -4206,6 +4213,36 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case GN_HELLS_PLANT_ATK:
 		skill_attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
 		break;
+#ifdef RENEWAL
+	case NJ_ISSEN: // teleport for Issen
+		{
+			status_change_end(bl, SC_NEN, INVALID_TIMER);
+			status_change_end(bl, SC_HIDING, INVALID_TIMER);
+		
+			short x, y, i = 2; // Move 2 cells for Issen(from target)
+			struct block_list *mbl = bl;
+			short dir = 0;
+
+			skill_attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
+
+			status_set_hp(src,max(status_get_max_hp(src)/100, 1),0);
+
+			dir = map_calc_dir(src,bl->x,bl->y);
+			if( dir > 0 && dir < 4) x = -i;
+			else if( dir > 4 ) x = i;
+			else x = 0;
+			if( dir > 2 && dir < 6 ) y = -i;
+			else if( dir == 7 || dir < 2 ) y = i;
+			else y = 0;
+			if( (mbl == src || (!map_flag_gvg(src->m) && !map[src->m].flag.battleground) ) && // only NJ_ISSEN don't have slide effect in GVG
+				unit_movepos(src, mbl->x+x, mbl->y+y, 1, 1) ) {
+				clif_slide(src, src->x, src->y);
+				//uncomment this if you want to remove MO_EXTREMITYFIST glitchy walking effect. [malufett]
+				//clif_fixpos(src);
+			}
+		}
+		break;
+#endif
 	/**
 	 * Rune Knight
 	 **/
@@ -5523,6 +5560,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		clif_skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,src,type,100,skill_lv,i)); // Homunc
 		break;
 	case NJ_BUNSINJYUTSU:
+		status_change_end(bl, SC_BUNSINJYUTSU, INVALID_TIMER); // on official recasting cancels existing mirror image [helvetica]
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,
 			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
 		status_change_end(bl, SC_NEN, INVALID_TIMER);
@@ -15234,23 +15272,23 @@ static int skill_trap_splash (struct block_list *bl, va_list ap)
 			skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,ATK_DEF,tick);
 			break;
 		case UNT_GROUNDDRIFT_WIND:
-			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+			if(skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
 				sc_start(ss,bl,SC_STUN,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
 			break;
 		case UNT_GROUNDDRIFT_DARK:
-			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+			if(skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
 				sc_start(ss,bl,SC_BLIND,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
 			break;
 		case UNT_GROUNDDRIFT_POISON:
-			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+			if(skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
 				sc_start(ss,bl,SC_POISON,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
 			break;
 		case UNT_GROUNDDRIFT_WATER:
-			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+			if(skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
 				sc_start(ss,bl,SC_FREEZE,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
 			break;
 		case UNT_GROUNDDRIFT_FIRE:
-			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
+			if(skill_attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
 				skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0);
 			break;
 		case UNT_ELECTRICSHOCKER:

+ 49 - 8
src/map/status.c

@@ -1886,7 +1886,7 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
 	// [Skotlex]
 #ifdef RENEWAL
 	if (bl->type == BL_HOM) {
-		//str = ((rstr + dex + status->luk) / 3) + (((TBL_HOM*)bl)->homunculus.level / 10);
+		// str = ((rstr + dex + status->luk) / 3) + (((TBL_HOM*)bl)->homunculus.level / 10);
 		str = (((rstr + dex + status->luk) / 3) + (((TBL_HOM*)bl)->homunculus.level / 10))*2; //Because Renewal ATK isn't implemented we adjust the actual ATK until it is
 		return cap_value(str, 0, USHRT_MAX);
 	}
@@ -1903,6 +1903,18 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
 	return cap_value(str, 0, USHRT_MAX);
 }
 
+#ifdef RENEWAL
+unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status)
+{
+	float str = status->str;
+
+	if (wa.range > 1)
+		str = status->dex;
+
+	return wa.atk + wa.atk2 + wa.atk * (str/200);
+}
+#endif
+
 #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); }
@@ -2711,15 +2723,20 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 	i = status->luk + sd->status.luk + sd->param_bonus[5] + sd->param_equip[5];
 	status->luk = cap_value(i,0,USHRT_MAX);
 
-// ------ BASE ATTACK CALCULATION ------
+// ------ ATTACK CALCULATION ------
 
-	// Base batk value is set on status_calc_misc
+	// Base batk value is set in status_calc_misc
+#ifndef RENEWAL
 	// weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?)
 	if (sd->status.weapon < MAX_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
 		status->batk += sd->weapon_atk[sd->status.weapon];
 	// Absolute modifiers from passive skills
 	if((skill=pc_checkskill(sd,BS_HILTBINDING))>0)
 		status->batk += 4;
+#else
+	status->watk = (status_weapon_atk(status->lhw, status) >= 0) ? status_weapon_atk(status->lhw, status) : 0;
+	status->eatk = (sd->bonus.eatk >= 0) ? sd->bonus.eatk : 0;
+#endif
 
 // ----- HP MAX CALCULATION -----
 
@@ -3907,6 +3924,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
 		 **/
 		status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl));
 		if( bl->type&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 ){
 				status->matk_max += sd->bonus.ematk;
@@ -3915,12 +3935,33 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
 			status->matk_min = status_calc_ematk(bl, sc, status->matk_min);
 			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( 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;
+			
+			if(b_status->lhw.matk) {
+				if (sd) {
+					sd->state.lr_flag = 1;
+					status->lhw.matk = b_status->lhw.matk;
+					sd->state.lr_flag = 0;
+				} else {
+					status->lhw.matk = b_status->lhw.matk;
+				}
+			}
+						
+			if(b_status->rhw.matk) {
+				status->rhw.matk = b_status->rhw.matk;
+			}
+			
+			if(status->rhw.matk) {
+				wMatk += status->rhw.matk;
+				variance += wMatk * status->rhw.wlv / 10;
+			}
+			
+			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;
 		}
 #endif
 		if (bl->type&BL_PC && sd->matk_rate != 100) {

+ 5 - 0
src/map/status.h

@@ -1622,6 +1622,10 @@ struct status_data {
 	unsigned short
 		str, agi, vit, int_, dex, luk,
 		batk,
+#ifdef RENEWAL
+		watk,
+		eatk,
+#endif
 		matk_min, matk_max,
 		speed,
 		amotion, adelay, dmotion;
@@ -1847,6 +1851,7 @@ 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 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
 

Неке датотеке нису приказане због велике количине промена