diff options
-rw-r--r-- | db/constants.conf | 6 | ||||
-rw-r--r-- | db/quest_db.conf | 4 | ||||
-rw-r--r-- | npc/003-3/malindou.txt | 18 | ||||
-rw-r--r-- | npc/005-5/cynric.txt | 1 | ||||
-rw-r--r-- | npc/006-2-1/chirp.txt | 1 | ||||
-rw-r--r-- | npc/009-3/barzil.txt | 1 | ||||
-rw-r--r-- | npc/012-1/richard.txt | 1 | ||||
-rw-r--r-- | npc/017-1/misc.txt | 1 | ||||
-rw-r--r-- | npc/018-5/storage.txt | 1 | ||||
-rw-r--r-- | npc/020-1/misc.txt | 1 | ||||
-rw-r--r-- | npc/024-3/arauto.txt | 1 | ||||
-rw-r--r-- | npc/025-1/drahcir.txt | 1 | ||||
-rw-r--r-- | npc/027-7/banker.txt | 1 | ||||
-rw-r--r-- | npc/functions/bank.txt | 218 | ||||
-rw-r--r-- | npc/functions/hub.txt | 6 |
15 files changed, 260 insertions, 2 deletions
diff --git a/db/constants.conf b/db/constants.conf index 6c93bb947..540c7b40b 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -2365,6 +2365,12 @@ constants_db: { HCD_MOUBOOTAUR: 9 HCD_MARKET: 10 + comment__: "Merchant Requests" + MERCQ_LETTER: 1 + MERCQ_GOODS: 2 + MERCQ_SCOUT: 3 + MERCQ_NONE: 99 + comment__: "Mirror Lake Server Identifiers" WORLD_ID: 2 MLP_CR: 1 diff --git a/db/quest_db.conf b/db/quest_db.conf index 111ad13e0..b20e4e14d 100644 --- a/db/quest_db.conf +++ b/db/quest_db.conf @@ -108,6 +108,10 @@ quest_db: ( Id: 21 Name: "General_NightInRed" }, +{ + Id: 22 + Name: "General_MerchantRequest" +}, // ID 31 to 50: Candor Quests { diff --git a/npc/003-3/malindou.txt b/npc/003-3/malindou.txt index fb0e48744..bd49b3e11 100644 --- a/npc/003-3/malindou.txt +++ b/npc/003-3/malindou.txt @@ -10,9 +10,27 @@ Banker(.name$, "Tulimshar", 9000); close; +OnScoutPing: + // Check for failure + if (getunittype(MERCHANT_ID) != UNITTYPE_MOB) { + dispbottom l("The associate teleports away to avoid an injury. You have failed the escorting quest."); + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+900; + MERCHANT_ID = 0; + } + // Map fix + getmapxy(.@m$, .@x, .@y, 0); + if (@merc_map$ != .@m$) + unitwarp(MERCHANT_ID, .@m$, .@x, .@y); + // Walk command + unitwalk(MERCHANT_ID, getcharid(3)); + // Continue loop + addtimer(rand2(10000), "Malindou::OnScoutPing"); + end; + OnInit: .sex = G_MALE; .distance = 4; + .bankId = RegisterBank("Tulimshar", 1); // Update handler (use `date +%s` for this) // Current UPDATE value: Qui Jun 7 08:10:55 -03 2018 diff --git a/npc/005-5/cynric.txt b/npc/005-5/cynric.txt index dd60e6043..73585c540 100644 --- a/npc/005-5/cynric.txt +++ b/npc/005-5/cynric.txt @@ -10,6 +10,7 @@ OnInit: .sex = G_MALE; .distance = 4; + .bankId = RegisterBank("Candor", 0); end; } diff --git a/npc/006-2-1/chirp.txt b/npc/006-2-1/chirp.txt index 05de00c8b..26bb2d9a8 100644 --- a/npc/006-2-1/chirp.txt +++ b/npc/006-2-1/chirp.txt @@ -10,6 +10,7 @@ OnInit: .sex = G_OTHER; .distance = 4; + .bankId = RegisterBank("Piou Isles", 0); end; } diff --git a/npc/009-3/barzil.txt b/npc/009-3/barzil.txt index 2f3216d0d..75d2e938a 100644 --- a/npc/009-3/barzil.txt +++ b/npc/009-3/barzil.txt @@ -25,5 +25,6 @@ L_Tier2: OnInit: .sex = G_MALE; .distance = 4; + .bankId = RegisterBank("Halinarzo", 6); end; } diff --git a/npc/012-1/richard.txt b/npc/012-1/richard.txt index 5dc2c31c6..c58070995 100644 --- a/npc/012-1/richard.txt +++ b/npc/012-1/richard.txt @@ -10,5 +10,6 @@ OnInit: .sex = G_MALE; .distance = 4; + .bankId = RegisterBank("Hurnscald", 3); end; } diff --git a/npc/017-1/misc.txt b/npc/017-1/misc.txt index 30efd9ecb..3131fd34c 100644 --- a/npc/017-1/misc.txt +++ b/npc/017-1/misc.txt @@ -152,6 +152,7 @@ OnInit: OnInit: .sex = G_MALE; .distance = 5; + .bankId = RegisterBank("LoF", 4); end; } diff --git a/npc/018-5/storage.txt b/npc/018-5/storage.txt index cd843b785..a6df3853e 100644 --- a/npc/018-5/storage.txt +++ b/npc/018-5/storage.txt @@ -27,5 +27,6 @@ OnInit: .sex = G_OTHER; .distance = 5; + .bankId = RegisterBank("Lilit", 7); end; } diff --git a/npc/020-1/misc.txt b/npc/020-1/misc.txt index f3b24ee0d..88b210407 100644 --- a/npc/020-1/misc.txt +++ b/npc/020-1/misc.txt @@ -113,6 +113,7 @@ OnInit: OnInit: .sex = G_MALE; .distance = 5; + .bankId = RegisterBank("Nivalis", 10); end; } diff --git a/npc/024-3/arauto.txt b/npc/024-3/arauto.txt index 5c6eb6377..862be80a0 100644 --- a/npc/024-3/arauto.txt +++ b/npc/024-3/arauto.txt @@ -11,6 +11,7 @@ OnInit: .sex = G_MALE; .distance = 5; + .bankId = RegisterBank("Frostia", 12); end; } diff --git a/npc/025-1/drahcir.txt b/npc/025-1/drahcir.txt index 72a3b7c76..be8dfe753 100644 --- a/npc/025-1/drahcir.txt +++ b/npc/025-1/drahcir.txt @@ -11,6 +11,7 @@ OnInit: .sex = G_MALE; .distance = 5; + .bankId = RegisterBank("Fortress Town", 19); end; } diff --git a/npc/027-7/banker.txt b/npc/027-7/banker.txt index 0a478f8fa..66e7d2187 100644 --- a/npc/027-7/banker.txt +++ b/npc/027-7/banker.txt @@ -11,6 +11,7 @@ OnInit: .sex = G_MALE; .distance = 4; + .bankId = RegisterBank("Magic Academy", 17); end; } diff --git a/npc/functions/bank.txt b/npc/functions/bank.txt index d4c0d30ce..e6b77be5b 100644 --- a/npc/functions/bank.txt +++ b/npc/functions/bank.txt @@ -195,6 +195,7 @@ function script BKReg { // name, city, price (defaults to 10k) function script Banker { + .@bankId = getvariableofnpc(.bankId, strnpcinfo(0)); mesn getarg(0); mesq l("Welcome! My name is @@, I am a representative of the Merchant Guild on @@.", getarg(0), getarg(1)); next; @@ -212,6 +213,7 @@ function script Banker { rif(REBIRTH, l("I would like to use the Deluxe Storage.")), rif(getcharid(2) > 0, l("I would like to use the Guild Storage.")), l("What is this guild for?"), + rif(.@bankId && Zeny < 50000, l("Can I help the Guild in any way?")), l("Bye."); switch (@menu) { @@ -281,12 +283,16 @@ function script Banker { mes ""; BKInfo(); break; + case 8: + mes ""; + callfunc("MerchantQuest", .@bankId - 1); + break; } - if (@menu != 8) { + if (@menu != 9) { speech S_FIRST_BLANK_LINE | S_LAST_NEXT | S_NO_NPC_NAME, l("Something else?"); } - } while (@menu != 8); + } while (@menu != 9); } closedialog; goodbye; @@ -294,6 +300,214 @@ function script Banker { } +// This function registers a bank for guild purposes +// .bankId = RegisterBank(Town, {Main Quest Stage at which banks become available}) +function script RegisterBank { + array_push($@BANK_NAME$, strnpcinfo(1)); + array_push($@BANK_TOWN$, getarg(0)); + array_push($@BANK_MINLV, getarg(1,1)); + return getarraysize($@BANK_NAME$); // bankId actually is offset in 1 for rif() +} + +// Quests for Banking System, to provide poor players a way for quick bucks +// MerchantQuest(.@bankId) +function script MerchantQuest { + mes ""; + // Quest Type, Quest Data, Quest Timer + .@q=getq(General_MerchantRequest); + .@q2=getq2(General_MerchantRequest); + .@q3=getq3(General_MerchantRequest); + .@id=getarg(0); + + // Cooldown + if (.@q3 > gettimetick(2)) { + mesn $@BANK_NAME$[.@id]; + mesq l("There are no tasks for you right now."); + mesc l("Please come back later, in %s.", FuzzyTime(.@q3)); + next; + return; + } + + // TODO: Submit/Abort current request + switch (.@q) { + case MERCQ_LETTER: + if (.@id == .@q2) { + mesn $@BANK_NAME$[.@id]; + mesq l("Thanks for the letter! Your efforts are greatly appreciated."); + Zeny+=rand2(7, 12) * 57; + getexp 67, 9; + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+1800; + return; + } + else + { + mesn $@BANK_NAME$[.@id]; + mesq l("Current task: Deliver a letter to %s", $@BANK_TOWN$[.@q2]); + next; + select + l("Continue"), + l("Abort") + " ["+l("Change task")+"]"; + mes ""; + if (@menu == 1) + return; + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2); + } + break; + /* ***************************************** */ + case MERCQ_GOODS: + .@cont=ASK_NO; + if (countitem(.@q2)) { + mesc l("Deliver %s?", getitemlink(.@q2)); + .@cont=askyesno(); + } + if (.@cont == ASK_YES) { + mesn $@BANK_NAME$[.@id]; + mesq l("Thanks for the %s! Your efforts are greatly appreciated.", getitemlink(.@q2)); + delitem .@q2, 1; + .@price = getiteminfo(.@q2, ITEMINFO_SELLPRICE); + Zeny+=.@price + rand2(12, 18) * 57; + getexp 120, 18; + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+7200; + return; + } + else + { + mesn $@BANK_NAME$[.@id]; + mesq l("Current task: Purchase a(n) %s", getitemlink(.@q2)); + next; + select + l("Continue"), + l("Abort") + " ["+l("Change task")+"]"; + mes ""; + if (@menu == 1) + return; + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2); + } + break; + /* ***************************************** */ + case MERCQ_SCOUT: + // This remains challenging even at high levels, but not if you use ship. + if (.@id == .@q2) { + // TODO: Dismiss the timer, or fail if MERCHANT_ID points to nothing + // Fail 1: Merchant_ID is no longer valid + if (getunittype(MERCHANT_ID) != UNITTYPE_MOB) { + mesn $@BANK_NAME$[.@id]; + mesq l("Our associate warped away... No thanks to you!"); + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+900; + close; + } + // Fail 2: Merchant was left behind + if (!gettimer(0, getcharid(3), "Malindou::OnScoutPing")) { + mesn $@BANK_NAME$[.@id]; + mesq l("...Did you lose our associate? Please try again."); + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+900; + close; + } + // Complete the quest + deltimer("Malindou::OnScoutPing"); + mesn $@BANK_NAME$[.@id]; + mesq l("Thanks for scorting our associate! Your efforts are greatly appreciated."); + Zeny+=rand2(24, 52) * 57; + getexp 360, 44; + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+7200; //Original: 43200 + unitkill(MERCHANT_ID); + MERCHANT_ID = 0; + return; + } + else + { + mesn $@BANK_NAME$[.@id]; + mesq l("Current task: Scout guild member to %s", $@BANK_TOWN$[.@q2]); + next; + select + l("Continue"), + l("Abort"); + mes ""; + if (@menu == 1) + return; + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2); + } + break; + } + + do + { + mesc l("The %s Merchant Guild has a few requests for you:", $@BANK_TOWN$[.@id]); + .@town = .@id; + while (.@town == .@id || getq(General_Narrator) < $@BANK_MINLV[.@town]) { + .@town=rand2(getarraysize($@BANK_TOWN$)); + } + select + l("How does this works?"), + rif(.@town != .@id, l("★ Deliver a letter")), + l("★★ Purchase goods"), + rif(is_sponsor() && .@town != .@id, l("★★★ Scout a merchant")), + l("Sorry, I won't accept any."); + mes ""; + switch (@menu) { + case 1: + mesc l("The Merchant Guild spawns multiple continents, and we can offer you a few tasks for them. Be careful as you might not be able to finish them and you'll have to abort!"); + mesc l("The more stars, the harder it is."); + next; + mesc l("After completing a request, there'll be a cooldown, proportional to the difficulty."); + mesc l("You can only have one Merchant Guild request active at same time."); + next; + break; + // Deliver a letter + case 2: + mesc l("We need you to deliver this important letter to %s! Avoid the roads and bandits!", $@BANK_NAME$[.@town]); + next; + mesc l("Accept request?"); + if (askyesno() == ASK_YES) { + mesc l("I'm counting on you!"); + setq General_MerchantRequest, MERCQ_LETTER, .@town, gettimetick(2); + return; + } + break; + // Purchase goods + case 3: + // TODO: List with items which are sold + .@item=any(YellowDye, Knife, InfantryHelmet, LeatherGloves, SilkRobe, CroconutBox, FishBox); + mesc l("The merchant guild needs %s! Purchase it and deliver at the nearest merchant guild member!", getitemlink(.@item)); + next; + mesc l("Accept request?"); + if (askyesno() == ASK_YES) { + mesc l("I'm counting on you!"); + setq General_MerchantRequest, MERCQ_GOODS, .@item, gettimetick(2); + return; + } + break; + // Scout a guild member + case 4: + mesc l("The merchant guild needs you to scout a Guild Member to %s! Absolutely don't let they get injuried!", $@BANK_NAME$[.@town]); + next; + mesc l("Accept request?"); + if (askyesno() == ASK_YES) { + mesc l("I'm counting on you!"); + getmapxy(.@m$, .@x, .@y, 0); + MERCHANT_ID=monster(.@m$, .@x, .@y, "Merchant", any(GameMaster, GameMistress), 1); + // Could also be a Gladiator, as long that you can distinguish them + setunitdata(MERCHANT_ID, UDT_MAXHP, 1); + setunitdata(MERCHANT_ID, UDT_HP, 1); + setunitdata(MERCHANT_ID, UDT_DEF, 1); + setunitdata(MERCHANT_ID, UDT_MDEF, 1); + setunitdata(MERCHANT_ID, UDT_FLEE, 1); + setunitdata(MERCHANT_ID, UDT_LEVEL, 1); + // Timer which makes Merchant follow you every once in a while + @merc_map$ = getmap(); + addtimer(rand2(10000), "Malindou::OnScoutPing"); + setq General_MerchantRequest, MERCQ_SCOUT, .@town, gettimetick(2); + return; + } + break; + default: + return; + } + } while (true); + return; +} + + // still_owed = TakeMoney (amount, reason) // This function is meant to be used from clientversion, when a quest failed // to take money from user. diff --git a/npc/functions/hub.txt b/npc/functions/hub.txt index b00ed850d..fc1c814e9 100644 --- a/npc/functions/hub.txt +++ b/npc/functions/hub.txt @@ -318,6 +318,12 @@ function script HUB_Logout { } LOGIN_TIME = 0; } + // Died or logged out during a Merchant Quest + if (MERCHANT_ID) { + setq General_MerchantRequest, MERCQ_NONE, 0, gettimetick(2)+900; + unitkill(MERCHANT_ID); + MERCHANT_ID = 0; + } // Crazyfefe hot fix if (.@dead) { // It was PK |