From 794c1a8247a73c0b05cbb88ecf34fa57c4da4b7b Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Sat, 31 May 2014 21:42:44 +0700 Subject: [PATCH] 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 --- db/const.txt | 8 +- db/import-tmpl/item_flag.txt | 1 + db/pre-re/item_flag.txt | 1 + db/pre-re/skill_require_db.txt | 24 +-- db/re/item_combo_db.txt | 4 +- db/re/item_flag.txt | 1 + db/re/skill_require_db.txt | 24 +-- doc/script_commands.txt | 12 +- src/char/int_mail.c | 2 +- src/char/int_storage.c | 2 +- src/common/mmo.h | 10 + src/config/core.h | 7 +- src/login/loginlog_sql.c | 2 +- src/map/atcommand.c | 55 +++--- src/map/battle.c | 112 ++++++----- src/map/clif.c | 4 +- src/map/elemental.c | 8 +- src/map/elemental.h | 2 +- src/map/guild.c | 2 +- src/map/itemdb.c | 82 +++------ src/map/itemdb.h | 8 +- src/map/map.c | 3 +- src/map/npc.c | 70 +++---- src/map/pc.c | 32 ++-- src/map/pc.h | 6 +- src/map/script.c | 66 ++++--- src/map/skill.c | 328 +++++++++++++++------------------ src/map/skill.h | 80 ++++---- src/map/status.c | 28 +-- src/map/status.h | 3 +- src/map/storage.c | 4 +- src/map/trade.c | 2 +- 32 files changed, 498 insertions(+), 495 deletions(-) diff --git a/db/const.txt b/db/const.txt index 05041eebfb..9275aa618c 100644 --- a/db/const.txt +++ b/db/const.txt @@ -1743,6 +1743,7 @@ SC__FEINTBOMB 594 SC__CHAOS 595 SC_ELEMENTAL_SHIELD 596 SC_EXTREMITYFIST2 597 +SC_CHASEWALK2 598 //Status Icon SI_BLANK -1 @@ -1926,7 +1927,7 @@ SI_MAXSPPERCENT 178 SI_DEFENCE 179 SI_SLOWDOWN 180 SI_PRESERVE 181 -SI_INCSTR 182 +SI_CHASEWALK2 182 SI_NOT_EXTREMITYFIST 183 SI_INTRAVISION 184 SI_MOVESLOW_POTION 185 @@ -4598,5 +4599,10 @@ IT_AMMO 10 IT_DELAYCONSUME 11 IT_CASH 18 +Bound_Account 1 +Bound_Guild 2 +Bound_Party 3 +Bound_Char 4 + false 0 true 1 diff --git a/db/import-tmpl/item_flag.txt b/db/import-tmpl/item_flag.txt index 1fa1297f13..0eeb2fe67c 100644 --- a/db/import-tmpl/item_flag.txt +++ b/db/import-tmpl/item_flag.txt @@ -4,3 +4,4 @@ // : // 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 diff --git a/db/pre-re/item_flag.txt b/db/pre-re/item_flag.txt index 4775330f31..7202764dc3 100644 --- a/db/pre-re/item_flag.txt +++ b/db/pre-re/item_flag.txt @@ -4,6 +4,7 @@ // : // 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 diff --git a/db/pre-re/skill_require_db.txt b/db/pre-re/skill_require_db.txt index fdf15e030d..d363fc7690 100644 --- a/db/pre-re/skill_require_db.txt +++ b/db/pre-re/skill_require_db.txt @@ -118,7 +118,7 @@ //**** // WZ Wizard -80,0,0,75,0,0,0,99,0,0,none,0,0,717,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_FIREPILLAR +80,0,0,75,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,717,1,717,1,717,1,717,1,717,1,0 //WZ_FIREPILLAR 81,0,0,35:37:39:41:43:45:47:49:51:53,0,0,0,99,0,0,none,SC_SIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_SIGHTRASHER 83,0,0,20:24:30:34:40:44:50:54:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_METEOR 84,0,0,20:23:26:29:32:35:38:41:44:47,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_JUPITEL @@ -678,25 +678,25 @@ //**** // NC Mechanic 2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_BOOSTKNUCKLE -2257,0,0,50,0,0,0,99,0,0,mado,0,0,1549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_PILEBUNKER +2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549 //NC_PILEBUNKER 2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_VULCANARM -2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_FLAMELAUNCHER +2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139 //NC_FLAMELAUNCHER 2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_COLDSLOWER 2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ARMSCANNON -2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ACCELERATION -2263,0,0,25,0,0,0,99,0,0,mado,0,0,2801,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_HOVERING +2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800 //NC_ACCELERATION +2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801 //NC_HOVERING 2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_F_SIDESLIDE 2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_B_SIDESLIDE -2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_SELFDESTRUCTION -2268,0,0,100,0,0,0,99,0,0,mado,0,0,2803,0,6360,1,6363,1,6362,1,6361,1,6146,2,0,0,0,0,0,0,0,0,0 //NC_SHAPESHIFT -2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_EMERGENCYCOOL +2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802 //NC_SELFDESTRUCTION +2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803 //NC_SHAPESHIFT +2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804 //NC_EMERGENCYCOOL 2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_INFRAREDSCAN 2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ANALYZE -2272,0,0,90,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_MAGNETICFIELD -2273,0,0,90,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_NEUTRALBARRIER -2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_STEALTHFIELD -2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,2807,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_REPAIR +2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805 //NC_MAGNETICFIELD +2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806 //NC_NEUTRALBARRIER +2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808 //NC_STEALTHFIELD +2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807 //NC_REPAIR 2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_AXEBOOMERANG 2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_POWERSWING diff --git a/db/re/item_combo_db.txt b/db/re/item_combo_db.txt index 022f90bd3f..fd5e7ad497 100644 --- a/db/re/item_combo_db.txt +++ b/db/re/item_combo_db.txt @@ -248,7 +248,7 @@ 15068:20710,{ bonus bAgi,5; bonus bFlee,10; } 15088:18816:18818,{ bonus bMatk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; } 15088:18817:18819,{ bonus bBaseAtk,BaseLevel/3; bonus2 bExpAddClass,Class_All,5; } -15116:20743:22046,{ bonus bMaxSPrate,25; bonus bMaxSPrate,25; bonus bSpeedAddRate,n; } +15116:20743:22046,{ bonus bMaxSPrate,25; bonus bMaxSPrate,25; bonus bSpeedAddRate,10; } 18507:18539,{ bonus bUseSPrate,-3; } 18538:5041,{ bonus2 bSubRace,RC_Angel,9; } 18538:5048,{ bonus2 bSubRace,RC_Demon,9; } @@ -260,6 +260,7 @@ 18656:5475,{ bonus bBaseAtk,30; bonus bMatk,30; bonus2 bAddMonsterDropItem,529,400; bonus2 bAddMonsterDropItem,530,400; bonus2 bAddMonsterDropItem,538,400; bonus2 bAddMonsterDropItem,12192,400;} 18776:20710,{ bonus bBaseAtk,10; } 18776:22015,{ bonus bMatk,20; } +18997:28326:28327,{ bonus bSpeed,25; bonus bBaseAtk,50; bonus bMatk,50; } 24012:24013:24014:24015:24016:24017,{ bonus bAllStats,9; } 24018:24019:24020,{ if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) + getequiprefinerycnt(EQI_SHADOW_WEAPON) >= 23) { bonus bAtkRate,1; } } 24021:24022:24023,{ if(getequiprefinerycnt(EQI_SHADOW_ACC_R) + getequiprefinerycnt(EQI_SHADOW_ACC_L) + getequiprefinerycnt(EQI_SHADOW_WEAPON) >= 23) { bonus bMatkRate,1; } } @@ -303,5 +304,4 @@ 24150:24151,{ bonus bAtkRate,1; if (getequiprefinerycnt(EQI_SHADOW_ACC_R)+getequiprefinerycnt(EQI_SHADOW_ACC_L) >= 15) bonus bNoSizeFix,1; } 24152:24153,{ bonus bAtk,getequiprefinerycnt(EQI_SHADOW_WEAPON); if (getequiprefinerycnt(EQI_SHADOW_WEAPON)+getequiprefinerycnt(EQI_SHADOW_ACC_R) >= 15) bonus bUnbreakableWeapon,1; } 24154:24155,{ bonus bDef,getequiprefinerycnt(EQI_SHADOW_ARMOR); if (getequiprefinerycnt(EQI_SHADOW_ARMOR)+getequiprefinerycnt(EQI_SHADOW_ACC_L) >= 15) bonus bUnbreakableArmor,1; } -18997:28326:28327,{ bonus bSpeed,25; bonus bBaseAtk,50; bonus bMatk,50; } 28326:28327,{ bonus bInt,8; bonus bStr,8; } diff --git a/db/re/item_flag.txt b/db/re/item_flag.txt index 92a9abb59e..bce767a2ff 100644 --- a/db/re/item_flag.txt +++ b/db/re/item_flag.txt @@ -4,6 +4,7 @@ // : // 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 diff --git a/db/re/skill_require_db.txt b/db/re/skill_require_db.txt index 20a3634fb4..65487bdcc9 100644 --- a/db/re/skill_require_db.txt +++ b/db/re/skill_require_db.txt @@ -118,7 +118,7 @@ //**** // WZ Wizard -80,0,0,75,0,0,0,99,0,0,none,0,0,717,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_FIREPILLAR +80,0,0,75,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,717,1,717,1,717,1,717,1,717,1,0 //WZ_FIREPILLAR 81,0,0,35:37:39:41:43:45:47:49:51:53,0,0,0,99,0,0,none,SC_SIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_SIGHTRASHER 83,0,0,20:24:30:34:40:44:50:54:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_METEOR 84,0,0,20:23:26:29:32:35:38:41:44:47,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WZ_JUPITEL @@ -678,25 +678,25 @@ //**** // NC Mechanic 2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_BOOSTKNUCKLE -2257,0,0,50,0,0,0,99,0,0,mado,0,0,1549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_PILEBUNKER +2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549 //NC_PILEBUNKER 2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_VULCANARM -2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_FLAMELAUNCHER +2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139 //NC_FLAMELAUNCHER 2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_COLDSLOWER 2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ARMSCANNON -2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ACCELERATION -2263,0,0,25,0,0,0,99,0,0,mado,0,0,2801,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_HOVERING +2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800 //NC_ACCELERATION +2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801 //NC_HOVERING 2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_F_SIDESLIDE 2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_B_SIDESLIDE -2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_SELFDESTRUCTION -2268,0,0,100,0,0,0,99,0,0,mado,0,0,2803,0,6360,1,6363,1,6362,1,6361,1,6146,2,0,0,0,0,0,0,0,0,0 //NC_SHAPESHIFT -2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_EMERGENCYCOOL +2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802 //NC_SELFDESTRUCTION +2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803 //NC_SHAPESHIFT +2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804 //NC_EMERGENCYCOOL 2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_INFRAREDSCAN 2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_ANALYZE -2272,0,0,90,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_MAGNETICFIELD -2273,0,0,90,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_NEUTRALBARRIER -2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_STEALTHFIELD -2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,2807,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_REPAIR +2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805 //NC_MAGNETICFIELD +2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806 //NC_NEUTRALBARRIER +2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808 //NC_STEALTHFIELD +2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807 //NC_REPAIR 2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_AXEBOOMERANG 2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //NC_POWERSWING diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 65e69d7109..5f93a4fbb5 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -4353,10 +4353,10 @@ in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in some cases cannot be traded or stored. Valid bound types are: - 1 - Account Bound - 2 - Guild Bound - 3 - Party Bound - 4 - Character Bound + Bound_Account : Account Bound item + Bound_Guild : Guild Bound item + Bound_Party : Party Bound item + Bound_Char : Character Bound item --------------------------------------- @@ -4506,8 +4506,8 @@ See 'getitem2' for an explanation of the expanded parameters. *cartdelitem2 ,,,,,,,,{,}; *cartdelitem2 "",,,,,,,,{,}; -*storageitem2 ,,,,,,,,{,}; -*storageitem2 "",,,,,,,,{,}; +*storagedelitem2 ,,,,,,,,{,}; +*storagedelitem2 "",,,,,,,,{,}; Same like delitem2, but deletes item from cart or storage. If cart is not mounted, it will be failed. diff --git a/src/char/int_mail.c b/src/char/int_mail.c index 28f46c4b82..e4d097c2e5 100644 --- a/src/char/int_mail.c +++ b/src/char/int_mail.c @@ -184,7 +184,7 @@ static bool mail_loadmessage(int mail_id, struct mail_message* msg) Sql_GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data); Sql_GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10); msg->item.expire_time = 0; - msg->item.bound = 0; + msg->item.bound = BOUND_NONE; for( j = 0; j < MAX_SLOTS; j++ ) { diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 86dd6cef1b..5925d10300 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -289,7 +289,7 @@ int mapif_parse_itembound_retrieve(int fd) SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) { - if(item.bound == 2) { + if(item.bound == BOUND_GUILD) { memcpy(&items[i],&item,sizeof(struct item)); i++; } diff --git a/src/common/mmo.h b/src/common/mmo.h index 026aa21169..fd7d3402fd 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -785,6 +785,16 @@ enum { SEX_SERVER }; +/// Item Bound Type +enum bound_type { + BOUND_NONE = 0, /// No bound + BOUND_ACCOUNT, /// 1- Account Bound + BOUND_GUILD, /// 2 - Guild Bound + BOUND_PARTY, /// 3 - Party Bound + BOUND_CHAR, /// 4 - Character Bound + BOUND_MAX +}; + // sanity checks... #if MAX_ZENY > INT_MAX #error MAX_ZENY is too big diff --git a/src/config/core.h b/src/config/core.h index 798f4a2612..0d764231e1 100644 --- a/src/config/core.h +++ b/src/config/core.h @@ -62,12 +62,7 @@ /// Uncomment to enable skills damage adjustments /// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the /// damage rate of specified skills. -//#define ADJUST_SKILL_DAMAGE - -/// The skill damage adjustment rate is capped at 100000. -#ifdef ADJUST_SKILL_DAMAGE -#define MAX_SKILL_DAMAGE_RATE 100000 -#endif +#define ADJUST_SKILL_DAMAGE /// Uncomment to enable the job base HP/SP table (job_basehpsp_db.txt) //#define HP_SP_TABLES diff --git a/src/login/loginlog_sql.c b/src/login/loginlog_sql.c index d61172697b..90c585df49 100644 --- a/src/login/loginlog_sql.c +++ b/src/login/loginlog_sql.c @@ -13,7 +13,7 @@ static char global_db_hostname[32] = "127.0.0.1"; static uint16 global_db_port = 3306; static char global_db_username[32] = "ragnarok"; -static char global_db_password[32] = "ragnarok"; +static char global_db_password[32] = ""; static char global_db_database[32] = "ragnarok"; static char global_codepage[32] = ""; // local sql settings diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 5bcab04d87..510e7651a8 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1198,7 +1198,7 @@ ACMD_FUNC(heal) ACMD_FUNC(item) { char item_name[100]; - int number = 0, flag = 0, bound = 0; + int number = 0, flag = 0, bound = BOUND_NONE; struct item item_tmp; struct item_data *item_data[10]; int get_count, i, j=0; @@ -1207,12 +1207,19 @@ ACMD_FUNC(item) nullpo_retr(-1, sd); memset(item_name, '\0', sizeof(item_name)); - if (!strcmpi(command+1,"itembound") && (!message || !*message || ( - sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 2 && - sscanf(message, "%99s %d %d", item_name, &number, &bound) < 2 - ))) { - clif_displaymessage(fd, msg_txt(sd,295)); // Please enter an item name or ID (usage: @item ). - 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 ). + 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 - clif_displaymessage(fd, msg_txt(sd,297)); // ). - 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 + clif_displaymessage(fd, msg_txt(sd,297)); // ). + 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 diff --git a/src/map/battle.c b/src/map/battle.c index 91a2806297..c8611b6719 100644 --- a/src/map/battle.c +++ b/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; diff --git a/src/map/clif.c b/src/map/clif.c index 82b261e619..30376e579e 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2261,7 +2261,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) WFIFOL(fd,offs+23)=sd->status.inventory[n].expire_time; #endif #if PACKETVER >= 20071002 - WFIFOW(fd,offs+27)=sd->status.inventory[n].bound ? 2 : 0; + WFIFOW(fd,offs+27)=sd->status.inventory[n].bound ? BOUND_GUILD : 0; #endif } @@ -2367,7 +2367,7 @@ void clif_item_sub(unsigned char *buf, int n, int idx, struct item *i, struct it clif_addcards(WBUFP(buf, n+12), i); //8B #if PACKETVER >= 20071002 WBUFL(buf,n+20)=i->expire_time; - WBUFW(buf,n+24)=i->bound ? 2 : 0; + WBUFW(buf,n+24)=i->bound ? BOUND_GUILD : 0; #endif #if PACKETVER >= 20100629 WBUFW(buf,n+26)= (id->equip&EQP_VISIBLE)?id->look:0; diff --git a/src/map/elemental.c b/src/map/elemental.c index 7a73f8eda9..5c75d1204a 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -561,19 +561,19 @@ int elemental_unlocktarget(struct elemental_data *ed) { return 0; } -int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) { - int idx = skill_get_index(skill_id); +bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) { + uint16 idx = skill_get_index(skill_id); nullpo_retr(1,ed); if (idx == 0) - return 1; // invalid skill id + return false; // invalid skill id return skill_isNotOk(skill_id,ed->master); } struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){ struct skill_condition req; - int idx = skill_get_index(skill_id); + uint16 idx = skill_get_index(skill_id); memset(&req,0,sizeof(req)); diff --git a/src/map/elemental.h b/src/map/elemental.h index a676768c6b..521525e8f6 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -92,7 +92,7 @@ void elemental_summon_stop(struct elemental_data *ed); int elemental_get_lifetime(struct elemental_data *ed); int elemental_unlocktarget(struct elemental_data *ed); -int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed); +bool elemental_skillnotok(uint16 skill_id, struct elemental_data *ed); int elemental_set_target( struct map_session_data *sd, struct block_list *bl ); int elemental_clean_single_effect(struct elemental_data *ed, uint16 skill_id); int elemental_clean_effect(struct elemental_data *ed); diff --git a/src/map/guild.c b/src/map/guild.c index a8b8e7c849..b521e3601a 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1807,7 +1807,7 @@ int guild_break(struct map_session_data *sd,char *name) { //Guild bound item check - Removes the bound flag j = pc_bound_chk(sd,2,idxlist); for(i=0;istatus.inventory[idxlist[i]].bound = 0; + sd->status.inventory[idxlist[i]].bound = BOUND_NONE; #endif intif_guild_break(g->guild_id); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 2eff7a647e..28e5a16b3b 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -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 * , -* &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]); } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 41838f27a5..8ecb922a03 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -475,11 +475,11 @@ bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(str #define itemdb_canmail(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canmail_sub) #define itemdb_canauction(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canauction_sub) -bool itemdb_isequip(int); -bool itemdb_isequip2(struct item_data *); +bool itemdb_isequip2(struct item_data *id); +#define itemdb_isequip(nameid) itemdb_isequip2(itemdb_search(nameid)) char itemdb_isidentified(int); -bool itemdb_isstackable(uint16 nameid); -bool itemdb_isstackable2(struct item_data *data); +bool itemdb_isstackable2(struct item_data *id); +#define itemdb_isstackable(nameid) itemdb_isstackable2(itemdb_search(nameid)) uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID bool itemdb_isNoEquip(struct item_data *id, uint16 m); diff --git a/src/map/map.c b/src/map/map.c index b3d436fd74..74bc54ca6e 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -65,7 +65,7 @@ char default_codepage[32] = ""; int map_server_port = 3306; char map_server_ip[32] = "127.0.0.1"; char map_server_id[32] = "ragnarok"; -char map_server_pw[32] = "ragnarok"; +char map_server_pw[32] = ""; char map_server_db[32] = "ragnarok"; Sql* mmysql_handle; @@ -1677,6 +1677,7 @@ int map_quit(struct map_session_data *sd) { status_change_end(&sd->bl, SC_GLORYWOUNDS, INVALID_TIMER); status_change_end(&sd->bl, SC_SOULCOLD, INVALID_TIMER); status_change_end(&sd->bl, SC_HAWKEYES, INVALID_TIMER); + status_change_end(&sd->bl, SC_CHASEWALK2, INVALID_TIMER); if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4) status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure. status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER); diff --git a/src/map/npc.c b/src/map/npc.c index 55742ce7d7..20dc8bf04b 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -124,9 +124,9 @@ int npc_isnear_sub(struct block_list* bl, va_list args) { int skill_id = va_arg(args, int); if (skill_id > 0) { //If skill_id > 0 that means is used for INF2_NO_NEARNPC [Cydh] - int16 idx = skill_get_index(skill_id); + uint16 idx = skill_get_index(skill_id); - if (idx >= 0 && skill_db[idx].unit_nonearnpc_type) { + if (idx > 0 && skill_db[idx].unit_nonearnpc_type) { while (1) { if (skill_db[idx].unit_nonearnpc_type&1 && nd->subtype == WARP) break; if (skill_db[idx].unit_nonearnpc_type&2 && nd->subtype == SHOP) break; @@ -3723,40 +3723,46 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con map[m].flag.notomb = state; else if (!strcmpi(w3,"skill_damage")) { #ifdef ADJUST_SKILL_DAMAGE - char skill[NAME_LENGTH]; + char skill[SKILL_NAME_LENGTH]; int pc = 0, mob = 0, boss = 0, other = 0, caster = 0; - memset(skill,0,sizeof(skill)); - map[m].flag.skill_damage = state; //set the mapflag + 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; + } } } } diff --git a/src/map/pc.c b/src/map/pc.c index f6994f2998..cf0dfa30fa 100755 --- a/src/map/pc.c +++ b/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;iskillcooldown); +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(iskillcooldown[i].id == skill_id); + if (i < cooldownlen) { cooldown += sd->skillcooldown[i].val; cooldown = max(0,cooldown); } diff --git a/src/map/pc.h b/src/map/pc.h index 8b509810b6..740731c0fd 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -827,7 +827,7 @@ int pc_isequip(struct map_session_data *sd,int n); int pc_equippoint(struct map_session_data *sd,int n); int pc_setinventorydata(struct map_session_data *sd); -int pc_get_skillcooldown(struct map_session_data *sd, int id, int lv); +int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); int pc_checkskill(struct map_session_data *sd,uint16 skill_id); short pc_checkequip(struct map_session_data *sd,int pos); bool pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max); @@ -851,14 +851,14 @@ int pc_memo(struct map_session_data* sd, int pos); int pc_checkadditem(struct map_session_data*,int,int); int pc_inventoryblank(struct map_session_data*); -int pc_search_inventory(struct map_session_data *sd,int item_id); +short pc_search_inventory(struct map_session_data *sd, uint16 nameid); int pc_payzeny(struct map_session_data*,int, enum e_log_pick_type type, struct map_session_data*); char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type); int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_session_data*); int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type); //Bound items -int pc_bound_chk(TBL_PC *sd,int type,int *idxlist); +int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist); // Special Shop System int pc_paycash( struct map_session_data *sd, int price, int points, e_log_pick_type type ); diff --git a/src/map/script.c b/src/map/script.c index 10e2431828..be11a6ab60 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -2289,6 +2289,7 @@ void script_hardcoded_constants(void) { script_set_constant("Option_Invisible",OPTION_INVISIBLE,false); script_set_constant("Option_Orcish",OPTION_ORCISH,false); script_set_constant("Option_Wedding",OPTION_WEDDING,false); + script_set_constant("Option_Ruwach",OPTION_RUWACH,false); script_set_constant("Option_Chasewalk",OPTION_CHASEWALK,false); script_set_constant("Option_Flying",OPTION_FLYING,false); script_set_constant("Option_Xmas",OPTION_XMAS,false); @@ -6455,22 +6456,24 @@ BUILDIN_FUNC(getitem) if( !strcmp(script_getfuncname(st),"getitembound") ) { char bound = script_getnum(st,4); - if( bound < 1 || bound > 4) { //Not a correct bound type - 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)); // 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)); // 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 {}; - * @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;istatus.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; diff --git a/src/map/skill.c b/src/map/skill.c index c828761e12..ce9afb3bfa 100755 --- a/src/map/skill.c +++ b/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 diff --git a/src/map/skill.h b/src/map/skill.h index 63c0a8c21e..9d41e24b39 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -22,6 +22,8 @@ struct status_change_entry; #define MAX_SKILL_IMPROVISE_DB 50 #define MAX_SKILL_LEVEL 100 #define MAX_SKILL_CRIMSON_MARKER 3 +#define SKILL_NAME_LENGTH 31 +#define SKILL_DESC_LENGTH 31 DBMap* skilldb_name2id; @@ -104,51 +106,53 @@ enum e_skill_display { SD_PREAMBLE = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected }; -#define MAX_SKILL_ITEM_REQUIRE 10 -#define MAX_SKILL_STATUS_REQUIRE 3 -#define MAX_SKILL_EQUIP_REQUIRE 10 +#define MAX_SKILL_ITEM_REQUIRE 10 /// Maximum required items +#define MAX_SKILL_STATUS_REQUIRE 3 /// Maximum required statuses +#define MAX_SKILL_EQUIP_REQUIRE 10 /// Maximum required equipped item struct skill_condition { - int hp, - mhp, - sp, - hp_rate, - sp_rate, - ammo, - ammo_qty, - weapon, - zeny, - state, - spiritball, - itemid[MAX_SKILL_ITEM_REQUIRE], - amount[MAX_SKILL_ITEM_REQUIRE]; - short *eqItem; - enum sc_type *status; - uint8 status_count, eqItem_count; + int hp, /// HP cost + mhp, /// Max HP to trigger + sp, /// SP cost + hp_rate, /// HP cost (%) + sp_rate, /// SP cost (%) + ammo, /// Ammo type + ammo_qty, /// Amount of ammo + weapon, /// Weapon type + zeny, /// Zeny cost + state, /// State/condition + spiritball, /// Spiritball cost + itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item + amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item + uint16 *eqItem; /// List of equipped item + enum sc_type *status; /// List of Status required (SC) + uint8 status_count, /// Count of SC + eqItem_count; /// Count of equipped item }; struct s_skill_require { - int hp[MAX_SKILL_LEVEL], - mhp[MAX_SKILL_LEVEL], - sp[MAX_SKILL_LEVEL], - hp_rate[MAX_SKILL_LEVEL], - sp_rate[MAX_SKILL_LEVEL], - zeny[MAX_SKILL_LEVEL], - weapon, - ammo, - ammo_qty[MAX_SKILL_LEVEL], - state, - spiritball[MAX_SKILL_LEVEL], - itemid[MAX_SKILL_ITEM_REQUIRE], - amount[MAX_SKILL_ITEM_REQUIRE]; - short *eqItem; - enum sc_type *status; - uint8 status_count, eqItem_count; + int hp[MAX_SKILL_LEVEL], /// HP cost + mhp[MAX_SKILL_LEVEL], /// Max HP to trigger + sp[MAX_SKILL_LEVEL], /// SP cost + hp_rate[MAX_SKILL_LEVEL], /// HP cost (%) + sp_rate[MAX_SKILL_LEVEL], /// SP cost (%) + zeny[MAX_SKILL_LEVEL], /// Zeny cost + weapon, /// Weapon type + ammo, /// Ammo type + ammo_qty[MAX_SKILL_LEVEL], /// Amount of ammo + state, /// State/condition + spiritball[MAX_SKILL_LEVEL], /// Spiritball cost + itemid[MAX_SKILL_ITEM_REQUIRE], /// Required item + amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item + uint16 *eqItem; /// List of equipped item + enum sc_type *status; /// List of Status required (SC) + uint8 status_count, /// Count of SC + eqItem_count; /// Count of equipped item }; /// Database skills struct s_skill_db { - char name[NAME_LENGTH]; - char desc[40]; + char name[SKILL_NAME_LENGTH]; + char desc[SKILL_DESC_LENGTH]; int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max; int num[MAX_SKILL_LEVEL]; int cast[MAX_SKILL_LEVEL],walkdelay[MAX_SKILL_LEVEL],delay[MAX_SKILL_LEVEL]; @@ -261,7 +265,7 @@ enum { UF_ENSEMBLE = 0x0200, // Duet UF_SONG = 0x0400, // Song UF_DUALMODE = 0x0800, // Spells should trigger both ontimer and onplace/onout/onleft effects. - UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center + UF_RANGEDSINGLEUNIT = 0x2000 // hack for ranged layout, only display center }; /// Create Database item diff --git a/src/map/status.c b/src/map/status.c index d2aaf903ce..d0b493b039 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -821,11 +821,11 @@ void initChangeTables(void) add_sc( RL_HAMMER_OF_GOD , SC_STUN ); set_sc( RL_B_TRAP , SC_B_TRAP , SI_B_TRAP , SCB_SPEED ); set_sc( RL_E_CHAIN , SC_E_CHAIN , SI_E_CHAIN , SCB_NONE ); - set_sc( RL_P_ALTER , SC_P_ALTER , SI_P_ALTER , SCB_BATK ); + set_sc( RL_P_ALTER , SC_P_ALTER , SI_P_ALTER , SCB_NONE ); set_sc( RL_SLUGSHOT , SC_STUN , SI_SLUGSHOT , SCB_NONE ); - set_sc( RL_HEAT_BARREL , SC_HEAT_BARREL , SI_HEAT_BARREL , SCB_BATK|SCB_ASPD|SCB_HIT ); - set_sc_with_vfx( RL_C_MARKER , SC_C_MARKER , SI_C_MARKER , SCB_SPEED ); - set_sc_with_vfx( RL_AM_BLAST , SC_ANTI_M_BLAST , SI_ANTI_M_BLAST , SCB_DEF_ELE ); + set_sc( RL_HEAT_BARREL , SC_HEAT_BARREL , SI_HEAT_BARREL , SCB_FLEE|SCB_ASPD ); + set_sc_with_vfx( RL_C_MARKER , SC_C_MARKER , SI_C_MARKER , SCB_FLEE ); + set_sc_with_vfx( RL_AM_BLAST , SC_ANTI_M_BLAST , SI_ANTI_M_BLAST , SCB_NONE ); set_sc_with_vfx( SC_ALL_RIDING , SC_ALL_RIDING , SI_ALL_RIDING , SCB_SPEED ); @@ -855,7 +855,7 @@ void initChangeTables(void) StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY; StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE; StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1; - StatusIconChangeTable[SC_INCSTR] = SI_INCSTR; + StatusIconChangeTable[SC_CHASEWALK2] = SI_CHASEWALK2; StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT; StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION; StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR; @@ -1055,6 +1055,7 @@ void initChangeTables(void) StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL; StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED; + StatusChangeFlagTable[SC_CHASEWALK2] |= SCB_STR; /* Cash Items */ StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR; @@ -4749,6 +4750,8 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang return 50; if(sc->data[SC_INCALLSTATUS]) str += sc->data[SC_INCALLSTATUS]->val1; + if(sc->data[SC_CHASEWALK2]) + str += sc->data[SC_CHASEWALK2]->val1; if(sc->data[SC_INCSTR]) str += sc->data[SC_INCSTR]->val1; if(sc->data[SC_STRFOOD]) @@ -5174,7 +5177,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan if(sc->data[SC__ENERVATION]) batk -= batk * sc->data[SC__ENERVATION]->val2 / 100; if( sc->data[SC_ZANGETSU] ) - batk += batk * sc->data[SC_ZANGETSU]->val2 / 100; + batk += sc->data[SC_ZANGETSU]->val2; if(sc->data[SC_EQC]) batk -= batk * sc->data[SC_EQC]->val3 / 100; if(sc->data[SC_QUEST_BUFF1]) @@ -5543,7 +5546,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change if (sc->data[SC_TEARGAS]) flee -= flee * 50 / 100; if( sc->data[SC_C_MARKER] ) - flee -= 10; + flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100; if(sc->data[SC_HEAT_BARREL]) flee -= sc->data[SC_HEAT_BARREL]->val4; @@ -9695,7 +9698,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; case SC_PAIN_KILLER: // Yommy leak need confirm val2 = 10 * val1; // aspd reduction % - val3 = (( 200 * val1 ) * status_get_lv(src)) / 150; // dmg reduction linear + val3 = min((( 200 * val1 ) * status_get_lv(src)) / 150, 1000); // dmg reduction linear. upto a maximum of 1000 [iRO Wiki] if(sc->data[SC_PARALYSIS]) sc_start(src,bl, SC_ENDURE, 100, val1, tick); // Start endure for same duration break; @@ -9775,8 +9778,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; case SC_C_MARKER: val2 = src->id; + val3 = 10; //-10% flee //Start timer to send mark on mini map - val3 = tick/1000; + val4 = tick/1000; tick_time = 1000; break; case SC_H_MINE: @@ -11256,8 +11260,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if(!status_charge(bl, 0, sce->val4)) break; // Not enough SP to continue. - if (!sc->data[SC_INCSTR]) { - sc_start(bl,bl, SC_INCSTR,100,1<<(sce->val1-1), + if (!sc->data[SC_CHASEWALK2]) { + sc_start(bl,bl, SC_CHASEWALK2,100,1<<(sce->val1-1), (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) // SL bonus -> x10 duration *skill_get_time2(status_sc2skill(type),sce->val1)); } @@ -12039,7 +12043,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) } break; case SC_C_MARKER: - if( --(sce->val3) >= 0 ) { + if( --(sce->val4) >= 0 ) { TBL_PC *tsd = map_id2sd(sce->val2); if (!tsd || tsd->bl.m != bl->m) //End the SC if caster isn't in same map break; diff --git a/src/map/status.h b/src/map/status.h index fa52c689e9..5da7559457 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -701,6 +701,7 @@ typedef enum sc_type { SC__FEINTBOMB, SC__CHAOS, SC_ELEMENTAL_SHIELD, + SC_CHASEWALK2, #ifdef RENEWAL SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled @@ -893,7 +894,7 @@ enum si_type { // SI_DEFENCE = 179, // SI_SLOWDOWN = 180, SI_PRESERVE = 181, - SI_INCSTR = 182, + SI_CHASEWALK2 = 182, // SI_NOT_EXTREMITYFIST = 183, SI_INTRAVISION = 184, // SI_MOVESLOW_POTION = 185, diff --git a/src/map/storage.c b/src/map/storage.c index 58c876b0d8..8a3bc364f2 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -180,7 +180,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data, return 1; } - if( (item_data->bound > 1) && !pc_can_give_bounded_items(sd) ) { + if( (item_data->bound > BOUND_ACCOUNT) && !pc_can_give_bounded_items(sd) ) { clif_displaymessage(sd->fd, msg_txt(sd,294)); return 1; } @@ -519,7 +519,7 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto return 1; } - if( (item_data->bound == 1 || item_data->bound > 2) && !pc_can_give_bounded_items(sd) ) { + if( (item_data->bound == BOUND_ACCOUNT || item_data->bound > BOUND_GUILD) && !pc_can_give_bounded_items(sd) ) { clif_displaymessage(sd->fd, msg_txt(sd,294)); return 1; } diff --git a/src/map/trade.c b/src/map/trade.c index 12cba927d4..4d08c584c3 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -379,7 +379,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) return; } - if( ((item->bound == 1 || item->bound > 2) || (item->bound == 2 && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound + if( ((item->bound == BOUND_ACCOUNT || item->bound > BOUND_GUILD) || (item->bound == BOUND_GUILD && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound clif_displaymessage(sd->fd, msg_txt(sd,293)); clif_tradeitemok(sd, index+2, 1); return;