summaryrefslogtreecommitdiff
path: root/npc/012-1
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2022-10-23 21:44:22 -0300
committerJesusaves <cpntb1@ymail.com>2022-10-23 21:44:22 -0300
commita7c45a192268da2601cef47a4cdba987ae2327ca (patch)
treec5fb5b97db109fe7106496dd96498c475881046b /npc/012-1
downloadserverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.gz
serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.bz2
serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.xz
serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.zip
Initial commit (Moubootaur Legends fork)
Diffstat (limited to 'npc/012-1')
-rw-r--r--npc/012-1/_import.txt26
-rw-r--r--npc/012-1/_mobs.txt10
-rw-r--r--npc/012-1/_warps.txt13
-rw-r--r--npc/012-1/andrei.txt181
-rw-r--r--npc/012-1/bot.txt137
-rw-r--r--npc/012-1/dyrinthetraveler.txt110
-rw-r--r--npc/012-1/estate.txt95
-rw-r--r--npc/012-1/guards.txt734
-rw-r--r--npc/012-1/gwendolyn.txt590
-rw-r--r--npc/012-1/hinnak.txt162
-rw-r--r--npc/012-1/igor.txt14
-rw-r--r--npc/012-1/jack.txt180
-rw-r--r--npc/012-1/locamit.txt72
-rw-r--r--npc/012-1/luffyx.txt87
-rw-r--r--npc/012-1/mahad.txt68
-rw-r--r--npc/012-1/mapflags.txt9
-rw-r--r--npc/012-1/milly.txt155
-rw-r--r--npc/012-1/richard.txt14
-rw-r--r--npc/012-1/ship.txt23
-rw-r--r--npc/012-1/shoppakep.txt81
-rw-r--r--npc/012-1/soul-menhir.txt20
-rw-r--r--npc/012-1/statue.txt31
-rw-r--r--npc/012-1/terezin.txt61
-rw-r--r--npc/012-1/town.txt13
-rw-r--r--npc/012-1/wateranimation.txt29
25 files changed, 2915 insertions, 0 deletions
diff --git a/npc/012-1/_import.txt b/npc/012-1/_import.txt
new file mode 100644
index 0000000..57e4e73
--- /dev/null
+++ b/npc/012-1/_import.txt
@@ -0,0 +1,26 @@
+// Map 012-1: Hurnscald
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+"npc/012-1/_mobs.txt",
+"npc/012-1/_warps.txt",
+"npc/012-1/andrei.txt",
+"npc/012-1/bot.txt",
+"npc/012-1/dyrinthetraveler.txt",
+"npc/012-1/estate.txt",
+"npc/012-1/guards.txt",
+"npc/012-1/gwendolyn.txt",
+"npc/012-1/hinnak.txt",
+"npc/012-1/igor.txt",
+"npc/012-1/jack.txt",
+"npc/012-1/locamit.txt",
+"npc/012-1/luffyx.txt",
+"npc/012-1/mahad.txt",
+"npc/012-1/mapflags.txt",
+"npc/012-1/milly.txt",
+"npc/012-1/richard.txt",
+"npc/012-1/ship.txt",
+"npc/012-1/shoppakep.txt",
+"npc/012-1/soul-menhir.txt",
+"npc/012-1/statue.txt",
+"npc/012-1/terezin.txt",
+"npc/012-1/town.txt",
+"npc/012-1/wateranimation.txt",
diff --git a/npc/012-1/_mobs.txt b/npc/012-1/_mobs.txt
new file mode 100644
index 0000000..12bd68b
--- /dev/null
+++ b/npc/012-1/_mobs.txt
@@ -0,0 +1,10 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Map 012-1: Hurnscald mobs
+012-1,90,63,35,14 monster Red Butterfly 1025,4,30000,90000
+012-1,90,62,36,15 monster Mana Bug 1075,5,30000,90000
+012-1,85,33,35,15 monster Pinkie 1132,8,30000,20000,Hinnak::OnKillPinkie
+012-1,44,56,21,41 monster Clover Patch 1028,3,60000,90000
+012-1,135,58,7,29 monster Piousse 1003,6,40000,60000
+012-1,85,86,52,15 monster Silk Worm 1034,5,30000,25000
+012-1,115,69,1,1 monster Training Dummy 1021,1,10000,10000
+012-1,81,59,54,35 monster Squirrel 1032,12,30000,45000
diff --git a/npc/012-1/_warps.txt b/npc/012-1/_warps.txt
new file mode 100644
index 0000000..2798abb
--- /dev/null
+++ b/npc/012-1/_warps.txt
@@ -0,0 +1,13 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Map 012-1: Hurnscald warps
+012-1,22,62,0 warp #012-1_22_62 0,3,014-3,205,92
+012-1,79,17,0 warp #012-1_79_17 3,0,014-1,78,97
+012-1,79,102,0 warp #012-1_79_102 3,0,014-2,178,22
+012-1,132,101,0 warp #012-1_132_101 2,0,014-2,232,21
+012-1,65,55,0 warp #012-1_65_55 0,0,012-2,36,46
+012-1,89,58,0 warp #012-1_89_58 0,0,012-3,41,45
+012-1,101,55,0 warp #012-1_101_55 0,0,012-4,35,30
+012-1,121,71,0 warp #012-1_121_71 0,0,012-5,34,36
+012-1,116,66,0 warp #012-1_116_66 0,0,012-5,23,26
+012-1,110,56,0 warp #012-1_110_56 0,0,012-6,58,68
+012-1,102,69,0 warp #012-1_102_69 0,0,012-7,35,64
diff --git a/npc/012-1/andrei.txt b/npc/012-1/andrei.txt
new file mode 100644
index 0000000..0f984f7
--- /dev/null
+++ b/npc/012-1/andrei.txt
@@ -0,0 +1,181 @@
+// TMW-2 Script
+// Author:
+// Jesusalva
+// Description:
+// Legendary hero
+
+// I started with 'Greetings, citzen' and then I thought on 4144.
+// He would never do such formal, hero-ish introduction. So I decided for something
+// more realistic, which sounded like a human hero (ie. a normal player).
+
+012-1,75,58,0 script Andrei Sakar NPC_ANDREI,{
+ // NLib_question ( )
+ function NLib_question {
+ //freeloop(true);
+ do {
+ @qid=rand(0,7);
+ } while (! (2**@qid) & @sortable);
+ debugmes "Question "+@qid;
+ @sortable-=(2**@qid);
+ setarray @ans$, $@NLIBa1$[@qid], $@NLIBa2$[@qid], $@NLIBa3$[@qid], $@NLIBa4$[@qid];
+ setarray @val, $@NLIBmr1[@qid], $@NLIBmr2[@qid], $@NLIBmr3[@qid], $@NLIBmr4[@qid];
+ /*
+ @nm=15;
+ @i=0;
+ debugmes "BG WHILE S00002";
+ while (@nm > 0) {
+ do {
+ @nai=rand(0,3);
+ } while ((2**@nai) & @nm);
+ debugmes "BG WS2 NODE";
+ @nm-=@nai;
+ @ans$[@i]=@as$[@nai];
+ @val[@i]=@nai;
+ }
+ debugmes "BG NO FREE LOOP";
+ //freeloop(false);
+ */
+ // Final: @ans$ ; @val ; @qid
+ // Question, menuret, QID
+
+ mes "";
+ addtimer(30000, "Andrei Sakar::OnTooLong");
+ .@q=getq3(Q_NivalisLibday);
+ setq3 Q_NivalisLibday, .@q-7;
+ mesn;
+ mesq $@NLIBqs$[@qid];
+ menuint
+ @ans$[0], @val[0],
+ @ans$[1], @val[1],
+ @ans$[2], @val[2],
+ @ans$[3], @val[3];
+ mes "";
+ deltimer("Andrei Sakar::OnTooLong");
+ if (@menuret == 1) {
+ .@q=getq3(Q_NivalisLibday);
+ setq3 Q_NivalisLibday, .@q+7;
+ mesn;
+ mesq l("That's right.");
+ next;
+ } else {
+ mesn;
+ mesq l("Sorry, but that's wrong.");
+ close;
+ }
+ debugmes "BG END";
+ // end
+ }
+
+ mesn l("Andrei Sakar, Legendary Hero");
+ if ($NLIB_DAY || ($@GM_OVERRIDE && is_admin())) goto L_Quizz;
+
+L_Default:
+ if (strcharinfo(0) == $MOST_HEROIC$)
+ mesq l("Hi, @@.", strcharinfo(0));
+ else
+ mesq l("Hi.");
+ if ($GAME_STORYLINE >= 3 && $LIGHT_HOLDER$ == "") {
+ next;
+ mesn l("Andrei Sakar, Legendary Hero");
+ mesq l("If %s meet the true form of the %s and prove to be a real hero, the sword will give itself for them. But if they fail to prove real heroism, the sword will leave after a while.", $WORLD_HERO$, getitemlink(Lightbringer));
+ next;
+ mesn l("Andrei Sakar, Legendary Hero");
+ mesq l("Not a single deed, but continued heroism. A real hero must be strong. Must help others. Must show up above others. Should have magic even if they don't use, and of course, the world should be in need of a hero. No one is born as hero, for heroes are forged, not born.");
+ next;
+ mesn l("Andrei Sakar, Legendary Hero");
+ mesq l("And remember: If it was easy, I would be wielding it right now. Instead, I use a %s. So take courage.", getitemlink(ImmortalSword));
+ }
+ close;
+
+L_Quizz:
+ .@q=getq3(Q_NivalisLibday);
+ if (.@q == 0) {
+ setq3 Q_NivalisLibday, 100;
+ .@q=100;
+ } else if (.@q > 100) {
+ goto L_Default;
+ }
+
+ mesq l("We are assembling forces to take Nivalis back.");
+ mesq l("I'll make you five questions about lore and general knowledge. You'll have 30 seconds to read and answer each.");
+ mesq l("If you finish everything, and answer everything right, you may get a reward.");
+ mesq l("If you take too long you'll be penalized.");
+ mesq l("Do you want to start?");
+ next;
+ if (askyesno() == ASK_NO)
+ close;
+ setarray @sortable, 255;
+
+ NLib_question();
+ NLib_question();
+ NLib_question();
+ NLib_question();
+ NLib_question();
+
+
+ mesn;
+ .@q=getq3(Q_NivalisLibday);
+ // You cannot go above 100 points.
+ if (.@q > 100) {
+ mesq l("...More bugs.");
+ mesc l("A bug was found. Aborting script."), 1;
+ close;
+ } else if (.@q == 100) {
+ mesq l("Congratulations. You really know about the world lore.");
+ getitem HastePotion, 2;
+ getitem StrengthPotion, 2;
+ getitem Bread, 5;
+ } else if (.@q > 90) {
+ mesq l("Outstanding. Congratulations.");
+ getitem HastePotion, 2;
+ getitem StrengthPotion, 2;
+ getitem Bread, 4;
+ } else if (.@q > 75) {
+ mesq l("Good, knowing the world lore is important.");
+ getitem HastePotion, 1;
+ getitem StrengthPotion, 1;
+ getitem Bread, 4;
+ } else if (.@q > 50) {
+ mesq l("Good job.");
+ getitem HastePotion, 1;
+ getitem StrengthPotion, 1;
+ getitem Bread, 2;
+ } else if (.@q > 25) {
+ mesq l("Well, that was bad, but at least you know a bit from story.");
+ getitem Bread, 2;
+ } else if (.@q > 0) {
+ mesq l("Terrible. You know almost nothing from world lore...");
+ getitem Bread, 1;
+ } else {
+ mesq l("You really should read the dialogs.");
+ }
+ // If you got a negative value, this will default to 1.
+ getexp .@q*BaseLevel, .@q*JobLevel;
+ setq3 Q_NivalisLibday, 9999;
+ close;
+
+OnTooLong:
+ .@q=getq3(Q_NivalisLibday);
+ setq3 Q_NivalisLibday, .@q-21;
+ npctalk3 l("You took too long to answer.");
+ close;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 5;
+ /* Because I was lazy to calculate array size, it is hard-coded to eight questions numbered from 0 to 7.
+ setarray $@NLIBqs$;
+ setarray $@NLIBa1$;
+ setarray $@NLIBa2$;
+ setarray $@NLIBa3$;
+ setarray $@NLIBa4$;
+ setarray $@NLIBmr1;
+ setarray $@NLIBmr2;
+ setarray $@NLIBmr3;
+ setarray $@NLIBmr4;
+ */
+ if ($FIRESOFSTEAM >= 10)
+ disablenpc .name$;
+ end;
+
+}
diff --git a/npc/012-1/bot.txt b/npc/012-1/bot.txt
new file mode 100644
index 0000000..3a6422b
--- /dev/null
+++ b/npc/012-1/bot.txt
@@ -0,0 +1,137 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+// Description:
+// Introduces the new area ingame
+// Quest:
+// TODO: Quest, requires 1× LOFCoin (obtain for free with Pyndragon)
+// Reward: Mouboo Figurine
+
+012-1,82,59,0 script LOFBot NPC_PLAYER,{
+ .@q=getq(HurnscaldQuest_LOFPass);
+ if (rand2(1,5) % 2 == 1) {
+ mesn;
+ mesq l("Ah, @@ is sooo amazing!", $MOST_HEROIC$);
+ next;
+ }
+ mesn;
+ mesq l("Have you ever heard of the [@@http://landoffire.org/|Land Of Fire@@]? It is a really cool game which is being developed by Pyndragon and Pihro!");
+ next;
+ mesn;
+ mesq l("They had a TMWA server, but the Monster King went hyperactive and... Well, it crashed here.");
+ if (.@q == 0) goto L_Quest;
+ if (.@q == 1) goto L_Report;
+ if (.@q == 2) goto L_Report; // To accomodate Pyn's node. Not required.
+
+L_Menu:
+ mes "";
+ menu
+ l("How can I reach the Land Of Fire?"), L_Where,
+ l("Tell me about the Land Of Fire."), L_Fire,
+ l("What are the Transcendence Gates?"), L_Gates,
+ l("Thanks for the help."), L_Close;
+
+// TODO: Perhaps it is worth mentioning on JSaves Castle is a Mana Source and thus, magic&skills work better, and weapons work worse?
+L_Where:
+ mes "";
+ mesn;
+ mesq l("If you head west, you'll eventually reach the magical Kamelot Castle.");
+ next;
+ mesn;
+ mesq l("Inside it, there'll be a Transcendence Gate.");
+ next;
+ mesn;
+ mesq l("It is a really cool place. You must visit it someday!");
+ next;
+ goto L_Menu;
+
+L_Fire:
+ mes "";
+ mesn;
+ mesq l("The Land Of Fire Village was the result from the collapse of two worlds. It is a huge village.");
+ next;
+ mesq l("It have lots of lava caves, and some cool stuff, like the @@, can only be craft there.", getitemlink(SaviorArmor));
+ next;
+ mesq l("Unique monsters can be found there, and people say about staffs which shoot raw death and doom from it!");
+ next;
+ mesq l("It's self sufficient economically, and many fairies enjoy travelling there. In fact, rumors says the Fairy Kingdom is near it!");
+ next;
+ goto L_Menu;
+
+L_Gates:
+ mes "";
+ mesn;
+ mesq l("Ah, you'll find on the Land Of Fire Village four transcendence gates.");
+ next;
+ mesn;
+ mesq l("People from here always look dumbfolded when they walk past them and find themselves somewhere else.");
+ next;
+ mesn;
+ mesq l("There's usually not a lot of things to do past these gates, but some monsters which only lives on the Land of Fire can only be found there!");
+ next;
+ goto L_Menu;
+
+L_Close:
+ closedialog;
+ npctalkonce l("Ah, @@ is so amazing!", $MOST_HEROIC$);
+ close;
+
+L_Quest:
+ mesn;
+ mesq l("Actually, could I ask you a favor?");
+ next;
+ mesn;
+ mesq l("I want a %s so badly... Pyndragon, in the forge, the master blacksmith which makes powerful weapons for high levels, can give you one.", getitemlink(LOFCoin));
+ next;
+ mesn;
+ mesq l("Just tell him that I want to reconsider, and that I want the souvenir he offered me when I moved to Hurnscald.");
+ next;
+ setq HurnscaldQuest_LOFPass, 1;
+ goto L_Menu;
+
+L_Report:
+ mes l("Did you brought me a %s?", getitemlink(LOFCoin));
+ next;
+ if (askyesno() == ASK_YES) goto L_Check;
+ goto L_Menu;
+
+L_Check:
+ if (!countitem(LOFCoin)) goto L_NoItem;
+ inventoryplace MoubooFigurine, 1;
+ delitem LOFCoin, 1;
+ getitem MoubooFigurine, 1;
+ getexp 400, 20;
+ setq HurnscaldQuest_LOFPass, 3;
+ mesn;
+ mesq lg("Thanks, my friend.");
+ next;
+ mesn;
+ mesq l("Here, you can have this souvenir.");
+ mesc l("* Item obtained: %s", getitemlink(MoubooFigurine));
+ next;
+ goto L_Menu;
+
+L_NoItem:
+ mesn;
+ mesq l("I want a %s so badly... Pyndragon, in the forge, the master blacksmith which makes powerful weapons for high levels, can give you one.", getitemlink(LOFCoin));
+ next;
+ mesn;
+ mesq l("Just tell him that I want to reconsider, and that I want the souvenir he offered me when I moved to Hurnscald.");
+ next;
+ goto L_Menu;
+
+OnInit:
+ .@npcId = getnpcid(.name$);
+ setunitdata(.@npcId, UDT_HEADTOP, CenturionHelmet);
+ setunitdata(.@npcId, UDT_HEADMIDDLE, SaviorArmor);
+ setunitdata(.@npcId, UDT_HEADBOTTOM, TulimsharGuardBoots);
+ setunitdata(.@npcId, UDT_WEAPON, BromenalPants);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 1);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 1);
+ npcsit;
+
+ .sex = G_OTHER;
+ .distance = 5;
+ end;
+}
+
diff --git a/npc/012-1/dyrinthetraveler.txt b/npc/012-1/dyrinthetraveler.txt
new file mode 100644
index 0000000..318ad6a
--- /dev/null
+++ b/npc/012-1/dyrinthetraveler.txt
@@ -0,0 +1,110 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+// Description:
+// The Travelers travel around the world telling stories.
+
+012-1,119,52,0 script Dyrin The Traveler NPC_M_COINKEEPER,{
+
+ mesn;
+ if (strcharinfo(0) == $MOST_HEROIC$) mesq l("Wow! Are you @@? Everyone, in every city, talks about you!", $MOST_HEROIC$);
+ if (strcharinfo(0) == $MOST_HEROIC$) next;
+
+ mesq l("Hello. I am @@, and I am from a family of travellers. We travel though the whole world, looking for exotic goods.", .name$);
+ next;
+ mesq l("You can buy rare items with me, or I can tell you about different cities in our world.");
+
+L_Menu:
+ mes "";
+ menu
+ l("I want to trade with you."), L_Trade,
+ l("Tell me about Halinarzo."), L_Halin,
+ l("Tell me about Hurnscald."), L_Hurns,
+ l("Tell me about Nivalis."), L_Nival,
+ l("Tell me about Artis."), L_Artis,
+ l("Sorry, I'll pass."), L_Close;
+
+L_Hurns:
+ mes "";
+ mesn;
+ mesq l("Hurnscald was founded after Tulimshar, in more fertile lands. Their walls are not so sturdy as the ones of Tulimshar.");
+ next;
+ mesq l("Under the leadership of King Wusher, they were the first to accept immigrants from other races. You will find humans and non-humans there.");
+ next;
+ mesq l("The fertile climate is ideal for mushrooms. You can also find lots of wood.");
+ next;
+ mesq l("Their economy provide many edible items and potions.");
+ next;
+ goto L_Menu;
+
+L_Halin:
+ mes "";
+ mesn;
+ mesq l("Halinarzo was founded to explore Mana Stones.");
+ next;
+ mesq l("You can find both huge swamps, as huge desertic areas near and on it.");
+ next;
+ mesq l("Lizards are the main monster found, and they steal gold from innocent bypassers.");
+ next;
+ mesq l("Without any mana stone left, and because the walls were not very strong, most of the city was destroyed.");
+ next;
+ mesq l("Unlike many other cities, if you want people in eternal need of items, there is a good place to look.");
+ next;
+ goto L_Menu;
+
+L_Nival:
+ mes "";
+ mesn;
+ mesq l("Nivalis was the last human settlement built during the First Era.");
+ next;
+ mesq l("It's cold, harsh climate makes difficult to live there. It was founded by people thrown away from Tulimshar and Hunrscald for political reasons.");
+ next;
+ mesq l("The cold climate is ideal for slimes, penguins, and other icy creatures. You can find lots of... ice, of course!");
+ next;
+ mesq l("Some items are only produced in Nivalis. After all, it is hard to work properly with ice in a desert!");
+ next;
+ goto L_Menu;
+
+L_Artis:
+ mes "";
+ mesn;
+ mesq l("Artis is a city port founded after the Great Fire on the other continent.");
+ next;
+ mesq l("People say it is the second biggest city from the world.");
+ next;
+ mesq l("Different kind of monsters live near the city. For example, blubs. I have no idea of what are those.");
+ next;
+ mesq l("People usually dock there when travelling to the second continent. Nothing exceptional about economy.");
+ next;
+ if ($FIRESOFSTEAM) {
+ mesq l("They used to export food and other things but there has been radio silence recentely; Which is why Andrei Sakar and a group of adventurers borrowed Nard's ship and went to investigate.");
+ next;
+ }
+ goto L_Menu;
+
+L_Trade:
+ mesn;
+ mesq l("Use your @@ as currency!", getitemlink(StrangeCoin));
+ tutmes l("%s is obtained during events, daily logins, heroic deeds, gifts, etc. But cannot be bought with real money.", getitemlink(StrangeCoin));
+ next;
+ openshop "Aeros Trader";
+ closedialog;
+
+L_Close:
+ close;
+
+OnInit:
+ .@npcId = getnpcid(.name$);
+ setunitdata(.@npcId, UDT_HEADTOP, NPCEyes);
+ setunitdata(.@npcId, UDT_HEADMIDDLE, UglyChristmasSweater); // All travelers wear this stuff
+ setunitdata(.@npcId, UDT_HEADBOTTOM, TulimsharGuardBoots);
+ setunitdata(.@npcId, UDT_WEAPON, SilkPants);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 13);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 12);
+ npcsit;
+
+ .sex = G_MALE;
+ .distance = 5;
+ end;
+}
+
diff --git a/npc/012-1/estate.txt b/npc/012-1/estate.txt
new file mode 100644
index 0000000..96912a8
--- /dev/null
+++ b/npc/012-1/estate.txt
@@ -0,0 +1,95 @@
+// TMW2: Moubootaur Legends scripts.
+// Author:
+// Jesusalva
+// Description:
+// Real Estate System
+
+// ID: 1
+// $ESTATE_OWNER[.id] → Account ID owner of the Real Estate
+// $ESTATE_OWNERNAME$[.id] → Human readable name of Real Estate owner
+// $ESTATE_RENTTIME[.id] → When the rent will expire
+// $ESTATE_MOBILIA_2[.id] → Bitmask of mobilia currently purchased on Monster Collision (6) (Use on walls only)
+// $ESTATE_MOBILIA_4[.id] → Bitmask of mobilia currently purchased on Air Collision (2)
+// $ESTATE_MOBILIA_8[.id] → Bitmask of mobilia currently purchased on Water Collision (3)
+// $ESTATE_MOBILIA_32[.id] → Bitmask of mobilia currently purchased on Yellow Collision (4)
+// $ESTATE_MOBILIA_64[.id] → Bitmask of mobilia currently purchased on Normal Collision (1)
+// $ESTATE_MOBILIA_128[.id] → Bitmask of mobilia currently purchased on Player Collision (5)
+// $ESTATE_PASSWORD$[.id] → Password to enter the estate. If it is "", then no password required
+// Note: GMs and Administrators can always use super password "mouboo" to enter a locked estate
+// $ESTATE_DOORBELL[.id] → If doorbell is disabled (enabled by default)
+
+// REAL_ESTATE_CREDITS → Credits equivalent to GP the player have. Will be used first.
+
+// The sign is the main controller
+012-1,94,70,0 script Sign#RES_0128 NPC_SWORDS_SIGN,{
+ if ($ESTATE_RENTTIME[.id] < gettimetick(2))
+ goto L_RentAvailable;
+
+ if ($ESTATE_OWNER[.id] == getcharid(3))
+ goto L_Manage;
+
+ if (is_admin() && $@GM_OVERRIDE)
+ goto L_Manage;
+
+ mesc l("This estate currently belongs to @@.", $ESTATE_OWNERNAME$[.id]);
+ mesc l("Press the doorbell?");
+ next;
+ if (askyesno() == ASK_YES)
+ doevent "Doorbell#RES_0128::OnDoorbell";
+ close;
+
+L_RentAvailable:
+ realestate_rent(.id, .price);
+ close;
+
+L_Manage:
+ realestate_manage(.id, (.price*7/10));
+ close;
+
+OnInit:
+ .sex = G_OTHER;
+ .distance = 3;
+
+ // Estate Settings
+ .id=1; // Estate ID
+ .price=60000; // Monthly rent price. Renew is only 70% from this value.
+ end;
+
+}
+
+// Door entrance
+012-1,95,69,0 script #RES_0128 NPC_HIDDEN,0,0,{
+ end;
+OnTouch:
+ if ($ESTATE_RENTTIME[.id] < gettimetick(2))
+ goto L_RentAvailable;
+
+ if ($ESTATE_OWNER[.id] == getcharid(3) || $ESTATE_PASSWORD$[.id] == "")
+ goto L_Warp;
+
+ mesc l("The door is locked");
+ next;
+ mesc l("However, it can be unlocked if you know the password:");
+ if (is_gm()) mesc l("You can use super password \"mouboo\" to unlock the door."), 1;
+ input .@password$;
+ // GMs can use super password "mouboo"
+ if (.@password$ == $ESTATE_PASSWORD$[.id] || (is_gm() && .@password$ == "mouboo"))
+ goto L_Warp;
+ close;
+
+L_Warp:
+ warp "012-8", 33, 33;
+ closeclientdialog;
+ close;
+
+L_RentAvailable:
+ dispbottom l("This estate is available for rent, talk to the sign to rent it.");
+ close;
+
+OnInit:
+ // Estate Settings
+ .id=1; // Estate ID
+ end;
+
+}
+
diff --git a/npc/012-1/guards.txt b/npc/012-1/guards.txt
new file mode 100644
index 0000000..d36cc5b
--- /dev/null
+++ b/npc/012-1/guards.txt
@@ -0,0 +1,734 @@
+// TMW2 scripts.
+// Authors:
+// Jesusalva
+// Description:
+// Protect Hurnscald
+
+012-1,71,24,0 script Lieutenant Paul NPC_PLAYER,{
+ .@q=getq(HurnscaldQuest_Lieutenant);
+ .@k=getq2(HurnscaldQuest_Lieutenant);
+ // The Monster King guild have a special menu
+ if (!$HURNS_LIBDATE && is_master()) goto L_Admus;
+ if (strcharinfo(2) == "Monster King") goto L_MKControl;
+ mesn;
+ mesq l("It is %s since the last great attack from the Monster King.", FuzzyTime($HURNS_LIBDATE,1,2));
+ next;
+ mesn;
+ mesq l("Many citzens are still cowering in fear. Paths are closed, economy is a disaster, things are not as they should be.");
+ next;
+ mesn;
+ mesq l("But we are working day and night. We hope that soon, more people come out and this place gets lively again.");
+ if (BaseLevel >= 20 && MPQUEST && .@q <= 15) goto L_Quest;
+ close;
+
+// Paul's quest
+L_Quest:
+ next;
+ // Quest State, Legacy value
+ @fc=0;
+ if (.@q == 0 && BaseLevel >= 20) @fc=1;
+ if (.@q == 1 && BaseLevel >= 22) @fc=2;
+ if (.@q == 2 && BaseLevel >= 24) @fc=3;
+ if (.@q == 3 && BaseLevel >= 26) @fc=4;
+ if (.@q == 4 && BaseLevel >= 28) @fc=5;
+ if (.@q == 5 && BaseLevel >= 30) @fc=6;
+ if (.@q == 6 && BaseLevel >= 32) @fc=7;
+ if (.@q == 7 && BaseLevel >= 34) @fc=8;
+ if (.@q == 8 && BaseLevel >= 36) @fc=9;
+ if (.@q == 9 && BaseLevel >= 38) @fc=10;
+ if (.@q == 10 && BaseLevel >= 40) @fc=11;
+ if (.@q == 11 && BaseLevel >= 44) @fc=12;
+ if (.@q == 12 && BaseLevel >= 48) @fc=13;
+ if (.@q == 13 && BaseLevel >= 52) @fc=14;
+ if (.@q == 14 && BaseLevel >= 56) @fc=15;
+ if (.@q == 15 && BaseLevel >= 60) @fc=16;
+ if (@fc)
+ goto L_Assign;
+ mesn;
+ mesq l("I see you are a Monster Hunting Quest Participant, right? I don't need your help right now, but maybe later, who knows?");
+ close;
+
+L_Assign:
+ // 2 ** 0 = 1 * 100 = 100 mob points
+ // 2 ** 1 = 2 * 99 = 198 mob points
+ // 2 ** 2 = 4 * 98 = 392 mob points
+ // ...
+ // 2 ** 9 = 512 * 91 = 46592 mob points (when fc = 10)
+ // Then comes the stupdly high table
+ // 2 ** 10 = 1024 * 90 = 92,160 mpt (when fc = 11)
+ // 2 ** 11 = 2048 * 89 = 182k
+ // 2 ** 12 = 4096 * 88 = 360k
+ // 2 ** 13 = 8192 * 87 = 712k
+ // ... 2 ^ 15 * 85 = 2.8 million
+ @rq=(2**(@fc-1))*(101-@fc);
+ if (@fc == 16) @rq=1500000;
+
+ // Check if you already met objective
+ if (.@k > 0 && Mobpt >= .@k+@rq) {
+ setq HurnscaldQuest_Lieutenant, @fc, 0;
+ // Do not deduct mob points anymore because gathering them without spending is a challenge on its own.
+ // Mobpt-=@rq;
+ mesn;
+ mesq l("Good job collecting the monster points for me. Here's your reward.");
+ @xp=1000;
+ // reward is 30% from reference level exp to level up
+ switch (@fc) {
+ case 1: @xp=486; break;
+ case 2: @xp=597; break;
+ case 3: @xp=751; break;
+ case 4: @xp=1028; break;
+ case 5: @xp=1342; break;
+ case 6: @xp=2399; break;
+ case 7: @xp=3128; break;
+ case 8: @xp=4190; break;
+ case 9: @xp=5303; break;
+ case 10: @xp=6532; break;
+ /* After this it demands so much XP, I raised the rate from 30 to 100%
+ case 11: @xp=10234; break;
+ case 12: @xp=12630; break;
+ case 13: @xp=15908; break;
+ case 14: @xp=19212; break;
+ case 15: @xp=22792; break;
+ case 16: @xp=34577; break;
+ */
+ case 11: @xp=34212; break;
+ case 12: @xp=53026; break;
+ case 13: @xp=75973; break;
+ case 14: @xp=142784; break;
+ case 15: @xp=215198; break;
+ case 16: @xp=365914; break;
+ }
+ getexp @xp, @fc*3;
+ Zeny=Zeny+@fc*15+@fc;
+ mesc l("* Gained @@ EXP and @@ Job Exp", @xp, @fc*3);
+ mesc l("* Gained @@ GP", @fc*15+@fc);
+ // Welcome to the stupid table
+ if (@fc >= 10) {
+ switch (@fc) {
+ case 10:
+ .@tea=Coffee; .@gift=BronzeGift; .@rare=ScrollSTerranite;
+ break;
+ case 11:
+ .@tea=ChamomileTea; .@gift=SilverGift; .@rare=WhiskeyAle;
+ break;
+ case 12:
+ .@tea=SpearmintTea; .@gift=SilverGift; .@rare=PrecisionPotion;
+ break;
+ case 13:
+ .@tea=OolongTea; .@gift=GoldenGift; .@rare=SacredLifePotion;
+ break;
+ case 14:
+ .@tea=JasmineTea; .@gift=GoldenGift; .@rare=MercBoxEE;
+ break;
+ case 15:
+ .@tea=YerbaMate; .@gift=PrismGift; .@rare=MysteriousFruit;
+ break;
+ default: // 16+
+ .@tea=ElixirOfLife; .@gift=PrismGift; .@rare=MylarinDust;
+ break;
+ }
+ mesc l("For your incredibly hard work, you got:");
+ mesf("* %d %s", 1, getitemlink(.@tea));
+ mesf("* %d %s", 1, getitemlink(.@gift));
+ mesf("##B* %d %s##b", 1, getitemlink(.@rare));
+ getitem .@rare, 1;
+ getitem .@gift, 1;
+ getitem .@tea, 1;
+ }
+ close;
+ }
+ // Assign quest
+ else if (.@k == 0) {
+ mesn;
+ mesq l("Maybe you can help our city. I see you are a Monster Hunting Quest Participant, right?");
+ next;
+ mesn;
+ mesq l("So, I'm placing a special bounty for @@ Mob Points.", @rq);
+ mesq l("You currently have @@, so if you accept and come back later with @@ Mob Points, I'll mark the bounty as complete.", Mobpt, Mobpt+@rq);
+ next;
+ mesc l("Accept quest?");
+ if (askyesno() == ASK_YES) {
+ setq HurnscaldQuest_Lieutenant, @fc-1, Mobpt;
+ }
+ }
+ // Resume quest
+ else {
+ // Reset if needed
+ if (Mobpt-.@k < 0) {
+ setq2 HurnscaldQuest_Lieutenant, Mobpt;
+ .@k=0;
+ }
+ mesn;
+ mesq l("You have collected @@/@@ Mob Points.", Mobpt-.@k, @rq);
+ }
+ close;
+
+///////////////////////////
+// Liberation Day facility
+///////////////////////////
+L_Admus:
+ mes ".:: " + col("HURNSCALD LIBERATION DAY - ADMUS PANEL", 2) + " ::.";
+ mesc l("For HLib, a GM must take the role of the Monster King");
+ mesc("Protip: Use @hide to not interfere.");
+ mes l("Determine Team Size (If everyone is ready and stdby at Tulimshar, use: @@. Minimum 2 players.)", getusers(1)-1);
+ input $@BG1_SIZE;
+ if ($@BG1_SIZE < 2 && !$@GM_OVERRIDE) close;
+ $@BG1_SIZE=$@BG1_SIZE+1;
+
+ kickwaitingroomall("Hurnsguard");
+ setmapflagnosave("012-1", "000-1", 22, 22);
+ //setmapflag("012-1", mf_nocommand); // This is just too powerful!
+ setmapflag("012-1",mf_zone,"MMO"); // MMO Zone: Overrides GM Commands
+ setmapflag("012-1", mf_battleground);
+ setmapflag("012-1", mf_nopenalty);
+ setmapflag("012-1",mf_bexp,126);
+ enablenpc "Hurnsguard";
+ donpcevent "Hurnsguard::OnSet";
+ donpcevent "Lieutenant Paul::OnSet";
+ addmapmask "012-1", MASK_MATTACK;
+ addmapmask "012-1", MASK_EVILSANCTUM;
+ pvpon("012-1");
+ disablenpc "#012-1_22_62";
+ disablenpc "#012-1_79_17";
+ disablenpc "#012-1_79_102";
+ disablenpc "#012-1_132_101";
+ disablenpc "#012-1_65_55";
+ disablenpc "#012-1_89_58";
+ disablenpc "#012-1_101_55";
+ disablenpc "#012-1_121_71";
+ disablenpc "#012-1_116_66";
+ disablenpc "#012-1_110_56";
+ disablenpc "#012-1_102_69";
+ disablenpc "Andrei Sakar";
+ disablenpc "Dyrin The Traveler";
+ disablenpc "Gwendolyn";
+ disablenpc "Jack";
+ disablenpc "Locamit";
+ disablenpc "Richard";
+ disablenpc "Soul Menhir#hurns";
+ disablenpc "HurnsShip#M";
+ disablenpc "Hinnak";
+ disablenpc "Tezzerin";
+ disablenpc "Luffyx";
+ disablenpc "Shoppa Kep";
+ announce "##1Hear ya, hear ya! There are "+str($@BG1_SIZE-1)+" vacant slots at Hurnsguard to LIBERATE HURNSCALD!", bc_all | bc_npc;
+ mesc "You are assigned to Monster Forces. Do not leave Hurnscald.", 1;
+ close;
+
+// Monster King Siege (deprecated)
+L_MKControl:
+ mesn;
+ mes l("Oh noes! You've found the Hurnscald control panel!");
+ next;
+ select
+ l("Abort"),
+ l("Initiate a siege");
+ mes "";
+ if (@menu == 2) {
+ doevent "#HurnscaldSiege::OnStartSiege";
+ closedialog;
+ }
+ close;
+
+// Hurnscald Liberation Day Core Logic
+OnSet:
+ .CYCLES=0;
+ waitingroom("Monster Army", 2, "start#hurns_lib::OnReadyCheck", 1);
+ end;
+
+OnEnterBG:
+ debugmes "Paul::OnEnterBG";
+ $@FK_Team2 = waitingroom2bg("012-1",141, 65,"start#hurns_lib::OnPlayer2Quit","start#hurns_lib::OnPlayer2Death");
+ setbgteam $@FK_Team2, 2;
+ end;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 4;
+
+ .@npcId = getnpcid(.name$);
+ setunitdata(.@npcId, UDT_HEADTOP, BullHelmet);
+ setunitdata(.@npcId, UDT_HEADMIDDLE, LieutenantArmor);
+ setunitdata(.@npcId, UDT_HEADBOTTOM, RaidTrousers);
+ setunitdata(.@npcId, UDT_SHIELD, LousyMoccasins); // TODO FIXME: Display Boots
+ setunitdata(.@npcId, UDT_WEAPON, Backsword);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 12);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 15);
+
+ end;
+}
+
+// Liberation Day Script
+012-1,122,25,0 script Hurnsguard NPC_PLAYER,{
+ //query_sql("SELECT online FROM `char` WHERE name='Saulc GM'", .@online);
+ // TODO
+ .@online=$@BG1_SIZE;
+ if (!.@online) {
+ mesn;
+ mesq l("We are planning to take over Hurnscald from the Monster King, and we will need everybody's help.");
+ next;
+ mesn;
+ mesq l("As soon that Saulc GM get back, we can start.");
+ close;
+ }
+ mesc l("Hurnscald Liberation Day special event"), 3;
+ mes "";
+ mesc l("The objective of this event is to ##Bslay the Monster Admiral##b.");
+ mesc l("If you die, you ##Bwon't##b be able to rejoin, but you won't suffer the penalty.");
+ next;
+ mesc l("If all players there die, Hurnscald WON'T BE LIBERATED.");
+ mesc l("This basically means that it'll be another day without it.");
+ mesc l("Also, the more players survive, the better rewards will be given.");
+ next;
+ mesc l("Right click on this NPC to join the Hurnscald Alliance."), 3;
+ mesc l("The number of players must be precise, meaning if someone doesn't joins,");
+ mesc l("the event won't start and HURNSCALD WON'T BE LIBERATED.");
+ next;
+ mesc l("Once you join the Alliance, you won't be able to talk with people outside it.");
+ mesc l("Additionaly, all your movement will be restricted until either you're warped or log out.");
+ close;
+
+OnSet:
+ waitingroom("Hurnscald Alliance", $@BG1_SIZE, "start#hurns_lib::OnReadyCheck", $@BG1_SIZE-1);
+ end;
+
+OnInit:
+ .CYCLES=0;
+ .@npcId = getnpcid(.name$);
+ setunitdata(.@npcId, UDT_HEADTOP, GoldenWarlordPlate); // Light armor
+ setunitdata(.@npcId, UDT_HEADMIDDLE, JeansChaps); // Pants
+ setunitdata(.@npcId, UDT_HEADBOTTOM, DeepBlackBoots); // Shoes
+ setunitdata(.@npcId, UDT_WEAPON, BugSlayer);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 13);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 7);
+ if ($HURNS_LIBDATE)
+ disablenpc(.name$);
+ end;
+
+OnEnterBG:
+ debugmes "Alliance::OnEnterBG";
+ $@FK_Team1 = waitingroom2bg("012-1",141, 65,"start#hurns_lib::OnPlayerQuit","start#hurns_lib::OnPlayerDeath");
+ setbgteam $@FK_Team1, 1;
+ end;
+
+OnDoEvent:
+ debugmes "OnDoEvent";
+ mapannounce("012-1", "Find and slay the Monster Admiral! DO NOT ATTACK GUARDS. Don't let everyone die!", bc_map);
+ .@Pl=getmapusers("012-1");
+ .CYCLES=0;
+
+ // Guards won't attack the Monster Staff
+ areamonster("012-1", 52, 45, 127, 80, "Monster Sergeant", Forain, .@Pl/3+1, "Hurnsguard::OnXtreem");
+ areamonster("012-1", 52, 45, 127, 80, "Monster Sergeant", Moonshroom, .@Pl/2+1, "Hurnsguard::OnXtreem");
+ areamonster("012-1", 52, 45, 127, 80, "Monster Soldier", AngryScorpion, .@Pl, "Hurnsguard::OnSkip");
+ for (.@i = 0; .@i < .@Pl; .@i++)
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Friendly Guard", FallenGuard1, "Cassia::OnSkip");
+ initnpctimer();
+ end;
+
+OnSkip:
+ // Here, coins drop rate are based on REMAINING PLAYERS and DEFEATED MONSTER LEVEL.
+ // A level 100 monster can have a 5% drop bonus against a level 0 monster.
+ // You have 1.2% of base chance, plus 0.5% each player + 0.05% each monster level.
+ if (rand(10000) <= 120 + (getmapusers("012-1")*50) + (strmobinfo(3,killedrid)*5))
+ getmapxy(.@m$, .@x, .@y, 0);
+ makeitem(any(Plushroom, Chagashroom, Bread, HalfCroconut, Aquada, CasinoCoins, CactusCocktail, AppleCocktail, CherryCocktail), any(1,1,2), "012-1", .@x, .@y);
+ end;
+
+OnTimer300000:
+ .@Pl=getmapusers("012-1")+mobcount("012-1", "Cassia::OnSkip")-1;
+ .@Pla=getmapusers("012-1");
+ .@Mb=mobcount("012-1", "Hurnsguard::OnSkip")+mobcount("012-1", "Hurnsguard::OnXtreem")+2; // Saulc GM is an enemy for server code
+ for (.@i = 0; .@i < .@Pla; .@i++)
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Friendly Guard", FallenGuard1, "Cassia::OnSkip");
+
+ // See if we need extra guards, depending on how outnumbered allied forces are.
+ if ((.@Mb / .@Pl) > 7) {
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
+ }
+ if ((.@Mb / .@Pl) > 6) {
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
+ }
+ if ((.@Mb / .@Pl) > 5) {
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
+ }
+ if ((.@Mb / .@Pl) > 4) {
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
+ }
+ if ((.@Mb / .@Pl) > 3) {
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
+ }
+ .@Pl=getmapusers("012-1")+mobcount("012-1", "Cassia::OnSkip")-1;
+ .@Pla=getmapusers("012-1")-1;
+
+ mapannounce("012-1", "Survivors: "+.@Pla+" Hurnscald Alliance: "+.@Pl+" Monsters: "+.@Mb, bc_map);
+ initnpctimer;
+ end;
+
+OnTimer10000:
+OnTimer120000:
+OnTimer240000:
+ .CYCLES=.CYCLES+1;
+
+ // Scripted monsters
+ if (.CYCLES == 2) {
+ mapannounce("012-1", "Monster Lieutenant appears! Watch out!", bc_map);
+ bg_monster($@FK_Team2, "012-1", 65, 71, "Monster Lieutenant", NightScorpion, "Hurnsguard::OnXtreem");
+ } else if (.CYCLES == 3) {
+ mapannounce("012-1", "Monster Admiral appears! Kill it to liberate Hurns!", bc_map);
+ .@boss=bg_monster($@FK_Team2, "012-1", 65, 71, "Monster Admiral", GiantMutatedBat, "Hurnsguard::OnVictory");
+ // Give huge amounts of health to the boss (Default: 43310)
+ setunitdata(.@boss, UDT_MAXHP, 100000);
+ setunitdata(.@boss, UDT_HP, 100000);
+ }
+
+ // One monster per user alive
+ .@Pl=getmapusers("012-1");
+ for (.@i = 0; .@i < .@Pl; .@i++) {
+ .@monsterId=any(CaveMaggot, RedSlime, LavaSlime, BlackScorpion,
+ AngryRedScorpion, Sarracenus, Snake, MountainSnake, GreenSlime,
+ Bandit, BlackScorpion, HouseMaggot, AngryScorpion, MagicGoblin,
+ Pinkie, Mouboo, Scorpion, Yeti);
+
+ bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", .@monsterId, "Hurnsguard::OnSkip");
+ // 40% odds of having an extra monster spawned (player loop)
+ if (rand(1,5) % 2 == 0)
+ bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", .@monsterId, "Hurnsguard::OnSkip");
+ }
+ // One slime blast per general
+ .@Mgg=mobcount("012-1", "Hurnsguard::OnXtreem");
+ for (.@i = 0; .@i < .@Mgg; .@i++) {
+ bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", SlimeBlast, "Cassia::OnSkip");
+ }
+ // One Magic Goblin or Pinkie per cycle
+ for (.@i = 0; .@i < .CYCLES; .@i++) {
+ if (rand(1,2) == 1)
+ bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", Pinkie, "Hurnsguard::OnSkip");
+ else
+ bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", MagicGoblin, "Hurnsguard::OnSkip");
+ }
+ // Spawn Angry Scorpions on the whole map. These monsters are neutral!
+ areamonster("012-1", 33, 16, 137, 100, "Monster Soldier", AngryScorpion, .CYCLES, "Hurnsguard::OnSkip");
+
+ // One extra guard on every summon
+ bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
+ end;
+
+OnXtreem:
+ if (rand2(0,100) > 50)
+ getitem StrangeCoin, 2;
+ // Here, the drop is a Bronze Gift, based on living players and players nearby.
+ // You have 0.1% of base chance, plus 0.2% each fighting player + 1% each near player.
+ getmapxy(.@m$, .@x, .@y, 0);
+ if (rand(10000) <= 10 + (getmapusers("012-1")*20) + (getareausers("012-1", .@x-8, .@x+8, .@y-8, .@y+8)*100))
+ makeitem(BronzeGift, 1, "012-1", .@x, .@y);
+ end;
+
+OnVictory:
+ $HURNS_LIBDATE=gettimetick(2);
+ removemapflag("012-1", mf_nosave);
+ disablenpc "Hurnsguard";
+ pvpoff("012-1");
+ removemapmask "012-1", MASK_MATTACK;
+ removemapmask "012-1", MASK_EVILSANCTUM;
+ //removemapflag("012-1", mf_nocommand);
+ setmapflag("012-1",mf_zone,"Normal2"); // Revert MMO Zone
+ removemapflag("012-1", mf_battleground);
+ removemapflag("012-1", mf_bexp);
+ setmapflag("012-1",mf_bexp,100);
+ enablenpc "#012-1_22_62";
+ enablenpc "#012-1_79_17";
+ enablenpc "#012-1_79_102";
+ enablenpc "#012-1_132_101";
+ enablenpc "#012-1_65_55";
+ enablenpc "#012-1_89_58";
+ enablenpc "#012-1_101_55";
+ enablenpc "#012-1_121_71";
+ enablenpc "#012-1_116_66";
+ enablenpc "#012-1_110_56";
+ enablenpc "#012-1_102_69";
+ enablenpc "Andrei Sakar";
+ enablenpc "Dyrin The Traveler";
+ enablenpc "Gwendolyn";
+ enablenpc "Jack";
+ enablenpc "Locamit";
+ enablenpc "Richard";
+ enablenpc "Soul Menhir#hurns";
+ enablenpc "HurnsShip#M";
+ enablenpc "Hinnak";
+ enablenpc "Tezzerin";
+ enablenpc "Luffyx";
+ enablenpc "Shoppa Kep";
+ announce "##2Hurnscald was recovered!", bc_all | bc_npc;
+ killmonster("012-1", "All");
+ changemusic "012-1", "tws_birds_in_the_sunrise.ogg"; // Play a more peaceful tune.
+ stopnpctimer;
+ maptimer("012-1", 10, "Hurnsguard::OnReward");
+ // Here, coins drop rate are based on REMAINING PLAYERS and DEFEATED MONSTER LEVEL.
+ // You have $coinsrate of base chance, plus 2% for each living player.
+ // $coinsrate is set on Aeros Event Master, and defaults to 6%
+ if (rand(10000) <= $coinsrate + (getmapusers("012-1")*200))
+ getmapxy(.@m$, .@x, .@y, 0);
+ makeitem(StrangeCoin, 1, "012-1", .@x, .@y);
+ //Karma=Karma+1;
+ $MOST_HEROIC$=strcharinfo(0);
+ bg_destroy(1);
+ bg_destroy(2);
+ // Auto-schedule Liberation Day
+ // a month from now, to happen on a saturday
+ .@offset = gettime(GETTIME_WEEKDAY); // How long since sunday?
+ .@offset += 1; // Move it to Saturday
+ .@offset += 30; // Add a month
+ .@offset += gettimeparam(GETTIME_DAYOFMONTH); // Apply offset to the all days
+ $NLIB_SEQDAY = .@offset; // Schedule the event
+
+ end;
+
+OnReward:
+ bg_leave();
+ // Let's say we have 5 players for reference. Subtract a Game Master, he doesn't counts.
+ .@Pl=getmapusers("012-1")-1;
+ getexp .@Pl*600, .@Pl*30; // 3,000 exp, 150 jxp
+ Zeny=Zeny+.@Pl*300; // 1,500 gp
+ specialeffect(FX_FANFARE, AREA, getcharid(3));
+ end;
+
+}
+
+////////////////////////////////////////////////
+//== Battleground Engine ======================
+////////////////////////////////////////////////
+012-1,0,0,0 script start#hurns_lib NPC_HIDDEN,{
+OnInit:
+ end;
+
+OnEnable:
+ end;
+
+OnPlayerQuit:
+OnPlayerDeath:
+OnPlayer2Quit:
+OnPlayer2Death:
+ bg_leave();
+ // Check if we are done for.
+ warp "000-1", 22, 22;
+ .@Pl=getmapusers("012-1");
+ if (.@Pl <= 1 && !$@GM_OVERRIDE) {
+ announce "##1Hurnscald is lost!", bc_all | bc_npc;
+ disablenpc "Hurnsguard";
+ pvpoff("012-1");
+ removemapmask "012-1", 10;
+ removemapflag("012-1", mf_nocommand);
+ removemapflag("012-1", mf_battleground);
+ killmonster("012-1", "all");
+ bg_destroy(1);
+ bg_destroy(2);
+ }
+ end;
+
+OnReadyCheck:
+ .@Alliance = getwaitingroomstate(0,"Hurnsguard");
+ debugmes "Check:" +str(.@Alliance)+"<"+ str($@BG1_SIZE-1);
+ if ( .@Alliance < $@BG1_SIZE-1 )
+ end;
+ donpcevent "Hurnsguard::OnEnterBG";
+ donpcevent "Lieutenant Paul::OnEnterBG";
+ debugmes "Prepare Warp";
+ bg_warp $@FK_Team1,"012-1",141, 65;
+ bg_warp $@FK_Team2,"012-1",69, 71;
+ changemusic "012-1", "misuse.ogg";
+ donpcevent "Hurnsguard::OnDoEvent";
+ //initnpctimer;
+ end;
+}
+
+////////////////////////
+// Handle Guard's logic
+////////////////////////
+function script CheckpointGuard {
+ mesn;
+ mesq l("I am stationed here to protect Hurnscald from monsters.");
+ next;
+ mesn;
+ mesq l("If the Monster King attacks, I will try to control inbound monsters here.");
+ close;
+ return;
+}
+
+012-1,81,18,0 script Checkpoint Guard#1 NPC_GUARD2,{
+ CheckpointGuard();
+ end;
+
+OnInit:
+ .sex = G_FEMALE;
+ .distance = 5;
+ end;
+}
+
+
+012-1,26,60,0 script Checkpoint Guard#2 NPC_GUARD1,{
+ CheckpointGuard();
+ end;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 5;
+ end;
+}
+
+012-1,80,98,0 script Checkpoint Guard#3 NPC_GUARD2,{
+ CheckpointGuard();
+ end;
+
+OnInit:
+ .sex = G_FEMALE;
+ .distance = 5;
+ end;
+}
+
+
+012-1,134,98,0 script Checkpoint Guard#4 NPC_GUARD1,{
+ CheckpointGuard();
+ end;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 5;
+ end;
+}
+
+012-1,94,56,0 script Guard#012-1.1 NPC_GUARD1,{
+ .@q=getq(HurnscaldQuest_HungryGuard);
+ if (.@q == 0) {
+ mesn l("Guard");
+ mesq l("Hey, you! Could you bring me an @@?", getitemlink(RedApple));
+ next;
+ mesn l("Guard");
+ mesq l("I'm hungry like a bear :b");
+ if (!countitem(RedApple))
+ close;
+ select
+ l("Here, you can have this one!"),
+ l("Nope, sorry!");
+ mes "";
+ if (@menu == 1) {
+ delitem RedApple, 1;
+ setq HurnscaldQuest_HungryGuard, 1;
+ getexp 500, 0;
+ mesn l("Guard");
+ mesq l("Oooh, many thanks! ^.^");
+ }
+ close;
+ }
+ legiontalk;
+ end;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 5;
+ end;
+}
+
+
+012-1,112,65,0 script Guard#012-1.2 NPC_GUARD2,{
+ legiontalk;
+ end;
+
+OnInit:
+ .sex = G_FEMALE;
+ .distance = 5;
+ end;
+}
+
+
+
+012-1,0,0,0 script #HurnscaldSiege NPC_HIDDEN,{
+ end;
+
+// Begin Siege
+OnMKSiege:
+ $@SIEGE_ABORTED = false;
+OnStartSiege:
+ kamibroadcast(col("WARNING! WARNING! Monster Army is moving towards Hurnscald!!",1));
+ do_siege("012-1", "014-3", "HURNS", TP_HURNS, .name$, .siegetime);
+ initnpctimer;
+ end;
+
+// Timers
+OnTimer5000:
+ .siegetime+=5;
+ do_siege("012-1", "014-3", "HURNS", TP_HURNS, .name$, .siegetime);
+ switch (.siegetime) {
+ // Monster Army arrives in town
+ case 60:
+ disablenpc "Oscar";
+ disablenpc "Gwendolyn";
+ disablenpc "Milly";
+ disablenpc "LOFBot";
+ disablenpc "Locamit";
+ disablenpc "Andrei Sakar";
+ disablenpc "Luffyx";
+ disablenpc "Tezzerin";
+ disablenpc "Hinnak";
+ disablenpc "Igor";
+ disablenpc "Dyrin The Traveler";
+ disablenpc "Mahad";
+ disablenpc "Jack";
+ break;
+ // Monster Army deployed in town
+ case 90:
+ disablenpc "Shoppa Kep";
+ disablenpc "Richard";
+
+ disablenpc "Celestia";
+ disablenpc "Airlia";
+ disablenpc "Nicholas";
+ disablenpc "Wyara";
+ disablenpc "Alan";
+ disablenpc "Khafar";
+ disablenpc "Melina";
+ disablenpc "Helena";
+ disablenpc "Rakinorf, Mayor";
+ break;
+ // Monster army have withdrawn completly
+ case MK_SIEGE_DURATION:
+ .siegetime=0;
+ announce(("Hurnscald siege is over!"), bc_all);
+ enablenpc "Gwendolyn";
+ enablenpc "Milly";
+ enablenpc "LOFBot";
+ enablenpc "Locamit";
+ enablenpc "Andrei Sakar";
+ enablenpc "Luffyx";
+ enablenpc "Tezzerin";
+ enablenpc "Hinnak";
+ enablenpc "Igor";
+ enablenpc "Dyrin The Traveler";
+ enablenpc "Mahad";
+ enablenpc "Jack";
+ enablenpc "Shoppa Kep";
+ enablenpc "Richard";
+ enablenpc "Celestia";
+ enablenpc "Airlia";
+ enablenpc "Nicholas";
+ enablenpc "Wyara";
+ enablenpc "Alan";
+ enablenpc "Khafar";
+ enablenpc "Melina";
+ enablenpc "Helena";
+ enablenpc "Rakinorf, Mayor";
+ enablenpc "Oscar";
+ stopnpctimer;
+ end;
+ break;
+ }
+
+ // Loop again
+ initnpctimer;
+ end;
+
+OnInit:
+ .siegetime=0;
+ end;
+}
+
diff --git a/npc/012-1/gwendolyn.txt b/npc/012-1/gwendolyn.txt
new file mode 100644
index 0000000..42953dd
--- /dev/null
+++ b/npc/012-1/gwendolyn.txt
@@ -0,0 +1,590 @@
+// TMW2 Script
+// Author:
+// The Mana World Team
+// Edited by:
+// Jesusalva
+// Description:
+// Archery Trainer
+
+012-1,88,52,0 script Gwendolyn NPC_BOWMASTER,{
+ .@q=getq(HurnscaldQuest_HarkEye);
+ .@fbow=getq(HurnscaldQuest_ForestBow);
+
+ if (.@q == 6) goto L_State6;
+ if (.@q == 5) goto L_State5;
+ if (.@q == 4) goto L_State4;
+ if (.@q == 3) goto L_State3;
+ if (.@q == 2) goto L_State2;
+ if (.@q == 1) goto L_State1;
+
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Hey there. My name is Gwendolyn Bowmaker; I'm the granddaughter of the famous Glinda Bowmaker.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("She and her husband Simon Bowmaker, vowed to teach the ways of archery to those with willpower, and allow everyone to use a bow.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("I intend to continue with my family's tradition, by teaching the Way of Archery.");
+ setq HurnscaldQuest_HarkEye, 1;
+ next;
+
+L_State1:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Are you interested in becoming a student of Archery?");
+ next;
+ menu
+ l("I want to become an archer!"),L_Fee,
+ l("I'm not interested right now."),L_Abort;
+
+L_Fee:
+ mes "";
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Wonderful! My fee is @@. This fee is the first step in separating those with willpower, from those without.", .SCHOOLFEE);
+ next;
+ menu
+ l("That's a lot, but I think it will be worth it."),L_Next,
+ l("I'm not sure I want to spend that much."),L_Abort;
+
+L_Next:
+ mes "";
+ if (Zeny < .SCHOOLFEE)
+ goto L_No_Money;
+
+ Zeny = Zeny - .SCHOOLFEE;
+ setq HurnscaldQuest_HarkEye, 2;
+
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Great! The first thing you need is, obviously, a bow. You should not use any you come across, but a high quality one.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Inside this house is my brother Alan. He knows how to make Forest Bows of exquisite quality.");
+ next;
+
+ if (countitem("ForestBow") < 1) {
+ goto L_Close;
+ }
+ select
+ l("I already have a Forest Bow.");
+ mes "";
+
+L_State2:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Let me see your bow.");
+ next;
+
+ if (countitem("ForestBow") < 1)
+ goto L_NoBow;
+ if (.@fbow < 2)
+ goto L_FakeBow;
+
+ setq HurnscaldQuest_HarkEye, 3;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Very well, this looks fine. It is time for your first lesson.");
+ next;
+ goto L_Lesson;
+
+L_Lesson:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("The advantage of fighting with a ranged weapon is that you can stay out of the enemy's range. So there is no need to spend training on your resistance.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("But remember: This makes you much more vulnerable, and you usually cannot hit from too close, so watch your step and don't stumble into your enemy's attack.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Also your strength doesn't matter much. It helps you to carry more arrows with you, but nothing a few trips to the store won't do.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("The most important thing to improve is your dexterity. When you use a bow, it is your dexterity that determines if you are able to hit your enemy where it hurts most.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Also worth mentioning is how to improve your ability to shoot fast. You need to be agile to grab a new arrow from your quiver and aim for the next shot before your enemy has recovered from your last.");
+ next;
+
+L_State3:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("To demonstrate that you understood what I'm trying to teach you, you should go and fight against some snakes. I know they're strong, but that's not important to an archer.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("To prove me your results, bring me @@ @@, @@ @@ and @@ @@.",
+ .CAVE_EGGS_AMOUNT, getitemlink(CaveSnakeEgg),
+ .SNAKE_EGGS_AMOUNT, getitemlink(SnakeEgg),
+ .MOUNTAIN_EGGS_AMOUNT, getitemlink(MountainSnakeEgg));
+ next;
+ menu
+ l("Can you please repeat your lesson?"),L_Lesson,
+ l("I will go and hunt some snakes."),L_Close,
+ l("I have what you want."),L_Next1;
+
+L_Next1:
+ mes "";
+ if (countitem("CaveSnakeEgg") < .CAVE_EGGS_AMOUNT
+ ||countitem("SnakeEgg") < .SNAKE_EGGS_AMOUNT
+ ||countitem("MountainSnakeEgg") < .MOUNTAIN_EGGS_AMOUNT)
+ goto L_Insufficient;
+
+ delitem "CaveSnakeEgg", .CAVE_EGGS_AMOUNT;
+ delitem "SnakeEgg", .SNAKE_EGGS_AMOUNT;
+ delitem "MountainSnakeEgg", .MOUNTAIN_EGGS_AMOUNT;
+
+ getexp .QUEST_EGG_EXP, 100;
+
+ setq HurnscaldQuest_HarkEye, 4;
+
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Very well. That will make a great meal. You pass!");
+ next;
+
+L_State4:
+ if (BaseLevel < .BASELEVEL_GAME)
+ goto L_NotReady;
+ if (!MAGIC_LVL)
+ goto L_NotReady;
+ mesc l("Gwendolyn takes an analyzing look at you. Then she nods.");
+ next;
+ setq HurnscaldQuest_HarkEye, 5;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Ok. You have made great progress. I think you are ready for further tasks.");
+ next;
+ goto L_Explain;
+
+L_Explain:
+ mes "";
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("As you might have noticed, it depends on many circumstances if your arrow finds its target. Your shot may be too powerful or too weak, so the arrow goes far beyond your target or hits the ground before it reaches its destination.");
+ next;
+ mesq l("The greater the distance to your target is, the more important is the strength and direction of the wind. Even if you are exploring a cave, there might be air flow caused by the corners in the cave.");
+ next;
+ mesq l("Ok, you can see that target over there? I will tell you how strong the wind blows and from which direction. Then you will try to hit the target by moving right or left and decide how powerful you want to shoot.");
+ next;
+ goto L_State5;
+
+L_State5:
+ // needed for the minigame:
+ .@wdX = 0; // wind direction x-coordinate, rand
+ .@wdY = 0; // wind direction y-coordinate, rand
+ // set .@wp, 0; // windpower
+ .@spX = 0; // start position x-coordinate, player decision
+ // set .@spY, 0; // start position y-coordinate, const
+ .@sp = 0; // shotpower, player decision
+ //set .@targetX, 0; // target position, const
+ //set .@targetY, 20; // target position, const
+ .@pointX = 0; // point the player hits, x-coordinate
+ .@pointY = 0; // point the player hits, y-coordinate
+ .@wdIndex = 0;
+ //
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Show me what you can!");
+ next;
+ menu
+ l("Can you please explain the task again?"),L_Explain,
+ l("I'm ready, let's start!"),L_Game,
+ l("I'm sorry, I will come back later."),L_Close;
+
+L_Game:
+ mes "";
+ if (countitem(ForestBow) < 1)
+ goto L_NoBow;
+ if (countitem(TrainingArrow) < 1)
+ goto L_Arrows;
+ delitem TrainingArrow, 1;
+ mesc l("You go to the training field and stand exactly on the same level with the target. The target is located about 13 meters north of you. You take one arrow and look at Gwendolyn.");
+ next;
+
+ // possibility for wdX and wdY to become zero is reduced, so windless status is less often
+ .@wdX = rand(9) - 4;
+ if (.@wdX != 2 && .@wdX !=-2) .@wdX = rand(9) - 4;
+ if (.@wdX == 0) .@wdX = rand(9) - 4;
+
+ .@wdY = rand(9) - 4;
+ if (.@wdY != 2 && .@wdY !=-2) .@wdY = rand(9) - 4;
+ if (.@wdY == 0) .@wdY = rand(9) - 4;
+
+ // wind direction array, where the wind blows to:
+ // 123
+ // 456
+ // 789
+ //here is where the wind comes from, that's why it is the opposite.
+ setarray .@wd$,"error1, please report", l("southeast"), l("south"), l("southwest"), l("east"),
+ "error2, please report", l("west"), l("northeast"), l("north"), l("northwest");
+ @paramX = .@wdX;
+ @paramY = .@wdY;
+ callsub S_getDirection;
+ .@wdIndex = @returnIndex;
+
+ // Cheat
+ if (is_admin() && debug)
+ dispbottom l("Wind: @@, @@",.@wdX,.@wdY);
+
+ .@wp_sq = (.@wdX * .@wdX) + (.@wdY * .@wdY);
+
+ if (.@wp_sq == 0)
+ goto L_wp0;
+ if (.@wp_sq < 3)
+ goto L_wp1;
+ if (.@wp_sq < 9)
+ goto L_wp2;
+ if (.@wp_sq < 19)
+ goto L_wp3;
+ goto L_wp4;
+
+
+L_wp0:
+ mesn l("Gwendolyn Bowmaker");
+ mesq lg("You're lucky. It is windless now.");
+ next;
+ goto L_Start;
+
+L_wp1:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("There is a slight breeze coming from @@.", .@wd$[.@wdIndex]);
+ next;
+ goto L_Start;
+
+L_wp2:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("The wind is blowing from @@.", .@wd$[.@wdIndex]);
+ next;
+ goto L_Start;
+
+L_wp3:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Right now, there is a strong wind blowing from @@.", .@wd$[.@wdIndex]);
+ next;
+ goto L_Start;
+
+L_wp4:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Here we have a squall from @@.", .@wd$[.@wdIndex]);
+ next;
+ goto L_Start;
+
+L_Start:
+ mesc l("Do you want to go to the left, the right or stay where you are?");
+ next;
+ menu
+ l("I want to move left."),L_Left,
+ l("I go right."),L_Right,
+ l("I stay."),L_Stay,
+ l("I will try it later."),L_Close;
+
+L_Stay:
+ .@spX = 0;
+ mesc l("You stay where you are..");
+ next;
+ goto L_Power;
+
+L_Left:
+ mesc l("How many steps?");
+ next;
+ menu
+ "1",L_Left1,
+ "2",L_Left2,
+ "3",L_Left3,
+ "4",L_Left4;
+
+L_Left1:
+ .@spX = -1;
+ mesc l("You take one step to the left.");
+ next;
+ goto L_Power;
+
+L_Left2:
+ .@spX = -2;
+ mesc l("You take two steps to the left.");
+ next;
+ goto L_Power;
+
+L_Left3:
+ .@spX = -3;
+ mesc l("You take three steps to the left.");
+ next;
+ goto L_Power;
+
+L_Left4:
+ .@spX = -4;
+ mesc l("You take four steps to the left.");
+ next;
+ goto L_Power;
+
+L_Right:
+ mesc l("How many steps?");
+ next;
+ menu
+ "1",L_Right1,
+ "2",L_Right2,
+ "3",L_Right3,
+ "4",L_Right4;
+
+L_Right1:
+ .@spX = 1;
+ mesc l("You take one step to the right.");
+ next;
+ goto L_Power;
+
+L_Right2:
+ .@spX = 2;
+ mesc l("You take two steps to the right.");
+ next;
+ goto L_Power;
+
+L_Right3:
+ .@spX = 3;
+ mesc l("You take three steps to the right.");
+ next;
+ goto L_Power;
+
+L_Right4:
+ .@spX = 4;
+ mesc l("You take four steps to the right.");
+ next;
+ goto L_Power;
+
+L_Power:
+ mes "";
+ mesc l("How powerfully do you want to shoot?");
+ next;
+ select
+ l("very weak shot"),
+ l("rather weak shot"),
+ l("weak shot"),
+ l("somewhat weak shot"),
+ l("medium shot"),
+ l("somewhat powerful shot"),
+ l("powerful shot"),
+ l("rather powerful shot"),
+ l("very powerful shot");
+
+ // we have 9 menu entries, so scale @menu, which is in range 1-9, to a scale in -4 to +4
+ .@sp = @menu - 5;
+ // calculate where you hit. You range is in [-8, 8] in X and Y as well
+ .@pointX = .@wdX + .@spX;
+ .@pointY = .@wdY + .@sp;
+
+ // Debug information. If you move wind info to above, you CHEAT.
+ if (is_admin()) {
+ dispbottom l("Wind: @@, @@",.@wdX,.@wdY);
+ dispbottom l("You: @@, @@",.@spX,.@sp);
+ dispbottom l("Final: @@, @@",.@pointX,.@pointY);
+
+ }
+
+ if( .@pointX==0 && .@pointY==0 )
+ goto L_Success;
+
+ //set .@targethit to these numbers:
+ //1,2,3 for left above, above, right above,
+ //4,5,6 for left, hit, right
+ //7,8,9 for lower left, below, lower right;
+ setarray .@target_direction$, "error3, please report", l("left above"), l("above"), l("right above"), l("left"),
+ "error4, please report", l("right"), l("lower left"), l("below"), l("lower right");
+
+ @paramX = .@pointX;
+ @paramY = .@pointY;
+ callsub S_getDirection;
+ .@targethit = @returnIndex;
+
+ //now check how close
+ //get the distance squared:
+ // so it is in range 0 - 64:
+ // 0 is hit
+ // < 5 is very close
+ // <17 is close
+ // rest is a quite bad shot
+ .@target_dist_sq = (.@pointX * .@pointX) + (.@pointY*.@pointY);
+
+ if (.@target_dist_sq < 5)
+ goto L_Quite;
+ if (.@target_dist_sq < 17)
+ goto L_Almost;
+
+ //here are bad shots:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("D'oh, what a terrible shot!");
+ next;
+ mesq l("Do you even know what a bow is?");
+ next;
+ mesq l("That was far @@.", .@target_direction$[.@targethit]);
+ next;
+ goto L_Game;
+
+L_Almost:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("That was @@.", .@target_direction$[.@targethit]);
+ next;
+ mesq l("I suggest some training.");
+ next;
+ goto L_Game;
+
+L_Quite:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("That was quite close. Impressive!");
+ next;
+ mesq l("It was a little @@.", .@target_direction$[.@targethit]);
+ next;
+ mesq l("But you did not hit... have another try.");
+ next;
+ // You might get unlucky and the wind may change
+ if(rand(5) == 2) goto L_Game;
+ mesq l("Hurry up, before the wind changes.");
+ next;
+ goto L_Start;
+
+L_Success:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Wonderful! That was great! Directly hit the bull's eye!"); // TRANSLATORS: manner of speak, "to hit exactly on the target"
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Maybe you did it, after all!");
+ next;
+ mesq l("Let me inspect it...");
+ mesc l("She walks to the target.");
+ next;
+ if( rand2(400) > (2*readparam2(bDex) + readparam2(bAgi)))
+ goto L_Miss;
+
+ setq HurnscaldQuest_HarkEye, 6;
+
+ skill TMW2_CHARGEDARROW, 1, 0;
+ getexp .QUEST_HAWK_EXP, 0;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Perfect indeed! Congratulations!");
+ next;
+
+ mesq l("Remember, there is always something new to learn. And you should not let your training down in order to keep and improve your abilities.");
+ next;
+ goto L_Close;
+
+L_Miss:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Ohh! A fingernail aside.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("That is quite impressive, but you can perform better with more training.");
+ next;
+ goto L_Game;
+
+L_State6:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("You really have a reason to be proud.");
+ next;
+ goto L_Close;
+
+L_Abort:
+ mes "";
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("That's a pity. Well, if you change your mind, come back any time.");
+ next;
+ goto L_Close;
+
+L_No_Money:
+ mes "";
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("I am sorry, but it seems that you don't have enough money. Come back when you have reorganized your finances.");
+ next;
+ goto L_Close;
+
+L_NoBow:
+ mesq l("As an archer, you should always carry your bow with you. Doesn't warriors carry those heavy swords without complaining? Go and get it.");
+ next;
+ mesq l("Also, I don't care if you don't like the @@. That's the weapon a true archer should use!", getitemlink(ForestBow));
+ goto L_Close;
+
+L_FakeBow:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("You just bought it? You won't learn anything from that.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("To understand the nature of this bow, you have to collect the needed material by yourself. Only this way will you get a feeling of what it means to use such a weapon.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("The best thing would be to let you make the bow by yourself. But I guess, that would go to far. And it would take ages to get a high quality bow.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Do as I told you, and talk to Alan for the bow!");
+ next;
+ goto L_Close;
+
+L_Insufficient:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Maybe I should also give you a lesson in how to count? You don't have enough.");
+ next;
+ goto L_Close;
+
+L_NotReady:
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("I am pleased about your progress, but you are not ready for the next step yet. Go and do some more training, before you come back.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Remember also: It is wise to speak with people you meet on your journey, there is always something new to learn.");
+ next;
+ goto L_Close;
+
+L_Arrows:
+ mesc l("Gwendolyn sighs and shake her head.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("Another lecture: Take always enough arrows with you. Go and come back when you are equipped adequately.");
+ next;
+ mesn l("Gwendolyn Bowmaker");
+ mesq l("For this training, I need @@, not the usual arrow you use.", getitemlink(TrainingArrow));
+ next;
+ goto L_Close;
+
+L_Close:
+ @paramX=0;
+ @paramY=0;
+ @returnIndex=0;
+ closedialog;
+ goodbye;
+ close;
+
+S_getDirection:
+ // get @paramX @paramY as parameters
+ // returns an index where these parameters are in relation to origin
+ // 123
+ // 456 whereas 5 is the origin. (3,6,9 there is paramX>0); (1,2,3 there is paramY>0)
+ // 789
+ //first check the quadrants and after check more precisely
+ if(@paramX>0 && @paramY>0) @returnIndex = 3;
+ if(@paramX>0 && @paramY<0) @returnIndex = 9;
+ if(@paramX<0 && @paramY>0) @returnIndex = 1;
+ if(@paramX<0 && @paramY<0) @returnIndex = 7;
+
+ //straight left
+ if ( (@paramX < 0) && (@paramY >= @paramX/2) && (-@paramY >= @paramX/2) ) @returnIndex = 4;
+
+ //straight right
+ if ( (@paramX > 0) && (@paramY <= @paramX/2) && (-@paramY <= @paramX/2) ) @returnIndex = 6;
+
+ //straight above
+ if ( (@paramY > 0) && (@paramX <= @paramY/2) && (-@paramX <= @paramY/2) ) @returnIndex = 2;
+
+ //straight below
+ if ( (@paramY < 0) && (@paramX >= @paramY/2) && (-@paramX >= @paramY/2) ) @returnIndex = 8;
+
+ //check the origin, because the origin is found by the "straight" lines as well. (should not, but is.. maybe a bug?)
+ if( @paramX==0 && @paramY==0 ) @returnIndex = 5;
+ return;
+
+OnInit:
+ // schoolfee in gp
+ .SCHOOLFEE = 2500;
+
+ // how many eggs do you need of each kind?
+ .CAVE_EGGS_AMOUNT = 21;
+ .SNAKE_EGGS_AMOUNT = 15;
+ .MOUNTAIN_EGGS_AMOUNT = 7;
+
+ // experience for eggs
+ .QUEST_EGG_EXP = 7500;
+
+ // The needed level for the minigame:
+ .BASELEVEL_GAME = 45;
+
+ // experience gained for hitting the bullseye:
+ .QUEST_HAWK_EXP = 12000;
+
+ .sex = G_FEMALE;
+ .distance = 7;
+ end;
+}
diff --git a/npc/012-1/hinnak.txt b/npc/012-1/hinnak.txt
new file mode 100644
index 0000000..47b019c
--- /dev/null
+++ b/npc/012-1/hinnak.txt
@@ -0,0 +1,162 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+// Description:
+// Hurnscald farmer.
+
+012-1,105,30,0 script Hinnak NPC_ORC,{
+ .@q1=getq(HurnscaldQuest_Farmers);
+ .@q2=getq2(HurnscaldQuest_Farmers);
+ mesn;
+ if (strcharinfo(0) == $MOST_HEROIC$) mesq l("Ah, if it isn't @@? You're the talk of the town!", $MOST_HEROIC$);
+ if (strcharinfo(0) == $MOST_HEROIC$) next;
+ if (.@q1 == 0) goto L_Start;
+ if (.@q1 == 1) goto L_Check;
+ if (.@q1 == 4) goto L_Letter;
+ if (.@q1 == 5) goto L_Thanks;
+ mesq l("Maybe you could now help my friend Oscar. His farm is west of here.");
+ close;
+
+L_Start:
+ mesq l("I hate you Pinkies, and I hate the Monster King too, for bringing forth these plagues!!");
+ next;
+ mesn strcharinfo(0);
+ mesc l("The farmer seems mad and in need of help. Will you help him?");
+ if (askyesno() != ASK_YES) {
+ mesq l("Sorry, I have to go.");
+ close;
+ }
+ next;
+ mesn;
+ mesq l("Ah, so you're willing to help? Great! Because I HATE THEM ALL!");
+ next;
+ if (readparam2(bAgi) < 20) goto L_Slow;
+ if (BaseLevel < 20) goto L_Weak;
+ mesn;
+ mesq l("They jump left and right and left and right again, and I can't catch them.");
+ next;
+ mesn;
+ mesq l("Please kill some of them, and bring me 10 @@!", getitemlink(PinkAntenna));
+ setq HurnscaldQuest_Farmers, 1, 0;
+ close;
+
+OnKillPinkie:
+ .@q1=getq(HurnscaldQuest_Farmers);
+ .@q2=getq2(HurnscaldQuest_Farmers);
+ if (.@q1 == 1) {
+ setq2 HurnscaldQuest_Farmers, .@q2+1;
+ if (! (.@q2+1) % 10)
+ dispbottom l("@@ pinkies killed on @@'s field.", .@q2+1, l("Oscar"));
+ }
+ fix_mobkill(Pinkie);
+ end;
+
+L_Slow:
+ mesn;
+ mesq l("But you're too slow to catch any of them. Sorry.");
+ next;
+ mesc l("Raise agility to do this quest.");
+ close;
+
+L_Weak:
+ mesn;
+ mesq l("But you're too weak to beat any of them. Sorry.");
+ close;
+
+L_Check:
+ mesq l("Hey, how is the monster extermination going?");
+ next;
+ mesn;
+ // You in average need to kill 244 Pinkies. You get this bonus for not leaving the fields.
+ if (.@q2 >= 210)
+ mesq l("You killed so many Pinkies, I don't care with the Antennas anymore! They are almost gone!");
+ else if (.@q2 >= 150)
+ mesq l("I see you are doing good. Keep slaying them, hahaah!");
+ else if (.@q2 >= 100)
+ mesq l("Good job, you already killed over 100! Hahah, that sure teach them a lesson!");
+ else if (.@q2 >= 50)
+ mesq l("Yeah, teach them a lesson! Keep going!");
+ else
+ mesq l("Go kill them!!");
+ next;
+ menu
+ rif (.@q2 >= 210 && countitem(PinkAntenna) >= 10, l("No, I insist, keep the Antennas as a trophy.")), L_RealHelp,
+ rif (.@q2 >= 210 && countitem(PinkAntenna) < 10, l("Thanks, they don't like to drop their Antennas.")), L_TrueHelp,
+ rif (.@q2 >= 100 && .@q2 < 210 && countitem(PinkAntenna) >= 10, l("Here are the Antennas.")), L_Help,
+ rif (.@q2 < 100 && countitem(PinkAntenna) >= 10, l("Here are the Antennas.")), L_NoKill,
+ l("I'm not done yet. I'll be back."), -;
+ close;
+
+L_RealHelp:
+ inventoryplace Scythe, 1;
+ delitem PinkAntenna, 10;
+ getexp 1600, 60;
+ Zeny=Zeny+2500;
+ setq HurnscaldQuest_Farmers, 2, 0;
+ getitem Scythe, 1;
+ mes "";
+ mesn;
+ mesq l("Waw! You really did it, you're the savior of my farm!! You have my eternal gratitute. Here is 2500 GP for your troubles!");
+ close;
+
+L_TrueHelp:
+ mes "";
+ mesn;
+ mesq l("I know how hard it is! I hate them with all my heart, only seeing you killing them left and right was GREAT!");
+ next;
+ inventoryplace Scythe, 1;
+ getitem Scythe, 1;
+ getexp 1000, 0;
+ Zeny=Zeny+500;
+ setq HurnscaldQuest_Farmers, 2, 0;
+ mesn;
+ mesq l("You have my eternal gratitute. Here is 500 GP for your troubles.");
+ close;
+
+L_Help:
+ inventoryplace Scythe, 1;
+ delitem PinkAntenna, 10;
+ getexp 1000, 0;
+ Zeny=Zeny+1000;
+ setq HurnscaldQuest_Farmers, 2, 0;
+ getitem Scythe, 1;
+ mes "";
+ mesn;
+ mesq l("Many thanks. You have my eternal gratitute. Here is 1000 GP for your troubles.");
+ close;
+
+L_NoKill:
+ mesn;
+ mesq l("That won't do it. I want to see PINK BLOOD! No... not so cluttered. Just kill the Pinkies on my farm.");
+ next;
+ mesn;
+ mesq l("The antennas by themselves mean nothing, I want to see you killing my ENEMIES, the pinkies!");
+ close;
+
+L_Letter:
+ mesq l("You're the savior of Hurnscald crops. Half from the world would die from famine, weren't for you.");
+ next;
+ mesn;
+ mesq l("@@ and I signed this letter. Deliver it to Airlia on the Town Hall, and she'll reward you correctly.", l("Oscar"));
+ close;
+
+L_Thanks:
+ mesq l("Many thanks for all the help!");
+ next;
+ GHQ_Assign(Pinkie, "Hurnscald", getitemlink(PinkHelmet) + col(l(" (Hinnak's and Oscar's fields Pinkies may not count)"), 1));
+ close;
+
+OnInit:
+ .@npcId = getnpcid(.name$);
+ setunitdata(.@npcId, UDT_HEADTOP, FarmerHat);
+ setunitdata(.@npcId, UDT_HEADMIDDLE, LeatherShirt);
+ setunitdata(.@npcId, UDT_HEADBOTTOM, TulimsharGuardBoots);
+ setunitdata(.@npcId, UDT_WEAPON, CottonTrousers);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 2);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 0);
+
+ .sex = G_MALE;
+ .distance = 5;
+ end;
+}
+
diff --git a/npc/012-1/igor.txt b/npc/012-1/igor.txt
new file mode 100644
index 0000000..dfd9b9b
--- /dev/null
+++ b/npc/012-1/igor.txt
@@ -0,0 +1,14 @@
+// TMW2 scripts.
+// Author:
+// Jesusalva
+// Description:
+// Igor gives the player latest news on the world
+
+012-1,126,59,0 script Igor NPC_JOURNALMAN,{
+ Journalman(.name$);
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 5;
+ end;
+}
diff --git a/npc/012-1/jack.txt b/npc/012-1/jack.txt
new file mode 100644
index 0000000..b36c09f
--- /dev/null
+++ b/npc/012-1/jack.txt
@@ -0,0 +1,180 @@
+// TMW-2 Script
+// Originals: TMW Org.
+//
+// Author:
+// Jesusalva
+// Description:
+// Jack is Hurnscald Lumberjack
+
+012-1,69,93,0 script Jack NPC_LUMBERJACK,{
+ .@q1=getq(HurnscaldQuest_ForestBow);
+ //.@q2=getq(HurnscaldQuest_WoodShield);
+
+ mesn "Jack, the Lumberjack";
+ mesq l("Hello there! I'm Jack, the Lumberjack, and enemy of all trees. If you need some firewood, just let me know.");
+ mes "";
+ select
+ l("Nothing at the moment, thanks."),
+ l("I want you to transform my raw log in a wooden log"),
+ rif(.@q1 == 1, l("I need a sturdy wood piece for a Forest Bow."));
+
+ mes "";
+
+ switch (@menu) {
+ case 1:
+ close;
+ break;
+ case 2:
+ goto L_Polish;
+ break;
+ case 3:
+ goto L_ForestBow;
+ break;
+ }
+
+ close;
+
+L_Polish:
+ mesn;
+ mes l("Yes, unless you're doing something VERY special, a Wooden Log is what you need.");
+ mes l("I can make a @@ for just one @@ and @@ GP for my work.", getitemlink(WoodenLog), getitemlink(RawLog), .cost);
+ input .@count;
+ mes "";
+
+ if (.@count == 0)
+ close;
+
+ .@Cost = .@count * .cost;
+ .@empty = countitem(RawLog);
+
+ if (.@empty < .@count || Zeny < .@Cost) {
+ mesn;
+ mesq l("You can't afford my services for that amount. Sorry.");
+ }
+
+ inventoryplace WoodenLog, .@count;
+
+ Zeny = Zeny - .@Cost;
+ delitem RawLog, .@count;
+ getitem WoodenLog, .@count;
+ mesc l("There you go, %s. If you don't know anything about crafting I heard someone on Tulimshar's Terranite Forge can help?", lg("gal", "pal"));
+ close;
+
+L_ForestBow:
+ .@k=getq2(HurnscaldQuest_ForestBow);
+
+ switch (.@k) {
+ case 0:
+ mesn;
+ mesq l("Ah, don't bother me with that. That wood must be special, it must bend and cannot break. Too difficult to find!");
+ next;
+ mesn;
+ mesq l("I also do not keep any stock of them. If you really want it, you can bring me some Raw Logs. I'll show you which one is the good one. Deal?");
+ next;
+ if (BaseLevel < 25) {
+ mesn;
+ mesq l("Actually, nevermind. I'll wait you grind level 25 first, then we can do this."); // Note: Fisherman part is level 30!
+ close;
+ }
+ mesn strcharinfo(0);
+ mesq l("I'm railroaded here, I cannot say no. I'll bring you some @@. Break them until one of them fit.", getitemlink(RawLog));
+ setq2 HurnscaldQuest_ForestBow, 1;
+ close;
+ break;
+ case 99:
+ mesn;
+ mesq l("Good luck...");
+ break;
+ default:
+ goto L_Loop;
+ }
+ goto L_Close;
+
+L_Loop:
+ .@k=getq2(HurnscaldQuest_ForestBow);
+ mesn;
+ mesq l("Bring me your wood, and I'll show you which one is sturdy, yet flexible enough to make a good Forest Bow.");
+ mes "";
+ select
+ rif(countitem(RawLog) > 0, l("Try this one.")),
+ l("Don't break my stuff.");
+
+ if (@menu == 2)
+ close;
+
+ mesc l("Jack bends the log over his knee.");
+ delitem RawLog, 1;
+ .@success=rand(6,26)-.@k; // You will never need more than 20 logs nor less than 5 logs
+
+ if (.@success <= 1) {
+ mesc l("The wood bends a little, but doesn't breaks.");
+ getexp 295, 100; // 10% of max exp
+ setq2 HurnscaldQuest_ForestBow, 99;
+ next;
+ mesn;
+ mesq lg("That's the right wood, my son. Here, I'll wrap it so you don't accidentaly lose it. Good luck with your quest!");
+ close;
+ } else {
+ mesc l("However, the log breaks with a loud crack.");
+ Zeny=Zeny+10;
+ getexp 5, 1;
+ setq2 HurnscaldQuest_ForestBow, .@k+1;
+ next;
+ mesn;
+ mesq lg("Sorry, son. I know how hard this is. But this is teaching you a valuable lesson, your eye will be more sharp for quality wood from now on.");
+ next;
+ }
+
+ goto L_Loop;
+
+/* Copy-paste from TMW Org.
+ I'll uncomment and rewrite when time comes.
+
+L_NohMask_Ask:
+ menu
+ "I'll keep that in mind.", L_Close,
+ "I heard you aren't delivering any more living wood. Why not?", L_Next,
+ "Have you seen anything that might be connected to the recent robberies in town?", L_NohMask_Answer;
+
+L_NohMask_Answer:
+ mesn "Jack, the Lumberjack";
+ mes "\"Sorry, no.\"";
+ goto L_Close;
+
+L_Made_Shield:
+ mesn "Jack, the Lumberjack";
+ mes "\"Speaking of that shield...\"";
+ mes "\"It has put me behind on all these new Nivalis orders, now that the ship is running there.\"";
+ next;
+ mes "\"Care to help out? I'll pay you for your time.\"";
+ goto L_Daily;
+
+L_Daily:
+ @dq_level = 30;
+ @dq_cost = 25;
+ @dq_count = 30;
+ @dq_name$ = "RawLog";
+ @dq_friendly_name$ = "raw logs";
+ @dq_money = 4000;
+ @dq_exp = 4000;
+
+ callfunc "DailyQuest";
+
+ next;
+
+ mesn "Jack, the Lumberjack";
+ mes "\"Check back with me tomorrow, and I'll let you know if I need any help with that shipment.\"";
+
+ goto L_Close;
+*/
+
+L_Close:
+ close;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 5;
+ .cost=60;
+ end;
+
+}
diff --git a/npc/012-1/locamit.txt b/npc/012-1/locamit.txt
new file mode 100644
index 0000000..c4acd9d
--- /dev/null
+++ b/npc/012-1/locamit.txt
@@ -0,0 +1,72 @@
+// TMW2 scripts.
+// Authors:
+// Saulc
+// Jesusalva
+// Reid
+// Travolta
+// Description:
+// Tamiloc is the barber.
+// Locamit is an anagram.
+
+012-1,60,73,0 script Locamit NPC_ELVEN_FEMALE_ARMOR_SHOP,{
+ function setRace {
+ clear;
+ setnpcdialogtitle l("Debug - Modify Race");
+ mes l("Race") + ": " + $@allraces$[Class];
+ next;
+ mes l("Please select the desired race.");
+ switch (select("Human:Ukar:Redy:Elf:Orc:Raijin:Tritan"))
+ {
+ default:
+ jobchange max(0, @menu-1);
+ }
+ return;
+ }
+
+
+ mesn;
+ mesq l("Hi! Do you want a hair cut?");
+
+ do
+ {
+ select
+ l("What is my current hairstyle and hair color?"),
+ l("I'd like to get a different style."),
+ l("Can you do something with my color?"),
+ rif(is_staff(), l("I am a GM, and I want to change my Race!")),
+ l("I'm fine for now, thank you.");
+
+ switch (@menu) {
+ case 1:
+ BarberSayStyle 3;
+ break;
+ case 2:
+ BarberChangeStyle;
+ speech S_FIRST_BLANK_LINE | S_LAST_NEXT,
+ l("Enjoy your new style.");
+ l("Anything else?");
+ break;
+ case 3:
+ BarberChangeColor;
+ speech S_FIRST_BLANK_LINE | S_LAST_NEXT,
+ l("I hope you like this color.");
+ l("Anything else?");
+ break;
+ case 4:
+ setRace;
+ break;
+ case 5:
+ speech S_FIRST_BLANK_LINE | S_LAST_NEXT,
+ l("Feel free to come visit me another time.");
+
+ goodbye;
+ }
+ } while (1);
+ close;
+
+
+OnInit:
+ .sex = G_FEMALE;
+ .distance = 5;
+ end;
+}
diff --git a/npc/012-1/luffyx.txt b/npc/012-1/luffyx.txt
new file mode 100644
index 0000000..d2cb239
--- /dev/null
+++ b/npc/012-1/luffyx.txt
@@ -0,0 +1,87 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+// Description:
+// Hunt mouboos, Summer Quest
+
+012-1,68,74,0 script Luffyx NPC_RAIJIN,{
+ .@q=getq(SQuest_Summer);
+ mesn;
+ if (season() == SUMMER) {
+ mesq l("Yay it's summer! I love June 21st, and the summer vacations!");
+ if (.@q < 1)
+ goto L_SummerQuest;
+ } else {
+ mesq l("Aww it's not summer. I love June 21st, and the summer vacations!");
+ }
+
+L_Main:
+ if (GHQUEST)
+ GHQ_Assign(ForestMushroom, "Hurnscald");
+ close;
+
+L_SummerQuest:
+ next;
+ mesn;
+ mesq l("Hey, do you know what is good on summer? @@!", getitemlink(LuffyxSummerShorts));
+ next;
+ mesn;
+ mes l("What about you bring me:");
+ mes l("@@/80 @@", countitem(CactusCocktail), getitemlink(CactusCocktail));
+ mes l("@@/40 @@", countitem(AppleCocktail), getitemlink(AppleCocktail));
+ mes l("@@/25 @@", countitem(CherryCocktail), getitemlink(CherryCocktail));
+ mes l("@@/1 @@", countitem(JeansShorts), getitemlink(JeansShorts));
+ next;
+ select
+ l("Not now, thanks"),
+ l("To be honest, I have that with me!");
+
+ mes "";
+ if (@menu == 1)
+ goto L_Main;
+ if (@menu == 2) {
+ if (
+ countitem(CactusCocktail) < 80 ||
+ countitem(AppleCocktail) < 40 ||
+ countitem(CherryCocktail) < 25 ||
+ !countitem(JeansShorts)
+ ) goto L_Lying;
+
+ inventoryplace LuffyxSummerShorts, 1;
+ delitem CherryCocktail, 25;
+ delitem AppleCocktail, 40;
+ delitem CactusCocktail, 80;
+ delitem JeansShorts, 1;
+ getitem LuffyxSummerShorts, 1;
+ getexp 6500, 120;
+ setq SQuest_Summer, 1;
+ mesn;
+ mesq l("Yay yay! Many thanks! Here, take the reward as promised!");
+ next;
+ mesn;
+ mesq l("We can do this again on next summer!");
+ goto L_Main;
+ }
+
+ close;
+
+L_Lying:
+ mesn;
+ mesq l("Please don't lie to me...");
+ goto L_Main;
+
+OnInit:
+ .@npcId = getnpcid(.name$);
+ setunitdata(.@npcId, UDT_HEADTOP, CommunityShirt);
+ setunitdata(.@npcId, UDT_HEADMIDDLE, JeansChaps);
+ setunitdata(.@npcId, UDT_HEADBOTTOM, DeepBlackBoots);
+ setunitdata(.@npcId, UDT_WEAPON, BugSlayer);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 13);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 7);
+
+ .distance=4;
+ .sex=G_MALE;
+ end;
+
+}
+
diff --git a/npc/012-1/mahad.txt b/npc/012-1/mahad.txt
new file mode 100644
index 0000000..e37cc69
--- /dev/null
+++ b/npc/012-1/mahad.txt
@@ -0,0 +1,68 @@
+// TMW-2 Script
+// Author:
+// Saulc
+// Jesusalva
+// Description:
+// Mahad is the Hurnscald Well Master
+// ...Well, he takes the water from the pond, but you shouldn't mind this.
+// It's still safe to drink, 100% warranted!
+// Note: You may get a Grass Carp (worth 100 GP) instead. Bottle is lost? O.o
+
+012-1,117,54,0 script Mahad NPC_PLAYER,{
+ mesn;
+ mes l("I can fill your bottle with water for only @@ gp the bottle.", .price);
+ mes l("After all, I am the Well Master!");
+ input .@count;
+ mes "";
+
+ if (!.@count)
+ close;
+
+ .@gp = .@count * .price;
+
+ // Not enough cash
+ if (Zeny < .@gp) {
+ mesn;
+ mes l("You don't have enough gold! You need @@ gp.", .@gp);
+ close;
+ }
+
+ // Not enough bottles
+ if (countitem(EmptyBottle) < .@count) {
+ mesn;
+ mes l("You don't have that many empty bottles!");
+ close;
+ }
+
+ inventoryplace GrassCarp, .@count, BottleOfWoodlandWater, .@count;
+ delitem EmptyBottle, .@count;
+
+ // Calculate how many grass carp you'll get
+ .@iced=0;
+ for (.@i=0; .@i < .@count; .@i++) {
+ if (rand(1,1000) < 11)
+ .@iced++;
+ }
+
+ // Apply the results and have a happy day!
+ Zeny-=.@gp;
+ if (.@iced)
+ getitem GrassCarp, .@iced;
+ getitem BottleOfWoodlandWater, .@count-.@iced;
+ close;
+
+OnInit:
+ .price = 60;
+ .sex = G_MALE;
+ .distance = 7;
+
+ .@npcId = getnpcid(.name$);
+ // Check items.xml for info about this
+ setunitdata(.@npcId, UDT_HEADTOP, InfantryHelmet);
+ setunitdata(.@npcId, UDT_HEADMIDDLE, SailorShirt);
+ setunitdata(.@npcId, UDT_HEADBOTTOM, RaidTrousers);
+ setunitdata(.@npcId, UDT_HAIRSTYLE, 7);
+ setunitdata(.@npcId, UDT_HAIRCOLOR, 17);
+
+ end;
+}
diff --git a/npc/012-1/mapflags.txt b/npc/012-1/mapflags.txt
new file mode 100644
index 0000000..19c4352
--- /dev/null
+++ b/npc/012-1/mapflags.txt
@@ -0,0 +1,9 @@
+012-1 mapflag town
+012-1 mapflag nopenalty
+012-2 mapflag town
+012-3 mapflag town
+012-4 mapflag town
+012-5 mapflag town
+012-6 mapflag town
+012-7 mapflag town
+012-8 mapflag town
diff --git a/npc/012-1/milly.txt b/npc/012-1/milly.txt
new file mode 100644
index 0000000..1935858
--- /dev/null
+++ b/npc/012-1/milly.txt
@@ -0,0 +1,155 @@
+// TMW2 script.
+// Authors:
+// Jesusalva
+// Description:
+// Milly here is mixed with Crastur's almanach quest.
+// She controls "World's Hero quest", which is now her MAIN QUEST;
+// But maybe later she'll get nodes about Khafar etc but not like in TMW
+//
+// Her reward is a Plush Mouboo. Along about 1000 Mouboo Figurines, and whatever
+// grand reward for completing Main Storyline, and a mega blaster level at magic,
+// and probably within another general quest, YOU CAN SUMMON THE MOUBOOTAUR
+// Eh... I think you need all seven Mana Fragments to control it, though.
+// Without these fragments, you'll just face the baddest boss fight ever and die
+// miserably, because the moubootaur is... well... Simply put... THE MOUBOOTAUR.
+
+012-1,111,66,0 script Milly NPC_TEDDYGIRL,{
+ .@q=getq(General_Milly);
+ mesn;
+ if (.@q >= 1) mesq lg("Hello my hero!");
+ else mesq l("Hello.");
+ if (.@q == 0) goto L_Assign;
+ else if (.@q == 1) goto L_Feat;
+ close;
+
+L_Assign:
+ next;
+ mesn;
+ mesq lg("hey, hey, are you a hero, are you a hero?");
+ next;
+ mesn;
+ mesq l("I want to meet a hero!");
+ next;
+ mesc b(l(".:: World's Hero Quest ::.")), 3;
+ msObjective(reputation("Candor") >= 100, l("* become @@ Hero", l("Candor")));
+ msObjective(reputation("Tulim") >= 100, l("* become @@ Hero", l("Tulimshar")));
+ msObjective(reputation("Halin") >= 100, l("* become @@ Hero", l("Halinarzo")));
+ msObjective(reputation("Hurns") >= 100, l("* become @@ Hero", l("Hurnscald")));
+ msObjective(reputation("LoF") >= 100, l("* become @@ Hero", l("Land Of Fire")));
+ msObjective(reputation("Nival") >= 100, l("* become @@ Hero", l("Nivalis")));
+ msObjective(reputation("Frostia") >= 100, l("* become @@ Hero", l("Frostia")));
+ next;
+ if (reputation("Candor") >= 100 &&
+ reputation("Tulim") >= 100 &&
+ reputation("Halin") >= 100 &&
+ reputation("Hurns") >= 100 &&
+ reputation("LoF") >= 100 &&
+ reputation("Nival") >= 100 &&
+ reputation("Frostia") >= 100) goto L_Finish;
+ mesc l("You can become a hero by completing every quest in a certain location.");
+ close;
+
+L_Finish:
+ mesn;
+ mesq lg("Wo-wo-wow! You really did it! You're the best!");
+ next;
+ mesn;
+ mesq l("But the game still is in development, so not every quest was added yet.");
+ next;
+ mesn;
+ mesq l("Do you want to get a reward nonetheless? You will lose @@.", b(l("any planned experience and gold reward.")));
+ mesc l("Also note that, under team's discretion, all rewards from this quest might be erasen along quest state.");
+ mesc l("This would mean you might need to complete this quest again in the future.");
+ next;
+ // Debug
+ percentheal 100, 100;
+ sc_start SC_ATTHASTE_POTION1, 1800000, 30;
+ /*
+ mesn;
+ mesc l("Saulc was here"), 1;
+ close;
+ */
+ // / Debug
+ if (askyesno() == ASK_YES) {
+ mes "";
+ inventoryplace PlushMouboo, 1;
+ setq General_Milly, 1;
+ getitem PlushMouboo, 1;
+ getexp 100, 100; // No, not really.
+ mesn;
+ mesq lg("Here you go, miss! Thanks for being my hero! <3", "Here you go, mister! Thanks for being my hero! <3");
+ }
+ close;
+
+L_Feat:
+ next;
+ mesn;
+ mesq l("Hey hey, can you impress me? Can you impress me?");
+ next;
+ mesn;
+ mesq l("I want you to impress me, so I can brag about you to all my friends!");
+ next;
+ mesc b(l(".:: Impressive Hero Quest ::.")), 3;
+ msObjective(YETIKING_WINNER, l("* Impress %s", l("the Yeti King")));
+ msObjective(HEROESHOLD_WINNER, l("* Impress %s", l("Colonel Dustman")));
+ msObjective(REBIRTH_WINNER, l("* Impress %s", l("Sir Phoenix")));
+ msObjective(QUIRINO_WINNER, l("* Impress %s", l("Quirin Voraz")));
+ msObjective(GEMINI_WINNER, l("* Impress %s", l("Valia Gemini")));
+ msObjective(GHQ_WINNER, l("* Impress %s", l("Aidan and Pet Detective")));
+ msObjective(EPISODE_WINNER, l("* Impress %s", l("The Doctor")));
+ msObjective(FORT_1ST_VISIT, l("* Impress %s", l("The Alliance")));
+ msObjective(MOUBOOTAUR_WINNER, l("* Impress %s", l("Andrei Sakar")));
+ mes "";
+ mesc l("You need to finish at least %d/%d tasks.", 7, 9);
+ .@t = 0;
+ if (YETIKING_WINNER) .@t += 1;
+ if (HEROESHOLD_WINNER) .@t += 1;
+ if (REBIRTH_WINNER) .@t += 1;
+ if (QUIRINO_WINNER) .@t += 1;
+ if (GEMINI_WINNER) .@t += 1;
+ if (GHQ_WINNER) .@t += 1;
+ if (EPISODE_WINNER) .@t += 1;
+ if (FORT_1ST_VISIT) .@t += 1;
+ if (MOUBOOTAUR_WINNER) .@t += 1;
+ if (.@t >= 7) goto L_Epic;
+ close;
+
+L_Epic:
+ next;
+ mesn;
+ mesq lg("Wo-wo-wow! You really did it! You're the best!");
+ next;
+ mesn;
+ mesq l("But the game still is in development, so not every great feat was added yet.");
+ next;
+ mesn;
+ mesq l("Do you want to get a reward nonetheless? You will lose @@.", b(l("any planned experience and gold reward.")));
+ mesc l("Also note that, under team's discretion, all rewards from this quest might be erasen along quest state.");
+ mesc l("This would mean you might need to complete this quest again in the future.");
+ next;
+ // Debug
+ percentheal 100, 100;
+ sc_start SC_ATTHASTE_POTION1, 1800000, 30;
+ /*
+ mesn;
+ mesc l("Saulc was here"), 1;
+ close;
+ */
+ // / Debug
+ if (askyesno() == ASK_YES) {
+ mes "";
+ inventoryplace SunnyCrystal, 1;
+ setq General_Milly, 2;
+ getitem SunnyCrystal, 1;
+ getexp 100, 100; // No, not really.
+ mesn;
+ mesq lg("Here you go, miss! Thanks for being my hero! <3", "Here you go, mister! Thanks for being my hero! <3");
+ }
+ close;
+
+OnInit:
+ .sex=G_FEMALE;
+ .distance=5;
+ end;
+}
+
diff --git a/npc/012-1/richard.txt b/npc/012-1/richard.txt
new file mode 100644
index 0000000..5dc2c31
--- /dev/null
+++ b/npc/012-1/richard.txt
@@ -0,0 +1,14 @@
+// TMW-2 Script.
+// Author:
+// Saulc
+// Jesusalva
+
+012-1,65,64,0 script Richard NPC_LLOYD,{
+ Banker(.name$, "Hurnscald", 10000);
+ close;
+
+OnInit:
+ .sex = G_MALE;
+ .distance = 4;
+ end;
+}
diff --git a/npc/012-1/ship.txt b/npc/012-1/ship.txt
new file mode 100644
index 0000000..b478e35
--- /dev/null
+++ b/npc/012-1/ship.txt
@@ -0,0 +1,23 @@
+// TMW2 scripts.
+// Authors:
+// Jesusalva
+// Description:
+// This script controls access to Ships, fixing variables.
+
+012-1,157,65,0 script HurnsShip#M NPC_HIDDEN,0,0,{
+
+OnTouch:
+ EnterTown("Hurns");
+ goto L_Warp;
+
+L_Warp:
+ /* Is Hurnscald already liberated? Precendence. */
+ if (!$HURNS_LIBDATE) {
+ warp "Save", 0, 0;
+ end;
+ }
+
+ warp "016-1@"+LOCATION$, 21, 26;
+ closedialog;
+ close;
+}
diff --git a/npc/012-1/shoppakep.txt b/npc/012-1/shoppakep.txt
new file mode 100644
index 0000000..13fb8f3
--- /dev/null
+++ b/npc/012-1/shoppakep.txt
@@ -0,0 +1,81 @@
+// TMW2 Script.
+// Author:
+// Jesusalva
+// Description:
+// Random Hurnscald Shopper with random overpriced stuff and gifts
+
+012-1,58,64,0 script Shoppa Kep NPC_SHOPPAKEP,{
+ mesn;
+ mesq lg("Welcome! Only the finest wares!");
+ next;
+ closedialog;
+ npcshopattach(.name$);
+ shop .name$;
+ close;
+
+ function ShoppaKepItem {
+ return any(Aquada, Manana, HalfEggshell, SpearmintTea);
+ }
+
+OnInit:
+ .CurrentItem=ShoppaKepItem();
+ .ThisRebootAmou=rand2(30,70);
+
+ .sex = G_FEMALE;
+ .distance = 5;
+
+
+ sleep(SHOPWAIT);
+ tradertype(NST_MARKET);
+ sellitem CottonTrousers, 80000, 1;
+ sellitem CottonSkirt, 40000, 1;
+ sellitem MiniSkirt, 35000, 1;
+ sellitem ShortTankTop, 20000, 1;
+ sellitem CottonGloves, 20000, 1;
+ sellitem CottonBoots, 10000, 1;
+
+ sellitem PinkieLeg, 500, 1;
+ sellitem Bread, -1, 50;
+ sellitem Piberries, -1, 30;
+ sellitem Plushroom, -1, 3;
+ sellitem Chagashroom, -1, 3;
+
+ sellitem PiouFeathers, -1, .ThisRebootAmou;
+ sellitem .CurrentItem, getiteminfo(.CurrentItem, ITEMINFO_BUYPRICE)*15/10, rand2(2,6);
+
+ end;
+
+OnClock1759:
+ restoreshopitem PinkieLeg, 500, 1;
+OnClock0546:
+ restoreshopitem CottonTrousers, 80000, 1;
+ restoreshopitem CottonSkirt, 40000, 1;
+ restoreshopitem MiniSkirt, 35000, 1;
+ restoreshopitem ShortTankTop, 20000, 1;
+ restoreshopitem CottonGloves, 20000, 1;
+ restoreshopitem CottonBoots, 10000, 1;
+
+ restoreshopitem Bread, -1, 50;
+ restoreshopitem Piberries, -1, 30;
+ restoreshopitem Plushroom, -1, 3;
+ restoreshopitem Chagashroom, -1, 3;
+
+ restoreshopitem PiouFeathers, -1, .ThisRebootAmou;
+
+ stopselling(.CurrentItem);
+ .CurrentItem=ShoppaKepItem();
+ sellitem .CurrentItem, getiteminfo(.CurrentItem, ITEMINFO_BUYPRICE)*15/10, rand2(2,6);
+ end;
+
+// Pay your taxes!
+OnBuyItem:
+ debugmes("Purchase confirmed");
+ PurchaseTaxes();
+ end;
+
+OnSellItem:
+ debugmes("Sale confirmed");
+ SaleTaxes();
+ end;
+}
+
diff --git a/npc/012-1/soul-menhir.txt b/npc/012-1/soul-menhir.txt
new file mode 100644
index 0000000..419541f
--- /dev/null
+++ b/npc/012-1/soul-menhir.txt
@@ -0,0 +1,20 @@
+// TMW2 scripts.
+// Author:
+// Jesusalva
+// Description:
+// Soul Menhir
+
+012-1,88,69,0 script Soul Menhir#hurns NPC_SOUL_NORMAL,{
+ @map$ = "012-1";
+ setarray @Xs, 86, 87, 86, 87;
+ setarray @Ys, 69, 70, 69, 70;
+ @x = 0;
+ @y = 0;
+ callfunc "SoulMenhir";
+ @map$ = "";
+ cleararray @Xs[0], 0, getarraysize(@Xs);
+ cleararray @Ys[0], 0, getarraysize(@Ys);
+ @x = 0;
+ @y = 0;
+ close;
+}
diff --git a/npc/012-1/statue.txt b/npc/012-1/statue.txt
new file mode 100644
index 0000000..9ff9044
--- /dev/null
+++ b/npc/012-1/statue.txt
@@ -0,0 +1,31 @@
+// TMW-2 Script
+// Author:
+// Jesusalva
+// Description:
+// These statues are of great honor to whoever have their name written in them!
+
+012-1,84,63,0 script Hero Statue#012-1 NPC_STATUE_ANDREI,{
+
+ mes l("This statue was built for memory of Andrei Sakar, the greatest hero this world has even seen.");
+ mes l("For defending Hurnscald alone and saving all its inhabitants.");
+ mes l("For fighting against the Monster King once and getting out alive to tell the story.");
+ mes l("For all his great deeds, and thousands of lives he saved, this statue is in his honor.");
+ if ($MOST_HEROIC$ == "")
+ goto L_Fame;
+ next;
+ mes l("Also in honor of @@, who did a great act of bravery recently. May they keep protecting our world!", $MOST_HEROIC$);
+
+L_Fame:
+ next;
+ mesq l("All hail the ones who proven their worth before the whole Alliance!");
+
+ HallOfHonor();
+ HallOfGuild();
+ close;
+
+OnInit:
+ .sex = G_OTHER;
+ .distance = 4;
+ end;
+}
+
diff --git a/npc/012-1/terezin.txt b/npc/012-1/terezin.txt
new file mode 100644
index 0000000..82a5d09
--- /dev/null
+++ b/npc/012-1/terezin.txt
@@ -0,0 +1,61 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+// Description:
+// Hinnak's Wife, Terezin (renamed to make an Easter Egg)
+// NPC_MONA?
+
+012-1,110,41,0 script Tezzerin NPC_ELVEN_FEMALE_READING,{
+ .@q1=getq(HurnscaldQuest_Farmers);
+ .@q2=getq2(HurnscaldQuest_Farmers);
+ if (strcharinfo(0) == $MOST_HEROIC$) mesn;
+ if (strcharinfo(0) == $MOST_HEROIC$) mesq l("Ah, @@, welcome!", $MOST_HEROIC$);
+ if (strcharinfo(0) == $MOST_HEROIC$) next;
+ if (.@q1 == 5 && .@q2 == 0) goto L_PinkieHat;
+ if (.@q1 == 4) goto L_Almost;
+ if (.@q1 >= 2) goto L_Thanks;
+ mesn;
+ mesq l("Ah, my husband Hinnak is so hard working...");
+ close;
+
+L_Almost:
+ mesn;
+ mesq l("You deserve a reward for helping my husband Hinnak, but please, get Oscar's reward first.");
+ close;
+
+L_Thanks:
+ mesn;
+ mesq l("Thanks for helping my husband. I'll think if there's something I can do for you, why don't you help Oscar on the meanwhile...?");
+ close;
+
+L_PinkieHat:
+ mesn;
+ mesq l("You deserve a reward for helping my husband. I can make you a nice gift.");
+ next;
+ mesn;
+ mesq l("Please bring me a single @@ and @@ GP, and I'll give you a memeto.", getitemlink(PinkAntenna), 6500);
+ if (countitem(PinkAntenna) < 1 || Zeny < 6500)
+ close;
+ next;
+ mesn strcharinfo(0);
+ mesc l("Give the Antenna and the GP to her?");
+ if (askyesno() != ASK_YES) {
+ mesq l("I'll seek one for you.");
+ close;
+ }
+ delitem PinkAntenna, 1;
+ if (Zeny < 6500)
+ close;
+ Zeny=Zeny-6500;
+ getitem PinkieHat, 1;
+ mesn;
+ mesq l("Here, I did this @@ for you! I'm pretty sure this is also a drop, but that's literally everything I could do for helping my husband.", getitemlink(PinkieHat));
+ setq2 HurnscaldQuest_Farmers, 1;
+ close;
+
+OnInit:
+ .sex = G_FEMALE;
+ .distance = 5;
+ end;
+}
+
diff --git a/npc/012-1/town.txt b/npc/012-1/town.txt
new file mode 100644
index 0000000..fdffb17
--- /dev/null
+++ b/npc/012-1/town.txt
@@ -0,0 +1,13 @@
+// TMW-2 Script
+// Author:
+// Jesusalva
+// Description:
+// Reset LOCATION$ when entering a town
+
+012-1,78,101,0 script #LocHurns NPC_HIDDEN,3,1,{
+OnTouch:
+ EnterTown("Hurns"); end;
+}
+012-1,132,100,0 duplicate(#LocHurns) #LocHurnsS NPC_HIDDEN,2,1
+012-1,23,61,0 duplicate(#LocHurns) #LocHurnsW NPC_HIDDEN,1,2
+012-1,78,18,0 duplicate(#LocHurns) #LocHurnsE NPC_HIDDEN,3,1
diff --git a/npc/012-1/wateranimation.txt b/npc/012-1/wateranimation.txt
new file mode 100644
index 0000000..4621afb
--- /dev/null
+++ b/npc/012-1/wateranimation.txt
@@ -0,0 +1,29 @@
+// TMW2 scripts.
+// Author:
+// gumi
+// Reid
+// Saulc
+// Jesusalva
+// Description:
+// Water animations, splash, fishes, etc...
+
+012-1,119,54,0 script #Hurn_WAM0 NPC_WATER_SPLASH,{
+
+ fishing(1,
+ CommonCarp,
+ GrassCarp,
+ BottleOfWoodlandWater);
+
+ close;
+
+OnInit:
+ .sex = G_OTHER;
+ .distance = 4;
+ end;
+}
+
+012-1,137,58,0 duplicate(#Hurn_WAM0) #Hurn_WAM1 NPC_WATER_SPLASH
+012-1,137,88,0 duplicate(#Hurn_WAM0) #Hurn_WAM2 NPC_WATER_SPLASH
+012-1,59,12,0 duplicate(#Hurn_WAM0) #Hurn_WAM3 NPC_WATER_SPLASH
+012-1,138,31,0 duplicate(#Hurn_WAM0) #Hurn_WAM4 NPC_WATER_SPLASH
+