summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md41
-rw-r--r--db/constants.conf26
-rw-r--r--db/mob_db2.conf6
-rw-r--r--db/mob_skill_db2.conf8
-rw-r--r--db/pet_db2.conf41
-rw-r--r--db/pre-re/mob_db.conf4
-rw-r--r--db/pre-re/mob_skill_db.conf8
-rw-r--r--db/re/item_combo_db.conf8
-rw-r--r--db/re/item_db.conf339
-rw-r--r--db/re/mob_db.conf902
-rw-r--r--db/re/mob_skill_db.conf73
-rw-r--r--db/re/pet_db.conf1542
-rw-r--r--doc/constants.md91
-rw-r--r--doc/mob_skill_db.md223
-rw-r--r--doc/script_commands.txt7
-rw-r--r--sql-files/item_db_re.sql50
-rw-r--r--sql-files/main.sql7
-rw-r--r--sql-files/mob_db_re.sql31
-rw-r--r--sql-files/mob_skill_db_re.sql8
-rw-r--r--sql-files/upgrades/2020-05-01--04-44.sql25
-rw-r--r--sql-files/upgrades/index.txt1
-rw-r--r--src/char/char.c64
-rw-r--r--src/char/inter.c8
-rw-r--r--src/char/mapif.c7
-rw-r--r--src/common/cbasetypes.h2
-rw-r--r--src/common/mmo.h5
-rw-r--r--src/login/account.c15
-rw-r--r--src/login/login.c8
-rw-r--r--src/map/atcommand.c49
-rw-r--r--src/map/battle.c15
-rw-r--r--src/map/clif.c79
-rw-r--r--src/map/clif.h11
-rw-r--r--src/map/intif.c14
-rw-r--r--src/map/map.c11
-rw-r--r--src/map/map.h5
-rw-r--r--src/map/mapreg_sql.c10
-rw-r--r--src/map/mob.c683
-rw-r--r--src/map/mob.h9
-rw-r--r--src/map/npc_chat.c3
-rw-r--r--src/map/packets.h5
-rw-r--r--src/map/packets_keys_main.h5
-rw-r--r--src/map/packets_keys_zero.h5
-rw-r--r--src/map/packets_shuffle_main.h5
-rw-r--r--src/map/packets_shuffle_zero.h5
-rw-r--r--src/map/packets_struct.h36
-rw-r--r--src/map/pc.c164
-rw-r--r--src/map/pc.h11
-rw-r--r--src/map/pet.c20
-rw-r--r--src/map/script.c52
-rw-r--r--src/map/script.h1
-rw-r--r--src/map/skill.c119
-rw-r--r--src/map/skill.h1
-rw-r--r--src/map/status.c5
-rw-r--r--src/map/unit.c4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc32
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc40
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc10
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc284
58 files changed, 4404 insertions, 839 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 97cbf5bfc..3bcb8b3f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,44 @@ and this project does not adhere to [Semantic Versioning](http://semver.org/spec
If you are reading this in a text editor, simply ignore this section
-->
+## [v2020.05.03] `May 03 2020`
+
+### Added
+
+- Added the new pets (including the jRO exclusive ones) and their related items/monsters to the renewal database. (#2689)
+- Added constants `ALL_MOBS_NONBOSS`, `ALL_MOBS_BOSS`, `ALL_MOBS` for the special mob IDs for global skill assignment in the mob skill database. (part of #2691)
+- Added support for `__func__` on Windows, since it's now available in every supported compiler. (part of #2691)
+- Added documentation for the mob skill database. See `doc/mob_skill_db.conf`. (#2680)
+- Added missing functions for the name ack packets for `BL_ITEM` and `BL_SKILL`. (part of #2695)
+- Added/updated packets and encryption keys for clients up to 2020-04-14. (#2695)
+- Added support for packets `ZC_LAPINEUPGRADE_OPEN`, `CZ_LAPINEUPGRADE_CLOSE` and `ZC_LAPINEUPGRADE_RESULT` and a placeholder for `CZ_LAPINEUPGRADE_MAKE_ITEM`. (part of #2695)
+- Added a new cell type `cell_noskill`, to block skill usage. (#2188)
+
+### Changed
+
+- Removed warning messages about missing elements in the mob db, since it's an optional field. (part of #2689)
+- Updated the renewal pet database with the correct values and bonuses. (part of #2689, issue #2435)
+- Changed `mob_getfriendstatus()` to consider character as friends of their support monsters, for consistency with `mob_getfriendhprate()`. (part of #2691)
+- Changed `MSC_AFTERSKILL` to trigger on any skill when its `ConditionData` is 0, for consistency with `MSC_SKILLUSED`. (part of #2691)
+- Improved data validation and error reporting in the mob skill database. (part of #2691)
+- Changed return values of `mob_skill_use()` and `mobskill_event()`. Any third party code that uses them needs to be updated. (part of #2691)
+- Changed the battle configuration flag `manner_system` to be applied immediately to any existing `SC_NOCHAT`. (#2696, issue #227)
+- Changed the `atcommand()` command to ignore `PCBLOCK_COMMANDS`. (#2062)
+
+### Fixed
+
+- Fixed `SC_AUTOTRADE`, `SC_KSPROTECTED` and `SC_NO_SWITCH_EQUIP` incorrectly recognized as unknown status changes. (#2686, issue #2684)
+- Prevented `SC_KSPROTECTED` from starting on dead monsters. (part of #2686)
+- Fixed character unhiding while disguised or when using `@option 0`. (#2687, issues #1556 and #2104)
+- Fixed an incorrect order of operations causing results too small in various calculations related to free cell search, mob skill chances/delays, exp penalty, pet hunger and friendly rates, cast duration. (#2690)
+- Fixed errors caused by `pet_ai_sub_hard()` called for monsters that haven't been added to a map yet. (#2693)
+- Fixed a wrong packet error displayed when using an incorrect password for the char-login connection. (part of #2695)
+- Fixed a security check in the lapine ack packet handler. (part of #2695)
+- Fixed some incorrect assumptions about the skill index values, causing the Bard/Dancer soul link to grant the wrong skills. (#2710, issue #2670)
+- Fixed some conditions that could cause a skill to be attempted to save to the database with a negative skill level, resulting in query errors and data loss. (part of #2710)
+- Fixed the skill type of `RK_DRAGONBREATH` and `RK_DRAGONBREATH_WATER` to be `BF_WEAPON` and support the `bLongAtkRate` bonus. (#1304)
+- Fixed `SC_TELEKINESIS_INTENSE` to add percent MATK instead of fixed MATK. (part of #1304)
+
## [v2020.04.05] `April 05 2020` `PATCH 1`
### Fixed
@@ -1322,7 +1360,8 @@ If you are reading this in a text editor, simply ignore this section
- New versioning scheme and project changelogs/release notes (#1853)
[Unreleased]: https://github.com/HerculesWS/Hercules/compare/stable...master
-[v2020.04.05]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05...v2020.04.05+1
+[v2020.05.03]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05+1...v2020.05.03
+[v2020.04.05+1]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05...v2020.04.05+1
[v2020.04.05]: https://github.com/HerculesWS/Hercules/compare/v2020.03.08+2...v2020.04.05
[v2020.03.08+2]: https://github.com/HerculesWS/Hercules/compare/v2020.03.08+1...v2020.03.08+2
[v2020.03.08+1]: https://github.com/HerculesWS/Hercules/compare/v2020.03.08...v2020.03.08+1
diff --git a/db/constants.conf b/db/constants.conf
index 9b11a43e9..6f8030a45 100644
--- a/db/constants.conf
+++ b/db/constants.conf
@@ -428,17 +428,20 @@ constants_db: {
mf_nogstorage: 60
comment__: "Cell Properties"
- cell_walkable: 0
- cell_shootable: 1
- cell_water: 2
- cell_npc: 3
- cell_basilica: 4
- cell_landprotector: 5
- cell_novending: 6
- cell_nochat: 7
+ cell_walkable: 0
+ cell_shootable: 1
+ cell_water: 2
+ cell_npc: 3
+ cell_basilica: 4
+ cell_landprotector: 5
+ cell_novending: 6
+ cell_nochat: 7
+ cell_icewall: 8
+ cell_noicewall: 9
+ cell_noskill: 10
comment__: "Cell checks"
- //cell_gettype: 0
+ cell_gettype: 0
cell_chkwall: 1
cell_chkwater: 2
cell_chkcliff: 3
@@ -446,12 +449,15 @@ constants_db: {
cell_chkreach: 5
cell_chknopass: 6
cell_chknoreach: 7
- //cell_chkstack: 8
+ cell_chkstack: 8
cell_chknpc: 9
cell_chkbasilica: 10
cell_chklandprotector: 11
cell_chknovending: 12
cell_chknochat: 13
+ cell_chkicewall: 14
+ cell_chknoicewall: 15
+ cell_chknoskill: 16
comment__: "Bonuses / Parameter IDs"
bMaxHP: 6
diff --git a/db/mob_db2.conf b/db/mob_db2.conf
index 8cc1a1459..ef3b631f2 100644
--- a/db/mob_db2.conf
+++ b/db/mob_db2.conf
@@ -57,9 +57,9 @@ mob_db: (
}
ViewRange: view range (int, defaults to 1)
ChaseRange: chase range (int, defaults to 1)
- Size: size (int, defaults to 1)
- Race: race (int, defaults to 0)
- Element: (type, level)
+ Size: size (string, defaults to "Size_Small")
+ Race: race (string, defaults to "RC_Formless")
+ Element: (type, level) (string/int, defaults to "Ele_Neutral"/1)
Mode: {
CanMove: true/false (bool, defaults to false)
Looter: true/false (bool, defaults to false)
diff --git a/db/mob_skill_db2.conf b/db/mob_skill_db2.conf
index 6a732ff2d..de4b014fa 100644
--- a/db/mob_skill_db2.conf
+++ b/db/mob_skill_db2.conf
@@ -36,20 +36,20 @@ mob_skill_db:(
<Skill_Constant>: {
ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob.
SkillLevel: (int, defaults to 1)
- SkillState: (int, defaults to 0)
- SkillTarget: (int, defaults to 0)
+ SkillState: (string, defaults to "MSS_ANY")
+ SkillTarget: (string, defaults to "MST_TARGET")
Rate: (int, defaults to 1)
CastTime: (int, defaults to 0)
Delay: (int, defaults to 0)
Cancelable: (boolean, defaults to false)
- CastCondition: (int, defaults to 0)
+ CastCondition: (string, defaults to "MSC_ALWAYS")
ConditionData: (int, defaults to 0)
val0: (int, defaults to 0)
val1: (int, defaults to 0)
val2: (int, defaults to 0)
val3: (int, defaults to 0)
val4: (int, defaults to 0)
- Emotion: (int, defaults to 0)
+ Emotion: (int, defaults to -1)
ChatMsgID: (int, defaults to 0)
}
}
diff --git a/db/pet_db2.conf b/db/pet_db2.conf
index d6862da32..235e41c0b 100644
--- a/db/pet_db2.conf
+++ b/db/pet_db2.conf
@@ -34,30 +34,39 @@ pet_db:(
{
// ================ Mandatory fields ==============================
Id: ID (int)
- SpriteName: "Sprite_Name" (string)
Name: "Pet Name" (string)
+ EggItem: "Egg Item Constant" (string)
// ================ Optional fields ===============================
- TamingItem: Taming Item (string, defaults to 0)
- EggItem: Egg Id (string, defaults to 0)
- AccessoryItem: Equipment Id (string, defaults to 0)
- FoodItem: Food Id (string, defaults to 0)
- FoodEffectiveness: hunger points (int, defaults to 0)
- HungerDelay: hunger time (int, defaults to 0)
+ TamingItem: "Taming Item Constant" (string, defaults to 0)
+ FoodItem: "Food Item Constant" (string, defaults to "Pet_Food" (ID=537))
+ AccessoryItem: "Equipment Item Constant" (string, defaults to 0)
+ FoodEffectiveness: hunger points (int, defaults to 80)
+ HungerDelay: hunger time (int, defaults to 60)
+ HungerDecrement: hunger points (int, defaults to 1)
Intimacy: {
- Initial: start intimacy (int, defaults to 0)
- FeedIncrement: feeding intimacy (int, defaults to 0)
- OverFeedDecrement: overfeeding intimacy (int, defaults to 0)
- OwnerDeathDecrement: owner die intimacy (int, defaults to 0)
+ Initial: start intimacy (int, defaults to 250)
+ FeedIncrement: feeding intimacy (int, defaults to 10)
+ OverFeedDecrement: overfeeding intimacy (int, defaults to 100)
+ OwnerDeathDecrement: owner die intimacy (int, defaults to 20)
+ StarvingDelay: starving time (int, defaults to 20)
+ StarvingDecrement: starving intimacy (int, defaults to 20)
}
- CaptureRate: capture rate (int, defaults to 0)
- Speed: speed (int, defaults to 0)
+ CaptureRate: capture rate (int, defaults to 1000)
+ Speed: speed (int, defaults to 150)
SpecialPerformance: true/false (boolean, defaults to false)
TalkWithEmotes: convert talk (boolean, defaults to false)
- AttackRate: attack rate (int, defaults to 0)
- DefendRate: Defence attack (int, defaults to 0)
- ChangeTargetRate: change target (int, defaults to 0)
+ AttackRate: attack rate (int, defaults to 300)
+ DefendRate: Defence attack (int, defaults to 300)
+ ChangeTargetRate: change target (int, defaults to 800)
+ AutoFeed: true/false (boolean, defaults to false)
PetScript: <" Pet Script (can also be multi-line) ">
EquipScript: <" Equip Script (can also be multi-line) ">
+ Evolve: {
+ EggID: { (string, Evolved Pet EggID)
+ Name: Amount (items required to perform evolution)
+ ...
+ }
+ }
},
**************************************************************************/
// entries in this file will override the ones in /(pre-)re/pet_db.conf
diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf
index 78e255f36..92fd149f3 100644
--- a/db/pre-re/mob_db.conf
+++ b/db/pre-re/mob_db.conf
@@ -57,9 +57,9 @@ mob_db: (
}
ViewRange: view range (int, defaults to 1)
ChaseRange: chase range (int, defaults to 1)
- Size: size (string, defaults to "Size_Medium")
+ Size: size (string, defaults to "Size_Small")
Race: race (string, defaults to "RC_Formless")
- Element: (type, level)
+ Element: (type, level) (string/int, defaults to "Ele_Neutral"/1)
Mode: {
CanMove: true/false (bool, defaults to false)
Looter: true/false (bool, defaults to false)
diff --git a/db/pre-re/mob_skill_db.conf b/db/pre-re/mob_skill_db.conf
index 11af05e98..b6e3af07f 100644
--- a/db/pre-re/mob_skill_db.conf
+++ b/db/pre-re/mob_skill_db.conf
@@ -36,20 +36,20 @@ mob_skill_db:(
<Skill_Constant>: {
ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob.
SkillLevel: (int, defaults to 1)
- SkillState: (int, defaults to 0)
- SkillTarget: (int, defaults to 0)
+ SkillState: (string, defaults to "MSS_ANY")
+ SkillTarget: (string, defaults to "MST_TARGET")
Rate: (int, defaults to 1)
CastTime: (int, defaults to 0)
Delay: (int, defaults to 0)
Cancelable: (boolean, defaults to false)
- CastCondition: (int, defaults to 0)
+ CastCondition: (string, defaults to "MSC_ALWAYS")
ConditionData: (int, defaults to 0)
val0: (int, defaults to 0)
val1: (int, defaults to 0)
val2: (int, defaults to 0)
val3: (int, defaults to 0)
val4: (int, defaults to 0)
- Emotion: (int, defaults to 0)
+ Emotion: (int, defaults to -1)
ChatMsgID: (int, defaults to 0)
}
}
diff --git a/db/re/item_combo_db.conf b/db/re/item_combo_db.conf
index 31630546a..668b4bac0 100644
--- a/db/re/item_combo_db.conf
+++ b/db/re/item_combo_db.conf
@@ -3221,4 +3221,12 @@ combo_db: (
bonus2 bVariableCastrate, "WL_JACKFROST", -.@r;
">
},
+{
+ Items: ["Rigid_Nightmare_Terror_Card", "Nightmare_Terror_Card"]
+ Script: <" bonus(bAtkRate, 10); ">
+},
+{
+ Items: ["Rigid_Nightmare_Terror_Card", "Nightmare_Card"]
+ Script: <" bonus(bMaxSPrate, 10); ">
+},
)
diff --git a/db/re/item_db.conf b/db/re/item_db.conf
index ddc38dd15..408fb3ef8 100644
--- a/db/re/item_db.conf
+++ b/db/re/item_db.conf
@@ -70646,6 +70646,8 @@ item_db: (
Id: 6221
AegisName: "Mystic_Leaf_Cat_Ball"
Name: "Mystic Hydra Ball"
+ Type: "IT_PETEGG"
+ Buy: 20
},
{
Id: 6222
@@ -74426,6 +74428,18 @@ item_db: (
Weight: 10
},
{
+ Id: 6669
+ AegisName: "Emerald_Leaf"
+ Name: "Emerald Leaf"
+ Weight: 10
+},
+{
+ Id: 6670
+ AegisName: "Log_"
+ Name: "Tree Log"
+ Weight: 10
+},
+{
Id: 6671
AegisName: "Geffen_Magic_Coin"
Name: "Geffen Magic Tournament Coin"
@@ -74540,6 +74554,30 @@ item_db: (
Weight: 10
},
{
+ Id: 6762
+ AegisName: "Banana_Can"
+ Name: "Banana Can"
+ Weight: 10
+},
+{
+ Id: 6763
+ AegisName: "Spicy_Rice_Cake"
+ Name: "Spicy Rice Cake"
+ Weight: 10
+},
+{
+ Id: 6764
+ AegisName: "Hot_Dog"
+ Name: "Hot Dog"
+ Weight: 10
+},
+{
+ Id: 6765
+ AegisName: "Ferris_Wheel_Biscuit"
+ Name: "Ferris Wheel Biscuit"
+ Weight: 10
+},
+{
Id: 6804
AegisName: "ORGANIC_PUMPKIN"
Name: "Organic Pumpkin"
@@ -83636,6 +83674,48 @@ item_db: (
Buy: 20
},
{
+ Id: 9063
+ AegisName: "Woodie_Egg"
+ Name: "Woodie Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9064
+ AegisName: "Elephant_Egg"
+ Name: "Elephant Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9065
+ AegisName: "Gorilla_Egg"
+ Name: "Gorilla Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9066
+ AegisName: "Lion_Egg"
+ Name: "Lion Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9067
+ AegisName: "Rhino_Egg"
+ Name: "Rhino Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9068
+ AegisName: "Blue_Unicorn_Egg"
+ Name: "Blue Unicorn Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
Id: 9069
AegisName: "Mastering_Egg"
Name: "Mastering Egg"
@@ -83657,6 +83737,55 @@ item_db: (
Buy: 20
},
{
+ Id: 9074
+ AegisName: "Rubylit_Egg"
+ Name: "Rubylit Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9075
+ AegisName: "Sapphilit_Egg"
+ Name: "Sapphilit Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9076
+ AegisName: "Emelit_Egg"
+ Name: "Emelit Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9077
+ AegisName: "Topalit_Egg"
+ Name: "Topalit Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9078
+ AegisName: "Amelit_Egg"
+ Name: "Amelit Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9079
+ AegisName: "Mythlit_Egg"
+ Name: "Mythlit Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9080
+ AegisName: "Tamadora_Egg"
+ Name: "Tamadora Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
Id: 9087
AegisName: "High_Orc_Egg"
Name: "High Orc Egg"
@@ -83844,6 +83973,76 @@ item_db: (
Name: "Ein_Ddbox"
},
{
+ Id: 9115
+ AegisName: "Bacsojin2_Egg_"
+ Name: "Bacsojin Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9116
+ AegisName: "Rigid_Nightmare_Terror_Egg"
+ Name: "Rigid Nightmare Terror Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9117
+ AegisName: "Contaminated_Wanderer_Egg"
+ Name: "Contaminated Wanderer Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9118
+ AegisName: "Aliot_Egg"
+ Name: "Aliot Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9119
+ AegisName: "Alicel_Egg"
+ Name: "Alicel Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9120
+ AegisName: "Aliza_Egg"
+ Name: "Aliza Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9121
+ AegisName: "Orc_Hero_Egg_"
+ Name: "Orc Hero Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9122
+ AegisName: "Gloom_Under_Night_Egg"
+ Name: "Gloom Under Night Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9123
+ AegisName: "Child_Admin_Beta_Egg"
+ Name: "Child Admin Beta Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9124
+ AegisName: "Child_Admin_Alpha_Egg"
+ Name: "Child Admin Alpha Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
Id: 9523
AegisName: "Metal_Rifine_Ticket"
Name: "Metal_Rifine_Ticket"
@@ -84139,9 +84338,32 @@ item_db: (
Buy: 20
},
{
+ Id: 10040
+ AegisName: "Red_Bell_Necklace"
+ Name: "Red Bell Necklace"
+ Type: "IT_PETARMOR"
+ Buy: 20
+},
+{
Id: 10042
AegisName: "Dark_Mane"
Name: "Dark_Mane"
+ Type: "IT_PETARMOR"
+ Buy: 20
+},
+{
+ Id: 10043
+ AegisName: "Little_Headdress_Beta"
+ Name: "Little Headdress Beta"
+ Type: "IT_PETARMOR"
+ Buy: 20
+},
+{
+ Id: 10044
+ AegisName: "Little_Headdress_Alpha"
+ Name: "Little Headdress Alpha"
+ Type: "IT_PETARMOR"
+ Buy: 20
},
//== Misc "Etc" Books ======================================
@@ -85340,6 +85562,14 @@ item_db: (
Script: <" itemheal rand(10,40),0; ">
},
{
+ Id: 11605
+ AegisName: "Cookie_Bat"
+ Name: "Cookie Bat"
+ Type: "IT_HEALING"
+ Weight: 50
+ Script: <" itemheal(rand(50, 100), 0); ">
+},
+{
Id: 11607
AegisName: "Crepe"
Name: "Crepe"
@@ -85375,6 +85605,13 @@ item_db: (
Name: "Sweet_Potato_"
},
{
+ Id: 11616
+ AegisName: "Yummy_Meat"
+ Name: "Yummy Meat"
+ Type: "IT_HEALING"
+ Weight: 50
+},
+{
Id: 11620
AegisName: "Bearopy"
Name: "Bearopy"
@@ -148791,6 +149028,36 @@ item_db: (
Script: <" Zeny += rand(500, 550); ">
},
{
+ Id: 23187
+ AegisName: "Sap_Jelly"
+ Name: "Sap Jelly"
+ Type: "IT_USABLE"
+ Nouse: {
+ sitting: true
+ }
+ Script: <" pet(NINE_TAIL); ">
+},
+{
+ Id: 23188
+ AegisName: "Unprocessed_Parts"
+ Name: "Unprocessed Parts"
+ Type: "IT_USABLE"
+ Nouse: {
+ sitting: true
+ }
+ Script: <" pet(GREMLIN); ">
+},
+{
+ Id: 23189
+ AegisName: "SmallDoll_Needle"
+ Name: "Small Doll Needle"
+ Type: "IT_USABLE"
+ Nouse: {
+ sitting: true
+ }
+ Script: <" pet(TEDDY_BEAR); ">
+},
+{
Id: 23242
AegisName: "Fried_Chicken"
Name: "Fried_Chicken"
@@ -153738,6 +154005,24 @@ item_db: (
Weight: 1200
},
{
+ Id: 25231
+ AegisName: "Suspicious_Bottle"
+ Name: "Suspicious Bottle"
+ Weight: 10
+},
+{
+ Id: 25232
+ AegisName: "Cheap_Lubricant"
+ Name: "Cheap Lubricant"
+ Weight: 10
+},
+{
+ Id: 25233
+ AegisName: "Cotton_Tufts"
+ Name: "Cotton Tufts"
+ Weight: 10
+},
+{
Id: 25258
AegisName: "BrokenArrow"
Name: "BrokenArrow"
@@ -153783,6 +154068,12 @@ item_db: (
Name: "Mightysoul_Essence"
},
{
+ Id: 25377
+ AegisName: "Luxurious_Pet_Food"
+ Name: "Luxurious Pet Food"
+ Weight: 1
+},
+{
Id: 25390
AegisName: "Captured_Savage"
Name: "Captured_Savage"
@@ -154578,6 +154869,29 @@ item_db: (
bonus2(bSkillAtk, RL_HAMMER_OF_GOD, getrefine() >= 10 ? 60 : 30);
">
},
+{
+ Id: 27352
+ AegisName: "Rigid_Nightmare_Terror_Card"
+ Name: "Rigid Nightmare Terror Card"
+ Type: "IT_CARD"
+ Buy: 20
+ Weight: 10
+ Loc: "EQP_SHOES"
+ Script: <" bonus(bMaxSPrate, 5); ">
+},
+{
+ Id: 27361
+ AegisName: "Contaminated_Wanderer_Card"
+ Name: "Contaminated Wanderer Card"
+ Type: "IT_CARD"
+ Buy: 20
+ Weight: 10
+ Loc: "EQP_WEAPON"
+ Script: <"
+ bonus2(bAddSize,Size_Medium, 30);
+ bonus2(bAddSize,Size_Large, 30);
+ ">
+},
//== New Katars ============================================
{
@@ -156447,6 +156761,19 @@ item_db: (
Name: "Shinee_Opal"
},
{
+ Id: 31022
+ AegisName: "Abandoned_Teddy_Bear_Card"
+ Name: "Abandoned Teddy Bear Card"
+ Type: "IT_CARD"
+ Buy: 20
+ Weight: 10
+ Loc: "EQP_SHOES"
+ Script: <"
+ bonus(bMaxSPrate, 20);
+ bonus2(bAddEff2, Eff_Curse, 20);
+ ">
+},
+{
Id: 31172
AegisName: "Roast_Memory"
Name: "Roast_Memory"
@@ -157912,6 +158239,12 @@ item_db: (
Name: "ArchbishopStone_Robe2"
},
{
+ Id: 1000103
+ AegisName: "Barmil_Ticket"
+ Name: "Barmil Ticket"
+ Weight: 10
+},
+{
Id: 1000213
AegisName: "WarlockStone_Robe2"
Name: "WarlockStone_Robe2"
@@ -157971,4 +158304,10 @@ item_db: (
AegisName: "AssacrossStone_Bottom2"
Name: "AssacrossStone_Bottom2"
},
+{
+ Id: 1000227
+ AegisName: "Cloud_Cotton"
+ Name: "Cloud Cotton"
+ Weight: 10
+},
)
diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf
index 492b75a04..99518c461 100644
--- a/db/re/mob_db.conf
+++ b/db/re/mob_db.conf
@@ -57,9 +57,9 @@ mob_db: (
}
ViewRange: view range (int, defaults to 1)
ChaseRange: chase range (int, defaults to 1)
- Size: size (string, defaults to "Size_Medium")
+ Size: size (string, defaults to "Size_Small")
Race: race (string, defaults to "RC_Formless")
- Element: (type, level)
+ Element: (type, level) (string/int, defaults to "Ele_Neutral"/1)
Mode: {
CanMove: true/false (bool, defaults to false)
Looter: true/false (bool, defaults to false)
@@ -83701,7 +83701,46 @@ mob_db: (
DamageMotion: 360
},
//2962,E_DEVILING
-//2963,WOODIE
+{
+ Id: 2963
+ SpriteName: "WOODIE"
+ Name: "Woodie"
+ Hp: 60
+ Exp: 18
+ JExp: 10
+ Attack: [13, 3]
+ Def: 2
+ Mdef: 5
+ Stats: {
+ Str: 6
+ Agi: 1
+ Vit: 1
+ Dex: 6
+ Luk: 5
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Race: "RC_Plant"
+ Element: ("Ele_Water", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 400
+ AttackDelay: 1872
+ AttackMotion: 672
+ DamageMotion: 480
+ Drops: {
+ Solid_Twig: 2000
+ Resin: 2000
+ Log: 2000
+ Wooden_Block: 2000
+ Oridecon_Stone: 200
+ Log_: 5000
+ Woodie_Card: 300
+ }
+},
//2964,EXP_1000
//2965,TW_APOCALIPS_H
//2966,TW_B_EREMES
@@ -83733,7 +83772,53 @@ mob_db: (
//2992,XM_LUDE
//2993,XM_HYLOZOIST
//2994,XM_MARIONETTE
-//2995,XM_TEDDY_BEAR
+{
+ Id: 2995
+ SpriteName: "XM_TEDDY_BEAR"
+ Name: "Abandoned Teddy Bear"
+ Lv: 148
+ Hp: 180000
+ Exp: 6666
+ JExp: 7332
+ Attack: [1347, 577]
+ Def: 106
+ Mdef: 44
+ Stats: {
+ Str: 44
+ Agi: 166
+ Vit: 44
+ Int: 44
+ Dex: 166
+ Luk: 44
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Demon"
+ Element: ("Ele_Undead", 3)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ CanAttack: true
+ Detector: true
+ CastSensorChase: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 512
+ AttackMotion: 780
+ DamageMotion: 504
+ Drops: {
+ Screw: 1900
+ Oridecon_Hammer: 150
+ Str_Dish09: 100
+ Runstone_Quality: 1000
+ Runstone_Rare: 100
+ Abandoned_Teddy_Bear_Card: 1
+ }
+},
{
Id: 2996
SpriteName: "XM_CELINE_KIMI"
@@ -84009,6 +84094,142 @@ mob_db: (
//3154,RECON_ROBOT
//3155,REPAIR_ROBOT
//3156,EXPLORATION_ROVER
+{
+ Id: 3162
+ SpriteName: "ELEPHANT"
+ Name: "Elephant"
+ Lv: 48
+ Hp: 1080
+ Exp: 184
+ JExp: 207
+ Attack: [184, 48]
+ Def: 70
+ Mdef: 30
+ Stats: {
+ Str: 40
+ Agi: 45
+ Vit: 32
+ Int: 19
+ Dex: 42
+ Luk: 20
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Brute"
+ Element: ("Ele_Fire", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 1028
+ AttackMotion: 528
+ DamageMotion: 360
+},
+{
+ Id: 3163
+ SpriteName: "GORILLA"
+ Name: "Gorilla"
+ Lv: 48
+ Hp: 1080
+ Exp: 184
+ JExp: 207
+ Attack: [184, 48]
+ Def: 70
+ Mdef: 30
+ Stats: {
+ Str: 40
+ Agi: 45
+ Vit: 32
+ Int: 19
+ Dex: 42
+ Luk: 20
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Brute"
+ Element: ("Ele_Fire", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 190
+ AttackDelay: 1028
+ AttackMotion: 528
+ DamageMotion: 360
+},
+{
+ Id: 3164
+ SpriteName: "LION"
+ Name: "Lion"
+ Lv: 48
+ Hp: 1080
+ Exp: 184
+ JExp: 207
+ Attack: [184, 48]
+ Def: 70
+ Mdef: 30
+ Stats: {
+ Str: 40
+ Agi: 45
+ Vit: 32
+ Int: 19
+ Dex: 42
+ Luk: 20
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Brute"
+ Element: ("Ele_Fire", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 1028
+ AttackMotion: 528
+ DamageMotion: 360
+},
+{
+ Id: 3165
+ SpriteName: "RHINO"
+ Name: "Rhino"
+ Lv: 48
+ Hp: 1080
+ Exp: 184
+ JExp: 207
+ Attack: [184, 48]
+ Def: 70
+ Mdef: 30
+ Stats: {
+ Str: 40
+ Agi: 45
+ Vit: 32
+ Int: 19
+ Dex: 42
+ Luk: 20
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Brute"
+ Element: ("Ele_Fire", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 1028
+ AttackMotion: 528
+ DamageMotion: 360
+},
//3166,M_E_DEVILING
{
Id: 3169
@@ -84387,7 +84608,38 @@ mob_db: (
DamageMotion: 480
MvpExp: 0
},*/
-
+{
+ Id: 3261
+ SpriteName: "BLUE_UNICORN"
+ Name: "Blue Unicorn"
+ Lv: 30
+ Hp: 20
+ Exp: 99
+ JExp: 112
+ Attack: [106, 29]
+ Def: 36
+ Mdef: 17
+ Stats: {
+ Str: 17
+ Agi: 26
+ Vit: 20
+ Int: 18
+ Dex: 36
+ Luk: 5
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Race: "RC_Plant"
+ Element: ("Ele_Poison", 1)
+ Mode: {
+ CanMove: true
+ CanAttack: true
+ }
+ MoveSpeed: 300
+ AttackDelay: 1672
+ AttackMotion: 672
+ DamageMotion: 480
+},
//3295,G_MOBSTER
//3296,HIDDEN_TEST
//3297,PAD_LEVIATHAN
@@ -84398,7 +84650,11 @@ mob_db: (
//3303,PAD_HELHEIM
//3304,PAD_MUSPELHEIM
//3305,PAD_ZAEROG
-//3306,PAD_TAMADORA
+{/* jRO exclusive pet. No stats required. */
+ Id: 3306
+ SpriteName: "PAD_TAMADORA"
+ Name: "Tamadora"
+},
//3307,PAD_TAMADORABABY
//3308,ROC_EMPELIUM
//3309,ROC_OBJ_A
@@ -84409,11 +84665,31 @@ mob_db: (
//3314,SMOKIE_THIEF
//3315,PAD_KINGGOLD
//3316,PAD_KINGMETAL
-//3317,PAD_RUBYLIT
-//3318,PAD_SAPPHILIT
-//3319,PAD_EMELIT
-//3320,PAD_TOPALIT
-//3321,PAD_AMELIT
+{/* jRO exclusive pet. No stats required. */
+ Id: 3317
+ SpriteName: "PAD_RUBYLIT"
+ Name: "Rubylit"
+},
+{/* jRO exclusive pet. No stats required. */
+ Id: 3318
+ SpriteName: "PAD_SAPPHILIT"
+ Name: "Sapphilit"
+},
+{/* jRO exclusive pet. No stats required. */
+ Id: 3319
+ SpriteName: "PAD_EMELIT"
+ Name: "Emelit"
+},
+{/* jRO exclusive pet. No stats required. */
+ Id: 3320
+ SpriteName: "PAD_TOPALIT"
+ Name: "Topalit"
+},
+{/* jRO exclusive pet. No stats required. */
+ Id: 3321
+ SpriteName: "PAD_AMELIT"
+ Name: "Amelit"
+},
//3322,PAD_METAL_DRAGON
//3323,PAD_M_FLAME_KNIGHT
//3324,PAD_M_ICE_KNIGHT
@@ -84441,7 +84717,11 @@ mob_db: (
//3346,PAD_SIREN_H
//3347,PAD_LILITH_H
//3348,PAD_HERA_H
-//3349,PAD_MYTHLIT
+{/* jRO exclusive pet. No stats required. */
+ Id: 3349
+ SpriteName: "PAD_MYTHLIT"
+ Name: "Mythlit"
+},
//3350,PAD_TYRRA
//3351,PAD_TYRANNOS
//3352,PAD_PLESSIE
@@ -84530,4 +84810,602 @@ mob_db: (
Captured_Soul: 4000
}
},
+{
+ Id: 3495
+ SpriteName: "DR_EGGRING"
+ Name: "Eggring"
+ Hp: 50
+ Exp: 50
+ JExp: 35
+ Attack: [7, 1]
+ Def: 2
+ Mdef: 4
+ Stats: {
+ Str: 6
+ Agi: 1
+ Vit: 1
+ Dex: 6
+ Luk: 4
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Race: "RC_Plant"
+ Element: ("Ele_Earth", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 400
+ AttackDelay: 1872
+ AttackMotion: 672
+ DamageMotion: 480
+ Drops: {
+ Jellopy: 7000
+ Apple: 1000
+ Sticky_Mucus: 400
+ Phracon: 30
+ Wing_Of_Fly: 500
+ Apple: 150
+ Apple: 20
+ Eggring_Card: 20
+ }
+},
+{
+ Id: 3496
+ SpriteName: "DR_LUNATIC"
+ Name: "Leaf Lunatic"
+ Lv: 3
+ Hp: 44
+ Exp: 50
+ JExp: 35
+ Attack: [12, 1]
+ Def: 16
+ Stats: {
+ Str: 9
+ Agi: 1
+ Vit: 2
+ Dex: 7
+ Luk: 4
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Brute"
+ Element: ("Ele_Neutral", 3)
+ Mode: {
+ CanMove: true
+ CanAttack: true
+ }
+ MoveSpeed: 200
+ AttackDelay: 1456
+ AttackMotion: 456
+ DamageMotion: 336
+ Drops: {
+ Clover: 7000
+ Feather: 3000
+ Pierrot_Nose: 4
+ Apple: 1000
+ Wing_Of_Fly: 500
+ Carrot: 3000
+ Phracon: 30
+ Leaf_Lunatic_Card: 10
+ }
+},
+{
+ Id: 3636
+ SpriteName: "LITTLE_ISIS"
+ Name: "Little Isis"
+ Lv: 59
+ Hp: 2092
+ Exp: 279
+ JExp: 298
+ Attack: [278, 81]
+ Def: 83
+ Mdef: 5
+ Stats: {
+ Str: 58
+ Agi: 43
+ Vit: 22
+ Int: 5
+ Dex: 43
+ Luk: 15
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Large"
+ Race: "RC_Demon"
+ Element: ("Ele_Dark", 1)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ CanAttack: true
+ Detector: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 200
+ AttackDelay: 1384
+ AttackMotion: 768
+ DamageMotion: 336
+},
+{
+ Id: 3669
+ SpriteName: "DIABOLIC2"
+ Name: "Diabolic2"
+ Lv: 104
+ Hp: 10572
+ Exp: 1086
+ JExp: 1073
+ Attack: [772, 283]
+ Def: 68
+ Mdef: 61
+ Stats: {
+ Str: 103
+ Agi: 80
+ Vit: 53
+ Int: 65
+ Dex: 94
+ Luk: 25
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Demon"
+ Element: ("Ele_Dark", 2)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CanAttack: true
+ Detector: true
+ Angry: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 1080
+ AttackMotion: 780
+ DamageMotion: 180
+},
+{
+ Id: 3670
+ SpriteName: "DELETER_2"
+ Name: "Deleter 2"
+ Lv: 105
+ Hp: 10000
+ Exp: 1049
+ JExp: 1038
+ Attack: [733, 265]
+ Def: 114
+ Mdef: 53
+ Stats: {
+ Str: 98
+ Agi: 72
+ Vit: 65
+ Int: 49
+ Dex: 68
+ Luk: 71
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Race: "RC_Dragon"
+ Element: ("Ele_Fire", 2)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ Assist: true
+ CanAttack: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 175
+ AttackDelay: 1024
+ AttackMotion: 624
+ DamageMotion: 336
+},
+{
+ Id: 3731
+ SpriteName: "SCATLETON"
+ Name: "Scatleton"
+ Lv: 14
+ Hp: 140
+ Attack: [50, 13]
+ Def: 13
+ Stats: {
+ Str: 10
+ Agi: 12
+ Vit: 8
+ Int: 5
+ Dex: 17
+ Luk: 7
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Demon"
+ Element: ("Ele_Dark", 1)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CanAttack: true
+ }
+ MoveSpeed: 300
+ AttackDelay: 1600
+ AttackMotion: 900
+ DamageMotion: 240
+},
+{
+ Id: 3790
+ SpriteName: "SWEETS_DROPS"
+ Name: "Sweets Drops"
+ Lv: 1
+ Hp: 20
+ Exp: 27
+ JExp: 20
+ Attack: [12, 1]
+ Def: 16
+ Stats: {
+ Str: 1
+ Agi: 1
+ Vit: 1
+ Int: 1
+ Dex: 1
+ Luk: 1
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Race: "RC_Plant"
+ Element: ("Ele_Fire", 1)
+ Mode: {
+ CanMove: true
+ Looter: true
+ CanAttack: true
+ }
+ MoveSpeed: 440
+ AttackDelay: 1372
+ AttackMotion: 672
+ DamageMotion: 480
+},
+{
+ Id: 3971
+ SpriteName: "SKELION"
+ Name: "Skelion"
+ Lv: 150
+ Hp: 13000
+ Exp: 594
+ JExp: 669
+ Attack: [222, 56]
+ Def: 88
+ Mdef: 16
+ Stats: {
+ Str: 25
+ Agi: 16
+ Vit: 12
+ Int: 45
+ Dex: 33
+ Luk: 29
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Small"
+ Race: "RC_Formless"
+ Element: ("Ele_Neutral", 1)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ Boss: true
+ CanAttack: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 960
+ AttackMotion: 864
+ DamageMotion: 0
+},
+{
+ Id: 20373
+ SpriteName: "NIGHTMARE_TERROR_H"
+ Name: "Rigid Nightmare Terror"
+ Lv: 179
+ Hp: 1523377
+ Exp: 138489
+ JExp: 96942
+ Attack: [1709, 725]
+ Def: 242
+ Mdef: 75
+ Stats: {
+ Str: 81
+ Agi: 149
+ Vit: 21
+ Int: 186
+ Dex: 129
+ Luk: 61
+ }
+ ViewRange: 12
+ ChaseRange: 10
+ Size: "Size_Large"
+ Race: "RC_Demon"
+ Element: ("Ele_Dark", 3)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CanAttack: true
+ Detector: true
+ Angry: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 165
+ AttackDelay: 1216
+ AttackMotion: 816
+ DamageMotion: 432
+ Drops: {
+ Rigid_Nightmare_Terror_Card: 10
+ }
+},
+{
+ Id: 20420
+ SpriteName: "WANDER_MAN_H"
+ Name: "Corrupted Wanderer"
+ Lv: 187
+ Hp: 2387582
+ Exp: 170542
+ JExp: 119379
+ Attack: [3654, 1645]
+ Def: 289
+ Mdef: 102
+ Stats: {
+ Str: 176
+ Agi: 121
+ Vit: 34
+ Int: 67
+ Dex: 139
+ Luk: 77
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Race: "RC_Demon"
+ Element: ("Ele_Wind", 2)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CanAttack: true
+ Detector: true
+ Angry: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 100
+ AttackDelay: 672
+ AttackMotion: 500
+ DamageMotion: 192
+ Drops: {
+ Contaminated_Wanderer_Card: 10
+ }
+},
+{
+ Id: 20423
+ SpriteName: "BACSOJIN2"
+ Name: "Bacsojin"
+ Lv: 97
+ Hp: 720500
+ Sp: 1
+ Exp: 801792
+ JExp: 542880
+ AttackRange: 3
+ Attack: [1414, 2036]
+ Def: 210
+ Mdef: 178
+ Stats: {
+ Str: 118
+ Agi: 244
+ Vit: 98
+ Int: 126
+ Dex: 246
+ Luk: 102
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Large"
+ Race: "RC_DemiHuman"
+ Element: ("Ele_Wind", 3)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ Boss: true
+ CanAttack: true
+ Detector: true
+ CastSensorChase: true
+ ChangeChase: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 130
+ AttackDelay: 576
+ AttackMotion: 960
+ DamageMotion: 480
+},
+{
+ Id: 20424
+ SpriteName: "MOONLIGHT2"
+ Name: "Moonlight Flower"
+ Lv: 79
+ Hp: 324000
+ Sp: 1
+ Exp: 367488
+ JExp: 271440
+ AttackRange: 1
+ Attack: [2232, 1251]
+ Def: 254
+ Mdef: 81
+ Stats: {
+ Str: 86
+ Agi: 102
+ Vit: 93
+ Int: 82
+ Dex: 157
+ Luk: 120
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Medium"
+ Race: "RC_Demon"
+ Element: ("Ele_Fire", 3)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ Boss: true
+ CanAttack: true
+ Detector: true
+ CastSensorChase: true
+ ChangeChase: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 1276
+ AttackMotion: 576
+ DamageMotion: 288
+},
+{
+ Id: 20425
+ SpriteName: "PHREEONI2"
+ Name: "Phreeoni"
+ Lv: 71
+ Hp: 300000
+ Sp: 1
+ Exp: 127600
+ JExp: 180000
+ AttackRange: 1
+ Attack: [693, 967]
+ Def: 269
+ Mdef: 98
+ Stats: {
+ Str: 88
+ Agi: 70
+ Vit: 112
+ Int: 87
+ Dex: 122
+ Luk: 71
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Large"
+ Race: "RC_Brute"
+ Element: ("Ele_Neutral", 3)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ Boss: true
+ CanAttack: true
+ Detector: true
+ CastSensorChase: true
+ ChangeChase: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 200
+ AttackDelay: 1020
+ AttackMotion: 1020
+ DamageMotion: 288
+},
+{
+ Id: 20571
+ SpriteName: "ORK_HERO2"
+ Name: "Orc Hero"
+ Lv: 50
+ Hp: 362000
+ Sp: 1
+ Exp: 106920
+ JExp: 97200
+ AttackRange: 1
+ Attack: [662, 441]
+ Def: 197
+ Mdef: 70
+ Stats: {
+ Str: 97
+ Agi: 82
+ Vit: 107
+ Int: 71
+ Dex: 144
+ Luk: 43
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Large"
+ Race: "RC_DemiHuman"
+ Element: ("Ele_Earth", 2)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ Boss: true
+ CanAttack: true
+ Detector: true
+ CastSensorChase: true
+ ChangeChase: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 150
+ AttackDelay: 1678
+ AttackMotion: 780
+ DamageMotion: 648
+},
+{
+ Id: 20619
+ SpriteName: "GLOOMUNDERNIGHT2"
+ Name: "Gloom Under Night"
+ Lv: 139
+ Hp: 3005000
+ Sp: 1
+ Exp: 2808000
+ JExp: 1800000
+ AttackRange: 3
+ Attack: [6592, 2785]
+ Def: 479
+ Mdef: 262
+ Stats: {
+ Str: 191
+ Agi: 223
+ Vit: 187
+ Int: 155
+ Dex: 362
+ Luk: 163
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Large"
+ Race: "RC_Formless"
+ Element: ("Ele_Ghost", 3)
+ Mode: {
+ CanMove: true
+ Aggressive: true
+ CastSensorIdle: true
+ Boss: true
+ CanAttack: true
+ Detector: true
+ CastSensorChase: true
+ ChangeChase: true
+ ChangeTargetMelee: true
+ ChangeTargetChase: true
+ }
+ MoveSpeed: 200
+ AttackDelay: 1344
+ AttackMotion: 2880
+ DamageMotion: 576
+},
+{/** Needs info. No data found. Using dummy data for now to enable pet. **/
+ Id: 20696
+ SpriteName: "EP17_2_CHILD_ADMIN1"
+ Name: "Child Admin Beta"
+},
+{/** Needs info. No data found. Using dummy data for now to enable pet. **/
+ Id: 20697
+ SpriteName: "EP17_2_CHILD_ADMIN2"
+ Name: "Child Admin Alpha"
+},
)
diff --git a/db/re/mob_skill_db.conf b/db/re/mob_skill_db.conf
index 624970c5f..b7f1164da 100644
--- a/db/re/mob_skill_db.conf
+++ b/db/re/mob_skill_db.conf
@@ -36,20 +36,20 @@ mob_skill_db:(
<Skill_Constant>: {
ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob.
SkillLevel: (int, defaults to 1)
- SkillState: (int, defaults to 0)
- SkillTarget: (int, defaults to 0)
+ SkillState: (string, defaults to "MSS_ANY")
+ SkillTarget: (string, defaults to "MST_TARGET")
Rate: (int, defaults to 1)
CastTime: (int, defaults to 0)
Delay: (int, defaults to 0)
Cancelable: (boolean, defaults to false)
- CastCondition: (int, defaults to 0)
+ CastCondition: (string, defaults to "MSC_ALWAYS")
ConditionData: (int, defaults to 0)
val0: (int, defaults to 0)
val1: (int, defaults to 0)
val2: (int, defaults to 0)
val3: (int, defaults to 0)
val4: (int, defaults to 0)
- Emotion: (int, defaults to 0)
+ Emotion: (int, defaults to -1)
ChatMsgID: (int, defaults to 0)
}
}
@@ -100586,6 +100586,71 @@ mob_skill_db:(
CastCondition: "MSC_ALWAYS"
}
}
+ WOODIE: {
+ AL_HEAL: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 9
+ Rate: 10000
+ CastTime: 500
+ Delay: 5000
+ SkillTarget: "MST_SELF"
+ }
+ NPC_FIREATTACK: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 3
+ Rate: 2000
+ CastTime: 500
+ Delay: 5000
+ SkillTarget: "MST_TARGET"
+ }
+ NPC_GROUNDATTACK: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 3
+ Rate: 2000
+ CastTime: 500
+ Delay: 5000
+ SkillTarget: "MST_TARGET"
+ }
+ }
+ XM_TEDDY_BEAR: {
+ NPC_CURSEATTACK: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 4
+ Rate: 500
+ Delay: 5000
+ SkillTarget: "MST_SELF"
+ }
+ NPC_CURSEATTACK: {
+ SkillState: "MSS_FOLLOW"
+ SkillLevel: 4
+ Rate: 500
+ Delay: 5000
+ SkillTarget: "MST_SELF"
+ }
+ NPC_CRITICALSLASH: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 1
+ Rate: 500
+ Delay: 5000
+ SkillTarget: "MST_TARGET"
+ }
+ SA_DISPELL: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 1
+ Rate: 50
+ CastTime: 1000
+ Delay: 15000
+ SkillTarget: "MST_TARGET"
+ }
+ BS_HAMMERFALL: {
+ SkillState: "MSS_BERSERK"
+ SkillLevel: 5
+ Rate: 500
+ CastTime: 1000
+ Delay: 5000
+ SkillTarget: "MST_TARGET"
+ }
+ }
TIMEHOLDER: {
NPC_AGIUP: {
SkillState: "MSS_BERSERK"
diff --git a/db/re/pet_db.conf b/db/re/pet_db.conf
index 3392a8191..f31131653 100644
--- a/db/re/pet_db.conf
+++ b/db/re/pet_db.conf
@@ -72,10 +72,11 @@ pet_db:(
{
Id: 1002
Name: "Poring"
- TamingItem: "Unripe_Apple"
EggItem: "Poring_Egg"
- AccessoryItem: "Backpack"
+ TamingItem: "Unripe_Apple"
FoodItem: "Apple_Juice"
+ AccessoryItem: "Backpack"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
@@ -85,7 +86,11 @@ pet_db:(
DefendRate: 400
PetScript: <" petloot(10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bLuk, 3);
+ bonus(bCritical, 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bLuk, 2);
bonus(bCritical, 1);
}
@@ -100,9 +105,10 @@ pet_db:(
{
Id: 1011
Name: "ChonChon"
- TamingItem: "Rotten_Fish"
EggItem: "Chonchon_Egg"
+ TamingItem: "Rotten_Fish"
AccessoryItem: "Monster_Oxygen_Mask"
+ HungerDecrement: 6
Intimacy: {
FeedIncrement: 30
}
@@ -113,7 +119,11 @@ pet_db:(
ChangeTargetRate: 250
PetScript: <" petskillbonus(bAgi, 4, 10, 50); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAgi, 2);
+ bonus(bFlee, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bAgi, 1);
bonus(bFlee, 2);
}
@@ -122,9 +132,10 @@ pet_db:(
{
Id: 1014
Name: "Spore"
- TamingItem: "Dew_Laden_Moss"
EggItem: "Spore_Egg"
+ TamingItem: "Dew_Laden_Moss"
AccessoryItem: "Bark_Shorts"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 30
}
@@ -134,18 +145,20 @@ pet_db:(
ChangeTargetRate: 500
PetScript: <" petrecovery(SC_POISON, 60); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bHit, 8);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bHit, 5);
- bonus(bAtk, -2);
- }
">
},
{
Id: 1019
Name: "PecoPeco"
- TamingItem: "Fatty_Chubby_Earthworm"
EggItem: "PecoPeco_Egg"
+ TamingItem: "Fatty_Chubby_Earthworm"
AccessoryItem: "Battered_Pot"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 30
}
@@ -154,10 +167,11 @@ pet_db:(
DefendRate: 500
PetScript: <" petskillbonus(bSpeedRate, 25, 20, 20); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxHP, 200);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bMaxHP, 150);
- bonus(bMaxSP, -10);
- }
">
Evolve: {
Grand_Peco_Peco_Egg: {
@@ -172,9 +186,10 @@ pet_db:(
{
Id: 1023
Name: "Orc Warrior"
- TamingItem: "Horror_Of_Tribe"
EggItem: "Orc_Warrior_Egg"
+ TamingItem: "Horror_Of_Tribe"
AccessoryItem: "Wild_Flower"
+ HungerDecrement: 5
Intimacy: {
FeedIncrement: 20
}
@@ -185,10 +200,11 @@ pet_db:(
ChangeTargetRate: 300
PetScript: <" petskillattack("NPC_PIERCINGATT", 100, 1, 0, 10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAtk, 15);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bAtk, 10);
- bonus(bDef, -3);
- }
">
Evolve: {
High_Orc_Egg: {
@@ -203,9 +219,10 @@ pet_db:(
{
Id: 1026
Name: "Munak"
- TamingItem: "No_Recipient"
EggItem: "Munak_Egg"
+ TamingItem: "No_Recipient"
AccessoryItem: "Punisher"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 20
}
@@ -214,7 +231,11 @@ pet_db:(
ChangeTargetRate: 300
PetScript: <" petskillattack("NPC_DARKNESSATTACK", 444, 1, 0, 10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bInt, 2);
+ bonus(bDef, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bInt, 1);
bonus(bDef, 1);
}
@@ -223,19 +244,21 @@ pet_db:(
{
Id: 1029
Name: "Isis"
- TamingItem: "Armlet_Of_Obedience"
EggItem: "Isis_Egg"
+ TamingItem: "Armlet_Of_Obedience"
AccessoryItem: "Queens_Hair_Ornament"
+ HungerDecrement: 3
CaptureRate: 500
AttackRate: 650
DefendRate: 450
ChangeTargetRate: 150
PetScript: <" petskillsupport("PR_MAGNIFICAT", 2, 60, 50, 50); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
- bonus(bMatkRate, -1);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAtkRate, 2);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bAtkRate, 1);
- }
">
Evolve: {
Little_Isis_Egg: {
@@ -249,10 +272,11 @@ pet_db:(
{
Id: 1031
Name: "Poporing"
- TamingItem: "Bitter_Herb"
EggItem: "Poporing_Egg"
- AccessoryItem: "Backpack"
+ TamingItem: "Bitter_Herb"
FoodItem: "Green_Herb"
+ AccessoryItem: "Backpack"
+ HungerDecrement: 5
Intimacy: {
FeedIncrement: 30
}
@@ -261,7 +285,11 @@ pet_db:(
ChangeTargetRate: 400
PetScript: <" petloot(15); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bLuk, 3);
+ bonus2(bSubEle, Ele_Poison, 15);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bLuk, 2);
bonus2(bSubEle, Ele_Poison, 10);
}
@@ -270,10 +298,11 @@ pet_db:(
{
Id: 1035
Name: "Hunter Fly"
- TamingItem: "Monster_Juice"
EggItem: "Hunter_Fly_Egg"
- AccessoryItem: "Monster_Oxygen_Mask"
+ TamingItem: "Monster_Juice"
FoodItem: "Red_Gemstone"
+ AccessoryItem: "Monster_Oxygen_Mask"
+ HungerDecrement: 5
CaptureRate: 500
SpecialPerformance: true
AttackRate: 500
@@ -281,19 +310,21 @@ pet_db:(
ChangeTargetRate: 200
PetScript: <" petskillattack("NPC_WINDATTACK", 888, 2, 0, 10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
- bonus(bFlee, -5);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bFlee2, 2);
- }
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bHit, 1);
">
},
{
Id: 1042
Name: "Steel ChonChon"
- TamingItem: "Lusty_Iron"
EggItem: "Steel_Chonchon_Egg"
- AccessoryItem: "Monster_Oxygen_Mask"
+ TamingItem: "Lusty_Iron"
FoodItem: "Iron_Ore"
+ AccessoryItem: "Monster_Oxygen_Mask"
+ HungerDecrement: 5
Intimacy: {
FeedIncrement: 20
}
@@ -303,19 +334,21 @@ pet_db:(
ChangeTargetRate: 200
PetScript: <" petskillbonus(bAgiVit, 4, 20, 40); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bFlee, 9);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bFlee, 6);
- bonus(bAgi, -1);
- }
">
},
{
Id: 1049
Name: "Picky"
- TamingItem: "Earthworm_The_Dude"
EggItem: "Picky_Egg"
- AccessoryItem: "Tiny_Egg_Shell"
+ TamingItem: "Earthworm_The_Dude"
FoodItem: "Red_Herb"
+ AccessoryItem: "Tiny_Egg_Shell"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 40
}
@@ -326,7 +359,11 @@ pet_db:(
ChangeTargetRate: 50
PetScript: <" petskillbonus(bStr, 3, 10, 50); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bStr, 2);
+ bonus(bAtk, 8);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bStr, 1);
bonus(bAtk, 5);
}
@@ -335,8 +372,8 @@ pet_db:(
{
Id: 1052
Name: "Rocker"
- TamingItem: "Singing_Flower"
EggItem: "Rocker_Egg"
+ TamingItem: "Singing_Flower"
AccessoryItem: "Rocker_Glasses"
Intimacy: {
FeedIncrement: 30
@@ -347,7 +384,11 @@ pet_db:(
ChangeTargetRate: 600
PetScript: <" petskillbonus(bAllStats, 1, 10, 50); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bHPrecovRate, 8);
+ bonus(bMaxHP, 38);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bHPrecovRate, 5);
bonus(bMaxHP, 25);
}
@@ -364,9 +405,10 @@ pet_db:(
{
Id: 1056
Name: "Smokie"
- TamingItem: "Baked_Yam"
EggItem: "Smokie_Egg"
+ TamingItem: "Baked_Yam"
AccessoryItem: "Red_Muffler"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 30
}
@@ -376,7 +418,11 @@ pet_db:(
ChangeTargetRate: 100
PetScript: <" petskillbonus(bPerfectHide, 1, 3600, 0); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAgi, 2);
+ bonus(bFlee2, 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bAgi, 1);
bonus(bFlee2, 1);
}
@@ -385,21 +431,24 @@ pet_db:(
{
Id: 1057
Name: "Yoyo"
- TamingItem: "Tropical_Banana"
EggItem: "Yoyo_Egg"
- AccessoryItem: "Monkey_Circlet"
+ TamingItem: "Tropical_Banana"
FoodItem: "Banana_Juice"
+ AccessoryItem: "Monkey_Circlet"
+ HungerDecrement: 5
Intimacy: {
FeedIncrement: 20
}
SpecialPerformance: true
+ DefendRate: 800
ChangeTargetRate: 400
PetScript: <" petloot(20); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bCritical, 5);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bCritical, 3);
- bonus(bLuk, -1);
- }
">
Evolve: {
Choco_Egg: {
@@ -413,10 +462,11 @@ pet_db:(
{
Id: 1063
Name: "Lunatic"
- TamingItem: "Rainbow_Carrot"
EggItem: "Lunatic_Egg"
- AccessoryItem: "Silk_Ribbon"
+ TamingItem: "Rainbow_Carrot"
FoodItem: "Carrot_Juice"
+ AccessoryItem: "Silk_Ribbon"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 40
}
@@ -424,7 +474,11 @@ pet_db:(
ChangeTargetRate: 1000
PetScript: <" petskillbonus(bLuk, 3, 10, 50); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bCritical, 3);
+ bonus(bAtk, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bCritical, 2);
bonus(bAtk, 2);
}
@@ -441,9 +495,10 @@ pet_db:(
{
Id: 1077
Name: "Poison Spore"
- TamingItem: "Deadly_Noxious_Herb"
EggItem: "Poison_Spore_Egg"
+ TamingItem: "Deadly_Noxious_Herb"
AccessoryItem: "Bark_Shorts"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 20
}
@@ -452,7 +507,11 @@ pet_db:(
ChangeTargetRate: 400
PetScript: <" petskillattack("NPC_POISON", 20, 0, 0, 10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bStr, 2);
+ bonus(bInt, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bStr, 1);
bonus(bInt, 1);
}
@@ -461,29 +520,36 @@ pet_db:(
{
Id: 1101
Name: "Baphomet Jr."
- TamingItem: "Book_Of_Devil"
EggItem: "Bapho_Jr_Egg"
- AccessoryItem: "Skull_Helm"
+ TamingItem: "Book_Of_Devil"
FoodItem: "Honey"
+ AccessoryItem: "Skull_Helm"
+ HungerDecrement: 2
CaptureRate: 200
AttackRate: 1000
DefendRate: 100
ChangeTargetRate: 200
PetScript: <" petskillattack("NPC_DARKNESSATTACK", 1776, 4, 0, 5); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bDef, 2);
+ bonus(bMdef, 2);
+ bonus2(bResEff, Eff_Stun, 200);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bDef, 1);
bonus(bMdef, 1);
- bonus2(bResEff, Eff_Stun, -100);
+ bonus2(bResEff, Eff_Stun, 100);
}
">
},
{
Id: 1107
Name: "Baby Desert Wolf"
- TamingItem: "Well_Dried_Bone"
EggItem: "Baby_Desert_Wolf_Egg"
+ TamingItem: "Well_Dried_Bone"
AccessoryItem: "Transparent_Headgear"
+ HungerDecrement: 6
Intimacy: {
FeedIncrement: 40
}
@@ -492,7 +558,11 @@ pet_db:(
ChangeTargetRate: 400
PetScript: <" petskillattack("SM_PROVOKE", 1, 0, 0, 5);">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bInt, 2);
+ bonus(bMaxSP, 75);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bInt, 1);
bonus(bMaxSP, 50);
}
@@ -501,20 +571,25 @@ pet_db:(
{
Id: 1109
Name: "Deviruchi"
- TamingItem: "Contracts_In_Shadow"
EggItem: "Deviruchi_Egg"
- AccessoryItem: "Pacifier"
+ TamingItem: "Contracts_In_Shadow"
FoodItem: "Shoot"
+ AccessoryItem: "Pacifier"
+ HungerDecrement: 2
CaptureRate: 500
+ AttackRate: 800
DefendRate: 200
ChangeTargetRate: 100
PetScript: <" petskillbonus(bAgiDexStr, 6, 20, 40); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
- bonus(bMatkRate, 1);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bAtkRate, 1);
- bonus(bMaxHPrate, -3);
- bonus(bMaxSPrate, -3);
+ bonus(bMatkRate, 1);
+ }
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxHPrate, 1);
+ bonus(bMaxSPrate, 1);
}
">
Evolve: {
@@ -529,19 +604,21 @@ pet_db:(
{
Id: 1110
Name: "Dokebi"
- TamingItem: "Old_Broom"
EggItem: "Dokkaebi_Egg"
+ TamingItem: "Old_Broom"
AccessoryItem: "Wig"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 20
}
CaptureRate: 500
PetScript: <" petskillattack("BS_HAMMERFALL", 1, 0, 0, 10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMatkRate, 2);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bMatkRate, 1);
- bonus(bAtkRate, -1);
- }
">
Evolve: {
Am_Mut_Egg: {
@@ -555,10 +632,11 @@ pet_db:(
{
Id: 1113
Name: "Drops"
- TamingItem: "Orange_Juice"
EggItem: "Drops_Egg"
- AccessoryItem: "Backpack"
+ TamingItem: "Orange_Juice"
FoodItem: "Yellow_Herb"
+ AccessoryItem: "Backpack"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 40
}
@@ -568,7 +646,11 @@ pet_db:(
ChangeTargetRate: 500
PetScript: <" petloot(10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bHit, 5);
+ bonus(bAtk, 5);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bHit, 3);
bonus(bAtk, 3);
}
@@ -580,35 +662,35 @@ pet_db:(
Apple_Juice: 3
Eggring_Card: 1
}
-/*
Sweet_Drops_Egg: {
- 25290: 500
+ Sweets_Coin: 500
Candy: 50
Candy_Striper: 50
Drops_Card: 1
}
-*/
}
},
{
Id: 1155
Name: "Petite"
- TamingItem: "Shining_Stone"
EggItem: "Green_Petite_Egg"
+ TamingItem: "Shining_Stone"
AccessoryItem: "Stellar_Hairpin"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 20
}
CaptureRate: 500
+ AttackRate: 800
DefendRate: 400
ChangeTargetRate: 100
PetScript: <" petskillattack("WZ_HEAVENDRIVE", 500, 1, 0, 10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
- bonus(bDef, -2);
- bonus(bMdef, -2);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bAspdRate, 1);
- }
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAgi, 1);
">
Evolve: {
Earth_Deleter_Egg: {
@@ -622,9 +704,10 @@ pet_db:(
{
Id: 1167
Name: "Savage Babe"
- TamingItem: "Sweet_Milk"
EggItem: "Savage_Bebe_Egg"
+ TamingItem: "Sweet_Milk"
AccessoryItem: "Green_Lace"
+ HungerDecrement: 7
Intimacy: {
FeedIncrement: 40
}
@@ -634,7 +717,11 @@ pet_db:(
ChangeTargetRate: 200
PetScript: <" petskillbonus(bVit, 4, 10, 50); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bVit, 2);
+ bonus(bMaxHP, 75);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bVit, 1);
bonus(bMaxHP, 50);
}
@@ -651,16 +738,21 @@ pet_db:(
{
Id: 1170
Name: "Sohee"
- TamingItem: "Silver_Knife_Of_Chaste"
EggItem: "Sohee_Egg"
+ TamingItem: "Silver_Knife_Of_Chaste"
AccessoryItem: "Golden_Bell"
+ HungerDecrement: 3
CaptureRate: 500
AttackRate: 100
DefendRate: 1000
ChangeTargetRate: 200
PetScript: <" petskillsupport(AL_HEAL, 10, 60, 33, 100); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bStr, 2);
+ bonus(bDex, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bStr, 1);
bonus(bDex, 1);
}
@@ -669,9 +761,10 @@ pet_db:(
{
Id: 1188
Name: "Bon Gun"
- TamingItem: "Heart_Of_Her"
EggItem: "Bongun_Egg"
+ TamingItem: "Heart_Of_Her"
AccessoryItem: "Sword_Of_Grave_Keeper"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 30
}
@@ -682,7 +775,11 @@ pet_db:(
ChangeTargetRate: 400
PetScript: <" petskillattack("NPC_DARKNESSATTACK", 555, 1, 1, 1); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bVit, 2);
+ bonus2(bResEff, Eff_Stun, 200);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bVit, 1);
bonus2(bResEff, Eff_Stun, 100);
}
@@ -699,16 +796,21 @@ pet_db:(
{
Id: 1200
Name: "Zealotus"
- TamingItem: "Prohibition_Red_Candle"
EggItem: "Zherlthsh_Egg"
+ TamingItem: "Prohibition_Red_Candle"
FoodItem: "Immortal_Heart"
+ HungerDecrement: 7
CaptureRate: 300
AttackRate: 1000
DefendRate: 100
ChangeTargetRate: 500
PetScript: <" petskillattack("AS_SONICBLOW", 1, 0, 0, 3); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus2(bAddRace, RC_DemiPlayer, 3);
+ bonus2(bMagicAddRace, RC_DemiPlayer, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus2(bAddRace, RC_DemiPlayer, 2);
bonus2(bMagicAddRace, RC_DemiPlayer, 2);
}
@@ -717,16 +819,21 @@ pet_db:(
{
Id: 1245
Name: "Christmas Goblin"
- TamingItem: "Sweet_Candy_Striper"
EggItem: "Santa_Goblin_Egg"
+ TamingItem: "Sweet_Candy_Striper"
FoodItem: "Scell"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
CaptureRate: 2000
PetScript: <" petskillattack("MG_SIGHT", 5, 0, 5, 5); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxHP, 45);
+ bonus2(bSubEle, Ele_Water, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bMaxHP, 30);
bonus2(bSubEle, Ele_Water, 1);
}
@@ -735,85 +842,126 @@ pet_db:(
{
Id: 1275
Name: "Alice"
- TamingItem: "Sway_Apron"
EggItem: "Alice_Egg"
+ TamingItem: "Sway_Apron"
FoodItem: "White_Potion"
+ HungerDecrement: 2
Intimacy: {
FeedIncrement: 20
}
+ CaptureRate: 800
AttackRate: 100
DefendRate: 1000
ChangeTargetRate: 200
PetScript: <" petskillsupport("AL_HEAL", 5, 60, 25, 100); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMdef, 2);
+ bonus2(bAddRaceTolerance, RC_DemiPlayer, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bMdef, 1);
bonus2(bAddRaceTolerance, RC_DemiPlayer, 1);
}
">
+ Evolve: {
+ Aliza_Egg: {
+ Alices_Apron: 500
+ Green_Herb: 200
+ Elunium: 30
+ Alice_Card: 1
+ }
+ }
},
// New Pets
{
Id: 1122
Name: "Goblin"
- TamingItem: "Knife_Goblin_Ring"
EggItem: "Knife_Goblin_Egg"
+ TamingItem: "Knife_Goblin_Ring"
FoodItem: "Green_Apple"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
+ CaptureRate: 800
PetScript: <" petskillattack("NPC_WINDATTACK", 5, 0, 5, 5); ">
},
{
Id: 1123
Name: "Goblin"
- TamingItem: "Flail_Goblin_Ring"
EggItem: "Flail_Goblin_Egg"
+ TamingItem: "Flail_Goblin_Ring"
FoodItem: "Green_Apple"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
+ CaptureRate: 800
PetScript: <" petskillattack("NPC_FIREATTACK", 5, 0, 5, 5); ">
},
{
Id: 1125
Name: "Goblin"
- TamingItem: "Hammer_Goblin_Ring"
EggItem: "Hammer_Goblin_Egg"
+ TamingItem: "Hammer_Goblin_Ring"
FoodItem: "Green_Apple"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
+ CaptureRate: 800
PetScript: <" petskillattack("NPC_GROUNDATTACK", 5, 0, 5, 5); ">
},
{
Id: 1208
Name: "Wanderer"
- TamingItem: "Skull_Of_Vagabond"
EggItem: "Wanderer_Egg"
+ TamingItem: "Skull_Of_Vagabond"
FoodItem: "Spirit_Liquor"
+ HungerDecrement: 2
Intimacy: {
FeedIncrement: 20
}
+ CaptureRate: 800
PetScript: <" petskillattack("NPC_UNDEADATTACK", 5, 0, 5, 5); ">
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAgi, 4);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bAgi, 3);
+ ">
+ Evolve: {
+ Contaminated_Wanderer_Egg: {
+ Skull: 500
+ Sacred_Marks: 50
+ Transparent_Cloth: 100
+ Wander_Man_Card: 1
+ }
+ }
},
{
Id: 1382
Name: "Diabolic"
- TamingItem: "Red_Burning_Stone"
EggItem: "Diabolic_Egg"
+ TamingItem: "Red_Burning_Stone"
FoodItem: "Meat_Veg_Skewer"
+ HungerDecrement: 2
+ CaptureRate: 800
PetScript: <" petskillattack("WZ_METEOR", 2, 0, 5, 5); ">
},
{
Id: 1385
Name: "Deleter"
- TamingItem: "Holy_Marble"
EggItem: "Red_Deleter_Egg"
+ TamingItem: "Holy_Marble"
FoodItem: "Whole_Barbecue"
+ HungerDecrement: 4
Intimacy: {
FeedIncrement: 20
}
+ CaptureRate: 800
PetScript: <" petskillattack("SM_MAGNUM", 5, 0, 5, 5); ">
},
{
@@ -821,6 +969,7 @@ pet_db:(
Name: "Spring Rabbit"
EggItem: "Spring_Rabbit_Egg"
FoodItem: "Bok_Choy"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
@@ -833,9 +982,11 @@ pet_db:(
Name: "New Year Doll"
EggItem: "New_Year_Doll_Egg"
FoodItem: "Mojji"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 30
}
+ CaptureRate: 800
PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); ">
},
// Episode 13
@@ -844,6 +995,7 @@ pet_db:(
Name: "Rice Cake"
EggItem: "Rice_Cake_Egg"
FoodItem: "Green_Herb"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
@@ -854,10 +1006,11 @@ pet_db:(
ChangeTargetRate: 200
PetScript: <" petskillsupport("CR_DEFENDER", 3, 240, 50, 100); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus2(bSubEle, Ele_Neutral, 2);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus2(bSubEle, Ele_Neutral, 1);
- bonus(bMaxHPrate, -1);
- }
">
},
{
@@ -865,9 +1018,10 @@ pet_db:(
Name: "Christmas Snow Rabbit"
EggItem: "Snow_Rabbit_Egg"
FoodItem: "Candy"
+ HungerDecrement: 3
SpecialPerformance: true
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_CORDIAL)
bonus2(bExpAddRace, RC_All, 5);
">
},
@@ -875,44 +1029,52 @@ pet_db:(
{
Id: 1040
Name: "Golem"
- TamingItem: "Magical_Lithography"
EggItem: "Golem_Egg"
- AccessoryItem: "Windup_Spring"
+ TamingItem: "Magical_Lithography"
FoodItem: "Mystic_Stone"
+ AccessoryItem: "Windup_Spring"
+ HungerDecrement: 7
Intimacy: {
FeedIncrement: 20
}
- CaptureRate: 500
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxHP, 150);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bMaxHP, 100);
- bonus(bFlee, -5);
- }
">
},
{
Id: 1143
Name: "Marionette"
- TamingItem: "Delicious_Shaved_Ice"
EggItem: "Marionette_Egg"
- AccessoryItem: "Star_Hairband"
+ TamingItem: "Delicious_Shaved_Ice"
FoodItem: "Small_Snow_Flower"
- CaptureRate: 500
+ AccessoryItem: "Star_Hairband"
+ HungerDecrement: 3
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
- bonus(bSPrecovRate, 3);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ autobonus("{ bonus2(bSubEle, Ele_Neutral, 20); heal(100, 0); }", 10, 5000, BF_SHORT|BF_NORMAL);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ autobonus("{ bonus2(bSubEle, Ele_Neutral, 20); heal(100, 0); }", 10, 3000, BF_SHORT|BF_NORMAL);
">
},
{
Id: 1148
Name: "Medusa"
- TamingItem: "Splendid_Mirror"
EggItem: "Medusa_Egg"
- AccessoryItem: "Queens_Coronet"
+ TamingItem: "Splendid_Mirror"
FoodItem: "Apple_Pudding"
- CaptureRate: 200
+ AccessoryItem: "Queens_Coronet"
+ HungerDecrement: 3
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bVit, 2);
+ bonus2(bResEff, Eff_Stone, 800);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bVit, 1);
bonus2(bResEff, Eff_Stone, 500);
}
@@ -921,198 +1083,264 @@ pet_db:(
{
Id: 1179
Name: "Whisper"
- TamingItem: "Fit_Pipe"
EggItem: "Whisper_Egg"
- AccessoryItem: "Spirit_Chain_"
+ TamingItem: "Fit_Pipe"
FoodItem: "Damp_Darkness"
+ AccessoryItem: "Spirit_Chain_"
+ HungerDecrement: 7
Intimacy: {
FeedIncrement: 20
}
- CaptureRate: 500
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bFlee, 10);
+ skill("TF_HIDING", 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bFlee, 7);
- bonus(bDef, -3);
+ skill("TF_HIDING", 1);
}
">
},
{
Id: 1299
Name: "Goblin Leader"
- TamingItem: "Staff_Of_Leader"
EggItem: "Goblin_Leader_Egg"
- AccessoryItem: "Nice_Badge"
+ TamingItem: "Staff_Of_Leader"
FoodItem: "Big_Cell"
- CaptureRate: 50
+ AccessoryItem: "Nice_Badge"
+ HungerDecrement: 7
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus2(bAddRace, RC_DemiPlayer, 5);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus2(bAddRace, RC_DemiPlayer, 3);
">
},
{
Id: 1370
Name: "Succubus"
- TamingItem: "Boys_Naivety"
EggItem: "Succubus_Egg"
- AccessoryItem: "Black_Butterfly_Mask"
+ TamingItem: "Boys_Naivety"
FoodItem: "Vital_Flower_"
- CaptureRate: 200
+ AccessoryItem: "Black_Butterfly_Mask"
+ HungerDecrement: 3
+ CaptureRate: 300
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
- bonus2(bHPDrainRate, 50, 5);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus2(bHPDrainRate, 20, 5);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxHPrate, 1);
">
},
{
Id: 1374
Name: "Incubus"
- TamingItem: "Grils_Naivety"
EggItem: "Incubus_Egg"
- AccessoryItem: "Ball_Mask"
+ TamingItem: "Grils_Naivety"
FoodItem: "Vital_Flower"
- CaptureRate: 50
+ AccessoryItem: "Ball_Mask"
+ HungerDecrement: 3
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxSPrate, 5);
+ bonus2(bSPDrainRate, 30, 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bMaxSPrate, 3);
+ bonus2(bSPDrainRate, 20, 1);
+ }
">
},
{
Id: 1379
Name: "Nightmare Terror"
- TamingItem: "Hell_Contract"
EggItem: "Nightmare_Terror_Egg"
- AccessoryItem: "Hell_Horn"
+ TamingItem: "Hell_Contract"
FoodItem: "Fresh_Plant"
- CaptureRate: 200
+ AccessoryItem: "Hell_Horn"
+ HungerDecrement: 3
+ CaptureRate: 300
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus2(bResEff, Eff_Sleep, 10000);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bInt, 1);
">
+ Evolve: {
+ Rigid_Nightmare_Terror_Egg: {
+ Burning_Horse_Shoe: 500
+ Blue_Herb: 100
+ Shell: 100
+ Nightmare_Terror_Card: 1
+ }
+ }
},
{
Id: 1401
Name: "Shinobi"
- TamingItem: "Kuloren"
EggItem: "Shinobi_Egg"
- AccessoryItem: "Wine_On_Sleeve"
+ TamingItem: "Kuloren"
FoodItem: "Grilled_Rice_Cake"
+ AccessoryItem: "Wine_On_Sleeve"
+ HungerDecrement: 7
Intimacy: {
FeedIncrement: 20
}
- CaptureRate: 500
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAgi, 3);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bAgi, 2);
">
},
{
Id: 1404
Name: "Miyabi Doll"
- TamingItem: "Gril_Doll"
EggItem: "Miyabi_Ningyo_Egg"
- AccessoryItem: "Summer_Fan"
+ TamingItem: "Gril_Doll"
FoodItem: "Well_Ripened_Berry"
+ AccessoryItem: "Summer_Fan"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 15
}
- CaptureRate: 200
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bInt, 2);
+ bonus(bVariableCastrate, -5);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bInt, 1);
- bonus(bCastrate, -3);
+ bonus(bVariableCastrate, -3);
}
">
},
{
Id: 1416
Name: "Evil Nymph"
- TamingItem: "Charming_Lotus"
EggItem: "Wicked_Nymph_Egg"
- AccessoryItem: "Jade_Trinket"
+ TamingItem: "Charming_Lotus"
FoodItem: "Morning_Dew"
+ AccessoryItem: "Jade_Trinket"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 15
}
- CaptureRate: 500
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxSP, 45);
+ bonus(bSPrecovRate, 8);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bMaxSP, 30);
bonus(bSPrecovRate, 5);
}
">
+ Evolve: {
+ Bacsojin2_Egg_: {
+ Mightysoul_Essence: 30
+ Civil_Servant_Card: 10
+ Li_Me_Mang_Ryang_Card: 10
+ Dancing_Dragon_Card: 10
+ }
+ }
},
{
Id: 1495
Name: "Stone Shooter"
- TamingItem: "Oilpalm_Coconut"
EggItem: "Stone_Shooter_Egg"
- AccessoryItem: "Apro_Hair"
+ TamingItem: "Oilpalm_Coconut"
FoodItem: "Plant_Neutrient"
+ AccessoryItem: "Apro_Hair"
+ HungerDecrement: 7
Intimacy: {
FeedIncrement: 20
}
- CaptureRate: 500
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus2(bSubEle, Ele_Fire, 5);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus2(bSubEle, Ele_Fire, 3);
">
},
{
Id: 1504
Name: "Dullahan"
- TamingItem: "Luxury_Whisky_Bottle"
EggItem: "Dullahan_Egg"
- AccessoryItem: "Death_Coil"
+ TamingItem: "Luxury_Whisky_Bottle"
FoodItem: "Sunset_On_The_Rock"
- CaptureRate: 200
+ AccessoryItem: "Death_Coil"
+ HungerDecrement: 3
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bCritAtkRate, 8);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bCritAtkRate, 5);
">
},
{
Id: 1505
Name: "Loli Ruri"
- TamingItem: "Very_Red_Juice"
EggItem: "Loli_Ruri_Egg"
- AccessoryItem: "Fashionable_Glasses"
+ TamingItem: "Very_Red_Juice"
FoodItem: "Pumpkin_Pie_"
+ AccessoryItem: "Fashionable_Glasses"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 15
}
- CaptureRate: 200
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
bonus(bMaxHPrate, 3);
- bonus3(bAutoSpellWhenHit, "AL_HEAL", 1, 50);
+ bonus3(bAutoSpellWhenHit, "AL_HEAL", 2, 10);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMaxHPrate, 3);
+ bonus3(bAutoSpellWhenHit, "AL_HEAL", 1, 10);
}
">
},
{
Id: 1513
Name: "Mao Guai"
- TamingItem: "Fan_Of_Wind"
EggItem: "Civil_Servant_Egg"
- AccessoryItem: "Golden_Earing"
+ TamingItem: "Fan_Of_Wind"
FoodItem: "Flavored_Alcohol"
- CaptureRate: 500
+ AccessoryItem: "Golden_Earing"
+ HungerDecrement: 3
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxSP, 15);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus(bMaxSP, 10);
">
},
{
Id: 1519
Name: "Green Maiden"
- TamingItem: "Tantanmen"
EggItem: "Chung_E_Egg"
+ TamingItem: "Tantanmen"
FoodItem: "Bun_"
+ HungerDecrement: 3
Intimacy: {
FeedIncrement: 50
}
CaptureRate: 2000
PetScript: <" petskillattack("CR_SHIELDCHARGE", 5, 0, 5, 5); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bDef, 2);
+ bonus2(bAddRaceTolerance, RC_DemiPlayer, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
bonus(bDef, 1);
bonus2(bAddRaceTolerance, RC_DemiPlayer, 1);
}
@@ -1121,40 +1349,49 @@ pet_db:(
{
Id: 1586
Name: "Leaf Cat"
- TamingItem: "Very_Soft_Plant"
EggItem: "Leaf_Cat_Egg"
- AccessoryItem: "Green_Lucky_Bag"
+ TamingItem: "Very_Soft_Plant"
FoodItem: "Fish_With_Blue_Back"
+ AccessoryItem: "Green_Lucky_Bag"
+ HungerDecrement: 7
Intimacy: {
FeedIncrement: 20
}
- CaptureRate: 200
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus2(bAddRaceTolerance, RC_Brute, 5);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
bonus2(bAddRaceTolerance, RC_Brute, 3);
">
},
{
Id: 1630
Name: "White Lady"
- TamingItem: "Shiny_Wing_Gown"
EggItem: "Bacsojin_Egg"
- AccessoryItem: "Round_Hair_Ornament"
+ TamingItem: "Shiny_Wing_Gown"
FoodItem: "Traditional_Cookie"
- CaptureRate: 2000
+ AccessoryItem: "Round_Hair_Ornament"
+ HungerDecrement: 7
+ CaptureRate: 300
},
{
Id: 1837
Name: "Fire Imp"
- TamingItem: "Flaming_Ice"
EggItem: "Imp_Egg"
- AccessoryItem: "Horn_Protector"
+ TamingItem: "Flaming_Ice"
FoodItem: "Flame_Gemstone"
- CaptureRate: 200
+ AccessoryItem: "Horn_Protector"
+ HungerDecrement: 3
+ CaptureRate: 300
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
- bonus2(bSubEle, Ele_Fire, 2);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus2(bSubEle, Ele_Fire, 3);
bonus2(bAddEle, Ele_Fire, 2);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus2(bSubEle, Ele_Fire, 2);
+ bonus2(bAddEle, Ele_Fire, 1);
}
">
},
@@ -1162,18 +1399,32 @@ pet_db:(
{
Id: 2057
Name: "Strange Cramp"
- TamingItem: "Leaf_Cat_Ball"
EggItem: "Mystic_Leaf_Cat_Ball"
- CaptureRate: 50
+ TamingItem: "Leaf_Cat_Ball"
+ FoodEffectiveness: 1
+ HungerDecrement: 0
+ Intimacy: {
+ FeedIncrement: 1
+ OverFeedDecrement: 0
+ OwnerDeathDecrement: 0
+ }
+ CaptureRate: 5000
AttackRate: 350
DefendRate: 400
},
{
Id: 2081
Name: "Strange Hydra"
- TamingItem: "Leaf_Cat_Ball"
EggItem: "Mystic_Leaf_Cat_Ball"
- CaptureRate: 50
+ TamingItem: "Leaf_Cat_Ball"
+ FoodEffectiveness: 1
+ HungerDecrement: 0
+ Intimacy: {
+ FeedIncrement: 1
+ OverFeedDecrement: 0
+ OwnerDeathDecrement: 0
+ }
+ CaptureRate: 5000
AttackRate: 350
DefendRate: 400
},
@@ -1181,21 +1432,35 @@ pet_db:(
{
Id: 2313
Name: "Tikbalang"
- TamingItem: "Tikbalang_Belt"
EggItem: "Tikbalang_Pet"
+ TamingItem: "Tikbalang_Belt"
FoodItem: "Monsters_Feed"
+ HungerDecrement: 8
SpecialPerformance: true
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMdef, 5);
+ bonus2(bAddDamageClass, 2317, 10);
+ bonus2(bAddDamageClass, 2318, 10);
+ bonus2(bAddDamageClass, 2319, 10);
bonus2(bAddDamageClass, 2320, 10);
bonus2(bAddDamageClass, 2321, 10);
bonus2(bAddDamageClass, 2322, 10);
+ bonus2(bAddDamageClass, 2327, 10);
+ bonus2(bAddDamageClass, 2332, 10);
+ bonus2(bAddDamageClass, 2333, 10);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMdef, 3);
bonus2(bAddDamageClass, 2317, 10);
bonus2(bAddDamageClass, 2318, 10);
- bonus2(bAddDamageClass, 2327, 10);
bonus2(bAddDamageClass, 2319, 10);
- bonus2(bAddDamageClass, 2333, 10);
+ bonus2(bAddDamageClass, 2320, 10);
+ bonus2(bAddDamageClass, 2321, 10);
+ bonus2(bAddDamageClass, 2322, 10);
+ bonus2(bAddDamageClass, 2327, 10);
bonus2(bAddDamageClass, 2332, 10);
+ bonus2(bAddDamageClass, 2333, 10);
}
">
},
@@ -1203,10 +1468,10 @@ pet_db:(
{
Id: 1242
Name: "Marin"
- TamingItem: "Juicy_Fruit"
EggItem: "Marin_Egg"
- AccessoryItem: "Tw_Backpack"
+ TamingItem: "Juicy_Fruit"
FoodItem: "Fruit_Sundae"
+ AccessoryItem: "Tw_Backpack"
Intimacy: {
FeedIncrement: 50
}
@@ -1215,7 +1480,7 @@ pet_db:(
},
{
Id: 2200
- Name: "Tiny"
+ Name: "Taini"
EggItem: "Egg_Of_Tiny"
FoodItem: "Apple"
SpecialPerformance: true
@@ -1226,21 +1491,23 @@ pet_db:(
Name: "Little Poring"
TamingItem: "Unripe_Apple2"
EggItem: "Novice_Poring_Egg"
- AccessoryItem: "Backpack"
FoodItem: "Apple_Juice"
+ FoodEffectiveness: 20
+ HungerDecrement: 3
Intimacy: {
- FeedIncrement: 50
+ FeedIncrement: 100
+ StarvingDecrement: 1
}
- CaptureRate: 2000
- SpecialPerformance: true
+ CaptureRate: 1000
AttackRate: 350
DefendRate: 400
PetScript: <" petloot(10); ">
EquipScript: <"
- if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
- bonus(bLuk, 2);
- bonus(bCritical, 1);
- }
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bHPrecovRate, 75);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bHPrecovRate, 50);
">
},
// New Pets [Need Info]
@@ -1249,6 +1516,22 @@ pet_db:(
Name: "Mastering"
EggItem: "Mastering_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bLuk, 3);
+ bonus(bCritical, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bLuk, 3);
+ bonus(bCritical, 2);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bLuk, 3);
+ bonus(bCritical, 1);
+ } else {
+ bonus(bLuk, 2);
+ bonus(bCritical, 1);
+ }
+ ">
Evolve: {
Angeling_Egg: {
Yellow_Potion: 20
@@ -1263,63 +1546,173 @@ pet_db:(
Name: "Angeling"
EggItem: "Angeling_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxHPrate, 2);
+ bonus(bHealPower, 8);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMaxHPrate, 2);
+ bonus(bHealPower, 6);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bMaxHPrate, 1);
+ bonus(bHealPower, 4);
+ } else {
+ bonus(bMaxHPrate, 1);
+ bonus(bHealPower, 2);
+ }
+ ">
},
{
Id: 1301
Name: "Am Mut"
EggItem: "Am_Mut_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMatkRate, 4);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bMatkRate, 3);
+ else if (.@intimacy >= PET_INTIMACY_NEUTRAL)
+ bonus(bMatkRate, 2);
+ else
+ bonus(bMatkRate, 1);
+ ">
},
-/*
{
Id: 3636
Name: "Little Isis"
EggItem: "Little_Isis_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAtkRate, 4);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bAtkRate, 3);
+ else if (.@intimacy >= PET_INTIMACY_NEUTRAL)
+ bonus(bAtkRate, 2);
+ else
+ bonus(bAtkRate, 1);
+ ">
},
-*/
{
Id: 1214
Name: "Choco"
EggItem: "Choco_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bCritical, 9);
+ bonus(bLongAtkRate, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bCritical, 7);
+ bonus(bLongAtkRate, 2);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bCritical, 5);
+ bonus(bLongAtkRate, 1);
+ } else {
+ bonus(bCritical, 3);
+ }
+ ">
},
-/*
{
Id: 3495
Name: "Eggring"
EggItem: "Eggring_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bHit, 9);
+ bonus(bAtk, 9);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bHit, 7);
+ bonus(bAtk, 7);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bHit, 5);
+ bonus(bAtk, 5);
+ } else {
+ bonus(bHit, 3);
+ bonus(bAtk, 3);
+ }
+ ">
},
-*/
{
Id: 1512
Name: "Hyegun"
EggItem: "Hyegun_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bVit, 4);
+ bonus2(bResEff, Eff_Stun, 400);
+ bonus2(bSPDrainRate, 10, 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bVit, 3);
+ bonus2(bResEff, Eff_Stun, 300);
+ bonus2(bSPDrainRate, 10, 1);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bVit, 2);
+ bonus2(bResEff, Eff_Stun, 200);
+ } else {
+ bonus(bVit, 1);
+ bonus2(bResEff, Eff_Stun, 100);
+ }
+ ">
},
-/*
{
Id: 3496
Name: "Leaf Lunatic"
EggItem: "Leaf_Lunatic_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bCritical, 5);
+ bonus(bAtk, 5);
+ bonus2(bAddRace, RC_Formless, 6);
+ bonus2(bMagicAddRace, RC_Formless, 6);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bCritical, 4);
+ bonus(bAtk, 4);
+ bonus2(bAddRace, RC_Formless, 3);
+ bonus2(bMagicAddRace, RC_Formless, 3);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bCritical, 3);
+ bonus(bAtk, 3);
+ } else {
+ bonus(bCritical, 2);
+ bonus(bAtk, 2);
+ }
+ ">
},
-*/
{
Id: 1180
Name: "Nine Tails"
EggItem: "Nine_Tails_Egg"
- AutoFeed: true
+ TamingItem: "Sap_Jelly"
+ FoodItem: "Suspicious_Bottle"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bCritical, 3);
+ bonus(bHit, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bCritical, 2);
+ bonus(bHit, 2);
+ }
+ ">
Evolve: {
-/*
Cat_o_Nine_Tails_Egg: {
- 23187: 3
+ Sap_Jelly: 3
Fox_Tail: 999
Punisher: 1
Nine_Tail_Card: 1
}
-*/
}
},
{
@@ -1327,152 +1720,807 @@ pet_db:(
Name: "Cat o' Nine Tails"
EggItem: "Cat_o_Nine_Tails_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bCritical, 5);
+ bonus(bHit, 5);
+ autobonus("{ bonus2(bHPRegenRate, 400, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bCritical, 4);
+ bonus(bHit, 4);
+ autobonus("{ bonus2(bHPRegenRate, 300, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bCritical, 3);
+ bonus(bHit, 3);
+ } else {
+ bonus(bCritical, 2);
+ bonus(bHit, 2);
+ }
+ ">
Evolve: {
-/*
Moonlight_Flower_Egg: {
- 25375: 30
+ Mightysoul_Essence: 30
Nine_Tail_Card: 10
Sohee_Card: 10
Munak_Card: 10
}
-*/
}
},
-/*
{
Id: 3669
Name: "Diabolic"
EggItem: "Diabolic_Egg_"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAtkRate, 2);
+ bonus(bMatkRate, 2);
+ bonus(bMaxHPrate, 2);
+ bonus(bMaxSPrate, 2);
+ bonus5(bAutoSpell, "MG_FIREBOLT", 3, 50, BF_WEAPON|BF_SHORT, 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bAtkRate, 2);
+ bonus(bMatkRate, 2);
+ bonus(bMaxHPrate, 1);
+ bonus(bMaxSPrate, 1);
+ bonus5(bAutoSpell, "MG_FIREBOLT", 3, 50, BF_WEAPON|BF_SHORT, 1);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bAtkRate, 1);
+ bonus(bMatkRate, 1);
+ bonus(bMaxHPrate, 1);
+ bonus(bMaxSPrate, 1);
+ } else {
+ bonus(bAtkRate, 1);
+ bonus(bMatkRate, 1);
+ }
+ ">
},
-*/
-/*
{
Id: 3670
Name: "Earth Deleter"
EggItem: "Earth_Deleter_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAspdRate, 3);
+ bonus(bAgi, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bAspdRate, 2);
+ bonus(bAgi, 2);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bAspdRate, 1);
+ bonus(bAgi, 1);
+ } else {
+ bonus(bAspdRate, 1);
+ }
+ ">
},
-*/
{
Id: 1622
Name: "Teddy Bear"
EggItem: "Teddy_Bear_Egg"
- AutoFeed: true
+ TamingItem: "SmallDoll_Needle"
+ FoodItem: "Cotton_Tufts"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxSP, 100);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bMaxSP, 50);
+ ">
Evolve: {
-/*
Abandoned_Teddy_Bear_Egg: {
- 23189: 3
+ SmallDoll_Needle: 3
Cursed_Seal: 300
Cardinal_Jewel_: 50
Teddy_Bear_Card: 1
}
-*/
+ Aliot_Egg: {
+ Screw: 500
+ Honey: 100
+ White_Jewel: 10
+ Teddy_Bear_Card: 1
+ }
+ Alicel_Egg: {
+ Screw: 500
+ Honey: 100
+ Bloody_Page: 50
+ Teddy_Bear_Card: 1
+ }
}
},
{
Id: 1632
Name: "Gremlin"
EggItem: "Gremlin_Egg"
- AutoFeed: true
+ TamingItem: "Unprocessed_Parts"
+ FoodItem: "Cheap_Lubricant"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bDex, 2);
+ bonus(bHit, 1);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bDex, 1);
+ bonus(bHit, 1);
+ }
+ ">
Evolve: {
-/*
Hodremlin_Egg: {
- 23188: 3
+ Unprocessed_Parts: 3
Damp_Darkness: 50
Will_Of_Darkness: 200
Hodremlin_Card: 1
}
-*/
}
},
-/*
{
Id: 3731
- Name: "Scatleton Crate"
- EggItem: "Scatleton_Crate"
- AutoFeed: true
+ Name: "Scatleton"
+ EggItem: "Scatelon_Egg"
+ FoodItem: "Delicious_Fish"
+ AccessoryItem: "Red_Bell_Necklace"
+ EquipScript: <"
+ if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_CORDIAL)
+ bonus2(bAddItemHealRate, 579, 100);
+ ">
+ Evolve: {
+ Skelion_Egg: {
+ Memory_Of_Gyol: 2
+ Yummy_Meat: 100
+ Cookie_Bat: 100
+ }
+ }
},
-*/
{
Id: 1041
Name: "Mummy"
EggItem: "Mummy_Egg"
- AutoFeed: true
+ TamingItem: "Elixir_Bandage"
+ FoodItem: "Mementos"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bHit, 5);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bHit, 4);
+ ">
Evolve: {
-/*
Ancient_Mummy_Egg: {
- 23256: 3
+ Elixir_Bandage: 3
Rune_Of_Darkness: 200
Gold: 30
Ancient_Mummy_Card: 1
}
-*/
}
},
{
Id: 1010
Name: "Willow"
EggItem: "Willow_Egg"
- AutoFeed: true
+ TamingItem: "Dew_Of_Old_Tree"
+ FoodItem: "Tree_Of_Archer_1"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bInt, 3);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bInt, 2);
+ ">
},
{
Id: 1782
Name: "Roween"
EggItem: "Roween_Egg"
- AutoFeed: true
+ TamingItem: "Foul_Rotten_Meat"
+ FoodItem: "Rotten_Meat"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus2(bMagicAtkEle, Ele_Wind, 3);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus2(bMagicAtkEle, Ele_Wind, 2);
+ ">
},
{
Id: 1773
Name: "Hodremlin"
EggItem: "Hodremlin_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bDex, 2);
+ bonus(bHit, 2);
+ bonus(bCritAtkRate, 9);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bDex, 2);
+ bonus(bHit, 2);
+ bonus(bCritAtkRate, 7);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bDex, 2);
+ bonus(bHit, 1);
+ } else {
+ bonus(bDex, 1);
+ bonus(bHit, 1);
+ }
+ ">
+ Evolve: {
+ Gloom_Under_Night_Egg: {
+ Hodremlin_Card: 10
+ Isilla_Card: 10
+ Agav_Card: 10
+ Mightysoul_Essence: 30
+ }
+ }
},
{
Id: 1058
Name: "Metaller"
EggItem: "Metaller_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bHPrecovRate, 20);
+ bonus(bMaxHP, 70);
+ bonus2(bAddRace, RC_Plant, 6);
+ bonus2(bMagicAddRace, RC_Plant, 6);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bHPrecovRate, 15);
+ bonus(bMaxHP, 55);
+ bonus2(bAddRace, RC_Plant, 3);
+ bonus2(bMagicAddRace, RC_Plant, 3);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bHPrecovRate, 10);
+ bonus(bMaxHP, 38);
+ } else {
+ bonus(bHPrecovRate, 5);
+ bonus(bMaxHP, 25);
+ }
+ ">
},
{
Id: 1297
Name: "Ancient Mummy"
EggItem: "Ancient_Mummy_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bHit, 6);
+ bonus2(bAddRace, RC_Dragon, 6);
+ bonus2(bMagicAddRace, RC_Dragon, 6);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bHit, 6);
+ bonus2(bAddRace, RC_Dragon, 3);
+ bonus2(bMagicAddRace, RC_Dragon, 3);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bHit, 5);
+ } else {
+ bonus(bHit, 4);
+ }
+ ">
},
-/*{
+{
Id: 2995
Name: "Abandoned Teddy Bear"
EggItem: "Abandoned_Teddy_Bear_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxSP, 150);
+ autobonus("{ bonus2(bSPRegenRate, 40, 1000); }", 30, 5000, BF_MAGIC);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMaxSP, 150);
+ autobonus("{ bonus2(bSPRegenRate, 30, 1000); }", 30, 5000, BF_MAGIC);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bMaxSP, 100);
+ } else {
+ bonus(bMaxSP, 50);
+ }
+ ">
},
-*/
-/* UNKNOWN MONSTER
{
- Id: 0
+ Id: 3790
Name: "Sweet Drops"
EggItem: "Sweet_Drops_Egg"
+ FoodItem: "Candy"
AutoFeed: true
+ EquipScript: <"
+ if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL)
+ bonus2(bExpAddRace, RC_All, 1);
+ ">
},
-*/
{
- Id: 1159
+ Id: 20425
Name: "Phreeoni"
EggItem: "Phreeoni_Egg"
+ FoodItem: "Luxurious_Pet_Food"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bHit, 18);
+ bonus(bPerfectHitRate, 15);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bHit, 14);
+ bonus(bPerfectHitRate, 10);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bHit, 10);
+ bonus(bPerfectHitRate, 5);
+ } else {
+ bonus(bHit, 6);
+ }
+ ">
},
{
- Id: 1150
+ Id: 20424
Name: "Moonlight Flower"
EggItem: "Moonlight_Flower_Egg"
+ FoodItem: "Luxurious_Pet_Food"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bCritical, 6);
+ bonus(bHit, 6);
+ autobonus("{ bonus2(bHPRegenRate, 500, 1000); bonus2(bSPRegenRate, 20, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bCritical, 5);
+ bonus(bHit, 5);
+ autobonus("{ bonus2(bHPRegenRate, 400, 1000); bonus2(bSPRegenRate, 10, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bCritical, 4);
+ bonus(bHit, 4);
+ autobonus("{ bonus2(bHPRegenRate, 300, 1000); }", 20, 5000, BF_WEAPON|BF_SHORT);
+ } else {
+ bonus(bCritical, 3);
+ bonus(bHit, 3);
+ }
+ ">
},
-/*
{
Id: 3971
Name: "Skelion"
EggItem: "Skelion_Egg"
+ FoodItem: "Yummy_Meat"
+ AccessoryItem: "Dark_Mane"
+ AutoFeed: true
+ EquipScript: <"
+ if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_CORDIAL)
+ bonus2(bAddItemHealRate, 579, 100);
+ ">
+},
+{
+ Id: 2336
+ Name: "Domovoi"
+ EggItem: "Brownie_Egg"
+ EquipScript: <"
+ if (getpetinfo(PETINFO_INTIMACY) >= PET_INTIMACY_LOYAL) {
+ bonus2(bAddRace, RC_DemiPlayer, 1);
+ bonus2(bMagicAddRace, RC_DemiPlayer, 1);
+ bonus2(bAddRaceTolerance, RC_DemiPlayer, 1);
+ }
+ ">
+},
+{
+ Id: 2963
+ Name: "Woodie"
+ EggItem: "Woodie_Egg"
+ FoodItem: "Emerald_Leaf"
+},
+{
+ Id: 3162
+ Name: "Elephant"
+ EggItem: "Elephant_Egg"
+ FoodItem: "Banana_Can"
+},
+{
+ Id: 3163
+ Name: "Gorilla"
+ EggItem: "Gorilla_Egg"
+ FoodItem: "Spicy_Rice_Cake"
+},
+{
+ Id: 3164
+ Name: "Lion"
+ EggItem: "Lion_Egg"
+ FoodItem: "Hot_Dog"
+},
+{
+ Id: 3165
+ Name: "Rhino"
+ EggItem: "Rhino_Egg"
+ FoodItem: "Ferris_Wheel_Biscuit"
+},
+{
+ Id: 3261
+ Name: "Blue Unicorn"
+ EggItem: "Blue_Unicorn_Egg"
+ FoodItem: "Blue_Herb"
+},
+{
+ Id: 1166
+ Name: "Savage"
+ EggItem: "Savage_Egg"
AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bVit, 2);
+ bonus(bMaxHP, 200);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bVit, 2);
+ bonus(bMaxHP, 100);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bVit, 2);
+ bonus(bMaxHP, 50);
+ } else {
+ bonus(bVit, 1);
+ bonus(bMaxHP, 50);
+ }
+ ">
+},
+{
+ Id: 1369
+ Name: "Grand Peco"
+ EggItem: "Grand_Peco_Peco_Egg"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxHP, 400);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bMaxHP, 300);
+ else if (.@intimacy >= PET_INTIMACY_NEUTRAL)
+ bonus(bMaxHP, 200);
+ else
+ bonus(bMaxHP, 150);
+ ">
+},
+{
+ Id: 1213
+ Name: "High Orc"
+ EggItem: "High_Orc_Egg"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAtk, 25);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bAtk, 20);
+ else if (.@intimacy >= PET_INTIMACY_NEUTRAL)
+ bonus(bAtk, 15);
+ else
+ bonus(bAtk, 10);
+ ">
+ Evolve: {
+ Orc_Hero_Egg_: {
+ Voucher_Of_Orcish_Hero: 10
+ Orc_Warrior_Card: 10
+ Orc_Baby_Card_Card: 10
+ Mightysoul_Essence: 30
+ }
+ }
+},
+{
+ Id: 20423
+ Name: "Bacsojin"
+ EggItem: "Bacsojin2_Egg_"
+ FoodItem: "Luxurious_Pet_Food"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxSPrate, 5);
+ bonus(bDelayrate, -3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMaxSPrate, 4);
+ bonus(bDelayrate, -2);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bMaxSPrate, 3);
+ bonus(bDelayrate, -1);
+ } else {
+ bonus(bMaxSPrate, 2);
+ }
+ ">
+},
+{
+ Id: 20373
+ Name: "Rigid Nightmare Terror"
+ EggItem: "Rigid_Nightmare_Terror_Egg"
+ FoodItem: "Luxurious_Pet_Food"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bInt, 4);
+ bonus(bMaxSPrate, 3);
+ bonus2(bResEff, Eff_Sleep, 10000);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bInt, 3);
+ bonus(bMaxSPrate, 1);
+ bonus2(bResEff, Eff_Sleep, 10000);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bInt, 2);
+ } else {
+ bonus(bInt, 1);
+ }
+ ">
+},
+{
+ Id: 20420
+ Name: "Contaminated Wanderer Egg"
+ EggItem: "Contaminated_Wanderer_Egg"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAgi, 4);
+ bonus(bCritical, 3);
+ bonus(bCritAtkRate, 7);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bAgi, 4);
+ bonus(bCritical, 2);
+ bonus(bCritAtkRate, 5);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bAgi, 4);
+ bonus(bCritical, 1);
+ } else {
+ bonus(bAgi, 4);
+ }
+ ">
+},
+{
+ Id: 1736
+ Name: "Aliot"
+ EggItem: "Aliot_Egg"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAspdRate, 5);
+ bonus(bHit, 12);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bAspdRate, 4);
+ bonus(bHit, 9);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bAspdRate, 3);
+ bonus(bHit, 6);
+ } else {
+ bonus(bAspdRate, 2);
+ }
+ ">
+},
+{
+ Id: 1735
+ Name: "Alicel"
+ EggItem: "Alicel_Egg"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bVariableCastrate, -5);
+ bonus2(bMagicAddEle, Ele_Neutral, 5);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bVariableCastrate, -4);
+ bonus2(bMagicAddEle, Ele_Neutral, 3);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bVariableCastrate, -3);
+ } else {
+ bonus(bVariableCastrate, -2);
+ }
+ ">
+},
+{
+ Id: 1737
+ Name: "Aliza"
+ EggItem: "Aliza_Egg"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMdef, 7);
+ bonus(bHealPower, 6);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMdef, 6);
+ bonus(bHealPower, 4);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bMdef, 5);
+ bonus(bHealPower, 2);
+ } else {
+ bonus(bMdef, 4);
+ }
+ ">
+},
+{
+ Id: 20571
+ Name: "Orc Hero"
+ EggItem: "Orc_Hero_Egg_"
+ FoodItem: "Luxurious_Pet_Food"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bAtkRate, 7);
+ bonus(bCritAtkRate, 3);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bAtkRate, 4);
+ bonus(bCritAtkRate, 1);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bAtkRate, 2);
+ } else {
+ bonus(bAtkRate, 1);
+ }
+ ">
+},
+{
+ Id: 20619
+ Name: "Gloom Under Night"
+ EggItem: "Gloom_Under_Night_Egg"
+ FoodItem: "Luxurious_Pet_Food"
+ AutoFeed: true
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMatk, 40);
+ bonus2(bMagicAtkEle, Ele_Ghost, 7);
+ bonus2(bMagicAtkEle, Ele_Fire, 7);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMatk, 30);
+ bonus2(bMagicAtkEle, Ele_Ghost, 5);
+ bonus2(bMagicAtkEle, Ele_Fire, 5);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus(bMatk, 20);
+ } else {
+ bonus(bMatk, 10);
+ }
+ ">
+},
+{
+ Id: 20696
+ Name: "Child Admin Beta"
+ EggItem: "Child_Admin_Beta_Egg"
+ FoodItem: "Cloud_Cotton"
+ AccessoryItem: "Little_Headdress_Beta"
+ EquipScript: <"
+ .@map$ = strcharinfo(PC_MAP);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@map$ == "ba_lost" || .@map$ == "ba_pw02") {
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus2(bAddRace, RC_All, 10);
+ bonus2(bMagicAddRace, RC_All, 10);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus2(bAddRace, RC_All, 6);
+ bonus2(bMagicAddRace, RC_All, 6);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus2(bAddRace, RC_All, 3);
+ bonus2(bMagicAddRace, RC_All, 3);
+ }
+ }
+ ">
+ Evolve: {
+ Child_Admin_Alpha_Egg: {
+ Barmil_Ticket: 500
+ Broken_Steel_Piece: 50
+ Mystery_Piece: 10
+ }
+ }
+},
+{
+ Id: 20697
+ Name: "Child Admin Alpha"
+ EggItem: "Child_Admin_Alpha_Egg"
+ AccessoryItem: "Little_Headdress_Alpha"
+ AutoFeed: true
+ EquipScript: <"
+ .@map$ = strcharinfo(PC_MAP);
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@map$ == "ba_pw01" || .@map$ == "ba_pw03" || .@map$ == "ba_2whs01" || .@map$ == "ba_2whs02") {
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus2(bAddRace, RC_All, 15);
+ bonus2(bMagicAddRace, RC_All, 15);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus2(bAddRace, RC_All, 8);
+ bonus2(bMagicAddRace, RC_All, 8);
+ } else if (.@intimacy >= PET_INTIMACY_NEUTRAL) {
+ bonus2(bAddRace, RC_All, 4);
+ bonus2(bMagicAddRace, RC_All, 4);
+ }
+ }
+ ">
+},
+// jRO exclusive pets.
+{
+ Id: 3317
+ Name: "Rubylit"
+ EggItem: "Rubylit_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAtk, 20);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bAtk, 10);
+ ">
+},
+{
+ Id: 3318
+ Name: "Sapphilit"
+ EggItem: "Sapphilit_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxHP, 200);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bMaxHP, 100);
+ ">
+},
+{
+ Id: 3319
+ Name: "Emelit"
+ EggItem: "Emelit_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL) {
+ bonus(bMaxHP, 100);
+ bonus(bMaxSP, 50);
+ } else if (.@intimacy >= PET_INTIMACY_CORDIAL) {
+ bonus(bMaxHP, 50);
+ bonus(bMaxSP, 25);
+ }
+ ">
+},
+{
+ Id: 3320
+ Name: "Topalit"
+ EggItem: "Topalit_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMaxSP, 100);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bMaxSP, 50);
+ ">
+},
+{
+ Id: 3321
+ Name: "Amelit"
+ EggItem: "Amelit_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bMatk, 20);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bMatk, 10);
+ ">
+},
+{
+ Id: 3349
+ Name: "Mythlit"
+ EggItem: "Mythlit_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ bonus(bAllStats, 2);
+ else if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus(bAllStats, 1);
+ ">
+},
+{
+ Id: 3306
+ Name: "Tamadora"
+ EggItem: "Tamadora_Egg"
+ EquipScript: <"
+ .@intimacy = getpetinfo(PETINFO_INTIMACY);
+ if (.@intimacy >= PET_INTIMACY_CORDIAL)
+ bonus4(bAutoSpellWhenHit, AL_HEAL, 1, 20, 1);
+ if (.@intimacy >= PET_INTIMACY_LOYAL)
+ skill(AL_HEAL, 1);
+ ">
},
-*/
)
diff --git a/doc/constants.md b/doc/constants.md
index f0c7f50c8..09ff61381 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -375,9 +375,13 @@
- `cell_landprotector`: 5
- `cell_novending`: 6
- `cell_nochat`: 7
+- `cell_icewall`: 8
+- `cell_noicewall`: 9
+- `cell_noskill`: 10
### Cell checks
+- `cell_gettype`: 0
- `cell_chkwall`: 1
- `cell_chkwater`: 2
- `cell_chkcliff`: 3
@@ -385,11 +389,15 @@
- `cell_chkreach`: 5
- `cell_chknopass`: 6
- `cell_chknoreach`: 7
+- `cell_chkstack`: 8
- `cell_chknpc`: 9
- `cell_chkbasilica`: 10
- `cell_chklandprotector`: 11
- `cell_chknovending`: 12
- `cell_chknochat`: 13
+- `cell_chkicewall`: 14
+- `cell_chknoicewall`: 15
+- `cell_chknoskill`: 16
### Bonuses / Parameter IDs
@@ -5105,6 +5113,12 @@
- `MST_AROUND4`: 12
- `MST_AROUND`: 12
+### Monster group constants
+
+- `ALL_MOBS_NONBOSS`: -1
+- `ALL_MOBS_BOSS`: -2
+- `ALL_MOBS`: -3
+
### pc block constants, use with *setpcblock* and *checkpcblock*
- `PCBLOCK_NONE`: 0
@@ -8187,17 +8201,48 @@
- `FATAL_DAYS`: 2958
- `TORTUROUS_REDEEMER`: 2959
- `E_TORTUROUS_REDEEMER`: 2961
+- `WOODIE`: 2963
+- `XM_TEDDY_BEAR`: 2995
- `XM_CELINE_KIMI`: 2996
- `GRIM_REAPER_ANKOU`: 3029
- `TIMEHOLDER`: 3074
+- `ELEPHANT`: 3162
+- `GORILLA`: 3163
+- `LION`: 3164
+- `RHINO`: 3165
- `J_REB_SHECIL1`: 3169
- `J_REB_SHECIL2`: 3170
- `E1_FELOCK`: 3181
- `MM_SARAH`: 3190
- `ORGANIC_JAKK`: 3202
- `INORGANIC_JAKK`: 3203
+- `BLUE_UNICORN`: 3261
+- `PAD_TAMADORA`: 3306
+- `PAD_RUBYLIT`: 3317
+- `PAD_SAPPHILIT`: 3318
+- `PAD_EMELIT`: 3319
+- `PAD_TOPALIT`: 3320
+- `PAD_AMELIT`: 3321
+- `PAD_MYTHLIT`: 3349
- `DARK_SOUL`: 3381
- `WANDERING_SOUL`: 3382
+- `DR_EGGRING`: 3495
+- `DR_LUNATIC`: 3496
+- `LITTLE_ISIS`: 3636
+- `DIABOLIC2`: 3669
+- `DELETER_2`: 3670
+- `SCATLETON`: 3731
+- `SWEETS_DROPS`: 3790
+- `SKELION`: 3971
+- `NIGHTMARE_TERROR_H`: 20373
+- `WANDER_MAN_H`: 20420
+- `BACSOJIN2`: 20423
+- `MOONLIGHT2`: 20424
+- `PHREEONI2`: 20425
+- `ORK_HERO2`: 20571
+- `GLOOMUNDERNIGHT2`: 20619
+- `EP17_2_CHILD_ADMIN1`: 20696
+- `EP17_2_CHILD_ADMIN2`: 20697
## Items (db/re/item_db.conf)
- `Red_Potion`: 501
@@ -12726,6 +12771,8 @@
- `Memory_Of_Jack`: 6657
- `Halloween_Coin`: 6658
- `RWC_Inicializer`: 6665
+- `Emerald_Leaf`: 6669
+- `Log_`: 6670
- `Geffen_Magic_Coin`: 6671
- `Gray_Shard`: 6672
- `Bossnia_Pass`: 6673
@@ -12737,6 +12784,10 @@
- `Steel_Article`: 6746
- `Steel_Article_`: 6747
- `Corrupted_Charm`: 6755
+- `Banana_Can`: 6762
+- `Spicy_Rice_Cake`: 6763
+- `Hot_Dog`: 6764
+- `Ferris_Wheel_Biscuit`: 6765
- `ORGANIC_PUMPKIN`: 6804
- `INORGANIC_PUMPKIN`: 6805
- `Solo_Troops_Badge`: 6821
@@ -13750,9 +13801,22 @@
- `Brownie_Egg`: 9060
- `Marin_Egg`: 9061
- `Novice_Poring_Egg`: 9062
+- `Woodie_Egg`: 9063
+- `Elephant_Egg`: 9064
+- `Gorilla_Egg`: 9065
+- `Lion_Egg`: 9066
+- `Rhino_Egg`: 9067
+- `Blue_Unicorn_Egg`: 9068
- `Mastering_Egg`: 9069
- `Savage_Egg`: 9070
- `Grand_Peco_Peco_Egg`: 9071
+- `Rubylit_Egg`: 9074
+- `Sapphilit_Egg`: 9075
+- `Emelit_Egg`: 9076
+- `Topalit_Egg`: 9077
+- `Amelit_Egg`: 9078
+- `Mythlit_Egg`: 9079
+- `Tamadora_Egg`: 9080
- `High_Orc_Egg`: 9087
- `Angeling_Egg`: 9088
- `Am_Mut_Egg`: 9089
@@ -13779,6 +13843,16 @@
- `Phreeoni_Egg`: 9111
- `Moonlight_Flower_Egg`: 9112
- `Skelion_Egg`: 9113
+- `Bacsojin2_Egg_`: 9115
+- `Rigid_Nightmare_Terror_Egg`: 9116
+- `Contaminated_Wanderer_Egg`: 9117
+- `Aliot_Egg`: 9118
+- `Alicel_Egg`: 9119
+- `Aliza_Egg`: 9120
+- `Orc_Hero_Egg_`: 9121
+- `Gloom_Under_Night_Egg`: 9122
+- `Child_Admin_Beta_Egg`: 9123
+- `Child_Admin_Alpha_Egg`: 9124
- `Ein_Ddbox`: 9514
- `Metal_Rifine_Ticket`: 9523
- `Ein_Ddbox2`: 9529
@@ -13823,7 +13897,10 @@
- `Black_Butterfly_Mask`: 10037
- `Horn_Protector`: 10038
- `Tw_Backpack`: 10039
+- `Red_Bell_Necklace`: 10040
- `Dark_Mane`: 10042
+- `Little_Headdress_Beta`: 10043
+- `Little_Headdress_Alpha`: 10044
- `Prontera_Book_01`: 11000
- `Adventure_Story01`: 11001
- `Great_Chef_Orleans01`: 11002
@@ -13947,6 +14024,7 @@
- `Trance_Candy_Y`: 11594
- `Trance_Candy_G`: 11595
- `Catnip_Fruit`: 11602
+- `Cookie_Bat`: 11605
- `Crepe`: 11607
- `Chocolate_Egg`: 11608
- `Yummy_Cookie_Egg`: 11609
@@ -13954,6 +14032,7 @@
- `Aromatic_Pop_Corn`: 11612
- `Fresh_Milk`: 11614
- `Sweet_Potato_`: 11615
+- `Yummy_Meat`: 11616
- `Bearopy`: 11620
- `Aromatic_Pop_Corn_`: 11625
- `Girl_Bunch_Of_Flower`: 11701
@@ -18170,6 +18249,9 @@
- `Integer_Time`: 22837
- `Something_Candy_Holder`: 22838
- `Old_Money_Pocket`: 22876
+- `Sap_Jelly`: 23187
+- `Unprocessed_Parts`: 23188
+- `SmallDoll_Needle`: 23189
- `Fried_Chicken`: 23242
- `Fried_Chicken_1`: 23243
- `Elixir_Bandage`: 23256
@@ -18823,6 +18905,9 @@
- `S_Genesis_Pendant`: 24582
- `S_Genesis_Earing`: 24583
- `Slug_Bullet`: 25187
+- `Suspicious_Bottle`: 25231
+- `Cheap_Lubricant`: 25232
+- `Cotton_Tufts`: 25233
- `BrokenArrow`: 25258
- `Shining_Spore`: 25265
- `Dried_Leaf_Of_Ygg`: 25266
@@ -18832,6 +18917,7 @@
- `Happiness_Clover`: 25295
- `Golden_Corn`: 25340
- `Mightysoul_Essence`: 25375
+- `Luxurious_Pet_Food`: 25377
- `Captured_Savage`: 25390
- `Goodly_Bough`: 25391
- `Free_Pass_Ticket`: 25392
@@ -18983,6 +19069,8 @@
- `Ein_1HWHIP`: 26215
- `Faceworm_Queen_Card`: 27164
- `Captain_Felock_Card`: 27182
+- `Rigid_Nightmare_Terror_Card`: 27352
+- `Contaminated_Wanderer_Card`: 27361
- `Thanos_Katar`: 28000
- `Katar_Of_Evil_Slayer`: 28001
- `Half_BF_Katar2`: 28002
@@ -19130,6 +19218,7 @@
- `GH_Cursed_Crystal_`: 29590
- `Cursed_Emerald`: 29591
- `Shinee_Opal`: 29592
+- `Abandoned_Teddy_Bear_Card`: 31022
- `Roast_Memory`: 31172
- `C_Black_Cat`: 31186
- `Choco_Minihat`: 31195
@@ -19313,6 +19402,7 @@
- `Imperial_Trip_Suit`: 450074
- `ILL_Piece_B`: 100004
- `Imperial_Firerain_Suit`: 450075
+- `Cloud_Cotton`: 1000227
- `Imperial_Crimson_Robe`: 450076
- `Imperial_Frost_Robe`: 450077
- `Imperial_Psychic_Robe`: 450078
@@ -19435,6 +19525,7 @@
- `Boost_Gatling`: 830000
- `Abyss_Ddbox3`: 100144
- `Abyss_Ddbox4`: 100145
+- `Barmil_Ticket`: 1000103
> End of list
diff --git a/doc/mob_skill_db.md b/doc/mob_skill_db.md
new file mode 100644
index 000000000..12d3649de
--- /dev/null
+++ b/doc/mob_skill_db.md
@@ -0,0 +1,223 @@
+# Monster skill database
+
+<!--
+## Copyright
+> This file is part of Hercules.
+> http://herc.ws - http://github.com/HerculesWS/Hercules
+>
+> Copyright (C) 2020 Hercules Dev Team
+> Copyright (C) Zarbony
+> Copyright (C) Kenpachi
+>
+> Hercules is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+>
+> This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+> See the GNU General Public License for more details.
+>
+> You should have received a copy of the GNU General Public License along with this program.
+> If not, see <http://www.gnu.org/licenses/>.
+-->
+
+## Description
+This file is a documentation for the monster skill database files.
+ * [db/mob_skill_db2.conf](../db/mob_skill_db2.conf)
+ * [db/pre-re/mob_skill_db.conf](../db/pre-re/mob_skill_db.conf)
+ * [db/re/mob_skill_db.conf](../db/re/mob_skill_db.conf)
+
+--------------------------------------------------------------
+
+## Entry structure
+```
+ <Monster_Constant>: {
+ <Skill_Constant>: {
+ ClearSkills:
+ SkillLevel:
+ SkillState:
+ SkillTarget:
+ Rate:
+ CastTime:
+ Delay:
+ Cancelable:
+ CastCondition:
+ ConditionData:
+ val0:
+ val1:
+ val2:
+ val3:
+ val4:
+ Emotion:
+ ChatMsgID:
+ }
+ }
+```
+
+--------------------------------------------------------------
+
+## Field list
+
+Name | Data type | Default value
+:--------------- | :-------- | :------------
+Monster_Constant | constant | No default value
+Skill_Constant | constant | No default value
+ClearSkills | boolean | false
+SkillLevel | int | 1
+SkillState | string | "MSS_ANY"
+SkillTarget | string | "MST_TARGET"
+Rate | int | 1
+CastTime | int | 0
+Delay | int | 0
+Cancelable | boolean | false
+CastCondition | string | "MSC_ALWAYS"
+ConditionData | int | 0
+val0 | int | 0
+val1 | int | 0
+val2 | int | 0
+val3 | int | 0
+val4 | int | 0
+Emotion | int | -1
+ChatMsgID | int | 0
+
+--------------------------------------------------------------
+
+## Field explanation
+
+### Monster_Constant
+The monster's name constant, found in [mob_db.conf](../db/re/mob_db.conf) as *SpriteName*.
+There are 3 special constants for global skill assignment:
+* `ALL_MOBS`: Add skills to all monsters.
+* `ALL_MOBS_BOSS`: Add skills to all boss monsters.
+* `ALL_MOBS_NONBOSS`: Add skills to all non-boss monsters.
+
+### Skill_Constant
+The skill's name constant, found in [skill_db.conf](../db/re/skill_db.conf) as *Name*.
+Note: You can add multiple Skill_Constant blocks.
+
+### ClearSkills
+If set to `true`, all previously defined skills for this monster will be removed.
+
+### SkillLevel
+The skill level which should be used.
+Minimum value is `1`. Maximum value is `mob_max_skilllvl` from [conf/map/battle/skill.conf](../conf/map/battle/skill.conf#L318).
+
+### SkillState
+Defines in which state the monster is able to cast the skill.
+State | Description
+:------------ | :----------
+MSS_ANY | Monster is in any state except `MSS_DEAD`.
+MSS_IDLE | Monster has no target and isn't walking.
+MSS_WALK | Monster is walking.
+MSS_LOOT | Monster is looting or walking to loot.
+MSS_DEAD | Monster is dying.
+MSS_BERSERK | Monster is attacking after starting the battle.
+MSS_ANGRY | Monster is attacking after being attacked.
+MSS_RUSH | Monster is following an enemy after being attacked.
+MSS_FOLLOW | Monster is following an enemy without being attacked.
+MSS_ANYTARGET | Same as `MSS_ANY` but monster must have a target.
+
+### SkillTarget
+Defines the skill's target.
+Target | Description
+:---------- | :----------
+MST_TARGET | The monster's current target.
+MST_RANDOM | A random enemy within skill range.
+MST_SELF | The monster itself.
+MST_FRIEND | A random friend within skill range. If no friend was found, `MST_SELF` is used.
+MST_MASTER | The monster's master. If no master was found, `MST_FRIEND` is used.
+MST_AROUND1 | Random cell within a range of `1`. (Affects ground skills only.)
+MST_AROUND2 | Random cell within a range of `2`. (Affects ground skills only.)
+MST_AROUND3 | Random cell within a range of `3`. (Affects ground skills only.)
+MST_AROUND4 | Random cell within a range of `4`. (Affects ground skills only.)
+MST_AROUND5 | Same as `MST_AROUND1`, but the monster's current target must be in skill range.
+MST_AROUND6 | Same as `MST_AROUND2`, but the monster's current target must be in skill range.
+MST_AROUND7 | Same as `MST_AROUND3`, but the monster's current target must be in skill range.
+MST_AROUND8 | Same as `MST_AROUND4`, but the monster's current target must be in skill range.
+MST_AROUND | Same as `MST_AROUND4`.
+
+### Rate
+The chance of successfully casting the skill if the condition is fulfilled. (10000 = 100%)
+Minimum value is `1`. Maximum value is `10000`.
+
+### CastTime
+The skill's cast time in milliseconds.
+Minimum value is `0`. Maximum value is `MOB_MAX_CASTTIME` from [src/map/mob.c](../src/map/mob.c#L81).
+
+### Delay
+The time in milliseconds before attempting to cast the same skill again.
+Minimum value is `0`. Maximum value is `MOB_MAX_DELAY` from [src/map/mob.c](../src/map/mob.c#L82).
+
+### Cancelable
+Defines whether the skill is cancelable or not.
+
+### CastCondition
+Defines the condition to successfully cast the skill.
+Condition | Description
+:-------------------- | :----------
+MSC_ALWAYS | No condition.
+MSC_MYHPLTMAXRATE | Monster's HP in percent is less than or equal to `ConditionData`.
+MSC_MYHPINRATE | Monster's HP in percent is greater than or equal to `ConditionData` and less than or equal to `val0`.
+MSC_FRIENDHPLTMAXRATE | Friend's HP in percent is less than or equal to `ConditionData`.
+MSC_FRIENDHPINRATE | Friend's HP in percent is greater than or equal to `ConditionData` and less than or equal to `val0`.
+MSC_MYSTATUSON | Monster has status change `ConditionData` enabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.)
+MSC_MYSTATUSOFF | Monster has status change `ConditionData` disabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.)
+MSC_FRIENDSTATUSON | Friend has status change `ConditionData` enabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.)
+MSC_FRIENDSTATUSOFF | Friend has status change `ConditionData` disabled. (See [doc/constants.md](./constants.md#Status-Changes) for a list of available status changes.)
+MSC_ATTACKPCGT | Monster is attacked by more than `ConditionData` units.
+MSC_ATTACKPCGE | Monster is attacked by `ConditionData` or more units.
+MSC_SLAVELT | Monster has less than `ConditionData` slaves.
+MSC_SLAVELE | Monster has `ConditionData` or less active slaves.
+MSC_CLOSEDATTACKED | Monster is melee attacked.
+MSC_LONGRANGEATTACKED | Monster is range attacked.
+MSC_AFTERSKILL | Monster has used skill `ConditionData`. (If `ConditionData` is `0`, all skills are triggered.)
+MSC_SKILLUSED | Skill `ConditionData` was used on the monster. (If `ConditionData` is `0`, all skills are triggered.)
+MSC_CASTTARGETED | A skill is being cast on the monster.
+MSC_RUDEATTACKED | Monster was rude attacked `RUDE_ATTACKED_COUNT` times. ([src/map/mob.c#L84](../src/map/mob.c))
+MSC_MASTERHPLTMAXRATE | The monster master's HP in percent is less than `ConditionData`.
+MSC_MASTERATTACKED | The monster's master is attacked.
+MSC_ALCHEMIST | The monster was summoned by an Alchemist class character.
+MSC_SPAWN | The monster spawns.
+
+### ConditionData
+Additional cast condition data. Meaning depends on the situation. See `CastCondition` table.
+
+### val0
+Additional data. Meaning depends on the situation.
+ * `MSC_MYHPINRATE`/`MSC_FRIENDHPINRATE`: See `CastCondition` table.
+ * `NPC_SUMMONMONSTER`: Slave monster ID.
+ * `NPC_SUMMONSLAVE`: Slave monster ID.
+ * `NPC_METAMORPHOSIS`: Transform monster ID.
+ * `NPC_EMOTION`: Emotion ID. (See [doc/constants.md](./constants.md#emotes) for a list of available emotions.)
+ * `NPC_EMOTION_ON`: Emotion ID. (See [doc/constants.md](./constants.md#emotes) for a list of available emotions.)
+
+### val1
+Additional data. Meaning depends on the situation.
+ * `NPC_SUMMONMONSTER`: Slave monster ID.
+ * `NPC_SUMMONSLAVE`: Slave monster ID.
+ * `NPC_METAMORPHOSIS`: Transform monster ID.
+ * `NPC_EMOTION`: Monster's mode is changed to specified value.
+ * `NPC_EMOTION_ON`: Monster's mode is changed to specified value.
+
+### val2
+Additional data. Meaning depends on the situation.
+ * `NPC_SUMMONMONSTER`: Slave monster ID.
+ * `NPC_SUMMONSLAVE`: Slave monster ID.
+ * `NPC_METAMORPHOSIS`: Transform monster ID.
+
+### val3
+Additional data. Meaning depends on the situation.
+ * `NPC_SUMMONMONSTER`: Slave monster ID.
+ * `NPC_SUMMONSLAVE`: Slave monster ID.
+ * `NPC_METAMORPHOSIS`: Transform monster ID.
+
+### val4
+Additional data. Meaning depends on the situation.
+ * `NPC_SUMMONMONSTER`: Slave monster ID.
+ * `NPC_SUMMONSLAVE`: Slave monster ID.
+ * `NPC_METAMORPHOSIS`: Transform monster ID.
+
+### Emotion
+The ID of the emotion the monster will use when casting the skill.
+(See [doc/constants.md](./constants.md#emotes) for a list of available emotions.)
+
+### ChatMsgID
+The ID of the message the monster will say when casting the skill.
+(See [db/mob_chat_db.txt](../db/mob_chat_db.txt) for a list of available messages.)
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 3b77aeb2c..3c0b37a85 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -536,7 +536,9 @@ variables or an empty string ("", nothing between the quotes) for string
variables. Once you set it to that, the variable is as good as forgotten
forever, and no trace remains of it even if it was stored with character
or account data. The maximum length of variable name including prefix and
-suffix is 32.
+suffix is 32. Permanent string variables (name$, $name$, #name$, ##name$)
+can store text with a maximum length of 255 characters. All other string
+type variables have no such limitation.
Some variables are special, that is, they are already defined for you by
the scripting engine. You can see the full list somewhere in
@@ -1710,7 +1712,8 @@ The default value of 'min' and 'max' can be set with 'input_min_value' and
For numeric inputs the value is capped to the range [min, max]. Returns 1
if the value was higher than 'max', -1 if lower than 'min' and 0 otherwise.
For string inputs it returns 1 if the string was longer than 'max', -1 is
-shorter than 'min' and 0 otherwise.
+shorter than 'min' and 0 otherwise. Note that an input string has a maximum
+length of 70 characters.
---------------------------------------
diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql
index a24b385f7..b9332701d 100644
--- a/sql-files/item_db_re.sql
+++ b/sql-files/item_db_re.sql
@@ -4212,7 +4212,7 @@ REPLACE INTO `item_db` VALUES ('6217','Mandragora_Flowerpot','Mandragora Flowerp
REPLACE INTO `item_db` VALUES ('6218','Disin_Delivery_Box','Dieshin\'s Delivery Box','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6219','Para_Team_Mark','Eden Group Mark','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6220','Mysterious_Dyestuff','Mysterious Dyestuffs','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('6221','Mystic_Leaf_Cat_Ball','Mystic Hydra Ball','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6221','Mystic_Leaf_Cat_Ball','Mystic Hydra Ball','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6222','Shining_Beads','Shining Beads','3','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6223','Carnium','Carnium','3','0','2000','1000','150','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6224','Bradium','Bradium','3','0','2000','1000','150','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -4595,6 +4595,8 @@ REPLACE INTO `item_db` VALUES ('6656','Goast_Free_Charm','Controlling Amulet','3
REPLACE INTO `item_db` VALUES ('6657','Memory_Of_Jack','Jack Memories','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6658','Halloween_Coin','Halloween Coin','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6665','RWC_Inicializer','RWC Enchant Reset Ticket','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6669','Emerald_Leaf','Emerald Leaf','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6670','Log_','Tree Log','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6671','Geffen_Magic_Coin','Geffen Magic Tournament Coin','3','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6672','Gray_Shard','Gray Piece','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6673','Bossnia_Pass','Ticket to Bossnia','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -4606,6 +4608,10 @@ REPLACE INTO `item_db` VALUES ('6712','Lovely_Stick','Love Wand','3','0','0','0'
REPLACE INTO `item_db` VALUES ('6746','Steel_Article','Steel Artifact','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6747','Steel_Article_','Steel Artifact','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6755','Corrupted_Charm','Contaminated Magic','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6762','Banana_Can','Banana Can','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6763','Spicy_Rice_Cake','Spicy Rice Cake','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6764','Hot_Dog','Hot Dog','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('6765','Ferris_Wheel_Biscuit','Ferris Wheel Biscuit','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6804','ORGANIC_PUMPKIN','Organic Pumpkin','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6805','INORGANIC_PUMPKIN','Inorganic Pumpkin','3','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('6821','Solo_Troops_Badge','Single Union Badge','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -5619,9 +5625,22 @@ REPLACE INTO `item_db` VALUES ('9059','Tikbalang_Pet','Tikbalang Egg','7','0','2
REPLACE INTO `item_db` VALUES ('9060','Brownie_Egg','Egg of Domovoi','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9061','Marin_Egg','Marin Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9062','Novice_Poring_Egg','Novice Poring Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9063','Woodie_Egg','Woodie Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9064','Elephant_Egg','Elephant Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9065','Gorilla_Egg','Gorilla Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9066','Lion_Egg','Lion Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9067','Rhino_Egg','Rhino Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9068','Blue_Unicorn_Egg','Blue Unicorn Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9069','Mastering_Egg','Mastering Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9070','Savage_Egg','Savage Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9071','Grand_Peco_Peco_Egg','Grand Peco Peco Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9074','Rubylit_Egg','Rubylit Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9075','Sapphilit_Egg','Sapphilit Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9076','Emelit_Egg','Emelit Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9077','Topalit_Egg','Topalit Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9078','Amelit_Egg','Amelit Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9079','Mythlit_Egg','Mythlit Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9080','Tamadora_Egg','Tamadora Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9087','High_Orc_Egg','High Orc Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9088','Angeling_Egg','Angeling Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9089','Am_Mut_Egg','Am Mut Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -5649,6 +5668,16 @@ REPLACE INTO `item_db` VALUES ('9111','Phreeoni_Egg','Phreeoni Egg','7','0','20'
REPLACE INTO `item_db` VALUES ('9112','Moonlight_Flower_Egg','Moonlight Flower Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9113','Skelion_Egg','Skelion Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9514','Ein_Ddbox','Ein_Ddbox','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9115','Bacsojin2_Egg_','Bacsojin Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9116','Rigid_Nightmare_Terror_Egg','Rigid Nightmare Terror Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9117','Contaminated_Wanderer_Egg','Contaminated Wanderer Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9118','Aliot_Egg','Aliot Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9119','Alicel_Egg','Alicel Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9120','Aliza_Egg','Aliza Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9121','Orc_Hero_Egg_','Orc Hero Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9122','Gloom_Under_Night_Egg','Gloom Under Night Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9123','Child_Admin_Beta_Egg','Child Admin Beta Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('9124','Child_Admin_Alpha_Egg','Child Admin Alpha Egg','7','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9523','Metal_Rifine_Ticket','Metal_Rifine_Ticket','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9529','Ein_Ddbox2','Ein_Ddbox2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('9550','Gemstone_Of_Time','Gemstone_Of_Time','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -5692,7 +5721,10 @@ REPLACE INTO `item_db` VALUES ('10036','Hell_Horn','Horn Of Hell','8','0','20','
REPLACE INTO `item_db` VALUES ('10037','Black_Butterfly_Mask','Black Butterfly Mask','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('10038','Horn_Protector','Horn Barrier','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('10039','Tw_Backpack','Tw Backpack','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('10042','Dark_Mane','Dark_Mane','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('10040','Red_Bell_Necklace','Red Bell Necklace','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('10042','Dark_Mane','Dark_Mane','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('10043','Little_Headdress_Beta','Little Headdress Beta','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('10044','Little_Headdress_Alpha','Little Headdress Alpha','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11000','Prontera_Book_01','History book of Prontera','3','0','8000','4000','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11001','Adventure_Story01','Adventure Story Vol.1','3','0','8000','4000','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11002','Great_Chef_Orleans01','Chef King Orleans Vol.1','3','0','8000','4000','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','1','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -5816,6 +5848,7 @@ REPLACE INTO `item_db` VALUES ('11593','Trance_Candy_B','Blue Transform Candy','
REPLACE INTO `item_db` VALUES ('11594','Trance_Candy_Y','Yellow Transform Candy','0','0','0','0','30','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','itemheal rand(45,65),0; specialeffect(EF_CLOAKING, AREA, playerattached()); showscript \"Trans-Form-!! Jack Fo-rm!!\"; montransform JAKK, 600000, SC_MTF_PUMPKIN, 2000;','','');
REPLACE INTO `item_db` VALUES ('11595','Trance_Candy_G','Green Transform Candy','0','0','0','0','30','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','itemheal rand(45,65),0; specialeffect(EF_CLOAKING, AREA, playerattached()); showscript \"Trans-Form-!! Cube Fo-rm!!\"; montransform QUVE, 600000, SC_MTF_HITFLEE, 10, 20;','','');
REPLACE INTO `item_db` VALUES ('11602','Catnip_Fruit','Catnip Fruit','0','0','15','7','1','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','itemheal rand(10,40),0;','','');
+REPLACE INTO `item_db` VALUES ('11605','Cookie_Bat','Cookie Bat','0','0','0','0','50','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','itemheal(rand(50, 100), 0);','','');
REPLACE INTO `item_db` VALUES ('11607','Crepe','Crepe','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11608','Chocolate_Egg','Chocolate_Egg','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11609','Yummy_Cookie_Egg','Yummy_Cookie_Egg','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -5823,6 +5856,7 @@ REPLACE INTO `item_db` VALUES ('11611','Pop_Corn','Pop_Corn','3','0','0','0','0'
REPLACE INTO `item_db` VALUES ('11612','Aromatic_Pop_Corn','Aromatic_Pop_Corn','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11614','Fresh_Milk','Fresh_Milk','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11615','Sweet_Potato_','Sweet_Potato_','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('11616','Yummy_Meat','Yummy Meat','0','0','0','0','50','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11620','Bearopy','Bearopy','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11625','Aromatic_Pop_Corn_','Aromatic_Pop_Corn_','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('11701','Girl_Bunch_Of_Flower','Girl\'s Bouquet','0','0','20','10','50','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','itemheal rand(105,145),0;','','');
@@ -10039,6 +10073,9 @@ REPLACE INTO `item_db` VALUES ('22808','Special_Gift_Box','Special Gift Box','2'
REPLACE INTO `item_db` VALUES ('22837','Integer_Time','Integer Time','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','50',NULL,'0','1','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','TmpRouletteBronze += 1;','','');
REPLACE INTO `item_db` VALUES ('22838','Something_Candy_Holder','Pumpkin Candy Holder','2','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','getrandgroupitem 22838,1;','','');
REPLACE INTO `item_db` VALUES ('22876','Old_Money_Pocket','Old Money Pocket','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','Zeny += rand(500, 550);','','');
+REPLACE INTO `item_db` VALUES ('23187','Sap_Jelly','Sap Jelly','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'1',NULL,'0',NULL,'0','pet(NINE_TAIL);','','');
+REPLACE INTO `item_db` VALUES ('23188','Unprocessed_Parts','Unprocessed Parts','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'1',NULL,'0',NULL,'0','pet(GREMLIN);','','');
+REPLACE INTO `item_db` VALUES ('23189','SmallDoll_Needle','Small Doll Needle','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'1',NULL,'0',NULL,'0','pet(TEDDY_BEAR);','','');
REPLACE INTO `item_db` VALUES ('23242','Fried_Chicken','Fried_Chicken','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('23243','Fried_Chicken_1','Fried_Chicken_1','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('23256','Elixir_Bandage','Elixir_Bandage','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -10692,6 +10729,9 @@ REPLACE INTO `item_db` VALUES ('24581','S_Genesis_Weapon','S_Genesis_Weapon','3'
REPLACE INTO `item_db` VALUES ('24582','S_Genesis_Pendant','S_Genesis_Pendant','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('24583','S_Genesis_Earing','S_Genesis_Earing','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25187','Slug_Bullet','Slug Bullet','3','0','1200','600','1200','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('25231','Suspicious_Bottle','Suspicious Bottle','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('25232','Cheap_Lubricant','Cheap Lubricant','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('25233','Cotton_Tufts','Cotton Tufts','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25258','BrokenArrow','BrokenArrow','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25265','Shining_Spore','Shining_Spore','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25266','Dried_Leaf_Of_Ygg','Dried_Leaf_Of_Ygg','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -10701,6 +10741,7 @@ REPLACE INTO `item_db` VALUES ('25294','Clover_Ticket','Clover_Ticket','3','0','
REPLACE INTO `item_db` VALUES ('25295','Happiness_Clover','Happiness_Clover','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25340','Golden_Corn','Golden_Corn','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25375','Mightysoul_Essence','Mightysoul_Essence','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('25377','Luxurious_Pet_Food','Luxurious Pet Food','3','0','0','0','1','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25390','Captured_Savage','Captured_Savage','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25391','Goodly_Bough','Goodly_Bough','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('25392','Free_Pass_Ticket','Free_Pass_Ticket','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -10852,6 +10893,8 @@ REPLACE INTO `item_db` VALUES ('26164','ElectricFox_OS','ElectricFox_OS','3','0'
REPLACE INTO `item_db` VALUES ('26215','Ein_1HWHIP','Ein_1HWHIP','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('27164','Faceworm_Queen_Card','Faceworm Queen Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','64','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bMaxHPrate, -10); bonus(bCritical, 15 + getrefine()); bonus(bCritAtkRate, getrefine());','','');
REPLACE INTO `item_db` VALUES ('27182','Captain_Felock_Card','Captain Felock Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','2','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bAtk, 30); bonus2(bSkillAtk, RL_AM_BLAST, getrefine() >= 10 ? 60 : 30); bonus2(bSkillAtk, RL_HAMMER_OF_GOD, getrefine() >= 10 ? 60 : 30);','','');
+REPLACE INTO `item_db` VALUES ('27352','Rigid_Nightmare_Terror_Card','Rigid Nightmare Terror Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','64','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bMaxSPrate, 5);','','');
+REPLACE INTO `item_db` VALUES ('27361','Contaminated_Wanderer_Card','Contaminated Wanderer Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','2','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2(bAddSize,Size_Medium, 30); bonus2(bAddSize,Size_Large, 30);','','');
REPLACE INTO `item_db` VALUES ('28000','Thanos_Katar','Thanatos Katar','4','16','20','10','1800','220','80','0','1','1','4096','56','2','34','4','120',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,6; bonus bVit,6; bonus bLuk,-6; bonus2 bSPDrainRate,10,5; bonus2 bHPDrainRate,10,5; bonus2 bHPLossRate,100,10000;','','heal -1000,0;');
REPLACE INTO `item_db` VALUES ('28001','Katar_Of_Evil_Slayer','Evil Slayer Ripper Katar','4','16','20','10','1200','120','0','0','1','1','4096','56','2','34','3','100',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddRace,RC_Demon,10; bonus2 bAddRace,RC_Undead,10; if(getrefine()>8) { bonus bAtkRate,5; } if(getrefine()>11) { bonus bAtkRate,7; }','','');
REPLACE INTO `item_db` VALUES ('28002','Half_BF_Katar2','Half BF Katar2','4','16','20','10','0','130','0','0','1','0','4096','63','2','34','3','80',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,1; bonus bDex,1; bonus bLuk,1; bonus2 bAddRace,RC_DemiPlayer,35; bonus bCritAtkRate,10; bonus bAspdRate,3; bonus bUnbreakableWeapon,0;','','');
@@ -10999,6 +11042,7 @@ REPLACE INTO `item_db` VALUES ('29589','GH_Cursed_Gemstone_','GH_Cursed_Gemstone
REPLACE INTO `item_db` VALUES ('29590','GH_Cursed_Crystal_','GH_Cursed_Crystal_','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('29591','Cursed_Emerald','Cursed_Emerald','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('29592','Shinee_Opal','Shinee_Opal','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('31022','Abandoned_Teddy_Bear_Card','Abandoned Teddy Bear Card','6','0','20','10','10','0','0','0','0','0','18446744073709551615','63','2','64','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus(bMaxSPrate, 20); bonus2(bAddEff2, Eff_Curse, 20);','','');
REPLACE INTO `item_db` VALUES ('31172','Roast_Memory','Roast_Memory','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('31186','C_Black_Cat','C_Black_Cat','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('31195','Choco_Minihat','Choco_Minihat','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -11292,6 +11336,7 @@ REPLACE INTO `item_db` VALUES ('1000016','HighpriestStone_Top2','HighpriestStone
REPLACE INTO `item_db` VALUES ('1000017','HighpriestStone_Middle2','HighpriestStone_Middle2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000018','HighpriestStone_Bottom2','HighpriestStone_Bottom2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000019','ArchbishopStone_Robe2','ArchbishopStone_Robe2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('1000103','Barmil_Ticket','Barmil Ticket','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000213','WarlockStone_Robe2','WarlockStone_Robe2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000214','WarlockStone_Top2','WarlockStone_Top2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000215','WarlockStone_Middle2','WarlockStone_Middle2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -11304,3 +11349,4 @@ REPLACE INTO `item_db` VALUES ('1000221','GuillcrossStone_Robe2','GuillcrossSton
REPLACE INTO `item_db` VALUES ('1000222','AssacrossStone_Top2','AssacrossStone_Top2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000223','AssacrossStone_Middle2','AssacrossStone_Middle2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('1000224','AssacrossStone_Bottom2','AssacrossStone_Bottom2','3','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
+REPLACE INTO `item_db` VALUES ('1000227','Cloud_Cotton','Cloud Cotton','3','0','0','0','10','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
diff --git a/sql-files/main.sql b/sql-files/main.sql
index dcd7e543d..d5b7735fc 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -51,7 +51,7 @@ CREATE TABLE IF NOT EXISTS `acc_reg_str_db` (
`account_id` INT UNSIGNED NOT NULL DEFAULT '0',
`key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
`index` INT UNSIGNED NOT NULL DEFAULT '0',
- `value` VARCHAR(254) NOT NULL DEFAULT '0',
+ `value` VARCHAR(255) NOT NULL DEFAULT '0',
PRIMARY KEY (`account_id`,`key`,`index`),
KEY `account_id` (`account_id`)
) ENGINE=MyISAM;
@@ -275,7 +275,7 @@ CREATE TABLE IF NOT EXISTS `char_reg_str_db` (
`char_id` INT UNSIGNED NOT NULL DEFAULT '0',
`key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
`index` INT UNSIGNED NOT NULL DEFAULT '0',
- `value` VARCHAR(254) NOT NULL DEFAULT '0',
+ `value` VARCHAR(255) NOT NULL DEFAULT '0',
PRIMARY KEY (`char_id`,`key`,`index`),
KEY `char_id` (`char_id`)
) ENGINE=MyISAM;
@@ -372,7 +372,7 @@ CREATE TABLE IF NOT EXISTS `global_acc_reg_str_db` (
`account_id` INT UNSIGNED NOT NULL DEFAULT '0',
`key` VARCHAR(32) BINARY NOT NULL DEFAULT '',
`index` INT UNSIGNED NOT NULL DEFAULT '0',
- `value` VARCHAR(254) NOT NULL DEFAULT '0',
+ `value` VARCHAR(255) NOT NULL DEFAULT '0',
PRIMARY KEY (`account_id`,`key`,`index`),
KEY `account_id` (`account_id`)
) ENGINE=MyISAM;
@@ -938,6 +938,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1574463539); -- 2019-11-2
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1579817630); -- 2020-01-24--01-09.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1584838560); -- 2020-03-22--01-56.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1584842940); -- 2020-03-22--03-09.sql
+INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1588301040); -- 2020-05-01--04-44.sql
--
-- Table structure for table `storage`
diff --git a/sql-files/mob_db_re.sql b/sql-files/mob_db_re.sql
index 713054e9c..4864affb2 100644
--- a/sql-files/mob_db_re.sql
+++ b/sql-files/mob_db_re.sql
@@ -1806,14 +1806,45 @@ REPLACE INTO `mob_db` VALUES (2957,'FORGOTTEN_NAME','Forgotten Name','Forgotten
REPLACE INTO `mob_db` VALUES (2958,'FATAL_DAYS','Fatal Days','Fatal Days',120,24240,1,2052,2026,2,1025,403,84,41,100,71,63,85,115,37,10,12,1,6,67,14469,170,720,384,480,0,0,0,0,0,0,0,1038,2500,1050,2500,6672,1500,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (2959,'TORTUROUS_REDEEMER','Torturous Redeemer','Torturous Redeemer',120,103342,1,10599,8378,1,1253,500,144,28,133,69,72,55,165,44,10,12,1,7,62,14757,200,672,420,360,0,0,0,0,0,0,0,923,2000,6672,10000,6672,10000,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (2961,'E_TORTUROUS_REDEEMER','Torturous Redeemer','Torturous Redeemer',120,103342,1,1,1,1,1,1,144,28,1,1,1,1,1,1,10,12,1,7,62,14757,200,672,420,360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (2963,'WOODIE','Woodie','Woodie',1,60,1,18,10,1,13,3,2,5,6,1,1,0,6,5,10,12,0,3,21,131,400,1872,672,480,0,0,0,0,0,0,0,7203,2000,907,2000,7201,2000,1019,2000,756,200,6670,5000,0,0,0,0,0,0,4558,300);
+REPLACE INTO `mob_db` VALUES (2995,'XM_TEDDY_BEAR','Abandoned Teddy Bear','Abandoned Teddy Bear',148,180000,1,6666,7332,1,1347,577,106,44,44,166,44,44,166,44,10,12,0,6,69,13205,150,780,780,504,0,0,0,0,0,0,0,7317,1900,615,150,12074,100,12734,1000,12738,100,0,0,0,0,0,0,0,0,31022,1);
REPLACE INTO `mob_db` VALUES (2996,'XM_CELINE_KIMI','Celine Kimi','Celine Kimi',160,66666666,1,4444444,4033332,2,5636,8303,479,444,144,166,44,444,166,166,10,12,2,1,28,13973,100,1056,1056,480,444444,616,10000,617,10000,22534,10000,22534,4000,18549,4000,7642,4000,19701,100,13442,100,712,10000,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3029,'GRIM_REAPER_ANKOU','Grim Reaper Ankou','Grim Reaper Ankou',159,50000000,1553,300000,330000,1,1500,2500,200,70,200,100,200,200,220,100,10,12,2,1,89,133,200,900,864,480,0,0,0,0,0,0,0,607,500,603,200,604,200,22537,10000,522,200,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3074,'TIMEHOLDER','Time Holder','Time Holder',170,25000000,1,2291250,1938750,1,5250,2100,288,265,224,152,251,257,402,77,10,12,2,6,80,14261,100,398,384,288,2291250,0,0,0,0,0,0,1095,3000,2121,10,7054,3000,22515,3000,18874,20,16024,5,15089,3,0,0,0,0,4625,1);
+REPLACE INTO `mob_db` VALUES (3162,'ELEPHANT','Elephant','Elephant',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,150,1028,528,360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3163,'GORILLA','Gorilla','Gorilla',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,190,1028,528,360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3164,'LION','Lion','Lion',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,150,1028,528,360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3165,'RHINO','Rhino','Rhino',48,1080,1,184,207,1,184,48,70,30,40,45,32,19,42,20,10,12,0,2,23,131,150,1028,528,360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3169,'J_REB_SHECIL1','Shooting Target','Shooting Target',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,1,200,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3170,'J_REB_SHECIL2','Shooting Target','Shooting Target',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,1,200,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3181,'E1_FELOCK','Captain Ferlock','Captain Ferlock',130,3000000,1,3088,333333,10,0,0,0,0,0,0,0,0,0,0,10,12,2,9,47,129,170,1018,1008,300,0,0,0,0,0,0,0,15117,100,20744,100,22047,100,12082,3000,12072,3000,12087,3000,12077,3000,12092,3000,0,0,27182,1);
REPLACE INTO `mob_db` VALUES (3190,'MM_SARAH','Sarah','Sarah',160,100000000,1,0,0,12,1090,2755,276,255,43,161,6,188,225,136,10,12,1,0,20,164,2000,500,500,0,0,0,0,0,0,0,0,15121,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4610,1);
REPLACE INTO `mob_db` VALUES (3202,'ORGANIC_JAKK','Organic Pumpkin','Organic Pumpkin',10,40,1,20,13,1,100,0,160,99,1,1,1,1,999,1,1,1,0,3,21,97,200,398,199,0,0,0,0,0,0,0,0,6804,5000,6804,5000,6804,1000,2267,100,1062,1000,664,100,546,1000,12192,100,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3203,'INORGANIC_JAKK','Inorganic Pumpkin','Inorganic Pumpkin',10,40,1,20,13,1,100,0,160,99,1,1,1,1,999,1,1,1,0,3,21,97,200,398,199,0,0,0,0,0,0,0,0,6805,5000,6805,5000,6805,1000,2267,100,1062,1000,664,100,546,1000,12192,100,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3261,'BLUE_UNICORN','Blue Unicorn','Blue Unicorn',30,20,1,99,112,1,106,29,36,17,17,26,20,18,36,5,10,12,0,3,25,129,300,1672,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3306,'PAD_TAMADORA','Tamadora','Tamadora',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3317,'PAD_RUBYLIT','Rubylit','Rubylit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3318,'PAD_SAPPHILIT','Sapphilit','Sapphilit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3319,'PAD_EMELIT','Emelit','Emelit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3320,'PAD_TOPALIT','Topalit','Topalit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3321,'PAD_AMELIT','Amelit','Amelit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3349,'PAD_MYTHLIT','Mythlit','Mythlit',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3381,'DARK_SOUL','Dark Soul','Dark Soul',10,20,1,0,0,1,20,20,0,0,1,1,1,1,1,1,1,1,1,6,27,129,100,1960,960,504,0,0,0,0,0,0,0,12192,2000,6914,4000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (3382,'WANDERING_SOUL','Wandering Soul','Wandering Soul',1,10,1,0,0,1,10,10,0,0,1,1,1,1,1,1,1,1,1,6,28,129,100,1248,1248,576,0,0,0,0,0,0,0,12192,2000,6915,4000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3495,'DR_EGGRING','Eggring','Eggring',1,50,1,50,35,1,7,1,2,4,6,1,1,0,6,4,10,12,0,3,22,131,400,1872,672,480,0,0,0,0,0,0,0,909,7000,512,1000,938,400,1010,30,601,500,512,150,512,20,0,0,0,0,4659,20);
+REPLACE INTO `mob_db` VALUES (3496,'DR_LUNATIC','Leaf Lunatic','Leaf Lunatic',3,44,1,50,35,1,12,1,16,0,9,1,2,0,7,4,10,12,0,2,60,129,200,1456,456,336,0,0,0,0,0,0,0,705,7000,949,3000,2262,4,512,1000,601,500,515,3000,1010,30,0,0,0,0,4663,10);
+REPLACE INTO `mob_db` VALUES (3636,'LITTLE_ISIS','Little Isis','Little Isis',59,2092,1,279,298,1,278,81,83,5,58,43,22,5,43,15,10,12,2,6,27,12693,200,1384,768,336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3669,'DIABOLIC2','Diabolic2','Diabolic2',104,10572,1,1086,1073,1,772,283,68,61,103,80,53,65,94,25,10,12,0,6,47,14725,150,1080,780,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3670,'DELETER_2','Deleter 2','Deleter 2',105,10000,1,1049,1038,1,733,265,114,53,98,72,65,49,68,71,10,12,0,9,43,12429,175,1024,624,336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3731,'SCATLETON','Scatleton','Scatleton',14,140,1,0,0,1,50,13,13,0,10,12,8,5,17,7,10,12,0,6,27,133,300,1600,900,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3790,'SWEETS_DROPS','Sweets Drops','Sweets Drops',1,20,1,27,20,1,12,1,16,0,1,1,1,1,1,1,10,12,0,3,23,131,440,1372,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (3971,'SKELION','Skelion','Skelion',150,13000,1,594,669,1,222,56,88,16,25,16,12,45,33,29,10,12,0,0,20,165,150,960,864,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20373,'NIGHTMARE_TERROR_H','Rigid Nightmare Terror','Rigid Nightmare Terror',179,1523377,1,138489,96942,1,1709,725,242,75,81,149,21,186,129,61,12,12,2,6,67,14725,165,1216,816,432,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27352,10);
+REPLACE INTO `mob_db` VALUES (20420,'WANDER_MAN_H','Corrupted Wanderer','Corrupted Wanderer',187,2387582,1,170542,119379,1,3654,1645,289,102,176,121,34,67,139,77,10,12,0,6,44,14725,100,672,500,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27361,10);
+REPLACE INTO `mob_db` VALUES (20423,'BACSOJIN2','Bacsojin','Bacsojin',97,720500,1,801792,542880,3,1414,2036,210,178,118,244,98,126,246,102,10,12,2,7,64,14261,130,960,960,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20424,'MOONLIGHT2','Moonlight Flower','Moonlight Flower',79,324000,1,367488,271440,1,2232,1251,254,81,86,102,93,82,157,120,10,12,1,6,63,14261,150,1276,576,288,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20425,'PHREEONI2','Phreeoni','Phreeoni',71,300000,1,127600,180000,1,693,967,269,98,88,70,112,87,122,71,10,12,2,2,60,14261,200,1020,1020,288,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20571,'ORK_HERO2','Orc Hero','Orc Hero',50,362000,1,106920,97200,1,662,441,197,70,97,82,107,71,144,43,10,12,2,7,42,14261,150,1678,780,648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20619,'GLOOMUNDERNIGHT2','Gloom Under Night','Gloom Under Night',139,3005000,1,2808000,1800000,3,6592,2785,479,262,191,223,187,155,362,163,10,12,2,0,68,14261,200,2000,2000,576,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20696,'EP17_2_CHILD_ADMIN1','Child Admin Beta','Child Admin Beta',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (20697,'EP17_2_CHILD_ADMIN2','Child Admin Alpha','Child Admin Alpha',1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,20,0,0,4000,2000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
diff --git a/sql-files/mob_skill_db_re.sql b/sql-files/mob_skill_db_re.sql
index 5bdb5aec4..37d8f5165 100644
--- a/sql-files/mob_skill_db_re.sql
+++ b/sql-files/mob_skill_db_re.sql
@@ -10055,6 +10055,14 @@ REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@SM_BASH','attack',5
REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@NPC_FIREATTACK','attack',186,3,1000,0,200000,'yes','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@WZ_FIREPILLAR','attack',80,5,500,0,10000,'no','around2','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (2959,'Torturous Redeemer@SM_MAGNUM','attack',7,5,500,0,10000,'no','self','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2963,'Woodie@AL_HEAL','attack',28,9,10000,500,5000,'no','self','myhpinrate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2963,'Woodie@NPC_FIREATTACK','attack',186,3,2000,500,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2963,'Woodie@NPC_GROUNDATTACK','attack',185,3,2000,500,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@NPC_CURSEATTACK','attack',181,4,500,0,5000,'no','self','myhpinrate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@NPC_CURSEATTACK','follow',181,4,500,0,5000,'no','self','myhpinrate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@NPC_CRITICALSLASH','attack',170,1,500,0,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@SA_DISPELL','attack',289,1,50,1000,15000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (2995,'Abandoned Teddy Bear@BS_HAMMERFALL','attack',110,5,500,1000,5000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (3074,'Time Holder@NPC_AGIUP','attack',350,5,10000,0,10000,'yes','self','myhpltmaxrate','30',NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (3074,'Time Holder@AL_INCAGI','chase',29,10,2000,700,10000,'no','self','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (3074,'Time Holder@WZ_METEOR','attack',83,11,1000,500,10000,'no','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
diff --git a/sql-files/upgrades/2020-05-01--04-44.sql b/sql-files/upgrades/2020-05-01--04-44.sql
new file mode 100644
index 000000000..6cb5a30ec
--- /dev/null
+++ b/sql-files/upgrades/2020-05-01--04-44.sql
@@ -0,0 +1,25 @@
+#1588301040
+
+-- This file is part of Hercules.
+-- http://herc.ws - http://github.com/HerculesWS/Hercules
+--
+-- Copyright (C) 2019-2020 Hercules Dev Team
+--
+-- Hercules is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ALTER TABLE `acc_reg_str_db` MODIFY `value` VARCHAR(255) NOT NULL DEFAULT '0';
+ALTER TABLE `char_reg_str_db` MODIFY `value` VARCHAR(255) NOT NULL DEFAULT '0';
+ALTER TABLE `global_acc_reg_str_db` MODIFY `value` VARCHAR(255) NOT NULL DEFAULT '0';
+
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1588301040);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index fdd5fcc5a..64a7793f8 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -62,3 +62,4 @@
2020-01-24--01-09.sql
2020-03-22--01-56.sql
2020-03-22--03-09.sql
+2020-05-01--04-44.sql
diff --git a/src/char/char.c b/src/char/char.c
index aac9ad20c..c61b6107a 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -425,8 +425,6 @@ static struct DBData char_create_charstatus(union DBKey key, va_list args)
static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
{
- int i = 0;
- int count = 0;
int diff = 0;
char save_status[128]; //For displaying save information. [Skotlex]
struct mmo_charstatus *cp;
@@ -591,8 +589,9 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
//insert here.
StrBuf->Clear(&buf);
StrBuf->Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", memo_db);
- for( i = 0, count = 0; i < MAX_MEMOPOINTS; ++i )
- {
+
+ int count = 0;
+ for (int i = 0; i < MAX_MEMOPOINTS; ++i) {
if( p->memo_point[i].map )
{
if( count )
@@ -624,24 +623,29 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
StrBuf->Clear(&buf);
StrBuf->Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`,`flag`) VALUES ", skill_db);
//insert here.
- for (i = 0, count = 0; i < MAX_SKILL_DB; ++i) {
- if( p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY ) {
- if( p->skill[i].lv == 0 && ( p->skill[i].flag == SKILL_FLAG_PERM_GRANTED || p->skill[i].flag == SKILL_FLAG_PERMANENT ) )
- continue;
- if( p->skill[i].flag != SKILL_FLAG_PERMANENT && p->skill[i].flag != SKILL_FLAG_PERM_GRANTED && (p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0) == 0 )
- continue;
- if( count )
- StrBuf->AppendStr(&buf, ",");
- StrBuf->Printf(&buf, "('%d','%d','%d','%d')", char_id, p->skill[i].id,
- ( (p->skill[i].flag == SKILL_FLAG_PERMANENT || p->skill[i].flag == SKILL_FLAG_PERM_GRANTED) ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0),
- p->skill[i].flag == SKILL_FLAG_PERM_GRANTED ? p->skill[i].flag : 0);/* other flags do not need to be saved */
- ++count;
- }
+ int count = 0;
+ for (int i = 0; i < MAX_SKILL_DB; ++i) {
+ if (p->skill[i].id == 0)
+ continue;
+ if (p->skill[i].flag == SKILL_FLAG_TEMPORARY)
+ continue;
+ if (p->skill[i].lv == 0 && (p->skill[i].flag == SKILL_FLAG_PERM_GRANTED || p->skill[i].flag == SKILL_FLAG_PERMANENT))
+ continue;
+ if (p->skill[i].flag == SKILL_FLAG_REPLACED_LV_0)
+ continue;
+
+ if (Assert_chk(p->skill[i].flag == SKILL_FLAG_PERMANENT || p->skill[i].flag == SKILL_FLAG_PERM_GRANTED || p->skill[i].flag > SKILL_FLAG_REPLACED_LV_0))
+ continue;
+ if (count != 0)
+ StrBuf->AppendStr(&buf, ",");
+ int saved_lv = (p->skill[i].flag > SKILL_FLAG_REPLACED_LV_0) ? p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0 : p->skill[i].lv;
+ int saved_flag = p->skill[i].flag == SKILL_FLAG_PERM_GRANTED ? p->skill[i].flag : 0; // other flags do not need to be saved
+ StrBuf->Printf(&buf, "('%d','%d','%d','%d')", char_id, p->skill[i].id, saved_lv, saved_flag);
+
+ ++count;
}
- if( count )
- {
- if( SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)) )
- {
+ if (count != 0) {
+ if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) {
Sql_ShowDebug(inter->sql_handle);
errors++;
}
@@ -651,7 +655,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
}
diff = 0;
- for(i = 0; i < MAX_FRIENDS; i++){
+ for (int i = 0; i < MAX_FRIENDS; i++) {
if(p->friends[i].char_id != cp->friends[i].char_id ||
p->friends[i].account_id != cp->friends[i].account_id){
diff = 1;
@@ -669,8 +673,8 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
StrBuf->Clear(&buf);
StrBuf->Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db);
- for( i = 0, count = 0; i < MAX_FRIENDS; ++i )
- {
+ int count = 0;
+ for (int i = 0; i < MAX_FRIENDS; ++i) {
if( p->friends[i].char_id > 0 )
{
if( count )
@@ -695,7 +699,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
StrBuf->Clear(&buf);
StrBuf->Printf(&buf, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", hotkey_db);
diff = 0;
- for(i = 0; i < ARRAYLENGTH(p->hotkeys); i++){
+ for (int i = 0; i < ARRAYLENGTH(p->hotkeys); i++) {
if(memcmp(&p->hotkeys[i], &cp->hotkeys[i], sizeof(struct hotkey)))
{
if( diff )
@@ -1369,7 +1373,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa
SqlStmt_ShowDebug(stmt);
}
- if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED )
+ if (tmp_skill.flag != SKILL_FLAG_PERM_GRANTED)
tmp_skill.flag = SKILL_FLAG_PERMANENT;
for (i = 0; i < MAX_SKILL_DB && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i) {
@@ -2898,13 +2902,13 @@ static void char_global_accreg_to_login_add(const char *key, unsigned int index,
if( val ) {
char *sval = (char*)val;
- len = strlen(sval)+1;
+ len = strlen(sval);
- WFIFOB(chr->login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ WFIFOB(chr->login_fd, nlen) = (unsigned char)len; // Won't be higher; the column size is 255.
nlen += 1;
- safestrncpy(WFIFOP(chr->login_fd,nlen), sval, len);
- nlen += len;
+ safestrncpy(WFIFOP(chr->login_fd, nlen), sval, len + 1);
+ nlen += len + 1;
}
} else {
WFIFOB(chr->login_fd, nlen) = val ? 0 : 1;
diff --git a/src/char/inter.c b/src/char/inter.c
index 2d8d06a9c..5252b3315 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -676,13 +676,13 @@ static int inter_accreg_fromsql(int account_id, int char_id, int fd, int type)
plen += 4;
SQL->GetData(inter->sql_handle, 2, &data, NULL);
- len = strlen(data)+1;
+ len = strlen(data);
- WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ WFIFOB(fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255.
plen += 1;
- safestrncpy(WFIFOP(fd,plen), data, len);
- plen += len;
+ safestrncpy(WFIFOP(fd, plen), data, len + 1);
+ plen += len + 1;
WFIFOW(fd, 14) += 1;
diff --git a/src/char/mapif.c b/src/char/mapif.c
index 9077afae4..f0c886586 100644
--- a/src/char/mapif.c
+++ b/src/char/mapif.c
@@ -2030,7 +2030,8 @@ static int mapif_parse_Registry(int fd)
if (count != 0) {
int cursor = 14, i;
- char key[SCRIPT_VARNAME_LENGTH+1], sval[254];
+ char key[SCRIPT_VARNAME_LENGTH + 1];
+ char sval[SCRIPT_STRING_VAR_LENGTH + 1];
bool isLoginActive = sockt->session_is_active(chr->login_fd);
if (isLoginActive)
@@ -2057,8 +2058,8 @@ static int mapif_parse_Registry(int fd)
/* str */
case 2:
len = RFIFOB(fd, cursor);
- safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len));
- cursor += len + 1;
+ safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1));
+ cursor += len + 2;
inter->savereg(account_id, char_id, key, index, (intptr_t)sval, true);
break;
case 3:
diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h
index 0b5613316..6053d86d9 100644
--- a/src/common/cbasetypes.h
+++ b/src/common/cbasetypes.h
@@ -95,7 +95,7 @@
// debug function name
#ifndef __NETBSD__
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
-# if __GNUC__ >= 2
+# if __GNUC__ >= 2 || defined(WIN32)
# define __func__ __FUNCTION__
# else
# define __func__ ""
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 9421f6e35..d2f3aa8f1 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -380,7 +380,10 @@ STATIC_ASSERT(MAX_ITEM_OPTIONS <= 5, "This value is limited by the client and da
#define JOBL_BABY 0x2000
#define JOBL_THIRD 0x4000
-#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable
+#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable's name including affixes and excluding NULL-terminator.
+STATIC_ASSERT(SCRIPT_VARNAME_LENGTH <= 32, "This value is limited by the inter-server communication and database layout and should only be increased if you know the consequences.");
+#define SCRIPT_STRING_VAR_LENGTH 255 ///< Maximum length of strings stored in script variables excluding NULL-terminator.
+STATIC_ASSERT(SCRIPT_STRING_VAR_LENGTH <= 255, "This value is limited by the inter-server communication and database layout and should only be increased if you know the consequences.");
#define INFINITE_DURATION (-1) // Infinite duration for status changes
diff --git a/src/login/account.c b/src/login/account.c
index 3632c257a..ec0bc81e8 100644
--- a/src/login/account.c
+++ b/src/login/account.c
@@ -632,7 +632,8 @@ static void account_mmo_save_accreg2(AccountDB *self, int fd, int account_id, in
sql_handle = db->accounts;
if (count) {
int cursor = 14, i;
- char key[SCRIPT_VARNAME_LENGTH+1], sval[254];
+ char key[SCRIPT_VARNAME_LENGTH + 1];
+ char sval[SCRIPT_STRING_VAR_LENGTH + 1];
for (i = 0; i < count; i++) {
unsigned int index;
@@ -657,8 +658,8 @@ static void account_mmo_save_accreg2(AccountDB *self, int fd, int account_id, in
/* str */
case 2:
len = RFIFOB(fd, cursor);
- safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len));
- cursor += len + 1;
+ safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1));
+ cursor += len + 2;
if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_db, account_id, key, index, sval) )
Sql_ShowDebug(sql_handle);
break;
@@ -719,13 +720,13 @@ static void account_mmo_send_accreg2(AccountDB *self, int fd, int account_id, in
plen += 4;
SQL->GetData(sql_handle, 2, &data, NULL);
- len = strlen(data)+1;
+ len = strlen(data);
- WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ WFIFOB(fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255.
plen += 1;
- safestrncpy(WFIFOP(fd,plen), data, len);
- plen += len;
+ safestrncpy(WFIFOP(fd, plen), data, len + 1);
+ plen += len + 1;
WFIFOW(fd, 14) += 1;
diff --git a/src/login/login.c b/src/login/login.c
index 4201a8b4e..623457b8a 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -1406,10 +1406,10 @@ static void login_client_login_mobile_otp_request(int fd, struct login_session_d
static void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) __attribute__((nonnull (2)));
static void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status)
{
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x2711;
- WFIFOB(fd,2) = status;
- WFIFOSET(fd,3);
+ WFIFOHEAD(fd, 3);
+ WFIFOW(fd, 0) = 0x2711;
+ WFIFOB(fd, 2) = status;
+ WFIFOSET2(fd, 3);
}
// CA_CHARSERVERCONNECT
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 91ddc3ef9..54cc9e2c9 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -962,39 +962,10 @@ ACMD(option)
*------------------------------------------*/
ACMD(hide)
{
- if (pc_isinvisible(sd)) {
- sd->sc.option &= ~OPTION_INVISIBLE;
- if (sd->disguise != -1 )
- status->set_viewdata(&sd->bl, sd->disguise);
- else
- status->set_viewdata(&sd->bl, sd->status.class);
- clif->message(fd, msg_fd(fd,10)); // Invisible: Off
-
- // increment the number of pvp players on the map
- map->list[sd->bl.m].users_pvp++;
-
- if( map->list[sd->bl.m].flag.pvp && !map->list[sd->bl.m].flag.pvp_nocalcrank ) {
- // register the player for ranking calculations
- sd->pvp_timer = timer->add( timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0 );
- }
- //bugreport:2266
- map->foreachinmovearea(clif->insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl);
- } else {
- clif->clearunit_area(&sd->bl, CLR_OUTSIGHT);
- sd->sc.option |= OPTION_INVISIBLE;
- sd->vd.class = INVISIBLE_CLASS;
- clif->message(fd, msg_fd(fd,11)); // Invisible: On
-
- // decrement the number of pvp players on the map
- map->list[sd->bl.m].users_pvp--;
-
- if( map->list[sd->bl.m].flag.pvp && !map->list[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER ) {
- // unregister the player for ranking
- timer->delete( sd->pvp_timer, pc->calc_pvprank_timer );
- sd->pvp_timer = INVALID_TIMER;
- }
- }
- clif->changeoption(&sd->bl);
+ if (pc_isinvisible(sd))
+ pc->unhide(sd, true);
+ else
+ pc->hide(sd, true);
return true;
}
@@ -8945,13 +8916,17 @@ ACMD(accinfo)
/* [Ind] */
ACMD(set)
{
- char reg[SCRIPT_VARNAME_LENGTH+1], val[254];
+ char reg[SCRIPT_VARNAME_LENGTH + 1];
+ char val[SCRIPT_STRING_VAR_LENGTH + 1];
struct script_data* data;
int toset = 0;
bool is_str = false;
size_t len;
- if (!*message || (toset = sscanf(message, "%32s %253[^\n]", reg, val)) < 1) {
+ char format[20];
+ safesnprintf(format, sizeof(format), "%%%ds %%%d[^\\n]", SCRIPT_VARNAME_LENGTH, SCRIPT_STRING_VAR_LENGTH);
+
+ if (*message == '\0' || (toset = sscanf(message, format, reg, val)) < 1) {
clif->message(fd, msg_fd(fd,1367)); // Usage: @set <variable name> <value>
clif->message(fd, msg_fd(fd,1368)); // Usage: ex. "@set PoringCharVar 50"
clif->message(fd, msg_fd(fd,1369)); // Usage: ex. "@set PoringCharVarSTR$ Super Duper String"
@@ -10594,9 +10569,9 @@ static bool atcommand_exec(const int fd, struct map_session_data *sd, const char
clif->message(fd, msg_fd(fd,143));
return false;
}
+ if (sd->block_action.commands) // *pcblock script command
+ return false;
}
- if (sd->block_action.commands) // *pcblock script command
- return false;
if (*message == atcommand->char_symbol)
is_atcommand = false;
diff --git a/src/map/battle.c b/src/map/battle.c
index 40c645cf7..c8cd71b94 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -3750,7 +3750,7 @@ static struct Damage battle_calc_magic_attack(struct block_list *src, struct blo
if (sc){
if( sc->data[SC_TELEKINESIS_INTENSE] && s_ele == ELE_GHOST )
- ad.damage += sc->data[SC_TELEKINESIS_INTENSE]->val3;
+ ad.damage += ad.damage * sc->data[SC_TELEKINESIS_INTENSE]->val3 / 100;
}
switch(skill_id){
case MG_FIREBOLT:
@@ -4124,13 +4124,6 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc
case NPC_EVILLAND:
md.damage = skill->calc_heal(src,target,skill_id,skill_lv,false);
break;
- case RK_DRAGONBREATH:
- case RK_DRAGONBREATH_WATER:
- md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv;
- RE_LVL_MDMOD(150);
- if (sd) md.damage = md.damage * (95 + 5 * pc->checkskill(sd,RK_DRAGONTRAINING)) / 100;
- md.flag |= BF_LONG|BF_WEAPON;
- break;
/**
* Ranger
**/
@@ -4958,6 +4951,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
break;
}
break;
+ case RK_DRAGONBREATH:
+ case RK_DRAGONBREATH_WATER:
+ wd.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv;
+ wd.damage = wd.damage * status->get_lv(src) / 150;
+ if (sd) wd.damage = wd.damage * (95 + 5 * pc->checkskill(sd, RK_DRAGONTRAINING)) / 100;
+ break;
default:
{
i = (flag.cri
diff --git a/src/map/clif.c b/src/map/clif.c
index 496a8beda..ab13ffe1f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9722,6 +9722,17 @@ static void clif_elemname_ack(int fd, struct block_list *bl)
clif->send_selforarea(fd, bl, &packet, sizeof(struct PACKET_ZC_ACK_REQNAME_TITLE));
}
+static void clif_skillname_ack(int fd, struct block_list *bl)
+{
+}
+
+static void clif_itemname_ack(int fd, struct block_list *bl)
+{
+ nullpo_retv(bl);
+ ShowError("clif_itemname_ack: bad type %u(%d)\n", bl->type, bl->id);
+ Assert_retv(0);
+}
+
static void clif_unknownname_ack(int fd, struct block_list *bl)
{
nullpo_retv(bl);
@@ -9758,6 +9769,12 @@ static void clif_blname_ack(int fd, struct block_list *bl)
case BL_ELEM:
clif->elemname_ack(fd, bl);
break;
+ case BL_ITEM:
+ clif->itemname_ack(fd, bl);
+ break;
+ case BL_SKILL:
+ clif->skillname_ack(fd, bl);
+ break;
default:
clif->unknownname_ack(fd, bl);
break;
@@ -11777,7 +11794,7 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd)
char *str = target + 4; // Skip the NPC: string part.
struct npc_data *nd;
if ((nd = npc->name2id(str))) {
- char split_data[NUM_WHISPER_VAR][CHAT_SIZE_MAX];
+ char split_data[NUM_WHISPER_VAR][SCRIPT_STRING_VAR_LENGTH + 1];
char *split;
char output[256];
@@ -23780,12 +23797,15 @@ static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) _
static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd)
{
#if PACKETVER >= 20160302
+ if (sd->state.lapine_ui == 0)
+ return;
+
const struct PACKET_CZ_LAPINEDDUKDDAK_ACK *p = RP2PTR(fd);
struct item_data *it = itemdb->exists(p->itemId);
if (it == NULL || it->lapineddukddak == NULL)
return;
- if (pc_cant_act(sd))
+ if (pc_cant_act_except_lapine(sd))
return;
if (pc->search_inventory(sd, it->nameid) == INDEX_NOT_FOUND)
return;
@@ -23846,6 +23866,55 @@ static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd)
#endif // PACKETVER >= 20160504
}
+static bool clif_lapineUpgrade_open(struct map_session_data *sd, int item_id)
+{
+#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+ nullpo_retr(false, sd);
+ nullpo_retr(false, itemdb->exists(item_id));
+ struct PACKET_ZC_LAPINEUPGRADE_OPEN p;
+
+ p.packetType = HEADER_ZC_LAPINEUPGRADE_OPEN;
+ p.itemId = item_id;
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
+
+ return true;
+#else
+ return false;
+#endif // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+}
+
+static void clif_parse_lapineUpgrade_close(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+static void clif_parse_lapineUpgrade_close(int fd, struct map_session_data *sd)
+{
+#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+}
+
+static void clif_parse_lapineUpgrade_makeItem(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+static void clif_parse_lapineUpgrade_makeItem(int fd, struct map_session_data *sd)
+{
+#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+ ShowError("Lapin upgrade not implimented yet");
+ clif->lapineUpgrade_result(sd, LAPINE_UPGRADE_FAILED);
+#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+}
+
+static bool clif_lapineUpgrade_result(struct map_session_data *sd, enum lapineUpgrade_result result)
+{
+#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+ nullpo_retr(false, sd);
+ struct PACKET_ZC_LAPINEUPGRADE_RESULT p;
+
+ p.packetType = HEADER_ZC_LAPINEUPGRADE_RESULT;
+ p.result = result;
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
+
+ return true;
+#else
+ return false;
+#endif // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+}
+
/*==========================================
* Main client packet processing function
*------------------------------------------*/
@@ -24346,6 +24415,8 @@ void clif_defaults(void)
clif->mobname_normal_ack = clif_mobname_normal_ack;
clif->chatname_ack = clif_chatname_ack;
clif->elemname_ack = clif_elemname_ack;
+ clif->skillname_ack = clif_skillname_ack;
+ clif->itemname_ack = clif_itemname_ack;
clif->unknownname_ack = clif_unknownname_ack;
clif->monster_hp_bar = clif_monster_hp_bar;
clif->hpmeter = clif_hpmeter;
@@ -25089,5 +25160,9 @@ void clif_defaults(void)
clif->lapineDdukDdak_result = clif_lapineDdukDdak_result;
clif->plapineDdukDdak_ack = clif_parse_lapineDdukDdak_ack;
clif->plapineDdukDdak_close = clif_parse_lapineDdukDdak_close;
+ clif->lapineUpgrade_open = clif_lapineUpgrade_open;
+ clif->lapineUpgrade_result = clif_lapineUpgrade_result;
+ clif->pLapineUpgrade_close = clif_parse_lapineUpgrade_close;
+ clif->pLapineUpgrade_makeItem = clif_parse_lapineUpgrade_makeItem;
clif->pReqGearOff = clif_parse_reqGearOff;
}
diff --git a/src/map/clif.h b/src/map/clif.h
index 25ac65af5..fdaaf85e3 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -733,6 +733,11 @@ enum lapineddukddak_result {
LAPINEDDKUKDDAK_INVALID_ITEM = 7,
};
+enum lapineUpgrade_result {
+ LAPINE_UPGRADE_SUCCESS = 0,
+ LAPINE_UPGRADE_FAILED = 1
+};
+
enum removeGear_flag {
REMOVE_MOUNT_0 = 0, // unused
REMOVE_MOUNT_DRAGON = 1,
@@ -952,6 +957,8 @@ struct clif_interface {
void (*mobname_normal_ack) (int fd, struct block_list *bl);
void (*chatname_ack) (int fd, struct block_list *bl);
void (*elemname_ack) (int fd, struct block_list *bl);
+ void (*skillname_ack) (int fd, struct block_list *bl);
+ void (*itemname_ack) (int fd, struct block_list *bl);
void (*unknownname_ack) (int fd, struct block_list *bl);
void (*monster_hp_bar) ( struct mob_data* md, struct map_session_data *sd );
int (*hpmeter) (struct map_session_data *sd);
@@ -1688,6 +1695,10 @@ struct clif_interface {
bool (*lapineDdukDdak_result) (struct map_session_data *sd, enum lapineddukddak_result result);
void (*plapineDdukDdak_ack) (int fd, struct map_session_data *sd);
void (*plapineDdukDdak_close) (int fd, struct map_session_data *sd);
+ bool (*lapineUpgrade_open) (struct map_session_data *sd, int item_id);
+ bool (*lapineUpgrade_result) (struct map_session_data *sd, enum lapineUpgrade_result result);
+ void (*pLapineUpgrade_close) (int fd, struct map_session_data *sd);
+ void (*pLapineUpgrade_makeItem) (int fd, struct map_session_data *sd);
void (*pReqGearOff) (int fd, struct map_session_data *sd);
};
diff --git a/src/map/intif.c b/src/map/intif.c
index a420b7204..276b40780 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -218,13 +218,13 @@ static int intif_saveregistry(struct map_session_data *sd)
plen += 1;
if( p->value ) {
- len = strlen(p->value)+1;
+ len = strlen(p->value);
- WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ WFIFOB(inter_fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255.
plen += 1;
- safestrncpy(WFIFOP(inter_fd,plen), p->value, len);
- plen += len;
+ safestrncpy(WFIFOP(inter_fd, plen), p->value, len + 1);
+ plen += len + 1;
} else {
script->reg_destroy_single(sd,key.i64,&p->flag);
}
@@ -1025,7 +1025,7 @@ static void intif_parse_Registers(int fd)
* { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) }
**/
if (type) {
- char sval[254];
+ char sval[SCRIPT_STRING_VAR_LENGTH + 1];
for (i = 0; i < max; i++) {
int len = RFIFOB(fd, cursor);
safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len));
@@ -1035,8 +1035,8 @@ static void intif_parse_Registers(int fd)
cursor += 4;
len = RFIFOB(fd, cursor);
- safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len));
- cursor += len + 1;
+ safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1));
+ cursor += len + 2;
script->set_reg(NULL,sd,reference_uid(script->add_variable(key), index), key, sval, NULL);
}
diff --git a/src/map/map.c b/src/map/map.c
index b2c9c77c3..f66f40dfc 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1713,9 +1713,9 @@ static bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x,
tx = *x + dx;
ty = *y + dy;
if (unit_is_dir_or_opposite(dir, UNIT_DIR_SOUTHWEST))
- tx *= costrange / MOVE_COST;
+ tx = tx * costrange / MOVE_COST;
if (unit_is_dir_or_opposite(dir, UNIT_DIR_NORTHWEST))
- ty *= costrange / MOVE_COST;
+ ty = ty * costrange / MOVE_COST;
if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) {
*x = tx;
*y = ty;
@@ -1724,9 +1724,9 @@ static bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x,
tx = *x + dx;
ty = *y + dy;
if (unit_is_dir_or_opposite(dir, UNIT_DIR_NORTHWEST))
- tx *= costrange / MOVE_COST;
+ tx = tx * costrange / MOVE_COST;
if (unit_is_dir_or_opposite(dir, UNIT_DIR_SOUTHWEST))
- ty *= costrange / MOVE_COST;
+ ty = ty * costrange / MOVE_COST;
if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) {
*x = tx;
*y = ty;
@@ -3077,6 +3077,8 @@ static int map_getcellp(struct map_data *m, const struct block_list *bl, int16 x
return (cell.icewall);
case CELL_CHKNOICEWALL:
return (cell.noicewall);
+ case CELL_CHKNOSKILL:
+ return (cell.noskill);
// special checks
case CELL_CHKPASS:
@@ -3141,6 +3143,7 @@ static void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
case CELL_NOCHAT: map->list[m].cell[j].nochat = flag; break;
case CELL_ICEWALL: map->list[m].cell[j].icewall = flag; break;
case CELL_NOICEWALL: map->list[m].cell[j].noicewall = flag; break;
+ case CELL_NOSKILL: map->list[m].cell[j].noskill = flag; break;
default:
ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
diff --git a/src/map/map.h b/src/map/map.h
index 2de6df2f7..64736a6f5 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -588,6 +588,7 @@ typedef enum {
CELL_NOCHAT,
CELL_ICEWALL,
CELL_NOICEWALL,
+ CELL_NOSKILL,
} cell_t;
@@ -612,6 +613,7 @@ typedef enum {
CELL_CHKNOCHAT,
CELL_CHKICEWALL,
CELL_CHKNOICEWALL,
+ CELL_CHKNOSKILL,
} cell_chk;
@@ -630,7 +632,8 @@ struct mapcell {
novending : 1,
nochat : 1,
icewall : 1,
- noicewall : 1;
+ noicewall : 1,
+ noskill : 1;
#ifdef CELL_NOSTACK
int cell_bl; //Holds amount of bls in this cell.
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 741505e17..2963637da 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -176,9 +176,9 @@ static bool mapreg_setregstr(int64 uid, const char *str)
if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert.
char tmp_str[(SCRIPT_VARNAME_LENGTH+1)*2+1];
- char tmp_str2[255*2+1];
+ char tmp_str2[SCRIPT_STRING_VAR_LENGTH * 2 + 1];
SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, SCRIPT_VARNAME_LENGTH+1));
- SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, 255));
+ SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, SCRIPT_STRING_VAR_LENGTH));
if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%u','%s')", mapreg->table, tmp_str, i, tmp_str2) )
Sql_ShowDebug(map->mysql_handle);
}
@@ -203,7 +203,7 @@ static void script_load_mapreg(void)
struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);
char varname[SCRIPT_VARNAME_LENGTH+1];
int index;
- char value[255+1];
+ char value[SCRIPT_STRING_VAR_LENGTH + 1];
uint32 length;
if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg->table)
@@ -261,8 +261,8 @@ static void script_save_mapreg(void)
if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) )
Sql_ShowDebug(map->mysql_handle);
} else {
- char tmp_str2[2*255+1];
- SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255));
+ char tmp_str2[SCRIPT_STRING_VAR_LENGTH * 2 + 1];
+ SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, SCRIPT_STRING_VAR_LENGTH));
if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) )
Sql_ShowDebug(map->mysql_handle);
}
diff --git a/src/map/mob.c b/src/map/mob.c
index 51a32abd9..dcbdccedd 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -78,6 +78,7 @@ struct mob_interface *mob;
// Move probability for mobs away from players (rate of 1000 minute)
// in Aegis, this is 100% for mobs that have been activated by players and none otherwise.
#define MOB_LAZYMOVEPERC(md) ((md)->state.spotted?1000:0)
+#define MOB_MAX_CASTTIME (10 * 60 * 1000) // Maximum cast time for monster skills. (10 minutes)
#define MOB_MAX_DELAY (24*3600*1000)
#define MAX_MINCHASE 30 //Max minimum chase value to use for mobs.
#define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used?
@@ -446,6 +447,9 @@ static bool mob_ksprotected(struct block_list *src, struct block_list *target)
if( !battle_config.ksprotection )
return false; // KS Protection Disabled
+ if (status->isdead(target) != 0)
+ return false; // Target is dead.
+
if( !(md = BL_CAST(BL_MOB,target)) )
return false; // Target is not MOB
@@ -1519,7 +1523,7 @@ static int mob_unlocktarget(struct mob_data *md, int64 tick)
FALLTHROUGH
case MSS_IDLE:
// Idle skill.
- if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL) && mob->skill_use(md, tick, -1))
+ if ((++md->ud.walk_count % IDLE_SKILL_INTERVAL) == 0 && mob->skill_use(md, tick, -1) == 0)
break;
//Random walk.
if (!md->master_id &&
@@ -1699,7 +1703,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, int64 tick)
|| !mob->can_reach(md, tbl, md->min_chase, MSS_RUSH)
)
&& md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
- && !mob->skill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack
+ && mob->skill_use(md, tick, MSC_RUDEATTACKED) == 0 // If can't rude Attack
&& can_move && unit->escape(&md->bl, tbl, rnd()%10 +1) // Attempt escape
) {
//Escaped
@@ -1727,7 +1731,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, int64 tick)
) {
// Rude attacked
if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT
- && !mob->skill_use(md, tick, MSC_RUDEATTACKED) && can_move
+ && mob->skill_use(md, tick, MSC_RUDEATTACKED) == 0 && can_move != 0
&& !tbl && unit->escape(&md->bl, abl, rnd()%10 +1)
) {
//Escaped.
@@ -3387,272 +3391,344 @@ static struct block_list *mob_getmasterhpltmaxrate(struct mob_data *md, int rate
return NULL;
}
-/*==========================================
- * What a status state suits by nearby MOB is looked for.
- *------------------------------------------*/
+
+/**
+ * Checks if the passed monster/character meets the passed status change requirements
+ * and returns it by reference parameter on success.
+ *
+ * @param bl The monster/character to check.
+ * @param ap List of arguments. (Source monster, MSC_* flag, SC_* flag, reference bl.)
+ * @return Always 0.
+ *
+ **/
static int mob_getfriendstatus_sub(struct block_list *bl, va_list ap)
{
- int cond1,cond2;
- struct mob_data **fr = NULL, *md = NULL, *mmd = NULL;
- int flag=0;
-
nullpo_ret(bl);
- Assert_ret(bl->type == BL_MOB);
- md = BL_UCAST(BL_MOB, bl);
- nullpo_ret(mmd=va_arg(ap,struct mob_data *));
- if( mmd->bl.id == bl->id && !(battle_config.mob_ai&0x10) )
+ struct mob_data *md = va_arg(ap, struct mob_data *);
+
+ nullpo_ret(md);
+
+ if (md->bl.id == bl->id && (battle_config.mob_ai & 0x10) == 0)
+ return 0;
+
+ if (battle->check_target(&md->bl, bl, BCT_ENEMY) > 0)
return 0;
- if (battle->check_target(&mmd->bl,bl,BCT_ENEMY)>0)
+ int cond1 = va_arg(ap, int);
+ int cond2 = va_arg(ap, int);
+ struct block_list **fr = va_arg(ap, struct block_list **);
+
+ if ((*fr) != NULL) // A friend was already found.
return 0;
- cond1=va_arg(ap,int);
- cond2=va_arg(ap,int);
- fr=va_arg(ap,struct mob_data **);
- if( cond2==-1 ){
- int j;
- for(j=SC_COMMON_MIN;j<=SC_COMMON_MAX && !flag;j++){
- if ((flag=(md->sc.data[j] != NULL))) //Once an effect was found, break out. [Skotlex]
+
+ int flag = 0;
+ struct status_change *sc = status->get_sc(bl);
+
+ if (cond2 == -1) { // Check for any of the common status alignments.
+ for (int i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) {
+ if ((flag = (sc->data[i] != NULL)) != 0) // Once an effect was found, break out. [Skotlex]
break;
}
- }else
- flag=( md->sc.data[cond2] != NULL );
- if( flag^( cond1==MSC_FRIENDSTATUSOFF ) )
- (*fr)=md;
+ } else {
+ flag = (sc->data[cond2] != NULL);
+ }
+
+ if ((flag ^ (cond1 == MSC_FRIENDSTATUSOFF)) != 0)
+ (*fr) = bl;
return 0;
}
-static struct mob_data *mob_getfriendstatus(struct mob_data *md, int cond1, int cond2)
+/**
+ * Gets a random monster/character within a range of 8 cells around md.
+ * If md is summoned (no monster slave!) a character is picker, otherwise a monster.
+ *
+ * @param md The monster which tries to cast a skill.
+ * @param cond1 Whether to check for active or inactive status change. (MSC_FRIENDSTATUSON/MSC_FRIENDSTATUSOFF)
+ * @param cond2 The status change (SC_* flag) to check.
+ * @return A randomly picked monster/character within range.
+ *
+ **/
+static struct block_list *mob_getfriendstatus(struct mob_data *md, int cond1, int cond2)
{
- struct mob_data* fr = NULL;
nullpo_ret(md);
- map->foreachinrange(mob->getfriendstatus_sub, &md->bl, 8,BL_MOB, md,cond1,cond2,&fr);
+ int type = (md->special_state.ai != AI_NONE) ? BL_PC : BL_MOB;
+ struct block_list *fr = NULL;
+
+ map->foreachinrange(mob->getfriendstatus_sub, &md->bl, 8, type, md, cond1, cond2, &fr);
+
return fr;
}
-/*==========================================
- * Skill use judging
- *------------------------------------------*/
-static int mobskill_use(struct mob_data *md, int64 tick, int event)
+/**
+ * Checks if skill cast condition in fulfilled and executes the skill in case of success.
+ *
+ * @param md The monster which tries to cast a skill.
+ * @param tick The timestamp of skill execution.
+ * @param event The MSC_* flag which triggered the skill execution. (-1 for non-event skill conditions.)
+ * @return 0 on success, 1 on failure.
+ *
+ **/
+static int mob_skill_use(struct mob_data *md, int64 tick, int event)
{
- struct mob_skill *ms;
- struct block_list *fbl = NULL; //Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex]
- struct block_list *bl;
- struct mob_data *fmd = NULL;
- int i,j,n;
-
nullpo_ret(md);
- nullpo_ret(ms = md->db->skill);
- if (!battle_config.mob_skill_rate || md->ud.skilltimer != INVALID_TIMER || !md->db->maxskill)
- return 0;
+ struct mob_skill *ms = md->db->skill;
+
+ nullpo_ret(ms);
+
+ if (battle_config.mob_skill_rate == 0 || md->ud.skilltimer != INVALID_TIMER || md->db->maxskill == 0)
+ return 1;
if (event == -1 && DIFF_TICK(md->ud.canact_tick, tick) > 0)
- return 0; //Skill act delay only affects non-event skills.
+ return 1; // Skill act delay only affects non-event skill conditions.
- //Pick a starting position and loop from that.
- i = (battle_config.mob_ai&0x100) ? rnd()%md->db->maxskill : 0;
- for (n = 0; n < md->db->maxskill; i++, n++) {
- int c2, flag = 0;
+ // Pick a starting position and loop from that.
+ int skill_idx = ((battle_config.mob_ai & 0x100) != 0) ? rnd() % md->db->maxskill : 0;
- if (i == md->db->maxskill)
- i = 0;
+ for (int i = 0; i < md->db->maxskill; skill_idx++, i++) {
+ if (skill_idx == md->db->maxskill)
+ skill_idx = 0;
- if (DIFF_TICK(tick, md->skilldelay[i]) < ms[i].delay)
+ if (DIFF_TICK(tick, md->skilldelay[skill_idx]) < ms[skill_idx].delay)
continue;
- c2 = ms[i].cond2;
+ enum MobSkillState state = ms[skill_idx].state;
- if (ms[i].state != md->state.skillstate) {
- if (md->state.skillstate != MSS_DEAD && (ms[i].state == MSS_ANY ||
- (ms[i].state == MSS_ANYTARGET && md->target_id && md->state.skillstate != MSS_LOOT)
- )) //ANYTARGET works with any state as long as there's a target. [Skotlex]
- ;
- else
+ if (state != md->state.skillstate) {
+ bool state_dead = (md->state.skillstate == MSS_DEAD);
+ bool any_target = (state == MSS_ANYTARGET && md->target_id != 0 && md->state.skillstate != MSS_LOOT);
+
+ // MSS_ANYTARGET works with any state as long as there's a target. [Skotlex]
+ if (state_dead || (state != MSS_ANY && !any_target))
continue;
}
- if (rnd() % 10000 > ms[i].permillage) //Lupus (max value = 10000)
+
+ if (rnd() % 10000 > ms[skill_idx].permillage)
continue;
- if (ms[i].cond1 == event)
- flag = 1; //Trigger skill.
- else if (ms[i].cond1 == MSC_SKILLUSED)
- flag = ((event & 0xffff) == MSC_SKILLUSED && ((event >> 16) == c2 || c2 == 0));
- else if(event == -1){
- //Avoid entering on defined events to avoid "hyper-active skill use" due to the overflow of calls to this function in battle.
- switch (ms[i].cond1)
- {
- case MSC_ALWAYS:
- flag = 1; break;
- case MSC_MYHPLTMAXRATE: // HP< maxhp%
- flag = get_percentage(md->status.hp, md->status.max_hp);
- flag = (flag <= c2);
- break;
- case MSC_MYHPINRATE:
- flag = get_percentage(md->status.hp, md->status.max_hp);
- flag = (flag >= c2 && flag <= ms[i].val[0]);
- break;
- case MSC_MYSTATUSON: // status[num] on
- case MSC_MYSTATUSOFF: // status[num] off
- if (!md->sc.count) {
- flag = 0;
- } else if (ms[i].cond2 == -1) {
- for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++)
- if ((flag = (md->sc.data[j]!=NULL)) != 0)
- break;
- } else {
- flag = (md->sc.data[ms[i].cond2]!=NULL);
+ int cast_cond = ms[skill_idx].cond1;
+ int cond_data = ms[skill_idx].cond2;
+ int flag = 0;
+ struct block_list *fbl = NULL; // Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex]
+
+ if (cast_cond == event) {
+ flag = 1; // Trigger skill.
+ } else if (cast_cond == MSC_SKILLUSED) {
+ flag = ((event & 0xFFFF) == MSC_SKILLUSED && ((event >> 16) == cond_data || cond_data == 0));
+ } else if (event == -1) {
+ // Avoid entering on defined events to avoid "hyper-active skill use" due to the overflow of calls to this function in battle.
+ switch (cast_cond) {
+ case MSC_ALWAYS:
+ flag = 1;
+ break;
+ case MSC_MYHPLTMAXRATE: // HP <= x%
+ flag = get_percentage(md->status.hp, md->status.max_hp);
+ flag = (flag <= cond_data);
+ break;
+ case MSC_MYHPINRATE: // HP >= x% && HP <= y%
+ flag = get_percentage(md->status.hp, md->status.max_hp);
+ flag = (flag >= cond_data && flag <= ms[skill_idx].val[0]);
+ break;
+ case MSC_MYSTATUSON: // Status change x is active.
+ case MSC_MYSTATUSOFF: // Status change x is inactive.
+ if (cond_data == -1) { // Check for any of the common status alignments.
+ for (int j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++) {
+ if ((flag = (md->sc.data[j] != NULL)) != 0)
+ break;
}
- flag ^= (ms[i].cond1 == MSC_MYSTATUSOFF); break;
- case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp%
- flag = ((fbl = mob->getfriendhprate(md, 0, ms[i].cond2)) != NULL); break;
- case MSC_FRIENDHPINRATE:
- flag = ((fbl = mob->getfriendhprate(md, ms[i].cond2, ms[i].val[0])) != NULL); break;
- case MSC_FRIENDSTATUSON: // friend status[num] on
- case MSC_FRIENDSTATUSOFF: // friend status[num] off
- flag = ((fmd = mob->getfriendstatus(md, ms[i].cond1, ms[i].cond2)) != NULL); break;
- case MSC_SLAVELT: // slave < num
- flag = (mob->countslave(&md->bl) < c2 ); break;
- case MSC_ATTACKPCGT: // attack pc > num
- flag = (unit->counttargeted(&md->bl) > c2); break;
- case MSC_SLAVELE: // slave <= num
- flag = (mob->countslave(&md->bl) <= c2 ); break;
- case MSC_ATTACKPCGE: // attack pc >= num
- flag = (unit->counttargeted(&md->bl) >= c2); break;
- case MSC_AFTERSKILL:
- flag = (md->ud.skill_id == c2); break;
- case MSC_RUDEATTACKED:
- flag = (md->state.attacked_count >= RUDE_ATTACKED_COUNT);
- if (flag) md->state.attacked_count = 0; //Rude attacked count should be reset after the skill condition is met. Thanks to Komurka [Skotlex]
- break;
- case MSC_MASTERHPLTMAXRATE:
- flag = ((fbl = mob->getmasterhpltmaxrate(md, ms[i].cond2)) != NULL); break;
- case MSC_MASTERATTACKED:
- flag = (md->master_id > 0 && (fbl=map->id2bl(md->master_id)) != NULL && unit->counttargeted(fbl) > 0);
- break;
- case MSC_ALCHEMIST:
- flag = (md->state.alchemist);
- break;
+ } else {
+ flag = (md->sc.data[cond_data] != NULL);
+ }
+
+ flag ^= (cast_cond == MSC_MYSTATUSOFF);
+ break;
+ case MSC_FRIENDHPLTMAXRATE: // FriendHP <= x%
+ flag = ((fbl = mob->getfriendhprate(md, 0, cond_data)) != NULL);
+ break;
+ case MSC_FRIENDHPINRATE: // FriendHP >= x% && FriendHP <= y%
+ flag = ((fbl = mob->getfriendhprate(md, cond_data, ms[skill_idx].val[0])) != NULL);
+ break;
+ case MSC_FRIENDSTATUSON: // Friend's status change x is active.
+ case MSC_FRIENDSTATUSOFF: // Friend's status change x is inactive.
+ flag = ((fbl = mob->getfriendstatus(md, cast_cond, cond_data)) != NULL);
+ break;
+ case MSC_SLAVELT: // Monster has less than x active slaves.
+ flag = (mob->countslave(&md->bl) < cond_data);
+ break;
+ case MSC_ATTACKPCGT: // Monster is attacked by more than x units.
+ flag = (unit->counttargeted(&md->bl) > cond_data);
+ break;
+ case MSC_SLAVELE: // Monster has x or less active slaves.
+ flag = (mob->countslave(&md->bl) <= cond_data);
+ break;
+ case MSC_ATTACKPCGE: // Monster is attacked by x or more units.
+ flag = (unit->counttargeted(&md->bl) >= cond_data);
+ break;
+ case MSC_AFTERSKILL: // Monster used skill x, or any skill if x is 0.
+ flag = (md->ud.skill_id == cond_data || cond_data == 0);
+ break;
+ case MSC_RUDEATTACKED: // Monster was rude attacked RUDE_ATTACKED_COUNT or more times.
+ flag = (md->state.attacked_count >= RUDE_ATTACKED_COUNT);
+
+ // Rude attacked count should be reset after the skill condition is met. Thanks to Komurka [Skotlex]
+ if (flag)
+ md->state.attacked_count = 0;
+
+ break;
+ case MSC_MASTERHPLTMAXRATE: // MasterHP < x%
+ flag = ((fbl = mob->getmasterhpltmaxrate(md, cond_data)) != NULL);
+ break;
+ case MSC_MASTERATTACKED: // Monster's master is under attack.
+ flag = (md->master_id > 0 && (fbl = map->id2bl(md->master_id)) != NULL);
+ flag = (fbl != NULL && unit->counttargeted(fbl) > 0);
+ break;
+ case MSC_ALCHEMIST: // Monster was summoned by an Alchemist.
+ flag = (md->state.alchemist != 0);
+ break;
}
}
- if (!flag)
- continue; //Skill requisite failed to be fulfilled.
+ if (flag == 0) // Skill cast condition not fulfilled.
+ continue;
+
+ // Execute skill.
+ if (skill->get_casttype(ms[skill_idx].skill_id) == CAST_GROUND) { // Ground skill.
+ int target_type = ms[skill_idx].target;
+ int skill_range = skill->get_range2(&md->bl, ms[skill_idx].skill_id, ms[skill_idx].skill_lv);
+ struct block_list *bl;
- //Execute skill
- if (skill->get_casttype(ms[i].skill_id) == CAST_GROUND) {//Ground skill.
- short x, y;
- switch (ms[i].target) {
- case MST_RANDOM: //Pick a random enemy within skill range.
- bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md),
- skill->get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv));
- break;
- case MST_TARGET:
- case MST_AROUND5:
- case MST_AROUND6:
- case MST_AROUND7:
- case MST_AROUND8:
- bl = map->id2bl(md->target_id);
- break;
- case MST_MASTER:
- bl = &md->bl;
- if (md->master_id)
- bl = map->id2bl(md->master_id);
- if (bl) //Otherwise, fall through.
- break;
- FALLTHROUGH
- case MST_FRIEND:
- bl = fbl?fbl:(fmd?&fmd->bl:&md->bl);
- break;
- default:
- bl = &md->bl;
+ switch (target_type) {
+ case MST_RANDOM: // Pick a random enemy within skill range. Skill center is monster position.
+ bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), skill_range);
+ break;
+ case MST_TARGET: // Monster's current target is within skill range. Skill center is monster position.
+ case MST_AROUND5: // Monster's current target is within skill range. Skill center is a random cell within a range of 1.
+ case MST_AROUND6: // Monster's current target is within skill range. Skill center is a random cell within a range of 2.
+ case MST_AROUND7: // Monster's current target is within skill range. Skill center is a random cell within a range of 3.
+ case MST_AROUND8: // Monster's current target is within skill range. Skill center is a random cell within a range of 4.
+ bl = map->id2bl(md->target_id);
+ break;
+ case MST_MASTER: // Monster's master is within skill range. Skill center is monster position.
+ // If monster has no master, use the monster as target,
+ bl = (md->master_id != 0) ? map->id2bl(md->master_id) : &md->bl;
+
+ if (bl != NULL)
break;
+
+ // If monster has a master but master wasn't found, try a friend.
+ FALLTHROUGH
+ case MST_FRIEND: // Monster's friend is within skill range. Skill center is monster position.
+ bl = (fbl != NULL) ? fbl : &md->bl;
+ break;
+ default: // Monster is within skill range. Skill center is monster position.
+ bl = &md->bl;
+ break;
}
- if (!bl) continue;
-
- x = bl->x;
- y = bl->y;
- // Look for an area to cast the spell around...
- if (ms[i].target >= MST_AROUND1 || ms[i].target >= MST_AROUND5) {
- j = ms[i].target >= MST_AROUND1?
- (ms[i].target-MST_AROUND1) +1:
- (ms[i].target-MST_AROUND5) +1;
- map->search_freecell(&md->bl, md->bl.m, &x, &y, j, j, 3);
+
+ if (bl == NULL) // No target found.
+ continue;
+
+ short x = bl->x;
+ short y = bl->y;
+
+ // Find a target cell.
+ if (target_type >= MST_AROUND5 && target_type <= MST_AROUND) {
+ int range = target_type - ((target_type >= MST_AROUND1) ? MST_AROUND1 : MST_AROUND5) + 1;
+ map->search_freecell(&md->bl, md->bl.m, &x, &y, range, range, 3);
}
- md->skill_idx = i;
+
+ md->skill_idx = skill_idx;
map->freeblock_lock();
- if( !battle->check_range(&md->bl,bl,skill->get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv))
- || !unit->skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel)
- ) {
+
+ uint16 sk_id = ms[skill_idx].skill_id;
+ uint16 sk_lv = ms[skill_idx].skill_lv;
+ int casttime = ms[skill_idx].casttime;
+ short cancel = ms[skill_idx].cancel;
+
+ if (!battle->check_range(&md->bl, bl, skill_range)
+ || unit->skilluse_pos2(&md->bl, x, y, sk_id, sk_lv, casttime, cancel) == 0) {
map->freeblock_unlock();
continue;
}
- } else {
- //Targeted skill
- switch (ms[i].target) {
- case MST_RANDOM: //Pick a random enemy within skill range.
- bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md),
- skill->get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv));
- break;
- case MST_TARGET:
- bl = map->id2bl(md->target_id);
- break;
- case MST_MASTER:
- bl = &md->bl;
- if (md->master_id)
- bl = map->id2bl(md->master_id);
- if (bl) //Otherwise, fall through.
- break;
- FALLTHROUGH
- case MST_FRIEND:
- if (fbl) {
- bl = fbl;
- break;
- } else if (fmd) {
- bl = &fmd->bl;
- break;
- } // else fall through
- FALLTHROUGH
- default:
- bl = &md->bl;
+ } else { // Targeted skill.
+ int skill_range = skill->get_range2(&md->bl, ms[skill_idx].skill_id, ms[skill_idx].skill_lv);
+ struct block_list *bl;
+
+ switch (ms[skill_idx].target) {
+ case MST_RANDOM: // Pick a random enemy within skill range.
+ bl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), skill_range);
+ break;
+ case MST_TARGET: // Monster's current target is within skill range.
+ bl = map->id2bl(md->target_id);
+ break;
+ case MST_MASTER: // Monster's master is within skill range.
+ // If monster has no master, use the monster as target,
+ bl = (md->master_id != 0) ? map->id2bl(md->master_id) : &md->bl;
+
+ if (bl != NULL)
break;
+
+ // If monster has a master but master wasn't found, try a friend.
+ FALLTHROUGH
+ case MST_FRIEND: // Monster's friend is within skill range.
+ bl = (fbl != NULL) ? fbl : &md->bl;
+ break;
+ default: // Monster is within skill range.
+ bl = &md->bl;
+ break;
}
- if (!bl) continue;
- md->skill_idx = i;
+ if (bl == NULL) // No target found.
+ continue;
+
+ md->skill_idx = skill_idx;
map->freeblock_lock();
- if( !battle->check_range(&md->bl,bl,skill->get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv))
- || !unit->skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel)
- ) {
+
+ uint16 sk_id = ms[skill_idx].skill_id;
+ uint16 sk_lv = ms[skill_idx].skill_lv;
+ int casttime = ms[skill_idx].casttime;
+ short cancel = ms[skill_idx].cancel;
+
+ if (!battle->check_range(&md->bl, bl, skill_range)
+ || unit->skilluse_id2(&md->bl, bl->id, sk_id, sk_lv, casttime, cancel) == 0) {
map->freeblock_unlock();
continue;
}
}
- //Skill used. Post-setups...
- if ( ms[ i ].msg_id ){ //Display color message [SnakeDrak]
- struct mob_chat *mc = mob->chat(ms[i].msg_id);
+
+ // Skill used.
+ if (ms[skill_idx].msg_id != 0) { // Display color message. [SnakeDrak]
char temp[CHAT_SIZE_MAX];
char name[NAME_LENGTH];
- snprintf(name, sizeof name,"%s", md->name);
- strtok(name, "#"); // discard extra name identifier if present [Daegaladh]
- safesnprintf(temp, sizeof temp,"%s : %s", name, mc->msg);
+ struct mob_chat *mc = mob->chat(ms[skill_idx].msg_id);
+
+ snprintf(name, sizeof(name), "%s", md->name);
+ strtok(name, "#"); // Discard extra name identifier if present. [Daegaladh]
+ safesnprintf(temp, sizeof(temp), "%s : %s", name, mc->msg);
clif->messagecolor(&md->bl, mc->color, temp);
}
- if(!(battle_config.mob_ai&0x200)) { //pass on delay to same skill.
- for (j = 0; j < md->db->maxskill; j++)
- if (md->db->skill[j].skill_id == ms[i].skill_id)
- md->skilldelay[j]=tick;
- } else
- md->skilldelay[i]=tick;
+
+ if ((battle_config.mob_ai & 0x200) == 0) { // Pass on delay to same skill.
+ for (int j = 0; j < md->db->maxskill; j++) {
+ if (md->db->skill[j].skill_id == ms[skill_idx].skill_id)
+ md->skilldelay[j] = tick;
+ }
+ } else {
+ md->skilldelay[skill_idx] = tick;
+ }
+
map->freeblock_unlock();
- return 1;
+ return 0;
}
- //No skill was used.
+
+ // No skill was used.
md->skill_idx = -1;
- return 0;
+ return 1;
}
+
/*==========================================
* Skill use event processing
*------------------------------------------*/
@@ -3663,7 +3739,7 @@ static int mobskill_event(struct mob_data *md, struct block_list *src, int64 tic
nullpo_ret(md);
nullpo_ret(src);
if(md->bl.prev == NULL || md->status.hp <= 0)
- return 0;
+ return 1;
if (md->special_state.ai == AI_SPHERE) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
md->state.alchemist = 1;
@@ -3683,7 +3759,7 @@ static int mobskill_event(struct mob_data *md, struct block_list *src, int64 tic
else if (flag&BF_LONG && !(flag&BF_MAGIC)) //Long-attacked should not include magic.
res = mob->skill_use(md, tick, MSC_LONGRANGEATTACKED);
- if (!res)
+ if (res != 0)
//Restore previous target only if skill condition failed to trigger. [Skotlex]
md->target_id = target_id;
//Otherwise check if the target is an enemy, and unlock if needed.
@@ -3907,8 +3983,8 @@ static int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16
}
}
- mob_skills[i].permillage *= battle_config.mob_skill_rate / 100;
- mob_skills[i].delay *= battle_config.mob_skill_delay / 100;
+ mob_skills[i].permillage = mob_skills[i].permillage * battle_config.mob_skill_rate / 100;
+ mob_skills[i].delay = mob_skills[i].delay * battle_config.mob_skill_delay / 100;
db->maxskill = ++i;
}
@@ -5012,12 +5088,10 @@ static int mob_read_db_sub(struct config_setting_t *mobt, int n, const char *sou
md.status.def_ele = i32;
md.status.ele_lv = value;
} else if (!inherit) {
- ShowWarning("mob_read_db_sub: Missing element for monster ID %d.\n", md.mob_id);
md.status.def_ele = ELE_NEUTRAL;
md.status.ele_lv = 1;
}
} else if (!inherit) {
- ShowWarning("mob_read_db_sub: Missing element for monster ID %d.\n", md.mob_id);
md.status.def_ele = ELE_NEUTRAL;
md.status.ele_lv = 1;
}
@@ -5491,115 +5565,134 @@ static bool mob_skill_db_libconfig_sub(struct config_setting_t *it, int n)
return true;
}
+/**
+ * Reads a single monster skill from DB.
+ *
+ * @param it The libconfig settings block, which contains the skill data.
+ * @param n The skill data block's index within the parent monster block.
+ * @param mob_id The monster's ID.
+ * @return true on success, false on failure.
+ *
+ **/
static bool mob_skill_db_libconfig_sub_skill(struct config_setting_t *it, int n, int mob_id)
{
- int i, j, idx = 0;
- int i32;
- int skill_id = 0;
- int skill_idx = 0;
- bool clearskills = false;
- const char *name = config_setting_name(it);
- struct mob_skill *ms, gms;
-
nullpo_retr(false, it);
Assert_retr(false, mob_id <= 0 || mob->db(mob_id) != mob->dummy);
- if (!(skill_id = skill->name2id(name))) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Non existant skill id %d in monster %d, skipping.\n", skill_id, mob_id);
+ int skill_id = 0;
+ const char *name = config_setting_name(it);
+ const char *mob_str = (mob_id < 0) ? "global ID" : "monster";
+
+ if ((skill_id = skill->name2id(name)) == 0) {
+ ShowWarning("%s: Non existant skill %d in %s %d, skipping.\n", __func__, skill_id, mob_str, mob_id);
return false;
}
+ const char *skill_name = skill->get_name(skill_id);
+ bool clearskills = false;
+
// If ClearSkills flag is enabled clear all the previous skills.
- if (libconfig->setting_lookup_bool_real(it, "ClearSkills", &clearskills) && clearskills) {
- if (mob_id < 0) // Clearing skills globaly is not supported
+ if (libconfig->setting_lookup_bool_real(it, "ClearSkills", &clearskills) == CONFIG_TRUE && clearskills) {
+ if (mob_id < 0) {
+ ShowError("%s: Global skill clearing is not supported, skipping. (Global ID %d, skill %d (%s).)\n",
+ __func__, mob_id, skill_id, skill_name);
return false;
+ }
+
memset(mob->db_data[mob_id]->skill, 0, sizeof(struct mob_skill) * MAX_MOBSKILL);
mob->db_data[mob_id]->maxskill = 0;
return true;
}
- if (mob_id < 0) {
- // Prepare global skill. [Skotlex]
+ struct mob_skill *ms;
+
+ if (mob_id < 0) { // Prepare global skill. [Skotlex]
+ struct mob_skill gms;
memset(&gms, 0, sizeof (struct mob_skill));
ms = &gms;
} else {
+ int idx = 0;
+
ARR_FIND(0, MAX_MOBSKILL, idx, (ms = &mob->db_data[mob_id]->skill[idx])->skill_id == 0);
+
if (idx == MAX_MOBSKILL) {
- ShowError("mob_skill_db_libconfig_sub_skill: Too many skills for monster %d\n", mob_id);
+ ShowError("%s: Too many skills for monster %d, skipping.\n", __func__, mob_id);
return false;
}
+
+ mob->db_data[mob_id]->maxskill = idx + 1;
}
+
ms->skill_id = skill_id;
+ int i32 = MSS_ANY;
if (mob->lookup_const(it, "SkillState", &i32) && (i32 < MSS_ANY || i32 > MSS_ANYTARGET)) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill state %d for skill id %d in monster %d, defaulting to MSS_ANY.\n", i32, skill_id, mob_id);
+ ShowWarning("%s: Invalid skill state %d for skill %d (%s) in %s %d, defaulting to MSS_ANY.\n",
+ __func__, i32, skill_id, skill_name, mob_str, mob_id);
i32 = MSS_ANY;
}
ms->state = i32;
- if (!libconfig->setting_lookup_int(it, "SkillLevel", &i32) || i32 <= 0)
- i32 = 1;
- ms->skill_lv = i32 > battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : i32; //we strip max skill level
+ int res = libconfig->setting_lookup_int(it, "SkillLevel", &i32);
+ ms->skill_lv = (res == CONFIG_FALSE) ? 1 : cap_value(i32, 1, battle_config.mob_max_skilllvl);
- //Apply battle_config modifiers to rate (permillage) and delay [Skotlex]
- if (libconfig->setting_lookup_int(it, "Rate", &i32))
- ms->permillage = i32;
+ res = libconfig->setting_lookup_int(it, "Rate", &i32);
+ ms->permillage = (res == CONFIG_FALSE) ? 1 : cap_value(i32, 1, 10000);
+ // Apply battle_config modifier to rate (permillage).
if (battle_config.mob_skill_rate != 100)
ms->permillage = ms->permillage * battle_config.mob_skill_rate / 100;
+
if (ms->permillage > 10000)
ms->permillage = 10000;
- else if (ms->permillage == 0 && battle_config.mob_skill_rate)
+ else if (ms->permillage == 0 && battle_config.mob_skill_rate != 0)
ms->permillage = 1;
- if (libconfig->setting_lookup_int(it, "CastTime", &i32) && i32 > 0)
- ms->casttime = i32;
+ res = libconfig->setting_lookup_int(it, "CastTime", &i32);
+ ms->casttime = (res == CONFIG_FALSE) ? 0 : cap_value(i32, 0, MOB_MAX_CASTTIME);
+
+ res = libconfig->setting_lookup_int(it, "Delay", &i32);
+ ms->delay = (res == CONFIG_FALSE) ? 0 : cap_value(i32, 0, MOB_MAX_DELAY);
- if (libconfig->setting_lookup_int(it, "Delay", &i32))
- ms->delay = i32;
+ // Apply battle_config modifier to delay.
if (battle_config.mob_skill_delay != 100)
ms->delay = ms->delay * battle_config.mob_skill_delay / 100;
- if (ms->delay < 0 || ms->delay > MOB_MAX_DELAY) //time overflow?
- ms->delay = MOB_MAX_DELAY;
- if (libconfig->setting_lookup_bool(it, "Cancelable", &i32))
- ms->cancel = (i32 == 0) ? 0 : 1;
+ ms->delay = min(ms->delay, MOB_MAX_DELAY);
+
+ res = libconfig->setting_lookup_bool(it, "Cancelable", &i32);
+ ms->cancel = (res == CONFIG_FALSE) ? 0 : cap_value(i32, 0, 1);
+ i32 = MST_TARGET;
if (mob->lookup_const(it, "SkillTarget", &i32) && (i32 < MST_TARGET || i32 > MST_AROUND)) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill target %d for skill id %d in monster %d, defaulting to MST_TARGET.\n", i32, skill_id, mob_id);
- ms->target = MST_TARGET;
+ ShowWarning("%s: Invalid skill target %d for skill %d (%s) in %s %d, defaulting to MST_TARGET.\n",
+ __func__, i32, skill_id, skill_name, mob_str, mob_id);
+ i32 = MST_TARGET;
}
ms->target = i32;
- //Check that the target condition is right for the skill type. [Skotlex]
- skill_idx = skill->get_index(skill_id);
- if (skill->get_casttype2(skill_idx) == CAST_GROUND) {//Ground skill.
- if (ms->target > MST_AROUND) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Wrong mob skill target for ground skill %d (%s) for %s.\n",
- ms->skill_id, skill->dbs->db[skill_idx].name,
- mob_id < 0 ? "all mobs" : mob->db_data[mob_id]->sprite);
- ms->target = MST_TARGET;
- }
- } else if (ms->target > MST_MASTER) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
- ms->skill_id, skill->dbs->db[skill_idx].name,
- mob_id < 0 ? "all mobs" : mob->db_data[mob_id]->sprite);
+ // Check the target condition for non-ground skills. (Ground skills can use every target.)
+ if (skill->get_casttype2(skill->get_index(skill_id)) != CAST_GROUND && ms->target > MST_MASTER) {
+ ShowWarning("%s: Wrong skill target %d for non-ground skill %d (%s) in %s %d, defaulting to MST_TARGET.\n",
+ __func__, ms->target, skill_id, skill_name, mob_str, mob_id);
ms->target = MST_TARGET;
}
+ i32 = MSC_ALWAYS;
if (mob->lookup_const(it, "CastCondition", &i32) && (i32 < MSC_ALWAYS || i32 > MSC_SPAWN)) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill condition %d for skill id %d in monster %d, defaulting to MSC_ALWAYS.\n", i32, skill_id, mob_id);
- ms->cond1 = MSC_ALWAYS;
+ ShowWarning("%s: Invalid skill condition %d for skill id %d (%s) in %s %d, defaulting to MSC_ALWAYS.\n",
+ __func__, i32, skill_id, skill_name, mob_str, mob_id);
+ i32 = MSC_ALWAYS;
}
ms->cond1 = i32;
- if (mob->lookup_const(it, "ConditionData", &i32))
- ms->cond2 = i32;
+ ms->cond2 = !mob->lookup_const(it, "ConditionData", &i32) ? 0 : cap_value(i32, SHRT_MIN, SHRT_MAX);
- for (i = 0; i < 5; i++) {
+ for (int i = 0; i < 5; i++) {
char valname[16];
sprintf(valname, "val%1d", i);
- if (libconfig->setting_lookup_int(it, valname, &i32))
+
+ if (libconfig->setting_lookup_int(it, valname, &i32) == CONFIG_TRUE)
ms->val[i] = i32;
}
@@ -5610,60 +5703,64 @@ static bool mob_skill_db_libconfig_sub_skill(struct config_setting_t *it, int n,
if (mob_id > 0 && (uint32)ms->val[1] == mob->db(mob_id)->status.mode) {
ms->val[1] = MD_NONE;
- ms->val[4] = 1; //request to return mode to normal.
+ ms->val[4] = 1; // Request to return mode to normal.
}
}
if (ms->skill_id == NPC_EMOTION_ON && mob_id > 0 && ms->val[1] != MD_NONE) {
- //Adds a mode to the mob.
- //Remove aggressive mode when the new mob type is passive.
- if (!(ms->val[1] & MD_AGGRESSIVE))
+ // Add a mode to the mob and remove aggressive mode if the new mode is passive.
+ if ((ms->val[1] & MD_AGGRESSIVE) == 0)
ms->val[3] |= MD_AGGRESSIVE;
- ms->val[2] |= (uint32)ms->val[1]; //Add the new mode.
- ms->val[1] = MD_NONE; //Do not "set" it.
+
+ ms->val[2] |= (uint32)ms->val[1]; // Add the new mode.
+ ms->val[1] = MD_NONE; // Do not "set" it.
}
- if (libconfig->setting_lookup_int(it, "Emotion", &i32))
- ms->emotion = i32;
- else
- ms->emotion = -1;
+ res = libconfig->setting_lookup_int(it, "Emotion", &i32);
+ ms->emotion = (res == CONFIG_FALSE) ? -1 : cap_value(i32, -1, SHRT_MAX);
- if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) && i32 > 0 && i32 <= MAX_MOB_CHAT) {
- if (mob->chat_db[i32] == NULL) {
- ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid msg id %d for skill id %d in monster %d, ignoring.\n", i32, skill_id, mob_id);
+ if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) == CONFIG_TRUE) {
+ if (i32 <= 0 || i32 > MAX_MOB_CHAT || mob->chat_db[i32] == NULL) {
+ ShowWarning("%s: Invalid message ID %d for skill %d (%s) in %s %d, ignoring.\n",
+ __func__, i32, skill_id, skill_name, mob_str, mob_id);
} else {
ms->msg_id = i32;
}
}
- if (mob_id < 0) {
- // Set this skill to ALL mobs. [Skotlex]
- mob_id *= -1;
- for (i = 1; i < MAX_MOB_DB; i++) {
+ if (mob_id < 0) { // Global skill assignment.
+ mob_id = -mob_id;
+
+ for (int i = 1; i < MAX_MOB_DB; i++) {
if (mob->db_data[i] == NULL)
continue;
- if (mob->db_data[i]->status.mode & MD_BOSS) {
- if (!(mob_id & 2)) //Skill not for bosses
+
+ if ((mob->db_data[i]->status.mode & MD_BOSS) != 0) {
+ if ((mob_id & 2) == 0) // Skill not for boss monsters.
continue;
} else {
- if (!(mob_id & 1)) //Skill not for normal enemies.
+ if ((mob_id & 1) == 0) // Skill not for normal monsters.
continue;
}
- ARR_FIND(0, MAX_MOBSKILL, j, mob->db_data[i]->skill[j].skill_id == 0);
- if (j == MAX_MOBSKILL)
+
+ int idx;
+
+ ARR_FIND(0, MAX_MOBSKILL, idx, mob->db_data[i]->skill[idx].skill_id == 0);
+
+ if (idx == MAX_MOBSKILL) {
+ ShowError("%s: Too many skills for monster %d in global ID %d, skipping.\n",
+ __func__, i, -mob_id);
continue;
+ }
- memcpy(&mob->db_data[i]->skill[j], ms, sizeof(struct mob_skill));
- mob->db_data[i]->maxskill = j + 1;
+ memcpy(&mob->db_data[i]->skill[idx], ms, sizeof(struct mob_skill));
+ mob->db_data[i]->maxskill = idx + 1;
}
- } else { //Skill set on a single mob.
- mob->db_data[mob_id]->maxskill = idx + 1;
}
return true;
}
-
/*==========================================
* mob_skill_db.txt reading
*------------------------------------------*/
@@ -6059,7 +6156,7 @@ void mob_defaults(void)
mob->getmasterhpltmaxrate = mob_getmasterhpltmaxrate;
mob->getfriendstatus_sub = mob_getfriendstatus_sub;
mob->getfriendstatus = mob_getfriendstatus;
- mob->skill_use = mobskill_use;
+ mob->skill_use = mob_skill_use;
mob->skill_event = mobskill_event;
mob->is_clone = mob_is_clone;
mob->clone_spawn = mob_clone_spawn;
diff --git a/src/map/mob.h b/src/map/mob.h
index 4cfddc2cd..6ad1ce705 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -323,6 +323,13 @@ enum {
MSC_SPAWN,
};
+/** Special monster(-name) constants used to assign skills to a group of monsters. **/
+enum mob_group {
+ ALL_MOBS_NONBOSS = -1,
+ ALL_MOBS_BOSS = -2,
+ ALL_MOBS = -3,
+};
+
/**
* Mob IDs
*/
@@ -566,7 +573,7 @@ struct mob_interface {
struct block_list* (*getfriendhprate) (struct mob_data *md, int min_rate, int max_rate);
struct block_list* (*getmasterhpltmaxrate) (struct mob_data *md, int rate);
int (*getfriendstatus_sub) (struct block_list *bl, va_list ap);
- struct mob_data* (*getfriendstatus) (struct mob_data *md, int cond1, int cond2);
+ struct block_list *(*getfriendstatus) (struct mob_data *md, int cond1, int cond2);
int (*skill_use) (struct mob_data *md, int64 tick, int event);
int (*skill_event) (struct mob_data *md, struct block_list *src, int64 tick, int flag);
int (*is_clone) (int class_);
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index 0ca84cff4..0df323e96 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -394,7 +394,8 @@ static int npc_chat_sub(struct block_list *bl, va_list ap)
// save out the matched strings
for (i = 0; i < r; i++)
{
- char var[15], val[255];
+ char var[SCRIPT_VARNAME_LENGTH + 1];
+ char val[SCRIPT_STRING_VAR_LENGTH + 1];
snprintf(var, sizeof(var), "$@p%i$", i);
libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val));
script->set_var(sd, var, val);
diff --git a/src/map/packets.h b/src/map/packets.h
index 1e6dc71bc..e30acbdf7 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -1824,6 +1824,11 @@ packet(0x96e,clif->ackmergeitems);
packet(0x0aa4, clif->pRefineryUIClose);
#endif
+#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+ packet(0x0ab5, clif->pLapineUpgrade_close);
+ packet(0x0ab6, clif->pLapineUpgrade_makeItem);
+#endif
+
// 2017-02-28aRagexeRE
#if PACKETVER >= 20170228
// new packets
diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h
index e3a89827c..8ebbb39be 100644
--- a/src/map/packets_keys_main.h
+++ b/src/map/packets_keys_main.h
@@ -37,7 +37,7 @@
packetKeys(0x49357d72,0x22c370a1,0x5f836591);
#endif
-// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-06bRagexeRE, 2019-11-07aRagexe, 2019-11-07aRagexeRE, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-13eRagexeRE, 2019-11-20aRagexe, 2019-11-20cRagexeRE, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27aRagexeRE, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04aRagexeRE, 2019-12-04bRagexe, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11aRagexe, 2019-12-11fRagexeRE, 2019-12-18bRagexe, 2019-12-18bRagexeRE, 2019-12-24aRagexe, 2019-12-24aRagexeRE, 2019-12-24bRagexe, 2019-12-24bRagexeRE, 2020-01-08aRagexe, 2020-01-08bRagexeRE, 2020-01-22cRagexe, 2020-01-22cRagexeRE, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-05aRagexeRE, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-12aRagexeRE, 2020-02-19dRagexe, 2020-02-19eRagexeRE, 2020-03-04aRagexe, 2020-03-04aRagexeRE, 2020-03-18bRagexe, 2020-04-01bRagexe
+// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-06bRagexeRE, 2019-11-07aRagexe, 2019-11-07aRagexeRE, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-13eRagexeRE, 2019-11-20aRagexe, 2019-11-20cRagexeRE, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27aRagexeRE, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04aRagexeRE, 2019-12-04bRagexe, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11aRagexe, 2019-12-11fRagexeRE, 2019-12-18bRagexe, 2019-12-18bRagexeRE, 2019-12-24aRagexe, 2019-12-24aRagexeRE, 2019-12-24bRagexe, 2019-12-24bRagexeRE, 2020-01-08aRagexe, 2020-01-08bRagexeRE, 2020-01-22cRagexe, 2020-01-22cRagexeRE, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-05aRagexeRE, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-12aRagexeRE, 2020-02-19dRagexe, 2020-02-19eRagexeRE, 2020-03-04aRagexe, 2020-03-04aRagexeRE, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe
#if PACKETVER == 20101123 || \
PACKETVER == 20101124 || \
PACKETVER == 20101125 || \
@@ -191,7 +191,8 @@
PACKETVER == 20200219 || \
PACKETVER == 20200304 || \
PACKETVER == 20200318 || \
- PACKETVER >= 20200401
+ PACKETVER == 20200401 || \
+ PACKETVER >= 20200414
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h
index f189032d3..904159d37 100644
--- a/src/map/packets_keys_zero.h
+++ b/src/map/packets_keys_zero.h
@@ -30,7 +30,7 @@
/* This file is autogenerated, please do not commit manual changes */
-// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero
+// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero
#if PACKETVER == 20171018 || \
PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
@@ -110,7 +110,8 @@
PACKETVER == 20200226 || \
PACKETVER == 20200304 || \
PACKETVER == 20200318 || \
- PACKETVER >= 20200401
+ PACKETVER == 20200401 || \
+ PACKETVER >= 20200414
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h
index beedc950f..d643f3b0e 100644
--- a/src/map/packets_shuffle_main.h
+++ b/src/map/packets_shuffle_main.h
@@ -9794,7 +9794,7 @@
packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14
#endif
-// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-07aRagexe, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-20aRagexe, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04bRagexe, 2019-12-11aRagexe, 2019-12-18bRagexe, 2019-12-24aRagexe, 2019-12-24bRagexe, 2020-01-08aRagexe, 2020-01-22cRagexe, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-19dRagexe, 2020-03-04aRagexe, 2020-03-18bRagexe, 2020-04-01bRagexe
+// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-07aRagexe, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-20aRagexe, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04bRagexe, 2019-12-11aRagexe, 2019-12-18bRagexe, 2019-12-24aRagexe, 2019-12-24bRagexe, 2020-01-08aRagexe, 2020-01-22cRagexe, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-19dRagexe, 2020-03-04aRagexe, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe
#if PACKETVER == 20190904 || \
PACKETVER == 20190918 || \
PACKETVER == 20190925 || \
@@ -9822,7 +9822,8 @@
PACKETVER == 20200219 || \
PACKETVER == 20200304 || \
PACKETVER == 20200318 || \
- PACKETVER == 20200401
+ PACKETVER == 20200401 || \
+ PACKETVER == 20200414
packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26
packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5
packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36
diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h
index 15936f854..fb12688c0 100644
--- a/src/map/packets_shuffle_zero.h
+++ b/src/map/packets_shuffle_zero.h
@@ -803,7 +803,7 @@
packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14
#endif
-// 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero
+// 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero
#if PACKETVER == 20190828 || \
PACKETVER == 20190911 || \
PACKETVER == 20190918 || \
@@ -822,7 +822,8 @@
PACKETVER == 20200226 || \
PACKETVER == 20200304 || \
PACKETVER == 20200318 || \
- PACKETVER == 20200401
+ PACKETVER == 20200401 || \
+ PACKETVER == 20200414
packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26
packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5
packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index ca2fb8aef..3129a05d9 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -3891,6 +3891,42 @@ struct PACKET_ZC_AUTORUN_SKILL {
} __attribute__((packed));
DEFINE_PACKET_HEADER(ZC_AUTORUN_SKILL, 0x0147);
+#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_LAPINEUPGRADE_OPEN {
+ int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+ uint32 itemId;
+#else
+ uint16 itemId;
+#endif
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_LAPINEUPGRADE_OPEN, 0x0ab4);
+
+struct PACKET_ZC_LAPINEUPGRADE_RESULT {
+ int16 packetType;
+ uint16 result;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_LAPINEUPGRADE_RESULT, 0x0ab7);
+#endif // PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
+
+#if PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_LAPINEUPGRADE_CLOSE {
+ int16 packetType;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_LAPINEUPGRADE_CLOSE, 0x0ab5);
+
+struct PACKET_CZ_LAPINEUPGRADE_MAKE_ITEM {
+ int16 packetType;
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+ uint32 itemId;
+#else
+ uint16 itemId;
+#endif
+ uint16 index;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_LAPINEUPGRADE_MAKE_ITEM, 0x0ab6);
+#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris
diff --git a/src/map/pc.c b/src/map/pc.c
index 90282209b..5faadf76a 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1605,58 +1605,56 @@ static void pc_calc_skilltree_clear(struct map_session_data *sd)
*------------------------------------------*/
static int pc_calc_skilltree(struct map_session_data *sd)
{
- int i,id=0,flag;
- int class = 0, classidx = 0;
-
nullpo_ret(sd);
- i = pc->calc_skilltree_normalize_job(sd);
- class = pc->mapid2jobid(i, sd->status.sex);
+ uint32 job = pc->calc_skilltree_normalize_job(sd);
+ int class = pc->mapid2jobid(job, sd->status.sex);
if (class == -1) {
//Unable to normalize job??
- ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id);
+ ShowError("pc_calc_skilltree: Unable to normalize job %u for character %s (%d:%d)\n", job, sd->status.name, sd->status.account_id, sd->status.char_id);
return 1;
}
- classidx = pc->class2idx(class);
+ int classidx = pc->class2idx(class);
pc->calc_skilltree_clear(sd);
- for (i = 0; i < MAX_SKILL_DB; i++) {
- if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
- { // Restore original level of skills after deleting earned skills.
+ for (int i = 0; i < MAX_SKILL_DB; i++) {
+ if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0) {
+ // Restore original level of skills after deleting earned skills.
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
}
- if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU )
- { //Enable Bard/Dancer spirit linked skills.
- if (sd->status.sex) {
- // Link dancer skills to bard.
- if (i < 8) {
- Assert_report(i >= 8);
- continue;
- }
- if (sd->status.skill[i-8].lv < 10)
- continue;
- sd->status.skill[i].id = skill->dbs->db[i].nameid;
- sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
- sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
+ if (sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER
+ && ((skill->dbs->db[i].nameid >= BA_WHISTLE && skill->dbs->db[i].nameid <= BA_APPLEIDUN)
+ || (skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU))
+ ) {
+ //Enable Bard/Dancer spirit linked skills.
+ int linked_nameid = skill->get_linked_song_dance_id(skill->dbs->db[i].nameid);
+ if (linked_nameid == 0) {
+ Assert_report("Linked bard/dance skill not found");
+ continue;
+ }
+ int copy_from_index;
+ int copy_to_index;
+ if (sd->status.sex == SEX_MALE && skill->dbs->db[i].nameid >= BA_WHISTLE && skill->dbs->db[i].nameid <= BA_APPLEIDUN) {
+ copy_from_index = i;
+ copy_to_index = skill->get_index(linked_nameid);
} else {
- // Link bard skills to dancer.
- if (i < 8) {
- Assert_report(i >= 8);
- continue;
- }
- if (sd->status.skill[i].lv < 10)
- continue;
- sd->status.skill[i-8].id = skill->dbs->db[i-8].nameid;
- sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
- sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
+ copy_from_index = skill->get_index(linked_nameid);
+ copy_to_index = i;
}
+ if (copy_from_index < copy_to_index)
+ continue; // Copy only after the source skill has been filled into the tree
+ if (sd->status.skill[copy_from_index].lv < 10)
+ continue; // Copy only if the linked skill has been mastered
+ sd->status.skill[copy_to_index].id = skill->dbs->db[copy_to_index].nameid;
+ sd->status.skill[copy_to_index].lv = sd->status.skill[copy_from_index].lv; // Set the level to the same as the linking skill
+ sd->status.skill[copy_to_index].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
}
}
if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) {
- for (i = 0; i < MAX_SKILL_DB; i++) {
+ for (int i = 0; i < MAX_SKILL_DB; i++) {
switch(skill->dbs->db[i].nameid) {
/**
* Dummy skills must be added here otherwise they'll be displayed in the,
@@ -1688,9 +1686,11 @@ static int pc_calc_skilltree(struct map_session_data *sd)
return 0;
}
+ bool changed = false;
do {
- flag = 0;
- for (i = 0; i < MAX_SKILL_TREE && (id = pc->skill_tree[classidx][i].id) > 0; i++) {
+ changed = false;
+ int id;
+ for (int i = 0; i < MAX_SKILL_TREE && (id = pc->skill_tree[classidx][i].id) > 0; i++) {
int idx = pc->skill_tree[classidx][i].idx;
bool satisfied = true;
if (sd->status.skill[idx].id > 0)
@@ -1740,10 +1740,10 @@ static int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[idx].lv = 1; // need to manually specify a skill level
sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
}
- flag = 1; // skill list has changed, perform another pass
+ changed = true; // skill list has changed, perform another pass
}
}
- } while(flag);
+ } while (changed);
pc->calc_skilltree_bonus(sd, classidx);
@@ -4206,7 +4206,7 @@ static int pc_skill(struct map_session_data *sd, int id, int level, int flag)
if( sd->status.skill[index].id == id ) {
if( sd->status.skill[index].lv >= level )
return 0;
- if( sd->status.skill[index].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
+ if (sd->status.skill[index].flag == SKILL_FLAG_PERMANENT) // Non-granted skill, store its level.
sd->status.skill[index].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[index].lv;
} else {
sd->status.skill[index].id = id;
@@ -7568,7 +7568,7 @@ static int pc_allskillup(struct map_session_data *sd)
nullpo_ret(sd);
for (i = 0; i < MAX_SKILL_DB; i++) {
- if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
+ if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0) {
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
if (sd->status.skill[i].lv == 0)
@@ -8325,7 +8325,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)
base_penalty *= 2;
if (sd->status.mod_death != 100)
- base_penalty *= sd->status.mod_death / 100;
+ base_penalty = base_penalty * sd->status.mod_death / 100;
sd->status.base_exp -= min(sd->status.base_exp, base_penalty);
clif->updatestatus(sd, SP_BASEEXP);
@@ -8350,7 +8350,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)
job_penalty *= 2;
if (sd->status.mod_death != 100)
- job_penalty *= sd->status.mod_death / 100;
+ job_penalty = job_penalty * sd->status.mod_death / 100;
sd->status.job_exp -= min(sd->status.job_exp, job_penalty);
clif->updatestatus(sd, SP_JOBEXP);
@@ -9288,6 +9288,72 @@ static int pc_changelook(struct map_session_data *sd, int type, int val)
return 0;
}
+/**
+ * Hides a character.
+ *
+ * @param sd The character to hide.
+ * @param show_msg Whether to show message to the character or not.
+ *
+ **/
+static void pc_hide(struct map_session_data *sd, bool show_msg)
+{
+ nullpo_retv(sd);
+
+ clif->clearunit_area(&sd->bl, CLR_OUTSIGHT);
+ sd->sc.option |= OPTION_INVISIBLE;
+ sd->vd.class = INVISIBLE_CLASS;
+
+ if (show_msg)
+ clif->message(sd->fd, atcommand->msgsd(sd, 11)); // Invisible: On
+
+ // Decrement the number of pvp players on the map.
+ map->list[sd->bl.m].users_pvp--;
+
+ if (map->list[sd->bl.m].flag.pvp != 0 && map->list[sd->bl.m].flag.pvp_nocalcrank == 0
+ && sd->pvp_timer != INVALID_TIMER) { // Unregister the player for ranking.
+ timer->delete(sd->pvp_timer, pc->calc_pvprank_timer);
+ sd->pvp_timer = INVALID_TIMER;
+ }
+
+ clif->changeoption(&sd->bl);
+}
+
+/**
+ * Unhides a character.
+ *
+ * @param sd The character to unhide.
+ * @param show_msg Whether to show message to the character or not.
+ *
+ **/
+static void pc_unhide(struct map_session_data *sd, bool show_msg)
+{
+ nullpo_retv(sd);
+
+ sd->sc.option &= ~OPTION_INVISIBLE;
+
+ if (sd->disguise != -1)
+ status->set_viewdata(&sd->bl, sd->disguise);
+ else
+ status->set_viewdata(&sd->bl, sd->status.class);
+
+ if (show_msg)
+ clif->message(sd->fd, atcommand->msgsd(sd, 10)); // Invisible: Off
+
+ // Increment the number of pvp players on the map.
+ map->list[sd->bl.m].users_pvp++;
+
+ if (map->list[sd->bl.m].flag.pvp != 0 && map->list[sd->bl.m].flag.pvp_nocalcrank == 0) // Register the player for ranking.
+ sd->pvp_timer = timer->add(timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0);
+
+ // bugreport:2266
+ map->foreachinmovearea(clif->insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl);
+
+ if (sd->disguise != -1)
+ clif->spawn_unit(&sd->bl, AREA_WOS);
+
+ clif->changeoption(&sd->bl);
+}
+
/*==========================================
* Give an option (type) to player (sd) and display it to client
*------------------------------------------*/
@@ -9299,7 +9365,13 @@ static int pc_setoption(struct map_session_data *sd, int type)
//Option has to be changed client-side before the class sprite or it won't always work (eg: Wedding sprite) [Skotlex]
sd->sc.option=type;
- clif->changeoption(&sd->bl);
+
+ if ((p_type & OPTION_INVISIBLE) != 0 && (type & OPTION_INVISIBLE) == 0) // Unhide character.
+ pc->unhide(sd, false);
+ else if ((p_type & OPTION_INVISIBLE) == 0 && (type & OPTION_INVISIBLE) != 0) // Hide character.
+ pc->hide(sd, false);
+ else
+ clif->changeoption(&sd->bl);
if( (type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc->checkskill(sd,RK_DRAGONTRAINING) > 0) ) {
// Mounting
@@ -11256,7 +11328,7 @@ static int pc_charm_timer(int tid, int64 tick, int id, intptr_t data)
* @param max Maximum amount of charms to add.
* @param type Charm type (@see spirit_charm_types)
*/
-static void pc_add_charm(struct map_session_data *sd, int interval, int max, int type)
+static void pc_add_charm(struct map_session_data *sd, int interval, int max, enum spirit_charm_types type)
{
int tid, i;
@@ -11298,7 +11370,7 @@ static void pc_add_charm(struct map_session_data *sd, int interval, int max, int
* @param count Amount of charms to remove.
* @param type Type of charm to remove.
*/
-static void pc_del_charm(struct map_session_data *sd, int count, int type)
+static void pc_del_charm(struct map_session_data *sd, int count, enum spirit_charm_types type)
{
int i;
@@ -12824,6 +12896,8 @@ void pc_defaults(void)
pc->itemheal = pc_itemheal;
pc->percentheal = pc_percentheal;
pc->jobchange = pc_jobchange;
+ pc->hide = pc_hide;
+ pc->unhide = pc_unhide;
pc->setoption = pc_setoption;
pc->setcart = pc_setcart;
pc->setfalcon = pc_setfalcon;
diff --git a/src/map/pc.h b/src/map/pc.h
index 2699b7882..e560df549 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -439,7 +439,7 @@ END_ZEROED_BLOCK;
int spiritball, spiritball_old;
int spirit_timer[MAX_SPIRITBALL];
int charm_count;
- int charm_type;
+ enum spirit_charm_types charm_type;
int charm_timer[MAX_SPIRITCHARM];
unsigned char potion_success_counter; //Potion successes in row counter
unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
@@ -678,6 +678,7 @@ END_ZEROED_BLOCK;
#define pc_isidle(sd) ( (sd)->chat_id != 0 || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(sockt->last_tick, (sd)->idletime) >= battle->bc->idle_no_share )
#define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading )
#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
+#define pc_cant_act_except_lapine(sd) ((sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1)
/* equals pc_cant_act except it doesn't check for chat rooms */
#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
@@ -687,7 +688,7 @@ END_ZEROED_BLOCK;
#define pc_ishiding(sd) ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) )
#define pc_iscloaking(sd) ( !((sd)->sc.option&OPTION_CHASEWALK) && ((sd)->sc.option&OPTION_CLOAK) )
#define pc_ischasewalk(sd) ( (sd)->sc.option&OPTION_CHASEWALK )
-#define pc_ismuted(sc,type) ( (sc)->data[SC_NOCHAT] && (sc)->data[SC_NOCHAT]->val1&(type) )
+#define pc_ismuted(sc, type) ( (sc)->data[SC_NOCHAT] != NULL && (battle_config.manner_system & (type)) != 0 )
#define pc_isvending(sd) ((sd)->state.vending || (sd)->state.prevend || (sd)->state.buyingstore)
#ifdef NEW_CARTS
@@ -1044,6 +1045,8 @@ END_ZEROED_BLOCK; /* End */
int (*itemheal) (struct map_session_data *sd,int itemid, int hp,int sp);
int (*percentheal) (struct map_session_data *sd,int hp,int sp);
int (*jobchange) (struct map_session_data *sd, int class, int upper);
+ void (*hide) (struct map_session_data *sd, bool show_msg);
+ void (*unhide) (struct map_session_data *sd, bool show_msg);
int (*setoption) (struct map_session_data *sd,int type);
int (*setcart) (struct map_session_data* sd, int type);
void (*setfalcon) (struct map_session_data *sd, bool flag);
@@ -1127,8 +1130,8 @@ END_ZEROED_BLOCK; /* End */
int (*load_combo) (struct map_session_data *sd);
- void (*add_charm) (struct map_session_data *sd, int interval, int max, int type);
- void (*del_charm) (struct map_session_data *sd, int count, int type);
+ void (*add_charm) (struct map_session_data *sd, int interval, int max, enum spirit_charm_types type);
+ void (*del_charm) (struct map_session_data *sd, int count, enum spirit_charm_types type);
void (*baselevelchanged) (struct map_session_data *sd);
int (*level_penalty_mod) (int diff, unsigned char race, uint32 mode, int type);
diff --git a/src/map/pet.c b/src/map/pet.c
index 620779765..299de42c7 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -323,7 +323,7 @@ static int pet_hungry(int tid, int64 tick, int id, intptr_t data)
}
clif->send_petdata(sd, pd, 2, pd->pet.hungry);
- interval *= battle_config.pet_hungry_delay_rate / 100;
+ interval = interval * battle_config.pet_hungry_delay_rate / 100;
pd->pet_hungry_timer = timer->add(tick + max(interval, 1), pet->hungry, sd->bl.id, 0);
return 0;
@@ -944,7 +944,7 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
else
intimacy += pd->petDB->r_hungry / 2; // Increase intimacy by 50% of FeedIncrement.
- intimacy *= battle_config.pet_friendly_rate / 100;
+ intimacy = intimacy * battle_config.pet_friendly_rate / 100;
pet->set_intimate(pd, pd->pet.intimate + intimacy);
if (pd->pet.intimate == PET_INTIMACY_NONE) {
@@ -1128,12 +1128,22 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, int
return 0;
}
+/**
+ * Calls pet_ai_sub_hard() for a character's pet if conditions are fulfilled.
+ *
+ * @param sd The character.
+ * @param ap Additional arguments. In this case only the time stamp of pet AI timer execution.
+ * @return Always 0.
+ *
+ **/
static int pet_ai_sub_foreachclient(struct map_session_data *sd, va_list ap)
{
- int64 tick = va_arg(ap,int64);
nullpo_ret(sd);
- if(sd->status.pet_id && sd->pd)
- pet->ai_sub_hard(sd->pd,sd,tick);
+
+ int64 tick = va_arg(ap, int64);
+
+ if (sd->bl.prev != NULL && sd->status.pet_id != 0 && sd->pd != NULL && sd->pd->bl.prev != NULL)
+ pet->ai_sub_hard(sd->pd, sd, tick);
return 0;
}
diff --git a/src/map/script.c b/src/map/script.c
index c08f5e829..347ef3d2a 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3395,6 +3395,32 @@ static void set_reg_instance_num(struct script_state *st, int64 num, const char
}
/**
+ * Validates if a variable is permanent (stored in database) by passed variable name.
+ *
+ * @param name The variable name to validate.
+ * @return True if variable is permanent, otherwise false.
+ *
+ **/
+static bool script_is_permanent_variable(const char *name)
+{
+ nullpo_retr(false, name);
+
+ if (strlen(name) == 0)
+ return false;
+
+ if (ISALNUM(name[0]) != 0)
+ return true; // Permanent characater variable.
+
+ if (name[0] == '#')
+ return true; // Permanent (global) account variable.
+
+ if (strlen(name) > 1 && name[0] == '$' && ISALNUM(name[1]) != 0)
+ return true; // Permanent server variable.
+
+ return false;
+}
+
+/**
* Stores the value of a script variable
*
* @param st current script state.
@@ -3439,6 +3465,18 @@ static int set_reg(struct script_state *st, struct map_session_data *sd, int64 n
if (is_string_variable(name)) {// string variable
const char *str = (const char*)value;
+ if (script->is_permanent_variable(name) && strlen(str) > SCRIPT_STRING_VAR_LENGTH) {
+ ShowError("script:set_reg: Value of variable %s is too long: %lu! Maximum is %d. Skipping...\n",
+ name, strlen(str), SCRIPT_STRING_VAR_LENGTH);
+
+ if (st != NULL) {
+ script->reportsrc(st);
+ st->state = END;
+ }
+
+ return 0;
+ }
+
switch (prefix) {
case '@':
if (ref) {
@@ -16111,7 +16149,6 @@ static BUILDIN(atcommand)
struct map_session_data *sd, *dummy_sd = NULL;
int fd;
const char* cmd;
- bool ret = true;
cmd = script_getstr(st,2);
@@ -16134,11 +16171,12 @@ static BUILDIN(atcommand)
if (!atcommand->exec(fd, sd, cmd, false)) {
ShowWarning("script: buildin_atcommand: failed to execute command '%s'\n", cmd);
- script->reportsrc(st);
- ret = false;
+ if (dummy_sd != NULL)
+ aFree(dummy_sd);
+ return false;
}
if (dummy_sd) aFree(dummy_sd);
- return ret;
+ return true;
}
/**
@@ -27847,6 +27885,11 @@ static void script_hardcoded_constants(void)
script->set_constant("MST_AROUND4", MST_AROUND4, false, false);
script->set_constant("MST_AROUND", MST_AROUND , false, false);
+ script->constdb_comment("Monster group constants");
+ script->set_constant("ALL_MOBS_NONBOSS", ALL_MOBS_NONBOSS, false, false);
+ script->set_constant("ALL_MOBS_BOSS", ALL_MOBS_BOSS, false, false);
+ script->set_constant("ALL_MOBS", ALL_MOBS, false, false);
+
script->constdb_comment("pc block constants, use with *setpcblock* and *checkpcblock*");
script->set_constant("PCBLOCK_NONE", PCBLOCK_NONE, false, false);
script->set_constant("PCBLOCK_MOVE", PCBLOCK_MOVE, false, false);
@@ -28250,6 +28293,7 @@ void script_defaults(void)
script->load_parameters = script_load_parameters;
script->print_line = script_print_line;
script->errorwarning_sub = script_errorwarning_sub;
+ script->is_permanent_variable = script_is_permanent_variable;
script->set_reg = set_reg;
script->set_reg_ref_str = set_reg_npcscope_str;
script->set_reg_pc_ref_str = set_reg_pc_ref_str;
diff --git a/src/map/script.h b/src/map/script.h
index 511497a66..5fa81dc0e 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -984,6 +984,7 @@ struct script_interface {
void (*load_parameters) (void);
const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line);
void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
+ bool (*is_permanent_variable) (const char *name);
int (*set_reg) (struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
void (*set_reg_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
void (*set_reg_pc_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
diff --git a/src/map/skill.c b/src/map/skill.c
index 3dccf7a9e..caa1a0f29 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -72,6 +72,34 @@ static struct s_skill_dbs skilldbs;
struct skill_interface *skill;
+static const struct {
+ int start;
+ int end;
+} skill_idx_ranges[] = {
+ { NV_BASIC, NPC_LEX_AETERNA },
+ { KN_CHARGEATK, SA_ELEMENTWIND },
+ { RK_ENCHANTBLADE, AB_SILENTIUM },
+ { WL_WHITEIMPRISON, SC_FEINTBOMB },
+ { LG_CANNONSPEAR, SR_GENTLETOUCH_REVITALIZE },
+ { WA_SWING_DANCE, WA_MOONLIT_SERENADE },
+ { MI_RUSH_WINDMILL, MI_HARMONIZE },
+ { WM_LESSON, WM_UNLIMITED_HUMMING_VOICE },
+ { SO_FIREWALK, SO_EARTH_INSIGNIA },
+ { GN_TRAINING_SWORD, GN_SLINGITEM_RANGEMELEEATK },
+ { AB_SECRAMENT, LG_OVERBRAND_PLUSATK },
+ { ALL_ODINS_RECALL, ALL_LIGHTGUARD },
+ { RL_GLITTERING_GREED, RL_GLITTERING_GREED_ATK },
+ { KO_YAMIKUMO, OB_AKAITSUKI },
+ { ECL_SNOWFLIP, ALL_THANATOS_RECALL },
+ { GC_DARKCROW, NC_MAGMA_ERUPTION_DOTDAMAGE },
+ { SU_BASIC_SKILL, SU_SPIRITOFSEA },
+ { HLIF_HEAL, MH_VOLCANIC_ASH },
+ { MS_BASH, MER_INVINCIBLEOFF2 },
+ { EL_CIRCLE_OF_FIRE, EL_STONE_RAIN },
+ { GD_APPROVAL, GD_DEVELOPMENT },
+ CUSTOM_SKILL_RANGES
+};
+
//Since only mob-casted splash skills can hit ice-walls
static int skill_splash_target(struct block_list *bl)
{
@@ -96,51 +124,37 @@ static int skill_name2id(const char *name)
/// Returns the skill's array index, or 0 (Unknown Skill).
static int skill_get_index(int skill_id)
{
- int skillRange[] = { NV_BASIC, NPC_LEX_AETERNA,
- KN_CHARGEATK, SA_ELEMENTWIND,
- RK_ENCHANTBLADE, AB_SILENTIUM,
- WL_WHITEIMPRISON, SC_FEINTBOMB,
- LG_CANNONSPEAR, SR_GENTLETOUCH_REVITALIZE,
- WA_SWING_DANCE, WA_MOONLIT_SERENADE,
- MI_RUSH_WINDMILL, MI_HARMONIZE,
- WM_LESSON, WM_UNLIMITED_HUMMING_VOICE,
- SO_FIREWALK, SO_EARTH_INSIGNIA,
- GN_TRAINING_SWORD, GN_SLINGITEM_RANGEMELEEATK,
- AB_SECRAMENT, LG_OVERBRAND_PLUSATK,
- ALL_ODINS_RECALL, ALL_LIGHTGUARD,
- RL_GLITTERING_GREED, RL_GLITTERING_GREED_ATK,
- KO_YAMIKUMO, OB_AKAITSUKI,
- ECL_SNOWFLIP, ALL_THANATOS_RECALL,
- GC_DARKCROW, NC_MAGMA_ERUPTION_DOTDAMAGE,
- SU_BASIC_SKILL, SU_SPIRITOFSEA,
- HLIF_HEAL, MH_VOLCANIC_ASH,
- MS_BASH, MER_INVINCIBLEOFF2,
- EL_CIRCLE_OF_FIRE, EL_STONE_RAIN,
- GD_APPROVAL, GD_DEVELOPMENT
- CUSTOM_SKILL_RANGES};
- int length = sizeof(skillRange) / sizeof(int);
- STATIC_ASSERT(sizeof(skillRange) / sizeof(int) % 2 == 0, "skill_get_index: skillRange should be multiple of 2");
-
-
- if (skill_id < skillRange[0] || skill_id > skillRange[length - 1]) {
+ int length = ARRAYLENGTH(skill_idx_ranges);
+
+
+ if (skill_id < skill_idx_ranges[0].start || skill_id > skill_idx_ranges[length - 1].end) {
ShowWarning("skill_get_index: skill id '%d' is not being handled!\n", skill_id);
+ Assert_report(0);
return 0;
}
int skill_idx = 0;
+ bool found = false;
// Map Skill ID to Skill Indexes (in reverse order)
- for (int i = 0; i < length; i += 2) {
+ for (int i = 0; i < length; i++) {
// Check if SkillID belongs to this range.
- if (skill_id <= skillRange[i + 1] && skill_id >= skillRange[i]) {
- skill_idx += (skillRange[i + 1] - skill_id);
+ if (skill_id <= skill_idx_ranges[i].end && skill_id >= skill_idx_ranges[i].start) {
+ skill_idx += (skill_idx_ranges[i].end - skill_id);
+ found = true;
break;
}
// Add the difference of current range
- skill_idx += (skillRange[i + 1] - skillRange[i] + 1);
+ skill_idx += (skill_idx_ranges[i].end - skill_idx_ranges[i].start + 1);
}
+ if (!found) {
+ ShowWarning("skill_get_index: skill id '%d' (idx: %d) is not handled as it lies outside the defined ranges!\n", skill_id, skill_idx);
+ Assert_report(0);
+ return 0;
+ }
if (skill_idx >= MAX_SKILL_DB) {
ShowWarning("skill_get_index: skill id '%d'(idx: %d) is not being handled as it exceeds MAX_SKILL_DB!\n", skill_id, skill_idx);
+ Assert_report(0);
return 0;
}
@@ -1012,6 +1026,9 @@ static int skillnotok(uint16 skill_id, struct map_session_data *sd)
if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
return 0; // can do any damn thing they want
+ if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNOSKILL))
+ return 1; // block usage on 'noskill' cells [Wolfie]
+
if (skill_id == AL_TELEPORT && sd->autocast.type == AUTOCAST_ITEM && sd->autocast.skill_lv > 2)
return 0; // Teleport level 3 and higher bypasses this check if cast by itemskill() script commands.
@@ -5005,7 +5022,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl
if( (tsc = status->get_sc(bl)) && (tsc->data[SC_HIDING] )) {
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
} else
- skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
+ skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
}
break;
case NPC_SELFDESTRUCTION: {
@@ -7383,7 +7400,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
int rate = 100 * (100 - (tstatus->int_ / 2 + tstatus->vit / 3 + tstatus->luk / 10));
int duration = skill->get_time2(skill_id, skill_lv);
- duration *= (100 - (tstatus->int_ + tstatus->vit) / 2) / 100;
+ duration = duration * (100 - (tstatus->int_ + tstatus->vit) / 2) / 100;
status->change_start(src, bl, SC_BLIND, rate, 1, 0, 0, 0, duration, SCFLAG_NONE);
}
@@ -10470,7 +10487,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
case KO_KAZEHU_SEIRAN:
case KO_DOHU_KOUKAI:
if(sd) {
- int ttype = skill->get_ele(skill_id, skill_lv);
+ enum spirit_charm_types ttype = skill->get_ele(skill_id, skill_lv);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
pc->add_charm(sd, skill->get_time(skill_id, skill_lv), MAX_SPIRITCHARM, ttype); // replace existing charms of other type
}
@@ -10927,6 +10944,37 @@ static int skill_count_wos(struct block_list *bl, va_list ap)
return 0;
}
+/**
+ * Returns the linked song/dance skill ID, if any (for the Bard/Dancer Soul Link).
+ *
+ * @param skill_id The skill ID to look up
+ *
+ * @return The linked song or dance's skill ID if any
+ * @retval 0 if the given skill_id doesn't have a linked skill ID
+ */
+static int skill_get_linked_song_dance_id(int skill_id)
+{
+ switch (skill_id) {
+ case BA_WHISTLE:
+ return DC_HUMMING;
+ case BA_ASSASSINCROSS:
+ return DC_DONTFORGETME;
+ case BA_POEMBRAGI:
+ return DC_FORTUNEKISS;
+ case BA_APPLEIDUN:
+ return DC_SERVICEFORYOU;
+ case DC_HUMMING:
+ return BA_WHISTLE;
+ case DC_DONTFORGETME:
+ return BA_ASSASSINCROSS;
+ case DC_FORTUNEKISS:
+ return BA_POEMBRAGI;
+ case DC_SERVICEFORYOU:
+ return BA_APPLEIDUN;
+ }
+ return 0;
+}
+
/*==========================================
*
*------------------------------------------*/
@@ -11296,7 +11344,7 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill
FALLTHROUGH
case GS_GROUNDDRIFT: //Ammo should be deleted right away.
if ( skill_id == WM_SEVERE_RAINSTORM )
- sc_start(src,src,SC_NO_SWITCH_EQUIP,100,0,skill->get_time(skill_id,skill_lv));
+ sc_start(src, src, type, 100, 0, skill->get_time(skill_id, skill_lv));
skill->unitsetting(src,skill_id,skill_lv,x,y,0);
break;
case WZ_ICEWALL:
@@ -21801,4 +21849,5 @@ void skill_defaults(void)
skill->splash_target = skill_splash_target;
skill->check_npc_chaospanic = skill_check_npc_chaospanic;
skill->count_wos = skill_count_wos;
+ skill->get_linked_song_dance_id = skill_get_linked_song_dance_id;
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 65195dc75..4dbbaf147 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -2200,6 +2200,7 @@ struct skill_interface {
int (*splash_target) (struct block_list* bl);
int (*check_npc_chaospanic) (struct block_list *bl, va_list args);
int (*count_wos) (struct block_list *bl, va_list ap);
+ int (*get_linked_song_dance_id) (int skill_id);
};
#ifdef HERCULES_CORE
diff --git a/src/map/status.c b/src/map/status.c
index 5ea4d880d..dc49f7e4e 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -696,6 +696,7 @@ static void initChangeTables(void)
status->set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SCB_STR|SCB_CRI|SCB_MAXHP );
status->set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SCB_NONE );
status->set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SCB_MAXHP );
+ status->set_sc( WM_SEVERE_RAINSTORM , SC_NO_SWITCH_EQUIP , SCB_NONE );
/**
* Sorcerer
@@ -7832,6 +7833,9 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
calc_flag = status->dbs->ChangeFlagTable[type];
if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs
switch(type) {
+ case SC_AUTOTRADE:
+ case SC_KSPROTECTED:
+ break; // Prevent calling status_change_start_unknown_sc().
case SC_ADORAMUS:
sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1));
// Fall through to SC_INC_AGI
@@ -8076,7 +8080,6 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
// This is done this way because the message that the client displays is hardcoded, and only
// shows how many minutes are remaining. [Panikon]
total_tick = 60000;
- val1 = battle_config.manner_system; //Mute filters.
if (sd)
{
clif->changestatus(sd,SP_MANNER,sd->status.manner);
diff --git a/src/map/unit.c b/src/map/unit.c
index d484056f9..19f09f83c 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -436,7 +436,7 @@ static int unit_walk_toxy_timer(int tid, int64 tick, int id, intptr_t data)
// Walk skills are triggered regardless of target due to the idle-walk mob state.
// But avoid triggering on stop-walk calls.
if (tid != INVALID_TIMER && (ud->walk_count % WALK_SKILL_INTERVAL) == 0
- && map->list[bl->m].users > 0 && mob->skill_use(md, tick, -1) == 1) {
+ && map->list[bl->m].users > 0 && mob->skill_use(md, tick, -1) == 0) {
// Walk skills are supposed to be used while walking
if (!(ud->skill_id == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER)
&& md->state.skillstate != MSS_WALK) {
@@ -2345,7 +2345,7 @@ static int unit_attack_timer_sub(struct block_list *src, int tid, int64 tick)
if(md) {
//First attack is always a normal attack
if(md->state.skillstate == MSS_ANGRY || md->state.skillstate == MSS_BERSERK) {
- if (mob->skill_use(md,tick,-1)) {
+ if (mob->skill_use(md, tick, -1) == 0) {
map->freeblock_unlock();
return 1;
}
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index b8aa5ae61..ef71f1967 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -1410,6 +1410,10 @@ typedef void (*HPMHOOK_pre_clif_chatname_ack) (int *fd, struct block_list **bl);
typedef void (*HPMHOOK_post_clif_chatname_ack) (int fd, struct block_list *bl);
typedef void (*HPMHOOK_pre_clif_elemname_ack) (int *fd, struct block_list **bl);
typedef void (*HPMHOOK_post_clif_elemname_ack) (int fd, struct block_list *bl);
+typedef void (*HPMHOOK_pre_clif_skillname_ack) (int *fd, struct block_list **bl);
+typedef void (*HPMHOOK_post_clif_skillname_ack) (int fd, struct block_list *bl);
+typedef void (*HPMHOOK_pre_clif_itemname_ack) (int *fd, struct block_list **bl);
+typedef void (*HPMHOOK_post_clif_itemname_ack) (int fd, struct block_list *bl);
typedef void (*HPMHOOK_pre_clif_unknownname_ack) (int *fd, struct block_list **bl);
typedef void (*HPMHOOK_post_clif_unknownname_ack) (int fd, struct block_list *bl);
typedef void (*HPMHOOK_pre_clif_monster_hp_bar) (struct mob_data **md, struct map_session_data **sd);
@@ -2762,6 +2766,14 @@ typedef void (*HPMHOOK_pre_clif_plapineDdukDdak_ack) (int *fd, struct map_sessio
typedef void (*HPMHOOK_post_clif_plapineDdukDdak_ack) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_plapineDdukDdak_close) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_plapineDdukDdak_close) (int fd, struct map_session_data *sd);
+typedef bool (*HPMHOOK_pre_clif_lapineUpgrade_open) (struct map_session_data **sd, int *item_id);
+typedef bool (*HPMHOOK_post_clif_lapineUpgrade_open) (bool retVal___, struct map_session_data *sd, int item_id);
+typedef bool (*HPMHOOK_pre_clif_lapineUpgrade_result) (struct map_session_data **sd, enum lapineUpgrade_result *result);
+typedef bool (*HPMHOOK_post_clif_lapineUpgrade_result) (bool retVal___, struct map_session_data *sd, enum lapineUpgrade_result result);
+typedef void (*HPMHOOK_pre_clif_pLapineUpgrade_close) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pLapineUpgrade_close) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_pLapineUpgrade_makeItem) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pLapineUpgrade_makeItem) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_pReqGearOff) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pReqGearOff) (int fd, struct map_session_data *sd);
#endif // MAP_CLIF_H
@@ -5452,8 +5464,8 @@ typedef struct block_list* (*HPMHOOK_pre_mob_getmasterhpltmaxrate) (struct mob_d
typedef struct block_list* (*HPMHOOK_post_mob_getmasterhpltmaxrate) (struct block_list* retVal___, struct mob_data *md, int rate);
typedef int (*HPMHOOK_pre_mob_getfriendstatus_sub) (struct block_list **bl, va_list ap);
typedef int (*HPMHOOK_post_mob_getfriendstatus_sub) (int retVal___, struct block_list *bl, va_list ap);
-typedef struct mob_data* (*HPMHOOK_pre_mob_getfriendstatus) (struct mob_data **md, int *cond1, int *cond2);
-typedef struct mob_data* (*HPMHOOK_post_mob_getfriendstatus) (struct mob_data* retVal___, struct mob_data *md, int cond1, int cond2);
+typedef struct block_list* (*HPMHOOK_pre_mob_getfriendstatus) (struct mob_data **md, int *cond1, int *cond2);
+typedef struct block_list* (*HPMHOOK_post_mob_getfriendstatus) (struct block_list* retVal___, struct mob_data *md, int cond1, int cond2);
typedef int (*HPMHOOK_pre_mob_skill_use) (struct mob_data **md, int64 *tick, int *event);
typedef int (*HPMHOOK_post_mob_skill_use) (int retVal___, struct mob_data *md, int64 tick, int event);
typedef int (*HPMHOOK_pre_mob_skill_event) (struct mob_data **md, struct block_list **src, int64 *tick, int *flag);
@@ -6210,6 +6222,10 @@ typedef int (*HPMHOOK_pre_pc_percentheal) (struct map_session_data **sd, int *hp
typedef int (*HPMHOOK_post_pc_percentheal) (int retVal___, struct map_session_data *sd, int hp, int sp);
typedef int (*HPMHOOK_pre_pc_jobchange) (struct map_session_data **sd, int *class, int *upper);
typedef int (*HPMHOOK_post_pc_jobchange) (int retVal___, struct map_session_data *sd, int class, int upper);
+typedef void (*HPMHOOK_pre_pc_hide) (struct map_session_data **sd, bool *show_msg);
+typedef void (*HPMHOOK_post_pc_hide) (struct map_session_data *sd, bool show_msg);
+typedef void (*HPMHOOK_pre_pc_unhide) (struct map_session_data **sd, bool *show_msg);
+typedef void (*HPMHOOK_post_pc_unhide) (struct map_session_data *sd, bool show_msg);
typedef int (*HPMHOOK_pre_pc_setoption) (struct map_session_data **sd, int *type);
typedef int (*HPMHOOK_post_pc_setoption) (int retVal___, struct map_session_data *sd, int type);
typedef int (*HPMHOOK_pre_pc_setcart) (struct map_session_data **sd, int *type);
@@ -6340,10 +6356,10 @@ typedef void (*HPMHOOK_pre_pc_itemcd_do) (struct map_session_data **sd, bool *lo
typedef void (*HPMHOOK_post_pc_itemcd_do) (struct map_session_data *sd, bool load);
typedef int (*HPMHOOK_pre_pc_load_combo) (struct map_session_data **sd);
typedef int (*HPMHOOK_post_pc_load_combo) (int retVal___, struct map_session_data *sd);
-typedef void (*HPMHOOK_pre_pc_add_charm) (struct map_session_data **sd, int *interval, int *max, int *type);
-typedef void (*HPMHOOK_post_pc_add_charm) (struct map_session_data *sd, int interval, int max, int type);
-typedef void (*HPMHOOK_pre_pc_del_charm) (struct map_session_data **sd, int *count, int *type);
-typedef void (*HPMHOOK_post_pc_del_charm) (struct map_session_data *sd, int count, int type);
+typedef void (*HPMHOOK_pre_pc_add_charm) (struct map_session_data **sd, int *interval, int *max, enum spirit_charm_types *type);
+typedef void (*HPMHOOK_post_pc_add_charm) (struct map_session_data *sd, int interval, int max, enum spirit_charm_types type);
+typedef void (*HPMHOOK_pre_pc_del_charm) (struct map_session_data **sd, int *count, enum spirit_charm_types *type);
+typedef void (*HPMHOOK_post_pc_del_charm) (struct map_session_data *sd, int count, enum spirit_charm_types type);
typedef void (*HPMHOOK_pre_pc_baselevelchanged) (struct map_session_data **sd);
typedef void (*HPMHOOK_post_pc_baselevelchanged) (struct map_session_data *sd);
typedef int (*HPMHOOK_pre_pc_level_penalty_mod) (int *diff, unsigned char *race, uint32 *mode, int *type);
@@ -6972,6 +6988,8 @@ typedef const char* (*HPMHOOK_pre_script_print_line) (StringBuf **buf, const cha
typedef const char* (*HPMHOOK_post_script_print_line) (const char* retVal___, StringBuf *buf, const char *p, const char *mark, int line);
typedef void (*HPMHOOK_pre_script_errorwarning_sub) (StringBuf **buf, const char **src, const char **file, int *start_line, const char **error_msg, const char **error_pos);
typedef void (*HPMHOOK_post_script_errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
+typedef bool (*HPMHOOK_pre_script_is_permanent_variable) (const char **name);
+typedef bool (*HPMHOOK_post_script_is_permanent_variable) (bool retVal___, const char *name);
typedef int (*HPMHOOK_pre_script_set_reg) (struct script_state **st, struct map_session_data **sd, int64 *num, const char **name, const void **value, struct reg_db **ref);
typedef int (*HPMHOOK_post_script_set_reg) (int retVal___, struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
typedef void (*HPMHOOK_pre_script_set_reg_ref_str) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str);
@@ -7668,6 +7686,8 @@ typedef int (*HPMHOOK_pre_skill_check_npc_chaospanic) (struct block_list **bl, v
typedef int (*HPMHOOK_post_skill_check_npc_chaospanic) (int retVal___, struct block_list *bl, va_list args);
typedef int (*HPMHOOK_pre_skill_count_wos) (struct block_list **bl, va_list ap);
typedef int (*HPMHOOK_post_skill_count_wos) (int retVal___, struct block_list *bl, va_list ap);
+typedef int (*HPMHOOK_pre_skill_get_linked_song_dance_id) (int *skill_id);
+typedef int (*HPMHOOK_post_skill_get_linked_song_dance_id) (int retVal___, int skill_id);
#endif // MAP_SKILL_H
#ifdef COMMON_SOCKET_H /* sockt */
typedef void (*HPMHOOK_pre_sockt_init) (void);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 109c30885..e8cb41240 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -1000,6 +1000,10 @@ struct {
struct HPMHookPoint *HP_clif_chatname_ack_post;
struct HPMHookPoint *HP_clif_elemname_ack_pre;
struct HPMHookPoint *HP_clif_elemname_ack_post;
+ struct HPMHookPoint *HP_clif_skillname_ack_pre;
+ struct HPMHookPoint *HP_clif_skillname_ack_post;
+ struct HPMHookPoint *HP_clif_itemname_ack_pre;
+ struct HPMHookPoint *HP_clif_itemname_ack_post;
struct HPMHookPoint *HP_clif_unknownname_ack_pre;
struct HPMHookPoint *HP_clif_unknownname_ack_post;
struct HPMHookPoint *HP_clif_monster_hp_bar_pre;
@@ -2352,6 +2356,14 @@ struct {
struct HPMHookPoint *HP_clif_plapineDdukDdak_ack_post;
struct HPMHookPoint *HP_clif_plapineDdukDdak_close_pre;
struct HPMHookPoint *HP_clif_plapineDdukDdak_close_post;
+ struct HPMHookPoint *HP_clif_lapineUpgrade_open_pre;
+ struct HPMHookPoint *HP_clif_lapineUpgrade_open_post;
+ struct HPMHookPoint *HP_clif_lapineUpgrade_result_pre;
+ struct HPMHookPoint *HP_clif_lapineUpgrade_result_post;
+ struct HPMHookPoint *HP_clif_pLapineUpgrade_close_pre;
+ struct HPMHookPoint *HP_clif_pLapineUpgrade_close_post;
+ struct HPMHookPoint *HP_clif_pLapineUpgrade_makeItem_pre;
+ struct HPMHookPoint *HP_clif_pLapineUpgrade_makeItem_post;
struct HPMHookPoint *HP_clif_pReqGearOff_pre;
struct HPMHookPoint *HP_clif_pReqGearOff_post;
struct HPMHookPoint *HP_cmdline_init_pre;
@@ -4790,6 +4802,10 @@ struct {
struct HPMHookPoint *HP_pc_percentheal_post;
struct HPMHookPoint *HP_pc_jobchange_pre;
struct HPMHookPoint *HP_pc_jobchange_post;
+ struct HPMHookPoint *HP_pc_hide_pre;
+ struct HPMHookPoint *HP_pc_hide_post;
+ struct HPMHookPoint *HP_pc_unhide_pre;
+ struct HPMHookPoint *HP_pc_unhide_post;
struct HPMHookPoint *HP_pc_setoption_pre;
struct HPMHookPoint *HP_pc_setoption_post;
struct HPMHookPoint *HP_pc_setcart_pre;
@@ -5502,6 +5518,8 @@ struct {
struct HPMHookPoint *HP_script_print_line_post;
struct HPMHookPoint *HP_script_errorwarning_sub_pre;
struct HPMHookPoint *HP_script_errorwarning_sub_post;
+ struct HPMHookPoint *HP_script_is_permanent_variable_pre;
+ struct HPMHookPoint *HP_script_is_permanent_variable_post;
struct HPMHookPoint *HP_script_set_reg_pre;
struct HPMHookPoint *HP_script_set_reg_post;
struct HPMHookPoint *HP_script_set_reg_ref_str_pre;
@@ -6192,6 +6210,8 @@ struct {
struct HPMHookPoint *HP_skill_check_npc_chaospanic_post;
struct HPMHookPoint *HP_skill_count_wos_pre;
struct HPMHookPoint *HP_skill_count_wos_post;
+ struct HPMHookPoint *HP_skill_get_linked_song_dance_id_pre;
+ struct HPMHookPoint *HP_skill_get_linked_song_dance_id_post;
struct HPMHookPoint *HP_sockt_init_pre;
struct HPMHookPoint *HP_sockt_init_post;
struct HPMHookPoint *HP_sockt_final_pre;
@@ -7881,6 +7901,10 @@ struct {
int HP_clif_chatname_ack_post;
int HP_clif_elemname_ack_pre;
int HP_clif_elemname_ack_post;
+ int HP_clif_skillname_ack_pre;
+ int HP_clif_skillname_ack_post;
+ int HP_clif_itemname_ack_pre;
+ int HP_clif_itemname_ack_post;
int HP_clif_unknownname_ack_pre;
int HP_clif_unknownname_ack_post;
int HP_clif_monster_hp_bar_pre;
@@ -9233,6 +9257,14 @@ struct {
int HP_clif_plapineDdukDdak_ack_post;
int HP_clif_plapineDdukDdak_close_pre;
int HP_clif_plapineDdukDdak_close_post;
+ int HP_clif_lapineUpgrade_open_pre;
+ int HP_clif_lapineUpgrade_open_post;
+ int HP_clif_lapineUpgrade_result_pre;
+ int HP_clif_lapineUpgrade_result_post;
+ int HP_clif_pLapineUpgrade_close_pre;
+ int HP_clif_pLapineUpgrade_close_post;
+ int HP_clif_pLapineUpgrade_makeItem_pre;
+ int HP_clif_pLapineUpgrade_makeItem_post;
int HP_clif_pReqGearOff_pre;
int HP_clif_pReqGearOff_post;
int HP_cmdline_init_pre;
@@ -11671,6 +11703,10 @@ struct {
int HP_pc_percentheal_post;
int HP_pc_jobchange_pre;
int HP_pc_jobchange_post;
+ int HP_pc_hide_pre;
+ int HP_pc_hide_post;
+ int HP_pc_unhide_pre;
+ int HP_pc_unhide_post;
int HP_pc_setoption_pre;
int HP_pc_setoption_post;
int HP_pc_setcart_pre;
@@ -12383,6 +12419,8 @@ struct {
int HP_script_print_line_post;
int HP_script_errorwarning_sub_pre;
int HP_script_errorwarning_sub_post;
+ int HP_script_is_permanent_variable_pre;
+ int HP_script_is_permanent_variable_post;
int HP_script_set_reg_pre;
int HP_script_set_reg_post;
int HP_script_set_reg_ref_str_pre;
@@ -13073,6 +13111,8 @@ struct {
int HP_skill_check_npc_chaospanic_post;
int HP_skill_count_wos_pre;
int HP_skill_count_wos_post;
+ int HP_skill_get_linked_song_dance_id_pre;
+ int HP_skill_get_linked_song_dance_id_post;
int HP_sockt_init_pre;
int HP_sockt_init_post;
int HP_sockt_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index ac30b97d4..6b89841ad 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -524,6 +524,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->mobname_normal_ack, HP_clif_mobname_normal_ack) },
{ HP_POP(clif->chatname_ack, HP_clif_chatname_ack) },
{ HP_POP(clif->elemname_ack, HP_clif_elemname_ack) },
+ { HP_POP(clif->skillname_ack, HP_clif_skillname_ack) },
+ { HP_POP(clif->itemname_ack, HP_clif_itemname_ack) },
{ HP_POP(clif->unknownname_ack, HP_clif_unknownname_ack) },
{ HP_POP(clif->monster_hp_bar, HP_clif_monster_hp_bar) },
{ HP_POP(clif->hpmeter, HP_clif_hpmeter) },
@@ -1200,6 +1202,10 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->lapineDdukDdak_result, HP_clif_lapineDdukDdak_result) },
{ HP_POP(clif->plapineDdukDdak_ack, HP_clif_plapineDdukDdak_ack) },
{ HP_POP(clif->plapineDdukDdak_close, HP_clif_plapineDdukDdak_close) },
+ { HP_POP(clif->lapineUpgrade_open, HP_clif_lapineUpgrade_open) },
+ { HP_POP(clif->lapineUpgrade_result, HP_clif_lapineUpgrade_result) },
+ { HP_POP(clif->pLapineUpgrade_close, HP_clif_pLapineUpgrade_close) },
+ { HP_POP(clif->pLapineUpgrade_makeItem, HP_clif_pLapineUpgrade_makeItem) },
{ HP_POP(clif->pReqGearOff, HP_clif_pReqGearOff) },
/* cmdline_interface */
{ HP_POP(cmdline->init, HP_cmdline_init) },
@@ -2453,6 +2459,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pc->itemheal, HP_pc_itemheal) },
{ HP_POP(pc->percentheal, HP_pc_percentheal) },
{ HP_POP(pc->jobchange, HP_pc_jobchange) },
+ { HP_POP(pc->hide, HP_pc_hide) },
+ { HP_POP(pc->unhide, HP_pc_unhide) },
{ HP_POP(pc->setoption, HP_pc_setoption) },
{ HP_POP(pc->setcart, HP_pc_setcart) },
{ HP_POP(pc->setfalcon, HP_pc_setfalcon) },
@@ -2817,6 +2825,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->load_parameters, HP_script_load_parameters) },
{ HP_POP(script->print_line, HP_script_print_line) },
{ HP_POP(script->errorwarning_sub, HP_script_errorwarning_sub) },
+ { HP_POP(script->is_permanent_variable, HP_script_is_permanent_variable) },
{ HP_POP(script->set_reg, HP_script_set_reg) },
{ HP_POP(script->set_reg_ref_str, HP_script_set_reg_ref_str) },
{ HP_POP(script->set_reg_pc_ref_str, HP_script_set_reg_pc_ref_str) },
@@ -3165,6 +3174,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(skill->splash_target, HP_skill_splash_target) },
{ HP_POP(skill->check_npc_chaospanic, HP_skill_check_npc_chaospanic) },
{ HP_POP(skill->count_wos, HP_skill_count_wos) },
+ { HP_POP(skill->get_linked_song_dance_id, HP_skill_get_linked_song_dance_id) },
/* socket_interface */
{ HP_POP(sockt->init, HP_sockt_init) },
{ HP_POP(sockt->final, HP_sockt_final) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 940f96ca2..02d55228e 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -13035,6 +13035,58 @@ void HP_clif_elemname_ack(int fd, struct block_list *bl) {
}
return;
}
+void HP_clif_skillname_ack(int fd, struct block_list *bl) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_skillname_ack_pre > 0) {
+ void (*preHookFunc) (int *fd, struct block_list **bl);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_skillname_ack_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_skillname_ack_pre[hIndex].func;
+ preHookFunc(&fd, &bl);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.skillname_ack(fd, bl);
+ }
+ if (HPMHooks.count.HP_clif_skillname_ack_post > 0) {
+ void (*postHookFunc) (int fd, struct block_list *bl);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_skillname_ack_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_skillname_ack_post[hIndex].func;
+ postHookFunc(fd, bl);
+ }
+ }
+ return;
+}
+void HP_clif_itemname_ack(int fd, struct block_list *bl) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_itemname_ack_pre > 0) {
+ void (*preHookFunc) (int *fd, struct block_list **bl);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_itemname_ack_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_itemname_ack_pre[hIndex].func;
+ preHookFunc(&fd, &bl);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.itemname_ack(fd, bl);
+ }
+ if (HPMHooks.count.HP_clif_itemname_ack_post > 0) {
+ void (*postHookFunc) (int fd, struct block_list *bl);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_itemname_ack_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_itemname_ack_post[hIndex].func;
+ postHookFunc(fd, bl);
+ }
+ }
+ return;
+}
void HP_clif_unknownname_ack(int fd, struct block_list *bl) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_unknownname_ack_pre > 0) {
@@ -30663,6 +30715,112 @@ void HP_clif_plapineDdukDdak_close(int fd, struct map_session_data *sd) {
}
return;
}
+bool HP_clif_lapineUpgrade_open(struct map_session_data *sd, int item_id) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_clif_lapineUpgrade_open_pre > 0) {
+ bool (*preHookFunc) (struct map_session_data **sd, int *item_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_open_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_open_pre[hIndex].func;
+ retVal___ = preHookFunc(&sd, &item_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.clif.lapineUpgrade_open(sd, item_id);
+ }
+ if (HPMHooks.count.HP_clif_lapineUpgrade_open_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int item_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_open_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_open_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, item_id);
+ }
+ }
+ return retVal___;
+}
+bool HP_clif_lapineUpgrade_result(struct map_session_data *sd, enum lapineUpgrade_result result) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_clif_lapineUpgrade_result_pre > 0) {
+ bool (*preHookFunc) (struct map_session_data **sd, enum lapineUpgrade_result *result);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_result_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_result_pre[hIndex].func;
+ retVal___ = preHookFunc(&sd, &result);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.clif.lapineUpgrade_result(sd, result);
+ }
+ if (HPMHooks.count.HP_clif_lapineUpgrade_result_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, enum lapineUpgrade_result result);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_lapineUpgrade_result_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_lapineUpgrade_result_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, result);
+ }
+ }
+ return retVal___;
+}
+void HP_clif_pLapineUpgrade_close(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_pLapineUpgrade_close_pre > 0) {
+ void (*preHookFunc) (int *fd, struct map_session_data **sd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_close_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_close_pre[hIndex].func;
+ preHookFunc(&fd, &sd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pLapineUpgrade_close(fd, sd);
+ }
+ if (HPMHooks.count.HP_clif_pLapineUpgrade_close_post > 0) {
+ void (*postHookFunc) (int fd, struct map_session_data *sd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_close_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_close_post[hIndex].func;
+ postHookFunc(fd, sd);
+ }
+ }
+ return;
+}
+void HP_clif_pLapineUpgrade_makeItem(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_pre > 0) {
+ void (*preHookFunc) (int *fd, struct map_session_data **sd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_makeItem_pre[hIndex].func;
+ preHookFunc(&fd, &sd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pLapineUpgrade_makeItem(fd, sd);
+ }
+ if (HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_post > 0) {
+ void (*postHookFunc) (int fd, struct map_session_data *sd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pLapineUpgrade_makeItem_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pLapineUpgrade_makeItem_post[hIndex].func;
+ postHookFunc(fd, sd);
+ }
+ }
+ return;
+}
void HP_clif_pReqGearOff(int fd, struct map_session_data *sd) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_pReqGearOff_pre > 0) {
@@ -53703,11 +53861,11 @@ int HP_mob_getfriendstatus_sub(struct block_list *bl, va_list ap) {
}
return retVal___;
}
-struct mob_data* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond2) {
+struct block_list* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond2) {
int hIndex = 0;
- struct mob_data* retVal___ = NULL;
+ struct block_list* retVal___ = NULL;
if (HPMHooks.count.HP_mob_getfriendstatus_pre > 0) {
- struct mob_data* (*preHookFunc) (struct mob_data **md, int *cond1, int *cond2);
+ struct block_list* (*preHookFunc) (struct mob_data **md, int *cond1, int *cond2);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_getfriendstatus_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_mob_getfriendstatus_pre[hIndex].func;
@@ -53722,7 +53880,7 @@ struct mob_data* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond
retVal___ = HPMHooks.source.mob.getfriendstatus(md, cond1, cond2);
}
if (HPMHooks.count.HP_mob_getfriendstatus_post > 0) {
- struct mob_data* (*postHookFunc) (struct mob_data* retVal___, struct mob_data *md, int cond1, int cond2);
+ struct block_list* (*postHookFunc) (struct block_list* retVal___, struct mob_data *md, int cond1, int cond2);
for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_getfriendstatus_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_mob_getfriendstatus_post[hIndex].func;
retVal___ = postHookFunc(retVal___, md, cond1, cond2);
@@ -63705,6 +63863,58 @@ int HP_pc_jobchange(struct map_session_data *sd, int class, int upper) {
}
return retVal___;
}
+void HP_pc_hide(struct map_session_data *sd, bool show_msg) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_pc_hide_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd, bool *show_msg);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_hide_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_pc_hide_pre[hIndex].func;
+ preHookFunc(&sd, &show_msg);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.pc.hide(sd, show_msg);
+ }
+ if (HPMHooks.count.HP_pc_hide_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd, bool show_msg);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_hide_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_pc_hide_post[hIndex].func;
+ postHookFunc(sd, show_msg);
+ }
+ }
+ return;
+}
+void HP_pc_unhide(struct map_session_data *sd, bool show_msg) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_pc_unhide_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd, bool *show_msg);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_unhide_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_pc_unhide_pre[hIndex].func;
+ preHookFunc(&sd, &show_msg);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.pc.unhide(sd, show_msg);
+ }
+ if (HPMHooks.count.HP_pc_unhide_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd, bool show_msg);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_unhide_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_pc_unhide_post[hIndex].func;
+ postHookFunc(sd, show_msg);
+ }
+ }
+ return;
+}
int HP_pc_setoption(struct map_session_data *sd, int type) {
int hIndex = 0;
int retVal___ = 0;
@@ -65443,10 +65653,10 @@ int HP_pc_load_combo(struct map_session_data *sd) {
}
return retVal___;
}
-void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, int type) {
+void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, enum spirit_charm_types type) {
int hIndex = 0;
if (HPMHooks.count.HP_pc_add_charm_pre > 0) {
- void (*preHookFunc) (struct map_session_data **sd, int *interval, int *max, int *type);
+ void (*preHookFunc) (struct map_session_data **sd, int *interval, int *max, enum spirit_charm_types *type);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_add_charm_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_pc_add_charm_pre[hIndex].func;
@@ -65461,7 +65671,7 @@ void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, int typ
HPMHooks.source.pc.add_charm(sd, interval, max, type);
}
if (HPMHooks.count.HP_pc_add_charm_post > 0) {
- void (*postHookFunc) (struct map_session_data *sd, int interval, int max, int type);
+ void (*postHookFunc) (struct map_session_data *sd, int interval, int max, enum spirit_charm_types type);
for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_add_charm_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_pc_add_charm_post[hIndex].func;
postHookFunc(sd, interval, max, type);
@@ -65469,10 +65679,10 @@ void HP_pc_add_charm(struct map_session_data *sd, int interval, int max, int typ
}
return;
}
-void HP_pc_del_charm(struct map_session_data *sd, int count, int type) {
+void HP_pc_del_charm(struct map_session_data *sd, int count, enum spirit_charm_types type) {
int hIndex = 0;
if (HPMHooks.count.HP_pc_del_charm_pre > 0) {
- void (*preHookFunc) (struct map_session_data **sd, int *count, int *type);
+ void (*preHookFunc) (struct map_session_data **sd, int *count, enum spirit_charm_types *type);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_del_charm_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_pc_del_charm_pre[hIndex].func;
@@ -65487,7 +65697,7 @@ void HP_pc_del_charm(struct map_session_data *sd, int count, int type) {
HPMHooks.source.pc.del_charm(sd, count, type);
}
if (HPMHooks.count.HP_pc_del_charm_post > 0) {
- void (*postHookFunc) (struct map_session_data *sd, int count, int type);
+ void (*postHookFunc) (struct map_session_data *sd, int count, enum spirit_charm_types type);
for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_del_charm_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_pc_del_charm_post[hIndex].func;
postHookFunc(sd, count, type);
@@ -73263,6 +73473,33 @@ void HP_script_errorwarning_sub(StringBuf *buf, const char *src, const char *fil
}
return;
}
+bool HP_script_is_permanent_variable(const char *name) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_script_is_permanent_variable_pre > 0) {
+ bool (*preHookFunc) (const char **name);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_script_is_permanent_variable_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_script_is_permanent_variable_pre[hIndex].func;
+ retVal___ = preHookFunc(&name);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.script.is_permanent_variable(name);
+ }
+ if (HPMHooks.count.HP_script_is_permanent_variable_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *name);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_script_is_permanent_variable_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_script_is_permanent_variable_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, name);
+ }
+ }
+ return retVal___;
+}
int HP_script_set_reg(struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref) {
int hIndex = 0;
int retVal___ = 0;
@@ -82804,6 +83041,33 @@ int HP_skill_count_wos(struct block_list *bl, va_list ap) {
}
return retVal___;
}
+int HP_skill_get_linked_song_dance_id(int skill_id) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_skill_get_linked_song_dance_id_pre > 0) {
+ int (*preHookFunc) (int *skill_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_linked_song_dance_id_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_skill_get_linked_song_dance_id_pre[hIndex].func;
+ retVal___ = preHookFunc(&skill_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.skill.get_linked_song_dance_id(skill_id);
+ }
+ if (HPMHooks.count.HP_skill_get_linked_song_dance_id_post > 0) {
+ int (*postHookFunc) (int retVal___, int skill_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_linked_song_dance_id_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_skill_get_linked_song_dance_id_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, skill_id);
+ }
+ }
+ return retVal___;
+}
/* socket_interface */
void HP_sockt_init(void) {
int hIndex = 0;