summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.md83
-rw-r--r--doc/mob_skill_db.md223
-rw-r--r--sql-files/item_db_re.sql50
-rw-r--r--sql-files/mob_db_re.sql31
-rw-r--r--sql-files/mob_skill_db_re.sql8
-rw-r--r--src/char/char.c56
-rw-r--r--src/common/cbasetypes.h2
-rw-r--r--src/login/login.c8
-rw-r--r--src/map/atcommand.c41
-rw-r--r--src/map/battle.c15
-rw-r--r--src/map/clif.c77
-rw-r--r--src/map/clif.h11
-rw-r--r--src/map/map.c8
-rw-r--r--src/map/mob.c683
-rw-r--r--src/map/mob.h9
-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.c13
-rw-r--r--src/map/skill.c116
-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.inc30
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc36
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc9
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc257
43 files changed, 4176 insertions, 787 deletions
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 cf2bd7da2..eec334d18 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"
@@ -148798,6 +149035,36 @@ item_db: (
Script: <" Zeny += rand(500, 550); ">
},
{
+ Id: 23187
+ AegisName: "Sap_Jelly"
+ Name: "Sap Jelly"
+ Type: "IT_USABLE"
+ Nouse: {
+ sitting: true
+ }
+ Script: <" pet(NINE_TAIL); ">
+},
+{
+ Id: 23188
+ AegisName: "Unprocessed_Parts"
+ Name: "Unprocessed Parts"
+ Type: "IT_USABLE"
+ Nouse: {
+ sitting: true
+ }
+ Script: <" pet(GREMLIN); ">
+},
+{
+ Id: 23189
+ AegisName: "SmallDoll_Needle"
+ Name: "Small Doll Needle"
+ Type: "IT_USABLE"
+ Nouse: {
+ sitting: true
+ }
+ Script: <" pet(TEDDY_BEAR); ">
+},
+{
Id: 23242
AegisName: "Fried_Chicken"
Name: "Fried_Chicken"
@@ -153745,6 +154012,24 @@ item_db: (
Weight: 1200
},
{
+ Id: 25231
+ AegisName: "Suspicious_Bottle"
+ Name: "Suspicious Bottle"
+ Weight: 10
+},
+{
+ Id: 25232
+ AegisName: "Cheap_Lubricant"
+ Name: "Cheap Lubricant"
+ Weight: 10
+},
+{
+ Id: 25233
+ AegisName: "Cotton_Tufts"
+ Name: "Cotton Tufts"
+ Weight: 10
+},
+{
Id: 25258
AegisName: "BrokenArrow"
Name: "BrokenArrow"
@@ -153790,6 +154075,12 @@ item_db: (
Name: "Mightysoul_Essence"
},
{
+ Id: 25377
+ AegisName: "Luxurious_Pet_Food"
+ Name: "Luxurious Pet Food"
+ Weight: 1
+},
+{
Id: 25390
AegisName: "Captured_Savage"
Name: "Captured_Savage"
@@ -154585,6 +154876,29 @@ item_db: (
bonus2(bSkillAtk, RL_HAMMER_OF_GOD, getrefine() >= 10 ? 60 : 30);
">
},
+{
+ Id: 27352
+ AegisName: "Rigid_Nightmare_Terror_Card"
+ Name: "Rigid Nightmare Terror Card"
+ Type: "IT_CARD"
+ Buy: 20
+ Weight: 10
+ Loc: "EQP_SHOES"
+ Script: <" bonus(bMaxSPrate, 5); ">
+},
+{
+ Id: 27361
+ AegisName: "Contaminated_Wanderer_Card"
+ Name: "Contaminated Wanderer Card"
+ Type: "IT_CARD"
+ Buy: 20
+ Weight: 10
+ Loc: "EQP_WEAPON"
+ Script: <"
+ bonus2(bAddSize,Size_Medium, 30);
+ bonus2(bAddSize,Size_Large, 30);
+ ">
+},
//== New Katars ============================================
{
@@ -156454,6 +156768,19 @@ item_db: (
Name: "Shinee_Opal"
},
{
+ Id: 31022
+ AegisName: "Abandoned_Teddy_Bear_Card"
+ Name: "Abandoned Teddy Bear Card"
+ Type: "IT_CARD"
+ Buy: 20
+ Weight: 10
+ Loc: "EQP_SHOES"
+ Script: <"
+ bonus(bMaxSPrate, 20);
+ bonus2(bAddEff2, Eff_Curse, 20);
+ ">
+},
+{
Id: 31172
AegisName: "Roast_Memory"
Name: "Roast_Memory"
@@ -157919,6 +158246,12 @@ item_db: (
Name: "ArchbishopStone_Robe2"
},
{
+ Id: 1000103
+ AegisName: "Barmil_Ticket"
+ Name: "Barmil Ticket"
+ Weight: 10
+},
+{
Id: 1000213
AegisName: "WarlockStone_Robe2"
Name: "WarlockStone_Robe2"
@@ -157978,4 +158311,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 25880c29e..509764424 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -5111,6 +5111,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
@@ -8193,17 +8199,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
@@ -12732,6 +12769,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
@@ -12743,6 +12782,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
@@ -13756,9 +13799,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
@@ -13785,6 +13841,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
@@ -13829,7 +13895,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
@@ -13953,6 +14022,7 @@
- `Trance_Candy_Y`: 11594
- `Trance_Candy_G`: 11595
- `Catnip_Fruit`: 11602
+- `Cookie_Bat`: 11605
- `Crepe`: 11607
- `Chocolate_Egg`: 11608
- `Yummy_Cookie_Egg`: 11609
@@ -13960,6 +14030,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
@@ -18176,6 +18247,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
@@ -18829,6 +18903,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
@@ -18838,6 +18915,7 @@
- `Happiness_Clover`: 25295
- `Golden_Corn`: 25340
- `Mightysoul_Essence`: 25375
+- `Luxurious_Pet_Food`: 25377
- `Captured_Savage`: 25390
- `Goodly_Bough`: 25391
- `Free_Pass_Ticket`: 25392
@@ -18989,6 +19067,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
@@ -19136,6 +19216,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
@@ -19319,6 +19400,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
@@ -19441,6 +19523,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/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/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/src/char/char.c b/src/char/char.c
index aac9ad20c..0406dbecf 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) {
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/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..3fe6c8581 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;
}
@@ -10594,9 +10565,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..7be5c6978 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;
@@ -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/map.c b/src/map/map.c
index 760960c78..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;
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/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..45c954dc0 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -16111,7 +16111,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 +16133,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 +27847,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);
diff --git a/src/map/skill.c b/src/map/skill.c
index 19c575d89..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;
}
@@ -5008,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: {
@@ -7386,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);
}
@@ -10473,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
}
@@ -10930,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;
+}
+
/*==========================================
*
*------------------------------------------*/
@@ -11299,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:
@@ -21804,4 +21849,5 @@ void skill_defaults(void)
skill->splash_target = skill_splash_target;
skill->check_npc_chaospanic = skill_check_npc_chaospanic;
skill->count_wos = skill_count_wos;
+ skill->get_linked_song_dance_id = skill_get_linked_song_dance_id;
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 65195dc75..4dbbaf147 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -2200,6 +2200,7 @@ struct skill_interface {
int (*splash_target) (struct block_list* bl);
int (*check_npc_chaospanic) (struct block_list *bl, va_list args);
int (*count_wos) (struct block_list *bl, va_list ap);
+ int (*get_linked_song_dance_id) (int skill_id);
};
#ifdef HERCULES_CORE
diff --git a/src/map/status.c b/src/map/status.c
index d3e85e5be..9a274c080 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
@@ -7808,6 +7809,9 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl
calc_flag = status->dbs->ChangeFlagTable[type];
if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs
switch(type) {
+ case SC_AUTOTRADE:
+ case SC_KSPROTECTED:
+ break; // Prevent calling status_change_start_unknown_sc().
case SC_ADORAMUS:
sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1));
// Fall through to SC_INC_AGI
@@ -8052,7 +8056,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..80ba50d73 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);
@@ -7668,6 +7684,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..70bc309f3 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;
@@ -6192,6 +6208,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 +7899,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 +9255,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 +11701,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;
@@ -13073,6 +13107,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..c9b673a1f 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) },
@@ -3165,6 +3173,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..599cbfdfd 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);
@@ -82804,6 +83014,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;