summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/map/battle/feature.conf5
-rw-r--r--db/pre-re/pet_db.conf7
-rw-r--r--db/re/item_db.conf203
-rw-r--r--db/re/pet_db.conf377
-rw-r--r--doc/constants.md29
-rw-r--r--doc/sample/npc_rodex.txt4
-rw-r--r--doc/script_commands.txt70
-rw-r--r--npc/dev/test.txt14
-rw-r--r--npc/instances/EndlessTower.txt26
-rw-r--r--npc/instances/NydhoggsNest.txt25
-rw-r--r--npc/instances/OrcsMemory.txt27
-rw-r--r--npc/instances/SealedShrine.txt40
-rw-r--r--npc/re/instances/BakonawaLake.txt20
-rw-r--r--npc/re/instances/BangungotHospital.txt26
-rw-r--r--npc/re/instances/BuwayaCave.txt27
-rw-r--r--npc/re/instances/EclageInterior.txt24
-rw-r--r--npc/re/instances/HazyForest.txt51
-rw-r--r--npc/re/instances/MalangdoCulvert.txt25
-rw-r--r--npc/re/instances/OldGlastHeim.txt24
-rw-r--r--npc/re/instances/WolfchevLaboratory.txt41
-rw-r--r--npc/re/instances/ghost_palace.txt29
-rw-r--r--npc/re/instances/octopus_cave.txt27
-rw-r--r--npc/re/instances/saras_memory.txt22
-rw-r--r--sql-files/item_db_re.sql29
-rw-r--r--sql-files/main.sql2
-rw-r--r--sql-files/upgrades/2018-06-05--12-02.sql24
-rw-r--r--sql-files/upgrades/index.txt1
-rw-r--r--src/char/int_pet.c15
-rw-r--r--src/common/HPM.h6
-rw-r--r--src/common/HPMDataCheck.h3
-rw-r--r--src/common/console.c5
-rw-r--r--src/common/core.c11
-rw-r--r--src/common/mmo.h1
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/clif.c144
-rw-r--r--src/map/clif.h15
-rw-r--r--src/map/packets.h2
-rw-r--r--src/map/packets_struct.h12
-rw-r--r--src/map/pet.c163
-rw-r--r--src/map/pet.h15
-rw-r--r--src/map/script.c101
-rw-r--r--src/map/skill.c8
-rw-r--r--src/map/skill.h2
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc14
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc12
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc3
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc101
-rw-r--r--tools/petevolutionconverter.py248
-rw-r--r--tools/utils/common.py15
50 files changed, 1749 insertions, 348 deletions
diff --git a/conf/map/battle/feature.conf b/conf/map/battle/feature.conf
index 8d19539b4..285633209 100644
--- a/conf/map/battle/feature.conf
+++ b/conf/map/battle/feature.conf
@@ -71,6 +71,11 @@ features: {
// false: disable
enable_homun_autofeed: true
+ // Allow Pet autofeeding
+ // true: enable (Default)
+ // false: disable
+ enable_pet_autofeed: true
+
// Enable Attendance System for clients >= 2018-03-07bRagexeRE or 2018-04-04bRagexe or 2018-04-11aRagexe_zero
// true: enable (Default)
// false: disable
diff --git a/db/pre-re/pet_db.conf b/db/pre-re/pet_db.conf
index 3ce78e546..91f9cb8e8 100644
--- a/db/pre-re/pet_db.conf
+++ b/db/pre-re/pet_db.conf
@@ -56,6 +56,13 @@ pet_db:(
AttackRate: attack rate (int, defaults to 0)
DefendRate: Defence attack (int, defaults to 0)
ChangeTargetRate: change target (int, defaults to 0)
+ Evolve: {
+ EggID: { (string, Evolved Pet EggID)
+ Name: Amount (items required to perform evolution)
+ ...
+ }
+ }
+ AutoFeed: true/false (boolean, defaults to false)
PetScript: <" Pet Script (can also be multi-line) ">
EquipScript: <" Equip Script (can also be multi-line) ">
},
diff --git a/db/re/item_db.conf b/db/re/item_db.conf
index bc3470fd9..3974a911e 100644
--- a/db/re/item_db.conf
+++ b/db/re/item_db.conf
@@ -83540,6 +83540,209 @@ item_db: (
Type: "IT_PETEGG"
Buy: 20
},
+{
+ Id: 9069
+ AegisName: "Mastering_Egg"
+ Name: "Mastering Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9070
+ AegisName: "Savage_Egg"
+ Name: "Savage Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9071
+ AegisName: "Grand_Peco_Peco_Egg"
+ Name: "Grand Peco Peco Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9087
+ AegisName: "High_Orc_Egg"
+ Name: "High Orc Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9088
+ AegisName: "Angeling_Egg"
+ Name: "Angeling Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9089
+ AegisName: "Am_Mut_Egg"
+ Name: "Am Mut Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9090
+ AegisName: "Little_Isis_Egg"
+ Name: "Little Isis Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9091
+ AegisName: "Choco_Egg"
+ Name: "Choco Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9092
+ AegisName: "Eggring_Egg"
+ Name: "Eggring Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9093
+ AegisName: "Hyegun_Egg"
+ Name: "Hyegun Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9094
+ AegisName: "Leaf_Lunatic_Egg"
+ Name: "Leaf Lunatic Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9095
+ AegisName: "Nine_Tails_Egg"
+ Name: "Nine Tails Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9096
+ AegisName: "Cat_o_Nine_Tails_Egg"
+ Name: "Cat o' Nine Tails Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9097
+ AegisName: "Diabolic_Egg_"
+ Name: "Diabolic Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9098
+ AegisName: "Earth_Deleter_Egg"
+ Name: "Earth Deleter Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9099
+ AegisName: "Teddy_Bear_Egg"
+ Name: "Teddy Bear Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9100
+ AegisName: "Gremlin_Egg"
+ Name: "Gremlin Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9101
+ AegisName: "Scatelon_Egg"
+ Name: "Scatleton Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9102
+ AegisName: "Mummy_Egg"
+ Name: "Mummy Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9103
+ AegisName: "Willow_Egg"
+ Name: "Willow Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9104
+ AegisName: "Roween_Egg"
+ Name: "Roween Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9105
+ AegisName: "Hodremlin_Egg"
+ Name: "Hodremlin Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9106
+ AegisName: "Metaller_Egg"
+ Name: "Metaller Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9107
+ AegisName: "Ancient_Mummy_Egg"
+ Name: "Ancient Mummy Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9108
+ AegisName: "Abandoned_Teddy_Bear_Egg"
+ Name: "Abandoned Teddy Bear Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9109
+ AegisName: "Sweet_Drops_Egg"
+ Name: "Sweet Drops Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9111
+ AegisName: "Phreeoni_Egg"
+ Name: "Phreeoni Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9112
+ AegisName: "Moonlight_Flower_Egg"
+ Name: "Moonlight Flower Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
+{
+ Id: 9113
+ AegisName: "Skelion_Egg"
+ Name: "Skelion Egg"
+ Type: "IT_PETEGG"
+ Buy: 20
+},
//== Pet Accessories =======================================
{
diff --git a/db/re/pet_db.conf b/db/re/pet_db.conf
index 6d6083e59..a28da61ff 100644
--- a/db/re/pet_db.conf
+++ b/db/re/pet_db.conf
@@ -56,6 +56,13 @@ pet_db:(
AttackRate: attack rate (int, defaults to 0)
DefendRate: Defence attack (int, defaults to 0)
ChangeTargetRate: change target (int, defaults to 0)
+ Evolve: {
+ EggID: { (string, Evolved Pet EggID)
+ Name: Amount (items required to perform evolution)
+ ...
+ }
+ }
+ AutoFeed: true/false (boolean, defaults to false)
PetScript: <" Pet Script (can also be multi-line) ">
EquipScript: <" Equip Script (can also be multi-line) ">
},
@@ -87,6 +94,12 @@ pet_db:(
bonus(bLuk, 2);
bonus(bCritical, 1);
">
+ Evolve: {
+ Mastering_Egg: {
+ Leaf_Of_Yggdrasil: 10
+ Unripe_Apple: 3
+ }
+ }
},
{
Id: 1011
@@ -170,6 +183,15 @@ pet_db:(
bonus(bMaxHP, 150);
bonus(bMaxSP, -10);
">
+ Evolve: {
+ Grand_Peco_Peco_Egg: {
+ Pet_Food: 10
+ Fatty_Chubby_Earthworm: 3
+ Peco_Wing_Feather: 300
+ Pecopeco_Card: 1
+ Fruit_Of_Mastela: 10
+ }
+ }
},
{
Id: 1023
@@ -198,6 +220,15 @@ pet_db:(
bonus(bAtk, 10);
bonus(bDef, -3);
">
+ Evolve: {
+ High_Orc_Egg: {
+ Horror_Of_Tribe: 3
+ Orcish_Sword: 1
+ Orcish_Voucher: 500
+ Cigar: 1
+ Orc_Warrior_Card: 1
+ }
+ }
},
{
Id: 1026
@@ -252,6 +283,14 @@ pet_db:(
bonus(bMatkRate, -1);
bonus(bAtkRate, 1);
">
+ Evolve: {
+ Little_Isis_Egg: {
+ Armlet_Of_Obedience: 3
+ Queens_Hair_Ornament: 1
+ Shining_Scales: 300
+ Crystal_Jewel__: 6
+ }
+ }
},
{
Id: 1031
@@ -391,6 +430,14 @@ pet_db:(
bonus(bHPrecovRate, 5);
bonus(bMaxHP, 25);
">
+ Evolve: {
+ Metaller_Egg: {
+ Singing_Plant: 3
+ Grasshoppers_Leg: 777
+ Yellow_Herb: 200
+ Metaller_Card: 1
+ }
+ }
},
{
Id: 1056
@@ -447,6 +494,14 @@ pet_db:(
bonus(bCritical, 3);
bonus(bLuk, -1);
">
+ Evolve: {
+ Choco_Egg: {
+ Tropical_Banana: 3
+ Monkey_Doll: 2
+ Cacao: 300
+ Yoyo_Card: 1
+ }
+ }
},
{
Id: 1063
@@ -474,6 +529,14 @@ pet_db:(
bonus(bCritical, 2);
bonus(bAtk, 2);
">
+ Evolve: {
+ Leaf_Lunatic_Egg: {
+ Great_Leaf: 100
+ Clover: 250
+ Four_Leaf_Clover: 30
+ Leaf_Lunatic_Card: 1
+ }
+ }
},
{
Id: 1077
@@ -585,6 +648,14 @@ pet_db:(
bonus(bMaxHPrate, -3);
bonus(bMaxSPrate, -3);
">
+ Evolve: {
+ Diabolic_Egg_: {
+ Contracts_In_Shadow: 3
+ Petite_DiablOfs_Wing: 250
+ Sacred_Marks: 30
+ Deviruchi_Card: 1
+ }
+ }
},
{
Id: 1110
@@ -612,6 +683,14 @@ pet_db:(
bonus(bMatkRate, 1);
bonus(bAtkRate, -1);
">
+ Evolve: {
+ Am_Mut_Egg: {
+ Old_Broom: 3
+ Violet_Dyestuffs: 3
+ Dokkaebi_Horn: 300
+ Gold: 3
+ }
+ }
},
{
Id: 1113
@@ -640,6 +719,22 @@ pet_db:(
bonus(bHit, 3);
bonus(bAtk, 3);
">
+ Evolve: {
+ Eggring_Egg: {
+ Piece_Of_Egg_Shell: 20
+ Old_Frying_Pan: 10
+ Apple_Juice: 3
+ Eggring_Card: 1
+ }
+/*
+ Sweet_Drops_Egg: {
+ 25290: 500
+ Candy: 50
+ Candy_Striper: 50
+ Drops_Card: 1
+ }
+*/
+ }
},
{
Id: 1155
@@ -668,6 +763,14 @@ pet_db:(
bonus(bMdef, -2);
bonus(bAspdRate, 1);
">
+ Evolve: {
+ Earth_Deleter_Egg: {
+ Shining_Stone: 3
+ Petti_Tail: 100
+ Aloebera: 150
+ Deleter_Card: 1
+ }
+ }
},
{
Id: 1167
@@ -695,6 +798,14 @@ pet_db:(
bonus(bVit, 1);
bonus(bMaxHP, 50);
">
+ Evolve: {
+ Savage_Egg: {
+ Pet_Food: 10
+ Sweet_Milk: 3
+ Meat: 100
+ Feather: 50
+ }
+ }
},
{
Id: 1170
@@ -750,6 +861,14 @@ pet_db:(
bonus(bVit, 1);
bonus2(bResEff, Eff_Stun, 100);
">
+ Evolve: {
+ Hyegun_Egg: {
+ Hyegun_Hat: 1
+ Munak_Doll: 100
+ Old_Portrait: 50
+ Hyegun_Card: 1
+ }
+ }
},
{
Id: 1200
@@ -1646,4 +1765,262 @@ pet_db:(
bonus(bCritical, 1);
">
},
+// New Pets [Need Info]
+{
+ Id: 1090
+ SpriteName: "MASTERING"
+ Name: "Mastering"
+ EggItem: "Mastering_Egg"
+ AutoFeed: true
+ Evolve: {
+ Angeling_Egg: {
+ Yellow_Potion: 20
+ Spirit_Chain: 1
+ White_Herb: 50
+ Jellopy: 200
+ }
+ }
+},
+{
+ Id: 1096
+ SpriteName: "ANGELING"
+ Name: "Angeling"
+ EggItem: "Angeling_Egg"
+ AutoFeed: true
+},
+{
+ Id: 1301
+ SpriteName: "AM_MUT"
+ Name: "Am Mut"
+ EggItem: "Am_Mut_Egg"
+ AutoFeed: true
+},
+/*
+{
+ Id: 3636
+ SpriteName: "LITTLE_ISIS"
+ Name: "Little Isis"
+ EggItem: "Little_Isis_Egg"
+ AutoFeed: true
+},
+*/
+{
+ Id: 1214
+ SpriteName: "CHOCO"
+ Name: "Choco"
+ EggItem: "Choco_Egg"
+ AutoFeed: true
+},
+/*
+{
+ Id: 3495
+ SpriteName: "DR_EGGRING"
+ Name: "Eggring"
+ EggItem: "Eggring_Egg"
+ AutoFeed: true
+},
+*/
+{
+ Id: 1512
+ SpriteName: "HYEGUN"
+ Name: "Hyegun"
+ EggItem: "Hyegun_Egg"
+ AutoFeed: true
+},
+/*
+{
+ Id: 3496
+ SpriteName: "DR_LUNATIC"
+ Name: "Leaf Lunatic"
+ EggItem: "Leaf_Lunatic_Egg"
+ AutoFeed: true
+},
+*/
+{
+ Id: 1180
+ SpriteName: "NINE_TAIL"
+ Name: "Nine Tails"
+ EggItem: "Nine_Tails_Egg"
+ AutoFeed: true
+ Evolve: {
+/*
+ Cat_o_Nine_Tails_Egg: {
+ 23187: 3
+ Fox_Tail: 999
+ Punisher: 1
+ Nine_Tail_Card: 1
+ }
+*/
+ }
+},
+{
+ Id: 1307
+ SpriteName: "CAT_O_NINE_TAIL"
+ Name: "Cat o' Nine Tails"
+ EggItem: "Cat_o_Nine_Tails_Egg"
+ AutoFeed: true
+ Evolve: {
+/*
+ Moonlight_Flower_Egg: {
+ 25375: 30
+ Nine_Tail_Card: 10
+ Sohee_Card: 10
+ Munak_Card: 10
+ }
+*/
+ }
+},
+/*
+{
+ Id: 3669
+ SpriteName: "DIABOLIC2"
+ Name: "Diabolic"
+ EggItem: "Diabolic_Egg_"
+ AutoFeed: true
+},
+*/
+/*
+{
+ Id: 3670
+ SpriteName: "DELETER_2"
+ Name: "Earth Deleter"
+ EggItem: "Earth_Deleter_Egg"
+ AutoFeed: true
+},
+*/
+{
+ Id: 1622
+ SpriteName: "TEDDY_BEAR"
+ Name: "Teddy Bear"
+ EggItem: "Teddy_Bear_Egg"
+ AutoFeed: true
+ Evolve: {
+/*
+ Abandoned_Teddy_Bear_Egg: {
+ 23189: 3
+ Cursed_Seal: 300
+ Cardinal_Jewel_: 50
+ Teddy_Bear_Card: 1
+ }
+*/
+ }
+},
+{
+ Id: 1632
+ SpriteName: "GREMLIN"
+ Name: "Gremlin"
+ EggItem: "Gremlin_Egg"
+ AutoFeed: true
+ Evolve: {
+/*
+ Hodremlin_Egg: {
+ 23188: 3
+ Damp_Darkness: 50
+ Will_Of_Darkness: 200
+ Hodremlin_Card: 1
+ }
+*/
+ }
+},
+/*
+{
+ Id: 3731
+ SpriteName: "SCATLETON"
+ Name: "Scatleton Crate"
+ EggItem: "Scatleton_Crate"
+ AutoFeed: true
+},
+*/
+{
+ Id: 1041
+ SpriteName: "MUMMY"
+ Name: "Mummy"
+ EggItem: "Mummy_Egg"
+ AutoFeed: true
+ Evolve: {
+/*
+ Ancient_Mummy_Egg: {
+ 23256: 3
+ Rune_Of_Darkness: 200
+ Gold: 30
+ Ancient_Mummy_Card: 1
+ }
+*/
+ }
+},
+{
+ Id: 1010
+ SpriteName: "WILOW"
+ Name: "Willow"
+ EggItem: "Willow_Egg"
+ AutoFeed: true
+},
+{
+ Id: 1782
+ SpriteName: "ROWEEN"
+ Name: "Roween"
+ EggItem: "Roween_Egg"
+ AutoFeed: true
+},
+{
+ Id: 1773
+ SpriteName: "HODREMLIN"
+ Name: "Hodremlin"
+ EggItem: "Hodremlin_Egg"
+ AutoFeed: true
+},
+{
+ Id: 1058
+ SpriteName: "METALLER"
+ Name: "Metaller"
+ EggItem: "Metaller_Egg"
+ AutoFeed: true
+},
+{
+ Id: 1297
+ SpriteName: "ANCIENT_MUMMY"
+ Name: "Ancient Mummy"
+ EggItem: "Ancient_Mummy_Egg"
+ AutoFeed: true
+},
+/*{
+ Id: 2995
+ SpriteName: "XM_TEDDY_BEAR"
+ Name: "Abandoned Teddy Bear"
+ EggItem: "Abandoned_Teddy_Bear_Egg"
+ AutoFeed: true
+},
+*/
+/* UNKNOWN MONSTER
+{
+ Id: 0
+ SpriteName: "X"
+ Name: "Sweet Drops"
+ EggItem: "Sweet_Drops_Egg"
+ AutoFeed: true
+},
+*/
+{
+ Id: 1159
+ SpriteName: "PHREEONI"
+ Name: "Phreeoni"
+ EggItem: "Phreeoni_Egg"
+ AutoFeed: true
+},
+{
+ Id: 1150
+ SpriteName: "MOONLIGHT"
+ Name: "Moonlight Flower"
+ EggItem: "Moonlight_Flower_Egg"
+ AutoFeed: true
+},
+/*
+{
+ Id: 3971
+ SpriteName: "SKELION"
+ Name: "Skelion"
+ EggItem: "Skelion_Egg"
+ AutoFeed: true
+},
+*/
)
diff --git a/doc/constants.md b/doc/constants.md
index 654e5eb64..565048840 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -13318,6 +13318,35 @@
- `Brownie_Egg`: 9060
- `Marin_Egg`: 9061
- `Novice_Poring_Egg`: 9062
+- `Mastering_Egg`: 9069
+- `Savage_Egg`: 9070
+- `Grand_Peco_Peco_Egg`: 9071
+- `High_Orc_Egg`: 9087
+- `Angeling_Egg`: 9088
+- `Am_Mut_Egg`: 9089
+- `Little_Isis_Egg`: 9090
+- `Choco_Egg`: 9091
+- `Eggring_Egg`: 9092
+- `Hyegun_Egg`: 9093
+- `Leaf_Lunatic_Egg`: 9094
+- `Nine_Tails_Egg`: 9095
+- `Cat_o_Nine_Tails_Egg`: 9096
+- `Diabolic_Egg_`: 9097
+- `Earth_Deleter_Egg`: 9098
+- `Teddy_Bear_Egg`: 9099
+- `Gremlin_Egg`: 9100
+- `Scatelon_Egg`: 9101
+- `Mummy_Egg`: 9102
+- `Willow_Egg`: 9103
+- `Roween_Egg`: 9104
+- `Hodremlin_Egg`: 9105
+- `Metaller_Egg`: 9106
+- `Ancient_Mummy_Egg`: 9107
+- `Abandoned_Teddy_Bear_Egg`: 9108
+- `Sweet_Drops_Egg`: 9109
+- `Phreeoni_Egg`: 9111
+- `Moonlight_Flower_Egg`: 9112
+- `Skelion_Egg`: 9113
- `Skull_Helm`: 10001
- `Monster_Oxygen_Mask`: 10002
- `Transparent_Headgear`: 10003
diff --git a/doc/sample/npc_rodex.txt b/doc/sample/npc_rodex.txt
index a808a1aa9..0975e609c 100644
--- a/doc/sample/npc_rodex.txt
+++ b/doc/sample/npc_rodex.txt
@@ -20,12 +20,12 @@ prontera,150,150,4 script Rodex Mail 1_M_01,{
// Sends a messsage to attached player "Account Box" from "Rodex Test", with title "Rodex Test3",
// with message "Hello World, How are You?", 1000 Zenies and 5 Red Potions attached
rodex_sendmail_acc(
- getcharid(CHAR_ID_CHAR), "Rodex Test", "Rodex Test3", "Hello World, How are You?",
+ getcharid(CHAR_ID_ACCOUNT), "Rodex Test", "Rodex Test3", "Hello World, How are You?",
1000,
Red_Potion, 5
);
- // Sends a messsage to attached player "Account Box" from "Rodex Test", with title "Rodex Test6",
+ // Sends a messsage to attached player from "Rodex Test", with title "Rodex Test6",
// with message "Hello World, How are You?", 1000 Zenies, 5 Red Potions and
// 1 +10 Knife[3] with 3 Poring Cards (Broken)
rodex_sendmail2(
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 36c4da35a..a00756056 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -2473,6 +2473,7 @@ arrays:
---------------------------------------
*readparam(<parameter number>{, "<player name>"})
+*readparam(<parameter number>{, <account id>})
This function will return the basic stats of an invoking character,
referred to by the parameter number. Instead of a number, you can use a
@@ -2511,6 +2512,21 @@ Example 3:
---------------------------------------
+*setparam(<parameter number>, <value>{, "<player name>"})
+*setparam(<parameter number>, <value>{, <account id>})
+
+Sets a parameter on the given player. See readparam() for more info about
+parameters. Keep in mind that not all read-able parameters are also set-able.
+
+Parameters that can be modified include:
+
+StatusPoint, BaseLevel, SkillPoint, Zeny, Sex, Weight, MaxWeight, JobLevel,
+BaseExp, JobExp, Hp, MaxHp, Sp, MaxSp, Karma, Manner, Fame, bVit, bDex, bAgi,
+bStr, bInt, bLuk
+
+
+---------------------------------------
+
*getcharid(<type>{, "<character name>"})
This function will return a unique ID number of the invoking character,
@@ -2756,7 +2772,9 @@ save points. Available information types are:
---------------------------------------
-*getcharip({"<character name>"|<account id>|<char id>})
+*getcharip({"<character name>"})
+*getcharip({<account id>})
+*getcharip({<character id>})
This function will return the IP address of the invoking character, or, if
a player is specified, of that character. A blank string is returned if no
@@ -3413,7 +3431,8 @@ behave specially when talked to by GMs.
---------------------------------------
-*setgroupid(<new group id>{, "<character name>"|<account id>})
+*setgroupid(<new group id>{, "<character name>"})
+*setgroupid(<new group id>{, <account id>})
This function will temporary adjust the id of player group the account to which the
player specified if the new group id is available.
@@ -4372,7 +4391,7 @@ offline in the mean time, attachrid() returns false, otherwise true.
---------------------------------------
-*rid2name(<rid>)
+*rid2name(<account id>)
Converts rid to name. Note: The player/monster/NPC must be online/enabled.
Good for PCKillEvent where you can convert 'killedrid' to the name of the
@@ -4616,13 +4635,12 @@ effects.
---------------------------------------
-*recovery()
-*recovery(<account id>)
+*recovery({<account id>})
*recovery("<map name>"{, <x1>, <y1>, <x2>, <y2>})
-In its first form, this command will revive and restore full HP and SP to all
-characters currently connected to the server. In its second form, it will only
-affect the target player. In its third form it will affect a whole map or area.
+This command will revive and restore full HP and SP to all characters currently
+connected to the server. If an account id is supplied, it will instead only
+affect this character. If a map is supplied it will affect a whole map or area.
---------------------------------------
@@ -5138,8 +5156,10 @@ Example:
close();
---------------------------------------
-*getnameditem(<item id>, <character name|character ID>)
-*getnameditem("<item name>", <character name|character ID>)
+*getnameditem(<item id>, "<character name>")
+*getnameditem(<item id>, <character ID>)
+*getnameditem("<item name>", "<character name>")
+*getnameditem("<item name>", <character ID>)
Create an item signed with the given character's name.
@@ -5303,7 +5323,7 @@ Check getitem2() to understand the arguments of the function.
---------------------------------------
-*groupranditem(<item_id/constant>)
+*groupranditem(<item id>)
Returns the item_id of a random item picked from the item container specified. There
are different item containers and they are specified in 'db/(pre-)re/item_group.conf'.
@@ -5313,7 +5333,7 @@ Example:
---------------------------------------
-*getrandgroupitem(<item_id/constant>, <quantity>)
+*getrandgroupitem(<item id>, <quantity>)
Similar to the above example, this command allows players to obtain the specified
quantity of a random item from the container. The different containers
@@ -6195,7 +6215,7 @@ Examples:
@ /!\ This command is deprecated @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-Prevents the player from moving when the option != 0, and 0 enables the
+Prevents the player from moving when the option != 0, and 0 enables the
player to move again. The player has to be the account ID of a character,
and will run for the attached player if zero is supplied.
@@ -6823,12 +6843,12 @@ valid <type> for gettimer() are:
---------------------------------------
-*initnpctimer({ "<NPC name>" {, <Attach Flag>} } |
- { "<NPC name>" | <Attach Flag> })
-*stopnpctimer({ "<NPC name>" {, <Detach Flag>} } |
- { "<NPC name>" | <Detach Flag> })
-*startnpctimer({ "<NPC name>" {, <Attach Flag>} } |
- { "<NPC name>" | <Attach Flag> })
+*initnpctimer({"<NPC name>"{, <Attach Flag>}})
+*initnpctimer({<Attach Flag>})
+*stopnpctimer({"<NPC name>"{, <Detach Flag>}})
+*stopnpctimer({<Detach Flag>}})
+*startnpctimer({"<NPC name>"{, <Attach Flag>}})
+*startnpctimer({<Attach Flag>})
*setnpctimer(<tick>{, "<NPC name>"})
*getnpctimer(<type of information>{, "<NPC name>"})
*attachnpctimer({"<character name>"})
@@ -9369,19 +9389,19 @@ Add quest of the <ID2> to the the quest log, and the state is "active".
---------------------------------------
-*questprogress(<ID>{, PLAYTIME|HUNTING})
+*questprogress(<ID>{, <type>})
If no additional argument supplied, return the state of the quest:
0 = Quest not started (not in quest log)
1 = Quest has been given
2 = Quest completed
-If parameter PLAYTIME is supplied:
+If <type> PLAYTIME is supplied:
0 = Quest not started (not in quest log)
1 = The time limit has not yet been reached
2 = The time limit has been reached
-If parameter HUNTING is supplied:
+If <type> HUNTING is supplied:
0 = Quest not started (not in quest log)
1 = Player hasn't killed all of the target monsters
2 = Player has killed all of the target monsters
@@ -10023,7 +10043,7 @@ returns 1 on success, 0 on failure.
//=====================================
---------------------------------------
-*join_clan(<ClanID>{,<RID>})
+*join_clan(<ClanID>{, <account id>})
Joins a player into the given clan.
If no RID is given, will run with the current attached player.
@@ -10032,7 +10052,7 @@ returns true on success, false on failure.
---------------------------------------
-*clan_leave({<RID>})
+*clan_leave({<account id>})
Removes a player from its clan.
If no RID is given, will run with the current attached player.
@@ -10068,4 +10088,4 @@ the available flags are:
Opens the styling shop on client
---------------------------------------- \ No newline at end of file
+---------------------------------------
diff --git a/npc/dev/test.txt b/npc/dev/test.txt
index a6f89f857..036a94916 100644
--- a/npc/dev/test.txt
+++ b/npc/dev/test.txt
@@ -150,6 +150,20 @@ function script HerculesSelfTestHelper {
callsub(OnCheck, "Prefix decrement --", .@y);
callsub(OnCheck, "Prefix decrement --", .@x);
+ // Increment and decrement operators after a condition
+ .@x = 0;
+ if (1) .@x++;
+ callsub(OnCheck, "Suffix increment ++ after (condition)", .@x);
+ .@x = 2;
+ if (1) .@x--;
+ callsub(OnCheck, "Suffix decrement -- after (condition)", .@x);
+ .@x = 0;
+ if (1) ++.@x;
+ callsub(OnCheck, "Prefix increment ++ after (condition)", .@x);
+ .@x = 2;
+ if (1) --.@x;
+ callsub(OnCheck, "Prefix decrement -- after (condition)", .@x);
+
// Order of [] and --/++
.@a[1] = 0;
.@a[1]++; // .@a[1] = .@a[1] + 1;
diff --git a/npc/instances/EndlessTower.txt b/npc/instances/EndlessTower.txt
index dc60ce766..2964f7e2a 100644
--- a/npc/instances/EndlessTower.txt
+++ b/npc/instances/EndlessTower.txt
@@ -220,23 +220,21 @@ e_tower,81,105,0 script Tower Protection Stone 2_MONEMUS,{
switch (select(.@str$, "Enter the Dungeon", "Return to Alberta", "Cancel")) {
case 1:
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mesf("Party Name: %s", .@p_name$);
- mesf("Party Leader: %s", strcharinfo(PC_NAME));
- mesf("^0000ff%s ^000000- Reservation Failed!", .@md_name$);
- close();
+ if (.@instance >= 0) {
+ for (.@i = 1; .@i <= 6; ++.@i) {
+ if (instance_attachmap(.@i + "@tower", .@instance) == "") {
+ mesf("Party Name: %s", .@p_name$);
+ mesf("Party Leader: %s", strcharinfo(PC_NAME));
+ mesf("^0000ff%s ^000000- Reservation Failed!", .@md_name$);
+ instance_destroy(.@instance);
+ close();
+ }
+ }
+ instance_set_timeout(14400, 300, .@instance);
+ instance_init(.@instance);
}
mesf("^0000ff%s^000000 - Try to reserve", .@md_name$);
mes("After making a reservation, you have to talk to NPC behind and select the menu 'Enter the Dungeon' to enter the dungeon.");
- for (.@i = 1; .@i <= 6; ++.@i) {
- if (instance_attachmap(.@i + "@tower", .@instance) == "") {
- mesf("^0000ff%s ^000000- Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
- }
- }
- instance_set_timeout(14400, 300, .@instance);
- instance_init(.@instance);
close();
case 2:
callsub(L_Enter, 0, 1, .@md_name$, .@p_name$);
diff --git a/npc/instances/NydhoggsNest.txt b/npc/instances/NydhoggsNest.txt
index 46ffdaef3..d39d90cd3 100644
--- a/npc/instances/NydhoggsNest.txt
+++ b/npc/instances/NydhoggsNest.txt
@@ -128,21 +128,18 @@ nyd_dun02,100,201,3 script Yggdrasil Gatekeeper HIDDEN_NPC,8,8,{
switch (select("Please allow me to enter.", "I want to go in.", "I want to leave.")) {
case 1:
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mes("[Yggdrasil Gatekeeper]");
- mes("The Guardian seems to wish to be alone. I will go in and check, please wait out here.");
- close();
+ if (.@instance >= 0) {
+ for (.@i = 1; .@i <= 2; ++.@i) {
+ if (instance_attachmap(.@i + "@nyd", .@instance) == "") {
+ mes("[Yggdrasil Gatekeeper]");
+ mes("The Guardian seems to wish to be alone. I will go in and check, please wait out here.");
+ instance_destroy(.@instance);
+ close();
+ }
+ }
+ instance_set_timeout(144000, 300, .@instance);
+ instance_init(.@instance);
}
- for (.@i = 1; .@i <= 2; ++.@i) {
- if (instance_attachmap(.@i + "@nyd", .@instance) == "")
- break;
- }
- if (.@i < 2) {
- instance_destroy(.@instance);
- close();
- }
- instance_set_timeout(144000, 300, .@instance);
- instance_init(.@instance);
mes("[Yggdrasil Gatekeeper]");
mes("I've recorded your request, are you ready to go inside?");
next();
diff --git a/npc/instances/OrcsMemory.txt b/npc/instances/OrcsMemory.txt
index 1aaf2fd42..383786696 100644
--- a/npc/instances/OrcsMemory.txt
+++ b/npc/instances/OrcsMemory.txt
@@ -67,23 +67,20 @@ gef_fild10,242,202,0 script Dimensional Gorge Piece 2_MONEMUS,{
switch (select(.@str$, "Enter the Dungeon", "Cancel")) {
case 1:
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mesf("Party Name: %s", .@p_name$);
- mesf("Party Leader: %s", strcharinfo(PC_NAME));
- mesf("^0000ff%s ^000000 - Reservation Failed.", .@md_name$);
- close();
+ if (.@instance >= 0) {
+ for (.@i = 1; .@i <= 2; ++.@i) {
+ if (instance_attachmap(.@i + "@orcs", .@instance) == "") {
+ mesf("Party Name: %s", .@p_name$);
+ mesf("Party Leader: %s", strcharinfo(PC_NAME));
+ mesf("^0000ff%s ^000000 - Reservation Failed.", .@md_name$);
+ instance_destroy(.@instance);
+ close();
+ }
+ }
+ instance_set_timeout(7200, 300, .@instance);
+ instance_init(.@instance);
}
mesf("^0000ff%s^000000- Attempting to book an entrance", .@md_name$);
- for (.@i = 1; .@i <= 2; ++.@i) {
- if (instance_attachmap(.@i + "@orcs", .@instance) == "")
- break;
- }
- if (.@i < 2) {
- instance_destroy(.@instance);
- close();
- }
- instance_set_timeout(7200, 300, .@instance);
- instance_init(.@instance);
mesf("After making a reservation, you have to select 'Enter the Dungeon' from the menu if you wish to enter the %s.", .@md_name$);
close();
case 2:
diff --git a/npc/instances/SealedShrine.txt b/npc/instances/SealedShrine.txt
index 3bc3d951a..91771c31c 100644
--- a/npc/instances/SealedShrine.txt
+++ b/npc/instances/SealedShrine.txt
@@ -118,37 +118,33 @@ monk_test,309,146,3 script Friar Patrick#edq 4_M_OLDFRIAR,{
mesf("Party name is %s...", getpartyname(.@party_id));
mesf("Name of the leader is %s...", strcharinfo(PC_NAME));
.@instance = instance_create(_("Sealed Catacomb"), .@party_id);
- if (.@instance < 0) {
- mes("Umm... But it seems that there is a problem here... I'll check quickly. Please wait.");
- } else {
+ if (.@instance >= 0) {
for (.@i = 1; .@i <= 2; .@i++) {
if (instance_attachmap(.@i + "@cata", .@instance) == "") {
- mesf("Failed to attach %d@cata as a map!", .@i);
+ mes("Umm... But it seems that there is a problem here... I'll check quickly. Please wait.");
instance_destroy(.@instance);
close();
}
}
-
instance_set_timeout(7200, 300, .@instance);
instance_init(.@instance);
-
- mes("Okay... I'll adjust the shrine's seal so that you and your group can enter.");
- next();
- mes("[Friar Patrick]");
- mes("You will see a sign when the seal has broken. Please wait until the sign appears...");
- next();
- mes("[Friar Patrick]");
- mes("When you see the sign, put your hands on the gravestone... Then you can move inside.");
- next();
- mes("[Friar Patrick]");
- mes("One thing that you should remember is... Anyone who enters this shrine will be cursed by Baphomet and cannot enter or leave while they are cursed.");
- next();
- mes("[Friar Patrick]");
- mes("And one more thing... In this cursed area, some skills, which are protected by outer physical power are prohibited by the effect of the seal.");
- next();
- mes("[Friar Patrick]");
- mes("For example, the skills like ^0000FFSafety Wall and Assumptio^000000... So you'd better prepare before entering the shrine.");
}
+ mes("Okay... I'll adjust the shrine's seal so that you and your group can enter.");
+ next();
+ mes("[Friar Patrick]");
+ mes("You will see a sign when the seal has broken. Please wait until the sign appears...");
+ next();
+ mes("[Friar Patrick]");
+ mes("When you see the sign, put your hands on the gravestone... Then you can move inside.");
+ next();
+ mes("[Friar Patrick]");
+ mes("One thing that you should remember is... Anyone who enters this shrine will be cursed by Baphomet and cannot enter or leave while they are cursed.");
+ next();
+ mes("[Friar Patrick]");
+ mes("And one more thing... In this cursed area, some skills, which are protected by outer physical power are prohibited by the effect of the seal.");
+ next();
+ mes("[Friar Patrick]");
+ mes("For example, the skills like ^0000FFSafety Wall and Assumptio^000000... So you'd better prepare before entering the shrine.");
} else {
mes("[Friar Patrick]");
mes("Umm... I recognize your courage, but... I can't permit anyone to enter this place. I can only permit the leader of a party to enter first.");
diff --git a/npc/re/instances/BakonawaLake.txt b/npc/re/instances/BakonawaLake.txt
index 65622171b..5226db6cc 100644
--- a/npc/re/instances/BakonawaLake.txt
+++ b/npc/re/instances/BakonawaLake.txt
@@ -82,18 +82,16 @@ ma_scene01,174,179,4 script Taho 4_M_DEWZATIMAN,{
switch (.@i) {
case 1:
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mes("[Taho]");
- mes("Oh, the rope got dropped. I have to make a new one.");
- close();
- }
- if (instance_attachmap("1@ma_b", .@instance) == "") {
- mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@ma_b", .@instance) == "") {
+ mes("[Taho]");
+ mes("Oh, the rope got dropped. I have to make a new one.");
+ instance_destroy(.@instance);
+ close();
+ }
+ instance_set_timeout(7200, 300, .@instance);
+ instance_init(.@instance);
}
- instance_set_timeout(7200, 300, .@instance);
- instance_init(.@instance);
mes("[Taho]");
mes("Now I'm weaving, so you can go down when I'm done.");
close();
diff --git a/npc/re/instances/BangungotHospital.txt b/npc/re/instances/BangungotHospital.txt
index 9e8e836c4..6972322e1 100644
--- a/npc/re/instances/BangungotHospital.txt
+++ b/npc/re/instances/BangungotHospital.txt
@@ -274,21 +274,19 @@ L_Enter:
switch(select(((getarg(0))?"Prepare to enter the second floor.":""), "Enter the second floor.", "Do not enter.")) {
case 1:
.@instance = instance_create(.@md_name$,getcharid(CHAR_ID_PARTY));
- if (.@instance < 0) {
- mes "[Nurse Maenne]";
- mes "A critical situation has happened.";
- mes "You can't go up to the 2nd floor.";
- close2;
- cutin "",255;
- end;
- }
- if (instance_attachmap("1@ma_h",.@instance) == "") {
- mes "^0000ff"+.@md_name$+"^000000 - Reservation Failed!";
- instance_destroy(.@instance);
- close;
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@ma_h", .@instance) == "") {
+ mes("[Nurse Maenne]");
+ mes("A critical situation has happened.");
+ mes("You can't go up to the 2nd floor.");
+ instance_destroy(.@instance);
+ close2();
+ cutin("", 255);
+ end;
+ }
+ instance_set_timeout(3600, 300, .@instance);
+ instance_init(.@instance);
}
- instance_set_timeout 3600,300,.@instance;
- instance_init(.@instance);
mes "[Nurse Maenne]";
mes "We are preparing to go up";
mes "to the second floor.";
diff --git a/npc/re/instances/BuwayaCave.txt b/npc/re/instances/BuwayaCave.txt
index 393ac5d9e..1d3eddc6a 100644
--- a/npc/re/instances/BuwayaCave.txt
+++ b/npc/re/instances/BuwayaCave.txt
@@ -93,22 +93,19 @@ ma_fild02,312,317,5 script Guard#buwaya_cave 4_MAL_SOLDIER,{
// fall through
}
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mes("[Guard]");
- mesf("Party name is... %s.", getpartyname(.@party_id));
- mesf("Party leader is... %s", strcharinfo(PC_NAME));
- mesf("^0000ff%s^000000 cannot be opened now.", .@md_name$);
- mes("Please try a moment later.");
- close();
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@ma_c", .@instance) == "") {
+ mes("[Guard]");
+ mesf("Party name is... %s.", getpartyname(.@party_id));
+ mesf("Party leader is... %s", strcharinfo(PC_NAME));
+ mesf("^0000ff%s^000000 cannot be opened now.", .@md_name$);
+ mes("Please try a moment later.");
+ instance_destroy(.@instance);
+ close();
+ }
+ instance_set_timeout(3600, 300, .@instance);
+ instance_init(.@instance);
}
- if (instance_attachmap("1@ma_c", .@instance) == "") {
- mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
- }
- instance_set_timeout(3600, 300, .@instance);
- instance_init(.@instance);
-
mes("[Guard]");
mesf("I will open up the tunnel to ^0000ff%s^000000.", .@md_name$);
mes("I wish you good luck.");
diff --git a/npc/re/instances/EclageInterior.txt b/npc/re/instances/EclageInterior.txt
index 6b2808e05..2b2117b93 100644
--- a/npc/re/instances/EclageInterior.txt
+++ b/npc/re/instances/EclageInterior.txt
@@ -55,20 +55,18 @@ ecl_hub01,132,12,3 script Chief of Staff#tl01::EclInstance 4_F_FAIRY,{
switch (select("Enter it.", "Forget it.")) {
case 1:
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mes("[Shenime]");
- mes("There are some soldiers dispatched by Mayor not too long ago.");
- mes("I should sure hope that you aren't the disturbance they're looking for, right?");
- close();
- }
- if (instance_attachmap("1@ecl", .@instance) == "") {
- mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@ecl", .@instance) == "") {
+ mes("[Shenime]");
+ mes("There are some soldiers dispatched by Mayor not too long ago.");
+ mes("I should sure hope that you aren't the disturbance they're looking for, right?");
+ instance_destroy(.@instance);
+ close();
+ }
+ ecl_interior_time = gettimetick(2) + 20 * 60;
+ instance_set_timeout(1200, 1200, .@instance);
+ instance_init(.@instance);
}
- ecl_interior_time = gettimetick(2) + 20 * 60;
- instance_set_timeout(1200, 1200, .@instance);
- instance_init(.@instance);
mes("[Shenime]");
mes("Given the tight internal security, you should prepare yourself.");
mes("Wait here for a minute.");
diff --git a/npc/re/instances/HazyForest.txt b/npc/re/instances/HazyForest.txt
index 291ce54db..24e03b22e 100644
--- a/npc/re/instances/HazyForest.txt
+++ b/npc/re/instances/HazyForest.txt
@@ -101,35 +101,34 @@ bif_fild01,158,340,5 script Laphine Soldier#mist 4_M_FAIRYSOLDIER,{
mesf("Party Name %s...", getpartyname(.@party_id));
mesf("Party Leader %s...", strcharinfo(PC_NAME));
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mes("Hmm...");
- next();
- mes("[Laphine Soldier]");
- if (!.@playtime)
- mes("It's dangerous in the forest.");
- else
- mes("The atmosphere is somewhat tense in the forest.");
- mes("...Why don't you just go back today?");
- close();
- }
- if (instance_attachmap("1@mist", .@instance) != "") {
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@mist", .@instance) == "") {
+ mes("Hmm...");
+ next();
+ mes("[Laphine Soldier]");
+ if (!.@playtime)
+ mes("It's dangerous in the forest.");
+ else
+ mes("The atmosphere is somewhat tense in the forest.");
+ mes("...Why don't you just go back today?");
+ instance_destroy(.@instance);
+ close();
+ }
instance_set_timeout(7200, 300, .@instance);
instance_init(.@instance);
- mes("I've got it. I've written them down on the report here.");
- next();
- mes("[Laphine Soldier]");
- mes("You'll get permission soon.");
- mes("Now go to the log tunnel, the only way to get into the Hazy Forest.");
- mes("You understand?");
- next();
- mes("[Laphine Soldier]");
- mes("We can't go against the forest,");
- mes("but maybe you humans can.");
- mes("Good luck!");
- close();
- } else {
- instance_destroy(.@instance);
}
+ mes("I've got it. I've written them down on the report here.");
+ next();
+ mes("[Laphine Soldier]");
+ mes("You'll get permission soon.");
+ mes("Now go to the log tunnel, the only way to get into the Hazy Forest.");
+ mes("You understand?");
+ next();
+ mes("[Laphine Soldier]");
+ mes("We can't go against the forest,");
+ mes("but maybe you humans can.");
+ mes("Good luck!");
+ close();
case 2:
mes("[Laphine Soldier]");
mes("Well, you've made the right decision.");
diff --git a/npc/re/instances/MalangdoCulvert.txt b/npc/re/instances/MalangdoCulvert.txt
index 2e51f0fd5..d61509511 100644
--- a/npc/re/instances/MalangdoCulvert.txt
+++ b/npc/re/instances/MalangdoCulvert.txt
@@ -433,20 +433,19 @@ mal_in01,160,34,4 script Missing, the Cleaner 4_CAT_SAILOR2,{
close();
case 2:
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mesf("Party name: %s", getpartyname(.@party_id));
- mesf("Party leader: %s", strcharinfo(PC_NAME));
- mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
- close();
+ if (.@instance >= 0) {
+ for (.@i = 1; .@i <= 2; .@i++) {
+ if (instance_attachmap(.@i + "@pump", .@instance) == "") {
+ mesf("Party name: %s", getpartyname(.@party_id));
+ mesf("Party leader: %s", strcharinfo(PC_NAME));
+ mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
+ instance_destroy(.@instance);
+ close();
+ }
+ }
+ instance_set_timeout(3600, 300, .@instance);
+ instance_init(.@instance);
}
- if (instance_attachmap("1@pump", .@instance) == "" || instance_attachmap("2@pump", .@instance) == "") {
- mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
- }
- instance_set_timeout(3600, 300, .@instance);
- instance_init(.@instance);
-
mesf("^3333FF%s^000000 - Reserving", .@md_name$);
mes("After making the reservation, you");
mes("have to select Enter the Culvert.");
diff --git a/npc/re/instances/OldGlastHeim.txt b/npc/re/instances/OldGlastHeim.txt
index c317e7495..587de45bf 100644
--- a/npc/re/instances/OldGlastHeim.txt
+++ b/npc/re/instances/OldGlastHeim.txt
@@ -110,19 +110,19 @@ glast_01,204,273,6 script Hugin#ghinstance 4_M_SAGE_C,{
if (getcharid(CHAR_ID_CHAR) != getpartyleader(.@party_id, 2))
end;
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mesf("Party Name: %s", .@p_name$);
- mesf("Party Leader: %s", strcharinfo(PC_NAME));
- mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
- close();
- }
- if (instance_attachmap("1@gl_k", .@instance) == "" || instance_attachmap("2@gl_k", .@instance) == "") {
- mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
+ if (.@instance >= 0) {
+ for (.@i = 1; .@i <= 2; .@i++) {
+ if (instance_attachmap(.@i + "@gl_k", .@instance) == "") {
+ mesf("Party Name: %s", .@p_name$);
+ mesf("Party Leader: %s", strcharinfo(PC_NAME));
+ mesf("^0000ff%s^000000 - Reservation Failed!", .@md_name$);
+ instance_destroy(.@instance);
+ close();
+ }
+ }
+ instance_set_timeout(3600, 300, .@instance);
+ instance_init(.@instance);
}
- instance_set_timeout(3600, 300, .@instance);
- instance_init(.@instance);
mes("[Hugin]");
mes("The time gap was created. When you're ready, talk to me again.");
close();
diff --git a/npc/re/instances/WolfchevLaboratory.txt b/npc/re/instances/WolfchevLaboratory.txt
index d6c5516e5..efb32be7e 100644
--- a/npc/re/instances/WolfchevLaboratory.txt
+++ b/npc/re/instances/WolfchevLaboratory.txt
@@ -1859,30 +1859,29 @@ lhz_dun04,151,276,3 script Researcher#memo 4_LGTSCIENCE,{
}
if (getpartyleader(getcharid(CHAR_ID_PARTY),2) == getcharid(CHAR_ID_CHAR)) {
.@instance = instance_create("Worsef", getcharid(CHAR_ID_PARTY));
- if (.@instance < 0) {
- mes "[Wolfchev]";
- mes "Hmm.. Lab entering system is a bit weird. Would wait for me to check the system?";
- } else {
- mes "[Wolfchev]";
- mes "Please hold on..";
- next;
- mes "Wolfchev starts to control certain gear.";
- next;
- progressbar "FF00FF", 2;
- if (instance_attachmap("1@lhz", .@instance) != "") {
- instance_set_timeout 14400, 300, .@instance;
- instance_init(.@instance);
- mes "[Wolfchev]";
- mes "Alright! I have marked lan entering system code as";
- mes "^0000ff"+ strcharinfo(PC_PARTY) +"^000000 party leader's name ^0000ff"+ strcharinfo(PC_NAME) +"^000000!!.";
- next;
- mes "[Wolfchev]";
- mes "Now, your party is free to pass the entrance.";
- } else {
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@lhz", .@instance) == "") {
+ mes("[Wolfchev]");
+ mes("Hmm.. Lab entering system is a bit weird. Would wait for me to check the system?");
instance_destroy(.@instance);
+ close();
}
+ instance_set_timeout 14400, 300, .@instance;
+ instance_init(.@instance);
}
- close;
+ mes("[Wolfchev]");
+ mes("Please hold on..");
+ next();
+ mes("Wolfchev starts to control certain gear.");
+ next();
+ progressbar("FF00FF", 2);
+ mes("[Wolfchev]");
+ mes("Alright! I have marked lan entering system code as");
+ mesf("^0000ff%s^000000 party leader's name ^0000ff%s^000000!!.", strcharinfo(PC_PARTY), strcharinfo(PC_NAME));
+ next();
+ mes("[Wolfchev]");
+ mes("Now, your party is free to pass the entrance.");
+ close();
} else {
mes "[Wolfchev]";
mes "You are not the ^0000ffLeader of the party^000000, are you? Please go get the leader.";
diff --git a/npc/re/instances/ghost_palace.txt b/npc/re/instances/ghost_palace.txt
index e4ca12f99..3e708dc57 100644
--- a/npc/re/instances/ghost_palace.txt
+++ b/npc/re/instances/ghost_palace.txt
@@ -91,27 +91,24 @@ dali02,44,129,5 script Unpleasent Royal Guard 4_M_SAKRAYROYAL,{
.@instance = instance_create(_("Ghost Palace"), .@party_id);
.@p_name$ = getpartyname(.@party_id);
.@md_name$ = _("Ghost Palace");
- if (.@instance < 0) {
- mesf("Party Name: %s", .@p_name$);
- mesf("Party Leader: %s", strcharinfo(PC_NAME));
- mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
- close();
- }
- if (instance_attachmap("1@spa", .@instance) != "") {
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@spa", .@instance) == "") {
+ mesf("Party Name: %s", .@p_name$);
+ mesf("Party Leader: %s", strcharinfo(PC_NAME));
+ mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
+ instance_destroy(.@instance);
+ close();
+ }
instance_set_timeout(3600, 300, .@instance);
instance_init(.@instance);
if (!questprogress(1260))
setquest(1260);
- mes("[Unpleasent Royal Guard]");
- mes("Thank You..\r"
- "I will open the secret passage to ^0000FFGhost Palace.^000000\r"
- "Please be ready!");
- close();
- } else {
- instance_destroy(.@instance);
- mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
- close();
}
+ mes("[Unpleasent Royal Guard]");
+ mes("Thank You..\r"
+ "I will open the secret passage to ^0000FFGhost Palace.^000000\r"
+ "Please be ready!");
+ close();
}
dali02,41,134,0 script Interdimensional Device::gpportal PORTAL,{
diff --git a/npc/re/instances/octopus_cave.txt b/npc/re/instances/octopus_cave.txt
index e4d8d4357..4c964072a 100644
--- a/npc/re/instances/octopus_cave.txt
+++ b/npc/re/instances/octopus_cave.txt
@@ -85,22 +85,19 @@ mal_dun01,151,235,5 script Starfish 4_ASTER,{
erasequest(4197);
if (countitem(Octopus_Hunt_Stick)) {
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mes("[Starfish]");
- mesf("Party name is... %s.", getpartyname(.@party_id));
- mesf("Party leader is... %s.", strcharinfo(PC_NAME));
- mesf("^0000FF%s^000000, I cannot open now, hehe.", .@md_name$);
- mes("Now is not the time, please wait.");
- close();
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@cash", .@instance) == "") {
+ mes("[Starfish]");
+ mesf("Party name is... %s.", getpartyname(.@party_id));
+ mesf("Party leader is... %s.", strcharinfo(PC_NAME));
+ mesf("^0000FF%s^000000, I cannot open now, hehe.", .@md_name$);
+ mes("Now is not the time, please wait.");
+ instance_destroy(.@instance);
+ close();
+ }
+ instance_set_timeout(3600, 300, .@instance);
+ instance_init(.@instance);
}
- if (instance_attachmap("1@cash", .@instance) == "") {
- mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
- }
- instance_set_timeout(3600, 300, .@instance);
- instance_init(.@instance);
-
mes("[Starfish]");
mesf("I will open the gate for a while to ^0000FF%s^000000.", .@md_name$);
mes("Please catch that pervert octopus, and come back with it sticked to the pick, hehe.");
diff --git a/npc/re/instances/saras_memory.txt b/npc/re/instances/saras_memory.txt
index c9a47534b..9eac396aa 100644
--- a/npc/re/instances/saras_memory.txt
+++ b/npc/re/instances/saras_memory.txt
@@ -185,19 +185,17 @@ dali,138,118,0 script Dimensional Device#dimen PORTAL,{
if (getcharid(CHAR_ID_CHAR) != getpartyleader(.@party_id, 2))
end;
.@instance = instance_create(.@md_name$, .@party_id);
- if (.@instance < 0) {
- mesf("Party Name: %s", .@p_name$);
- mesf("Party Leader: %s", strcharinfo(PC_NAME));
- mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
- close();
- }
- if (instance_attachmap("1@sara", .@instance) == "") {
- mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
- instance_destroy(.@instance);
- close();
+ if (.@instance >= 0) {
+ if (instance_attachmap("1@sara", .@instance) == "") {
+ mesf("Party Name: %s", .@p_name$);
+ mesf("Party Leader: %s", strcharinfo(PC_NAME));
+ mesf("^0000FF%s^000000 - Reservation Failed!", .@md_name$);
+ instance_destroy(.@instance);
+ close();
+ }
+ instance_set_timeout(3600, 300, .@instance);
+ instance_init(.@instance);
}
- instance_set_timeout(3600, 300, .@instance);
- instance_init(.@instance);
mes("^FF0000The dimensional boots up cleanly. Use the device to enter the crack in space and time.^000000");
close();
case 2:
diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql
index e72e96b32..5763847dc 100644
--- a/sql-files/item_db_re.sql
+++ b/sql-files/item_db_re.sql
@@ -5601,6 +5601,35 @@ 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 ('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 ('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','','','');
+REPLACE INTO `item_db` VALUES ('9090','Little_Isis_Egg','Little Isis 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 ('9091','Choco_Egg','Choco 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 ('9092','Eggring_Egg','Eggring 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 ('9093','Hyegun_Egg','Hyegun 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 ('9094','Leaf_Lunatic_Egg','Leaf Lunatic 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 ('9095','Nine_Tails_Egg','Nine Tails 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 ('9096','Cat_o_Nine_Tails_Egg','Cat o\' Nine Tails 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 ('9097','Diabolic_Egg_','Diabolic 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 ('9098','Earth_Deleter_Egg','Earth Deleter 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 ('9099','Teddy_Bear_Egg','Teddy Bear 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 ('9100','Gremlin_Egg','Gremlin 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 ('9101','Scatelon_Egg','Scatleton 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 ('9102','Mummy_Egg','Mummy 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 ('9103','Willow_Egg','Willow 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 ('9104','Roween_Egg','Roween 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 ('9105','Hodremlin_Egg','Hodremlin 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 ('9106','Metaller_Egg','Metaller 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 ('9107','Ancient_Mummy_Egg','Ancient Mummy 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 ('9108','Abandoned_Teddy_Bear_Egg','Abandoned Teddy Bear 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 ('9109','Sweet_Drops_Egg','Sweet Drops 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 ('9111','Phreeoni_Egg','Phreeoni 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 ('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 ('10001','Skull_Helm','Skull Helm','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('10002','Monster_Oxygen_Mask','Monster Oxygen Mask','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('10003','Transparent_Headgear','Transparent Head Protector','8','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 2e51d6a12..8f7e5355b 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -782,6 +782,7 @@ CREATE TABLE IF NOT EXISTS `pet` (
`hungry` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',
`rename_flag` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
`incubate` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `autofeed` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`pet_id`)
) ENGINE=MyISAM;
@@ -893,6 +894,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1496588700); -- 2017-06-0
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1509835214); -- 2017-11-04--10-39.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1519671456); -- 2018-02-26--15-57.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1520654809); -- 2018-03-10--04-06.sql
+INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1528180320); -- 2018-06-05--12-02.sql
--
-- Table structure for table `storage`
--
diff --git a/sql-files/upgrades/2018-06-05--12-02.sql b/sql-files/upgrades/2018-06-05--12-02.sql
new file mode 100644
index 000000000..26c22243f
--- /dev/null
+++ b/sql-files/upgrades/2018-06-05--12-02.sql
@@ -0,0 +1,24 @@
+#1528180320
+
+-- This file is part of Hercules.
+-- http://herc.ws - http://github.com/HerculesWS/Hercules
+--
+-- Copyright (C) 2018 Hercules Dev Team
+-- Copyright (C) 2018 Dastgir
+--
+-- Hercules is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ALTER TABLE `pet` ADD COLUMN `autofeed` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0';
+
+INSERT INTO `sql_updates` (`timestamp`, `ignored`) VALUES (1528180320 , 'No');
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index dac60b6aa..5a737f93a 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -45,3 +45,4 @@
2017-11-04--10-39.sql
2018-02-26--15-57.sql
2018-03-10--04-06.sql
+2018-06-05--12-02.sql
diff --git a/src/char/int_pet.c b/src/char/int_pet.c
index 0ece11b51..f270f205d 100644
--- a/src/char/int_pet.c
+++ b/src/char/int_pet.c
@@ -66,19 +66,19 @@ int inter_pet_tosql(const struct s_pet *p)
if (p->pet_id == 0) {
// New pet.
if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` "
- "(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`) "
- "VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+ "(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`, `autofeed`) "
+ "VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
- p->equip, intimate, hungry, p->rename_flag, p->incubate)) {
+ p->equip, intimate, hungry, p->rename_flag, p->incubate, p->autofeed)) {
Sql_ShowDebug(inter->sql_handle);
return 0;
}
pet_id = (int)SQL->LastInsertId(inter->sql_handle);
} else {
// Update pet.
- if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d' WHERE `pet_id`='%d'",
+ if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d', `autofeed`='%d' WHERE `pet_id`='%d'",
pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
- p->equip, intimate, hungry, p->rename_flag, p->incubate, p->pet_id)) {
+ p->equip, intimate, hungry, p->rename_flag, p->incubate, p->autofeed, p->pet_id)) {
Sql_ShowDebug(inter->sql_handle);
return 0;
}
@@ -102,9 +102,9 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
nullpo_ret(p);
memset(p, 0, sizeof(struct s_pet));
- //`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
+ //`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`, `autofeed`)
- if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
+ if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`,`autofeed` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
{
Sql_ShowDebug(inter->sql_handle);
return 0;
@@ -124,6 +124,7 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
SQL->GetData(inter->sql_handle, 9, &data, NULL); p->hungry = atoi(data);
SQL->GetData(inter->sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
SQL->GetData(inter->sql_handle, 11, &data, NULL); p->incubate = atoi(data);
+ SQL->GetData(inter->sql_handle, 12, &data, NULL); p->autofeed = atoi(data);
SQL->FreeResult(inter->sql_handle);
diff --git a/src/common/HPM.h b/src/common/HPM.h
index e55397022..efa5d8370 100644
--- a/src/common/HPM.h
+++ b/src/common/HPM.h
@@ -42,11 +42,7 @@
#define DLL HINSTANCE
#else // ! WIN32
#include <dlfcn.h>
- #ifdef RTLD_DEEPBIND // Certain linux distributions require this, but it's not available everywhere
- #define plugin_open(x) dlopen((x),RTLD_NOW|RTLD_DEEPBIND)
- #else // ! RTLD_DEEPBIND
- #define plugin_open(x) dlopen((x),RTLD_NOW)
- #endif // RTLD_DEEPBIND
+ #define plugin_open(x) dlopen((x), RTLD_NOW)
#define plugin_import(x,y,z) (z)dlsym((x),(y))
#define plugin_close(x) dlclose(x)
#define plugin_geterror(buf) ((void)buf, dlerror())
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 8df39df02..2370dfa8d 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -588,6 +588,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "PACKET_CZ_ADD_ITEM_TO_MAIL", sizeof(struct PACKET_CZ_ADD_ITEM_TO_MAIL), SERVER_TYPE_MAP },
{ "PACKET_CZ_CHECKNAME", sizeof(struct PACKET_CZ_CHECKNAME), SERVER_TYPE_MAP },
{ "PACKET_CZ_OPEN_UI", sizeof(struct PACKET_CZ_OPEN_UI), SERVER_TYPE_MAP },
+ { "PACKET_CZ_PET_EVOLUTION", sizeof(struct PACKET_CZ_PET_EVOLUTION), SERVER_TYPE_MAP },
{ "PACKET_CZ_PRIVATE_AIRSHIP_REQUEST", sizeof(struct PACKET_CZ_PRIVATE_AIRSHIP_REQUEST), SERVER_TYPE_MAP },
{ "PACKET_CZ_REQ_DELETE_MAIL", sizeof(struct PACKET_CZ_REQ_DELETE_MAIL), SERVER_TYPE_MAP },
{ "PACKET_CZ_REQ_ITEM_FROM_MAIL", sizeof(struct PACKET_CZ_REQ_ITEM_FROM_MAIL), SERVER_TYPE_MAP },
@@ -696,6 +697,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "packet_viewequip_ack", sizeof(struct packet_viewequip_ack), SERVER_TYPE_MAP },
{ "packet_whisper_message", sizeof(struct packet_whisper_message), SERVER_TYPE_MAP },
{ "packet_wis_end", sizeof(struct packet_wis_end), SERVER_TYPE_MAP },
+ { "pet_evolution_items", sizeof(struct pet_evolution_items), SERVER_TYPE_MAP },
#else
#define MAP_PACKETS_STRUCT_H
#endif // MAP_PACKETS_STRUCT_H
@@ -746,6 +748,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
#ifdef MAP_PET_H
{ "pet_bonus", sizeof(struct pet_bonus), SERVER_TYPE_MAP },
{ "pet_data", sizeof(struct pet_data), SERVER_TYPE_MAP },
+ { "pet_evolve_data", sizeof(struct pet_evolve_data), SERVER_TYPE_MAP },
{ "pet_interface", sizeof(struct pet_interface), SERVER_TYPE_MAP },
{ "pet_loot", sizeof(struct pet_loot), SERVER_TYPE_MAP },
{ "pet_recovery", sizeof(struct pet_recovery), SERVER_TYPE_MAP },
diff --git a/src/common/console.c b/src/common/console.c
index 0b0a900f6..e7edd7e1e 100644
--- a/src/common/console.c
+++ b/src/common/console.c
@@ -133,7 +133,10 @@ int console_parse_key_pressed(void)
**/
CPCMD_C(exit, server)
{
- core->runflag = 0;
+ if (core->shutdown_callback != NULL)
+ core->shutdown_callback();
+ else
+ core->runflag = CORE_ST_STOP;
}
/**
diff --git a/src/common/core.c b/src/common/core.c
index 1bd332eec..406bb7629 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -80,9 +80,6 @@
// And don't complain to us if the XYZ plugin you installed wiped your hard disk, or worse.
// Note: This feature is deprecated, and should not be used.
-/// Called when a terminate signal is received.
-void (*shutdown_callback)(void) = NULL;
-
struct core_interface core_s;
struct core_interface *core = &core_s;
@@ -128,8 +125,8 @@ static BOOL WINAPI console_handler(DWORD c_event)
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
- if( shutdown_callback != NULL )
- shutdown_callback();
+ if (core->shutdown_callback != NULL)
+ core->shutdown_callback();
else
core->runflag = CORE_ST_STOP;// auto-shutdown
break;
@@ -158,8 +155,8 @@ static void sig_proc(int sn)
case SIGTERM:
if (++is_called > 3)
exit(EXIT_SUCCESS);
- if( shutdown_callback != NULL )
- shutdown_callback();
+ if (core->shutdown_callback != NULL)
+ core->shutdown_callback();
else
core->runflag = CORE_ST_STOP;// auto-shutdown
break;
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 74d48dd47..0b4ba4a45 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -544,6 +544,7 @@ struct s_pet {
char name[NAME_LENGTH];
char rename_flag;
char incubate;
+ int autofeed;
};
struct s_homunculus { //[orn]
diff --git a/src/map/battle.c b/src/map/battle.c
index 6a961afeb..4d320704a 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7319,6 +7319,7 @@ static const struct battle_data {
{ "features/rodex", &battle_config.feature_rodex, 1, 0, 1, },
{ "features/rodex_use_accountmail", &battle_config.feature_rodex_use_accountmail, 0, 0, 1, },
{ "features/enable_homun_autofeed", &battle_config.feature_enable_homun_autofeed, 1, 0, 1, },
+ { "features/enable_pet_autofeed", &battle_config.feature_enable_pet_autofeed, 1, 0, 1, },
{ "storage_use_item", &battle_config.storage_use_item, 0, 0, 1, },
{ "features/enable_attendance_system", &battle_config.feature_enable_attendance_system,1, 0, 1, },
{ "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, },
diff --git a/src/map/battle.h b/src/map/battle.h
index c325daf0d..f4176f142 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -563,6 +563,7 @@ struct Battle_Config {
int feature_rodex_use_accountmail;
int feature_enable_homun_autofeed;
+ int feature_enable_pet_autofeed;
int storage_use_item;
diff --git a/src/map/clif.c b/src/map/clif.c
index aeaf03e43..c085c4fe4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9093,7 +9093,7 @@ void clif_feel_hate_reset(struct map_session_data *sd)
/// value:
/// 0 = disabled
/// 1 = enabled
-void clif_zc_config(struct map_session_data* sd, int type, int flag)
+void clif_zc_config(struct map_session_data* sd, enum CZ_CONFIG type, int flag)
{
int fd;
nullpo_retv(sd);
@@ -13755,6 +13755,115 @@ void clif_parse_ChangePetName(int fd, struct map_session_data *sd)
pet->change_name(sd, RFIFOP(fd,2));
}
+void clif_parse_pet_evolution(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+/// Request to Evolve the pet (CZ_PET_EVOLUTION) [Dastgir/Hercules]
+/// 09fb <Length>.W <EvolvedPetEggID>.W {<index>.W <amount>.W}*items
+void clif_parse_pet_evolution(int fd, struct map_session_data *sd)
+{
+ const struct PACKET_CZ_PET_EVOLUTION *p = RP2PTR(fd);
+ int i = 0, idx, petIndex;
+
+ Assert_retv(p->PacketLength >= (uint16)sizeof(struct PACKET_CZ_PET_EVOLUTION));
+
+ if (sd->status.pet_id == 0) {
+ clif->petEvolutionResult(fd, PET_EVOL_NO_CALLPET);
+ return;
+ }
+
+ ARR_FIND(0, MAX_INVENTORY, idx, sd->status.inventory[idx].card[0] == CARD0_PET &&
+ sd->status.pet_id == MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
+
+ if (idx == MAX_INVENTORY) {
+ clif->petEvolutionResult(fd, PET_EVOL_NO_PETEGG);
+ return;
+ }
+
+ // Not Loyal Yet
+ if (sd->pd == NULL || sd->pd->pet.intimate < 900) {
+ clif->petEvolutionResult(fd, PET_EVOL_RG_FAMILIAR);
+ return;
+ }
+
+ ARR_FIND(0, MAX_PET_DB, petIndex, pet->db[petIndex].class_ == sd->pd->pet.class_);
+
+ if (petIndex == MAX_PET_DB) {
+ // Which error?
+ clif->petEvolutionResult(fd, PET_EVOL_UNKNOWN);
+ return;
+ }
+
+ // Client side validation is not done as it is insecure.
+ for (i = 0; i < VECTOR_LENGTH(pet->db[petIndex].evolve_data); i++) {
+ struct pet_evolve_data *ped = &VECTOR_INDEX(pet->db[petIndex].evolve_data, i);
+ if (ped->petEggId == p->EvolvedPetEggID) {
+ int j;
+ int pet_id;
+
+ if (VECTOR_LENGTH(ped->items) == 0) {
+ clif->petEvolutionResult(fd, PET_EVOL_NO_RECIPE);
+ return;
+ }
+ for (j = 0; j < VECTOR_LENGTH(ped->items); j++) {
+ struct itemlist_entry *list = &VECTOR_INDEX(ped->items, j);
+ int n = pc->search_inventory(sd, list->id);
+
+ if (n == INDEX_NOT_FOUND) {
+ clif->petEvolutionResult(fd, PET_EVOL_NO_MATERIAL);
+ return;
+ }
+ }
+
+ for (j = 0; j < VECTOR_LENGTH(ped->items); j++) {
+ struct itemlist_entry *list = &VECTOR_INDEX(ped->items, j);
+ int n = pc->search_inventory(sd, list->id);
+
+ if (pc->delitem(sd, n, list->amount, 0, DELITEM_NORMAL, LOG_TYPE_EGG) == 1) {
+ clif->petEvolutionResult(fd, PET_EVOL_NO_MATERIAL);
+ return;
+ }
+ }
+
+ // Return to Egg
+ pet->return_egg(sd, sd->pd);
+
+ if (pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG) == 1) {
+ clif->petEvolutionResult(fd, PET_EVOL_NO_PETEGG);
+ return;
+ }
+
+ pet_id = pet->search_petDB_index(ped->petEggId, PET_EGG);
+ if (pet_id >= 0) {
+ sd->catch_target_class = pet->db[pet_id].class_;
+
+ intif->create_pet(
+ sd->status.account_id, sd->status.char_id,
+ (short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv,
+ (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate,
+ 100, 0, 1, pet->db[pet_id].jname);
+ clif->petEvolutionResult(fd, PET_EVOL_SUCCESS);
+ } else {
+ clif->petEvolutionResult(fd, PET_EVOL_UNKNOWN);
+ }
+ return;
+ }
+ }
+
+ clif->petEvolutionResult(fd, PET_EVOL_UNKNOWN);
+}
+
+/**
+ * Result of Pet Evolution (ZC_PET_EVOLUTION_RESULT)
+ * 0x9fc <Result>.L
+ */
+void clif_pet_evolution_result(int fd, enum pet_evolution_result result) {
+#if PACKETVER >= 20140122
+ WFIFOHEAD(fd, packet_len(0x9fc));
+ WFIFOW(fd, 0) = 0x9fc;
+ WFIFOL(fd, 2) = result;
+ WFIFOSET(fd, packet_len(0x9fc));
+#endif
+}
+
void clif_parse_GMKick(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
/// /kill (CZ_DISCONNECT_CHARACTER).
/// Request to disconnect a character.
@@ -16154,24 +16263,38 @@ void clif_parse_cz_config(int fd, struct map_session_data *sd) __attribute__((no
/// 02d8 <type>.L <value>.L
/// type:
/// 0 = open equip window
+/// 2 = pet autofeeding
/// 3 = homunculus autofeeding
/// value:
/// 0 = disabled
/// 1 = enabled
void clif_parse_cz_config(int fd, struct map_session_data *sd)
{
- int type = RFIFOL(fd, 2);
+ enum CZ_CONFIG type = RFIFOL(fd, 2);
int flag = RFIFOL(fd, 6);
- if (type == CZ_CONFIG_OPEN_EQUIPMENT_WINDOW) {
+ switch (type) {
+ case CZ_CONFIG_OPEN_EQUIPMENT_WINDOW:
sd->status.show_equip = flag;
- } else if (type == CZ_CONFIG_HOMUNCULUS_AUTOFEEDING) {
- struct homun_data *hd;
- hd = sd->hd;
+ break;
+ case CZ_CONFIG_PET_AUTOFEEDING: {
+ struct pet_data *pd = sd->pd;
+ nullpo_retv(pd);
+ if (pd->petDB->autofeed == 0) {
+ clif->message(fd, "Autofeed is disabled for this pet.");
+ return;
+ }
+ pd->pet.autofeed = flag;
+ break;
+ }
+ case CZ_CONFIG_HOMUNCULUS_AUTOFEEDING: {
+ struct homun_data *hd = sd->hd;
nullpo_retv(hd);
hd->homunculus.autofeed = flag;
- } else {
- ShowWarning("clif_parse_cz_config: Unsupported type has been received (%d).", type);
+ break;
+ }
+ default:
+ ShowWarning("clif_parse_cz_config: Unsupported type has been received (%u).\n", type);
return;
}
clif->zc_config(sd, type, flag);
@@ -21991,4 +22114,9 @@ void clif_defaults(void) {
clif->pReqStyleChange = clif_parse_cz_req_style_change;
clif->cz_req_style_change_sub = clif_cz_req_style_change_sub;
clif->style_change_response = clif_style_change_response;
+
+ // -- Pet Evolution
+ clif->pPetEvolution = clif_parse_pet_evolution;
+ clif->petEvolutionResult = clif_pet_evolution_result;
+
}
diff --git a/src/map/clif.h b/src/map/clif.h
index 4b625023f..eb9881533 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -592,6 +592,17 @@ enum private_airship {
P_AIRSHIP_ITEM_INVALID
};
+/** Pet Evolution Results */
+enum pet_evolution_result {
+ PET_EVOL_UNKNOWN = 0x0,
+ PET_EVOL_NO_CALLPET = 0x1,
+ PET_EVOL_NO_PETEGG = 0x2,
+ PET_EVOL_NO_RECIPE = 0x3,
+ PET_EVOL_NO_MATERIAL = 0x4,
+ PET_EVOL_RG_FAMILIAR = 0x5,
+ PET_EVOL_SUCCESS = 0x6,
+};
+
/**
* Structures
**/
@@ -834,7 +845,7 @@ struct clif_interface {
void (*mission_info) (struct map_session_data *sd, int mob_id, unsigned char progress);
void (*feel_hate_reset) (struct map_session_data *sd);
void (*partytickack) (struct map_session_data* sd, bool flag);
- void (*zc_config) (struct map_session_data *sd, int type, int flag);
+ void (*zc_config) (struct map_session_data *sd, enum CZ_CONFIG type, int flag);
void (*viewequip_ack) (struct map_session_data* sd, struct map_session_data* tsd);
void (*equpcheckbox) (struct map_session_data* sd);
void (*displayexp) (struct map_session_data *sd, uint64 exp, char type, bool is_quest);
@@ -1484,6 +1495,8 @@ struct clif_interface {
void (*pReqStyleChange) (int fd, struct map_session_data *sd);
void (*cz_req_style_change_sub) (struct map_session_data *sd, int type, int16 idx, bool isitem);
void (*style_change_response) (struct map_session_data *sd, enum stylist_shop flag);
+ void (*pPetEvolution) (int fd, struct map_session_data *sd);
+ void (*petEvolutionResult) (int fd, enum pet_evolution_result result);
};
#ifdef HERCULES_CORE
diff --git a/src/map/packets.h b/src/map/packets.h
index e5fda598d..ebd971005 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -3029,7 +3029,7 @@ packet(0x96e,-1,clif->ackmergeitems);
// 2014-01-22aRagexeRE
#if PACKETVER >= 20140122
// new packets
- packet(0x09fb,-1,clif->pDull/*,XXX*/); // CZ_PET_EVOLUTION
+ packet(0x09fb,-1,clif->pPetEvolution); // CZ_PET_EVOLUTION
packet(0x09fc,6); // ZC_PET_EVOLUTION_RESULT
packet(0x09fd,-1); // ZC_NOTIFY_MOVEENTRY11
packet(0x09fe,-1); // ZC_NOTIFY_NEWENTRY11
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index d152ffd2a..bcdf1061a 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -1762,6 +1762,18 @@ struct PACKET_ZC_STYLE_CHANGE_RES {
int8 flag;
} __attribute__((packed));
+struct pet_evolution_items {
+ int16 index;
+ int16 amount;
+} __attribute__((packed));
+
+struct PACKET_CZ_PET_EVOLUTION {
+ int16 PacketType;
+ uint16 PacketLength;
+ int16 EvolvedPetEggID;
+ // struct pet_evolution_items items[];
+} __attribute__((packed));
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris
diff --git a/src/map/pet.c b/src/map/pet.c
index 4bac79dc8..58c26d1ce 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -85,8 +85,21 @@ void pet_set_intimate(struct pet_data *pd, int value)
sd = pd->msd;
pd->pet.intimate = value;
+
if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) )
status_calc_pc(sd,SCO_NONE);
+
+ /* Pet is lost, delete the egg */
+ if (value <= 0) {
+ int i;
+
+ ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].card[0] == CARD0_PET &&
+ pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if (i != MAX_INVENTORY) {
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG);
+ }
+ }
}
int pet_create_egg(struct map_session_data *sd, int item_id)
@@ -233,6 +246,13 @@ int pet_hungry(int tid, int64 tick, int id, intptr_t data) {
return 1; //You lost the pet already, the rest is irrelevant.
pd->pet.hungry--;
+ /* Pet Autofeed */
+ if (battle_config.feature_enable_homun_autofeed != 0) {
+ if (pd->petDB->autofeed == 1 && pd->pet.autofeed == 1 && pd->pet.hungry <= 25) {
+ pet->food(sd, pd);
+ }
+ }
+
if( pd->pet.hungry < 0 )
{
pet_stop_attack(pd);
@@ -311,23 +331,21 @@ int pet_performance(struct map_session_data *sd, struct pet_data *pd)
int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
{
- struct item tmp_item;
- int flag;
+ int i;
nullpo_retr(1, sd);
nullpo_retr(1, pd);
pet->lootitem_drop(pd,sd);
- memset(&tmp_item,0,sizeof(tmp_item));
- tmp_item.nameid = pd->petDB->EggID;
- tmp_item.identify = 1;
- tmp_item.card[0] = CARD0_PET;
- tmp_item.card[1] = GetWord(pd->pet.pet_id,0);
- tmp_item.card[2] = GetWord(pd->pet.pet_id,1);
- tmp_item.card[3] = pd->pet.rename_flag;
- if((flag = pc->additem(sd,&tmp_item,1,LOG_TYPE_EGG))) {
- clif->additem(sd,0,0,flag);
- map->addflooritem(&sd->bl, &tmp_item, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
+
+ // Pet Evolution
+ ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].card[0] == CARD0_PET &&
+ pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if (i != MAX_INVENTORY) {
+ sd->status.inventory[i].identify = 1;
+ sd->status.inventory[i].bound = IBT_NONE;
}
+
pd->pet.incubate = 1;
unit->free(&pd->bl,CLR_OUTSIGHT);
@@ -462,19 +480,23 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag) {
}
if(p->incubate == 1) {
int i;
- //Delete egg from inventory. [Skotlex]
- for (i = 0; i < MAX_INVENTORY; i++) {
- if(sd->status.inventory[i].card[0] == CARD0_PET &&
- p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]))
- break;
- }
- if(i >= MAX_INVENTORY) {
+ // Get Egg Index
+ ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].card[0] == CARD0_PET &&
+ p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if(i == MAX_INVENTORY) {
ShowError("pet_recv_petdata: Hatching pet (%d:%s) aborted, couldn't find egg in inventory for removal!\n",p->pet_id, p->name);
sd->status.pet_id = 0;
return 1;
}
- if (!pet->birth_process(sd,p)) //Pet hatched. Delete egg.
- pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG);
+
+
+ if (!pet->birth_process(sd,p)) {
+ // Pet Evolution, Hide the egg by setting identify to 0 [Dastgir/Hercules]
+ sd->status.inventory[i].identify = 0;
+ // bind the egg to the character to avoid moving it via forged packets [Asheraf]
+ sd->status.inventory[i].bound = IBT_CHARACTER;
+ }
} else {
pet->data_init(sd,p);
if(sd->pd && sd->bl.prev != NULL) {
@@ -1359,6 +1381,14 @@ int pet_read_db_sub(struct config_setting_t *it, int n, const char *source)
if (libconfig->setting_lookup_int(it, "ChangeTargetRate", &i32))
pet->db[n].change_target_rate = i32;
+ // Pet Evolution
+ if ((t = libconfig->setting_get_member(it, "Evolve")) && config_setting_is_group(t)) {
+ pet->read_db_sub_evolution(t, n);
+ }
+
+ if ((t = libconfig->setting_get_member(it, "AutoFeed")) && (i32 = libconfig->setting_get_bool(t)))
+ pet->db[n].autofeed = i32;
+
if (libconfig->setting_lookup_string(it, "PetScript", &str))
pet->db[n].pet_script = *str ? script->parse(str, source, -pet->db[n].class_, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
@@ -1368,6 +1398,81 @@ int pet_read_db_sub(struct config_setting_t *it, int n, const char *source)
return pet->db[n].class_;
}
+/**
+ * Read Pet Evolution Database [Dastgir/Hercules]
+ * @param t libconfig setting
+ * @param n Pet DB Index
+ */
+void pet_read_db_sub_evolution(struct config_setting_t *t, int n)
+{
+ struct config_setting_t *pett;
+ int i = 0;
+ const char *str = NULL;
+
+ nullpo_retv(t);
+ Assert_retv(n >= 0 && n < MAX_PET_DB);
+
+ VECTOR_INIT(pet->db[n].evolve_data);
+
+ while ((pett = libconfig->setting_get_elem(t, i))) {
+ if (config_setting_is_group(pett)) {
+ struct pet_evolve_data ped;
+ struct item_data *data;
+ struct config_setting_t *item;
+ int j = 0, i32 = 0;
+
+ str = config_setting_name(pett);
+
+ if (!(data = itemdb->name2id(str))) {
+ ShowWarning("pet_read_evolve_db_sub: Invalid Egg '%s' in Pet #%d, skipping.\n", str, pet->db[n].class_);
+ return;
+ } else {
+ ped.petEggId = data->nameid;
+ }
+
+ VECTOR_INIT(ped.items);
+
+ while ((item = libconfig->setting_get_elem(pett, j))) {
+ struct itemlist_entry list = { 0 };
+ int quantity = 0;
+
+ str = config_setting_name(item);
+ data = itemdb->search_name(str);
+
+ if (!data) {
+ ShowWarning("pet_read_evolve_db_sub: required item %s not found in egg %d\n", str, ped.petEggId);
+ j++;
+ continue;
+ }
+
+ list.id = data->nameid;
+
+ if (mob->get_const(item, &i32) && i32 >= 0) {
+ quantity = i32;
+ }
+
+ if (quantity <= 0) {
+ ShowWarning("pet_read_evolve_db_sub: invalid quantity %d for egg %d\n", quantity, ped.petEggId);
+ j++;
+ continue;
+ }
+
+ list.amount = quantity;
+
+ VECTOR_ENSURE(ped.items, 1, 1);
+ VECTOR_PUSH(ped.items, list);
+
+ j++;
+
+ }
+
+ VECTOR_ENSURE(pet->db[n].evolve_data, 1, 1);
+ VECTOR_PUSH(pet->db[n].evolve_data, ped);
+ }
+ i++;
+ }
+}
+
bool pet_read_db_sub_intimacy(int idx, struct config_setting_t *t)
{
int i32 = 0;
@@ -1396,6 +1501,7 @@ void pet_read_db_clear(void)
// Remove any previous scripts in case reloaddb was invoked.
for (i = 0; i < MAX_PET_DB; i++) {
+ int j;
if (pet->db[i].pet_script) {
script->free_code(pet->db[i].pet_script);
pet->db[i].pet_script = NULL;
@@ -1404,6 +1510,11 @@ void pet_read_db_clear(void)
script->free_code(pet->db[i].equip_script);
pet->db[i].equip_script = NULL;
}
+
+ for (j = 0; j < VECTOR_LENGTH(pet->db[i].evolve_data); j++) {
+ VECTOR_CLEAR(VECTOR_INDEX(pet->db[i].evolve_data, j).items);
+ }
+ VECTOR_CLEAR(pet->db[i].evolve_data);
}
memset(pet->db, 0, sizeof(pet->db));
return;
@@ -1437,6 +1548,7 @@ int do_final_pet(void)
int i;
for( i = 0; i < MAX_PET_DB; i++ )
{
+ int j;
if( pet->db[i].pet_script )
{
script->free_code(pet->db[i].pet_script);
@@ -1447,9 +1559,16 @@ int do_final_pet(void)
script->free_code(pet->db[i].equip_script);
pet->db[i].equip_script = NULL;
}
+
+ /* Pet Evolution [Dastgir/Hercules] */
+ for (j = 0; j < VECTOR_LENGTH(pet->db[i].evolve_data); j++) {
+ VECTOR_CLEAR(VECTOR_INDEX(pet->db[i].evolve_data, j).items);
+ }
+ VECTOR_CLEAR(pet->db[i].evolve_data);
}
ers_destroy(pet->item_drop_ers);
ers_destroy(pet->item_drop_list_ers);
+
return 0;
}
void pet_defaults(void) {
@@ -1503,4 +1622,6 @@ void pet_defaults(void) {
pet->read_db_sub = pet_read_db_sub;
pet->read_db_sub_intimacy = pet_read_db_sub_intimacy;
pet->read_db_clear = pet_read_db_clear;
+
+ pet->read_db_sub_evolution = pet_read_db_sub_evolution;
}
diff --git a/src/map/pet.h b/src/map/pet.h
index d341be97c..b3a16c5d7 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -30,6 +30,12 @@
#define MAX_PET_DB 300
#define MAX_PETLOOT_SIZE 30
+/** Pet Evolution [Dastgir/Hercules] */
+struct pet_evolve_data {
+ int petEggId;
+ VECTOR_DECL(struct itemlist_entry) items;
+};
+
struct s_pet_db {
short class_;
char name[NAME_LENGTH],jname[NAME_LENGTH];
@@ -50,8 +56,12 @@ struct s_pet_db {
int attack_rate;
int defence_attack_rate;
int change_target_rate;
+ int autofeed;
struct script_code *equip_script;
struct script_code *pet_script;
+
+ /* Pet Evolution */
+ VECTOR_DECL(struct pet_evolve_data) evolve_data;
};
enum { PET_CLASS,PET_CATCH,PET_EGG,PET_EQUIP,PET_FOOD };
@@ -127,6 +137,7 @@ struct pet_interface {
struct s_pet_db db[MAX_PET_DB];
struct eri *item_drop_ers; //For loot drops delay structures.
struct eri *item_drop_list_ers;
+
/* */
int (*init) (bool minimal);
int (*final) (void);
@@ -172,6 +183,10 @@ struct pet_interface {
int (*read_db_sub) (struct config_setting_t *it, int n, const char *source);
bool (*read_db_sub_intimacy) (int idx, struct config_setting_t *t);
void (*read_db_clear) (void);
+
+ /* Pet Evolution [Dastgir/Hercules] */
+ void (*read_db_sub_evolution) (struct config_setting_t *t, int n);
+
};
#ifdef HERCULES_CORE
diff --git a/src/map/script.c b/src/map/script.c
index 410a707f1..952496486 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -1428,8 +1428,8 @@ const char* script_parse_subexpr(const char* p,int limit)
p=script->skip_space(p);
while((
(op=C_OP3, opl=0, len=1,*p=='?') // ?:
- || (op=C_ADD, opl=9, len=1,*p=='+') // +
- || (op=C_SUB, opl=9, len=1,*p=='-') // -
+ || (op=C_ADD, opl=9, len=1,*p=='+' && p[1]!='+') // +
+ || (op=C_SUB, opl=9, len=1,*p=='-' && p[1]!='-') // -
|| (op=C_POW, opl=11,len=2,*p=='*' && p[1]=='*') // **
|| (op=C_MUL, opl=10,len=1,*p=='*') // *
|| (op=C_DIV, opl=10,len=1,*p=='/') // /
@@ -8597,7 +8597,8 @@ BUILDIN(disableitemuse)
* return the basic stats of sd
* chk pc->readparam for available type
*------------------------------------------*/
-BUILDIN(readparam) {
+BUILDIN(readparam)
+{
int type;
struct map_session_data *sd;
struct script_data *data = script_getdata(st, 2);
@@ -8609,7 +8610,11 @@ BUILDIN(readparam) {
}
if (script_hasdata(st, 3)) {
- sd = script->nick2sd(st, script_getstr(st, 3));
+ if (script_isstringtype(st, 3)) {
+ sd = script->nick2sd(st, script_getstr(st, 3));
+ } else {
+ sd = script->id2sd(st, script_getnum(st, 3));
+ }
} else {
sd = script->rid2sd(st);
}
@@ -8623,6 +8628,43 @@ BUILDIN(readparam) {
return true;
}
+BUILDIN(setparam)
+{
+ int type;
+ struct map_session_data *sd;
+ struct script_data *data = script_getdata(st, 2);
+ int val = script_getnum(st, 3);
+
+ if (data_isreference(data) && reference_toparam(data)) {
+ type = reference_getparamtype(data);
+ } else {
+ type = script->conv_num(st, data);
+ }
+
+ if (script_hasdata(st, 4)) {
+ if (script_isstringtype(st, 4)) {
+ sd = script->nick2sd(st, script_getstr(st, 4));
+ } else {
+ sd = script->id2sd(st, script_getnum(st, 4));
+ }
+ } else {
+ sd = script->rid2sd(st);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return true;
+ }
+
+ if (pc->setparam(sd, type, val) == 0) {
+ script_pushint(st, 0);
+ return false;
+ }
+
+ script_pushint(st, 1);
+ return true;
+}
+
/*==========================================
* Return charid identification
* return by @num :
@@ -21160,6 +21202,7 @@ BUILDIN(instance_create)
const char *name;
int owner_id, res;
int type = IOT_PARTY;
+ struct map_session_data *sd = map->id2sd(st->rid);
name = script_getstr(st, 2);
owner_id = script_getnum(st, 3);
@@ -21172,22 +21215,43 @@ BUILDIN(instance_create)
}
res = instance->create(owner_id, name, (enum instance_owner_type) type);
- if( res == -4 ) { // Already exists
- script_pushint(st, -1);
- return true;
- } else if( res < 0 ) {
+ if (sd != NULL) {
+ switch (res) {
+ case -4: // Already exists
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_DUPLICATE, name);
+ break;
+ case -3: // No free instances
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_EXIST, name);
+ break;
+ case -2: // Invalid type
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_RIGHT, name);
+ break;
+ case -1: // Unknown
+ clif->msgtable_str(sd, MSG_MDUNGEON_SUBSCRIPTION_ERROR_UNKNOWN, name);
+ break;
+ default:
+ if (res < 0)
+ ShowError("buildin_instance_create: failed to unknown reason [%d].\n", res);
+ }
+ } else {
const char *err;
- switch(res) {
- case -3: err = "No free instances"; break;
- case -2: err = "Invalid party ID"; break;
- case -1: err = "Invalid type"; break;
- default: err = "Unknown"; break;
+ switch (res) {
+ case -3:
+ err = "No free instances";
+ break;
+ case -2:
+ err = "Invalid party ID";
+ break;
+ case -1:
+ err = "Invalid type";
+ break;
+ default:
+ err = "Unknown";
+ break;
}
- ShowError("buildin_instance_create: %s [%d].\n", err, res);
- script_pushint(st, -2);
- return true;
+ if (res < 0)
+ ShowError("buildin_instance_create: %s [%d].\n", err, res);
}
-
script_pushint(st, res);
return true;
}
@@ -23860,7 +23924,7 @@ bool rodex_sendmail_sub(struct script_state* st, struct rodex_message *msg)
{
const char *sender_name, *title, *body;
- if (!strcmp(script->getfuncname(st), "rodex_sendmail_acc2"))
+ if (strcmp(script->getfuncname(st), "rodex_sendmail_acc") == 0 || strcmp(script->getfuncname(st), "rodex_sendmail_acc2") == 0)
msg->receiver_accountid = script_getnum(st, 2);
else
msg->receiver_id = script_getnum(st, 2);
@@ -24390,6 +24454,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(checkweight,"vi*"),
BUILDIN_DEF(checkweight2,"rr"),
BUILDIN_DEF(readparam,"i?"),
+ BUILDIN_DEF(setparam,"ii?"),
BUILDIN_DEF(getcharid,"i?"),
BUILDIN_DEF(getnpcid,"i?"),
BUILDIN_DEF(getpartyname,"i"),
diff --git a/src/map/skill.c b/src/map/skill.c
index 6eacde897..34c36d7f3 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -15027,8 +15027,9 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
}
break;
default:
- skill->check_condition_castend_unknown(sd, &skill_id, &skill_lv);
- break;
+ if (!skill->check_condition_castend_unknown(sd, &skill_id, &skill_lv))
+ break;
+ return 0;
}
st = &sd->battle_status;
@@ -15115,8 +15116,9 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
return 1;
}
-void skill_check_condition_castend_unknown(struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv)
+bool skill_check_condition_castend_unknown(struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv)
{
+ return false;
}
// type&2: consume items (after skill was used)
diff --git a/src/map/skill.h b/src/map/skill.h
index e16094eae..bd1dc3344 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -2172,7 +2172,7 @@ struct skill_interface {
int (*check_condition_castbegin_mount_unknown) (struct status_change *sc, uint16 *skill_id);
int (*check_condition_castbegin_madogear_unknown) (struct status_change *sc, uint16 *skill_id);
int (*check_condition_castbegin_unknown) (struct status_change *sc, uint16 *skill_id);
- void (*check_condition_castend_unknown) (struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv);
+ bool (*check_condition_castend_unknown) (struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv);
bool (*get_requirement_off_unknown) (struct status_change *sc, uint16 *skill_id);
bool (*get_requirement_item_unknown) (struct status_change *sc, struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv, uint16 *idx, int *i);
void (*get_requirement_unknown) (struct status_change *sc, struct map_session_data* sd, uint16 *skill_id, uint16 *skill_lv, struct skill_condition *req);
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 7c609f0bf..6d184d082 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -1266,8 +1266,8 @@ typedef void (*HPMHOOK_pre_clif_feel_hate_reset) (struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_feel_hate_reset) (struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_partytickack) (struct map_session_data **sd, bool *flag);
typedef void (*HPMHOOK_post_clif_partytickack) (struct map_session_data *sd, bool flag);
-typedef void (*HPMHOOK_pre_clif_zc_config) (struct map_session_data **sd, int *type, int *flag);
-typedef void (*HPMHOOK_post_clif_zc_config) (struct map_session_data *sd, int type, int flag);
+typedef void (*HPMHOOK_pre_clif_zc_config) (struct map_session_data **sd, enum CZ_CONFIG *type, int *flag);
+typedef void (*HPMHOOK_post_clif_zc_config) (struct map_session_data *sd, enum CZ_CONFIG type, int flag);
typedef void (*HPMHOOK_pre_clif_viewequip_ack) (struct map_session_data **sd, struct map_session_data **tsd);
typedef void (*HPMHOOK_post_clif_viewequip_ack) (struct map_session_data *sd, struct map_session_data *tsd);
typedef void (*HPMHOOK_pre_clif_equpcheckbox) (struct map_session_data **sd);
@@ -2450,6 +2450,10 @@ typedef void (*HPMHOOK_pre_clif_cz_req_style_change_sub) (struct map_session_dat
typedef void (*HPMHOOK_post_clif_cz_req_style_change_sub) (struct map_session_data *sd, int type, int16 idx, bool isitem);
typedef void (*HPMHOOK_pre_clif_style_change_response) (struct map_session_data **sd, enum stylist_shop *flag);
typedef void (*HPMHOOK_post_clif_style_change_response) (struct map_session_data *sd, enum stylist_shop flag);
+typedef void (*HPMHOOK_pre_clif_pPetEvolution) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pPetEvolution) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_petEvolutionResult) (int *fd, enum pet_evolution_result *result);
+typedef void (*HPMHOOK_post_clif_petEvolutionResult) (int fd, enum pet_evolution_result result);
#endif // MAP_CLIF_H
#ifdef COMMON_CORE_H /* cmdline */
typedef void (*HPMHOOK_pre_cmdline_init) (void);
@@ -6110,6 +6114,8 @@ typedef bool (*HPMHOOK_pre_pet_read_db_sub_intimacy) (int *idx, struct config_se
typedef bool (*HPMHOOK_post_pet_read_db_sub_intimacy) (bool retVal___, int idx, struct config_setting_t *t);
typedef void (*HPMHOOK_pre_pet_read_db_clear) (void);
typedef void (*HPMHOOK_post_pet_read_db_clear) (void);
+typedef void (*HPMHOOK_pre_pet_read_db_sub_evolution) (struct config_setting_t **t, int *n);
+typedef void (*HPMHOOK_post_pet_read_db_sub_evolution) (struct config_setting_t *t, int n);
#endif // MAP_PET_H
#ifdef CHAR_PINCODE_H /* pincode */
typedef void (*HPMHOOK_pre_pincode_handle) (int *fd, struct char_session_data **sd);
@@ -7102,8 +7108,8 @@ typedef int (*HPMHOOK_pre_skill_check_condition_castbegin_madogear_unknown) (str
typedef int (*HPMHOOK_post_skill_check_condition_castbegin_madogear_unknown) (int retVal___, struct status_change *sc, uint16 *skill_id);
typedef int (*HPMHOOK_pre_skill_check_condition_castbegin_unknown) (struct status_change **sc, uint16 **skill_id);
typedef int (*HPMHOOK_post_skill_check_condition_castbegin_unknown) (int retVal___, struct status_change *sc, uint16 *skill_id);
-typedef void (*HPMHOOK_pre_skill_check_condition_castend_unknown) (struct map_session_data **sd, uint16 **skill_id, uint16 **skill_lv);
-typedef void (*HPMHOOK_post_skill_check_condition_castend_unknown) (struct map_session_data *sd, uint16 *skill_id, uint16 *skill_lv);
+typedef bool (*HPMHOOK_pre_skill_check_condition_castend_unknown) (struct map_session_data **sd, uint16 **skill_id, uint16 **skill_lv);
+typedef bool (*HPMHOOK_post_skill_check_condition_castend_unknown) (bool retVal___, struct map_session_data *sd, uint16 *skill_id, uint16 *skill_lv);
typedef bool (*HPMHOOK_pre_skill_get_requirement_off_unknown) (struct status_change **sc, uint16 **skill_id);
typedef bool (*HPMHOOK_post_skill_get_requirement_off_unknown) (bool retVal___, struct status_change *sc, uint16 *skill_id);
typedef bool (*HPMHOOK_pre_skill_get_requirement_item_unknown) (struct status_change **sc, struct map_session_data **sd, uint16 **skill_id, uint16 **skill_lv, uint16 **idx, int **i);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index d17955db7..671a9cb5c 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -2046,6 +2046,10 @@ struct {
struct HPMHookPoint *HP_clif_cz_req_style_change_sub_post;
struct HPMHookPoint *HP_clif_style_change_response_pre;
struct HPMHookPoint *HP_clif_style_change_response_post;
+ struct HPMHookPoint *HP_clif_pPetEvolution_pre;
+ struct HPMHookPoint *HP_clif_pPetEvolution_post;
+ struct HPMHookPoint *HP_clif_petEvolutionResult_pre;
+ struct HPMHookPoint *HP_clif_petEvolutionResult_post;
struct HPMHookPoint *HP_cmdline_init_pre;
struct HPMHookPoint *HP_cmdline_init_post;
struct HPMHookPoint *HP_cmdline_final_pre;
@@ -4762,6 +4766,8 @@ struct {
struct HPMHookPoint *HP_pet_read_db_sub_intimacy_post;
struct HPMHookPoint *HP_pet_read_db_clear_pre;
struct HPMHookPoint *HP_pet_read_db_clear_post;
+ struct HPMHookPoint *HP_pet_read_db_sub_evolution_pre;
+ struct HPMHookPoint *HP_pet_read_db_sub_evolution_post;
struct HPMHookPoint *HP_quest_init_pre;
struct HPMHookPoint *HP_quest_init_post;
struct HPMHookPoint *HP_quest_final_pre;
@@ -8421,6 +8427,10 @@ struct {
int HP_clif_cz_req_style_change_sub_post;
int HP_clif_style_change_response_pre;
int HP_clif_style_change_response_post;
+ int HP_clif_pPetEvolution_pre;
+ int HP_clif_pPetEvolution_post;
+ int HP_clif_petEvolutionResult_pre;
+ int HP_clif_petEvolutionResult_post;
int HP_cmdline_init_pre;
int HP_cmdline_init_post;
int HP_cmdline_final_pre;
@@ -11137,6 +11147,8 @@ struct {
int HP_pet_read_db_sub_intimacy_post;
int HP_pet_read_db_clear_pre;
int HP_pet_read_db_clear_post;
+ int HP_pet_read_db_sub_evolution_pre;
+ int HP_pet_read_db_sub_evolution_post;
int HP_quest_init_pre;
int HP_quest_init_post;
int HP_quest_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index c9463b1b8..942693da8 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1046,6 +1046,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->pReqStyleChange, HP_clif_pReqStyleChange) },
{ HP_POP(clif->cz_req_style_change_sub, HP_clif_cz_req_style_change_sub) },
{ HP_POP(clif->style_change_response, HP_clif_style_change_response) },
+ { HP_POP(clif->pPetEvolution, HP_clif_pPetEvolution) },
+ { HP_POP(clif->petEvolutionResult, HP_clif_petEvolutionResult) },
/* cmdline_interface */
{ HP_POP(cmdline->init, HP_cmdline_init) },
{ HP_POP(cmdline->final, HP_cmdline_final) },
@@ -2439,6 +2441,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pet->read_db_sub, HP_pet_read_db_sub) },
{ HP_POP(pet->read_db_sub_intimacy, HP_pet_read_db_sub_intimacy) },
{ HP_POP(pet->read_db_clear, HP_pet_read_db_clear) },
+ { HP_POP(pet->read_db_sub_evolution, HP_pet_read_db_sub_evolution) },
/* quest_interface */
{ HP_POP(quest->init, HP_quest_init) },
{ HP_POP(quest->final, HP_quest_final) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index bd2ef870f..5cd54ba22 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -11221,10 +11221,10 @@ void HP_clif_partytickack(struct map_session_data *sd, bool flag) {
}
return;
}
-void HP_clif_zc_config(struct map_session_data *sd, int type, int flag) {
+void HP_clif_zc_config(struct map_session_data *sd, enum CZ_CONFIG type, int flag) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_zc_config_pre > 0) {
- void (*preHookFunc) (struct map_session_data **sd, int *type, int *flag);
+ void (*preHookFunc) (struct map_session_data **sd, enum CZ_CONFIG *type, int *flag);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_zc_config_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_clif_zc_config_pre[hIndex].func;
@@ -11239,7 +11239,7 @@ void HP_clif_zc_config(struct map_session_data *sd, int type, int flag) {
HPMHooks.source.clif.zc_config(sd, type, flag);
}
if (HPMHooks.count.HP_clif_zc_config_post > 0) {
- void (*postHookFunc) (struct map_session_data *sd, int type, int flag);
+ void (*postHookFunc) (struct map_session_data *sd, enum CZ_CONFIG type, int flag);
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_zc_config_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_clif_zc_config_post[hIndex].func;
postHookFunc(sd, type, flag);
@@ -26649,6 +26649,58 @@ void HP_clif_style_change_response(struct map_session_data *sd, enum stylist_sho
}
return;
}
+void HP_clif_pPetEvolution(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_pPetEvolution_pre > 0) {
+ void (*preHookFunc) (int *fd, struct map_session_data **sd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pPetEvolution_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pPetEvolution_pre[hIndex].func;
+ preHookFunc(&fd, &sd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pPetEvolution(fd, sd);
+ }
+ if (HPMHooks.count.HP_clif_pPetEvolution_post > 0) {
+ void (*postHookFunc) (int fd, struct map_session_data *sd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pPetEvolution_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pPetEvolution_post[hIndex].func;
+ postHookFunc(fd, sd);
+ }
+ }
+ return;
+}
+void HP_clif_petEvolutionResult(int fd, enum pet_evolution_result result) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_petEvolutionResult_pre > 0) {
+ void (*preHookFunc) (int *fd, enum pet_evolution_result *result);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_petEvolutionResult_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_petEvolutionResult_pre[hIndex].func;
+ preHookFunc(&fd, &result);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.petEvolutionResult(fd, result);
+ }
+ if (HPMHooks.count.HP_clif_petEvolutionResult_post > 0) {
+ void (*postHookFunc) (int fd, enum pet_evolution_result result);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_petEvolutionResult_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_petEvolutionResult_post[hIndex].func;
+ postHookFunc(fd, result);
+ }
+ }
+ return;
+}
/* cmdline_interface */
void HP_cmdline_init(void) {
int hIndex = 0;
@@ -63447,6 +63499,32 @@ void HP_pet_read_db_clear(void) {
}
return;
}
+void HP_pet_read_db_sub_evolution(struct config_setting_t *t, int n) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_pet_read_db_sub_evolution_pre > 0) {
+ void (*preHookFunc) (struct config_setting_t **t, int *n);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_sub_evolution_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_pet_read_db_sub_evolution_pre[hIndex].func;
+ preHookFunc(&t, &n);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.pet.read_db_sub_evolution(t, n);
+ }
+ if (HPMHooks.count.HP_pet_read_db_sub_evolution_post > 0) {
+ void (*postHookFunc) (struct config_setting_t *t, int n);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_read_db_sub_evolution_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_pet_read_db_sub_evolution_post[hIndex].func;
+ postHookFunc(t, n);
+ }
+ }
+ return;
+}
/* quest_interface */
void HP_quest_init(bool minimal) {
int hIndex = 0;
@@ -76386,31 +76464,32 @@ int HP_skill_check_condition_castbegin_unknown(struct status_change *sc, uint16
}
return retVal___;
}
-void HP_skill_check_condition_castend_unknown(struct map_session_data *sd, uint16 *skill_id, uint16 *skill_lv) {
+bool HP_skill_check_condition_castend_unknown(struct map_session_data *sd, uint16 *skill_id, uint16 *skill_lv) {
int hIndex = 0;
+ bool retVal___ = false;
if (HPMHooks.count.HP_skill_check_condition_castend_unknown_pre > 0) {
- void (*preHookFunc) (struct map_session_data **sd, uint16 **skill_id, uint16 **skill_lv);
+ bool (*preHookFunc) (struct map_session_data **sd, uint16 **skill_id, uint16 **skill_lv);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_check_condition_castend_unknown_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_skill_check_condition_castend_unknown_pre[hIndex].func;
- preHookFunc(&sd, &skill_id, &skill_lv);
+ retVal___ = preHookFunc(&sd, &skill_id, &skill_lv);
}
if (*HPMforce_return) {
*HPMforce_return = false;
- return;
+ return retVal___;
}
}
{
- HPMHooks.source.skill.check_condition_castend_unknown(sd, skill_id, skill_lv);
+ retVal___ = HPMHooks.source.skill.check_condition_castend_unknown(sd, skill_id, skill_lv);
}
if (HPMHooks.count.HP_skill_check_condition_castend_unknown_post > 0) {
- void (*postHookFunc) (struct map_session_data *sd, uint16 *skill_id, uint16 *skill_lv);
+ bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, uint16 *skill_id, uint16 *skill_lv);
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_check_condition_castend_unknown_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_skill_check_condition_castend_unknown_post[hIndex].func;
- postHookFunc(sd, skill_id, skill_lv);
+ retVal___ = postHookFunc(retVal___, sd, skill_id, skill_lv);
}
}
- return;
+ return retVal___;
}
bool HP_skill_get_requirement_off_unknown(struct status_change *sc, uint16 *skill_id) {
int hIndex = 0;
diff --git a/tools/petevolutionconverter.py b/tools/petevolutionconverter.py
new file mode 100644
index 000000000..0ccc71314
--- /dev/null
+++ b/tools/petevolutionconverter.py
@@ -0,0 +1,248 @@
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+#
+# This file is part of Hercules.
+# http://herc.ws - http://github.com/HerculesWS/Hercules
+#
+# Copyright (C) 2018 Hercules Dev Team
+# Copyright (C) 2018 Dastgir
+#
+# 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/>.
+#
+# Usage:
+# python petevolutionconverter.py PetEvolutionCln.lub re ../ > pet_evolve_db.conf
+
+import re
+import sys
+import utils.common as Tools
+
+def printHeader():
+ print('''//================= Hercules Database =====================================
+//= _ _ _
+//= | | | | | |
+//= | |_| | ___ _ __ ___ _ _| | ___ ___
+//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __|
+//= | | | | __/ | | (__| |_| | | __/\__ \
+//= \_| |_/\___|_| \___|\__,_|_|\___||___/
+//================= License ===============================================
+//= This file is part of Hercules.
+//= http://herc.ws - http://github.com/HerculesWS/Hercules
+//=
+//= Copyright (C) 2018 Hercules Dev Team
+//=
+//= Hercules is free software: you can redistribute it and/or modify
+//= it under the terms of the GNU General Public License as published by
+//= the Free Software Foundation, either version 3 of the License, or
+//= (at your option) any later version.
+//=
+//= This program is distributed in the hope that it will be useful,
+//= but WITHOUT ANY WARRANTY; without even the implied warranty of
+//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//= GNU General Public License for more details.
+//=
+//= You should have received a copy of the GNU General Public License
+//= along with this program. If not, see <http://www.gnu.org/licenses/>.
+//=========================================================================
+//= Pets Database
+//=========================================================================
+
+pet_db:(
+/**************************************************************************
+ ************* Entry structure ********************************************
+ **************************************************************************
+{
+ // ================ Mandatory fields ==============================
+ Id: ID (int)
+ SpriteName: "Sprite_Name" (string)
+ Name: "Pet Name" (string)
+ // ================ Optional fields ===============================
+ TamingItem: Taming Item (string, defaults to 0)
+ EggItem: Egg Id (string, defaults to 0)
+ AccessoryItem: Equipment Id (string, defaults to 0)
+ FoodItem: Food Id (string, defaults to 0)
+ FoodEffectiveness: hunger points (int, defaults to 0)
+ HungerDelay: hunger time (int, defaults to 0)
+ Intimacy: {
+ Initial: start intimacy (int, defaults to 0)
+ FeedIncrement: feeding intimacy (int, defaults to 0)
+ OverFeedDecrement: overfeeding intimacy (int, defaults to 0)
+ OwnerDeathDecrement: owner die intimacy (int, defaults to 0)
+ }
+ CaptureRate: capture rate (int, defaults to 0)
+ Speed: speed (int, defaults to 0)
+ SpecialPerformance: true/false (boolean, defaults to false)
+ TalkWithEmotes: convert talk (boolean, defaults to false)
+ AttackRate: attack rate (int, defaults to 0)
+ DefendRate: Defence attack (int, defaults to 0)
+ ChangeTargetRate: change target (int, defaults to 0)
+ Evolve: {
+ EggID: { (string, Evolved Pet EggID)
+ Name: Amount (items required to perform evolution)
+ ...
+ }
+ }
+ AutoFeed: true/false (boolean, defaults to false)
+ PetScript: <" Pet Script (can also be multi-line) ">
+ EquipScript: <" Equip Script (can also be multi-line) ">
+},
+**************************************************************************/''')
+
+def printID(db, name, tabSize = 1):
+ if (name not in db or int(db[name]) == 0):
+ return
+ print('{}{}: {}'.format('\t'*tabSize, name, db[name]))
+
+def printString(db, name, tabSize = 1):
+ if (name not in db or db[name].strip() == ""):
+ return
+ print('{}{}: "{}"'.format('\t'*tabSize, name, db[name]))
+
+def printBool(db, name):
+ if (name not in db or db[name] == '0'):
+ return
+ print('\t{}: true'.format(name))
+
+def printScript(db, name):
+ if (name not in db or db[name].strip() == ""):
+ return
+ print('\t{}: <{}>'.format(name, db[name]))
+
+def printEntry(ItemDB, EvolveDB, autoFeedDB, entry, mode, serverpath):
+ PetDB = Tools.LoadDB('pet_db', mode, serverpath)
+
+ for i, db in enumerate(PetDB):
+ print('{')
+ printID(db, 'Id')
+ printString(db, 'SpriteName')
+ printString(db, 'Name')
+
+ printString(db, 'TamingItem')
+ printString(db, 'EggItem')
+ printString(db, 'AccessoryItem')
+ printString(db, 'FoodItem')
+ printID(db, 'FoodEffectiveness')
+ printID(db, 'HungerDelay')
+
+ if ('Intimacy' in db and (db['Intimacy']['Initial'] != 0 or db['Intimacy']['FeedIncrement'] != 0 or
+ db['Intimacy']['OverFeedDecrement'] != 0 or db['Intimacy']['OwnerDeathDecrement'] != 0)):
+ print('\tIntimacy: {')
+ printID(db['Intimacy'], 'Initial', 2)
+ printID(db['Intimacy'], 'FeedIncrement', 2)
+ printID(db['Intimacy'], 'OverFeedDecrement', 2)
+ printID(db['Intimacy'], 'OwnerDeathDecrement', 2)
+ print('\t}')
+ #
+ printID(db, 'CaptureRate')
+ printID(db, 'Speed')
+ printBool(db, 'SpecialPerformance')
+ printBool(db, 'TalkWithEmotes')
+ printID(db, 'AttackRate')
+ printID(db, 'DefendRate')
+ printID(db, 'ChangeTargetRate')
+ if (str(db['Id']) in autoFeedDB):
+ print('\tAutoFeed: true')
+ else:
+ print('\tAutoFeed: false')
+ printScript(db, 'PetScript')
+ printScript(db, 'EquipScript')
+
+ if (db['EggItem'] in EvolveDB):
+ entry = EvolveDB[db['EggItem']]
+ print('\tEvolve: {')
+
+ for evolve in entry:
+ if ('comment' in evolve):
+ print('/*')
+ print('\t\t{}: {'.format(evolve['Id']))
+
+ for items in evolve['items']:
+ print('\t\t\t{}: {}'.format(items[0], items[1]))
+
+ print('\t\t}')
+ if ('comment' in evolve):
+ print('*/')
+
+ print('\t}')
+ print('},')
+
+def saveEntry(EvolveDB, entry):
+ if (entry['from'] not in EvolveDB):
+ EvolveDB[entry['from']] = list()
+ EvolveDB[entry['from']].append(entry)
+ return EvolveDB
+
+def getItemConstant(entry, ItemDB, itemID):
+ if (itemID in ItemDB):
+ return ItemDB[itemID]
+ print(itemID, "not found", entry)
+ entry['comment'] = 1
+ return itemID
+
+def ConvertDB(luaName, mode, serverpath):
+ ItemDB = Tools.LoadDBConsts('item_db', mode, serverpath)
+ f = open(luaName)
+ content = f.read()
+ f.close()
+
+ recipeDB = re.findall(r'InsertEvolutionRecipeLGU\((\d+),\s*(\d+),\s*(\d+),\s*(\d+)\)', content)
+ autoFeedDB = re.findall(r'InsertPetAutoFeeding\((\d+)\)', content)
+
+ current = 0
+
+ entry = dict()
+ EvolveDB = dict()
+
+ printHeader()
+ for recipe in recipeDB:
+ fromEgg = getItemConstant(entry, ItemDB, int(recipe[0]))
+ petEgg = getItemConstant(entry, ItemDB, int(recipe[1]))
+
+ if (current == 0):
+ entry = {
+ 'Id': petEgg,
+ 'from': fromEgg,
+ 'items': list()
+ }
+ current = petEgg
+
+ if (current != petEgg):
+ EvolveDB = saveEntry(EvolveDB, entry)
+ entry = {
+ 'Id': petEgg,
+ 'from': fromEgg,
+ 'items': list()
+ }
+ entry['id'] = petEgg
+ entry['items'] = list()
+ current = petEgg
+
+ itemConst = getItemConstant(entry, ItemDB, int(recipe[2]))
+ quantity = int(recipe[3])
+
+ entry['items'].append((itemConst, quantity))
+ saveEntry(EvolveDB, entry)
+
+ printEntry(ItemDB, EvolveDB, autoFeedDB, entry, mode, serverpath)
+ print(')')
+
+
+if len(sys.argv) != 4:
+ print('Pet Evolution Lua to DB')
+ print('Usage:')
+ print(' petevolutionconverter.py lua mode serverpath')
+ print("example:")
+ print(' petevolutionconverter.py PetEvolutionCln.lua pre-re ../')
+ exit(1)
+
+ConvertDB(sys.argv[1], sys.argv[2], sys.argv[3])
diff --git a/tools/utils/common.py b/tools/utils/common.py
index 1a398d544..7b7811654 100644
--- a/tools/utils/common.py
+++ b/tools/utils/common.py
@@ -48,3 +48,18 @@ def LoadDBConsts(DBname, mode, serverpath):
print('LoadDBConsts: invalid database name {}'.format(DBname))
exit(1)
return consts
+
+def LoadDB(DBname, mode, serverpath):
+ filenames = [serverpath + 'db/{}/{}.conf'.format(mode, DBname)]
+
+ if os.path.isfile(serverpath + 'db/{}2.conf'.format(DBname)):
+ filenames.append(serverpath + 'db/{}2.conf'.format(DBname))
+
+ consts = dict()
+ for filename in filenames:
+ with io.open(filename) as f:
+ config = libconf.load(f)
+ db = config[DBname]
+ return db
+ print('LoadDB: invalid database name {}'.format(DBname))
+ exit(1)