Просмотр исходного кода

Bug fixes & Misc:
-- Map crashed because empty item_combo script (bugreport:8959)
-- Wrong MATK calculation of Distort Crescent/Zangetsu effect (SC_ZANGETSU) (bugreport:8998)
-- Wrong damage reduction of Sera's Pain Killer effect (SC_PAIN_KILLER) (bugreport:8994)
-- Fixed Shape Shift (NC_SHAPESHIFT) wrong requirement (bugreport:9002)
-- @itembound, getitembound usage. Not, now allowed for unspecified bound_type (thank Ceejay Abne! http://rathena.org/board/index.php?showtopic=94726)
-- Change check behavior for skill requirement level-dependent check.
-- Removed NC_REPAIR hardcoded requirement.
-- Moved the required equipped item to 'RequiredEquipment' on skill_require_db.txt.
-- Missing "Option_Ruwach" as contantan.
-- Corrected Chasewalk STR bonus, it's SC_CHASEWALK2, different with SC_INCSTR.
-- Corrected some Rebellion skill's effects.
-- USESKILL_FAIL_MADOGEAR message for failed skill that needs player has Madogear.
-- Changed skill name and description length to 31 chars.
-- Some documentation updates.
-- Follow up 0f2dd7f. (Well, using empty password in import file, won't works, if you want, empty the original conf file. Fix this later, related on 'sscanf' for those files)
-- Follow up 28c90bb, thank @julia40124009
-- Misc. :P

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>

Cydh Ramdh 11 лет назад
Родитель
Сommit
794c1a8247

+ 7 - 1
db/const.txt

@@ -1743,6 +1743,7 @@ SC__FEINTBOMB	594
 SC__CHAOS	595
 SC_ELEMENTAL_SHIELD	596
 SC_EXTREMITYFIST2	597
+SC_CHASEWALK2	598
 
 //Status Icon
 SI_BLANK	-1
@@ -1926,7 +1927,7 @@ SI_MAXSPPERCENT	178
 SI_DEFENCE	179
 SI_SLOWDOWN	180
 SI_PRESERVE	181
-SI_INCSTR	182
+SI_CHASEWALK2	182
 SI_NOT_EXTREMITYFIST	183
 SI_INTRAVISION	184
 SI_MOVESLOW_POTION	185
@@ -4598,5 +4599,10 @@ IT_AMMO	10
 IT_DELAYCONSUME	11
 IT_CASH	18
 
+Bound_Account	1
+Bound_Guild	2
+Bound_Party	3
+Bound_Char	4
+
 false	0
 true	1

+ 1 - 0
db/import-tmpl/item_flag.txt

@@ -4,3 +4,4 @@
 // <Flag>:
 // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
 // 2 - As item group container, check player's inventory and weight before consumed
+// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree

+ 1 - 0
db/pre-re/item_flag.txt

@@ -4,6 +4,7 @@
 // <Flag>:
 // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
 // 2 - As item group container, check player's inventory and weight before consumed
+// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
 
 // Logged as Dead Branch item
 604,1 //Branch_Of_Dead_Tree

+ 12 - 12
db/pre-re/skill_require_db.txt

@@ -118,7 +118,7 @@
 
 //****
 // WZ Wizard
-80,0,0,75,0,0,0,99,0,0,none,0,0,717,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//WZ_FIREPILLAR
+80,0,0,75,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,717,1,717,1,717,1,717,1,717,1,0						//WZ_FIREPILLAR
 81,0,0,35:37:39:41:43:45:47:49:51:53,0,0,0,99,0,0,none,SC_SIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//WZ_SIGHTRASHER
 83,0,0,20:24:30:34:40:44:50:54:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//WZ_METEOR
 84,0,0,20:23:26:29:32:35:38:41:44:47,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//WZ_JUPITEL
@@ -678,25 +678,25 @@
 //****
 // NC Mechanic
 2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_BOOSTKNUCKLE
-2257,0,0,50,0,0,0,99,0,0,mado,0,0,1549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_PILEBUNKER
+2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549							//NC_PILEBUNKER
 2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_VULCANARM
-2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_FLAMELAUNCHER
+2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139						//NC_FLAMELAUNCHER
 2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_COLDSLOWER
 2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ARMSCANNON
-2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ACCELERATION
-2263,0,0,25,0,0,0,99,0,0,mado,0,0,2801,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_HOVERING
+2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800					//NC_ACCELERATION
+2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801						//NC_HOVERING
 2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_F_SIDESLIDE
 2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_B_SIDESLIDE
 
-2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_SELFDESTRUCTION
-2268,0,0,100,0,0,0,99,0,0,mado,0,0,2803,0,6360,1,6363,1,6362,1,6361,1,6146,2,0,0,0,0,0,0,0,0,0			//NC_SHAPESHIFT
-2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_EMERGENCYCOOL
+2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802						//NC_SELFDESTRUCTION
+2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803			//NC_SHAPESHIFT
+2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804						//NC_EMERGENCYCOOL
 2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//NC_INFRAREDSCAN
 2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_ANALYZE
-2272,0,0,90,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_MAGNETICFIELD
-2273,0,0,90,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_NEUTRALBARRIER
-2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_STEALTHFIELD
-2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,2807,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			//NC_REPAIR
+2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805						//NC_MAGNETICFIELD
+2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806						//NC_NEUTRALBARRIER
+2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808				//NC_STEALTHFIELD
+2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807			//NC_REPAIR
 
 2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_AXEBOOMERANG
 2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_POWERSWING

+ 2 - 2
db/re/item_combo_db.txt

@@ -248,7 +248,7 @@
 15068:20710,{ bonus bAgi,5; bonus bFlee,10; }
 15088:18816:18818,{ bonus bMatk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; }
 15088:18817:18819,{ bonus bBaseAtk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; }
-15116:20743:22046,{ bonus bMaxSPrate,25; bonus bMaxSPrate,25; bonus bSpeedAddRate,n; }
+15116:20743:22046,{ bonus bMaxSPrate,25; bonus bMaxSPrate,25; bonus bSpeedAddRate,10; }
 18507:18539,{ bonus bUseSPrate,-3; }
 18538:5041,{ bonus2 bSubRace,RC_Angel,9; }
 18538:5048,{ bonus2 bSubRace,RC_Demon,9; }
@@ -260,6 +260,7 @@
 18656:5475,{ bonus bBaseAtk,30; bonus bMatk,30; bonus2 bAddMonsterDropItem,529,400; bonus2 bAddMonsterDropItem,530,400; bonus2 bAddMonsterDropItem,538,400; bonus2 bAddMonsterDropItem,12192,400;}
 18776:20710,{ bonus bBaseAtk,10; }
 18776:22015,{ bonus bMatk,20; }
+18997:28326:28327,{ bonus bSpeed,25; bonus bBaseAtk,50; bonus bMatk,50; }
 24012:24013:24014:24015:24016:24017,{ bonus bAllStats,9; }
 24018:24019:24020,{ if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) + getequiprefinerycnt(EQI_SHADOW_WEAPON) >= 23) { bonus bAtkRate,1; } }
 24021:24022:24023,{ if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) + getequiprefinerycnt(EQI_SHADOW_WEAPON) >= 23) { bonus bMatkRate,1; } }
@@ -303,5 +304,4 @@
 24150:24151,{ bonus bAtkRate,1; if (getequiprefinerycnt(EQI_SHADOW_ACC_R)+getequiprefinerycnt(EQI_SHADOW_ACC_L) >= 15) bonus bNoSizeFix,1; }
 24152:24153,{ bonus bAtk,getequiprefinerycnt(EQI_SHADOW_WEAPON); if (getequiprefinerycnt(EQI_SHADOW_WEAPON)+getequiprefinerycnt(EQI_SHADOW_ACC_R) >= 15) bonus bUnbreakableWeapon,1; }
 24154:24155,{ bonus bDef,getequiprefinerycnt(EQI_SHADOW_ARMOR); if (getequiprefinerycnt(EQI_SHADOW_ARMOR)+getequiprefinerycnt(EQI_SHADOW_ACC_L) >= 15) bonus bUnbreakableArmor,1; }
-18997:28326:28327,{ bonus bSpeed,25; bonus bBaseAtk,50; bonus bMatk,50; }
 28326:28327,{ bonus bInt,8; bonus bStr,8; }

+ 1 - 0
db/re/item_flag.txt

@@ -4,6 +4,7 @@
 // <Flag>:
 // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
 // 2 - As item group container, check player's inventory and weight before consumed
+// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
 
 // Logged as Dead Branch item
 604,1 //Branch_Of_Dead_Tree

+ 12 - 12
db/re/skill_require_db.txt

@@ -118,7 +118,7 @@
 
 //****
 // WZ Wizard
-80,0,0,75,0,0,0,99,0,0,none,0,0,717,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//WZ_FIREPILLAR
+80,0,0,75,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,717,1,717,1,717,1,717,1,717,1,0						//WZ_FIREPILLAR
 81,0,0,35:37:39:41:43:45:47:49:51:53,0,0,0,99,0,0,none,SC_SIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//WZ_SIGHTRASHER
 83,0,0,20:24:30:34:40:44:50:54:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//WZ_METEOR
 84,0,0,20:23:26:29:32:35:38:41:44:47,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//WZ_JUPITEL
@@ -678,25 +678,25 @@
 //****
 // NC Mechanic
 2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_BOOSTKNUCKLE
-2257,0,0,50,0,0,0,99,0,0,mado,0,0,1549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_PILEBUNKER
+2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549							//NC_PILEBUNKER
 2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_VULCANARM
-2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_FLAMELAUNCHER
+2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139						//NC_FLAMELAUNCHER
 2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_COLDSLOWER
 2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ARMSCANNON
-2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ACCELERATION
-2263,0,0,25,0,0,0,99,0,0,mado,0,0,2801,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_HOVERING
+2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800					//NC_ACCELERATION
+2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801						//NC_HOVERING
 2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_F_SIDESLIDE
 2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_B_SIDESLIDE
 
-2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_SELFDESTRUCTION
-2268,0,0,100,0,0,0,99,0,0,mado,0,0,2803,0,6360,1,6363,1,6362,1,6361,1,6146,2,0,0,0,0,0,0,0,0,0			//NC_SHAPESHIFT
-2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_EMERGENCYCOOL
+2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802						//NC_SELFDESTRUCTION
+2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803			//NC_SHAPESHIFT
+2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804						//NC_EMERGENCYCOOL
 2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//NC_INFRAREDSCAN
 2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_ANALYZE
-2272,0,0,90,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_MAGNETICFIELD
-2273,0,0,90,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_NEUTRALBARRIER
-2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_STEALTHFIELD
-2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,2807,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			//NC_REPAIR
+2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805						//NC_MAGNETICFIELD
+2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806						//NC_NEUTRALBARRIER
+2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808				//NC_STEALTHFIELD
+2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807			//NC_REPAIR
 
 2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_AXEBOOMERANG
 2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_POWERSWING

+ 6 - 6
doc/script_commands.txt

@@ -4353,10 +4353,10 @@ in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in
 some cases cannot be traded or stored.
 
 Valid bound types are:
- 1 - Account Bound
- 2 - Guild Bound
- 3 - Party Bound
- 4 - Character Bound
+ Bound_Account : Account Bound item
+ Bound_Guild   : Guild Bound item
+ Bound_Party   : Party Bound item
+ Bound_Char    : Character Bound item
 
 ---------------------------------------
 
@@ -4506,8 +4506,8 @@ See 'getitem2' for an explanation of the expanded parameters.
 
 *cartdelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
 *cartdelitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
-*storageitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
-*storageitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
+*storagedelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
+*storagedelitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
 
 Same like delitem2, but deletes item from cart or storage.
 If cart is not mounted, it will be failed.

+ 1 - 1
src/char/int_mail.c

@@ -184,7 +184,7 @@ static bool mail_loadmessage(int mail_id, struct mail_message* msg)
 		Sql_GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data);
 		Sql_GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10);
 		msg->item.expire_time = 0;
-		msg->item.bound = 0;
+		msg->item.bound = BOUND_NONE;
 
 		for( j = 0; j < MAX_SLOTS; j++ )
 		{

+ 1 - 1
src/char/int_storage.c

@@ -289,7 +289,7 @@ int mapif_parse_itembound_retrieve(int fd)
 		SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
 	while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) {
-		if(item.bound == 2) {
+		if(item.bound == BOUND_GUILD) {
 			memcpy(&items[i],&item,sizeof(struct item));
 			i++;
 		}

+ 10 - 0
src/common/mmo.h

@@ -785,6 +785,16 @@ enum {
 	SEX_SERVER
 };
 
+/// Item Bound Type
+enum bound_type {
+	BOUND_NONE = 0, /// No bound
+	BOUND_ACCOUNT, /// 1- Account Bound
+	BOUND_GUILD, /// 2 - Guild Bound
+	BOUND_PARTY, /// 3 - Party Bound
+	BOUND_CHAR, /// 4 - Character Bound
+	BOUND_MAX
+};
+
 // sanity checks...
 #if MAX_ZENY > INT_MAX
 #error MAX_ZENY is too big

+ 1 - 6
src/config/core.h

@@ -62,12 +62,7 @@
 /// Uncomment to enable skills damage adjustments
 /// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the
 /// damage rate of specified skills.
-//#define ADJUST_SKILL_DAMAGE
-
-/// The skill damage adjustment rate is capped at 100000.
-#ifdef ADJUST_SKILL_DAMAGE
-#define MAX_SKILL_DAMAGE_RATE 100000
-#endif
+#define ADJUST_SKILL_DAMAGE
 
 /// Uncomment to enable the job base HP/SP table (job_basehpsp_db.txt)
 //#define HP_SP_TABLES

+ 1 - 1
src/login/loginlog_sql.c

@@ -13,7 +13,7 @@
 static char   global_db_hostname[32] = "127.0.0.1";
 static uint16 global_db_port = 3306;
 static char   global_db_username[32] = "ragnarok";
-static char   global_db_password[32] = "ragnarok";
+static char   global_db_password[32] = "";
 static char   global_db_database[32] = "ragnarok";
 static char   global_codepage[32] = "";
 // local sql settings

+ 30 - 25
src/map/atcommand.c

@@ -1198,7 +1198,7 @@ ACMD_FUNC(heal)
 ACMD_FUNC(item)
 {
 	char item_name[100];
-	int number = 0, flag = 0, bound = 0;
+	int number = 0, flag = 0, bound = BOUND_NONE;
 	struct item item_tmp;
 	struct item_data *item_data[10];
 	int get_count, i, j=0;
@@ -1207,12 +1207,19 @@ ACMD_FUNC(item)
 	nullpo_retr(-1, sd);
 	memset(item_name, '\0', sizeof(item_name));
 
-	if (!strcmpi(command+1,"itembound") && (!message || !*message || (
-		sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 2 &&
-		sscanf(message, "%99s %d %d", item_name, &number, &bound) < 2
-	))) {
-		clif_displaymessage(fd, msg_txt(sd,295)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity> <bound_type>).
-		return -1;
+	if (!strcmpi(command+1,"itembound")) {
+		if (!message || !*message || (
+			sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 3 &&
+			sscanf(message, "%99s %d %d", item_name, &number, &bound) < 3))
+		{
+			clif_displaymessage(fd, msg_txt(sd,295)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity> <bound_type>).
+			clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
+			return -1;
+		}
+		if( bound <= BOUND_NONE || bound >= BOUND_MAX ) {
+			clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
+			return -1;
+		}
 	} else if (!message || !*message || (
 		sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
 		sscanf(message, "%99s %d", item_name, &number) < 1
@@ -1231,11 +1238,6 @@ ACMD_FUNC(item)
 		j++;
 	}
 
-	if( bound < 0 || bound > 4 ) {
-		clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
-		return -1;
-	}
-
 	if (number <= 0)
 		number = 1;
 	get_count = number;
@@ -1273,19 +1275,27 @@ ACMD_FUNC(item2)
 	struct item item_tmp;
 	struct item_data *item_data;
 	char item_name[100];
-	int item_id, number = 0, bound = 0;
+	int item_id, number = 0, bound = BOUND_NONE;
 	int identify = 0, refine = 0, attr = 0;
 	int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 	nullpo_retr(-1, sd);
 
 	memset(item_name, '\0', sizeof(item_name));
 
-	if (!strcmpi(command+1,"itembound2") && (!message || !*message || (
-		sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
-		sscanf(message, "%99s %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))) {
-		clif_displaymessage(fd, msg_txt(sd,296)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
-		clif_displaymessage(fd, msg_txt(sd,297)); //   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
-		return -1;
+	if (!strcmpi(command+1,"itembound2")) {
+		if (!message || !*message || (
+			sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
+			sscanf(message, "%99s %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))
+		{
+			clif_displaymessage(fd, msg_txt(sd,296)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
+			clif_displaymessage(fd, msg_txt(sd,297)); //   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
+			clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
+			return -1;
+		}
+		if( bound <= BOUND_NONE || bound >= BOUND_MAX ) {
+			clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
+			return -1;
+		}
 	} else if ( !message || !*message || (
 		sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
 		sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
@@ -1298,11 +1308,6 @@ ACMD_FUNC(item2)
 	if (number <= 0)
 		number = 1;
 
-	if( bound < 0 || bound > 4 ) {
-		clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
-		return -1;
-	}
-
 	item_id = 0;
 	if ((item_data = itemdb_searchname(item_name)) != NULL ||
 	    (item_data = itemdb_exists(atoi(item_name))) != NULL)
@@ -3926,7 +3931,7 @@ ACMD_FUNC(mapinfo) {
 				if (map[m_id].skill_damage[j].skill_id) {
 					sprintf(atcmd_output,"     %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
 						,j+1
-						,skill_db[skill_get_index(map[m_id].skill_damage[j].skill_id)].name
+						,skill_get_name(map[m_id].skill_damage[j].skill_id)
 						,map[m_id].skill_damage[j].pc
 						,map[m_id].skill_damage[j].mob
 						,map[m_id].skill_damage[j].boss

+ 62 - 50
src/map/battle.c

@@ -1066,7 +1066,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 			DAMAGE_SUBRATE(sc->data[SC_GRANITIC_ARMOR]->val2)
 
 		if(sc->data[SC_PAIN_KILLER])
-			DAMAGE_SUBRATE(sc->data[SC_PAIN_KILLER]->val3);
+			damage -= sc->data[SC_PAIN_KILLER]->val3;
 
 		if( sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT )
 			DAMAGE_ADDRATE(sc->data[SC_DARKCROW]->val2);
@@ -1723,45 +1723,44 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
 	return 0;
 }
 
-/*==========================================
- * Damage calculation for adjusting skill damage
- * Credits:
-		[Lilith] for the first release of this
-		[Cydh] finishing and adding mapflag
- * battle_skill_damage_skill() - skill_id based
- * battle_skill_damage_map() - map based
- *------------------------------------------*/
+/** Damage calculation for adjusting skill damage
+ * @param caster Applied caster type for damage skill
+ * @param type BL_Type of attacker
+ * @author [Lilith] for the first release of this, [Cydh]
+ **/
 #ifdef ADJUST_SKILL_DAMAGE
-static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type type)
-{
+static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) {
 	if (caster == 0)
 		return false;
 
-	while (1) {
-		if (caster&SDC_PC && type == BL_PC) break;
-		if (caster&SDC_MOB && type == BL_MOB) break;
-		if (caster&SDC_PET && type == BL_PET) break;
-		if (caster&SDC_HOM && type == BL_HOM) break;
-		if (caster&SDC_MER && type == BL_MER) break;
-		if (caster&SDC_ELEM && type == BL_ELEM) break;
-		return false;
+	switch (src_type) {
+		case BL_PC: if (caster&SDC_PC) return true; break;
+		case BL_MOB: if (caster&SDC_MOB) return true; break;
+		case BL_PET: if (caster&SDC_PET) return true; break;
+		case BL_HOM: if (caster&SDC_HOM) return true; break;
+		case BL_MER: if (caster&SDC_MER) return true; break;
+		case BL_ELEM: if (caster&SDC_ELEM) return true; break;
 	}
-	return true;
+	return false;
 }
 
-static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id)
-{
-	unsigned short m = src->m;
-	int idx;
+/** Gets skill damage rate from a skill (based on skill_damage_db.txt)
+* @param src
+* @param target
+* @param skill_id
+* @return Skill damage rate
+*/
+static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id) {
+	uint16 idx = skill_get_index(skill_id), m = src->m;
 	struct s_skill_damage *damage = NULL;
 
-	if ((idx = skill_get_index(skill_id)) < 0 || !skill_db[idx].damage.map)
+	if (!idx || !skill_db[idx].damage.map)
 		return 0;
 
 	damage = &skill_db[idx].damage;
 
 	//check the adjustment works for specified type
-	if (!battle_skill_damage_iscaster(damage->caster,src->type))
+	if (!battle_skill_damage_iscaster(damage->caster, src->type))
 		return 0;
 
 	if ((damage->map&1 && (!map[m].flag.pvp && !map_flag_gvg(m) && !map[m].flag.battleground && !map[m].flag.skill_damage && !map[m].flag.restricted)) ||
@@ -1787,8 +1786,13 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
 	return 0;
 }
 
-static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id)
-{
+/** Gets skill damage rate from a skill (based on 'skill_damage' mapflag)
+* @param src
+* @param target
+* @param skill_id
+* @return Skill damage rate
+*/
+static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id) {
 	int rate = 0;
 	uint16 m = src->m;
 	uint8 i;
@@ -1796,8 +1800,8 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
 	if (!map[m].flag.skill_damage)
 		return 0;
 
-	/* modifier for all skills */
-	if (battle_skill_damage_iscaster(map[m].adjust.damage.caster,src->type)) {
+	// Damage rate for all skills at this map
+	if (battle_skill_damage_iscaster(map[m].adjust.damage.caster, src->type)) {
 		switch (target->type) {
 			case BL_PC:
 				rate = map[m].adjust.damage.pc;
@@ -1814,10 +1818,10 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
 		}
 	}
 
-	/* modifier for specified map */
-	ARR_FIND(0,MAX_MAP_SKILL_MODIFIER,i,map[m].skill_damage[i].skill_id == skill_id);
-	if (i < MAX_MAP_SKILL_MODIFIER) {
-		if (battle_skill_damage_iscaster(map[m].skill_damage[i].caster,src->type)) {
+	// Damage rate for specified skill at this map
+	ARR_FIND(0, ARRAYLENGTH(map[m].skill_damage), i, map[m].skill_damage[i].skill_id == skill_id);
+	if (i < ARRAYLENGTH(map[m].skill_damage)) {
+		if (battle_skill_damage_iscaster(map[m].skill_damage[i].caster, src->type)) {
 			switch (target->type) {
 				case BL_PC:
 					rate += map[m].skill_damage[i].pc;
@@ -1837,11 +1841,16 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
 	return rate;
 }
 
-static int battle_skill_damage(struct block_list *src, struct block_list *target, uint16 skill_id)
-{
+/** Check skill damage adjustment based on mapflags and skill_damage_db.txt for specified skill
+* @param src
+* @param target
+* @param skill_id
+* @return Total damage rate
+*/
+static int battle_skill_damage(struct block_list *src, struct block_list *target, uint16 skill_id) {
 	if (!target)
 		return 0;
-	return battle_skill_damage_skill(src,target,skill_id) + battle_skill_damage_map(src,target,skill_id);
+	return battle_skill_damage_skill(src, target, skill_id) + battle_skill_damage_map(src, target, skill_id);
 }
 #endif
 
@@ -2865,9 +2874,9 @@ struct Damage battle_calc_skill_base_damage(struct Damage wd, struct block_list
 }
 
 //For quick div adjustment.
-#define damage_div_fix(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; }
-#define damage_div_fix2(dmg, div) { if (div > 1) (dmg)*=div; }
-#define damage_div_fix_renewal(wd, div) { damage_div_fix2(wd.statusAtk, div); damage_div_fix2(wd.weaponAtk, div); damage_div_fix2(wd.equipAtk, div); damage_div_fix2(wd.masteryAtk, div); }
+#define DAMAGE_DIV_FIX(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; }
+#define DAMAGE_DIV_FIX2(dmg, div) { if (div > 1) (dmg)*=div; }
+#define DAMAGE_DIV_FIX_RENEWAL(wd, div) { DAMAGE_DIV_FIX2(wd.statusAtk, div); DAMAGE_DIV_FIX2(wd.weaponAtk, div); DAMAGE_DIV_FIX2(wd.equipAtk, div); DAMAGE_DIV_FIX2(wd.masteryAtk, div); }
 /*=======================================
  * Check for and calculate multi attacks
  *---------------------------------------
@@ -3825,8 +3834,8 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
 			break;
 		case RL_D_TAIL:
 			skillratio += -100 + (2500 + 500 * skill_lv );
-			if (sd && &sd->c_marker)
-				skillratio /= max(sd->c_marker.count,1);
+			//if (sd && &sd->c_marker)
+			//	skillratio /= max(sd->c_marker.count,1);
 			break;
 		case RL_R_TRIP:
 			skillratio += -100 + (150 * skill_lv); //(custom)
@@ -3849,6 +3858,9 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
 		case RL_FIRE_RAIN:
 			skillratio += -100 + 2000 + status_get_dex(src); //(custom) //kRO Update 2013-07-24. 2,000% + caster's DEX (?) [Cydh]
 			break;
+		case RL_AM_BLAST:
+			skillratio += -100 + (skill_lv * status_get_dex(src) / 2); //(custom)
+			break;
 	}
 	return skillratio;
 }
@@ -4656,7 +4668,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
 #endif
 	}
 
-	/* Skill damage adjustment */
+	// Skill damage adjustment
 #ifdef ADJUST_SKILL_DAMAGE
 	if ((skill_damage = battle_skill_damage(src, target, skill_id)) != 0)
 		ATK_ADDRATE(wd.damage, wd.damage2, skill_damage);
@@ -5118,9 +5130,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
 	}
 
 	// perform multihit calculations
-	damage_div_fix_renewal(wd, wd.div_);
+	DAMAGE_DIV_FIX_RENEWAL(wd, wd.div_);
 #endif
-	damage_div_fix(wd.damage, wd.div_);
+	DAMAGE_DIV_FIX(wd.damage, wd.div_);
 
 	// only do 1 dmg to plant, no need to calculate rest
 	if(target_has_infinite_defense(target, skill_id))
@@ -5886,7 +5898,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 #endif
 	}
 
-	damage_div_fix(ad.damage, ad.div_);
+	DAMAGE_DIV_FIX(ad.damage, ad.div_);
 
 	if (flag.infdef && ad.damage)
 		ad.damage = ad.damage>0?1:-1;
@@ -5906,7 +5918,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 			break;
 	}
 
-	/* Skill damage adjustment */
+	// Skill damage adjustment
 #ifdef ADJUST_SKILL_DAMAGE
 	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
 		MATK_ADDRATE(skill_damage);
@@ -6015,7 +6027,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 
 		if (skill_id == SN_FALCONASSAULT) {
 			//Div fix of Blitzbeat
-			damage_div_fix2(md.damage, skill_get_num(HT_BLITZBEAT, 5));
+			DAMAGE_DIV_FIX2(md.damage, skill_get_num(HT_BLITZBEAT, 5));
 
 			//Falcon Assault Modifier
 			md.damage=(int64)md.damage*(150+70*skill_lv)/100;
@@ -6189,7 +6201,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 			ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
 	}
 
-	damage_div_fix(md.damage, md.div_);
+	DAMAGE_DIV_FIX(md.damage, md.div_);
 
 	if (!(nk&NK_IGNORE_FLEE))
 	{
@@ -6294,7 +6306,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 		break;
 	}
 
-	/* Skill damage adjustment */
+	// Skill damage adjustment
 #ifdef ADJUST_SKILL_DAMAGE
 	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
 		md.damage += (int64)md.damage * skill_damage / 100;

+ 2 - 2
src/map/clif.c

@@ -2261,7 +2261,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
 		WFIFOL(fd,offs+23)=sd->status.inventory[n].expire_time;
 #endif
 #if PACKETVER >= 20071002
-		WFIFOW(fd,offs+27)=sd->status.inventory[n].bound ? 2 : 0;
+		WFIFOW(fd,offs+27)=sd->status.inventory[n].bound ? BOUND_GUILD : 0;
 #endif
 	}
 
@@ -2367,7 +2367,7 @@ void clif_item_sub(unsigned char *buf, int n, int idx, struct item *i, struct it
 		clif_addcards(WBUFP(buf, n+12), i); //8B
 #if PACKETVER >= 20071002
 		WBUFL(buf,n+20)=i->expire_time;
-		WBUFW(buf,n+24)=i->bound ? 2 : 0;
+		WBUFW(buf,n+24)=i->bound ? BOUND_GUILD : 0;
 #endif
 #if PACKETVER >= 20100629
 		WBUFW(buf,n+26)= (id->equip&EQP_VISIBLE)?id->look:0;

+ 4 - 4
src/map/elemental.c

@@ -561,19 +561,19 @@ int elemental_unlocktarget(struct elemental_data *ed) {
 	return 0;
 }
 
-int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) {
-	int idx = skill_get_index(skill_id);
+bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) {
+	uint16 idx = skill_get_index(skill_id);
 	nullpo_retr(1,ed);
 
 	if (idx == 0)
-		return 1; // invalid skill id
+		return false; // invalid skill id
 
 	return skill_isNotOk(skill_id,ed->master);
 }
 
 struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
 	struct skill_condition req;
-	int idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(skill_id);
 
 	memset(&req,0,sizeof(req));
 

+ 1 - 1
src/map/elemental.h

@@ -92,7 +92,7 @@ void elemental_summon_stop(struct elemental_data *ed);
 int elemental_get_lifetime(struct elemental_data *ed);
 
 int elemental_unlocktarget(struct elemental_data *ed);
-int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed);
+bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed);
 int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
 int elemental_clean_single_effect(struct elemental_data *ed, uint16 skill_id);
 int elemental_clean_effect(struct elemental_data *ed);

+ 1 - 1
src/map/guild.c

@@ -1807,7 +1807,7 @@ int guild_break(struct map_session_data *sd,char *name) {
 	//Guild bound item check - Removes the bound flag
 	j = pc_bound_chk(sd,2,idxlist);
 	for(i=0;i<j;i++)
-		sd->status.inventory[idxlist[i]].bound = 0;
+		sd->status.inventory[idxlist[i]].bound = BOUND_NONE;
 #endif
 
 	intif_guild_break(g->guild_id);

+ 26 - 56
src/map/itemdb.c

@@ -471,30 +471,14 @@ struct item_data* itemdb_search(int nameid)
 	return id;
 }
 
-/*==========================================
- * Returns if given item is a player-equippable piece.
- *------------------------------------------*/
-bool itemdb_isequip(int nameid)
-{
-	int type=itemdb_type(nameid);
-	switch (type) {
-		case IT_WEAPON:
-		case IT_ARMOR:
-		case IT_AMMO:
-		case IT_SHADOWGEAR:
-			return true;
-		default:
-			return false;
-	}
-}
-
-/*==========================================
- * Alternate version of itemdb_isequip
- *------------------------------------------*/
-bool itemdb_isequip2(struct item_data *data)
+/** Checks if item is equip type or not
+* @param id Item data
+* @return True if item is equip, false otherwise
+*/
+bool itemdb_isequip2(struct item_data *id)
 {
-	nullpo_ret(data);
-	switch(data->type) {
+	nullpo_ret(id);
+	switch(id->type) {
 		case IT_WEAPON:
 		case IT_ARMOR:
 		case IT_AMMO:
@@ -505,31 +489,14 @@ bool itemdb_isequip2(struct item_data *data)
 	}
 }
 
-/*==========================================
- * Returns if given item's type is stackable.
- *------------------------------------------*/
-bool itemdb_isstackable(uint16 nameid)
-{
-  uint8 type = itemdb_type(nameid);
-  switch(type) {
-	  case IT_WEAPON:
-	  case IT_ARMOR:
-	  case IT_PETEGG:
-	  case IT_PETARMOR:
-	  case IT_SHADOWGEAR:
-		  return false;
-	  default:
-		  return true;
-  }
-}
-
-/*==========================================
- * Alternate version of itemdb_isstackable
- *------------------------------------------*/
-bool itemdb_isstackable2(struct item_data *data)
+/** Checks if item is stackable or not
+* @param id Item data
+* @return True if item is stackable, false otherwise
+*/
+bool itemdb_isstackable2(struct item_data *id)
 {
-  nullpo_ret(data);
-  switch(data->type) {
+  nullpo_ret(id);
+  switch(id->type) {
 	  case IT_WEAPON:
 	  case IT_ARMOR:
 	  case IT_PETEGG:
@@ -665,7 +632,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
 		unsigned int j, prob = 1;
 		uint16 nameid, amt = 1, dur = 0;
 		uint8 rand_group = 1;
-		char *str[9], *p, announced = 0, named = 0, bound = 0;
+		char *str[9], *p, announced = 0, named = 0, bound = BOUND_NONE;
 		struct s_item_group_random *random = NULL;
 		struct s_item_group_db *group = NULL;
 		bool found = false;
@@ -739,7 +706,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
 		if (str[5] != NULL) announced = atoi(str[5]);
 		if (str[6] != NULL) dur = cap_value(atoi(str[6]),0,UINT16_MAX);
 		if (str[7] != NULL) named = atoi(str[7]);
-		if (str[8] != NULL) bound = cap_value(atoi(str[8]),0,4);
+		if (str[8] != NULL) bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1);
 
 		found = true;
 		if (!(group = (struct s_item_group_db *) idb_get(itemdb_group, group_id))) {
@@ -986,23 +953,25 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current) {
 
 /** Misc Item flags
 * <item_id>,<flag>
-* &1 - Log as dead branch
+* &1 - As dead branch item
 * &2 - As item container
 */
 static bool itemdb_read_flag(char* fields[], int columns, int current) {
 	uint16 nameid = atoi(fields[0]);
-	uint8 flag = atoi(fields[1]);
+	uint8 flag;
+	bool set;
 	struct item_data *id;
 
 	if (!(id = itemdb_exists(nameid))) {
 		ShowError("itemdb_read_flag: Invalid item item with id %d\n", nameid);
 		return true;
 	}
+	
+	flag = abs(atoi(fields[1]));
+	set = atoi(fields[1]) > 0;
 
-	if (flag&1)
-		id->flag.dead_branch = 1;
-	if (flag&2)
-		id->flag.group = 1;
+	if (flag&1) id->flag.dead_branch = set ? 1 : 0;
+	if (flag&2) id->flag.group = set ? 1 : 0;
 
 	return true;
 }
@@ -1653,7 +1622,8 @@ static void destroy_item_data(struct item_data* self, bool free_self) {
 		for( i = 0; i < self->combos_count; i++ ) {
 			if( !self->combos[i]->isRef ) {
 				aFree(self->combos[i]->nameid);
-				script_free_code(self->combos[i]->script);
+				if (self->combos[i]->script)
+					script_free_code(self->combos[i]->script);
 			}
 			aFree(self->combos[i]);
 		}

+ 4 - 4
src/map/itemdb.h

@@ -475,11 +475,11 @@ bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(str
 #define itemdb_canmail(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canmail_sub)
 #define itemdb_canauction(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canauction_sub)
 
-bool itemdb_isequip(int);
-bool itemdb_isequip2(struct item_data *);
+bool itemdb_isequip2(struct item_data *id);
+#define itemdb_isequip(nameid) itemdb_isequip2(itemdb_search(nameid))
 char itemdb_isidentified(int);
-bool itemdb_isstackable(uint16 nameid);
-bool itemdb_isstackable2(struct item_data *data);
+bool itemdb_isstackable2(struct item_data *id);
+#define itemdb_isstackable(nameid) itemdb_isstackable2(itemdb_search(nameid))
 uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
 bool itemdb_isNoEquip(struct item_data *id, uint16 m);
 

+ 2 - 1
src/map/map.c

@@ -65,7 +65,7 @@ char default_codepage[32] = "";
 int map_server_port = 3306;
 char map_server_ip[32] = "127.0.0.1";
 char map_server_id[32] = "ragnarok";
-char map_server_pw[32] = "ragnarok";
+char map_server_pw[32] = "";
 char map_server_db[32] = "ragnarok";
 Sql* mmysql_handle;
 
@@ -1677,6 +1677,7 @@ int map_quit(struct map_session_data *sd) {
 		status_change_end(&sd->bl, SC_GLORYWOUNDS, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_SOULCOLD, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_HAWKEYES, INVALID_TIMER);
+		status_change_end(&sd->bl, SC_CHASEWALK2, INVALID_TIMER);
 		if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
 			status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
 		status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);

+ 40 - 34
src/map/npc.c

@@ -124,9 +124,9 @@ int npc_isnear_sub(struct block_list* bl, va_list args) {
 	int skill_id = va_arg(args, int);
 
 	if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
-		int16 idx = skill_get_index(skill_id);
+		uint16 idx = skill_get_index(skill_id);
 
-		if (idx >= 0 && skill_db[idx].unit_nonearnpc_type) {
+		if (idx > 0 && skill_db[idx].unit_nonearnpc_type) {
 			while (1) {
 				if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break;
 				if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) break;
@@ -3723,40 +3723,46 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 		map[m].flag.notomb = state;
 	else if (!strcmpi(w3,"skill_damage")) {
 #ifdef ADJUST_SKILL_DAMAGE
-		char skill[NAME_LENGTH];
+		char skill[SKILL_NAME_LENGTH];
 		int pc = 0, mob = 0, boss = 0, other = 0, caster = 0;
 
-		memset(skill,0,sizeof(skill));
-		map[m].flag.skill_damage = state;	//set the mapflag
-
-		if (sscanf(w4,"%24[^,],%d,%d,%d,%d,%d[^\n]",skill,&caster,&pc,&mob,&boss,&other) >= 3) {
-			caster = (!caster) ? SDC_ALL : caster;
-			pc = cap_value(pc,-100,MAX_SKILL_DAMAGE_RATE);
-			mob = cap_value(mob,-100,MAX_SKILL_DAMAGE_RATE);
-			boss = cap_value(boss,-100,MAX_SKILL_DAMAGE_RATE);
-			other = cap_value(other,-100,MAX_SKILL_DAMAGE_RATE);
-
-			if (strcmp(skill,"all") == 0) {	//adjust damages for all skills
-				map[m].adjust.damage.caster = caster;
-				map[m].adjust.damage.pc = pc;
-				map[m].adjust.damage.mob = mob;
-				map[m].adjust.damage.boss = boss;
-				map[m].adjust.damage.other = other;
-			}
-			else if (skill_name2id(skill) <= 0)
-				ShowWarning("npc_parse_mapflag: skill_damage: Invalid skill name '%s'. Skipping (file '%s', line '%d')\n",skill,filepath,strline(buffer,start-buffer));
-			else {	//damages for specified skill
-				int i;
-				ARR_FIND(0,MAX_MAP_SKILL_MODIFIER,i,map[m].skill_damage[i].skill_id <= 0);
-				if (i >= MAX_SKILL)
-					ShowWarning("npc_parse_mapflag: skill_damage: Skill damage for map '%s' is overflow.\n",map[m].name);
-				else {
-					map[m].skill_damage[i].skill_id = skill_name2id(skill);
-					map[m].skill_damage[i].caster = caster;
-					map[m].skill_damage[i].pc = pc;
-					map[m].skill_damage[i].mob = mob;
-					map[m].skill_damage[i].boss = boss;
-					map[m].skill_damage[i].other = other;
+		memset(skill, 0, sizeof(skill));
+		map[m].flag.skill_damage = state;	// Set the mapflag
+
+		if (!state) {
+			memset(map[m].skill_damage, 0, sizeof(map[m].skill_damage));
+			memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage));
+		}
+		else {
+			if (sscanf(w4, "%30[^,],%d,%d,%d,%d,%d[^\n]", skill, &caster, &pc, &mob, &boss, &other) >= 3) {
+				caster = (!caster) ? SDC_ALL : caster;
+				pc = cap_value(pc, -100, INT_MAX);
+				mob = cap_value(mob, -100, INT_MAX);
+				boss = cap_value(boss, -100, INT_MAX);
+				other = cap_value(other, -100, INT_MAX);
+
+				if (strcmp(skill,"all") == 0) {	// Adjust damages for all skills
+					map[m].adjust.damage.caster = caster;
+					map[m].adjust.damage.pc = pc;
+					map[m].adjust.damage.mob = mob;
+					map[m].adjust.damage.boss = boss;
+					map[m].adjust.damage.other = other;
+				}
+				else if (skill_name2id(skill) <= 0)
+					ShowWarning("npc_parse_mapflag: skill_damage: Invalid skill name '%s'. Skipping (file '%s', line '%d')\n", skill, filepath, strline(buffer,start-buffer));
+				else {	//damages for specified skill
+					uint8 i;
+					ARR_FIND(0, ARRAYLENGTH(map[m].skill_damage), i, map[m].skill_damage[i].skill_id <= 0);
+					if (i >= ARRAYLENGTH(map[m].skill_damage))
+						ShowWarning("npc_parse_mapflag: skill_damage: Skill damage for map '%s' is overflow.\n", map[m].name);
+					else {
+						map[m].skill_damage[i].skill_id = skill_name2id(skill);
+						map[m].skill_damage[i].caster = caster;
+						map[m].skill_damage[i].pc = pc;
+						map[m].skill_damage[i].mob = mob;
+						map[m].skill_damage[i].boss = boss;
+						map[m].skill_damage[i].other = other;
+					}
 				}
 			}
 		}

+ 17 - 15
src/map/pc.c

@@ -4132,15 +4132,17 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
 	return 0;
 }
 
-/*==========================================
+/**
  * Searching a specified itemid in inventory and return his stored index
- *------------------------------------------*/
-int pc_search_inventory(struct map_session_data *sd,int item_id)
-{
+ * @param sd Player
+ * @param nameid Find this Item!
+ * @return Stored index in inventory, or -1 if not found.
+ **/
+short pc_search_inventory(struct map_session_data *sd, uint16 nameid) {
 	int16 i;
 	nullpo_retr(-1, sd);
 
-	ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0) );
+	ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && (sd->status.inventory[i].amount > 0 || nameid == 0) );
 	return ( i < MAX_INVENTORY ) ? i : -1;
 }
 
@@ -4736,7 +4738,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		return 1;
 	}
 
-	if( !itemdb_cancartstore(item_data, pc_get_group_level(sd)) || (item_data->bound > 1 && !pc_can_give_bounded_items(sd)))
+	if( !itemdb_cancartstore(item_data, pc_get_group_level(sd)) || (item_data->bound > BOUND_ACCOUNT && !pc_can_give_bounded_items(sd)))
 	{ // Check item trade restrictions	[Skotlex]
 		clif_displaymessage (sd->fd, msg_txt(sd,264));
 		return 1;
@@ -4896,7 +4898,7 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
  * 3 Party Bound
  * 4 Character Bound
  *------------------------------------------*/
-int pc_bound_chk(TBL_PC *sd,int type,int *idxlist)
+int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist)
 {
 	int i=0, j=0;
 	for(i=0;i<MAX_INVENTORY;i++){
@@ -5308,17 +5310,17 @@ int pc_memo(struct map_session_data* sd, int pos)
  * @param lv : skill lv
  * @return player skill cooldown
  */
-int pc_get_skillcooldown(struct map_session_data *sd, int id, int lv) {
-	int i, cooldown=0;
-	int idx = skill_get_index (id);
-	int cooldownlen = ARRAYLENGTH(sd->skillcooldown);
+int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv) {
+	uint8 i;
+	uint16 idx = skill_get_index(skill_id);
+	int cooldown = 0, cooldownlen = ARRAYLENGTH(sd->skillcooldown);
 	
 	if (!idx) return 0;
-	if (skill_db[idx].cooldown[lv - 1])
-		cooldown = skill_db[idx].cooldown[lv - 1];
+	if (skill_db[idx].cooldown[skill_lv - 1])
+		cooldown = skill_db[idx].cooldown[skill_lv - 1];
 
-	ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == id);
-	if(i<cooldownlen){
+	ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == skill_id);
+	if (i < cooldownlen) {
 		cooldown += sd->skillcooldown[i].val;
 		cooldown = max(0,cooldown);
 	}

+ 3 - 3
src/map/pc.h

@@ -827,7 +827,7 @@ int pc_isequip(struct map_session_data *sd,int n);
 int pc_equippoint(struct map_session_data *sd,int n);
 int pc_setinventorydata(struct map_session_data *sd);
 
-int pc_get_skillcooldown(struct map_session_data *sd, int id, int lv);
+int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
 int pc_checkskill(struct map_session_data *sd,uint16 skill_id);
 short pc_checkequip(struct map_session_data *sd,int pos);
 bool pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max);
@@ -851,14 +851,14 @@ int pc_memo(struct map_session_data* sd, int pos);
 
 int pc_checkadditem(struct map_session_data*,int,int);
 int pc_inventoryblank(struct map_session_data*);
-int pc_search_inventory(struct map_session_data *sd,int item_id);
+short pc_search_inventory(struct map_session_data *sd, uint16 nameid);
 int pc_payzeny(struct map_session_data*,int, enum e_log_pick_type type, struct map_session_data*);
 char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type);
 int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_session_data*);
 int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type);
 
 //Bound items
-int pc_bound_chk(TBL_PC *sd,int type,int *idxlist);
+int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist);
 
 // Special Shop System
 int pc_paycash( struct map_session_data *sd, int price, int points, e_log_pick_type type );

+ 34 - 28
src/map/script.c

@@ -2289,6 +2289,7 @@ void script_hardcoded_constants(void) {
 	script_set_constant("Option_Invisible",OPTION_INVISIBLE,false);
 	script_set_constant("Option_Orcish",OPTION_ORCISH,false);
 	script_set_constant("Option_Wedding",OPTION_WEDDING,false);
+	script_set_constant("Option_Ruwach",OPTION_RUWACH,false);
 	script_set_constant("Option_Chasewalk",OPTION_CHASEWALK,false);
 	script_set_constant("Option_Flying",OPTION_FLYING,false);
 	script_set_constant("Option_Xmas",OPTION_XMAS,false);
@@ -6455,22 +6456,24 @@ BUILDIN_FUNC(getitem)
 
 	if( !strcmp(script_getfuncname(st),"getitembound") ) {
 		char bound = script_getnum(st,4);
-		if( bound < 1 || bound > 4) { //Not a correct bound type
+		if( bound > BOUND_NONE && bound < BOUND_MAX ) {
+			it.bound = bound;
+			if( script_hasdata(st,5) )
+				sd=map_id2sd(script_getnum(st,5));
+			else
+				sd=script_rid2sd(st); // Attached player
+		}
+		else { //Not a correct bound type
 			ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound);
-			return 1;
+			return SCRIPT_CMD_FAILURE;
 		}
-		it.bound = bound;
-		if( script_hasdata(st,5) )
-			sd=map_id2sd(script_getnum(st,5));
-		else
-			sd=script_rid2sd(st); // Attached player
 	} else if( script_hasdata(st,4) )
 		sd=map_id2sd(script_getnum(st,4)); // <Account ID>
 	else
 		sd=script_rid2sd(st); // Attached player
 
 	if( sd == NULL ) // no target
-		return 0;
+		return SCRIPT_CMD_SUCCESS;
 
 	//Check if it's stackable.
 	if (!itemdb_isstackable(nameid))
@@ -6499,9 +6502,9 @@ BUILDIN_FUNC(getitem)
  *------------------------------------------*/
 BUILDIN_FUNC(getitem2)
 {
-	int nameid,amount,get_count,i,flag = 0;
-	int iden,ref,attr,c1,c2,c3,c4;
-	char bound=0;
+	int nameid, amount, get_count, i, flag = 0;
+	int iden, ref, attr, c1, c2, c3, c4;
+	char bound = BOUND_NONE;
 	struct item_data *item_data;
 	struct item item_tmp;
 	TBL_PC *sd;
@@ -6509,21 +6512,23 @@ BUILDIN_FUNC(getitem2)
 
 	if( !strcmp(script_getfuncname(st),"getitembound2") ) {
 		bound = script_getnum(st,11);
-		if( bound < 1 || bound > 3) { //Not a correct bound type
+		if( bound > BOUND_NONE && bound < BOUND_MAX ) {
+			if( script_hasdata(st,12) )
+				sd=map_id2sd(script_getnum(st,12));
+			else
+				sd=script_rid2sd(st); // Attached player
+		}
+		else {
 			ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound);
-			return 1;
+			return SCRIPT_CMD_FAILURE;
 		}
-		if( script_hasdata(st,12) )
-			sd=map_id2sd(script_getnum(st,12));
-		else
-			sd=script_rid2sd(st); // Attached player
 	} else if( script_hasdata(st,11) )
 		sd=map_id2sd(script_getnum(st,11)); // <Account ID>
 	else
 		sd=script_rid2sd(st); // Attached player
 
 	if( sd == NULL ) // no target
-		return 0;
+		return SCRIPT_CMD_SUCCESS;
 
 	data=script_getdata(st,2);
 	get_val(st,data);
@@ -6652,7 +6657,7 @@ BUILDIN_FUNC(rentitem) {
 	it.nameid = nameid;
 	it.identify = 1;
 	it.expire_time = (unsigned int)(time(NULL) + seconds);
-	it.bound = 0;
+	it.bound = BOUND_NONE;
 
 	if( (flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT)) )
 	{
@@ -11472,7 +11477,8 @@ BUILDIN_FUNC(removemapflag)
 			case MF_SKILL_DAMAGE:
 				{
 					map[m].flag.skill_damage = 0;
-					memset(&map[m].adjust.damage,0,sizeof(map[m].adjust.damage));
+					memset(map[m].skill_damage, 0, sizeof(map[m].skill_damage));
+					memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage));
 				} break;
 #endif
 		}
@@ -18228,24 +18234,24 @@ BUILDIN_FUNC(stand)
 
 /** Creates an array of bounded item IDs
  * countbound {<type>};
- * @param type: 1 - Account Bound; 2 - Guild Bound; 3 - Party Bound
+ * @param type: 0 - All bound items; 1 - Account Bound; 2 - Guild Bound; 3 - Party Bound
  * @return amt: Amount of items found
  */
 BUILDIN_FUNC(countbound)
 {
-	int i, type, j=0, k=0;
+	int i, type, j = 0, k = 0;
 	TBL_PC *sd;
 
 	if( (sd = script_rid2sd(st)) == NULL )
 		return SCRIPT_CMD_FAILURE;
 
-	type = script_hasdata(st,2)?script_getnum(st,2):0;
+	type = script_getnum(st,2);
 
-	for(i=0;i<MAX_INVENTORY;i++){
-		if(sd->status.inventory[i].nameid > 0 && (
-			(!type && sd->status.inventory[i].bound > 0) ||
-			(type && sd->status.inventory[i].bound == type)
-		)) {
+	for( i = 0; i < MAX_INVENTORY; i ++ ) {
+		if( sd->status.inventory[i].nameid > 0 && (
+			(!type && sd->status.inventory[i].bound) || (type && sd->status.inventory[i].bound == type)
+			))
+		{
 			pc_setreg(sd,reference_uid(add_str("@bound_items"), k),sd->status.inventory[i].nameid);
 			k++;
 			j += sd->status.inventory[i].amount;

+ 153 - 175
src/map/skill.c

@@ -445,7 +445,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
 * @author Aru - for previous check; Jobbie for class restriction idea; Cydh expands the copyable skill
 */
 static char skill_isCopyable(struct map_session_data *sd, uint16 skill_id) {
-	int idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(skill_id);
 
 	// Only copy skill that player doesn't have or the skill is old clone
 	if (sd->status.skill[idx].id != 0 && sd->status.skill[idx].flag != SKILL_FLAG_PLAGIARIZED)
@@ -721,7 +721,7 @@ bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md)
 bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y) {
 	int inf;
 
-	if (!src || skill_get_index(skill_id) < 0)
+	if (!src || skill_get_index(skill_id) == 0)
 		return false;
 
 	if (src->type == BL_PC && pc_has_permission(BL_CAST(BL_PC,src),PC_PERM_SKILL_UNCONDITIONAL))
@@ -1550,10 +1550,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 	case RL_SLUGSHOT:
 		if (bl->type != BL_PC)
 			sc_start(src,bl,SC_STUN,10 * skill_lv + rnd()%50,skill_lv,skill_get_time2(skill_id,skill_lv)); //(custom)
-		else if (dstsd) {
-			pc_setsit(dstsd);
-			clif_sitting(bl);
-		}
+		else if (dstsd)
+			//sit duration 2+skill_lv
+			status_change_start(src,bl,SC_SITDOWN_FORCE,10000,skill_lv,0,0,0,(2+skill_lv)*1000,1|2|8);
 		break;
 	case RL_BANISHING_BUSTER:
 		{
@@ -1625,7 +1624,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 					case SC_REBOUND:		case SC_TELEKINESIS_INTENSE:
 					case SC_HEAT_BARREL:	case SC_HEAT_BARREL_AFTER:	case SC_P_ALTER:
 					case SC_E_CHAIN:		case SC_C_MARKER:		case SC_B_TRAP:
-					case SC_H_MINE:			case SC_RECOGNIZEDSPELL:
+					case SC_H_MINE:			case SC_RECOGNIZEDSPELL:	case SC_CHASEWALK2:
 					case SC_MTF_ASPD:		case SC_MTF_RANGEATK:	case SC_MTF_MATK:
 					case SC_MTF_MLEATKED:	case SC_MTF_CRIDAMAGE:	case SC_GN_CARTBOOST:
 #ifdef RENEWAL
@@ -2594,7 +2593,7 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
 	else if (&tsd->sc && tsd->sc.data[SC_PRESERVE] && !tsd->sc.data[SC__REPRODUCE])
 		return;
 	else {
-		short idx;
+		uint16 idx;
 		unsigned char lv;
 
 		// Copy Referal: dummy skills should point to their source upon copying
@@ -2629,7 +2628,7 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
 		}
 
 		//Use skill index, avoiding out-of-bound array [Cydh]
-		if ((idx = skill_get_index(skill_id)) < 0)
+		if (!(idx = skill_get_index(skill_id)))
 			return;
 
 		switch (skill_isCopyable(tsd,skill_id)) {
@@ -3011,7 +3010,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 
 	map_freeblock_lock();
 
-	if (bl->type == BL_PC && skill_id && skill_get_index(skill_id) >= 0 && skill_db[skill_get_index(skill_id)].copyable.option && //Only copy skill that copyable [Cydh]
+	if (bl->type == BL_PC && skill_id && skill_get_index(skill_id) > 0 && skill_db[skill_get_index(skill_id)].copyable.option && //Only copy skill that copyable [Cydh]
 		dmg.flag&BF_SKILL && dmg.damage+dmg.damage2 > 0 && damage < status_get_hp(bl)) //Cannot copy skills if the blow will kill you. [Skotlex]
 		skill_do_copy(src,bl,skill_id,skill_lv);
 
@@ -3413,7 +3412,7 @@ static int skill_check_condition_mercenary(struct block_list *bl, int skill, int
 	if( (idx = skill_get_index(skill)) == 0 )
 		return 0;
 
-	// Requeriments
+	// Requirements
 	for( i = 0; i < ARRAYLENGTH(itemid); i++ )
 	{
 		itemid[i] = skill_db[idx].require.itemid[i];
@@ -14453,7 +14452,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 			break;
 		case ST_MADO:
 			if( !pc_ismadogear(sd) ) {
-				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+				clif_skill_fail(sd,skill_id,USESKILL_FAIL_MADOGEAR,0);
 				return false;
 			}
 			break;
@@ -14475,10 +14474,6 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 	if (require.status_count) {
 		uint8 i;
 		/* May has multiple requirements */
-		//if (!sc) {
-		//	clif_skill_fail(sd, skill_id, USESKILL_FAIL_CONDITION, 0);
-		//	return false;
-		//}
 		for (i = 0; i < require.status_count; i++) {
 			enum sc_type req_sc = require.status[i];
 			if (req_sc == SC_NONE)
@@ -14512,10 +14507,11 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 	//check if equiped item
 	if (require.eqItem_count) {
 		for (i = 0; i < require.eqItem_count; i++) {
-			int reqeqit = require.eqItem[i];
-			if(!reqeqit) break; //no more required item get out of here
+			uint16 reqeqit = require.eqItem[i];
+			if (!reqeqit)
+				break; //no more required item get out of here
 			if (!pc_checkequip2(sd,reqeqit,EQI_ACC_L,EQI_MAX)) {
-				char output[128];
+				char output[CHAT_SIZE_MAX];
 				//Official use msgstringtable.txt for each skill failure
 				sprintf(output,msg_txt(sd,722),itemdb_jname(reqeqit));
 				clif_colormes(sd,color_table[COLOR_RED],output);
@@ -14566,7 +14562,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
 	struct skill_condition require;
 	struct status_data *status;
 	int i;
-	int index[MAX_SKILL_ITEM_REQUIRE];
+	short index[MAX_SKILL_ITEM_REQUIRE];
 
 	nullpo_retr(false,sd);
 
@@ -14724,8 +14720,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
 			else if( require.itemid[i] == ITEMID_ANCILLA )
 				clif_skill_fail(sd,skill_id,USESKILL_FAIL_ANCILLA,0); //Ancilla is required.
 			else {
-				char output[128];
-
+				char output[CHAT_SIZE_MAX];
 				//Official is using msgstringtable.txt for each requirement failure
 				//clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 				sprintf(output, msg_txt(sd,720), itemdb_jname(require.itemid[i])); // %s is required.
@@ -14748,45 +14743,45 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
 */
 void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type)
 {
-	struct skill_condition req;
+	struct skill_condition require;
 
 	nullpo_retv(sd);
 
-	req = skill_get_requirement(sd,skill_id,skill_lv);
+	require = skill_get_requirement(sd,skill_id,skill_lv);
 
 	if( type&1 ) {
 		switch( skill_id ) {
 			case CG_TAROTCARD: // TarotCard will consume sp in skill_cast_nodamage_id [Inkfish]
 			case MC_IDENTIFY:
 			case RL_D_TAIL:
-				req.sp = 0;
+				require.sp = 0;
 				break;
 			case GS_DESPERADO:
 				if (sd->skill_id_old == RL_FALLEN_ANGEL) //Don't consume SP if triggered by Fallen Angel
-					req.sp = 0;
+					require.sp = 0;
 				break;
 			default:
 				if(sd->state.autocast)
-					req.sp = 0;
+					require.sp = 0;
 			break;
 		}
-		if(req.hp || req.sp)
-			status_zap(&sd->bl, req.hp, req.sp);
+		if(require.hp || require.sp)
+			status_zap(&sd->bl, require.hp, require.sp);
 
-		if(req.spiritball > 0)
-			pc_delspiritball(sd,req.spiritball,0);
-		else if(req.spiritball == -1) {
+		if(require.spiritball > 0)
+			pc_delspiritball(sd,require.spiritball,0);
+		else if(require.spiritball == -1) {
 			sd->spiritball_old = sd->spiritball;
 			pc_delspiritball(sd,sd->spiritball,0);
 		}
 
-		if(req.zeny > 0)
+		if(require.zeny > 0)
 		{
 			if( skill_id == NJ_ZENYNAGE )
-				req.zeny = 0; //Zeny is reduced on skill_attack.
-			if( sd->status.zeny < req.zeny )
-				req.zeny = sd->status.zeny;
-			pc_payzeny(sd,req.zeny,LOG_TYPE_CONSUME,NULL);
+				require.zeny = 0; //Zeny is reduced on skill_attack.
+			if( sd->status.zeny < require.zeny )
+				require.zeny = sd->status.zeny;
+			pc_payzeny(sd,require.zeny,LOG_TYPE_CONSUME,NULL);
 		}
 	}
 
@@ -14799,10 +14794,10 @@ void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, ui
 
 		for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i )
 		{
-			if( !req.itemid[i] )
+			if( !require.itemid[i] )
 				continue;
 
-			if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
+			if( itemid_isgemstone(require.itemid[i]) && skill_id != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
 				continue; //Gemstones are checked, but not substracted from inventory.
 
 			switch( skill_id ){
@@ -14831,8 +14826,8 @@ void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, ui
 					break;
 			}
 
-			if( (n = pc_search_inventory(sd,req.itemid[i])) >= 0 )
-				pc_delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME);
+			if( (n = pc_search_inventory(sd,require.itemid[i])) >= 0 )
+				pc_delitem(sd,n,require.amount[i],0,1,LOG_TYPE_CONSUME);
 		}
 	}
 }
@@ -14851,6 +14846,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 	struct status_change *sc;
 	int i,hp_rate,sp_rate, sp_skill_rate_bonus = 100;
 	uint16 idx;
+	bool level_dependent = false;
 
 	memset(&req,0,sizeof(req));
 
@@ -14945,85 +14941,13 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 	req.eqItem_count = skill_db[idx].require.eqItem_count;
 	req.eqItem = skill_db[idx].require.eqItem;
 
-	for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++ ) {
-		if( (skill_id == AM_POTIONPITCHER || skill_id == CR_SLIMPITCHER || skill_id == CR_CULTIVATION) && i != skill_lv%11 - 1 )
-			continue;
-
-		switch( skill_id ) {
-			case AM_CALLHOMUN:
-				if (sd->status.hom_id) //Don't delete items when hom is already out.
-					continue;
-				break;
-			case NC_SHAPESHIFT:
-				if( i < 4 )
-					continue;
-				break;
-			case WZ_FIREPILLAR: // celest
-				if (skill_lv <= 5)	// no gems required at level 1-5
-					continue;
-				break;
-			case AB_ADORAMUS:
-				if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2)) )
-					continue;
-				break;
-			case WL_COMET:
-				if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0)) )
-					continue;
-				break;
-			case GN_FIRE_EXPANSION:
-				if( i < 5 )
-					continue;
-				break;
-			case SO_SUMMON_AGNI:
-			case SO_SUMMON_AQUA:
-			case SO_SUMMON_VENTUS:
-			case SO_SUMMON_TERA:
-			case SO_WATER_INSIGNIA:
-			case SO_FIRE_INSIGNIA:
-			case SO_WIND_INSIGNIA:
-			case SO_EARTH_INSIGNIA:
-				if( i < 3 )
-					continue;
-				break;
-		}
-
-		req.itemid[i] = skill_db[idx].require.itemid[i];
-		req.amount[i] = skill_db[idx].require.amount[i];
-
-		// Check requirement for gemstone.
-		if (itemid_isgemstone(req.itemid[i])) {
-			if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
-				req.itemid[i] = req.amount[i] = 0;
-			else {
-				if( sd->special_state.no_gemstone )
-				{	// All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
-					if( skill_id != SA_ABRACADABRA )
-		 				req.itemid[i] = req.amount[i] = 0;
-					else if( --req.amount[i] < 1 )
-						req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
-				}
-				if(sc && sc->data[SC_INTOABYSS])
-				{
-					if( skill_id != SA_ABRACADABRA )
-						req.itemid[i] = req.amount[i] = 0;
-					else if( --req.amount[i] < 1 )
-						req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
-				}
-			}
-		}
-		if( skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
-			int16 itIndex;
-			if( (itIndex = pc_search_inventory(sd,req.itemid[i])) < 0  || ( itIndex >= 0 && sd->status.inventory[itIndex].amount < req.amount[i] ) ){
-				req.itemid[i] = ITEMID_TRAP_ALLOY;
-				req.amount[i] = 1;
-			}
-			break;
-		}
-	}
-
-	/* requirements are level-dependent */
 	switch( skill_id ) {
+		/* Skill level-dependent checks */
 		case NC_SHAPESHIFT:
+		case NC_REPAIR:
+			//NOTE: Please make sure Magic_Gear_Fuel in the last position in skill_require_db.txt
+			req.itemid[1] = skill_db[idx].require.itemid[MAX_SKILL_ITEM_REQUIRE-1];
+			req.amount[1] = skill_db[idx].require.amount[MAX_SKILL_ITEM_REQUIRE-1];
 		case GN_FIRE_EXPANSION:
 		case SO_SUMMON_AGNI:
 		case SO_SUMMON_AQUA:
@@ -15033,26 +14957,74 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 		case SO_FIRE_INSIGNIA:
 		case SO_WIND_INSIGNIA:
 		case SO_EARTH_INSIGNIA:
-			req.itemid[skill_lv-1] = skill_db[idx].require.itemid[skill_lv-1];
-			req.amount[skill_lv-1] = skill_db[idx].require.amount[skill_lv-1];
+		case WZ_FIREPILLAR: // no gems required at level 1-5 [celest]
+			req.itemid[0] = skill_db[idx].require.itemid[min(skill_lv-1,MAX_SKILL_ITEM_REQUIRE-1)];
+			req.amount[0] = skill_db[idx].require.amount[min(skill_lv-1,MAX_SKILL_ITEM_REQUIRE-1)];
+			level_dependent = true;
+
+		/* Normal skill requirements and gemstone checks */
+		default:
+			for( i = 0; i < ((!level_dependent) ? MAX_SKILL_ITEM_REQUIRE : 2); i++ ) {
+				// Skip this for level_dependent requirement, just looking forward for gemstone removal. Assumed if there is gemstone there.
+				if (!level_dependent) {
+					switch( skill_id ) {
+						case AM_POTIONPITCHER:
+						case CR_SLIMPITCHER:
+						case CR_CULTIVATION:
+							if (i != skill_lv%11 - 1)
+								continue;
+							break;
+						case AM_CALLHOMUN:
+							if (sd->status.hom_id) //Don't delete items when hom is already out.
+								continue;
+							break;
+						case AB_ADORAMUS:
+							if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2)) )
+								continue;
+							break;
+						case WL_COMET:
+							if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0)) )
+								continue;
+							break;
+					}
+
+					req.itemid[i] = skill_db[idx].require.itemid[i];
+					req.amount[i] = skill_db[idx].require.amount[i];
+
+					if( skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
+						int16 itIndex;
+						if( (itIndex = pc_search_inventory(sd,req.itemid[i])) < 0  || ( itIndex >= 0 && sd->status.inventory[itIndex].amount < req.amount[i] ) ){
+							req.itemid[i] = ITEMID_TRAP_ALLOY;
+							req.amount[i] = 1;
+						}
+						break;
+					}
+				}
+
+				// Check requirement for gemstone.
+				if (itemid_isgemstone(req.itemid[i])) {
+					if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
+						req.itemid[i] = req.amount[i] = 0;
+					else {
+						if( sd->special_state.no_gemstone )
+						{	// All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
+							if( skill_id != SA_ABRACADABRA )
+		 						req.itemid[i] = req.amount[i] = 0;
+							else if( --req.amount[i] < 1 )
+								req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
+						}
+						if(sc && sc->data[SC_INTOABYSS])
+						{
+							if( skill_id != SA_ABRACADABRA )
+								req.itemid[i] = req.amount[i] = 0;
+							else if( --req.amount[i] < 1 )
+								req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
+						}
+					}
+				}
+			}
 			break;
 	}
-	if (skill_id == NC_REPAIR) {
-		switch(skill_lv) {
-			case 1:
-			case 2:
-				req.itemid[1] = ITEMID_REPAIR_A;
-				break;
-			case 3:
-			case 4:
-				req.itemid[1] = ITEMID_REPAIR_B;
-				break;
-			case 5:
-				req.itemid[1] = ITEMID_REPAIR_C;
-				break;
-		}
-		req.amount[1] = 1;
-	}
 
 	// Check for cost reductions due to skills & SCs
 	switch(skill_id) {
@@ -19350,29 +19322,37 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current)
 	return true;
 }
 
-/** Split string to int or constanta value (const.txt)
+/** Split string to int by constanta value (const.txt) or atoi()
 * @param *str: String input
 * @param *val: Temporary storage
 * @param *delim: Delimiter (for multiple value support)
-* @param useConst: 'true' uses const.txt as reference, 'false' uses atoi()
-* @param min: Min value of each const. Example: SC has min value SC_NONE (-1), so the value that less or equal won't be counted
+* @param min_value: Minimum value. If the splitted value is less or equal than this, will be skipped
+* @param max: Maximum number that can be allocated
 * @return count: Number of success
 */
-uint8 skill_split2(char *str, int *val, const char *delim, bool useConst, short min) {
+uint8 skill_split_atoi2(char *str, int *val, const char *delim, int min_value, uint16 max) {
 	uint8 i = 0;
-	char *p = strtok(str,delim);
+	char *p = strtok(str, delim);
 
 	while (p != NULL) {
-		int n = -1;
-		if (useConst)
-			script_get_constant(trim(p),&n);
-		else
+		int n = min_value;
+		trim(p);
+
+		if (ISDIGIT(p[0])) // If using numeric
 			n = atoi(p);
-		if (n > min) {
+		else if (!script_get_constant(p, &n)) { // If using constant value
+			ShowError("skill_split_atoi2: Invalid value: '%s'\n", p);
+			p = strtok(NULL, delim);
+			continue;
+		}
+
+		if (n > min_value) {
 			val[i] = n;
 			i++;
+			if (i >= max)
+				break;
 		}
-		p = strtok(NULL,delim);
+		p = strtok(NULL, delim);
 	}
 	return i;
 }
@@ -19383,8 +19363,10 @@ static void skill_destroy_requirement(void) {
 	for (i = 0; i < MAX_SKILL; i++) {
 		if (skill_db[i].require.status_count)
 			aFree(skill_db[i].require.status);
+		skill_db[i].require.status_count = 0;
 		if (skill_db[i].require.eqItem_count)
 			aFree(skill_db[i].require.eqItem);
+		skill_db[i].require.eqItem_count = 0;
 	}
 }
 
@@ -19396,10 +19378,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	char* p;
 	uint16 skill_id = atoi(split[0]), idx, i;
 
-	if (!skill_get_index(skill_id)) // invalid skill id
+	if (!(idx = skill_get_index(skill_id))) // invalid skill id
 		return false;
 
-	idx = skill_get_index(skill_id);
 	skill_split_atoi(split[1],skill_db[idx].require.hp);
 	skill_split_atoi(split[2],skill_db[idx].require.mhp);
 	skill_split_atoi(split[3],skill_db[idx].require.sp);
@@ -19455,11 +19436,12 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	else skill_db[idx].require.state = ST_NONE;	// Unknown or no state
 
 	//Status requirements
+	//FIXME: Default entry should be -1/SC_ALL in skill_require_db.txt but it's 0/SC_STONE.
 	trim(split[11]);
-	if (split[11][0] != '\0') {
+	if (split[11][0] != '\0' || atoi(split[11])) {
 		int require[MAX_SKILL_STATUS_REQUIRE];
-		if ((skill_db[idx].require.status_count = skill_split2(split[11],require,":",true,SC_NONE))) {
-			skill_db[idx].require.status = aMalloc(skill_db[idx].require.status_count * sizeof(sc_type));
+		if ((skill_db[idx].require.status_count = skill_split_atoi2(split[11], require, ":", SC_STONE, ARRAYLENGTH(require)))) {
+			CREATE(skill_db[idx].require.status, enum sc_type, skill_db[idx].require.status_count);
 			for (i = 0; i < skill_db[idx].require.status_count; i++)
 				skill_db[idx].require.status[i] = (sc_type)require[i];
 		}
@@ -19475,10 +19457,10 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	//Equipped Item requirements.
 	//NOTE: We don't check the item is exist or not here
 	trim(split[33]);
-	if (split[33][0] != '\0') {
+	if (split[33][0] != '\0' || atoi(split[33])) {
 		int require[MAX_SKILL_EQUIP_REQUIRE];
-		if ((skill_db[idx].require.eqItem_count = skill_split2(split[33],require,":",false,501))) {
-			skill_db[idx].require.eqItem = aMalloc(skill_db[idx].require.eqItem_count * sizeof(short));
+		if ((skill_db[idx].require.eqItem_count = skill_split_atoi2(split[33], require, ":", 500, ARRAYLENGTH(require)))) {
+			CREATE(skill_db[idx].require.eqItem, uint16, skill_db[idx].require.eqItem_count);
 			for (i = 0; i < skill_db[idx].require.eqItem_count; i++)
 				skill_db[idx].require.eqItem[i] = require[i];
 		}
@@ -19490,8 +19472,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 * SkillID,CastingTime,AfterCastActDelay,AfterCastWalkDelay,Duration1,Duration2,Cooldown{,Fixedcast}
 */
 static bool skill_parse_row_castdb(char* split[], int columns, int current) {
-	uint16 skill_id = atoi(split[0]);
-	uint16 idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(atoi(split[0]));
 	if( !idx ) // invalid skill id
 		return false;
 
@@ -19511,8 +19492,7 @@ static bool skill_parse_row_castdb(char* split[], int columns, int current) {
 * SkillID,Cast,Delay (optional)
 */
 static bool skill_parse_row_castnodexdb(char* split[], int columns, int current) {
-	uint16 skill_id = atoi(split[0]);
-	uint16 idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(atoi(split[0]));
 	if( !idx ) // invalid skill id
 		return false;
 
@@ -19527,8 +19507,7 @@ static bool skill_parse_row_castnodexdb(char* split[], int columns, int current)
 * SkillID,Flag
 */
 static bool skill_parse_row_nocastdb(char* split[], int columns, int current) {
-	uint16 skill_id = atoi(split[0]);
-	uint16 idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(atoi(split[0]));
 	if( !idx ) // invalid skill id
 		return false;
 
@@ -19541,8 +19520,7 @@ static bool skill_parse_row_nocastdb(char* split[], int columns, int current) {
 * ID,unit ID,unit ID 2,layout,range,interval,target,flag
 */
 static bool skill_parse_row_unitdb(char* split[], int columns, int current) {
-	uint16 skill_id = atoi(split[0]);
-	uint16 idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(atoi(split[0]));
 	if( !idx ) // invalid skill id
 		return false;
 
@@ -19635,7 +19613,7 @@ static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
 
 	if( !skill_get_index(skill_id) || !skill_get_max(skill_id) )
 		ShowError("spellbook_db: Invalid skill ID %d\n", skill_id);
-	if ( !skill_get_inf(skill_id) )
+	if( !skill_get_inf(skill_id) )
 		ShowError("spellbook_db: Passive skills cannot be memorized (%d/%s)\n", skill_id, skill_get_name(skill_id));
 	if( points < 1 )
 		ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skill_id, skill_get_name(skill_id));
@@ -19709,12 +19687,12 @@ static bool skill_parse_row_copyabledb(char* split[], int column, int current) {
 	uint8 option;
 
 	trim(split[0]);
-	if(ISDIGIT(split[0][0]))
+	if (ISDIGIT(split[0][0]))
 		id = atoi(split[0]);
 	else
 		id = skill_name2id(split[0]);
 
-	if ((id = skill_get_index(id)) < 0) {
+	if ((id = skill_get_index(id)) == 0) {
 		ShowError("skill_parse_row_copyabledb: Invalid skill '%s'\n",split[0]);
 		return false;
 	}
@@ -19739,12 +19717,12 @@ static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int curr
 	int16 id;
 
 	trim(split[0]);
-	if(ISDIGIT(split[0][0]))
+	if (ISDIGIT(split[0][0]))
 		id = atoi(split[0]);
 	else
 		id = skill_name2id(split[0]);
 
-	if ((id = skill_get_index(id)) < 0) { // invalid skill id
+	if ((id = skill_get_index(id)) == 0) { // invalid skill id
 		ShowError("skill_parse_row_nonearnpcrangedb: Invalid skill '%s'\n",split[0]);
 		return false;
 	}
@@ -19811,27 +19789,27 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
 	return true;
 }
 
-/*==========================================
+/**
  * Manage Skill Damage database [Lilith]
- *------------------------------------------*/
+ **/
 #ifdef ADJUST_SKILL_DAMAGE
 static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
 {
 	uint16 skill_id = skill_name2id(split[0]), idx;
-	if ((idx = skill_get_index(skill_id)) < 0) { // invalid skill id
+	if ((idx = skill_get_index(skill_id)) == 0) { // invalid skill id
 		ShowWarning("skill_parse_row_skilldamage: Invalid skill '%s'. Skipping..",split[0]);
 		return false;
 	}
 	memset(&skill_db[idx].damage,0,sizeof(struct s_skill_damage));
 	skill_db[idx].damage.caster |= atoi(split[1]);
 	skill_db[idx].damage.map |= atoi(split[2]);
-	skill_db[idx].damage.pc = cap_value(atoi(split[3]),-100,MAX_SKILL_DAMAGE_RATE);
+	skill_db[idx].damage.pc = cap_value(atoi(split[3]),-100,INT_MAX);
 	if (split[3])
-		skill_db[idx].damage.mob = cap_value(atoi(split[4]),-100,MAX_SKILL_DAMAGE_RATE);
+		skill_db[idx].damage.mob = cap_value(atoi(split[4]),-100,INT_MAX);
 	if (split[4])
-		skill_db[idx].damage.boss = cap_value(atoi(split[5]),-100,MAX_SKILL_DAMAGE_RATE);
+		skill_db[idx].damage.boss = cap_value(atoi(split[5]),-100,INT_MAX);
 	if (split[5])
-		skill_db[idx].damage.other = cap_value(atoi(split[6]),-100,MAX_SKILL_DAMAGE_RATE);
+		skill_db[idx].damage.other = cap_value(atoi(split[6]),-100,INT_MAX);
 	return true;
 }
 #endif

+ 42 - 38
src/map/skill.h

@@ -22,6 +22,8 @@ struct status_change_entry;
 #define MAX_SKILL_IMPROVISE_DB 50
 #define MAX_SKILL_LEVEL 100
 #define MAX_SKILL_CRIMSON_MARKER 3
+#define SKILL_NAME_LENGTH 31
+#define SKILL_DESC_LENGTH 31
 
 DBMap* skilldb_name2id;
 
@@ -104,51 +106,53 @@ enum e_skill_display {
 	SD_PREAMBLE  = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
 };
 
-#define MAX_SKILL_ITEM_REQUIRE	10
-#define MAX_SKILL_STATUS_REQUIRE 3
-#define MAX_SKILL_EQUIP_REQUIRE 10
+#define MAX_SKILL_ITEM_REQUIRE	10 /// Maximum required items
+#define MAX_SKILL_STATUS_REQUIRE 3 /// Maximum required statuses
+#define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
 struct skill_condition {
-	int hp,
-		mhp,
-		sp,
-		hp_rate,
-		sp_rate,
-		ammo,
-		ammo_qty,
-		weapon,
-		zeny,
-		state,
-		spiritball,
-		itemid[MAX_SKILL_ITEM_REQUIRE],
-		amount[MAX_SKILL_ITEM_REQUIRE];
-	short *eqItem;
-	enum sc_type *status;
-	uint8 status_count, eqItem_count;
+	int hp, /// HP cost
+		mhp, /// Max HP to trigger
+		sp, /// SP cost
+		hp_rate, /// HP cost (%)
+		sp_rate, /// SP cost (%)
+		ammo, /// Ammo type
+		ammo_qty, /// Amount of ammo
+		weapon, /// Weapon type
+		zeny, /// Zeny cost
+		state, /// State/condition
+		spiritball, /// Spiritball cost
+		itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
+		amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
+	uint16 *eqItem; /// List of equipped item
+	enum sc_type *status; /// List of Status required (SC)
+	uint8 status_count, /// Count of SC
+		eqItem_count; /// Count of equipped item
 };
 
 struct s_skill_require {
-	int hp[MAX_SKILL_LEVEL],
-		mhp[MAX_SKILL_LEVEL],
-		sp[MAX_SKILL_LEVEL],
-		hp_rate[MAX_SKILL_LEVEL],
-		sp_rate[MAX_SKILL_LEVEL],
-		zeny[MAX_SKILL_LEVEL],
-		weapon,
-		ammo,
-		ammo_qty[MAX_SKILL_LEVEL],
-		state,
-		spiritball[MAX_SKILL_LEVEL],
-		itemid[MAX_SKILL_ITEM_REQUIRE],
-		amount[MAX_SKILL_ITEM_REQUIRE];
-	short *eqItem;
-	enum sc_type *status;
-	uint8 status_count, eqItem_count;
+	int hp[MAX_SKILL_LEVEL], /// HP cost
+		mhp[MAX_SKILL_LEVEL], /// Max HP to trigger
+		sp[MAX_SKILL_LEVEL], /// SP cost
+		hp_rate[MAX_SKILL_LEVEL], /// HP cost (%)
+		sp_rate[MAX_SKILL_LEVEL], /// SP cost (%)
+		zeny[MAX_SKILL_LEVEL], /// Zeny cost
+		weapon, /// Weapon type
+		ammo, /// Ammo type
+		ammo_qty[MAX_SKILL_LEVEL], /// Amount of ammo
+		state, /// State/condition
+		spiritball[MAX_SKILL_LEVEL], /// Spiritball cost
+		itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
+		amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
+	uint16 *eqItem; /// List of equipped item
+	enum sc_type *status; /// List of Status required (SC)
+	uint8 status_count, /// Count of SC
+		eqItem_count; /// Count of equipped item
 };
 
 /// Database skills
 struct s_skill_db {
-	char name[NAME_LENGTH];
-	char desc[40];
+	char name[SKILL_NAME_LENGTH];
+	char desc[SKILL_DESC_LENGTH];
 	int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
 	int num[MAX_SKILL_LEVEL];
 	int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL];
@@ -261,7 +265,7 @@ enum {
 	UF_ENSEMBLE      = 0x0200,	// Duet
 	UF_SONG          = 0x0400,	// Song
 	UF_DUALMODE      = 0x0800,	// Spells should trigger both ontimer and onplace/onout/onleft effects.
-    UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center
+	UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center
 };
 
 /// Create Database item

+ 16 - 12
src/map/status.c

@@ -821,11 +821,11 @@ void initChangeTables(void)
 	add_sc( RL_HAMMER_OF_GOD	, SC_STUN );
 	set_sc( RL_B_TRAP		, SC_B_TRAP		, SI_B_TRAP		, SCB_SPEED );
 	set_sc( RL_E_CHAIN		, SC_E_CHAIN	, SI_E_CHAIN	, SCB_NONE );
-	set_sc( RL_P_ALTER		, SC_P_ALTER	, SI_P_ALTER	, SCB_BATK );
+	set_sc( RL_P_ALTER		, SC_P_ALTER	, SI_P_ALTER	, SCB_NONE );
 	set_sc( RL_SLUGSHOT		, SC_STUN		, SI_SLUGSHOT	, SCB_NONE );
-	set_sc( RL_HEAT_BARREL	, SC_HEAT_BARREL	, SI_HEAT_BARREL	, SCB_BATK|SCB_ASPD|SCB_HIT );
-	set_sc_with_vfx( RL_C_MARKER	, SC_C_MARKER		, SI_C_MARKER		, SCB_SPEED );
-	set_sc_with_vfx( RL_AM_BLAST	, SC_ANTI_M_BLAST	, SI_ANTI_M_BLAST	, SCB_DEF_ELE );
+	set_sc( RL_HEAT_BARREL	, SC_HEAT_BARREL	, SI_HEAT_BARREL	, SCB_FLEE|SCB_ASPD );
+	set_sc_with_vfx( RL_C_MARKER	, SC_C_MARKER		, SI_C_MARKER		, SCB_FLEE );
+	set_sc_with_vfx( RL_AM_BLAST	, SC_ANTI_M_BLAST	, SI_ANTI_M_BLAST	, SCB_NONE );
 
 	set_sc_with_vfx( SC_ALL_RIDING		, SC_ALL_RIDING		, SI_ALL_RIDING		, SCB_SPEED );
 
@@ -855,7 +855,7 @@ void initChangeTables(void)
 	StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
 	StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
 	StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
-	StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
+	StatusIconChangeTable[SC_CHASEWALK2] = SI_CHASEWALK2;
 	StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
 	StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
 	StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
@@ -1055,6 +1055,7 @@ void initChangeTables(void)
 	StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
 	StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED;
+	StatusChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
 
 	/* Cash Items */
 	StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
@@ -4749,6 +4750,8 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
 		return 50;
 	if(sc->data[SC_INCALLSTATUS])
 		str += sc->data[SC_INCALLSTATUS]->val1;
+	if(sc->data[SC_CHASEWALK2])
+		str += sc->data[SC_CHASEWALK2]->val1;
 	if(sc->data[SC_INCSTR])
 		str += sc->data[SC_INCSTR]->val1;
 	if(sc->data[SC_STRFOOD])
@@ -5174,7 +5177,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 	if(sc->data[SC__ENERVATION])
 		batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
 	if( sc->data[SC_ZANGETSU] )
-		batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
+		batk += sc->data[SC_ZANGETSU]->val2;
 	if(sc->data[SC_EQC])
 		batk -= batk * sc->data[SC_EQC]->val3 / 100;
 	if(sc->data[SC_QUEST_BUFF1])
@@ -5543,7 +5546,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
 	if (sc->data[SC_TEARGAS])
 		flee -= flee * 50 / 100;
 	if( sc->data[SC_C_MARKER] )
-		flee -= 10;
+		flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100;
 	if(sc->data[SC_HEAT_BARREL])
 		flee -= sc->data[SC_HEAT_BARREL]->val4;
 
@@ -9695,7 +9698,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			break;
 		case SC_PAIN_KILLER: // Yommy leak need confirm
 			val2 = 10 * val1; // aspd reduction %
-			val3 = (( 200 * val1 ) * status_get_lv(src)) / 150; // dmg reduction linear
+			val3 = min((( 200 * val1 ) * status_get_lv(src)) / 150, 1000); // dmg reduction linear. upto a maximum of 1000 [iRO Wiki]
 			if(sc->data[SC_PARALYSIS])
 				sc_start(src,bl, SC_ENDURE, 100, val1, tick); // Start endure for same duration
 			break;
@@ -9775,8 +9778,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			break;
 		case SC_C_MARKER:
 			val2 = src->id;
+			val3 = 10; //-10% flee
 			//Start timer to send mark on mini map
-			val3 = tick/1000;
+			val4 = tick/1000;
 			tick_time = 1000;
 			break;
 		case SC_H_MINE:
@@ -11256,8 +11260,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 		if(!status_charge(bl, 0, sce->val4))
 			break; // Not enough SP to continue.
 
-		if (!sc->data[SC_INCSTR]) {
-			sc_start(bl,bl, SC_INCSTR,100,1<<(sce->val1-1),
+		if (!sc->data[SC_CHASEWALK2]) {
+			sc_start(bl,bl, SC_CHASEWALK2,100,1<<(sce->val1-1),
 				(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) // SL bonus -> x10 duration
 				*skill_get_time2(status_sc2skill(type),sce->val1));
 		}
@@ -12039,7 +12043,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 		}
 		break;
 	case SC_C_MARKER:
-		if( --(sce->val3) >= 0 ) {
+		if( --(sce->val4) >= 0 ) {
 			TBL_PC *tsd = map_id2sd(sce->val2);
 			if (!tsd || tsd->bl.m != bl->m) //End the SC if caster isn't in same map
 				break;

+ 2 - 1
src/map/status.h

@@ -701,6 +701,7 @@ typedef enum sc_type {
 	SC__FEINTBOMB,
 	SC__CHAOS,
 	SC_ELEMENTAL_SHIELD,
+	SC_CHASEWALK2,
 
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
@@ -893,7 +894,7 @@ enum si_type {
 //	SI_DEFENCE = 179,
 //	SI_SLOWDOWN = 180,
 	SI_PRESERVE		= 181,
-	SI_INCSTR		= 182,
+	SI_CHASEWALK2	= 182,
 //	SI_NOT_EXTREMITYFIST = 183,
 	SI_INTRAVISION		= 184,
 //	SI_MOVESLOW_POTION = 185,

+ 2 - 2
src/map/storage.c

@@ -180,7 +180,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
 		return 1;
 	}
 
-	if( (item_data->bound > 1) && !pc_can_give_bounded_items(sd) ) {
+	if( (item_data->bound > BOUND_ACCOUNT) && !pc_can_give_bounded_items(sd) ) {
 		clif_displaymessage(sd->fd, msg_txt(sd,294));
 		return 1;
 	}
@@ -519,7 +519,7 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
 		return 1;
 	}
 
-	if( (item_data->bound == 1 || item_data->bound > 2) && !pc_can_give_bounded_items(sd) ) {
+	if( (item_data->bound == BOUND_ACCOUNT || item_data->bound > BOUND_GUILD) && !pc_can_give_bounded_items(sd) ) {
 		clif_displaymessage(sd->fd, msg_txt(sd,294));
 		return 1;
 	}

+ 1 - 1
src/map/trade.c

@@ -379,7 +379,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
 		return;
 	}
 
-	if( ((item->bound == 1 || item->bound > 2) || (item->bound == 2 && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound
+	if( ((item->bound == BOUND_ACCOUNT || item->bound > BOUND_GUILD) || (item->bound == BOUND_GUILD && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound
 		clif_displaymessage(sd->fd, msg_txt(sd,293));
 		clif_tradeitemok(sd, index+2, 1);
 		return;