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:
parent
201d7961fa
commit
d95f5d2db7
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>";
|
||||
|
@ -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) )
|
||||
|
@ -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, },
|
||||
|
@ -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 ) {
|
||||
|
58
src/map/pc.c
58
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_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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
156
src/map/skill.c
156
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 ) {
|
||||
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) + (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);
|
||||
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: {(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);
|
||||
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: {(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
|
||||
}
|
||||
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;
|
||||
|
@ -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: {(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;
|
||||
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: {(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;
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user