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.
This commit is contained in:
aleos89 2015-08-17 14:13:22 -04:00
parent 201d7961fa
commit d95f5d2db7
22 changed files with 301 additions and 265 deletions

View File

@ -51,15 +51,14 @@ random_monster_checklv: no
// NOTE: Wedding Rings and Whips/Musical Instruments will check gender regardless of setting.
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.
// 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?
// Only affects the delay between using items, prevents healing item abuse. Recommended ~500 ms

View File

@ -1368,7 +1368,7 @@
2304,1000,0,0,500,1500,5000
//-- SC_ESCAPE
5010,0,0,0,1000,0,15000
5010,0,500,0,50000,20000,10000:8000:6000:4000:2000
//==========================================
//==== Royal Guard skills ==================
@ -1386,7 +1386,7 @@
2313,0,1000,0,300000,0,0
//-- LG_RAGEBURST
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
//-- LG_EXEEDBREAK
2316,5000:5500:6000:6500:7000,1000,0,300000,0,0
@ -1470,7 +1470,7 @@
//==== Minstresl skills ====================
//-- MI_RUSH_WINDMILL
2381,0,2000,0,60000,0,0
2381,1000,2000,0,60000,0,0
//-- MI_ECHOSONG
2382,1000,2000,0,60000,0,0
//-- MI_HARMONIZE

View File

@ -697,7 +697,7 @@
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
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
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
@ -1023,7 +1023,7 @@
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
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
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
@ -1140,9 +1140,9 @@
// WM Wanderer/Minstrel
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
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
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
@ -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
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
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
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
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
@ -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
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
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
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

View File

@ -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
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
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
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
@ -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
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
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
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

View File

@ -134,7 +134,7 @@
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
2419,0xde, , 0, 1,1000,enemy, 0x1014 //WM_POEMOFNETHERWORLD
@ -169,7 +169,7 @@
3020,0xf8, , 0, 2, 500,all, 0x018 //KO_ZENKAI
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
8020,0xf5, , 3, 0,2300:2100:1900:1700:1500,enemy, 0x018 //MH_POISON_MIST

View File

@ -1370,7 +1370,7 @@
//-- SC_FEINTBOMB
2304,1000,0,0,500,1500,5000,-1
//-- 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 ==================
@ -1388,26 +1388,26 @@
2313,0,1000,0,300000,0,0,-1
//-- LG_RAGEBURST
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
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
2317,500,2000,0,0,0,0,0
2317,500,2000,0,0,0,0,-1
//-- LG_PRESTIGE
2318,1000,0,0,30000:45000:60000:75000:90000,0,60000,2000
//-- LG_BANDING
2319,0,0,0,-1,2000:4000:6000:8000:10000,0,-1
//-- 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
2321,2000:2500:3000:3500:4000,2000,0,10000,0,5000,500
//-- 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
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
2324,1000,3000,0,0,0,20000,0
2324,1000,3000,0,0,0,20000,-1
//-- LG_INSPIRATION
2325,2000,2000,0,30000:45000:60000:75000:90000,0,540000:480000:420000:360000:300000,1000
//-- LG_KINGS_GRACE
@ -1470,7 +1470,7 @@
//==== Minstresl skills ====================
//-- MI_RUSH_WINDMILL
2381,0,2000,0,60000,0,0,-1
2381,1000,2000,0,60000,0,0,-1
//-- MI_ECHOSONG
2382,1000,2000,0,60000,0,0,-1
//-- MI_HARMONIZE

View File

@ -1023,7 +1023,7 @@
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
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
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
@ -1140,9 +1140,9 @@
// WM Wanderer/Minstrel
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
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
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
@ -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
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
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
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
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
@ -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
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
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
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

View File

@ -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
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
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
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

View File

@ -136,7 +136,7 @@
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
2419,0xde, , 0, 1,1000,enemy, 0x1014 //WM_POEMOFNETHERWORLD
@ -171,7 +171,7 @@
3020,0xf8, , 0, 2, 500,all, 0x018 //KO_ZENKAI
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
8020,0xf5, , 3, 0,2300:2100:1900:1700:1500,enemy, 0x018 //MH_POISON_MIST

View File

@ -6,31 +6,19 @@
//
// - 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

View File

@ -2488,6 +2488,19 @@ Deletes the spirit ball(s) from player.
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
@ -5563,9 +5576,10 @@ Examples:
---------------------------------------
*pcblockmove <id>,<option>;
*unitblockmove <id>,<option>;
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.
Examples:
@ -7087,6 +7101,10 @@ This command will make a <GID> stop attacking.
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>";

View File

@ -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.
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 )
StringBuf_Printf(&buf, ", `card%d`", j);
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, 7, SQLDT_UINT, &item.expire_time, 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 )
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
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].attribute == item.attribute &&
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.
else
{
// update all fields.
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 )
StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
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.
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 )
StringBuf_Printf(&buf, ", `card%d`", j);
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, 8, SQLDT_CHAR, &item.favorite, 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 )
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
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.
ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
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.
else {
// update all fields.
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 )
StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
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, 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,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);
for( i = 0; i < MAX_SLOTS; ++i )
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, 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, 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);
for( i = 0; i < MAX_SLOTS; ++i )
if( SQL_ERROR == SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) )

View File

@ -3676,23 +3676,21 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
skillratio += -100 + (skill_lv + 2) * 50;
RE_LVL_DMOD(100);
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;
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] %
@ -7818,7 +7816,7 @@ static const struct _battle_data {
{ "max_heal_lv", &battle_config.max_heal_lv, 11, 1, INT_MAX, },
{ "max_heal", &battle_config.max_heal, 9999, 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, },
{ "cashfood_use_interval", &battle_config.cashfood_use_interval, 60000, 0, INT_MAX, },
{ "wedding_modifydisplay", &battle_config.wedding_modifydisplay, 0, 0, 1, },

View File

@ -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;
unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
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 ) {

View File

@ -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_tick = tick;
sd->npc_idle_type = NPCT_INPUT;
sd->state.ignoretimeout = false;
#endif
sd->canuseitem_tick = tick;
@ -1412,7 +1413,6 @@ void pc_reg_received(struct map_session_data *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);
pc_check_available_item(sd); // Check for invalid(ated) items.
pc_load_combo(sd);
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)
return;
pc_check_available_item(sd); // Check for invalid(ated) items.
for( i = 0; i < MAX_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.
*------------------------------------------*/
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];
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;
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);
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);
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);
}
}
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;
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);
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);
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);
}
}
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;
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);
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);
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);
}
}

View File

@ -210,7 +210,6 @@ struct map_session_data {
unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo]
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 blockedmove :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 killer : 1;
@ -239,6 +238,7 @@ struct map_session_data {
unsigned int hpmeter_visible : 1;
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]
bool ignoretimeout; // Prevent the SECURE_NPCTIMEOUT function from closing current script.
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;

View File

@ -16440,19 +16440,20 @@ BUILDIN_FUNC(rid2name)
BUILDIN_FUNC(pcblockmove)
{
int id, flag;
TBL_PC *sd = NULL;
struct block_list *bl = NULL;
id = script_getnum(st,2);
flag = script_getnum(st,3);
if(id)
sd = map_id2sd(id);
if (script_getnum(st, 2))
bl = map_id2bl(script_getnum(st,2));
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;
}
@ -20349,6 +20350,31 @@ BUILDIN_FUNC(showscript) {
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"
// 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(pcblockmove,"ii"),
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
// [zBuffer] List of unit control commands --->
BUILDIN_DEF(getunittype,"i"),
BUILDIN_DEF(getunitname,"i"),
BUILDIN_DEF(setunitname,"is"),
@ -20764,11 +20790,12 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(unitattack,"iv?"),
BUILDIN_DEF(unitstopattack,"i"),
BUILDIN_DEF(unitstopwalk,"i"),
BUILDIN_DEF2(pcblockmove,"unitblockmove","ii"),
BUILDIN_DEF(unittalk,"is"),
BUILDIN_DEF(unitemote,"ii"),
BUILDIN_DEF(unitskilluseid,"ivi??"), // originally by Qamera [Celest]
BUILDIN_DEF(unitskillusepos,"iviii?"), // [Celest]
// <--- [zBuffer] List of mob control commands
// <--- [zBuffer] List of unit control commands
BUILDIN_DEF(sleep,"i"),
BUILDIN_DEF(sleep2,"i"),
BUILDIN_DEF(awake,"s"),
@ -20908,6 +20935,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(getattachedrid,""),
BUILDIN_DEF(getvar,"vi"),
BUILDIN_DEF(showscript,"s?"),
BUILDIN_DEF(ignoretimeout,"i?"),
#include "../custom/script_def.inc"

View File

@ -397,18 +397,22 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
switch( skill_id ) {
case BA_APPLEIDUN:
#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
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
if( sd )
hp += 5*pc_checkskill(sd,BA_MUSICALLESSON);
hp += 5 * pc_checkskill(sd,BA_MUSICALLESSON);
break;
case PR_SANCTUARY:
hp = (skill_lv>6)?777:skill_lv*100;
hp = (skill_lv > 6) ? 777 : skill_lv * 100;
break;
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;
default:
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
* 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
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
if (skill_id == AB_HIGHNESSHEAL)
hp = hp * ( 17 + 3 * skill_lv ) / 10;
if( sd && ((skill = pc_checkskill(sd, HP_MEDITATIO)) > 0) )
hp += hp * skill * 2 / 100;
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;
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)) )
hp += hp*skill/100;
hp += hp * skill / 100;
if( sc && sc->data[SC_OFFERTORIUM] && (skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL ||
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]
// Note: in this part matk bonuses from items or skills are not applied
switch( skill_id ) {
case BA_APPLEIDUN: case PR_SANCTUARY:
case NPC_EVILLAND: break;
case BA_APPLEIDUN:
case PR_SANCTUARY:
case NPC_EVILLAND:
break;
default:
{
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:
skill_id = WL_CHAINLIGHTNING;
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_PLUSATK:
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:
dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
break;
case WZ_SIGHTBLASTER:
case HT_CLAYMORETRAP:
case HT_BLASTMINE:
case HT_FLASHER:
@ -3220,9 +3243,6 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
case HT_LANDMINE:
dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type);
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_BANISHING_BUSTER:
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 SC_DIMENSIONDOOR:
case SC_BLOODYLUST:
case WM_REVERBERATION:
case GN_THORNS_TRAP:
case GN_HELLS_PLANT:
case RL_B_TRAP:
case SC_ESCAPE:
//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)
return 0;
@ -3878,7 +3900,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
break;
case WM_REVERBERATION_MELEE:
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;
case SC_FATALMENACE:
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)
return 0;
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());
su->limit = DIFF_TICK(gettick(), sg->tick) + 1500;
su->limit = DIFF_TICK(gettick(), sg->tick);
sg->unit_id = UNT_USED_TRAPS;
}
return 0;
return 1;
}
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_WINDMILL:
case SR_RIDEINLIGHTNING:
case WM_SOUND_OF_DESTRUCTION:
case WM_REVERBERATION:
case WM_REVERBERATION_MELEE:
case WM_REVERBERATION_MAGIC:
case SO_VARETYR_SPEAR:
case GN_CART_TORNADO:
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?
skill_addtimerskill(src,tick+250,src->id,0,0,skill_id,skill_lv,2,flag|BCT_ENEMY|SD_SPLASH|1);
break;
case WM_REVERBERATION_MELEE:
case WM_REVERBERATION_MAGIC:
skill_area_temp[1] = 0;
break;
default:
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);
// 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 ) {
map_freeblock_unlock(); // Don't consume a second gemstone.
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]);
else {
// Success chance: (Skill Level x 6) + (Voice Lesson Skill Level x 2) + (Casters 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);
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);
@ -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 )] %
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);
// Resistance: {(Targets Base Level / 20) + (Targets 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);
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:
if (flag&1) {
struct status_data *bstatus = status_get_base_status(bl);
// Resistance: {(Targets Base Level / 20) + (Targets 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
}
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);
}
case GN_WALLOFTHORN:
case SC_ESCAPE:
ud->skillx = target->x;
ud->skilly = target->y;
ud->skilltimer = tid;
@ -11595,9 +11621,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
break;
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);
flag |= 1;
break;
case LG_OVERBRAND: {
@ -11636,8 +11663,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
break;
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;
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))
target = BCT_ALL;
break;
case HT_ANKLESNARE:
if( flag&2 ) val3 = SC_ESCAPE;
case HT_SKIDTRAP:
case MA_SKIDTRAP:
//Save position of caster
val1 = ((src->x)<<16)|(src->y);
case HT_ANKLESNARE:
case HT_SHOCKWAVE:
case HT_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_ICEBOUNDTRAP:
case RL_B_TRAP:
case SC_ESCAPE:
{
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));
@ -12344,11 +12372,6 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
case LG_BANDING:
limit = -1;
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.
if( skill_id == WM_POEMOFNETHERWORLD && map_flag_gvg2(src->m) )
target = BCT_ALL;
@ -12476,6 +12499,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
case MA_SKIDTRAP:
case HT_CLAYMORETRAP:
case HT_BLASTMINE:
case SC_ESCAPE:
unit_val1 = 3500;
break;
@ -12499,6 +12523,9 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
if (unit_val1 < 1) unit_val1 = 1;
unit_val2 = 0;
break;
case WM_REVERBERATION:
unit_val1 = 1 + skill_lv;
break;
case WM_POEMOFNETHERWORLD:
unit_val1 = 1 + skill_lv;
break;
@ -13067,7 +13094,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
case UNT_ANKLESNARE:
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);
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:
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;
break;
@ -13882,11 +13909,10 @@ int64 skill_unit_ondamaged(struct skill_unit *unit, int64 damage)
case UNT_ANKLESNARE:
case UNT_ICEWALL:
case UNT_WALLOFTHORN:
case UNT_REVERBERATION:
case UNT_NETHERWORLD:
unit->val1 -= (int)cap_value(damage,INT_MIN,INT_MAX);
break;
case UNT_REVERBERATION:
unit->val1--;
default:
damage = 0;
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.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;
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;
}
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) )
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;
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;
case UNT_FIRINGTRAP:
case UNT_ICEBOUNDTRAP:
@ -17176,11 +17204,14 @@ int skill_delunit(struct skill_unit* unit)
// perform ondelete actions
switch (group->skill_id) {
case HT_ANKLESNARE: {
case HT_ANKLESNARE:
case SC_ESCAPE:
{
struct block_list* target = map_id2bl(group->val2);
enum sc_type type = status_skill2sc(group->skill_id);
if( target )
status_change_end(target, SC_ANKLE, INVALID_TIMER);
status_change_end(target, type, INVALID_TIMER);
}
break;
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_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);
break;
}
@ -17683,10 +17714,10 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
clif_changetraplook(bl,UNT_USED_TRAPS);
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) + 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;
break;
break;
case UNT_FEINTBOMB: {
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;
case UNT_REVERBERATION:
if (unit->val1 <= 0)
unit->limit = DIFF_TICK(tick, group->tick) + 700;
break;
case UNT_NETHERWORLD:
if (unit->val1 <= 0) {
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;
}
break;

View File

@ -698,6 +698,7 @@ void initChangeTables(void)
add_sc( SC_CHAOSPANIC , SC_CONFUSION );
add_sc( SC_BLOODYLUST , SC_BERSERK );
add_sc( SC_FEINTBOMB , SC__FEINTBOMB );
add_sc( SC_ESCAPE , SC_ANKLE );
/* Sura */
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));
}
/**
* 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
* 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
break;
case SC_NETHERWORLD:
// Resistance: {(Targets Base Level / 50) + (Targets 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;
case SC_MARSHOFABYSS:
// 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;
break;
case SC_VOICEOFSIREN:
// Resistance: {(Targets Base Level / 10) + (Targets 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;
case SC_B_TRAP:
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.
sc_start(bl, bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
break;
case SC_SITDOWN_FORCE:
if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
clif_standing(bl);
}
break;
case SC_NEUTRALBARRIER_MASTER:
case SC_STEALTHFIELD_MASTER:
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:
status_change_end(bl,SC_TEARGAS_SOB,INVALID_TIMER);
break;
case SC_SITDOWN_FORCE:
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);
clif_standing(bl);
}
break;
case SC_KYOUGAKU:
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:
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();
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 );
}
map_freeblock_unlock();
return 0;
}
@ -12158,7 +12130,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC__SHADOWFORM:
if( --(sce->val4) >= 0 ) {
if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
if( !status_charge(bl, 0, 11 - sce->val1) )
break;
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
return 0;

View File

@ -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);
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);
int status_readdb(void);
int do_init_status(void);

View File

@ -1349,12 +1349,7 @@ int unit_can_move(struct block_list *bl) {
if (DIFF_TICK(ud->canmove_tick, gettick()) > 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
// Status changes that block movement

View File

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