Browse Source

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.

aleos89 11 years ago
parent
commit
c046668034

+ 1 - 1
conf/msg_conf/map_msg.conf

@@ -746,7 +746,7 @@
 730: Character cannot be disguised while in monster form.
 730: Character cannot be disguised while in monster form.
 731: Transforming into monster is not allowed in Guild Wars.
 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
 //733-899 free
 
 

+ 6 - 6
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
 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
 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
 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
 2304,0,6,4,-1,0,0,3,1,no,0,0,0,weapon,0,0x0,	SC_FEINTBOMB,Feint Bomb
 
 
 //****
 //****

+ 6 - 0
db/pre-re/skill_nocast_db.txt

@@ -156,6 +156,7 @@
 361,512	//HP_ASSUMPTIO
 361,512	//HP_ASSUMPTIO
 691,512	//CASH_ASSUMPTIO
 691,512	//CASH_ASSUMPTIO
 2284,512	//SC_FATALMENACE
 2284,512	//SC_FATALMENACE
+2294,512	//SC_IGNORANCE
 2300,512	//SC_DIMENSIONDOOR
 2300,512	//SC_DIMENSIONDOOR
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -167,6 +168,7 @@
 405,1024	//PF_SPIDERWEB
 405,1024	//PF_SPIDERWEB
 674,1024	//NPC_EXPULSION
 674,1024	//NPC_EXPULSION
 2284,1024	//SC_FATALMENACE
 2284,1024	//SC_FATALMENACE
+2294,1024	//SC_IGNORANCE
 2300,1024	//SC_DIMENSIONDOOR
 2300,1024	//SC_DIMENSIONDOOR
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -177,5 +179,9 @@
 491,2048	//CR_CULTIVATION
 491,2048	//CR_CULTIVATION
 1013,2048	//BS_GREED
 1013,2048	//BS_GREED
 2299,2048	//SC_MANHOLE
 2299,2048	//SC_MANHOLE
+2300,2048	//SC_DIMENSIONDOOR
+2301,2048	//SC_CHAOSPANIC
+2303,2048	//SC_BLOODYLUST
 2419,2048	//WM_POEMOFNETHERWORLD
 2419,2048	//WM_POEMOFNETHERWORLD
 2482,2048	//GN_WALLOFTHORN
 2482,2048	//GN_WALLOFTHORN
+2493,2048	//GN_SLINGITEM

+ 9 - 9
db/pre-re/skill_unit_db.txt

@@ -121,18 +121,18 @@
 2273,0xe2,    ,  2, 0, 500,all,   0x000	//NC_NEUTRALBARRIER
 2273,0xe2,    ,  2, 0, 500,all,   0x000	//NC_NEUTRALBARRIER
 2274,0xe3,    ,  2, 0, 500,friend,0x000	//NC_STEALTHFIELD
 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
 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
 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
 2443,0xdc,    ,  0, 0,1000,enemy, 0x00A	//SO_FIREWALK
 2444,0xdd,    ,  0, 0,1000,enemy, 0x00A	//SO_ELECTRICWALK
 2444,0xdd,    ,  0, 0,1000,enemy, 0x00A	//SO_ELECTRICWALK
@@ -148,7 +148,7 @@
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 
 
 2479,0xe5,    ,  0, 1,1000,enemy, 0x006	//GN_THORNS_TRAP
 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
 2484,0x86,    ,  0, 1, 100,enemy, 0x080	//GN_CRAZYWEED_ATK
 2485,0xe7,    ,  0, 2,2000,enemy, 0x098	//GN_DEMONIC_FIRE
 2485,0xe7,    ,  0, 2,2000,enemy, 0x098	//GN_DEMONIC_FIRE
 2487,0xe8,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER
 2487,0xe8,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER

+ 6 - 6
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
 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
 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
 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
 2304,0,6,4,-1,0,0,3,1,no,0,0,0,weapon,0,0x0,	SC_FEINTBOMB,Feint Bomb
 
 
 //****
 //****

+ 6 - 0
db/re/skill_nocast_db.txt

@@ -155,6 +155,7 @@
 361,512	//HP_ASSUMPTIO
 361,512	//HP_ASSUMPTIO
 691,512	//CASH_ASSUMPTIO
 691,512	//CASH_ASSUMPTIO
 2284,512	//SC_FATALMENACE
 2284,512	//SC_FATALMENACE
+2294,512	//SC_IGNORANCE
 2300,512	//SC_DIMENSIONDOOR
 2300,512	//SC_DIMENSIONDOOR
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -166,6 +167,7 @@
 405,1024	//PF_SPIDERWEB
 405,1024	//PF_SPIDERWEB
 674,1024	//NPC_EXPULSION
 674,1024	//NPC_EXPULSION
 2284,1024	//SC_FATALMENACE
 2284,1024	//SC_FATALMENACE
+2294,1024	//SC_IGNORANCE
 2300,1024	//SC_DIMENSIONDOOR
 2300,1024	//SC_DIMENSIONDOOR
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -176,5 +178,9 @@
 491,2048	//CR_CULTIVATION
 491,2048	//CR_CULTIVATION
 1013,2048	//BS_GREED
 1013,2048	//BS_GREED
 2299,2048	//SC_MANHOLE
 2299,2048	//SC_MANHOLE
+2300,2048	//SC_DIMENSIONDOOR
+2301,2048	//SC_CHAOSPANIC
+2303,2048	//SC_BLOODYLUST
 2419,2048	//WM_POEMOFNETHERWORLD
 2419,2048	//WM_POEMOFNETHERWORLD
 2482,2048	//GN_WALLOFTHORN
 2482,2048	//GN_WALLOFTHORN
+2493,2048	//GN_SLINGITEM

+ 10 - 10
db/re/skill_unit_db.txt

@@ -98,7 +98,7 @@
 527,0xbc,    , -1, 0,2000,enemy, 0x018	//NJ_TATAMIGAESHI
 527,0xbc,    , -1, 0,2000,enemy, 0x018	//NJ_TATAMIGAESHI
 535,0xbd,    , -1, 0,  20,enemy, 0x010	//NJ_KAENSIN
 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
 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
 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
 //706,0xfd,    ,  0, 0,1000,all, 0x000	//NPC_VENOMFOG
@@ -123,18 +123,18 @@
 2273,0xe2,    ,  2, 0, 500,all,   0x000	//NC_NEUTRALBARRIER
 2273,0xe2,    ,  2, 0, 500,all,   0x000	//NC_NEUTRALBARRIER
 2274,0xe3,    ,  2, 0, 500,friend,0x000	//NC_STEALTHFIELD
 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
 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
 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
 2443,0xdc,    ,  0, 0,1000,enemy, 0x00A	//SO_FIREWALK
 2444,0xdd,    ,  0, 0,1000,enemy, 0x00A	//SO_ELECTRICWALK
 2444,0xdd,    ,  0, 0,1000,enemy, 0x00A	//SO_ELECTRICWALK
@@ -150,7 +150,7 @@
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 
 
 2479,0xe5,    ,  0, 1,1000,enemy, 0x006	//GN_THORNS_TRAP
 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
 2484,0x86,    ,  0, 1, 100,enemy, 0x080	//GN_CRAZYWEED_ATK
 2485,0xe7,    ,  0, 2,2000,enemy, 0x098	//GN_DEMONIC_FIRE
 2485,0xe7,    ,  0, 2,2000,enemy, 0x098	//GN_DEMONIC_FIRE
 2487,0xe8,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER
 2487,0xe8,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER

+ 34 - 16
doc/mob_db_mode_list.txt

@@ -11,22 +11,28 @@
 Bit Legend:
 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:
 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.
 Random Target: Picks a new random target in range on each attack / skill.
 	(not implemented)
 	(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:
 Aegis Mob Types:
 -------------------------------------------------------------------------------
 -------------------------------------------------------------------------------
 
 

+ 35 - 27
src/map/battle.c

@@ -2230,7 +2230,8 @@ static bool battle_skill_stacks_masteries_vvs(uint16 skill_id)
 #ifndef RENEWAL
 #ifndef RENEWAL
 		skill_id == PA_SHIELDCHAIN || skill_id == CR_SHIELDBOOMERANG ||
 		skill_id == PA_SHIELDCHAIN || skill_id == CR_SHIELDBOOMERANG ||
 #endif
 #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 false;
 
 
 	return true;
 	return true;
@@ -2647,8 +2648,6 @@ struct Damage battle_calc_skill_base_damage(struct Damage wd, struct block_list
 			break;
 			break;
 		case CR_SHIELDBOOMERANG:
 		case CR_SHIELDBOOMERANG:
 		case PA_SHIELDCHAIN:
 		case PA_SHIELDCHAIN:
-		case LG_SHIELDPRESS:
-		case LG_EARTHDRIVE:
 			wd.damage = sstatus->batk;
 			wd.damage = sstatus->batk;
 			if (sd) {
 			if (sd) {
 				short index = sd->equip_index[EQI_HAND_L];
 				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;
 			break;
 		case LG_SHIELDPRESS:
 		case LG_SHIELDPRESS:
 			skillratio = 150 * skill_lv + status_get_str(src);
 			skillratio = 150 * skill_lv + status_get_str(src);
-			if( sd ) {
+			if (sd) {
 				short index = sd->equip_index[EQI_HAND_L];
 				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;
 					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;
 			break;
 		case LG_PINPOINTATTACK:
 		case LG_PINPOINTATTACK:
 			skillratio = (100 * skill_lv) + (5 * status_get_agi(src));
 			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);
 			RE_LVL_DMOD(100);
 			break;
 			break;
 		case LG_EARTHDRIVE:
 		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:
 		case LG_HESPERUSLIT:
 			skillratio = 120 * skill_lv;
 			skillratio = 120 * skill_lv;
 			if( sc && sc->data[SC_BANDING] )
 			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)
 			if(sd)
 				atk += (30 * pc_checkskill(sd, RA_TOOTHOFWUG));
 				atk += (30 * pc_checkskill(sd, RA_TOOTHOFWUG));
 			break;
 			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)
 		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)
 			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 );
 				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:
 		case RK_DRAGONBREATH_WATER:
 		case RK_DRAGONBREATH_WATER:
 		case NC_SELFDESTRUCTION:
 		case NC_SELFDESTRUCTION:
-		case LG_SHIELDPRESS:
-		case LG_EARTHDRIVE:
 		case KO_HAPPOKUNAI: {
 		case KO_HAPPOKUNAI: {
 				int64 tmp = wd.damage;
 				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);
 		skill_castend_damage_id(src, target, 0, 1, tick, 0);
 	if ( target->type == BL_SKILL && damage > 0 ){
 	if ( target->type == BL_SKILL && damage > 0 ){
 		TBL_SKILL *su = (TBL_SKILL*)target;
 		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();
 	map_freeblock_lock();
 
 
 	if( skill_check_shadowform(target, damage, wd.div_) ) {
 	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
 						}else
 							return 0;
 							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;
 				state |= BCT_ENEMY;
 				strip_enemy = 0;
 				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;
 				return 0;
 		}
 		}
 			break;
 			break;

+ 2 - 0
src/map/pc.c

@@ -9059,6 +9059,8 @@ bool pc_unequipitem(struct map_session_data *sd,int n,int flag) {
 		return false;
 		return false;
 	}
 	}
 	if (&sd->sc) {
 	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])
 		if (sd->sc.data[SC_HEAT_BARREL])
 			status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER);
 			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))
 		if (sd->sc.data[SC_P_ALTER] && (sd->inventory_data[n]->type == IT_WEAPON || sd->inventory_data[n]->type == IT_AMMO))

+ 88 - 46
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 };
 			const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
 
 
 			for( i = 0; i < skill_lv; i++ )
 			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;
 		break;
 	case WL_JACKFROST:
 	case WL_JACKFROST:
@@ -1725,15 +1725,17 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 			if( rate )
 			if( rate )
 				skill_break_equip(src,bl, EQP_ARMOR, rate, BCT_ENEMY);
 				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);
 		struct unit_data *ud = unit_bl2ud(src);
 
 
 		if( sc->data[SC_WILD_STORM_OPTION] )
 		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;
 			break;
 		case BL_SKILL:
 		case BL_SKILL:
 			su = (struct skill_unit *)target;
 			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;
 			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);
 						skill_addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag|4);
 				}
 				}
 				break;
 				break;
-			case GN_WALLOFTHORN:
-				unit_stop_walking(bl,1);
-				skill_blown(dsrc,bl,dmg.blewcount,dir, 0x2 );
-				clif_fixpos(bl);
-				break;
 			default:
 			default:
 				skill_blown(dsrc,bl,dmg.blewcount,dir, 0x0 );
 				skill_blown(dsrc,bl,dmg.blewcount,dir, 0x0 );
 				if ( !dmg.blewcount && bl->type == BL_SKILL && damage > 0 ){
 				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_UNLUCKY:
 	case SC_WEAKNESS:
 	case SC_WEAKNESS:
 		if( !(tsc && tsc->data[type]) ) {
 		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));
 					   - (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);
 			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)));
 			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:
 	case SC_IGNORANCE:
 		if( !(tsc && tsc->data[type]) ) {
 		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));
 					   - (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);
 			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)))) {
 			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 WM_POEMOFNETHERWORLD:
 	case SO_PSYCHIC_WAVE:
 	case SO_PSYCHIC_WAVE:
 	case SO_VACUUM_EXTREME:
 	case SO_VACUUM_EXTREME:
-	case GN_WALLOFTHORN:
 	case GN_THORNS_TRAP:
 	case GN_THORNS_TRAP:
 	case GN_DEMONIC_FIRE:
 	case GN_DEMONIC_FIRE:
 	case GN_HELLS_PLANT:
 	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);
 		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
 		break;
 		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: {
 	case GN_CRAZYWEED: {
 			int area = skill_get_splash(GN_CRAZYWEED_ATK, skill_lv);
 			int area = skill_get_splash(GN_CRAZYWEED_ATK, skill_lv);
 			for( i = 0; i < 3 + (skill_lv/2); i++ ) {
 			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;
 			val2 = 0;
 			break;
 			break;
 		case WM_REVERBERATION:
 		case WM_REVERBERATION:
+		case WM_POEMOFNETHERWORLD:
 			val1 = 1 + skill_lv;
 			val1 = 1 + skill_lv;
 			break;
 			break;
 		case GN_WALLOFTHORN:
 		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);
 			skill_blown(ss,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0);
 			break;
 			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:
 		case UNT_FIRE_EXPANSION_SMOKE_POWDER:
 			if( !sce )
 			if( !sce )
 				sc_start(ss, bl, type, 100, sg->skill_lv, sg->limit);
 				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;
 			int count=0;
 			const int x = bl->x, y = bl->y;
 			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;
 				break;
 
 
 			//Take into account these hit more times than the timer interval can handle.
 			//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);
 				skill_attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0);
 			break;
 			break;
 		case UNT_NETHERWORLD:
 		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));
 					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;
 			break;
 		case UNT_THORNS_TRAP:
 		case UNT_THORNS_TRAP:
@@ -12966,6 +12990,17 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 			}
 			}
 			break;
 			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:
 		case UNT_DEMONIC_FIRE:
 			switch( sg->val2 ) {
 			switch( sg->val2 ) {
 				case 1:
 				case 1:
@@ -13004,13 +13039,18 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 			}
 			}
 			break;
 			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_FIRE_INSIGNIA:
 		case UNT_WATER_INSIGNIA:
 		case UNT_WATER_INSIGNIA:
 		case UNT_WIND_INSIGNIA:
 		case UNT_WIND_INSIGNIA:
 		case UNT_EARTH_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
 				int hp = tstatus->max_hp / 100; //+1% each 5s
 				if ((sg->val3) % 5) { //each 5s
 				if ((sg->val3) % 5) { //each 5s
 					if (tstatus->def_ele == skill_get_ele(sg->skill_id,sg->skill_lv)){
 					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_ICEWALL:
 	case UNT_REVERBERATION:
 	case UNT_REVERBERATION:
 	case UNT_WALLOFTHORN:
 	case UNT_WALLOFTHORN:
+	case UNT_NETHERWORLD:
 		src->val1-=(int)cap_value(damage,INT_MIN,INT_MAX);
 		src->val1-=(int)cap_value(damage,INT_MIN,INT_MAX);
 		break;
 		break;
 	default:
 	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);
 				skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0);
 			break;
 			break;
 		case UNT_ELECTRICSHOCKER:
 		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;
 			break;
 		case UNT_MAGENTATRAP:
 		case UNT_MAGENTATRAP:
 		case UNT_COBALTTRAP:
 		case UNT_COBALTTRAP:
@@ -17054,12 +17103,14 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
 			break;
 			break;
 
 
 			case UNT_REVERBERATION:
 			case UNT_REVERBERATION:
+			case UNT_NETHERWORLD:
 				if( unit->val1 <= 0 ) { // If it was deactivated.
 				if( unit->val1 <= 0 ) { // If it was deactivated.
 					skill_delunit(unit);
 					skill_delunit(unit);
 					break;
 					break;
 				}
 				}
 				clif_changetraplook(bl,UNT_USED_TRAPS);
 				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;
 				group->limit = DIFF_TICK(tick,group->tick)+1000;
 				unit->limit = DIFF_TICK(tick,group->tick)+1000;
 				unit->limit = DIFF_TICK(tick,group->tick)+1000;
 				group->unit_id = UNT_USED_TRAPS;
 				group->unit_id = UNT_USED_TRAPS;
@@ -17123,9 +17174,11 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
 				}
 				}
 				break;
 				break;
 			case UNT_REVERBERATION:
 			case UNT_REVERBERATION:
-				if( unit->val1 <= 0 ){
+			case UNT_NETHERWORLD:
+				if (unit->val1 <= 0) {
 					clif_changetraplook(bl,UNT_USED_TRAPS);
 					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;
 					group->limit = DIFF_TICK(tick,group->tick)+1000;
 					unit->limit = DIFF_TICK(tick,group->tick)+1000;
 					unit->limit = DIFF_TICK(tick,group->tick)+1000;
 					group->unit_id = UNT_USED_TRAPS;
 					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)
 	if (skill_get_unit_flag(group->skill_id)&UF_ENSEMBLE)
 		return 0; //Ensembles may not be moved around.
 		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 = (int *) aCalloc(group->unit_count, sizeof(int));
 	//    m_flag
 	//    m_flag
 	//		0: Neither of the following (skill_unit_onplace & skill_unit_onout are needed)
 	//		0: Neither of the following (skill_unit_onplace & skill_unit_onout are needed)
@@ -18819,14 +18869,6 @@ void skill_init_unit_layout (void) {
 						pos++;
 						pos++;
 					}
 					}
 					break;
 					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:
 				default:
 					ShowError("unknown unit layout at skill %d\n",i);
 					ShowError("unknown unit layout at skill %d\n",i);
 					break;
 					break;

+ 1 - 1
src/map/skill.h

@@ -180,7 +180,7 @@ struct s_skill_db {
 };
 };
 extern struct s_skill_db skill_db[MAX_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_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))
 #define MAX_SKILL_UNIT_COUNT ((MAX_SQUARE_LAYOUT*2+1)*(MAX_SQUARE_LAYOUT*2+1))
 struct s_skill_unit_layout {
 struct s_skill_unit_layout {

+ 33 - 18
src/map/status.c

@@ -1050,8 +1050,8 @@ void initChangeTables(void)
 	StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
 	StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
 	StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
 	StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
 	StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
 	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_WEDDING] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_ALL_RIDING] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_ALL_RIDING] |= SCB_SPEED;
 	StatusChangeFlagTable[SC_PUSH_CART] |= 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])
 	if(sc->data[SC_STEELBODY])
 		return 90;
 		return 90;
 #endif
 #endif
+	if(sc->data[SC_DEFSET])
+		return sc->data[SC_DEFSET]->val1;
+	if(sc->data[SC_UNLIMIT])
+		return 1;
 
 
 	if(sc->data[SC_ARMORCHANGE])
 	if(sc->data[SC_ARMORCHANGE])
 		def += sc->data[SC_ARMORCHANGE]->val2;
 		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;
 		def -= def * sc->data[SC_ASH]->val3/100;
 	if( sc->data[SC_OVERED_BOOST] )
 	if( sc->data[SC_OVERED_BOOST] )
 		def -= def * sc->data[SC_OVERED_BOOST]->val3 / 100;
 		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);;
 	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;
 		return 0;
 	if(sc->data[SC_ETERNALCHAOS])
 	if(sc->data[SC_ETERNALCHAOS])
 		return 0;
 		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])
 	if(sc->data[SC_SUN_COMFORT])
 		def2 += sc->data[SC_SUN_COMFORT]->val2;
 		def2 += sc->data[SC_SUN_COMFORT]->val2;
 	if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 )
 	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;
 		def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
 	if(sc->data[SC_EQC])
 	if(sc->data[SC_EQC])
 		def2 -= def2 * sc->data[SC_EQC]->val2 / 100;
 		def2 -= def2 * sc->data[SC_EQC]->val2 / 100;
-	if(sc->data[SC_UNLIMIT])
-		return 1;
 
 
 #ifdef RENEWAL
 #ifdef RENEWAL
 	return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
 	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])
 	if(sc->data[SC_STEELBODY])
 		return 90;
 		return 90;
 #endif
 #endif
+	if(sc->data[SC_MDEFSET])
+		return sc->data[SC_MDEFSET]->val1;
+	if(sc->data[SC_UNLIMIT])
+		return 1;
 
 
 	if(sc->data[SC_ARMORCHANGE])
 	if(sc->data[SC_ARMORCHANGE])
 		mdef += sc->data[SC_ARMORCHANGE]->val3;
 		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])
 	if (sc->data[SC_ODINS_POWER])
 		mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
 		mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
-	if(sc->data[SC_UNLIMIT])
-		return 1;
 
 
 	return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
 	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);
 		return (short)cap_value(mdef2,1,SHRT_MAX);
 #endif
 #endif
 
 
-
 	if(sc->data[SC_BERSERK])
 	if(sc->data[SC_BERSERK])
 		return 0;
 		return 0;
 	if(sc->data[SC_SKA])
 	if(sc->data[SC_SKA])
 		return 90;
 		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])
 	if(sc->data[SC_MINDBREAKER])
 		mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
 		mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
 	if(sc->data[SC_ANALYZE])
 	if(sc->data[SC_ANALYZE])
 		mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
 		mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
-	if(sc->data[SC_UNLIMIT])
-		return 1;
 
 
 #ifdef RENEWAL
 #ifdef RENEWAL
 	return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
 	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;
 			sc_def2 = status->agi*25;
 			break;
 			break;
 		case SC_ELECTRICSHOCKER:
 		case SC_ELECTRICSHOCKER:
-			if( bl->type == BL_MOB )
-				tick_def2 = status->agi*100;
+			tick_def2 = (status->vit + status->agi) * 70;
 			break;
 			break;
 		case SC_CRYSTALIZE:
 		case SC_CRYSTALIZE:
 			tick_def2 = b_status->vit*100;
 			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_CLOSECONFINE2:
 		case SC_TINDER_BREAKER:
 		case SC_TINDER_BREAKER:
 		case SC_TINDER_BREAKER2:
 		case SC_TINDER_BREAKER2:
-		case SC_SPIDERWEB:
-		case SC_ELECTRICSHOCKER:
 		case SC_BITE:
 		case SC_BITE:
 		case SC_THORNSTRAP:
 		case SC_THORNSTRAP:
 		case SC__MANHOLE:
 		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);
 			unit_stop_walking(bl,1);
 		break;
 		break;
 		case SC_ANKLE:
 		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;
 		break;
 		case SC_HIDING:
 		case SC_HIDING:
 		case SC_CLOAKING:
 		case SC_CLOAKING:
@@ -11605,7 +11619,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 
 
 	case SC_ELECTRICSHOCKER:
 	case SC_ELECTRICSHOCKER:
 		if( --(sce->val4) >= 0 ) {
 		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);
 			sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
 			return 0;
 			return 0;
 		}
 		}

+ 21 - 21
src/map/status.h

@@ -1538,29 +1538,29 @@ extern int current_equip_item_index;
 extern int current_equip_card_id;
 extern int current_equip_card_id;
 
 
 //Mode definitions to clear up code reading. [Skotlex]
 //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_MELEE	= 0x001000,
 	MD_CHANGETARGET_CHASE	= 0x002000,
 	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 MD_MASK 0x00FFFF
 #define ATR_MASK 0xFF0000
 #define ATR_MASK 0xFF0000