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>
This commit is contained in:
parent
28c90bb841
commit
794c1a8247
@ -1743,6 +1743,7 @@ SC__FEINTBOMB 594
|
||||
SC__CHAOS 595
|
||||
SC_ELEMENTAL_SHIELD 596
|
||||
SC_EXTREMITYFIST2 597
|
||||
SC_CHASEWALK2 598
|
||||
|
||||
//Status Icon
|
||||
SI_BLANK -1
|
||||
@ -1926,7 +1927,7 @@ SI_MAXSPPERCENT 178
|
||||
SI_DEFENCE 179
|
||||
SI_SLOWDOWN 180
|
||||
SI_PRESERVE 181
|
||||
SI_INCSTR 182
|
||||
SI_CHASEWALK2 182
|
||||
SI_NOT_EXTREMITYFIST 183
|
||||
SI_INTRAVISION 184
|
||||
SI_MOVESLOW_POTION 185
|
||||
@ -4598,5 +4599,10 @@ IT_AMMO 10
|
||||
IT_DELAYCONSUME 11
|
||||
IT_CASH 18
|
||||
|
||||
Bound_Account 1
|
||||
Bound_Guild 2
|
||||
Bound_Party 3
|
||||
Bound_Char 4
|
||||
|
||||
false 0
|
||||
true 1
|
||||
|
@ -4,3 +4,4 @@
|
||||
// <Flag>:
|
||||
// 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
|
||||
// 2 - As item group container, check player's inventory and weight before consumed
|
||||
// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
|
||||
|
@ -4,6 +4,7 @@
|
||||
// <Flag>:
|
||||
// 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
|
||||
// 2 - As item group container, check player's inventory and weight before consumed
|
||||
// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
|
||||
|
||||
// Logged as Dead Branch item
|
||||
604,1 //Branch_Of_Dead_Tree
|
||||
|
@ -118,7 +118,7 @@
|
||||
|
||||
//****
|
||||
// WZ Wizard
|
||||
80,0,0,75,0,0,0,99,0,0,none,0,0,717,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_FIREPILLAR
|
||||
80,0,0,75,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,717,1,717,1,717,1,717,1,717,1,0 //WZ_FIREPILLAR
|
||||
81,0,0,35:37:39:41:43:45:47:49:51:53,0,0,0,99,0,0,none,SC_SIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_SIGHTRASHER
|
||||
83,0,0,20:24:30:34:40:44:50:54:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_METEOR
|
||||
84,0,0,20:23:26:29:32:35:38:41:44:47,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_JUPITEL
|
||||
@ -678,25 +678,25 @@
|
||||
//****
|
||||
// NC Mechanic
|
||||
2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_BOOSTKNUCKLE
|
||||
2257,0,0,50,0,0,0,99,0,0,mado,0,0,1549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_PILEBUNKER
|
||||
2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549 //NC_PILEBUNKER
|
||||
2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_VULCANARM
|
||||
2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_FLAMELAUNCHER
|
||||
2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139 //NC_FLAMELAUNCHER
|
||||
2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_COLDSLOWER
|
||||
2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ARMSCANNON
|
||||
2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ACCELERATION
|
||||
2263,0,0,25,0,0,0,99,0,0,mado,0,0,2801,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_HOVERING
|
||||
2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800 //NC_ACCELERATION
|
||||
2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801 //NC_HOVERING
|
||||
2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_F_SIDESLIDE
|
||||
2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_B_SIDESLIDE
|
||||
|
||||
2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_SELFDESTRUCTION
|
||||
2268,0,0,100,0,0,0,99,0,0,mado,0,0,2803,0,6360,1,6363,1,6362,1,6361,1,6146,2,0,0,0,0,0,0,0,0,0 //NC_SHAPESHIFT
|
||||
2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_EMERGENCYCOOL
|
||||
2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802 //NC_SELFDESTRUCTION
|
||||
2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803 //NC_SHAPESHIFT
|
||||
2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804 //NC_EMERGENCYCOOL
|
||||
2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_INFRAREDSCAN
|
||||
2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ANALYZE
|
||||
2272,0,0,90,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_MAGNETICFIELD
|
||||
2273,0,0,90,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_NEUTRALBARRIER
|
||||
2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_STEALTHFIELD
|
||||
2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,2807,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_REPAIR
|
||||
2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805 //NC_MAGNETICFIELD
|
||||
2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806 //NC_NEUTRALBARRIER
|
||||
2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808 //NC_STEALTHFIELD
|
||||
2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807 //NC_REPAIR
|
||||
|
||||
2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_AXEBOOMERANG
|
||||
2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_POWERSWING
|
||||
|
@ -248,7 +248,7 @@
|
||||
15068:20710,{ bonus bAgi,5; bonus bFlee,10; }
|
||||
15088:18816:18818,{ bonus bMatk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; }
|
||||
15088:18817:18819,{ bonus bBaseAtk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; }
|
||||
15116:20743:22046,{ bonus bMaxSPrate,25; bonus bMaxSPrate,25; bonus bSpeedAddRate,n; }
|
||||
15116:20743:22046,{ bonus bMaxSPrate,25; bonus bMaxSPrate,25; bonus bSpeedAddRate,10; }
|
||||
18507:18539,{ bonus bUseSPrate,-3; }
|
||||
18538:5041,{ bonus2 bSubRace,RC_Angel,9; }
|
||||
18538:5048,{ bonus2 bSubRace,RC_Demon,9; }
|
||||
@ -260,6 +260,7 @@
|
||||
18656:5475,{ bonus bBaseAtk,30; bonus bMatk,30; bonus2 bAddMonsterDropItem,529,400; bonus2 bAddMonsterDropItem,530,400; bonus2 bAddMonsterDropItem,538,400; bonus2 bAddMonsterDropItem,12192,400;}
|
||||
18776:20710,{ bonus bBaseAtk,10; }
|
||||
18776:22015,{ bonus bMatk,20; }
|
||||
18997:28326:28327,{ bonus bSpeed,25; bonus bBaseAtk,50; bonus bMatk,50; }
|
||||
24012:24013:24014:24015:24016:24017,{ bonus bAllStats,9; }
|
||||
24018:24019:24020,{ if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) + getequiprefinerycnt(EQI_SHADOW_WEAPON) >= 23) { bonus bAtkRate,1; } }
|
||||
24021:24022:24023,{ if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) + getequiprefinerycnt(EQI_SHADOW_WEAPON) >= 23) { bonus bMatkRate,1; } }
|
||||
@ -303,5 +304,4 @@
|
||||
24150:24151,{ bonus bAtkRate,1; if (getequiprefinerycnt(EQI_SHADOW_ACC_R)+getequiprefinerycnt(EQI_SHADOW_ACC_L) >= 15) bonus bNoSizeFix,1; }
|
||||
24152:24153,{ bonus bAtk,getequiprefinerycnt(EQI_SHADOW_WEAPON); if (getequiprefinerycnt(EQI_SHADOW_WEAPON)+getequiprefinerycnt(EQI_SHADOW_ACC_R) >= 15) bonus bUnbreakableWeapon,1; }
|
||||
24154:24155,{ bonus bDef,getequiprefinerycnt(EQI_SHADOW_ARMOR); if (getequiprefinerycnt(EQI_SHADOW_ARMOR)+getequiprefinerycnt(EQI_SHADOW_ACC_L) >= 15) bonus bUnbreakableArmor,1; }
|
||||
18997:28326:28327,{ bonus bSpeed,25; bonus bBaseAtk,50; bonus bMatk,50; }
|
||||
28326:28327,{ bonus bInt,8; bonus bStr,8; }
|
||||
|
@ -4,6 +4,7 @@
|
||||
// <Flag>:
|
||||
// 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag)
|
||||
// 2 - As item group container, check player's inventory and weight before consumed
|
||||
// NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree
|
||||
|
||||
// Logged as Dead Branch item
|
||||
604,1 //Branch_Of_Dead_Tree
|
||||
|
@ -118,7 +118,7 @@
|
||||
|
||||
//****
|
||||
// WZ Wizard
|
||||
80,0,0,75,0,0,0,99,0,0,none,0,0,717,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_FIREPILLAR
|
||||
80,0,0,75,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,717,1,717,1,717,1,717,1,717,1,0 //WZ_FIREPILLAR
|
||||
81,0,0,35:37:39:41:43:45:47:49:51:53,0,0,0,99,0,0,none,SC_SIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_SIGHTRASHER
|
||||
83,0,0,20:24:30:34:40:44:50:54:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_METEOR
|
||||
84,0,0,20:23:26:29:32:35:38:41:44:47,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_JUPITEL
|
||||
@ -678,25 +678,25 @@
|
||||
//****
|
||||
// NC Mechanic
|
||||
2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_BOOSTKNUCKLE
|
||||
2257,0,0,50,0,0,0,99,0,0,mado,0,0,1549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_PILEBUNKER
|
||||
2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549 //NC_PILEBUNKER
|
||||
2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_VULCANARM
|
||||
2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_FLAMELAUNCHER
|
||||
2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139 //NC_FLAMELAUNCHER
|
||||
2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_COLDSLOWER
|
||||
2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ARMSCANNON
|
||||
2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ACCELERATION
|
||||
2263,0,0,25,0,0,0,99,0,0,mado,0,0,2801,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_HOVERING
|
||||
2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800 //NC_ACCELERATION
|
||||
2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801 //NC_HOVERING
|
||||
2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_F_SIDESLIDE
|
||||
2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_B_SIDESLIDE
|
||||
|
||||
2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_SELFDESTRUCTION
|
||||
2268,0,0,100,0,0,0,99,0,0,mado,0,0,2803,0,6360,1,6363,1,6362,1,6361,1,6146,2,0,0,0,0,0,0,0,0,0 //NC_SHAPESHIFT
|
||||
2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_EMERGENCYCOOL
|
||||
2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802 //NC_SELFDESTRUCTION
|
||||
2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803 //NC_SHAPESHIFT
|
||||
2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804 //NC_EMERGENCYCOOL
|
||||
2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_INFRAREDSCAN
|
||||
2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ANALYZE
|
||||
2272,0,0,90,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_MAGNETICFIELD
|
||||
2273,0,0,90,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_NEUTRALBARRIER
|
||||
2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_STEALTHFIELD
|
||||
2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,2807,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_REPAIR
|
||||
2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805 //NC_MAGNETICFIELD
|
||||
2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806 //NC_NEUTRALBARRIER
|
||||
2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808 //NC_STEALTHFIELD
|
||||
2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807 //NC_REPAIR
|
||||
|
||||
2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_AXEBOOMERANG
|
||||
2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_POWERSWING
|
||||
|
@ -4353,10 +4353,10 @@ in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in
|
||||
some cases cannot be traded or stored.
|
||||
|
||||
Valid bound types are:
|
||||
1 - Account Bound
|
||||
2 - Guild Bound
|
||||
3 - Party Bound
|
||||
4 - Character Bound
|
||||
Bound_Account : Account Bound item
|
||||
Bound_Guild : Guild Bound item
|
||||
Bound_Party : Party Bound item
|
||||
Bound_Char : Character Bound item
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -4506,8 +4506,8 @@ See 'getitem2' for an explanation of the expanded parameters.
|
||||
|
||||
*cartdelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
*cartdelitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
*storageitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
*storageitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
*storagedelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
*storagedelitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
|
||||
Same like delitem2, but deletes item from cart or storage.
|
||||
If cart is not mounted, it will be failed.
|
||||
|
@ -184,7 +184,7 @@ static bool mail_loadmessage(int mail_id, struct mail_message* msg)
|
||||
Sql_GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data);
|
||||
Sql_GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10);
|
||||
msg->item.expire_time = 0;
|
||||
msg->item.bound = 0;
|
||||
msg->item.bound = BOUND_NONE;
|
||||
|
||||
for( j = 0; j < MAX_SLOTS; j++ )
|
||||
{
|
||||
|
@ -289,7 +289,7 @@ int mapif_parse_itembound_retrieve(int fd)
|
||||
SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
|
||||
|
||||
while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) {
|
||||
if(item.bound == 2) {
|
||||
if(item.bound == BOUND_GUILD) {
|
||||
memcpy(&items[i],&item,sizeof(struct item));
|
||||
i++;
|
||||
}
|
||||
|
@ -785,6 +785,16 @@ enum {
|
||||
SEX_SERVER
|
||||
};
|
||||
|
||||
/// Item Bound Type
|
||||
enum bound_type {
|
||||
BOUND_NONE = 0, /// No bound
|
||||
BOUND_ACCOUNT, /// 1- Account Bound
|
||||
BOUND_GUILD, /// 2 - Guild Bound
|
||||
BOUND_PARTY, /// 3 - Party Bound
|
||||
BOUND_CHAR, /// 4 - Character Bound
|
||||
BOUND_MAX
|
||||
};
|
||||
|
||||
// sanity checks...
|
||||
#if MAX_ZENY > INT_MAX
|
||||
#error MAX_ZENY is too big
|
||||
|
@ -62,12 +62,7 @@
|
||||
/// Uncomment to enable skills damage adjustments
|
||||
/// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the
|
||||
/// damage rate of specified skills.
|
||||
//#define ADJUST_SKILL_DAMAGE
|
||||
|
||||
/// The skill damage adjustment rate is capped at 100000.
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
#define MAX_SKILL_DAMAGE_RATE 100000
|
||||
#endif
|
||||
#define ADJUST_SKILL_DAMAGE
|
||||
|
||||
/// Uncomment to enable the job base HP/SP table (job_basehpsp_db.txt)
|
||||
//#define HP_SP_TABLES
|
||||
|
@ -13,7 +13,7 @@
|
||||
static char global_db_hostname[32] = "127.0.0.1";
|
||||
static uint16 global_db_port = 3306;
|
||||
static char global_db_username[32] = "ragnarok";
|
||||
static char global_db_password[32] = "ragnarok";
|
||||
static char global_db_password[32] = "";
|
||||
static char global_db_database[32] = "ragnarok";
|
||||
static char global_codepage[32] = "";
|
||||
// local sql settings
|
||||
|
@ -1198,7 +1198,7 @@ ACMD_FUNC(heal)
|
||||
ACMD_FUNC(item)
|
||||
{
|
||||
char item_name[100];
|
||||
int number = 0, flag = 0, bound = 0;
|
||||
int number = 0, flag = 0, bound = BOUND_NONE;
|
||||
struct item item_tmp;
|
||||
struct item_data *item_data[10];
|
||||
int get_count, i, j=0;
|
||||
@ -1207,12 +1207,19 @@ ACMD_FUNC(item)
|
||||
nullpo_retr(-1, sd);
|
||||
memset(item_name, '\0', sizeof(item_name));
|
||||
|
||||
if (!strcmpi(command+1,"itembound") && (!message || !*message || (
|
||||
sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 2 &&
|
||||
sscanf(message, "%99s %d %d", item_name, &number, &bound) < 2
|
||||
))) {
|
||||
clif_displaymessage(fd, msg_txt(sd,295)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity> <bound_type>).
|
||||
return -1;
|
||||
if (!strcmpi(command+1,"itembound")) {
|
||||
if (!message || !*message || (
|
||||
sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 3 &&
|
||||
sscanf(message, "%99s %d %d", item_name, &number, &bound) < 3))
|
||||
{
|
||||
clif_displaymessage(fd, msg_txt(sd,295)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity> <bound_type>).
|
||||
clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
|
||||
return -1;
|
||||
}
|
||||
if( bound <= BOUND_NONE || bound >= BOUND_MAX ) {
|
||||
clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
|
||||
return -1;
|
||||
}
|
||||
} else if (!message || !*message || (
|
||||
sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
|
||||
sscanf(message, "%99s %d", item_name, &number) < 1
|
||||
@ -1231,11 +1238,6 @@ ACMD_FUNC(item)
|
||||
j++;
|
||||
}
|
||||
|
||||
if( bound < 0 || bound > 4 ) {
|
||||
clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
get_count = number;
|
||||
@ -1273,19 +1275,27 @@ ACMD_FUNC(item2)
|
||||
struct item item_tmp;
|
||||
struct item_data *item_data;
|
||||
char item_name[100];
|
||||
int item_id, number = 0, bound = 0;
|
||||
int item_id, number = 0, bound = BOUND_NONE;
|
||||
int identify = 0, refine = 0, attr = 0;
|
||||
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
memset(item_name, '\0', sizeof(item_name));
|
||||
|
||||
if (!strcmpi(command+1,"itembound2") && (!message || !*message || (
|
||||
sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
|
||||
sscanf(message, "%99s %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))) {
|
||||
clif_displaymessage(fd, msg_txt(sd,296)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
|
||||
clif_displaymessage(fd, msg_txt(sd,297)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
|
||||
return -1;
|
||||
if (!strcmpi(command+1,"itembound2")) {
|
||||
if (!message || !*message || (
|
||||
sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
|
||||
sscanf(message, "%99s %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))
|
||||
{
|
||||
clif_displaymessage(fd, msg_txt(sd,296)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
|
||||
clif_displaymessage(fd, msg_txt(sd,297)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
|
||||
clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
|
||||
return -1;
|
||||
}
|
||||
if( bound <= BOUND_NONE || bound >= BOUND_MAX ) {
|
||||
clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
|
||||
return -1;
|
||||
}
|
||||
} else if ( !message || !*message || (
|
||||
sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
|
||||
sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
|
||||
@ -1298,11 +1308,6 @@ ACMD_FUNC(item2)
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
|
||||
if( bound < 0 || bound > 4 ) {
|
||||
clif_displaymessage(fd, msg_txt(sd,298)); // Invalid bound type
|
||||
return -1;
|
||||
}
|
||||
|
||||
item_id = 0;
|
||||
if ((item_data = itemdb_searchname(item_name)) != NULL ||
|
||||
(item_data = itemdb_exists(atoi(item_name))) != NULL)
|
||||
@ -3926,7 +3931,7 @@ ACMD_FUNC(mapinfo) {
|
||||
if (map[m_id].skill_damage[j].skill_id) {
|
||||
sprintf(atcmd_output," %d. %s : %d%%, %d%%, %d%%, %d%% | %d"
|
||||
,j+1
|
||||
,skill_db[skill_get_index(map[m_id].skill_damage[j].skill_id)].name
|
||||
,skill_get_name(map[m_id].skill_damage[j].skill_id)
|
||||
,map[m_id].skill_damage[j].pc
|
||||
,map[m_id].skill_damage[j].mob
|
||||
,map[m_id].skill_damage[j].boss
|
||||
|
112
src/map/battle.c
112
src/map/battle.c
@ -1066,7 +1066,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
DAMAGE_SUBRATE(sc->data[SC_GRANITIC_ARMOR]->val2)
|
||||
|
||||
if(sc->data[SC_PAIN_KILLER])
|
||||
DAMAGE_SUBRATE(sc->data[SC_PAIN_KILLER]->val3);
|
||||
damage -= sc->data[SC_PAIN_KILLER]->val3;
|
||||
|
||||
if( sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT )
|
||||
DAMAGE_ADDRATE(sc->data[SC_DARKCROW]->val2);
|
||||
@ -1723,45 +1723,44 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Damage calculation for adjusting skill damage
|
||||
* Credits:
|
||||
[Lilith] for the first release of this
|
||||
[Cydh] finishing and adding mapflag
|
||||
* battle_skill_damage_skill() - skill_id based
|
||||
* battle_skill_damage_map() - map based
|
||||
*------------------------------------------*/
|
||||
/** Damage calculation for adjusting skill damage
|
||||
* @param caster Applied caster type for damage skill
|
||||
* @param type BL_Type of attacker
|
||||
* @author [Lilith] for the first release of this, [Cydh]
|
||||
**/
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type type)
|
||||
{
|
||||
static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) {
|
||||
if (caster == 0)
|
||||
return false;
|
||||
|
||||
while (1) {
|
||||
if (caster&SDC_PC && type == BL_PC) break;
|
||||
if (caster&SDC_MOB && type == BL_MOB) break;
|
||||
if (caster&SDC_PET && type == BL_PET) break;
|
||||
if (caster&SDC_HOM && type == BL_HOM) break;
|
||||
if (caster&SDC_MER && type == BL_MER) break;
|
||||
if (caster&SDC_ELEM && type == BL_ELEM) break;
|
||||
return false;
|
||||
switch (src_type) {
|
||||
case BL_PC: if (caster&SDC_PC) return true; break;
|
||||
case BL_MOB: if (caster&SDC_MOB) return true; break;
|
||||
case BL_PET: if (caster&SDC_PET) return true; break;
|
||||
case BL_HOM: if (caster&SDC_HOM) return true; break;
|
||||
case BL_MER: if (caster&SDC_MER) return true; break;
|
||||
case BL_ELEM: if (caster&SDC_ELEM) return true; break;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id)
|
||||
{
|
||||
unsigned short m = src->m;
|
||||
int idx;
|
||||
/** Gets skill damage rate from a skill (based on skill_damage_db.txt)
|
||||
* @param src
|
||||
* @param target
|
||||
* @param skill_id
|
||||
* @return Skill damage rate
|
||||
*/
|
||||
static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id) {
|
||||
uint16 idx = skill_get_index(skill_id), m = src->m;
|
||||
struct s_skill_damage *damage = NULL;
|
||||
|
||||
if ((idx = skill_get_index(skill_id)) < 0 || !skill_db[idx].damage.map)
|
||||
if (!idx || !skill_db[idx].damage.map)
|
||||
return 0;
|
||||
|
||||
damage = &skill_db[idx].damage;
|
||||
|
||||
//check the adjustment works for specified type
|
||||
if (!battle_skill_damage_iscaster(damage->caster,src->type))
|
||||
if (!battle_skill_damage_iscaster(damage->caster, src->type))
|
||||
return 0;
|
||||
|
||||
if ((damage->map&1 && (!map[m].flag.pvp && !map_flag_gvg(m) && !map[m].flag.battleground && !map[m].flag.skill_damage && !map[m].flag.restricted)) ||
|
||||
@ -1787,8 +1786,13 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id)
|
||||
{
|
||||
/** Gets skill damage rate from a skill (based on 'skill_damage' mapflag)
|
||||
* @param src
|
||||
* @param target
|
||||
* @param skill_id
|
||||
* @return Skill damage rate
|
||||
*/
|
||||
static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id) {
|
||||
int rate = 0;
|
||||
uint16 m = src->m;
|
||||
uint8 i;
|
||||
@ -1796,8 +1800,8 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
|
||||
if (!map[m].flag.skill_damage)
|
||||
return 0;
|
||||
|
||||
/* modifier for all skills */
|
||||
if (battle_skill_damage_iscaster(map[m].adjust.damage.caster,src->type)) {
|
||||
// Damage rate for all skills at this map
|
||||
if (battle_skill_damage_iscaster(map[m].adjust.damage.caster, src->type)) {
|
||||
switch (target->type) {
|
||||
case BL_PC:
|
||||
rate = map[m].adjust.damage.pc;
|
||||
@ -1814,10 +1818,10 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
|
||||
}
|
||||
}
|
||||
|
||||
/* modifier for specified map */
|
||||
ARR_FIND(0,MAX_MAP_SKILL_MODIFIER,i,map[m].skill_damage[i].skill_id == skill_id);
|
||||
if (i < MAX_MAP_SKILL_MODIFIER) {
|
||||
if (battle_skill_damage_iscaster(map[m].skill_damage[i].caster,src->type)) {
|
||||
// Damage rate for specified skill at this map
|
||||
ARR_FIND(0, ARRAYLENGTH(map[m].skill_damage), i, map[m].skill_damage[i].skill_id == skill_id);
|
||||
if (i < ARRAYLENGTH(map[m].skill_damage)) {
|
||||
if (battle_skill_damage_iscaster(map[m].skill_damage[i].caster, src->type)) {
|
||||
switch (target->type) {
|
||||
case BL_PC:
|
||||
rate += map[m].skill_damage[i].pc;
|
||||
@ -1837,11 +1841,16 @@ static int battle_skill_damage_map(struct block_list *src, struct block_list *ta
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int battle_skill_damage(struct block_list *src, struct block_list *target, uint16 skill_id)
|
||||
{
|
||||
/** Check skill damage adjustment based on mapflags and skill_damage_db.txt for specified skill
|
||||
* @param src
|
||||
* @param target
|
||||
* @param skill_id
|
||||
* @return Total damage rate
|
||||
*/
|
||||
static int battle_skill_damage(struct block_list *src, struct block_list *target, uint16 skill_id) {
|
||||
if (!target)
|
||||
return 0;
|
||||
return battle_skill_damage_skill(src,target,skill_id) + battle_skill_damage_map(src,target,skill_id);
|
||||
return battle_skill_damage_skill(src, target, skill_id) + battle_skill_damage_map(src, target, skill_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2865,9 +2874,9 @@ struct Damage battle_calc_skill_base_damage(struct Damage wd, struct block_list
|
||||
}
|
||||
|
||||
//For quick div adjustment.
|
||||
#define damage_div_fix(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; }
|
||||
#define damage_div_fix2(dmg, div) { if (div > 1) (dmg)*=div; }
|
||||
#define damage_div_fix_renewal(wd, div) { damage_div_fix2(wd.statusAtk, div); damage_div_fix2(wd.weaponAtk, div); damage_div_fix2(wd.equipAtk, div); damage_div_fix2(wd.masteryAtk, div); }
|
||||
#define DAMAGE_DIV_FIX(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; }
|
||||
#define DAMAGE_DIV_FIX2(dmg, div) { if (div > 1) (dmg)*=div; }
|
||||
#define DAMAGE_DIV_FIX_RENEWAL(wd, div) { DAMAGE_DIV_FIX2(wd.statusAtk, div); DAMAGE_DIV_FIX2(wd.weaponAtk, div); DAMAGE_DIV_FIX2(wd.equipAtk, div); DAMAGE_DIV_FIX2(wd.masteryAtk, div); }
|
||||
/*=======================================
|
||||
* Check for and calculate multi attacks
|
||||
*---------------------------------------
|
||||
@ -3825,8 +3834,8 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
break;
|
||||
case RL_D_TAIL:
|
||||
skillratio += -100 + (2500 + 500 * skill_lv );
|
||||
if (sd && &sd->c_marker)
|
||||
skillratio /= max(sd->c_marker.count,1);
|
||||
//if (sd && &sd->c_marker)
|
||||
// skillratio /= max(sd->c_marker.count,1);
|
||||
break;
|
||||
case RL_R_TRIP:
|
||||
skillratio += -100 + (150 * skill_lv); //(custom)
|
||||
@ -3849,6 +3858,9 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
case RL_FIRE_RAIN:
|
||||
skillratio += -100 + 2000 + status_get_dex(src); //(custom) //kRO Update 2013-07-24. 2,000% + caster's DEX (?) [Cydh]
|
||||
break;
|
||||
case RL_AM_BLAST:
|
||||
skillratio += -100 + (skill_lv * status_get_dex(src) / 2); //(custom)
|
||||
break;
|
||||
}
|
||||
return skillratio;
|
||||
}
|
||||
@ -4656,7 +4668,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Skill damage adjustment */
|
||||
// Skill damage adjustment
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
if ((skill_damage = battle_skill_damage(src, target, skill_id)) != 0)
|
||||
ATK_ADDRATE(wd.damage, wd.damage2, skill_damage);
|
||||
@ -5118,9 +5130,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
}
|
||||
|
||||
// perform multihit calculations
|
||||
damage_div_fix_renewal(wd, wd.div_);
|
||||
DAMAGE_DIV_FIX_RENEWAL(wd, wd.div_);
|
||||
#endif
|
||||
damage_div_fix(wd.damage, wd.div_);
|
||||
DAMAGE_DIV_FIX(wd.damage, wd.div_);
|
||||
|
||||
// only do 1 dmg to plant, no need to calculate rest
|
||||
if(target_has_infinite_defense(target, skill_id))
|
||||
@ -5886,7 +5898,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
#endif
|
||||
}
|
||||
|
||||
damage_div_fix(ad.damage, ad.div_);
|
||||
DAMAGE_DIV_FIX(ad.damage, ad.div_);
|
||||
|
||||
if (flag.infdef && ad.damage)
|
||||
ad.damage = ad.damage>0?1:-1;
|
||||
@ -5906,7 +5918,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
break;
|
||||
}
|
||||
|
||||
/* Skill damage adjustment */
|
||||
// Skill damage adjustment
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
|
||||
MATK_ADDRATE(skill_damage);
|
||||
@ -6015,7 +6027,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
|
||||
if (skill_id == SN_FALCONASSAULT) {
|
||||
//Div fix of Blitzbeat
|
||||
damage_div_fix2(md.damage, skill_get_num(HT_BLITZBEAT, 5));
|
||||
DAMAGE_DIV_FIX2(md.damage, skill_get_num(HT_BLITZBEAT, 5));
|
||||
|
||||
//Falcon Assault Modifier
|
||||
md.damage=(int64)md.damage*(150+70*skill_lv)/100;
|
||||
@ -6189,7 +6201,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
|
||||
}
|
||||
|
||||
damage_div_fix(md.damage, md.div_);
|
||||
DAMAGE_DIV_FIX(md.damage, md.div_);
|
||||
|
||||
if (!(nk&NK_IGNORE_FLEE))
|
||||
{
|
||||
@ -6294,7 +6306,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
break;
|
||||
}
|
||||
|
||||
/* Skill damage adjustment */
|
||||
// Skill damage adjustment
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
if ((skill_damage = battle_skill_damage(src,target,skill_id)) != 0)
|
||||
md.damage += (int64)md.damage * skill_damage / 100;
|
||||
|
@ -2261,7 +2261,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
|
||||
WFIFOL(fd,offs+23)=sd->status.inventory[n].expire_time;
|
||||
#endif
|
||||
#if PACKETVER >= 20071002
|
||||
WFIFOW(fd,offs+27)=sd->status.inventory[n].bound ? 2 : 0;
|
||||
WFIFOW(fd,offs+27)=sd->status.inventory[n].bound ? BOUND_GUILD : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2367,7 +2367,7 @@ void clif_item_sub(unsigned char *buf, int n, int idx, struct item *i, struct it
|
||||
clif_addcards(WBUFP(buf, n+12), i); //8B
|
||||
#if PACKETVER >= 20071002
|
||||
WBUFL(buf,n+20)=i->expire_time;
|
||||
WBUFW(buf,n+24)=i->bound ? 2 : 0;
|
||||
WBUFW(buf,n+24)=i->bound ? BOUND_GUILD : 0;
|
||||
#endif
|
||||
#if PACKETVER >= 20100629
|
||||
WBUFW(buf,n+26)= (id->equip&EQP_VISIBLE)?id->look:0;
|
||||
|
@ -561,19 +561,19 @@ int elemental_unlocktarget(struct elemental_data *ed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) {
|
||||
int idx = skill_get_index(skill_id);
|
||||
bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) {
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
nullpo_retr(1,ed);
|
||||
|
||||
if (idx == 0)
|
||||
return 1; // invalid skill id
|
||||
return false; // invalid skill id
|
||||
|
||||
return skill_isNotOk(skill_id,ed->master);
|
||||
}
|
||||
|
||||
struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
|
||||
struct skill_condition req;
|
||||
int idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
memset(&req,0,sizeof(req));
|
||||
|
||||
|
@ -92,7 +92,7 @@ void elemental_summon_stop(struct elemental_data *ed);
|
||||
int elemental_get_lifetime(struct elemental_data *ed);
|
||||
|
||||
int elemental_unlocktarget(struct elemental_data *ed);
|
||||
int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed);
|
||||
bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed);
|
||||
int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
|
||||
int elemental_clean_single_effect(struct elemental_data *ed, uint16 skill_id);
|
||||
int elemental_clean_effect(struct elemental_data *ed);
|
||||
|
@ -1807,7 +1807,7 @@ int guild_break(struct map_session_data *sd,char *name) {
|
||||
//Guild bound item check - Removes the bound flag
|
||||
j = pc_bound_chk(sd,2,idxlist);
|
||||
for(i=0;i<j;i++)
|
||||
sd->status.inventory[idxlist[i]].bound = 0;
|
||||
sd->status.inventory[idxlist[i]].bound = BOUND_NONE;
|
||||
#endif
|
||||
|
||||
intif_guild_break(g->guild_id);
|
||||
|
@ -471,13 +471,14 @@ struct item_data* itemdb_search(int nameid)
|
||||
return id;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Returns if given item is a player-equippable piece.
|
||||
*------------------------------------------*/
|
||||
bool itemdb_isequip(int nameid)
|
||||
/** 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)
|
||||
{
|
||||
int type=itemdb_type(nameid);
|
||||
switch (type) {
|
||||
nullpo_ret(id);
|
||||
switch(id->type) {
|
||||
case IT_WEAPON:
|
||||
case IT_ARMOR:
|
||||
case IT_AMMO:
|
||||
@ -488,48 +489,14 @@ bool itemdb_isequip(int nameid)
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Alternate version of itemdb_isequip
|
||||
*------------------------------------------*/
|
||||
bool itemdb_isequip2(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) {
|
||||
case IT_WEAPON:
|
||||
case IT_ARMOR:
|
||||
case IT_AMMO:
|
||||
case IT_SHADOWGEAR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* 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)
|
||||
{
|
||||
nullpo_ret(data);
|
||||
switch(data->type) {
|
||||
nullpo_ret(id);
|
||||
switch(id->type) {
|
||||
case IT_WEAPON:
|
||||
case IT_ARMOR:
|
||||
case IT_PETEGG:
|
||||
@ -665,7 +632,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
unsigned int j, prob = 1;
|
||||
uint16 nameid, amt = 1, dur = 0;
|
||||
uint8 rand_group = 1;
|
||||
char *str[9], *p, announced = 0, named = 0, bound = 0;
|
||||
char *str[9], *p, announced = 0, named = 0, bound = BOUND_NONE;
|
||||
struct s_item_group_random *random = NULL;
|
||||
struct s_item_group_db *group = NULL;
|
||||
bool found = false;
|
||||
@ -739,7 +706,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
if (str[5] != NULL) announced = atoi(str[5]);
|
||||
if (str[6] != NULL) dur = cap_value(atoi(str[6]),0,UINT16_MAX);
|
||||
if (str[7] != NULL) named = atoi(str[7]);
|
||||
if (str[8] != NULL) bound = cap_value(atoi(str[8]),0,4);
|
||||
if (str[8] != NULL) bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1);
|
||||
|
||||
found = true;
|
||||
if (!(group = (struct s_item_group_db *) idb_get(itemdb_group, group_id))) {
|
||||
@ -986,23 +953,25 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current) {
|
||||
|
||||
/** Misc Item flags
|
||||
* <item_id>,<flag>
|
||||
* &1 - Log as dead branch
|
||||
* &1 - As dead branch item
|
||||
* &2 - As item container
|
||||
*/
|
||||
static bool itemdb_read_flag(char* fields[], int columns, int current) {
|
||||
uint16 nameid = atoi(fields[0]);
|
||||
uint8 flag = atoi(fields[1]);
|
||||
uint8 flag;
|
||||
bool set;
|
||||
struct item_data *id;
|
||||
|
||||
if (!(id = itemdb_exists(nameid))) {
|
||||
ShowError("itemdb_read_flag: Invalid item item with id %d\n", nameid);
|
||||
return true;
|
||||
}
|
||||
|
||||
flag = abs(atoi(fields[1]));
|
||||
set = atoi(fields[1]) > 0;
|
||||
|
||||
if (flag&1)
|
||||
id->flag.dead_branch = 1;
|
||||
if (flag&2)
|
||||
id->flag.group = 1;
|
||||
if (flag&1) id->flag.dead_branch = set ? 1 : 0;
|
||||
if (flag&2) id->flag.group = set ? 1 : 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1653,7 +1622,8 @@ static void destroy_item_data(struct item_data* self, bool free_self) {
|
||||
for( i = 0; i < self->combos_count; i++ ) {
|
||||
if( !self->combos[i]->isRef ) {
|
||||
aFree(self->combos[i]->nameid);
|
||||
script_free_code(self->combos[i]->script);
|
||||
if (self->combos[i]->script)
|
||||
script_free_code(self->combos[i]->script);
|
||||
}
|
||||
aFree(self->combos[i]);
|
||||
}
|
||||
|
@ -475,11 +475,11 @@ bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(str
|
||||
#define itemdb_canmail(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canmail_sub)
|
||||
#define itemdb_canauction(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canauction_sub)
|
||||
|
||||
bool itemdb_isequip(int);
|
||||
bool itemdb_isequip2(struct item_data *);
|
||||
bool itemdb_isequip2(struct item_data *id);
|
||||
#define itemdb_isequip(nameid) itemdb_isequip2(itemdb_search(nameid))
|
||||
char itemdb_isidentified(int);
|
||||
bool itemdb_isstackable(uint16 nameid);
|
||||
bool itemdb_isstackable2(struct item_data *data);
|
||||
bool itemdb_isstackable2(struct item_data *id);
|
||||
#define itemdb_isstackable(nameid) itemdb_isstackable2(itemdb_search(nameid))
|
||||
uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
|
||||
bool itemdb_isNoEquip(struct item_data *id, uint16 m);
|
||||
|
||||
|
@ -65,7 +65,7 @@ char default_codepage[32] = "";
|
||||
int map_server_port = 3306;
|
||||
char map_server_ip[32] = "127.0.0.1";
|
||||
char map_server_id[32] = "ragnarok";
|
||||
char map_server_pw[32] = "ragnarok";
|
||||
char map_server_pw[32] = "";
|
||||
char map_server_db[32] = "ragnarok";
|
||||
Sql* mmysql_handle;
|
||||
|
||||
@ -1677,6 +1677,7 @@ int map_quit(struct map_session_data *sd) {
|
||||
status_change_end(&sd->bl, SC_GLORYWOUNDS, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_SOULCOLD, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_HAWKEYES, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_CHASEWALK2, INVALID_TIMER);
|
||||
if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
|
||||
status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
|
||||
status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
|
||||
|
@ -124,9 +124,9 @@ int npc_isnear_sub(struct block_list* bl, va_list args) {
|
||||
int skill_id = va_arg(args, int);
|
||||
|
||||
if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh]
|
||||
int16 idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
if (idx >= 0 && skill_db[idx].unit_nonearnpc_type) {
|
||||
if (idx > 0 && skill_db[idx].unit_nonearnpc_type) {
|
||||
while (1) {
|
||||
if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break;
|
||||
if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) break;
|
||||
@ -3723,40 +3723,46 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
|
||||
map[m].flag.notomb = state;
|
||||
else if (!strcmpi(w3,"skill_damage")) {
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
char skill[NAME_LENGTH];
|
||||
char skill[SKILL_NAME_LENGTH];
|
||||
int pc = 0, mob = 0, boss = 0, other = 0, caster = 0;
|
||||
|
||||
memset(skill,0,sizeof(skill));
|
||||
map[m].flag.skill_damage = state; //set the mapflag
|
||||
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 (!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
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
src/map/pc.c
32
src/map/pc.c
@ -4132,15 +4132,17 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
/**
|
||||
* Searching a specified itemid in inventory and return his stored index
|
||||
*------------------------------------------*/
|
||||
int pc_search_inventory(struct map_session_data *sd,int item_id)
|
||||
{
|
||||
* @param sd Player
|
||||
* @param nameid Find this Item!
|
||||
* @return Stored index in inventory, or -1 if not found.
|
||||
**/
|
||||
short pc_search_inventory(struct map_session_data *sd, uint16 nameid) {
|
||||
int16 i;
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0) );
|
||||
ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && (sd->status.inventory[i].amount > 0 || nameid == 0) );
|
||||
return ( i < MAX_INVENTORY ) ? i : -1;
|
||||
}
|
||||
|
||||
@ -4736,7 +4738,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( !itemdb_cancartstore(item_data, pc_get_group_level(sd)) || (item_data->bound > 1 && !pc_can_give_bounded_items(sd)))
|
||||
if( !itemdb_cancartstore(item_data, pc_get_group_level(sd)) || (item_data->bound > BOUND_ACCOUNT && !pc_can_give_bounded_items(sd)))
|
||||
{ // Check item trade restrictions [Skotlex]
|
||||
clif_displaymessage (sd->fd, msg_txt(sd,264));
|
||||
return 1;
|
||||
@ -4896,7 +4898,7 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
|
||||
* 3 Party Bound
|
||||
* 4 Character Bound
|
||||
*------------------------------------------*/
|
||||
int pc_bound_chk(TBL_PC *sd,int type,int *idxlist)
|
||||
int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist)
|
||||
{
|
||||
int i=0, j=0;
|
||||
for(i=0;i<MAX_INVENTORY;i++){
|
||||
@ -5308,17 +5310,17 @@ int pc_memo(struct map_session_data* sd, int pos)
|
||||
* @param lv : skill lv
|
||||
* @return player skill cooldown
|
||||
*/
|
||||
int pc_get_skillcooldown(struct map_session_data *sd, int id, int lv) {
|
||||
int i, cooldown=0;
|
||||
int idx = skill_get_index (id);
|
||||
int cooldownlen = ARRAYLENGTH(sd->skillcooldown);
|
||||
int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv) {
|
||||
uint8 i;
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
int cooldown = 0, cooldownlen = ARRAYLENGTH(sd->skillcooldown);
|
||||
|
||||
if (!idx) return 0;
|
||||
if (skill_db[idx].cooldown[lv - 1])
|
||||
cooldown = skill_db[idx].cooldown[lv - 1];
|
||||
if (skill_db[idx].cooldown[skill_lv - 1])
|
||||
cooldown = skill_db[idx].cooldown[skill_lv - 1];
|
||||
|
||||
ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == id);
|
||||
if(i<cooldownlen){
|
||||
ARR_FIND(0, cooldownlen, i, sd->skillcooldown[i].id == skill_id);
|
||||
if (i < cooldownlen) {
|
||||
cooldown += sd->skillcooldown[i].val;
|
||||
cooldown = max(0,cooldown);
|
||||
}
|
||||
|
@ -827,7 +827,7 @@ int pc_isequip(struct map_session_data *sd,int n);
|
||||
int pc_equippoint(struct map_session_data *sd,int n);
|
||||
int pc_setinventorydata(struct map_session_data *sd);
|
||||
|
||||
int pc_get_skillcooldown(struct map_session_data *sd, int id, int lv);
|
||||
int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
int pc_checkskill(struct map_session_data *sd,uint16 skill_id);
|
||||
short pc_checkequip(struct map_session_data *sd,int pos);
|
||||
bool pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max);
|
||||
@ -851,14 +851,14 @@ int pc_memo(struct map_session_data* sd, int pos);
|
||||
|
||||
int pc_checkadditem(struct map_session_data*,int,int);
|
||||
int pc_inventoryblank(struct map_session_data*);
|
||||
int pc_search_inventory(struct map_session_data *sd,int item_id);
|
||||
short pc_search_inventory(struct map_session_data *sd, uint16 nameid);
|
||||
int pc_payzeny(struct map_session_data*,int, enum e_log_pick_type type, struct map_session_data*);
|
||||
char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type);
|
||||
int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_session_data*);
|
||||
int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type);
|
||||
|
||||
//Bound items
|
||||
int pc_bound_chk(TBL_PC *sd,int type,int *idxlist);
|
||||
int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist);
|
||||
|
||||
// Special Shop System
|
||||
int pc_paycash( struct map_session_data *sd, int price, int points, e_log_pick_type type );
|
||||
|
@ -2289,6 +2289,7 @@ void script_hardcoded_constants(void) {
|
||||
script_set_constant("Option_Invisible",OPTION_INVISIBLE,false);
|
||||
script_set_constant("Option_Orcish",OPTION_ORCISH,false);
|
||||
script_set_constant("Option_Wedding",OPTION_WEDDING,false);
|
||||
script_set_constant("Option_Ruwach",OPTION_RUWACH,false);
|
||||
script_set_constant("Option_Chasewalk",OPTION_CHASEWALK,false);
|
||||
script_set_constant("Option_Flying",OPTION_FLYING,false);
|
||||
script_set_constant("Option_Xmas",OPTION_XMAS,false);
|
||||
@ -6455,22 +6456,24 @@ BUILDIN_FUNC(getitem)
|
||||
|
||||
if( !strcmp(script_getfuncname(st),"getitembound") ) {
|
||||
char bound = script_getnum(st,4);
|
||||
if( bound < 1 || bound > 4) { //Not a correct bound type
|
||||
ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound);
|
||||
return 1;
|
||||
if( bound > BOUND_NONE && bound < BOUND_MAX ) {
|
||||
it.bound = bound;
|
||||
if( script_hasdata(st,5) )
|
||||
sd=map_id2sd(script_getnum(st,5));
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
}
|
||||
else { //Not a correct bound type
|
||||
ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
it.bound = bound;
|
||||
if( script_hasdata(st,5) )
|
||||
sd=map_id2sd(script_getnum(st,5));
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
} else if( script_hasdata(st,4) )
|
||||
sd=map_id2sd(script_getnum(st,4)); // <Account ID>
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
|
||||
if( sd == NULL ) // no target
|
||||
return 0;
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
//Check if it's stackable.
|
||||
if (!itemdb_isstackable(nameid))
|
||||
@ -6499,9 +6502,9 @@ BUILDIN_FUNC(getitem)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(getitem2)
|
||||
{
|
||||
int nameid,amount,get_count,i,flag = 0;
|
||||
int iden,ref,attr,c1,c2,c3,c4;
|
||||
char bound=0;
|
||||
int nameid, amount, get_count, i, flag = 0;
|
||||
int iden, ref, attr, c1, c2, c3, c4;
|
||||
char bound = BOUND_NONE;
|
||||
struct item_data *item_data;
|
||||
struct item item_tmp;
|
||||
TBL_PC *sd;
|
||||
@ -6509,21 +6512,23 @@ BUILDIN_FUNC(getitem2)
|
||||
|
||||
if( !strcmp(script_getfuncname(st),"getitembound2") ) {
|
||||
bound = script_getnum(st,11);
|
||||
if( bound < 1 || bound > 3) { //Not a correct bound type
|
||||
ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound);
|
||||
return 1;
|
||||
if( bound > BOUND_NONE && bound < BOUND_MAX ) {
|
||||
if( script_hasdata(st,12) )
|
||||
sd=map_id2sd(script_getnum(st,12));
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
}
|
||||
else {
|
||||
ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
if( script_hasdata(st,12) )
|
||||
sd=map_id2sd(script_getnum(st,12));
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
} else if( script_hasdata(st,11) )
|
||||
sd=map_id2sd(script_getnum(st,11)); // <Account ID>
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
|
||||
if( sd == NULL ) // no target
|
||||
return 0;
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
data=script_getdata(st,2);
|
||||
get_val(st,data);
|
||||
@ -6652,7 +6657,7 @@ BUILDIN_FUNC(rentitem) {
|
||||
it.nameid = nameid;
|
||||
it.identify = 1;
|
||||
it.expire_time = (unsigned int)(time(NULL) + seconds);
|
||||
it.bound = 0;
|
||||
it.bound = BOUND_NONE;
|
||||
|
||||
if( (flag = pc_additem(sd, &it, 1, LOG_TYPE_SCRIPT)) )
|
||||
{
|
||||
@ -11472,7 +11477,8 @@ BUILDIN_FUNC(removemapflag)
|
||||
case MF_SKILL_DAMAGE:
|
||||
{
|
||||
map[m].flag.skill_damage = 0;
|
||||
memset(&map[m].adjust.damage,0,sizeof(map[m].adjust.damage));
|
||||
memset(map[m].skill_damage, 0, sizeof(map[m].skill_damage));
|
||||
memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage));
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
@ -18228,24 +18234,24 @@ BUILDIN_FUNC(stand)
|
||||
|
||||
/** Creates an array of bounded item IDs
|
||||
* countbound {<type>};
|
||||
* @param type: 1 - Account Bound; 2 - Guild Bound; 3 - Party Bound
|
||||
* @param type: 0 - All bound items; 1 - Account Bound; 2 - Guild Bound; 3 - Party Bound
|
||||
* @return amt: Amount of items found
|
||||
*/
|
||||
BUILDIN_FUNC(countbound)
|
||||
{
|
||||
int i, type, j=0, k=0;
|
||||
int i, type, j = 0, k = 0;
|
||||
TBL_PC *sd;
|
||||
|
||||
if( (sd = script_rid2sd(st)) == NULL )
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
type = script_hasdata(st,2)?script_getnum(st,2):0;
|
||||
type = script_getnum(st,2);
|
||||
|
||||
for(i=0;i<MAX_INVENTORY;i++){
|
||||
if(sd->status.inventory[i].nameid > 0 && (
|
||||
(!type && sd->status.inventory[i].bound > 0) ||
|
||||
(type && sd->status.inventory[i].bound == type)
|
||||
)) {
|
||||
for( i = 0; i < MAX_INVENTORY; i ++ ) {
|
||||
if( sd->status.inventory[i].nameid > 0 && (
|
||||
(!type && sd->status.inventory[i].bound) || (type && sd->status.inventory[i].bound == type)
|
||||
))
|
||||
{
|
||||
pc_setreg(sd,reference_uid(add_str("@bound_items"), k),sd->status.inventory[i].nameid);
|
||||
k++;
|
||||
j += sd->status.inventory[i].amount;
|
||||
|
328
src/map/skill.c
328
src/map/skill.c
@ -445,7 +445,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
|
||||
* @author Aru - for previous check; Jobbie for class restriction idea; Cydh expands the copyable skill
|
||||
*/
|
||||
static char skill_isCopyable(struct map_session_data *sd, uint16 skill_id) {
|
||||
int idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
// Only copy skill that player doesn't have or the skill is old clone
|
||||
if (sd->status.skill[idx].id != 0 && sd->status.skill[idx].flag != SKILL_FLAG_PLAGIARIZED)
|
||||
@ -721,7 +721,7 @@ bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md)
|
||||
bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y) {
|
||||
int inf;
|
||||
|
||||
if (!src || skill_get_index(skill_id) < 0)
|
||||
if (!src || skill_get_index(skill_id) == 0)
|
||||
return false;
|
||||
|
||||
if (src->type == BL_PC && pc_has_permission(BL_CAST(BL_PC,src),PC_PERM_SKILL_UNCONDITIONAL))
|
||||
@ -1550,10 +1550,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
|
||||
case RL_SLUGSHOT:
|
||||
if (bl->type != BL_PC)
|
||||
sc_start(src,bl,SC_STUN,10 * skill_lv + rnd()%50,skill_lv,skill_get_time2(skill_id,skill_lv)); //(custom)
|
||||
else if (dstsd) {
|
||||
pc_setsit(dstsd);
|
||||
clif_sitting(bl);
|
||||
}
|
||||
else if (dstsd)
|
||||
//sit duration 2+skill_lv
|
||||
status_change_start(src,bl,SC_SITDOWN_FORCE,10000,skill_lv,0,0,0,(2+skill_lv)*1000,1|2|8);
|
||||
break;
|
||||
case RL_BANISHING_BUSTER:
|
||||
{
|
||||
@ -1625,7 +1624,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
|
||||
case SC_REBOUND: case SC_TELEKINESIS_INTENSE:
|
||||
case SC_HEAT_BARREL: case SC_HEAT_BARREL_AFTER: case SC_P_ALTER:
|
||||
case SC_E_CHAIN: case SC_C_MARKER: case SC_B_TRAP:
|
||||
case SC_H_MINE: case SC_RECOGNIZEDSPELL:
|
||||
case SC_H_MINE: case SC_RECOGNIZEDSPELL: case SC_CHASEWALK2:
|
||||
case SC_MTF_ASPD: case SC_MTF_RANGEATK: case SC_MTF_MATK:
|
||||
case SC_MTF_MLEATKED: case SC_MTF_CRIDAMAGE: case SC_GN_CARTBOOST:
|
||||
#ifdef RENEWAL
|
||||
@ -2594,7 +2593,7 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
|
||||
else if (&tsd->sc && tsd->sc.data[SC_PRESERVE] && !tsd->sc.data[SC__REPRODUCE])
|
||||
return;
|
||||
else {
|
||||
short idx;
|
||||
uint16 idx;
|
||||
unsigned char lv;
|
||||
|
||||
// Copy Referal: dummy skills should point to their source upon copying
|
||||
@ -2629,7 +2628,7 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
|
||||
}
|
||||
|
||||
//Use skill index, avoiding out-of-bound array [Cydh]
|
||||
if ((idx = skill_get_index(skill_id)) < 0)
|
||||
if (!(idx = skill_get_index(skill_id)))
|
||||
return;
|
||||
|
||||
switch (skill_isCopyable(tsd,skill_id)) {
|
||||
@ -3011,7 +3010,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
|
||||
map_freeblock_lock();
|
||||
|
||||
if (bl->type == BL_PC && skill_id && skill_get_index(skill_id) >= 0 && skill_db[skill_get_index(skill_id)].copyable.option && //Only copy skill that copyable [Cydh]
|
||||
if (bl->type == BL_PC && skill_id && skill_get_index(skill_id) > 0 && skill_db[skill_get_index(skill_id)].copyable.option && //Only copy skill that copyable [Cydh]
|
||||
dmg.flag&BF_SKILL && dmg.damage+dmg.damage2 > 0 && damage < status_get_hp(bl)) //Cannot copy skills if the blow will kill you. [Skotlex]
|
||||
skill_do_copy(src,bl,skill_id,skill_lv);
|
||||
|
||||
@ -3413,7 +3412,7 @@ static int skill_check_condition_mercenary(struct block_list *bl, int skill, int
|
||||
if( (idx = skill_get_index(skill)) == 0 )
|
||||
return 0;
|
||||
|
||||
// Requeriments
|
||||
// Requirements
|
||||
for( i = 0; i < ARRAYLENGTH(itemid); i++ )
|
||||
{
|
||||
itemid[i] = skill_db[idx].require.itemid[i];
|
||||
@ -14453,7 +14452,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
|
||||
break;
|
||||
case ST_MADO:
|
||||
if( !pc_ismadogear(sd) ) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_MADOGEAR,0);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -14475,10 +14474,6 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
|
||||
if (require.status_count) {
|
||||
uint8 i;
|
||||
/* May has multiple requirements */
|
||||
//if (!sc) {
|
||||
// clif_skill_fail(sd, skill_id, USESKILL_FAIL_CONDITION, 0);
|
||||
// return false;
|
||||
//}
|
||||
for (i = 0; i < require.status_count; i++) {
|
||||
enum sc_type req_sc = require.status[i];
|
||||
if (req_sc == SC_NONE)
|
||||
@ -14512,10 +14507,11 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
|
||||
//check if equiped item
|
||||
if (require.eqItem_count) {
|
||||
for (i = 0; i < require.eqItem_count; i++) {
|
||||
int reqeqit = require.eqItem[i];
|
||||
if(!reqeqit) break; //no more required item get out of here
|
||||
uint16 reqeqit = require.eqItem[i];
|
||||
if (!reqeqit)
|
||||
break; //no more required item get out of here
|
||||
if (!pc_checkequip2(sd,reqeqit,EQI_ACC_L,EQI_MAX)) {
|
||||
char output[128];
|
||||
char output[CHAT_SIZE_MAX];
|
||||
//Official use msgstringtable.txt for each skill failure
|
||||
sprintf(output,msg_txt(sd,722),itemdb_jname(reqeqit));
|
||||
clif_colormes(sd,color_table[COLOR_RED],output);
|
||||
@ -14566,7 +14562,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
|
||||
struct skill_condition require;
|
||||
struct status_data *status;
|
||||
int i;
|
||||
int index[MAX_SKILL_ITEM_REQUIRE];
|
||||
short index[MAX_SKILL_ITEM_REQUIRE];
|
||||
|
||||
nullpo_retr(false,sd);
|
||||
|
||||
@ -14724,8 +14720,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
|
||||
else if( require.itemid[i] == ITEMID_ANCILLA )
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_ANCILLA,0); //Ancilla is required.
|
||||
else {
|
||||
char output[128];
|
||||
|
||||
char output[CHAT_SIZE_MAX];
|
||||
//Official is using msgstringtable.txt for each requirement failure
|
||||
//clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
sprintf(output, msg_txt(sd,720), itemdb_jname(require.itemid[i])); // %s is required.
|
||||
@ -14748,45 +14743,45 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
|
||||
*/
|
||||
void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type)
|
||||
{
|
||||
struct skill_condition req;
|
||||
struct skill_condition require;
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
req = skill_get_requirement(sd,skill_id,skill_lv);
|
||||
require = skill_get_requirement(sd,skill_id,skill_lv);
|
||||
|
||||
if( type&1 ) {
|
||||
switch( skill_id ) {
|
||||
case CG_TAROTCARD: // TarotCard will consume sp in skill_cast_nodamage_id [Inkfish]
|
||||
case MC_IDENTIFY:
|
||||
case RL_D_TAIL:
|
||||
req.sp = 0;
|
||||
require.sp = 0;
|
||||
break;
|
||||
case GS_DESPERADO:
|
||||
if (sd->skill_id_old == RL_FALLEN_ANGEL) //Don't consume SP if triggered by Fallen Angel
|
||||
req.sp = 0;
|
||||
require.sp = 0;
|
||||
break;
|
||||
default:
|
||||
if(sd->state.autocast)
|
||||
req.sp = 0;
|
||||
require.sp = 0;
|
||||
break;
|
||||
}
|
||||
if(req.hp || req.sp)
|
||||
status_zap(&sd->bl, req.hp, req.sp);
|
||||
if(require.hp || require.sp)
|
||||
status_zap(&sd->bl, require.hp, require.sp);
|
||||
|
||||
if(req.spiritball > 0)
|
||||
pc_delspiritball(sd,req.spiritball,0);
|
||||
else if(req.spiritball == -1) {
|
||||
if(require.spiritball > 0)
|
||||
pc_delspiritball(sd,require.spiritball,0);
|
||||
else if(require.spiritball == -1) {
|
||||
sd->spiritball_old = sd->spiritball;
|
||||
pc_delspiritball(sd,sd->spiritball,0);
|
||||
}
|
||||
|
||||
if(req.zeny > 0)
|
||||
if(require.zeny > 0)
|
||||
{
|
||||
if( skill_id == NJ_ZENYNAGE )
|
||||
req.zeny = 0; //Zeny is reduced on skill_attack.
|
||||
if( sd->status.zeny < req.zeny )
|
||||
req.zeny = sd->status.zeny;
|
||||
pc_payzeny(sd,req.zeny,LOG_TYPE_CONSUME,NULL);
|
||||
require.zeny = 0; //Zeny is reduced on skill_attack.
|
||||
if( sd->status.zeny < require.zeny )
|
||||
require.zeny = sd->status.zeny;
|
||||
pc_payzeny(sd,require.zeny,LOG_TYPE_CONSUME,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14799,10 +14794,10 @@ void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, ui
|
||||
|
||||
for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i )
|
||||
{
|
||||
if( !req.itemid[i] )
|
||||
if( !require.itemid[i] )
|
||||
continue;
|
||||
|
||||
if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
|
||||
if( itemid_isgemstone(require.itemid[i]) && skill_id != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
|
||||
continue; //Gemstones are checked, but not substracted from inventory.
|
||||
|
||||
switch( skill_id ){
|
||||
@ -14831,8 +14826,8 @@ void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, ui
|
||||
break;
|
||||
}
|
||||
|
||||
if( (n = pc_search_inventory(sd,req.itemid[i])) >= 0 )
|
||||
pc_delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME);
|
||||
if( (n = pc_search_inventory(sd,require.itemid[i])) >= 0 )
|
||||
pc_delitem(sd,n,require.amount[i],0,1,LOG_TYPE_CONSUME);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14851,6 +14846,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
|
||||
struct status_change *sc;
|
||||
int i,hp_rate,sp_rate, sp_skill_rate_bonus = 100;
|
||||
uint16 idx;
|
||||
bool level_dependent = false;
|
||||
|
||||
memset(&req,0,sizeof(req));
|
||||
|
||||
@ -14945,85 +14941,13 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
|
||||
req.eqItem_count = skill_db[idx].require.eqItem_count;
|
||||
req.eqItem = skill_db[idx].require.eqItem;
|
||||
|
||||
for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++ ) {
|
||||
if( (skill_id == AM_POTIONPITCHER || skill_id == CR_SLIMPITCHER || skill_id == CR_CULTIVATION) && i != skill_lv%11 - 1 )
|
||||
continue;
|
||||
|
||||
switch( skill_id ) {
|
||||
case AM_CALLHOMUN:
|
||||
if (sd->status.hom_id) //Don't delete items when hom is already out.
|
||||
continue;
|
||||
break;
|
||||
case NC_SHAPESHIFT:
|
||||
if( i < 4 )
|
||||
continue;
|
||||
break;
|
||||
case WZ_FIREPILLAR: // celest
|
||||
if (skill_lv <= 5) // no gems required at level 1-5
|
||||
continue;
|
||||
break;
|
||||
case AB_ADORAMUS:
|
||||
if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2)) )
|
||||
continue;
|
||||
break;
|
||||
case WL_COMET:
|
||||
if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0)) )
|
||||
continue;
|
||||
break;
|
||||
case GN_FIRE_EXPANSION:
|
||||
if( i < 5 )
|
||||
continue;
|
||||
break;
|
||||
case SO_SUMMON_AGNI:
|
||||
case SO_SUMMON_AQUA:
|
||||
case SO_SUMMON_VENTUS:
|
||||
case SO_SUMMON_TERA:
|
||||
case SO_WATER_INSIGNIA:
|
||||
case SO_FIRE_INSIGNIA:
|
||||
case SO_WIND_INSIGNIA:
|
||||
case SO_EARTH_INSIGNIA:
|
||||
if( i < 3 )
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
req.itemid[i] = skill_db[idx].require.itemid[i];
|
||||
req.amount[i] = skill_db[idx].require.amount[i];
|
||||
|
||||
// Check requirement for gemstone.
|
||||
if (itemid_isgemstone(req.itemid[i])) {
|
||||
if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
|
||||
req.itemid[i] = req.amount[i] = 0;
|
||||
else {
|
||||
if( sd->special_state.no_gemstone )
|
||||
{ // All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
|
||||
if( skill_id != SA_ABRACADABRA )
|
||||
req.itemid[i] = req.amount[i] = 0;
|
||||
else if( --req.amount[i] < 1 )
|
||||
req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
|
||||
}
|
||||
if(sc && sc->data[SC_INTOABYSS])
|
||||
{
|
||||
if( skill_id != SA_ABRACADABRA )
|
||||
req.itemid[i] = req.amount[i] = 0;
|
||||
else if( --req.amount[i] < 1 )
|
||||
req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
|
||||
}
|
||||
}
|
||||
}
|
||||
if( skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
|
||||
int16 itIndex;
|
||||
if( (itIndex = pc_search_inventory(sd,req.itemid[i])) < 0 || ( itIndex >= 0 && sd->status.inventory[itIndex].amount < req.amount[i] ) ){
|
||||
req.itemid[i] = ITEMID_TRAP_ALLOY;
|
||||
req.amount[i] = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* requirements are level-dependent */
|
||||
switch( skill_id ) {
|
||||
/* Skill level-dependent checks */
|
||||
case NC_SHAPESHIFT:
|
||||
case NC_REPAIR:
|
||||
//NOTE: Please make sure Magic_Gear_Fuel in the last position in skill_require_db.txt
|
||||
req.itemid[1] = skill_db[idx].require.itemid[MAX_SKILL_ITEM_REQUIRE-1];
|
||||
req.amount[1] = skill_db[idx].require.amount[MAX_SKILL_ITEM_REQUIRE-1];
|
||||
case GN_FIRE_EXPANSION:
|
||||
case SO_SUMMON_AGNI:
|
||||
case SO_SUMMON_AQUA:
|
||||
@ -15033,26 +14957,74 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
|
||||
case SO_FIRE_INSIGNIA:
|
||||
case SO_WIND_INSIGNIA:
|
||||
case SO_EARTH_INSIGNIA:
|
||||
req.itemid[skill_lv-1] = skill_db[idx].require.itemid[skill_lv-1];
|
||||
req.amount[skill_lv-1] = skill_db[idx].require.amount[skill_lv-1];
|
||||
case WZ_FIREPILLAR: // no gems required at level 1-5 [celest]
|
||||
req.itemid[0] = skill_db[idx].require.itemid[min(skill_lv-1,MAX_SKILL_ITEM_REQUIRE-1)];
|
||||
req.amount[0] = skill_db[idx].require.amount[min(skill_lv-1,MAX_SKILL_ITEM_REQUIRE-1)];
|
||||
level_dependent = true;
|
||||
|
||||
/* Normal skill requirements and gemstone checks */
|
||||
default:
|
||||
for( i = 0; i < ((!level_dependent) ? MAX_SKILL_ITEM_REQUIRE : 2); i++ ) {
|
||||
// Skip this for level_dependent requirement, just looking forward for gemstone removal. Assumed if there is gemstone there.
|
||||
if (!level_dependent) {
|
||||
switch( skill_id ) {
|
||||
case AM_POTIONPITCHER:
|
||||
case CR_SLIMPITCHER:
|
||||
case CR_CULTIVATION:
|
||||
if (i != skill_lv%11 - 1)
|
||||
continue;
|
||||
break;
|
||||
case AM_CALLHOMUN:
|
||||
if (sd->status.hom_id) //Don't delete items when hom is already out.
|
||||
continue;
|
||||
break;
|
||||
case AB_ADORAMUS:
|
||||
if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2)) )
|
||||
continue;
|
||||
break;
|
||||
case WL_COMET:
|
||||
if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && (sd->special_state.no_gemstone == 2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0)) )
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
req.itemid[i] = skill_db[idx].require.itemid[i];
|
||||
req.amount[i] = skill_db[idx].require.amount[i];
|
||||
|
||||
if( skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
|
||||
int16 itIndex;
|
||||
if( (itIndex = pc_search_inventory(sd,req.itemid[i])) < 0 || ( itIndex >= 0 && sd->status.inventory[itIndex].amount < req.amount[i] ) ){
|
||||
req.itemid[i] = ITEMID_TRAP_ALLOY;
|
||||
req.amount[i] = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check requirement for gemstone.
|
||||
if (itemid_isgemstone(req.itemid[i])) {
|
||||
if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
|
||||
req.itemid[i] = req.amount[i] = 0;
|
||||
else {
|
||||
if( sd->special_state.no_gemstone )
|
||||
{ // All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
|
||||
if( skill_id != SA_ABRACADABRA )
|
||||
req.itemid[i] = req.amount[i] = 0;
|
||||
else if( --req.amount[i] < 1 )
|
||||
req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
|
||||
}
|
||||
if(sc && sc->data[SC_INTOABYSS])
|
||||
{
|
||||
if( skill_id != SA_ABRACADABRA )
|
||||
req.itemid[i] = req.amount[i] = 0;
|
||||
else if( --req.amount[i] < 1 )
|
||||
req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (skill_id == NC_REPAIR) {
|
||||
switch(skill_lv) {
|
||||
case 1:
|
||||
case 2:
|
||||
req.itemid[1] = ITEMID_REPAIR_A;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
req.itemid[1] = ITEMID_REPAIR_B;
|
||||
break;
|
||||
case 5:
|
||||
req.itemid[1] = ITEMID_REPAIR_C;
|
||||
break;
|
||||
}
|
||||
req.amount[1] = 1;
|
||||
}
|
||||
|
||||
// Check for cost reductions due to skills & SCs
|
||||
switch(skill_id) {
|
||||
@ -19350,29 +19322,37 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Split string to int or constanta value (const.txt)
|
||||
/** Split string to int by constanta value (const.txt) or atoi()
|
||||
* @param *str: String input
|
||||
* @param *val: Temporary storage
|
||||
* @param *delim: Delimiter (for multiple value support)
|
||||
* @param useConst: 'true' uses const.txt as reference, 'false' uses atoi()
|
||||
* @param min: Min value of each const. Example: SC has min value SC_NONE (-1), so the value that less or equal won't be counted
|
||||
* @param min_value: Minimum value. If the splitted value is less or equal than this, will be skipped
|
||||
* @param max: Maximum number that can be allocated
|
||||
* @return count: Number of success
|
||||
*/
|
||||
uint8 skill_split2(char *str, int *val, const char *delim, bool useConst, short min) {
|
||||
uint8 skill_split_atoi2(char *str, int *val, const char *delim, int min_value, uint16 max) {
|
||||
uint8 i = 0;
|
||||
char *p = strtok(str,delim);
|
||||
char *p = strtok(str, delim);
|
||||
|
||||
while (p != NULL) {
|
||||
int n = -1;
|
||||
if (useConst)
|
||||
script_get_constant(trim(p),&n);
|
||||
else
|
||||
int n = min_value;
|
||||
trim(p);
|
||||
|
||||
if (ISDIGIT(p[0])) // If using numeric
|
||||
n = atoi(p);
|
||||
if (n > min) {
|
||||
else if (!script_get_constant(p, &n)) { // If using constant value
|
||||
ShowError("skill_split_atoi2: Invalid value: '%s'\n", p);
|
||||
p = strtok(NULL, delim);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n > min_value) {
|
||||
val[i] = n;
|
||||
i++;
|
||||
if (i >= max)
|
||||
break;
|
||||
}
|
||||
p = strtok(NULL,delim);
|
||||
p = strtok(NULL, delim);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -19383,8 +19363,10 @@ static void skill_destroy_requirement(void) {
|
||||
for (i = 0; i < MAX_SKILL; i++) {
|
||||
if (skill_db[i].require.status_count)
|
||||
aFree(skill_db[i].require.status);
|
||||
skill_db[i].require.status_count = 0;
|
||||
if (skill_db[i].require.eqItem_count)
|
||||
aFree(skill_db[i].require.eqItem);
|
||||
skill_db[i].require.eqItem_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19396,10 +19378,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
|
||||
char* p;
|
||||
uint16 skill_id = atoi(split[0]), idx, i;
|
||||
|
||||
if (!skill_get_index(skill_id)) // invalid skill id
|
||||
if (!(idx = skill_get_index(skill_id))) // invalid skill id
|
||||
return false;
|
||||
|
||||
idx = skill_get_index(skill_id);
|
||||
skill_split_atoi(split[1],skill_db[idx].require.hp);
|
||||
skill_split_atoi(split[2],skill_db[idx].require.mhp);
|
||||
skill_split_atoi(split[3],skill_db[idx].require.sp);
|
||||
@ -19455,11 +19436,12 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
|
||||
else skill_db[idx].require.state = ST_NONE; // Unknown or no state
|
||||
|
||||
//Status requirements
|
||||
//FIXME: Default entry should be -1/SC_ALL in skill_require_db.txt but it's 0/SC_STONE.
|
||||
trim(split[11]);
|
||||
if (split[11][0] != '\0') {
|
||||
if (split[11][0] != '\0' || atoi(split[11])) {
|
||||
int require[MAX_SKILL_STATUS_REQUIRE];
|
||||
if ((skill_db[idx].require.status_count = skill_split2(split[11],require,":",true,SC_NONE))) {
|
||||
skill_db[idx].require.status = aMalloc(skill_db[idx].require.status_count * sizeof(sc_type));
|
||||
if ((skill_db[idx].require.status_count = skill_split_atoi2(split[11], require, ":", SC_STONE, ARRAYLENGTH(require)))) {
|
||||
CREATE(skill_db[idx].require.status, enum sc_type, skill_db[idx].require.status_count);
|
||||
for (i = 0; i < skill_db[idx].require.status_count; i++)
|
||||
skill_db[idx].require.status[i] = (sc_type)require[i];
|
||||
}
|
||||
@ -19475,10 +19457,10 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
|
||||
//Equipped Item requirements.
|
||||
//NOTE: We don't check the item is exist or not here
|
||||
trim(split[33]);
|
||||
if (split[33][0] != '\0') {
|
||||
if (split[33][0] != '\0' || atoi(split[33])) {
|
||||
int require[MAX_SKILL_EQUIP_REQUIRE];
|
||||
if ((skill_db[idx].require.eqItem_count = skill_split2(split[33],require,":",false,501))) {
|
||||
skill_db[idx].require.eqItem = aMalloc(skill_db[idx].require.eqItem_count * sizeof(short));
|
||||
if ((skill_db[idx].require.eqItem_count = skill_split_atoi2(split[33], require, ":", 500, ARRAYLENGTH(require)))) {
|
||||
CREATE(skill_db[idx].require.eqItem, uint16, skill_db[idx].require.eqItem_count);
|
||||
for (i = 0; i < skill_db[idx].require.eqItem_count; i++)
|
||||
skill_db[idx].require.eqItem[i] = require[i];
|
||||
}
|
||||
@ -19490,8 +19472,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
|
||||
* SkillID,CastingTime,AfterCastActDelay,AfterCastWalkDelay,Duration1,Duration2,Cooldown{,Fixedcast}
|
||||
*/
|
||||
static bool skill_parse_row_castdb(char* split[], int columns, int current) {
|
||||
uint16 skill_id = atoi(split[0]);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(atoi(split[0]));
|
||||
if( !idx ) // invalid skill id
|
||||
return false;
|
||||
|
||||
@ -19511,8 +19492,7 @@ static bool skill_parse_row_castdb(char* split[], int columns, int current) {
|
||||
* SkillID,Cast,Delay (optional)
|
||||
*/
|
||||
static bool skill_parse_row_castnodexdb(char* split[], int columns, int current) {
|
||||
uint16 skill_id = atoi(split[0]);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(atoi(split[0]));
|
||||
if( !idx ) // invalid skill id
|
||||
return false;
|
||||
|
||||
@ -19527,8 +19507,7 @@ static bool skill_parse_row_castnodexdb(char* split[], int columns, int current)
|
||||
* SkillID,Flag
|
||||
*/
|
||||
static bool skill_parse_row_nocastdb(char* split[], int columns, int current) {
|
||||
uint16 skill_id = atoi(split[0]);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(atoi(split[0]));
|
||||
if( !idx ) // invalid skill id
|
||||
return false;
|
||||
|
||||
@ -19541,8 +19520,7 @@ static bool skill_parse_row_nocastdb(char* split[], int columns, int current) {
|
||||
* ID,unit ID,unit ID 2,layout,range,interval,target,flag
|
||||
*/
|
||||
static bool skill_parse_row_unitdb(char* split[], int columns, int current) {
|
||||
uint16 skill_id = atoi(split[0]);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
uint16 idx = skill_get_index(atoi(split[0]));
|
||||
if( !idx ) // invalid skill id
|
||||
return false;
|
||||
|
||||
@ -19635,7 +19613,7 @@ static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
|
||||
|
||||
if( !skill_get_index(skill_id) || !skill_get_max(skill_id) )
|
||||
ShowError("spellbook_db: Invalid skill ID %d\n", skill_id);
|
||||
if ( !skill_get_inf(skill_id) )
|
||||
if( !skill_get_inf(skill_id) )
|
||||
ShowError("spellbook_db: Passive skills cannot be memorized (%d/%s)\n", skill_id, skill_get_name(skill_id));
|
||||
if( points < 1 )
|
||||
ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skill_id, skill_get_name(skill_id));
|
||||
@ -19709,12 +19687,12 @@ static bool skill_parse_row_copyabledb(char* split[], int column, int current) {
|
||||
uint8 option;
|
||||
|
||||
trim(split[0]);
|
||||
if(ISDIGIT(split[0][0]))
|
||||
if (ISDIGIT(split[0][0]))
|
||||
id = atoi(split[0]);
|
||||
else
|
||||
id = skill_name2id(split[0]);
|
||||
|
||||
if ((id = skill_get_index(id)) < 0) {
|
||||
if ((id = skill_get_index(id)) == 0) {
|
||||
ShowError("skill_parse_row_copyabledb: Invalid skill '%s'\n",split[0]);
|
||||
return false;
|
||||
}
|
||||
@ -19739,12 +19717,12 @@ static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int curr
|
||||
int16 id;
|
||||
|
||||
trim(split[0]);
|
||||
if(ISDIGIT(split[0][0]))
|
||||
if (ISDIGIT(split[0][0]))
|
||||
id = atoi(split[0]);
|
||||
else
|
||||
id = skill_name2id(split[0]);
|
||||
|
||||
if ((id = skill_get_index(id)) < 0) { // invalid skill id
|
||||
if ((id = skill_get_index(id)) == 0) { // invalid skill id
|
||||
ShowError("skill_parse_row_nonearnpcrangedb: Invalid skill '%s'\n",split[0]);
|
||||
return false;
|
||||
}
|
||||
@ -19811,27 +19789,27 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
|
||||
return true;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
/**
|
||||
* Manage Skill Damage database [Lilith]
|
||||
*------------------------------------------*/
|
||||
**/
|
||||
#ifdef ADJUST_SKILL_DAMAGE
|
||||
static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
|
||||
{
|
||||
uint16 skill_id = skill_name2id(split[0]), idx;
|
||||
if ((idx = skill_get_index(skill_id)) < 0) { // invalid skill id
|
||||
if ((idx = skill_get_index(skill_id)) == 0) { // invalid skill id
|
||||
ShowWarning("skill_parse_row_skilldamage: Invalid skill '%s'. Skipping..",split[0]);
|
||||
return false;
|
||||
}
|
||||
memset(&skill_db[idx].damage,0,sizeof(struct s_skill_damage));
|
||||
skill_db[idx].damage.caster |= atoi(split[1]);
|
||||
skill_db[idx].damage.map |= atoi(split[2]);
|
||||
skill_db[idx].damage.pc = cap_value(atoi(split[3]),-100,MAX_SKILL_DAMAGE_RATE);
|
||||
skill_db[idx].damage.pc = cap_value(atoi(split[3]),-100,INT_MAX);
|
||||
if (split[3])
|
||||
skill_db[idx].damage.mob = cap_value(atoi(split[4]),-100,MAX_SKILL_DAMAGE_RATE);
|
||||
skill_db[idx].damage.mob = cap_value(atoi(split[4]),-100,INT_MAX);
|
||||
if (split[4])
|
||||
skill_db[idx].damage.boss = cap_value(atoi(split[5]),-100,MAX_SKILL_DAMAGE_RATE);
|
||||
skill_db[idx].damage.boss = cap_value(atoi(split[5]),-100,INT_MAX);
|
||||
if (split[5])
|
||||
skill_db[idx].damage.other = cap_value(atoi(split[6]),-100,MAX_SKILL_DAMAGE_RATE);
|
||||
skill_db[idx].damage.other = cap_value(atoi(split[6]),-100,INT_MAX);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@ struct status_change_entry;
|
||||
#define MAX_SKILL_IMPROVISE_DB 50
|
||||
#define MAX_SKILL_LEVEL 100
|
||||
#define MAX_SKILL_CRIMSON_MARKER 3
|
||||
#define SKILL_NAME_LENGTH 31
|
||||
#define SKILL_DESC_LENGTH 31
|
||||
|
||||
DBMap* skilldb_name2id;
|
||||
|
||||
@ -104,51 +106,53 @@ enum e_skill_display {
|
||||
SD_PREAMBLE = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
|
||||
};
|
||||
|
||||
#define MAX_SKILL_ITEM_REQUIRE 10
|
||||
#define MAX_SKILL_STATUS_REQUIRE 3
|
||||
#define MAX_SKILL_EQUIP_REQUIRE 10
|
||||
#define MAX_SKILL_ITEM_REQUIRE 10 /// Maximum required items
|
||||
#define MAX_SKILL_STATUS_REQUIRE 3 /// Maximum required statuses
|
||||
#define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item
|
||||
struct skill_condition {
|
||||
int hp,
|
||||
mhp,
|
||||
sp,
|
||||
hp_rate,
|
||||
sp_rate,
|
||||
ammo,
|
||||
ammo_qty,
|
||||
weapon,
|
||||
zeny,
|
||||
state,
|
||||
spiritball,
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE],
|
||||
amount[MAX_SKILL_ITEM_REQUIRE];
|
||||
short *eqItem;
|
||||
enum sc_type *status;
|
||||
uint8 status_count, eqItem_count;
|
||||
int hp, /// HP cost
|
||||
mhp, /// Max HP to trigger
|
||||
sp, /// SP cost
|
||||
hp_rate, /// HP cost (%)
|
||||
sp_rate, /// SP cost (%)
|
||||
ammo, /// Ammo type
|
||||
ammo_qty, /// Amount of ammo
|
||||
weapon, /// Weapon type
|
||||
zeny, /// Zeny cost
|
||||
state, /// State/condition
|
||||
spiritball, /// Spiritball cost
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
|
||||
amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
};
|
||||
|
||||
struct s_skill_require {
|
||||
int hp[MAX_SKILL_LEVEL],
|
||||
mhp[MAX_SKILL_LEVEL],
|
||||
sp[MAX_SKILL_LEVEL],
|
||||
hp_rate[MAX_SKILL_LEVEL],
|
||||
sp_rate[MAX_SKILL_LEVEL],
|
||||
zeny[MAX_SKILL_LEVEL],
|
||||
weapon,
|
||||
ammo,
|
||||
ammo_qty[MAX_SKILL_LEVEL],
|
||||
state,
|
||||
spiritball[MAX_SKILL_LEVEL],
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE],
|
||||
amount[MAX_SKILL_ITEM_REQUIRE];
|
||||
short *eqItem;
|
||||
enum sc_type *status;
|
||||
uint8 status_count, eqItem_count;
|
||||
int hp[MAX_SKILL_LEVEL], /// HP cost
|
||||
mhp[MAX_SKILL_LEVEL], /// Max HP to trigger
|
||||
sp[MAX_SKILL_LEVEL], /// SP cost
|
||||
hp_rate[MAX_SKILL_LEVEL], /// HP cost (%)
|
||||
sp_rate[MAX_SKILL_LEVEL], /// SP cost (%)
|
||||
zeny[MAX_SKILL_LEVEL], /// Zeny cost
|
||||
weapon, /// Weapon type
|
||||
ammo, /// Ammo type
|
||||
ammo_qty[MAX_SKILL_LEVEL], /// Amount of ammo
|
||||
state, /// State/condition
|
||||
spiritball[MAX_SKILL_LEVEL], /// Spiritball cost
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item
|
||||
amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item
|
||||
uint16 *eqItem; /// List of equipped item
|
||||
enum sc_type *status; /// List of Status required (SC)
|
||||
uint8 status_count, /// Count of SC
|
||||
eqItem_count; /// Count of equipped item
|
||||
};
|
||||
|
||||
/// Database skills
|
||||
struct s_skill_db {
|
||||
char name[NAME_LENGTH];
|
||||
char desc[40];
|
||||
char name[SKILL_NAME_LENGTH];
|
||||
char desc[SKILL_DESC_LENGTH];
|
||||
int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
|
||||
int num[MAX_SKILL_LEVEL];
|
||||
int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL];
|
||||
@ -261,7 +265,7 @@ enum {
|
||||
UF_ENSEMBLE = 0x0200, // Duet
|
||||
UF_SONG = 0x0400, // Song
|
||||
UF_DUALMODE = 0x0800, // Spells should trigger both ontimer and onplace/onout/onleft effects.
|
||||
UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center
|
||||
UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center
|
||||
};
|
||||
|
||||
/// Create Database item
|
||||
|
@ -821,11 +821,11 @@ void initChangeTables(void)
|
||||
add_sc( RL_HAMMER_OF_GOD , SC_STUN );
|
||||
set_sc( RL_B_TRAP , SC_B_TRAP , SI_B_TRAP , SCB_SPEED );
|
||||
set_sc( RL_E_CHAIN , SC_E_CHAIN , SI_E_CHAIN , SCB_NONE );
|
||||
set_sc( RL_P_ALTER , SC_P_ALTER , SI_P_ALTER , SCB_BATK );
|
||||
set_sc( RL_P_ALTER , SC_P_ALTER , SI_P_ALTER , SCB_NONE );
|
||||
set_sc( RL_SLUGSHOT , SC_STUN , SI_SLUGSHOT , SCB_NONE );
|
||||
set_sc( RL_HEAT_BARREL , SC_HEAT_BARREL , SI_HEAT_BARREL , SCB_BATK|SCB_ASPD|SCB_HIT );
|
||||
set_sc_with_vfx( RL_C_MARKER , SC_C_MARKER , SI_C_MARKER , SCB_SPEED );
|
||||
set_sc_with_vfx( RL_AM_BLAST , SC_ANTI_M_BLAST , SI_ANTI_M_BLAST , SCB_DEF_ELE );
|
||||
set_sc( RL_HEAT_BARREL , SC_HEAT_BARREL , SI_HEAT_BARREL , SCB_FLEE|SCB_ASPD );
|
||||
set_sc_with_vfx( RL_C_MARKER , SC_C_MARKER , SI_C_MARKER , SCB_FLEE );
|
||||
set_sc_with_vfx( RL_AM_BLAST , SC_ANTI_M_BLAST , SI_ANTI_M_BLAST , SCB_NONE );
|
||||
|
||||
set_sc_with_vfx( SC_ALL_RIDING , SC_ALL_RIDING , SI_ALL_RIDING , SCB_SPEED );
|
||||
|
||||
@ -855,7 +855,7 @@ void initChangeTables(void)
|
||||
StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
|
||||
StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
|
||||
StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
|
||||
StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
|
||||
StatusIconChangeTable[SC_CHASEWALK2] = SI_CHASEWALK2;
|
||||
StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
|
||||
StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
|
||||
StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
|
||||
@ -1055,6 +1055,7 @@ void initChangeTables(void)
|
||||
StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
|
||||
StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
|
||||
StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED;
|
||||
StatusChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
|
||||
|
||||
/* Cash Items */
|
||||
StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
|
||||
@ -4749,6 +4750,8 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
|
||||
return 50;
|
||||
if(sc->data[SC_INCALLSTATUS])
|
||||
str += sc->data[SC_INCALLSTATUS]->val1;
|
||||
if(sc->data[SC_CHASEWALK2])
|
||||
str += sc->data[SC_CHASEWALK2]->val1;
|
||||
if(sc->data[SC_INCSTR])
|
||||
str += sc->data[SC_INCSTR]->val1;
|
||||
if(sc->data[SC_STRFOOD])
|
||||
@ -5174,7 +5177,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
|
||||
if(sc->data[SC__ENERVATION])
|
||||
batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
|
||||
if( sc->data[SC_ZANGETSU] )
|
||||
batk += batk * sc->data[SC_ZANGETSU]->val2 / 100;
|
||||
batk += sc->data[SC_ZANGETSU]->val2;
|
||||
if(sc->data[SC_EQC])
|
||||
batk -= batk * sc->data[SC_EQC]->val3 / 100;
|
||||
if(sc->data[SC_QUEST_BUFF1])
|
||||
@ -5543,7 +5546,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
if (sc->data[SC_TEARGAS])
|
||||
flee -= flee * 50 / 100;
|
||||
if( sc->data[SC_C_MARKER] )
|
||||
flee -= 10;
|
||||
flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100;
|
||||
if(sc->data[SC_HEAT_BARREL])
|
||||
flee -= sc->data[SC_HEAT_BARREL]->val4;
|
||||
|
||||
@ -9695,7 +9698,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
case SC_PAIN_KILLER: // Yommy leak need confirm
|
||||
val2 = 10 * val1; // aspd reduction %
|
||||
val3 = (( 200 * val1 ) * status_get_lv(src)) / 150; // dmg reduction linear
|
||||
val3 = min((( 200 * val1 ) * status_get_lv(src)) / 150, 1000); // dmg reduction linear. upto a maximum of 1000 [iRO Wiki]
|
||||
if(sc->data[SC_PARALYSIS])
|
||||
sc_start(src,bl, SC_ENDURE, 100, val1, tick); // Start endure for same duration
|
||||
break;
|
||||
@ -9775,8 +9778,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
case SC_C_MARKER:
|
||||
val2 = src->id;
|
||||
val3 = 10; //-10% flee
|
||||
//Start timer to send mark on mini map
|
||||
val3 = tick/1000;
|
||||
val4 = tick/1000;
|
||||
tick_time = 1000;
|
||||
break;
|
||||
case SC_H_MINE:
|
||||
@ -11256,8 +11260,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
if(!status_charge(bl, 0, sce->val4))
|
||||
break; // Not enough SP to continue.
|
||||
|
||||
if (!sc->data[SC_INCSTR]) {
|
||||
sc_start(bl,bl, SC_INCSTR,100,1<<(sce->val1-1),
|
||||
if (!sc->data[SC_CHASEWALK2]) {
|
||||
sc_start(bl,bl, SC_CHASEWALK2,100,1<<(sce->val1-1),
|
||||
(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) // SL bonus -> x10 duration
|
||||
*skill_get_time2(status_sc2skill(type),sce->val1));
|
||||
}
|
||||
@ -12039,7 +12043,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
}
|
||||
break;
|
||||
case SC_C_MARKER:
|
||||
if( --(sce->val3) >= 0 ) {
|
||||
if( --(sce->val4) >= 0 ) {
|
||||
TBL_PC *tsd = map_id2sd(sce->val2);
|
||||
if (!tsd || tsd->bl.m != bl->m) //End the SC if caster isn't in same map
|
||||
break;
|
||||
|
@ -701,6 +701,7 @@ typedef enum sc_type {
|
||||
SC__FEINTBOMB,
|
||||
SC__CHAOS,
|
||||
SC_ELEMENTAL_SHIELD,
|
||||
SC_CHASEWALK2,
|
||||
|
||||
#ifdef RENEWAL
|
||||
SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
|
||||
@ -893,7 +894,7 @@ enum si_type {
|
||||
// SI_DEFENCE = 179,
|
||||
// SI_SLOWDOWN = 180,
|
||||
SI_PRESERVE = 181,
|
||||
SI_INCSTR = 182,
|
||||
SI_CHASEWALK2 = 182,
|
||||
// SI_NOT_EXTREMITYFIST = 183,
|
||||
SI_INTRAVISION = 184,
|
||||
// SI_MOVESLOW_POTION = 185,
|
||||
|
@ -180,7 +180,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (item_data->bound > 1) && !pc_can_give_bounded_items(sd) ) {
|
||||
if( (item_data->bound > BOUND_ACCOUNT) && !pc_can_give_bounded_items(sd) ) {
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,294));
|
||||
return 1;
|
||||
}
|
||||
@ -519,7 +519,7 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (item_data->bound == 1 || item_data->bound > 2) && !pc_can_give_bounded_items(sd) ) {
|
||||
if( (item_data->bound == BOUND_ACCOUNT || item_data->bound > BOUND_GUILD) && !pc_can_give_bounded_items(sd) ) {
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,294));
|
||||
return 1;
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
|
||||
return;
|
||||
}
|
||||
|
||||
if( ((item->bound == 1 || item->bound > 2) || (item->bound == 2 && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound
|
||||
if( ((item->bound == BOUND_ACCOUNT || item->bound > BOUND_GUILD) || (item->bound == BOUND_GUILD && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound
|
||||
clif_displaymessage(sd->fd, msg_txt(sd,293));
|
||||
clif_tradeitemok(sd, index+2, 1);
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user