From c046668034d74843b0ae9518d24b97856732f1e0 Mon Sep 17 00:00:00 2001 From: aleos89 Date: Thu, 24 Apr 2014 12:05:22 -0400 Subject: [PATCH] Bug Fixes * Updated Earth Strain's equipment divest chance to include Base Level and DEX. (bugreport:8922) * Updated some skill usages on certain maps. (bugreport:8923) - Masquerade - Ignorance is no longer usable in instances. - Dimension Door, Chaos Panic, Bloody Lust, and Sling Item are no longer usabled in towns. * Updated Earth Drive and Shield Press damage formulas. * Fixed Raigekisai dealing damage too quickly which was causing double damage. (bugreport:8926) * Electric Shocker, Reverberation, and Poem of Netherworld cannot be knocked back. * Updated the effect of Poem of Netherworld, Reverberation, Electric Shocker, and Wall of Thorn to official. * Updated the skill unit layouts for Man Hole, Dimension Door, Chaos Panic, Maelstrom, and Bloody Lust. * Zephyr will no longer affect Elementals. * Dragon Breath and Self Destruction will no longer consider VVS and masteries. * Updated Vellum Weapons item script to official. * Masquerades cannot be casted on MVPs. * Unequipping Hovering Booster will remove Hover. * Fixed a typo in the map_msg. * Updated the monster mode documentation. --- conf/msg_conf/map_msg.conf | 2 +- db/pre-re/skill_db.txt | 12 +-- db/pre-re/skill_nocast_db.txt | 6 ++ db/pre-re/skill_unit_db.txt | 18 ++--- db/re/skill_db.txt | 12 +-- db/re/skill_nocast_db.txt | 6 ++ db/re/skill_unit_db.txt | 20 ++--- doc/mob_db_mode_list.txt | 50 +++++++++---- src/map/battle.c | 62 +++++++++------- src/map/pc.c | 2 + src/map/skill.c | 134 ++++++++++++++++++++++------------ src/map/skill.h | 2 +- src/map/status.c | 51 ++++++++----- src/map/status.h | 42 +++++------ 14 files changed, 258 insertions(+), 161 deletions(-) diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index 05814bc4fd..3e73a4cddd 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -746,7 +746,7 @@ 730: Character cannot be disguised while in monster form. 731: Transforming into monster is not allowed in Guild Wars. -732: Item cannot be openned when your inventory is full. +732: Item cannot be opened when your inventory is full. //733-899 free diff --git a/db/pre-re/skill_db.txt b/db/pre-re/skill_db.txt index d66fb4a4eb..4dc182a848 100644 --- a/db/pre-re/skill_db.txt +++ b/db/pre-re/skill_db.txt @@ -1055,12 +1055,12 @@ 2295,3,6,1,0,0x1,0,3,1,yes,0,0,0,none,0,0x20, SC_LAZINESS,Masquerade - Laziness 2296,3,6,1,0,0x1,0,3,1,yes,0,0,0,none,0,0x20, SC_UNLUCKY,Masquerade - Unlucky 2297,3,6,1,0,0x1,0,3,1,yes,0,0,0,none,0,0x20, SC_WEAKNESS,Masquerade - Weakness -2298,3,6,1,0,0x1,0,5,1,yes,0,0,0,weapon,0,0x8020, SC_STRIPACCESSARY,Strip Accessory //CHECK Is weapon attack type needed? -2299,7,6,2,0,0x1,0,3,1,yes,0,0,3,none,0,0x0, SC_MANHOLE,Man Hole -2300,7,6,2,0,0x1,0,3,1,yes,0,0,1,none,0,0x0, SC_DIMENSIONDOOR,Dimension Door -2301,7,6,2,0,0x1,0,3,1,yes,0,0x20000,0,none,0,0x0, SC_CHAOSPANIC,Chaos Panic -2302,7,6,2,0,0x1,0,3,1,yes,0,0x20000,1,none,0,0x0, SC_MAELSTROM,Maelstrom -2303,7,6,2,0,0x1,3,3,1,yes,0,0,1,none,0,0x0, SC_BLOODYLUST,Bloody Lust +2298,3,6,1,0,0x1,0,5,1,yes,0,0,0,none,0,0x8020, SC_STRIPACCESSARY,Strip Accessory +2299,7,6,2,0,0x1,0,3,1,yes,0,0,3,magic,0,0x0, SC_MANHOLE,Man Hole +2300,7,6,2,0,0x1,0,3,1,yes,0,0,1,magic,0,0x0, SC_DIMENSIONDOOR,Dimension Door +2301,7,6,2,0,0x1,0,3,1,yes,0,0x20000,0,magic,0,0x0, SC_CHAOSPANIC,Chaos Panic +2302,7,6,2,0,0x1,0,3,1,yes,0,0x20000,1,magic,0,0x0, SC_MAELSTROM,Maelstrom +2303,7,6,2,0,0x1,0,3,1,yes,0,0,0,magic,0,0x0, SC_BLOODYLUST,Bloody Lust 2304,0,6,4,-1,0,0,3,1,no,0,0,0,weapon,0,0x0, SC_FEINTBOMB,Feint Bomb //**** diff --git a/db/pre-re/skill_nocast_db.txt b/db/pre-re/skill_nocast_db.txt index b151ee5379..01973ec554 100644 --- a/db/pre-re/skill_nocast_db.txt +++ b/db/pre-re/skill_nocast_db.txt @@ -156,6 +156,7 @@ 361,512 //HP_ASSUMPTIO 691,512 //CASH_ASSUMPTIO 2284,512 //SC_FATALMENACE +2294,512 //SC_IGNORANCE 2300,512 //SC_DIMENSIONDOOR //---------------------------------------------------------------------------- @@ -167,6 +168,7 @@ 405,1024 //PF_SPIDERWEB 674,1024 //NPC_EXPULSION 2284,1024 //SC_FATALMENACE +2294,1024 //SC_IGNORANCE 2300,1024 //SC_DIMENSIONDOOR //---------------------------------------------------------------------------- @@ -177,5 +179,9 @@ 491,2048 //CR_CULTIVATION 1013,2048 //BS_GREED 2299,2048 //SC_MANHOLE +2300,2048 //SC_DIMENSIONDOOR +2301,2048 //SC_CHAOSPANIC +2303,2048 //SC_BLOODYLUST 2419,2048 //WM_POEMOFNETHERWORLD 2482,2048 //GN_WALLOFTHORN +2493,2048 //GN_SLINGITEM diff --git a/db/pre-re/skill_unit_db.txt b/db/pre-re/skill_unit_db.txt index 0e09ecbdba..14e19ef2ce 100644 --- a/db/pre-re/skill_unit_db.txt +++ b/db/pre-re/skill_unit_db.txt @@ -121,18 +121,18 @@ 2273,0xe2, , 2, 0, 500,all, 0x000 //NC_NEUTRALBARRIER 2274,0xe3, , 2, 0, 500,friend,0x000 //NC_STEALTHFIELD -2299,0xcc, , 0, 1,1000,all, 0x006 //SC_MANHOLE -2300,0xcd, , 0, 1,1000,all, 0x006 //SC_DIMENSIONDOOR -2301,0xce, , 0, 2, -1,all, 0x200E //SC_CHAOSPANIC -2302,0xcf, , 0, 2, -1,enemy, 0x002 //SC_MAELSTROM -2303,0xd0, , 0, 2, -1,all, 0x2018 //SC_BLOODYLUST -2304,0xd1, , 0, 2, 500,enemy, 0x018 //SC_FEINTBOMB +2299,0xcc, , 0, 1,1000,all, 0x006 //SC_MANHOLE +2300,0xcd, , 0, 0,1000,all, 0x006 //SC_DIMENSIONDOOR +2301,0xce, , 2, 0, -1,all, 0x200E //SC_CHAOSPANIC +2302,0xcf, , 2, 0, -1,all, 0x2002 //SC_MAELSTROM +2303,0xd0, , 3, 0, -1,all, 0x201A //SC_BLOODYLUST +2304,0xd1, , 0, 2, 500,enemy, 0x018 //SC_FEINTBOMB 2319,0xec, , 0, 3,5000,all, 0x000 //LG_BANDING -2414,0xda, , 0, 1,1000,enemy, 0x008 //WM_REVERBERATION +2414,0xda, , 0, 0,1000,enemy, 0x008 //WM_REVERBERATION 2418,0xdb, , 0, 5, 300,enemy, 0x800 //WM_SEVERE_RAINSTORM -2419,0xde, , 0, 1,1000,enemy, 0x014 //WM_POEMOFNETHERWORLD +2419,0xde, , 0, 1,1000,enemy, 0x014 //WM_POEMOFNETHERWORLD 2443,0xdc, , 0, 0,1000,enemy, 0x00A //SO_FIREWALK 2444,0xdd, , 0, 0,1000,enemy, 0x00A //SO_ELECTRICWALK @@ -148,7 +148,7 @@ 2468,0xf4, , 0, 1,1000,all, 0x010 //SO_EARTH_INSIGNIA 2479,0xe5, , 0, 1,1000,enemy, 0x006 //GN_THORNS_TRAP -2482,0xe6,0x7f, -1, 2, -1,all, 0x000 //GN_WALLOFTHORN +2482,0xe6,0x7f, 0, 1, 100,all, 0x000 //GN_WALLOFTHORN 2484,0x86, , 0, 1, 100,enemy, 0x080 //GN_CRAZYWEED_ATK 2485,0xe7, , 0, 2,2000,enemy, 0x098 //GN_DEMONIC_FIRE 2487,0xe8, , 2, 0, -1,all, 0x2000 //GN_FIRE_EXPANSION_SMOKE_POWDER diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index c12dac6014..844a10af0b 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -1055,12 +1055,12 @@ 2295,3,6,1,0,0x1,0,3,1,yes,0,0,0,none,0,0x20, SC_LAZINESS,Masquerade - Laziness 2296,3,6,1,0,0x1,0,3,1,yes,0,0,0,none,0,0x20, SC_UNLUCKY,Masquerade - Unlucky 2297,3,6,1,0,0x1,0,3,1,yes,0,0,0,none,0,0x20, SC_WEAKNESS,Masquerade - Weakness -2298,3,6,1,0,0x1,0,5,1,yes,0,0,0,weapon,0,0x8020, SC_STRIPACCESSARY,Strip Accessory //CHECK Is weapon attack type needed? -2299,7,6,2,0,0x1,0,3,1,yes,0,0,3,none,0,0x0, SC_MANHOLE,Man Hole -2300,7,6,2,0,0x1,0,3,1,yes,0,0,1,none,0,0x0, SC_DIMENSIONDOOR,Dimension Door -2301,7,6,2,0,0x1,0,3,1,yes,0,0x20000,0,none,0,0x0, SC_CHAOSPANIC,Chaos Panic -2302,7,6,2,0,0x1,0,3,1,yes,0,0x20000,1,none,0,0x0, SC_MAELSTROM,Maelstrom -2303,7,6,2,0,0x1,3,3,1,yes,0,0,1,none,0,0x0, SC_BLOODYLUST,Bloody Lust +2298,3,6,1,0,0x1,0,5,1,yes,0,0,0,none,0,0x8020, SC_STRIPACCESSARY,Strip Accessory +2299,7,6,2,0,0x1,0,3,1,yes,0,0,3,magic,0,0x0, SC_MANHOLE,Man Hole +2300,7,6,2,0,0x1,0,3,1,yes,0,0,1,magic,0,0x0, SC_DIMENSIONDOOR,Dimension Door +2301,7,6,2,0,0x1,0,3,1,yes,0,0x20000,0,magic,0,0x0, SC_CHAOSPANIC,Chaos Panic +2302,7,6,2,0,0x1,0,3,1,yes,0,0x20000,1,magic,0,0x0, SC_MAELSTROM,Maelstrom +2303,7,6,2,0,0x1,0,3,1,yes,0,0,0,magic,0,0x0, SC_BLOODYLUST,Bloody Lust 2304,0,6,4,-1,0,0,3,1,no,0,0,0,weapon,0,0x0, SC_FEINTBOMB,Feint Bomb //**** diff --git a/db/re/skill_nocast_db.txt b/db/re/skill_nocast_db.txt index 66830d037d..1f1a0712f8 100644 --- a/db/re/skill_nocast_db.txt +++ b/db/re/skill_nocast_db.txt @@ -155,6 +155,7 @@ 361,512 //HP_ASSUMPTIO 691,512 //CASH_ASSUMPTIO 2284,512 //SC_FATALMENACE +2294,512 //SC_IGNORANCE 2300,512 //SC_DIMENSIONDOOR //---------------------------------------------------------------------------- @@ -166,6 +167,7 @@ 405,1024 //PF_SPIDERWEB 674,1024 //NPC_EXPULSION 2284,1024 //SC_FATALMENACE +2294,1024 //SC_IGNORANCE 2300,1024 //SC_DIMENSIONDOOR //---------------------------------------------------------------------------- @@ -176,5 +178,9 @@ 491,2048 //CR_CULTIVATION 1013,2048 //BS_GREED 2299,2048 //SC_MANHOLE +2300,2048 //SC_DIMENSIONDOOR +2301,2048 //SC_CHAOSPANIC +2303,2048 //SC_BLOODYLUST 2419,2048 //WM_POEMOFNETHERWORLD 2482,2048 //GN_WALLOFTHORN +2493,2048 //GN_SLINGITEM diff --git a/db/re/skill_unit_db.txt b/db/re/skill_unit_db.txt index ca76cf475b..c03b18858e 100644 --- a/db/re/skill_unit_db.txt +++ b/db/re/skill_unit_db.txt @@ -98,7 +98,7 @@ 527,0xbc, , -1, 0,2000,enemy, 0x018 //NJ_TATAMIGAESHI 535,0xbd, , -1, 0, 20,enemy, 0x010 //NJ_KAENSIN 538,0xbb, , 1:1:1:2:2:2:3:3:3:4,0,-1,all,0x010 //NJ_SUITON -541,0x86, , 0, 3:3:4:4:5, 100,enemy, 0x018 //NJ_RAIGEKISAI +541,0x86, , 0, 3:3:4:4:5,1000,enemy, 0x018 //NJ_RAIGEKISAI 670,0xc7, , 1, 4:7:10:13:16:19:22:25:28:31,1000,all,0x008 //NPC_EVILLAND //706,0xfd, , 0, 0,1000,all, 0x000 //NPC_VENOMFOG @@ -123,18 +123,18 @@ 2273,0xe2, , 2, 0, 500,all, 0x000 //NC_NEUTRALBARRIER 2274,0xe3, , 2, 0, 500,friend,0x000 //NC_STEALTHFIELD -2299,0xcc, , 0, 1,1000,all, 0x006 //SC_MANHOLE -2300,0xcd, , 0, 1,1000,all, 0x006 //SC_DIMENSIONDOOR -2301,0xce, , 0, 2, -1,all, 0x200E //SC_CHAOSPANIC -2302,0xcf, , 0, 2, -1,enemy, 0x002 //SC_MAELSTROM -2303,0xd0, , 0, 2, -1,all, 0x2018 //SC_BLOODYLUST -2304,0xd1, , 0, 2, 500,enemy, 0x018 //SC_FEINTBOMB +2299,0xcc, , 0, 1,1000,all, 0x006 //SC_MANHOLE +2300,0xcd, , 0, 0,1000,all, 0x006 //SC_DIMENSIONDOOR +2301,0xce, , 2, 0, -1,all, 0x200E //SC_CHAOSPANIC +2302,0xcf, , 2, 0, -1,all, 0x2002 //SC_MAELSTROM +2303,0xd0, , 3, 0, -1,all, 0x201A //SC_BLOODYLUST +2304,0xd1, , 0, 2, 500,enemy, 0x018 //SC_FEINTBOMB 2319,0xec, , 0, 3,5000,all, 0x000 //LG_BANDING -2414,0xda, , 0, 1,1000,enemy, 0x008 //WM_REVERBERATION +2414,0xda, , 0, 0,1000,enemy, 0x008 //WM_REVERBERATION 2418,0xdb, , 0, 5, 300,enemy, 0x800 //WM_SEVERE_RAINSTORM -2419,0xde, , 0, 1,1000,enemy, 0x014 //WM_POEMOFNETHERWORLD +2419,0xde, , 0, 1,1000,enemy, 0x014 //WM_POEMOFNETHERWORLD 2443,0xdc, , 0, 0,1000,enemy, 0x00A //SO_FIREWALK 2444,0xdd, , 0, 0,1000,enemy, 0x00A //SO_ELECTRICWALK @@ -150,7 +150,7 @@ 2468,0xf4, , 0, 1,1000,all, 0x010 //SO_EARTH_INSIGNIA 2479,0xe5, , 0, 1,1000,enemy, 0x006 //GN_THORNS_TRAP -2482,0xe6,0x7f, -1, 2, -1,all, 0x000 //GN_WALLOFTHORN +2482,0xe6,0x7f, 0, 1, 100,all, 0x000 //GN_WALLOFTHORN 2484,0x86, , 0, 1, 100,enemy, 0x080 //GN_CRAZYWEED_ATK 2485,0xe7, , 0, 2,2000,enemy, 0x098 //GN_DEMONIC_FIRE 2487,0xe8, , 2, 0, -1,all, 0x2000 //GN_FIRE_EXPANSION_SMOKE_POWDER diff --git a/doc/mob_db_mode_list.txt b/doc/mob_db_mode_list.txt index 3d521ef666..09e41fc890 100644 --- a/doc/mob_db_mode_list.txt +++ b/doc/mob_db_mode_list.txt @@ -11,22 +11,28 @@ Bit Legend: ------------------------------------------------------------------------------- -MD_CANMOVE | 0x0001 | 1 -MD_LOOTER | 0x0002 | 2 -MD_AGGRESSIVE | 0x0004 | 4 -MD_ASSIST | 0x0008 | 8 -MD_CASTSENSOR_IDLE | 0x0010 | 16 -MD_BOSS | 0x0020 | 32 -MD_PLANT | 0x0040 | 64 -MD_CANATTACK | 0x0080 | 128 -MD_DETECTOR | 0x0100 | 256 -MD_CASTSENSOR_CHASE | 0x0200 | 512 -MD_CHANGECHASE | 0x0400 | 1024 -MD_ANGRY | 0x0800 | 2048 -MD_CHANGETARGET_MELEE | 0x1000 | 4096 -MD_CHANGETARGET_CHASE | 0x2000 | 8192 -MD_TARGETWEAK | 0x4000 | 16384 -MD_RANDOMTARGET | 0x8000 | 32768 (not implemented) +MD_CANMOVE | 0x000001 | 1 +MD_LOOTER | 0x000002 | 2 +MD_AGGRESSIVE | 0x000004 | 4 +MD_ASSIST | 0x000008 | 8 +MD_CASTSENSOR_IDLE | 0x000010 | 16 +MD_BOSS | 0x000020 | 32 +MD_PLANT | 0x000040 | 64 +MD_CANATTACK | 0x000080 | 128 +MD_DETECTOR | 0x000100 | 256 +MD_CASTSENSOR_CHASE | 0x000200 | 512 +MD_CHANGECHASE | 0x000400 | 1024 +MD_ANGRY | 0x000800 | 2048 +MD_CHANGETARGET_MELEE | 0x001000 | 4096 +MD_CHANGETARGET_CHASE | 0x002000 | 8192 +MD_TARGETWEAK | 0x004000 | 16384 +MD_RANDOMTARGET | 0x008000 | 32768 (not implemented) +MD_IGNOREMELEE | 0x010000 | 65536 +MD_IGNOREMAGIC | 0x020000 | 131072 +MD_IGNORERANGED | 0x040000 | 262144 +MD_MVP | 0x080000 | 524288 +MD_IGNOREMISC | 0x100000 | 1048576 +MD_KNOCKBACK_IMMUNE | 0x200000 | 2097152 Explanation for modes: ------------------------------------------------------------------------------- @@ -77,6 +83,18 @@ Target Weak: Allows aggressive monsters to only be aggressive against Random Target: Picks a new random target in range on each attack / skill. (not implemented) +Ignore Melee: The mob will take 1 HP damage from physical attacks. + +Ignore Magic: The mob will take 1 HP damage from magic attacks. + +Ignore Range: The mob will take 1 HP damage from ranged attacks. + +MVP: Flagged as MVP which makes mobs resistance to Coma. + +Ignore Misc: The mob will take 1 HP damage from "none" attack type. + +Knockback Immune: The mob will be unable to be knocked back. + Aegis Mob Types: ------------------------------------------------------------------------------- diff --git a/src/map/battle.c b/src/map/battle.c index ca4d32c72b..aeb271528b 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2230,7 +2230,8 @@ static bool battle_skill_stacks_masteries_vvs(uint16 skill_id) #ifndef RENEWAL skill_id == PA_SHIELDCHAIN || skill_id == CR_SHIELDBOOMERANG || #endif - skill_id == LG_SHIELDPRESS || skill_id == LG_EARTHDRIVE || skill_id == RK_DRAGONBREATH_WATER) + skill_id == RK_DRAGONBREATH || skill_id == RK_DRAGONBREATH_WATER || skill_id == NC_SELFDESTRUCTION || + skill_id == LG_SHIELDPRESS || skill_id == LG_EARTHDRIVE) return false; return true; @@ -2647,8 +2648,6 @@ struct Damage battle_calc_skill_base_damage(struct Damage wd, struct block_list break; case CR_SHIELDBOOMERANG: case PA_SHIELDCHAIN: - case LG_SHIELDPRESS: - case LG_EARTHDRIVE: wd.damage = sstatus->batk; if (sd) { short index = sd->equip_index[EQI_HAND_L]; @@ -3405,16 +3404,13 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s break; case LG_SHIELDPRESS: skillratio = 150 * skill_lv + status_get_str(src); - if( sd ) { + if (sd) { short index = sd->equip_index[EQI_HAND_L]; - if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) { + + if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR) skillratio += sd->inventory_data[index]->weight / 10; - RE_LVL_DMOD(100); - skillratio += status_get_vit(src) * sd->status.inventory[index].refine; - } - } else { - RE_LVL_DMOD(100); } + RE_LVL_DMOD(100); break; case LG_PINPOINTATTACK: skillratio = (100 * skill_lv) + (5 * status_get_agi(src)); @@ -3459,17 +3455,14 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s RE_LVL_DMOD(100); break; case LG_EARTHDRIVE: - { - int16 sh_w = 0; - if (sd && sd->equip_index[EQI_HAND_L] >= 0) { - int16 idx = sd->equip_index[EQI_HAND_L]; - if (sd->inventory_data[idx] && sd->inventory_data[idx]->type == IT_ARMOR) - sh_w = sd->inventory_data[idx]->weight/10; - } - skillratio += -100 + (skill_lv+1) * max(sh_w,1); - RE_LVL_DMOD(100); - break; + if (sd) { + short index = sd->equip_index[EQI_HAND_L]; + + if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR) + skillratio += -100 + (skill_lv + 1) * sd->inventory_data[index]->weight / 10; } + RE_LVL_DMOD(100); + break; case LG_HESPERUSLIT: skillratio = 120 * skill_lv; if( sc && sc->data[SC_BANDING] ) @@ -3825,6 +3818,16 @@ static int battle_calc_skill_constant_addition(struct Damage wd, struct block_li if(sd) atk += (30 * pc_checkskill(sd, RA_TOOTHOFWUG)); break; + case LG_SHIELDPRESS: + if (sd) { + int damagevalue = 0; + short index = sd->equip_index[EQI_HAND_L]; + + if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR) + damagevalue = sstatus->vit * sd->status.inventory[index].refine; + atk = damagevalue; + } + break; case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40) if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40) atk = ( skill_lv * 500 + status_get_lv(target) * 40 ); @@ -4846,8 +4849,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl case RK_DRAGONBREATH: case RK_DRAGONBREATH_WATER: case NC_SELFDESTRUCTION: - case LG_SHIELDPRESS: - case LG_EARTHDRIVE: case KO_HAPPOKUNAI: { int64 tmp = wd.damage; @@ -6532,9 +6533,17 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t skill_castend_damage_id(src, target, 0, 1, tick, 0); if ( target->type == BL_SKILL && damage > 0 ){ TBL_SKILL *su = (TBL_SKILL*)target; - if( su->group && su->group->skill_id == HT_BLASTMINE) - skill_blown(src, target, 3, -1, 0); + + if (su->group) { + if (su->group->skill_id == HT_BLASTMINE) + skill_blown(src, target, 3, -1, 0); + if (su->group->skill_id == GN_WALLOFTHORN) { + if (--su->val2 <= 0) + skill_delunit(su); + } + } } + map_freeblock_lock(); if( skill_check_shadowform(target, damage, wd.div_) ) { @@ -6900,11 +6909,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f }else return 0; } - } else if (su->group->skill_id==WZ_ICEWALL || - su->group->skill_id == GN_WALLOFTHORN) { + } else if (su->group->skill_id == WZ_ICEWALL || su->group->skill_id == GN_WALLOFTHORN) { state |= BCT_ENEMY; strip_enemy = 0; - } else //Excepting traps and icewall, you should not be able to target skills. + } else //Excepting traps, Icewall, and Wall of Thorns, you should not be able to target skills. return 0; } break; diff --git a/src/map/pc.c b/src/map/pc.c index 1e36c80b8e..9a7b7a91dc 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -9059,6 +9059,8 @@ bool pc_unequipitem(struct map_session_data *sd,int n,int flag) { return false; } if (&sd->sc) { + if (sd->sc.data[SC_HOVERING] && sd->inventory_data[n]->type == IT_ARMOR && sd->inventory_data[n]->nameid == ITEMID_HOVERING_BOOSTER) + status_change_end(&sd->bl, SC_HOVERING, INVALID_TIMER); if (sd->sc.data[SC_HEAT_BARREL]) status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER); if (sd->sc.data[SC_P_ALTER] && (sd->inventory_data[n]->type == IT_WEAPON || sd->inventory_data[n]->type == IT_AMMO)) diff --git a/src/map/skill.c b/src/map/skill.c index a71d7f630b..e822e19df8 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1295,7 +1295,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC }; for( i = 0; i < skill_lv; i++ ) - skill_strip_equip(src,bl,pos[i],(5 + skill_lv) * skill_lv,skill_lv,skill_get_time2(skill_id,skill_lv)); + skill_strip_equip(src,bl,pos[i],6 * skill_lv + status_get_lv(src) / 4 + status_get_dex(src) / 10,skill_lv,skill_get_time2(skill_id,skill_lv)); } break; case WL_JACKFROST: @@ -1725,15 +1725,17 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint if( rate ) skill_break_equip(src,bl, EQP_ARMOR, rate, BCT_ENEMY); } - if( sd && sd->def_set_race[tstatus->race].rate ) - status_change_start(src,bl, SC_DEFSET, sd->def_set_race[tstatus->race].rate, sd->def_set_race[tstatus->race].value, - 0, 0, 0, sd->def_set_race[tstatus->race].tick, 2); - if( sd && sd->def_set_race[tstatus->race].rate ) - status_change_start(src,bl, SC_MDEFSET, sd->mdef_set_race[tstatus->race].rate, sd->mdef_set_race[tstatus->race].value, - 0, 0, 0, sd->mdef_set_race[tstatus->race].tick, 2); + if (sd && !skill_id && bl->type == BL_PC) { // This effect does not work with skills. + if (sd->def_set_race[tstatus->race].rate) + status_change_start(src,bl, SC_DEFSET, sd->def_set_race[tstatus->race].rate, sd->def_set_race[tstatus->race].value, + 0, 0, 0, sd->def_set_race[tstatus->race].tick, 2); + if (sd->def_set_race[tstatus->race].rate) + status_change_start(src,bl, SC_MDEFSET, sd->mdef_set_race[tstatus->race].rate, sd->mdef_set_race[tstatus->race].value, + 0, 0, 0, sd->mdef_set_race[tstatus->race].tick, 2); + } } - if( sd && sd->ed && sc && !status_isdead(bl) && !skill_id ){ + if( sd && sd->ed && sc && !status_isdead(bl) && !skill_id ) { struct unit_data *ud = unit_bl2ud(src); if( sc->data[SC_WILD_STORM_OPTION] ) @@ -2376,8 +2378,18 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in break; case BL_SKILL: su = (struct skill_unit *)target; - if( su && su->group && su->group->unit_id == UNT_ANKLESNARE ) - return 0; // ankle snare cannot be knocked back + + if (su && su->group) { + switch (su->group->unit_id) { + case UNT_ICEWALL: + case UNT_ANKLESNARE: + case UNT_ELECTRICSHOCKER: + case UNT_REVERBERATION: + case UNT_NETHERWORLD: + case UNT_WALLOFTHORN: + return 0; //Cannot be knocked back + } + } break; } @@ -3059,11 +3071,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list * skill_addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag|4); } break; - case GN_WALLOFTHORN: - unit_stop_walking(bl,1); - skill_blown(dsrc,bl,dmg.blewcount,dir, 0x2 ); - clif_fixpos(bl); - break; default: skill_blown(dsrc,bl,dmg.blewcount,dir, 0x0 ); if ( !dmg.blewcount && bl->type == BL_SKILL && damage > 0 ){ @@ -9044,7 +9051,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_UNLUCKY: case SC_WEAKNESS: if( !(tsc && tsc->data[type]) ) { - int rate = status_get_lv(src) / 10 + rnd_value(sstatus->dex / 12, sstatus->dex / 4) + ( sd ? sd->status.job_level : 50 ) + 10 * skill_lv + int rate; + + if (is_boss(bl)) + break; + rate = status_get_lv(src) / 10 + rnd_value(sstatus->dex / 12, sstatus->dex / 4) + ( sd ? sd->status.job_level : 50 ) + 10 * skill_lv - (status_get_lv(bl) / 10 + rnd_value(tstatus->agi / 6, tstatus->agi / 3) + tstatus->luk / 10 + ( dstsd ? (dstsd->max_weight / 10 - dstsd->weight / 10 ) / 100 : 0)); rate = cap_value(rate, skill_lv + sstatus->dex / 20, 100); clif_skill_nodamage(src,bl,skill_id,0,sc_start(src,bl,type,rate,skill_lv,skill_get_time(skill_id,skill_lv))); @@ -9054,7 +9065,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_IGNORANCE: if( !(tsc && tsc->data[type]) ) { - int rate = status_get_lv(src) / 10 + rnd_value(sstatus->dex / 12, sstatus->dex / 4) + ( sd ? sd->status.job_level : 50 ) + 10 * skill_lv + int rate; + + if (is_boss(bl)) + break; + rate = status_get_lv(src) / 10 + rnd_value(sstatus->dex / 12, sstatus->dex / 4) + ( sd ? sd->status.job_level : 50 ) + 10 * skill_lv - (status_get_lv(bl) / 10 + rnd_value(tstatus->agi / 6, tstatus->agi / 3) + tstatus->luk / 10 + ( dstsd ? (dstsd->max_weight / 10 - dstsd->weight / 10 ) / 100 : 0)); rate = cap_value(rate, skill_lv + sstatus->dex / 20, 100); if (clif_skill_nodamage(src,bl,skill_id,0,sc_start(src,bl,type,rate,skill_lv,skill_get_time(skill_id,skill_lv)))) { @@ -10823,7 +10838,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case WM_POEMOFNETHERWORLD: case SO_PSYCHIC_WAVE: case SO_VACUUM_EXTREME: - case GN_WALLOFTHORN: case GN_THORNS_TRAP: case GN_DEMONIC_FIRE: case GN_HELLS_PLANT: @@ -11276,6 +11290,19 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui skill_unitsetting(src,skill_id,skill_lv,x,y,0); break; + case GN_WALLOFTHORN: { + static const int dx[] = {-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2, 2, 2, 1, 0}; + static const int dy[] = { 2, 2, 1, 0,-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2}; + struct unit_data *ud = unit_bl2ud(src); + + for (i = 0; i < 16; i++) { + x = ud->skillx + dx[i]; + y = ud->skilly + dy[i]; + skill_unitsetting(src, skill_id, skill_lv, x, y, 0); + } + flag |= 1; + } + break; case GN_CRAZYWEED: { int area = skill_get_splash(GN_CRAZYWEED_ATK, skill_lv); for( i = 0; i < 3 + (skill_lv/2); i++ ) { @@ -12109,6 +12136,7 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill val2 = 0; break; case WM_REVERBERATION: + case WM_POEMOFNETHERWORLD: val1 = 1 + skill_lv; break; case GN_WALLOFTHORN: @@ -12366,13 +12394,6 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un skill_blown(ss,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0); break; - case UNT_WALLOFTHORN: - if( status_get_mode(bl)&MD_BOSS ) - break; // iRO Wiki says that this skill don't affect to Boss monsters. - if( map_flag_vs(bl->m) || bl->id == src->bl.id || battle_check_target(&src->bl,bl, BCT_ENEMY) == 1 ) - skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); - break; - case UNT_FIRE_EXPANSION_SMOKE_POWDER: if( !sce ) sc_start(ss, bl, type, 100, sg->skill_lv, sg->limit); @@ -12463,7 +12484,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns int count=0; const int x = bl->x, y = bl->y; - if( sg->skill_id == GN_WALLOFTHORN && !map_flag_vs(bl->m) ) + if (skill_id == GN_WALLOFTHORN && battle_check_target(ss, bl, BCT_ENEMY) <= 0) break; //Take into account these hit more times than the timer interval can handle. @@ -12942,9 +12963,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns skill_attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0); break; case UNT_NETHERWORLD: - if( !(status_get_mode(bl)&MD_BOSS) || (!map_flag_gvg2(ss->m) && battle_check_target(&src->bl,bl,BCT_PARTY) < 0) ) { - if( !(tsc && tsc->data[type]) ) + if (!(status_get_mode(bl)&MD_BOSS) || (!map_flag_gvg2(ss->m) && battle_check_target(&src->bl,bl,BCT_PARTY) < 0)) { + if (!(tsc && tsc->data[type])) { sc_start(ss, bl, type, 100, sg->skill_lv, skill_get_time2(sg->skill_id,sg->skill_lv)); + sg->limit = DIFF_TICK(tick,sg->tick); + sg->unit_id = UNT_USED_TRAPS; + } } break; case UNT_THORNS_TRAP: @@ -12966,6 +12990,17 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns } break; + case UNT_WALLOFTHORN: + if (status_get_mode(bl)&MD_BOSS) + break; // This skill doesn't affect to Boss monsters. [iRO Wiki] + if (battle_check_target(ss, bl, BCT_ENEMY) <= 0) { + unit_stop_walking(bl, 1); + skill_blown(&src->bl, bl, skill_get_blewcount(sg->skill_id, sg->skill_lv), unit_getdir(bl), 0x2); + clif_fixpos(bl); + } else + skill_attack(skill_get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); + break; + case UNT_DEMONIC_FIRE: switch( sg->val2 ) { case 1: @@ -13004,13 +13039,18 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns } break; + case UNT_ZEPHYR: + if (ss == bl) + break; // Doesn't affect the Elemental + sc_start(ss, bl, type, 100, sg->skill_lv, sg->interval); + break; + case UNT_FIRE_INSIGNIA: case UNT_WATER_INSIGNIA: case UNT_WIND_INSIGNIA: case UNT_EARTH_INSIGNIA: - case UNT_ZEPHYR: - sc_start(ss, bl,type, 100, sg->skill_lv, sg->interval); - if (sg->unit_id != UNT_ZEPHYR && !battle_check_undead(tstatus->race, tstatus->def_ele)) { + sc_start(ss, bl, type, 100, sg->skill_lv, sg->interval); + if (!battle_check_undead(tstatus->race, tstatus->def_ele)) { int hp = tstatus->max_hp / 100; //+1% each 5s if ((sg->val3) % 5) { //each 5s if (tstatus->def_ele == skill_get_ele(sg->skill_id,sg->skill_lv)){ @@ -13409,6 +13449,7 @@ int64 skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int64 case UNT_ICEWALL: case UNT_REVERBERATION: case UNT_WALLOFTHORN: + case UNT_NETHERWORLD: src->val1-=(int)cap_value(damage,INT_MIN,INT_MAX); break; default: @@ -16307,7 +16348,15 @@ static int skill_trap_splash (struct block_list *bl, va_list ap) skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0); break; case UNT_ELECTRICSHOCKER: - clif_skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5); + if (bl->id != ss->id) { + if (status_get_mode(bl)&MD_BOSS) + break; + if (status_change_start(ss, bl, SC_ELECTRICSHOCKER, 10000, sg->skill_lv, sg->group_id, 0, 0, skill_get_time2(sg->skill_id, sg->skill_lv), 8)) { + map_moveblock(bl, unit->bl.x, unit->bl.y, tick); + clif_fixpos(bl); + clif_skill_damage(src, bl, tick, 0, 0, -30000, 1, sg->skill_id, sg->skill_lv, 5); + } + } break; case UNT_MAGENTATRAP: case UNT_COBALTTRAP: @@ -17054,12 +17103,14 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) break; case UNT_REVERBERATION: + case UNT_NETHERWORLD: if( unit->val1 <= 0 ) { // If it was deactivated. skill_delunit(unit); break; } clif_changetraplook(bl,UNT_USED_TRAPS); - map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); + if (group->unit_id == UNT_REVERBERATION) + map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); group->limit = DIFF_TICK(tick,group->tick)+1000; unit->limit = DIFF_TICK(tick,group->tick)+1000; group->unit_id = UNT_USED_TRAPS; @@ -17123,9 +17174,11 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) } break; case UNT_REVERBERATION: - if( unit->val1 <= 0 ){ + case UNT_NETHERWORLD: + if (unit->val1 <= 0) { clif_changetraplook(bl,UNT_USED_TRAPS); - map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); + if (group->unit_id == UNT_REVERBERATION) + map_foreachinrange(skill_trap_splash, bl, skill_get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); group->limit = DIFF_TICK(tick,group->tick)+1000; unit->limit = DIFF_TICK(tick,group->tick)+1000; group->unit_id = UNT_USED_TRAPS; @@ -17331,9 +17384,6 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int16 m, int16 d if (skill_get_unit_flag(group->skill_id)&UF_ENSEMBLE) return 0; //Ensembles may not be moved around. - if( group->unit_id == UNT_ICEWALL || group->unit_id == UNT_WALLOFTHORN ) - return 0; //Icewalls and Wall of Thorns don't get knocked back - m_flag = (int *) aCalloc(group->unit_count, sizeof(int)); // m_flag // 0: Neither of the following (skill_unit_onplace & skill_unit_onout are needed) @@ -18819,14 +18869,6 @@ void skill_init_unit_layout (void) { pos++; } break; - case GN_WALLOFTHORN: { - static const int dx[] = {-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2, 2, 2, 1, 0}; - static const int dy[] = { 2, 2, 1, 0,-1,-2,-2,-2,-2,-2,-1, 0, 1, 2, 2, 2}; - skill_unit_layout[pos].count = 16; - memcpy(skill_unit_layout[pos].dx,dx,sizeof(dx)); - memcpy(skill_unit_layout[pos].dy,dy,sizeof(dy)); - } - break; default: ShowError("unknown unit layout at skill %d\n",i); break; diff --git a/src/map/skill.h b/src/map/skill.h index ef40188765..63c0a8c21e 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -180,7 +180,7 @@ struct s_skill_db { }; extern struct s_skill_db skill_db[MAX_SKILL_DB]; -#define MAX_SKILL_UNIT_LAYOUT 55 // RL_FIRE_RAIN increased to 51 +#define MAX_SKILL_UNIT_LAYOUT 55 #define MAX_SQUARE_LAYOUT 5 // 11*11 Placement of a maximum unit #define MAX_SKILL_UNIT_COUNT ((MAX_SQUARE_LAYOUT*2+1)*(MAX_SQUARE_LAYOUT*2+1)) struct s_skill_unit_layout { diff --git a/src/map/status.c b/src/map/status.c index 8a6cae98aa..700b97c737 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1050,8 +1050,8 @@ void initChangeTables(void) StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN; StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN; StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD; - StatusChangeFlagTable[SC_DEFSET] |= SCB_DEF; - StatusChangeFlagTable[SC_MDEFSET] |= SCB_MDEF; + StatusChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2; + StatusChangeFlagTable[SC_MDEFSET] |= SCB_MDEF|SCB_MDEF2; StatusChangeFlagTable[SC_WEDDING] |= SCB_SPEED; StatusChangeFlagTable[SC_ALL_RIDING] |= SCB_SPEED; StatusChangeFlagTable[SC_PUSH_CART] |= SCB_SPEED; @@ -5551,6 +5551,10 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, if(sc->data[SC_STEELBODY]) return 90; #endif + if(sc->data[SC_DEFSET]) + return sc->data[SC_DEFSET]->val1; + if(sc->data[SC_UNLIMIT]) + return 1; if(sc->data[SC_ARMORCHANGE]) def += sc->data[SC_ARMORCHANGE]->val2; @@ -5612,8 +5616,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, def -= def * sc->data[SC_ASH]->val3/100; if( sc->data[SC_OVERED_BOOST] ) def -= def * sc->data[SC_OVERED_BOOST]->val3 / 100; - if(sc->data[SC_UNLIMIT]) - return 1; return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);; } @@ -5638,6 +5640,11 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change return 0; if(sc->data[SC_ETERNALCHAOS]) return 0; + if(sc->data[SC_DEFSET]) + return sc->data[SC_DEFSET]->val1; + if(sc->data[SC_UNLIMIT]) + return 1; + if(sc->data[SC_SUN_COMFORT]) def2 += sc->data[SC_SUN_COMFORT]->val2; if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 ) @@ -5678,8 +5685,6 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100; if(sc->data[SC_EQC]) def2 -= def2 * sc->data[SC_EQC]->val2 / 100; - if(sc->data[SC_UNLIMIT]) - return 1; #ifdef RENEWAL return (short)cap_value(def2,SHRT_MIN,SHRT_MAX); @@ -5711,6 +5716,10 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, if(sc->data[SC_STEELBODY]) return 90; #endif + if(sc->data[SC_MDEFSET]) + return sc->data[SC_MDEFSET]->val1; + if(sc->data[SC_UNLIMIT]) + return 1; if(sc->data[SC_ARMORCHANGE]) mdef += sc->data[SC_ARMORCHANGE]->val3; @@ -5739,8 +5748,6 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, } if (sc->data[SC_ODINS_POWER]) mdef -= 20 * sc->data[SC_ODINS_POWER]->val1; - if(sc->data[SC_UNLIMIT]) - return 1; return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX); } @@ -5761,17 +5768,19 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang return (short)cap_value(mdef2,1,SHRT_MAX); #endif - if(sc->data[SC_BERSERK]) return 0; if(sc->data[SC_SKA]) return 90; + if(sc->data[SC_MDEFSET]) + return sc->data[SC_MDEFSET]->val1; + if(sc->data[SC_UNLIMIT]) + return 1; + if(sc->data[SC_MINDBREAKER]) mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100; if(sc->data[SC_ANALYZE]) mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; - if(sc->data[SC_UNLIMIT]) - return 1; #ifdef RENEWAL return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX); @@ -7155,8 +7164,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ sc_def2 = status->agi*25; break; case SC_ELECTRICSHOCKER: - if( bl->type == BL_MOB ) - tick_def2 = status->agi*100; + tick_def2 = (status->vit + status->agi) * 70; break; case SC_CRYSTALIZE: tick_def2 = b_status->vit*100; @@ -9853,8 +9861,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC_CLOSECONFINE2: case SC_TINDER_BREAKER: case SC_TINDER_BREAKER2: - case SC_SPIDERWEB: - case SC_ELECTRICSHOCKER: case SC_BITE: case SC_THORNSTRAP: case SC__MANHOLE: @@ -9871,8 +9877,16 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty unit_stop_walking(bl,1); break; case SC_ANKLE: - if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) ) - unit_stop_walking(bl,1); + case SC_SPIDERWEB: + case SC_ELECTRICSHOCKER: + { + int knockback_immune = sd ? !sd->special_state.no_knockback : !(status->mode&(MD_KNOCKBACK_IMMUNE|MD_BOSS)); + + if (knockback_immune) { + if (battle_config.skill_trap_type && !map_flag_gvg2(bl->m)) + unit_stop_walking(bl, 1); + } + } break; case SC_HIDING: case SC_CLOAKING: @@ -11605,7 +11619,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_ELECTRICSHOCKER: if( --(sce->val4) >= 0 ) { - status_charge(bl, 0, status->max_sp / 100 * sce->val1 * 5 ); + if (!status_charge(bl, 0, 5 * sce->val1 * status->max_sp / 100)) + ; // Keep immobilize status even the SP is already running out. sc_timer_next(1000 + tick, status_change_timer, bl->id, data); return 0; } diff --git a/src/map/status.h b/src/map/status.h index 23fd92e093..3bc9cede72 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1538,29 +1538,29 @@ extern int current_equip_item_index; extern int current_equip_card_id; //Mode definitions to clear up code reading. [Skotlex] -enum e_mode -{ - MD_CANMOVE = 0x000001, - MD_LOOTER = 0x000002, - MD_AGGRESSIVE = 0x000004, - MD_ASSIST = 0x000008, - MD_CASTSENSOR_IDLE = 0x000010, - MD_BOSS = 0x000020, - MD_PLANT = 0x000040, - MD_CANATTACK = 0x000080, - MD_DETECTOR = 0x000100, - MD_CASTSENSOR_CHASE = 0x000200, - MD_CHANGECHASE = 0x000400, - MD_ANGRY = 0x000800, +enum e_mode { + MD_CANMOVE = 0x000001, + MD_LOOTER = 0x000002, + MD_AGGRESSIVE = 0x000004, + MD_ASSIST = 0x000008, + MD_CASTSENSOR_IDLE = 0x000010, + MD_BOSS = 0x000020, + MD_PLANT = 0x000040, + MD_CANATTACK = 0x000080, + MD_DETECTOR = 0x000100, + MD_CASTSENSOR_CHASE = 0x000200, + MD_CHANGECHASE = 0x000400, + MD_ANGRY = 0x000800, MD_CHANGETARGET_MELEE = 0x001000, MD_CHANGETARGET_CHASE = 0x002000, - MD_TARGETWEAK = 0x004000, - MD_IGNOREMELEE = 0x010000, //takes 1 HP damage from melee physical attacks - MD_IGNOREMAGIC = 0x020000, //takes 1 HP damage from magic - MD_IGNORERANGED = 0x040000, //takes 1 HP damage from ranged physical attacks - MD_MVP = 0x080000, //MVP - instant kill / coma-like skills don't work - MD_IGNOREMISC = 0x100000, //takes 1 HP damage from "none" attack type - MD_KNOCKBACK_IMMUNE = 0x200000, //can't be knocked back + MD_TARGETWEAK = 0x004000, + MD_RANDOMTARGET = 0x008000, + MD_IGNOREMELEE = 0x010000, + MD_IGNOREMAGIC = 0x020000, + MD_IGNORERANGED = 0x040000, + MD_MVP = 0x080000, + MD_IGNOREMISC = 0x100000, + MD_KNOCKBACK_IMMUNE = 0x200000, }; #define MD_MASK 0x00FFFF #define ATR_MASK 0xFF0000