diff options
56 files changed, 5532 insertions, 577 deletions
diff --git a/conf/map/battle/feature.conf b/conf/map/battle/feature.conf index e01c7f93d..c0c60e475 100644 --- a/conf/map/battle/feature.conf +++ b/conf/map/battle/feature.conf @@ -70,4 +70,12 @@ features: { // true: enable (Default) // false: disable enable_homun_autofeed: true + + // Enable Attendance System for clients >= 2018-03-07bRagexeRE or 2018-04-04bRagexe + // true: enable (Default) + // false: disable + enable_attendance_system: true + + // Attendance End time in the format YearMonthDay + feature_attendance_endtime: 20180331 } diff --git a/conf/map/battle/items.conf b/conf/map/battle/items.conf index f7ffd3f32..135df7107 100644 --- a/conf/map/battle/items.conf +++ b/conf/map/battle/items.conf @@ -119,3 +119,7 @@ bow_unequip_arrow: true // How much should rental mounts increase a player's movement speed? (Note 2) // Official: 25 (Default) boarding_halter_speed: 25 + +// Allow to use items when the storage is open? +// Official: false (Default) +storage_use_item: false diff --git a/conf/messages.conf b/conf/messages.conf index 3f395ab5e..7adff9dff 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -74,7 +74,10 @@ 46: %s recalled! 47: Base level can't go any higher. 48: Any work in progress (NPC dialog, manufacturing ...) quit and try again. -//49-52 FREE +49: Unable to Teleport in this area +50: This skill cannot be used within this area. +51: This item cannot be used within this area. +//52 FREE 53: '%s' stats: 54: No player found in map '%s'. 55: 1 player found in map '%s'. @@ -475,7 +478,9 @@ 538: Hack on trade: character '%s' (account: %d) try to trade more items that he has. 539: This player has %d of a kind of item (id: %d), and tried to trade %d of them. 540: This player has been definitively blocked. -//541-545 FREE +//541-543 FREE +544: <MSG>3455</MSG> +545: <MSG>3456,%d</MSG> // @showmobs 546: Please enter a mob name/id (usage: @showmobs <mob name/id>) 547: Invalid mob name %s! diff --git a/db/attendance_db.conf b/db/attendance_db.conf new file mode 100644 index 000000000..f63ceed53 --- /dev/null +++ b/db/attendance_db.conf @@ -0,0 +1,119 @@ +//================= Hercules Database ===================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2018 Hercules Dev Team +//= Copyright (C) 2018 Asheraf +//= +//= 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/>. +//========================================================================= + +attendance_db:( +/************************************************************************** + ************* Entry structure ******************************************** + ************************************************************************** +{ + // ================ Mandatory fields ============================== + ItemID: Item Constant (string) + Amount: Item Amount (int) +}, +**************************************************************************/ +{ + ItemID: "Red_Potion" + Amount: 10 +}, +{ + ItemID: "Orange_Potion" + Amount: 10 +}, +{ + ItemID: "Yellow_Potion" + Amount: 10 +}, +{ + ItemID: "White_Potion" + Amount: 10 +}, +{ + ItemID: "Blue_Potion" + Amount: 10 +}, +{ + ItemID: "Red_Potion" + Amount: 20 +}, +{ + ItemID: "Orange_Potion" + Amount: 20 +}, +{ + ItemID: "Yellow_Potion" + Amount: 20 +}, +{ + ItemID: "White_Potion" + Amount: 20 +}, +{ + ItemID: "Blue_Potion" + Amount: 20 +}, +{ + ItemID: "Red_Potion" + Amount: 30 +}, +{ + ItemID: "Orange_Potion" + Amount: 30 +}, +{ + ItemID: "Yellow_Potion" + Amount: 30 +}, +{ + ItemID: "White_Potion" + Amount: 30 +}, +{ + ItemID: "Blue_Potion" + Amount: 30 +}, +{ + ItemID: "Red_Potion" + Amount: 40 +}, +{ + ItemID: "Orange_Potion" + Amount: 40 +}, +{ + ItemID: "Yellow_Potion" + Amount: 40 +}, +{ + ItemID: "White_Potion" + Amount: 40 +}, +{ + ItemID: "Blue_Potion" + Amount: 40 +} +) diff --git a/db/constants.conf b/db/constants.conf index 8c3336f79..cc0fb3104 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -3877,4 +3877,62 @@ constants_db: { UDT_STATADD: 54 UDT_ROBE: 55 UDT_BODY2: 56 + + comment__: "HatEffect Constants" + HAT_EF_BLOSSOM_FLUTTERING: 1 + HAT_EF_MERMAID_LONGING: 2 + HAT_EF_RL_BANISHING_BUSTER: 3 + HAT_EF_LJOSALFAR: 4 + HAT_EF_CLOCKING: 5 + HAT_EF_SNOW: 6 + HAT_EF_MAKEBLUR: 7 + HAT_EF_SLEEPATTACK: 8 + HAT_EF_GUMGANG: 9 + HAT_EF_TALK_FROSTJOKE: 10 + HAT_EF_DEMONSTRATION: 11 + HAT_EF_FLUTTER_BUTTERFLY: 12 + HAT_EF_ANGEL_FLUTTERING: 13 + HAT_EF_BLESSING_OF_ANGELS: 14 + HAT_EF_ELECTRIC: 15 + HAT_EF_GREEN_FLOOR: 16 + HAT_EF_SHRINK: 17 + HAT_EF_VALHALLA_IDOL: 18 + HAT_EF_ANGEL_STAIRS: 19 + HAT_EF_GLOW_OF_NEW_YEAR: 20 + HAT_EF_BOTTOM_FORTUNEKISS: 21 + HAT_EF_PINKBODY: 22 + HAT_EF_DOUBLEGUMGANG: 23 + HAT_EF_GIANTBODY: 24 + HAT_EF_GREEN99_6: 25 + HAT_EF_CIRCLEPOWER: 26 + HAT_EF_BOTTOM_BLOODYLUST: 27 + HAT_EF_WATER_BELOW: 28 + HAT_EF_LEVEL99_150: 29 + HAT_EF_YELLOWFLY3: 30 + HAT_EF_KAGEMUSYA: 31 + HAT_EF_CHERRYBLOSSOM: 32 + HAT_EF_STRANGELIGHTS: 33 + HAT_EF_WL_TELEKINESIS_INTENSE: 34 + HAT_EF_AB_OFFERTORIUM_RING: 35 + HAT_EF_WHITEBODY2: 36 + HAT_EF_SAKURA: 37 + HAT_EF_CLOUD2: 38 + HAT_EF_FEATHER_FLUTTERING: 39 + HAT_EF_CAMELLIA_HAIR_PIN: 40 + HAT_EF_JP_EV_EFFECT01: 41 + HAT_EF_JP_EV_EFFECT02: 42 + HAT_EF_JP_EV_EFFECT03: 43 + HAT_EF_FLORAL_WALTZ: 44 + HAT_EF_MAGICAL_FEATHER: 45 + HAT_EF_HAT_EFFECT: 46 + HAT_EF_BAKURETSU_HADOU: 47 + HAT_EF_GOLD_SHOWER: 48 + HAT_EF_WHITEBODY: 49 + HAT_EF_WATER_BELOW2: 50 + HAT_EF_FIREWORK: 51 + HAT_EF_RETURN_TW_1ST_HAT: 52 + HAT_EF_C_FLUTTERBUTTERFLY_BL: 53 + HAT_EF_QSCARABA: 54 + HAT_EF_FSTONE: 55 + HAT_EF_MAGICCIRCLE: 56 } diff --git a/db/pet_db2.conf b/db/pet_db2.conf new file mode 100644 index 000000000..34a6130e4 --- /dev/null +++ b/db/pet_db2.conf @@ -0,0 +1,64 @@ +//================= Hercules Database ===================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2018 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/>. +//========================================================================= +//= Pets Database +//========================================================================= + +pet_db:( +/************************************************************************** + ************* Entry structure ******************************************** + ************************************************************************** +{ + // ================ Mandatory fields ============================== + Id: ID (int) + SpriteName: "Sprite_Name" (string) + Name: "Pet Name" (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) + 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) + } + CaptureRate: capture rate (int, defaults to 0) + Speed: speed (int, defaults to 0) + 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) + PetScript: <" Pet Script (can also be multi-line) "> + EquipScript: <" Equip Script (can also be multi-line) "> +}, +**************************************************************************/ + // entries in this file will override the ones in /(pre-)re/pet_db.conf +) diff --git a/db/pet_db2.txt b/db/pet_db2.txt deleted file mode 100644 index 4e9b26fd9..000000000 --- a/db/pet_db2.txt +++ /dev/null @@ -1,52 +0,0 @@ -// Pet Additional Database -// -// Structure of Database: -// MobID,Name,JName,LureID,EggID,EquipID,FoodID,Fullness,HungryDelay,R_Hungry,R_Full,Intimate,Die,Capture,Speed,S_Performance,talk_convert_class,attack_rate,defence_attack_rate,change_target_rate,pet_script,loyal_script -// -// 01. MobID Monster ID of the pet. -// 02. Name Name of the monster as defined in the database. -// 03. JName The display name of the monster when hatched. -// 04. LureID Pet Tame Item ID. -// 05. EggID Pet Egg ID. -// 06. EquipID Pet Accessory ID. -// 07. FoodID Pet Food ID. -// 08. Fullness The amount of hunger points increasing with each feeding. -// 09. HungryDelay The amount of time it takes for hunger to decrease after feeding. (Default: 60 seconds) -// 10. R_Hungry Amount of Intimacy that is increased when fed. -// 11. R_Full Amount of Intimacy that is decreased when over-fed. -// 12. Intimate Amount of Intimacy the pet starts with. -// 13. Die Amount of Intimacy that is decreased when the pet owner dies. -// 14. Capture Capture succes rate (10000 = 100%) -// 15. Speed Pet's walk speed. (Defaul: 150) -// 16. S_Performance Special Performance. (Yes = 1, No = 0) -// 17. talk_convert_class Disables pet talk (instead of talking they emote with /!.) -// 18. attack_rate Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy). -// 19. defence_attack_rate Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy). -// 20. change_target_rate Rate of which the pet will change its attack target. -// 21. pet_script Script to execute when the pet is hatched. -// 22. loyal_script Script to execute when the pet is hatched (requires at least pet_equip_min_friendly intimacy, independent of pet_script). -//NOTE: The max value (100%) of attack_rate, defense_rate & change_target_rate is 10000. - -//In theory you can use any valid script, but it is run only once upon pet -//loading, so it is recommended you use the specific pet scripts: - -//petskillattack skillid, skilllv, hits, rate, bonusrate -//Skill attack that triggers while the pet is attacking. Rate is the base -//chance of execution per attack. Bonusrate is an additional success rate when -//intimacy reaches max. If hits is specified and different than 0, it will make -//the pet cast the skill with a fixed amount of damage inflicted and the -//specified number of hits. A value of zero uses the skill's defaults. - -//petskillsupport skillid, skilllv, delay, hp%, sp% -//Casts a support skill when the health levels are below the specified hp% and -//sp%. Delay is the minimum time in seconds before the skill can be cast again - -//petrecovery type, delay: Cures the "type" status effect after "delay" seconds - -//petskillbonus type, value, duration, delay -//Gives bonus stats. Type is the stat to increase (bStr, bLuk), value is the -//amount by which it is increased, duration signals how long the bonus lasts -//delay is the time elapsed after the bonus ends and before it starts again. - -//A single pet can have petloot, petskillbonus, petskillattack and -//petskillsupport at the same time, but only one of each. diff --git a/db/pre-re/item_db.conf b/db/pre-re/item_db.conf index a98495eee..d62bbf19c 100644 --- a/db/pre-re/item_db.conf +++ b/db/pre-re/item_db.conf @@ -64561,7 +64561,21 @@ item_db: ( Type: "IT_PETEGG" Buy: 20 }, - +{ + Id: 9058 + AegisName: "Snow_Rabbit_Egg" + Name: "Christmas Snow Rabbit Egg" + Type: "IT_PETEGG" + Buy: 20 + Trade: { + nodrop: true + notrade: true + nocart: true + nogstorage: true + nomail: true + noauction: true + } +}, //== Pet Accessories ======================================= { Id: 10001 diff --git a/db/pre-re/pet_db.conf b/db/pre-re/pet_db.conf new file mode 100644 index 000000000..3ce78e546 --- /dev/null +++ b/db/pre-re/pet_db.conf @@ -0,0 +1,1544 @@ +//================= Hercules Database ===================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2018 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/>. +//========================================================================= +//= Pets Database +//========================================================================= + +pet_db:( +/************************************************************************** + ************* Entry structure ******************************************** + ************************************************************************** +{ + // ================ Mandatory fields ============================== + Id: ID (int) + SpriteName: "Sprite_Name" (string) + Name: "Pet Name" (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) + 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) + } + CaptureRate: capture rate (int, defaults to 0) + Speed: speed (int, defaults to 0) + 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) + PetScript: <" Pet Script (can also be multi-line) "> + EquipScript: <" Equip Script (can also be multi-line) "> +}, +**************************************************************************/ +{ + Id: 1002 + SpriteName: "PORING" + Name: "Poring" + TamingItem: "Unripe_Apple" + EggItem: "Poring_Egg" + AccessoryItem: "Backpack" + FoodItem: "Apple_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 + PetScript: <" petloot(10); "> + EquipScript: <" + bonus(bLuk, 2); + bonus(bCritical, 1); + "> +}, +{ + Id: 1011 + SpriteName: "CHONCHON" + Name: "ChonChon" + TamingItem: "Rotten_Fish" + EggItem: "Chonchon_Egg" + AccessoryItem: "Monster_Oxygen_Mask" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 250 + PetScript: <" petskillbonus(bAgi, 4, 10, 50); "> + EquipScript: <" + bonus(bAgi, 1); + bonus(bFlee, 2); + "> +}, +{ + Id: 1014 + SpriteName: "SPORE" + Name: "Spore" + TamingItem: "Dew_Laden_Moss" + EggItem: "Spore_Egg" + AccessoryItem: "Bark_Shorts" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 350 + DefendRate: 500 + ChangeTargetRate: 500 + PetScript: <" petrecovery(SC_POISON, 60); "> + EquipScript: <" + bonus(bHit, 5); + bonus(bAtk, -2); + "> +}, +{ + Id: 1019 + SpriteName: "PECOPECO" + Name: "PecoPeco" + TamingItem: "Fatty_Chubby_Earthworm" + EggItem: "PecoPeco_Egg" + AccessoryItem: "Battered_Pot" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 400 + DefendRate: 500 + ChangeTargetRate: 800 + PetScript: <" petskillbonus(bSpeedRate, 25, 20, 20); "> + EquipScript: <" + bonus(bMaxHP, 150); + bonus(bMaxSP, -10); + "> +}, +{ + Id: 1023 + SpriteName: "ORK_WARRIOR" + Name: "Orc Warrior" + TamingItem: "Horror_Of_Tribe" + EggItem: "Orc_Warrior_Egg" + AccessoryItem: "Wild_Flower" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + SpecialPerformance: true + AttackRate: 600 + DefendRate: 200 + ChangeTargetRate: 300 + PetScript: <" petskillattack("NPC_PIERCINGATT", 100, 1, 0, 10); "> + EquipScript: <" + bonus(bAtk, 10); + bonus(bDef, -3); + "> +}, +{ + Id: 1026 + SpriteName: "MUNAK" + Name: "Munak" + TamingItem: "No_Recipient" + EggItem: "Munak_Egg" + AccessoryItem: "Punisher" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 750 + ChangeTargetRate: 300 + PetScript: <" petskillattack("NPC_DARKNESSATTACK", 444, 1, 0, 10); "> + EquipScript: <" + bonus(bInt, 1); + bonus(bDef, 1); + "> +}, +{ + Id: 1029 + SpriteName: "ISIS" + Name: "Isis" + TamingItem: "Armlet_Of_Obedience" + EggItem: "Isis_Egg" + AccessoryItem: "Queens_Hair_Ornament" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 650 + DefendRate: 450 + ChangeTargetRate: 150 + PetScript: <" petskillsupport("PR_MAGNIFICAT", 2, 60, 50, 50); "> + EquipScript: <" + bonus(bMatkRate, -1); + bonus(bAtkRate, 1); + "> +}, +{ + Id: 1031 + SpriteName: "POPORING" + Name: "Poporing" + TamingItem: "Bitter_Herb" + EggItem: "Poporing_Egg" + AccessoryItem: "Backpack" + FoodItem: "Green_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 500 + ChangeTargetRate: 400 + PetScript: <" petloot(15); "> + EquipScript: <" + bonus(bLuk, 2); + bonus2(bSubEle, Ele_Poison, 10); + "> +}, +{ + Id: 1035 + SpriteName: "HUNTER_FLY" + Name: "Hunter Fly" + TamingItem: "Monster_Juice" + EggItem: "Hunter_Fly_Egg" + AccessoryItem: "Monster_Oxygen_Mask" + FoodItem: "Red_Gemstone" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillattack("NPC_WINDATTACK", 888, 2, 0, 10); "> + EquipScript: <" + bonus(bFlee, -5); + bonus(bFlee2, 2); + "> +}, +{ + Id: 1042 + SpriteName: "STEEL_CHONCHON" + Name: "Steel ChonChon" + TamingItem: "Lusty_Iron" + EggItem: "Steel_Chonchon_Egg" + AccessoryItem: "Monster_Oxygen_Mask" + FoodItem: "Iron_Ore" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillbonus(bAgiVit, 4, 20, 40); "> + EquipScript: <" + bonus(bFlee, 6); + bonus(bAgi, -1); + "> +}, +{ + Id: 1049 + SpriteName: "PICKY" + Name: "Picky" + TamingItem: "Earthworm_The_Dude" + EggItem: "Picky_Egg" + AccessoryItem: "Tiny_Egg_Shell" + FoodItem: "Red_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 600 + ChangeTargetRate: 50 + PetScript: <" petskillbonus(bStr, 3, 10, 50); "> + EquipScript: <" + bonus(bStr, 1); + bonus(bAtk, 5); + "> +}, +{ + Id: 1052 + SpriteName: "ROCKER" + Name: "Rocker" + TamingItem: "Singing_Flower" + EggItem: "Rocker_Egg" + AccessoryItem: "Rocker_Glasses" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 350 + DefendRate: 350 + ChangeTargetRate: 600 + PetScript: <" petskillbonus(bAllStats, 1, 10, 50); "> + EquipScript: <" + bonus(bHPrecovRate, 5); + bonus(bMaxHP, 25); + "> +}, +{ + Id: 1056 + SpriteName: "SMOKIE" + Name: "Smokie" + TamingItem: "Baked_Yam" + EggItem: "Smokie_Egg" + AccessoryItem: "Red_Muffler" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 600 + DefendRate: 600 + ChangeTargetRate: 100 + PetScript: <" petskillbonus(bPerfectHide, 1, 3600, 0); "> + EquipScript: <" + bonus(bAgi, 1); + bonus(bFlee2, 1); + "> +}, +{ + Id: 1057 + SpriteName: "YOYO" + Name: "Yoyo" + TamingItem: "Tropical_Banana" + EggItem: "Yoyo_Egg" + AccessoryItem: "Monkey_Circlet" + FoodItem: "Banana_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 800 + ChangeTargetRate: 400 + PetScript: <" petloot(20); "> + EquipScript: <" + bonus(bCritical, 3); + bonus(bLuk, -1); + "> +}, +{ + Id: 1063 + SpriteName: "LUNATIC" + Name: "Lunatic" + TamingItem: "Rainbow_Carrot" + EggItem: "Lunatic_Egg" + AccessoryItem: "Silk_Ribbon" + FoodItem: "Carrot_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 1000 + PetScript: <" petskillbonus(bLuk, 3, 10, 50); "> + EquipScript: <" + bonus(bCritical, 2); + bonus(bAtk, 2); + "> +}, +{ + Id: 1077 + SpriteName: "POISON_SPORE" + Name: "Poison Spore" + TamingItem: "Deadly_Noxious_Herb" + EggItem: "Poison_Spore_Egg" + AccessoryItem: "Bark_Shorts" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + AttackRate: 600 + DefendRate: 200 + ChangeTargetRate: 400 + PetScript: <" petskillattack("NPC_POISON", 20, 0, 0, 10); "> + EquipScript: <" + bonus(bStr, 1); + bonus(bInt, 1); + "> +}, +{ + Id: 1101 + SpriteName: "BAPHOMET_" + Name: "Baphomet Jr." + TamingItem: "Book_Of_Devil" + EggItem: "Bapho_Jr_Egg" + AccessoryItem: "Skull_Helm" + FoodItem: "Honey" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 1000 + DefendRate: 100 + ChangeTargetRate: 200 + PetScript: <" petskillattack("NPC_DARKNESSATTACK", 1776, 4, 0, 5); "> + EquipScript: <" + bonus(bDef, 1); + bonus(bMdef, 1); + bonus2(bResEff, Eff_Stun, -100); + "> +}, +{ + Id: 1107 + SpriteName: "DESERT_WOLF_B" + Name: "Baby Desert Wolf" + TamingItem: "Well_Dried_Bone" + EggItem: "Baby_Desert_Wolf_Egg" + AccessoryItem: "Transparent_Headgear" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + AttackRate: 400 + DefendRate: 400 + ChangeTargetRate: 400 + PetScript: <" petskillattack("SM_PROVOKE", 1, 0, 0, 5);"> + EquipScript: <" + bonus(bInt, 1); + bonus(bMaxSP, 50); + "> +}, +{ + Id: 1109 + SpriteName: "DEVIRUCHI" + Name: "Deviruchi" + TamingItem: "Contracts_In_Shadow" + EggItem: "Deviruchi_Egg" + AccessoryItem: "Pacifier" + FoodItem: "Shoot" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 800 + DefendRate: 200 + ChangeTargetRate: 100 + PetScript: <" petskillbonus(bAgiDexStr, 6, 20, 40); "> + EquipScript: <" + bonus(bMatkRate, 1); + bonus(bAtkRate, 1); + bonus(bMaxHPrate, -3); + bonus(bMaxSPrate, -3); + "> +}, +{ + Id: 1110 + SpriteName: "DOKEBI" + Name: "Dokebi" + TamingItem: "Old_Broom" + EggItem: "Dokkaebi_Egg" + AccessoryItem: "Wig" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("BS_HAMMERFALL", 1, 0, 0, 10); "> + EquipScript: <" + bonus(bMatkRate, 1); + bonus(bAtkRate, -1); + "> +}, +{ + Id: 1113 + SpriteName: "DROPS" + Name: "Drops" + TamingItem: "Orange_Juice" + EggItem: "Drops_Egg" + AccessoryItem: "Backpack" + FoodItem: "Yellow_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 400 + ChangeTargetRate: 500 + PetScript: <" petloot(10); "> + EquipScript: <" + bonus(bHit, 3); + bonus(bAtk, 3); + "> +}, +{ + Id: 1155 + SpriteName: "PETIT" + Name: "Petite" + TamingItem: "Shining_Stone" + EggItem: "Green_Petite_Egg" + AccessoryItem: "Stellar_Hairpin" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 800 + DefendRate: 400 + ChangeTargetRate: 100 + PetScript: <" petskillattack("WZ_HEAVENDRIVE", 500, 1, 0, 10); "> + EquipScript: <" + bonus(bDef, -2); + bonus(bMdef, -2); + bonus(bAspdRate, 1); + "> +}, +{ + Id: 1167 + SpriteName: "SAVAGE_BABE" + Name: "Savage Babe" + TamingItem: "Sweet_Milk" + EggItem: "Savage_Bebe_Egg" + AccessoryItem: "Green_Lace" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillbonus(bVit, 4, 10, 50); "> + EquipScript: <" + bonus(bVit, 1); + bonus(bMaxHP, 50); + "> +}, +{ + Id: 1170 + SpriteName: "SOHEE" + Name: "Sohee" + TamingItem: "Silver_Knife_Of_Chaste" + EggItem: "Sohee_Egg" + AccessoryItem: "Golden_Bell" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 100 + DefendRate: 1000 + ChangeTargetRate: 200 + PetScript: <" petskillsupport(AL_HEAL, 10, 60, 33, 100); "> + EquipScript: <" + bonus(bStr, 1); + bonus(bDex, 1); + "> +}, +{ + Id: 1188 + SpriteName: "BON_GUN" + Name: "Bon Gun" + TamingItem: "Heart_Of_Her" + EggItem: "Bongun_Egg" + AccessoryItem: "Sword_Of_Grave_Keeper" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + SpecialPerformance: true + AttackRate: 600 + DefendRate: 200 + ChangeTargetRate: 400 + PetScript: <" petskillattack("NPC_DARKNESSATTACK", 555, 1, 1, 1); "> + EquipScript: <" + bonus(bVit, 1); + bonus2(bResEff, Eff_Stun, 100); + "> +}, +{ + Id: 1200 + SpriteName: "ZHERLTHSH" + Name: "Zealotus" + TamingItem: "Prohibition_Red_Candle" + EggItem: "Zherlthsh_Egg" + FoodItem: "Immortal_Heart" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 300 + Speed: 150 + AttackRate: 1000 + DefendRate: 100 + ChangeTargetRate: 500 + PetScript: <" petskillattack("AS_SONICBLOW", 1, 0, 0, 3); "> + EquipScript: <" + bonus2(bAddRace, RC_DemiPlayer, 2); + bonus2(bMagicAddRace, RC_DemiPlayer, 2); + "> +}, +{ + Id: 1245 + SpriteName: "GOBLINE_XMAS" + Name: "Christmas Goblin" + TamingItem: "Sweet_Candy_Striper" + EggItem: "Santa_Goblin_Egg" + FoodItem: "Scell" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("MG_SIGHT", 5, 0, 5, 5); "> + EquipScript: <" + bonus(bMaxHP, 30); + bonus2(bSubEle, Ele_Water, 1); + "> +}, +{ + Id: 1275 + SpriteName: "ALICE" + Name: "Alice" + TamingItem: "Sway_Apron" + EggItem: "Alice_Egg" + FoodItem: "White_Potion" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 100 + DefendRate: 1000 + ChangeTargetRate: 200 + PetScript: <" petskillsupport("AL_HEAL", 5, 60, 25, 100); "> + EquipScript: <" + bonus(bMdef, 1); + bonus2(bSubRace, RC_DemiPlayer, 1); + "> +}, +// New Pets +{ + Id: 1122 + SpriteName: "GOBLIN_1" + Name: "Goblin" + TamingItem: "Knife_Goblin_Ring" + EggItem: "Knife_Goblin_Egg" + FoodItem: "Green_Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_WINDATTACK", 5, 0, 5, 5); "> + +}, +{ + Id: 1123 + SpriteName: "GOBLIN_2" + Name: "Goblin" + TamingItem: "Flail_Goblin_Ring" + EggItem: "Flail_Goblin_Egg" + FoodItem: "Green_Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_FIREATTACK", 5, 0, 5, 5); "> + +}, +{ + Id: 1125 + SpriteName: "GOBLIN_4" + Name: "Goblin" + TamingItem: "Hammer_Goblin_Ring" + EggItem: "Hammer_Goblin_Egg" + FoodItem: "Green_Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_GROUNDATTACK", 5, 0, 5, 5); "> +}, +{ + Id: 1208 + SpriteName: "WANDER_MAN" + Name: "Wanderer" + TamingItem: "Skull_Of_Vagabond" + EggItem: "Wanderer_Egg" + FoodItem: "Spirit_Liquor" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_UNDEADATTACK", 5, 0, 5, 5); "> +}, +{ + Id: 1382 + SpriteName: "DIABOLIC" + Name: "Diabolic" + TamingItem: "Red_Burning_Stone" + EggItem: "Diabolic_Egg" + FoodItem: "Meat_Veg_Skewer" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("WZ_METEOR", 2, 0, 5, 5); "> +}, +{ + Id: 1385 + SpriteName: "DELETER_" + Name: "Deleter" + TamingItem: "Holy_Marble" + EggItem: "Red_Deleter_Egg" + FoodItem: "Whole_Barbecue" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("SM_MAGNUM", 5, 0, 5, 5); "> +}, +{ + Id: 1879 + SpriteName: "ECLIPSE_P" + Name: "Spring Rabbit" + EggItem: "Spring_Rabbit_Egg" + FoodItem: "Bok_Choy" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("TF_THROWSTONE", 1, 0, 5, 5); "> +}, +// Episode 12 +{ + Id: 1963 + SpriteName: "P_CHUNG_E" + Name: "New Year Doll" + EggItem: "New_Year_Doll_Egg" + FoodItem: "Mojji" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); "> +}, +// Episode 13 +{ + Id: 1815 + SpriteName: "EVENT_RICECAKE" + Name: "Rice Cake" + EggItem: "Rice_Cake_Egg" + FoodItem: "Green_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillsupport("CR_DEFENDER", 3, 240, 50, 100); "> + EquipScript: <" + bonus2(bSubEle, Ele_Neutral, 1); + bonus(bMaxHPrate, -1); + "> +}, +{ + Id: 2210 + SpriteName: "XMAS_LUNATIC" + Name: "Christmas Snow Rabbit" + EggItem: "Snow_Rabbit_Egg" + FoodItem: "Candy" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bExpAddRace, RC_All, 5); "> +}, +// Episode 13.2 +{ + Id: 1040 + SpriteName: "GOLEM" + Name: "Golem" + TamingItem: "Magical_Lithography" + EggItem: "Golem_Egg" + AccessoryItem: "Windup_Spring" + FoodItem: "Mystic_Stone" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bMaxHP, 100); + bonus(bFlee, -5); + "> +}, +{ + Id: 1143 + SpriteName: "MARIONETTE" + Name: "Marionette" + TamingItem: "Delicious_Shaved_Ice" + EggItem: "Marionette_Egg" + AccessoryItem: "Star_Hairband" + FoodItem: "Small_Snow_Flower" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bSPrecovRate, 3); "> +}, +{ + Id: 1148 + SpriteName: "MEDUSA" + Name: "Medusa" + TamingItem: "Splendid_Mirror" + EggItem: "Medusa_Egg" + AccessoryItem: "Queens_Coronet" + FoodItem: "Apple_Pudding" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bVit, 1); + bonus2(bResEff, Eff_Stone, 500); + "> +}, +{ + Id: 1179 + SpriteName: "WHISPER" + Name: "Whisper" + TamingItem: "Fit_Pipe" + EggItem: "Whisper_Egg" + AccessoryItem: "Spirit_Chain_" + FoodItem: "Damp_Darkness" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bFlee, 7); + bonus(bDef, -3); + "> +}, +{ + Id: 1299 + SpriteName: "GOBLIN_LEADER" + Name: "Goblin Leader" + TamingItem: "Staff_Of_Leader" + EggItem: "Goblin_Leader_Egg" + AccessoryItem: "Nice_Badge" + FoodItem: "Big_Cell" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 50 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bAddRace, RC_DemiPlayer, 3); "> +}, +{ + Id: 1370 + SpriteName: "SUCCUBUS" + Name: "Succubus" + TamingItem: "Boys_Naivety" + EggItem: "Succubus_Egg" + AccessoryItem: "Black_Butterfly_Mask" + FoodItem: "Vital_Flower_" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bHPDrainRate, 50, 5); "> +}, +{ + Id: 1374 + SpriteName: "INCUBUS" + Name: "Incubus" + TamingItem: "Grils_Naivety" + EggItem: "Incubus_Egg" + AccessoryItem: "Ball_Mask" + FoodItem: "Vital_Flower" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 50 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bMaxSPrate, 3); "> +}, +{ + Id: 1379 + SpriteName: "NIGHTMARE_TERROR" + Name: "Nightmare Terror" + TamingItem: "Hell_Contract" + EggItem: "Nightmare_Terror_Egg" + AccessoryItem: "Hell_Horn" + FoodItem: "Fresh_Plant" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bResEff, Eff_Sleep, 10000); "> +}, +{ + Id: 1401 + SpriteName: "SHINOBI" + Name: "Shinobi" + TamingItem: "Kuloren" + EggItem: "Shinobi_Egg" + AccessoryItem: "Wine_On_Sleeve" + FoodItem: "Grilled_Rice_Cake" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bAgi, 2); "> +}, +{ + Id: 1404 + SpriteName: "MIYABI_NINGYO" + Name: "Miyabi Doll" + TamingItem: "Gril_Doll" + EggItem: "Miyabi_Ningyo_Egg" + AccessoryItem: "Summer_Fan" + FoodItem: "Well_Ripened_Berry" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 15 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bInt, 1); + bonus(bCastrate, -3); + "> +}, +{ + Id: 1416 + SpriteName: "WICKED_NYMPH" + Name: "Evil Nymph" + TamingItem: "Charming_Lotus" + EggItem: "Wicked_Nymph_Egg" + AccessoryItem: "Jade_Trinket" + FoodItem: "Morning_Dew" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 15 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bMaxSP, 30); + bonus(bSPrecovRate, 5); + "> +}, +{ + Id: 1495 + SpriteName: "STONE_SHOOTER" + Name: "Stone Shooter" + TamingItem: "Oilpalm_Coconut" + EggItem: "Stone_Shooter_Egg" + AccessoryItem: "Apro_Hair" + FoodItem: "Plant_Neutrient" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bSubEle, Ele_Fire, 3); "> +}, +{ + Id: 1504 + SpriteName: "DULLAHAN" + Name: "Dullahan" + TamingItem: "Luxury_Whisky_Bottle" + EggItem: "Dullahan_Egg" + AccessoryItem: "Death_Coil" + FoodItem: "Sunset_On_The_Rock" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bCritAtkRate, 5); "> +}, +{ + Id: 1505 + SpriteName: "LOLI_RURI" + Name: "Loli Ruri" + TamingItem: "Very_Red_Juice" + EggItem: "Loli_Ruri_Egg" + AccessoryItem: "Fashionable_Glasses" + FoodItem: "Pumpkin_Pie_" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 15 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bMaxHPrate, 3); + bonus3(bAutoSpellWhenHit, "AL_HEAL", 1, 50); + "> +}, +{ + Id: 1513 + SpriteName: "CIVIL_SERVANT" + Name: "Mao Guai" + TamingItem: "Fan_Of_Wind" + EggItem: "Civil_Servant_Egg" + AccessoryItem: "Golden_Earing" + FoodItem: "Flavored_Alcohol" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bMaxSP, 10); "> +}, +{ + Id: 1519 + SpriteName: "CHUNG_E" + Name: "Green Maiden" + TamingItem: "Tantanmen" + EggItem: "Chung_E_Egg" + FoodItem: "Bun_" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); "> + EquipScript: <" + bonus(bDef, 1); + bonus2(bSubRace, RC_DemiPlayer, 1); + "> +}, +{ + Id: 1586 + SpriteName: "LEAF_CAT" + Name: "Leaf Cat" + TamingItem: "Very_Soft_Plant" + EggItem: "Leaf_Cat_Egg" + AccessoryItem: "Green_Lucky_Bag" + FoodItem: "Fish_With_Blue_Back" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus2(bSubRace, RC_Brute, 3); + "> +}, +{ + Id: 1630 + SpriteName: "BACSOJIN_" + Name: "White Lady" + TamingItem: "Shiny_Wing_Gown" + EggItem: "Bacsojin_Egg" + AccessoryItem: "Round_Hair_Ornament" + FoodItem: "Traditional_Cookie" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 +}, +{ + Id: 1837 + SpriteName: "IMP" + Name: "Fire Imp" + TamingItem: "Flaming_Ice" + EggItem: "Imp_Egg" + AccessoryItem: "Horn_Protector" + FoodItem: "Flame_Gemstone" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus2(bSubEle, Ele_Fire, 2); + bonus2(bAddEle, Ele_Fire, 2); + "> +}, +// Episode 13.2 Brasilis +{ + Id: 2057 + SpriteName: "E_CRAMP" + Name: "Strange Cramp" + TamingItem: "Leaf_Cat_Ball" + EggItem: "Mystic_Leaf_Cat_Ball" + CaptureRate: 50 + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 +}, +{ + Id: 2081 + SpriteName: "E_HYDRA" + Name: "Strange Hydra" + TamingItem: "Leaf_Cat_Ball" + EggItem: "Mystic_Leaf_Cat_Ball" + CaptureRate: 50 + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 +}, +) diff --git a/db/pre-re/pet_db.txt b/db/pre-re/pet_db.txt deleted file mode 100644 index c0f3a3e91..000000000 --- a/db/pre-re/pet_db.txt +++ /dev/null @@ -1,124 +0,0 @@ -// Pet Database -// -// Structure of Database: -// MobID,Name,JName,LureID,EggID,EquipID,FoodID,Fullness,HungryDelay,R_Hungry,R_Full,Intimate,Die,Capture,Speed,S_Performance,talk_convert_class,attack_rate,defence_attack_rate,change_target_rate,pet_script,loyal_script -// -// 01. MobID Monster ID of the pet. -// 02. Name Name of the monster as defined in the database. -// 03. JName The display name of the monster when hatched. -// 04. LureID Pet Tame Item ID. -// 05. EggID Pet Egg ID. -// 06. EquipID Pet Accessory ID. -// 07. FoodID Pet Food ID. -// 08. Fullness The amount of hunger points increasing with each feeding. -// 09. HungryDelay The amount of time it takes for hunger to decrease after feeding. (Default: 60 seconds) -// 10. R_Hungry Amount of Intimacy that is increased when fed. -// 11. R_Full Amount of Intimacy that is decreased when over-fed. -// 12. Intimate Amount of Intimacy the pet starts with. -// 13. Die Amount of Intimacy that is decreased when the pet owner dies. -// 14. Capture Capture succes rate (10000 = 100%) -// 15. Speed Pet's walk speed. (Defaul: 150) -// 16. S_Performance Special Performance. (Yes = 1, No = 0) -// 17. talk_convert_class Disables pet talk (instead of talking they emote with /!.) -// 18. attack_rate Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy). -// 19. defence_attack_rate Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy). -// 20. change_target_rate Rate of which the pet will change its attack target. -// 21. pet_script Script to execute when the pet is hatched. -// 22. loyal_script Script to execute when the pet is hatched (requires at least pet_equip_min_friendly intimacy, independent of pet_script). -// NOTE: The max value (100%) of attack_rate, defense_rate & change_target_rate is 10000. - -// In theory you can use any valid script, but it is run only once upon pet -// loading, so it is recommended you use the specific pet scripts: - -// petskillattack skillid, skilllv, hits, rate, bonusrate Skill attack that -// triggers while the pet is attacking. Rate is the base chance of execution -// per attack. Bonusrate is an additional success rate when intimacy reaches -// max. If hits is specified and different than 0, it will make the pet cast -// the skill with a fixed amount of damage inflicted and the specified number -// of hits. A value of zero uses the skill's defaults. - -// petskillsupport skillid, skilllv, delay, hp%, sp% Casts a support skill when -// the health levels are below the specified hp% and sp%. Delay is the minimum -// time in seconds before the skill can be cast again - -// petrecovery type, delay: Cures the "type" status effect after "delay" -// seconds - -// petskillbonus type, value, duration, delay Gives bonus stats. Type is the -// stat to increase (bStr, bLuk), value is the amount by which it is increased, -// duration signals how long the bonus lasts delay is the time elapsed after -// the bonus ends and before it starts again. - -// A single pet can have petloot, petskillbonus, petskillattack and -// petskillsupport at the same time, but only one of each. - -// Core -1002,PORING,Poring,619,9001,10013,531,80,60,50,100,250,20,2000,150,1,0,350,400,800,{ petloot 10; },{ bonus bLuk,2; bonus bCritical,1; } -1011,CHONCHON,ChonChon,624,9006,10002,537,80,60,30,100,250,20,1500,150,1,0,500,500,250,{ petskillbonus bAgi,4,10,50; },{ bonus bAgi,1; bonus bFlee,2; } -1014,SPORE,Spore,630,9012,10017,537,80,60,30,100,250,20,1500,150,0,0,350,500,500,{ petrecovery SC_POISON,60; },{ bonus bHit,5; bonus bAtk,-2; } -1019,PECOPECO,PecoPeco,632,9014,10010,537,80,60,30,100,250,20,1000,150,1,0,400,500,800,{ petskillbonus bSpeedRate,25,20,20; },{ bonus bMaxHP,150; bonus bMaxSP,-10; } -1023,ORK_WARRIOR,Orc Warrior,635,9017,10009,537,80,60,20,100,250,20,500,150,1,0,600,200,300,{ petskillattack "NPC_PIERCINGATT",100,1,0,10; },{ bonus bAtk,10; bonus bDef,-3; } -1026,MUNAK,Munak,636,9018,10008,537,80,60,20,100,250,20,500,150,0,0,300,750,300,{ petskillattack "NPC_DARKNESSATTACK",444,1,0,10; },{ bonus bInt,1; bonus bDef,1; } -1029,ISIS,Isis,639,9021,10006,537,80,60,10,100,250,20,500,150,0,0,650,450,150,{ petskillsupport "PR_MAGNIFICAT",2,60,50,50; },{ bonus bMatkRate,-1; bonus bAtkRate,1; } -1031,POPORING,Poporing,621,9003,10013,511,80,60,30,100,250,20,1000,150,1,0,300,500,400,{ petloot 15; },{ bonus bLuk,2; bonus2 bSubEle,Ele_Poison,10; } -1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,60,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack "NPC_WINDATTACK",888,2,0,10; },{ bonus bFlee,-5; bonus bFlee2,2; } -1042,STEEL_CHONCHON,Steel ChonChon,625,9007,10002,1002,80,60,20,100,250,20,1000,150,1,0,500,500,200,{ petskillbonus bAgiVit,4,20,40; },{ bonus bFlee,6; bonus bAgi,-1; } -1049,PICKY,Picky,623,9005,10012,507,80,60,40,100,250,20,2000,150,1,0,500,600,50,{ petskillbonus bStr,3,10,50;},{ bonus bStr,1; bonus bAtk,5; } -1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,150,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50; },{ bonus bHPrecovRate,5; bonus bMaxHP,25; } -1056,SMOKIE,Smokie,633,9015,10019,537,80,60,30,100,250,20,1000,150,1,0,600,600,100,{ petskillbonus bPerfectHide,1,3600,0; },{ bonus bAgi,1; bonus bFlee2,1; } -1057,YOYO,Yoyo,634,9016,10018,532,80,60,20,100,250,20,1000,150,1,0,300,800,400,{ petloot 20; },{ bonus bCritical,3; bonus bLuk,-1; } -1063,LUNATIC,Lunatic,622,9004,10007,534,80,60,40,100,250,20,1500,150,0,0,300,300,1000,{ petskillbonus bLuk,3,10,50; },{ bonus bCritical,2; bonus bAtk,2; } -1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,60,20,100,250,20,1000,150,0,0,600,200,400,{ petskillattack "NPC_POISON",20,0,0,10; },{ bonus bStr,1; bonus bInt,1; } -1101,BAPHOMET_,Baphomet Jr.,642,9024,10001,518,80,60,10,100,250,20,200,150,0,0,1000,100,200,{ petskillattack "NPC_DARKNESSATTACK",1776,4,0,5; },{ bonus bDef,1; bonus bMdef,1; bonus2 bResEff,Eff_Stun,-100; } -1107,DESERT_WOLF_B,Baby Desert Wolf,628,9010,10003,537,80,60,40,100,250,20,1000,150,0,0,400,400,400,{ petskillattack "SM_PROVOKE",1,0,0,5;},{ bonus bInt,1; bonus bMaxSP,50; } -1109,DEVIRUCHI,Deviruchi,641,9023,10004,711,80,60,10,100,250,20,500,150,0,0,800,200,100,{ petskillbonus bAgiDexStr,6,20,40; },{ bonus bMatkRate,1; bonus bAtkRate,1; bonus bMaxHPrate,-3; bonus bMaxSPrate,-3; } -1110,DOKEBI,Dokebi,637,9019,10005,537,80,60,20,100,250,20,500,150,0,0,300,300,800,{ petskillattack "BS_HAMMERFALL",1,0,0,10; },{ bonus bMatkRate,1; bonus bAtkRate,-1; } -1113,DROPS,Drops,620,9002,10013,508,80,60,40,100,250,20,1500,150,1,0,300,400,500,{ petloot 10; },{ bonus bHit,3; bonus bAtk,3; } -1155,PETIT,Petite,640,9022,10011,537,80,60,20,100,250,20,500,150,0,0,800,400,100,{ petskillattack "WZ_HEAVENDRIVE",500,1,0,10; },{ bonus bDef,-2; bonus bMdef,-2; bonus bAspdRate,1; } -1167,SAVAGE_BABE,Savage Babe,627,9009,10015,537,80,60,40,100,250,20,1500,150,0,0,500,500,200,{ petskillbonus bVit,4,10,50; },{ bonus bVit,1; bonus bMaxHP,50; } -1170,SOHEE,Sohee,638,9020,10016,537,80,60,10,100,250,20,500,150,0,0,100,1000,200,{ petskillsupport AL_HEAL,10,60,33,100; },{ bonus bStr,1; bonus bDex,1; } -1188,BON_GUN,Bon Gun,659,9025,10020,537,80,60,30,100,250,20,500,150,1,0,600,200,400,{ petskillattack "NPC_DARKNESSATTACK",555,1,1,1; },{ bonus bVit,1; bonus2 bResEff,Eff_Stun,100; } -1200,ZHERLTHSH,Zealotus,660,9026,0,929,80,60,10,100,250,20,300,150,0,0,1000,100,500,{ petskillattack "AS_SONICBLOW",1,0,0,3; },{ bonus2 bAddRace,RC_DemiPlayer,2; bonus2 bMagicAddRace,RC_DemiPlayer,2; } -1245,GOBLINE_XMAS,Christmas Goblin,12225,9029,0,911,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "MG_SIGHT",5,0,5,5; },{ bonus bMaxHP,30; bonus2 bSubEle,Ele_Water,1; } -1275,ALICE,Alice,661,9027,0,504,80,60,20,100,250,20,800,150,0,0,100,1000,200,{ petskillsupport "AL_HEAL",5,60,25,100; },{ bonus bMdef,1; bonus2 bSubRace,RC_DemiPlayer,1; } - -// New Pets -1122,GOBLIN_1,Goblin,14569,9032,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_WINDATTACK",5,0,5,5; },{} -1123,GOBLIN_2,Goblin,14570,9033,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_FIREATTACK",5,0,5,5; },{} -1125,GOBLIN_4,Goblin,14571,9034,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_GROUNDATTACK",5,0,5,5; },{} -1208,WANDER_MAN,Wanderer,14574,9037,0,7824,80,60,20,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_UNDEADATTACK",5,0,5,5; },{} -1382,DIABOLIC,Diabolic,14573,9036,0,7823,80,60,10,100,250,20,800,150,0,0,300,300,800,{ petskillattack "WZ_METEOR",2,0,5,5; },{} -1385,DELETER_,Deleter,14572,9035,0,7822,80,60,20,100,250,20,800,150,0,0,300,300,800,{ petskillattack "SM_MAGNUM",5,0,5,5; },{} -1879,ECLIPSE_P,Spring Rabbit,0,9031,0,7766,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "TF_THROWSTONE",1,0,5,5; },{} - -// Episode 12 -1963,P_CHUNG_E,New Year Doll,0,9038,0,554,80,60,30,100,250,20,800,150,0,0,300,300,800,{ petskillattack "CR_SHIELDCHARGE",5,0,5,5; },{} - -// Episode 13 -1815,EVENT_RICECAKE,Rice Cake,0,9028,0,511,80,60,50,100,250,20,2000,150,1,0,500,500,200,{ petskillsupport "CR_DEFENDER",3,240,50,100; },{ bonus2 bSubEle,Ele_Neutral,1; bonus bMaxHPrate,-1; } -2210,XMAS_LUNATIC,Christmas Snow Rabbit,0,9058,0,529,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{ bonus2 bExpAddRace,RC_All,5; } - -// Episode 13.2 -1040,GOLEM,Golem,12371,9053,10035,6111,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxHP,100; bonus bFlee,-5; } -1143,MARIONETTE,Marionette,12361,9043,10025,6098,80,60,10,100,250,20,500,150,0,0,300,300,800,{},{ bonus bSPrecovRate,3; } -1148,MEDUSA,Medusa,12368,9050,10032,6108,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus bVit,1; bonus2 bResEff,Eff_Stone,500; } -1179,WHISPER,Whisper,12363,9045,10027,6100,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bFlee,7; bonus bDef,-3; } -1299,GOBLIN_LEADER,Goblin Leader,12364,9046,10028,6104,80,60,10,100,250,20,50,150,0,0,300,300,800,{},{ bonus2 bAddRace,RC_DemiPlayer,3; } -1370,SUCCUBUS,Succubus,12373,9055,10037,6113,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bHPDrainRate,50,5; } -1374,INCUBUS,Incubus,12370,9052,10034,6110,80,60,10,100,250,20,50,150,0,0,300,300,800,{},{ bonus bMaxSPrate,3; } -1379,NIGHTMARE_TERROR,Nightmare Terror,12372,9054,10036,6112,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bResEff,Eff_Sleep,10000; } -1401,SHINOBI,Shinobi,12362,9044,10026,6099,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bAgi,2; } -1404,MIYABI_NINGYO,Miyabi Doll,12366,9048,10030,6106,80,60,15,100,250,20,200,150,0,0,300,300,800,{},{ bonus bInt,1; bonus bCastrate,-3; } -1416,WICKED_NYMPH,Evil Nymph,12365,9047,10029,6105,80,60,15,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxSP,30; bonus bSPrecovRate,5; } -1495,STONE_SHOOTER,Stone Shooter,12369,9051,10033,6109,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus2 bSubEle,Ele_Fire,3; } -1504,DULLAHAN,Dullahan,12367,9049,10031,6107,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus bCritAtkRate,5; } -1505,LOLI_RURI,Loli Ruri,12360,9042,10024,6097,80,60,15,100,250,20,200,150,0,0,300,300,800,{},{ bonus bMaxHPrate,3; bonus3 bAutoSpellWhenHit,"AL_HEAL",1,50; } -1513,CIVIL_SERVANT,Mao Guai,12358,9040,10022,6095,80,60,10,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxSP,10; } -1519,CHUNG_E,Green Maiden,12395,9030,0,6115,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "CR_SHIELDCHARGE",5,0,5,5; },{ bonus bDef,1; bonus2 bSubRace,RC_DemiPlayer,1; } -1586,LEAF_CAT,Leaf Cat,12359,9041,10023,6096,80,60,20,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bSubRace,RC_Brute,3; } -1630,BACSOJIN_,White Lady,12357,9039,10021,6094,80,60,10,100,250,20,2000,150,0,0,300,300,800,{},{} -1837,IMP,Fire Imp,12374,9056,10038,6114,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bSubEle,Ele_Fire,2; bonus2 bAddEle,Ele_Fire,2; } - -// Episode 13.2 Brasilis -2057,E_CRAMP,Strange Cramp,12408,6221,0,0,0,0,0,0,0,0,50,0,0,0,350,400,800,{},{} // kRO version -2081,E_HYDRA,Strange Hydra,12408,6221,0,0,0,0,0,0,0,0,50,0,0,0,350,400,800,{},{} // iRO/cRO version diff --git a/db/re/item_db.conf b/db/re/item_db.conf index 80baad89f..6c4e820e8 100644 --- a/db/re/item_db.conf +++ b/db/re/item_db.conf @@ -144605,8 +144605,8 @@ item_db: ( Type: "IT_ARMOR" Loc: "EQP_COSTUME_HEAD_LOW" ViewSprite: 1331 - OnEquipScript: <" sc_start SC_BLOSSOM_FLUTTERING, -1, 0; "> - OnUnequipScript: <" sc_end SC_BLOSSOM_FLUTTERING; "> + OnEquipScript: <" hateffect(HAT_EF_BLOSSOM_FLUTTERING, true); "> + OnUnequipScript: <" hateffect(HAT_EF_BLOSSOM_FLUTTERING, false); "> }, { Id: 20286 diff --git a/db/re/pet_db.conf b/db/re/pet_db.conf new file mode 100644 index 000000000..6d6083e59 --- /dev/null +++ b/db/re/pet_db.conf @@ -0,0 +1,1649 @@ +//================= Hercules Database ===================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License =============================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2018 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/>. +//========================================================================= +//= Pets Database +//========================================================================= + +pet_db:( +/************************************************************************** + ************* Entry structure ******************************************** + ************************************************************************** +{ + // ================ Mandatory fields ============================== + Id: ID (int) + SpriteName: "Sprite_Name" (string) + Name: "Pet Name" (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) + 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) + } + CaptureRate: capture rate (int, defaults to 0) + Speed: speed (int, defaults to 0) + 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) + PetScript: <" Pet Script (can also be multi-line) "> + EquipScript: <" Equip Script (can also be multi-line) "> +}, +**************************************************************************/ +{ + Id: 1002 + SpriteName: "PORING" + Name: "Poring" + TamingItem: "Unripe_Apple" + EggItem: "Poring_Egg" + AccessoryItem: "Backpack" + FoodItem: "Apple_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 + PetScript: <" petloot(10); "> + EquipScript: <" + bonus(bLuk, 2); + bonus(bCritical, 1); + "> +}, +{ + Id: 1011 + SpriteName: "CHONCHON" + Name: "ChonChon" + TamingItem: "Rotten_Fish" + EggItem: "Chonchon_Egg" + AccessoryItem: "Monster_Oxygen_Mask" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 250 + PetScript: <" petskillbonus(bAgi, 4, 10, 50); "> + EquipScript: <" + bonus(bAgi, 1); + bonus(bFlee, 2); + "> +}, +{ + Id: 1014 + SpriteName: "SPORE" + Name: "Spore" + TamingItem: "Dew_Laden_Moss" + EggItem: "Spore_Egg" + AccessoryItem: "Bark_Shorts" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 350 + DefendRate: 500 + ChangeTargetRate: 500 + PetScript: <" petrecovery(SC_POISON, 60); "> + EquipScript: <" + bonus(bHit, 5); + bonus(bAtk, -2); + "> +}, +{ + Id: 1019 + SpriteName: "PECOPECO" + Name: "PecoPeco" + TamingItem: "Fatty_Chubby_Earthworm" + EggItem: "PecoPeco_Egg" + AccessoryItem: "Battered_Pot" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 400 + DefendRate: 500 + ChangeTargetRate: 800 + PetScript: <" petskillbonus(bSpeedRate, 25, 20, 20); "> + EquipScript: <" + bonus(bMaxHP, 150); + bonus(bMaxSP, -10); + "> +}, +{ + Id: 1023 + SpriteName: "ORK_WARRIOR" + Name: "Orc Warrior" + TamingItem: "Horror_Of_Tribe" + EggItem: "Orc_Warrior_Egg" + AccessoryItem: "Wild_Flower" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + SpecialPerformance: true + AttackRate: 600 + DefendRate: 200 + ChangeTargetRate: 300 + PetScript: <" petskillattack("NPC_PIERCINGATT", 100, 1, 0, 10); "> + EquipScript: <" + bonus(bAtk, 10); + bonus(bDef, -3); + "> +}, +{ + Id: 1026 + SpriteName: "MUNAK" + Name: "Munak" + TamingItem: "No_Recipient" + EggItem: "Munak_Egg" + AccessoryItem: "Punisher" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 750 + ChangeTargetRate: 300 + PetScript: <" petskillattack("NPC_DARKNESSATTACK", 444, 1, 0, 10); "> + EquipScript: <" + bonus(bInt, 1); + bonus(bDef, 1); + "> +}, +{ + Id: 1029 + SpriteName: "ISIS" + Name: "Isis" + TamingItem: "Armlet_Of_Obedience" + EggItem: "Isis_Egg" + AccessoryItem: "Queens_Hair_Ornament" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 650 + DefendRate: 450 + ChangeTargetRate: 150 + PetScript: <" petskillsupport("PR_MAGNIFICAT", 2, 60, 50, 50); "> + EquipScript: <" + bonus(bMatkRate, -1); + bonus(bAtkRate, 1); + "> +}, +{ + Id: 1031 + SpriteName: "POPORING" + Name: "Poporing" + TamingItem: "Bitter_Herb" + EggItem: "Poporing_Egg" + AccessoryItem: "Backpack" + FoodItem: "Green_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 500 + ChangeTargetRate: 400 + PetScript: <" petloot(15); "> + EquipScript: <" + bonus(bLuk, 2); + bonus2(bSubEle, Ele_Poison, 10); + "> +}, +{ + Id: 1035 + SpriteName: "HUNTER_FLY" + Name: "Hunter Fly" + TamingItem: "Monster_Juice" + EggItem: "Hunter_Fly_Egg" + AccessoryItem: "Monster_Oxygen_Mask" + FoodItem: "Red_Gemstone" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillattack("NPC_WINDATTACK", 888, 2, 0, 10); "> + EquipScript: <" + bonus(bFlee, -5); + bonus(bFlee2, 2); + "> +}, +{ + Id: 1042 + SpriteName: "STEEL_CHONCHON" + Name: "Steel ChonChon" + TamingItem: "Lusty_Iron" + EggItem: "Steel_Chonchon_Egg" + AccessoryItem: "Monster_Oxygen_Mask" + FoodItem: "Iron_Ore" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillbonus(bAgiVit, 4, 20, 40); "> + EquipScript: <" + bonus(bFlee, 6); + bonus(bAgi, -1); + "> +}, +{ + Id: 1049 + SpriteName: "PICKY" + Name: "Picky" + TamingItem: "Earthworm_The_Dude" + EggItem: "Picky_Egg" + AccessoryItem: "Tiny_Egg_Shell" + FoodItem: "Red_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 600 + ChangeTargetRate: 50 + PetScript: <" petskillbonus(bStr, 3, 10, 50); "> + EquipScript: <" + bonus(bStr, 1); + bonus(bAtk, 5); + "> +}, +{ + Id: 1052 + SpriteName: "ROCKER" + Name: "Rocker" + TamingItem: "Singing_Flower" + EggItem: "Rocker_Egg" + AccessoryItem: "Rocker_Glasses" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 350 + DefendRate: 350 + ChangeTargetRate: 600 + PetScript: <" petskillbonus(bAllStats, 1, 10, 50); "> + EquipScript: <" + bonus(bHPrecovRate, 5); + bonus(bMaxHP, 25); + "> +}, +{ + Id: 1056 + SpriteName: "SMOKIE" + Name: "Smokie" + TamingItem: "Baked_Yam" + EggItem: "Smokie_Egg" + AccessoryItem: "Red_Muffler" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 600 + DefendRate: 600 + ChangeTargetRate: 100 + PetScript: <" petskillbonus(bPerfectHide, 1, 3600, 0); "> + EquipScript: <" + bonus(bAgi, 1); + bonus(bFlee2, 1); + "> +}, +{ + Id: 1057 + SpriteName: "YOYO" + Name: "Yoyo" + TamingItem: "Tropical_Banana" + EggItem: "Yoyo_Egg" + AccessoryItem: "Monkey_Circlet" + FoodItem: "Banana_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 800 + ChangeTargetRate: 400 + PetScript: <" petloot(20); "> + EquipScript: <" + bonus(bCritical, 3); + bonus(bLuk, -1); + "> +}, +{ + Id: 1063 + SpriteName: "LUNATIC" + Name: "Lunatic" + TamingItem: "Rainbow_Carrot" + EggItem: "Lunatic_Egg" + AccessoryItem: "Silk_Ribbon" + FoodItem: "Carrot_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 1000 + PetScript: <" petskillbonus(bLuk, 3, 10, 50); "> + EquipScript: <" + bonus(bCritical, 2); + bonus(bAtk, 2); + "> +}, +{ + Id: 1077 + SpriteName: "POISON_SPORE" + Name: "Poison Spore" + TamingItem: "Deadly_Noxious_Herb" + EggItem: "Poison_Spore_Egg" + AccessoryItem: "Bark_Shorts" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + AttackRate: 600 + DefendRate: 200 + ChangeTargetRate: 400 + PetScript: <" petskillattack("NPC_POISON", 20, 0, 0, 10); "> + EquipScript: <" + bonus(bStr, 1); + bonus(bInt, 1); + "> +}, +{ + Id: 1101 + SpriteName: "BAPHOMET_" + Name: "Baphomet Jr." + TamingItem: "Book_Of_Devil" + EggItem: "Bapho_Jr_Egg" + AccessoryItem: "Skull_Helm" + FoodItem: "Honey" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 1000 + DefendRate: 100 + ChangeTargetRate: 200 + PetScript: <" petskillattack("NPC_DARKNESSATTACK", 1776, 4, 0, 5); "> + EquipScript: <" + bonus(bDef, 1); + bonus(bMdef, 1); + bonus2(bResEff, Eff_Stun, -100); + "> +}, +{ + Id: 1107 + SpriteName: "DESERT_WOLF_B" + Name: "Baby Desert Wolf" + TamingItem: "Well_Dried_Bone" + EggItem: "Baby_Desert_Wolf_Egg" + AccessoryItem: "Transparent_Headgear" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + AttackRate: 400 + DefendRate: 400 + ChangeTargetRate: 400 + PetScript: <" petskillattack("SM_PROVOKE", 1, 0, 0, 5);"> + EquipScript: <" + bonus(bInt, 1); + bonus(bMaxSP, 50); + "> +}, +{ + Id: 1109 + SpriteName: "DEVIRUCHI" + Name: "Deviruchi" + TamingItem: "Contracts_In_Shadow" + EggItem: "Deviruchi_Egg" + AccessoryItem: "Pacifier" + FoodItem: "Shoot" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 800 + DefendRate: 200 + ChangeTargetRate: 100 + PetScript: <" petskillbonus(bAgiDexStr, 6, 20, 40); "> + EquipScript: <" + bonus(bMatkRate, 1); + bonus(bAtkRate, 1); + bonus(bMaxHPrate, -3); + bonus(bMaxSPrate, -3); + "> +}, +{ + Id: 1110 + SpriteName: "DOKEBI" + Name: "Dokebi" + TamingItem: "Old_Broom" + EggItem: "Dokkaebi_Egg" + AccessoryItem: "Wig" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("BS_HAMMERFALL", 1, 0, 0, 10); "> + EquipScript: <" + bonus(bMatkRate, 1); + bonus(bAtkRate, -1); + "> +}, +{ + Id: 1113 + SpriteName: "DROPS" + Name: "Drops" + TamingItem: "Orange_Juice" + EggItem: "Drops_Egg" + AccessoryItem: "Backpack" + FoodItem: "Yellow_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 400 + ChangeTargetRate: 500 + PetScript: <" petloot(10); "> + EquipScript: <" + bonus(bHit, 3); + bonus(bAtk, 3); + "> +}, +{ + Id: 1155 + SpriteName: "PETIT" + Name: "Petite" + TamingItem: "Shining_Stone" + EggItem: "Green_Petite_Egg" + AccessoryItem: "Stellar_Hairpin" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 800 + DefendRate: 400 + ChangeTargetRate: 100 + PetScript: <" petskillattack("WZ_HEAVENDRIVE", 500, 1, 0, 10); "> + EquipScript: <" + bonus(bDef, -2); + bonus(bMdef, -2); + bonus(bAspdRate, 1); + "> +}, +{ + Id: 1167 + SpriteName: "SAVAGE_BABE" + Name: "Savage Babe" + TamingItem: "Sweet_Milk" + EggItem: "Savage_Bebe_Egg" + AccessoryItem: "Green_Lace" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 40 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1500 + Speed: 150 + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillbonus(bVit, 4, 10, 50); "> + EquipScript: <" + bonus(bVit, 1); + bonus(bMaxHP, 50); + "> +}, +{ + Id: 1170 + SpriteName: "SOHEE" + Name: "Sohee" + TamingItem: "Silver_Knife_Of_Chaste" + EggItem: "Sohee_Egg" + AccessoryItem: "Golden_Bell" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 100 + DefendRate: 1000 + ChangeTargetRate: 200 + PetScript: <" petskillsupport(AL_HEAL, 10, 60, 33, 100); "> + EquipScript: <" + bonus(bStr, 1); + bonus(bDex, 1); + "> +}, +{ + Id: 1188 + SpriteName: "BON_GUN" + Name: "Bon Gun" + TamingItem: "Heart_Of_Her" + EggItem: "Bongun_Egg" + AccessoryItem: "Sword_Of_Grave_Keeper" + FoodItem: "Pet_Food" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + SpecialPerformance: true + AttackRate: 600 + DefendRate: 200 + ChangeTargetRate: 400 + PetScript: <" petskillattack("NPC_DARKNESSATTACK", 555, 1, 1, 1); "> + EquipScript: <" + bonus(bVit, 1); + bonus2(bResEff, Eff_Stun, 100); + "> +}, +{ + Id: 1200 + SpriteName: "ZHERLTHSH" + Name: "Zealotus" + TamingItem: "Prohibition_Red_Candle" + EggItem: "Zherlthsh_Egg" + FoodItem: "Immortal_Heart" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 300 + Speed: 150 + AttackRate: 1000 + DefendRate: 100 + ChangeTargetRate: 500 + PetScript: <" petskillattack("AS_SONICBLOW", 1, 0, 0, 3); "> + EquipScript: <" + bonus2(bAddRace, RC_DemiPlayer, 2); + bonus2(bMagicAddRace, RC_DemiPlayer, 2); + "> +}, +{ + Id: 1245 + SpriteName: "GOBLINE_XMAS" + Name: "Christmas Goblin" + TamingItem: "Sweet_Candy_Striper" + EggItem: "Santa_Goblin_Egg" + FoodItem: "Scell" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("MG_SIGHT", 5, 0, 5, 5); "> + EquipScript: <" + bonus(bMaxHP, 30); + bonus2(bSubEle, Ele_Water, 1); + "> +}, +{ + Id: 1275 + SpriteName: "ALICE" + Name: "Alice" + TamingItem: "Sway_Apron" + EggItem: "Alice_Egg" + FoodItem: "White_Potion" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 100 + DefendRate: 1000 + ChangeTargetRate: 200 + PetScript: <" petskillsupport("AL_HEAL", 5, 60, 25, 100); "> + EquipScript: <" + bonus(bMdef, 1); + bonus2(bAddRaceTolerance, RC_DemiPlayer, 1); + "> +}, +// New Pets +{ + Id: 1122 + SpriteName: "GOBLIN_1" + Name: "Goblin" + TamingItem: "Knife_Goblin_Ring" + EggItem: "Knife_Goblin_Egg" + FoodItem: "Green_Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_WINDATTACK", 5, 0, 5, 5); "> +}, +{ + Id: 1123 + SpriteName: "GOBLIN_2" + Name: "Goblin" + TamingItem: "Flail_Goblin_Ring" + EggItem: "Flail_Goblin_Egg" + FoodItem: "Green_Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_FIREATTACK", 5, 0, 5, 5); "> +}, +{ + Id: 1125 + SpriteName: "GOBLIN_4" + Name: "Goblin" + TamingItem: "Hammer_Goblin_Ring" + EggItem: "Hammer_Goblin_Egg" + FoodItem: "Green_Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_GROUNDATTACK", 5, 0, 5, 5); "> +}, +{ + Id: 1208 + SpriteName: "WANDER_MAN" + Name: "Wanderer" + TamingItem: "Skull_Of_Vagabond" + EggItem: "Wanderer_Egg" + FoodItem: "Spirit_Liquor" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("NPC_UNDEADATTACK", 5, 0, 5, 5); "> +}, +{ + Id: 1382 + SpriteName: "DIABOLIC" + Name: "Diabolic" + TamingItem: "Red_Burning_Stone" + EggItem: "Diabolic_Egg" + FoodItem: "Meat_Veg_Skewer" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("WZ_METEOR", 2, 0, 5, 5); "> +}, +{ + Id: 1385 + SpriteName: "DELETER_" + Name: "Deleter" + TamingItem: "Holy_Marble" + EggItem: "Red_Deleter_Egg" + FoodItem: "Whole_Barbecue" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("SM_MAGNUM", 5, 0, 5, 5); "> +}, +{ + Id: 1879 + SpriteName: "ECLIPSE_P" + Name: "Spring Rabbit" + EggItem: "Spring_Rabbit_Egg" + FoodItem: "Bok_Choy" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("TF_THROWSTONE", 1, 0, 5, 5); "> +}, +// Episode 12 +{ + Id: 1963 + SpriteName: "P_CHUNG_E" + Name: "New Year Doll" + EggItem: "New_Year_Doll_Egg" + FoodItem: "Mojji" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 30 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 800 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); "> +}, +// Episode 13 +{ + Id: 1815 + SpriteName: "EVENT_RICECAKE" + Name: "Rice Cake" + EggItem: "Rice_Cake_Egg" + FoodItem: "Green_Herb" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 500 + DefendRate: 500 + ChangeTargetRate: 200 + PetScript: <" petskillsupport("CR_DEFENDER", 3, 240, 50, 100); "> + EquipScript: <" + bonus2(bSubEle, Ele_Neutral, 1); + bonus(bMaxHPrate, -1); + "> +}, +{ + Id: 2210 + SpriteName: "XMAS_LUNATIC" + Name: "Christmas Snow Rabbit" + EggItem: "Snow_Rabbit_Egg" + FoodItem: "Candy" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bExpAddRace, RC_All, 5); "> +}, +// Episode 13.2 +{ + Id: 1040 + SpriteName: "GOLEM" + Name: "Golem" + TamingItem: "Magical_Lithography" + EggItem: "Golem_Egg" + AccessoryItem: "Windup_Spring" + FoodItem: "Mystic_Stone" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bMaxHP, 100); + bonus(bFlee, -5); + "> +}, +{ + Id: 1143 + SpriteName: "MARIONETTE" + Name: "Marionette" + TamingItem: "Delicious_Shaved_Ice" + EggItem: "Marionette_Egg" + AccessoryItem: "Star_Hairband" + FoodItem: "Small_Snow_Flower" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bSPrecovRate, 3); "> +}, +{ + Id: 1148 + SpriteName: "MEDUSA" + Name: "Medusa" + TamingItem: "Splendid_Mirror" + EggItem: "Medusa_Egg" + AccessoryItem: "Queens_Coronet" + FoodItem: "Apple_Pudding" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bVit, 1); + bonus2(bResEff, Eff_Stone, 500); + "> +}, +{ + Id: 1179 + SpriteName: "WHISPER" + Name: "Whisper" + TamingItem: "Fit_Pipe" + EggItem: "Whisper_Egg" + AccessoryItem: "Spirit_Chain_" + FoodItem: "Damp_Darkness" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bFlee, 7); + bonus(bDef, -3); + "> +}, +{ + Id: 1299 + SpriteName: "GOBLIN_LEADER" + Name: "Goblin Leader" + TamingItem: "Staff_Of_Leader" + EggItem: "Goblin_Leader_Egg" + AccessoryItem: "Nice_Badge" + FoodItem: "Big_Cell" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 50 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bAddRace, RC_DemiPlayer, 3); "> +}, +{ + Id: 1370 + SpriteName: "SUCCUBUS" + Name: "Succubus" + TamingItem: "Boys_Naivety" + EggItem: "Succubus_Egg" + AccessoryItem: "Black_Butterfly_Mask" + FoodItem: "Vital_Flower_" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bHPDrainRate, 50, 5); "> +}, +{ + Id: 1374 + SpriteName: "INCUBUS" + Name: "Incubus" + TamingItem: "Grils_Naivety" + EggItem: "Incubus_Egg" + AccessoryItem: "Ball_Mask" + FoodItem: "Vital_Flower" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 50 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bMaxSPrate, 3); "> +}, +{ + Id: 1379 + SpriteName: "NIGHTMARE_TERROR" + Name: "Nightmare Terror" + TamingItem: "Hell_Contract" + EggItem: "Nightmare_Terror_Egg" + AccessoryItem: "Hell_Horn" + FoodItem: "Fresh_Plant" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bResEff, Eff_Sleep, 10000); "> +}, +{ + Id: 1401 + SpriteName: "SHINOBI" + Name: "Shinobi" + TamingItem: "Kuloren" + EggItem: "Shinobi_Egg" + AccessoryItem: "Wine_On_Sleeve" + FoodItem: "Grilled_Rice_Cake" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bAgi, 2); "> +}, +{ + Id: 1404 + SpriteName: "MIYABI_NINGYO" + Name: "Miyabi Doll" + TamingItem: "Gril_Doll" + EggItem: "Miyabi_Ningyo_Egg" + AccessoryItem: "Summer_Fan" + FoodItem: "Well_Ripened_Berry" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 15 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bInt, 1); + bonus(bCastrate, -3); + "> +}, +{ + Id: 1416 + SpriteName: "WICKED_NYMPH" + Name: "Evil Nymph" + TamingItem: "Charming_Lotus" + EggItem: "Wicked_Nymph_Egg" + AccessoryItem: "Jade_Trinket" + FoodItem: "Morning_Dew" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 15 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bMaxSP, 30); + bonus(bSPrecovRate, 5); + "> +}, +{ + Id: 1495 + SpriteName: "STONE_SHOOTER" + Name: "Stone Shooter" + TamingItem: "Oilpalm_Coconut" + EggItem: "Stone_Shooter_Egg" + AccessoryItem: "Apro_Hair" + FoodItem: "Plant_Neutrient" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus2(bSubEle, Ele_Fire, 3); "> +}, +{ + Id: 1504 + SpriteName: "DULLAHAN" + Name: "Dullahan" + TamingItem: "Luxury_Whisky_Bottle" + EggItem: "Dullahan_Egg" + AccessoryItem: "Death_Coil" + FoodItem: "Sunset_On_The_Rock" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bCritAtkRate, 5); "> +}, +{ + Id: 1505 + SpriteName: "LOLI_RURI" + Name: "Loli Ruri" + TamingItem: "Very_Red_Juice" + EggItem: "Loli_Ruri_Egg" + AccessoryItem: "Fashionable_Glasses" + FoodItem: "Pumpkin_Pie_" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 15 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus(bMaxHPrate, 3); + bonus3(bAutoSpellWhenHit, "AL_HEAL", 1, 50); + "> +}, +{ + Id: 1513 + SpriteName: "CIVIL_SERVANT" + Name: "Mao Guai" + TamingItem: "Fan_Of_Wind" + EggItem: "Civil_Servant_Egg" + AccessoryItem: "Golden_Earing" + FoodItem: "Flavored_Alcohol" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 500 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" bonus(bMaxSP, 10); "> +}, +{ + Id: 1519 + SpriteName: "CHUNG_E" + Name: "Green Maiden" + TamingItem: "Tantanmen" + EggItem: "Chung_E_Egg" + FoodItem: "Bun_" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); "> + EquipScript: <" + bonus(bDef, 1); + bonus2(bAddRaceTolerance, RC_DemiPlayer, 1); + "> +}, +{ + Id: 1586 + SpriteName: "LEAF_CAT" + Name: "Leaf Cat" + TamingItem: "Very_Soft_Plant" + EggItem: "Leaf_Cat_Egg" + AccessoryItem: "Green_Lucky_Bag" + FoodItem: "Fish_With_Blue_Back" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 20 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus2(bAddRaceTolerance, RC_Brute, 3); + "> +}, +{ + Id: 1630 + SpriteName: "BACSOJIN_" + Name: "White Lady" + TamingItem: "Shiny_Wing_Gown" + EggItem: "Bacsojin_Egg" + AccessoryItem: "Round_Hair_Ornament" + FoodItem: "Traditional_Cookie" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 +}, +{ + Id: 1837 + SpriteName: "IMP" + Name: "Fire Imp" + TamingItem: "Flaming_Ice" + EggItem: "Imp_Egg" + AccessoryItem: "Horn_Protector" + FoodItem: "Flame_Gemstone" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 200 + Speed: 150 + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus2(bSubEle, Ele_Fire, 2); + bonus2(bAddEle, Ele_Fire, 2); + "> +}, +// Episode 13.2 Brasilis +{ + Id: 2057 + SpriteName: "E_CRAMP" + Name: "Strange Cramp" + TamingItem: "Leaf_Cat_Ball" + EggItem: "Mystic_Leaf_Cat_Ball" + CaptureRate: 50 + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 +}, +{ + Id: 2081 + SpriteName: "E_HYDRA" + Name: "Strange Hydra" + TamingItem: "Leaf_Cat_Ball" + EggItem: "Mystic_Leaf_Cat_Ball" + CaptureRate: 50 + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 +}, +// Episode 14.1 +{ + Id: 2313 + SpriteName: "TIKBALANG" + Name: "Tikbalang" + TamingItem: "Tikbalang_Belt" + EggItem: "Tikbalang_Pet" + FoodItem: "Monsters_Feed" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 1000 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 + EquipScript: <" + bonus2(bAddDamageClass, 2320, 10); + bonus2(bAddDamageClass, 2321, 10); + bonus2(bAddDamageClass, 2322, 10); + bonus2(bAddDamageClass, 2317, 10); + bonus2(bAddDamageClass, 2318, 10); + bonus2(bAddDamageClass, 2327, 10); + bonus2(bAddDamageClass, 2319, 10); + bonus2(bAddDamageClass, 2333, 10); + bonus2(bAddDamageClass, 2332, 10); + "> +}, +// New Pets +{ + Id: 1242 + SpriteName: "MARIN" + Name: "Marin" + TamingItem: "Juicy_Fruit" + EggItem: "Marin_Egg" + AccessoryItem: "Tw_Backpack" + FoodItem: "Fruit_Sundae" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 +}, +{ + Id: 2200 + SpriteName: "J_TAINI" + Name: "Tiny" + EggItem: "Egg_Of_Tiny" + FoodItem: "Apple" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 10 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + Speed: 150 + SpecialPerformance: true + AttackRate: 300 + DefendRate: 300 + ChangeTargetRate: 800 +}, +// Episode 14.2 +{ + Id: 2398 + SpriteName: "LITTLE_PORING" + Name: "Little Poring" + TamingItem: "Unripe_Apple2" + EggItem: "Novice_Poring_Egg" + AccessoryItem: "Backpack" + FoodItem: "Apple_Juice" + FoodEffectiveness: 80 + HungerDelay: 60 + Intimacy: { + Initial: 250 + FeedIncrement: 50 + OverFeedDecrement: 100 + OwnerDeathDecrement: 20 + } + CaptureRate: 2000 + Speed: 150 + SpecialPerformance: true + AttackRate: 350 + DefendRate: 400 + ChangeTargetRate: 800 + PetScript: <" petloot(10); "> + EquipScript: <" + bonus(bLuk, 2); + bonus(bCritical, 1); + "> +}, +) diff --git a/db/re/pet_db.txt b/db/re/pet_db.txt deleted file mode 100644 index 42d758cb9..000000000 --- a/db/re/pet_db.txt +++ /dev/null @@ -1,133 +0,0 @@ -// Pet Database -// -// Structure of Database: -// MobID,Name,JName,LureID,EggID,EquipID,FoodID,Fullness,HungryDelay,R_Hungry,R_Full,Intimate,Die,Capture,Speed,S_Performance,talk_convert_class,attack_rate,defence_attack_rate,change_target_rate,pet_script,loyal_script -// -// 01. MobID Monster ID of the pet. -// 02. Name Name of the monster as defined in the database. -// 03. JName The display name of the monster when hatched. -// 04. LureID Pet Tame Item ID. -// 05. EggID Pet Egg ID. -// 06. EquipID Pet Accessory ID. -// 07. FoodID Pet Food ID. -// 08. Fullness The amount of hunger points increasing with each feeding. -// 09. HungryDelay The amount of time it takes for hunger to decrease after feeding. (Default: 60 seconds) -// 10. R_Hungry Amount of Intimacy that is increased when fed. -// 11. R_Full Amount of Intimacy that is decreased when over-fed. -// 12. Intimate Amount of Intimacy the pet starts with. -// 13. Die Amount of Intimacy that is decreased when the pet owner dies. -// 14. Capture Capture succes rate (10000 = 100%) -// 15. Speed Pet's walk speed. (Defaul: 150) -// 16. S_Performance Special Performance. (Yes = 1, No = 0) -// 17. talk_convert_class Disables pet talk (instead of talking they emote with /!.) -// 18. attack_rate Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy). -// 19. defence_attack_rate Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy). -// 20. change_target_rate Rate of which the pet will change its attack target. -// 21. pet_script Script to execute when the pet is hatched. -// 22. loyal_script Script to execute when the pet is hatched (requires at least pet_equip_min_friendly intimacy, independent of pet_script). -//NOTE: The max value (100%) of attack_rate, defense_rate & change_target_rate is 10000. - -//In theory you can use any valid script, but it is run only once upon pet -//loading, so it is recommended you use the specific pet scripts: - -//petskillattack skillid, skilllv, hits, rate, bonusrate -//Skill attack that triggers while the pet is attacking. Rate is the base -//chance of execution per attack. Bonusrate is an additional success rate when -//intimacy reaches max. If hits is specified and different than 0, it will make -//the pet cast the skill with a fixed amount of damage inflicted and the -//specified number of hits. A value of zero uses the skill's defaults. - -//petskillsupport skillid, skilllv, delay, hp%, sp% -//Casts a support skill when the health levels are below the specified hp% and -//sp%. Delay is the minimum time in seconds before the skill can be cast again - -//petrecovery type, delay: Cures the "type" status effect after "delay" seconds - -//petskillbonus type, value, duration, delay -//Gives bonus stats. Type is the stat to increase (bStr, bLuk), value is the -//amount by which it is increased, duration signals how long the bonus lasts -//delay is the time elapsed after the bonus ends and before it starts again. - -//A single pet can have petloot, petskillbonus, petskillattack and -//petskillsupport at the same time, but only one of each. - -// Core -1002,PORING,Poring,619,9001,10013,531,80,60,50,100,250,20,2000,150,1,0,350,400,800,{ petloot 10; },{ bonus bLuk,2; bonus bCritical,1; } -1011,CHONCHON,ChonChon,624,9006,10002,537,80,60,30,100,250,20,1500,150,1,0,500,500,250,{ petskillbonus bAgi,4,10,50; },{ bonus bAgi,1; bonus bFlee,2; } -1014,SPORE,Spore,630,9012,10017,537,80,60,30,100,250,20,1500,150,0,0,350,500,500,{ petrecovery SC_POISON,60; },{ bonus bHit,5; bonus bAtk,-2; } -1019,PECOPECO,PecoPeco,632,9014,10010,537,80,60,30,100,250,20,1000,150,1,0,400,500,800,{ petskillbonus bSpeedRate,25,20,20; },{ bonus bMaxHP,150; bonus bMaxSP,-10; } -1023,ORK_WARRIOR,Orc Warrior,635,9017,10009,537,80,60,20,100,250,20,500,150,1,0,600,200,300,{ petskillattack "NPC_PIERCINGATT",100,1,0,10; },{ bonus bAtk,10; bonus bDef,-3; } -1026,MUNAK,Munak,636,9018,10008,537,80,60,20,100,250,20,500,150,0,0,300,750,300,{ petskillattack "NPC_DARKNESSATTACK",444,1,0,10; },{ bonus bInt,1; bonus bDef,1; } -1029,ISIS,Isis,639,9021,10006,537,80,60,10,100,250,20,500,150,0,0,650,450,150,{ petskillsupport "PR_MAGNIFICAT",2,60,50,50; },{ bonus bMatkRate,-1; bonus bAtkRate,1; } -1031,POPORING,Poporing,621,9003,10013,511,80,60,30,100,250,20,1000,150,1,0,300,500,400,{ petloot 15; },{ bonus bLuk,2; bonus2 bSubEle,Ele_Poison,10; } -1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,60,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack "NPC_WINDATTACK",888,2,0,10; },{ bonus bFlee,-5; bonus bFlee2,2; } -1042,STEEL_CHONCHON,Steel ChonChon,625,9007,10002,1002,80,60,20,100,250,20,1000,150,1,0,500,500,200,{ petskillbonus bAgiVit,4,20,40; },{ bonus bFlee,6; bonus bAgi,-1; } -1049,PICKY,Picky,623,9005,10012,507,80,60,40,100,250,20,2000,150,1,0,500,600,50,{ petskillbonus bStr,3,10,50;},{ bonus bStr,1; bonus bAtk,5; } -1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,150,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50; },{ bonus bHPrecovRate,5; bonus bMaxHP,25; } -1056,SMOKIE,Smokie,633,9015,10019,537,80,60,30,100,250,20,1000,150,1,0,600,600,100,{ petskillbonus bPerfectHide,1,3600,0; },{ bonus bAgi,1; bonus bFlee2,1; } -1057,YOYO,Yoyo,634,9016,10018,532,80,60,20,100,250,20,1000,150,1,0,300,800,400,{ petloot 20; },{ bonus bCritical,3; bonus bLuk,-1; } -1063,LUNATIC,Lunatic,622,9004,10007,534,80,60,40,100,250,20,1500,150,0,0,300,300,1000,{ petskillbonus bLuk,3,10,50; },{ bonus bCritical,2; bonus bAtk,2; } -1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,60,20,100,250,20,1000,150,0,0,600,200,400,{ petskillattack "NPC_POISON",20,0,0,10; },{ bonus bStr,1; bonus bInt,1; } -1101,BAPHOMET_,Baphomet Jr.,642,9024,10001,518,80,60,10,100,250,20,200,150,0,0,1000,100,200,{ petskillattack "NPC_DARKNESSATTACK",1776,4,0,5; },{ bonus bDef,1; bonus bMdef,1; bonus2 bResEff,Eff_Stun,-100; } -1107,DESERT_WOLF_B,Baby Desert Wolf,628,9010,10003,537,80,60,40,100,250,20,1000,150,0,0,400,400,400,{ petskillattack "SM_PROVOKE",1,0,0,5;},{ bonus bInt,1; bonus bMaxSP,50; } -1109,DEVIRUCHI,Deviruchi,641,9023,10004,711,80,60,10,100,250,20,500,150,0,0,800,200,100,{ petskillbonus bAgiDexStr,6,20,40; },{ bonus bMatkRate,1; bonus bAtkRate,1; bonus bMaxHPrate,-3; bonus bMaxSPrate,-3; } -1110,DOKEBI,Dokebi,637,9019,10005,537,80,60,20,100,250,20,500,150,0,0,300,300,800,{ petskillattack "BS_HAMMERFALL",1,0,0,10; },{ bonus bMatkRate,1; bonus bAtkRate,-1; } -1113,DROPS,Drops,620,9002,10013,508,80,60,40,100,250,20,1500,150,1,0,300,400,500,{ petloot 10; },{ bonus bHit,3; bonus bAtk,3; } -1155,PETIT,Petite,640,9022,10011,537,80,60,20,100,250,20,500,150,0,0,800,400,100,{ petskillattack "WZ_HEAVENDRIVE",500,1,0,10; },{ bonus bDef,-2; bonus bMdef,-2; bonus bAspdRate,1; } -1167,SAVAGE_BABE,Savage Babe,627,9009,10015,537,80,60,40,100,250,20,1500,150,0,0,500,500,200,{ petskillbonus bVit,4,10,50; },{ bonus bVit,1; bonus bMaxHP,50; } -1170,SOHEE,Sohee,638,9020,10016,537,80,60,10,100,250,20,500,150,0,0,100,1000,200,{ petskillsupport AL_HEAL,10,60,33,100; },{ bonus bStr,1; bonus bDex,1; } -1188,BON_GUN,Bon Gun,659,9025,10020,537,80,60,30,100,250,20,500,150,1,0,600,200,400,{ petskillattack "NPC_DARKNESSATTACK",555,1,1,1; },{ bonus bVit,1; bonus2 bResEff,Eff_Stun,100; } -1200,ZHERLTHSH,Zealotus,660,9026,0,929,80,60,10,100,250,20,300,150,0,0,1000,100,500,{ petskillattack "AS_SONICBLOW",1,0,0,3; },{ bonus2 bAddRace,RC_DemiPlayer,2; bonus2 bMagicAddRace,RC_DemiPlayer,2; } -1245,GOBLINE_XMAS,Christmas Goblin,12225,9029,0,911,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "MG_SIGHT",5,0,5,5; },{ bonus bMaxHP,30; bonus2 bSubEle,Ele_Water,1; } -1275,ALICE,Alice,661,9027,0,504,80,60,20,100,250,20,800,150,0,0,100,1000,200,{ petskillsupport "AL_HEAL",5,60,25,100; },{ bonus bMdef,1; bonus2 bAddRaceTolerance,RC_DemiPlayer,1; } - -// New Pets -1122,GOBLIN_1,Goblin,14569,9032,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_WINDATTACK",5,0,5,5; },{} -1123,GOBLIN_2,Goblin,14570,9033,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_FIREATTACK",5,0,5,5; },{} -1125,GOBLIN_4,Goblin,14571,9034,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_GROUNDATTACK",5,0,5,5; },{} -1208,WANDER_MAN,Wanderer,14574,9037,0,7824,80,60,20,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_UNDEADATTACK",5,0,5,5; },{} -1382,DIABOLIC,Diabolic,14573,9036,0,7823,80,60,10,100,250,20,800,150,0,0,300,300,800,{ petskillattack "WZ_METEOR",2,0,5,5; },{} -1385,DELETER_,Deleter,14572,9035,0,7822,80,60,20,100,250,20,800,150,0,0,300,300,800,{ petskillattack "SM_MAGNUM",5,0,5,5; },{} -1879,ECLIPSE_P,Spring Rabbit,0,9031,0,7766,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "TF_THROWSTONE",1,0,5,5; },{} - -// Episode 12 -1963,P_CHUNG_E,New Year Doll,0,9038,0,554,80,60,30,100,250,20,800,150,0,0,300,300,800,{ petskillattack "CR_SHIELDCHARGE",5,0,5,5; },{} - -// Episode 13 -1815,EVENT_RICECAKE,Rice Cake,0,9028,0,511,80,60,50,100,250,20,2000,150,1,0,500,500,200,{ petskillsupport "CR_DEFENDER",3,240,50,100; },{ bonus2 bSubEle,Ele_Neutral,1; bonus bMaxHPrate,-1; } -2210,XMAS_LUNATIC,Christmas Snow Rabbit,0,9058,0,529,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{ bonus2 bExpAddRace,RC_All,5; } - -// Episode 13.2 -1040,GOLEM,Golem,12371,9053,10035,6111,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxHP,100; bonus bFlee,-5; } -1143,MARIONETTE,Marionette,12361,9043,10025,6098,80,60,10,100,250,20,500,150,0,0,300,300,800,{},{ bonus bSPrecovRate,3; } -1148,MEDUSA,Medusa,12368,9050,10032,6108,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus bVit,1; bonus2 bResEff,Eff_Stone,500; } -1179,WHISPER,Whisper,12363,9045,10027,6100,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bFlee,7; bonus bDef,-3; } -1299,GOBLIN_LEADER,Goblin Leader,12364,9046,10028,6104,80,60,10,100,250,20,50,150,0,0,300,300,800,{},{ bonus2 bAddRace,RC_DemiPlayer,3; } -1370,SUCCUBUS,Succubus,12373,9055,10037,6113,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bHPDrainRate,50,5; } -1374,INCUBUS,Incubus,12370,9052,10034,6110,80,60,10,100,250,20,50,150,0,0,300,300,800,{},{ bonus bMaxSPrate,3; } -1379,NIGHTMARE_TERROR,Nightmare Terror,12372,9054,10036,6112,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bResEff,Eff_Sleep,10000; } -1401,SHINOBI,Shinobi,12362,9044,10026,6099,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bAgi,2; } -1404,MIYABI_NINGYO,Miyabi Doll,12366,9048,10030,6106,80,60,15,100,250,20,200,150,0,0,300,300,800,{},{ bonus bInt,1; bonus bCastrate,-3; } -1416,WICKED_NYMPH,Evil Nymph,12365,9047,10029,6105,80,60,15,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxSP,30; bonus bSPrecovRate,5; } -1495,STONE_SHOOTER,Stone Shooter,12369,9051,10033,6109,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus2 bSubEle,Ele_Fire,3; } -1504,DULLAHAN,Dullahan,12367,9049,10031,6107,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus bCritAtkRate,5; } -1505,LOLI_RURI,Loli Ruri,12360,9042,10024,6097,80,60,15,100,250,20,200,150,0,0,300,300,800,{},{ bonus bMaxHPrate,3; bonus3 bAutoSpellWhenHit,"AL_HEAL",1,50; } -1513,CIVIL_SERVANT,Mao Guai,12358,9040,10022,6095,80,60,10,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxSP,10; } -1519,CHUNG_E,Green Maiden,12395,9030,0,6115,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "CR_SHIELDCHARGE",5,0,5,5; },{ bonus bDef,1; bonus2 bAddRaceTolerance,RC_DemiPlayer,1; } -1586,LEAF_CAT,Leaf Cat,12359,9041,10023,6096,80,60,20,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bAddRaceTolerance,RC_Brute,2; } -1630,BACSOJIN_,White Lady,12357,9039,10021,6094,80,60,10,100,250,20,2000,150,0,0,300,300,800,{},{} -1837,IMP,Fire Imp,12374,9056,10038,6114,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bSubEle,Ele_Fire,2; bonus2 bAddEle,Ele_Fire,2; } - -// Episode 13.2 Brasilis -2057,E_CRAMP,Strange Cramp,12408,6221,0,0,0,0,0,0,0,0,50,0,0,0,350,400,800,{},{} // kRO version -2081,E_HYDRA,Strange Hydra,12408,6221,0,0,0,0,0,0,0,0,50,0,0,0,350,400,800,{},{} // iRO/cRO version - -// Episode 14.1 -2313,TIKBALANG,Tikbalang,12699,9059,0,528,80,60,10,100,250,20,1000,150,1,0,300,300,800,{},{ bonus2 bAddDamageClass,2320,10; bonus2 bAddDamageClass,2321,10; bonus2 bAddDamageClass,2322,10; bonus2 bAddDamageClass,2317,10; bonus2 bAddDamageClass,2318,10; bonus2 bAddDamageClass,2327,10; bonus2 bAddDamageClass,2319,10; bonus2 bAddDamageClass,2333,10; bonus2 bAddDamageClass,2332,10; } - -// New Pets -1242,MARIN,Marin,12789,9061,10039,6534,80,60,50,100,250,20,2000,150,1,0,300,300,800,{},{} -2200,J_TAINI,Tiny,0,9057,0,512,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{} - -// Episode 14.2 -2398,LITTLE_PORING,Little Poring,12846,9062,10013,531,80,60,50,100,250,20,2000,150,1,0,350,400,800,{ petloot 10; },{ bonus bLuk,2; bonus bCritical,1; } diff --git a/doc/constants.md b/doc/constants.md index cd5417471..978cc7ecd 100644 --- a/doc/constants.md +++ b/doc/constants.md @@ -3793,6 +3793,65 @@ - `UDT_ROBE`: 55 - `UDT_BODY2`: 56 +### HatEffect Constants + +- `HAT_EF_BLOSSOM_FLUTTERING`: 1 +- `HAT_EF_MERMAID_LONGING`: 2 +- `HAT_EF_RL_BANISHING_BUSTER`: 3 +- `HAT_EF_LJOSALFAR`: 4 +- `HAT_EF_CLOCKING`: 5 +- `HAT_EF_SNOW`: 6 +- `HAT_EF_MAKEBLUR`: 7 +- `HAT_EF_SLEEPATTACK`: 8 +- `HAT_EF_GUMGANG`: 9 +- `HAT_EF_TALK_FROSTJOKE`: 10 +- `HAT_EF_DEMONSTRATION`: 11 +- `HAT_EF_FLUTTER_BUTTERFLY`: 12 +- `HAT_EF_ANGEL_FLUTTERING`: 13 +- `HAT_EF_BLESSING_OF_ANGELS`: 14 +- `HAT_EF_ELECTRIC`: 15 +- `HAT_EF_GREEN_FLOOR`: 16 +- `HAT_EF_SHRINK`: 17 +- `HAT_EF_VALHALLA_IDOL`: 18 +- `HAT_EF_ANGEL_STAIRS`: 19 +- `HAT_EF_GLOW_OF_NEW_YEAR`: 20 +- `HAT_EF_BOTTOM_FORTUNEKISS`: 21 +- `HAT_EF_PINKBODY`: 22 +- `HAT_EF_DOUBLEGUMGANG`: 23 +- `HAT_EF_GIANTBODY`: 24 +- `HAT_EF_GREEN99_6`: 25 +- `HAT_EF_CIRCLEPOWER`: 26 +- `HAT_EF_BOTTOM_BLOODYLUST`: 27 +- `HAT_EF_WATER_BELOW`: 28 +- `HAT_EF_LEVEL99_150`: 29 +- `HAT_EF_YELLOWFLY3`: 30 +- `HAT_EF_KAGEMUSYA`: 31 +- `HAT_EF_CHERRYBLOSSOM`: 32 +- `HAT_EF_STRANGELIGHTS`: 33 +- `HAT_EF_WL_TELEKINESIS_INTENSE`: 34 +- `HAT_EF_AB_OFFERTORIUM_RING`: 35 +- `HAT_EF_WHITEBODY2`: 36 +- `HAT_EF_SAKURA`: 37 +- `HAT_EF_CLOUD2`: 38 +- `HAT_EF_FEATHER_FLUTTERING`: 39 +- `HAT_EF_CAMELLIA_HAIR_PIN`: 40 +- `HAT_EF_JP_EV_EFFECT01`: 41 +- `HAT_EF_JP_EV_EFFECT02`: 42 +- `HAT_EF_JP_EV_EFFECT03`: 43 +- `HAT_EF_FLORAL_WALTZ`: 44 +- `HAT_EF_MAGICAL_FEATHER`: 45 +- `HAT_EF_HAT_EFFECT`: 46 +- `HAT_EF_BAKURETSU_HADOU`: 47 +- `HAT_EF_GOLD_SHOWER`: 48 +- `HAT_EF_WHITEBODY`: 49 +- `HAT_EF_WATER_BELOW2`: 50 +- `HAT_EF_FIREWORK`: 51 +- `HAT_EF_RETURN_TW_1ST_HAT`: 52 +- `HAT_EF_C_FLUTTERBUTTERFLY_BL`: 53 +- `HAT_EF_QSCARABA`: 54 +- `HAT_EF_FSTONE`: 55 +- `HAT_EF_MAGICCIRCLE`: 56 + ## Hardcoded Constants (source) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index e14e80444..d69322745 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -3271,6 +3271,13 @@ produced). It's useful for when you want to check whether an item contains cards or if it's signed. --------------------------------------- + +*hateffect(<Hat Effect ID>, <State>) + +This will set a Hat Effect onto the player. The state field allows you to +enable (true) or disable (false) the effect on the player. + +--------------------------------------- //===================================== 2.1 - End of Item-Related Commands //===================================== diff --git a/npc/mapflag/noteleport.txt b/npc/mapflag/noteleport.txt index 700964da4..b80498f89 100644 --- a/npc/mapflag/noteleport.txt +++ b/npc/mapflag/noteleport.txt @@ -154,6 +154,7 @@ thor_camp mapflag noteleport moc_para01 mapflag noteleport // Job Quests ==================== +pay_arche mapflag noteleport job_sword1 mapflag noteleport job_thief1 mapflag noteleport // 2-1 ----------------------- diff --git a/sql-files/item_db.sql b/sql-files/item_db.sql index 3a045faf0..08b1be3cd 100644 --- a/sql-files/item_db.sql +++ b/sql-files/item_db.sql @@ -4202,6 +4202,7 @@ REPLACE INTO `item_db` VALUES ('9053','Golem_Egg','Golem Egg','7','0','20','10', REPLACE INTO `item_db` VALUES ('9054','Nightmare_Terror_Egg','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 ('9055','Succubus_Egg','Succubus 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 ('9056','Imp_Egg','Imp 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 ('9058','Snow_Rabbit_Egg','Christmas Snow Rabbit 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','467',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('10001','Skull_Helm','Skull Helm','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 ('10002','Monster_Oxygen_Mask','Monster Oxygen 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 ('10003','Transparent_Headgear','Transparent Head Protector','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','','',''); diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index 4c762b8e8..072895142 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -9638,7 +9638,7 @@ REPLACE INTO `item_db` VALUES ('20281','C_Kindergarten_Hat','Costume Kindergarte REPLACE INTO `item_db` VALUES ('20282','C_White_Student_Cap','Costume White Student Cap','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','1024','0','0',NULL,'1','0','877','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('20283','C_Over_Protector','Costume Over Protector','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','1024','0','0',NULL,'1','0','1329','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('20284','C_Cherry_Blossom_Hat','Costume Sakura Hat','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','1024','0','0',NULL,'1','0','1330','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); -REPLACE INTO `item_db` VALUES ('20285','C_Blossom_Fluttering','Costume Dancing Fallen Sakura','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','4096','0','0',NULL,'1','0','1331','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','sc_start SC_BLOSSOM_FLUTTERING, -1, 0;','sc_end SC_BLOSSOM_FLUTTERING;'); +REPLACE INTO `item_db` VALUES ('20285','C_Blossom_Fluttering','Costume Dancing Fallen Sakura','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','4096','0','0',NULL,'1','0','1331','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','hateffect(HAT_EF_BLOSSOM_FLUTTERING, true);','hateffect(HAT_EF_BLOSSOM_FLUTTERING, false);'); REPLACE INTO `item_db` VALUES ('20286','C_Under_Rim_Glasses_Red','Costume Under Rim Glasses Red','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','2048','0','0',NULL,'1','0','1332','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('20287','C_Mans_Medal_','Costume Man\'s Medal(Gold)','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','1024','0','0',NULL,'1','0','1333','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); REPLACE INTO `item_db` VALUES ('20288','C_Bijou_Hat','Costume Bijou Hat','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','1024','0','0',NULL,'1','0','1334','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','',''); diff --git a/sql-files/main.sql b/sql-files/main.sql index 5546c0271..2e51d6a12 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -219,6 +219,8 @@ CREATE TABLE IF NOT EXISTS `char` ( `uniqueitem_counter` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0', `sex` ENUM('M','F','U') NOT NULL DEFAULT 'U', `hotkey_rowshift` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + `attendance_count` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', + `attendance_timer` BIGINT(20) NULL DEFAULT '0', PRIMARY KEY (`char_id`), UNIQUE KEY `name_key` (`name`), KEY `account_id` (`account_id`), @@ -890,6 +892,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1496588640); -- 2017-06-0 INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1496588700); -- 2017-06-04--15-05.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1509835214); -- 2017-11-04--10-39.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1519671456); -- 2018-02-26--15-57.sql +INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1520654809); -- 2018-03-10--04-06.sql -- -- Table structure for table `storage` -- diff --git a/sql-files/upgrades/2018-03-10--04-06.sql b/sql-files/upgrades/2018-03-10--04-06.sql new file mode 100644 index 000000000..ee827735d --- /dev/null +++ b/sql-files/upgrades/2018-03-10--04-06.sql @@ -0,0 +1,24 @@ +#1520654809 + +-- This file is part of Hercules. +-- http://herc.ws - http://github.com/HerculesWS/Hercules +-- +-- Copyright (C) 2017 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 `char` ADD COLUMN `attendance_count` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `hotkey_rowshift`; +ALTER TABLE `char` ADD COLUMN `attendance_timer` BIGINT(20) NULL DEFAULT '0' AFTER `attendance_count`; + +INSERT INTO `sql_updates` (`timestamp`, `ignored`) VALUES (1520654809 , 'No'); diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt index a2d0c5171..dac60b6aa 100644 --- a/sql-files/upgrades/index.txt +++ b/sql-files/upgrades/index.txt @@ -44,3 +44,4 @@ 2017-06-04--15-05.sql 2017-11-04--10-39.sql 2018-02-26--15-57.sql +2018-03-10--04-06.sql diff --git a/src/char/char.c b/src/char/char.c index 0069e7f1d..84cc1b688 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -467,7 +467,8 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) (p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->look.robe != cp->look.robe) || (p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) || (p->uniqueitem_counter != cp->uniqueitem_counter) || (p->hotkey_rowshift != cp->hotkey_rowshift) || - (p->clan_id != cp->clan_id) || (p->last_login != cp->last_login) + (p->clan_id != cp->clan_id) || (p->last_login != cp->last_login) || (p->attendance_count != cp->attendance_count) || + (p->attendance_timer != cp->attendance_timer) ) { //Save status unsigned int opt = 0; @@ -485,7 +486,7 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) "`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d'," "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d'," "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'," - "`hotkey_rowshift`='%d',`clan_id`='%d',`last_login`='%"PRId64"'" + "`hotkey_rowshift`='%d',`clan_id`='%d',`last_login`='%"PRId64"',`attendance_count`='%d',`attendance_timer`='%"PRId64"'" " WHERE `account_id`='%d' AND `char_id` = '%d'", char_db, p->base_level, p->job_level, p->base_exp, p->job_exp, p->zeny, @@ -497,7 +498,7 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename, (unsigned long)p->delete_date, // FIXME: platform-dependent size p->look.robe,p->slotchange,opt,p->font,p->uniqueitem_counter, - p->hotkey_rowshift,p->clan_id,p->last_login, + p->hotkey_rowshift,p->clan_id,p->last_login, p->attendance_count, p->attendance_timer, p->account_id, p->char_id) ) { Sql_ShowDebug(inter->sql_handle); @@ -1175,7 +1176,7 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every "`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`," "`hair_color`,`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`," "`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`," - "`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`" + "`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`, `attendance_count`, `attendance_timer`" " FROM `%s` WHERE `char_id`=? LIMIT 1", char_db) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, sizeof char_id) || SQL_ERROR == SQL->StmtExecute(stmt) @@ -1240,6 +1241,8 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every || SQL_ERROR == SQL->StmtBindColumn(stmt, 58, SQLDT_UCHAR, &p->hotkey_rowshift, sizeof p->hotkey_rowshift, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 59, SQLDT_INT, &p->clan_id, sizeof p->clan_id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 60, SQLDT_INT64, &p->last_login, sizeof p->last_login, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 61, SQLDT_SHORT, &p->attendance_count, sizeof p->attendance_count, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 62, SQLDT_INT64, &p->attendance_timer, sizeof p->attendance_timer, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); @@ -3328,7 +3331,7 @@ void char_char_name_ack(int fd, int char_id) WFIFOHEAD(fd,30); WFIFOW(fd,0) = 0x2b09; WFIFOL(fd,2) = char_id; -#if !defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221)) +#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 || PACKETVER_ZERO_NUM >= 20180328 if (chr->loadName(char_id, WFIFOP(fd,6)) == 0) WFIFOL(fd, 6) = 0; #else diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 0102f11a0..3f34e883b 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -417,8 +417,8 @@ struct guild * inter_guild_fromsql(int guild_id) } // load guild member info - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name` " - "FROM `%s` WHERE `guild_id`='%d' ORDER BY `position`", guild_member_db, guild_id) ) + if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT g.`account_id`,g.`char_id`,g.`hair`,g.`hair_color`,g.`gender`,g.`class`,g.`lv`,g.`exp`,g.`exp_payper`,g.`online`,g.`position`,g.`name`,c.`last_login`" + "FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d' ORDER BY `position`", guild_member_db, char_db, guild_id) ) { Sql_ShowDebug(inter->sql_handle); aFree(g); @@ -442,6 +442,7 @@ struct guild * inter_guild_fromsql(int guild_id) if( m->position >= MAX_GUILDPOSITION ) // Fix reduction of MAX_GUILDPOSITION [PoW] m->position = MAX_GUILDPOSITION - 1; SQL->GetData(inter->sql_handle, 11, &data, &len); memcpy(m->name, data, min(len, NAME_LENGTH)); + SQL->GetData(inter->sql_handle, 12, &data, NULL); m->last_login = atoi(data); m->modified = GS_MEMBER_UNMODIFIED; } @@ -975,7 +976,7 @@ int mapif_guild_withdraw(int guild_id,int account_id,int char_id,int flag, const // Send short member's info int mapif_guild_memberinfoshort(struct guild *g, int idx) { - unsigned char buf[19]; + unsigned char buf[23]; nullpo_ret(g); Assert_ret(idx >= 0 && idx < MAX_GUILD); WBUFW(buf, 0)=0x3835; @@ -985,7 +986,8 @@ int mapif_guild_memberinfoshort(struct guild *g, int idx) WBUFB(buf,14)=(unsigned char)g->member[idx].online; WBUFW(buf,15)=g->member[idx].lv; WBUFW(buf,17)=g->member[idx].class; - mapif->sendall(buf,19); + WBUFL(buf,19)=g->member[idx].last_login; + mapif->sendall(buf,23); return 0; } @@ -1366,6 +1368,7 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, g->member[i].online = online; g->member[i].lv = lv; g->member[i].class = class; + g->member[i].last_login = (uint32)time(NULL); g->member[i].modified = GS_MEMBER_MODIFIED; mapif->guild_memberinfoshort(g,i); } diff --git a/src/char/int_rodex.c b/src/char/int_rodex.c index 2001ddc43..0dab66f61 100644 --- a/src/char/int_rodex.c +++ b/src/char/int_rodex.c @@ -83,8 +83,8 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64 if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" - "FROM `%s` WHERE (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `send_date` + '%d' > '%d' AND `mail_id` > '%"PRId64"')" - "ORDER BY `mail_id` ASC", rodex_db, char_id, (int)time(NULL), 2 * RODEX_EXPIRE, (int)time(NULL), mail_id) + "FROM `%s` WHERE (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `expire_date` + '%d' > '%d' AND `mail_id` > '%"PRId64"')" + "ORDER BY `mail_id` ASC", rodex_db, char_id, (int)time(NULL), RODEX_EXPIRE, (int)time(NULL), mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); @@ -98,8 +98,8 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64 "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE " "((`expire_date` > '%d' AND (`receiver_id` = '%d' OR `receiver_accountid` = '%d'))" - "OR (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `send_date` + '%d' > '%d'))" - "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, account_id, char_id, (int)time(NULL), 2 * RODEX_EXPIRE, (int)time(NULL)) + "OR (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `expire_date` + '%d' > '%d'))" + "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, account_id, char_id, (int)time(NULL), RODEX_EXPIRE, (int)time(NULL)) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index 4bcb33e23..f8a55218e 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -426,6 +426,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { #define MAP_CLAN_H #endif // MAP_CLAN_H #ifdef MAP_CLIF_H + { "attendance_entry", sizeof(struct attendance_entry), SERVER_TYPE_MAP }, { "cdelayed_damage", sizeof(struct cdelayed_damage), SERVER_TYPE_MAP }, { "clif_interface", sizeof(struct clif_interface), SERVER_TYPE_MAP }, { "hCSData", sizeof(struct hCSData), SERVER_TYPE_MAP }, @@ -585,6 +586,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "NORMALITEM_INFO", sizeof(struct NORMALITEM_INFO), SERVER_TYPE_MAP }, { "PACKET_CZ_ADD_ITEM_TO_MAIL", sizeof(struct PACKET_CZ_ADD_ITEM_TO_MAIL), SERVER_TYPE_MAP }, { "PACKET_CZ_CHECKNAME", sizeof(struct PACKET_CZ_CHECKNAME), SERVER_TYPE_MAP }, + { "PACKET_CZ_OPEN_UI", sizeof(struct PACKET_CZ_OPEN_UI), SERVER_TYPE_MAP }, { "PACKET_CZ_REQ_DELETE_MAIL", sizeof(struct PACKET_CZ_REQ_DELETE_MAIL), SERVER_TYPE_MAP }, { "PACKET_CZ_REQ_ITEM_FROM_MAIL", sizeof(struct PACKET_CZ_REQ_ITEM_FROM_MAIL), SERVER_TYPE_MAP }, { "PACKET_CZ_REQ_NEXT_MAIL_LIST", sizeof(struct PACKET_CZ_REQ_NEXT_MAIL_LIST), SERVER_TYPE_MAP }, @@ -605,14 +607,18 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "PACKET_ZC_ADD_MEMBER_TO_GROUP", sizeof(struct PACKET_ZC_ADD_MEMBER_TO_GROUP), SERVER_TYPE_MAP }, { "PACKET_ZC_CHECKNAME", sizeof(struct PACKET_ZC_CHECKNAME), SERVER_TYPE_MAP }, { "PACKET_ZC_CLANINFO", sizeof(struct PACKET_ZC_CLANINFO), SERVER_TYPE_MAP }, + { "PACKET_ZC_FORMATSTRING_MSG", sizeof(struct PACKET_ZC_FORMATSTRING_MSG), SERVER_TYPE_MAP }, { "PACKET_ZC_GROUP_LIST", sizeof(struct PACKET_ZC_GROUP_LIST), SERVER_TYPE_MAP }, { "PACKET_ZC_GROUP_LIST_SUB", sizeof(struct PACKET_ZC_GROUP_LIST_SUB), SERVER_TYPE_MAP }, { "PACKET_ZC_MAIL_LIST", sizeof(struct PACKET_ZC_MAIL_LIST), SERVER_TYPE_MAP }, + { "PACKET_ZC_MSG_COLOR", sizeof(struct PACKET_ZC_MSG_COLOR), SERVER_TYPE_MAP }, { "PACKET_ZC_NOTIFY_CLAN_CHAT", sizeof(struct PACKET_ZC_NOTIFY_CLAN_CHAT), SERVER_TYPE_MAP }, { "PACKET_ZC_NOTIFY_CLAN_CONNECTINFO", sizeof(struct PACKET_ZC_NOTIFY_CLAN_CONNECTINFO), SERVER_TYPE_MAP }, { "PACKET_ZC_NOTIFY_UNREADMAIL", sizeof(struct PACKET_ZC_NOTIFY_UNREADMAIL), SERVER_TYPE_MAP }, + { "PACKET_ZC_OPEN_UI", sizeof(struct PACKET_ZC_OPEN_UI), SERVER_TYPE_MAP }, { "PACKET_ZC_READ_MAIL", sizeof(struct PACKET_ZC_READ_MAIL), SERVER_TYPE_MAP }, { "PACKET_ZC_SKILL_SCALE", sizeof(struct PACKET_ZC_SKILL_SCALE), SERVER_TYPE_MAP }, + { "PACKET_ZC_UI_ACTION", sizeof(struct PACKET_ZC_UI_ACTION), SERVER_TYPE_MAP }, { "PACKET_ZC_WRITE_MAIL_RESULT", sizeof(struct PACKET_ZC_WRITE_MAIL_RESULT), SERVER_TYPE_MAP }, { "ZC_PROGRESS_ACTOR", sizeof(struct ZC_PROGRESS_ACTOR), SERVER_TYPE_MAP }, { "mail_item", sizeof(struct mail_item), SERVER_TYPE_MAP }, @@ -656,8 +662,14 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "packet_npc_market_result_ack", sizeof(struct packet_npc_market_result_ack), SERVER_TYPE_MAP }, { "packet_package_item_announce", sizeof(struct packet_package_item_announce), SERVER_TYPE_MAP }, { "packet_party_leader_changed", sizeof(struct packet_party_leader_changed), SERVER_TYPE_MAP }, + { "packet_quest_add_header", sizeof(struct packet_quest_add_header), SERVER_TYPE_MAP }, + { "packet_quest_hunt_info", sizeof(struct packet_quest_hunt_info), SERVER_TYPE_MAP }, + { "packet_quest_hunt_info_sub", sizeof(struct packet_quest_hunt_info_sub), SERVER_TYPE_MAP }, + { "packet_quest_hunt_sub", sizeof(struct packet_quest_hunt_sub), SERVER_TYPE_MAP }, { "packet_quest_list_header", sizeof(struct packet_quest_list_header), SERVER_TYPE_MAP }, { "packet_quest_list_info", sizeof(struct packet_quest_list_info), SERVER_TYPE_MAP }, + { "packet_quest_update_header", sizeof(struct packet_quest_update_header), SERVER_TYPE_MAP }, + { "packet_quest_update_hunt", sizeof(struct packet_quest_update_hunt), SERVER_TYPE_MAP }, { "packet_roulette_close_ack", sizeof(struct packet_roulette_close_ack), SERVER_TYPE_MAP }, { "packet_roulette_generate_ack", sizeof(struct packet_roulette_generate_ack), SERVER_TYPE_MAP }, { "packet_roulette_info_ack", sizeof(struct packet_roulette_info_ack), SERVER_TYPE_MAP }, diff --git a/src/common/mmo.h b/src/common/mmo.h index f9cbc57de..1110fa8f5 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -81,6 +81,22 @@ #undef ENABLE_PACKETVER_ZERO #endif // DISABLE_PACKETVER_ZERO +#if !defined(PACKETVER_RE) && !defined(PACKETVER_ZERO) + #define PACKETVER_MAIN_NUM PACKETVER +#else + #define PACKETVER_MAIN_NUM 0 +#endif +#ifdef PACKETVER_RE + #define PACKETVER_RE_NUM PACKETVER +#else + #define PACKETVER_RE_NUM 0 +#endif +#ifdef PACKETVER_ZERO + #define PACKETVER_ZERO_NUM PACKETVER +#else + #define PACKETVER_ZERO_NUM 0 +#endif + // Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18 #if defined(PACKETVER_RE) && ( PACKETVER == 20120410 || PACKETVER == 20120418 ) #define PARTY_RECRUIT @@ -664,6 +680,9 @@ struct mmo_charstatus { uint32 uniqueitem_counter; + int64 attendance_timer; + short attendance_count; + unsigned char hotkey_rowshift; }; @@ -746,6 +765,7 @@ struct guild_member { char name[NAME_LENGTH]; struct map_session_data *sd; unsigned char modified; + uint32 last_login; }; struct guild_position { diff --git a/src/map/battle.c b/src/map/battle.c index b2490ed23..5f56599d7 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7320,6 +7320,9 @@ static const struct battle_data { { "features/rodex", &battle_config.feature_rodex, 1, 0, 1, }, { "features/rodex_use_accountmail", &battle_config.feature_rodex_use_accountmail, 0, 0, 1, }, { "features/enable_homun_autofeed", &battle_config.feature_enable_homun_autofeed, 1, 0, 1, }, + { "storage_use_item", &battle_config.storage_use_item, 0, 0, 1, }, + { "features/enable_attendance_system", &battle_config.feature_enable_attendance_system,1, 0, 1, }, + { "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, }, }; #ifndef STATS_OPT_OUT /** diff --git a/src/map/battle.h b/src/map/battle.h index 9eb7557f8..998c0b011 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -563,6 +563,11 @@ struct Battle_Config { int feature_rodex_use_accountmail; int feature_enable_homun_autofeed; + + int storage_use_item; + + int feature_enable_attendance_system; + int feature_attendance_endtime; }; /* criteria for battle_config.idletime_critera */ diff --git a/src/map/clif.c b/src/map/clif.c index cf5edd0e0..60f4b18c0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1539,6 +1539,7 @@ bool clif_spawn(struct block_list *bl) clif->spiritcharm(sd); if (sd->status.look.robe != 0) clif->refreshlook(bl, bl->id, LOOK_ROBE, sd->status.look.robe, AREA); + clif->hat_effect(bl, NULL, AREA); } break; case BL_MOB: @@ -4395,6 +4396,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { clif->sendbgemblem_single(sd->fd,tsd); if (tsd->status.look.robe != 0) clif->refreshlook(&sd->bl, bl->id, LOOK_ROBE, tsd->status.look.robe, SELF); + clif->hat_effect(bl, &sd->bl, SELF); } break; case BL_MER: // Devotion Effects @@ -5466,6 +5468,7 @@ void clif_skill_warppoint(struct map_session_data* sd, uint16 skill_id, uint16 s /// 0 = "Saved location as a Memo Point for Warp skill." in color 0xFFFF00 (cyan) /// 1 = "Skill Level is not high enough." in color 0x0000FF (red) /// 2 = "You haven't learned Warp." in color 0x0000FF (red) +/// 3 = "Cannot save location as a Memo Point at current location." in color 0x0000FF (red) /// /// @param sd Who receives the message /// @param type What message @@ -5488,6 +5491,7 @@ void clif_skill_memomessage(struct map_session_data* sd, int type) /// 0 = "Unable to Teleport in this area" in color 0xFFFF00 (cyan) /// 1 = "Saved point cannot be memorized." in color 0x0000FF (red) /// 2 = "This skill cannot be used within this area." in color 0xFFFF00 (cyan) +/// 3 = "This item cannot be used within this area." in color 0xFFFF00 (cyan) /// /// @param sd Who receives the message /// @param type What message @@ -6092,7 +6096,7 @@ void clif_wis_end(int fd, int flag) { void clif_solved_charname(int fd, int charid, const char* name) { nullpo_retv(name); -#if !defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221)) +#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 || PACKETVER_ZERO_NUM >= 20180328 WFIFOHEAD(fd, packet_len(0x0af7)); WFIFOW(fd, 0) = 0xaf7; if (*name == 0) { @@ -7715,7 +7719,7 @@ void clif_guild_memberlist(struct map_session_data *sd) memset(WFIFOP(fd, c * size + 34), 0, 50); //[Ind] - This is displayed in the 'note' column but being you can't edit it it's sent empty. memcpy(WFIFOP(fd, c * size + 84), m->name, NAME_LENGTH); #else - WFIFOL(fd, c * size + 34) = 0; // [4144] this is member last login time. But in hercules it not present. + WFIFOL(fd, c * size + 34) = m->last_login; // [Megasantos] - Shows last date online #endif c++; } @@ -9230,6 +9234,56 @@ void clif_msgtable_skill(struct map_session_data* sd, uint16 skill_id, int msg_i } /** +* Displays a format string from msgstringtable.txt with a %s value (ZC_FORMATSTRING_MSG). +* +* @param sd The target character. +* @param msg_id msgstringtable message index, 0-based (@see enum clif_messages) +* @param value The value to fill %s. +*/ +void clif_msgtable_str(struct map_session_data *sd, uint16 msg_id, const char *value) +{ + int message_len; + int len; + struct PACKET_ZC_FORMATSTRING_MSG *p; + + nullpo_retv(sd); + nullpo_retv(value); + + message_len = (int)strlen(value) + 1; + len = sizeof(*p) + message_len + 1; + + p = (struct PACKET_ZC_FORMATSTRING_MSG *)aMalloc(len); + p->PacketType = 0x2c2; + p->PacketLength = len; + p->MessageId = msg_id; + safestrncpy(p->MessageString, value, message_len); + p->MessageString[message_len] = 0; + + clif->send(p, p->PacketLength, &sd->bl, SELF); + aFree(p); +} + +/** +* Displays a format string from msgstringtable.txt with a color (ZC_MSG_COLOR). +* +* @param sd The target character. +* @param msg_id msgstringtable message index, 0-based (@see enum clif_messages) +* @param color The color to use +*/ +void clif_msgtable_color(struct map_session_data *sd, uint16 msg_id, uint32 color) +{ + struct PACKET_ZC_MSG_COLOR p; + + nullpo_retv(sd); + + p.PacketType = 0x9cd; + p.MessageId = msg_id; + p.MessageColor = RGB2BGR(color); + + clif->send(&p, sizeof(p), &sd->bl, SELF); +} + +/** * Validates and processes a global/guild/party message packet. * * @param[in] sd The source character. @@ -9756,6 +9810,13 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) { clif->partyinvitationstate(sd); clif->equpcheckbox(sd); #endif + +#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920 + if (sd->hd != NULL) + clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed); + else + clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); +#endif if( (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100) && (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m) || map->list[sd->state.pmap].flag.battleground || map->list[sd->bl.m].flag.battleground) ) @@ -14218,10 +14279,8 @@ void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int cha WFIFOL(fd, 2) = sd->status.friends[i].account_id; WFIFOL(fd, 6) = sd->status.friends[i].char_id; WFIFOB(fd, 10) = !online; //Yeah, a 1 here means "logged off", go figure... -#ifndef PACKETVER_ZERO -#if PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221) +#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 memcpy(WFIFOP(fd, 11), sd->status.friends[i].name, NAME_LENGTH); -#endif #endif // PACKETVER_ZERO WFIFOSET(fd, packet_len(0x206)); @@ -14245,7 +14304,7 @@ void clif_friendslist_send(struct map_session_data *sd) { int i = 0, n, fd = sd->fd; -#if !defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221)) +#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 const int offset = 8; #else const int offset = 32; @@ -14257,7 +14316,7 @@ void clif_friendslist_send(struct map_session_data *sd) for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) { WFIFOL(fd, 4 + offset * i + 0) = sd->status.friends[i].account_id; WFIFOL(fd, 4 + offset * i + 4) = sd->status.friends[i].char_id; -#if !(!defined(PACKETVER_ZERO) && (PACKETVER >= 20180307 || (defined(PACKETVER_RE) && PACKETVER >= 20180221))) +#if !(PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221) memcpy(WFIFOP(fd, 4 + offset * i + 8), &sd->status.friends[i].name, NAME_LENGTH); #endif } @@ -16126,6 +16185,7 @@ void clif_parse_PartyTick(int fd, struct map_session_data* sd) /// Sends list of all quest states (ZC_ALL_QUEST_LIST). /// 02b1 <packet len>.W <num>.L { <quest id>.L <active>.B }*num /// 097a <packet len>.W <num>.L { <quest id>.L <active>.B <remaining time>.L <time>.L <count>.W { <mob_id>.L <killed>.W <total>.W <mob name>.24B }*count }*num +/// 09f8 <packet len>.W <num>.L { <quest id>.L <active>.B <remaining time>.L <time>.L <count>.W { <hunt identification>.L <mob type>.L <mob_id>.L <min level>.L <max level>.L <killed>.W <total>.W <mob name>.24B }*count }*num void clif_quest_send_list(struct map_session_data *sd) { int i, len, real_len; @@ -16164,8 +16224,16 @@ void clif_quest_send_list(struct map_session_data *sd) real_len += sizeof(info->objectives[j]); mob_data = mob->db(qi->objectives[j].mob); - +#if PACKETVER >= 20150513 + info->objectives[j].huntIdent = (sd->quest_log[i].quest_id * 1000) + j; + info->objectives[j].mobType = 0; // Info Needed +#endif info->objectives[j].mob_id = qi->objectives[j].mob; +#if PACKETVER >= 20150513 + // Info Needed + info->objectives[j].levelMin = 0; + info->objectives[j].levelMax = 0; +#endif info->objectives[j].huntCount = sd->quest_log[i].count[j]; info->objectives[j].maxCount = qi->objectives[j].count; safestrncpy(info->objectives[j].mobName, mob_data->jname, sizeof(info->objectives[j].mobName)); @@ -16213,33 +16281,53 @@ void clif_quest_send_mission(struct map_session_data *sd) /// Notification about a new quest (ZC_ADD_QUEST). /// 02b3 <quest id>.L <active>.B <start time>.L <expire time>.L <mobs>.W { <mob id>.L <mob count>.W <mob name>.24B }*3 +/// 09f9 <quest id>.L <active>.B <start time>.L <expire time>.L <mobs>.W { <hunt identification>.L <mob type>.L <mob id>.L <min level>.L <max level>.L <mob count>.W <mob name>.24B }*3 void clif_quest_add(struct map_session_data *sd, struct quest *qd) { - int fd; - int i; + int i, len; + uint8 *buf = NULL; + struct packet_quest_add_header *packet = NULL; struct quest_db *qi; nullpo_retv(sd); nullpo_retv(qd); - fd = sd->fd; + qi = quest->db(qd->quest_id); - WFIFOHEAD(fd, packet_len(0x2b3)); - WFIFOW(fd, 0) = 0x2b3; - WFIFOL(fd, 2) = qd->quest_id; - WFIFOB(fd, 6) = qd->state; - WFIFOB(fd, 7) = qd->time - qi->time; - WFIFOL(fd, 11) = qd->time; - WFIFOW(fd, 15) = qi->objectives_count; + Assert_retv(qi->objectives_count < MAX_QUEST_OBJECTIVES); + + len = sizeof(struct packet_quest_add_header) + + MAX_QUEST_OBJECTIVES * sizeof(struct packet_quest_hunt_sub); // >= than the actual length + + buf = aCalloc(1, len); + packet = (struct packet_quest_add_header *)WBUFP(buf, 0); + + packet->PacketType = questAddType; + packet->questID = qd->quest_id; + packet->active = qd->state; + packet->quest_svrTime = qd->time - qi->time; + packet->quest_endTime = qd->time; + packet->count = qi->objectives_count; for (i = 0; i < qi->objectives_count; i++) { struct mob_db *monster; - WFIFOL(fd, i*30+17) = qi->objectives[i].mob; - WFIFOW(fd, i*30+21) = qd->count[i]; + monster = mob->db(qi->objectives[i].mob); - memcpy(WFIFOP(fd, i*30+23), monster->jname, NAME_LENGTH); - } - WFIFOSET(fd, packet_len(0x2b3)); +#if PACKETVER >= 20150513 + packet->objectives[i].huntIdent = (qd->quest_id * 1000) + i; + packet->objectives[i].mobType = 0; // Info Needed +#endif + packet->objectives[i].mob_id = qi->objectives[i].mob; +#if PACKETVER >= 20150513 + // Info Needed + packet->objectives[i].levelMin = 0; + packet->objectives[i].levelMax = 0; +#endif + packet->objectives[i].huntCount = qd->count[i]; + memcpy(packet->objectives[i].mobName, monster->jname, NAME_LENGTH); + } + clif->send(buf, len, &sd->bl, SELF); + aFree(buf); } /// Notification about a quest being removed (ZC_DEL_QUEST). @@ -16257,32 +16345,84 @@ void clif_quest_delete(struct map_session_data *sd, int quest_id) { /// Notification of an update to the hunting mission counter (ZC_UPDATE_MISSION_HUNT). /// 02b5 <packet len>.W <mobs>.W { <quest id>.L <mob id>.L <total count>.W <current count>.W }*3 +/// 09fa <packet len>.W <mobs>.W { <quest id>.L <hunt identification>.L <total count>.W <current count>.W }*3 void clif_quest_update_objective(struct map_session_data *sd, struct quest *qd) { - int fd; - int i; + int i, len, real_len; + uint8 *buf = NULL; + struct packet_quest_update_header *packet = NULL; struct quest_db *qi; - int len; nullpo_retv(sd); nullpo_retv(qd); - fd = sd->fd; + qi = quest->db(qd->quest_id); - len = qi->objectives_count * 12 + 6; + Assert_retv(qi->objectives_count < MAX_QUEST_OBJECTIVES); + + len = sizeof(struct packet_quest_update_header) + + MAX_QUEST_OBJECTIVES * sizeof(struct packet_quest_update_hunt); // >= than the actual length - WFIFOHEAD(fd, len); - WFIFOW(fd, 0) = 0x2b5; - WFIFOW(fd, 2) = len; - WFIFOW(fd, 4) = qi->objectives_count; + buf = aCalloc(1, len); + packet = (struct packet_quest_update_header *)WBUFP(buf, 0); + real_len = sizeof(*packet); + + packet->PacketType = questUpdateType; + packet->count = qi->objectives_count; for (i = 0; i < qi->objectives_count; i++) { - WFIFOL(fd, i*12+6) = qd->quest_id; - WFIFOL(fd, i*12+10) = qi->objectives[i].mob; - WFIFOW(fd, i*12+14) = qi->objectives[i].count; - WFIFOW(fd, i*12+16) = qd->count[i]; + real_len += sizeof(packet->objectives[i]); + + packet->objectives[i].questID = qd->quest_id; +#if PACKETVER >= 20150513 + packet->objectives[i].huntIdent = (qd->quest_id * 1000) + i; +#else + packet->objectives[i].mob_id = qi->objectives[i].mob; +#endif + packet->objectives[i].maxCount = qi->objectives[i].count; + packet->objectives[i].count = qd->count[i]; } + packet->PacketLength = real_len; + clif->send(buf, real_len, &sd->bl, SELF); + aFree(buf); +} - WFIFOSET(fd, len); +/// Notification of an hunting mission counter just after quest is added (ZC_HUNTING_QUEST_INFO). +/// 08fe <packet len>.W { <quest id>.L <mob id>.L <total count>.W <current count>.W }*3 +void clif_quest_notify_objective(struct map_session_data *sd, struct quest *qd) +{ +#if PACKETVER >= 20150513 + int i, len, real_len; + uint8 *buf = NULL; + struct packet_quest_hunt_info *packet = NULL; + struct quest_db *qi; + + nullpo_retv(sd); + nullpo_retv(qd); + + qi = quest->db(qd->quest_id); + Assert_retv(qi->objectives_count < MAX_QUEST_OBJECTIVES); + + len = sizeof(struct packet_quest_hunt_info) + + MAX_QUEST_OBJECTIVES * sizeof(struct packet_quest_hunt_info_sub); // >= than the actual length + + buf = aCalloc(1, len); + packet = (struct packet_quest_hunt_info *)WBUFP(buf, 0); + real_len = sizeof(*packet); + + packet->PacketType = questUpdateType2; + + for (i = 0; i < qi->objectives_count; i++) { + real_len += sizeof(packet->info[i]); + + packet->info[i].questID = qd->quest_id; + packet->info[i].mob_id = qi->objectives[i].mob; + packet->info[i].maxCount = qi->objectives[i].count; + packet->info[i].count = qd->count[i]; + } + packet->PacketLength = real_len; + clif->send(buf, real_len, &sd->bl, SELF); + aFree(buf); +#endif } void clif_parse_questStateAck(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -20228,6 +20368,248 @@ void clif_skill_scale(struct block_list *bl, int src_id, int x, int y, uint16 sk #endif } +/// Send hat effects to the client (ZC_HAT_EFFECT). +/// 0A3B <Length>.W <AID>.L <Status>.B { <HatEffectId>.W } +void clif_hat_effect(struct block_list *bl, struct block_list *tbl, enum send_target target) +{ +#if PACKETVER >= 20150422 + unsigned char *buf; + int len, i; + struct map_session_data *sd; + + nullpo_retv(bl); + + sd = BL_CAST(BL_PC, bl); + + nullpo_retv(sd); + + len = 9 + VECTOR_LENGTH(sd->hatEffectId) * 2; + + buf = (unsigned char*)aMalloc(len); + + WBUFW(buf, 0) = 0xa3b; + WBUFW(buf, 2) = len; + WBUFL(buf, 4) = bl->id; + WBUFB(buf, 8) = 1; + + for( i = 0; i < VECTOR_LENGTH(sd->hatEffectId); i++ ){ + WBUFW(buf, 9 + i * 2) = VECTOR_INDEX(sd->hatEffectId, i); + } + + if (tbl != NULL) { + clif->send(buf, len, tbl, target); + } else { + clif->send(buf, len, bl, target); + } + + aFree(buf); +#endif +} + +void clif_hat_effect_single(struct block_list *bl, uint16 effectId, bool enable){ +#if PACKETVER >= 20150422 + unsigned char buf[13]; + + nullpo_retv(bl); + + WBUFW(buf,0) = 0xa3b; + WBUFW(buf,2) = 13; + WBUFL(buf,4) = bl->id; + WBUFB(buf,8) = enable; + WBUFL(buf,9) = effectId; + + clif_send(buf, 13, bl, AREA); +#endif +} + +bool clif_parse_attendance_db(void) +{ + struct config_t attendance_conf; + struct config_setting_t *attendance = NULL, *it = NULL; + const char *config_filename = "db/attendance_db.conf"; // FIXME hardcoded name + int i = 0; + + if (!libconfig->load_file(&attendance_conf, config_filename)) + return false; + attendance = libconfig->lookup(&attendance_conf, "attendance_db"); + + VECTOR_CLEAR(clif->attendance_data); + + while ((it = libconfig->setting_get_elem(attendance, i++))) { + clif->attendancedb_libconfig_sub(it, i, config_filename); + } + + libconfig->destroy(&attendance_conf); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename); + return true; +} + +bool clif_attendancedb_libconfig_sub(struct config_setting_t *it, int n, const char *source) +{ + struct attendance_entry entry = { 0 }; + int i32 = 0; + + nullpo_ret(it); + nullpo_ret(source); + + if (!itemdb->lookup_const(it, "ItemID", &i32) || i32 < 0) { + ShowWarning("clif_attendancedb_libconfig_sub: unknown item %d, entry #%d, skipping.\n", i32, n); + return false; + } + entry.nameid = i32; + + if (!libconfig->setting_lookup_int(it, "Amount", &i32) || i32 < 1) { + ShowWarning("clif_attendancedb_libconfig_sub: invalid amount %d, entry #%d, skipping.\n", i32, n); + return false; + } + entry.qty = i32; + + VECTOR_ENSURE(clif->attendance_data, 1, 1); + VECTOR_PUSH(clif->attendance_data, entry); + return true; +} + +bool clif_attendance_timediff(struct map_session_data *sd) +{ + int64 timediff; + + nullpo_retr(false, sd); + + timediff = (time(NULL) / (60 * 60 * 24)) - (sd->status.attendance_timer / (60 * 60 * 24)); + + if (timediff <= 0) + return false; + return true; +} +time_t clif_attendance_getendtime(void) +{ + time_t timestamp; + struct tm tmtime = { 0 }; + int year = 0, month = 0, day = 0; + char timestring[9]; + + sprintf(timestring, "%8d", battle_config.feature_attendance_endtime); + sscanf(timestring, "%4d%2d%2d", &year, &month, &day); + + tmtime.tm_year = year - 1900; + tmtime.tm_mon = month - 1; + tmtime.tm_mday = day; + + timestamp = mktime(&tmtime); + + return timestamp; +} + +void clif_parse_open_ui_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); +void clif_parse_open_ui_request(int fd, struct map_session_data *sd) +{ + + const struct PACKET_CZ_OPEN_UI *p = RP2PTR(fd); + + if (clif->attendance_getendtime() < time(NULL)) { + clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED); + return; + } + + if (battle_config.feature_enable_attendance_system != 1) + return; + + clif->open_ui(sd, p->UIType); +} + +void clif_open_ui(struct map_session_data *sd, int8 UIType) +{ +#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 + int claimed = 0; + struct PACKET_ZC_OPEN_UI p; + + nullpo_retv(sd); + + p.PacketType = 0xAE2; + switch (UIType) { + case 5: // client will send 5 for the request but requires to receive ATTENDANCE_UI (7) to open the correct ui. + if (clif->attendance_timediff(sd) != true) + ++claimed; + else if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data)) + sd->status.attendance_count = 0; + p.UIType = ATTENDANCE_UI; + p.data = sd->status.attendance_count * 10 + claimed; + break; + default: + ShowWarning("clif_open_ui: Requested UI (%d) is not implemented yet.\n", UIType); + return; + } + + clif->send(&p, sizeof(p), &sd->bl, SELF); +#else + ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404.\n"); +#endif +} + +void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); +void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) +{ +#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 + + struct rodex_message msg = { 0 }; + struct attendance_entry *entry; + int attendance_count; + char title[RODEX_TITLE_LENGTH], body[MAIL_BODY_LENGTH]; + + if (clif->attendance_getendtime() < time(NULL)) { + clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED); + return; + } + + if (battle_config.feature_enable_attendance_system != 1) + return; + + if (clif->attendance_timediff(sd) != true) + return; + + if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data)) + sd->status.attendance_count = 0; + + attendance_count = sd->status.attendance_count; + ++sd->status.attendance_count; + sd->status.attendance_timer = time(NULL); + + msg.receiver_id = sd->status.char_id; + sprintf(title, msg_txt(545), attendance_count + 1); + sprintf(body, msg_txt(545), attendance_count + 1); + + entry = &VECTOR_INDEX(clif->attendance_data, attendance_count); + msg.items[0].item.nameid = entry->nameid; + msg.items[0].item.amount = entry->qty; + msg.items[0].item.identify = 1; + msg.type = MAIL_TYPE_NPC | MAIL_TYPE_ITEM; + + safestrncpy(msg.sender_name, msg_txt(544), NAME_LENGTH); + safestrncpy(msg.title, title, RODEX_TITLE_LENGTH); + safestrncpy(msg.body, body, MAIL_BODY_LENGTH); + msg.send_date = (int)time(NULL); + msg.expire_date = (int)time(NULL) + RODEX_EXPIRE; + + intif->rodex_sendmail(&msg); + clif->ui_action(sd, 0, sd->status.attendance_count); +#else + ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404.\n"); +#endif +} + +void clif_ui_action(struct map_session_data *sd, int32 UIType, int32 data) +{ + + struct PACKET_ZC_UI_ACTION p; + + nullpo_retv(sd); + + p.PacketType = 0xAF0; + p.UIType = UIType; + p.data = data; + + clif->send(&p, sizeof(p), &sd->bl, SELF); +} /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -20790,6 +21172,8 @@ void clif_defaults(void) { clif->msgtable_skill = clif_msgtable_skill; clif->msgtable = clif_msgtable; clif->msgtable_num = clif_msgtable_num; + clif->msgtable_str = clif_msgtable_str; + clif->msgtable_color = clif_msgtable_color; clif->message = clif_displaymessage; clif->messageln = clif_displaymessage2; clif->messages = clif_displaymessage_sprintf; @@ -20924,6 +21308,7 @@ void clif_defaults(void) { clif->quest_delete = clif_quest_delete; clif->quest_update_status = clif_quest_update_status; clif->quest_update_objective = clif_quest_update_objective; + clif->quest_notify_objective = clif_quest_notify_objective; clif->quest_show_event = clif_quest_show_event; /* mail-related */ clif->mail_window = clif_Mail_window; @@ -21318,4 +21703,16 @@ void clif_defaults(void) { clif->clan_leave = clif_clan_leave; clif->clan_message = clif_clan_message; clif->pClanMessage = clif_parse_ClanMessage; + // -- Hat Effect + clif->hat_effect = clif_hat_effect; + clif->hat_effect_single = clif_hat_effect_single; + + clif->pAttendanceDB = clif_parse_attendance_db; + clif->attendancedb_libconfig_sub = clif_attendancedb_libconfig_sub; + clif->attendance_timediff = clif_attendance_timediff; + clif->attendance_getendtime = clif_attendance_getendtime; + clif->pOpenUIRequest = clif_parse_open_ui_request; + clif->open_ui = clif_open_ui; + clif->pAttendanceRewardRequest = clif_parse_attendance_reward_request; + clif->ui_action = clif_ui_action; } diff --git a/src/map/clif.h b/src/map/clif.h index acf79c373..f0eaaf6eb 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -388,6 +388,7 @@ enum clif_messages { MSG_NPC_WORK_IN_PROGRESS = 0x783, // FIXME[Haru]: This seems to be 0x784 in the msgstringtable files I found. MSG_REINS_CANT_USE_MOUNTED = 0x78b, // FIXME[Haru]: This seems to be 0x785 in the msgstringtalbe files I found. MSG_PARTY_LEADER_SAMEMAP = 0x82e, //< It is only possible to change the party leader while on the same map. + MSG_ATTENDANCE_UNAVAILABLE = 0xd92, ///< Attendance Check failed. Please try again later. }; /** @@ -575,6 +576,19 @@ enum CZ_CONFIG { CZ_CONFIG_HOMUNCULUS_AUTOFEEDING = 3, }; /** +* Client UI types +* used with packet 0xAE2 to request the client to open a specific ui +**/ +enum ui_types { + BANK_UI = 0, + STYLIST_UI, + CAPTCHA_UI, + MACRO_UI, + TIPBOX_UI = 5, + RENEWQUEST_UI, + ATTENDANCE_UI +}; +/** * Structures **/ typedef void (*pFunc)(int, struct map_session_data *); //cant help but put it first @@ -599,6 +613,12 @@ struct merge_item { int16 nameid; }; +/* attendance data */ +struct attendance_entry { + int nameid; + int qty; +}; + /** * Clif.c Interface **/ @@ -628,6 +648,8 @@ struct clif_interface { bool ally_only; /* */ struct eri *delayed_damage_ers; + /* */ + VECTOR_DECL(struct attendance_entry) attendance_data; /* core */ int (*init) (bool minimal); void (*final) (void); @@ -886,6 +908,8 @@ struct clif_interface { void (*msgtable) (struct map_session_data* sd, unsigned short msg_id); void (*msgtable_num) (struct map_session_data *sd, unsigned short msg_id, int value); void (*msgtable_skill) (struct map_session_data *sd, uint16 skill_id, int msg_id); + void (*msgtable_str) (struct map_session_data *sd, uint16 msg_id, const char *value); + void (*msgtable_color) (struct map_session_data *sd, uint16 msg_id, uint32 color); void (*message) (const int fd, const char* mes); void (*messageln) (const int fd, const char* mes); /* message+s(printf) */ @@ -1021,6 +1045,7 @@ struct clif_interface { void (*quest_delete) (struct map_session_data *sd, int quest_id); void (*quest_update_status) (struct map_session_data *sd, int quest_id, bool active); void (*quest_update_objective) (struct map_session_data *sd, struct quest *qd); + void (*quest_notify_objective) (struct map_session_data *sd, struct quest *qd); void (*quest_show_event) (struct map_session_data *sd, struct block_list *bl, short state, short color); /* mail-related */ void (*mail_window) (int fd, int flag); @@ -1413,6 +1438,18 @@ struct clif_interface { void (*clan_leave) (struct map_session_data *sd); void (*clan_message) (struct clan *c, const char *mes, int len); void (*pClanMessage) (int fd, struct map_session_data* sd); + /* Hat Effect */ + void (*hat_effect) (struct block_list *bl, struct block_list *tbl, enum send_target target); + void (*hat_effect_single) (struct block_list *bl, uint16 effectId, bool enable); + + bool (*pAttendanceDB) (void); + bool (*attendancedb_libconfig_sub) (struct config_setting_t *it, int n, const char *source); + bool (*attendance_timediff) (struct map_session_data *sd); + time_t (*attendance_getendtime) (void); + void (*pOpenUIRequest) (int fd, struct map_session_data *sd); + void (*open_ui) (struct map_session_data *sd, int8 UIType); + void (*pAttendanceRewardRequest) (int fd, struct map_session_data *sd); + void (*ui_action) (struct map_session_data *sd, int32 UIType, int32 data); }; #ifdef HERCULES_CORE diff --git a/src/map/guild.c b/src/map/guild.c index 11609ec81..d33df5e08 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -275,6 +275,7 @@ void guild_makemember(struct guild_member *m,struct map_session_data *sd) m->online = 1; m->position = MAX_GUILDPOSITION-1; memcpy(m->name,sd->status.name,NAME_LENGTH); + m->last_login = (uint32)time(NULL); // When player create or join a guild the date is updated return; } @@ -1001,7 +1002,7 @@ int guild_send_memberinfoshort(struct map_session_data *sd,int online) return 0; } -int guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class) +int guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login) { // cleaned up [LuzZza] int i, alv, c, idx = INDEX_NOT_FOUND, om = 0, oldonline = -1; struct guild *g = guild->search(guild_id); @@ -1017,6 +1018,7 @@ int guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int on m->online=online; m->lv=lv; m->class = class; + m->last_login = last_login; idx=i; } alv+=m->lv; diff --git a/src/map/guild.h b/src/map/guild.h index 9296f9ec0..d6bba2a56 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -126,7 +126,7 @@ struct guild_interface { int (*check_alliance) (int guild_id1, int guild_id2, int flag); /* */ int (*send_memberinfoshort) (struct map_session_data *sd,int online); - int (*recv_memberinfoshort) (int guild_id, int account_id, int char_id, int online, int lv, int16 class); + int (*recv_memberinfoshort) (int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login); int (*change_memberposition) (int guild_id,int account_id,int char_id,short idx); int (*memberposition_changed) (struct guild *g,int idx,int pos); int (*change_position) (int guild_id,int idx,int mode,int exp_mode,const char *name); diff --git a/src/map/intif.c b/src/map/intif.c index f656a0df9..e9bf0e96b 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1494,7 +1494,7 @@ void intif_parse_GuildMemberWithdraw(int fd) { // ACK guild member basic info void intif_parse_GuildMemberInfoShort(int fd) { - guild->recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17)); + guild->recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17),RFIFOL(fd,19)); } // ACK guild break @@ -2846,7 +2846,7 @@ void intif_defaults(void) { -1,-1,27,-1, -1,-1,37,-1, 7, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 - 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 + 10,-1,15, 0, 79,23, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 -1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 -1,-1, 7, 7, 7,11, 8, 0, 10, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari] Clan System[Murilo BiO] -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish] diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 17a73400a..7f0ebb39c 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -2387,6 +2387,8 @@ void itemdb_read(bool minimal) { if (minimal) return; + itemdb->name_constants(); + itemdb->read_combos(); itemdb->read_groups(); itemdb->read_chains(); @@ -2619,6 +2621,7 @@ void do_final_itemdb(void) { itemdb->options->destroy(itemdb->options, itemdb->options_final_sub); itemdb->destroy_item_data(&itemdb->dummy, 0); db_destroy(itemdb->names); + VECTOR_CLEAR(clif->attendance_data); } void do_init_itemdb(bool minimal) { @@ -2637,6 +2640,8 @@ void do_init_itemdb(bool minimal) { /** it failed? we disable it **/ if (battle_config.feature_roulette == 1 && !clif->parse_roulette_db()) battle_config.feature_roulette = 0; + VECTOR_INIT(clif->attendance_data); + clif->pAttendanceDB(); } void itemdb_defaults(void) { itemdb = &itemdb_s; diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 5344a7cd6..b170059ca 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -137,6 +137,8 @@ enum item_itemid { ITEMID_MAGIC_CASTLE = 12308, ITEMID_BULGING_HEAD = 12309, ITEMID_THICK_MANUAL50 = 12312, + ITEMID_N_FLY_WING = 12323, + ITEMID_N_BUTTERFLY_WING = 12324, ITEMID_N_MAGNIFIER = 12325, ITEMID_ANSILA = 12333, ITEMID_REPAIRA = 12392, @@ -162,6 +164,7 @@ enum item_itemid { ITEMID_THURISAZ = 12731, ITEMID_WYRD = 12732, ITEMID_HAGALAZ = 12733, + ITEMID_C_WING_OF_FLY = 12887, ITEMID_DUN_TELE_SCROLL1 = 14527, ITEMID_BATTLE_MANUAL25 = 14532, ITEMID_BATTLE_MANUAL100 = 14533, diff --git a/src/map/packets.h b/src/map/packets.h index 462efd31b..db98cdc28 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -3427,7 +3427,7 @@ packet(0x96e,-1,clif->ackmergeitems); // 2016-03-23aRagexeRE #if PACKETVER >= 20160323 // new packets - packet(0x0a68,3); + packet(0x0a68,3,clif->pOpenUIRequest); packet(0x0a69,6); packet(0x0a6a,12); packet(0x0a6b,-1); @@ -3970,7 +3970,7 @@ packet(0x96e,-1,clif->ackmergeitems); #if PACKETVER >= 20180117 // new packets - packet(0x0aef,2); + packet(0x0aef,2,clif->pAttendanceRewardRequest); packet(0x0af0,10); // changed packet sizes packet(0x0ae9,13); @@ -4044,4 +4044,47 @@ packet(0x96e,-1,clif->ackmergeitems); #endif #endif // PACKETVER_ZERO +#ifndef PACKETVER_ZERO +// 2018-03-21aRagexe, 2018-03-21aRagexeRE +#if PACKETVER >= 20180321 +// new packets + packet(0x0af8,11,clif->pDull/*,XXX*/); +// changed packet sizes + packet(0x0ae7,34,clif->pDull/*,XXX*/); +#endif +#endif // PACKETVER_ZERO + +#ifdef PACKETVER_ZERO +// 2018-03-28_1aRagexe_zero +#if PACKETVER >= 20180328 +// new packets + packet(0x0af8,11,clif->pDull/*,XXX*/); + packet(0x0af9,6,clif->pDull/*,XXX*/); + packet(0x0afa,54,clif->pDull/*,XXX*/); +// changed packet sizes + packet(0x0206,35); // ZC_FRIENDS_STATE + packet(0x0ae7,38,clif->pDull/*,XXX*/); +#endif +#endif // PACKETVER_ZERO + + +#ifndef PACKETVER_ZERO +// 2018-04-04bRagexe, 2018-04-04cRagexeRE +#if PACKETVER >= 20180404 +// new packets + packet(0x0af9,6,clif->pDull/*,XXX*/); + packet(0x0afa,54,clif->pDull/*,XXX*/); +// changed packet sizes + packet(0x0ae7,38,clif->pDull/*,XXX*/); +#endif +#endif // PACKETVER_ZERO + +#ifdef PACKETVER_RE +// 2018-04-04cRagexeRE +#if PACKETVER >= 20180404 +// changed packet sizes + packet(0x0821,102,clif->pDull/*,XXX*/); // AC_OTP_USER +#endif +#endif + #endif /* MAP_PACKETS_H */ diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h index 066e7d2c3..150fb486a 100644 --- a/src/map/packets_keys_main.h +++ b/src/map/packets_keys_main.h @@ -874,11 +874,15 @@ packetKeys(0x6A596301,0x76866D0E,0x32294A45); #endif -// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe +// 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 #if PACKETVER == 20131223 || \ PACKETVER == 20140508 || \ PACKETVER == 20140611 || \ - PACKETVER == 20150225 + PACKETVER == 20150225 || \ + PACKETVER == 20180315 || \ + PACKETVER == 20180321 || \ + PACKETVER == 20180328 || \ + PACKETVER >= 20180404 packetKeys(0x00000000,0x00000000,0x00000000); #endif @@ -1976,5 +1980,10 @@ packetKeys(0x47DA10EB,0x4B922CCF,0x765C5055); #endif +// 2018-03-14nRagexe +#if PACKETVER == 20180314 + packetKeys(0x2FF07149,0x00596EA3,0x2B853026); +#endif + #endif /* MAP_PACKETS_MAIN_KEYS_H */ diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h index 75196e6b4..2bd6f1604 100644 --- a/src/map/packets_keys_zero.h +++ b/src/map/packets_keys_zero.h @@ -29,7 +29,7 @@ /* This file is autogenerated, please do not commit manual changes */ -// 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 +// 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 #if PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ PACKETVER == 20171024 || \ @@ -38,7 +38,10 @@ PACKETVER == 20171030 || \ PACKETVER == 20171031 || \ PACKETVER == 20171109 || \ - PACKETVER == 20171113 + PACKETVER == 20171113 || \ + PACKETVER == 20180315 || \ + PACKETVER == 20180321 || \ + PACKETVER == 20180328 packetKeys(0x00000000,0x00000000,0x00000000); #endif @@ -141,5 +144,10 @@ packetKeys(0x56C82ABE,0x61AE2B2E,0x472E272E); #endif +// 2018-03-14nRagexe_zero +#if PACKETVER == 20180314 + packetKeys(0x2FC330DD,0x01C04E1F,0x4D914DE2); +#endif + #endif /* MAP_PACKETS_ZERO_KEYS_H */ diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h index aabf9c3f3..16d480893 100644 --- a/src/map/packets_shuffle_main.h +++ b/src/map/packets_shuffle_main.h @@ -3178,41 +3178,6 @@ packet(0x096a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER #endif -// 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe -#if PACKETVER == 20140508 || \ - PACKETVER == 20140611 || \ - PACKETVER == 20150225 - packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS - packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER - packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD - packet(0x0281,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK - packet(0x02c4,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ - packet(0x035f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE - packet(0x0360,6,clif->pTickSend,2); // CZ_REQUEST_TIME - packet(0x0361,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION - packet(0x0362,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP - packet(0x0363,6,clif->pDropItem,2,4); // CZ_ITEM_THROW - packet(0x0364,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE - packet(0x0365,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY - packet(0x0366,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND - packet(0x0367,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX - packet(0x0368,6,clif->pGetCharNameRequest,2); // CZ_REQNAME - packet(0x0369,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID - packet(0x0436,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER - packet(0x0437,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT - packet(0x0438,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL - packet(0x07e4,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES - packet(0x07ec,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD - packet(0x0802,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER - packet(0x0811,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE - packet(0x0815,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE - packet(0x0817,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE - packet(0x0819,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE - packet(0x0835,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO - packet(0x0838,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE - packet(0x083c,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK -#endif - // 2014-05-14bRagexe, 2014-05-14bRagexeRE, 2014-05-14cRagexeRE #if PACKETVER == 20140514 packet(0x0437,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK @@ -3380,6 +3345,44 @@ packet(0x0969,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE #endif +// 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 +#if PACKETVER == 20140611 || \ + PACKETVER == 20150225 || \ + PACKETVER == 20180315 || \ + PACKETVER == 20180321 || \ + PACKETVER == 20180328 || \ + PACKETVER >= 20180404 + packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS + packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER + packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD + packet(0x0281,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK + packet(0x02c4,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ + packet(0x035f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE + packet(0x0360,6,clif->pTickSend,2); // CZ_REQUEST_TIME + packet(0x0361,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION + packet(0x0362,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP + packet(0x0363,6,clif->pDropItem,2,4); // CZ_ITEM_THROW + packet(0x0364,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE + packet(0x0365,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY + packet(0x0366,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND + packet(0x0367,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX + packet(0x0368,6,clif->pGetCharNameRequest,2); // CZ_REQNAME + packet(0x0369,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID + packet(0x0436,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER + packet(0x0437,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT + packet(0x0438,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL + packet(0x07e4,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES + packet(0x07ec,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD + packet(0x0802,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER + packet(0x0811,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE + packet(0x0815,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE + packet(0x0817,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE + packet(0x0819,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE + packet(0x0835,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO + packet(0x0838,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE + packet(0x083c,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK +#endif + // 2014-06-18aRagexe, 2014-06-18cRagexeRE #if PACKETVER == 20140618 packet(0x085d,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE @@ -9667,5 +9670,38 @@ packet(0x0969,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT #endif +// 2018-03-14nRagexe +#if PACKETVER == 20180314 + packet(0x0361,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK + packet(0x0366,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL + packet(0x0369,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER + packet(0x0436,6,clif->pDropItem,2,4); // CZ_ITEM_THROW + packet(0x085a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME + packet(0x0862,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP + packet(0x0863,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES + packet(0x0868,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD + packet(0x086e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY + packet(0x0874,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE + packet(0x087a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER + packet(0x0888,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION + packet(0x088a,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND + packet(0x088d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD + packet(0x0894,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE + packet(0x089b,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX + packet(0x0921,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT + packet(0x0927,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE + packet(0x092f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE + packet(0x0933,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE + packet(0x0935,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ + packet(0x0945,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER + packet(0x094d,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE + packet(0x094e,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS + packet(0x0956,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK + packet(0x0959,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE + packet(0x095f,6,clif->pTickSend,2); // CZ_REQUEST_TIME + packet(0x0962,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO + packet(0x0967,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID +#endif + #endif /* MAP_PACKETS_SHUFFLE_MAIN_H */ diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h index 463ab1679..7cd52d971 100644 --- a/src/map/packets_shuffle_zero.h +++ b/src/map/packets_shuffle_zero.h @@ -36,7 +36,7 @@ /* This file is autogenerated, please do not commit manual changes */ -// 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 +// 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 #if PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ PACKETVER == 20171024 || \ @@ -45,7 +45,10 @@ PACKETVER == 20171030 || \ PACKETVER == 20171031 || \ PACKETVER == 20171109 || \ - PACKETVER == 20171113 + PACKETVER == 20171113 || \ + PACKETVER == 20180315 || \ + PACKETVER == 20180321 || \ + PACKETVER == 20180328 packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD @@ -652,5 +655,38 @@ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME #endif +// 2018-03-14nRagexe_zero +#if PACKETVER == 20180314 + packet(0x023b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ + packet(0x0438,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE + packet(0x07ec,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER + packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE + packet(0x083c,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION + packet(0x085d,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS + packet(0x085f,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE + packet(0x0866,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER + packet(0x0878,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD + packet(0x088d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD + packet(0x0891,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY + packet(0x0897,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP + packet(0x0899,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE + packet(0x089e,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES + packet(0x08a1,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK + packet(0x0917,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO + packet(0x0918,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT + packet(0x091f,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND + packet(0x0920,6,clif->pTickSend,2); // CZ_REQUEST_TIME + packet(0x0923,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK + packet(0x0930,6,clif->pDropItem,2,4); // CZ_ITEM_THROW + packet(0x0931,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE + packet(0x093f,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID + packet(0x0946,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX + packet(0x094a,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL + packet(0x094e,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE + packet(0x0954,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER + packet(0x0956,6,clif->pGetCharNameRequest,2); // CZ_REQNAME + packet(0x0958,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE +#endif + #endif /* MAP_PACKETS_SHUFFLE_ZERO_H */ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 2a65eb6cf..438084778 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -302,7 +302,7 @@ enum packet_headers { rouletteinfoackType = 0xa1c, roulettgenerateackType = 0xa20, roulettercvitemackType = 0xa22, -#if 0 // Unknown +#if PACKETVER >= 20150513 // [4144] 0x09f8 handling in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE questListType = 0x9f8, ///< ZC_ALL_QUEST_LIST3 #elif PACKETVER >= 20141022 questListType = 0x97a, ///< ZC_ALL_QUEST_LIST2 @@ -357,6 +357,17 @@ enum packet_headers { clanLeave = 0x0989, ///< ZC_ACK_CLAN_LEAVE clanMessage = 0x098E, ///< ZC_NOTIFY_CLAN_CHAT #endif +#if PACKETVER >= 20150513 // [4144] 0x09f9 handled in client from 2014-10-29aRagexe and 2014-03-26cRagexeRE + questAddType = 0x9f9, +#else + questAddType = 0x2b3, +#endif // PACKETVER < 20150513 +#if PACKETVER >= 20150513 + questUpdateType = 0x9fa, +#else + questUpdateType = 0x2b5, +#endif // PACKETVER < 20150513 + questUpdateType2 = 0x8fe, }; #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute @@ -1248,10 +1259,19 @@ struct packet_hotkey { } __attribute__((packed)); /** - * MISSION_HUNT_INFO + * MISSION_HUNT_INFO (PACKETVER >= 20141022) + * MISSION_HUNT_INFO_EX (PACKETVER >= 20150513) */ struct packet_mission_info_sub { - int32 mob_id; +#if PACKETVER >= 20150513 + uint32 huntIdent; + uint32 mobType; +#endif + uint32 mob_id; +#if PACKETVER >= 20150513 + int16 levelMin; + int16 levelMax; +#endif int16 huntCount; int16 maxCount; char mobName[NAME_LENGTH]; @@ -1259,7 +1279,7 @@ struct packet_mission_info_sub { /** * PACKET_ZC_ALL_QUEST_LIST2_INFO (PACKETVER >= 20141022) - * PACKET_ZC_ALL_QUEST_LIST3_INFO (PACKETVER Unknown) / unused + * PACKET_ZC_ALL_QUEST_LIST3_INFO (PACKETVER >= 20150513) */ struct packet_quest_list_info { int32 questID; @@ -1276,7 +1296,7 @@ struct packet_quest_list_info { * Header for: * PACKET_ZC_ALL_QUEST_LIST (PACKETVER < 20141022) * PACKET_ZC_ALL_QUEST_LIST2 (PACKETVER >= 20141022) - * PACKET_ZC_ALL_QUEST_LIST3 (PACKETVER Unknown) / unused + * PACKET_ZC_ALL_QUEST_LIST3 (PACKETVER >= 20150513) * * @remark * Contains (is followed by) a variable-length array of packet_quest_list_info @@ -1598,6 +1618,117 @@ struct PACKET_ZC_NOTIFY_CLAN_CHAT { char Message[]; } __attribute__((packed)); +/** + * PACKET_ZC_MISSION_HUNT (PACKETVER < 20150513) + * PACKET_ZC_MISSION_HUNT_EX (PACKETVER >= 20150513) + */ +struct packet_quest_hunt_sub { +#if PACKETVER >= 20150513 + uint32 huntIdent; + uint32 mobType; +#endif + uint32 mob_id; +#if PACKETVER >= 20150513 + int16 levelMin; + int16 levelMax; +#endif + int16 huntCount; + char mobName[NAME_LENGTH]; +} __attribute__((packed)); + +/** + * Header for: + * PACKET_ZC_ADD_QUEST (PACKETVER < 20150513) + * PACKET_ZC_ADD_QUEST_EX (PACKETVER >= 20150513) + */ +struct packet_quest_add_header { + uint16 PacketType; + uint32 questID; + uint8 active; + int32 quest_svrTime; + int32 quest_endTime; + int16 count; + struct packet_quest_hunt_sub objectives[]; +} __attribute__((packed)); + +/** + * PACKET_MOB_HUNTING (PACKETVER < 20150513) + * PACKET_MOB_HUNTING_EX (PACKETVER >= 20150513) + */ +struct packet_quest_update_hunt { + uint32 questID; +#if PACKETVER >= 20150513 + uint32 huntIdent; +#else + uint32 mob_id; +#endif // PACKETVER < 20150513 + int16 maxCount; + int16 count; +} __attribute__((packed)); + +/** + * Header for: + * PACKET_ZC_UPDATE_MISSION_HUNT (PACKETVER < 20150513) + * PACKET_ZC_UPDATE_MISSION_HUNT_EX (PACKETVER >= 20150513) + */ +struct packet_quest_update_header { + uint16 PacketType; + uint16 PacketLength; + int16 count; + struct packet_quest_update_hunt objectives[]; +} __attribute__((packed)); + +/** + * Header for: + * PACKET_MOB_HUNTING (PACKETVER >= 20150513) + */ +struct packet_quest_hunt_info_sub { + uint32 questID; + uint32 mob_id; + int16 maxCount; + int16 count; +} __attribute__((packed)); + +/** + * Header for: + * ZC_HUNTING_QUEST_INFO (PACKETVER >= 20150513) + */ +struct packet_quest_hunt_info { + uint16 PacketType; + uint16 PacketLength; + struct packet_quest_hunt_info_sub info[]; +} __attribute__((packed)); + +struct PACKET_ZC_FORMATSTRING_MSG { + uint16 PacketType; + uint16 PacketLength; + uint16 MessageId; + char MessageString[]; +} __attribute__((packed)); + +struct PACKET_ZC_MSG_COLOR { + uint16 PacketType; + uint16 MessageId; + uint32 MessageColor; +} __attribute__((packed)); + +struct PACKET_CZ_OPEN_UI { + int16 PacketType; + int8 UIType; +} __attribute__((packed)); + +struct PACKET_ZC_OPEN_UI { + int16 PacketType; + int8 UIType; + int32 data; +} __attribute__((packed)); + +struct PACKET_ZC_UI_ACTION { + int16 PacketType; + int32 UIType; + int32 data; +} __attribute__((packed)); + #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 cd4b2a54f..ee1fcd7da 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1293,6 +1293,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim VECTOR_INIT(sd->script_queues); VECTOR_INIT(sd->storage.item); // initialize storage item vector. + VECTOR_INIT(sd->hatEffectId); sd->state.dialog = 0; @@ -4901,15 +4902,16 @@ int pc_isUseitem(struct map_session_data *sd,int n) return 0; // You cannot use this item while sitting. } - if (sd->state.storage_flag != STORAGE_FLAG_CLOSED && item->type != IT_CASH) { - clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1475)); - return 0; // You cannot use this item while storage is open. - } - switch( nameid ) { // TODO: Is there no better way to handle this, other than hardcoding item IDs? case ITEMID_ANODYNE: - if (map_flag_gvg2(sd->bl.m)) + if (map_flag_gvg2(sd->bl.m)) { +#if PACKETVER >= 20080311 + clif->skill_mapinfomessage(sd, 3); +#else + clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 51)); +#endif return 0; + } break; case ITEMID_GIANT_FLY_WING: { @@ -4943,12 +4945,19 @@ int pc_isUseitem(struct map_session_data *sd,int n) } FALLTHROUGH case ITEMID_WING_OF_FLY: + case ITEMID_N_FLY_WING: + case ITEMID_C_WING_OF_FLY: if (map->list[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m)) { +#if PACKETVER >= 20080311 clif->skill_mapinfomessage(sd, 0); +#else + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd, 49)); +#endif return 0; } /* Fall through */ case ITEMID_WING_OF_BUTTERFLY: + case ITEMID_N_BUTTERFLY_WING: case ITEMID_DUN_TELE_SCROLL1: case ITEMID_DUN_TELE_SCROLL2: case ITEMID_WOB_RUNE: // Yellow Butterfly Wing @@ -4960,15 +4969,27 @@ int pc_isUseitem(struct map_session_data *sd,int n) clif->message(sd->fd, msg_sd(sd,863)); // "Duel: Can't use this item in duel." return 0; } - if( nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && map->list[sd->bl.m].flag.noreturn ) + if (nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && map->list[sd->bl.m].flag.noreturn) { +#if PACKETVER >= 20080311 + clif->skill_mapinfomessage(sd, 0); +#else + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd, 49)); +#endif return 0; + } break; case ITEMID_BRANCH_OF_DEAD_TREE: case ITEMID_RED_POUCH_OF_SURPRISE: case ITEMID_BLOODY_DEAD_BRANCH: case ITEMID_PORING_BOX: - if( map->list[sd->bl.m].flag.nobranch || map_flag_gvg2(sd->bl.m) ) + if (map->list[sd->bl.m].flag.nobranch || map_flag_gvg2(sd->bl.m)) { +#if PACKETVER >= 20080311 + clif->skill_mapinfomessage(sd, 3); +#else + clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 51)); +#endif return 0; + } break; // Mercenary Items @@ -4988,8 +5009,14 @@ int pc_isUseitem(struct map_session_data *sd,int n) break; case ITEMID_NEURALIZER: - if( !map->list[sd->bl.m].flag.reset ) + if (!map->list[sd->bl.m].flag.reset) { +#if PACKETVER >= 20080311 + clif->skill_mapinfomessage(sd, 3); +#else + clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 51)); +#endif return 0; + } break; } @@ -5092,6 +5119,11 @@ int pc_useitem(struct map_session_data *sd,int n) { return 0; } + if (battle_config.storage_use_item == 1 && sd->state.storage_flag != STORAGE_FLAG_CLOSED) { + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd, 1475)); + return 0; // You cannot use this item while storage is open. + } + if( sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0 ) return 0; @@ -5178,7 +5210,11 @@ int pc_useitem(struct map_session_data *sd,int n) { /* on restricted maps the item is consumed but the effect is not used */ for(i = 0; i < map->list[sd->bl.m].zone->disabled_items_count; i++) { if( map->list[sd->bl.m].zone->disabled_items[i] == nameid ) { - clif->msgtable(sd, MSG_ITEM_CANT_USE_AREA); // This item cannot be used within this area +#if PACKETVER >= 20080311 + clif->skill_mapinfomessage(sd, 3); +#else + clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 50)); +#endif if( battle_config.item_restricted_consumption_type && sd->status.inventory[n].expire_time == 0 ) { clif->useitemack(sd,n,sd->status.inventory[n].amount-1,true); pc->delitem(sd, n, 1, 1, DELITEM_NORMAL, LOG_TYPE_CONSUME); diff --git a/src/map/pc.h b/src/map/pc.h index a01152df5..e699e5750 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -618,6 +618,9 @@ END_ZEROED_BLOCK; const char* delunit_prevfile; int delunit_prevline; + // HatEffect + VECTOR_DECL(int) hatEffectId; + }; #define EQP_WEAPON EQP_HAND_R diff --git a/src/map/pet.c b/src/map/pet.c index 2997a4b5a..57800dc0a 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -39,6 +39,7 @@ #include "map/skill.h" #include "map/status.h" #include "map/unit.h" +#include "common/conf.h" #include "common/db.h" #include "common/ers.h" #include "common/memmgr.h" @@ -1199,145 +1200,213 @@ int pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) { return 0; } -/** - * Loads (or reloads) the pet database. - */ -int read_petdb(void) +void pet_read_db(void) { const char *filename[] = { - DBPATH"pet_db.txt", - "pet_db2.txt", + DBPATH"pet_db.conf", + "pet_db2.conf" }; - int i,j; + int i; - // Remove any previous scripts in case reloaddb was invoked. - for (j = 0; j < MAX_PET_DB; j++) { - if (pet->db[j].pet_script) { - script->free_code(pet->db[j].pet_script); - pet->db[j].pet_script = NULL; - } - if (pet->db[j].equip_script) { - script->free_code(pet->db[j].equip_script); - pet->db[j].equip_script = NULL; + pet->read_db_clear(); + + for (i = 0; i < ARRAYLENGTH(filename); ++i) { + pet->read_db_libconfig(filename[i], i > 0 ? true : false); + } +} + +int pet_read_db_libconfig(const char *filename, bool ignore_missing) +{ + struct config_t pet_db_conf; + struct config_setting_t *pdb; + struct config_setting_t *t; + char filepath[256]; + bool duplicate[MAX_MOB_DB] = { 0 }; + int i = 0, count = 0; + + nullpo_ret(filename); + + safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, filename); + + if (!exists(filepath)) { + if (!ignore_missing) { + ShowError("pet_read_db_libconfig: can't find file %s\n", filepath); } + return 0; } - // clear database - memset(pet->db,0,sizeof(pet->db)); + if (!libconfig->load_file(&pet_db_conf, filepath)) + return 0; - j = 0; // entry counter - for (i = 0; i < ARRAYLENGTH(filename); i++) { - char line[1024]; - int lines, entries; - FILE *fp; - - sprintf(line, "%s/%s", map->db_path, filename[i]); - fp=fopen(line,"r"); - if (fp == NULL) { - if (i == 0) - ShowError("can't read %s\n",line); + if ((pdb = libconfig->setting_get_member(pet_db_conf.root, "pet_db")) == NULL) { + ShowError("can't read %s\n", filepath); + return 0; + } + + while ((t = libconfig->setting_get_elem(pdb, i++))) { + int pet_id = pet->read_db_sub(t, i - 1, filename); + + if (pet_id <= 0 || pet_id >= MAX_MOB_DB) continue; + + if (duplicate[pet_id]) { + ShowWarning("pet_read_db_libconfig:%s: duplicate entry of ID #%d\n", filename, pet_id); + } else { + duplicate[pet_id] = true; } - lines = entries = 0; - while (fgets(line, sizeof(line), fp) && j < MAX_PET_DB) { - char *str[22], *p; - int nameid, k; - lines++; - - if (line[0] == '/' && line[1] == '/') - continue; - memset(str, 0, sizeof(str)); - p = line; - while (ISSPACE(*p)) - ++p; - if (*p == '\0') - continue; // empty line - for (k = 0; k < 20; ++k) { - str[k] = p; - p = strchr(p,','); - if (p == NULL) - break; // comma not found - *p = '\0'; - ++p; - } + count++; + } + libconfig->destroy(&pet_db_conf); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename); - if (p == NULL) { - ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines); - continue; - } + return count; +} - // Pet Script - if (*p != '{') { - ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines); - continue; - } +int pet_read_db_sub(struct config_setting_t *it, int n, const char *source) +{ + struct config_setting_t *t = NULL; + struct item_data *data = NULL; + const char *str = NULL; + int i32 = 0; - str[20] = p; - p = strstr(p+1,"},"); - if (p == NULL) { - ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines); - continue; - } - p[1] = '\0'; - p += 2; + nullpo_ret(it); + nullpo_ret(source); + Assert_ret(n >= 0 && n < MAX_PET_DB); - // Equip Script - if (*p != '{') { - ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines); - continue; - } - str[21] = p; + if (!libconfig->setting_lookup_int(it, "Id", &i32)) { + ShowWarning("pet_read_db_sub: Missing Id in \"%s\", entry #%d, skipping.\n", source, n); + return 0; + } + pet->db[n].class_ = i32; - nameid = atoi(str[0]); - if (nameid <= 0) - continue; + if (!libconfig->setting_lookup_string(it, "SpriteName", &str) || !*str ) { + ShowWarning("pet_read_db_sub: Missing SpriteName in pet %d of \"%s\", skipping.\n", pet->db[n].class_, source); + return 0; + } + safestrncpy(pet->db[n].name, str, sizeof(pet->db[n].name)); - if (!mob->db_checkid(nameid)) { - ShowWarning("pet_db reading: Invalid mob-class %d, pet not read.\n", nameid); - continue; - } + if (!libconfig->setting_lookup_string(it, "Name", &str) || !*str) { + ShowWarning("pet_read_db_sub: Missing Name in pet %d of \"%s\", skipping.\n", pet->db[n].class_, source); + return 0; + } + safestrncpy(pet->db[n].jname, str, sizeof(pet->db[n].jname)); - pet->db[j].class_ = nameid; - safestrncpy(pet->db[j].name,str[1],NAME_LENGTH); - safestrncpy(pet->db[j].jname,str[2],NAME_LENGTH); - pet->db[j].itemID=atoi(str[3]); - pet->db[j].EggID=atoi(str[4]); - pet->db[j].AcceID=atoi(str[5]); - pet->db[j].FoodID=atoi(str[6]); - pet->db[j].fullness=atoi(str[7]); - pet->db[j].hungry_delay=atoi(str[8])*1000; - pet->db[j].r_hungry=atoi(str[9]); - if (pet->db[j].r_hungry <= 0) - pet->db[j].r_hungry=1; - pet->db[j].r_full=atoi(str[10]); - pet->db[j].intimate=atoi(str[11]); - pet->db[j].die=atoi(str[12]); - pet->db[j].capture=atoi(str[13]); - pet->db[j].speed=atoi(str[14]); - pet->db[j].s_perfor=(char)atoi(str[15]); - pet->db[j].talk_convert_class=atoi(str[16]); - pet->db[j].attack_rate=atoi(str[17]); - pet->db[j].defence_attack_rate=atoi(str[18]); - pet->db[j].change_target_rate=atoi(str[19]); - pet->db[j].pet_script = NULL; - pet->db[j].equip_script = NULL; - - if (*str[20]) - pet->db[j].pet_script = script->parse(str[20], filename[i], lines, 0, NULL); - if (*str[21]) - pet->db[j].equip_script = script->parse(str[21], filename[i], lines, 0, NULL); - - j++; - entries++; + if (libconfig->setting_lookup_string(it, "TamingItem", &str)) { + if (!(data = itemdb->name2id(str))) { + ShowWarning("pet_read_db_sub: Invalid item '%s' in pet %d of \"%s\", defaulting to 0.\n", str, pet->db[n].class_, source); + } else { + pet->db[n].itemID = (uint16)data->nameid; } + } - if (j >= MAX_PET_DB) - ShowWarning("read_petdb: Reached max number of pets [%d]. Remaining pets were not read.\n ", MAX_PET_DB); - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n", entries, filename[i]); + if (libconfig->setting_lookup_string(it, "EggItem", &str)) { + if (!(data = itemdb->name2id(str))) { + ShowWarning("pet_read_db_sub: Invalid item '%s' in pet %d of \"%s\", defaulting to 0.\n", str, pet->db[n].class_, source); + } else { + pet->db[n].EggID = (uint16)data->nameid; + } } - return 0; + + if (libconfig->setting_lookup_string(it, "AccessoryItem", &str)) { + if (!(data = itemdb->name2id(str))) { + ShowWarning("pet_read_db_sub: Invalid item '%s' in pet %d of \"%s\", defaulting to 0.\n", str, pet->db[n].class_, source); + } else { + pet->db[n].AcceID = (uint16)data->nameid; + } + } + + if (libconfig->setting_lookup_string(it, "FoodItem", &str)) { + if (!(data = itemdb->name2id(str))) { + ShowWarning("pet_read_db_sub: Invalid item '%s' in pet %d of \"%s\", defaulting to 0.\n", str, pet->db[n].class_, source); + } else { + pet->db[n].FoodID = (uint16)data->nameid; + } + } + + if (libconfig->setting_lookup_int(it, "FoodEffectiveness", &i32)) + pet->db[n].fullness = i32; + + if (libconfig->setting_lookup_int(it, "HungerDelay", &i32)) + pet->db[n].hungry_delay = i32 * 1000; + + if ((t = libconfig->setting_get_member(it, "Intimacy"))) { + if (config_setting_is_group(t)) { + pet->read_db_sub_intimacy(n, t); + } + } + if (pet->db[n].r_hungry <= 0) + pet->db[n].r_hungry = 1; + + if (libconfig->setting_lookup_int(it, "CaptureRate", &i32)) + pet->db[n].capture = i32; + + if (libconfig->setting_lookup_int(it, "Speed", &i32)) + pet->db[n].speed = i32; + + if ((t = libconfig->setting_get_member(it, "SpecialPerformance")) && (i32 = libconfig->setting_get_bool(t))) + pet->db[n].s_perfor = (char)i32; + + if ((t = libconfig->setting_get_member(it, "TalkWithEmotes")) && (i32 = libconfig->setting_get_bool(t))) + pet->db[n].talk_convert_class = i32; + + if (libconfig->setting_lookup_int(it, "AttackRate", &i32)) + pet->db[n].attack_rate = i32; + + if (libconfig->setting_lookup_int(it, "DefendRate", &i32)) + pet->db[n].defence_attack_rate = i32; + + if (libconfig->setting_lookup_int(it, "ChangeTargetRate", &i32)) + pet->db[n].change_target_rate = i32; + + if (libconfig->setting_lookup_string(it, "PetScript", &str)) + pet->db[n].pet_script = *str ? script->parse(str, source, -pet->db[n].class_, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + + if (libconfig->setting_lookup_string(it, "EquipScript", &str)) + pet->db[n].equip_script = *str ? script->parse(str, source, -pet->db[n].class_, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + + return pet->db[n].class_; +} + +bool pet_read_db_sub_intimacy(int idx, struct config_setting_t *t) +{ + int i32 = 0; + + nullpo_retr(false, t); + Assert_ret(idx >= 0 && idx < MAX_PET_DB); + + if (libconfig->setting_lookup_int(t, "Initial", &i32)) + pet->db[idx].intimate = i32; + + if (libconfig->setting_lookup_int(t, "FeedIncrement", &i32)) + pet->db[idx].r_hungry = i32; + + if (libconfig->setting_lookup_int(t, "OverFeedDecrement", &i32)) + pet->db[idx].r_full = i32; + + if (libconfig->setting_lookup_int(t, "OwnerDeathDecrement", &i32)) + pet->db[idx].die = i32; + + return true; +} + +void pet_read_db_clear(void) +{ + int i; + + // Remove any previous scripts in case reloaddb was invoked. + for (i = 0; i < MAX_PET_DB; i++) { + if (pet->db[i].pet_script) { + script->free_code(pet->db[i].pet_script); + pet->db[i].pet_script = NULL; + } + if (pet->db[i].equip_script) { + script->free_code(pet->db[i].equip_script); + pet->db[i].equip_script = NULL; + } + } + memset(pet->db, 0, sizeof(pet->db)); + return; } /*========================================== @@ -1428,5 +1497,10 @@ void pet_defaults(void) { pet->skill_bonus_timer = pet_skill_bonus_timer; pet->recovery_timer = pet_recovery_timer; pet->skill_support_timer = pet_skill_support_timer; - pet->read_db = read_petdb; + + pet->read_db = pet_read_db; + pet->read_db_libconfig = pet_read_db_libconfig; + pet->read_db_sub = pet_read_db_sub; + pet->read_db_sub_intimacy = pet_read_db_sub_intimacy; + pet->read_db_clear = pet_read_db_clear; } diff --git a/src/map/pet.h b/src/map/pet.h index 9a0287b42..19e524c16 100644 --- a/src/map/pet.h +++ b/src/map/pet.h @@ -166,7 +166,12 @@ struct pet_interface { int (*skill_bonus_timer) (int tid, int64 tick, int id, intptr_t data); int (*recovery_timer) (int tid, int64 tick, int id, intptr_t data); int (*skill_support_timer) (int tid, int64 tick, int id, intptr_t data); - int (*read_db) (void); + + void (*read_db) (void); + int (*read_db_libconfig) (const char *filename, bool ignore_missing); + int (*read_db_sub) (struct config_setting_t *it, int n, const char *source); + bool (*read_db_sub_intimacy) (int idx, struct config_setting_t *t); + void (*read_db_clear) (void); }; #ifdef HERCULES_CORE diff --git a/src/map/quest.c b/src/map/quest.c index 4c5dcb59f..581ecf45e 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -148,7 +148,11 @@ int quest_add(struct map_session_data *sd, int quest_id, unsigned int time_limit sd->save_quest = true; clif->quest_add(sd, &sd->quest_log[n]); +#if PACKETVER >= 20150513 + clif->quest_notify_objective(sd, &sd->quest_log[n]); +#else clif->quest_update_objective(sd, &sd->quest_log[n]); +#endif if ((map->save_settings & 64) != 0) chrif->save(sd, 0); @@ -201,7 +205,11 @@ int quest_change(struct map_session_data *sd, int qid1, int qid2) clif->quest_delete(sd, qid1); clif->quest_add(sd, &sd->quest_log[i]); +#if PACKETVER >= 20150513 + clif->quest_notify_objective(sd, &sd->quest_log[i]); +#else clif->quest_update_objective(sd, &sd->quest_log[i]); +#endif if( map->save_settings&64 ) chrif->save(sd,0); diff --git a/src/map/rodex.c b/src/map/rodex.c index 0e9e4ee2a..d1b0191ac 100644 --- a/src/map/rodex.c +++ b/src/map/rodex.c @@ -383,7 +383,7 @@ struct rodex_message *rodex_get_mail(struct map_session_data *sd, int64 mail_id) if ((msg->is_deleted == true) || (msg->expire_date < time(NULL) && ((msg->receiver_accountid > 0) || (msg->receiver_id == char_id && msg->sender_id != char_id))) - || ((msg->send_date + 2 * RODEX_EXPIRE) < time(NULL)) + || (msg->expire_date + RODEX_EXPIRE < time(NULL)) ) return NULL; diff --git a/src/map/script.c b/src/map/script.c index d653800cc..275601dcc 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12815,12 +12815,12 @@ enum mapinfo_info { BUILDIN(getmapinfo) { enum mapinfo_info mode = script_getnum(st, 2); - int16 m; + int16 m = -1; if (script_hasdata(st, 3)) { if (script_isstringtype(st, 3)) { const char *str = script_getstr(st, 3); - m = map->mapname2mapid(str); + m = map->mapindex2mapid(strdb_iget(mapindex->db, str)); } else { m = script_getnum(st, 3); } @@ -23965,6 +23965,42 @@ BUILDIN(clan_master) } /** + * hateffect(EffectID, Enable_State) + */ +BUILDIN(hateffect) +{ +#if PACKETVER >= 20150422 + struct map_session_data *sd = script_rid2sd(st); + int effectId, enabled = 0; + int i; + + if (sd == NULL) + return false; + + effectId = script_getnum(st, 2); + enabled = script_getnum(st, 3); + + for (i = 0; i < VECTOR_LENGTH(sd->hatEffectId); ++i) { + if (VECTOR_INDEX(sd->hatEffectId, i) == effectId) { + if (enabled == 1) { // Already Enabled + return true; + } else { // Remove + VECTOR_ERASE(sd->hatEffectId, i); + clif->hat_effect_single(&sd->bl, effectId, enabled); + return true; + } + } + } + + VECTOR_ENSURE(sd->hatEffectId, 1, 1); + VECTOR_PUSH(sd->hatEffectId, effectId); + + clif->hat_effect_single(&sd->bl, effectId, enabled); +#endif + return true; +} + +/** * Adds a built-in script function. * * @param buildin Script function data @@ -24679,6 +24715,9 @@ void script_parse_builtin(void) { BUILDIN_DEF2(rodex_sendmail2, "rodex_sendmail_acc2", "isss?????????????????????????????????????????"), BUILDIN_DEF(_,"s"), BUILDIN_DEF2(_, "_$", "s"), + + // -- HatEffect + BUILDIN_DEF(hateffect, "ii"), }; int i, len = ARRAYLENGTH(BUILDIN); RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up diff --git a/src/map/skill.c b/src/map/skill.c index 3d541bf76..9108b6575 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6503,16 +6503,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case TK_JUMPKICK: /* Check if the target is an enemy; if not, skill should fail so the character doesn't unit->movepos (exploitable) */ - if( battle->check_target(src, bl, BCT_ENEMY) > 0 ) - { - if( unit->movepos(src, bl->x, bl->y, 1, 1) ) - { - skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); - clif->slide(src,bl->x,bl->y); + if (battle->check_target(src, bl, BCT_ENEMY) > 0) { + if (unit->movepos(src, bl->x, bl->y, 1, 1)) { + skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); + clif->slide(src, bl->x, bl->y); } + } else if (sd != NULL) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL, 0); } - else - clif->skill_fail(sd,skill_id,USESKILL_FAIL,0); break; case AL_INCAGI: diff --git a/src/map/status.c b/src/map/status.c index 3e4b4a45c..b2f67735b 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1780,7 +1780,11 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin for(i = 0; i < map->list[src->m].zone->disabled_skills_count; i++) { if( skill_id == map->list[src->m].zone->disabled_skills[i]->nameid && (map->list[src->m].zone->disabled_skills[i]->type&src->type) ) { if (src->type == BL_PC) { - clif->msgtable(sd, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area +#if PACKETVER >= 20080311 + clif->skill_mapinfomessage(sd, 2); +#else + clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 50)); +#endif } else if (src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE) { if( st->mode&MD_BOSS ) { /* is boss */ if( !( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS ) ) diff --git a/src/map/unit.c b/src/map/unit.c index c40aa7000..64bd17edc 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2766,6 +2766,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) } VECTOR_CLEAR(sd->script_queues); VECTOR_CLEAR(sd->storage.item); + VECTOR_CLEAR(sd->hatEffectId); sd->storage.received = false; if( sd->quest_log != NULL ) { aFree(sd->quest_log); diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index bd17dc7fe..4bd77f588 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -1452,6 +1452,10 @@ typedef void (*HPMHOOK_pre_clif_msgtable_num) (struct map_session_data **sd, uns typedef void (*HPMHOOK_post_clif_msgtable_num) (struct map_session_data *sd, unsigned short msg_id, int value); typedef void (*HPMHOOK_pre_clif_msgtable_skill) (struct map_session_data **sd, uint16 *skill_id, int *msg_id); typedef void (*HPMHOOK_post_clif_msgtable_skill) (struct map_session_data *sd, uint16 skill_id, int msg_id); +typedef void (*HPMHOOK_pre_clif_msgtable_str) (struct map_session_data **sd, uint16 *msg_id, const char **value); +typedef void (*HPMHOOK_post_clif_msgtable_str) (struct map_session_data *sd, uint16 msg_id, const char *value); +typedef void (*HPMHOOK_pre_clif_msgtable_color) (struct map_session_data **sd, uint16 *msg_id, uint32 *color); +typedef void (*HPMHOOK_post_clif_msgtable_color) (struct map_session_data *sd, uint16 msg_id, uint32 color); typedef void (*HPMHOOK_pre_clif_message) (const int *fd, const char **mes); typedef void (*HPMHOOK_post_clif_message) (const int fd, const char *mes); typedef void (*HPMHOOK_pre_clif_messageln) (const int *fd, const char **mes); @@ -1692,6 +1696,8 @@ typedef void (*HPMHOOK_pre_clif_quest_update_status) (struct map_session_data ** typedef void (*HPMHOOK_post_clif_quest_update_status) (struct map_session_data *sd, int quest_id, bool active); typedef void (*HPMHOOK_pre_clif_quest_update_objective) (struct map_session_data **sd, struct quest **qd); typedef void (*HPMHOOK_post_clif_quest_update_objective) (struct map_session_data *sd, struct quest *qd); +typedef void (*HPMHOOK_pre_clif_quest_notify_objective) (struct map_session_data **sd, struct quest **qd); +typedef void (*HPMHOOK_post_clif_quest_notify_objective) (struct map_session_data *sd, struct quest *qd); typedef void (*HPMHOOK_pre_clif_quest_show_event) (struct map_session_data **sd, struct block_list **bl, short *state, short *color); typedef void (*HPMHOOK_post_clif_quest_show_event) (struct map_session_data *sd, struct block_list *bl, short state, short color); typedef void (*HPMHOOK_pre_clif_mail_window) (int *fd, int *flag); @@ -2404,6 +2410,26 @@ typedef void (*HPMHOOK_pre_clif_clan_message) (struct clan **c, const char **mes typedef void (*HPMHOOK_post_clif_clan_message) (struct clan *c, const char *mes, int len); typedef void (*HPMHOOK_pre_clif_pClanMessage) (int *fd, struct map_session_data **sd); typedef void (*HPMHOOK_post_clif_pClanMessage) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_hat_effect) (struct block_list **bl, struct block_list **tbl, enum send_target *target); +typedef void (*HPMHOOK_post_clif_hat_effect) (struct block_list *bl, struct block_list *tbl, enum send_target target); +typedef void (*HPMHOOK_pre_clif_hat_effect_single) (struct block_list **bl, uint16 *effectId, bool *enable); +typedef void (*HPMHOOK_post_clif_hat_effect_single) (struct block_list *bl, uint16 effectId, bool enable); +typedef bool (*HPMHOOK_pre_clif_pAttendanceDB) (void); +typedef bool (*HPMHOOK_post_clif_pAttendanceDB) (bool retVal___); +typedef bool (*HPMHOOK_pre_clif_attendancedb_libconfig_sub) (struct config_setting_t **it, int *n, const char **source); +typedef bool (*HPMHOOK_post_clif_attendancedb_libconfig_sub) (bool retVal___, struct config_setting_t *it, int n, const char *source); +typedef bool (*HPMHOOK_pre_clif_attendance_timediff) (struct map_session_data **sd); +typedef bool (*HPMHOOK_post_clif_attendance_timediff) (bool retVal___, struct map_session_data *sd); +typedef time_t (*HPMHOOK_pre_clif_attendance_getendtime) (void); +typedef time_t (*HPMHOOK_post_clif_attendance_getendtime) (time_t retVal___); +typedef void (*HPMHOOK_pre_clif_pOpenUIRequest) (int *fd, struct map_session_data **sd); +typedef void (*HPMHOOK_post_clif_pOpenUIRequest) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_open_ui) (struct map_session_data **sd, int8 *UIType); +typedef void (*HPMHOOK_post_clif_open_ui) (struct map_session_data *sd, int8 UIType); +typedef void (*HPMHOOK_pre_clif_pAttendanceRewardRequest) (int *fd, struct map_session_data **sd); +typedef void (*HPMHOOK_post_clif_pAttendanceRewardRequest) (int fd, struct map_session_data *sd); +typedef void (*HPMHOOK_pre_clif_ui_action) (struct map_session_data **sd, int32 *UIType, int32 *data); +typedef void (*HPMHOOK_post_clif_ui_action) (struct map_session_data *sd, int32 UIType, int32 data); #endif // MAP_CLIF_H #ifdef COMMON_CORE_H /* cmdline */ typedef void (*HPMHOOK_pre_cmdline_init) (void); @@ -2668,8 +2694,8 @@ typedef int (*HPMHOOK_pre_guild_check_alliance) (int *guild_id1, int *guild_id2, typedef int (*HPMHOOK_post_guild_check_alliance) (int retVal___, int guild_id1, int guild_id2, int flag); typedef int (*HPMHOOK_pre_guild_send_memberinfoshort) (struct map_session_data **sd, int *online); typedef int (*HPMHOOK_post_guild_send_memberinfoshort) (int retVal___, struct map_session_data *sd, int online); -typedef int (*HPMHOOK_pre_guild_recv_memberinfoshort) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class); -typedef int (*HPMHOOK_post_guild_recv_memberinfoshort) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class); +typedef int (*HPMHOOK_pre_guild_recv_memberinfoshort) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class, uint32 *last_login); +typedef int (*HPMHOOK_post_guild_recv_memberinfoshort) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login); typedef int (*HPMHOOK_pre_guild_change_memberposition) (int *guild_id, int *account_id, int *char_id, short *idx); typedef int (*HPMHOOK_post_guild_change_memberposition) (int retVal___, int guild_id, int account_id, int char_id, short idx); typedef int (*HPMHOOK_pre_guild_memberposition_changed) (struct guild **g, int *idx, int *pos); @@ -6018,8 +6044,16 @@ typedef int (*HPMHOOK_pre_pet_recovery_timer) (int *tid, int64 *tick, int *id, i typedef int (*HPMHOOK_post_pet_recovery_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data); typedef int (*HPMHOOK_pre_pet_skill_support_timer) (int *tid, int64 *tick, int *id, intptr_t *data); typedef int (*HPMHOOK_post_pet_skill_support_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data); -typedef int (*HPMHOOK_pre_pet_read_db) (void); -typedef int (*HPMHOOK_post_pet_read_db) (int retVal___); +typedef void (*HPMHOOK_pre_pet_read_db) (void); +typedef void (*HPMHOOK_post_pet_read_db) (void); +typedef int (*HPMHOOK_pre_pet_read_db_libconfig) (const char **filename, bool *ignore_missing); +typedef int (*HPMHOOK_post_pet_read_db_libconfig) (int retVal___, const char *filename, bool ignore_missing); +typedef int (*HPMHOOK_pre_pet_read_db_sub) (struct config_setting_t **it, int *n, const char **source); +typedef int (*HPMHOOK_post_pet_read_db_sub) (int retVal___, struct config_setting_t *it, int n, const char *source); +typedef bool (*HPMHOOK_pre_pet_read_db_sub_intimacy) (int *idx, struct config_setting_t **t); +typedef bool (*HPMHOOK_post_pet_read_db_sub_intimacy) (bool retVal___, int idx, struct config_setting_t *t); +typedef void (*HPMHOOK_pre_pet_read_db_clear) (void); +typedef void (*HPMHOOK_post_pet_read_db_clear) (void); #endif // MAP_PET_H #ifdef CHAR_PINCODE_H /* pincode */ typedef void (*HPMHOOK_pre_pincode_handle) (int *fd, struct char_session_data **sd); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 9d531e370..c01f8000c 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -1046,6 +1046,10 @@ struct { struct HPMHookPoint *HP_clif_msgtable_num_post; struct HPMHookPoint *HP_clif_msgtable_skill_pre; struct HPMHookPoint *HP_clif_msgtable_skill_post; + struct HPMHookPoint *HP_clif_msgtable_str_pre; + struct HPMHookPoint *HP_clif_msgtable_str_post; + struct HPMHookPoint *HP_clif_msgtable_color_pre; + struct HPMHookPoint *HP_clif_msgtable_color_post; struct HPMHookPoint *HP_clif_message_pre; struct HPMHookPoint *HP_clif_message_post; struct HPMHookPoint *HP_clif_messageln_pre; @@ -1286,6 +1290,8 @@ struct { struct HPMHookPoint *HP_clif_quest_update_status_post; struct HPMHookPoint *HP_clif_quest_update_objective_pre; struct HPMHookPoint *HP_clif_quest_update_objective_post; + struct HPMHookPoint *HP_clif_quest_notify_objective_pre; + struct HPMHookPoint *HP_clif_quest_notify_objective_post; struct HPMHookPoint *HP_clif_quest_show_event_pre; struct HPMHookPoint *HP_clif_quest_show_event_post; struct HPMHookPoint *HP_clif_mail_window_pre; @@ -1998,6 +2004,26 @@ struct { struct HPMHookPoint *HP_clif_clan_message_post; struct HPMHookPoint *HP_clif_pClanMessage_pre; struct HPMHookPoint *HP_clif_pClanMessage_post; + struct HPMHookPoint *HP_clif_hat_effect_pre; + struct HPMHookPoint *HP_clif_hat_effect_post; + struct HPMHookPoint *HP_clif_hat_effect_single_pre; + struct HPMHookPoint *HP_clif_hat_effect_single_post; + struct HPMHookPoint *HP_clif_pAttendanceDB_pre; + struct HPMHookPoint *HP_clif_pAttendanceDB_post; + struct HPMHookPoint *HP_clif_attendancedb_libconfig_sub_pre; + struct HPMHookPoint *HP_clif_attendancedb_libconfig_sub_post; + struct HPMHookPoint *HP_clif_attendance_timediff_pre; + struct HPMHookPoint *HP_clif_attendance_timediff_post; + struct HPMHookPoint *HP_clif_attendance_getendtime_pre; + struct HPMHookPoint *HP_clif_attendance_getendtime_post; + struct HPMHookPoint *HP_clif_pOpenUIRequest_pre; + struct HPMHookPoint *HP_clif_pOpenUIRequest_post; + struct HPMHookPoint *HP_clif_open_ui_pre; + struct HPMHookPoint *HP_clif_open_ui_post; + struct HPMHookPoint *HP_clif_pAttendanceRewardRequest_pre; + struct HPMHookPoint *HP_clif_pAttendanceRewardRequest_post; + struct HPMHookPoint *HP_clif_ui_action_pre; + struct HPMHookPoint *HP_clif_ui_action_post; struct HPMHookPoint *HP_cmdline_init_pre; struct HPMHookPoint *HP_cmdline_init_post; struct HPMHookPoint *HP_cmdline_final_pre; @@ -4670,6 +4696,14 @@ struct { struct HPMHookPoint *HP_pet_skill_support_timer_post; struct HPMHookPoint *HP_pet_read_db_pre; struct HPMHookPoint *HP_pet_read_db_post; + struct HPMHookPoint *HP_pet_read_db_libconfig_pre; + struct HPMHookPoint *HP_pet_read_db_libconfig_post; + struct HPMHookPoint *HP_pet_read_db_sub_pre; + struct HPMHookPoint *HP_pet_read_db_sub_post; + struct HPMHookPoint *HP_pet_read_db_sub_intimacy_pre; + struct HPMHookPoint *HP_pet_read_db_sub_intimacy_post; + struct HPMHookPoint *HP_pet_read_db_clear_pre; + struct HPMHookPoint *HP_pet_read_db_clear_post; struct HPMHookPoint *HP_quest_init_pre; struct HPMHookPoint *HP_quest_init_post; struct HPMHookPoint *HP_quest_final_pre; @@ -7327,6 +7361,10 @@ struct { int HP_clif_msgtable_num_post; int HP_clif_msgtable_skill_pre; int HP_clif_msgtable_skill_post; + int HP_clif_msgtable_str_pre; + int HP_clif_msgtable_str_post; + int HP_clif_msgtable_color_pre; + int HP_clif_msgtable_color_post; int HP_clif_message_pre; int HP_clif_message_post; int HP_clif_messageln_pre; @@ -7567,6 +7605,8 @@ struct { int HP_clif_quest_update_status_post; int HP_clif_quest_update_objective_pre; int HP_clif_quest_update_objective_post; + int HP_clif_quest_notify_objective_pre; + int HP_clif_quest_notify_objective_post; int HP_clif_quest_show_event_pre; int HP_clif_quest_show_event_post; int HP_clif_mail_window_pre; @@ -8279,6 +8319,26 @@ struct { int HP_clif_clan_message_post; int HP_clif_pClanMessage_pre; int HP_clif_pClanMessage_post; + int HP_clif_hat_effect_pre; + int HP_clif_hat_effect_post; + int HP_clif_hat_effect_single_pre; + int HP_clif_hat_effect_single_post; + int HP_clif_pAttendanceDB_pre; + int HP_clif_pAttendanceDB_post; + int HP_clif_attendancedb_libconfig_sub_pre; + int HP_clif_attendancedb_libconfig_sub_post; + int HP_clif_attendance_timediff_pre; + int HP_clif_attendance_timediff_post; + int HP_clif_attendance_getendtime_pre; + int HP_clif_attendance_getendtime_post; + int HP_clif_pOpenUIRequest_pre; + int HP_clif_pOpenUIRequest_post; + int HP_clif_open_ui_pre; + int HP_clif_open_ui_post; + int HP_clif_pAttendanceRewardRequest_pre; + int HP_clif_pAttendanceRewardRequest_post; + int HP_clif_ui_action_pre; + int HP_clif_ui_action_post; int HP_cmdline_init_pre; int HP_cmdline_init_post; int HP_cmdline_final_pre; @@ -10951,6 +11011,14 @@ struct { int HP_pet_skill_support_timer_post; int HP_pet_read_db_pre; int HP_pet_read_db_post; + int HP_pet_read_db_libconfig_pre; + int HP_pet_read_db_libconfig_post; + int HP_pet_read_db_sub_pre; + int HP_pet_read_db_sub_post; + int HP_pet_read_db_sub_intimacy_pre; + int HP_pet_read_db_sub_intimacy_post; + int HP_pet_read_db_clear_pre; + int HP_pet_read_db_clear_post; int HP_quest_init_pre; int HP_quest_init_post; int HP_quest_final_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index 5551668d2..2e762a231 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -546,6 +546,8 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->msgtable, HP_clif_msgtable) }, { HP_POP(clif->msgtable_num, HP_clif_msgtable_num) }, { HP_POP(clif->msgtable_skill, HP_clif_msgtable_skill) }, + { HP_POP(clif->msgtable_str, HP_clif_msgtable_str) }, + { HP_POP(clif->msgtable_color, HP_clif_msgtable_color) }, { HP_POP(clif->message, HP_clif_message) }, { HP_POP(clif->messageln, HP_clif_messageln) }, { HP_POP(clif->process_chat_message, HP_clif_process_chat_message) }, @@ -666,6 +668,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->quest_delete, HP_clif_quest_delete) }, { HP_POP(clif->quest_update_status, HP_clif_quest_update_status) }, { HP_POP(clif->quest_update_objective, HP_clif_quest_update_objective) }, + { HP_POP(clif->quest_notify_objective, HP_clif_quest_notify_objective) }, { HP_POP(clif->quest_show_event, HP_clif_quest_show_event) }, { HP_POP(clif->mail_window, HP_clif_mail_window) }, { HP_POP(clif->mail_read, HP_clif_mail_read) }, @@ -1022,6 +1025,16 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->clan_leave, HP_clif_clan_leave) }, { HP_POP(clif->clan_message, HP_clif_clan_message) }, { HP_POP(clif->pClanMessage, HP_clif_pClanMessage) }, + { HP_POP(clif->hat_effect, HP_clif_hat_effect) }, + { HP_POP(clif->hat_effect_single, HP_clif_hat_effect_single) }, + { HP_POP(clif->pAttendanceDB, HP_clif_pAttendanceDB) }, + { HP_POP(clif->attendancedb_libconfig_sub, HP_clif_attendancedb_libconfig_sub) }, + { HP_POP(clif->attendance_timediff, HP_clif_attendance_timediff) }, + { HP_POP(clif->attendance_getendtime, HP_clif_attendance_getendtime) }, + { HP_POP(clif->pOpenUIRequest, HP_clif_pOpenUIRequest) }, + { HP_POP(clif->open_ui, HP_clif_open_ui) }, + { HP_POP(clif->pAttendanceRewardRequest, HP_clif_pAttendanceRewardRequest) }, + { HP_POP(clif->ui_action, HP_clif_ui_action) }, /* cmdline_interface */ { HP_POP(cmdline->init, HP_cmdline_init) }, { HP_POP(cmdline->final, HP_cmdline_final) }, @@ -2393,6 +2406,10 @@ struct HookingPointData HookingPoints[] = { { HP_POP(pet->recovery_timer, HP_pet_recovery_timer) }, { HP_POP(pet->skill_support_timer, HP_pet_skill_support_timer) }, { HP_POP(pet->read_db, HP_pet_read_db) }, + { HP_POP(pet->read_db_libconfig, HP_pet_read_db_libconfig) }, + { HP_POP(pet->read_db_sub, HP_pet_read_db_sub) }, + { HP_POP(pet->read_db_sub_intimacy, HP_pet_read_db_sub_intimacy) }, + { HP_POP(pet->read_db_clear, HP_pet_read_db_clear) }, /* quest_interface */ { HP_POP(quest->init, HP_quest_init) }, { HP_POP(quest->final, HP_quest_final) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 2e20ab157..6b89e4f65 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -13622,6 +13622,58 @@ void HP_clif_msgtable_skill(struct map_session_data *sd, uint16 skill_id, int ms } return; } +void HP_clif_msgtable_str(struct map_session_data *sd, uint16 msg_id, const char *value) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_msgtable_str_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, uint16 *msg_id, const char **value); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_msgtable_str_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_msgtable_str_pre[hIndex].func; + preHookFunc(&sd, &msg_id, &value); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.msgtable_str(sd, msg_id, value); + } + if (HPMHooks.count.HP_clif_msgtable_str_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, uint16 msg_id, const char *value); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_msgtable_str_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_msgtable_str_post[hIndex].func; + postHookFunc(sd, msg_id, value); + } + } + return; +} +void HP_clif_msgtable_color(struct map_session_data *sd, uint16 msg_id, uint32 color) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_msgtable_color_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, uint16 *msg_id, uint32 *color); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_msgtable_color_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_msgtable_color_pre[hIndex].func; + preHookFunc(&sd, &msg_id, &color); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.msgtable_color(sd, msg_id, color); + } + if (HPMHooks.count.HP_clif_msgtable_color_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, uint16 msg_id, uint32 color); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_msgtable_color_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_msgtable_color_post[hIndex].func; + postHookFunc(sd, msg_id, color); + } + } + return; +} void HP_clif_message(const int fd, const char *mes) { int hIndex = 0; if (HPMHooks.count.HP_clif_message_pre > 0) { @@ -16753,6 +16805,32 @@ void HP_clif_quest_update_objective(struct map_session_data *sd, struct quest *q } return; } +void HP_clif_quest_notify_objective(struct map_session_data *sd, struct quest *qd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_quest_notify_objective_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, struct quest **qd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_notify_objective_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_quest_notify_objective_pre[hIndex].func; + preHookFunc(&sd, &qd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.quest_notify_objective(sd, qd); + } + if (HPMHooks.count.HP_clif_quest_notify_objective_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, struct quest *qd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_notify_objective_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_quest_notify_objective_post[hIndex].func; + postHookFunc(sd, qd); + } + } + return; +} void HP_clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, short state, short color) { int hIndex = 0; if (HPMHooks.count.HP_clif_quest_show_event_pre > 0) { @@ -26018,6 +26096,271 @@ void HP_clif_pClanMessage(int fd, struct map_session_data *sd) { } return; } +void HP_clif_hat_effect(struct block_list *bl, struct block_list *tbl, enum send_target target) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_hat_effect_pre > 0) { + void (*preHookFunc) (struct block_list **bl, struct block_list **tbl, enum send_target *target); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_hat_effect_pre[hIndex].func; + preHookFunc(&bl, &tbl, &target); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.hat_effect(bl, tbl, target); + } + if (HPMHooks.count.HP_clif_hat_effect_post > 0) { + void (*postHookFunc) (struct block_list *bl, struct block_list *tbl, enum send_target target); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_hat_effect_post[hIndex].func; + postHookFunc(bl, tbl, target); + } + } + return; +} +void HP_clif_hat_effect_single(struct block_list *bl, uint16 effectId, bool enable) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_hat_effect_single_pre > 0) { + void (*preHookFunc) (struct block_list **bl, uint16 *effectId, bool *enable); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_single_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_hat_effect_single_pre[hIndex].func; + preHookFunc(&bl, &effectId, &enable); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.hat_effect_single(bl, effectId, enable); + } + if (HPMHooks.count.HP_clif_hat_effect_single_post > 0) { + void (*postHookFunc) (struct block_list *bl, uint16 effectId, bool enable); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hat_effect_single_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_hat_effect_single_post[hIndex].func; + postHookFunc(bl, effectId, enable); + } + } + return; +} +bool HP_clif_pAttendanceDB(void) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_clif_pAttendanceDB_pre > 0) { + bool (*preHookFunc) (void); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pAttendanceDB_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pAttendanceDB_pre[hIndex].func; + retVal___ = preHookFunc(); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.pAttendanceDB(); + } + if (HPMHooks.count.HP_clif_pAttendanceDB_post > 0) { + bool (*postHookFunc) (bool retVal___); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pAttendanceDB_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pAttendanceDB_post[hIndex].func; + retVal___ = postHookFunc(retVal___); + } + } + return retVal___; +} +bool HP_clif_attendancedb_libconfig_sub(struct config_setting_t *it, int n, const char *source) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_clif_attendancedb_libconfig_sub_pre > 0) { + bool (*preHookFunc) (struct config_setting_t **it, int *n, const char **source); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_attendancedb_libconfig_sub_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_attendancedb_libconfig_sub_pre[hIndex].func; + retVal___ = preHookFunc(&it, &n, &source); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.attendancedb_libconfig_sub(it, n, source); + } + if (HPMHooks.count.HP_clif_attendancedb_libconfig_sub_post > 0) { + bool (*postHookFunc) (bool retVal___, struct config_setting_t *it, int n, const char *source); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_attendancedb_libconfig_sub_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_attendancedb_libconfig_sub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, it, n, source); + } + } + return retVal___; +} +bool HP_clif_attendance_timediff(struct map_session_data *sd) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_clif_attendance_timediff_pre > 0) { + bool (*preHookFunc) (struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_attendance_timediff_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_attendance_timediff_pre[hIndex].func; + retVal___ = preHookFunc(&sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.attendance_timediff(sd); + } + if (HPMHooks.count.HP_clif_attendance_timediff_post > 0) { + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_attendance_timediff_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_attendance_timediff_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd); + } + } + return retVal___; +} +time_t HP_clif_attendance_getendtime(void) { +/* Unknown return type 'time_t'. Initializing to '0'. */ + int hIndex = 0; + time_t retVal___ = 0; + if (HPMHooks.count.HP_clif_attendance_getendtime_pre > 0) { + time_t (*preHookFunc) (void); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_attendance_getendtime_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_attendance_getendtime_pre[hIndex].func; + retVal___ = preHookFunc(); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.attendance_getendtime(); + } + if (HPMHooks.count.HP_clif_attendance_getendtime_post > 0) { + time_t (*postHookFunc) (time_t retVal___); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_attendance_getendtime_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_attendance_getendtime_post[hIndex].func; + retVal___ = postHookFunc(retVal___); + } + } + return retVal___; +} +void HP_clif_pOpenUIRequest(int fd, struct map_session_data *sd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_pOpenUIRequest_pre > 0) { + void (*preHookFunc) (int *fd, struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pOpenUIRequest_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pOpenUIRequest_pre[hIndex].func; + preHookFunc(&fd, &sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pOpenUIRequest(fd, sd); + } + if (HPMHooks.count.HP_clif_pOpenUIRequest_post > 0) { + void (*postHookFunc) (int fd, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pOpenUIRequest_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pOpenUIRequest_post[hIndex].func; + postHookFunc(fd, sd); + } + } + return; +} +void HP_clif_open_ui(struct map_session_data *sd, int8 UIType) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_open_ui_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, int8 *UIType); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_open_ui_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_open_ui_pre[hIndex].func; + preHookFunc(&sd, &UIType); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.open_ui(sd, UIType); + } + if (HPMHooks.count.HP_clif_open_ui_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, int8 UIType); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_open_ui_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_open_ui_post[hIndex].func; + postHookFunc(sd, UIType); + } + } + return; +} +void HP_clif_pAttendanceRewardRequest(int fd, struct map_session_data *sd) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_pAttendanceRewardRequest_pre > 0) { + void (*preHookFunc) (int *fd, struct map_session_data **sd); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pAttendanceRewardRequest_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_pAttendanceRewardRequest_pre[hIndex].func; + preHookFunc(&fd, &sd); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pAttendanceRewardRequest(fd, sd); + } + if (HPMHooks.count.HP_clif_pAttendanceRewardRequest_post > 0) { + void (*postHookFunc) (int fd, struct map_session_data *sd); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pAttendanceRewardRequest_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_pAttendanceRewardRequest_post[hIndex].func; + postHookFunc(fd, sd); + } + } + return; +} +void HP_clif_ui_action(struct map_session_data *sd, int32 UIType, int32 data) { + int hIndex = 0; + if (HPMHooks.count.HP_clif_ui_action_pre > 0) { + void (*preHookFunc) (struct map_session_data **sd, int32 *UIType, int32 *data); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_ui_action_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_clif_ui_action_pre[hIndex].func; + preHookFunc(&sd, &UIType, &data); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.ui_action(sd, UIType, data); + } + if (HPMHooks.count.HP_clif_ui_action_post > 0) { + void (*postHookFunc) (struct map_session_data *sd, int32 UIType, int32 data); + for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_ui_action_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_clif_ui_action_post[hIndex].func; + postHookFunc(sd, UIType, data); + } + } + return; +} /* cmdline_interface */ void HP_cmdline_init(void) { int hIndex = 0; @@ -29222,15 +29565,15 @@ int HP_guild_send_memberinfoshort(struct map_session_data *sd, int online) { } return retVal___; } -int HP_guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class) { +int HP_guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_guild_recv_memberinfoshort_pre > 0) { - int (*preHookFunc) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class); + int (*preHookFunc) (int *guild_id, int *account_id, int *char_id, int *online, int *lv, int16 *class, uint32 *last_login); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_guild_recv_memberinfoshort_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_guild_recv_memberinfoshort_pre[hIndex].func; - retVal___ = preHookFunc(&guild_id, &account_id, &char_id, &online, &lv, &class); + retVal___ = preHookFunc(&guild_id, &account_id, &char_id, &online, &lv, &class, &last_login); } if (*HPMforce_return) { *HPMforce_return = false; @@ -29238,13 +29581,13 @@ int HP_guild_recv_memberinfoshort(int guild_id, int account_id, int char_id, int } } { - retVal___ = HPMHooks.source.guild.recv_memberinfoshort(guild_id, account_id, char_id, online, lv, class); + retVal___ = HPMHooks.source.guild.recv_memberinfoshort(guild_id, account_id, char_id, online, lv, class, last_login); } if (HPMHooks.count.HP_guild_recv_memberinfoshort_post > 0) { - int (*postHookFunc) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class); + int (*postHookFunc) (int retVal___, int guild_id, int account_id, int char_id, int online, int lv, int16 class, uint32 last_login); for (hIndex = 0; hIndex < HPMHooks.count.HP_guild_recv_memberinfoshort_post; hIndex++) { postHookFunc = HPMHooks.list.HP_guild_recv_memberinfoshort_post[hIndex].func; - retVal___ = postHookFunc(retVal___, guild_id, account_id, char_id, online, lv, class); + retVal___ = postHookFunc(retVal___, guild_id, account_id, char_id, online, lv, class, last_login); } } return retVal___; @@ -62202,33 +62545,139 @@ int HP_pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) { } return retVal___; } -int HP_pet_read_db(void) { +void HP_pet_read_db(void) { int hIndex = 0; - int retVal___ = 0; if (HPMHooks.count.HP_pet_read_db_pre > 0) { - int (*preHookFunc) (void); + void (*preHookFunc) (void); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_pet_read_db_pre[hIndex].func; - retVal___ = preHookFunc(); + preHookFunc(); } if (*HPMforce_return) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.pet.read_db(); + HPMHooks.source.pet.read_db(); } if (HPMHooks.count.HP_pet_read_db_post > 0) { - int (*postHookFunc) (int retVal___); + void (*postHookFunc) (void); for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_post; hIndex++) { postHookFunc = HPMHooks.list.HP_pet_read_db_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + postHookFunc(); + } + } + return; +} +int HP_pet_read_db_libconfig(const char *filename, bool ignore_missing) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_pet_read_db_libconfig_pre > 0) { + int (*preHookFunc) (const char **filename, bool *ignore_missing); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_libconfig_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pet_read_db_libconfig_pre[hIndex].func; + retVal___ = preHookFunc(&filename, &ignore_missing); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pet.read_db_libconfig(filename, ignore_missing); + } + if (HPMHooks.count.HP_pet_read_db_libconfig_post > 0) { + int (*postHookFunc) (int retVal___, const char *filename, bool ignore_missing); + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_libconfig_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pet_read_db_libconfig_post[hIndex].func; + retVal___ = postHookFunc(retVal___, filename, ignore_missing); + } + } + return retVal___; +} +int HP_pet_read_db_sub(struct config_setting_t *it, int n, const char *source) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_pet_read_db_sub_pre > 0) { + int (*preHookFunc) (struct config_setting_t **it, int *n, const char **source); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_sub_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pet_read_db_sub_pre[hIndex].func; + retVal___ = preHookFunc(&it, &n, &source); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pet.read_db_sub(it, n, source); + } + if (HPMHooks.count.HP_pet_read_db_sub_post > 0) { + int (*postHookFunc) (int retVal___, struct config_setting_t *it, int n, const char *source); + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_sub_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pet_read_db_sub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, it, n, source); + } + } + return retVal___; +} +bool HP_pet_read_db_sub_intimacy(int idx, struct config_setting_t *t) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_pet_read_db_sub_intimacy_pre > 0) { + bool (*preHookFunc) (int *idx, struct config_setting_t **t); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_sub_intimacy_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pet_read_db_sub_intimacy_pre[hIndex].func; + retVal___ = preHookFunc(&idx, &t); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pet.read_db_sub_intimacy(idx, t); + } + if (HPMHooks.count.HP_pet_read_db_sub_intimacy_post > 0) { + bool (*postHookFunc) (bool retVal___, int idx, struct config_setting_t *t); + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_sub_intimacy_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pet_read_db_sub_intimacy_post[hIndex].func; + retVal___ = postHookFunc(retVal___, idx, t); } } return retVal___; } +void HP_pet_read_db_clear(void) { + int hIndex = 0; + if (HPMHooks.count.HP_pet_read_db_clear_pre > 0) { + void (*preHookFunc) (void); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_clear_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pet_read_db_clear_pre[hIndex].func; + preHookFunc(); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pet.read_db_clear(); + } + if (HPMHooks.count.HP_pet_read_db_clear_post > 0) { + void (*postHookFunc) (void); + for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_clear_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pet_read_db_clear_post[hIndex].func; + postHookFunc(); + } + } + return; +} /* quest_interface */ void HP_quest_init(bool minimal) { int hIndex = 0; diff --git a/tools/petdbconverter.py b/tools/petdbconverter.py new file mode 100644 index 000000000..261c1e6ad --- /dev/null +++ b/tools/petdbconverter.py @@ -0,0 +1,214 @@ +#! /usr/bin/env python +# -*- coding: utf8 -*- +# +# This file is part of Hercules. +# http://herc.ws - http://github.com/HerculesWS/Hercules +# +# Copyright (C) 2018 Hercules Dev Team +# Copyright (C) 2018 Asheraf +# Copyright (C) 2015 Andrei Karas (4144) +# +# Hercules is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import re +import sys + +def isValidEntry(line): + if re.match('^[0-9]+,.*', line): + return True + return False + +def curlSplit(line): + return re.split('[{}]|},', line) + +def commaSplit(line): + return line.split(',') + +def printIntField(name, value): + if int(value) != 0: + print('\t{0}: {1}'.format(name, value)) + +def printIntField2(name, value): + if int(value) != 0: + print('\t\t{0}: {1}'.format(name, value)) + +def printStrField(name, value): + if value != '': + print('\t{0}: \"{1}\"'.format(name, value)) + +def printBool(name, value): + if int(value) != 0: + print('\t{0}: true'.format(name)) + +def printIntimacy(arr): + if int(arr[9]) == 0 or int(arr[10]) == 0 or int(arr[11]) == 0 or int(arr[12]) == 0: + return + print('\tIntimacy: {') + printIntField2('Initial', arr[11]) + printIntField2('FeedIncrement', arr[9]) + printIntField2('OverFeedDecrement', arr[10]) + printIntField2('OwnerDeathDecrement', arr[12]) + print('\t}') + +def printScript(name, value): + if re.match('.*[a-zA-Z0-9,]+.*', value): + print('\t{0}: <\"{1}\">'.format(name, value)) + +def printItemName(fieldname, itemid, itemDb): + value = int(itemid) + if value != 0: + if value not in itemDb: + print("// Error: pet item with id {0} not found in item_db.conf".format(value)) + else: + printStrField(fieldname, itemDb[value]) + + +def printHeader(): + print(""" +pet_db:( +/************************************************************************** + ************* Entry structure ******************************************** + ************************************************************************** +{ + // ================ Mandatory fields ============================== + Id: ID (int) + SpriteName: "Sprite_Name" (string) + Name: "Pet Name" (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) + 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) + } + CaptureRate: capture rate (int, defaults to 0) + Speed: speed (int, defaults to 0) + 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) + PetScript: <" Pet Script (can also be multi-line) "> + EquipScript: <" Equip Script (can also be multi-line) "> +}, +**************************************************************************/ + """) + +def printFooter(): + print(')\n') + +def convertFile(inFile, itemDb): + if inFile != "" and not os.path.exists(inFile): + return + + if inFile == "": + r = sys.stdin + else: + r = open(inFile, "r") + + printHeader() + for line in r: + if isValidEntry(line) == True: + print('{') + firstsplit = curlSplit(line) + secondsplit = commaSplit(firstsplit[0]) + printIntField('Id', secondsplit[0]) + printStrField('SpriteName', secondsplit[1]) + printStrField('Name', secondsplit[2]) + printItemName('TamingItem', secondsplit[3], itemDb) + printItemName('EggItem', secondsplit[4], itemDb) + printItemName('AccessoryItem', secondsplit[5], itemDb) + printItemName('FoodItem', secondsplit[6], itemDb) + printIntField('FoodEffectiveness', secondsplit[7]) + printIntField('HungerDelay', secondsplit[8]) + printIntimacy(secondsplit) + printIntField('CaptureRate', secondsplit[13]) + printIntField('Speed', secondsplit[14]) + printBool('SpecialPerformance', secondsplit[15]) + printBool('TalkWithEmotes', secondsplit[16]) + printIntField('AttackRate', secondsplit[17]) + printIntField('DefendRate', secondsplit[18]) + printIntField('ChangeTargetRate', secondsplit[19]) + printScript('PetScript', firstsplit[1]) + printScript('EquipScript', firstsplit[3]) + print('},') + printFooter() + +def printHelp(): + print("PetDB converter from txt to conf format") + print("Usage:") + print(" petdbconverter.py re serverpath dbfilepath") + print(" petdbconverter.py pre-re serverpath dbfilepath") + print("Usage for read from stdin:") + print(" petdbconverter.py re dbfilepath") + +def readItemDB(inFile, itemDb): + itemId = 0 + itemName = "" + started = False + with open(inFile, "r") as r: + for line in r: + line = line.strip() + if started == True: + if line == "},": + started = False + elif line[:10] == "AegisName:": + itemName = line[12:-1] + elif line[:3] == "Id:": + try: + itemId = int(line[4:]) + except: + started = False + if itemId != 0 and itemName != "": +# was need for remove wrong characters +# itemName = itemName.replace(".", "") +# if itemName[0] >= "0" and itemName[0] <= "9": +# itemName = "Num" + itemName + itemDb[itemId] = itemName + started = False + else: + if line == "{": + started = True + itemId = 0 + itemName = "" + return itemDb + +if len(sys.argv) != 4 and len(sys.argv) != 3: + printHelp(); + exit(1) +startPath = sys.argv[2] +if len(sys.argv) == 4: + sourceFile = sys.argv[3] +else: + sourceFile = ""; + +itemDb = dict() +if sys.argv[1] == "re": + itemDb = readItemDB(startPath + "/db/re/item_db.conf", itemDb) + itemDb = readItemDB(startPath + "/db/item_db2.conf", itemDb) +elif sys.argv[1] == "pre-re": + itemDb = readItemDB(startPath + "/db/pre-re/item_db.conf", itemDb) + itemDb = readItemDB(startPath + "/db/item_db2.conf", itemDb) +else: + printHelp(); + exit(1) + +convertFile(sourceFile, itemDb)
\ No newline at end of file |