summaryrefslogtreecommitdiff
path: root/world/map/npc/029-2
diff options
context:
space:
mode:
Diffstat (limited to 'world/map/npc/029-2')
-rw-r--r--world/map/npc/029-2/_import.txt13
-rw-r--r--world/map/npc/029-2/_mobs.txt15
-rw-r--r--world/map/npc/029-2/_warps.txt8
-rw-r--r--world/map/npc/029-2/barrels.txt63
-rw-r--r--world/map/npc/029-2/barrels_config.txt105
-rw-r--r--world/map/npc/029-2/mapflags.txt2
-rw-r--r--world/map/npc/029-2/morgan.txt132
-rw-r--r--world/map/npc/029-2/sorfina.txt388
-rw-r--r--world/map/npc/029-2/stat_reset.txt44
-rw-r--r--world/map/npc/029-2/tanisha.txt299
-rw-r--r--world/map/npc/029-2/two_arms.txt4
11 files changed, 1073 insertions, 0 deletions
diff --git a/world/map/npc/029-2/_import.txt b/world/map/npc/029-2/_import.txt
new file mode 100644
index 00000000..bbf2ecdd
--- /dev/null
+++ b/world/map/npc/029-2/_import.txt
@@ -0,0 +1,13 @@
+// Map 029-2: Candor Island Indoor
+// This file is generated automatically. All manually changes will be removed when running the Converter.
+map: 029-2.gat
+npc: npc/029-2/_mobs.txt
+npc: npc/029-2/_warps.txt
+npc: npc/029-2/barrels.txt
+npc: npc/029-2/barrels_config.txt
+npc: npc/029-2/mapflags.txt
+npc: npc/029-2/morgan.txt
+npc: npc/029-2/sorfina.txt
+npc: npc/029-2/stat_reset.txt
+npc: npc/029-2/tanisha.txt
+npc: npc/029-2/two_arms.txt
diff --git a/world/map/npc/029-2/_mobs.txt b/world/map/npc/029-2/_mobs.txt
new file mode 100644
index 00000000..faddfb5b
--- /dev/null
+++ b/world/map/npc/029-2/_mobs.txt
@@ -0,0 +1,15 @@
+// This file is generated automatically. All manually changes will be removed when running the Converter.
+// Candor Island Indoor mobs
+
+029-2.gat,33,57,24,7|monster|HouseMaggot|1050,7,100000ms,30000ms,Mob029-2::On1050
+
+
+029-2.gat,0,0,0|script|Mob029-2|-1
+{
+ end;
+
+On1050:
+ set @mobID, 1050;
+ callfunc "MobPoints";
+ end;
+}
diff --git a/world/map/npc/029-2/_warps.txt b/world/map/npc/029-2/_warps.txt
new file mode 100644
index 00000000..258f224b
--- /dev/null
+++ b/world/map/npc/029-2/_warps.txt
@@ -0,0 +1,8 @@
+// This file is generated automatically. All manually changes will be removed when running the Converter.
+// Candor Island Indoor warps
+
+029-2.gat,29,62|warp|To Outside|-1,-1,029-1.gat,40,89
+029-2.gat,22,93|warp|To Outside|-1,-1,029-1.gat,44,84
+029-2.gat,112,84|warp|To Bedroom|-1,-1,029-2.gat,44,30
+029-2.gat,103,62|warp|To Outside|-1,-1,029-1.gat,52,85
+029-2.gat,94,31|warp|To Outside|-1,-1,029-1.gat,58,80
diff --git a/world/map/npc/029-2/barrels.txt b/world/map/npc/029-2/barrels.txt
new file mode 100644
index 00000000..aba6ed58
--- /dev/null
+++ b/world/map/npc/029-2/barrels.txt
@@ -0,0 +1,63 @@
+// Barrels
+// Author: Wushin
+029-2.gat,23,86,0|script|Barrel#0|400
+{
+ setarray @npc_loc, 23, 86, 2;
+ set @barrel, 0;
+ callfunc "CheckBarrel";
+ end;
+
+OnMaggotDeath:
+ set @mobID, 1050;
+ callfunc "MobPoints";
+ end;
+}
+029-2.gat,28,86,0|script|Barrel#1|400
+{
+ setarray @npc_loc, 28, 86, 2;
+ set @barrel, 1;
+ callfunc "CheckBarrel";
+ end;
+}
+029-2.gat,31,91,0|script|Barrel#2|400
+{
+ setarray @npc_loc, 31, 91, 2;
+ set @barrel, 2;
+ callfunc "CheckBarrel";
+ end;
+}
+029-2.gat,36,85,0|script|Barrel#3|400
+{
+ setarray @npc_loc, 36, 85, 2;
+ set @barrel, 3;
+ callfunc "CheckBarrel";
+ end;
+}
+029-2.gat,40,89,0|script|Barrel#4|400
+{
+ setarray @npc_loc, 40, 89, 2;
+ set @barrel, 4;
+ callfunc "CheckBarrel";
+ end;
+}
+029-2.gat,38,91,0|script|Barrel#5|400
+{
+ setarray @npc_loc, 38, 91, 2;
+ set @barrel, 5;
+ callfunc "CheckBarrel";
+ end;
+}
+029-2.gat,29,92,0|script|Barrel#6|400
+{
+ setarray @npc_loc, 29, 92, 2;
+ set @barrel, 6;
+ callfunc "CheckBarrel";
+ end;
+}
+029-2.gat,24,91,0|script|Barrel#7|400
+{
+ setarray @npc_loc, 24, 91, 2;
+ set @barrel, 7;
+ callfunc "CheckBarrel";
+ end;
+}
diff --git a/world/map/npc/029-2/barrels_config.txt b/world/map/npc/029-2/barrels_config.txt
new file mode 100644
index 00000000..5407a944
--- /dev/null
+++ b/world/map/npc/029-2/barrels_config.txt
@@ -0,0 +1,105 @@
+// Barrels
+// Author: Wushin
+029-2.gat,33,88,24,7|monster|HouseMaggot|1050,2,100000ms,30000ms,Barrel#0::OnMaggotDeath
+-|script|#BarrelConfig|-1
+{
+ end;
+
+OnInit:
+ setarray $@BarrelBits, (1 << 20), (1 << 21), (1 << 22), (1 << 23), (1 << 24), (1 << 25), (1 << 26), (1 << 27);
+ setarray $@BarrelRewards, 533, 507, 505, 518, 537, 526;
+ set $@BarrelSpawnCnt, 1;
+ set $@BarrelSpawnId, 1050;
+ set $@BarrelSpawnName$, "House Maggot";
+ set $@BarrelMax, getarraysize($@BarrelBits);
+ end;
+}
+function|script|SetBarrelMask
+{
+ set STARTAREA, (STARTAREA & ~(NIBBLE_4_MASK) | (@barrel_tmp << NIBBLE_4_SHIFT));
+ set @barrel_tmp, 0;
+ return;
+}
+function|script|CheckBarrelQuest
+{
+ callfunc "CountBarrels";
+ set @barrel_quest, ((STARTAREA & NIBBLE_4_MASK) >> NIBBLE_4_SHIFT);
+ return;
+}
+function|script|CountBarrels
+{
+ set @barrel_count, 0;
+ set @count_tmp, 0;
+ goto L_Loop;
+
+L_Loop:
+ if (STARTAREA & $@BarrelBits[@barrel_count])
+ goto L_AddOne;
+ goto L_LoopAgain;
+
+L_AddOne:
+ set @barrel_count, (@barrel_count + 1);
+ goto L_LoopAgain;
+
+L_LoopAgain:
+ set @count_tmp, (@count_tmp + 1);
+ if (@count_tmp == getarraysize($@BarrelBits))
+ goto L_BarrelTally;
+ goto L_Loop;
+
+L_BarrelTally:
+ return;
+}
+function|script|CheckBarrel
+{
+ callfunc "PCtoNPCRange";
+ if (@npc_check)
+ goto L_Range;
+ callfunc "CheckBarrelQuest";
+ if (!(@barrel_quest == 2))
+ goto L_NoI;
+ if (STARTAREA & $@BarrelBits[@barrel])
+ goto L_Empty;
+ set STARTAREA, STARTAREA | $@BarrelBits[@barrel];
+
+ callfunc "CountBarrels";
+ if (@barrel_count == $@BarrelMax)
+ goto L_QuestReward;
+ set @player_random, rand(@barrel_count * 10);
+ set @barrel_random, rand(@barrel_count * $@BarrelMax);
+ if (@barrel_random > @player_random)
+ goto L_Spawn;
+ goto L_Reward;
+
+L_Range:
+ message strcharinfo(0), "You'll need to get closer.";
+ goto L_Return;
+
+L_NoI:
+ message strcharinfo(0), "Nothing interesting here.";
+ goto L_Return;
+
+L_Empty:
+ message strcharinfo(0), "You've already searched this barrel.";
+ goto L_Return;
+
+L_QuestReward:
+ message strcharinfo(0), "You found the bug bomb.";
+ misceffect 33;
+ set @barrel_tmp, 3;
+ callfunc "SetBarrelMask";
+ killmonster getmap() + ".gat", "Barrel#0::OnMaggotDeath";
+ goto L_Return;
+
+L_Spawn:
+ message strcharinfo(0), "Uck, More Maggots!";
+ areamonster getmap() + ".gat", @npc_loc[0], @npc_loc[1], (@npc_loc[0] + 1), (@npc_loc[1] + 1), $@BarrelSpawnName$, $@BarrelSpawnId, $@BarrelSpawnCnt, "Barrel#0::OnMaggotDeath";
+ goto L_Return;
+
+L_Reward:
+ getitem $@BarrelRewards[rand(getarraysize($@BarrelRewards))], 1;
+ goto L_Return;
+
+L_Return:
+ return;
+}
diff --git a/world/map/npc/029-2/mapflags.txt b/world/map/npc/029-2/mapflags.txt
new file mode 100644
index 00000000..ef75b6c6
--- /dev/null
+++ b/world/map/npc/029-2/mapflags.txt
@@ -0,0 +1,2 @@
+029-2.gat|mapflag|nosave|029-2,22,24
+029-2.gat|mapflag|resave|029-2,22,24
diff --git a/world/map/npc/029-2/morgan.txt b/world/map/npc/029-2/morgan.txt
new file mode 100644
index 00000000..f6679f67
--- /dev/null
+++ b/world/map/npc/029-2/morgan.txt
@@ -0,0 +1,132 @@
+// Tut mage
+// Author: Wushin
+// Gains Access to Magic School
+// See 024-2 clean that shit up
+// Morgan, liana
+function|script|MorganState
+{
+ callfunc "ClearVariables";
+ set @morgan, ((STARTAREA & NIBBLE_3_MASK) >> NIBBLE_3_SHIFT);
+ return;
+}
+function|script|SetMorganMask
+{
+ set STARTAREA, (STARTAREA & ~(NIBBLE_3_MASK) | (@morgan_tmp << NIBBLE_3_SHIFT));
+ set @morgan_tmp, 0;
+ return;
+}
+029-2,105,57,0|script|MorganDebug|355
+{
+ mes "[Morgan Debug]";
+ mes "Reset?";
+ menu
+ "Yes.", L_Reset,
+ "No.", L_End;
+L_Reset:
+ set STARTAREA, (STARTAREA & ~(NIBBLE_3_MASK) | (0 << NIBBLE_3_SHIFT));
+ mes "Reset!";
+ goto L_End;
+
+L_End:
+ end;
+
+OnInit:
+ if (!debug)
+ disablenpc "MorganDebug";
+ end;
+}
+029-2,101,57,0|script|Morgan#_M|355
+{
+ setarray @npc_loc, 101, 57, 4;
+ callfunc "PCtoNPCRange";
+ if (@npc_check)
+ goto L_Close;
+ callfunc "MorganState";
+ if (readparam(bInt) >= 5)
+ goto L_Learn;
+ goto L_NotMagic;
+
+L_Learn:
+ if (@morgan == 0)
+ goto L_NotSeen;
+ if (@morgan == 1)
+ goto L_Seen;
+ if (@morgan == 2)
+ goto L_Started;
+ if (@morgan == 3)
+ goto L_CastOnce;
+ if (@morgan == 4)
+ goto L_LearningDone;
+ goto L_Close;
+
+L_NotSeen:
+ set @morgan_tmp, 1;
+ callfunc "SetMorganMask";
+ mes "[Morgan]";
+ mes "\"Welcome to the magic school of Candor\"";
+ mes "\"My name is Morgan, I'm Head of Wizardry.\"";
+ mes "\"You appear to have the markings to use magic.\"";
+ mes "\"Granted you are still to young to cast spells.\"";
+ mes "\"But we can teach you to use simple magic devices.\"";
+ mes "\"Would you like to learn some apprentice skills?\"";
+ menu
+ "Yes.", L_Start,
+ "Maybe later", L_Close;
+
+L_Seen:
+ mes "[Morgan]";
+ mes "\"Have you returned to learn some magic?\"";
+ menu
+ "Yes.", L_Start,
+ "Maybe later", L_Close;
+
+L_NotMagic:
+ mes "[Morgan]";
+ mes "\"Hrmm you don't appear to posses enough magical talent to teach.\"";
+ goto L_Close;
+
+L_Start:
+ set @morgan_tmp, 2;
+ callfunc "SetMorganMask";
+ mes "\"Great, lets begin your first lesson.\"";
+ getitem 1171, 1;
+ mes "\"This is a wand, there are many like it but this one is now yours.\"";
+ mes "\"Various wands and staffs are found throughout the land with many different strengths and weaknesses.\"";
+ mes "\"To use the wand you need to have it equipped and speak the incantation to let it tap into your mana.\"";
+ mes "\"As the power of your magic grows so will the spells you can cast.\"";
+ mes "\"Lets start with a basic wand attack. " + getspellinvocation("wand") + "\"";
+ mes "\"Equip the wand and lets try out that spell.\"";
+ mes "\"To cast a spell open the chat window, type the invocation and press enter.\"";
+ mes "\"Speak to me again once you've cast the spell.\"";
+ goto L_Close;
+
+L_Started:
+ mes "[Morgan]";
+ mes "\"Lets start with a basic wand attack. " + getspellinvocation("wand") + "\"";
+ mes "\"Equip the wand and lets try out that spell.\"";
+ mes "\"To cast a spell open the chat window, type the invocation and press enter.\"";
+ mes "\"Speak to me again once you've cast the spell.\"";
+ goto L_Close;
+
+L_CastOnce:
+ mes "[Morgan]";
+ mes "\"Ok, good job! Looks like you have good mana flow.\"";
+ mes "\"Onto the next lesson. Now that you have " + getspellinvocation("wand") + " cast,\"";
+ mes "\"Each time you attack the wand will convert a bit of you mana into a magic bolt.\"";
+ mes "\"After so many attacks, you will need to recast the invocation to stay attuned to the wand.\"";
+ mes "\"(Logging out will also cancel any spell effects currently active in-game.).\"";
+ set @morgan_tmp, 4;
+ callfunc "SetMorganMask";
+ goto L_Close;
+
+L_LearningDone:
+ mes "[Morgan]";
+ mes "\"" + getspellinvocation("wand") + " is a basic wand attack.\"";
+ mes "\"A Wand must be equipped to use the spell.\"";
+ mes "\"To cast a spell open the chat window, type the invocation and press enter.\"";
+ mes "\"I've taught you all I can for now. You should visit the Mana Seed north west of Hurnscald.\"";
+ goto L_Close;
+
+L_Close:
+ close;
+}
diff --git a/world/map/npc/029-2/sorfina.txt b/world/map/npc/029-2/sorfina.txt
new file mode 100644
index 00000000..671835f1
--- /dev/null
+++ b/world/map/npc/029-2/sorfina.txt
@@ -0,0 +1,388 @@
+// This file is part of the Tutorial
+// Author: Jenalya
+029-2.gat,27,27,0|script|Sorfina|154,0,1
+{
+ setarray @npc_loc, 27, 27, 2;
+ callfunc "PCtoNPCRange";
+ if (@npc_check)
+ goto L_Close;
+ goto L_Main;
+
+L_Main:
+ callfunc "TutorialState";
+ if (@tutorial == 10) goto L_Hasan;
+ if (@tutorial >= 4) goto L_Again;
+ if (@tutorial == 3) goto L_Clothes;
+ if (@tutorial == 2) goto L_Dresser;
+ if (@tutorial == 1) goto L_Carpet;
+ goto L_Start;
+
+L_Start:
+ mes "You open your eyes.";
+ mes "";
+ mes "[Old Woman]";
+ mes "\"Ah, you woke up. You washed ashore on the beach 3 days ago. You've been asleep since.";
+ mes "You must have been thrown off one of the ships sailing during that last tremor.\"";
+ mes "\"My little granddaughter Tanisha found you. Kaan was able to carry you to bed.";
+ mes "We've been taking care of you ever since. Waiting for you to wake up.\"";
+ mes "\"You didn't have any possessions on you when we found you and no one knows who you are.\"";
+ mes "Do you have a name?";
+ menu
+ strcharinfo(0), L_Name;
+
+L_Name:
+ mes "[Old Woman]";
+ mes "\"Well " + strcharinfo(0) + " what else can you tell me about yourself?.\"";
+ menu
+ "Umm... I... I don't remember anything...", L_KnowNothing;
+
+L_KnowNothing:
+ mes "[Old Woman]";
+ mes "\"Well I can tell you some useful things, if you want to hear.";
+ mes "Some of it might jog your memory or at least help you catch your bearings.";
+ mes "Oh, and by the way my name is Sorfina.\"";
+ menu
+ "That would be great!",L_Tut,
+ "No, thanks. I already know how things are going.",L_SkipTut;
+
+L_Tut:
+ mes "She smiles at you.";
+ mes "[Sorfina]";
+ mes "\"You have arrived at a very strange time. The Council is visiting Candor today.\"";
+ mes "\"All the recent rumbling from the cave has all of Candor worried.\"";
+ mes "\"Our guess is something with the last big shaker was the reason you ended up here.\"";
+ mes "\"Ok, lets start by getting you dressed.\"";
+ goto L_Carpet;
+
+L_Carpet:
+ mes "[Sorfina]";
+ mes "\"Try to take a few steps and walk to that carpet over there.";
+ mes "Just use the ###keyMoveUp; to move up, press ###keyMoveDown; to move down, ";
+ mes "press ###keyMoveLeft; to move left, press ###keyMoveRight; to move right ";
+ mes " or click on the place you want to go to.\"";
+ set @tutorial_tmp, 1;
+ callfunc "SetTutorialMask";
+ goto L_Close;
+
+L_Dresser:
+ mes "[Sorfina]";
+ mes "\"In that dresser there are some clothes you can wear.\"";
+ mes "\"To interact with things in your environment or talk to NPCs you can either click on it or press ###keyTargetNPC; to focus and ###keyTalk; to talk/activate.\"";
+ mes "\"Now get the clothes out of the dresser.\"";
+ goto L_Close;
+
+L_Naked:
+ mes "[Sorfina]";
+ mes "\"Press ###keyWindowInventory; or click on the Inventory button in the bar at the upper right corner to open your bag.\"";
+ mes "\"Once we stop talking, double-click on the clothes to equip.\"";
+ mes "\"Talk to me again after you get dressed. You can either click on me, or press ###keyTargetNPC; to focus on me and ###keyTalk; to talk.\"";
+ goto L_Close;
+
+L_Clothes:
+ if (getequipid(equip_torso) < 0)
+ goto L_Naked;
+ mes "[Sorfina]";
+ mes "\"That's much better, don't you think?\"";
+ mes "\"Here take this.\"";
+ getitem "HitchhikersTowel", 1;
+ mes "\"Your HitchHikers Towel will return you to your last set soul menhir or here if not set.\"";
+ mes "\"It can't be used constantly as the magic needs time to power the jump.\"";
+ mes "\"I think this will help you a bit. To get more information, press the button Setup and look at the controls on the Keyboard tab. You can also change them as you like.";
+ mes "Talk to me again if you want me to explain more things.\"";
+
+ mes "\"Oh, and if you're looking for extra work, you should talk to Aidan and Valon when you go outside. They're giving rewards for monster hunting.";
+ mes "You can find Aidan near the camp fire outside and Valon out by the fields in the east.\"";
+ next;
+
+ mes "She digs in her pocket for a moment.";
+ mes "\"And here is some money for you. Don't spend it all in one place.";
+ mes "Now go help Tanisha downstairs.\"";
+ set Zeny, Zeny + 30;
+ set @tutorial_tmp, 4;
+ callfunc "SetTutorialMask";
+ goto L_Close;
+
+L_Again:
+ mes "[Sorfina]";
+ mes "\"Make yourself at home! Do you have any questions?\"";
+ menu
+ "Yes, could you explain about...",L_Explain,
+ "Could I get Healed?",L_Heal,
+ "No, thanks.",L_Close;
+
+L_Heal:
+ if (BaseLevel > 20)
+ goto L_NoHeal;
+ mes "[Sorfina]";
+ mes "\"Hello Dear! You look tired, you should rest a moment.\"";
+ mes "You take a short nap and feel refreshed.";
+ heal MaxHp, 0;
+ goto L_Main;
+
+L_NoHeal:
+ mes "[Sorfina]";
+ mes "\"I'm sorry but your wounds are far to advanced for my skills.\"";
+ goto L_Main;
+
+L_Explain:
+ menu
+ "... walking?",L_Walk,
+ "... talking?",L_Talk,
+ "... the inventory and items?",L_Items,
+ "... shortcuts?",L_Shortcut,
+ "... what to do in Candor?",L_Aidan,
+ "... nevermind.",L_Close;
+
+L_Walk:
+ mes "[Sorfina]";
+ mes "\"You can use the arrow keys to walk around.";
+ mes "Just use the ###keyMoveUp; to move up, press ###keyMoveDown; to move down, ";
+ mes "press ###keyMoveLeft; to move left, press ###keyMoveRight; to move right ";
+ mes " or click on the place you want to go to.\"";
+ mes "This only works if that place is reachable and walkable.\"";
+ goto L_Close;
+
+L_Talk:
+ mes "[Sorfina]";
+ mes "\"If you want to talk to a normal person, you can click at him or her.";
+ mes "Or you can press ###keyTargetNPC; to focus on the nearest person and then press ###keyTalk; to talk.\"";
+ next;
+ mes "\"If you want to talk to other adventurers, press ###keyChat; to open your chat window.";
+ mes "Then type your message and press Enter to send.\"";
+ next;
+ mes "\"You may want to talk privately to another adventurer sometimes. In that case you can whisper.";
+ mes "After pressing ###keyChat; type '/whisper [name] [message]'.";
+ mes "Or you can right click on someone and choose the whisper option.\"";
+ next;
+ mes "\"Press ###keyWindowChat; to show and hide your chat window.\"";
+ goto L_Close;
+
+L_Items:
+ mes "[Sorfina]";
+ mes "\"There are three types of items.";
+ mes "They can be Consumables, Equipment or Miscellaneous.\"";
+ next;
+ mes "\"Consumable items such as Potions, can be used only once.";
+ mes "After use, they will disappear from your inventory.";
+ mes "There are some rare items that can be used but don't get consumed.";
+ next;
+ mes "\"Equipment items like Armors, Weapons, Accessories can be equipped for fashionable purposes or to raise your status.\"";
+ next;
+ mes "\"Miscellaneous items such as maggot slime, can be used in creating other items, or just to trade and sell.\"";
+ next;
+ mes "\"Your HitchHikers Towel will return you to your last set soul menhir or here if not set.\"";
+ mes "\"It can't be used constantly as the magic needs time to power the jump.\"";
+ next;
+ mes "\"Press ###keyWindowInventory; to open your inventory.";
+ mes "When placing your cursor over an item there, you can see a box with some information about that item.\"";
+ next;
+ mes "\"To use or equip an item, select it by double-clicking on it.";
+ mes "Selecting the item then pressing Use or Equip also works.\"";
+ goto L_Close;
+
+L_Shortcut:
+ mes "[Sorfina]";
+ mes "\"Press ###keyWindowShortcut; or click the Shortcut button in the bar at the upper right to open your shortcut window.\"";
+ next;
+ mes "\"You can select the item you want to put on a shortcut with your mouse and then click on the position in the shortcut window you want to place it.\"";
+ next;
+ mes "\"Now you can use or equip/unequip it by pressing the number of the shortcut.\"";
+ goto L_Close;
+
+L_Aidan:
+ mes "[Sorfina]";
+ mes "\"I heard Aidan and Valon are looking for brave adventurers, you might want to talk to them. ";
+ mes "You can find Aidan near the camp fire outside. The fields are just south of the town exit. ";
+ mes "You'll see Valon of the city gaurd standing there. They both are offering rewards for monster hunting.\"";
+ next;
+ mes "\"When you leave this area to the South, you'll come to the docks.";
+ mes "They will take you to Hurnscald, a major trading port.\"";
+ next;
+ mes "\"Go east out of Candor and north. You will find the cave everyone is talking about to the north.";
+ next;
+ mes "Talk to everybody. You can never tell when they might know something useful.\"";
+ goto L_Close;
+
+L_Hasan:
+ mes "[Sorfina]";
+ mes "\"Make yourself at home! Do you have any questions?\"";
+ menu
+ "A guy named Hasan is bullying people.",L_Next,
+ "Yes, could you explain again about...",L_Explain,
+ "No, thanks.",L_Close;
+
+L_Next:
+ mes "\"Ah, Hasan. He's causing trouble again?\"";
+ mes "She shakes her head.";
+ mes "[Sorfina]";
+ mes "\This guy has been a plague ever since he could walk. He's always causing trouble.\"";
+ mes "\"And his father... Well, one day his father thought he should teach Hasan a lesson.\"";
+ mes "\"He took him into the desert and then left him there!";
+ mes "Hasan was only seven years old!\"";
+ mes "\"I never understood how someone could do something like that to a child, even if it's a rascal like Hasan.\"";
+ mes "\"Anyway, Hasan tried to find his way back home, but stumbled into a nest of scorpions!\"";
+ mes "She shakes her head.";
+ mes "\"If Valon hadn't have come along that moment, Hasan would have died that day.\"";
+ mes "\"However, the scorpions poison caused a bad fever and once Hasan had recovered from that, he was even more malicious than before.\"";
+ mes "She sighs.";
+ set @tutorial_tmp, 11;
+ callfunc "SetTutorialMask";
+ goto L_Close;
+
+L_SkipTut:
+ mes "[Sorfina]";
+ mes "\"Really? You seem quite unexperienced. Listening to some advice won't hurt.\"";
+ menu
+ "Thinking about it twice... please tell me.",L_Tut,
+ "Yeah, but thanks for the offer. Bye.",L_Bye;
+
+L_Bye:
+ mes "[Sorfina]";
+ mes "\"Alright, if you say so. But take at least this. See you later.\"";
+ getitem "Knife", 1;
+ getitem "SlingShot", 1;
+ getitem "SlingBullet", 500;
+ getitem "HitchhikersTowel", 1;
+ getitem "CottonShirt", 1;
+ getitem "RaggedShorts", 1;
+ set Zeny, Zeny + 50;
+ set @tutorial_tmp, 8;
+ callfunc "SetTutorialMask";
+ goto L_Close;
+
+L_Close:
+ close;
+
+OnTouch:
+ callfunc "TutorialState";
+ if (@tutorial > 0)
+ end;
+ goto L_Start;
+}
+
+029-2.gat,33,27,0|script|#Carpet|32767,1,1
+{
+ end;
+
+OnTouch:
+ callfunc "TutorialState";
+ if (@tutorial != 1)
+ end;
+ mes "[Sorfina]";
+ mes "\"You should get dressed now.\"";
+ mes "\"In that dresser there are some clothes you can wear.\"";
+ mes "\"To interact with things in your environment or talk to NPCs you can either click on it or press N to focus and T to talk/activate.\"";
+ next;
+ mes "\"Now get the clothes out of the dresser.\"";
+ set @tutorial_tmp, 2;
+ callfunc "SetTutorialMask";
+ close;
+}
+
+029-2.gat,29,23,0|script|Dresser#tutorial|400
+{
+ setarray @npc_loc, 29, 23, 2;
+ callfunc "PCtoNPCRange";
+ if (@npc_check)
+ goto L_CloseDis;
+ callfunc "TutorialState";
+ if (@tutorial > 2) goto L_Empty;
+ if (@tutorial == 2) goto L_Shirt;
+ goto L_Walk;
+
+L_Walk:
+ mes "[Sorfina]";
+ mes "\"Thats not what I said to do. Please don't skip ahead.\"";
+ close;
+
+L_Shirt:
+ mes "You take a simple Cotton Shirt and some very worn-out Ragged Shorts out of the dresser.";
+ getitem "CottonShirt", 1;
+ getitem "RaggedShorts", 1;
+ mes "[Sorfina]";
+ mes "\"Great! Now you can equip it.\"";
+ mes "\"You can open your inventory by pressing F3 or clicking on the 'Inventory' button in the bar at the upper right corner.\"";
+ next;
+ mes "\"After we finish talking, click on the clothes and press the equip button.\"";
+ set @tutorial_tmp, 3;
+ callfunc "SetTutorialMask";
+ close;
+
+L_Empty:
+ mes "The dresser is empty.";
+ close;
+
+L_CloseDis:
+ mes "You cannot reach that far.";
+ close;
+}
+
+029-2.gat,44,31,0|script|#DoorOutTut1|45,0,0
+{
+ end;
+
+OnTouch:
+ callfunc "TutorialState";
+ if (@tutorial < 4)
+ goto L_Block;
+ warp "029-2.gat", 112, 85;
+ end;
+
+L_Block:
+ message strcharinfo(0), "Sorfina: Wait a moment! You're not ready to leave.";
+ end;
+}
+029-2.gat,23,24,0|script|#GameRules1|32767,0,1
+{
+ end;
+
+OnTouch:
+ if (TUT_var > 0)
+ end;
+ mes "[Server/Client Notice]";
+ mes "The explanations in this tutorial are based on the official client, Manaplus.";
+ mes "If you're using another client, settings and controls may be different.";
+ callfunc "GameRules";
+ close;
+}
+029-2.gat,21,24,0|script|#GameRules2|32767,0,1
+{
+ end;
+
+OnTouch:
+ if (TUT_var > 0)
+ end;
+ callfunc "GameRules";
+ mes "[Server/Client Notice]";
+ mes "The explanations in this tutorial are based on the official client, Manaplus.";
+ mes "If you're using another client, settings and controls may be different.";
+ close;
+}
+029-2.gat,22,26,0|script|#GameRules3|32767,1,0
+{
+ if (TUT_var == 0)
+ goto L_KnockBack;
+ goto L_Close;
+
+L_KnockBack:
+ message strcharinfo(0), "Please Accept the Game rules";
+ warp "029-2.gat", 22, 24;
+ goto L_Close;
+
+L_Close:
+ close;
+}
+029-2.gat,24,24,0|script|#GameRules4|32767,0,1
+{
+ if (TUT_var == 0)
+ goto L_KnockBack;
+ goto L_Close;
+
+L_KnockBack:
+ message strcharinfo(0), "Please Accept the Game rules";
+ warp "029-2.gat", 22, 24;
+ goto L_Close;
+
+L_Close:
+ close;
+}
diff --git a/world/map/npc/029-2/stat_reset.txt b/world/map/npc/029-2/stat_reset.txt
new file mode 100644
index 00000000..f3af6df6
--- /dev/null
+++ b/world/map/npc/029-2/stat_reset.txt
@@ -0,0 +1,44 @@
+//
+
+029-2.gat,98,92,0|script|Jessie|159
+{
+ setarray @npc_loc, 98, 91, 4;
+ callfunc "PCtoNPCRange";
+ if (@npc_check)
+ goto L_Close;
+ if (BaseLevel >= 10)
+ goto L_Sorry;
+
+ mes "[Jessie]";
+ mes "\"I know a spell that will";
+ mes "reset status points on the youngings.";
+ next;
+ menu
+ "Reset my stats",L_Reset,
+ "Forget about it",L_Pass;
+
+L_Reset:
+ resetstatus;
+
+ mes "[Jessie]";
+ mes "\"There you are.";
+ mes "";
+ mes "Good as new!\"";
+ goto L_Close;
+
+L_Pass:
+ mes "[Jessie]";
+ mes "\"Very well then, see you.\"";
+ goto L_Close;
+
+L_Sorry:
+ mes "[Jessie]";
+ mes "\"My spell only works on the very young, sorry.\"";
+ next;
+ mes "\"You can try Mailvox in the Tulimshar Bazaar or Wyara in the Potion Shop in Hurnscald.\"";
+ next;
+ goto L_Close;
+
+L_Close:
+ close;
+}
diff --git a/world/map/npc/029-2/tanisha.txt b/world/map/npc/029-2/tanisha.txt
new file mode 100644
index 00000000..b45b5d06
--- /dev/null
+++ b/world/map/npc/029-2/tanisha.txt
@@ -0,0 +1,299 @@
+// This file is part of the Tutorial
+// Authors: Jenalya, alastrim
+// Cleanup: o11c
+
+029-2.gat,110,88,0|script|Tanisha|114
+{
+ setarray @npc_loc, 110, 88, 4;
+ callfunc "PCtoNPCRange";
+ if (@npc_check)
+ goto L_Close;
+
+ if (isin("029-2.gat", 98, 84, 106, 89))
+ goto L_Fighting;
+
+ callfunc "TutorialState";
+ if (@tutorial >= 8) goto L_Tut_Done;
+ if (@tutorial == 7) goto L_Stats;
+ if (@tutorial == 6) goto L_Fail;
+ if (@tutorial == 5) goto L_Maggots;
+
+ mes "[Tanisha]";
+ mes "\"Hey! You're up again!\"";
+ emotion EMOTE_HAPPY;
+ mes "\"Are you feeling better?\"";
+ menu
+ "Yes, thank you.",L_Next,
+ "Yeah, but everything is gone. My stuff and memories..",L_Next;
+
+L_Next:
+ mes "[Tanisha]";
+ mes "\"I'm glad you're feeling better. It was really bad luck what happened to you.";
+ mes "Hey, I have an idea.\"";
+ set @tutorial_tmp, 5;
+ callfunc "SetTutorialMask";
+ goto L_Maggots;
+
+L_Maggots:
+ mes "[Tanisha]";
+ mes "\"There are some maggots eating the goods and I'm supposed to get rid of them.";
+ mes "But they're so yucky!\"";
+ mes "\"If you kill them, I'll give you my knife.";
+ mes "What do you say?\"";
+ menu
+ "I guess it's the least I can do.",L_Next1;
+
+L_Next1:
+ mes "[Tanisha]";
+ mes "\"Wonderful.";
+ // since the check happens here, it is actually possible to have
+ // more than $@Maggot_MaxHunters in the area at one time
+ // but that's not a BIG problem
+ if (getareausers("029-2.gat", 98, 84, 106, 89) >= $@Maggot_MaxHunters)
+ goto L_Crowded;
+ next;
+ goto L_Fight_Again;
+
+L_Fight_Again:
+ mes "[Tanisha]";
+ mes "\"Ok, listen what to do.";
+ mes "Equip a weapon and kill the maggots.\"";
+ mes "\"Press ###keyTargetMonster; to focus on a monster. With ###keyTargetAttack; you can focus and start attacking the same time.";
+ mes "But it also works to click on the monster with your mouse.\"";
+ next;
+ mes "\"If you press the ###keyTarget;, you can abort your attack.\"";
+ next;
+ mes "\"Maggots aren't aggressive, so they won't harm you until you attack them first. Take them out one by one.\"";
+ next;
+ mes "\"Sometimes dead monsters leave some useful things. You can pick them up by pressing ###keyPickup; or clicking on the items with your mouse.\"";
+ close2;
+ // The getitem must be in the same place as set @tutorial, 2;
+ // since it was moved to after L_Fight_Again, add it conditionally
+ callfunc "TutorialState";
+ if (@tutorial == 5)
+ goto L_GetFightItems;
+ goto L_ContinueFight;
+
+L_GetFightItems:
+ set @tutorial_tmp, 6;
+ callfunc "SetTutorialMask";
+ getitem "Knife", 1;
+ getitem "SlingShot", 1;
+ getitem "SlingBullet", 500;
+ goto L_ContinueFight;
+
+L_ContinueFight:
+ set @tutorial_tmp, 6;
+ callfunc "SetTutorialMask";
+ set @Maggot_Kills, 0;
+ set @time, 0;
+ if (getareausers("029-2.gat", 98, 84, 106, 89) == 0)
+ initnpctimer;
+ warp "029-2.gat", 101, 87;
+ goto L_Summon;
+
+L_Summon:
+ areamonster "029-2.gat", 98, 84, 106, 89, "", 1002, 1, "Tanisha::OnMaggotDeath";
+ end;
+
+L_Stats:
+ mes "[Tanisha]";
+ mes "\"That was great! Like a professional exterminator!\"";
+ mes "\"And it seems you became stronger and more experienced.";
+ mes "That means you got some status points which you can use to increase your abilities.\"";
+ mes "\"Press ###keyWindowStatus; or click the Status button in the bar at the upper right to see your status window. There you can distribute your points on six different properties.\"";
+ next;
+ goto L_StatsRe;
+
+L_StatsRe:
+ mes "\"Strength makes you hit harder and you can carry more weight.\"";
+ mes "\"Agility increases your attack speed and your ability to dodge attacks.\"";
+ mes "\"Vitality gives you more hit points and more defense against physical attacks.\"";
+ mes "\"Intelligence is useful for magic attack and defense.";
+ mes "But as long as you don't know any magic, you shouldn't use your points on this.\"";
+ mes "\"Dexterity is needed to hit monsters. It's also very important for the damage if you use a ranged weapon.\"";
+ mes "\"Luck gives you the chance to do critical hits and lowers the chance to receive a critical hit from your opponent.\"";
+ next;
+ mes "\"Think about how you want to play before assigning the points.\"";
+ mes "\"My Uncle sitting at the counter knows a spell to help the younglings reset their stats.\"";
+ mes "\"He also knows of mages with even more powerful reset spells.\"";
+ next;
+ callfunc "TutorialState";
+ if (@tutorial == 7)
+ goto L_Money;
+ goto L_Advice;
+
+L_Money:
+ next;
+ mes "[Tanisha]";
+ mes "\"Hey, you are so smart taking out all that yucky maggots for me.";
+ mes "You can have my pocket money. Here.\"";
+ set @tutorial_tmp, 8;
+ callfunc "SetTutorialMask";
+ set Zeny, Zeny + 5;
+ next;
+ goto L_Advice;
+
+L_Advice:
+ mes "\"When you go to Hurnscald, you should see Bernard. He can make a delicious soup!";
+ mes "Good luck!\"";
+ emotion EMOTE_HAPPY;
+ goto L_Close;
+
+L_Explain:
+ menu
+ "... how to fight?",L_Fight,
+ "... monsters?",L_Mob,
+ "... status points?",L_StatsRe,
+ "... what to do in Hurnscald?",L_Advice,
+ "... nevermind.",L_Close;
+
+L_Fight:
+ mes "[Tanisha]";
+ mes "\"Press ###keyTargetMonster; to focus on a monster. With ###keyTargetAttack; you can focus and attack.";
+ mes "But it also works to click on the monster with your mouse.\"";
+ next;
+ mes "\"If you press the ###keyTarget; button, you can abort your attack.\"";
+ next;
+ mes "\"Sometimes dead monsters leave some useful things. You can pick them up with pressing ###keyPickup; or clicking on the items with your mouse.\"";
+ next;
+ mes "\"If you feel exhausted from battle you can sit down by pressing ###keyBeingSit; to recover faster.\"";
+ goto L_Close;
+
+L_Mob:
+ mes "[Tanisha]";
+ mes "\"I don't know much about monsters, I'm just a little girl. But I know a few things.";
+ mes "There are several types of monsters...Aggressive, Neutral, and Assistants.\"";
+ next;
+ mes "\"Aggressive monsters will attack you as soon as they see you.\"";
+ next;
+ mes "\"Neutral monsters are peaceful until they get attacked.\"";
+ next;
+ mes "\"Assistants are monsters who help each other.\"";
+ goto L_Close;
+
+L_Tut_Done:
+ mes "[Tanisha]";
+ mes "\"These yucky maggots! They're eating our goods!";
+ mes "No matter how many of them you kill, they always come back.\"";
+ mes "She sighs.";
+ mes "[Tanisha]";
+ mes "\"Do you have any questions?\"";
+ menu
+ "Yes, could you explain about...", L_Explain,
+ "No, thanks.", L_Close;
+
+L_Crowded:
+ mes "[Tanisha]";
+ mes "\"That's great! But...";
+ mes "it seems a little crowded in there.\"";
+ mes "\"Let's wait a short while.\"";
+ goto L_Close;
+
+L_Sleep:
+ warp "029-2.gat", 101, 87;
+ mes "[Tanisha]";
+ mes "\"What are you doing in there?";
+ mes "Sleeping?";
+ mes "Come back when you're serious.\"";
+ set @Maggot_Kills, 0;
+ set @time, 0;
+ close2;
+ if (getareausers("029-2.gat", 98, 84, 106, 89) == 0)
+ goto L_CleanUp;
+ end;
+
+L_Fail:
+ mes "Tanisha seems to be trying hard to supress laughter.";
+ mes "[Tanisha]";
+ mes "\"The maggots defeated you.\"";
+ mes "She bursts out with laughter.";
+ mes "\"Oops, I'm sorry. It's just too funny.";
+ mes "Do you want to try it again?\"";
+ menu
+ "Sure!", L_Next2,
+ "No, I need a rest.", L_Close;
+
+L_Next2:
+ if (getareausers("029-2.gat", 98, 84, 106, 89) >= $@Maggot_MaxHunters)
+ goto L_Crowded;
+ goto L_Fight_Again;
+
+L_Fighting:
+ message strcharinfo(0), "Tanisha: I believe in you!";
+ end;
+
+OnTimer1000:
+ setnpctimer 0;
+ if (getareausers("029-2.gat", 98, 84, 106, 89) == 0)
+ goto L_CleanUp;
+ // This is needed because multiple players can be in the area at once
+ areatimer "029-2.gat", 98, 84, 106, 89, 0, "Tanisha::OnTick";
+ end;
+
+L_CleanUp:
+ killmonster "029-2.gat", "Tanisha::OnMaggotDeath";
+ set $@Maggot_Hunters, 0;
+ stopnpctimer;
+ areamonster "029-2.gat", 98, 84, 106, 89, "", 1002, 1, "Tanisha::OnMaggotDeath";
+ end;
+
+OnTick:
+ set @time, @time + 1;
+ if (@time > 300)
+ goto L_Sleep;
+ if (isdead())
+ end;
+ if (Hp > 20)
+ end;
+ heal MaxHp, 0;
+ message strcharinfo(0), "Tanisha: You're doing good!";
+ end;
+
+OnMaggotDeath:
+ if (@Maggot_Kills == 1)
+ message strcharinfo(0), "Tanisha: Aaahhhh... another one! It will crawl up your legs!";
+ if (@Maggot_Kills == 2)
+ message strcharinfo(0), "Tanisha: Ohh... Irrhk... Eeeeww... They just appear from nowhere!";
+ if (@Maggot_Kills == 3)
+ message strcharinfo(0), "Tanisha: Yuck... I think I am getting sick.";
+ if (isin("029-2.gat", 98, 84, 106, 89))
+ set @Maggot_Kills, @Maggot_Kills + 1;
+ if (@Maggot_Kills < 5)
+ goto L_Summon;
+ // else, complete
+ warp "029-2.gat", 110, 88;
+ set @tutorial_tmp, 7;
+ callfunc "SetTutorialMask";
+ set @Maggot_Kills, 0;
+ set @time, 0;
+ if (getareausers("029-2.gat", 98, 84, 106, 89) == 0)
+ goto L_CleanUp;
+ end;
+
+L_Close:
+ close;
+
+OnInit:
+ set $@Maggot_MaxHunters, 4;
+ areamonster "029-2.gat", 98, 84, 106, 89, "", 1002, 1, "Tanisha::OnMaggotDeath";
+ end;
+}
+029-2.gat,114,93,0|script|#DoorOutTut2|45,0,0
+{
+ end;
+
+OnTouch:
+ callfunc "TutorialState";
+ if (@tutorial >= 8)
+ goto L_Warp;
+ goto L_Block;
+
+L_Warp:
+ warp "029-1.gat", 32, 100;
+ end;
+
+L_Block:
+ message strcharinfo(0), "Tanisha: Please come here. I'd like some help!";
+ end;
+}
diff --git a/world/map/npc/029-2/two_arms.txt b/world/map/npc/029-2/two_arms.txt
new file mode 100644
index 00000000..33b4b843
--- /dev/null
+++ b/world/map/npc/029-2/two_arms.txt
@@ -0,0 +1,4 @@
+// Forge Shops
+
+029-2.gat,99,25,0|shop|Rosen|311,SlingShot:*500,SlingBullet:*1,ShortBow:*8000,Arrow:*1,IronArrow:*4
+029-2.gat,112,24,0|shop|Toichi|377,Knife:*50,SharpKnife:*100,Dagger:*1000,LeatherShirt:*2000,LeatherShield:*2000