Skill Changes:
* Wizard/Warlock Skill * Moved Sightrasher (WZ_SIGHTRASHER) requirement to check Sight (SC_SIGHT) is active or not to skill_check_condition_castend section. * Fixed Sightrasher (WZ_SIGHTRASHER) splash area to 3x3. (bugreport:9298) * Now Comet (WL_COMET) cannot hits Hiding target (The mistake is not at flag 0x10000 in skill_db.txt, the flash should be added by SD_ANIMATION). (bugreport:8909). * Now Reading Spell Book (WL_READING_SB) checking the number of available spell books in Spell Book DB first to prevent infinite loop. * Sage Skill * Now Abracadabra (SA_ABRACADABRA) checking the number of available skills in Abra DB first to prevent infinite loop. * Reduced MAX_SKILL_ABRA_DB from 350 to 160. * Shadow Chaser Skill * Fixed Chaos Panic (SC_CHAOSPANIC) effect. (bugreport:9321). * Genetic Skill * Now Wall of Thorn (GN_WALLOFTHORN) can be knocked back but not a whole skill group and durability (HP & max hit) for each skill unit. * Guillotine Cross Skill * Now Magic Mushroom (SC_MAGICMUSHROOM) effect checks the number of available skills in Magic Mushroom DB first to prevent infinite loop. * Changed 'RemoveFlag' in db/magicmushroom_db.txt value to 1 to remove skill by importing. (bugreport:9322). * Wanderer/Minstrel Skill * Now Randomize Spell (WM_RANDOMIZESPELL) checks the number of available skills in Improvise DB first to prevent infinite loop. * Reduced MAX_SKILL_IMPROVISE_DB from 50 to 30. * Rebellion Skill * Cleaned up, added, corrected some (missing) sequences & DB values. * Fixed Hammer of God (RL_HAMMER_OF_GOD) splash damage. * Fixed Shaterred Strom (RL_S_STORM) push back & force to sit effect (for player, or stun for monsters) (first implementation leftover). * Fixed Slug Shot (RL_SLUGSHOT) hitrate-distance penalty (first implementation leftover). * Fixed Howling Mine (RL_H_MINE) damage ratios (first implementation leftover). * Now Bind Trap (RL_B_TRAP) only can be placed 1 at same time. * Fixed Bind Trap (RL_B_TRAP) damage calculation by using Caster's DEX, Target's Current HP, & Skill Level. FIXME: Exact formula still unknown (refers to idAthena formula). * Now Dragon Tail (RL_D_TAIL) doesn't split damage among targets anymore. * Now Crimson Marker (RL_C_MARKER) will fails to cast if no slot available. * Implemented official packet `ZC_C_MARKERINFO` of Crimson Marker (RL_C_MARKER) mini-map marker (first implementation leftover). !TODO: Confirm the packet for older or newer clients (idAthena partial merge r1497) * References: http://forums.irowiki.org/showpost.php?p=1387992&postcount=968, follow up 507f047, dd67f9d Misc: * Fixed some skills that should work only in shoot range (map_foreachinshootange, by default), and added check for respecting *skill_wall_check* (map_foreachinrange). * Fixed item stackable check for `/item` command, follow up 9b4d922. * Fixed npc source file isn't removed properly by @unloadnpcfile. (bugreport:9311). * Added constantan for status_change_start() and sc_start() scripts as well * SCSTART_NONE = 0x0 * SCSTART_NOAVOID = 0x1 * SCSTART_NOTICKDEF = 0x2 * SCSTART_LOADED = 0x4 * SCSTART_NORATEDEF = 0x8 * SCSTART_NOICON = 0x10 * Moved and changed itemdb_unique_id() to pc_generate_unique_id(). * Seperated check for skill SC requirement to skill_check_condition_sc_required(). * Added skill unit flag `UF_KNOCKBACK_GROUP`, just an option to make skill unit can be knocked back a whole group. * Typos and other minor changes! Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
parent
c6ba813994
commit
ce090ce916
@ -4,5 +4,5 @@
|
||||
// Structure of Database:
|
||||
// SkillID{,RemoveFlag}
|
||||
//
|
||||
// - To remove entry by importing, put any value on 'RemoveFlag'
|
||||
// - To remove entry by importing, put 1 value on 'RemoveFlag'
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Structure of Database:
|
||||
// SkillID{,RemoveFlag}
|
||||
//
|
||||
// - To remove entry by importing, put any value on 'RemoveFlag'
|
||||
// - To remove entry by importing, put 1 value on 'RemoveFlag'
|
||||
|
||||
7 //SM_MAGNUM
|
||||
8 //SM_ENDURE
|
||||
|
@ -2244,6 +2244,7 @@ packet_ver: 45
|
||||
0x023B,26,friendslistadd,2
|
||||
0x0361,5,hommenu,2:4
|
||||
0x0887,36,storagepassword,2:4:20
|
||||
0x09C1,10,ZC_C_MARKERINFO,2:6:8
|
||||
|
||||
//2013-12-23Ragexe
|
||||
packet_ver: 46
|
||||
@ -2277,13 +2278,14 @@ packet_ver: 46
|
||||
0x0361,5,hommenu,2:4
|
||||
0x08A4,36,storagepassword,2:4:20
|
||||
//New Packets
|
||||
0x09D4,2,dull,0 //npcshopclosed
|
||||
//0x097E,12 //ZC_UPDATE_RANKING_POINT
|
||||
0x09B4,6,dull,0 //Cash Shop - Special Tab
|
||||
0x09CE,102,itemmonster,2
|
||||
0x09D4,2,dull,0 //npcshopclosed
|
||||
//NPC Market
|
||||
0x09D8,2,dull,0 //npcmarketclosed
|
||||
0x09D6,-1,dull,0 //npcmarketpurchase
|
||||
0x09D8,2,dull,0 //npcmarketclosed
|
||||
0x09DF,7
|
||||
0x09B4,6,dull,0 // Cash Shop - Special Tab
|
||||
|
||||
//Add new packets here
|
||||
//packet_ver: 47
|
||||
|
@ -6,22 +6,23 @@
|
||||
// layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
|
||||
// target = friend (party +guildmates +neutral players) / party / guild
|
||||
// ally (party +guildmates) / all / sameguild (guild but no allies) / enemy
|
||||
// flag 0x0001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x0002(UF_NOREITERRATION) Spell cannot be stacked
|
||||
// 0x0004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x0008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x0010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x0020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x0040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x0080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x0100(UF_DANCE) Dance skill
|
||||
// 0x0200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x0400(UF_SONG) Song skill
|
||||
// 0x0800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x1000(UF_NOKNOCKBACK) Cannot be knocked back (only unit that can be damaged)
|
||||
// 0x2000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// 0x4000(UF_REM_CRAZYWEED) Removed if be overlapped by GN_CRAZYWEED
|
||||
// 0x8000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN
|
||||
// flag 0x00001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x00002(UF_NOREITERRATION) Spell cannot be stacked
|
||||
// 0x00004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x00008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x00010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x00020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x00040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x00080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x00100(UF_DANCE) Dance skill
|
||||
// 0x00200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x00400(UF_SONG) Song skill
|
||||
// 0x00800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x01000(UF_NOKNOCKBACK) Cannot be knocked back (only unit that can be damaged)
|
||||
// 0x02000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// 0x04000(UF_REM_CRAZYWEED) Removed if be overlapped by GN_CRAZYWEED
|
||||
// 0x08000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN
|
||||
// 0x10000(UF_KNOCKBACK_GROUP) Knock back a whole skill group (by default, skill unit is knocked back each unit)
|
||||
// Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets
|
||||
//
|
||||
// Notes:
|
||||
@ -126,7 +127,7 @@
|
||||
|
||||
2299,0xcc, , 0, 1,1000,all, 0xC006 //SC_MANHOLE
|
||||
2300,0xcd, , 0, 0,1000,all, 0xC006 //SC_DIMENSIONDOOR
|
||||
2301,0xce, , 2, 0, -1,all, 0xE00E //SC_CHAOSPANIC
|
||||
2301,0xce, , 2, 0,1000,all, 0xE00E //SC_CHAOSPANIC
|
||||
2302,0xcf, , 2, 0, -1,all, 0xE002 //SC_MAELSTROM
|
||||
2303,0xd0, , 3, 0, -1,all, 0xE058 //SC_BLOODYLUST
|
||||
2304,0xd1, , 0, 2, 500,enemy, 0x018 //SC_FEINTBOMB
|
||||
@ -151,7 +152,7 @@
|
||||
2468,0xf4, , 0, 1,1000,all, 0x010 //SO_EARTH_INSIGNIA
|
||||
|
||||
2479,0xe5, , 0, 1,1000,enemy, 0xC006 //GN_THORNS_TRAP
|
||||
2482,0xe6,0x7f, -1, 1, 300,enemy, 0xD000 //GN_WALLOFTHORN
|
||||
2482,0xe6,0x7f, -1, 1, 300,enemy, 0xC000 //GN_WALLOFTHORN
|
||||
2484,0x86, , 0, 1, 100,enemy, 0x080 //GN_CRAZYWEED_ATK
|
||||
2485,0xe7, , 0, 2,2000,enemy, 0x8098 //GN_DEMONIC_FIRE
|
||||
2487,0xe8, , 2, 0, -1,enemy, 0x2000 //GN_FIRE_EXPANSION_SMOKE_POWDER
|
||||
|
@ -1643,11 +1643,11 @@
|
||||
//-- RL_RICHS_COIN
|
||||
2552,0,1000,0,600000,0,0,-1
|
||||
//-- RL_MASS_SPIRAL
|
||||
2553,0,1000,0,0,30000,1000,-1
|
||||
2553,2000,1000,0,0,30000,1000,-1
|
||||
//-- RL_BANISHING_BUSTER
|
||||
2554,3000:2500:2000:1500:1000,1000,0,0,0,1500,-1
|
||||
//-- RL_B_TRAP
|
||||
2555,0,0,0,10000:11000:12000:13000:14000,0,2000,-1
|
||||
2555,0,0,0,4000,6000:7000:8000:9000:10000,2000,-1
|
||||
//-- RL_FLICKER
|
||||
2556,0,500,0,0,0,2000,-1
|
||||
//-- RL_S_STORM
|
||||
@ -1659,27 +1659,27 @@
|
||||
//-- RL_C_MARKER
|
||||
2560,0,0,0,30000,0,1000,-1
|
||||
//-- RL_FIREDANCE
|
||||
2561,0,1500,0,0,0,5000,-1
|
||||
2561,1600:1500:1400:1200:1000,1500,0,0,0,5000,-1
|
||||
//-- RL_H_MINE
|
||||
2562,0,1500,0,30000,15000,2000,-1
|
||||
2562,2000,1500,0,30000,15000,5000:4500:4000:3500:3000,-1
|
||||
//-- RL_P_ALTER
|
||||
2563,0,1000,0,60000,0,5000,-1
|
||||
2563,0,1000,0,30000:45000:60000:75000:90000,0,5000,-1
|
||||
//-- RL_FALLEN_ANGEL
|
||||
2564,0,1500,0,0,0,4500:4000:3500:2500:2000,-1
|
||||
//-- RL_R_TRIP
|
||||
2565,0,1500,0,0,0,3000,-1
|
||||
//-- RL_D_TAIL
|
||||
2566,0,1500,0,0,0,5000,-1
|
||||
2566,2000,1500,0,0,0,5000,-1
|
||||
//-- RL_FIRE_RAIN
|
||||
2567,0,1500,0,100,0,5000,-1
|
||||
//-- RL_HEAT_BARREL
|
||||
2568,0,1000,0,60000,10000,10000,-1
|
||||
//-- RL_AM_BLAST
|
||||
2569,2000,1500,0,0,6000:7000:8000:9000:10000,1000,-1
|
||||
2569,2000,1500,0,0,6000:7000:8000:9000:10000,1000,1000
|
||||
//-- RL_SLUGSHOT
|
||||
2570,5000:6000:7000:8000:9000,1000,0,0,10000,1500,1000
|
||||
2570,5000:6000:7000:8000:9000,1000,0,2000,0,1500,1000
|
||||
//-- RL_HAMMER_OF_GOD
|
||||
2571,0,1000,0,0,3000:3000:4000:4000:5000,3000,-1
|
||||
2571,3000,1000,0,0,3000:3000:4000:4000:5000,3000,-1
|
||||
//-- RL_R_TRIP_PLUSATK
|
||||
//2572,0,0,0,0,0,0,-1
|
||||
//-- RL_B_FLICKER_ATK
|
||||
|
@ -864,7 +864,7 @@
|
||||
1003,0,0,0,0,0,0,1,0,no,0,0x1,0,weapon,0,0x0, AS_SONICACCEL,Sonic Acceleration
|
||||
1004,9,8,1,0,0x8,0,1,1,no,0,0x1,0,weapon,0,0x0, AS_VENOMKNIFE,Throw Venom Knife
|
||||
1005,1,6,1,0,0x1,0,1,1,no,0,0x1,0,weapon,0,0x0, RG_CLOSECONFINE,Close Confine
|
||||
1006,0,6,4,3,0,2,1,1,yes,0,0x1,0,magic,3,0x20, WZ_SIGHTBLASTER,Sight Blaster
|
||||
1006,0,6,4,3,0,1,1,1,yes,0,0x1,0,magic,3,0x20, WZ_SIGHTBLASTER,Sight Blaster
|
||||
1007,0,6,4,0,0x1,0,1,0,no,0,0x1,0,none,0,0x0, SA_CREATECON,Create Elemental Converter
|
||||
1008,9,6,1,1,0x1,0,1,1,yes,0,0x1,0,magic,0,0x0, SA_ELEMENTWATER,Elemental Change Water
|
||||
1009,-9,6,1,0,0,0,1,1,no,0,0x1,0,weapon,3,0x0, HT_PHANTASMIC,Phantasmic Arrow
|
||||
@ -1235,25 +1235,25 @@
|
||||
// Rebellion
|
||||
//2551,0,0,0,0,0,0,10,0,no,0,0,0,none,0,0, RL_GLITTERING_GREED,Flip The Coin Greed
|
||||
2552,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0,0x0, RL_RICHS_COIN,Rich's Coin
|
||||
2553,15,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, RL_MASS_SPIRAL,Mass Spiral
|
||||
2554,9,6,1,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_BANISHING_BUSTER,Banishing Buster
|
||||
2555,3,6,2,0,0x1,1,5,1,no,0,0,3,misc,0,0x0, RL_B_TRAP,Bind Trap
|
||||
2553,-9,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, RL_MASS_SPIRAL,Mass Spiral
|
||||
2554,-9,6,1,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_BANISHING_BUSTER,Banishing Buster
|
||||
2555,3:4:4:5:5,6,2,0,0x1,1,5,1,no,0,0,1,misc,0,0x0, RL_B_TRAP,Bind Trap
|
||||
2556,0,6,4,0,0x3,-1,1,1,no,0,0,0,none,0,0x0, RL_FLICKER,Flicker
|
||||
2557,9,6,1,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_S_STORM,Shatter Storm
|
||||
2557,-9,6,1,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_S_STORM,Shatter Storm
|
||||
2558,0,6,4,0,0x1,0,10,1,no,0,0,0,none,0,0x0, RL_E_CHAIN,Eternal Chain
|
||||
2559,-9,6,4,-1,0x3,21,1,1,no,0,0x0,0,weapon,0,0x0, RL_QD_SHOT,Quick Draw Shot
|
||||
2560,11,6,1,0,0x1,0,1,1,no,0,0,3,none,0,0x0, RL_C_MARKER,Crimson Marker
|
||||
2561,0,6,4,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_FIREDANCE,Fire Dance
|
||||
2562,7:8:9:10:11,6,1,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_H_MINE,Howling Mine
|
||||
2559,-9,6,4,-1,0x0,10,1,1,no,0,0x0,0,weapon,0,0x0, RL_QD_SHOT,Quick Draw Shot
|
||||
2560,-9,6,1,0,0x1,0,1,1,no,0,0,3,none,0,0x0, RL_C_MARKER,Crimson Marker
|
||||
2561,0,6,4,-1,0x2,3,5,1,no,0,0,0,weapon,0,0x0, RL_FIREDANCE,Fire Dance
|
||||
2562,-9,6,1,-1,0x0,2,5,1,no,0,0,0,weapon,0,0x0, RL_H_MINE,Howling Mine
|
||||
2563,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, RL_P_ALTER,Platinum Alter
|
||||
2564,9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, RL_FALLEN_ANGEL,Fallen Angel
|
||||
2564,-9,6,2,0,0x1,0,5,1,no,0,0,0,none,0,0x0, RL_FALLEN_ANGEL,Fallen Angel
|
||||
2565,0,6,4,-1,0x2,3:3:4:5:6,5,1,no,0,0,0,weapon,3,0x0, RL_R_TRIP,Round Trip
|
||||
2566,0,6,4,-1,0x3,-1,5,1,no,0,0,0,weapon,0,0x0, RL_D_TAIL,Dragon Tail
|
||||
2567,9,6,2,-1,0x2,1,5,1,no,0,0,0,weapon,0,0, RL_FIRE_RAIN,Fire Rain
|
||||
2567,-9,6,2,-1,0x2,1,5,1,no,0,0,0,weapon,0,0, RL_FIRE_RAIN,Fire Rain
|
||||
2568,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, RL_HEAT_BARREL,Heat Barrel
|
||||
2569,9,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, RL_AM_BLAST,Anti-Material Blast
|
||||
2570,9,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, RL_SLUGSHOT,Slug Shot
|
||||
2571,7:8:9:10:11,6,2,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_HAMMER_OF_GOD,Hammer of God
|
||||
2569,-9,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, RL_AM_BLAST,Anti-Material Blast
|
||||
2570,-9,6,1,-1,0,0,5,1,no,0,0,0,weapon,6,0x0, RL_SLUGSHOT,Slug Shot
|
||||
2571,-9,6,2,-1,0x2,2,5,1,no,0,0,0,weapon,0,0x0, RL_HAMMER_OF_GOD,Hammer of God
|
||||
2572,0,6,1,-1,0x40,0,5,1,no,0,0,0,weapon,0,0, RL_R_TRIP_PLUSATK,Round Trip Plus Attack
|
||||
//2573,0,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0, RL_B_FLICKER_ATK,Bind Flicker Attack
|
||||
//2574,0,6,1,-1,0,0,10,1,no,0,0,0,weapon,0,0, RL_GLITTERING_GREED_ATK,Flip The Coin Greed Attack
|
||||
@ -1266,7 +1266,7 @@
|
||||
3004,3:4:5:6:7,8,1,-1,0,0,5,-2,no,0,0,0,weapon,0,0x0, KO_JYUMONJIKIRI,Cross Strike
|
||||
3005,2,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0, KO_SETSUDAN,Soul Sever
|
||||
3006,7:8:9:10:11,6,2,-1,0x42,2,5,1,no,0,0,0,weapon,0,0x0, KO_BAKURETSU,Bakuretsu Kunai
|
||||
3007,5,6,4,-1,0x42,4:4:4:4:5,5,1,no,0,0,0,weapon,0,0x0, KO_HAPPOKUNAI,Happo Kunai
|
||||
3007,0,6,4,-1,0x42,4:4:4:4:5,5,1,no,0,0,0,weapon,0,0x0, KO_HAPPOKUNAI,Happo Kunai
|
||||
3008,11,8,2,0,0x56,1:1:1:1:1:1:1:1:1:2,10,-10,no,0,0,0,misc,0,0x0, KO_MUCHANAGE,Mucha Nage
|
||||
3009,9:10:11:12:13,8,2,-1,0x2,3,5,2,no,0,0,0,weapon,0,0x0, KO_HUUMARANKA,Huuma Shuriken Ranka
|
||||
3010,3,6,4,0,0x52,0,5,1,no,0,0x80,0,weapon,0,0x10, KO_MAKIBISHI,Makibishi
|
||||
|
@ -896,7 +896,7 @@
|
||||
2554,0,0,55:60:65:70:75,0,0,0,20,3,1,none,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_BANISHING_BUSTER
|
||||
2555,0,0,30:32:34:36:38,0,0,0,17:18:19:20:21,0,0,none,0,1,7940,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_B_TRAP
|
||||
2556,0,0,2,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 //RL_FLICKER
|
||||
2557,0,0,55:60:65:70:75,0,0,0,20,3,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_S_STORM
|
||||
2557,0,0,55:60:65:70:75,0,0,0,20,3,1,none,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_S_STORM
|
||||
2558,0,0,45,0,0,0,17:18:19:20:21,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 //RL_E_CHAIN
|
||||
2559,0,0,5,0,0,0,17:18:19:20:21,3:4:5,1,none,SC_QD_SHOT_READY,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_QD_SHOT
|
||||
2560,0,0,10,0,0,0,17:18:19:20:21,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 //RL_C_MARKER
|
||||
|
@ -6,22 +6,23 @@
|
||||
// layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
|
||||
// target = friend (party +guildmates +neutral players) / party / guild
|
||||
// ally (party +guildmates) / all / sameguild (guild but no allies) / enemy
|
||||
// flag 0x0001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x0002(UF_NOREITERRATION) Spell cannot be stacked
|
||||
// 0x0004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x0008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x0010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x0020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x0040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x0080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x0100(UF_DANCE) Dance skill
|
||||
// 0x0200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x0400(UF_SONG) Song skill
|
||||
// 0x0800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x1000(UF_NOKNOCKBACK) Cannot be knocked back (only unit that can be damaged)
|
||||
// 0x2000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// 0x4000(UF_REM_CRAZYWEED) Removed if be overlapped by GN_CRAZYWEED
|
||||
// 0x8000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN
|
||||
// flag 0x00001(UF_DEFNOTENEMY) If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
// 0x00002(UF_NOREITERRATION) Spell cannot be stacked
|
||||
// 0x00004(UF_NOFOOTSET) Spell cannot be cast near/on targets
|
||||
// 0x00008(UF_NOOVERLAP) Spell effects do not overlap
|
||||
// 0x00010(UF_PATHCHECK) Only cells with a shootable path will be placed
|
||||
// 0x00020(UF_NOPC) Spell cannot affect players.
|
||||
// 0x00040(UF_NOMOB) Spell cannot affect mobs.
|
||||
// 0x00080(UF_SKILL) Spell CAN affect skills.
|
||||
// 0x00100(UF_DANCE) Dance skill
|
||||
// 0x00200(UF_ENSEMBLE) Ensemble skill
|
||||
// 0x00400(UF_SONG) Song skill
|
||||
// 0x00800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
|
||||
// 0x01000(UF_NOKNOCKBACK) Cannot be knocked back (only unit that can be damaged)
|
||||
// 0x02000(UF_RANGEDSINGLEUNIT) Layout hack, use layout range propriety but only display center.
|
||||
// 0x04000(UF_REM_CRAZYWEED) Removed if be overlapped by GN_CRAZYWEED
|
||||
// 0x08000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN
|
||||
// 0x10000(UF_KNOCKBACK_GROUP) Knock back a whole skill group (by default, skill unit is knocked back each unit)
|
||||
// Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets
|
||||
//
|
||||
// Notes:
|
||||
@ -128,8 +129,8 @@
|
||||
|
||||
2299,0xcc, , 0, 1,1000,all, 0xC006 //SC_MANHOLE
|
||||
2300,0xcd, , 0, 0,1000,all, 0xC006 //SC_DIMENSIONDOOR
|
||||
2301,0xce, , 2, 0, -1,all, 0xC00E //SC_CHAOSPANIC
|
||||
2302,0xcf, , 2, 0, -1,all, 0xC002 //SC_MAELSTROM
|
||||
2301,0xce, , 2, 0,1000,all, 0xE00E //SC_CHAOSPANIC
|
||||
2302,0xcf, , 2, 0, -1,all, 0xE002 //SC_MAELSTROM
|
||||
2303,0xd0, , 3, 0, -1,all, 0xE058 //SC_BLOODYLUST
|
||||
2304,0xd1, , 0, 2, 500,enemy, 0x018 //SC_FEINTBOMB
|
||||
|
||||
@ -153,7 +154,7 @@
|
||||
2468,0xf4, , 0, 1,1000,all, 0x010 //SO_EARTH_INSIGNIA
|
||||
|
||||
2479,0xe5, , 0, 1,1000,enemy, 0xC006 //GN_THORNS_TRAP
|
||||
2482,0xe6,0x7f, -1, 1, 300,enemy, 0xD000 //GN_WALLOFTHORN
|
||||
2482,0xe6,0x7f, -1, 1, 300,enemy, 0xC000 //GN_WALLOFTHORN
|
||||
2484,0x86, , 0, 1, 100,enemy, 0x080 //GN_CRAZYWEED_ATK
|
||||
2485,0xe7, , 0, 2,2000,enemy, 0x8098 //GN_DEMONIC_FIRE
|
||||
2487,0xe8, , 2, 0, -1,enemy, 0x2000 //GN_FIRE_EXPANSION_SMOKE_POWDER
|
||||
|
@ -100,8 +100,8 @@
|
||||
// Renewal variable cast time reduction
|
||||
#ifdef RENEWAL_CAST
|
||||
#define VARCAST_REDUCTION(val){ \
|
||||
if( (varcast_r += val) != 0 && varcast_r >= 0 ) \
|
||||
time = time * (1 - (float)min(val, 100) / 100); \
|
||||
if( (varcast_r += (val)) != 0 && varcast_r >= 0 ) \
|
||||
time = time * (1 - (float)min((val), 100) / 100); \
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
|
@ -5775,7 +5775,7 @@ ACMD_FUNC(autotrade) {
|
||||
|
||||
if( battle_config.at_timeout ) {
|
||||
int timeout = atoi(message);
|
||||
status_change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
|
||||
status_change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, SCSTART_NONE);
|
||||
}
|
||||
|
||||
channel_pcquit(sd,0xF); //leave all chan
|
||||
|
@ -347,16 +347,16 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
|
||||
if (sc && sc->count) { //increase dmg by src status
|
||||
switch(atk_elem){
|
||||
case ELE_FIRE:
|
||||
if(sc->data[SC_VOLCANO]) ratio += enchant_eff[sc->data[SC_VOLCANO]->val1-1];
|
||||
if (sc->data[SC_VOLCANO]) ratio += sc->data[SC_VOLCANO]->val3;
|
||||
break;
|
||||
case ELE_WIND:
|
||||
if(sc->data[SC_VIOLENTGALE]) ratio += enchant_eff[sc->data[SC_VIOLENTGALE]->val1-1];
|
||||
if (sc->data[SC_VIOLENTGALE]) ratio += sc->data[SC_VIOLENTGALE]->val3;
|
||||
break;
|
||||
case ELE_WATER:
|
||||
if(sc->data[SC_DELUGE]) ratio += enchant_eff[sc->data[SC_DELUGE]->val1-1];
|
||||
if (sc->data[SC_DELUGE]) ratio += sc->data[SC_DELUGE]->val3;
|
||||
break;
|
||||
case ELE_GHOST:
|
||||
if(sc->data[SC_TELEKINESIS_INTENSE]) ratio += (sc->data[SC_TELEKINESIS_INTENSE]->val3);
|
||||
if (sc->data[SC_TELEKINESIS_INTENSE]) ratio += (sc->data[SC_TELEKINESIS_INTENSE]->val3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -886,7 +886,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
else
|
||||
sce->val3 = 1000; // Next shield
|
||||
}
|
||||
status_change_start(src,bl,SC_STUN,10000,0,0,0,0,1000,2);
|
||||
status_change_start(src,bl,SC_STUN,10000,0,0,0,0,1000,SCSTART_NOTICKDEF);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2247,8 +2247,15 @@ static bool is_attack_hitting(struct Damage wd, struct block_list *src, struct b
|
||||
hitrate -= 35 - 5 * skill_lv;
|
||||
break;
|
||||
case RL_SLUGSHOT:
|
||||
if (distance_bl(src,target) > 3)
|
||||
hitrate -= (10 - (skill_lv - 1));
|
||||
{
|
||||
int8 dist = distance_bl(src, target);
|
||||
if (dist > 3) {
|
||||
// Reduce n hitrate for each cell after initial 3 cells. Different each level
|
||||
// -10:-9:-8:-7:-6
|
||||
dist -= 3;
|
||||
hitrate -= ((11 - skill_lv) * dist);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (sd && wd.type&DMG_MULTI_HIT && wd.div_ == 2) // +1 hit per level of Double Attack on a successful double attack (making sure other multi attack skills do not trigger this) [helvetica]
|
||||
@ -2422,7 +2429,7 @@ static int battle_get_weapon_element(struct Damage wd, struct block_list *src, s
|
||||
element = ELE_HOLY;
|
||||
break;
|
||||
case RL_H_MINE:
|
||||
if (sd && sd->skill_id_old == RL_FLICKER) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER
|
||||
if (sd && sd->flicker) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER
|
||||
element = ELE_FIRE;
|
||||
break;
|
||||
}
|
||||
@ -3034,9 +3041,10 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
skillratio += -100 + sc->data[SC_EXEEDBREAK]->val1;
|
||||
status_change_end(src,SC_EXEEDBREAK,INVALID_TIMER);
|
||||
}
|
||||
if(sc->data[SC_HEAT_BARREL])
|
||||
//!TODO: Verify this placement & skills that affected by these effects [Cydh]
|
||||
if (sc->data[SC_HEAT_BARREL])
|
||||
skillratio += 200;
|
||||
if(sc->data[SC_P_ALTER])
|
||||
if (sc->data[SC_P_ALTER])
|
||||
skillratio += sc->data[SC_P_ALTER]->val2;
|
||||
}
|
||||
|
||||
@ -3858,9 +3866,11 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
* Rebellion
|
||||
**/
|
||||
case RL_MASS_SPIRAL:
|
||||
// 200%:400%:600%:800%:1000%
|
||||
skillratio += -100 + (200 * skill_lv);
|
||||
break;
|
||||
case RL_FIREDANCE:
|
||||
// 100%:200%:300%:400%:500% (+Level ??)
|
||||
skillratio += -100 + (100 * skill_lv);
|
||||
skillratio += (skillratio * status_get_lv(src)) / 300; //(custom)
|
||||
break;
|
||||
@ -3873,7 +3883,7 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
case RL_SLUGSHOT:
|
||||
{
|
||||
uint16 w = 50;
|
||||
int16 idx = 0;
|
||||
int16 idx = -1;
|
||||
if (sd && (idx = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[idx])
|
||||
w = sd->inventory_data[idx]->weight;
|
||||
w /= 10;
|
||||
@ -3881,9 +3891,8 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
}
|
||||
break;
|
||||
case RL_D_TAIL:
|
||||
// 3000%:3500%:4000%:4500%:5000%
|
||||
skillratio += -100 + (2500 + 500 * skill_lv );
|
||||
//if (sd && &sd->c_marker)
|
||||
// skillratio /= max(sd->c_marker.count,1);
|
||||
break;
|
||||
case RL_R_TRIP:
|
||||
skillratio += -100 + (150 * skill_lv); //(custom)
|
||||
@ -3892,10 +3901,11 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
|
||||
skillratio += -100 + (50 * skill_lv); //(custom)
|
||||
break;
|
||||
case RL_H_MINE:
|
||||
skillratio += 100 + (200 * skill_lv);
|
||||
//If damaged by Flicker
|
||||
if (sd && sd->skill_id_old == RL_FLICKER && tsc && tsc->data[SC_H_MINE] && tsc->data[SC_H_MINE]->val2 == src->id)
|
||||
skillratio += 400 + (300 * skill_lv);
|
||||
// 400%:600%:800%:1000%:1200%
|
||||
skillratio += -100 + (200 + 200 * skill_lv);
|
||||
//If damaged by Flicker, explosion damage (800%:1100%:1400%:1700%:2000%)
|
||||
if (sd && sd->flicker)
|
||||
skillratio += 300 + (100 * skill_lv);
|
||||
break;
|
||||
case RL_HAMMER_OF_GOD:
|
||||
//! TODO: Please check the right formula. [Cydh]
|
||||
@ -6156,7 +6166,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
md.damage = ( skill_lv * status_get_lv(src) * 10 ) + ( status_get_int(src) * 7 / 2 ) * ( 18 + (sd?sd->status.job_level:0) / 4 ) * ( 5 / (10 - ((sd) ? pc_checkskill(sd,AM_CANNIBALIZE) : skill_get_max(AM_CANNIBALIZE))) );
|
||||
break;
|
||||
case RL_B_TRAP:
|
||||
md.damage = (200 + status_get_int(src) + status_get_dex(src)) * skill_lv * 10; //(custom)
|
||||
// kRO 2014-02-12: Damage: Caster's DEX, Target's current HP, Skill Level
|
||||
md.damage = ((200 + status_get_dex(src)) * skill_lv * 10) + sstatus->hp; // (custom)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1375,7 +1375,7 @@ int chrif_load_scdata(int fd) {
|
||||
for (i = 0; i < count; i++) {
|
||||
struct status_change_data *data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
|
||||
|
||||
status_change_start(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 1|2|4|8);
|
||||
status_change_start(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_LOADED|SCSTART_NORATEDEF);
|
||||
}
|
||||
|
||||
pc_scdata_received(sd);
|
||||
|
100
src/map/clif.c
100
src/map/clif.c
@ -753,22 +753,22 @@ void clif_dropflooritem(struct flooritem_data* fitem)
|
||||
|
||||
nullpo_retv(fitem);
|
||||
|
||||
if (fitem->item_data.nameid == 0)
|
||||
if (fitem->item.nameid == 0)
|
||||
return;
|
||||
|
||||
WBUFW(buf, offset+0) = header;
|
||||
WBUFL(buf, offset+2) = fitem->bl.id;
|
||||
WBUFW(buf, offset+6) = ((view = itemdb_viewid(fitem->item_data.nameid)) > 0) ? view : fitem->item_data.nameid;
|
||||
WBUFW(buf, offset+6) = ((view = itemdb_viewid(fitem->item.nameid)) > 0) ? view : fitem->item.nameid;
|
||||
#if PACKETVER >= 20130000
|
||||
WBUFW(buf, offset+8) = itemtype(fitem->item_data.nameid);
|
||||
WBUFW(buf, offset+8) = itemtype(fitem->item.nameid);
|
||||
offset +=2;
|
||||
#endif
|
||||
WBUFB(buf, offset+8) = fitem->item_data.identify;
|
||||
WBUFB(buf, offset+8) = fitem->item.identify;
|
||||
WBUFW(buf, offset+9) = fitem->bl.x;
|
||||
WBUFW(buf, offset+11) = fitem->bl.y;
|
||||
WBUFB(buf, offset+13) = fitem->subx;
|
||||
WBUFB(buf, offset+14) = fitem->suby;
|
||||
WBUFW(buf, offset+15) = fitem->item_data.amount;
|
||||
WBUFW(buf, offset+15) = fitem->item.amount;
|
||||
|
||||
clif_send(buf, packet_len(header), &fitem->bl, AREA);
|
||||
}
|
||||
@ -4498,14 +4498,14 @@ void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fi
|
||||
WFIFOHEAD(fd,packet_len(0x9d));
|
||||
WFIFOW(fd,0)=0x9d;
|
||||
WFIFOL(fd,2)=fitem->bl.id;
|
||||
if((view = itemdb_viewid(fitem->item_data.nameid)) > 0)
|
||||
if((view = itemdb_viewid(fitem->item.nameid)) > 0)
|
||||
WFIFOW(fd,6)=view;
|
||||
else
|
||||
WFIFOW(fd,6)=fitem->item_data.nameid;
|
||||
WFIFOB(fd,8)=fitem->item_data.identify;
|
||||
WFIFOW(fd,6)=fitem->item.nameid;
|
||||
WFIFOB(fd,8)=fitem->item.identify;
|
||||
WFIFOW(fd,9)=fitem->bl.x;
|
||||
WFIFOW(fd,11)=fitem->bl.y;
|
||||
WFIFOW(fd,13)=fitem->item_data.amount;
|
||||
WFIFOW(fd,13)=fitem->item.amount;
|
||||
WFIFOB(fd,15)=fitem->subx;
|
||||
WFIFOB(fd,16)=fitem->suby;
|
||||
WFIFOSET(fd,packet_len(0x9d));
|
||||
@ -13173,7 +13173,7 @@ void clif_parse_GM_Item_Monster(int fd, struct map_session_data *sd)
|
||||
// Item
|
||||
if( (id = itemdb_searchname(str)) ) {
|
||||
StringBuf_Init(&command);
|
||||
if( id->type == IT_WEAPON || id->type == IT_ARMOR ) //Nonstackable
|
||||
if( !itemdb_isstackable2(id) ) //Nonstackable
|
||||
StringBuf_Printf(&command, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand_symbol, id->nameid);
|
||||
else
|
||||
StringBuf_Printf(&command, "%citem %d 20", atcommand_symbol, id->nameid);
|
||||
@ -17340,21 +17340,36 @@ void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) {
|
||||
|
||||
/**
|
||||
* Marks Crimson Marker target on mini-map to the caster
|
||||
* TODO: Please, check the proper packet for Crimson Marker [Cydh]
|
||||
* 09C1 <id>.L <x>.W <y>.W (ZC_C_MARKERINFO)
|
||||
* @param fd
|
||||
* @param bl Crimson Marker target
|
||||
* @param remove True remove the marker from map, false therwise
|
||||
**/
|
||||
void clif_crimson_marker(int fd, struct block_list *bl, bool remove) {
|
||||
WFIFOHEAD(fd,packet_len(0x107));
|
||||
WFIFOW(fd,0) = 0x107;
|
||||
WFIFOL(fd,2) = bl->id;
|
||||
WFIFOW(fd,6) = (remove) ? -1 : bl->x;
|
||||
WFIFOW(fd,8) = (remove) ? -1 : bl->y;
|
||||
WFIFOSET(fd,packet_len(0x107));
|
||||
void clif_crimson_marker(struct map_session_data *sd, struct block_list *bl, bool remove) {
|
||||
struct s_packet_db* info;
|
||||
int cmd = 0;
|
||||
int16 len;
|
||||
unsigned char buf[11];
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
cmd = packet_db_ack[sd->packet_ver][ZC_C_MARKERINFO];
|
||||
if (!cmd)
|
||||
cmd = 0x09C1; //default
|
||||
info = &packet_db[sd->packet_ver][cmd];
|
||||
if (!(len = info->len))
|
||||
return;
|
||||
|
||||
WBUFW(buf, 0) = cmd;
|
||||
WBUFL(buf, info->pos[0]) = bl->id;
|
||||
WBUFW(buf, info->pos[1]) = (remove ? -1 : bl->x);
|
||||
WBUFW(buf, info->pos[2]) = (remove ? -1 : bl->y);
|
||||
clif_send(buf, len, &sd->bl, SELF);
|
||||
}
|
||||
|
||||
///TODO: Special item that obtained, must be broadcasted by this packet
|
||||
/**
|
||||
* !TODO: Special item that obtained, must be broadcasted by this packet
|
||||
* 07fd ?? (ZC_BROADCASTING_SPECIAL_ITEM_OBTAIN)
|
||||
*/
|
||||
//void clif_broadcast_obtain_special_item() {}
|
||||
|
||||
#ifdef DUMP_UNKNOWN_PACKET
|
||||
@ -17531,7 +17546,7 @@ void packetdb_readdb(void)
|
||||
int max_cmd=-1;
|
||||
bool skip_ver = false;
|
||||
int warned = 0;
|
||||
char *str[64],*p,*str2[64],*p2,w1[256],w2[256];
|
||||
int packet_ver = MAX_PACKET_VER; // read into packet_db's version by default
|
||||
int packet_len_table[MAX_PACKET_DB] = {
|
||||
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@ -18012,6 +18027,7 @@ void packetdb_readdb(void)
|
||||
{ "ZC_PERSONAL_INFOMATION", ZC_PERSONAL_INFOMATION},
|
||||
{ "ZC_PERSONAL_INFOMATION_CHN", ZC_PERSONAL_INFOMATION_CHN},
|
||||
{ "ZC_CLEAR_DIALOG", ZC_CLEAR_DIALOG},
|
||||
{ "ZC_C_MARKERINFO", ZC_C_MARKERINFO},
|
||||
};
|
||||
const char *filename[] = { "packet_db.txt", DBIMPORT"/packet_db.txt"};
|
||||
int f;
|
||||
@ -18022,14 +18038,14 @@ void packetdb_readdb(void)
|
||||
packet_len(i) = packet_len_table[i];
|
||||
|
||||
clif_config.packet_db_ver = MAX_PACKET_VER;
|
||||
for(f = 0; f<ARRAYLENGTH(filename); f++){
|
||||
for(f = 0; f < ARRAYLENGTH(filename); f++){
|
||||
int ln=0;
|
||||
int entries = 0;
|
||||
int packet_ver = MAX_PACKET_VER; // read into packet_db's version by default
|
||||
|
||||
sprintf(line, "%s/%s", db_path,filename[f]);
|
||||
if( (fp=fopen(line,"r"))==NULL ){
|
||||
if(f==0) {
|
||||
char *str[64],*p,*str2[64],*p2;
|
||||
|
||||
sprintf(line, "%s/%s", db_path, filename[f]);
|
||||
if( (fp = fopen(line,"r")) == NULL ){
|
||||
if (f == 0) {
|
||||
ShowFatalError("Can't read %s\n", line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -18037,12 +18053,12 @@ void packetdb_readdb(void)
|
||||
}
|
||||
|
||||
while( fgets(line, sizeof(line), fp) ) {
|
||||
char w1[256],w2[256];
|
||||
ln++;
|
||||
if(line[0]=='/' && line[1]=='/')
|
||||
continue;
|
||||
if (sscanf(line,"%255[^:]: %255[^\r\n]",w1,w2) == 2)
|
||||
{
|
||||
if(strcmpi(w1,"packet_ver")==0) {
|
||||
if (sscanf(line,"%255[^:]: %255[^\r\n]",w1,w2) == 2) {
|
||||
if (strcmpi(w1,"packet_ver") == 0) {
|
||||
int prev_ver = packet_ver;
|
||||
skip_ver = false;
|
||||
packet_ver = atoi(w2);
|
||||
@ -18080,7 +18096,7 @@ void packetdb_readdb(void)
|
||||
memcpy(&packet_db_ack[packet_ver], &packet_db_ack[prev_ver], sizeof(packet_db_ack[0]));
|
||||
continue;
|
||||
} else if(strcmpi(w1,"packet_db_ver")==0) {
|
||||
if(strcmpi(w2,"default")==0) //This is the preferred version.
|
||||
if (strcmpi(w2,"default") == 0) //This is the preferred version.
|
||||
clif_config.packet_db_ver = MAX_PACKET_VER;
|
||||
else // to manually set the packet DB version
|
||||
clif_config.packet_db_ver = cap_value(atoi(w2), 0, MAX_PACKET_VER);
|
||||
@ -18092,14 +18108,15 @@ void packetdb_readdb(void)
|
||||
continue; // Skipping current packet version
|
||||
|
||||
memset(str,0,sizeof(str));
|
||||
for(j=0,p=line;j<4 && p; ++j) {
|
||||
str[j]=p;
|
||||
p=strchr(p,',');
|
||||
if(p) *p++=0;
|
||||
for (j = 0, p = line; j < 4 && p; ++j) {
|
||||
str[j] = p;
|
||||
p = strchr(p,',');
|
||||
if (p)
|
||||
*p++=0;
|
||||
}
|
||||
if(str[0]==NULL)
|
||||
if (str[0] == NULL)
|
||||
continue;
|
||||
cmd=strtol(str[0],(char **)NULL,0);
|
||||
cmd = strtol(str[0],(char **)NULL,0);
|
||||
|
||||
if(max_cmd < cmd)
|
||||
max_cmd = cmd;
|
||||
@ -18139,11 +18156,12 @@ void packetdb_readdb(void)
|
||||
ShowError("packet_db: packet error\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for(j=0,p2=str[3];p2;j++){
|
||||
for(j = 0, p2 = str[3]; p2; j++){
|
||||
short k;
|
||||
str2[j]=p2;
|
||||
p2=strchr(p2,':');
|
||||
if(p2) *p2++=0;
|
||||
str2[j] = p2;
|
||||
p2 = strchr(p2,':');
|
||||
if(p2)
|
||||
*p2++=0;
|
||||
k = atoi(str2[j]);
|
||||
// if (packet_db[packet_ver][cmd].pos[j] != k && clif_config.prefer_packet_db) // not used for now
|
||||
|
||||
|
@ -46,6 +46,7 @@ enum e_packet_ack {
|
||||
ZC_PERSONAL_INFOMATION,
|
||||
ZC_PERSONAL_INFOMATION_CHN,
|
||||
ZC_CLEAR_DIALOG,
|
||||
ZC_C_MARKERINFO,
|
||||
//add other here
|
||||
MAX_ACK_FUNC //auto upd len
|
||||
};
|
||||
@ -380,7 +381,6 @@ enum clif_messages {
|
||||
NEED_REINS_OF_MOUNT = 0x78c,
|
||||
};
|
||||
|
||||
|
||||
enum e_personalinfo {
|
||||
PINFO_BASIC = 0,
|
||||
PINFO_PREMIUM,
|
||||
@ -881,7 +881,7 @@ void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char
|
||||
void clif_ranklist(struct map_session_data *sd, int16 rankingType);
|
||||
void clif_update_rankingpoint(struct map_session_data *sd, int rankingtype, int point);
|
||||
|
||||
void clif_crimson_marker(int fd, struct block_list *bl, bool remove);
|
||||
void clif_crimson_marker(struct map_session_data *sd, struct block_list *bl, bool remove);
|
||||
|
||||
//void clif_broadcast_obtain_special_item(); ///TODO!
|
||||
|
||||
|
@ -1430,15 +1430,6 @@ static int itemdb_read_sqldb(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique item ID function
|
||||
* @param sd : Player
|
||||
* @return unique_id
|
||||
*/
|
||||
uint64 itemdb_unique_id(struct map_session_data *sd) {
|
||||
return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
|
||||
}
|
||||
|
||||
/** Check if the item is restricted by item_noequip.txt
|
||||
* @param id Item that will be checked
|
||||
* @param m Map ID
|
||||
@ -1465,10 +1456,10 @@ bool itemdb_isNoEquip(struct item_data *id, uint16 m) {
|
||||
*/
|
||||
bool itemdb_is_spellbook2(unsigned short nameid) {
|
||||
unsigned char i;
|
||||
if (!nameid || !itemdb_exists(nameid))
|
||||
if (!nameid || !itemdb_exists(nameid) || !skill_spellbook_count)
|
||||
return false;
|
||||
ARR_FIND(0, MAX_SKILL_SPELLBOOK_DB, i, skill_spellbook_db[i].nameid == nameid);
|
||||
if (i >= MAX_SKILL_SPELLBOOK_DB)
|
||||
if (i == MAX_SKILL_SPELLBOOK_DB)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -480,7 +480,6 @@ bool itemdb_isequip2(struct item_data *id);
|
||||
char itemdb_isidentified(unsigned short nameid);
|
||||
bool itemdb_isstackable2(struct item_data *id);
|
||||
#define itemdb_isstackable(nameid) itemdb_isstackable2(itemdb_search(nameid))
|
||||
uint64 itemdb_unique_id(struct map_session_data *sd); // Unique Item ID
|
||||
bool itemdb_isNoEquip(struct item_data *id, uint16 m);
|
||||
|
||||
struct item_combo *itemdb_combo_exists(unsigned short combo_id);
|
||||
|
@ -1289,8 +1289,8 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
}
|
||||
|
||||
|
||||
if (search_petDB_index(fitem->item_data.nameid, PET_EGG) >= 0)
|
||||
intif_delete_petdata(MakeDWord(fitem->item_data.card[1], fitem->item_data.card[2]));
|
||||
if (search_petDB_index(fitem->item.nameid, PET_EGG) >= 0)
|
||||
intif_delete_petdata(MakeDWord(fitem->item.card[1], fitem->item.card[2]));
|
||||
|
||||
clif_clearflooritem(fitem, 0);
|
||||
map_deliddb(&fitem->bl);
|
||||
@ -1442,14 +1442,14 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
|
||||
* @param flag: &1 MVP item. &2 do stacking check. &4 bypass droppable check.
|
||||
* @return 0:failure, x:item_gid [MIN_FLOORITEM;MAX_FLOORITEM]==[2;START_ACCOUNT_NUM]
|
||||
*------------------------------------------*/
|
||||
int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags)
|
||||
int map_addflooritem(struct item *item,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags)
|
||||
{
|
||||
int r;
|
||||
struct flooritem_data *fitem=NULL;
|
||||
|
||||
nullpo_ret(item_data);
|
||||
nullpo_ret(item);
|
||||
|
||||
if(!(flags&4) && battle_config.item_onfloor && (itemdb_traderight(item_data->nameid)&1) )
|
||||
if(!(flags&4) && battle_config.item_onfloor && (itemdb_traderight(item->nameid)&1) )
|
||||
return 0; //can't be dropped
|
||||
|
||||
if(!map_searchrandfreecell(m,&x,&y,flags&2?1:0))
|
||||
@ -1475,8 +1475,8 @@ int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,i
|
||||
fitem->third_get_charid = third_charid;
|
||||
fitem->third_get_tick = fitem->second_get_tick + (flags&1 ? battle_config.mvp_item_third_get_time : battle_config.item_third_get_time);
|
||||
|
||||
memcpy(&fitem->item_data,item_data,sizeof(*item_data));
|
||||
fitem->item_data.amount=amount;
|
||||
memcpy(&fitem->item,item,sizeof(*item));
|
||||
fitem->item.amount=amount;
|
||||
fitem->subx=(r&3)*3+3;
|
||||
fitem->suby=((r>>2)&3)*3+3;
|
||||
fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0);
|
||||
|
@ -425,7 +425,7 @@ struct flooritem_data {
|
||||
int cleartimer;
|
||||
int first_get_charid,second_get_charid,third_get_charid;
|
||||
unsigned int first_get_tick,second_get_tick,third_get_tick;
|
||||
struct item item_data;
|
||||
struct item item;
|
||||
};
|
||||
|
||||
enum _sp {
|
||||
@ -795,7 +795,7 @@ bool map_addnpc(int16 m,struct npc_data *);
|
||||
int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data);
|
||||
int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data);
|
||||
void map_clearflooritem(struct block_list* bl);
|
||||
int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags);
|
||||
int map_addflooritem(struct item *item,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags);
|
||||
|
||||
// instances
|
||||
int map_addinstancemap(const char*,int);
|
||||
|
@ -417,7 +417,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target)
|
||||
return true;
|
||||
} while(0);
|
||||
|
||||
status_change_start(src, target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0);
|
||||
status_change_start(src, target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, SCSTART_NOAVOID);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1603,15 +1603,15 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
|
||||
|
||||
fitem = (struct flooritem_data *)tbl;
|
||||
//Logs items, taken by (L)ooter Mobs [Lupus]
|
||||
log_pick_mob(md, LOG_TYPE_LOOT, fitem->item_data.amount, &fitem->item_data);
|
||||
log_pick_mob(md, LOG_TYPE_LOOT, fitem->item.amount, &fitem->item);
|
||||
|
||||
if (md->lootitem_count < LOOTITEM_SIZE) {
|
||||
memcpy (&md->lootitem[md->lootitem_count++], &fitem->item_data, sizeof(md->lootitem[0]));
|
||||
memcpy (&md->lootitem[md->lootitem_count++], &fitem->item, sizeof(md->lootitem[0]));
|
||||
} else { //Destroy first looted item...
|
||||
if (md->lootitem[0].card[0] == CARD0_PET)
|
||||
intif_delete_petdata( MakeDWord(md->lootitem[0].card[1],md->lootitem[0].card[2]) );
|
||||
memmove(&md->lootitem[0], &md->lootitem[1], (LOOTITEM_SIZE-1)*sizeof(md->lootitem[0]));
|
||||
memcpy (&md->lootitem[LOOTITEM_SIZE-1], &fitem->item_data, sizeof(md->lootitem[0]));
|
||||
memcpy (&md->lootitem[LOOTITEM_SIZE-1], &fitem->item, sizeof(md->lootitem[0]));
|
||||
}
|
||||
if (pcdb_checkid(md->vd->class_))
|
||||
{ //Give them walk act/delay to properly mimic players. [Skotlex]
|
||||
|
@ -4175,6 +4175,8 @@ bool npc_unloadfile( const char* path ) {
|
||||
if( found ) /* refresh event cache */
|
||||
npc_read_event_script();
|
||||
|
||||
npc_delsrcfile(path);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
28
src/map/pc.c
28
src/map/pc.c
@ -4311,7 +4311,7 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p
|
||||
clif_additem(sd,i,amount,0);
|
||||
}
|
||||
if( !itemdb_isstackable2(id) && !item->unique_id )
|
||||
sd->status.inventory[i].unique_id = itemdb_unique_id(sd);
|
||||
sd->status.inventory[i].unique_id = pc_generate_unique_id(sd);
|
||||
log_pick_pc(sd, log_type, amount, &sd->status.inventory[i]);
|
||||
|
||||
sd->weight += w;
|
||||
@ -4471,7 +4471,7 @@ bool pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
|
||||
}
|
||||
|
||||
//This function takes care of giving the item to whoever should have it, considering party-share options.
|
||||
if ((flag = party_share_loot(p,sd,&fitem->item_data, fitem->first_get_charid))) {
|
||||
if ((flag = party_share_loot(p,sd,&fitem->item, fitem->first_get_charid))) {
|
||||
clif_additem(sd,0,0,flag);
|
||||
return true;
|
||||
}
|
||||
@ -9546,7 +9546,7 @@ void pc_check_available_item(struct map_session_data *sd) {
|
||||
continue;
|
||||
}
|
||||
if (!sd->status.inventory[i].unique_id && !itemdb_isstackable(it))
|
||||
sd->status.inventory[i].unique_id = itemdb_unique_id(sd);
|
||||
sd->status.inventory[i].unique_id = pc_generate_unique_id(sd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9564,7 +9564,7 @@ void pc_check_available_item(struct map_session_data *sd) {
|
||||
continue;
|
||||
}
|
||||
if (!sd->status.cart[i].unique_id && !itemdb_isstackable(it))
|
||||
sd->status.cart[i].unique_id = itemdb_unique_id(sd);
|
||||
sd->status.cart[i].unique_id = pc_generate_unique_id(sd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9582,7 +9582,7 @@ void pc_check_available_item(struct map_session_data *sd) {
|
||||
continue;
|
||||
}
|
||||
if (!sd->status.storage.items[i].unique_id && !itemdb_isstackable(it))
|
||||
sd->status.storage.items[i].unique_id = itemdb_unique_id(sd);
|
||||
sd->status.storage.items[i].unique_id = pc_generate_unique_id(sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10964,22 +10964,21 @@ enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int mo
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Cirmson Marker data from caster
|
||||
* Clear Crimson Marker data from caster
|
||||
* @param sd: Player
|
||||
**/
|
||||
void pc_crimson_marker_clear(struct map_session_data *sd) {
|
||||
uint8 i;
|
||||
|
||||
if (!sd || !(&sd->c_marker) || !sd->c_marker.target)
|
||||
if (!sd)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_SKILL_CRIMSON_MARKER; i++) {
|
||||
struct block_list *bl = NULL;
|
||||
if (sd->c_marker.target[i] && (bl = map_id2bl(sd->c_marker.target[i])))
|
||||
if (sd->c_marker[i] && (bl = map_id2bl(sd->c_marker[i])))
|
||||
status_change_end(bl,SC_C_MARKER,INVALID_TIMER);
|
||||
sd->c_marker.target[i] = 0;
|
||||
sd->c_marker[i] = 0;
|
||||
}
|
||||
sd->c_marker.count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -11233,6 +11232,15 @@ bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short inde
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Unique item ID for player
|
||||
* @param sd : Player
|
||||
* @return A generated Unique item ID
|
||||
*/
|
||||
uint64 pc_generate_unique_id(struct map_session_data *sd) {
|
||||
return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* pc Init/Terminate
|
||||
*------------------------------------------*/
|
||||
|
@ -591,11 +591,8 @@ struct map_session_data {
|
||||
|
||||
uint16 dmglog[DAMAGELOG_SIZE_PC]; ///target ids
|
||||
|
||||
struct s_crimson_marker { ///Store target that marked by Crimson Marker [Cydh]
|
||||
int target[MAX_SKILL_CRIMSON_MARKER]; //Target id storage
|
||||
uint8 count; //Count of target for skill used (i.e. RL_D_TAIL).
|
||||
} c_marker;
|
||||
bool flicker; ///Is Flicker Skill skill as player's last action? [Cydh]
|
||||
int c_marker[MAX_SKILL_CRIMSON_MARKER]; /// Store target that marked by Crimson Marker [Cydh]
|
||||
bool flicker; /// Check RL_FLICKER usage status [Cydh]
|
||||
|
||||
int storage_size; /// Holds player storage size (VIP system).
|
||||
#ifdef VIP_ENABLE
|
||||
@ -879,6 +876,8 @@ char pc_additem(struct map_session_data *sd, struct item *item, int amount, e_lo
|
||||
char pc_getzeny(struct map_session_data *sd, int zeny, enum e_log_pick_type type, struct map_session_data *tsd);
|
||||
char pc_delitem(struct map_session_data *sd, int n, int amount, int type, short reason, e_log_pick_type log_type);
|
||||
|
||||
uint64 pc_generate_unique_id(struct map_session_data *sd);
|
||||
|
||||
//Bound items
|
||||
int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist);
|
||||
|
||||
|
@ -946,8 +946,8 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
|
||||
} else{
|
||||
struct flooritem_data *fitem = (struct flooritem_data *)target;
|
||||
if(pd->loot->count < pd->loot->max){
|
||||
memcpy(&pd->loot->item[pd->loot->count++],&fitem->item_data,sizeof(pd->loot->item[0]));
|
||||
pd->loot->weight += itemdb_weight(fitem->item_data.nameid)*fitem->item_data.amount;
|
||||
memcpy(&pd->loot->item[pd->loot->count++],&fitem->item,sizeof(pd->loot->item[0]));
|
||||
pd->loot->weight += itemdb_weight(fitem->item.nameid)*fitem->item.amount;
|
||||
map_clearflooritem(target);
|
||||
}
|
||||
//Target is unlocked regardless of whether it was picked or not.
|
||||
|
@ -2369,6 +2369,14 @@ void script_hardcoded_constants(void) {
|
||||
script_set_constant("BSF_REM_DEBUFF",BSF_REM_DEBUFF,false);
|
||||
script_set_constant("BSF_ALL",BSF_ALL,false);
|
||||
script_set_constant("BSF_CLEARALL",BSF_CLEARALL,false);
|
||||
|
||||
/* sc_start flags */
|
||||
script_set_constant("SCSTART_NONE",SCSTART_NONE,false);
|
||||
script_set_constant("SCSTART_NOAVOID",SCSTART_NOAVOID,false);
|
||||
script_set_constant("SCSTART_NOTICKDEF",SCSTART_NOTICKDEF,false);
|
||||
script_set_constant("SCSTART_LOADED",SCSTART_LOADED,false);
|
||||
script_set_constant("SCSTART_NORATEDEF",SCSTART_NORATEDEF,false);
|
||||
script_set_constant("SCSTART_NOICON",SCSTART_NOICON,false);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@ -7753,8 +7761,31 @@ BUILDIN_FUNC(strnpcinfo)
|
||||
}
|
||||
|
||||
|
||||
// aegis->athena slot position conversion table
|
||||
static unsigned int equip[] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_GARMENT,EQP_SHOES,EQP_ACC_L,EQP_ACC_R,EQP_HEAD_MID,EQP_HEAD_LOW,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_GARMENT,EQP_AMMO,EQP_SHADOW_ARMOR,EQP_SHADOW_WEAPON,EQP_SHADOW_SHIELD,EQP_SHADOW_SHOES,EQP_SHADOW_ACC_R,EQP_SHADOW_ACC_L};
|
||||
/// aegis->athena slot position conversion table
|
||||
/// Index is used by EQI_ in db/const.txt
|
||||
static unsigned int equip[] = {
|
||||
EQP_HEAD_TOP,
|
||||
EQP_ARMOR,
|
||||
EQP_HAND_L,
|
||||
EQP_HAND_R,
|
||||
EQP_GARMENT,
|
||||
EQP_SHOES,
|
||||
EQP_ACC_L,
|
||||
EQP_ACC_R,
|
||||
EQP_HEAD_MID,
|
||||
EQP_HEAD_LOW,
|
||||
EQP_COSTUME_HEAD_LOW,
|
||||
EQP_COSTUME_HEAD_MID,
|
||||
EQP_COSTUME_HEAD_TOP,
|
||||
EQP_COSTUME_GARMENT,
|
||||
EQP_AMMO,
|
||||
EQP_SHADOW_ARMOR,
|
||||
EQP_SHADOW_WEAPON,
|
||||
EQP_SHADOW_SHIELD,
|
||||
EQP_SHADOW_SHOES,
|
||||
EQP_SHADOW_ACC_R,
|
||||
EQP_SHADOW_ACC_L
|
||||
};
|
||||
|
||||
/*==========================================
|
||||
* GetEquipID(Pos); Pos: 1-14
|
||||
@ -10267,12 +10298,12 @@ BUILDIN_FUNC(getareausers)
|
||||
*------------------------------------------*/
|
||||
static int buildin_getareadropitem_sub(struct block_list *bl,va_list ap)
|
||||
{
|
||||
int item=va_arg(ap,int);
|
||||
int nameid=va_arg(ap,int);
|
||||
int *amount=va_arg(ap,int *);
|
||||
struct flooritem_data *drop=(struct flooritem_data *)bl;
|
||||
|
||||
if(drop->item_data.nameid==item)
|
||||
(*amount)+=drop->item_data.amount;
|
||||
if(drop->item.nameid==nameid)
|
||||
(*amount)+=drop->item.amount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -10280,7 +10311,7 @@ BUILDIN_FUNC(getareadropitem)
|
||||
{
|
||||
const char *str;
|
||||
int16 m,x0,y0,x1,y1;
|
||||
int item,amount=0;
|
||||
int nameid,amount=0;
|
||||
struct script_data *data;
|
||||
|
||||
str=script_getstr(st,2);
|
||||
@ -10294,18 +10325,18 @@ BUILDIN_FUNC(getareadropitem)
|
||||
if( data_isstring(data) ){
|
||||
const char *name=conv_str(st,data);
|
||||
struct item_data *item_data = itemdb_searchname(name);
|
||||
item=UNKNOWN_ITEM_ID;
|
||||
nameid=UNKNOWN_ITEM_ID;
|
||||
if( item_data )
|
||||
item=item_data->nameid;
|
||||
nameid=item_data->nameid;
|
||||
}else
|
||||
item=conv_num(st,data);
|
||||
nameid=conv_num(st,data);
|
||||
|
||||
if( (m=map_mapname2mapid(str))< 0){
|
||||
script_pushint(st,-1);
|
||||
return 0;
|
||||
}
|
||||
map_foreachinarea(buildin_getareadropitem_sub,
|
||||
m,x0,y0,x1,y1,BL_ITEM,item,&amount);
|
||||
m,x0,y0,x1,y1,BL_ITEM,nameid,&amount);
|
||||
script_pushint(st,amount);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@ -10492,7 +10523,7 @@ BUILDIN_FUNC(getscrate)
|
||||
bl = map_id2bl(st->rid);
|
||||
|
||||
if (bl)
|
||||
rate = status_get_sc_def(NULL,bl, (sc_type)type, 10000, 10000, 0);
|
||||
rate = status_get_sc_def(NULL,bl, (sc_type)type, 10000, 10000, SCSTART_NONE);
|
||||
|
||||
script_pushint(st,rate);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -16674,7 +16705,7 @@ BUILDIN_FUNC(mercenary_sc_start)
|
||||
tick = script_getnum(st,3);
|
||||
val1 = script_getnum(st,4);
|
||||
|
||||
status_change_start(NULL, &sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2);
|
||||
status_change_start(NULL, &sd->md->bl, type, 10000, val1, 0, 0, 0, tick, SCSTART_NOTICKDEF);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
940
src/map/skill.c
940
src/map/skill.c
File diff suppressed because it is too large
Load Diff
@ -18,10 +18,10 @@ struct status_change_entry;
|
||||
#define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements
|
||||
#define MAX_SKILL_ARROW_DB 150 /// Max Arrow Creation DB
|
||||
#define MAX_ARROW_RESULT 5 /// Max Arrow results/created
|
||||
#define MAX_SKILL_ABRA_DB 350 /// Max Skill list of Abracadabra DB
|
||||
#define MAX_SKILL_IMPROVISE_DB 50 /// Max Skill for Improvise
|
||||
#define MAX_SKILL_ABRA_DB 160 /// Max Skill list of Abracadabra DB
|
||||
#define MAX_SKILL_IMPROVISE_DB 30 /// Max Skill for Improvise
|
||||
#define MAX_SKILL_LEVEL 100 /// Max Skill Level
|
||||
#define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets
|
||||
#define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
|
||||
#define SKILL_NAME_LENGTH 31 /// Max Skill Name length
|
||||
#define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
|
||||
|
||||
@ -101,7 +101,7 @@ enum e_skill_inf3 {
|
||||
/// Flags passed to skill_attack/skill_area_sub
|
||||
enum e_skill_display {
|
||||
SD_LEVEL = 0x1000, // skill_attack will send -1 instead of skill level (affects display of some skills)
|
||||
SD_ANIMATION = 0x2000, // skill_attack will use '5' instead of the skill's 'type' (this makes skills show an animation)
|
||||
SD_ANIMATION = 0x2000, // skill_attack will use '5' instead of the skill's 'type' (this makes skills show an animation). Also being used in skill_attack for splash skill (NK_SPLASH) to check status_check_skilluse
|
||||
SD_SPLASH = 0x4000, // skill_area_sub will count targets in skill_area_temp[2]
|
||||
SD_PREAMBLE = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
|
||||
};
|
||||
@ -259,22 +259,23 @@ struct skill_unit_group_tickset {
|
||||
|
||||
|
||||
enum {
|
||||
UF_DEFNOTENEMY = 0x0001, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
UF_NOREITERATION = 0x0002, // Spell cannot be stacked
|
||||
UF_NOFOOTSET = 0x0004, // Spell cannot be cast near/on targets
|
||||
UF_NOOVERLAP = 0x0008, // Spell effects do not overlap
|
||||
UF_PATHCHECK = 0x0010, // Only cells with a shootable path will be placed
|
||||
UF_NOPC = 0x0020, // May not target players
|
||||
UF_NOMOB = 0x0040, // May not target mobs
|
||||
UF_SKILL = 0x0080, // May target skills
|
||||
UF_DANCE = 0x0100, // Dance
|
||||
UF_ENSEMBLE = 0x0200, // Duet
|
||||
UF_SONG = 0x0400, // Song
|
||||
UF_DUALMODE = 0x0800, // Spells should trigger both ontimer and onplace/onout/onleft effects.
|
||||
UF_NOKNOCKBACK = 0x1000, // Skill unit cannot be knocked back
|
||||
UF_RANGEDSINGLEUNIT = 0x2000, // hack for ranged layout, only display center
|
||||
UF_REM_CRAZYWEED = 0x4000, // removed by Crazyweed
|
||||
UF_REM_FIRERAIN = 0x8000, // removed by Fire Rain
|
||||
UF_DEFNOTENEMY = 0x00001, // If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
||||
UF_NOREITERATION = 0x00002, // Spell cannot be stacked
|
||||
UF_NOFOOTSET = 0x00004, // Spell cannot be cast near/on targets
|
||||
UF_NOOVERLAP = 0x00008, // Spell effects do not overlap
|
||||
UF_PATHCHECK = 0x00010, // Only cells with a shootable path will be placed
|
||||
UF_NOPC = 0x00020, // May not target players
|
||||
UF_NOMOB = 0x00040, // May not target mobs
|
||||
UF_SKILL = 0x00080, // May target skills
|
||||
UF_DANCE = 0x00100, // Dance
|
||||
UF_ENSEMBLE = 0x00200, // Duet
|
||||
UF_SONG = 0x00400, // Song
|
||||
UF_DUALMODE = 0x00800, // Spells should trigger both ontimer and onplace/onout/onleft effects.
|
||||
UF_NOKNOCKBACK = 0x01000, // Skill unit cannot be knocked back
|
||||
UF_RANGEDSINGLEUNIT = 0x02000, // hack for ranged layout, only display center
|
||||
UF_REM_CRAZYWEED = 0x04000, // removed by Crazyweed
|
||||
UF_REM_FIRERAIN = 0x08000, // removed by Fire Rain
|
||||
UF_KNOCKBACK_GROUP = 0x10000, // knockback skill unit with its group instead of single unit
|
||||
};
|
||||
|
||||
/// Create Database item
|
||||
@ -303,9 +304,7 @@ struct s_skill_abra_db {
|
||||
int per[MAX_SKILL_LEVEL]; /// Probability summoned
|
||||
};
|
||||
extern struct s_skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
|
||||
|
||||
extern int enchant_eff[5];
|
||||
extern int deluge_eff[5];
|
||||
extern unsigned short skill_abra_count;
|
||||
|
||||
void do_init_skill(void);
|
||||
void do_final_skill(void);
|
||||
@ -414,6 +413,7 @@ int skill_check_unit_cell(uint16 skill_id,int16 m,int16 x,int16 y,int unit_id);
|
||||
int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range);
|
||||
int skill_unit_move(struct block_list *bl,unsigned int tick,int flag);
|
||||
void skill_unit_move_unit_group( struct skill_unit_group *group, int16 m,int16 dx,int16 dy);
|
||||
void skill_unit_move_unit(struct block_list *bl, int dx, int dy);
|
||||
|
||||
struct skill_unit_group *skill_check_dancing( struct block_list *src );
|
||||
|
||||
@ -1984,17 +1984,19 @@ struct s_skill_spellbook_db {
|
||||
unsigned short point;
|
||||
};
|
||||
extern struct s_skill_spellbook_db skill_spellbook_db[MAX_SKILL_SPELLBOOK_DB];
|
||||
int skill_spellbook (struct map_session_data *sd, unsigned short nameid);
|
||||
extern unsigned short skill_spellbook_count;
|
||||
void skill_spellbook (struct map_session_data *sd, unsigned short nameid);
|
||||
int skill_block_check(struct block_list *bl, enum sc_type type, uint16 skill_id);
|
||||
|
||||
/**
|
||||
* Guilottine Cross
|
||||
**/
|
||||
#define MAX_SKILL_MAGICMUSHROOM_DB 23
|
||||
#define MAX_SKILL_MAGICMUSHROOM_DB 25
|
||||
struct s_skill_magicmushroom_db {
|
||||
uint16 skill_id;
|
||||
};
|
||||
extern struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
|
||||
extern unsigned short skill_magicmushroom_count;
|
||||
int skill_maelstrom_suction(struct block_list *bl, va_list ap);
|
||||
bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit);
|
||||
|
||||
|
282
src/map/status.c
282
src/map/status.c
@ -689,7 +689,7 @@ void initChangeTables(void)
|
||||
set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_MAXHP );
|
||||
set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
|
||||
set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
|
||||
add_sc( SC_CHAOSPANIC , SC__CHAOS );
|
||||
add_sc( SC_CHAOSPANIC , SC_CONFUSION );
|
||||
add_sc( SC_BLOODYLUST , SC_BERSERK );
|
||||
add_sc( SC_FEINTBOMB , SC__FEINTBOMB );
|
||||
|
||||
@ -801,6 +801,7 @@ void initChangeTables(void)
|
||||
/* Rebellion */
|
||||
add_sc( RL_MASS_SPIRAL , SC_BLEEDING );
|
||||
add_sc( RL_HAMMER_OF_GOD , SC_STUN );
|
||||
set_sc( RL_H_MINE , SC_H_MINE , SI_H_MINE , SCB_NONE);
|
||||
set_sc( RL_B_TRAP , SC_B_TRAP , SI_B_TRAP , SCB_SPEED );
|
||||
set_sc( RL_E_CHAIN , SC_E_CHAIN , SI_E_CHAIN , SCB_NONE );
|
||||
set_sc( RL_P_ALTER , SC_P_ALTER , SI_P_ALTER , SCB_NONE );
|
||||
@ -981,7 +982,6 @@ void initChangeTables(void)
|
||||
StatusIconChangeTable[SC_MTF_CRIDAMAGE] = SI_MTF_CRIDAMAGE;
|
||||
StatusIconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
|
||||
StatusIconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
|
||||
StatusIconChangeTable[SC_H_MINE] = SI_H_MINE;
|
||||
StatusIconChangeTable[SC_QD_SHOT_READY] = SI_E_QD_SHOT_READY;
|
||||
StatusIconChangeTable[SC_HEAT_BARREL_AFTER] = SI_HEAT_BARREL_AFTER;
|
||||
StatusIconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS;
|
||||
@ -1918,9 +1918,8 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
return false;
|
||||
if(skill_id == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
|
||||
return false;
|
||||
if (tsc->data[SC__MANHOLE])
|
||||
if (!(skill_get_inf3(skill_id)&INF3_USABLE_MANHOLE))
|
||||
return false;
|
||||
if (tsc->data[SC__MANHOLE] && !(skill_get_inf3(skill_id)&INF3_USABLE_MANHOLE))
|
||||
return false;
|
||||
}
|
||||
|
||||
// If targetting, cloak+hide protect you, otherwise only hiding does.
|
||||
@ -5491,6 +5490,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
if(sc->data[SC_TINDER_BREAKER] || sc->data[SC_TINDER_BREAKER2])
|
||||
return 1; // 1 = min flee
|
||||
|
||||
// Fixed value
|
||||
if(sc->data[SC_INCFLEE])
|
||||
flee += sc->data[SC_INCFLEE]->val1;
|
||||
if(sc->data[SC_FLEEFOOD])
|
||||
@ -5521,11 +5521,14 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
flee += sc->data[SC_HALLUCINATIONWALK]->val2;
|
||||
if( sc->data[SC_WATER_BARRIER] )
|
||||
flee -= sc->data[SC_WATER_BARRIER]->val3;
|
||||
if( sc->data[SC_C_MARKER] )
|
||||
flee -= sc->data[SC_C_MARKER]->val3;
|
||||
#ifdef RENEWAL
|
||||
if( sc->data[SC_SPEARQUICKEN] )
|
||||
flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
|
||||
#endif
|
||||
|
||||
// Rate value
|
||||
if(sc->data[SC_INCFLEERATE])
|
||||
flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
|
||||
if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
|
||||
@ -5558,8 +5561,8 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
flee += flee * 20 / 100;
|
||||
if (sc->data[SC_TEARGAS])
|
||||
flee -= flee * 50 / 100;
|
||||
if( sc->data[SC_C_MARKER] )
|
||||
flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100;
|
||||
//if( sc->data[SC_C_MARKER] )
|
||||
// flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100;
|
||||
if(sc->data[SC_HEAT_BARREL])
|
||||
flee -= sc->data[SC_HEAT_BARREL]->val4;
|
||||
|
||||
@ -7043,14 +7046,10 @@ void status_change_init(struct block_list *bl)
|
||||
* @param type: Status change (SC_*)
|
||||
* @param rate: Initial percentage rate of affecting bl
|
||||
* @param tick: Initial duration that the status change affects bl
|
||||
* @param flag: Value which determines what parts to calculate
|
||||
* &1: Cannot be avoided (it has to start)
|
||||
* &2: Tick should not be reduced (by vit, luk, lv, etc)
|
||||
* &4: sc_data loaded, no value has to be altered.
|
||||
* &8: rate should not be reduced
|
||||
* @param flag: Value which determines what parts to calculate. See e_status_change_start_flags
|
||||
* @return adjusted duration based on flag values
|
||||
**/
|
||||
int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
|
||||
int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag)
|
||||
{
|
||||
/// Resistance rate: 10000 = 100%
|
||||
/// Example: 50% (5000) -> sc_def = 5000 -> 25%;
|
||||
@ -7269,6 +7268,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
|
||||
case SC_VOICEOFSIREN:
|
||||
tick_def2 = (status_get_lv(bl) * 100) + ((bl->type == BL_PC)?((TBL_PC*)bl)->status.job_level * 200 : 0);
|
||||
break;
|
||||
case SC_B_TRAP:
|
||||
tick_def = b_status->str * 50; // (custom)
|
||||
break;
|
||||
default:
|
||||
// Effect that cannot be reduced? Likely a buff.
|
||||
if (!(rnd()%10000 < rate))
|
||||
@ -7320,7 +7322,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
|
||||
tick_def = sc_def;
|
||||
|
||||
// Natural resistance
|
||||
if (!(flag&8)) {
|
||||
if (!(flag&SCSTART_NORATEDEF)) {
|
||||
rate -= rate*sc_def/10000;
|
||||
rate -= sc_def2;
|
||||
|
||||
@ -7347,10 +7349,11 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
|
||||
return 0;
|
||||
|
||||
// Even if a status change doesn't have a duration, it should still trigger
|
||||
if (tick < 1) return 1;
|
||||
if (tick < 1)
|
||||
return 1;
|
||||
|
||||
// Rate reduction
|
||||
if (flag&2)
|
||||
// Duration cannot be reduced
|
||||
if (flag&SCSTART_NOTICKDEF)
|
||||
return tick;
|
||||
|
||||
tick -= tick*tick_def/10000;
|
||||
@ -7458,16 +7461,10 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) {
|
||||
* @param rate: Initial percentage rate of affecting bl (0~10000)
|
||||
* @param val1~4: Depends on type of status change
|
||||
* @param tick: Initial duration that the status change affects bl
|
||||
* @param flag: Value which determines what parts to calculate
|
||||
* &1 : Cannot be avoided (it has to start)
|
||||
* &2 : Tick should not be reduced (by vit, luk, lv, etc)
|
||||
* &4 : sc_data loaded, no value has to be altered.
|
||||
* &8 : rate should not be reduced
|
||||
* &16: don't send SI
|
||||
* @param flag: Value which determines what parts to calculate. See e_status_change_start_flags
|
||||
* @return adjusted duration based on flag values
|
||||
**/
|
||||
int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
|
||||
{
|
||||
int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,unsigned char flag) {
|
||||
struct map_session_data *sd = NULL;
|
||||
struct status_change* sc;
|
||||
struct status_change_entry* sce;
|
||||
@ -7565,11 +7562,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
sd = BL_CAST(BL_PC, bl);
|
||||
|
||||
// Adjust tick according to status resistances
|
||||
if( !(flag&(1|4)) ) {
|
||||
if( !(flag&(SCSTART_NOAVOID|SCSTART_LOADED)) ) {
|
||||
tick = status_get_sc_def(src, bl, type, rate, tick, flag);
|
||||
if( !tick ) return 0;
|
||||
if( !tick )
|
||||
return 0;
|
||||
}
|
||||
|
||||
vd = status_get_viewdata(bl);
|
||||
|
||||
undead_flag = battle_check_undead(status->race,status->def_ele);
|
||||
// Check for immunities / sc fails
|
||||
switch (type) {
|
||||
@ -7595,7 +7595,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
return 0;
|
||||
case SC_FREEZE:
|
||||
// Undead are immune to Freeze/Stone
|
||||
if (undead_flag && !(flag&1))
|
||||
if (undead_flag && !(flag&SCSTART_NOAVOID))
|
||||
return 0;
|
||||
case SC_DEEPSLEEP:
|
||||
case SC_SLEEP:
|
||||
@ -7724,7 +7724,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
// Strip skills, need to divest something or it fails.
|
||||
case SC_STRIPWEAPON:
|
||||
if (sd && !(flag&4)) { // Apply sc anyway if loading saved sc_data
|
||||
if (sd && !(flag&SCSTART_LOADED)) { // Apply sc anyway if loading saved sc_data
|
||||
short i;
|
||||
opt_flag = 0; // Reuse to check success condition.
|
||||
if(sd->bonus.unstripable_equip&EQP_WEAPON)
|
||||
@ -7747,7 +7747,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_STRIPSHIELD:
|
||||
if( val2 == 1 ) val2 = 0; // GX effect. Do not take shield off..
|
||||
else
|
||||
if (sd && !(flag&4)) {
|
||||
if (sd && !(flag&SCSTART_LOADED)) {
|
||||
short i;
|
||||
if(sd->bonus.unstripable_equip&EQP_SHIELD)
|
||||
return 0;
|
||||
@ -7759,7 +7759,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
|
||||
break;
|
||||
case SC_STRIPARMOR:
|
||||
if (sd && !(flag&4)) {
|
||||
if (sd && !(flag&SCSTART_LOADED)) {
|
||||
short i;
|
||||
if(sd->bonus.unstripable_equip&EQP_ARMOR)
|
||||
return 0;
|
||||
@ -7771,7 +7771,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
|
||||
break;
|
||||
case SC_STRIPHELM:
|
||||
if (sd && !(flag&4)) {
|
||||
if (sd && !(flag&SCSTART_LOADED)) {
|
||||
short i;
|
||||
if(sd->bonus.unstripable_equip&EQP_HELM)
|
||||
return 0;
|
||||
@ -7896,20 +7896,19 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
if (sc->data[SC_P_ALTER] || sc->data[SC_HEAT_BARREL])
|
||||
return 0;
|
||||
break;
|
||||
case SC_C_MARKER:
|
||||
if (src == bl)
|
||||
|
||||
case SC_WEDDING:
|
||||
case SC_XMAS:
|
||||
case SC_SUMMER:
|
||||
case SC_HANBOK:
|
||||
case SC_OKTOBERFEST:
|
||||
if (!vd)
|
||||
return 0;
|
||||
else {
|
||||
struct status_change *tsc = status_get_sc(bl);
|
||||
// Failed if the target is already marked and the new marker that isn't same marker
|
||||
if (tsc && tsc->data[type] && tsc->data[type]->val2 != src->id)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for BOSS resistances
|
||||
if(status->mode&MD_BOSS && !(flag&1)) {
|
||||
if(status->mode&MD_BOSS && !(flag&SCSTART_NOAVOID)) {
|
||||
if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
|
||||
return 0;
|
||||
switch (type) {
|
||||
@ -7953,7 +7952,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
}
|
||||
}
|
||||
// Check for mvp resistance // atm only those who OS
|
||||
if(status->mode&MD_MVP && !(flag&1)) {
|
||||
if(status->mode&MD_MVP && !(flag&SCSTART_NOAVOID)) {
|
||||
switch (type) {
|
||||
case SC_COMA:
|
||||
// continue list...
|
||||
@ -8274,7 +8273,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC__LAZINESS:
|
||||
case SC__WEAKNESS:
|
||||
case SC__UNLUCKY:
|
||||
case SC__CHAOS:
|
||||
//case SC__CHAOS:
|
||||
return 0;
|
||||
case SC_COMBO:
|
||||
case SC_DANCING:
|
||||
@ -8337,11 +8336,26 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
}
|
||||
}
|
||||
|
||||
vd = status_get_viewdata(bl);
|
||||
calc_flag = StatusChangeFlagTable[type];
|
||||
if(!(flag&4)) // &4 - Do not parse val settings when loading SCs
|
||||
if(!(flag&SCSTART_LOADED)) // &4 - Do not parse val settings when loading SCs
|
||||
switch(type)
|
||||
{
|
||||
/* Permanent effects */
|
||||
case SC_AETERNA:
|
||||
case SC_MODECHANGE:
|
||||
case SC_WEIGHT50:
|
||||
case SC_WEIGHT90:
|
||||
case SC_BROKENWEAPON:
|
||||
case SC_BROKENARMOR:
|
||||
case SC_READYSTORM:
|
||||
case SC_READYDOWN:
|
||||
case SC_READYCOUNTER:
|
||||
case SC_READYTURN:
|
||||
case SC_DODGE:
|
||||
case SC_PUSH_CART:
|
||||
tick = -1;
|
||||
break;
|
||||
|
||||
case SC_DECREASEAGI:
|
||||
case SC_INCREASEAGI:
|
||||
case SC_ADORAMUS:
|
||||
@ -8351,17 +8365,17 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
case SC_ENDURE:
|
||||
val2 = 7; // Hit-count [Celest]
|
||||
if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && !val4 ) {
|
||||
if( !(flag&SCSTART_NOAVOID) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && !val4 ) {
|
||||
struct map_session_data *tsd;
|
||||
if( sd ) {
|
||||
int i;
|
||||
for( i = 0; i < MAX_DEVOTION; i++ ) {
|
||||
if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1|16);
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
}
|
||||
}
|
||||
else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
}
|
||||
// val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
|
||||
if( val4 )
|
||||
@ -8445,17 +8459,17 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_REFLECTSHIELD:
|
||||
val2 = 10+val1*3; // %Dmg reflected
|
||||
// val4 used to mark if reflect shield is an inheritance bonus from Devotion
|
||||
if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) ) {
|
||||
if( !(flag&SCSTART_NOAVOID) && (bl->type&(BL_PC|BL_MER)) ) {
|
||||
struct map_session_data *tsd;
|
||||
if( sd ) {
|
||||
int i;
|
||||
for( i = 0; i < MAX_DEVOTION; i++ ) {
|
||||
if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 1, tick, 1|16);
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 1, tick, SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
}
|
||||
}
|
||||
else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 1, tick, 1);
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 1, tick, SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
}
|
||||
break;
|
||||
case SC_STRIPWEAPON:
|
||||
@ -8481,25 +8495,44 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
val4 = 5 + val1*2; // Chance of casting
|
||||
break;
|
||||
case SC_VOLCANO:
|
||||
val2 = val1*10; // Watk increase
|
||||
{
|
||||
int8 enchant_eff[] = { 10, 14, 17, 19, 20 }; // Enchant addition
|
||||
uint8 i = max((val1-1)%5, 0);
|
||||
|
||||
val2 = val1*10; // Watk increase
|
||||
#ifndef RENEWAL
|
||||
if (status->def_ele != ELE_FIRE)
|
||||
val2 = 0;
|
||||
if (status->def_ele != ELE_FIRE)
|
||||
val2 = 0;
|
||||
#endif
|
||||
val3 = enchant_eff[i];
|
||||
}
|
||||
break;
|
||||
case SC_VIOLENTGALE:
|
||||
val2 = val1*3; // Flee increase
|
||||
{
|
||||
int8 enchant_eff[] = { 10, 14, 17, 19, 20 }; // Enchant addition
|
||||
uint8 i = max((val1-1)%5, 0);
|
||||
|
||||
val2 = val1*3; // Flee increase
|
||||
#ifndef RENEWAL
|
||||
if (status->def_ele != ELE_WIND)
|
||||
val2 = 0;
|
||||
if (status->def_ele != ELE_WIND)
|
||||
val2 = 0;
|
||||
#endif
|
||||
val3 = enchant_eff[i];
|
||||
}
|
||||
break;
|
||||
case SC_DELUGE:
|
||||
val2 = deluge_eff[val1-1]; // HP increase
|
||||
{
|
||||
int8 deluge_eff[] = { 5, 9, 12, 14, 15 }; // HP addition rate n/100
|
||||
int8 enchant_eff[] = { 10, 14, 17, 19, 20 }; // Enchant addition
|
||||
uint8 i = max((val1-1)%5, 0);
|
||||
|
||||
val2 = deluge_eff[i]; // HP increase
|
||||
#ifndef RENEWAL
|
||||
if(status->def_ele != ELE_WATER)
|
||||
val2 = 0;
|
||||
if (status->def_ele != ELE_WATER)
|
||||
val2 = 0;
|
||||
#endif
|
||||
val3 = enchant_eff[i];
|
||||
}
|
||||
break;
|
||||
case SC_SUITON:
|
||||
if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) {
|
||||
@ -8551,15 +8584,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
val2 = 50*(2+type-SC_ASPDPOTION0);
|
||||
break;
|
||||
|
||||
case SC_WEDDING:
|
||||
case SC_XMAS:
|
||||
case SC_SUMMER:
|
||||
case SC_HANBOK:
|
||||
case SC_OKTOBERFEST:
|
||||
if (!vd) return 0;
|
||||
// Store previous values as they could be removed.
|
||||
unit_stop_attack(bl);
|
||||
break;
|
||||
case SC_NOCHAT:
|
||||
// A hardcoded interval of 60 seconds is expected, as the time that SC_NOCHAT uses is defined by
|
||||
// mmocharstatus.manner, each negative point results in 1 minute with this status activated.
|
||||
@ -8607,7 +8631,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
|
||||
case SC_CONFUSION:
|
||||
clif_emotion(bl,E_WHAT);
|
||||
if (!val4)
|
||||
clif_emotion(bl,E_WHAT);
|
||||
break;
|
||||
case SC_BLEEDING:
|
||||
val4 = tick/10000;
|
||||
@ -8674,24 +8699,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
tick_time = 10; // [GodLesZ] tick time
|
||||
break;
|
||||
|
||||
/* Permanent effects */
|
||||
case SC_AETERNA:
|
||||
case SC_MODECHANGE:
|
||||
case SC_WEIGHT50:
|
||||
case SC_WEIGHT90:
|
||||
case SC_BROKENWEAPON:
|
||||
case SC_BROKENARMOR:
|
||||
case SC_READYSTORM:
|
||||
case SC_READYDOWN:
|
||||
case SC_READYCOUNTER:
|
||||
case SC_READYTURN:
|
||||
case SC_DODGE:
|
||||
case SC_PUSH_CART:
|
||||
tick = -1;
|
||||
break;
|
||||
|
||||
case SC_AUTOGUARD:
|
||||
if( !(flag&1) ) {
|
||||
if( !(flag&SCSTART_NOAVOID) ) {
|
||||
struct map_session_data *tsd;
|
||||
int i;
|
||||
for( i = val2 = 0; i < val1; i++) {
|
||||
@ -8703,17 +8712,17 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
if( sd ) {
|
||||
for( i = 0; i < MAX_DEVOTION; i++ ) {
|
||||
if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1|16);
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
}
|
||||
}
|
||||
else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
|
||||
status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_DEFENDER:
|
||||
if (!(flag&1)) {
|
||||
if (!(flag&SCSTART_NOAVOID)) {
|
||||
val2 = 5 + 15*val1; // Damage reduction
|
||||
val3 = 0; // Unused, previously speed adjustment
|
||||
val4 = 250 - 50*val1; // Aspd adjustment
|
||||
@ -8723,7 +8732,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
int i;
|
||||
for (i = 0; i < MAX_DEVOTION; i++) { // See if there are devoted characters, and pass the status to them. [Skotlex]
|
||||
if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
|
||||
status_change_start(src,&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
|
||||
status_change_start(src,&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCSTART_NOAVOID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8848,7 +8857,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
while( i >= 0 ) {
|
||||
enum sc_type type2 = types[i];
|
||||
if( d_sc->data[type2] )
|
||||
status_change_start(d_bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, (type2 == SC_REFLECTSHIELD ? 1 : 0), skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1), (type2 == SC_DEFENDER) ? 1 : 1|16);
|
||||
status_change_start(d_bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, (type2 == SC_REFLECTSHIELD ? 1 : 0), skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1), (type2 == SC_DEFENDER) ? 1 : SCSTART_NOAVOID|SCSTART_NOICON);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
@ -9239,7 +9248,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
tick_time = 4000; // [GodLesZ] tick time
|
||||
break;
|
||||
case SC_PYREXIA:
|
||||
status_change_start(src,bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
|
||||
status_change_start(src,bl,SC_BLIND,10000,val1,0,0,0,30000,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF); // Blind status that last for 30 seconds
|
||||
val4 = tick / 3000;
|
||||
tick_time = 3000; // [GodLesZ] tick time
|
||||
break;
|
||||
@ -9355,14 +9364,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
case SC__UNLUCKY:
|
||||
{
|
||||
short rand_eff;
|
||||
sc_type rand_eff;
|
||||
switch(rand() % 3) {
|
||||
case 1: rand_eff = SC_BLIND; break;
|
||||
case 2: rand_eff = SC_SILENCE; break;
|
||||
default: rand_eff = SC_POISON; break;
|
||||
}
|
||||
val2 = 10 * val1; // Crit and Flee2 Reduction
|
||||
status_change_start(src,bl,rand_eff,10000,val1,0,0,0,tick,10);
|
||||
status_change_start(src,bl,rand_eff,10000,val1,0,0,0,tick,SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
|
||||
break;
|
||||
}
|
||||
case SC__WEAKNESS:
|
||||
@ -9842,11 +9851,12 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
val3 = val1 * 25; // -movespeed (custom)
|
||||
break;
|
||||
case SC_C_MARKER:
|
||||
val2 = src->id;
|
||||
val3 = 10; //-10% flee
|
||||
// val1 = skill_lv
|
||||
// val2 = src_id
|
||||
val3 = 10; // -10 flee
|
||||
//Start timer to send mark on mini map
|
||||
val4 = tick/1000;
|
||||
tick_time = 1000;
|
||||
tick_time = 1000; // Sends every 1 seconds
|
||||
break;
|
||||
case SC_H_MINE:
|
||||
val2 = src->id;
|
||||
@ -9854,8 +9864,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_HEAT_BARREL:
|
||||
//kRO Update 2014-02-26
|
||||
{
|
||||
short n = 10;
|
||||
if (sd) n = sd->spiritball_old;
|
||||
uint8 n = 10;
|
||||
if (sd)
|
||||
n = (uint8)sd->spiritball_old;
|
||||
val2 = val1 * 5; // -fixed casttime (custom)
|
||||
val3 = val1 * n / 5; // +aspd (custom)
|
||||
val4 = 75 - val1 * 5; // -flee
|
||||
@ -9863,8 +9874,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
break;
|
||||
case SC_P_ALTER:
|
||||
{
|
||||
short n = 10;
|
||||
if (sd) n = sd->spiritball_old;
|
||||
uint8 n = 10;
|
||||
if (sd)
|
||||
n = (uint8)sd->spiritball_old;
|
||||
val2 = val1 * n * 2; // +atk (custom)
|
||||
val3 = val1 * 15; // +def (custom)
|
||||
}
|
||||
@ -9872,7 +9884,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_E_CHAIN:
|
||||
val2 = 10;
|
||||
if (sd)
|
||||
val2 = (uint8)sd->spiritball_old;
|
||||
val2 = sd->spiritball_old;
|
||||
break;
|
||||
case SC_ANTI_M_BLAST:
|
||||
val2 = val1 * 10;
|
||||
@ -10007,7 +10019,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_BITE:
|
||||
case SC_THORNSTRAP:
|
||||
case SC__MANHOLE:
|
||||
case SC__CHAOS:
|
||||
//case SC__CHAOS:
|
||||
case SC_CRYSTALIZE:
|
||||
case SC_CURSEDCIRCLE_ATKER:
|
||||
case SC_FEAR:
|
||||
@ -10017,11 +10029,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_PARALYSIS:
|
||||
case SC_MAGNETICFIELD:
|
||||
unit_stop_walking(bl,1);
|
||||
break;
|
||||
break;
|
||||
case SC_ANKLE:
|
||||
if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) )
|
||||
unit_stop_walking(bl,1);
|
||||
break;
|
||||
break;
|
||||
case SC_HIDING:
|
||||
case SC_CLOAKING:
|
||||
case SC_CLOAKINGEXCEED:
|
||||
@ -10031,16 +10043,21 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_CAMOUFLAGE:
|
||||
case SC_VOICEOFSIREN:
|
||||
case SC_HEAT_BARREL_AFTER:
|
||||
case SC_WEDDING:
|
||||
case SC_XMAS:
|
||||
case SC_SUMMER:
|
||||
case SC_HANBOK:
|
||||
case SC_OKTOBERFEST:
|
||||
unit_stop_attack(bl);
|
||||
break;
|
||||
break;
|
||||
case SC_SILENCE:
|
||||
if (battle_config.sc_castcancel&bl->type)
|
||||
unit_skillcastcancel(bl, 0);
|
||||
break;
|
||||
break;
|
||||
case SC_VACUUM_EXTREME:
|
||||
if (!map_flag_gvg(bl->m))
|
||||
unit_stop_walking(bl, 1);
|
||||
break;
|
||||
break;
|
||||
case SC_ITEMSCRIPT: // Shows Buff Icons
|
||||
if (sd && val2 != SI_BLANK)
|
||||
clif_status_change(bl, (enum si_type)val2, 1, tick, 0, 0, 0);
|
||||
@ -10231,7 +10248,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
calc_flag&=~SCB_DYE;
|
||||
}
|
||||
|
||||
if(!(flag&16) && !(flag&4 && StatusDisplayType[type]))
|
||||
if(!(flag&SCSTART_NOICON) && !(flag&SCSTART_LOADED && StatusDisplayType[type]))
|
||||
clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
|
||||
|
||||
// Used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
|
||||
@ -10333,7 +10350,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_C_MARKER:
|
||||
//Send mini-map, don't wait for first timer triggered
|
||||
if (src->type == BL_PC && (sd = map_id2sd(src->id)))
|
||||
clif_crimson_marker(sd->fd,bl,false);
|
||||
clif_crimson_marker(sd, bl, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -10495,7 +10512,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
struct status_change_entry *sce;
|
||||
struct status_data *status;
|
||||
struct view_data *vd;
|
||||
int opt_flag=0, calc_flag,temp_n = 0;
|
||||
int opt_flag = 0, calc_flag;
|
||||
|
||||
nullpo_ret(bl);
|
||||
|
||||
@ -10542,11 +10559,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
if ( StatusChangeStateTable[type] )
|
||||
status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
|
||||
|
||||
switch (type) {
|
||||
case SC_H_MINE: temp_n = sc->data[type]->val3; break; // If ended by RL_FLICKER, don't drop the trap
|
||||
case SC_C_MARKER: temp_n = sc->data[type]->val2; break; // Player who gave mark
|
||||
}
|
||||
|
||||
sc->data[type] = NULL;
|
||||
|
||||
if (sd && StatusDisplayType[type])
|
||||
@ -10984,15 +10996,15 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
case SC_C_MARKER:
|
||||
{
|
||||
// Remove mark data from caster
|
||||
struct map_session_data *caster = map_id2sd(temp_n);
|
||||
struct map_session_data *caster = map_id2sd(sce->val2);
|
||||
uint8 i = 0;
|
||||
|
||||
if (!caster || !&caster->c_marker || !caster->c_marker.target)
|
||||
if (!caster)
|
||||
break;
|
||||
ARR_FIND(0,MAX_SKILL_CRIMSON_MARKER,i,caster->c_marker.target[i] == bl->id);
|
||||
ARR_FIND(0,MAX_SKILL_CRIMSON_MARKER,i,caster->c_marker[i] == bl->id);
|
||||
if (i < MAX_SKILL_CRIMSON_MARKER) {
|
||||
caster->c_marker.target[i] = 0;
|
||||
clif_crimson_marker(caster->fd,bl,true);
|
||||
caster->c_marker[i] = 0;
|
||||
clif_crimson_marker(caster, bl, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -11000,15 +11012,17 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
||||
{
|
||||
// Drop the material from target if expired
|
||||
struct item it;
|
||||
if (temp_n)
|
||||
struct map_session_data *caster = NULL;
|
||||
|
||||
if (sce->val3 || status_isdead(bl) || !(caster = map_id2sd(sce->val2)))
|
||||
break;
|
||||
if (!itemdb_exists(skill_get_itemid(RL_H_MINE,0)))
|
||||
break;
|
||||
memset(&it,0,sizeof(it));
|
||||
memset(&it, 0, sizeof(it));
|
||||
it.nameid = skill_get_itemid(RL_H_MINE,0);
|
||||
it.amount = max(skill_get_itemqty(RL_H_MINE,0),1);
|
||||
it.identify = 1;
|
||||
map_addflooritem(&it,it.amount,bl->m,bl->x,bl->y,0,0,0,4);
|
||||
map_addflooritem(&it, it.amount, bl->m,bl->x, bl->y, caster->status.char_id, 0, 0, 4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -11646,15 +11660,18 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
}
|
||||
|
||||
if( !flag ) { // Random Skill Cast
|
||||
if (sd && !pc_issit(sd)) { // Can't cast if sit
|
||||
int mushroom_skill_id = 0;
|
||||
if (skill_magicmushroom_count && sd && !pc_issit(sd)) { // Can't cast if sit
|
||||
int mushroom_skill_id = 0, checked = 0, checked_max = MAX_SKILL_MAGICMUSHROOM_DB * 3;
|
||||
unit_stop_attack(bl);
|
||||
unit_skillcastcancel(bl,1);
|
||||
do {
|
||||
int i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
|
||||
mushroom_skill_id = skill_magicmushroom_db[i].skill_id;
|
||||
}
|
||||
while( mushroom_skill_id == 0 );
|
||||
while( checked++ < checked_max && mushroom_skill_id == 0 );
|
||||
|
||||
if (!skill_get_index(mushroom_skill_id))
|
||||
break;
|
||||
|
||||
switch( skill_get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage
|
||||
case CAST_GROUND:
|
||||
@ -12114,17 +12131,18 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
break;
|
||||
case SC_C_MARKER:
|
||||
if( --(sce->val4) >= 0 ) {
|
||||
TBL_PC *tsd = map_id2sd(sce->val2);
|
||||
if (!tsd || tsd->bl.m != bl->m) //End the SC if caster isn't in same map
|
||||
TBL_PC *caster = map_id2sd(sce->val2);
|
||||
if (!caster || caster->bl.m != bl->m) //End the SC if caster isn't in same map
|
||||
break;
|
||||
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
|
||||
clif_crimson_marker(tsd->fd,bl,false);
|
||||
clif_crimson_marker(caster, bl, false);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Default for all non-handled control paths is to end the status
|
||||
|
||||
return status_change_end( bl,type,tid );
|
||||
#undef sc_timer_next
|
||||
}
|
||||
@ -12474,7 +12492,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl )
|
||||
data.val2 = sc->data[i]->val2;
|
||||
data.val3 = sc->data[i]->val3;
|
||||
data.val4 = sc->data[i]->val4;
|
||||
status_change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
|
||||
status_change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1732,6 +1732,16 @@ enum e_status_calc_opt {
|
||||
SCO_FORCE = 0x2, /* Only relevant to BL_PC types, ensures call bypasses the queue caused by delayed damage */
|
||||
};
|
||||
|
||||
/// Flags for status_change_start and status_get_sc_def
|
||||
enum e_status_change_start_flags {
|
||||
SCSTART_NONE = 0x00,
|
||||
SCSTART_NOAVOID = 0x01, /// Cannot be avoided (it has to start)
|
||||
SCSTART_NOTICKDEF = 0x02, /// Tick should not be reduced (by statuses or bonuses)
|
||||
SCSTART_LOADED = 0x04, /// When sc_data loaded (fetched from table), no values (val1 ~ val4) have to be altered/recalculate
|
||||
SCSTART_NORATEDEF = 0x08, /// Rate should not be reduced (by statuses or bonuses)
|
||||
SCSTART_NOICON = 0x10, /// Status icon won't be sent to client
|
||||
};
|
||||
|
||||
///Enum for bonus_script's flag [Cydh]
|
||||
enum e_bonus_script_flags {
|
||||
BSF_REM_ON_DEAD = 0x001, ///Removed when dead
|
||||
@ -1995,13 +2005,13 @@ struct status_change *status_get_sc(struct block_list *bl);
|
||||
int status_isdead(struct block_list *bl);
|
||||
int status_isimmune(struct block_list *bl);
|
||||
|
||||
int status_get_sc_def(struct block_list *src,struct block_list *bl, enum sc_type type, int rate, int tick, int flag);
|
||||
int status_get_sc_def(struct block_list *src,struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag);
|
||||
//Short version, receives rate in 1->100 range, and does not uses a flag setting.
|
||||
#define sc_start(src, bl, type, rate, val1, tick) status_change_start(src,bl,type,100*(rate),val1,0,0,0,tick,0)
|
||||
#define sc_start2(src, bl, type, rate, val1, val2, tick) status_change_start(src,bl,type,100*(rate),val1,val2,0,0,tick,0)
|
||||
#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) status_change_start(src,bl,type,100*(rate),val1,val2,val3,val4,tick,0)
|
||||
#define sc_start(src, bl, type, rate, val1, tick) status_change_start(src,bl,type,100*(rate),val1,0,0,0,tick,SCSTART_NONE)
|
||||
#define sc_start2(src, bl, type, rate, val1, val2, tick) status_change_start(src,bl,type,100*(rate),val1,val2,0,0,tick,SCSTART_NONE)
|
||||
#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) status_change_start(src,bl,type,100*(rate),val1,val2,val3,val4,tick,SCSTART_NONE)
|
||||
|
||||
int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
|
||||
int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,unsigned char flag);
|
||||
int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
|
||||
#define status_change_end(bl,type,tid) status_change_end_(bl,type,tid,__FILE__,__LINE__)
|
||||
int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data);
|
||||
|
@ -934,8 +934,12 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
|
||||
if(dx || dy) {
|
||||
map_foreachinmovearea(clif_outsight, bl, AREA_SIZE, dx, dy, bl->type == BL_PC ? BL_ALL : BL_PC, bl);
|
||||
|
||||
if(su)
|
||||
skill_unit_move_unit_group(su->group, bl->m, dx, dy);
|
||||
if(su) {
|
||||
if (su->group && skill_get_unit_flag(su->group->skill_id)&UF_KNOCKBACK_GROUP)
|
||||
skill_unit_move_unit_group(su->group, bl->m, dx, dy);
|
||||
else
|
||||
skill_unit_move_unit(bl, nx, ny);
|
||||
}
|
||||
else
|
||||
map_moveblock(bl, nx, ny, gettick());
|
||||
|
||||
@ -1424,6 +1428,19 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RL_C_MARKER:
|
||||
{
|
||||
uint8 i = 0;
|
||||
ARR_FIND(0, MAX_SKILL_CRIMSON_MARKER, i, sd->c_marker[i] == target_id);
|
||||
if (i == MAX_SKILL_CRIMSON_MARKER) {
|
||||
ARR_FIND(0, MAX_SKILL_CRIMSON_MARKER, i, sd->c_marker[i] == 0);
|
||||
if (i == MAX_SKILL_CRIMSON_MARKER) { // No free slots, skill Fail
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!skill_check_condition_castbegin(sd, skill_id, skill_lv))
|
||||
return 0;
|
||||
|
@ -24,8 +24,8 @@ Main($sCmd,$sTarget);
|
||||
|
||||
sub GetArgs {
|
||||
GetOptions(
|
||||
'cmd=s' => \$sCmd, # wich command to run
|
||||
'atcf=s' => \$sAtcf, #atc doc file
|
||||
'cmd=s' => \$sCmd, # which command to run
|
||||
'atcf=s' => \$sAtcf, #atcommand doc file
|
||||
'scriptf=s' => \$sSctf, #script doc file
|
||||
'inc_atcf=s' => \$sInc_atcf, #include script doc file (for customs doc)
|
||||
'inc_scrtf=s' => \$sInc_scrtf, #include script doc file (for customs doc)
|
||||
@ -35,7 +35,7 @@ sub GetArgs {
|
||||
) or $sHelp=1; #display help if invalid option
|
||||
|
||||
if( $sHelp ) {
|
||||
print "Incorect option specified, available option are:\n"
|
||||
print "Incorrect option specified, available options are:\n"
|
||||
."\t --atcf filename => file (specify atcommand doc to use)\n"
|
||||
."\t --inc_atcf filename => include file (specify atcommand doc to use)\n"
|
||||
."\t --scriptf filename => file (specify script doc to use)\n"
|
||||
@ -46,12 +46,12 @@ sub GetArgs {
|
||||
exit;
|
||||
}
|
||||
unless($sTarget =~ /$sValidTarget/i){
|
||||
print "Incorect target specified, available target are:\n"
|
||||
print "Incorrect target specified, available target is:\n"
|
||||
."\t --target => target (specify wich check to run [(default)$sValidTarget])\n";
|
||||
exit;
|
||||
}
|
||||
unless($sCmd =~ /$sValidCmd/i){
|
||||
print "Incorect command specified, available command are:\n"
|
||||
print "Incorrect command specified, available command is:\n"
|
||||
."\t --cmd => cmd (specify wich command to run [(default)$sValidCmd])\n";
|
||||
exit;
|
||||
}
|
||||
@ -65,14 +65,14 @@ sub Main { my ($sCmd,$sTarget) = @_;
|
||||
if($sTarget=~/script/i){ #find which script commands are missing from doc/script_commands.txt
|
||||
my $raSct_cmd = Script_GetCmd();
|
||||
if($sCmd =~ /ls/i) {
|
||||
print "The list of script-command found are = \n[ @$raSct_cmd ] \n\n";
|
||||
print "The list of script-commands found are = \n[ @$raSct_cmd ] \n\n";
|
||||
}
|
||||
if($sCmd =~ /chk/i) { Script_Chk($raSct_cmd); }
|
||||
}
|
||||
if($sTarget=~/atc/i){ #find which atcommands are missing from doc/atcommands.txt
|
||||
my $raAct_cmd = Atc_GetCmd();
|
||||
if($sCmd =~ /ls/i) {
|
||||
print "The list of atcommand found are = \n[ @$raAct_cmd ] \n\n";
|
||||
print "The list of atcommands found are = \n[ @$raAct_cmd ] \n\n";
|
||||
}
|
||||
if($sCmd =~ /chk/i) { Atc_Chk($raAct_cmd); }
|
||||
}
|
||||
@ -240,12 +240,12 @@ sub Atc_Chk { my ($raDef_act) = @_;
|
||||
if($sLeftOverChk){
|
||||
my $raLeftover_sct = Chk(\@aDoc_act,$raDef_act); #we just inverse the chk for leftover
|
||||
if(scalar(@$raLeftover_sct)){
|
||||
print "Those atcommand command was found in doc but no source associated, leftover ? : {\n";
|
||||
print "Those atcommands were found in doc but no source associated, leftover ? : {\n";
|
||||
foreach(@$raLeftover_sct){
|
||||
print "\t$_ \n";
|
||||
}
|
||||
print "}\n\n";
|
||||
}
|
||||
else { print "All atcommand in documentation match a source ATCMD, no leftover found\n"; }
|
||||
else { print "All atcommands in documentation match a source ATCMD, no leftover found\n"; }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user