Ver código fonte

* Added new bonuses bHealPower and bHealPower2.
* Heal skills code clean up.
- bSkillHeal can affect offensive heal now.
- bSkillHeal2 can affect AppleIdun and SlimPitcher now.

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

Inkfish 16 anos atrás
pai
commit
ac5aa55ae7
10 arquivos alterados com 82 adições e 77 exclusões
  1. 4 0
      Changelog-Trunk.txt
  2. 2 0
      db/const.txt
  3. 8 8
      db/item_db.txt
  4. 3 5
      src/map/battle.c
  5. 1 0
      src/map/map.h
  6. 10 2
      src/map/pc.c
  7. 1 0
      src/map/pc.h
  8. 50 61
      src/map/skill.c
  9. 1 1
      src/map/skill.h
  10. 2 0
      src/map/status.c

+ 4 - 0
Changelog-Trunk.txt

@@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 09/05/29
+	* Added new bonuses bHealPower and bHealPower2. [Inkfish]
+	* Heal skills code clean up. [Inkfish]
+	- bSkillHeal can affect offensive heal now. 
+	- bSkillHeal2 can affect AppleIdun and SlimPitcher now.
 	* Added new bonuses bUnbreakableGarment and bUnbreakableShoes. [Inkfish]
 	* Some more fixes to skill condition issues. [Inkfish]
 	- Fixed skills fail when MAX_INVENTORY reached.

+ 2 - 0
db/const.txt

@@ -383,6 +383,8 @@ bIgnoreMdefRate	1086
 bIgnoreDefRate	1087
 bSkillHeal2	1088
 bAddEffOnSkill	1089
+bHealPower	1090
+bHealPower2	1091
 
 bRestartFullRecover	2000
 bNoCastCancel	2001

+ 8 - 8
db/item_db.txt

@@ -843,7 +843,7 @@
 1622,Hypnotist's_Staff_,Hypnotist's Staff,4,20,,500,70,,1,2,0x00000001,7,2,2,3,30,1,10,{ bonus bInt,1; bonus bMatkRate,25; },{},{}
 1623,Mighty_Staff_C,Refined Mighty Staff,4,1,,700,165,,1,0,0x00818314,7,2,2,3,1,0,10,{ bonus bStr,10; bonus bInt,4; bonus bMatkRate,20; bonus bSPDrainValue,-1; },{},{}
 1624,Lich_Bone_Wand,Lich's Bone Wand,4,20,,800,60,,1,2,0x00018314,2,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; bonus bMatkRate,20; bonus3 bAutoSpellWhenHit,"NPC_WIDECURSE",5,10+getrefine(); if(getrefine()>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}
-1625,Healing_Staff,Recovery Staff,4,20,,400,10,,1,0,0x00008110,7,2,2,3,55,1,10,{ bonus bAtkEle,Ele_Holy; bonus bMatkRate,15; bonus2 bSkillAtk,"AL_HEAL",(getrefine()*3/2); bonus2 bSkillHeal,"AL_HEAL",(getrefine()*3/2); bonus2 bSkillAtk,"PR_SANCTUARY",(getrefine()*3/2); bonus2 bSkillHeal,"PR_SANCTUARY",(getrefine()*3/2); },{},{}
+1625,Healing_Staff,Recovery Staff,4,20,,400,10,,1,0,0x00008110,7,2,2,3,55,1,10,{ bonus bAtkEle,Ele_Holy; bonus bMatkRate,15; bonus bHealPower,(getrefine()*3/2); },{},{}
 1626,Piercing_Staff,Staff of Piercing,4,20,,500,80,,1,0,0x00018314,2,2,2,3,70,1,10,{ bonus bInt,4; bonus bMatkRate,15; bonus bIgnoreMdefRate,10+getrefine(); },{},{}
 1627,Staffy,Staffy,4,20,,0,120,,1,0,0x00818314,7,2,2,1,1,0,10,{ bonus bMatkRate,15; bonus2 bAddRace,RC_Boss,50; bonus2 bAddRace,RC_NonBoss,50; },{},{}
 1628,Survival_Rod_C,Refined Survivor's Rod,4,1,,0,71,,1,0,0x00818314,7,2,2,3,1,0,10,{ bonus bDex,4; bonus bMatkRate,20; bonus bMaxHP,500; },{},{}
@@ -852,14 +852,14 @@
 1631,Holy_Stick,Holy Stick,4,20,,500,50,,1,1,0x00008100,7,2,2,4,70,1,10,{ bonus bAtkEle,Ele_Holy; bonus bMatkRate,15; bonus2 bCastrate,156,-25; bonus2 bCastrate,77,-25; bonus2 bCastrate,79,-25; },{},{}
 1632,Warlock's_Magic_Wand,Warlock's Magic Wand,4,0,,0,70,,1,0,0x00818314,7,2,2,3,80,1,10,{ bonus bint,4; bonus bDex,3; bonus bMatkRate,15; bonus2 bIgnoreMdefRate,RC_DemiHuman,25; bonus3 bAddEff,Eff_Stun,500,ATF_SKILL; bonus bUnbreakableWeapon,0; },{},{}
 1633,Warlock's_Battle_Wand,Warlock's Battle Wand,4,0,,0,70,,1,0,0x00818314,7,2,2,3,80,1,10,{ bonus bInt,3; bonus bDex,3; bonus bMatkRate,15; bonus2 bMagicAddRace,RC_DemiHuman,15; bonus3 bAddEff,Eff_Stun,500,ATF_SKILL; bonus bUnbreakableWeapon,0; },{},{}
-1634,Strong_Recovery_Wand,Strong Recovery Wand,4,0,,0,70,,1,0,0x00818314,7,2,2,3,80,1,10,{ bonus bMatkRate,15; bonus2 bSkillAtk,"AL_HEAL",14; bonus2 bSkillHeal,"AL_HEAL",14; bonus2 bSkillAtk,"PR_SANCTUARY",14; bonus2 bSkillHeal,"PR_SANCTUARY",14; bonus2 bSPRegenRate,5,10000; bonus bUnbreakableWeapon,0; },{},{}
+1634,Strong_Recovery_Wand,Strong Recovery Wand,4,0,,0,70,,1,0,0x00818314,7,2,2,3,80,1,10,{ bonus bMatkRate,15; bonus2 bSkillHeal,"AL_HEAL",14; bonus2 bSkillHeal,"PR_SANCTUARY",14; bonus2 bSPRegenRate,5,10000; bonus bUnbreakableWeapon,0; },{},{}
 1635,Speedy_Recovery_Wand,Speedy Recovery Wand,4,0,,0,70,,1,0,0x00818314,7,2,2,3,80,1,10,{ bonus bInt,3; bonus bDex,2; bonus bMatkRate,15; bonus bDelayRate,-15; bonus2 bSPRegenRate,5,10000; bonus bUnbreakableWeapon,0; },{},{}
 1636,Dark_Thorn_Staff,Thorn Staff of Darkness,4,20,,700,60,,1,0,0x00018314,2,2,34,4,75,1,10,{ bonus bInt,3; bonus bDex,3; bonus bMatkRate,20; bonus bIgnoreMdefRate,getrefine(); bonus bDelayRate,-(getrefine()); },{},{}
 //1637#Eraser#
-1638,Healing_Staff_,Healing Staff,4,20,,400,10,,1,0,0x00008110,7,2,2,3,55,1,10,{ bonus bAtkEle,Ele_Holy; bonus bMatkRate,15; bonus2 bSkillAtk,"AL_HEAL",(getrefine()*3/2); bonus2 bSkillHeal,"AL_HEAL",(getrefine()*3/2); bonus2 bSkillAtk,"PR_SANCTUARY",(getrefine()*3/2); bonus2 bSkillHeal,"PR_SANCTUARY",(getrefine()*3/2); },{},{}
+1638,Healing_Staff_,Healing Staff,4,20,,400,10,,1,0,0x00008110,7,2,2,3,55,1,10,{ bonus bAtkEle,Ele_Holy; bonus bMatkRate,15; bonus2 bSkillHeal,"AL_HEAL",(getrefine()*3/2); bonus2 bSkillHeal,"PR_SANCTUARY",(getrefine()*3/2); },{},{}
 1639,Novice_Rod,Novice_Rod,4,1,,0,15,,1,0,0x00818315,7,2,2,1,1,0,10,{ bonus bMatkRate,16; },{},{}
 1640,Glorious_Arc_Wand,Glorious Arc Wand,4,0,,0,70,,1,0,0x00018314,7,2,2,4,80,1,10,{ bonus bMatkRate,15 + getrefine(); bonus2 bMagicAddRace,RC_DemiHuman,15; bonus2 bIgnoreMdefRate,RC_DemiHuman,25; bonus bUnbreakableWeapon,0; if(getrefine() > 5) bonus2 bIgnoreMdefRate,RC_DemiHuman,5; if(getrefine() > 8) { bonus bMatkRate,5; bonus bCastrate,-5; bonus bDelayRate,-5; } },{},{}
-1641,Glorious_Staff_of_Recovery,Glorious Staff of Recovery,4,0,,0,70,,1,0,0x00018314,7,2,2,4,80,1,10,{ bonus bMatkRate,15; bonus2 bSkillAtk,"AL_HEAL",14; bonus2 bSkillHeal,"AL_HEAL",14; bonus2 bSkillAtk,"PR_SANCTUARY",14; bonus2 bSkillHeal,"PR_SANCTUARY",14; bonus bDelayRate,-10; bonus bUnbreakableWeapon,0; if(getrefine() > 5) { bonus2 bSkillAtk,"AL_HEAL",5; bonus2 bSkillHeal,"AL_HEAL",5; bonus2 bSkillAtk,"PR_SANCTUARY",5; bonus2 bSkillHeal,"PR_SANCTUARY",5; } if(getrefine() > 8) bonus5 bAutoSpellOnSkill,"AL_HEAL","AL_HEAL",10,100,1; if(getrefine() > 9) { bonus2 bSkillAtk,"AL_HEAL",10; bonus2 bSkillHeal,"AL_HEAL",10; bonus2 bSkillAtk,"PR_SANCTUARY",10; bonus2 bSkillHeal,"PR_SANCTUARY",10; } },{},{}
+1641,Glorious_Staff_of_Recovery,Glorious Staff of Recovery,4,0,,0,70,,1,0,0x00018314,7,2,2,4,80,1,10,{ bonus bMatkRate,15; bonus2 bSkillHeal,"AL_HEAL",14; bonus2 bSkillHeal,"PR_SANCTUARY",14; bonus bDelayRate,-10; bonus bUnbreakableWeapon,0; if(getrefine() > 5) { bonus2 bSkillHeal,"AL_HEAL",5; bonus2 bSkillHeal,"PR_SANCTUARY",5; } if(getrefine() > 8) bonus5 bAutoSpellOnSkill,"AL_HEAL","AL_HEAL",10,100,1; if(getrefine() > 9) { bonus2 bSkillHeal,"AL_HEAL",10; bonus2 bSkillHeal,"PR_SANCTUARY",10; } },{},{}
 // Bows
 1701,Bow,Bow,4,1000,,500,15,,5,3,0x000A0848,7,2,34,1,4,1,11,{},{},{}
 1702,Bow_,Bow,4,1000,,500,15,,5,4,0x000A0848,7,2,34,1,4,1,11,{},{},{}
@@ -1236,13 +1236,13 @@
 2371,G_Strings_,Pantie,5,1000,,100,,4,,1,0xFFFFFFFF,7,2,16,,0,1,0,{},{},{}
 2372,Mage_Coat_,Mage Coat,5,20,,600,,5,,1,0x00810204,7,2,16,,50,1,0,{ bonus bMdef,5; bonus bInt,1; },{},{}
 2373,Holy_Robe_,Holy Robe,5,20,,1700,,7,,1,0x00008110,7,2,16,,60,1,0,{ bonus bMdef,5; bonus2 bSubRace,RC_Demon,15; bonus2 bSubEle,Ele_Dark,10; },{},{}
-2374,Lucifer_Robe,Diabolus Robe,5,20,,300,,6,,1,0x00098B1C,2,2,16,,55,1,0,{ bonus bMaxSP,150; bonus bMdef,5; bonus2 bSkillAtk,"AL_HEAL",6; bonus2 bSkillheal,"AL_HEAL",6; bonus bDelayRate,-10; if (isequipped(2729)) { bonus bAtkRate,3; bonus bMatkRate,3; } },{},{}
+2374,Lucifer_Robe,Diabolus Robe,5,20,,300,,6,,1,0x00098B1C,2,2,16,,55,1,0,{ bonus bMaxSP,150; bonus bMdef,5; bonus2 bSkillheal,"AL_HEAL",6; bonus bDelayRate,-10; if (isequipped(2729)) { bonus bAtkRate,3; bonus bMatkRate,3; } },{},{}
 2375,Lucifer_Armor,Diabolus Armor,5,20,,600,,7,,1,0x000654E2,2,2,16,,55,1,0,{ bonus bStr,2; bonus bDex,1; bonus bMaxHP,150; bonus2 bResEff,Eff_Stun,500; bonus2 bResEff,Eff_Stone,500; if (isequipped(2729)) { bonus bAtkRate,3; bonus bMatkRate,3; } },{},{}
 2376,Assaulter_Plate,Assaulter Plate,5,0,,0,,7,,1,0x006444A2,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2538) && isequipped(2435)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bVit,3; bonus bMaxHPRate,12; bonus2 bSkillHeal2,"AL_HEAL",10; bonus2 bAddItemHealRate,IG_Recovery,10; bonusautoscript2 "{ sc_start4 SC_HPREGEN,10000,600,1,0,0; }",50,BF_WEAPON; }; },{},{}
 2377,Elite_Engineer_Armor,Elite Engineer Armor,5,0,,0,,7,,1,0x00040420,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2538) && isequipped(2435)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bStr,3; bonus bMaxHPRate,12; bonus2 bSkillAtk,"MC_MAMMONITE",20; bonus2 bSkillHeal,"AM_POTIONPITCHER",10; bonus2 bSkillHeal2,"AM_POTIONPITCHER",10; bonus2 bSkillHeal2,"AL_HEAL",10; bonus bUnbreakableArmor,0; }; },{},{}
 2378,Assassin_Robe,Assassin Robe,5,0,,0,,7,,1,0x02021040,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2538) && isequipped(2435)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bAgi,3; bonus bMaxHPRate,12; bonus bCriticalRate,5; bonus bAspdRate,5; bonusautoscript "{ sc_start4 SC_HPREGEN,10000,300,1,0,0; }",50,BF_WEAPON; }; },{},{}
 2379,Warlock's_Battle_Robe,Warlock's Battle Robe,5,0,,0,,3,,1,0x00810204,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2539) && isequipped(2436)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bInt,3; bonus bMaxHPRate,12; bonus2 bResEff,Eff_Stun,2000; bonusautoscript2 "{ sc_start4 SC_ELEMENTALCHANGE,10000,1,Ele_Ghost,1,0; }",50,BF_WEAPON; }; },{},{}
-2380,Medic's_Robe,Medic's Robe,5,0,,0,,3,,1,0x00008110,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2539) && isequipped(2436)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bInt,3; bonus bMaxHPRate,12; bonus2 bcastRate,156,-50; bonus2 bSkillAtk,"AL_HEAL",6; bonus2 bSkillHeal,"AL_HEAL",6; bonus2 bSkillAtk,"PR_SANCTUARY",6; bonus2 bSkillHeal,"PR_SANCTUARY",6; bonusautoscript2 "{ sc_start4 SC_ELEMENTALCHANGE,10000,1,Ele_Ghost,1,0; }",50,BF_WEAPON; }; },{},{}
+2380,Medic's_Robe,Medic's Robe,5,0,,0,,3,,1,0x00008110,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2539) && isequipped(2436)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bInt,3; bonus bMaxHPRate,12; bonus2 bcastRate,156,-50; bonus2 bSkillHeal,"AL_HEAL",6; bonus2 bSkillHeal,"PR_SANCTUARY",6; bonusautoscript2 "{ sc_start4 SC_ELEMENTALCHANGE,10000,1,Ele_Ghost,1,0; }",50,BF_WEAPON; }; },{},{}
 2381,Elite_Archer_Suit,Elite Archer Suit,5,0,,0,,3,,1,0x00080808,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2539) && isequipped(2436)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bDex,3; bonus bMaxHPRate,12; bonus bLongAtkDef,10; bonus bDelayRate,-25; }; },{},{}
 2382,Elite_Shooter_Suit,Elite Shooter Suit,5,0,,0,,3,,1,0x01000000,7,2,16,,80,1,0,{ bonus bMaxHP,150; bonus bMdef,2; bonus2 bSubRace,RC_DemiHuman,2; if (isequipped(2540) && isequipped(2437)) { bonus2 bSubRace,RC_NonDemiHuman,-300; bonus bDex,3; bonus bMaxHPRate,12; bonus bLongAtkDef,10; bonus bDelayRate,-25; }; },{},{}
 2383,Brynhild,Brynhild,5,0,,400,,,,0,0xFFFFFFFF,7,2,16,,94,0,0,{ bonus bMdef,10; bonus bMaxHP,20*BaseLevel; bonus bMaxSP,5*BaseLevel; bonus2 bAddRace,RC_NonBoss,10; bonus2 bAddRace,RC_Boss,10; bonus bMatkRate,10; bonus bUnbreakableArmor,0; bonus bNoKnockback,0; },{},{}
@@ -1485,7 +1485,7 @@
 2726,Icarus_Wing,Icarus Wings,5,20,,100,,0,,0,0x00000800,2,2,136,,70,0,0,{ bonus bMaxSP,50; bonus bDex,3; },{},{}
 2727,Bowman_Scarf,Bowman Scarf,5,20,,200,,0,,0,0x00000800,2,2,136,,0,0,0,{ bonus bMaxSP,50; bonus bDex,3; if (isequipped(2726)) bonus bUseSPrate,-25; },{},{}
 2728,Morroc_Skin1,Cursed Hand,5,0,,50,,0,,1,0xFFFFFFFE,7,2,136,,80,0,0,{ bonus3 bAutoSpell,"NPC_CRITICALWOUND",1,30; bonus bHit,10; bonus bHPrecovRate,20; },{},{}
-2729,Lucifer_Ring,Diabolus Ring,5,0,,50,,0,,1,0x000FDF80,2,2,136,,0,0,0,{ bonus bMaxHP,100; bonus bMaxSP,100; bonus2 bSkillAtk,"AL_HEAL",5; bonus2 bSkillheal,"AL_HEAL",5; bonus2 bAddDamageClass,1916,10; bonus2 bAddDamageClass,1917,10; },{},{}
+2729,Lucifer_Ring,Diabolus Ring,5,0,,50,,0,,1,0x000FDF80,2,2,136,,0,0,0,{ bonus bMaxHP,100; bonus bMaxSP,100; bonus2 bSkillheal,"AL_HEAL",5; bonus2 bAddDamageClass,1916,10; bonus2 bAddDamageClass,1917,10; },{},{}
 2730,Morroc_Seal,Continental Guard Seal,5,0,,50,,0,,1,0xFFFFFFFE,7,2,136,,80,0,0,{ bonus bMaxHP,50; bonus bAspdRate,3; },{},{}
 2731,Morroc_Charm_Stone,Rune Charm Stone,5,0,,50,,0,,1,0xFFFFFFFE,7,2,136,,80,0,0,{ bonus bMaxSP,50; bonus bCastRate,-1; },{},{}
 2732,Morroc_Ring,Death Medalion,5,0,,50,,0,,1,0xFFFFFFFE,7,2,136,,80,0,0,{ bonus bCritical,5; },{},{}
@@ -1902,7 +1902,7 @@
 4369,Venatu_Card,Venatu Card,6,20,,10,,,,,,,,16,,,,,{ bonus bLuk,readparam(bAgi)/18; },{},{}
 4370,Dimik_Card,Dimik Card,6,20,,10,,,,,,,,16,,,,,{ bonus bVit,getrefine()-5; },{},{}
 4371,Archdam_Card,Archdam Card,6,20,,10,,,,,,,,16,,,,,{ bonus bBaseAtk,10; bonus bCastrate,20; if(isequipped(4311,4319,4331)) { bonus bInt,1; bonus bStr,1; bonus bDef,2; bonus bSPrecovRate,10; bonus2 bSkillAtk,"PA_SHIELDCHAIN",10; bonus2 bSkillAtk,"PA_SACRIFICE",10; bonus bCastrate,-10; if(BaseJob == Job_Crusader) { bonus bDefEle,Ele_Holy; } } },{},{}
-4372,Bacsojin_Card,Bacsojin Card,6,20,,10,,,,,,,,769,,,,,{ bonus2 bSkillAtk,"AL_HEAL",30; bonus2 bSkillHeal,"AL_HEAL",30; bonus2 bSkillAtk,"PR_SANCTUARY",30; bonus2 bSkillHeal,"PR_SANCTUARY",30; bonus2 bSkillHeal,"AM_POTIONPITCHER",30; bonus bUseSPrate,15; },{},{}
+4372,Bacsojin_Card,Bacsojin Card,6,20,,10,,,,,,,,769,,,,,{ bonus bHealPower,30; bonus bUseSPrate,15; },{},{}
 4373,Chung_E_Card,Chung E Card,6,20,,10,,,,,,,,4,,,,,{ bonus bLuk,getrefine()-5; bonus bCritical,getrefine(); },{},{}
 4374,Apocalips_H_Card,Vesper Card,6,20,,10,,,,,,,,769,,,,,{ bonus bDex,2; bonus2 bIgnoreMdefRate,RC_Boss,30; },{},{}
 4375,Orc_Baby_Card_Card,Orc Baby Card,6,20,,10,,,,,,,,4,,,,,{ if(getrefine()>=9) { bonus2 bSubEle,Ele_Neutral,15; bonus bFlee,15; } else { bonus2 bSubEle,Ele_Neutral,10; bonus bFlee,10; } },{},{}

+ 3 - 5
src/map/battle.c

@@ -2279,14 +2279,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 		{	//Calc base damage according to skill
 			case AL_HEAL:
 			case PR_BENEDICTIO:
-				ad.damage = skill_calc_heal(src, target, skill_lv)/2;
+			case PR_SANCTUARY:
+				ad.damage = skill_calc_heal(src, target, skill_num, skill_lv)/2;
 				break;
 			case PR_ASPERSIO:
 				ad.damage = 40;
 				break;
-			case PR_SANCTUARY:
-				ad.damage = (skill_lv>6)?388:skill_lv*50;
-				break;
 			case ALL_RESURRECTION:
 			case PR_TURNUNDEAD:
 				//Undead check is on skill_castend_damageid code.
@@ -2673,7 +2671,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 		md.dmotion = 0; //No flinch animation.
 		break;
 	case NPC_EVILLAND:
-		md.damage = (skill_lv>6)?666:skill_lv*100;
+		md.damage = skill_calc_heal(src,target,skill_num,skill_lv);
 		break;
 	}
 

+ 1 - 0
src/map/map.h

@@ -308,6 +308,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_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

+ 10 - 2
src/map/pc.c

@@ -2179,6 +2179,14 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
 		if(!sd->state.lr_flag)
 			sd->hp_gain_value += val;
 		break;
+	case SP_ADD_HEAL_RATE:
+		if(sd->state.lr_flag != 2)
+			sd->add_heal_rate += val;
+		break;
+	case SP_ADD_HEAL2_RATE:
+		if(sd->state.lr_flag != 2)
+			sd->add_heal2_rate += val;
+		break;
 	default:
 		ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
 		break;
@@ -5235,7 +5243,7 @@ int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
 
 int pc_skillheal_bonus(struct map_session_data *sd, int skill_num)
 {
-	int i, bonus = 0;
+	int i, bonus = sd->add_heal_rate;
 
 	ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == skill_num);
 	if( i < ARRAYLENGTH(sd->skillheal) ) bonus += sd->skillheal[i].val;
@@ -5245,7 +5253,7 @@ int pc_skillheal_bonus(struct map_session_data *sd, int skill_num)
 
 int pc_skillheal2_bonus(struct map_session_data *sd, int skill_num)
 {
-	int i, bonus = 0;
+	int i, bonus = sd->add_heal2_rate;
 
 	ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == skill_num);
 	if( i < ARRAYLENGTH(sd->skillheal2) ) bonus += sd->skillheal2[i].val;

+ 1 - 0
src/map/pc.h

@@ -267,6 +267,7 @@ struct map_session_data {
 	
 	short splash_range, splash_add_range;
 	short add_steal_rate;
+	short add_heal_rate, add_heal2_rate;
 	short sp_gain_value, hp_gain_value;
 	short sp_vanish_rate;
 	short sp_vanish_per;	

+ 50 - 61
src/map/skill.c

@@ -269,32 +269,59 @@ int skill_get_range2 (struct block_list *bl, int id, int lv)
 	return range;
 }
 
-int skill_calc_heal (struct block_list *src, struct block_list *target, int skill_lv)
+int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_id, int skill_lv)
 {
 	int skill, heal;
+	struct map_session_data *sd = map_id2sd(src->id);
+	struct map_session_data *tsd = map_id2sd(target->id);
 	struct status_change* sc;
 
-	if (skill_lv >= battle_config.max_heal_lv)
-		return battle_config.max_heal;
-
-	heal = ( status_get_lv(src)+status_get_int(src) )/8 *(4+ skill_lv*8);
-	if(src->type == BL_PC && ((skill = pc_checkskill((TBL_PC*)src, HP_MEDITATIO)) > 0))
-		heal += heal * skill * 2 / 100;
+	switch( skill_id )
+	{
+	case BA_APPLEIDUN:
+		heal = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+		if( sd )
+			heal += 5*pc_checkskill(sd,BA_MUSICALLESSON);
+		break;
+	case PR_SANCTUARY:
+		heal = (skill_lv>6)?777:skill_lv*100;
+		break;
+	case NPC_EVILLAND:
+		heal = (skill_lv>6)?666:skill_lv*100;
+		break;
+	default:
+		if (skill_lv >= battle_config.max_heal_lv)
+			return battle_config.max_heal;
 
-	if(src->type == BL_HOM && (skill = merc_hom_checkskill(((TBL_HOM*)src), HLIF_BRAIN)) > 0)
-		heal += heal * skill * 2 / 100;
+		heal = ( status_get_lv(src)+status_get_int(src) )/8 *(4+ skill_lv*8);
+		if( sd && ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) )
+			heal += heal * skill * 2 / 100;
+		else if( src->type == BL_HOM && (skill = merc_hom_checkskill(((TBL_HOM*)src), HLIF_BRAIN)) > 0 )
+			heal += heal * skill * 2 / 100;
+		break;
+	}
 
-	if(target && target->type == BL_MER)
+	//FIXME: Is NPC_EVILLAND or BA_APPLEIDUN really an exception or we failed to add them to the original code? [Inkfish]
+	if( target && target->type == BL_MER && skill_id != NPC_EVILLAND )
 		heal >>= 1;
 
+	if( sd && (skill = pc_skillheal_bonus(sd, skill_id)) )
+		heal += heal*skill/100;
+	
+	if( tsd && (skill = pc_skillheal2_bonus(tsd, skill_id)) )
+		heal += heal*skill/100;
+
+	//FIXME: Is offensive heal affected by the following status? [Inkfish]
+	//According to the original code, HEAL is but SANCTUARY isn't. Is that true?
 	sc = status_get_sc(target);
 	if( sc && sc->count )
 	{
 		if( sc->data[SC_CRITICALWOUND] )
 			heal -= heal * sc->data[SC_CRITICALWOUND]->val2/100;
-		if( sc->data[SC_INCHEALRATE] )
+		if( sc->data[SC_INCHEALRATE] ) //FIXME: BA_APPLEIDUN not affected by this one? [Inkfish]
 			heal += heal * sc->data[SC_INCHEALRATE]->val1/100;
 	}
+
 	return heal;
 }
 
@@ -3146,22 +3173,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case HLIF_HEAL:	//[orn]
 	case AL_HEAL:
 		{
-			int heal = skill_calc_heal(src, bl, skilllv);
+			int heal = skill_calc_heal(src, bl, skillid, skilllv);
 			int heal_get_jobexp;
 
 			if( status_isimmune(bl) || (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) )
 				heal=0;
 
-			if( sd )
-			{
-				if( (i = pc_skillheal_bonus(sd, skillid)) )
-					heal += heal * i / 100;
-				if( sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0 )
-					heal = heal*2;
-			}
-
-			if( dstsd && (i = pc_skillheal2_bonus(dstsd, skillid)) )
-				heal += heal * i / 100;
+			if( sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0 )
+				heal = heal*2;
 
 			if( tsc && tsc->count )
 			{
@@ -5174,12 +5193,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			int hp = potion_hp, sp = potion_sp;
 			hp = hp * (100 + (tstatus->vit<<1))/100;
 			sp = sp * (100 + (tstatus->int_<<1))/100;
-
 			if (dstsd) {
 				if (hp)
-					hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10)/100;
+					hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10 + pc_skillheal2_bonus(dstsd, skillid))/100;
 				if (sp)
-					sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10)/100;
+					sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10 + pc_skillheal2_bonus(dstsd, skillid))/100;
 			}
 			if (tsc && tsc->data[SC_CRITICALWOUND])
 			{
@@ -5541,11 +5559,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				bl = map_id2bl(battle_gettarget(src));
 
 			if (!bl) bl = src;
-			i = skill_calc_heal( src, bl, 1+rand()%skilllv);
-			if (sd && (rnd = pc_skillheal_bonus(sd, skillid)) > 0)
-				i += i * rnd / 100;
-			if (dstsd && (rnd = pc_skillheal2_bonus(dstsd, skillid)) > 0)
-				i += i * rnd / 100;
+			i = skill_calc_heal(src, bl, skillid, 1+rand()%skilllv);
 			//Eh? why double skill packet?
 			clif_skill_nodamage(src,bl,AL_HEAL,i,1);
 			clif_skill_nodamage(src,bl,skillid,i,1);
@@ -6307,8 +6321,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
 		if (sd) {
 			int i = skilllv%11 - 1;
 			int j = pc_search_inventory(sd,skill_db[skillid].itemid[i]);
-			if(j < 0 || skill_db[skillid].itemid[i] <= 0 || sd->inventory_data[j] == NULL ||
-				sd->status.inventory[j].amount < skill_db[skillid].amount[i]) {
+			if( j < 0 || skill_db[skillid].itemid[i] <= 0 || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill_db[skillid].amount[i] )
+			{
 				clif_skill_fail(sd,skillid,0,0);
 				return 1;
 			}
@@ -6743,9 +6757,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli
 	case PR_SANCTUARY:
 	case NPC_EVILLAND:
 		val1=(skilllv+3)*2;
-		val2=(skilllv>6)?(skillid == PR_SANCTUARY?777:666):skilllv*100;
-		if (sd && (i = pc_skillheal_bonus(sd, skillid)))
-			val2 += val2 * i / 100;
 		break;
 
 	case WZ_FIREPILLAR:
@@ -6839,13 +6850,8 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli
 		break;
 	case BA_APPLEIDUN:
 		val1 = 5+2*skilllv+status->vit/10; // MaxHP percent increase
-		val2 = 30+5*skilllv+5*(status->vit/10); // HP recovery
-		if(sd){
+		if(sd)
 			val1 += pc_checkskill(sd,BA_MUSICALLESSON);
-			val2 += 5*pc_checkskill(sd,BA_MUSICALLESSON);
-			if ((i = pc_skillheal_bonus(sd, skillid)))
-				val2 += val2 * i / 100;
-		}
 		break;
 	case DC_SERVICEFORYOU:
 		val1 = 15+skilllv+(status->int_/10); // MaxSP percent increase TO-DO: this INT bonus value is guessed
@@ -7309,27 +7315,14 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 			}
 			else
 			{
-				int heal = sg->val2;
+				int heal = skill_calc_heal(ss,bl,sg->skill_id,sg->skill_lv);
 				struct mob_data *md = BL_CAST(BL_MOB, bl);
 				if( md && mob_is_battleground(md) )
 					break;
 				if( tstatus->hp >= tstatus->max_hp )
 					break;
-				if( tsc )
-				{
-					if( tsc->data[SC_INCHEALRATE] )
-						heal += heal * tsc->data[SC_INCHEALRATE]->val1 / 100;
-					if( tsc->data[SC_CRITICALWOUND] )
-						heal -= heal * tsc->data[SC_CRITICALWOUND]->val2 / 100;
-				}
-				if( tsd )
-					heal += heal * pc_skillheal2_bonus(tsd, sg->skill_id) / 100;
-
-				if( bl->type == BL_MER )
-					heal /= 2;
 				if( status_isimmune(bl) )
 					heal = 0;
-
 				clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
 				status_heal(bl, heal, 0, 0);
 				if( diff >= 500 )
@@ -7346,11 +7339,9 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 				if(battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
 					skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
 			} else {
-				int heal = sg->val2;
+				int heal = skill_calc_heal(ss,bl,sg->skill_id,sg->skill_lv);
 				if (tstatus->hp >= tstatus->max_hp)
 					break;
-				if (tsc && tsc->data[SC_CRITICALWOUND])
-					heal -= heal * tsc->data[SC_CRITICALWOUND]->val2 / 100;
 				if (status_isimmune(bl))
 					heal = 0;
 				clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
@@ -7509,9 +7500,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 			int heal;
 			if( sg->src_id == bl->id && !(tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_BARDDANCER) )
 				break; // affects self only when soullinked
-			heal = sg->val2;
-			if(tsc && tsc->data[SC_CRITICALWOUND])
-				heal -= heal * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+			heal = skill_calc_heal(ss,bl,sg->skill_id, sg->skill_lv);
 			clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
 			status_heal(bl, heal, 0, 0);
 			break;

+ 1 - 1
src/map/skill.h

@@ -318,7 +318,7 @@ void skill_identify(struct map_session_data *sd,int idx);
 void skill_weaponrefine(struct map_session_data *sd,int idx); // [Celest]
 int skill_autospell(struct map_session_data *md,int skillid);
 
-int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_lv);
+int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_id, int skill_lv);
 
 bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce);
 

+ 2 - 0
src/map/status.c

@@ -1806,6 +1806,8 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 		+ sizeof(sd->splash_range)
 		+ sizeof(sd->splash_add_range)
 		+ sizeof(sd->add_steal_rate)
+		+ sizeof(sd->add_heal_rate)
+		+ sizeof(sd->add_heal2_rate)
 		+ sizeof(sd->hp_gain_value)
 		+ sizeof(sd->sp_gain_value)
 		+ sizeof(sd->sp_vanish_rate)