diff options
60 files changed, 4853 insertions, 874 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 97cbf5bfc..3bcb8b3f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,44 @@ and this project does not adhere to [Semantic Versioning](http://semver.org/spec If you are reading this in a text editor, simply ignore this section --> +## [v2020.05.03] `May 03 2020` + +### Added + +- Added the new pets (including the jRO exclusive ones) and their related items/monsters to the renewal database. (#2689) +- Added constants `ALL_MOBS_NONBOSS`, `ALL_MOBS_BOSS`, `ALL_MOBS` for the special mob IDs for global skill assignment in the mob skill database. (part of #2691) +- Added support for `__func__` on Windows, since it's now available in every supported compiler. (part of #2691) +- Added documentation for the mob skill database. See `doc/mob_skill_db.conf`. (#2680) +- Added missing functions for the name ack packets for `BL_ITEM` and `BL_SKILL`. (part of #2695) +- Added/updated packets and encryption keys for clients up to 2020-04-14. (#2695) +- Added support for packets `ZC_LAPINEUPGRADE_OPEN`, `CZ_LAPINEUPGRADE_CLOSE` and `ZC_LAPINEUPGRADE_RESULT` and a placeholder for `CZ_LAPINEUPGRADE_MAKE_ITEM`. (part of #2695) +- Added a new cell type `cell_noskill`, to block skill usage. (#2188) + +### Changed + +- Removed warning messages about missing elements in the mob db, since it's an optional field. (part of #2689) +- Updated the renewal pet database with the correct values and bonuses. (part of #2689, issue #2435) +- Changed `mob_getfriendstatus()` to consider character as friends of their support monsters, for consistency with `mob_getfriendhprate()`. (part of #2691) +- Changed `MSC_AFTERSKILL` to trigger on any skill when its `ConditionData` is 0, for consistency with `MSC_SKILLUSED`. (part of #2691) +- Improved data validation and error reporting in the mob skill database. (part of #2691) +- Changed return values of `mob_skill_use()` and `mobskill_event()`. Any third party code that uses them needs to be updated. (part of #2691) +- Changed the battle configuration flag `manner_system` to be applied immediately to any existing `SC_NOCHAT`. (#2696, issue #227) +- Changed the `atcommand()` command to ignore `PCBLOCK_COMMANDS`. (#2062) + +### Fixed + +- Fixed `SC_AUTOTRADE`, `SC_KSPROTECTED` and `SC_NO_SWITCH_EQUIP` incorrectly recognized as unknown status changes. (#2686, issue #2684) +- Prevented `SC_KSPROTECTED` from starting on dead monsters. (part of #2686) +- Fixed character unhiding while disguised or when using `@option 0`. (#2687, issues #1556 and #2104) +- Fixed an incorrect order of operations causing results too small in various calculations related to free cell search, mob skill chances/delays, exp penalty, pet hunger and friendly rates, cast duration. (#2690) +- Fixed errors caused by `pet_ai_sub_hard()` called for monsters that haven't been added to a map yet. (#2693) +- Fixed a wrong packet error displayed when using an incorrect password for the char-login connection. (part of #2695) +- Fixed a security check in the lapine ack packet handler. (part of #2695) +- Fixed some incorrect assumptions about the skill index values, causing the Bard/Dancer soul link to grant the wrong skills. (#2710, issue #2670) +- Fixed some conditions that could cause a skill to be attempted to save to the database with a negative skill level, resulting in query errors and data loss. (part of #2710) +- Fixed the skill type of `RK_DRAGONBREATH` and `RK_DRAGONBREATH_WATER` to be `BF_WEAPON` and support the `bLongAtkRate` bonus. (#1304) +- Fixed `SC_TELEKINESIS_INTENSE` to add percent MATK instead of fixed MATK. (part of #1304) + ## [v2020.04.05] `April 05 2020` `PATCH 1` ### Fixed @@ -1322,7 +1360,8 @@ If you are reading this in a text editor, simply ignore this section - New versioning scheme and project changelogs/release notes (#1853) [Unreleased]: https://github.com/HerculesWS/Hercules/compare/stable...master -[v2020.04.05]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05...v2020.04.05+1 +[v2020.05.03]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05+1...v2020.05.03 +[v2020.04.05+1]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05...v2020.04.05+1 [v2020.04.05]: https://github.com/HerculesWS/Hercules/compare/v2020.03.08+2...v2020.04.05 [v2020.03.08+2]: https://github.com/HerculesWS/Hercules/compare/v2020.03.08+1...v2020.03.08+2 [v2020.03.08+1]: https://github.com/HerculesWS/Hercules/compare/v2020.03.08...v2020.03.08+1 diff --git a/db/constants.conf b/db/constants.conf index 9b11a43e9..6f8030a45 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -428,17 +428,20 @@ constants_db: { mf_nogstorage: 60 comment__: "Cell Properties" - cell_walkable: 0 - cell_shootable: 1 - cell_water: 2 - cell_npc: 3 - cell_basilica: 4 - cell_landprotector: 5 - cell_novending: 6 - cell_nochat: 7 + cell_walkable: 0 + cell_shootable: 1 + cell_water: 2 + cell_npc: 3 + cell_basilica: 4 + cell_landprotector: 5 + cell_novending: 6 + cell_nochat: 7 + cell_icewall: 8 + cell_noicewall: 9 + cell_noskill: 10 comment__: "Cell checks" - //cell_gettype: 0 + cell_gettype: 0 cell_chkwall: 1 cell_chkwater: 2 cell_chkcliff: 3 @@ -446,12 +449,15 @@ constants_db: { cell_chkreach: 5 cell_chknopass: 6 cell_chknoreach: 7 - //cell_chkstack: 8 + cell_chkstack: 8 cell_chknpc: 9 cell_chkbasilica: 10 cell_chklandprotector: 11 cell_chknovending: 12 cell_chknochat: 13 + cell_chkicewall: 14 + cell_chknoicewall: 15 + cell_chknoskill: 16 comment__: "Bonuses / Parameter IDs" bMaxHP: 6 diff --git a/db/mob_db2.conf b/db/mob_db2.conf index 8cc1a1459..ef3b631f2 100644 --- a/db/mob_db2.conf +++ b/db/mob_db2.conf @@ -57,9 +57,9 @@ mob_db: ( } ViewRange: view range (int, defaults to 1) ChaseRange: chase range (int, defaults to 1) - Size: size (int, defaults to 1) - Race: race (int, defaults to 0) - Element: (type, level) + Size: size (string, defaults to "Size_Small") + Race: race (string, defaults to "RC_Formless") + Element: (type, level) (string/int, defaults to "Ele_Neutral"/1) Mode: { CanMove: true/false (bool, defaults to false) Looter: true/false (bool, defaults to false) diff --git a/db/mob_skill_db2.conf b/db/mob_skill_db2.conf index 6a732ff2d..de4b014fa 100644 --- a/db/mob_skill_db2.conf +++ b/db/mob_skill_db2.conf @@ -36,20 +36,20 @@ mob_skill_db:( <Skill_Constant>: { ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob. SkillLevel: (int, defaults to 1) - SkillState: (int, defaults to 0) - SkillTarget: (int, defaults to 0) + SkillState: (string, defaults to "MSS_ANY") + SkillTarget: (string, defaults to "MST_TARGET") Rate: (int, defaults to 1) CastTime: (int, defaults to 0) Delay: (int, defaults to 0) Cancelable: (boolean, defaults to false) - CastCondition: (int, defaults to 0) + CastCondition: (string, defaults to "MSC_ALWAYS") ConditionData: (int, defaults to 0) val0: (int, defaults to 0) val1: (int, defaults to 0) val2: (int, defaults to 0) val3: (int, defaults to 0) val4: (int, defaults to 0) - Emotion: (int, defaults to 0) + Emotion: (int, defaults to -1) ChatMsgID: (int, defaults to 0) } } diff --git a/db/pet_db2.conf b/db/pet_db2.conf index d6862da32..235e41c0b 100644 --- a/db/pet_db2.conf +++ b/db/pet_db2.conf @@ -34,30 +34,39 @@ pet_db:( { // ================ Mandatory fields ============================== Id: ID (int) - SpriteName: "Sprite_Name" (string) Name: "Pet Name" (string) + EggItem: "Egg Item Constant" (string) // ================ Optional fields =============================== - TamingItem: Taming Item (string, defaults to 0) - EggItem: Egg Id (string, defaults to 0) - AccessoryItem: Equipment Id (string, defaults to 0) - FoodItem: Food Id (string, defaults to 0) - FoodEffectiveness: hunger points (int, defaults to 0) - HungerDelay: hunger time (int, defaults to 0) + TamingItem: "Taming Item Constant" (string, defaults to 0) + FoodItem: "Food Item Constant" (string, defaults to "Pet_Food" (ID=537)) + AccessoryItem: "Equipment Item Constant" (string, defaults to 0) + FoodEffectiveness: hunger points (int, defaults to 80) + HungerDelay: hunger time (int, defaults to 60) + HungerDecrement: hunger points (int, defaults to 1) Intimacy: { - Initial: start intimacy (int, defaults to 0) - FeedIncrement: feeding intimacy (int, defaults to 0) - OverFeedDecrement: overfeeding intimacy (int, defaults to 0) - OwnerDeathDecrement: owner die intimacy (int, defaults to 0) + Initial: start intimacy (int, defaults to 250) + FeedIncrement: feeding intimacy (int, defaults to 10) + OverFeedDecrement: overfeeding intimacy (int, defaults to 100) + OwnerDeathDecrement: owner die intimacy (int, defaults to 20) + StarvingDelay: starving time (int, defaults to 20) + StarvingDecrement: starving intimacy (int, defaults to 20) } - CaptureRate: capture rate (int, defaults to 0) - Speed: speed (int, defaults to 0) + CaptureRate: capture rate (int, defaults to 1000) + Speed: speed (int, defaults to 150) SpecialPerformance: true/false (boolean, defaults to false) TalkWithEmotes: convert talk (boolean, defaults to false) - AttackRate: attack rate (int, defaults to 0) - DefendRate: Defence attack (int, defaults to 0) - ChangeTargetRate: change target (int, defaults to 0) + AttackRate: attack rate (int, defaults to 300) + DefendRate: Defence attack (int, defaults to 300) + ChangeTargetRate: change target (int, defaults to 800) + AutoFeed: true/false (boolean, defaults to false) PetScript: <" Pet Script (can also be multi-line) "> EquipScript: <" Equip Script (can also be multi-line) "> + Evolve: { + EggID: { (string, Evolved Pet EggID) + Name: Amount (items required to perform evolution) + ... + } + } }, **************************************************************************/ // entries in this file will override the ones in /(pre-)re/pet_db.conf diff --git a/db/pre-re/item_db.conf b/db/pre-re/item_db.conf index 74aeaa460..493a758cc 100644 --- a/db/pre-re/item_db.conf +++ b/db/pre-re/item_db.conf @@ -67262,8 +67262,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_WATER, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_FIRE, 1200000, 20, -15); "> }, { @@ -67275,8 +67274,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_WATER, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_WIND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_WATER, 1200000, 20, -15); "> }, { @@ -67288,8 +67286,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_GROUND, 1200000, 20, -15); "> }, { @@ -67301,8 +67298,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_WIND, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_WIND, 1200000, 20, -15); "> }, { @@ -69503,10 +69499,7 @@ item_db: ( Type: "IT_USABLE" Weight: 10 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); + sc_start4(SC_ARMOR_RESIST, 300000, 20, 20, 20, 20); "> }, { diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf index 78e255f36..92fd149f3 100644 --- a/db/pre-re/mob_db.conf +++ b/db/pre-re/mob_db.conf @@ -57,9 +57,9 @@ mob_db: ( } ViewRange: view range (int, defaults to 1) ChaseRange: chase range (int, defaults to 1) - Size: size (string, defaults to "Size_Medium") + Size: size (string, defaults to "Size_Small") Race: race (string, defaults to "RC_Formless") - Element: (type, level) + Element: (type, level) (string/int, defaults to "Ele_Neutral"/1) Mode: { CanMove: true/false (bool, defaults to false) Looter: true/false (bool, defaults to false) diff --git a/db/pre-re/mob_skill_db.conf b/db/pre-re/mob_skill_db.conf index 11af05e98..b6e3af07f 100644 --- a/db/pre-re/mob_skill_db.conf +++ b/db/pre-re/mob_skill_db.conf @@ -36,20 +36,20 @@ mob_skill_db:( <Skill_Constant>: { ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob. SkillLevel: (int, defaults to 1) - SkillState: (int, defaults to 0) - SkillTarget: (int, defaults to 0) + SkillState: (string, defaults to "MSS_ANY") + SkillTarget: (string, defaults to "MST_TARGET") Rate: (int, defaults to 1) CastTime: (int, defaults to 0) Delay: (int, defaults to 0) Cancelable: (boolean, defaults to false) - CastCondition: (int, defaults to 0) + CastCondition: (string, defaults to "MSC_ALWAYS") ConditionData: (int, defaults to 0) val0: (int, defaults to 0) val1: (int, defaults to 0) val2: (int, defaults to 0) val3: (int, defaults to 0) val4: (int, defaults to 0) - Emotion: (int, defaults to 0) + Emotion: (int, defaults to -1) ChatMsgID: (int, defaults to 0) } } diff --git a/db/re/item_combo_db.conf b/db/re/item_combo_db.conf index 31630546a..668b4bac0 100644 --- a/db/re/item_combo_db.conf +++ b/db/re/item_combo_db.conf @@ -3221,4 +3221,12 @@ combo_db: ( bonus2 bVariableCastrate, "WL_JACKFROST", -.@r; "> }, +{ + Items: ["Rigid_Nightmare_Terror_Card", "Nightmare_Terror_Card"] + Script: <" bonus(bAtkRate, 10); "> +}, +{ + Items: ["Rigid_Nightmare_Terror_Card", "Nightmare_Card"] + Script: <" bonus(bMaxSPrate, 10); "> +}, ) diff --git a/db/re/item_db.conf b/db/re/item_db.conf index cf2bd7da2..408fb3ef8 100644 --- a/db/re/item_db.conf +++ b/db/re/item_db.conf @@ -70646,6 +70646,8 @@ item_db: ( Id: 6221 AegisName: "Mystic_Leaf_Cat_Ball" Name: "Mystic Hydra Ball" + Type: "IT_PETEGG" + Buy: 20 }, { Id: 6222 @@ -74426,6 +74428,18 @@ item_db: ( Weight: 10 }, { + Id: 6669 + AegisName: "Emerald_Leaf" + Name: "Emerald Leaf" + Weight: 10 +}, +{ + Id: 6670 + AegisName: "Log_" + Name: "Tree Log" + Weight: 10 +}, +{ Id: 6671 AegisName: "Geffen_Magic_Coin" Name: "Geffen Magic Tournament Coin" @@ -74540,6 +74554,30 @@ item_db: ( Weight: 10 }, { + Id: 6762 + AegisName: "Banana_Can" + Name: "Banana Can" + Weight: 10 +}, +{ + Id: 6763 + AegisName: "Spicy_Rice_Cake" + Name: "Spicy Rice Cake" + Weight: 10 +}, +{ + Id: 6764 + AegisName: "Hot_Dog" + Name: "Hot Dog" + Weight: 10 +}, +{ + Id: 6765 + AegisName: "Ferris_Wheel_Biscuit" + Name: "Ferris Wheel Biscuit" + Weight: 10 +}, +{ Id: 6804 AegisName: "ORGANIC_PUMPKIN" Name: "Organic Pumpkin" @@ -83636,6 +83674,48 @@ item_db: ( Buy: 20 }, { + Id: 9063 + AegisName: "Woodie_Egg" + Name: "Woodie Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9064 + AegisName: "Elephant_Egg" + Name: "Elephant Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9065 + AegisName: "Gorilla_Egg" + Name: "Gorilla Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9066 + AegisName: "Lion_Egg" + Name: "Lion Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9067 + AegisName: "Rhino_Egg" + Name: "Rhino Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9068 + AegisName: "Blue_Unicorn_Egg" + Name: "Blue Unicorn Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ Id: 9069 AegisName: "Mastering_Egg" Name: "Mastering Egg" @@ -83657,6 +83737,55 @@ item_db: ( Buy: 20 }, { + Id: 9074 + AegisName: "Rubylit_Egg" + Name: "Rubylit Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9075 + AegisName: "Sapphilit_Egg" + Name: "Sapphilit Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9076 + AegisName: "Emelit_Egg" + Name: "Emelit Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9077 + AegisName: "Topalit_Egg" + Name: "Topalit Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9078 + AegisName: "Amelit_Egg" + Name: "Amelit Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9079 + AegisName: "Mythlit_Egg" + Name: "Mythlit Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9080 + AegisName: "Tamadora_Egg" + Name: "Tamadora Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ Id: 9087 AegisName: "High_Orc_Egg" Name: "High Orc Egg" @@ -83844,6 +83973,76 @@ item_db: ( Name: "Ein_Ddbox" }, { + Id: 9115 + AegisName: "Bacsojin2_Egg_" + Name: "Bacsojin Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9116 + AegisName: "Rigid_Nightmare_Terror_Egg" + Name: "Rigid Nightmare Terror Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9117 + AegisName: "Contaminated_Wanderer_Egg" + Name: "Contaminated Wanderer Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9118 + AegisName: "Aliot_Egg" + Name: "Aliot Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9119 + AegisName: "Alicel_Egg" + Name: "Alicel Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9120 + AegisName: "Aliza_Egg" + Name: "Aliza Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9121 + AegisName: "Orc_Hero_Egg_" + Name: "Orc Hero Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9122 + AegisName: "Gloom_Under_Night_Egg" + Name: "Gloom Under Night Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9123 + AegisName: "Child_Admin_Beta_Egg" + Name: "Child Admin Beta Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ + Id: 9124 + AegisName: "Child_Admin_Alpha_Egg" + Name: "Child Admin Alpha Egg" + Type: "IT_PETEGG" + Buy: 20 +}, +{ Id: 9523 AegisName: "Metal_Rifine_Ticket" Name: "Metal_Rifine_Ticket" @@ -84139,9 +84338,32 @@ item_db: ( Buy: 20 }, { + Id: 10040 + AegisName: "Red_Bell_Necklace" + Name: "Red Bell Necklace" + Type: "IT_PETARMOR" + Buy: 20 +}, +{ Id: 10042 AegisName: "Dark_Mane" Name: "Dark_Mane" + Type: "IT_PETARMOR" + Buy: 20 +}, +{ + Id: 10043 + AegisName: "Little_Headdress_Beta" + Name: "Little Headdress Beta" + Type: "IT_PETARMOR" + Buy: 20 +}, +{ + Id: 10044 + AegisName: "Little_Headdress_Alpha" + Name: "Little Headdress Alpha" + Type: "IT_PETARMOR" + Buy: 20 }, //== Misc "Etc" Books ====================================== @@ -85340,6 +85562,14 @@ item_db: ( Script: <" itemheal rand(10,40),0; "> }, { + Id: 11605 + AegisName: "Cookie_Bat" + Name: "Cookie Bat" + Type: "IT_HEALING" + Weight: 50 + Script: <" itemheal(rand(50, 100), 0); "> +}, +{ Id: 11607 AegisName: "Crepe" Name: "Crepe" @@ -85375,6 +85605,13 @@ item_db: ( Name: "Sweet_Potato_" }, { + Id: 11616 + AegisName: "Yummy_Meat" + Name: "Yummy Meat" + Type: "IT_HEALING" + Weight: 50 +}, +{ Id: 11620 AegisName: "Bearopy" Name: "Bearopy" @@ -86901,8 +87138,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_WATER, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_FIRE, 1200000, 20, -15); "> }, { @@ -86914,8 +87150,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_WATER, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_WIND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_WATER, 1200000, 20, -15); "> }, { @@ -86927,8 +87162,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_FIRE, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_GROUND, 1200000, 20, -15); "> }, { @@ -86940,8 +87174,7 @@ item_db: ( Weight: 10 BuyingStore: true Script: <" - sc_start(SC_RESIST_PROPERTY_WIND, 1200000, 20); - sc_start(SC_RESIST_PROPERTY_GROUND, 1200000, -15, 10000, SCFLAG_NOAVOID | SCFLAG_NOICON); + sc_start2(SC_RESIST_PROPERTY_WIND, 1200000, 20, -15); "> }, { @@ -89165,10 +89398,7 @@ item_db: ( Type: "IT_USABLE" Weight: 10 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); + sc_start4(SC_ARMOR_RESIST, 300000, 20, 20, 20, 20); "> }, { @@ -148798,6 +149028,36 @@ item_db: ( Script: <" Zeny += rand(500, 550); "> }, { + Id: 23187 + AegisName: "Sap_Jelly" + Name: "Sap Jelly" + Type: "IT_USABLE" + Nouse: { + sitting: true + } + Script: <" pet(NINE_TAIL); "> +}, +{ + Id: 23188 + AegisName: "Unprocessed_Parts" + Name: "Unprocessed Parts" + Type: "IT_USABLE" + Nouse: { + sitting: true + } + Script: <" pet(GREMLIN); "> +}, +{ + Id: 23189 + AegisName: "SmallDoll_Needle" + Name: "Small Doll Needle" + Type: "IT_USABLE" + Nouse: { + sitting: true + } + Script: <" pet(TEDDY_BEAR); "> +}, +{ Id: 23242 AegisName: "Fried_Chicken" Name: "Fried_Chicken" @@ -153745,6 +154005,24 @@ item_db: ( Weight: 1200 }, { + Id: 25231 + AegisName: "Suspicious_Bottle" + Name: "Suspicious Bottle" + Weight: 10 +}, +{ + Id: 25232 + AegisName: "Cheap_Lubricant" + Name: "Cheap Lubricant" + Weight: 10 +}, +{ + Id: 25233 + AegisName: "Cotton_Tufts" + Name: "Cotton Tufts" + Weight: 10 +}, +{ Id: 25258 AegisName: "BrokenArrow" Name: "BrokenArrow" @@ -153790,6 +154068,12 @@ item_db: ( Name: "Mightysoul_Essence" }, { + Id: 25377 + AegisName: "Luxurious_Pet_Food" + Name: "Luxurious Pet Food" + Weight: 1 +}, +{ Id: 25390 AegisName: "Captured_Savage" Name: "Captured_Savage" @@ -154585,6 +154869,29 @@ item_db: ( bonus2(bSkillAtk, RL_HAMMER_OF_GOD, getrefine() >= 10 ? 60 : 30); "> }, +{ + Id: 27352 + AegisName: "Rigid_Nightmare_Terror_Card" + Name: "Rigid Nightmare Terror Card" + Type: "IT_CARD" + Buy: 20 + Weight: 10 + Loc: "EQP_SHOES" + Script: <" bonus(bMaxSPrate, 5); "> +}, +{ + Id: 27361 + AegisName: "Contaminated_Wanderer_Card" + Name: "Contaminated Wanderer Card" + Type: "IT_CARD" + Buy: 20 + Weight: 10 + Loc: "EQP_WEAPON" + Script: <" + bonus2(bAddSize,Size_Medium, 30); + bonus2(bAddSize,Size_Large, 30); + "> +}, //== New Katars ============================================ { @@ -156454,6 +156761,19 @@ item_db: ( Name: "Shinee_Opal" }, { + Id: 31022 + AegisName: "Abandoned_Teddy_Bear_Card" + Name: "Abandoned Teddy Bear Card" + Type: "IT_CARD" + Buy: 20 + Weight: 10 + Loc: "EQP_SHOES" + Script: <" + bonus(bMaxSPrate, 20); + bonus2(bAddEff2, Eff_Curse, 20); + "> +}, +{ Id: 31172 AegisName: "Roast_Memory" Name: "Roast_Memory" @@ -157919,6 +158239,12 @@ item_db: ( Name: "ArchbishopStone_Robe2" }, { + Id: 1000103 + AegisName: "Barmil_Ticket" + Name: "Barmil Ticket" + Weight: 10 +}, +{ Id: 1000213 AegisName: "WarlockStone_Robe2" Name: "WarlockStone_Robe2" @@ -157978,4 +158304,10 @@ item_db: ( AegisName: "AssacrossStone_Bottom2" Name: "AssacrossStone_Bottom2" }, +{ + Id: 1000227 + AegisName: "Cloud_Cotton" + Name: "Cloud Cotton" + Weight: 10 +}, ) diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index 492b75a04..99518c461 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -57,9 +57,9 @@ mob_db: ( } ViewRange: view range (int, defaults to 1) ChaseRange: chase range (int, defaults to 1) - Size: size (string, defaults to "Size_Medium") + Size: size (string, defaults to "Size_Small") Race: race (string, defaults to "RC_Formless") - Element: (type, level) + Element: (type, level) (string/int, defaults to "Ele_Neutral"/1) Mode: { CanMove: true/false (bool, defaults to false) Looter: true/false (bool, defaults to false) @@ -83701,7 +83701,46 @@ mob_db: ( DamageMotion: 360 }, //2962,E_DEVILING -//2963,WOODIE +{ + Id: 2963 + SpriteName: "WOODIE" + Name: "Woodie" + Hp: 60 + Exp: 18 + JExp: 10 + Attack: [13, 3] + Def: 2 + Mdef: 5 + Stats: { + Str: 6 + Agi: 1 + Vit: 1 + Dex: 6 + Luk: 5 + } + ViewRange: 10 + ChaseRange: 12 + Race: "RC_Plant" + Element: ("Ele_Water", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 400 + AttackDelay: 1872 + AttackMotion: 672 + DamageMotion: 480 + Drops: { + Solid_Twig: 2000 + Resin: 2000 + Log: 2000 + Wooden_Block: 2000 + Oridecon_Stone: 200 + Log_: 5000 + Woodie_Card: 300 + } +}, //2964,EXP_1000 //2965,TW_APOCALIPS_H //2966,TW_B_EREMES @@ -83733,7 +83772,53 @@ mob_db: ( //2992,XM_LUDE //2993,XM_HYLOZOIST //2994,XM_MARIONETTE -//2995,XM_TEDDY_BEAR +{ + Id: 2995 + SpriteName: "XM_TEDDY_BEAR" + Name: "Abandoned Teddy Bear" + Lv: 148 + Hp: 180000 + Exp: 6666 + JExp: 7332 + Attack: [1347, 577] + Def: 106 + Mdef: 44 + Stats: { + Str: 44 + Agi: 166 + Vit: 44 + Int: 44 + Dex: 166 + Luk: 44 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Demon" + Element: ("Ele_Undead", 3) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + CanAttack: true + Detector: true + CastSensorChase: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 150 + AttackDelay: 512 + AttackMotion: 780 + DamageMotion: 504 + Drops: { + Screw: 1900 + Oridecon_Hammer: 150 + Str_Dish09: 100 + Runstone_Quality: 1000 + Runstone_Rare: 100 + Abandoned_Teddy_Bear_Card: 1 + } +}, { Id: 2996 SpriteName: "XM_CELINE_KIMI" @@ -84009,6 +84094,142 @@ mob_db: ( //3154,RECON_ROBOT //3155,REPAIR_ROBOT //3156,EXPLORATION_ROVER +{ + Id: 3162 + SpriteName: "ELEPHANT" + Name: "Elephant" + Lv: 48 + Hp: 1080 + Exp: 184 + JExp: 207 + Attack: [184, 48] + Def: 70 + Mdef: 30 + Stats: { + Str: 40 + Agi: 45 + Vit: 32 + Int: 19 + Dex: 42 + Luk: 20 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Brute" + Element: ("Ele_Fire", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 150 + AttackDelay: 1028 + AttackMotion: 528 + DamageMotion: 360 +}, +{ + Id: 3163 + SpriteName: "GORILLA" + Name: "Gorilla" + Lv: 48 + Hp: 1080 + Exp: 184 + JExp: 207 + Attack: [184, 48] + Def: 70 + Mdef: 30 + Stats: { + Str: 40 + Agi: 45 + Vit: 32 + Int: 19 + Dex: 42 + Luk: 20 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Brute" + Element: ("Ele_Fire", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 190 + AttackDelay: 1028 + AttackMotion: 528 + DamageMotion: 360 +}, +{ + Id: 3164 + SpriteName: "LION" + Name: "Lion" + Lv: 48 + Hp: 1080 + Exp: 184 + JExp: 207 + Attack: [184, 48] + Def: 70 + Mdef: 30 + Stats: { + Str: 40 + Agi: 45 + Vit: 32 + Int: 19 + Dex: 42 + Luk: 20 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Brute" + Element: ("Ele_Fire", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 150 + AttackDelay: 1028 + AttackMotion: 528 + DamageMotion: 360 +}, +{ + Id: 3165 + SpriteName: "RHINO" + Name: "Rhino" + Lv: 48 + Hp: 1080 + Exp: 184 + JExp: 207 + Attack: [184, 48] + Def: 70 + Mdef: 30 + Stats: { + Str: 40 + Agi: 45 + Vit: 32 + Int: 19 + Dex: 42 + Luk: 20 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Brute" + Element: ("Ele_Fire", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 150 + AttackDelay: 1028 + AttackMotion: 528 + DamageMotion: 360 +}, //3166,M_E_DEVILING { Id: 3169 @@ -84387,7 +84608,38 @@ mob_db: ( DamageMotion: 480 MvpExp: 0 },*/ - +{ + Id: 3261 + SpriteName: "BLUE_UNICORN" + Name: "Blue Unicorn" + Lv: 30 + Hp: 20 + Exp: 99 + JExp: 112 + Attack: [106, 29] + Def: 36 + Mdef: 17 + Stats: { + Str: 17 + Agi: 26 + Vit: 20 + Int: 18 + Dex: 36 + Luk: 5 + } + ViewRange: 10 + ChaseRange: 12 + Race: "RC_Plant" + Element: ("Ele_Poison", 1) + Mode: { + CanMove: true + CanAttack: true + } + MoveSpeed: 300 + AttackDelay: 1672 + AttackMotion: 672 + DamageMotion: 480 +}, //3295,G_MOBSTER //3296,HIDDEN_TEST //3297,PAD_LEVIATHAN @@ -84398,7 +84650,11 @@ mob_db: ( //3303,PAD_HELHEIM //3304,PAD_MUSPELHEIM //3305,PAD_ZAEROG -//3306,PAD_TAMADORA +{/* jRO exclusive pet. No stats required. */ + Id: 3306 + SpriteName: "PAD_TAMADORA" + Name: "Tamadora" +}, //3307,PAD_TAMADORABABY //3308,ROC_EMPELIUM //3309,ROC_OBJ_A @@ -84409,11 +84665,31 @@ mob_db: ( //3314,SMOKIE_THIEF //3315,PAD_KINGGOLD //3316,PAD_KINGMETAL -//3317,PAD_RUBYLIT -//3318,PAD_SAPPHILIT -//3319,PAD_EMELIT -//3320,PAD_TOPALIT -//3321,PAD_AMELIT +{/* jRO exclusive pet. No stats required. */ + Id: 3317 + SpriteName: "PAD_RUBYLIT" + Name: "Rubylit" +}, +{/* jRO exclusive pet. No stats required. */ + Id: 3318 + SpriteName: "PAD_SAPPHILIT" + Name: "Sapphilit" +}, +{/* jRO exclusive pet. No stats required. */ + Id: 3319 + SpriteName: "PAD_EMELIT" + Name: "Emelit" +}, +{/* jRO exclusive pet. No stats required. */ + Id: 3320 + SpriteName: "PAD_TOPALIT" + Name: "Topalit" +}, +{/* jRO exclusive pet. No stats required. */ + Id: 3321 + SpriteName: "PAD_AMELIT" + Name: "Amelit" +}, //3322,PAD_METAL_DRAGON //3323,PAD_M_FLAME_KNIGHT //3324,PAD_M_ICE_KNIGHT @@ -84441,7 +84717,11 @@ mob_db: ( //3346,PAD_SIREN_H //3347,PAD_LILITH_H //3348,PAD_HERA_H -//3349,PAD_MYTHLIT +{/* jRO exclusive pet. No stats required. */ + Id: 3349 + SpriteName: "PAD_MYTHLIT" + Name: "Mythlit" +}, //3350,PAD_TYRRA //3351,PAD_TYRANNOS //3352,PAD_PLESSIE @@ -84530,4 +84810,602 @@ mob_db: ( Captured_Soul: 4000 } }, +{ + Id: 3495 + SpriteName: "DR_EGGRING" + Name: "Eggring" + Hp: 50 + Exp: 50 + JExp: 35 + Attack: [7, 1] + Def: 2 + Mdef: 4 + Stats: { + Str: 6 + Agi: 1 + Vit: 1 + Dex: 6 + Luk: 4 + } + ViewRange: 10 + ChaseRange: 12 + Race: "RC_Plant" + Element: ("Ele_Earth", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 400 + AttackDelay: 1872 + AttackMotion: 672 + DamageMotion: 480 + Drops: { + Jellopy: 7000 + Apple: 1000 + Sticky_Mucus: 400 + Phracon: 30 + Wing_Of_Fly: 500 + Apple: 150 + Apple: 20 + Eggring_Card: 20 + } +}, +{ + Id: 3496 + SpriteName: "DR_LUNATIC" + Name: "Leaf Lunatic" + Lv: 3 + Hp: 44 + Exp: 50 + JExp: 35 + Attack: [12, 1] + Def: 16 + Stats: { + Str: 9 + Agi: 1 + Vit: 2 + Dex: 7 + Luk: 4 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Brute" + Element: ("Ele_Neutral", 3) + Mode: { + CanMove: true + CanAttack: true + } + MoveSpeed: 200 + AttackDelay: 1456 + AttackMotion: 456 + DamageMotion: 336 + Drops: { + Clover: 7000 + Feather: 3000 + Pierrot_Nose: 4 + Apple: 1000 + Wing_Of_Fly: 500 + Carrot: 3000 + Phracon: 30 + Leaf_Lunatic_Card: 10 + } +}, +{ + Id: 3636 + SpriteName: "LITTLE_ISIS" + Name: "Little Isis" + Lv: 59 + Hp: 2092 + Exp: 279 + JExp: 298 + Attack: [278, 81] + Def: 83 + Mdef: 5 + Stats: { + Str: 58 + Agi: 43 + Vit: 22 + Int: 5 + Dex: 43 + Luk: 15 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Large" + Race: "RC_Demon" + Element: ("Ele_Dark", 1) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + CanAttack: true + Detector: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 200 + AttackDelay: 1384 + AttackMotion: 768 + DamageMotion: 336 +}, +{ + Id: 3669 + SpriteName: "DIABOLIC2" + Name: "Diabolic2" + Lv: 104 + Hp: 10572 + Exp: 1086 + JExp: 1073 + Attack: [772, 283] + Def: 68 + Mdef: 61 + Stats: { + Str: 103 + Agi: 80 + Vit: 53 + Int: 65 + Dex: 94 + Luk: 25 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Demon" + Element: ("Ele_Dark", 2) + Mode: { + CanMove: true + Aggressive: true + CanAttack: true + Detector: true + Angry: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 150 + AttackDelay: 1080 + AttackMotion: 780 + DamageMotion: 180 +}, +{ + Id: 3670 + SpriteName: "DELETER_2" + Name: "Deleter 2" + Lv: 105 + Hp: 10000 + Exp: 1049 + JExp: 1038 + Attack: [733, 265] + Def: 114 + Mdef: 53 + Stats: { + Str: 98 + Agi: 72 + Vit: 65 + Int: 49 + Dex: 68 + Luk: 71 + } + ViewRange: 10 + ChaseRange: 12 + Race: "RC_Dragon" + Element: ("Ele_Fire", 2) + Mode: { + CanMove: true + Aggressive: true + Assist: true + CanAttack: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 175 + AttackDelay: 1024 + AttackMotion: 624 + DamageMotion: 336 +}, +{ + Id: 3731 + SpriteName: "SCATLETON" + Name: "Scatleton" + Lv: 14 + Hp: 140 + Attack: [50, 13] + Def: 13 + Stats: { + Str: 10 + Agi: 12 + Vit: 8 + Int: 5 + Dex: 17 + Luk: 7 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Demon" + Element: ("Ele_Dark", 1) + Mode: { + CanMove: true + Aggressive: true + CanAttack: true + } + MoveSpeed: 300 + AttackDelay: 1600 + AttackMotion: 900 + DamageMotion: 240 +}, +{ + Id: 3790 + SpriteName: "SWEETS_DROPS" + Name: "Sweets Drops" + Lv: 1 + Hp: 20 + Exp: 27 + JExp: 20 + Attack: [12, 1] + Def: 16 + Stats: { + Str: 1 + Agi: 1 + Vit: 1 + Int: 1 + Dex: 1 + Luk: 1 + } + ViewRange: 10 + ChaseRange: 12 + Race: "RC_Plant" + Element: ("Ele_Fire", 1) + Mode: { + CanMove: true + Looter: true + CanAttack: true + } + MoveSpeed: 440 + AttackDelay: 1372 + AttackMotion: 672 + DamageMotion: 480 +}, +{ + Id: 3971 + SpriteName: "SKELION" + Name: "Skelion" + Lv: 150 + Hp: 13000 + Exp: 594 + JExp: 669 + Attack: [222, 56] + Def: 88 + Mdef: 16 + Stats: { + Str: 25 + Agi: 16 + Vit: 12 + Int: 45 + Dex: 33 + Luk: 29 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Small" + Race: "RC_Formless" + Element: ("Ele_Neutral", 1) + Mode: { + CanMove: true + Aggressive: true + Boss: true + CanAttack: true + } + MoveSpeed: 150 + AttackDelay: 960 + AttackMotion: 864 + DamageMotion: 0 +}, +{ + Id: 20373 + SpriteName: "NIGHTMARE_TERROR_H" + Name: "Rigid Nightmare Terror" + Lv: 179 + Hp: 1523377 + Exp: 138489 + JExp: 96942 + Attack: [1709, 725] + Def: 242 + Mdef: 75 + Stats: { + Str: 81 + Agi: 149 + Vit: 21 + Int: 186 + Dex: 129 + Luk: 61 + } + ViewRange: 12 + ChaseRange: 10 + Size: "Size_Large" + Race: "RC_Demon" + Element: ("Ele_Dark", 3) + Mode: { + CanMove: true + Aggressive: true + CanAttack: true + Detector: true + Angry: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 165 + AttackDelay: 1216 + AttackMotion: 816 + DamageMotion: 432 + Drops: { + Rigid_Nightmare_Terror_Card: 10 + } +}, +{ + Id: 20420 + SpriteName: "WANDER_MAN_H" + Name: "Corrupted Wanderer" + Lv: 187 + Hp: 2387582 + Exp: 170542 + JExp: 119379 + Attack: [3654, 1645] + Def: 289 + Mdef: 102 + Stats: { + Str: 176 + Agi: 121 + Vit: 34 + Int: 67 + Dex: 139 + Luk: 77 + } + ViewRange: 10 + ChaseRange: 12 + Race: "RC_Demon" + Element: ("Ele_Wind", 2) + Mode: { + CanMove: true + Aggressive: true + CanAttack: true + Detector: true + Angry: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 100 + AttackDelay: 672 + AttackMotion: 500 + DamageMotion: 192 + Drops: { + Contaminated_Wanderer_Card: 10 + } +}, +{ + Id: 20423 + SpriteName: "BACSOJIN2" + Name: "Bacsojin" + Lv: 97 + Hp: 720500 + Sp: 1 + Exp: 801792 + JExp: 542880 + AttackRange: 3 + Attack: [1414, 2036] + Def: 210 + Mdef: 178 + Stats: { + Str: 118 + Agi: 244 + Vit: 98 + Int: 126 + Dex: 246 + Luk: 102 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Large" + Race: "RC_DemiHuman" + Element: ("Ele_Wind", 3) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + Boss: true + CanAttack: true + Detector: true + CastSensorChase: true + ChangeChase: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 130 + AttackDelay: 576 + AttackMotion: 960 + DamageMotion: 480 +}, +{ + Id: 20424 + SpriteName: "MOONLIGHT2" + Name: "Moonlight Flower" + Lv: 79 + Hp: 324000 + Sp: 1 + Exp: 367488 + JExp: 271440 + AttackRange: 1 + Attack: [2232, 1251] + Def: 254 + Mdef: 81 + Stats: { + Str: 86 + Agi: 102 + Vit: 93 + Int: 82 + Dex: 157 + Luk: 120 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Medium" + Race: "RC_Demon" + Element: ("Ele_Fire", 3) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + Boss: true + CanAttack: true + Detector: true + CastSensorChase: true + ChangeChase: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 150 + AttackDelay: 1276 + AttackMotion: 576 + DamageMotion: 288 +}, +{ + Id: 20425 + SpriteName: "PHREEONI2" + Name: "Phreeoni" + Lv: 71 + Hp: 300000 + Sp: 1 + Exp: 127600 + JExp: 180000 + AttackRange: 1 + Attack: [693, 967] + Def: 269 + Mdef: 98 + Stats: { + Str: 88 + Agi: 70 + Vit: 112 + Int: 87 + Dex: 122 + Luk: 71 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Large" + Race: "RC_Brute" + Element: ("Ele_Neutral", 3) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + Boss: true + CanAttack: true + Detector: true + CastSensorChase: true + ChangeChase: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 200 + AttackDelay: 1020 + AttackMotion: 1020 + DamageMotion: 288 +}, +{ + Id: 20571 + SpriteName: "ORK_HERO2" + Name: "Orc Hero" + Lv: 50 + Hp: 362000 + Sp: 1 + Exp: 106920 + JExp: 97200 + AttackRange: 1 + Attack: [662, 441] + Def: 197 + Mdef: 70 + Stats: { + Str: 97 + Agi: 82 + Vit: 107 + Int: 71 + Dex: 144 + Luk: 43 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Large" + Race: "RC_DemiHuman" + Element: ("Ele_Earth", 2) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + Boss: true + CanAttack: true + Detector: true + CastSensorChase: true + ChangeChase: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 150 + AttackDelay: 1678 + AttackMotion: 780 + DamageMotion: 648 +}, +{ + Id: 20619 + SpriteName: "GLOOMUNDERNIGHT2" + Name: "Gloom Under Night" + Lv: 139 + Hp: 3005000 + Sp: 1 + Exp: 2808000 + JExp: 1800000 + AttackRange: 3 + Attack: [6592, 2785] + Def: 479 + Mdef: 262 + Stats: { + Str: 191 + Agi: 223 + Vit: 187 + Int: 155 + Dex: 362 + Luk: 163 + } + ViewRange: 10 + ChaseRange: 12 + Size: "Size_Large" + Race: "RC_Formless" + Element: ("Ele_Ghost", 3) + Mode: { + CanMove: true + Aggressive: true + CastSensorIdle: true + Boss: true + CanAttack: true + Detector: true + CastSensorChase: true + ChangeChase: true + ChangeTargetMelee: true + ChangeTargetChase: true + } + MoveSpeed: 200 + AttackDelay: 1344 + AttackMotion: 2880 + DamageMotion: 576 +}, +{/** Needs info. No data found. Using dummy data for now to enable pet. **/ + Id: 20696 + SpriteName: "EP17_2_CHILD_ADMIN1" + Name: "Child Admin Beta" +}, +{/** Needs info. No data found. Using dummy data for now to enable pet. **/ + Id: 20697 + SpriteName: "EP17_2_CHILD_ADMIN2" + Name: "Child Admin Alpha" +}, ) diff --git a/db/re/mob_skill_db.conf b/db/re/mob_skill_db.conf index 624970c5f..b7f1164da 100644 --- a/db/re/mob_skill_db.conf +++ b/db/re/mob_skill_db.conf @@ -36,20 +36,20 @@ mob_skill_db:( <Skill_Constant>: { ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob. SkillLevel: (int, defaults to 1) - SkillState: (int, defaults to 0) - SkillTarget: (int, defaults to 0) + SkillState: (string, defaults to "MSS_ANY") + SkillTarget: (string, defaults to "MST_TARGET") Rate: (int, defaults to 1) CastTime: (int, defaults to 0) Delay: (int, defaults to 0) Cancelable: (boolean, defaults to false) - CastCondition: (int, defaults to 0) + CastCondition: (string, defaults to "MSC_ALWAYS") ConditionData: (int, defaults to 0) val0: (int, defaults to 0) val1: (int, defaults to 0) val2: (int, defaults to 0) val3: (int, defaults to 0) val4: (int, defaults to 0) - Emotion: (int, defaults to 0) + Emotion: (int, defaults to -1) ChatMsgID: (int, defaults to 0) } } @@ -100586,6 +100586,71 @@ mob_skill_db:( CastCondition: "MSC_ALWAYS" } } + WOODIE: { + AL_HEAL: { + SkillState: "MSS_BERSERK" + SkillLevel: 9 + Rate: 10000 + CastTime: 500 + Delay: 5000 + SkillTarget: "MST_SELF" + } + NPC_FIREATTACK: { + SkillState: "MSS_BERSERK" + SkillLevel: 3 + Rate: 2000 + CastTime: 500 + Delay: 5000 + SkillTarget: "MST_TARGET" + } + NPC_GROUNDATTACK: { + SkillState: "MSS_BERSERK" + SkillLevel: 3 + Rate: 2000 + CastTime: 500 + Delay: 5000 + SkillTarget: "MST_TARGET" + } + } + XM_TEDDY_BEAR: { + NPC_CURSEATTACK: { + SkillState: "MSS_BERSERK" + SkillLevel: 4 + Rate: 500 + Delay: 5000 + SkillTarget: "MST_SELF" + } + NPC_CURSEATTACK: { + SkillState: "MSS_FOLLOW" + SkillLevel: 4 + Rate: 500 + Delay: 5000 + SkillTarget: "MST_SELF" + } + NPC_CRITICALSLASH: { + SkillState: "MSS_BERSERK" + SkillLevel: 1 + Rate: 500 + Delay: 5000 + SkillTarget: "MST_TARGET" + } + SA_DISPELL: { + SkillState: "MSS_BERSERK" + SkillLevel: 1 + Rate: 50 + CastTime: 1000 + Delay: 15000 + SkillTarget: "MST_TARGET" + } + BS_HAMMERFALL: { + SkillState: "MSS_BERSERK" + SkillLevel: 5 + Rate: 500 + CastTime: 1000 + Delay: 5000 + SkillTarget: "MST_TARGET" + } + } TIMEHOLDER: { NPC_AGIUP: { SkillState: "MSS_BERSERK" diff --git a/db/re/pet_db.conf b/db/re/pet_db.conf index 3392a8191..f31131653 100644 --- a/db/re/pet_db.conf +++ b/db/re/pet_db.conf @@ -72,10 +72,11 @@ pet_db:( { Id: 1002 Name: "Poring" - TamingItem: "Unripe_Apple" EggItem: "Poring_Egg" - AccessoryItem: "Backpack" + TamingItem: "Unripe_Apple" FoodItem: "Apple_Juice" + AccessoryItem: "Backpack" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } @@ -85,7 +86,11 @@ pet_db:( DefendRate: 400 PetScript: <" petloot(10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bLuk, 3); + bonus(bCritical, 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bLuk, 2); bonus(bCritical, 1); } @@ -100,9 +105,10 @@ pet_db:( { Id: 1011 Name: "ChonChon" - TamingItem: "Rotten_Fish" EggItem: "Chonchon_Egg" + TamingItem: "Rotten_Fish" AccessoryItem: "Monster_Oxygen_Mask" + HungerDecrement: 6 Intimacy: { FeedIncrement: 30 } @@ -113,7 +119,11 @@ pet_db:( ChangeTargetRate: 250 PetScript: <" petskillbonus(bAgi, 4, 10, 50); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAgi, 2); + bonus(bFlee, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bAgi, 1); bonus(bFlee, 2); } @@ -122,9 +132,10 @@ pet_db:( { Id: 1014 Name: "Spore" - TamingItem: "Dew_Laden_Moss" EggItem: "Spore_Egg" + TamingItem: "Dew_Laden_Moss" AccessoryItem: "Bark_Shorts" + HungerDecrement: 3 Intimacy: { FeedIncrement: 30 } @@ -134,18 +145,20 @@ pet_db:( ChangeTargetRate: 500 PetScript: <" petrecovery(SC_POISON, 60); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bHit, 8); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bHit, 5); - bonus(bAtk, -2); - } "> }, { Id: 1019 Name: "PecoPeco" - TamingItem: "Fatty_Chubby_Earthworm" EggItem: "PecoPeco_Egg" + TamingItem: "Fatty_Chubby_Earthworm" AccessoryItem: "Battered_Pot" + HungerDecrement: 4 Intimacy: { FeedIncrement: 30 } @@ -154,10 +167,11 @@ pet_db:( DefendRate: 500 PetScript: <" petskillbonus(bSpeedRate, 25, 20, 20); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxHP, 200); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bMaxHP, 150); - bonus(bMaxSP, -10); - } "> Evolve: { Grand_Peco_Peco_Egg: { @@ -172,9 +186,10 @@ pet_db:( { Id: 1023 Name: "Orc Warrior" - TamingItem: "Horror_Of_Tribe" EggItem: "Orc_Warrior_Egg" + TamingItem: "Horror_Of_Tribe" AccessoryItem: "Wild_Flower" + HungerDecrement: 5 Intimacy: { FeedIncrement: 20 } @@ -185,10 +200,11 @@ pet_db:( ChangeTargetRate: 300 PetScript: <" petskillattack("NPC_PIERCINGATT", 100, 1, 0, 10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAtk, 15); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bAtk, 10); - bonus(bDef, -3); - } "> Evolve: { High_Orc_Egg: { @@ -203,9 +219,10 @@ pet_db:( { Id: 1026 Name: "Munak" - TamingItem: "No_Recipient" EggItem: "Munak_Egg" + TamingItem: "No_Recipient" AccessoryItem: "Punisher" + HungerDecrement: 3 Intimacy: { FeedIncrement: 20 } @@ -214,7 +231,11 @@ pet_db:( ChangeTargetRate: 300 PetScript: <" petskillattack("NPC_DARKNESSATTACK", 444, 1, 0, 10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bInt, 2); + bonus(bDef, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bInt, 1); bonus(bDef, 1); } @@ -223,19 +244,21 @@ pet_db:( { Id: 1029 Name: "Isis" - TamingItem: "Armlet_Of_Obedience" EggItem: "Isis_Egg" + TamingItem: "Armlet_Of_Obedience" AccessoryItem: "Queens_Hair_Ornament" + HungerDecrement: 3 CaptureRate: 500 AttackRate: 650 DefendRate: 450 ChangeTargetRate: 150 PetScript: <" petskillsupport("PR_MAGNIFICAT", 2, 60, 50, 50); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { - bonus(bMatkRate, -1); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAtkRate, 2); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bAtkRate, 1); - } "> Evolve: { Little_Isis_Egg: { @@ -249,10 +272,11 @@ pet_db:( { Id: 1031 Name: "Poporing" - TamingItem: "Bitter_Herb" EggItem: "Poporing_Egg" - AccessoryItem: "Backpack" + TamingItem: "Bitter_Herb" FoodItem: "Green_Herb" + AccessoryItem: "Backpack" + HungerDecrement: 5 Intimacy: { FeedIncrement: 30 } @@ -261,7 +285,11 @@ pet_db:( ChangeTargetRate: 400 PetScript: <" petloot(15); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bLuk, 3); + bonus2(bSubEle, Ele_Poison, 15); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bLuk, 2); bonus2(bSubEle, Ele_Poison, 10); } @@ -270,10 +298,11 @@ pet_db:( { Id: 1035 Name: "Hunter Fly" - TamingItem: "Monster_Juice" EggItem: "Hunter_Fly_Egg" - AccessoryItem: "Monster_Oxygen_Mask" + TamingItem: "Monster_Juice" FoodItem: "Red_Gemstone" + AccessoryItem: "Monster_Oxygen_Mask" + HungerDecrement: 5 CaptureRate: 500 SpecialPerformance: true AttackRate: 500 @@ -281,19 +310,21 @@ pet_db:( ChangeTargetRate: 200 PetScript: <" petskillattack("NPC_WINDATTACK", 888, 2, 0, 10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { - bonus(bFlee, -5); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bFlee2, 2); - } + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bHit, 1); "> }, { Id: 1042 Name: "Steel ChonChon" - TamingItem: "Lusty_Iron" EggItem: "Steel_Chonchon_Egg" - AccessoryItem: "Monster_Oxygen_Mask" + TamingItem: "Lusty_Iron" FoodItem: "Iron_Ore" + AccessoryItem: "Monster_Oxygen_Mask" + HungerDecrement: 5 Intimacy: { FeedIncrement: 20 } @@ -303,19 +334,21 @@ pet_db:( ChangeTargetRate: 200 PetScript: <" petskillbonus(bAgiVit, 4, 20, 40); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bFlee, 9); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bFlee, 6); - bonus(bAgi, -1); - } "> }, { Id: 1049 Name: "Picky" - TamingItem: "Earthworm_The_Dude" EggItem: "Picky_Egg" - AccessoryItem: "Tiny_Egg_Shell" + TamingItem: "Earthworm_The_Dude" FoodItem: "Red_Herb" + AccessoryItem: "Tiny_Egg_Shell" + HungerDecrement: 4 Intimacy: { FeedIncrement: 40 } @@ -326,7 +359,11 @@ pet_db:( ChangeTargetRate: 50 PetScript: <" petskillbonus(bStr, 3, 10, 50); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bStr, 2); + bonus(bAtk, 8); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bStr, 1); bonus(bAtk, 5); } @@ -335,8 +372,8 @@ pet_db:( { Id: 1052 Name: "Rocker" - TamingItem: "Singing_Flower" EggItem: "Rocker_Egg" + TamingItem: "Singing_Flower" AccessoryItem: "Rocker_Glasses" Intimacy: { FeedIncrement: 30 @@ -347,7 +384,11 @@ pet_db:( ChangeTargetRate: 600 PetScript: <" petskillbonus(bAllStats, 1, 10, 50); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bHPrecovRate, 8); + bonus(bMaxHP, 38); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bHPrecovRate, 5); bonus(bMaxHP, 25); } @@ -364,9 +405,10 @@ pet_db:( { Id: 1056 Name: "Smokie" - TamingItem: "Baked_Yam" EggItem: "Smokie_Egg" + TamingItem: "Baked_Yam" AccessoryItem: "Red_Muffler" + HungerDecrement: 4 Intimacy: { FeedIncrement: 30 } @@ -376,7 +418,11 @@ pet_db:( ChangeTargetRate: 100 PetScript: <" petskillbonus(bPerfectHide, 1, 3600, 0); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAgi, 2); + bonus(bFlee2, 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bAgi, 1); bonus(bFlee2, 1); } @@ -385,21 +431,24 @@ pet_db:( { Id: 1057 Name: "Yoyo" - TamingItem: "Tropical_Banana" EggItem: "Yoyo_Egg" - AccessoryItem: "Monkey_Circlet" + TamingItem: "Tropical_Banana" FoodItem: "Banana_Juice" + AccessoryItem: "Monkey_Circlet" + HungerDecrement: 5 Intimacy: { FeedIncrement: 20 } SpecialPerformance: true + DefendRate: 800 ChangeTargetRate: 400 PetScript: <" petloot(20); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bCritical, 5); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bCritical, 3); - bonus(bLuk, -1); - } "> Evolve: { Choco_Egg: { @@ -413,10 +462,11 @@ pet_db:( { Id: 1063 Name: "Lunatic" - TamingItem: "Rainbow_Carrot" EggItem: "Lunatic_Egg" - AccessoryItem: "Silk_Ribbon" + TamingItem: "Rainbow_Carrot" FoodItem: "Carrot_Juice" + AccessoryItem: "Silk_Ribbon" + HungerDecrement: 4 Intimacy: { FeedIncrement: 40 } @@ -424,7 +474,11 @@ pet_db:( ChangeTargetRate: 1000 PetScript: <" petskillbonus(bLuk, 3, 10, 50); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bCritical, 3); + bonus(bAtk, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bCritical, 2); bonus(bAtk, 2); } @@ -441,9 +495,10 @@ pet_db:( { Id: 1077 Name: "Poison Spore" - TamingItem: "Deadly_Noxious_Herb" EggItem: "Poison_Spore_Egg" + TamingItem: "Deadly_Noxious_Herb" AccessoryItem: "Bark_Shorts" + HungerDecrement: 3 Intimacy: { FeedIncrement: 20 } @@ -452,7 +507,11 @@ pet_db:( ChangeTargetRate: 400 PetScript: <" petskillattack("NPC_POISON", 20, 0, 0, 10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bStr, 2); + bonus(bInt, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bStr, 1); bonus(bInt, 1); } @@ -461,29 +520,36 @@ pet_db:( { Id: 1101 Name: "Baphomet Jr." - TamingItem: "Book_Of_Devil" EggItem: "Bapho_Jr_Egg" - AccessoryItem: "Skull_Helm" + TamingItem: "Book_Of_Devil" FoodItem: "Honey" + AccessoryItem: "Skull_Helm" + HungerDecrement: 2 CaptureRate: 200 AttackRate: 1000 DefendRate: 100 ChangeTargetRate: 200 PetScript: <" petskillattack("NPC_DARKNESSATTACK", 1776, 4, 0, 5); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bDef, 2); + bonus(bMdef, 2); + bonus2(bResEff, Eff_Stun, 200); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bDef, 1); bonus(bMdef, 1); - bonus2(bResEff, Eff_Stun, -100); + bonus2(bResEff, Eff_Stun, 100); } "> }, { Id: 1107 Name: "Baby Desert Wolf" - TamingItem: "Well_Dried_Bone" EggItem: "Baby_Desert_Wolf_Egg" + TamingItem: "Well_Dried_Bone" AccessoryItem: "Transparent_Headgear" + HungerDecrement: 6 Intimacy: { FeedIncrement: 40 } @@ -492,7 +558,11 @@ pet_db:( ChangeTargetRate: 400 PetScript: <" petskillattack("SM_PROVOKE", 1, 0, 0, 5);"> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bInt, 2); + bonus(bMaxSP, 75); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bInt, 1); bonus(bMaxSP, 50); } @@ -501,20 +571,25 @@ pet_db:( { Id: 1109 Name: "Deviruchi" - TamingItem: "Contracts_In_Shadow" EggItem: "Deviruchi_Egg" - AccessoryItem: "Pacifier" + TamingItem: "Contracts_In_Shadow" FoodItem: "Shoot" + AccessoryItem: "Pacifier" + HungerDecrement: 2 CaptureRate: 500 + AttackRate: 800 DefendRate: 200 ChangeTargetRate: 100 PetScript: <" petskillbonus(bAgiDexStr, 6, 20, 40); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { - bonus(bMatkRate, 1); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bAtkRate, 1); - bonus(bMaxHPrate, -3); - bonus(bMaxSPrate, -3); + bonus(bMatkRate, 1); + } + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxHPrate, 1); + bonus(bMaxSPrate, 1); } "> Evolve: { @@ -529,19 +604,21 @@ pet_db:( { Id: 1110 Name: "Dokebi" - TamingItem: "Old_Broom" EggItem: "Dokkaebi_Egg" + TamingItem: "Old_Broom" AccessoryItem: "Wig" + HungerDecrement: 4 Intimacy: { FeedIncrement: 20 } CaptureRate: 500 PetScript: <" petskillattack("BS_HAMMERFALL", 1, 0, 0, 10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMatkRate, 2); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bMatkRate, 1); - bonus(bAtkRate, -1); - } "> Evolve: { Am_Mut_Egg: { @@ -555,10 +632,11 @@ pet_db:( { Id: 1113 Name: "Drops" - TamingItem: "Orange_Juice" EggItem: "Drops_Egg" - AccessoryItem: "Backpack" + TamingItem: "Orange_Juice" FoodItem: "Yellow_Herb" + AccessoryItem: "Backpack" + HungerDecrement: 4 Intimacy: { FeedIncrement: 40 } @@ -568,7 +646,11 @@ pet_db:( ChangeTargetRate: 500 PetScript: <" petloot(10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bHit, 5); + bonus(bAtk, 5); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bHit, 3); bonus(bAtk, 3); } @@ -580,35 +662,35 @@ pet_db:( Apple_Juice: 3 Eggring_Card: 1 } -/* Sweet_Drops_Egg: { - 25290: 500 + Sweets_Coin: 500 Candy: 50 Candy_Striper: 50 Drops_Card: 1 } -*/ } }, { Id: 1155 Name: "Petite" - TamingItem: "Shining_Stone" EggItem: "Green_Petite_Egg" + TamingItem: "Shining_Stone" AccessoryItem: "Stellar_Hairpin" + HungerDecrement: 4 Intimacy: { FeedIncrement: 20 } CaptureRate: 500 + AttackRate: 800 DefendRate: 400 ChangeTargetRate: 100 PetScript: <" petskillattack("WZ_HEAVENDRIVE", 500, 1, 0, 10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { - bonus(bDef, -2); - bonus(bMdef, -2); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bAspdRate, 1); - } + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAgi, 1); "> Evolve: { Earth_Deleter_Egg: { @@ -622,9 +704,10 @@ pet_db:( { Id: 1167 Name: "Savage Babe" - TamingItem: "Sweet_Milk" EggItem: "Savage_Bebe_Egg" + TamingItem: "Sweet_Milk" AccessoryItem: "Green_Lace" + HungerDecrement: 7 Intimacy: { FeedIncrement: 40 } @@ -634,7 +717,11 @@ pet_db:( ChangeTargetRate: 200 PetScript: <" petskillbonus(bVit, 4, 10, 50); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bVit, 2); + bonus(bMaxHP, 75); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bVit, 1); bonus(bMaxHP, 50); } @@ -651,16 +738,21 @@ pet_db:( { Id: 1170 Name: "Sohee" - TamingItem: "Silver_Knife_Of_Chaste" EggItem: "Sohee_Egg" + TamingItem: "Silver_Knife_Of_Chaste" AccessoryItem: "Golden_Bell" + HungerDecrement: 3 CaptureRate: 500 AttackRate: 100 DefendRate: 1000 ChangeTargetRate: 200 PetScript: <" petskillsupport(AL_HEAL, 10, 60, 33, 100); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bStr, 2); + bonus(bDex, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bStr, 1); bonus(bDex, 1); } @@ -669,9 +761,10 @@ pet_db:( { Id: 1188 Name: "Bon Gun" - TamingItem: "Heart_Of_Her" EggItem: "Bongun_Egg" + TamingItem: "Heart_Of_Her" AccessoryItem: "Sword_Of_Grave_Keeper" + HungerDecrement: 4 Intimacy: { FeedIncrement: 30 } @@ -682,7 +775,11 @@ pet_db:( ChangeTargetRate: 400 PetScript: <" petskillattack("NPC_DARKNESSATTACK", 555, 1, 1, 1); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bVit, 2); + bonus2(bResEff, Eff_Stun, 200); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bVit, 1); bonus2(bResEff, Eff_Stun, 100); } @@ -699,16 +796,21 @@ pet_db:( { Id: 1200 Name: "Zealotus" - TamingItem: "Prohibition_Red_Candle" EggItem: "Zherlthsh_Egg" + TamingItem: "Prohibition_Red_Candle" FoodItem: "Immortal_Heart" + HungerDecrement: 7 CaptureRate: 300 AttackRate: 1000 DefendRate: 100 ChangeTargetRate: 500 PetScript: <" petskillattack("AS_SONICBLOW", 1, 0, 0, 3); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus2(bAddRace, RC_DemiPlayer, 3); + bonus2(bMagicAddRace, RC_DemiPlayer, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus2(bAddRace, RC_DemiPlayer, 2); bonus2(bMagicAddRace, RC_DemiPlayer, 2); } @@ -717,16 +819,21 @@ pet_db:( { Id: 1245 Name: "Christmas Goblin" - TamingItem: "Sweet_Candy_Striper" EggItem: "Santa_Goblin_Egg" + TamingItem: "Sweet_Candy_Striper" FoodItem: "Scell" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } CaptureRate: 2000 PetScript: <" petskillattack("MG_SIGHT", 5, 0, 5, 5); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxHP, 45); + bonus2(bSubEle, Ele_Water, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bMaxHP, 30); bonus2(bSubEle, Ele_Water, 1); } @@ -735,85 +842,126 @@ pet_db:( { Id: 1275 Name: "Alice" - TamingItem: "Sway_Apron" EggItem: "Alice_Egg" + TamingItem: "Sway_Apron" FoodItem: "White_Potion" + HungerDecrement: 2 Intimacy: { FeedIncrement: 20 } + CaptureRate: 800 AttackRate: 100 DefendRate: 1000 ChangeTargetRate: 200 PetScript: <" petskillsupport("AL_HEAL", 5, 60, 25, 100); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMdef, 2); + bonus2(bAddRaceTolerance, RC_DemiPlayer, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bMdef, 1); bonus2(bAddRaceTolerance, RC_DemiPlayer, 1); } "> + Evolve: { + Aliza_Egg: { + Alices_Apron: 500 + Green_Herb: 200 + Elunium: 30 + Alice_Card: 1 + } + } }, // New Pets { Id: 1122 Name: "Goblin" - TamingItem: "Knife_Goblin_Ring" EggItem: "Knife_Goblin_Egg" + TamingItem: "Knife_Goblin_Ring" FoodItem: "Green_Apple" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } + CaptureRate: 800 PetScript: <" petskillattack("NPC_WINDATTACK", 5, 0, 5, 5); "> }, { Id: 1123 Name: "Goblin" - TamingItem: "Flail_Goblin_Ring" EggItem: "Flail_Goblin_Egg" + TamingItem: "Flail_Goblin_Ring" FoodItem: "Green_Apple" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } + CaptureRate: 800 PetScript: <" petskillattack("NPC_FIREATTACK", 5, 0, 5, 5); "> }, { Id: 1125 Name: "Goblin" - TamingItem: "Hammer_Goblin_Ring" EggItem: "Hammer_Goblin_Egg" + TamingItem: "Hammer_Goblin_Ring" FoodItem: "Green_Apple" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } + CaptureRate: 800 PetScript: <" petskillattack("NPC_GROUNDATTACK", 5, 0, 5, 5); "> }, { Id: 1208 Name: "Wanderer" - TamingItem: "Skull_Of_Vagabond" EggItem: "Wanderer_Egg" + TamingItem: "Skull_Of_Vagabond" FoodItem: "Spirit_Liquor" + HungerDecrement: 2 Intimacy: { FeedIncrement: 20 } + CaptureRate: 800 PetScript: <" petskillattack("NPC_UNDEADATTACK", 5, 0, 5, 5); "> + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAgi, 4); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bAgi, 3); + "> + Evolve: { + Contaminated_Wanderer_Egg: { + Skull: 500 + Sacred_Marks: 50 + Transparent_Cloth: 100 + Wander_Man_Card: 1 + } + } }, { Id: 1382 Name: "Diabolic" - TamingItem: "Red_Burning_Stone" EggItem: "Diabolic_Egg" + TamingItem: "Red_Burning_Stone" FoodItem: "Meat_Veg_Skewer" + HungerDecrement: 2 + CaptureRate: 800 PetScript: <" petskillattack("WZ_METEOR", 2, 0, 5, 5); "> }, { Id: 1385 Name: "Deleter" - TamingItem: "Holy_Marble" EggItem: "Red_Deleter_Egg" + TamingItem: "Holy_Marble" FoodItem: "Whole_Barbecue" + HungerDecrement: 4 Intimacy: { FeedIncrement: 20 } + CaptureRate: 800 PetScript: <" petskillattack("SM_MAGNUM", 5, 0, 5, 5); "> }, { @@ -821,6 +969,7 @@ pet_db:( Name: "Spring Rabbit" EggItem: "Spring_Rabbit_Egg" FoodItem: "Bok_Choy" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } @@ -833,9 +982,11 @@ pet_db:( Name: "New Year Doll" EggItem: "New_Year_Doll_Egg" FoodItem: "Mojji" + HungerDecrement: 3 Intimacy: { FeedIncrement: 30 } + CaptureRate: 800 PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); "> }, // Episode 13 @@ -844,6 +995,7 @@ pet_db:( Name: "Rice Cake" EggItem: "Rice_Cake_Egg" FoodItem: "Green_Herb" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } @@ -854,10 +1006,11 @@ pet_db:( ChangeTargetRate: 200 PetScript: <" petskillsupport("CR_DEFENDER", 3, 240, 50, 100); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus2(bSubEle, Ele_Neutral, 2); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus2(bSubEle, Ele_Neutral, 1); - bonus(bMaxHPrate, -1); - } "> }, { @@ -865,9 +1018,10 @@ pet_db:( Name: "Christmas Snow Rabbit" EggItem: "Snow_Rabbit_Egg" FoodItem: "Candy" + HungerDecrement: 3 SpecialPerformance: true EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_CORDIAL) bonus2(bExpAddRace, RC_All, 5); "> }, @@ -875,44 +1029,52 @@ pet_db:( { Id: 1040 Name: "Golem" - TamingItem: "Magical_Lithography" EggItem: "Golem_Egg" - AccessoryItem: "Windup_Spring" + TamingItem: "Magical_Lithography" FoodItem: "Mystic_Stone" + AccessoryItem: "Windup_Spring" + HungerDecrement: 7 Intimacy: { FeedIncrement: 20 } - CaptureRate: 500 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxHP, 150); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bMaxHP, 100); - bonus(bFlee, -5); - } "> }, { Id: 1143 Name: "Marionette" - TamingItem: "Delicious_Shaved_Ice" EggItem: "Marionette_Egg" - AccessoryItem: "Star_Hairband" + TamingItem: "Delicious_Shaved_Ice" FoodItem: "Small_Snow_Flower" - CaptureRate: 500 + AccessoryItem: "Star_Hairband" + HungerDecrement: 3 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) - bonus(bSPrecovRate, 3); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + autobonus("{ bonus2(bSubEle, Ele_Neutral, 20); heal(100, 0); }", 10, 5000, BF_SHORT|BF_NORMAL); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + autobonus("{ bonus2(bSubEle, Ele_Neutral, 20); heal(100, 0); }", 10, 3000, BF_SHORT|BF_NORMAL); "> }, { Id: 1148 Name: "Medusa" - TamingItem: "Splendid_Mirror" EggItem: "Medusa_Egg" - AccessoryItem: "Queens_Coronet" + TamingItem: "Splendid_Mirror" FoodItem: "Apple_Pudding" - CaptureRate: 200 + AccessoryItem: "Queens_Coronet" + HungerDecrement: 3 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bVit, 2); + bonus2(bResEff, Eff_Stone, 800); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bVit, 1); bonus2(bResEff, Eff_Stone, 500); } @@ -921,198 +1083,264 @@ pet_db:( { Id: 1179 Name: "Whisper" - TamingItem: "Fit_Pipe" EggItem: "Whisper_Egg" - AccessoryItem: "Spirit_Chain_" + TamingItem: "Fit_Pipe" FoodItem: "Damp_Darkness" + AccessoryItem: "Spirit_Chain_" + HungerDecrement: 7 Intimacy: { FeedIncrement: 20 } - CaptureRate: 500 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bFlee, 10); + skill("TF_HIDING", 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bFlee, 7); - bonus(bDef, -3); + skill("TF_HIDING", 1); } "> }, { Id: 1299 Name: "Goblin Leader" - TamingItem: "Staff_Of_Leader" EggItem: "Goblin_Leader_Egg" - AccessoryItem: "Nice_Badge" + TamingItem: "Staff_Of_Leader" FoodItem: "Big_Cell" - CaptureRate: 50 + AccessoryItem: "Nice_Badge" + HungerDecrement: 7 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus2(bAddRace, RC_DemiPlayer, 5); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus2(bAddRace, RC_DemiPlayer, 3); "> }, { Id: 1370 Name: "Succubus" - TamingItem: "Boys_Naivety" EggItem: "Succubus_Egg" - AccessoryItem: "Black_Butterfly_Mask" + TamingItem: "Boys_Naivety" FoodItem: "Vital_Flower_" - CaptureRate: 200 + AccessoryItem: "Black_Butterfly_Mask" + HungerDecrement: 3 + CaptureRate: 300 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) - bonus2(bHPDrainRate, 50, 5); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus2(bHPDrainRate, 20, 5); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxHPrate, 1); "> }, { Id: 1374 Name: "Incubus" - TamingItem: "Grils_Naivety" EggItem: "Incubus_Egg" - AccessoryItem: "Ball_Mask" + TamingItem: "Grils_Naivety" FoodItem: "Vital_Flower" - CaptureRate: 50 + AccessoryItem: "Ball_Mask" + HungerDecrement: 3 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxSPrate, 5); + bonus2(bSPDrainRate, 30, 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bMaxSPrate, 3); + bonus2(bSPDrainRate, 20, 1); + } "> }, { Id: 1379 Name: "Nightmare Terror" - TamingItem: "Hell_Contract" EggItem: "Nightmare_Terror_Egg" - AccessoryItem: "Hell_Horn" + TamingItem: "Hell_Contract" FoodItem: "Fresh_Plant" - CaptureRate: 200 + AccessoryItem: "Hell_Horn" + HungerDecrement: 3 + CaptureRate: 300 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus2(bResEff, Eff_Sleep, 10000); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bInt, 1); "> + Evolve: { + Rigid_Nightmare_Terror_Egg: { + Burning_Horse_Shoe: 500 + Blue_Herb: 100 + Shell: 100 + Nightmare_Terror_Card: 1 + } + } }, { Id: 1401 Name: "Shinobi" - TamingItem: "Kuloren" EggItem: "Shinobi_Egg" - AccessoryItem: "Wine_On_Sleeve" + TamingItem: "Kuloren" FoodItem: "Grilled_Rice_Cake" + AccessoryItem: "Wine_On_Sleeve" + HungerDecrement: 7 Intimacy: { FeedIncrement: 20 } - CaptureRate: 500 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAgi, 3); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bAgi, 2); "> }, { Id: 1404 Name: "Miyabi Doll" - TamingItem: "Gril_Doll" EggItem: "Miyabi_Ningyo_Egg" - AccessoryItem: "Summer_Fan" + TamingItem: "Gril_Doll" FoodItem: "Well_Ripened_Berry" + AccessoryItem: "Summer_Fan" + HungerDecrement: 3 Intimacy: { FeedIncrement: 15 } - CaptureRate: 200 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bInt, 2); + bonus(bVariableCastrate, -5); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bInt, 1); - bonus(bCastrate, -3); + bonus(bVariableCastrate, -3); } "> }, { Id: 1416 Name: "Evil Nymph" - TamingItem: "Charming_Lotus" EggItem: "Wicked_Nymph_Egg" - AccessoryItem: "Jade_Trinket" + TamingItem: "Charming_Lotus" FoodItem: "Morning_Dew" + AccessoryItem: "Jade_Trinket" + HungerDecrement: 3 Intimacy: { FeedIncrement: 15 } - CaptureRate: 500 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxSP, 45); + bonus(bSPrecovRate, 8); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bMaxSP, 30); bonus(bSPrecovRate, 5); } "> + Evolve: { + Bacsojin2_Egg_: { + Mightysoul_Essence: 30 + Civil_Servant_Card: 10 + Li_Me_Mang_Ryang_Card: 10 + Dancing_Dragon_Card: 10 + } + } }, { Id: 1495 Name: "Stone Shooter" - TamingItem: "Oilpalm_Coconut" EggItem: "Stone_Shooter_Egg" - AccessoryItem: "Apro_Hair" + TamingItem: "Oilpalm_Coconut" FoodItem: "Plant_Neutrient" + AccessoryItem: "Apro_Hair" + HungerDecrement: 7 Intimacy: { FeedIncrement: 20 } - CaptureRate: 500 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus2(bSubEle, Ele_Fire, 5); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus2(bSubEle, Ele_Fire, 3); "> }, { Id: 1504 Name: "Dullahan" - TamingItem: "Luxury_Whisky_Bottle" EggItem: "Dullahan_Egg" - AccessoryItem: "Death_Coil" + TamingItem: "Luxury_Whisky_Bottle" FoodItem: "Sunset_On_The_Rock" - CaptureRate: 200 + AccessoryItem: "Death_Coil" + HungerDecrement: 3 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bCritAtkRate, 8); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bCritAtkRate, 5); "> }, { Id: 1505 Name: "Loli Ruri" - TamingItem: "Very_Red_Juice" EggItem: "Loli_Ruri_Egg" - AccessoryItem: "Fashionable_Glasses" + TamingItem: "Very_Red_Juice" FoodItem: "Pumpkin_Pie_" + AccessoryItem: "Fashionable_Glasses" + HungerDecrement: 3 Intimacy: { FeedIncrement: 15 } - CaptureRate: 200 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { bonus(bMaxHPrate, 3); - bonus3(bAutoSpellWhenHit, "AL_HEAL", 1, 50); + bonus3(bAutoSpellWhenHit, "AL_HEAL", 2, 10); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMaxHPrate, 3); + bonus3(bAutoSpellWhenHit, "AL_HEAL", 1, 10); } "> }, { Id: 1513 Name: "Mao Guai" - TamingItem: "Fan_Of_Wind" EggItem: "Civil_Servant_Egg" - AccessoryItem: "Golden_Earing" + TamingItem: "Fan_Of_Wind" FoodItem: "Flavored_Alcohol" - CaptureRate: 500 + AccessoryItem: "Golden_Earing" + HungerDecrement: 3 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxSP, 15); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus(bMaxSP, 10); "> }, { Id: 1519 Name: "Green Maiden" - TamingItem: "Tantanmen" EggItem: "Chung_E_Egg" + TamingItem: "Tantanmen" FoodItem: "Bun_" + HungerDecrement: 3 Intimacy: { FeedIncrement: 50 } CaptureRate: 2000 PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bDef, 2); + bonus2(bAddRaceTolerance, RC_DemiPlayer, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { bonus(bDef, 1); bonus2(bAddRaceTolerance, RC_DemiPlayer, 1); } @@ -1121,40 +1349,49 @@ pet_db:( { Id: 1586 Name: "Leaf Cat" - TamingItem: "Very_Soft_Plant" EggItem: "Leaf_Cat_Egg" - AccessoryItem: "Green_Lucky_Bag" + TamingItem: "Very_Soft_Plant" FoodItem: "Fish_With_Blue_Back" + AccessoryItem: "Green_Lucky_Bag" + HungerDecrement: 7 Intimacy: { FeedIncrement: 20 } - CaptureRate: 200 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus2(bAddRaceTolerance, RC_Brute, 5); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) bonus2(bAddRaceTolerance, RC_Brute, 3); "> }, { Id: 1630 Name: "White Lady" - TamingItem: "Shiny_Wing_Gown" EggItem: "Bacsojin_Egg" - AccessoryItem: "Round_Hair_Ornament" + TamingItem: "Shiny_Wing_Gown" FoodItem: "Traditional_Cookie" - CaptureRate: 2000 + AccessoryItem: "Round_Hair_Ornament" + HungerDecrement: 7 + CaptureRate: 300 }, { Id: 1837 Name: "Fire Imp" - TamingItem: "Flaming_Ice" EggItem: "Imp_Egg" - AccessoryItem: "Horn_Protector" + TamingItem: "Flaming_Ice" FoodItem: "Flame_Gemstone" - CaptureRate: 200 + AccessoryItem: "Horn_Protector" + HungerDecrement: 3 + CaptureRate: 300 EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { - bonus2(bSubEle, Ele_Fire, 2); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus2(bSubEle, Ele_Fire, 3); bonus2(bAddEle, Ele_Fire, 2); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus2(bSubEle, Ele_Fire, 2); + bonus2(bAddEle, Ele_Fire, 1); } "> }, @@ -1162,18 +1399,32 @@ pet_db:( { Id: 2057 Name: "Strange Cramp" - TamingItem: "Leaf_Cat_Ball" EggItem: "Mystic_Leaf_Cat_Ball" - CaptureRate: 50 + TamingItem: "Leaf_Cat_Ball" + FoodEffectiveness: 1 + HungerDecrement: 0 + Intimacy: { + FeedIncrement: 1 + OverFeedDecrement: 0 + OwnerDeathDecrement: 0 + } + CaptureRate: 5000 AttackRate: 350 DefendRate: 400 }, { Id: 2081 Name: "Strange Hydra" - TamingItem: "Leaf_Cat_Ball" EggItem: "Mystic_Leaf_Cat_Ball" - CaptureRate: 50 + TamingItem: "Leaf_Cat_Ball" + FoodEffectiveness: 1 + HungerDecrement: 0 + Intimacy: { + FeedIncrement: 1 + OverFeedDecrement: 0 + OwnerDeathDecrement: 0 + } + CaptureRate: 5000 AttackRate: 350 DefendRate: 400 }, @@ -1181,21 +1432,35 @@ pet_db:( { Id: 2313 Name: "Tikbalang" - TamingItem: "Tikbalang_Belt" EggItem: "Tikbalang_Pet" + TamingItem: "Tikbalang_Belt" FoodItem: "Monsters_Feed" + HungerDecrement: 8 SpecialPerformance: true EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMdef, 5); + bonus2(bAddDamageClass, 2317, 10); + bonus2(bAddDamageClass, 2318, 10); + bonus2(bAddDamageClass, 2319, 10); bonus2(bAddDamageClass, 2320, 10); bonus2(bAddDamageClass, 2321, 10); bonus2(bAddDamageClass, 2322, 10); + bonus2(bAddDamageClass, 2327, 10); + bonus2(bAddDamageClass, 2332, 10); + bonus2(bAddDamageClass, 2333, 10); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMdef, 3); bonus2(bAddDamageClass, 2317, 10); bonus2(bAddDamageClass, 2318, 10); - bonus2(bAddDamageClass, 2327, 10); bonus2(bAddDamageClass, 2319, 10); - bonus2(bAddDamageClass, 2333, 10); + bonus2(bAddDamageClass, 2320, 10); + bonus2(bAddDamageClass, 2321, 10); + bonus2(bAddDamageClass, 2322, 10); + bonus2(bAddDamageClass, 2327, 10); bonus2(bAddDamageClass, 2332, 10); + bonus2(bAddDamageClass, 2333, 10); } "> }, @@ -1203,10 +1468,10 @@ pet_db:( { Id: 1242 Name: "Marin" - TamingItem: "Juicy_Fruit" EggItem: "Marin_Egg" - AccessoryItem: "Tw_Backpack" + TamingItem: "Juicy_Fruit" FoodItem: "Fruit_Sundae" + AccessoryItem: "Tw_Backpack" Intimacy: { FeedIncrement: 50 } @@ -1215,7 +1480,7 @@ pet_db:( }, { Id: 2200 - Name: "Tiny" + Name: "Taini" EggItem: "Egg_Of_Tiny" FoodItem: "Apple" SpecialPerformance: true @@ -1226,21 +1491,23 @@ pet_db:( Name: "Little Poring" TamingItem: "Unripe_Apple2" EggItem: "Novice_Poring_Egg" - AccessoryItem: "Backpack" FoodItem: "Apple_Juice" + FoodEffectiveness: 20 + HungerDecrement: 3 Intimacy: { - FeedIncrement: 50 + FeedIncrement: 100 + StarvingDecrement: 1 } - CaptureRate: 2000 - SpecialPerformance: true + CaptureRate: 1000 AttackRate: 350 DefendRate: 400 PetScript: <" petloot(10); "> EquipScript: <" - if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { - bonus(bLuk, 2); - bonus(bCritical, 1); - } + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bHPrecovRate, 75); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bHPrecovRate, 50); "> }, // New Pets [Need Info] @@ -1249,6 +1516,22 @@ pet_db:( Name: "Mastering" EggItem: "Mastering_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bLuk, 3); + bonus(bCritical, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bLuk, 3); + bonus(bCritical, 2); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bLuk, 3); + bonus(bCritical, 1); + } else { + bonus(bLuk, 2); + bonus(bCritical, 1); + } + "> Evolve: { Angeling_Egg: { Yellow_Potion: 20 @@ -1263,63 +1546,173 @@ pet_db:( Name: "Angeling" EggItem: "Angeling_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxHPrate, 2); + bonus(bHealPower, 8); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMaxHPrate, 2); + bonus(bHealPower, 6); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bMaxHPrate, 1); + bonus(bHealPower, 4); + } else { + bonus(bMaxHPrate, 1); + bonus(bHealPower, 2); + } + "> }, { Id: 1301 Name: "Am Mut" EggItem: "Am_Mut_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMatkRate, 4); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bMatkRate, 3); + else if (.@intimacy >= PET_INTIMACY_NEUTRAL) + bonus(bMatkRate, 2); + else + bonus(bMatkRate, 1); + "> }, -/* { Id: 3636 Name: "Little Isis" EggItem: "Little_Isis_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAtkRate, 4); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bAtkRate, 3); + else if (.@intimacy >= PET_INTIMACY_NEUTRAL) + bonus(bAtkRate, 2); + else + bonus(bAtkRate, 1); + "> }, -*/ { Id: 1214 Name: "Choco" EggItem: "Choco_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bCritical, 9); + bonus(bLongAtkRate, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bCritical, 7); + bonus(bLongAtkRate, 2); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bCritical, 5); + bonus(bLongAtkRate, 1); + } else { + bonus(bCritical, 3); + } + "> }, -/* { Id: 3495 Name: "Eggring" EggItem: "Eggring_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bHit, 9); + bonus(bAtk, 9); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bHit, 7); + bonus(bAtk, 7); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bHit, 5); + bonus(bAtk, 5); + } else { + bonus(bHit, 3); + bonus(bAtk, 3); + } + "> }, -*/ { Id: 1512 Name: "Hyegun" EggItem: "Hyegun_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bVit, 4); + bonus2(bResEff, Eff_Stun, 400); + bonus2(bSPDrainRate, 10, 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bVit, 3); + bonus2(bResEff, Eff_Stun, 300); + bonus2(bSPDrainRate, 10, 1); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bVit, 2); + bonus2(bResEff, Eff_Stun, 200); + } else { + bonus(bVit, 1); + bonus2(bResEff, Eff_Stun, 100); + } + "> }, -/* { Id: 3496 Name: "Leaf Lunatic" EggItem: "Leaf_Lunatic_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bCritical, 5); + bonus(bAtk, 5); + bonus2(bAddRace, RC_Formless, 6); + bonus2(bMagicAddRace, RC_Formless, 6); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bCritical, 4); + bonus(bAtk, 4); + bonus2(bAddRace, RC_Formless, 3); + bonus2(bMagicAddRace, RC_Formless, 3); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bCritical, 3); + bonus(bAtk, 3); + } else { + bonus(bCritical, 2); + bonus(bAtk, 2); + } + "> }, -*/ { Id: 1180 Name: "Nine Tails" EggItem: "Nine_Tails_Egg" - AutoFeed: true + TamingItem: "Sap_Jelly" + FoodItem: "Suspicious_Bottle" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bCritical, 3); + bonus(bHit, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bCritical, 2); + bonus(bHit, 2); + } + "> Evolve: { -/* Cat_o_Nine_Tails_Egg: { - 23187: 3 + Sap_Jelly: 3 Fox_Tail: 999 Punisher: 1 Nine_Tail_Card: 1 } -*/ } }, { @@ -1327,152 +1720,807 @@ pet_db:( Name: "Cat o' Nine Tails" EggItem: "Cat_o_Nine_Tails_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bCritical, 5); + bonus(bHit, 5); + autobonus("{ bonus2(bHPRegenRate, 400, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bCritical, 4); + bonus(bHit, 4); + autobonus("{ bonus2(bHPRegenRate, 300, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bCritical, 3); + bonus(bHit, 3); + } else { + bonus(bCritical, 2); + bonus(bHit, 2); + } + "> Evolve: { -/* Moonlight_Flower_Egg: { - 25375: 30 + Mightysoul_Essence: 30 Nine_Tail_Card: 10 Sohee_Card: 10 Munak_Card: 10 } -*/ } }, -/* { Id: 3669 Name: "Diabolic" EggItem: "Diabolic_Egg_" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAtkRate, 2); + bonus(bMatkRate, 2); + bonus(bMaxHPrate, 2); + bonus(bMaxSPrate, 2); + bonus5(bAutoSpell, "MG_FIREBOLT", 3, 50, BF_WEAPON|BF_SHORT, 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bAtkRate, 2); + bonus(bMatkRate, 2); + bonus(bMaxHPrate, 1); + bonus(bMaxSPrate, 1); + bonus5(bAutoSpell, "MG_FIREBOLT", 3, 50, BF_WEAPON|BF_SHORT, 1); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bAtkRate, 1); + bonus(bMatkRate, 1); + bonus(bMaxHPrate, 1); + bonus(bMaxSPrate, 1); + } else { + bonus(bAtkRate, 1); + bonus(bMatkRate, 1); + } + "> }, -*/ -/* { Id: 3670 Name: "Earth Deleter" EggItem: "Earth_Deleter_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAspdRate, 3); + bonus(bAgi, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bAspdRate, 2); + bonus(bAgi, 2); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bAspdRate, 1); + bonus(bAgi, 1); + } else { + bonus(bAspdRate, 1); + } + "> }, -*/ { Id: 1622 Name: "Teddy Bear" EggItem: "Teddy_Bear_Egg" - AutoFeed: true + TamingItem: "SmallDoll_Needle" + FoodItem: "Cotton_Tufts" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxSP, 100); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bMaxSP, 50); + "> Evolve: { -/* Abandoned_Teddy_Bear_Egg: { - 23189: 3 + SmallDoll_Needle: 3 Cursed_Seal: 300 Cardinal_Jewel_: 50 Teddy_Bear_Card: 1 } -*/ + Aliot_Egg: { + Screw: 500 + Honey: 100 + White_Jewel: 10 + Teddy_Bear_Card: 1 + } + Alicel_Egg: { + Screw: 500 + Honey: 100 + Bloody_Page: 50 + Teddy_Bear_Card: 1 + } } }, { Id: 1632 Name: "Gremlin" EggItem: "Gremlin_Egg" - AutoFeed: true + TamingItem: "Unprocessed_Parts" + FoodItem: "Cheap_Lubricant" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bDex, 2); + bonus(bHit, 1); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bDex, 1); + bonus(bHit, 1); + } + "> Evolve: { -/* Hodremlin_Egg: { - 23188: 3 + Unprocessed_Parts: 3 Damp_Darkness: 50 Will_Of_Darkness: 200 Hodremlin_Card: 1 } -*/ } }, -/* { Id: 3731 - Name: "Scatleton Crate" - EggItem: "Scatleton_Crate" - AutoFeed: true + Name: "Scatleton" + EggItem: "Scatelon_Egg" + FoodItem: "Delicious_Fish" + AccessoryItem: "Red_Bell_Necklace" + EquipScript: <" + if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_CORDIAL) + bonus2(bAddItemHealRate, 579, 100); + "> + Evolve: { + Skelion_Egg: { + Memory_Of_Gyol: 2 + Yummy_Meat: 100 + Cookie_Bat: 100 + } + } }, -*/ { Id: 1041 Name: "Mummy" EggItem: "Mummy_Egg" - AutoFeed: true + TamingItem: "Elixir_Bandage" + FoodItem: "Mementos" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bHit, 5); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bHit, 4); + "> Evolve: { -/* Ancient_Mummy_Egg: { - 23256: 3 + Elixir_Bandage: 3 Rune_Of_Darkness: 200 Gold: 30 Ancient_Mummy_Card: 1 } -*/ } }, { Id: 1010 Name: "Willow" EggItem: "Willow_Egg" - AutoFeed: true + TamingItem: "Dew_Of_Old_Tree" + FoodItem: "Tree_Of_Archer_1" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bInt, 3); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bInt, 2); + "> }, { Id: 1782 Name: "Roween" EggItem: "Roween_Egg" - AutoFeed: true + TamingItem: "Foul_Rotten_Meat" + FoodItem: "Rotten_Meat" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus2(bMagicAtkEle, Ele_Wind, 3); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus2(bMagicAtkEle, Ele_Wind, 2); + "> }, { Id: 1773 Name: "Hodremlin" EggItem: "Hodremlin_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bDex, 2); + bonus(bHit, 2); + bonus(bCritAtkRate, 9); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bDex, 2); + bonus(bHit, 2); + bonus(bCritAtkRate, 7); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bDex, 2); + bonus(bHit, 1); + } else { + bonus(bDex, 1); + bonus(bHit, 1); + } + "> + Evolve: { + Gloom_Under_Night_Egg: { + Hodremlin_Card: 10 + Isilla_Card: 10 + Agav_Card: 10 + Mightysoul_Essence: 30 + } + } }, { Id: 1058 Name: "Metaller" EggItem: "Metaller_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bHPrecovRate, 20); + bonus(bMaxHP, 70); + bonus2(bAddRace, RC_Plant, 6); + bonus2(bMagicAddRace, RC_Plant, 6); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bHPrecovRate, 15); + bonus(bMaxHP, 55); + bonus2(bAddRace, RC_Plant, 3); + bonus2(bMagicAddRace, RC_Plant, 3); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bHPrecovRate, 10); + bonus(bMaxHP, 38); + } else { + bonus(bHPrecovRate, 5); + bonus(bMaxHP, 25); + } + "> }, { Id: 1297 Name: "Ancient Mummy" EggItem: "Ancient_Mummy_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bHit, 6); + bonus2(bAddRace, RC_Dragon, 6); + bonus2(bMagicAddRace, RC_Dragon, 6); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bHit, 6); + bonus2(bAddRace, RC_Dragon, 3); + bonus2(bMagicAddRace, RC_Dragon, 3); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bHit, 5); + } else { + bonus(bHit, 4); + } + "> }, -/*{ +{ Id: 2995 Name: "Abandoned Teddy Bear" EggItem: "Abandoned_Teddy_Bear_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxSP, 150); + autobonus("{ bonus2(bSPRegenRate, 40, 1000); }", 30, 5000, BF_MAGIC); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMaxSP, 150); + autobonus("{ bonus2(bSPRegenRate, 30, 1000); }", 30, 5000, BF_MAGIC); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bMaxSP, 100); + } else { + bonus(bMaxSP, 50); + } + "> }, -*/ -/* UNKNOWN MONSTER { - Id: 0 + Id: 3790 Name: "Sweet Drops" EggItem: "Sweet_Drops_Egg" + FoodItem: "Candy" AutoFeed: true + EquipScript: <" + if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) + bonus2(bExpAddRace, RC_All, 1); + "> }, -*/ { - Id: 1159 + Id: 20425 Name: "Phreeoni" EggItem: "Phreeoni_Egg" + FoodItem: "Luxurious_Pet_Food" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bHit, 18); + bonus(bPerfectHitRate, 15); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bHit, 14); + bonus(bPerfectHitRate, 10); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bHit, 10); + bonus(bPerfectHitRate, 5); + } else { + bonus(bHit, 6); + } + "> }, { - Id: 1150 + Id: 20424 Name: "Moonlight Flower" EggItem: "Moonlight_Flower_Egg" + FoodItem: "Luxurious_Pet_Food" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bCritical, 6); + bonus(bHit, 6); + autobonus("{ bonus2(bHPRegenRate, 500, 1000); bonus2(bSPRegenRate, 20, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bCritical, 5); + bonus(bHit, 5); + autobonus("{ bonus2(bHPRegenRate, 400, 1000); bonus2(bSPRegenRate, 10, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bCritical, 4); + bonus(bHit, 4); + autobonus("{ bonus2(bHPRegenRate, 300, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT); + } else { + bonus(bCritical, 3); + bonus(bHit, 3); + } + "> }, -/* { Id: 3971 Name: "Skelion" EggItem: "Skelion_Egg" + FoodItem: "Yummy_Meat" + AccessoryItem: "Dark_Mane" + AutoFeed: true + EquipScript: <" + if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_CORDIAL) + bonus2(bAddItemHealRate, 579, 100); + "> +}, +{ + Id: 2336 + Name: "Domovoi" + EggItem: "Brownie_Egg" + EquipScript: <" + if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) { + bonus2(bAddRace, RC_DemiPlayer, 1); + bonus2(bMagicAddRace, RC_DemiPlayer, 1); + bonus2(bAddRaceTolerance, RC_DemiPlayer, 1); + } + "> +}, +{ + Id: 2963 + Name: "Woodie" + EggItem: "Woodie_Egg" + FoodItem: "Emerald_Leaf" +}, +{ + Id: 3162 + Name: "Elephant" + EggItem: "Elephant_Egg" + FoodItem: "Banana_Can" +}, +{ + Id: 3163 + Name: "Gorilla" + EggItem: "Gorilla_Egg" + FoodItem: "Spicy_Rice_Cake" +}, +{ + Id: 3164 + Name: "Lion" + EggItem: "Lion_Egg" + FoodItem: "Hot_Dog" +}, +{ + Id: 3165 + Name: "Rhino" + EggItem: "Rhino_Egg" + FoodItem: "Ferris_Wheel_Biscuit" +}, +{ + Id: 3261 + Name: "Blue Unicorn" + EggItem: "Blue_Unicorn_Egg" + FoodItem: "Blue_Herb" +}, +{ + Id: 1166 + Name: "Savage" + EggItem: "Savage_Egg" AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bVit, 2); + bonus(bMaxHP, 200); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bVit, 2); + bonus(bMaxHP, 100); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bVit, 2); + bonus(bMaxHP, 50); + } else { + bonus(bVit, 1); + bonus(bMaxHP, 50); + } + "> +}, +{ + Id: 1369 + Name: "Grand Peco" + EggItem: "Grand_Peco_Peco_Egg" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxHP, 400); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bMaxHP, 300); + else if (.@intimacy >= PET_INTIMACY_NEUTRAL) + bonus(bMaxHP, 200); + else + bonus(bMaxHP, 150); + "> +}, +{ + Id: 1213 + Name: "High Orc" + EggItem: "High_Orc_Egg" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAtk, 25); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bAtk, 20); + else if (.@intimacy >= PET_INTIMACY_NEUTRAL) + bonus(bAtk, 15); + else + bonus(bAtk, 10); + "> + Evolve: { + Orc_Hero_Egg_: { + Voucher_Of_Orcish_Hero: 10 + Orc_Warrior_Card: 10 + Orc_Baby_Card_Card: 10 + Mightysoul_Essence: 30 + } + } +}, +{ + Id: 20423 + Name: "Bacsojin" + EggItem: "Bacsojin2_Egg_" + FoodItem: "Luxurious_Pet_Food" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxSPrate, 5); + bonus(bDelayrate, -3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMaxSPrate, 4); + bonus(bDelayrate, -2); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bMaxSPrate, 3); + bonus(bDelayrate, -1); + } else { + bonus(bMaxSPrate, 2); + } + "> +}, +{ + Id: 20373 + Name: "Rigid Nightmare Terror" + EggItem: "Rigid_Nightmare_Terror_Egg" + FoodItem: "Luxurious_Pet_Food" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bInt, 4); + bonus(bMaxSPrate, 3); + bonus2(bResEff, Eff_Sleep, 10000); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bInt, 3); + bonus(bMaxSPrate, 1); + bonus2(bResEff, Eff_Sleep, 10000); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bInt, 2); + } else { + bonus(bInt, 1); + } + "> +}, +{ + Id: 20420 + Name: "Contaminated Wanderer Egg" + EggItem: "Contaminated_Wanderer_Egg" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAgi, 4); + bonus(bCritical, 3); + bonus(bCritAtkRate, 7); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bAgi, 4); + bonus(bCritical, 2); + bonus(bCritAtkRate, 5); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bAgi, 4); + bonus(bCritical, 1); + } else { + bonus(bAgi, 4); + } + "> +}, +{ + Id: 1736 + Name: "Aliot" + EggItem: "Aliot_Egg" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAspdRate, 5); + bonus(bHit, 12); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bAspdRate, 4); + bonus(bHit, 9); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bAspdRate, 3); + bonus(bHit, 6); + } else { + bonus(bAspdRate, 2); + } + "> +}, +{ + Id: 1735 + Name: "Alicel" + EggItem: "Alicel_Egg" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bVariableCastrate, -5); + bonus2(bMagicAddEle, Ele_Neutral, 5); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bVariableCastrate, -4); + bonus2(bMagicAddEle, Ele_Neutral, 3); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bVariableCastrate, -3); + } else { + bonus(bVariableCastrate, -2); + } + "> +}, +{ + Id: 1737 + Name: "Aliza" + EggItem: "Aliza_Egg" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMdef, 7); + bonus(bHealPower, 6); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMdef, 6); + bonus(bHealPower, 4); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bMdef, 5); + bonus(bHealPower, 2); + } else { + bonus(bMdef, 4); + } + "> +}, +{ + Id: 20571 + Name: "Orc Hero" + EggItem: "Orc_Hero_Egg_" + FoodItem: "Luxurious_Pet_Food" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bAtkRate, 7); + bonus(bCritAtkRate, 3); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bAtkRate, 4); + bonus(bCritAtkRate, 1); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bAtkRate, 2); + } else { + bonus(bAtkRate, 1); + } + "> +}, +{ + Id: 20619 + Name: "Gloom Under Night" + EggItem: "Gloom_Under_Night_Egg" + FoodItem: "Luxurious_Pet_Food" + AutoFeed: true + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMatk, 40); + bonus2(bMagicAtkEle, Ele_Ghost, 7); + bonus2(bMagicAtkEle, Ele_Fire, 7); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMatk, 30); + bonus2(bMagicAtkEle, Ele_Ghost, 5); + bonus2(bMagicAtkEle, Ele_Fire, 5); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus(bMatk, 20); + } else { + bonus(bMatk, 10); + } + "> +}, +{ + Id: 20696 + Name: "Child Admin Beta" + EggItem: "Child_Admin_Beta_Egg" + FoodItem: "Cloud_Cotton" + AccessoryItem: "Little_Headdress_Beta" + EquipScript: <" + .@map$ = strcharinfo(PC_MAP); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@map$ == "ba_lost" || .@map$ == "ba_pw02") { + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus2(bAddRace, RC_All, 10); + bonus2(bMagicAddRace, RC_All, 10); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus2(bAddRace, RC_All, 6); + bonus2(bMagicAddRace, RC_All, 6); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus2(bAddRace, RC_All, 3); + bonus2(bMagicAddRace, RC_All, 3); + } + } + "> + Evolve: { + Child_Admin_Alpha_Egg: { + Barmil_Ticket: 500 + Broken_Steel_Piece: 50 + Mystery_Piece: 10 + } + } +}, +{ + Id: 20697 + Name: "Child Admin Alpha" + EggItem: "Child_Admin_Alpha_Egg" + AccessoryItem: "Little_Headdress_Alpha" + AutoFeed: true + EquipScript: <" + .@map$ = strcharinfo(PC_MAP); + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@map$ == "ba_pw01" || .@map$ == "ba_pw03" || .@map$ == "ba_2whs01" || .@map$ == "ba_2whs02") { + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus2(bAddRace, RC_All, 15); + bonus2(bMagicAddRace, RC_All, 15); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus2(bAddRace, RC_All, 8); + bonus2(bMagicAddRace, RC_All, 8); + } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) { + bonus2(bAddRace, RC_All, 4); + bonus2(bMagicAddRace, RC_All, 4); + } + } + "> +}, +// jRO exclusive pets. +{ + Id: 3317 + Name: "Rubylit" + EggItem: "Rubylit_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAtk, 20); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bAtk, 10); + "> +}, +{ + Id: 3318 + Name: "Sapphilit" + EggItem: "Sapphilit_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxHP, 200); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bMaxHP, 100); + "> +}, +{ + Id: 3319 + Name: "Emelit" + EggItem: "Emelit_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) { + bonus(bMaxHP, 100); + bonus(bMaxSP, 50); + } else if (.@intimacy >= PET_INTIMACY_CORDIAL) { + bonus(bMaxHP, 50); + bonus(bMaxSP, 25); + } + "> +}, +{ + Id: 3320 + Name: "Topalit" + EggItem: "Topalit_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMaxSP, 100); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bMaxSP, 50); + "> +}, +{ + Id: 3321 + Name: "Amelit" + EggItem: "Amelit_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bMatk, 20); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bMatk, 10); + "> +}, +{ + Id: 3349 + Name: "Mythlit" + EggItem: "Mythlit_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_LOYAL) + bonus(bAllStats, 2); + else if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus(bAllStats, 1); + "> +}, +{ + Id: 3306 + Name: "Tamadora" + EggItem: "Tamadora_Egg" + EquipScript: <" + .@intimacy = getpetinfo(PETINFO_INTIMACY); + if (.@intimacy >= PET_INTIMACY_CORDIAL) + bonus4(bAutoSpellWhenHit, AL_HEAL, 1, 20, 1); + if (.@intimacy >= PET_INTIMACY_LOYAL) + skill(AL_HEAL, 1); + "> }, -*/ ) diff --git a/doc/constants.md b/doc/constants.md index f0c7f50c8..09ff61381 100644 --- a/doc/constants.md +++ b/doc/constants.md @@ -375,9 +375,13 @@ - `cell_landprotector`: 5 - `cell_novending`: 6 - `cell_nochat`: 7 +- `cell_icewall`: 8 +- `cell_noicewall`: 9 +- `cell_noskill`: 10 ### Cell checks +- `cell_gettype`: 0 - `cell_chkwall`: 1 - `cell_chkwater`: 2 - `cell_chkcliff`: 3 @@ -385,11 +389,15 @@ - `cell_chkreach`: 5 - `cell_chknopass`: 6 - `cell_chknoreach`: 7 +- `cell_chkstack`: 8 - `cell_chknpc`: 9 - `cell_chkbasilica`: 10 - `cell_chklandprotector`: 11 - `cell_chknovending`: 12 - `cell_chknochat`: 13 +- `cell_chkicewall`: 14 +- `cell_chknoicewall`: 15 +- `cell_chknoskill`: 16 ### Bonuses / Parameter IDs @@ -5105,6 +5113,12 @@ - `MST_AROUND4`: 12 - `MST_AROUND`: 12 +### Monster group constants + +- `ALL_MOBS_NONBOSS`: -1 +- `ALL_MOBS_BOSS`: -2 +- `ALL_MOBS`: -3 + ### pc block constants, use with *setpcblock* and *checkpcblock* - `PCBLOCK_NONE`: 0 @@ -8187,17 +8201,48 @@ - `FATAL_DAYS`: 2958 - `TORTUROUS_REDEEMER`: 2959 - `E_TORTUROUS_REDEEMER`: 2961 +- `WOODIE`: 2963 +- `XM_TEDDY_BEAR`: 2995 - `XM_CELINE_KIMI`: 2996 - `GRIM_REAPER_ANKOU`: 3029 - `TIMEHOLDER`: 3074 +- `ELEPHANT`: 3162 +- `GORILLA`: 3163 +- `LION`: 3164 +- `RHINO`: 3165 - `J_REB_SHECIL1`: 3169 - `J_REB_SHECIL2`: 3170 - `E1_FELOCK`: 3181 - `MM_SARAH`: 3190 - `ORGANIC_JAKK`: 3202 - `INORGANIC_JAKK`: 3203 +- `BLUE_UNICORN`: 3261 +- `PAD_TAMADORA`: 3306 +- `PAD_RUBYLIT`: 3317 +- `PAD_SAPPHILIT`: 3318 +- `PAD_EMELIT`: 3319 +- `PAD_TOPALIT`: 3320 +- `PAD_AMELIT`: 3321 +- `PAD_MYTHLIT`: 3349 - `DARK_SOUL`: 3381 - `WANDERING_SOUL`: 3382 +- `DR_EGGRING`: 3495 +- `DR_LUNATIC`: 3496 +- `LITTLE_ISIS`: 3636 +- `DIABOLIC2`: 3669 +- `DELETER_2`: 3670 +- `SCATLETON`: 3731 +- `SWEETS_DROPS`: 3790 +- `SKELION`: 3971 +- `NIGHTMARE_TERROR_H`: 20373 +- `WANDER_MAN_H`: 20420 +- `BACSOJIN2`: 20423 +- `MOONLIGHT2`: 20424 +- `PHREEONI2`: 20425 +- `ORK_HERO2`: 20571 +- `GLOOMUNDERNIGHT2`: 20619 +- `EP17_2_CHILD_ADMIN1`: 20696 +- `EP17_2_CHILD_ADMIN2`: 20697 ## Items (db/re/item_db.conf) - `Red_Potion`: 501 @@ -12726,6 +12771,8 @@ - `Memory_Of_Jack`: 6657 - `Halloween_Coin`: 6658 - `RWC_Inicializer`: 6665 +- `Emerald_Leaf`: 6669 +- `Log_`: 6670 - `Geffen_Magic_Coin`: 6671 - `Gray_Shard`: 6672 - `Bossnia_Pass`: 6673 @@ -12737,6 +12784,10 @@ - `Steel_Article`: 6746 - `Steel_Article_`: 6747 - `Corrupted_Charm`: 6755 +- `Banana_Can`: 6762 +- `Spicy_Rice_Cake`: 6763 +- `Hot_Dog`: 6764 +- `Ferris_Wheel_Biscuit`: 6765 - `ORGANIC_PUMPKIN`: 6804 - `INORGANIC_PUMPKIN`: 6805 - `Solo_Troops_Badge`: 6821 @@ -13750,9 +13801,22 @@ - `Brownie_Egg`: 9060 - `Marin_Egg`: 9061 - `Novice_Poring_Egg`: 9062 +- `Woodie_Egg`: 9063 +- `Elephant_Egg`: 9064 +- `Gorilla_Egg`: 9065 +- `Lion_Egg`: 9066 +- `Rhino_Egg`: 9067 +- `Blue_Unicorn_Egg`: 9068 - `Mastering_Egg`: 9069 - `Savage_Egg`: 9070 - `Grand_Peco_Peco_Egg`: 9071 +- `Rubylit_Egg`: 9074 +- `Sapphilit_Egg`: 9075 +- `Emelit_Egg`: 9076 +- `Topalit_Egg`: 9077 +- `Amelit_Egg`: 9078 +- `Mythlit_Egg`: 9079 +- `Tamadora_Egg`: 9080 - `High_Orc_Egg`: 9087 - `Angeling_Egg`: 9088 - `Am_Mut_Egg`: 9089 @@ -13779,6 +13843,16 @@ - `Phreeoni_Egg`: 9111 - `Moonlight_Flower_Egg`: 9112 - `Skelion_Egg`: 9113 +- `Bacsojin2_Egg_`: 9115 +- `Rigid_Nightmare_Terror_Egg`: 9116 +- `Contaminated_Wanderer_Egg`: 9117 +- `Aliot_Egg`: 9118 +- `Alicel_Egg`: 9119 +- `Aliza_Egg`: 9120 +- `Orc_Hero_Egg_`: 9121 +- `Gloom_Under_Night_Egg`: 9122 +- `Child_Admin_Beta_Egg`: 9123 +- `Child_Admin_Alpha_Egg`: 9124 - `Ein_Ddbox`: 9514 - `Metal_Rifine_Ticket`: 9523 - `Ein_Ddbox2`: 9529 @@ -13823,7 +13897,10 @@ - `Black_Butterfly_Mask`: 10037 - `Horn_Protector`: 10038 - `Tw_Backpack`: 10039 +- `Red_Bell_Necklace`: 10040 - `Dark_Mane`: 10042 +- `Little_Headdress_Beta`: 10043 +- `Little_Headdress_Alpha`: 10044 - `Prontera_Book_01`: 11000 - `Adventure_Story01`: 11001 - `Great_Chef_Orleans01`: 11002 @@ -13947,6 +14024,7 @@ - `Trance_Candy_Y`: 11594 - `Trance_Candy_G`: 11595 - `Catnip_Fruit`: 11602 +- `Cookie_Bat`: 11605 - `Crepe`: 11607 - `Chocolate_Egg`: 11608 - `Yummy_Cookie_Egg`: 11609 @@ -13954,6 +14032,7 @@ - `Aromatic_Pop_Corn`: 11612 - `Fresh_Milk`: 11614 - `Sweet_Potato_`: 11615 +- `Yummy_Meat`: 11616 - `Bearopy`: 11620 - `Aromatic_Pop_Corn_`: 11625 - `Girl_Bunch_Of_Flower`: 11701 @@ -18170,6 +18249,9 @@ - `Integer_Time`: 22837 - `Something_Candy_Holder`: 22838 - `Old_Money_Pocket`: 22876 +- `Sap_Jelly`: 23187 +- `Unprocessed_Parts`: 23188 +- `SmallDoll_Needle`: 23189 - `Fried_Chicken`: 23242 - `Fried_Chicken_1`: 23243 - `Elixir_Bandage`: 23256 @@ -18823,6 +18905,9 @@ - `S_Genesis_Pendant`: 24582 - `S_Genesis_Earing`: 24583 - `Slug_Bullet`: 25187 +- `Suspicious_Bottle`: 25231 +- `Cheap_Lubricant`: 25232 +- `Cotton_Tufts`: 25233 - `BrokenArrow`: 25258 - `Shining_Spore`: 25265 - `Dried_Leaf_Of_Ygg`: 25266 @@ -18832,6 +18917,7 @@ - `Happiness_Clover`: 25295 - `Golden_Corn`: 25340 - `Mightysoul_Essence`: 25375 +- `Luxurious_Pet_Food`: 25377 - `Captured_Savage`: 25390 - `Goodly_Bough`: 25391 - `Free_Pass_Ticket`: 25392 @@ -18983,6 +19069,8 @@ - `Ein_1HWHIP`: 26215 - `Faceworm_Queen_Card`: 27164 - `Captain_Felock_Card`: 27182 +- `Rigid_Nightmare_Terror_Card`: 27352 +- `Contaminated_Wanderer_Card`: 27361 - `Thanos_Katar`: 28000 - `Katar_Of_Evil_Slayer`: 28001 - `Half_BF_Katar2`: 28002 @@ -19130,6 +19218,7 @@ - `GH_Cursed_Crystal_`: 29590 - `Cursed_Emerald`: 29591 - `Shinee_Opal`: 29592 +- `Abandoned_Teddy_Bear_Card`: 31022 - `Roast_Memory`: 31172 - `C_Black_Cat`: 31186 - `Choco_Minihat`: 31195 @@ -19313,6 +19402,7 @@ - `Imperial_Trip_Suit`: 450074 - `ILL_Piece_B`: 100004 - `Imperial_Firerain_Suit`: 450075 +- `Cloud_Cotton`: 1000227 - `Imperial_Crimson_Robe`: 450076 - `Imperial_Frost_Robe`: 450077 - `Imperial_Psychic_Robe`: 450078 @@ -19435,6 +19525,7 @@ - `Boost_Gatling`: 830000 - `Abyss_Ddbox3`: 100144 - `Abyss_Ddbox4`: 100145 +- `Barmil_Ticket`: 1000103 > End of list diff --git a/doc/mob_skill_db.md b/doc/mob_skill_db.md new file mode 100644 index 000000000..12d3649de --- /dev/null +++ b/doc/mob_skill_db.md @@ -0,0 +1,223 @@ +# Monster skill database + +<!-- +## Copyright +> This file is part of Hercules. +> http://herc.ws - http://github.com/HerculesWS/Hercules +> +> Copyright (C) 2020 Hercules Dev Team +> Copyright (C) Zarbony +> Copyright (C) Kenpachi +> +> 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/>. +--> + +## Description +This file is a documentation for the monster skill database files. + * [db/mob_skill_db2.conf](../db/mob_skill_db2.conf) + * [db/pre-re/mob_skill_db.conf](../db/pre-re/mob_skill_db.conf) + * [db/re/mob_skill_db.conf](../db/re/mob_skill_db.conf) + +-------------------------------------------------------------- + +## Entry structure +``` + <Monster_Constant>: { + <Skill_Constant>: { + ClearSkills: + SkillLevel: + SkillState: + SkillTarget: + Rate: + CastTime: + Delay: + Cancelable: + CastCondition: + ConditionData: + val0: + val1: + val2: + val3: + val4: + Emotion: + ChatMsgID: + } + } +``` + +-------------------------------------------------------------- + +## Field list + +Name | Data type | Default value +:--------------- | :-------- | :------------ +Monster_Constant | constant | No default value +Skill_Constant | constant | No default value +ClearSkills | boolean | false +SkillLevel | int | 1 +SkillState | string | "MSS_ANY" +SkillTarget | string | "MST_TARGET" +Rate | int | 1 +CastTime | int | 0 +Delay | int | 0 +Cancelable | boolean | false +CastCondition | string | "MSC_ALWAYS" +ConditionData | int | 0 +val0 | int | 0 +val1 | int | 0 +val2 | int | 0 +val3 | int | 0 +val4 | int | 0 +Emotion | int | -1 +ChatMsgID | int | 0 + +-------------------------------------------------------------- + +## Field explanation + +### Monster_Constant +The monster's name constant, found in [mob_db.conf](../db/re/mob_db.conf) as *SpriteName*. +There are 3 special constants for global skill assignment: +* `ALL_MOBS`: Add skills to all monsters. +* `ALL_MOBS_BOSS`: Add skills to all boss monsters. +* `ALL_MOBS_NONBOSS`: Add skills to all non-boss monsters. + +### Skill_Constant +The skill's name constant, found in [skill_db.conf](../db/re/skill_db.conf) as *Name*. +Note: You can add multiple Skill_Constant blocks. + +### ClearSkills +If set to `true`, all previously defined skills for this monster will be removed. + +### SkillLevel +The skill level which should be used. +Minimum value is `1`. Maximum value is `mob_max_skilllvl` from [conf/map/battle/skill.conf](../conf/map/battle/skill.conf#L318). + +### SkillState +Defines in which state the monster is able to cast the skill. +State | Description +:------------ | :---------- +MSS_ANY | Monster is in any state except `MSS_DEAD`. +MSS_IDLE | Monster has no target and isn't walking. +MSS_WALK | Monster is walking. +MSS_LOOT | Monster is looting or walking to loot. +MSS_DEAD | Monster is dying. +MSS_BERSERK | Monster is attacking after starting the battle. +MSS_ANGRY | Monster is attacking after being attacked. +MSS_RUSH | Monster is following an enemy after being attacked. +MSS_FOLLOW | Monster is following an enemy without being attacked. +MSS_ANYTARGET | Same as `MSS_ANY` but monster must have a target. + +### SkillTarget +Defines the skill's target. +Target | Description +:---------- | :---------- +MST_TARGET | The monster's current target. +MST_RANDOM | A random enemy within skill range. +MST_SELF | The monster itself. +MST_FRIEND | A random friend within skill range. If no friend was found, `MST_SELF` is used. +MST_MASTER | The monster's master. If no master was found, `MST_FRIEND` is used. +MST_AROUND1 | Random cell within a range of `1`. (Affects ground skills only.) +MST_AROUND2 | Random cell within a range of `2`. (Affects ground skills only.) +MST_AROUND3 | Random cell within a range of `3`. (Affects ground skills only.) +MST_AROUND4 | Random cell within a range of `4`. (Affects ground skills only.) +MST_AROUND5 | Same as `MST_AROUND1`, but the monster's current target must be in skill range. +MST_AROUND6 | Same as `MST_AROUND2`, but the monster's current target must be in skill range. +MST_AROUND7 | Same as `MST_AROUND3`, but the monster's current target must be in skill range. +MST_AROUND8 | Same as `MST_AROUND4`, but the monster's current target must be in skill range. +MST_AROUND | Same as `MST_AROUND4`. + +### Rate +The chance of successfully casting the skill if the condition is fulfilled. (10000 = 100%) +Minimum value is `1`. Maximum value is `10000`. + +### CastTime +The skill's cast time in milliseconds. +Minimum value is `0`. Maximum value is `MOB_MAX_CASTTIME` from [src/map/mob.c](../src/map/mob.c#L81). + +### Delay +The time in milliseconds before attempting to cast the same skill again. +Minimum value is `0`. Maximum value is `MOB_MAX_DELAY` from [src/map/mob.c](../src/map/mob.c#L82). + +### Cancelable +Defines whether the skill is cancelable or not. + +### CastCondition +Defines the condition to successfully cast the skill. +Condition | Description +:-------------------- | :---------- +MSC_ALWAYS | No condition. +MSC_MYHPLTMAXRATE | Monster's HP in percent is less than or equal to `ConditionData`. +MSC_MYHPINRATE | Monster's HP in percent is greater than or equal to `ConditionData` and less than or equal to `val0`. +MSC_FRIENDHPLTMAXRATE | Friend's HP in percent is less than or equal to `ConditionData`. +MSC_FRIENDHPINRATE | Friend's HP in percent is greater than or equal to `ConditionData` and less than or equal to `val0`. +MSC_MYSTATUSON | Monster has status change `ConditionData` enabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.) +MSC_MYSTATUSOFF | Monster has status change `ConditionData` disabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.) +MSC_FRIENDSTATUSON | Friend has status change `ConditionData` enabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.) +MSC_FRIENDSTATUSOFF | Friend has status change `ConditionData` disabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.) +MSC_ATTACKPCGT | Monster is attacked by more than `ConditionData` units. +MSC_ATTACKPCGE | Monster is attacked by `ConditionData` or more units. +MSC_SLAVELT | Monster has less than `ConditionData` slaves. +MSC_SLAVELE | Monster has `ConditionData` or less active slaves. +MSC_CLOSEDATTACKED | Monster is melee attacked. +MSC_LONGRANGEATTACKED | Monster is range attacked. +MSC_AFTERSKILL | Monster has used skill `ConditionData`. (If `ConditionData` is `0`, all skills are triggered.) +MSC_SKILLUSED | Skill `ConditionData` was used on the monster. (If `ConditionData` is `0`, all skills are triggered.) +MSC_CASTTARGETED | A skill is being cast on the monster. +MSC_RUDEATTACKED | Monster was rude attacked `RUDE_ATTACKED_COUNT` times. ([src/map/mob.c#L84](../src/map/mob.c)) +MSC_MASTERHPLTMAXRATE | The monster master's HP in percent is less than `ConditionData`. +MSC_MASTERATTACKED | The monster's master is attacked. +MSC_ALCHEMIST | The monster was summoned by an Alchemist class character. +MSC_SPAWN | The monster spawns. + +### ConditionData +Additional cast condition data. Meaning depends on the situation. See `CastCondition` table. + +### val0 +Additional data. Meaning depends on the situation. + * `MSC_MYHPINRATE`/`MSC_FRIENDHPINRATE`: See `CastCondition` table. + * `NPC_SUMMONMONSTER`: Slave monster ID. + * `NPC_SUMMONSLAVE`: Slave monster ID. + * `NPC_METAMORPHOSIS`: Transform monster ID. + * `NPC_EMOTION`: Emotion ID. (See [doc/constants.md](./constants.md#emotes) for a list of available emotions.) + * `NPC_EMOTION_ON`: Emotion ID. (See [doc/constants.md](./constants.md#emotes) for a list of available emotions.) + +### val1 +Additional data. Meaning depends on the situation. + * `NPC_SUMMONMONSTER`: Slave monster ID. + * `NPC_SUMMONSLAVE`: Slave monster ID. + * `NPC_METAMORPHOSIS`: Transform monster ID. + * `NPC_EMOTION`: Monster's mode is changed to specified value. + * `NPC_EMOTION_ON`: Monster's mode is changed to specified value. + +### val2 +Additional data. Meaning depends on the situation. + * `NPC_SUMMONMONSTER`: Slave monster ID. + * `NPC_SUMMONSLAVE`: Slave monster ID. + * `NPC_METAMORPHOSIS`: Transform monster ID. + +### val3 +Additional data. Meaning depends on the situation. + * `NPC_SUMMONMONSTER`: Slave monster ID. + * `NPC_SUMMONSLAVE`: Slave monster ID. + * `NPC_METAMORPHOSIS`: Transform monster ID. + +### val4 +Additional data. Meaning depends on the situation. + * `NPC_SUMMONMONSTER`: Slave monster ID. + * `NPC_SUMMONSLAVE`: Slave monster ID. + * `NPC_METAMORPHOSIS`: Transform monster ID. + +### Emotion +The ID of the emotion the monster will use when casting the skill. +(See [doc/constants.md](./constants.md#emotes) for a list of available emotions.) + +### ChatMsgID +The ID of the message the monster will say when casting the skill. +(See [db/mob_chat_db.txt](../db/mob_chat_db.txt) for a list of available messages.) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 9dcf21978..a597dfaa2 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -536,7 +536,9 @@ variables or an empty string ("", nothing between the quotes) for string variables. Once you set it to that, the variable is as good as forgotten forever, and no trace remains of it even if it was stored with character or account data. The maximum length of variable name including prefix and -suffix is 32. +suffix is 32. Permanent string variables (name$, $name$, #name$, ##name$) +can store text with a maximum length of 255 characters. All other string +type variables have no such limitation. Some variables are special, that is, they are already defined for you by the scripting engine. You can see the full list somewhere in @@ -1710,7 +1712,8 @@ The default value of 'min' and 'max' can be set with 'input_min_value' and For numeric inputs the value is capped to the range [min, max]. Returns 1 if the value was higher than 'max', -1 if lower than 'min' and 0 otherwise. For string inputs it returns 1 if the string was longer than 'max', -1 is -shorter than 'min' and 0 otherwise. +shorter than 'min' and 0 otherwise. Note that an input string has a maximum +length of 70 characters. --------------------------------------- diff --git a/sql-files/item_db.sql b/sql-files/item_db.sql index ac3cad389..70ecb2094 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','2 REPLACE INTO `item_db` VALUES ('12115','Elemental_Water','Elemental Converter','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','itemskill ITEM_ENCHANTARMS,2;','',''); REPLACE INTO `item_db` VALUES ('12116','Elemental_Earth','Elemental Converter','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','itemskill ITEM_ENCHANTARMS,3;','',''); REPLACE INTO `item_db` VALUES ('12117','Elemental_Wind','Elemental Converter','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','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_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 ('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_start2(SC_RESIST_PROPERTY_FIRE, 1200000, 20, -15);','',''); +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_start2(SC_RESIST_PROPERTY_WATER, 1200000, 20, -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_start2(SC_RESIST_PROPERTY_GROUND, 1200000, 20, -15);','',''); +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_start2(SC_RESIST_PROPERTY_WIND, 1200000, 20, -15);','',''); 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_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 ('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 ('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 a24b385f7..c378bbc88 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -4212,7 +4212,7 @@ REPLACE INTO `item_db` VALUES ('6217','Mandragora_Flowerpot','Mandragora Flowerp REPLACE INTO `item_db` VALUES ('6218','Disin_Delivery_Box','Dieshin\'s Delivery Box','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6219','Para_Team_Mark','Eden Group Mark','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6220','Mysterious_Dyestuff','Mysterious Dyestuffs','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 ('6221','Mystic_Leaf_Cat_Ball','Mystic Hydra Ball','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 ('6221','Mystic_Leaf_Cat_Ball','Mystic Hydra Ball','7','0','20','10','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 ('6222','Shining_Beads','Shining Beads','3','0','20','10','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 ('6223','Carnium','Carnium','3','0','2000','1000','150','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','','',''); REPLACE INTO `item_db` VALUES ('6224','Bradium','Bradium','3','0','2000','1000','150','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','','',''); @@ -4595,6 +4595,8 @@ REPLACE INTO `item_db` VALUES ('6656','Goast_Free_Charm','Controlling Amulet','3 REPLACE INTO `item_db` VALUES ('6657','Memory_Of_Jack','Jack Memories','3','0','0','0','0','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 ('6658','Halloween_Coin','Halloween Coin','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 ('6665','RWC_Inicializer','RWC Enchant Reset Ticket','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 ('6669','Emerald_Leaf','Emerald Leaf','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 ('6670','Log_','Tree Log','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 ('6671','Geffen_Magic_Coin','Geffen Magic Tournament Coin','3','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6672','Gray_Shard','Gray Piece','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('6673','Bossnia_Pass','Ticket to Bossnia','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','',''); @@ -4606,6 +4608,10 @@ REPLACE INTO `item_db` VALUES ('6712','Lovely_Stick','Love Wand','3','0','0','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 ('6762','Banana_Can','Banana Can','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 ('6763','Spicy_Rice_Cake','Spicy Rice Cake','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 ('6764','Hot_Dog','Hot Dog','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 ('6765','Ferris_Wheel_Biscuit','Ferris Wheel Biscuit','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 ('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','','',''); REPLACE INTO `item_db` VALUES ('6821','Solo_Troops_Badge','Single Union Badge','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','',''); @@ -5619,9 +5625,22 @@ REPLACE INTO `item_db` VALUES ('9059','Tikbalang_Pet','Tikbalang Egg','7','0','2 REPLACE INTO `item_db` VALUES ('9060','Brownie_Egg','Egg of Domovoi','7','0','20','10','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 ('9061','Marin_Egg','Marin Egg','7','0','20','10','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 ('9062','Novice_Poring_Egg','Novice Poring Egg','7','0','20','10','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 ('9063','Woodie_Egg','Woodie Egg','7','0','20','10','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 ('9064','Elephant_Egg','Elephant Egg','7','0','20','10','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 ('9065','Gorilla_Egg','Gorilla Egg','7','0','20','10','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 ('9066','Lion_Egg','Lion Egg','7','0','20','10','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 ('9067','Rhino_Egg','Rhino Egg','7','0','20','10','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 ('9068','Blue_Unicorn_Egg','Blue Unicorn Egg','7','0','20','10','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 ('9069','Mastering_Egg','Mastering Egg','7','0','20','10','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 ('9070','Savage_Egg','Savage Egg','7','0','20','10','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 ('9071','Grand_Peco_Peco_Egg','Grand Peco Peco Egg','7','0','20','10','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 ('9074','Rubylit_Egg','Rubylit Egg','7','0','20','10','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 ('9075','Sapphilit_Egg','Sapphilit Egg','7','0','20','10','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 ('9076','Emelit_Egg','Emelit Egg','7','0','20','10','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 ('9077','Topalit_Egg','Topalit Egg','7','0','20','10','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 ('9078','Amelit_Egg','Amelit Egg','7','0','20','10','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 ('9079','Mythlit_Egg','Mythlit Egg','7','0','20','10','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 ('9080','Tamadora_Egg','Tamadora Egg','7','0','20','10','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 ('9087','High_Orc_Egg','High Orc Egg','7','0','20','10','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 ('9088','Angeling_Egg','Angeling Egg','7','0','20','10','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 ('9089','Am_Mut_Egg','Am Mut Egg','7','0','20','10','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','','',''); @@ -5649,6 +5668,16 @@ REPLACE INTO `item_db` VALUES ('9111','Phreeoni_Egg','Phreeoni Egg','7','0','20' REPLACE INTO `item_db` VALUES ('9112','Moonlight_Flower_Egg','Moonlight Flower Egg','7','0','20','10','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 ('9113','Skelion_Egg','Skelion Egg','7','0','20','10','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 ('9514','Ein_Ddbox','Ein_Ddbox','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 ('9115','Bacsojin2_Egg_','Bacsojin Egg','7','0','20','10','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 ('9116','Rigid_Nightmare_Terror_Egg','Rigid Nightmare Terror Egg','7','0','20','10','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 ('9117','Contaminated_Wanderer_Egg','Contaminated Wanderer Egg','7','0','20','10','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 ('9118','Aliot_Egg','Aliot Egg','7','0','20','10','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 ('9119','Alicel_Egg','Alicel Egg','7','0','20','10','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 ('9120','Aliza_Egg','Aliza Egg','7','0','20','10','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 ('9121','Orc_Hero_Egg_','Orc Hero Egg','7','0','20','10','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 ('9122','Gloom_Under_Night_Egg','Gloom Under Night Egg','7','0','20','10','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 ('9123','Child_Admin_Beta_Egg','Child Admin Beta Egg','7','0','20','10','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 ('9124','Child_Admin_Alpha_Egg','Child Admin Alpha Egg','7','0','20','10','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 ('9523','Metal_Rifine_Ticket','Metal_Rifine_Ticket','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 ('9529','Ein_Ddbox2','Ein_Ddbox2','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 ('9550','Gemstone_Of_Time','Gemstone_Of_Time','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','','',''); @@ -5692,7 +5721,10 @@ REPLACE INTO `item_db` VALUES ('10036','Hell_Horn','Horn Of Hell','8','0','20',' REPLACE INTO `item_db` VALUES ('10037','Black_Butterfly_Mask','Black Butterfly Mask','8','0','20','10','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 ('10038','Horn_Protector','Horn Barrier','8','0','20','10','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 ('10039','Tw_Backpack','Tw Backpack','8','0','20','10','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 ('10042','Dark_Mane','Dark_Mane','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 ('10040','Red_Bell_Necklace','Red Bell Necklace','8','0','20','10','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 ('10042','Dark_Mane','Dark_Mane','8','0','20','10','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 ('10043','Little_Headdress_Beta','Little Headdress Beta','8','0','20','10','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 ('10044','Little_Headdress_Alpha','Little Headdress Alpha','8','0','20','10','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 ('11000','Prontera_Book_01','History book of Prontera','3','0','8000','4000','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','','',''); REPLACE INTO `item_db` VALUES ('11001','Adventure_Story01','Adventure Story Vol.1','3','0','8000','4000','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','','',''); REPLACE INTO `item_db` VALUES ('11002','Great_Chef_Orleans01','Chef King Orleans Vol.1','3','0','8000','4000','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','','',''); @@ -5816,6 +5848,7 @@ REPLACE INTO `item_db` VALUES ('11593','Trance_Candy_B','Blue Transform Candy',' REPLACE INTO `item_db` VALUES ('11594','Trance_Candy_Y','Yellow Transform Candy','0','0','0','0','30','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','itemheal rand(45,65),0; specialeffect(EF_CLOAKING, AREA, playerattached()); showscript \"Trans-Form-!! Jack Fo-rm!!\"; montransform JAKK, 600000, SC_MTF_PUMPKIN, 2000;','',''); REPLACE INTO `item_db` VALUES ('11595','Trance_Candy_G','Green Transform Candy','0','0','0','0','30','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','itemheal rand(45,65),0; specialeffect(EF_CLOAKING, AREA, playerattached()); showscript \"Trans-Form-!! Cube Fo-rm!!\"; montransform QUVE, 600000, SC_MTF_HITFLEE, 10, 20;','',''); REPLACE INTO `item_db` VALUES ('11602','Catnip_Fruit','Catnip Fruit','0','0','15','7','1','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','itemheal rand(10,40),0;','',''); +REPLACE INTO `item_db` VALUES ('11605','Cookie_Bat','Cookie Bat','0','0','0','0','50','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','itemheal(rand(50, 100), 0);','',''); REPLACE INTO `item_db` VALUES ('11607','Crepe','Crepe','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 ('11608','Chocolate_Egg','Chocolate_Egg','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 ('11609','Yummy_Cookie_Egg','Yummy_Cookie_Egg','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','','',''); @@ -5823,6 +5856,7 @@ REPLACE INTO `item_db` VALUES ('11611','Pop_Corn','Pop_Corn','3','0','0','0','0' REPLACE INTO `item_db` VALUES ('11612','Aromatic_Pop_Corn','Aromatic_Pop_Corn','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 ('11614','Fresh_Milk','Fresh_Milk','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 ('11615','Sweet_Potato_','Sweet_Potato_','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 ('11616','Yummy_Meat','Yummy Meat','0','0','0','0','50','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 ('11620','Bearopy','Bearopy','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 ('11625','Aromatic_Pop_Corn_','Aromatic_Pop_Corn_','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 ('11701','Girl_Bunch_Of_Flower','Girl\'s Bouquet','0','0','20','10','50','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','itemheal rand(105,145),0;','',''); @@ -5961,10 +5995,10 @@ REPLACE INTO `item_db` VALUES ('12114','Elemental_Fire','Elemental Converter','2 REPLACE INTO `item_db` VALUES ('12115','Elemental_Water','Elemental Converter','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','itemskill ITEM_ENCHANTARMS,2;','',''); REPLACE INTO `item_db` VALUES ('12116','Elemental_Earth','Elemental Converter','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','itemskill ITEM_ENCHANTARMS,3;','',''); REPLACE INTO `item_db` VALUES ('12117','Elemental_Wind','Elemental Converter','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','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_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 ('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_start2(SC_RESIST_PROPERTY_FIRE, 1200000, 20, -15);','',''); +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_start2(SC_RESIST_PROPERTY_WATER, 1200000, 20, -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_start2(SC_RESIST_PROPERTY_GROUND, 1200000, 20, -15);','',''); +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_start2(SC_RESIST_PROPERTY_WIND, 1200000, 20, -15);','',''); 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;','',''); @@ -6119,7 +6153,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_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 ('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 ('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;','',''); @@ -10039,6 +10073,9 @@ REPLACE INTO `item_db` VALUES ('22808','Special_Gift_Box','Special Gift Box','2' REPLACE INTO `item_db` VALUES ('22837','Integer_Time','Integer Time','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','50',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','TmpRouletteBronze += 1;','',''); REPLACE INTO `item_db` VALUES ('22838','Something_Candy_Holder','Pumpkin Candy Holder','2','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','getrandgroupitem 22838,1;','',''); REPLACE INTO `item_db` VALUES ('22876','Old_Money_Pocket','Old Money Pocket','2','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','Zeny += rand(500, 550);','',''); +REPLACE INTO `item_db` VALUES ('23187','Sap_Jelly','Sap Jelly','2','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,'1',NULL,'0',NULL,'0','pet(NINE_TAIL);','',''); +REPLACE INTO `item_db` VALUES ('23188','Unprocessed_Parts','Unprocessed Parts','2','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,'1',NULL,'0',NULL,'0','pet(GREMLIN);','',''); +REPLACE INTO `item_db` VALUES ('23189','SmallDoll_Needle','Small Doll Needle','2','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,'1',NULL,'0',NULL,'0','pet(TEDDY_BEAR);','',''); REPLACE INTO `item_db` VALUES ('23242','Fried_Chicken','Fried_Chicken','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 ('23243','Fried_Chicken_1','Fried_Chicken_1','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 ('23256','Elixir_Bandage','Elixir_Bandage','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','','',''); @@ -10692,6 +10729,9 @@ REPLACE INTO `item_db` VALUES ('24581','S_Genesis_Weapon','S_Genesis_Weapon','3' 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 ('25231','Suspicious_Bottle','Suspicious Bottle','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 ('25232','Cheap_Lubricant','Cheap Lubricant','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 ('25233','Cotton_Tufts','Cotton Tufts','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 ('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','','',''); @@ -10701,6 +10741,7 @@ REPLACE INTO `item_db` VALUES ('25294','Clover_Ticket','Clover_Ticket','3','0',' REPLACE INTO `item_db` VALUES ('25295','Happiness_Clover','Happiness_Clover','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 ('25340','Golden_Corn','Golden_Corn','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 ('25375','Mightysoul_Essence','Mightysoul_Essence','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 ('25377','Luxurious_Pet_Food','Luxurious Pet Food','3','0','0','0','1','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 ('25390','Captured_Savage','Captured_Savage','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 ('25391','Goodly_Bough','Goodly_Bough','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 ('25392','Free_Pass_Ticket','Free_Pass_Ticket','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','','',''); @@ -10852,6 +10893,8 @@ REPLACE INTO `item_db` VALUES ('26164','ElectricFox_OS','ElectricFox_OS','3','0' REPLACE INTO `item_db` VALUES ('26215','Ein_1HWHIP','Ein_1HWHIP','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 ('27164','Faceworm_Queen_Card','Faceworm Queen Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','64','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bMaxHPrate, -10); bonus(bCritical, 15 + getrefine()); bonus(bCritAtkRate, getrefine());','',''); REPLACE INTO `item_db` VALUES ('27182','Captain_Felock_Card','Captain Felock Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','2','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bAtk, 30); bonus2(bSkillAtk, RL_AM_BLAST, getrefine() >= 10 ? 60 : 30); bonus2(bSkillAtk, RL_HAMMER_OF_GOD, getrefine() >= 10 ? 60 : 30);','',''); +REPLACE INTO `item_db` VALUES ('27352','Rigid_Nightmare_Terror_Card','Rigid Nightmare Terror Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','64','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bMaxSPrate, 5);','',''); +REPLACE INTO `item_db` VALUES ('27361','Contaminated_Wanderer_Card','Contaminated Wanderer Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','2','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2(bAddSize,Size_Medium, 30); bonus2(bAddSize,Size_Large, 30);','',''); REPLACE INTO `item_db` VALUES ('28000','Thanos_Katar','Thanatos Katar','4','16','20','10','1800','220','80','0','1','1','4096','56','2','34','4','120',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,6; bonus bVit,6; bonus bLuk,-6; bonus2 bSPDrainRate,10,5; bonus2 bHPDrainRate,10,5; bonus2 bHPLossRate,100,10000;','','heal -1000,0;'); REPLACE INTO `item_db` VALUES ('28001','Katar_Of_Evil_Slayer','Evil Slayer Ripper Katar','4','16','20','10','1200','120','0','0','1','1','4096','56','2','34','3','100',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddRace,RC_Demon,10; bonus2 bAddRace,RC_Undead,10; if(getrefine()>8) { bonus bAtkRate,5; } if(getrefine()>11) { bonus bAtkRate,7; }','',''); REPLACE INTO `item_db` VALUES ('28002','Half_BF_Katar2','Half BF Katar2','4','16','20','10','0','130','0','0','1','0','4096','63','2','34','3','80',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,1; bonus bDex,1; bonus bLuk,1; bonus2 bAddRace,RC_DemiPlayer,35; bonus bCritAtkRate,10; bonus bAspdRate,3; bonus bUnbreakableWeapon,0;','',''); @@ -10999,6 +11042,7 @@ REPLACE INTO `item_db` VALUES ('29589','GH_Cursed_Gemstone_','GH_Cursed_Gemstone REPLACE INTO `item_db` VALUES ('29590','GH_Cursed_Crystal_','GH_Cursed_Crystal_','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 ('29591','Cursed_Emerald','Cursed_Emerald','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 ('29592','Shinee_Opal','Shinee_Opal','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 ('31022','Abandoned_Teddy_Bear_Card','Abandoned Teddy Bear Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','64','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bMaxSPrate, 20); bonus2(bAddEff2, Eff_Curse, 20);','',''); REPLACE INTO `item_db` VALUES ('31172','Roast_Memory','Roast_Memory','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 ('31186','C_Black_Cat','C_Black_Cat','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 ('31195','Choco_Minihat','Choco_Minihat','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','','',''); @@ -11292,6 +11336,7 @@ REPLACE INTO `item_db` VALUES ('1000016','HighpriestStone_Top2','HighpriestStone REPLACE INTO `item_db` VALUES ('1000017','HighpriestStone_Middle2','HighpriestStone_Middle2','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 ('1000018','HighpriestStone_Bottom2','HighpriestStone_Bottom2','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 ('1000019','ArchbishopStone_Robe2','ArchbishopStone_Robe2','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 ('1000103','Barmil_Ticket','Barmil Ticket','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 ('1000213','WarlockStone_Robe2','WarlockStone_Robe2','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 ('1000214','WarlockStone_Top2','WarlockStone_Top2','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 ('1000215','WarlockStone_Middle2','WarlockStone_Middle2','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','','',''); @@ -11304,3 +11349,4 @@ REPLACE INTO `item_db` VALUES ('1000221','GuillcrossStone_Robe2','GuillcrossSton REPLACE INTO `item_db` VALUES ('1000222','AssacrossStone_Top2','AssacrossStone_Top2','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 ('1000223','AssacrossStone_Middle2','AssacrossStone_Middle2','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 ('1000224','AssacrossStone_Bottom2','AssacrossStone_Bottom2','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 ('1000227','Cloud_Cotton','Cloud Cotton','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','','',''); diff --git a/sql-files/main.sql b/sql-files/main.sql index dcd7e543d..d5b7735fc 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -51,7 +51,7 @@ CREATE TABLE IF NOT EXISTS `acc_reg_str_db` ( `account_id` INT UNSIGNED NOT NULL DEFAULT '0', `key` VARCHAR(32) BINARY NOT NULL DEFAULT '', `index` INT UNSIGNED NOT NULL DEFAULT '0', - `value` VARCHAR(254) NOT NULL DEFAULT '0', + `value` VARCHAR(255) NOT NULL DEFAULT '0', PRIMARY KEY (`account_id`,`key`,`index`), KEY `account_id` (`account_id`) ) ENGINE=MyISAM; @@ -275,7 +275,7 @@ CREATE TABLE IF NOT EXISTS `char_reg_str_db` ( `char_id` INT UNSIGNED NOT NULL DEFAULT '0', `key` VARCHAR(32) BINARY NOT NULL DEFAULT '', `index` INT UNSIGNED NOT NULL DEFAULT '0', - `value` VARCHAR(254) NOT NULL DEFAULT '0', + `value` VARCHAR(255) NOT NULL DEFAULT '0', PRIMARY KEY (`char_id`,`key`,`index`), KEY `char_id` (`char_id`) ) ENGINE=MyISAM; @@ -372,7 +372,7 @@ CREATE TABLE IF NOT EXISTS `global_acc_reg_str_db` ( `account_id` INT UNSIGNED NOT NULL DEFAULT '0', `key` VARCHAR(32) BINARY NOT NULL DEFAULT '', `index` INT UNSIGNED NOT NULL DEFAULT '0', - `value` VARCHAR(254) NOT NULL DEFAULT '0', + `value` VARCHAR(255) NOT NULL DEFAULT '0', PRIMARY KEY (`account_id`,`key`,`index`), KEY `account_id` (`account_id`) ) ENGINE=MyISAM; @@ -938,6 +938,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1574463539); -- 2019-11-2 INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1579817630); -- 2020-01-24--01-09.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1584838560); -- 2020-03-22--01-56.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1584842940); -- 2020-03-22--03-09.sql +INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1588301040); -- 2020-05-01--04-44.sql -- -- Table structure for table `storage` diff --git a/sql-files/mob_db_re.sql b/sql-files/mob_db_re.sql index 713054e9c..4864affb2 100644 --- a/sql-files/mob_db_re.sql +++ b/sql-files/mob_db_re.sql @@ -1806,14 +1806,45 @@ REPLACE INTO `mob_db` VALUES (2957,'FORGOTTEN_NAME','Forgotten Name','Forgotten REPLACE INTO `mob_db` VALUES (2958,'FATAL_DAYS','Fatal Days','Fatal Days',120,24240,1,2052,2026,2,1025,403,84,41,100,71,63,85,115,37,10,12,1,6,67,14469,170,720,384,480,0,0,0,0,0,0,0,1038,2500,1050,2500,6672,1500,0,0,0,0,0,0,0,0,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (2959,'TORTUROUS_REDEEMER','Torturous Redeemer','Torturous Redeemer',120,103342,1,10599,8378,1,1253,500,144,28,133,69,72,55,165,44,10,12,1,7,62,14757,200,672,420,360,0,0,0,0,0,0,0,923,2000,6672,10000,6672,10000,0,0,0,0,0,0,0,0,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (2961,'E_TORTUROUS_REDEEMER','Torturous Redeemer','Torturous Redeemer',120,103342,1,1,1,1,1,1,144,28,1,1,1,1,1,1,10,12,1,7,62,14757,200,672,420,360,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 (2963,'WOODIE','Woodie','Woodie',1,60,1,18,10,1,13,3,2,5,6,1,1,0,6,5,10,12,0,3,21,131,400,1872,672,480,0,0,0,0,0,0,0,7203,2000,907,2000,7201,2000,1019,2000,756,200,6670,5000,0,0,0,0,0,0,4558,300); +REPLACE INTO `mob_db` VALUES (2995,'XM_TEDDY_BEAR','Abandoned Teddy Bear','Abandoned Teddy Bear',148,180000,1,6666,7332,1,1347,577,106,44,44,166,44,44,166,44,10,12,0,6,69,13205,150,780,780,504,0,0,0,0,0,0,0,7317,1900,615,150,12074,100,12734,1000,12738,100,0,0,0,0,0,0,0,0,31022,1); 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 (3162,'ELEPHANT','Elephant','Elephant',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,150,1028,528,360,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 (3163,'GORILLA','Gorilla','Gorilla',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,190,1028,528,360,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 (3164,'LION','Lion','Lion',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,150,1028,528,360,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 (3165,'RHINO','Rhino','Rhino',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,150,1028,528,360,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 (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); REPLACE INTO `mob_db` VALUES (3203,'INORGANIC_JAKK','Inorganic Pumpkin','Inorganic 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,6805,5000,6805,5000,6805,1000,2267,100,1062,1000,664,100,546,1000,12192,100,0,0,0,0); +REPLACE INTO `mob_db` VALUES (3261,'BLUE_UNICORN','Blue Unicorn','Blue Unicorn',30,20,1,99,112,1,106,29,36,17,17,26,20,18,36,5,10,12,0,3,25,129,300,1672,672,480,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 (3306,'PAD_TAMADORA','Tamadora','Tamadora',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3317,'PAD_RUBYLIT','Rubylit','Rubylit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3318,'PAD_SAPPHILIT','Sapphilit','Sapphilit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3319,'PAD_EMELIT','Emelit','Emelit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3320,'PAD_TOPALIT','Topalit','Topalit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3321,'PAD_AMELIT','Amelit','Amelit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3349,'PAD_MYTHLIT','Mythlit','Mythlit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (3381,'DARK_SOUL','Dark Soul','Dark Soul',10,20,1,0,0,1,20,20,0,0,1,1,1,1,1,1,1,1,1,6,27,129,100,1960,960,504,0,0,0,0,0,0,0,12192,2000,6914,4000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); REPLACE INTO `mob_db` VALUES (3382,'WANDERING_SOUL','Wandering Soul','Wandering Soul',1,10,1,0,0,1,10,10,0,0,1,1,1,1,1,1,1,1,1,6,28,129,100,1248,1248,576,0,0,0,0,0,0,0,12192,2000,6915,4000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); +REPLACE INTO `mob_db` VALUES (3495,'DR_EGGRING','Eggring','Eggring',1,50,1,50,35,1,7,1,2,4,6,1,1,0,6,4,10,12,0,3,22,131,400,1872,672,480,0,0,0,0,0,0,0,909,7000,512,1000,938,400,1010,30,601,500,512,150,512,20,0,0,0,0,4659,20); +REPLACE INTO `mob_db` VALUES (3496,'DR_LUNATIC','Leaf Lunatic','Leaf Lunatic',3,44,1,50,35,1,12,1,16,0,9,1,2,0,7,4,10,12,0,2,60,129,200,1456,456,336,0,0,0,0,0,0,0,705,7000,949,3000,2262,4,512,1000,601,500,515,3000,1010,30,0,0,0,0,4663,10); +REPLACE INTO `mob_db` VALUES (3636,'LITTLE_ISIS','Little Isis','Little Isis',59,2092,1,279,298,1,278,81,83,5,58,43,22,5,43,15,10,12,2,6,27,12693,200,1384,768,336,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 (3669,'DIABOLIC2','Diabolic2','Diabolic2',104,10572,1,1086,1073,1,772,283,68,61,103,80,53,65,94,25,10,12,0,6,47,14725,150,1080,780,180,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 (3670,'DELETER_2','Deleter 2','Deleter 2',105,10000,1,1049,1038,1,733,265,114,53,98,72,65,49,68,71,10,12,0,9,43,12429,175,1024,624,336,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 (3731,'SCATLETON','Scatleton','Scatleton',14,140,1,0,0,1,50,13,13,0,10,12,8,5,17,7,10,12,0,6,27,133,300,1600,900,240,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 (3790,'SWEETS_DROPS','Sweets Drops','Sweets Drops',1,20,1,27,20,1,12,1,16,0,1,1,1,1,1,1,10,12,0,3,23,131,440,1372,672,480,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 (3971,'SKELION','Skelion','Skelion',150,13000,1,594,669,1,222,56,88,16,25,16,12,45,33,29,10,12,0,0,20,165,150,960,864,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 (20373,'NIGHTMARE_TERROR_H','Rigid Nightmare Terror','Rigid Nightmare Terror',179,1523377,1,138489,96942,1,1709,725,242,75,81,149,21,186,129,61,12,12,2,6,67,14725,165,1216,816,432,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,27352,10); +REPLACE INTO `mob_db` VALUES (20420,'WANDER_MAN_H','Corrupted Wanderer','Corrupted Wanderer',187,2387582,1,170542,119379,1,3654,1645,289,102,176,121,34,67,139,77,10,12,0,6,44,14725,100,672,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,27361,10); +REPLACE INTO `mob_db` VALUES (20423,'BACSOJIN2','Bacsojin','Bacsojin',97,720500,1,801792,542880,3,1414,2036,210,178,118,244,98,126,246,102,10,12,2,7,64,14261,130,960,960,480,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 (20424,'MOONLIGHT2','Moonlight Flower','Moonlight Flower',79,324000,1,367488,271440,1,2232,1251,254,81,86,102,93,82,157,120,10,12,1,6,63,14261,150,1276,576,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 (20425,'PHREEONI2','Phreeoni','Phreeoni',71,300000,1,127600,180000,1,693,967,269,98,88,70,112,87,122,71,10,12,2,2,60,14261,200,1020,1020,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 (20571,'ORK_HERO2','Orc Hero','Orc Hero',50,362000,1,106920,97200,1,662,441,197,70,97,82,107,71,144,43,10,12,2,7,42,14261,150,1678,780,648,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 (20619,'GLOOMUNDERNIGHT2','Gloom Under Night','Gloom Under Night',139,3005000,1,2808000,1800000,3,6592,2785,479,262,191,223,187,155,362,163,10,12,2,0,68,14261,200,2000,2000,576,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 (20696,'EP17_2_CHILD_ADMIN1','Child Admin Beta','Child Admin Beta',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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 (20697,'EP17_2_CHILD_ADMIN2','Child Admin Alpha','Child Admin Alpha',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,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); diff --git a/sql-files/mob_skill_db_re.sql b/sql-files/mob_skill_db_re.sql index 5bdb5aec4..37d8f5165 100644 --- a/sql-files/mob_skill_db_re.sql +++ b/sql-files/mob_skill_db_re.sql @@ -10055,6 +10055,14 @@ REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@SM_BASH','attack',5 REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@NPC_FIREATTACK','attack',186,3,1000,0,200000,'yes','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@WZ_FIREPILLAR','attack',80,5,500,0,10000,'no','around2','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@SM_MAGNUM','attack',7,5,500,0,10000,'no','self','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2963,'Woodie@AL_HEAL','attack',28,9,10000,500,5000,'no','self','myhpinrate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2963,'Woodie@NPC_FIREATTACK','attack',186,3,2000,500,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2963,'Woodie@NPC_GROUNDATTACK','attack',185,3,2000,500,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@NPC_CURSEATTACK','attack',181,4,500,0,5000,'no','self','myhpinrate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@NPC_CURSEATTACK','follow',181,4,500,0,5000,'no','self','myhpinrate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@NPC_CRITICALSLASH','attack',170,1,500,0,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@SA_DISPELL','attack',289,1,50,1000,15000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@BS_HAMMERFALL','attack',110,5,500,1000,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `mob_skill_db` VALUES (3074,'Time Holder@NPC_AGIUP','attack',350,5,10000,0,10000,'yes','self','myhpltmaxrate','30',NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `mob_skill_db` VALUES (3074,'Time Holder@AL_INCAGI','chase',29,10,2000,700,10000,'no','self','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `mob_skill_db` VALUES (3074,'Time Holder@WZ_METEOR','attack',83,11,1000,500,10000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql-files/upgrades/2020-05-01--04-44.sql b/sql-files/upgrades/2020-05-01--04-44.sql new file mode 100644 index 000000000..6cb5a30ec --- /dev/null +++ b/sql-files/upgrades/2020-05-01--04-44.sql @@ -0,0 +1,25 @@ +#1588301040 + +-- This file is part of Hercules. +-- http://herc.ws - http://github.com/HerculesWS/Hercules +-- +-- Copyright (C) 2019-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/>. + +ALTER TABLE `acc_reg_str_db` MODIFY `value` VARCHAR(255) NOT NULL DEFAULT '0'; +ALTER TABLE `char_reg_str_db` MODIFY `value` VARCHAR(255) NOT NULL DEFAULT '0'; +ALTER TABLE `global_acc_reg_str_db` MODIFY `value` VARCHAR(255) NOT NULL DEFAULT '0'; + +INSERT INTO `sql_updates` (`timestamp`) VALUES (1588301040); diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt index fdd5fcc5a..64a7793f8 100644 --- a/sql-files/upgrades/index.txt +++ b/sql-files/upgrades/index.txt @@ -62,3 +62,4 @@ 2020-01-24--01-09.sql 2020-03-22--01-56.sql 2020-03-22--03-09.sql +2020-05-01--04-44.sql diff --git a/src/char/char.c b/src/char/char.c index aac9ad20c..c61b6107a 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -425,8 +425,6 @@ static struct DBData char_create_charstatus(union DBKey key, va_list args) static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) { - int i = 0; - int count = 0; int diff = 0; char save_status[128]; //For displaying save information. [Skotlex] struct mmo_charstatus *cp; @@ -591,8 +589,9 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) //insert here. StrBuf->Clear(&buf); StrBuf->Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", memo_db); - for( i = 0, count = 0; i < MAX_MEMOPOINTS; ++i ) - { + + int count = 0; + for (int i = 0; i < MAX_MEMOPOINTS; ++i) { if( p->memo_point[i].map ) { if( count ) @@ -624,24 +623,29 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) StrBuf->Clear(&buf); StrBuf->Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`,`flag`) VALUES ", skill_db); //insert here. - for (i = 0, count = 0; i < MAX_SKILL_DB; ++i) { - if( p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY ) { - if( p->skill[i].lv == 0 && ( p->skill[i].flag == SKILL_FLAG_PERM_GRANTED || p->skill[i].flag == SKILL_FLAG_PERMANENT ) ) - continue; - if( p->skill[i].flag != SKILL_FLAG_PERMANENT && p->skill[i].flag != SKILL_FLAG_PERM_GRANTED && (p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0) == 0 ) - continue; - if( count ) - StrBuf->AppendStr(&buf, ","); - StrBuf->Printf(&buf, "('%d','%d','%d','%d')", char_id, p->skill[i].id, - ( (p->skill[i].flag == SKILL_FLAG_PERMANENT || p->skill[i].flag == SKILL_FLAG_PERM_GRANTED) ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0), - p->skill[i].flag == SKILL_FLAG_PERM_GRANTED ? p->skill[i].flag : 0);/* other flags do not need to be saved */ - ++count; - } + int count = 0; + for (int i = 0; i < MAX_SKILL_DB; ++i) { + if (p->skill[i].id == 0) + continue; + if (p->skill[i].flag == SKILL_FLAG_TEMPORARY) + continue; + if (p->skill[i].lv == 0 && (p->skill[i].flag == SKILL_FLAG_PERM_GRANTED || p->skill[i].flag == SKILL_FLAG_PERMANENT)) + continue; + if (p->skill[i].flag == SKILL_FLAG_REPLACED_LV_0) + continue; + + if (Assert_chk(p->skill[i].flag == SKILL_FLAG_PERMANENT || p->skill[i].flag == SKILL_FLAG_PERM_GRANTED || p->skill[i].flag > SKILL_FLAG_REPLACED_LV_0)) + continue; + if (count != 0) + StrBuf->AppendStr(&buf, ","); + int saved_lv = (p->skill[i].flag > SKILL_FLAG_REPLACED_LV_0) ? p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0 : p->skill[i].lv; + int saved_flag = p->skill[i].flag == SKILL_FLAG_PERM_GRANTED ? p->skill[i].flag : 0; // other flags do not need to be saved + StrBuf->Printf(&buf, "('%d','%d','%d','%d')", char_id, p->skill[i].id, saved_lv, saved_flag); + + ++count; } - if( count ) - { - if( SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)) ) - { + if (count != 0) { + if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) { Sql_ShowDebug(inter->sql_handle); errors++; } @@ -651,7 +655,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) } diff = 0; - for(i = 0; i < MAX_FRIENDS; i++){ + for (int i = 0; i < MAX_FRIENDS; i++) { if(p->friends[i].char_id != cp->friends[i].char_id || p->friends[i].account_id != cp->friends[i].account_id){ diff = 1; @@ -669,8 +673,8 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) StrBuf->Clear(&buf); StrBuf->Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db); - for( i = 0, count = 0; i < MAX_FRIENDS; ++i ) - { + int count = 0; + for (int i = 0; i < MAX_FRIENDS; ++i) { if( p->friends[i].char_id > 0 ) { if( count ) @@ -695,7 +699,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) StrBuf->Clear(&buf); StrBuf->Printf(&buf, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", hotkey_db); diff = 0; - for(i = 0; i < ARRAYLENGTH(p->hotkeys); i++){ + for (int i = 0; i < ARRAYLENGTH(p->hotkeys); i++) { if(memcmp(&p->hotkeys[i], &cp->hotkeys[i], sizeof(struct hotkey))) { if( diff ) @@ -1369,7 +1373,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa SqlStmt_ShowDebug(stmt); } - if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED ) + if (tmp_skill.flag != SKILL_FLAG_PERM_GRANTED) tmp_skill.flag = SKILL_FLAG_PERMANENT; for (i = 0; i < MAX_SKILL_DB && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i) { @@ -2898,13 +2902,13 @@ static void char_global_accreg_to_login_add(const char *key, unsigned int index, if( val ) { char *sval = (char*)val; - len = strlen(sval)+1; + len = strlen(sval); - WFIFOB(chr->login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + WFIFOB(chr->login_fd, nlen) = (unsigned char)len; // Won't be higher; the column size is 255. nlen += 1; - safestrncpy(WFIFOP(chr->login_fd,nlen), sval, len); - nlen += len; + safestrncpy(WFIFOP(chr->login_fd, nlen), sval, len + 1); + nlen += len + 1; } } else { WFIFOB(chr->login_fd, nlen) = val ? 0 : 1; diff --git a/src/char/inter.c b/src/char/inter.c index 2d8d06a9c..5252b3315 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -676,13 +676,13 @@ static int inter_accreg_fromsql(int account_id, int char_id, int fd, int type) plen += 4; SQL->GetData(inter->sql_handle, 2, &data, NULL); - len = strlen(data)+1; + len = strlen(data); - WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + WFIFOB(fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255. plen += 1; - safestrncpy(WFIFOP(fd,plen), data, len); - plen += len; + safestrncpy(WFIFOP(fd, plen), data, len + 1); + plen += len + 1; WFIFOW(fd, 14) += 1; diff --git a/src/char/mapif.c b/src/char/mapif.c index 9077afae4..f0c886586 100644 --- a/src/char/mapif.c +++ b/src/char/mapif.c @@ -2030,7 +2030,8 @@ static int mapif_parse_Registry(int fd) if (count != 0) { int cursor = 14, i; - char key[SCRIPT_VARNAME_LENGTH+1], sval[254]; + char key[SCRIPT_VARNAME_LENGTH + 1]; + char sval[SCRIPT_STRING_VAR_LENGTH + 1]; bool isLoginActive = sockt->session_is_active(chr->login_fd); if (isLoginActive) @@ -2057,8 +2058,8 @@ static int mapif_parse_Registry(int fd) /* str */ case 2: len = RFIFOB(fd, cursor); - safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); - cursor += len + 1; + safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1)); + cursor += len + 2; inter->savereg(account_id, char_id, key, index, (intptr_t)sval, true); break; case 3: diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 0b5613316..6053d86d9 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -95,7 +95,7 @@ // debug function name #ifndef __NETBSD__ #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L -# if __GNUC__ >= 2 +# if __GNUC__ >= 2 || defined(WIN32) # define __func__ __FUNCTION__ # else # define __func__ "" diff --git a/src/common/mmo.h b/src/common/mmo.h index 9421f6e35..d2f3aa8f1 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -380,7 +380,10 @@ STATIC_ASSERT(MAX_ITEM_OPTIONS <= 5, "This value is limited by the client and da #define JOBL_BABY 0x2000 #define JOBL_THIRD 0x4000 -#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable +#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable's name including affixes and excluding NULL-terminator. +STATIC_ASSERT(SCRIPT_VARNAME_LENGTH <= 32, "This value is limited by the inter-server communication and database layout and should only be increased if you know the consequences."); +#define SCRIPT_STRING_VAR_LENGTH 255 ///< Maximum length of strings stored in script variables excluding NULL-terminator. +STATIC_ASSERT(SCRIPT_STRING_VAR_LENGTH <= 255, "This value is limited by the inter-server communication and database layout and should only be increased if you know the consequences."); #define INFINITE_DURATION (-1) // Infinite duration for status changes diff --git a/src/login/account.c b/src/login/account.c index 3632c257a..ec0bc81e8 100644 --- a/src/login/account.c +++ b/src/login/account.c @@ -632,7 +632,8 @@ static void account_mmo_save_accreg2(AccountDB *self, int fd, int account_id, in sql_handle = db->accounts; if (count) { int cursor = 14, i; - char key[SCRIPT_VARNAME_LENGTH+1], sval[254]; + char key[SCRIPT_VARNAME_LENGTH + 1]; + char sval[SCRIPT_STRING_VAR_LENGTH + 1]; for (i = 0; i < count; i++) { unsigned int index; @@ -657,8 +658,8 @@ static void account_mmo_save_accreg2(AccountDB *self, int fd, int account_id, in /* str */ case 2: len = RFIFOB(fd, cursor); - safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); - cursor += len + 1; + safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1)); + cursor += len + 2; if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_db, account_id, key, index, sval) ) Sql_ShowDebug(sql_handle); break; @@ -719,13 +720,13 @@ static void account_mmo_send_accreg2(AccountDB *self, int fd, int account_id, in plen += 4; SQL->GetData(sql_handle, 2, &data, NULL); - len = strlen(data)+1; + len = strlen(data); - WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + WFIFOB(fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255. plen += 1; - safestrncpy(WFIFOP(fd,plen), data, len); - plen += len; + safestrncpy(WFIFOP(fd, plen), data, len + 1); + plen += len + 1; WFIFOW(fd, 14) += 1; diff --git a/src/login/login.c b/src/login/login.c index 4201a8b4e..623457b8a 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -1406,10 +1406,10 @@ static void login_client_login_mobile_otp_request(int fd, struct login_session_d static void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) __attribute__((nonnull (2))); static void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) { - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x2711; - WFIFOB(fd,2) = status; - WFIFOSET(fd,3); + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x2711; + WFIFOB(fd, 2) = status; + WFIFOSET2(fd, 3); } // CA_CHARSERVERCONNECT diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 91ddc3ef9..54cc9e2c9 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -962,39 +962,10 @@ ACMD(option) *------------------------------------------*/ ACMD(hide) { - if (pc_isinvisible(sd)) { - sd->sc.option &= ~OPTION_INVISIBLE; - if (sd->disguise != -1 ) - status->set_viewdata(&sd->bl, sd->disguise); - else - status->set_viewdata(&sd->bl, sd->status.class); - clif->message(fd, msg_fd(fd,10)); // Invisible: Off - - // increment the number of pvp players on the map - map->list[sd->bl.m].users_pvp++; - - if( map->list[sd->bl.m].flag.pvp && !map->list[sd->bl.m].flag.pvp_nocalcrank ) { - // register the player for ranking calculations - sd->pvp_timer = timer->add( timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0 ); - } - //bugreport:2266 - map->foreachinmovearea(clif->insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl); - } else { - clif->clearunit_area(&sd->bl, CLR_OUTSIGHT); - sd->sc.option |= OPTION_INVISIBLE; - sd->vd.class = INVISIBLE_CLASS; - clif->message(fd, msg_fd(fd,11)); // Invisible: On - - // decrement the number of pvp players on the map - map->list[sd->bl.m].users_pvp--; - - if( map->list[sd->bl.m].flag.pvp && !map->list[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER ) { - // unregister the player for ranking - timer->delete( sd->pvp_timer, pc->calc_pvprank_timer ); - sd->pvp_timer = INVALID_TIMER; - } - } - clif->changeoption(&sd->bl); + if (pc_isinvisible(sd)) + pc->unhide(sd, true); + else + pc->hide(sd, true); return true; } @@ -8945,13 +8916,17 @@ ACMD(accinfo) /* [Ind] */ ACMD(set) { - char reg[SCRIPT_VARNAME_LENGTH+1], val[254]; + char reg[SCRIPT_VARNAME_LENGTH + 1]; + char val[SCRIPT_STRING_VAR_LENGTH + 1]; struct script_data* data; int toset = 0; bool is_str = false; size_t len; - if (!*message || (toset = sscanf(message, "%32s %253[^\n]", reg, val)) < 1) { + char format[20]; + safesnprintf(format, sizeof(format), "%%%ds %%%d[^\\n]", SCRIPT_VARNAME_LENGTH, SCRIPT_STRING_VAR_LENGTH); + + if (*message == '\0' || (toset = sscanf(message, format, reg, val)) < 1) { clif->message(fd, msg_fd(fd,1367)); // Usage: @set <variable name> <value> clif->message(fd, msg_fd(fd,1368)); // Usage: ex. "@set PoringCharVar 50" clif->message(fd, msg_fd(fd,1369)); // Usage: ex. "@set PoringCharVarSTR$ Super Duper String" @@ -10594,9 +10569,9 @@ static bool atcommand_exec(const int fd, struct map_session_data *sd, const char clif->message(fd, msg_fd(fd,143)); return false; } + if (sd->block_action.commands) // *pcblock script command + return false; } - if (sd->block_action.commands) // *pcblock script command - return false; if (*message == atcommand->char_symbol) is_atcommand = false; diff --git a/src/map/battle.c b/src/map/battle.c index 40c645cf7..c8cd71b94 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3750,7 +3750,7 @@ static struct Damage battle_calc_magic_attack(struct block_list *src, struct blo if (sc){ if( sc->data[SC_TELEKINESIS_INTENSE] && s_ele == ELE_GHOST ) - ad.damage += sc->data[SC_TELEKINESIS_INTENSE]->val3; + ad.damage += ad.damage * sc->data[SC_TELEKINESIS_INTENSE]->val3 / 100; } switch(skill_id){ case MG_FIREBOLT: @@ -4124,13 +4124,6 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc case NPC_EVILLAND: md.damage = skill->calc_heal(src,target,skill_id,skill_lv,false); break; - case RK_DRAGONBREATH: - case RK_DRAGONBREATH_WATER: - md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv; - RE_LVL_MDMOD(150); - if (sd) md.damage = md.damage * (95 + 5 * pc->checkskill(sd,RK_DRAGONTRAINING)) / 100; - md.flag |= BF_LONG|BF_WEAPON; - break; /** * Ranger **/ @@ -4958,6 +4951,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl break; } break; + case RK_DRAGONBREATH: + case RK_DRAGONBREATH_WATER: + wd.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv; + wd.damage = wd.damage * status->get_lv(src) / 150; + if (sd) wd.damage = wd.damage * (95 + 5 * pc->checkskill(sd, RK_DRAGONTRAINING)) / 100; + break; default: { i = (flag.cri diff --git a/src/map/clif.c b/src/map/clif.c index 496a8beda..ab13ffe1f 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9722,6 +9722,17 @@ static void clif_elemname_ack(int fd, struct block_list *bl) clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE)); } +static void clif_skillname_ack(int fd, struct block_list *bl) +{ +} + +static void clif_itemname_ack(int fd, struct block_list *bl) +{ + nullpo_retv(bl); + ShowError("clif_itemname_ack: bad type %u(%d)\n", bl->type, bl->id); + Assert_retv(0); +} + static void clif_unknownname_ack(int fd, struct block_list *bl) { nullpo_retv(bl); @@ -9758,6 +9769,12 @@ static void clif_blname_ack(int fd, struct block_list *bl) case BL_ELEM: clif->elemname_ack(fd, bl); break; + case BL_ITEM: + clif->itemname_ack(fd, bl); + break; + case BL_SKILL: + clif->skillname_ack(fd, bl); + break; default: clif->unknownname_ack(fd, bl); break; @@ -11777,7 +11794,7 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd) char *str = target + 4; // Skip the NPC: string part. struct npc_data *nd; if ((nd = npc->name2id(str))) { - char split_data[NUM_WHISPER_VAR][CHAT_SIZE_MAX]; + char split_data[NUM_WHISPER_VAR][SCRIPT_STRING_VAR_LENGTH + 1]; char *split; char output[256]; @@ -23780,12 +23797,15 @@ static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) _ static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) { #if PACKETVER >= 20160302 + if (sd->state.lapine_ui == 0) + return; + const struct PACKET_CZ_LAPINEDDUKDDAK_ACK *p = RP2PTR(fd); struct item_data *it = itemdb->exists(p->itemId); if (it == NULL || it->lapineddukddak == NULL) return; - if (pc_cant_act(sd)) + if (pc_cant_act_except_lapine(sd)) return; if (pc->search_inventory(sd, it->nameid) == INDEX_NOT_FOUND) return; @@ -23846,6 +23866,55 @@ static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd) #endif // PACKETVER >= 20160504 } +static bool clif_lapineUpgrade_open(struct map_session_data *sd, int item_id) +{ +#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) + nullpo_retr(false, sd); + nullpo_retr(false, itemdb->exists(item_id)); + struct PACKET_ZC_LAPINEUPGRADE_OPEN p; + + p.packetType = HEADER_ZC_LAPINEUPGRADE_OPEN; + p.itemId = item_id; + clif->send(&p, sizeof(p), &sd->bl, SELF); + + return true; +#else + return false; +#endif // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) +} + +static void clif_parse_lapineUpgrade_close(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_lapineUpgrade_close(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) +#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) +} + +static void clif_parse_lapineUpgrade_makeItem(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_lapineUpgrade_makeItem(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) + ShowError("Lapin upgrade not implimented yet"); + clif->lapineUpgrade_result(sd, LAPINE_UPGRADE_FAILED); +#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) +} + +static bool clif_lapineUpgrade_result(struct map_session_data *sd, enum lapineUpgrade_result result) +{ +#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) + nullpo_retr(false, sd); + struct PACKET_ZC_LAPINEUPGRADE_RESULT p; + + p.packetType = HEADER_ZC_LAPINEUPGRADE_RESULT; + p.result = result; + clif->send(&p, sizeof(p), &sd->bl, SELF); + + return true; +#else + return false; +#endif // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) +} + /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -24346,6 +24415,8 @@ void clif_defaults(void) clif->mobname_normal_ack = clif_mobname_normal_ack; clif->chatname_ack = clif_chatname_ack; clif->elemname_ack = clif_elemname_ack; + clif->skillname_ack = clif_skillname_ack; + clif->itemname_ack = clif_itemname_ack; clif->unknownname_ack = clif_unknownname_ack; clif->monster_hp_bar = clif_monster_hp_bar; clif->hpmeter = clif_hpmeter; @@ -25089,5 +25160,9 @@ void clif_defaults(void) clif->lapineDdukDdak_result = clif_lapineDdukDdak_result; clif->plapineDdukDdak_ack = clif_parse_lapineDdukDdak_ack; clif->plapineDdukDdak_close = clif_parse_lapineDdukDdak_close; + clif->lapineUpgrade_open = clif_lapineUpgrade_open; + clif->lapineUpgrade_result = clif_lapineUpgrade_result; + clif->pLapineUpgrade_close = clif_parse_lapineUpgrade_close; + clif->pLapineUpgrade_makeItem = clif_parse_lapineUpgrade_makeItem; clif->pReqGearOff = clif_parse_reqGearOff; } diff --git a/src/map/clif.h b/src/map/clif.h index 25ac65af5..fdaaf85e3 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -733,6 +733,11 @@ enum lapineddukddak_result { LAPINEDDKUKDDAK_INVALID_ITEM = 7, }; +enum lapineUpgrade_result { + LAPINE_UPGRADE_SUCCESS = 0, + LAPINE_UPGRADE_FAILED = 1 +}; + enum removeGear_flag { REMOVE_MOUNT_0 = 0, // unused REMOVE_MOUNT_DRAGON = 1, @@ -952,6 +957,8 @@ struct clif_interface { void (*mobname_normal_ack) (int fd, struct block_list *bl); void (*chatname_ack) (int fd, struct block_list *bl); void (*elemname_ack) (int fd, struct block_list *bl); + void (*skillname_ack) (int fd, struct block_list *bl); + void (*itemname_ack) (int fd, struct block_list *bl); void (*unknownname_ack) (int fd, struct block_list *bl); void (*monster_hp_bar) ( struct mob_data* md, struct map_session_data *sd ); int (*hpmeter) (struct map_session_data *sd); @@ -1688,6 +1695,10 @@ struct clif_interface { bool (*lapineDdukDdak_result) (struct map_session_data *sd, enum lapineddukddak_result result); void (*plapineDdukDdak_ack) (int fd, struct map_session_data *sd); void (*plapineDdukDdak_close) (int fd, struct map_session_data *sd); + bool (*lapineUpgrade_open) (struct map_session_data *sd, int item_id); + bool (*lapineUpgrade_result) (struct map_session_data *sd, enum lapineUpgrade_result result); + void (*pLapineUpgrade_close) (int fd, struct map_session_data *sd); + void (*pLapineUpgrade_makeItem) (int fd, struct map_session_data *sd); void (*pReqGearOff) (int fd, struct map_session_data *sd); }; diff --git a/src/map/intif.c b/src/map/intif.c index a420b7204..276b40780 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -218,13 +218,13 @@ static int intif_saveregistry(struct map_session_data *sd) plen += 1; if( p->value ) { - len = strlen(p->value)+1; + len = strlen(p->value); - WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + WFIFOB(inter_fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255. plen += 1; - safestrncpy(WFIFOP(inter_fd,plen), p->value, len); - plen += len; + safestrncpy(WFIFOP(inter_fd, plen), p->value, len + 1); + plen += len + 1; } else { script->reg_destroy_single(sd,key.i64,&p->flag); } @@ -1025,7 +1025,7 @@ static void intif_parse_Registers(int fd) * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) } **/ if (type) { - char sval[254]; + char sval[SCRIPT_STRING_VAR_LENGTH + 1]; for (i = 0; i < max; i++) { int len = RFIFOB(fd, cursor); safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); @@ -1035,8 +1035,8 @@ static void intif_parse_Registers(int fd) cursor += 4; len = RFIFOB(fd, cursor); - safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); - cursor += len + 1; + safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1)); + cursor += len + 2; script->set_reg(NULL,sd,reference_uid(script->add_variable(key), index), key, sval, NULL); } diff --git a/src/map/map.c b/src/map/map.c index b2c9c77c3..f66f40dfc 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1713,9 +1713,9 @@ static bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, tx = *x + dx; ty = *y + dy; if (unit_is_dir_or_opposite(dir, UNIT_DIR_SOUTHWEST)) - tx *= costrange / MOVE_COST; + tx = tx * costrange / MOVE_COST; if (unit_is_dir_or_opposite(dir, UNIT_DIR_NORTHWEST)) - ty *= costrange / MOVE_COST; + ty = ty * costrange / MOVE_COST; if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) { *x = tx; *y = ty; @@ -1724,9 +1724,9 @@ static bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, tx = *x + dx; ty = *y + dy; if (unit_is_dir_or_opposite(dir, UNIT_DIR_NORTHWEST)) - tx *= costrange / MOVE_COST; + tx = tx * costrange / MOVE_COST; if (unit_is_dir_or_opposite(dir, UNIT_DIR_SOUTHWEST)) - ty *= costrange / MOVE_COST; + ty = ty * costrange / MOVE_COST; if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) { *x = tx; *y = ty; @@ -3077,6 +3077,8 @@ static int map_getcellp(struct map_data *m, const struct block_list *bl, int16 x return (cell.icewall); case CELL_CHKNOICEWALL: return (cell.noicewall); + case CELL_CHKNOSKILL: + return (cell.noskill); // special checks case CELL_CHKPASS: @@ -3141,6 +3143,7 @@ static void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) case CELL_NOCHAT: map->list[m].cell[j].nochat = flag; break; case CELL_ICEWALL: map->list[m].cell[j].icewall = flag; break; case CELL_NOICEWALL: map->list[m].cell[j].noicewall = flag; break; + case CELL_NOSKILL: map->list[m].cell[j].noskill = flag; break; default: ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell); diff --git a/src/map/map.h b/src/map/map.h index b3cdef025..17f210bc3 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -596,6 +596,7 @@ typedef enum { CELL_NOCHAT, CELL_ICEWALL, CELL_NOICEWALL, + CELL_NOSKILL, } cell_t; @@ -620,6 +621,7 @@ typedef enum { CELL_CHKNOCHAT, CELL_CHKICEWALL, CELL_CHKNOICEWALL, + CELL_CHKNOSKILL, } cell_chk; @@ -638,7 +640,8 @@ struct mapcell { novending : 1, nochat : 1, icewall : 1, - noicewall : 1; + noicewall : 1, + noskill : 1; #ifdef CELL_NOSTACK int cell_bl; //Holds amount of bls in this cell. diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index 741505e17..2963637da 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -176,9 +176,9 @@ static bool mapreg_setregstr(int64 uid, const char *str) if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert. char tmp_str[(SCRIPT_VARNAME_LENGTH+1)*2+1]; - char tmp_str2[255*2+1]; + char tmp_str2[SCRIPT_STRING_VAR_LENGTH * 2 + 1]; SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, SCRIPT_VARNAME_LENGTH+1)); - SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, 255)); + SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, SCRIPT_STRING_VAR_LENGTH)); if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%u','%s')", mapreg->table, tmp_str, i, tmp_str2) ) Sql_ShowDebug(map->mysql_handle); } @@ -203,7 +203,7 @@ static void script_load_mapreg(void) struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle); char varname[SCRIPT_VARNAME_LENGTH+1]; int index; - char value[255+1]; + char value[SCRIPT_STRING_VAR_LENGTH + 1]; uint32 length; if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg->table) @@ -261,8 +261,8 @@ static void script_save_mapreg(void) if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) ) Sql_ShowDebug(map->mysql_handle); } else { - char tmp_str2[2*255+1]; - SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255)); + char tmp_str2[SCRIPT_STRING_VAR_LENGTH * 2 + 1]; + SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, SCRIPT_STRING_VAR_LENGTH)); if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) ) Sql_ShowDebug(map->mysql_handle); } diff --git a/src/map/mob.c b/src/map/mob.c index 51a32abd9..dcbdccedd 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -78,6 +78,7 @@ struct mob_interface *mob; // Move probability for mobs away from players (rate of 1000 minute) // in Aegis, this is 100% for mobs that have been activated by players and none otherwise. #define MOB_LAZYMOVEPERC(md) ((md)->state.spotted?1000:0) +#define MOB_MAX_CASTTIME (10 * 60 * 1000) // Maximum cast time for monster skills. (10 minutes) #define MOB_MAX_DELAY (24*3600*1000) #define MAX_MINCHASE 30 //Max minimum chase value to use for mobs. #define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used? @@ -446,6 +447,9 @@ static bool mob_ksprotected(struct block_list *src, struct block_list *target) if( !battle_config.ksprotection ) return false; // KS Protection Disabled + if (status->isdead(target) != 0) + return false; // Target is dead. + if( !(md = BL_CAST(BL_MOB,target)) ) return false; // Target is not MOB @@ -1519,7 +1523,7 @@ static int mob_unlocktarget(struct mob_data *md, int64 tick) FALLTHROUGH case MSS_IDLE: // Idle skill. - if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL) && mob->skill_use(md, tick, -1)) + if ((++md->ud.walk_count % IDLE_SKILL_INTERVAL) == 0 && mob->skill_use(md, tick, -1) == 0) break; //Random walk. if (!md->master_id && @@ -1699,7 +1703,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, int64 tick) || !mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) ) && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT - && !mob->skill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack + && mob->skill_use(md, tick, MSC_RUDEATTACKED) == 0 // If can't rude Attack && can_move && unit->escape(&md->bl, tbl, rnd()%10 +1) // Attempt escape ) { //Escaped @@ -1727,7 +1731,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, int64 tick) ) { // Rude attacked if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT - && !mob->skill_use(md, tick, MSC_RUDEATTACKED) && can_move + && mob->skill_use(md, tick, MSC_RUDEATTACKED) == 0 && can_move != 0 && !tbl && unit->escape(&md->bl, abl, rnd()%10 +1) ) { //Escaped. @@ -3387,272 +3391,344 @@ static struct block_list *mob_getmasterhpltmaxrate(struct mob_data *md, int rate return NULL; } -/*========================================== - * What a status state suits by nearby MOB is looked for. - *------------------------------------------*/ + +/** + * Checks if the passed monster/character meets the passed status change requirements + * and returns it by reference parameter on success. + * + * @param bl The monster/character to check. + * @param ap List of arguments. (Source monster, MSC_* flag, SC_* flag, reference bl.) + * @return Always 0. + * + **/ static int mob_getfriendstatus_sub(struct block_list *bl, va_list ap) { - int cond1,cond2; - struct mob_data **fr = NULL, *md = NULL, *mmd = NULL; - int flag=0; - nullpo_ret(bl); - Assert_ret(bl->type == BL_MOB); - md = BL_UCAST(BL_MOB, bl); - nullpo_ret(mmd=va_arg(ap,struct mob_data *)); - if( mmd->bl.id == bl->id && !(battle_config.mob_ai&0x10) ) + struct mob_data *md = va_arg(ap, struct mob_data *); + + nullpo_ret(md); + + if (md->bl.id == bl->id && (battle_config.mob_ai & 0x10) == 0) + return 0; + + if (battle->check_target(&md->bl, bl, BCT_ENEMY) > 0) return 0; - if (battle->check_target(&mmd->bl,bl,BCT_ENEMY)>0) + int cond1 = va_arg(ap, int); + int cond2 = va_arg(ap, int); + struct block_list **fr = va_arg(ap, struct block_list **); + + if ((*fr) != NULL) // A friend was already found. return 0; - cond1=va_arg(ap,int); - cond2=va_arg(ap,int); - fr=va_arg(ap,struct mob_data **); - if( cond2==-1 ){ - int j; - for(j=SC_COMMON_MIN;j<=SC_COMMON_MAX && !flag;j++){ - if ((flag=(md->sc.data[j] != NULL))) //Once an effect was found, break out. [Skotlex] + + int flag = 0; + struct status_change *sc = status->get_sc(bl); + + if (cond2 == -1) { // Check for any of the common status alignments. + for (int i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) { + if ((flag = (sc->data[i] != NULL)) != 0) // Once an effect was found, break out. [Skotlex] break; } - }else - flag=( md->sc.data[cond2] != NULL ); - if( flag^( cond1==MSC_FRIENDSTATUSOFF ) ) - (*fr)=md; + } else { + flag = (sc->data[cond2] != NULL); + } + + if ((flag ^ (cond1 == MSC_FRIENDSTATUSOFF)) != 0) + (*fr) = bl; return 0; } -static struct mob_data *mob_getfriendstatus(struct mob_data *md, int cond1, int cond2) +/** + * Gets a random monster/character within a range of 8 cells around md. + * If md is summoned (no monster slave!) a character is picker, otherwise a monster. + * + * @param md The monster which tries to cast a skill. + * @param cond1 Whether to check for active or inactive status change. (MSC_FRIENDSTATUSON/MSC_FRIENDSTATUSOFF) + * @param cond2 The status change (SC_* flag) to check. + * @return A randomly picked monster/character within range. + * + **/ +static struct block_list *mob_getfriendstatus(struct mob_data *md, int cond1, int cond2) { - struct mob_data* fr = NULL; nullpo_ret(md); - map->foreachinrange(mob->getfriendstatus_sub, &md->bl, 8,BL_MOB, md,cond1,cond2,&fr); + int type = (md->special_state.ai != AI_NONE) ? BL_PC : BL_MOB; + struct block_list *fr = NULL; + + map->foreachinrange(mob->getfriendstatus_sub, &md->bl, 8, type, md, cond1, cond2, &fr); + return fr; } -/*========================================== - * Skill use judging - *------------------------------------------*/ -static int mobskill_use(struct mob_data *md, int64 tick, int event) +/** + * Checks if skill cast condition in fulfilled and executes the skill in case of success. + * + * @param md The monster which tries to cast a skill. + * @param tick The timestamp of skill execution. + * @param event The MSC_* flag which triggered the skill execution. (-1 for non-event skill conditions.) + * @return 0 on success, 1 on failure. + * + **/ +static int mob_skill_use(struct mob_data *md, int64 tick, int event) { - struct mob_skill *ms; - struct block_list *fbl = NULL; //Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex] - struct block_list *bl; - struct mob_data *fmd = NULL; - int i,j,n; - nullpo_ret(md); - nullpo_ret(ms = md->db->skill); - if (!battle_config.mob_skill_rate || md->ud.skilltimer != INVALID_TIMER || !md->db->maxskill) - return 0; + struct mob_skill *ms = md->db->skill; + + nullpo_ret(ms); + + if (battle_config.mob_skill_rate == 0 || md->ud.skilltimer != INVALID_TIMER || md->db->maxskill == 0) + return 1; if (event == -1 && DIFF_TICK(md->ud.canact_tick, tick) > 0) - return 0; //Skill act delay only affects non-event skills. + return 1; // Skill act delay only affects non-event skill conditions. - //Pick a starting position and loop from that. - i = (battle_config.mob_ai&0x100) ? rnd()%md->db->maxskill : 0; - for (n = 0; n < md->db->maxskill; i++, n++) { - int c2, flag = 0; + // Pick a starting position and loop from that. + int skill_idx = ((battle_config.mob_ai & 0x100) != 0) ? rnd() % md->db->maxskill : 0; - if (i == md->db->maxskill) - i = 0; + for (int i = 0; i < md->db->maxskill; skill_idx++, i++) { + if (skill_idx == md->db->maxskill) + skill_idx = 0; - if (DIFF_TICK(tick, md->skilldelay[i]) < ms[i].delay) + if (DIFF_TICK(tick, md->skilldelay[skill_idx]) < ms[skill_idx].delay) continue; - c2 = ms[i].cond2; + enum MobSkillState state = ms[skill_idx].state; - if (ms[i].state != md->state.skillstate) { - if (md->state.skillstate != MSS_DEAD && (ms[i].state == MSS_ANY || - (ms[i].state == MSS_ANYTARGET && md->target_id && md->state.skillstate != MSS_LOOT) - )) //ANYTARGET works with any state as long as there's a target. [Skotlex] - ; - else + if (state != md->state.skillstate) { + bool state_dead = (md->state.skillstate == MSS_DEAD); + bool any_target = (state == MSS_ANYTARGET && md->target_id != 0 && md->state.skillstate != MSS_LOOT); + + // MSS_ANYTARGET works with any state as long as there's a target. [Skotlex] + if (state_dead || (state != MSS_ANY && !any_target)) continue; } - if (rnd() % 10000 > ms[i].permillage) //Lupus (max value = 10000) + + if (rnd() % 10000 > ms[skill_idx].permillage) continue; - if (ms[i].cond1 == event) - flag = 1; //Trigger skill. - else if (ms[i].cond1 == MSC_SKILLUSED) - flag = ((event & 0xffff) == MSC_SKILLUSED && ((event >> 16) == c2 || c2 == 0)); - else if(event == -1){ - //Avoid entering on defined events to avoid "hyper-active skill use" due to the overflow of calls to this function in battle. - switch (ms[i].cond1) - { - case MSC_ALWAYS: - flag = 1; break; - case MSC_MYHPLTMAXRATE: // HP< maxhp% - flag = get_percentage(md->status.hp, md->status.max_hp); - flag = (flag <= c2); - break; - case MSC_MYHPINRATE: - flag = get_percentage(md->status.hp, md->status.max_hp); - flag = (flag >= c2 && flag <= ms[i].val[0]); - break; - case MSC_MYSTATUSON: // status[num] on - case MSC_MYSTATUSOFF: // status[num] off - if (!md->sc.count) { - flag = 0; - } else if (ms[i].cond2 == -1) { - for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++) - if ((flag = (md->sc.data[j]!=NULL)) != 0) - break; - } else { - flag = (md->sc.data[ms[i].cond2]!=NULL); + int cast_cond = ms[skill_idx].cond1; + int cond_data = ms[skill_idx].cond2; + int flag = 0; + struct block_list *fbl = NULL; // Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex] + + if (cast_cond == event) { + flag = 1; // Trigger skill. + } else if (cast_cond == MSC_SKILLUSED) { + flag = ((event & 0xFFFF) == MSC_SKILLUSED && ((event >> 16) == cond_data || cond_data == 0)); + } else if (event == -1) { + // Avoid entering on defined events to avoid "hyper-active skill use" due to the overflow of calls to this function in battle. + switch (cast_cond) { + case MSC_ALWAYS: + flag = 1; + break; + case MSC_MYHPLTMAXRATE: // HP <= x% + flag = get_percentage(md->status.hp, md->status.max_hp); + flag = (flag <= cond_data); + break; + case MSC_MYHPINRATE: // HP >= x% && HP <= y% + flag = get_percentage(md->status.hp, md->status.max_hp); + flag = (flag >= cond_data && flag <= ms[skill_idx].val[0]); + break; + case MSC_MYSTATUSON: // Status change x is active. + case MSC_MYSTATUSOFF: // Status change x is inactive. + if (cond_data == -1) { // Check for any of the common status alignments. + for (int j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++) { + if ((flag = (md->sc.data[j] != NULL)) != 0) + break; } - flag ^= (ms[i].cond1 == MSC_MYSTATUSOFF); break; - case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp% - flag = ((fbl = mob->getfriendhprate(md, 0, ms[i].cond2)) != NULL); break; - case MSC_FRIENDHPINRATE: - flag = ((fbl = mob->getfriendhprate(md, ms[i].cond2, ms[i].val[0])) != NULL); break; - case MSC_FRIENDSTATUSON: // friend status[num] on - case MSC_FRIENDSTATUSOFF: // friend status[num] off - flag = ((fmd = mob->getfriendstatus(md, ms[i].cond1, ms[i].cond2)) != NULL); break; - case MSC_SLAVELT: // slave < num - flag = (mob->countslave(&md->bl) < c2 ); break; - case MSC_ATTACKPCGT: // attack pc > num - flag = (unit->counttargeted(&md->bl) > c2); break; - case MSC_SLAVELE: // slave <= num - flag = (mob->countslave(&md->bl) <= c2 ); break; - case MSC_ATTACKPCGE: // attack pc >= num - flag = (unit->counttargeted(&md->bl) >= c2); break; - case MSC_AFTERSKILL: - flag = (md->ud.skill_id == c2); break; - case MSC_RUDEATTACKED: - flag = (md->state.attacked_count >= RUDE_ATTACKED_COUNT); - if (flag) md->state.attacked_count = 0; //Rude attacked count should be reset after the skill condition is met. Thanks to Komurka [Skotlex] - break; - case MSC_MASTERHPLTMAXRATE: - flag = ((fbl = mob->getmasterhpltmaxrate(md, ms[i].cond2)) != NULL); break; - case MSC_MASTERATTACKED: - flag = (md->master_id > 0 && (fbl=map->id2bl(md->master_id)) != NULL && unit->counttargeted(fbl) > 0); - break; - case MSC_ALCHEMIST: - flag = (md->state.alchemist); - break; + } else { + flag = (md->sc.data[cond_data] != NULL); + } + + flag ^= (cast_cond == MSC_MYSTATUSOFF); + break; + case MSC_FRIENDHPLTMAXRATE: // FriendHP <= x% + flag = ((fbl = mob->getfriendhprate(md, 0, cond_data)) != NULL); + break; + case MSC_FRIENDHPINRATE: // FriendHP >= x% && FriendHP <= y% + flag = ((fbl = mob->getfriendhprate(md, cond_data, ms[skill_idx].val[0])) != NULL); + break; + case MSC_FRIENDSTATUSON: // Friend's status change x is active. + case MSC_FRIENDSTATUSOFF: // Friend's status change x is inactive. + flag = ((fbl = mob->getfriendstatus(md, cast_cond, cond_data)) != NULL); + break; + case MSC_SLAVELT: // Monster has less than x active slaves. + flag = (mob->countslave(&md->bl) < cond_data); + break; + case MSC_ATTACKPCGT: // Monster is attacked by more than x units. + flag = (unit->counttargeted(&md->bl) > cond_data); + break; + case MSC_SLAVELE: // Monster has x or less active slaves. + flag = (mob->countslave(&md->bl) <= cond_data); + break; + case MSC_ATTACKPCGE: // Monster is attacked by x or more units. + flag = (unit->counttargeted(&md->bl) >= cond_data); + break; + case MSC_AFTERSKILL: // Monster used skill x, or any skill if x is 0. + flag = (md->ud.skill_id == cond_data || cond_data == 0); + break; + case MSC_RUDEATTACKED: // Monster was rude attacked RUDE_ATTACKED_COUNT or more times. + flag = (md->state.attacked_count >= RUDE_ATTACKED_COUNT); + + // Rude attacked count should be reset after the skill condition is met. Thanks to Komurka [Skotlex] + if (flag) + md->state.attacked_count = 0; + + break; + case MSC_MASTERHPLTMAXRATE: // MasterHP < x% + flag = ((fbl = mob->getmasterhpltmaxrate(md, cond_data)) != NULL); + break; + case MSC_MASTERATTACKED: // Monster's master is under attack. + flag = (md->master_id > 0 && (fbl = map->id2bl(md->master_id)) != NULL); + flag = (fbl != NULL && unit->counttargeted(fbl) > 0); + break; + case MSC_ALCHEMIST: // Monster was summoned by an Alchemist. + flag = (md->state.alchemist != 0); + break; } } - if (!flag) - continue; //Skill requisite failed to be fulfilled. + if (flag == 0) // Skill cast condition not fulfilled. + continue; + + // Execute skill. + if (skill->get_casttype(ms[skill_idx].skill_id) == CAST_GROUND) { // Ground skill. + int target_type = ms[skill_idx].target; + int skill_range = skill->get_range2(&md->bl, ms[skill_idx].skill_id, ms[skill_idx].skill_lv); + struct block_list *bl; - //Execute skill - if (skill->get_casttype(ms[i].skill_id) == CAST_GROUND) {//Ground skill. - short x, y; - switch (ms[i].target) { - case MST_RANDOM: //Pick a random enemy within skill range. - bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), - skill->get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv)); - break; - case MST_TARGET: - case MST_AROUND5: - case MST_AROUND6: - case MST_AROUND7: - case MST_AROUND8: - bl = map->id2bl(md->target_id); - break; - case MST_MASTER: - bl = &md->bl; - if (md->master_id) - bl = map->id2bl(md->master_id); - if (bl) //Otherwise, fall through. - break; - FALLTHROUGH - case MST_FRIEND: - bl = fbl?fbl:(fmd?&fmd->bl:&md->bl); - break; - default: - bl = &md->bl; + switch (target_type) { + case MST_RANDOM: // Pick a random enemy within skill range. Skill center is monster position. + bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), skill_range); + break; + case MST_TARGET: // Monster's current target is within skill range. Skill center is monster position. + case MST_AROUND5: // Monster's current target is within skill range. Skill center is a random cell within a range of 1. + case MST_AROUND6: // Monster's current target is within skill range. Skill center is a random cell within a range of 2. + case MST_AROUND7: // Monster's current target is within skill range. Skill center is a random cell within a range of 3. + case MST_AROUND8: // Monster's current target is within skill range. Skill center is a random cell within a range of 4. + bl = map->id2bl(md->target_id); + break; + case MST_MASTER: // Monster's master is within skill range. Skill center is monster position. + // If monster has no master, use the monster as target, + bl = (md->master_id != 0) ? map->id2bl(md->master_id) : &md->bl; + + if (bl != NULL) break; + + // If monster has a master but master wasn't found, try a friend. + FALLTHROUGH + case MST_FRIEND: // Monster's friend is within skill range. Skill center is monster position. + bl = (fbl != NULL) ? fbl : &md->bl; + break; + default: // Monster is within skill range. Skill center is monster position. + bl = &md->bl; + break; } - if (!bl) continue; - - x = bl->x; - y = bl->y; - // Look for an area to cast the spell around... - if (ms[i].target >= MST_AROUND1 || ms[i].target >= MST_AROUND5) { - j = ms[i].target >= MST_AROUND1? - (ms[i].target-MST_AROUND1) +1: - (ms[i].target-MST_AROUND5) +1; - map->search_freecell(&md->bl, md->bl.m, &x, &y, j, j, 3); + + if (bl == NULL) // No target found. + continue; + + short x = bl->x; + short y = bl->y; + + // Find a target cell. + if (target_type >= MST_AROUND5 && target_type <= MST_AROUND) { + int range = target_type - ((target_type >= MST_AROUND1) ? MST_AROUND1 : MST_AROUND5) + 1; + map->search_freecell(&md->bl, md->bl.m, &x, &y, range, range, 3); } - md->skill_idx = i; + + md->skill_idx = skill_idx; map->freeblock_lock(); - if( !battle->check_range(&md->bl,bl,skill->get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) - || !unit->skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) - ) { + + uint16 sk_id = ms[skill_idx].skill_id; + uint16 sk_lv = ms[skill_idx].skill_lv; + int casttime = ms[skill_idx].casttime; + short cancel = ms[skill_idx].cancel; + + if (!battle->check_range(&md->bl, bl, skill_range) + || unit->skilluse_pos2(&md->bl, x, y, sk_id, sk_lv, casttime, cancel) == 0) { map->freeblock_unlock(); continue; } - } else { - //Targeted skill - switch (ms[i].target) { - case MST_RANDOM: //Pick a random enemy within skill range. - bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), - skill->get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv)); - break; - case MST_TARGET: - bl = map->id2bl(md->target_id); - break; - case MST_MASTER: - bl = &md->bl; - if (md->master_id) - bl = map->id2bl(md->master_id); - if (bl) //Otherwise, fall through. - break; - FALLTHROUGH - case MST_FRIEND: - if (fbl) { - bl = fbl; - break; - } else if (fmd) { - bl = &fmd->bl; - break; - } // else fall through - FALLTHROUGH - default: - bl = &md->bl; + } else { // Targeted skill. + int skill_range = skill->get_range2(&md->bl, ms[skill_idx].skill_id, ms[skill_idx].skill_lv); + struct block_list *bl; + + switch (ms[skill_idx].target) { + case MST_RANDOM: // Pick a random enemy within skill range. + bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), skill_range); + break; + case MST_TARGET: // Monster's current target is within skill range. + bl = map->id2bl(md->target_id); + break; + case MST_MASTER: // Monster's master is within skill range. + // If monster has no master, use the monster as target, + bl = (md->master_id != 0) ? map->id2bl(md->master_id) : &md->bl; + + if (bl != NULL) break; + + // If monster has a master but master wasn't found, try a friend. + FALLTHROUGH + case MST_FRIEND: // Monster's friend is within skill range. + bl = (fbl != NULL) ? fbl : &md->bl; + break; + default: // Monster is within skill range. + bl = &md->bl; + break; } - if (!bl) continue; - md->skill_idx = i; + if (bl == NULL) // No target found. + continue; + + md->skill_idx = skill_idx; map->freeblock_lock(); - if( !battle->check_range(&md->bl,bl,skill->get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) - || !unit->skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) - ) { + + uint16 sk_id = ms[skill_idx].skill_id; + uint16 sk_lv = ms[skill_idx].skill_lv; + int casttime = ms[skill_idx].casttime; + short cancel = ms[skill_idx].cancel; + + if (!battle->check_range(&md->bl, bl, skill_range) + || unit->skilluse_id2(&md->bl, bl->id, sk_id, sk_lv, casttime, cancel) == 0) { map->freeblock_unlock(); continue; } } - //Skill used. Post-setups... - if ( ms[ i ].msg_id ){ //Display color message [SnakeDrak] - struct mob_chat *mc = mob->chat(ms[i].msg_id); + + // Skill used. + if (ms[skill_idx].msg_id != 0) { // Display color message. [SnakeDrak] char temp[CHAT_SIZE_MAX]; char name[NAME_LENGTH]; - snprintf(name, sizeof name,"%s", md->name); - strtok(name, "#"); // discard extra name identifier if present [Daegaladh] - safesnprintf(temp, sizeof temp,"%s : %s", name, mc->msg); + struct mob_chat *mc = mob->chat(ms[skill_idx].msg_id); + + snprintf(name, sizeof(name), "%s", md->name); + strtok(name, "#"); // Discard extra name identifier if present. [Daegaladh] + safesnprintf(temp, sizeof(temp), "%s : %s", name, mc->msg); clif->messagecolor(&md->bl, mc->color, temp); } - if(!(battle_config.mob_ai&0x200)) { //pass on delay to same skill. - for (j = 0; j < md->db->maxskill; j++) - if (md->db->skill[j].skill_id == ms[i].skill_id) - md->skilldelay[j]=tick; - } else - md->skilldelay[i]=tick; + + if ((battle_config.mob_ai & 0x200) == 0) { // Pass on delay to same skill. + for (int j = 0; j < md->db->maxskill; j++) { + if (md->db->skill[j].skill_id == ms[skill_idx].skill_id) + md->skilldelay[j] = tick; + } + } else { + md->skilldelay[skill_idx] = tick; + } + map->freeblock_unlock(); - return 1; + return 0; } - //No skill was used. + + // No skill was used. md->skill_idx = -1; - return 0; + return 1; } + /*========================================== * Skill use event processing *------------------------------------------*/ @@ -3663,7 +3739,7 @@ static int mobskill_event(struct mob_data *md, struct block_list *src, int64 tic nullpo_ret(md); nullpo_ret(src); if(md->bl.prev == NULL || md->status.hp <= 0) - return 0; + return 1; if (md->special_state.ai == AI_SPHERE) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex] md->state.alchemist = 1; @@ -3683,7 +3759,7 @@ static int mobskill_event(struct mob_data *md, struct block_list *src, int64 tic else if (flag&BF_LONG && !(flag&BF_MAGIC)) //Long-attacked should not include magic. res = mob->skill_use(md, tick, MSC_LONGRANGEATTACKED); - if (!res) + if (res != 0) //Restore previous target only if skill condition failed to trigger. [Skotlex] md->target_id = target_id; //Otherwise check if the target is an enemy, and unlock if needed. @@ -3907,8 +3983,8 @@ static int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 } } - mob_skills[i].permillage *= battle_config.mob_skill_rate / 100; - mob_skills[i].delay *= battle_config.mob_skill_delay / 100; + mob_skills[i].permillage = mob_skills[i].permillage * battle_config.mob_skill_rate / 100; + mob_skills[i].delay = mob_skills[i].delay * battle_config.mob_skill_delay / 100; db->maxskill = ++i; } @@ -5012,12 +5088,10 @@ static int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *sou md.status.def_ele = i32; md.status.ele_lv = value; } else if (!inherit) { - ShowWarning("mob_read_db_sub: Missing element for monster ID %d.\n", md.mob_id); md.status.def_ele = ELE_NEUTRAL; md.status.ele_lv = 1; } } else if (!inherit) { - ShowWarning("mob_read_db_sub: Missing element for monster ID %d.\n", md.mob_id); md.status.def_ele = ELE_NEUTRAL; md.status.ele_lv = 1; } @@ -5491,115 +5565,134 @@ static bool mob_skill_db_libconfig_sub(struct config_setting_t *it, int n) return true; } +/** + * Reads a single monster skill from DB. + * + * @param it The libconfig settings block, which contains the skill data. + * @param n The skill data block's index within the parent monster block. + * @param mob_id The monster's ID. + * @return true on success, false on failure. + * + **/ static bool mob_skill_db_libconfig_sub_skill(struct config_setting_t *it, int n, int mob_id) { - int i, j, idx = 0; - int i32; - int skill_id = 0; - int skill_idx = 0; - bool clearskills = false; - const char *name = config_setting_name(it); - struct mob_skill *ms, gms; - nullpo_retr(false, it); Assert_retr(false, mob_id <= 0 || mob->db(mob_id) != mob->dummy); - if (!(skill_id = skill->name2id(name))) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Non existant skill id %d in monster %d, skipping.\n", skill_id, mob_id); + int skill_id = 0; + const char *name = config_setting_name(it); + const char *mob_str = (mob_id < 0) ? "global ID" : "monster"; + + if ((skill_id = skill->name2id(name)) == 0) { + ShowWarning("%s: Non existant skill %d in %s %d, skipping.\n", __func__, skill_id, mob_str, mob_id); return false; } + const char *skill_name = skill->get_name(skill_id); + bool clearskills = false; + // If ClearSkills flag is enabled clear all the previous skills. - if (libconfig->setting_lookup_bool_real(it, "ClearSkills", &clearskills) && clearskills) { - if (mob_id < 0) // Clearing skills globaly is not supported + if (libconfig->setting_lookup_bool_real(it, "ClearSkills", &clearskills) == CONFIG_TRUE && clearskills) { + if (mob_id < 0) { + ShowError("%s: Global skill clearing is not supported, skipping. (Global ID %d, skill %d (%s).)\n", + __func__, mob_id, skill_id, skill_name); return false; + } + memset(mob->db_data[mob_id]->skill, 0, sizeof(struct mob_skill) * MAX_MOBSKILL); mob->db_data[mob_id]->maxskill = 0; return true; } - if (mob_id < 0) { - // Prepare global skill. [Skotlex] + struct mob_skill *ms; + + if (mob_id < 0) { // Prepare global skill. [Skotlex] + struct mob_skill gms; memset(&gms, 0, sizeof (struct mob_skill)); ms = &gms; } else { + int idx = 0; + ARR_FIND(0, MAX_MOBSKILL, idx, (ms = &mob->db_data[mob_id]->skill[idx])->skill_id == 0); + if (idx == MAX_MOBSKILL) { - ShowError("mob_skill_db_libconfig_sub_skill: Too many skills for monster %d\n", mob_id); + ShowError("%s: Too many skills for monster %d, skipping.\n", __func__, mob_id); return false; } + + mob->db_data[mob_id]->maxskill = idx + 1; } + ms->skill_id = skill_id; + int i32 = MSS_ANY; if (mob->lookup_const(it, "SkillState", &i32) && (i32 < MSS_ANY || i32 > MSS_ANYTARGET)) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill state %d for skill id %d in monster %d, defaulting to MSS_ANY.\n", i32, skill_id, mob_id); + ShowWarning("%s: Invalid skill state %d for skill %d (%s) in %s %d, defaulting to MSS_ANY.\n", + __func__, i32, skill_id, skill_name, mob_str, mob_id); i32 = MSS_ANY; } ms->state = i32; - if (!libconfig->setting_lookup_int(it, "SkillLevel", &i32) || i32 <= 0) - i32 = 1; - ms->skill_lv = i32 > battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : i32; //we strip max skill level + int res = libconfig->setting_lookup_int(it, "SkillLevel", &i32); + ms->skill_lv = (res == CONFIG_FALSE) ? 1 : cap_value(i32, 1, battle_config.mob_max_skilllvl); - //Apply battle_config modifiers to rate (permillage) and delay [Skotlex] - if (libconfig->setting_lookup_int(it, "Rate", &i32)) - ms->permillage = i32; + res = libconfig->setting_lookup_int(it, "Rate", &i32); + ms->permillage = (res == CONFIG_FALSE) ? 1 : cap_value(i32, 1, 10000); + // Apply battle_config modifier to rate (permillage). if (battle_config.mob_skill_rate != 100) ms->permillage = ms->permillage * battle_config.mob_skill_rate / 100; + if (ms->permillage > 10000) ms->permillage = 10000; - else if (ms->permillage == 0 && battle_config.mob_skill_rate) + else if (ms->permillage == 0 && battle_config.mob_skill_rate != 0) ms->permillage = 1; - if (libconfig->setting_lookup_int(it, "CastTime", &i32) && i32 > 0) - ms->casttime = i32; + res = libconfig->setting_lookup_int(it, "CastTime", &i32); + ms->casttime = (res == CONFIG_FALSE) ? 0 : cap_value(i32, 0, MOB_MAX_CASTTIME); + + res = libconfig->setting_lookup_int(it, "Delay", &i32); + ms->delay = (res == CONFIG_FALSE) ? 0 : cap_value(i32, 0, MOB_MAX_DELAY); - if (libconfig->setting_lookup_int(it, "Delay", &i32)) - ms->delay = i32; + // Apply battle_config modifier to delay. if (battle_config.mob_skill_delay != 100) ms->delay = ms->delay * battle_config.mob_skill_delay / 100; - if (ms->delay < 0 || ms->delay > MOB_MAX_DELAY) //time overflow? - ms->delay = MOB_MAX_DELAY; - if (libconfig->setting_lookup_bool(it, "Cancelable", &i32)) - ms->cancel = (i32 == 0) ? 0 : 1; + ms->delay = min(ms->delay, MOB_MAX_DELAY); + + res = libconfig->setting_lookup_bool(it, "Cancelable", &i32); + ms->cancel = (res == CONFIG_FALSE) ? 0 : cap_value(i32, 0, 1); + i32 = MST_TARGET; if (mob->lookup_const(it, "SkillTarget", &i32) && (i32 < MST_TARGET || i32 > MST_AROUND)) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill target %d for skill id %d in monster %d, defaulting to MST_TARGET.\n", i32, skill_id, mob_id); - ms->target = MST_TARGET; + ShowWarning("%s: Invalid skill target %d for skill %d (%s) in %s %d, defaulting to MST_TARGET.\n", + __func__, i32, skill_id, skill_name, mob_str, mob_id); + i32 = MST_TARGET; } ms->target = i32; - //Check that the target condition is right for the skill type. [Skotlex] - skill_idx = skill->get_index(skill_id); - if (skill->get_casttype2(skill_idx) == CAST_GROUND) {//Ground skill. - if (ms->target > MST_AROUND) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Wrong mob skill target for ground skill %d (%s) for %s.\n", - ms->skill_id, skill->dbs->db[skill_idx].name, - mob_id < 0 ? "all mobs" : mob->db_data[mob_id]->sprite); - ms->target = MST_TARGET; - } - } else if (ms->target > MST_MASTER) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n", - ms->skill_id, skill->dbs->db[skill_idx].name, - mob_id < 0 ? "all mobs" : mob->db_data[mob_id]->sprite); + // Check the target condition for non-ground skills. (Ground skills can use every target.) + if (skill->get_casttype2(skill->get_index(skill_id)) != CAST_GROUND && ms->target > MST_MASTER) { + ShowWarning("%s: Wrong skill target %d for non-ground skill %d (%s) in %s %d, defaulting to MST_TARGET.\n", + __func__, ms->target, skill_id, skill_name, mob_str, mob_id); ms->target = MST_TARGET; } + i32 = MSC_ALWAYS; if (mob->lookup_const(it, "CastCondition", &i32) && (i32 < MSC_ALWAYS || i32 > MSC_SPAWN)) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill condition %d for skill id %d in monster %d, defaulting to MSC_ALWAYS.\n", i32, skill_id, mob_id); - ms->cond1 = MSC_ALWAYS; + ShowWarning("%s: Invalid skill condition %d for skill id %d (%s) in %s %d, defaulting to MSC_ALWAYS.\n", + __func__, i32, skill_id, skill_name, mob_str, mob_id); + i32 = MSC_ALWAYS; } ms->cond1 = i32; - if (mob->lookup_const(it, "ConditionData", &i32)) - ms->cond2 = i32; + ms->cond2 = !mob->lookup_const(it, "ConditionData", &i32) ? 0 : cap_value(i32, SHRT_MIN, SHRT_MAX); - for (i = 0; i < 5; i++) { + for (int i = 0; i < 5; i++) { char valname[16]; sprintf(valname, "val%1d", i); - if (libconfig->setting_lookup_int(it, valname, &i32)) + + if (libconfig->setting_lookup_int(it, valname, &i32) == CONFIG_TRUE) ms->val[i] = i32; } @@ -5610,60 +5703,64 @@ static bool mob_skill_db_libconfig_sub_skill(struct config_setting_t *it, int n, if (mob_id > 0 && (uint32)ms->val[1] == mob->db(mob_id)->status.mode) { ms->val[1] = MD_NONE; - ms->val[4] = 1; //request to return mode to normal. + ms->val[4] = 1; // Request to return mode to normal. } } if (ms->skill_id == NPC_EMOTION_ON && mob_id > 0 && ms->val[1] != MD_NONE) { - //Adds a mode to the mob. - //Remove aggressive mode when the new mob type is passive. - if (!(ms->val[1] & MD_AGGRESSIVE)) + // Add a mode to the mob and remove aggressive mode if the new mode is passive. + if ((ms->val[1] & MD_AGGRESSIVE) == 0) ms->val[3] |= MD_AGGRESSIVE; - ms->val[2] |= (uint32)ms->val[1]; //Add the new mode. - ms->val[1] = MD_NONE; //Do not "set" it. + + ms->val[2] |= (uint32)ms->val[1]; // Add the new mode. + ms->val[1] = MD_NONE; // Do not "set" it. } - if (libconfig->setting_lookup_int(it, "Emotion", &i32)) - ms->emotion = i32; - else - ms->emotion = -1; + res = libconfig->setting_lookup_int(it, "Emotion", &i32); + ms->emotion = (res == CONFIG_FALSE) ? -1 : cap_value(i32, -1, SHRT_MAX); - if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) && i32 > 0 && i32 <= MAX_MOB_CHAT) { - if (mob->chat_db[i32] == NULL) { - ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid msg id %d for skill id %d in monster %d, ignoring.\n", i32, skill_id, mob_id); + if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) == CONFIG_TRUE) { + if (i32 <= 0 || i32 > MAX_MOB_CHAT || mob->chat_db[i32] == NULL) { + ShowWarning("%s: Invalid message ID %d for skill %d (%s) in %s %d, ignoring.\n", + __func__, i32, skill_id, skill_name, mob_str, mob_id); } else { ms->msg_id = i32; } } - if (mob_id < 0) { - // Set this skill to ALL mobs. [Skotlex] - mob_id *= -1; - for (i = 1; i < MAX_MOB_DB; i++) { + if (mob_id < 0) { // Global skill assignment. + mob_id = -mob_id; + + for (int i = 1; i < MAX_MOB_DB; i++) { if (mob->db_data[i] == NULL) continue; - if (mob->db_data[i]->status.mode & MD_BOSS) { - if (!(mob_id & 2)) //Skill not for bosses + + if ((mob->db_data[i]->status.mode & MD_BOSS) != 0) { + if ((mob_id & 2) == 0) // Skill not for boss monsters. continue; } else { - if (!(mob_id & 1)) //Skill not for normal enemies. + if ((mob_id & 1) == 0) // Skill not for normal monsters. continue; } - ARR_FIND(0, MAX_MOBSKILL, j, mob->db_data[i]->skill[j].skill_id == 0); - if (j == MAX_MOBSKILL) + + int idx; + + ARR_FIND(0, MAX_MOBSKILL, idx, mob->db_data[i]->skill[idx].skill_id == 0); + + if (idx == MAX_MOBSKILL) { + ShowError("%s: Too many skills for monster %d in global ID %d, skipping.\n", + __func__, i, -mob_id); continue; + } - memcpy(&mob->db_data[i]->skill[j], ms, sizeof(struct mob_skill)); - mob->db_data[i]->maxskill = j + 1; + memcpy(&mob->db_data[i]->skill[idx], ms, sizeof(struct mob_skill)); + mob->db_data[i]->maxskill = idx + 1; } - } else { //Skill set on a single mob. - mob->db_data[mob_id]->maxskill = idx + 1; } return true; } - /*========================================== * mob_skill_db.txt reading *------------------------------------------*/ @@ -6059,7 +6156,7 @@ void mob_defaults(void) mob->getmasterhpltmaxrate = mob_getmasterhpltmaxrate; mob->getfriendstatus_sub = mob_getfriendstatus_sub; mob->getfriendstatus = mob_getfriendstatus; - mob->skill_use = mobskill_use; + mob->skill_use = mob_skill_use; mob->skill_event = mobskill_event; mob->is_clone = mob_is_clone; mob->clone_spawn = mob_clone_spawn; diff --git a/src/map/mob.h b/src/map/mob.h index 4cfddc2cd..6ad1ce705 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -323,6 +323,13 @@ enum { MSC_SPAWN, }; +/** Special monster(-name) constants used to assign skills to a group of monsters. **/ +enum mob_group { + ALL_MOBS_NONBOSS = -1, + ALL_MOBS_BOSS = -2, + ALL_MOBS = -3, +}; + /** * Mob IDs */ @@ -566,7 +573,7 @@ struct mob_interface { struct block_list* (*getfriendhprate) (struct mob_data *md, int min_rate, int max_rate); struct block_list* (*getmasterhpltmaxrate) (struct mob_data *md, int rate); int (*getfriendstatus_sub) (struct block_list *bl, va_list ap); - struct mob_data* (*getfriendstatus) (struct mob_data *md, int cond1, int cond2); + struct block_list *(*getfriendstatus) (struct mob_data *md, int cond1, int cond2); int (*skill_use) (struct mob_data *md, int64 tick, int event); int (*skill_event) (struct mob_data *md, struct block_list *src, int64 tick, int flag); int (*is_clone) (int class_); diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c index 0ca84cff4..0df323e96 100644 --- a/src/map/npc_chat.c +++ b/src/map/npc_chat.c @@ -394,7 +394,8 @@ static int npc_chat_sub(struct block_list *bl, va_list ap) // save out the matched strings for (i = 0; i < r; i++) { - char var[15], val[255]; + char var[SCRIPT_VARNAME_LENGTH + 1]; + char val[SCRIPT_STRING_VAR_LENGTH + 1]; snprintf(var, sizeof(var), "$@p%i$", i); libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val)); script->set_var(sd, var, val); diff --git a/src/map/packets.h b/src/map/packets.h index 1e6dc71bc..e30acbdf7 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -1824,6 +1824,11 @@ packet(0x96e,clif->ackmergeitems); packet(0x0aa4, clif->pRefineryUIClose); #endif +#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) + packet(0x0ab5, clif->pLapineUpgrade_close); + packet(0x0ab6, clif->pLapineUpgrade_makeItem); +#endif + // 2017-02-28aRagexeRE #if PACKETVER >= 20170228 // new packets diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h index e3a89827c..8ebbb39be 100644 --- a/src/map/packets_keys_main.h +++ b/src/map/packets_keys_main.h @@ -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, 2020-01-22cRagexe, 2020-01-22cRagexeRE, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-05aRagexeRE, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-12aRagexeRE, 2020-02-19dRagexe, 2020-02-19eRagexeRE, 2020-03-04aRagexe, 2020-03-04aRagexeRE, 2020-03-18bRagexe, 2020-04-01bRagexe +// 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, 2020-02-12aRagexe, 2020-02-12aRagexeRE, 2020-02-19dRagexe, 2020-02-19eRagexeRE, 2020-03-04aRagexe, 2020-03-04aRagexeRE, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe #if PACKETVER == 20101123 || \ PACKETVER == 20101124 || \ PACKETVER == 20101125 || \ @@ -191,7 +191,8 @@ PACKETVER == 20200219 || \ PACKETVER == 20200304 || \ PACKETVER == 20200318 || \ - PACKETVER >= 20200401 + PACKETVER == 20200401 || \ + PACKETVER >= 20200414 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h index f189032d3..904159d37 100644 --- a/src/map/packets_keys_zero.h +++ b/src/map/packets_keys_zero.h @@ -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, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_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, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero #if PACKETVER == 20171018 || \ PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ @@ -110,7 +110,8 @@ PACKETVER == 20200226 || \ PACKETVER == 20200304 || \ PACKETVER == 20200318 || \ - PACKETVER >= 20200401 + PACKETVER == 20200401 || \ + PACKETVER >= 20200414 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h index beedc950f..d643f3b0e 100644 --- a/src/map/packets_shuffle_main.h +++ b/src/map/packets_shuffle_main.h @@ -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, 2020-01-22cRagexe, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-19dRagexe, 2020-03-04aRagexe, 2020-03-18bRagexe, 2020-04-01bRagexe +// 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, 2020-02-12aRagexe, 2020-02-19dRagexe, 2020-03-04aRagexe, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe #if PACKETVER == 20190904 || \ PACKETVER == 20190918 || \ PACKETVER == 20190925 || \ @@ -9822,7 +9822,8 @@ PACKETVER == 20200219 || \ PACKETVER == 20200304 || \ PACKETVER == 20200318 || \ - PACKETVER == 20200401 + PACKETVER == 20200401 || \ + PACKETVER == 20200414 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 15936f854..fb12688c0 100644 --- a/src/map/packets_shuffle_zero.h +++ b/src/map/packets_shuffle_zero.h @@ -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, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_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, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero #if PACKETVER == 20190828 || \ PACKETVER == 20190911 || \ PACKETVER == 20190918 || \ @@ -822,7 +822,8 @@ PACKETVER == 20200226 || \ PACKETVER == 20200304 || \ PACKETVER == 20200318 || \ - PACKETVER == 20200401 + PACKETVER == 20200401 || \ + PACKETVER == 20200414 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 ca2fb8aef..3129a05d9 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -3891,6 +3891,42 @@ struct PACKET_ZC_AUTORUN_SKILL { } __attribute__((packed)); DEFINE_PACKET_HEADER(ZC_AUTORUN_SKILL, 0x0147); +#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) +struct PACKET_ZC_LAPINEUPGRADE_OPEN { + int16 packetType; +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + uint32 itemId; +#else + uint16 itemId; +#endif +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_LAPINEUPGRADE_OPEN, 0x0ab4); + +struct PACKET_ZC_LAPINEUPGRADE_RESULT { + int16 packetType; + uint16 result; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_LAPINEUPGRADE_RESULT, 0x0ab7); +#endif // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO) + +#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) +struct PACKET_CZ_LAPINEUPGRADE_CLOSE { + int16 packetType; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_LAPINEUPGRADE_CLOSE, 0x0ab5); + +struct PACKET_CZ_LAPINEUPGRADE_MAKE_ITEM { + int16 packetType; +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + uint32 itemId; +#else + uint16 itemId; +#endif + uint16 index; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_LAPINEUPGRADE_MAKE_ITEM, 0x0ab6); +#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) + #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 90282209b..5faadf76a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1605,58 +1605,56 @@ static void pc_calc_skilltree_clear(struct map_session_data *sd) *------------------------------------------*/ static int pc_calc_skilltree(struct map_session_data *sd) { - int i,id=0,flag; - int class = 0, classidx = 0; - nullpo_ret(sd); - i = pc->calc_skilltree_normalize_job(sd); - class = pc->mapid2jobid(i, sd->status.sex); + uint32 job = pc->calc_skilltree_normalize_job(sd); + int class = pc->mapid2jobid(job, sd->status.sex); if (class == -1) { //Unable to normalize job?? - ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id); + ShowError("pc_calc_skilltree: Unable to normalize job %u for character %s (%d:%d)\n", job, sd->status.name, sd->status.account_id, sd->status.char_id); return 1; } - classidx = pc->class2idx(class); + int classidx = pc->class2idx(class); pc->calc_skilltree_clear(sd); - for (i = 0; i < MAX_SKILL_DB; i++) { - if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) - { // Restore original level of skills after deleting earned skills. + for (int i = 0; i < MAX_SKILL_DB; i++) { + if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0) { + // Restore original level of skills after deleting earned skills. sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0; sd->status.skill[i].flag = SKILL_FLAG_PERMANENT; } - if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU ) - { //Enable Bard/Dancer spirit linked skills. - if (sd->status.sex) { - // Link dancer skills to bard. - if (i < 8) { - Assert_report(i >= 8); - continue; - } - if (sd->status.skill[i-8].lv < 10) - continue; - sd->status.skill[i].id = skill->dbs->db[i].nameid; - sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill - sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill + if (sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER + && ((skill->dbs->db[i].nameid >= BA_WHISTLE && skill->dbs->db[i].nameid <= BA_APPLEIDUN) + || (skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU)) + ) { + //Enable Bard/Dancer spirit linked skills. + int linked_nameid = skill->get_linked_song_dance_id(skill->dbs->db[i].nameid); + if (linked_nameid == 0) { + Assert_report("Linked bard/dance skill not found"); + continue; + } + int copy_from_index; + int copy_to_index; + if (sd->status.sex == SEX_MALE && skill->dbs->db[i].nameid >= BA_WHISTLE && skill->dbs->db[i].nameid <= BA_APPLEIDUN) { + copy_from_index = i; + copy_to_index = skill->get_index(linked_nameid); } else { - // Link bard skills to dancer. - if (i < 8) { - Assert_report(i >= 8); - continue; - } - if (sd->status.skill[i].lv < 10) - continue; - sd->status.skill[i-8].id = skill->dbs->db[i-8].nameid; - sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill - sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill + copy_from_index = skill->get_index(linked_nameid); + copy_to_index = i; } + if (copy_from_index < copy_to_index) + continue; // Copy only after the source skill has been filled into the tree + if (sd->status.skill[copy_from_index].lv < 10) + continue; // Copy only if the linked skill has been mastered + sd->status.skill[copy_to_index].id = skill->dbs->db[copy_to_index].nameid; + sd->status.skill[copy_to_index].lv = sd->status.skill[copy_from_index].lv; // Set the level to the same as the linking skill + sd->status.skill[copy_to_index].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill } } if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) { - for (i = 0; i < MAX_SKILL_DB; i++) { + for (int i = 0; i < MAX_SKILL_DB; i++) { switch(skill->dbs->db[i].nameid) { /** * Dummy skills must be added here otherwise they'll be displayed in the, @@ -1688,9 +1686,11 @@ static int pc_calc_skilltree(struct map_session_data *sd) return 0; } + bool changed = false; do { - flag = 0; - for (i = 0; i < MAX_SKILL_TREE && (id = pc->skill_tree[classidx][i].id) > 0; i++) { + changed = false; + int id; + for (int i = 0; i < MAX_SKILL_TREE && (id = pc->skill_tree[classidx][i].id) > 0; i++) { int idx = pc->skill_tree[classidx][i].idx; bool satisfied = true; if (sd->status.skill[idx].id > 0) @@ -1740,10 +1740,10 @@ static int pc_calc_skilltree(struct map_session_data *sd) sd->status.skill[idx].lv = 1; // need to manually specify a skill level sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill. } - flag = 1; // skill list has changed, perform another pass + changed = true; // skill list has changed, perform another pass } } - } while(flag); + } while (changed); pc->calc_skilltree_bonus(sd, classidx); @@ -4206,7 +4206,7 @@ static int pc_skill(struct map_session_data *sd, int id, int level, int flag) if( sd->status.skill[index].id == id ) { if( sd->status.skill[index].lv >= level ) return 0; - if( sd->status.skill[index].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level. + if (sd->status.skill[index].flag == SKILL_FLAG_PERMANENT) // Non-granted skill, store its level. sd->status.skill[index].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[index].lv; } else { sd->status.skill[index].id = id; @@ -7568,7 +7568,7 @@ static int pc_allskillup(struct map_session_data *sd) nullpo_ret(sd); for (i = 0; i < MAX_SKILL_DB; i++) { - if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) { + if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0) { sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0; sd->status.skill[i].flag = SKILL_FLAG_PERMANENT; if (sd->status.skill[i].lv == 0) @@ -8325,7 +8325,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src) base_penalty *= 2; if (sd->status.mod_death != 100) - base_penalty *= sd->status.mod_death / 100; + base_penalty = base_penalty * sd->status.mod_death / 100; sd->status.base_exp -= min(sd->status.base_exp, base_penalty); clif->updatestatus(sd, SP_BASEEXP); @@ -8350,7 +8350,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src) job_penalty *= 2; if (sd->status.mod_death != 100) - job_penalty *= sd->status.mod_death / 100; + job_penalty = job_penalty * sd->status.mod_death / 100; sd->status.job_exp -= min(sd->status.job_exp, job_penalty); clif->updatestatus(sd, SP_JOBEXP); @@ -9288,6 +9288,72 @@ static int pc_changelook(struct map_session_data *sd, int type, int val) return 0; } +/** + * Hides a character. + * + * @param sd The character to hide. + * @param show_msg Whether to show message to the character or not. + * + **/ +static void pc_hide(struct map_session_data *sd, bool show_msg) +{ + nullpo_retv(sd); + + clif->clearunit_area(&sd->bl, CLR_OUTSIGHT); + sd->sc.option |= OPTION_INVISIBLE; + sd->vd.class = INVISIBLE_CLASS; + + if (show_msg) + clif->message(sd->fd, atcommand->msgsd(sd, 11)); // Invisible: On + + // Decrement the number of pvp players on the map. + map->list[sd->bl.m].users_pvp--; + + if (map->list[sd->bl.m].flag.pvp != 0 && map->list[sd->bl.m].flag.pvp_nocalcrank == 0 + && sd->pvp_timer != INVALID_TIMER) { // Unregister the player for ranking. + timer->delete(sd->pvp_timer, pc->calc_pvprank_timer); + sd->pvp_timer = INVALID_TIMER; + } + + clif->changeoption(&sd->bl); +} + +/** + * Unhides a character. + * + * @param sd The character to unhide. + * @param show_msg Whether to show message to the character or not. + * + **/ +static void pc_unhide(struct map_session_data *sd, bool show_msg) +{ + nullpo_retv(sd); + + sd->sc.option &= ~OPTION_INVISIBLE; + + if (sd->disguise != -1) + status->set_viewdata(&sd->bl, sd->disguise); + else + status->set_viewdata(&sd->bl, sd->status.class); + + if (show_msg) + clif->message(sd->fd, atcommand->msgsd(sd, 10)); // Invisible: Off + + // Increment the number of pvp players on the map. + map->list[sd->bl.m].users_pvp++; + + if (map->list[sd->bl.m].flag.pvp != 0 && map->list[sd->bl.m].flag.pvp_nocalcrank == 0) // Register the player for ranking. + sd->pvp_timer = timer->add(timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0); + + // bugreport:2266 + map->foreachinmovearea(clif->insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl); + + if (sd->disguise != -1) + clif->spawn_unit(&sd->bl, AREA_WOS); + + clif->changeoption(&sd->bl); +} + /*========================================== * Give an option (type) to player (sd) and display it to client *------------------------------------------*/ @@ -9299,7 +9365,13 @@ static int pc_setoption(struct map_session_data *sd, int type) //Option has to be changed client-side before the class sprite or it won't always work (eg: Wedding sprite) [Skotlex] sd->sc.option=type; - clif->changeoption(&sd->bl); + + if ((p_type & OPTION_INVISIBLE) != 0 && (type & OPTION_INVISIBLE) == 0) // Unhide character. + pc->unhide(sd, false); + else if ((p_type & OPTION_INVISIBLE) == 0 && (type & OPTION_INVISIBLE) != 0) // Hide character. + pc->hide(sd, false); + else + clif->changeoption(&sd->bl); if( (type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc->checkskill(sd,RK_DRAGONTRAINING) > 0) ) { // Mounting @@ -11256,7 +11328,7 @@ static int pc_charm_timer(int tid, int64 tick, int id, intptr_t data) * @param max Maximum amount of charms to add. * @param type Charm type (@see spirit_charm_types) */ -static void pc_add_charm(struct map_session_data *sd, int interval, int max, int type) +static void pc_add_charm(struct map_session_data *sd, int interval, int max, enum spirit_charm_types type) { int tid, i; @@ -11298,7 +11370,7 @@ static void pc_add_charm(struct map_session_data *sd, int interval, int max, int * @param count Amount of charms to remove. * @param type Type of charm to remove. */ -static void pc_del_charm(struct map_session_data *sd, int count, int type) +static void pc_del_charm(struct map_session_data *sd, int count, enum spirit_charm_types type) { int i; @@ -12824,6 +12896,8 @@ void pc_defaults(void) pc->itemheal = pc_itemheal; pc->percentheal = pc_percentheal; pc->jobchange = pc_jobchange; + pc->hide = pc_hide; + pc->unhide = pc_unhide; pc->setoption = pc_setoption; pc->setcart = pc_setcart; pc->setfalcon = pc_setfalcon; diff --git a/src/map/pc.h b/src/map/pc.h index 2699b7882..e560df549 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -439,7 +439,7 @@ END_ZEROED_BLOCK; int spiritball, spiritball_old; int spirit_timer[MAX_SPIRITBALL]; int charm_count; - int charm_type; + enum spirit_charm_types charm_type; int charm_timer[MAX_SPIRITCHARM]; unsigned char potion_success_counter; //Potion successes in row counter unsigned char mission_count; //Stores the bounty kill count for TK_MISSION @@ -678,6 +678,7 @@ END_ZEROED_BLOCK; #define pc_isidle(sd) ( (sd)->chat_id != 0 || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(sockt->last_tick, (sd)->idletime) >= battle->bc->idle_no_share ) #define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading ) #define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1) +#define pc_cant_act_except_lapine(sd) ((sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1) /* equals pc_cant_act except it doesn't check for chat rooms */ #define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1) @@ -687,7 +688,7 @@ END_ZEROED_BLOCK; #define pc_ishiding(sd) ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) ) #define pc_iscloaking(sd) ( !((sd)->sc.option&OPTION_CHASEWALK) && ((sd)->sc.option&OPTION_CLOAK) ) #define pc_ischasewalk(sd) ( (sd)->sc.option&OPTION_CHASEWALK ) -#define pc_ismuted(sc,type) ( (sc)->data[SC_NOCHAT] && (sc)->data[SC_NOCHAT]->val1&(type) ) +#define pc_ismuted(sc, type) ( (sc)->data[SC_NOCHAT] != NULL && (battle_config.manner_system & (type)) != 0 ) #define pc_isvending(sd) ((sd)->state.vending || (sd)->state.prevend || (sd)->state.buyingstore) #ifdef NEW_CARTS @@ -1044,6 +1045,8 @@ END_ZEROED_BLOCK; /* End */ int (*itemheal) (struct map_session_data *sd,int itemid, int hp,int sp); int (*percentheal) (struct map_session_data *sd,int hp,int sp); int (*jobchange) (struct map_session_data *sd, int class, int upper); + void (*hide) (struct map_session_data *sd, bool show_msg); + void (*unhide) (struct map_session_data *sd, bool show_msg); int (*setoption) (struct map_session_data *sd,int type); int (*setcart) (struct map_session_data* sd, int type); void (*setfalcon) (struct map_session_data *sd, bool flag); @@ -1127,8 +1130,8 @@ END_ZEROED_BLOCK; /* End */ int (*load_combo) (struct map_session_data *sd); - void (*add_charm) (struct map_session_data *sd, int interval, int max, int type); - void (*del_charm) (struct map_session_data *sd, int count, int type); + void (*add_charm) (struct map_session_data *sd, int interval, int max, enum spirit_charm_types type); + void (*del_charm) (struct map_session_data *sd, int count, enum spirit_charm_types type); void (*baselevelchanged) (struct map_session_data *sd); int (*level_penalty_mod) (int diff, unsigned char race, uint32 mode, int type); diff --git a/src/map/pet.c b/src/map/pet.c index 620779765..299de42c7 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -323,7 +323,7 @@ static int pet_hungry(int tid, int64 tick, int id, intptr_t data) } clif->send_petdata(sd, pd, 2, pd->pet.hungry); - interval *= battle_config.pet_hungry_delay_rate / 100; + interval = interval * battle_config.pet_hungry_delay_rate / 100; pd->pet_hungry_timer = timer->add(tick + max(interval, 1), pet->hungry, sd->bl.id, 0); return 0; @@ -944,7 +944,7 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd) else intimacy += pd->petDB->r_hungry / 2; // Increase intimacy by 50% of FeedIncrement. - intimacy *= battle_config.pet_friendly_rate / 100; + intimacy = intimacy * battle_config.pet_friendly_rate / 100; pet->set_intimate(pd, pd->pet.intimate + intimacy); if (pd->pet.intimate == PET_INTIMACY_NONE) { @@ -1128,12 +1128,22 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, int return 0; } +/** + * Calls pet_ai_sub_hard() for a character's pet if conditions are fulfilled. + * + * @param sd The character. + * @param ap Additional arguments. In this case only the time stamp of pet AI timer execution. + * @return Always 0. + * + **/ static int pet_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { - int64 tick = va_arg(ap,int64); nullpo_ret(sd); - if(sd->status.pet_id && sd->pd) - pet->ai_sub_hard(sd->pd,sd,tick); + + int64 tick = va_arg(ap, int64); + + if (sd->bl.prev != NULL && sd->status.pet_id != 0 && sd->pd != NULL && sd->pd->bl.prev != NULL) + pet->ai_sub_hard(sd->pd, sd, tick); return 0; } diff --git a/src/map/script.c b/src/map/script.c index bf9348645..0fd8bda2a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3539,6 +3539,32 @@ static void set_reg_instance_num(struct script_state *st, int64 num, const char } /** + * Validates if a variable is permanent (stored in database) by passed variable name. + * + * @param name The variable name to validate. + * @return True if variable is permanent, otherwise false. + * + **/ +static bool script_is_permanent_variable(const char *name) +{ + nullpo_retr(false, name); + + if (strlen(name) == 0) + return false; + + if (ISALNUM(name[0]) != 0) + return true; // Permanent characater variable. + + if (name[0] == '#') + return true; // Permanent (global) account variable. + + if (strlen(name) > 1 && name[0] == '$' && ISALNUM(name[1]) != 0) + return true; // Permanent server variable. + + return false; +} + +/** * Stores the value of a script variable * * @param st current script state. @@ -3583,6 +3609,18 @@ static int set_reg(struct script_state *st, struct map_session_data *sd, int64 n if (is_string_variable(name)) {// string variable const char *str = (const char*)value; + if (script->is_permanent_variable(name) && strlen(str) > SCRIPT_STRING_VAR_LENGTH) { + ShowError("script:set_reg: Value of variable %s is too long: %lu! Maximum is %d. Skipping...\n", + name, strlen(str), SCRIPT_STRING_VAR_LENGTH); + + if (st != NULL) { + script->reportsrc(st); + st->state = END; + } + + return 0; + } + switch (prefix) { case '@': if (ref) { @@ -16362,7 +16400,6 @@ static BUILDIN(atcommand) struct map_session_data *sd, *dummy_sd = NULL; int fd; const char* cmd; - bool ret = true; cmd = script_getstr(st,2); @@ -16385,11 +16422,12 @@ static BUILDIN(atcommand) if (!atcommand->exec(fd, sd, cmd, false)) { ShowWarning("script: buildin_atcommand: failed to execute command '%s'\n", cmd); - script->reportsrc(st); - ret = false; + if (dummy_sd != NULL) + aFree(dummy_sd); + return false; } if (dummy_sd) aFree(dummy_sd); - return ret; + return true; } /** @@ -28101,6 +28139,11 @@ static void script_hardcoded_constants(void) script->set_constant("MST_AROUND4", MST_AROUND4, false, false); script->set_constant("MST_AROUND", MST_AROUND , false, false); + script->constdb_comment("Monster group constants"); + script->set_constant("ALL_MOBS_NONBOSS", ALL_MOBS_NONBOSS, false, false); + script->set_constant("ALL_MOBS_BOSS", ALL_MOBS_BOSS, false, false); + script->set_constant("ALL_MOBS", ALL_MOBS, false, false); + script->constdb_comment("pc block constants, use with *setpcblock* and *checkpcblock*"); script->set_constant("PCBLOCK_NONE", PCBLOCK_NONE, false, false); script->set_constant("PCBLOCK_MOVE", PCBLOCK_MOVE, false, false); @@ -28505,6 +28548,7 @@ void script_defaults(void) script->load_parameters = script_load_parameters; script->print_line = script_print_line; script->errorwarning_sub = script_errorwarning_sub; + script->is_permanent_variable = script_is_permanent_variable; script->set_reg = set_reg; script->set_reg_ref_str = set_reg_npcscope_str; script->set_reg_pc_ref_str = set_reg_pc_ref_str; diff --git a/src/map/script.h b/src/map/script.h index 89759db30..df5297ac0 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -993,6 +993,7 @@ struct script_interface { void (*load_parameters) (void); const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line); void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos); + bool (*is_permanent_variable) (const char *name); int (*set_reg) (struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref); void (*set_reg_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str); void (*set_reg_pc_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str); diff --git a/src/map/skill.c b/src/map/skill.c index 3dccf7a9e..caa1a0f29 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -72,6 +72,34 @@ static struct s_skill_dbs skilldbs; struct skill_interface *skill; +static const struct { + int start; + int end; +} skill_idx_ranges[] = { + { 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 +}; + //Since only mob-casted splash skills can hit ice-walls static int skill_splash_target(struct block_list *bl) { @@ -96,51 +124,37 @@ 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) { - 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]) { + int length = ARRAYLENGTH(skill_idx_ranges); + + + if (skill_id < skill_idx_ranges[0].start || skill_id > skill_idx_ranges[length - 1].end) { ShowWarning("skill_get_index: skill id '%d' is not being handled!\n", skill_id); + Assert_report(0); return 0; } int skill_idx = 0; + bool found = false; // Map Skill ID to Skill Indexes (in reverse order) - for (int i = 0; i < length; i += 2) { + for (int i = 0; i < length; i++) { // Check if SkillID belongs to this range. - if (skill_id <= skillRange[i + 1] && skill_id >= skillRange[i]) { - skill_idx += (skillRange[i + 1] - skill_id); + if (skill_id <= skill_idx_ranges[i].end && skill_id >= skill_idx_ranges[i].start) { + skill_idx += (skill_idx_ranges[i].end - skill_id); + found = true; break; } // Add the difference of current range - skill_idx += (skillRange[i + 1] - skillRange[i] + 1); + skill_idx += (skill_idx_ranges[i].end - skill_idx_ranges[i].start + 1); } + if (!found) { + ShowWarning("skill_get_index: skill id '%d' (idx: %d) is not handled as it lies outside the defined ranges!\n", skill_id, skill_idx); + Assert_report(0); + return 0; + } 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); + Assert_report(0); return 0; } @@ -1012,6 +1026,9 @@ static int skillnotok(uint16 skill_id, struct map_session_data *sd) if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) return 0; // can do any damn thing they want + if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNOSKILL)) + return 1; // block usage on 'noskill' cells [Wolfie] + if (skill_id == AL_TELEPORT && sd->autocast.type == AUTOCAST_ITEM && sd->autocast.skill_lv > 2) return 0; // Teleport level 3 and higher bypasses this check if cast by itemskill() script commands. @@ -5005,7 +5022,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl if( (tsc = status->get_sc(bl)) && (tsc->data[SC_HIDING] )) { clif->skill_nodamage(src,src,skill_id,skill_lv,1); } else - skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag); + skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); } break; case NPC_SELFDESTRUCTION: { @@ -7383,7 +7400,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * 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; + duration = duration * (100 - (tstatus->int_ + tstatus->vit) / 2) / 100; status->change_start(src, bl, SC_BLIND, rate, 1, 0, 0, 0, duration, SCFLAG_NONE); } @@ -10470,7 +10487,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * case KO_KAZEHU_SEIRAN: case KO_DOHU_KOUKAI: if(sd) { - int ttype = skill->get_ele(skill_id, skill_lv); + enum spirit_charm_types ttype = skill->get_ele(skill_id, skill_lv); clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); pc->add_charm(sd, skill->get_time(skill_id, skill_lv), MAX_SPIRITCHARM, ttype); // replace existing charms of other type } @@ -10927,6 +10944,37 @@ static int skill_count_wos(struct block_list *bl, va_list ap) return 0; } +/** + * Returns the linked song/dance skill ID, if any (for the Bard/Dancer Soul Link). + * + * @param skill_id The skill ID to look up + * + * @return The linked song or dance's skill ID if any + * @retval 0 if the given skill_id doesn't have a linked skill ID + */ +static int skill_get_linked_song_dance_id(int skill_id) +{ + switch (skill_id) { + case BA_WHISTLE: + return DC_HUMMING; + case BA_ASSASSINCROSS: + return DC_DONTFORGETME; + case BA_POEMBRAGI: + return DC_FORTUNEKISS; + case BA_APPLEIDUN: + return DC_SERVICEFORYOU; + case DC_HUMMING: + return BA_WHISTLE; + case DC_DONTFORGETME: + return BA_ASSASSINCROSS; + case DC_FORTUNEKISS: + return BA_POEMBRAGI; + case DC_SERVICEFORYOU: + return BA_APPLEIDUN; + } + return 0; +} + /*========================================== * *------------------------------------------*/ @@ -11296,7 +11344,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill FALLTHROUGH case GS_GROUNDDRIFT: //Ammo should be deleted right away. if ( skill_id == WM_SEVERE_RAINSTORM ) - sc_start(src,src,SC_NO_SWITCH_EQUIP,100,0,skill->get_time(skill_id,skill_lv)); + sc_start(src, src, type, 100, 0, skill->get_time(skill_id, skill_lv)); skill->unitsetting(src,skill_id,skill_lv,x,y,0); break; case WZ_ICEWALL: @@ -21801,4 +21849,5 @@ void skill_defaults(void) skill->splash_target = skill_splash_target; skill->check_npc_chaospanic = skill_check_npc_chaospanic; skill->count_wos = skill_count_wos; + skill->get_linked_song_dance_id = skill_get_linked_song_dance_id; } diff --git a/src/map/skill.h b/src/map/skill.h index 65195dc75..4dbbaf147 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2200,6 +2200,7 @@ struct skill_interface { int (*splash_target) (struct block_list* bl); int (*check_npc_chaospanic) (struct block_list *bl, va_list args); int (*count_wos) (struct block_list *bl, va_list ap); + int (*get_linked_song_dance_id) (int skill_id); }; #ifdef HERCULES_CORE diff --git a/src/map/status.c b/src/map/status.c index d3e85e5be..dc49f7e4e 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -696,6 +696,7 @@ static void initChangeTables(void) status->set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SCB_STR|SCB_CRI|SCB_MAXHP ); status->set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SCB_NONE ); status->set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SCB_MAXHP ); + status->set_sc( WM_SEVERE_RAINSTORM , SC_NO_SWITCH_EQUIP , SCB_NONE ); /** * Sorcerer @@ -865,6 +866,10 @@ static void initChangeTables(void) status->dbs->ChangeFlagTable[SC_WEDDING] |= SCB_SPEED; status->dbs->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_WATER] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_GROUND] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_FIRE] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_RESIST_PROPERTY_WIND] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; status->dbs->ChangeFlagTable[SC_TARGET_BLOOD] |= SCB_ALL; @@ -3029,6 +3034,22 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3; sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4; } + if (sc->data[SC_RESIST_PROPERTY_WATER] != NULL) { // Coldproof Potion + sd->subele[ELE_WATER] += sc->data[SC_RESIST_PROPERTY_WATER]->val1; + sd->subele[ELE_WIND] += sc->data[SC_RESIST_PROPERTY_WATER]->val2; + } + if (sc->data[SC_RESIST_PROPERTY_GROUND] != NULL) { // Earthproof Potion + sd->subele[ELE_EARTH] += sc->data[SC_RESIST_PROPERTY_GROUND]->val1; + sd->subele[ELE_FIRE] += sc->data[SC_RESIST_PROPERTY_GROUND]->val2; + } + if (sc->data[SC_RESIST_PROPERTY_FIRE] != NULL) { // Fireproof Potion + sd->subele[ELE_FIRE] += sc->data[SC_RESIST_PROPERTY_FIRE]->val1; + sd->subele[ELE_WATER] += sc->data[SC_RESIST_PROPERTY_FIRE]->val2; + } + if (sc->data[SC_RESIST_PROPERTY_WIND] != NULL) { // Thunderproof Potion + sd->subele[ELE_WIND] += sc->data[SC_RESIST_PROPERTY_WIND]->val1; + sd->subele[ELE_EARTH] += sc->data[SC_RESIST_PROPERTY_WIND]->val2; + } if (sc->data[SC_FIRE_CLOAK_OPTION]) { i = sc->data[SC_FIRE_CLOAK_OPTION]->val2; sd->subele[ELE_FIRE] += i; @@ -7753,6 +7774,10 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl case SC_ENCHANTARMS: case SC_ARMORPROPERTY: case SC_ARMOR_RESIST: + case SC_RESIST_PROPERTY_WATER: + case SC_RESIST_PROPERTY_GROUND: + case SC_RESIST_PROPERTY_FIRE: + case SC_RESIST_PROPERTY_WIND: break; case SC_GOSPEL: //Must not override a casting gospel char. @@ -7808,6 +7833,9 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl calc_flag = status->dbs->ChangeFlagTable[type]; if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs switch(type) { + case SC_AUTOTRADE: + case SC_KSPROTECTED: + break; // Prevent calling status_change_start_unknown_sc(). case SC_ADORAMUS: sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1)); // Fall through to SC_INC_AGI @@ -8052,7 +8080,6 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl // This is done this way because the message that the client displays is hardcoded, and only // shows how many minutes are remaining. [Panikon] total_tick = 60000; - val1 = battle_config.manner_system; //Mute filters. if (sd) { clif->changestatus(sd,SP_MANNER,sd->status.manner); @@ -8699,6 +8726,210 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl //associated, and yet are not wrong/unknown. [Skotlex] //break; } + case SC_ARMOR_RESIST: { + struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER]; + struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND]; + struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE]; + struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND]; + + // Water + int sum_water = val1 + ((sce_fire != NULL) ? sce_fire->val2 : 0); + bool show_icon = true; + if (sce_water != NULL && sce_water->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_water->timer); + if (td != NULL) { + sum_water += sce_water->val1; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_water - val1 > 0) + show_icon = false; + } + } + if (val1 > 0 && sum_water > 0 && show_icon) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER); + clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0); + } else if (sum_water <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER)); + } + + // Ground + int sum_ground = val2 + ((sce_wind != NULL) ? sce_wind->val2 : 0); + show_icon = true; + if (sce_ground != NULL && sce_ground->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_ground->timer); + if (td != NULL) { + sum_ground += sce_ground->val1; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_ground - val2 > 0) + show_icon = false; + } + } + if (val2 > 0 && sum_ground > 0 && show_icon) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND); + clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0); + } else if (sum_ground <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND)); + } + + // Fire + int sum_fire = val3 + ((sce_ground != NULL) ? sce_ground->val2 : 0); + show_icon = true; + if (sce_fire != NULL && sce_fire->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_fire->timer); + if (td != NULL) { + sum_fire += sce_fire->val1; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_fire - val3 > 0) + show_icon = false; + } + } + if (val3 > 0 && sum_fire > 0 && show_icon) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE); + clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0); + } else if (sum_fire <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE)); + } + + // Wind + int sum_wind = val4 + ((sce_water != NULL) ? sce_water->val2 : 0); + show_icon = true; + if (sce_wind != NULL && sce_wind->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_wind->timer); + if (td != NULL) { + sum_wind += sce_wind->val1; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_wind - val4 > 0) + show_icon = false; + } + } + if (val4 > 0 && sum_wind > 0 && show_icon) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND); + clif->status_change(bl, sc_icn, sc_typ, 1, total_tick, 0, 0, 0); + } else if (sum_wind <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND)); + } + + break; + } + case SC_RESIST_PROPERTY_WATER: { + struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST]; + struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE]; + struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND]; + + // Water + int sum_water = val1 + ((sce_fire != NULL) ? sce_fire->val2 : 0); + if (sce_all != NULL && sce_all->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_all->timer); + if (td != NULL) { + sum_water += sce_all->val1; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_water - val1 > 0) + flag |= SCFLAG_NOICON; + } + } + if (sum_water <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER)); + flag |= SCFLAG_NOICON; + } + + // Wind + int sum_wind = val2 + ((sce_wind != NULL) ? sce_wind->val1 : 0); + sum_wind += (sce_all != NULL) ? sce_all->val4 : 0; + if (sum_wind <= 0) + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND)); + + break; + } + case SC_RESIST_PROPERTY_GROUND: { + struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST]; + struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND]; + struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE]; + + // Ground + int sum_ground = val1 + ((sce_wind != NULL) ? sce_wind->val2 : 0); + if (sce_all != NULL && sce_all->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_all->timer); + if (td != NULL) { + sum_ground += sce_all->val2; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_ground - val1 > 0) + flag |= SCFLAG_NOICON; + } + } + if (sum_ground <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND)); + flag |= SCFLAG_NOICON; + } + + // Fire + int sum_fire = val2 + ((sce_fire != NULL) ? sce_fire->val1 : 0); + sum_fire += (sce_all != NULL) ? sce_all->val3 : 0; + if (sum_fire <= 0) + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE)); + + break; + } + case SC_RESIST_PROPERTY_FIRE: { + struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST]; + struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND]; + struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER]; + + // Fire + int sum_fire = val1 + ((sce_ground != NULL) ? sce_ground->val2 : 0); + if (sce_all != NULL && sce_all->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_all->timer); + if (td != NULL) { + sum_fire += sce_all->val3; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_fire - val1 > 0) + flag |= SCFLAG_NOICON; + } + } + if (sum_fire <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE)); + flag |= SCFLAG_NOICON; + } + + // Water + int sum_water = val2 + ((sce_water != NULL) ? sce_water->val1 : 0); + sum_water += (sce_all != NULL) ? sce_all->val1 : 0; + if (sum_water <= 0) + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER)); + + break; + } + case SC_RESIST_PROPERTY_WIND: { + struct status_change_entry *sce_all = sc->data[SC_ARMOR_RESIST]; + struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER]; + struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND]; + + // Wind + int sum_wind = val1 + ((sce_water != NULL) ? sce_water->val2 : 0); + if (sce_all != NULL && sce_all->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sce_all->timer); + if (td != NULL) { + sum_wind += sce_all->val4; + int left = (int)DIFF_TICK(td->tick, timer->gettick()); + if (left > total_tick && sum_wind - val1 > 0) + flag |= SCFLAG_NOICON; + } + } + if (sum_wind <= 0) { + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND)); + flag |= SCFLAG_NOICON; + } + + // Ground + int sum_ground = val2 + ((sce_ground != NULL) ? sce_ground->val1 : 0); + sum_ground += (sce_all != NULL) ? sce_all->val2 : 0; + if (sum_ground <= 0) + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND)); + + break; + } case SC_MER_FLEE: case SC_MER_ATK: case SC_MER_HIT: @@ -10625,6 +10856,9 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, vd = status->get_viewdata(bl); calc_flag = status->dbs->ChangeFlagTable[type]; + + bool remove_icon = true; + switch(type) { case SC_GRANITIC_ARMOR: { @@ -11056,6 +11290,202 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, break; } break; + case SC_ARMOR_RESIST: { + struct status_change_entry *sce_water = sc->data[SC_RESIST_PROPERTY_WATER]; + struct status_change_entry *sce_ground = sc->data[SC_RESIST_PROPERTY_GROUND]; + struct status_change_entry *sce_fire = sc->data[SC_RESIST_PROPERTY_FIRE]; + struct status_change_entry *sce_wind = sc->data[SC_RESIST_PROPERTY_WIND]; + + // Water + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WATER)); + if (sce_water != NULL && sce_water->timer != INVALID_TIMER) { + int sum_water = sce_water->val1 + ((sce_fire != NULL) ? sce_fire->val2 : 0); + const struct TimerData *td = timer->get(sce_water->timer); + if (td != NULL && sce_water->val1 > 0 && sum_water > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sce_water->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + // Ground + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_GROUND)); + if (sce_ground != NULL && sce_ground->timer != INVALID_TIMER) { + int sum_ground = sce_ground->val1 + ((sce_wind != NULL) ? sce_wind->val2 : 0); + const struct TimerData *td = timer->get(sce_ground->timer); + if (td != NULL && sce_ground->val1 > 0 && sum_ground > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sce_ground->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + // Fire + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_FIRE)); + if (sce_fire != NULL && sce_fire->timer != INVALID_TIMER) { + int sum_fire = sce_fire->val1 + ((sce_ground != NULL) ? sce_ground->val2 : 0); + const struct TimerData *td = timer->get(sce_fire->timer); + if (td != NULL && sce_fire->val1 > 0 && sum_fire > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sce_fire->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + // Wind + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(SC_RESIST_PROPERTY_WIND)); + if (sce_wind != NULL && sce_wind->timer != INVALID_TIMER) { + int sum_wind = sce_wind->val1 + ((sce_water != NULL) ? sce_water->val2 : 0); + const struct TimerData *td = timer->get(sce_wind->timer); + if (td != NULL && sce_wind->val1 > 0 && sum_wind > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sce_wind->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + break; + } + case SC_RESIST_PROPERTY_WATER: + if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer); + if (td == NULL) + break; + + // Water + int sum_water = sc->data[SC_ARMOR_RESIST]->val1; + if (sc->data[SC_RESIST_PROPERTY_FIRE] != NULL) + sum_water += sc->data[SC_RESIST_PROPERTY_FIRE]->val2; + if (sc->data[SC_ARMOR_RESIST]->val1 > 0 && sum_water > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + remove_icon = false; + } + + // Wind + int sum_wind = sc->data[SC_ARMOR_RESIST]->val4; + if (sc->data[SC_RESIST_PROPERTY_WIND] != NULL) + sum_wind += sc->data[SC_RESIST_PROPERTY_WIND]->val1; + if (sc->data[SC_ARMOR_RESIST]->val4 > 0 && sum_wind > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + break; + case SC_RESIST_PROPERTY_GROUND: + if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer); + if (td == NULL) + break; + + // Ground + int sum_ground = sc->data[SC_ARMOR_RESIST]->val2; + if (sc->data[SC_RESIST_PROPERTY_WIND] != NULL) + sum_ground += sc->data[SC_RESIST_PROPERTY_WIND]->val2; + if (sc->data[SC_ARMOR_RESIST]->val2 > 0 && sum_ground > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + remove_icon = false; + } + + // Fire + int sum_fire = sc->data[SC_ARMOR_RESIST]->val3; + if (sc->data[SC_RESIST_PROPERTY_FIRE] != NULL) + sum_fire += sc->data[SC_RESIST_PROPERTY_FIRE]->val1; + if (sc->data[SC_ARMOR_RESIST]->val3 > 0 && sum_fire > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + break; + case SC_RESIST_PROPERTY_FIRE: + if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer); + if (td == NULL) + break; + + // Fire + int sum_fire = sc->data[SC_ARMOR_RESIST]->val3; + if (sc->data[SC_RESIST_PROPERTY_GROUND] != NULL) + sum_fire += sc->data[SC_RESIST_PROPERTY_GROUND]->val2; + if (sc->data[SC_ARMOR_RESIST]->val3 > 0 && sum_fire > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_FIRE); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_FIRE); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + remove_icon = false; + } + + // Water + int sum_water = sc->data[SC_ARMOR_RESIST]->val1; + if (sc->data[SC_RESIST_PROPERTY_WATER] != NULL) + sum_water += sc->data[SC_RESIST_PROPERTY_WATER]->val1; + if (sc->data[SC_ARMOR_RESIST]->val1 > 0 && sum_water > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WATER); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WATER); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + break; + case SC_RESIST_PROPERTY_WIND: + if (sc->data[SC_ARMOR_RESIST] != NULL && sc->data[SC_ARMOR_RESIST]->timer != INVALID_TIMER) { + const struct TimerData *td = timer->get(sc->data[SC_ARMOR_RESIST]->timer); + if (td == NULL) + break; + + // Wind + int sum_wind = sc->data[SC_ARMOR_RESIST]->val4; + if (sc->data[SC_RESIST_PROPERTY_WATER] != NULL) + sum_wind += sc->data[SC_RESIST_PROPERTY_WATER]->val2; + if (sc->data[SC_ARMOR_RESIST]->val4 > 0 && sum_wind > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_WIND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_WIND); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + remove_icon = false; + } + + // Ground + int sum_ground = sc->data[SC_ARMOR_RESIST]->val2; + if (sc->data[SC_RESIST_PROPERTY_GROUND] != NULL) + sum_ground += sc->data[SC_RESIST_PROPERTY_GROUND]->val1; + if (sc->data[SC_ARMOR_RESIST]->val2 > 0 && sum_ground > 0) { + int sc_icn = status->get_sc_icon(SC_RESIST_PROPERTY_GROUND); + int sc_typ = status->get_sc_relevant_bl_types(SC_RESIST_PROPERTY_GROUND); + int sc_tck = (int)DIFF_TICK(td->tick, timer->gettick()); + int sc_ttl = sc->data[SC_ARMOR_RESIST]->total_tick; + clif->status_change_sub(bl, sc_icn, sc_typ, 1, sc_tck, sc_ttl, 0, 0, 0); + } + } + + break; } opt_flag = 1; @@ -11269,7 +11699,8 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, #endif //On Aegis, when turning off a status change, first goes the sc packet, then the option packet. - clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(type)); + if (remove_icon) + clif->sc_end(bl, bl->id, AREA, status->get_sc_icon(type)); if( opt_flag&8 ) //bugreport:681 clif->changeoption2(bl); diff --git a/src/map/unit.c b/src/map/unit.c index d484056f9..19f09f83c 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -436,7 +436,7 @@ static int unit_walk_toxy_timer(int tid, int64 tick, int id, intptr_t data) // Walk skills are triggered regardless of target due to the idle-walk mob state. // But avoid triggering on stop-walk calls. if (tid != INVALID_TIMER && (ud->walk_count % WALK_SKILL_INTERVAL) == 0 - && map->list[bl->m].users > 0 && mob->skill_use(md, tick, -1) == 1) { + && map->list[bl->m].users > 0 && mob->skill_use(md, tick, -1) == 0) { // Walk skills are supposed to be used while walking if (!(ud->skill_id == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER) && md->state.skillstate != MSS_WALK) { @@ -2345,7 +2345,7 @@ static int unit_attack_timer_sub(struct block_list *src, int tid, int64 tick) if(md) { //First attack is always a normal attack if(md->state.skillstate == MSS_ANGRY || md->state.skillstate == MSS_BERSERK) { - if (mob->skill_use(md,tick,-1)) { + if (mob->skill_use(md, tick, -1) == 0) { map->freeblock_unlock(); return 1; } diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index d7cc45904..d20766956 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -1410,6 +1410,10 @@ typedef void (*HPMHOOK_pre_clif_chatname_ack) (int *fd, struct block_list **bl); typedef void (*HPMHOOK_post_clif_chatname_ack) (int fd, struct block_list *bl); typedef void (*HPMHOOK_pre_clif_elemname_ack) (int *fd, struct block_list **bl); typedef void (*HPMHOOK_post_clif_elemname_ack) (int fd, struct block_list *bl); +typedef void (*HPMHOOK_pre_clif_skillname_ack) (int *fd, struct block_list **bl); +typedef void (*HPMHOOK_post_clif_skillname_ack) (int fd, struct block_list *bl); +typedef void (*HPMHOOK_pre_clif_itemname_ack) (int *fd, struct block_list **bl); +typedef void (*HPMHOOK_post_clif_itemname_ack) (int fd, struct block_list *bl); typedef void (*HPMHOOK_pre_clif_unknownname_ack) (int *fd, struct block_list **bl); typedef void (*HPMHOOK_post_clif_unknownname_ack) (int fd, struct block_list *bl); typedef void (*HPMHOOK_pre_clif_monster_hp_bar) (struct mob_data **md, struct map_session_data **sd); @@ -2762,6 +2766,14 @@ typedef void (*HPMHOOK_pre_clif_plapineDdukDdak_ack) (int *fd, struct map_sessio typedef void (*HPMHOOK_post_clif_plapineDdukDdak_ack) (int fd, struct map_session_data *sd); typedef void (*HPMHOOK_pre_clif_plapineDdukDdak_close) (int *fd, struct map_session_data **sd); typedef void (*HPMHOOK_post_clif_plapineDdukDdak_close) (int fd, struct map_session_data *sd); +typedef bool (*HPMHOOK_pre_clif_lapineUpgrade_open) (struct map_session_data **sd, int *item_id); +typedef bool (*HPMHOOK_post_clif_lapineUpgrade_open) (bool retVal___, struct map_session_data *sd, int item_id); +typedef bool (*HPMHOOK_pre_clif_lapineUpgrade_result) (struct map_session_data **sd, enum lapineUpgrade_result *result); +typedef bool (*HPMHOOK_post_clif_lapineUpgrade_result) (bool retVal___, struct map_session_data *sd, enum lapineUpgrade_result result); +typedef void (*HPMHOOK_pre_clif_pLapineUpgrade_close) (int *fd, struct map_session_data **sd); +typedef void (*HPMHOOK_post_clif_pLapineUpgrade_close) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_pLapineUpgrade_makeItem) (int *fd, struct map_session_data **sd); +typedef void (*HPMHOOK_post_clif_pLapineUpgrade_makeItem) (int fd, struct map_session_data *sd); typedef void (*HPMHOOK_pre_clif_pReqGearOff) (int *fd, struct map_session_data **sd); typedef void (*HPMHOOK_post_clif_pReqGearOff) (int fd, struct map_session_data *sd); #endif // MAP_CLIF_H @@ -5452,8 +5464,8 @@ typedef struct block_list* (*HPMHOOK_pre_mob_getmasterhpltmaxrate) (struct mob_d typedef struct block_list* (*HPMHOOK_post_mob_getmasterhpltmaxrate) (struct block_list* retVal___, struct mob_data *md, int rate); typedef int (*HPMHOOK_pre_mob_getfriendstatus_sub) (struct block_list **bl, va_list ap); typedef int (*HPMHOOK_post_mob_getfriendstatus_sub) (int retVal___, struct block_list *bl, va_list ap); -typedef struct mob_data* (*HPMHOOK_pre_mob_getfriendstatus) (struct mob_data **md, int *cond1, int *cond2); -typedef struct mob_data* (*HPMHOOK_post_mob_getfriendstatus) (struct mob_data* retVal___, struct mob_data *md, int cond1, int cond2); +typedef struct block_list* (*HPMHOOK_pre_mob_getfriendstatus) (struct mob_data **md, int *cond1, int *cond2); +typedef struct block_list* (*HPMHOOK_post_mob_getfriendstatus) (struct block_list* retVal___, struct mob_data *md, int cond1, int cond2); typedef int (*HPMHOOK_pre_mob_skill_use) (struct mob_data **md, int64 *tick, int *event); typedef int (*HPMHOOK_post_mob_skill_use) (int retVal___, struct mob_data *md, int64 tick, int event); typedef int (*HPMHOOK_pre_mob_skill_event) (struct mob_data **md, struct block_list **src, int64 *tick, int *flag); @@ -6210,6 +6222,10 @@ typedef int (*HPMHOOK_pre_pc_percentheal) (struct map_session_data **sd, int *hp typedef int (*HPMHOOK_post_pc_percentheal) (int retVal___, struct map_session_data *sd, int hp, int sp); typedef int (*HPMHOOK_pre_pc_jobchange) (struct map_session_data **sd, int *class, int *upper); typedef int (*HPMHOOK_post_pc_jobchange) (int retVal___, struct map_session_data *sd, int class, int upper); +typedef void (*HPMHOOK_pre_pc_hide) (struct map_session_data **sd, bool *show_msg); +typedef void (*HPMHOOK_post_pc_hide) (struct map_session_data *sd, bool show_msg); +typedef void (*HPMHOOK_pre_pc_unhide) (struct map_session_data **sd, bool *show_msg); +typedef void (*HPMHOOK_post_pc_unhide) (struct map_session_data *sd, bool show_msg); typedef int (*HPMHOOK_pre_pc_setoption) (struct map_session_data **sd, int *type); typedef int (*HPMHOOK_post_pc_setoption) (int retVal___, struct map_session_data *sd, int type); typedef int (*HPMHOOK_pre_pc_setcart) (struct map_session_data **sd, int *type); @@ -6340,10 +6356,10 @@ typedef void (*HPMHOOK_pre_pc_itemcd_do) (struct map_session_data **sd, bool *lo typedef void (*HPMHOOK_post_pc_itemcd_do) (struct map_session_data *sd, bool load); typedef int (*HPMHOOK_pre_pc_load_combo) (struct map_session_data **sd); typedef int (*HPMHOOK_post_pc_load_combo) (int retVal___, struct map_session_data *sd); -typedef void (*HPMHOOK_pre_pc_add_charm) (struct map_session_data **sd, int *interval, int *max, int *type); -typedef void (*HPMHOOK_post_pc_add_charm) (struct map_session_data *sd, int interval, int max, int type); -typedef void (*HPMHOOK_pre_pc_del_charm) (struct map_session_data **sd, int *count, int *type); -typedef void (*HPMHOOK_post_pc_del_charm) (struct map_session_data *sd, int count, int type); +typedef void (*HPMHOOK_pre_pc_add_charm) (struct map_session_data **sd, int *interval, int *max, enum spirit_charm_types *type); +typedef void (*HPMHOOK_post_pc_add_charm) (struct map_session_data *sd, int interval, int max, enum spirit_charm_types type); +typedef void (*HPMHOOK_pre_pc_del_charm) (struct map_session_data **sd, int *count, enum spirit_charm_types *type); +typedef void (*HPMHOOK_post_pc_del_charm) (struct map_session_data *sd, int count, enum spirit_charm_types type); typedef void (*HPMHOOK_pre_pc_baselevelchanged) (struct map_session_data **sd); typedef void (*HPMHOOK_post_pc_baselevelchanged) (struct map_session_data *sd); typedef int (*HPMHOOK_pre_pc_level_penalty_mod) (int *diff, unsigned char *race, uint32 *mode, int *type); @@ -6974,6 +6990,8 @@ typedef const char* (*HPMHOOK_pre_script_print_line) (StringBuf **buf, const cha typedef const char* (*HPMHOOK_post_script_print_line) (const char* retVal___, StringBuf *buf, const char *p, const char *mark, int line); typedef void (*HPMHOOK_pre_script_errorwarning_sub) (StringBuf **buf, const char **src, const char **file, int *start_line, const char **error_msg, const char **error_pos); typedef void (*HPMHOOK_post_script_errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos); +typedef bool (*HPMHOOK_pre_script_is_permanent_variable) (const char **name); +typedef bool (*HPMHOOK_post_script_is_permanent_variable) (bool retVal___, const char *name); typedef int (*HPMHOOK_pre_script_set_reg) (struct script_state **st, struct map_session_data **sd, int64 *num, const char **name, const void **value, struct reg_db **ref); typedef int (*HPMHOOK_post_script_set_reg) (int retVal___, struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref); typedef void (*HPMHOOK_pre_script_set_reg_ref_str) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str); @@ -7670,6 +7688,8 @@ typedef int (*HPMHOOK_pre_skill_check_npc_chaospanic) (struct block_list **bl, v typedef int (*HPMHOOK_post_skill_check_npc_chaospanic) (int retVal___, struct block_list *bl, va_list args); typedef int (*HPMHOOK_pre_skill_count_wos) (struct block_list **bl, va_list ap); typedef int (*HPMHOOK_post_skill_count_wos) (int retVal___, struct block_list *bl, va_list ap); +typedef int (*HPMHOOK_pre_skill_get_linked_song_dance_id) (int *skill_id); +typedef int (*HPMHOOK_post_skill_get_linked_song_dance_id) (int retVal___, int skill_id); #endif // MAP_SKILL_H #ifdef COMMON_SOCKET_H /* sockt */ typedef void (*HPMHOOK_pre_sockt_init) (void); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 3bde525cf..02ba063ed 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -1000,6 +1000,10 @@ struct { struct HPMHookPoint *HP_clif_chatname_ack_post; struct HPMHookPoint *HP_clif_elemname_ack_pre; struct HPMHookPoint *HP_clif_elemname_ack_post; + struct HPMHookPoint *HP_clif_skillname_ack_pre; + struct HPMHookPoint *HP_clif_skillname_ack_post; + struct HPMHookPoint *HP_clif_itemname_ack_pre; + struct HPMHookPoint *HP_clif_itemname_ack_post; struct HPMHookPoint *HP_clif_unknownname_ack_pre; struct HPMHookPoint *HP_clif_unknownname_ack_post; struct HPMHookPoint *HP_clif_monster_hp_bar_pre; @@ -2352,6 +2356,14 @@ struct { struct HPMHookPoint *HP_clif_plapineDdukDdak_ack_post; struct HPMHookPoint *HP_clif_plapineDdukDdak_close_pre; struct HPMHookPoint *HP_clif_plapineDdukDdak_close_post; + struct HPMHookPoint *HP_clif_lapineUpgrade_open_pre; + struct HPMHookPoint *HP_clif_lapineUpgrade_open_post; + struct HPMHookPoint *HP_clif_lapineUpgrade_result_pre; + struct HPMHookPoint *HP_clif_lapineUpgrade_result_post; + struct HPMHookPoint *HP_clif_pLapineUpgrade_close_pre; + struct HPMHookPoint *HP_clif_pLapineUpgrade_close_post; + struct HPMHookPoint *HP_clif_pLapineUpgrade_makeItem_pre; + struct HPMHookPoint *HP_clif_pLapineUpgrade_makeItem_post; struct HPMHookPoint *HP_clif_pReqGearOff_pre; struct HPMHookPoint *HP_clif_pReqGearOff_post; struct HPMHookPoint *HP_cmdline_init_pre; @@ -4790,6 +4802,10 @@ struct { struct HPMHookPoint *HP_pc_percentheal_post; struct HPMHookPoint *HP_pc_jobchange_pre; struct HPMHookPoint *HP_pc_jobchange_post; + struct HPMHookPoint *HP_pc_hide_pre; + struct HPMHookPoint *HP_pc_hide_post; + struct HPMHookPoint *HP_pc_unhide_pre; + struct HPMHookPoint *HP_pc_unhide_post; struct HPMHookPoint *HP_pc_setoption_pre; struct HPMHookPoint *HP_pc_setoption_post; struct HPMHookPoint *HP_pc_setcart_pre; @@ -5504,6 +5520,8 @@ struct { struct HPMHookPoint *HP_script_print_line_post; struct HPMHookPoint *HP_script_errorwarning_sub_pre; struct HPMHookPoint *HP_script_errorwarning_sub_post; + struct HPMHookPoint *HP_script_is_permanent_variable_pre; + struct HPMHookPoint *HP_script_is_permanent_variable_post; struct HPMHookPoint *HP_script_set_reg_pre; struct HPMHookPoint *HP_script_set_reg_post; struct HPMHookPoint *HP_script_set_reg_ref_str_pre; @@ -6194,6 +6212,8 @@ struct { struct HPMHookPoint *HP_skill_check_npc_chaospanic_post; struct HPMHookPoint *HP_skill_count_wos_pre; struct HPMHookPoint *HP_skill_count_wos_post; + struct HPMHookPoint *HP_skill_get_linked_song_dance_id_pre; + struct HPMHookPoint *HP_skill_get_linked_song_dance_id_post; struct HPMHookPoint *HP_sockt_init_pre; struct HPMHookPoint *HP_sockt_init_post; struct HPMHookPoint *HP_sockt_final_pre; @@ -7883,6 +7903,10 @@ struct { int HP_clif_chatname_ack_post; int HP_clif_elemname_ack_pre; int HP_clif_elemname_ack_post; + int HP_clif_skillname_ack_pre; + int HP_clif_skillname_ack_post; + int HP_clif_itemname_ack_pre; + int HP_clif_itemname_ack_post; int HP_clif_unknownname_ack_pre; int HP_clif_unknownname_ack_post; int HP_clif_monster_hp_bar_pre; @@ -9235,6 +9259,14 @@ struct { int HP_clif_plapineDdukDdak_ack_post; int HP_clif_plapineDdukDdak_close_pre; int HP_clif_plapineDdukDdak_close_post; + int HP_clif_lapineUpgrade_open_pre; + int HP_clif_lapineUpgrade_open_post; + int HP_clif_lapineUpgrade_result_pre; + int HP_clif_lapineUpgrade_result_post; + int HP_clif_pLapineUpgrade_close_pre; + int HP_clif_pLapineUpgrade_close_post; + int HP_clif_pLapineUpgrade_makeItem_pre; + int HP_clif_pLapineUpgrade_makeItem_post; int HP_clif_pReqGearOff_pre; int HP_clif_pReqGearOff_post; int HP_cmdline_init_pre; @@ -11673,6 +11705,10 @@ struct { int HP_pc_percentheal_post; int HP_pc_jobchange_pre; int HP_pc_jobchange_post; + int HP_pc_hide_pre; + int HP_pc_hide_post; + int HP_pc_unhide_pre; + int HP_pc_unhide_post; int HP_pc_setoption_pre; int HP_pc_setoption_post; int HP_pc_setcart_pre; @@ -12387,6 +12423,8 @@ struct { int HP_script_print_line_post; int HP_script_errorwarning_sub_pre; int HP_script_errorwarning_sub_post; + int HP_script_is_permanent_variable_pre; + int HP_script_is_permanent_variable_post; int HP_script_set_reg_pre; int HP_script_set_reg_post; int HP_script_set_reg_ref_str_pre; @@ -13077,6 +13115,8 @@ struct { int HP_skill_check_npc_chaospanic_post; int HP_skill_count_wos_pre; int HP_skill_count_wos_post; + int HP_skill_get_linked_song_dance_id_pre; + int HP_skill_get_linked_song_dance_id_post; int HP_sockt_init_pre; int HP_sockt_init_post; int HP_sockt_final_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index e7515b19f..4a36c5a1e 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -524,6 +524,8 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->mobname_normal_ack, HP_clif_mobname_normal_ack) }, { HP_POP(clif->chatname_ack, HP_clif_chatname_ack) }, { HP_POP(clif->elemname_ack, HP_clif_elemname_ack) }, + { HP_POP(clif->skillname_ack, HP_clif_skillname_ack) }, + { HP_POP(clif->itemname_ack, HP_clif_itemname_ack) }, { HP_POP(clif->unknownname_ack, HP_clif_unknownname_ack) }, { HP_POP(clif->monster_hp_bar, HP_clif_monster_hp_bar) }, { HP_POP(clif->hpmeter, HP_clif_hpmeter) }, @@ -1200,6 +1202,10 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->lapineDdukDdak_result, HP_clif_lapineDdukDdak_result) }, { HP_POP(clif->plapineDdukDdak_ack, HP_clif_plapineDdukDdak_ack) }, { HP_POP(clif->plapineDdukDdak_close, HP_clif_plapineDdukDdak_close) }, + { HP_POP(clif->lapineUpgrade_open, HP_clif_lapineUpgrade_open) }, + { HP_POP(clif->lapineUpgrade_result, HP_clif_lapineUpgrade_result) }, + { HP_POP(clif->pLapineUpgrade_close, HP_clif_pLapineUpgrade_close) }, + { HP_POP(clif->pLapineUpgrade_makeItem, HP_clif_pLapineUpgrade_makeItem) }, { HP_POP(clif->pReqGearOff, HP_clif_pReqGearOff) }, /* cmdline_interface */ { HP_POP(cmdline->init, HP_cmdline_init) }, @@ -2453,6 +2459,8 @@ struct HookingPointData HookingPoints[] = { { HP_POP(pc->itemheal, HP_pc_itemheal) }, { HP_POP(pc->percentheal, HP_pc_percentheal) }, { HP_POP(pc->jobchange, HP_pc_jobchange) }, + { HP_POP(pc->hide, HP_pc_hide) }, + { HP_POP(pc->unhide, HP_pc_unhide) }, { HP_POP(pc->setoption, HP_pc_setoption) }, { HP_POP(pc->setcart, HP_pc_setcart) }, { HP_POP(pc->setfalcon, HP_pc_setfalcon) }, @@ -2818,6 +2826,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(script->load_parameters, HP_script_load_parameters) }, { HP_POP(script->print_line, HP_script_print_line) }, { HP_POP(script->errorwarning_sub, HP_script_errorwarning_sub) }, + { HP_POP(script->is_permanent_variable, HP_script_is_permanent_variable) }, { HP_POP(script->set_reg, HP_script_set_reg) }, { HP_POP(script->set_reg_ref_str, HP_script_set_reg_ref_str) }, { HP_POP(script->set_reg_pc_ref_str, HP_script_set_reg_pc_ref_str) }, @@ -3166,6 +3175,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(skill->splash_target, HP_skill_splash_target) }, { HP_POP(skill->check_npc_chaospanic, HP_skill_check_npc_chaospanic) }, { HP_POP(skill->count_wos, HP_skill_count_wos) }, + { HP_POP(skill->get_linked_song_dance_id, HP_skill_get_linked_song_dance_id) }, /* socket_interface */ { HP_POP(sockt->init, HP_sockt_init) }, { HP_POP(sockt->final, HP_sockt_final) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 6c5071020..f0e395b64 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -13035,6 +13035,58 @@ void HP_clif_elemname_ack(int fd, struct block_list *bl) { } return; } +void HP_clif_skillname_ack(int fd, struct block_list *bl) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_skillname_ack_pre > 0) { + void (*preHookFunc) (int *fd, struct block_list **bl); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_skillname_ack_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_skillname_ack_pre[hIndex].func; + preHookFunc(&fd, &bl); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.skillname_ack(fd, bl); + } + if (HPMHooks.count.HP_clif_skillname_ack_post > 0) { + void (*postHookFunc) (int fd, struct block_list *bl); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_skillname_ack_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_skillname_ack_post[hIndex].func; + postHookFunc(fd, bl); + } + } + return; +} +void HP_clif_itemname_ack(int fd, struct block_list *bl) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_itemname_ack_pre > 0) { + void (*preHookFunc) (int *fd, struct block_list **bl); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_itemname_ack_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_itemname_ack_pre[hIndex].func; + preHookFunc(&fd, &bl); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.itemname_ack(fd, bl); + } + if (HPMHooks.count.HP_clif_itemname_ack_post > 0) { + void (*postHookFunc) (int fd, struct block_list *bl); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_itemname_ack_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_itemname_ack_post[hIndex].func; + postHookFunc(fd, bl); + } + } + return; +} void HP_clif_unknownname_ack(int fd, struct block_list *bl) { int hIndex = 0; if (HPMHooks.count.HP_clif_unknownname_ack_pre > 0) { @@ -30663,6 +30715,112 @@ void HP_clif_plapineDdukDdak_close(int fd, struct map_session_data *sd) { } return; } +bool HP_clif_lapineUpgrade_open(struct map_session_data *sd, int item_id) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_clif_lapineUpgrade_open_pre > 0) { + bool (*preHookFunc) (struct map_session_data **sd, int *item_id); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_open_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_open_pre[hIndex].func; + retVal___ = preHookFunc(&sd, &item_id); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.lapineUpgrade_open(sd, item_id); + } + if (HPMHooks.count.HP_clif_lapineUpgrade_open_post > 0) { + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int item_id); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_open_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_open_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, item_id); + } + } + return retVal___; +} +bool HP_clif_lapineUpgrade_result(struct map_session_data *sd, enum lapineUpgrade_result result) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_clif_lapineUpgrade_result_pre > 0) { + bool (*preHookFunc) (struct map_session_data **sd, enum lapineUpgrade_result *result); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_result_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_result_pre[hIndex].func; + retVal___ = preHookFunc(&sd, &result); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.lapineUpgrade_result(sd, result); + } + if (HPMHooks.count.HP_clif_lapineUpgrade_result_post > 0) { + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, enum lapineUpgrade_result result); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_result_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_result_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, result); + } + } + return retVal___; +} +void HP_clif_pLapineUpgrade_close(int fd, struct map_session_data *sd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_pLapineUpgrade_close_pre > 0) { + void (*preHookFunc) (int *fd, struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_close_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_close_pre[hIndex].func; + preHookFunc(&fd, &sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pLapineUpgrade_close(fd, sd); + } + if (HPMHooks.count.HP_clif_pLapineUpgrade_close_post > 0) { + void (*postHookFunc) (int fd, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_close_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_close_post[hIndex].func; + postHookFunc(fd, sd); + } + } + return; +} +void HP_clif_pLapineUpgrade_makeItem(int fd, struct map_session_data *sd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_pre > 0) { + void (*preHookFunc) (int *fd, struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_makeItem_pre[hIndex].func; + preHookFunc(&fd, &sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pLapineUpgrade_makeItem(fd, sd); + } + if (HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_post > 0) { + void (*postHookFunc) (int fd, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_makeItem_post[hIndex].func; + postHookFunc(fd, sd); + } + } + return; +} void HP_clif_pReqGearOff(int fd, struct map_session_data *sd) { int hIndex = 0; if (HPMHooks.count.HP_clif_pReqGearOff_pre > 0) { @@ -53703,11 +53861,11 @@ int HP_mob_getfriendstatus_sub(struct block_list *bl, va_list ap) { } return retVal___; } -struct mob_data* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond2) { +struct block_list* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond2) { int hIndex = 0; - struct mob_data* retVal___ = NULL; + struct block_list* retVal___ = NULL; if (HPMHooks.count.HP_mob_getfriendstatus_pre > 0) { - struct mob_data* (*preHookFunc) (struct mob_data **md, int *cond1, int *cond2); + struct block_list* (*preHookFunc) (struct mob_data **md, int *cond1, int *cond2); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_getfriendstatus_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mob_getfriendstatus_pre[hIndex].func; @@ -53722,7 +53880,7 @@ struct mob_data* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond retVal___ = HPMHooks.source.mob.getfriendstatus(md, cond1, cond2); } if (HPMHooks.count.HP_mob_getfriendstatus_post > 0) { - struct mob_data* (*postHookFunc) (struct mob_data* retVal___, struct mob_data *md, int cond1, int cond2); + struct block_list* (*postHookFunc) (struct block_list* retVal___, struct mob_data *md, int cond1, int cond2); for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_getfriendstatus_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mob_getfriendstatus_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, cond1, cond2); @@ -63705,6 +63863,58 @@ int HP_pc_jobchange(struct map_session_data *sd, int class, int upper) { } return retVal___; } +void HP_pc_hide(struct map_session_data *sd, bool show_msg) { + int hIndex = 0; + if (HPMHooks.count.HP_pc_hide_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, bool *show_msg); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_hide_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pc_hide_pre[hIndex].func; + preHookFunc(&sd, &show_msg); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.hide(sd, show_msg); + } + if (HPMHooks.count.HP_pc_hide_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, bool show_msg); + for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_hide_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pc_hide_post[hIndex].func; + postHookFunc(sd, show_msg); + } + } + return; +} +void HP_pc_unhide(struct map_session_data *sd, bool show_msg) { + int hIndex = 0; + if (HPMHooks.count.HP_pc_unhide_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, bool *show_msg); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_unhide_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pc_unhide_pre[hIndex].func; + preHookFunc(&sd, &show_msg); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.unhide(sd, show_msg); + } + if (HPMHooks.count.HP_pc_unhide_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, bool show_msg); + for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_unhide_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pc_unhide_post[hIndex].func; + postHookFunc(sd, show_msg); + } + } + return; +} int HP_pc_setoption(struct map_session_data *sd, int type) { int hIndex = 0; int retVal___ = 0; @@ -65443,10 +65653,10 @@ int HP_pc_load_combo(struct map_session_data *sd) { } return retVal___; } -void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, int type) { +void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, enum spirit_charm_types type) { int hIndex = 0; if (HPMHooks.count.HP_pc_add_charm_pre > 0) { - void (*preHookFunc) (struct map_session_data **sd, int *interval, int *max, int *type); + void (*preHookFunc) (struct map_session_data **sd, int *interval, int *max, enum spirit_charm_types *type); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_add_charm_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_pc_add_charm_pre[hIndex].func; @@ -65461,7 +65671,7 @@ void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, int typ HPMHooks.source.pc.add_charm(sd, interval, max, type); } if (HPMHooks.count.HP_pc_add_charm_post > 0) { - void (*postHookFunc) (struct map_session_data *sd, int interval, int max, int type); + void (*postHookFunc) (struct map_session_data *sd, int interval, int max, enum spirit_charm_types type); for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_add_charm_post; hIndex++) { postHookFunc = HPMHooks.list.HP_pc_add_charm_post[hIndex].func; postHookFunc(sd, interval, max, type); @@ -65469,10 +65679,10 @@ void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, int typ } return; } -void HP_pc_del_charm(struct map_session_data *sd, int count, int type) { +void HP_pc_del_charm(struct map_session_data *sd, int count, enum spirit_charm_types type) { int hIndex = 0; if (HPMHooks.count.HP_pc_del_charm_pre > 0) { - void (*preHookFunc) (struct map_session_data **sd, int *count, int *type); + void (*preHookFunc) (struct map_session_data **sd, int *count, enum spirit_charm_types *type); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_del_charm_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_pc_del_charm_pre[hIndex].func; @@ -65487,7 +65697,7 @@ void HP_pc_del_charm(struct map_session_data *sd, int count, int type) { HPMHooks.source.pc.del_charm(sd, count, type); } if (HPMHooks.count.HP_pc_del_charm_post > 0) { - void (*postHookFunc) (struct map_session_data *sd, int count, int type); + void (*postHookFunc) (struct map_session_data *sd, int count, enum spirit_charm_types type); for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_del_charm_post; hIndex++) { postHookFunc = HPMHooks.list.HP_pc_del_charm_post[hIndex].func; postHookFunc(sd, count, type); @@ -73290,6 +73500,33 @@ void HP_script_errorwarning_sub(StringBuf *buf, const char *src, const char *fil } return; } +bool HP_script_is_permanent_variable(const char *name) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_script_is_permanent_variable_pre > 0) { + bool (*preHookFunc) (const char **name); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_script_is_permanent_variable_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_script_is_permanent_variable_pre[hIndex].func; + retVal___ = preHookFunc(&name); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.is_permanent_variable(name); + } + if (HPMHooks.count.HP_script_is_permanent_variable_post > 0) { + bool (*postHookFunc) (bool retVal___, const char *name); + for (hIndex = 0; hIndex < HPMHooks.count.HP_script_is_permanent_variable_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_script_is_permanent_variable_post[hIndex].func; + retVal___ = postHookFunc(retVal___, name); + } + } + return retVal___; +} int HP_script_set_reg(struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref) { int hIndex = 0; int retVal___ = 0; @@ -82831,6 +83068,33 @@ int HP_skill_count_wos(struct block_list *bl, va_list ap) { } return retVal___; } +int HP_skill_get_linked_song_dance_id(int skill_id) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_skill_get_linked_song_dance_id_pre > 0) { + int (*preHookFunc) (int *skill_id); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_linked_song_dance_id_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_skill_get_linked_song_dance_id_pre[hIndex].func; + retVal___ = preHookFunc(&skill_id); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.skill.get_linked_song_dance_id(skill_id); + } + if (HPMHooks.count.HP_skill_get_linked_song_dance_id_post > 0) { + int (*postHookFunc) (int retVal___, int skill_id); + for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_linked_song_dance_id_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_skill_get_linked_song_dance_id_post[hIndex].func; + retVal___ = postHookFunc(retVal___, skill_id); + } + } + return retVal___; +} /* socket_interface */ void HP_sockt_init(void) { int hIndex = 0; |