summaryrefslogtreecommitdiff
path: root/npc/functions
diff options
context:
space:
mode:
Diffstat (limited to 'npc/functions')
-rw-r--r--npc/functions/clientversion.txt174
-rw-r--r--npc/functions/estate.txt170
-rw-r--r--npc/functions/estate2.txt275
-rw-r--r--npc/functions/fishing.txt14
-rw-r--r--npc/functions/gmbot.txt24
-rw-r--r--npc/functions/hub.txt15
-rw-r--r--npc/functions/main.txt7
-rw-r--r--npc/functions/math.txt4
-rw-r--r--npc/functions/mobpoint.txt5
-rw-r--r--npc/functions/news.txt11
-rw-r--r--npc/functions/refine.txt16
-rw-r--r--npc/functions/scoreboards.txt10
-rw-r--r--npc/functions/seasons.txt16
-rw-r--r--npc/functions/siege.txt5
-rw-r--r--npc/functions/treasure.txt4
-rw-r--r--npc/functions/util.txt53
16 files changed, 594 insertions, 209 deletions
diff --git a/npc/functions/clientversion.txt b/npc/functions/clientversion.txt
index 873873018..51e5eab84 100644
--- a/npc/functions/clientversion.txt
+++ b/npc/functions/clientversion.txt
@@ -284,8 +284,8 @@ function script clientupdater {
}
// General Updates
// seg jul 15 16:41:35 -03 2019
- if (UPDATE < 1563219695) {
- UPDATE=1563219695;
+ if (UPDATE < 1565039378) {
+ UPDATE=1565039378;
.@dg=true;
mesc l(".:: This is Release 9.5 Academy ::."), 0;
//mesc l(".:: This is Release 10.0 Infinity ::."), 0;
@@ -416,6 +416,170 @@ function script clientupdater {
}
// Cleanup
deletearray RNGTREASURE_DATE;
+
+ // Open Beta 2019 Main Event Rewards
+ .@u$=strtolower(strcharinfo(0));
+ setarray .@officialnick$, "jesusalva", "kolchak", "xanthem", "seeds", "dangerduck", "test123", "sertrop", "lawncable", "pookie", "saulc",
+ "apane", "omatt";
+ setarray .@expval, 211625, 1955041, 938439, 59663, 73899, 10338, 7494, 7857, 1992, 360, 443, 193, 5180;
+ setarray .@gpval, 150321, 863215, 3263, 973137, 5650, 18343, 45227, 42002, 37381, 50000, 50450, 50275, 49988;
+ setarray .@summer, 19, 30, 55, 0, 4, 2, 3, 4, 0, 0, 0, 0, 2;
+ /* Data for python
+ # import exp from exptable
+ i=0
+ THEARRAY=[]
+ while i < len(names):
+ raw=overflow[i]
+ c=0
+ while c < level[i]:
+ raw+=exp[c]
+ c+=1
+ print("%s: %d exp" % (names[i], raw))
+ THEARRAY.append(int(raw*0.3))
+ i+=1
+
+ setarray .@levelval, 48, 66, 60, 39, 40, 28, 25, 26, 17, 10, 10, 8, 23;
+ setarray .@overflow, 25762, 338713, 55746, 1275, 14516, 504, 2855, 640, 360, 0, 277, 18, 598;
+ */
+
+ // Open Beta 2019
+ .@ranking=array_find(.@officialnick$, .@u$);
+ // Mishana LawnCable bObr Jesusalva demure
+ showavatar NPC_LOF_RICH;
+ mes "";
+ mes "*************************************";
+ mes "";
+ mesn ("TMW2 Staff");
+ mesc l("Hello, @@! We are proud to announce the @@ RESULTS!", strcharinfo(0) , b(l("Open Beta 2019"))), 3;
+ mes "";
+ mesc l("1st Place - Jesusalva (65)");
+ mesc l("2nd Place - Kolchak (63)");
+ mesc l("3rd Place - Xanthem (56)");
+ mesc l("4th Place - seeds (43)");
+ mesc l("5th Place - dangerDuck (23)");
+ mesc l("6th Place - test123 (20)");
+ mesc l("7th Place - Sertrop (17)");
+ mesc l("8th Place - Pookie (13)");
+ mesc l("9th Place - LawnCable (13)");
+ mesc l("10th Place - Saulc (8)");
+ mes "";
+ mesc l("It was a reeeeeealy close dispute for the podium, but Jesusalva crafted an item at the last minute and took the first place!");
+ mesc l("Although KOLCHAK managed to rank first in almost every ranking, Jesusalva was too close, and the Crafting gave him the edge he needed to take first place.");
+ mesc l("Congratulations to everyone who participated on the event, even those who didn't made to the top 10!");
+ if (.@ranking >= 0) {
+ #ADD_LVL=.@expval[.@ranking];
+
+ // Force Ched quest start if you haven't done so already
+ .@year=getq(SQuest_Ched);
+ if (.@year != (gettime(GETTIME_YEAR)-2000))
+ setq SQuest_Ched, (gettime(GETTIME_YEAR)-2000), 0, 0;
+
+
+ @ched=getq2(SQuest_Ched);
+ .@pts=.@summer[.@ranking];
+ if (.@pts) {
+ getexp rand2(.@pts-1, .@pts*11/10), rand2(0,.@pts/25);
+ setq2 SQuest_Ched, @ched+.@pts;
+ }
+
+ switch (.@ranking+1) {
+ case 1:
+ getitembound Tyranny, 1, 1;
+ getitem MercBoxEE, 1;
+ getitem EquipmentBlueprintE, 1;
+ getitem HousingLetterI, 1;
+ getitem StrangeCoin, 150;
+ break;
+ case 2:
+ getitem MercBoxEE, 1;
+ getitem EquipmentBlueprintE, 1;
+ getitem HousingLetterI, 1;
+ getitem StrangeCoin, 100;
+ break;
+ case 3:
+ getitem MercBoxDD, 1;
+ getitem EquipmentBlueprintD, 1;
+ getitem HousingLetterI, 1;
+ getitem StrangeCoin, 100;
+ break;
+ case 4:
+ case 5:
+ getitem MercBoxCC, 1;
+ getitem EquipmentBlueprintC, 1;
+ getitem HousingLetterI, 1;
+ getitem StrangeCoin, 50;
+ break;
+ case 6:
+ case 7:
+ getitem MercBoxBB, 1;
+ getitem StrangeCoin, 30;
+ break;
+ case 8:
+ case 9:
+ getitem MercBoxAA, 1;
+ getitem StrangeCoin, 10;
+ break;
+ case 10:
+ getitem MercBoxAA, 1;
+ break;
+ } // switch(ranking)
+
+ // GP conversion rules
+ // if you have less than 50k, we'll return you to initial amount
+ // Because it is a thankyou for participating on the event ;-)
+ .@trugp=max(50000, .@gpval[.@ranking]);
+
+ // You get to carry over 1 GP for each 1000 GP too (max 1000 GP bonus)
+ Zeny+=min(1000, .@trugp/1000);
+
+ // You'll get 1 Rare Point for every 1k GP obtained
+ // Top was 1,000,000 → 1000 rare points
+ #RARE_POINTS+=.@trugp/1000;
+
+ } // if ranking
+ }
+ // Negative Karma = good. And positive karma allows PvP. So...
+ // sex ago 9 18:10:20 -03 201
+ if (UPDATE < 1565385020) {
+ UPDATE=1565385020;
+ // PVP bugfix
+ Karma=0;
+ // Allow to skip quest if you already have the Grimorium
+ if (countitem(JesusalvaGrimorium) && getskilllv(TMW2_SKILLPERMIT) == 2) {
+ skill TMW2_SKILLPERMIT, 3, 0;
+ }
+ // This can't happen but anyway, just in case...
+ if (getskilllv(TMW2_TRANSMIGRATION) > 10) {
+ skill TMW2_TRANSMIGRATION, 10, 0;
+ }
+ // Magic Skill Points for this skill went from 3 to 2
+ if (getskilllv(ASC_METEORASSAULT))
+ MAGIC_PTS-=1;
+ // Treasure Key from Lua
+ if (getq(General_Narrator) >= 3)
+ getitem TreasureKey, 1;
+
+ // Post-poned Referral Rewards
+ if (#REFERRAL_PROG && BaseLevel >= 25 && #REFERRAL_CTRL < 1) {
+ #REFERRAL_CTRL=1;
+ rodex_sendmail(gf_charid(#REFERRAL_PROG), "TMW2 Team", "Recruited Player got Lv 25!", strcharinfo(0)+" just got level 25!\nAs they get stronger, more rewards will be sent to you!", 0, SilverGift, 1);
+ }
+ if (#REFERRAL_PROG && BaseLevel >= 50 && #REFERRAL_CTRL < 2) {
+ #REFERRAL_CTRL=2;
+ rodex_sendmail(gf_charid(#REFERRAL_PROG), "TMW2 Team", "Recruited Player got Lv 50!", strcharinfo(0)+" just got level 50!\nAs they get stronger, more rewards will be sent to you!", 0, ArcmageBoxset, 1);
+ }
+ #REFERRAL_CTRL=3;
+ if (#REFERRAL_PROG && BaseLevel >= 75 && #REFERRAL_CTRL < 3) {
+ rodex_sendmail(gf_charid(#REFERRAL_PROG), "TMW2 Team", "Recruited Player got Lv 75!", strcharinfo(0)+" just got level 75!\nAs they get stronger, more rewards will be sent to you!", 0, PrismGift, 1);
+ }
+ // Eisten Rewards
+ if (BaseLevel >= 50 && getq(TulimsharQuest_Eistein) == 2)
+ getitem SilverGift, 1;
+ if (BaseLevel >= 75 && getq(TulimsharQuest_Eistein) == 3)
+ getitem GoldenGift, 1;
+ if (BaseLevel >= 75 && getq(TulimsharQuest_Eistein) >= 3)
+ getitem GraduationRobe, 1;
+
}
// Test Server Updates
// seg jul 22 21:23:00 -03 2019
@@ -431,6 +595,7 @@ function script clientupdater {
// #ADD_LVL means the user have to right to get some levels. This is a sketch. The code might be deleted.
if (#ADD_LVL) {
.@dg=1;
+ /*
mesn "Jesus Saves";
mesc l("Oh - Welcome to TMW2: Moubootaur Legends!"), 3;
next;
@@ -448,6 +613,7 @@ function script clientupdater {
//atcommand "@blvl "+#ADD_LVL;
//getitem TimeFlask, 1;
#ADD_LVL=(#ADD_LVL*9)/10;
+ */
if ((readparam(BaseExp)+#ADD_LVL > readparam(NextBaseExp))) {
do {
.@v=readparam(NextBaseExp)-readparam(BaseExp);
@@ -462,8 +628,10 @@ function script clientupdater {
}
- if (.@dg)
+ if (.@dg) {
+ next;
closeclientdialog;
+ }
return;
}
diff --git a/npc/functions/estate.txt b/npc/functions/estate.txt
index e0290a12d..6f8c2acfd 100644
--- a/npc/functions/estate.txt
+++ b/npc/functions/estate.txt
@@ -3,7 +3,7 @@
// Jesusalva
// Description:
// Real Estate System
-// Script Helpers
+// Primary Script Helpers
// WARNING: They affect directly the real estate global variables!
// This function reduces payment accordingly
@@ -94,171 +94,3 @@ function script realestate_hasmobilia {
return false;
}
-
-
-//////////////////////////////////////////////////////////////////////////////
-///////////// Dialog Helpers
-// "If you copy-paste the same line too often, make a function for it"
-
-
-// Rent_Available Label
-// Returns true regardless of player decision
-// realestate_rent ( estate_id, price, <rent time> )
-function script realestate_rent {
- .id=getarg(0);
- .price=getarg(1);
- .time=getarg(2, 2592000); // Defaults to 30 days
-
- do
- {
- mesc l("This Real Estate is available for rent for only @@ GP!", format_number(.price));
- .@gp=REAL_ESTATE_CREDITS+Zeny;
- mesc l("You currently have: @@ GP and mobiliary credits", format_number(.@gp));
- next;
- select
- rif(.@gp > .price, l("Rent it! Make it mine!")),
- l("Information"),
- l("Don't rent it");
-
- // You want to rent
- if (@menu == 1) {
- if ($ESTATE_RENTTIME[.id] > gettimetick(2)) {
- mesc l("Somebody already rented it before you!");
- close;
- }
- REAL_ESTATE_CREDITS=REAL_ESTATE_CREDITS-.price;
- if (REAL_ESTATE_CREDITS < 0) {
- Zeny+=REAL_ESTATE_CREDITS;
- REAL_ESTATE_CREDITS=0;
- }
-
- // Payment done, you can now acquire the house for a month
- $ESTATE_RENTTIME[.id]=gettimetick(2)+.time;
-
- // If you're not the previous owner
- // Remove previous owner furniture and reset room password
- if ($ESTATE_OWNER[.id] != getcharid(3)) {
- /*
- $ESTATE_MOBILIA_2[.id]=0;
- $ESTATE_MOBILIA_4[.id]=0;
- $ESTATE_MOBILIA_8[.id]=0;
- $ESTATE_MOBILIA_32[.id]=0;
- $ESTATE_MOBILIA_64[.id]=0;
- $ESTATE_MOBILIA_128[.id]=0;
- */
- $ESTATE_PASSWORD$[.id]="";
- $ESTATE_DOORBELL[.id]=false;
- }
-
- // Register your info so you can manage it
- $ESTATE_OWNER[.id]=getcharid(3);
- $ESTATE_OWNERNAME$[.id]=strcharinfo(0);
-
- mesc l("Rent successful for 30 days!");
- } else if (@menu == 2) {
- mesc l("You can rent this house to make it yours.") + " " + l("The rent lasts 30 days.");
- mesc l("Then you'll be able to buy furniture and utility.");
- mesc l("The door is password-protected, so your friends can enter but strangers stay outside.");
- next;
- mesc l("Both rent and furniture are bought using money, however, there are mobiliary credits.");
- mesc l("Mobiliary Credits is a special currency which can only be used on real estate.");
- mesc l("It's obtained with ADMINS or by selling furniture. It is sumed to money and used first.");
- next;
- }
- } while (@menu == 2);
- return true;
-}
-
-
-
-
-
-// L_Manage Label
-// Returns true regardless of player decision
-// realestate_manage ( estate_id, price, <rent time> )
-function script realestate_manage {
- .id=getarg(0);
- .price=getarg(1);
- .time=getarg(2, 2592000); // Defaults to 30 days
-
- do
- {
- mesc l("@@'s Estate", strcharinfo(0));
- mesc ".:: "+ l("Managment Menu") + " ::.";
-
- .@gp=REAL_ESTATE_CREDITS+Zeny;
- mesc l("Rent time available: @@", FuzzyTime($ESTATE_RENTTIME[.id]));
- mesc l("Total Credits and GP: @@", format_number(.@gp));
- mes "";
- mesc l("Rent Renew Price: @@ GP", format_number(.price));
- mesc l("Room password: @@", $ESTATE_PASSWORD$[.id]);
- if ($ESTATE_DOORBELL[.id])
- mesc l("Doorbell is disabled"), 1;
-
- next;
- select
- l("Leave"),
- l("Enable/disable doorbell"),
- l("Set room password"),
- rif(.@gp >= .price && $ESTATE_RENTTIME[.id] < gettimetick(2)+.time, l("Renew Rent")),
- rif($@GM_OVERRIDE, l("Destroy all mobilia")),
- rif($@GM_OVERRIDE, l("Expire rent time"));
-
- switch (@menu) {
- case 1:
- break;
- case 2:
- $ESTATE_DOORBELL[.id]=!$ESTATE_DOORBELL[.id];
- break;
- case 3:
- mesc l("(Leave the password blank to disable)");
- mesc l("Current Room password: @@", $ESTATE_PASSWORD$[.id]);
- mesc l("Input new password: ");
- input .@password$;
- mesc l("Repeat new password: ");
- input .@passwordc$;
- if (.@password$ == .@passwordc$) {
- $ESTATE_PASSWORD$[.id]=.@password$;
- mesc l("Password changed with success!"), 3;
- } else {
- mesc l("The passwords doesn't match."), 1;
- }
- break;
- case 4:
- // The check is performed before showing the menu option
- // I guess it could be hacked, but I'll probably see negative GP...
- REAL_ESTATE_CREDITS=REAL_ESTATE_CREDITS-.price;
- if (REAL_ESTATE_CREDITS < 0) {
- Zeny+=REAL_ESTATE_CREDITS;
- REAL_ESTATE_CREDITS=0;
- }
-
- // Payment done, you can now acquire the house for a month
- // If you lost the rent on the meanwhile, it'll renew
- // If you lost the rent and somebody else rented it, you lose the GP
- $ESTATE_RENTTIME[.id]+=.time;
- break;
- case 5:
- mesc l("Are you sure? This cannot be undone!"), 1;
- next;
- if (validatepin()) {
- $ESTATE_MOBILIA_2[.id]=0;
- $ESTATE_MOBILIA_4[.id]=0;
- $ESTATE_MOBILIA_8[.id]=0;
- $ESTATE_MOBILIA_32[.id]=0;
- $ESTATE_MOBILIA_64[.id]=0;
- $ESTATE_MOBILIA_128[.id]=0;
- $ESTATE_PASSWORD$[.id]="";
- $ESTATE_DOORBELL[.id]=false;
- }
- case 6:
- mesc l("Are you sure? This cannot be undone!"), 1;
- next;
- if (validatepin()) {
- $ESTATE_RENTTIME[.id]=gettimetick(2);
- }
- }
- } while (@menu != 1);
- return true;
-}
-
diff --git a/npc/functions/estate2.txt b/npc/functions/estate2.txt
new file mode 100644
index 000000000..758a73e4b
--- /dev/null
+++ b/npc/functions/estate2.txt
@@ -0,0 +1,275 @@
+// TMW2: Moubootaur Legends scripts.
+// Author:
+// Jesusalva
+// Description:
+// Real Estate System
+// Secondary Script Helpers
+// WARNING: They affect directly the real estate global variables!
+//////////////////////////////////////////////////////////////////////////////
+///////////// Dialog Helpers
+// "If you copy-paste the same line too often, make a function for it"
+
+// Rent_Available Label
+// Returns true regardless of player decision
+// realestate_rent ( estate_id, price, <rent time> )
+function script realestate_rent {
+ .id=getarg(0);
+ .price=getarg(1);
+ .time=getarg(2, 2592000); // Defaults to 30 days
+
+ do
+ {
+ mesc l("This Real Estate is available for rent for only @@ GP!", format_number(.price));
+ .@gp=REAL_ESTATE_CREDITS+Zeny;
+ mesc l("You currently have: @@ GP and mobiliary credits", format_number(.@gp));
+ next;
+ select
+ rif(.@gp > .price, l("Rent it! Make it mine!")),
+ l("Information"),
+ l("Don't rent it");
+
+ // You want to rent
+ if (@menu == 1) {
+ if ($ESTATE_RENTTIME[.id] > gettimetick(2)) {
+ mesc l("Somebody already rented it before you!");
+ close;
+ }
+ REAL_ESTATE_CREDITS=REAL_ESTATE_CREDITS-.price;
+ if (REAL_ESTATE_CREDITS < 0) {
+ Zeny+=REAL_ESTATE_CREDITS;
+ REAL_ESTATE_CREDITS=0;
+ }
+
+ // Payment done, you can now acquire the house for a month
+ $ESTATE_RENTTIME[.id]=gettimetick(2)+.time;
+
+ // If you're not the previous owner
+ // Remove previous owner furniture and reset room password
+ if ($ESTATE_OWNER[.id] != getcharid(3)) {
+ /*
+ $ESTATE_MOBILIA_2[.id]=0;
+ $ESTATE_MOBILIA_4[.id]=0;
+ $ESTATE_MOBILIA_8[.id]=0;
+ $ESTATE_MOBILIA_32[.id]=0;
+ $ESTATE_MOBILIA_64[.id]=0;
+ $ESTATE_MOBILIA_128[.id]=0;
+ */
+ $ESTATE_PASSWORD$[.id]="";
+ $ESTATE_DOORBELL[.id]=false;
+ }
+
+ // Register your info so you can manage it
+ $ESTATE_OWNER[.id]=getcharid(3);
+ $ESTATE_OWNERNAME$[.id]=strcharinfo(0);
+
+ mesc l("Rent successful for 30 days!");
+ } else if (@menu == 2) {
+ mesc l("You can rent this house to make it yours.") + " " + l("The rent lasts 30 days.");
+ mesc l("Then you'll be able to buy furniture and utility.");
+ mesc l("The door is password-protected, so your friends can enter but strangers stay outside.");
+ next;
+ mesc l("Both rent and furniture are bought using money, however, there are mobiliary credits.");
+ mesc l("Mobiliary Credits is a special currency which can only be used on real estate.");
+ mesc l("It's obtained with ADMINS or by selling furniture. It is sumed to money and used first.");
+ next;
+ }
+ } while (@menu == 2);
+ return true;
+}
+
+
+
+
+
+// L_Manage Label
+// Returns true regardless of player decision
+// realestate_manage ( estate_id, price, <rent time> )
+function script realestate_manage {
+ .id=getarg(0);
+ .price=getarg(1);
+ .time=getarg(2, 2592000); // Defaults to 30 days
+
+ do
+ {
+ mesc l("@@'s Estate", strcharinfo(0));
+ mesc ".:: "+ l("Managment Menu") + " ::.";
+
+ .@gp=REAL_ESTATE_CREDITS+Zeny;
+ mesc l("Rent time available: @@", FuzzyTime($ESTATE_RENTTIME[.id]));
+ mesc l("Total Credits and GP: @@", format_number(.@gp));
+ mes "";
+ mesc l("Rent Renew Price: @@ GP", format_number(.price));
+ mesc l("Room password: @@", $ESTATE_PASSWORD$[.id]);
+ if ($ESTATE_DOORBELL[.id])
+ mesc l("Doorbell is disabled"), 1;
+
+ next;
+ select
+ l("Leave"),
+ l("Enable/disable doorbell"),
+ l("Set room password"),
+ rif(.@gp >= .price && $ESTATE_RENTTIME[.id] < gettimetick(2)+.time, l("Renew Rent")),
+ rif($@GM_OVERRIDE, l("Destroy all mobilia")),
+ rif($@GM_OVERRIDE, l("Expire rent time"));
+
+ switch (@menu) {
+ case 1:
+ break;
+ case 2:
+ $ESTATE_DOORBELL[.id]=!$ESTATE_DOORBELL[.id];
+ break;
+ case 3:
+ mesc l("(Leave the password blank to disable)");
+ mesc l("Current Room password: @@", $ESTATE_PASSWORD$[.id]);
+ mesc l("Input new password: ");
+ input .@password$;
+ mesc l("Repeat new password: ");
+ input .@passwordc$;
+ if (.@password$ == .@passwordc$) {
+ $ESTATE_PASSWORD$[.id]=.@password$;
+ mesc l("Password changed with success!"), 3;
+ } else {
+ mesc l("The passwords doesn't match."), 1;
+ }
+ break;
+ case 4:
+ // The check is performed before showing the menu option
+ // I guess it could be hacked, but I'll probably see negative GP...
+ REAL_ESTATE_CREDITS=REAL_ESTATE_CREDITS-.price;
+ if (REAL_ESTATE_CREDITS < 0) {
+ Zeny+=REAL_ESTATE_CREDITS;
+ REAL_ESTATE_CREDITS=0;
+ }
+
+ // Payment done, you can now acquire the house for a month
+ // If you lost the rent on the meanwhile, it'll renew
+ // If you lost the rent and somebody else rented it, you lose the GP
+ $ESTATE_RENTTIME[.id]+=.time;
+ break;
+ case 5:
+ mesc l("Are you sure? This cannot be undone!"), 1;
+ next;
+ if (validatepin()) {
+ $ESTATE_MOBILIA_2[.id]=0;
+ $ESTATE_MOBILIA_4[.id]=0;
+ $ESTATE_MOBILIA_8[.id]=0;
+ $ESTATE_MOBILIA_32[.id]=0;
+ $ESTATE_MOBILIA_64[.id]=0;
+ $ESTATE_MOBILIA_128[.id]=0;
+ $ESTATE_PASSWORD$[.id]="";
+ $ESTATE_DOORBELL[.id]=false;
+ }
+ case 6:
+ mesc l("Are you sure? This cannot be undone!"), 1;
+ next;
+ if (validatepin()) {
+ $ESTATE_RENTTIME[.id]=gettimetick(2);
+ }
+ }
+ } while (@menu != 1);
+ return true;
+}
+
+
+// Piano Mobilia
+// realestate_piano ( {mapname} )
+function script realestate_piano {
+ .@loc$=getarg(0, getmap());
+ mesc l("Do you want to play a song?");
+ mesc l("This is not saved.");
+ select
+ l("Nothing"),
+ l("Default"),
+ l("Indoors 1 (Peace)"),
+ l("Indoors 2 (Dimonds)"),
+ l("TMW Adventure"),
+ l("Sailing Away!"),
+ l("Magick Real"),
+ l("The Forest"),
+ l("Dragons and Toast"),
+ l("Unforgiving Lands"),
+ l("Arabesque (Action)"),
+ l("No Chains (Tulimshar)"),
+ l("School of Quirks (Candor)"),
+ l("Cake Town (Hurnscald)"),
+ l("Steam (LoF Village)"),
+ l("Woodland Fantasy"),
+ l("Birds in the Sunrise");
+
+ mes "";
+ .@m$="";
+ switch (@menu) {
+ case 1:
+ return; break;
+ case 2:
+ .@m$="8bit_the_hero.ogg"; break;
+ case 3:
+ .@m$="peace.ogg"; break;
+ case 4:
+ .@m$="peace2.ogg"; break;
+ case 5:
+ .@m$="tmw_adventure.ogg"; break;
+ case 6:
+ .@m$="sail_away.ogg"; break;
+ case 7:
+ .@m$="magick_real.ogg"; break;
+ case 8:
+ .@m$="dariunas_forest.ogg"; break;
+ case 9:
+ .@m$="dragon_and_toast.ogg"; break;
+ case 10:
+ .@m$="Unforgiving_Lands.ogg"; break;
+ case 11:
+ .@m$="Arabesque.ogg"; break;
+ case 12:
+ .@m$="mvrasseli_nochains.ogg"; break;
+ case 13:
+ .@m$="school_of_quirks.ogg"; break;
+ case 14:
+ .@m$="caketown.ogg"; break;
+ case 15:
+ .@m$="steam.ogg"; break;
+ case 16:
+ .@m$="woodland_fantasy.ogg"; break;
+ case 17:
+ .@m$="tws_birds_in_the_sunrise.ogg"; break;
+
+ }
+ changemusic .@loc$, .@m$;
+ return;
+}
+
+
+
+// Cauldron Mobilia
+// realestate_cauldron ( )
+function script realestate_cauldron {
+ select
+ l("Alchemy"),
+ l("Crafting");
+ mes "";
+ if (@menu == 1) {
+ do {
+ mesc l("What will you brew today?");
+ if (AlchemySystem(CRAFT_PLAYER))
+ mesc l("Success!"), 3;
+ else
+ mesc l("That didn't work!"), 1;
+ next;
+ mesc l("Try again?");
+ } while (askyesno() == ASK_YES);
+ }
+ else if (@menu == 2) {
+ do {
+ mesc l("What will you craft today?");
+ if (SmithSystem(CRAFT_PLAYER))
+ mesc l("Success!"), 3;
+ else
+ mesc l("That didn't work!"), 1;
+ next;
+ mesc l("Try again?");
+ } while (askyesno() == ASK_YES);
+ }
+ return;
+}
+
diff --git a/npc/functions/fishing.txt b/npc/functions/fishing.txt
index 52f9fcc9a..a68984cfa 100644
--- a/npc/functions/fishing.txt
+++ b/npc/functions/fishing.txt
@@ -40,7 +40,8 @@ OnBite:
setnpcdir @fishing_spot$, LEFT;
@fishing_tick = gettimetick(0);
- specialeffect(getvariableofnpc(.bite_fx, @fishing_spot$), SELF, playerattached());
+ .@bite_fx=getvariableofnpc(.bite_fx, @fishing_spot$);
+ specialeffect(.@bite_fx ? .@bite_fx : 30, SELF, playerattached());
end;
OnCleanUp:
@@ -245,6 +246,7 @@ function script fishing {
.@fish_id = 0;
}
+ @fishing_spot$="";
return .@fish_id;
}
@@ -256,6 +258,16 @@ function script fishing {
return -5;
}
+ // This "hack" will prevent you from fishing at two spots (buggy)
+ // It'll cancel the previous fishing too, per logical rule.
+ if (@fishing_spot$ != "") {
+ deltimer "global fishing handler::OnCleanUp"; // cancel auto cleanup
+ deltimer "global fishing handler::OnBite";
+ fishing_cleanup(@fishing_spot$); // clean up manually
+ @fishing_spot$="";
+ dispbottom l("You left your fishing spot!");
+ return -4;
+ }
// begin fishing
narrator S_LAST_NEXT,
diff --git a/npc/functions/gmbot.txt b/npc/functions/gmbot.txt
index 9c164ff7d..b04c40002 100644
--- a/npc/functions/gmbot.txt
+++ b/npc/functions/gmbot.txt
@@ -141,39 +141,44 @@ OnTimer90000:
debugmes "Monster King (bot): "+.mp$+" ("+.@x+", "+.@y+")";
// If too few players are online, we don't need an event AT ALL!
- if (.users < rand(2,4)) {
+ if (.users < rand2(2,4)) {
initnpctimer;
end;
}
// Siege events (req. 300 aggro, 3 users, and 70% chances to begin)
if ($@MK_AGGRO >= 300 && .users >= 3 && rand(0,100) < 70 &&
- $GAME_STORYLINE == 2 && $@MK_THROTTLE < gettimetick(2)){
+ is_between(1, 3, $GAME_STORYLINE) && $@MK_THROTTLE < gettimetick(2)){
+ // Delta handles the compulsory wait time between waves.
+ // 6 hours normally, 12 hours if the army is in disarray.
+ .@delta=6;
+ if ($GAME_STORYLINE == 3)
+ .@delta=12;
// Tulimshar
if (.mp$ ~= "003-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
- $@MK_THROTTLE=gettimetick(2)+3*60*60;
+ $@MK_THROTTLE=gettimetick(2)+.@delta*60*60;
$@MK_SCENE=MK_SIEGE_TULIM;
donpcevent("Lieutenant Dausen::OnMKSiege");
}
// Halinarzo
else if (.mp$ ~= "009-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
- $@MK_THROTTLE=gettimetick(2)+3*60*60;
+ $@MK_THROTTLE=gettimetick(2)+.@delta*60*60;
$@MK_SCENE=MK_SIEGE_HALIN;
donpcevent("Lieutenant Jacob::OnMKSiege");
}
// Hurnscald
else if (.mp$ ~= "012-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
- $@MK_THROTTLE=gettimetick(2)+3*60*60;
+ $@MK_THROTTLE=gettimetick(2)+.@delta*60*60;
$@MK_SCENE=MK_SIEGE_HURNS;
donpcevent("#HurnscaldSiege::OnMKSiege");
}
// Nivalis
else if (.mp$ ~= "020-*") {
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
- $@MK_THROTTLE=gettimetick(2)+3*60*60;
+ $@MK_THROTTLE=gettimetick(2)+.@delta*60*60;
$@MK_SCENE=MK_SIEGE_NIVAL;
donpcevent("Lieutenant Joshua::OnMKSiege");
}
@@ -182,18 +187,15 @@ OnTimer90000:
// If a player is nearby while the Monster King prepares, event may happen
// Minimum 60 Aggro
if (.nearby > 1 && $@MK_AGGRO >= 80 &&
- ($GAME_STORYLINE == 1 || $GAME_STORYLINE == 3)){
+ ($GAME_STORYLINE == 1 || ($GAME_STORYLINE == 3 && $@MK_THROTTLE >= gettimetick(2)) )){
// We should decide event kind, but that's NYI
announce ("Monster King: I smell humans! Humans must die!"), bc_map|bc_npc;
getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, $@MK);
- // 50% more monsters at night time
- if (is_night())
- $@MK_AGGRO=$@MK_AGGRO*3/2;
// Spawn stuff
areamonster(.@m$, .@x-20, .@y-20, .@x+20, .@y+20, "Monster", ManaGhost, ($@MK_AGGRO/10)+.nearby, "Monster King::OnSlaveDie");
- $@MK_AGGRO=$@MK_AGGRO/5;
+ $@MK_AGGRO=($@MK_AGGRO*$GAME_STORYLINE)/5;
}
// Maybe, just maybe, game storyline must be updated here
diff --git a/npc/functions/hub.txt b/npc/functions/hub.txt
index 8632b3e0d..eb535d9f6 100644
--- a/npc/functions/hub.txt
+++ b/npc/functions/hub.txt
@@ -63,6 +63,18 @@ function script HUB_Logout {
if (.@mapa$ == "020-7-1") {
callfunc("BSClearNest", @nestid);
}
+ // Died or logged out on Player Story 5 - Forgotten Throne Room
+ if (.@mapa$ ~= "hmc*") {
+ .@n$=instance_npcname("#Core02331");
+ deltimer(.@n$+"::OnW01");
+ deltimer(.@n$+"::OnW02");
+ deltimer(.@n$+"::OnE07");
+ deltimer(.@n$+"::OnE08");
+ deltimer(.@n$+"::OnE09");
+ deltimer(.@n$+"::OnE10");
+ deltimer(.@n$+"::OnE11");
+ deltimer(.@n$+"::OnE12");
+ }
// Died or logged out during Sagratha Fight
if (.@mapa$ ~= "sgt2*") {
setq1 HurnscaldQuest_Sagratha, 3;
@@ -94,6 +106,7 @@ function script HUB_Logout {
if (!getmapflag(.@mapa$, mf_pvp) && !getmapflag(.@mapa$, mf_pvp_noparty) && !getmapflag(.@mapa$, mf_pvpnoguild)) {
recovery(getcharid(3));
warp .@mapa$, .@a, .@b;
+ percentheal 100, 100;
dispbottom l("REVENGE TIME!");
.@trueid=getcharid(3);
//detachrid();
@@ -104,6 +117,8 @@ function script HUB_Logout {
sc_end SC_OVERLAPEXPUP;
sc_start SC_OVERLAPEXPUP, 300000, -20;
dispbottom l("For cowardingly killing in a \"secure\" area, you will be severely punished.");
+ //Karma+=1;
+ sc_start SC_STUN, 15000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK;
addtimer(15000, "#mobptsys::OnUnlock");
percentheal -88, -100;
detachrid();
diff --git a/npc/functions/main.txt b/npc/functions/main.txt
index 5e897901b..e1b93fa46 100644
--- a/npc/functions/main.txt
+++ b/npc/functions/main.txt
@@ -337,6 +337,13 @@ function script gf_charname {
return .@value$[0];
}
+// Get some char ID from account ID, even if offline
+// ( Name )
+function script gf_charid {
+ .@nb = query_sql("SELECT char_id FROM `char` WHERE account_id="+escape_sql(getarg(0))+" LIMIT 1", .@value$);
+ return .@value$[0];
+}
+
// Request pincode and validate it. Use any non-4-digits code to cancel. Failure will dc you.
// Returns 1 if pin check is OK.
function script validatepin {
diff --git a/npc/functions/math.txt b/npc/functions/math.txt
index 068d46cba..fc27bec40 100644
--- a/npc/functions/math.txt
+++ b/npc/functions/math.txt
@@ -73,7 +73,9 @@ function script log2 {
// is_between ( lower, higher, target)
function script is_between {
.@val=getarg(2);
- return (getarg(0) < .@val && getarg(1) >= .@val);
+ .@min=getarg(0);
+ .@max=getarg(1);
+ return (.@min < .@val && .@val <= .@max);
}
diff --git a/npc/functions/mobpoint.txt b/npc/functions/mobpoint.txt
index 8133c938f..9c901bc3d 100644
--- a/npc/functions/mobpoint.txt
+++ b/npc/functions/mobpoint.txt
@@ -43,10 +43,11 @@ OnNPCKillEvent:
// Remove undue Job exp
// The check is probably correct, but setparam is not working =/
/*
+ */
if (strmobinfo(7, killedrid) == 0 && readparam(JobExp) > 0) {
- setparam(JobExp, readparam(JobExp)-1);
+ //setparam(JobExp, readparam(JobExp)-1);
+ JobExp-=1;
}
- */
// call functions
callfunc "mobpoint";
diff --git a/npc/functions/news.txt b/npc/functions/news.txt
index 4ee44f102..ee5ac2d25 100644
--- a/npc/functions/news.txt
+++ b/npc/functions/news.txt
@@ -424,8 +424,17 @@ function script Journalman {
mesc l("The Monster King Army is attacking towns at random, but players already reduced their organization to @@ %%!", .@def);
mesc l("With recent player activity, the Monster king is @@!", .@st$);
break;
+ case 3:
+ mesc l("The Monster Army is in complete disarray, sieges are much less frequent.");
+ mesc l("The mist over the Impregnable Fortress Peak finally lowered down, and it seems... The peaks are no more!");
+ mesc l("The Monster King Lair is not in a impregnable mountain, but in a small island now!!");
+ break;
+ case 4:
+ mesc l("We must defeat the Monster King on his evil lair!");
+ mesc l("Only then we may have peace!!");
+ break;
default:
- Exception(l("I do now know what this means: GS-@@-ICXN-@@", $GAME_STORYLINE, $@MK_TEMPVAR), RB_DEFAULT|RB_SPEECH); break;
+ Exception(l("I do now know what this means: GS-@@-ICXN-@@", $GAME_STORYLINE, $MK_TEMPVAR), RB_DEFAULT|RB_SPEECH); break;
}
next;
diff --git a/npc/functions/refine.txt b/npc/functions/refine.txt
index 74f72857f..1936b5542 100644
--- a/npc/functions/refine.txt
+++ b/npc/functions/refine.txt
@@ -90,7 +90,7 @@ function script refineMaster {
}
mesn;
mesq l("This @@ is a nice stuff. I can refine it for @@ GP and @@ @@.", getitemlink(.@item), .@price, .@amount, getitemlink(.@rg));
- mesc l("Success ratio is of aprox. @@ %", (100-(.@rlv*7))+rand(-6,6));
+ mesc l("Success ratio is of aprox. @@ %", (100-(.@rlv*7))+rand2(-6,6));
next;
if (askyesno() != ASK_YES)
close;
@@ -144,7 +144,7 @@ function script refineMaster {
}
// Were we successful?
- if (getequippercentrefinery(.@it) > rand(100)) {
+ if (getequippercentrefinery(.@it) > rand2(100)) {
successrefitem .@it;
mesn;
mesq l("HAHAHAHAH! Shiny as new, and stronger than ever! Have fun!");
@@ -152,7 +152,7 @@ function script refineMaster {
mesc l("Armors: +3~5 defense");
next;
// Perhaps the item has broken?
- } else if (rand(100) < .@rvl*2) {
+ } else if (rand2(100) < .@rlv) {
failedrefitem .@it;
mesc l("*CRASH*");
next;
@@ -163,7 +163,7 @@ function script refineMaster {
mesq l("Well, you were warned. Do you have any other stuff for me?");
next;
// Item is weakened.
- } else {
+ } else if (rand2(100) < .@rlv) {
downrefitem .@it, 1;
mesn;
mesq l("A masterpiece!... Whaaaat, this stuff got ##Bweaker##b??");
@@ -174,6 +174,14 @@ function script refineMaster {
mesn;
mesq l("I'm sure I could refine this again, if you bring me the payment and the reagents again.");
next;
+ // Nothing happens
+ } else {
+ mesn;
+ mesq l("Well, I did my best, but this had been so refined, that it was difficult to find my way.");
+ next;
+ mesn;
+ mesq l("I'm sure I could refine this again, if you bring me the payment and the reagents again.");
+ next;
}
return;
}
diff --git a/npc/functions/scoreboards.txt b/npc/functions/scoreboards.txt
index 9ceac8265..fb1c4974c 100644
--- a/npc/functions/scoreboards.txt
+++ b/npc/functions/scoreboards.txt
@@ -386,10 +386,20 @@ function script HallOf2019 {
mes l(".:: Ched's Summer 2019 ::.");
mesc l("June 21st - September 21st");
mes "";
+ /*
mes l(".:: Chocolate Day ::.");
mesc l("Event Canceled"), 1;
//mesc l("Scheduled: July 7th");
mes "";
+ */
+ mes l(".:: Open Beta 2019 ::.");
+ mes l("1. Jesusalva - 65");
+ mes l("2. Kolchak - 63");
+ mes l("3. Xanthem - 56");
+ mesc l("4. seeds - 43");
+ mesc l("5. dangerDuck - 23");
+ //mesc l("Scheduled: July 20th ~ 31st");
+ mes "";
mes l(".:: Free Software Day ::.");
mesc l("Scheduled: September 9th");
mes "";
diff --git a/npc/functions/seasons.txt b/npc/functions/seasons.txt
index cb742e558..51fee458f 100644
--- a/npc/functions/seasons.txt
+++ b/npc/functions/seasons.txt
@@ -204,31 +204,31 @@ function script SeasonReload {
OnSummerStart:
addmonsterdrop(SaxsoGhost, CherryCocktail, 450);
- addmonsterdrop(DesertBandit, CherryCocktail, 410);
+ addmonsterdrop(DesertBandit, CherryCocktail, 410); // INVALID
addmonsterdrop(Duck, CherryCocktail, 360);
addmonsterdrop(Croc, CherryCocktail, 180);
addmonsterdrop(RedButterfly, CherryCocktail, 100);
-
+
addmonsterdrop(Centaur, CactusCocktail, 1000);
- addmonsterdrop(GiantMaggot, CactusCocktail, 290);
- addmonsterdrop(FireGoblin, CactusCocktail, 220);
+ addmonsterdrop(GiantMaggot, CactusCocktail, 290); // INVALID
+ addmonsterdrop(FireGoblin, CactusCocktail, 220); // INVALID
addmonsterdrop(DesertMaggot, CactusCocktail, 190);
addmonsterdrop(Scorpion, CactusCocktail, 165);
addmonsterdrop(Maggot, CactusCocktail, 140);
-
+
addmonsterdrop(AlphaMouboo, AppleCocktail, 850);
addmonsterdrop(OceanCroc, AppleCocktail, 480);
addmonsterdrop(Mouboo, AppleCocktail, 280);
addmonsterdrop(RedScorpion, AppleCocktail, 120);
addmonsterdrop(Pinkie, AppleCocktail, 70);
-
+
addmonsterdrop(Duck, Sunglasses, 1);
addmonsterdrop(Croc, Sunglasses, 1);
addmonsterdrop(SaxsoGhost, Sunglasses, 1);
- addmonsterdrop(DesertMaggot, Sunglasses, 1);
+ addmonsterdrop(DesertMaggot, Sunglasses, 1); // INVALID
addmonsterdrop(Scorpion, Sunglasses, 1);
- addmonsterdrop(GiantMaggot, Sunglasses, 1);
+ addmonsterdrop(GiantMaggot, Sunglasses, 1); // INVALID
addmonsterdrop(Centaur, Sunglasses, 3);
addmonsterdrop(AlphaMouboo, Sunglasses, 1);
addmonsterdrop(OceanCroc, Sunglasses, 1);
diff --git a/npc/functions/siege.txt b/npc/functions/siege.txt
index d4d56ac45..e8f40b229 100644
--- a/npc/functions/siege.txt
+++ b/npc/functions/siege.txt
@@ -191,10 +191,11 @@ function script siege_check {
.@mb+=mobcount(.@m$, "#SiegeCtrl::OnColonelDeath");
.@mb+=mobcount(.@m$, "#SiegeCtrl::OnGeneralDeath");
- // Players failed, so reduce score in 1
+ // Players failed, so reduce score in 1~10 (like Sergeant~General).
+ // In future, it could be inverse proportion (-9 for sergeant, -1 for general)
if (.@mb) {
if ($GAME_STORYLINE == 2)
- $MK_TEMPVAR-=1;
+ $MK_TEMPVAR-=rand2(1, 10);
kamibroadcast("Players failed to defend the city!!");
debugmes "Number of boss grade monsters found: %d", .@mb;
$SIEGE_DIFFICULTY=max(1, ($SIEGE_DIFFICULTY/2));
diff --git a/npc/functions/treasure.txt b/npc/functions/treasure.txt
index 83da812e4..e97dced4f 100644
--- a/npc/functions/treasure.txt
+++ b/npc/functions/treasure.txt
@@ -40,8 +40,8 @@ function script TreasureBox {
.@loot=any(SmokeGrenade, SnakeEgg, LachesisBrew, ArrowAmmoBox, CoinBag, SilverGift, TerraniteOre, LeadOre, TinOre, SilverOre, GoldOre, TitaniumOre, FluoPowder, AlchemyBlueprintB, AncientBlueprint);
else if (.@r < 1000 || .@t == 0)
.@loot=any(MoubooSteak, ClothoLiquor, Coal, RedPlushWine, HastePotion, StrengthPotion, Dagger, BronzeGift, IronOre, CopperOre, AlchemyBlueprintA);
- else if (.@r < 4000)
- .@loot=any(Croconut, Potatoz, MoubooSteak, ClothoLiquor, Coal, SmallMushroom, HastePotion, StrengthPotion, Beer);
+ else if (.@r < 5000)
+ .@loot=any(Croconut, Potatoz, MoubooSteak, ClothoLiquor, Coal, SmallMushroom, HastePotion, StrengthPotion, WoodenLog, LeatherPatch, Beer);
else
.@loot=any(FatesPotion, ChocolateBar, Plushroom, Chagashroom, RawLog, LeatherPatch, BugLeg, ScorpionStinger, SmallKnife, StrangeCoin);
diff --git a/npc/functions/util.txt b/npc/functions/util.txt
index 0e50e2d30..21abcd1f2 100644
--- a/npc/functions/util.txt
+++ b/npc/functions/util.txt
@@ -142,7 +142,7 @@ function script nard_reputation {
function script reputation {
.@nr=0; // Base reputation
- // Tulimshar Quests (14 points)
+ // Tulimshar Quests (16 points)
if (getarg(0) == "Tulim") {
// Eugene Quest (+1 rep)
if (getq(TulimsharQuests_Fishman) >= 2)
@@ -223,7 +223,7 @@ function script reputation {
- // Hurnscald Quests (9 points)
+ // Hurnscald Quests (11 points)
} else if (getarg(0) == "Hurns") {
// Alan Quest (+1 rep)
@@ -269,8 +269,16 @@ function script reputation {
if (getq(HurnscaldQuest_Lieutenant) >= 10)
.@nr=.@nr+1;
+ // Thorn Quest (+1 rep)
+ if (getq(HurnscaldQuest_Thorn) >= 1)
+ .@nr=.@nr+1;
+
+ // Blossom Quest (+1 rep)
+ if (getq(HurnscaldQuest_Blossom) >= 1)
+ .@nr=.@nr+1;
+
// HURNSCALD Magical Forumula
- .@nr=.@nr*100/9;
+ .@nr=.@nr*100/11;
@@ -309,7 +317,7 @@ function script reputation {
- // Nivalis Quests (2 points)
+ // Nivalis Quests (6 points)
} else if (getarg(0) == "Nival") {
// Nivalis Well Quest (+1 rep)
@@ -397,7 +405,7 @@ function script reputation {
- // Candor Quests (9 points)
+ // Candor Quests (10 points)
} else if (getarg(0) == "Candor") {
// Valon Quest (+1 rep)
@@ -699,6 +707,26 @@ function script mlearn {
return true;
}
*/
+// transcheck( {item 1, amount 1}, {item 2, amount 2}... )
+// returns true upon success
+function script transcheck {
+ if (getargcount() < 2 || getargcount() % 2 != 0)
+ return Exception("Faulty learning skill command invoked - error");
+
+ // Count items
+ for (.@i=0;.@i < getargcount(); .@i++) {
+ if (countitem(getarg(.@i)) < getarg(.@i+1))
+ return false;
+ .@i++;
+ }
+
+ // Delete Items
+ for (.@i=0;.@i < getargcount(); .@i++) {
+ delitem getarg(.@i), getarg(.@i+1);
+ .@i++;
+ }
+ return true;
+}
// Returns a value defining your current magic control (affects success ratio, higher is better)
// A value of '5' means perfect control, and a value of '0' means overwhelm.
@@ -708,6 +736,21 @@ function script abizit {
return min(MAGIC_EXP/.@base, 5);
}
+// anyloot( {item 1, amount 1, chance 1}, {item 2, amount 2, chance 2}... )
+// Give chance (standard 1~10000 roll) to obtain item, capped at amount.
+function script anyloot {
+ if (getargcount() < 3 || getargcount() % 3 != 0)
+ return Exception("Faulty anyloot skill command invoked - error");
+
+ // Get Items
+ for (.@i=0;.@i < getargcount(); .@i++) {
+ if (rand2(10000) < getarg(.@i+2))
+ getitem getarg(.@i), rand2(1, getarg(.@i+1));
+ .@i++;
+ }
+ return true;
+}
+
// Returns, based on a 1-5 range, the title for both thief and merc ranks
// thiefrank() / mercrank()