Browse Source

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 years ago
parent
commit
794c1a8247

+ 7 - 1
db/const.txt

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

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

@@ -4,3 +4,4 @@
 // <Flag>:
 // <Flag>:
 // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
 // 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
 // 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>:
 // <Flag>:
 // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
 // 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
 // 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
 // Logged as Dead Branch item
 604,1 //Branch_Of_Dead_Tree
 604,1 //Branch_Of_Dead_Tree

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

@@ -118,7 +118,7 @@
 
 
 //****
 //****
 // WZ Wizard
 // 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
 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
 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
 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
 // 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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; }
 15068:20710,{ bonus bAgi,5; bonus bFlee,10; }
 15088:18816:18818,{ bonus bMatk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; }
 15088:18816:18818,{ bonus bMatk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; }
 15088:18817:18819,{ bonus bBaseAtk,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; }
 18507:18539,{ bonus bUseSPrate,-3; }
 18538:5041,{ bonus2 bSubRace,RC_Angel,9; }
 18538:5041,{ bonus2 bSubRace,RC_Angel,9; }
 18538:5048,{ bonus2 bSubRace,RC_Demon,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;}
 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:20710,{ bonus bBaseAtk,10; }
 18776:22015,{ bonus bMatk,20; }
 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; }
 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; } }
 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; } }
 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; }
 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; }
 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; }
 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; }
 28326:28327,{ bonus bInt,8; bonus bStr,8; }

+ 1 - 0
db/re/item_flag.txt

@@ -4,6 +4,7 @@
 // <Flag>:
 // <Flag>:
 // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
 // 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
 // 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
 // Logged as Dead Branch item
 604,1 //Branch_Of_Dead_Tree
 604,1 //Branch_Of_Dead_Tree

+ 12 - 12
db/re/skill_require_db.txt

@@ -118,7 +118,7 @@
 
 
 //****
 //****
 // WZ Wizard
 // 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
 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
 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
 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
 // 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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.
 some cases cannot be traded or stored.
 
 
 Valid bound types are:
 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 id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
 *cartdelitem2 "<item name>",<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.
 Same like delitem2, but deletes item from cart or storage.
 If cart is not mounted, it will be failed.
 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,14, &data, NULL); msg->item.identify = atoi(data);
 		Sql_GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10);
 		Sql_GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10);
 		msg->item.expire_time = 0;
 		msg->item.expire_time = 0;
-		msg->item.bound = 0;
+		msg->item.bound = BOUND_NONE;
 
 
 		for( j = 0; j < MAX_SLOTS; j++ )
 		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);
 		SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
 
 
 	while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) {
 	while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) {
-		if(item.bound == 2) {
+		if(item.bound == BOUND_GUILD) {
 			memcpy(&items[i],&item,sizeof(struct item));
 			memcpy(&items[i],&item,sizeof(struct item));
 			i++;
 			i++;
 		}
 		}

+ 10 - 0
src/common/mmo.h

@@ -785,6 +785,16 @@ enum {
 	SEX_SERVER
 	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...
 // sanity checks...
 #if MAX_ZENY > INT_MAX
 #if MAX_ZENY > INT_MAX
 #error MAX_ZENY is too big
 #error MAX_ZENY is too big

+ 1 - 6
src/config/core.h

@@ -62,12 +62,7 @@
 /// Uncomment to enable skills damage adjustments
 /// Uncomment to enable skills damage adjustments
 /// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the
 /// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the
 /// damage rate of specified skills.
 /// 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)
 /// Uncomment to enable the job base HP/SP table (job_basehpsp_db.txt)
 //#define HP_SP_TABLES
 //#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 char   global_db_hostname[32] = "127.0.0.1";
 static uint16 global_db_port = 3306;
 static uint16 global_db_port = 3306;
 static char   global_db_username[32] = "ragnarok";
 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_db_database[32] = "ragnarok";
 static char   global_codepage[32] = "";
 static char   global_codepage[32] = "";
 // local sql settings
 // local sql settings

+ 30 - 25
src/map/atcommand.c

@@ -1198,7 +1198,7 @@ ACMD_FUNC(heal)
 ACMD_FUNC(item)
 ACMD_FUNC(item)
 {
 {
 	char item_name[100];
 	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 item_tmp;
 	struct item_data *item_data[10];
 	struct item_data *item_data[10];
 	int get_count, i, j=0;
 	int get_count, i, j=0;
@@ -1207,12 +1207,19 @@ ACMD_FUNC(item)
 	nullpo_retr(-1, sd);
 	nullpo_retr(-1, sd);
 	memset(item_name, '\0', sizeof(item_name));
 	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 || (
 	} else if (!message || !*message || (
 		sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
 		sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
 		sscanf(message, "%99s %d", item_name, &number) < 1
 		sscanf(message, "%99s %d", item_name, &number) < 1
@@ -1231,11 +1238,6 @@ ACMD_FUNC(item)
 		j++;
 		j++;
 	}
 	}
 
 
-	if( bound < 0 || bound > 4 ) {
-		clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
-		return -1;
-	}
-
 	if (number <= 0)
 	if (number <= 0)
 		number = 1;
 		number = 1;
 	get_count = number;
 	get_count = number;
@@ -1273,19 +1275,27 @@ ACMD_FUNC(item2)
 	struct item item_tmp;
 	struct item item_tmp;
 	struct item_data *item_data;
 	struct item_data *item_data;
 	char item_name[100];
 	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 identify = 0, refine = 0, attr = 0;
 	int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 	int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 	nullpo_retr(-1, sd);
 	nullpo_retr(-1, sd);
 
 
 	memset(item_name, '\0', sizeof(item_name));
 	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 || (
 	} 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, "\"%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
 		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)
 	if (number <= 0)
 		number = 1;
 		number = 1;
 
 
-	if( bound < 0 || bound > 4 ) {
-		clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
-		return -1;
-	}
-
 	item_id = 0;
 	item_id = 0;
 	if ((item_data = itemdb_searchname(item_name)) != NULL ||
 	if ((item_data = itemdb_searchname(item_name)) != NULL ||
 	    (item_data = itemdb_exists(atoi(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) {
 				if (map[m_id].skill_damage[j].skill_id) {
 					sprintf(atcmd_output,"     %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
 					sprintf(atcmd_output,"     %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
 						,j+1
 						,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].pc
 						,map[m_id].skill_damage[j].mob
 						,map[m_id].skill_damage[j].mob
 						,map[m_id].skill_damage[j].boss
 						,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)
 			DAMAGE_SUBRATE(sc->data[SC_GRANITIC_ARMOR]->val2)
 
 
 		if(sc->data[SC_PAIN_KILLER])
 		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 )
 		if( sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT )
 			DAMAGE_ADDRATE(sc->data[SC_DARKCROW]->val2);
 			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;
 	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
 #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)
 	if (caster == 0)
 		return false;
 		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;
 	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;
 		return 0;
 
 
 	damage = &skill_db[idx].damage;
 	damage = &skill_db[idx].damage;
 
 
 	//check the adjustment works for specified type
 	//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;
 		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)) ||
 	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;
 	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;
 	int rate = 0;
 	uint16 m = src->m;
 	uint16 m = src->m;
 	uint8 i;
 	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)
 	if (!map[m].flag.skill_damage)
 		return 0;
 		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) {
 		switch (target->type) {
 			case BL_PC:
 			case BL_PC:
 				rate = map[m].adjust.damage.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) {
 			switch (target->type) {
 				case BL_PC:
 				case BL_PC:
 					rate += map[m].skill_damage[i].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;
 	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)
 	if (!target)
 		return 0;
 		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
 #endif
 
 
@@ -2865,9 +2874,9 @@ struct Damage battle_calc_skill_base_damage(struct Damage wd, struct block_list
 }
 }
 
 
 //For quick div adjustment.
 //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
  * 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;
 			break;
 		case RL_D_TAIL:
 		case RL_D_TAIL:
 			skillratio += -100 + (2500 + 500 * skill_lv );
 			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;
 			break;
 		case RL_R_TRIP:
 		case RL_R_TRIP:
 			skillratio += -100 + (150 * skill_lv); //(custom)
 			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:
 		case RL_FIRE_RAIN:
 			skillratio += -100 + 2000 + status_get_dex(src); //(custom) //kRO Update 2013-07-24. 2,000% + caster's DEX (?) [Cydh]
 			skillratio += -100 + 2000 + status_get_dex(src); //(custom) //kRO Update 2013-07-24. 2,000% + caster's DEX (?) [Cydh]
 			break;
 			break;
+		case RL_AM_BLAST:
+			skillratio += -100 + (skill_lv * status_get_dex(src) / 2); //(custom)
+			break;
 	}
 	}
 	return skillratio;
 	return skillratio;
 }
 }
@@ -4656,7 +4668,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
 #endif
 #endif
 	}
 	}
 
 
-	/* Skill damage adjustment */
+	// Skill damage adjustment
 #ifdef ADJUST_SKILL_DAMAGE
 #ifdef ADJUST_SKILL_DAMAGE
 	if ((skill_damage = battle_skill_damage(src, target, skill_id)) != 0)
 	if ((skill_damage = battle_skill_damage(src, target, skill_id)) != 0)
 		ATK_ADDRATE(wd.damage, wd.damage2, skill_damage);
 		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
 	// perform multihit calculations
-	damage_div_fix_renewal(wd, wd.div_);
+	DAMAGE_DIV_FIX_RENEWAL(wd, wd.div_);
 #endif
 #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
 	// only do 1 dmg to plant, no need to calculate rest
 	if(target_has_infinite_defense(target, skill_id))
 	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
 #endif
 	}
 	}
 
 
-	damage_div_fix(ad.damage, ad.div_);
+	DAMAGE_DIV_FIX(ad.damage, ad.div_);
 
 
 	if (flag.infdef && ad.damage)
 	if (flag.infdef && ad.damage)
 		ad.damage = ad.damage>0?1:-1;
 		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;
 			break;
 	}
 	}
 
 
-	/* Skill damage adjustment */
+	// Skill damage adjustment
 #ifdef ADJUST_SKILL_DAMAGE
 #ifdef ADJUST_SKILL_DAMAGE
 	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
 	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
 		MATK_ADDRATE(skill_damage);
 		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) {
 		if (skill_id == SN_FALCONASSAULT) {
 			//Div fix of Blitzbeat
 			//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
 			//Falcon Assault Modifier
 			md.damage=(int64)md.damage*(150+70*skill_lv)/100;
 			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));
 			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))
 	if (!(nk&NK_IGNORE_FLEE))
 	{
 	{
@@ -6294,7 +6306,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 		break;
 		break;
 	}
 	}
 
 
-	/* Skill damage adjustment */
+	// Skill damage adjustment
 #ifdef ADJUST_SKILL_DAMAGE
 #ifdef ADJUST_SKILL_DAMAGE
 	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
 	if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
 		md.damage += (int64)md.damage * skill_damage / 100;
 		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;
 		WFIFOL(fd,offs+23)=sd->status.inventory[n].expire_time;
 #endif
 #endif
 #if PACKETVER >= 20071002
 #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
 #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
 		clif_addcards(WBUFP(buf, n+12), i); //8B
 #if PACKETVER >= 20071002
 #if PACKETVER >= 20071002
 		WBUFL(buf,n+20)=i->expire_time;
 		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
 #endif
 #if PACKETVER >= 20100629
 #if PACKETVER >= 20100629
 		WBUFW(buf,n+26)= (id->equip&EQP_VISIBLE)?id->look:0;
 		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;
 	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);
 	nullpo_retr(1,ed);
 
 
 	if (idx == 0)
 	if (idx == 0)
-		return 1; // invalid skill id
+		return false; // invalid skill id
 
 
 	return skill_isNotOk(skill_id,ed->master);
 	return skill_isNotOk(skill_id,ed->master);
 }
 }
 
 
 struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
 struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
 	struct skill_condition req;
 	struct skill_condition req;
-	int idx = skill_get_index(skill_id);
+	uint16 idx = skill_get_index(skill_id);
 
 
 	memset(&req,0,sizeof(req));
 	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_get_lifetime(struct elemental_data *ed);
 
 
 int elemental_unlocktarget(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_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_single_effect(struct elemental_data *ed, uint16 skill_id);
 int elemental_clean_effect(struct elemental_data *ed);
 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
 	//Guild bound item check - Removes the bound flag
 	j = pc_bound_chk(sd,2,idxlist);
 	j = pc_bound_chk(sd,2,idxlist);
 	for(i=0;i<j;i++)
 	for(i=0;i<j;i++)
-		sd->status.inventory[idxlist[i]].bound = 0;
+		sd->status.inventory[idxlist[i]].bound = BOUND_NONE;
 #endif
 #endif
 
 
 	intif_guild_break(g->guild_id);
 	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;
 	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_WEAPON:
 		case IT_ARMOR:
 		case IT_ARMOR:
 		case IT_AMMO:
 		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_WEAPON:
 	  case IT_ARMOR:
 	  case IT_ARMOR:
 	  case IT_PETEGG:
 	  case IT_PETEGG:
@@ -665,7 +632,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
 		unsigned int j, prob = 1;
 		unsigned int j, prob = 1;
 		uint16 nameid, amt = 1, dur = 0;
 		uint16 nameid, amt = 1, dur = 0;
 		uint8 rand_group = 1;
 		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_random *random = NULL;
 		struct s_item_group_db *group = NULL;
 		struct s_item_group_db *group = NULL;
 		bool found = false;
 		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[5] != NULL) announced = atoi(str[5]);
 		if (str[6] != NULL) dur = cap_value(atoi(str[6]),0,UINT16_MAX);
 		if (str[6] != NULL) dur = cap_value(atoi(str[6]),0,UINT16_MAX);
 		if (str[7] != NULL) named = atoi(str[7]);
 		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;
 		found = true;
 		if (!(group = (struct s_item_group_db *) idb_get(itemdb_group, group_id))) {
 		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
 /** Misc Item flags
 * <item_id>,<flag>
 * <item_id>,<flag>
-* &1 - Log as dead branch
+* &1 - As dead branch item
 * &2 - As item container
 * &2 - As item container
 */
 */
 static bool itemdb_read_flag(char* fields[], int columns, int current) {
 static bool itemdb_read_flag(char* fields[], int columns, int current) {
 	uint16 nameid = atoi(fields[0]);
 	uint16 nameid = atoi(fields[0]);
-	uint8 flag = atoi(fields[1]);
+	uint8 flag;
+	bool set;
 	struct item_data *id;
 	struct item_data *id;
 
 
 	if (!(id = itemdb_exists(nameid))) {
 	if (!(id = itemdb_exists(nameid))) {
 		ShowError("itemdb_read_flag: Invalid item item with id %d\n", nameid);
 		ShowError("itemdb_read_flag: Invalid item item with id %d\n", nameid);
 		return true;
 		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;
 	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++ ) {
 		for( i = 0; i < self->combos_count; i++ ) {
 			if( !self->combos[i]->isRef ) {
 			if( !self->combos[i]->isRef ) {
 				aFree(self->combos[i]->nameid);
 				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]);
 			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_canmail(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canmail_sub)
 #define itemdb_canauction(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canauction_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);
 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
 uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
 bool itemdb_isNoEquip(struct item_data *id, uint16 m);
 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;
 int map_server_port = 3306;
 char map_server_ip[32] = "127.0.0.1";
 char map_server_ip[32] = "127.0.0.1";
 char map_server_id[32] = "ragnarok";
 char map_server_id[32] = "ragnarok";
-char map_server_pw[32] = "ragnarok";
+char map_server_pw[32] = "";
 char map_server_db[32] = "ragnarok";
 char map_server_db[32] = "ragnarok";
 Sql* mmysql_handle;
 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_GLORYWOUNDS, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_SOULCOLD, 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_HAWKEYES, INVALID_TIMER);
+		status_change_end(&sd->bl, SC_CHASEWALK2, INVALID_TIMER);
 		if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
 		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_ENDURE, INVALID_TIMER); //No need to save infinite endure.
 		status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
 		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);
 	int skill_id = va_arg(args, int);
 
 
 	if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
 	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) {
 			while (1) {
 				if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break;
 				if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break;
 				if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) 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;
 		map[m].flag.notomb = state;
 	else if (!strcmpi(w3,"skill_damage")) {
 	else if (!strcmpi(w3,"skill_damage")) {
 #ifdef ADJUST_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;
 		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;
 	return 0;
 }
 }
 
 
-/*==========================================
+/**
  * Searching a specified itemid in inventory and return his stored index
  * 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;
 	int16 i;
 	nullpo_retr(-1, sd);
 	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;
 	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;
 		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]
 	{ // Check item trade restrictions	[Skotlex]
 		clif_displaymessage (sd->fd, msg_txt(sd,264));
 		clif_displaymessage (sd->fd, msg_txt(sd,264));
 		return 1;
 		return 1;
@@ -4896,7 +4898,7 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
  * 3 Party Bound
  * 3 Party Bound
  * 4 Character 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;
 	int i=0, j=0;
 	for(i=0;i<MAX_INVENTORY;i++){
 	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
  * @param lv : skill lv
  * @return player skill cooldown
  * @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 (!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 += sd->skillcooldown[i].val;
 		cooldown = max(0,cooldown);
 		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_equippoint(struct map_session_data *sd,int n);
 int pc_setinventorydata(struct map_session_data *sd);
 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);
 int pc_checkskill(struct map_session_data *sd,uint16 skill_id);
 short pc_checkequip(struct map_session_data *sd,int pos);
 short pc_checkequip(struct map_session_data *sd,int pos);
 bool pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max);
 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_checkadditem(struct map_session_data*,int,int);
 int pc_inventoryblank(struct map_session_data*);
 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*);
 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);
 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_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);
 int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type);
 
 
 //Bound items
 //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
 // Special Shop System
 int pc_paycash( struct map_session_data *sd, int price, int points, e_log_pick_type type );
 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_Invisible",OPTION_INVISIBLE,false);
 	script_set_constant("Option_Orcish",OPTION_ORCISH,false);
 	script_set_constant("Option_Orcish",OPTION_ORCISH,false);
 	script_set_constant("Option_Wedding",OPTION_WEDDING,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_Chasewalk",OPTION_CHASEWALK,false);
 	script_set_constant("Option_Flying",OPTION_FLYING,false);
 	script_set_constant("Option_Flying",OPTION_FLYING,false);
 	script_set_constant("Option_Xmas",OPTION_XMAS,false);
 	script_set_constant("Option_Xmas",OPTION_XMAS,false);
@@ -6455,22 +6456,24 @@ BUILDIN_FUNC(getitem)
 
 
 	if( !strcmp(script_getfuncname(st),"getitembound") ) {
 	if( !strcmp(script_getfuncname(st),"getitembound") ) {
 		char bound = script_getnum(st,4);
 		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);
 			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) )
 	} else if( script_hasdata(st,4) )
 		sd=map_id2sd(script_getnum(st,4)); // <Account ID>
 		sd=map_id2sd(script_getnum(st,4)); // <Account ID>
 	else
 	else
 		sd=script_rid2sd(st); // Attached player
 		sd=script_rid2sd(st); // Attached player
 
 
 	if( sd == NULL ) // no target
 	if( sd == NULL ) // no target
-		return 0;
+		return SCRIPT_CMD_SUCCESS;
 
 
 	//Check if it's stackable.
 	//Check if it's stackable.
 	if (!itemdb_isstackable(nameid))
 	if (!itemdb_isstackable(nameid))
@@ -6499,9 +6502,9 @@ BUILDIN_FUNC(getitem)
  *------------------------------------------*/
  *------------------------------------------*/
 BUILDIN_FUNC(getitem2)
 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_data *item_data;
 	struct item item_tmp;
 	struct item item_tmp;
 	TBL_PC *sd;
 	TBL_PC *sd;
@@ -6509,21 +6512,23 @@ BUILDIN_FUNC(getitem2)
 
 
 	if( !strcmp(script_getfuncname(st),"getitembound2") ) {
 	if( !strcmp(script_getfuncname(st),"getitembound2") ) {
 		bound = script_getnum(st,11);
 		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);
 			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) )
 	} else if( script_hasdata(st,11) )
 		sd=map_id2sd(script_getnum(st,11)); // <Account ID>
 		sd=map_id2sd(script_getnum(st,11)); // <Account ID>
 	else
 	else
 		sd=script_rid2sd(st); // Attached player
 		sd=script_rid2sd(st); // Attached player
 
 
 	if( sd == NULL ) // no target
 	if( sd == NULL ) // no target
-		return 0;
+		return SCRIPT_CMD_SUCCESS;
 
 
 	data=script_getdata(st,2);
 	data=script_getdata(st,2);
 	get_val(st,data);
 	get_val(st,data);
@@ -6652,7 +6657,7 @@ BUILDIN_FUNC(rentitem) {
 	it.nameid = nameid;
 	it.nameid = nameid;
 	it.identify = 1;
 	it.identify = 1;
 	it.expire_time = (unsigned int)(time(NULL) + seconds);
 	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)) )
 	if( (flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT)) )
 	{
 	{
@@ -11472,7 +11477,8 @@ BUILDIN_FUNC(removemapflag)
 			case MF_SKILL_DAMAGE:
 			case MF_SKILL_DAMAGE:
 				{
 				{
 					map[m].flag.skill_damage = 0;
 					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;
 				} break;
 #endif
 #endif
 		}
 		}
@@ -18228,24 +18234,24 @@ BUILDIN_FUNC(stand)
 
 
 /** Creates an array of bounded item IDs
 /** Creates an array of bounded item IDs
  * countbound {<type>};
  * 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
  * @return amt: Amount of items found
  */
  */
 BUILDIN_FUNC(countbound)
 BUILDIN_FUNC(countbound)
 {
 {
-	int i, type, j=0, k=0;
+	int i, type, j = 0, k = 0;
 	TBL_PC *sd;
 	TBL_PC *sd;
 
 
 	if( (sd = script_rid2sd(st)) == NULL )
 	if( (sd = script_rid2sd(st)) == NULL )
 		return SCRIPT_CMD_FAILURE;
 		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);
 			pc_setreg(sd,reference_uid(add_str("@bound_items"), k),sd->status.inventory[i].nameid);
 			k++;
 			k++;
 			j += sd->status.inventory[i].amount;
 			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
 * @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) {
 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
 	// 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)
 	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) {
 bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y) {
 	int inf;
 	int inf;
 
 
-	if (!src || skill_get_index(skill_id) < 0)
+	if (!src || skill_get_index(skill_id) == 0)
 		return false;
 		return false;
 
 
 	if (src->type == BL_PC && pc_has_permission(BL_CAST(BL_PC,src),PC_PERM_SKILL_UNCONDITIONAL))
 	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:
 	case RL_SLUGSHOT:
 		if (bl->type != BL_PC)
 		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)
 			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;
 		break;
 	case RL_BANISHING_BUSTER:
 	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_REBOUND:		case SC_TELEKINESIS_INTENSE:
 					case SC_HEAT_BARREL:	case SC_HEAT_BARREL_AFTER:	case SC_P_ALTER:
 					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_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_ASPD:		case SC_MTF_RANGEATK:	case SC_MTF_MATK:
 					case SC_MTF_MLEATKED:	case SC_MTF_CRIDAMAGE:	case SC_GN_CARTBOOST:
 					case SC_MTF_MLEATKED:	case SC_MTF_CRIDAMAGE:	case SC_GN_CARTBOOST:
 #ifdef RENEWAL
 #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])
 	else if (&tsd->sc && tsd->sc.data[SC_PRESERVE] && !tsd->sc.data[SC__REPRODUCE])
 		return;
 		return;
 	else {
 	else {
-		short idx;
+		uint16 idx;
 		unsigned char lv;
 		unsigned char lv;
 
 
 		// Copy Referal: dummy skills should point to their source upon copying
 		// 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]
 		//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;
 			return;
 
 
 		switch (skill_isCopyable(tsd,skill_id)) {
 		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();
 	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]
 		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);
 		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 )
 	if( (idx = skill_get_index(skill)) == 0 )
 		return 0;
 		return 0;
 
 
-	// Requeriments
+	// Requirements
 	for( i = 0; i < ARRAYLENGTH(itemid); i++ )
 	for( i = 0; i < ARRAYLENGTH(itemid); i++ )
 	{
 	{
 		itemid[i] = skill_db[idx].require.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;
 			break;
 		case ST_MADO:
 		case ST_MADO:
 			if( !pc_ismadogear(sd) ) {
 			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;
 				return false;
 			}
 			}
 			break;
 			break;
@@ -14475,10 +14474,6 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 	if (require.status_count) {
 	if (require.status_count) {
 		uint8 i;
 		uint8 i;
 		/* May has multiple requirements */
 		/* 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++) {
 		for (i = 0; i < require.status_count; i++) {
 			enum sc_type req_sc = require.status[i];
 			enum sc_type req_sc = require.status[i];
 			if (req_sc == SC_NONE)
 			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
 	//check if equiped item
 	if (require.eqItem_count) {
 	if (require.eqItem_count) {
 		for (i = 0; i < require.eqItem_count; i++) {
 		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)) {
 			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
 				//Official use msgstringtable.txt for each skill failure
 				sprintf(output,msg_txt(sd,722),itemdb_jname(reqeqit));
 				sprintf(output,msg_txt(sd,722),itemdb_jname(reqeqit));
 				clif_colormes(sd,color_table[COLOR_RED],output);
 				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 skill_condition require;
 	struct status_data *status;
 	struct status_data *status;
 	int i;
 	int i;
-	int index[MAX_SKILL_ITEM_REQUIRE];
+	short index[MAX_SKILL_ITEM_REQUIRE];
 
 
 	nullpo_retr(false,sd);
 	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 )
 			else if( require.itemid[i] == ITEMID_ANCILLA )
 				clif_skill_fail(sd,skill_id,USESKILL_FAIL_ANCILLA,0); //Ancilla is required.
 				clif_skill_fail(sd,skill_id,USESKILL_FAIL_ANCILLA,0); //Ancilla is required.
 			else {
 			else {
-				char output[128];
-
+				char output[CHAT_SIZE_MAX];
 				//Official is using msgstringtable.txt for each requirement failure
 				//Official is using msgstringtable.txt for each requirement failure
 				//clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 				//clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 				sprintf(output, msg_txt(sd,720), itemdb_jname(require.itemid[i])); // %s is required.
 				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)
 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);
 	nullpo_retv(sd);
 
 
-	req = skill_get_requirement(sd,skill_id,skill_lv);
+	require = skill_get_requirement(sd,skill_id,skill_lv);
 
 
 	if( type&1 ) {
 	if( type&1 ) {
 		switch( skill_id ) {
 		switch( skill_id ) {
 			case CG_TAROTCARD: // TarotCard will consume sp in skill_cast_nodamage_id [Inkfish]
 			case CG_TAROTCARD: // TarotCard will consume sp in skill_cast_nodamage_id [Inkfish]
 			case MC_IDENTIFY:
 			case MC_IDENTIFY:
 			case RL_D_TAIL:
 			case RL_D_TAIL:
-				req.sp = 0;
+				require.sp = 0;
 				break;
 				break;
 			case GS_DESPERADO:
 			case GS_DESPERADO:
 				if (sd->skill_id_old == RL_FALLEN_ANGEL) //Don't consume SP if triggered by Fallen Angel
 				if (sd->skill_id_old == RL_FALLEN_ANGEL) //Don't consume SP if triggered by Fallen Angel
-					req.sp = 0;
+					require.sp = 0;
 				break;
 				break;
 			default:
 			default:
 				if(sd->state.autocast)
 				if(sd->state.autocast)
-					req.sp = 0;
+					require.sp = 0;
 			break;
 			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;
 			sd->spiritball_old = sd->spiritball;
 			pc_delspiritball(sd,sd->spiritball,0);
 			pc_delspiritball(sd,sd->spiritball,0);
 		}
 		}
 
 
-		if(req.zeny > 0)
+		if(require.zeny > 0)
 		{
 		{
 			if( skill_id == NJ_ZENYNAGE )
 			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 )
 		for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i )
 		{
 		{
-			if( !req.itemid[i] )
+			if( !require.itemid[i] )
 				continue;
 				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.
 				continue; //Gemstones are checked, but not substracted from inventory.
 
 
 			switch( skill_id ){
 			switch( skill_id ){
@@ -14831,8 +14826,8 @@ void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, ui
 					break;
 					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;
 	struct status_change *sc;
 	int i,hp_rate,sp_rate, sp_skill_rate_bonus = 100;
 	int i,hp_rate,sp_rate, sp_skill_rate_bonus = 100;
 	uint16 idx;
 	uint16 idx;
+	bool level_dependent = false;
 
 
 	memset(&req,0,sizeof(req));
 	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_count = skill_db[idx].require.eqItem_count;
 	req.eqItem = skill_db[idx].require.eqItem;
 	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 ) {
 	switch( skill_id ) {
+		/* Skill level-dependent checks */
 		case NC_SHAPESHIFT:
 		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 GN_FIRE_EXPANSION:
 		case SO_SUMMON_AGNI:
 		case SO_SUMMON_AGNI:
 		case SO_SUMMON_AQUA:
 		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_FIRE_INSIGNIA:
 		case SO_WIND_INSIGNIA:
 		case SO_WIND_INSIGNIA:
 		case SO_EARTH_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;
 			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
 	// Check for cost reductions due to skills & SCs
 	switch(skill_id) {
 	switch(skill_id) {
@@ -19350,29 +19322,37 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current)
 	return true;
 	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 *str: String input
 * @param *val: Temporary storage
 * @param *val: Temporary storage
 * @param *delim: Delimiter (for multiple value support)
 * @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
 * @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;
 	uint8 i = 0;
-	char *p = strtok(str,delim);
+	char *p = strtok(str, delim);
 
 
 	while (p != NULL) {
 	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);
 			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;
 			val[i] = n;
 			i++;
 			i++;
+			if (i >= max)
+				break;
 		}
 		}
-		p = strtok(NULL,delim);
+		p = strtok(NULL, delim);
 	}
 	}
 	return i;
 	return i;
 }
 }
@@ -19383,8 +19363,10 @@ static void skill_destroy_requirement(void) {
 	for (i = 0; i < MAX_SKILL; i++) {
 	for (i = 0; i < MAX_SKILL; i++) {
 		if (skill_db[i].require.status_count)
 		if (skill_db[i].require.status_count)
 			aFree(skill_db[i].require.status);
 			aFree(skill_db[i].require.status);
+		skill_db[i].require.status_count = 0;
 		if (skill_db[i].require.eqItem_count)
 		if (skill_db[i].require.eqItem_count)
 			aFree(skill_db[i].require.eqItem);
 			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;
 	char* p;
 	uint16 skill_id = atoi(split[0]), idx, i;
 	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;
 		return false;
 
 
-	idx = skill_get_index(skill_id);
 	skill_split_atoi(split[1],skill_db[idx].require.hp);
 	skill_split_atoi(split[1],skill_db[idx].require.hp);
 	skill_split_atoi(split[2],skill_db[idx].require.mhp);
 	skill_split_atoi(split[2],skill_db[idx].require.mhp);
 	skill_split_atoi(split[3],skill_db[idx].require.sp);
 	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
 	else skill_db[idx].require.state = ST_NONE;	// Unknown or no state
 
 
 	//Status requirements
 	//Status requirements
+	//FIXME: Default entry should be -1/SC_ALL in skill_require_db.txt but it's 0/SC_STONE.
 	trim(split[11]);
 	trim(split[11]);
-	if (split[11][0] != '\0') {
+	if (split[11][0] != '\0' || atoi(split[11])) {
 		int require[MAX_SKILL_STATUS_REQUIRE];
 		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++)
 			for (i = 0; i < skill_db[idx].require.status_count; i++)
 				skill_db[idx].require.status[i] = (sc_type)require[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.
 	//Equipped Item requirements.
 	//NOTE: We don't check the item is exist or not here
 	//NOTE: We don't check the item is exist or not here
 	trim(split[33]);
 	trim(split[33]);
-	if (split[33][0] != '\0') {
+	if (split[33][0] != '\0' || atoi(split[33])) {
 		int require[MAX_SKILL_EQUIP_REQUIRE];
 		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++)
 			for (i = 0; i < skill_db[idx].require.eqItem_count; i++)
 				skill_db[idx].require.eqItem[i] = require[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}
 * SkillID,CastingTime,AfterCastActDelay,AfterCastWalkDelay,Duration1,Duration2,Cooldown{,Fixedcast}
 */
 */
 static bool skill_parse_row_castdb(char* split[], int columns, int current) {
 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
 	if( !idx ) // invalid skill id
 		return false;
 		return false;
 
 
@@ -19511,8 +19492,7 @@ static bool skill_parse_row_castdb(char* split[], int columns, int current) {
 * SkillID,Cast,Delay (optional)
 * SkillID,Cast,Delay (optional)
 */
 */
 static bool skill_parse_row_castnodexdb(char* split[], int columns, int current) {
 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
 	if( !idx ) // invalid skill id
 		return false;
 		return false;
 
 
@@ -19527,8 +19507,7 @@ static bool skill_parse_row_castnodexdb(char* split[], int columns, int current)
 * SkillID,Flag
 * SkillID,Flag
 */
 */
 static bool skill_parse_row_nocastdb(char* split[], int columns, int current) {
 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
 	if( !idx ) // invalid skill id
 		return false;
 		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
 * ID,unit ID,unit ID 2,layout,range,interval,target,flag
 */
 */
 static bool skill_parse_row_unitdb(char* split[], int columns, int current) {
 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
 	if( !idx ) // invalid skill id
 		return false;
 		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) )
 	if( !skill_get_index(skill_id) || !skill_get_max(skill_id) )
 		ShowError("spellbook_db: Invalid skill ID %d\n", 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));
 		ShowError("spellbook_db: Passive skills cannot be memorized (%d/%s)\n", skill_id, skill_get_name(skill_id));
 	if( points < 1 )
 	if( points < 1 )
 		ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skill_id, skill_get_name(skill_id));
 		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;
 	uint8 option;
 
 
 	trim(split[0]);
 	trim(split[0]);
-	if(ISDIGIT(split[0][0]))
+	if (ISDIGIT(split[0][0]))
 		id = atoi(split[0]);
 		id = atoi(split[0]);
 	else
 	else
 		id = skill_name2id(split[0]);
 		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]);
 		ShowError("skill_parse_row_copyabledb: Invalid skill '%s'\n",split[0]);
 		return false;
 		return false;
 	}
 	}
@@ -19739,12 +19717,12 @@ static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int curr
 	int16 id;
 	int16 id;
 
 
 	trim(split[0]);
 	trim(split[0]);
-	if(ISDIGIT(split[0][0]))
+	if (ISDIGIT(split[0][0]))
 		id = atoi(split[0]);
 		id = atoi(split[0]);
 	else
 	else
 		id = skill_name2id(split[0]);
 		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]);
 		ShowError("skill_parse_row_nonearnpcrangedb: Invalid skill '%s'\n",split[0]);
 		return false;
 		return false;
 	}
 	}
@@ -19811,27 +19789,27 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
 	return true;
 	return true;
 }
 }
 
 
-/*==========================================
+/**
  * Manage Skill Damage database [Lilith]
  * Manage Skill Damage database [Lilith]
- *------------------------------------------*/
+ **/
 #ifdef ADJUST_SKILL_DAMAGE
 #ifdef ADJUST_SKILL_DAMAGE
 static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
 static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
 {
 {
 	uint16 skill_id = skill_name2id(split[0]), idx;
 	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]);
 		ShowWarning("skill_parse_row_skilldamage: Invalid skill '%s'. Skipping..",split[0]);
 		return false;
 		return false;
 	}
 	}
 	memset(&skill_db[idx].damage,0,sizeof(struct s_skill_damage));
 	memset(&skill_db[idx].damage,0,sizeof(struct s_skill_damage));
 	skill_db[idx].damage.caster |= atoi(split[1]);
 	skill_db[idx].damage.caster |= atoi(split[1]);
 	skill_db[idx].damage.map |= atoi(split[2]);
 	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])
 	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])
 	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])
 	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;
 	return true;
 }
 }
 #endif
 #endif

+ 42 - 38
src/map/skill.h

@@ -22,6 +22,8 @@ struct status_change_entry;
 #define MAX_SKILL_IMPROVISE_DB 50
 #define MAX_SKILL_IMPROVISE_DB 50
 #define MAX_SKILL_LEVEL 100
 #define MAX_SKILL_LEVEL 100
 #define MAX_SKILL_CRIMSON_MARKER 3
 #define MAX_SKILL_CRIMSON_MARKER 3
+#define SKILL_NAME_LENGTH 31
+#define SKILL_DESC_LENGTH 31
 
 
 DBMap* skilldb_name2id;
 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
 	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 {
 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 {
 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
 /// Database skills
 struct s_skill_db {
 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 range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
 	int num[MAX_SKILL_LEVEL];
 	int num[MAX_SKILL_LEVEL];
 	int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[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_ENSEMBLE      = 0x0200,	// Duet
 	UF_SONG          = 0x0400,	// Song
 	UF_SONG          = 0x0400,	// Song
 	UF_DUALMODE      = 0x0800,	// Spells should trigger both ontimer and onplace/onout/onleft effects.
 	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
 /// Create Database item

+ 16 - 12
src/map/status.c

@@ -821,11 +821,11 @@ void initChangeTables(void)
 	add_sc( RL_HAMMER_OF_GOD	, SC_STUN );
 	add_sc( RL_HAMMER_OF_GOD	, SC_STUN );
 	set_sc( RL_B_TRAP		, SC_B_TRAP		, SI_B_TRAP		, SCB_SPEED );
 	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_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_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 );
 	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_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
 	StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
 	StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
 	StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
 	StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
-	StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
+	StatusIconChangeTable[SC_CHASEWALK2] = SI_CHASEWALK2;
 	StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
 	StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
 	StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
 	StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
 	StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
 	StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
@@ -1055,6 +1055,7 @@ void initChangeTables(void)
 	StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
 	StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
 	StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED;
+	StatusChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
 
 
 	/* Cash Items */
 	/* Cash Items */
 	StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
 	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;
 		return 50;
 	if(sc->data[SC_INCALLSTATUS])
 	if(sc->data[SC_INCALLSTATUS])
 		str += sc->data[SC_INCALLSTATUS]->val1;
 		str += sc->data[SC_INCALLSTATUS]->val1;
+	if(sc->data[SC_CHASEWALK2])
+		str += sc->data[SC_CHASEWALK2]->val1;
 	if(sc->data[SC_INCSTR])
 	if(sc->data[SC_INCSTR])
 		str += sc->data[SC_INCSTR]->val1;
 		str += sc->data[SC_INCSTR]->val1;
 	if(sc->data[SC_STRFOOD])
 	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])
 	if(sc->data[SC__ENERVATION])
 		batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
 		batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
 	if( sc->data[SC_ZANGETSU] )
 	if( sc->data[SC_ZANGETSU] )
-		batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
+		batk += sc->data[SC_ZANGETSU]->val2;
 	if(sc->data[SC_EQC])
 	if(sc->data[SC_EQC])
 		batk -= batk * sc->data[SC_EQC]->val3 / 100;
 		batk -= batk * sc->data[SC_EQC]->val3 / 100;
 	if(sc->data[SC_QUEST_BUFF1])
 	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])
 	if (sc->data[SC_TEARGAS])
 		flee -= flee * 50 / 100;
 		flee -= flee * 50 / 100;
 	if( sc->data[SC_C_MARKER] )
 	if( sc->data[SC_C_MARKER] )
-		flee -= 10;
+		flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100;
 	if(sc->data[SC_HEAT_BARREL])
 	if(sc->data[SC_HEAT_BARREL])
 		flee -= sc->data[SC_HEAT_BARREL]->val4;
 		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;
 			break;
 		case SC_PAIN_KILLER: // Yommy leak need confirm
 		case SC_PAIN_KILLER: // Yommy leak need confirm
 			val2 = 10 * val1; // aspd reduction %
 			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])
 			if(sc->data[SC_PARALYSIS])
 				sc_start(src,bl, SC_ENDURE, 100, val1, tick); // Start endure for same duration
 				sc_start(src,bl, SC_ENDURE, 100, val1, tick); // Start endure for same duration
 			break;
 			break;
@@ -9775,8 +9778,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			break;
 			break;
 		case SC_C_MARKER:
 		case SC_C_MARKER:
 			val2 = src->id;
 			val2 = src->id;
+			val3 = 10; //-10% flee
 			//Start timer to send mark on mini map
 			//Start timer to send mark on mini map
-			val3 = tick/1000;
+			val4 = tick/1000;
 			tick_time = 1000;
 			tick_time = 1000;
 			break;
 			break;
 		case SC_H_MINE:
 		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))
 		if(!status_charge(bl, 0, sce->val4))
 			break; // Not enough SP to continue.
 			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
 				(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));
 				*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;
 		break;
 	case SC_C_MARKER:
 	case SC_C_MARKER:
-		if( --(sce->val3) >= 0 ) {
+		if( --(sce->val4) >= 0 ) {
 			TBL_PC *tsd = map_id2sd(sce->val2);
 			TBL_PC *tsd = map_id2sd(sce->val2);
 			if (!tsd || tsd->bl.m != bl->m) //End the SC if caster isn't in same map
 			if (!tsd || tsd->bl.m != bl->m) //End the SC if caster isn't in same map
 				break;
 				break;

+ 2 - 1
src/map/status.h

@@ -701,6 +701,7 @@ typedef enum sc_type {
 	SC__FEINTBOMB,
 	SC__FEINTBOMB,
 	SC__CHAOS,
 	SC__CHAOS,
 	SC_ELEMENTAL_SHIELD,
 	SC_ELEMENTAL_SHIELD,
+	SC_CHASEWALK2,
 
 
 #ifdef RENEWAL
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
 	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_DEFENCE = 179,
 //	SI_SLOWDOWN = 180,
 //	SI_SLOWDOWN = 180,
 	SI_PRESERVE		= 181,
 	SI_PRESERVE		= 181,
-	SI_INCSTR		= 182,
+	SI_CHASEWALK2	= 182,
 //	SI_NOT_EXTREMITYFIST = 183,
 //	SI_NOT_EXTREMITYFIST = 183,
 	SI_INTRAVISION		= 184,
 	SI_INTRAVISION		= 184,
 //	SI_MOVESLOW_POTION = 185,
 //	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;
 		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));
 		clif_displaymessage(sd->fd, msg_txt(sd,294));
 		return 1;
 		return 1;
 	}
 	}
@@ -519,7 +519,7 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
 		return 1;
 		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));
 		clif_displaymessage(sd->fd, msg_txt(sd,294));
 		return 1;
 		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;
 		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_displaymessage(sd->fd, msg_txt(sd,293));
 		clif_tradeitemok(sd, index+2, 1);
 		clif_tradeitemok(sd, index+2, 1);
 		return;
 		return;