diff options
38 files changed, 1914 insertions, 298 deletions
diff --git a/conf/battle/feature.conf b/conf/battle/feature.conf index 440dbb31a..37b05c657 100644 --- a/conf/battle/feature.conf +++ b/conf/battle/feature.conf @@ -18,3 +18,12 @@ feature.search_stores: on // Atcommand suggestions (Note 1) // If one type incomplete atcommand, it will suggest the complete ones. feature.atcommand_suggestions: off + +// Banking (Note 1) +// Requires: 2013-07-24aRagexe or later +feature.banking: on + +// Auction (Note 1) +// Feature became unstable on clients 2012 onwards (exact date not known), +// it has been fixed on clients 2013-05-15 onwards however. +feature.auction: off
\ No newline at end of file diff --git a/conf/inter-server.conf b/conf/inter-server.conf index 09ac15f82..db94494f1 100644 --- a/conf/inter-server.conf +++ b/conf/inter-server.conf @@ -109,6 +109,7 @@ mercenary_db: mercenary mercenary_owner_db: mercenary_owner ragsrvinfo_db: ragsrvinfo elemental_db: elemental +account_data_db: account_data // Map Database Tables item_db_db: item_db diff --git a/conf/logs.conf b/conf/logs.conf index f036cbccf..6933e84fe 100644 --- a/conf/logs.conf +++ b/conf/logs.conf @@ -25,6 +25,7 @@ // 0x02000 - (E) Log mail system transactions. // 0x04000 - (I) Log auction system transactions. // 0x08000 - (B) Log buying store transactions +// 0x20000 - (K) Log account bank transactions // 0x10000 - (X) Log all other transactions (rentals expiring/inserting cards/items removed by item_check/ // rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill) // Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059 diff --git a/conf/map-server.conf b/conf/map-server.conf index fb4614ca3..a3afde66c 100644 --- a/conf/map-server.conf +++ b/conf/map-server.conf @@ -97,11 +97,12 @@ minsave_time: 100 // 32: After successfully submitting an item for auction // 64: After successfully get/delete/complete a quest // 128: After every buying store transaction +// 256: After every bank transaction (deposit/withdraw) // NOTE: These settings decrease the chance of dupes/lost items when there's a // server crash at the expense of increasing the map/char server lag. If your // server rarely crashes, but experiences interserver lag, you may want to set // these off. -save_settings: 255 +save_settings: 511 // When @help or @h is typed when you are a gm, this is displayed for helping new gms understand gm commands. help_txt: conf/help.txt diff --git a/conf/messages.conf b/conf/messages.conf index fc8599f5b..4a08c0893 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -1519,5 +1519,12 @@ 1480: I am %s Super Novice~ 1481: Help me out~ Please~ T_T +//Banking +1482: You can't withdraw that much money +1483: Banking is disabled + +//src/map/atcommand.c::ACMD(auction) +1484: Auction is disabled + //Custom translations import: conf/import/msg_conf.txt diff --git a/db/re/item_db.txt b/db/re/item_db.txt index b4c2ca654..7385672d9 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -8011,7 +8011,6 @@ 18572,Korean_Judge_Hat,Judges Hat,5,20,,300,,2,,1,0xFFFFFFFF,63,2,256,,0,1,377,{ bonus bMdef,2; },{},{} 18573,White_Feather,White Feather,5,20,,500,,2,,1,0xFFFFFFFF,63,2,256,,30,1,741,{},{},{} 18574,Lord_of_Death,Lord of the Dead Helm,5,20,,1000,,10,,1,0xFFFFFFFF,63,2,768,,70,1,742,{ bonus bMdef,5; },{},{} -18574,Lord_of_Death,Lord of the Dead Helm,5,20,,1000,,10,,1,0xFFFFFFFF,63,2,768,,70,1,742,{ bonus bMdef,5; },{},{} 18575,Wunderkammer,Wunderkammer,5,20,,500,,10,,1,0xFFFFFFFF,7,2,769,,20,0,743,{ bonus bMdef,10; },{},{} 18576,YinYang_Earring,Yin Yang Earrings,5,20,,100,,0,,0,0xFFFFFFFF,63,2,512,,50,0,744,{},{},{} 18577,24_Bolt,Screw Stuck Head,5,20,,200,,0,,0,0xFFFFFFFF,63,2,512,,10,0,696,{},{},{} @@ -8042,7 +8041,6 @@ 18602,Watermelon_Slice,Watermelon Bite,5,20,,100,,0,,0,0xFFFFFFFF,63,2,1,,30,0,763,{ bonus bUnbreakableHelm,0; bonus bMdef,4; bonus2 bAddEle,Ele_Fire,4; },{},{} 18603,Black_Devil_Mask_,Black Devil's Mask,5,20,,100,,0,,1,0xFFFFFFFF,63,2,512,,0,0,760,{ bonus bAllStats,1; },{},{} 18604,Falcon_Mask,Falcon Mask,5,10,,30,,0,,1,0xFFFFFFFF,63,2,513,,50,0,782,{},{},{} -18604,Falcon_Mask,Falcon Mask,5,10,,30,,0,,1,0xFFFFFFFF,63,2,513,,50,0,782,{},{},{} 18605,Dark_Age,Dark Age,5,20,,200,,3,,1,0xFFFFFFFF,63,2,256,,10,1,766,{ bonus bMdef,3; },{},{} 18606,Tear_Drop,Tear drop,5,20,,100,,1,,0,0xFFFFFFFF,63,2,513,,30,0,767,{},{},{} 18607,Blush_,Blush,5,20,,100,,0,,1,0xFFFFFFFF,63,2,512,,0,0,125,{},{},{} diff --git a/doc/script_commands.txt b/doc/script_commands.txt index c0fc8ce40..756efd992 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -5655,20 +5655,46 @@ above 91000 intimacy with its owner. --------------------------------------- +*gethominfo(<type>) + +This function works as a direct counterpart of 'getpetinfo': + 0 - Homunculus unique ID + 1 - Homunculus Class + 2 - Name + 3 - Friendly level (intimacy score). 100000 is full loyalty. + 4 - Hungry level. 100 is completely full. + 5 - Rename flag. 0 means this homunculus has not been named yet. + 6 - Homunculus level + +--------------------------------------- + +*morphembryo; + +This command will try to put the invoking player's Homunculus in an +uncallable state, required for mutation into a Homunculus S. The player +will also receive a Strange Embryo (ID 6415) in their inventory if +successful, which is deleted upon mutation. + +The command will fail if the invoking player does not have an evolved +Homunculus at level 99 or above. The /swt emotion is shown upon failure. + +Returns 1 upon success and 0 for all failures. + +--------------------------------------- + *hommutate {<ID>}; -This command will try to mutate the invoking player's Homunculus into a -Homunculus S. The Strange Embryo (ID 6415) is deleted upon success. +This command will try to mutate the invoking player's Homunculus into +a Homunculus S. The Strange Embryo (ID 6415) is deleted upon success. -The command will fail if the invoking player does not have an evolved -Homunculus at level 99 or above, if it is not in the embryo state (from -the 'morphembryo' command), or if the invoking player does not possess a -Strange Embryo. The /swt emotion is shown upon failure. +The command will fail if the invoking player does not have an evolved +Homunculus at level 99 or above, if it is not in the embryo state +(from the 'morphembryo' command), or if the invoking player does not +possess a Strange Embryo. The /swt emotion is shown upon failure. -If the optional parameter <ID> is set, the invoking player's Homunculus -will change into the specified Homunculus ID. Otherwise, a random -Homunculus S will be chosen. See 'db/homunculus_db.txt' for a full list of -IDs. +If the optional parameter <ID> is set, the invoking player's Homunculus +will change into the specified Homunculus ID. Otherwise, a random Homunculus S +will be chosen. See 'db/homunculus_db.txt' for a full list of IDs. Returns 1 upon success and 0 for all failures. @@ -5685,19 +5711,6 @@ and will return the following values: --------------------------------------- -*gethominfo(<type>) - -This function works as a direct counterpart of 'getpetinfo': - 0 - Homunculus unique ID - 1 - Homunculus Class - 2 - Name - 3 - Friendly level (intimacy score). 100000 is full loyalty. - 4 - Hungry level. 100 is completely full. - 5 - Rename flag. 0 means this homunculus has not been named yet. - 6 - Homunculus level - ---------------------------------------- - *unitwalk <GID>,<x>,<y>; *unitwalk <GID>,<mapid>; diff --git a/npc/re/mobs/dungeons/dew_dun.txt b/npc/re/mobs/dungeons/dew_dun.txt index 1080a1cf1..9b8a3e8ee 100644 --- a/npc/re/mobs/dungeons/dew_dun.txt +++ b/npc/re/mobs/dungeons/dew_dun.txt @@ -3,27 +3,28 @@ //===== By: ================================================== //= Chilly //===== Current Version: ===================================== -//= 1.0 +//= 1.1 //===== Compatible With: ===================================== //= Hercules //===== Description: ========================================= //= Official kRO monster spawns //===== Additional Comments: ================================= //= 1.0 First Release +//= 1.1 Updated spawn delays. [Euphy] //============================================================ //================================================== // dew_dun01 - Volcanic Island of Krakatoa //================================================== -dew_dun01,0,0,0,0 monster Ancient Worm 1305,25,0,0,0 -dew_dun01,0,0,0,0 monster Gullinbursti 1311,10,0,0,0 -dew_dun01,0,0,0,0 monster Comodo 2152,70,0,0,0 -dew_dun01,0,0,0,0 boss_monster Leak 2156,1,7200000,600000,1 +dew_dun01,0,0,0,0 monster Comodo 2152,70,5000,0,0 +dew_dun01,0,0,0,0 monster Ancient Worm 1305,25,5000,0,0 +dew_dun01,0,0,0,0 monster Gullinbursti 1311,10,5000,0,0 +dew_dun01,0,0,0,0 boss_monster Leak 2156,1,7200000,0,1 //================================================== // dew_dun02 - Tina Grace Cave //================================================== -dew_dun02,0,0,0,0 monster Am Mut 1301,20,0,0,0 -dew_dun02,0,0,0,0 monster Gajomart 1309,30,0,0,0 -dew_dun02,0,0,0,0 monster Banaspaty 2154,50,0,0,0 -dew_dun02,0,0,0,0 monster Butoijo 2155,30,0,0,0 +dew_dun02,0,0,0,0 monster Banaspaty 2154,50,5000,0,0 +dew_dun02,0,0,0,0 monster Gajomart 1309,30,5000,0,0 +dew_dun02,0,0,0,0 monster Am Mut 1301,20,5000,0,0 +dew_dun02,0,0,0,0 monster Butoijo 2155,30,5000,0,0
\ No newline at end of file diff --git a/npc/re/mobs/dungeons/dic_dun.txt b/npc/re/mobs/dungeons/dic_dun.txt index f173fec0e..95715d678 100644 --- a/npc/re/mobs/dungeons/dic_dun.txt +++ b/npc/re/mobs/dungeons/dic_dun.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= Kisuka //===== Current Version: ===================================== -//= 1.1 +//= 1.2 //===== Compatible With: ===================================== //= Hercules //===== Description: ========================================= @@ -11,34 +11,35 @@ //===== Additional Comments: ================================= //= 1.0 Official spawns from Aegis [Kisuka] //= 1.1 Added Nightmare Scaraba Hole [Chilly] +//= 1.2 Updated Nightmare spawns and names. [Euphy] //============================================================ //================================================== // dic_dun01 - Underground Passage Kamidal Tunnel //================================================== -dic_dun01,0,0,0,0 monster One-Horned Scarab 2083,50,5000,0,0 -dic_dun01,0,0,0,0 monster Two-Horned Scarab 2084,45,5000,0,0 -dic_dun01,0,0,0,0 monster Scarab Egg 2088,15,5000,0,0 -dic_dun01,0,0,0,0 monster Scarab Egg 2089,15,5000,0,0 +dic_dun01,0,0,0,0 monster One-Horned Scaraba 2083,50,5000,0,0 +dic_dun01,0,0,0,0 monster Two-Horned Scaraba 2084,45,5000,0,0 +dic_dun01,0,0,0,0 monster Scaraba Egg 2088,15,5000,0,0 +dic_dun01,0,0,0,0 monster Scaraba Egg 2089,15,5000,0,0 //================================================== -// dic_dun02 - Underground Nest Scarab Hole +// dic_dun02 - Underground Nest Scaraba Hole //================================================== -dic_dun02,0,0,0,0 monster Antler Scarab 2085,50,5000,0,0 -dic_dun02,0,0,0,0 monster Rake Scarab 2086,45,5000,0,0 -dic_dun02,0,0,0,0 monster Antler Scarab Egg 2090,15,5000,0,0 -dic_dun02,0,0,0,0 monster Rake Scarab Egg 2091,15,5000,0,0 -dic_dun02,0,0,0,0 boss_monster Scarab Queen 2087,1,7200000,0,0 +dic_dun02,0,0,0,0 monster Antler Scaraba 2085,50,5000,0,0 +dic_dun02,0,0,0,0 monster Rake Scaraba 2086,45,5000,0,0 +dic_dun02,0,0,0,0 monster Antler Scaraba Egg 2090,15,5000,0,0 +dic_dun02,0,0,0,0 monster Rake Scaraba Egg 2091,15,5000,0,0 +dic_dun02,0,0,0,0 boss_monster Scaraba Queen 2087,1,7200000,0,1 //================================================== // dic_dun03 - Nightmare Scaraba Hole //================================================== -dic_dun03,0,0,0,0 monster Gold One-Horn Scaraba 2161,50,0,0,0 -dic_dun03,0,0,0,0 monster Gold Two-Horn Scaraba 2162,45,0,0,0 -dic_dun03,0,0,0,0 monster Gold Antler Scaraba 2163,50,0,0,0 -dic_dun03,0,0,0,0 monster Gold Rake Scaraba 2164,45,0,0,0 -dic_dun03,0,0,0,0 monster Gold One-Horn Scaraba Egg 2166,15,0,0,0 -dic_dun03,0,0,0,0 monster Gold Two-Horn Scaraba Egg 2167,15,0,0,0 -dic_dun03,0,0,0,0 monster Gold Antler Scaraba Egg 2168,15,0,0,0 -dic_dun03,0,0,0,0 monster Gold Rake Scaraba Egg 2169,15,0,0,0 -dic_dun03,0,0,0,0 boss_monster Gold Queen Scaraba 2165,1,7200000,600000,1 +dic_dun03,0,0,0,0 monster Gold One-Horn Scaraba Egg 2166,10,5000,0,0 +dic_dun03,0,0,0,0 monster Gold Two-Horn Scaraba Egg 2167,10,5000,0,0 +dic_dun03,0,0,0,0 monster Gold Antler Scaraba Egg 2168,10,5000,0,0 +dic_dun03,0,0,0,0 monster Gold Rake Scaraba Egg 2169,10,5000,0,0 +dic_dun03,0,0,0,0 monster Gold One-Horn Scaraba 2161,30,5000,0,0 +dic_dun03,0,0,0,0 monster Gold Two-Horn Scaraba 2162,30,5000,0,0 +dic_dun03,0,0,0,0 monster Gold Antler Scaraba 2163,40,5000,0,0 +dic_dun03,0,0,0,0 monster Gold Rake Scaraba 2164,40,5000,0,0 +dic_dun03,0,0,0,0 boss_monster Gold Queen Scaraba 2165,1,7200000,0,1
\ No newline at end of file diff --git a/npc/re/mobs/dungeons/iz_dun.txt b/npc/re/mobs/dungeons/iz_dun.txt index 8d4fad684..afa850598 100644 --- a/npc/re/mobs/dungeons/iz_dun.txt +++ b/npc/re/mobs/dungeons/iz_dun.txt @@ -3,13 +3,14 @@ //===== By: ================================================== //= Athena (1.0) //===== Current Version: ===================================== -//= 1.3 +//= 1.4 //===== Compatible With: ===================================== //= Hercules //===== Additional Comments: ================================= //= 1.1 Official kRO 10.1 spawns for 1-4 [Playtester] //= 1.2 More accurate spawns [Playtester] //= 1.3 Added Izlude Dungeon F6 spawns [Chilly] +//= 1.4 Official F6 spawns [Euphy] //============================================================ //================================================== @@ -112,8 +113,8 @@ iz_dun04,33,115,0,0 monster Hydra 1068,1,321000,150000,0 //================================================== // iz_dun05 - Undersea Tunnel F6 //================================================== -iz_dun05,0,0,0,0 monster King Dramoh 2198,20,0,0,0 -iz_dun05,0,0,0,0 monster Sropho 2201,50,0,0,0 -iz_dun05,0,0,0,0 monster Pot Dofle 2203,30,0,0,0 -iz_dun05,0,0,0,0 monster Sedora 2204,50,0,0,0 -iz_dun05,0,0,0,0 boss_monster Kraken 2202,1,7200000,600000,1 +iz_dun05,0,0,0,0 monster Sropho 2201,50,5000,0,0 +iz_dun05,0,0,0,0 monster Sedora 2204,60,5000,0,0 +iz_dun05,0,0,0,0 monster Pot Dofle 2203,30,5000,0,0 +iz_dun05,0,0,0,0 monster King Dramoh 2198,25,5000,0,0 +iz_dun05,0,0,0,0 boss_monster Kraken 2202,1,7200000,1800000,0 diff --git a/npc/re/mobs/fields/dewata.txt b/npc/re/mobs/fields/dewata.txt index 58118c4dc..6401b520b 100644 --- a/npc/re/mobs/fields/dewata.txt +++ b/npc/re/mobs/fields/dewata.txt @@ -3,16 +3,17 @@ //===== By: ================================================== //= Chilly //===== Current Version: ===================================== -//= 1.0 +//= 1.1 //===== Description: ========================================= //= Official kRO monster spawns //===== Additional Comments: ================================= //= 1.0 First Release +//= 1.1 Updated spawn delays. [Euphy] //============================================================ //================================================== // dew_fild01 - Dewata Field Tribal Village //================================================== -dew_fild01,0,0,0,0 monster Argiope 1099,45,0,0,0 -dew_fild01,0,0,0,0 monster Alnoldi 2151,60,0,0,0 -dew_fild01,0,0,0,0 monster Cendrawasih 2153,10,0,0,0 +dew_fild01,0,0,0,0 monster Alnoldi 2151,60,5000,0,0 +dew_fild01,0,0,0,0 monster Argiope 1099,45,5000,0,0 +dew_fild01,0,0,0,0 monster Cendrawasih 2153,10,5000,0,0
\ No newline at end of file diff --git a/npc/re/quests/homu_s.txt b/npc/re/quests/homu_s.txt deleted file mode 100644 index 66e2b5c3d..000000000 --- a/npc/re/quests/homu_s.txt +++ /dev/null @@ -1,144 +0,0 @@ -//===== Hercules Script ====================================== -//= Homunculus S Quest -//===== By: ================================================== -//= Masao -//===== Current Version: ===================================== -//= 1.1 -//===== Compatible With: ===================================== -//= Hercules -//===== Description: ========================================= -//= Evolves an Homunculus which is at least Level 99 to the -//= new Homunculus S Class. -//===== Additional Comments: ================================= -//= 1.0 First Version. The actual changing dialog is currently -//= customized. [Masao] -//= 1.1 Cleaning. [Euphy] -//============================================================ - -job3_gen01,12,44,4 script Viorel#job3_gen01 542,{ - - if((Class != Job_Genetic) && (Class != Job_Genetic_T) && (Class != Job_Baby_Genetic)){ - mes "[Viorel]"; - mes "^FF4800Homunculus^000000 research requires a lot of time and funding."; - mes "However, I believe passion is the most important factor."; - next; - switch(select("End conversation.:What are you talking about?:Why are you always standing there?")) { - case 1: - mes "[Viorel]"; - mes "So long~!"; - close; - case 2: - mes "[Viorel]"; - mes "You see, ^006400Alchemists^000000 have an inquisitive nature."; - mes "People like me, especially, even think of creating life itself."; - next; - mes "[Viorel]"; - mes "You'd have to research ^FF4800Homunculus^000000 to understand."; - mes "Now, if you'll excuse me~!"; - close; - case 3: - emotion 4,0; - mes "[Viorel]"; - mes "What, is it so strange to see an Alchemist in their own lab?"; - mes "How so?"; - close; - } - } - mes "[Viorel]"; - mes "Hello "+strcharinfo(0)+","; - mes "what can I do for a fellow Alchemist like you?"; - next; - switch(select("I want to evolve my Homunculus:About Homunculus S:Cancel")){ - case 1: - mes "[Viorel]"; - if(!getskilllv("AM_BIOETHICS")){ - mes "I'm sorry, but you must know the Skill Bioethics! Otherwise I can't let your Homunculus evolve into a Homunculus S."; - close; - } - if(!gethominfo(1)){ - mes "You don't even have a Homunculus!"; - close; - } - if(gethominfo(1) < 6009){ - mes "You must have an evolved Homunculus, or you can't turn it into the new Homunculus S."; - close; - } - if(gethominfo(6) < 99){ - mes "Your Homunculus must be level 99 to evolve into a Homuculus S!"; - mes "Come back after you've trained your Homunculus a little bit more."; - close; - } - if(gethominfo(1) == 6048 || gethominfo(1) == 6049 || gethominfo(1) == 6050 || gethominfo(1) == 6051 || gethominfo(1) == 6052){ - mes "Your Homunculus S looks great!"; - mes "I hope you will experience many great adventures with it!"; - close; - } - mes "Great, it seems like you're all ready to get your Homunculus to the next level!"; - next; - mes "[Viorel]"; - mes "Now you can either directly change your Homunculus to a random Homunculus S or you can donate a little fee of 50,000z"; - mes "to the Alchemist Guild. For this you'll be able to change your Homunculus into your desired Homunculus S Class!"; - mes "So, what do you think?"; - next; - switch(Select("I want to donate.:I don't want to donate.:Cancel")){ - case 1: - if(Zeny < 50000){ - mes "[Viorel]"; - mes "Haha, nice try my friend! But you don't even have the 50,000z to donate!"; - mes "Come back if you have the Zeny."; - close; - } - mes "[Viorel]"; - mes "Alright, now please tell me which Homunculus you'd like to have:"; - next; - set .@i, select("Eira:Bayeri:Sera:Dieter:Elanor:Cancel"); - if (.@i == 6) { - mes "[Viorel]"; - mes "So long~!"; - close; - } - case 2: - mes "[Viorel]"; - mes "Ok, it's all set! Now just give me a moment!"; - next; - mes "[Viorel]"; - mes "Abra..."; - next; - mes "[Viorel]"; - mes "Kadabra..."; - next; - mes "[Viorel]"; - mes "Simsala!"; - mes "..."; - mes "Oh, sorry... wrong game!"; - next; - mes "[Viorel]"; - mes "Here you go! Your new Homunculus S!"; - if (.@i) { - hommutate 6047+.@i; - set Zeny,Zeny - 50000; - } - else hommutate; - close; - case 3: - mes "[Viorel]"; - mes "So long~!"; - close; - } - case 2: - mes "[Viorel]"; - mes "The Homunculus S are the new and improved versions of the current Homunculus you know."; - mes "These new Homunculus have been made because the monsters in our world keep getting stronger and"; - mes "stronger, and our current Homunculus are just not able to keep up with them anymore."; - next; - mes "[Viorel]"; - mes "But since we're Alchemists and we don't want to abandon our precious Homunculus, we've discovered a way"; - mes "to improve their skills and strength in order to keep them by our side, and joining us once more"; - mes "in battle! Isn't that great?"; - close; - case 3: - mes "[Viorel]"; - mes "So long~!"; - close; - } -} diff --git a/npc/re/quests/homun_s.txt b/npc/re/quests/homun_s.txt new file mode 100644 index 000000000..66b7537c9 --- /dev/null +++ b/npc/re/quests/homun_s.txt @@ -0,0 +1,1362 @@ +//===== Hercules Script ====================================== +//= Homunculus S Quest +//===== By: ================================================== +//= Masao +//===== Current Version: ===================================== +//= 1.2 +//===== Compatible With: ===================================== +//= Hercules +//===== Description: ========================================= +//= Evolves an Homunculus which is at least Level 99 to the +//= new Homunculus S Class. +//===== Additional Comments: ================================= +//= 1.0 First Version. The actual changing dialog is currently +//= customized. [Masao] +//= 1.1 Cleaning. [Euphy] +//= 1.2 Replaced with official script. [Euphy] +//============================================================ + +// Main NPCs +//============================================================ +job3_gen01,12,44,3 script Viorel#job3_gen01 542,{ + if (countitem(6415)) { + if (Class == Job_Genetic || Class == Job_Genetic_T || Class == Job_Baby_Genetic) { + disable_items; + if (checkquest(4159) == -1 && checkquest(4160) == -1) { + mes "[Viorel]"; + mes "Why are you here?"; + mes "Shouldn't you be at ^005DFFJeyna^000000's house?"; + close2; + for(set .@i,4154; .@i<=4160; set .@i,.@i+1) { + if (checkquest(.@i) > -1) + erasequest .@i; + } + setquest 4154; + setquest 4159; + morphembryo; + if (countitem(6415) == 0) + getitem 6415,1; //Strange_Embryo + else if (countitem(6415) > 1) + delitem 6415, (countitem(6415) - 1); //Strange_Embryo + warp "que_house_s",63,41; + end; + } + enable_items; + } else if (Class == Job_Novice_High || Class == Job_Merchant_High || Class == Job_Alchemist || Class == Job_Creator) { + emotion e_what; + mes "[Viorel]"; + mes "I don't know what's going on, but the way I remember it you were supposed to be qualified to research ^FF4800Homunculus^000000."; + next; + mes "[Viorel]"; + mes "Whatever the reason, you're not able to continue the research on ^FF4800Homunculus^000000."; + mes "Come back after you become a ^005DFFGenetic^000000 and have obtained a ^0000FFBioethics^000000."; + close; + } else { + delitem 6415, countitem(6415); //Strange_Embryo + mes "[Viorel]"; + mes "Wait, that embryo you have seems a little strange."; + next; + mes "[Viorel]"; + mes "Unless you have a job researching ^FF4800Homunculus^000000...."; + mes "It will be of no help to you what so ever."; + next; + mes "[Viorel]"; + mes "I'm in charge of managing ^0000FFStrange Embryo^000000 so I'll take care of that for you."; + mes "No offense, and I'm not doing anything bad here."; + close; + } + } + if ((Class == Job_Genetic || Class == Job_Genetic_T || Class == Job_Baby_Genetic) && (checkquest(4154) > -1)) { + if ((checkquest(4155) > -1) || (checkquest(4160) > -1)) { + mes "[Viorel]"; + mes "Weather's great."; + next; + callsub L_CheckHomunculus; + mes "[Viorel]"; + mes "Ready to go to my house?"; + next; + switch(select("Go to ^005DFFViorel^000000's house.:Don't go.")) { + case 1: + mes "[Viorel]"; + mes "Good choice."; + mes "Now, close your eyes for a second..."; + close2; + warp "que_house_s",19,42; + end; + case 2: + mes "[Viorel]"; + mes "Come back when you're ready."; + mes "You must come with the ^FF4800Homunculus^000000."; + close; + } + } else { + mes "[Viorel]"; + mes "Why are you here?"; + mes "Shouldn't you be at ^005DFFJeyna^000000's house?"; + next; + callsub L_CheckHomunculus; + mes "[Viorel]"; + mes "Now, ready to go to ^005DFFJeyna^000000?"; + next; + switch(select("Go to ^005DFFJeyna^000000's room.:Don't go.")) { + case 1: + mes "[Viorel]"; + mes "Good choice."; + mes "Now, close your eyes for a second..."; + close2; + warp "que_house_s",63,41; + end; + case 2: + mes "[Viorel]"; + mes "Come back when you're ready."; + mes "You must come with the ^FF4800Homunculus^000000."; + close; + } + } + } + if (BaseJob == Job_Merchant) { + mes "[Viorel]"; + mes "I used to be a merchant once, just like you."; + mes "I'm researching on ^FF4800Homunculus^000000."; + next; + mes "[Viorel]"; + mes "If you're interested in ^FF4800Homunculus^000000, become an ^005DFFAlchemist^000000 or a ^005DFFCreator^000000."; + close; + } else if (BaseJob == Job_Alchemist && Class < Job_Genetic) { + mes "[Viorel]"; + mes "I've spent lots of time and energy on Homunculus."; + mes "If you feel like you're at a dead end, come back next time with a ^FF4800Homunculus^000000."; + next; + mes "[Viorel]"; + mes "Oh. Of course you need to have the suitable potentials. You could probably prove yourself once you become a ^FF4800Genetic^000000."; + close; + } else if (Class == Job_Genetic || Class == Job_Genetic_T || Class == Job_Baby_Genetic) { + if (gethominfo(6) >= 99 && (gethominfo(1) >= 6009 && gethominfo(1) <= 6016)) { // Level 99+ evolved Homunculus + mes "[Viorel]"; + mes "Oh, great~!"; + mes "You have a ^FF4800Homunculus^000000."; + mes "With passion invested in its research we can make them better."; + next; + mes "[Viorel]"; + mes "I must speak to you in private. Would you mind going to my house with me?"; + next; + switch(select("Go to ^005DFFViorel^000000's home.:Stay here.")) { + case 1: + mes "[Viorel]"; + mes "Good choice."; + mes "Now, close your eyes for a second..."; + close2; + setquest 4154; + setquest 4155; + warp "que_house_s",19,42; + end; + case 2: + mes "[Viorel]"; + mes "If you feel like you're at a dead end, come back next time with a ^FF4800Homunculus^000000."; + close; + } + } else if (gethominfo(6) >= 99 && (gethominfo(1) >= 6048 && gethominfo(1) <= 6052)) { // Level 99+ mutated Homunculus-S + mes "[Viorel]"; + mes "Hello again."; + mes "Perhaps you may be interested"; + mes "in the newly created ^FF4800Homunculus^000000,"; + mes "born from the new ^006400Homunculus Mutation System^000000?"; + next; + switch(select("Nope. Good bye.:Please, I'm busy.:That's exactly what I wanted to hear.:Why are you always standing there?")) { + case 1: + emotion e_heh; + mes "[Viorel]"; + mes "Okay."; + mes "Good seeing you."; + mes "Good bye then~!"; + close; + case 2: + emotion e_omg; + mes "[Viorel]"; + mes "!!!!"; + mes "I... I see."; + mes "I thought you were here to see me."; + close; + case 3: + emotion e_ic; + mes "[Viorel]"; + mes "Just as I thought."; + mes "Let's have a look at the notes my dear friend Jeyna left."; + next; + playbgm "30.mp3"; // One Step Closer + callfunc "F_HomMutateInfo","[Memo Pad Notes]"; + mes "[Viorel]"; + mes "Hmm."; + mes "Well, that's all there is to it."; + mes "It's up to you to find out more."; + close2; + playbgm "08.mp3"; // Theme of Prontera + end; + case 4: + emotion e_swt; + mes "[Viorel]"; + mes "No, I do not stand here every day."; + mes "But why do YOU stand there every day?"; + next; + mes "[Viorel]"; + mes "What?"; + mes "No, the way I see it"; + mes "you seem to be here every time I'm here."; + close; + } + } else { + if (gethominfo(1) >= 6009) { // Evolved Homunculus + mes "[Viorel]"; + mes "Hmm, you seem to have a special bond with your ^FF4800Homunculus^000000."; + next; + mes "[Viorel]"; + mes "Come back to me when that ^FF4800Homunculus^000000 reaches ^0000FFlevel 99^000000."; + close; + } else { + mes "[Viorel]"; + mes "You do not yet possess an evolved ^FF4800Homunculus^000000..."; + mes "As you may well know about evolution:"; + next; + mes "[Viorel]"; + mes "Using the ^0000FFStone of Sage^000000 when intimacy level is above ^006400Intimate^000000, the ^FF4800Homunculus^000000 goes through ^006400Evolution^000000."; + close; + } + } + } + mes "[Viorel]"; + mes "^FF4800Homunculus^000000 research requires a lot of time and funding."; + mes "However, I believe passion is the most important factor."; + next; + switch(select("End conversation.:What are you talking about?:Why are you always standing there?")) { + case 1: + mes "[Viorel]"; + mes "So long~!"; + close; + case 2: + mes "[Viorel]"; + mes "You see, ^006400Alchemists^000000 have an inquisitive nature."; + mes "People like me, especially, even think of creating life itself."; + next; + mes "[Viorel]"; + mes "You'd have to research ^FF4800Homunculus^000000 to understand."; + mes "Now, if you'll excuse me~!"; + close; + case 3: + emotion e_swt; + mes "[Viorel]"; + mes "What, is it so strange to see an Alchemist in their own lab?"; + mes "How so?"; + close; + } + end; +L_CheckHomunculus: + if (gethominfo(6) < 99 || (gethominfo(1) < 6009 || gethominfo(1) > 6016)) { // Not level 99+ evolved Homunculus + mes "[Viorel]"; + mes "Huh?"; + mes "Where's the ^FF4800Homunculus^000000 you used to have?"; + mes "Perhaps I've mistaken it for something else..."; + next; + mes "[Viorel]"; + mes "......."; + mes " "; + mes "(Seems to be thinking about something.)"; + next; + emotion e_heh; + mes "[Viorel]"; + mes "Ha ha~"; + mes "I think I've mistaken you for someone else."; + mes "If you'll excuse me."; + close; + } + return; +} + +que_house_s,24,47,3 script Viorel#homun_s 542,{ + if (checkquest(4155) > -1) { + emotion e_dum; + mes "[Viorel]"; + mes "Good."; + mes "I see that you mean business."; + next; + playbgm "33.mp3"; // Yuna Song + mes "[Viorel]"; + mes "Maybe you'll agree."; + mes "Currently, your ^FF4800Homunculus^000000 is not in its perfect state."; + next; + mes "[Viorel]"; + mes "These days, studies on the growth of the ^FF4800Homunculus^000000 are actively taking place."; + mes "But, I do believe that I have found something special."; + next; + mes "[Viorel]"; + mes "In order to break the current limitations of the ^FF4800Homunculus^000000, mutations need to happen."; + next; + switch(select("Like, biological experiments...?!:Well, yeah, naturally.:I don't want to hurt my Homunculus!")) { + case 1: + emotion e_swt2; + mes "[Viorel]"; + mes "Don't look so surprised."; + mes "Ethics in biology are kind of blurry right now, right?"; + mes "I mean..."; + next; + mes "[Viorel]"; + mes "It's my duty to study the true potential of the ^FF4800Homunculus^000000."; + next; + mes "[Viorel]"; + mes "So far, Homunculus haven't demonstrated their full potential, but I know that I am close to a breakthrough."; + next; + break; + case 2: + emotion e_sigh; + mes "[Viorel]"; + mes "Yes."; + mes "I'm glad you're not upset."; + mes "Mutation,"; + mes "a word that sparks evil in the minds of the ordinary,"; + mes "which made my research very difficult to proceed with."; + next; + mes "[Viorel]"; + mes "Do you remember?"; + mes "^005DFFKellasus^000000 of ^8B4513Lighthalzen^000000, the pioneer of ^FF4800Homunculus^000000 research."; + next; + mes "[Viorel]"; + mes "I believe that this research fulfills the promise made with ^005DFFKellasus^000000, the giver of knowledge and belief."; + next; + break; + case 3: + emotion e_swt; + mes "[Viorel]"; + mes "I understand your concern."; + mes "But I want to assure you that this Mutation does not harm or hurt your ^FF4800Homunculus^000000."; + next; + mes "[Viorel]"; + mes "On the contrary, the ^FF4800Homunculus^000000 of today are in pain from imperfection, unable to live up to their supposed potentials."; + mes "Moreover, those ^FF4800Homunculus^000000 were often abandoned."; + next; + mes "[Viorel]"; + mes "Don't get me wrong, I study the ^FF4800Homunculus^000000 because I love them."; + next; + break; + } + mes "[Viorel]"; + mes "Well, by the way..."; + mes "I have found this new mutation to be quite stable."; + next; + mes "[Viorel]"; + mes "^006400The technology exists,"; + mes "and they will likely have new"; + mes "skills when mutated...^000000"; + next; + mes "[Viorel]"; + mes "The minor side effect..."; + mes "^006400Their appearance will change^000000."; + mes "But I think you'll find that pretty satisfying."; + next; + mes "[Viorel]"; + mes "I quote from ^005DFFKassibian^000000, an expert in ^FF4800Homunculus^000000 techniques,"; + mes "^006400The truth is not in a single form~!^000000"; + mes "Ha ha."; + next; + emotion e_flash; + mes "[Viorel]"; + mes "I know it's a little abrupt, but..."; + mes "How about changing your ^FF4800Homunculus^000000 into something incredible with my marvelous achievement, the ^006400Homunculus Mutation System^000000?"; + next; + switch(select("Explore the ^006400Homunculus Mutation System^000000.:Cancel.")) { + case 1: + emotion e_no1; + mes "[Viorel]"; + mes "Good choice."; + mes "Success lurks outside the box of conventional thinking, right?"; + next; + mes "[Viorel]"; + mes "The first person to help with the research is ^005DFFJeyna^000000."; + mes "I'll send you to ^005DFFJeyna^000000."; + mes "There, you'll learn more about the new ^0000FFHomunculus^000000."; + close2; + setquest 4156; + erasequest 4155; + warp "que_house_s",63,41; + end; + case 2: + emotion e_dots; + mes "[Viorel]"; + mes "I don't see why you hesitate."; + mes "I am not trying to deceive you."; + mes "Maybe you need some time to think about it?"; + next; + switch(select("Think about it.:I'm just going to walk away.")) { + case 1: + mes "[Viorel]"; + mes "We'll talk in a bit then."; + close; + case 2: + emotion e_otl; + mes "[Viorel]"; + mes "Shame."; + mes "However, I respect your opinion."; + mes "I'll send you back to the ^8B4513Laboratory^000000."; + close2; + erasequest 4154; + erasequest 4155; + warp "job3_gen01",12,47; + end; + } + } + } else if (checkquest(4160) > -1) { + playbgm "33.mp3"; // Yuna Song + mes "[Viorel]"; + mes "The ^FF4800Homunculus^000000 I saw before has returned to its ^0000FFembryo^000000 state."; + mes "A little strange, but..."; + mes "You don't have to worry about it."; + next; + mes "[Viorel]"; + mes "By the way..."; + mes "I forgot to tell you something."; + mes "In order to stabilize the Mutation process, I need some materials first."; + next; + mes "[Viorel]"; + mes "Fortunately, you don't have to find them yourself because I have them here already.."; + mes "But, I'll need ^FF000050,000 zeny^000000, you know, as a service fee."; + next; + mes "[Viorel]"; + mes "I wish that I could do it for free but I'm not exactly made of money, you know."; + mes "That and I lack any investors to support my research at the moment."; + next; + mes "[Viorel]"; + mes "In fact, if I had enough zeny to continue my research, then I could solve a lot of my problems..."; + next; + mes "[Viorel]"; + mes "Anyways, you can try to do this with or without the stabilization process. It's all up to you."; + next; + mes "[Viorel]"; + mes "If you choose the unstable"; + mes "mutation, I can't guarentee what kind of Homunculus you're going to get."; + mes "Anyways, it's up to you."; + next; + switch(select("Mutation stabilization (50,000 zeny):Unstable mutation")) { + case 1: + if (Zeny < 50000) { + mes "[Viorel]"; + mes "I don't think you have ^FF000050 thousand Zeny^000000 with you right now."; + mes "Please bring enough Zeny."; + mes "I'll be waiting."; + mes "Want me to send you back to the ^8B4513Laboratory^000000?"; + next; + switch(select("No thanks.:Yes. Send me back to the Lab.")) { + case 1: + mes "[Viorel]"; + mes "Alright."; + mes "I'll see you in a bit."; + close; + case 2: + mes "[Viorel]"; + mes "Alright."; + mes "I'll be waiting at the ^8B4513Laboratory^000000."; + close2; + warp "job3_gen01",12,47; + end; + } + } + emotion e_no1; + playbgm "19.mp3"; // Under the Ground + mes "[Viorel]"; + mes "Good choice."; + mes "Choose from the different types of ^0000FFHomunculus^000000."; + next; + switch(select("Eira:Sera:Dieter:Bayeri:Eleanor")) { + case 1: + cutin "Mer_Eira_Card",3; + set .@Homunculus,6048; //MER_EIRA + break; + case 2: + cutin "Mer_Sera_Card",3; + set .@Homunculus,6050; //MER_SERA + break; + case 3: + cutin "Mer_Dieter_Card",3; + set .@Homunculus,6051; //MER_DIETER + break; + case 4: + cutin "Mer_Bayeri_Card",3; + set .@Homunculus,6049; //MER_BAYERI + break; + case 5: + cutin "Mer_Eleanor_Card",3; + set .@Homunculus,6052; //MER_ELEANOR + break; + } + mes "[Viorel]"; + mes "Are you sure?"; + next; + if(select("Yes.:No.") == 2) { + cutin "",255; + playbgm "33.mp3"; // Yuna Song + mes "[Viorel]"; + mes "I see."; + mes "Give it more time to think."; + close; + } + cutin "",255; + mes "[Viorel]"; + mes "Excellent!"; + mes "Let's get on with it."; + next; + specialeffect2 EF_BASH; + mes "[Viorel]"; + mes "Now focus~!"; + mes "You... need..."; + mes "... concentration."; + next; + specialeffect2 EF_PROVIDENCE; + mes "[Viorel]"; + mes "Good. Almost done!"; + next; + specialeffect2 EF_SUI_EXPLOSION; + set Zeny, Zeny - 50000; + hommutate .@Homunculus; + break; + case 2: + emotion e_hmm; + mes "[Viorel]"; + mes "So, your choice is the Unstable Mutation Process."; + mes "You believe in destiny?"; + mes "Seriously..."; + mes "Do you really wish to proceed"; + mes "with the process of random outcome?"; + next; + if(select("Go ahead. (Random Mutation):Cancel.") == 2) { + playbgm "33.mp3"; // Yuna Song + mes "[Viorel]"; + mes "I see."; + mes "Give it more time to think."; + close; + } + emotion e_dots; + mes "[Viorel]"; + mes "Hmm..."; + mes "The exploration of knowledge"; + mes "is full of surprises."; + mes "......."; + next; + emotion e_heh; + mes "[Viorel]"; + mes "Ha ha."; + mes "Hey, I feel like a Blacksmith!"; + mes "Now let's get on with it."; + next; + specialeffect2 EF_BASH; + mes "[Viorel]"; + mes "Now focus~!"; + mes "You... need..."; + mes "... concentration."; + next; + specialeffect2 EF_PRESSURE; + mes "[Viorel]"; + mes "Concentrate a little more!"; + next; + specialeffect2 EF_PROVIDENCE; + mes "[Viorel]"; + mes "Good. Almost done!"; + next; + specialeffect2 EF_SUI_EXPLOSION; + hommutate; + break; + } + erasequest 4160; + erasequest 4154; + emotion e_ho; + playbgm "64.mp3"; // One Fine Day + mes "[Viorel]"; + mes "Okay, Mutation Complete."; + mes "Phew... Didn't skip a heartbeat, did you?"; + next; + mes "[Viorel]"; + mes "Remember what ^005DFFKellasus^000000 said?"; + mes "To the doorstep of the truth..."; + mes "We must see for ourselves"; + mes "the path that leads to it."; + next; + mes "[Viorel]"; + mes "^0000FF" + strcharinfo(0) + "^000000,"; + mes "I haven't known you"; + mes "for a very long time,"; + mes "but I get the feeling that"; + mes "you'll achieve great things."; + next; + mes "[Viorel]"; + mes "Good luck on you adventures."; + mes "I hope that your new ^FF4800Homunculus^000000 will excel under your care."; + next; + mes "[Viorel]"; + mes "And don't you forget."; + mes "Our research"; + mes "has only just begun~!"; + close; + } else { + for(set .@i,4154; .@i<=4160; set .@i,.@i+1) { + if (checkquest(.@i) > -1) + erasequest .@i; + } + mes "[Viorel]"; + mes "Now that all the work is done, I ask you to take your leave."; + mes "I need to recuperate."; + close2; + warp "job3_gen01",12,47; + end; + } +} + +que_house_s,80,42,3 script Jeyna#homun_s 558,{ + if (checkquest(4156) > -1) { + playbgm "28.mp3"; // You're in Ruins + emotion e_gasp; + mes "[Jeyna]"; + mes "Welcome."; + mes "I just got word from ^005DFFViorel^000000 that you were coming."; + next; + emotion e_hmm; + mes "[Jeyna]"; + mes "By the way..."; + mes "Did he convince you to do something...?"; + mes "He does have a way with words."; + next; + mes "[Jeyna]"; + mes "He needs them because Alchemists are such awkward people."; + emotion e_sigh; + next; + mes "[Jeyna]"; + mes "Anyways~"; + mes "^0000FF"+strcharinfo(0)+"^000000 and ^005DFFViorel^000000 seem like two peas in a pod."; + next; + emotion e_heh; + mes "[Jeyna]"; + mes "Hahaha~ No offense."; + mes "I think it's a good thing."; + mes "Oh, yes."; + mes "You're here for the ^FF4800Homunculus^000000 Mutation."; + next; + mes "[Jeyna]"; + mes "While I do some preparation,"; + mes "why don't you take a look at that board?"; + mes "The ^006400Homunculus Mutation System^000000 has ^0000FF5 different types^000000 of new mutations."; + next; + emotion e_gasp,0,"Magic Board#homun_s"; + mes "[Jeyna]"; + mes "Your ^FF4800Homunculus^000000 can mutate into any of the 5 different forms."; + next; + emotion e_ic; + mes "[Jeyna]"; + mes "Let's see..."; + mes "The ^006400Homunculus Mutation System^000000 includes new evolutions of the normal ^0000FFHomunculus^000000."; + mes "After they mutate, all previously learned skills will also remain."; + next; + mes "[Jeyna]"; + mes "In other words..."; + mes "Even if you change the magic wielder ^FF4800Vanilmirth^000000 to a fighter type,"; + mes "skills such as Caprice will be"; + mes "^006400retained and usable even after Mutation^000000."; + next; + emotion e_gasp,0,"Magic Board#homun_s"; + mes "[Jeyna]"; + mes "Take a look at the Magic Board behind me and decide for yourself."; + close2; + setquest 4157; + erasequest 4156; + end; + } else if (checkquest(4157) > -1) { + emotion e_what; + mes "[Jeyna]"; + mes "Take a look at the board behind me, on the right."; + close2; + emotion e_gasp,0,"Magic Board#homun_s"; + end; + } else if (checkquest(4158) > -1) { + playbgm "28.mp3"; // You're in Ruins + disable_items; + mes "[Jeyna]"; + mes "Okay, I'm ready too."; + mes "In order to revert the process now, I need the Homunculus in its embryo form."; + next; + callsub L_CheckHomunculus; + if (checkweight(6415,1) == 0) { + mes "[Jeyna]"; + mes "But,"; + mes "You don't have enough space to carry an ^0000FFembryo^000000."; + mes "Please come back with enough space in your bag."; + next; + mes "[Jeyna]"; + mes "Please return to the ^8B4513Laboratory^000000."; + mes "You can find ^005DFFViorel^000000 at the ^8B4513Laboratory^000000 once you empty your bag."; + next; + mes "[Jeyna]"; + mes "When you're done with emptying your bag, ask ^005DFFViorel^000000 to send you back here."; + mes "Go on and empty your bag~!"; + close2; + warp "job3_gen01",12,47; + end; + } + mes "[Jeyna]"; + mes "Now's about time for a decision."; + mes "To go through the Mutation to the new ^0000FFHomunculus^000000 with the Homunculus Mutation System,"; + mes "you need to go through the process of regression to turn the Homunculus back to its ^0000FFembryo^000000 state."; + next; + mes "[Jeyna]"; + mes "And..."; + mes "^006400You cannot use the ability Call Homunculus until the process is complete.^000000"; + mes "It won't take long, so don't wander off."; + next; + mes "[Jeyna]"; + mes "So, please decide."; + mes "Do you want to proceed with the new ^0000FFHomunculus Mutation System^000000?"; + next; + switch(select("Yes, I do.:I need to think more.")) { + case 1: + if (checkhomcall() == 1) { + mes "[Jeyna]"; + mes "Oh, wait a minute."; + mes "To proceed with the Mutation, you need to wake up the Homunculus from the state of Vaporization."; + next; + mes "[Jeyna]"; + mes "Come back after you've done that."; + close; + } + emotion e_no1; + mes "[Jeyna]"; + mes "Good thinking."; + mes "It is unacceptable for Alchemists like us to fear challenge."; + next; + playbgm "01.mp3"; // Title + mes "[Jeyna]"; + mes "Now I need you to focus."; + next; + specialeffect2 EF_ABSORBSPIRITS; + mes "[Jeyna]"; + mes "We need to..."; + mes "Stabilize a little more."; + mes "......."; + next; + specialeffect2 EF_CURE; + mes "[Jeyna]"; + mes "In a few moments, the ^FF4800Homunculus^000000 will return to its embryo state."; + next; + specialeffect2 EF_HOLYHIT; + mes "[Jeyna]"; + mes "Into a special embryo..."; + next; + callsub L_CheckHomunculus; + specialeffect2 EF_BLESSING; + morphembryo; + setquest 4159; + erasequest 4158; + emotion e_ho; + mes "[Jeyna]"; + mes "Phew~ All done."; + mes "Hmm, its state is a little strange."; + next; + emotion e_heh; + mes "[Jeyna]"; + mes "I guess it'll be just fine."; + mes "Don't lose that ^0000FFStrange Embryo^000000."; + mes "Also..."; + next; + mes "[Jeyna]"; + mes "Don't do anything like changing jobs or anything like that before the process is over."; + mes "If so, you, ^0000FF"+strcharinfo(0)+"^000000 might lose all the abilities you have over the Homunculus."; + next; + mes "[Jeyna]"; + mes "All that concentration made me tired."; + mes "I'll just take a glass of water."; + close; + case 2: + playbgm "28.mp3"; // You're in Ruins + emotion e_sigh; + mes "[Jeyna]"; + mes "Maybe I shouldn't have asked in the first place."; + close; + } + } else if (checkquest(4159) > -1 || checkquest(4160) > -1) { + playbgm "28.mp3"; // You're in Ruins + mes "[Jeyna]"; + mes "^005DFFViorel^000000 will finish the mutation process."; + mes "Now it's my time to say good bye."; + next; + mes "[Jeyna]"; + mes "It was short, but it was nice to meet you."; + mes "We'll see each other again some time."; + next; + mes "[Jeyna]"; + mes "Best of luck~!"; + close2; + setquest 4160; + erasequest 4159; + warp "que_house_s",19,42; + end; + } else { + if (checkquest(4154) > -1) + erasequest 4154; + mes "[Jeyna]"; + mes "Hey, how did you get in here?"; + mes "Please get out. I'm changing~!"; + close2; + warp "job3_gen01",12,47; + end; + } + end; +L_CheckHomunculus: + if (gethominfo(6) < 99 || (gethominfo(1) < 6009 || gethominfo(1) > 6016)) { // Not level 99+ evolved Homunculus + mes "[Jeyna]"; + mes "Hey, wait."; + mes "The condition of the ^FF4800Homunculus^000000 is not suitable."; + mes "That was close."; + next; + mes "[Jeyna]"; + mes "To use the Homunculus Mutation System"; + mes "to change to the new"; + mes "^FF4800Homunculus^000000,"; + mes "the ^006400Homunculus must be above level 99 and evolved^000000."; + next; + mes "[Jeyna]"; + mes "Come back to ^005DFFViorel^000000 when you're ready."; + mes "I'll see you later then~!"; + close2; + erasequest 4154; + erasequest 4158; + warp "job3_gen01",12,47; + end; + } + return; +} + +// Magic Board +//============================================================ +que_house_s,83,47,3 script Magic Board#homun_s 857,{ + playbgm "26.mp3"; // Everlasting Wanderers + callfunc "F_HomMutateInfo","[Magic Board Posts]"; + mes "[Magic Board Posts]"; + mes ":: ^0000FFHomunculus^000000 research is"; + mes ":: so much fun."; + mes ":: Be an Alchemist"; + mes ":: who always enjoys"; + mes ":: one's research."; + next; + mes "[Magic Board Posts]"; + mes ":: Oh, and Viorel..."; + mes ":: About what you said"; + mes ":: yesterday..."; + mes "::"; + mes "::"; + next; + mes "--------------------------"; + mes "The rest is sealed because it seems to be a private message."; + close2; + if (checkquest(4157) > -1) { + setquest 4158; + erasequest 4157; + } + end; +} + +function script F_HomMutateInfo { + mes getarg(0); + mes ":: The ability of the mutated"; + mes ":: ^0000FFHomunculus^000000 clearly goes"; + mes ":: beyond the previous state."; + mes ":: In addition, its appearance"; + mes ":: will evolve as well."; + next; + mes getarg(0); + mes ":: ^0000FFHomunculus^000000 appearances of the"; + mes ":: new types can be classified"; + mes ":: based on different species."; + mes ":: Creatures of the same species"; + mes ":: generally have a similar"; + mes ":: appearance."; + next; + mes getarg(0); + mes ":: The category, appearance and"; + mes ":: ability of the ^0000FFHomunculus^000000"; + mes ":: via the Homunculus Mutation"; + mes ":: System are as follows:"; + next; + cutin "Mer_Eira_Card",3; + mes getarg(0); + mes ":: The first of the five"; + mes ":: is called ^FF4800Eira^000000."; + mes ":: Beautiful and graceful."; + next; + mes getarg(0); + mes ":: ^FF4800Eira^000000 uses"; + mes ":: ^006400Wind Element^000000 Magic Attacks and"; + mes ":: Support Skills."; + mes ":: It even has the ability"; + mes ":: to revive its"; + mes ":: fallen master."; + next; + mes getarg(0); + mes ":: ^FF4800Eira^000000 eats"; + mes ":: ^0000FFSmall Snow Flower^000000."; + mes ":: Surprising how it survives on"; + mes ":: such a small amount."; + mes ":: ^0000FFSmall Snow Flower^000000 can be bought"; + mes ":: from ^005DFFTaming Merchants^000000."; + next; + cutin "",255; + cutin "Mer_Sera_Card",3; + mes getarg(0); + mes ":: The second of the five"; + mes ":: is known as ^FF4800Sera^000000."; + mes ":: It looks just like ^FF0000Mistress^000000 but"; + mes ":: it doesn't run away."; + next; + mes getarg(0); + mes ":: ^FF4800Sera^000000"; + mes ":: specializes in ^006400Poison Attacks^000000."; + mes ":: Also, it uses distinct"; + mes ":: Support Skills using poisons."; + next; + mes getarg(0); + mes ":: ^FF4800Sera^000000 eats"; + mes ":: ^0000FFApple Pudding^000000."; + mes ":: It prefers sweet food."; + mes ":: ^0000FFApple Pudding^000000 can be bought"; + mes ":: from ^005DFFTaming Merchants^000000."; + next; + cutin "",255; + cutin "Mer_Dieter_Card",3; + mes getarg(0); + mes ":: The third of the five"; + mes ":: is ^FF4800Dieter^000000."; + mes ":: It looks unusual but it"; + mes ":: has a good demeanor."; + next; + mes getarg(0); + mes ":: ^FF4800Dieter^000000 uses"; + mes ":: ^FF0000Fire^000000 based Attacks and"; + mes ":: Support Skills."; + mes ":: It is just as fragile..."; + mes ":: ah, reliable, as it looks."; + next; + mes getarg(0); + mes ":: ^FF4800Dieter^000000 eats"; + mes ":: ^0000FFBig Cell^000000."; + mes ":: ^0000FFBig Cell^000000 can be bought"; + mes ":: from ^005DFFTaming Merchants^000000."; + next; + cutin "",255; + cutin "Mer_Bayeri_Card",3; + mes getarg(0); + mes ":: The fourth of the five"; + mes ":: is ^FF4800Bayeri^000000."; + mes ":: Bayeri has the form of a"; + mes ":: unicorn."; + next; + mes getarg(0); + mes ":: It has a powerful dash skill"; + mes ":: and uses ^006400Holy Element^000000 magic."; + mes ":: Unfortunately,"; + mes ":: they won't let you ride them."; + mes ":: Not all four-legged creatures"; + mes ":: can be ridden."; + next; + mes getarg(0); + mes ":: ^FF4800Bayeri^000000 eats"; + mes ":: ^0000FFFresh Plant^000000."; + mes ":: No matter how hungry it"; + mes ":: never feeds on rotten greens."; + mes ":: ^0000FFFresh Plant^000000 can be bought"; + mes ":: from ^005DFFTaming Merchants^000000."; + next; + cutin "",255; + cutin "Mer_Eleanor_Card",3; + mes getarg(0); + mes ":: The last of the five"; + mes ":: is ^FF4800Eleanor^000000."; + mes ":: It has a feminine appearance"; + mes ":: and outstanding physical skill."; + next; + mes getarg(0); + mes ":: ^FF4800Eleanor^000000"; + mes ":: uses ^006400Strike or Grapple Attacks^000000"; + mes ":: sequentially in battle."; + mes ":: Absolutely stunning."; + next; + mes getarg(0); + mes ":: ^FF4800Eleanor^000000 eats"; + mes ":: ^0000FFKid's Dumpling^000000."; + mes ":: Don't confuse it with a normal"; + mes ":: dumpling."; + mes ":: ^0000FFKid's Dumpling^000000 can be bought"; + mes ":: from ^005DFFTaming Merchants^000000."; + next; + cutin "",255; + return; +} + +// Books +//============================================================ +que_house_s,13,52,3 script Open Book#01homun_s 111,{ + switch(rand(1,7)) { + case 1: + mes "[Bookcase Notes]"; + mes "Insanity and Genius are the same in concept in that they are both abnormal phenomenon."; + mes "Observing the chemist ^005DFFMorgenstein^000000 of ^8B4513Geffen^000000, I consider them equal."; + next; + mes "[Bookcase Notes]"; + mes "Once I had to visit..."; + mes "the strange ^005DFFMorgenstein^000000 for research purposes."; + next; + mes "[Bookcase Notes]"; + mes "I had a meat stew before I met ^005DFFMorgenstein^000000,"; + mes "surprisingly enough, he muttered that he smelled meat even before I was close."; + next; + mes "[Bookcase Notes]"; + mes "I never thought that chemists had a great sense of smell."; + mes "The next time I give"; + mes "^005DFFMorgenstein^000000 a visit,"; + mes "I'll eat some other meal."; + close; + case 2: + mes "[Bookcase Notes]"; + mes "^005DFFDe Bris^000000 thinks the enthusiasm of Alchemists has lately dropped <Dramatically>..."; + next; + mes "[Bookcase Notes]"; + mes "He especially didn't like the fact that I was bound tightly to ^FF4800Homunculus^000000 research."; + mes "He didn't say such a thing when we studied together in ^8B4513Rune Midgarts^000000."; + next; + mes "[Bookcase Notes]"; + mes "One day, I'll show ^005DFFDe Bris^000000 my ^FF4800Homunculus^000000 research data."; + mes "I love watching him jump out of his skin.... I look forward to the day."; + close; + case 3: + mes "[Bookcase Notes]"; + mes "^005DFFDe Bris^000000' passion for the ^57007FGenetic^000000 arts is amazing."; + next; + mes "[Bookcase Notes]"; + mes "Recently, the Alchemist Union offered me the chance to join the ^57007FGenetic^000000 through a letter."; + mes "I wonder what ^005DFFDe Bris^000000 said to the union..."; + next; + mes "[Bookcase Notes]"; + mes "Well, I appreciate it..."; + mes "However, for me right now"; + mes "my research is of utmost priority."; + close; + case 4: + mes "[Bookcase Notes]"; + mes "There's something funny ^005DFFDarcia^000000 said to me."; + mes "It was about when ^005DFFJeyna^000000 first came to learn about potion combination......"; + next; + mes "[Bookcase Notes]"; + mes "She did good up to the stage of pouring water into the mixture."; + mes "She just had to put it into an empty bottle..."; + next; + mes "[Bookcase Notes]"; + mes "^005DFFDarcia^000000 watched what she would do with the last stage,"; + mes "and the confused ^005DFFJeyna^000000 drank the mixture out of the bowl and told her that it healed well."; + next; + mes "[Bookcase Notes]"; + mes "To think that even ^005DFFJeyna^000000,"; + mes "now a master of potion combination,"; + mes "had her rookie mistakes"; + mes "shows how hard it is to imagine"; + mes "and forecast one's past and future."; + close; + case 5: + mes "[Bookcase Notes]"; + mes "^005DFFVincent^000000, I think I did it."; + mes "I will never forget your words of courage "; + mes "and I am grateful that I now get to pay you back."; + next; + mes "[Bookcase Notes]"; + mes "It was indeed a long process."; + mes "When many of the union"; + mes "considered my research insignificant"; + mes "... Though I did not lose my belief"; + mes "it did heart deep inside."; + next; + mes "[Bookcase Notes]"; + mes "The few friends who believed me"; + mes "especially ^005DFFJeyna^000000"; + mes "and you ^005DFFVincent^000000 ..."; + mes "I am sincerely thankful with all my soul."; + next; + mes "[Bookcase Notes]"; + mes "They say that,"; + mes "the end justifies the means."; + mes "At first,"; + mes "I did not know what it meant..."; + next; + mes "[Bookcase Notes]"; + mes "Now I know."; + mes "I know how important it is"; + mes "to follow one's heart."; + next; + mes "[Bookcase Notes]"; + mes "I'll drop by very soon."; + mes "Be well until then."; + close; + case 6: + mes "[Bookcase Notes]"; + mes "A game called ^0000FFThe Epic Battle 2^000000, similar to chess, was intriguing."; + next; + mes "[Bookcase Notes]"; + mes "Some time ago, I met a ^0000FFFruit Seller^000000 who excelled in The Epic Battle 2."; + mes "He even overcame the infamous ^006400Grizzly Shockwave Strategy^000000 and ^006400God of Death Terror^000000 with ease."; + next; + mes "[Bookcase Notes]"; + mes "To overcome those in the early stages of the battle of the ^0000FFPriest Faction^000000..."; + mes "It is difficult for me, since I need to combine the pieces and use some luring skills."; + next; + mes "[Bookcase Notes]"; + mes "I wonder when I'll become a 3 Carat Diamond level player."; + close; + case 7: + mes "[Bookcase Notes]"; + mes "There are many Alchemists who like the ^FF4800Vanilmirth^000000."; + next; + mes "[Bookcase Notes]"; + mes "But I prefer the ^FF4800Amistr^000000."; + mes "It's cute when it wags its tale with those shiny eyes."; + next; + mes "[Bookcase Notes]"; + mes "My Amistr Jonathan is clever and mellow, making it ever so lovable."; + mes "We're good friends, aren't we Jonathan?"; + close; + } +} + +que_house_s,16,52,3 script Open Book#02homun_s 111,{ + switch(rand(1,8)) { + case 1: + mes "[Bookcase Notes]"; + mes "What should I write to ^005DFFDe Bris^000000."; + mes ":: To my noted "; + mes ":: Genetic friend De Bris."; + mes ":: How's Lighthalzen?"; + mes ":: Do they have enough of those"; + mes ":: cookies you oh so love?"; + next; + mes "[Bookcase Notes]"; + mes ":: I'll drop by soon"; + mes ":: with some cookies."; + mes ":: When we meet,"; + mes ":: I'll introduce you to my"; + mes ":: ^006400New Homunculus^000000."; + next; + mes "[Bookcase Notes]"; + mes ":: No need to be alert."; + mes ":: Unlike you,"; + mes ":: they aren't interested in "; + mes ":: what others have to eat."; + mes ":: I'll see you soon~!"; + mes ":: Dare close the door on me."; + close; + case 2: + mes "[Bookcase Notes]"; + mes "The last time I visited the Alchemist Union, there was an interesting debate on the table."; + mes "I think it was something to do with ^006400Negligence of Homunculus in public places^000000."; + next; + mes "[Bookcase Notes]"; + mes "While the master dozed off,"; + mes "one of the ^FF4800Homunculus^000000 off its leash"; + mes "caused some sort of problem."; + next; + mes "[Bookcase Notes]"; + mes "I will make sure that my Homunculus Jonathan..."; + mes "is trained well not to cause trouble around other people."; + close; + case 3: + mes "[Bookcase Notes]"; + mes "There's a new toy me and ^005DFFJeyna^000000 have grown fond of."; + mes "It's relatively new,"; + mes "called... ^0000FF'Helo'^000000, I think?"; + next; + mes "[Bookcase Notes]"; + mes "There was a related song to it, sung by some ^57007FMinstrel^000000."; + mes "The lyrics were something like ^006400'Ahhh~Ahh~Ahhhhhhhh'^000000."; + next; + mes "[Bookcase Notes]"; + mes "The entertainment itself is fun,"; + mes "but the music is also excellent,"; + mes "and when I listen to it"; + mes "it feels like my SP is restored significantly."; + next; + mes "[Bookcase Notes]"; + mes "I must say,"; + mes "entertainment is crucial when resting"; + mes "to boost morale for research."; + mes "^006400For Homunculus~!^000000"; + close; + case 4: + mes "[Bookcase Notes]"; + mes "From what I heard from the union member"; + mes "^005DFFParmy^000000,"; + mes "^005DFFRaspuchin^000000 is still his own weird self."; + next; + mes "[Bookcase Notes]"; + mes "It may not be such a good idea"; + mes "to drive those energetic souls"; + mes "coming to change jobs"; + mes "with such enthusiasm."; + close; + case 5: + mes "[Bookcase Notes]"; + mes "A friend of mine who was into painting,"; + mes "suggested making a <Graphic Novel> called"; + mes "^0000FFMUTATIONER^000000"; + mes "after he heard about my research"; + mes "and my works."; + next; + mes "[Bookcase Notes]"; + mes "The story begins..."; + mes "With an alien"; + mes "^FF4800Homunculus^000000"; + mes "visiting our world."; + next; + mes "[Bookcase Notes]"; + mes "The visiting alien"; + mes "^FF4800Homunculus^000000 can survive"; + mes "without a master"; + mes "and it could change into"; + mes "various creatures that"; + mes "roam our world."; + next; + mes "[Bookcase Notes]"; + mes "These alien^FF4800Homunculus^000000"; + mes "have two opposing factions"; + mes "divided by political differences."; + mes "In our world, we call them"; + mes "^006400Aut-homun^000000 and "; + mes "^006400Decept-homun^000000"; + next; + mes "[Bookcase Notes]"; + mes "The ^006400Aut-homun^000000 are our friends."; + mes "Their leader,"; + mes "called ^005DFFOptimus Poring^000000,"; + mes "is built and so cool"; + mes "for a poring,"; + mes "and it summons a cart at will!"; + next; + mes "[Bookcase Notes]"; + mes "The opposing side, the ^006400Decept-homun^000000,"; + mes "is led by ^005DFFMegatroll^000000"; + mes "and they use all means "; + mes "to destroy our world."; + next; + mes "[Bookcase Notes]"; + mes "The hero of this story"; + mes "is one from ^8B4513Alberta^000000 called ^005DFFJam Wicky^000000,"; + mes "who meets ^005DFFOptimus Poring^000000"; + mes "while shopping for a cart,"; + mes "as if it was his destiny."; + next; + mes "[Bookcase Notes]"; + mes "And so thus"; + mes "unfolds an epic battle"; + mes "in the ^8B4513Moroc Desert^000000"; + mes "where the fate of our world"; + mes "lies in his hands..."; + next; + mes "[Bookcase Notes]"; + mes "Enough of that~!"; + mes "The rest of the story can be"; + mes "checked in the published copy."; + mes "^0000FFMUTATIONER^000000"; + mes "It's going to be awesome~!"; + close; + case 6: + mes "[Bookcase Notes]"; + mes "The Union sent a special gift to its members."; + mes "It's called a ^0000FFHigh Clip 4^000000."; + next; + mes "[Bookcase Notes]"; + mes "It is originally used as a tool to allow easy whispering between members, but it also has other useful functions."; + next; + mes "[Bookcase Notes]"; + mes "A guild invented this. I recall that their emblem had an image of an apple."; + close; + case 7: + mes "[Bookcase Notes]"; + mes "Homunculus is indeed worthy."; + mes "However, like everyone else, I sometimes question its meaning and future."; + next; + mes "[Bookcase Notes]"; + mes "I believe that life given by nature was supposed to be used for oneself."; + mes "However..."; + next; + mes "[Bookcase Notes]"; + mes "The research to give the Homunculus life is, in reality, for the benefit of man."; + mes "Perhaps mankind is not ready ethically to create life."; + close; + case 8: + mes "[Bookcase Notes]"; + mes "Some time ago, ^005DFFJeyna^000000 introduced me to someone."; + mes "She is from ^8B4513Geffen^000000,"; + mes "and she introduced herself as a ^005DFFChicken Researcher^000000."; + next; + mes "[Bookcase Notes]"; + mes "She is an expert on something called the ^006400Legendary Bijofnil^000000."; + mes "She finds it offensive that people think that the Bijofnil is a hawk."; + next; + mes "[Bookcase Notes]"; + mes "She said something about somewhere in ^8B4513Hvergilmir's Fountain^000000"; + mes "there exists a ^005DFFtalking chicken^000000 and other stories..."; + mes "Well, it went on like that"; + mes "and it was interesting."; + close; + } +} + +// Notifiers +//============================================================ +que_house_s,11,52,3 script #03homun_s 111,{ + end; +OnInit: + initnpctimer; + end; +OnTimer6000: + emotion e_gasp; + end; +OnTimer7000: + emotion e_gasp,0,"#04homun_s"; + stopnpctimer; + initnpctimer; + end; +} + +que_house_s,14,52,3 script #04homun_s 111,{ + end; +} + +// Researcher's Pet +//============================================================ +que_house_s,24,46,3 script Jonathan#homun_s 6002,{ + end; +} + +que_house_s,23,46,3 script #05homun_s 111,{ + emotion e_no,0,"Jonathan#homun_s"; + if (gethominfo(1) < 6048 || gethominfo(1) > 6052) { // Not mutated Homunculus-S + mes "[Jonathan]"; + mes "Hwang~ Hwang!"; + next; + mes ":: It seems to be Viorel's"; + mes ":: Homunculus."; + mes ":: It is wearing a small necklace"; + mes ":: with the name Jonathan engraved"; + mes ":: on it."; + close; + } else { + mes "[Jonathan]"; + mes "Hwang~?!"; + next; + emotion e_swt2,0,"Jonathan#homun_s"; + mes "[Jonathan]"; + mes "*Sniff* ..."; + next; + mes ":: This Amistr"; + mes ":: called Jonathan"; + mes ":: seems to be surprised by my"; + mes ":: new Homunculus."; + close; + } +}
\ No newline at end of file diff --git a/npc/re/scripts.conf b/npc/re/scripts.conf index e3b683a34..86cf10d28 100644 --- a/npc/re/scripts.conf +++ b/npc/re/scripts.conf @@ -88,7 +88,7 @@ npc: npc/re/quests/eden/eden_service.txt npc: npc/re/quests/eden/eden_tutorial.txt // -------------------------------------------------------------- //npc: npc/re/quests/cupet.txt -npc: npc/re/quests/homu_s.txt +npc: npc/re/quests/homun_s.txt npc: npc/re/quests/magic_books.txt npc: npc/re/quests/mrsmile.txt npc: npc/re/quests/pile_bunker.txt diff --git a/sql-files/main.sql b/sql-files/main.sql index 0e9dc5b67..1f654ed14 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -657,6 +657,8 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1362794218); INSERT INTO `sql_updates` (`timestamp`) VALUES (1364409316); INSERT INTO `sql_updates` (`timestamp`) VALUES (1366075474); INSERT INTO `sql_updates` (`timestamp`) VALUES (1366078541); +INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728); +INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003); -- -- Table structure for table `sstatus` @@ -691,6 +693,10 @@ CREATE TABLE IF NOT EXISTS `storage` ( KEY `account_id` (`account_id`) ) ENGINE=MyISAM; +-- +-- Table structure for table `interreg` +-- + CREATE TABLE IF NOT EXISTS `interreg` ( `varname` varchar(11) NOT NULL, `value` varchar(20) NOT NULL, @@ -698,3 +704,14 @@ CREATE TABLE IF NOT EXISTS `interreg` ( ) ENGINE=InnoDB; INSERT INTO `interreg` (`varname`, `value`) VALUES ('unique_id', '0'); + +-- +-- Table structure for table `account_data` +-- + +CREATE TABLE IF NOT EXISTS `account_data` ( + `account_id` int(11) unsigned NOT NULL default '0', + `bank_vault` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`account_id`) +) ENGINE=MyISAM; + diff --git a/sql-files/upgrades/2013-10-09--21-38.sql b/sql-files/upgrades/2013-10-09--21-38.sql new file mode 100644 index 000000000..fee85c40b --- /dev/null +++ b/sql-files/upgrades/2013-10-09--21-38.sql @@ -0,0 +1,3 @@ +#1381354728 +ALTER TABLE `zenylog` MODIFY `type` enum('T','V','P','M','S','N','D','C','A','E','I','B','K') NOT NULL DEFAULT 'S'; +INSERT INTO `sql_updates` (`timestamp`) VALUES (1381354728);
\ No newline at end of file diff --git a/sql-files/upgrades/2013-10-10--16-36.sql b/sql-files/upgrades/2013-10-10--16-36.sql new file mode 100644 index 000000000..784449898 --- /dev/null +++ b/sql-files/upgrades/2013-10-10--16-36.sql @@ -0,0 +1,7 @@ +#1381423003 +CREATE TABLE IF NOT EXISTS `account_data` ( + `account_id` int(11) unsigned NOT NULL default '0', + `bank_vault` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`account_id`) +) ENGINE=MyISAM; +INSERT INTO `sql_updates` (`timestamp`) VALUES (1381423003);
\ No newline at end of file diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt index 984898b22..2996a07f0 100644 --- a/sql-files/upgrades/index.txt +++ b/sql-files/upgrades/index.txt @@ -4,3 +4,5 @@ 2013-03-06--00-00.sql 2013-03-09--01-56.sql 2013-04-16--01-24.sql +2013-10-09--21-38.sql +2013-10-10--16-36.sql
\ No newline at end of file diff --git a/src/char/char.c b/src/char/char.c index 7a948398c..5a51130de 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -70,6 +70,7 @@ char mercenary_owner_db[256] = "mercenary_owner"; char ragsrvinfo_db[256] = "ragsrvinfo"; char elemental_db[256] = "elemental"; char interreg_db[32] = "interreg"; +char account_data_db[256] = "account_data"; // show loading/saving messages int save_log = 1; @@ -497,6 +498,14 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) } else strcat(save_status, " status"); } + + if( p->bank_vault != cp->bank_vault ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`bank_vault`) VALUES ('%d','%d')",account_data_db,p->account_id,p->bank_vault) ) { + Sql_ShowDebug(sql_handle); + errors++; + } else + strcat(save_status, " bank"); + } //Values that will seldom change (to speed up saving) if ( @@ -675,6 +684,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) strcat(save_status, " hotkeys"); } #endif + StrBuf->Destroy(&buf); if (save_status[0]!='\0' && save_log) ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status); @@ -1085,6 +1095,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything int hotkey_num; #endif unsigned int opt; + int account_id; memset(p, 0, sizeof(struct mmo_charstatus)); @@ -1174,6 +1185,9 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything SQL->StmtFree(stmt); return 0; } + + account_id = p->account_id; + p->last_point.map = mapindex_name2id(last_map); p->save_point.map = mapindex_name2id(save_map); @@ -1338,6 +1352,15 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything mercenary_owner_fromsql(char_id, p); strcat(t_msg, " mercenary"); + //`account_data` (`account_id`,`bank_vault`) + if( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `bank_vault` FROM `%s` WHERE `account_id`=? LIMIT 1", account_data_db) + || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &account_id, 0) + || SQL_ERROR == SQL->StmtExecute(stmt) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &p->bank_vault, 0, NULL, NULL) ) + SqlStmt_ShowDebug(stmt); + + if( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) + strcat(t_msg, " bank"); if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg); //ok. all data load successfuly! SQL->StmtFree(stmt); @@ -4721,6 +4744,8 @@ void sql_config_read(const char* cfgName) safestrncpy(elemental_db,w2,sizeof(elemental_db)); else if(!strcmpi(w1,"interreg_db")) safestrncpy(interreg_db,w2,sizeof(interreg_db)); + else if(!strcmpi(w1,"account_data_db")) + safestrncpy(account_data_db,w2,sizeof(account_data_db)); //support the import command, just like any other config else if(!strcmpi(w1,"import")) sql_config_read(w2); diff --git a/src/common/mmo.h b/src/common/mmo.h index 205cf8425..ccba0fa7f 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -90,6 +90,10 @@ //Max amount of a single stacked item #define MAX_AMOUNT 30000 #define MAX_ZENY 1000000000 + +//Official Limit: 2.1b ( the var that stores the money doesn't go much higher than this by default ) +#define MAX_BANK_ZENY 2100000000 + #define MAX_FAME 1000000000 #define MAX_CART 100 #define MAX_SKILL 1478 @@ -366,6 +370,7 @@ struct mmo_charstatus { unsigned int base_exp,job_exp; int zeny; + int bank_vault; short class_; unsigned int status_point,skill_point; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3d04a6bff..10c96e317 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6869,7 +6869,7 @@ ACMD(makehomun) { homunid = atoi(message); if( homunid == -1 && sd->status.hom_id && !homun_alive(sd->hd) ) { - if( !sd->hd->homunculus.vaporize ) + if( sd->hd->homunculus.vaporize ) homun->ressurect(sd, 100, sd->bl.x, sd->bl.y); else homun->call(sd); @@ -7956,10 +7956,14 @@ ACMD(feelreset) /*========================================== * AUCTION SYSTEM *------------------------------------------*/ -ACMD(auction) -{ +ACMD(auction) { nullpo_ret(sd); + if( !battle_config.feature_auction ) { + clif->colormes(sd->fd,COLOR_RED,msg_txt(1484)); + return false; + } + clif->auction_openwindow(sd); return true; diff --git a/src/map/battle.c b/src/map/battle.c index 928d14c22..ef62eb1d2 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6474,6 +6474,10 @@ static const struct _battle_data { { "client_accept_chatdori", &battle_config.client_accept_chatdori, 0, 0, INT_MAX, }, { "snovice_call_type", &battle_config.snovice_call_type, 0, 0, 1, }, { "guild_notice_changemap", &battle_config.guild_notice_changemap, 2, 0, 2, }, + { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, + { "feature.auction", &battle_config.feature_auction, 0, 0, 2, }, + + }; #ifndef STATS_OPT_OUT /** @@ -6695,6 +6699,22 @@ void battle_adjust_conf(void) { battle_config.feature_search_stores = 0; } #endif + +#if PACKETVER < 20130724 + if( battle_config.feature_banking ) { + ShowWarning("conf/battle/feature.conf banking is enabled but it requires PACKETVER 2013-07-24 or newer, disabling...\n"); + battle_config.feature_banking = 0; + } +#endif + +#if PACKETVER > 20120000 && PACKETVER < 20130515 /* exact date (when it started) not known */ + if( battle_config.feature_auction == 1 ) { + ShowWarning("conf/battle/feature.conf:feature.auction is enabled but it is not stable on PACKETVER "EXPAND_AND_QUOTE(PACKETVER)", disabling...\n"); + ShowWarning("conf/battle/feature.conf:feature.auction change value to '2' to silence this warning and maintain it enabled\n"); + battle_config.feature_auction = 0; + } +#endif + #ifndef CELL_NOSTACK if (battle_config.cell_stack_limit != 1) diff --git a/src/map/battle.h b/src/map/battle.h index 6d5d5f186..533fa40b0 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -461,6 +461,8 @@ struct Battle_Config { int snovice_call_type; int guild_notice_changemap; + int feature_banking; + int feature_auction; } battle_config; // Dammage delayed info diff --git a/src/map/clif.c b/src/map/clif.c index 357c4dc6a..823a44956 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -61,10 +61,11 @@ struct clif_interface clif_s; //Converts item type in case of pet eggs. static inline int itemtype(int type) { - switch( type ){ + switch( type ) { #if PACKETVER >= 20080827 case IT_WEAPON: return IT_ARMOR; case IT_ARMOR: + case IT_PETARMOR: #endif case IT_PETEGG: return IT_WEAPON; default: return type; @@ -1378,7 +1379,7 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag) WBUFW(buf,0)=0x22e; memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH); // Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true) - WBUFB(buf,26)=(battle_config.hom_rename?0:hd->homunculus.rename_flag) | (hd->homunculus.vaporize << 1) | (hd->homunculus.hp?0:4); + WBUFB(buf,26)=(battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0); WBUFW(buf,27)=hd->homunculus.level; WBUFW(buf,29)=hd->homunculus.hunger; WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ; @@ -14987,6 +14988,9 @@ void clif_Auction_openwindow(struct map_session_data *sd) if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading ) return; + if( !battle_config.feature_auction ) + return; + WFIFOHEAD(fd,packet_len(0x25f)); WFIFOW(fd,0) = 0x25f; WFIFOL(fd,2) = 0; @@ -15076,6 +15080,9 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd) int amount = RFIFOL(fd,4); // Always 1 struct item_data *item; + if( !battle_config.feature_auction ) + return; + if( sd->auction.amount > 0 ) sd->auction.amount = 0; @@ -15151,6 +15158,9 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) struct auction_data auction; struct item_data *item; + if( !battle_config.feature_auction ) + return; + auction.price = RFIFOL(fd,2); auction.buynow = RFIFOL(fd,6); auction.hours = RFIFOW(fd,10); @@ -15282,6 +15292,9 @@ void clif_parse_Auction_search(int fd, struct map_session_data* sd) short type = RFIFOW(fd,2), page = RFIFOW(fd,32); int price = RFIFOL(fd,4); // FIXME: bug #5071 + if( !battle_config.feature_auction ) + return; + clif->pAuction_cancelreg(fd, sd); safestrncpy(search_text, (char*)RFIFOP(fd,8), sizeof(search_text)); @@ -15297,6 +15310,10 @@ void clif_parse_Auction_search(int fd, struct map_session_data* sd) void clif_parse_Auction_buysell(int fd, struct map_session_data* sd) { short type = RFIFOW(fd,2) + 6; + + if( !battle_config.feature_auction ) + return; + clif->pAuction_cancelreg(fd, sd); intif->Auction_requestlist(sd->status.char_id, type, 0, "", 1); @@ -17725,6 +17742,79 @@ void clif_cart_additem_ack(struct map_session_data *sd, int flag) { clif->send(&p,sizeof(p), &sd->bl, SELF); } +/* Bank System [Yommy/Hercules] */ +void clif_parse_BankDeposit(int fd, struct map_session_data* sd) { + struct packet_banking_deposit_req *p = P2PTR(fd); + int money; + + if( !battle_config.feature_banking ) { + clif->colormes(fd,COLOR_RED,msg_txt(1483)); + return; + } + + money = (int)cap_value(p->Money,0,INT_MAX); + + pc->bank_deposit(sd,money); +} + +void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) { + struct packet_banking_withdraw_req *p = P2PTR(fd); + int money; + + if( !battle_config.feature_banking ) { + clif->colormes(fd,COLOR_RED,msg_txt(1483)); + return; + } + + money = (int)cap_value(p->Money,0,INT_MAX); + + pc->bank_withdraw(sd,money); +} + +void clif_parse_BankCheck(int fd, struct map_session_data* sd) { + struct packet_banking_check p; + + if( !battle_config.feature_banking ) { + clif->colormes(fd,COLOR_RED,msg_txt(1483)); + return; + } + + p.PacketType = banking_checkType; + p.Money = (int)sd->status.bank_vault; + p.Reason = (short)0; + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} + +void clif_parse_BankOpen(int fd, struct map_session_data* sd) { + return; +} + +void clif_parse_BankClose(int fd, struct map_session_data* sd) { + return; +} + +void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) { + struct packet_banking_deposit_ack p; + + p.PacketType = banking_deposit_ackType; + p.Balance = sd->status.zeny;/* how much zeny char has after operation */ + p.Money = (int64)sd->status.bank_vault;/* money in the bank */ + p.Reason = (short)reason; + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} +void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) { + struct packet_banking_withdraw_ack p; + + p.PacketType = banking_withdraw_ackType; + p.Balance = sd->status.zeny;/* how much zeny char has after operation */ + p.Money = (int64)sd->status.bank_vault;/* money in the bank */ + p.Reason = (short)reason; + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} + /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -17735,10 +17825,6 @@ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { unsigned short clif_parse_cmd_normal( int fd, struct map_session_data *sd ) { unsigned short cmd = RFIFOW(fd,0); - // filter out invalid / unsupported packets - if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) - return 0; - return cmd; } unsigned short clif_parse_cmd_decrypt( int fd, struct map_session_data *sd ) { @@ -17746,10 +17832,6 @@ unsigned short clif_parse_cmd_decrypt( int fd, struct map_session_data *sd ) { cmd = clif->decrypt_cmd(cmd, sd); - // filter out invalid / unsupported packets - if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) - return 0; - return cmd; } unsigned short clif_parse_cmd_optional( int fd, struct map_session_data *sd ) { @@ -17824,7 +17906,10 @@ int clif_parse(int fd) { else parse_cmd_func = clif->parse_cmd; - if( !( cmd = parse_cmd_func(fd,sd) ) ) { + cmd = parse_cmd_func(fd,sd); + + // filter out invalid / unsupported packets + if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) { ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x (0x%04x), %d bytes received), disconnecting session #%d.\n", cmd, RFIFOW(fd,0), RFIFOREST(fd), fd); #ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); @@ -18523,6 +18608,9 @@ void clif_defaults(void) { clif->chsys_quitg = clif_hercules_chsys_quitg; clif->chsys_gjoin = clif_hercules_chsys_gjoin; clif->chsys_gleave = clif_hercules_chsys_gleave; + /* Bank System [Yommy/Hercules] */ + clif->bank_deposit = clif_bank_deposit; + clif->bank_withdraw = clif_bank_withdraw; /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -18745,4 +18833,10 @@ void clif_defaults(void) { clif->pPartyBookingReqVolunteer = clif_parse_PartyBookingReqVolunteer; clif->pPartyBookingRefuseVolunteer = clif_parse_PartyBookingRefuseVolunteer; clif->pPartyBookingCancelVolunteer = clif_parse_PartyBookingCancelVolunteer; + /* Bank System [Yommy/Hercules] */ + clif->pBankDeposit = clif_parse_BankDeposit; + clif->pBankWithdraw = clif_parse_BankWithdraw; + clif->pBankCheck = clif_parse_BankCheck; + clif->pBankOpen = clif_parse_BankOpen; + clif->pBankClose = clif_parse_BankClose; } diff --git a/src/map/clif.h b/src/map/clif.h index 1a2748353..2baca2aaf 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -414,6 +414,19 @@ enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED { BGQND_FAIL_NOT_QUEUING = 11, }; +enum e_BANKING_DEPOSIT_ACK { + BDA_SUCCESS = 0x0, + BDA_ERROR = 0x1, + BDA_NO_MONEY = 0x2, + BDA_OVERFLOW = 0x3, +}; +enum e_BANKING_WITHDRAW_ACK { + BWA_SUCCESS = 0x0, + BWA_NO_MONEY = 0x1, + BWA_UNKNOWN_ERROR = 0x2, +}; + + /** * Structures **/ @@ -964,6 +977,9 @@ struct clif_interface { void (*chsys_quitg) (struct map_session_data *sd); void (*chsys_gjoin) (struct guild *g1,struct guild *g2); void (*chsys_gleave) (struct guild *g1,struct guild *g2); + /* Bank System [Yommy/Hercules] */ + void (*bank_deposit) (struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason); + void (*bank_withdraw) (struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason); /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -1184,6 +1200,12 @@ struct clif_interface { void (*pPartyBookingReqVolunteer) (int fd, struct map_session_data *sd); void (*pPartyBookingRefuseVolunteer) (int fd, struct map_session_data *sd); void (*pPartyBookingCancelVolunteer) (int fd, struct map_session_data *sd); + /* Bank System [Yommy/Hercules] */ + void (*pBankDeposit) (int fd, struct map_session_data *sd); + void (*pBankWithdraw) (int fd, struct map_session_data *sd); + void (*pBankCheck) (int fd, struct map_session_data *sd); + void (*pBankOpen) (int fd, struct map_session_data *sd); + void (*pBankClose) (int fd, struct map_session_data *sd); }; struct clif_interface *clif; diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 45e9af2b0..1e47053fe 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -134,25 +134,25 @@ int homunculus_dead(struct homun_data *hd) { } //Vaporize a character's homun. If flag, HP needs to be 80% or above. -int homunculus_vaporize(struct map_session_data *sd, int flag) { +int homunculus_vaporize(struct map_session_data *sd, enum homun_state flag) { struct homun_data *hd; nullpo_ret(sd); hd = sd->hd; - if (!hd || hd->homunculus.vaporize) + if (!hd || hd->homunculus.vaporize != HOM_ST_ACTIVE) return 0; if (status->isdead(&hd->bl)) return 0; //Can't vaporize a dead homun. - if (flag && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80) + if (flag == HOM_ST_REST && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80) return 0; hd->regen.state.block = 3; //Block regen while vaporized. //Delete timers when vaporized. homun->hunger_timer_delete(hd); - hd->homunculus.vaporize = 1; + hd->homunculus.vaporize = flag; if(battle_config.hom_setting&0x40) memset(hd->blockskill, 0, sizeof(hd->blockskill)); clif->hominfo(sd, sd->hd, 0); @@ -260,7 +260,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) { int i = 0 ; nullpo_retv(hd); - if(hd->homunculus.vaporize) + if(hd->homunculus.vaporize != HOM_ST_ACTIVE) return; i = skill_id - HM_SKILLBASE; @@ -471,7 +471,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) { int homunculus_gainexp(struct homun_data *hd,unsigned int exp) { enum homun_type htype; - if(hd->homunculus.vaporize) + if(hd->homunculus.vaporize != HOM_ST_ACTIVE) return 1; if( (htype = homun->class2type(hd->homunculus.class_)) == HT_INVALID ) { @@ -571,7 +571,7 @@ unsigned char homunculus_menu(struct map_session_data *sd,unsigned char menu_num bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) { int i, foodID, emotion; - if(hd->homunculus.vaporize) + if(hd->homunculus.vaporize == HOM_ST_REST) return false; foodID = hd->homunculusDB->foodID; @@ -781,11 +781,11 @@ bool homunculus_call(struct map_session_data *sd) { hd = sd->hd; - if (!hd->homunculus.vaporize) + if (hd->homunculus.vaporize != HOM_ST_REST) return false; //Can't use this if homun wasn't vaporized. homun->init_timers(hd); - hd->homunculus.vaporize = 0; + hd->homunculus.vaporize = HOM_ST_ACTIVE; if (hd->bl.prev == NULL) { //Spawn him hd->bl.x = sd->bl.x; hd->bl.y = sd->bl.y; @@ -833,7 +833,7 @@ bool homunculus_recv_data(int account_id, struct s_homunculus *sh, int flag) { homun->create(sd, sh); hd = sd->hd; - if(hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL) { + if(hd && hd->homunculus.hp && hd->homunculus.vaporize == HOM_ST_ACTIVE && hd->bl.prev == NULL && sd->bl.prev != NULL) { enum homun_type htype = homun->class2type(hd->homunculus.class_); map->addblock(&hd->bl); @@ -908,7 +908,7 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short hd = sd->hd; - if (hd->homunculus.vaporize) + if (hd->homunculus.vaporize != HOM_ST_ACTIVE) return false; // vaporized homunculi need to be 'called' if (!status->isdead(&hd->bl)) diff --git a/src/map/homunculus.h b/src/map/homunculus.h index 9562ed5c3..2cb558930 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -11,7 +11,7 @@ #define MAX_HOM_SKILL_REQUIRE 5 #define homdb_checkid(id) (id >= HM_CLASS_BASE && id <= HM_CLASS_MAX) -#define homun_alive(x) ((x) && (x)->homunculus.vaporize != 1 && (x)->battle_status.hp > 0) +#define homun_alive(x) ((x) && (x)->homunculus.vaporize == HOM_ST_ACTIVE && (x)->battle_status.hp > 0) struct h_stats { unsigned int HP, SP; @@ -44,6 +44,12 @@ enum { SP_HUNGRY = 0x2, }; +enum homun_state { + HOM_ST_ACTIVE = 0,/* either alive or dead */ + HOM_ST_REST = 1,/* is resting (vaporized) */ + HOM_ST_MORPH = 2,/* in morph state */ +}; + struct homun_data { struct block_list bl; struct unit_data ud; @@ -94,7 +100,7 @@ struct homunculus_interface { enum homun_type (*class2type) (int class_); void (*damaged) (struct homun_data *hd); int (*dead) (struct homun_data *hd); - int (*vaporize) (struct map_session_data *sd, int flag); + int (*vaporize) (struct map_session_data *sd, enum homun_state flag); int (*delete) (struct homun_data *hd, int emote); int (*checkskill) (struct homun_data *hd, uint16 skill_id); int (*calc_skilltree) (struct homun_data *hd, int flag_evolve); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index fe2c43fcc..09eec557d 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1704,12 +1704,11 @@ int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) * Reading item from item db * item_db2 overwriting item_db *------------------------------------------*/ -int itemdb_readdb(void) -{ +int itemdb_readdb(void) { const char* filename[] = { DBPATH"item_db.txt", "item_db2.txt" }; - + bool duplicate[MAX_ITEMDB]; int fi; for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) { @@ -1726,11 +1725,13 @@ int itemdb_readdb(void) continue; } + memset(&duplicate,0,sizeof(duplicate)); + // process rows one by one while(fgets(line, sizeof(line), fp)) { char *str[32], *p; - int i; + int i, id = 0; lines++; if(line[0] == '/' && line[1] == '/') continue; @@ -1807,9 +1808,14 @@ int itemdb_readdb(void) } } - if (!itemdb->parse_dbrow(str, filepath, lines, 0)) + if (!(id = itemdb->parse_dbrow(str, filepath, lines, 0))) continue; + if( duplicate[id] ) { + ShowWarning("itemdb_readdb:%s: duplicate entry of ID #%d (%s/%s)\n",filename[fi],id,itemdb_name(id),itemdb_jname(id)); + } else + duplicate[id] = true; + count++; } @@ -1836,7 +1842,7 @@ int itemdb_read_sqldb(void) { for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) { uint32 count = 0; - + // retrieve all rows from the item database if( SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) ) { Sql_ShowDebug(map->mysql_handle); @@ -1856,6 +1862,7 @@ int itemdb_read_sqldb(void) { if (!itemdb->parse_dbrow(str, item_db_name[fi], -(atoi(str[0])), SCRIPT_IGNORE_EXTERNAL_BRACKETS)) continue; + ++count; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index fe67ebbef..0f46c1c01 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -40,6 +40,7 @@ enum item_itemid { ITEMID_RED_GEMSTONE = 716, ITEMID_BLUE_GEMSTONE = 717, ITEMID_TRAP = 1065, + ITEMID_STRANGE_EMBRYO = 6415, ITEMID_FACE_PAINT = 6120, ITEMID_STONE = 7049, ITEMID_SKULL_ = 7420, diff --git a/src/map/log.c b/src/map/log.c index e33240505..19a98f34b 100644 --- a/src/map/log.c +++ b/src/map/log.c @@ -40,6 +40,7 @@ char log_picktype2char(e_log_pick_type type) { case LOG_TYPE_AUCTION: return 'I'; // Auct(I)on case LOG_TYPE_BUYING_STORE: return 'B'; // (B)uying Store case LOG_TYPE_LOOT: return 'L'; // (L)oot (consumed monster pick/drop) + case LOG_TYPE_BANK: return 'K'; // Ban(K) Transactions case LOG_TYPE_OTHER: return 'X'; // Other } diff --git a/src/map/log.h b/src/map/log.h index 07606c8ef..9864a54d7 100644 --- a/src/map/log.h +++ b/src/map/log.h @@ -60,6 +60,7 @@ typedef enum e_log_pick_type { LOG_TYPE_AUCTION = 0x04000, LOG_TYPE_BUYING_STORE = 0x08000, LOG_TYPE_OTHER = 0x10000, + LOG_TYPE_BANK = 0x20000, // combinations LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME, // all diff --git a/src/map/packets.h b/src/map/packets.h index c91b5d50c..918f0a10f 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2375,6 +2375,21 @@ packet(0x020d,-1); packet(0x0930,36,clif->pStoragePassword,0); #endif +/* Bank System [Yommy/Hercules] */ +#if PACKETVER >= 20130724 + packet(0x09A6,12); // ZC_BANKING_CHECK + packet(0x09A7,10,clif->pBankDeposit,2,4,6); + packet(0x09A8,16); // ZC_ACK_BANKING_DEPOSIT + packet(0x09A9,10,clif->pBankWithdraw,2,4,6); + packet(0x09AA,16); // ZC_ACK_BANKING_WITHDRAW + packet(0x09AB,6,clif->pBankCheck,2,4); + //// + packet(0x09B6,6,clif->pBankOpen,2,4); + packet(0x09B7,4); // ZC_ACK_OPEN_BANKING + packet(0x09B8,6,clif->pBankClose,2,4); + packet(0x09B9,4); // ZC_ACK_CLOSE_BANKING +#endif + //2013-07-03Ragexe (Shakto) #if PACKETVER >= 20130703 packet(0x0930,5,clif->pChangeDir,2,4); diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index f39b4a55b..9d7282c92 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -18,6 +18,9 @@ struct EQUIPSLOTINFO { * **/ enum packet_headers { + banking_withdraw_ackType = 0x9aa, + banking_deposit_ackType = 0x9a8, + banking_checkType = 0x9a6, cart_additem_ackType = 0x12c, sc_notickType = 0x196, #if PACKETVER < 20061218 @@ -543,6 +546,38 @@ struct packet_cart_additem_ack { char result; } __attribute__((packed)); +struct packet_banking_check { + short PacketType; + int64 Money; + short Reason; +} __attribute__((packed)); + +struct packet_banking_deposit_req { + short PacketType; + unsigned int AID; + int Money; +} __attribute__((packed)); + +struct packet_banking_withdraw_req { + short PacketType; + unsigned int AID; + int Money; +} __attribute__((packed)); + +struct packet_banking_deposit_ack { + short PacketType; + short Reason; + int64 Money; + int Balance; +} __attribute__((packed)); + +struct packet_banking_withdraw_ack { + short PacketType; + short Reason; + int64 Money; + int Balance; +} __attribute__((packed)); + #pragma pack(pop) #endif /* _PACKETS_STRUCT_H_ */ diff --git a/src/map/pc.c b/src/map/pc.c index 6b7d6c735..157d9e28a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6438,7 +6438,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) pc->setoption(sd, i); if( homun_alive(sd->hd) && pc->checkskill(sd, AM_CALLHOMUN) ) - homun->vaporize(sd, 0); + homun->vaporize(sd, HOM_ST_ACTIVE); } for( i = 1; i < MAX_SKILL; i++ ) { @@ -6663,7 +6663,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { if (sd->status.hom_id > 0){ if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE]) - homun->vaporize(sd, 0); + homun->vaporize(sd, HOM_ST_ACTIVE); } if( sd->md ) @@ -7588,7 +7588,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) pc->setoption(sd, i); if(homun_alive(sd->hd) && !pc->checkskill(sd, AM_CALLHOMUN)) - homun->vaporize(sd, 0); + homun->vaporize(sd, HOM_ST_ACTIVE); if(sd->status.manner < 0) clif->changestatus(sd,SP_MANNER,sd->status.manner); @@ -10079,6 +10079,51 @@ void pc_itemcd_do(struct map_session_data *sd, bool load) { return; } +void pc_bank_deposit(struct map_session_data *sd, int money) { + unsigned int limit_check = money+sd->status.bank_vault; + + if( money <= 0 || limit_check > MAX_BANK_ZENY ) { + clif->bank_deposit(sd,BDA_OVERFLOW); + return; + } else if ( money > sd->status.zeny ) { + clif->bank_deposit(sd,BDA_NO_MONEY); + return; + } + + if( pc->payzeny(sd,money, LOG_TYPE_BANK, NULL) ) + clif->bank_deposit(sd,BDA_NO_MONEY); + else { + sd->status.bank_vault += money; + if( map->save_settings&256 ) + chrif->save(sd,0); + clif->bank_deposit(sd,BDA_SUCCESS); + } +} +void pc_bank_withdraw(struct map_session_data *sd, int money) { + unsigned int limit_check = money+sd->status.zeny; + + if( money <= 0 ) { + clif->bank_withdraw(sd,BWA_UNKNOWN_ERROR); + return; + } else if ( money > sd->status.bank_vault ) { + clif->bank_withdraw(sd,BWA_NO_MONEY); + return; + } else if ( limit_check > MAX_ZENY ) { + /* no official response for this scenario exists. */ + clif->colormes(sd->fd,COLOR_RED,msg_txt(1482)); + return; + } + + if( pc->getzeny(sd,money, LOG_TYPE_BANK, NULL) ) + clif->bank_withdraw(sd,BWA_NO_MONEY); + else { + sd->status.bank_vault -= money; + if( map->save_settings&256 ) + chrif->save(sd,0); + clif->bank_withdraw(sd,BWA_SUCCESS); + } +} + /*========================================== * pc Init/Terminate *------------------------------------------*/ @@ -10402,4 +10447,7 @@ void pc_defaults(void) { pc->checkcombo = pc_checkcombo; pc->calcweapontype = pc_calcweapontype; pc->removecombo = pc_removecombo; + + pc->bank_withdraw = pc_bank_withdraw; + pc->bank_deposit = pc_bank_deposit; } diff --git a/src/map/pc.h b/src/map/pc.h index fadb922b5..f770818c2 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -961,6 +961,9 @@ struct pc_interface { int (*checkcombo) (struct map_session_data *sd, struct item_data *data ); int (*calcweapontype) (struct map_session_data *sd); int (*removecombo) (struct map_session_data *sd, struct item_data *data ); + + void (*bank_deposit) (struct map_session_data *sd, int money); + void (*bank_withdraw) (struct map_session_data *sd, int money); }; struct pc_interface *pc; diff --git a/src/map/script.c b/src/map/script.c index 8460b23b0..1bedb78b6 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6780,7 +6780,7 @@ BUILDIN(strnpcinfo) { } /*========================================== - * GetEquipID(Pos); Pos: 1-10 + * GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE *------------------------------------------*/ BUILDIN(getequipid) { @@ -9564,44 +9564,82 @@ BUILDIN(homunculus_evolution) /*========================================== * [Xantara] + * Checks for vaporized morph state + * and deletes ITEMID_STRANGE_EMBRYO. *------------------------------------------*/ BUILDIN(homunculus_mutate) { int homun_id; enum homun_type m_class, m_id; TBL_PC *sd; + bool success = false; sd = script->rid2sd(st); if( sd == NULL || sd->hd == NULL ) return true; - - if( script_hasdata(st,2) ) - homun_id = script_getnum(st,2); - else - homun_id = 6048 + (rnd() % 4); - - if( homun_alive(sd->hd) ) { + + if( sd->hd->homunculus.vaporize == HOM_ST_MORPH ) { + int i = pc->search_inventory(sd, ITEMID_STRANGE_EMBRYO); + if( script_hasdata(st,2) ) + homun_id = script_getnum(st,2); + else + homun_id = 6048 + (rnd() % 4); + m_class = homun->class2type(sd->hd->homunculus.class_); m_id = homun->class2type(homun_id); - if( m_class != HT_INVALID && m_id != HT_INVALID && m_class == HT_EVO && m_id == HT_S && sd->hd->homunculus.level >= 99 ) + if( m_class == HT_EVO && m_id == HT_S && + sd->hd->homunculus.level >= 99 && i >= 0 && + !pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_SCRIPT) ) { + sd->hd->homunculus.vaporize = HOM_ST_REST; // Remove morph state. + homun->call(sd); // Respawn homunculus. homun->mutate(sd->hd, homun_id); - else + success = true; + } else clif->emotion(&sd->hd->bl, E_SWT); - } + } else + clif->emotion(&sd->hd->bl, E_SWT); + + script_pushint(st,success?1:0); return true; } -// [Zephyrus] -BUILDIN(homunculus_shuffle) { +/*========================================== + * Puts homunculus into morph state + * and gives ITEMID_STRANGE_EMBRYO. + *------------------------------------------*/ +BUILDIN(homunculus_morphembryo) { + enum homun_type m_class; + int i = 0; TBL_PC *sd; + bool success = false; - sd=script->rid2sd(st); - if( sd == NULL ) + sd = script->rid2sd(st); + if( sd == NULL || sd->hd == NULL ) return true; - if(homun_alive(sd->hd)) - homun->shuffle(sd->hd); + if( homun_alive(sd->hd) ) { + m_class = homun->class2type(sd->hd->homunculus.class_); + + if ( m_class == HT_EVO && sd->hd->homunculus.level >= 99 ) { + struct item item_tmp; + + memset(&item_tmp, 0, sizeof(item_tmp)); + item_tmp.nameid = ITEMID_STRANGE_EMBRYO; + item_tmp.identify = 1; + + if( (i = pc->additem(sd, &item_tmp, 1, LOG_TYPE_SCRIPT)) ) { + clif->additem(sd, 0, 0, i); + clif->emotion(&sd->hd->bl, E_SWT); + } else { + homun->vaporize(sd, HOM_ST_MORPH); + success = true; + } + } else + clif->emotion(&sd->hd->bl, E_SWT); + } else + clif->emotion(&sd->hd->bl, E_SWT); + script_pushint(st, success?1:0); return true; } @@ -9612,21 +9650,29 @@ BUILDIN(homunculus_shuffle) { * 1 = Homunculus is vaporized (rest) * 2 = Homunculus is in morph state *------------------------------------------*/ -BUILDIN(checkhomcall) -{ +BUILDIN(homunculus_checkcall) { TBL_PC *sd = script->rid2sd(st); - TBL_HOM *hd; - if( sd == NULL ) - return false; - - hd = sd->hd; - - if( !hd ) + if( sd == NULL || !sd->hd ) script_pushint(st, -1); else - script_pushint(st, hd->homunculus.vaporize); + script_pushint(st, sd->hd->homunculus.vaporize); + + return true; +} + +// [Zephyrus] +BUILDIN(homunculus_shuffle) { + TBL_PC *sd; + + sd=script->rid2sd(st); + if( sd == NULL ) + return true; + + if(homun_alive(sd->hd)) + homun->shuffle(sd->hd); + return true; } @@ -12166,12 +12212,9 @@ BUILDIN(getpetinfo) BUILDIN(gethominfo) { TBL_PC *sd=script->rid2sd(st); - TBL_HOM *hd; - int type=script_getnum(st,2); + int type = script_getnum(st,2); - hd = sd?sd->hd:NULL; - if(!homun_alive(hd)) - { + if(!sd || !sd->hd) { if (type == 2) script_pushconststr(st,"null"); else @@ -12180,13 +12223,13 @@ BUILDIN(gethominfo) } switch(type){ - case 0: script_pushint(st,hd->homunculus.hom_id); break; - case 1: script_pushint(st,hd->homunculus.class_); break; - case 2: script_pushstrcopy(st,hd->homunculus.name); break; - case 3: script_pushint(st,hd->homunculus.intimacy); break; - case 4: script_pushint(st,hd->homunculus.hunger); break; - case 5: script_pushint(st,hd->homunculus.rename_flag); break; - case 6: script_pushint(st,hd->homunculus.level); break; + case 0: script_pushint(st,sd->hd->homunculus.hom_id); break; + case 1: script_pushint(st,sd->hd->homunculus.class_); break; + case 2: script_pushstrcopy(st,sd->hd->homunculus.name); break; + case 3: script_pushint(st,sd->hd->homunculus.intimacy); break; + case 4: script_pushint(st,sd->hd->homunculus.hunger); break; + case 5: script_pushint(st,sd->hd->homunculus.rename_flag); break; + case 6: script_pushint(st,sd->hd->homunculus.level); break; default: script_pushint(st,0); break; @@ -17655,8 +17698,9 @@ void script_parse_builtin(void) { BUILDIN_DEF(warpportal,"iisii"), BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] BUILDIN_DEF2(homunculus_mutate,"hommutate","?"), + BUILDIN_DEF2(homunculus_morphembryo,"morphembryo",""), + BUILDIN_DEF2(homunculus_checkcall,"checkhomcall",""), BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus] - BUILDIN_DEF(checkhomcall,""), BUILDIN_DEF(eaclass,"?"), //[Skotlex] BUILDIN_DEF(roclass,"i?"), //[Skotlex] BUILDIN_DEF(checkvending,"?"), diff --git a/src/map/skill.c b/src/map/skill.c index 248e19e77..70e946119 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6971,21 +6971,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if(sd) { struct map_session_data *f_sd = pc->get_father(sd); struct map_session_data *m_sd = pc->get_mother(sd); - // if neither was found - if(!f_sd && !m_sd) { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - map->freeblock_unlock(); - return 0; + bool we_baby_parents = false; + if(m_sd && check_distance_bl(bl,&m_sd->bl,AREA_SIZE)) { + sc_start(&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + clif->specialeffect(&m_sd->bl,408,AREA); + we_baby_parents = true; } - status->change_start(bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8); - if (f_sd) { + if(f_sd && check_distance_bl(bl,&f_sd->bl,AREA_SIZE)) { sc_start(&f_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->specialeffect(&f_sd->bl,408,AREA); + we_baby_parents = true; } - if (m_sd) { - sc_start(&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); - clif->specialeffect(&m_sd->bl,408,AREA); + if (!we_baby_parents) { + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + map->freeblock_unlock(); + return 0; } + else status->change_start(bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8); } break; @@ -7516,7 +7518,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AM_REST: if (sd) { - if (homun->vaporize(sd,1)) + if (homun->vaporize(sd,HOM_ST_REST)) clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); else clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); diff --git a/src/map/status.c b/src/map/status.c index 497d02bbf..ae900e04d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -8230,7 +8230,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if( pc_isridingwug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUGRIDER); if( pc_isfalcon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_FALCON); if( sd->status.pet_id > 0 ) pet->menu(sd, 3); - if( homun_alive(sd->hd) ) homun->vaporize(sd,1); + if( homun_alive(sd->hd) ) homun->vaporize(sd,HOM_ST_REST); if( sd->md ) mercenary->delete(sd->md,3); } break; |