Browse Source

Bug Fixes
* Fixes #447 - Added script command 'unitblockmove' to be used with OnTouch and Unit Commands.
* Fixes #448 - Leech End will no longer get a player stuck in stand/sit modes.
* Fixes #503 - Added script command 'ignoretimeout' which disables the SECURE_NPCTIMEOUT of a specific script.
* Fixes #521 - Pre-renewal Shield Chain should always be Neutral damage.
* Fixes #532 - Fixed an issue with the 'item_check' config not saving the unique ID when enabled.
* Fixes #537 - Arms Cannon is now a single unit target skill.
* Fixes #541 - Cleaned up Ignition Break damage formula.
* Fixes #543 and Fixes #552 - Cleaned up Reverberation to match official. Now splits damage among targets.
* Fixes #546 - Updated Randomize Spell to the latest official skill list and rates.
* Fixes #547 - Escape is now a self skill and can use normal Traps if no Alloy Traps are available.
* Fixes #551 - Great Echo and Sound of Destruction can now blocked by Pneuma.
* Fixes #556 - Adjusted Arrullo, Deep Sleep Lullaby, Netherworld, and Voice of Siren duration formulas to properly account base/job levels.
* Fixes #561 - Pre-renewal Tiger Cannon now properly removes HP when casting skill.
* Fixes #576 - Shield Spell, Exceed Break, Overbrand, Moon Slasher, Piety, Earth Drive, and Hesperuslit no longer have fixed cast time.
* Cleaned up Shadow Formation SP Drain formula to be 11-skill_lv per second.
* Sound of Destruction is now a placement skill type.
* Updated variable cast time for Windmill Rush from 2 seconds to 1 second.

aleos89 9 years ago
parent
commit
d95f5d2db7

+ 7 - 8
conf/battle/items.conf

@@ -51,15 +51,14 @@ random_monster_checklv: no
 // NOTE: Wedding Rings and Whips/Musical Instruments will check gender regardless of setting.
 // NOTE: Wedding Rings and Whips/Musical Instruments will check gender regardless of setting.
 ignore_items_gender: yes
 ignore_items_gender: yes
 
 
-// Item check?
-// On map change it will check for items not tagged as "available" and 
+// On map change it will check for items not tagged as "available" and
 // auto-delete them from inventory/cart/storage.
 // auto-delete them from inventory/cart/storage.
-// NOTE: An item is not available if it was not loaded from the item_db or you 
-// specify it as unavailable in db/item_avail.txt
-// 1: Inventory
-// 2: Cart
-// 4: Storage
-item_check: 0
+// NOTE: An item is not available if it was not loaded from the item_db or
+// specified as unavailable in db/item_avail.txt
+// 0x1: Inventory
+// 0x2: Cart
+// 0x4: Storage
+item_check: 0x0
 
 
 // How much time must pass between item uses?
 // How much time must pass between item uses?
 // Only affects the delay between using items, prevents healing item abuse. Recommended ~500 ms
 // Only affects the delay between using items, prevents healing item abuse. Recommended ~500 ms

+ 3 - 3
db/pre-re/skill_cast_db.txt

@@ -1368,7 +1368,7 @@
 2304,1000,0,0,500,1500,5000
 2304,1000,0,0,500,1500,5000
 
 
 //-- SC_ESCAPE
 //-- SC_ESCAPE
-5010,0,0,0,1000,0,15000
+5010,0,500,0,50000,20000,10000:8000:6000:4000:2000
 //==========================================
 //==========================================
 
 
 //==== Royal Guard skills ==================
 //==== Royal Guard skills ==================
@@ -1386,7 +1386,7 @@
 2313,0,1000,0,300000,0,0
 2313,0,1000,0,300000,0,0
 //-- LG_RAGEBURST
 //-- LG_RAGEBURST
 2314,0,3000,0,0,0,0
 2314,0,3000,0,0,0,0
-//-- LG_SHIELDSPELL //TODO apply proper duration [malufett]
+//-- LG_SHIELDSPELL
 2315,1000,1000,0,3000:30000:30000,0,2000
 2315,1000,1000,0,3000:30000:30000,0,2000
 //-- LG_EXEEDBREAK
 //-- LG_EXEEDBREAK
 2316,5000:5500:6000:6500:7000,1000,0,300000,0,0
 2316,5000:5500:6000:6500:7000,1000,0,300000,0,0
@@ -1470,7 +1470,7 @@
 
 
 //==== Minstresl skills ====================
 //==== Minstresl skills ====================
 //-- MI_RUSH_WINDMILL
 //-- MI_RUSH_WINDMILL
-2381,0,2000,0,60000,0,0
+2381,1000,2000,0,60000,0,0
 //-- MI_ECHOSONG
 //-- MI_ECHOSONG
 2382,1000,2000,0,60000,0,0
 2382,1000,2000,0,60000,0,0
 //-- MI_HARMONIZE
 //-- MI_HARMONIZE

+ 8 - 8
db/pre-re/skill_db.txt

@@ -697,7 +697,7 @@
 477,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0,0x4000,	WS_WEAPONREFINE,Upgrade Weapon
 477,0,6,4,0,0x1,0,10,1,no,0,0,0,weapon,0,0x4000,	WS_WEAPONREFINE,Upgrade Weapon
 478,3,6,2,0,0x3,3,10,1,no,0,0,0,none,0,0x0,		CR_SLIMPITCHER,Aid Condensed Potion
 478,3,6,2,0,0x3,3,10,1,no,0,0,0,none,0,0x0,		CR_SLIMPITCHER,Aid Condensed Potion
 479,1,6,16,0,0x1,0,5,1,yes,0,0,0,weapon,0,0x0,	CR_FULLPROTECTION,Full Protection
 479,1,6,16,0,0x1,0,5,1,yes,0,0,0,weapon,0,0x0,	CR_FULLPROTECTION,Full Protection
-480,5,8,1,-1,0,0,5,5,no,0,0,0,weapon,0,0x20000,		PA_SHIELDCHAIN,Shield Chain
+480,5,8,1,0,0,0,5,5,no,0,0,0,weapon,0,0x20000,		PA_SHIELDCHAIN,Shield Chain
 481,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		HP_MANARECHARGE,Mana Recharge
 481,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0,		HP_MANARECHARGE,Mana Recharge
 482,0,6,4,0,0x1,0,5,1,no,0,0,0,magic,0,0x0,		PF_DOUBLECASTING,Double Casting
 482,0,6,4,0,0x1,0,5,1,no,0,0,0,magic,0,0x0,		PF_DOUBLECASTING,Double Casting
 483,14,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x20,	HW_GANBANTEIN,Ganbantein
 483,14,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x20,	HW_GANBANTEIN,Ganbantein
@@ -1023,7 +1023,7 @@
 2258,13,6,1,-1,0x2,1,3,1,no,0,0,0,weapon,0,0x0,	NC_VULCANARM,Vulcan Arm
 2258,13,6,1,-1,0x2,1,3,1,no,0,0,0,weapon,0,0x0,	NC_VULCANARM,Vulcan Arm
 2259,7,6,1,3,0,2,3,1,no,0,0,5,weapon,0,0x0,		NC_FLAMELAUNCHER,Flame Launcher
 2259,7,6,1,3,0,2,3,1,no,0,0,5,weapon,0,0x0,		NC_FLAMELAUNCHER,Flame Launcher
 2260,7,6,2,1,0x2,2:3:4,3,1,no,0,0x40000,0,weapon,0,0x0,	NC_COLDSLOWER,Cold Slower
 2260,7,6,2,1,0x2,2:3:4,3,1,no,0,0x40000,0,weapon,0,0x0,	NC_COLDSLOWER,Cold Slower
-2261,9:11:13,6,2,-1,0x42,3:2:1,3,1,no,0,0,0,weapon,0,0x0,	NC_ARMSCANNON,Arm Cannon
+2261,9:11:13,6,1,-1,0x42,3:2:1,3,1,no,0,0,0,weapon,0,0x0,	NC_ARMSCANNON,Arm Cannon
 2262,0,6,4,0,0x1,0,3,1,no,0,0,0,none,0,0x0,		NC_ACCELERATION,Acceleration
 2262,0,6,4,0,0x1,0,3,1,no,0,0,0,none,0,0x0,		NC_ACCELERATION,Acceleration
 2263,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0,0x0,		NC_HOVERING,Hovering
 2263,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0,0x0,		NC_HOVERING,Hovering
 2264,0,6,4,0,0x1,0,1,1,no,0,0,0,none,7,0x0,		NC_F_SIDESLIDE,Front-Side Slide
 2264,0,6,4,0,0x1,0,1,1,no,0,0,0,none,7,0x0,		NC_F_SIDESLIDE,Front-Side Slide
@@ -1140,9 +1140,9 @@
 // WM Wanderer/Minstrel
 // WM Wanderer/Minstrel
 2412,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0,		WM_LESSON,Lesson
 2412,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0,		WM_LESSON,Lesson
 2413,9,8,1,-1,0,0,5,-2:-2:-3:-3:-4,yes,0,0,0,magic,0,0x0,	WM_METALICSOUND,Metallic Sound
 2413,9,8,1,-1,0,0,5,-2:-2:-3:-3:-4,yes,0,0,0,magic,0,0x0,	WM_METALICSOUND,Metallic Sound
-2414,9,6,2,-1,0x3,1,5,1,yes,0,0x80,0,none,0,0x0,	WM_REVERBERATION,Reverberation
-2415,0,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0,	WM_REVERBERATION_MELEE,Reverberation Melee
-2416,0,6,1,0,0,0,5,1,no,0,0,0,magic,0,0x0,	WM_REVERBERATION_MAGIC,Reverberation Magic
+2414,9,6,2,0,0x3,2,5,1,yes,0,0x80,0,none,0,0x0,	WM_REVERBERATION,Reverberation
+2415,0,6,1,-1,0x6,2,5,1,no,0,0,0,weapon,0,0x0,	WM_REVERBERATION_MELEE,Reverberation Melee
+2416,0,6,1,0,0x6,2,5,1,no,0,0,0,magic,0,0x0,	WM_REVERBERATION_MAGIC,Reverberation Magic
 2417,11,6,2,0,0x3,5,1,1,no,0,0,0,none,0,0x0,	WM_DOMINION_IMPULSE,Dominion Impulse
 2417,11,6,2,0,0x3,5,1,1,no,0,0,0,none,0,0x0,	WM_DOMINION_IMPULSE,Dominion Impulse
 2418,9,6,2,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	WM_SEVERE_RAINSTORM,Severe Rainstorm
 2418,9,6,2,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	WM_SEVERE_RAINSTORM,Severe Rainstorm
 2419,9,6,2,0,0x3,1,5,1,yes,0,0x80,5,none,0,0x0,	WM_POEMOFNETHERWORLD,Poem of The Netherworld
 2419,9,6,2,0,0x3,1,5,1,yes,0,0x80,5,none,0,0x0,	WM_POEMOFNETHERWORLD,Poem of The Netherworld
@@ -1155,9 +1155,9 @@
 2426,9,6,2,0,0x2,2:3:3:4:4,5,1,yes,0,0x4000,0,weapon,0,0x0,	WM_GREAT_ECHO,Great Echo
 2426,9,6,2,0,0x2,2:3:3:4:4,5,1,yes,0,0x4000,0,weapon,0,0x0,	WM_GREAT_ECHO,Great Echo
 2427,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SONG_OF_MANA,Song of Mana
 2427,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SONG_OF_MANA,Song of Mana
 2428,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_DANCE_WITH_WUG,Dance With A Warg
 2428,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_DANCE_WITH_WUG,Dance With A Warg
-2429,9,6,1,0,0x42,4:4:5:5:6,5,1,yes,0,0x4000,0,weapon,0,0x0,	WM_SOUND_OF_DESTRUCTION,Sound of Destruction //CHECK Source shows its magic attack. Need to confirm before changing.
+2429,9,6,2,0,0x42,4:4:5:5:6,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SOUND_OF_DESTRUCTION,Sound of Destruction
 2430,0,6,4,0,0x3,3:4:5:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SATURDAY_NIGHT_FEVER,Saturday Night Fever
 2430,0,6,4,0,0x3,3:4:5:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SATURDAY_NIGHT_FEVER,Saturday Night Fever
-2431,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,magic,0,0x0,	WM_LERADS_DEW,Lerad's Dew
+2431,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_LERADS_DEW,Lerad's Dew
 2432,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_MELODYOFSINK,Melody of Sink
 2432,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_MELODYOFSINK,Melody of Sink
 2433,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_BEYOND_OF_WARCRY,Warcry of Beyond
 2433,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_BEYOND_OF_WARCRY,Warcry of Beyond
 2434,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_UNLIMITED_HUMMING_VOICE,Unlimited Humming Voice
 2434,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_UNLIMITED_HUMMING_VOICE,Unlimited Humming Voice
@@ -1317,7 +1317,7 @@
 5007,0,6,4,0,0x3,5:6:7:8:9,5,1,no,0,0,0,none,0,0x0, WM_FRIGG_SONG,Frigg's Song
 5007,0,6,4,0,0x3,5:6:7:8:9,5,1,no,0,0,0,none,0,0x0, WM_FRIGG_SONG,Frigg's Song
 5008,0,6,4,0,0x3,11,5,1,no,0,0,0,none,0,0x0, SO_ELEMENTAL_SHIELD,Elemental Shield
 5008,0,6,4,0,0x3,11,5,1,no,0,0,0,none,0,0x0, SO_ELEMENTAL_SHIELD,Elemental Shield
 5009,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO,Flash Combo
 5009,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO,Flash Combo
-5010,0,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SC_ESCAPE,Emergency Escape
+5010,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SC_ESCAPE,Emergency Escape
 5011,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, AB_OFFERTORIUM,Offertorium
 5011,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, AB_OFFERTORIUM,Offertorium
 5012,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WL_TELEKINESIS_INTENSE,Intense Telekinesis
 5012,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WL_TELEKINESIS_INTENSE,Intense Telekinesis
 5013,0,6,4,0,0x3,0,5,1,no,0,0,0,none,0,0x0, LG_KINGS_GRACE,King's Grace
 5013,0,6,4,0,0x3,0,5,1,no,0,0,0,none,0,0x0, LG_KINGS_GRACE,King's Grace

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

@@ -759,7 +759,7 @@
 2327,0,0,8:9:10:11:12,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					//SR_SKYNETBLOW
 2327,0,0,8:9:10:11:12,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					//SR_SKYNETBLOW
 2328,0,0,36:40:44:48:52,0,0,0,99,0,0,none,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//SR_EARTHSHAKER
 2328,0,0,36:40:44:48:52,0,0,0,99,0,0,none,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//SR_EARTHSHAKER
 2329,0,0,20:30:40:50:60,0,0,0,99,0,0,none,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//SR_FALLENEMPIRE
 2329,0,0,20:30:40:50:60,0,0,0,99,0,0,none,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//SR_FALLENEMPIRE
-2330,0,0,1:2:3:4:5:6:7:8:9:10,0,0,0,99,0,0,none,SC_EXPLOSIONSPIRITS,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//SR_TIGERCANNON
+2330,0,0,1:2:3:4:5:6:7:8:9:10,-12:-14:-16:-18:-20:-22:-24:-26:-28:-30,-6:-7:-8:-9:-10:-11:-12:-13:-14:-15,0,99,0,0,none,SC_EXPLOSIONSPIRITS,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//SR_TIGERCANNON
 2331,0,0,1,0,-11:-12:-13:-14:-15:-16:-17:-18:-19:-20,0,99,0,0,none,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//SR_HELLGATE
 2331,0,0,1,0,-11:-12:-13:-14:-15:-16:-17:-18:-19:-20,0,99,0,0,none,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//SR_HELLGATE
 2332,0,0,150,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							//SR_RAMPAGEBLASTER
 2332,0,0,150,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							//SR_RAMPAGEBLASTER
 2333,0,0,80,0,0,0,99,0,0,none,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//SR_CRESCENTELBOW
 2333,0,0,80,0,0,0,99,0,0,none,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//SR_CRESCENTELBOW
@@ -809,7 +809,7 @@
 2423,0,0,42:46:50:54:58,0,0,0,13:14,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				//WM_SIRCLEOFNATURE
 2423,0,0,42:46:50:54:58,0,0,0,13:14,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				//WM_SIRCLEOFNATURE
 2424,0,0,40:45:50:55:60,0,0,0,13:14,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				//WM_RANDOMIZESPELL
 2424,0,0,40:45:50:55:60,0,0,0,13:14,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				//WM_RANDOMIZESPELL
 2425,0,0,60:75:90:105:120,0,0,0,13:14,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			//MW_GLOOMYDAY
 2425,0,0,60:75:90:105:120,0,0,0,13:14,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			//MW_GLOOMYDAY
-2426,0,0,80:90:100:110:120,0,0,0,99,0,0,none,0,0,11513,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			//WM_GREAT_ECHO // Missing 1 Lozange. Need item ID.
+2426,0,0,80:90:100:110:120,0,0,0,99,0,0,none,0,0,11513,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			//WM_GREAT_ECHO
 2427,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_SONG_OF_MANA
 2427,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_SONG_OF_MANA
 2428,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_DANCE_WITH_WUG
 2428,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_DANCE_WITH_WUG
 2429,0,0,50:60:70:80:90,0,0,0,13:14,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				//WM_SOUND_OF_DESTRUCTION
 2429,0,0,50:60:70:80:90,0,0,0,13:14,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				//WM_SOUND_OF_DESTRUCTION

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

@@ -134,7 +134,7 @@
 
 
 2319,0xec,    ,  0, 3,5000,all,   0x000	//LG_BANDING
 2319,0xec,    ,  0, 3,5000,all,   0x000	//LG_BANDING
 
 
-2414,0xda,    ,  0, 0,  -1,enemy, 0x1000	//WM_REVERBERATION
+2414,0xda,    ,  0, 0,1000,enemy, 0x1000	//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, 0x1014 //WM_POEMOFNETHERWORLD
 2419,0xde,    ,  0, 1,1000,enemy, 0x1014 //WM_POEMOFNETHERWORLD
 
 
@@ -169,7 +169,7 @@
 3020,0xf8,    ,  0, 2, 500,all, 0x018   //KO_ZENKAI
 3020,0xf8,    ,  0, 2, 500,all, 0x018   //KO_ZENKAI
 
 
 5006,0x101,   ,  0, 3, 500,enemy, 0x018	//NC_MAGMA_ERUPTION
 5006,0x101,   ,  0, 3, 500,enemy, 0x018	//NC_MAGMA_ERUPTION
-5010,0xfe,    ,  0, 2,  -1,enemy, 0x000	//SC_ESCAPE
+5010,0x91,    ,  0, 1,1000,all,   0x002	//SC_ESCAPE
 5013,0x102,   ,  3, 0,  -1,all,   0x2002	//LG_KINGS_GRACE
 5013,0x102,   ,  3, 0,  -1,all,   0x2002	//LG_KINGS_GRACE
 
 
 8020,0xf5,    ,  3, 0,2300:2100:1900:1700:1500,enemy,   0x018	//MH_POISON_MIST
 8020,0xf5,    ,  3, 0,2300:2100:1900:1700:1500,enemy,   0x018	//MH_POISON_MIST

+ 10 - 10
db/re/skill_cast_db.txt

@@ -1370,7 +1370,7 @@
 //-- SC_FEINTBOMB
 //-- SC_FEINTBOMB
 2304,1000,0,0,500,1500,5000,-1
 2304,1000,0,0,500,1500,5000,-1
 //-- SC_ESCAPE
 //-- SC_ESCAPE
-5010,0,0,0,1000,0,15000,-1
+5010,0,500,0,50000,20000,10000:8000:6000:4000:2000,-1
 //==========================================
 //==========================================
 
 
 //==== Royal Guard skills ==================
 //==== Royal Guard skills ==================
@@ -1388,26 +1388,26 @@
 2313,0,1000,0,300000,0,0,-1
 2313,0,1000,0,300000,0,0,-1
 //-- LG_RAGEBURST
 //-- LG_RAGEBURST
 2314,0,3000,0,0,0,0,-1
 2314,0,3000,0,0,0,0,-1
-//-- LG_SHIELDSPELL //TODO apply proper duration [malufett]
-2315,1000,1000,0,3000:30000:30000,0,2000,0
+//-- LG_SHIELDSPELL
+2315,1000,1000,0,3000:30000:30000,0,2000,-1
 //-- LG_EXEEDBREAK
 //-- LG_EXEEDBREAK
-2316,5000:5500:6000:6500:7000,1000,0,300000,0,0,0
+2316,5000:5500:6000:6500:7000,1000,0,300000,0,0,-1
 //-- LG_OVERBRAND
 //-- LG_OVERBRAND
-2317,500,2000,0,0,0,0,0
+2317,500,2000,0,0,0,0,-1
 //-- LG_PRESTIGE
 //-- LG_PRESTIGE
 2318,1000,0,0,30000:45000:60000:75000:90000,0,60000,2000
 2318,1000,0,0,30000:45000:60000:75000:90000,0,60000,2000
 //-- LG_BANDING
 //-- LG_BANDING
 2319,0,0,0,-1,2000:4000:6000:8000:10000,0,-1
 2319,0,0,0,-1,2000:4000:6000:8000:10000,0,-1
 //-- LG_MOONSLASHER
 //-- LG_MOONSLASHER
-2320,1000,1000,0,0,0,6000:5000:4000:3000:2000,0
+2320,1000,1000,0,0,0,6000:5000:4000:3000:2000,-1
 //-- LG_RAYOFGENESIS
 //-- LG_RAYOFGENESIS
 2321,2000:2500:3000:3500:4000,2000,0,10000,0,5000,500
 2321,2000:2500:3000:3500:4000,2000,0,10000,0,5000,500
 //-- LG_PIETY
 //-- LG_PIETY
-2322,3000:2500:2000:1500:1000,0,0,60000:80000:100000:120000:140000,0,0,0
+2322,3000:2500:2000:1500:1000,0,0,60000:80000:100000:120000:140000,0,0,-1
 //-- LG_EARTHDRIVE
 //-- LG_EARTHDRIVE
-2323,1000,1000,0,3000:6000:9000:12000:15000,0,7000:6000:5000:4000:3000,0
+2323,1000,1000,0,3000:6000:9000:12000:15000,0,7000:6000:5000:4000:3000,-1
 //-- LG_HESPERUSLIT
 //-- LG_HESPERUSLIT
-2324,1000,3000,0,0,0,20000,0
+2324,1000,3000,0,0,0,20000,-1
 //-- LG_INSPIRATION
 //-- LG_INSPIRATION
 2325,2000,2000,0,30000:45000:60000:75000:90000,0,540000:480000:420000:360000:300000,1000
 2325,2000,2000,0,30000:45000:60000:75000:90000,0,540000:480000:420000:360000:300000,1000
 //-- LG_KINGS_GRACE
 //-- LG_KINGS_GRACE
@@ -1470,7 +1470,7 @@
 
 
 //==== Minstresl skills ====================
 //==== Minstresl skills ====================
 //-- MI_RUSH_WINDMILL
 //-- MI_RUSH_WINDMILL
-2381,0,2000,0,60000,0,0,-1
+2381,1000,2000,0,60000,0,0,-1
 //-- MI_ECHOSONG
 //-- MI_ECHOSONG
 2382,1000,2000,0,60000,0,0,-1
 2382,1000,2000,0,60000,0,0,-1
 //-- MI_HARMONIZE
 //-- MI_HARMONIZE

+ 7 - 7
db/re/skill_db.txt

@@ -1023,7 +1023,7 @@
 2258,13,6,1,-1,0x2,1,3,1,no,0,0,0,weapon,0,0x0,	NC_VULCANARM,Vulcan Arm
 2258,13,6,1,-1,0x2,1,3,1,no,0,0,0,weapon,0,0x0,	NC_VULCANARM,Vulcan Arm
 2259,7,6,1,3,0,2,3,1,no,0,0,5,weapon,0,0x0,		NC_FLAMELAUNCHER,Flame Launcher
 2259,7,6,1,3,0,2,3,1,no,0,0,5,weapon,0,0x0,		NC_FLAMELAUNCHER,Flame Launcher
 2260,7,6,2,1,0x2,2:3:4,3,1,no,0,0x40000,0,weapon,0,0x0,	NC_COLDSLOWER,Cold Slower
 2260,7,6,2,1,0x2,2:3:4,3,1,no,0,0x40000,0,weapon,0,0x0,	NC_COLDSLOWER,Cold Slower
-2261,9:11:13,6,2,-1,0x42,3:2:1,3,1,no,0,0,0,weapon,0,0x0,	NC_ARMSCANNON,Arm Cannon
+2261,9:11:13,6,1,-1,0x42,3:2:1,3,1,no,0,0,0,weapon,0,0x0,	NC_ARMSCANNON,Arm Cannon
 2262,0,6,4,0,0x1,0,3,1,no,0,0,0,none,0,0x0,		NC_ACCELERATION,Acceleration
 2262,0,6,4,0,0x1,0,3,1,no,0,0,0,none,0,0x0,		NC_ACCELERATION,Acceleration
 2263,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0,0x0,		NC_HOVERING,Hovering
 2263,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0,0x0,		NC_HOVERING,Hovering
 2264,0,6,4,0,0x1,0,1,1,no,0,0,0,none,7,0x0,		NC_F_SIDESLIDE,Front-Side Slide
 2264,0,6,4,0,0x1,0,1,1,no,0,0,0,none,7,0x0,		NC_F_SIDESLIDE,Front-Side Slide
@@ -1140,9 +1140,9 @@
 // WM Wanderer/Minstrel
 // WM Wanderer/Minstrel
 2412,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0,		WM_LESSON,Lesson
 2412,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0x0,		WM_LESSON,Lesson
 2413,9,8,1,-1,0,0,5,-2:-2:-3:-3:-4,yes,0,0,0,magic,0,0x0,	WM_METALICSOUND,Metallic Sound
 2413,9,8,1,-1,0,0,5,-2:-2:-3:-3:-4,yes,0,0,0,magic,0,0x0,	WM_METALICSOUND,Metallic Sound
-2414,9,6,2,-1,0x3,1,5,1,yes,0,0x80,0,none,0,0x0,	WM_REVERBERATION,Reverberation
-2415,0,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0,	WM_REVERBERATION_MELEE,Reverberation Melee
-2416,0,6,1,0,0,0,5,1,no,0,0,0,magic,0,0x0,	WM_REVERBERATION_MAGIC,Reverberation Magic
+2414,9,6,2,0,0x3,2,5,1,yes,0,0x80,0,none,0,0x0,	WM_REVERBERATION,Reverberation
+2415,0,6,1,-1,0x6,2,5,1,no,0,0,0,weapon,0,0x0,	WM_REVERBERATION_MELEE,Reverberation Melee
+2416,0,6,1,0,0x6,2,5,1,no,0,0,0,magic,0,0x0,	WM_REVERBERATION_MAGIC,Reverberation Magic
 2417,11,6,2,0,0x3,5,1,1,no,0,0,0,none,0,0x0,	WM_DOMINION_IMPULSE,Dominion Impulse
 2417,11,6,2,0,0x3,5,1,1,no,0,0,0,none,0,0x0,	WM_DOMINION_IMPULSE,Dominion Impulse
 2418,9,6,2,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	WM_SEVERE_RAINSTORM,Severe Rainstorm
 2418,9,6,2,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	WM_SEVERE_RAINSTORM,Severe Rainstorm
 2419,9,6,2,0,0x3,1,5,1,yes,0,0x80,5,none,0,0x0,	WM_POEMOFNETHERWORLD,Poem of The Netherworld
 2419,9,6,2,0,0x3,1,5,1,yes,0,0x80,5,none,0,0x0,	WM_POEMOFNETHERWORLD,Poem of The Netherworld
@@ -1155,9 +1155,9 @@
 2426,9,6,2,0,0x2,2:3:3:4:4,5,1,yes,0,0x4000,0,weapon,0,0x0,	WM_GREAT_ECHO,Great Echo
 2426,9,6,2,0,0x2,2:3:3:4:4,5,1,yes,0,0x4000,0,weapon,0,0x0,	WM_GREAT_ECHO,Great Echo
 2427,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SONG_OF_MANA,Song of Mana
 2427,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SONG_OF_MANA,Song of Mana
 2428,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_DANCE_WITH_WUG,Dance With A Warg
 2428,0,6,4,0,0x3,5:6:7:8:9,5,1,yes,0,0x4000,0,none,0,0x0,	WM_DANCE_WITH_WUG,Dance With A Warg
-2429,9,6,1,0,0x42,4:4:5:5:6,5,1,yes,0,0x4000,0,weapon,0,0x0,	WM_SOUND_OF_DESTRUCTION,Sound of Destruction //CHECK Source shows its magic attack. Need to confirm before changing.
+2429,9,6,2,0,0x42,4:4:5:5:6,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SOUND_OF_DESTRUCTION,Sound of Destruction
 2430,0,6,4,0,0x3,3:4:5:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SATURDAY_NIGHT_FEVER,Saturday Night Fever
 2430,0,6,4,0,0x3,3:4:5:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_SATURDAY_NIGHT_FEVER,Saturday Night Fever
-2431,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,magic,0,0x0,	WM_LERADS_DEW,Lerad's Dew
+2431,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_LERADS_DEW,Lerad's Dew
 2432,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_MELODYOFSINK,Melody of Sink
 2432,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_MELODYOFSINK,Melody of Sink
 2433,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_BEYOND_OF_WARCRY,Warcry of Beyond
 2433,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_BEYOND_OF_WARCRY,Warcry of Beyond
 2434,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_UNLIMITED_HUMMING_VOICE,Unlimited Humming Voice
 2434,0,6,4,0,0x3,5:5:6:6:7,5,1,yes,0,0x4000,0,none,0,0x0,	WM_UNLIMITED_HUMMING_VOICE,Unlimited Humming Voice
@@ -1320,7 +1320,7 @@
 5007,0,6,4,0,0x3,5:6:7:8:9,5,1,no,0,0,0,none,0,0x0, WM_FRIGG_SONG,Frigg's Song
 5007,0,6,4,0,0x3,5:6:7:8:9,5,1,no,0,0,0,none,0,0x0, WM_FRIGG_SONG,Frigg's Song
 5008,0,6,4,0,0x3,11,5,1,no,0,0,0,none,0,0x0, SO_ELEMENTAL_SHIELD,Elemental Shield
 5008,0,6,4,0,0x3,11,5,1,no,0,0,0,none,0,0x0, SO_ELEMENTAL_SHIELD,Elemental Shield
 5009,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO,Flash Combo
 5009,1,6,1,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO,Flash Combo
-5010,0,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SC_ESCAPE,Emergency Escape
+5010,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SC_ESCAPE,Emergency Escape
 5011,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, AB_OFFERTORIUM,Offertorium
 5011,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, AB_OFFERTORIUM,Offertorium
 5012,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WL_TELEKINESIS_INTENSE,Intense Telekinesis
 5012,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WL_TELEKINESIS_INTENSE,Intense Telekinesis
 5013,0,6,4,0,0x3,0,5,1,no,0,0,0,none,0,0x0, LG_KINGS_GRACE,King's Grace
 5013,0,6,4,0,0x3,0,5,1,no,0,0,0,none,0,0x0, LG_KINGS_GRACE,King's Grace

+ 1 - 1
db/re/skill_require_db.txt

@@ -809,7 +809,7 @@
 2423,0,0,42:46:50:54:58,0,0,0,13:14,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				//WM_SIRCLEOFNATURE
 2423,0,0,42:46:50:54:58,0,0,0,13:14,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				//WM_SIRCLEOFNATURE
 2424,0,0,40:45:50:55:60,0,0,0,13:14,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				//WM_RANDOMIZESPELL
 2424,0,0,40:45:50:55:60,0,0,0,13:14,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				//WM_RANDOMIZESPELL
 2425,0,0,60:75:90:105:120,0,0,0,13:14,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			//MW_GLOOMYDAY
 2425,0,0,60:75:90:105:120,0,0,0,13:14,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			//MW_GLOOMYDAY
-2426,0,0,80:90:100:110:120,0,0,0,99,0,0,none,0,0,11513,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			//WM_GREAT_ECHO // Missing 1 Lozange. Need item ID.
+2426,0,0,80:90:100:110:120,0,0,0,99,0,0,none,0,0,11513,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			//WM_GREAT_ECHO
 2427,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_SONG_OF_MANA
 2427,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_SONG_OF_MANA
 2428,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_DANCE_WITH_WUG
 2428,0,0,120:140:160:180:200,0,0,0,13:14,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			//WM_DANCE_WITH_WUG
 2429,0,0,50:60:70:80:90,0,0,0,13:14,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				//WM_SOUND_OF_DESTRUCTION
 2429,0,0,50:60:70:80:90,0,0,0,13:14,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				//WM_SOUND_OF_DESTRUCTION

+ 2 - 2
db/re/skill_unit_db.txt

@@ -136,7 +136,7 @@
 
 
 2319,0xec,    ,  0, 3,5000,all,   0x000	//LG_BANDING
 2319,0xec,    ,  0, 3,5000,all,   0x000	//LG_BANDING
 
 
-2414,0xda,    ,  0, 0,  -1,enemy, 0x1000	//WM_REVERBERATION
+2414,0xda,    ,  0, 0,1000,enemy, 0x1000	//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, 0x1014 //WM_POEMOFNETHERWORLD
 2419,0xde,    ,  0, 1,1000,enemy, 0x1014 //WM_POEMOFNETHERWORLD
 
 
@@ -171,7 +171,7 @@
 3020,0xf8,    ,  0, 2, 500,all, 0x018   //KO_ZENKAI
 3020,0xf8,    ,  0, 2, 500,all, 0x018   //KO_ZENKAI
 
 
 5006,0x101,   ,  0, 3, 500,enemy, 0x018	//NC_MAGMA_ERUPTION
 5006,0x101,   ,  0, 3, 500,enemy, 0x018	//NC_MAGMA_ERUPTION
-5010,0xfe,    ,  0, 2,  -1,enemy, 0x000	//SC_ESCAPE
+5010,0x91,    ,  0, 1,1000,all,   0x002	//SC_ESCAPE
 5013,0x102,   ,  3, 0,  -1,all,   0x2002	//LG_KINGS_GRACE
 5013,0x102,   ,  3, 0,  -1,all,   0x2002	//LG_KINGS_GRACE
 
 
 8020,0xf5,    ,  3, 0,2300:2100:1900:1700:1500,enemy,   0x018	//MH_POISON_MIST
 8020,0xf5,    ,  3, 0,2300:2100:1900:1700:1500,enemy,   0x018	//MH_POISON_MIST

+ 16 - 28
db/skill_improvise_db.txt

@@ -6,31 +6,19 @@
 //
 //
 // - To remove entry by importing, put 0 on 'Rate'
 // - To remove entry by importing, put 0 on 'Rate'
 
 
-// Mage Skills
-10,5000	// Sight
-11,5000	// Napalm Beat
-12,5000	// Safety Wall
-13,5000	// Soul Strike
-14,5000	// Cold Bolt
-15,5000	// Frost Diver
-16,5000	// Stone Curse
-17,5000	// Fire Ball
-18,5000	// Fire Wall
-19,5000	// Fire Bolt
-20,5000	// Lightning Bolt
-21,5000	// Thunderstorm
-
-// Wizard Skills
-80,2500	// Fire Pillar
-81,2500	// Sightrasher
-83,2500	// Meteor Storm
-84,2500	// Jupitel Thunder
-85,2500	// Lord of Vermilion
-86,2500	// Water Ball
-87,2500	// Ice Wall
-88,2500	// Frost Nova
-89,2500	// Storm Gust
-90,2500	// Earth Spike
-91,2500	// Heaven's Drive
-92,2500	// Quagmire
-93,2500	// Sense
+11,60000	// Napalm Beat
+12,40000	// Safety Wall
+13,60000	// Soul Strike
+14,60000	// Cold Bolt
+15,60000	// Frost Diver
+17,60000	// Fire Ball
+18,40000	// Fire Wall
+19,60000	// Fire Bolt
+20,60000	// Lightning Bolt
+21,40000	// Thunderstorm
+80,40000	// Fire Pillar
+83,40000	// Meteor Storm
+84,60000	// Jupitel Thunder
+85,40000	// Lord of Vermilion
+86,60000	// Water Ball
+89,40000	// Storm Gust

+ 19 - 1
doc/script_commands.txt

@@ -2488,6 +2488,19 @@ Deletes the spirit ball(s) from player.
 
 
 Counts the spirit ball that player has.
 Counts the spirit ball that player has.
 
 
+---------------------------------------
+
+*ignoretimeout <flag>{,<char_id>};
+
+Disables the SECURE_NPCTIMEOUT function on the character invoking the script,
+or by the given character ID/character name.
+
+Valid flag:
+ 0 - Enabled SECURE_NPCTIMEOUT.
+ 1 - Disable SECURE_NPCTIMEOUT.
+
+Note: SECURE_NPCTIMEOUT must be enabled for this to work.
+
 ---------------------------------------
 ---------------------------------------
 \\
 \\
 2,2 Item-related commands
 2,2 Item-related commands
@@ -5563,9 +5576,10 @@ Examples:
 ---------------------------------------
 ---------------------------------------
 
 
 *pcblockmove <id>,<option>;
 *pcblockmove <id>,<option>;
+*unitblockmove <id>,<option>;
 
 
 Prevents the given GID from moving when the option is 1, and enables the ID to
 Prevents the given GID from moving when the option is 1, and enables the ID to
-move again when the option is 0. This command will run for the attached player
+move again when the option is 0. This command will run for the attached unit
 if the given GID is zero.
 if the given GID is zero.
 
 
 Examples:
 Examples:
@@ -7087,6 +7101,10 @@ This command will make a <GID> stop attacking.
 
 
 This command will make a <GID> stop moving.
 This command will make a <GID> stop moving.
 
 
+Note: If this is called from OnTouch, then the walktimer attached to the unit is
+removed from OnTouch which causes this command to not stop the unit from walking.
+Suggest to use 'unitblockmove' to forcefully stop the unit with OnTouch.
+
 ---------------------------------------
 ---------------------------------------
 
 
 *unittalk <GID>,"<text>";
 *unittalk <GID>,"<text>";

+ 23 - 19
src/char/char.c

@@ -575,7 +575,7 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 	// it significantly reduces cpu load on the database server.
 	// it significantly reduces cpu load on the database server.
 
 
 	StringBuf_Init(&buf);
 	StringBuf_Init(&buf);
-	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`");
+	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
 	for( j = 0; j < MAX_SLOTS; ++j )
 	for( j = 0; j < MAX_SLOTS; ++j )
 		StringBuf_Printf(&buf, ", `card%d`", j);
 		StringBuf_Printf(&buf, ", `card%d`", j);
 	StringBuf_Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id);
 	StringBuf_Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id);
@@ -599,8 +599,9 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 	SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
+	SqlStmt_BindColumn(stmt, 9, SQLDT_UINT64,    &item.unique_id,   0, NULL, NULL);
 	for( j = 0; j < MAX_SLOTS; ++j )
 	for( j = 0; j < MAX_SLOTS; ++j )
-		SqlStmt_BindColumn(stmt, 9+j, SQLDT_USHORT, &item.card[j], 0, NULL, NULL);
+		SqlStmt_BindColumn(stmt, 10+j, SQLDT_USHORT, &item.card[j], 0, NULL, NULL);
 
 
 	// bit array indicating which inventory items have already been matched
 	// bit array indicating which inventory items have already been matched
 	flag = (bool*) aCalloc(max, sizeof(bool));
 	flag = (bool*) aCalloc(max, sizeof(bool));
@@ -628,14 +629,15 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 				    items[i].refine == item.refine &&
 				    items[i].refine == item.refine &&
 				    items[i].attribute == item.attribute &&
 				    items[i].attribute == item.attribute &&
 				    items[i].expire_time == item.expire_time &&
 				    items[i].expire_time == item.expire_time &&
-				    items[i].bound == item.bound )
+				    items[i].bound == item.bound &&
+					items[i].unique_id == item.unique_id )
 				;	//Do nothing.
 				;	//Do nothing.
 				else
 				else
 				{
 				{
 					// update all fields.
 					// update all fields.
 					StringBuf_Clear(&buf);
 					StringBuf_Clear(&buf);
-					StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `bound`='%d'",
-						tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound);
+					StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `bound`='%d', `unique_id`='%"PRIu64"'",
+						tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound, items[i].unique_id);
 					for( j = 0; j < MAX_SLOTS; ++j )
 					for( j = 0; j < MAX_SLOTS; ++j )
 						StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
 						StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
 					StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
 					StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
@@ -718,7 +720,7 @@ int char_inventory_to_sql(const struct item items[], int max, int id) {
 	// it significantly reduces cpu load on the database server.
 	// it significantly reduces cpu load on the database server.
 
 
 	StringBuf_Init(&buf);
 	StringBuf_Init(&buf);
-	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`");
+	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`");
 	for( j = 0; j < MAX_SLOTS; ++j )
 	for( j = 0; j < MAX_SLOTS; ++j )
 		StringBuf_Printf(&buf, ", `card%d`", j);
 		StringBuf_Printf(&buf, ", `card%d`", j);
 	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, id);
 	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, id);
@@ -743,8 +745,9 @@ int char_inventory_to_sql(const struct item items[], int max, int id) {
 	SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,      &item.favorite,    0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,      &item.favorite,    0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR,      &item.bound,       0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR,      &item.bound,       0, NULL, NULL);
+	SqlStmt_BindColumn(stmt, 10,SQLDT_UINT64,    &item.unique_id,   0, NULL, NULL);
 	for( j = 0; j < MAX_SLOTS; ++j )
 	for( j = 0; j < MAX_SLOTS; ++j )
-		SqlStmt_BindColumn(stmt, 10+j, SQLDT_USHORT, &item.card[j], 0, NULL, NULL);
+		SqlStmt_BindColumn(stmt, 11+j, SQLDT_USHORT, &item.card[j], 0, NULL, NULL);
 
 
 	// bit array indicating which inventory items have already been matched
 	// bit array indicating which inventory items have already been matched
 	flag = (bool*) aCalloc(max, sizeof(bool));
 	flag = (bool*) aCalloc(max, sizeof(bool));
@@ -764,20 +767,21 @@ int char_inventory_to_sql(const struct item items[], int max, int id) {
 			   ) {	//They are the same item.
 			   ) {	//They are the same item.
 				ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
 				ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
 				if( j == MAX_SLOTS &&
 				if( j == MAX_SLOTS &&
-				   items[i].amount == item.amount &&
-				   items[i].equip == item.equip &&
-				   items[i].identify == item.identify &&
-				   items[i].refine == item.refine &&
-				   items[i].attribute == item.attribute &&
-				   items[i].expire_time == item.expire_time &&
-				   items[i].favorite == item.favorite &&
-				   items[i].bound == item.bound )
+					items[i].amount == item.amount &&
+					items[i].equip == item.equip &&
+					items[i].identify == item.identify &&
+					items[i].refine == item.refine &&
+					items[i].attribute == item.attribute &&
+					items[i].expire_time == item.expire_time &&
+					items[i].favorite == item.favorite &&
+					items[i].bound == item.bound &&
+					items[i].unique_id == item.unique_id )
 					;	//Do nothing.
 					;	//Do nothing.
 				else {
 				else {
 					// update all fields.
 					// update all fields.
 					StringBuf_Clear(&buf);
 					StringBuf_Clear(&buf);
-					StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d', `bound`='%d'",
-					    schema_config.inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound);
+					StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d', `bound`='%d', `unique_id`='%"PRIu64"'",
+					    schema_config.inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound, items[i].unique_id);
 					for( j = 0; j < MAX_SLOTS; ++j )
 					for( j = 0; j < MAX_SLOTS; ++j )
 						StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
 						StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
 					StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
 					StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
@@ -1161,7 +1165,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &tmp_item.expire_time, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &tmp_item.expire_time, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,      &tmp_item.favorite, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,      &tmp_item.favorite, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR,      &tmp_item.bound, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR,      &tmp_item.bound, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt,10, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL) )
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt,10, SQLDT_UINT64,    &tmp_item.unique_id, 0, NULL, NULL) )
 		SqlStmt_ShowDebug(stmt);
 		SqlStmt_ShowDebug(stmt);
 	for( i = 0; i < MAX_SLOTS; ++i )
 	for( i = 0; i < MAX_SLOTS; ++i )
 		if( SQL_ERROR == SqlStmt_BindColumn(stmt, 11+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) )
 		if( SQL_ERROR == SqlStmt_BindColumn(stmt, 11+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) )
@@ -1192,7 +1196,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR,        &tmp_item.attribute, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR,        &tmp_item.attribute, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,        &tmp_item.expire_time, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,        &tmp_item.expire_time, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,        &tmp_item.bound, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,        &tmp_item.bound, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_ULONGLONG,   &tmp_item.unique_id, 0, NULL, NULL) )
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_UINT64,      &tmp_item.unique_id, 0, NULL, NULL) )
 		SqlStmt_ShowDebug(stmt);
 		SqlStmt_ShowDebug(stmt);
 	for( i = 0; i < MAX_SLOTS; ++i )
 	for( i = 0; i < MAX_SLOTS; ++i )
 		if( SQL_ERROR == SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) )
 		if( SQL_ERROR == SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) )

+ 16 - 18
src/map/battle.c

@@ -3676,23 +3676,21 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
 			skillratio += -100 + (skill_lv + 2) * 50;
 			skillratio += -100 + (skill_lv + 2) * 50;
 			RE_LVL_DMOD(100);
 			RE_LVL_DMOD(100);
 			break;
 			break;
-		case RK_IGNITIONBREAK: {
-				// 3x3 cell Damage = ATK [{(Skill Level x 300) x (1 + [(Caster's Base Level - 100) / 100])}] %
-				// 7x7 cell Damage = ATK [{(Skill Level x 250) x (1 + [(Caster's Base Level - 100) / 100])}] %
-				// 11x11 cell Damage = ATK [{(Skill Level x 200) x (1 + [(Caster's Base Level - 100) / 100])}] %
-				int celldamage = 300; // Maximum base damage of 3x3 cell.
-
-				i = distance_bl(src,target);
-				if (i > 1 && i <= 3)
-					celldamage -= 50; // 7x7 cell
-				else if (i > 3 && i <= 5)
-					celldamage -= 100; // 11x11 cell
-				celldamage = (skill_lv * celldamage) * (1 + (status_get_lv(src) - 100) / 100);
-				// Elemental check, 1.5x damage if your element is fire.
-				if (sstatus->rhw.ele == ELE_FIRE)
-					celldamage += 100 * skill_lv;
-				skillratio += -100 + celldamage;
-			}
+		case RK_IGNITIONBREAK:
+			// 3x3 cell Damage = ATK [{(Skill Level x 300) x (1 + [(Caster's Base Level - 100) / 100])}] %
+			// 7x7 cell Damage = ATK [{(Skill Level x 250) x (1 + [(Caster's Base Level - 100) / 100])}] %
+			// 11x11 cell Damage = ATK [{(Skill Level x 200) x (1 + [(Caster's Base Level - 100) / 100])}] %
+			i = distance_bl(src,target);
+			if (i < 2)
+				skillratio += -100 + 300 * skill_lv;
+			else if (i < 4)
+				skillratio += -100 + 250 * skill_lv;
+			else
+				skillratio += -100 + 200 * skill_lv;
+			skillratio = skillratio * status_get_lv(src) / 100;
+			// Elemental check, 1.5x damage if your weapon element is fire.
+			if (sstatus->rhw.ele == ELE_FIRE)
+				skillratio += 100 * skill_lv;
 			break;
 			break;
 		case RK_STORMBLAST:
 		case RK_STORMBLAST:
 			skillratio += -100 + (((sd) ? pc_checkskill(sd,RK_RUNEMASTERY) : 0) + (status_get_int(src) / 8)) * 100; // ATK = [{Rune Mastery Skill Level + (Caster's INT / 8)} x 100] %
 			skillratio += -100 + (((sd) ? pc_checkskill(sd,RK_RUNEMASTERY) : 0) + (status_get_int(src) / 8)) * 100; // ATK = [{Rune Mastery Skill Level + (Caster's INT / 8)} x 100] %
@@ -7818,7 +7816,7 @@ static const struct _battle_data {
 	{ "max_heal_lv",                        &battle_config.max_heal_lv,                     11,     1,      INT_MAX,        },
 	{ "max_heal_lv",                        &battle_config.max_heal_lv,                     11,     1,      INT_MAX,        },
 	{ "max_heal",                           &battle_config.max_heal,                        9999,   0,      INT_MAX,        },
 	{ "max_heal",                           &battle_config.max_heal,                        9999,   0,      INT_MAX,        },
 	{ "combo_delay_rate",                   &battle_config.combo_delay_rate,                100,    0,      INT_MAX,        },
 	{ "combo_delay_rate",                   &battle_config.combo_delay_rate,                100,    0,      INT_MAX,        },
-	{ "item_check",                         &battle_config.item_check,                      0,      0,      7,              },
+	{ "item_check",                         &battle_config.item_check,                      0x0,    0x0,    0x7,            },
 	{ "item_use_interval",                  &battle_config.item_use_interval,               100,    0,      INT_MAX,        },
 	{ "item_use_interval",                  &battle_config.item_use_interval,               100,    0,      INT_MAX,        },
 	{ "cashfood_use_interval",              &battle_config.cashfood_use_interval,           60000,  0,      INT_MAX,        },
 	{ "cashfood_use_interval",              &battle_config.cashfood_use_interval,           60000,  0,      INT_MAX,        },
 	{ "wedding_modifydisplay",              &battle_config.wedding_modifydisplay,           0,      0,      1,              },
 	{ "wedding_modifydisplay",              &battle_config.wedding_modifydisplay,           0,      0,      1,              },

+ 5 - 3
src/map/npc.c

@@ -263,9 +263,11 @@ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat
 	struct map_session_data* sd = NULL;
 	struct map_session_data* sd = NULL;
 	unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
 	unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
 	int cur_tick = gettick(); //ensure we are on last tick
 	int cur_tick = gettick(); //ensure we are on last tick
-	if( (sd = map_id2sd(id)) == NULL || !sd->npc_id ) {
-		if( sd ) sd->npc_idle_timer = INVALID_TIMER;
-		return 0;//Not logged in anymore OR no longer attached to a npc
+
+	if ((sd = map_id2sd(id)) == NULL || !sd->npc_id || sd->state.ignoretimeout) {
+		if (sd)
+			sd->npc_idle_timer = INVALID_TIMER;
+		return 0; // Not logged in anymore OR no longer attached to a NPC OR using 'ignoretimeout' script command
 	}
 	}
 
 
 	switch( sd->npc_idle_type ) {
 	switch( sd->npc_idle_type ) {

+ 31 - 27
src/map/pc.c

@@ -1125,6 +1125,7 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
 	sd->npc_idle_timer = INVALID_TIMER;
 	sd->npc_idle_timer = INVALID_TIMER;
 	sd->npc_idle_tick = tick;
 	sd->npc_idle_tick = tick;
 	sd->npc_idle_type = NPCT_INPUT;
 	sd->npc_idle_type = NPCT_INPUT;
+	sd->state.ignoretimeout = false;
 #endif
 #endif
 
 
 	sd->canuseitem_tick = tick;
 	sd->canuseitem_tick = tick;
@@ -1412,7 +1413,6 @@ void pc_reg_received(struct map_session_data *sd)
 	if (!chrif_auth_finished(sd))
 	if (!chrif_auth_finished(sd))
 		ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
 		ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
 
 
-	pc_check_available_item(sd); // Check for invalid(ated) items.
 	pc_load_combo(sd);
 	pc_load_combo(sd);
 
 
 	status_calc_pc(sd, (enum e_status_calc_opt)(SCO_FIRST|SCO_FORCE));
 	status_calc_pc(sd, (enum e_status_calc_opt)(SCO_FIRST|SCO_FORCE));
@@ -9650,6 +9650,8 @@ void pc_checkitem(struct map_session_data *sd) {
 	if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
 	if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
 		return;
 		return;
 
 
+	pc_check_available_item(sd); // Check for invalid(ated) items.
+
 	for( i = 0; i < MAX_INVENTORY; i++ ) {
 	for( i = 0; i < MAX_INVENTORY; i++ ) {
 		it = sd->status.inventory[i];
 		it = sd->status.inventory[i];
 
 
@@ -9679,62 +9681,64 @@ void pc_checkitem(struct map_session_data *sd) {
 /*==========================================
 /*==========================================
  * Checks for unavailable items and removes them.
  * Checks for unavailable items and removes them.
  *------------------------------------------*/
  *------------------------------------------*/
-void pc_check_available_item(struct map_session_data *sd) {
-	int i, it;
+void pc_check_available_item(struct map_session_data *sd)
+{
+	int i;
+	unsigned short nameid;
 	char output[256];
 	char output[256];
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 
 
-	if( battle_config.item_check&1 ) { // Check for invalid(ated) items in inventory.
-		for( i = 0; i < MAX_INVENTORY; i++ ) {
-			it = sd->status.inventory[i].nameid;
+	if (battle_config.item_check&0x1) { // Check for invalid(ated) items in inventory.
+		for(i = 0; i < MAX_INVENTORY; i++) {
+			nameid = sd->status.inventory[i].nameid;
 
 
-			if (!it)
+			if (!nameid)
 				continue;
 				continue;
-			if (!itemdb_available(it)) {
-				sprintf(output, msg_txt(sd, 709), it); // Item %hu has been removed from your inventory.
+			if (!itemdb_available(nameid)) {
+				sprintf(output, msg_txt(sd, 709), nameid); // Item %hu has been removed from your inventory.
 				clif_displaymessage(sd->fd, output);
 				clif_displaymessage(sd->fd, output);
-				ShowWarning("Removed invalid/disabled item id %hu from inventory (amount=%d, char_id=%d).\n", it, sd->status.inventory[i].amount, sd->status.char_id);
+				ShowWarning("Removed invalid/disabled item id %hu from inventory (amount=%d, char_id=%d).\n", nameid, sd->status.inventory[i].amount, sd->status.char_id);
 				pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
 				pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
 				continue;
 				continue;
 			}
 			}
-			if (!sd->status.inventory[i].unique_id && !itemdb_isstackable(it))
+			if (!sd->status.inventory[i].unique_id && !itemdb_isstackable(nameid))
 				sd->status.inventory[i].unique_id = pc_generate_unique_id(sd);
 				sd->status.inventory[i].unique_id = pc_generate_unique_id(sd);
 		}
 		}
 	}
 	}
 
 
-	if( battle_config.item_check&2 ) { // Check for invalid(ated) items in cart.
-		for( i = 0; i < MAX_CART; i++ ) {
-			it = sd->status.cart[i].nameid;
+	if (battle_config.item_check&0x2) { // Check for invalid(ated) items in cart.
+		for(i = 0; i < MAX_CART; i++) {
+			nameid = sd->status.cart[i].nameid;
 
 
-			if (!it)
+			if (!nameid)
 				continue;
 				continue;
-			if (!itemdb_available(it)) {
-				sprintf(output, msg_txt(sd, 710), it); // Item %hu has been removed from your cart.
+			if (!itemdb_available(nameid)) {
+				sprintf(output, msg_txt(sd, 710), nameid); // Item %hu has been removed from your cart.
 				clif_displaymessage(sd->fd, output);
 				clif_displaymessage(sd->fd, output);
-				ShowWarning("Removed invalid/disabled item id %hu from cart (amount=%d, char_id=%d).\n", it, sd->status.cart[i].amount, sd->status.char_id);
+				ShowWarning("Removed invalid/disabled item id %hu from cart (amount=%d, char_id=%d).\n", nameid, sd->status.cart[i].amount, sd->status.char_id);
 				pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
 				pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
 				continue;
 				continue;
 			}
 			}
-			if (!sd->status.cart[i].unique_id && !itemdb_isstackable(it))
+			if (!sd->status.cart[i].unique_id && !itemdb_isstackable(nameid))
 				sd->status.cart[i].unique_id = pc_generate_unique_id(sd);
 				sd->status.cart[i].unique_id = pc_generate_unique_id(sd);
 		}
 		}
 	}
 	}
 
 
-	if( battle_config.item_check&4 ) { // Check for invalid(ated) items in storage.
-		for( i = 0; i < sd->storage_size; i++ ) {
-			it = sd->status.storage.items[i].nameid;
+	if (battle_config.item_check&0x4) { // Check for invalid(ated) items in storage.
+		for(i = 0; i < sd->storage_size; i++) {
+			nameid = sd->status.storage.items[i].nameid;
 
 
-			if (!it)
+			if (!nameid)
 				continue;
 				continue;
-			if (!itemdb_available(it)) {
-				sprintf(output, msg_txt(sd, 711), it); // Item %hu has been removed from your storage.
+			if (!itemdb_available(nameid)) {
+				sprintf(output, msg_txt(sd, 711), nameid); // Item %hu has been removed from your storage.
 				clif_displaymessage(sd->fd, output);
 				clif_displaymessage(sd->fd, output);
-				ShowWarning("Removed invalid/disabled item id %hu from storage (amount=%d, char_id=%d).\n", it, sd->status.storage.items[i].amount, sd->status.char_id);
+				ShowWarning("Removed invalid/disabled item id %hu from storage (amount=%d, char_id=%d).\n", nameid, sd->status.storage.items[i].amount, sd->status.char_id);
 				storage_delitem(sd, i, sd->status.storage.items[i].amount);
 				storage_delitem(sd, i, sd->status.storage.items[i].amount);
 				continue;
 				continue;
 			}
 			}
-			if (!sd->status.storage.items[i].unique_id && !itemdb_isstackable(it))
+			if (!sd->status.storage.items[i].unique_id && !itemdb_isstackable(nameid))
 				sd->status.storage.items[i].unique_id = pc_generate_unique_id(sd);
 				sd->status.storage.items[i].unique_id = pc_generate_unique_id(sd);
  		}
  		}
 	}
 	}

+ 1 - 1
src/map/pc.h

@@ -210,7 +210,6 @@ struct map_session_data {
 		unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
 		unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
 		unsigned int size :2; // for tiny/large types
 		unsigned int size :2; // for tiny/large types
 		unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
 		unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
-		unsigned int blockedmove :1;
 		unsigned int using_fake_npc :1;
 		unsigned int using_fake_npc :1;
 		unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
 		unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
 		unsigned int killer : 1;
 		unsigned int killer : 1;
@@ -239,6 +238,7 @@ struct map_session_data {
 		unsigned int hpmeter_visible : 1;
 		unsigned int hpmeter_visible : 1;
 		unsigned disable_atcommand_on_npc : 1; //Prevent to use atcommand while talking with NPC [Kichi]
 		unsigned disable_atcommand_on_npc : 1; //Prevent to use atcommand while talking with NPC [Kichi]
 		uint8 isBoundTrading; // Player is currently add bound item to trade list [Cydh]
 		uint8 isBoundTrading; // Player is currently add bound item to trade list [Cydh]
+		bool ignoretimeout; // Prevent the SECURE_NPCTIMEOUT function from closing current script.
 	} state;
 	} state;
 	struct {
 	struct {
 		unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
 		unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;

+ 40 - 12
src/map/script.c

@@ -16440,19 +16440,20 @@ BUILDIN_FUNC(rid2name)
 
 
 BUILDIN_FUNC(pcblockmove)
 BUILDIN_FUNC(pcblockmove)
 {
 {
-	int id, flag;
-	TBL_PC *sd = NULL;
-
-	id = script_getnum(st,2);
-	flag = script_getnum(st,3);
+	struct block_list *bl = NULL;
 
 
-	if(id)
-		sd = map_id2sd(id);
+	if (script_getnum(st, 2))
+		bl = map_id2bl(script_getnum(st,2));
 	else
 	else
-		sd = script_rid2sd(st);
+		bl = map_id2bl(st->rid);
+
+	if (bl) {
+		struct unit_data *ud = unit_bl2ud(bl);
+
+		if (ud)
+			ud->state.blockedmove = script_getnum(st,3) > 0;
+	}
 
 
-	if(sd)
-		sd->state.blockedmove = flag > 0;
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
@@ -20349,6 +20350,31 @@ BUILDIN_FUNC(showscript) {
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
+/**
+ * Ignore the SECURE_NPCTIMEOUT function.
+ * ignoretimeout <flag>{,<char_id>};
+ */
+BUILDIN_FUNC(ignoretimeout)
+{
+#ifdef SECURE_NPCTIMEOUT
+	struct map_session_data *sd = NULL;
+
+	if (script_hasdata(st,3)) {
+		if (!script_isstring(st,3))
+			sd = map_charid2sd(script_getnum(st,3));
+		else
+			sd = map_nick2sd(script_getstr(st,3));
+	} else
+		sd = script_rid2sd(st);
+
+	if (!sd)
+		return SCRIPT_CMD_FAILURE;
+
+	sd->state.ignoretimeout = script_getnum(st,2) > 0;
+#endif
+	return SCRIPT_CMD_SUCCESS;
+}
+
 #include "../custom/script.inc"
 #include "../custom/script.inc"
 
 
 // declarations that were supposed to be exported from npc_chat.c
 // declarations that were supposed to be exported from npc_chat.c
@@ -20751,7 +20777,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(pcstopfollow,"i"),
 	BUILDIN_DEF(pcstopfollow,"i"),
 	BUILDIN_DEF(pcblockmove,"ii"),
 	BUILDIN_DEF(pcblockmove,"ii"),
 	// <--- [zBuffer] List of player cont commands
 	// <--- [zBuffer] List of player cont commands
-	// [zBuffer] List of mob control commands --->
+	// [zBuffer] List of unit control commands --->
 	BUILDIN_DEF(getunittype,"i"),
 	BUILDIN_DEF(getunittype,"i"),
 	BUILDIN_DEF(getunitname,"i"),
 	BUILDIN_DEF(getunitname,"i"),
 	BUILDIN_DEF(setunitname,"is"),
 	BUILDIN_DEF(setunitname,"is"),
@@ -20764,11 +20790,12 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(unitattack,"iv?"),
 	BUILDIN_DEF(unitattack,"iv?"),
 	BUILDIN_DEF(unitstopattack,"i"),
 	BUILDIN_DEF(unitstopattack,"i"),
 	BUILDIN_DEF(unitstopwalk,"i"),
 	BUILDIN_DEF(unitstopwalk,"i"),
+	BUILDIN_DEF2(pcblockmove,"unitblockmove","ii"),
 	BUILDIN_DEF(unittalk,"is"),
 	BUILDIN_DEF(unittalk,"is"),
 	BUILDIN_DEF(unitemote,"ii"),
 	BUILDIN_DEF(unitemote,"ii"),
 	BUILDIN_DEF(unitskilluseid,"ivi??"), // originally by Qamera [Celest]
 	BUILDIN_DEF(unitskilluseid,"ivi??"), // originally by Qamera [Celest]
 	BUILDIN_DEF(unitskillusepos,"iviii?"), // [Celest]
 	BUILDIN_DEF(unitskillusepos,"iviii?"), // [Celest]
-// <--- [zBuffer] List of mob control commands
+// <--- [zBuffer] List of unit control commands
 	BUILDIN_DEF(sleep,"i"),
 	BUILDIN_DEF(sleep,"i"),
 	BUILDIN_DEF(sleep2,"i"),
 	BUILDIN_DEF(sleep2,"i"),
 	BUILDIN_DEF(awake,"s"),
 	BUILDIN_DEF(awake,"s"),
@@ -20908,6 +20935,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(getattachedrid,""),
 	BUILDIN_DEF(getattachedrid,""),
 	BUILDIN_DEF(getvar,"vi"),
 	BUILDIN_DEF(getvar,"vi"),
 	BUILDIN_DEF(showscript,"s?"),
 	BUILDIN_DEF(showscript,"s?"),
+	BUILDIN_DEF(ignoretimeout,"i?"),
 
 
 #include "../custom/script_def.inc"
 #include "../custom/script_def.inc"
 
 

+ 93 - 63
src/map/skill.c

@@ -397,18 +397,22 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
 	switch( skill_id ) {
 	switch( skill_id ) {
 		case BA_APPLEIDUN:
 		case BA_APPLEIDUN:
 #ifdef RENEWAL
 #ifdef RENEWAL
-			hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+			hp = 100 + 5 * skill_lv + 5 * (status_get_vit(src) / 10); // HP recovery
 #else
 #else
-			hp = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+			hp = 30 + 5 * skill_lv + 5 * (status_get_vit(src) / 10); // HP recovery
 #endif
 #endif
 			if( sd )
 			if( sd )
-				hp += 5*pc_checkskill(sd,BA_MUSICALLESSON);
+				hp += 5 * pc_checkskill(sd,BA_MUSICALLESSON);
 			break;
 			break;
 		case PR_SANCTUARY:
 		case PR_SANCTUARY:
-			hp = (skill_lv>6)?777:skill_lv*100;
+			hp = (skill_lv > 6) ? 777 : skill_lv * 100;
 			break;
 			break;
 		case NPC_EVILLAND:
 		case NPC_EVILLAND:
-			hp = (skill_lv>6)?666:skill_lv*100;
+			hp = (skill_lv > 6) ? 666 : skill_lv * 100;
+			break;
+		case AB_HIGHNESSHEAL:
+			hp = ((status_get_lv(src) + status_get_int(src)) / 8) * (4 + ((sd ? pc_checkskill(sd,AL_HEAL) : 1) * 8));
+			hp = (hp * (17 + 3 * skill_lv)) / 10;
 			break;
 			break;
 		default:
 		default:
 			if (skill_lv >= battle_config.max_heal_lv)
 			if (skill_lv >= battle_config.max_heal_lv)
@@ -418,12 +422,10 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
 			 * Renewal Heal Formula
 			 * Renewal Heal Formula
 			 * Formula: ( [(Base Level + INT) / 5] x 30 ) x (Heal Level / 10) x (Modifiers) + MATK
 			 * Formula: ( [(Base Level + INT) / 5] x 30 ) x (Heal Level / 10) x (Modifiers) + MATK
 			 */
 			 */
-			hp = (status_get_lv(src) + status_get_int(src)) / 5 * 30  * (skill_id == AB_HIGHNESSHEAL ? ((sd) ? pc_checkskill(sd,AL_HEAL) : skill_get_max(AL_HEAL)) : skill_lv) / 10;
+			hp = (status_get_lv(src) + status_get_int(src)) / 5 * 30 * skill_lv / 10;
 #else
 #else
-			hp = (status_get_lv(src) + status_get_int(src)) / 8 * (4 + ( (skill_id == AB_HIGHNESSHEAL ? ((sd) ? pc_checkskill(sd,AL_HEAL) : skill_get_max(AL_HEAL)) : skill_lv) * 8));
+			hp = (status_get_lv(src) + status_get_int(src)) / 8 * (4 + (skill_lv * 8));
 #endif
 #endif
-			if (skill_id == AB_HIGHNESSHEAL)
-				hp = hp * ( 17 + 3 * skill_lv ) / 10;
 			if( sd && ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) )
 			if( sd && ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) )
 				hp += hp * skill * 2 / 100;
 				hp += hp * skill * 2 / 100;
 			else if( src->type == BL_HOM && (skill = hom_checkskill(((TBL_HOM*)src), HLIF_BRAIN)) > 0 )
 			else if( src->type == BL_HOM && (skill = hom_checkskill(((TBL_HOM*)src), HLIF_BRAIN)) > 0 )
@@ -437,10 +439,10 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
 		hp >>= 1;
 		hp >>= 1;
 
 
 	if( sd && (skill = pc_skillheal_bonus(sd, skill_id)) )
 	if( sd && (skill = pc_skillheal_bonus(sd, skill_id)) )
-		hp += hp*skill/100;
+		hp += hp * skill / 100;
 
 
 	if( tsd && (skill = pc_skillheal2_bonus(tsd, skill_id)) )
 	if( tsd && (skill = pc_skillheal2_bonus(tsd, skill_id)) )
-		hp += hp*skill/100;
+		hp += hp * skill / 100;
 
 
 	if( sc && sc->data[SC_OFFERTORIUM] && (skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL ||
 	if( sc && sc->data[SC_OFFERTORIUM] && (skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL ||
 		skill_id == PR_SANCTUARY || skill_id == AL_HEAL) )
 		skill_id == PR_SANCTUARY || skill_id == AL_HEAL) )
@@ -460,8 +462,10 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
 	// MATK part of the RE heal formula [malufett]
 	// MATK part of the RE heal formula [malufett]
 	// Note: in this part matk bonuses from items or skills are not applied
 	// Note: in this part matk bonuses from items or skills are not applied
 	switch( skill_id ) {
 	switch( skill_id ) {
-		case BA_APPLEIDUN:	case PR_SANCTUARY:
-		case NPC_EVILLAND:	break;
+		case BA_APPLEIDUN:
+		case PR_SANCTUARY:
+		case NPC_EVILLAND:
+			break;
 		default:
 		default:
 			{
 			{
 				struct status_data *status = status_get_status_data(src);
 				struct status_data *status = status_get_status_data(src);
@@ -2713,6 +2717,24 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
 			case WL_CHAINLIGHTNING_ATK:
 			case WL_CHAINLIGHTNING_ATK:
 				skill_id = WL_CHAINLIGHTNING;
 				skill_id = WL_CHAINLIGHTNING;
 				break;
 				break;
+			case WL_TETRAVORTEX_FIRE:
+			case WL_TETRAVORTEX_WATER:
+			case WL_TETRAVORTEX_WIND:
+			case WL_TETRAVORTEX_GROUND:
+				skill_id = WL_TETRAVORTEX;
+				break;
+			case WL_SUMMON_ATK_FIRE:
+				skill_id = WL_SUMMONFB;
+				break;
+			case WL_SUMMON_ATK_WIND:
+				skill_id = WL_SUMMONBL;
+				break;
+			case WL_SUMMON_ATK_WATER:
+				skill_id = WL_SUMMONWB;
+				break;
+			case WL_SUMMON_ATK_GROUND:
+				skill_id = WL_SUMMONSTONE;
+				break;
 			case LG_OVERBRAND_BRANDISH:
 			case LG_OVERBRAND_BRANDISH:
 			case LG_OVERBRAND_PLUSATK:
 			case LG_OVERBRAND_PLUSATK:
 				skill_id = LG_OVERBRAND;
 				skill_id = LG_OVERBRAND;
@@ -3207,6 +3229,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 		case WM_REVERBERATION_MAGIC:
 		case WM_REVERBERATION_MAGIC:
 			dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
 			dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
 			break;
 			break;
+		case WZ_SIGHTBLASTER:
 		case HT_CLAYMORETRAP:
 		case HT_CLAYMORETRAP:
 		case HT_BLASTMINE:
 		case HT_BLASTMINE:
 		case HT_FLASHER:
 		case HT_FLASHER:
@@ -3220,9 +3243,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 		case HT_LANDMINE:
 		case HT_LANDMINE:
 			dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type);
 			dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type);
 			break;
 			break;
-		case WZ_SIGHTBLASTER:
-			dmg.dmotion = clif_skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, flag&SD_LEVEL?-1:skill_lv, 5);
-			break;
 		case RL_R_TRIP_PLUSATK:
 		case RL_R_TRIP_PLUSATK:
 		case RL_BANISHING_BUSTER:
 		case RL_BANISHING_BUSTER:
 		case RL_S_STORM:
 		case RL_S_STORM:
@@ -3468,9 +3488,11 @@ static int skill_check_unit_range_sub(struct block_list *bl, va_list ap)
 		case RA_ICEBOUNDTRAP:
 		case RA_ICEBOUNDTRAP:
 		case SC_DIMENSIONDOOR:
 		case SC_DIMENSIONDOOR:
 		case SC_BLOODYLUST:
 		case SC_BLOODYLUST:
+		case WM_REVERBERATION:
 		case GN_THORNS_TRAP:
 		case GN_THORNS_TRAP:
 		case GN_HELLS_PLANT:
 		case GN_HELLS_PLANT:
 		case RL_B_TRAP:
 		case RL_B_TRAP:
+		case SC_ESCAPE:
 			//Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set)
 			//Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set)
 			if (skill_id != g_skill_id && !(skill_get_inf2(g_skill_id)&INF2_TRAP) && g_skill_id != AS_VENOMDUST && g_skill_id != MH_POISON_MIST)
 			if (skill_id != g_skill_id && !(skill_get_inf2(g_skill_id)&INF2_TRAP) && g_skill_id != AS_VENOMDUST && g_skill_id != MH_POISON_MIST)
 				return 0;
 				return 0;
@@ -3878,7 +3900,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
 					break;
 					break;
 				case WM_REVERBERATION_MELEE:
 				case WM_REVERBERATION_MELEE:
 				case WM_REVERBERATION_MAGIC:
 				case WM_REVERBERATION_MAGIC:
-					skill_attack(skill_get_type(skl->skill_id),src, src, target, skl->skill_id, skl->skill_lv, 0, SD_LEVEL);
+					skill_castend_damage_id(src,target,skl->skill_id,skl->skill_lv,tick,skl->flag);
 					break;
 					break;
 				case SC_FATALMENACE:
 				case SC_FATALMENACE:
 					if( src == target ) // Casters Part
 					if( src == target ) // Casters Part
@@ -4071,12 +4093,11 @@ static int skill_active_reverberation(struct block_list *bl, va_list ap) {
 	if (bl->type != BL_SKILL)
 	if (bl->type != BL_SKILL)
 		return 0;
 		return 0;
 	if (su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION) {
 	if (su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION) {
-		clif_changetraplook(bl, UNT_USED_TRAPS);
 		map_foreachinrange(skill_trap_splash, bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, gettick());
 		map_foreachinrange(skill_trap_splash, bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, gettick());
-		su->limit = DIFF_TICK(gettick(), sg->tick) + 1500;
+		su->limit = DIFF_TICK(gettick(), sg->tick);
 		sg->unit_id = UNT_USED_TRAPS;
 		sg->unit_id = UNT_USED_TRAPS;
 	}
 	}
-	return 0;
+	return 1;
 }
 }
 
 
 static int skill_reveal_trap(struct block_list *bl, va_list ap)
 static int skill_reveal_trap(struct block_list *bl, va_list ap)
@@ -4480,8 +4501,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case SR_FLASHCOMBO_ATK_STEP4:
 	case SR_FLASHCOMBO_ATK_STEP4:
 	case SR_WINDMILL:
 	case SR_WINDMILL:
 	case SR_RIDEINLIGHTNING:
 	case SR_RIDEINLIGHTNING:
-	case WM_SOUND_OF_DESTRUCTION:
-	case WM_REVERBERATION:
+	case WM_REVERBERATION_MELEE:
+	case WM_REVERBERATION_MAGIC:
 	case SO_VARETYR_SPEAR:
 	case SO_VARETYR_SPEAR:
 	case GN_CART_TORNADO:
 	case GN_CART_TORNADO:
 	case GN_CARTCANNON:
 	case GN_CARTCANNON:
@@ -4522,6 +4543,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 				case NPC_EARTHQUAKE://FIXME: Isn't EarthQuake a ground skill after all?
 				case NPC_EARTHQUAKE://FIXME: Isn't EarthQuake a ground skill after all?
 					skill_addtimerskill(src,tick+250,src->id,0,0,skill_id,skill_lv,2,flag|BCT_ENEMY|SD_SPLASH|1);
 					skill_addtimerskill(src,tick+250,src->id,0,0,skill_id,skill_lv,2,flag|BCT_ENEMY|SD_SPLASH|1);
 					break;
 					break;
+				case WM_REVERBERATION_MELEE:
+				case WM_REVERBERATION_MAGIC:
+					skill_area_temp[1] = 0;
+					break;
 				default:
 				default:
 					break;
 					break;
 			}
 			}
@@ -4543,7 +4568,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 				skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, (skill_id == AS_SPLASHER)?1:skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill_area_sub_count);
 				skill_area_temp[0] = map_foreachinrange(skill_area_sub, bl, (skill_id == AS_SPLASHER)?1:skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill_area_sub_count);
 
 
 			// recursive invocation of skill_castend_damage_id() with flag|1
 			// recursive invocation of skill_castend_damage_id() with flag|1
-			map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+			map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), (skill_id == WM_REVERBERATION_MELEE || skill_id == WM_REVERBERATION_MAGIC) ? BL_CHAR : splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
 			if( skill_id == AS_SPLASHER ) {
 			if( skill_id == AS_SPLASHER ) {
 				map_freeblock_unlock(); // Don't consume a second gemstone.
 				map_freeblock_unlock(); // Don't consume a second gemstone.
 				return 0;
 				return 0;
@@ -9620,7 +9645,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			sc_start2(src,bl,type,skill_area_temp[5],skill_lv,src->id,skill_area_temp[6]);
 			sc_start2(src,bl,type,skill_area_temp[5],skill_lv,src->id,skill_area_temp[6]);
 		else {
 		else {
 			// Success chance: (Skill Level x 6) + (Voice Lesson Skill Level x 2) + (Caster’s Job Level / 2) %
 			// Success chance: (Skill Level x 6) + (Voice Lesson Skill Level x 2) + (Caster’s Job Level / 2) %
-			skill_area_temp[5] = skill_lv * 6 + ((sd) ? pc_checkskill(sd, WM_LESSON) : skill_get_max(WM_LESSON)) * 2 + (sd ? sd->status.job_level : 50) / 2;
+			skill_area_temp[5] = skill_lv * 6 + ((sd) ? pc_checkskill(sd, WM_LESSON) : 1) * 2 + (sd ? sd->status.job_level : 50) / 2;
 			skill_area_temp[6] = skill_get_time(skill_id,skill_lv);
 			skill_area_temp[6] = skill_get_time(skill_id,skill_lv);
 			map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv), BL_CHAR|BL_SKILL, src, skill_id, skill_lv, tick, flag|BCT_ALL|BCT_WOS|1, skill_castend_nodamage_id);
 			map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv), BL_CHAR|BL_SKILL, src, skill_id, skill_lv, tick, flag|BCT_ALL|BCT_WOS|1, skill_castend_nodamage_id);
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -9834,8 +9859,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			// Success chance: [(15 + 5 * Skill Level) + ( Caster's INT / 5 ) + ( Caster's Job Level / 5 ) - ( Target's INT / 6 ) - ( Target's LUK / 10 )] %
 			// Success chance: [(15 + 5 * Skill Level) + ( Caster's INT / 5 ) + ( Caster's Job Level / 5 ) - ( Target's INT / 6 ) - ( Target's LUK / 10 )] %
 			int rate = (15 + 5 * skill_lv) * 1000 + status_get_int(src) * 200 + (sd ? sd->status.job_level * 200 : 0) - status_get_int(bl) * 1000 / 6 - status_get_luk(bl) * 100;
 			int rate = (15 + 5 * skill_lv) * 1000 + status_get_int(src) * 200 + (sd ? sd->status.job_level * 200 : 0) - status_get_int(bl) * 1000 / 6 - status_get_luk(bl) * 100;
 			struct status_data *bstatus = status_get_base_status(bl);
 			struct status_data *bstatus = status_get_base_status(bl);
-			// Resistance: {(Target’s Base Level / 20) + (Target’s Base INT / 40)} seconds
-			int duration = skill_get_time(skill_id, skill_lv) - (status_get_baselevel_limit(bl, 150) * 50 + bstatus->int_ * 25);
+			// Resistance: {(Target's Base Level / 20) + (Target's Base INT / 40)} seconds
+			int duration = skill_get_time(skill_id, skill_lv) - (status_get_lv(bl) * 50 + bstatus->int_ * 25);
 			clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
 			clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
 			status_change_start(src,bl,type,rate,skill_lv,0,0,0,max(duration,5000),SCSTART_NORATEDEF|SCSTART_NOTICKDEF); // Avoid general resistance
 			status_change_start(src,bl,type,rate,skill_lv,0,0,0,max(duration,5000),SCSTART_NORATEDEF|SCSTART_NOTICKDEF); // Avoid general resistance
 		}
 		}
@@ -9844,8 +9869,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case WM_LULLABY_DEEPSLEEP:
 	case WM_LULLABY_DEEPSLEEP:
 		if (flag&1) {
 		if (flag&1) {
 			struct status_data *bstatus = status_get_base_status(bl);
 			struct status_data *bstatus = status_get_base_status(bl);
-			// Resistance: {(Target’s Base Level / 20) + (Target’s Base INT / 20)} seconds
-			int duration = skill_area_temp[6] - (status_get_baselevel_limit(bl, 150) * 50 + bstatus->int_ * 50);
+			// Resistance: {(Target's Base Level / 20) + (Target's Base INT / 20)} seconds
+			int duration = skill_area_temp[6] - (status_get_lv(bl) * 50 + bstatus->int_ * 50);
 			status_change_start(src,bl,type,skill_area_temp[5],skill_lv,0,0,0,max(duration,5000),SCSTART_NORATEDEF|SCSTART_NOTICKDEF); // Avoid general resistance
 			status_change_start(src,bl,type,skill_area_temp[5],skill_lv,0,0,0,max(duration,5000),SCSTART_NORATEDEF|SCSTART_NOTICKDEF); // Avoid general resistance
 		}
 		}
 		else {
 		else {
@@ -10666,6 +10691,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
 					return skill_castend_pos(tid,tick,id,data);
 					return skill_castend_pos(tid,tick,id,data);
 				}
 				}
 			case GN_WALLOFTHORN:
 			case GN_WALLOFTHORN:
+			case SC_ESCAPE:
 				ud->skillx = target->x;
 				ud->skillx = target->x;
 				ud->skilly = target->y;
 				ud->skilly = target->y;
 				ud->skilltimer = tid;
 				ud->skilltimer = tid;
@@ -11595,9 +11621,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
 		break;
 		break;
 
 
 	case SC_ESCAPE:
 	case SC_ESCAPE:
-		clif_skill_nodamage(src,src,skill_id,-1,1);
-		skill_unitsetting(src,HT_ANKLESNARE,skill_lv,x,y,2);
+		clif_skill_nodamage(src,src,skill_id,skill_lv,1);
+		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
 		skill_addtimerskill(src,tick,src->id,0,0,skill_id,skill_lv,0,0);
 		skill_addtimerskill(src,tick,src->id,0,0,skill_id,skill_lv,0,0);
+		flag |= 1;
 		break;
 		break;
 
 
 	case LG_OVERBRAND: {
 	case LG_OVERBRAND: {
@@ -11636,8 +11663,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
 		break;
 		break;
 
 
 	case WM_GREAT_ECHO:
 	case WM_GREAT_ECHO:
-		flag|=1; // Should counsume 1 item per skill usage.
-		map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill_castend_damage_id);
+	case WM_SOUND_OF_DESTRUCTION:
+		i = skill_get_splash(skill_id,skill_lv);
+		map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
 		break;
 		break;
 
 
 	case WM_SEVERE_RAINSTORM:
 	case WM_SEVERE_RAINSTORM:
@@ -12144,12 +12172,11 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 			&& (src->type&battle_config.vs_traps_bctall))
 			&& (src->type&battle_config.vs_traps_bctall))
 			target = BCT_ALL;
 			target = BCT_ALL;
 		break;
 		break;
-	case HT_ANKLESNARE:
-		if( flag&2 ) val3 = SC_ESCAPE;
 	case HT_SKIDTRAP:
 	case HT_SKIDTRAP:
 	case MA_SKIDTRAP:
 	case MA_SKIDTRAP:
 		//Save position of caster
 		//Save position of caster
 		val1 = ((src->x)<<16)|(src->y);
 		val1 = ((src->x)<<16)|(src->y);
+	case HT_ANKLESNARE:
 	case HT_SHOCKWAVE:
 	case HT_SHOCKWAVE:
 	case HT_SANDMAN:
 	case HT_SANDMAN:
 	case MA_SANDMAN:
 	case MA_SANDMAN:
@@ -12169,6 +12196,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 	case RA_FIRINGTRAP:
 	case RA_FIRINGTRAP:
 	case RA_ICEBOUNDTRAP:
 	case RA_ICEBOUNDTRAP:
 	case RL_B_TRAP:
 	case RL_B_TRAP:
+	case SC_ESCAPE:
 		{
 		{
 			struct skill_condition req = skill_get_requirement(sd,skill_id,skill_lv);
 			struct skill_condition req = skill_get_requirement(sd,skill_id,skill_lv);
 			ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY));
 			ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY));
@@ -12344,11 +12372,6 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 	case LG_BANDING:
 	case LG_BANDING:
 		limit = -1;
 		limit = -1;
 		break;
 		break;
-	case WM_REVERBERATION:
-		if( battle_config.vs_traps_bctall && map_flag_vs(src->m) && (src->type&battle_config.vs_traps_bctall) )
-			target = BCT_ALL;
-		val1 = skill_lv + 1;
-		val2 = 1;
 	case WM_POEMOFNETHERWORLD:	// Can't be placed on top of Land Protector.
 	case WM_POEMOFNETHERWORLD:	// Can't be placed on top of Land Protector.
 		if( skill_id == WM_POEMOFNETHERWORLD && map_flag_gvg2(src->m) )
 		if( skill_id == WM_POEMOFNETHERWORLD && map_flag_gvg2(src->m) )
 			target = BCT_ALL;
 			target = BCT_ALL;
@@ -12476,6 +12499,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 			case MA_SKIDTRAP:
 			case MA_SKIDTRAP:
 			case HT_CLAYMORETRAP:
 			case HT_CLAYMORETRAP:
 			case HT_BLASTMINE:
 			case HT_BLASTMINE:
+			case SC_ESCAPE:
 				unit_val1 = 3500;
 				unit_val1 = 3500;
 				break;
 				break;
 
 
@@ -12499,6 +12523,9 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 				if (unit_val1 < 1) unit_val1 = 1;
 				if (unit_val1 < 1) unit_val1 = 1;
 				unit_val2 = 0;
 				unit_val2 = 0;
 				break;
 				break;
+			case WM_REVERBERATION:
+				unit_val1 = 1 + skill_lv;
+				break;
 			case WM_POEMOFNETHERWORLD:
 			case WM_POEMOFNETHERWORLD:
 				unit_val1 = 1 + skill_lv;
 				unit_val1 = 1 + skill_lv;
 				break;
 				break;
@@ -13067,7 +13094,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 
 
 		case UNT_ANKLESNARE:
 		case UNT_ANKLESNARE:
 		case UNT_MANHOLE:
 		case UNT_MANHOLE:
-			if( sg->val2 == 0 && tsc && (sg->unit_id == UNT_ANKLESNARE || bl->id != sg->src_id) ) {
+			if( sg->val2 == 0 && tsc && ((sg->unit_id == UNT_ANKLESNARE && skill_id != SC_ESCAPE) || bl->id != sg->src_id) ) {
 				int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
 				int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
 
 
 				if( status_change_start(ss, bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, SCSTART_NORATEDEF) ) {
 				if( status_change_start(ss, bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, SCSTART_NORATEDEF) ) {
@@ -13386,8 +13413,8 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 
 
 		case UNT_REVERBERATION:
 		case UNT_REVERBERATION:
 			clif_changetraplook(&unit->bl,UNT_USED_TRAPS);
 			clif_changetraplook(&unit->bl,UNT_USED_TRAPS);
-			map_foreachinrange(skill_trap_splash,&unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &unit->bl,tick);
-			sg->limit = DIFF_TICK(tick,sg->tick) + 1500;
+			map_foreachinrange(skill_trap_splash, &unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &unit->bl, tick);
+			sg->limit = DIFF_TICK(tick,sg->tick) + 1000;
 			sg->unit_id = UNT_USED_TRAPS;
 			sg->unit_id = UNT_USED_TRAPS;
 			break;
 			break;
 
 
@@ -13882,11 +13909,10 @@ int64 skill_unit_ondamaged(struct skill_unit *unit, int64 damage)
 		case UNT_ANKLESNARE:
 		case UNT_ANKLESNARE:
 		case UNT_ICEWALL:
 		case UNT_ICEWALL:
 		case UNT_WALLOFTHORN:
 		case UNT_WALLOFTHORN:
+		case UNT_REVERBERATION:
 		case UNT_NETHERWORLD:
 		case UNT_NETHERWORLD:
 			unit->val1 -= (int)cap_value(damage,INT_MIN,INT_MAX);
 			unit->val1 -= (int)cap_value(damage,INT_MIN,INT_MAX);
 			break;
 			break;
-		case UNT_REVERBERATION:
-			unit->val1--;
 		default:
 		default:
 			damage = 0;
 			damage = 0;
 			break;
 			break;
@@ -15461,10 +15487,14 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 					req.itemid[i] = skill_db[idx]->require.itemid[i];
 					req.itemid[i] = skill_db[idx]->require.itemid[i];
 					req.amount[i] = skill_db[idx]->require.amount[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){
+					if (skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0 || skill_id == SC_ESCAPE) {
 						int16 itIndex;
 						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;
+
+						if ((itIndex = pc_search_inventory(sd,req.itemid[i])) < 0 || ( itIndex >= 0 && sd->status.inventory[itIndex].amount < req.amount[i])) {
+							if (skill_id == SC_ESCAPE) // Alloy Trap has priority over normal Trap
+								req.itemid[i] = ITEMID_TRAP;
+							else
+								req.itemid[i] = ITEMID_TRAP_ALLOY;
 							req.amount[i] = 1;
 							req.amount[i] = 1;
 						}
 						}
 						break;
 						break;
@@ -16866,11 +16896,9 @@ static int skill_trap_splash(struct block_list *bl, va_list ap)
 			if( bl->type != BL_PC && !is_boss(bl) )
 			if( bl->type != BL_PC && !is_boss(bl) )
 				sc_start2(ss,bl,SC_ELEMENTALCHANGE,100,sg->skill_lv,skill_get_ele(sg->skill_id,sg->skill_lv),skill_get_time2(sg->skill_id,sg->skill_lv));
 				sc_start2(ss,bl,SC_ELEMENTALCHANGE,100,sg->skill_lv,skill_get_ele(sg->skill_id,sg->skill_lv),skill_get_time2(sg->skill_id,sg->skill_lv));
 			break;
 			break;
-		case UNT_REVERBERATION:
-			if( battle_check_target(src, bl, BCT_ENEMY) > 0 ) {
-				skill_attack(BF_WEAPON, ss, src, bl, WM_REVERBERATION_MELEE, sg->skill_lv,tick, 0);
-				skill_addtimerskill(ss, tick + 200, bl->id, 0, 0, WM_REVERBERATION_MAGIC, sg->skill_lv, BF_MAGIC, SD_LEVEL);
-			}
+		case UNT_REVERBERATION: // For proper skill delay animation when used with Dominion Impulse
+			skill_addtimerskill(ss, tick + status_get_amotion(ss), bl->id, 0, 0, WM_REVERBERATION_MELEE, sg->skill_lv, BF_WEAPON, 0);
+			skill_addtimerskill(ss, tick + status_get_amotion(ss) * 2, bl->id, 0, 0, WM_REVERBERATION_MAGIC, sg->skill_lv, BF_MAGIC, 0);
 			break;
 			break;
 		case UNT_FIRINGTRAP:
 		case UNT_FIRINGTRAP:
 		case UNT_ICEBOUNDTRAP:
 		case UNT_ICEBOUNDTRAP:
@@ -17176,11 +17204,14 @@ int skill_delunit(struct skill_unit* unit)
 
 
 	// perform ondelete actions
 	// perform ondelete actions
 	switch (group->skill_id) {
 	switch (group->skill_id) {
-		case HT_ANKLESNARE: {
+		case HT_ANKLESNARE:
+		case SC_ESCAPE:
+			{
 				struct block_list* target = map_id2bl(group->val2);
 				struct block_list* target = map_id2bl(group->val2);
+				enum sc_type type = status_skill2sc(group->skill_id);
 
 
 				if( target )
 				if( target )
-					status_change_end(target, SC_ANKLE, INVALID_TIMER);
+					status_change_end(target, type, INVALID_TIMER);
 			}
 			}
 			break;
 			break;
 		case WZ_ICEWALL:
 		case WZ_ICEWALL:
@@ -17609,7 +17640,7 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
 
 
 			case UNT_ANKLESNARE:
 			case UNT_ANKLESNARE:
 			case UNT_ELECTRICSHOCKER:
 			case UNT_ELECTRICSHOCKER:
-				if( group->val2 > 0 || group->val3 == SC_ESCAPE ) { //Used Trap doesn't return back to item
+				if (group->val2 > 0) { //Used Trap doesn't return back to item
 					skill_delunit(unit);
 					skill_delunit(unit);
 					break;
 					break;
 				}
 				}
@@ -17683,10 +17714,10 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
 				clif_changetraplook(bl,UNT_USED_TRAPS);
 				clif_changetraplook(bl,UNT_USED_TRAPS);
 				if (group->unit_id == UNT_REVERBERATION)
 				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);
 					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) + 1500;
-				unit->limit = DIFF_TICK(tick,group->tick) + 1500;
+				group->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;
-			break;
+				break;
 
 
 			case UNT_FEINTBOMB: {
 			case UNT_FEINTBOMB: {
 				struct block_list *src = map_id2bl(group->src_id);
 				struct block_list *src = map_id2bl(group->src_id);
@@ -17760,14 +17791,13 @@ 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)
-					unit->limit = DIFF_TICK(tick, group->tick) + 700;
-				break;
 			case UNT_NETHERWORLD:
 			case UNT_NETHERWORLD:
 				if (unit->val1 <= 0) {
 				if (unit->val1 <= 0) {
 					clif_changetraplook(bl,UNT_USED_TRAPS);
 					clif_changetraplook(bl,UNT_USED_TRAPS);
-					group->limit = DIFF_TICK(tick,group->tick)+1000;
-					unit->limit = DIFF_TICK(tick,group->tick)+1000;
+					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;
 					group->unit_id = UNT_USED_TRAPS;
 				}
 				}
 				break;
 				break;

+ 13 - 41
src/map/status.c

@@ -698,6 +698,7 @@ void initChangeTables(void)
 	add_sc( SC_CHAOSPANIC		, SC_CONFUSION		);
 	add_sc( SC_CHAOSPANIC		, SC_CONFUSION		);
 	add_sc( SC_BLOODYLUST		, SC_BERSERK		);
 	add_sc( SC_BLOODYLUST		, SC_BERSERK		);
 	add_sc( SC_FEINTBOMB		, SC__FEINTBOMB		);
 	add_sc( SC_FEINTBOMB		, SC__FEINTBOMB		);
+	add_sc( SC_ESCAPE			, SC_ANKLE			);
 
 
 	/* Sura */
 	/* Sura */
 	add_sc( SR_DRAGONCOMBO			, SC_STUN		);
 	add_sc( SR_DRAGONCOMBO			, SC_STUN		);
@@ -7272,28 +7273,6 @@ void status_change_init(struct block_list *bl)
 	memset(sc, 0, sizeof (struct status_change));
 	memset(sc, 0, sizeof (struct status_change));
 }
 }
 
 
-/**
- * Get base level of bl, cap the value by level_limit
- * @param bl Object [BL_PC|BL_MOB|BL_HOM|BL_MER|BL_ELEM]
- * @param level_limit Level cap
- * @return Base level or level_limit
- **/
-int status_get_baselevel_limit(struct block_list *bl, int level_limit) {
-	int lvl = status_get_lv(bl);
-	return min(lvl, level_limit);
-}
-
-/**
- * Get job level of player, cap the value by level_limit.
- * @param sd Player
- * @param level_limit Level cap
- * @return Job level or level_limit or 0 if not a player
- **/
-int status_get_joblevel_limit(struct map_session_data *sd, int level_limit) {
-	int lvl = sd ? sd->status.job_level : 0;
-	return min(lvl, level_limit);
-}
-
 /**
 /**
  * Applies SC defense to a given status change
  * Applies SC defense to a given status change
  * This function also determines whether or not the status change will be applied
  * This function also determines whether or not the status change will be applied
@@ -7465,8 +7444,8 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 			tick_def2 = (b_status->int_ + status_get_lv(bl))*50; // kRO balance update lists this formula
 			tick_def2 = (b_status->int_ + status_get_lv(bl))*50; // kRO balance update lists this formula
 			break;
 			break;
 		case SC_NETHERWORLD:
 		case SC_NETHERWORLD:
-			// Resistance: {(Target’s Base Level / 50) + (Target’s Job Level / 10)} seconds
-			tick_def2 = status_get_baselevel_limit(bl, 150) * 20 + status_get_joblevel_limit(sd, 50) * 100;
+			// Resistance: {(Target's Base Level / 50) + (Target's Job Level / 10)} seconds
+			tick_def2 = status_get_lv(bl) * 20 + (sd ? sd->status.job_level : 1) * 100;
 			break;
 			break;
 		case SC_MARSHOFABYSS:
 		case SC_MARSHOFABYSS:
 			// 5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second }
 			// 5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second }
@@ -7513,8 +7492,8 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 			tick_def2 = (status->vit + status->luk)*50;
 			tick_def2 = (status->vit + status->luk)*50;
 			break;
 			break;
 		case SC_VOICEOFSIREN:
 		case SC_VOICEOFSIREN:
-			// Resistance: {(Target’s Base Level / 10) + (Target’s Job Level / 5)} seconds
-			tick_def2 = status_get_baselevel_limit(bl, 150) * 100 + status_get_joblevel_limit(sd, 50) * 200;
+			// Resistance: {(Target's Base Level / 10) + (Target's Job Level / 5)} seconds
+			tick_def2 = status_get_lv(bl) * 100 + (sd ? sd->status.job_level : 1) * 200;
 			break;
 			break;
 		case SC_B_TRAP:
 		case SC_B_TRAP:
 			tick_def = b_status->str * 50; // (custom)
 			tick_def = b_status->str * 50; // (custom)
@@ -11269,11 +11248,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 		case SC_SATURDAYNIGHTFEVER: // Sit down force of Saturday Night Fever has the duration of only 3 seconds.
 		case SC_SATURDAYNIGHTFEVER: // Sit down force of Saturday Night Fever has the duration of only 3 seconds.
 			sc_start(bl, bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
 			sc_start(bl, bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
 			break;
 			break;
-		case SC_SITDOWN_FORCE:
-			if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
-				clif_standing(bl);
-			}
-			break;
 		case SC_NEUTRALBARRIER_MASTER:
 		case SC_NEUTRALBARRIER_MASTER:
 		case SC_STEALTHFIELD_MASTER:
 		case SC_STEALTHFIELD_MASTER:
 			if( sce->val2 ) {
 			if( sce->val2 ) {
@@ -11329,11 +11303,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 		case SC_TEARGAS:
 		case SC_TEARGAS:
 			status_change_end(bl,SC_TEARGAS_SOB,INVALID_TIMER);
 			status_change_end(bl,SC_TEARGAS_SOB,INVALID_TIMER);
 			break;
 			break;
+		case SC_SITDOWN_FORCE:
 		case SC_BANANA_BOMB_SITDOWN:
 		case SC_BANANA_BOMB_SITDOWN:
-			if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
+			if( sd && pc_issit(sd) && pc_setstand(sd, false) )
 				skill_sit(sd,0);
 				skill_sit(sd,0);
-				clif_standing(bl);
-			}
 			break;
 			break;
 		case SC_KYOUGAKU:
 		case SC_KYOUGAKU:
 			clif_status_load(bl, SI_KYOUGAKU, 0); // Avoid client crash
 			clif_status_load(bl, SI_KYOUGAKU, 0); // Avoid client crash
@@ -11978,14 +11951,13 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 
 
 	case SC_LEECHESEND:
 	case SC_LEECHESEND:
 		if( --(sce->val4) >= 0 ) {
 		if( --(sce->val4) >= 0 ) {
-			int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
-			damage += status->vit * (sce->val1 - 3);
-			unit_skillcastcancel(bl,2);
+			int damage = status->vit * (sce->val1 - 3) + status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
+
 			map_freeblock_lock();
 			map_freeblock_lock();
-			status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,DMG_NORMAL,0), 1);
-			if( sc->data[type] ) {
+			status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,DMG_NORMAL,0), 0);
+			unit_skillcastcancel(bl, 2);
+			if (sc->data[type])
 				sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
 				sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
-			}
 			map_freeblock_unlock();
 			map_freeblock_unlock();
 			return 0;
 			return 0;
 		}
 		}
@@ -12158,7 +12130,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 
 
 	case SC__SHADOWFORM:
 	case SC__SHADOWFORM:
 		if( --(sce->val4) >= 0 ) {
 		if( --(sce->val4) >= 0 ) {
-			if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
+			if( !status_charge(bl, 0, 11 - sce->val1) )
 				break;
 				break;
 			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;

+ 0 - 3
src/map/status.h

@@ -2197,9 +2197,6 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ
 
 
 unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status);
 unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status);
 
 
-int status_get_baselevel_limit(struct block_list *bl, int level_limit);
-int status_get_joblevel_limit(struct map_session_data *sd, int level_limit);
-
 void initChangeTables(void);
 void initChangeTables(void);
 int status_readdb(void);
 int status_readdb(void);
 int do_init_status(void);
 int do_init_status(void);

+ 1 - 6
src/map/unit.c

@@ -1349,12 +1349,7 @@ int unit_can_move(struct block_list *bl) {
 	if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
 	if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
 		return 0;
 		return 0;
 
 
-	if (sd && (
-		pc_issit(sd) ||
-		sd->state.vending ||
-		sd->state.buyingstore ||
-		sd->state.blockedmove
-	))
+	if ((sd && (pc_issit(sd) || sd->state.vending || sd->state.buyingstore)) || ud->state.blockedmove)
 		return 0; // Can't move
 		return 0; // Can't move
 
 
 	// Status changes that block movement
 	// Status changes that block movement

+ 1 - 0
src/map/unit.h

@@ -53,6 +53,7 @@ struct unit_data {
 		unsigned running : 1;
 		unsigned running : 1;
 		unsigned speed_changed : 1;
 		unsigned speed_changed : 1;
 		unsigned walk_script : 1;
 		unsigned walk_script : 1;
+		unsigned blockedmove : 1;
 	} state;
 	} state;
 	char walk_done_event[EVENT_NAME_LENGTH];
 	char walk_done_event[EVENT_NAME_LENGTH];
 };
 };