Browse Source

Initial implementation of pet evolution system + Pet DB conversion to YAML (#3544)

* Implemented official pet evolution system
* Added evolved pets to pet database
* Corrected various pet system mechanics
* Migrated pet database to YAML format and the converter from CSV format

Thanks to @Lemongrass3110 @aleos89 and @Atemo for their suggestions and additional fixes
Jittapan Pluemsumran 6 years ago
parent
commit
ac558d7c1e
48 changed files with 4510 additions and 549 deletions
  1. 2 1
      .gitattributes
  2. 12 0
      conf/battle/feature.conf
  3. 4 7
      conf/battle/pet.conf
  4. 1 2
      conf/msg_conf/map_msg.conf
  5. 1 2
      conf/msg_conf/map_msg_chn.conf
  6. 1 2
      conf/msg_conf/map_msg_frn.conf
  7. 1 2
      conf/msg_conf/map_msg_idn.conf
  8. 1 2
      conf/msg_conf/map_msg_por.conf
  9. 1 2
      conf/msg_conf/map_msg_rus.conf
  10. 1 2
      conf/msg_conf/map_msg_spn.conf
  11. 1 2
      conf/msg_conf/map_msg_tha.conf
  12. 0 60
      db/import-tmpl/pet_db.txt
  13. 486 0
      db/import-tmpl/pet_db.yml
  14. 63 0
      db/pet_db.yml
  15. 0 104
      db/pre-re/pet_db.txt
  16. 867 0
      db/pre-re/pet_db.yml
  17. 56 0
      db/re/item_db.txt
  18. 4 4
      db/re/mob_db.txt
  19. 0 110
      db/re/pet_db.txt
  20. 1733 0
      db/re/pet_db.yml
  21. 1 1
      doc/atcommands.txt
  22. 31 7
      doc/script_commands.txt
  23. 1 0
      sql-files/main.sql
  24. 2 0
      sql-files/upgrades/upgrade_20190309.sql
  25. 10 8
      src/char/int_pet.cpp
  26. 24 0
      src/common/database.cpp
  27. 2 0
      src/common/database.hpp
  28. 1 0
      src/common/mmo.hpp
  29. 11 6
      src/map/atcommand.cpp
  30. 15 0
      src/map/battle.cpp
  31. 4 0
      src/map/battle.hpp
  32. 50 14
      src/map/clif.cpp
  33. 13 0
      src/map/clif.hpp
  34. 6 3
      src/map/clif_packetdb.hpp
  35. 4 0
      src/map/itemdb.cpp
  36. 1 0
      src/map/itemdb.hpp
  37. 1 1
      src/map/map-server.vcxproj
  38. 11 0
      src/map/mob.cpp
  39. 1 0
      src/map/mob.hpp
  40. 1 1
      src/map/pc.cpp
  41. 636 113
      src/map/pet.cpp
  42. 73 31
      src/map/pet.hpp
  43. 8 7
      src/map/script.cpp
  44. 17 0
      src/map/script_constants.hpp
  45. 1 1
      src/map/skill.cpp
  46. 6 7
      src/map/status.cpp
  47. 4 46
      src/map/unit.cpp
  48. 340 1
      src/tool/csv2yaml.cpp

+ 2 - 1
.gitattributes

@@ -1,5 +1,6 @@
 *        text=auto
 *        text=auto
-*.c      diff=cpp
+*.cpp diff=cpp
+*.yml diff
 *.sln    merge=union
 *.sln    merge=union
 *.vcproj merge=union
 *.vcproj merge=union
 *.vcxproj merge=union
 *.vcxproj merge=union

+ 12 - 0
conf/battle/feature.conf

@@ -71,6 +71,18 @@ feature.achievement: on
 // Requires: 2017-02-08bRagexeRE or later
 // Requires: 2017-02-08bRagexeRE or later
 feature.equipswitch: on
 feature.equipswitch: on
 
 
+// Pet evolution (Note 1)
+// Requires: 2014-10-08aRagexe or later
+feature.petevolution: on
+
+// Automatic Pet Feeding (Note 1)
+// Requires: 2014-10-08aRagexe or later
+feature.petautofeed: on
+
+// At which hunger rate should pet autofeeding trigger? (Note 2)
+// Default: 89
+feature.pet_autofeed_rate: 89
+
 // Homunculues Autofeeding (Note 1)
 // Homunculues Autofeeding (Note 1)
 // Requires: 2017-09-20bRagexeRE or later
 // Requires: 2017-09-20bRagexeRE or later
 feature.homunculus_autofeed: on
 feature.homunculus_autofeed: on

+ 4 - 7
conf/battle/pet.conf

@@ -21,10 +21,6 @@ pet_friendly_rate: 100
 // The rate at which a pet will become hungry. (Note 2)
 // The rate at which a pet will become hungry. (Note 2)
 pet_hungry_delay_rate: 100
 pet_hungry_delay_rate: 100
 
 
-// If your pet is hungry by how much will the friendlyness decrease by. (Default is 5)
-// Note: The friendlyness is 0-1000 total, at 0 the pet runs away.
-pet_hungry_friendly_decrease: 5
-
 // Does the pet need its equipment before it does its skill? (Note 1)
 // Does the pet need its equipment before it does its skill? (Note 1)
 pet_equip_required: yes
 pet_equip_required: yes
 
 
@@ -39,9 +35,6 @@ pet_damage_support: no
 // At max (1000) support rate is 150%.
 // At max (1000) support rate is 150%.
 pet_support_min_friendly: 900
 pet_support_min_friendly: 900
 
 
-// Same as above, but this is to use the pet_script field with official pet abilities.
-pet_equip_min_friendly: 900
-
 // Whether or not the pet's will use skills. (Note 1)
 // Whether or not the pet's will use skills. (Note 1)
 // Note: Offensive pet skills need at least pet_attack_support or 
 // Note: Offensive pet skills need at least pet_attack_support or 
 // pet_damage_support to work (they trigger while the pet is attacking).
 // pet_damage_support to work (they trigger while the pet is attacking).
@@ -81,3 +74,7 @@ pet_ignore_infinite_def: yes
 
 
 // Whether or not the pet will continue to attack when the master is dead. (Note 1)
 // Whether or not the pet will continue to attack when the master is dead. (Note 1)
 pet_master_dead: no
 pet_master_dead: no
+
+// Send auto-feed notice even if the client setting is OFF (Note 1) 
+// Official: yes
+pet_autofeed_always: yes

+ 1 - 2
conf/msg_conf/map_msg.conf

@@ -458,8 +458,7 @@
 // Homunculus messages
 // Homunculus messages
 450: You already have a homunculus
 450: You already have a homunculus
 
 
-// Return pet to egg message
-451: You can't return your pet because your inventory is full.
+//451 free
 
 
 // Message System
 // Message System
 460: Please enter a valid language (usage: @langtype <language>).
 460: Please enter a valid language (usage: @langtype <language>).

+ 1 - 2
conf/msg_conf/map_msg_chn.conf

@@ -441,8 +441,7 @@
 // Homunculus messages
 // Homunculus messages
 450: 你已經擁有一個人工生命體了
 450: 你已經擁有一個人工生命體了
 
 
-// Return pet to egg message
-451: 你無法收回寵物,因為你身上沒有空間了
+//451 free
 
 
 // Message System
 // Message System
 460: 請輸入合法的語言 (usage: @langtype <language>).
 460: 請輸入合法的語言 (usage: @langtype <language>).

+ 1 - 2
conf/msg_conf/map_msg_frn.conf

@@ -449,8 +449,7 @@
 // Homunculus messages
 // Homunculus messages
 450: Vous possédez déjà un homunculus
 450: Vous possédez déjà un homunculus
 
 
-// Return pet to egg message
-451: Vous ne pouvez pas remettre votre pet dans son oeuf car votre inventaire est plein.
+//451 free
 
 
 // Message System
 // Message System
 460: Entrez une langue (usage: @langtype <langue>).
 460: Entrez une langue (usage: @langtype <langue>).

+ 1 - 2
conf/msg_conf/map_msg_idn.conf

@@ -459,8 +459,7 @@
 // Pesan-pesan untuk Homunculus
 // Pesan-pesan untuk Homunculus
 450: Kamu sudah memiliki homunculus
 450: Kamu sudah memiliki homunculus
 
 
-// Pesan tentang mengembalikan peliharaan ke telur
-451: Kamu tidak dapat mengembalikan peliharaan kamu karena inventory penuh.
+//451 free
 
 
 // Sistem Pesan
 // Sistem Pesan
 460: Harap masukkan tipe bahasa yang valid. (Penggunaan: @langtype <bahasa>).
 460: Harap masukkan tipe bahasa yang valid. (Penggunaan: @langtype <bahasa>).

+ 1 - 2
conf/msg_conf/map_msg_por.conf

@@ -468,8 +468,7 @@
 // Mensagens de homunculus
 // Mensagens de homunculus
 450: Você já possui um homunculus
 450: Você já possui um homunculus
 
 
-// Mensagem de retorno do pet ao ovo
-451: Você não pode retornar o seu bichinho de estimação para o ovo pois o seu inventário está lotado.
+//451 free
 
 
 // Sistema de Mensagens
 // Sistema de Mensagens
 460: Digite um idioma válido (uso: @langtype <idioma>).
 460: Digite um idioma válido (uso: @langtype <idioma>).

+ 1 - 2
conf/msg_conf/map_msg_rus.conf

@@ -449,8 +449,7 @@
 // Сообщения команды @makehomun
 // Сообщения команды @makehomun
 450: У вас уже есть гомункулус
 450: У вас уже есть гомункулус
 
 
-// Возвращение питомца в яйцо
-451: Вы не можете вернуть питомца в яйцо, потому что ваш инвентарь забит.
+//451 free
 
 
 // @langtype
 // @langtype
 460: Введите существующий язык (Используйте: @langtype <язык>).
 460: Введите существующий язык (Используйте: @langtype <язык>).

+ 1 - 2
conf/msg_conf/map_msg_spn.conf

@@ -458,8 +458,7 @@
 // Mensajes de homúnculos
 // Mensajes de homúnculos
 450: Ya tienes un homúnculo.
 450: Ya tienes un homúnculo.
 
 
-// Mensaje al devolver la mascota al huevo
-451: No puedes devolver tu mascota al huevo porque tu inventario está lleno.
+//451 free
 
 
 // Sistema de mensajería
 // Sistema de mensajería
 460: Introduce un idioma válido (instrucciones: @langtype <idioma>)
 460: Introduce un idioma válido (instrucciones: @langtype <idioma>)

+ 1 - 2
conf/msg_conf/map_msg_tha.conf

@@ -447,8 +447,7 @@
 // Homunculus messages
 // Homunculus messages
 450: ¤Ø³ÁÕ Homunculus ÍÂÙèáÅéÇ.
 450: ¤Ø³ÁÕ Homunculus ÍÂÙèáÅéÇ.
 
 
-// Return pet to egg message
-451: ¤Ø³äÁèÊÒÁÒöà¡çºÊѵÇìàÅÕé§ä´éà¾ÃÒЪèͧà¡çº¢Í§ã¹µÑÇÅФÃàµçÁ.
+//451 free
 
 
 // Message System
 // Message System
 460: â»Ã´àÅ×Í¡ÀÒÉÒ·Õèµéͧ¡Òà (ÇÔ¸Õãªé: @langtype <ÀÒÉÒ>).
 460: â»Ã´àÅ×Í¡ÀÒÉÒ·Õèµéͧ¡Òà (ÇÔ¸Õãªé: @langtype <ÀÒÉÒ>).

+ 0 - 60
db/import-tmpl/pet_db.txt

@@ -1,60 +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 Hunger is decreased every [HungryDelay] seconds.
-// 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, 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.
-
-//petskillattack2 skillid, damage, hits, rate, bonusrate
-//Same as petskillattack, but the damage and number of hits is fixed
-//the damage specified is total, not per hit.
-
-//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
-
-//petheal amount, delay, hp%, sp%
-//Similar to petskillsupport, but the skill is fixed to heal (28) and the
-//heal-amount is fixed to the value given.
-
-//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 (or
-//petskillattack2) and petskillsupport (or petheal) at the same time,
-//but only one of each.
-

+ 486 - 0
db/import-tmpl/pet_db.yml

@@ -0,0 +1,486 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2019 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program 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/>.
+#
+###########################################################################
+# Custom Pet Database
+###########################################################################
+#
+# Pet Settings
+#
+###########################################################################
+# - Mob                      Monster that can be used as pet
+#   TameItem                 Pet Tame Item.
+#   EggItem                  Pet Egg Item.
+#   EquipItem                Pet Accessory Item. (Default: 0)
+#   FoodItem                 Pet Food Item. (Default: 0)
+#   Fullness                 The amount of hunger is decreased every [HungryDelay] seconds.
+#   HungryDelay              The amount of time in seconds it takes for hunger to decrease after feeding. (Default: 60)
+#   HungerIncrease           The amount of hunger that is increased every time the pet is fed (Default: 20)
+#   IntimacyStart            Amount of Intimacy the pet starts with. (Default: 250)
+#   IntimacyFed              Amount of Intimacy that is increased when fed. (Default: 50)
+#   IntimacyOverfed          Amount of Intimacy that is increased when over-fed. (Default: -100)
+#   IntimacyHungry           Amount of Intimacy that is increased when the pet is hungry. (Default: -5)
+#   IntimacyOwnerDie         Amount of Intimacy that is increased when the pet owner dies. (Default: -20)
+#   CaptureRate              Capture success rate. (10000 = 100%)
+#   SpecialPerformance       If a pet has a Special Performance. (Default: true)
+#   AttackRate               Rate of which the pet will attack [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   RetaliateRate            Rate of which the pet will retaliate when master is being attacked [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   ChangeTargetRate         Rate of which the pet will change its attack target. (10000 = 100%)
+#   AllowAutoFeed            Allows turning automatic pet feeding on. (Default: false)
+#   Script                   Bonus script to execute when the pet is alive. (Default: null)
+#   SupportScript            Bonus script to execute when pet_status_support is enabled. (Default: null)
+#   Evolution:               Pet evolution settings. (Optional) (Default: null)
+#     - Target               Mob this pet can evolve to.
+#       ItemRequirements:      Item requirements for evolving this pet.
+#         - Item               Self-explanatory
+#           Amount
+###########################################################################
+
+Header:
+  Type: PET_DB
+  Version: 1
+
+#Body:
+#  - Mob: PORING
+#    AttackRate: 350
+#    RetaliateRate: 400
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petloot 10;
+#  - Mob: DROPS
+#    AttackRate: 300
+#    RetaliateRate: 400
+#    ChangeTargetRate: 500
+#    SupportScript: >
+#      petloot 10;
+#  - Mob: POPORING
+#    AttackRate: 300
+#    RetaliateRate: 500
+#    ChangeTargetRate: 400
+#    SupportScript: >
+#      petloot 15;
+#  - Mob: LUNATIC
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 1000
+#    SupportScript: >
+#      petskillbonus bLuk,3,10,50;
+#  - Mob: PICKY
+#    AttackRate: 500
+#    RetaliateRate: 600
+#    ChangeTargetRate: 50
+#    SupportScript: >
+#      petskillbonus bStr,3,10,50;
+#  - Mob: CHONCHON
+#    AttackRate: 500
+#    RetaliateRate: 500
+#    ChangeTargetRate: 250
+#    SupportScript: >
+#      petskillbonus bAgi,4,10,50;
+#  - Mob: STEEL_CHONCHON
+#    AttackRate: 500
+#    RetaliateRate: 500
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillbonus bAgiVit,4,20,40;
+#  - Mob: HUNTER_FLY
+#    AttackRate: 500
+#    RetaliateRate: 500
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillattack2 "NPC_WINDATTACK",888,2,0,10;
+#  - Mob: SAVAGE_BABE
+#    AttackRate: 500
+#    RetaliateRate: 500
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillbonus bVit,4,10,50;
+#  - Mob: DESERT_WOLF_B
+#    AttackRate: 400
+#    RetaliateRate: 400
+#    ChangeTargetRate: 400
+#    SupportScript: >
+#      petskillattack "SM_PROVOKE",1,0,5;
+#  - Mob: ROCKER
+#    AttackRate: 350
+#    RetaliateRate: 350
+#    ChangeTargetRate: 600
+#    SupportScript: >
+#      petskillbonus bAllStats,1,10,50;
+#  - Mob: SPORE
+#    AttackRate: 350
+#    RetaliateRate: 500
+#    ChangeTargetRate: 500
+#    SupportScript: >
+#      petrecovery SC_POISON,60;
+#  - Mob: POISON_SPORE
+#    AttackRate: 600
+#    RetaliateRate: 200
+#    ChangeTargetRate: 400
+#    SupportScript: >
+#      petskillattack "NPC_POISON",20,0,10;
+#  - Mob: PECOPECO
+#    AttackRate: 400
+#    RetaliateRate: 500
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillbonus bSpeedRate,25,20,20;
+#  - Mob: SMOKIE
+#    AttackRate: 600
+#    RetaliateRate: 600
+#    ChangeTargetRate: 100
+#    SupportScript: >
+#      petskillbonus bPerfectHide,1,3600,0;
+#  - Mob: YOYO
+#    AttackRate: 300
+#    RetaliateRate: 800
+#    ChangeTargetRate: 400
+#    SupportScript: >
+#      petloot 20;
+#  - Mob: ORK_WARRIOR
+#    AttackRate: 600
+#    RetaliateRate: 200
+#    ChangeTargetRate: 300
+#    SupportScript: >
+#      petskillattack2 "NPC_PIERCINGATT",100,1,0,10;
+#  - Mob: MUNAK
+#    AttackRate: 300
+#    RetaliateRate: 750
+#    ChangeTargetRate: 300
+#    SupportScript: >
+#      petskillattack2 "NPC_DARKNESSATTACK",444,1,0,10;
+#  - Mob: DOKEBI
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "BS_HAMMERFALL",1,0,10;
+#  - Mob: SOHEE
+#    AttackRate: 100
+#    RetaliateRate: 1000
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillsupport "AL_HEAL",5,60,33,100;
+#  - Mob: ISIS
+#    AttackRate: 650
+#    RetaliateRate: 450
+#    ChangeTargetRate: 150
+#    SupportScript: >
+#      petskillsupport "PR_MAGNIFICAT",2,60,50,50;
+#  - Mob: PETIT
+#    AttackRate: 800
+#    RetaliateRate: 400
+#    ChangeTargetRate: 100
+#    SupportScript: >
+#      petskillattack2 "WZ_HEAVENDRIVE",500,1,0,10;
+#  - Mob: DEVIRUCHI
+#    AttackRate: 800
+#    RetaliateRate: 200
+#    ChangeTargetRate: 100
+#    SupportScript: >
+#      petskillbonus bAgiDexStr,6,20,40;
+#  - Mob: BAPHOMET_
+#    AttackRate: 1000
+#    RetaliateRate: 100
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillattack2 "NPC_DARKNESSATTACK",1776,4,0,5;
+#  - Mob: BON_GUN
+#    AttackRate: 600
+#    RetaliateRate: 200
+#    ChangeTargetRate: 400
+#    SupportScript: >
+#      petskillattack2 "NPC_DARKNESSATTACK",555,1,1,1;
+#  - Mob: ZHERLTHSH
+#    AttackRate: 1000
+#    RetaliateRate: 100
+#    ChangeTargetRate: 500
+#    SupportScript: >
+#      petskillattack "AS_SONICBLOW",1,0,3;
+#  - Mob: ALICE
+#    AttackRate: 100
+#    RetaliateRate: 1000
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillsupport "AL_HEAL",5,60,25,100;
+#  - Mob: EVENT_RICECAKE
+#    AttackRate: 500
+#    RetaliateRate: 500
+#    ChangeTargetRate: 200
+#    SupportScript: >
+#      petskillsupport "CR_DEFENDER",3,240,50,100;
+#  - Mob: GOBLINE_XMAS
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "MG_SIGHT",5,5,5;
+#  - Mob: CHUNG_E
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "CR_SHIELDCHARGE",5,5,5;
+#  - Mob: ECLIPSE_P
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "TF_THROWSTONE",1,5,5;
+#  - Mob: GOBLIN_1
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "NPC_WINDATTACK",5,5,5;
+#  - Mob: GOBLIN_2
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "NPC_FIREATTACK",5,5,5;
+#  - Mob: GOBLIN_4
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "NPC_GROUNDATTACK",5,5,5;
+#  - Mob: DELETER_
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "SM_MAGNUM",5,5,5;
+#  - Mob: DIABOLIC
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "WZ_METEOR",2,5,5;
+#  - Mob: WANDER_MAN
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "NPC_UNDEADATTACK",5,5,5;
+#  - Mob: P_CHUNG_E
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      petskillattack "CR_SHIELDCHARGE",5,5,5;
+#  - Mob: GOLEM
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MARIONETTE
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MEDUSA
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: WHISPER
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: GOBLIN_LEADER
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: SUCCUBUS
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      bonus2 bHPDrainRate,10,5;
+#  - Mob: INCUBUS
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#    SupportScript: >
+#      bonus bMaxSPRate,3;
+#      bonus2 bSPDrainRate,10,1;
+#  - Mob: NIGHTMARE_TERROR
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: SHINOBI
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MIYABI_NINGYO
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: WICKED_NYMPH
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: STONE_SHOOTER
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: DULLAHAN
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: LOLI_RURI
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: CIVIL_SERVANT
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: LEAF_CAT
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: BACSOJIN_
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: IMP
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: E_CRAMP
+#    AttackRate: 350
+#    RetaliateRate: 400
+#    ChangeTargetRate: 800
+#  - Mob: E_HYDRA
+#    AttackRate: 350
+#    RetaliateRate: 400
+#    ChangeTargetRate: 800
+#  - Mob: J_TAINI
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: XMAS_LUNATIC
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: TIKBALANG
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MARIN
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: LITTLE_PORING
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: NINE_TAIL
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: GREMLIN
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MUMMY
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: TEDDY_BEAR
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MASTERING
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: METALLER
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: ANGELING
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: MOONLIGHT
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: SAVAGE
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: HIGH_ORC
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: CHOCO
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: ANCIENT_MUMMY
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: AM_MUT
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: CAT_O_NINE_TAIL
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: GRAND_PECO
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: HYEGUN
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: HODREMLIN
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: XM_TEDDY_BEAR
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: DR_EGGRING
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: DR_LUNATIC
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: LITTLE_ISIS
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: DIABOLIC2
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: DELETER_2
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800
+#  - Mob: SWEETS_DROPS
+#    AttackRate: 300
+#    RetaliateRate: 300
+#    ChangeTargetRate: 800

+ 63 - 0
db/pet_db.yml

@@ -0,0 +1,63 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2019 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program 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/>.
+#
+###########################################################################
+# Pet Database
+###########################################################################
+#
+# Pet Settings
+#
+###########################################################################
+# - Mob                      Monster that can be used as pet
+#   TameItem                 Pet Tame Item.
+#   EggItem                  Pet Egg Item.
+#   EquipItem                Pet Accessory Item. (Default: 0)
+#   FoodItem                 Pet Food Item. (Default: 0)
+#   Fullness                 The amount of hunger is decreased every [HungryDelay] seconds.
+#   HungryDelay              The amount of time in seconds it takes for hunger to decrease after feeding. (Default: 60)
+#   HungerIncrease           The amount of hunger that is increased every time the pet is fed (Default: 20)
+#   IntimacyStart            Amount of Intimacy the pet starts with. (Default: 250)
+#   IntimacyFed              Amount of Intimacy that is increased when fed. (Default: 50)
+#   IntimacyOverfed          Amount of Intimacy that is increased when over-fed. (Default: -100)
+#   IntimacyHungry           Amount of Intimacy that is increased when the pet is hungry. (Default: -5)
+#   IntimacyOwnerDie         Amount of Intimacy that is increased when the pet owner dies. (Default: -20)
+#   CaptureRate              Capture success rate. (10000 = 100%)
+#   SpecialPerformance       If a pet has a Special Performance. (Default: true)
+#   AttackRate               Rate of which the pet will attack [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   RetaliateRate            Rate of which the pet will retaliate when master is being attacked [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   ChangeTargetRate         Rate of which the pet will change its attack target. (10000 = 100%)
+#   AllowAutoFeed            Allows turning automatic pet feeding on. (Default: false)
+#   Script                   Bonus script to execute when the pet is alive. (Default: null)
+#   SupportScript            Bonus script to execute when pet_status_support is enabled. (Default: null)
+#   Evolution:               Pet evolution settings. (Optional) (Default: null)
+#     - Target               Mob this pet can evolve to.
+#       ItemRequirements:      Item requirements for evolving this pet.
+#         - Item               Self-explanatory
+#           Amount
+###########################################################################
+
+Header:
+  Type: PET_DB
+  Version: 1
+
+Footer:
+  Imports:
+  - Path: db/pre-re/pet_db.yml
+    Mode: Prerenewal
+  - Path: db/re/pet_db.yml
+    Mode: Renewal
+  - Path: db/import/pet_db.yml

+ 0 - 104
db/pre-re/pet_db.txt

@@ -1,104 +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 Hunger is decreased every [HungryDelay] seconds.
-// 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.
-//Please see "The Pet AI commands" in 'doc/script_commands.txt'.
-
-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; }
-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; }
-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; }
-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; }
-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; }
-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; }
-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; }
-1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,60,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack2 "NPC_WINDATTACK",888,2,0,10; },{ bonus bFlee,-5; bonus bFlee2,2; }
-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; }
-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,5;},{ bonus bInt,1; bonus bMaxSP,50; }
-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; }
-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; }
-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,10; },{ bonus bStr,1; bonus bInt,1; }
-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; }
-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; }
-1023,ORK_WARRIOR,Orc Warrior,635,9017,10009,537,80,60,20,100,250,20,500,150,1,0,600,200,300,{ petskillattack2 "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,{ petskillattack2 "NPC_DARKNESSATTACK",444,1,0,10; },{ bonus bInt,1; bonus bDef,1; }
-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,10; },{ bonus bMatkRate,1; bonus bAtkRate,-1; }
-1170,SOHEE,Sohee,638,9020,10016,537,80,60,10,100,250,20,500,150,0,0,100,1000,200,{ petskillsupport "AL_HEAL",5,60,33,100; },{ bonus bStr,1; bonus bDex,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; }
-1155,PETIT,Petite,640,9022,10011,537,80,60,20,100,250,20,500,150,0,0,800,400,100,{ petskillattack2 "WZ_HEAVENDRIVE",500,1,0,10; },{ bonus bDef,-2; bonus bMdef,-2; bonus bAspdRate,1; }
-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; }
-1101,BAPHOMET_,Baphomet Jr.,642,9024,10001,518,80,60,10,100,250,20,200,150,0,0,1000,100,200,{ petskillattack2 "NPC_DARKNESSATTACK",1776,4,0,5; },{ bonus bDef,1; bonus bMdef,1; bonus2 bResEff,Eff_Stun,-100; }
-1188,BON_GUN,Bon Gun,659,9025,10020,537,80,60,30,100,250,20,500,150,1,0,600,200,400,{ petskillattack2 "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,3; },{ bonus2 bAddRace,RC_Demihuman,2; bonus2 bAddRace,RC_Player,2; bonus2 bMagicAddRace,RC_DemiHuman,2; bonus2 bMagicAddRace,RC_Player,2; }
-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_DemiHuman,1; bonus2 bSubRace,RC_Player,1; }
-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; }
-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,5,5; },{ bonus bMaxHP,30; bonus2 bSubEle,Ele_Water,1; }
-
-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,5,5; },{ bonus bDef,1; bonus2 bSubRace,RC_DemiHuman,1; bonus2 bSubRace,RC_Player,1; }
-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,5,5; },{}
-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,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,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,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,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,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,5,5; },{ bonus bAgi,3; bonus bDex,1; }
-
-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,5,5; },{}
-
-// New pets JapanRO Mobile
-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_DemiHuman,3; bonus2 bAddRace,RC_Player,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,10; }
-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; }
-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; }
-
-// Brasilis Quest - Suspicious Beach [UNHATCHABLE]
-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
-
-// New pets (FIX ME: pet bonuses for 2210 and 2313 do not require loyalty)
-//2200,J_TAINI,Tiny,0,9057,0,512,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{}
-//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; }
-//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; }
-1242,MARIN,Marin,12789,9061,10039,6534,80,60,50,100,250,20,2000,150,1,0,300,300,800,{},{}
-//2398,LITTLE_PORING,Novice Poring,12846,9062,0,531,80,60,1000,0,250,0,5000,150,0,0,300,300,800,{},{ bonus bHPrecovRate,50; }

+ 867 - 0
db/pre-re/pet_db.yml

@@ -0,0 +1,867 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2019 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program 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/>.
+#
+###########################################################################
+# Pre-Renewal Pet Database
+###########################################################################
+#
+# Pet Settings
+#
+###########################################################################
+# - Mob                      Monster that can be used as pet
+#   TameItem                 Pet Tame Item.
+#   EggItem                  Pet Egg Item.
+#   EquipItem                Pet Accessory Item. (Default: 0)
+#   FoodItem                 Pet Food Item. (Default: 0)
+#   Fullness                 The amount of hunger is decreased every [HungryDelay] seconds.
+#   HungryDelay              The amount of time in seconds it takes for hunger to decrease after feeding. (Default: 60)
+#   HungerIncrease           The amount of hunger that is increased every time the pet is fed (Default: 20)
+#   IntimacyStart            Amount of Intimacy the pet starts with. (Default: 250)
+#   IntimacyFed              Amount of Intimacy that is increased when fed. (Default: 50)
+#   IntimacyOverfed          Amount of Intimacy that is increased when over-fed. (Default: -100)
+#   IntimacyHungry           Amount of Intimacy that is increased when the pet is hungry. (Default: -5)
+#   IntimacyOwnerDie         Amount of Intimacy that is increased when the pet owner dies. (Default: -20)
+#   CaptureRate              Capture success rate. (10000 = 100%)
+#   SpecialPerformance       If a pet has a Special Performance. (Default: true)
+#   AttackRate               Rate of which the pet will attack [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   RetaliateRate            Rate of which the pet will retaliate when master is being attacked [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   ChangeTargetRate         Rate of which the pet will change its attack target. (10000 = 100%)
+#   AllowAutoFeed            Allows turning automatic pet feeding on. (Default: false)
+#   Script                   Bonus script to execute when the pet is alive. (Default: null)
+#   SupportScript            Bonus script to execute when pet_status_support is enabled. (Default: null)
+#   Evolution:               Pet evolution settings. (Optional) (Default: null)
+#     - Target               Mob this pet can evolve to.
+#       ItemRequirements:      Item requirements for evolving this pet.
+#         - Item               Self-explanatory
+#           Amount
+###########################################################################
+
+Header:
+  Type: PET_DB
+  Version: 1
+
+Body:
+  - Mob: PORING
+    TameItem: Unripe_Apple
+    EggItem: Poring_Egg
+    EquipItem: Backpack
+    FoodItem: Apple_Juice
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bLuk,2;
+        bonus bCritical,1;
+      }
+  - Mob: DROPS
+    TameItem: Orange_Juice
+    EggItem: Drops_Egg
+    EquipItem: Backpack
+    FoodItem: Yellow_Herb
+    Fullness: 80
+    IntimacyFed: 40
+    CaptureRate: 1500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,3;
+        bonus bAtk,3;
+      }
+  - Mob: POPORING
+    TameItem: Bitter_Herb
+    EggItem: Poporing_Egg
+    EquipItem: Backpack
+    FoodItem: Green_Herb
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bLuk,2;
+        bonus2 bSubEle,Ele_Poison,10;
+      }
+  - Mob: LUNATIC
+    TameItem: Rainbow_Carrot
+    EggItem: Lunatic_Egg
+    EquipItem: Silk_Ribbon
+    FoodItem: Carrot_Juice
+    Fullness: 80
+    IntimacyFed: 40
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,2;
+        bonus bAtk,2;
+      }
+  - Mob: PICKY
+    TameItem: Earthworm_The_Dude
+    EggItem: Picky_Egg
+    EquipItem: Tiny_Egg_Shell
+    FoodItem: Red_Herb
+    Fullness: 80
+    IntimacyFed: 40
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bStr,1;
+        bonus bAtk,5;
+      }
+  - Mob: CHONCHON
+    TameItem: Rotten_Fish
+    EggItem: Chonchon_Egg
+    EquipItem: Monster_Oxygen_Mask
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 1500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,1;
+        bonus bFlee,2;
+      }
+  - Mob: STEEL_CHONCHON
+    TameItem: Lusty_Iron
+    EggItem: Steel_Chonchon_Egg
+    EquipItem: Monster_Oxygen_Mask
+    FoodItem: Iron_Ore
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bFlee,6;
+        bonus bAgi,-1;
+      }
+  - Mob: HUNTER_FLY
+    TameItem: Monster_Juice
+    EggItem: Hunter_Fly_Egg
+    EquipItem: Monster_Oxygen_Mask
+    FoodItem: Red_Gemstone
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bFlee,-5;
+        bonus bFlee2,2;
+      }
+  - Mob: SAVAGE_BABE
+    TameItem: Sweet_Milk
+    EggItem: Savage_Bebe_Egg
+    EquipItem: Green_Lace
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 40
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,1;
+        bonus bMaxHP,50;
+      }
+  - Mob: DESERT_WOLF_B
+    TameItem: Well_Dried_Bone
+    EggItem: Baby_Desert_Wolf_Egg
+    EquipItem: Transparent_Headgear
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 40
+    CaptureRate: 1000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bInt,1;
+        bonus bMaxSP,50;
+      }
+  - Mob: ROCKER
+    TameItem: Singing_Flower
+    EggItem: Rocker_Egg
+    EquipItem: Rocker_Glasses
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHPrecovRate,5;
+        bonus bMaxHP,25;
+      }
+  - Mob: SPORE
+    TameItem: Dew_Laden_Moss
+    EggItem: Spore_Egg
+    EquipItem: Bark_Shorts
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,5;
+        bonus bAtk,-2;
+      }
+  - Mob: POISON_SPORE
+    TameItem: Deadly_Noxious_Herb
+    EggItem: Poison_Spore_Egg
+    EquipItem: Bark_Shorts
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 1000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bStr,1;
+        bonus bInt,1;
+      }
+  - Mob: PECOPECO
+    TameItem: Fatty_Chubby_Earthworm
+    EggItem: PecoPeco_Egg
+    EquipItem: Battered_Pot
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,150;
+        bonus bMaxSP,-10;
+      }
+  - Mob: SMOKIE
+    TameItem: Baked_Yam
+    EggItem: Smokie_Egg
+    EquipItem: Red_Muffler
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,1;
+        bonus bFlee2,1;
+      }
+  - Mob: YOYO
+    TameItem: Tropical_Banana
+    EggItem: Yoyo_Egg
+    EquipItem: Monkey_Circlet
+    FoodItem: Banana_Juice
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,3;
+        bonus bLuk,-1;
+      }
+  - Mob: ORK_WARRIOR
+    TameItem: Horror_Of_Tribe
+    EggItem: Orc_Warrior_Egg
+    EquipItem: Wild_Flower
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAtk,10;
+        bonus bDef,-3;
+      }
+  - Mob: MUNAK
+    TameItem: No_Recipient
+    EggItem: Munak_Egg
+    EquipItem: Punisher
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bInt,1;
+        bonus bDef,1;
+      }
+  - Mob: DOKEBI
+    TameItem: Old_Broom
+    EggItem: Dokkaebi_Egg
+    EquipItem: Wig
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,1;
+        bonus bAtkRate,-1;
+      }
+  - Mob: SOHEE
+    TameItem: Silver_Knife_Of_Chaste
+    EggItem: Sohee_Egg
+    EquipItem: Golden_Bell
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bStr,1;
+        bonus bDex,1;
+      }
+  - Mob: ISIS
+    TameItem: Armlet_Of_Obedience
+    EggItem: Isis_Egg
+    EquipItem: Queen's_Hair_Ornament
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,-1;
+        bonus bAtkRate,1;
+      }
+  - Mob: PETIT
+    TameItem: Shining_Stone
+    EggItem: Green_Petite_Egg
+    EquipItem: Stellar_Hairpin
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDef,-2;
+        bonus bMdef,-2;
+        bonus bAspdRate,1;
+      }
+  - Mob: DEVIRUCHI
+    TameItem: Contracts_In_Shadow
+    EggItem: Deviruchi_Egg
+    EquipItem: Pacifier
+    FoodItem: Shoot
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,1;
+        bonus bAtkRate,1;
+        bonus bMaxHPrate,-3;
+        bonus bMaxSPrate,-3;
+      }
+  - Mob: BAPHOMET_
+    TameItem: Book_Of_Devil
+    EggItem: Bapho_Jr._Egg
+    EquipItem: Skull_Helm
+    FoodItem: Honey
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDef,1;
+        bonus bMdef,1;
+        bonus2 bResEff,Eff_Stun,-100;
+      }
+  - Mob: BON_GUN
+    TameItem: Heart_Of_Her
+    EggItem: Bongun_Egg
+    EquipItem: Sword_Of_Grave_Keeper
+    FoodItem: Pet_Food
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,1;
+        bonus2 bResEff,Eff_Stun,100;
+      }
+  - Mob: ZHERLTHSH
+    TameItem: Prohibition_Red_Candle
+    EggItem: Zherlthsh_Egg
+    FoodItem: Immortal_Heart
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 300
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bAddRace,RC_Demihuman,2;
+        bonus2 bMagicAddRace,RC_DemiHuman,2;
+        bonus2 bAddRace,RC_Player,2;
+        bonus2 bMagicAddRace,RC_Player,2;
+      }
+  - Mob: ALICE
+    TameItem: Sway_Apron
+    EggItem: Alice_Egg
+    FoodItem: White_Potion
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 800
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMdef,1;
+        bonus2 bSubRace,RC_DemiHuman,1;
+        bonus2 bSubRace,RC_Player,1;
+      }
+  - Mob: EVENT_RICECAKE
+    EggItem: Rice_Cake_Egg
+    FoodItem: Green_Herb
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubEle,Ele_Neutral,1;
+        bonus bMaxHPrate,-1;
+      }
+  - Mob: GOBLINE_XMAS
+    TameItem: Sweet_Candy_Striper
+    EggItem: Santa_Goblin_Egg
+    FoodItem: Scell
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 2000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,30;
+        bonus2 bSubEle,Ele_Water,1;
+      }
+  - Mob: CHUNG_E
+    TameItem: Tantanmen
+    EggItem: Chung_E_Egg
+    FoodItem: Bun_
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 2000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDef,1;
+        bonus2 bSubRace,RC_DemiHuman,1;
+        bonus2 bSubRace,RC_Player,1;
+      }
+  - Mob: ECLIPSE_P
+    EggItem: Spring_Rabbit_Egg
+    FoodItem: Bok_Choy
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 2000
+    SpecialPerformance: false
+  - Mob: GOBLIN_1
+    TameItem: Knife_Goblin_Ring
+    EggItem: Knife_Goblin_Egg
+    FoodItem: Green_Apple
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: GOBLIN_2
+    TameItem: Flail_Goblin_Ring
+    EggItem: Flail_Goblin_Egg
+    FoodItem: Green_Apple
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: GOBLIN_4
+    TameItem: Hammer_Goblin_Ring
+    EggItem: Hammer_Goblin_Egg
+    FoodItem: Green_Apple
+    Fullness: 80
+    IntimacyFed: 50
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: DELETER_
+    TameItem: Holy_Marble
+    EggItem: Red_Deleter_Egg
+    FoodItem: Whole_Barbecue
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: DIABOLIC
+    TameItem: Red_Burning_Stone
+    EggItem: Diabolic_Egg
+    FoodItem: Meat_Veg_Skewer
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: WANDER_MAN
+    TameItem: Skull_Of_Vagabond
+    EggItem: Wanderer_Egg
+    FoodItem: Spirit_Liquor
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 800
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,3;
+        bonus bDex,1;
+      }
+  - Mob: P_CHUNG_E
+    EggItem: New_Year_Doll_Egg
+    FoodItem: Mojji
+    Fullness: 80
+    IntimacyFed: 30
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: GOLEM
+    TameItem: Magical_Lithography
+    EggItem: Golem_Egg
+    EquipItem: Windup_Spring
+    FoodItem: Mystic_Stone
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,100;
+        bonus bFlee,-5;
+      }
+  - Mob: MARIONETTE
+    TameItem: Delicious_Shaved_Ice
+    EggItem: Marionette_Egg
+    EquipItem: Star_Hairband
+    FoodItem: Small_Snow_Flower
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bSPrecovRate,3;
+      }
+  - Mob: MEDUSA
+    TameItem: Splendid_Mirror
+    EggItem: Medusa_Egg
+    EquipItem: Queen's_Coronet
+    FoodItem: Apple_Pudding
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,1;
+        bonus2 bResEff,Eff_Stone,500;
+      }
+  - Mob: WHISPER
+    TameItem: Fit_Pipe
+    EggItem: Whisper_Egg
+    EquipItem: Spirit_Chain_
+    FoodItem: Damp_Darkness
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bFlee,7;
+        bonus bDef,-3;
+      }
+  - Mob: GOBLIN_LEADER
+    TameItem: Staff_Of_Leader
+    EggItem: Goblin_Leader_Egg
+    EquipItem: Nice_Badge
+    FoodItem: Big_Cell
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 50
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bAddRace,RC_DemiHuman,3;
+        bonus2 bAddRace,RC_Player,3;
+      }
+  - Mob: SUCCUBUS
+    TameItem: Boy's_Naivety
+    EggItem: Succubus_Egg
+    EquipItem: Black_Butterfly_Mask
+    FoodItem: Vital_Flower_
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bHpDrainRate,50,5;
+      }
+  - Mob: INCUBUS
+    TameItem: Gril's_Naivety
+    EggItem: Incubus_Egg
+    EquipItem: Ball_Mask
+    FoodItem: Vital_Flower
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 50
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSPRate,3;
+      }
+  - Mob: NIGHTMARE_TERROR
+    TameItem: Hell_Contract
+    EggItem: Nightmare_Terror_Egg
+    EquipItem: Hell_Horn
+    FoodItem: Fresh_Plant
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bResEff,Eff_Sleep,10000;
+      }
+  - Mob: SHINOBI
+    TameItem: Kuloren
+    EggItem: Shinobi_Egg
+    EquipItem: Wine_On_Sleeve
+    FoodItem: Grilled_Rice_Cake
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,2;
+      }
+  - Mob: MIYABI_NINGYO
+    TameItem: Gril_Doll
+    EggItem: Miyabi_Ningyo_Egg
+    EquipItem: Summer_Fan
+    FoodItem: Well_Ripened_Berry
+    Fullness: 80
+    IntimacyFed: 15
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bInt,1;
+        bonus bCastrate,-3;
+      }
+  - Mob: WICKED_NYMPH
+    TameItem: Charming_Lotus
+    EggItem: Wicked_Nymph_Egg
+    EquipItem: Jade_Trinket
+    FoodItem: Morning_Dew
+    Fullness: 80
+    IntimacyFed: 15
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSP,30;
+        bonus bSPrecovRate,5;
+      }
+  - Mob: STONE_SHOOTER
+    TameItem: Oilpalm_Coconut
+    EggItem: Stone_Shooter_Egg
+    EquipItem: Apro_Hair
+    FoodItem: Plant_Neutrient
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubEle,Ele_Fire,3;
+      }
+  - Mob: DULLAHAN
+    TameItem: Luxury_Whisky_Bottle
+    EggItem: Dullahan_Egg
+    EquipItem: Death_Coil
+    FoodItem: Sunset_On_The_Rock
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritAtkRate,5;
+      }
+  - Mob: LOLI_RURI
+    TameItem: Very_Red_Juice
+    EggItem: Loli_Ruri_Egg
+    EquipItem: Fashionable_Glasses
+    FoodItem: Pumpkin_Pie_
+    Fullness: 80
+    IntimacyFed: 15
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHPRate,3;
+        bonus3 bAutoSpellWhenHit,"AL_HEAL",1,10;
+      }
+  - Mob: CIVIL_SERVANT
+    TameItem: Fan_Of_Wind
+    EggItem: Civil_Servant_Egg
+    EquipItem: Golden_Earing
+    FoodItem: Flavored_Alcohol
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSP,10;
+      }
+  - Mob: LEAF_CAT
+    TameItem: Very_Soft_Plant
+    EggItem: Leaf_Cat_Egg
+    EquipItem: Green_Lucky_Bag
+    FoodItem: Fish_With_Blue_Back
+    Fullness: 80
+    IntimacyFed: 20
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubRace,RC_Brute,3;
+      }
+  - Mob: BACSOJIN_
+    TameItem: Shiny_Wing_Gown
+    EggItem: Bacsojin_Egg
+    EquipItem: Round_Hair_Ornament
+    FoodItem: Traditional_Cookie
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 2000
+    SpecialPerformance: false
+  - Mob: IMP
+    TameItem: Flaming_Ice
+    EggItem: Imp_Egg
+    EquipItem: Horn_Protector
+    FoodItem: Flame_Gemstone
+    Fullness: 80
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubEle,Ele_Fire,2;
+        bonus2 bAddEle,Ele_Fire,2;
+      }

+ 56 - 0
db/re/item_db.txt

@@ -5999,11 +5999,54 @@
 9060,Brownie_Egg,Brownie Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9060,Brownie_Egg,Brownie Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9061,Marin_Egg,Marin Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9061,Marin_Egg,Marin Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9062,Novice_Poring_Egg,Novice Poring Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9062,Novice_Poring_Egg,Novice Poring Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9063,Woodie_Egg,Woodie Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9064,Elephant_Egg,Elephant Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9065,Gorilla_Egg,Gorilla Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9066,Lion_Egg,Lion Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9067,Rhino_Egg,Rhino Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9068,Blue_Unicorn_Egg,Blue Unicorn Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9068,Blue_Unicorn_Egg,Blue Unicorn Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9069,Mastering_Egg,Mastering Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9069,Mastering_Egg,Mastering Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9070,Savage_Egg,Savage Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9070,Savage_Egg,Savage Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9071,Grand_Peco_Peco_Egg,Grand Peco Peco Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9071,Grand_Peco_Peco_Egg,Grand Peco Peco Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9072,Orc_Hero_Egg,Orc Hero Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9073,Orc_Lord_Egg,Orc Lord Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9074,Rubylit_Egg,Rubylit Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9075,Sapphilit_Egg,Sapphilit Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9076,Emelit_Egg,Emelit Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9077,Topalit_Egg,Topalit Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9078,Amelit_Egg,Amelit Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9079,Mythlit_Egg,Mythlit Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9080,Tamadora_Egg,Tamadora Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+
 9087,High_Orc_Egg,High Orc Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 9087,High_Orc_Egg,High Orc Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9088,Angeling_Egg,Angeling Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9089,Am_Mut_Egg,Am Mut Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9090,Little_Isis_Egg,Little Isis Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9091,Choco_Egg,Choco Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9092,Eggring_Egg,Eggring Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9093,Hyegun_Egg,Hyegun Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9094,Dr_Lunatic_Egg,Leaf Lunatic Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9095,Nine_Tail_Egg,Nine Tail Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9096,Cat_o_Nine_Tail_Egg,Cat o Nine Tail Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9097,Diabolic_2_Egg,Diabolic Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9098,Fire_Deleter_Egg,Fire Deleter Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9099,Teddy_Bear_Egg,Teddy Bear Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9100,Gremlin_Egg,Gremlin Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9101,Scatleton_Egg,Scatleton Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9102,Mummy_Egg,Mummy Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9103,Willow_Egg,Willow Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9104,Roween_Egg,Roween Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9105,Hodremlin_Egg,Hodremlin Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9106,Metaller_Egg,Metaller Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9107,Ancient_Mummy_Egg,Ancient Mummy Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9108,Xm_Teddy_Bear_Egg,Xmas Teddy Bear Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9109,Sweet_Drops_Egg,Sweet Drops Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+
+9111,Phreeoni_Egg,Phreeoni Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9112,Moonlight_Egg,Moonlight Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9113,Skelion_Egg,Skelion Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9114,Pouring_Egg,Pouring Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
+9115,Bacsojin2_Egg_,Bacsojin Egg,7,20,,0,,,,,,,,,,,,,{},{},{}
 //===================================================================
 //===================================================================
 // Pet Accessories
 // Pet Accessories
 //===================================================================
 //===================================================================
@@ -6046,6 +6089,9 @@
 10037,Black_Butterfly_Mask,Black Butterfly Mask,8,20,,0,,,,,,,,,,,,,{},{},{}
 10037,Black_Butterfly_Mask,Black Butterfly Mask,8,20,,0,,,,,,,,,,,,,{},{},{}
 10038,Horn_Protector,Horn Barrier,8,20,,0,,,,,,,,,,,,,{},{},{}
 10038,Horn_Protector,Horn Barrier,8,20,,0,,,,,,,,,,,,,{},{},{}
 10039,Tw_Backpack,Tw Backpack,8,20,,0,,,,,,,,,,,,,{},{},{}
 10039,Tw_Backpack,Tw Backpack,8,20,,0,,,,,,,,,,,,,{},{},{}
+10040,Red_Bell_Necklace,Red Bell Necklace,8,20,,0,,,,,,,,,,,,,{},{},{}
+10041,Shiny_Star_Button,Shiny Star Button,8,20,,0,,,,,,,,,,,,,{},{},{}
+10042,Dark_Mane,Dark Mane,8,20,,0,,,,,,,,,,,,,{},{},{}
 //===================================================================
 //===================================================================
 // Misc "Etc" Books
 // Misc "Etc" Books
 //===================================================================
 //===================================================================
@@ -11335,6 +11381,9 @@
 23126,Bullet_Case_Poison,Poison Bullet Cartridge,2,10,,250,,,,,0xFFFFFFFF,63,2,,,,,,{ getitem 13231,500; },{},{}
 23126,Bullet_Case_Poison,Poison Bullet Cartridge,2,10,,250,,,,,0xFFFFFFFF,63,2,,,,,,{ getitem 13231,500; },{},{}
 23127,Bullet_Case_Blind,Blind Bullet Cartridge,2,10,,250,,,,,0xFFFFFFFF,63,2,,,,,,{ getitem 13232,500; },{},{}
 23127,Bullet_Case_Blind,Blind Bullet Cartridge,2,10,,250,,,,,0xFFFFFFFF,63,2,,,,,,{ getitem 13232,500; },{},{}
 23177,Kafra_Card_,Kafra Card,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ callfunc "F_CashStore"; },{},{}
 23177,Kafra_Card_,Kafra Card,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ callfunc "F_CashStore"; },{},{}
+23188,Unprocessed_Parts,Unprocessed Parts,2,10,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ pet 1632; },{},{}
+23189,Small_Needle_Kit,Small Needle Kit,2,10,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ pet 1622; },{},{}
+23187,Sap_Liquid,Sap Liquid,2,10,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ pet 1180; },{},{}
 23191,Varetyr_Spear_Scroll_1_5,Level 5 Varetyr Spear,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "SO_VARETYR_SPEAR",5; },{},{}
 23191,Varetyr_Spear_Scroll_1_5,Level 5 Varetyr Spear,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "SO_VARETYR_SPEAR",5; },{},{}
 23192,Diamond_Dust_Scroll_1_5,Level 5 Diamond Dust,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "SO_DIAMONDDUST",5; },{},{}
 23192,Diamond_Dust_Scroll_1_5,Level 5 Diamond Dust,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "SO_DIAMONDDUST",5; },{},{}
 23193,Crimson_Rock_Scroll_1_5,Level 5 Crimson Rock,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "WL_CRIMSONROCK",5; },{},{}
 23193,Crimson_Rock_Scroll_1_5,Level 5 Crimson Rock,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "WL_CRIMSONROCK",5; },{},{}
@@ -11343,6 +11392,7 @@
 //
 //
 23228,Hazy_Mooncake,Hazy Mooncake,0,768,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ /* unknown */ },{},{}
 23228,Hazy_Mooncake,Hazy Mooncake,0,768,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ /* unknown */ },{},{}
 //
 //
+23256,Elixir_Bandages,Elixir Bandages,2,10,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ pet 1041; },{},{}
 23277,Mado_Box,Emergency Magic Gear,2,10000,,3000,,,,,0x00000400,56,2,,,100,,,{ setmadogear 1; },{},{}
 23277,Mado_Box,Emergency Magic Gear,2,10000,,3000,,,,,0x00000400,56,2,,,100,,,{ setmadogear 1; },{},{}
 23280,N_Fly_Wing_,Novice Fly Wing,11,10,,0,,,,,0xFFFFFFFF,63,2,,,1:98,,,{ itemskill "AL_TELEPORT",1; },{},{}
 23280,N_Fly_Wing_,Novice Fly Wing,11,10,,0,,,,,0xFFFFFFFF,63,2,,,1:98,,,{ itemskill "AL_TELEPORT",1; },{},{}
 23288,Compressed_Wing_Of_Fly,Compressed Fly Wing,11,1000,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "AL_TELEPORT",1; },{},{}
 23288,Compressed_Wing_Of_Fly,Compressed Fly Wing,11,1000,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "AL_TELEPORT",1; },{},{}
@@ -11661,6 +11711,9 @@
 25185,Locket_Pendant,Locket Pendant,3,0,,0,,,,,,,,,,,,,{},{},{}
 25185,Locket_Pendant,Locket Pendant,3,0,,0,,,,,,,,,,,,,{},{},{}
 25187,Slug_Bullet,Slug Bullet,3,1200,,1200,,,,,,,,,,,,,{},{},{}
 25187,Slug_Bullet,Slug Bullet,3,1200,,1200,,,,,,,,,,,,,{},{},{}
 25223,Para_Team_Coin,Eden Group Coin,3,0,,0,,,,,,,,,,,,,{},{},{}
 25223,Para_Team_Coin,Eden Group Coin,3,0,,0,,,,,,,,,,,,,{},{},{}
+25231,Suspicious_Bottle,Suspicious Bottle,3,0,,10,,,,,,,,,,,,,{},{},{}
+25232,Cheap_Lubricant,Cheap Lubricant,3,0,,10,,,,,,,,,,,,,{},{},{}
+25233,Cotton_Tufts,Cotton Tufts,3,0,,10,,,,,,,,,,,,,{},{},{}
 25238,New_Normal_Lubricant,New Normal Lubricant,3,0,,0,,,,,,,,,,,,,{},{},{}
 25238,New_Normal_Lubricant,New Normal Lubricant,3,0,,0,,,,,,,,,,,,,{},{},{}
 25239,New_Advanced_Lubricant,New Advanced Lubricant,3,0,,0,,,,,,,,,,,,,{},{},{}
 25239,New_Advanced_Lubricant,New Advanced Lubricant,3,0,,0,,,,,,,,,,,,,{},{},{}
 25246,Juice_Mix_Package,Juice Mix Package,3,0,,0,,,,,,,,,,,,,{},{},{}
 25246,Juice_Mix_Package,Juice Mix Package,3,0,,0,,,,,,,,,,,,,{},{},{}
@@ -11684,6 +11737,9 @@
 25283,Brown_Muffler,Brown Muffler,3,420,,10,,,,,,,,,,,,,{},{},{}
 25283,Brown_Muffler,Brown Muffler,3,420,,10,,,,,,,,,,,,,{},{},{}
 25284,Swamp_Bug_Shell,Swamp Bug Shell,3,0,,10,,,,,,,,,,,,,{},{},{}
 25284,Swamp_Bug_Shell,Swamp Bug Shell,3,0,,10,,,,,,,,,,,,,{},{},{}
 25285,Brown_Rat_Tail,Brown Rat Tail,3,0,,10,,,,,,,,,,,,,{},{},{}
 25285,Brown_Rat_Tail,Brown Rat Tail,3,0,,10,,,,,,,,,,,,,{},{},{}
+25290,Sweets_Festival_Coin,Sweets Festival Coin,3,0,,0,,,,,,,,,,,,,{},{},{}
+25375,Powerful_Soul_Essence,Powerful Soul Essence,3,0,,0,,,,,,,,,,,,,{},{},{}
+25377,Luxurious_Pet_Food,Luxurious Pet Food,3,0,,10,,,,,,,,,,,,,{},{},{}
 //
 //
 25464,World_Moving_Rights,World Moving Rights,3,20,,0,,,,,,,,,,,,,{},{},{}
 25464,World_Moving_Rights,World Moving Rights,3,20,,0,,,,,,,,,,,,,{},{},{}
 //
 //

+ 4 - 4
db/re/mob_db.txt

@@ -2796,7 +2796,7 @@
 //3633,EP16_2_VENOM_KIMERA
 //3633,EP16_2_VENOM_KIMERA
 //3634,MYSTCASE_GIANT
 //3634,MYSTCASE_GIANT
 //3635,EVENT_KOBOLD
 //3635,EVENT_KOBOLD
-//3636,LITTLE_ISIS
+3636,LITTLE_ISIS,Little Isis,Little Isis,59,2092,1,531,597,1,192,229,83,5,58,43,22,5,39,15,10,12,2,6,27,0x2003095,200,1384,768,336,0,0,0,0,0,0,0,936,5335,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 //3637,MD_SKELETON_60
 //3637,MD_SKELETON_60
 //3638,MD_SKELETON_80
 //3638,MD_SKELETON_80
 //3639,MD_SKELETON_100
 //3639,MD_SKELETON_100
@@ -2829,8 +2829,8 @@
 //3666,MD_DRAINLIAR_100
 //3666,MD_DRAINLIAR_100
 //3667,MD_DRAINLIAR_160
 //3667,MD_DRAINLIAR_160
 //3668,B_KIEL_
 //3668,B_KIEL_
-//3669,DIABOLIC2
-//3670,DELETER_2
+3669,DIABOLIC2,Diabolic2,Diabolic2,104,10572,1,2172,1629,1,544,644,68,61,103,80,53,65,78,25,10,12,0,6,47,0x2003885,150,1080,780,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+3670,DELETER_2,Deleter 2,Deleter 2,105,10000,1,2099,1574,1,510,621,114,53,98,65,49,72,57,73,10,12,1,9,43,0x308D,175,1024,624,336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 //3671,JP_MAZEMOB_01
 //3671,JP_MAZEMOB_01
 //3672,JP_MAZEMOB_02
 //3672,JP_MAZEMOB_02
 //3673,JP_MAZEMOB_03
 //3673,JP_MAZEMOB_03
@@ -2950,7 +2950,7 @@
 3787,RR_ARCLOUSE,Rr Arclouse,Swamp Arclouze,106,1120,1,864,900,1,316,126,76,36,41,73,23,29,122,15,10,12,1,4,42,0x2003885,100,768,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27177,1
 3787,RR_ARCLOUSE,Rr Arclouse,Swamp Arclouze,106,1120,1,864,900,1,316,126,76,36,41,73,23,29,122,15,10,12,1,4,42,0x2003885,100,768,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27177,1
 3788,RR_CRAMP,Rr Cramp,Brown Rat,101,988,1,681,720,1,185,74,68,42,38,43,17,15,97,30,10,12,0,2,45,0x3885,100,768,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27176,1
 3788,RR_CRAMP,Rr Cramp,Brown Rat,101,988,1,681,720,1,185,74,68,42,38,43,17,15,97,30,10,12,0,2,45,0x3885,100,768,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27176,1
 //3789,ESCAPED_LETTER
 //3789,ESCAPED_LETTER
-//3790,SWEETS_DROPS
+3790,SWEETS_DROPS,Sweets Drops,Sweets Drops,2,45,1,27,20,1,12,13,16,0,8,1,1,0,6,2,10,12,1,3,23,0x83,400,1372,672,480,0,0,0,0,0,0,0,909,7500,1602,80,938,500,512,1100,713,1700,512,800,620,20,0,0,0,0,0,0
 //3791,JP_E_MONSTER_73
 //3791,JP_E_MONSTER_73
 //3792,ILL_GAZETI
 //3792,ILL_GAZETI
 //3793,ILL_SNOWIER
 //3793,ILL_SNOWIER

+ 0 - 110
db/re/pet_db.txt

@@ -1,110 +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 Hunger is decreased every [HungryDelay] seconds.
-// 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.
-//Please see "The Pet AI commands" in 'doc/script_commands.txt'.
-
-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; }
-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; }
-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; }
-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; }
-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; }
-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; }
-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; }
-1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,60,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack2 "NPC_WINDATTACK",888,2,0,10; },{ bonus bFlee,-5; bonus bFlee2,2; }
-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; }
-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,5;},{ bonus bInt,1; bonus bMaxSP,50; }
-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; }
-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; }
-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,10; },{ bonus bStr,1; bonus bInt,1; }
-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; }
-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; }
-1023,ORK_WARRIOR,Orc Warrior,635,9017,10009,537,80,60,20,100,250,20,500,150,1,0,600,200,300,{ petskillattack2 "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,{ petskillattack2 "NPC_DARKNESSATTACK",444,1,0,10; },{ bonus bInt,1; bonus bDef,1; }
-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,10; },{ bonus bMatkRate,1; bonus2 bAddClass,Class_All,-1; }
-1170,SOHEE,Sohee,638,9020,10016,537,80,60,10,100,250,20,500,150,0,0,100,1000,200,{ petskillsupport "AL_HEAL",5,60,33,100; },{ bonus bStr,1; bonus bDex,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; bonus2 bAddClass,Class_All,1; }
-1155,PETIT,Petite,640,9022,10011,537,80,60,20,100,250,20,500,150,0,0,800,400,100,{ petskillattack2 "WZ_HEAVENDRIVE",500,1,0,10; },{ bonus bDef,-2; bonus bMdef,-2; bonus bAspdRate,1; }
-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; bonus2 bAddClass,Class_All,1; bonus bMaxHPrate,-3; bonus bMaxSPrate,-3; }
-1101,BAPHOMET_,Baphomet Jr.,642,9024,10001,518,80,60,10,100,250,20,200,150,0,0,1000,100,200,{ petskillattack2 "NPC_DARKNESSATTACK",1776,4,0,5; },{ bonus bDef,1; bonus bMdef,1; bonus2 bResEff,Eff_Stun,-100; }
-1188,BON_GUN,Bon Gun,659,9025,10020,537,80,60,30,100,250,20,500,150,1,0,600,200,400,{ petskillattack2 "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,3; },{ bonus2 bAddRace,RC_Demihuman,2; bonus2 bAddRace,RC_Player,2; bonus2 bMagicAddRace,RC_DemiHuman,2; bonus2 bMagicAddRace, RC_Player,2; }
-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_DemiHuman,1; bonus2 bSubRace,RC_Player,1; }
-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; }
-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,5,5; },{ bonus bMaxHP,30; bonus2 bSubEle,Ele_Water,1; }
-
-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,5,5; },{ bonus bDef,1; bonus2 bSubRace,RC_DemiHuman,1; bonus2 bSubRace,RC_Player,1; }
-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,5,5; },{}
-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,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,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,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,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,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,5,5; },{ bonus bAgi,3; bonus bDex,1; }
-
-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,5,5; },{}
-
-// New pets JapanRO Mobile
-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_DemiHuman,3; bonus2 bAddRace,RC_Player,3; }
-1370,SUCCUBUS,Succubus,12373,9055,10037,6113,80,60,10,100,250,20,200,150,0,0,300,300,800,{ bonus2 bHPDrainRate,10,5; },{ bonus2 bHPDrainRate,30,5; bonus bMaxHPrate,1; }
-1374,INCUBUS,Incubus,12370,9052,10034,6110,80,60,10,100,250,20,50,150,0,0,300,300,800,{ bonus bMaxSPRate,3; bonus2 bSPDrainRate,10,1; },{ bonus bMaxSPRate,5; bonus2 bSPDrainRate,30,1; }
-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,10; }
-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; }
-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; }
-
-// Brasilis Quest - Suspicious Beach [UNHATCHABLE]
-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
-
-// New pets (FIX ME: pet bonuses for 2210 and 2313 do not require loyalty)
-2200,J_TAINI,Tiny,0,9057,0,512,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{}
-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; }
-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; }
-1242,MARIN,Marin,12789,9061,10039,6534,80,60,50,100,250,20,2000,150,1,0,300,300,800,{},{}
-2398,LITTLE_PORING,Novice Poring,12846,9062,0,531,80,60,1000,0,250,0,5000,150,0,0,300,300,800,{},{ bonus bHPrecovRate,50; }
-
-// New pets from kRO 2014-10-08 (Needs more info)
-//1090,MASTERING,Mastering,<LureID>,9069,<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>,{ set .@i,getpetinfo(3); /*Awkward=LUK + 2, CRI + 1; Neutral=LUK + 3, CRI + 1; Cordial=LUK + 3, CRI + 2; Best Friend=LUK + 3, CRI + 3;*/ }
-//1166,SAVAGE,Savage,<LureID>,9070,<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>,{ set .@i,getpetinfo(3); /*Awkward=VIT + 1, MHP + 50; Neutral=VIT + 2, MHP + 50; Cordial=VIT + 2, MHP + 100; Best Friend=VIT + 2, MHP + 200;*/ }
-//1369,GRAND_PECO,Grand Peco,<LureID>,9071,<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>,{ set .@i,getpetinfo(3); /*Awkward=MHP + 150; Neutral=MHP + 200; Cordial=MHP + 300; Best Friend=MHP + 400;*/ }
-//1213,HIGH_ORC,High Orc,<LureID>,9087,<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>,{ set .@i,getpetinfo(3); /*Awkward=ATK + 10; Neutral=ATK + 15; Cordial=ATK + 20; Best Friend=ATK + 25;*/ }

+ 1733 - 0
db/re/pet_db.yml

@@ -0,0 +1,1733 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2019 rAthena Development Team
+#   https://rathena.org - https://github.com/rathena
+#
+# This program 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/>.
+#
+###########################################################################
+# Renewal Pet Database
+###########################################################################
+#
+# Pet Settings
+#
+###########################################################################
+# - Mob                      Monster that can be used as pet
+#   TameItem                 Pet Tame Item.
+#   EggItem                  Pet Egg Item.
+#   EquipItem                Pet Accessory Item. (Default: 0)
+#   FoodItem                 Pet Food Item. (Default: 0)
+#   Fullness                 The amount of hunger is decreased every [HungryDelay] seconds.
+#   HungryDelay              The amount of time in seconds it takes for hunger to decrease after feeding. (Default: 60)
+#   HungerIncrease           The amount of hunger that is increased every time the pet is fed (Default: 20)
+#   IntimacyStart            Amount of Intimacy the pet starts with. (Default: 250)
+#   IntimacyFed              Amount of Intimacy that is increased when fed. (Default: 50)
+#   IntimacyOverfed          Amount of Intimacy that is increased when over-fed. (Default: -100)
+#   IntimacyHungry           Amount of Intimacy that is increased when the pet is hungry. (Default: -5)
+#   IntimacyOwnerDie         Amount of Intimacy that is increased when the pet owner dies. (Default: -20)
+#   CaptureRate              Capture success rate. (10000 = 100%)
+#   SpecialPerformance       If a pet has a Special Performance. (Default: true)
+#   AttackRate               Rate of which the pet will attack [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   RetaliateRate            Rate of which the pet will retaliate when master is being attacked [requires at least pet_support_min_friendly intimacy]. (10000 = 100%)
+#   ChangeTargetRate         Rate of which the pet will change its attack target. (10000 = 100%)
+#   AllowAutoFeed            Allows turning automatic pet feeding on. (Default: false)
+#   Script                   Bonus script to execute when the pet is alive. (Default: null)
+#   SupportScript            Bonus script to execute when pet_status_support is enabled. (Default: null)
+#   Evolution:               Pet evolution settings. (Optional) (Default: null)
+#     - Target               Mob this pet can evolve to.
+#       ItemRequirements:      Item requirements for evolving this pet.
+#         - Item               Self-explanatory
+#           Amount
+###########################################################################
+
+Header:
+  Type: PET_DB
+  Version: 1
+
+Body:
+  - Mob: PORING
+    TameItem: Unripe_Apple
+    EggItem: Poring_Egg
+    EquipItem: Backpack
+    FoodItem: Apple_Juice
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bLuk,2;
+        bonus bCritical,1;
+      }
+    Evolution:
+      - Target: MASTERING
+        ItemRequirements:
+          - Item: Leaf_Of_Yggdrasil
+            Amount: 10
+          - Item: Unripe_Apple
+            Amount: 3
+
+  - Mob: DROPS
+    TameItem: Orange_Juice
+    EggItem: Drops_Egg
+    EquipItem: Backpack
+    FoodItem: Yellow_Herb
+    Fullness: 4
+    IntimacyFed: 40
+    CaptureRate: 1500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,3;
+        bonus bAtk,3;
+      }
+    Evolution:
+      - Target: DR_EGGRING
+        ItemRequirements:
+          - Item: Piece_Of_Egg_Shell
+            Amount: 20
+          - Item: Old_Frying_Pan
+            Amount: 10
+          - Item: Apple_Juice
+            Amount: 3
+          - Item: Eggring_Card
+            Amount: 1
+      - Target: SWEETS_DROPS
+        ItemRequirements:
+          - Item: Sweets_Festival_Coin
+            Amount: 500
+          - Item: Candy
+            Amount: 50
+          - Item: Candy_Striper
+            Amount: 50
+          - Item: Drops_Card
+            Amount: 1
+  - Mob: POPORING
+    TameItem: Bitter_Herb
+    EggItem: Poporing_Egg
+    EquipItem: Backpack
+    FoodItem: Green_Herb
+    Fullness: 5
+    IntimacyFed: 30
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bLuk,2;
+        bonus2 bSubEle,Ele_Poison,10;
+      }
+  - Mob: LUNATIC
+    TameItem: Rainbow_Carrot
+    EggItem: Lunatic_Egg
+    EquipItem: Silk_Ribbon
+    FoodItem: Carrot_Juice
+    Fullness: 4
+    IntimacyFed: 40
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,2;
+        bonus bAtk,2;
+      }
+    Evolution:
+      - Target: DR_LUNATIC
+        ItemRequirements: 
+          - Item: Great_Leaf
+            Amount: 100
+          - Item: Clover
+            Amount: 250
+          - Item: Four_Leaf_Clover
+            Amount: 30
+          - Item: Leaf_Lunatic_Card
+            Amount: 1
+
+  - Mob: PICKY
+    TameItem: Earthworm_The_Dude
+    EggItem: Picky_Egg
+    EquipItem: Tiny_Egg_Shell
+    FoodItem: Red_Herb
+    Fullness: 4   
+    IntimacyFed: 40
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bStr,1;
+        bonus bAtk,5;
+      }
+  - Mob: CHONCHON
+    TameItem: Rotten_Fish
+    EggItem: Chonchon_Egg
+    EquipItem: Monster_Oxygen_Mask
+    FoodItem: Pet_Food
+    Fullness: 6
+    IntimacyFed: 30
+    CaptureRate: 1500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,1;
+        bonus bFlee,2;
+      }
+  - Mob: STEEL_CHONCHON
+    TameItem: Lusty_Iron
+    EggItem: Steel_Chonchon_Egg
+    EquipItem: Monster_Oxygen_Mask
+    FoodItem: Iron_Ore
+    Fullness: 5
+    IntimacyFed: 20
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bFlee,6;
+        bonus bAgi,-1;
+      }
+  - Mob: HUNTER_FLY
+    TameItem: Monster_Juice
+    EggItem: Hunter_Fly_Egg
+    EquipItem: Monster_Oxygen_Mask
+    FoodItem: Red_Gemstone
+    Fullness: 5
+    IntimacyFed: 10
+    CaptureRate: 500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bFlee,-5;
+        bonus bFlee2,2;
+      }
+  - Mob: SAVAGE_BABE
+    TameItem: Sweet_Milk
+    EggItem: Savage_Bebe_Egg
+    EquipItem: Green_Lace
+    FoodItem: Pet_Food
+    Fullness: 7
+    IntimacyFed: 40
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,1;
+        bonus bMaxHP,50;
+      }
+    Evolution:
+      - Target: SAVAGE
+        ItemRequirements:
+          - Item: Pet_Food
+            Amount: 10
+          - Item: Sweet_Milk
+            Amount: 3
+          - Item: Meat
+            Amount: 100
+          - Item: Feather
+            Amount: 50
+  - Mob: DESERT_WOLF_B
+    TameItem: Well_Dried_Bone
+    EggItem: Baby_Desert_Wolf_Egg
+    EquipItem: Transparent_Headgear
+    FoodItem: Pet_Food
+    Fullness: 6
+    IntimacyFed: 40
+    CaptureRate: 1000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bInt,1;
+        bonus bMaxSP,50;
+      }
+  - Mob: ROCKER
+    TameItem: Singing_Flower
+    EggItem: Rocker_Egg
+    EquipItem: Rocker_Glasses
+    FoodItem: Pet_Food
+    Fullness: 1
+    IntimacyFed: 30
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHPrecovRate,5;
+        bonus bMaxHP,25;
+      }
+    Evolution:
+      - Target: METALLER
+        ItemRequirements:
+          - Item: Singing_Plant
+            Amount: 3
+          - Item: Grasshopper's_Leg
+            Amount: 777
+          - Item: Yellow_Herb
+            Amount: 200
+          - Item: Metaller_Card
+            Amount: 1
+  - Mob: SPORE
+    TameItem: Dew_Laden_Moss
+    EggItem: Spore_Egg
+    EquipItem: Bark_Shorts
+    FoodItem: Pet_Food
+    Fullness: 3
+    IntimacyFed: 30
+    CaptureRate: 1500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,5;
+        bonus bAtk,-2;
+      }
+  - Mob: POISON_SPORE
+    TameItem: Deadly_Noxious_Herb
+    EggItem: Poison_Spore_Egg
+    EquipItem: Bark_Shorts
+    FoodItem: Pet_Food
+    Fullness: 3
+    IntimacyFed: 20
+    CaptureRate: 1000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bStr,1;
+        bonus bInt,1;
+      }
+  - Mob: PECOPECO
+    TameItem: Fatty_Chubby_Earthworm
+    EggItem: PecoPeco_Egg
+    EquipItem: Battered_Pot
+    FoodItem: Pet_Food
+    Fullness: 4
+    IntimacyFed: 30
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,150;
+        bonus bMaxSP,-10;
+      }
+    Evolution:
+      - Target: GRAND_PECO
+        ItemRequirements:
+          - Item: Pet_Food
+            Amount: 10
+          - Item: Fatty_Chubby_Earthworm
+            Amount: 3
+          - Item: Peco_Wing_Feather
+            Amount: 300
+          - Item: Pecopeco_Card
+            Amount: 1
+          - Item: Fruit_Of_Mastela
+            Amount: 10
+  - Mob: SMOKIE
+    TameItem: Baked_Yam
+    EggItem: Smokie_Egg
+    EquipItem: Red_Muffler
+    FoodItem: Pet_Food
+    Fullness: 4
+    IntimacyFed: 30
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,1;
+        bonus bFlee2,1;
+      }
+  - Mob: YOYO
+    TameItem: Tropical_Banana
+    EggItem: Yoyo_Egg
+    EquipItem: Monkey_Circlet
+    FoodItem: Banana_Juice
+    Fullness: 5
+    IntimacyFed: 20
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,3;
+        bonus bLuk,-1;
+      }
+    Evolution:
+      - Target: CHOCO
+        ItemRequirements:
+          - Item: Tropical_Banana
+            Amount: 3
+          - Item: Monkey_Doll
+            Amount: 2
+          - Item: Cacao
+            Amount: 300
+          - Item: Yoyo_Card
+            Amount: 1
+  - Mob: ORK_WARRIOR
+    TameItem: Horror_Of_Tribe
+    EggItem: Orc_Warrior_Egg
+    EquipItem: Wild_Flower
+    FoodItem: Pet_Food
+    Fullness: 5
+    IntimacyFed: 20
+    CaptureRate: 500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAtk,10;
+        bonus bDef,-3;
+      }
+    Evolution:
+      - Target: HIGH_ORC
+        ItemRequirements:
+          - Item: Horror_Of_Tribe
+            Amount: 3
+          - Item: Orcish_Sword
+            Amount: 1
+          - Item: Orcish_Voucher
+            Amount: 500
+          - Item: Cigar
+            Amount: 1
+          - Item: Orc_Warrior_Card
+            Amount: 1
+  - Mob: MUNAK
+    TameItem: No_Recipient
+    EggItem: Munak_Egg
+    EquipItem: Punisher
+    FoodItem: Pet_Food
+    Fullness: 3
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bInt,1;
+        bonus bDef,1;
+      }
+  - Mob: DOKEBI
+    TameItem: Old_Broom
+    EggItem: Dokkaebi_Egg
+    EquipItem: Wig
+    FoodItem: Pet_Food
+    Fullness: 4
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,1;
+        bonus bAtkRate,-1;
+      }
+    Evolution:
+      - Target: AM_MUT
+        ItemRequirements:
+          - Item: Old_Broom
+            Amount: 3
+          - Item: Violet_Dyestuffs
+            Amount: 3
+          - Item: Dokkaebi_Horn
+            Amount: 300
+          - Item: Gold
+            Amount: 3
+  - Mob: SOHEE
+    TameItem: Silver_Knife_Of_Chaste
+    EggItem: Sohee_Egg
+    EquipItem: Golden_Bell
+    FoodItem: Pet_Food
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bStr,1;
+        bonus bDex,1;
+      }
+  - Mob: ISIS
+    TameItem: Armlet_Of_Obedience
+    EggItem: Isis_Egg
+    EquipItem: Queen's_Hair_Ornament
+    FoodItem: Pet_Food
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,-1;
+        bonus bAtkRate,1;
+      }
+    Evolution:
+      - Target: LITTLE_ISIS
+        ItemRequirements:
+          - Item: Armlet_Of_Obedience
+            Amount: 3
+          - Item: Crystal_Jewel__
+            Amount: 6
+          - Item: Queen's_Hair_Ornament
+            Amount: 1
+          - Item: Shining_Scales
+            Amount: 300
+  - Mob: PETIT
+    TameItem: Shining_Stone
+    EggItem: Green_Petite_Egg
+    EquipItem: Stellar_Hairpin
+    FoodItem: Pet_Food
+    Fullness: 4
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDef,-2;
+        bonus bMdef,-2;
+        bonus bAspdRate,1;
+      }
+    Evolution:
+      - Target: DELETER_2
+        ItemRequirements:
+          - Item: Shining_Stone
+            Amount: 3
+          - Item: Petti_Tail
+            Amount: 100
+          - Item: Aloebera
+            Amount: 150
+          - Item: Deleter_Card
+            Amount: 1
+  - Mob: DEVIRUCHI
+    TameItem: Contracts_In_Shadow
+    EggItem: Deviruchi_Egg
+    EquipItem: Pacifier
+    FoodItem: Shoot
+    Fullness: 2
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,1;
+        bonus bAtkRate,1;
+        bonus bMaxHPrate,-3;
+        bonus bMaxSPrate,-3;
+      }
+    Evolution:
+      - Target: DIABOLIC2
+        ItemRequirements:
+          - Item: Contracts_In_Shadow
+            Amount: 3
+          - Item: Petite_DiablOfs_Wing
+            Amount: 250
+          - Item: Sacred_Marks
+            Amount: 30
+          - Item: Deviruchi_Card
+            Amount: 1
+  - Mob: BAPHOMET_
+    TameItem: Book_Of_Devil
+    EggItem: Bapho_Jr._Egg
+    EquipItem: Skull_Helm
+    FoodItem: Honey
+    Fullness: 2
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDef,1;
+        bonus bMdef,1;
+        bonus2 bResEff,Eff_Stun,-100;
+      }
+  - Mob: BON_GUN
+    TameItem: Heart_Of_Her
+    EggItem: Bongun_Egg
+    EquipItem: Sword_Of_Grave_Keeper
+    FoodItem: Pet_Food
+    Fullness: 4
+    IntimacyFed: 30
+    CaptureRate: 500
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,1;
+        bonus2 bResEff,Eff_Stun,100;
+      }
+    Evolution:
+      - Target: HYEGUN
+        ItemRequirements:
+          - Item: Hyegun_Hat
+            Amount: 1
+          - Item: Munak_Doll
+            Amount: 100
+          - Item: Old_Portrait
+            Amount: 50
+          - Item: Hyegun_Card
+            Amount: 1
+  - Mob: ZHERLTHSH
+    TameItem: Prohibition_Red_Candle
+    EggItem: Zherlthsh_Egg
+    FoodItem: Immortal_Heart
+    Fullness: 7
+    IntimacyFed: 10
+    CaptureRate: 300
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bAddRace,RC_Demihuman,2;
+        bonus2 bMagicAddRace,RC_DemiHuman,2;
+        bonus2 bAddRace,RC_Player,2;
+        bonus2 bMagicAddRace,RC_Player,2;
+      }
+  - Mob: ALICE
+    TameItem: Sway_Apron
+    EggItem: Alice_Egg
+    FoodItem: White_Potion
+    Fullness: 2
+    IntimacyFed: 20
+    CaptureRate: 800
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMdef,1;
+        bonus2 bSubRace,RC_DemiHuman,1;
+        bonus2 bSubRace,RC_Player,1;
+      }
+  - Mob: EVENT_RICECAKE
+    EggItem: Rice_Cake_Egg
+    FoodItem: Green_Herb
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubEle,Ele_Neutral,1;
+        bonus bMaxHPrate,-1;
+      }
+  - Mob: GOBLINE_XMAS
+    TameItem: Sweet_Candy_Striper
+    EggItem: Santa_Goblin_Egg
+    FoodItem: Scell
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,30;
+        bonus2 bSubEle,Ele_Water,1;
+      }
+  - Mob: CHUNG_E
+    TameItem: Tantanmen
+    EggItem: Chung_E_Egg
+    FoodItem: Bun_
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDef,1;
+        bonus2 bSubRace,RC_DemiHuman,1;
+        bonus2 bSubRace,RC_Player,1;
+      }
+  - Mob: ECLIPSE_P
+    EggItem: Spring_Rabbit_Egg
+    FoodItem: Bok_Choy
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+    SpecialPerformance: false
+  - Mob: GOBLIN_1
+    TameItem: Knife_Goblin_Ring
+    EggItem: Knife_Goblin_Egg
+    FoodItem: Green_Apple
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: GOBLIN_2
+    TameItem: Flail_Goblin_Ring
+    EggItem: Flail_Goblin_Egg
+    FoodItem: Green_Apple
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: GOBLIN_4
+    TameItem: Hammer_Goblin_Ring
+    EggItem: Hammer_Goblin_Egg
+    FoodItem: Green_Apple
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: DELETER_
+    TameItem: Holy_Marble
+    EggItem: Red_Deleter_Egg
+    FoodItem: Whole_Barbecue
+    Fullness: 4
+    IntimacyFed: 20
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: DIABOLIC
+    TameItem: Red_Burning_Stone
+    EggItem: Diabolic_Egg
+    FoodItem: Meat_Veg_Skewer
+    Fullness: 2
+    IntimacyFed: 10
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: WANDER_MAN
+    TameItem: Skull_Of_Vagabond
+    EggItem: Wanderer_Egg
+    FoodItem: Spirit_Liquor
+    Fullness: 2
+    IntimacyFed: 20
+    CaptureRate: 800
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,3;
+        bonus bDex,1;
+      }
+  - Mob: P_CHUNG_E
+    EggItem: New_Year_Doll_Egg
+    FoodItem: Mojji
+    Fullness: 3
+    IntimacyFed: 30
+    CaptureRate: 800
+    SpecialPerformance: false
+  - Mob: GOLEM
+    TameItem: Magical_Lithography
+    EggItem: Golem_Egg
+    EquipItem: Windup_Spring
+    FoodItem: Mystic_Stone
+    Fullness: 7
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,100;
+        bonus bFlee,-5;
+      }
+  - Mob: MARIONETTE
+    TameItem: Delicious_Shaved_Ice
+    EggItem: Marionette_Egg
+    EquipItem: Star_Hairband
+    FoodItem: Small_Snow_Flower
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bSPrecovRate,3;
+      }
+  - Mob: MEDUSA
+    TameItem: Splendid_Mirror
+    EggItem: Medusa_Egg
+    EquipItem: Queen's_Coronet
+    FoodItem: Apple_Pudding
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,1;
+        bonus2 bResEff,Eff_Stone,500;
+      }
+  - Mob: WHISPER
+    TameItem: Fit_Pipe
+    EggItem: Whisper_Egg
+    EquipItem: Spirit_Chain_
+    FoodItem: Damp_Darkness
+    Fullness: 7
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bFlee,7;
+        bonus bDef,-3;
+      }
+  - Mob: GOBLIN_LEADER
+    TameItem: Staff_Of_Leader
+    EggItem: Goblin_Leader_Egg
+    EquipItem: Nice_Badge
+    FoodItem: Big_Cell
+    Fullness: 7
+    IntimacyFed: 10
+    CaptureRate: 50
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bAddRace,RC_DemiHuman,3;
+        bonus2 bAddRace,RC_Player,3;
+      }
+  - Mob: SUCCUBUS
+    TameItem: Boy's_Naivety
+    EggItem: Succubus_Egg
+    EquipItem: Black_Butterfly_Mask
+    FoodItem: Vital_Flower_
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bHPDrainRate,30,5;
+        bonus bMaxHPrate,1;
+      }
+  - Mob: INCUBUS
+    TameItem: Gril's_Naivety
+    EggItem: Incubus_Egg
+    EquipItem: Ball_Mask
+    FoodItem: Vital_Flower
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 50
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSPRate,5;
+        bonus2 bSPDrainRate,30,1;
+      }
+  - Mob: NIGHTMARE_TERROR
+    TameItem: Hell_Contract
+    EggItem: Nightmare_Terror_Egg
+    EquipItem: Hell_Horn
+    FoodItem: Fresh_Plant
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bResEff,Eff_Sleep,10000;
+      }
+  - Mob: SHINOBI
+    TameItem: Kuloren
+    EggItem: Shinobi_Egg
+    EquipItem: Wine_On_Sleeve
+    FoodItem: Grilled_Rice_Cake
+    Fullness: 7
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAgi,2;
+      }
+  - Mob: MIYABI_NINGYO
+    TameItem: Gril_Doll
+    EggItem: Miyabi_Ningyo_Egg
+    EquipItem: Summer_Fan
+    FoodItem: Well_Ripened_Berry
+    Fullness: 3
+    IntimacyFed: 15
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bInt,1;
+        bonus bCastrate,-3;
+      }
+  - Mob: WICKED_NYMPH
+    TameItem: Charming_Lotus
+    EggItem: Wicked_Nymph_Egg
+    EquipItem: Jade_Trinket
+    FoodItem: Morning_Dew
+    Fullness: 3
+    IntimacyFed: 15
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSP,30;
+        bonus bSPrecovRate,5;
+      }
+  - Mob: STONE_SHOOTER
+    TameItem: Oilpalm_Coconut
+    EggItem: Stone_Shooter_Egg
+    EquipItem: Apro_Hair
+    FoodItem: Plant_Neutrient
+    Fullness: 7
+    IntimacyFed: 20
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubEle,Ele_Fire,3;
+      }
+  - Mob: DULLAHAN
+    TameItem: Luxury_Whisky_Bottle
+    EggItem: Dullahan_Egg
+    EquipItem: Death_Coil
+    FoodItem: Sunset_On_The_Rock
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritAtkRate,5;
+      }
+  - Mob: LOLI_RURI
+    TameItem: Very_Red_Juice
+    EggItem: Loli_Ruri_Egg
+    EquipItem: Fashionable_Glasses
+    FoodItem: Pumpkin_Pie_
+    Fullness: 3
+    IntimacyFed: 15
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHPRate,3;
+        bonus3 bAutoSpellWhenHit,"AL_HEAL",1,10;
+      }
+  - Mob: CIVIL_SERVANT
+    TameItem: Fan_Of_Wind
+    EggItem: Civil_Servant_Egg
+    EquipItem: Golden_Earing
+    FoodItem: Flavored_Alcohol
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 500
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSP,10;
+      }
+  - Mob: LEAF_CAT
+    TameItem: Very_Soft_Plant
+    EggItem: Leaf_Cat_Egg
+    EquipItem: Green_Lucky_Bag
+    FoodItem: Fish_With_Blue_Back
+    Fullness: 7
+    IntimacyFed: 20
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubRace,RC_Brute,3;
+      }
+  - Mob: BACSOJIN_
+    TameItem: Shiny_Wing_Gown
+    EggItem: Bacsojin_Egg
+    EquipItem: Round_Hair_Ornament
+    FoodItem: Traditional_Cookie
+    Fullness: 7
+    IntimacyFed: 10
+    CaptureRate: 2000
+    SpecialPerformance: false
+  - Mob: IMP
+    TameItem: Flaming_Ice
+    EggItem: Imp_Egg
+    EquipItem: Horn_Protector
+    FoodItem: Flame_Gemstone
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 200
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bSubEle,Ele_Fire,2;
+        bonus2 bAddEle,Ele_Fire,2;
+      }
+  - Mob: E_CRAMP
+    TameItem: Leaf_Cat_Ball
+    EggItem: Mystic_Leaf_Cat_Ball
+    Fullness: 0
+    HungryDelay: 0
+    IntimacyStart: 0
+    IntimacyFed: 0
+    IntimacyOverfed: 0
+    IntimacyOwnerDie: 0
+    CaptureRate: 50
+    SpecialPerformance: false
+  - Mob: E_HYDRA
+    TameItem: Leaf_Cat_Ball
+    EggItem: Mystic_Leaf_Cat_Ball
+    Fullness: 0
+    HungryDelay: 0
+    IntimacyStart: 0
+    IntimacyFed: 0
+    IntimacyOverfed: 0
+    IntimacyOwnerDie: 0
+    CaptureRate: 50
+    SpecialPerformance: false
+  - Mob: J_TAINI
+    EggItem: Egg_Of_Tiny
+    FoodItem: Apple
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 0
+  - Mob: XMAS_LUNATIC
+    EggItem: Snow_Rabbit_Egg
+    FoodItem: Candy
+    Fullness: 3
+    IntimacyFed: 10
+    CaptureRate: 0
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bExpAddRace,RC_All,5;
+      }
+  - Mob: TIKBALANG
+    TameItem: Tikbalang_Belt
+    EggItem: Tikbalang_Pet
+    FoodItem: Monster's_Feed
+    Fullness: 8
+    IntimacyFed: 10
+    CaptureRate: 1000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus2 bAddDamageClass,2317,10;
+        bonus2 bAddDamageClass,2318,10;
+        bonus2 bAddDamageClass,2319,10;
+        bonus2 bAddDamageClass,2320,10;
+        bonus2 bAddDamageClass,2321,10;
+        bonus2 bAddDamageClass,2322,10;
+        bonus2 bAddDamageClass,2327,10;
+        bonus2 bAddDamageClass,2332,10;
+        bonus2 bAddDamageClass,2333,10;
+      }
+  - Mob: MARIN
+    TameItem: Juicy_Fruit
+    EggItem: Marin_Egg
+    EquipItem: Tw_Backpack
+    FoodItem: Fruit_Sundae
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+  - Mob: LITTLE_PORING
+    TameItem: Unripe_Apple2
+    EggItem: Novice_Poring_Egg
+    FoodItem: Apple_Juice
+    Fullness: 3
+    IntimacyFed: 1000
+    IntimacyOverfed: 0
+    IntimacyOwnerDie: 0
+    CaptureRate: 5000
+    SpecialPerformance: false
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHPrecovRate,50;
+      }
+  - Mob: NINE_TAIL
+    TameItem: Sap_Liquid
+    EggItem: Nine_Tail_Egg
+    FoodItem: Suspicious_Bottle
+    Fullness: 4
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,3;
+        bonus bHit,2;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bCritical,2;
+        bonus bHit,2;
+      }
+    Evolution:
+      - Target: CAT_O_NINE_TAIL
+        ItemRequirements:
+          - Item: Sap_Liquid
+            Amount: 3
+          - Item: Fox_Tail
+            Amount: 999
+          - Item: Punisher
+            Amount: 1
+          - Item: Nine_Tail_Card
+            Amount: 1
+  - Mob: GREMLIN
+    TameItem: Unprocessed_Parts
+    EggItem: Gremlin_Egg
+    FoodItem: Cheap_Lubricant
+    Fullness: 4
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus Dex,2;
+        bonus bHit,1;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bDex,1;
+        bonus bHit,1;
+      }
+    Evolution:
+      - Target: HODREMLIN
+        ItemRequirements:
+          - Item: Unprocessed_Parts
+            Amount: 3
+          - Item: Damp_Darkness
+            Amount: 50
+          - Item: Will_Of_Darkness
+            Amount: 200
+          - Item: Hodremlin_Card
+            Amount: 1
+  - Mob: MUMMY
+    TameItem: Elixir_Bandages
+    EggItem: Mummy_Egg
+    FoodItem: Mementos
+    Fullness: 7
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,5;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bHit,4;
+      }
+    Evolution:
+      - Target: ANCIENT_MUMMY
+        ItemRequirements:
+          - Item: Elixir_Bandages
+            Amount: 3
+          - Item: Rune_Of_Darkness
+            Amount: 200
+          - Item: Gold
+            Amount: 30
+          - Item: Ancient_Mummy_Card
+            Amount: 1
+  - Mob: TEDDY_BEAR
+    TameItem: Small_Needle_Kit
+    EggItem: Teddy_Bear_Egg
+    FoodItem: Cotton_Tufts
+    Fullness: 3
+    IntimacyFed: 50
+    CaptureRate: 2000
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMaxSP,150;
+      }
+    Evolution:
+      - Target: XM_TEDDY_BEAR
+        ItemRequirements:
+          - Item: Small_Needle_Kit
+            Amount: 3
+          - Item: Cursed_Seal
+            Amount: 300
+          - Item: Cardinal_Jewel_
+            Amount: 50
+          - Item: Teddy_Bear_Card
+            Amount: 1
+
+  # Pet Evolution, most are dummy values
+  - Mob: MASTERING
+    EggItem: Mastering_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bLuk,3;
+        bonus bCritical,3;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bLuk,3;
+        bonus bCritical,2;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bLuk,3;
+        bonus bCritical,1;
+      }else{
+        bonus bLuk,2;
+        bonus bCritical,1;
+      }
+    Evolution:
+      - Target: ANGELING
+        ItemRequirements:
+          - Item: Yellow_Potion
+            Amount: 20
+          - Item: Spirit_Chain
+            Amount: 1
+          - Item: White_Herb
+            Amount: 50
+          - Item: Jellopy
+            Amount: 200
+  - Mob: METALLER
+    EggItem: Metaller_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHPrecovRate,20;
+        bonus bMaxHP,70;
+        bonus2 bAddRace,RC_Plant,6;
+        bonus2 bMagicAddRace,RC_Plant,6;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bHPrecovRate,15;
+        bonus bMaxHP,55;
+        bonus2 bAddRace,RC_Plant,3;
+        bonus2 bMagicAddRace,RC_Plant,3;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bHPrecovRate,10;
+        bonus bMaxHP,38;
+      }else{
+        bonus bHPrecovRate,5;
+        bonus bMaxHP,25;
+      }
+  - Mob: ANGELING
+    EggItem: Angeling_Egg
+    FoodItem: Pet_Food
+    Fullness: 1
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHPrate,2;
+        bonus bHealPower,8;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMaxHPrate,2;
+        bonus bHealPower,6;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bMaxHPrate,1;
+        bonus bHealPower,4;
+      }else{
+        bonus bMaxHPrate,1;
+        bonus bHealPower,2;
+      }
+  - Mob: MOONLIGHT
+    EggItem: Moonlight_Egg
+    FoodItem: Luxurious_Pet_Food
+    Fullness: 1
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,6;
+        bonus bHit,6;
+        autobonus "{ bonus bHPRegenRate,500,1000; bonus bSPRegenRate,20,1000; }",30,5000,BF_WEAPON|BF_SHORT;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bCritical,5;
+        bonus bHit,5;
+        autobonus "{ bonus bHPRegenRate,400,1000; bonus bSPRegenRate,10,1000; }",30,5000,BF_WEAPON|BF_SHORT;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bCritical,4;
+        bonus bHit,4;
+        autobonus "{ bonus bHPRegenRate,300,1000; }",20,5000,BF_WEAPON|BF_SHORT;
+      }else{
+        bonus bCritical,3;
+        bonus bHit,3;
+      }
+  - Mob: SAVAGE
+    EggItem: Savage_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,200;
+        bonus bVit,2;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMaxHP,100;
+        bonus bVit,2;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bMaxHP,50;
+        bonus bVit,2;
+      }else{
+        bonus bMaxHP,50;
+        bonus bVit,1;
+      }
+  - Mob: HIGH_ORC
+    EggItem: High_Orc_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,200;
+        bonus bVit,2;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMaxHP,100;
+        bonus bVit,2;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bMaxHP,50;
+        bonus bVit,2;
+      }else{
+        bonus bMaxHP,50;
+        bonus bVit,1;
+      }
+  - Mob: CHOCO
+    EggItem: Choco_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,9;
+        bonus bLongAtkRate,3;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bCritical,7;
+        bonus bLongAtkRate,2;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bCritical,5;
+        bonus bLongAtkRate,1;
+      }else{
+        bonus bCritical,3;
+      }
+  - Mob: ANCIENT_MUMMY
+    EggItem: Ancient_Mummy_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,6;
+        bonus2 bAddClass,Class_All,6;
+        bonus2 bMagicAddClass,Class_All,6;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bHit,6;
+        bonus2 bAddClass,Class_All,3;
+        bonus2 bMagicAddClass,Class_All,3;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bHit,5;
+      }else{
+        bonus bHit,4;
+      }
+  - Mob: AM_MUT
+    EggItem: Am_Mut_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMatkRate,4;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMatkRate,3;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bMatkRate,2;
+      }else{
+        bonus bMatkRate,1;
+      }
+  - Mob: CAT_O_NINE_TAIL
+    EggItem: Cat_o_Nine_Tail_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,5;
+        bonus bHit,5;
+        autobonus "{ bonus bHPRegenRate,400,1000; }",20,5000,BF_WEAPON|BF_SHORT;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bCritical,4;
+        bonus bHit,4;
+        autobonus "{ bonus bHPRegenRate,300,1000; }",20,5000,BF_WEAPON|BF_SHORT;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bCritical,3;
+        bonus bHit,3;
+      }else{
+        bonus bCritical,2;
+        bonus bHit,2;
+      }
+    Evolution:
+      - Target: MOONLIGHT
+        ItemRequirements:
+          - Item: Powerful_Soul_Essence
+            Amount: 30
+          - Item: Nine_Tail_Card
+            Amount: 10
+          - Item: Sohee_Card
+            Amount: 10
+          - Item: Munak_Card
+            Amount: 10
+  - Mob: GRAND_PECO
+    EggItem: Grand_Peco_Peco_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxHP,400;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMaxHP,300;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bMaxHP,200;
+      }else{
+        bonus bMaxHP,150;
+      }
+  - Mob: HYEGUN
+    EggItem: Hyegun_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bVit,4;
+        bonus2 bResEff,Eff_Stun,400;
+        bonus2 bSPDrainRate,20,1;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bVit,3;
+        bonus2 bResEff,Eff_Stun,300;
+        bonus2 bSPDrainRate,10,1;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bVit,2;
+        bonus2 bResEff,Eff_Stun,200;
+      }else{
+        bonus bVit,1;
+        bonus2 bResEff,Eff_Stun,100;
+      }
+  - Mob: HODREMLIN
+    EggItem: Hodremlin_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bDex,2;
+        bonus bHit,2;
+        bonus bCritAtkRate,9;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bDex,2;
+        bonus bHit,2;
+        bonus bCritAtkRate,7;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bDex,2;
+        bonus bHit,1;
+      }else{
+        bonus bDex,1;
+        bonus bHit,1;
+      }
+  - Mob: XM_TEDDY_BEAR
+    EggItem: Xm_Teddy_Bear_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bMaxSP,150;
+        autobonus "{ bonus bSPRegenRate,40,1000; }",30,5000,BF_MAGIC;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bMaxSP,150;
+        autobonus "{ bonus bSPRegenRate,30,1000; }",30,5000,BF_MAGIC;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bMaxSP,100;
+      }else{
+        bonus bMaxSP,50;
+      }
+  - Mob: DR_EGGRING
+    EggItem: Eggring_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bHit,9;
+        bonus bAtk,9;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bHit,7;
+        bonus bAtk,7;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bHit,5;
+        bonus bAtk,5;
+      }else{
+        bonus bHit,3;
+        bonus bAtk,3;
+      }
+  - Mob: DR_LUNATIC
+    EggItem: Dr_Lunatic_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bCritical,5;
+        bonus bAtk,5;
+        bonus2 bAddRace,RC_Formless,6;
+        bonus2 bMagicAddRace,RC_Formless,6;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bCritical,4;
+        bonus bAtk,4;
+        bonus2 bAddRace,RC_Formless,3;
+        bonus2 bMagicAddRace,RC_Formless,3;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bCritical,3;
+        bonus bAtk,3;
+      }else{
+        bonus bCritical,2;
+        bonus bAtk,2;
+      }
+  - Mob: LITTLE_ISIS
+    EggItem: Little_Isis_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAtkRate,4;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bAtkRate,3;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bAtkRate,2;
+      }else{
+        bonus bAtkRate,1;
+      }
+  - Mob: DIABOLIC2
+    EggItem: Diabolic_2_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bAtkRate,2;
+        bonus bMatkRate,2;
+        bonus bMaxHPrate,1;
+        bonus bMaxSPrate,1;
+        bonus5 bAutoSpell,"MG_FIREBOLT",3,50,BF_WEAPON|BF_SHORT,1;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bAtkRate,1;
+        bonus bMatkRate,1;
+        bonus bMaxHPrate,1;
+        bonus bMaxSPrate,1;
+      }else{
+        bonus bAtkRate,1;
+        bonus bMatkRate,1;
+      }
+  - Mob: DELETER_2
+    EggItem: Fire_Deleter_Egg
+    FoodItem: Pet_Food
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_LOYAL ){
+        bonus bAspdRate,3;
+        bonus bAgi,3;
+      }else if( .@i >= PET_INTIMATE_CORDIAL ){
+        bonus bAspdRate,2;
+        bonus bAgi,2;
+      }else if( .@i >= PET_INTIMATE_NEUTRAL ){
+        bonus bAspdRate,2;
+        bonus bAgi,1;
+      }else{
+        bonus bAspdRate,1;
+      }
+  - Mob: SWEETS_DROPS
+    EggItem: Sweet_Drops_Egg
+    FoodItem: Candy
+    Fullness: 2
+    HungryDelay: 120
+    IntimacyFed: 15
+    CaptureRate: 0
+    SpecialPerformance: false
+    AllowAutoFeed: true
+    Script: >
+      .@i = getpetinfo(PETINFO_INTIMATE);
+      
+      if( .@i >= PET_INTIMATE_CORDIAL ){
+        /* bonus2 bExpAddClass,Class_All,3; */
+        bonus2 bExpAddClass,Class_All,1;
+      }

+ 1 - 1
doc/atcommands.txt

@@ -1361,7 +1361,7 @@ Affected files:
 -- battleconf: battle_athena.conf, battle_conf.txt
 -- battleconf: battle_athena.conf, battle_conf.txt
 -- instancedb: instance_db.txt
 -- instancedb: instance_db.txt
 -- itemdb: item_db.txt, item_group_db.txt, item_trade.txt, item_noequip.txt, item_nouse.txt, item_combo_db.txt, item_avail.txt, item_stack.txt, item_delay.txt, item_buyingstore.txt, item_flag.txt
 -- itemdb: item_db.txt, item_group_db.txt, item_trade.txt, item_noequip.txt, item_nouse.txt, item_combo_db.txt, item_avail.txt, item_stack.txt, item_delay.txt, item_buyingstore.txt, item_flag.txt
--- mobdb: mob_db.txt, mob_item_ratio.txt, mob_chat_db.txt, mob_avail.txt, mob_race2_db.txt, mob_branch.txt, mob_poring.txt, mob_boss.txt, mob_pouch.txt, mob_classchange.txt, pet_db.txt, homunculus_db.txt, homun_skill_tree.txt, exp_homun.txt, mercenary_db.txt, mercenary_skill_db.txt, elemental_db.txt, elemental_skill_db.txt
+-- mobdb: mob_db.txt, mob_item_ratio.txt, mob_chat_db.txt, mob_avail.txt, mob_race2_db.txt, mob_branch.txt, mob_poring.txt, mob_boss.txt, mob_pouch.txt, mob_classchange.txt, pet_db.yml, homunculus_db.txt, homun_skill_tree.txt, exp_homun.txt, mercenary_db.txt, mercenary_skill_db.txt, elemental_db.txt, elemental_skill_db.txt
 -- motd: motd.txt
 -- motd: motd.txt
 -- msgconf: atcommand_athena.conf
 -- msgconf: atcommand_athena.conf
 -- pcdb: statpoint.txt, job_exp.txt, skill_tree.txt, attr_fix.txt, job_db1.txt, job_db2.txt, job_basehpsp_db.txt, job_maxhpsp_db.txt, job_param_db.txt, level_penalty.txt
 -- pcdb: statpoint.txt, job_exp.txt, skill_tree.txt, attr_fix.txt, job_db1.txt, job_db2.txt, job_basehpsp_db.txt, job_maxhpsp_db.txt, job_param_db.txt, level_penalty.txt

+ 31 - 7
doc/script_commands.txt

@@ -9380,7 +9380,7 @@ monster as long as it is in the pet database and the targeted monster requires t
 item used.
 item used.
 See 'doc/mob_db_mode_list.txt' for more information about monster modes.
 See 'doc/mob_db_mode_list.txt' for more information about monster modes.
 
 
-A full list of pet IDs can be found inside 'db/(pre-)re/pet_db.txt'.
+A full list of pet IDs can be found inside 'db/(pre-)re/pet_db.yml'.
 
 
 ---------------------------------------
 ---------------------------------------
 
 
@@ -9388,7 +9388,7 @@ A full list of pet IDs can be found inside 'db/(pre-)re/pet_db.txt'.
 
 
 This command will create a pet egg and put it in the invoking character's
 This command will create a pet egg and put it in the invoking character's
 inventory. The kind of pet is specified by pet ID numbers listed in
 inventory. The kind of pet is specified by pet ID numbers listed in
-'db/(pre-)re/pet_db.txt'. The egg is created exactly as if the character just successfully
+'db/(pre-)re/pet_db.yml'. The egg is created exactly as if the character just successfully
 caught a pet in the normal way.
 caught a pet in the normal way.
 
 
 	// This will make you a poring:
 	// This will make you a poring:
@@ -9406,16 +9406,40 @@ This function will return pet information for the pet the invoking character
 currently has active. Valid types are:
 currently has active. Valid types are:
 
 
  PETINFO_ID - Pet ID
  PETINFO_ID - Pet ID
- PETINFO_CLASS - Pet class number as per 'db/(pre-)re/pet_db.txt' - will tell you what kind of a pet it
-     is.
+ PETINFO_CLASS - Pet class number as per 'db/(pre-)re/pet_db.yml' - will tell you what kind of a pet it is.
  PETINFO_NAME - Pet name. Will return "null" if there's no pet.
  PETINFO_NAME - Pet name. Will return "null" if there's no pet.
  PETINFO_INTIMATE - Pet friendly level (intimacy score). 1000 is full loyalty.
  PETINFO_INTIMATE - Pet friendly level (intimacy score). 1000 is full loyalty.
- PETINFO_HUNGRY - Pet hungry level. 100 is completely full.
+ PETINFO_HUNGRY - Pet hungry level. 100 is full hunger.
  PETINFO_RENAMED - Pet rename flag. 0 means this pet has not been named yet.
  PETINFO_RENAMED - Pet rename flag. 0 means this pet has not been named yet.
  PETINFO_LEVEL - Pet level
  PETINFO_LEVEL - Pet level
  PETINFO_BLOCKID - Pet Game ID
  PETINFO_BLOCKID - Pet Game ID
- PETINFO_EGGID - Pet egg item id
- PETINFO_FOODID - Pet food item id
+ PETINFO_EGGID - Pet egg item ID
+ PETINFO_FOODID - Pet food item ID
+
+PETINFO_INTIMATE can be used with the following constants for checking values:
+ PET_INTIMATE_NONE = 0
+ PET_INTIMATE_AWKWARD = 1 ~ 99
+ PET_INTIMATE_SHY = 100 ~ 249
+ PET_INTIMATE_NEUTRAL = 250 ~ 749
+ PET_INTIMATE_CORDIAL = 750 ~ 909
+ PET_INTIMATE_LOYAL = 910 ~ 1000
+
+PETINFO_HUNGRY can be used with the following constants for checking values:
+ PET_HUNGRY_NONE = 0
+ PET_HUNGRY_VERY_HUNGRY = 1 ~ 10
+ PET_HUNGRY_HUNGRY = 11 ~ 25
+ PET_HUNGRY_NEUTRAL = 26 ~ 75
+ PET_HUNGRY_SATISFIED = 76 ~ 90
+ PET_HUNGRY_STUFFED = 91 ~ 100
+
+Example:
+	mes "[Vet]";
+	mes "Your pet + " getpetinfo(PETINFO_NAME);
+	if (getpetinfo(PETINFO_INTIMATE) < PET_INTIMATE_LOYAL)
+		mes "has some growing to do on you!";
+	else
+		mes "seems to love you very much!";
+	close;
 
 
 ---------------------------------------
 ---------------------------------------
 
 

+ 1 - 0
sql-files/main.sql

@@ -967,6 +967,7 @@ CREATE TABLE IF NOT EXISTS `pet` (
   `hungry` smallint(9) unsigned NOT NULL default '0',
   `hungry` smallint(9) unsigned NOT NULL default '0',
   `rename_flag` tinyint(4) unsigned NOT NULL default '0',
   `rename_flag` tinyint(4) unsigned NOT NULL default '0',
   `incubate` int(11) unsigned NOT NULL default '0',
   `incubate` int(11) unsigned NOT NULL default '0',
+  `autofeed` tinyint(2) NOT NULL default '0',
   PRIMARY KEY  (`pet_id`)
   PRIMARY KEY  (`pet_id`)
 ) ENGINE=MyISAM;
 ) ENGINE=MyISAM;
 
 

+ 2 - 0
sql-files/upgrades/upgrade_20190309.sql

@@ -0,0 +1,2 @@
+ALTER TABLE `pet`
+	ADD COLUMN `autofeed` tinyint(2) NOT NULL default '0' AFTER `incubate`;

+ 10 - 8
src/char/int_pet.cpp

@@ -23,7 +23,7 @@ int mapif_load_pet(int fd, uint32 account_id, uint32 char_id, int pet_id);
 //---------------------------------------------------------
 //---------------------------------------------------------
 int inter_pet_tosql(int pet_id, struct s_pet* p)
 int inter_pet_tosql(int pet_id, struct s_pet* p)
 {
 {
-	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
+	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`,`autofeed`)
 	char esc_name[NAME_LENGTH*2+1];// escaped pet name
 	char esc_name[NAME_LENGTH*2+1];// escaped pet name
 
 
 	Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
 	Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
@@ -33,10 +33,10 @@ int inter_pet_tosql(int pet_id, struct s_pet* p)
 	if( pet_id == -1 )
 	if( pet_id == -1 )
 	{// New pet.
 	{// New pet.
 		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
 		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
-			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`) "
-			"VALUES ('%d', '%s', '%d', '%d', '%d', '%hu', '%hu', '%d', '%d', '%d', '%d')",
+			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`,`autofeed`) "
+			"VALUES ('%d', '%s', '%d', '%d', '%d', '%hu', '%hu', '%d', '%d', '%d', '%d', '%d')",
 			schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
 			schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
-			p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate) )
+			p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate, p->autofeed) )
 		{
 		{
 			Sql_ShowDebug(sql_handle);
 			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
@@ -45,9 +45,9 @@ int inter_pet_tosql(int pet_id, struct s_pet* p)
 	}
 	}
 	else
 	else
 	{// Update pet.
 	{// Update pet.
-		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%hu',`equip`='%hu',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d' WHERE `pet_id`='%d'",
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%hu',`equip`='%hu',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d',`autofeed`='%d' WHERE `pet_id`='%d'",
 			schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
 			schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
-			p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate, p->pet_id) )
+			p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate, p->autofeed, p->pet_id) )
 		{
 		{
 			Sql_ShowDebug(sql_handle);
 			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
@@ -69,9 +69,9 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
 #endif
 #endif
 	memset(p, 0, sizeof(struct s_pet));
 	memset(p, 0, sizeof(struct s_pet));
 
 
-	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
+	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`,`autofeed`)
 
 
-	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate` FROM `%s` WHERE `pet_id`='%d'", schema_config.pet_db, pet_id) )
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`,`autofeed` FROM `%s` WHERE `pet_id`='%d'", schema_config.pet_db, pet_id) )
 	{
 	{
 		Sql_ShowDebug(sql_handle);
 		Sql_ShowDebug(sql_handle);
 		return 0;
 		return 0;
@@ -91,6 +91,7 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
 		Sql_GetData(sql_handle,  9, &data, NULL); p->hungry = atoi(data);
 		Sql_GetData(sql_handle,  9, &data, NULL); p->hungry = atoi(data);
 		Sql_GetData(sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
 		Sql_GetData(sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
 		Sql_GetData(sql_handle, 11, &data, NULL); p->incubate = atoi(data);
 		Sql_GetData(sql_handle, 11, &data, NULL); p->incubate = atoi(data);
+		Sql_GetData(sql_handle, 12, &data, NULL); p->autofeed = atoi(data) != 0;
 
 
 		Sql_FreeResult(sql_handle);
 		Sql_FreeResult(sql_handle);
 
 
@@ -201,6 +202,7 @@ int mapif_create_pet(int fd, uint32 account_id, uint32 char_id, short pet_class,
 	pet_pt->hungry = hungry;
 	pet_pt->hungry = hungry;
 	pet_pt->rename_flag = rename_flag;
 	pet_pt->rename_flag = rename_flag;
 	pet_pt->incubate = incubate;
 	pet_pt->incubate = incubate;
+	pet_pt->autofeed = 0;
 
 
 	if(pet_pt->hungry < 0)
 	if(pet_pt->hungry < 0)
 		pet_pt->hungry = 0;
 		pet_pt->hungry = 0;

+ 24 - 0
src/common/database.cpp

@@ -20,6 +20,24 @@ bool YamlDatabase::nodeExists( const YAML::Node& node, const std::string& name )
 	}
 	}
 }
 }
 
 
+bool YamlDatabase::nodesExist( const YAML::Node& node, std::initializer_list<const std::string> names ){
+	bool missing = false;
+
+	for( const std::string& name : names ){
+		if( !this->nodeExists( node, name ) ){
+			ShowError( "Missing mandatory node \"%s\".\n", name.c_str() );
+			missing = true;
+		}
+	}
+
+	if( missing ){
+		this->invalidWarning( node, "At least one mandatory node did not exist.\n" );
+		return false;
+	}
+
+	return true;
+}
+
 bool YamlDatabase::verifyCompatibility( const YAML::Node& rootNode ){
 bool YamlDatabase::verifyCompatibility( const YAML::Node& rootNode ){
 	if( !this->nodeExists( rootNode, "Header" ) ){
 	if( !this->nodeExists( rootNode, "Header" ) ){
 		ShowError( "No database \"Header\" was found.\n" );
 		ShowError( "No database \"Header\" was found.\n" );
@@ -67,6 +85,12 @@ bool YamlDatabase::load(){
 	return this->load( this->getDefaultLocation() );
 	return this->load( this->getDefaultLocation() );
 }
 }
 
 
+bool YamlDatabase::reload(){
+	this->clear();
+
+	return this->load();
+}
+
 bool YamlDatabase::load(const std::string& path) {
 bool YamlDatabase::load(const std::string& path) {
 	YAML::Node rootNode;
 	YAML::Node rootNode;
 
 

+ 2 - 0
src/common/database.hpp

@@ -31,6 +31,7 @@ private:
 protected:
 protected:
 	// Helper functions
 	// Helper functions
 	bool nodeExists( const YAML::Node& node, const std::string& name );
 	bool nodeExists( const YAML::Node& node, const std::string& name );
+	bool nodesExist( const YAML::Node& node, std::initializer_list<const std::string> names );
 	void invalidWarning( const YAML::Node &node, const char* fmt, ... );
 	void invalidWarning( const YAML::Node &node, const char* fmt, ... );
 	std::string getCurrentFile();
 	std::string getCurrentFile();
 
 
@@ -58,6 +59,7 @@ public:
 	}
 	}
 
 
 	bool load();
 	bool load();
+	bool reload();
 
 
 	// Functions that need to be implemented for each type
 	// Functions that need to be implemented for each type
 	virtual void clear() = 0;
 	virtual void clear() = 0;

+ 1 - 0
src/common/mmo.hpp

@@ -407,6 +407,7 @@ struct s_pet {
 	char name[NAME_LENGTH];
 	char name[NAME_LENGTH];
 	char rename_flag;
 	char rename_flag;
 	char incubate;
 	char incubate;
+	bool autofeed;
 };
 };
 
 
 struct s_homunculus {	//[orn]
 struct s_homunculus {	//[orn]

+ 11 - 6
src/map/atcommand.cpp

@@ -2742,7 +2742,6 @@ ACMD_FUNC(guildlevelup) {
 ACMD_FUNC(makeegg) {
 ACMD_FUNC(makeegg) {
 	struct item_data *item_data;
 	struct item_data *item_data;
 	int id;
 	int id;
-	struct s_pet_db* pet;
 
 
 	nullpo_retr(-1, sd);
 	nullpo_retr(-1, sd);
 
 
@@ -2759,12 +2758,18 @@ ACMD_FUNC(makeegg) {
 	else
 	else
 		id = atoi(message);
 		id = atoi(message);
 
 
-	pet = pet_db(id);
-	if (!pet)
+	std::shared_ptr<s_pet_db> pet = pet_db.find(id);
+
+	if( pet == nullptr ){
 		pet = pet_db_search(id, PET_EGG);
 		pet = pet_db_search(id, PET_EGG);
+	}
+
 	if (pet != nullptr) {
 	if (pet != nullptr) {
 		sd->catch_target_class = pet->class_;
 		sd->catch_target_class = pet->class_;
-		intif_create_pet(sd->status.account_id, sd->status.char_id, pet->class_, mob_db(pet->class_)->lv, pet->EggID, 0, pet->intimate, 100, 0, 1, pet->jname);
+
+		struct mob_db* mdb = mob_db(pet->class_);
+
+		intif_create_pet(sd->status.account_id, sd->status.char_id, pet->class_, mdb->lv, pet->EggID, 0, pet->intimate, 100, 0, 1, mdb->jname);
 	} else {
 	} else {
 		clif_displaymessage(fd, msg_txt(sd,180)); // The monster/egg name/id doesn't exist.
 		clif_displaymessage(fd, msg_txt(sd,180)); // The monster/egg name/id doesn't exist.
 		return -1;
 		return -1;
@@ -3819,7 +3824,7 @@ ACMD_FUNC(reload) {
 		clif_displaymessage(fd, msg_txt(sd,97)); // Item database has been reloaded.
 		clif_displaymessage(fd, msg_txt(sd,97)); // Item database has been reloaded.
 	} else if (strstr(command, "mobdb") || strncmp(message, "mobdb", 3) == 0) {
 	} else if (strstr(command, "mobdb") || strncmp(message, "mobdb", 3) == 0) {
 		mob_reload();
 		mob_reload();
-		read_petdb();
+		pet_db.reload();
 		hom_reload();
 		hom_reload();
 		mercenary_readdb();
 		mercenary_readdb();
 		mercenary_read_skilldb();
 		mercenary_read_skilldb();
@@ -4488,7 +4493,7 @@ ACMD_FUNC(repairall)
 
 
 	count = 0;
 	count = 0;
 	for (i = 0; i < MAX_INVENTORY; i++) {
 	for (i = 0; i < MAX_INVENTORY; i++) {
-		if (sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].attribute == 1) {
+		if (sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].card[0] != CARD0_PET && sd->inventory.u.items_inventory[i].attribute == 1) {
 			sd->inventory.u.items_inventory[i].attribute = 0;
 			sd->inventory.u.items_inventory[i].attribute = 0;
 			clif_produceeffect(sd, 0, sd->inventory.u.items_inventory[i].nameid);
 			clif_produceeffect(sd, 0, sd->inventory.u.items_inventory[i].nameid);
 			count++;
 			count++;

+ 15 - 0
src/map/battle.cpp

@@ -8506,6 +8506,10 @@ static const struct _battle_data {
 	{ "allow_bound_sell",                   &battle_config.allow_bound_sell,                0,      0,      0xF,            },
 	{ "allow_bound_sell",                   &battle_config.allow_bound_sell,                0,      0,      0xF,            },
 	{ "event_refine_chance",                &battle_config.event_refine_chance,             0,      0,      1,              },
 	{ "event_refine_chance",                &battle_config.event_refine_chance,             0,      0,      1,              },
 	{ "autoloot_adjust",                    &battle_config.autoloot_adjust,                 0,      0,      1,              },
 	{ "autoloot_adjust",                    &battle_config.autoloot_adjust,                 0,      0,      1,              },
+	{ "feature.petevolution",               &battle_config.feature_petevolution,            1,      0,      1,              },
+	{ "feature.petautofeed",                &battle_config.feature_pet_autofeed,            1,      0,      1,              },
+	{ "feature.pet_autofeed_rate",          &battle_config.feature_pet_autofeed_rate,      89,      0,    100,              },
+	{ "pet_autofeed_always",                &battle_config.pet_autofeed_always,             1,      0,      1,              },
 	{ "broadcast_hide_name",                &battle_config.broadcast_hide_name,             2,      0,      NAME_LENGTH,    },
 	{ "broadcast_hide_name",                &battle_config.broadcast_hide_name,             2,      0,      NAME_LENGTH,    },
 	{ "skill_drop_items_full",              &battle_config.skill_drop_items_full,           0,      0,      1,              },
 	{ "skill_drop_items_full",              &battle_config.skill_drop_items_full,           0,      0,      1,              },
 	{ "switch_remove_edp",                  &battle_config.switch_remove_edp,               2,      0,      3,              },
 	{ "switch_remove_edp",                  &battle_config.switch_remove_edp,               2,      0,      3,              },
@@ -8649,6 +8653,17 @@ void battle_adjust_conf()
 	}
 	}
 #endif
 #endif
 
 
+#if PACKETVER < 20141008
+	if (battle_config.feature_petevolution) {
+		ShowWarning("conf/battle/feature.conf petevolution is enabled but it requires PACKETVER 2014-10-08 or newer, disabling...\n");
+		battle_config.feature_petevolution = 0;
+	}
+	if (battle_config.feature_pet_auto_feed) {
+		ShowWarning("conf/battle/feature.conf pet auto feed is enabled but it requires PACKETVER 2014-10-08 or newer, disabling...\n");
+		battle_config.feature_pet_auto_feed = 0;
+	}
+#endif
+
 #if PACKETVER < 20170208
 #if PACKETVER < 20170208
 	if (battle_config.feature_equipswitch) {
 	if (battle_config.feature_equipswitch) {
 		ShowWarning("conf/battle/feature.conf equip switch is enabled but it requires PACKETVER 2017-02-08 or newer, disabling...\n");
 		ShowWarning("conf/battle/feature.conf equip switch is enabled but it requires PACKETVER 2017-02-08 or newer, disabling...\n");

+ 4 - 0
src/map/battle.hpp

@@ -641,6 +641,10 @@ struct Battle_Config
 	int allow_bound_sell;
 	int allow_bound_sell;
 	int event_refine_chance;
 	int event_refine_chance;
 	int autoloot_adjust;
 	int autoloot_adjust;
+	int feature_petevolution;
+	int feature_pet_autofeed;
+	int feature_pet_autofeed_rate;
+	int pet_autofeed_always;
 	int broadcast_hide_name;
 	int broadcast_hide_name;
 	int skill_drop_items_full;
 	int skill_drop_items_full;
 	int switch_remove_edp;
 	int switch_remove_edp;

+ 50 - 14
src/map/clif.cpp

@@ -7970,25 +7970,13 @@ void clif_send_petstatus(struct map_session_data *sd)
 void clif_pet_emotion(struct pet_data *pd,int param)
 void clif_pet_emotion(struct pet_data *pd,int param)
 {
 {
 	unsigned char buf[16];
 	unsigned char buf[16];
-	s_pet_db *pet_db_ptr;
 
 
 	nullpo_retv(pd);
 	nullpo_retv(pd);
 
 
-	pet_db_ptr = pd->get_pet_db();
-
 	memset(buf,0,packet_len(0x1aa));
 	memset(buf,0,packet_len(0x1aa));
 
 
 	WBUFW(buf,0)=0x1aa;
 	WBUFW(buf,0)=0x1aa;
 	WBUFL(buf,2)=pd->bl.id;
 	WBUFL(buf,2)=pd->bl.id;
-	if(param >= 100 && pet_db_ptr->talk_convert_class) {
-		if(pet_db_ptr->talk_convert_class < 0)
-			return;
-		else if(pet_db_ptr->talk_convert_class > 0) {
-			// replace mob_id component of talk/act data
-			param -= (pd->pet.class_ - 100)*100;
-			param += (pet_db_ptr->talk_convert_class - 100)*100;
-		}
-	}
 	WBUFL(buf,6)=param;
 	WBUFL(buf,6)=param;
 
 
 	clif_send(buf,packet_len(0x1aa),&pd->bl,AREA);
 	clif_send(buf,packet_len(0x1aa),&pd->bl,AREA);
@@ -10408,7 +10396,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 	if( sd->pd ) {
 	if( sd->pd ) {
 		if( battle_config.pet_no_gvg && mapdata_flag_gvg(mapdata) ) { //Return the pet to egg. [Skotlex]
 		if( battle_config.pet_no_gvg && mapdata_flag_gvg(mapdata) ) { //Return the pet to egg. [Skotlex]
 			clif_displaymessage(sd->fd, msg_txt(sd,666));
 			clif_displaymessage(sd->fd, msg_txt(sd,666));
-			pet_menu(sd, 3); //Option 3 is return to egg.
+			pet_return_egg( sd, sd->pd );
 		} else {
 		} else {
 			if(map_addblock(&sd->pd->bl))
 			if(map_addblock(&sd->pd->bl))
 				return;
 				return;
@@ -10527,6 +10515,21 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		clif_partyinvitationstate(sd);
 		clif_partyinvitationstate(sd);
 		clif_equipcheckbox(sd);
 		clif_equipcheckbox(sd);
 #endif
 #endif
+#if PACKETVER >= 20141008
+		if( battle_config.pet_autofeed_always ){
+			// Always send ON or OFF
+			if( sd->pd && battle_config.feature_pet_autofeed ){
+				clif_configuration( sd, CONFIG_PET_AUTOFEED, sd->pd->pet.autofeed );
+			}else{
+				clif_configuration( sd, CONFIG_PET_AUTOFEED, false );
+			}
+		}else{
+			// Only send when enabled
+			if( sd->pd && battle_config.feature_pet_autofeed && sd->pd->pet.autofeed ){
+				clif_configuration( sd, CONFIG_PET_AUTOFEED, true );
+			}
+		}
+#endif
 #if PACKETVER >= 20170920
 #if PACKETVER >= 20170920
 		if( battle_config.homunculus_autofeed_always ){
 		if( battle_config.homunculus_autofeed_always ){
 			// Always send ON or OFF
 			// Always send ON or OFF
@@ -16687,7 +16690,12 @@ void clif_parse_configuration( int fd, struct map_session_data* sd ){
 			sd->status.show_equip = flag;
 			sd->status.show_equip = flag;
 			break;
 			break;
 		case CONFIG_PET_AUTOFEED:
 		case CONFIG_PET_AUTOFEED:
-			// TODO: Implement with pet evolution system
+			// Player can not click this if he does not have a pet
+			if( sd->pd == nullptr || !battle_config.feature_pet_autofeed || !sd->pd->get_pet_db()->allow_autofeed ){
+				return;
+			}
+
+			sd->pd->pet.autofeed = flag;
 			break;
 			break;
 		case CONFIG_HOMUNCULUS_AUTOFEED:
 		case CONFIG_HOMUNCULUS_AUTOFEED:
 			// Player can not click this if he does not have a homunculus or it is vaporized
 			// Player can not click this if he does not have a homunculus or it is vaporized
@@ -20369,6 +20377,34 @@ void clif_achievement_reward_ack(int fd, unsigned char result, int achievement_i
 	WFIFOSET(fd, packet_len(0xa26));
 	WFIFOSET(fd, packet_len(0xa26));
 }
 }
 
 
+/// Process the pet evolution request
+/// 09fb <packetType>.W <packetLength>.W <evolutionPetEggITID>.W (CZ_PET_EVOLUTION)
+void clif_parse_pet_evolution( int fd, struct map_session_data *sd ){
+#if PACKETVER >= 20141008
+	auto pet = pet_db_search(RFIFOW(fd, 4), PET_EGG);
+
+	if (!pet) {
+		clif_pet_evolution_result(sd, e_pet_evolution_result::FAIL_NOT_PETEGG);
+		return;
+	}
+
+	pet_evolution(sd, pet->class_);
+#endif
+}
+
+/// Sends the result of the evolution to the client.
+/// 09fc <result>.L (ZC_PET_EVOLUTION_RESULT)
+void clif_pet_evolution_result( struct map_session_data* sd, e_pet_evolution_result result ){
+#if PACKETVER >= 20141008
+	int fd = sd->fd;
+
+	WFIFOHEAD(fd, packet_len(0x9fc));
+	WFIFOW(fd, 0) = 0x9fc;
+	WFIFOL(fd, 2) = static_cast<uint32>(result);
+	WFIFOSET(fd, packet_len(0x9fc));
+#endif
+}
+
 /*
 /*
  * This packet is sent by /changedress or /nocosplay
  * This packet is sent by /changedress or /nocosplay
  *
  *

+ 13 - 0
src/map/clif.hpp

@@ -549,6 +549,16 @@ enum e_damage_type : uint8_t {
 	DMG_TOUCH,				/// (touch skill?)
 	DMG_TOUCH,				/// (touch skill?)
 };
 };
 
 
+enum class e_pet_evolution_result : uint32 {
+	FAIL_UNKNOWN = 0x0,
+	FAIL_NOTEXIST_CALLPET = 0x1,
+	FAIL_NOT_PETEGG = 0x2,
+	FAIL_RECIPE = 0x3,
+	FAIL_MATERIAL = 0x4,
+	FAIL_RG_FAMILIAR = 0x5,
+	SUCCESS = 0x6
+};
+
 enum e_config_type : uint32 {
 enum e_config_type : uint32 {
 	CONFIG_OPEN_EQUIPMENT_WINDOW = 0,
 	CONFIG_OPEN_EQUIPMENT_WINDOW = 0,
 	// Unknown
 	// Unknown
@@ -1113,4 +1123,7 @@ void clif_equipswitch_add( struct map_session_data* sd,uint16 index, uint32 pos,
 void clif_equipswitch_remove( struct map_session_data* sd, uint16 index, uint32 pos, bool failed );
 void clif_equipswitch_remove( struct map_session_data* sd, uint16 index, uint32 pos, bool failed );
 void clif_equipswitch_reply( struct map_session_data* sd, bool failed );
 void clif_equipswitch_reply( struct map_session_data* sd, bool failed );
 
 
+/// Pet evolution
+void clif_pet_evolution_result( struct map_session_data* sd, e_pet_evolution_result result );
+
 #endif /* CLIF_HPP */
 #endif /* CLIF_HPP */

+ 6 - 3
src/map/clif_packetdb.hpp

@@ -2193,6 +2193,12 @@
 	packet(0x09DA,-1);
 	packet(0x09DA,-1);
 #endif
 #endif
 
 
+// 2014-10-08Ragexe
+#if PACKETVER >= 20141008
+	parseable_packet(0x9FB, -1, clif_parse_pet_evolution, 2, 4); // CZ_PET_EVOLUTION
+	packet(0x09FC, 6); // ZC_PET_EVOLUTION_RESULT
+#endif
+
 // 2014-10-16Ragexe
 // 2014-10-16Ragexe
 #if PACKETVER >= 20141016
 #if PACKETVER >= 20141016
 	packet(0x09DF,7);
 	packet(0x09DF,7);
@@ -2284,9 +2290,6 @@
 	parseable_packet(0x0A2E,6,clif_parse_change_title,0); // CZ_REQ_CHANGE_TITLE
 	parseable_packet(0x0A2E,6,clif_parse_change_title,0); // CZ_REQ_CHANGE_TITLE
 	packet(0x0A2F,7); // ZC_ACK_CHANGE_TITLE
 	packet(0x0A2F,7); // ZC_ACK_CHANGE_TITLE
 	packet(0x0A30,106); // ZC_ACK_REQNAMEALL2
 	packet(0x0A30,106); // ZC_ACK_REQNAMEALL2
-	// Pet Evolution System
-	parseable_packet(0x09FB,-1,clif_parse_dull,0); // CZ_PET_EVOLUTION
-	packet(0x09FC,6); // ZC_PET_EVOLUTION_RESULT
 
 
 	// Quest UI
 	// Quest UI
 	packet(0x08FE,-1); // ZC_HUNTING_QUEST_INFO
 	packet(0x08FE,-1); // ZC_HUNTING_QUEST_INFO

+ 4 - 0
src/map/itemdb.cpp

@@ -116,6 +116,10 @@ struct item_data* itemdb_searchname(const char *str)
 	return itemdb_searchname1(str, false);
 	return itemdb_searchname1(str, false);
 }
 }
 
 
+struct item_data* itemdb_search_aegisname( const char *str ){
+	return itemdb_searchname1( str, true );
+}
+
 /**
 /**
  * @see DBMatcher
  * @see DBMatcher
  */
  */

+ 1 - 0
src/map/itemdb.hpp

@@ -889,6 +889,7 @@ struct s_random_opt_group {
 };
 };
 
 
 struct item_data* itemdb_searchname(const char *name);
 struct item_data* itemdb_searchname(const char *name);
+struct item_data* itemdb_search_aegisname( const char *str );
 int itemdb_searchname_array(struct item_data** data, int size, const char *str);
 int itemdb_searchname_array(struct item_data** data, int size, const char *str);
 struct item_data* itemdb_search(unsigned short nameid);
 struct item_data* itemdb_search(unsigned short nameid);
 struct item_data* itemdb_exists(unsigned short nameid);
 struct item_data* itemdb_exists(unsigned short nameid);

+ 1 - 1
src/map/map-server.vcxproj

@@ -351,7 +351,7 @@
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_race2_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_race2_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_race2_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_race2_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_random_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_random_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_random_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_random_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_skill_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_skill_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_skill_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_skill_db.txt')" />
-    <Copy SourceFiles="$(SolutionDir)db\import-tmpl\pet_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\pet_db.txt')" />
+    <Copy SourceFiles="$(SolutionDir)db\import-tmpl\pet_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\pet_db.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine_db.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine_db.yml')" />

+ 11 - 0
src/map/mob.cpp

@@ -333,6 +333,17 @@ uint16 mobdb_searchname(const char * const str)
 {
 {
 	return mobdb_searchname_(str, true);
 	return mobdb_searchname_(str, true);
 }
 }
+
+struct mob_db* mobdb_search_aegisname( const char* str ){
+	for( auto &mobdb_pair : mob_db_data ){
+		if( strcmpi( str, mobdb_pair.second.sprite ) == 0 ){
+			return &mobdb_pair.second;
+		}
+	}
+
+	return nullptr;
+}
+
 /*==========================================
 /*==========================================
  * Founds up to N matches. Returns number of matches [Skotlex]
  * Founds up to N matches. Returns number of matches [Skotlex]
  *------------------------------------------*/
  *------------------------------------------*/

+ 1 - 0
src/map/mob.hpp

@@ -301,6 +301,7 @@ struct item_drop_list {
 
 
 struct mob_db *mob_db(int mob_id);
 struct mob_db *mob_db(int mob_id);
 uint16 mobdb_searchname(const char * const str);
 uint16 mobdb_searchname(const char * const str);
+struct mob_db* mobdb_search_aegisname( const char* str );
 int mobdb_searchname_array(const char *str, uint16 * out, int size);
 int mobdb_searchname_array(const char *str, uint16 * out, int size);
 int mobdb_checkid(const int id);
 int mobdb_checkid(const int id);
 struct view_data* mob_get_viewdata(int mob_id);
 struct view_data* mob_get_viewdata(int mob_id);

+ 1 - 1
src/map/pc.cpp

@@ -7944,7 +7944,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 	if(sd->status.pet_id > 0 && sd->pd) {
 	if(sd->status.pet_id > 0 && sd->pd) {
 		struct pet_data *pd = sd->pd;
 		struct pet_data *pd = sd->pd;
 		if( !mapdata->flag[MF_NOEXPPENALTY] ) {
 		if( !mapdata->flag[MF_NOEXPPENALTY] ) {
-			pet_set_intimate(pd, pd->pet.intimate - pd->get_pet_db()->die);
+			pet_set_intimate(pd, pd->pet.intimate + pd->get_pet_db()->die);
 			if( pd->pet.intimate < 0 )
 			if( pd->pet.intimate < 0 )
 				pd->pet.intimate = 0;
 				pd->pet.intimate = 0;
 			clif_send_petdata(sd,sd->pd,1,pd->pet.intimate);
 			clif_send_petdata(sd,sd->pd,1,pd->pet.intimate);

File diff suppressed because it is too large
+ 636 - 113
src/map/pet.cpp


+ 73 - 31
src/map/pet.hpp

@@ -5,6 +5,7 @@
 #define PET_HPP
 #define PET_HPP
 
 
 #include "../common/cbasetypes.hpp"
 #include "../common/cbasetypes.hpp"
+#include "../common/database.hpp"
 #include "../common/mmo.hpp"
 #include "../common/mmo.hpp"
 #include "../common/timer.hpp"
 #include "../common/timer.hpp"
 
 
@@ -12,42 +13,49 @@
 #include "status.hpp"
 #include "status.hpp"
 #include "unit.hpp"
 #include "unit.hpp"
 
 
+#include <unordered_map>
+
 #define MAX_PETLOOT_SIZE	30
 #define MAX_PETLOOT_SIZE	30
 
 
+struct s_pet_evo_data {
+	uint16 target_mob_id;
+	std::unordered_map<uint16, uint32> requirements;
+};
+
 /// Pet DB
 /// Pet DB
 struct s_pet_db {
 struct s_pet_db {
-	short class_; ///< Monster ID
-	char name[NAME_LENGTH], ///< AEGIS name
-		jname[NAME_LENGTH]; ///< English name
-	unsigned short itemID; ///< Lure ID
-	unsigned short EggID; ///< Egg ID
-	unsigned short AcceID; ///< Accessory ID
-	unsigned short FoodID; ///< Food ID
-	int fullness; ///< Amount of hunger decresed each hungry_delay interval
-	int hungry_delay; ///< Hunger value decrease each x seconds
-	int r_hungry; ///< Intimacy increased after feeding
-	int r_full; ///< Intimacy reduced when over-fed
-	int intimate; ///< Initial intimacy value
-	int die; ///< Intimacy decreased when die
-	int capture; ///< Capture success rate 1000 = 100%
-	int speed; ///< Walk speed
-	char s_perfor; ///< Special performance
-	int talk_convert_class; ///< Disables pet talk (instead of talking they emote  with /!.) (?)
-	int attack_rate; ///< Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy).
-	int defence_attack_rate; ///< Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy).
-	int change_target_rate; ///< Rate of which the pet will change its attack target.
+	uint16 class_; ///< Monster ID
+	uint16 itemID; ///< Lure ID
+	uint16 EggID; ///< Egg ID
+	uint16 AcceID; ///< Accessory ID
+	uint16 FoodID; ///< Food ID
+	uint16 fullness; ///< Amount of hunger decresed each hungry_delay interval
+	uint32 hungry_delay; ///< Hunger value decrease each x seconds
+	int32 hunger_increase; ///< Hunger increased every time the pet is fed.
+	int32 r_hungry; ///< Intimacy increased after feeding
+	int32 r_full; ///< Intimacy increased when over-fed
+	uint32 intimate; ///< Initial intimacy value
+	int32 die; ///< Intimacy increased when die
+	int32 hungry_intimacy_dec; ///< Intimacy increased when hungry
+	uint16 capture; ///< Capture success rate 10000 = 100%
+	bool s_perfor; ///< Special performance
+	uint16 attack_rate; ///< Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy).
+	uint16 defence_attack_rate; ///< Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy).
+	uint16 change_target_rate; ///< Rate of which the pet will change its attack target.
+	bool allow_autofeed; ///< Can this pet use auto feeding mechanic.
+	std::unordered_map<uint16, std::shared_ptr<s_pet_evo_data>> evolution_data; ///< Data for evolving the pet.
 	struct script_code
 	struct script_code
-		*pet_script, ///< Script since pet hatched
-		*pet_loyal_script; ///< Script when pet is loyal
+		*pet_support_script, ///< Script since pet hatched. For pet* script commands only.
+		*pet_bonus_script; ///< Bonus script for this pet.
 
 
 	~s_pet_db()
 	~s_pet_db()
 	{
 	{
-		if( this->pet_script ){
-			script_free_code(this->pet_script);
+		if( this->pet_support_script ){
+			script_free_code(this->pet_support_script);
 		}
 		}
 
 
-		if( this->pet_loyal_script ){
-			script_free_code(this->pet_loyal_script);
+		if( this->pet_bonus_script ){
+			script_free_code(this->pet_bonus_script);
 		}
 		}
 	}
 	}
 };
 };
@@ -60,6 +68,25 @@ enum e_pet_catch : uint16 {
 	PET_CATCH_UNIVERSAL_ITEM = 2,
 	PET_CATCH_UNIVERSAL_ITEM = 2,
 };
 };
 
 
+enum e_pet_intimate_level : uint16 {
+	PET_INTIMATE_NONE = 0,
+	PET_INTIMATE_AWKWARD = 1,
+	PET_INTIMATE_SHY = 100,
+	PET_INTIMATE_NEUTRAL = 250,
+	PET_INTIMATE_CORDIAL = 750,
+	PET_INTIMATE_LOYAL = 910,
+	PET_INTIMATE_MAX = 1000
+};
+
+enum e_pet_hungry : uint16 {
+	PET_HUNGRY_NONE = 0,
+	PET_HUNGRY_VERY_HUNGRY = 10,
+	PET_HUNGRY_HUNGRY = 25,
+	PET_HUNGRY_NEUTRAL = 75,
+	PET_HUNGRY_SATISFIED = 90,
+	PET_HUNGRY_STUFFED = 100
+};
+
 struct pet_recovery { //Stat recovery
 struct pet_recovery { //Stat recovery
 	enum sc_type type;	//Status Change id
 	enum sc_type type;	//Status Change id
 	unsigned short delay; //How long before curing (secs).
 	unsigned short delay; //How long before curing (secs).
@@ -99,7 +126,18 @@ struct pet_loot {
 	unsigned short max;
 	unsigned short max;
 };
 };
 
 
-struct s_pet_db *pet_db(uint16 pet_id);
+class PetDatabase : public TypesafeYamlDatabase<uint16,s_pet_db>{
+public:
+	PetDatabase() : TypesafeYamlDatabase( "PET_DB", 1 ){
+
+	}
+
+	const std::string getDefaultLocation();
+	uint64 parseBodyNode( const YAML::Node& node );
+	bool reload();
+};
+
+extern PetDatabase pet_db;
 
 
 struct pet_data {
 struct pet_data {
 	struct block_list bl;
 	struct block_list bl;
@@ -126,8 +164,8 @@ struct pet_data {
 	int masterteleport_timer;
 	int masterteleport_timer;
 	struct map_session_data *master;
 	struct map_session_data *master;
 
 
-	s_pet_db* get_pet_db() {
-		return pet_db(this->pet.class_);
+	std::shared_ptr<s_pet_db> get_pet_db() {
+		return pet_db.find(this->pet.class_);
 	}
 	}
 };
 };
 
 
@@ -137,9 +175,10 @@ void pet_set_intimate(struct pet_data *pd, int value);
 int pet_target_check(struct pet_data *pd,struct block_list *bl,int type);
 int pet_target_check(struct pet_data *pd,struct block_list *bl,int type);
 void pet_unlocktarget(struct pet_data *pd);
 void pet_unlocktarget(struct pet_data *pd);
 int pet_sc_check(struct map_session_data *sd, int type); //Skotlex
 int pet_sc_check(struct map_session_data *sd, int type); //Skotlex
-struct s_pet_db* pet_db_search(int key, enum e_pet_itemtype type);
+std::shared_ptr<s_pet_db> pet_db_search(int key, enum e_pet_itemtype type);
 int pet_hungry_timer_delete(struct pet_data *pd);
 int pet_hungry_timer_delete(struct pet_data *pd);
 bool pet_data_init(struct map_session_data *sd, struct s_pet *pet);
 bool pet_data_init(struct map_session_data *sd, struct s_pet *pet);
+bool pet_return_egg( struct map_session_data *sd, struct pet_data *pd );
 int pet_birth_process(struct map_session_data *sd, struct s_pet *pet);
 int pet_birth_process(struct map_session_data *sd, struct s_pet *pet);
 int pet_recv_petdata(uint32 account_id,struct s_pet *p,int flag);
 int pet_recv_petdata(uint32 account_id,struct s_pet *p,int flag);
 int pet_select_egg(struct map_session_data *sd,short egg_index);
 int pet_select_egg(struct map_session_data *sd,short egg_index);
@@ -156,11 +195,14 @@ TIMER_FUNC(pet_skill_support_timer); // [Skotlex]
 TIMER_FUNC(pet_skill_bonus_timer); // [Valaris]
 TIMER_FUNC(pet_skill_bonus_timer); // [Valaris]
 TIMER_FUNC(pet_recovery_timer); // [Valaris]
 TIMER_FUNC(pet_recovery_timer); // [Valaris]
 TIMER_FUNC(pet_heal_timer); // [Valaris]
 TIMER_FUNC(pet_heal_timer); // [Valaris]
+int pet_egg_search(struct map_session_data *sd, int pet_id);
+void pet_evolution(struct map_session_data *sd, int16 pet_id);
+int pet_food(struct map_session_data *sd, struct pet_data *pd);
+void pet_clear_support_bonuses(struct map_session_data *sd);
 
 
 #define pet_stop_walking(pd, type) unit_stop_walking(&(pd)->bl, type)
 #define pet_stop_walking(pd, type) unit_stop_walking(&(pd)->bl, type)
 #define pet_stop_attack(pd) unit_stop_attack(&(pd)->bl)
 #define pet_stop_attack(pd) unit_stop_attack(&(pd)->bl)
 
 
-void read_petdb(void);
 void do_init_pet(void);
 void do_init_pet(void);
 void do_final_pet(void);
 void do_final_pet(void);
 
 

+ 8 - 7
src/map/script.cpp

@@ -8638,7 +8638,7 @@ BUILDIN_FUNC(getbrokenid)
 
 
 	num = script_getnum(st,2);
 	num = script_getnum(st,2);
 	for(i = 0; i < MAX_INVENTORY; i++) {
 	for(i = 0; i < MAX_INVENTORY; i++) {
-		if(sd->inventory.u.items_inventory[i].attribute) {
+		if( sd->inventory.u.items_inventory[i].card[0] != CARD0_PET && sd->inventory.u.items_inventory[i].attribute ){
 				brokencounter++;
 				brokencounter++;
 				if(num == brokencounter){
 				if(num == brokencounter){
 					id = sd->inventory.u.items_inventory[i].nameid;
 					id = sd->inventory.u.items_inventory[i].nameid;
@@ -8667,7 +8667,7 @@ BUILDIN_FUNC(repair)
 
 
 	num = script_getnum(st,2);
 	num = script_getnum(st,2);
 	for(i = 0; i < MAX_INVENTORY; i++) {
 	for(i = 0; i < MAX_INVENTORY; i++) {
-		if(sd->inventory.u.items_inventory[i].attribute) {
+		if( sd->inventory.u.items_inventory[i].card[0] != CARD0_PET && sd->inventory.u.items_inventory[i].attribute ){
 				repaircounter++;
 				repaircounter++;
 				if(num == repaircounter) {
 				if(num == repaircounter) {
 					sd->inventory.u.items_inventory[i].attribute = 0;
 					sd->inventory.u.items_inventory[i].attribute = 0;
@@ -8695,8 +8695,7 @@ BUILDIN_FUNC(repairall)
 
 
 	for(i = 0; i < MAX_INVENTORY; i++)
 	for(i = 0; i < MAX_INVENTORY; i++)
 	{
 	{
-		if(sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].attribute)
-		{
+		if( sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].card[0] != CARD0_PET && sd->inventory.u.items_inventory[i].attribute ){
 			sd->inventory.u.items_inventory[i].attribute = 0;
 			sd->inventory.u.items_inventory[i].attribute = 0;
 			clif_produceeffect(sd,0,sd->inventory.u.items_inventory[i].nameid);
 			clif_produceeffect(sd,0,sd->inventory.u.items_inventory[i].nameid);
 			repaircounter++;
 			repaircounter++;
@@ -10110,13 +10109,12 @@ BUILDIN_FUNC(makepet)
 {
 {
 	struct map_session_data* sd;
 	struct map_session_data* sd;
 	uint16 mob_id;
 	uint16 mob_id;
-	struct s_pet_db* pet;
 
 
 	if( !script_rid2sd(sd) )
 	if( !script_rid2sd(sd) )
 		return SCRIPT_CMD_FAILURE;
 		return SCRIPT_CMD_FAILURE;
 
 
 	mob_id = script_getnum(st,2);
 	mob_id = script_getnum(st,2);
-	pet = pet_db(mob_id);
+	std::shared_ptr<s_pet_db> pet = pet_db.find(mob_id);
 
 
 	if( !pet ){
 	if( !pet ){
 		ShowError( "buildin_makepet: failed to create a pet with mob id %hu\n", mob_id);
 		ShowError( "buildin_makepet: failed to create a pet with mob id %hu\n", mob_id);
@@ -10124,7 +10122,10 @@ BUILDIN_FUNC(makepet)
 	}
 	}
 
 
 	sd->catch_target_class = mob_id;
 	sd->catch_target_class = mob_id;
-	intif_create_pet( sd->status.account_id, sd->status.char_id, pet->class_, mob_db(pet->class_)->lv, pet->EggID, 0, pet->intimate, 100, 0, 1, pet->jname );
+
+	struct mob_db* mdb = mob_db(pet->class_);
+
+	intif_create_pet( sd->status.account_id, sd->status.char_id, pet->class_, mdb->lv, pet->EggID, 0, pet->intimate, 100, 0, 1, mdb->jname );
 
 
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }

+ 17 - 0
src/map/script_constants.hpp

@@ -7105,6 +7105,23 @@
 	export_constant(PET_CATCH_UNIVERSAL);
 	export_constant(PET_CATCH_UNIVERSAL);
 	export_constant(PET_CATCH_UNIVERSAL_ITEM);
 	export_constant(PET_CATCH_UNIVERSAL_ITEM);
 
 
+	/* pet intimacy levels */
+	export_constant(PET_INTIMATE_NONE);
+	export_constant(PET_INTIMATE_AWKWARD);
+	export_constant(PET_INTIMATE_SHY);
+	export_constant(PET_INTIMATE_NEUTRAL);
+	export_constant(PET_INTIMATE_CORDIAL);
+	export_constant(PET_INTIMATE_LOYAL);
+	export_constant(PET_INTIMATE_MAX);
+
+	/* pet hunger levels */
+	export_constant(PET_HUNGRY_NONE);
+	export_constant(PET_HUNGRY_VERY_HUNGRY);
+	export_constant(PET_HUNGRY_HUNGRY);
+	export_constant(PET_HUNGRY_NEUTRAL);
+	export_constant(PET_HUNGRY_SATISFIED);
+	export_constant(PET_HUNGRY_STUFFED);
+
 	/* monster modes */
 	/* monster modes */
 	export_constant(MD_NONE);
 	export_constant(MD_NONE);
 	export_constant(MD_CANMOVE);
 	export_constant(MD_CANMOVE);

+ 1 - 1
src/map/skill.cpp

@@ -6514,7 +6514,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 		break;
 	case SA_TAMINGMONSTER:
 	case SA_TAMINGMONSTER:
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
-		if (sd && dstmd && pet_db(dstmd->mob_id)) {
+		if (sd && dstmd && pet_db.find(dstmd->mob_id)) {
 			pet_catch_process1(sd, dstmd->mob_id);
 			pet_catch_process1(sd, dstmd->mob_id);
 		}
 		}
 		break;
 		break;

+ 6 - 7
src/map/status.cpp

@@ -2969,7 +2969,7 @@ void status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
 		memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
 		memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
 		pd->status.mode = MD_CANMOVE; // Pets discard all modes, except walking
 		pd->status.mode = MD_CANMOVE; // Pets discard all modes, except walking
 		pd->status.class_ = CLASS_NORMAL;
 		pd->status.class_ = CLASS_NORMAL;
-		pd->status.speed = pd->get_pet_db()->speed;
+		pd->status.speed = pd->db->status.speed;
 
 
 		if(battle_config.pet_attack_support || battle_config.pet_damage_support) {
 		if(battle_config.pet_attack_support || battle_config.pet_damage_support) {
 			// Attack support requires the pet to be able to attack
 			// Attack support requires the pet to be able to attack
@@ -3823,11 +3823,10 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt)
 
 
 	if( sd->pd ) { // Pet Bonus
 	if( sd->pd ) { // Pet Bonus
 		struct pet_data *pd = sd->pd;
 		struct pet_data *pd = sd->pd;
-		s_pet_db *pet_db_ptr = pd->get_pet_db();
-
-		if( pet_db_ptr != nullptr && pet_db_ptr->pet_loyal_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
-			run_script(pd->get_pet_db()->pet_loyal_script,0,sd->bl.id,0);
-		if( pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
+		std::shared_ptr<s_pet_db> pet_db_ptr = pd->get_pet_db();
+		if( pet_db_ptr != nullptr && pet_db_ptr->pet_bonus_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
+			run_script(pet_db_ptr->pet_bonus_script,0,sd->bl.id,0);
+		if( pet_db_ptr != nullptr && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
 			pc_bonus(sd,pd->bonus->type, pd->bonus->val);
 			pc_bonus(sd,pd->bonus->type, pd->bonus->val);
 	}
 	}
 
 
@@ -10568,7 +10567,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 				if( pc_iswug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
 				if( pc_iswug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
 				if( pc_isridingwug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
 				if( pc_isridingwug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
 				if( pc_isfalcon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
 				if( pc_isfalcon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
-				if( sd->status.pet_id > 0 ) pet_menu(sd, 3);
+				if( sd->status.pet_id > 0 ) pet_return_egg(sd, sd->pd);
 				if( hom_is_active(sd->hd) ) hom_vaporize(sd, HOM_ST_ACTIVE);
 				if( hom_is_active(sd->hd) ) hom_vaporize(sd, HOM_ST_ACTIVE);
 				//if( sd->md ) mercenary_delete(sd->md,3); // Are Mercenaries removed? [aleos]
 				//if( sd->md ) mercenary_delete(sd->md,3); // Are Mercenaries removed? [aleos]
 			}
 			}

+ 4 - 46
src/map/unit.cpp

@@ -982,7 +982,7 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo
 		} else
 		} else
 			sd->areanpc_id=0;
 			sd->areanpc_id=0;
 
 
-		if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) {
+		if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > PET_INTIMATE_NONE ) {
 			// Check if pet needs to be teleported. [Skotlex]
 			// Check if pet needs to be teleported. [Skotlex]
 			int flag = 0;
 			int flag = 0;
 			struct block_list* pbl = &sd->pd->bl;
 			struct block_list* pbl = &sd->pd->bl;
@@ -3033,7 +3033,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 		case BL_PET: {
 		case BL_PET: {
 			struct pet_data *pd = (struct pet_data*)bl;
 			struct pet_data *pd = (struct pet_data*)bl;
 
 
-			if( pd->pet.intimate <= 0 && !(pd->master && !pd->master->state.active) ) {
+			if( pd->pet.intimate <= PET_INTIMATE_NONE && !(pd->master && !pd->master->state.active) ) {
 				// If logging out, this is deleted on unit_free
 				// If logging out, this is deleted on unit_free
 				clif_clearunit_area(bl,clrtype);
 				clif_clearunit_area(bl,clrtype);
 				map_delblock(bl);
 				map_delblock(bl);
@@ -3265,51 +3265,9 @@ int unit_free(struct block_list *bl, clr_type clrtype)
 			struct map_session_data *sd = pd->master;
 			struct map_session_data *sd = pd->master;
 
 
 			pet_hungry_timer_delete(pd);
 			pet_hungry_timer_delete(pd);
+			pet_clear_support_bonuses(sd);
 
 
-			if( pd->a_skill ) {
-				aFree(pd->a_skill);
-				pd->a_skill = NULL;
-			}
-
-			if( pd->s_skill ) {
-				if (pd->s_skill->timer != INVALID_TIMER) {
-					if (pd->s_skill->id)
-						delete_timer(pd->s_skill->timer, pet_skill_support_timer);
-					else
-						delete_timer(pd->s_skill->timer, pet_heal_timer);
-				}
-
-				aFree(pd->s_skill);
-				pd->s_skill = NULL;
-			}
-
-			if( pd->recovery ) {
-				if(pd->recovery->timer != INVALID_TIMER)
-					delete_timer(pd->recovery->timer, pet_recovery_timer);
-
-				aFree(pd->recovery);
-				pd->recovery = NULL;
-			}
-
-			if( pd->bonus ) {
-				if (pd->bonus->timer != INVALID_TIMER)
-					delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
-
-				aFree(pd->bonus);
-				pd->bonus = NULL;
-			}
-
-			if( pd->loot ) {
-				pet_lootitem_drop(pd,sd);
-
-				if (pd->loot->item)
-					aFree(pd->loot->item);
-
-				aFree (pd->loot);
-				pd->loot = NULL;
-			}
-
-			if( pd->pet.intimate > 0 )
+			if( pd->pet.intimate > PET_INTIMATE_NONE )
 				intif_save_petdata(pd->pet.account_id,&pd->pet);
 				intif_save_petdata(pd->pet.account_id,&pd->pet);
 			else { // Remove pet.
 			else { // Remove pet.
 				intif_delete_petdata(pd->pet.pet_id);
 				intif_delete_petdata(pd->pet.pet_id);

+ 340 - 1
src/tool/csv2yaml.cpp

@@ -24,6 +24,9 @@
 #include "../common/strlib.hpp"
 #include "../common/strlib.hpp"
 #include "../common/utilities.hpp"
 #include "../common/utilities.hpp"
 
 
+// Only for constants - do not use functions of it or linking will fail
+#include "../map/mob.hpp" // MAX_MVP_DROP and MAX_MOB_DROP
+
 using namespace rathena;
 using namespace rathena;
 
 
 #ifndef WIN32
 #ifndef WIN32
@@ -45,11 +48,16 @@ int getch( void ){
 
 
 // Forward declaration of conversion functions
 // Forward declaration of conversion functions
 static bool guild_read_guildskill_tree_db( char* split[], int columns, int current );
 static bool guild_read_guildskill_tree_db( char* split[], int columns, int current );
+static size_t pet_read_db( const char* file );
 
 
 // Constants for conversion
 // Constants for conversion
+std::unordered_map<uint16, std::string> aegis_itemnames;
+std::unordered_map<uint16, std::string> aegis_mobnames;
 std::unordered_map<uint16, std::string> aegis_skillnames;
 std::unordered_map<uint16, std::string> aegis_skillnames;
 
 
 // Forward declaration of constant loading functions
 // Forward declaration of constant loading functions
+static bool parse_item_constants( const char* path );
+static bool parse_mob_constants( char* split[], int columns, int current );
 static bool parse_skill_constants( char* split[], int columns, int current );
 static bool parse_skill_constants( char* split[], int columns, int current );
 
 
 bool fileExists( const std::string& path );
 bool fileExists( const std::string& path );
@@ -109,6 +117,10 @@ int do_init( int argc, char** argv ){
 	const std::string path_db_import = path_db + "/" + DBIMPORT;
 	const std::string path_db_import = path_db + "/" + DBIMPORT;
 
 
 	// Loads required conversion constants
 	// Loads required conversion constants
+	parse_item_constants( ( path_db_mode + "/item_db.txt" ).c_str() );
+	parse_item_constants( ( path_db_import + "/item_db.txt" ).c_str() );
+	sv_readdb( path_db_mode.c_str(), "mob_db.txt", ',', 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, -1, &parse_mob_constants, false );
+	sv_readdb( path_db_import.c_str(), "mob_db.txt", ',', 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, 31 + 2 * MAX_MVP_DROP + 2 * MAX_MOB_DROP, -1, &parse_mob_constants, false );
 	sv_readdb( path_db_mode.c_str(), "skill_db.txt", ',', 18, 18, -1, parse_skill_constants, false );
 	sv_readdb( path_db_mode.c_str(), "skill_db.txt", ',', 18, 18, -1, parse_skill_constants, false );
 	sv_readdb( path_db_import.c_str(), "skill_db.txt", ',', 18, 18, -1, parse_skill_constants, false );
 	sv_readdb( path_db_import.c_str(), "skill_db.txt", ',', 18, 18, -1, parse_skill_constants, false );
 
 
@@ -117,12 +129,23 @@ int do_init( int argc, char** argv ){
 		path_db_import
 		path_db_import
 	};
 	};
 
 
-	if( process( "GUILD_SKILL_TREE_DB", 1, guild_skill_tree_paths, "guild_skill_tree", []( const std::string& path, const std::string& name_ext ) -> bool {
+	if( !process( "GUILD_SKILL_TREE_DB", 1, guild_skill_tree_paths, "guild_skill_tree", []( const std::string& path, const std::string& name_ext ) -> bool {
 		return sv_readdb( path.c_str(), name_ext.c_str(), ',', 2 + MAX_GUILD_SKILL_REQUIRE * 2, 2 + MAX_GUILD_SKILL_REQUIRE * 2, -1, &guild_read_guildskill_tree_db, false );
 		return sv_readdb( path.c_str(), name_ext.c_str(), ',', 2 + MAX_GUILD_SKILL_REQUIRE * 2, 2 + MAX_GUILD_SKILL_REQUIRE * 2, -1, &guild_read_guildskill_tree_db, false );
 	} ) ){
 	} ) ){
 		return 0;
 		return 0;
 	}
 	}
 
 
+	std::vector<std::string> pet_paths = {
+		path_db_mode,
+		path_db_import
+	};
+
+	if( !process( "PET_DB", 1, pet_paths, "pet_db", []( const std::string& path, const std::string& name_ext ) -> bool {
+		return pet_read_db( ( path + name_ext ).c_str() );
+	} ) ){
+		return 0;
+	}
+
 	// TODO: add implementations ;-)
 	// TODO: add implementations ;-)
 
 
 	return 0;
 	return 0;
@@ -197,6 +220,141 @@ bool askConfirmation( const char* fmt, ... ){
 }
 }
 
 
 // Constant loading functions
 // Constant loading functions
+static bool parse_item_constants( const char* path ){
+	uint32 lines = 0, count = 0;
+	char line[1024];
+
+	FILE* fp;
+
+	fp = fopen(path, "r");
+	if (fp == NULL) {
+		ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
+		return false;
+	}
+
+	// process rows one by one
+	while (fgets(line, sizeof(line), fp))
+	{
+		char *str[32], *p;
+		int i;
+		lines++;
+		if (line[0] == '/' && line[1] == '/')
+			continue;
+		memset(str, 0, sizeof(str));
+
+		p = strstr(line, "//");
+
+		if (p != nullptr) {
+			*p = '\0';
+		}
+
+		p = line;
+		while (ISSPACE(*p))
+			++p;
+		if (*p == '\0')
+			continue;// empty line
+		for (i = 0; i < 19; ++i)
+		{
+			str[i] = p;
+			p = strchr(p, ',');
+			if (p == NULL)
+				break;// comma not found
+			*p = '\0';
+			++p;
+		}
+
+		if (p == NULL)
+		{
+			ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+			continue;
+		}
+
+		// Script
+		if (*p != '{')
+		{
+			ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+			continue;
+		}
+		str[19] = p + 1;
+		p = strstr(p + 1, "},");
+		if (p == NULL)
+		{
+			ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+			continue;
+		}
+		*p = '\0';
+		p += 2;
+
+		// OnEquip_Script
+		if (*p != '{')
+		{
+			ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+			continue;
+		}
+		str[20] = p + 1;
+		p = strstr(p + 1, "},");
+		if (p == NULL)
+		{
+			ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+			continue;
+		}
+		*p = '\0';
+		p += 2;
+
+		// OnUnequip_Script (last column)
+		if (*p != '{')
+		{
+			ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+			continue;
+		}
+		str[21] = p;
+		p = &str[21][strlen(str[21]) - 2];
+
+		if (*p != '}') {
+			/* lets count to ensure it's not something silly e.g. a extra space at line ending */
+			int lcurly = 0, rcurly = 0;
+
+			for (size_t v = 0; v < strlen(str[21]); v++) {
+				if (str[21][v] == '{')
+					lcurly++;
+				else if (str[21][v] == '}') {
+					rcurly++;
+					p = &str[21][v];
+				}
+			}
+
+			if (lcurly != rcurly) {
+				ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+				continue;
+			}
+		}
+		str[21] = str[21] + 1;  //skip the first left curly
+		*p = '\0';              //null the last right curly
+
+		uint16 item_id = atoi( str[0] );
+		char* name = trim( str[1] );
+
+		aegis_itemnames[item_id] = std::string(name);
+
+		count++;
+	}
+
+	fclose(fp);
+
+	ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, path);
+
+	return true;
+}
+
+static bool parse_mob_constants( char* split[], int columns, int current ){
+	uint16 mob_id = atoi( split[0] );
+	char* name = trim( split[1] );
+
+	aegis_mobnames[mob_id] = std::string( name );
+
+	return true;
+}
+
 static bool parse_skill_constants( char* split[], int columns, int current ){
 static bool parse_skill_constants( char* split[], int columns, int current ){
 	uint16 skill_id = atoi( split[0] );
 	uint16 skill_id = atoi( split[0] );
 	char* name = trim( split[16] );
 	char* name = trim( split[16] );
@@ -252,3 +410,184 @@ static bool guild_read_guildskill_tree_db( char* split[], int columns, int curre
 
 
 	return true;
 	return true;
 }
 }
+
+// Copied and adjusted from pet.cpp
+static size_t pet_read_db( const char* file ){
+	FILE* fp = fopen( file, "r" );
+
+	if( fp == nullptr ){
+		ShowError( "can't read %s\n", file );
+		return 0;
+	}
+
+	int lines = 0;
+	size_t entries = 0;
+	char line[1024];
+
+	while( fgets( line, sizeof(line), fp ) ) {
+		char *str[22], *p;
+		unsigned 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;
+		}
+
+		if( p == NULL ) {
+			ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines);
+			continue;
+		}
+
+		// Pet Script
+		if( *p != '{' ) {
+			ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
+			continue;
+		}
+
+		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;
+
+		// Equip Script
+		if( *p != '{' ) {
+			ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines);
+			continue;
+		}
+
+		str[21] = p;
+
+		uint16 mob_id = atoi( str[0] );
+		std::string* mob_name = util::umap_find( aegis_mobnames, mob_id );
+
+		if( mob_name == nullptr ){
+			ShowWarning( "pet_db reading: Invalid mob-class %hu, pet not read.\n", mob_id );
+			continue;
+		}
+
+		YAML::Node node;
+
+		node["Mob"] = *mob_name;
+
+		uint16 tame_item_id = (uint16)atoi( str[3] );
+
+		if( tame_item_id > 0 ){
+			std::string* tame_item_name = util::umap_find( aegis_itemnames, tame_item_id );
+
+			if( tame_item_name == nullptr ){
+				ShowError( "Item name for item id %hu is not known.\n", tame_item_id );
+				return false;
+			}
+
+			node["TameItem"] = *tame_item_name;
+		}
+
+		uint16 egg_item_id = (uint16)atoi( str[4] );
+
+		std::string* egg_item_name = util::umap_find( aegis_itemnames, egg_item_id );
+
+		if( egg_item_name == nullptr ){
+			ShowError( "Item name for item id %hu is not known.\n", egg_item_id );
+			return false;
+		}
+
+		node["EggItem"] = *egg_item_name;
+
+		uint16 equip_item_id = (uint16)atoi( str[5] );
+
+		if( equip_item_id > 0 ){
+			std::string* equip_item_name = util::umap_find( aegis_itemnames, equip_item_id );
+
+			if( equip_item_name == nullptr ){
+				ShowError( "Item name for item id %hu is not known.\n", equip_item_id );
+				return false;
+			}
+
+			node["EquipItem"] = *equip_item_name;
+		}
+
+		uint16 food_item_id = (uint16)atoi( str[6] );
+
+		if( food_item_id > 0 ){
+			std::string* food_item_name = util::umap_find( aegis_itemnames, food_item_id );
+
+			if( food_item_name == nullptr ){
+				ShowError( "Item name for item id %hu is not known.\n", food_item_id );
+				return false;
+			}
+
+			node["FoodItem"] = *food_item_name;
+		}
+
+		node["Fullness"] = atoi( str[7] );
+		// Default: 60
+		if( atoi( str[8] ) != 60 ){
+			node["HungryDelay"] = atoi( str[8] );
+		}
+		// Default: 250
+		if( atoi( str[11] ) != 250 ){
+			node["IntimacyStart"] = atoi( str[11] );
+		}
+		node["IntimacyFed"] = atoi( str[9] );
+		// Default: -100
+		if( atoi( str[10] ) != 100 ){
+			node["IntimacyOverfed"] = -atoi( str[10] );
+		}
+		// pet_hungry_friendly_decrease battle_conf
+		//node["IntimacyHungry"] = -5;
+		// Default: -20
+		if( atoi( str[12] ) != 20 ){
+			node["IntimacyOwnerDie"] = -atoi( str[12] );
+		}
+		node["CaptureRate"] = atoi( str[13] );
+		// Default: true
+		if( atoi( str[15] ) == 0 ){
+			node["SpecialPerformance"] = false;
+		}
+		node["AttackRate"] = atoi( str[17] );
+		node["RetaliateRate"] = atoi( str[18] );
+		node["ChangeTargetRate"] = atoi( str[19] );
+
+		if( *str[21] ){
+			node["Script"] = str[21];
+		}
+
+		if( *str[20] ){
+			node["SupportScript"] = str[20];
+		}
+
+		body[counter++] = node;
+
+		entries++;
+	}
+
+	fclose(fp);
+	ShowStatus("Done reading '" CL_WHITE "%d" CL_RESET "' pets in '" CL_WHITE "%s" CL_RESET "'.\n", entries, file );
+
+	return entries;
+}

Some files were not shown because too many files changed in this diff