diff options
77 files changed, 11057 insertions, 2298 deletions
diff --git a/.travis.yml b/.travis.yml index cb4139c38..e4497257b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ matrix: - cd ../.. - ./tools/checksql.sh - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" HPM="1" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" HPM="1" addons: apt: sources: @@ -60,7 +60,7 @@ matrix: - libxml-sax-perl - libxml-parser-perl - compiler: clang - env: CONFIGURE_FLAGS="--enable-debug CC=clang-5.0 --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: CONFIGURE_FLAGS="--enable-debug CC=clang-5.0 --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -80,7 +80,7 @@ matrix: - gdb - clang-5.0 - compiler: clang - env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -114,11 +114,11 @@ matrix: - compiler: clang env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot" - compiler: gcc - env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" - compiler: gcc env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot" - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -136,7 +136,7 @@ matrix: - gdb - gcc-5 - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -154,7 +154,7 @@ matrix: - gdb - gcc-6 - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-7 --disable-manager --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-7 --disable-manager --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" addons: apt: sources: @@ -172,7 +172,7 @@ matrix: - gdb - gcc-7 - compiler: gcc - env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --enable-Werror --enable-packetver=20200108 --enable-packetver-re --enable-buildbot" + env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --enable-Werror --enable-packetver=20200205 --enable-packetver-re --enable-buildbot" addons: apt: sources: diff --git a/conf/common/inter-server.conf b/conf/common/inter-server.conf index 5bec34d44..7696774d6 100644 --- a/conf/common/inter-server.conf +++ b/conf/common/inter-server.conf @@ -118,6 +118,7 @@ inter_configuration: { autotrade_data_db: "autotrade_data" npc_market_data_db: "npc_market_data" npc_barter_data_db: "npc_barter_data" + npc_expanded_barter_data_db: "npc_expanded_barter_data" } } diff --git a/conf/map/battle/misc.conf b/conf/map/battle/misc.conf index cc2abc16c..8cc1d0171 100644 --- a/conf/map/battle/misc.conf +++ b/conf/map/battle/misc.conf @@ -101,7 +101,7 @@ duel_allow_teleport: false // Autoleave duel when die duel_autoleave_when_die: true -// Delay between using @duel in minutes +// Delay between using @duel in seconds duel_time_interval: 60 // Restrict duel usage to same map diff --git a/conf/messages.conf b/conf/messages.conf index b91b03921..98b0e0a9d 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -191,7 +191,7 @@ 170: The item is not equippable. 171: %d - void 172: Speed returned to normal. -//173 FREE +173: Please enter a valid madogear type. 174: Number of status points changed. 175: Number of skill points changed. 176: Current amount of zeny changed. @@ -368,7 +368,7 @@ 353: Duel: The Player is in the duel already. 354: Duel: Invitation has been sent. 355: Duel: You can't use @duel without @reject. -356: Duel: You can take part in duel once per %d minutes. +356: Duel: You can take part in duel again after %d seconds. 357: Duel: Invalid value. 358: Duel: You can't use @leave. You aren't a duelist. 359: Duel: You've left the duel. @@ -1016,8 +1016,8 @@ // @loadnpc 1132: Please enter a script file name (usage: @loadnpc <file name>). -// @npcoff -1133: Please enter a NPC name (usage: @npcoff <NPC_name>). +// @unloadnpc +1133: Please enter a NPC name (Usage: @unloadnpc <NPC_name> {<flag>}). // @jail 1134: Please enter a player name (usage: @jail <char_name>). @@ -1455,8 +1455,8 @@ 1384: User '%s' permissions updated successfully. The changes are temporary. // @unloadnpcfile -1385: Usage: @unloadnpcfile <file name> -1386: File unloaded. Be aware that mapflags and monsters spawned directly are not removed. +1385: Usage: @unloadnpcfile <path> {<flag>} +1386: File unloaded. Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details. 1387: File not found. // General command messages @@ -1636,5 +1636,13 @@ 1514: %d: Refine All Equip (Costume) 1515: %d: Refine All Equip (Shadow) +// @reloadnpc +1516: Usage: @reloadnpc <path> {<flag>} +1517: Script could not be unloaded. + +// File name validation +1518: Not a file. +1519: Can't open file. + //Custom translations import: conf/import/msg_conf.txt diff --git a/db/constants.conf b/db/constants.conf index f76f2ea6a..6f87b2d51 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -1416,6 +1416,7 @@ constants_db: { SC_RESIST_PROPERTY_FIRE: 666 SC_RESIST_PROPERTY_WIND: 667 SC_CLIENT_ONLY_EQUIP_ARROW: 668 + SC_MADOGEAR: 669 comment__: "Emotes" e_gasp: 0 @@ -4730,4 +4731,5 @@ constants_db: { SI_FRESHSHRIMP: 921 SI_SUHIDE: 933 SI_SPRITEMABLE: 937 + SI_MADOGEAR: 1149 } diff --git a/db/pre-re/item_db.conf b/db/pre-re/item_db.conf index 7d9708f81..38833636d 100644 --- a/db/pre-re/item_db.conf +++ b/db/pre-re/item_db.conf @@ -67261,7 +67261,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,-15,0,20,0; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_WATER, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12119 @@ -67271,7 +67274,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,20,0,0,-15; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_WATER, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_WIND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12120 @@ -67281,7 +67287,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,0,20,-15,0; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12121 @@ -67291,7 +67300,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,0,-15,0,20; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_WIND, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12122 @@ -69521,7 +69533,12 @@ item_db: ( Name: "Undead Elemental Scroll" Type: "IT_USABLE" Weight: 10 - Script: <" sc_start4 SC_ARMOR_RESIST,300000,20,20,20,20; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_FIRE, 300000, 20); + sc_start(SC_RESIST_PROPERTY_WATER, 300000, 20); + sc_start(SC_RESIST_PROPERTY_WIND, 300000, 20); + sc_start(SC_RESIST_PROPERTY_GROUND, 300000, 20); + "> }, { Id: 12280 diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf index 45592ad90..78e255f36 100644 --- a/db/pre-re/mob_db.conf +++ b/db/pre-re/mob_db.conf @@ -102,7 +102,7 @@ mob_db: ( HeadTopId: top headgear id (int, defaults to 0) HeadMidId: middle headgear id (int, defaults to 0) HeadLowId: lower headgear id (int, defaults to 0) - HairStyleId: hair style id (int, defaults to 0) + HairStyleId: hair style id (int, defaults to 1) BodyStyleId: clothes id (int, defaults to 0) HairColorId: hair color id (int, defaults to 0) BodyColorId: clothes color id (int, defaults to 0) diff --git a/db/quest_db.conf b/db/quest_db.conf index adf425405..8163c540a 100644 --- a/db/quest_db.conf +++ b/db/quest_db.conf @@ -12626,6 +12626,42 @@ quest_db: ( Name: "About skills" }, { + Id: 12340 + Name: "Suspicious Person" +}, +{ + Id: 12341 + Name: "New Challenge" +}, +{ + Id: 12342 + Name: "Crafting Firearms" +}, +{ + Id: 12343 + Name: "Target Practice" + Targets: ( + { + MobId: 3169 + Count: 10 + }, + ) +}, +{ + Id: 12344 + Name: "Wrong Target Practice" + Targets: ( + { + MobId: 3170 + Count: 3 + }, + ) +}, +{ + Id: 12345 + Name: "Transforming to Rebellion" +}, +{ Id: 13101 Name: "The way of Taekwon" }, diff --git a/db/re/item_db.conf b/db/re/item_db.conf index d06c02279..4f5be9de5 100644 --- a/db/re/item_db.conf +++ b/db/re/item_db.conf @@ -74523,6 +74523,16 @@ item_db: ( Name: "Love Wand" }, { + Id: 6746 + AegisName: "Steel_Article" + Name: "Steel Artifact" +}, +{ + Id: 6747 + AegisName: "Steel_Article_" + Name: "Steel Artifact" +}, +{ Id: 6755 AegisName: "Corrupted_Charm" Name: "Contaminated Magic" @@ -86890,7 +86900,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,-15,0,20,0; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_WATER, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12119 @@ -86900,7 +86913,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,20,0,0,-15; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_WATER, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_WIND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12120 @@ -86910,7 +86926,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,0,20,-15,0; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12121 @@ -86920,7 +86939,10 @@ item_db: ( Buy: 2 Weight: 10 BuyingStore: true - Script: <" sc_start4 SC_ARMORPROPERTY,1200000,0,-15,0,20; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_WIND, 1200000, 20); + sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + "> }, { Id: 12122 @@ -89170,7 +89192,12 @@ item_db: ( Name: "Undead Elemental Scroll" Type: "IT_USABLE" Weight: 10 - Script: <" sc_start4 SC_ARMOR_RESIST,300000,20,20,20,20; "> + Script: <" + sc_start(SC_RESIST_PROPERTY_FIRE, 300000, 20); + sc_start(SC_RESIST_PROPERTY_WATER, 300000, 20); + sc_start(SC_RESIST_PROPERTY_WIND, 300000, 20); + sc_start(SC_RESIST_PROPERTY_GROUND, 300000, 20); + "> }, { Id: 12280 @@ -101203,6 +101230,58 @@ item_db: ( "> }, { + Id: 13118 + AegisName: "Tiny_Flame" + Name: "Fading Flame" + Type: "IT_WEAPON" + Weight: 100 + Range: 7 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_ARMS" + WeaponLv: 1 + EquipLv: 1 + Trade: { + nodrop: true + notrade: true + nocart: true + nostorage: true + nogstorage: true + nomail: true + noauction: true + } + Subtype: "W_REVOLVER" +}, +{ + Id: 13119 + AegisName: "Freedom_Flame" + Name: "Freedom Flame" + Type: "IT_WEAPON" + Weight: 100 + Atk: 100 + Range: 7 + Slots: 2 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_ARMS" + WeaponLv: 3 + EquipLv: 99 + Trade: { + nodrop: true + notrade: true + nocart: true + nostorage: true + nogstorage: true + nomail: true + noauction: true + } + Subtype: "W_REVOLVER" +}, +{ Id: 13120 AegisName: "H_FEATHER_H_FIRE" Name: "Heaven's_Feather_&_Hell's_Fire" @@ -102872,6 +102951,7 @@ item_db: ( Atk: 15 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" @@ -102887,6 +102967,7 @@ item_db: ( Atk: 30 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" @@ -102905,6 +102986,7 @@ item_db: ( Atk: 50 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" @@ -102920,6 +103002,7 @@ item_db: ( Atk: 50 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" @@ -102935,6 +103018,7 @@ item_db: ( Atk: 50 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" @@ -102953,6 +103037,7 @@ item_db: ( Atk: 50 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" @@ -102971,11 +103056,98 @@ item_db: ( Atk: 50 Job: { Gunslinger: true + Rebellion: true } Loc: "EQP_AMMO" Subtype: "A_BULLET" Script: <" bonus bAtkEle, Ele_Water; "> }, +{ + Id: 13228 + AegisName: "Flare_Bullet" + Name: "Flare Bullet" + Type: "IT_AMMO" + Buy: 15 + Weight: 5 + Atk: 50 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_AMMO" + Subtype: "A_BULLET" + Script: <" bonus bAtkEle, Ele_Fire; "> +}, +{ + Id: 13229 + AegisName: "Lightning_Bullet" + Name: "Lightning Bullet" + Type: "IT_AMMO" + Buy: 15 + Weight: 5 + Atk: 50 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_AMMO" + Subtype: "A_BULLET" + Script: <" bonus bAtkEle, Ele_Wind; "> +}, +{ + Id: 13230 + AegisName: "Ice_Bullet" + Name: "Ice Bullet" + Type: "IT_AMMO" + Buy: 15 + Weight: 5 + Atk: 50 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_AMMO" + Subtype: "A_BULLET" + Script: <" bonus bAtkEle, Ele_Water; "> +}, +{ + Id: 13231 + AegisName: "Poison_Bullet" + Name: "Poison Bullet" + Type: "IT_AMMO" + Buy: 15 + Weight: 5 + Atk: 50 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_AMMO" + Subtype: "A_BULLET" + Script: <" + bonus bAtkEle, Ele_Poison; + bonus2 bAddEff, Eff_Poison, 500; + "> +}, +{ + Id: 13232 + AegisName: "Blind_Bullet" + Name: "Blind Bullet" + Type: "IT_AMMO" + Buy: 15 + Weight: 5 + Atk: 50 + Job: { + Gunslinger: true + Rebellion: true + } + Loc: "EQP_AMMO" + Subtype: "A_BULLET" + Script: <" + bonus bAtkEle, Ele_Dark; + bonus2 bAddEff, Eff_Blind, 500; + "> +}, //== Shurikens & Kunais ==================================== { @@ -153447,6 +153619,13 @@ item_db: ( Name: "S_Genesis_Earing" }, { + Id: 25187 + AegisName: "Slug_Bullet" + Name: "Slug Bullet" + Buy: 1200 + Weight: 1200 +}, +{ Id: 25258 AegisName: "BrokenArrow" Name: "BrokenArrow" diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index c0c726f25..492b75a04 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -102,7 +102,7 @@ mob_db: ( HeadTopId: top headgear id (int, defaults to 0) HeadMidId: middle headgear id (int, defaults to 0) HeadLowId: lower headgear id (int, defaults to 0) - HairStyleId: hair style id (int, defaults to 0) + HairStyleId: hair style id (int, defaults to 1) BodyStyleId: clothes id (int, defaults to 0) HairColorId: hair color id (int, defaults to 0) BodyColorId: clothes color id (int, defaults to 0) @@ -64487,7 +64487,43 @@ mob_db: ( //2428,G_L_SEYREN //2429,G_L_EREMES //2430,G_L_HARWORD -//2431,G_L_SHECIL +{ + Id: 2431 + SpriteName: "G_L_SHECIL" + Name: "Hunter Shecil" + Lv: 98 + Hp: 8835 + Sp: 1 + AttackRange: 14 + Attack: [574, 223] + Def: 68 + Mdef: 13 + Stats: { + Str: 108 + Agi: 113 + Vit: 60 + Int: 72 + Dex: 148 + Luk: 37 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Medium" + Race: "RC_DemiHuman" + Element: ("Ele_Wind", 3) + Mode: { + CanMove: true + Aggressive: true + CanAttack: true + Angry: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 160 + AttackDelay: 432 + AttackMotion: 400 + DamageMotion: 288 +}, //2432,G_L_KATRINN //2433,G_L_MAGALETA //2434,G_L_YGNIZEM @@ -83975,6 +84011,30 @@ mob_db: ( //3156,EXPLORATION_ROVER //3166,M_E_DEVILING { + Id: 3169 + SpriteName: "J_REB_SHECIL1" + Name: "Shooting Target" + Size: "Size_Small" + Race: "RC_Formless" + Element: ("Ele_Neutral", 1) + Mode: { + CanMove: true + } + MoveSpeed: 200 +}, +{ + Id: 3170 + SpriteName: "J_REB_SHECIL2" + Name: "Shooting Target" + Size: "Size_Small" + Race: "RC_Formless" + Element: ("Ele_Neutral", 1) + Mode: { + CanMove: true + } + MoveSpeed: 200 +}, +{ Id: 3181 SpriteName: "E1_FELOCK" Name: "Captain Ferlock" diff --git a/db/sc_config.conf b/db/sc_config.conf index 1d8f50e1c..2520fc595 100644 --- a/db/sc_config.conf +++ b/db/sc_config.conf @@ -3664,3 +3664,14 @@ SC_SV_ROOTTWIST: { NoBoss: true } } +SC_MADOGEAR: { + Visible: true + Flags: { + NoDeathReset: true + NoDispelReset: true + NoClearanceReset: true + NoAllReset: true + NoBoss: true + } + Icon: "SI_MADOGEAR" +} diff --git a/doc/atcommands.txt b/doc/atcommands.txt index 419cb0acd..0cddc1680 100644 --- a/doc/atcommands.txt +++ b/doc/atcommands.txt @@ -1273,31 +1273,47 @@ Example: --------------------------------------- -@unloadnpc <npc name> - -Unloads an NPC. +@unloadnpc <NPC_name> {<flag>} + +Unloads a NPC. +Flag: + 0 - do not unload mobs spawned by NPCs in file + 1 - unload mobs spawned by NPCs in file + Default is 1; every number other than 0 will be treaten as 1. + Mobs that were spawned with monster/areamonster/guardian/bg_monster/atcommand("@monster xy") are affected. +Note: + Be aware that some changes made by NPC are not reverted on unload. + Please use the OnNPCUnload label to clean things up by yourself. Commonly relevant for these script commands: + -> setmapflagnosave, setmapflag, removemapflags, setbattleflag, setcell, setwall + -> agitstart/agitstart2, agitend/agitend2, gvgon, gvgoff, pvpon, pvpoff + -> addmonsterdrop, setitemscript, npcshopitem, npcshopadditem, npcshopdelitem, hateffect, disguise + -> pcfollow, pcblockmove, setpcblock, setnpcdir, navigateto, viewpoint, add_group_command, skill/addtoskill + -> instance and battleground related stuff (excepting bg_monster) Example: -@unloadnpc Job Master +@unloadnpc Job Master 0 --------------------------------------- -@unloadnpcfile <path> +@unloadnpcfile <path> {<flag>} Unloads all NPCs in a file. +Flag: See @unloadnpc +Note: See @unloadnpc Example: -@unloadnpcfile npc/custom/jobmaster.txt +@unloadnpcfile npc/custom/jobmaster.txt 0 --------------------------------------- -@reloadnpc <path> +@reloadnpc <path> {<flag>} Unloads all NPCs in a file and reload it again. -Note: Be aware that mapflags and monsters spawned directly are not removed. +Flag: See @unloadnpc +Note: See @unloadnpc Example: -@reloadnpc npc/custom/jobmaster.txt +@reloadnpc npc/custom/jobmaster.txt 0 --------------------------------------- diff --git a/doc/constants.md b/doc/constants.md index 257696c4e..07ae12ce3 100644 --- a/doc/constants.md +++ b/doc/constants.md @@ -5152,6 +5152,7 @@ - `NST_MARKET`: 2 - `NST_CUSTOM`: 3 - `NST_BARTER`: 4 +- `NST_EXPANDED_BARTER`: 5 ### script unit data types @@ -5291,1130 +5292,1130 @@ ## Skills (db/re/skill_db.txt) -- `NV_BASIC`: 1 -- `SM_SWORD`: 2 -- `SM_TWOHAND`: 3 -- `SM_RECOVERY`: 4 -- `SM_BASH`: 5 -- `SM_PROVOKE`: 6 -- `SM_MAGNUM`: 7 -- `SM_ENDURE`: 8 -- `MG_SRECOVERY`: 9 -- `MG_SIGHT`: 10 -- `MG_NAPALMBEAT`: 11 -- `MG_SAFETYWALL`: 12 -- `MG_SOULSTRIKE`: 13 -- `MG_COLDBOLT`: 14 -- `MG_FROSTDIVER`: 15 -- `MG_STONECURSE`: 16 -- `MG_FIREBALL`: 17 -- `MG_FIREWALL`: 18 -- `MG_FIREBOLT`: 19 -- `MG_LIGHTNINGBOLT`: 20 -- `MG_THUNDERSTORM`: 21 -- `AL_DP`: 22 -- `AL_DEMONBANE`: 23 -- `AL_RUWACH`: 24 -- `AL_PNEUMA`: 25 -- `AL_TELEPORT`: 26 -- `AL_WARP`: 27 -- `AL_HEAL`: 28 -- `AL_INCAGI`: 29 -- `AL_DECAGI`: 30 -- `AL_HOLYWATER`: 31 -- `AL_CRUCIS`: 32 -- `AL_ANGELUS`: 33 -- `AL_BLESSING`: 34 -- `AL_CURE`: 35 -- `MC_INCCARRY`: 36 -- `MC_DISCOUNT`: 37 -- `MC_OVERCHARGE`: 38 -- `MC_PUSHCART`: 39 -- `MC_IDENTIFY`: 40 -- `MC_VENDING`: 41 -- `MC_MAMMONITE`: 42 -- `AC_OWL`: 43 -- `AC_VULTURE`: 44 -- `AC_CONCENTRATION`: 45 -- `AC_DOUBLE`: 46 -- `AC_SHOWER`: 47 -- `TF_DOUBLE`: 48 -- `TF_MISS`: 49 -- `TF_STEAL`: 50 -- `TF_HIDING`: 51 -- `TF_POISON`: 52 -- `TF_DETOXIFY`: 53 -- `ALL_RESURRECTION`: 54 -- `KN_SPEARMASTERY`: 55 -- `KN_PIERCE`: 56 -- `KN_BRANDISHSPEAR`: 57 -- `KN_SPEARSTAB`: 58 -- `KN_SPEARBOOMERANG`: 59 -- `KN_TWOHANDQUICKEN`: 60 -- `KN_AUTOCOUNTER`: 61 -- `KN_BOWLINGBASH`: 62 -- `KN_RIDING`: 63 -- `KN_CAVALIERMASTERY`: 64 -- `PR_MACEMASTERY`: 65 -- `PR_IMPOSITIO`: 66 -- `PR_SUFFRAGIUM`: 67 -- `PR_ASPERSIO`: 68 -- `PR_BENEDICTIO`: 69 -- `PR_SANCTUARY`: 70 -- `PR_SLOWPOISON`: 71 -- `PR_STRECOVERY`: 72 -- `PR_KYRIE`: 73 -- `PR_MAGNIFICAT`: 74 -- `PR_GLORIA`: 75 -- `PR_LEXDIVINA`: 76 -- `PR_TURNUNDEAD`: 77 -- `PR_LEXAETERNA`: 78 -- `PR_MAGNUS`: 79 -- `WZ_FIREPILLAR`: 80 -- `WZ_SIGHTRASHER`: 81 -- `WZ_METEOR`: 83 -- `WZ_JUPITEL`: 84 -- `WZ_VERMILION`: 85 -- `WZ_WATERBALL`: 86 -- `WZ_ICEWALL`: 87 -- `WZ_FROSTNOVA`: 88 -- `WZ_STORMGUST`: 89 -- `WZ_EARTHSPIKE`: 90 -- `WZ_HEAVENDRIVE`: 91 -- `WZ_QUAGMIRE`: 92 -- `WZ_ESTIMATION`: 93 -- `BS_IRON`: 94 -- `BS_STEEL`: 95 -- `BS_ENCHANTEDSTONE`: 96 -- `BS_ORIDEOCON`: 97 -- `BS_DAGGER`: 98 -- `BS_SWORD`: 99 -- `BS_TWOHANDSWORD`: 100 -- `BS_AXE`: 101 -- `BS_MACE`: 102 -- `BS_KNUCKLE`: 103 -- `BS_SPEAR`: 104 -- `BS_HILTBINDING`: 105 -- `BS_FINDINGORE`: 106 -- `BS_WEAPONRESEARCH`: 107 -- `BS_REPAIRWEAPON`: 108 -- `BS_SKINTEMPER`: 109 -- `BS_HAMMERFALL`: 110 -- `BS_ADRENALINE`: 111 -- `BS_WEAPONPERFECT`: 112 -- `BS_OVERTHRUST`: 113 -- `BS_MAXIMIZE`: 114 -- `HT_SKIDTRAP`: 115 -- `HT_LANDMINE`: 116 -- `HT_ANKLESNARE`: 117 -- `HT_SHOCKWAVE`: 118 -- `HT_SANDMAN`: 119 -- `HT_FLASHER`: 120 -- `HT_FREEZINGTRAP`: 121 -- `HT_BLASTMINE`: 122 -- `HT_CLAYMORETRAP`: 123 -- `HT_REMOVETRAP`: 124 -- `HT_TALKIEBOX`: 125 -- `HT_BEASTBANE`: 126 -- `HT_FALCON`: 127 -- `HT_STEELCROW`: 128 -- `HT_BLITZBEAT`: 129 -- `HT_DETECTING`: 130 -- `HT_SPRINGTRAP`: 131 -- `AS_RIGHT`: 132 -- `AS_LEFT`: 133 -- `AS_KATAR`: 134 -- `AS_CLOAKING`: 135 -- `AS_SONICBLOW`: 136 -- `AS_GRIMTOOTH`: 137 -- `AS_ENCHANTPOISON`: 138 -- `AS_POISONREACT`: 139 -- `AS_VENOMDUST`: 140 -- `AS_SPLASHER`: 141 -- `NV_FIRSTAID`: 142 -- `NV_TRICKDEAD`: 143 -- `SM_MOVINGRECOVERY`: 144 -- `SM_FATALBLOW`: 145 -- `SM_AUTOBERSERK`: 146 -- `AC_MAKINGARROW`: 147 -- `AC_CHARGEARROW`: 148 -- `TF_SPRINKLESAND`: 149 -- `TF_BACKSLIDING`: 150 -- `TF_PICKSTONE`: 151 -- `TF_THROWSTONE`: 152 -- `MC_CARTREVOLUTION`: 153 -- `MC_CHANGECART`: 154 -- `MC_LOUD`: 155 -- `AL_HOLYLIGHT`: 156 -- `MG_ENERGYCOAT`: 157 -- `NPC_PIERCINGATT`: 158 -- `NPC_MENTALBREAKER`: 159 -- `NPC_RANGEATTACK`: 160 -- `NPC_ATTRICHANGE`: 161 -- `NPC_CHANGEWATER`: 162 -- `NPC_CHANGEGROUND`: 163 -- `NPC_CHANGEFIRE`: 164 -- `NPC_CHANGEWIND`: 165 -- `NPC_CHANGEPOISON`: 166 -- `NPC_CHANGEHOLY`: 167 -- `NPC_CHANGEDARKNESS`: 168 -- `NPC_CHANGETELEKINESIS`: 169 -- `NPC_CRITICALSLASH`: 170 -- `NPC_COMBOATTACK`: 171 -- `NPC_GUIDEDATTACK`: 172 -- `NPC_SELFDESTRUCTION`: 173 -- `NPC_SPLASHATTACK`: 174 -- `NPC_SUICIDE`: 175 -- `NPC_POISON`: 176 -- `NPC_BLINDATTACK`: 177 -- `NPC_SILENCEATTACK`: 178 -- `NPC_STUNATTACK`: 179 -- `NPC_PETRIFYATTACK`: 180 -- `NPC_CURSEATTACK`: 181 -- `NPC_SLEEPATTACK`: 182 -- `NPC_RANDOMATTACK`: 183 -- `NPC_WATERATTACK`: 184 -- `NPC_GROUNDATTACK`: 185 -- `NPC_FIREATTACK`: 186 -- `NPC_WINDATTACK`: 187 -- `NPC_POISONATTACK`: 188 -- `NPC_HOLYATTACK`: 189 -- `NPC_DARKNESSATTACK`: 190 -- `NPC_TELEKINESISATTACK`: 191 -- `NPC_MAGICALATTACK`: 192 -- `NPC_METAMORPHOSIS`: 193 -- `NPC_PROVOCATION`: 194 -- `NPC_SMOKING`: 195 -- `NPC_SUMMONSLAVE`: 196 -- `NPC_EMOTION`: 197 -- `NPC_TRANSFORMATION`: 198 -- `NPC_BLOODDRAIN`: 199 -- `NPC_ENERGYDRAIN`: 200 -- `NPC_KEEPING`: 201 -- `NPC_DARKBREATH`: 202 -- `NPC_DARKBLESSING`: 203 -- `NPC_BARRIER`: 204 -- `NPC_DEFENDER`: 205 -- `NPC_LICK`: 206 -- `NPC_HALLUCINATION`: 207 -- `NPC_REBIRTH`: 208 -- `NPC_SUMMONMONSTER`: 209 -- `RG_SNATCHER`: 210 -- `RG_STEALCOIN`: 211 -- `RG_BACKSTAP`: 212 -- `RG_TUNNELDRIVE`: 213 -- `RG_RAID`: 214 -- `RG_STRIPWEAPON`: 215 -- `RG_STRIPSHIELD`: 216 -- `RG_STRIPARMOR`: 217 -- `RG_STRIPHELM`: 218 -- `RG_INTIMIDATE`: 219 -- `RG_GRAFFITI`: 220 -- `RG_FLAGGRAFFITI`: 221 -- `RG_CLEANER`: 222 -- `RG_GANGSTER`: 223 -- `RG_COMPULSION`: 224 -- `RG_PLAGIARISM`: 225 -- `AM_AXEMASTERY`: 226 -- `AM_LEARNINGPOTION`: 227 -- `AM_PHARMACY`: 228 -- `AM_DEMONSTRATION`: 229 -- `AM_ACIDTERROR`: 230 -- `AM_POTIONPITCHER`: 231 -- `AM_CANNIBALIZE`: 232 -- `AM_SPHEREMINE`: 233 -- `AM_CP_WEAPON`: 234 -- `AM_CP_SHIELD`: 235 -- `AM_CP_ARMOR`: 236 -- `AM_CP_HELM`: 237 -- `AM_BIOETHICS`: 238 -- `AM_CALLHOMUN`: 243 -- `AM_REST`: 244 -- `AM_RESURRECTHOMUN`: 247 -- `CR_TRUST`: 248 -- `CR_AUTOGUARD`: 249 -- `CR_SHIELDCHARGE`: 250 -- `CR_SHIELDBOOMERANG`: 251 -- `CR_REFLECTSHIELD`: 252 -- `CR_HOLYCROSS`: 253 -- `CR_GRANDCROSS`: 254 -- `CR_DEVOTION`: 255 -- `CR_PROVIDENCE`: 256 -- `CR_DEFENDER`: 257 -- `CR_SPEARQUICKEN`: 258 -- `MO_IRONHAND`: 259 -- `MO_SPIRITSRECOVERY`: 260 -- `MO_CALLSPIRITS`: 261 -- `MO_ABSORBSPIRITS`: 262 -- `MO_TRIPLEATTACK`: 263 -- `MO_BODYRELOCATION`: 264 -- `MO_DODGE`: 265 -- `MO_INVESTIGATE`: 266 -- `MO_FINGEROFFENSIVE`: 267 -- `MO_STEELBODY`: 268 -- `MO_BLADESTOP`: 269 -- `MO_EXPLOSIONSPIRITS`: 270 -- `MO_EXTREMITYFIST`: 271 -- `MO_CHAINCOMBO`: 272 -- `MO_COMBOFINISH`: 273 -- `SA_ADVANCEDBOOK`: 274 -- `SA_CASTCANCEL`: 275 -- `SA_MAGICROD`: 276 -- `SA_SPELLBREAKER`: 277 -- `SA_FREECAST`: 278 -- `SA_AUTOSPELL`: 279 -- `SA_FLAMELAUNCHER`: 280 -- `SA_FROSTWEAPON`: 281 -- `SA_LIGHTNINGLOADER`: 282 -- `SA_SEISMICWEAPON`: 283 -- `SA_DRAGONOLOGY`: 284 -- `SA_VOLCANO`: 285 -- `SA_DELUGE`: 286 -- `SA_VIOLENTGALE`: 287 -- `SA_LANDPROTECTOR`: 288 -- `SA_DISPELL`: 289 -- `SA_ABRACADABRA`: 290 -- `SA_MONOCELL`: 291 -- `SA_CLASSCHANGE`: 292 -- `SA_SUMMONMONSTER`: 293 -- `SA_REVERSEORCISH`: 294 -- `SA_DEATH`: 295 -- `SA_FORTUNE`: 296 -- `SA_TAMINGMONSTER`: 297 -- `SA_QUESTION`: 298 -- `SA_GRAVITY`: 299 -- `SA_LEVELUP`: 300 -- `SA_INSTANTDEATH`: 301 -- `SA_FULLRECOVERY`: 302 -- `SA_COMA`: 303 -- `BD_ADAPTATION`: 304 -- `BD_ENCORE`: 305 -- `BD_LULLABY`: 306 -- `BD_RICHMANKIM`: 307 -- `BD_ETERNALCHAOS`: 308 -- `BD_DRUMBATTLEFIELD`: 309 -- `BD_RINGNIBELUNGEN`: 310 -- `BD_ROKISWEIL`: 311 -- `BD_INTOABYSS`: 312 -- `BD_SIEGFRIED`: 313 -- `BA_MUSICALLESSON`: 315 -- `BA_MUSICALSTRIKE`: 316 -- `BA_DISSONANCE`: 317 -- `BA_FROSTJOKER`: 318 -- `BA_WHISTLE`: 319 -- `BA_ASSASSINCROSS`: 320 -- `BA_POEMBRAGI`: 321 -- `BA_APPLEIDUN`: 322 -- `DC_DANCINGLESSON`: 323 -- `DC_THROWARROW`: 324 -- `DC_UGLYDANCE`: 325 -- `DC_SCREAM`: 326 -- `DC_HUMMING`: 327 -- `DC_DONTFORGETME`: 328 -- `DC_FORTUNEKISS`: 329 -- `DC_SERVICEFORYOU`: 330 -- `NPC_RANDOMMOVE`: 331 -- `NPC_SPEEDUP`: 332 -- `NPC_REVENGE`: 333 -- `WE_MALE`: 334 -- `WE_FEMALE`: 335 -- `WE_CALLPARTNER`: 336 -- `ITM_TOMAHAWK`: 337 -- `NPC_DARKCROSS`: 338 -- `NPC_GRANDDARKNESS`: 339 -- `NPC_DARKSTRIKE`: 340 -- `NPC_DARKTHUNDER`: 341 -- `NPC_STOP`: 342 -- `NPC_WEAPONBRAKER`: 343 -- `NPC_ARMORBRAKE`: 344 -- `NPC_HELMBRAKE`: 345 -- `NPC_SHIELDBRAKE`: 346 -- `NPC_UNDEADATTACK`: 347 -- `NPC_CHANGEUNDEAD`: 348 -- `NPC_POWERUP`: 349 -- `NPC_AGIUP`: 350 -- `NPC_SIEGEMODE`: 351 -- `NPC_CALLSLAVE`: 352 -- `NPC_INVISIBLE`: 353 -- `NPC_RUN`: 354 -- `LK_AURABLADE`: 355 -- `LK_PARRYING`: 356 -- `LK_CONCENTRATION`: 357 -- `LK_TENSIONRELAX`: 358 -- `LK_BERSERK`: 359 -- `HP_ASSUMPTIO`: 361 -- `HP_BASILICA`: 362 -- `HP_MEDITATIO`: 363 -- `HW_SOULDRAIN`: 364 -- `HW_MAGICCRASHER`: 365 -- `HW_MAGICPOWER`: 366 -- `PA_PRESSURE`: 367 -- `PA_SACRIFICE`: 368 -- `PA_GOSPEL`: 369 -- `CH_PALMSTRIKE`: 370 -- `CH_TIGERFIST`: 371 -- `CH_CHAINCRUSH`: 372 -- `PF_HPCONVERSION`: 373 -- `PF_SOULCHANGE`: 374 -- `PF_SOULBURN`: 375 -- `ASC_KATAR`: 376 -- `ASC_EDP`: 378 -- `ASC_BREAKER`: 379 -- `SN_SIGHT`: 380 -- `SN_FALCONASSAULT`: 381 -- `SN_SHARPSHOOTING`: 382 -- `SN_WINDWALK`: 383 -- `WS_MELTDOWN`: 384 -- `WS_CARTBOOST`: 387 -- `ST_CHASEWALK`: 389 -- `ST_REJECTSWORD`: 390 -- `CR_ALCHEMY`: 392 -- `CR_SYNTHESISPOTION`: 393 -- `CG_ARROWVULCAN`: 394 -- `CG_MOONLIT`: 395 -- `CG_MARIONETTE`: 396 -- `LK_SPIRALPIERCE`: 397 -- `LK_HEADCRUSH`: 398 -- `LK_JOINTBEAT`: 399 -- `HW_NAPALMVULCAN`: 400 -- `CH_SOULCOLLECT`: 401 -- `PF_MINDBREAKER`: 402 -- `PF_MEMORIZE`: 403 -- `PF_FOGWALL`: 404 -- `PF_SPIDERWEB`: 405 -- `ASC_METEORASSAULT`: 406 -- `ASC_CDP`: 407 -- `WE_BABY`: 408 -- `WE_CALLPARENT`: 409 -- `WE_CALLBABY`: 410 -- `TK_RUN`: 411 -- `TK_READYSTORM`: 412 -- `TK_STORMKICK`: 413 -- `TK_READYDOWN`: 414 -- `TK_DOWNKICK`: 415 -- `TK_READYTURN`: 416 -- `TK_TURNKICK`: 417 -- `TK_READYCOUNTER`: 418 -- `TK_COUNTER`: 419 -- `TK_DODGE`: 420 -- `TK_JUMPKICK`: 421 -- `TK_HPTIME`: 422 -- `TK_SPTIME`: 423 -- `TK_POWER`: 424 -- `TK_SEVENWIND`: 425 -- `TK_HIGHJUMP`: 426 -- `SG_FEEL`: 427 -- `SG_SUN_WARM`: 428 -- `SG_MOON_WARM`: 429 -- `SG_STAR_WARM`: 430 -- `SG_SUN_COMFORT`: 431 -- `SG_MOON_COMFORT`: 432 -- `SG_STAR_COMFORT`: 433 -- `SG_HATE`: 434 -- `SG_SUN_ANGER`: 435 -- `SG_MOON_ANGER`: 436 -- `SG_STAR_ANGER`: 437 -- `SG_SUN_BLESS`: 438 -- `SG_MOON_BLESS`: 439 -- `SG_STAR_BLESS`: 440 -- `SG_DEVIL`: 441 -- `SG_FRIEND`: 442 -- `SG_KNOWLEDGE`: 443 -- `SG_FUSION`: 444 -- `SL_ALCHEMIST`: 445 -- `AM_BERSERKPITCHER`: 446 -- `SL_MONK`: 447 -- `SL_STAR`: 448 -- `SL_SAGE`: 449 -- `SL_CRUSADER`: 450 -- `SL_SUPERNOVICE`: 451 -- `SL_KNIGHT`: 452 -- `SL_WIZARD`: 453 -- `SL_PRIEST`: 454 -- `SL_BARDDANCER`: 455 -- `SL_ROGUE`: 456 -- `SL_ASSASIN`: 457 -- `SL_BLACKSMITH`: 458 -- `BS_ADRENALINE2`: 459 -- `SL_HUNTER`: 460 -- `SL_SOULLINKER`: 461 -- `SL_KAIZEL`: 462 -- `SL_KAAHI`: 463 -- `SL_KAUPE`: 464 -- `SL_KAITE`: 465 -- `SL_KAINA`: 466 -- `SL_STIN`: 467 -- `SL_STUN`: 468 -- `SL_SMA`: 469 -- `SL_SWOO`: 470 -- `SL_SKE`: 471 -- `SL_SKA`: 472 -- `SM_SELFPROVOKE`: 473 -- `NPC_EMOTION_ON`: 474 -- `ST_PRESERVE`: 475 -- `ST_FULLSTRIP`: 476 -- `WS_WEAPONREFINE`: 477 -- `CR_SLIMPITCHER`: 478 -- `CR_FULLPROTECTION`: 479 -- `PA_SHIELDCHAIN`: 480 -- `HP_MANARECHARGE`: 481 -- `PF_DOUBLECASTING`: 482 -- `HW_GANBANTEIN`: 483 -- `HW_GRAVITATION`: 484 -- `WS_CARTTERMINATION`: 485 -- `WS_OVERTHRUSTMAX`: 486 -- `CG_LONGINGFREEDOM`: 487 -- `CG_HERMODE`: 488 -- `CG_TAROTCARD`: 489 -- `CR_ACIDDEMONSTRATION`: 490 -- `CR_CULTIVATION`: 491 -- `ITEM_ENCHANTARMS`: 492 -- `TK_MISSION`: 493 -- `SL_HIGH`: 494 -- `KN_ONEHAND`: 495 -- `AM_TWILIGHT1`: 496 -- `AM_TWILIGHT2`: 497 -- `AM_TWILIGHT3`: 498 -- `HT_POWER`: 499 -- `GS_GLITTERING`: 500 -- `GS_FLING`: 501 -- `GS_TRIPLEACTION`: 502 -- `GS_BULLSEYE`: 503 -- `GS_MADNESSCANCEL`: 504 -- `GS_ADJUSTMENT`: 505 -- `GS_INCREASING`: 506 -- `GS_MAGICALBULLET`: 507 -- `GS_CRACKER`: 508 -- `GS_SINGLEACTION`: 509 -- `GS_SNAKEEYE`: 510 -- `GS_CHAINACTION`: 511 -- `GS_TRACKING`: 512 -- `GS_DISARM`: 513 -- `GS_PIERCINGSHOT`: 514 -- `GS_RAPIDSHOWER`: 515 -- `GS_DESPERADO`: 516 -- `GS_GATLINGFEVER`: 517 -- `GS_DUST`: 518 -- `GS_FULLBUSTER`: 519 -- `GS_SPREADATTACK`: 520 -- `GS_GROUNDDRIFT`: 521 -- `NJ_TOBIDOUGU`: 522 -- `NJ_SYURIKEN`: 523 -- `NJ_KUNAI`: 524 -- `NJ_HUUMA`: 525 -- `NJ_ZENYNAGE`: 526 -- `NJ_TATAMIGAESHI`: 527 -- `NJ_KASUMIKIRI`: 528 -- `NJ_SHADOWJUMP`: 529 -- `NJ_KIRIKAGE`: 530 -- `NJ_UTSUSEMI`: 531 -- `NJ_BUNSINJYUTSU`: 532 -- `NJ_NINPOU`: 533 -- `NJ_KOUENKA`: 534 -- `NJ_KAENSIN`: 535 -- `NJ_BAKUENRYU`: 536 -- `NJ_HYOUSENSOU`: 537 -- `NJ_SUITON`: 538 -- `NJ_HYOUSYOURAKU`: 539 -- `NJ_HUUJIN`: 540 -- `NJ_RAIGEKISAI`: 541 -- `NJ_KAMAITACHI`: 542 -- `NJ_NEN`: 543 -- `NJ_ISSEN`: 544 -- `NPC_EARTHQUAKE`: 653 -- `NPC_FIREBREATH`: 654 -- `NPC_ICEBREATH`: 655 -- `NPC_THUNDERBREATH`: 656 -- `NPC_ACIDBREATH`: 657 -- `NPC_DARKNESSBREATH`: 658 -- `NPC_DRAGONFEAR`: 659 -- `NPC_BLEEDING`: 660 -- `NPC_PULSESTRIKE`: 661 -- `NPC_HELLJUDGEMENT`: 662 -- `NPC_WIDESILENCE`: 663 -- `NPC_WIDEFREEZE`: 664 -- `NPC_WIDEBLEEDING`: 665 -- `NPC_WIDESTONE`: 666 -- `NPC_WIDECONFUSE`: 667 -- `NPC_WIDESLEEP`: 668 -- `NPC_WIDESIGHT`: 669 -- `NPC_EVILLAND`: 670 -- `NPC_MAGICMIRROR`: 671 -- `NPC_SLOWCAST`: 672 -- `NPC_CRITICALWOUND`: 673 -- `NPC_EXPULSION`: 674 -- `NPC_STONESKIN`: 675 -- `NPC_ANTIMAGIC`: 676 -- `NPC_WIDECURSE`: 677 -- `NPC_WIDESTUN`: 678 -- `NPC_VAMPIRE_GIFT`: 679 -- `NPC_WIDESOULDRAIN`: 680 -- `ALL_INCCARRY`: 681 -- `NPC_TALK`: 682 -- `NPC_HELLPOWER`: 683 -- `NPC_WIDEHELLDIGNITY`: 684 -- `NPC_INVINCIBLE`: 685 -- `NPC_INVINCIBLEOFF`: 686 -- `NPC_ALLHEAL`: 687 -- `GM_SANDMAN`: 688 -- `CASH_BLESSING`: 689 -- `CASH_INCAGI`: 690 -- `CASH_ASSUMPTIO`: 691 -- `ALL_CATCRY`: 692 -- `ALL_PARTYFLEE`: 693 -- `ALL_ANGEL_PROTECT`: 694 -- `ALL_DREAM_SUMMERNIGHT`: 695 -- `ALL_REVERSEORCISH`: 697 - `ALL_WEWISH`: 698 -- `HLIF_HEAL`: 8001 -- `HLIF_AVOID`: 8002 -- `HLIF_BRAIN`: 8003 -- `HLIF_CHANGE`: 8004 -- `HAMI_CASTLE`: 8005 -- `HAMI_DEFENCE`: 8006 -- `HAMI_SKIN`: 8007 -- `HAMI_BLOODLUST`: 8008 -- `HFLI_MOON`: 8009 -- `HFLI_FLEET`: 8010 -- `HFLI_SPEED`: 8011 -- `HFLI_SBR44`: 8012 -- `HVAN_CAPRICE`: 8013 -- `HVAN_CHAOTIC`: 8014 -- `HVAN_INSTRUCT`: 8015 -- `HVAN_EXPLOSION`: 8016 -- `MH_SUMMON_LEGION`: 8018 -- `MH_NEEDLE_OF_PARALYZE`: 8019 -- `MH_POISON_MIST`: 8020 -- `MH_PAIN_KILLER`: 8021 -- `MH_LIGHT_OF_REGENE`: 8022 -- `MH_OVERED_BOOST`: 8023 -- `MH_ERASER_CUTTER`: 8024 -- `MH_XENO_SLASHER`: 8025 -- `MH_SILENT_BREEZE`: 8026 -- `MH_STYLE_CHANGE`: 8027 -- `MH_SONIC_CRAW`: 8028 -- `MH_SILVERVEIN_RUSH`: 8029 -- `MH_MIDNIGHT_FRENZY`: 8030 -- `MH_STAHL_HORN`: 8031 -- `MH_GOLDENE_FERSE`: 8032 -- `MH_STEINWAND`: 8033 -- `MH_HEILIGE_STANGE`: 8034 -- `MH_ANGRIFFS_MODUS`: 8035 -- `MH_TINDER_BREAKER`: 8036 -- `MH_CBC`: 8037 -- `MH_EQC`: 8038 -- `MH_MAGMA_FLOW`: 8039 -- `MH_GRANITIC_ARMOR`: 8040 -- `MH_LAVA_SLIDE`: 8041 -- `MH_PYROCLASTIC`: 8042 -- `MH_VOLCANIC_ASH`: 8043 -- `MS_BASH`: 8201 -- `MS_MAGNUM`: 8202 -- `MS_BOWLINGBASH`: 8203 -- `MS_PARRYING`: 8204 -- `MS_REFLECTSHIELD`: 8205 -- `MS_BERSERK`: 8206 -- `MA_DOUBLE`: 8207 -- `MA_SHOWER`: 8208 -- `MA_SKIDTRAP`: 8209 -- `MA_LANDMINE`: 8210 -- `MA_SANDMAN`: 8211 -- `MA_FREEZINGTRAP`: 8212 -- `MA_REMOVETRAP`: 8213 -- `MA_CHARGEARROW`: 8214 -- `MA_SHARPSHOOTING`: 8215 -- `ML_PIERCE`: 8216 -- `ML_BRANDISH`: 8217 -- `ML_SPIRALPIERCE`: 8218 -- `ML_DEFENDER`: 8219 -- `ML_AUTOGUARD`: 8220 -- `ML_DEVOTION`: 8221 -- `MER_MAGNIFICAT`: 8222 -- `MER_QUICKEN`: 8223 -- `MER_SIGHT`: 8224 -- `MER_CRASH`: 8225 -- `MER_REGAIN`: 8226 -- `MER_TENDER`: 8227 -- `MER_BENEDICTION`: 8228 -- `MER_RECUPERATE`: 8229 -- `MER_MENTALCURE`: 8230 -- `MER_COMPRESS`: 8231 -- `MER_PROVOKE`: 8232 -- `MER_AUTOBERSERK`: 8233 -- `MER_DECAGI`: 8234 -- `MER_SCAPEGOAT`: 8235 -- `MER_LEXDIVINA`: 8236 -- `MER_ESTIMATION`: 8237 -- `MER_KYRIE`: 8238 -- `MER_BLESSING`: 8239 -- `MER_INCAGI`: 8240 -- `EL_CIRCLE_OF_FIRE`: 8401 -- `EL_FIRE_CLOAK`: 8402 -- `EL_FIRE_MANTLE`: 8403 -- `EL_WATER_SCREEN`: 8404 -- `EL_WATER_DROP`: 8405 -- `EL_WATER_BARRIER`: 8406 -- `EL_WIND_STEP`: 8407 -- `EL_WIND_CURTAIN`: 8408 -- `EL_ZEPHYR`: 8409 -- `EL_SOLID_SKIN`: 8410 -- `EL_STONE_SHIELD`: 8411 -- `EL_POWER_OF_GAIA`: 8412 -- `EL_PYROTECHNIC`: 8413 -- `EL_HEATER`: 8414 -- `EL_TROPIC`: 8415 -- `EL_AQUAPLAY`: 8416 -- `EL_COOLER`: 8417 -- `EL_CHILLY_AIR`: 8418 -- `EL_GUST`: 8419 -- `EL_BLAST`: 8420 -- `EL_WILD_STORM`: 8421 -- `EL_PETROLOGY`: 8422 -- `EL_CURSED_SOIL`: 8423 -- `EL_UPHEAVAL`: 8424 -- `EL_FIRE_ARROW`: 8425 -- `EL_FIRE_BOMB`: 8426 -- `EL_FIRE_BOMB_ATK`: 8427 -- `EL_FIRE_WAVE`: 8428 -- `EL_FIRE_WAVE_ATK`: 8429 -- `EL_ICE_NEEDLE`: 8430 -- `EL_WATER_SCREW`: 8431 -- `EL_WATER_SCREW_ATK`: 8432 -- `EL_TIDAL_WEAPON`: 8433 -- `EL_WIND_SLASH`: 8434 -- `EL_HURRICANE`: 8435 -- `EL_HURRICANE_ATK`: 8436 -- `EL_TYPOON_MIS`: 8437 -- `EL_TYPOON_MIS_ATK`: 8438 -- `EL_STONE_HAMMER`: 8439 -- `EL_ROCK_CRUSHER`: 8440 -- `EL_ROCK_CRUSHER_ATK`: 8441 -- `EL_STONE_RAIN`: 8442 -- `GD_APPROVAL`: 10000 -- `GD_KAFRACONTRACT`: 10001 -- `GD_GUARDRESEARCH`: 10002 -- `GD_GUARDUP`: 10003 -- `GD_EXTENSION`: 10004 -- `GD_GLORYGUILD`: 10005 -- `GD_LEADERSHIP`: 10006 -- `GD_GLORYWOUNDS`: 10007 -- `GD_SOULCOLD`: 10008 -- `GD_HAWKEYES`: 10009 -- `GD_BATTLEORDER`: 10010 -- `GD_REGENERATION`: 10011 -- `GD_RESTORE`: 10012 -- `GD_EMERGENCYCALL`: 10013 -- `GD_DEVELOPMENT`: 10014 -- `RL_GLITTERING_GREED`: 2551 -- `RL_RICHS_COIN`: 2552 -- `RL_MASS_SPIRAL`: 2553 -- `RL_BANISHING_BUSTER`: 2554 -- `RL_B_TRAP`: 2555 -- `RL_FLICKER`: 2556 -- `RL_S_STORM`: 2557 -- `RL_E_CHAIN`: 2558 -- `RL_QD_SHOT`: 2559 -- `RL_C_MARKER`: 2560 -- `RL_FIREDANCE`: 2561 -- `RL_H_MINE`: 2562 -- `RL_P_ALTER`: 2563 -- `RL_FALLEN_ANGEL`: 2564 -- `RL_R_TRIP`: 2565 -- `RL_D_TAIL`: 2566 -- `RL_FIRE_RAIN`: 2567 -- `RL_HEAT_BARREL`: 2568 -- `RL_AM_BLAST`: 2569 -- `RL_SLUGSHOT`: 2570 -- `RL_HAMMER_OF_GOD`: 2571 -- `RL_R_TRIP_PLUSATK`: 2572 -- `RL_B_FLICKER_ATK`: 2573 -- `RL_GLITTERING_GREED_ATK`: 2574 -- `KN_CHARGEATK`: 1001 -- `CR_SHRINK`: 1002 -- `AS_SONICACCEL`: 1003 -- `AS_VENOMKNIFE`: 1004 -- `RG_CLOSECONFINE`: 1005 -- `WZ_SIGHTBLASTER`: 1006 -- `SA_CREATECON`: 1007 -- `SA_ELEMENTWATER`: 1008 -- `HT_PHANTASMIC`: 1009 -- `BA_PANGVOICE`: 1010 -- `DC_WINKCHARM`: 1011 -- `BS_UNFAIRLYTRICK`: 1012 -- `BS_GREED`: 1013 -- `PR_REDEMPTIO`: 1014 -- `MO_KITRANSLATION`: 1015 -- `MO_BALKYOUNG`: 1016 -- `SA_ELEMENTGROUND`: 1017 -- `SA_ELEMENTFIRE`: 1018 +- `ALL_REVERSEORCISH`: 697 +- `ALL_DREAM_SUMMERNIGHT`: 695 +- `ALL_ANGEL_PROTECT`: 694 +- `ALL_PARTYFLEE`: 693 +- `ALL_CATCRY`: 692 +- `CASH_ASSUMPTIO`: 691 +- `CASH_INCAGI`: 690 +- `CASH_BLESSING`: 689 +- `GM_SANDMAN`: 688 +- `NPC_ALLHEAL`: 687 +- `NPC_INVINCIBLEOFF`: 686 +- `NPC_INVINCIBLE`: 685 +- `NPC_WIDEHELLDIGNITY`: 684 +- `NPC_HELLPOWER`: 683 +- `NPC_TALK`: 682 +- `ALL_INCCARRY`: 681 +- `NPC_WIDESOULDRAIN`: 680 +- `NPC_VAMPIRE_GIFT`: 679 +- `NPC_WIDESTUN`: 678 +- `NPC_WIDECURSE`: 677 +- `NPC_ANTIMAGIC`: 676 +- `NPC_STONESKIN`: 675 +- `NPC_EXPULSION`: 674 +- `NPC_CRITICALWOUND`: 673 +- `NPC_SLOWCAST`: 672 +- `NPC_MAGICMIRROR`: 671 +- `NPC_EVILLAND`: 670 +- `NPC_WIDESIGHT`: 669 +- `NPC_WIDESLEEP`: 668 +- `NPC_WIDECONFUSE`: 667 +- `NPC_WIDESTONE`: 666 +- `NPC_WIDEBLEEDING`: 665 +- `NPC_WIDEFREEZE`: 664 +- `NPC_WIDESILENCE`: 663 +- `NPC_HELLJUDGEMENT`: 662 +- `NPC_PULSESTRIKE`: 661 +- `NPC_BLEEDING`: 660 +- `NPC_DRAGONFEAR`: 659 +- `NPC_DARKNESSBREATH`: 658 +- `NPC_ACIDBREATH`: 657 +- `NPC_THUNDERBREATH`: 656 +- `NPC_ICEBREATH`: 655 +- `NPC_FIREBREATH`: 654 +- `NPC_EARTHQUAKE`: 653 +- `NJ_ISSEN`: 544 +- `NJ_NEN`: 543 +- `NJ_KAMAITACHI`: 542 +- `NJ_RAIGEKISAI`: 541 +- `NJ_HUUJIN`: 540 +- `NJ_HYOUSYOURAKU`: 539 +- `NJ_SUITON`: 538 +- `NJ_HYOUSENSOU`: 537 +- `NJ_BAKUENRYU`: 536 +- `NJ_KAENSIN`: 535 +- `NJ_KOUENKA`: 534 +- `NJ_NINPOU`: 533 +- `NJ_BUNSINJYUTSU`: 532 +- `NJ_UTSUSEMI`: 531 +- `NJ_KIRIKAGE`: 530 +- `NJ_SHADOWJUMP`: 529 +- `NJ_KASUMIKIRI`: 528 +- `NJ_TATAMIGAESHI`: 527 +- `NJ_ZENYNAGE`: 526 +- `NJ_HUUMA`: 525 +- `NJ_KUNAI`: 524 +- `NJ_SYURIKEN`: 523 +- `NJ_TOBIDOUGU`: 522 +- `GS_GROUNDDRIFT`: 521 +- `GS_SPREADATTACK`: 520 +- `GS_FULLBUSTER`: 519 +- `GS_DUST`: 518 +- `GS_GATLINGFEVER`: 517 +- `GS_DESPERADO`: 516 +- `GS_RAPIDSHOWER`: 515 +- `GS_PIERCINGSHOT`: 514 +- `GS_DISARM`: 513 +- `GS_TRACKING`: 512 +- `GS_CHAINACTION`: 511 +- `GS_SNAKEEYE`: 510 +- `GS_SINGLEACTION`: 509 +- `GS_CRACKER`: 508 +- `GS_MAGICALBULLET`: 507 +- `GS_INCREASING`: 506 +- `GS_ADJUSTMENT`: 505 +- `GS_MADNESSCANCEL`: 504 +- `GS_BULLSEYE`: 503 +- `GS_TRIPLEACTION`: 502 +- `GS_FLING`: 501 +- `GS_GLITTERING`: 500 +- `HT_POWER`: 499 +- `AM_TWILIGHT3`: 498 +- `AM_TWILIGHT2`: 497 +- `AM_TWILIGHT1`: 496 +- `KN_ONEHAND`: 495 +- `SL_HIGH`: 494 +- `TK_MISSION`: 493 +- `ITEM_ENCHANTARMS`: 492 +- `CR_CULTIVATION`: 491 +- `CR_ACIDDEMONSTRATION`: 490 +- `CG_TAROTCARD`: 489 +- `CG_HERMODE`: 488 +- `CG_LONGINGFREEDOM`: 487 +- `WS_OVERTHRUSTMAX`: 486 +- `WS_CARTTERMINATION`: 485 +- `HW_GRAVITATION`: 484 +- `HW_GANBANTEIN`: 483 +- `PF_DOUBLECASTING`: 482 +- `HP_MANARECHARGE`: 481 +- `PA_SHIELDCHAIN`: 480 +- `CR_FULLPROTECTION`: 479 +- `CR_SLIMPITCHER`: 478 +- `WS_WEAPONREFINE`: 477 +- `ST_FULLSTRIP`: 476 +- `ST_PRESERVE`: 475 +- `NPC_EMOTION_ON`: 474 +- `SM_SELFPROVOKE`: 473 +- `SL_SKA`: 472 +- `SL_SKE`: 471 +- `SL_SWOO`: 470 +- `SL_SMA`: 469 +- `SL_STUN`: 468 +- `SL_STIN`: 467 +- `SL_KAINA`: 466 +- `SL_KAITE`: 465 +- `SL_KAUPE`: 464 +- `SL_KAAHI`: 463 +- `SL_KAIZEL`: 462 +- `SL_SOULLINKER`: 461 +- `SL_HUNTER`: 460 +- `BS_ADRENALINE2`: 459 +- `SL_BLACKSMITH`: 458 +- `SL_ASSASIN`: 457 +- `SL_ROGUE`: 456 +- `SL_BARDDANCER`: 455 +- `SL_PRIEST`: 454 +- `SL_WIZARD`: 453 +- `SL_KNIGHT`: 452 +- `SL_SUPERNOVICE`: 451 +- `SL_CRUSADER`: 450 +- `SL_SAGE`: 449 +- `SL_STAR`: 448 +- `SL_MONK`: 447 +- `AM_BERSERKPITCHER`: 446 +- `SL_ALCHEMIST`: 445 +- `SG_FUSION`: 444 +- `SG_KNOWLEDGE`: 443 +- `SG_FRIEND`: 442 +- `SG_DEVIL`: 441 +- `SG_STAR_BLESS`: 440 +- `SG_MOON_BLESS`: 439 +- `SG_SUN_BLESS`: 438 +- `SG_STAR_ANGER`: 437 +- `SG_MOON_ANGER`: 436 +- `SG_SUN_ANGER`: 435 +- `SG_HATE`: 434 +- `SG_STAR_COMFORT`: 433 +- `SG_MOON_COMFORT`: 432 +- `SG_SUN_COMFORT`: 431 +- `SG_STAR_WARM`: 430 +- `SG_MOON_WARM`: 429 +- `SG_SUN_WARM`: 428 +- `SG_FEEL`: 427 +- `TK_HIGHJUMP`: 426 +- `TK_SEVENWIND`: 425 +- `TK_POWER`: 424 +- `TK_SPTIME`: 423 +- `TK_HPTIME`: 422 +- `TK_JUMPKICK`: 421 +- `TK_DODGE`: 420 +- `TK_COUNTER`: 419 +- `TK_READYCOUNTER`: 418 +- `TK_TURNKICK`: 417 +- `TK_READYTURN`: 416 +- `TK_DOWNKICK`: 415 +- `TK_READYDOWN`: 414 +- `TK_STORMKICK`: 413 +- `TK_READYSTORM`: 412 +- `TK_RUN`: 411 +- `WE_CALLBABY`: 410 +- `WE_CALLPARENT`: 409 +- `WE_BABY`: 408 +- `ASC_CDP`: 407 +- `ASC_METEORASSAULT`: 406 +- `PF_SPIDERWEB`: 405 +- `PF_FOGWALL`: 404 +- `PF_MEMORIZE`: 403 +- `PF_MINDBREAKER`: 402 +- `CH_SOULCOLLECT`: 401 +- `HW_NAPALMVULCAN`: 400 +- `LK_JOINTBEAT`: 399 +- `LK_HEADCRUSH`: 398 +- `LK_SPIRALPIERCE`: 397 +- `CG_MARIONETTE`: 396 +- `CG_MOONLIT`: 395 +- `CG_ARROWVULCAN`: 394 +- `CR_SYNTHESISPOTION`: 393 +- `CR_ALCHEMY`: 392 +- `ST_REJECTSWORD`: 390 +- `ST_CHASEWALK`: 389 +- `WS_CARTBOOST`: 387 +- `WS_MELTDOWN`: 384 +- `SN_WINDWALK`: 383 +- `SN_SHARPSHOOTING`: 382 +- `SN_FALCONASSAULT`: 381 +- `SN_SIGHT`: 380 +- `ASC_BREAKER`: 379 +- `ASC_EDP`: 378 +- `ASC_KATAR`: 376 +- `PF_SOULBURN`: 375 +- `PF_SOULCHANGE`: 374 +- `PF_HPCONVERSION`: 373 +- `CH_CHAINCRUSH`: 372 +- `CH_TIGERFIST`: 371 +- `CH_PALMSTRIKE`: 370 +- `PA_GOSPEL`: 369 +- `PA_SACRIFICE`: 368 +- `PA_PRESSURE`: 367 +- `HW_MAGICPOWER`: 366 +- `HW_MAGICCRASHER`: 365 +- `HW_SOULDRAIN`: 364 +- `HP_MEDITATIO`: 363 +- `HP_BASILICA`: 362 +- `HP_ASSUMPTIO`: 361 +- `LK_BERSERK`: 359 +- `LK_TENSIONRELAX`: 358 +- `LK_CONCENTRATION`: 357 +- `LK_PARRYING`: 356 +- `LK_AURABLADE`: 355 +- `NPC_RUN`: 354 +- `NPC_INVISIBLE`: 353 +- `NPC_CALLSLAVE`: 352 +- `NPC_SIEGEMODE`: 351 +- `NPC_AGIUP`: 350 +- `NPC_POWERUP`: 349 +- `NPC_CHANGEUNDEAD`: 348 +- `NPC_UNDEADATTACK`: 347 +- `NPC_SHIELDBRAKE`: 346 +- `NPC_HELMBRAKE`: 345 +- `NPC_ARMORBRAKE`: 344 +- `NPC_WEAPONBRAKER`: 343 +- `NPC_STOP`: 342 +- `NPC_DARKTHUNDER`: 341 +- `NPC_DARKSTRIKE`: 340 +- `NPC_GRANDDARKNESS`: 339 +- `NPC_DARKCROSS`: 338 +- `ITM_TOMAHAWK`: 337 +- `WE_CALLPARTNER`: 336 +- `WE_FEMALE`: 335 +- `WE_MALE`: 334 +- `NPC_REVENGE`: 333 +- `NPC_SPEEDUP`: 332 +- `NPC_RANDOMMOVE`: 331 +- `DC_SERVICEFORYOU`: 330 +- `DC_FORTUNEKISS`: 329 +- `DC_DONTFORGETME`: 328 +- `DC_HUMMING`: 327 +- `DC_SCREAM`: 326 +- `DC_UGLYDANCE`: 325 +- `DC_THROWARROW`: 324 +- `DC_DANCINGLESSON`: 323 +- `BA_APPLEIDUN`: 322 +- `BA_POEMBRAGI`: 321 +- `BA_ASSASSINCROSS`: 320 +- `BA_WHISTLE`: 319 +- `BA_FROSTJOKER`: 318 +- `BA_DISSONANCE`: 317 +- `BA_MUSICALSTRIKE`: 316 +- `BA_MUSICALLESSON`: 315 +- `BD_SIEGFRIED`: 313 +- `BD_INTOABYSS`: 312 +- `BD_ROKISWEIL`: 311 +- `BD_RINGNIBELUNGEN`: 310 +- `BD_DRUMBATTLEFIELD`: 309 +- `BD_ETERNALCHAOS`: 308 +- `BD_RICHMANKIM`: 307 +- `BD_LULLABY`: 306 +- `BD_ENCORE`: 305 +- `BD_ADAPTATION`: 304 +- `SA_COMA`: 303 +- `SA_FULLRECOVERY`: 302 +- `SA_INSTANTDEATH`: 301 +- `SA_LEVELUP`: 300 +- `SA_GRAVITY`: 299 +- `SA_QUESTION`: 298 +- `SA_TAMINGMONSTER`: 297 +- `SA_FORTUNE`: 296 +- `SA_DEATH`: 295 +- `SA_REVERSEORCISH`: 294 +- `SA_SUMMONMONSTER`: 293 +- `SA_CLASSCHANGE`: 292 +- `SA_MONOCELL`: 291 +- `SA_ABRACADABRA`: 290 +- `SA_DISPELL`: 289 +- `SA_LANDPROTECTOR`: 288 +- `SA_VIOLENTGALE`: 287 +- `SA_DELUGE`: 286 +- `SA_VOLCANO`: 285 +- `SA_DRAGONOLOGY`: 284 +- `SA_SEISMICWEAPON`: 283 +- `SA_LIGHTNINGLOADER`: 282 +- `SA_FROSTWEAPON`: 281 +- `SA_FLAMELAUNCHER`: 280 +- `SA_AUTOSPELL`: 279 +- `SA_FREECAST`: 278 +- `SA_SPELLBREAKER`: 277 +- `SA_MAGICROD`: 276 +- `SA_CASTCANCEL`: 275 +- `SA_ADVANCEDBOOK`: 274 +- `MO_COMBOFINISH`: 273 +- `MO_CHAINCOMBO`: 272 +- `MO_EXTREMITYFIST`: 271 +- `MO_EXPLOSIONSPIRITS`: 270 +- `MO_BLADESTOP`: 269 +- `MO_STEELBODY`: 268 +- `MO_FINGEROFFENSIVE`: 267 +- `MO_INVESTIGATE`: 266 +- `MO_DODGE`: 265 +- `MO_BODYRELOCATION`: 264 +- `MO_TRIPLEATTACK`: 263 +- `MO_ABSORBSPIRITS`: 262 +- `MO_CALLSPIRITS`: 261 +- `MO_SPIRITSRECOVERY`: 260 +- `MO_IRONHAND`: 259 +- `CR_SPEARQUICKEN`: 258 +- `CR_DEFENDER`: 257 +- `CR_PROVIDENCE`: 256 +- `CR_DEVOTION`: 255 +- `CR_GRANDCROSS`: 254 +- `CR_HOLYCROSS`: 253 +- `CR_REFLECTSHIELD`: 252 +- `CR_SHIELDBOOMERANG`: 251 +- `CR_SHIELDCHARGE`: 250 +- `CR_AUTOGUARD`: 249 +- `CR_TRUST`: 248 +- `AM_RESURRECTHOMUN`: 247 +- `AM_REST`: 244 +- `AM_CALLHOMUN`: 243 +- `AM_BIOETHICS`: 238 +- `AM_CP_HELM`: 237 +- `AM_CP_ARMOR`: 236 +- `AM_CP_SHIELD`: 235 +- `AM_CP_WEAPON`: 234 +- `AM_SPHEREMINE`: 233 +- `AM_CANNIBALIZE`: 232 +- `AM_POTIONPITCHER`: 231 +- `AM_ACIDTERROR`: 230 +- `AM_DEMONSTRATION`: 229 +- `AM_PHARMACY`: 228 +- `AM_LEARNINGPOTION`: 227 +- `AM_AXEMASTERY`: 226 +- `RG_PLAGIARISM`: 225 +- `RG_COMPULSION`: 224 +- `RG_GANGSTER`: 223 +- `RG_CLEANER`: 222 +- `RG_FLAGGRAFFITI`: 221 +- `RG_GRAFFITI`: 220 +- `RG_INTIMIDATE`: 219 +- `RG_STRIPHELM`: 218 +- `RG_STRIPARMOR`: 217 +- `RG_STRIPSHIELD`: 216 +- `RG_STRIPWEAPON`: 215 +- `RG_RAID`: 214 +- `RG_TUNNELDRIVE`: 213 +- `RG_BACKSTAP`: 212 +- `RG_STEALCOIN`: 211 +- `RG_SNATCHER`: 210 +- `NPC_SUMMONMONSTER`: 209 +- `NPC_REBIRTH`: 208 +- `NPC_HALLUCINATION`: 207 +- `NPC_LICK`: 206 +- `NPC_DEFENDER`: 205 +- `NPC_BARRIER`: 204 +- `NPC_DARKBLESSING`: 203 +- `NPC_DARKBREATH`: 202 +- `NPC_KEEPING`: 201 +- `NPC_ENERGYDRAIN`: 200 +- `NPC_BLOODDRAIN`: 199 +- `NPC_TRANSFORMATION`: 198 +- `NPC_EMOTION`: 197 +- `NPC_SUMMONSLAVE`: 196 +- `NPC_SMOKING`: 195 +- `NPC_PROVOCATION`: 194 +- `NPC_METAMORPHOSIS`: 193 +- `NPC_MAGICALATTACK`: 192 +- `NPC_TELEKINESISATTACK`: 191 +- `NPC_DARKNESSATTACK`: 190 +- `NPC_HOLYATTACK`: 189 +- `NPC_POISONATTACK`: 188 +- `NPC_WINDATTACK`: 187 +- `NPC_FIREATTACK`: 186 +- `NPC_GROUNDATTACK`: 185 +- `NPC_WATERATTACK`: 184 +- `NPC_RANDOMATTACK`: 183 +- `NPC_SLEEPATTACK`: 182 +- `NPC_CURSEATTACK`: 181 +- `NPC_PETRIFYATTACK`: 180 +- `NPC_STUNATTACK`: 179 +- `NPC_SILENCEATTACK`: 178 +- `NPC_BLINDATTACK`: 177 +- `NPC_POISON`: 176 +- `NPC_SUICIDE`: 175 +- `NPC_SPLASHATTACK`: 174 +- `NPC_SELFDESTRUCTION`: 173 +- `NPC_GUIDEDATTACK`: 172 +- `NPC_COMBOATTACK`: 171 +- `NPC_CRITICALSLASH`: 170 +- `NPC_CHANGETELEKINESIS`: 169 +- `NPC_CHANGEDARKNESS`: 168 +- `NPC_CHANGEHOLY`: 167 +- `NPC_CHANGEPOISON`: 166 +- `NPC_CHANGEWIND`: 165 +- `NPC_CHANGEFIRE`: 164 +- `NPC_CHANGEGROUND`: 163 +- `NPC_CHANGEWATER`: 162 +- `NPC_ATTRICHANGE`: 161 +- `NPC_RANGEATTACK`: 160 +- `NPC_MENTALBREAKER`: 159 +- `NPC_PIERCINGATT`: 158 +- `MG_ENERGYCOAT`: 157 +- `AL_HOLYLIGHT`: 156 +- `MC_LOUD`: 155 +- `MC_CHANGECART`: 154 +- `MC_CARTREVOLUTION`: 153 +- `TF_THROWSTONE`: 152 +- `TF_PICKSTONE`: 151 +- `TF_BACKSLIDING`: 150 +- `TF_SPRINKLESAND`: 149 +- `AC_CHARGEARROW`: 148 +- `AC_MAKINGARROW`: 147 +- `SM_AUTOBERSERK`: 146 +- `SM_FATALBLOW`: 145 +- `SM_MOVINGRECOVERY`: 144 +- `NV_TRICKDEAD`: 143 +- `NV_FIRSTAID`: 142 +- `AS_SPLASHER`: 141 +- `AS_VENOMDUST`: 140 +- `AS_POISONREACT`: 139 +- `AS_ENCHANTPOISON`: 138 +- `AS_GRIMTOOTH`: 137 +- `AS_SONICBLOW`: 136 +- `AS_CLOAKING`: 135 +- `AS_KATAR`: 134 +- `AS_LEFT`: 133 +- `AS_RIGHT`: 132 +- `HT_SPRINGTRAP`: 131 +- `HT_DETECTING`: 130 +- `HT_BLITZBEAT`: 129 +- `HT_STEELCROW`: 128 +- `HT_FALCON`: 127 +- `HT_BEASTBANE`: 126 +- `HT_TALKIEBOX`: 125 +- `HT_REMOVETRAP`: 124 +- `HT_CLAYMORETRAP`: 123 +- `HT_BLASTMINE`: 122 +- `HT_FREEZINGTRAP`: 121 +- `HT_FLASHER`: 120 +- `HT_SANDMAN`: 119 +- `HT_SHOCKWAVE`: 118 +- `HT_ANKLESNARE`: 117 +- `HT_LANDMINE`: 116 +- `HT_SKIDTRAP`: 115 +- `BS_MAXIMIZE`: 114 +- `BS_OVERTHRUST`: 113 +- `BS_WEAPONPERFECT`: 112 +- `BS_ADRENALINE`: 111 +- `BS_HAMMERFALL`: 110 +- `BS_SKINTEMPER`: 109 +- `BS_REPAIRWEAPON`: 108 +- `BS_WEAPONRESEARCH`: 107 +- `BS_FINDINGORE`: 106 +- `BS_HILTBINDING`: 105 +- `BS_SPEAR`: 104 +- `BS_KNUCKLE`: 103 +- `BS_MACE`: 102 +- `BS_AXE`: 101 +- `BS_TWOHANDSWORD`: 100 +- `BS_SWORD`: 99 +- `BS_DAGGER`: 98 +- `BS_ORIDEOCON`: 97 +- `BS_ENCHANTEDSTONE`: 96 +- `BS_STEEL`: 95 +- `BS_IRON`: 94 +- `WZ_ESTIMATION`: 93 +- `WZ_QUAGMIRE`: 92 +- `WZ_HEAVENDRIVE`: 91 +- `WZ_EARTHSPIKE`: 90 +- `WZ_STORMGUST`: 89 +- `WZ_FROSTNOVA`: 88 +- `WZ_ICEWALL`: 87 +- `WZ_WATERBALL`: 86 +- `WZ_VERMILION`: 85 +- `WZ_JUPITEL`: 84 +- `WZ_METEOR`: 83 +- `WZ_SIGHTRASHER`: 81 +- `WZ_FIREPILLAR`: 80 +- `PR_MAGNUS`: 79 +- `PR_LEXAETERNA`: 78 +- `PR_TURNUNDEAD`: 77 +- `PR_LEXDIVINA`: 76 +- `PR_GLORIA`: 75 +- `PR_MAGNIFICAT`: 74 +- `PR_KYRIE`: 73 +- `PR_STRECOVERY`: 72 +- `PR_SLOWPOISON`: 71 +- `PR_SANCTUARY`: 70 +- `PR_BENEDICTIO`: 69 +- `PR_ASPERSIO`: 68 +- `PR_SUFFRAGIUM`: 67 +- `PR_IMPOSITIO`: 66 +- `PR_MACEMASTERY`: 65 +- `KN_CAVALIERMASTERY`: 64 +- `KN_RIDING`: 63 +- `KN_BOWLINGBASH`: 62 +- `KN_AUTOCOUNTER`: 61 +- `KN_TWOHANDQUICKEN`: 60 +- `KN_SPEARBOOMERANG`: 59 +- `KN_SPEARSTAB`: 58 +- `KN_BRANDISHSPEAR`: 57 +- `KN_PIERCE`: 56 +- `KN_SPEARMASTERY`: 55 +- `ALL_RESURRECTION`: 54 +- `TF_DETOXIFY`: 53 +- `TF_POISON`: 52 +- `TF_HIDING`: 51 +- `TF_STEAL`: 50 +- `TF_MISS`: 49 +- `TF_DOUBLE`: 48 +- `AC_SHOWER`: 47 +- `AC_DOUBLE`: 46 +- `AC_CONCENTRATION`: 45 +- `AC_VULTURE`: 44 +- `AC_OWL`: 43 +- `MC_MAMMONITE`: 42 +- `MC_VENDING`: 41 +- `MC_IDENTIFY`: 40 +- `MC_PUSHCART`: 39 +- `MC_OVERCHARGE`: 38 +- `MC_DISCOUNT`: 37 +- `MC_INCCARRY`: 36 +- `AL_CURE`: 35 +- `AL_BLESSING`: 34 +- `AL_ANGELUS`: 33 +- `AL_CRUCIS`: 32 +- `AL_HOLYWATER`: 31 +- `AL_DECAGI`: 30 +- `AL_INCAGI`: 29 +- `AL_HEAL`: 28 +- `AL_WARP`: 27 +- `AL_TELEPORT`: 26 +- `AL_PNEUMA`: 25 +- `AL_RUWACH`: 24 +- `AL_DEMONBANE`: 23 +- `AL_DP`: 22 +- `MG_THUNDERSTORM`: 21 +- `MG_LIGHTNINGBOLT`: 20 +- `MG_FIREBOLT`: 19 +- `MG_FIREWALL`: 18 +- `MG_FIREBALL`: 17 +- `MG_STONECURSE`: 16 +- `MG_FROSTDIVER`: 15 +- `MG_COLDBOLT`: 14 +- `MG_SOULSTRIKE`: 13 +- `MG_SAFETYWALL`: 12 +- `MG_NAPALMBEAT`: 11 +- `MG_SIGHT`: 10 +- `MG_SRECOVERY`: 9 +- `SM_ENDURE`: 8 +- `SM_MAGNUM`: 7 +- `SM_PROVOKE`: 6 +- `SM_BASH`: 5 +- `SM_RECOVERY`: 4 +- `SM_TWOHAND`: 3 +- `SM_SWORD`: 2 +- `NV_BASIC`: 1 - `SA_ELEMENTWIND`: 1019 -- `RK_ENCHANTBLADE`: 2001 -- `RK_SONICWAVE`: 2002 -- `RK_DEATHBOUND`: 2003 -- `RK_HUNDREDSPEAR`: 2004 -- `RK_WINDCUTTER`: 2005 -- `RK_IGNITIONBREAK`: 2006 -- `RK_DRAGONTRAINING`: 2007 -- `RK_DRAGONBREATH`: 2008 -- `RK_DRAGONHOWLING`: 2009 -- `RK_RUNEMASTERY`: 2010 -- `RK_MILLENNIUMSHIELD`: 2011 -- `RK_CRUSHSTRIKE`: 2012 -- `RK_REFRESH`: 2013 -- `RK_GIANTGROWTH`: 2014 -- `RK_STONEHARDSKIN`: 2015 -- `RK_VITALITYACTIVATION`: 2016 -- `RK_STORMBLAST`: 2017 -- `RK_FIGHTINGSPIRIT`: 2018 -- `RK_ABUNDANCE`: 2019 -- `RK_PHANTOMTHRUST`: 2020 -- `GC_VENOMIMPRESS`: 2021 -- `GC_CROSSIMPACT`: 2022 -- `GC_DARKILLUSION`: 2023 -- `GC_RESEARCHNEWPOISON`: 2024 -- `GC_CREATENEWPOISON`: 2025 -- `GC_ANTIDOTE`: 2026 -- `GC_POISONINGWEAPON`: 2027 -- `GC_WEAPONBLOCKING`: 2028 -- `GC_COUNTERSLASH`: 2029 -- `GC_WEAPONCRUSH`: 2030 -- `GC_VENOMPRESSURE`: 2031 -- `GC_POISONSMOKE`: 2032 -- `GC_CLOAKINGEXCEED`: 2033 -- `GC_PHANTOMMENACE`: 2034 -- `GC_HALLUCINATIONWALK`: 2035 -- `GC_ROLLINGCUTTER`: 2036 -- `GC_CROSSRIPPERSLASHER`: 2037 -- `AB_JUDEX`: 2038 -- `AB_ANCILLA`: 2039 -- `AB_ADORAMUS`: 2040 -- `AB_CLEMENTIA`: 2041 -- `AB_CANTO`: 2042 -- `AB_CHEAL`: 2043 -- `AB_EPICLESIS`: 2044 -- `AB_PRAEFATIO`: 2045 -- `AB_ORATIO`: 2046 -- `AB_LAUDAAGNUS`: 2047 -- `AB_LAUDARAMUS`: 2048 -- `AB_EUCHARISTICA`: 2049 -- `AB_RENOVATIO`: 2050 -- `AB_HIGHNESSHEAL`: 2051 -- `AB_CLEARANCE`: 2052 -- `AB_EXPIATIO`: 2053 -- `AB_DUPLELIGHT`: 2054 -- `AB_DUPLELIGHT_MELEE`: 2055 -- `AB_DUPLELIGHT_MAGIC`: 2056 +- `SA_ELEMENTFIRE`: 1018 +- `SA_ELEMENTGROUND`: 1017 +- `MO_BALKYOUNG`: 1016 +- `MO_KITRANSLATION`: 1015 +- `PR_REDEMPTIO`: 1014 +- `BS_GREED`: 1013 +- `BS_UNFAIRLYTRICK`: 1012 +- `DC_WINKCHARM`: 1011 +- `BA_PANGVOICE`: 1010 +- `HT_PHANTASMIC`: 1009 +- `SA_ELEMENTWATER`: 1008 +- `SA_CREATECON`: 1007 +- `WZ_SIGHTBLASTER`: 1006 +- `RG_CLOSECONFINE`: 1005 +- `AS_VENOMKNIFE`: 1004 +- `AS_SONICACCEL`: 1003 +- `CR_SHRINK`: 1002 +- `KN_CHARGEATK`: 1001 - `AB_SILENTIUM`: 2057 -- `WL_WHITEIMPRISON`: 2201 -- `WL_SOULEXPANSION`: 2202 -- `WL_FROSTMISTY`: 2203 -- `WL_JACKFROST`: 2204 -- `WL_MARSHOFABYSS`: 2205 -- `WL_RECOGNIZEDSPELL`: 2206 -- `WL_SIENNAEXECRATE`: 2207 -- `WL_RADIUS`: 2208 -- `WL_STASIS`: 2209 -- `WL_DRAINLIFE`: 2210 -- `WL_CRIMSONROCK`: 2211 -- `WL_HELLINFERNO`: 2212 -- `WL_COMET`: 2213 -- `WL_CHAINLIGHTNING`: 2214 -- `WL_CHAINLIGHTNING_ATK`: 2215 -- `WL_EARTHSTRAIN`: 2216 -- `WL_TETRAVORTEX`: 2217 -- `WL_TETRAVORTEX_FIRE`: 2218 -- `WL_TETRAVORTEX_WATER`: 2219 -- `WL_TETRAVORTEX_WIND`: 2220 -- `WL_TETRAVORTEX_GROUND`: 2221 -- `WL_SUMMONFB`: 2222 -- `WL_SUMMONBL`: 2223 -- `WL_SUMMONWB`: 2224 -- `WL_SUMMON_ATK_FIRE`: 2225 -- `WL_SUMMON_ATK_WIND`: 2226 -- `WL_SUMMON_ATK_WATER`: 2227 -- `WL_SUMMON_ATK_GROUND`: 2228 -- `WL_SUMMONSTONE`: 2229 -- `WL_RELEASE`: 2230 -- `WL_READING_SB`: 2231 -- `WL_FREEZE_SP`: 2232 -- `RA_ARROWSTORM`: 2233 -- `RA_FEARBREEZE`: 2234 -- `RA_RANGERMAIN`: 2235 -- `RA_AIMEDBOLT`: 2236 -- `RA_DETONATOR`: 2237 -- `RA_ELECTRICSHOCKER`: 2238 -- `RA_CLUSTERBOMB`: 2239 -- `RA_WUGMASTERY`: 2240 -- `RA_WUGRIDER`: 2241 -- `RA_WUGDASH`: 2242 -- `RA_WUGSTRIKE`: 2243 -- `RA_WUGBITE`: 2244 -- `RA_TOOTHOFWUG`: 2245 -- `RA_SENSITIVEKEEN`: 2246 -- `RA_CAMOUFLAGE`: 2247 -- `RA_RESEARCHTRAP`: 2248 -- `RA_MAGENTATRAP`: 2249 -- `RA_COBALTTRAP`: 2250 -- `RA_MAIZETRAP`: 2251 -- `RA_VERDURETRAP`: 2252 -- `RA_FIRINGTRAP`: 2253 -- `RA_ICEBOUNDTRAP`: 2254 -- `NC_MADOLICENCE`: 2255 -- `NC_BOOSTKNUCKLE`: 2256 -- `NC_PILEBUNKER`: 2257 -- `NC_VULCANARM`: 2258 -- `NC_FLAMELAUNCHER`: 2259 -- `NC_COLDSLOWER`: 2260 -- `NC_ARMSCANNON`: 2261 -- `NC_ACCELERATION`: 2262 -- `NC_HOVERING`: 2263 -- `NC_F_SIDESLIDE`: 2264 -- `NC_B_SIDESLIDE`: 2265 -- `NC_MAINFRAME`: 2266 -- `NC_SELFDESTRUCTION`: 2267 -- `NC_SHAPESHIFT`: 2268 -- `NC_EMERGENCYCOOL`: 2269 -- `NC_INFRAREDSCAN`: 2270 -- `NC_ANALYZE`: 2271 -- `NC_MAGNETICFIELD`: 2272 -- `NC_NEUTRALBARRIER`: 2273 -- `NC_STEALTHFIELD`: 2274 -- `NC_REPAIR`: 2275 -- `NC_TRAININGAXE`: 2276 -- `NC_RESEARCHFE`: 2277 -- `NC_AXEBOOMERANG`: 2278 -- `NC_POWERSWING`: 2279 -- `NC_AXETORNADO`: 2280 -- `NC_SILVERSNIPER`: 2281 -- `NC_MAGICDECOY`: 2282 -- `NC_DISJOINT`: 2283 -- `SC_FATALMENACE`: 2284 -- `SC_REPRODUCE`: 2285 -- `SC_AUTOSHADOWSPELL`: 2286 -- `SC_SHADOWFORM`: 2287 -- `SC_TRIANGLESHOT`: 2288 -- `SC_BODYPAINT`: 2289 -- `SC_INVISIBILITY`: 2290 -- `SC_DEADLYINFECT`: 2291 -- `SC_ENERVATION`: 2292 -- `SC_GROOMY`: 2293 -- `SC_IGNORANCE`: 2294 -- `SC_LAZINESS`: 2295 -- `SC_UNLUCKY`: 2296 -- `SC_WEAKNESS`: 2297 -- `SC_STRIPACCESSARY`: 2298 -- `SC_MANHOLE`: 2299 -- `SC_DIMENSIONDOOR`: 2300 -- `SC_CHAOSPANIC`: 2301 -- `SC_MAELSTROM`: 2302 -- `SC_BLOODYLUST`: 2303 +- `AB_DUPLELIGHT_MAGIC`: 2056 +- `AB_DUPLELIGHT_MELEE`: 2055 +- `AB_DUPLELIGHT`: 2054 +- `AB_EXPIATIO`: 2053 +- `AB_CLEARANCE`: 2052 +- `AB_HIGHNESSHEAL`: 2051 +- `AB_RENOVATIO`: 2050 +- `AB_EUCHARISTICA`: 2049 +- `AB_LAUDARAMUS`: 2048 +- `AB_LAUDAAGNUS`: 2047 +- `AB_ORATIO`: 2046 +- `AB_PRAEFATIO`: 2045 +- `AB_EPICLESIS`: 2044 +- `AB_CHEAL`: 2043 +- `AB_CANTO`: 2042 +- `AB_CLEMENTIA`: 2041 +- `AB_ADORAMUS`: 2040 +- `AB_ANCILLA`: 2039 +- `AB_JUDEX`: 2038 +- `GC_CROSSRIPPERSLASHER`: 2037 +- `GC_ROLLINGCUTTER`: 2036 +- `GC_HALLUCINATIONWALK`: 2035 +- `GC_PHANTOMMENACE`: 2034 +- `GC_CLOAKINGEXCEED`: 2033 +- `GC_POISONSMOKE`: 2032 +- `GC_VENOMPRESSURE`: 2031 +- `GC_WEAPONCRUSH`: 2030 +- `GC_COUNTERSLASH`: 2029 +- `GC_WEAPONBLOCKING`: 2028 +- `GC_POISONINGWEAPON`: 2027 +- `GC_ANTIDOTE`: 2026 +- `GC_CREATENEWPOISON`: 2025 +- `GC_RESEARCHNEWPOISON`: 2024 +- `GC_DARKILLUSION`: 2023 +- `GC_CROSSIMPACT`: 2022 +- `GC_VENOMIMPRESS`: 2021 +- `RK_PHANTOMTHRUST`: 2020 +- `RK_ABUNDANCE`: 2019 +- `RK_FIGHTINGSPIRIT`: 2018 +- `RK_STORMBLAST`: 2017 +- `RK_VITALITYACTIVATION`: 2016 +- `RK_STONEHARDSKIN`: 2015 +- `RK_GIANTGROWTH`: 2014 +- `RK_REFRESH`: 2013 +- `RK_CRUSHSTRIKE`: 2012 +- `RK_MILLENNIUMSHIELD`: 2011 +- `RK_RUNEMASTERY`: 2010 +- `RK_DRAGONHOWLING`: 2009 +- `RK_DRAGONBREATH`: 2008 +- `RK_DRAGONTRAINING`: 2007 +- `RK_IGNITIONBREAK`: 2006 +- `RK_WINDCUTTER`: 2005 +- `RK_HUNDREDSPEAR`: 2004 +- `RK_DEATHBOUND`: 2003 +- `RK_SONICWAVE`: 2002 +- `RK_ENCHANTBLADE`: 2001 - `SC_FEINTBOMB`: 2304 -- `LG_CANNONSPEAR`: 2307 -- `LG_BANISHINGPOINT`: 2308 -- `LG_TRAMPLE`: 2309 -- `LG_SHIELDPRESS`: 2310 -- `LG_REFLECTDAMAGE`: 2311 -- `LG_PINPOINTATTACK`: 2312 -- `LG_FORCEOFVANGUARD`: 2313 -- `LG_RAGEBURST`: 2314 -- `LG_SHIELDSPELL`: 2315 -- `LG_EXEEDBREAK`: 2316 -- `LG_OVERBRAND`: 2317 -- `LG_PRESTIGE`: 2318 -- `LG_BANDING`: 2319 -- `LG_MOONSLASHER`: 2320 -- `LG_RAYOFGENESIS`: 2321 -- `LG_PIETY`: 2322 -- `LG_EARTHDRIVE`: 2323 -- `LG_HESPERUSLIT`: 2324 -- `LG_INSPIRATION`: 2325 -- `SR_DRAGONCOMBO`: 2326 -- `SR_SKYNETBLOW`: 2327 -- `SR_EARTHSHAKER`: 2328 -- `SR_FALLENEMPIRE`: 2329 -- `SR_TIGERCANNON`: 2330 -- `SR_HELLGATE`: 2331 -- `SR_RAMPAGEBLASTER`: 2332 -- `SR_CRESCENTELBOW`: 2333 -- `SR_CURSEDCIRCLE`: 2334 -- `SR_LIGHTNINGWALK`: 2335 -- `SR_KNUCKLEARROW`: 2336 -- `SR_WINDMILL`: 2337 -- `SR_RAISINGDRAGON`: 2338 -- `SR_GENTLETOUCH`: 2339 -- `SR_ASSIMILATEPOWER`: 2340 -- `SR_POWERVELOCITY`: 2341 -- `SR_CRESCENTELBOW_AUTOSPELL`: 2342 -- `SR_GATEOFHELL`: 2343 -- `SR_GENTLETOUCH_QUIET`: 2344 -- `SR_GENTLETOUCH_CURE`: 2345 -- `SR_GENTLETOUCH_ENERGYGAIN`: 2346 -- `SR_GENTLETOUCH_CHANGE`: 2347 +- `SC_BLOODYLUST`: 2303 +- `SC_MAELSTROM`: 2302 +- `SC_CHAOSPANIC`: 2301 +- `SC_DIMENSIONDOOR`: 2300 +- `SC_MANHOLE`: 2299 +- `SC_STRIPACCESSARY`: 2298 +- `SC_WEAKNESS`: 2297 +- `SC_UNLUCKY`: 2296 +- `SC_LAZINESS`: 2295 +- `SC_IGNORANCE`: 2294 +- `SC_GROOMY`: 2293 +- `SC_ENERVATION`: 2292 +- `SC_DEADLYINFECT`: 2291 +- `SC_INVISIBILITY`: 2290 +- `SC_BODYPAINT`: 2289 +- `SC_TRIANGLESHOT`: 2288 +- `SC_SHADOWFORM`: 2287 +- `SC_AUTOSHADOWSPELL`: 2286 +- `SC_REPRODUCE`: 2285 +- `SC_FATALMENACE`: 2284 +- `NC_DISJOINT`: 2283 +- `NC_MAGICDECOY`: 2282 +- `NC_SILVERSNIPER`: 2281 +- `NC_AXETORNADO`: 2280 +- `NC_POWERSWING`: 2279 +- `NC_AXEBOOMERANG`: 2278 +- `NC_RESEARCHFE`: 2277 +- `NC_TRAININGAXE`: 2276 +- `NC_REPAIR`: 2275 +- `NC_STEALTHFIELD`: 2274 +- `NC_NEUTRALBARRIER`: 2273 +- `NC_MAGNETICFIELD`: 2272 +- `NC_ANALYZE`: 2271 +- `NC_INFRAREDSCAN`: 2270 +- `NC_EMERGENCYCOOL`: 2269 +- `NC_SHAPESHIFT`: 2268 +- `NC_SELFDESTRUCTION`: 2267 +- `NC_MAINFRAME`: 2266 +- `NC_B_SIDESLIDE`: 2265 +- `NC_F_SIDESLIDE`: 2264 +- `NC_HOVERING`: 2263 +- `NC_ACCELERATION`: 2262 +- `NC_ARMSCANNON`: 2261 +- `NC_COLDSLOWER`: 2260 +- `NC_FLAMELAUNCHER`: 2259 +- `NC_VULCANARM`: 2258 +- `NC_PILEBUNKER`: 2257 +- `NC_BOOSTKNUCKLE`: 2256 +- `NC_MADOLICENCE`: 2255 +- `RA_ICEBOUNDTRAP`: 2254 +- `RA_FIRINGTRAP`: 2253 +- `RA_VERDURETRAP`: 2252 +- `RA_MAIZETRAP`: 2251 +- `RA_COBALTTRAP`: 2250 +- `RA_MAGENTATRAP`: 2249 +- `RA_RESEARCHTRAP`: 2248 +- `RA_CAMOUFLAGE`: 2247 +- `RA_SENSITIVEKEEN`: 2246 +- `RA_TOOTHOFWUG`: 2245 +- `RA_WUGBITE`: 2244 +- `RA_WUGSTRIKE`: 2243 +- `RA_WUGDASH`: 2242 +- `RA_WUGRIDER`: 2241 +- `RA_WUGMASTERY`: 2240 +- `RA_CLUSTERBOMB`: 2239 +- `RA_ELECTRICSHOCKER`: 2238 +- `RA_DETONATOR`: 2237 +- `RA_AIMEDBOLT`: 2236 +- `RA_RANGERMAIN`: 2235 +- `RA_FEARBREEZE`: 2234 +- `RA_ARROWSTORM`: 2233 +- `WL_FREEZE_SP`: 2232 +- `WL_READING_SB`: 2231 +- `WL_RELEASE`: 2230 +- `WL_SUMMONSTONE`: 2229 +- `WL_SUMMON_ATK_GROUND`: 2228 +- `WL_SUMMON_ATK_WATER`: 2227 +- `WL_SUMMON_ATK_WIND`: 2226 +- `WL_SUMMON_ATK_FIRE`: 2225 +- `WL_SUMMONWB`: 2224 +- `WL_SUMMONBL`: 2223 +- `WL_SUMMONFB`: 2222 +- `WL_TETRAVORTEX_GROUND`: 2221 +- `WL_TETRAVORTEX_WIND`: 2220 +- `WL_TETRAVORTEX_WATER`: 2219 +- `WL_TETRAVORTEX_FIRE`: 2218 +- `WL_TETRAVORTEX`: 2217 +- `WL_EARTHSTRAIN`: 2216 +- `WL_CHAINLIGHTNING_ATK`: 2215 +- `WL_CHAINLIGHTNING`: 2214 +- `WL_COMET`: 2213 +- `WL_HELLINFERNO`: 2212 +- `WL_CRIMSONROCK`: 2211 +- `WL_DRAINLIFE`: 2210 +- `WL_STASIS`: 2209 +- `WL_RADIUS`: 2208 +- `WL_SIENNAEXECRATE`: 2207 +- `WL_RECOGNIZEDSPELL`: 2206 +- `WL_MARSHOFABYSS`: 2205 +- `WL_JACKFROST`: 2204 +- `WL_FROSTMISTY`: 2203 +- `WL_SOULEXPANSION`: 2202 +- `WL_WHITEIMPRISON`: 2201 - `SR_GENTLETOUCH_REVITALIZE`: 2348 -- `WA_SWING_DANCE`: 2350 -- `WA_SYMPHONY_OF_LOVER`: 2351 +- `SR_GENTLETOUCH_CHANGE`: 2347 +- `SR_GENTLETOUCH_ENERGYGAIN`: 2346 +- `SR_GENTLETOUCH_CURE`: 2345 +- `SR_GENTLETOUCH_QUIET`: 2344 +- `SR_GATEOFHELL`: 2343 +- `SR_CRESCENTELBOW_AUTOSPELL`: 2342 +- `SR_POWERVELOCITY`: 2341 +- `SR_ASSIMILATEPOWER`: 2340 +- `SR_GENTLETOUCH`: 2339 +- `SR_RAISINGDRAGON`: 2338 +- `SR_WINDMILL`: 2337 +- `SR_KNUCKLEARROW`: 2336 +- `SR_LIGHTNINGWALK`: 2335 +- `SR_CURSEDCIRCLE`: 2334 +- `SR_CRESCENTELBOW`: 2333 +- `SR_RAMPAGEBLASTER`: 2332 +- `SR_HELLGATE`: 2331 +- `SR_TIGERCANNON`: 2330 +- `SR_FALLENEMPIRE`: 2329 +- `SR_EARTHSHAKER`: 2328 +- `SR_SKYNETBLOW`: 2327 +- `SR_DRAGONCOMBO`: 2326 +- `LG_INSPIRATION`: 2325 +- `LG_HESPERUSLIT`: 2324 +- `LG_EARTHDRIVE`: 2323 +- `LG_PIETY`: 2322 +- `LG_RAYOFGENESIS`: 2321 +- `LG_MOONSLASHER`: 2320 +- `LG_BANDING`: 2319 +- `LG_PRESTIGE`: 2318 +- `LG_OVERBRAND`: 2317 +- `LG_EXEEDBREAK`: 2316 +- `LG_SHIELDSPELL`: 2315 +- `LG_RAGEBURST`: 2314 +- `LG_FORCEOFVANGUARD`: 2313 +- `LG_PINPOINTATTACK`: 2312 +- `LG_REFLECTDAMAGE`: 2311 +- `LG_SHIELDPRESS`: 2310 +- `LG_TRAMPLE`: 2309 +- `LG_BANISHINGPOINT`: 2308 +- `LG_CANNONSPEAR`: 2307 - `WA_MOONLIT_SERENADE`: 2352 -- `MI_RUSH_WINDMILL`: 2381 -- `MI_ECHOSONG`: 2382 +- `WA_SYMPHONY_OF_LOVER`: 2351 +- `WA_SWING_DANCE`: 2350 - `MI_HARMONIZE`: 2383 -- `WM_LESSON`: 2412 -- `WM_METALICSOUND`: 2413 -- `WM_REVERBERATION`: 2414 -- `WM_REVERBERATION_MELEE`: 2415 -- `WM_REVERBERATION_MAGIC`: 2416 -- `WM_DOMINION_IMPULSE`: 2417 -- `WM_SEVERE_RAINSTORM`: 2418 -- `WM_POEMOFNETHERWORLD`: 2419 -- `WM_VOICEOFSIREN`: 2420 -- `WM_DEADHILLHERE`: 2421 -- `WM_LULLABY_DEEPSLEEP`: 2422 -- `WM_SIRCLEOFNATURE`: 2423 -- `WM_RANDOMIZESPELL`: 2424 -- `WM_GLOOMYDAY`: 2425 -- `WM_GREAT_ECHO`: 2426 -- `WM_SONG_OF_MANA`: 2427 -- `WM_DANCE_WITH_WUG`: 2428 -- `WM_SOUND_OF_DESTRUCTION`: 2429 -- `WM_SATURDAY_NIGHT_FEVER`: 2430 -- `WM_LERADS_DEW`: 2431 -- `WM_MELODYOFSINK`: 2432 -- `WM_BEYOND_OF_WARCRY`: 2433 +- `MI_ECHOSONG`: 2382 +- `MI_RUSH_WINDMILL`: 2381 - `WM_UNLIMITED_HUMMING_VOICE`: 2434 -- `SO_FIREWALK`: 2443 -- `SO_ELECTRICWALK`: 2444 -- `SO_SPELLFIST`: 2445 -- `SO_EARTHGRAVE`: 2446 -- `SO_DIAMONDDUST`: 2447 -- `SO_POISON_BUSTER`: 2448 -- `SO_PSYCHIC_WAVE`: 2449 -- `SO_CLOUD_KILL`: 2450 -- `SO_STRIKING`: 2451 -- `SO_WARMER`: 2452 -- `SO_VACUUM_EXTREME`: 2453 -- `SO_VARETYR_SPEAR`: 2454 -- `SO_ARRULLO`: 2455 -- `SO_EL_CONTROL`: 2456 -- `SO_SUMMON_AGNI`: 2457 -- `SO_SUMMON_AQUA`: 2458 -- `SO_SUMMON_VENTUS`: 2459 -- `SO_SUMMON_TERA`: 2460 -- `SO_EL_ACTION`: 2461 -- `SO_EL_ANALYSIS`: 2462 -- `SO_EL_SYMPATHY`: 2463 -- `SO_EL_CURE`: 2464 -- `SO_FIRE_INSIGNIA`: 2465 -- `SO_WATER_INSIGNIA`: 2466 -- `SO_WIND_INSIGNIA`: 2467 +- `WM_BEYOND_OF_WARCRY`: 2433 +- `WM_MELODYOFSINK`: 2432 +- `WM_LERADS_DEW`: 2431 +- `WM_SATURDAY_NIGHT_FEVER`: 2430 +- `WM_SOUND_OF_DESTRUCTION`: 2429 +- `WM_DANCE_WITH_WUG`: 2428 +- `WM_SONG_OF_MANA`: 2427 +- `WM_GREAT_ECHO`: 2426 +- `WM_GLOOMYDAY`: 2425 +- `WM_RANDOMIZESPELL`: 2424 +- `WM_SIRCLEOFNATURE`: 2423 +- `WM_LULLABY_DEEPSLEEP`: 2422 +- `WM_DEADHILLHERE`: 2421 +- `WM_VOICEOFSIREN`: 2420 +- `WM_POEMOFNETHERWORLD`: 2419 +- `WM_SEVERE_RAINSTORM`: 2418 +- `WM_DOMINION_IMPULSE`: 2417 +- `WM_REVERBERATION_MAGIC`: 2416 +- `WM_REVERBERATION_MELEE`: 2415 +- `WM_REVERBERATION`: 2414 +- `WM_METALICSOUND`: 2413 +- `WM_LESSON`: 2412 - `SO_EARTH_INSIGNIA`: 2468 -- `GN_TRAINING_SWORD`: 2474 -- `GN_REMODELING_CART`: 2475 -- `GN_CART_TORNADO`: 2476 -- `GN_CARTCANNON`: 2477 -- `GN_CARTBOOST`: 2478 -- `GN_THORNS_TRAP`: 2479 -- `GN_BLOOD_SUCKER`: 2480 -- `GN_SPORE_EXPLOSION`: 2481 -- `GN_WALLOFTHORN`: 2482 -- `GN_CRAZYWEED`: 2483 -- `GN_CRAZYWEED_ATK`: 2484 -- `GN_DEMONIC_FIRE`: 2485 -- `GN_FIRE_EXPANSION`: 2486 -- `GN_FIRE_EXPANSION_SMOKE_POWDER`: 2487 -- `GN_FIRE_EXPANSION_TEAR_GAS`: 2488 -- `GN_FIRE_EXPANSION_ACID`: 2489 -- `GN_HELLS_PLANT`: 2490 -- `GN_HELLS_PLANT_ATK`: 2491 -- `GN_MANDRAGORA`: 2492 -- `GN_SLINGITEM`: 2493 -- `GN_CHANGEMATERIAL`: 2494 -- `GN_MIX_COOKING`: 2495 -- `GN_MAKEBOMB`: 2496 -- `GN_S_PHARMACY`: 2497 +- `SO_WIND_INSIGNIA`: 2467 +- `SO_WATER_INSIGNIA`: 2466 +- `SO_FIRE_INSIGNIA`: 2465 +- `SO_EL_CURE`: 2464 +- `SO_EL_SYMPATHY`: 2463 +- `SO_EL_ANALYSIS`: 2462 +- `SO_EL_ACTION`: 2461 +- `SO_SUMMON_TERA`: 2460 +- `SO_SUMMON_VENTUS`: 2459 +- `SO_SUMMON_AQUA`: 2458 +- `SO_SUMMON_AGNI`: 2457 +- `SO_EL_CONTROL`: 2456 +- `SO_ARRULLO`: 2455 +- `SO_VARETYR_SPEAR`: 2454 +- `SO_VACUUM_EXTREME`: 2453 +- `SO_WARMER`: 2452 +- `SO_STRIKING`: 2451 +- `SO_CLOUD_KILL`: 2450 +- `SO_PSYCHIC_WAVE`: 2449 +- `SO_POISON_BUSTER`: 2448 +- `SO_DIAMONDDUST`: 2447 +- `SO_EARTHGRAVE`: 2446 +- `SO_SPELLFIST`: 2445 +- `SO_ELECTRICWALK`: 2444 +- `SO_FIREWALK`: 2443 - `GN_SLINGITEM_RANGEMELEEATK`: 2498 -- `AB_SECRAMENT`: 2515 -- `WM_SEVERE_RAINSTORM_MELEE`: 2516 -- `SR_HOWLINGOFLION`: 2517 -- `SR_RIDEINLIGHTNING`: 2518 +- `GN_S_PHARMACY`: 2497 +- `GN_MAKEBOMB`: 2496 +- `GN_MIX_COOKING`: 2495 +- `GN_CHANGEMATERIAL`: 2494 +- `GN_SLINGITEM`: 2493 +- `GN_MANDRAGORA`: 2492 +- `GN_HELLS_PLANT_ATK`: 2491 +- `GN_HELLS_PLANT`: 2490 +- `GN_FIRE_EXPANSION_ACID`: 2489 +- `GN_FIRE_EXPANSION_TEAR_GAS`: 2488 +- `GN_FIRE_EXPANSION_SMOKE_POWDER`: 2487 +- `GN_FIRE_EXPANSION`: 2486 +- `GN_DEMONIC_FIRE`: 2485 +- `GN_CRAZYWEED_ATK`: 2484 +- `GN_CRAZYWEED`: 2483 +- `GN_WALLOFTHORN`: 2482 +- `GN_SPORE_EXPLOSION`: 2481 +- `GN_BLOOD_SUCKER`: 2480 +- `GN_THORNS_TRAP`: 2479 +- `GN_CARTBOOST`: 2478 +- `GN_CARTCANNON`: 2477 +- `GN_CART_TORNADO`: 2476 +- `GN_REMODELING_CART`: 2475 +- `GN_TRAINING_SWORD`: 2474 - `LG_OVERBRAND_BRANDISH`: 2519 -- `RETURN_TO_ELDICASTES`: 2534 -- `ALL_BUYING_STORE`: 2535 -- `ALL_GUARDIAN_RECALL`: 2536 -- `ALL_ODINS_POWER`: 2537 +- `SR_RIDEINLIGHTNING`: 2518 +- `SR_HOWLINGOFLION`: 2517 +- `WM_SEVERE_RAINSTORM_MELEE`: 2516 +- `AB_SECRAMENT`: 2515 - `MC_CARTDECORATE`: 2544 -- `KO_YAMIKUMO`: 3001 -- `KO_RIGHT`: 3002 -- `KO_LEFT`: 3003 -- `KO_JYUMONJIKIRI`: 3004 -- `KO_SETSUDAN`: 3005 -- `KO_BAKURETSU`: 3006 -- `KO_HAPPOKUNAI`: 3007 -- `KO_MUCHANAGE`: 3008 -- `KO_HUUMARANKA`: 3009 -- `KO_MAKIBISHI`: 3010 -- `KO_MEIKYOUSISUI`: 3011 -- `KO_ZANZOU`: 3012 -- `KO_KYOUGAKU`: 3013 -- `KO_JYUSATSU`: 3014 -- `KO_KAHU_ENTEN`: 3015 -- `KO_HYOUHU_HUBUKI`: 3016 -- `KO_KAZEHU_SEIRAN`: 3017 -- `KO_DOHU_KOUKAI`: 3018 -- `KO_KAIHOU`: 3019 -- `KO_ZENKAI`: 3020 -- `KO_GENWAKU`: 3021 -- `KO_IZAYOI`: 3022 -- `KG_KAGEHUMI`: 3023 -- `KG_KYOMU`: 3024 -- `KG_KAGEMUSYA`: 3025 -- `OB_ZANGETSU`: 3026 -- `OB_OBOROGENSOU`: 3027 -- `OB_OBOROGENSOU_TRANSITION_ATK`: 3028 +- `ALL_ODINS_POWER`: 2537 +- `ALL_GUARDIAN_RECALL`: 2536 +- `ALL_BUYING_STORE`: 2535 +- `RETURN_TO_ELDICASTES`: 2534 +- `RL_GLITTERING_GREED_ATK`: 2574 +- `RL_B_FLICKER_ATK`: 2573 +- `RL_R_TRIP_PLUSATK`: 2572 +- `RL_HAMMER_OF_GOD`: 2571 +- `RL_SLUGSHOT`: 2570 +- `RL_AM_BLAST`: 2569 +- `RL_HEAT_BARREL`: 2568 +- `RL_FIRE_RAIN`: 2567 +- `RL_D_TAIL`: 2566 +- `RL_R_TRIP`: 2565 +- `RL_FALLEN_ANGEL`: 2564 +- `RL_P_ALTER`: 2563 +- `RL_H_MINE`: 2562 +- `RL_FIREDANCE`: 2561 +- `RL_C_MARKER`: 2560 +- `RL_QD_SHOT`: 2559 +- `RL_E_CHAIN`: 2558 +- `RL_S_STORM`: 2557 +- `RL_FLICKER`: 2556 +- `RL_B_TRAP`: 2555 +- `RL_BANISHING_BUSTER`: 2554 +- `RL_MASS_SPIRAL`: 2553 +- `RL_RICHS_COIN`: 2552 +- `RL_GLITTERING_GREED`: 2551 - `OB_AKAITSUKI`: 3029 -- `ECL_SNOWFLIP`: 3031 -- `ECL_PEONYMAMY`: 3032 -- `ECL_SADAGUI`: 3033 -- `ECL_SEQUOIADUST`: 3034 +- `OB_OBOROGENSOU_TRANSITION_ATK`: 3028 +- `OB_OBOROGENSOU`: 3027 +- `OB_ZANGETSU`: 3026 +- `KG_KAGEMUSYA`: 3025 +- `KG_KYOMU`: 3024 +- `KG_KAGEHUMI`: 3023 +- `KO_IZAYOI`: 3022 +- `KO_GENWAKU`: 3021 +- `KO_ZENKAI`: 3020 +- `KO_KAIHOU`: 3019 +- `KO_DOHU_KOUKAI`: 3018 +- `KO_KAZEHU_SEIRAN`: 3017 +- `KO_HYOUHU_HUBUKI`: 3016 +- `KO_KAHU_ENTEN`: 3015 +- `KO_JYUSATSU`: 3014 +- `KO_KYOUGAKU`: 3013 +- `KO_ZANZOU`: 3012 +- `KO_MEIKYOUSISUI`: 3011 +- `KO_MAKIBISHI`: 3010 +- `KO_HUUMARANKA`: 3009 +- `KO_MUCHANAGE`: 3008 +- `KO_HAPPOKUNAI`: 3007 +- `KO_BAKURETSU`: 3006 +- `KO_SETSUDAN`: 3005 +- `KO_JYUMONJIKIRI`: 3004 +- `KO_LEFT`: 3003 +- `KO_RIGHT`: 3002 +- `KO_YAMIKUMO`: 3001 - `ECLAGE_RECALL`: 3035 -- `GC_DARKCROW`: 5001 -- `RA_UNLIMIT`: 5002 -- `GN_ILLUSIONDOPING`: 5003 -- `RK_DRAGONBREATH_WATER`: 5004 -- `RK_LUXANIMA`: 5005 -- `NC_MAGMA_ERUPTION`: 5006 -- `WM_FRIGG_SONG`: 5007 -- `SO_ELEMENTAL_SHIELD`: 5008 -- `SR_FLASHCOMBO`: 5009 -- `SC_ESCAPE`: 5010 -- `AB_OFFERTORIUM`: 5011 -- `WL_TELEKINESIS_INTENSE`: 5012 -- `LG_KINGS_GRACE`: 5013 +- `ECL_SEQUOIADUST`: 3034 +- `ECL_SADAGUI`: 3033 +- `ECL_PEONYMAMY`: 3032 +- `ECL_SNOWFLIP`: 3031 - `ALL_FULL_THROTTLE`: 5014 -- `SU_BASIC_SKILL`: 5018 -- `SU_BITE`: 5019 -- `SU_HIDE`: 5020 -- `SU_SCRATCH`: 5021 -- `SU_STOOP`: 5022 -- `SU_LOPE`: 5023 -- `SU_SPRITEMABLE`: 5024 -- `SU_POWEROFLAND`: 5025 -- `SU_SV_STEMSPEAR`: 5026 -- `SU_CN_POWDERING`: 5027 -- `SU_CN_METEOR`: 5028 -- `SU_SV_ROOTTWIST`: 5029 -- `SU_SV_ROOTTWIST_ATK`: 5030 -- `SU_POWEROFLIFE`: 5031 -- `SU_SCAROFTAROU`: 5032 -- `SU_PICKYPECK`: 5033 -- `SU_PICKYPECK_DOUBLE_ATK`: 5034 -- `SU_ARCLOUSEDASH`: 5035 -- `SU_LUNATICCARROTBEAT`: 5036 -- `SU_POWEROFSEA`: 5037 -- `SU_TUNABELLY`: 5038 -- `SU_TUNAPARTY`: 5039 -- `SU_BUNCHOFSHRIMP`: 5040 -- `SU_FRESHSHRIMP`: 5041 -- `SU_CN_METEOR_ATK`: 5042 +- `LG_KINGS_GRACE`: 5013 +- `WL_TELEKINESIS_INTENSE`: 5012 +- `AB_OFFERTORIUM`: 5011 +- `SC_ESCAPE`: 5010 +- `SR_FLASHCOMBO`: 5009 +- `SO_ELEMENTAL_SHIELD`: 5008 +- `WM_FRIGG_SONG`: 5007 +- `NC_MAGMA_ERUPTION`: 5006 +- `RK_LUXANIMA`: 5005 +- `RK_DRAGONBREATH_WATER`: 5004 +- `GN_ILLUSIONDOPING`: 5003 +- `RA_UNLIMIT`: 5002 +- `GC_DARKCROW`: 5001 - `SU_LUNATICCARROTBEAT2`: 5043 +- `SU_CN_METEOR_ATK`: 5042 +- `SU_FRESHSHRIMP`: 5041 +- `SU_BUNCHOFSHRIMP`: 5040 +- `SU_TUNAPARTY`: 5039 +- `SU_TUNABELLY`: 5038 +- `SU_POWEROFSEA`: 5037 +- `SU_LUNATICCARROTBEAT`: 5036 +- `SU_ARCLOUSEDASH`: 5035 +- `SU_PICKYPECK_DOUBLE_ATK`: 5034 +- `SU_PICKYPECK`: 5033 +- `SU_SCAROFTAROU`: 5032 +- `SU_POWEROFLIFE`: 5031 +- `SU_SV_ROOTTWIST_ATK`: 5030 +- `SU_SV_ROOTTWIST`: 5029 +- `SU_CN_METEOR`: 5028 +- `SU_CN_POWDERING`: 5027 +- `SU_SV_STEMSPEAR`: 5026 +- `SU_POWEROFLAND`: 5025 +- `SU_SPRITEMABLE`: 5024 +- `SU_LOPE`: 5023 +- `SU_STOOP`: 5022 +- `SU_SCRATCH`: 5021 +- `SU_HIDE`: 5020 +- `SU_BITE`: 5019 +- `SU_BASIC_SKILL`: 5018 +- `MH_VOLCANIC_ASH`: 8043 +- `MH_PYROCLASTIC`: 8042 +- `MH_LAVA_SLIDE`: 8041 +- `MH_GRANITIC_ARMOR`: 8040 +- `MH_MAGMA_FLOW`: 8039 +- `MH_EQC`: 8038 +- `MH_CBC`: 8037 +- `MH_TINDER_BREAKER`: 8036 +- `MH_ANGRIFFS_MODUS`: 8035 +- `MH_HEILIGE_STANGE`: 8034 +- `MH_STEINWAND`: 8033 +- `MH_GOLDENE_FERSE`: 8032 +- `MH_STAHL_HORN`: 8031 +- `MH_MIDNIGHT_FRENZY`: 8030 +- `MH_SILVERVEIN_RUSH`: 8029 +- `MH_SONIC_CRAW`: 8028 +- `MH_STYLE_CHANGE`: 8027 +- `MH_SILENT_BREEZE`: 8026 +- `MH_XENO_SLASHER`: 8025 +- `MH_ERASER_CUTTER`: 8024 +- `MH_OVERED_BOOST`: 8023 +- `MH_LIGHT_OF_REGENE`: 8022 +- `MH_PAIN_KILLER`: 8021 +- `MH_POISON_MIST`: 8020 +- `MH_NEEDLE_OF_PARALYZE`: 8019 +- `MH_SUMMON_LEGION`: 8018 +- `HVAN_EXPLOSION`: 8016 +- `HVAN_INSTRUCT`: 8015 +- `HVAN_CHAOTIC`: 8014 +- `HVAN_CAPRICE`: 8013 +- `HFLI_SBR44`: 8012 +- `HFLI_SPEED`: 8011 +- `HFLI_FLEET`: 8010 +- `HFLI_MOON`: 8009 +- `HAMI_BLOODLUST`: 8008 +- `HAMI_SKIN`: 8007 +- `HAMI_DEFENCE`: 8006 +- `HAMI_CASTLE`: 8005 +- `HLIF_CHANGE`: 8004 +- `HLIF_BRAIN`: 8003 +- `HLIF_AVOID`: 8002 +- `HLIF_HEAL`: 8001 +- `MER_INCAGI`: 8240 +- `MER_BLESSING`: 8239 +- `MER_KYRIE`: 8238 +- `MER_ESTIMATION`: 8237 +- `MER_LEXDIVINA`: 8236 +- `MER_SCAPEGOAT`: 8235 +- `MER_DECAGI`: 8234 +- `MER_AUTOBERSERK`: 8233 +- `MER_PROVOKE`: 8232 +- `MER_COMPRESS`: 8231 +- `MER_MENTALCURE`: 8230 +- `MER_RECUPERATE`: 8229 +- `MER_BENEDICTION`: 8228 +- `MER_TENDER`: 8227 +- `MER_REGAIN`: 8226 +- `MER_CRASH`: 8225 +- `MER_SIGHT`: 8224 +- `MER_QUICKEN`: 8223 +- `MER_MAGNIFICAT`: 8222 +- `ML_DEVOTION`: 8221 +- `ML_AUTOGUARD`: 8220 +- `ML_DEFENDER`: 8219 +- `ML_SPIRALPIERCE`: 8218 +- `ML_BRANDISH`: 8217 +- `ML_PIERCE`: 8216 +- `MA_SHARPSHOOTING`: 8215 +- `MA_CHARGEARROW`: 8214 +- `MA_REMOVETRAP`: 8213 +- `MA_FREEZINGTRAP`: 8212 +- `MA_SANDMAN`: 8211 +- `MA_LANDMINE`: 8210 +- `MA_SKIDTRAP`: 8209 +- `MA_SHOWER`: 8208 +- `MA_DOUBLE`: 8207 +- `MS_BERSERK`: 8206 +- `MS_REFLECTSHIELD`: 8205 +- `MS_PARRYING`: 8204 +- `MS_BOWLINGBASH`: 8203 +- `MS_MAGNUM`: 8202 +- `MS_BASH`: 8201 +- `EL_STONE_RAIN`: 8442 +- `EL_ROCK_CRUSHER_ATK`: 8441 +- `EL_ROCK_CRUSHER`: 8440 +- `EL_STONE_HAMMER`: 8439 +- `EL_TYPOON_MIS_ATK`: 8438 +- `EL_TYPOON_MIS`: 8437 +- `EL_HURRICANE_ATK`: 8436 +- `EL_HURRICANE`: 8435 +- `EL_WIND_SLASH`: 8434 +- `EL_TIDAL_WEAPON`: 8433 +- `EL_WATER_SCREW_ATK`: 8432 +- `EL_WATER_SCREW`: 8431 +- `EL_ICE_NEEDLE`: 8430 +- `EL_FIRE_WAVE_ATK`: 8429 +- `EL_FIRE_WAVE`: 8428 +- `EL_FIRE_BOMB_ATK`: 8427 +- `EL_FIRE_BOMB`: 8426 +- `EL_FIRE_ARROW`: 8425 +- `EL_UPHEAVAL`: 8424 +- `EL_CURSED_SOIL`: 8423 +- `EL_PETROLOGY`: 8422 +- `EL_WILD_STORM`: 8421 +- `EL_BLAST`: 8420 +- `EL_GUST`: 8419 +- `EL_CHILLY_AIR`: 8418 +- `EL_COOLER`: 8417 +- `EL_AQUAPLAY`: 8416 +- `EL_TROPIC`: 8415 +- `EL_HEATER`: 8414 +- `EL_PYROTECHNIC`: 8413 +- `EL_POWER_OF_GAIA`: 8412 +- `EL_STONE_SHIELD`: 8411 +- `EL_SOLID_SKIN`: 8410 +- `EL_ZEPHYR`: 8409 +- `EL_WIND_CURTAIN`: 8408 +- `EL_WIND_STEP`: 8407 +- `EL_WATER_BARRIER`: 8406 +- `EL_WATER_DROP`: 8405 +- `EL_WATER_SCREEN`: 8404 +- `EL_FIRE_MANTLE`: 8403 +- `EL_FIRE_CLOAK`: 8402 +- `EL_CIRCLE_OF_FIRE`: 8401 +- `GD_DEVELOPMENT`: 10014 +- `GD_EMERGENCYCALL`: 10013 +- `GD_RESTORE`: 10012 +- `GD_REGENERATION`: 10011 +- `GD_BATTLEORDER`: 10010 +- `GD_HAWKEYES`: 10009 +- `GD_SOULCOLD`: 10008 +- `GD_GLORYWOUNDS`: 10007 +- `GD_LEADERSHIP`: 10006 +- `GD_GLORYGUILD`: 10005 +- `GD_EXTENSION`: 10004 +- `GD_GUARDUP`: 10003 +- `GD_GUARDRESEARCH`: 10002 +- `GD_KAFRACONTRACT`: 10001 +- `GD_APPROVAL`: 10000 ## Mobs (db/re/mob_db.txt) @@ -7741,6 +7742,7 @@ - `DUMMY_150`: 2411 - `DUMMY_10_FIRE`: 2413 - `RUNAWAY_BOOK`: 2414 +- `G_L_SHECIL`: 2431 - `MG_ZOMBIE`: 2464 - `MG_WRAITH`: 2465 - `MG_GHOUL`: 2466 @@ -8137,6 +8139,8 @@ - `XM_CELINE_KIMI`: 2996 - `GRIM_REAPER_ANKOU`: 3029 - `TIMEHOLDER`: 3074 +- `J_REB_SHECIL1`: 3169 +- `J_REB_SHECIL2`: 3170 - `E1_FELOCK`: 3181 - `MM_SARAH`: 3190 - `ORGANIC_JAKK`: 3202 @@ -12679,6 +12683,8 @@ - `Bag_Of_Selling_Goods`: 6682 - `Cash_Hair_Coupon`: 6707 - `Lovely_Stick`: 6712 +- `Steel_Article`: 6746 +- `Steel_Article_`: 6747 - `Corrupted_Charm`: 6755 - `ORGANIC_PUMPKIN`: 6804 - `INORGANIC_PUMPKIN`: 6805 @@ -14953,6 +14959,8 @@ - `Upg_Revolver`: 13115 - `Novice_Revolver`: 13116 - `TE_Woe_Pistol`: 13117 +- `Tiny_Flame`: 13118 +- `Freedom_Flame`: 13119 - `H_FEATHER_H_FIRE`: 13120 - `ALTAIR_ARES`: 13122 - `ALTAIR_ARES_`: 13124 @@ -15035,6 +15043,11 @@ - `Poison_Sphere_`: 13225 - `Blind_Sphere_`: 13226 - `Freezing_Sphere_`: 13227 +- `Flare_Bullet`: 13228 +- `Lightning_Bullet`: 13229 +- `Ice_Bullet`: 13230 +- `Poison_Bullet`: 13231 +- `Blind_Bullet`: 13232 - `Shuriken`: 13250 - `Nimbus_Shuriken`: 13251 - `Flash_Shuriken`: 13252 @@ -18756,6 +18769,7 @@ - `S_Genesis_Weapon`: 24581 - `S_Genesis_Pendant`: 24582 - `S_Genesis_Earing`: 24583 +- `Slug_Bullet`: 25187 - `BrokenArrow`: 25258 - `Shining_Spore`: 25265 - `Dried_Leaf_Of_Ygg`: 25266 diff --git a/doc/mob_db.txt b/doc/mob_db.txt index 53d345255..0280ae9c4 100644 --- a/doc/mob_db.txt +++ b/doc/mob_db.txt @@ -82,7 +82,7 @@ mob_db: ( HeadTopId: top headgear id (int, defaults to 0) HeadMidId: middle headgear id (int, defaults to 0) HeadLowId: lower headgear id (int, defaults to 0) - HairStyleId: hair style id (int, defaults to 0) + HairStyleId: hair style id (int, defaults to 1) BodyStyleId: clothes id (int, defaults to 0) HairColorId: hair color id (int, defaults to 0) BodyColorId: clothes color id (int, defaults to 0) @@ -193,7 +193,7 @@ Element: Monster's element. Sets element type and level. Mode: Monster AI behaviour. If this block is omitted, monster doesn't react to anything. All the settings in this group are boolean values, Default value is false (mode not set) for any missing setting. - See /doc/sample/mob_db_mode_list.txt for more information about monsters Mode types. + See /doc/mob_db_mode_list.md for more information about monsters Mode types. MoveSpeed: Monster's speed. Sets speed (cells/sec). MoveSpeed is calculated to Hercules with this formula: 1000 / SPEED (CELLS/SEC) @@ -278,3 +278,4 @@ DamageTakenRate: ViewData: Overrides the default view data sent to the client with the given values for: Sprite, Weapon, Shield, Robe, HeadTop, HeadMid, HeadLow, HairStyle, BodyStyle, HairColor, BodyColor, Gender, Options + Note: HairStyleId will only default to 1, if the ViewData block is defined. diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 1d8ed786b..4004e5cd2 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -324,11 +324,13 @@ The types that a trader object can have are the following: and need to be refurbished) - NST_CUSTOM (3) Custom Shop (any currency, item/var/etca, check sample) - NST_BARTER (4) Barter Shop (each item with own item currency) +- NST_EXPANDED_BARTER (5) Expanded Barter Shop (buy items and spend zeny and items) Unless otherwise specified via *tradertype an trader object will be defined as NST_ZENY. Note: NST_MARKET is only available with PACKETVER 20131223 or newer. -Note: NST_BARTER is only available with PACKETVER 20181226 zero or newer. +Note: NST_BARTER is only available with PACKETVER 20190116 main or 20190116 RE or 20181226 zero or newer. +Note: NST_EXPANDED_BARTER is only available with PACKETVER 20190904 main or 20190904 RE or 20190828 zero or newer. See '12 - NPC Trader-Related Commands' and /doc/sample/npc_trader_sample.txt for more information regarding how to use this NPC type. @@ -1032,6 +1034,11 @@ will only execute once and will not execute if the map server reconnects to the char server later. Note that all those events will be executed upon scripts reloading. +OnNPCUnload: + +OnNPCUnload will be executed when a NPC is unloaded. +OnNPCUnload is called when @reloadscript, @reloadnpc, @unloadnpc or @unloadnpcfile is used. + OnAgitStart: OnAgitEnd: OnAgitInit: @@ -4378,7 +4385,7 @@ falcon and false if they don't. --------------------------------------- -*setmount({<flag>}) +*setmount({<flag>{, <type>}}) *checkmount() If <flag> is MOUNT_NONE this command will remove the mount from the @@ -4414,6 +4421,12 @@ The following flag values are accepted: Unlike 'setfalcon' and 'setcart' this will not work at all if they aren't of a class which can ride a mount. +For clients PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 +you can pass a <type> flag which specifies the madogear wanted. +The Available types: + MADO_ROBOT + MADO_SUITE + The accompanying function will return MOUNT_NONE if the invoking character is not on a mount, and a non-zero value (according to the above constants) if they are. @@ -7039,6 +7052,18 @@ NPCs talking while hidden then revealing... you can wonder around =P). --------------------------------------- +*cloakonnpc("<NPC object name>"{, <account_id>}) +*cloakoffnpc("<NPC object name>"{, <account_id>}) + +These commands are used to apply the cloaking effect on npcs +this is a visual effect only and it does NOT stop the player +from interacting with the npc. + +If an account_id is specified then the effect will only display to the given id, +otherwise it's displayed to the entire npc area. + +--------------------------------------- + *doevent("<NPC object name>::<event label>") This command will start a new execution thread in a specified NPC object @@ -10290,6 +10315,7 @@ when the optional NPC_Name param is used. *sellitem(<Item_ID>{, <price>{, <qty>}}) *sellitem(<Item_ID>, <qty>, <currency_id>, <currency_amount>) +*sellitem(<Item_ID>, <zeny>, <qty>{, <currency_id1>, <currency_amount1>{, <currency_refine1>}{, ...}}) adds (or modifies) <Item_ID> data to the shop, when <price> is not provided (or when it is -1) itemdb default is used. @@ -10298,7 +10324,37 @@ qty is only necessary for NST_MARKET trader types. when <Item_ID> is already in the shop, the previous data (price/qty), is overwritten with the new. -currency_id and currency_amount can be used only with shop type NST_BARTER +currency_id and currency_amount can be used only with shop type NST_BARTER. +zeny, currency_id1, currency_amount1, currency_refine1, can be used only with +shop type NST_EXPANDED_BARTER. + +--------------------------------------- + +*startsellitem(<Item_ID>, <zeny>, <qty>) + +Starts adding item into expanded barter shop (NST_EXPANDED_BARTER). +Before this command possible to use commands *sellitemcurrency. +Need PACKETVER 20190904 main or 20190904 RE or 20190828 zero or newer. + +Alternative way for add item to expanded barter shop is *sellitem with +currency parameters. + +--------------------------------------- + +*sellitemcurrency(<Item_ID>, <qty>{, <refine>}) + +adds <Item_ID> as currency into expanded barter shop (NST_EXPANDED_BARTER) +If <refine> set to -1, mean for any refine level. +if <refine> missing used value -1. + +Need PACKETVER 20190904 main or 20190904 RE or 20190828 zero or newer. + +--------------------------------------- + +*endsellitem() + +Complete adding item into expanded barter shop (NST_EXPANDED_BARTER). +Need PACKETVER 20190904 main or 20190904 RE or 20190828 zero or newer. --------------------------------------- @@ -10589,6 +10645,14 @@ returns progress on success and false on failure --------------------------------------- +*achievement_iscompleted(<ach_id>{, <account_id>}) + +Checks whether the attached player have completed all the given achievement objectives. + +returns true if yes and false if no. + +--------------------------------------- + *itempreview(<index>) Update already opened preview window with item from diff --git a/npc/custom/expandedbartershop.txt b/npc/custom/expandedbartershop.txt new file mode 100644 index 000000000..5ba988ad9 --- /dev/null +++ b/npc/custom/expandedbartershop.txt @@ -0,0 +1,63 @@ +//===== Hercules Script ====================================== +//= Expanded barter shop demo +//===== By: ================================================== +//= 4144 +//===== Current Version: ===================================== +//= 1.0 +//===== Description: ========================================= +//= Expanded barter shop demo in prontera. +//============================================================ + +prontera,160,284,4 trader Expanded Barter Shop#prt 4_M_KID1,{ + end; +OnInit: + tradertype(NST_EXPANDED_BARTER); + + // Selling Orange_Potion with items price and 4 items price + startsellitem(Orange_Potion, 2, 100000); + sellitemcurrency(Banana, 2); + sellitemcurrency(Apple, 1); + sellitemcurrency(Carrot, 2); + sellitemcurrency(Sweet_Potato, 1); + endsellitem(); + + // sell item with price only in zeny + sellitem(White_Herb, 1, 100); + // sell item with zeny and item price + sellitem(Blue_Herb, 22, 200, Orange_Potion, 2, 3); + + // sell item with price only in zeny (infinite amount) + sellitem(Green_Herb, 3, -1); + + // sell item with zeny and two items price (1) + sellitem(Orange_Potion, 20, 100000, Banana, 2, -1, Berserk_Potion, 10, -1); + + // sell item with zeny and two items price (same as before but with different zeny price) + sellitem(Orange_Potion, 1, 100000, Banana, 2, -1, Berserk_Potion, 10, -1); + + // sell item with item price + sellitem(Blade, 0, 1000, Sword, 2, -1); + + // sell item with zeny and two items price + sellitem(Scimiter, 2000, -1, Sword, 1, 2, Sword, 1, 5); + + // sell item with zeny and two items price (selling another Orange_Potion) + sellitem(Orange_Potion, 1, 100000, Green_Herb, 2, -1); + + // modify selling Orange_Potion with items price (same as previous) + // modification reset amount stored in db + startsellitem(Orange_Potion, 1, 100); + sellitemcurrency(Green_Herb, 2); + endsellitem(); + + // sell item with zeny and item price (selling another White_Herb) + sellitem(White_Herb, 10, 100, Banana, 1, -1); + + // stop selling blades +// stopselling(Blade, 1); + + // sell item with zeny and two items price (modify amount for entry (1)) +// sellitem(Orange_Potion, 1, 200000, Banana, 2, -1, Berserk_Potion, 10, -1); + + end; +} diff --git a/npc/re/jobs/2e/rebellion.txt b/npc/re/jobs/2e/rebellion.txt new file mode 100644 index 000000000..53beb11f5 --- /dev/null +++ b/npc/re/jobs/2e/rebellion.txt @@ -0,0 +1,1035 @@ +//================= Hercules Script ======================================= +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2020 Hercules Dev Team +//= Copyright (C) Dastgir +//= +//= Hercules is free software: you can redistribute it and/or modify +//= it under the terms of the GNU General Public License as published by +//= the Free Software Foundation, either version 3 of the License, or +//= (at your option) any later version. +//= +//= This program is distributed in the hope that it will be useful, +//= but WITHOUT ANY WARRANTY; without even the implied warranty of +//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//= GNU General Public License for more details. +//= +//= You should have received a copy of the GNU General Public License +//= along with this program. If not, see <http://www.gnu.org/licenses/>. +//========================================================================= +//= Rebellion Job Quest +//================= Description =========================================== +//= Job change Quest from Gunslinger -> Rebellion +//================= Current Version ======================================= +//= 1.0 +//========================================================================= + +job_gun,1,1,1 script Administrator1 CLEAR_NPC,{ + callfunc("F_GM_NPC"); + mes("Please enter the password."); + .@success = callfunc("F_GM_NPC", 1854, 0); + if (.@sucess != 1) + close(); + + mes("[Time Administrator]"); + mes("What time would you like to return?"); + next(); + .@select = select("Cancel", "Test monster spawn", "Start from beginning", "Furnace Zone", "Shooting Zone", "Complete the test"); + if (.@select == 1) { + close(); + } else if (.@select == 2) { + donpcevent("#target::OnStart"); + donpcevent("#nontarget::OnStart"); + close(); + } else if (.@select == 4) { + .@questComplete = 12341; + } else if (.@select == 5) { + .@questComplete = 12342; + } else if (.@select == 6) { + .@questComplete = 12344; + } + for (.@i = 12340; .@i <= 12345; .@i++) { + erasequest(.@i); + if (.@i <= .@questComplete) { + setquest(.@i); + completequest(.@i); + } + } + close(); + +OnInit: + disablenpc(strnpcinfo(NPC_NAME)); + end; +} + +// Warps +job_gun,56,26,0 warp rebelroom#1 2,2,einbroch,49,97 +job_gun,18,10,0 warp rebelroom#2 2,2,job_gun,81,29 +job_gun,165,22,0 warp rebelroom#3 2,2,job_gun,196,35 +job_gun,197,49,0 warp rebelroom#4 2,2,job_gun,157,21 + +job_gun,88,144,0 warp shootingrange#1 3,3,job_gun,93,123 +job_gun,105,97,0 warp shootingrange#2 3,3,job_gun,125,98 +job_gun,156,115,0 warp shootingrange#3 3,3,job_gun,157,137 +job_gun,152,154,0 warp shootingrange#4 3,3,job_gun,135,154 +job_gun,130,146,0 warp shootingrange#5 3,3,job_gun,120,130 + +job_gun,165,18,1 script Furnace Controller#1 CLEAR_NPC,{ + if (Class != Job_Gunslinger) { + mes("Only authorized user can do the operation."); + close(); + } + if (getstatus(SC_MONSTER_TRANSFORM, 1) != G_L_SHECIL) { + mes("Not an authorized user. Abort the operation."); + close(); + } + if (questprogress(12342) != 1) { + mes("Not an authorized user. Abort the operation."); + close(); + } + mes("Do you want to dredge the mold up from the furnace?"); + next(); + if (select("Quit.", "Begin.") == 1) { + mes("Switch to the Standby mode."); + close(); + } + hideonnpc("Furnace Controller#1"); + donpcevent("Furnace Controller#2::OnStart"); + mes("Initializing Furnace Controller ZX-3100..."); + close(); + +OnInit: + hideoffnpc("Furnace Controller#1"); + end; +} + +job_gun,214,36,1 script Auto Anvil#1 CLEAR_NPC,{ + if (Class != Job_Gunslinger) { + mes("Only authorized user can do the operation."); + close(); + } + if (countitem(Tiny_Flame) > 0) { + mes("Unauthorized firearm creation has been detected. Report to Manager Elwin."); + close(); + } + if (checkweight(Tiny_Flame, 1) == 0) { + mes("You have too many items, please reduce them to continue."); + close(); + } + if (getstatus(SC_MONSTER_TRANSFORM, 1) != G_L_SHECIL || countitem(Steel_Article_) <= 4 || questprogress(12342) != 1) { + mes("Not an authorized user. Abort the operation."); + close(); + } + + mes("Do you want to use the auto anvil and shape the standard Steel Artifacts into a firearm?"); + next(); + if (select("Quit.", "Begin.") == 1) { + mes("For your safety, please step away from the auto anvil."); + close(); + } + if (rand(1, 10) > 6) { + specialeffect(EF_REPAIRWEAPON); + mes("You have successfully created a firearm using the auto anvil. ^ff0000Please report before your transformation expires^000000."); + delitem(Steel_Article_, 5); + getitem(Tiny_Flame, 1); + } else { + specialeffect(EF_SUI_EXPLOSION); + mes("Failed to create a firearm."); + delitem(Steel_Article_, 5); + } + close(); + +OnInit: + hideoffnpc("Auto Anvil#1"); + end; +} + +job_gun,165,18,1 script Furnace Controller#2 CLEAR_NPC,{ + mes("The system is busy dredging a completed mold from the furnace."); + close(); + +OnInit: + hideonnpc("Furnace Controller#2"); + end; + +OnStart: + hideoffnpc("Furnace Controller#2"); + sleep(3000); + mapannounce("job_gun", "Furnace Controller: Dredging a mold up from the furnace... Workers, stand by at the production line.", bc_map, "0x00ff44"); + sleep(500); + .@wh_start = 0; + while (true) { + if (.@wh_start >= 30) + break; + + .@eff_rnd = rand(1, 100); + if (.@eff_rnd < 33) { // 0 - 32 + donpcevent("Heating Furnace#3::OnStart"); + } else if (.@eff_rnd > 66) { // 67-100 + donpcevent("Heating Furnace#4::OnStart"); + } else { // 33-66 + donpcevent("Heating Furnace#5::OnStart"); + } + sleep(200); + makeitem(Steel_Article, 1, "job_gun", rand(127, 143), rand(26, 29)); + if (rand(1, 10) > 7) { + makeitem(Steel_Article_, 1, "job_gun", rand(127, 143), rand(26, 29)); + } + .@wh_start += 1; + sleep(500); + + } + sleep(2000); + mapannounce("job_gun", "Furnace Controller: Finishing the operation... Entering Standby mode in 15 seconds.", bc_map, "0x00ff44"); + sleep(15000); + hideonnpc("Furnace Controller#2"); + hideoffnpc("Furnace Controller#1"); + end; +} + +job_gun,130,31,1 script Heating Furnace#3 CLEAR_NPC,{ + end; + +OnStart: + specialeffect(EF_FIREPILLAR); + sleep(500); + specialeffect(EF_FIREPILLARBOMB); + end; +} + +job_gun,136,31,1 script Heating Furnace#4 CLEAR_NPC,{ + end; + +OnStart: + specialeffect(EF_FIREPILLAR); + sleep(500); + specialeffect(EF_FIREPILLARBOMB); + end; +} + +job_gun,141,31,1 script Heating Furnace#5 CLEAR_NPC,{ + end; + +OnStart: + specialeffect(EF_FIREPILLAR); + sleep(500); + specialeffect(EF_FIREPILLARBOMB); + end; +} + +function script F_summonTargetMonster { + .@monster_id = getarg(0); + .@max_mob_count = getarg(1); + .@monster_name$ = getarg(2); + .@event_name$ = getarg(3); + while(true) { + .@mob_dead_num = mobcount("job_gun", .@event_name$); + if (.@mob_dead_num >= .@max_mob_count) + break; + + switch(rand(1, 5)) { + case 1: + .@mobx = rand(88, 99); + .@moby = rand(143, 147); + break; + case 2: + .@mobx = rand(92, 96); + .@moby = rand(95, 122); + break; + case 3: + .@mobx = rand(143, 159); + .@moby = rand(99, 100); + break; + case 4: + .@mobx = rand(157, 158); + .@moby = rand(137, 160); + break; + case 5: + .@mobx = rand(119, 134); + .@moby = rand(156, 160); + break; + } + monster("job_gun", .@mobx, .@moby, .@monster_name$, .@monster_id, 1, .@event_name$); + } + return; +} + +job_gun,1,4,1 script #target CLEAR_NPC,{ + end; + +OnStart: + killmonster("job_gun", "#target::OnTargetDead"); + callfunc("F_summonTargetMonster", J_REB_SHECIL1, 16, _("Standard-issue Target"), "#target::OnTargetDead"); + end; + +OnInit: + hideonnpc("#target"); + callfunc("F_summonTargetMonster", J_REB_SHECIL1, 16, _("Standard-issue Target"), "#target::OnTargetDead"); + end; + +OnTargetDead: + hideonnpc("#target"); + callfunc("F_summonTargetMonster", J_REB_SHECIL1, 16, _("Standard-issue Target"), "#target::OnTargetDead"); + end; +} + +job_gun,1,5,1 script #nontarget CLEAR_NPC,{ + end; +OnStart: + killmonster("job_gun", "#nontarget::OnNonTargetDead"); + hideonnpc("#nontarget"); + callfunc("F_summonTargetMonster", J_REB_SHECIL2, 56, _("Defective Target"), "#nontarget::OnNonTargetDead"); + end; + +OnInit: + hideonnpc("#nontarget"); + callfunc("F_summonTargetMonster", J_REB_SHECIL2, 56, _("Defective Target"), "#nontarget::OnNonTargetDead"); + end; + +OnNonTargetDead: + hideonnpc("#nontarget"); + callfunc("F_summonTargetMonster", J_REB_SHECIL2, 56, _("Defective Target"), "#nontarget::OnNonTargetDead"); + end; +} + +moc_fild12,261,318,3 script Suspicious Man 4_M_MOCASS2,2,2,{ + end; +OnTouch: + if (Class != Job_Gunslinger || BaseLevel < 99 || JobLevel < 70) + end; + if (questprogress(12340) < 1) { + mes("[Suspicious Man]"); + mes("Finally I've found you, Vagabond Spike! Your neck is mine!"); + next(); + select("Say what?"); + + mes("[Suspicious Man]"); + mes("*Snort* Don't pretend like you don't know. Look at this poster! You're in it!"); + next(); + select("I see the resemblance, but that's not me."); + + mesf("[%s]", strcharinfo(PC_NAME)); + mes("Forget the resemblance. Where did you get that poster? I've never committed a crime."); + next(); + mes("[Suspicious Man]"); + mes("I knew you'd try to lie your way out."); + next(); + mes("[Suspicious Man]"); + mes("The ^0000ffEinbroch Private Pub^000000 has released that wanted poster. You have many bounty hunters like me on your heels."); + next(); + mes("[Suspicious Man]"); + mes("I don't care if you're the right one so long as you look it and I can take you dead or alive."); + next(); + } else { + mes("[Suspicious Man]"); + mes("It's you again! You've got guts to come back here!"); + next(); + } + switch (select("Make a run for it.", "Fight him.")) { + case 1: + mes("^0000ffI should run for now and think about this later.^000000"); + close2(); + break; + case 2: + mes("^0000ffHe's not the only bounty hunter after me, if he's telling the truth. I need time to strategize.^000000"); + close2(); + break; + } + setquest(12340); + warp("moc_fild12", 186, 83); + end; +} + +einbroch,54,97,3 script Bouncer 4_M_REBELLION,2,2,{ + if (Class != Job_Gunslinger) { + mes("[Bouncer]"); + mes("No loitering around the venue."); + close(); + } + if (questprogress(12340) < 1) { + mes("[Bouncer]"); + mes("Under construction, can't get in."); + close(); + } else if (questprogress(12340) == 1) { + mes("[Bouncer]"); + mes("*Gasp* You! I thought you were already captured. Ooh, doesn't matter now. You're my Get Out of Jail Free card!"); + next(); + select("I'm not the criminal you think I am!"); + mes("[Bouncer]"); + mes("You aren't?"); + next(); + mes("^0000ffThe bouncer examines your face.^000000"); + next(); + mes("[Bouncer]"); + mes("Hm, you bear a striking resemblance, though you don't look not as menacing as that criminal Spike"); + next(); + select("I want to talk to the poster publisher."); + mes("[Bouncer]"); + mes("Your problem is a bit out of my league. Get in. If I find out you're the real deal all along, I'll see that you'll never see the outside again."); + close2(); + warp("job_gun", 81, 29); + } else if (questprogress(12340) > 1) { + mes("[Bouncer]"); + mes("You're back. Why?"); + next(); + if (select("I want in.", "I was passing by.") == 2) { + mes("[Bouncer]"); + mes("You're silly."); + close(); + } + mes("[Bouncer]"); + mes("Go ahead. Stay out of trouble."); + close2(); + warp("job_gun", 70, 28); + } + end; +} + +job_gun,68,33,3 script Ruthless Rebellion 4_F_REBELLION,2,2,{ + mes("[Ruthless Rebellion]"); + mes("Do you know how to use a gun?"); + close(); +} + +job_gun,78,33,6 script Suspicious Gunslinger 4_M_JOB_BLACKSMITH,2,2,{ + mes("[Suspicious Gunslinger]"); + mes("... "); + next(); + mes("[Quiet Gunslinger]"); + mes("Don't say I look like a blacksmith you know."); + close(); +} + +job_gun,74,24,6 script Drunken Man 4_M_LIEMAN,2,2,{ + mes("[Drunken Man]"); + mes("*Hiccups* Oh, I'm the owner here."); + mes("Oh wait, am I in the pub or someplace else? Zzz..."); + close(); +} + +job_gun,64,33,6 script Anxious Man 4_M_ALCHE_A,2,2,{ + mes("[Anxious Man]"); + mes("Maybe I'm in the wrong place. This place doesn't look like a pub."); + close(); +} + +job_gun,86,29,3 script Kulbertinov 4_M_REBELLION,2,2,{ + if (Class != Job_Gunslinger) { + mes("[Kulbertinov]"); + mes("Are you looking for me?"); + close(); + } + if (questprogress(12340) < 1) { + mes("[Kulbertinov]"); + mes("Can I help you?"); + close(); + } else if (questprogress(12340) == 1) { + mes("[Kulbertinov]"); + mes("What do you want?"); + next(); + select("I'm mistaken for a criminal!"); + mes("[Kulbertinov]"); + mes("Wait a minute... Mwah hah hah!"); + next(); + mes("^0000ffHe scans your face, then guffaws.^000000"); + next(); + mes("[Kulbertinov]"); + mes("I'm sorry. For a moment, I thought Spike came back to life. He was found dead three days ago."); + next(); + select("He was captured already?"); + mes("[Kulbertinov]"); + mes("Yes, and the bounty hunter was already paid. The news hasn't spread, and you're the spitting image of him. Go figure."); + next(); + select("You have to do something!"); + mes("[Kulbertinov]"); + mes("I'm sorry, but I can't talk to every single bounty hunter for you. Of course, I'm willing to compensate for your inconvenience."); + next(); + mes("[Kulbertinov]"); + mes("Hey, how about you join our ranks? At the very last, you won't get shot."); + next(); + select("You want me become a bounty hunter?"); + mes("[Kulbertinov]"); + mes("No, bounty hunting is just a pastime. We're the experts of all the firearms in the world."); + next(); + mes("[Kulbertinov]"); + mes("Carefree spirits!"); + mes("Magical spitfires!"); + mes("We call ourselves the ^0000ffRebellion^000000."); + next(); + mes("[Kulbertinov]"); + mes("You look like you know how to use a gun. How'd you like to join our ranks? You won't have to worry about other bounty hunters anymore too."); + next(); + switch (select("Let me think it over.", "I don't think I have a choice.")) { + case 1: + mes("[Kulbertinov]"); + mes("You can think it over and over, but the answer won't change. Just take the offer."); + break; + case 2: + mes("[Kulbertinov]"); + mes("Good thinking. Might as well do it now and get it over with."); + break; + } + next(); + mes("[Kulbertinov]"); + mes("Talk to Enwin Conick. She guides drifting spirits like you to the way of the Rebellion. I'll send word to her. Ah, and don't point your gun at her."); + setquest(12341); + completequest(12340); + } else if (questprogress(12340) > 1) { + mes("[Kulbertinov]"); + mes("Do you have business with Elwin Conick?"); + next(); + if (select("No.", "Send me to Elwin Conick.") == 1) { + mes("[Kulbertinov]"); + mes("All right. Care for a shot of vodka?"); + close(); + } + mes("[Kulbertinov]"); + mes("Okay, I'll let her know."); + } + close2(); + warp("job_gun", 19, 15); + end; +} + +job_gun,19,24,3 script Elwin Conick#1 4_F_REBELLION,2,2,{ + if (Class != Job_Gunslinger) { + mes("[Elwin Conick]"); + mes("If you don't want to join Rebellions, just get out."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (questprogress(12341) == 1) { + mes("[Elwin Conick]"); + mes("Do you to join us Rebellions?"); + next(); + mes("^0000ffThe short woman with keen eyes stares into your eyes.^000000"); + next(); + mes("[Elwin Conick]"); + mes("Sign here."); + next(); + mes("^0000ffThe undersigned party [_____] will not speak of the test even if he or she suffers injury, mutilation, or death in an unforeseen accident that may occur during the test.^000000"); + next(); + select("WHAT?!"); + mes("[Elwin Conick]"); + mes("Do you want join us or not?"); + next(); + if (select("I give up.", "...I'll sign.") == 1) { + mes("[Elwin Conick]"); + mes("Your choice."); + close2(); + warp("job_gun", 81, 29); + end; + } + mes("[Elwin Conick]"); + mes("Good. Now, follow me."); + close2(); + warp("job_gun", 117, 41); + end; + } + if (questprogress(12342) == 1) { + mes("[Elwin Conick]"); + mes("Do you want to try again?"); + next(); + if (select("I give up.", "Do it.") == 1) { + mes("[Elwin Conick]"); + mes("Your choice."); + close2(); + warp("job_gun", 81, 29); + end; + } + mes("[Elwin Conick]"); + mes("Follow me."); + close2(); + warp("job_gun", 117, 41); + end; + } + if (questprogress(12343) == 1) { + mes("[Elwin Conick]"); + mes("You still have Ivan's shooting test, do you want to try again?"); + next(); + if (select("I give up.", "Do it.") == 1) { + mes("[Elwin Conick]"); + mes("It's not worth to give up, now go out and relax."); + close2(); + warp("job_gun", 81, 29); + end; + } + mes("[Elwin Conick]"); + mes("Remember to give your best."); + close2(); + warp("job_gun", 120, 130); + end; + } + if (questprogress(12343) > 1) { + mes("[Elwin Conick]"); + mes("Ivan's shooting test have not finished yet, do you want to try again?"); + next(); + if (select("I give up.", "Do it.") == 1) { + mes("[Elwin Conick]"); + mes("It's not worth to give up, now go out and relax."); + close2(); + warp("job_gun", 81, 29); + end; + } + mes("[Elwin Conick]"); + mes("Remember to give your best."); + close2(); + warp("job_gun", 120, 130); + end; + } + if (questprogress(12345) == 1) { + mes("[Elwin Conick]"); + mes("Ivan is waiting for you, go find him."); + close2(); + warp("job_gun", 120, 130); + end; + } + mes("[Elwin Conick]"); + mes("You have no more test to take. Why don't you go out and have a drink?"); + close2(); + warp("job_gun", 81, 29); + end; +} + +job_gun,117,46,3 script Elwin Conick#2 4_F_REBELLION,2,2,{ + if (Class != Job_Gunslinger) { + mes("[Elwin Conick]"); + mes("If you don't want to join Rebellions, just get out."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (getstatus(SC_MONSTER_TRANSFORM, 1) == G_L_SHECIL) { + mes("^0000ffYou are already in the test form. If you have finished all your tests, report to Elwin Conick in the Assembly Room^000000."); + close(); + } else if (getstatus(SC_MONSTER_TRANSFORM, 1) > 1) { + mes("[Elwin Conick]"); + mes("Look at yourself, do you really want to test?"); + next(); + mes("^0000ffElwin see you turn into another form and she is very angry. Wait for your current form ends, and then find her again.^000000"); + next(); + if (select("Wait.", "Go away.") == 1) { + mes("[Elwin Conick]"); + mes("It's not worth to give up, now go out and relax.."); + close(); + } + mes("[Elwin Conick]"); + mes("Come back when you aren't in any form."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (questprogress(12341) == 1) { + .@st_job1 = countitem(Steel_Article); + .@st_job2 = countitem(Steel_Article_); + if (.@st_job1 > 0) { + delitem(Steel_Article, .@st_job1); + mes("[Elwin Conick]"); + mes("Any leftover Steel Artifacts must be returned after the test."); + close(); + } + if (.@st_job2 > 0) { + delitem(Steel_Article_, .@st_job2); + mes("[Elwin Conick]"); + mes("Any leftover Steel Artifacts must be returned after the test."); + close(); + } + if (countitem(Tiny_Flame) > 0) { + delitem(Tiny_Flame, 1); + mes("[Elwin Conick]"); + mes("Time over. You failed the test. Let me take all your leftover test materials."); + close(); + } + setquest(12342); + completequest(12341); + .@showDialog = true; + } else if (questprogress(12342) == 1) { + .@st_job1 = countitem(Steel_Article); + .@st_job2 = countitem(Steel_Article_); + if (.@st_job1 > 0) { + delitem(Steel_Article, .@st_job1); + mes("[Elwin Conick]"); + mes("Any leftover Steel Artifacts must be returned after the test."); + close(); + } + if (.@st_job2 > 0) { + delitem(Steel_Article_, .@st_job2); + mes("[Elwin Conick]"); + mes("Time over. You failed the test. Let me take all your leftover test materials."); + close(); + } + if (countitem(Tiny_Flame) > 0) { + delitem(Tiny_Flame, 1); + mes("[Elwin Conick]"); + mes("Time over. You failed the test. Let me take all your leftover test materials."); + close2(); + end; + } + .@showDialog = true; + } + if (.@showDialog) { + mes("[Elwin Conick]"); + mes("Listen up. I'm not going to great lengths trying to explain the test to you."); + next(); + select("Okay."); + mes("[Elwin Conick]"); + mes("This is where the firearm molds are cast. Everywhere you can see Steel Artifacts are being produced."); + next(); + mes("[Elwin Conick]"); + mes("You'll be asked to control switches on the machine and select 5 standard Steel Artifacts."); + next(); + mes("[Elwin Conick]"); + mes("You'll then take them to the next Assembly Room and assemble them into a complete firearm. You'll be given 3 minutes to finish all that. ^0000ffTo check the elapsed time, you'll be transformed into a different job^000000."); + next(); + mes("[Elwin Conick]"); + mes("I'll be in the next room, waiting for you to bring me a complete firearm. Remember, ^0000ffyou fail the test when your transformation expires after 3 minutes^000000."); + montransform(G_L_SHECIL, 180000); + close(); + } + mes("[Elwin Conick]"); + mes("Ah? Are you lost? You need to register first and then get back here."); + close2(); + warp("job_gun", 81, 29); + end; +} + +job_gun,198,39,3 script Elwin Conick#3 4_F_REBELLION,2,2,{ + if (Class != Job_Gunslinger) { + mes("[Elwin Conick]"); + mes("If you don't want to join Rebellions, just get out."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (questprogress(12342) != 1) { + mes("[Elwin Conick]"); + mes("Ah? Are you lost? You need to register first and then get back here."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (getstatus(SC_MONSTER_TRANSFORM, 1) == G_L_SHECIL) { + if (countitem(Tiny_Flame) == 0) { + mes("[Elwin Conick]"); + mes("Are you done? I don't see any completed firearm in your inventory."); + close(); + } + delitem(Tiny_Flame, 1); + mes("[Elwin Conick]"); + mes("It's shoddy but not bad, given the time. You passed."); + next(); + mes("[Elwin Conick]"); + mes("Let me take all your leftover test materials."); + .@st_job1 = countitem(Steel_Article); + .@st_job2 = countitem(Steel_Article_); + if (.@st_job1 > 0) { + delitem(Steel_Article, .@st_job1); + } + if (.@st_job2 > 0) { + delitem(Steel_Article_, .@st_job2); + } + next(); + mes("[Elwin Conick]"); + mes("Now you can move on to the next course. Ivan Sidorenko will oversee your test."); + completequest(12342); + close2(); + warp("job_gun", 120, 133); + end; + + } else if (getstatus(SC_MONSTER_TRANSFORM, 1) > 1) { + mes("[Elwin Conick]"); + mes("Look at yourself, do you really want to test?"); + next(); + mes("^0000ffElwin see you turn into another form and she is very angry. Wait for your current form ends, and then find her again.^000000"); + next(); + if (select("Wait.", "Go away.") == 1) { + mes("[Elwin Conick]"); + mes("It's not worth to give up, now go out and relax.."); + close(); + } + mes("[Elwin Conick]"); + mes("Come back when you aren't in any form."); + close2(); + warp("job_gun", 81, 29); + end; + } else { + mes("[Elwin Conick]"); + mes("Time over. You failed the test. Let me take all your leftover test materials."); + .@st_job1 = countitem(Steel_Article); + .@st_job2 = countitem(Steel_Article_); + if (.@st_job1 > 0) { + delitem(Steel_Article, .@st_job1); + } + if (.@st_job2 > 0) { + delitem(Steel_Article_, .@st_job2); + } + if (countitem(Tiny_Flame) > 0) { + delitem(Tiny_Flame, 1); + } + next(); + mes("[Elwin Conick]"); + mes("Let's start again."); + close2(); + warp("job_gun", 117, 41); + end; + } + end; +} + +job_gun,120,138,3 script Ivan Sidorenko#1 4_M_REBELLION,2,2,{ + if (Class != Job_Gunslinger) { + mes("[Ivan Sidorenko]"); + mes("This is shooting test area, you can't come here as you like."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (questprogress(12342) < 2) { + mes("[Ivan Sidorenko]"); + mes("There seems to be a mistake, you can't stay here."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (questprogress(12343) < 1) { + mes("[Ivan Sidorenko]"); + mes("Hey, stay focused--we're using live ammo here, and you can get shot anytime."); + next(); + mes("[Ivan Sidorenko]"); + mes("Let me make this quick. Basically you'll be running in this shooting range consisting of 5 sections."); + next(); + mes("[Ivan Sidorenko]"); + mes("The objective is to find enemies in the midst of a crowd quickly and without fail."); + next(); + mes("[Ivan Sidorenko]"); + mes("Among all the targets, you must shoot only the ^0000ffStandard-issue Targets^000000. If you make a mistake, you'll lose points."); + next(); + mes("[Ivan Sidorenko]"); + mes("Let's try. There aren't many ^0000ffStandard-issue Targets^000000, so keep your eyes peeled."); + next(); + mes("[Ivan Sidorenko]"); + mes("^0000ffYou have 3 minutes to finish this test. If you can't finish before your transformation expires^000000, you'll fail. If that happens, just follow the path back to me."); + next(); + mes("[Ivan Sidorenko]"); + mes("^0000ffYou'll fail if you miss a Standard-issue Target, or shoot 3 incorrect targets^000000. Let's get started."); + setquest(12343); + setquest(12344); + montransform(G_L_SHECIL, 180000); + close2(); + warp("job_gun", 102, 146); + end; + } else if (questprogress(12343) == 1) { + .@standard_target = 0; + .@failed_target = 0; + .@total_target = 0; + if (questprogress(12343, HUNTING) == 2) { + .@standard_target = 10; + } + if (questprogress(12344, HUNTING) == 2) { + .@failed_target = 2; + } + if (getstatus(SC_MONSTER_TRANSFORM, 1) != G_L_SHECIL) { + .@total_target = 5; + } + .@target_count = .@standard_target - (.@failed_target + .@total_target); // + if (.@target_count > 9) { // Killed 10 Standard, 0 Failed + completequest(12343); + completequest(12344); + setquest(12345); + mes("[Ivan Sidorenko]"); + mes("Good job. I didn't think you could pass so quickly."); + next(); + mes("[Ivan Sidorenko]"); + mes("You may leave and wait outside. I'll bring other instructors' evaluation reports to see you."); + close2(); + warp("job_gun", 210, 132); + end; + } else if (.@target_count == 8) { // Killed 10 Standard, 3 failed + erasequest(12343); + erasequest(12344); + mes("[Ivan Sidorenko]"); + mes("You're quick enough, but you shot too many incorrect targets. You failed."); + next(); + } else if (.@target_count == 5) { // Timeout + erasequest(12343); + erasequest(12344); + mes("[Ivan Sidorenko]"); + mes("You accurate enough, but you took too much time. Slow Rebellions don't survive long enough."); + next(); + } else if (.@target_count < 5) { // Timeout and failed targets + erasequest(12343); + erasequest(12344); + mes("[Ivan Sidorenko]"); + mes("You failed at both speed and accuracy. How did you survive this long?"); + next(); + } else { + erasequest(12343); + erasequest(12344); + mes("[Ivan Sidorenko]"); + mes("There's a problem, the statistic seems to be wrong. Well... This can happen sometimes."); + next(); + } + mes("[Ivan Sidorenko]"); + mes("Let's try again. Be more careful this time."); + setquest(12343); + setquest(12344); + montransform(G_L_SHECIL, 180000); + close2(); + warp("job_gun", 102, 146); + end; + } else { + mes("[Ivan Sidorenko]"); + mes("How did you not leave?"); + next(); + mes("[Ivan Sidorenko]"); + mes("You may leave and wait outside. I'll bring other instructors' evaluation reports to see you."); + close2(); + warp("job_gun", 210, 132); + end; + } + end; +} + +job_gun,220,132,3 script Ivan Sidorenko#2 4_M_REBELLION,2,2,{ + .@now_weight = MaxWeight - Weight; + if (checkweight(Knife, 1) == 0) { + mes("You have too many items, please reduce them to continue."); + close(); + } + if (.@now_weight < 1000) { + mes("The items in your inventory are weighing you down. Lighten your weight first."); + close(); + } + if (questprogress(12345) != 1) { + mes("[Ivan Sidorenko]"); + mes("There must have been a mistake. You aren't supposed to remain here."); + close2(); + warp("job_gun", 81, 29); + end; + } + if (Class == Job_Gunslinger) { + if (BaseLevel < 99 || JobLevel < 70) { + mes("[Ivan Sidorenko]"); + mes("Huh? You look so weak? I have nothing more to say."); + close(); + } + if (SkillPoint != 0) { + mes("[Ivan Sidorenko]"); + mes("Oh no~ You still have Skill Points."); + close(); + } + mes("[Ivan Sidorenko]"); + mes("Kulbertinov, Elwin, and I've evaluated your Rebellion test results."); + next(); + mes("[Ivan Sidorenko]"); + mes("And..."); + next(); + mes("[Ivan Sidorenko]"); + mes("You've met all our requirements including the attitude and the test performance."); + next(); + mes("[Ivan Sidorenko]"); + mes("That's right, you're now a member of the Rebellion. Get ready to be wowed."); + next(); + jobchange(Job_Rebellion); + completequest(12345); + mes("[Ivan Sidorenko]"); + mes("And Elwin wants you to have this. Take good care of it. He made it for you."); + getitem(Freedom_Flame, 1); + next(); + mes("[Ivan Sidorenko]"); + mes("See you later."); + close2(); + warp("job_gun", 81, 29); + end; + } else if (Class == Job_Rebellion) { + mes("[Ivan Sidorenko]"); + mes("This life should be fun, not boring."); + next(); + mes("[Ivan Sidorenko]"); + mes("And by becoming a Rebellion your life should be upgraded. So, go and create a great journey, make us proud!"); + close(); + } else { + mes("[Ivan Sidorenko]"); + mes("Do you have something to say to me, don't you?"); + close(); + } +} + +job_gun,220,138,4 trader Prop Vending Machine 2_VENDING_MACHINE1,{ + end; +OnInit: + sellitem(Slug_Bullet_1); + sellitem(Slug_Bullet_2); + sellitem(Slug_Bullet_3); + sellitem(Slug_Bullet_4); + sellitem(Slug_Bullet_5); + sellitem(Fullmetal_Jacket_Bullet); + sellitem(Mine_Projectile); + sellitem(Dragon_Tail_Missile); + end; +} + +job_gun,216,138,4 script Butler Karlex 1_M_01,{ + mes("[Butler Karlex]"); + mes("Use this temporary storage to keep your items safe while on the Advancement test."); + next(); + .@select = select("Cancel", "Open the storage."); + mes("[Butler Karlex]"); + mes("Thank you for using the service."); + close2(); + if (.@select == 2) { + openstorage(); + } + end; +} + +prontera,92,209,4 trader Rebellion Weapons 2_VENDING_MACHINE1,{ + end; +OnInit: + sellitem(H_FEATHER_H_FIRE); + sellitem(ALTAIR_ARES); + sellitem(COLORSCOPE); + sellitem(RAG203); + sellitem(DEATHFIRE); + sellitem(R_THUNDER); + sellitem(P_BREAKER); + sellitem(MINIMAY); + sellitem(TEMPEST); + sellitem(END_OF_HORIZON); + sellitem(Southern_Cross_R); + end; +} + +prontera,96,209,4 trader Rebellion Accessories 2_VENDING_MACHINE1,{ + end; +OnInit: + sellitem(Slug_Bullet); + sellitem(Fullmetal_Jacket_Bullet); + sellitem(Mine_Projectile); + sellitem(Dragon_Tail_Missile); + sellitem(Special_Alloy_Trap); + sellitem(Bullet); + sellitem(Silver_Bullet_); + sellitem(Shell_Of_Blood_); + sellitem(AP_Ammo); + sellitem(Blaze_Bullet); + sellitem(Freezing_Bullet); + sellitem(Electric_Shock_Bullet); + sellitem(Magical_Stone_Bullet); + sellitem(Sanctified_Bullet); + sellitem(Flare_Bullet); + sellitem(Lightning_Bullet); + sellitem(Poison_Bullet); + sellitem(Blind_Bullet); + sellitem(Ice_Bullet); + end; +} diff --git a/npc/re/other/achievement_treasures.txt b/npc/re/other/achievement_treasures.txt new file mode 100644 index 000000000..38fb69d77 --- /dev/null +++ b/npc/re/other/achievement_treasures.txt @@ -0,0 +1,342 @@ +//================= Hercules Script ======================================= +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2020 Hercules Dev Team +//= +//= Hercules is free software: you can redistribute it and/or modify +//= it under the terms of the GNU General Public License as published by +//= the Free Software Foundation, either version 3 of the License, or +//= (at your option) any later version. +//= +//= This program is distributed in the hope that it will be useful, +//= but WITHOUT ANY WARRANTY; without even the implied warranty of +//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//= GNU General Public License for more details. +//= +//= You should have received a copy of the GNU General Public License +//= along with this program. If not, see <http://www.gnu.org/licenses/>. +//========================================================================= +// Exploration Achievements +//========================================================================= + +- script achievement_tr FAKE_NPC,{ + sscanf(strnpcinfo(NPC_NAME_HIDDEN), "tr%d", .@id); + if (!achievement_iscompleted(.@id)) + achievement_progress(.@id, 1, 1, true); + end; +OnInit: + cloakonnpc(strnpcinfo(NPC_NAME)); + end; +} + +- script achievement_wp FAKE_NPC,{ +OnTouch: + sscanf(strnpcinfo(NPC_NAME_HIDDEN), "wp%d", .@id); + if (!achievement_iscompleted(.@id)) + cloakoffnpc(sprintf("#tr%d", .@id), playerattached()); + end; +} + +// Treasure Chests +prt_fild01,146,126,4 duplicate(achievement_tr) #tr120001 4_TREASURE_BOX +prt_fild02,142,221,4 duplicate(achievement_tr) #tr120002 4_TREASURE_BOX +prt_fild03,172,139,4 duplicate(achievement_tr) #tr120003 4_TREASURE_BOX +prt_fild04,118,57,4 duplicate(achievement_tr) #tr120004 4_TREASURE_BOX +prt_fild05,189,291,4 duplicate(achievement_tr) #tr120005 4_TREASURE_BOX +prt_fild06,298,304,4 duplicate(achievement_tr) #tr120006 4_TREASURE_BOX +prt_fild07,44,104,4 duplicate(achievement_tr) #tr120007 4_TREASURE_BOX +prt_fild08,203,222,4 duplicate(achievement_tr) #tr120008 4_TREASURE_BOX +prt_fild09,37,354,4 duplicate(achievement_tr) #tr120009 4_TREASURE_BOX +prt_fild10,177,206,4 duplicate(achievement_tr) #tr120010 4_TREASURE_BOX +gef_fild00,73,119,4 duplicate(achievement_tr) #tr120011 4_TREASURE_BOX +gef_fild01,222,224,4 duplicate(achievement_tr) #tr120012 4_TREASURE_BOX +gef_fild05,202,292,4 duplicate(achievement_tr) #tr120013 4_TREASURE_BOX +gef_fild06,279,105,4 duplicate(achievement_tr) #tr120014 4_TREASURE_BOX +gef_fild07,184,249,4 duplicate(achievement_tr) #tr120015 4_TREASURE_BOX +gef_fild09,170,73,4 duplicate(achievement_tr) #tr120016 4_TREASURE_BOX +gef_fild11,239,248,4 duplicate(achievement_tr) #tr120017 4_TREASURE_BOX +moc_fild11,188,218,4 duplicate(achievement_tr) #tr120018 4_TREASURE_BOX +moc_fild12,234,96,4 duplicate(achievement_tr) #tr120019 4_TREASURE_BOX +moc_fild13,290,207,4 duplicate(achievement_tr) #tr120020 4_TREASURE_BOX +moc_fild16,196,108,4 duplicate(achievement_tr) #tr120021 4_TREASURE_BOX +moc_fild17,269,105,4 duplicate(achievement_tr) #tr120022 4_TREASURE_BOX +moc_fild18,54,284,4 duplicate(achievement_tr) #tr120023 4_TREASURE_BOX +pay_fild01,167,243,4 duplicate(achievement_tr) #tr120024 4_TREASURE_BOX +pay_fild02,105,240,4 duplicate(achievement_tr) #tr120025 4_TREASURE_BOX +pay_fild03,144,97,4 duplicate(achievement_tr) #tr120026 4_TREASURE_BOX +pay_fild04,257,95,4 duplicate(achievement_tr) #tr120027 4_TREASURE_BOX +pay_fild07,365,37,4 duplicate(achievement_tr) #tr120028 4_TREASURE_BOX +pay_fild08,237,345,4 duplicate(achievement_tr) #tr120029 4_TREASURE_BOX +pay_fild09,251,42,4 duplicate(achievement_tr) #tr120030 4_TREASURE_BOX +pay_fild10,196,38,4 duplicate(achievement_tr) #tr120031 4_TREASURE_BOX +mjolnir_01,47,60,4 duplicate(achievement_tr) #tr120032 4_TREASURE_BOX +mjolnir_02,77,49,4 duplicate(achievement_tr) #tr120033 4_TREASURE_BOX +mjolnir_03,190,200,4 duplicate(achievement_tr) #tr120034 4_TREASURE_BOX +mjolnir_04,201,146,4 duplicate(achievement_tr) #tr120035 4_TREASURE_BOX +mjolnir_05,43,327,4 duplicate(achievement_tr) #tr120036 4_TREASURE_BOX +mjolnir_06,162,290,4 duplicate(achievement_tr) #tr120037 4_TREASURE_BOX +mjolnir_07,321,127,4 duplicate(achievement_tr) #tr120038 4_TREASURE_BOX +mjolnir_08,175,225,4 duplicate(achievement_tr) #tr120039 4_TREASURE_BOX +mjolnir_09,299,123,4 duplicate(achievement_tr) #tr120040 4_TREASURE_BOX +mjolnir_10,353,371,4 duplicate(achievement_tr) #tr120041 4_TREASURE_BOX +mjolnir_11,325,178,4 duplicate(achievement_tr) #tr120042 4_TREASURE_BOX +mjolnir_12,110,298,4 duplicate(achievement_tr) #tr120043 4_TREASURE_BOX +cmd_fild01,112,200,4 duplicate(achievement_tr) #tr120044 4_TREASURE_BOX +cmd_fild02,86,94,4 duplicate(achievement_tr) #tr120045 4_TREASURE_BOX +cmd_fild03,144,190,4 duplicate(achievement_tr) #tr120046 4_TREASURE_BOX +cmd_fild04,151,191,4 duplicate(achievement_tr) #tr120047 4_TREASURE_BOX +cmd_fild06,221,108,4 duplicate(achievement_tr) #tr120048 4_TREASURE_BOX +cmd_fild07,269,322,4 duplicate(achievement_tr) #tr120049 4_TREASURE_BOX +cmd_fild08,181,136,4 duplicate(achievement_tr) #tr120050 4_TREASURE_BOX +cmd_fild09,211,266,4 duplicate(achievement_tr) #tr120051 4_TREASURE_BOX +yuno_fild01,284,138,4 duplicate(achievement_tr) #tr120052 4_TREASURE_BOX +yuno_fild12,76,268,4 duplicate(achievement_tr) #tr120053 4_TREASURE_BOX +yuno_fild02,142,191,4 duplicate(achievement_tr) #tr120054 4_TREASURE_BOX +yuno_fild03,135,329,4 duplicate(achievement_tr) #tr120055 4_TREASURE_BOX +yuno_fild04,35,369,4 duplicate(achievement_tr) #tr120056 4_TREASURE_BOX +yuno_fild06,262,220,4 duplicate(achievement_tr) #tr120057 4_TREASURE_BOX +yuno_fild07,113,339,4 duplicate(achievement_tr) #tr120058 4_TREASURE_BOX +yuno_fild08,179,209,4 duplicate(achievement_tr) #tr120059 4_TREASURE_BOX +yuno_fild09,166,228,4 duplicate(achievement_tr) #tr120060 4_TREASURE_BOX +yuno_fild11,141,357,4 duplicate(achievement_tr) #tr120061 4_TREASURE_BOX +hu_fild01,347,312,4 duplicate(achievement_tr) #tr120062 4_TREASURE_BOX +hu_fild02,80,152,4 duplicate(achievement_tr) #tr120063 4_TREASURE_BOX +hu_fild04,322,313,4 duplicate(achievement_tr) #tr120064 4_TREASURE_BOX +hu_fild06,204,228,4 duplicate(achievement_tr) #tr120065 4_TREASURE_BOX +hu_fild05,197,210,4 duplicate(achievement_tr) #tr120066 4_TREASURE_BOX +ein_fild01,266,277,4 duplicate(achievement_tr) #tr120067 4_TREASURE_BOX +ein_fild03,99,332,4 duplicate(achievement_tr) #tr120068 4_TREASURE_BOX +ein_fild04,334,305,4 duplicate(achievement_tr) #tr120069 4_TREASURE_BOX +ein_fild05,337,233,4 duplicate(achievement_tr) #tr120070 4_TREASURE_BOX +ein_fild06,174,245,4 duplicate(achievement_tr) #tr120071 4_TREASURE_BOX +ein_fild07,188,50,4 duplicate(achievement_tr) #tr120072 4_TREASURE_BOX +ein_fild08,258,78,4 duplicate(achievement_tr) #tr120073 4_TREASURE_BOX +ein_fild09,330,76,4 duplicate(achievement_tr) #tr120074 4_TREASURE_BOX +lhz_fild01,118,73,4 duplicate(achievement_tr) #tr120075 4_TREASURE_BOX +lhz_fild02,239,243,4 duplicate(achievement_tr) #tr120076 4_TREASURE_BOX +lhz_fild03,313,132,4 duplicate(achievement_tr) #tr120077 4_TREASURE_BOX +ra_fild01,138,166,4 duplicate(achievement_tr) #tr120078 4_TREASURE_BOX +ra_fild03,224,275,4 duplicate(achievement_tr) #tr120079 4_TREASURE_BOX +ra_fild08,326,45,4 duplicate(achievement_tr) #tr120080 4_TREASURE_BOX +ra_fild12,352,165,4 duplicate(achievement_tr) #tr120081 4_TREASURE_BOX +ra_fild04,92,302,4 duplicate(achievement_tr) #tr120082 4_TREASURE_BOX +ra_fild05,59,59,4 duplicate(achievement_tr) #tr120083 4_TREASURE_BOX +ra_fild06,362,230,4 duplicate(achievement_tr) #tr120084 4_TREASURE_BOX +ve_fild01,180,234,4 duplicate(achievement_tr) #tr120085 4_TREASURE_BOX +ve_fild02,65,194,4 duplicate(achievement_tr) #tr120086 4_TREASURE_BOX +ve_fild03,197,242,4 duplicate(achievement_tr) #tr120087 4_TREASURE_BOX +ve_fild04,288,279,4 duplicate(achievement_tr) #tr120088 4_TREASURE_BOX +ve_fild07,33,113,4 duplicate(achievement_tr) #tr120089 4_TREASURE_BOX +ecl_fild01,234,217,4 duplicate(achievement_tr) #tr120090 4_TREASURE_BOX +bif_fild02,155,322,4 duplicate(achievement_tr) #tr120091 4_TREASURE_BOX +bif_fild01,147,64,4 duplicate(achievement_tr) #tr120092 4_TREASURE_BOX +spl_fild01,335,315,4 duplicate(achievement_tr) #tr120093 4_TREASURE_BOX +spl_fild02,153,358,4 duplicate(achievement_tr) #tr120094 4_TREASURE_BOX +spl_fild03,61,286,4 duplicate(achievement_tr) #tr120095 4_TREASURE_BOX +man_fild01,41,172,4 duplicate(achievement_tr) #tr120096 4_TREASURE_BOX +man_fild02,268,357,4 duplicate(achievement_tr) #tr120097 4_TREASURE_BOX +man_fild03,198,91,4 duplicate(achievement_tr) #tr120098 4_TREASURE_BOX +dic_fild01,227,82,4 duplicate(achievement_tr) #tr120099 4_TREASURE_BOX +dic_fild02,147,196,4 duplicate(achievement_tr) #tr120100 4_TREASURE_BOX +ama_fild01,187,337,4 duplicate(achievement_tr) #tr120101 4_TREASURE_BOX +gon_fild01,171,332,4 duplicate(achievement_tr) #tr120102 4_TREASURE_BOX +lou_fild01,104,232,4 duplicate(achievement_tr) #tr120103 4_TREASURE_BOX +ayo_fild01,289,70,4 duplicate(achievement_tr) #tr120104 4_TREASURE_BOX +mosk_fild02,176,77,4 duplicate(achievement_tr) #tr120105 4_TREASURE_BOX +bra_fild01,99,193,4 duplicate(achievement_tr) #tr120106 4_TREASURE_BOX +dew_fild01,175,287,4 duplicate(achievement_tr) #tr120107 4_TREASURE_BOX +ma_fild01,308,206,4 duplicate(achievement_tr) #tr120108 4_TREASURE_BOX +ma_fild02,246,323,4 duplicate(achievement_tr) #tr120109 4_TREASURE_BOX +abbey03,27,72,4 duplicate(achievement_tr) #tr120110 4_TREASURE_BOX +abyss_03,86,55,4 duplicate(achievement_tr) #tr120111 4_TREASURE_BOX +alde_dun04,90,107,4 duplicate(achievement_tr) #tr120112 4_TREASURE_BOX +ama_dun03,60,163,4 duplicate(achievement_tr) #tr120113 4_TREASURE_BOX +anthell02,253,41,4 duplicate(achievement_tr) #tr120114 4_TREASURE_BOX +ayo_dun02,150,256,4 duplicate(achievement_tr) #tr120115 4_TREASURE_BOX +beach_dun3,102,71,4 duplicate(achievement_tr) #tr120116 4_TREASURE_BOX +bra_dun02,171,121,4 duplicate(achievement_tr) #tr120117 4_TREASURE_BOX +c_tower4,37,158,4 duplicate(achievement_tr) #tr120118 4_TREASURE_BOX +dew_dun02,87,272,4 duplicate(achievement_tr) #tr120119 4_TREASURE_BOX +dic_dun03,216,211,4 duplicate(achievement_tr) #tr120120 4_TREASURE_BOX +ecl_tdun04,37,37,4 duplicate(achievement_tr) #tr120121 4_TREASURE_BOX +ein_dun02,31,255,4 duplicate(achievement_tr) #tr120122 4_TREASURE_BOX +gef_dun02,222,163,4 duplicate(achievement_tr) #tr120123 4_TREASURE_BOX +gl_sew04,288,6,4 duplicate(achievement_tr) #tr120124 4_TREASURE_BOX +gl_knt02,126,235,4 duplicate(achievement_tr) #tr120125 4_TREASURE_BOX +gl_cas02,53,151,4 duplicate(achievement_tr) #tr120126 4_TREASURE_BOX +gl_prison1,126,158,4 duplicate(achievement_tr) #tr120127 4_TREASURE_BOX +gon_dun03,166,231,4 duplicate(achievement_tr) #tr120128 4_TREASURE_BOX +ice_dun03,45,261,4 duplicate(achievement_tr) #tr120129 4_TREASURE_BOX +in_sphinx5,154,107,4 duplicate(achievement_tr) #tr120130 4_TREASURE_BOX +iz_dun05,64,223,4 duplicate(achievement_tr) #tr120131 4_TREASURE_BOX +kh_dun02,70,107,4 duplicate(achievement_tr) #tr120132 4_TREASURE_BOX +lhz_dun03,240,221,4 duplicate(achievement_tr) #tr120133 4_TREASURE_BOX +lou_dun03,29,228,4 duplicate(achievement_tr) #tr120134 4_TREASURE_BOX +mag_dun02,197,77,4 duplicate(achievement_tr) #tr120135 4_TREASURE_BOX +mjo_dun03,76,220,4 duplicate(achievement_tr) #tr120136 4_TREASURE_BOX +moc_pryd06,102,121,4 duplicate(achievement_tr) #tr120137 4_TREASURE_BOX +orcsdun02,31,72,4 duplicate(achievement_tr) #tr120138 4_TREASURE_BOX +pay_dun04,120,124,4 duplicate(achievement_tr) #tr120139 4_TREASURE_BOX +prt_maze03,11,14,4 duplicate(achievement_tr) #tr120140 4_TREASURE_BOX +prt_sewb4,19,183,4 duplicate(achievement_tr) #tr120141 4_TREASURE_BOX +tha_t06,150,176,4 duplicate(achievement_tr) #tr120142 4_TREASURE_BOX +thor_v03,220,221,4 duplicate(achievement_tr) #tr120143 4_TREASURE_BOX +treasure02,19,142,4 duplicate(achievement_tr) #tr120144 4_TREASURE_BOX +tur_dun04,134,130,4 duplicate(achievement_tr) #tr120145 4_TREASURE_BOX +xmas_dun02,120,224,4 duplicate(achievement_tr) #tr120146 4_TREASURE_BOX + +// Hidden Warps +prt_fild01,146,126,0 duplicate(achievement_wp) #wp120001 HIDDEN_WARP_NPC,5,5 +prt_fild02,142,221,0 duplicate(achievement_wp) #wp120002 HIDDEN_WARP_NPC,5,5 +prt_fild03,172,139,0 duplicate(achievement_wp) #wp120003 HIDDEN_WARP_NPC,5,5 +prt_fild04,118,57,0 duplicate(achievement_wp) #wp120004 HIDDEN_WARP_NPC,5,5 +prt_fild05,189,291,0 duplicate(achievement_wp) #wp120005 HIDDEN_WARP_NPC,5,5 +prt_fild06,298,304,0 duplicate(achievement_wp) #wp120006 HIDDEN_WARP_NPC,5,5 +prt_fild07,44,104,0 duplicate(achievement_wp) #wp120007 HIDDEN_WARP_NPC,5,5 +prt_fild08,203,222,0 duplicate(achievement_wp) #wp120008 HIDDEN_WARP_NPC,5,5 +prt_fild09,37,354,0 duplicate(achievement_wp) #wp120009 HIDDEN_WARP_NPC,5,5 +prt_fild10,177,206,0 duplicate(achievement_wp) #wp120010 HIDDEN_WARP_NPC,5,5 +gef_fild00,73,119,0 duplicate(achievement_wp) #wp120011 HIDDEN_WARP_NPC,5,5 +gef_fild01,222,224,0 duplicate(achievement_wp) #wp120012 HIDDEN_WARP_NPC,5,5 +gef_fild05,202,292,0 duplicate(achievement_wp) #wp120013 HIDDEN_WARP_NPC,5,5 +gef_fild06,279,105,0 duplicate(achievement_wp) #wp120014 HIDDEN_WARP_NPC,5,5 +gef_fild07,184,249,0 duplicate(achievement_wp) #wp120015 HIDDEN_WARP_NPC,5,5 +gef_fild09,170,73,0 duplicate(achievement_wp) #wp120016 HIDDEN_WARP_NPC,5,5 +gef_fild11,239,248,0 duplicate(achievement_wp) #wp120017 HIDDEN_WARP_NPC,5,5 +moc_fild11,188,218,0 duplicate(achievement_wp) #wp120018 HIDDEN_WARP_NPC,5,5 +moc_fild12,234,96,0 duplicate(achievement_wp) #wp120019 HIDDEN_WARP_NPC,5,5 +moc_fild13,290,207,0 duplicate(achievement_wp) #wp120020 HIDDEN_WARP_NPC,5,5 +moc_fild16,196,108,0 duplicate(achievement_wp) #wp120021 HIDDEN_WARP_NPC,5,5 +moc_fild17,269,105,0 duplicate(achievement_wp) #wp120022 HIDDEN_WARP_NPC,5,5 +moc_fild18,54,284,0 duplicate(achievement_wp) #wp120023 HIDDEN_WARP_NPC,5,5 +pay_fild01,167,243,0 duplicate(achievement_wp) #wp120024 HIDDEN_WARP_NPC,5,5 +pay_fild02,105,240,0 duplicate(achievement_wp) #wp120025 HIDDEN_WARP_NPC,5,5 +pay_fild03,144,97,0 duplicate(achievement_wp) #wp120026 HIDDEN_WARP_NPC,5,5 +pay_fild04,257,95,0 duplicate(achievement_wp) #wp120027 HIDDEN_WARP_NPC,5,5 +pay_fild07,365,37,0 duplicate(achievement_wp) #wp120028 HIDDEN_WARP_NPC,5,5 +pay_fild08,237,345,0 duplicate(achievement_wp) #wp120029 HIDDEN_WARP_NPC,5,5 +pay_fild09,251,42,0 duplicate(achievement_wp) #wp120030 HIDDEN_WARP_NPC,5,5 +pay_fild10,196,38,0 duplicate(achievement_wp) #wp120031 HIDDEN_WARP_NPC,5,5 +mjolnir_01,47,60,0 duplicate(achievement_wp) #wp120032 HIDDEN_WARP_NPC,5,5 +mjolnir_02,77,49,0 duplicate(achievement_wp) #wp120033 HIDDEN_WARP_NPC,5,5 +mjolnir_03,190,200,0 duplicate(achievement_wp) #wp120034 HIDDEN_WARP_NPC,5,5 +mjolnir_04,201,146,0 duplicate(achievement_wp) #wp120035 HIDDEN_WARP_NPC,5,5 +mjolnir_05,43,327,0 duplicate(achievement_wp) #wp120036 HIDDEN_WARP_NPC,5,5 +mjolnir_06,162,290,0 duplicate(achievement_wp) #wp120037 HIDDEN_WARP_NPC,5,5 +mjolnir_07,321,127,0 duplicate(achievement_wp) #wp120038 HIDDEN_WARP_NPC,5,5 +mjolnir_08,175,225,0 duplicate(achievement_wp) #wp120039 HIDDEN_WARP_NPC,5,5 +mjolnir_09,299,123,0 duplicate(achievement_wp) #wp120040 HIDDEN_WARP_NPC,5,5 +mjolnir_10,353,371,0 duplicate(achievement_wp) #wp120041 HIDDEN_WARP_NPC,5,5 +mjolnir_11,325,178,0 duplicate(achievement_wp) #wp120042 HIDDEN_WARP_NPC,5,5 +mjolnir_12,110,298,0 duplicate(achievement_wp) #wp120043 HIDDEN_WARP_NPC,5,5 +cmd_fild01,112,200,0 duplicate(achievement_wp) #wp120044 HIDDEN_WARP_NPC,5,5 +cmd_fild02,86,94,0 duplicate(achievement_wp) #wp120045 HIDDEN_WARP_NPC,5,5 +cmd_fild03,144,190,0 duplicate(achievement_wp) #wp120046 HIDDEN_WARP_NPC,5,5 +cmd_fild04,151,191,0 duplicate(achievement_wp) #wp120047 HIDDEN_WARP_NPC,5,5 +cmd_fild06,221,108,0 duplicate(achievement_wp) #wp120048 HIDDEN_WARP_NPC,5,5 +cmd_fild07,269,322,0 duplicate(achievement_wp) #wp120049 HIDDEN_WARP_NPC,5,5 +cmd_fild08,181,136,0 duplicate(achievement_wp) #wp120050 HIDDEN_WARP_NPC,5,5 +cmd_fild09,211,266,0 duplicate(achievement_wp) #wp120051 HIDDEN_WARP_NPC,5,5 +yuno_fild01,284,138,0 duplicate(achievement_wp) #wp120052 HIDDEN_WARP_NPC,5,5 +yuno_fild12,76,268,0 duplicate(achievement_wp) #wp120053 HIDDEN_WARP_NPC,5,5 +yuno_fild02,142,191,0 duplicate(achievement_wp) #wp120054 HIDDEN_WARP_NPC,5,5 +yuno_fild03,135,329,0 duplicate(achievement_wp) #wp120055 HIDDEN_WARP_NPC,5,5 +yuno_fild04,35,369,0 duplicate(achievement_wp) #wp120056 HIDDEN_WARP_NPC,5,5 +yuno_fild06,262,220,0 duplicate(achievement_wp) #wp120057 HIDDEN_WARP_NPC,5,5 +yuno_fild07,113,339,0 duplicate(achievement_wp) #wp120058 HIDDEN_WARP_NPC,5,5 +yuno_fild08,179,209,0 duplicate(achievement_wp) #wp120059 HIDDEN_WARP_NPC,5,5 +yuno_fild09,166,228,0 duplicate(achievement_wp) #wp120060 HIDDEN_WARP_NPC,5,5 +yuno_fild11,141,357,0 duplicate(achievement_wp) #wp120061 HIDDEN_WARP_NPC,5,5 +hu_fild01,347,312,0 duplicate(achievement_wp) #wp120062 HIDDEN_WARP_NPC,5,5 +hu_fild02,80,152,0 duplicate(achievement_wp) #wp120063 HIDDEN_WARP_NPC,5,5 +hu_fild04,322,313,0 duplicate(achievement_wp) #wp120064 HIDDEN_WARP_NPC,5,5 +hu_fild06,204,228,0 duplicate(achievement_wp) #wp120065 HIDDEN_WARP_NPC,5,5 +hu_fild05,197,210,0 duplicate(achievement_wp) #wp120066 HIDDEN_WARP_NPC,5,5 +ein_fild01,266,277,0 duplicate(achievement_wp) #wp120067 HIDDEN_WARP_NPC,5,5 +ein_fild03,99,332,0 duplicate(achievement_wp) #wp120068 HIDDEN_WARP_NPC,5,5 +ein_fild04,334,305,0 duplicate(achievement_wp) #wp120069 HIDDEN_WARP_NPC,5,5 +ein_fild05,337,233,0 duplicate(achievement_wp) #wp120070 HIDDEN_WARP_NPC,5,5 +ein_fild06,174,245,0 duplicate(achievement_wp) #wp120071 HIDDEN_WARP_NPC,5,5 +ein_fild07,188,50,0 duplicate(achievement_wp) #wp120072 HIDDEN_WARP_NPC,5,5 +ein_fild08,258,78,0 duplicate(achievement_wp) #wp120073 HIDDEN_WARP_NPC,5,5 +ein_fild09,330,76,0 duplicate(achievement_wp) #wp120074 HIDDEN_WARP_NPC,5,5 +lhz_fild01,118,73,0 duplicate(achievement_wp) #wp120075 HIDDEN_WARP_NPC,5,5 +lhz_fild02,239,243,0 duplicate(achievement_wp) #wp120076 HIDDEN_WARP_NPC,5,5 +lhz_fild03,313,132,0 duplicate(achievement_wp) #wp120077 HIDDEN_WARP_NPC,5,5 +ra_fild01,138,166,0 duplicate(achievement_wp) #wp120078 HIDDEN_WARP_NPC,5,5 +ra_fild03,224,275,0 duplicate(achievement_wp) #wp120079 HIDDEN_WARP_NPC,5,5 +ra_fild08,326,45,0 duplicate(achievement_wp) #wp120080 HIDDEN_WARP_NPC,5,5 +ra_fild12,352,165,0 duplicate(achievement_wp) #wp120081 HIDDEN_WARP_NPC,5,5 +ra_fild04,92,302,0 duplicate(achievement_wp) #wp120082 HIDDEN_WARP_NPC,5,5 +ra_fild05,59,59,0 duplicate(achievement_wp) #wp120083 HIDDEN_WARP_NPC,5,5 +ra_fild06,362,230,0 duplicate(achievement_wp) #wp120084 HIDDEN_WARP_NPC,5,5 +ve_fild01,180,234,0 duplicate(achievement_wp) #wp120085 HIDDEN_WARP_NPC,5,5 +ve_fild02,65,194,0 duplicate(achievement_wp) #wp120086 HIDDEN_WARP_NPC,5,5 +ve_fild03,197,242,0 duplicate(achievement_wp) #wp120087 HIDDEN_WARP_NPC,5,5 +ve_fild04,288,279,0 duplicate(achievement_wp) #wp120088 HIDDEN_WARP_NPC,5,5 +ve_fild07,33,113,0 duplicate(achievement_wp) #wp120089 HIDDEN_WARP_NPC,5,5 +ecl_fild01,234,217,0 duplicate(achievement_wp) #wp120090 HIDDEN_WARP_NPC,5,5 +bif_fild02,155,322,0 duplicate(achievement_wp) #wp120091 HIDDEN_WARP_NPC,5,5 +bif_fild01,147,64,0 duplicate(achievement_wp) #wp120092 HIDDEN_WARP_NPC,5,5 +spl_fild01,335,315,0 duplicate(achievement_wp) #wp120093 HIDDEN_WARP_NPC,5,5 +spl_fild02,153,358,0 duplicate(achievement_wp) #wp120094 HIDDEN_WARP_NPC,5,5 +spl_fild03,61,286,0 duplicate(achievement_wp) #wp120095 HIDDEN_WARP_NPC,5,5 +man_fild01,41,172,0 duplicate(achievement_wp) #wp120096 HIDDEN_WARP_NPC,5,5 +man_fild02,268,357,0 duplicate(achievement_wp) #wp120097 HIDDEN_WARP_NPC,5,5 +man_fild03,198,91,0 duplicate(achievement_wp) #wp120098 HIDDEN_WARP_NPC,5,5 +dic_fild01,227,82,0 duplicate(achievement_wp) #wp120099 HIDDEN_WARP_NPC,5,5 +dic_fild02,147,196,0 duplicate(achievement_wp) #wp120100 HIDDEN_WARP_NPC,5,5 +ama_fild01,187,337,0 duplicate(achievement_wp) #wp120101 HIDDEN_WARP_NPC,5,5 +gon_fild01,171,332,0 duplicate(achievement_wp) #wp120102 HIDDEN_WARP_NPC,5,5 +lou_fild01,104,232,0 duplicate(achievement_wp) #wp120103 HIDDEN_WARP_NPC,5,5 +ayo_fild01,289,70,0 duplicate(achievement_wp) #wp120104 HIDDEN_WARP_NPC,5,5 +mosk_fild02,176,77,0 duplicate(achievement_wp) #wp120105 HIDDEN_WARP_NPC,5,5 +bra_fild01,99,193,0 duplicate(achievement_wp) #wp120106 HIDDEN_WARP_NPC,5,5 +dew_fild01,175,287,0 duplicate(achievement_wp) #wp120107 HIDDEN_WARP_NPC,5,5 +ma_fild01,308,206,0 duplicate(achievement_wp) #wp120108 HIDDEN_WARP_NPC,5,5 +ma_fild02,246,323,0 duplicate(achievement_wp) #wp120109 HIDDEN_WARP_NPC,5,5 +abbey03,27,72,0 duplicate(achievement_wp) #wp120110 HIDDEN_WARP_NPC,5,5 +abyss_03,86,55,0 duplicate(achievement_wp) #wp120111 HIDDEN_WARP_NPC,5,5 +alde_dun04,90,107,0 duplicate(achievement_wp) #wp120112 HIDDEN_WARP_NPC,5,5 +ama_dun03,60,163,0 duplicate(achievement_wp) #wp120113 HIDDEN_WARP_NPC,5,5 +anthell02,253,41,0 duplicate(achievement_wp) #wp120114 HIDDEN_WARP_NPC,5,5 +ayo_dun02,150,256,0 duplicate(achievement_wp) #wp120115 HIDDEN_WARP_NPC,5,5 +beach_dun3,102,71,0 duplicate(achievement_wp) #wp120116 HIDDEN_WARP_NPC,5,5 +bra_dun02,171,121,0 duplicate(achievement_wp) #wp120117 HIDDEN_WARP_NPC,5,5 +c_tower4,37,158,0 duplicate(achievement_wp) #wp120118 HIDDEN_WARP_NPC,5,5 +dew_dun02,87,272,0 duplicate(achievement_wp) #wp120119 HIDDEN_WARP_NPC,5,5 +dic_dun03,216,211,0 duplicate(achievement_wp) #wp120120 HIDDEN_WARP_NPC,5,5 +ecl_tdun04,37,37,0 duplicate(achievement_wp) #wp120121 HIDDEN_WARP_NPC,5,5 +ein_dun02,31,255,0 duplicate(achievement_wp) #wp120122 HIDDEN_WARP_NPC,5,5 +gef_dun02,222,163,0 duplicate(achievement_wp) #wp120123 HIDDEN_WARP_NPC,5,5 +gl_sew04,288,6,0 duplicate(achievement_wp) #wp120124 HIDDEN_WARP_NPC,5,5 +gl_knt02,126,235,0 duplicate(achievement_wp) #wp120125 HIDDEN_WARP_NPC,5,5 +gl_cas02,53,151,0 duplicate(achievement_wp) #wp120126 HIDDEN_WARP_NPC,5,5 +gl_prison1,126,158,0 duplicate(achievement_wp) #wp120127 HIDDEN_WARP_NPC,5,5 +gon_dun03,166,231,0 duplicate(achievement_wp) #wp120128 HIDDEN_WARP_NPC,5,5 +ice_dun03,45,261,0 duplicate(achievement_wp) #wp120129 HIDDEN_WARP_NPC,5,5 +in_sphinx5,154,107,0 duplicate(achievement_wp) #wp120130 HIDDEN_WARP_NPC,5,5 +iz_dun05,64,223,0 duplicate(achievement_wp) #wp120131 HIDDEN_WARP_NPC,5,5 +kh_dun02,70,107,0 duplicate(achievement_wp) #wp120132 HIDDEN_WARP_NPC,5,5 +lhz_dun03,240,221,0 duplicate(achievement_wp) #wp120133 HIDDEN_WARP_NPC,5,5 +lou_dun03,29,228,0 duplicate(achievement_wp) #wp120134 HIDDEN_WARP_NPC,5,5 +mag_dun02,197,77,0 duplicate(achievement_wp) #wp120135 HIDDEN_WARP_NPC,5,5 +mjo_dun03,76,220,0 duplicate(achievement_wp) #wp120136 HIDDEN_WARP_NPC,5,5 +moc_pryd06,102,121,0 duplicate(achievement_wp) #wp120137 HIDDEN_WARP_NPC,5,5 +orcsdun02,31,72,0 duplicate(achievement_wp) #wp120138 HIDDEN_WARP_NPC,5,5 +pay_dun04,120,124,0 duplicate(achievement_wp) #wp120139 HIDDEN_WARP_NPC,5,5 +prt_maze03,11,14,0 duplicate(achievement_wp) #wp120140 HIDDEN_WARP_NPC,5,5 +prt_sewb4,19,183,0 duplicate(achievement_wp) #wp120141 HIDDEN_WARP_NPC,5,5 +tha_t06,150,176,0 duplicate(achievement_wp) #wp120142 HIDDEN_WARP_NPC,5,5 +thor_v03,220,221,0 duplicate(achievement_wp) #wp120143 HIDDEN_WARP_NPC,5,5 +treasure02,19,142,0 duplicate(achievement_wp) #wp120144 HIDDEN_WARP_NPC,5,5 +tur_dun04,134,130,0 duplicate(achievement_wp) #wp120145 HIDDEN_WARP_NPC,5,5 +xmas_dun02,120,224,0 duplicate(achievement_wp) #wp120146 HIDDEN_WARP_NPC,5,5 diff --git a/npc/re/scripts.conf b/npc/re/scripts.conf index 2499d99b2..5ecf6b741 100644 --- a/npc/re/scripts.conf +++ b/npc/re/scripts.conf @@ -136,6 +136,7 @@ "npc/re/other/turbo_track.txt", // - Clan System "npc/re/other/clans.txt", +"npc/re/other/achievement_treasures.txt", //================= Quests ================================================ // - Eden Group ------------------------------------------------- diff --git a/npc/re/scripts_jobs.conf b/npc/re/scripts_jobs.conf index f112334de..6dd99e813 100644 --- a/npc/re/scripts_jobs.conf +++ b/npc/re/scripts_jobs.conf @@ -40,6 +40,7 @@ "npc/re/jobs/1-1e/taekwon.txt", // - 2e "npc/re/jobs/2e/kagerou_oboro.txt", +"npc/re/jobs/2e/rebellion.txt", // - 3-1 "npc/re/jobs/3-1/archbishop.txt", "npc/re/jobs/3-1/mechanic.txt", diff --git a/npc/scripts_custom.conf b/npc/scripts_custom.conf index 4e346238f..bf970b8ca 100644 --- a/npc/scripts_custom.conf +++ b/npc/scripts_custom.conf @@ -51,6 +51,7 @@ //"npc/custom/item_signer.txt", //"npc/custom/woe_controller.txt", //"npc/custom/bartershop.txt", +//"npc/custom/expandedbartershop.txt", //================= Other Scripts ========================================= // -- MVP Arena diff --git a/sql-files/item_db.sql b/sql-files/item_db.sql index a0f07fc7a..c6546502e 100644 --- a/sql-files/item_db.sql +++ b/sql-files/item_db.sql @@ -4491,10 +4491,10 @@ REPLACE INTO `item_db` VALUES ('12114','Elemental_Fire','Elemental Converter','1 REPLACE INTO `item_db` VALUES ('12115','Elemental_Water','Elemental Converter','11','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','itemskill ITEM_ENCHANTARMS,2;','',''); REPLACE INTO `item_db` VALUES ('12116','Elemental_Earth','Elemental Converter','11','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','itemskill ITEM_ENCHANTARMS,3;','',''); REPLACE INTO `item_db` VALUES ('12117','Elemental_Wind','Elemental Converter','11','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','itemskill ITEM_ENCHANTARMS,5;','',''); -REPLACE INTO `item_db` VALUES ('12118','Resist_Fire','Fireproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,-15,0,20,0;','',''); -REPLACE INTO `item_db` VALUES ('12119','Resist_Water','Coldproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,20,0,0,-15;','',''); -REPLACE INTO `item_db` VALUES ('12120','Resist_Earth','Earthproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,0,20,-15,0;','',''); -REPLACE INTO `item_db` VALUES ('12121','Resist_Wind','Thunderproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,0,-15,0,20;','',''); +REPLACE INTO `item_db` VALUES ('12118','Resist_Fire','Fireproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, 20); sc_start(SC_RESIST_PROPERTY_WATER, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); +REPLACE INTO `item_db` VALUES ('12119','Resist_Water','Coldproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_WATER, 1200000, 20); sc_start(SC_RESIST_PROPERTY_WIND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); +REPLACE INTO `item_db` VALUES ('12120','Resist_Earth','Earthproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, 20); sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); +REPLACE INTO `item_db` VALUES ('12121','Resist_Wind','Thunderproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_WIND, 1200000, 20); sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); REPLACE INTO `item_db` VALUES ('12122','Sesame_Pastry','Sesame Pastry','2','0','2','1','70','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_FOOD_BASICHIT,1200000,30;','',''); REPLACE INTO `item_db` VALUES ('12123','Honey_Pastry','Honey Pastry','2','0','2','1','70','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_FOOD_BASICAVOIDANCE,1200000,30;','',''); REPLACE INTO `item_db` VALUES ('12124','Rainbow_Cake','Rainbow Cake','2','0','2','1','70','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_BATKFOOD,1200000,10; sc_start SC_MATKFOOD,120000,10;','',''); @@ -4649,7 +4649,7 @@ REPLACE INTO `item_db` VALUES ('12275','Gold_Pill_2','Taecheongdan','0','0','0', REPLACE INTO `item_db` VALUES ('12276','Mimic_Scroll','Mimic Scroll','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','73',NULL,'0',NULL,'0',NULL,'0','mercenary_create M_MIMIC, 1800000;','',''); REPLACE INTO `item_db` VALUES ('12277','Disguise_Scroll','Disguise Scroll','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','73',NULL,'0',NULL,'0',NULL,'0','mercenary_create M_DISGUISE, 1800000;','',''); REPLACE INTO `item_db` VALUES ('12278','Alice_Scroll','Alice Scroll','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','73',NULL,'0',NULL,'0',NULL,'0','mercenary_create M_ALICE, 1800000;','',''); -REPLACE INTO `item_db` VALUES ('12279','Undead_Element_Scroll','Undead Elemental Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMOR_RESIST,300000,20,20,20,20;','',''); +REPLACE INTO `item_db` VALUES ('12279','Undead_Element_Scroll','Undead Elemental Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_FIRE, 300000, 20); sc_start(SC_RESIST_PROPERTY_WATER, 300000, 20); sc_start(SC_RESIST_PROPERTY_WIND, 300000, 20); sc_start(SC_RESIST_PROPERTY_GROUND, 300000, 20);','',''); REPLACE INTO `item_db` VALUES ('12280','Holy_Element_Scroll','Holy Elemental Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','specialeffect(EF_BENEDICTIO, AREA, playerattached()); sc_start SC_BENEDICTIO,300000,1;','',''); REPLACE INTO `item_db` VALUES ('12281','Tresure_Box_WoE','Event Treasure Box','2','0','20','10','150','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','getrandgroupitem 12281,1;','',''); REPLACE INTO `item_db` VALUES ('12282','Internet_Cafe1','Internet Cafe1','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_FOOD_STR, 5400000, 3; sc_start SC_FOOD_DEX, 5400000, 3; sc_start SC_FOOD_AGI, 5400000, 3; sc_start SC_FOOD_INT, 5400000, 3; sc_start SC_FOOD_VIT, 5400000, 3; sc_start SC_FOOD_LUK, 5400000, 3; sc_start SC_PLUSATTACKPOWER, 5400000, 15; sc_start SC_PLUSMAGICPOWER, 5400000, 15;','',''); diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index 58d89d11e..bc1e23376 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -4603,6 +4603,8 @@ REPLACE INTO `item_db` VALUES ('6681','XMAS_Cookie','XMAS Cookie','3','0','0','0 REPLACE INTO `item_db` VALUES ('6682','Bag_Of_Selling_Goods','Bag Of Selling Goods','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6707','Cash_Hair_Coupon','Cash Hair Coupon','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6712','Lovely_Stick','Love Wand','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); +REPLACE INTO `item_db` VALUES ('6746','Steel_Article','Steel Artifact','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); +REPLACE INTO `item_db` VALUES ('6747','Steel_Article_','Steel Artifact','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6755','Corrupted_Charm','Contaminated Magic','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6804','ORGANIC_PUMPKIN','Organic Pumpkin','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6805','INORGANIC_PUMPKIN','Inorganic Pumpkin','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); @@ -5959,10 +5961,10 @@ REPLACE INTO `item_db` VALUES ('12114','Elemental_Fire','Elemental Converter','1 REPLACE INTO `item_db` VALUES ('12115','Elemental_Water','Elemental Converter','11','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','itemskill ITEM_ENCHANTARMS,2;','',''); REPLACE INTO `item_db` VALUES ('12116','Elemental_Earth','Elemental Converter','11','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','itemskill ITEM_ENCHANTARMS,3;','',''); REPLACE INTO `item_db` VALUES ('12117','Elemental_Wind','Elemental Converter','11','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','itemskill ITEM_ENCHANTARMS,5;','',''); -REPLACE INTO `item_db` VALUES ('12118','Resist_Fire','Fireproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,-15,0,20,0;','',''); -REPLACE INTO `item_db` VALUES ('12119','Resist_Water','Coldproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,20,0,0,-15;','',''); -REPLACE INTO `item_db` VALUES ('12120','Resist_Earth','Earthproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,0,20,-15,0;','',''); -REPLACE INTO `item_db` VALUES ('12121','Resist_Wind','Thunderproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMORPROPERTY,1200000,0,-15,0,20;','',''); +REPLACE INTO `item_db` VALUES ('12118','Resist_Fire','Fireproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, 20); sc_start(SC_RESIST_PROPERTY_WATER, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); +REPLACE INTO `item_db` VALUES ('12119','Resist_Water','Coldproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_WATER, 1200000, 20); sc_start(SC_RESIST_PROPERTY_WIND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); +REPLACE INTO `item_db` VALUES ('12120','Resist_Earth','Earthproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, 20); sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); +REPLACE INTO `item_db` VALUES ('12121','Resist_Wind','Thunderproof Potion','2','0','2','1','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_WIND, 1200000, 20); sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON);','',''); REPLACE INTO `item_db` VALUES ('12122','Sesame_Pastry','Sesame Pastry','2','0','2','1','70','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_FOOD_BASICHIT,1200000,30;','',''); REPLACE INTO `item_db` VALUES ('12123','Honey_Pastry','Honey Pastry','2','0','2','1','70','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_FOOD_BASICAVOIDANCE, 1200000, 30;','',''); REPLACE INTO `item_db` VALUES ('12124','Rainbow_Cake','Rainbow Cake','2','0','2','1','70','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_PLUSATTACKPOWER, 1200000, 10; sc_start SC_PLUSMAGICPOWER, 120000, 10;','',''); @@ -6117,7 +6119,7 @@ REPLACE INTO `item_db` VALUES ('12275','Gold_Pill_2','Taecheongdan','0','0','0', REPLACE INTO `item_db` VALUES ('12276','Mimic_Scroll','Mimic Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','mercenary_create M_MIMIC, 1800000;','',''); REPLACE INTO `item_db` VALUES ('12277','Disguise_Scroll','Disguise Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','mercenary_create M_DISGUISE, 1800000;','',''); REPLACE INTO `item_db` VALUES ('12278','Alice_Scroll','Alice Contract','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','mercenary_create M_ALICE, 1800000;','',''); -REPLACE INTO `item_db` VALUES ('12279','Undead_Element_Scroll','Undead Elemental Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start4 SC_ARMOR_RESIST,300000,20,20,20,20;','',''); +REPLACE INTO `item_db` VALUES ('12279','Undead_Element_Scroll','Undead Elemental Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start(SC_RESIST_PROPERTY_FIRE, 300000, 20); sc_start(SC_RESIST_PROPERTY_WATER, 300000, 20); sc_start(SC_RESIST_PROPERTY_WIND, 300000, 20); sc_start(SC_RESIST_PROPERTY_GROUND, 300000, 20);','',''); REPLACE INTO `item_db` VALUES ('12280','Holy_Element_Scroll','Holy Elemental Scroll','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','specialeffect(EF_BENEDICTIO, AREA, playerattached()); sc_start SC_BENEDICTIO,300000,1;','',''); REPLACE INTO `item_db` VALUES ('12281','Tresure_Box_WoE','Event Treasure Box','2','0','20','10','150','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','packageitem();','',''); REPLACE INTO `item_db` VALUES ('12282','Internet_Cafe1','Internet Cafe1','2','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','sc_start SC_FOOD_STR, 5400000, 3; sc_start SC_FOOD_DEX, 5400000, 3; sc_start SC_FOOD_AGI, 5400000, 3; sc_start SC_FOOD_INT, 5400000, 3; sc_start SC_FOOD_VIT, 5400000, 3; sc_start SC_FOOD_LUK, 5400000, 3; sc_start SC_PLUSATTACKPOWER, 5400000, 15; sc_start SC_PLUSMAGICPOWER, 5400000, 15;','',''); @@ -6877,6 +6879,8 @@ REPLACE INTO `item_db` VALUES ('13114','P_Revolver3','Eden Group Revolver III',' REPLACE INTO `item_db` VALUES ('13115','Upg_Revolver','Upgrade Revolver','4','17','20','10','500','35','0','0','7','1','16777216','1','2','34','3','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bBaseAtk,(getrefine()*5); bonus bLongAtkRate,(getrefine()*2); if(BaseLevel>70) { bonus bBaseAtk,(((BaseLevel-70)/10)*5); }','',''); REPLACE INTO `item_db` VALUES ('13116','Novice_Revolver','Beginner Revolver','4','17','0','0','500','20','0','0','7','0','16777216','1','2','34','1','0',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bHit,-5;','',''); REPLACE INTO `item_db` VALUES ('13117','TE_Woe_Pistol','TE Woe Pistol','4','17','0','0','0','60','0','0','7','0','1090519040','63','2','34','3','40',NULL,'0','0','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddRace,RC_Player,40; bonus2 bAddEff,Eff_Curse,1000;','',''); +REPLACE INTO `item_db` VALUES ('13118','Tiny_Flame','Fading Flame','4','17','0','0','100','0','0','0','7','0','1090519040','63','2','34','1','1',NULL,'1','0','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','','',''); +REPLACE INTO `item_db` VALUES ('13119','Freedom_Flame','Freedom Flame','4','17','0','0','100','100','0','0','7','2','1090519040','63','2','34','3','99',NULL,'1','0','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('13120','H_FEATHER_H_FIRE','Heaven\'s_Feather_&_Hell\'s_Fire','4','17','1250000','625000','800','150','0','0','9','1','1090519040','63','2','34','3','99',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSkillAtk,GS_DESPERADO,20; bonus2 bSkillAtk,RL_FALLEN_ANGEL,20;','',''); REPLACE INTO `item_db` VALUES ('13122','ALTAIR_ARES','Altea & Ares','4','17','1450000','725000','1000','200','0','0','9','0','1073741824','63','2','34','3','140',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bHit,5; bonus bDelayrate,10; bonus bLongAtkRate,30;','',''); REPLACE INTO `item_db` VALUES ('13124','ALTAIR_ARES_','Altea & Ares','4','17','1450000','725000','1000','200','0','0','9','1','1073741824','63','2','34','3','140',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bHit,5; bonus bDelayrate,10; bonus bLongAtkRate,30;','',''); @@ -6952,13 +6956,18 @@ REPLACE INTO `item_db` VALUES ('13217','Freezing_Bullet','Freezing Bullet','10', REPLACE INTO `item_db` VALUES ('13218','Electric_Shock_Bullet','Lightning Bullet','10','3','10','5','2','40','0','0','0','0','1090519040','63','2','32768','0','100',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Wind;','',''); REPLACE INTO `item_db` VALUES ('13219','Magical_Stone_Bullet','Magic Stone Bullet','10','3','10','5','2','40','0','0','0','0','1090519040','63','2','32768','0','100',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Earth;','',''); REPLACE INTO `item_db` VALUES ('13220','Sanctified_Bullet','Purifying Bullet','10','3','10','5','2','40','0','0','0','0','1090519040','63','2','32768','0','100',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Holy;','',''); -REPLACE INTO `item_db` VALUES ('13221','Silver_Bullet_','Silver Bullet','10','3','5','2','2','15','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Holy;','',''); -REPLACE INTO `item_db` VALUES ('13222','Shell_Of_Blood_','Bloody Shell','10','3','10','5','2','30','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Neutral; bonus2 bAddEff, Eff_Bleeding, 100;','',''); -REPLACE INTO `item_db` VALUES ('13223','Flare_Sphere_','Incendiary Grenade','10','3','15','7','5','50','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Fire;','',''); -REPLACE INTO `item_db` VALUES ('13224','Lighting_Sphere_','Lightning Grenade','10','3','15','7','5','50','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Wind;','',''); -REPLACE INTO `item_db` VALUES ('13225','Poison_Sphere_','Poison Grenade','10','3','15','7','5','50','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Poison; bonus2 bAddEff, Eff_Poison, 500;','',''); -REPLACE INTO `item_db` VALUES ('13226','Blind_Sphere_','Flash Grenade','10','3','15','7','5','50','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Dark; bonus2 bAddEff, Eff_Blind, 500;','',''); -REPLACE INTO `item_db` VALUES ('13227','Freezing_Sphere_','Cyro Grenade','10','3','15','7','5','50','0','0','0','0','16777216','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Water;','',''); +REPLACE INTO `item_db` VALUES ('13221','Silver_Bullet_','Silver Bullet','10','3','5','2','2','15','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Holy;','',''); +REPLACE INTO `item_db` VALUES ('13222','Shell_Of_Blood_','Bloody Shell','10','3','10','5','2','30','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Neutral; bonus2 bAddEff, Eff_Bleeding, 100;','',''); +REPLACE INTO `item_db` VALUES ('13223','Flare_Sphere_','Incendiary Grenade','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Fire;','',''); +REPLACE INTO `item_db` VALUES ('13224','Lighting_Sphere_','Lightning Grenade','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Wind;','',''); +REPLACE INTO `item_db` VALUES ('13225','Poison_Sphere_','Poison Grenade','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Poison; bonus2 bAddEff, Eff_Poison, 500;','',''); +REPLACE INTO `item_db` VALUES ('13226','Blind_Sphere_','Flash Grenade','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Dark; bonus2 bAddEff, Eff_Blind, 500;','',''); +REPLACE INTO `item_db` VALUES ('13227','Freezing_Sphere_','Cyro Grenade','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Water;','',''); +REPLACE INTO `item_db` VALUES ('13228','Flare_Bullet','Flare Bullet','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Fire;','',''); +REPLACE INTO `item_db` VALUES ('13229','Lightning_Bullet','Lightning Bullet','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Wind;','',''); +REPLACE INTO `item_db` VALUES ('13230','Ice_Bullet','Ice Bullet','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Water;','',''); +REPLACE INTO `item_db` VALUES ('13231','Poison_Bullet','Poison Bullet','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Poison; bonus2 bAddEff, Eff_Poison, 500;','',''); +REPLACE INTO `item_db` VALUES ('13232','Blind_Bullet','Blind Bullet','10','3','15','7','5','50','0','0','0','0','1090519040','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAtkEle, Ele_Dark; bonus2 bAddEff, Eff_Blind, 500;','',''); REPLACE INTO `item_db` VALUES ('13250','Shuriken','Shuriken','10','6','4','2','5','10','0','0','0','0','33554432','63','2','32768','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('13251','Nimbus_Shuriken','Nimbus Shuriken','10','6','10','5','5','30','0','0','0','0','33554432','63','2','32768','0','20',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('13252','Flash_Shuriken','Flash Shuriken','10','6','20','10','5','45','0','0','0','0','33554432','63','2','32768','0','40',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); @@ -10680,6 +10689,7 @@ REPLACE INTO `item_db` VALUES ('24580','S_Banish_Cannon_Shoes','S_Banish_Cannon_ REPLACE INTO `item_db` VALUES ('24581','S_Genesis_Weapon','S_Genesis_Weapon','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('24582','S_Genesis_Pendant','S_Genesis_Pendant','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('24583','S_Genesis_Earing','S_Genesis_Earing','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); +REPLACE INTO `item_db` VALUES ('25187','Slug_Bullet','Slug Bullet','3','0','1200','600','1200','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('25258','BrokenArrow','BrokenArrow','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('25265','Shining_Spore','Shining_Spore','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('25266','Dried_Leaf_Of_Ygg','Dried_Leaf_Of_Ygg','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); diff --git a/sql-files/main.sql b/sql-files/main.sql index 258c7293a..4e75ccc8b 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -935,6 +935,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1565293394); -- 2019-08-0 INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1570309293); -- 2019-10-05--19-01.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1570870260); -- 2019-10-21--14-21.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1574463539); -- 2019-11-22--23-58.sql +INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1579817630); -- 2020-01-24--01-09.sql -- -- Table structure for table `storage` @@ -1032,3 +1033,46 @@ CREATE TABLE IF NOT EXISTS `npc_barter_data` ( `priceAmount` INT UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`name`, `itemid`, `priceId`, `priceAmount`) ) ENGINE=MyISAM; + +CREATE TABLE IF NOT EXISTS `npc_expanded_barter_data` ( + `name` VARCHAR(24) NOT NULL DEFAULT '', + `itemId` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `zeny` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyId1` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount1` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine1` INT(11) NOT NULL DEFAULT '0', + `currencyId2` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount2` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine2` INT(11) NOT NULL DEFAULT '0', + `currencyId3` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount3` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine3` INT(11) NOT NULL DEFAULT '0', + `currencyId4` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount4` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine4` INT(11) NOT NULL DEFAULT '0', + `currencyId5` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount5` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine5` INT(11) NOT NULL DEFAULT '0', + `currencyId6` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount6` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine6` INT(11) NOT NULL DEFAULT '0', + `currencyId7` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount7` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine7` INT(11) NOT NULL DEFAULT '0', + `currencyId8` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount8` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine8` INT(11) NOT NULL DEFAULT '0', + `currencyId9` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount9` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine9` INT(11) NOT NULL DEFAULT '0', + `currencyId10` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount10` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine10` INT(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`name`, `itemid`, `zeny`, + `currencyId1`, `currencyAmount1`, `currencyRefine1`, + `currencyId2`, `currencyAmount2`, `currencyRefine2`, + `currencyId3`, `currencyAmount3`, `currencyRefine3`, + `currencyId4`, `currencyAmount4`, `currencyRefine4` +) +) ENGINE=MyISAM; diff --git a/sql-files/mob_db_re.sql b/sql-files/mob_db_re.sql index 80f5677e3..713054e9c 100644 --- a/sql-files/mob_db_re.sql +++ b/sql-files/mob_db_re.sql @@ -1412,6 +1412,7 @@ REPLACE INTO `mob_db` VALUES (2410,'DUMMY_100','Lv 100','Lv 100',100,99999999,1, REPLACE INTO `mob_db` VALUES (2411,'DUMMY_150','Lv 150','Lv 150',150,99999999,1,0,0,0,0,0,120,120,0,0,0,0,0,0,1,1,1,0,20,32768,200,398,199,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); REPLACE INTO `mob_db` VALUES (2413,'DUMMY_10_FIRE','Lv 10 (Fire)','Lv 10 (Fire)',10,99999999,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,23,32768,200,398,199,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); REPLACE INTO `mob_db` VALUES (2414,'RUNAWAY_BOOK','Runaway Book','Runaway Book',1,10,1,1,1,1,6,9,1,1,1,1,1,0,1,1,10,12,0,0,20,12417,150,864,500,192,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); +REPLACE INTO `mob_db` VALUES (2431,'G_L_SHECIL','Hunter Shecil','Hunter Shecil',98,8835,1,0,0,14,574,223,68,13,108,113,60,72,148,37,10,12,1,7,64,14469,160,432,400,288,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); REPLACE INTO `mob_db` VALUES (2464,'MG_ZOMBIE','Corrupted Steward','Corrupted Steward',130,135600,1,13332,15998,1,2364,444,15,15,44,22,77,25,88,22,10,12,1,1,29,14741,400,2612,912,288,0,0,0,0,0,0,0,6609,1000,6610,1000,6608,10,938,1000,727,500,6755,500,0,0,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (2465,'MG_WRAITH','Corrupted Monk','Corrupted Monk',133,100168,1,13998,16796,1,999,2787,80,200,16,26,30,115,79,5,10,12,2,1,89,14229,300,1816,576,240,0,0,0,0,0,0,0,731,100,747,500,2206,100,6608,10,6609,1000,6610,1000,6755,500,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (2466,'MG_GHOUL','Grand Chamberlain in Pa','Grand Chamberlain in Pa',132,208100,1,14222,17066,1,2965,666,30,30,88,44,88,21,95,44,10,12,1,1,49,14741,250,2456,912,504,0,0,0,0,0,0,0,756,100,2609,100,6608,10,6609,1000,6610,1000,7751,1000,6755,500,0,0,0,0,0,0); @@ -1808,6 +1809,8 @@ REPLACE INTO `mob_db` VALUES (2961,'E_TORTUROUS_REDEEMER','Torturous Redeemer',' REPLACE INTO `mob_db` VALUES (2996,'XM_CELINE_KIMI','Celine Kimi','Celine Kimi',160,66666666,1,4444444,4033332,2,5636,8303,479,444,144,166,44,444,166,166,10,12,2,1,28,13973,100,1056,1056,480,444444,616,10000,617,10000,22534,10000,22534,4000,18549,4000,7642,4000,19701,100,13442,100,712,10000,0,0,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (3029,'GRIM_REAPER_ANKOU','Grim Reaper Ankou','Grim Reaper Ankou',159,50000000,1553,300000,330000,1,1500,2500,200,70,200,100,200,200,220,100,10,12,2,1,89,133,200,900,864,480,0,0,0,0,0,0,0,607,500,603,200,604,200,22537,10000,522,200,0,0,0,0,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (3074,'TIMEHOLDER','Time Holder','Time Holder',170,25000000,1,2291250,1938750,1,5250,2100,288,265,224,152,251,257,402,77,10,12,2,6,80,14261,100,398,384,288,2291250,0,0,0,0,0,0,1095,3000,2121,10,7054,3000,22515,3000,18874,20,16024,5,15089,3,0,0,0,0,4625,1); +REPLACE INTO `mob_db` VALUES (3169,'J_REB_SHECIL1','Shooting Target','Shooting Target',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,1,200,4000,2000,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); +REPLACE INTO `mob_db` VALUES (3170,'J_REB_SHECIL2','Shooting Target','Shooting Target',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,1,200,4000,2000,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); REPLACE INTO `mob_db` VALUES (3181,'E1_FELOCK','Captain Ferlock','Captain Ferlock',130,3000000,1,3088,333333,10,0,0,0,0,0,0,0,0,0,0,10,12,2,9,47,129,170,1018,1008,300,0,0,0,0,0,0,0,15117,100,20744,100,22047,100,12082,3000,12072,3000,12087,3000,12077,3000,12092,3000,0,0,27182,1); REPLACE INTO `mob_db` VALUES (3190,'MM_SARAH','Sarah','Sarah',160,100000000,1,0,0,12,1090,2755,276,255,43,161,6,188,225,136,10,12,1,0,20,164,2000,500,500,0,0,0,0,0,0,0,0,15121,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4610,1); REPLACE INTO `mob_db` VALUES (3202,'ORGANIC_JAKK','Organic Pumpkin','Organic Pumpkin',10,40,1,20,13,1,100,0,160,99,1,1,1,1,999,1,1,1,0,3,21,97,200,398,199,0,0,0,0,0,0,0,0,6804,5000,6804,5000,6804,1000,2267,100,1062,1000,664,100,546,1000,12192,100,0,0,0,0); diff --git a/sql-files/upgrades/2020-01-24--01-09.sql b/sql-files/upgrades/2020-01-24--01-09.sql new file mode 100644 index 000000000..2370b267f --- /dev/null +++ b/sql-files/upgrades/2020-01-24--01-09.sql @@ -0,0 +1,63 @@ +#1579817630 + +-- This file is part of Hercules. +-- http://herc.ws - http://github.com/HerculesWS/Hercules +-- +-- Copyright (C) 2013-2020 Hercules Dev Team +-- +-- Hercules is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +CREATE TABLE IF NOT EXISTS `npc_expanded_barter_data` ( + `name` VARCHAR(24) NOT NULL DEFAULT '', + `itemId` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `zeny` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyId1` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount1` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine1` INT(11) NOT NULL DEFAULT '0', + `currencyId2` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount2` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine2` INT(11) NOT NULL DEFAULT '0', + `currencyId3` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount3` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine3` INT(11) NOT NULL DEFAULT '0', + `currencyId4` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount4` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine4` INT(11) NOT NULL DEFAULT '0', + `currencyId5` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount5` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine5` INT(11) NOT NULL DEFAULT '0', + `currencyId6` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount6` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine6` INT(11) NOT NULL DEFAULT '0', + `currencyId7` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount7` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine7` INT(11) NOT NULL DEFAULT '0', + `currencyId8` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount8` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine8` INT(11) NOT NULL DEFAULT '0', + `currencyId9` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount9` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine9` INT(11) NOT NULL DEFAULT '0', + `currencyId10` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyAmount10` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `currencyRefine10` INT(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`name`, `itemid`, `zeny`, + `currencyId1`, `currencyAmount1`, `currencyRefine1`, + `currencyId2`, `currencyAmount2`, `currencyRefine2`, + `currencyId3`, `currencyAmount3`, `currencyRefine3`, + `currencyId4`, `currencyAmount4`, `currencyRefine4` +) +) ENGINE=MyISAM; +INSERT INTO `sql_updates` (`timestamp`) VALUES (1579817630); diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt index f7fc2ac79..1ddd8b831 100644 --- a/sql-files/upgrades/index.txt +++ b/sql-files/upgrades/index.txt @@ -59,3 +59,4 @@ 2019-10-05--19-01.sql 2019-10-12--14-21.sql 2019-11-22--23-58.sql +2020-01-24--01-09.sql diff --git a/src/char/int_party.c b/src/char/int_party.c index b29ccaf24..c16eea34e 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -42,82 +42,139 @@ static struct inter_party_interface inter_party_s; struct inter_party_interface *inter_party; -//Updates party's level range and unsets even share if broken. +/** + * Updates party's level range and disables even share if requirements are not fulfilled. + * + * @param p The party. + * @return 0 on failure, 1 on success. + * + **/ static int inter_party_check_lv(struct party_data *p) { - int i; - unsigned int lv; nullpo_ret(p); - p->min_lv = UINT_MAX; - p->max_lv = 0; - for(i=0;i<MAX_PARTY;i++){ - /** - * - If not online OR if it's a family party and this is the child (doesn't affect exp range) - **/ - if(!p->party.member[i].online || p->party.member[i].char_id == p->family ) - continue; - lv=p->party.member[i].lv; - if (lv < p->min_lv) p->min_lv = lv; - if (lv > p->max_lv) p->max_lv = lv; + p->min_lv = MAX_LEVEL; + p->max_lv = 1; + + for (int i = 0; i < MAX_PARTY; i++) { + if (p->party.member[i].online == 0 || p->party.member[i].char_id == p->family) + continue; /// If not online OR if it's a family party and this is the child, don't affect exp range. + + p->min_lv = min(p->min_lv, p->party.member[i].lv); + p->max_lv = max(p->max_lv, p->party.member[i].lv); } - if (p->party.exp && !inter_party->check_exp_share(p)) { + if (p->party.exp == 1 && inter_party->check_exp_share(p) == 0) { p->party.exp = 0; mapif->party_optionchanged(0, &p->party, 0, 0); return 0; } + return 1; } -//Calculates the state of a party. + +/** + * Checks if a party is a family state party. (Family share feature.) + * Conditions for a family state party: + * - All party members have to belong to the same family. Not even offline strangers are allowed. + * So only parties with 2 or 3 members come in question. + * - At least one parent has to be on the same map with the child. + * - Parents within the party have to be level 70 or higher, even when offline. + * + * @param p The party. + * @return The child's char ID on success, otherwise 0. + * + **/ +static int inter_party_is_family_party(struct party_data *p) +{ + nullpo_ret(p); + + if (p->size < 2 || p->size > 3 || p->party.count < 2) + return 0; + + int child_id = 0; + + for (int i = 0; i < MAX_PARTY - 1; i++) { + if (p->party.member[i].online == 0) + continue; + + struct mmo_charstatus *char_i = idb_get(chr->char_db_, p->party.member[i].char_id); + + if (char_i == NULL) + continue; + + for (int j = i + 1; j < MAX_PARTY; j++) { + if (p->party.member[j].online == 0) + continue; + + struct mmo_charstatus *char_j = idb_get(chr->char_db_, p->party.member[j].char_id); + + if (char_j == NULL) + continue; + + if (p->party.member[i].map != p->party.member[j].map) + continue; + + if (char_i->char_id == char_j->child && char_j->base_level >= 70) + child_id = char_i->char_id; + + if (char_j->char_id == char_i->child && char_i->base_level >= 70) + child_id = char_j->char_id; + + if (child_id != 0) + break; + } + + if (child_id != 0) + break; + } + + if (child_id != 0 && p->size > 2) { + for (int i = 0; i < MAX_PARTY; i++) { + struct mmo_charstatus *party_member = idb_get(chr->char_db_, p->party.member[i].char_id); + + /// Check if there is a stranger within the party. + if (party_member != NULL && party_member->char_id != child_id && party_member->child != child_id) { + child_id = 0; /// Stranger detected. + break; + } + + /// Check if there is a parents with level lower than 70 within the party. + if (party_member != NULL && party_member->child == child_id && party_member->base_level < 70) { + child_id = 0; /// Parent with level lower than 70 detected. + break; + } + } + } + + return child_id; +} + +/** + * Calculates the state of a party. + * + * @param p The party. + * + **/ static void inter_party_calc_state(struct party_data *p) { - int i; nullpo_retv(p); - p->min_lv = UINT_MAX; - p->max_lv = 0; - p->party.count = - p->size = - p->family = 0; - - //Check party size - for(i=0;i<MAX_PARTY;i++){ - if (!p->party.member[i].lv) continue; + + p->party.count = 0; + p->size = 0; + + for (int i = 0; i < MAX_PARTY; i++) { + if (p->party.member[i].lv == 0) /// Is this even possible? [Kenpachi] + continue; + p->size++; - if(p->party.member[i].online) + + if (p->party.member[i].online == 1) p->party.count++; } - // FIXME[Haru]: What if the occupied positions aren't the first three? It can happen if some party members leave. This is the reason why family sharing some times stops working until you recreate your party - if( p->size == 2 && ( chr->char_child(p->party.member[0].char_id,p->party.member[1].char_id) || chr->char_child(p->party.member[1].char_id,p->party.member[0].char_id) ) ) { - //Child should be able to share with either of their parents [RoM] - if (p->party.member[0].class >= JOB_BABY && p->party.member[0].class <= JOB_SUPER_BABY) //first slot is the child? - p->family = p->party.member[0].char_id; - else - p->family = p->party.member[1].char_id; - } else if( p->size == 3 ) { - //Check Family State. - p->family = chr->char_family( - p->party.member[0].char_id, - p->party.member[1].char_id, - p->party.member[2].char_id - ); - } - //max/min levels. - for (i = 0; i < MAX_PARTY; i++) { - unsigned int lv = p->party.member[i].lv; - if (!lv) continue; - if (p->party.member[i].online - && p->party.member[i].char_id != p->family /* In families, the kid is not counted towards exp share rules. */ - ) { - if( lv < p->min_lv ) p->min_lv=lv; - if( p->max_lv < lv ) p->max_lv=lv; - } - } - if (p->party.exp && !inter_party->check_exp_share(p)) { - p->party.exp = 0; //Set off even share. - mapif->party_optionchanged(0, &p->party, 0, 0); - } + p->family = inter_party->is_family_party(p); + inter_party->check_lv(p); } // Save party to mysql @@ -195,6 +252,39 @@ static int inter_party_tosql(struct party *p, int flag, int index) return 1; } +/** + * Updates the `char`.`party_id` column and removes party data from memory. + * Sets the party ID of all characters whose party ID matches the passed one to 0. + * Calls idb_remove() to remove party data from memory. + * + * @param party_id The party ID. + * @return 0 on failure, 1 on success. + * + **/ +static int inter_party_del_nonexistent_party(int party_id) +{ + struct SqlStmt *stmt = SQL->StmtMalloc(inter->sql_handle); + + if (stmt == NULL) { + SqlStmt_ShowDebug(stmt); + return 0; + } + + const char *query = "UPDATE `%s` SET `party_id`='0' WHERE `party_id`=?"; + + if (SQL_ERROR == SQL->StmtPrepare(stmt, query, char_db) + || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_UINT32, &party_id, sizeof(party_id)) + || SQL_ERROR == SQL->StmtExecute(stmt)) { + SqlStmt_ShowDebug(stmt); + SQL->StmtFree(stmt); + return 0; + } + + idb_remove(inter_party->db, party_id); + + return 1; +} + // Read party from mysql static struct party_data *inter_party_fromsql(int party_id) { @@ -313,11 +403,18 @@ static struct party_data *inter_party_search_partyname(const char *const str) return p; } -// Returns whether this party can keep having exp share or not. +/** + * Checks if a party fulfills the requirements to share EXP. + * + * @param p The party. + * @return 1 if party can share EXP, otherwise 0. + * + **/ static int inter_party_check_exp_share(struct party_data *const p) { nullpo_ret(p); - return (p->party.count < 2 || p->max_lv - p->min_lv <= party_share_level); + + return (p->party.count < 2 || p->family != 0 || p->max_lv - p->min_lv <= party_share_level); } // Is there any member in the party? @@ -388,36 +485,38 @@ static struct party_data *inter_party_create(const char *name, int item, int ite return p; } -// Add a player to party request +/** + * Add a player to party request. + * + * @param party_id The ID of the party. + * @param member The member to add. + * @return true on success, otherwise false. + * + **/ static bool inter_party_add_member(int party_id, const struct party_member *member) { - struct party_data *p; - int i; + nullpo_retr(false, member); - nullpo_ret(member); - p = inter_party->fromsql(party_id); - if( p == NULL || p->size == MAX_PARTY ) { + if (party_id < 1) /// Invalid party ID. return false; - } - ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == 0 ); - if (i == MAX_PARTY) { - // Party full + struct party_data *p = inter_party->fromsql(party_id); + + if (p == NULL) { /// Party does not exist. + inter_party->del_nonexistent_party(party_id); return false; } + int i; + + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == 0); + + if (i == MAX_PARTY) /// Party is full. + return false; + memcpy(&p->party.member[i], member, sizeof(struct party_member)); p->party.member[i].leader = 0; - if (p->party.member[i].online) p->party.count++; - p->size++; - if (p->size == 2 || p->size == 3) // Check family state. And also accept either of their Parents. [RoM] - inter_party->calc_state(p); - else //Check even share range. - if (member->lv < p->min_lv || member->lv > p->max_lv || p->family) { - if (p->family) p->family = 0; //Family state broken. - inter_party->check_lv(p); - } - + inter_party->calc_state(p); /// Count online/offline members and check family state and even share range. mapif->party_info(-1, &p->party, 0); inter_party->tosql(&p->party, PS_ADDMEMBER, i); @@ -445,105 +544,92 @@ static bool inter_party_change_option(int party_id, int account_id, int exp, int return true; } -//Request leave party +/** + * Leave party request. + * + * @param party_id The ID of the party. + * @param account_id The account ID of the leaving character. + * @param char_id The char ID of the leaving character. + * @return true on success, otherwise false. + * + **/ static bool inter_party_leave(int party_id, int account_id, int char_id) { - struct party_data *p; - int i,j; + if (party_id < 1) /// Invalid party ID. + return false; - p = inter_party->fromsql(party_id); - if( p == NULL ) - {// Party does not exists? - if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) ) - Sql_ShowDebug(inter->sql_handle); + struct party_data *p = inter_party->fromsql(party_id); + + if (p == NULL) { /// Party does not exist. + inter_party->del_nonexistent_party(party_id); return false; } - for (i = 0; i < MAX_PARTY; i++) { - if(p->party.member[i].account_id == account_id && - p->party.member[i].char_id == char_id) { - break; - } - } - if (i >= MAX_PARTY) - return false; //Member not found? + int i; + + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id); + + if (i == MAX_PARTY) /// Character not found in party. + return false; mapif->party_withdraw(party_id, account_id, char_id); - j = p->party.member[i].lv; - if (p->party.member[i].online > 0) { + if (p->party.member[i].online == 1) p->party.member[i].online = 0; - p->party.count--; - } - inter_party->tosql(&p->party, PS_DELMEMBER, i); + memset(&p->party.member[i], 0, sizeof(struct party_member)); - p->size--; - if (j == p->min_lv || j == p->max_lv || p->family) { - if(p->family) p->family = 0; //Family state broken. - inter_party->check_lv(p); - } + inter_party->calc_state(p); /// Count online/offline members and check family state and even share range. + inter_party->tosql(&p->party, PS_DELMEMBER, i); - if (inter_party->check_empty(p) == 0) { + if (inter_party->check_empty(p) == 0) mapif->party_info(-1, &p->party, 0); - } + return true; } -// When member goes to other map or levels up. -static bool inter_party_change_map(int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv) +/** + * Updates party data if a member changes map or levels up. + * + * @param party_id The ID of the party. + * @param account_id The character's account ID. + * @param char_id The character's char ID. + * @param map The character's map index. + * @param online The character's online state. + * @param lv The character's level. + * @return true on success, otherwise false. + * + **/ +static bool inter_party_change_map(int party_id, int account_id, int char_id, unsigned short map, int online, int lv) { - struct party_data *p; - int i; + if (party_id < 1) /// Invalid party ID. + return false; - p = inter_party->fromsql(party_id); - if (p == NULL) + struct party_data *p = inter_party->fromsql(party_id); + + if (p == NULL) { /// Party does not exist. + inter_party->del_nonexistent_party(party_id); return false; + } + + int i; - for(i = 0; i < MAX_PARTY && - (p->party.member[i].account_id != account_id || - p->party.member[i].char_id != char_id); i++); + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id); - if (i == MAX_PARTY) + if (i == MAX_PARTY) /// Character not found in party. return false; if (p->party.member[i].online != online) - { p->party.member[i].online = online; - if (online) - p->party.count++; - else - p->party.count--; - // Even share check situations: Family state (always breaks) - // character logging on/off is max/min level (update level range) - // or character logging on/off has a different level (update level range using new level) - if (p->family || - (p->party.member[i].lv <= p->min_lv || p->party.member[i].lv >= p->max_lv) || - (p->party.member[i].lv != lv && (lv <= p->min_lv || lv >= p->max_lv)) - ) - { - p->party.member[i].lv = lv; - inter_party->check_lv(p); - } - //Send online/offline update. - mapif->party_membermoved(&p->party, i); - } - if (p->party.member[i].lv != lv) { - if(p->party.member[i].lv == p->min_lv || - p->party.member[i].lv == p->max_lv) - { - p->party.member[i].lv = lv; - inter_party->check_lv(p); - } else - p->party.member[i].lv = lv; - //There is no need to send level update to map servers - //since they do nothing with it. - } + if (p->party.member[i].lv != lv) + p->party.member[i].lv = lv; - if (p->party.member[i].map != map) { + if (p->party.member[i].map != map) p->party.member[i].map = map; - mapif->party_membermoved(&p->party, i); - } + + inter_party->calc_state(p); /// Count online/offline members and check family state and even share range. + mapif->party_membermoved(&p->party, i); /// Send online/offline update. + return true; } @@ -607,98 +693,104 @@ static int inter_party_parse_frommap(int fd) return 1; } +/** + * Sets the online state of a charcter within a party to online. + * + * @param char_id The character's char ID. + * @param party_id The ID of the party. + * @return 1 on success, otherwise 0. + * + **/ static int inter_party_CharOnline(int char_id, int party_id) { - struct party_data* p; - int i; - - if( party_id == -1 ) - {// Get party_id from the database + if (party_id == INDEX_NOT_FOUND) { /// Get party_id from the database. char* data; - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) ) - { + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) { Sql_ShowDebug(inter->sql_handle); return 0; } - if( SQL_SUCCESS != SQL->NextRow(inter->sql_handle) ) - return 0; //Eh? No party? + if (SQL_SUCCESS != SQL->NextRow(inter->sql_handle)) + return 0; SQL->GetData(inter->sql_handle, 0, &data, NULL); party_id = atoi(data); SQL->FreeResult(inter->sql_handle); } - if (party_id == 0) - return 0; //No party... - p = inter_party->fromsql(party_id); - if(!p) { - ShowError("Character %d's party %d not found!\n", char_id, party_id); + if (party_id == 0) /// Character isn't member of a party. return 0; - } - //Set member online - for(i=0; i<MAX_PARTY; i++) { - if (p->party.member[i].char_id == char_id) { - if (!p->party.member[i].online) { - p->party.member[i].online = 1; - p->party.count++; - if (p->party.member[i].lv < p->min_lv || - p->party.member[i].lv > p->max_lv) - inter_party->check_lv(p); - } - break; - } + struct party_data *p = inter_party->fromsql(party_id); + + if (p == NULL) { /// Party does not exist. + inter_party->del_nonexistent_party(party_id); + return 0; } + + int i; + + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].char_id == char_id); + + if (i == MAX_PARTY) /// Character not found in party. + return 0; + + p->party.member[i].online = 1; /// Set member online. + inter_party->calc_state(p); /// Count online/offline members and check family state and even share range. + return 1; } +/** + * Sets the online state of a charcter within a party to offline. + * + * @param char_id The character's char ID. + * @param party_id The ID of the party. + * @return 1 on success, otherwise 0. + * + **/ static int inter_party_CharOffline(int char_id, int party_id) { - struct party_data *p=NULL; - int i; - - if( party_id == -1 ) - {// Get guild_id from the database + if (party_id == INDEX_NOT_FOUND) { /// Get party_id from the database. char* data; - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) ) - { + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) { Sql_ShowDebug(inter->sql_handle); return 0; } - if( SQL_SUCCESS != SQL->NextRow(inter->sql_handle) ) - return 0; //Eh? No party? + if (SQL_SUCCESS != SQL->NextRow(inter->sql_handle)) + return 0; SQL->GetData(inter->sql_handle, 0, &data, NULL); party_id = atoi(data); SQL->FreeResult(inter->sql_handle); } - if (party_id == 0) - return 0; //No party... - //Character has a party, set character offline and check if they were the only member online - if ((p = inter_party->fromsql(party_id)) == NULL) + if (party_id == 0) /// Character isn't member of a party. return 0; - //Set member offline - for(i=0; i< MAX_PARTY; i++) { - if(p->party.member[i].char_id == char_id) - { - p->party.member[i].online = 0; - p->party.count--; - if(p->party.member[i].lv == p->min_lv || - p->party.member[i].lv == p->max_lv) - inter_party->check_lv(p); - break; - } + struct party_data *p = inter_party->fromsql(party_id); + + if (p == NULL) { /// Party does not exist. + inter_party->del_nonexistent_party(party_id); + return 0; } - if(!p->party.count) - //Parties don't have any data that needs be saved at this point... so just remove it from memory. + int i; + + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].char_id == char_id); + + if (i == MAX_PARTY) /// Character not found in party. + return 0; + + p->party.member[i].online = 0; /// Set member offline. + inter_party->calc_state(p); /// Count online/offline members and check family state and even share range. + + if (p->party.count == 0) /// Parties don't have any data that needs be saved at this point... so just remove it from memory. idb_remove(inter_party->db, party_id); + return 1; } @@ -712,8 +804,10 @@ void inter_party_defaults(void) inter_party->sql_init = inter_party_sql_init; inter_party->sql_final = inter_party_sql_final; inter_party->check_lv = inter_party_check_lv; + inter_party->is_family_party = inter_party_is_family_party; inter_party->calc_state = inter_party_calc_state; inter_party->tosql = inter_party_tosql; + inter_party->del_nonexistent_party = inter_party_del_nonexistent_party; inter_party->fromsql = inter_party_fromsql; inter_party->search_partyname = inter_party_search_partyname; inter_party->check_exp_share = inter_party_check_exp_share; diff --git a/src/char/int_party.h b/src/char/int_party.h index b3306cc13..0385b0e87 100644 --- a/src/char/int_party.h +++ b/src/char/int_party.h @@ -38,10 +38,11 @@ enum { }; struct party_data { - struct party party; - unsigned int min_lv, max_lv; - int family; //Is this party a family? if so, this holds the child id. - unsigned char size; //Total size of party. + struct party party; // Party data. + int min_lv; // The lowest base level of all party members. + int max_lv; // The highest base level of all party members. + int family; // Is this party a family? If so, this holds the child's char ID. + int size; // Amount of party members, including offline members. }; /** @@ -51,8 +52,10 @@ struct inter_party_interface { struct party_data *pt; struct DBMap *db; // int party_id -> struct party_data* int (*check_lv) (struct party_data *p); + int (*is_family_party) (struct party_data *p); void (*calc_state) (struct party_data *p); int (*tosql) (struct party *p, int flag, int index); + int (*del_nonexistent_party) (int party_id); struct party_data* (*fromsql) (int party_id); int (*sql_init) (void); void (*sql_final) (void); @@ -66,7 +69,7 @@ struct inter_party_interface { struct party_data *(*create) (const char *name, int item, int item2, const struct party_member *leader); bool (*add_member) (int party_id, const struct party_member *member); bool (*change_option) (int party_id, int account_id, int exp, int item, int map_fd); - bool (*change_map) (int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv); + bool (*change_map) (int party_id, int account_id, int char_id, unsigned short map, int online, int lv); bool (*disband) (int party_id); bool (*change_leader) (int party_id, int account_id, int char_id); }; diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index a0a9f8c35..11f79a11b 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -600,6 +600,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { #endif // MAP_MOB_H #ifdef MAP_NPC_H { "event_data", sizeof(struct event_data), SERVER_TYPE_MAP }, + { "npc_barter_currency", sizeof(struct npc_barter_currency), SERVER_TYPE_MAP }, { "npc_chat_interface", sizeof(struct npc_chat_interface), SERVER_TYPE_MAP }, { "npc_data", sizeof(struct npc_data), SERVER_TYPE_MAP }, { "npc_interface", sizeof(struct npc_interface), SERVER_TYPE_MAP }, @@ -743,6 +744,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "PACKET_ZC_SKILLINFO_LIST", sizeof(struct PACKET_ZC_SKILLINFO_LIST), SERVER_TYPE_MAP }, { "PACKET_ZC_SKILLINFO_UPDATE2", sizeof(struct PACKET_ZC_SKILLINFO_UPDATE2), SERVER_TYPE_MAP }, { "PACKET_ZC_SPRITE_CHANGE", sizeof(struct PACKET_ZC_SPRITE_CHANGE), SERVER_TYPE_MAP }, + { "PACKET_ZC_STATE_CHANGE", sizeof(struct PACKET_ZC_STATE_CHANGE), SERVER_TYPE_MAP }, { "PACKET_ZC_STATUS_CHANGE_ACK", sizeof(struct PACKET_ZC_STATUS_CHANGE_ACK), SERVER_TYPE_MAP }, { "PACKET_ZC_STYLE_CHANGE_RES", sizeof(struct PACKET_ZC_STYLE_CHANGE_RES), SERVER_TYPE_MAP }, { "PACKET_ZC_TALKBOX_CHATCONTENTS", sizeof(struct PACKET_ZC_TALKBOX_CHATCONTENTS), SERVER_TYPE_MAP }, diff --git a/src/common/mmo.h b/src/common/mmo.h index ec1b2948a..687f5a187 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -218,7 +218,7 @@ #define MAX_FAME 1000000000 #define MAX_CART 100 #ifndef MAX_SKILL_DB -#define MAX_SKILL_DB 1510 ///< Maximum number of skills in the skill DB (compacted array size) +#define MAX_SKILL_DB 1314 ///< Maximum number of skills in the skill DB (compacted array size) #endif #ifndef MAX_SKILL_ID #define MAX_SKILL_ID 10015 // [Ind/Hercules] max used skill ID @@ -822,8 +822,8 @@ struct party_member { int char_id; char name[NAME_LENGTH]; int class; + int lv; unsigned short map; - unsigned short lv; unsigned leader : 1, online : 1; }; diff --git a/src/common/packets/packets2020_len_main.h b/src/common/packets/packets2020_len_main.h index a85cddb29..3349c9872 100644 --- a/src/common/packets/packets2020_len_main.h +++ b/src/common/packets/packets2020_len_main.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2018-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2018-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -4611,5 +4611,25 @@ packetLen(0x0b6d, 6) // Packet: 0x0b6e packetLen(0x0b6e, 14) +// Packet: 0x0b6f +#if PACKETVER >= 20200122 +packetLen(0x0b6f, 177) +#endif + +// Packet: 0x0b70 +#if PACKETVER >= 20200122 +packetLen(0x0b70, 8) +#endif + +// Packet: 0x0b71 +#if PACKETVER >= 20200122 +packetLen(0x0b71, 177) +#endif + +// Packet: 0x0b72 +#if PACKETVER >= 20200122 +packetLen(0x0b72, 4) +#endif + #endif /* COMMON_PACKETS2020_LEN_MAIN_H */ diff --git a/src/common/packets/packets2020_len_re.h b/src/common/packets/packets2020_len_re.h index 6e72cbb7d..b33278c1c 100644 --- a/src/common/packets/packets2020_len_re.h +++ b/src/common/packets/packets2020_len_re.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2018-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2018-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -4617,5 +4617,25 @@ packetLen(0x0b6d, 6) // Packet: 0x0b6e packetLen(0x0b6e, 14) +// Packet: 0x0b6f +#if PACKETVER >= 20200122 +packetLen(0x0b6f, 177) +#endif + +// Packet: 0x0b70 +#if PACKETVER >= 20200122 +packetLen(0x0b70, 8) +#endif + +// Packet: 0x0b71 +#if PACKETVER >= 20200122 +packetLen(0x0b71, 177) +#endif + +// Packet: 0x0b72 +#if PACKETVER >= 20200122 +packetLen(0x0b72, 4) +#endif + #endif /* COMMON_PACKETS2020_LEN_RE_H */ diff --git a/src/common/packets/packets2020_len_zero.h b/src/common/packets/packets2020_len_zero.h new file mode 100644 index 000000000..153b66286 --- /dev/null +++ b/src/common/packets/packets2020_len_zero.h @@ -0,0 +1,4635 @@ +/** + * This file is part of Hercules. + * http://herc.ws - http://github.com/HerculesWS/Hercules + * + * Copyright (C) 2018-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) + * + * Hercules is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef COMMON_PACKETS2020_LEN_ZERO_H +#define COMMON_PACKETS2020_LEN_ZERO_H + +/* This file is autogenerated, please do not commit manual changes */ + +// Packet: 0x0064 +packetLen(0x0064, 55) + +// Packet: 0x0065 +packetLen(0x0065, 17) + +// Packet: 0x0066 +packetLen(0x0066, 3) + +// Packet: 0x0067 +packetLen(0x0067, 37) + +// Packet: 0x0068 +packetLen(0x0068, 46) + +// Packet: 0x0069 +packetLen(0x0069, -1) + +// Packet: 0x006a +packetLen(0x006a, 23) + +// Packet: 0x006b +packetLen(0x006b, -1) + +// Packet: 0x006c +packetLen(0x006c, 3) + +// Packet: 0x006d +packetLen(0x006d, 157) + +// Packet: 0x006e +packetLen(0x006e, 3) + +// Packet: 0x006f +packetLen(0x006f, 2) + +// Packet: 0x0070 +packetLen(0x0070, 3) + +// Packet: 0x0071 +packetLen(0x0071, 28) + +// Packet: 0x0072 +packetLen(0x0072, 22) + +// Packet: 0x0073 +packetLen(0x0073, 11) + +// Packet: 0x0074 +packetLen(0x0074, 3) + +// Packet: 0x0075 +packetLen(0x0075, -1) + +// Packet: 0x0076 +packetLen(0x0076, 9) + +// Packet: 0x0077 +packetLen(0x0077, 5) + +// Packet: 0x0078 +packetLen(0x0078, 55) + +// Packet: 0x0079 +packetLen(0x0079, 53) + +// Packet: 0x007a +packetLen(0x007a, 58) + +// Packet: 0x007b +packetLen(0x007b, 60) + +// Packet: 0x007c +packetLen(0x007c, 44) + +// Packet: 0x007d +packetLen(0x007d, 2) + +// Packet: 0x007e +packetLen(0x007e, 46) + +// Packet: 0x007f +packetLen(0x007f, 6) + +// Packet: 0x0080 +packetLen(0x0080, 7) + +// Packet: 0x0081 +packetLen(0x0081, 3) + +// Packet: 0x0082 +packetLen(0x0082, 2) + +// Packet: 0x0083 +packetLen(0x0083, 2) + +// Packet: 0x0084 +packetLen(0x0084, 2) + +// Packet: 0x0085 +packetLen(0x0085, 10) + +// Packet: 0x0086 +packetLen(0x0086, 16) + +// Packet: 0x0087 +packetLen(0x0087, 12) + +// Packet: 0x0088 +packetLen(0x0088, 10) + +// Packet: 0x0089 +packetLen(0x0089, 11) + +// Packet: 0x008a +packetLen(0x008a, 29) + +// Packet: 0x008b +packetLen(0x008b, 23) + +// Packet: 0x008c +packetLen(0x008c, 14) + +// Packet: 0x008d +packetLen(0x008d, -1) + +// Packet: 0x008e +packetLen(0x008e, -1) + +// Packet: 0x0090 +packetLen(0x0090, 7) + +// Packet: 0x0091 +packetLen(0x0091, 22) + +// Packet: 0x0092 +packetLen(0x0092, 28) + +// Packet: 0x0093 +packetLen(0x0093, 2) + +// Packet: 0x0094 +packetLen(0x0094, 19) + +// Packet: 0x0095 +packetLen(0x0095, 30) + +// Packet: 0x0096 +packetLen(0x0096, -1) + +// Packet: 0x0097 +packetLen(0x0097, -1) + +// Packet: 0x0098 +packetLen(0x0098, 3) + +// Packet: 0x0099 +packetLen(0x0099, -1) + +// Packet: 0x009a +packetLen(0x009a, -1) + +// Packet: 0x009b +packetLen(0x009b, 34) + +// Packet: 0x009c +packetLen(0x009c, 9) + +// Packet: 0x009d +packetLen(0x009d, 19) + +// Packet: 0x009e +packetLen(0x009e, 19) + +// Packet: 0x009f +packetLen(0x009f, 20) + +// Packet: 0x00a0 +packetLen(0x00a0, 33) + +// Packet: 0x00a1 +packetLen(0x00a1, 6) + +// Packet: 0x00a2 +packetLen(0x00a2, 14) + +// Packet: 0x00a3 +packetLen(0x00a3, -1) + +// Packet: 0x00a4 +packetLen(0x00a4, -1) + +// Packet: 0x00a5 +packetLen(0x00a5, -1) + +// Packet: 0x00a6 +packetLen(0x00a6, -1) + +// Packet: 0x00a7 +packetLen(0x00a7, 9) + +// Packet: 0x00a8 +packetLen(0x00a8, 7) + +// Packet: 0x00a9 +packetLen(0x00a9, 6) + +// Packet: 0x00aa +packetLen(0x00aa, 9) + +// Packet: 0x00ab +packetLen(0x00ab, 4) + +// Packet: 0x00ac +packetLen(0x00ac, 7) + +// Packet: 0x00ae +packetLen(0x00ae, -1) + +// Packet: 0x00af +packetLen(0x00af, 6) + +// Packet: 0x00b0 +packetLen(0x00b0, 8) + +// Packet: 0x00b1 +packetLen(0x00b1, 8) + +// Packet: 0x00b2 +packetLen(0x00b2, 3) + +// Packet: 0x00b3 +packetLen(0x00b3, 3) + +// Packet: 0x00b4 +packetLen(0x00b4, -1) + +// Packet: 0x00b5 +packetLen(0x00b5, 6) + +// Packet: 0x00b6 +packetLen(0x00b6, 6) + +// Packet: 0x00b7 +packetLen(0x00b7, -1) + +// Packet: 0x00b8 +packetLen(0x00b8, 7) + +// Packet: 0x00b9 +packetLen(0x00b9, 6) + +// Packet: 0x00ba +packetLen(0x00ba, 2) + +// Packet: 0x00bb +packetLen(0x00bb, 5) + +// Packet: 0x00bc +packetLen(0x00bc, 6) + +// Packet: 0x00bd +packetLen(0x00bd, 44) + +// Packet: 0x00be +packetLen(0x00be, 5) + +// Packet: 0x00bf +packetLen(0x00bf, 3) + +// Packet: 0x00c0 +packetLen(0x00c0, 7) + +// Packet: 0x00c1 +packetLen(0x00c1, 2) + +// Packet: 0x00c2 +packetLen(0x00c2, 6) + +// Packet: 0x00c3 +packetLen(0x00c3, 8) + +// Packet: 0x00c4 +packetLen(0x00c4, 6) + +// Packet: 0x00c5 +packetLen(0x00c5, 7) + +// Packet: 0x00c6 +packetLen(0x00c6, -1) + +// Packet: 0x00c7 +packetLen(0x00c7, -1) + +// Packet: 0x00c8 +packetLen(0x00c8, -1) + +// Packet: 0x00c9 +packetLen(0x00c9, -1) + +// Packet: 0x00ca +packetLen(0x00ca, 3) + +// Packet: 0x00cb +packetLen(0x00cb, 3) + +// Packet: 0x00cc +packetLen(0x00cc, 6) + +// Packet: 0x00cd +packetLen(0x00cd, 3) + +// Packet: 0x00ce +packetLen(0x00ce, 2) + +// Packet: 0x00cf +packetLen(0x00cf, 27) + +// Packet: 0x00d0 +packetLen(0x00d0, 3) + +// Packet: 0x00d1 +packetLen(0x00d1, 4) + +// Packet: 0x00d2 +packetLen(0x00d2, 4) + +// Packet: 0x00d3 +packetLen(0x00d3, 2) + +// Packet: 0x00d4 +packetLen(0x00d4, -1) + +// Packet: 0x00d5 +packetLen(0x00d5, -1) + +// Packet: 0x00d6 +packetLen(0x00d6, 3) + +// Packet: 0x00d7 +packetLen(0x00d7, -1) + +// Packet: 0x00d8 +packetLen(0x00d8, 6) + +// Packet: 0x00d9 +packetLen(0x00d9, 14) + +// Packet: 0x00da +packetLen(0x00da, 3) + +// Packet: 0x00db +packetLen(0x00db, -1) + +// Packet: 0x00dc +packetLen(0x00dc, 28) + +// Packet: 0x00dd +packetLen(0x00dd, 29) + +// Packet: 0x00de +packetLen(0x00de, -1) + +// Packet: 0x00df +packetLen(0x00df, -1) + +// Packet: 0x00e0 +packetLen(0x00e0, 30) + +// Packet: 0x00e1 +packetLen(0x00e1, 30) + +// Packet: 0x00e2 +packetLen(0x00e2, 26) + +// Packet: 0x00e3 +packetLen(0x00e3, 2) + +// Packet: 0x00e4 +packetLen(0x00e4, 6) + +// Packet: 0x00e5 +packetLen(0x00e5, 26) + +// Packet: 0x00e6 +packetLen(0x00e6, 3) + +// Packet: 0x00e7 +packetLen(0x00e7, 3) + +// Packet: 0x00e8 +packetLen(0x00e8, 8) + +// Packet: 0x00e9 +packetLen(0x00e9, 29) + +// Packet: 0x00ea +packetLen(0x00ea, 5) + +// Packet: 0x00eb +packetLen(0x00eb, 2) + +// Packet: 0x00ec +packetLen(0x00ec, 3) + +// Packet: 0x00ed +packetLen(0x00ed, 2) + +// Packet: 0x00ee +packetLen(0x00ee, 2) + +// Packet: 0x00ef +packetLen(0x00ef, 2) + +// Packet: 0x00f0 +packetLen(0x00f0, 3) + +// Packet: 0x00f1 +packetLen(0x00f1, 2) + +// Packet: 0x00f2 +packetLen(0x00f2, 6) + +// Packet: 0x00f3 +packetLen(0x00f3, -1) + +// Packet: 0x00f4 +packetLen(0x00f4, 31) + +// Packet: 0x00f5 +packetLen(0x00f5, 11) + +// Packet: 0x00f6 +packetLen(0x00f6, 8) + +// Packet: 0x00f7 +packetLen(0x00f7, 17) + +// Packet: 0x00f8 +packetLen(0x00f8, 2) + +// Packet: 0x00f9 +packetLen(0x00f9, 26) + +// Packet: 0x00fa +packetLen(0x00fa, 3) + +// Packet: 0x00fb +packetLen(0x00fb, -1) + +// Packet: 0x00fc +packetLen(0x00fc, 6) + +// Packet: 0x00fd +packetLen(0x00fd, 27) + +// Packet: 0x00fe +packetLen(0x00fe, 30) + +// Packet: 0x00ff +packetLen(0x00ff, 10) + +// Packet: 0x0100 +packetLen(0x0100, 2) + +// Packet: 0x0101 +packetLen(0x0101, 6) + +// Packet: 0x0102 +packetLen(0x0102, 6) + +// Packet: 0x0103 +packetLen(0x0103, 30) + +// Packet: 0x0104 +packetLen(0x0104, 79) + +// Packet: 0x0105 +packetLen(0x0105, 31) + +// Packet: 0x0106 +packetLen(0x0106, 10) + +// Packet: 0x0107 +packetLen(0x0107, 10) + +// Packet: 0x0108 +packetLen(0x0108, -1) + +// Packet: 0x0109 +packetLen(0x0109, -1) + +// Packet: 0x010a +packetLen(0x010a, 6) + +// Packet: 0x010b +packetLen(0x010b, 6) + +// Packet: 0x010c +packetLen(0x010c, 6) + +// Packet: 0x010d +packetLen(0x010d, 2) + +// Packet: 0x010e +packetLen(0x010e, 11) + +// Packet: 0x010f +packetLen(0x010f, -1) + +// Packet: 0x0110 +packetLen(0x0110, 14) + +// Packet: 0x0111 +packetLen(0x0111, 39) + +// Packet: 0x0112 +packetLen(0x0112, 4) + +// Packet: 0x0113 +packetLen(0x0113, 25) + +// Packet: 0x0114 +packetLen(0x0114, 31) + +// Packet: 0x0115 +packetLen(0x0115, 35) + +// Packet: 0x0116 +packetLen(0x0116, 17) + +// Packet: 0x0117 +packetLen(0x0117, 18) + +// Packet: 0x0118 +packetLen(0x0118, 2) + +// Packet: 0x0119 +packetLen(0x0119, 13) + +// Packet: 0x011a +packetLen(0x011a, 15) + +// Packet: 0x011b +packetLen(0x011b, 20) + +// Packet: 0x011c +packetLen(0x011c, 68) + +// Packet: 0x011d +packetLen(0x011d, 2) + +// Packet: 0x011e +packetLen(0x011e, 3) + +// Packet: 0x011f +packetLen(0x011f, 16) + +// Packet: 0x0120 +packetLen(0x0120, 6) + +// Packet: 0x0121 +packetLen(0x0121, 14) + +// Packet: 0x0122 +packetLen(0x0122, -1) + +// Packet: 0x0123 +packetLen(0x0123, -1) + +// Packet: 0x0124 +packetLen(0x0124, 31) + +// Packet: 0x0125 +packetLen(0x0125, 8) + +// Packet: 0x0126 +packetLen(0x0126, 8) + +// Packet: 0x0127 +packetLen(0x0127, 8) + +// Packet: 0x0128 +packetLen(0x0128, 8) + +// Packet: 0x0129 +packetLen(0x0129, 8) + +// Packet: 0x012a +packetLen(0x012a, 2) + +// Packet: 0x012b +packetLen(0x012b, 2) + +// Packet: 0x012c +packetLen(0x012c, 3) + +// Packet: 0x012d +packetLen(0x012d, 4) + +// Packet: 0x012e +packetLen(0x012e, 2) + +// Packet: 0x012f +packetLen(0x012f, -1) + +// Packet: 0x0130 +packetLen(0x0130, 6) + +// Packet: 0x0131 +packetLen(0x0131, 86) + +// Packet: 0x0132 +packetLen(0x0132, 6) + +// Packet: 0x0133 +packetLen(0x0133, -1) + +// Packet: 0x0134 +packetLen(0x0134, -1) + +// Packet: 0x0135 +packetLen(0x0135, 7) + +// Packet: 0x0136 +packetLen(0x0136, -1) + +// Packet: 0x0137 +packetLen(0x0137, 6) + +// Packet: 0x0138 +packetLen(0x0138, 3) + +// Packet: 0x0139 +packetLen(0x0139, 16) + +// Packet: 0x013a +packetLen(0x013a, 4) + +// Packet: 0x013b +packetLen(0x013b, 4) + +// Packet: 0x013c +packetLen(0x013c, 4) + +// Packet: 0x013d +packetLen(0x013d, 6) + +// Packet: 0x013e +packetLen(0x013e, 24) + +// Packet: 0x013f +packetLen(0x013f, 26) + +// Packet: 0x0140 +packetLen(0x0140, 22) + +// Packet: 0x0141 +packetLen(0x0141, 14) + +// Packet: 0x0142 +packetLen(0x0142, 6) + +// Packet: 0x0143 +packetLen(0x0143, 10) + +// Packet: 0x0144 +packetLen(0x0144, 23) + +// Packet: 0x0145 +packetLen(0x0145, 19) + +// Packet: 0x0146 +packetLen(0x0146, 6) + +// Packet: 0x0147 +packetLen(0x0147, 39) + +// Packet: 0x0148 +packetLen(0x0148, 8) + +// Packet: 0x0149 +packetLen(0x0149, 9) + +// Packet: 0x014a +packetLen(0x014a, 6) + +// Packet: 0x014b +packetLen(0x014b, 27) + +// Packet: 0x014c +packetLen(0x014c, -1) + +// Packet: 0x014d +packetLen(0x014d, 2) + +// Packet: 0x014e +packetLen(0x014e, 6) + +// Packet: 0x014f +packetLen(0x014f, 6) + +// Packet: 0x0150 +packetLen(0x0150, 110) + +// Packet: 0x0151 +packetLen(0x0151, 6) + +// Packet: 0x0152 +packetLen(0x0152, -1) + +// Packet: 0x0153 +packetLen(0x0153, -1) + +// Packet: 0x0154 +packetLen(0x0154, -1) + +// Packet: 0x0155 +packetLen(0x0155, -1) + +// Packet: 0x0156 +packetLen(0x0156, -1) + +// Packet: 0x0157 +packetLen(0x0157, 6) + +// Packet: 0x0159 +packetLen(0x0159, 54) + +// Packet: 0x015a +packetLen(0x015a, 66) + +// Packet: 0x015b +packetLen(0x015b, 54) + +// Packet: 0x015c +packetLen(0x015c, 90) + +// Packet: 0x015d +packetLen(0x015d, 42) + +// Packet: 0x015e +packetLen(0x015e, 6) + +// Packet: 0x015f +packetLen(0x015f, 42) + +// Packet: 0x0160 +packetLen(0x0160, -1) + +// Packet: 0x0161 +packetLen(0x0161, -1) + +// Packet: 0x0162 +packetLen(0x0162, -1) + +// Packet: 0x0163 +packetLen(0x0163, -1) + +// Packet: 0x0164 +packetLen(0x0164, -1) + +// Packet: 0x0165 +packetLen(0x0165, 30) + +// Packet: 0x0166 +packetLen(0x0166, -1) + +// Packet: 0x0167 +packetLen(0x0167, 3) + +// Packet: 0x0168 +packetLen(0x0168, 14) + +// Packet: 0x0169 +packetLen(0x0169, 3) + +// Packet: 0x016a +packetLen(0x016a, 30) + +// Packet: 0x016b +packetLen(0x016b, 10) + +// Packet: 0x016c +packetLen(0x016c, 43) + +// Packet: 0x016d +packetLen(0x016d, 14) + +// Packet: 0x016e +packetLen(0x016e, 186) + +// Packet: 0x016f +packetLen(0x016f, 182) + +// Packet: 0x0170 +packetLen(0x0170, 14) + +// Packet: 0x0171 +packetLen(0x0171, 30) + +// Packet: 0x0172 +packetLen(0x0172, 10) + +// Packet: 0x0173 +packetLen(0x0173, 3) + +// Packet: 0x0174 +packetLen(0x0174, -1) + +// Packet: 0x0175 +packetLen(0x0175, 6) + +// Packet: 0x0176 +packetLen(0x0176, 106) + +// Packet: 0x0177 +packetLen(0x0177, -1) + +// Packet: 0x0178 +packetLen(0x0178, 4) + +// Packet: 0x0179 +packetLen(0x0179, 5) + +// Packet: 0x017a +packetLen(0x017a, 4) + +// Packet: 0x017b +packetLen(0x017b, -1) + +// Packet: 0x017c +packetLen(0x017c, 6) + +// Packet: 0x017d +packetLen(0x017d, 7) + +// Packet: 0x017e +packetLen(0x017e, -1) + +// Packet: 0x017f +packetLen(0x017f, -1) + +// Packet: 0x0180 +packetLen(0x0180, 6) + +// Packet: 0x0181 +packetLen(0x0181, 3) + +// Packet: 0x0182 +packetLen(0x0182, 106) + +// Packet: 0x0183 +packetLen(0x0183, 10) + +// Packet: 0x0184 +packetLen(0x0184, 10) + +// Packet: 0x0185 +packetLen(0x0185, 34) + +// Packet: 0x0187 +packetLen(0x0187, 6) + +// Packet: 0x0188 +packetLen(0x0188, 8) + +// Packet: 0x0189 +packetLen(0x0189, 4) + +// Packet: 0x018a +packetLen(0x018a, 4) + +// Packet: 0x018b +packetLen(0x018b, 4) + +// Packet: 0x018c +packetLen(0x018c, 29) + +// Packet: 0x018d +packetLen(0x018d, -1) + +// Packet: 0x018e +packetLen(0x018e, 18) + +// Packet: 0x018f +packetLen(0x018f, 8) + +// Packet: 0x0190 +packetLen(0x0190, 23) + +// Packet: 0x0191 +packetLen(0x0191, 27) + +// Packet: 0x0192 +packetLen(0x0192, 24) + +// Packet: 0x0193 +packetLen(0x0193, 2) + +// Packet: 0x0194 +packetLen(0x0194, 30) + +// Packet: 0x0195 +packetLen(0x0195, 102) + +// Packet: 0x0196 +packetLen(0x0196, 9) + +// Packet: 0x0197 +packetLen(0x0197, 4) + +// Packet: 0x0198 +packetLen(0x0198, 8) + +// Packet: 0x0199 +packetLen(0x0199, 4) + +// Packet: 0x019a +packetLen(0x019a, 14) + +// Packet: 0x019b +packetLen(0x019b, 10) + +// Packet: 0x019c +packetLen(0x019c, -1) + +// Packet: 0x019d +packetLen(0x019d, 6) + +// Packet: 0x019e +packetLen(0x019e, 2) + +// Packet: 0x019f +packetLen(0x019f, 6) + +// Packet: 0x01a0 +packetLen(0x01a0, 3) + +// Packet: 0x01a1 +packetLen(0x01a1, 3) + +// Packet: 0x01a2 +packetLen(0x01a2, 37) + +// Packet: 0x01a3 +packetLen(0x01a3, 7) + +// Packet: 0x01a4 +packetLen(0x01a4, 11) + +// Packet: 0x01a5 +packetLen(0x01a5, 26) + +// Packet: 0x01a6 +packetLen(0x01a6, -1) + +// Packet: 0x01a7 +packetLen(0x01a7, 4) + +// Packet: 0x01a8 +packetLen(0x01a8, 4) + +// Packet: 0x01a9 +packetLen(0x01a9, 6) + +// Packet: 0x01aa +packetLen(0x01aa, 10) + +// Packet: 0x01ab +packetLen(0x01ab, 12) + +// Packet: 0x01ac +packetLen(0x01ac, 6) + +// Packet: 0x01ad +packetLen(0x01ad, -1) + +// Packet: 0x01ae +packetLen(0x01ae, 6) + +// Packet: 0x01af +packetLen(0x01af, 4) + +// Packet: 0x01b0 +packetLen(0x01b0, 11) + +// Packet: 0x01b1 +packetLen(0x01b1, 7) + +// Packet: 0x01b2 +packetLen(0x01b2, -1) + +// Packet: 0x01b3 +packetLen(0x01b3, 67) + +// Packet: 0x01b4 +packetLen(0x01b4, 12) + +// Packet: 0x01b5 +packetLen(0x01b5, 18) + +// Packet: 0x01b6 +packetLen(0x01b6, 114) + +// Packet: 0x01b7 +packetLen(0x01b7, 6) + +// Packet: 0x01b8 +packetLen(0x01b8, 3) + +// Packet: 0x01b9 +packetLen(0x01b9, 6) + +// Packet: 0x01ba +packetLen(0x01ba, 26) + +// Packet: 0x01bb +packetLen(0x01bb, 26) + +// Packet: 0x01bc +packetLen(0x01bc, 26) + +// Packet: 0x01bd +packetLen(0x01bd, 26) + +// Packet: 0x01be +packetLen(0x01be, 2) + +// Packet: 0x01bf +packetLen(0x01bf, 3) + +// Packet: 0x01c0 +packetLen(0x01c0, 2) + +// Packet: 0x01c1 +packetLen(0x01c1, 14) + +// Packet: 0x01c2 +packetLen(0x01c2, 10) + +// Packet: 0x01c3 +packetLen(0x01c3, -1) + +// Packet: 0x01c4 +packetLen(0x01c4, 32) + +// Packet: 0x01c5 +packetLen(0x01c5, 32) + +// Packet: 0x01c6 +packetLen(0x01c6, 4) + +// Packet: 0x01c7 +packetLen(0x01c7, 2) + +// Packet: 0x01c8 +packetLen(0x01c8, 15) + +// Packet: 0x01c9 +packetLen(0x01c9, 97) + +// Packet: 0x01ca +packetLen(0x01ca, 3) + +// Packet: 0x01cb +packetLen(0x01cb, 9) + +// Packet: 0x01cc +packetLen(0x01cc, 9) + +// Packet: 0x01cd +packetLen(0x01cd, 30) + +// Packet: 0x01ce +packetLen(0x01ce, 6) + +// Packet: 0x01cf +packetLen(0x01cf, 28) + +// Packet: 0x01d0 +packetLen(0x01d0, 8) + +// Packet: 0x01d1 +packetLen(0x01d1, 14) + +// Packet: 0x01d2 +packetLen(0x01d2, 10) + +// Packet: 0x01d3 +packetLen(0x01d3, 35) + +// Packet: 0x01d4 +packetLen(0x01d4, 6) + +// Packet: 0x01d5 +packetLen(0x01d5, -1) + +// Packet: 0x01d6 +packetLen(0x01d6, 4) + +// Packet: 0x01d7 +packetLen(0x01d7, 15) + +// Packet: 0x01d8 +packetLen(0x01d8, 58) + +// Packet: 0x01d9 +packetLen(0x01d9, 57) + +// Packet: 0x01da +packetLen(0x01da, 64) + +// Packet: 0x01db +packetLen(0x01db, 2) + +// Packet: 0x01dc +packetLen(0x01dc, -1) + +// Packet: 0x01dd +packetLen(0x01dd, 47) + +// Packet: 0x01de +packetLen(0x01de, 33) + +// Packet: 0x01df +packetLen(0x01df, 6) + +// Packet: 0x01e0 +packetLen(0x01e0, 30) + +// Packet: 0x01e1 +packetLen(0x01e1, 8) + +// Packet: 0x01e2 +packetLen(0x01e2, 34) + +// Packet: 0x01e3 +packetLen(0x01e3, 14) + +// Packet: 0x01e4 +packetLen(0x01e4, 2) + +// Packet: 0x01e5 +packetLen(0x01e5, 6) + +// Packet: 0x01e6 +packetLen(0x01e6, 26) + +// Packet: 0x01e7 +packetLen(0x01e7, 2) + +// Packet: 0x01e8 +packetLen(0x01e8, 28) + +// Packet: 0x01e9 +packetLen(0x01e9, 81) + +// Packet: 0x01ea +packetLen(0x01ea, 6) + +// Packet: 0x01eb +packetLen(0x01eb, 10) + +// Packet: 0x01ec +packetLen(0x01ec, 26) + +// Packet: 0x01ed +packetLen(0x01ed, 2) + +// Packet: 0x01ee +packetLen(0x01ee, -1) + +// Packet: 0x01ef +packetLen(0x01ef, -1) + +// Packet: 0x01f0 +packetLen(0x01f0, -1) + +// Packet: 0x01f1 +packetLen(0x01f1, -1) + +// Packet: 0x01f2 +packetLen(0x01f2, 20) + +// Packet: 0x01f3 +packetLen(0x01f3, 10) + +// Packet: 0x01f4 +packetLen(0x01f4, 32) + +// Packet: 0x01f5 +packetLen(0x01f5, 9) + +// Packet: 0x01f6 +packetLen(0x01f6, 34) + +// Packet: 0x01f7 +packetLen(0x01f7, 14) + +// Packet: 0x01f8 +packetLen(0x01f8, 2) + +// Packet: 0x01f9 +packetLen(0x01f9, 6) + +// Packet: 0x01fa +packetLen(0x01fa, 48) + +// Packet: 0x01fb +packetLen(0x01fb, 56) + +// Packet: 0x01fc +packetLen(0x01fc, -1) + +// Packet: 0x01fd +packetLen(0x01fd, 25) + +// Packet: 0x01fe +packetLen(0x01fe, 5) + +// Packet: 0x01ff +packetLen(0x01ff, 10) + +// Packet: 0x0200 +packetLen(0x0200, 26) + +// Packet: 0x0201 +packetLen(0x0201, -1) + +// Packet: 0x0202 +packetLen(0x0202, 26) + +// Packet: 0x0203 +packetLen(0x0203, 10) + +// Packet: 0x0204 +packetLen(0x0204, 18) + +// Packet: 0x0205 +packetLen(0x0205, 26) + +// Packet: 0x0206 +packetLen(0x0206, 35) + +// Packet: 0x0207 +packetLen(0x0207, 34) + +// Packet: 0x0208 +packetLen(0x0208, 14) + +// Packet: 0x0209 +packetLen(0x0209, 36) + +// Packet: 0x020a +packetLen(0x020a, 10) + +// Packet: 0x020d +packetLen(0x020d, -1) + +// Packet: 0x020e +packetLen(0x020e, 32) + +// Packet: 0x0212 +packetLen(0x0212, 26) + +// Packet: 0x0213 +packetLen(0x0213, 26) + +// Packet: 0x0214 +packetLen(0x0214, 42) + +// Packet: 0x0215 +packetLen(0x0215, 6) + +// Packet: 0x0216 +packetLen(0x0216, 6) + +// Packet: 0x0217 +packetLen(0x0217, 2) + +// Packet: 0x0218 +packetLen(0x0218, 2) + +// Packet: 0x0219 +packetLen(0x0219, 282) + +// Packet: 0x021a +packetLen(0x021a, 282) + +// Packet: 0x021b +packetLen(0x021b, 10) + +// Packet: 0x021c +packetLen(0x021c, 10) + +// Packet: 0x021d +packetLen(0x021d, 6) + +// Packet: 0x021e +packetLen(0x021e, 6) + +// Packet: 0x021f +packetLen(0x021f, 66) + +// Packet: 0x0220 +packetLen(0x0220, 10) + +// Packet: 0x0221 +packetLen(0x0221, -1) + +// Packet: 0x0222 +packetLen(0x0222, 6) + +// Packet: 0x0223 +packetLen(0x0223, 10) + +// Packet: 0x0224 +packetLen(0x0224, 10) + +// Packet: 0x0225 +packetLen(0x0225, 2) + +// Packet: 0x0226 +packetLen(0x0226, 282) + +// Packet: 0x0227 +packetLen(0x0227, 18) + +// Packet: 0x0228 +packetLen(0x0228, 18) + +// Packet: 0x0229 +packetLen(0x0229, 15) + +// Packet: 0x022a +packetLen(0x022a, 62) + +// Packet: 0x022b +packetLen(0x022b, 61) + +// Packet: 0x022c +packetLen(0x022c, 69) + +// Packet: 0x022d +packetLen(0x022d, 5) + +// Packet: 0x022e +packetLen(0x022e, 73) + +// Packet: 0x022f +packetLen(0x022f, 7) + +// Packet: 0x0230 +packetLen(0x0230, 12) + +// Packet: 0x0231 +packetLen(0x0231, 26) + +// Packet: 0x0232 +packetLen(0x0232, 9) + +// Packet: 0x0233 +packetLen(0x0233, 11) + +// Packet: 0x0234 +packetLen(0x0234, 6) + +// Packet: 0x0235 +packetLen(0x0235, -1) + +// Packet: 0x0236 +packetLen(0x0236, 10) + +// Packet: 0x0237 +packetLen(0x0237, 2) + +// Packet: 0x0238 +packetLen(0x0238, 282) + +// Packet: 0x0239 +packetLen(0x0239, 11) + +// Packet: 0x023a +packetLen(0x023a, 4) + +// Packet: 0x023b +packetLen(0x023b, 36) + +// Packet: 0x023c +packetLen(0x023c, 6) + +// Packet: 0x023d +packetLen(0x023d, 6) + +// Packet: 0x023e +packetLen(0x023e, 8) + +// Packet: 0x023f +packetLen(0x023f, 2) + +// Packet: 0x0240 +packetLen(0x0240, -1) + +// Packet: 0x0241 +packetLen(0x0241, 6) + +// Packet: 0x0242 +packetLen(0x0242, -1) + +// Packet: 0x0243 +packetLen(0x0243, 6) + +// Packet: 0x0244 +packetLen(0x0244, 6) + +// Packet: 0x0245 +packetLen(0x0245, 3) + +// Packet: 0x0246 +packetLen(0x0246, 4) + +// Packet: 0x0247 +packetLen(0x0247, 8) + +// Packet: 0x0248 +packetLen(0x0248, -1) + +// Packet: 0x0249 +packetLen(0x0249, 3) + +// Packet: 0x024a +packetLen(0x024a, 70) + +// Packet: 0x024b +packetLen(0x024b, 4) + +// Packet: 0x024c +packetLen(0x024c, 8) + +// Packet: 0x024d +packetLen(0x024d, 12) + +// Packet: 0x024e +packetLen(0x024e, 6) + +// Packet: 0x024f +packetLen(0x024f, 10) + +// Packet: 0x0250 +packetLen(0x0250, 3) + +// Packet: 0x0251 +packetLen(0x0251, 34) + +// Packet: 0x0252 +packetLen(0x0252, -1) + +// Packet: 0x0253 +packetLen(0x0253, 3) + +// Packet: 0x0254 +packetLen(0x0254, 3) + +// Packet: 0x0255 +packetLen(0x0255, 5) + +// Packet: 0x0256 +packetLen(0x0256, 5) + +// Packet: 0x0257 +packetLen(0x0257, 8) + +// Packet: 0x0258 +packetLen(0x0258, 2) + +// Packet: 0x0259 +packetLen(0x0259, 3) + +// Packet: 0x025a +packetLen(0x025a, -1) + +// Packet: 0x025b +packetLen(0x025b, 8) + +// Packet: 0x025c +packetLen(0x025c, 4) + +// Packet: 0x025d +packetLen(0x025d, 6) + +// Packet: 0x025e +packetLen(0x025e, 4) + +// Packet: 0x025f +packetLen(0x025f, 6) + +// Packet: 0x0260 +packetLen(0x0260, 6) + +// Packet: 0x0261 +packetLen(0x0261, 11) + +// Packet: 0x0262 +packetLen(0x0262, 11) + +// Packet: 0x0263 +packetLen(0x0263, 11) + +// Packet: 0x0264 +packetLen(0x0264, 20) + +// Packet: 0x0265 +packetLen(0x0265, 20) + +// Packet: 0x0266 +packetLen(0x0266, 30) + +// Packet: 0x0267 +packetLen(0x0267, 4) + +// Packet: 0x0268 +packetLen(0x0268, 4) + +// Packet: 0x0269 +packetLen(0x0269, 4) + +// Packet: 0x026a +packetLen(0x026a, 4) + +// Packet: 0x026b +packetLen(0x026b, 4) + +// Packet: 0x026c +packetLen(0x026c, 4) + +// Packet: 0x026d +packetLen(0x026d, 4) + +// Packet: 0x026f +packetLen(0x026f, 2) + +// Packet: 0x0270 +packetLen(0x0270, 2) + +// Packet: 0x0271 +packetLen(0x0271, 40) + +// Packet: 0x0272 +packetLen(0x0272, 44) + +// Packet: 0x0273 +packetLen(0x0273, 30) + +// Packet: 0x0274 +packetLen(0x0274, 8) + +// Packet: 0x0275 +packetLen(0x0275, 37) + +// Packet: 0x0276 +packetLen(0x0276, -1) + +// Packet: 0x0277 +packetLen(0x0277, 84) + +// Packet: 0x0278 +packetLen(0x0278, 2) + +// Packet: 0x0279 +packetLen(0x0279, 2) + +// Packet: 0x027a +packetLen(0x027a, -1) + +// Packet: 0x027b +packetLen(0x027b, 14) + +// Packet: 0x027c +packetLen(0x027c, 60) + +// Packet: 0x027d +packetLen(0x027d, 62) + +// Packet: 0x027e +packetLen(0x027e, -1) + +// Packet: 0x027f +packetLen(0x027f, 8) + +// Packet: 0x0280 +packetLen(0x0280, 12) + +// Packet: 0x0281 +packetLen(0x0281, 4) + +// Packet: 0x0282 +packetLen(0x0282, 284) + +// Packet: 0x0283 +packetLen(0x0283, 6) + +// Packet: 0x0284 +packetLen(0x0284, 14) + +// Packet: 0x0285 +packetLen(0x0285, 6) + +// Packet: 0x0286 +packetLen(0x0286, 4) + +// Packet: 0x0287 +packetLen(0x0287, -1) + +// Packet: 0x0288 +packetLen(0x0288, -1) + +// Packet: 0x0289 +packetLen(0x0289, 12) + +// Packet: 0x028a +packetLen(0x028a, 18) + +// Packet: 0x028b +packetLen(0x028b, -1) + +// Packet: 0x028c +packetLen(0x028c, 46) + +// Packet: 0x028d +packetLen(0x028d, 34) + +// Packet: 0x028e +packetLen(0x028e, 4) + +// Packet: 0x028f +packetLen(0x028f, 6) + +// Packet: 0x0290 +packetLen(0x0290, 4) + +// Packet: 0x0291 +packetLen(0x0291, 4) + +// Packet: 0x0292 +packetLen(0x0292, 2) + +// Packet: 0x0293 +packetLen(0x0293, 70) + +// Packet: 0x0294 +packetLen(0x0294, 10) + +// Packet: 0x0295 +packetLen(0x0295, -1) + +// Packet: 0x0296 +packetLen(0x0296, -1) + +// Packet: 0x0297 +packetLen(0x0297, -1) + +// Packet: 0x0298 +packetLen(0x0298, 10) + +// Packet: 0x0299 +packetLen(0x0299, 8) + +// Packet: 0x029a +packetLen(0x029a, 37) + +// Packet: 0x029b +packetLen(0x029b, 80) + +// Packet: 0x029c +packetLen(0x029c, 66) + +// Packet: 0x029d +packetLen(0x029d, -1) + +// Packet: 0x029e +packetLen(0x029e, 11) + +// Packet: 0x029f +packetLen(0x029f, 3) + +// Packet: 0x02a2 +packetLen(0x02a2, 8) + +// Packet: 0x02a5 +packetLen(0x02a5, 8) + +// Packet: 0x02a6 +packetLen(0x02a6, -1) + +// Packet: 0x02a7 +packetLen(0x02a7, -1) + +// Packet: 0x02aa +packetLen(0x02aa, 4) + +// Packet: 0x02ab +packetLen(0x02ab, 36) + +// Packet: 0x02ac +packetLen(0x02ac, 6) + +// Packet: 0x02ad +packetLen(0x02ad, 8) + +// Packet: 0x02b0 +packetLen(0x02b0, 85) + +// Packet: 0x02b1 +packetLen(0x02b1, -1) + +// Packet: 0x02b2 +packetLen(0x02b2, -1) + +// Packet: 0x02b3 +packetLen(0x02b3, 107) + +// Packet: 0x02b4 +packetLen(0x02b4, 6) + +// Packet: 0x02b5 +packetLen(0x02b5, -1) + +// Packet: 0x02b6 +packetLen(0x02b6, 7) + +// Packet: 0x02b7 +packetLen(0x02b7, 7) + +// Packet: 0x02b8 +packetLen(0x02b8, 32) + +// Packet: 0x02b9 +packetLen(0x02b9, 191) + +// Packet: 0x02ba +packetLen(0x02ba, 11) + +// Packet: 0x02bb +packetLen(0x02bb, 8) + +// Packet: 0x02bc +packetLen(0x02bc, 6) + +// Packet: 0x02c1 +packetLen(0x02c1, -1) + +// Packet: 0x02c2 +packetLen(0x02c2, -1) + +// Packet: 0x02c4 +packetLen(0x02c4, 26) + +// Packet: 0x02c5 +packetLen(0x02c5, 30) + +// Packet: 0x02c6 +packetLen(0x02c6, 30) + +// Packet: 0x02c7 +packetLen(0x02c7, 7) + +// Packet: 0x02c8 +packetLen(0x02c8, 3) + +// Packet: 0x02c9 +packetLen(0x02c9, 3) + +// Packet: 0x02ca +packetLen(0x02ca, 3) + +// Packet: 0x02cb +packetLen(0x02cb, 65) + +// Packet: 0x02cc +packetLen(0x02cc, 4) + +// Packet: 0x02cd +packetLen(0x02cd, 71) + +// Packet: 0x02ce +packetLen(0x02ce, 10) + +// Packet: 0x02cf +packetLen(0x02cf, 6) + +// Packet: 0x02d0 +packetLen(0x02d0, -1) + +// Packet: 0x02d1 +packetLen(0x02d1, -1) + +// Packet: 0x02d2 +packetLen(0x02d2, -1) + +// Packet: 0x02d3 +packetLen(0x02d3, 4) + +// Packet: 0x02d4 +packetLen(0x02d4, 39) + +// Packet: 0x02d5 +packetLen(0x02d5, 2) + +// Packet: 0x02d6 +packetLen(0x02d6, 6) + +// Packet: 0x02d7 +packetLen(0x02d7, -1) + +// Packet: 0x02d8 +packetLen(0x02d8, 10) + +// Packet: 0x02d9 +packetLen(0x02d9, 10) + +// Packet: 0x02da +packetLen(0x02da, 3) + +// Packet: 0x02db +packetLen(0x02db, -1) + +// Packet: 0x02dc +packetLen(0x02dc, -1) + +// Packet: 0x02dd +packetLen(0x02dd, 32) + +// Packet: 0x02de +packetLen(0x02de, 6) + +// Packet: 0x02df +packetLen(0x02df, 36) + +// Packet: 0x02e0 +packetLen(0x02e0, 34) + +// Packet: 0x02e1 +packetLen(0x02e1, 33) + +// Packet: 0x02e2 +packetLen(0x02e2, 20) + +// Packet: 0x02e3 +packetLen(0x02e3, 22) + +// Packet: 0x02e4 +packetLen(0x02e4, 11) + +// Packet: 0x02e5 +packetLen(0x02e5, 9) + +// Packet: 0x02e6 +packetLen(0x02e6, 6) + +// Packet: 0x02e7 +packetLen(0x02e7, -1) + +// Packet: 0x02e8 +packetLen(0x02e8, -1) + +// Packet: 0x02e9 +packetLen(0x02e9, -1) + +// Packet: 0x02ea +packetLen(0x02ea, -1) + +// Packet: 0x02eb +packetLen(0x02eb, 13) + +// Packet: 0x02ec +packetLen(0x02ec, 71) + +// Packet: 0x02ed +packetLen(0x02ed, 63) + +// Packet: 0x02ee +packetLen(0x02ee, 64) + +// Packet: 0x02ef +packetLen(0x02ef, 8) + +// Packet: 0x02f0 +packetLen(0x02f0, 10) + +// Packet: 0x02f1 +packetLen(0x02f1, 2) + +// Packet: 0x02f2 +packetLen(0x02f2, 2) + +// Packet: 0x02f3 +packetLen(0x02f3, -1) + +// Packet: 0x02f4 +packetLen(0x02f4, 3) + +// Packet: 0x02f5 +packetLen(0x02f5, 7) + +// Packet: 0x02f6 +packetLen(0x02f6, 7) + +// Packet: 0x035c +packetLen(0x035c, 2) + +// Packet: 0x035d +packetLen(0x035d, -1) + +// Packet: 0x035e +packetLen(0x035e, 2) + +// Packet: 0x035f +packetLen(0x035f, 5) + +// Packet: 0x0360 +packetLen(0x0360, 6) + +// Packet: 0x0361 +packetLen(0x0361, 5) + +// Packet: 0x0362 +packetLen(0x0362, 6) + +// Packet: 0x0363 +packetLen(0x0363, 6) + +// Packet: 0x0364 +packetLen(0x0364, 8) + +// Packet: 0x0365 +packetLen(0x0365, 8) + +// Packet: 0x0366 +packetLen(0x0366, 10) + +// Packet: 0x0367 +packetLen(0x0367, 31) + +// Packet: 0x0368 +packetLen(0x0368, 6) + +// Packet: 0x0369 +packetLen(0x0369, 6) + +// Packet: 0x03dd +packetLen(0x03dd, 18) + +// Packet: 0x03de +packetLen(0x03de, 18) + +// Packet: 0x0436 +packetLen(0x0436, 19) + +// Packet: 0x0437 +packetLen(0x0437, 7) + +// Packet: 0x0438 +packetLen(0x0438, 10) + +// Packet: 0x0439 +packetLen(0x0439, 8) + +// Packet: 0x043d +packetLen(0x043d, 8) + +// Packet: 0x043e +packetLen(0x043e, -1) + +// Packet: 0x043f +packetLen(0x043f, 25) + +// Packet: 0x0440 +packetLen(0x0440, 10) + +// Packet: 0x0441 +packetLen(0x0441, 4) + +// Packet: 0x0442 +packetLen(0x0442, -1) + +// Packet: 0x0443 +packetLen(0x0443, 8) + +// Packet: 0x0444 +packetLen(0x0444, -1) + +// Packet: 0x0445 +packetLen(0x0445, 12) + +// Packet: 0x0446 +packetLen(0x0446, 14) + +// Packet: 0x0447 +packetLen(0x0447, 2) + +// Packet: 0x0448 +packetLen(0x0448, -1) + +// Packet: 0x0449 +packetLen(0x0449, 4) + +// Packet: 0x044a +packetLen(0x044a, 6) + +// Packet: 0x044b +packetLen(0x044b, 2) + +// Packet: 0x07d7 +packetLen(0x07d7, 8) + +// Packet: 0x07d8 +packetLen(0x07d8, 8) + +// Packet: 0x07d9 +packetLen(0x07d9, 268) + +// Packet: 0x07da +packetLen(0x07da, 6) + +// Packet: 0x07db +packetLen(0x07db, 8) + +// Packet: 0x07dc +packetLen(0x07dc, 6) + +// Packet: 0x07dd +packetLen(0x07dd, 54) + +// Packet: 0x07de +packetLen(0x07de, 30) + +// Packet: 0x07df +packetLen(0x07df, 54) + +// Packet: 0x07e0 +packetLen(0x07e0, 58) + +// Packet: 0x07e1 +packetLen(0x07e1, 15) + +// Packet: 0x07e2 +packetLen(0x07e2, 8) + +// Packet: 0x07e3 +packetLen(0x07e3, 6) + +// Packet: 0x07e4 +packetLen(0x07e4, -1) + +// Packet: 0x07e5 +packetLen(0x07e5, 4) + +// Packet: 0x07e6 +packetLen(0x07e6, 8) + +// Packet: 0x07e7 +packetLen(0x07e7, 32) + +// Packet: 0x07e8 +packetLen(0x07e8, -1) + +// Packet: 0x07e9 +packetLen(0x07e9, 5) + +// Packet: 0x07ea +packetLen(0x07ea, 2) + +// Packet: 0x07eb +packetLen(0x07eb, -1) + +// Packet: 0x07ec +packetLen(0x07ec, 8) + +// Packet: 0x07ed +packetLen(0x07ed, 10) + +// Packet: 0x07ee +packetLen(0x07ee, 6) + +// Packet: 0x07ef +packetLen(0x07ef, 8) + +// Packet: 0x07f0 +packetLen(0x07f0, 6) + +// Packet: 0x07f1 +packetLen(0x07f1, 18) + +// Packet: 0x07f2 +packetLen(0x07f2, 8) + +// Packet: 0x07f3 +packetLen(0x07f3, 6) + +// Packet: 0x07f4 +packetLen(0x07f4, 3) + +// Packet: 0x07f5 +packetLen(0x07f5, 6) + +// Packet: 0x07f6 +packetLen(0x07f6, 14) + +// Packet: 0x07f7 +packetLen(0x07f7, -1) + +// Packet: 0x07f8 +packetLen(0x07f8, -1) + +// Packet: 0x07f9 +packetLen(0x07f9, -1) + +// Packet: 0x07fa +packetLen(0x07fa, 8) + +// Packet: 0x07fb +packetLen(0x07fb, 25) + +// Packet: 0x07fc +packetLen(0x07fc, 10) + +// Packet: 0x07fd +packetLen(0x07fd, -1) + +// Packet: 0x07fe +packetLen(0x07fe, 26) + +// Packet: 0x0800 +packetLen(0x0800, -1) + +// Packet: 0x0801 +packetLen(0x0801, -1) + +// Packet: 0x0802 +packetLen(0x0802, 18) + +// Packet: 0x0803 +packetLen(0x0803, 4) + +// Packet: 0x0804 +packetLen(0x0804, 14) + +// Packet: 0x0805 +packetLen(0x0805, -1) + +// Packet: 0x0806 +packetLen(0x0806, 2) + +// Packet: 0x0807 +packetLen(0x0807, 4) + +// Packet: 0x0808 +packetLen(0x0808, 14) + +// Packet: 0x0809 +packetLen(0x0809, 50) + +// Packet: 0x080a +packetLen(0x080a, 18) + +// Packet: 0x080b +packetLen(0x080b, 6) + +// Packet: 0x080c +packetLen(0x080c, 2) + +// Packet: 0x080d +packetLen(0x080d, 3) + +// Packet: 0x080e +packetLen(0x080e, 14) + +// Packet: 0x080f +packetLen(0x080f, 30) + +// Packet: 0x0810 +packetLen(0x0810, 3) + +// Packet: 0x0811 +packetLen(0x0811, -1) + +// Packet: 0x0812 +packetLen(0x0812, 8) + +// Packet: 0x0813 +packetLen(0x0813, -1) + +// Packet: 0x0814 +packetLen(0x0814, 86) + +// Packet: 0x0815 +packetLen(0x0815, 2) + +// Packet: 0x0816 +packetLen(0x0816, 6) + +// Packet: 0x0817 +packetLen(0x0817, 6) + +// Packet: 0x0818 +packetLen(0x0818, -1) + +// Packet: 0x0819 +packetLen(0x0819, -1) + +// Packet: 0x081a +packetLen(0x081a, 4) + +// Packet: 0x081b +packetLen(0x081b, 12) + +// Packet: 0x081c +packetLen(0x081c, 10) + +// Packet: 0x081d +packetLen(0x081d, 22) + +// Packet: 0x081e +packetLen(0x081e, 8) + +// Packet: 0x081f +packetLen(0x081f, -1) + +// Packet: 0x0820 +packetLen(0x0820, 11) + +// Packet: 0x0821 +packetLen(0x0821, 2) + +// Packet: 0x0822 +packetLen(0x0822, 9) + +// Packet: 0x0823 +packetLen(0x0823, -1) + +// Packet: 0x0824 +packetLen(0x0824, 8) + +// Packet: 0x0825 +packetLen(0x0825, -1) + +// Packet: 0x0827 +packetLen(0x0827, 6) + +// Packet: 0x0828 +packetLen(0x0828, 14) + +// Packet: 0x0829 +packetLen(0x0829, 12) + +// Packet: 0x082a +packetLen(0x082a, 10) + +// Packet: 0x082b +packetLen(0x082b, 6) + +// Packet: 0x082c +packetLen(0x082c, 10) + +// Packet: 0x082d +packetLen(0x082d, -1) + +// Packet: 0x0835 +packetLen(0x0835, -1) + +// Packet: 0x0836 +packetLen(0x0836, -1) + +// Packet: 0x0837 +packetLen(0x0837, 3) + +// Packet: 0x0838 +packetLen(0x0838, 2) + +// Packet: 0x0839 +packetLen(0x0839, 66) + +// Packet: 0x083a +packetLen(0x083a, 5) + +// Packet: 0x083b +packetLen(0x083b, 2) + +// Packet: 0x083c +packetLen(0x083c, 14) + +// Packet: 0x083d +packetLen(0x083d, 6) + +// Packet: 0x083e +packetLen(0x083e, 26) + +// Packet: 0x0840 +packetLen(0x0840, -1) + +// Packet: 0x0841 +packetLen(0x0841, 4) + +// Packet: 0x0842 +packetLen(0x0842, 6) + +// Packet: 0x0843 +packetLen(0x0843, 6) + +// Packet: 0x0844 +packetLen(0x0844, 2) + +// Packet: 0x0845 +packetLen(0x0845, 10) + +// Packet: 0x0846 +packetLen(0x0846, 4) + +// Packet: 0x0847 +packetLen(0x0847, -1) + +// Packet: 0x0848 +packetLen(0x0848, -1) + +// Packet: 0x0849 +packetLen(0x0849, 16) + +// Packet: 0x084a +packetLen(0x084a, 2) + +// Packet: 0x084b +packetLen(0x084b, 21) + +// Packet: 0x084c +packetLen(0x084c, 10) + +// Packet: 0x084d +packetLen(0x084d, 10) + +// Packet: 0x084e +packetLen(0x084e, 5) + +// Packet: 0x084f +packetLen(0x084f, 6) + +// Packet: 0x0850 +packetLen(0x0850, 7) + +// Packet: 0x0851 +packetLen(0x0851, -1) + +// Packet: 0x0852 +packetLen(0x0852, 2) + +// Packet: 0x0853 +packetLen(0x0853, -1) + +// Packet: 0x0854 +packetLen(0x0854, -1) + +// Packet: 0x0855 +packetLen(0x0855, 6) + +// Packet: 0x0856 +packetLen(0x0856, -1) + +// Packet: 0x0857 +packetLen(0x0857, -1) + +// Packet: 0x0858 +packetLen(0x0858, -1) + +// Packet: 0x0859 +packetLen(0x0859, -1) + +// Packet: 0x085a +packetLen(0x085a, 2) + +// Packet: 0x085b +packetLen(0x085b, 2) + +// Packet: 0x085c +packetLen(0x085c, 2) + +// Packet: 0x085d +packetLen(0x085d, 2) + +// Packet: 0x085e +packetLen(0x085e, 2) + +// Packet: 0x085f +packetLen(0x085f, 2) + +// Packet: 0x0860 +packetLen(0x0860, 2) + +// Packet: 0x0861 +packetLen(0x0861, 2) + +// Packet: 0x0862 +packetLen(0x0862, 2) + +// Packet: 0x0863 +packetLen(0x0863, 2) + +// Packet: 0x0864 +packetLen(0x0864, 2) + +// Packet: 0x0865 +packetLen(0x0865, 2) + +// Packet: 0x0866 +packetLen(0x0866, 2) + +// Packet: 0x0867 +packetLen(0x0867, 2) + +// Packet: 0x0868 +packetLen(0x0868, 2) + +// Packet: 0x0869 +packetLen(0x0869, 2) + +// Packet: 0x086a +packetLen(0x086a, 2) + +// Packet: 0x086b +packetLen(0x086b, 2) + +// Packet: 0x086c +packetLen(0x086c, 2) + +// Packet: 0x086d +packetLen(0x086d, 2) + +// Packet: 0x086e +packetLen(0x086e, 2) + +// Packet: 0x086f +packetLen(0x086f, 2) + +// Packet: 0x0870 +packetLen(0x0870, 2) + +// Packet: 0x0871 +packetLen(0x0871, 2) + +// Packet: 0x0872 +packetLen(0x0872, 2) + +// Packet: 0x0873 +packetLen(0x0873, 2) + +// Packet: 0x0874 +packetLen(0x0874, 2) + +// Packet: 0x0875 +packetLen(0x0875, 2) + +// Packet: 0x0876 +packetLen(0x0876, 2) + +// Packet: 0x0877 +packetLen(0x0877, 2) + +// Packet: 0x0878 +packetLen(0x0878, 2) + +// Packet: 0x0879 +packetLen(0x0879, 2) + +// Packet: 0x087a +packetLen(0x087a, 2) + +// Packet: 0x087b +packetLen(0x087b, 2) + +// Packet: 0x087c +packetLen(0x087c, 2) + +// Packet: 0x087d +packetLen(0x087d, 2) + +// Packet: 0x087e +packetLen(0x087e, 2) + +// Packet: 0x087f +packetLen(0x087f, 2) + +// Packet: 0x0880 +packetLen(0x0880, 2) + +// Packet: 0x0881 +packetLen(0x0881, 2) + +// Packet: 0x0882 +packetLen(0x0882, 2) + +// Packet: 0x0883 +packetLen(0x0883, 2) + +// Packet: 0x0884 +packetLen(0x0884, 2) + +// Packet: 0x0885 +packetLen(0x0885, 2) + +// Packet: 0x0886 +packetLen(0x0886, 2) + +// Packet: 0x0887 +packetLen(0x0887, 2) + +// Packet: 0x0888 +packetLen(0x0888, 2) + +// Packet: 0x0889 +packetLen(0x0889, 2) + +// Packet: 0x088a +packetLen(0x088a, 2) + +// Packet: 0x088b +packetLen(0x088b, 2) + +// Packet: 0x088c +packetLen(0x088c, 2) + +// Packet: 0x088d +packetLen(0x088d, 2) + +// Packet: 0x088e +packetLen(0x088e, 2) + +// Packet: 0x088f +packetLen(0x088f, 2) + +// Packet: 0x0890 +packetLen(0x0890, 2) + +// Packet: 0x0891 +packetLen(0x0891, 2) + +// Packet: 0x0892 +packetLen(0x0892, 2) + +// Packet: 0x0893 +packetLen(0x0893, 2) + +// Packet: 0x0894 +packetLen(0x0894, 2) + +// Packet: 0x0895 +packetLen(0x0895, 2) + +// Packet: 0x0896 +packetLen(0x0896, 2) + +// Packet: 0x0897 +packetLen(0x0897, 2) + +// Packet: 0x0898 +packetLen(0x0898, 2) + +// Packet: 0x0899 +packetLen(0x0899, 2) + +// Packet: 0x089a +packetLen(0x089a, 2) + +// Packet: 0x089b +packetLen(0x089b, 2) + +// Packet: 0x089c +packetLen(0x089c, 2) + +// Packet: 0x089d +packetLen(0x089d, 2) + +// Packet: 0x089e +packetLen(0x089e, 2) + +// Packet: 0x089f +packetLen(0x089f, 2) + +// Packet: 0x08a0 +packetLen(0x08a0, 2) + +// Packet: 0x08a1 +packetLen(0x08a1, 2) + +// Packet: 0x08a2 +packetLen(0x08a2, 2) + +// Packet: 0x08a3 +packetLen(0x08a3, 2) + +// Packet: 0x08a4 +packetLen(0x08a4, 2) + +// Packet: 0x08a5 +packetLen(0x08a5, 2) + +// Packet: 0x08a6 +packetLen(0x08a6, 2) + +// Packet: 0x08a7 +packetLen(0x08a7, 2) + +// Packet: 0x08a8 +packetLen(0x08a8, 2) + +// Packet: 0x08a9 +packetLen(0x08a9, 2) + +// Packet: 0x08aa +packetLen(0x08aa, 2) + +// Packet: 0x08ab +packetLen(0x08ab, 2) + +// Packet: 0x08ac +packetLen(0x08ac, 2) + +// Packet: 0x08ad +packetLen(0x08ad, 2) + +// Packet: 0x08af +packetLen(0x08af, 10) + +// Packet: 0x08b0 +packetLen(0x08b0, 17) + +// Packet: 0x08b1 +packetLen(0x08b1, -1) + +// Packet: 0x08b2 +packetLen(0x08b2, -1) + +// Packet: 0x08b3 +packetLen(0x08b3, -1) + +// Packet: 0x08b4 +packetLen(0x08b4, 2) + +// Packet: 0x08b5 +packetLen(0x08b5, 6) + +// Packet: 0x08b6 +packetLen(0x08b6, 3) + +// Packet: 0x08b8 +packetLen(0x08b8, 10) + +// Packet: 0x08b9 +packetLen(0x08b9, 12) + +// Packet: 0x08ba +packetLen(0x08ba, 10) + +// Packet: 0x08bb +packetLen(0x08bb, 8) + +// Packet: 0x08bc +packetLen(0x08bc, 10) + +// Packet: 0x08bd +packetLen(0x08bd, 8) + +// Packet: 0x08be +packetLen(0x08be, 14) + +// Packet: 0x08bf +packetLen(0x08bf, 8) + +// Packet: 0x08c0 +packetLen(0x08c0, -1) + +// Packet: 0x08c1 +packetLen(0x08c1, 2) + +// Packet: 0x08c2 +packetLen(0x08c2, 2) + +// Packet: 0x08c3 +packetLen(0x08c3, 10) + +// Packet: 0x08c4 +packetLen(0x08c4, 8) + +// Packet: 0x08c5 +packetLen(0x08c5, 6) + +// Packet: 0x08c6 +packetLen(0x08c6, 4) + +// Packet: 0x08c7 +packetLen(0x08c7, -1) + +// Packet: 0x08c8 +packetLen(0x08c8, 34) + +// Packet: 0x08c9 +packetLen(0x08c9, 2) + +// Packet: 0x08ca +packetLen(0x08ca, -1) + +// Packet: 0x08cb +packetLen(0x08cb, -1) + +// Packet: 0x08cc +packetLen(0x08cc, 109) + +// Packet: 0x08cd +packetLen(0x08cd, 10) + +// Packet: 0x08ce +packetLen(0x08ce, 2) + +// Packet: 0x08cf +packetLen(0x08cf, 10) + +// Packet: 0x08d0 +packetLen(0x08d0, 9) + +// Packet: 0x08d1 +packetLen(0x08d1, 7) + +// Packet: 0x08d2 +packetLen(0x08d2, 10) + +// Packet: 0x08d3 +packetLen(0x08d3, 10) + +// Packet: 0x08d4 +packetLen(0x08d4, 8) + +// Packet: 0x08d5 +packetLen(0x08d5, -1) + +// Packet: 0x08d6 +packetLen(0x08d6, 6) + +// Packet: 0x08d7 +packetLen(0x08d7, 28) + +// Packet: 0x08d8 +packetLen(0x08d8, 27) + +// Packet: 0x08d9 +packetLen(0x08d9, 30) + +// Packet: 0x08da +packetLen(0x08da, 26) + +// Packet: 0x08db +packetLen(0x08db, 27) + +// Packet: 0x08dc +packetLen(0x08dc, 26) + +// Packet: 0x08dd +packetLen(0x08dd, 27) + +// Packet: 0x08de +packetLen(0x08de, 27) + +// Packet: 0x08df +packetLen(0x08df, 50) + +// Packet: 0x08e0 +packetLen(0x08e0, 51) + +// Packet: 0x08e1 +packetLen(0x08e1, 51) + +// Packet: 0x08e2 +packetLen(0x08e2, 27) + +// Packet: 0x08e3 +packetLen(0x08e3, 157) + +// Packet: 0x08e4 +packetLen(0x08e4, 6) + +// Packet: 0x08fc +packetLen(0x08fc, 30) + +// Packet: 0x08fd +packetLen(0x08fd, 6) + +// Packet: 0x08fe +packetLen(0x08fe, -1) + +// Packet: 0x08ff +packetLen(0x08ff, 24) + +// Packet: 0x0900 +packetLen(0x0900, -1) + +// Packet: 0x0901 +packetLen(0x0901, -1) + +// Packet: 0x0902 +packetLen(0x0902, -1) + +// Packet: 0x0903 +packetLen(0x0903, -1) + +// Packet: 0x0904 +packetLen(0x0904, -1) + +// Packet: 0x0905 +packetLen(0x0905, -1) + +// Packet: 0x0906 +packetLen(0x0906, -1) + +// Packet: 0x0907 +packetLen(0x0907, 5) + +// Packet: 0x0908 +packetLen(0x0908, 5) + +// Packet: 0x090a +packetLen(0x090a, 26) + +// Packet: 0x090d +packetLen(0x090d, -1) + +// Packet: 0x090e +packetLen(0x090e, 2) + +// Packet: 0x090f +packetLen(0x090f, -1) + +// Packet: 0x0910 +packetLen(0x0910, 10) + +// Packet: 0x0911 +packetLen(0x0911, 30) + +// Packet: 0x0912 +packetLen(0x0912, 10) + +// Packet: 0x0913 +packetLen(0x0913, 30) + +// Packet: 0x0914 +packetLen(0x0914, -1) + +// Packet: 0x0915 +packetLen(0x0915, -1) + +// Packet: 0x0916 +packetLen(0x0916, 26) + +// Packet: 0x0917 +packetLen(0x0917, 2) + +// Packet: 0x0918 +packetLen(0x0918, 2) + +// Packet: 0x0919 +packetLen(0x0919, 2) + +// Packet: 0x091a +packetLen(0x091a, 2) + +// Packet: 0x091b +packetLen(0x091b, 2) + +// Packet: 0x091c +packetLen(0x091c, 2) + +// Packet: 0x091d +packetLen(0x091d, 2) + +// Packet: 0x091e +packetLen(0x091e, 2) + +// Packet: 0x091f +packetLen(0x091f, 2) + +// Packet: 0x0920 +packetLen(0x0920, 2) + +// Packet: 0x0921 +packetLen(0x0921, 2) + +// Packet: 0x0922 +packetLen(0x0922, 2) + +// Packet: 0x0923 +packetLen(0x0923, 2) + +// Packet: 0x0924 +packetLen(0x0924, 2) + +// Packet: 0x0925 +packetLen(0x0925, 2) + +// Packet: 0x0926 +packetLen(0x0926, 2) + +// Packet: 0x0927 +packetLen(0x0927, 2) + +// Packet: 0x0928 +packetLen(0x0928, 2) + +// Packet: 0x0929 +packetLen(0x0929, 2) + +// Packet: 0x092a +packetLen(0x092a, 2) + +// Packet: 0x092b +packetLen(0x092b, 2) + +// Packet: 0x092c +packetLen(0x092c, 2) + +// Packet: 0x092d +packetLen(0x092d, 2) + +// Packet: 0x092e +packetLen(0x092e, 2) + +// Packet: 0x092f +packetLen(0x092f, 2) + +// Packet: 0x0930 +packetLen(0x0930, 2) + +// Packet: 0x0931 +packetLen(0x0931, 2) + +// Packet: 0x0932 +packetLen(0x0932, 2) + +// Packet: 0x0933 +packetLen(0x0933, 2) + +// Packet: 0x0934 +packetLen(0x0934, 2) + +// Packet: 0x0935 +packetLen(0x0935, 2) + +// Packet: 0x0936 +packetLen(0x0936, 2) + +// Packet: 0x0937 +packetLen(0x0937, 2) + +// Packet: 0x0938 +packetLen(0x0938, 2) + +// Packet: 0x0939 +packetLen(0x0939, 2) + +// Packet: 0x093a +packetLen(0x093a, 2) + +// Packet: 0x093b +packetLen(0x093b, 2) + +// Packet: 0x093c +packetLen(0x093c, 2) + +// Packet: 0x093d +packetLen(0x093d, 2) + +// Packet: 0x093e +packetLen(0x093e, 2) + +// Packet: 0x093f +packetLen(0x093f, 2) + +// Packet: 0x0940 +packetLen(0x0940, 2) + +// Packet: 0x0941 +packetLen(0x0941, 2) + +// Packet: 0x0942 +packetLen(0x0942, 2) + +// Packet: 0x0943 +packetLen(0x0943, 2) + +// Packet: 0x0944 +packetLen(0x0944, 2) + +// Packet: 0x0945 +packetLen(0x0945, 2) + +// Packet: 0x0946 +packetLen(0x0946, 2) + +// Packet: 0x0947 +packetLen(0x0947, 2) + +// Packet: 0x0948 +packetLen(0x0948, 2) + +// Packet: 0x0949 +packetLen(0x0949, 2) + +// Packet: 0x094a +packetLen(0x094a, 2) + +// Packet: 0x094b +packetLen(0x094b, 2) + +// Packet: 0x094c +packetLen(0x094c, 2) + +// Packet: 0x094d +packetLen(0x094d, 2) + +// Packet: 0x094e +packetLen(0x094e, 2) + +// Packet: 0x094f +packetLen(0x094f, 2) + +// Packet: 0x0950 +packetLen(0x0950, 2) + +// Packet: 0x0951 +packetLen(0x0951, 2) + +// Packet: 0x0952 +packetLen(0x0952, 2) + +// Packet: 0x0953 +packetLen(0x0953, 2) + +// Packet: 0x0954 +packetLen(0x0954, 2) + +// Packet: 0x0955 +packetLen(0x0955, 2) + +// Packet: 0x0956 +packetLen(0x0956, 2) + +// Packet: 0x0957 +packetLen(0x0957, 2) + +// Packet: 0x0958 +packetLen(0x0958, 2) + +// Packet: 0x0959 +packetLen(0x0959, 2) + +// Packet: 0x095a +packetLen(0x095a, 2) + +// Packet: 0x095b +packetLen(0x095b, 2) + +// Packet: 0x095c +packetLen(0x095c, 2) + +// Packet: 0x095d +packetLen(0x095d, 2) + +// Packet: 0x095e +packetLen(0x095e, 2) + +// Packet: 0x095f +packetLen(0x095f, 2) + +// Packet: 0x0960 +packetLen(0x0960, 2) + +// Packet: 0x0961 +packetLen(0x0961, 2) + +// Packet: 0x0962 +packetLen(0x0962, 2) + +// Packet: 0x0963 +packetLen(0x0963, 2) + +// Packet: 0x0964 +packetLen(0x0964, 2) + +// Packet: 0x0965 +packetLen(0x0965, 2) + +// Packet: 0x0966 +packetLen(0x0966, 2) + +// Packet: 0x0967 +packetLen(0x0967, 2) + +// Packet: 0x0968 +packetLen(0x0968, 2) + +// Packet: 0x0969 +packetLen(0x0969, 2) + +// Packet: 0x096a +packetLen(0x096a, 2) + +// Packet: 0x096b +packetLen(0x096b, 4) + +// Packet: 0x096c +packetLen(0x096c, 6) + +// Packet: 0x096d +packetLen(0x096d, -1) + +// Packet: 0x096e +packetLen(0x096e, -1) + +// Packet: 0x096f +packetLen(0x096f, 7) + +// Packet: 0x0970 +packetLen(0x0970, 31) + +// Packet: 0x0971 +packetLen(0x0971, 6) + +// Packet: 0x0972 +packetLen(0x0972, -1) + +// Packet: 0x0973 +packetLen(0x0973, 7) + +// Packet: 0x0974 +packetLen(0x0974, 2) + +// Packet: 0x0975 +packetLen(0x0975, -1) + +// Packet: 0x0976 +packetLen(0x0976, -1) + +// Packet: 0x0977 +packetLen(0x0977, 14) + +// Packet: 0x0978 +packetLen(0x0978, 6) + +// Packet: 0x0979 +packetLen(0x0979, 50) + +// Packet: 0x097a +packetLen(0x097a, -1) + +// Packet: 0x097b +packetLen(0x097b, -1) + +// Packet: 0x097c +packetLen(0x097c, 4) + +// Packet: 0x097d +packetLen(0x097d, 288) + +// Packet: 0x097e +packetLen(0x097e, 12) + +// Packet: 0x097f +packetLen(0x097f, -1) + +// Packet: 0x0980 +packetLen(0x0980, 7) + +// Packet: 0x0981 +packetLen(0x0981, -1) + +// Packet: 0x0982 +packetLen(0x0982, 7) + +// Packet: 0x0983 +packetLen(0x0983, 29) + +// Packet: 0x0984 +packetLen(0x0984, 28) + +// Packet: 0x0985 +packetLen(0x0985, -1) + +// Packet: 0x0986 +packetLen(0x0986, 10) + +// Packet: 0x0987 +packetLen(0x0987, -1) + +// Packet: 0x0988 +packetLen(0x0988, 6) + +// Packet: 0x0989 +packetLen(0x0989, 2) + +// Packet: 0x098a +packetLen(0x098a, -1) + +// Packet: 0x098b +packetLen(0x098b, 2) + +// Packet: 0x098c +packetLen(0x098c, 4) + +// Packet: 0x098d +packetLen(0x098d, -1) + +// Packet: 0x098e +packetLen(0x098e, -1) + +// Packet: 0x098f +packetLen(0x098f, -1) + +// Packet: 0x0990 +packetLen(0x0990, 41) + +// Packet: 0x0991 +packetLen(0x0991, -1) + +// Packet: 0x0992 +packetLen(0x0992, -1) + +// Packet: 0x0993 +packetLen(0x0993, -1) + +// Packet: 0x0994 +packetLen(0x0994, -1) + +// Packet: 0x0995 +packetLen(0x0995, -1) + +// Packet: 0x0996 +packetLen(0x0996, -1) + +// Packet: 0x0997 +packetLen(0x0997, -1) + +// Packet: 0x0998 +packetLen(0x0998, 8) + +// Packet: 0x0999 +packetLen(0x0999, 11) + +// Packet: 0x099a +packetLen(0x099a, 9) + +// Packet: 0x099b +packetLen(0x099b, 8) + +// Packet: 0x099c +packetLen(0x099c, 6) + +// Packet: 0x099d +packetLen(0x099d, -1) + +// Packet: 0x099e +packetLen(0x099e, 12) + +// Packet: 0x099f +packetLen(0x099f, -1) + +// Packet: 0x09a0 +packetLen(0x09a0, 6) + +// Packet: 0x09a1 +packetLen(0x09a1, 2) + +// Packet: 0x09a2 +packetLen(0x09a2, 6) + +// Packet: 0x09a3 +packetLen(0x09a3, -1) + +// Packet: 0x09a4 +packetLen(0x09a4, 18) + +// Packet: 0x09a5 +packetLen(0x09a5, 7) + +// Packet: 0x09a6 +packetLen(0x09a6, 12) + +// Packet: 0x09a7 +packetLen(0x09a7, 10) + +// Packet: 0x09a8 +packetLen(0x09a8, 16) + +// Packet: 0x09a9 +packetLen(0x09a9, 10) + +// Packet: 0x09aa +packetLen(0x09aa, 16) + +// Packet: 0x09ab +packetLen(0x09ab, 6) + +// Packet: 0x09ac +packetLen(0x09ac, -1) + +// Packet: 0x09ad +packetLen(0x09ad, 12) + +// Packet: 0x09ae +packetLen(0x09ae, 19) + +// Packet: 0x09af +packetLen(0x09af, 4) + +// Packet: 0x09b0 +packetLen(0x09b0, 10) + +// Packet: 0x09b1 +packetLen(0x09b1, 4) + +// Packet: 0x09b2 +packetLen(0x09b2, 10) + +// Packet: 0x09b3 +packetLen(0x09b3, 6) + +// Packet: 0x09b4 +packetLen(0x09b4, 6) + +// Packet: 0x09b5 +packetLen(0x09b5, 2) + +// Packet: 0x09b6 +packetLen(0x09b6, 6) + +// Packet: 0x09b7 +packetLen(0x09b7, 4) + +// Packet: 0x09b8 +packetLen(0x09b8, 6) + +// Packet: 0x09b9 +packetLen(0x09b9, 4) + +// Packet: 0x09ba +packetLen(0x09ba, 2) + +// Packet: 0x09bb +packetLen(0x09bb, 6) + +// Packet: 0x09bc +packetLen(0x09bc, 6) + +// Packet: 0x09bd +packetLen(0x09bd, 2) + +// Packet: 0x09be +packetLen(0x09be, 2) + +// Packet: 0x09bf +packetLen(0x09bf, 4) + +// Packet: 0x09c1 +packetLen(0x09c1, 10) + +// Packet: 0x09c2 +packetLen(0x09c2, -1) + +// Packet: 0x09c3 +packetLen(0x09c3, 10) + +// Packet: 0x09c4 +packetLen(0x09c4, 10) + +// Packet: 0x09c5 +packetLen(0x09c5, 1042) + +// Packet: 0x09c6 +packetLen(0x09c6, -1) + +// Packet: 0x09c7 +packetLen(0x09c7, 18) + +// Packet: 0x09c8 +packetLen(0x09c8, -1) + +// Packet: 0x09c9 +packetLen(0x09c9, -1) + +// Packet: 0x09ca +packetLen(0x09ca, -1) + +// Packet: 0x09cb +packetLen(0x09cb, 17) + +// Packet: 0x09cc +packetLen(0x09cc, -1) + +// Packet: 0x09cd +packetLen(0x09cd, 8) + +// Packet: 0x09ce +packetLen(0x09ce, 102) + +// Packet: 0x09cf +packetLen(0x09cf, -1) + +// Packet: 0x09d0 +packetLen(0x09d0, -1) + +// Packet: 0x09d1 +packetLen(0x09d1, 14) + +// Packet: 0x09d2 +packetLen(0x09d2, -1) + +// Packet: 0x09d3 +packetLen(0x09d3, -1) + +// Packet: 0x09d4 +packetLen(0x09d4, 2) + +// Packet: 0x09d5 +packetLen(0x09d5, -1) + +// Packet: 0x09d6 +packetLen(0x09d6, -1) + +// Packet: 0x09d7 +packetLen(0x09d7, -1) + +// Packet: 0x09d8 +packetLen(0x09d8, 2) + +// Packet: 0x09d9 +packetLen(0x09d9, 4) + +// Packet: 0x09da +packetLen(0x09da, -1) + +// Packet: 0x09db +packetLen(0x09db, -1) + +// Packet: 0x09dc +packetLen(0x09dc, -1) + +// Packet: 0x09dd +packetLen(0x09dd, -1) + +// Packet: 0x09de +packetLen(0x09de, -1) + +// Packet: 0x09df +packetLen(0x09df, 7) + +// Packet: 0x09e0 +packetLen(0x09e0, -1) + +// Packet: 0x09e1 +packetLen(0x09e1, 8) + +// Packet: 0x09e2 +packetLen(0x09e2, 8) + +// Packet: 0x09e3 +packetLen(0x09e3, 8) + +// Packet: 0x09e4 +packetLen(0x09e4, 8) + +// Packet: 0x09e5 +packetLen(0x09e5, 18) + +// Packet: 0x09e6 +packetLen(0x09e6, 24) + +// Packet: 0x09e7 +packetLen(0x09e7, 3) + +// Packet: 0x09e8 +packetLen(0x09e8, 11) + +// Packet: 0x09e9 +packetLen(0x09e9, 2) + +// Packet: 0x09ea +packetLen(0x09ea, 11) + +// Packet: 0x09eb +packetLen(0x09eb, -1) + +// Packet: 0x09ec +packetLen(0x09ec, -1) + +// Packet: 0x09ed +packetLen(0x09ed, 3) + +// Packet: 0x09ee +packetLen(0x09ee, 11) + +// Packet: 0x09ef +packetLen(0x09ef, 11) + +// Packet: 0x09f0 +packetLen(0x09f0, -1) + +// Packet: 0x09f1 +packetLen(0x09f1, 11) + +// Packet: 0x09f2 +packetLen(0x09f2, 12) + +// Packet: 0x09f3 +packetLen(0x09f3, 11) + +// Packet: 0x09f4 +packetLen(0x09f4, 12) + +// Packet: 0x09f5 +packetLen(0x09f5, 11) + +// Packet: 0x09f6 +packetLen(0x09f6, 11) + +// Packet: 0x09f7 +packetLen(0x09f7, 77) + +// Packet: 0x09f8 +packetLen(0x09f8, -1) + +// Packet: 0x09f9 +packetLen(0x09f9, 143) + +// Packet: 0x09fa +packetLen(0x09fa, -1) + +// Packet: 0x09fb +packetLen(0x09fb, -1) + +// Packet: 0x09fc +packetLen(0x09fc, 6) + +// Packet: 0x09fd +packetLen(0x09fd, -1) + +// Packet: 0x09fe +packetLen(0x09fe, -1) + +// Packet: 0x09ff +packetLen(0x09ff, -1) + +// Packet: 0x0a00 +packetLen(0x0a00, 269) + +// Packet: 0x0a01 +packetLen(0x0a01, 3) + +// Packet: 0x0a02 +packetLen(0x0a02, 4) + +// Packet: 0x0a03 +packetLen(0x0a03, 2) + +// Packet: 0x0a04 +packetLen(0x0a04, 6) + +// Packet: 0x0a05 +packetLen(0x0a05, 63) + +// Packet: 0x0a06 +packetLen(0x0a06, 6) + +// Packet: 0x0a07 +packetLen(0x0a07, 9) + +// Packet: 0x0a08 +packetLen(0x0a08, 26) + +// Packet: 0x0a09 +packetLen(0x0a09, 55) + +// Packet: 0x0a0a +packetLen(0x0a0a, 57) + +// Packet: 0x0a0b +packetLen(0x0a0b, 57) + +// Packet: 0x0a0c +packetLen(0x0a0c, 66) + +// Packet: 0x0a0d +packetLen(0x0a0d, -1) + +// Packet: 0x0a0e +packetLen(0x0a0e, 14) + +// Packet: 0x0a0f +packetLen(0x0a0f, -1) + +// Packet: 0x0a10 +packetLen(0x0a10, -1) + +// Packet: 0x0a11 +packetLen(0x0a11, -1) + +// Packet: 0x0a12 +packetLen(0x0a12, 27) + +// Packet: 0x0a13 +packetLen(0x0a13, 26) + +// Packet: 0x0a14 +packetLen(0x0a14, 10) + +// Packet: 0x0a15 +packetLen(0x0a15, 12) + +// Packet: 0x0a16 +packetLen(0x0a16, 26) + +// Packet: 0x0a17 +packetLen(0x0a17, 6) + +// Packet: 0x0a18 +packetLen(0x0a18, 14) + +// Packet: 0x0a19 +packetLen(0x0a19, 2) + +// Packet: 0x0a1a +packetLen(0x0a1a, 25) + +// Packet: 0x0a1b +packetLen(0x0a1b, 2) + +// Packet: 0x0a1c +packetLen(0x0a1c, -1) + +// Packet: 0x0a1d +packetLen(0x0a1d, 2) + +// Packet: 0x0a1e +packetLen(0x0a1e, 3) + +// Packet: 0x0a1f +packetLen(0x0a1f, 2) + +// Packet: 0x0a20 +packetLen(0x0a20, 23) + +// Packet: 0x0a21 +packetLen(0x0a21, 3) + +// Packet: 0x0a22 +packetLen(0x0a22, 7) + +// Packet: 0x0a23 +packetLen(0x0a23, -1) + +// Packet: 0x0a24 +packetLen(0x0a24, 66) + +// Packet: 0x0a25 +packetLen(0x0a25, 6) + +// Packet: 0x0a26 +packetLen(0x0a26, 7) + +// Packet: 0x0a27 +packetLen(0x0a27, 8) + +// Packet: 0x0a28 +packetLen(0x0a28, 3) + +// Packet: 0x0a29 +packetLen(0x0a29, 6) + +// Packet: 0x0a2a +packetLen(0x0a2a, 6) + +// Packet: 0x0a2b +packetLen(0x0a2b, 14) + +// Packet: 0x0a2c +packetLen(0x0a2c, 12) + +// Packet: 0x0a2d +packetLen(0x0a2d, -1) + +// Packet: 0x0a2e +packetLen(0x0a2e, 6) + +// Packet: 0x0a2f +packetLen(0x0a2f, 7) + +// Packet: 0x0a30 +packetLen(0x0a30, 106) + +// Packet: 0x0a31 +packetLen(0x0a31, -1) + +// Packet: 0x0a32 +packetLen(0x0a32, 2) + +// Packet: 0x0a33 +packetLen(0x0a33, 7) + +// Packet: 0x0a34 +packetLen(0x0a34, 6) + +// Packet: 0x0a35 +packetLen(0x0a35, 4) + +// Packet: 0x0a36 +packetLen(0x0a36, 7) + +// Packet: 0x0a37 +packetLen(0x0a37, 69) + +// Packet: 0x0a38 +packetLen(0x0a38, 3) + +// Packet: 0x0a39 +packetLen(0x0a39, 36) + +// Packet: 0x0a3a +packetLen(0x0a3a, 12) + +// Packet: 0x0a3b +packetLen(0x0a3b, -1) + +// Packet: 0x0a3c +packetLen(0x0a3c, -1) + +// Packet: 0x0a3d +packetLen(0x0a3d, 20) + +// Packet: 0x0a3e +packetLen(0x0a3e, -1) + +// Packet: 0x0a3f +packetLen(0x0a3f, 11) + +// Packet: 0x0a40 +packetLen(0x0a40, 11) + +// Packet: 0x0a41 +packetLen(0x0a41, 18) + +// Packet: 0x0a42 +packetLen(0x0a42, 43) + +// Packet: 0x0a43 +packetLen(0x0a43, 85) + +// Packet: 0x0a44 +packetLen(0x0a44, -1) + +// Packet: 0x0a46 +packetLen(0x0a46, 14) + +// Packet: 0x0a47 +packetLen(0x0a47, 3) + +// Packet: 0x0a48 +packetLen(0x0a48, 2) + +// Packet: 0x0a49 +packetLen(0x0a49, 22) + +// Packet: 0x0a4a +packetLen(0x0a4a, 6) + +// Packet: 0x0a4b +packetLen(0x0a4b, 22) + +// Packet: 0x0a4c +packetLen(0x0a4c, 28) + +// Packet: 0x0a4d +packetLen(0x0a4d, -1) + +// Packet: 0x0a4e +packetLen(0x0a4e, 6) + +// Packet: 0x0a4f +packetLen(0x0a4f, -1) + +// Packet: 0x0a50 +packetLen(0x0a50, 4) + +// Packet: 0x0a51 +packetLen(0x0a51, 34) + +// Packet: 0x0a52 +packetLen(0x0a52, 20) + +// Packet: 0x0a53 +packetLen(0x0a53, 10) + +// Packet: 0x0a54 +packetLen(0x0a54, -1) + +// Packet: 0x0a55 +packetLen(0x0a55, 2) + +// Packet: 0x0a56 +packetLen(0x0a56, 6) + +// Packet: 0x0a57 +packetLen(0x0a57, 6) + +// Packet: 0x0a58 +packetLen(0x0a58, 8) + +// Packet: 0x0a59 +packetLen(0x0a59, -1) + +// Packet: 0x0a5a +packetLen(0x0a5a, 2) + +// Packet: 0x0a5b +packetLen(0x0a5b, 7) + +// Packet: 0x0a5c +packetLen(0x0a5c, 18) + +// Packet: 0x0a5d +packetLen(0x0a5d, 6) + +// Packet: 0x0a68 +packetLen(0x0a68, 3) + +// Packet: 0x0a69 +packetLen(0x0a69, 6) + +// Packet: 0x0a6a +packetLen(0x0a6a, 12) + +// Packet: 0x0a6b +packetLen(0x0a6b, -1) + +// Packet: 0x0a6c +packetLen(0x0a6c, 7) + +// Packet: 0x0a6d +packetLen(0x0a6d, -1) + +// Packet: 0x0a6e +packetLen(0x0a6e, -1) + +// Packet: 0x0a6f +packetLen(0x0a6f, -1) + +// Packet: 0x0a70 +packetLen(0x0a70, 2) + +// Packet: 0x0a71 +packetLen(0x0a71, -1) + +// Packet: 0x0a72 +packetLen(0x0a72, 61) + +// Packet: 0x0a73 +packetLen(0x0a73, 2) + +// Packet: 0x0a74 +packetLen(0x0a74, 8) + +// Packet: 0x0a76 +packetLen(0x0a76, 80) + +// Packet: 0x0a77 +packetLen(0x0a77, 15) + +// Packet: 0x0a78 +packetLen(0x0a78, 15) + +// Packet: 0x0a79 +packetLen(0x0a79, -1) + +// Packet: 0x0a7b +packetLen(0x0a7b, -1) + +// Packet: 0x0a7c +packetLen(0x0a7c, -1) + +// Packet: 0x0a7d +packetLen(0x0a7d, -1) + +// Packet: 0x0a7e +packetLen(0x0a7e, -1) + +// Packet: 0x0a7f +packetLen(0x0a7f, -1) + +// Packet: 0x0a80 +packetLen(0x0a80, 6) + +// Packet: 0x0a81 +packetLen(0x0a81, 4) + +// Packet: 0x0a82 +packetLen(0x0a82, 46) + +// Packet: 0x0a83 +packetLen(0x0a83, 46) + +// Packet: 0x0a84 +packetLen(0x0a84, 94) + +// Packet: 0x0a85 +packetLen(0x0a85, 82) + +// Packet: 0x0a86 +packetLen(0x0a86, -1) + +// Packet: 0x0a87 +packetLen(0x0a87, -1) + +// Packet: 0x0a88 +packetLen(0x0a88, 2) + +// Packet: 0x0a89 +packetLen(0x0a89, 61) + +// Packet: 0x0a8a +packetLen(0x0a8a, 6) + +// Packet: 0x0a8b +packetLen(0x0a8b, 2) + +// Packet: 0x0a8c +packetLen(0x0a8c, 2) + +// Packet: 0x0a8d +packetLen(0x0a8d, -1) + +// Packet: 0x0a8e +packetLen(0x0a8e, 2) + +// Packet: 0x0a8f +packetLen(0x0a8f, 2) + +// Packet: 0x0a90 +packetLen(0x0a90, 3) + +// Packet: 0x0a91 +packetLen(0x0a91, -1) + +// Packet: 0x0a92 +packetLen(0x0a92, -1) + +// Packet: 0x0a93 +packetLen(0x0a93, 3) + +// Packet: 0x0a94 +packetLen(0x0a94, 2) + +// Packet: 0x0a95 +packetLen(0x0a95, 4) + +// Packet: 0x0a96 +packetLen(0x0a96, 61) + +// Packet: 0x0a97 +packetLen(0x0a97, 8) + +// Packet: 0x0a98 +packetLen(0x0a98, 10) + +// Packet: 0x0a99 +packetLen(0x0a99, 4) + +// Packet: 0x0a9a +packetLen(0x0a9a, 10) + +// Packet: 0x0a9b +packetLen(0x0a9b, -1) + +// Packet: 0x0a9c +packetLen(0x0a9c, 2) + +// Packet: 0x0a9d +packetLen(0x0a9d, 4) + +// Packet: 0x0a9e +packetLen(0x0a9e, 2) + +// Packet: 0x0a9f +packetLen(0x0a9f, 2) + +// Packet: 0x0aa0 +packetLen(0x0aa0, 2) + +// Packet: 0x0aa1 +packetLen(0x0aa1, 4) + +// Packet: 0x0aa2 +packetLen(0x0aa2, -1) + +// Packet: 0x0aa3 +packetLen(0x0aa3, 9) + +// Packet: 0x0aa4 +packetLen(0x0aa4, 2) + +// Packet: 0x0aa5 +packetLen(0x0aa5, -1) + +// Packet: 0x0aa6 +packetLen(0x0aa6, 36) + +// Packet: 0x0aa7 +packetLen(0x0aa7, 6) + +// Packet: 0x0aa8 +packetLen(0x0aa8, 5) + +// Packet: 0x0aa9 +packetLen(0x0aa9, -1) + +// Packet: 0x0aaa +packetLen(0x0aaa, -1) + +// Packet: 0x0aab +packetLen(0x0aab, -1) + +// Packet: 0x0aac +packetLen(0x0aac, 69) + +// Packet: 0x0aad +packetLen(0x0aad, 51) + +// Packet: 0x0aae +packetLen(0x0aae, 2) + +// Packet: 0x0aaf +packetLen(0x0aaf, 6) + +// Packet: 0x0ab0 +packetLen(0x0ab0, 6) + +// Packet: 0x0ab1 +packetLen(0x0ab1, 14) + +// Packet: 0x0ab2 +packetLen(0x0ab2, 7) + +// Packet: 0x0ab3 +packetLen(0x0ab3, 19) + +// Packet: 0x0ab4 +packetLen(0x0ab4, 6) + +// Packet: 0x0ab5 +packetLen(0x0ab5, 2) + +// Packet: 0x0ab6 +packetLen(0x0ab6, 8) + +// Packet: 0x0ab7 +packetLen(0x0ab7, 4) + +// Packet: 0x0ab8 +packetLen(0x0ab8, 2) + +// Packet: 0x0ab9 +packetLen(0x0ab9, 47) + +// Packet: 0x0aba +packetLen(0x0aba, 2) + +// Packet: 0x0abb +packetLen(0x0abb, 2) + +// Packet: 0x0abc +packetLen(0x0abc, -1) + +// Packet: 0x0abd +packetLen(0x0abd, 10) + +// Packet: 0x0abe +packetLen(0x0abe, -1) + +// Packet: 0x0abf +packetLen(0x0abf, -1) + +// Packet: 0x0ac0 +packetLen(0x0ac0, 26) + +// Packet: 0x0ac1 +packetLen(0x0ac1, 26) + +// Packet: 0x0ac2 +packetLen(0x0ac2, -1) + +// Packet: 0x0ac3 +packetLen(0x0ac3, 2) + +// Packet: 0x0ac4 +packetLen(0x0ac4, -1) + +// Packet: 0x0ac5 +packetLen(0x0ac5, 156) + +// Packet: 0x0ac6 +packetLen(0x0ac6, 156) + +// Packet: 0x0ac7 +packetLen(0x0ac7, 156) + +// Packet: 0x0ac8 +packetLen(0x0ac8, 2) + +// Packet: 0x0ac9 +packetLen(0x0ac9, -1) + +// Packet: 0x0aca +packetLen(0x0aca, 3) + +// Packet: 0x0acb +packetLen(0x0acb, 12) + +// Packet: 0x0acc +packetLen(0x0acc, 18) + +// Packet: 0x0acd +packetLen(0x0acd, 23) + +// Packet: 0x0ace +packetLen(0x0ace, 4) + +// Packet: 0x0acf +packetLen(0x0acf, 68) + +// Packet: 0x0ad0 +packetLen(0x0ad0, 11) + +// Packet: 0x0ad1 +packetLen(0x0ad1, -1) + +// Packet: 0x0ad2 +packetLen(0x0ad2, 30) + +// Packet: 0x0ad3 +packetLen(0x0ad3, -1) + +// Packet: 0x0ad4 +packetLen(0x0ad4, -1) + +// Packet: 0x0ad5 +packetLen(0x0ad5, 2) + +// Packet: 0x0ad6 +packetLen(0x0ad6, 2) + +// Packet: 0x0ad7 +packetLen(0x0ad7, 8) + +// Packet: 0x0ad8 +packetLen(0x0ad8, 8) + +// Packet: 0x0ad9 +packetLen(0x0ad9, -1) + +// Packet: 0x0ada +packetLen(0x0ada, 32) + +// Packet: 0x0adb +packetLen(0x0adb, -1) + +// Packet: 0x0adc +packetLen(0x0adc, 6) + +// Packet: 0x0add +packetLen(0x0add, 24) + +// Packet: 0x0ade +packetLen(0x0ade, 6) + +// Packet: 0x0adf +packetLen(0x0adf, 58) + +// Packet: 0x0ae0 +packetLen(0x0ae0, 30) + +// Packet: 0x0ae1 +packetLen(0x0ae1, 28) + +// Packet: 0x0ae2 +packetLen(0x0ae2, 7) + +// Packet: 0x0ae3 +packetLen(0x0ae3, -1) + +// Packet: 0x0ae4 +packetLen(0x0ae4, 89) + +// Packet: 0x0ae5 +packetLen(0x0ae5, -1) + +// Packet: 0x0ae6 +packetLen(0x0ae6, 10) + +// Packet: 0x0ae7 +packetLen(0x0ae7, 38) + +// Packet: 0x0ae8 +packetLen(0x0ae8, 2) + +// Packet: 0x0ae9 +packetLen(0x0ae9, 13) + +// Packet: 0x0aec +packetLen(0x0aec, 2) + +// Packet: 0x0aed +packetLen(0x0aed, 2) + +// Packet: 0x0aee +packetLen(0x0aee, 2) + +// Packet: 0x0aef +packetLen(0x0aef, 2) + +// Packet: 0x0af0 +packetLen(0x0af0, 10) + +// Packet: 0x0af2 +packetLen(0x0af2, 40) + +// Packet: 0x0af3 +packetLen(0x0af3, -1) + +// Packet: 0x0af4 +packetLen(0x0af4, 11) + +// Packet: 0x0af5 +packetLen(0x0af5, 3) + +// Packet: 0x0af6 +packetLen(0x0af6, 88) + +// Packet: 0x0af7 +packetLen(0x0af7, 32) + +// Packet: 0x0af8 +packetLen(0x0af8, 11) + +// Packet: 0x0af9 +packetLen(0x0af9, 6) + +// Packet: 0x0afa +packetLen(0x0afa, 58) + +// Packet: 0x0afb +packetLen(0x0afb, -1) + +// Packet: 0x0afc +packetLen(0x0afc, 16) + +// Packet: 0x0afd +packetLen(0x0afd, -1) + +// Packet: 0x0afe +packetLen(0x0afe, -1) + +// Packet: 0x0aff +packetLen(0x0aff, -1) + +// Packet: 0x0b00 +packetLen(0x0b00, 8) + +// Packet: 0x0b01 +packetLen(0x0b01, 56) + +// Packet: 0x0b02 +packetLen(0x0b02, 26) + +// Packet: 0x0b03 +packetLen(0x0b03, -1) + +// Packet: 0x0b04 +packetLen(0x0b04, 90) + +// Packet: 0x0b05 +packetLen(0x0b05, 63) + +// Packet: 0x0b07 +packetLen(0x0b07, -1) + +// Packet: 0x0b08 +packetLen(0x0b08, -1) + +// Packet: 0x0b09 +packetLen(0x0b09, -1) + +// Packet: 0x0b0a +packetLen(0x0b0a, -1) + +// Packet: 0x0b0b +packetLen(0x0b0b, 4) + +// Packet: 0x0b0c +packetLen(0x0b0c, 155) + +// Packet: 0x0b0d +packetLen(0x0b0d, 10) + +// Packet: 0x0b0e +packetLen(0x0b0e, -1) + +// Packet: 0x0b0f +packetLen(0x0b0f, -1) + +// Packet: 0x0b10 +packetLen(0x0b10, 10) + +// Packet: 0x0b11 +packetLen(0x0b11, 4) + +// Packet: 0x0b12 +packetLen(0x0b12, 2) + +// Packet: 0x0b13 +packetLen(0x0b13, 48) + +// Packet: 0x0b14 +packetLen(0x0b14, 2) + +// Packet: 0x0b15 +packetLen(0x0b15, 7) + +// Packet: 0x0b16 +packetLen(0x0b16, 2) + +// Packet: 0x0b17 +packetLen(0x0b17, 3) + +// Packet: 0x0b18 +packetLen(0x0b18, 4) + +// Packet: 0x0b19 +packetLen(0x0b19, 2) + +// Packet: 0x0b1a +packetLen(0x0b1a, 29) + +// Packet: 0x0b1b +packetLen(0x0b1b, 2) + +// Packet: 0x0b1c +packetLen(0x0b1c, 2) + +// Packet: 0x0b1d +packetLen(0x0b1d, 2) + +// Packet: 0x0b1e +packetLen(0x0b1e, 14) + +// Packet: 0x0b1f +packetLen(0x0b1f, 14) + +// Packet: 0x0b20 +packetLen(0x0b20, 271) + +// Packet: 0x0b21 +packetLen(0x0b21, 13) + +// Packet: 0x0b22 +packetLen(0x0b22, 5) + +// Packet: 0x0b23 +packetLen(0x0b23, 6) + +// Packet: 0x0b24 +packetLen(0x0b24, 6) + +// Packet: 0x0b25 +packetLen(0x0b25, 6) + +// Packet: 0x0b27 +packetLen(0x0b27, -1) + +// Packet: 0x0b28 +packetLen(0x0b28, 3) + +// Packet: 0x0b2b +packetLen(0x0b2b, 11) + +// Packet: 0x0b2c +packetLen(0x0b2c, 3) + +// Packet: 0x0b2d +packetLen(0x0b2d, 11) + +// Packet: 0x0b2e +packetLen(0x0b2e, 4) + +// Packet: 0x0b2f +packetLen(0x0b2f, 73) + +// Packet: 0x0b30 +packetLen(0x0b30, -1) + +// Packet: 0x0b31 +packetLen(0x0b31, 17) + +// Packet: 0x0b32 +packetLen(0x0b32, -1) + +// Packet: 0x0b33 +packetLen(0x0b33, 17) + +// Packet: 0x0b34 +packetLen(0x0b34, 50) + +// Packet: 0x0b35 +packetLen(0x0b35, 3) + +// Packet: 0x0b36 +packetLen(0x0b36, -1) + +// Packet: 0x0b37 +packetLen(0x0b37, -1) + +// Packet: 0x0b39 +packetLen(0x0b39, -1) + +// Packet: 0x0b3c +packetLen(0x0b3c, 4) + +// Packet: 0x0b3d +packetLen(0x0b3d, -1) + +// Packet: 0x0b3e +packetLen(0x0b3e, -1) + +// Packet: 0x0b3f +packetLen(0x0b3f, 64) + +// Packet: 0x0b40 +packetLen(0x0b40, -1) + +// Packet: 0x0b41 +packetLen(0x0b41, 70) + +// Packet: 0x0b42 +packetLen(0x0b42, 62) + +// Packet: 0x0b43 +packetLen(0x0b43, 48) + +// Packet: 0x0b44 +packetLen(0x0b44, 58) + +// Packet: 0x0b45 +packetLen(0x0b45, 58) + +// Packet: 0x0b46 +packetLen(0x0b46, 10) + +// Packet: 0x0b47 +packetLen(0x0b47, 14) + +// Packet: 0x0b48 +packetLen(0x0b48, 18) + +// Packet: 0x0b49 +packetLen(0x0b49, 4) + +// Packet: 0x0b4a +packetLen(0x0b4a, 6) + +// Packet: 0x0b4b +packetLen(0x0b4b, 4) + +// Packet: 0x0b4c +packetLen(0x0b4c, 2) + +// Packet: 0x0b4d +packetLen(0x0b4d, -1) + +// Packet: 0x0b4e +packetLen(0x0b4e, -1) + +// Packet: 0x0b4f +packetLen(0x0b4f, 2) + +// Packet: 0x0b50 +packetLen(0x0b50, 2) + +// Packet: 0x0b51 +packetLen(0x0b51, 2) + +// Packet: 0x0b52 +packetLen(0x0b52, 2) + +// Packet: 0x0b53 +packetLen(0x0b53, 52) + +// Packet: 0x0b54 +packetLen(0x0b54, 8) + +// Packet: 0x0b55 +packetLen(0x0b55, -1) + +// Packet: 0x0b56 +packetLen(0x0b56, -1) + +// Packet: 0x0b57 +packetLen(0x0b57, -1) + +// Packet: 0x0b58 +packetLen(0x0b58, 2) + +// Packet: 0x0b59 +packetLen(0x0b59, 4) + +// Packet: 0x0b5a +packetLen(0x0b5a, -1) + +// Packet: 0x0b5b +packetLen(0x0b5b, 14) + +// Packet: 0x0b5c +packetLen(0x0b5c, 2) + +// Packet: 0x0b5d +packetLen(0x0b5d, 10) + +// Packet: 0x0b5e +packetLen(0x0b5e, 33) + +// Packet: 0x0b5f +packetLen(0x0b5f, -1) + +// Packet: 0x0b60 +packetLen(0x0b60, -1) + +// Packet: 0x0b61 +packetLen(0x0b61, -1) + +// Packet: 0x0b62 +packetLen(0x0b62, -1) + +// Packet: 0x0b63 +packetLen(0x0b63, -1) + +// Packet: 0x0b64 +packetLen(0x0b64, -1) + +// Packet: 0x0b65 +packetLen(0x0b65, -1) + +// Packet: 0x0b66 +packetLen(0x0b66, 26) + +// Packet: 0x0b67 +packetLen(0x0b67, 33) + +// Packet: 0x0b68 +packetLen(0x0b68, 12) + +// Packet: 0x0b69 +packetLen(0x0b69, 18) + +// Packet: 0x0b6a +packetLen(0x0b6a, -1) + +// Packet: 0x0b6b +packetLen(0x0b6b, 14) + +// Packet: 0x0b6c +packetLen(0x0b6c, 12) + +// Packet: 0x0b6d +packetLen(0x0b6d, 6) + +// Packet: 0x0b6e +packetLen(0x0b6e, 14) + +// Packet: 0x0b6f +#if PACKETVER >= 20200129 +packetLen(0x0b6f, 177) +#endif + +// Packet: 0x0b70 +#if PACKETVER >= 20200129 +packetLen(0x0b70, 8) +#endif + +// Packet: 0x0b71 +#if PACKETVER >= 20200129 +packetLen(0x0b71, 177) +#endif + +// Packet: 0x0b72 +#if PACKETVER >= 20200129 +packetLen(0x0b72, 4) +#endif + + +#endif /* COMMON_PACKETS2020_LEN_ZERO_H */ diff --git a/src/common/packets/packets_len_main.h b/src/common/packets/packets_len_main.h index 365b0af6f..7b93b35b0 100644 --- a/src/common/packets/packets_len_main.h +++ b/src/common/packets/packets_len_main.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2018-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2018-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/common/packets/packets_len_re.h b/src/common/packets/packets_len_re.h index 302381722..23a507886 100644 --- a/src/common/packets/packets_len_re.h +++ b/src/common/packets/packets_len_re.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2018-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2018-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/common/packets/packets_len_zero.h b/src/common/packets/packets_len_zero.h index 1385c80ee..9f1595459 100644 --- a/src/common/packets/packets_len_zero.h +++ b/src/common/packets/packets_len_zero.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2018-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2018-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,9 @@ /* This file is autogenerated, please do not commit manual changes */ -#if PACKETVER >= 20190000 +#if PACKETVER >= 20200000 +#include "common/packets/packets2020_len_zero.h" +#elif PACKETVER >= 20190000 #include "common/packets/packets2019_len_zero.h" #elif PACKETVER >= 20180000 #include "common/packets/packets2018_len_zero.h" diff --git a/src/common/utils.c b/src/common/utils.c index 48ce539b6..084080df7 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -132,7 +132,7 @@ void findfile(const char *p, const char *pat, void (func)(const char *, void *co { WIN32_FIND_DATAA FindFileData; HANDLE hFind; - char tmppath[MAX_PATH+1]; + char tmppath[MAX_DIR_PATH + 1]; const char *path = (p ==NULL)? "." : p; const char *pattern = (pat==NULL)? "" : pat; @@ -166,9 +166,26 @@ void findfile(const char *p, const char *pat, void (func)(const char *, void *co } return; } -#else -#define MAX_DIR_PATH 2048 +/** + * Checks if the passed path points to a file. + * + * @param path The path which should be checked. + * @return true if the passed path points to a file, otherwise false. + * + **/ +bool is_file(const char *path) +{ + nullpo_retr(false, path); + + char path_tmp[MAX_DIR_PATH + 1]; + + checkpath(path_tmp, path); + + return ((GetFileAttributesA(path_tmp) & FILE_ATTRIBUTE_DIRECTORY) == 0); +} + +#else static char *checkpath(char *path, const char *srcpath) { @@ -235,6 +252,27 @@ void findfile(const char *p, const char *pat, void (func)(const char *, void *co closedir(dir); } + +/** + * Checks if the passed path points to a file. + * + * @param path The path which should be checked. + * @return true if the passed path points to a file, otherwise false. + * + **/ +bool is_file(const char *path) +{ + nullpo_retr(false, path); + + char path_tmp[MAX_DIR_PATH + 1]; + + checkpath(path_tmp, path); + + struct stat path_stat; + + return (stat(path_tmp, &path_stat) == 0 && S_ISREG(path_stat.st_mode)); +} + #endif bool exists(const char *filename) diff --git a/src/common/utils.h b/src/common/utils.h index a0590db7f..3e0d73e40 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -31,6 +31,14 @@ /* [HCache] 1-byte key to ensure our method is the latest, we can modify to ensure the method matches */ #define HCACHE_KEY 'k' +#ifndef MAX_DIR_PATH +#ifdef WIN32 +#define MAX_DIR_PATH MAX_PATH +#else +#define MAX_DIR_PATH 2048 +#endif +#endif + //Caps values to min/max #define cap_value(a, min, max) (((a) >= (max)) ? (max) : ((a) <= (min)) ? (min) : (a)) @@ -40,6 +48,7 @@ void WriteDump(FILE* fp, const void* buffer, size_t length); void ShowDump(const void* buffer, size_t length); void findfile(const char *p, const char *pat, void (func)(const char *, void *), void *context); +bool is_file(const char *path); bool exists(const char* filename); /// calculates the value of A / B, in percent (rounded down) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3cd26079d..707522423 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -4212,12 +4212,19 @@ ACMD(mount_peco) return true; } if ((sd->job & MAPID_THIRDMASK) == MAPID_MECHANIC) { + int mtype = MADO_ROBOT; + if (!*message) + sscanf(message, "%d", &mtype); + if (mtype < MADO_ROBOT || mtype >= MADO_MAX) { + clif->message(fd, msg_fd(fd, 173)); // Please enter a valid madogear type. + return false; + } if (!pc_ismadogear(sd)) { clif->message(sd->fd,msg_fd(fd,1123)); // You have mounted your Mado Gear. - pc->setmadogear(sd, true); + pc->setmadogear(sd, true, (enum mado_type)mtype); } else { clif->message(sd->fd,msg_fd(fd,1124)); // You have released your Mado Gear. - pc->setmadogear(sd, false); + pc->setmadogear(sd, false, (enum mado_type)mtype); } return true; } @@ -4483,59 +4490,90 @@ ACMD(loadnpc) return true; } +/** + * Unloads a specific NPC. + * + * @code{.herc} + * @unloadnpc <NPC_name> {<flag>} + * @endcode + * + **/ ACMD(unloadnpc) { - struct npc_data *nd; - char NPCname[NAME_LENGTH+1]; - - memset(NPCname, '\0', sizeof(NPCname)); + char npc_name[NAME_LENGTH + 1] = {'\0'}; + int flag = 1; - if (!*message || sscanf(message, "%24[^\n]", NPCname) < 1) { - clif->message(fd, msg_fd(fd,1133)); // Please enter a NPC name (usage: @npcoff <NPC_name>). + if (*message == '\0' || sscanf(message, "%24s %1d", npc_name, &flag) < 1) { + clif->message(fd, msg_fd(fd, 1133)); /// Please enter a NPC name (Usage: @unloadnpc <NPC_name> {<flag>}). return false; } - - if ((nd = npc->name2id(NPCname)) == NULL) { - clif->message(fd, msg_fd(fd,111)); // This NPC doesn't exist. + + struct npc_data *nd = npc->name2id(npc_name); + + if (nd == NULL) { + clif->message(fd, msg_fd(fd, 111)); /// This NPC doesn't exist. return false; } - npc->unload_duplicates(nd); - npc->unload(nd,true); + npc->unload_duplicates(nd, (flag != 0)); + npc->unload(nd, true, (flag != 0)); npc->read_event_script(); - clif->message(fd, msg_fd(fd,112)); // Npc Disabled. + clif->message(fd, msg_fd(fd, 112)); /// Npc Disabled. return true; } -/// Unload existing NPC within the NPC file and reload it. -/// Usage: @reloadnpc npc/sample_npc.txt +/** + * Unloads a script file and reloads it. + * Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details. + * + * @code{.herc} + * @reloadnpc <path> {<flag>} + * @endcode + * + **/ ACMD(reloadnpc) { - if (!*message) { - clif->message(fd, msg_fd(fd, 1385)); // Usage: @unloadnpcfile <file name> + char format[20]; + + snprintf(format, sizeof(format), "%%%ds %%1d", MAX_DIR_PATH); + + char file_path[MAX_DIR_PATH + 1] = {'\0'}; + int flag = 1; + + if (*message == '\0' || (sscanf(message, format, file_path, &flag) < 1)) { + clif->message(fd, msg_fd(fd, 1516)); /// Usage: @reloadnpc <path> {<flag>} return false; - } else if (npc->unloadfile(message) == true) { - clif->message(fd, msg_fd(fd, 1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed. + } - FILE *fp = fopen(message, "r"); - // check if script file exists - if (fp == NULL) { - clif->message(fd, msg_fd(fd, 261)); - return false; - } - fclose(fp); + if (!exists(file_path)) { + clif->message(fd, msg_fd(fd, 1387)); /// File not found. + return false; + } - // add to list of script sources and run it - npc->addsrcfile(message); - npc->parsesrcfile(message, true); - npc->read_event_script(); + if (!is_file(file_path)) { + clif->message(fd, msg_fd(fd, 1518)); /// Not a file. + return false; + } - clif->message(fd, msg_fd(fd, 262)); - } else { - clif->message(fd, msg_fd(fd, 1387)); // File not found. + FILE *fp = fopen(file_path, "r"); + + if (fp == NULL) { + clif->message(fd, msg_fd(fd, 1519)); /// Can't open file. + return false; + } + + fclose(fp); + + if (!npc->unloadfile(file_path, (flag != 0))) { + clif->message(fd, msg_fd(fd, 1517)); /// Script could not be unloaded. return false; } + clif->message(fd, msg_fd(fd, 1386)); /// File unloaded. Be aware that... + npc->addsrcfile(file_path); + npc->parsesrcfile(file_path, true); + npc->read_event_script(); + clif->message(fd, msg_fd(fd, 262)); /// Script loaded. return true; } @@ -6576,47 +6614,52 @@ ACMD(reset) /*========================================== * *------------------------------------------*/ + +/** + * Spawns mobs which treats the invoking as its master. + * + * @code{.herc} + * @summon <monster name/ID> {<duration>} + * @endcode + * + **/ ACMD(summon) { - char name[NAME_LENGTH]; - int mob_id = 0; + char name[NAME_LENGTH + 1] = {'\0'}; int duration = 0; - struct mob_data *md; - int64 tick=timer->gettick(); - if (!*message || sscanf(message, "%23s %12d", name, &duration) < 1) - { - clif->message(fd, msg_fd(fd,1225)); // Please enter a monster name (usage: @summon <monster name> {duration}). + if (*message == '\0' || sscanf(message, "%24s %12d", name, &duration) < 1) { + clif->message(fd, msg_fd(fd, 1225)); /// Please enter a monster name (usage: @summon <monster name> {duration}). return false; } - if (duration < 1) - duration =1; - else if (duration > 60) - duration =60; + int mob_id = atoi(name); - if ((mob_id = atoi(name)) == 0) + if (mob_id == 0) mob_id = mob->db_searchname(name); - if(mob_id == 0 || mob->db_checkid(mob_id) == 0) - { - clif->message(fd, msg_fd(fd,40)); // Invalid monster ID or name. + + if (mob_id == 0 || mob->db_checkid(mob_id) == 0) { + clif->message(fd, msg_fd(fd, 40)); /// Invalid monster ID or name. return false; } - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE); + struct mob_data *md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, DEFAULT_MOB_JNAME, mob_id, "", + SZ_SMALL, AI_NONE, 0); - if(!md) + if (md == NULL) return false; md->master_id = sd->bl.id; md->special_state.ai = AI_ATTACK; - md->deletetimer = timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0); - clif->specialeffect(&md->bl,344,AREA); - mob->spawn(md); - sc_start4(NULL,&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); - clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,md->bl.x,md->bl.y,tick); - clif->message(fd, msg_fd(fd,39)); // All monster summoned! + const int64 tick = timer->gettick(); + + md->deletetimer = timer->add(tick + (int64)cap_value(duration, 1, 60) * 60000, mob->timer_delete, md->bl.id, 0); + clif->specialeffect(&md->bl, 344, AREA); + mob->spawn(md); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); + clif->skill_poseffect(&sd->bl, AM_CALLHOMUN, 1, md->bl.x, md->bl.y, tick); + clif->message(fd, msg_fd(fd, 39)); /// All monster summoned! return true; } @@ -8048,10 +8091,11 @@ ACMD(duel) return false; } - if (!duel->checktime(sd)) { + int64 diff = duel->difftime(sd); + if (diff > 0) { char output[CHAT_SIZE_MAX]; - // "Duel: You can take part in duel only one time per %d minutes." - sprintf(output, msg_fd(fd,356), battle_config.duel_time_interval); + // "Duel: You can take part in duel again after %d secconds." + sprintf(output, msg_fd(fd,356), (int)diff); clif->message(fd, output); return false; } @@ -8101,10 +8145,11 @@ ACMD(leave) ACMD(accept) { - if (!duel->checktime(sd)) { + int64 diff = duel->difftime(sd); + if (diff > 0) { char output[CHAT_SIZE_MAX]; - // "Duel: You can take part in duel only one time per %d minutes." - sprintf(output, msg_fd(fd,356), battle_config.duel_time_interval); + // "Duel: You can take part in duel again after %d seconds." + sprintf(output, msg_fd(fd,356), (int)diff); clif->message(fd, output); return false; } @@ -9007,19 +9052,54 @@ ACMD(addperm) return true; } +/** + * Unloads a script file. + * Note: Be aware that some changes made by NPC are not reverted on unload. See doc/atcommands.txt for details. + * + * @code{.herc} + * @unloadnpcfile <path> {<flag>} + * @endcode + * + **/ ACMD(unloadnpcfile) { - if (!*message) { - clif->message(fd, msg_fd(fd,1385)); // Usage: @unloadnpcfile <file name> + char format[20]; + + snprintf(format, sizeof(format), "%%%ds %%1d", MAX_DIR_PATH); + + char file_path[MAX_DIR_PATH + 1] = {'\0'}; + int flag = 1; + + if (*message == '\0' || (sscanf(message, format, file_path, &flag) < 1)) { + clif->message(fd, msg_fd(fd, 1385)); /// Usage: @unloadnpcfile <path> {<flag>} return false; } - if (npc->unloadfile(message)) { - clif->message(fd, msg_fd(fd,1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed. - } else { - clif->message(fd, msg_fd(fd,1387)); // File not found. + if (!exists(file_path)) { + clif->message(fd, msg_fd(fd, 1387)); /// File not found. + return false; + } + + if (!is_file(file_path)) { + clif->message(fd, msg_fd(fd, 1518)); /// Not a file. + return false; + } + + FILE *fp = fopen(file_path, "r"); + + if (fp == NULL) { + clif->message(fd, msg_fd(fd, 1519)); /// Can't open file. return false; } + + fclose(fp); + + if (!npc->unloadfile(file_path, (flag != 0))) { + clif->message(fd, msg_fd(fd, 1517)); /// Script could not be unloaded. + return false; + } + + clif->message(fd, msg_fd(fd, 1386)); /// File unloaded. Be aware that... return true; } diff --git a/src/map/atcommand.h b/src/map/atcommand.h index f3b1be51b..66827b3b2 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -41,7 +41,7 @@ struct config_setting_t; * Defines **/ #define ATCOMMAND_LENGTH 50 -#define MAX_MSG 1516 +#define MAX_MSG 1520 #define msg_txt(idx) atcommand->msg(idx) #define msg_sd(sd,msg_number) atcommand->msgsd((sd),(msg_number)) #define msg_fd(fd,msg_number) atcommand->msgfd((fd),(msg_number)) diff --git a/src/map/clif.c b/src/map/clif.c index 3dff01523..868117a96 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4032,51 +4032,58 @@ static void clif_misceffect(struct block_list *bl, int type) /// 0229 <id>.L <body state>.W <health state>.W <effect state>.L <pk mode>.B (ZC_STATE_CHANGE3) static void clif_changeoption(struct block_list *bl) { - unsigned char buf[32]; - struct status_change *sc; - struct map_session_data* sd; - nullpo_retv(bl); - if ( !(sc = status->get_sc(bl)) && bl->type != BL_NPC ) return; //How can an option change if there's no sc? + struct status_change *sc = status->get_sc(bl); - sd = BL_CAST(BL_PC, bl); + if (sc == NULL && bl->type != BL_NPC) // How can an option change if there's no sc? + return; -#if PACKETVER >= 7 - WBUFW(buf,0) = 0x229; - WBUFL(buf,2) = bl->id; - WBUFW(buf,6) = (sc) ? sc->opt1 : 0; - WBUFW(buf,8) = (sc) ? sc->opt2 : 0; - WBUFL(buf,10) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0); - WBUFB(buf,14) = (sd)? sd->status.karma : 0; + struct map_session_data *sd = BL_CAST(BL_PC, bl); + struct PACKET_ZC_STATE_CHANGE p; + p.packetType = HEADER_ZC_STATE_CHANGE; + p.AID = bl->id; + p.bodyState = (sc != NULL) ? sc->opt1 : 0; + p.healthState = (sc != NULL) ? sc->opt2 : 0; + p.effectState = (sc != NULL) ? sc->option : BL_UCCAST(BL_NPC, bl)->option; + p.isPKModeON = (sd != NULL) ? sd->status.karma : 0; if (clif->isdisguised(bl)) { - clif->send(buf,packet_len(0x229),bl,AREA_WOS); - WBUFL(buf,2) = -bl->id; - clif->send(buf,packet_len(0x229),bl,SELF); - WBUFL(buf,2) = bl->id; - WBUFL(buf,10) = OPTION_INVISIBLE; - clif->send(buf,packet_len(0x229),bl,SELF); + clif->send(&p, sizeof(p), bl, AREA_WOS); + p.AID = -bl->id; + clif->send(&p, sizeof(p), bl, SELF); + p.AID = bl->id; + p.effectState = OPTION_INVISIBLE; + clif->send(&p, sizeof(p), bl, SELF); } else { - clif->send(buf,packet_len(0x229),bl,AREA); + clif->send(&p, sizeof(p), bl, AREA); } -#else - WBUFW(buf,0) = 0x119; - WBUFL(buf,2) = bl->id; - WBUFW(buf,6) = (sc) ? sc->opt1 : 0; - WBUFW(buf,8) = (sc) ? sc->opt2 : 0; - WBUFL(buf,10) = (sc != NULL) ? sc->option : ((bl->type == BL_NPC) ? BL_UCCAST(BL_NPC, bl)->option : 0); - WBUFB(buf,12) = (sd)? sd->status.karma : 0; +} + +static void clif_changeoption_target(struct block_list *bl, struct block_list *target_bl, enum send_target target) +{ + nullpo_retv(bl); + nullpo_retv(target_bl); + + struct status_change *sc = status->get_sc(bl); + + if (sc == NULL && bl->type != BL_NPC) // How can an option change if there's no sc? + return; + + struct map_session_data *sd = BL_CAST(BL_PC, bl); + struct PACKET_ZC_STATE_CHANGE p; + p.packetType = HEADER_ZC_STATE_CHANGE; + p.AID = bl->id; + p.bodyState = (sc != NULL) ? sc->opt1 : 0; + p.healthState = (sc != NULL) ? sc->opt2 : 0; + p.effectState = (sc != NULL) ? sc->option : BL_UCCAST(BL_NPC, bl)->option; + p.isPKModeON = (sd != NULL) ? sd->status.karma : 0; if (clif->isdisguised(bl)) { - clif->send(buf,packet_len(0x119),bl,AREA_WOS); - WBUFL(buf,2) = -bl->id; - clif->send(buf,packet_len(0x119),bl,SELF); - WBUFL(buf,2) = bl->id; - WBUFW(buf,10) = OPTION_INVISIBLE; - clif->send(buf,packet_len(0x119),bl,SELF); - } else { - clif->send(buf,packet_len(0x119),bl,AREA); + p.AID = -bl->id; + clif->send(&p, sizeof(p), target_bl, target); + p.AID = bl->id; + p.effectState = OPTION_INVISIBLE; } -#endif + clif->send(&p, sizeof(p), target_bl, target); } /// Displays status change effects on NPCs/monsters (ZC_NPC_SHOWEFST_UPDATE). @@ -15273,8 +15280,8 @@ static void clif_parse_GMKick(int fd, struct map_session_data *sd) clif->GM_kickack(sd, 0); return; } - npc->unload_duplicates(nd); - npc->unload(nd,true); + npc->unload_duplicates(nd, true); + npc->unload(nd, true, true); npc->read_event_script(); } break; @@ -20028,7 +20035,7 @@ static void clif_cashShopOpen(int fd, struct map_session_data *sd, int tab) p->packetType = HEADER_ZC_SE_CASHSHOP_OPEN; p->cashPoints = sd->cashPoints; //[Ryuuzaki] - switched positions to reflect proper values p->kafraPoints = sd->kafraPoints; -#if PACKETVER_ZERO_NUM >= 20191224 +#if PACKETVER_MAIN_NUM >= 20200129 || PACKETVER_RE_NUM >= 20200205 || PACKETVER_ZERO_NUM >= 20191224 p->tab = tab; #endif WFIFOSET(fd, sizeof(struct PACKET_ZC_SE_CASHSHOP_OPEN)); @@ -23209,6 +23216,116 @@ static void clif_parse_NPCBarterPurchase(int fd, struct map_session_data *sd) #endif } +static void clif_parse_npc_expanded_barter_closed(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_npc_expanded_barter_closed(int fd, struct map_session_data *sd) +{ +} + +#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127 +#define NEXT_EXPANDED_BARTER_ITEM(var, count) \ + var = (struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub *)((char*)item + \ + sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub) + \ + count * sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2)) +#endif + +static void clif_npc_expanded_barter_open(struct map_session_data *sd, struct npc_data *nd) +{ +#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127 + nullpo_retv(sd); + nullpo_retv(nd); + struct npc_item_list *shop = nd->u.scr.shop->item; + const int shop_size = nd->u.scr.shop->items; + + int items_count = 0; + int currencies_count = 0; + struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN *packet = (struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN*)&packet_buf[0]; + STATIC_ASSERT(sizeof(packet_buf) > sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN), "packet_buf size too small"); + int buf_left = sizeof(packet_buf) - sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN); + packet->packetType = HEADER_ZC_NPC_EXPANDED_BARTER_OPEN; + struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub *item = &packet->items[0]; + + for (int i = 0; i < shop_size && buf_left >= sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub); i++) { + if (shop[i].nameid) { + struct item_data *id = itemdb->exists(shop[i].nameid); + if (id == NULL) + continue; + + item->nameid = shop[i].nameid; + item->type = itemtype(id->type); + item->amount = shop[i].qty; + item->weight = id->weight * 10; + item->index = i; + item->zeny = shop[i].value; + item->currency_count = 0; + buf_left -= sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub); + items_count ++; + int count = shop[i].value2; + if (buf_left < sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2) * count) { + NEXT_EXPANDED_BARTER_ITEM(item, 0); + break; + } + for (int j = 0; j < count; j ++) { + struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 *packet_currency = &item->currencies[j]; + struct npc_barter_currency *currency = &shop[i].currency[j]; + struct item_data *id2 = itemdb->exists(currency->nameid); + if (id2 == NULL) + continue; + packet_currency->nameid = currency->nameid; + if (currency->refine == -1) + packet_currency->refine_level = 0; + else + packet_currency->refine_level = currency->refine; + packet_currency->amount = currency->amount; + packet_currency->type = itemtype(id2->type); + currencies_count ++; + item->currency_count ++; + } + NEXT_EXPANDED_BARTER_ITEM(item, item->currency_count); + } + } + + packet->items_count = items_count; + packet->packetLength = sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN) + + sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub) * items_count + + sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2) * currencies_count; + clif->send(packet, packet->packetLength, &sd->bl, SELF); +#endif +} + +#undef NEXT_EXPANDED_BARTER_ITEM + +static void clif_parse_npc_expanded_barter_purchase(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_npc_expanded_barter_purchase(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828 + if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd)) + return; + + const struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE *const p = RP2PTR(fd); + int count = (p->packetLength - sizeof(struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE)) / sizeof p->list[0]; + struct barteritemlist item_list; + + Assert_retv(count >= 0 && count <= sd->status.inventorySize); + + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, count, 1); + + for (int i = 0; i < count; i++) { + struct barter_itemlist_entry entry = { 0 }; + entry.addId = p->list[i].itemId; + entry.addAmount = p->list[i].amount; + entry.removeIndex = -1; + entry.shopIndex = p->list[i].shopIndex; + VECTOR_PUSH(item_list, entry); + } + + int response = npc->expanded_barter_buylist(sd, &item_list); + clif->npc_buy_result(sd, response); + + VECTOR_CLEAR(item_list); +#endif +} + static void clif_parse_clientVersion(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); static void clif_parse_clientVersion(int fd, struct map_session_data *sd) { @@ -24102,6 +24219,7 @@ void clif_defaults(void) /* visual effects client-side */ clif->misceffect = clif_misceffect; clif->changeoption = clif_changeoption; + clif->changeoption_target = clif_changeoption_target; clif->changeoption2 = clif_changeoption2; clif->emotion = clif_emotion; clif->talkiebox = clif_talkiebox; @@ -24766,6 +24884,9 @@ void clif_defaults(void) clif->npc_barter_open = clif_npc_barter_open; clif->pNPCBarterClosed = clif_parse_NPCBarterClosed; clif->pNPCBarterPurchase = clif_parse_NPCBarterPurchase; + clif->npc_expanded_barter_open = clif_npc_expanded_barter_open; + clif->pNPCExpandedBarterPurchase = clif_parse_npc_expanded_barter_purchase; + clif->pNPCExpandedBarterClosed = clif_parse_npc_expanded_barter_closed; clif->pClientVersion = clif_parse_clientVersion; clif->pPing = clif_parse_ping; clif->ping = clif_ping; diff --git a/src/map/clif.h b/src/map/clif.h index b61772bba..25ac65af5 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -1006,6 +1006,7 @@ struct clif_interface { /* visual effects client-side */ void (*misceffect) (struct block_list* bl,int type); void (*changeoption) (struct block_list* bl); + void (*changeoption_target) (struct block_list *bl, struct block_list *target_bl, enum send_target target); void (*changeoption2) (struct block_list* bl); void (*emotion) (struct block_list *bl,int type); void (*talkiebox) (struct block_list* bl, const char* talkie); @@ -1663,6 +1664,9 @@ struct clif_interface { void (*npc_barter_open) (struct map_session_data *sd, struct npc_data *nd); void (*pNPCBarterClosed) (int fd, struct map_session_data *sd); void (*pNPCBarterPurchase) (int fd, struct map_session_data *sd); + void (*pNPCExpandedBarterClosed) (int fd, struct map_session_data *sd); + void (*pNPCExpandedBarterPurchase) (int fd, struct map_session_data *sd); + void (*npc_expanded_barter_open) (struct map_session_data *sd, struct npc_data *nd); void (*pClientVersion) (int fd, struct map_session_data *sd); void (*pPing) (int fd, struct map_session_data *sd); void (*ping) (struct map_session_data *sd); diff --git a/src/map/duel.c b/src/map/duel.c index dca040f83..c66fd6fc2 100644 --- a/src/map/duel.c +++ b/src/map/duel.c @@ -41,27 +41,12 @@ struct duel_interface *duel; *------------------------------------------*/ static void duel_savetime(struct map_session_data *sd) { - time_t clock; - struct tm *t; - - time(&clock); - t = localtime(&clock); - - pc_setglobalreg(sd, script->add_variable("PC_LAST_DUEL_TIME"), t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min); + pc_setglobalreg(sd, script->add_variable("PC_LAST_DUEL_TIME"), (int)time(NULL)); } -static int duel_checktime(struct map_session_data *sd) +static int64 duel_difftime(struct map_session_data *sd) { - int diff; - time_t clock; - struct tm *t; - - time(&clock); - t = localtime(&clock); - - diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, script->add_variable("PC_LAST_DUEL_TIME") ); - - return !(diff >= 0 && diff < battle_config.duel_time_interval); + return (pc_readglobalreg(sd, script->add_variable("PC_LAST_DUEL_TIME")) + battle_config.duel_time_interval - (int)time(NULL)); } static int duel_showinfo_sub(struct map_session_data *sd, va_list va) @@ -233,7 +218,7 @@ void duel_defaults(void) duel->reject = duel_reject; duel->leave = duel_leave; duel->showinfo = duel_showinfo; - duel->checktime = duel_checktime; + duel->difftime = duel_difftime; duel->init = do_init_duel; duel->final = do_final_duel; diff --git a/src/map/duel.h b/src/map/duel.h index 4e8985b96..1620ca891 100644 --- a/src/map/duel.h +++ b/src/map/duel.h @@ -52,7 +52,7 @@ struct duel_interface { void (*reject) (const unsigned int did, struct map_session_data* sd); void (*leave) (const unsigned int did, struct map_session_data* sd); void (*showinfo) (const unsigned int did, struct map_session_data* sd); - int (*checktime) (struct map_session_data* sd); + int64 (*difftime) (struct map_session_data* sd); void (*init) (bool minimal); void (*final) (void); diff --git a/src/map/instance.c b/src/map/instance.c index 90f2217b1..1104b7e88 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -446,7 +446,7 @@ static int instance_cleanup_sub(struct block_list *bl, va_list ap) map->quit(BL_UCAST(BL_PC, bl)); break; case BL_NPC: - npc->unload(BL_UCAST(BL_NPC, bl), true); + npc->unload(BL_UCAST(BL_NPC, bl), true, true); break; case BL_MOB: unit->free(bl,CLR_OUTSIGHT); diff --git a/src/map/map.c b/src/map/map.c index afdc2ed41..33f3fe716 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -638,9 +638,12 @@ static int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, i static int map_forcountinmap(int (*func)(struct block_list*, va_list), int16 m, int count, int type, ...) { - int returnCount; + int returnCount = 0; va_list ap; + if (m < 0) + return returnCount; + va_start(ap, type); returnCount = map->vforcountinarea(func, m, 0, 0, map->list[m].xs, map->list[m].ys, count, type, ap); va_end(ap); @@ -4452,6 +4455,7 @@ static bool inter_config_read_database_names(const char *filename, const struct libconfig->setting_lookup_mutable_string(setting, "autotrade_data_db", map->autotrade_data_db, sizeof(map->autotrade_data_db)); libconfig->setting_lookup_mutable_string(setting, "npc_market_data_db", map->npc_market_data_db, sizeof(map->npc_market_data_db)); libconfig->setting_lookup_mutable_string(setting, "npc_barter_data_db", map->npc_barter_data_db, sizeof(map->npc_barter_data_db)); + libconfig->setting_lookup_mutable_string(setting, "npc_expanded_barter_data_db", map->npc_expanded_barter_data_db, sizeof(map->npc_expanded_barter_data_db)); if (!mapreg->config_read(filename, setting, imported)) retval = false; @@ -6091,7 +6095,7 @@ static int cleanup_sub(struct block_list *bl, va_list ap) map->quit(BL_UCAST(BL_PC, bl)); break; case BL_NPC: - npc->unload(BL_UCAST(BL_NPC, bl), false); + npc->unload(BL_UCAST(BL_NPC, bl), false, true); break; case BL_MOB: unit->free(bl,CLR_OUTSIGHT); @@ -6749,6 +6753,7 @@ int do_init(int argc, char *argv[]) npc->event_do_oninit( false ); // Init npcs (OnInit) npc->market_fromsql(); /* after OnInit */ npc->barter_fromsql(); /* after OnInit */ + npc->expanded_barter_fromsql(); /* after OnInit */ if (battle_config.pk_mode) ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n"); diff --git a/src/map/map.h b/src/map/map.h index 78f1a3c89..dbd9c0fba 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1056,6 +1056,7 @@ struct map_interface { char autotrade_data_db[32]; char npc_market_data_db[32]; char npc_barter_data_db[32]; + char npc_expanded_barter_data_db[32]; char default_codepage[32]; char default_lang_str[64]; diff --git a/src/map/messages_main.h b/src/map/messages_main.h index b2b67f08c..6fc0310e7 100644 --- a/src/map/messages_main.h +++ b/src/map/messages_main.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20200108 +Latest version: 20200129 */ enum clif_messages { @@ -22464,6 +22464,63 @@ Search */ MSG_ID_EC1 = 0xec1, #endif +#if PACKETVER >= 20200122 +/*20200122 to latest +리서치 리포트 상태가 됩니다. +*/ + MSG_ID_EC2 = 0xec2, +/*20200122 to latest +리서치 리포트 상태가 해제됩니다. +*/ + MSG_ID_EC3 = 0xec3, +/*20200122 to latest +제조에 성공 했습니다. +*/ + MSG_ID_EC4 = 0xec4, +/*20200122 to latest +제조에 실패 했습니다. +*/ + MSG_ID_EC5 = 0xec5, +/*20200122 to latest +쉐도우 장비가 파괴 및 해제에서 보호됩니다. +*/ + MSG_ID_EC6 = 0xec6, +/*20200122 to latest +풀 쉐도우 프로텍션이 해제됩니다. +*/ + MSG_ID_EC7 = 0xec7, +/*20200122 to latest +식물형, 무형 몬스터에게 주는 데미지가 증가합니다. +*/ + MSG_ID_EC8 = 0xec8, +/*20200122 to latest +지옥 나무의 가루효과가 사라집니다. +*/ + MSG_ID_EC9 = 0xec9, +#endif +#if PACKETVER >= 20200129 +/*20200129 to latest +공격 장치가 활성화되었습니다. +*/ + MSG_ID_ECA = 0xeca, +/*20200129 to latest +공격 장치가 해제되었습니다. +*/ + MSG_ID_ECB = 0xecb, +/*20200129 to latest +물리 방어력 및 물리 저항력이 증가되었습니다. +*/ + MSG_ID_ECC = 0xecc, +/*20200129 to latest +방어 장치가 해제되었습니다. +*/ + MSG_ID_ECD = 0xecd, +/*20200129 to latest +검색 +Search +*/ + MSG_ID_ECE = 0xece, +#endif }; #endif /* MAP_MESSAGES_MAIN_H */ diff --git a/src/map/messages_re.h b/src/map/messages_re.h index 8cb3b6624..f4cc62d68 100644 --- a/src/map/messages_re.h +++ b/src/map/messages_re.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20200108 +Latest version: 20200205 */ enum clif_messages { @@ -21941,6 +21941,63 @@ Search */ MSG_ID_EC1 = 0xec1, #endif +#if PACKETVER >= 20200122 +/*20200122 to latest +리서치 리포트 상태가 됩니다. +*/ + MSG_ID_EC2 = 0xec2, +/*20200122 to latest +리서치 리포트 상태가 해제됩니다. +*/ + MSG_ID_EC3 = 0xec3, +/*20200122 to latest +제조에 성공 했습니다. +*/ + MSG_ID_EC4 = 0xec4, +/*20200122 to latest +제조에 실패 했습니다. +*/ + MSG_ID_EC5 = 0xec5, +/*20200122 to latest +쉐도우 장비가 파괴 및 해제에서 보호됩니다. +*/ + MSG_ID_EC6 = 0xec6, +/*20200122 to latest +풀 쉐도우 프로텍션이 해제됩니다. +*/ + MSG_ID_EC7 = 0xec7, +/*20200122 to latest +식물형, 무형 몬스터에게 주는 데미지가 증가합니다. +*/ + MSG_ID_EC8 = 0xec8, +/*20200122 to latest +지옥 나무의 가루효과가 사라집니다. +*/ + MSG_ID_EC9 = 0xec9, +#endif +#if PACKETVER >= 20200205 +/*20200205 to latest +공격 장치가 활성화되었습니다. +*/ + MSG_ID_ECA = 0xeca, +/*20200205 to latest +공격 장치가 해제되었습니다. +*/ + MSG_ID_ECB = 0xecb, +/*20200205 to latest +물리 방어력 및 물리 저항력이 증가되었습니다. +*/ + MSG_ID_ECC = 0xecc, +/*20200205 to latest +방어 장치가 해제되었습니다. +*/ + MSG_ID_ECD = 0xecd, +/*20200205 to latest +검색 +Search +*/ + MSG_ID_ECE = 0xece, +#endif }; #endif /* MAP_MESSAGES_RE_H */ diff --git a/src/map/messages_zero.h b/src/map/messages_zero.h index 18aed7d5b..55c0329ee 100644 --- a/src/map/messages_zero.h +++ b/src/map/messages_zero.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20191224 +Latest version: 20200129 */ enum clif_messages { @@ -6734,9 +6734,11 @@ The Memorial Dungeon's entry time limit expired; it has been destroyed. The Memorial Dungeon has been removed. */ MSG_MEMORIAL_DUN_DESTROY_REQUEST = 0x544, -/*20171018 to latest +/*20171018 to 20191224 메모리얼 던전에 시스템 오류가 발생하였습니다. 정상적인 게임 진행을 위해 재접속을 해주십시오. A system error has occurred in the Memorial Dungeon. Please relog in to the game to continue playing. +20200115 to latest +메모리얼 던전에 통신 장애가 발생하였습니다. 정상적인 게임 진행을 위해 잠시 후, 재접속을 해주십시오. */ MSG_MEMORIAL_DUN_ERROR = 0x545, /*20171018 to latest @@ -18319,8 +18321,10 @@ VTC 인증에 실패하였습니다. 가나다 정렬 */ MSG_ID_E8A = 0xe8a, -/*20191113 to latest +/*20191113 to 20191224 기본 결과물은 %s %d개 이나, 낮은 확률로 최대 %d개까지 생성될 수 있습니다. +20200115 to latest +※[%s] %d~%d개 제작 */ MSG_ID_E8B = 0xe8b, /*20191113 to latest @@ -18536,6 +18540,71 @@ https://member.gnjoy.com.tw/billing.aspx */ MSG_ID_EBE = 0xebe, #endif +#if PACKETVER >= 20200115 +/*20200115 to latest +역순 정렬 +*/ + MSG_ID_EBF = 0xebf, +/*20200115 to latest +검색 내용 입력 +*/ + MSG_ID_EC0 = 0xec0, +/*20200115 to latest +검색 +Search +*/ + MSG_ID_EC1 = 0xec1, +/*20200115 to latest +리서치 리포트 상태가 됩니다. +*/ + MSG_ID_EC2 = 0xec2, +/*20200115 to latest +리서치 리포트 상태가 해제됩니다. +*/ + MSG_ID_EC3 = 0xec3, +/*20200115 to latest +제조에 성공 했습니다. +*/ + MSG_ID_EC4 = 0xec4, +/*20200115 to latest +제조에 실패 했습니다. +*/ + MSG_ID_EC5 = 0xec5, +/*20200115 to latest +쉐도우 장비가 파괴 및 해제에서 보호됩니다. +*/ + MSG_ID_EC6 = 0xec6, +/*20200115 to latest +풀 쉐도우 프로텍션이 해제됩니다. +*/ + MSG_ID_EC7 = 0xec7, +/*20200115 to latest +식물형, 무형 몬스터에게 주는 데미지가 증가합니다. +*/ + MSG_ID_EC8 = 0xec8, +/*20200115 to latest +지옥 나무의 가루효과가 사라집니다. +*/ + MSG_ID_EC9 = 0xec9, +#endif +#if PACKETVER >= 20200129 +/*20200129 to latest +공격 장치가 활성화되었습니다. +*/ + MSG_ID_ECA = 0xeca, +/*20200129 to latest +공격 장치가 해제되었습니다. +*/ + MSG_ID_ECB = 0xecb, +/*20200129 to latest +물리 방어력 및 물리 저항력이 증가되었습니다. +*/ + MSG_ID_ECC = 0xecc, +/*20200129 to latest +방어 장치가 해제되었습니다. +*/ + MSG_ID_ECD = 0xecd, +#endif }; #endif /* MAP_MESSAGES_ZERO_H */ diff --git a/src/map/mob.c b/src/map/mob.c index 4b74abc8f..0830e5a5a 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -337,15 +337,23 @@ static int mob_parse_dataset(struct spawn_data *data) return 1; } -/*========================================== - * Generates the basic mob data using the spawn_data provided. - *------------------------------------------*/ -static struct mob_data *mob_spawn_dataset(struct spawn_data *data) + +/** + * Generates basic mob data by using the passed spawn data. + * + * @param data The mobs spawn data. + * @param npc_id If spawned by NPC script, this holds the ID of the invoking NPC. + * @return The generated mob data, later used to spawn the mob. + * + **/ +static struct mob_data *mob_spawn_dataset(struct spawn_data *data, int npc_id) { - struct mob_data *md = NULL; nullpo_retr(NULL, data); - CREATE(md, struct mob_data, 1); - md->bl.id= npc->get_new_npc_id(); + + struct mob_data *md = (struct mob_data *)aCalloc(1, sizeof(struct mob_data)); + + memcpy(md->name, data->name, NAME_LENGTH); + md->bl.id = npc->get_new_npc_id(); md->bl.type = BL_MOB; md->bl.m = data->m; md->bl.x = data->x; @@ -353,24 +361,29 @@ static struct mob_data *mob_spawn_dataset(struct spawn_data *data) md->class_ = data->class_; md->state.boss = data->state.boss; md->db = mob->db(md->class_); + md->npc_id = npc_id; + md->spawn_timer = INVALID_TIMER; + md->deletetimer = INVALID_TIMER; + md->skill_idx = -1; + if (data->level > 0 && data->level <= MAX_LEVEL) md->level = data->level; - memcpy(md->name, data->name, NAME_LENGTH); - if (data->state.ai) + + if (data->state.ai > 0) md->special_state.ai = data->state.ai; - if (data->state.size) + + if (data->state.size > 0) md->special_state.size = data->state.size; - if (data->eventname[0] && strlen(data->eventname) >= 4) + + if (data->eventname[0] != '\0' && strlen(data->eventname) >= 4) memcpy(md->npc_event, data->eventname, 50); - if(md->db->status.mode&MD_LOOTER) - md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item)); - md->spawn_timer = INVALID_TIMER; - md->deletetimer = INVALID_TIMER; - md->skill_idx = -1; + + if ((md->db->status.mode & MD_LOOTER) == MD_LOOTER) + md->lootitem = (struct item *)aCalloc(LOOTITEM_SIZE, sizeof(struct item)); + status->set_viewdata(&md->bl, md->class_); status->change_init(&md->bl); unit->dataset(&md->bl); - map->addiddb(&md->bl); return md; } @@ -503,7 +516,24 @@ static bool mob_ksprotected(struct block_list *src, struct block_list *target) return false; } -static struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai) +/** + * Prepares a mob's spawn data. + * + * @param bl The invoking character's block list. + * @param m The ID of the map where the mob should be spawned. + * @param x The x coordinate where the mob should be spawned. + * @param y The y coordinate where the mob should be spawned. + * @param mobname The mob's display name. + * @param class_ The mob's ID in database. + * @param event The name of the event which should be executed when the mob is killed. + * @param size The mob's size. + * @param ai The mob's AI. + * @param npc_id If spawned by NPC script, this holds the ID of the invoking NPC. + * @return The mob data generated by mob->spawn_dataset(). + * + **/ +static struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, + const char *event, unsigned int size, unsigned int ai, int npc_id) { struct spawn_data data; @@ -521,76 +551,100 @@ static struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 else strcpy(data.name, DEFAULT_MOB_JNAME); - if (event) + if (event != NULL) safestrncpy(data.eventname, event, sizeof(data.eventname)); - // Locate spot next to player. - if (bl && (x < 0 || y < 0)) + /** Locate spot next to player. **/ + if (bl != NULL && (x < 0 || y < 0)) map->search_freecell(bl, m, &x, &y, 1, 1, 0); - // if none found, pick random position on map + /** If none found, pick random position on map. **/ if (x <= 0 || x >= map->list[m].xs || y <= 0 || y >= map->list[m].ys) map->search_freecell(NULL, m, &x, &y, -1, -1, 1); data.x = x; data.y = y; - if (!mob->parse_dataset(&data)) + if (mob->parse_dataset(&data) == 0) return NULL; - return mob->spawn_dataset(&data); + return mob->spawn_dataset(&data, npc_id); } -/*========================================== - * Spawn a single mob on the specified coordinates. - *------------------------------------------*/ -static int mob_once_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai) +/** + * Spawns a given amount of mobs. + * + * @param sd The invoking character. + * @param m The ID of the map where the mob should be spawned. + * @param x The x coordinate where the mob should be spawned. + * @param y The y coordinate where the mob should be spawned. + * @param mobname The mob's display name. + * @param class_ The mob's ID in database. + * @param amount The amount of mobs to spawn. + * @param event The name of the event which should be executed when the mob is killed. + * @param size The mob's size. + * @param ai The mob's AI. + * @return The last spawned mob's GID, or 0 if spawning failed. + * + **/ +static int mob_once_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, const char *mobname, int class_, + int amount, const char *event, unsigned int size, unsigned int ai) { - struct mob_data* md = NULL; - int count, lv; bool no_guardian_data = false; - if( ai && ai&0x200 ) { + if (ai > 0 && (ai & 0x200) == 0x200) { no_guardian_data = true; - ai &=~ 0x200; + ai &= ~0x200; } if (m < 0 || amount <= 0) - return 0; // invalid input + return 0; - lv = (sd) ? sd->status.base_level : 255; + struct mob_data *md = NULL; - for (count = 0; count < amount; count++) { - int c = (class_ >= 0) ? class_ : mob->get_random_id(-class_ - 1, (battle_config.random_monster_checklv) ? 3 : 1, lv); - md = mob->once_spawn_sub((sd) ? &sd->bl : NULL, m, x, y, mobname, c, event, size, ai); + for (int i = 0; i < amount; i++) { + int mob_id = class_; - if (!md) + if (mob_id < 0) { + mob_id = mob->get_random_id(-class_ - 1, (battle_config.random_monster_checklv == 1) ? 3 : 1, + (sd != NULL) ? sd->status.base_level : 255); + } + + md = mob->once_spawn_sub((sd != NULL) ? &sd->bl : NULL, m, x, y, mobname, mob_id, event, size, ai, + (sd != NULL) ? sd->npc_id : 0); + + if (md == NULL) continue; if (class_ == MOBID_EMPELIUM && !no_guardian_data) { - struct guild_castle* gc = guild->mapindex2gc(map_id2index(m)); - struct guild* g = (gc) ? guild->search(gc->guild_id) : NULL; - if( gc ) { + struct guild_castle *gc = guild->mapindex2gc(map_id2index(m)); + + if (gc != NULL) { + struct guild *g = guild->search(gc->guild_id); + md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data)); md->guardian_data->castle = gc; md->guardian_data->number = MAX_GUARDIANS; - if( g ) + + if (g != NULL) md->guardian_data->g = g; - else if( gc->guild_id ) //Guild not yet available, retry in 5. - timer->add(timer->gettick()+5000,mob->spawn_guardian_sub,md->bl.id,gc->guild_id); + else if (gc->guild_id > 0) /// Guild not yet available, retry in 5s. + timer->add(timer->gettick() + 5000, mob->spawn_guardian_sub, md->bl.id, + gc->guild_id); } - } // end addition [Valaris] + } mob->spawn(md); - if (class_ < 0 && battle_config.dead_branch_active) { - //Behold Aegis's masterful decisions yet again... - //"I understand the "Aggressive" part, but the "Can Move" and "Can Attack" is just stupid" - Poki#3 - sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000); + if (class_ < 0 && battle_config.dead_branch_active == 1) { + /// Behold Aegis' masterful decisions yet again... + /// "I understand the "Aggressive" part, but the "Can Move" and "Can Attack" is just stupid" [Poki] + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, + 0, 60000); } } - return (md) ? md->bl.id : 0; // id of last spawned mob + return (md != NULL) ? md->bl.id : 0; /// ID of last spawned mob. } /*========================================== @@ -649,196 +703,236 @@ static int mob_once_spawn_area(struct map_session_data *sd, int16 m, int16 x0, i } /** - * Sets a guardian's guild data and liberates castle if couldn't retrieve guild data - * @param data (int)guild_id - * @retval Always 0 + * Sets a guardian's guild data and liberates castle if couldn't retrieve guild data. + * Required because the guild data may not be available at guardian spawn time. + * + * @param tid Required parameter for timer functions. Unused inside the function. + * @param tick Required parameter for timer functions. Unused inside the function. + * @param id The guardian mob's GID. + * @param data The guild ID. + * @return 1 on success, 0 on failure. + * * @author Skotlex + * **/ static int mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data) { - //Needed because the guild data may not be available at guardian spawn time. - struct block_list* bl = map->id2bl(id); - struct mob_data* md; - struct guild* g; + struct block_list *bl = map->id2bl(id); - if( bl == NULL ) //It is possible mob was already removed from map when the castle has no owner. [Skotlex] + if (bl == NULL || bl->type != BL_MOB) /// It is possible mob was already removed from map when the castle has no owner. [Skotlex] return 0; - Assert_ret(bl->type == BL_MOB); - md = BL_UCAST(BL_MOB, bl); + struct mob_data *md = BL_UCAST(BL_MOB, bl); + + if (md->guardian_data == NULL) + return 0; - nullpo_ret(md->guardian_data); - g = guild->search((int)data); + struct guild *g = guild->search((int)data); - if( g == NULL ) { //Liberate castle, if the guild is not found this is an error! [Skotlex] + if (g == NULL) { /// Liberate castle, if the guild is not found this is an error! [Skotlex] ShowError("mob_spawn_guardian_sub: Couldn't load guild %d!\n", (int)data); - //Not sure this is the best way, but otherwise we'd be invoking this for ALL guardians spawned later on. - if (md->class_ == MOBID_EMPELIUM && md->guardian_data) { + + /// Not sure this is the best way, but otherwise we'd be invoking this for ALL guardians spawned later on. + if (md->class_ == MOBID_EMPELIUM) { md->guardian_data->g = NULL; - if( md->guardian_data->castle->guild_id ) {//Free castle up. - ShowNotice("Clearing ownership of castle %d (%s)\n", md->guardian_data->castle->castle_id, md->guardian_data->castle->castle_name); + + if (md->guardian_data->castle->guild_id > 0) { /// Free castle up. + ShowNotice("mob_spawn_guardian_sub: Clearing ownership of castle %d (%s).\n", + md->guardian_data->castle->castle_id, + md->guardian_data->castle->castle_name); guild->castledatasave(md->guardian_data->castle->castle_id, 1, 0); } } else { - if( md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS - && md->guardian_data->castle->guardian[md->guardian_data->number].visible ) - guild->castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); + if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && + md->guardian_data->castle->guardian[md->guardian_data->number].visible == 1) + guild->castledatasave(md->guardian_data->castle->castle_id, + 10 + md->guardian_data->number, 0); - unit->free(&md->bl,CLR_OUTSIGHT); // Remove guardian. + unit->free(&md->bl, CLR_OUTSIGHT); /// Remove guardian. } + return 0; } - if( guild->checkskill(g,GD_GUARDUP) ) - status_calc_mob(md, SCO_NONE); // Give bonuses. + if (guild->checkskill(g, GD_GUARDUP) > 0) + status_calc_mob(md, SCO_NONE); /// Give bonuses. - return 0; + return 1; } -/*========================================== - * Summoning Guardians [Valaris] - *------------------------------------------*/ -static int mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index) +/** + * Summons a castle guardian mob. + * + * @param mapname The name of the map where the guardian should be spawned. + * @param x The x coordinate where the guardian should be spawned. + * @param y The y coordinate where the guardian should be spawned. + * @param mobname The guardian's display name. + * @param class_ The guardian's mob ID in database. + * @param event The name of the event which should be executed when the guardian is killed. + * @param guardian The guardian's index. + * @param has_index If false, the guardian will be temporarily. + * @param npc_id If spawned by NPC script, this holds the ID of the invoking NPC. + * @return The spawned guardian's GID, or 0 if spawning failed. + * + * @author Valaris + * + **/ +static int mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, + int guardian, bool has_index, int npc_id) { - struct mob_data *md=NULL; - struct spawn_data data; - struct guild *g=NULL; - struct guild_castle *gc; - int16 m; - nullpo_ret(mapname); nullpo_ret(mobname); nullpo_ret(event); - memset(&data, 0, sizeof(struct spawn_data)); - data.num = 1; - - m=map->mapname2mapid(mapname); + const int map_id = map->mapname2mapid(mapname); - if(m<0) - { + if (map_id == INDEX_NOT_FOUND) { ShowWarning("mob_spawn_guardian: Map [%s] not found.\n", mapname); return 0; } - data.m = m; - data.num = 1; - if(class_<=0) { - class_ = mob->get_random_id(-class_-1, 1, 99); - if (!class_) return 0; + + if ((x <= 0 || y <= 0) && map->search_freecell(NULL, map_id, &x, &y, -1, -1, 1) == 0) { + ShowWarning("mob_spawn_guardian: Couldn't locate a spawn cell for guardian class %d (index %d) on castle map %s.\n", + class_, guardian, mapname); + return 0; } - data.class_ = class_; + if (class_ <= 0 && (class_ = mob->get_random_id(-class_ - 1, 1, 99)) == 0) + return 0; - if( !has_index ) { + if (!has_index) { guardian = -1; - } else if( guardian < 0 || guardian >= MAX_GUARDIANS ) { - ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d (castle map %s)\n", guardian, class_, map->list[m].name); + } else if (guardian < 0 || guardian >= MAX_GUARDIANS) { + ShowError("mob_spawn_guardian: Invalid guardian index %d for guardian %d on castle map %s.\n", + guardian, class_, mapname); return 0; } - if((x<=0 || y<=0) && !map->search_freecell(NULL, m, &x, &y, -1,-1, 1)) { - ShowWarning("mob_spawn_guardian: Couldn't locate a spawn cell for guardian class %d (index %d) at castle map %s\n",class_, guardian, map->list[m].name); - return 0; - } + struct spawn_data data; + + memset(&data, 0, sizeof(struct spawn_data)); + data.num = 1; + data.m = map_id; + data.class_ = class_; data.x = x; data.y = y; safestrncpy(data.name, mobname, sizeof(data.name)); safestrncpy(data.eventname, event, sizeof(data.eventname)); - if (!mob->parse_dataset(&data)) + + if (mob->parse_dataset(&data) == 0) return 0; - gc=guild->mapname2gc(map->list[m].name); + struct guild_castle *gc = guild->mapname2gc(mapname); + if (gc == NULL) { - ShowError("mob_spawn_guardian: No castle set at map %s\n", map->list[m].name); + ShowError("mob_spawn_guardian: No castle set on map %s.\n", mapname); return 0; } - if (!gc->guild_id) - ShowWarning("mob_spawn_guardian: Spawning guardian %d on a castle with no guild (castle map %s)\n", class_, map->list[m].name); + + struct guild *g = NULL; + + if (gc->guild_id == 0) + ShowWarning("mob_spawn_guardian: Spawning guardian %d on a castle map %s with no guild.\n", + class_, mapname); else g = guild->search(gc->guild_id); - if( has_index && gc->guardian[guardian].id ) { - //Check if guardian already exists, refuse to spawn if so. - struct block_list *bl2 = map->id2bl(gc->guardian[guardian].id); // TODO: Why does this not use map->id2md? - struct mob_data *md2 = BL_CAST(BL_MOB, bl2); - if (md2 != NULL && md2->guardian_data != NULL && md2->guardian_data->number == guardian) { - ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian (castle map %s)\n", guardian, map->list[m].name); + if (has_index && gc->guardian[guardian].id != 0) { /// Check if guardian already exists, refuse to spawn if so. + struct mob_data *md = map->id2md(gc->guardian[guardian].id); + + if (md != NULL && md->guardian_data != NULL && md->guardian_data->number == guardian) { + ShowError("mob_spawn_guardian: Attempted to spawn guardian in position %d which already has a guardian on castle map %s.\n", + guardian, mapname); return 0; } } - md = mob->spawn_dataset(&data); + struct mob_data *md = mob->spawn_dataset(&data, npc_id); + md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data)); md->guardian_data->number = guardian; md->guardian_data->castle = gc; - if( has_index ) - {// permanent guardian + + if (has_index) { /// Permanent guardian. gc->guardian[guardian].id = md->bl.id; - } - else - {// temporary guardian + } else { /// Temporary guardian. int i; + ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == 0); - if( i == gc->temp_guardians_max ) - { + + if (i == gc->temp_guardians_max) { ++(gc->temp_guardians_max); RECREATE(gc->temp_guardians, int, gc->temp_guardians_max); } + gc->temp_guardians[i] = md->bl.id; } - if( g ) + + if (g != NULL) md->guardian_data->g = g; - else if( gc->guild_id ) - timer->add(timer->gettick()+5000,mob->spawn_guardian_sub,md->bl.id,gc->guild_id); - mob->spawn(md); + else if (gc->guild_id > 0) + timer->add(timer->gettick() + 5000, mob->spawn_guardian_sub, md->bl.id, gc->guild_id); + mob->spawn(md); return md->bl.id; } -/*========================================== - * Summoning BattleGround [Zephyrus] - *------------------------------------------*/ -static int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id) +/** + * Spawn a mob with allegiance to the given battle group. + * + * @param mapname The name of the map where the mob should be spawned. + * @param x The x coordinate where the mob should be spawned. + * @param y The y coordinate where the mob should be spawned. + * @param mobname The mob's display name. + * @param class_ The mob's mob ID in database. + * @param event The name of the event which should be executed when the mob is killed. + * @param bg_id The battle group ID. + * @param npc_id If spawned by NPC script, this holds the ID of the invoking NPC. + * @return The spawned mob's GID, or 0 if spawning failed. + * + * @author Zephyrus + * + **/ +static int mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, + unsigned int bg_id, int npc_id) { - struct mob_data *md = NULL; - struct spawn_data data; - int16 m; - nullpo_ret(mapname); nullpo_ret(mobname); nullpo_ret(event); - if( (m = map->mapname2mapid(mapname)) < 0 ) { + const int map_id = map->mapname2mapid(mapname); + + if (map_id == INDEX_NOT_FOUND) { ShowWarning("mob_spawn_bg: Map [%s] not found.\n", mapname); return 0; } - memset(&data, 0, sizeof(struct spawn_data)); - data.m = m; - data.num = 1; - if( class_ <= 0 ) - { - class_ = mob->get_random_id(-class_-1,1,99); - if( !class_ ) return 0; + if ((x <= 0 || y <= 0) && map->search_freecell(NULL, map_id, &x, &y, -1, -1, 1) == 0) { + ShowWarning("mob_spawn_bg: Couldn't locate a spawn cell for guardian class %d (bg_id %u) on map %s.\n", class_, bg_id, mapname); + return 0; } - data.class_ = class_; - if( (x <= 0 || y <= 0) && !map->search_freecell(NULL, m, &x, &y, -1,-1, 1) ) { - ShowWarning("mob_spawn_bg: Couldn't locate a spawn cell for guardian class %d (bg_id %u) at map %s\n", class_, bg_id, map->list[m].name); + if (class_ <= 0 && (class_ = mob->get_random_id(-class_ - 1, 1, 99)) == 0) return 0; - } + struct spawn_data data; + + memset(&data, 0, sizeof(struct spawn_data)); + data.num = 1; + data.m = map_id; + data.class_ = class_; data.x = x; data.y = y; safestrncpy(data.name, mobname, sizeof(data.name)); safestrncpy(data.eventname, event, sizeof(data.eventname)); - if( !mob->parse_dataset(&data) ) + + if (mob->parse_dataset(&data) == 0) return 0; - md = mob->spawn_dataset(&data); - mob->spawn(md); - md->bg_id = bg_id; // BG Team ID + struct mob_data *md = mob->spawn_dataset(&data, npc_id); + mob->spawn(md); + md->bg_id = bg_id; return md->bl.id; } @@ -3100,18 +3194,25 @@ static int mob_countslave(struct block_list *bl) return map->foreachinmap(mob->countslave_sub, bl->m, BL_MOB,bl->id); } -/*========================================== - * Summons amount slaves contained in the value[5] array using round-robin. [adapted by Skotlex] - *------------------------------------------*/ +/** + * Summons amount slaves contained in the value[5] array using round-robin. + * + * @param md2 The mob which summons the slaves. + * @param value Array with slave mob IDs. + * @param amount The amount of slaves to spawn. + * @param skill_id The Id of the skill which summons the slaves. + * @return 1 on success, 0 on failure. + * + * @author Skotlex + * + **/ static int mob_summonslave(struct mob_data *md2, int *value, int amount, uint16 skill_id) { - struct mob_data *md; - struct spawn_data data; - int count = 0,k=0,hp_rate=0; - nullpo_ret(md2); nullpo_ret(value); + struct spawn_data data; + memset(&data, 0, sizeof(struct spawn_data)); data.m = md2->bl.m; data.x = md2->bl.x; @@ -3120,31 +3221,42 @@ static int mob_summonslave(struct mob_data *md2, int *value, int amount, uint16 data.state.size = md2->special_state.size; data.state.ai = md2->special_state.ai; - if(mob->db_checkid(value[0]) == 0) + if (mob->db_checkid(value[0]) == 0) return 0; - /** - * Flags this monster is able to summon; saves a worth amount of memory upon deletion - **/ - md2->can_summon = 1; - while(count < 5 && mob->db_checkid(value[count])) count++; - if(count < 1) return 0; - if (amount > 0 && amount < count) { //Do not start on 0, pick some random sub subset [Skotlex] - k = rnd()%count; - amount+=k; //Increase final value by same amount to preserve total number to summon. + md2->can_summon = 1; /// Flags this monster is able to summon; saves a worth amount of memory upon deletion. + + int count = 0; + + while (count < 5 && mob->db_checkid(value[count]) != 0) + count++; + + if (count < 1) + return 0; + + int k = 0; + + if (amount > 0 && amount < count) { /// Do not start on 0, pick some random sub subset. [Skotlex] + k = rnd() % count; + amount += k; /// Increase final value by same amount to preserve total number to summon. } - if (!battle_config.monster_class_change_recover && - (skill_id == NPC_TRANSFORMATION || skill_id == NPC_METAMORPHOSIS)) + int hp_rate = 0; + + if ((skill_id == NPC_TRANSFORMATION || skill_id == NPC_METAMORPHOSIS) && + battle_config.monster_class_change_recover == 0) hp_rate = get_percentage(md2->status.hp, md2->status.max_hp); - for(;k<amount;k++) { - short x,y; - data.class_ = value[k%count]; //Summon slaves in round-robin fashion. [Skotlex] + for (; k < amount; k++) { + data.class_ = value[k % count]; /// Summon slaves in round-robin fashion. [Skotlex] + if (mob->db_checkid(data.class_) == 0) continue; - if (map->search_freecell(&md2->bl, 0, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 0)) { + short x; + short y; + + if (map->search_freecell(&md2->bl, 0, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 0) != 0) { data.x = x; data.y = y; } else { @@ -3152,49 +3264,52 @@ static int mob_summonslave(struct mob_data *md2, int *value, int amount, uint16 data.y = md2->bl.y; } - //These two need to be loaded from the db for each slave. if (battle_config.override_mob_names == 1) strcpy(data.name, DEFAULT_MOB_NAME); else strcpy(data.name, DEFAULT_MOB_JNAME); - if (!mob->parse_dataset(&data)) + if (mob->parse_dataset(&data) == 0) continue; - md= mob->spawn_dataset(&data); - if(skill_id == NPC_SUMMONSLAVE){ - md->master_id=md2->bl.id; + struct mob_data *md = mob->spawn_dataset(&data, 0); + + if (skill_id == NPC_SUMMONSLAVE) { + md->master_id = md2->bl.id; md->special_state.ai = md2->special_state.ai; } + mob->spawn(md); - if (hp_rate) //Scale HP - md->status.hp = md->status.max_hp*hp_rate/100; + if (hp_rate > 0) /// Scale HP. + md->status.hp = md->status.max_hp * hp_rate / 100; - //Inherit the aggressive mode of the master. - if (battle_config.slaves_inherit_mode && md->master_id) { + /** Inherit the aggressive mode of the master. **/ + if (battle_config.slaves_inherit_mode > 0 && md->master_id > 0) { switch (battle_config.slaves_inherit_mode) { - case 1: //Always aggressive - if (!(md->status.mode&MD_AGGRESSIVE)) - sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0); + case 1: /// Always aggressive. + if ((md->status.mode & MD_AGGRESSIVE) == 0) + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 0); + break; - case 2: //Always passive - if (md->status.mode&MD_AGGRESSIVE) - sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0); + case 2: /// Always passive. + if ((md->status.mode & MD_AGGRESSIVE) == MD_AGGRESSIVE) + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, 0, MD_AGGRESSIVE, 0); + break; - default: //Copy master. - if (md2->status.mode&MD_AGGRESSIVE) - sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0); + default: /// Copy master. + if ((md2->status.mode & MD_AGGRESSIVE) == MD_AGGRESSIVE) + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 0); else - sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, 0, MD_AGGRESSIVE, 0); break; } } - clif->skill_nodamage(&md->bl,&md->bl,skill_id,amount,1); + clif->skill_nodamage(&md->bl, &md->bl, skill_id, amount, 1); } - return 0; + return 1; } /*========================================== @@ -3588,211 +3703,239 @@ static int mob_is_clone(int class_) return class_; } -//Flag values: -//&1: Set special AI (fight mobs, not players) -//If mode is not passed, a default aggressive mode is used. -//If master_id is passed, clone is attached to him. -//Returns: ID of newly crafted copy. -static int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, uint32 mode, int flag, unsigned int duration) +/** + * Spawns a mob which is a clone of another character. + * + * @param sd The character which should be cloned. + * @param m The ID of the map where the clone should be spawned. + * @param x The x coordinate where the clone should be spawned. + * @param y The y coordinate where the clone should be spawned. + * @param event The name of the event which should be executed when the clone is killed. + * @param master_id If passed, the clone will be attached to this account ID. + * @param mode The clone's mob mode(s). (Defaults to MD_CANMOVE|MD_AGGRESSIVE|MD_ASSIST|MD_CANATTACK.) + * @param flag 0 - target characters; 1 - target mobs. + * @param duration How long the clone will live before it is auto-removed. (ms) + * @return The spawned clone's GID, or 0 if spawning failed. + * + **/ +static int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, + uint32 mode, int flag, unsigned int duration) { - int class_; - int i,j,h,inf, fd; - struct mob_data *md; - struct mob_skill *ms; - struct mob_db* db; - struct status_data *mstatus; - nullpo_ret(sd); - if(pc_isdead(sd) && master_id && flag&1) + if (pc_isdead(sd) && master_id != 0 && flag == 1) return 0; - ARR_FIND( MOB_CLONE_START, MOB_CLONE_END, class_, mob->db_data[class_] == NULL ); - if(class_ < 0 || class_ >= MOB_CLONE_END) + int class_; + + ARR_FIND(MOB_CLONE_START, MOB_CLONE_END, class_, mob->db_data[class_] == NULL); + + if (class_ < 0 || class_ >= MOB_CLONE_END) return 0; - db = mob->db_data[class_]=(struct mob_db*)aCalloc(1, sizeof(struct mob_db)); - mstatus = &db->status; - strcpy(db->sprite,sd->status.name); - strcpy(db->name,sd->status.name); - strcpy(db->jname,sd->status.name); - db->lv=status->get_lv(&sd->bl); + mob->db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db)); + + struct mob_db *db = mob->db_data[class_]; + struct status_data *mstatus = &db->status; + + strcpy(db->sprite, sd->status.name); + strcpy(db->name, sd->status.name); + strcpy(db->jname, sd->status.name); + db->lv = status->get_lv(&sd->bl); + db->dmg_taken_rate = 100; memcpy(mstatus, &sd->base_status, sizeof(struct status_data)); - mstatus->rhw.atk2= mstatus->dex + mstatus->rhw.atk + mstatus->rhw.atk2; //Max ATK - mstatus->rhw.atk = mstatus->dex; //Min ATK - if (mstatus->lhw.atk) { - mstatus->lhw.atk2= mstatus->dex + mstatus->lhw.atk + mstatus->lhw.atk2; //Max ATK - mstatus->lhw.atk = mstatus->dex; //Min ATK + mstatus->rhw.atk2 = mstatus->dex + mstatus->rhw.atk + mstatus->rhw.atk2; /// Max ATK. + mstatus->rhw.atk = mstatus->dex; /// Min ATK. + + if (mstatus->lhw.atk > 0) { + mstatus->lhw.atk2 = mstatus->dex + mstatus->lhw.atk + mstatus->lhw.atk2; /// Max ATK. + mstatus->lhw.atk = mstatus->dex; /// Min ATK. } - if (mode != MD_NONE) //User provided mode. + + if (mode != MD_NONE) /// User provided mode. mstatus->mode = mode; - else if (flag&1) //Friendly Character, remove looting. + else if (flag == 1) /// Friendly Character, remove looting. mstatus->mode &= ~MD_LOOTER; + mstatus->hp = mstatus->max_hp; mstatus->sp = mstatus->max_sp; memcpy(&db->vd, &sd->vd, sizeof(struct view_data)); - db->base_exp=1; - db->job_exp=1; - db->range2=AREA_SIZE; //Let them have the same view-range as players. - db->range3=AREA_SIZE; //Min chase of a screen. - db->option=sd->sc.option; + db->base_exp = 1; + db->job_exp = 1; + db->range2 = AREA_SIZE; /// Let them have the same view-range as players. + db->range3 = AREA_SIZE; /// Min chase of a screen. + db->option = sd->sc.option; - //Skill copy [Skotlex] - ms = &db->skill[0]; + const int fd = sd->fd; - /** - * We temporarily disable sd's fd so it doesn't receive the messages from skill_check_condition_castbegin - **/ - fd = sd->fd; - sd->fd = 0; - - //Go Backwards to give better priority to advanced skills. - for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) { - int idx = pc->skill_tree[pc->class2idx(sd->status.class)][j].idx; - int skill_id = pc->skill_tree[pc->class2idx(sd->status.class)][j].id; - if (!skill_id || sd->status.skill[idx].lv < 1 || - (skill->dbs->db[idx].inf2&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) - ) + sd->fd = 0; /// Temporarily disable sd's fd so it doesn't receive the messages from skill_check_condition_castbegin. + + struct mob_skill *mob_skills = &db->skill[0]; + + /// Go Backwards to give better priority to advanced skills. + for (int i = 0, j = MAX_SKILL_TREE - 1; j >= 0 && i < MAX_MOBSKILL; j--) { + const int idx = pc->skill_tree[pc->class2idx(sd->status.class)][j].idx; + const int skill_id = pc->skill_tree[pc->class2idx(sd->status.class)][j].id; + + if (skill_id == 0 || sd->status.skill[idx].lv < 1 || + (skill->dbs->db[idx].inf2 & (INF2_WEDDING_SKILL | INF2_GUILD_SKILL)) > 0) continue; - for(h = 0; h < map->list[sd->bl.m].zone->disabled_skills_count; h++) { - if( skill_id == map->list[sd->bl.m].zone->disabled_skills[h]->nameid && map->list[sd->bl.m].zone->disabled_skills[h]->subtype == MZS_CLONE ) { + + int h; + + for (h = 0; h < map->list[sd->bl.m].zone->disabled_skills_count; h++) { + if (skill_id == map->list[sd->bl.m].zone->disabled_skills[h]->nameid && + map->list[sd->bl.m].zone->disabled_skills[h]->subtype == MZS_CLONE) break; - } } - if( h < map->list[sd->bl.m].zone->disabled_skills_count ) + + if (h < map->list[sd->bl.m].zone->disabled_skills_count) continue; - //Normal aggressive mob, disable skills that cannot help them fight - //against players (those with flags UF_NOMOB and UF_NOPC are specific - //to always aid players!) [Skotlex] - if (!(flag&1) && - skill->get_unit_id(skill_id, 0) && - skill->get_unit_flag(skill_id)&(UF_NOMOB|UF_NOPC)) + + /// Normal aggressive mob. Disable skills that cannot help fighting against players. (Those with flags UF_NOMOB and UF_NOPC are specific to always aid players!) [Skotlex] + if (flag == 0 && skill->get_unit_id(skill_id, 0) != 0 && + (skill->get_unit_flag(skill_id) & (UF_NOMOB | UF_NOPC)) > 0) continue; - /** - * The clone should be able to cast the skill (e.g. have the required weapon) bugreport:5299) - **/ - if( !skill->check_condition_castbegin(sd,skill_id,sd->status.skill[idx].lv) ) + + /// The clone should be able to cast the skill. (E.g. have the required weapon.) [bugreport:5299] + if (skill->check_condition_castbegin(sd, skill_id, sd->status.skill[idx].lv) == 0) continue; - memset (&ms[i], 0, sizeof(struct mob_skill)); - ms[i].skill_id = skill_id; - ms[i].skill_lv = sd->status.skill[idx].lv; - ms[i].state = MSS_ANY; - ms[i].permillage = 500*battle_config.mob_skill_rate/100; //Default chance of all skills: 5% - ms[i].emotion = -1; - ms[i].cancel = 0; - ms[i].casttime = skill->cast_fix(&sd->bl,skill_id, ms[i].skill_lv); - ms[i].delay = 5000+skill->delay_fix(&sd->bl,skill_id, ms[i].skill_lv); - - inf = skill->dbs->db[idx].inf; - if (inf&INF_ATTACK_SKILL) { - ms[i].target = MST_TARGET; - ms[i].cond1 = MSC_ALWAYS; - if (skill->get_range(skill_id, ms[i].skill_lv) > 3) - ms[i].state = MSS_ANYTARGET; + memset(&mob_skills[i], 0, sizeof(struct mob_skill)); + mob_skills[i].skill_id = skill_id; + mob_skills[i].skill_lv = sd->status.skill[idx].lv; + mob_skills[i].state = MSS_ANY; + mob_skills[i].permillage = 500 * battle_config.mob_skill_rate / 100; /// Default chance of all skills: 5% + mob_skills[i].emotion = -1; + mob_skills[i].cancel = 0; + mob_skills[i].casttime = skill->cast_fix(&sd->bl, skill_id, mob_skills[i].skill_lv); + mob_skills[i].delay = 5000 + skill->delay_fix(&sd->bl, skill_id, mob_skills[i].skill_lv); + + const int inf = skill->dbs->db[idx].inf; + + if ((inf & INF_ATTACK_SKILL) == INF_ATTACK_SKILL) { + mob_skills[i].target = MST_TARGET; + mob_skills[i].cond1 = MSC_ALWAYS; + + if (skill->get_range(skill_id, mob_skills[i].skill_lv) > 3) + mob_skills[i].state = MSS_ANYTARGET; else - ms[i].state = MSS_BERSERK; - } else if(inf&INF_GROUND_SKILL) { - if (skill->get_inf2(skill_id)&INF2_TRAP) { //Traps! - ms[i].state = MSS_IDLE; - ms[i].target = MST_AROUND2; - ms[i].delay = 60000; - } else if (skill->get_unit_target(skill_id) == BCT_ENEMY) { //Target Enemy - ms[i].state = MSS_ANYTARGET; - ms[i].target = MST_TARGET; - ms[i].cond1 = MSC_ALWAYS; - } else { //Target allies - ms[i].target = MST_FRIEND; - ms[i].cond1 = MSC_FRIENDHPLTMAXRATE; - ms[i].cond2 = 95; + mob_skills[i].state = MSS_BERSERK; + } else if ((inf & INF_GROUND_SKILL) == INF_GROUND_SKILL) { + if ((skill->get_inf2(skill_id) & INF2_TRAP) == INF2_TRAP) { /// Traps! + mob_skills[i].state = MSS_IDLE; + mob_skills[i].target = MST_AROUND2; + mob_skills[i].delay = 60000; + } else if (skill->get_unit_target(skill_id) == BCT_ENEMY) { /// Target Enemy. + mob_skills[i].state = MSS_ANYTARGET; + mob_skills[i].target = MST_TARGET; + mob_skills[i].cond1 = MSC_ALWAYS; + } else { /// Target allies. + mob_skills[i].target = MST_FRIEND; + mob_skills[i].cond1 = MSC_FRIENDHPLTMAXRATE; + mob_skills[i].cond2 = 95; } - } else if (inf&INF_SELF_SKILL) { - if (skill->get_inf2(skill_id)&INF2_NO_TARGET_SELF) { //auto-select target skill. - ms[i].target = MST_TARGET; - ms[i].cond1 = MSC_ALWAYS; - if (skill->get_range(skill_id, ms[i].skill_lv) > 3) { - ms[i].state = MSS_ANYTARGET; - } else { - ms[i].state = MSS_BERSERK; - } - } else { //Self skill - ms[i].target = MST_SELF; - ms[i].cond1 = MSC_MYHPLTMAXRATE; - ms[i].cond2 = 90; - ms[i].permillage = 2000; - //Delay: Remove the stock 5 secs and add half of the support time. - ms[i].delay += -5000 +(skill->get_time(skill_id, ms[i].skill_lv) + skill->get_time2(skill_id, ms[i].skill_lv))/2; - if (ms[i].delay < 5000) - ms[i].delay = 5000; //With a minimum of 5 secs. + } else if ((inf & INF_SELF_SKILL) == INF_SELF_SKILL) { + if ((skill->get_inf2(skill_id) & INF2_NO_TARGET_SELF) == INF2_NO_TARGET_SELF) { /// Auto-select target skill. + mob_skills[i].target = MST_TARGET; + mob_skills[i].cond1 = MSC_ALWAYS; + + if (skill->get_range(skill_id, mob_skills[i].skill_lv) > 3) + mob_skills[i].state = MSS_ANYTARGET; + else + mob_skills[i].state = MSS_BERSERK; + } else { /// Self skill. + mob_skills[i].target = MST_SELF; + mob_skills[i].cond1 = MSC_MYHPLTMAXRATE; + mob_skills[i].cond2 = 90; + mob_skills[i].permillage = 2000; + + const int time1 = skill->get_time(skill_id, mob_skills[i].skill_lv); + const int time2 = skill->get_time2(skill_id, mob_skills[i].skill_lv); + + /** Delay: Remove the stock 5 secs and add half of the support time. **/ + mob_skills[i].delay += -5000 + (time1 + time2) / 2; + + if (mob_skills[i].delay < 5000) + mob_skills[i].delay = 5000; /// With a minimum of 5 seconds. } - } else if (inf&INF_SUPPORT_SKILL) { - ms[i].target = MST_FRIEND; - ms[i].cond1 = MSC_FRIENDHPLTMAXRATE; - ms[i].cond2 = 90; + } else if ((inf & INF_SUPPORT_SKILL) == INF_SUPPORT_SKILL) { + mob_skills[i].target = MST_FRIEND; + mob_skills[i].cond1 = MSC_FRIENDHPLTMAXRATE; + mob_skills[i].cond2 = 90; + if (skill_id == AL_HEAL) - ms[i].permillage = 5000; //Higher skill rate usage for heal. + mob_skills[i].permillage = 5000; /// Higher skill rate usage for heal. else if (skill_id == ALL_RESURRECTION) - ms[i].cond2 = 1; - //Delay: Remove the stock 5 secs and add half of the support time. - ms[i].delay += -5000 +(skill->get_time(skill_id, ms[i].skill_lv) + skill->get_time2(skill_id, ms[i].skill_lv))/2; - if (ms[i].delay < 2000) - ms[i].delay = 2000; //With a minimum of 2 secs. - - if (i+1 < MAX_MOBSKILL) { //duplicate this so it also triggers on self. - memcpy(&ms[i+1], &ms[i], sizeof(struct mob_skill)); + mob_skills[i].cond2 = 1; + + const int time1 = skill->get_time(skill_id, mob_skills[i].skill_lv); + const int time2 = skill->get_time2(skill_id, mob_skills[i].skill_lv); + + /** Delay: Remove the stock 5 secs and add half of the support time. **/ + mob_skills[i].delay += -5000 + (time1 + time2) / 2; + + if (mob_skills[i].delay < 2000) + mob_skills[i].delay = 2000; /// With a minimum of 2 seconds. + + if (i + 1 < MAX_MOBSKILL) { /// Duplicate this so it also triggers on self. + memcpy(&mob_skills[i + 1], &mob_skills[i], sizeof(struct mob_skill)); db->maxskill = ++i; - ms[i].target = MST_SELF; - ms[i].cond1 = MSC_MYHPLTMAXRATE; + mob_skills[i].target = MST_SELF; + mob_skills[i].cond1 = MSC_MYHPLTMAXRATE; } } else { - switch (skill_id) { //Certain Special skills that are passive, and thus, never triggered. - case MO_TRIPLEATTACK: - case TF_DOUBLE: - case GS_CHAINACTION: - ms[i].state = MSS_BERSERK; - ms[i].target = MST_TARGET; - ms[i].cond1 = MSC_ALWAYS; - ms[i].permillage = skill_id==MO_TRIPLEATTACK?(3000-ms[i].skill_lv*100):(ms[i].skill_lv*500); - ms[i].delay -= 5000; //Remove the added delay as these could trigger on "all hits". - break; - default: //Untreated Skill - continue; + switch (skill_id) { /// Certain special skills that are passive, and thus, never triggered. + case MO_TRIPLEATTACK: + FALLTHROUGH + case TF_DOUBLE: + FALLTHROUGH + case GS_CHAINACTION: + mob_skills[i].state = MSS_BERSERK; + mob_skills[i].target = MST_TARGET; + mob_skills[i].cond1 = MSC_ALWAYS; + + if (skill_id == MO_TRIPLEATTACK) + mob_skills[i].permillage = 3000 - mob_skills[i].skill_lv * 100; + else + mob_skills[i].permillage = mob_skills[i].skill_lv * 500; + + mob_skills[i].delay -= 5000; /// Remove the added delay as these could trigger on "all hits". + break; + default: /// Untreated skill. + continue; } } - if (battle_config.mob_skill_rate!= 100) - ms[i].permillage = ms[i].permillage*battle_config.mob_skill_rate/100; - if (battle_config.mob_skill_delay != 100) - ms[i].delay = ms[i].delay*battle_config.mob_skill_delay/100; + mob_skills[i].permillage *= battle_config.mob_skill_rate / 100; + mob_skills[i].delay *= battle_config.mob_skill_delay / 100; db->maxskill = ++i; } - /** - * We grant the session it's fd value back. - **/ - sd->fd = fd; + sd->fd = fd; /// We grant the session it's fd value back. + + /// Finally spawn it. + struct mob_data *md = mob->once_spawn_sub(&sd->bl, m, x, y, DEFAULT_MOB_NAME, class_, event, SZ_SMALL, AI_NONE, 0); - //Finally, spawn it. - md = mob->once_spawn_sub(&sd->bl, m, x, y, DEFAULT_MOB_NAME, class_, event, SZ_SMALL, AI_NONE); - if (!md) return 0; //Failed? + if (md == NULL) + return 0; /// Failed? md->special_state.clone = 1; - if (master_id || flag || duration) { //Further manipulate crafted char. - if (flag&1) //Friendly Character - md->special_state.ai = AI_ATTACK; - if (master_id) //Attach to Master - md->master_id = master_id; - if (duration) //Auto Delete after a while. - { - if( md->deletetimer != INVALID_TIMER ) - timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add(timer->gettick() + duration, mob->timer_delete, md->bl.id, 0); - } + if (flag == 1) /// Friendly character. + md->special_state.ai = AI_ATTACK; + + if (master_id != 0) /// Attach to master. + md->master_id = master_id; + + if (duration > 0) { /// Auto delete after a while. + if (md->deletetimer != INVALID_TIMER) + timer->delete(md->deletetimer, mob->timer_delete); + + md->deletetimer = timer->add(timer->gettick() + duration, mob->timer_delete, md->bl.id, 0); } mob->spawn(md); - return md->bl.id; } @@ -4206,8 +4349,12 @@ static void mob_read_db_viewdata_sub(struct mob_db *entry, struct config_setting entry->vd.head_mid = libconfig->setting_get_int(it); if ((it = libconfig->setting_get_member(t, "HeadLowId")) != NULL) entry->vd.head_bottom = libconfig->setting_get_int(it); + if ((it = libconfig->setting_get_member(t, "HairStyleId")) != NULL) entry->vd.hair_style = libconfig->setting_get_int(it); + else + entry->vd.hair_style = 1; + if ((it = libconfig->setting_get_member(t, "BodyStyleId")) != NULL) entry->vd.body_style = libconfig->setting_get_int(it); if ((it = libconfig->setting_get_member(t, "HairColorId")) != NULL) diff --git a/src/map/mob.h b/src/map/mob.h index 8fd16f191..8839809f2 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -255,6 +255,7 @@ struct mob_data { int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs) unsigned int bg_id; // BattleGround System int clan_id; // Clan System + int npc_id; // NPC ID if spawned with monster/areamonster/guardian/bg_monster/atcommand("@monster xy") (Used to kill mob on NPC unload.) int64 next_walktime, last_thinktime, last_linktime, last_pcneartime, dmgtick; short move_fail_count; @@ -507,14 +508,14 @@ struct mob_interface { int (*db_checkid) (const int id); struct view_data* (*get_viewdata) (int class_); int (*parse_dataset) (struct spawn_data *data); - struct mob_data* (*spawn_dataset) (struct spawn_data *data); + struct mob_data* (*spawn_dataset) (struct spawn_data *data, int npc_id); int (*get_random_id) (int type, int flag, int lv); bool (*ksprotected) (struct block_list *src, struct block_list *target); - struct mob_data* (*once_spawn_sub) (struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai); + struct mob_data* (*once_spawn_sub) (struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai, int npc_id); int (*once_spawn) (struct map_session_data *sd, int16 m, int16 x, int16 y, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai); int (*once_spawn_area) (struct map_session_data *sd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai); - int (*spawn_guardian) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index); - int (*spawn_bg) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id); + int (*spawn_guardian) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index, int npc_id); + int (*spawn_bg) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id, int npc_id); int (*can_reach) (struct mob_data *md, struct block_list *bl, int range, int state); int (*linksearch) (struct block_list *bl, va_list ap); int (*delayspawn) (int tid, int64 tick, int id, intptr_t data); diff --git a/src/map/npc.c b/src/map/npc.c index cc588e52c..d369aca82 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1457,7 +1457,11 @@ static int npc_cashshop_buylist(struct map_session_data *sd, int points, struct return ERROR_TYPE_NPC; if( nd->subtype != CASHSHOP ) { - if (nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET && nd->u.scr.shop->type != NST_BARTER) { + if (nd->subtype == SCRIPT && nd->u.scr.shop && + nd->u.scr.shop->type != NST_ZENY && + nd->u.scr.shop->type != NST_MARKET && + nd->u.scr.shop->type != NST_BARTER && + nd->u.scr.shop->type != NST_EXPANDED_BARTER) { shop = nd->u.scr.shop->item; shop_size = nd->u.scr.shop->items; } else { @@ -1623,7 +1627,7 @@ static void npc_market_tosql(struct npc_data *nd, int index) { nullpo_retv(nd); Assert_retv(index >= 0 && index < nd->u.scr.shop->items); - if (SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s','%d','%u')", + if (SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s','%d','%d')", map->npc_market_data_db, nd->exname, nd->u.scr.shop->item[index].nameid, nd->u.scr.shop->item[index].qty)) Sql_ShowDebug(map->mysql_handle); } @@ -1716,7 +1720,9 @@ static void npc_barter_tosql(struct npc_data *nd, int index) nullpo_retv(nd); Assert_retv(index >= 0 && index < nd->u.scr.shop->items); const struct npc_item_list *const item = &nd->u.scr.shop->item[index]; - if (SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s', '%d', '%u', '%u', '%d')", + if (item->qty == -1) + return; + if (SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s', '%d', '%d', '%u', '%d')", map->npc_barter_data_db, nd->exname, item->nameid, item->qty, item->value, item->value2)) { Sql_ShowDebug(map->mysql_handle); } @@ -1753,6 +1759,178 @@ static void npc_barter_delfromsql(struct npc_data *nd, int index) } } + +/** + * Loads persistent NPC Expanded Barter Data from SQL + **/ +static void npc_expanded_barter_fromsql(void) +{ + struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle); + char name[NAME_LENGTH + 1]; + int itemid; + int amount; + int zeny; + StringBuf buf; + + StrBuf->Init(&buf); + StrBuf->AppendStr(&buf, "SELECT `name`, `itemId`, `amount`, `zeny`"); + for (int k = 1; k < 11; k ++) { + StrBuf->Printf(&buf, ", `currencyId%d`, `currencyAmount%d`, `currencyRefine%d`", k, k, k); + } + StrBuf->Printf(&buf, " FROM `%s`", map->npc_expanded_barter_data_db); + + if (SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) + || SQL_ERROR == SQL->StmtExecute(stmt) + ) { + SqlStmt_ShowDebug(stmt); + SQL->StmtFree(stmt); + return; + } + + struct npc_barter_currency tempCurrency[10]; + SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name, sizeof name, NULL, NULL); + SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, sizeof itemid, NULL, NULL); + SQL->StmtBindColumn(stmt, 2, SQLDT_UINT32, &amount, sizeof amount, NULL, NULL); + SQL->StmtBindColumn(stmt, 3, SQLDT_UINT32, &zeny, sizeof zeny, NULL, NULL); + for (int k = 0; k < 10; k ++) { + SQL->StmtBindColumn(stmt, k * 3 + 4, SQLDT_INT, &tempCurrency[k].nameid, sizeof tempCurrency[k].nameid, NULL, NULL); + SQL->StmtBindColumn(stmt, k * 3 + 5, SQLDT_INT, &tempCurrency[k].amount, sizeof tempCurrency[k].amount, NULL, NULL); + SQL->StmtBindColumn(stmt, k * 3 + 6, SQLDT_INT, &tempCurrency[k].refine, sizeof tempCurrency[k].refine, NULL, NULL); + } + + while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) { + struct npc_data *nd = NULL; + unsigned short i; + + if ((nd = npc->name2id(name)) == NULL) { + ShowError("npc_expanded_barter_fromsql: NPC '%s' not found! skipping...\n",name); + npc->expanded_barter_delfromsql_sub(name, INT_MAX, 0, 0, NULL); + continue; + } else if (nd->subtype != SCRIPT || nd->u.scr.shop == NULL || nd->u.scr.shop->items == 0 || nd->u.scr.shop->type != NST_EXPANDED_BARTER) { + ShowError("npc_expanded_barter_fromsql: NPC '%s' is not proper for barter, skipping...\n",name); + npc->expanded_barter_delfromsql_sub(name, INT_MAX, 0, 0, NULL); + continue; + } + + for (i = 0; i < nd->u.scr.shop->items; i++) { + struct npc_item_list *const item = &nd->u.scr.shop->item[i]; + if (item->nameid == itemid && item->value == zeny) { + int count = nd->u.scr.shop->item[i].value2; + if (count > 10) + count = 10; + int curIndex; + for (curIndex = 0; curIndex < count; curIndex ++) { + struct npc_barter_currency *currency = &nd->u.scr.shop->item[i].currency[curIndex]; + struct npc_barter_currency *currency2 = &tempCurrency[curIndex]; + if (currency->nameid != currency2->nameid || + currency->amount != currency2->amount || + currency->refine != currency2->refine) { + break; + } + } + if (curIndex == count) { + item->qty = amount; + break; + } + } + } + + if (i == nd->u.scr.shop->items) { + ShowError("npc_expanded_barter_fromsql: NPC '%s' does not sell item %d (qty %d), deleting...\n", name, itemid, amount); + npc->expanded_barter_delfromsql_sub(name, itemid, zeny, 10, &tempCurrency[0]); + continue; + } + } + SQL->StmtFree(stmt); + StrBuf->Destroy(&buf); +} + +/** + * Saves persistent NPC Expanded Barter Data into SQL + **/ +static void npc_expanded_barter_tosql(struct npc_data *nd, int index) +{ + nullpo_retv(nd); + Assert_retv(index >= 0 && index < nd->u.scr.shop->items); + const struct npc_item_list *const item = &nd->u.scr.shop->item[index]; + if (item->qty == -1) + return; + + npc->expanded_barter_delfromsql(nd, index); + + StringBuf buf; + StrBuf->Init(&buf); + StrBuf->Printf(&buf, "INSERT INTO `%s` VALUES ('%s', '%d', '%d', '%u'", map->npc_expanded_barter_data_db, nd->exname, item->nameid, item->qty, item->value); + int currencyCount = item->value2; + if (currencyCount > 10) + currencyCount = 10; + int k; + for (k = 0; k < currencyCount; k++) { + struct npc_barter_currency *currency = &item->currency[k]; + StrBuf->Printf(&buf, ", '%d', '%d', '%d'", currency->nameid, currency->amount, currency->refine); + } + for (; k < 10; k ++) { + StrBuf->Printf(&buf, ", '0', '0', '0'"); + } + StrBuf->AppendStr(&buf, ")"); + + if (SQL_ERROR == SQL->QueryStr(map->mysql_handle, StrBuf->Value(&buf))) { + Sql_ShowDebug(map->mysql_handle); + } + StrBuf->Destroy(&buf); +} + +/** + * Removes persistent NPC Expanded Barter Data from SQL + */ +static void npc_expanded_barter_delfromsql_sub(const char *npcname, int itemId, int zeny, int currencyCount, struct npc_barter_currency* currency) +{ + if (itemId == INT_MAX) { + if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `name`='%s'", map->npc_expanded_barter_data_db, npcname)) + Sql_ShowDebug(map->mysql_handle); + } else { + StringBuf buf; + + StrBuf->Init(&buf); + StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE `name`='%s' AND `itemId`='%d' AND `zeny`='%d'", + map->npc_expanded_barter_data_db, npcname, itemId, zeny); + int k = 0; + if (currencyCount > 10) + currencyCount = 10; + for (k = 0; k < currencyCount; k++) { + struct npc_barter_currency *currency1 = ¤cy[k]; + StrBuf->Printf(&buf, " AND currencyId%d='%d' and currencyAmount%d='%d' and currencyRefine%d='%d'", + k + 1, currency1->nameid, k + 1, currency1->amount, k + 1, currency1->refine); + } + for (; k < 10; k ++) { + StrBuf->Printf(&buf, " AND currencyId%d='0' and currencyAmount%d='0' and currencyRefine%d='0'", + k + 1, k + 1, k + 1); + } + StrBuf->AppendStr(&buf, " LIMIT 1"); + + if (SQL_ERROR == SQL->QueryStr(map->mysql_handle, StrBuf->Value(&buf))) { + Sql_ShowDebug(map->mysql_handle); + } + StrBuf->Destroy(&buf); + } +} + + +/** + * Removes persistent NPC Expanded Barter Data from SQL + **/ +static void npc_expanded_barter_delfromsql(struct npc_data *nd, int index) +{ + nullpo_retv(nd); + if (index == INT_MAX) { + npc->expanded_barter_delfromsql_sub(nd->exname, INT_MAX, 0, 0, NULL); + } else { + Assert_retv(index >= 0 && index < nd->u.scr.shop->items); + const struct npc_item_list *const item = &nd->u.scr.shop->item[index]; + npc->expanded_barter_delfromsql_sub(nd->exname, item->nameid, item->value, item->value2, &item->currency[0]); + } +} + /** * Judges whether to allow and spawn a trader's window. **/ @@ -1788,6 +1966,9 @@ static bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) case NST_BARTER: clif->npc_barter_open(sd, nd); break; + case NST_EXPANDED_BARTER: + clif->npc_expanded_barter_open(sd, nd); + break; default: clif->cashshop_show(sd,nd); break; @@ -1914,7 +2095,11 @@ static int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, return ERROR_TYPE_ITEM_ID; // Invalid Item if( nd->subtype != CASHSHOP ) { - if (nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET && nd->u.scr.shop->type != NST_BARTER) { + if (nd->subtype == SCRIPT && nd->u.scr.shop && + nd->u.scr.shop->type != NST_ZENY && + nd->u.scr.shop->type != NST_MARKET && + nd->u.scr.shop->type != NST_BARTER && + nd->u.scr.shop->type != NST_EXPANDED_BARTER) { shop = nd->u.scr.shop->item; shop_size = nd->u.scr.shop->items; } else { @@ -2262,6 +2447,9 @@ static int npc_barter_buylist(struct map_session_data *sd, struct barteritemlist if (n < 0 || n >= sd->status.inventorySize) return 11; // wrong inventory index + if (entry->addAmount <= 0) + return 14; // not enough item amount in inventory + int removeId = sd->status.inventory[n].nameid; const int j = entry->shopIndex; if (j < 0 || j >= shop_size) @@ -2355,6 +2543,152 @@ static int npc_barter_buylist(struct map_session_data *sd, struct barteritemlist return 12; } + +/** + * Processes incoming npc expanded barter purchase list + **/ +static int npc_expanded_barter_buylist(struct map_session_data *sd, struct barteritemlist *item_list) +{ + nullpo_retr(1, sd); + nullpo_retr(1, item_list); + + struct npc_data* nd = npc->checknear(sd, map->id2bl(sd->npc_shopid)); + + if (nd == NULL || nd->subtype != SCRIPT || VECTOR_LENGTH(*item_list) == 0 || + !nd->u.scr.shop || nd->u.scr.shop->type != NST_EXPANDED_BARTER) { + return 11; + } + + struct npc_item_list *shop = nd->u.scr.shop->item; + unsigned short shop_size = nd->u.scr.shop->items; + int w = 0; + int new_ = 0; + int64 z = 0; + int items[MAX_INVENTORY] = { 0 }; + + // process entries in buy list, one by one + for (int i = 0; i < VECTOR_LENGTH(*item_list); ++i) { + struct barter_itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + + if (entry->addAmount <= 0) + return 14; // not enough item amount in inventory + + const int j = entry->shopIndex; + if (j < 0 || j >= shop_size) + return 13; // no such item in shop + if (entry->addId != shop[j].nameid && entry->addId != itemdb_viewid(shop[j].nameid)) + return 13; // no such item in shop + entry->addId = shop[j].nameid; // item_avail replacement + if (!itemdb->exists(entry->addId)) + return 13; // item no longer in itemdb + + if ((int)shop[j].qty != -1 && entry->addAmount > (int)shop[j].qty) + return 14; // not enough item amount in shop + + int currencyCount = shop[j].value2; + for (int currencyIndex = 0; currencyIndex < currencyCount; currencyIndex ++) { + struct npc_barter_currency *currency = &shop[j].currency[currencyIndex]; + const int currencyItemId = currency->nameid; + const int currencyRefine = currency->refine; + int removeAmount = currency->amount * entry->addAmount; + if (removeAmount <= 0) + continue; + for (int n = 0; n < sd->status.inventorySize && removeAmount > 0; ++n) { + // check item id and existing amount + if (sd->status.inventory[n].nameid == currencyItemId && sd->status.inventory[n].amount > 0) { + // check item refine level + if (currencyRefine != -1 && sd->status.inventory[n].refine != currencyRefine) + continue; + if (sd->status.inventory[n].amount >= removeAmount) { + items[n] += removeAmount; + removeAmount = 0; + w -= itemdb_weight(currencyItemId) * removeAmount; + break; + } else { + items[n] += sd->status.inventory[n].amount; + removeAmount -= sd->status.inventory[n].amount; + w -= itemdb_weight(currencyItemId) * sd->status.inventory[n].amount; + } + } + if (items[n] > sd->status.inventory[n].amount) + return 14; // not enough item amount in inventory + } + if (removeAmount != 0) { + return 14; // not enough item amount in inventory + } + } + + entry->addId = shop[j].nameid; //item_avail replacement + + npc_market_qty[i] = j; + + if (!itemdb->isstackable(entry->addId) && entry->addAmount > 1) { + //Exploit? You can't buy more than 1 of equipment types o.O + ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of non-stackable item %d!\n", + sd->status.name, sd->status.account_id, sd->status.char_id, entry->addAmount, entry->addId); + entry->addAmount = 1; + } + + switch (pc->checkadditem(sd, entry->addId, entry->addAmount)) { + case ADDITEM_EXIST: + break; + case ADDITEM_NEW: + new_++; + break; + case ADDITEM_OVERAMOUNT: /* TODO find official response for this */ + return 1; + } + + z += (int64)shop[j].value * entry->addAmount; + w += itemdb_weight(entry->addId) * entry->addAmount; + } + + if (z > sd->status.zeny) + return 3; // Not enough Zeny + + if ((int64)w + sd->weight > sd->max_weight) + return 2; // Too heavy + + if (pc->inventoryblank(sd) < new_) + return 3; // Not enough space to store items + + for (int i = 0; i < sd->status.inventorySize; ++i) { + const int removeAmountTotal = items[i]; + if (removeAmountTotal == 0) + continue; + if (pc->delitem(sd, i, removeAmountTotal, 0, DELITEM_SOLD, LOG_TYPE_NPC) != 0) { + return 11; // unknown exploit + } + } + + pc->payzeny(sd, (int)z, LOG_TYPE_NPC, NULL); + + for (int i = 0; i < VECTOR_LENGTH(*item_list); ++i) { + struct barter_itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + const int shopIdx = npc_market_qty[i]; + + if ((int)shop[shopIdx].qty != -1) { + if (entry->addAmount > (int)shop[shopIdx].qty) /* wohoo someone tampered with the packet. */ + return 14; + shop[shopIdx].qty -= entry->addAmount; + } + + npc->expanded_barter_tosql(nd, shopIdx); + + if (itemdb_type(entry->addId) == IT_PETEGG) { + pet->create_egg(sd, entry->addId); + } else { + struct item item_tmp; + memset(&item_tmp, 0, sizeof(item_tmp)); + item_tmp.nameid = entry->addId; + item_tmp.identify = 1; + pc->additem(sd, &item_tmp, entry->addAmount, LOG_TYPE_NPC); + } + } + + return 12; +} + /// npc_selllist for script-controlled shops static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_list, struct npc_data *nd) { @@ -2601,121 +2935,193 @@ static int npc_unload_ev_label(union DBKey key, struct DBData *data, va_list ap) return 0; } -//Chk if npc matches src_id, then unload. -//Sub-function used to find duplicates. +/** + * Unloads a NPC if it's a duplicate of the passed one. + * + * @param nd The NPC to check. + * @param args List of arguments. + * @return Always 0. + * + **/ static int npc_unload_dup_sub(struct npc_data *nd, va_list args) { - int src_id; - nullpo_ret(nd); - src_id = va_arg(args, int); + + const int src_id = va_arg(args, int); + const int unload_mobs = va_arg(args, int); + if (nd->src_id == src_id) - npc->unload(nd, true); + npc->unload(nd, true, (unload_mobs == 1)); + return 0; } -//Removes all npcs that are duplicates of the passed one. [Skotlex] -static void npc_unload_duplicates(struct npc_data *nd) +/** + * Unloads all NPCs which are duplicates of the passed one. + * + * @param nd The source NPC. + * @param unload_mobs If true, mobs spawned by duplicates will be removed. + * + * @author Skotlex + * + **/ +static void npc_unload_duplicates(struct npc_data *nd, bool unload_mobs) { nullpo_retv(nd); - map->foreachnpc(npc->unload_dup_sub,nd->bl.id); + + map->foreachnpc(npc->unload_dup_sub, nd->bl.id, unload_mobs); } -//Removes an npc from map and db. -//Single is to free name (for duplicates). -static int npc_unload(struct npc_data *nd, bool single) +/** + * Removes a mob, which was spawned by a NPC (monster/areamonster/guardian/bg_monster/atcommand("@monster xy")). + * + * @param md The mob to remove. + * @param args List of arguments. + * @return 1 on success, 0 on failure. + * + * @author Kenpachi + * + **/ +static int npc_unload_mob(struct mob_data *md, va_list args) +{ + nullpo_ret(md); + + const int npc_id = va_arg(args, int); + + if (md->npc_id == npc_id) { + md->state.npc_killmonster = 1; + status_kill(&md->bl); + return 1; + } + + return 0; +} + +/** + * Removes a NPC from map and database. + * + * @param nd The NPC which should be removed. + * @param single If true, names are freed. (For duplicates.) + * @param unload_mobs If true, mobs spawned by the NPC will be removed. + * @return Always 0. + * + **/ +static int npc_unload(struct npc_data *nd, bool single, bool unload_mobs) { nullpo_ret(nd); - if( nd->ud && nd->ud != &npc->base_ud ) { + if (nd->ud != NULL && nd->ud != &npc->base_ud) skill->clear_unitgroup(&nd->bl); - } npc->remove_map(nd); map->deliddb(&nd->bl); - if( single ) + + if (single) strdb_remove(npc->name_db, nd->exname); - if (nd->chat_id) // remove npc chatroom object and kick users + if (nd->chat_id != 0) /// Remove NPC chatroom object and kick users. chat->delete_npc_chat(nd); - npc_chat->finalize(nd); // deallocate npc PCRE data structures + npc_chat->finalize(nd); /// Deallocate NPC PCRE data structures. if (single && nd->path != NULL) { npc->releasepathreference(nd->path); nd->path = NULL; } - if (single && nd->bl.m != -1) + if (single && nd->bl.m != INDEX_NOT_FOUND) map->remove_questinfo(nd->bl.m, nd); + npc->questinfo_clear(nd); - if (nd->src_id == 0 && ( nd->subtype == SHOP || nd->subtype == CASHSHOP)) { - //src check for duplicate shops [Orcao] - aFree(nd->u.shop.shop_item); + if (nd->src_id == 0 && (nd->subtype == SHOP || nd->subtype == CASHSHOP)) { + aFree(nd->u.shop.shop_item); /// src check for duplicate shops. [Orcao] } else if (nd->subtype == SCRIPT) { - struct s_mapiterator *iter; - struct map_session_data *sd = NULL; + char evname[EVENT_NAME_LENGTH]; + + snprintf(evname, ARRAYLENGTH(evname), "%s::OnNPCUnload", nd->exname); + + struct event_data *ev = strdb_get(npc->ev_db, evname); + + if (ev != NULL) + script->run_npc(nd->u.scr.script, ev->pos, 0, nd->bl.id); /// Run OnNPCUnload. - if( single ) { - npc->ev_db->foreach(npc->ev_db,npc->unload_ev,nd->exname); //Clean up all events related - npc->ev_label_db->foreach(npc->ev_label_db,npc->unload_ev_label,nd); + if (single) { + npc->ev_db->foreach(npc->ev_db, npc->unload_ev, nd->exname); /// Clean up all related events. + npc->ev_label_db->foreach(npc->ev_label_db, npc->unload_ev_label, nd); } - iter = mapit_geteachpc(); - for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { - if (sd->npc_timer_id != INVALID_TIMER ) { + struct s_mapiterator *iter = mapit_geteachpc(); + struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); + + for (; mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { + if (sd->npc_timer_id != INVALID_TIMER) { const struct TimerData *td = timer->get(sd->npc_timer_id); - if( td && td->id != nd->bl.id ) + if (td != NULL && td->id != nd->bl.id) continue; - if( td && td->data ) + if (td != NULL && td->data != 0) ers_free(npc->timer_event_ers, (void*)td->data); + timer->delete(sd->npc_timer_id, npc->timerevent); sd->npc_timer_id = INVALID_TIMER; } } + mapit->free(iter); if (nd->u.scr.timerid != INVALID_TIMER) { - const struct TimerData *td; - td = timer->get(nd->u.scr.timerid); - if (td && td->data) + const struct TimerData *td = timer->get(nd->u.scr.timerid); + + if (td != NULL && td->data != 0) ers_free(npc->timer_event_ers, (void*)td->data); + timer->delete(nd->u.scr.timerid, npc->timerevent); } - if (nd->u.scr.timer_event) + + if (nd->u.scr.timer_event != NULL) aFree(nd->u.scr.timer_event); + if (nd->src_id == 0) { - if(nd->u.scr.script) { + if (nd->u.scr.script != NULL) { script->free_code(nd->u.scr.script); nd->u.scr.script = NULL; } - if (nd->u.scr.label_list) { + + if (nd->u.scr.label_list != NULL) { aFree(nd->u.scr.label_list); nd->u.scr.label_list = NULL; nd->u.scr.label_list_num = 0; } - if(nd->u.scr.shop) { - if(nd->u.scr.shop->item) + + if (nd->u.scr.shop != NULL) { + if (nd->u.scr.shop->item != NULL) { + for (int i = 0; i < nd->u.scr.shop->items; i ++) { + if (nd->u.scr.shop->item[i].currency != NULL) + aFree(nd->u.scr.shop->item[i].currency); + } aFree(nd->u.scr.shop->item); + } + aFree(nd->u.scr.shop); } } - if( nd->u.scr.guild_id ) + + if (nd->u.scr.guild_id > 0) guild->flag_remove(nd); } - if( nd->ud && nd->ud != &npc->base_ud ) { + if (nd->ud != NULL && nd->ud != &npc->base_ud) { aFree(nd->ud); nd->ud = NULL; } - HPM->data_store_destroy(&nd->hdata); + if (unload_mobs) + map->foreachmob(npc->unload_mob, nd->bl.id); + HPM->data_store_destroy(&nd->hdata); aFree(nd); - return 0; } @@ -4092,18 +4498,23 @@ static const char *npc_parse_function(const char *w1, const char *w2, const char return end; } -/*========================================== - * Parse Mob 1 - Parse mob list into each map - * Parse Mob 2 - Actually Spawns Mob - * [Wizputer] - *------------------------------------------*/ +/** + * Spawns a mob by using the passed spawn data. (Permanent mob spawns.) + * npc_parse_mob() - Parses mob list into each map. + * npc_parse_mob2() - Actually spawns mob. + * + * @param mobspawn The mobs spawn data. + * + * @author Wizputer + * + **/ static void npc_parse_mob2(struct spawn_data *mobspawn) { - int i; - nullpo_retv(mobspawn); - for( i = mobspawn->active; i < mobspawn->num; ++i ) { - struct mob_data* md = mob->spawn_dataset(mobspawn); + + for (int i = mobspawn->active; i < mobspawn->num; ++i) { + struct mob_data *md = mob->spawn_dataset(mobspawn, 0); + md->spawn = mobspawn; md->spawn->active++; mob->spawn(md); @@ -5160,128 +5571,143 @@ static void npc_process_files(int npc_min) npc->npc_id - npc_min, npc->npc_warp, npc->npc_shop, npc->npc_script, npc->npc_mob, npc->npc_cache_mob, npc->npc_delay_mob); } -//Clear then reload npcs files +/** + * Clears and then reloads all NPC files. + * + * @return Always 0. + * + **/ static int npc_reload(void) { - int npc_new_min = npc->npc_id; - struct s_mapiterator* iter; - struct block_list* bl; - - if (map->retval == EXIT_FAILURE) - map->retval = EXIT_SUCCESS; // Clear return status in case something failed before. - - /* clear guild flag cache */ - guild->flags_clear(); + if (map->retval == EXIT_FAILURE) /// Clear return status in case something failed before. + map->retval = EXIT_SUCCESS; + guild->flags_clear(); /// Clear guild flag cache. npc->path_db->clear(npc->path_db, npc->path_db_clear_sub); - db_clear(npc->name_db); db_clear(npc->ev_db); npc->ev_label_db->clear(npc->ev_label_db, npc->ev_label_db_clear_sub); - npc->npc_last_npd = NULL; npc->npc_last_path = NULL; npc->npc_last_ref = NULL; + + const int npc_new_min = npc->npc_id; + struct s_mapiterator *iter = mapit_geteachiddb(); - //Remove all npcs/mobs. [Skotlex] - iter = mapit_geteachiddb(); - for (bl = mapit->first(iter); mapit->exists(iter); bl = mapit->next(iter)) { - switch(bl->type) { - case BL_NPC: - if( bl->id != npc->fake_nd->bl.id )// don't remove fake_nd - npc->unload(BL_UCAST(BL_NPC, bl), false); - break; - case BL_MOB: - unit->free(bl,CLR_OUTSIGHT); - break; + /** Remove all NPCs/mobs. [Skotlex] **/ + for (struct block_list *bl = mapit->first(iter); mapit->exists(iter); bl = mapit->next(iter)) { + switch (bl->type) { + case BL_NPC: + if (bl->id != npc->fake_nd->bl.id) /// Don't remove fake_nd. + npc->unload(BL_UCAST(BL_NPC, bl), false, false); + + break; + case BL_MOB: + unit->free(bl, CLR_OUTSIGHT); + break; + default: + break; } } + mapit->free(iter); - if(battle_config.dynamic_mobs) {// dynamic check by [random] - int16 m; - for (m = 0; m < map->count; m++) { - int16 i; - for (i = 0; i < MAX_MOB_LIST_PER_MAP; i++) { + if (battle_config.dynamic_mobs) { /// Dynamic check. [random] + for (int m = 0; m < map->count; m++) { + for (int i = 0; i < MAX_MOB_LIST_PER_MAP; i++) { if (map->list[m].moblist[i] != NULL) { aFree(map->list[m].moblist[i]); map->list[m].moblist[i] = NULL; } - if( map->list[m].mob_delete_timer != INVALID_TIMER ) - { // Mobs were removed anyway,so delete the timer [Inkfish] + + if (map->list[m].mob_delete_timer != INVALID_TIMER) { /// Mobs were removed anyway, so delete the timer. [Inkfish] timer->delete(map->list[m].mob_delete_timer, map->removemobs_timer); map->list[m].mob_delete_timer = INVALID_TIMER; } } + if (map->list[m].npc_num > 0) - ShowWarning("npc_reload: %d npcs weren't removed at map %s!\n", map->list[m].npc_num, map->list[m].name); + ShowWarning("npc_reload: %d NPCs weren't removed from map %s!\n", + map->list[m].npc_num, map->list[m].name); } } - // clear mob spawn lookup index mob->clear_spawninfo(); - - npc->npc_warp = npc->npc_shop = npc->npc_script = 0; - npc->npc_mob = npc->npc_cache_mob = npc->npc_delay_mob = 0; - - // reset mapflags + npc->npc_warp = 0; + npc->npc_shop = 0; + npc->npc_script = 0; + npc->npc_mob = 0; + npc->npc_cache_mob = 0; + npc->npc_delay_mob = 0; map->zone_reload(); map->flags_init(); - - // Reprocess npc files and reload constants itemdb->name_constants(); clan->set_constants(); - npc_process_files( npc_new_min ); - + npc_process_files(npc_new_min); instance->reload(); - map->zone_init(); - - npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */ - - //Re-read the NPC Script Events cache. + npc->motd = npc->name2id("HerculesMOTD"); /// [Ind/Hercules] npc->read_event_script(); - // Execute main initialisation events - // The correct initialisation order is: - // OnInit -> OnInterIfInit -> OnInterIfInitOnce -> OnAgitInit -> OnAgitInit2 - npc->event_do_oninit( true ); + /** + * Execute main initialization events + * The correct initialization order is: + * OnInit -> OnInterIfInit -> OnInterIfInitOnce -> OnAgitInit -> OnAgitInit2 + * + **/ + npc->event_do_oninit(true); + npc->market_fromsql(); npc->barter_fromsql(); - // Execute rest of the startup events if connected to char-server. [Lance] - // Executed when connection is established with char-server in chrif_connectack - if( !intif->CheckForCharServer() ) { - ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInit")); - ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInitOnce")); - } - // Refresh guild castle flags on both woe setups - // These events are only executed after receiving castle information from char-server + npc->expanded_barter_fromsql(); + + /* + * Execute rest of the startup events if connected to char-server. [Lance] + * Executed when connection is established with char-server in chrif_connectack(). + */ + if (intif->CheckForCharServer() == 0) { + ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", + npc->event_doall("OnInterIfInit")); + ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", + npc->event_doall("OnInterIfInitOnce")); + } + + /* + * Refresh guild castle flags on both WoE setups. + * These events are only executed after receiving castle information from char-server. + */ npc->event_doall("OnAgitInit"); npc->event_doall("OnAgitInit2"); return 0; } -//Unload all npc in the given file -static bool npc_unloadfile(const char *filepath) +/** + * Unloads all NPCs in the given file. + * + * @param filepath Path to the file which should be unloaded. + * @param unload_mobs If true, mobs spawned by NPCs in the file will be removed. + * @return true if at least one NPC was unloaded, otherwise false. + * + **/ +static bool npc_unloadfile(const char *filepath, bool unload_mobs) { + nullpo_retr(false, filepath); + struct DBIterator *iter = db_iterator(npc->name_db); - struct npc_data* nd = NULL; bool found = false; - nullpo_retr(false, filepath); - - for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) { - if( nd->path && strcasecmp(nd->path,filepath) == 0 ) { // FIXME: This can break in case-sensitive file systems + for (struct npc_data *nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter)) { + if (nd->path != NULL && strcasecmp(nd->path, filepath) == 0) { // FIXME: This can break in case-sensitive file systems. found = true; - npc->unload_duplicates(nd);/* unload any npcs which could duplicate this but be in a different file */ - npc->unload(nd, true); + npc->unload_duplicates(nd, unload_mobs); /// Unload any NPC which could duplicate this but be in a different file. + npc->unload(nd, true, unload_mobs); } } dbi_destroy(iter); - if( found ) /* refresh event cache */ + if (found) /// Refresh event cache. npc->read_event_script(); return found; @@ -5514,6 +5940,7 @@ void npc_defaults(void) npc->unload_ev_label = npc_unload_ev_label; npc->unload_dup_sub = npc_unload_dup_sub; npc->unload_duplicates = npc_unload_duplicates; + npc->unload_mob = npc_unload_mob; npc->unload = npc_unload; npc->clearsrcfile = npc_clearsrcfile; npc->addsrcfile = npc_addsrcfile; @@ -5567,6 +5994,7 @@ void npc_defaults(void) npc->trader_update = npc_trader_update; npc->market_buylist = npc_market_buylist; npc->barter_buylist = npc_barter_buylist; + npc->expanded_barter_buylist = npc_expanded_barter_buylist; npc->trader_open = npc_trader_open; npc->market_fromsql = npc_market_fromsql; npc->market_tosql = npc_market_tosql; @@ -5576,6 +6004,10 @@ void npc_defaults(void) npc->barter_tosql = npc_barter_tosql; npc->barter_delfromsql = npc_barter_delfromsql; npc->barter_delfromsql_sub = npc_barter_delfromsql_sub; + npc->expanded_barter_fromsql = npc_expanded_barter_fromsql; + npc->expanded_barter_tosql = npc_expanded_barter_tosql; + npc->expanded_barter_delfromsql = npc_expanded_barter_delfromsql; + npc->expanded_barter_delfromsql_sub = npc_expanded_barter_delfromsql_sub; npc->db_checkid = npc_db_checkid; npc->refresh = npc_refresh; npc->questinfo_clear = npc_questinfo_clear; diff --git a/src/map/npc.h b/src/map/npc.h index c5f44f0e0..65c9796d9 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -48,6 +48,7 @@ enum npc_shop_types { NST_MARKET, /* official npc market type */ NST_CUSTOM, NST_BARTER, /* official npc barter type */ + NST_EXPANDED_BARTER, /* official npc expanded barter type */ /* */ NST_MAX, }; @@ -60,17 +61,25 @@ struct npc_label_list { int pos; }; +struct npc_barter_currency { + int nameid; + int refine; + int amount; +}; + struct npc_item_list { int nameid; unsigned int value; // price or barter currency item id - int value2; // barter currency item amount - unsigned int qty; + int value2; // barter currency item amount / expanded barter currency size + int qty; + struct npc_barter_currency *currency; }; struct npc_shop_data { unsigned char type;/* what am i */ struct npc_item_list *item;/* list */ unsigned int items;/* total */ + int shop_last_index; // only for NST_EXPANDED_BARTER }; struct npc_parse; struct npc_data { @@ -261,8 +270,9 @@ struct npc_interface { int (*unload_ev) (union DBKey key, struct DBData *data, va_list ap); int (*unload_ev_label) (union DBKey key, struct DBData *data, va_list ap); int (*unload_dup_sub) (struct npc_data *nd, va_list args); - void (*unload_duplicates) (struct npc_data *nd); - int (*unload) (struct npc_data *nd, bool single); + void (*unload_duplicates) (struct npc_data *nd, bool unload_mobs); + int (*unload_mob) (struct mob_data *md, va_list args); + int (*unload) (struct npc_data *nd, bool single, bool unload_mobs); void (*clearsrcfile) (void); void (*addsrcfile) (const char *name); void (*delsrcfile) (const char *name); @@ -304,7 +314,7 @@ struct npc_interface { int (*path_db_clear_sub) (union DBKey key, struct DBData *data, va_list args); int (*ev_label_db_clear_sub) (union DBKey key, struct DBData *data, va_list args); int (*reload) (void); - bool (*unloadfile) (const char *filepath); + bool (*unloadfile) (const char *filepath, bool unload_mobs); void (*do_clear_npc) (void); void (*debug_warps_sub) (struct npc_data *nd); void (*debug_warps) (void); @@ -314,6 +324,7 @@ struct npc_interface { void (*trader_update) (int master); enum market_buy_result (*market_buylist) (struct map_session_data *sd, struct itemlist *item_list); int (*barter_buylist) (struct map_session_data *sd, struct barteritemlist *item_list); + int (*expanded_barter_buylist) (struct map_session_data *sd, struct barteritemlist *item_list); bool (*trader_open) (struct map_session_data *sd, struct npc_data *nd); void (*market_fromsql) (void); void (*market_tosql) (struct npc_data *nd, int index); @@ -323,6 +334,10 @@ struct npc_interface { void (*barter_tosql) (struct npc_data *nd, int index); void (*barter_delfromsql) (struct npc_data *nd, int index); void (*barter_delfromsql_sub) (const char *npcname, int itemId, int itemId2, int amount2); + void (*expanded_barter_fromsql) (void); + void (*expanded_barter_tosql) (struct npc_data *nd, int index); + void (*expanded_barter_delfromsql) (struct npc_data *nd, int index); + void (*expanded_barter_delfromsql_sub) (const char *npcname, int itemId, int zeny, int currencyCount, struct npc_barter_currency* currency); bool (*db_checkid) (const int id); void (*refresh) (struct npc_data* nd); void (*questinfo_clear) (struct npc_data *nd); diff --git a/src/map/packets.h b/src/map/packets.h index 90b9beeb7..1e6dc71bc 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -1983,6 +1983,11 @@ packet(0x96e,clif->ackmergeitems); packet(0x0b4c,clif->pCashShopLimitedReq); #endif +#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828 + packet(0x0b57,clif->pNPCExpandedBarterPurchase); + packet(0x0b58,clif->pNPCExpandedBarterClosed); +#endif + #if PACKETVER >= 20191224 packet(0x0b6d,clif->pCashShopOpen2); #endif diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h index 1d5f96ee9..a72d9bf5f 100644 --- a/src/map/packets_keys_main.h +++ b/src/map/packets_keys_main.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ packetKeys(0x49357d72,0x22c370a1,0x5f836591); #endif -// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-06bRagexeRE, 2019-11-07aRagexe, 2019-11-07aRagexeRE, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-13eRagexeRE, 2019-11-20aRagexe, 2019-11-20cRagexeRE, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27aRagexeRE, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04aRagexeRE, 2019-12-04bRagexe, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11aRagexe, 2019-12-11fRagexeRE, 2019-12-18bRagexe, 2019-12-18bRagexeRE, 2019-12-24aRagexe, 2019-12-24aRagexeRE, 2019-12-24bRagexe, 2019-12-24bRagexeRE, 2020-01-08aRagexe, 2020-01-08bRagexeRE +// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-06bRagexeRE, 2019-11-07aRagexe, 2019-11-07aRagexeRE, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-13eRagexeRE, 2019-11-20aRagexe, 2019-11-20cRagexeRE, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27aRagexeRE, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04aRagexeRE, 2019-12-04bRagexe, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11aRagexe, 2019-12-11fRagexeRE, 2019-12-18bRagexe, 2019-12-18bRagexeRE, 2019-12-24aRagexe, 2019-12-24aRagexeRE, 2019-12-24bRagexe, 2019-12-24bRagexeRE, 2020-01-08aRagexe, 2020-01-08bRagexeRE, 2020-01-22cRagexe, 2020-01-22cRagexeRE, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-05aRagexeRE, 2020-02-06aRagexe #if PACKETVER == 20101123 || \ PACKETVER == 20101124 || \ PACKETVER == 20101125 || \ @@ -181,7 +181,12 @@ PACKETVER == 20191211 || \ PACKETVER == 20191218 || \ PACKETVER == 20191224 || \ - PACKETVER >= 20200108 + PACKETVER == 20200108 || \ + PACKETVER == 20200122 || \ + PACKETVER == 20200129 || \ + PACKETVER == 20200130 || \ + PACKETVER == 20200205 || \ + PACKETVER >= 20200206 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h index d4c96beca..90d226c92 100644 --- a/src/map/packets_keys_zero.h +++ b/src/map/packets_keys_zero.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ /* This file is autogenerated, please do not commit manual changes */ -// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero +// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero #if PACKETVER == 20171018 || \ PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ @@ -103,7 +103,9 @@ PACKETVER == 20191127 || \ PACKETVER == 20191204 || \ PACKETVER == 20191211 || \ - PACKETVER >= 20191224 + PACKETVER == 20191224 || \ + PACKETVER == 20200115 || \ + PACKETVER >= 20200129 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h index 83a9107f2..2d7f1d6ec 100644 --- a/src/map/packets_shuffle_main.h +++ b/src/map/packets_shuffle_main.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -9794,7 +9794,7 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif -// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-07aRagexe, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-20aRagexe, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04bRagexe, 2019-12-11aRagexe, 2019-12-18bRagexe, 2019-12-24aRagexe, 2019-12-24bRagexe, 2020-01-08aRagexe +// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-07aRagexe, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-20aRagexe, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04bRagexe, 2019-12-11aRagexe, 2019-12-18bRagexe, 2019-12-24aRagexe, 2019-12-24bRagexe, 2020-01-08aRagexe, 2020-01-22cRagexe, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-06aRagexe #if PACKETVER == 20190904 || \ PACKETVER == 20190918 || \ PACKETVER == 20190925 || \ @@ -9812,7 +9812,12 @@ PACKETVER == 20191211 || \ PACKETVER == 20191218 || \ PACKETVER == 20191224 || \ - PACKETVER == 20200108 + PACKETVER == 20200108 || \ + PACKETVER == 20200122 || \ + PACKETVER == 20200129 || \ + PACKETVER == 20200130 || \ + PACKETVER == 20200205 || \ + PACKETVER == 20200206 packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 diff --git a/src/map/packets_shuffle_re.h b/src/map/packets_shuffle_re.h index 9c9df85ed..757cfee55 100644 --- a/src/map/packets_shuffle_re.h +++ b/src/map/packets_shuffle_re.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -9744,7 +9744,7 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif -// 2019-09-04bRagexeRE, 2019-09-18cRagexeRE, 2019-09-25aRagexeRE, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexeRE, 2019-10-16gRagexeRE, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-11-06bRagexeRE, 2019-11-07aRagexeRE, 2019-11-13eRagexeRE, 2019-11-20cRagexeRE, 2019-11-27aRagexeRE, 2019-12-04aRagexeRE, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11fRagexeRE, 2019-12-18bRagexeRE, 2019-12-24aRagexeRE, 2019-12-24bRagexeRE, 2020-01-08bRagexeRE +// 2019-09-04bRagexeRE, 2019-09-18cRagexeRE, 2019-09-25aRagexeRE, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexeRE, 2019-10-16gRagexeRE, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-11-06bRagexeRE, 2019-11-07aRagexeRE, 2019-11-13eRagexeRE, 2019-11-20cRagexeRE, 2019-11-27aRagexeRE, 2019-12-04aRagexeRE, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11fRagexeRE, 2019-12-18bRagexeRE, 2019-12-24aRagexeRE, 2019-12-24bRagexeRE, 2020-01-08bRagexeRE, 2020-01-22cRagexeRE, 2020-02-05aRagexeRE #if PACKETVER == 20190904 || \ PACKETVER == 20190918 || \ PACKETVER == 20190925 || \ @@ -9761,7 +9761,9 @@ PACKETVER == 20191211 || \ PACKETVER == 20191218 || \ PACKETVER == 20191224 || \ - PACKETVER == 20200108 + PACKETVER == 20200108 || \ + PACKETVER == 20200122 || \ + PACKETVER == 20200205 packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h index 91b0c1e89..602264a8f 100644 --- a/src/map/packets_shuffle_zero.h +++ b/src/map/packets_shuffle_zero.h @@ -2,8 +2,8 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2020 Hercules Dev Team - * Copyright (C) 2018-2020 Andrei Karas (4144) + * Copyright (C) 2013-2020 Hercules Dev Team + * Copyright (C) 2018-2020 Andrei Karas (4144) * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -803,7 +803,7 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif -// 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero +// 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero #if PACKETVER == 20190828 || \ PACKETVER == 20190911 || \ PACKETVER == 20190918 || \ @@ -815,7 +815,9 @@ PACKETVER == 20191127 || \ PACKETVER == 20191204 || \ PACKETVER == 20191211 || \ - PACKETVER == 20191224 + PACKETVER == 20191224 || \ + PACKETVER == 20200115 || \ + PACKETVER == 20200129 packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 0fa602ba5..31b28e831 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -3770,7 +3770,7 @@ struct PACKET_CZ_SE_CASHSHOP_LIMITED_REQ { DEFINE_PACKET_HEADER(CZ_SE_CASHSHOP_LIMITED_REQ, 0x0b4c); #endif -#if PACKETVER_ZERO_NUM >= 20191224 +#if PACKETVER_MAIN_NUM >= 20200129 || PACKETVER_RE_NUM >= 20200205 || PACKETVER_ZERO_NUM >= 20191224 struct PACKET_ZC_SE_CASHSHOP_OPEN { int16 packetType; uint32 cashPoints; @@ -3788,6 +3788,91 @@ struct PACKET_ZC_SE_CASHSHOP_OPEN { DEFINE_PACKET_HEADER(ZC_SE_CASHSHOP_OPEN, 0x0845); #endif +#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828 +struct PACKET_CZ_NPC_EXPANDED_BARTER_CLOSE { + int16 packetType; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_CLOSE, 0x0b58); +#endif + +#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127 +struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 { +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + uint32 nameid; +#else + uint16 nameid; +#endif + uint16 refine_level; + uint32 amount; + uint16 type; +} __attribute__((packed)); + +struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub { +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + uint32 nameid; +#else + uint16 nameid; +#endif + uint16 type; + uint32 amount; + uint32 weight; + uint32 index; + uint32 zeny; + uint32 currency_count; + struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 currencies[]; +} __attribute__((packed)); + +struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN { + int16 packetType; + int16 packetLength; + int32 items_count; + struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub items[]; +} __attribute__((packed)); + +DEFINE_PACKET_HEADER(ZC_NPC_EXPANDED_BARTER_OPEN, 0x0b56); +#endif + +#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828 +struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub { +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + uint32 itemId; +#else + uint16 itemId; +#endif + uint32 shopIndex; + uint32 amount; +} __attribute__((packed)); + +struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE { + int16 packetType; + int16 packetLength; + struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub list[]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_PURCHASE, 0x0b57); +#endif + +#if PACKETVER >= 7 +struct PACKET_ZC_STATE_CHANGE { + int16 packetType; + uint32 AID; + int16 bodyState; + int16 healthState; + int32 effectState; + int8 isPKModeON; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_STATE_CHANGE, 0x0229); +#else +struct PACKET_ZC_STATE_CHANGE { + int16 PacketType; + uint32 AID; + int16 bodyState; + int16 healthState; + int16 effectState; + int8 isPKModeON; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_STATE_CHANGE, 0x0119); +#endif + #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) #endif // not NetBSD < 6 / Solaris diff --git a/src/map/pc.c b/src/map/pc.c index c4f9d8be0..9d2816f3d 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -9345,15 +9345,23 @@ static void pc_setridingpeco(struct map_session_data *sd, bool flag) * * @param sd Target player. * @param flag New state. + * @param mtype Type of the mado gear. **/ -static void pc_setmadogear(struct map_session_data *sd, bool flag) +static void pc_setmadogear(struct map_session_data *sd, bool flag, enum mado_type mtype) { nullpo_retv(sd); + Assert_retv(mtype >= MADO_ROBOT && mtype < MADO_MAX); + if (flag) { - if ((sd->job & MAPID_THIRDMASK) == MAPID_MECHANIC) + if ((sd->job & MAPID_THIRDMASK) == MAPID_MECHANIC) { pc->setoption(sd, sd->sc.option|OPTION_MADOGEAR); +#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 + sc_start(&sd->bl, &sd->bl, SC_MADOGEAR, 100, (int)mtype, INFINITE_DURATION); +#endif + } } else if (pc_ismadogear(sd)) { pc->setoption(sd, sd->sc.option&~OPTION_MADOGEAR); + // pc->setoption resets status effects when changing mado, no need to re do it here. } } diff --git a/src/map/pc.h b/src/map/pc.h index f4f0044a9..a3a3ee48d 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1037,7 +1037,7 @@ END_ZEROED_BLOCK; /* End */ int (*setcart) (struct map_session_data* sd, int type); void (*setfalcon) (struct map_session_data *sd, bool flag); void (*setridingpeco) (struct map_session_data *sd, bool flag); - void (*setmadogear) (struct map_session_data *sd, bool flag); + void (*setmadogear) (struct map_session_data *sd, bool flag, enum mado_type mtype); void (*setridingdragon) (struct map_session_data *sd, unsigned int type); void (*setridingwug) (struct map_session_data *sd, bool flag); int (*changelook) (struct map_session_data *sd,int type,int val); diff --git a/src/map/script.c b/src/map/script.c index 26bd678fe..b77e6a376 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10694,6 +10694,7 @@ static BUILDIN(checkmount) /** * Mounts or dismounts a combat mount. * + * setmount <flag>, <mtype>; * setmount <flag>; * setmount; * @@ -10712,6 +10713,8 @@ static BUILDIN(checkmount) * If an invalid value or no flag is specified, the appropriate mount is * auto-detected. As a result of this, there is no need to specify a flag at * all, unless it is a dragon color other than green. + * + * In newer clients you can specify the mado gear type though the mtype argument. */ static BUILDIN(setmount) { @@ -10724,6 +10727,12 @@ static BUILDIN(setmount) if (script_hasdata(st,2)) flag = script_getnum(st,2); + enum mado_type mtype = script_hasdata(st, 3) ? script_getnum(st, 3) : MADO_ROBOT; + if (mtype < MADO_ROBOT || mtype >= MADO_MAX) { + ShowError("script_setmount: Invalid mado type has been passed (%d).\n", flag); + return false; + } + // Color variants for Rune Knight dragon mounts. if (flag != SETMOUNT_TYPE_NONE) { if (flag < SETMOUNT_TYPE_AUTODETECT || flag >= SETMOUNT_TYPE_MAX) { @@ -10750,7 +10759,7 @@ static BUILDIN(setmount) } else if ((sd->job & MAPID_THIRDMASK) == MAPID_MECHANIC) { // Mechanic (Mado Gear) if (pc->checkskill(sd, NC_MADOLICENCE)) - pc->setmadogear(sd, true); + pc->setmadogear(sd, true, mtype); } else { // Knight / Crusader (Peco Peco) if (pc->checkskill(sd, KN_RIDING)) @@ -10764,7 +10773,7 @@ static BUILDIN(setmount) pc->setridingwug(sd, false); } if (pc_ismadogear(sd)) { - pc->setmadogear(sd, false); + pc->setmadogear(sd, false, mtype); } if (pc_isridingpeco(sd)) { pc->setridingpeco(sd, false); @@ -11775,6 +11784,13 @@ static BUILDIN(getunits) const char *mapname = script_getstr(st, 5); int16 m = map->mapname2mapid(mapname); + if (m == -1) { + ShowError("script:getunits: Invalid map(%s) provided.\n", mapname); + script->reportdata(data); + st->state = END; + return false; + } + if (script_hasdata(st, 9)) { int16 x1 = script_getnum(st, 6); int16 y1 = script_getnum(st, 7); @@ -12489,6 +12505,56 @@ static BUILDIN(hideonnpc) npc->enable(str,4); return true; } +/*========================================== + *------------------------------------------*/ +static BUILDIN(cloakonnpc) +{ + struct npc_data *nd = npc->name2id(script_getstr(st, 2)); + if (nd == NULL) { + ShowError("buildin_cloakonnpc: invalid npc name '%s'.\n", script_getstr(st, 2)); + return false; + } + + if (script_hasdata(st, 3)) { + struct map_session_data *sd = map->id2sd(script_getnum(st, 3)); + if (sd == NULL) + return false; + + uint32 val = nd->option; + nd->option |= OPTION_CLOAK; + clif->changeoption_target(&nd->bl, &sd->bl, SELF); + nd->option = val; + } else { + nd->option |= OPTION_CLOAK; + clif->changeoption(&nd->bl); + } + return true; +} +/*========================================== + *------------------------------------------*/ +static BUILDIN(cloakoffnpc) +{ + struct npc_data *nd = npc->name2id(script_getstr(st, 2)); + if (nd == NULL) { + ShowError("buildin_cloakoffnpc: invalid npc name '%s'.\n", script_getstr(st, 2)); + return false; + } + + if (script_hasdata(st, 3)) { + struct map_session_data *sd = map->id2sd(script_getnum(st, 3)); + if (sd == NULL) + return false; + + uint32 val = nd->option; + nd->option &= ~OPTION_CLOAK; + clif->changeoption_target(&nd->bl, &sd->bl, SELF); + nd->option = val; + } else { + nd->option &= ~OPTION_CLOAK; + clif->changeoption(&nd->bl); + } + return true; +} /* Starts a status effect on the target unit or on the attached player. * @@ -14526,47 +14592,53 @@ static BUILDIN(strmobinfo) return true; } -/*========================================== - * Summon guardians [Valaris] - * guardian("<map name>",<x>,<y>,"<name to show>",<mob id>{,"<event label>"}{,<guardian index>}) -> <id> - *------------------------------------------*/ +/** + * Summons a castle guardian mob. + * + * @code{.herc} + * guardian("<map name>", <x>, <y>, "<name to show>", <mob id>{, <guardian index>}); + * guardian("<map name>", <x>, <y>, "<name to show>", <mob id>{, "<event label>"{, <guardian index>}}); + * @endcode + * + * @author Valaris + * + **/ static BUILDIN(guardian) { - int class_ = 0, x = 0, y = 0, guardian = 0; - const char *str, *mapname, *evt=""; bool has_index = false; + int guardian = 0; + const char *event = ""; - mapname = script_getstr(st,2); - x = script_getnum(st,3); - y = script_getnum(st,4); - str = script_getstr(st,5); - class_ = script_getnum(st,6); - - if( script_hasdata(st,8) ) - {// "<event label>",<guardian index> - evt=script_getstr(st,7); - guardian=script_getnum(st,8); + if (script_hasdata(st, 8)) { /// "<event label>", <guardian index> + event = script_getstr(st, 7); + script->check_event(st, event); + guardian = script_getnum(st, 8); has_index = true; - } else if( script_hasdata(st,7) ) { - struct script_data *data = script_getdata(st,7); - script->get_val(st,data); // Dereference if it's a variable - if( data_isstring(data) ) { - // "<event label>" - evt=script_getstr(st,7); - } else if( data_isint(data) ) { - // <guardian index> - guardian=script_getnum(st,7); + } else if (script_hasdata(st, 7)) { + struct script_data *data = script_getdata(st, 7); + + script->get_val(st, data); /// Dereference if it's a variable. + + if (data_isstring(data)) { /// "<event label>" + event = script_getstr(st, 7); + script->check_event(st, event); + } else if (data_isint(data)) { /// <guardian index> + guardian = script_getnum(st, 7); has_index = true; } else { - ShowError("script:guardian: invalid data type for argument #6 (from 1)\n"); + ShowError("script:guardian: Invalid data type for argument #6!\n"); script->reportdata(data); return false; } } - script->check_event(st, evt); - script_pushint(st, mob->spawn_guardian(mapname,x,y,str,class_,evt,guardian,has_index)); + const char *mapname = script_getstr(st, 2); + const char *name = script_getstr(st, 5); + const int x = script_getnum(st, 3); + const int y = script_getnum(st, 4); + const int mob_id = script_getnum(st, 6); + script_pushint(st, mob->spawn_guardian(mapname, x, y, name, mob_id, event, guardian, has_index, st->oid)); return true; } /*========================================== @@ -16894,38 +16966,54 @@ static BUILDIN(logmes) return true; } +/** + * Summons a mob which will act as a slave for the invoking character. + * + * @code{.herc} + * summon("mob name", <mob id>{, <timeout>{, "event label"}}); + * @endcode + * + * @author Celest + * + **/ static BUILDIN(summon) { - int class_, timeout=0; - const char *str,*event=""; - struct mob_data *md; - int64 tick = timer->gettick(); struct map_session_data *sd = script->rid2sd(st); + if (sd == NULL) return true; - str = script_getstr(st,2); - class_ = script_getnum(st,3); - if( script_hasdata(st,4) ) - timeout=script_getnum(st,4); - if( script_hasdata(st,5) ) { - event=script_getstr(st,5); + const int64 tick = timer->gettick(); + + clif->skill_poseffect(&sd->bl, AM_CALLHOMUN, 1, sd->bl.x, sd->bl.y, tick); + + const char *event = ""; + + if (script_hasdata(st, 5)) { + event = script_getstr(st, 5); script->check_event(st, event); } - clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick); + const char *name = script_getstr(st, 2); + const int mob_id = script_getnum(st, 3); + struct mob_data *md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, name, mob_id, event, + SZ_SMALL, AI_NONE, 0); - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, class_, event, SZ_SMALL, AI_NONE); - if (md) { - md->master_id=sd->bl.id; + if (md != NULL) { + md->master_id = sd->bl.id; md->special_state.ai = AI_ATTACK; - if( md->deletetimer != INVALID_TIMER ) + + if (md->deletetimer != INVALID_TIMER) timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add(tick+(timeout>0?timeout*1000:60000),mob->timer_delete,md->bl.id,0); - mob->spawn (md); //Now it is ready for spawning. - clif->specialeffect(&md->bl,344,AREA); + + const int timeout = script_hasdata(st, 4) ? script_getnum(st, 4) * 1000 : 60000; + + md->deletetimer = timer->add(tick + ((timeout == 0) ? 60000 : timeout), mob->timer_delete, md->bl.id, 0); + mob->spawn(md); + clif->specialeffect(&md->bl, 344, AREA); sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); } + return true; } @@ -22219,6 +22307,23 @@ static BUILDIN(achievement_progress) return true; } +static BUILDIN(achievement_iscompleted) +{ + struct map_session_data *sd = script_hasdata(st, 3) ? map->id2sd(script_getnum(st, 3)) : script->rid2sd(st); + if (sd == NULL) + return false; + + int aid = script_getnum(st, 2); + const struct achievement_data *ad = achievement->get(aid); + if (ad == NULL) { + ShowError("buildin_achievement_iscompleted: Invalid Achievement %d provided.\n", aid); + return false; + } + + script_pushint(st, achievement->check_complete(sd, ad)); + return true; +} + /*========================================== * BattleGround System *------------------------------------------*/ @@ -22340,20 +22445,31 @@ static BUILDIN(bg_warp) return true; } +/** + * Spawns a mob with allegiance to the given battle group. + * + * @code{.herc} + * bg_monster(<battle group>, "<map name>", <x>, <y>, "<name to show>", <mob id>{, "<event label>"}); + * @endcode + * + **/ static BUILDIN(bg_monster) { - int class_ = 0, x = 0, y = 0, bg_id = 0; - const char *str, *mapname, *evt=""; + const char *event = ""; - bg_id = script_getnum(st,2); - mapname = script_getstr(st,3); - x = script_getnum(st,4); - y = script_getnum(st,5); - str = script_getstr(st,6); - class_ = script_getnum(st,7); - if( script_hasdata(st,8) ) evt = script_getstr(st,8); - script->check_event(st, evt); - script_pushint(st, mob->spawn_bg(mapname,x,y,str,class_,evt,bg_id)); + if (script_hasdata(st, 8)) { + event = script_getstr(st, 8); + script->check_event(st, event); + } + + const char *mapname = script_getstr(st, 3); + const char *name = script_getstr(st, 6); + const int bg_id = script_getnum(st, 2); + const int x = script_getnum(st, 4); + const int y = script_getnum(st, 5); + const int mob_id = script_getnum(st, 7); + + script_pushint(st, mob->spawn_bg(mapname, x, y, name, mob_id, event, bg_id, st->oid)); return true; } @@ -24677,6 +24793,133 @@ static BUILDIN(openshop) return true; } +static bool script_sellitemcurrency_add(struct npc_data *nd, struct script_state* st, int argIndex) +{ + nullpo_retr(false, nd); + nullpo_retr(false, st); + + if (!script_hasdata(st, argIndex + 1)) + return false; + + int id = script_getnum(st, argIndex); + struct item_data *it; + if (!(it = itemdb->exists(id))) { + ShowWarning("buildin_sellitemcurrency: unknown item id '%d'!\n", id); + return false; + } + int qty = 0; + if ((qty = script_getnum(st, argIndex + 1)) <= 0) { + ShowError("buildin_sellitemcurrency: invalid 'qty'!\n"); + return false; + } + int refine_level = -1; + if (script_hasdata(st, argIndex + 2)) { + refine_level = script_getnum(st, argIndex + 2); + } + int items = nd->u.scr.shop->items; + if (nd->u.scr.shop == NULL || items == 0) { + ShowWarning("buildin_sellitemcurrency: shop not have items!\n"); + return false; + } + if (nd->u.scr.shop->shop_last_index >= items || nd->u.scr.shop->shop_last_index < 0) { + ShowWarning("buildin_sellitemcurrency: wrong selected shop index!\n"); + return false; + } + + struct npc_item_list *item_list = &nd->u.scr.shop->item[nd->u.scr.shop->shop_last_index]; + int index = item_list->value2; + if (item_list->currency == NULL) { + CREATE(item_list->currency, struct npc_barter_currency, 1); + item_list->value2 ++; + } else { + RECREATE(item_list->currency, struct npc_barter_currency, ++item_list->value2); + } + struct npc_barter_currency *currency = &item_list->currency[index]; + currency->nameid = id; + currency->refine = refine_level; + currency->amount = qty; + return true; +} + +/** + * @call sellitemcurrency <Item_ID>,qty{,refine}}; + * + * adds <Item_ID> to last item in expanded barter shop + **/ +static BUILDIN(sellitemcurrency) +{ + struct npc_data *nd; + if ((nd = map->id2nd(st->oid)) == NULL) { + ShowWarning("buildin_sellitemcurrency: trying to run without a proper NPC!\n"); + return false; + } + if (nd->u.scr.shop == NULL || nd->u.scr.shop->type != NST_EXPANDED_BARTER) { + ShowWarning("buildin_sellitemcurrency: this command can be used only with expanded barter shops!\n"); + return false; + } + + script->sellitemcurrency_add(nd, st, 2); + return true; +} + +/** + * @call endsellitem; + * + * complete sell item in expanded barter shop (NST_EXPANDED_BARTER) + **/ +static BUILDIN(endsellitem) +{ + struct npc_data *nd; + if ((nd = map->id2nd(st->oid)) == NULL) { + ShowWarning("buildin_endsellitem: trying to run without a proper NPC!\n"); + return false; + } + if (nd->u.scr.shop == NULL || nd->u.scr.shop->type != NST_EXPANDED_BARTER) { + ShowWarning("buildin_endsellitem: this command can be used only with expanded barter shops!\n"); + return false; + } + + int newIndex = nd->u.scr.shop->shop_last_index; + const struct npc_item_list *const newItem = &nd->u.scr.shop->item[newIndex]; + int i = 0; + for (i = 0; i < nd->u.scr.shop->items - 1; i++) { + const struct npc_item_list *const item = &nd->u.scr.shop->item[i]; + if (item->nameid != newItem->nameid || item->value != newItem->value) + continue; + if (item->value2 != newItem->value2) + continue; + bool found = true; + for (int k = 0; k < item->value2; k ++) { + struct npc_barter_currency *currency = &item->currency[k]; + struct npc_barter_currency *newCurrency = &newItem->currency[k]; + if (currency->nameid != newCurrency->nameid || + currency->amount != newCurrency->amount || + currency->refine != newCurrency->refine) { + found = false; + break; + } + } + if (!found) + continue; + break; + } + + if (i != nd->u.scr.shop->items - 1) { + if (nd->u.scr.shop->item[i].qty != -1) { + nd->u.scr.shop->item[i].qty += nd->u.scr.shop->item[newIndex].qty; + npc->expanded_barter_tosql(nd, i); + } + nd->u.scr.shop->shop_last_index --; + nd->u.scr.shop->items--; + if (nd->u.scr.shop->item[newIndex].currency != NULL) { + aFree(nd->u.scr.shop->item[newIndex].currency); + nd->u.scr.shop->item[newIndex].currency = NULL; + } + } + + return true; +} + /** * @call sellitem <Item_ID>,{,price{,qty}}; * @@ -24700,30 +24943,65 @@ static BUILDIN(sellitem) return false; } - if (!nd->u.scr.shop) { + const bool have_shop = (nd->u.scr.shop != NULL); + if (!have_shop) { npc->trader_update(nd->src_id ? nd->src_id : nd->bl.id); - if (nd->u.scr.shop->type == NST_BARTER) { - if (!script_hasdata(st, 5)) { - ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n"); - return false; - } - value = script_getnum(st, 4); - value2 = script_getnum(st, 5); + } + + if (nd->u.scr.shop->type != NST_BARTER) { + value = script_hasdata(st, 3) ? script_getnum(st, 3) : it->value_buy; + if (value == -1) + value = it->value_buy; + } + + if (nd->u.scr.shop->type == NST_BARTER) { + if (!script_hasdata(st, 5)) { + ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n"); + return false; + } + value = script_getnum(st, 4); + value2 = script_getnum(st, 5); + } else if (nd->u.scr.shop->type == NST_EXPANDED_BARTER) { + if (!script_hasdata(st, 4)) { + ShowError("buildin_sellitem: invalid number of parameters for expanded barter type shop!\n"); + return false; } - } else {/* no need to run this if its empty */ + if ((qty = script_getnum(st, 4)) <= 0 && qty != -1) { + ShowError("buildin_sellitem: invalid 'qty' for expanded barter type shop!\n"); + return false; + } + } + + if (have_shop) { if (nd->u.scr.shop->type == NST_BARTER) { - if (!script_hasdata(st, 5)) { - ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n"); - return false; - } - value = script_getnum(st, 4); - value2 = script_getnum(st, 5); for (i = 0; i < nd->u.scr.shop->items; i++) { const struct npc_item_list *const item = &nd->u.scr.shop->item[i]; if (item->nameid == id && item->value == value && item->value2 == value2) { break; } } + } else if (nd->u.scr.shop->type == NST_EXPANDED_BARTER) { + for (i = 0; i < nd->u.scr.shop->items; i++) { + const struct npc_item_list *const item = &nd->u.scr.shop->item[i]; + if (item->nameid != id || item->value != value) + continue; + if (item->value2 != (script_lastdata(st) - 4) / 3) + continue; + bool found = true; + for (int k = 0; k < item->value2; k ++) { + const int scriptOffset = k * 3 + 5; + struct npc_barter_currency *currency = &item->currency[k]; + if (currency->nameid != script_getnum(st, scriptOffset) || + currency->amount != script_getnum(st, scriptOffset + 1) || + currency->refine != script_getnum(st, scriptOffset + 2)) { + found = false; + break; + } + } + if (!found) + continue; + break; + } } else { for (i = 0; i < nd->u.scr.shop->items; i++) { if (nd->u.scr.shop->item[i].nameid == id) { @@ -24733,12 +25011,6 @@ static BUILDIN(sellitem) } } - if (nd->u.scr.shop->type != NST_BARTER) { - value = script_hasdata(st,3) ? script_getnum(st, 3) : it->value_buy; - if( value == -1 ) - value = it->value_buy; - } - if( nd->u.scr.shop->type == NST_MARKET ) { if( !script_hasdata(st,4) || ( qty = script_getnum(st, 4) ) <= 0 ) { ShowError("buildin_sellitem: invalid 'qty' for market-type shop!\n"); @@ -24759,7 +25031,8 @@ static BUILDIN(sellitem) } } - if (i != nd->u.scr.shop->items) { + bool foundInShop = (i != nd->u.scr.shop->items); + if (foundInShop) { nd->u.scr.shop->item[i].value = value; nd->u.scr.shop->item[i].qty = qty; if (nd->u.scr.shop->type == NST_MARKET) /* has been manually updated, make it reflect on sql */ @@ -24785,8 +25058,84 @@ static BUILDIN(sellitem) nd->u.scr.shop->item[i].value = value; nd->u.scr.shop->item[i].value2 = value2; nd->u.scr.shop->item[i].qty = qty; + nd->u.scr.shop->item[i].currency = NULL; + } + nd->u.scr.shop->shop_last_index = i; + + if (!foundInShop) { + for (int k = 5; k <= script_lastdata(st); k += 3) { + script->sellitemcurrency_add(nd, st, k); + } + } + + if (foundInShop) { + if (nd->u.scr.shop->type == NST_EXPANDED_BARTER) { /* has been manually updated, make it reflect on sql */ + npc->expanded_barter_tosql(nd, i); + } + } + return true; +} + +/** + * @call startsellitem <Item_ID>,{,price{,qty}}; + * + * Starts adding item into expanded barter shop (NST_EXPANDED_BARTER) + **/ +static BUILDIN(startsellitem) +{ + struct npc_data *nd; + struct item_data *it; + int i = 0, id = script_getnum(st,2); + int value2 = 0; + int qty = 0; + + if (!(nd = map->id2nd(st->oid))) { + ShowWarning("buildin_startsellitem: trying to run without a proper NPC!\n"); + return false; + } else if (!(it = itemdb->exists(id))) { + ShowWarning("buildin_startsellitem: unknown item id '%d'!\n", id); + return false; + } + + const bool have_shop = (nd->u.scr.shop != NULL); + if (!have_shop) { + npc->trader_update(nd->src_id ? nd->src_id : nd->bl.id); } + if (nd->u.scr.shop->type != NST_EXPANDED_BARTER) { + ShowWarning("script_startsellitem: can works only for NST_EXPANDED_BARTER shops"); + return false; + } + + int value = script_hasdata(st, 3) ? script_getnum(st, 3) : it->value_buy; + if (value == -1) + value = it->value_buy; + + if ((qty = script_getnum(st, 4)) <= 0 && qty != -1) { + ShowError("buildin_startsellitem: invalid 'qty' for expanded barter type shop!\n"); + return false; + } + + for (i = 0; i < nd->u.scr.shop->items; i++) { + if (nd->u.scr.shop->item[i].nameid == 0) + break; + } + + if (i == nd->u.scr.shop->items) { + if (nd->u.scr.shop->items == USHRT_MAX) { + ShowWarning("buildin_startsellitem: Can't add %s (%s/%s), shop list is full!\n", it->name, nd->exname, nd->path); + return false; + } + i = nd->u.scr.shop->items; + RECREATE(nd->u.scr.shop->item, struct npc_item_list, ++nd->u.scr.shop->items); + } + + nd->u.scr.shop->item[i].nameid = it->nameid; + nd->u.scr.shop->item[i].value = value; + nd->u.scr.shop->item[i].value2 = value2; + nd->u.scr.shop->item[i].qty = qty; + nd->u.scr.shop->item[i].currency = NULL; + nd->u.scr.shop->shop_last_index = i; return true; } @@ -24820,6 +25169,18 @@ static BUILDIN(stopselling) break; } } + } else if (nd->u.scr.shop->type == NST_EXPANDED_BARTER) { + if (!script_hasdata(st, 3)) { + ShowError("buildin_stopselling: called with wrong number of arguments\n"); + return false; + } + const int price = script_getnum(st, 3); + for (i = 0; i < nd->u.scr.shop->items; i++) { + const struct npc_item_list *const item = &nd->u.scr.shop->item[i]; + if (item->nameid == id && item->value == price) { + break; + } + } } else { for (i = 0; i < nd->u.scr.shop->items; i++) { if (nd->u.scr.shop->item[i].nameid == id) { @@ -24833,13 +25194,19 @@ static BUILDIN(stopselling) if (nd->u.scr.shop->type == NST_MARKET) npc->market_delfromsql(nd, i); - if (nd->u.scr.shop->type == NST_BARTER) + else if (nd->u.scr.shop->type == NST_BARTER) npc->barter_delfromsql(nd, i); + else if (nd->u.scr.shop->type == NST_EXPANDED_BARTER) + npc->expanded_barter_delfromsql(nd, i); nd->u.scr.shop->item[i].nameid = 0; nd->u.scr.shop->item[i].value = 0; nd->u.scr.shop->item[i].value2 = 0; nd->u.scr.shop->item[i].qty = 0; + if (nd->u.scr.shop->item[i].currency != NULL) { + aFree(nd->u.scr.shop->item[i].currency); + nd->u.scr.shop->item[i].currency = NULL; + } for (i = 0, cursor = 0; i < nd->u.scr.shop->items; i++) { if (nd->u.scr.shop->item[i].nameid == 0) @@ -24850,14 +25217,18 @@ static BUILDIN(stopselling) nd->u.scr.shop->item[cursor].value = nd->u.scr.shop->item[i].value; nd->u.scr.shop->item[cursor].value2 = nd->u.scr.shop->item[i].value2; nd->u.scr.shop->item[cursor].qty = nd->u.scr.shop->item[i].qty; + nd->u.scr.shop->item[cursor].currency = nd->u.scr.shop->item[i].currency; } cursor++; } + nd->u.scr.shop->items--; + nd->u.scr.shop->item[nd->u.scr.shop->items].currency = NULL; script_pushint(st, 1); - } else + } else { script_pushint(st, 0); + } return true; } @@ -24916,6 +25287,7 @@ static BUILDIN(tradertype) } npc->market_delfromsql(nd, INT_MAX); npc->barter_delfromsql(nd, INT_MAX); + npc->expanded_barter_delfromsql(nd, INT_MAX); } #if PACKETVER < 20131223 @@ -24930,6 +25302,12 @@ static BUILDIN(tradertype) script->reportsrc(st); } #endif +#if PACKETVER_MAIN_NUM < 20191120 && PACKETVER_RE_NUM < 20191106 && PACKETVER_ZERO_NUM < 20191127 + if (type == NST_EXPANDED_BARTER) { + ShowWarning("buildin_tradertype: NST_EXPANDED_BARTER is only available with PACKETVER_ZERO_NUM 20191127 or PACKETVER_MAIN_NUM 20191120 or PACKETVER_RE_NUM 20191106 or newer!\n"); + script->reportsrc(st); + } +#endif if( nd->u.scr.shop ) nd->u.scr.shop->type = type; @@ -24973,8 +25351,8 @@ static BUILDIN(shopcount) } else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) { ShowWarning("buildin_shopcount(%d): trying to use without any items!\n",id); return false; - } else if (nd->u.scr.shop->type != NST_MARKET && nd->u.scr.shop->type != NST_BARTER) { - ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET and non-NST_BARTER shop!\n",id); + } else if (nd->u.scr.shop->type != NST_MARKET && nd->u.scr.shop->type != NST_BARTER && nd->u.scr.shop->type != NST_EXPANDED_BARTER) { + ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET and non-NST_BARTER and non-NST_EXPANDED_BARTER shop!\n",id); return false; } @@ -26363,7 +26741,7 @@ static void script_parse_builtin(void) BUILDIN_DEF(checkcart,""), BUILDIN_DEF(setfalcon,"?"), BUILDIN_DEF(checkfalcon,""), - BUILDIN_DEF(setmount,"?"), + BUILDIN_DEF(setmount,"??"), BUILDIN_DEF(checkmount,""), BUILDIN_DEF(checkwug,""), BUILDIN_DEF(savepoint,"sii"), @@ -26410,6 +26788,8 @@ static void script_parse_builtin(void) BUILDIN_DEF(disablenpc,"s"), BUILDIN_DEF(hideoffnpc,"s"), BUILDIN_DEF(hideonnpc,"s"), + BUILDIN_DEF(cloakonnpc,"s?"), + BUILDIN_DEF(cloakoffnpc,"s?"), BUILDIN_DEF(sc_start,"iii???"), BUILDIN_DEF2(sc_start,"sc_start2","iiii???"), BUILDIN_DEF2(sc_start,"sc_start4","iiiiii???"), @@ -26692,6 +27072,7 @@ static void script_parse_builtin(void) BUILDIN_DEF(agitcheck2,""), // Achievements [Smokexyz/Hercules] BUILDIN_DEF(achievement_progress, "iiii?"), + BUILDIN_DEF(achievement_iscompleted, "i?"), // BattleGround BUILDIN_DEF(waitingroom2bg,"siiss?"), BUILDIN_DEF(waitingroom2bg_single,"isiis"), @@ -26803,7 +27184,10 @@ static void script_parse_builtin(void) /* New Shop Support */ BUILDIN_DEF(openshop,"?"), - BUILDIN_DEF(sellitem,"i???"), + BUILDIN_DEF(sellitem, "i???*"), + BUILDIN_DEF(sellitemcurrency, "ii?"), + BUILDIN_DEF(startsellitem, "iii"), + BUILDIN_DEF(endsellitem, ""), BUILDIN_DEF(stopselling,"i??"), BUILDIN_DEF(setcurrency,"i?"), BUILDIN_DEF(tradertype,"i"), @@ -27364,6 +27748,7 @@ static void script_hardcoded_constants(void) script->set_constant("NST_MARKET", NST_MARKET, false, false); script->set_constant("NST_CUSTOM", NST_CUSTOM, false, false); script->set_constant("NST_BARTER", NST_BARTER, false, false); + script->set_constant("NST_EXPANDED_BARTER", NST_EXPANDED_BARTER, false, false); script->constdb_comment("script unit data types"); script->set_constant("UDT_TYPE", UDT_TYPE, false, false); @@ -27449,6 +27834,10 @@ static void script_hardcoded_constants(void) script->set_constant("GUILDINFO_MASTER_NAME", GUILDINFO_MASTER_NAME, false, false); script->set_constant("GUILDINFO_MASTER_CID", GUILDINFO_MASTER_CID, false, false); + script->constdb_comment("madogear types"); + script->set_constant("MADO_ROBOT", MADO_ROBOT, false, false); + script->set_constant("MADO_SUITE", MADO_SUITE, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); @@ -27812,4 +28201,6 @@ void script_defaults(void) script->run_item_rental_start_script = script_run_item_rental_start_script; script->run_item_rental_end_script = script_run_item_rental_end_script; script->run_item_lapineddukddak_script = script_run_item_lapineddukddak_script; + + script->sellitemcurrency_add = script_sellitemcurrency_add; } diff --git a/src/map/script.h b/src/map/script.h index d652f2155..8d7669d68 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -553,6 +553,18 @@ enum siege_type { }; /** + * Types of MadoGear + */ +enum mado_type { + MADO_ROBOT = 0x00, + // unused = 0x01, + MADO_SUITE = 0x02, +#ifndef MADO_MAX + MADO_MAX +#endif +}; + +/** * Structures **/ @@ -1054,6 +1066,7 @@ struct script_interface { void (*run_item_rental_end_script) (struct map_session_data *sd, struct item_data *data, int oid); void (*run_item_rental_start_script) (struct map_session_data *sd, struct item_data *data, int oid); void (*run_item_lapineddukddak_script) (struct map_session_data *sd, struct item_data *data, int oid); + bool (*sellitemcurrency_add) (struct npc_data *nd, struct script_state* st, int argIndex); }; #ifdef HERCULES_CORE diff --git a/src/map/skill.c b/src/map/skill.c index 4579b2ea7..0f0a72dce 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -67,20 +67,6 @@ #define SKILLUNITTIMER_INTERVAL 100 -// ranges reserved for mapping skill ids to skilldb offsets -#define HM_SKILLRANGEMIN 750 -#define HM_SKILLRANGEMAX (HM_SKILLRANGEMIN + MAX_HOMUNSKILL) -#define MC_SKILLRANGEMIN (HM_SKILLRANGEMAX + 1) -#define MC_SKILLRANGEMAX (MC_SKILLRANGEMIN + MAX_MERCSKILL) -#define EL_SKILLRANGEMIN (MC_SKILLRANGEMAX + 1) -#define EL_SKILLRANGEMAX (EL_SKILLRANGEMIN + MAX_ELEMENTALSKILL) -#define GD_SKILLRANGEMIN (EL_SKILLRANGEMAX + 1) -#define GD_SKILLRANGEMAX (GD_SKILLRANGEMIN + MAX_GUILDSKILL) - -#if GD_SKILLRANGEMAX > 999 - #error GD_SKILLRANGEMAX is greater than 999 -#endif - static struct skill_interface skill_s; static struct s_skill_dbs skilldbs; @@ -110,41 +96,55 @@ static int skill_name2id(const char *name) /// Returns the skill's array index, or 0 (Unknown Skill). static int skill_get_index(int skill_id) { - // avoid ranges reserved for mapping guild/homun/mercenary skills - if( (skill_id >= GD_SKILLRANGEMIN && skill_id <= GD_SKILLRANGEMAX) - || (skill_id >= HM_SKILLRANGEMIN && skill_id <= HM_SKILLRANGEMAX) - || (skill_id >= MC_SKILLRANGEMIN && skill_id <= MC_SKILLRANGEMAX) - || (skill_id >= EL_SKILLRANGEMIN && skill_id <= EL_SKILLRANGEMAX) ) + int skillRange[] = { NV_BASIC, NPC_LEX_AETERNA, + KN_CHARGEATK, SA_ELEMENTWIND, + RK_ENCHANTBLADE, AB_SILENTIUM, + WL_WHITEIMPRISON, SC_FEINTBOMB, + LG_CANNONSPEAR, SR_GENTLETOUCH_REVITALIZE, + WA_SWING_DANCE, WA_MOONLIT_SERENADE, + MI_RUSH_WINDMILL, MI_HARMONIZE, + WM_LESSON, WM_UNLIMITED_HUMMING_VOICE, + SO_FIREWALK, SO_EARTH_INSIGNIA, + GN_TRAINING_SWORD, GN_SLINGITEM_RANGEMELEEATK, + AB_SECRAMENT, LG_OVERBRAND_PLUSATK, + ALL_ODINS_RECALL, ALL_LIGHTGUARD, + RL_GLITTERING_GREED, RL_GLITTERING_GREED_ATK, + KO_YAMIKUMO, OB_AKAITSUKI, + ECL_SNOWFLIP, ALL_THANATOS_RECALL, + GC_DARKCROW, NC_MAGMA_ERUPTION_DOTDAMAGE, + SU_BASIC_SKILL, SU_SPIRITOFSEA, + HLIF_HEAL, MH_VOLCANIC_ASH, + MS_BASH, MER_INVINCIBLEOFF2, + EL_CIRCLE_OF_FIRE, EL_STONE_RAIN, + GD_APPROVAL, GD_DEVELOPMENT + CUSTOM_SKILL_RANGES}; + int length = sizeof(skillRange) / sizeof(int); + STATIC_ASSERT(sizeof(skillRange) / sizeof(int) % 2 == 0, "skill_get_index: skillRange should be multiple of 2"); + + + if (skill_id < skillRange[0] || skill_id > skillRange[length - 1]) { + ShowWarning("skill_get_index: skill id '%d' is not being handled!\n", skill_id); return 0; + } - // map skill id to skill db index - if( skill_id >= GD_SKILLBASE ) - skill_id = GD_SKILLRANGEMIN + skill_id - GD_SKILLBASE; - else if( skill_id >= EL_SKILLBASE ) - skill_id = EL_SKILLRANGEMIN + skill_id - EL_SKILLBASE; - else if( skill_id >= MC_SKILLBASE ) - skill_id = MC_SKILLRANGEMIN + skill_id - MC_SKILLBASE; - else if( skill_id >= HM_SKILLBASE ) - skill_id = HM_SKILLRANGEMIN + skill_id - HM_SKILLBASE; - //[Ind/Hercules] GO GO GO LESS! - http://herc.ws/board/topic/512-skill-id-processing-overhaul/ - else if( skill_id > 1019 && skill_id < 8001 ) { - if( skill_id < 2058 ) // 1020 - 2000 are empty - skill_id = 1020 + skill_id - 2001; - else if( skill_id < 2549 ) // 2058 - 2200 are empty - 1020+57 - skill_id = (1077) + skill_id - 2201; - else if ( skill_id < 3036 ) // 2549 - 3000 are empty - 1020+57+348 - skill_id = (1425) + skill_id - 3001; - else if ( skill_id < 5044 ) // 3036 - 5000 are empty - 1020+57+348+35 - skill_id = (1460) + skill_id - 5001; - else - ShowWarning("skill_get_index: skill id '%d' is not being handled!\n",skill_id); + int skill_idx = 0; + // Map Skill ID to Skill Indexes (in reverse order) + for (int i = 0; i < length; i += 2) { + // Check if SkillID belongs to this range. + if (skill_id <= skillRange[i + 1] && skill_id >= skillRange[i]) { + skill_idx += (skillRange[i + 1] - skill_id); + break; + } + // Add the difference of current range + skill_idx += (skillRange[i + 1] - skillRange[i] + 1); } - // validate result - if (skill_id <= 0|| skill_id >= MAX_SKILL_DB) + if (skill_idx >= MAX_SKILL_DB) { + ShowWarning("skill_get_index: skill id '%d'(idx: %d) is not being handled as it exceeds MAX_SKILL_DB!\n", skill_id, skill_idx); return 0; + } - return skill_id; + return skill_idx; } static const char *skill_get_name(int skill_id) @@ -5613,6 +5613,8 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) // Use a do so that you can break out of it when the skill fails. do { + bool is_asura = (ud->skill_id == MO_EXTREMITYFIST); + if(!target || target->prev==NULL) break; if(src->m != target->m || status->isdead(src)) break; @@ -5845,7 +5847,8 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) ud->skill_lv = ud->skilltarget = 0; } - if (src->id != target->id) + // Asura Strike caster doesn't look to their target in the end + if (src->id != target->id && !is_asura) unit->setdir(src, map->calc_dir(src, target->x, target->y)); map->freeblock_unlock(); @@ -5870,19 +5873,30 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) if (target && target->m == src->m) { //Move character to target anyway. int dir, x, y; + int dist = 3; // number of cells that asura caster will walk + dir = map->calc_dir(src,target->x,target->y); - if( dir > 0 && dir < 4) x = -2; - else if( dir > 4 ) x = 2; - else x = 0; - if( dir > 2 && dir < 6 ) y = -2; - else if( dir == 7 || dir < 2 ) y = 2; - else y = 0; - if (unit->movepos(src, src->x+x, src->y+y, 1, 1)) { + if (dir > 0 && dir < 4) + x = -dist; + else if (dir > 4) + x = dist; + else + x = 0; + + if (dir > 2 && dir < 6) + y = -dist; + else if (dir == 7 || dir < 2) + y = dist; + else + y = 0; + + if (unit->movepos(src, src->x + x, src->y + y, 1, 1) == 1) { //Display movement + animation. - clif->slide(src,src->x,src->y); + clif->slide(src, src->x, src->y); clif->spiritball(src); } - clif->skill_fail(sd, ud->skill_id, USESKILL_FAIL_LEVEL, 0, 0); + // "Skill Failed" message was already shown when checking that target is invalid + //clif->skill_fail(sd, ud->skill_id, USESKILL_FAIL_LEVEL, 0, 0); } } @@ -7306,27 +7320,34 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * break; case PR_STRECOVERY: - if(status->isimmune(bl)) { - clif->skill_nodamage(src,bl,skill_id,skill_lv,0); + if (status->isimmune(bl) != 0) { + clif->skill_nodamage(src, bl, skill_id, skill_lv, 0); break; } - if (tsc && tsc->opt1) { - status_change_end(bl, SC_FREEZE, INVALID_TIMER); - status_change_end(bl, SC_STONE, INVALID_TIMER); - status_change_end(bl, SC_SLEEP, INVALID_TIMER); - status_change_end(bl, SC_STUN, INVALID_TIMER); - status_change_end(bl, SC_WHITEIMPRISON, INVALID_TIMER); - } - status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER); - //Is this equation really right? It looks so... special. - if( battle->check_undead(tstatus->race,tstatus->def_ele) ) { - status->change_start(src, bl, SC_BLIND, - 100*(100-(tstatus->int_/2+tstatus->vit/3+tstatus->luk/10)), 1,0,0,0, - skill->get_time2(skill_id, skill_lv) * (100-(tstatus->int_+tstatus->vit)/2)/100,SCFLAG_NONE); + + if (!battle->check_undead(tstatus->race, tstatus->def_ele)) { + if (tsc != NULL && tsc->opt1 != 0) { + status_change_end(bl, SC_FREEZE, INVALID_TIMER); + status_change_end(bl, SC_STONE, INVALID_TIMER); + status_change_end(bl, SC_SLEEP, INVALID_TIMER); + status_change_end(bl, SC_STUN, INVALID_TIMER); + status_change_end(bl, SC_WHITEIMPRISON, INVALID_TIMER); + } + + status_change_end(bl, SC_NETHERWORLD, INVALID_TIMER); + } else { + int rate = 100 * (100 - (tstatus->int_ / 2 + tstatus->vit / 3 + tstatus->luk / 10)); + int duration = skill->get_time2(skill_id, skill_lv); + + duration *= (100 - (tstatus->int_ + tstatus->vit) / 2) / 100; + status->change_start(src, bl, SC_BLIND, rate, 1, 0, 0, 0, duration, SCFLAG_NONE); } - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - if(dstmd) - mob->unlocktarget(dstmd,tick); + + clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); + + if (dstmd != NULL) + mob->unlocktarget(dstmd, tick); + break; // Mercenary Supportive Skills @@ -9433,7 +9454,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * case NC_SELFDESTRUCTION: if (sd) { if (pc_ismadogear(sd)) - pc->setmadogear(sd, false); + pc->setmadogear(sd, false, MADO_ROBOT); clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); skill->castend_damage_id(src, src, skill_id, skill_lv, tick, flag); status->set_sp(src, 0, STATUS_HEAL_DEFAULT); @@ -10403,7 +10424,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * if(sd) { struct mob_data *summon_md; - summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src), MOBID_KO_KAGE, "", SZ_SMALL, AI_NONE); + summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src), MOBID_KO_KAGE, "", SZ_SMALL, AI_NONE, 0); if( summon_md ) { summon_md->master_id = src->id; summon_md->special_state.ai = AI_ZANZOU; @@ -10586,7 +10607,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * for (i = 0; i < summons[skill_lv-1].quantity; i++) { struct mob_data *summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src), - summons[skill_lv-1].mob_id, "", SZ_SMALL, AI_ATTACK); + summons[skill_lv-1].mob_id, "", SZ_SMALL, AI_ATTACK, 0); if (summon_md != NULL) { summon_md->master_id = src->id; if (summon_md->deletetimer != INVALID_TIMER) @@ -11369,7 +11390,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill } // Correct info, don't change any of this! [Celest] - md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), class_, "", SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), class_, "", SZ_SMALL, AI_NONE, 0); if (md) { md->master_id = src->id; md->special_state.ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA; @@ -11471,7 +11492,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); } else { int mob_id = skill_lv < 2 ? MOBID_BLACK_MUSHROOM + rnd()%2 : MOBID_RED_PLANT + rnd()%6; - struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE); + struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, DEFAULT_MOB_JNAME, mob_id, "", SZ_SMALL, AI_NONE, 0); int i; if (md == NULL) break; @@ -11617,7 +11638,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill case NC_SILVERSNIPER: { - struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), MOBID_SILVERSNIPER, "", SZ_SMALL, AI_NONE); + struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), MOBID_SILVERSNIPER, "", SZ_SMALL, AI_NONE, 0); if (md) { md->master_id = src->id; md->special_state.ai = AI_FLORA; @@ -18779,7 +18800,7 @@ static int skill_magicdecoy(struct map_session_data *sd, int nameid) break; } - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE, 0); if( md ) { md->master_id = sd->bl.id; md->special_state.ai = AI_FLORA; diff --git a/src/map/skill.h b/src/map/skill.h index dbda6470f..188a1c927 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -59,6 +59,12 @@ struct status_change_entry; #define MAX_SKILLUNITGROUPTICKSET 25 #define MAX_SKILL_NAME_LENGTH 32 +// Custom Skill Ranges is used in skill_get_index, to allocate indexes based on ID and gaps between 2 SkillID +#ifndef CUSTOM_SKILL_RANGES + #define CUSTOM_SKILL_RANGES +#endif // CUSTOM_SKILL_RANGES + + // (Epoque:) To-do: replace this macro with some sort of skill tree check (rather than hard-coded skill names) #define skill_ischangesex(id) ( \ ((id) >= BD_ADAPTATION && (id) <= DC_SERVICEFORYOU) || ((id) >= CG_ARROWVULCAN && (id) <= CG_MARIONETTE) || \ diff --git a/src/map/status.c b/src/map/status.c index 3b99b99b8..1f0f31119 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -9798,6 +9798,9 @@ static int status_get_val_flag(enum sc_type type) case SC_DAILYSENDMAILCNT: val_flag |= 1 | 2; break; + case SC_MADOGEAR: + val_flag |= 1; + break; } return val_flag; } diff --git a/src/map/status.h b/src/map/status.h index ecf27d411..ada18bc0a 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -853,6 +853,7 @@ typedef enum sc_type { SC_RESIST_PROPERTY_FIRE, SC_RESIST_PROPERTY_WIND, SC_CLIENT_ONLY_EQUIP_ARROW, + SC_MADOGEAR, #ifndef SC_MAX SC_MAX, //Automatically updated max, used in for's to check we are within bounds. #endif diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 1f34dfdd4..c1fb15810 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -1514,6 +1514,8 @@ typedef void (*HPMHOOK_pre_clif_misceffect) (struct block_list **bl, int *type); typedef void (*HPMHOOK_post_clif_misceffect) (struct block_list *bl, int type); typedef void (*HPMHOOK_pre_clif_changeoption) (struct block_list **bl); typedef void (*HPMHOOK_post_clif_changeoption) (struct block_list *bl); +typedef void (*HPMHOOK_pre_clif_changeoption_target) (struct block_list **bl, struct block_list **target_bl, enum send_target *target); +typedef void (*HPMHOOK_post_clif_changeoption_target) (struct block_list *bl, struct block_list *target_bl, enum send_target target); typedef void (*HPMHOOK_pre_clif_changeoption2) (struct block_list **bl); typedef void (*HPMHOOK_post_clif_changeoption2) (struct block_list *bl); typedef void (*HPMHOOK_pre_clif_emotion) (struct block_list **bl, int *type); @@ -2712,6 +2714,12 @@ typedef void (*HPMHOOK_pre_clif_pNPCBarterClosed) (int *fd, struct map_session_d typedef void (*HPMHOOK_post_clif_pNPCBarterClosed) (int fd, struct map_session_data *sd); typedef void (*HPMHOOK_pre_clif_pNPCBarterPurchase) (int *fd, struct map_session_data **sd); typedef void (*HPMHOOK_post_clif_pNPCBarterPurchase) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_pNPCExpandedBarterClosed) (int *fd, struct map_session_data **sd); +typedef void (*HPMHOOK_post_clif_pNPCExpandedBarterClosed) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_pNPCExpandedBarterPurchase) (int *fd, struct map_session_data **sd); +typedef void (*HPMHOOK_post_clif_pNPCExpandedBarterPurchase) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_npc_expanded_barter_open) (struct map_session_data **sd, struct npc_data **nd); +typedef void (*HPMHOOK_post_clif_npc_expanded_barter_open) (struct map_session_data *sd, struct npc_data *nd); typedef void (*HPMHOOK_pre_clif_pClientVersion) (int *fd, struct map_session_data **sd); typedef void (*HPMHOOK_post_clif_pClientVersion) (int fd, struct map_session_data *sd); typedef void (*HPMHOOK_pre_clif_pPing) (int *fd, struct map_session_data **sd); @@ -2844,8 +2852,8 @@ typedef void (*HPMHOOK_pre_duel_leave) (const unsigned int *did, struct map_sess typedef void (*HPMHOOK_post_duel_leave) (const unsigned int did, struct map_session_data *sd); typedef void (*HPMHOOK_pre_duel_showinfo) (const unsigned int *did, struct map_session_data **sd); typedef void (*HPMHOOK_post_duel_showinfo) (const unsigned int did, struct map_session_data *sd); -typedef int (*HPMHOOK_pre_duel_checktime) (struct map_session_data **sd); -typedef int (*HPMHOOK_post_duel_checktime) (int retVal___, struct map_session_data *sd); +typedef int64 (*HPMHOOK_pre_duel_difftime) (struct map_session_data **sd); +typedef int64 (*HPMHOOK_post_duel_difftime) (int64 retVal___, struct map_session_data *sd); typedef void (*HPMHOOK_pre_duel_init) (bool *minimal); typedef void (*HPMHOOK_post_duel_init) (bool minimal); typedef void (*HPMHOOK_pre_duel_final) (void); @@ -3532,10 +3540,14 @@ typedef bool (*HPMHOOK_post_inter_mercenary_delete) (bool retVal___, int merc_id #ifdef CHAR_INT_PARTY_H /* inter_party */ typedef int (*HPMHOOK_pre_inter_party_check_lv) (struct party_data **p); typedef int (*HPMHOOK_post_inter_party_check_lv) (int retVal___, struct party_data *p); +typedef int (*HPMHOOK_pre_inter_party_is_family_party) (struct party_data **p); +typedef int (*HPMHOOK_post_inter_party_is_family_party) (int retVal___, struct party_data *p); typedef void (*HPMHOOK_pre_inter_party_calc_state) (struct party_data **p); typedef void (*HPMHOOK_post_inter_party_calc_state) (struct party_data *p); typedef int (*HPMHOOK_pre_inter_party_tosql) (struct party **p, int *flag, int *index); typedef int (*HPMHOOK_post_inter_party_tosql) (int retVal___, struct party *p, int flag, int index); +typedef int (*HPMHOOK_pre_inter_party_del_nonexistent_party) (int *party_id); +typedef int (*HPMHOOK_post_inter_party_del_nonexistent_party) (int retVal___, int party_id); typedef struct party_data* (*HPMHOOK_pre_inter_party_fromsql) (int *party_id); typedef struct party_data* (*HPMHOOK_post_inter_party_fromsql) (struct party_data* retVal___, int party_id); typedef int (*HPMHOOK_pre_inter_party_sql_init) (void); @@ -3562,8 +3574,8 @@ typedef bool (*HPMHOOK_pre_inter_party_add_member) (int *party_id, const struct typedef bool (*HPMHOOK_post_inter_party_add_member) (bool retVal___, int party_id, const struct party_member *member); typedef bool (*HPMHOOK_pre_inter_party_change_option) (int *party_id, int *account_id, int *exp, int *item, int *map_fd); typedef bool (*HPMHOOK_post_inter_party_change_option) (bool retVal___, int party_id, int account_id, int exp, int item, int map_fd); -typedef bool (*HPMHOOK_pre_inter_party_change_map) (int *party_id, int *account_id, int *char_id, unsigned short *map, int *online, unsigned int *lv); -typedef bool (*HPMHOOK_post_inter_party_change_map) (bool retVal___, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv); +typedef bool (*HPMHOOK_pre_inter_party_change_map) (int *party_id, int *account_id, int *char_id, unsigned short *map, int *online, int *lv); +typedef bool (*HPMHOOK_post_inter_party_change_map) (bool retVal___, int party_id, int account_id, int char_id, unsigned short map, int online, int lv); typedef bool (*HPMHOOK_pre_inter_party_disband) (int *party_id); typedef bool (*HPMHOOK_post_inter_party_disband) (bool retVal___, int party_id); typedef bool (*HPMHOOK_pre_inter_party_change_leader) (int *party_id, int *account_id, int *char_id); @@ -5324,22 +5336,22 @@ typedef struct view_data* (*HPMHOOK_pre_mob_get_viewdata) (int *class_); typedef struct view_data* (*HPMHOOK_post_mob_get_viewdata) (struct view_data* retVal___, int class_); typedef int (*HPMHOOK_pre_mob_parse_dataset) (struct spawn_data **data); typedef int (*HPMHOOK_post_mob_parse_dataset) (int retVal___, struct spawn_data *data); -typedef struct mob_data* (*HPMHOOK_pre_mob_spawn_dataset) (struct spawn_data **data); -typedef struct mob_data* (*HPMHOOK_post_mob_spawn_dataset) (struct mob_data* retVal___, struct spawn_data *data); +typedef struct mob_data* (*HPMHOOK_pre_mob_spawn_dataset) (struct spawn_data **data, int *npc_id); +typedef struct mob_data* (*HPMHOOK_post_mob_spawn_dataset) (struct mob_data* retVal___, struct spawn_data *data, int npc_id); typedef int (*HPMHOOK_pre_mob_get_random_id) (int *type, int *flag, int *lv); typedef int (*HPMHOOK_post_mob_get_random_id) (int retVal___, int type, int flag, int lv); typedef bool (*HPMHOOK_pre_mob_ksprotected) (struct block_list **src, struct block_list **target); typedef bool (*HPMHOOK_post_mob_ksprotected) (bool retVal___, struct block_list *src, struct block_list *target); -typedef struct mob_data* (*HPMHOOK_pre_mob_once_spawn_sub) (struct block_list **bl, int16 *m, int16 *x, int16 *y, const char **mobname, int *class_, const char **event, unsigned int *size, unsigned int *ai); -typedef struct mob_data* (*HPMHOOK_post_mob_once_spawn_sub) (struct mob_data* retVal___, struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai); +typedef struct mob_data* (*HPMHOOK_pre_mob_once_spawn_sub) (struct block_list **bl, int16 *m, int16 *x, int16 *y, const char **mobname, int *class_, const char **event, unsigned int *size, unsigned int *ai, int *npc_id); +typedef struct mob_data* (*HPMHOOK_post_mob_once_spawn_sub) (struct mob_data* retVal___, struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai, int npc_id); typedef int (*HPMHOOK_pre_mob_once_spawn) (struct map_session_data **sd, int16 *m, int16 *x, int16 *y, const char **mobname, int *class_, int *amount, const char **event, unsigned int *size, unsigned int *ai); typedef int (*HPMHOOK_post_mob_once_spawn) (int retVal___, struct map_session_data *sd, int16 m, int16 x, int16 y, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai); typedef int (*HPMHOOK_pre_mob_once_spawn_area) (struct map_session_data **sd, int16 *m, int16 *x0, int16 *y0, int16 *x1, int16 *y1, const char **mobname, int *class_, int *amount, const char **event, unsigned int *size, unsigned int *ai); typedef int (*HPMHOOK_post_mob_once_spawn_area) (int retVal___, struct map_session_data *sd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, const char *mobname, int class_, int amount, const char *event, unsigned int size, unsigned int ai); -typedef int (*HPMHOOK_pre_mob_spawn_guardian) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, int *guardian, bool *has_index); -typedef int (*HPMHOOK_post_mob_spawn_guardian) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index); -typedef int (*HPMHOOK_pre_mob_spawn_bg) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, unsigned int *bg_id); -typedef int (*HPMHOOK_post_mob_spawn_bg) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id); +typedef int (*HPMHOOK_pre_mob_spawn_guardian) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, int *guardian, bool *has_index, int *npc_id); +typedef int (*HPMHOOK_post_mob_spawn_guardian) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index, int npc_id); +typedef int (*HPMHOOK_pre_mob_spawn_bg) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, unsigned int *bg_id, int *npc_id); +typedef int (*HPMHOOK_post_mob_spawn_bg) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id, int npc_id); typedef int (*HPMHOOK_pre_mob_can_reach) (struct mob_data **md, struct block_list **bl, int *range, int *state); typedef int (*HPMHOOK_post_mob_can_reach) (int retVal___, struct mob_data *md, struct block_list *bl, int range, int state); typedef int (*HPMHOOK_pre_mob_linksearch) (struct block_list **bl, va_list ap); @@ -5674,10 +5686,12 @@ typedef int (*HPMHOOK_pre_npc_unload_ev_label) (union DBKey *key, struct DBData typedef int (*HPMHOOK_post_npc_unload_ev_label) (int retVal___, union DBKey key, struct DBData *data, va_list ap); typedef int (*HPMHOOK_pre_npc_unload_dup_sub) (struct npc_data **nd, va_list args); typedef int (*HPMHOOK_post_npc_unload_dup_sub) (int retVal___, struct npc_data *nd, va_list args); -typedef void (*HPMHOOK_pre_npc_unload_duplicates) (struct npc_data **nd); -typedef void (*HPMHOOK_post_npc_unload_duplicates) (struct npc_data *nd); -typedef int (*HPMHOOK_pre_npc_unload) (struct npc_data **nd, bool *single); -typedef int (*HPMHOOK_post_npc_unload) (int retVal___, struct npc_data *nd, bool single); +typedef void (*HPMHOOK_pre_npc_unload_duplicates) (struct npc_data **nd, bool *unload_mobs); +typedef void (*HPMHOOK_post_npc_unload_duplicates) (struct npc_data *nd, bool unload_mobs); +typedef int (*HPMHOOK_pre_npc_unload_mob) (struct mob_data **md, va_list args); +typedef int (*HPMHOOK_post_npc_unload_mob) (int retVal___, struct mob_data *md, va_list args); +typedef int (*HPMHOOK_pre_npc_unload) (struct npc_data **nd, bool *single, bool *unload_mobs); +typedef int (*HPMHOOK_post_npc_unload) (int retVal___, struct npc_data *nd, bool single, bool unload_mobs); typedef void (*HPMHOOK_pre_npc_clearsrcfile) (void); typedef void (*HPMHOOK_post_npc_clearsrcfile) (void); typedef void (*HPMHOOK_pre_npc_addsrcfile) (const char **name); @@ -5760,8 +5774,8 @@ typedef int (*HPMHOOK_pre_npc_ev_label_db_clear_sub) (union DBKey *key, struct D typedef int (*HPMHOOK_post_npc_ev_label_db_clear_sub) (int retVal___, union DBKey key, struct DBData *data, va_list args); typedef int (*HPMHOOK_pre_npc_reload) (void); typedef int (*HPMHOOK_post_npc_reload) (int retVal___); -typedef bool (*HPMHOOK_pre_npc_unloadfile) (const char **filepath); -typedef bool (*HPMHOOK_post_npc_unloadfile) (bool retVal___, const char *filepath); +typedef bool (*HPMHOOK_pre_npc_unloadfile) (const char **filepath, bool *unload_mobs); +typedef bool (*HPMHOOK_post_npc_unloadfile) (bool retVal___, const char *filepath, bool unload_mobs); typedef void (*HPMHOOK_pre_npc_do_clear_npc) (void); typedef void (*HPMHOOK_post_npc_do_clear_npc) (void); typedef void (*HPMHOOK_pre_npc_debug_warps_sub) (struct npc_data **nd); @@ -5778,6 +5792,8 @@ typedef enum market_buy_result (*HPMHOOK_pre_npc_market_buylist) (struct map_ses typedef enum market_buy_result (*HPMHOOK_post_npc_market_buylist) (enum market_buy_result retVal___, struct map_session_data *sd, struct itemlist *item_list); typedef int (*HPMHOOK_pre_npc_barter_buylist) (struct map_session_data **sd, struct barteritemlist **item_list); typedef int (*HPMHOOK_post_npc_barter_buylist) (int retVal___, struct map_session_data *sd, struct barteritemlist *item_list); +typedef int (*HPMHOOK_pre_npc_expanded_barter_buylist) (struct map_session_data **sd, struct barteritemlist **item_list); +typedef int (*HPMHOOK_post_npc_expanded_barter_buylist) (int retVal___, struct map_session_data *sd, struct barteritemlist *item_list); typedef bool (*HPMHOOK_pre_npc_trader_open) (struct map_session_data **sd, struct npc_data **nd); typedef bool (*HPMHOOK_post_npc_trader_open) (bool retVal___, struct map_session_data *sd, struct npc_data *nd); typedef void (*HPMHOOK_pre_npc_market_fromsql) (void); @@ -5796,6 +5812,14 @@ typedef void (*HPMHOOK_pre_npc_barter_delfromsql) (struct npc_data **nd, int *in typedef void (*HPMHOOK_post_npc_barter_delfromsql) (struct npc_data *nd, int index); typedef void (*HPMHOOK_pre_npc_barter_delfromsql_sub) (const char **npcname, int *itemId, int *itemId2, int *amount2); typedef void (*HPMHOOK_post_npc_barter_delfromsql_sub) (const char *npcname, int itemId, int itemId2, int amount2); +typedef void (*HPMHOOK_pre_npc_expanded_barter_fromsql) (void); +typedef void (*HPMHOOK_post_npc_expanded_barter_fromsql) (void); +typedef void (*HPMHOOK_pre_npc_expanded_barter_tosql) (struct npc_data **nd, int *index); +typedef void (*HPMHOOK_post_npc_expanded_barter_tosql) (struct npc_data *nd, int index); +typedef void (*HPMHOOK_pre_npc_expanded_barter_delfromsql) (struct npc_data **nd, int *index); +typedef void (*HPMHOOK_post_npc_expanded_barter_delfromsql) (struct npc_data *nd, int index); +typedef void (*HPMHOOK_pre_npc_expanded_barter_delfromsql_sub) (const char **npcname, int *itemId, int *zeny, int *currencyCount, struct npc_barter_currency **currency); +typedef void (*HPMHOOK_post_npc_expanded_barter_delfromsql_sub) (const char *npcname, int itemId, int zeny, int currencyCount, struct npc_barter_currency *currency); typedef bool (*HPMHOOK_pre_npc_db_checkid) (const int *id); typedef bool (*HPMHOOK_post_npc_db_checkid) (bool retVal___, const int id); typedef void (*HPMHOOK_pre_npc_refresh) (struct npc_data **nd); @@ -6188,8 +6212,8 @@ typedef void (*HPMHOOK_pre_pc_setfalcon) (struct map_session_data **sd, bool *fl typedef void (*HPMHOOK_post_pc_setfalcon) (struct map_session_data *sd, bool flag); typedef void (*HPMHOOK_pre_pc_setridingpeco) (struct map_session_data **sd, bool *flag); typedef void (*HPMHOOK_post_pc_setridingpeco) (struct map_session_data *sd, bool flag); -typedef void (*HPMHOOK_pre_pc_setmadogear) (struct map_session_data **sd, bool *flag); -typedef void (*HPMHOOK_post_pc_setmadogear) (struct map_session_data *sd, bool flag); +typedef void (*HPMHOOK_pre_pc_setmadogear) (struct map_session_data **sd, bool *flag, enum mado_type *mtype); +typedef void (*HPMHOOK_post_pc_setmadogear) (struct map_session_data *sd, bool flag, enum mado_type mtype); typedef void (*HPMHOOK_pre_pc_setridingdragon) (struct map_session_data **sd, unsigned int *type); typedef void (*HPMHOOK_post_pc_setridingdragon) (struct map_session_data *sd, unsigned int type); typedef void (*HPMHOOK_pre_pc_setridingwug) (struct map_session_data **sd, bool *flag); @@ -7110,6 +7134,8 @@ typedef void (*HPMHOOK_pre_script_run_item_rental_start_script) (struct map_sess typedef void (*HPMHOOK_post_script_run_item_rental_start_script) (struct map_session_data *sd, struct item_data *data, int oid); typedef void (*HPMHOOK_pre_script_run_item_lapineddukddak_script) (struct map_session_data **sd, struct item_data **data, int *oid); typedef void (*HPMHOOK_post_script_run_item_lapineddukddak_script) (struct map_session_data *sd, struct item_data *data, int oid); +typedef bool (*HPMHOOK_pre_script_sellitemcurrency_add) (struct npc_data **nd, struct script_state **st, int *argIndex); +typedef bool (*HPMHOOK_post_script_sellitemcurrency_add) (bool retVal___, struct npc_data *nd, struct script_state *st, int argIndex); #endif // MAP_SCRIPT_H #ifdef MAP_SEARCHSTORE_H /* searchstore */ typedef bool (*HPMHOOK_pre_searchstore_open) (struct map_session_data **sd, unsigned int *uses, unsigned short *effect); diff --git a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc index a9a83511e..20f57dcb9 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc @@ -674,10 +674,14 @@ struct { struct HPMHookPoint *HP_inter_mercenary_delete_post; struct HPMHookPoint *HP_inter_party_check_lv_pre; struct HPMHookPoint *HP_inter_party_check_lv_post; + struct HPMHookPoint *HP_inter_party_is_family_party_pre; + struct HPMHookPoint *HP_inter_party_is_family_party_post; struct HPMHookPoint *HP_inter_party_calc_state_pre; struct HPMHookPoint *HP_inter_party_calc_state_post; struct HPMHookPoint *HP_inter_party_tosql_pre; struct HPMHookPoint *HP_inter_party_tosql_post; + struct HPMHookPoint *HP_inter_party_del_nonexistent_party_pre; + struct HPMHookPoint *HP_inter_party_del_nonexistent_party_post; struct HPMHookPoint *HP_inter_party_fromsql_pre; struct HPMHookPoint *HP_inter_party_fromsql_post; struct HPMHookPoint *HP_inter_party_sql_init_pre; @@ -2295,10 +2299,14 @@ struct { int HP_inter_mercenary_delete_post; int HP_inter_party_check_lv_pre; int HP_inter_party_check_lv_post; + int HP_inter_party_is_family_party_pre; + int HP_inter_party_is_family_party_post; int HP_inter_party_calc_state_pre; int HP_inter_party_calc_state_post; int HP_inter_party_tosql_pre; int HP_inter_party_tosql_post; + int HP_inter_party_del_nonexistent_party_pre; + int HP_inter_party_del_nonexistent_party_post; int HP_inter_party_fromsql_pre; int HP_inter_party_fromsql_post; int HP_inter_party_sql_init_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc index 7f52ebe46..e8e211f8b 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc @@ -368,8 +368,10 @@ struct HookingPointData HookingPoints[] = { { HP_POP(inter_mercenary->delete, HP_inter_mercenary_delete) }, /* inter_party_interface */ { HP_POP(inter_party->check_lv, HP_inter_party_check_lv) }, + { HP_POP(inter_party->is_family_party, HP_inter_party_is_family_party) }, { HP_POP(inter_party->calc_state, HP_inter_party_calc_state) }, { HP_POP(inter_party->tosql, HP_inter_party_tosql) }, + { HP_POP(inter_party->del_nonexistent_party, HP_inter_party_del_nonexistent_party) }, { HP_POP(inter_party->fromsql, HP_inter_party_fromsql) }, { HP_POP(inter_party->sql_init, HP_inter_party_sql_init) }, { HP_POP(inter_party->sql_final, HP_inter_party_sql_final) }, diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc index d5297c29c..a022abb54 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc @@ -8712,6 +8712,33 @@ int HP_inter_party_check_lv(struct party_data *p) { } return retVal___; } +int HP_inter_party_is_family_party(struct party_data *p) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_inter_party_is_family_party_pre > 0) { + int (*preHookFunc) (struct party_data **p); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_party_is_family_party_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_inter_party_is_family_party_pre[hIndex].func; + retVal___ = preHookFunc(&p); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.inter_party.is_family_party(p); + } + if (HPMHooks.count.HP_inter_party_is_family_party_post > 0) { + int (*postHookFunc) (int retVal___, struct party_data *p); + for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_party_is_family_party_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_inter_party_is_family_party_post[hIndex].func; + retVal___ = postHookFunc(retVal___, p); + } + } + return retVal___; +} void HP_inter_party_calc_state(struct party_data *p) { int hIndex = 0; if (HPMHooks.count.HP_inter_party_calc_state_pre > 0) { @@ -8765,6 +8792,33 @@ int HP_inter_party_tosql(struct party *p, int flag, int index) { } return retVal___; } +int HP_inter_party_del_nonexistent_party(int party_id) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_inter_party_del_nonexistent_party_pre > 0) { + int (*preHookFunc) (int *party_id); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_party_del_nonexistent_party_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_inter_party_del_nonexistent_party_pre[hIndex].func; + retVal___ = preHookFunc(&party_id); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.inter_party.del_nonexistent_party(party_id); + } + if (HPMHooks.count.HP_inter_party_del_nonexistent_party_post > 0) { + int (*postHookFunc) (int retVal___, int party_id); + for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_party_del_nonexistent_party_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_inter_party_del_nonexistent_party_post[hIndex].func; + retVal___ = postHookFunc(retVal___, party_id); + } + } + return retVal___; +} struct party_data* HP_inter_party_fromsql(int party_id) { int hIndex = 0; struct party_data* retVal___ = NULL; @@ -9115,11 +9169,11 @@ bool HP_inter_party_change_option(int party_id, int account_id, int exp, int ite } return retVal___; } -bool HP_inter_party_change_map(int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv) { +bool HP_inter_party_change_map(int party_id, int account_id, int char_id, unsigned short map, int online, int lv) { int hIndex = 0; bool retVal___ = false; if (HPMHooks.count.HP_inter_party_change_map_pre > 0) { - bool (*preHookFunc) (int *party_id, int *account_id, int *char_id, unsigned short *map, int *online, unsigned int *lv); + bool (*preHookFunc) (int *party_id, int *account_id, int *char_id, unsigned short *map, int *online, int *lv); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_party_change_map_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_inter_party_change_map_pre[hIndex].func; @@ -9134,7 +9188,7 @@ bool HP_inter_party_change_map(int party_id, int account_id, int char_id, unsign retVal___ = HPMHooks.source.inter_party.change_map(party_id, account_id, char_id, map, online, lv); } if (HPMHooks.count.HP_inter_party_change_map_post > 0) { - bool (*postHookFunc) (bool retVal___, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv); + bool (*postHookFunc) (bool retVal___, int party_id, int account_id, int char_id, unsigned short map, int online, int lv); for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_party_change_map_post; hIndex++) { postHookFunc = HPMHooks.list.HP_inter_party_change_map_post[hIndex].func; retVal___ = postHookFunc(retVal___, party_id, account_id, char_id, map, online, lv); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index eccf2a277..53ba3403c 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -1104,6 +1104,8 @@ struct { struct HPMHookPoint *HP_clif_misceffect_post; struct HPMHookPoint *HP_clif_changeoption_pre; struct HPMHookPoint *HP_clif_changeoption_post; + struct HPMHookPoint *HP_clif_changeoption_target_pre; + struct HPMHookPoint *HP_clif_changeoption_target_post; struct HPMHookPoint *HP_clif_changeoption2_pre; struct HPMHookPoint *HP_clif_changeoption2_post; struct HPMHookPoint *HP_clif_emotion_pre; @@ -2302,6 +2304,12 @@ struct { struct HPMHookPoint *HP_clif_pNPCBarterClosed_post; struct HPMHookPoint *HP_clif_pNPCBarterPurchase_pre; struct HPMHookPoint *HP_clif_pNPCBarterPurchase_post; + struct HPMHookPoint *HP_clif_pNPCExpandedBarterClosed_pre; + struct HPMHookPoint *HP_clif_pNPCExpandedBarterClosed_post; + struct HPMHookPoint *HP_clif_pNPCExpandedBarterPurchase_pre; + struct HPMHookPoint *HP_clif_pNPCExpandedBarterPurchase_post; + struct HPMHookPoint *HP_clif_npc_expanded_barter_open_pre; + struct HPMHookPoint *HP_clif_npc_expanded_barter_open_post; struct HPMHookPoint *HP_clif_pClientVersion_pre; struct HPMHookPoint *HP_clif_pClientVersion_post; struct HPMHookPoint *HP_clif_pPing_pre; @@ -2422,8 +2430,8 @@ struct { struct HPMHookPoint *HP_duel_leave_post; struct HPMHookPoint *HP_duel_showinfo_pre; struct HPMHookPoint *HP_duel_showinfo_post; - struct HPMHookPoint *HP_duel_checktime_pre; - struct HPMHookPoint *HP_duel_checktime_post; + struct HPMHookPoint *HP_duel_difftime_pre; + struct HPMHookPoint *HP_duel_difftime_post; struct HPMHookPoint *HP_duel_init_pre; struct HPMHookPoint *HP_duel_init_post; struct HPMHookPoint *HP_duel_final_pre; @@ -4272,6 +4280,8 @@ struct { struct HPMHookPoint *HP_npc_unload_dup_sub_post; struct HPMHookPoint *HP_npc_unload_duplicates_pre; struct HPMHookPoint *HP_npc_unload_duplicates_post; + struct HPMHookPoint *HP_npc_unload_mob_pre; + struct HPMHookPoint *HP_npc_unload_mob_post; struct HPMHookPoint *HP_npc_unload_pre; struct HPMHookPoint *HP_npc_unload_post; struct HPMHookPoint *HP_npc_clearsrcfile_pre; @@ -4374,6 +4384,8 @@ struct { struct HPMHookPoint *HP_npc_market_buylist_post; struct HPMHookPoint *HP_npc_barter_buylist_pre; struct HPMHookPoint *HP_npc_barter_buylist_post; + struct HPMHookPoint *HP_npc_expanded_barter_buylist_pre; + struct HPMHookPoint *HP_npc_expanded_barter_buylist_post; struct HPMHookPoint *HP_npc_trader_open_pre; struct HPMHookPoint *HP_npc_trader_open_post; struct HPMHookPoint *HP_npc_market_fromsql_pre; @@ -4392,6 +4404,14 @@ struct { struct HPMHookPoint *HP_npc_barter_delfromsql_post; struct HPMHookPoint *HP_npc_barter_delfromsql_sub_pre; struct HPMHookPoint *HP_npc_barter_delfromsql_sub_post; + struct HPMHookPoint *HP_npc_expanded_barter_fromsql_pre; + struct HPMHookPoint *HP_npc_expanded_barter_fromsql_post; + struct HPMHookPoint *HP_npc_expanded_barter_tosql_pre; + struct HPMHookPoint *HP_npc_expanded_barter_tosql_post; + struct HPMHookPoint *HP_npc_expanded_barter_delfromsql_pre; + struct HPMHookPoint *HP_npc_expanded_barter_delfromsql_post; + struct HPMHookPoint *HP_npc_expanded_barter_delfromsql_sub_pre; + struct HPMHookPoint *HP_npc_expanded_barter_delfromsql_sub_post; struct HPMHookPoint *HP_npc_db_checkid_pre; struct HPMHookPoint *HP_npc_db_checkid_post; struct HPMHookPoint *HP_npc_refresh_pre; @@ -5644,6 +5664,8 @@ struct { struct HPMHookPoint *HP_script_run_item_rental_start_script_post; struct HPMHookPoint *HP_script_run_item_lapineddukddak_script_pre; struct HPMHookPoint *HP_script_run_item_lapineddukddak_script_post; + struct HPMHookPoint *HP_script_sellitemcurrency_add_pre; + struct HPMHookPoint *HP_script_sellitemcurrency_add_post; struct HPMHookPoint *HP_searchstore_open_pre; struct HPMHookPoint *HP_searchstore_open_post; struct HPMHookPoint *HP_searchstore_query_pre; @@ -7949,6 +7971,8 @@ struct { int HP_clif_misceffect_post; int HP_clif_changeoption_pre; int HP_clif_changeoption_post; + int HP_clif_changeoption_target_pre; + int HP_clif_changeoption_target_post; int HP_clif_changeoption2_pre; int HP_clif_changeoption2_post; int HP_clif_emotion_pre; @@ -9147,6 +9171,12 @@ struct { int HP_clif_pNPCBarterClosed_post; int HP_clif_pNPCBarterPurchase_pre; int HP_clif_pNPCBarterPurchase_post; + int HP_clif_pNPCExpandedBarterClosed_pre; + int HP_clif_pNPCExpandedBarterClosed_post; + int HP_clif_pNPCExpandedBarterPurchase_pre; + int HP_clif_pNPCExpandedBarterPurchase_post; + int HP_clif_npc_expanded_barter_open_pre; + int HP_clif_npc_expanded_barter_open_post; int HP_clif_pClientVersion_pre; int HP_clif_pClientVersion_post; int HP_clif_pPing_pre; @@ -9267,8 +9297,8 @@ struct { int HP_duel_leave_post; int HP_duel_showinfo_pre; int HP_duel_showinfo_post; - int HP_duel_checktime_pre; - int HP_duel_checktime_post; + int HP_duel_difftime_pre; + int HP_duel_difftime_post; int HP_duel_init_pre; int HP_duel_init_post; int HP_duel_final_pre; @@ -11117,6 +11147,8 @@ struct { int HP_npc_unload_dup_sub_post; int HP_npc_unload_duplicates_pre; int HP_npc_unload_duplicates_post; + int HP_npc_unload_mob_pre; + int HP_npc_unload_mob_post; int HP_npc_unload_pre; int HP_npc_unload_post; int HP_npc_clearsrcfile_pre; @@ -11219,6 +11251,8 @@ struct { int HP_npc_market_buylist_post; int HP_npc_barter_buylist_pre; int HP_npc_barter_buylist_post; + int HP_npc_expanded_barter_buylist_pre; + int HP_npc_expanded_barter_buylist_post; int HP_npc_trader_open_pre; int HP_npc_trader_open_post; int HP_npc_market_fromsql_pre; @@ -11237,6 +11271,14 @@ struct { int HP_npc_barter_delfromsql_post; int HP_npc_barter_delfromsql_sub_pre; int HP_npc_barter_delfromsql_sub_post; + int HP_npc_expanded_barter_fromsql_pre; + int HP_npc_expanded_barter_fromsql_post; + int HP_npc_expanded_barter_tosql_pre; + int HP_npc_expanded_barter_tosql_post; + int HP_npc_expanded_barter_delfromsql_pre; + int HP_npc_expanded_barter_delfromsql_post; + int HP_npc_expanded_barter_delfromsql_sub_pre; + int HP_npc_expanded_barter_delfromsql_sub_post; int HP_npc_db_checkid_pre; int HP_npc_db_checkid_post; int HP_npc_refresh_pre; @@ -12489,6 +12531,8 @@ struct { int HP_script_run_item_rental_start_script_post; int HP_script_run_item_lapineddukddak_script_pre; int HP_script_run_item_lapineddukddak_script_post; + int HP_script_sellitemcurrency_add_pre; + int HP_script_sellitemcurrency_add_post; int HP_searchstore_open_pre; int HP_searchstore_open_post; int HP_searchstore_query_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index b8d5f3482..0904a1dac 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -576,6 +576,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->quitsave, HP_clif_quitsave) }, { HP_POP(clif->misceffect, HP_clif_misceffect) }, { HP_POP(clif->changeoption, HP_clif_changeoption) }, + { HP_POP(clif->changeoption_target, HP_clif_changeoption_target) }, { HP_POP(clif->changeoption2, HP_clif_changeoption2) }, { HP_POP(clif->emotion, HP_clif_emotion) }, { HP_POP(clif->talkiebox, HP_clif_talkiebox) }, @@ -1175,6 +1176,9 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->npc_barter_open, HP_clif_npc_barter_open) }, { HP_POP(clif->pNPCBarterClosed, HP_clif_pNPCBarterClosed) }, { HP_POP(clif->pNPCBarterPurchase, HP_clif_pNPCBarterPurchase) }, + { HP_POP(clif->pNPCExpandedBarterClosed, HP_clif_pNPCExpandedBarterClosed) }, + { HP_POP(clif->pNPCExpandedBarterPurchase, HP_clif_pNPCExpandedBarterPurchase) }, + { HP_POP(clif->npc_expanded_barter_open, HP_clif_npc_expanded_barter_open) }, { HP_POP(clif->pClientVersion, HP_clif_pClientVersion) }, { HP_POP(clif->pPing, HP_clif_pPing) }, { HP_POP(clif->ping, HP_clif_ping) }, @@ -1241,7 +1245,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(duel->reject, HP_duel_reject) }, { HP_POP(duel->leave, HP_duel_leave) }, { HP_POP(duel->showinfo, HP_duel_showinfo) }, - { HP_POP(duel->checktime, HP_duel_checktime) }, + { HP_POP(duel->difftime, HP_duel_difftime) }, { HP_POP(duel->init, HP_duel_init) }, { HP_POP(duel->final, HP_duel_final) }, /* elemental_interface */ @@ -2188,6 +2192,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(npc->unload_ev_label, HP_npc_unload_ev_label) }, { HP_POP(npc->unload_dup_sub, HP_npc_unload_dup_sub) }, { HP_POP(npc->unload_duplicates, HP_npc_unload_duplicates) }, + { HP_POP(npc->unload_mob, HP_npc_unload_mob) }, { HP_POP(npc->unload, HP_npc_unload) }, { HP_POP(npc->clearsrcfile, HP_npc_clearsrcfile) }, { HP_POP(npc->addsrcfile, HP_npc_addsrcfile) }, @@ -2239,6 +2244,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(npc->trader_update, HP_npc_trader_update) }, { HP_POP(npc->market_buylist, HP_npc_market_buylist) }, { HP_POP(npc->barter_buylist, HP_npc_barter_buylist) }, + { HP_POP(npc->expanded_barter_buylist, HP_npc_expanded_barter_buylist) }, { HP_POP(npc->trader_open, HP_npc_trader_open) }, { HP_POP(npc->market_fromsql, HP_npc_market_fromsql) }, { HP_POP(npc->market_tosql, HP_npc_market_tosql) }, @@ -2248,6 +2254,10 @@ struct HookingPointData HookingPoints[] = { { HP_POP(npc->barter_tosql, HP_npc_barter_tosql) }, { HP_POP(npc->barter_delfromsql, HP_npc_barter_delfromsql) }, { HP_POP(npc->barter_delfromsql_sub, HP_npc_barter_delfromsql_sub) }, + { HP_POP(npc->expanded_barter_fromsql, HP_npc_expanded_barter_fromsql) }, + { HP_POP(npc->expanded_barter_tosql, HP_npc_expanded_barter_tosql) }, + { HP_POP(npc->expanded_barter_delfromsql, HP_npc_expanded_barter_delfromsql) }, + { HP_POP(npc->expanded_barter_delfromsql_sub, HP_npc_expanded_barter_delfromsql_sub) }, { HP_POP(npc->db_checkid, HP_npc_db_checkid) }, { HP_POP(npc->refresh, HP_npc_refresh) }, { HP_POP(npc->questinfo_clear, HP_npc_questinfo_clear) }, @@ -2888,6 +2898,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(script->run_item_rental_end_script, HP_script_run_item_rental_end_script) }, { HP_POP(script->run_item_rental_start_script, HP_script_run_item_rental_start_script) }, { HP_POP(script->run_item_lapineddukddak_script, HP_script_run_item_lapineddukddak_script) }, + { HP_POP(script->sellitemcurrency_add, HP_script_sellitemcurrency_add) }, /* searchstore_interface */ { HP_POP(searchstore->open, HP_searchstore_open) }, { HP_POP(searchstore->query, HP_searchstore_query) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index e24b00f78..78702bedb 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -14402,6 +14402,32 @@ void HP_clif_changeoption(struct block_list *bl) { } return; } +void HP_clif_changeoption_target(struct block_list *bl, struct block_list *target_bl, enum send_target target) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_changeoption_target_pre > 0) { + void (*preHookFunc) (struct block_list **bl, struct block_list **target_bl, enum send_target *target); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_changeoption_target_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_changeoption_target_pre[hIndex].func; + preHookFunc(&bl, &target_bl, &target); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.changeoption_target(bl, target_bl, target); + } + if (HPMHooks.count.HP_clif_changeoption_target_post > 0) { + void (*postHookFunc) (struct block_list *bl, struct block_list *target_bl, enum send_target target); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_changeoption_target_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_changeoption_target_post[hIndex].func; + postHookFunc(bl, target_bl, target); + } + } + return; +} void HP_clif_changeoption2(struct block_list *bl) { int hIndex = 0; if (HPMHooks.count.HP_clif_changeoption2_pre > 0) { @@ -30003,6 +30029,84 @@ void HP_clif_pNPCBarterPurchase(int fd, struct map_session_data *sd) { } return; } +void HP_clif_pNPCExpandedBarterClosed(int fd, struct map_session_data *sd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_pNPCExpandedBarterClosed_pre > 0) { + void (*preHookFunc) (int *fd, struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCExpandedBarterClosed_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pNPCExpandedBarterClosed_pre[hIndex].func; + preHookFunc(&fd, &sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pNPCExpandedBarterClosed(fd, sd); + } + if (HPMHooks.count.HP_clif_pNPCExpandedBarterClosed_post > 0) { + void (*postHookFunc) (int fd, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCExpandedBarterClosed_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pNPCExpandedBarterClosed_post[hIndex].func; + postHookFunc(fd, sd); + } + } + return; +} +void HP_clif_pNPCExpandedBarterPurchase(int fd, struct map_session_data *sd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_pNPCExpandedBarterPurchase_pre > 0) { + void (*preHookFunc) (int *fd, struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCExpandedBarterPurchase_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pNPCExpandedBarterPurchase_pre[hIndex].func; + preHookFunc(&fd, &sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pNPCExpandedBarterPurchase(fd, sd); + } + if (HPMHooks.count.HP_clif_pNPCExpandedBarterPurchase_post > 0) { + void (*postHookFunc) (int fd, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCExpandedBarterPurchase_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pNPCExpandedBarterPurchase_post[hIndex].func; + postHookFunc(fd, sd); + } + } + return; +} +void HP_clif_npc_expanded_barter_open(struct map_session_data *sd, struct npc_data *nd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_npc_expanded_barter_open_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, struct npc_data **nd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_npc_expanded_barter_open_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_npc_expanded_barter_open_pre[hIndex].func; + preHookFunc(&sd, &nd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.npc_expanded_barter_open(sd, nd); + } + if (HPMHooks.count.HP_clif_npc_expanded_barter_open_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, struct npc_data *nd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_npc_expanded_barter_open_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_npc_expanded_barter_open_post[hIndex].func; + postHookFunc(sd, nd); + } + } + return; +} void HP_clif_pClientVersion(int fd, struct map_session_data *sd) { int hIndex = 0; if (HPMHooks.count.HP_clif_pClientVersion_pre > 0) { @@ -31601,14 +31705,14 @@ void HP_duel_showinfo(const unsigned int did, struct map_session_data *sd) { } return; } -int HP_duel_checktime(struct map_session_data *sd) { +int64 HP_duel_difftime(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; - if (HPMHooks.count.HP_duel_checktime_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd); + int64 retVal___ = 0; + if (HPMHooks.count.HP_duel_difftime_pre > 0) { + int64 (*preHookFunc) (struct map_session_data **sd); *HPMforce_return = false; - for (hIndex = 0; hIndex < HPMHooks.count.HP_duel_checktime_pre; hIndex++) { - preHookFunc = HPMHooks.list.HP_duel_checktime_pre[hIndex].func; + for (hIndex = 0; hIndex < HPMHooks.count.HP_duel_difftime_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_duel_difftime_pre[hIndex].func; retVal___ = preHookFunc(&sd); } if (*HPMforce_return) { @@ -31617,12 +31721,12 @@ int HP_duel_checktime(struct map_session_data *sd) { } } { - retVal___ = HPMHooks.source.duel.checktime(sd); + retVal___ = HPMHooks.source.duel.difftime(sd); } - if (HPMHooks.count.HP_duel_checktime_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); - for (hIndex = 0; hIndex < HPMHooks.count.HP_duel_checktime_post; hIndex++) { - postHookFunc = HPMHooks.list.HP_duel_checktime_post[hIndex].func; + if (HPMHooks.count.HP_duel_difftime_post > 0) { + int64 (*postHookFunc) (int64 retVal___, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_duel_difftime_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_duel_difftime_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); } } @@ -51949,15 +52053,15 @@ int HP_mob_parse_dataset(struct spawn_data *data) { } return retVal___; } -struct mob_data* HP_mob_spawn_dataset(struct spawn_data *data) { +struct mob_data* HP_mob_spawn_dataset(struct spawn_data *data, int npc_id) { int hIndex = 0; struct mob_data* retVal___ = NULL; if (HPMHooks.count.HP_mob_spawn_dataset_pre > 0) { - struct mob_data* (*preHookFunc) (struct spawn_data **data); + struct mob_data* (*preHookFunc) (struct spawn_data **data, int *npc_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_dataset_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mob_spawn_dataset_pre[hIndex].func; - retVal___ = preHookFunc(&data); + retVal___ = preHookFunc(&data, &npc_id); } if (*HPMforce_return) { *HPMforce_return = false; @@ -51965,13 +52069,13 @@ struct mob_data* HP_mob_spawn_dataset(struct spawn_data *data) { } } { - retVal___ = HPMHooks.source.mob.spawn_dataset(data); + retVal___ = HPMHooks.source.mob.spawn_dataset(data, npc_id); } if (HPMHooks.count.HP_mob_spawn_dataset_post > 0) { - struct mob_data* (*postHookFunc) (struct mob_data* retVal___, struct spawn_data *data); + struct mob_data* (*postHookFunc) (struct mob_data* retVal___, struct spawn_data *data, int npc_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_dataset_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mob_spawn_dataset_post[hIndex].func; - retVal___ = postHookFunc(retVal___, data); + retVal___ = postHookFunc(retVal___, data, npc_id); } } return retVal___; @@ -52030,15 +52134,15 @@ bool HP_mob_ksprotected(struct block_list *src, struct block_list *target) { } return retVal___; } -struct mob_data* HP_mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai) { +struct mob_data* HP_mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai, int npc_id) { int hIndex = 0; struct mob_data* retVal___ = NULL; if (HPMHooks.count.HP_mob_once_spawn_sub_pre > 0) { - struct mob_data* (*preHookFunc) (struct block_list **bl, int16 *m, int16 *x, int16 *y, const char **mobname, int *class_, const char **event, unsigned int *size, unsigned int *ai); + struct mob_data* (*preHookFunc) (struct block_list **bl, int16 *m, int16 *x, int16 *y, const char **mobname, int *class_, const char **event, unsigned int *size, unsigned int *ai, int *npc_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_once_spawn_sub_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mob_once_spawn_sub_pre[hIndex].func; - retVal___ = preHookFunc(&bl, &m, &x, &y, &mobname, &class_, &event, &size, &ai); + retVal___ = preHookFunc(&bl, &m, &x, &y, &mobname, &class_, &event, &size, &ai, &npc_id); } if (*HPMforce_return) { *HPMforce_return = false; @@ -52046,13 +52150,13 @@ struct mob_data* HP_mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, } } { - retVal___ = HPMHooks.source.mob.once_spawn_sub(bl, m, x, y, mobname, class_, event, size, ai); + retVal___ = HPMHooks.source.mob.once_spawn_sub(bl, m, x, y, mobname, class_, event, size, ai, npc_id); } if (HPMHooks.count.HP_mob_once_spawn_sub_post > 0) { - struct mob_data* (*postHookFunc) (struct mob_data* retVal___, struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai); + struct mob_data* (*postHookFunc) (struct mob_data* retVal___, struct block_list *bl, int16 m, int16 x, int16 y, const char *mobname, int class_, const char *event, unsigned int size, unsigned int ai, int npc_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_once_spawn_sub_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mob_once_spawn_sub_post[hIndex].func; - retVal___ = postHookFunc(retVal___, bl, m, x, y, mobname, class_, event, size, ai); + retVal___ = postHookFunc(retVal___, bl, m, x, y, mobname, class_, event, size, ai, npc_id); } } return retVal___; @@ -52111,15 +52215,15 @@ int HP_mob_once_spawn_area(struct map_session_data *sd, int16 m, int16 x0, int16 } return retVal___; } -int HP_mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index) { +int HP_mob_spawn_guardian(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index, int npc_id) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_mob_spawn_guardian_pre > 0) { - int (*preHookFunc) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, int *guardian, bool *has_index); + int (*preHookFunc) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, int *guardian, bool *has_index, int *npc_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_guardian_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mob_spawn_guardian_pre[hIndex].func; - retVal___ = preHookFunc(&mapname, &x, &y, &mobname, &class_, &event, &guardian, &has_index); + retVal___ = preHookFunc(&mapname, &x, &y, &mobname, &class_, &event, &guardian, &has_index, &npc_id); } if (*HPMforce_return) { *HPMforce_return = false; @@ -52127,26 +52231,26 @@ int HP_mob_spawn_guardian(const char *mapname, short x, short y, const char *mob } } { - retVal___ = HPMHooks.source.mob.spawn_guardian(mapname, x, y, mobname, class_, event, guardian, has_index); + retVal___ = HPMHooks.source.mob.spawn_guardian(mapname, x, y, mobname, class_, event, guardian, has_index, npc_id); } if (HPMHooks.count.HP_mob_spawn_guardian_post > 0) { - int (*postHookFunc) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index); + int (*postHookFunc) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, int guardian, bool has_index, int npc_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_guardian_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mob_spawn_guardian_post[hIndex].func; - retVal___ = postHookFunc(retVal___, mapname, x, y, mobname, class_, event, guardian, has_index); + retVal___ = postHookFunc(retVal___, mapname, x, y, mobname, class_, event, guardian, has_index, npc_id); } } return retVal___; } -int HP_mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id) { +int HP_mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id, int npc_id) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_mob_spawn_bg_pre > 0) { - int (*preHookFunc) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, unsigned int *bg_id); + int (*preHookFunc) (const char **mapname, short *x, short *y, const char **mobname, int *class_, const char **event, unsigned int *bg_id, int *npc_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_bg_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mob_spawn_bg_pre[hIndex].func; - retVal___ = preHookFunc(&mapname, &x, &y, &mobname, &class_, &event, &bg_id); + retVal___ = preHookFunc(&mapname, &x, &y, &mobname, &class_, &event, &bg_id, &npc_id); } if (*HPMforce_return) { *HPMforce_return = false; @@ -52154,13 +52258,13 @@ int HP_mob_spawn_bg(const char *mapname, short x, short y, const char *mobname, } } { - retVal___ = HPMHooks.source.mob.spawn_bg(mapname, x, y, mobname, class_, event, bg_id); + retVal___ = HPMHooks.source.mob.spawn_bg(mapname, x, y, mobname, class_, event, bg_id, npc_id); } if (HPMHooks.count.HP_mob_spawn_bg_post > 0) { - int (*postHookFunc) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id); + int (*postHookFunc) (int retVal___, const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id, int npc_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_bg_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mob_spawn_bg_post[hIndex].func; - retVal___ = postHookFunc(retVal___, mapname, x, y, mobname, class_, event, bg_id); + retVal___ = postHookFunc(retVal___, mapname, x, y, mobname, class_, event, bg_id, npc_id); } } return retVal___; @@ -56707,14 +56811,14 @@ int HP_npc_unload_dup_sub(struct npc_data *nd, va_list args) { } return retVal___; } -void HP_npc_unload_duplicates(struct npc_data *nd) { +void HP_npc_unload_duplicates(struct npc_data *nd, bool unload_mobs) { int hIndex = 0; if (HPMHooks.count.HP_npc_unload_duplicates_pre > 0) { - void (*preHookFunc) (struct npc_data **nd); + void (*preHookFunc) (struct npc_data **nd, bool *unload_mobs); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unload_duplicates_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_npc_unload_duplicates_pre[hIndex].func; - preHookFunc(&nd); + preHookFunc(&nd, &unload_mobs); } if (*HPMforce_return) { *HPMforce_return = false; @@ -56722,26 +56826,59 @@ void HP_npc_unload_duplicates(struct npc_data *nd) { } } { - HPMHooks.source.npc.unload_duplicates(nd); + HPMHooks.source.npc.unload_duplicates(nd, unload_mobs); } if (HPMHooks.count.HP_npc_unload_duplicates_post > 0) { - void (*postHookFunc) (struct npc_data *nd); + void (*postHookFunc) (struct npc_data *nd, bool unload_mobs); for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unload_duplicates_post; hIndex++) { postHookFunc = HPMHooks.list.HP_npc_unload_duplicates_post[hIndex].func; - postHookFunc(nd); + postHookFunc(nd, unload_mobs); } } return; } -int HP_npc_unload(struct npc_data *nd, bool single) { +int HP_npc_unload_mob(struct mob_data *md, va_list args) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_npc_unload_mob_pre > 0) { + int (*preHookFunc) (struct mob_data **md, va_list args); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unload_mob_pre; hIndex++) { + va_list args___copy; va_copy(args___copy, args); + preHookFunc = HPMHooks.list.HP_npc_unload_mob_pre[hIndex].func; + retVal___ = preHookFunc(&md, args___copy); + va_end(args___copy); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list args___copy; va_copy(args___copy, args); + retVal___ = HPMHooks.source.npc.unload_mob(md, args___copy); + va_end(args___copy); + } + if (HPMHooks.count.HP_npc_unload_mob_post > 0) { + int (*postHookFunc) (int retVal___, struct mob_data *md, va_list args); + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unload_mob_post; hIndex++) { + va_list args___copy; va_copy(args___copy, args); + postHookFunc = HPMHooks.list.HP_npc_unload_mob_post[hIndex].func; + retVal___ = postHookFunc(retVal___, md, args___copy); + va_end(args___copy); + } + } + return retVal___; +} +int HP_npc_unload(struct npc_data *nd, bool single, bool unload_mobs) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_npc_unload_pre > 0) { - int (*preHookFunc) (struct npc_data **nd, bool *single); + int (*preHookFunc) (struct npc_data **nd, bool *single, bool *unload_mobs); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unload_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_npc_unload_pre[hIndex].func; - retVal___ = preHookFunc(&nd, &single); + retVal___ = preHookFunc(&nd, &single, &unload_mobs); } if (*HPMforce_return) { *HPMforce_return = false; @@ -56749,13 +56886,13 @@ int HP_npc_unload(struct npc_data *nd, bool single) { } } { - retVal___ = HPMHooks.source.npc.unload(nd, single); + retVal___ = HPMHooks.source.npc.unload(nd, single, unload_mobs); } if (HPMHooks.count.HP_npc_unload_post > 0) { - int (*postHookFunc) (int retVal___, struct npc_data *nd, bool single); + int (*postHookFunc) (int retVal___, struct npc_data *nd, bool single, bool unload_mobs); for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unload_post; hIndex++) { postHookFunc = HPMHooks.list.HP_npc_unload_post[hIndex].func; - retVal___ = postHookFunc(retVal___, nd, single); + retVal___ = postHookFunc(retVal___, nd, single, unload_mobs); } } return retVal___; @@ -57870,15 +58007,15 @@ int HP_npc_reload(void) { } return retVal___; } -bool HP_npc_unloadfile(const char *filepath) { +bool HP_npc_unloadfile(const char *filepath, bool unload_mobs) { int hIndex = 0; bool retVal___ = false; if (HPMHooks.count.HP_npc_unloadfile_pre > 0) { - bool (*preHookFunc) (const char **filepath); + bool (*preHookFunc) (const char **filepath, bool *unload_mobs); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unloadfile_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_npc_unloadfile_pre[hIndex].func; - retVal___ = preHookFunc(&filepath); + retVal___ = preHookFunc(&filepath, &unload_mobs); } if (*HPMforce_return) { *HPMforce_return = false; @@ -57886,13 +58023,13 @@ bool HP_npc_unloadfile(const char *filepath) { } } { - retVal___ = HPMHooks.source.npc.unloadfile(filepath); + retVal___ = HPMHooks.source.npc.unloadfile(filepath, unload_mobs); } if (HPMHooks.count.HP_npc_unloadfile_post > 0) { - bool (*postHookFunc) (bool retVal___, const char *filepath); + bool (*postHookFunc) (bool retVal___, const char *filepath, bool unload_mobs); for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_unloadfile_post; hIndex++) { postHookFunc = HPMHooks.list.HP_npc_unloadfile_post[hIndex].func; - retVal___ = postHookFunc(retVal___, filepath); + retVal___ = postHookFunc(retVal___, filepath, unload_mobs); } } return retVal___; @@ -58109,6 +58246,33 @@ int HP_npc_barter_buylist(struct map_session_data *sd, struct barteritemlist *it } return retVal___; } +int HP_npc_expanded_barter_buylist(struct map_session_data *sd, struct barteritemlist *item_list) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_npc_expanded_barter_buylist_pre > 0) { + int (*preHookFunc) (struct map_session_data **sd, struct barteritemlist **item_list); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_buylist_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_npc_expanded_barter_buylist_pre[hIndex].func; + retVal___ = preHookFunc(&sd, &item_list); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.expanded_barter_buylist(sd, item_list); + } + if (HPMHooks.count.HP_npc_expanded_barter_buylist_post > 0) { + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct barteritemlist *item_list); + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_buylist_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_npc_expanded_barter_buylist_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, item_list); + } + } + return retVal___; +} bool HP_npc_trader_open(struct map_session_data *sd, struct npc_data *nd) { int hIndex = 0; bool retVal___ = false; @@ -58344,6 +58508,110 @@ void HP_npc_barter_delfromsql_sub(const char *npcname, int itemId, int itemId2, } return; } +void HP_npc_expanded_barter_fromsql(void) { + int hIndex = 0; + if (HPMHooks.count.HP_npc_expanded_barter_fromsql_pre > 0) { + void (*preHookFunc) (void); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_fromsql_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_npc_expanded_barter_fromsql_pre[hIndex].func; + preHookFunc(); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.expanded_barter_fromsql(); + } + if (HPMHooks.count.HP_npc_expanded_barter_fromsql_post > 0) { + void (*postHookFunc) (void); + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_fromsql_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_npc_expanded_barter_fromsql_post[hIndex].func; + postHookFunc(); + } + } + return; +} +void HP_npc_expanded_barter_tosql(struct npc_data *nd, int index) { + int hIndex = 0; + if (HPMHooks.count.HP_npc_expanded_barter_tosql_pre > 0) { + void (*preHookFunc) (struct npc_data **nd, int *index); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_tosql_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_npc_expanded_barter_tosql_pre[hIndex].func; + preHookFunc(&nd, &index); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.expanded_barter_tosql(nd, index); + } + if (HPMHooks.count.HP_npc_expanded_barter_tosql_post > 0) { + void (*postHookFunc) (struct npc_data *nd, int index); + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_tosql_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_npc_expanded_barter_tosql_post[hIndex].func; + postHookFunc(nd, index); + } + } + return; +} +void HP_npc_expanded_barter_delfromsql(struct npc_data *nd, int index) { + int hIndex = 0; + if (HPMHooks.count.HP_npc_expanded_barter_delfromsql_pre > 0) { + void (*preHookFunc) (struct npc_data **nd, int *index); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_delfromsql_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_npc_expanded_barter_delfromsql_pre[hIndex].func; + preHookFunc(&nd, &index); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.expanded_barter_delfromsql(nd, index); + } + if (HPMHooks.count.HP_npc_expanded_barter_delfromsql_post > 0) { + void (*postHookFunc) (struct npc_data *nd, int index); + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_delfromsql_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_npc_expanded_barter_delfromsql_post[hIndex].func; + postHookFunc(nd, index); + } + } + return; +} +void HP_npc_expanded_barter_delfromsql_sub(const char *npcname, int itemId, int zeny, int currencyCount, struct npc_barter_currency *currency) { + int hIndex = 0; + if (HPMHooks.count.HP_npc_expanded_barter_delfromsql_sub_pre > 0) { + void (*preHookFunc) (const char **npcname, int *itemId, int *zeny, int *currencyCount, struct npc_barter_currency **currency); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_delfromsql_sub_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_npc_expanded_barter_delfromsql_sub_pre[hIndex].func; + preHookFunc(&npcname, &itemId, &zeny, ¤cyCount, ¤cy); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.expanded_barter_delfromsql_sub(npcname, itemId, zeny, currencyCount, currency); + } + if (HPMHooks.count.HP_npc_expanded_barter_delfromsql_sub_post > 0) { + void (*postHookFunc) (const char *npcname, int itemId, int zeny, int currencyCount, struct npc_barter_currency *currency); + for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_expanded_barter_delfromsql_sub_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_npc_expanded_barter_delfromsql_sub_post[hIndex].func; + postHookFunc(npcname, itemId, zeny, currencyCount, currency); + } + } + return; +} bool HP_npc_db_checkid(const int id) { int hIndex = 0; bool retVal___ = false; @@ -63465,14 +63733,14 @@ void HP_pc_setridingpeco(struct map_session_data *sd, bool flag) { } return; } -void HP_pc_setmadogear(struct map_session_data *sd, bool flag) { +void HP_pc_setmadogear(struct map_session_data *sd, bool flag, enum mado_type mtype) { int hIndex = 0; if (HPMHooks.count.HP_pc_setmadogear_pre > 0) { - void (*preHookFunc) (struct map_session_data **sd, bool *flag); + void (*preHookFunc) (struct map_session_data **sd, bool *flag, enum mado_type *mtype); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_setmadogear_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_pc_setmadogear_pre[hIndex].func; - preHookFunc(&sd, &flag); + preHookFunc(&sd, &flag, &mtype); } if (*HPMforce_return) { *HPMforce_return = false; @@ -63480,13 +63748,13 @@ void HP_pc_setmadogear(struct map_session_data *sd, bool flag) { } } { - HPMHooks.source.pc.setmadogear(sd, flag); + HPMHooks.source.pc.setmadogear(sd, flag, mtype); } if (HPMHooks.count.HP_pc_setmadogear_post > 0) { - void (*postHookFunc) (struct map_session_data *sd, bool flag); + void (*postHookFunc) (struct map_session_data *sd, bool flag, enum mado_type mtype); for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_setmadogear_post; hIndex++) { postHookFunc = HPMHooks.list.HP_pc_setmadogear_post[hIndex].func; - postHookFunc(sd, flag); + postHookFunc(sd, flag, mtype); } } return; @@ -75306,6 +75574,33 @@ void HP_script_run_item_lapineddukddak_script(struct map_session_data *sd, struc } return; } +bool HP_script_sellitemcurrency_add(struct npc_data *nd, struct script_state *st, int argIndex) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_script_sellitemcurrency_add_pre > 0) { + bool (*preHookFunc) (struct npc_data **nd, struct script_state **st, int *argIndex); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_script_sellitemcurrency_add_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_script_sellitemcurrency_add_pre[hIndex].func; + retVal___ = preHookFunc(&nd, &st, &argIndex); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.sellitemcurrency_add(nd, st, argIndex); + } + if (HPMHooks.count.HP_script_sellitemcurrency_add_post > 0) { + bool (*postHookFunc) (bool retVal___, struct npc_data *nd, struct script_state *st, int argIndex); + for (hIndex = 0; hIndex < HPMHooks.count.HP_script_sellitemcurrency_add_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_script_sellitemcurrency_add_post[hIndex].func; + retVal___ = postHookFunc(retVal___, nd, st, argIndex); + } + } + return retVal___; +} /* searchstore_interface */ bool HP_searchstore_open(struct map_session_data *sd, unsigned int uses, unsigned short effect) { int hIndex = 0; |