summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/constants.conf6
-rw-r--r--db/quest_db.conf4
-rw-r--r--npc/003-3/malindou.txt18
-rw-r--r--npc/005-5/cynric.txt1
-rw-r--r--npc/006-2-1/chirp.txt1
-rw-r--r--npc/009-3/barzil.txt1
-rw-r--r--npc/012-1/richard.txt1
-rw-r--r--npc/017-1/misc.txt1
-rw-r--r--npc/018-5/storage.txt1
-rw-r--r--npc/020-1/misc.txt1
-rw-r--r--npc/024-3/arauto.txt1
-rw-r--r--npc/025-1/drahcir.txt1
-rw-r--r--npc/027-7/banker.txt1
-rw-r--r--npc/functions/bank.txt218
-rw-r--r--npc/functions/hub.txt6
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