diff options
Diffstat (limited to 'npc')
208 files changed, 3756 insertions, 1418 deletions
diff --git a/npc/000-0/sailors.txt b/npc/000-0/sailors.txt index f412c19c..76870170 100644 --- a/npc/000-0/sailors.txt +++ b/npc/000-0/sailors.txt @@ -35,7 +35,7 @@ OnTouch: setcamnpc "Sailors", 0, -32; mesn "Human Voice"; - mesq lg("Why Frenchy? It's a Russian!"); + mesq lg("I think he's from the East..."); next; setcamnpc "Sailors", 144, -80; @@ -45,7 +45,7 @@ OnTouch: setcamnpc; mesn "Raijin Voice"; - mesq lg("You stupid, she's English, look at the shape of her head.", "You stupid, he's English, look at the shape of his head."); + mesq lg("You think she's from the East? As in... Ancea?", "You think he's from the East? As in... Ancea?"); next; mesq l("Hey you! Can you hear us? Are you okay?"); next; diff --git a/npc/000-1/gugli.txt b/npc/000-1/gugli.txt index dd2e6739..77738a8a 100644 --- a/npc/000-1/gugli.txt +++ b/npc/000-1/gugli.txt @@ -150,7 +150,7 @@ L_Couwan: if (countitem(FishBox) > 0) delitem FishBox, 1; setq ShipQuests_Couwan, 2; - Zeny = Zeny + 10; + Zeny += 10; getexp 40, 0; message strcharinfo(0), l("You receive @@ E!", 10); @@ -202,7 +202,7 @@ L_TaskDone: if (countitem(PlushroomBox) == 1) delitem PlushroomBox, 1; setq ShipQuests_Gugli, 2; - Zeny = Zeny + 250; + Zeny += 250; getexp 50, 0; mes ""; diff --git a/npc/000-2-0/julia.txt b/npc/000-2-0/julia.txt index 1fde8713..24635648 100644 --- a/npc/000-2-0/julia.txt +++ b/npc/000-2-0/julia.txt @@ -289,7 +289,7 @@ OnTouch: next; mesq lg("I'm glad to see you're okay."); next; - mesq lg("Could I ask you what your native language is? A sailor told me you're Russian, but another one told me you're French... I'm a bit lost. I will register you on the ship passenger list just after that."); + mesq lg("Could I ask you what your native language is? A sailor told me you're from Ancea, but another one told me you're from Aemil because of the logo that... never mind. I'm a bit lost, if you could tell me what language you speak I will register you on the ship passenger list just after that."); next; chooseLang; mainMenu; diff --git a/npc/000-2-1/arpan.txt b/npc/000-2-1/arpan.txt index 9b2b9665..8c06ce48 100644 --- a/npc/000-2-1/arpan.txt +++ b/npc/000-2-1/arpan.txt @@ -7,6 +7,7 @@ // Variable: // 0 ShipQuests_Arpan // 1 ShipQuests_Julia +// 2 ShipQuests_ArpanMoney // Values: // 00 Has not talked to Arpan yet. // 01 Talked to Arpan and needs to get the clothes. @@ -15,6 +16,10 @@ // 10 Has not talked to Julia // 11 Need to see Julia // 12 Has been registered by Julia +// 20 Does not knows about money +// 21 Has not taken possession from Arpan +// 22 Took money from Arpan +// 23 Took money and clothes (Legacy only) 000-2-1,49,36,0 script LeftDoorCheck NPC_HIDDEN,0,0,{ .@q = getq(ShipQuests_Arpan); @@ -84,6 +89,7 @@ L_EquipDone: close; } +///////////////////////////////////////////////////////////////////////////// 000-2-1,49,33,0 script Magic Arpan NPC_MAGIC_ARPAN,{ .@q = getq(ShipQuests_Arpan); .@q_nard = getq(ShipQuests_Nard); @@ -152,6 +158,7 @@ L_Menu: l("Who are you?"), L_Who, rif(getq(ShipQuests_ArpanMoney) == 1, lg("Do you know what happened to the gold I had when you guys saved me?")), L_WhereMoney, rif(getq(ShipQuests_ArpanMoney) < 2, l("Where are my old clothes?")), L_WhereOldClothes, + rif(getq(ShipQuests_ArpanMoney) == 2 && LEGACY, l("About my my old clothes...")), L_LegacyClothes, rif(!.@equipped, lg("What should I do after taking these clothes?")), L_WhatCloth, rif(!.@equipped, l("Thank you, I'll take them and put them on.")), -, l("Nothing, sorry."), -; @@ -201,9 +208,28 @@ L_WhereOldClothes: setq ShipQuests_ArpanMoney, 2; .@q = getq(ShipQuests_Arpan); - Zeny = Zeny + 10; + Zeny += 10; message strcharinfo(0), l("You receive @@ E!", 10); + if (LEGACY) + goto L_LegacyClothes; + + goto L_BeforeMenu; + +L_LegacyClothes: + if (LEGACY) { + mesn strcharinfo(0); + select + lg("But... I remember that my clothes were very dear to me..."), + l("Oh okay."); + mes ""; + if (@menu == 1) { + mesn; + mesq l("Well, you can have them back, but they're yayaya, mostly destroyed. Not sure what yeye are going to do with that."); + getitem ClothesPack, 1; + setq ShipQuests_ArpanMoney, 3; + } + } goto L_BeforeMenu; L_WhereMoney: @@ -214,7 +240,7 @@ L_WhereMoney: setq ShipQuests_ArpanMoney, 2; .@q = getq(ShipQuests_Arpan); - Zeny = Zeny + 10; + Zeny += 10; message strcharinfo(0), l("You receive @@ E!", 10); goto L_BeforeMenu; diff --git a/npc/000-2-1/chefgado.txt b/npc/000-2-1/chefgado.txt index 69570fcf..0039e094 100644 --- a/npc/000-2-1/chefgado.txt +++ b/npc/000-2-1/chefgado.txt @@ -161,7 +161,7 @@ L_PoisonJulia: mesq l("The usurper has been punished! This is a great day! Take this reward as a prize for your loyalty to the old commander!"); setq ShipQuests_ChefGado, 4; - Zeny = Zeny + 200; + Zeny += 200; message strcharinfo(0), l("You receive @@ E!", 200); inventoryplace Bread, 1; getitem Bread, 1; diff --git a/npc/000-2-1/dan.txt b/npc/000-2-1/dan.txt index a60c88f1..31591734 100644 --- a/npc/000-2-1/dan.txt +++ b/npc/000-2-1/dan.txt @@ -63,7 +63,7 @@ L_QuestStory: L_She: mes ""; mesn; - mesq l("She is a good friend of mine... We wanted to marry a few weeks before her accident but..."); + mesq l("She is a good friend of mine... We wanted to move together a few weeks before her accident but..."); next; goto L_Quit2; diff --git a/npc/000-2-1/peter.txt b/npc/000-2-1/peter.txt index eaade56e..06825f0c 100644 --- a/npc/000-2-1/peter.txt +++ b/npc/000-2-1/peter.txt @@ -256,6 +256,7 @@ OnTimeout: // It's not _buggy_, it is just reckless. I would like a setting to restrict it // to destroy only instances owned by the char, or to destroy by name :p OnDone: + warp "000-2-1", 72, 36; .@q3 = getq3(ShipQuests_Peter); //instance_destroy(.@q3); if (@peter) @@ -285,7 +286,7 @@ OnDone: default: @peter=750; break; } - Zeny = Zeny + @peter; + Zeny += @peter; message strcharinfo(0), l("You receive @@ E!", @peter); // Some cleanup. Shouldn't cause bugs but it's absence causes a ugly behavior. diff --git a/npc/000-2-2/ratto.txt b/npc/000-2-2/ratto.txt index 14f98201..d30ccd17 100644 --- a/npc/000-2-2/ratto.txt +++ b/npc/000-2-2/ratto.txt @@ -86,12 +86,13 @@ OnRatto4Death: // This label is reached when all rattos are dead. We clear the respawn timers // (as we are going to delete the instance map anyway), warp you outside, and // from there onwards, Peter handles properly rewarding you. -L_Victor: - warp "000-2-1", 72, 36; +OnVictor: deltimer("RattosControl::OnRatto1Respawn"); deltimer("RattosControl::OnRatto2Respawn"); deltimer("RattosControl::OnRatto3Respawn"); deltimer("RattosControl::OnRatto4Respawn"); - doevent("Peter::OnDone"); + addtimercount("Peter::OnTimeout", 5000); + addtimer(5000, "Peter::OnDone"); + dispbottom l("It looks like all monsters were killed."); end; } diff --git a/npc/000-2-3/elmo.txt b/npc/000-2-3/elmo.txt index c623e321..4f4714f1 100644 --- a/npc/000-2-3/elmo.txt +++ b/npc/000-2-3/elmo.txt @@ -21,7 +21,7 @@ sailortalk; } - if (getq(ShipQuests_ArpanMoney) == 2) + if (getq(ShipQuests_ArpanMoney) >= 2) { got_money; } diff --git a/npc/001-1/calypsan.txt b/npc/001-1/calypsan.txt index c8b5b8bb..36668f1b 100644 --- a/npc/001-1/calypsan.txt +++ b/npc/001-1/calypsan.txt @@ -46,7 +46,7 @@ shop "Cashmere#Dye001-1"; break; default: - debugmes "Calypsan script error, tissue_type is incorrect"; + consolemes(CONSOLEMES_ERROR, "Calypsan script error, tissue_type is incorrect"); break; } close; diff --git a/npc/001-1/doors.txt b/npc/001-1/doors.txt index 67936b4b..7cf4e132 100644 --- a/npc/001-1/doors.txt +++ b/npc/001-1/doors.txt @@ -32,11 +32,15 @@ OnUnTouch: OnTouch: .@enora = getq(ArtisQuests_Enora); + .@legion = getq(Artis_Legion_Progress); + .@brotherhood = getq(General_Brotherhood); if (.@enora < 11) { setfakecells 57, 41, 1; end; } + if (.@legion == 6 && !.@brotherhood) + addtimer 30, "Sophialla#001-1::OnLegionComplete"; setfakecells 57, 41, 0; doorTouch; diff --git a/npc/001-1/enora.txt b/npc/001-1/enora.txt index 45e6e551..140f51b0 100644 --- a/npc/001-1/enora.txt +++ b/npc/001-1/enora.txt @@ -123,7 +123,7 @@ .@zeny_reward = getarg(1); getexp .@exp_reward, 0; - Zeny = Zeny + .@zeny_reward; + Zeny += .@zeny_reward; narrator S_LAST_NEXT, l("You received @@ EXP and @@ E.", .@exp_reward, .@zeny_reward); @@ -300,6 +300,8 @@ l("Only one more Fluffy to kill and it's done!"); return; + } else if (getq(ArtisQuests_Enora) == 10) { + inventoryplace TreasureKey, 1; } speech S_FIRST_BLANK_LINE | S_LAST_NEXT, @@ -314,6 +316,10 @@ { setq ArtisQuests_Enora, 11; enora_reward(140, 500); + getitem TreasureKey, 1; + mesn; + mesq l("Also, here is a %s. If you find a Treasure Chest somewhere, you can open it with this!", getitemlink(TreasureKey)); + next; } return; @@ -440,10 +446,7 @@ OnInit: end; } -001-1,0,0,0 script Mobs#001-1 NPC_HIDDEN,{ - end; - -OnNPCKillEvent: +function script EnoraKills { if (getq(ArtisQuests_Enora) == 10 && killedrid == Fluffy && strcharinfo(PC_MAP) == "001-1" @@ -451,5 +454,6 @@ OnNPCKillEvent: { setq(ArtisQuests_Enora, 10, getq2(ArtisQuests_Enora) + 1); } - end; + return; } + diff --git a/npc/001-1/fexil.txt b/npc/001-1/fexil.txt index 2ea78091..7b612674 100644 --- a/npc/001-1/fexil.txt +++ b/npc/001-1/fexil.txt @@ -122,7 +122,7 @@ l("Deal, I offer you @@ E!", .@price); delitem FluffyFur, .@amount; - Zeny = Zeny + .@price; + Zeny += .@price; break; diff --git a/npc/001-1/flags.txt b/npc/001-1/flags.txt index 10ebf3c4..5e70c25a 100644 --- a/npc/001-1/flags.txt +++ b/npc/001-1/flags.txt @@ -1,25 +1,17 @@ // Evol scripts. // Author: // Micksha +// Jesusalva // Description: // The flags supposed to mark Rowboat unmounting spots in Artis // THIS IS A PLACEHOLDER! 001-1,200,63,0 script Flag#1 NPC_FLAG_L,{ OnTouch: - narrator S_LAST_NEXT, - l("You see a suspicious greenish flag. It reminds you of something you seem to have forgotten."); -} - -001-1,27,101,0 script Flag#2 NPC_FLAG_R,{ - OnTouch: - narrator S_LAST_NEXT, - l("You see a suspicious greenish flag. It reminds you of something you seem to have forgotten."); -} - -001-1,68,139,0 script Flag#3 NPC_FLAG_R,{ - OnTouch: - narrator S_LAST_NEXT, + narrator l("You see a suspicious greenish flag. It reminds you of something you seem to have forgotten."); + close; } +001-1,27,101,0 duplicate(Flag#1) Flag#2 NPC_FLAG_R +001-1,68,139,0 duplicate(Flag#1) Flag#3 NPC_FLAG_R diff --git a/npc/001-1/katja.txt b/npc/001-1/katja.txt index 2d79a730..38ff2725 100644 --- a/npc/001-1/katja.txt +++ b/npc/001-1/katja.txt @@ -6,7 +6,7 @@ // Little girl playing around the hill on top of the port. // She wants you to find her brother. // Variables: -// AtrilQuests_LazyBrother = 19 -- quest var +// ArtisQuests_LazyBrother = 19 -- quest var // LazyBrother_TreesLeft = 15 -- how many trees left to search // LazyBrother_TreeSearched[15] -- whether given tree was searched // LazyBrother_TreeWithBrother -- the number of tree where he's hiding diff --git a/npc/001-1/koga.txt b/npc/001-1/koga.txt index 3aecb09a..2595be63 100644 --- a/npc/001-1/koga.txt +++ b/npc/001-1/koga.txt @@ -9,12 +9,24 @@ speech l("Ah, whom did you bring here?"), l("Isnt that the one Nard found on a float in the sea, with the sign of the Legion on his chest?"); - l("I hope they know what they are doing. So, come on board. I am looking forward to go back to Woodland, haven't been there for a while."); + next; + mesc l("Travel to woodlands?"); + if (askyesno() == ASK_YES) + { + speech + l("I hope they know what they are doing. So, come on board. I am looking forward to go back to Woodland, haven't been there for a while."); + next; + closeclientdialog; + setmount 0; + warp "008-1-1", 33, 63; + dispbottom l("After a tiring, yet fast, travel by Koga, you arrive at @@.", l("Woodlands")); + } close; OnInit: .sex = G_MALE; .distance = 4; + .alwaysVisible = true; end; } diff --git a/npc/001-1/qonan.txt b/npc/001-1/qonan.txt index 48b0c3f8..6805356a 100644 --- a/npc/001-1/qonan.txt +++ b/npc/001-1/qonan.txt @@ -60,6 +60,9 @@ l("You should check on the highest part of the cliff, I was hiding there."), l("I hope to see you soon."); getitem IronShovel, 1; + // For questlog + setq2 ArtisQuests_QOnan, .move__rand_x+any(-1,1); + setq3 ArtisQuests_QOnan, .move__rand_y+any(-1,1); close; case 2: speech S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, @@ -101,7 +104,7 @@ OnInit: } function script QOnanFoundItem { - setq ArtisQuests_QOnan, 2; + setq ArtisQuests_QOnan, 2, 0, 0; // getitem SmallChest, 1; narrator S_FIRST_BLANK_LINE, l("You found a small chest, surprisingly heavy for it's size."), diff --git a/npc/001-1/rowboat.txt b/npc/001-1/rowboat.txt index 3c8429a4..fa95f737 100644 --- a/npc/001-1/rowboat.txt +++ b/npc/001-1/rowboat.txt @@ -15,9 +15,16 @@ l("Do you have this commendatory letter?"); closeclientdialog(); if (askyesno() == 1) { - slide 204, 62; - movenpc("#Rowboat", 192, 25); - setmount 1; + if (getq(General_Brotherhood) >= 2) + { + slide 204, 62; + movenpc("#Rowboat", 192, 25); + setmount 1; + } + else + { + npctalk3 l("You're lying, aren't you? I heard nothing from you-know-whom!"); + } close; } diff --git a/npc/001-1/rowboathelper.txt b/npc/001-1/rowboathelper.txt index 675cfdaf..7cd419e4 100644 --- a/npc/001-1/rowboathelper.txt +++ b/npc/001-1/rowboathelper.txt @@ -27,8 +27,9 @@ l("Maybe you should try this phrase?")); if (askyesno() == ASK_YES) { - narrator(S_LAST_BLANK_LINE | S_LAST_NEXT, - l("'Enter strange phrase here.'")); + mesn strcharinfo(0); + mesc l("Sagratha is great."); + next; speech S_FIRST_BLANK_LINE | S_LAST_NEXT, l("Hello, a rowboat is on his way to the beach. Please wait for a while for it to arrive."); @@ -40,10 +41,6 @@ close; } -// Make sure to unmount the boat when player dies -OnPCDieEvent: - setmount 0; - OnInit: .distance = 1; } @@ -119,3 +116,9 @@ OnInit: .sex = G_OTHER; .distance = 1; } + +function script ForcedUnmount { + setmount 0; + return; +} + diff --git a/npc/001-1/salem.txt b/npc/001-1/salem.txt index c8ea3ab8..ceaeda8f 100644 --- a/npc/001-1/salem.txt +++ b/npc/001-1/salem.txt @@ -48,7 +48,7 @@ return 3; } - Zeny = Zeny - .@price; + Zeny -= .@price; getitem PiouEgg, 1; ArtisQuests_PiousBought += 1; mesq l("You take good care of your piou. Remember to feed it every day."); diff --git a/npc/001-1/sophialla.txt b/npc/001-1/sophialla.txt index ad4d508a..ad0755ec 100644 --- a/npc/001-1/sophialla.txt +++ b/npc/001-1/sophialla.txt @@ -6,15 +6,59 @@ // THIS IS A PLACEHOLDER! 001-1,73,40,0 script Sophialla#001-1 NPC_SOPHIALLA,{ + .@q=getq(General_Brotherhood); + if (!.@q) + { + speech + l("Hello."), + l("Can't you see I am reading? Please go, please."); + close; + } speech l("Hello."), l("Can't you see I am reading? If you need something, tell me the secret password."); + // TODO: Use a token to know password or whatever + select + l("Sorry to disturb you."), + rif(getq(ArtisQuests_MonaDad) == 3, l("Sagratha is great.")), + l("I don't know the password"); + mes ""; + if (@menu == 2) + { + speech + l("If you visit the sewers again... You'll find secret passages..."), + l("Look for the hideout, but tell no one about this. Then, say the password again."); + compareandsetq General_Brotherhood, 1, 2; + } + + speech lg("If you don't know it, just go, please."); + close; +OnLegionComplete: + restorecam; + mesn "???"; + mesc l("A strange voice seems to be calling out your name."); + next; + // NOTE: Sophialla is more than 15 tiles of distance from player + // Server refuses to send client data about where she is and that makes + // setcamnpc fail. This is why I set .alwaysVisible attribute to true. + // Note: you can work around with coordinates, but she won't be drawn. + setcamnpc "Sophialla#001-1"; + mesn; + mesq l("Hey. ppst. I have something important to tell you."); + next; + mesn; + mesq l("I just can't remember what. But come talk to me later once devs becomes less lazy."); + setq General_Brotherhood, 1; + next; + restorecam; + closeclientdialog; close; OnInit: .sex = G_FEMALE; .distance = 2; + .alwaysVisible = true; end; } diff --git a/npc/001-1/trees.txt b/npc/001-1/trees.txt index cba42f8f..2c147bf9 100644 --- a/npc/001-1/trees.txt +++ b/npc/001-1/trees.txt @@ -4,7 +4,7 @@ // Description: // Invisible tree NPCs for "Lazy Brother" quest // Variables: -// AtrilQuests_LazyBrother = 19 -- quest var +// ArtisQuests_LazyBrother = 19 -- quest var // LazyBrother_TreesLeft = 15 -- how many trees left to search // LazyBrother_TreeSearched[15] -- whether given tree was searched // LazyBrother_TreeWithBrother -- the number of tree where he's hiding @@ -99,7 +99,7 @@ L_FoundHim: close; } -001-1,179,30,0 script #AtrilTree1 NPC_KATJA_TREE,{ +001-1,179,30,0 script #ArtisTree1 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(1); end; OnInit: @@ -108,7 +108,7 @@ OnInit: end; } -001-1,177,29,0 script #AtrilTree2 NPC_KATJA_TREE,{ +001-1,177,29,0 script #ArtisTree2 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(2); end; OnInit: @@ -117,7 +117,7 @@ OnInit: end; } -001-1,183,28,0 script #AtrilTree3 NPC_KATJA_TREE,{ +001-1,183,28,0 script #ArtisTree3 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(3); end; OnInit: @@ -126,7 +126,7 @@ OnInit: end; } -001-1,182,25,0 script #AtrilTree4 NPC_KATJA_TREE,{ +001-1,182,25,0 script #ArtisTree4 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(4); end; OnInit: @@ -135,7 +135,7 @@ OnInit: end; } -001-1,187,26,0 script #AtrilTree5 NPC_KATJA_TREE,{ +001-1,187,26,0 script #ArtisTree5 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(5); end; OnInit: @@ -144,7 +144,7 @@ OnInit: end; } -001-1,189,28,0 script #AtrilTree6 NPC_KATJA_TREE,{ +001-1,189,28,0 script #ArtisTree6 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(6); end; OnInit: @@ -153,7 +153,7 @@ OnInit: end; } -001-1,184,30,0 script #AtrilTree7 NPC_KATJA_TREE,{ +001-1,184,30,0 script #ArtisTree7 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(7); end; OnInit: @@ -162,7 +162,7 @@ OnInit: end; } -001-1,189,31,0 script #AtrilTree8 NPC_KATJA_TREE,{ +001-1,189,31,0 script #ArtisTree8 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(8); end; OnInit: @@ -171,7 +171,7 @@ OnInit: end; } -001-1,191,30,0 script #AtrilTree9 NPC_KATJA_TREE,{ +001-1,191,30,0 script #ArtisTree9 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(9); end; OnInit: @@ -180,7 +180,7 @@ OnInit: end; } -001-1,191,33,0 script #AtrilTree10 NPC_KATJA_TREE,{ +001-1,191,33,0 script #ArtisTree10 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(10); end; OnInit: @@ -189,7 +189,7 @@ OnInit: end; } -001-1,187,34,0 script #AtrilTree11 NPC_KATJA_TREE,{ +001-1,187,34,0 script #ArtisTree11 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(11); end; OnInit: @@ -198,7 +198,7 @@ OnInit: end; } -001-1,185,35,0 script #AtrilTree12 NPC_KATJA_TREE,{ +001-1,185,35,0 script #ArtisTree12 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(12); end; OnInit: @@ -207,7 +207,7 @@ OnInit: end; } -001-1,182,34,0 script #AtrilTree13 NPC_KATJA_TREE,{ +001-1,182,34,0 script #ArtisTree13 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(13); end; OnInit: @@ -216,7 +216,7 @@ OnInit: end; } -001-1,180,33,0 script #AtrilTree14 NPC_KATJA_TREE,{ +001-1,180,33,0 script #ArtisTree14 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(14); end; OnInit: @@ -225,7 +225,7 @@ OnInit: end; } -001-1,181,32,0 script #AtrilTree15 NPC_KATJA_TREE,{ +001-1,181,32,0 script #ArtisTree15 NPC_KATJA_TREE,{ LazyBrotherTreeFunc(15); end; OnInit: diff --git a/npc/001-2-11/mona.txt b/npc/001-2-11/mona.txt index 366b658c..2f4e3da0 100644 --- a/npc/001-2-11/mona.txt +++ b/npc/001-2-11/mona.txt @@ -3,10 +3,12 @@ // Reid // Jesusalva // Description: -// A rich girl holding a candle. Her father went to examine weird noises on -// sewers and still haven't come back. Her mother is gone, but it is not clear -// if she died, abandoned them, or something else. +// A rich girl holding a candle. Her father went to examine weird noises in the +// sewers and still hasn't come back. Her mother is gone, but it is not clear +// whether she died, abandoned them, or something else. // Variable: +// MONA_TIME = gettimeparam(GETTIME_DAYOFMONTH) so you need 3 days +// MONA_REPEAT = How many times the quest was done // ArtisQuests_MonaDad // Quest states: // 0 - Quest not started @@ -35,14 +37,14 @@ } speech S_LAST_NEXT | S_NO_NPC_NAME, - l("Daddy did not come back home... He said that he would be back for lunch but it has already been a week!"), + l("Daddy never came back home... He said that he would be back for lunch but it has already been two days!"), l("You have to find him, or else I will tell him that you did not help me."); - switch (select(l("You do not give me much options."), l("The elder ran away from you."))) + switch (select(l("You do not give me a lot of options."), l("Your dad ran away from you!"))) { case 1: speech S_FIRST_BLANK_LINE, - l("He said that he would check why the manhole next to the house was doing weird sounds."), + l("He said that he would check why weird noises were coming from the manhole next to the house."), l("But he never returned."), l("Please find my daddy..."); @@ -64,30 +66,41 @@ // only to support Global Instances and in general is not a smart thing to do. function check_daddy_quest { - // Did you really brought Mundane to sewer exit (152, 56)? + // Did you really bring Mundane to sewer exit? // We need to add 1 tile in each direction of tolerance because addtimer() // is not exactly what I would call “a reliable way to do stuff” // Note that @variables sometimes get erasen AT RANDOM. // If this problem happens, move it char variables. // (that might cause problems with logout though.) // Temporary variables give you a time limit to report back... - if (@MUNDANE_OLDX >= 151 && @MUNDANE_OLDX <= 153 && - @MUNDANE_OLDY >= 55 && @MUNDANE_OLDY <= 57) { - // There's no need to check if instance still exists, because - // when the instance expires, you get warped to *somewhere*. - // This means the timer will die and MUNDANE_OLD* variables will stop - // being updated. - inventoryplace WoodenBow, 1; - speech 0x0, - l("Daddy finally came back home! He grabbed a snack and said he would be returning to the sewers."), - lg("He did said to you take this @@ as a gift. He says you are very skilled and will make a good use of his old weapon.", - "He did said to you take this @@ as a gift. He says you are very skilled and will make a good use of his old weapon.", - getitemlink(WoodenBow)), - l("He was never the same since mommy vanished..."); - getitem WoodenBow, 1; - setq(ArtisQuests_MonaDad, 3); - close; - } + // + // There's no need to check if instance still exists, because + // when the instance expires, you get warped to *somewhere*. + // This means the timer will die and MUNDANE_OLD* variables will stop + // being updated. + .@success=false; + + // Sewer mouths (warps to 001-1) + if (is_between(151, 153, @MUNDANE_OLDX) && + is_between(55, 57, @MUNDANE_OLDY)) + .@success=true; + + if (is_between(195, 197, @MUNDANE_OLDX) && + is_between(34, 36, @MUNDANE_OLDY)) + .@success=true; + + if (is_between(197, 199, @MUNDANE_OLDX) && + is_between(59, 61, @MUNDANE_OLDY)) + .@success=true; + + if (is_between(84, 86, @MUNDANE_OLDX) && + is_between(129, 131, @MUNDANE_OLDY)) + .@success=true; + + if (.@success) + return true; + else + return false; } // Here the script really starts @@ -97,11 +110,51 @@ } else if (getq(ArtisQuests_MonaDad) == 3) { - npctalkonce l("Thanks for finding daddy... I wish he spent more time with me..."); // TODO: Sophialla + // Quest Repeat takes priority. Don't worry, you won't lose password unless + // you accept the quest again. + if (MONA_TIME <= gettimeparam(GETTIME_DAYOFMONTH)) { + find_daddy_quest(); + } + + // Sagratha is Great B-) + npctalkonce any( + l("Thanks for finding daddy... I wish he spent more time with me..."), + l("Sagratha is great. Why does the strange woman near the Legion building always say that to daddy...?")); // TODO: Polish } else if (getq(ArtisQuests_MonaDad) == 2) { - check_daddy_quest(); + if (check_daddy_quest()) + { + if (!MONA_REPEAT) + { + inventoryplace WoodenSword, 1; + speech 0x0, + l("Daddy finally came back home! He grabbed a snack and said he would be returning to the sewers."), + lg("He did say that I should give you this @@ as a gift. He says you are very skilled and will make good use of his old weapon.", + "He did say that I should give you this @@ as a gift. He says you are very skilled and will make good use of his old weapon.", + getitemlink(WoodenSword)), + l("He has never been the same since mommy went away..."); + getitem WoodenSword, 1; + } + else if (MONA_REPEAT == 10) + { + speech + l("Daddy asked me to give you some money as a thank you for looking out for me."), + l("I don't want you! I want daddy!"); + mesc l("*sniff sniff*"); + emotion E_SAD; + Zeny+=1000; + } + else + { + inventoryplace TrainingArrow, 100; + getitem TrainingArrow, min(MONA_REPEAT*20, 100); + } + setq(ArtisQuests_MonaDad, 3); + MONA_TIME=gettimeparam(GETTIME_DAYOFMONTH)+3; + MONA_REPEAT+=1; + close; + } } else { diff --git a/npc/001-2-19/lloyd.txt b/npc/001-2-19/lloyd.txt index 9dfd97de..a0051caa 100644 --- a/npc/001-2-19/lloyd.txt +++ b/npc/001-2-19/lloyd.txt @@ -115,7 +115,7 @@ } else { - Zeny = Zeny - .@price; + Zeny -= .@price; setq ArtisQuests_Lloyd, 1; speech S_FIRST_BLANK_LINE | S_LAST_NEXT, l("Perfect!"), @@ -233,12 +233,14 @@ OnInit: .sex = G_MALE; .distance = 4; end; +} -OnPCLoginEvent: +function script FixBankVault { if (#MerchantBank) { BankVault += max(0, #MerchantBank); #MerchantBank = 0; } - end; + return; } + diff --git a/npc/001-2-22/peter.txt b/npc/001-2-22/peter.txt index 7fefb5f2..9c4402a2 100644 --- a/npc/001-2-22/peter.txt +++ b/npc/001-2-22/peter.txt @@ -256,6 +256,7 @@ OnTimeout: // It's not _buggy_, it is just reckless. I would like a setting to restrict it // to destroy only instances owned by the char, or to destroy by name :p OnDone: + warp "001-2-22", 72, 36; .@q3 = getq3(ShipQuests_Peter); //instance_destroy(.@q3); if (@peter) @@ -285,7 +286,7 @@ OnDone: default: @peter=750; break; } - Zeny = Zeny + @peter; + Zeny += @peter; message strcharinfo(0), l("You receive @@ E!", @peter); // Some cleanup. Shouldn't cause bugs but it's absence causes a ugly behavior. diff --git a/npc/001-2-23/ratto.txt b/npc/001-2-23/ratto.txt index 9b4130f6..24bb1e1a 100644 --- a/npc/001-2-23/ratto.txt +++ b/npc/001-2-23/ratto.txt @@ -87,11 +87,12 @@ OnRatto4Death: // (as we are going to delete the instance map anyway), warp you outside, and // from there onwards, Peter handles properly rewarding you. L_Victor: - warp "001-2-22", 72, 36; deltimer("RattosControl#Artis::OnRatto1Respawn"); deltimer("RattosControl#Artis::OnRatto2Respawn"); deltimer("RattosControl#Artis::OnRatto3Respawn"); deltimer("RattosControl#Artis::OnRatto4Respawn"); - doevent("Peter#Artis::OnDone"); + addtimercount("Peter#Artis::OnTimeout", 5000); + addtimer(5000, "Peter#Artis::OnDone"); + dispbottom l("It looks like all monsters were killed."); end; } diff --git a/npc/001-2-27/shop.txt b/npc/001-2-27/shop.txt index 597fd06b..c942eef5 100644 --- a/npc/001-2-27/shop.txt +++ b/npc/001-2-27/shop.txt @@ -30,6 +30,7 @@ OnClock01600: restoreshopitem LeatherShield, 10; restoreshopitem CopperArmbands, 8; restoreshopitem IronArmbands, 6; + end; } 001-2-27,43,29,0 trader Store#Weapon001-2-27 NPC_NO_SPRITE,{ @@ -40,6 +41,7 @@ OnInit: sellitem PiouSlayer, -1, 50; sellitem TrainingGladius, -1, 25; sellitem WoodenSword, -1, 50; + sellitem TrainingArrow, -1, 20000; .sex = G_OTHER; .distance = 2; @@ -57,4 +59,6 @@ OnClock01600: restoreshopitem PiouSlayer, 25; restoreshopitem TrainingGladius, 8; restoreshopitem WoodenSword, 25; + restoreshopitem TrainingArrow, 20000; + end; } diff --git a/npc/001-2-28/plush.txt b/npc/001-2-28/plush.txt index 330258b8..0cba5b2a 100644 --- a/npc/001-2-28/plush.txt +++ b/npc/001-2-28/plush.txt @@ -27,7 +27,7 @@ else { emotion E_HAPPY; - Zeny = Zeny - .@price; + Zeny -= .@price; INN_REGISTER = REDPLUSH_INN; PC_IS_DEAD = false; diff --git a/npc/001-2-32/_import.txt b/npc/001-2-32/_import.txt index 9043352d..b59046e0 100644 --- a/npc/001-2-32/_import.txt +++ b/npc/001-2-32/_import.txt @@ -1,4 +1,4 @@ -// Map 001-2-32: unnamed +// Map 001-2-32: Training Arena Lobby // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/001-2-32/_warps.txt", "npc/001-2-32/doors.txt", diff --git a/npc/001-2-32/_warps.txt b/npc/001-2-32/_warps.txt index 306493cb..4db4b354 100644 --- a/npc/001-2-32/_warps.txt +++ b/npc/001-2-32/_warps.txt @@ -1,3 +1,3 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-32: unnamed warps +// Map 001-2-32: Training Arena Lobby warps 001-2-32,27,33,0 warp #001-2-32_27_33 0,0,001-2-33,39,33 diff --git a/npc/001-2-32/serena.txt b/npc/001-2-32/serena.txt index 187a654c..fa650ef1 100644 --- a/npc/001-2-32/serena.txt +++ b/npc/001-2-32/serena.txt @@ -6,9 +6,7 @@ 001-2-32,27,27,0 script Serena NPC_SERENA,{ mesn; - mesq lg("Oh darling, what brought you here?"); - // ^^^^^^^ - // Expresses familiarity or elderliness in relation to PC. + mesq lg("Oh darling, what brought you here?"); // TRANSLATORS: Darling - Expresses familiarity or elderliness in relation to PC. // <scratch> // [ PC]: I was just looking around. @@ -47,9 +45,6 @@ // Alt-Siege // The city is being attacked. Go help the warriors and town-guard. - goto L_Close; - -L_Close: close; OnInit: diff --git a/npc/001-2-33/lozerk.txt b/npc/001-2-33/lozerk.txt index cdafb6bf..c751d4a0 100644 --- a/npc/001-2-33/lozerk.txt +++ b/npc/001-2-33/lozerk.txt @@ -143,7 +143,7 @@ { .@legion_progress = getq(Artis_Legion_Progress); .@enora = getq(ArtisQuests_Enora); - debugmes .@legion_progress + " " + .@enora; + consolemes(CONSOLEMES_DEBUG, .@legion_progress + " " + .@enora); select rif((.@legion_progress == 0) && (.@enora == 11), lg("Enora sent me here.")), rif(.@legion_progress == 2, lg("I'm done with my training.")), diff --git a/npc/001-2-33/mapflags.txt b/npc/001-2-33/mapflags.txt index 95e3a6ba..4882b03e 100644 --- a/npc/001-2-33/mapflags.txt +++ b/npc/001-2-33/mapflags.txt @@ -1,2 +1,3 @@ -001-2-33 mapflag mask 5 +001-2-33 mapflag mask 13 +001-2-33 mapflag nosave 001-2-33,34,42 001-2-33 mapflag town diff --git a/npc/001-2-33/triggers.txt b/npc/001-2-33/triggers.txt index 47a5ea90..e540869c 100644 --- a/npc/001-2-33/triggers.txt +++ b/npc/001-2-33/triggers.txt @@ -7,25 +7,25 @@ // Transition Top triggers 001-2-33,26,35,0 script #001-2-33LeftRemTop NPC_HIDDEN,0,2,{ OnTouch: - artisALRemTopMask; + artisALResetMask; close; } 001-2-33,27,35,0 script #001-2-33LeftAddTop NPC_HIDDEN,0,2,{ OnTouch: - artisALAddTopMask; + artisALTopMask; close; } 001-2-33,42,35,0 script #001-2-33RightRemTop NPC_HIDDEN,0,2,{ OnTouch: - artisALRemTopMask; + artisALResetMask; close; } 001-2-33,41,35,0 script #001-2-33RightAddTop NPC_HIDDEN,0,2,{ OnTouch: - artisALAddTopMask; + artisALTopMask; close; } @@ -33,69 +33,70 @@ OnTouch: 001-2-33,25,32,0 script #001-2-33LeftRemBot NPC_HIDDEN,1,0,{ OnTouch: - artisALRemBotMask; + artisALResetMask; close; } 001-2-33,25,31,0 script #001-2-33LeftAddBot NPC_HIDDEN,1,0,{ OnTouch: - artisALAddBotMask; + artisALBottomMask; close; } 001-2-33,43,32,0 script #001-2-33RightRemBot NPC_HIDDEN,1,0,{ OnTouch: - artisALRemBotMask; + artisALResetMask; close; } 001-2-33,43,31,0 script #001-2-33RightAddBot NPC_HIDDEN,1,0,{ OnTouch: - artisALAddBotMask; + artisALBottomMask; close; } // Warped location triggers -001-2-33,24,30,0 script #001-2-33WarpTopLeft NPC_HIDDEN,1,1,{ +001-2-33,24,30,0 script #001-2-33WarpTopLeft NPC_HIDDEN,0,0,{ OnTouch: - artisALUpdateMask; + artisALBottomMask; close; } -001-2-33,44,30,0 script #001-2-33WarpTopRight NPC_HIDDEN,1,1,{ +001-2-33,44,30,0 script #001-2-33WarpTopRight NPC_HIDDEN,0,0,{ OnTouch: - artisALUpdateMask; + artisALBottomMask; close; } -001-2-33,29,32,0 script #001-2-33WarpMidLeft NPC_HIDDEN,1,1,{ +// WarpMid is crazy and not working correctly, cause unknown. +001-2-33,29,34,0 script #001-2-33WarpMidLeft NPC_HIDDEN,1,1,{ OnTouch: - artisALUpdateMask; + artisALTopMask; close; } -001-2-33,39,32,0 script #001-2-33WarpMidRight NPC_HIDDEN,1,1,{ +001-2-33,39,34,0 script #001-2-33WarpMidRight NPC_HIDDEN,1,1,{ OnTouch: - artisALUpdateMask; + artisALTopMask; close; } -001-2-33,34,45,0 script #001-2-33WarpArtis NPC_HIDDEN,1,1,{ +001-2-33,34,45,0 script #001-2-33WarpArtis NPC_HIDDEN,2,3,{ OnTouch: - artisALUpdateMask; + artisALTopMask; close; } // Bottom Warp location triggers -001-2-33,43,38,0 script #001-2-33WarpBotLeft NPC_HIDDEN,1,0,{ +001-2-33,43,39,0 script #001-2-33WarpBotLeft NPC_HIDDEN,1,0,{ OnTouch: - artisALUpdateMask; + artisALResetMask; close; } -001-2-33,25,38,0 script #001-2-33WarpBotRight NPC_HIDDEN,1,0,{ +001-2-33,25,39,0 script #001-2-33WarpBotRight NPC_HIDDEN,1,0,{ OnTouch: - artisALUpdateMask; + artisALResetMask; close; } diff --git a/npc/001-2-34/_import.txt b/npc/001-2-34/_import.txt index 326973e6..9ec74d40 100644 --- a/npc/001-2-34/_import.txt +++ b/npc/001-2-34/_import.txt @@ -1,4 +1,4 @@ -// Map 001-2-34: unnamed +// Map 001-2-34: Training Room Lobby // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/001-2-34/_warps.txt", "npc/001-2-34/doors.txt", diff --git a/npc/001-2-34/_warps.txt b/npc/001-2-34/_warps.txt index 1311f071..06f74a95 100644 --- a/npc/001-2-34/_warps.txt +++ b/npc/001-2-34/_warps.txt @@ -1,3 +1,3 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-34: unnamed warps +// Map 001-2-34: Training Room Lobby warps 001-2-34,29,33,0 warp #001-2-34_29_33 0,0,001-2-33,29,33 diff --git a/npc/001-2-34/doors.txt b/npc/001-2-34/doors.txt index ca513945..e2ffee1f 100644 --- a/npc/001-2-34/doors.txt +++ b/npc/001-2-34/doors.txt @@ -1,29 +1,29 @@ // Evol scripts. // Author: // Reid +// Omatt +// Toams +// Jesus // Description: // Doors NPCs. 001-2-34,23,29,0 script ToTrainingRoom#001-2-34 NPC_HIDDEN,0,0,{ - OnTouch: - if ((getmapusers($@MAP_NAME$) == 0) && ($@FightingIsActive > 0)) - { - set $@FightingIsActive, 0; - killmonsterall "001-2-36"; - } - if (mobcount("001-2-36","all") > 0 && $@FightingIsActive > 0) - { - narrator - l("You hear some sound behind the door."), - l("Somebody is probably training, better wait for him to finish."); - } - else - { - warp "001-2-36", 36, 30; + .@q2=getq2(ArtisQuests_TrainingLegion); + // Map name limit: 4 chars (atl1) + .@mapn$="atl1@"+getcharid(0); + if (isinstance(.@q2) && .@q2 > 0) { + warp .@mapn$, 36, 30; + } else { + .@inst = instance_create("Training Room "+getcharid(0), getcharid(3), IOT_CHAR); + instance_attachmap("001-2-36", .@inst, false, .@mapn$); + // 30 minutes (1800s) inside, or 5 minutes (300s) outside + instance_set_timeout(1800, 300, .@inst); + instance_init(.@inst); + setq2 ArtisQuests_TrainingLegion, .@inst; + warp .@mapn$, 36, 30; } - closeclientdialog; - close; + end; } diff --git a/npc/001-2-34/samantha.txt b/npc/001-2-34/samantha.txt index f49e15aa..a571ccf6 100644 --- a/npc/001-2-34/samantha.txt +++ b/npc/001-2-34/samantha.txt @@ -7,10 +7,6 @@ 001-2-34,29,27,0 script Samantha NPC_SAMANTHA,{ mesn; mesq lg("Look who we have here, did you come for a training session?"); - - goto L_Close; - -L_Close: close; OnInit: diff --git a/npc/001-2-35/_import.txt b/npc/001-2-35/_import.txt index 969d9e1c..797b852a 100644 --- a/npc/001-2-35/_import.txt +++ b/npc/001-2-35/_import.txt @@ -1,4 +1,3 @@ -// Map 001-2-35: unnamed +// Map 001-2-35: Training Arena // This file is generated automatically. All manually added changes will be removed when running the Converter. -"npc/001-2-35/_warps.txt", "npc/001-2-35/mapflags.txt", diff --git a/npc/001-2-36/_import.txt b/npc/001-2-36/_import.txt index 222e5a7f..403b0b12 100644 --- a/npc/001-2-36/_import.txt +++ b/npc/001-2-36/_import.txt @@ -1,5 +1,5 @@ -// Map 001-2-36: unnamed +// Map 001-2-36: Training Room // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/001-2-36/_warps.txt", +"npc/001-2-36/hector.txt", "npc/001-2-36/mapflags.txt", -"npc/001-2-36/training_room_npc.txt", diff --git a/npc/001-2-36/_warps.txt b/npc/001-2-36/_warps.txt index 530050a7..bcb74de9 100644 --- a/npc/001-2-36/_warps.txt +++ b/npc/001-2-36/_warps.txt @@ -1,3 +1,3 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-36: unnamed warps +// Map 001-2-36: Training Room warps 001-2-36,37,30,0 warp #001-2-36_37_30 0,0,001-2-34,24,29 diff --git a/npc/001-2-36/hector.txt b/npc/001-2-36/hector.txt new file mode 100644 index 00000000..d25ca9e3 --- /dev/null +++ b/npc/001-2-36/hector.txt @@ -0,0 +1,459 @@ +// TrainingRoom +// Author: +// jak1 +// omatt +// toams +// Story: +// Reid +// Teru +// Spellchecking & Dialogs: +// Reid +// toams +// Variable: +// .fightingActive +// 0 = no fight active +// 1 = swordfight active +// 2 = bowfight active +// 3 = skillfight +// ArtisQuests_TrainingLegion +// 0 not started at all +// 1 swordTraining finished +// 2 bowTraining finished +// 3 bow and sword finished +// 4 end of training +// .mobID is related to quest state +// +// TODO adding rand messages like "try hit it harder..." for wave's +// TODO in first, second, and third training, input some tips about related weapon given. + + +001-2-36,32,36,0 script Hector#001-2-36 NPC_LUCAS,{ + + + 'instanceID = instance_id(); + 'npcName$ = strnpcinfo(NPC_NAME_UNIQUE); // required for call the label in the npc of this one instance + attachnpctimer; + initnpctimer; + + function waveEnded { + + if (.fightingActive == 1) + { + npctalk3(l("Well done, you aren't even bleeding that much!")); + if (getq(.quest_training) == 0) + setq(.quest_training, 1); + if (getq(.quest_training) == 2) + setq(.quest_training, 3); + } + if (.fightingActive == 2) + { + npctalk3(l("Great! Don't mind those scorched hairs, they will grow back.")); + if (getq(.quest_training) == 0) + setq(.quest_training, 2); + if (getq(.quest_training) == 1) + setq(.quest_training, 3); + } + if (.fightingActive == 3) + { + if (getq(.quest_training) == 3) + { + npctalk3(l("Congratulations, you have finished your training.")); + sleep2(2000); + npctalk3(l("The only way to improve yourself is practice, practice and some more practice.")); + setq(.quest_training, 4); + setq(Artis_Legion_Progress, 2); + } + else + { + npctalk3(l("You finished training the bashing skill. Pretty powerful isn't it?")); + } + } + + .currentWaveLevel = 1; + .fightingActive = 0; + 'mobDead = 0; + end; + } + + function mobSpawn { + + if (.fightingActive != 0) + { + if (.currentWaveLevel == .maxWaves) + { + npctalk3(l("Last Wave!")); + } + else + { + npctalk3(l("Wave " + .currentWaveLevel + "!")); + } + + areamonster('map$, .mobCoordinate[0], .mobCoordinate[1], .mobCoordinate[2], .mobCoordinate[3], + /* map x1 y1 x2 y2 */ + strmobinfo(1, .mobID[.fightingActive]), .mobID[.fightingActive], .currentWaveLevel, 'npcName$+"::OnTrainingMobDead"); + /* mob display mob id amount label */ + } + + end; + } + + function trainingEnd { + + sleep2(1500); + npctalk3(l("This training is over!")); + .fightingActive = 0; + .currentWaveLevel = 1; + killmonster('map$, "All"); + stopnpctimer(); + end; + } + + function checkWeapon { + // check for sword in swordtraining + if (getiteminfo(getequipid(EQI_HAND_R), ITEMINFO_SUBTYPE) != W_1HSWORD && .fightingActive == 1) + { + npctalk3(l("Hey! Use your sword!")); + trainingEnd; + } + + // check for bow in bowtraining + if (getiteminfo(getequipid(EQI_HAND_R), ITEMINFO_SUBTYPE) != W_BOW && .fightingActive == 2) + { + npctalk3(l("Hey! Use your bow!")); + trainingEnd; + } + + // no weapons may be equiped when training skill + if (getequipid(EQI_HAND_R) != -1 && .fightingActive == 3) + { + npctalk3(l("Hey! No weapons allowed this round!")); + trainingEnd; + } + + } + + + function mobKilled { + + 'mobDead = 0; // reset the count + + checkWeapon; // check if correct weapon is in use + + // on first skill training give SM_BASH skill and explain how to use it. + if (getq(.quest_training) == 3 && .currentWaveLevel == 1) + { + setcamnpc(strnpcinfo(NPC_NAME_UNIQUE)); // focus the npc when he talk to the player + speech(S_LAST_NEXT, + l("Using a skill consumes Mana."), + l("It takes a while to have full Mana again."), + l("The more intelligence points you have, the faster it goes."), + l("If you sit, you regain your Mana faster."), + l("Or you can drink a mana potion. This restores some Mana. How much depends on the potion."), + l("Here take one! I have plenty of them.")); + closedialog; + getitem(.mana_potion, 1); + sleep2(3000); + } + + if (.currentWaveLevel == .maxWaves ) + { + waveEnded; + } + + + .currentWaveLevel++; // next wave after killed dummy + + mobSpawn; + } + + function swordTraining { + speech(S_LAST_BLANK_LINE | S_LAST_NEXT, + l("You chose the sword for this training, make sure to equip it or we can't start.")); + + speech(S_LAST_BLANK_LINE | S_NO_NPC_NAME, + l("I will place some dummies in the fighting arena. @@ waves of dummies, kill them to finish this training.", .maxWaves), + l("Ready?")); + + askyesno; + if (@menu == ASK_NO) + { + closedialog; + end; + } + + closedialog; + .fightingActive = 1; + initnpctimer; + } + + function bowTraining { + speech(S_LAST_BLANK_LINE | S_LAST_NEXT, + l("You chose the bow for this training, make sure to equip it or we can't start.")); + + speech(S_LAST_BLANK_LINE | S_NO_NPC_NAME, + l("I've set these dummies on fire. Don't get too close to the dummies or the fire will hurt you."), + l("The range of your bow makes it possible to kill them from a distance."), + l("Ready?")); + + askyesno; + if (@menu == ASK_NO) + { + closedialog; + end; + } + + .fightingActive = 2; + initnpctimer; + } + + function skillTraining { + + if (getq(.quest_training) == 3) + { + //Give bashing skill + skill(.skill_name, 1, 0); + + speech(S_LAST_BLANK_LINE | S_NO_NPC_NAME, + l("Lets teach you the bashing skill. This is a very powerful way to hit your enemy by using only your bare hands."), + l("To use the skill you have to open your skills menu. Here you select the offensive tab and select the bash skill. When the bash skill is selected, press the use button the use the skill.")); + } + + speech(S_LAST_BLANK_LINE | S_NO_NPC_NAME, + l("You can only use this skill with bare hands, so make sure to unequip your weapons."), + l("@@ waves of dummies, you know how that ends.", .maxWaves), + l("Ready?")); + + askyesno; + if (@menu == ASK_NO) + { + closedialog; + end; + } + + .fightingActive = 3; + initnpctimer; + } + + function checkCombatZone { + + getmapxy('map$, @x, @y, 0); + if (@x < 24 || @x > 32 || @y < 33 || @y > 43) + return 1; + return 0; + } + + // choose training and start it + function trainingStart { + + if (checkCombatZone()) + { + npctalk3(l("Please enter the combat zone on the left.")); + closedialog; + end; + } + if (.fightingActive == 0) + { + switch (getq(.quest_training)) + { + case 0: speech(S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, + l("Which weapon do you want to train? Bow or sword?")); + + switch (select(l("I'll start with the sword."), + l("I would like to train the bow first."), + l("I don't feel like training today, see you later."))) + { + case 1: swordTraining; break; + case 2: bowTraining; break; + case 3: closedialog; end; + } + break; + case 1: speech(S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, + l("You have finished the sword training. Do you want to start training the bow?")); + + switch (select(l("Yes, I'm ready for some arrow shooting!"), + l("Can I train the sword some more?"), + l("I don't feel like training today, see you later."))) + { + case 1: bowTraining; break; + case 2: swordTraining; break; + case 3: closedialog; end; + } + break; + case 2: speech(S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, + l("You have finished the bow training. Do you want to start training the sword?")); + + switch (select(l("Yes, teach me how to cut and slice these dummies!"), + l("Can I train the bow some more?"), + l("I don't feel like training today, see you later."))) + { + case 1: swordTraining; break; + case 2: bowTraining; break; + case 3: closedialog; end; + } + break; + case 3: speech(S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, + l("You have mastered both the bow and the sword. The only thing left to teach you is the bashing skill.")); + + switch (select(l("A skill? That sounds useful!"), + l("Can I train the sword some more?"), + l("I would rather like to train the bow again."), + l("I don't feel like training today, see you later."))) + { + case 1: skillTraining; break; + case 2: swordTraining; break; + case 3: bowTraining; break; + case 4: closedialog; end; + } + break; + case 4: speech(S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, + l("Sure, which training do you want to start?")); + + switch (select(l("Skill training please"), + l("Can I train the sword some more?"), + l("I would like to train the bow again."), + l("I've changed my mind, see you later."))) + { + case 1: skillTraining; break; + case 2: swordTraining; break; + case 3: bowTraining; break; + case 4: closedialog; end; + } + break; + } + closedialog; + + npctalk3(l("Let's begin")); + + mobSpawn; + } + } + + function mainLoop { + + // if fighting is active say encouraging words to the player + if (.fightingActive != 0) + { + switch (.fightingActive) + { + case 1: npctalk3(l("Attack with your sword and kill them!")); end; + case 2: npctalk3(l("Use your bow and kill them!")); end; + case 3: npctalk3(l("Hey lazy bum! Attack the dummies")); end; + default: break; + } + } + + // only start if player talked with Lozerk + if (getq(Artis_Legion_Progress) < 1 ) + { + speech(S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("This is the training ground. And I ain't training nobody unless Lieutenant Lozerk tells me to!"), + l("So please get out!")); + closedialog; + end; + } + else + { + switch (getq(.quest_training)) + { + case 0: speech(S_FIRST_BLANK_LINE | S_LAST_NEXT, + l(.mockingGreeting$[rand(getarraysize(.mockingGreeting$))]), + l("Do you want some training? To be honest, it looks like you could use some...")); + break; + case 4: speech(S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Your training is finished, I taught you all I know."), + l("So now go and explore the world!")); + switch (select( + l("Can I first have an other look at your book?"), + l("Before doing that can I improve my fighting skills some more?"), + l("Okay!"))) + { + case 1: doevent("#EvolTutorial::OnRemoteHelp");; break; + case 2: trainingStart; break; + case 3: closedialog; end; + } + closedialog; + end; + default: speech(S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Hello again, ready to continue your lessons?")); break; + } + + do + { + selectd( + l("Yes, train me!"), + l("Hmm... But what is exactly this training?"), + l("I'm a bit lost in this game, can you first give me few tips?"), + l("Not right now, it looks like I got other stuff to do.")); + + switch (@menu) + { + case 1: trainingStart; break; + case 2: + // here text who explain what is the training of this npc + speech(S_FIRST_BLANK_LINE | S_LAST_NEXT | S_LAST_BLANK_LINE | S_NO_NPC_NAME, + l("In this training, my goal is to teach you how to be a skilled warrior, who can use a sword, a bow and a skill."), + l("For this, you need a sword and a bow."), + l("After you gathered your weapons, I will teach you how to use them.")); + break; + case 3: + speech(S_FIRST_BLANK_LINE | S_LAST_NEXT | S_LAST_BLANK_LINE | S_NO_NPC_NAME, + l("I have a book with all the info you need, do you want to read it?")); + askyesno; + if (@menu == ASK_YES) + { + doevent("#EvolTutorial::OnRemoteHelp"); + closedialog; + end; + } + break; + case 4: closedialog; end; + + default: closedialog; end; + } + } while (1); + } + } + + mainLoop; + closedialog; + end; + +OnTimer1000: + if (.fightingActive != 0) + { + if (checkCombatZone()) + { + npctalk3(l("You left the combat zone!")); + trainingEnd; + } + checkWeapon; + initnpctimer; + } + end; + +OnTrainingMobDead: + // the amount of mob spawned depend on currentwave + if (++'mobDead == .currentWaveLevel) + { + mobKilled; + } + end; + +OnInit: + .mana_potion = LargeMana; + .skill_name = SM_BASH; + .quest_training = ArtisQuests_TrainingLegion; + .quest_debug = .quest_training; + .maxWaves = 3; + + .currentWaveLevel = 1; + .fightingActive = 0; + + // here input some sentences "hello noob" like, the npc pick randomly a sentence + setarray .mockingGreeting$[0], "Hey noob!", "Hey somethingwholooklikeawarrior...", "Sup' chibi."; + setarray .mobID[0],0, Dummy, FireDummy, Dummy; // an array of dummies, one for each training + setarray .mobCoordinate[0], 24, 34, 31, 41; // this represent the square of "ring" training + + end; + +} diff --git a/npc/001-2-36/training_room_npc.txt b/npc/001-2-36/training_room_npc.txt deleted file mode 100644 index 022b5d2e..00000000 --- a/npc/001-2-36/training_room_npc.txt +++ /dev/null @@ -1,165 +0,0 @@ -// TrainingRoom -// -// Author: -// jak1 -// -// Story: -// Akko Teru -// Reid -// -// Spellchecking & Dialogs -// Reid - -// ~~ VARS ~~ -// $@FightingIsActive -// 0 = can Warp in Room (non active fight) -// 1 = can't Warp in Room (active fight) - -//TODO adding rand messages like "try hit it harder..." for wave's - - -001-2-36,32,36,0 script FightNPCName NPC_LUCAS,{ - - set $@NPCNAME$, "FightNPCName"; - set $@NPCNEXTNAME$, "Samantha"; - set $@MOB_ID, 1021; - set $@MOB_NAME$, "Dummy"; - set $@CURRENT_WAVE_LEVEL, 1; - set $@MAX_WAVES, 10; - - //Room and Mobspawn Coordinates - // TL BR - setarray $@MOB_SPAWN_COORDINATES, 24, 34, 31, 41; - setarray $@MAP_NAME$, "001-2-36"; - - set @roomPlayers, getmapusers($@MAP_NAME$); - - if(@roomPlayers > 1) - goto NotAlone; - - if ($@FightingIsActive == 1) - { - npctalk3 "You are not done now!"; - end; - } - - //call in Warp door if (1 = block) - set $@FightingIsActive, 1; - - if (!debug || !is_dev()) - goto start; - - //can be removed later! - menu - "get debug vars", debug_it, - "reset char var", resetVar, - "start training", -; - - -start: - if (FIGHT_TRAINING >= 1) - goto JobIsDone; - - getmapxy(.@map$, .@x, .@y, 0); - if (.@x < 24 || .@x > 32 || .@y < 33 || .@y > 43) - { - speech S_FIRST_BLANK_LINE, l("Please enter the combat zone on the left."); - close; - } - - setcells "001-2-36", 33, 35, 33, 38, 1, "fence"; - initnpctimer; - setnpctimer 0; - startnpctimer; - - npctalk3 l("Let's begin"); - end; - - -//cancel all actions, the Player needs to be alone in this Room -NotAlone: - npctalk3 "You dont feel so great with audience!"; - set $@FightingIsActive, 0; - end; - - -//If a Spawned Mob gets Killed -OnTrainingMobDead: - if ($@CURRENT_WAVE_LEVEL == $@MAX_WAVES ) - goto FinishedTraining; - - set $@CURRENT_WAVE_LEVEL, $@CURRENT_WAVE_LEVEL + 1; - setnpctimer 0; - startnpctimer; - end; - - -SpawnMonster: - if ( $@FightingIsActive == 1 ) - { - if ($@CURRENT_WAVE_LEVEL == $@MAX_WAVES) - { - npctalk "Last Wave!", $@NPCNAME$; - } - else - { - npctalk "Wave " + $@CURRENT_WAVE_LEVEL + "!", $@NPCNAME$; - } - - areamonster "001-2-36", $@MOB_SPAWN_COORDINATES[0], $@MOB_SPAWN_COORDINATES[1], $@MOB_SPAWN_COORDINATES[2], $@MOB_SPAWN_COORDINATES[3], $@MOB_NAME$, $@MOB_ID, 1, $@NPCNAME$ + "::OnTrainingMobDead"; - stopnpctimer; - setnpctimer 0; - } - else - { - set $@CURRENT_WAVE_LEVEL, 0; - } - stopnpctimer; - setnpctimer 0; - end; - - -//15 Secounds Waiting (Regeneration for fightRoom) -OnTimer5000: - goto SpawnMonster; - - -FinishedTraining: - //... TODO - - npctalk "Con. u finished it...", $@NPCNAME$; - stopnpctimer; - setnpctimer 0; - set $@CURRENT_WAVE_LEVEL, 0; - delcells "fence"; - if (FIGHT_TRAINING >= 1) - end; - set FIGHT_TRAINING, 1; - end; - -JobIsDone: - mes "Well done, you should talk to \"" + $@NPCNEXTNAME$ + "\"..."; - close; - - -// ----- DEBUG START ! ----- - -debug_it: - mes "DEBUG INFO"; - mes "- CharVariable:FIGHT_TRAINING "+ FIGHT_TRAINING; - mes "- maxWaves "+ $@MAX_WAVES; - mes "- currentWave "+ $@CURRENT_WAVE_LEVEL; - mes "- npcName "+ $@NPCNAME$; - mes "- mobName "+ $@MOB_NAME$; - mes "- mobID "+ $@MOB_ID; - close; - -resetVar: - set FIGHT_TRAINING , 0; -// ----- DEBUG END ! ----- - - -OnInit: - end; - -} diff --git a/npc/001-2-37/_import.txt b/npc/001-2-37/_import.txt index 05315d64..03162e19 100644 --- a/npc/001-2-37/_import.txt +++ b/npc/001-2-37/_import.txt @@ -1,4 +1,4 @@ -// Map 001-2-37: unnamed +// Map 001-2-37: Legion West Wing // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/001-2-37/_savepoints.txt", "npc/001-2-37/_warps.txt", diff --git a/npc/001-2-37/_savepoints.txt b/npc/001-2-37/_savepoints.txt index cd68fab2..30d7a797 100644 --- a/npc/001-2-37/_savepoints.txt +++ b/npc/001-2-37/_savepoints.txt @@ -1,5 +1,5 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-37: unnamed saves +// Map 001-2-37: Legion West Wing saves 001-2-37,25,41,0 script #save_001-2-37_25_41 NPC_SAVE_POINT,0,0,{ savepointparticle .map$, .x, .y, NO_INN; close; diff --git a/npc/001-2-37/_warps.txt b/npc/001-2-37/_warps.txt index f6997b5f..dabc5285 100644 --- a/npc/001-2-37/_warps.txt +++ b/npc/001-2-37/_warps.txt @@ -1,4 +1,4 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-37: unnamed warps +// Map 001-2-37: Legion West Wing warps 001-2-37,37,28,0 warp #001-2-37_37_28 0,0,001-2-33,24,30 001-2-37,37,33,0 warp #001-2-37_37_33 0,0,001-2-39,24,33 diff --git a/npc/001-2-38/_import.txt b/npc/001-2-38/_import.txt index e60aa3f9..63d2a402 100644 --- a/npc/001-2-38/_import.txt +++ b/npc/001-2-38/_import.txt @@ -1,4 +1,4 @@ -// Map 001-2-38: unnamed +// Map 001-2-38: Legion East Wing // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/001-2-38/_savepoints.txt", "npc/001-2-38/_warps.txt", diff --git a/npc/001-2-38/_savepoints.txt b/npc/001-2-38/_savepoints.txt index d4e4db2c..59be0f59 100644 --- a/npc/001-2-38/_savepoints.txt +++ b/npc/001-2-38/_savepoints.txt @@ -1,5 +1,5 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-38: unnamed saves +// Map 001-2-38: Legion East Wing saves 001-2-38,25,41,0 script #save_001-2-38_25_41 NPC_SAVE_POINT,0,0,{ savepointparticle .map$, .x, .y, NO_INN; close; diff --git a/npc/001-2-38/_warps.txt b/npc/001-2-38/_warps.txt index 9139345a..53e119b5 100644 --- a/npc/001-2-38/_warps.txt +++ b/npc/001-2-38/_warps.txt @@ -1,4 +1,4 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-38: unnamed warps +// Map 001-2-38: Legion East Wing warps 001-2-38,23,28,0 warp #001-2-38_23_28 0,0,001-2-33,44,30 001-2-38,23,33,0 warp #001-2-38_23_33 0,0,001-2-39,44,33 diff --git a/npc/001-2-39/_import.txt b/npc/001-2-39/_import.txt index 8ceee767..f3a2043a 100644 --- a/npc/001-2-39/_import.txt +++ b/npc/001-2-39/_import.txt @@ -1,4 +1,4 @@ -// Map 001-2-39: unnamed +// Map 001-2-39: Legion Command Room // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/001-2-39/_warps.txt", "npc/001-2-39/mapflags.txt", diff --git a/npc/001-2-39/_warps.txt b/npc/001-2-39/_warps.txt index 527acae5..1a25cfd3 100644 --- a/npc/001-2-39/_warps.txt +++ b/npc/001-2-39/_warps.txt @@ -1,4 +1,4 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-39: unnamed warps +// Map 001-2-39: Legion Command Room warps 001-2-39,45,33,0 warp #001-2-39_45_33 0,0,001-2-38,24,33 001-2-39,23,33,0 warp #001-2-39_23_33 0,0,001-2-37,36,33 diff --git a/npc/001-2-39/qanon.txt b/npc/001-2-39/qanon.txt index 150362c9..3a917ba9 100644 --- a/npc/001-2-39/qanon.txt +++ b/npc/001-2-39/qanon.txt @@ -4,15 +4,85 @@ // Reid // Description: // Artis's Legion of Aemil leader. +// Variables: +// Artis_Legion_Progress +// Values: +// 5 Sent by Lozerk. +// 6 Train forever (Cannot resume legion, must see brotherhood first) +// Technically, Q'Anon wants to see if player will recover his memory. +// After all, player memories might have something important. +// 7 Arrived at Hurnscald (This means we can resume legion) 001-2-39,34,41,0 script Q'Anon NPC_Q_ANON,{ + function legionState; + function notaMember; + .@q=getq(Artis_Legion_Progress); mesn; mesq lg("It's been a while, girl!", "It's been a while, boy!"); + next; + if (.@q < 5) + notaMember(); - goto L_Close; + select + rif(.@q == 5, l("Lozerk told me to talk to you and join the legion.")), + l("Thanks, sir Q'Anon."); + mes ""; + switch (@menu) + { + case 1: + legionState(); + break; + case 2: + mesn; + mesq lg("Make me proud, girl.", "Make me proud, boy."); + break; + } + close; -L_Close: +function notaMember { + mesn; + mesq col(l("*ahem*"), 9) + " " + l("Heh, did you saw me at the port? No?"); + next; + mesn; + mesq l("This is how good we Legion Members are. I was informed of your arrival way before you left Drasil Island."); + next; + mesn; + mesq l("I usually would not care, but it is not every day a complete stranger arrives at Artis."); + next; + mesn; + mesq l("You're welcome to stay here as long as you wish. Just don't do anything stupid, like a riot, for example."); close; + return; +} + +function legionState { + mesn; + mesq l("Oh? And do you think you have what it takes to be a proud Legion Member?"); + next; + mesn; + mesq lg("Listen, kid. Being a legion member is not a joke."); + next; + mesn; + mesq l("Hmm, why don't you go train a little more? We have several training rooms here."); + next; + mesn; + mesq l("Yes, I am authorizing you to use them as you deem fit, until you get stronger."); + next; + mesn; + mesq l("Also, build a reputation with the Legion. Talk to everyone. Help everyone. Prove me your worth!"); + next; + mesn; + mesq l("Only after you prove yourself, you may join our ranks as a proud member! Hahah!"); + setq Artis_Legion_Progress, 6; + // So, we probably should use Clan System for the major guilds. + // I guess major guilds are: Legion, Brotherhood + // minor guilds: Merchants, Thieves and Mages. + + // It would be the commands below: + // join_clan(CLAN_LEGION); + // clan_leave(); + return; +} OnInit: .sex = G_MALE; diff --git a/npc/001-2-40/trozz.txt b/npc/001-2-40/trozz.txt index df76c26f..5cb02840 100644 --- a/npc/001-2-40/trozz.txt +++ b/npc/001-2-40/trozz.txt @@ -5,17 +5,63 @@ // Chief of the Legion of Aemil of the city of Artis. 001-2-40,36,46,0 script Trozz#001-2-40 NPC_HUMAN_MALE_CHIEF_ARTIS_LEGION,{ + function Bureaucracy; + function Dueling; mesn; - mesq l("Hi."); + mesq l("Hi. I am Trozz, and I am the chief of legion training in Artis."); + next; + mesn; + mesq l("If you want to challenge someone for a friendly match, you are at the right place."); + next; + do + { + select + l("That's everything, thanks."), + l("I'm looking to have some paperwork fixed."), + l("How can I challenge someone for a match?"); + mes ""; + switch (@menu) { + case 1: + goodbye(); + break; + case 2: + Bureaucracy(); + break; + case 3: + Dueling(); + break; + } + } while (@menu != 1); + close; - goto L_Close; +function Bureaucracy { + mesn; + mesq l("If you need to deal with more bureaucratic stuff, go talk to Q'Anon. He is the boss here."); + next; + mesn; + mesq l("You can find him upstairs. Go left, then go right, and you'll find him."); + next; + return; +} -L_Close: - close; +function Dueling { + mesn; + mesq l("First, you need to use %s to enter in duel mode.", b("@duel")); + next; + mesn; + mesq l("Then, to challenge a player, you'll use \"%s <player_name>\".", b("@invite")); + next; + mesn; + mesq l("If you were invited to the duel instead, you can use %s or %s.", b("@accept"), b("@reject")); + next; + mesn; + mesq l("You can exit duel mode with %s. You'll also leave it by death.", b("@leave")); + next; + return; +} OnInit: .sex = G_MALE; .distance = 4; end; } - diff --git a/npc/001-2-41/edouard.txt b/npc/001-2-41/edouard.txt index f93d2042..2a3fd4cc 100644 --- a/npc/001-2-41/edouard.txt +++ b/npc/001-2-41/edouard.txt @@ -131,6 +131,7 @@ OnChair: 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?"), + l("How about changing my gender?"), l("What's your story again?"), l("I'm fine for now, thank you."); @@ -142,19 +143,25 @@ OnChair: case 2: BarberChangeStyle; speech S_FIRST_BLANK_LINE | S_LAST_NEXT, - l("Enjoy your new style."); + 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("I hope you like this color."), l("Anything else?"); break; case 4: - tellStory; + BarberChangeGender(); + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("You look fantastic."), + l("Anything else?"); break; case 5: + tellStory; + break; + case 6: speech S_FIRST_BLANK_LINE | S_LAST_NEXT, l("Feel free to come visit me another time."); diff --git a/npc/001-2-5/tutorial.txt b/npc/001-2-5/tutorial.txt index c7205221..8576db0f 100644 --- a/npc/001-2-5/tutorial.txt +++ b/npc/001-2-5/tutorial.txt @@ -3,384 +3,259 @@ // Ernando <ernando.quirino@hotmail.com> // Lunovox <rui.gravata@gmail.com> // Jesusalva <supremo@brasil.byethost22.com> +// Toams // Objective: Complete Tutorial about Evol/Hercules mechanics // License: GPL v3 001-2-5,34,32,0 script #EvolTutorial NPC_NO_SPRITE,{ -OnRemoteHelp: - function TutorialMenu; - function Manaplus; - function ExplicaGrama; - function Monstros; - function Quests; - function Status; - function NPC; - function Magica; - function Regras; - function Temporada; - function Experiencia; - function ExplicaBagagem; - function ExplicaTrade; - function ExplicaBatalha; - function ExplicaDialogo; - function Estilo; - function Comandos; - function Teclado; + function read_book { - mesc lg("This book contains the knowledge collected by ukars about how the world works."); - next; - TutorialMenu(); + setnpcdialogtitle l(.book_name$); -function TutorialMenu { - do - { - mesn strcharinfo(0); - select - l("I wanted info about how to play."), - l("How do I make money?"), - l("Monsters."), - l("Quests."), - l("Status."), - l("NPCs."), - l("Magic."), - l("Rules."), - l("Weather & Seasons."), - l("Experience."), - l("No, thanks!"); - mes ""; - switch (@menu) { - case 1: - Manaplus(); break; - case 2: - ExplicaGrama(); break; - case 3: - Monstros(); break; - case 4: - Quests(); break; - case 5: - Status(); break; - case 6: - NPC(); break; - case 7: - Magica(); break; - case 8: - Regras(); break; - case 9: - Temporada(); break; - case 10: - Experiencia(); break; - default: - close(); break; - } + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("This book contains the knowledge collected by ukars about how the world works."); - // Here we can repeat stuff - } while (true); - return; -} + @menu = 0; // reset for the rif -function Manaplus { - do - { - mesc l("What do you want to learn more about?"); - next; - mesn strcharinfo(0); - select - l("How I see my items?"), - l("How trade with other players?"), - l("How hunt monsters?"), - l("How talk with someone?"), - l("Styles."), - l("Commands."), - l("Shortcuts."), - l("I changed my mind."); - mes ""; - switch (@menu) { - case 1: - ExplicaBagagem(); break; - case 2: - ExplicaTrade(); break; - case 3: - ExplicaBatalha(); break; - case 4: - ExplicaDialogo(); break; - case 5: - Estilo(); break; - case 6: - Comandos(); break; - case 7: - Teclado(); break; - // case 8 is on the while condition - } + do + { + narrator S_NO_NPC_NAME, + l("Please select a chapter:"); - } while (@menu != 8); - return; -} + mes ""; -// Anything below this line is copy-pasted from SG:ManaBird, a TMW-BR clone -// It was translated by Google and therefore may have bad terms about ManaPlus interface. -// The data was then adapted by Moubootaur Legends and might have features NYI in Evol + select + rif(@menu == 1, "► ") + l("Ch 1 — How to make money."), + rif(@menu == 2, "► ") + l("Ch 2 — Everything about monsters."), + rif(@menu == 3, "► ") + l("Ch 3 — Quests."), + rif(@menu == 4, "► ") + l("Ch 4 — Status."), + rif(@menu == 5, "► ") + l("Ch 5 — NPC's."), + rif(@menu == 6, "► ") + l("Ch 6 — Magic."), + rif(@menu == 7, "► ") + l("Ch 7 — Rules."), + rif(@menu == 8, "► ") + l("Ch 8 — Weather & Seasons."), + rif(@menu == 9, "► ") + l("Ch 9 — Experience."), + rif(@menu == 10, "► ") + l("Ch 10 — How I see my items?"), + rif(@menu == 11, "► ") + l("Ch 11 — How trade with other players?"), + rif(@menu == 12, "► ") + l("Ch 12 — How hunt monsters?"), + rif(@menu == 13, "► ") + l("Ch 13 — How talk with someone?"), + rif(@menu == 14, "► ") + l("Ch 14 — Change your appearing."), + rif(@menu == 15, "► ") + l("Ch 15 — Commands."), + rif(@menu == 16, "► ") + l("Ch 16 — Shortcuts."); + + switch (@menu) { + case 1: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Merchants like to buy body parts of killed monsters and animals because they can make items and equipment."), + l("Some others also like to buy them to keep as trophies. Either way, you can make some money with that."), + l("You must find someone willing to buy, they usually will buy almost anything you have, even items which cannot be replaced, so be careful."), + l("You must \"add\" the items you plan on selling, and then press \"sell\" to confirm. You'll have this time to review."), + l("Some, but not all, from the rare or non-replaceable items will have a warning when you try to sell them."), + l("You can also make money %s. Nobody pays better than people in need of help.", b(l("by doing quests"))); + break; + case 2: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Monsters are everywhere. They're a plague we're trying to get rid of."), + l("There are three types of monsters: the aggressive, the neutral, and the collaborative."), + l("Aggressors always know when they are in danger! Therefore, they are always on standby, attacking anyone who appears ahead."), + l("Neutral monsters do not have such a sense of danger."), + l("They will not attack anyone unless they are attacked first."), + l("Normally, collaborative monsters behave like neutral monsters. Unless someone of the same species is in danger, at which point they all take an aggressive stance against the aggressor."), + l("It's always good to see if you have a lot of them around before you think about attacking one!"), + l("Also, most monsters get enraged and will attack whoever is closest to them, regardless of anything else."), + l("Not all monsters will do this, but most will. So if you see a monster running after a player and you stand in the way..."), + l("...It'll most likely attack you, instead."), + l("One last thing to keep in mind... If you are surrounded, you'll suffer an agility and defense penalty."), + l("But if you and other players surrounds the monster instead, they'll suffer the same penalties!"), + l("Any boss which was previously unhittable, can be hit with appropriate number of attackers."); + break; + case 3: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("There are people in the world who need help!"), + l("Most of these people will not think twice before giving a nice reward to anyone who helps them."), + l("So be nice and help people along the way!"), + l("Usually, they'll have an exclamation mark over their heads. But some quests are hidden, so talk to people and have fun!"); + break; + case 4: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("People vary greatly in the amount of strength, agility, dexterity, intelligence, vitality and luck."), + l("%s helps you carry more items and also gives you a more forceful blow, but ends up not being very interesting if you focus on weapons that use projectiles, such as the bow.", b(l("Strength"))), + l("Greater %s allows you to attack faster and has a greater chance of evading attacks.", b(l("agility"))), + l("Your %s determines your ability to hit monsters and is valuable to players who prefer weapons that use projectiles.", b(l("dexterity"))), + l("%s determines how many blows you can take before you die. It also affects status effects, like poison.", b(l("Vitality"))), + l("%s is very useful for alchemy and magic, but nowadays there are few opportunities to use it.", b(l("Intelligence"))), + l("Your %s determines several small things, including critical attacks, but DOES NOT affect drop rates.", b(l("luck"))), + l("A critical hit deals added damage and disregards defense. A critical always hit, although it can be blocked just fine."), + l("On a side note, more defense is always good, but the damage won't decrease on the same rate that defense raises."), + l("Also note that if you are in overweight, your natural regen will halt. 90% in weight, and you won't be able to attack."), + l("I recommend that you train your agility a great deal, since most monsters out there aren't really amazing at hitting you."), + l("For now do not take too much time to work on your intelligence, after all, magic use is very restricted nowadays."), + l("You can allocate point on those attributes every time you level up."),l("There's also a job level, which produces green sparkles when you level it."), + l("Job Level and certain equips can affect your status. You'll see the modifiers with a + sign."), + l("Do note that Job Level gives you skill points, and the status bonuses are really minor."); + break; + case 5: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("NPC's or non-playable characters are characters that are always in the game, offering a wide variety of reactions, from a simple friendly conversation to a desperate request for help."), + l("%s People usually doesn't shout, they talk. Because this, if you are too far, an NPC won't hear you.",b(l("IMPORTANT:"))), + l("When this is the case, you should get closer to the NPC, until they hear you."), l("If you are above the NPC and they still doesn't hear you, this mean they are deaf - you should report this!"); + break; + case 6: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Magic was banned for lore reasons? Seriously, after the mana war, only small tricks are allowed."), + l("It was heard about some adventurers whom obtained and use advanced magic, but that is still seen with bad eyes."); + break; + case 7: + mes ""; + callfunc "GameRules"; + break; + case 8: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + /* + // TODO: Implement Day/Night Cycle + mes l("First of, there's a day/night cycle on the game."); + if (is_night()) + mes l("It's currently night, that's why Candor is dark."); + else + mes l("It's currently day, but when night falls, Candor will become darker."); + next; + mes l("During night, the monsters usually respawn faster. That can be a problem with aggressive monsters."); + mes l("I also hear fisherman likes to fish at night. They say the catch is bigger, if you understand me."); + next; + */ + /* + // TODO: Implement Weather Cycle + mes l("There's also weather, meaning it can rain, snow, or even happen a sandstorm. They are usually cosmetic, but..."); + mes l("...who knows if there isn't a secret in that?"); + next; + */ + /* + // TODO: Implement Season Cycle + mes l("Besides this, there is Seasons. You know, summer, autumn, winter and spring."); + mes l("Each season unlocks a set of quests and drops which can only be obtained on the season."); + next; + mes l("Think on Season Quests as a yearly quest which you have three months to do."); + mes l("We follow north hemisphere seasons in case you're wondering."); + next; + */ + // We commented everything so we need something here + l("There is no day/night, weather, or season cycle in TMW yet."); + break; + case 9: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Experience can be gained by completing quests and killing monsters. When you accumulate enough experience, you'll level up!"), + l("Each level up will buff your base stats, and give you stats points to allocate."), + l("There's also a job level, which produces green sparkles when you level it."), + l("Job Level and certain equips can affect your status. You'll see the modifiers with a + sign."); + /* + // TODO: Evol doesn't have experience per mob level adjustment yet, nor have @monsterinfo for all players + mes l("Also, you'll get more experience by killing monsters stronger than you, and less experience by killing monsters weaker than you."); + mes l("You can find out the monster strength by using \"@monsterinfo <English Monster Name>\". Check the level in it!"); + next; + */ + break; + case 10: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("You can see all your equipment by pressing the F3 key."), + l("To equip or unequip an item, select it and press the 'Equip' or 'Unequip' button. You can not 'Equip' or 'Unequip' when talking to someone."), + l("Dress up! Do not walk without clothes! Always wear your items! They leave you less vulnerable to attacks and stronger to defeat your opponents."), + /* + // TODO: Evol doesn't have equipment set bonuses yet + mes b(l("Remember that some equipment sets will give you hidden stat bonuses! So dress yourself in a fashion way, if possible!")); + next; + */ + l("To discard an item you no longer want, select it and press the 'Discard' button. Generic items can be discarded or sold."), + l("Some special items cannot be traded, discarded, nor sold. With a right click, you can also protect normal items as if they were special ones."), + l("There are three types of items."), + l("Those for consumption, equipment and generics."), + l("Items for consumption, like potions, can only be used once."), + l("Once used, they will disappear from your inventory."), + l("Equippable items are armour, weapons and accessories."), + l("They can be equipped to make your look more interesting or to improve some of its features."), + l("Generic items are used for different purposes. In creating other items, to swap and sell, to collect, etc."); + break; + case 11: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Press the '###keyTrade;' key to ignore or accept business proposals. You and the other citizen who want to negotiate need to be in the configuration that accepts negotiations. if your configuration is 'Ignoring business proposals', then you will not receive the warning from any citizen wanting to negotiate with you, and you will not be able to initiate negotiations."), + l("To negotiate with other citizens, you should click the second mouse button on some other citizen who is accepting negotiations, and select the 'Negotiation' option from the menu that will appear."), + l("After you have confirmed the negotiation, a window with a vertical split will appear. The left side are the items you intend to offer in trading. The right side are the items that the other citizen intends to offer in trading."), + l("Open your inventory window (###keyWindowInventory; key) next to the trading window. Select an item you want to offer, and then press the Add button. To add money to the negotiation, enter the amount you will offer and press the Change button."), + l("When you have added all the items and money you want, press the 'Propose Trade' button. The other citizen must also press the 'Propose Trade' button."), + l("If the proposal is not convenient for you, just close the trading window to cancel the exchange of items and money. But if both press the 'Accept Negotiation' button, then the marketing will be finished."), + l("Remember! You're trading things, not lending/borrowing them. You are solely responsible for everything you own."); + break; + case 12: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Note down. To hunt a target you must click the primary mouse button on it. Avoid fighting monsters or citizens much stronger than you. %s", b(l("You will lose experience if you are defeated."))), + l("Within the cities is a place safe enough not to be attacked by another person (except during wars). But outside of them there are some places where the citizen can be attacked by enemies from other realms, or even by someone from the same realm."), + l("There are some stones scattered around the world that mark your point of return in case of defeats. Some ship chests may also serve as a return point. You can also select some beds in case of defeats."), + l("Almost all creatures drop useful items when defeated. To get the dropped item press the '###keyPickup;' key next to the item or click the primary button on the item."), + l("To focus on a creature, press the '###keyTargetMonster;' key. To focus on another citizen, press the '###keyTargetPlayer;' key. To attack the focused target press the '###keyAttack;' key or click the primary button on the creature."), + l("To focus on an NPC, press the '###keyTargetNPC;' key. To talk to him press the '###keyTalk;' key."), + l("To defocus or stop attacking, press Shift + A."), + l("You can, however, use '###keyTargetAttack;' to auto-select a monster and attack them. This usually also collects drops, but press '###keyPickup;' to be sure."); + break; + case 13: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("To display the dialog box with other citizens, press the '###keyWindowChat;' key."), + l("To speak in public select the 'General' tab. It serves to talk to people who are appearing on your screen."), + l("To speak privately with someone, click the second mouse button on the citizen and select the 'Whisper' option."), + l("In order to enter a message press the '###keyChat;' key, this will display the white box of typing. Type your message there and press '###keyChat;' again to send your speech."), + l("To speak privately to a friend who is not appearing on your screen, type the command '%s' and press '###keyChat;'. This command will open a long-distance dialog that has the name of who you want to talk to. Select this new tab and send your message through it.",b(l("/q [Player Name] "))), + l("And by last, to speak to everyone online, besides whoever might be idling on IRC, select the '#irc' tab."), + l("But be careful: do not scream by using a lot of capital letters, do not repeat yourself over and over, and above all DO NOT SPAM, or you may be severely penalized."); + break; + case 14: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("NPC stylists will cut your hair!"), + l("They are known to use a revolutionary hair growth formula."), + l("You will be amased by all the colors of hair dye they have."); + break; + case 15: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("You can execute commands by typing them in the chat window. They start with a '/' or '@' followed by the name of the command."), + l("%s clears the text box.", b("/clear")), + l("%s %s allows you to send a private message to the player. if [name] contains spaces, it must be enclosed in quotation marks.", b("/whisper"),l("[name]")), + l("%s displays amount of currently connected players.", b("/who")), + l("%s shows the number of people in the neighbourhood.", b("/present")), + l("%s shows the name of the map you are in.", b("/where")), + l("%s explains how to use all client commands.", b("/help")), + l("%s lists even more advanced commands, but some of them can only be used by admins or GM's.", b("@commands")), + l("%s will help when the client starts lagging. If you see an attack but no monsters, that's the cause.", b("@resync")), + l("%s allows you to change game language, anytime, anywhere.", b("@lang")), + l("%s will tell you all the rules once again.", b("@rules")), + //mes l("@toevent will warp you to event island, if an event is happening, of course."); + //mes l("@discord allows you to setup Discord integration settings."); + //mes l("@ucp allows you to manage your account, eg. recover lost email."); + //next; + //mes l("@resyncall is the more powerful version of @resync. It'll reload everything, even the clouds if needed."); + l("%s and %s will show this informative and absurdely big tutorial book." ,b("@info"),b("@tutorial")); + break; + case 16: + narrator S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("There are many key combinations, press F1 to see a short list of them!"); + break; + } + + } while (true); + end; + } + +OnShelfUse: + if (openbookshelf()) + read_book; + close; + +OnUse: + if (openbook()) + read_book; + close; -function ExplicaGrama { - mes l("Merchants like to buy body parts of killed monsters and animals because they can make items and equipment."); - next; - mes l("Some others also like to buy them to keep as trophies. Either way, you can make some money with that."); - next; - mes l("You must find someone willing to buy, they usually will buy almost anything you have, even items which cannot be replaced, so be careful."); - next; - mes l("You must \"add\" the items you plan on selling, and then press \"sell\" to confirm. You'll have this time to review."); - mes l("Some, but not all, from the rare or non-replaceable items will have a warning when you try to sell them."); - next; - mes l("You can also make money ##Bdoing quests##b. Nobody pays better than people in need of help."); - next; - return; -} -function ExplicaBagagem { - mes l("You can see all your equipment by pressing the F3 key."); - next; - mes l("To equip or unequip an item, select it and press the 'Equip' or 'Unequip' button. You can not 'Equip' or 'Unequip' when talking to someone."); - next; - mes l("Dress up! Do not walk without clothes! Always wear your items! They leave you less vulnerable to attacks and stronger to defeat your opponents."); - next; - /* - // TODO: Evol doesn't have equipment set bonuses yet - mes "##B"+l("Remember that some equipment sets will give you hidden stat bonuses! So dress yourself in a fashion way, if possible!")+"##b"; - next; - */ - mes l("To discard an item you no longer want, select it and press the 'Discard' button. Generic items can be discarded or sold."); - mes l("Some special items cannot be traded, discarded, nor sold. With a right click, you can also protect normal items as if they were special ones."); - next; - mes l("There are three types of items."); - mes l("Those for consumption, equipment and generics."); - next; - mes l("Items for consumption, like potions, can only be used once."); - mes l("Once used, they will disappear from your inventory."); - next; - mes l("Equippable items are armour, weapons and accessories."); - mes l("They can be equipped to make your look more interesting or to improve some of its features."); - next; - mes l("Generic items are used for different purposes. In creating other items, to swap and sell, to collect, etc."); - next; - return; -} -function ExplicaTrade { - mes l("Press the 'R' key to ignore or accept business proposals. You and the other citizen who want to negotiate need to be in the configuration that accepts negotiations. if your configuration is 'Ignoring business proposals', then you will not receive the warning from any citizen wanting to negotiate with you, and you will not be able to initiate negotiations."); - next; - mes l("To negotiate with other citizens, you should click the second mouse button on some other citizen who is accepting negotiations, and select the 'Negotiation' option from the menu that will appear."); - next; - mes l("After you have confirmed the negotiation, a window with a vertical split will appear. The left side are the items you intend to offer in trading. The right side are the items that the other citizen intends to offer in trading."); - next; - mes l("Open your inventory window (F3 key) next to the trading window. Select an item you want to offer, and then press the Add button. To add money to the negotiation, enter the amount you will offer and press the Change button."); - next; - mes l("When you have added all the items and money you want, press the 'Propose Business' button. The other citizen must also press the 'Propose Business' button."); - next; - mes l("if the proposal is not convenient for you, just close the trading window to cancel the exchange of items and money. But if both press the 'Accept Negotiation' button, then the marketing will be finished."); - next; - mes l("Remember! You're trading things, not lending/borrowing them. You are solely responsible for everything you own."); - next; - return; -} -// TODO: We have over nine instructions here. You usually can only memorise from three to five at a time! -function ExplicaBatalha { - mes l("Note down. To hunt a target you must click the primary mouse button on it. Avoid fighting monsters or citizens much stronger than you. ##BYou will lose experience if you are defeated.##b"); - next; - mes l("Within the cities is a place safe enough not to be attacked by another person (except during wars). But outside of them there are some places where the citizen can be attacked by enemies from other realms, or even by someone from the same realm."); - next; - mes l("There are some stones scattered around the world that mark your point of return in case of defeats. Some ship chests may also serve as a return point. You can also select some beds in case of defeats."); - next; - mes l("Almost all creatures drop useful items when defeated. To get the dropped item press the 'Z' key next to the item or click the primary button on the item."); - next; - mes l("To focus on a creature, press the 'A' key. To focus on another citizen, press the 'Q' key. To attack the focused target press the 'X' key or click the primary button on the creature."); - next; - mes l("To focus on an NPC, press the 'N' key. To talk to him press the 'T' key."); - next; - mes l("To defocus or stop attacking, press Shift + A."); - next; - mes l("You can, however, use ##BCtrl##b to auto-select a monster and attack them. This usually also collects drops, but press Z to be sure."); - next; - return; -} -function ExplicaDialogo { - mes l("To display the dialog box with other citizens, press the F7 key."); - next; - mes l("To speak in public select the 'General' tab. It serves to talk to people who are appearing on your screen."); - next; - mes l("To speak privately with someone, click the second mouse button on the citizen and select the 'Whisper' option."); - next; - mes l("In order to enter a message press the 'Enter' key, this will display the white box of typing. Type your message there and press 'Enter' again to send your speech."); - next; - mes l("To speak privately to a friend who is not appearing on your screen, type the command '##B /q Citizen Name ##b' and press 'Enter'. This command will open a long-distance dialog that has the name of who you want to talk to. Select this new tab and send your message through it."); - next; - //mes l("And by last, to speak to everyone online, besides whoever might be idling on Discord, select the '#world' tab."); - mes l("And by last, to speak to everyone online, besides whoever might be idling on IRC, select the '#irc' tab."); - next; - mes l("But be careful: do not scream when using a lot of capital letters, and do not keep repeating the lines, and above all DO NOT SPAM, or you may be severely penalized."); - next; - return; -} -function Monstros { - mes l("Monsters are everywhere. They're a plague we're trying to get rid of."); - next; - mes l("There are three types of monsters: the aggressive, the neutral, and the collaborative."); - next; - mes l("Aggressors always know when they are in danger! Therefore, they are always on standby, attacking anyone who appears ahead."); - next; - mes l("Neutral monsters do not have such a sense of danger."); - mes l("They will not attack anyone unless they are attacked first."); - next; - mes l("Normally, collaborative behave like neutral monsters. Unless some partner of the same species is in danger, at which point they all take an aggressive stance against the aggressor."); - mes l("It's always good to see if you have a lot of them around before you think about attacking one!"); - next; - mes "\""+l("Also, most monsters get enraged and will attack whoever is closest to them, regardless of anything else."); - mes l("Not all monsters will do this, but most will. So if you see a monster running after a player and you stand in the way..."); - mes l("...It'll most likely attack you, instead.")+"\""; - next; - mes l("One last thing to keep in mind... If you are surrounded, you'll suffer an agility and defense penalty."); - mes l("But if you and other players surrounds the monster instead, they'll suffer the same penalties!"); - mes l("Any boss which was previously unhittable, can be hit with appropriate number of attackers."); - next; - return; -} -function Estilo { - mes l("NPC stylists will cut your hair!"); - mes l("They are known to use a revolutionary hair growth formula."); - next; - return; -} -function Quests { - mes l("There are people in the world who need help!"); - mes l("Most of these people will not think twice before giving a nice reward to anyone who helps them."); - mes l("So be nice and help people along the way!"); - next; - mes l("Usually, they'll have an exclamation mark over their heads. But some quests are hidden, so talk to people and have fun!"); - next; - return; -} -function NPC { - mes l("NPCs(Non Playable Characters) or non-playable characters are characters that are always in the game, offering a wide variety of reactions, from a simple friendly conversation to a desperate request for help."); - next; - mes l("##BIMPORTANT:##b People usually doesn't shout, they talk. Because this, if you are too far, an NPC won't hear you."); - mes l("When this is the case, you should get closer to the NPC, until they hear you."); - mes l("If you are above the NPC and they still doesn't hear you, this mean they are deaf - you should report this!"); - next; - return; -} -function Comandos { - mes l("/ clear clears the text box."); - mes l("/ whisper [name] allows you to send a private message to the player. if [name] contains spaces, it must be enclosed in quotation marks."); - //mes l("/who mostra o número de jogadores conectados no momento."); - mes l("/ present shows the number of people in the neighbourhood."); - mes l("/ where shows the name of the map you are in."); - mes l("/ help explains how to use all client commands."); - mes l("@commands lists even more advanced commands, but you can't use all of them."); - next; - mes l("@resync will help when the client starts lagging. If you see an attack but no monsters, that's the cause."); - //mes l("@lang allows you to change game language, anytime, anywhere."); - mes l("@rules will tell you all the rules once again."); - //mes l("@toevent will warp you to event island, if an event is happening, of course."); - //mes l("@discord allows you to setup Discord integration settings."); - //mes l("@ucp allows you to manage your account, eg. recover lost email."); - //next; - //mes l("@resyncall is the more powerful version of @resync. It'll reload everything, even the clouds if needed."); - mes l("@info and @tutorial will show this informative and absurdely big tutorial book."); - next; - return; -} -function Status { - mes l("People vary greatly in the amount of strength, agility, dexterity, intelligence, vitality and luck."); - next; - mes l("@@ helps you carry more items and also gives you a more forceful blow, but ends up not being very interesting if you focus on weapons that use projectiles, such as the bow.", b(l("Strength"))); - mes l("Greater @@ allows you to attack faster and has a greater chance of evading attacks.", b(l("agility"))); - mes l("Your @@ determines your ability to hit monsters and is valuable to players who prefer weapons that use projectiles.", b(l("dexterity"))); - next; - mes l("@@ determines how many blows you can take before you die. It also affects status effects, like poison.", b(l("Vitality"))); - mes l("@@ is very useful for alchemy and magic, but nowadays there are few opportunities to use it.", b(l("Intelligence"))); - //mes l("Your @@ determines several small things, including critical attacks and, limited to a certain extent, affect drop rates.", b(l("luck"))); - mes l("Your @@ determines several small things, including critical attacks, but DOES NOT affect drop rates.", b(l("luck"))); - next; - mes l("A critical hit deals added damage and disregards defense. A critical always hit, although it can be blocked just fine."); - mes l("On a side note, more defense is always good, but the damage won't decrease on the same rate that defense raises."); - mes l("Also note that if you are in overweight, your natural regen will halt. 90% in weight, and you won't be able to attack."); - next; - mes l("I recommend that you train your agility a great deal, since most monsters out there aren't really amazing at hitting you."); - mes l("For now do not take too much time to work on your intelligence, after all, magic use is very restricted nowadays."); - next; - mes l("You can allocate point on those attributes every time you level up."); - mes l("There's also a job level, which produces green sparkles when you level it."); - mes l("Job Level and certain equips can affect your status. You'll see the modifiers with a + sign."); - mes l("Do note that Job Level gives you skill points, and the status bonuses are really minor."); - next; - return; -} -function Magica { - mes l("Magic was banned for lore reasons? Seriously, after the mana war, only small tricks are allowed."); - next; - mes l("It was heard about some adventurers whom obtained and use advanced magic, but that is still seen with bad eyes."); - next; - return; -} -function Teclado { - mes l("There are many key combinations, press F1 to see a short list of them!"); - next; - return; -} -function Temporada { - /* - // TODO: Implement Day/Night Cycle - mes l("First of, there's a day/night cycle on the game."); - if (is_night()) - mes l("It's currently night, that's why Candor is dark."); - else - mes l("It's currently day, but when night falls, Candor will become darker."); - next; - mes l("During night, the monsters usually respawn faster. That can be a problem with aggressive monsters."); - mes l("I also hear fisherman likes to fish at night. They say the catch is bigger, if you understand me."); - next; - */ - /* - // TODO: Implement Weather Cycle - mes l("There's also weather, meaning it can rain, snow, or even happen a sandstorm. They are usually cosmetic, but..."); - mes l("...who knows if there isn't a secret in that?"); - next; - */ - /* - // TODO: Implement Season Cycle - mes l("Besides this, there is Seasons. You know, summer, autumn, winter and spring."); - mes l("Each season unlocks a set of quests and drops which can only be obtained on the season."); - next; - mes l("Think on Season Quests as a yearly quest which you have three months to do."); - mes l("We follow north hemisphere seasons in case you're wondering."); - next; - */ - // We commented everything so we need something here - mes l("There is no day/night, weather, or season cycle in Evol... yet."); - next; - return; -} -function Experiencia { - mes l("Experience can be gained by completing quests and killing monsters. When you accumulate enough experience, you'll level up!"); - next; - mes l("Each level up will buff your base stats, and give you stats points to allocate. However, there is Job Level."); - next; - mes l("There's also a job level, which produces green sparkles when you level it."); - mes l("Job Level and certain equips can affect your status. You'll see the modifiers with a + sign."); - next; - /* - // TODO: Evol doesn't have experience per mob level adjustment yet, nor have @monsterinfo for all players - mes l("Also, you'll get more experience by killing monsters stronger than you, and less experience by killing monsters weaker than you."); - mes l("You can find out the monster strength by using \"@monsterinfo <English Monster Name>\". Check the level in it!"); - next; - */ - return; -} -function Regras { - callfunc "GameRules"; - next; - return; -} OnInit: - bindatcmd "info", "#EvolTutorial::OnRemoteHelp", 0, 0, 0; - bindatcmd "tutorial", "#EvolTutorial::OnRemoteHelp", 0, 0, 0; + .book_name$ = "Hitchiker's Guide To The Mana World"; + + bindatcmd "info", "#EvolTutorial::OnUse", 0, 0, 0; + bindatcmd "tutorial", "#EvolTutorial::OnUse", 0, 0, 0; .sex = G_OTHER; .distance = 1; diff --git a/npc/001-2-9/janus.txt b/npc/001-2-9/janus.txt index 616991a6..6d176615 100644 --- a/npc/001-2-9/janus.txt +++ b/npc/001-2-9/janus.txt @@ -31,7 +31,7 @@ } else { - Zeny = Zeny - .@party_price; + Zeny -= .@party_price; setq General_Janus, 2; skill NV_BASIC, 7, 0; @@ -61,7 +61,7 @@ else { inventoryplace GuildCertification, 1; - Zeny = Zeny - .@guild_price; + Zeny -= .@guild_price; setq General_Janus, 3; getitem GuildCertification, 1; diff --git a/npc/001-3-0/_warps.txt b/npc/001-3-0/_warps.txt index 65b56ff5..d192e4ef 100644 --- a/npc/001-3-0/_warps.txt +++ b/npc/001-3-0/_warps.txt @@ -3,6 +3,6 @@ 001-3-0,196,35,0 warp #001-3-0_196_35 0,0,001-1,197,35 001-3-0,172,41,0 warp #001-3-0_172_41 0,0,001-3-1,34,58 001-3-0,162,40,0 warp #001-3-0_162_40 0,0,001-3-1,23,57 -001-3-0,198,61,0 warp #001-3-0_198_61 0,0,001-1,199,61 +001-3-0,198,60,0 warp #001-3-0_198_60 0,0,001-1,199,61 001-3-0,152,55,0 warp #001-3-0_152_55 0,0,001-1,152,51 001-3-0,85,130,0 warp #001-3-0_85_130 0,0,001-1,86,130 diff --git a/npc/001-3-0/mundane.txt b/npc/001-3-0/mundane.txt index b653fa0d..01cde3e8 100644 --- a/npc/001-3-0/mundane.txt +++ b/npc/001-3-0/mundane.txt @@ -37,8 +37,8 @@ function rescue_mundane { speech(S_LAST_NEXT, - l("Scary... I am afraid of these Slimes, Rattos and Maggots... And worse, I am lost..."), - l("I already killed many strong monsters, but everyone has fears, right?!"), + l("Scary... I am afraid of all these Slimes, Rattos and Maggots... And worse, I am lost..."), + l("I was an archer of the Legion and shouldn't be scared of a few maggots, but everyone has fears, right?!"), l("My daughter is probably worried about me. Could you perhaps lead me out of here?")); switch (select(l("Yes, follow me!"), l("Not now. You see, I am also afraid of Slimes and Rattos!"))) @@ -49,17 +49,13 @@ case 2: speech(S_FIRST_BLANK_LINE, l("That's too bad... Although I think you're lying."), - l("If it is the latter, please take some courage and help me!")); + l("If so, please take some courage and help me!")); close; break; } .@ID=getcharid(0); .@MAP_NAME$="mona@"+str(.@ID); @MUNDANE_INSTID = instance_create("001-3-0@a"+(.@ID), getcharid(3), IOT_CHAR); - //debugmes "You are "+str(.@ID); - - //if (@MUNDANE_INSTID < 0) debugmes "Error: No instance ID"; - //debugmes "new instance id: " + str(@MUNDANE_INSTID); // XXX - Important Note - XXX // We currently have only FOUR chars to name the map. "001-3-0" or "mundane" have 7 chars, so that cannot be used. @@ -74,32 +70,35 @@ if (.@instanceMapName$ == "") { speech(0x0, l("Wait... You are that @@ from earlier, aren't you?", strcharinfo(0)), - l("If my memory serves me right, you died just before. Why don't you go out to buy better equipment?")); + l("If my memory serves me right, you were just defeated. Why don't you go out to buy better equipment?")); close; } // You have 5 minutes to complete the quest. This does not results in failure by itself, getq2 does that instance_set_timeout(300, 300, @MUNDANE_INSTID); instance_init(@MUNDANE_INSTID); - dispbottom(l("Mona Father's is right behind you. You have five minutes to bring him out of sewers!")); - - // Not sure if Green Slimes are exactly what we want here - and shouldn't it be "Slime"? (mind upper-case) - areamonster(.@MAP_NAME$, 119, 51, 162, 85, l("Green Slime"), slime, 3); - areamonster(.@MAP_NAME$, 190, 65, 193, 68, l("Ratto"), Ratto, 5); - areamonster(.@MAP_NAME$, 90, 67, 92, 72, l("Cave Maggot"), CaveMaggot, 3); - areamonster(.@MAP_NAME$, 99, 106, 102, 111, l("Green Slime"), slime, 3); - areamonster(.@MAP_NAME$, 115, 93, 115, 75, l("Green Slime"), slime, 3); - areamonster(.@MAP_NAME$, 120, 85, 7, 2, l("Little Green Slime"), slime-littleslime, 7); - areamonster(.@MAP_NAME$, 114, 65, 121, 68, l("Cave Maggot"), CaveMaggot, 5); - areamonster(.@MAP_NAME$, 137, 76, 130, 87, l("Spider"), Spider, 4); - areamonster(.@MAP_NAME$, 98, 92, 101, 94, l("Green Slime"), slime, 3); - setq ArtisQuests_MonaDad, 2; - warp(.@MAP_NAME$, 96,66); - addtimer(150, "Mundane::OnMove"); + dispbottom(l("Mona's father is right behind you. You have five minutes to bring him out of sewers!")); + + // Note: Difficulty is based on your level + .@BLVLBOOST=BaseLevel/10; + areamonster(.@MAP_NAME$, 119, 51, 162, 85, strmobinfo(1, Slime), Slime, 3+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 190, 65, 193, 68, strmobinfo(1, Ratto), Ratto, 5); + areamonster(.@MAP_NAME$, 90, 67, 92, 72, strmobinfo(1, CaveMaggot), CaveMaggot, 3+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 99, 106, 102, 111, strmobinfo(1, Slime), Slime, 3+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 115, 93, 115, 75, strmobinfo(1, Slime), Slime, 3+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 120, 85, 7, 2, strmobinfo(1, LittleSlime), LittleSlime, 7+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 114, 65, 121, 68, strmobinfo(1, CaveMaggot), CaveMaggot, 5+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 137, 76, 130, 87, strmobinfo(1, Spider), Spider, 4+.@BLVLBOOST); + areamonster(.@MAP_NAME$, 98, 92, 101, 94, strmobinfo(1, Slime), Slime, 3+.@BLVLBOOST); + + // Important temporary variables and move you accordingly + @MUNDANE_OLDX=.x; + @MUNDANE_OLDY=.y; + warp(.@MAP_NAME$, .x, .y); - // Important temporary variables - @MUNDANE_OLDX=96; - @MUNDANE_OLDY=66; + setq ArtisQuests_MonaDad, 2; + addtimer(150, instance_npcname(.name$, @MUNDANE_INSTID)+"::OnMove"); + updateSpotlight(true); close; } @@ -114,20 +113,6 @@ hello; end; -OnInit: - .sex = G_MALE; - .distance = 3; - end; - -/* -// If we are to use a fake-NPC (a monster which actually is a NPC, for example), -// We need to uncomment this code block. As we are moving the actual NPC, this is -// not needed (and harmful, too) -OnInstanceInit: - disablenpc(instance_npcname(.name$)); - end; -*/ - // This functions serves two major purposes: // 1- Move Mundane accordingly // 2- Be able to determine if you brought Mundane to exit or cheat (warp, etc.) @@ -143,23 +128,20 @@ OnMove: // This check shouldn't be needed but better safe than sorry if (.@m$ == "001-1") dispbottom l("Mundane ran straight home. He must be missing his daughter."); + else + dispbottom l("Mundane ran away, he did not trust the path you chose."); end; } // We actually won't move the NPC to your position, but to where you were last. // The NPC should not walk right in you because I thought it looks weird ingame. if (.@x == @MUNDANE_OLDX && .@y == @MUNDANE_OLDY) { - addtimer(150, "Mundane::OnMove"); + addtimer(150, instance_npcname(.name$, @MUNDANE_INSTID)+"::OnMove"); end; } // movenpc() will cause NPC to "jump" to player position. - // npcwalkto(x, y) could be better, but there are concerns about instance NPC, - // and the server code behind this function would need to be changed to actually - // use NPC walking animation (instead of just sliding it around). - // - // Mind the note about instance_npcname and about ignoring your position - // We should in future at least figure out the right direction to display too - movenpc(instance_npcname(.name$, @MUNDANE_INSTID), @MUNDANE_OLDX, @MUNDANE_OLDY); + // npcwalkto(x, y) will make it walk to your position. + npcwalkto @MUNDANE_OLDX, @MUNDANE_OLDY; // We now update the misleading @MUNDANE_OLD* variable with your current // position. @@ -167,10 +149,46 @@ OnMove: @MUNDANE_OLDY=.@y; // We must handle this every 150ms or so, which is player walk delay. // When you leave the map this timer will die. - addtimer(150, "Mundane::OnMove"); + addtimer(150, instance_npcname(.name$, @MUNDANE_INSTID)+"::OnMove"); + end; + +OnInit: + .sex = G_MALE; + .distance = 3; + .speed = 140; + +// Move Mundane every Sunday, Wednesday, and Friday +// to be less repetitive, and save also where it is +OnSun0000: +OnWed0000: +OnFri0000: + if (.begin) + delcells "MundaneProtection"; + + // Micksha may tweak this. + setarray .@valid_x, 96, 132, 150, 49; + setarray .@valid_y, 66, 86, 118, 47; + .@index=rand(0,getarraysize(.@valid_x)-1); + movenpc .name$, .@valid_x[.@index], .@valid_y[.@index]; + + // Create a 3x3 monster collision block over Mundane + setcells .map$, .x-3, .y-3, .x+3, .y+3, 6, "MundaneProtection"; + .begin=true; end; -OnPCDieEvent: +OnInstanceInit: + .speed = 140; // Double-sure + end; + +} + +function script MundaneLogout { + if (getq(ArtisQuests_MonaDad) != 2) end; + setq ArtisQuests_MonaDad, 1; + return; +} + +function script MundaneDeath { if (getq(ArtisQuests_MonaDad) != 2) end; setq ArtisQuests_MonaDad, 1; dispbottom l("What a pity! You've died."); @@ -179,15 +197,11 @@ OnPCDieEvent: // This will cause the NPC to "vanish", player is left to guess that he ran // back to where he originally was. // (ie. The NPC won't be fine without you if we have code to handle that). - getmapxy(.@m$, .@x, .@y, 0); - if (.@m$ ~= "mona@*") { + // NOTE: Maybe we could send the NPC running back to his original position? + // For future thought and testing by anyone interested. + if (strpos(getmap(), "mona@") >= 0) { disablenpc(instance_npcname(.name$, @MUNDANE_INSTID)); } - - // Uncommenting the code piece will warp you back to your savepoint. - // It's better to don't use this if the previous code works. - //recovery(); - //warp("Save",0,0); - end; + return; } diff --git a/npc/001-3-1/_warps.txt b/npc/001-3-1/_warps.txt index f0c3d747..4f79c590 100644 --- a/npc/001-3-1/_warps.txt +++ b/npc/001-3-1/_warps.txt @@ -2,3 +2,4 @@ // Map 001-3-1: Rivercave warps 001-3-1,24,58,0 warp #001-3-1_24_58 1,0,001-3-0,162,41 001-3-1,35,59,0 warp #001-3-1_35_59 1,0,001-3-0,172,42 +001-3-1,30,19,0 warp #001-3-1_30_19 0,0,001-3-2,30,116 diff --git a/npc/008-4-1/_import.txt b/npc/001-3-2/_import.txt index 0f706bbc..d427b6ed 100644 --- a/npc/008-4-1/_import.txt +++ b/npc/001-3-2/_import.txt @@ -1,5 +1,3 @@ -// Map 008-4-1: Cave Of Trials +// Map 001-3-2: Hideout // This file is generated automatically. All manually added changes will be removed when running the Converter. -"npc/008-4-1/_mobs.txt", -"npc/008-4-1/_warps.txt", -"npc/008-4-1/boss.txt", +"npc/001-3-2/_warps.txt", diff --git a/npc/001-2-35/_warps.txt b/npc/001-3-2/_warps.txt index d5939222..6b35b231 100644 --- a/npc/001-2-35/_warps.txt +++ b/npc/001-3-2/_warps.txt @@ -1,3 +1,3 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 001-2-35: unnamed warps -001-2-35,23,29,0 warp #001-2-35_23_29 0,0,001-2-32,32,29 +// Map 001-3-2: Hideout warps +001-3-2,30,117,0 warp #001-3-2_30_117 0,0,001-3-1,30,20 diff --git a/npc/008-1-1/_import.txt b/npc/008-1-1/_import.txt index be748cf8..4788f56c 100644 --- a/npc/008-1-1/_import.txt +++ b/npc/008-1-1/_import.txt @@ -4,3 +4,5 @@ "npc/008-1-1/_warps.txt", "npc/008-1-1/galimatia.txt", "npc/008-1-1/koga.txt", +"npc/008-1-1/morcant.txt", +"npc/008-1-1/sign.txt", diff --git a/npc/008-1-1/_mobs.txt b/npc/008-1-1/_mobs.txt index a34ccc1c..3bd8151c 100644 --- a/npc/008-1-1/_mobs.txt +++ b/npc/008-1-1/_mobs.txt @@ -2,7 +2,7 @@ // Map 008-1-1: Woodland mobs 008-1-1,173,86,25,5 monster Forest Maggot 1028,12,500,2500 008-1-1,132,56,7,5 monster Forest Maggot 1028,5,500,2500 -008-1-1,144,91,11,16 monster Butterfly 1032,8,10000,10000 +008-1-1,74,59,9,16 monster Butterfly 1032,4,20000,10000 008-1-1,63,73,11,5 monster Maggot 1026,7,500,10000 008-1-1,206,87,6,4 monster Mouboo 1023,3,30000,60000 008-1-1,131,45,0,0 monster Beehive 1056,1,30000,100000 @@ -17,50 +17,16 @@ 008-1-1,112,75,2,2 monster Pink Flower 1034,1,100,10000 008-1-1,110,46,3,2 monster Mauve Plant 1036,3,1000,2000 008-1-1,159,93,9,7 monster Silkworm 1040,4,3000,6000 -008-1-1,68,29,7,7 monster Mouboo 1023,3,30000,60000 +008-1-1,62,36,7,7 monster Mouboo 1023,3,30000,60000 008-1-1,126,45,0,0 monster Beehive 1056,1,30000,100000 008-1-1,121,45,0,0 monster Beehive 1056,1,30000,100000 -008-1-1,94,41,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,94,38,0,0 monster Blue Rose 1061,1,20000,15000 -008-1-1,94,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,93,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,93,39,0,0 monster Blue Rose 1061,1,20000,15000 -008-1-1,94,39,0,0 monster Blue Rose 1061,1,20000,15000 -008-1-1,95,39,0,0 monster Blue Rose 1061,1,20000,15000 -008-1-1,94,40,0,0 monster Blue Rose 1061,1,20000,15000 -008-1-1,93,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,94,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,94,43,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,95,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,96,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,96,41,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,97,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,97,43,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,98,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,99,42,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,99,41,0,0 monster Yellow Tulip 1059,1,20000,15000 -008-1-1,94,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,94,46,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,95,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,95,44,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,96,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,97,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,97,46,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,97,44,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,98,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,99,45,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,98,46,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,95,46,0,0 monster Red Rose 1062,1,20000,15000 -008-1-1,93,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,94,47,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,95,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,96,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,96,47,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,97,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,98,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,98,47,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,99,48,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,98,49,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,97,49,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,95,49,0,0 monster Yellow Rose 1060,1,20000,15000 -008-1-1,94,49,0,0 monster Yellow Rose 1060,1,20000,15000 +008-1-1,163,178,2,1 monster Red Rose 1062,1,50000,10000 +008-1-1,158,191,3,1 monster Yellow Rose 1060,1,20000,5000 +008-1-1,166,184,1,1 monster Blue Rose 1061,1,100000,20000 +008-1-1,137,86,11,16 monster Butterfly 1032,8,10000,10000 +008-1-1,75,41,14,4 monster Silkworm 1040,3,9000,6000 +008-1-1,122,75,8,4 monster Forest Maggot 1028,3,50000,2500 +008-1-1,96,45,1,0 monster Red Rose 1062,1,50000,10000 +008-1-1,97,47,2,0 monster Yellow Rose 1060,1,20000,5000 +008-1-1,99,45,0,0 monster Blue Rose 1061,1,100000,20000 +008-1-1,161,67,45,11 monster Moubi 1072,1,200000,1250000 diff --git a/npc/008-1-1/_warps.txt b/npc/008-1-1/_warps.txt index 56d9cc3f..db9189dc 100644 --- a/npc/008-1-1/_warps.txt +++ b/npc/008-1-1/_warps.txt @@ -2,3 +2,5 @@ // Map 008-1-1: Woodland warps 008-1-1,247,85,0 warp #008-1-1_247_85 0,1,008-1,21,85 008-1-1,202,47,0 warp #008-1-1_202_47 0,0,008-3-0,129,112 +008-1-1,51,57,0 warp #008-1-1_51_57 0,0,008-2-32,40,37 +008-1-1,181,198,0 warp #008-1-1_181_198 1,0,008-1-2,180,32 diff --git a/npc/008-1-1/koga.txt b/npc/008-1-1/koga.txt index f32e953c..e0a7c2b8 100644 --- a/npc/008-1-1/koga.txt +++ b/npc/008-1-1/koga.txt @@ -9,8 +9,15 @@ speech l("So, finally, we are here."), l("Do you want to go back to Artis? You really should be afraid of the Legion there, now that you have been here in Woodland. They somehow smell the odor of the Brotherhood."); - l("Better you stay here for a while. Come back when you are stronger."); - + next; + mesc l("Return to Artis?"); + if (askyesno() == ASK_YES) + { + closeclientdialog; + setmount 0; + warp "001-1", 199, 91; + dispbottom l("After a tiring, yet fast, travel by Koga, you arrive at @@.", l("Artis")); + } close; OnInit: diff --git a/npc/008-1-1/morcant.txt b/npc/008-1-1/morcant.txt new file mode 100644 index 00000000..afb35ad8 --- /dev/null +++ b/npc/008-1-1/morcant.txt @@ -0,0 +1,20 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Morcant the Captain, taking care on harbor issues. +// THIS IS A PLACEHOLDER! + +008-1-1,58,57,0 script Morcant NPC_MORCANT,{ + speech + l("Hello."), + l("My name is Morcant. I am a Captain, a bit bored since this harbor is not frequented much."), + l("I would like to offer you food and tell you stories, but.. have you ever heard of WildX? I won't need to say more, do I?"); + + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/008-1-1/sign.txt b/npc/008-1-1/sign.txt new file mode 100644 index 00000000..df554c2d --- /dev/null +++ b/npc/008-1-1/sign.txt @@ -0,0 +1,24 @@ +// Evol scripts. +// Authors: +// Micksha +// Description: +// Sign pillars in West Woodland. + +008-1-1,53,58,0 script Sign#008-1-1-merchant NPC_NO_SPRITE,{ + npctalkonce l("Merchant House"); + close; + +OnInit: + .distance = 1; + .sex = G_OTHER; + end; +} +008-1-1,157,87,0 script Sign#008-1-1-central NPC_NO_SPRITE,{ + npctalkonce l("Right: Hurnscald | Down: Swamp"); + close; + +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} diff --git a/npc/008-1-2/_import.txt b/npc/008-1-2/_import.txt new file mode 100644 index 00000000..f49fc06e --- /dev/null +++ b/npc/008-1-2/_import.txt @@ -0,0 +1,4 @@ +// Map 008-1-2: Swamp +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-1-2/_warps.txt", +"npc/008-1-2/sign.txt", diff --git a/npc/008-1-2/_warps.txt b/npc/008-1-2/_warps.txt new file mode 100644 index 00000000..c7ee0e45 --- /dev/null +++ b/npc/008-1-2/_warps.txt @@ -0,0 +1,4 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-1-2: Swamp warps +008-1-2,181,31,0 warp #008-1-2_181_31 1,0,008-1-1,180,197 +008-1-2,249,48,0 warp #008-1-2_249_48 0,0,008-1,23,216 diff --git a/npc/008-1-2/sign.txt b/npc/008-1-2/sign.txt new file mode 100644 index 00000000..73b011e3 --- /dev/null +++ b/npc/008-1-2/sign.txt @@ -0,0 +1,34 @@ +// Evol scripts. +// Authors: +// Micksha +// Description: +// Sign pillars in West Woodland. + +008-1-2,218,80,0 script Sign#008-1-2-northeast NPC_NO_SPRITE,{ + npctalkonce l("Up: West Woodland | Right: Dimond's Cove | Left: Sorentown"); + close; +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} + +008-1-2,145,80,0 script Sign#008-1-2-sorentown NPC_NO_SPRITE,{ + npctalkonce l("Left: Asphodel Moor | Right: All directions"); + close; + +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} + +008-1-2,39,192,0 script Sign#008-1-2-asphodel NPC_NO_SPRITE,{ + npctalkonce l("Down: Graveyard (under construction) | Up: All directions"); + close; + +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} diff --git a/npc/008-1/4144.txt b/npc/008-1/4144.txt new file mode 100644 index 00000000..953c2380 --- /dev/null +++ b/npc/008-1/4144.txt @@ -0,0 +1,91 @@ +// Evol Script +// Author: +// Jesusalva +// WildX +// Description: +// Andrei is not an human, according to studies conducted by TMW Team. +// He seems to be a highly advanced artificial intelligence. +// The fact that he was never seen contributes to this theory. +// Other members opinions: +// “4144 is a bot which sits on Hurnscald.” ~ Sagratha, 2016 + +008-1,246,105,0 script Andrei NPC_PLAYER,{ + function sittingBot; + function zealiteLore; + // TODO: Maybe we should use Karma here? For discussion + @is_billygates=(strcharinfo(0) == "WildX"); + speech + l("Hi."); + next; + do + { + select + l("Hello."), + l("Can I sit on you?"), + l("What are you doing?"); + mes ""; + switch (@menu) + { + case 1: + break; + case 2: + sittingBot(); + break; + case 3: + zealiteLore(); + break; + } + } while (@menu != 1); + + close; + + // Sitting Bot + function sittingBot + { + // This is just an easter egg (for now) + if (@is_billygates) { + speech S_LAST_NEXT, + l("Only if everyone agrees. You'll need to do a vote for that."), + l("Just kidding."); + } + + // Main dialog + speech S_LAST_NEXT, + l("I don't care, but there might be some adventurers and staff who might care."), + l("That's why you should always ask. This is good social etiqutte, you know?"), + l("Anyway, I would advise you to sit closer to the Soul Menhir, instead."); + return; + } + + // Zealite Info + function zealiteLore + { + speech S_LAST_NEXT, + l("I am maintaing Hurnscald's Soul Menhir in working conditions."), + l("Soul Menhirs are pieces of Zealite Ore, really needed to cast magic around here."), + l("They are not like your usual Terra Ore. Zealite is way more magical and powerful."), + l("This is why sometimes people try to steal shards from it... Poor fools."); + // Note: On TMW-BR, it is possible to "hit" Soul Menhirs for shards, which allow you to + // instantly teleport back to savepoint, even if lore-wise that was prohibted. + // This reference doesn't means it is actually possible to try that at all here. + return; + } + +// TODO: Replace with a good sprite and dye robes in green +OnInit: + .@npcId = getnpcid(.name$); + setunitdata(.@npcId, UDT_HEADTOP, FancyHat); // Wizard Hat + setunitdata(.@npcId, UDT_HEADMIDDLE, SilkRobe); + setunitdata(.@npcId, UDT_HEADBOTTOM, CottonGloves); + setunitdata(.@npcId, UDT_WEAPON, CottonBoots); + + // What is 4144's hair? He is always wearing his wizard hat + setunitdata(.@npcId, UDT_HAIRSTYLE, 7); + setunitdata(.@npcId, UDT_HAIRCOLOR, rand(1,20)); + npcsit; + + .sex = G_MALE; + .distance = 4; + end; +} + diff --git a/npc/008-1/_import.txt b/npc/008-1/_import.txt index 96d03c46..812a33fa 100644 --- a/npc/008-1/_import.txt +++ b/npc/008-1/_import.txt @@ -1,5 +1,6 @@ // Map 008-1: Hurnscald // This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-1/4144.txt", "npc/008-1/_mobs.txt", "npc/008-1/_warps.txt", "npc/008-1/auldsbel.txt", @@ -16,6 +17,7 @@ "npc/008-1/oscar.txt", "npc/008-1/sabine.txt", "npc/008-1/shop.txt", +"npc/008-1/sign.txt", "npc/008-1/snarfles.txt", "npc/008-1/soul-menhir.txt", "npc/008-1/voltain.txt", diff --git a/npc/008-1/_mobs.txt b/npc/008-1/_mobs.txt index 4a08a718..11f3e52a 100644 --- a/npc/008-1/_mobs.txt +++ b/npc/008-1/_mobs.txt @@ -58,7 +58,7 @@ 008-1,244,160,31,11 monster Mana Bug 1035,7,10000,10000 008-1,232,60,17,26 monster Mana Bug 1035,7,10000,10000 008-1,275,103,1,0 monster Clover Patch 1033,1,10000,30000 -008-1,278,153,1,0 monster Clover Patch 1033,1,10000,30000 +008-1,277,152,2,1 monster Clover Patch 1033,1,10000,30000 008-1,203,130,1,0 monster Clover Patch 1033,1,10000,30000 008-1,156,149,1,0 monster Clover Patch 1033,1,10000,30000 008-1,193,113,1,0 monster Clover Patch 1033,1,10000,30000 @@ -81,7 +81,7 @@ 008-1,68,167,14,9 monster Silkworm 1040,3,3000,6000 008-1,46,193,16,28 monster Grass Snake 1042,7,3000,12000 008-1,166,114,14,5 monster Spiky Mushroom 1049,2,3000,6000 -008-1,118,97,14,5 monster Spiky Mushroom 1049,2,3000,6000 +008-1,128,48,4,5 monster Bandit 1063,1,4000,11000 008-1,186,33,6,7 monster Spiky Mushroom 1049,4,3000,6000 008-1,84,77,4,2 monster Scorpion 1043,1,6000,12000 008-1,106,62,7,4 monster Mouboo 1023,1,30000,120000 @@ -99,3 +99,9 @@ 008-1,140,144,2,6 monster Mauve Plant 1036,3,1000,2000 008-1,192,147,3,2 monster Gamboge Plant 1038,2,1000,10000 008-1,197,136,2,5 monster Cobalt Plant 1039,2,1000,30000 +008-1,109,93,14,5 monster Spiky Mushroom 1049,2,3000,6000 +008-1,111,68,8,3 monster Robin Bandit 1064,2,8000,12000 +008-1,126,80,8,3 monster Bandit 1063,2,5500,8000 +008-1,122,44,4,7 monster Robin Bandit 1064,1,3000,8000 +008-1,89,116,7,6 monster Moubi 1072,1,10000000,1000000 +008-1,259,116,31,20 monster Maggot 1026,6,500,10000 diff --git a/npc/008-1/_warps.txt b/npc/008-1/_warps.txt index 9ca7640a..fad30de8 100644 --- a/npc/008-1/_warps.txt +++ b/npc/008-1/_warps.txt @@ -19,10 +19,15 @@ 008-1,151,80,0 warp #008-1_151_80 0,0,008-2-15,35,33 008-1,256,203,0 warp #008-1_256_203 0,0,008-2-20,25,31 008-1,128,138,0 warp #008-1_128_138 0,0,008-3-1,35,34 +008-1,250,23,0 warp #008-1_250_23 1,0,008-3-4,88,76 +008-1,283,26,0 warp #008-1_283_26 0,0,008-3-3,37,56 008-1,287,113,0 warp #008-1_287_113 0,0,008-2-8,26,28 008-1,252,211,0 warp #008-1_252_211 0,0,008-2-21,22,42 008-1,257,130,0 warp #008-1_257_130 0,0,008-2-28,25,31 008-1,233,131,0 warp #008-1_233_131 0,0,008-2-29,36,24 008-1,287,133,0 warp #008-1_287_133 0,0,008-2-30,52,39 008-1,20,85,0 warp #008-1_20_85 0,1,008-1-1,246,85 -008-1,165,171,0 warp #008-1_165_171 0,0,008-4-1,175,19 +008-1,165,171,0 warp #008-1_165_171 0,0,008-3-2,175,21 +008-1,289,125,0 warp #008-1_289_125 0,0,008-2-31,29,25 +008-1,22,216,0 warp #008-1_22_216 0,0,008-1-2,248,48 +008-1,109,82,0 warp #008-1_109_82 0,0,008-3-5,92,107 diff --git a/npc/008-1/milly.txt b/npc/008-1/milly.txt index 0ea17a1c..1ca72cee 100644 --- a/npc/008-1/milly.txt +++ b/npc/008-1/milly.txt @@ -25,6 +25,17 @@ // Description: // robberies in hurnscald +// Give player a Beanie Copter after 1,000,000 kills (server-wide) +function script GetBeanieCopter { + // Double-check against possible malpractices + if ($MONSTERS_KILLED % 1000000 == 0) { + announce(sprintf("Congratulations, \"%s\", on killing the %sth monster!.", strcharinfo(0), format_number($MONSTERS_KILLED)), bc_all); + getitem BeanieCopter, 1; + dispbottom l("How strange, this monster dropped a very rare hat!"); + } + return; +} + 008-1,282,114,0 script Milly NPC_GIRL_MILLY,{ // TODO: make the actual beanie copter quest after those are finished: diff --git a/npc/008-1/old-woman.txt b/npc/008-1/old-woman.txt index c6ca467b..5b97547b 100644 --- a/npc/008-1/old-woman.txt +++ b/npc/008-1/old-woman.txt @@ -28,8 +28,8 @@ 008-1,231,114,0 script Old Woman NPC_OLD_LADY,{ function is_inspector { - return (getequipcardid(EQI_HEAD_MID, 0) == NavyBlueCottonDye /*&& - getequipcardid(EQI_HEAD_LOW, 0) == NavyBlueCottonDye*/); // TODO / FIXME: remove the /* */ whenever we have cotton pants + return (getequipcardid(EQI_HEAD_MID, 0) == NavyBlueCottonDye && + getequipcardid(EQI_HEAD_LOW, 0) == NavyBlueCottonDye); } function oldwoman_ask { diff --git a/npc/008-1/shop.txt b/npc/008-1/shop.txt index f50912f2..a0b825ec 100644 --- a/npc/008-1/shop.txt +++ b/npc/008-1/shop.txt @@ -19,7 +19,6 @@ OnInit: sellitem ARedTulip, -1, 50; sellitem AWhiteTulip, -1, 50; sellitem AYellowTulip, -1, 50; - sellitem ABlueTulip, -1, 20; .sex = G_OTHER; .distance = 10; @@ -33,7 +32,6 @@ OnClock0000: restoreshopitem ARedTulip, 10; restoreshopitem AWhiteTulip, 10; restoreshopitem AYellowTulip, 10; - restoreshopitem ABlueTulip, 5; OnClock0800: restoreshopitem ARedRose, 10; restoreshopitem AWhiteRose, 10; @@ -42,7 +40,6 @@ OnClock0800: restoreshopitem ARedTulip, 10; restoreshopitem AWhiteTulip, 10; restoreshopitem AYellowTulip, 10; - restoreshopitem ABlueTulip, 5; OnClock1600: restoreshopitem ARedRose, 10; restoreshopitem AWhiteRose, 10; @@ -51,5 +48,4 @@ OnClock1600: restoreshopitem ARedTulip, 10; restoreshopitem AWhiteTulip, 10; restoreshopitem AYellowTulip, 10; - restoreshopitem ABlueTulip, 5; } diff --git a/npc/008-1/sign.txt b/npc/008-1/sign.txt new file mode 100644 index 00000000..17099ba4 --- /dev/null +++ b/npc/008-1/sign.txt @@ -0,0 +1,50 @@ +// Evol scripts. +// Authors: +// Micksha +// Description: +// Sign pillars in Hurnscald. + +008-1,142,105,0 script Sign#008-1-central NPC_NO_SPRITE,{ + npctalkonce l("Right: Hurnscald | Down: Dimond's Cove | Left: West Woodland | Up: Nivalis (under construction)"); + close; +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} + +008-1,126,160,0 script Sign#008-1-south NPC_NO_SPRITE,{ + npctalkonce l("Down: Dimond's Cove | Left: Swamp"); + close; +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} + +008-1,246,177,0 script Sign#008-1-southeast NPC_NO_SPRITE,{ + npctalkonce l("Left: Dimond's Cove | Up: Hurnscald | Right: Forsaken Inn"); + close; +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} + +008-1,251,104,0 script Sign#008-1-hurns NPC_NO_SPRITE,{ + npctalkonce l("Left: West Woodland | Up: North Mine | Right: Harbor | Down: other directions"); + close; +OnInit: + .distance = 2; + .sex = G_OTHER; + end; +} + +008-1,247,105,0 script Sign#008-1-4144 NPC_NO_SPRITE,{ + npctalkonce l("This place is dedicated to 4144, the alltime Hero."); + close; +OnInit: + .distance = 1; + .sex = G_OTHER; + end; +} diff --git a/npc/008-1/soul-menhir.txt b/npc/008-1/soul-menhir.txt index 3c295c92..2c57f0de 100644 --- a/npc/008-1/soul-menhir.txt +++ b/npc/008-1/soul-menhir.txt @@ -5,7 +5,11 @@ // place of power, mana refills faster when sitting nearby 008-1,252,111,0 script Soul Menhir#hurnscald NPC_NO_SPRITE,{ - + if (!@menhir_meditation_message) + { + dispbottom(l("You feel a strong magic aura. You want to sit near it and meditate.")); + @menhir_meditation_message=1; + } end; OnRefill: diff --git a/npc/008-2-2/melania.txt b/npc/008-2-2/melania.txt index bfd1e8be..cf02dc90 100644 --- a/npc/008-2-2/melania.txt +++ b/npc/008-2-2/melania.txt @@ -26,7 +26,7 @@ lodge_check(); } while (@menu != 2); - mesn; + speech S_FIRST_BLANK_LINE, l("I wish you a beautiful day."); close; @@ -89,7 +89,7 @@ else { emotion E_HAPPY; - Zeny = Zeny - .@price; + Zeny -= .@price; INN_REGISTER = .inn; PC_IS_DEAD = false; diff --git a/npc/008-2-2/melinda.txt b/npc/008-2-2/melinda.txt index 86f26e96..17127656 100644 --- a/npc/008-2-2/melinda.txt +++ b/npc/008-2-2/melinda.txt @@ -47,7 +47,7 @@ switch (select(l("Sure! [Don't tip]"), getinventorylist; if (@inventorylist_count == 100 && countitem("Beer") == 0) goto L_TooMany; - set Zeny, Zeny - 90; + Zeny -= 90; getitem Beer, 1; mes ""; mesn; @@ -59,7 +59,7 @@ switch (select(l("Sure! [Don't tip]"), getinventorylist; if (@inventorylist_count == 100 && countitem("Beer") == 0) goto L_TooMany; - set Zeny, Zeny - 95; + Zeny -= 95; getitem "Beer", 1; mes ""; mesn; @@ -71,7 +71,7 @@ switch (select(l("Sure! [Don't tip]"), getinventorylist; if (@inventorylist_count == 100 && countitem("Beer") == 0) goto L_TooMany; - set Zeny, Zeny - 100; + Zeny -= 100; getitem "Beer", 1; mes ""; mesn; diff --git a/npc/008-2-2/shop.txt b/npc/008-2-2/shop.txt index d0db9b67..d3699092 100644 --- a/npc/008-2-2/shop.txt +++ b/npc/008-2-2/shop.txt @@ -1,6 +1,7 @@ // Evol scripts. // Authors: // 4144 +// jesusalva // Reid // toams // Description: @@ -17,25 +18,17 @@ OnInit: sellitem Cheese, -1, 50; sellitem CherryCake, -1, 50; sellitem SmallHealing, -1, 50; + sellitem MaggotSlimePotion, -1, 50; .sex = G_OTHER; .distance = 10; end; +// FIXME Note: "20" doesn't means "restock 20 units". +// It means "restock if less than 20 units are being sold". +// Is this behavior intended? Seems like a bug. OnClock0000: - restoreshopitem Beer, 20; - restoreshopitem Bread, 20; - restoreshopitem RedPlushWine, 20; - restoreshopitem Cheese, 20; - restoreshopitem CherryCake, 20; - restoreshopitem SmallHealing, 20; OnClock0800: - restoreshopitem Beer, 20; - restoreshopitem Bread, 20; - restoreshopitem RedPlushWine, 20; - restoreshopitem Cheese, 20; - restoreshopitem CherryCake, 20; - restoreshopitem SmallHealing, 20; OnClock1600: restoreshopitem Beer, 20; restoreshopitem Bread, 20; @@ -43,4 +36,5 @@ OnClock1600: restoreshopitem Cheese, 20; restoreshopitem CherryCake, 20; restoreshopitem SmallHealing, 20; + restoreshopitem MaggotSlimePotion, 50; } diff --git a/npc/008-2-31/_import.txt b/npc/008-2-31/_import.txt new file mode 100644 index 00000000..7f013b3e --- /dev/null +++ b/npc/008-2-31/_import.txt @@ -0,0 +1,3 @@ +// Map 008-2-31: Kyttys Home +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-2-31/_warps.txt", diff --git a/npc/008-4-1/_warps.txt b/npc/008-2-31/_warps.txt index b1a26ad0..82846783 100644 --- a/npc/008-4-1/_warps.txt +++ b/npc/008-2-31/_warps.txt @@ -1,3 +1,3 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 008-4-1: Cave Of Trials warps -008-4-1,175,18,0 warp #008-4-1_175_18 2,0,008-1,165,170 +// Map 008-2-31: Kyttys Home warps +008-2-31,28,25,0 warp #008-2-31_28_25 0,0,008-1,288,125 diff --git a/npc/008-2-32/_import.txt b/npc/008-2-32/_import.txt new file mode 100644 index 00000000..ba8aa591 --- /dev/null +++ b/npc/008-2-32/_import.txt @@ -0,0 +1,4 @@ +// Map 008-2-32: Merchant House +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-2-32/_warps.txt", +"npc/008-2-32/thamas.txt", diff --git a/npc/008-2-32/_warps.txt b/npc/008-2-32/_warps.txt new file mode 100644 index 00000000..99f22bd8 --- /dev/null +++ b/npc/008-2-32/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-2-32: Merchant House warps +008-2-32,40,38,0 warp #008-2-32_40_38 0,0,008-1-1,51,58 diff --git a/npc/008-2-32/thamas.txt b/npc/008-2-32/thamas.txt new file mode 100644 index 00000000..f824493f --- /dev/null +++ b/npc/008-2-32/thamas.txt @@ -0,0 +1,20 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Thamas the soldier. +// THIS IS A PLACEHOLDER! + +008-2-32,36,31,0 script Thamas NPC_THAMAS,{ + speech + l("Hi there."), + l("I am a legion soldier who never talks much, until Jesusalva or WildX puts words in my mouth."), + l("Until then, let me be quiet. Talk to you later."); + + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/008-2-7/_import.txt b/npc/008-2-7/_import.txt index 4cb38df9..d3391d83 100644 --- a/npc/008-2-7/_import.txt +++ b/npc/008-2-7/_import.txt @@ -3,4 +3,6 @@ "npc/008-2-7/_savepoints.txt", "npc/008-2-7/_warps.txt", "npc/008-2-7/mapflags.txt", +"npc/008-2-7/shop.txt", +"npc/008-2-7/simon.txt", "npc/008-2-7/wyara.txt", diff --git a/npc/008-2-7/shop.txt b/npc/008-2-7/shop.txt new file mode 100644 index 00000000..30989eb3 --- /dev/null +++ b/npc/008-2-7/shop.txt @@ -0,0 +1,36 @@ +// Evol scripts. +// Authors: +// 4144 +// Micksha +// Reid +// toams +// Description: +// Simons Potion Shop. + +008-2-7,30,26,0 trader #Invisible008-2-7 NPC_HIDDEN,{ + +OnInit: + tradertype(NST_MARKET); + + sellitem SmallHealing, -1, 10; + sellitem MediumHealing, -1, 5; + sellitem SmallMana, -1, 10; + sellitem MediumMana, -1, 5; + sellitem ConcPotion, -1, 3; + sellitem IronPotion, -1, 3; + + .sex = G_OTHER; + .distance = 2; + end; + +OnClock0000: +OnClock0800: +OnClock1600: + restoreshopitem SmallHealing, 10; + restoreshopitem MediumHealing, 5; + restoreshopitem SmallMana, 10; + restoreshopitem MediumMana, 5; + restoreshopitem ConcPotion, 3; + restoreshopitem IronPotion, 3; + end; +} diff --git a/npc/008-2-7/simon.txt b/npc/008-2-7/simon.txt new file mode 100644 index 00000000..1b4ae071 --- /dev/null +++ b/npc/008-2-7/simon.txt @@ -0,0 +1,39 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Simon, Wyaras Apprentice. +// THIS IS A PLACEHOLDER! + +008-2-7,30,26,0 script Simon NPC_SIMON,{ + speech + l("Hi, I am Simon."), + l("I am Wyaras apprentice, helping her with selling her potions."), + l("I would prefer becoming a real Sorcerer one time. *sighs*"); + + switch (select(l("Potions? That sounds useful. What do you have?"), + l("Thats your problem, really."), + l("Becoming a Sorcerer? I want that too!"))) + { + case 1: + closeclientdialog; + shop "#Invisible008-2-7"; + close; + case 2: + speech S_FIRST_BLANK_LINE, + l("Leave me alone."); + close; + case 3: + speech S_FIRST_BLANK_LINE, + l("It needs so much training, but Wyara only leaves me here, standing and selling something instead of teaching me."); + close; + } + + + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/008-2-7/wyara.txt b/npc/008-2-7/wyara.txt index a875544a..502a5409 100644 --- a/npc/008-2-7/wyara.txt +++ b/npc/008-2-7/wyara.txt @@ -3,16 +3,79 @@ // Micksha // Description: // Wyara the witch. -// THIS IS A PLACEHOLDER! +// TODO: Buy or make plushroom potions +// TODO: Should she ask for a money comission when resetting status? 008-2-7,27,28,0 script Wyara#008-2-7 NPC_DARK_DRUID,{ + function confirmStatusReset; + function doStatusReset; speech l("What? Is there someone?"), l("Please, leave me alone. I have to pixel potions."), - lg("I will sell some when you return a bit later."); - + lg("I will sell some when you return a bit later."), + l("Unless you are interested in a status reset?"); + next; + do + { + select + l("I'm fine, thanks."), + l("I actually could use a status reset!"); + switch (@menu) { + case 2: + @plush_count = lognbaselvl(1, 10); + @plush_count = @plush_count*12/10; + if (confirmStatusReset()) + doStatusReset(); + break; + } + } while (@menu != 1); + // Note: There is some dark magic here, because confirmStatusReset() overrides @menu. close; +function confirmStatusReset { + mesn; + mesq l("Let me just have a quick look at you. Hm... I will need @@ @@s to reset your stats.", @plush_count, getitemlink(Plushroom)); + next; + mesn; + mesq l("Also, status point reset can't be undone. Do you really want this?"); + next; + if (askyesno() == ASK_YES) + { + if (countitem(Plushroom) >= @plush_count) + return 1; + mesn; + mesq l("Alright, but... You only have @@ @@, and I need @@ to do the status reset for you!", countitem(Plushroom), getitemlink(Plushroom), @plush_count); + } + return 0; +} + +function doStatusReset { + delitem Plushroom, @plush_count; + + .@wasSP = StatusPoint; + resetstatus; + + // Everything was done before dialog in case of forced disconnection + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Thank you."), + l("Now stand still... It should not take much time..."); + if (StatusPoint == .@wasSP) + { + speech + l("It seems that you have no status points to reset!"), + l("I'll return the plushroom to you, but please, do not waste my time."); + getitem Plushroom, @plush_count; + } + else + { + speech + l("Let's see... @@ of your status points have just been reset!", StatusPoint - .@wasSP), + l("Spend it wisely this time."), + lg("But you are welcome to reset your stats again if you bring me some more plushrooms!"); + } + return; +} + OnInit: .sex = G_FEMALE; .distance = 2; diff --git a/npc/008-3-0/_mobs.txt b/npc/008-3-0/_mobs.txt index f7062926..06015caf 100644 --- a/npc/008-3-0/_mobs.txt +++ b/npc/008-3-0/_mobs.txt @@ -1,7 +1,7 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. // Map 008-3-0: Rossy Cave mobs -008-3-0,83,62,21,7 monster Cave Maggot 1027,5,500,2000 -008-3-0,101,117,13,7 monster Cave Maggot 1027,5,500,2000 +008-3-0,30,113,7,14 monster Cave Maggot 1027,5,500,2000 +008-3-0,102,116,14,8 monster Cave Maggot 1027,5,500,2000 008-3-0,79,144,10,6 monster Cave Maggot 1027,7,500,2000 008-3-0,158,87,10,12 monster Cave Maggot 1027,7,500,2000 008-3-0,34,28,3,4 monster Poison Skull 1100,1,35000,60000 @@ -10,13 +10,74 @@ 008-3-0,128,146,5,3 monster Ratto 1005,4,35000,15000 008-3-0,120,61,5,3 monster Ratto 1005,4,35000,15000 008-3-0,138,64,10,7 monster Crafty 1018,10,1000,120000 -008-3-0,130,103,9,6 monster Crafty 1018,6,1000,120000 +008-3-0,129,102,11,6 monster Crafty 1018,6,1000,120000 008-3-0,67,114,10,2 monster Spider 1044,3,4000,8000 008-3-0,109,145,4,10 monster Spider 1044,5,4000,8000 008-3-0,68,84,3,7 monster Spider 1044,4,4000,8000 -008-3-0,83,166,0,0 monster Ruby Vein 1051,1,600000,60000 008-3-0,80,169,0,0 monster Diamond Vein 1045,1,600000,60000 -008-3-0,89,168,0,0 monster Emerald Vein 1052,1,600000,60000 -008-3-0,100,180,0,0 monster Topaz Vein 1054,1,600000,60000 -008-3-0,97,176,0,0 monster Sapphire Vein 1053,1,600000,60000 -008-3-0,94,180,0,0 monster Amethyst Vein 1055,1,600000,60000 +008-3-0,118,96,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,131,93,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-0,119,101,0,0 monster Gold Veinbloc 1070,1,600000,60000 +008-3-0,113,60,23,8 monster Cave Maggot 1027,7,500,2000 +008-3-0,199,68,8,9 monster Crafty 1018,5,1000,60000 +008-3-0,160,47,17,5 monster Crafty 1018,5,1000,120000 +008-3-0,119,200,20,4 monster Spider 1044,5,4000,8000 +008-3-0,34,193,11,9 monster Spider 1044,5,4000,8000 +008-3-0,26,115,5,17 monster Spider 1044,5,4000,8000 +008-3-0,82,60,21,7 monster Cave Maggot 1027,5,500,2000 +008-3-0,38,193,16,4 monster Cave Maggot 1027,5,500,2000 +008-3-0,114,199,12,3 monster Ratto 1005,4,35000,15000 +008-3-0,106,30,10,7 monster Crafty 1018,5,1000,120000 +008-3-0,78,128,11,21 monster Ratto 1005,4,35000,15000 +008-3-0,117,141,35,11 monster Crafty 1018,10,1000,120000 +008-3-0,117,101,18,11 monster Ratto 1005,7,35000,15000 +008-3-0,130,88,0,0 monster Ruby Vein 1051,1,600000,60000 +008-3-0,122,94,0,0 monster Ruby Vein 1051,1,600000,60000 +008-3-0,31,181,0,0 monster Sapphire Vein 1053,1,600000,60000 +008-3-0,31,198,0,0 monster Sapphire Vein 1053,1,600000,60000 +008-3-0,135,127,0,0 monster Topaz Vein 1054,1,600000,60000 +008-3-0,120,125,0,0 monster Topaz Vein 1054,1,600000,60000 +008-3-0,31,112,0,0 monster Amethyst Vein 1055,1,600000,60000 +008-3-0,24,123,0,0 monster Amethyst Vein 1055,1,600000,60000 +008-3-0,193,123,0,0 monster Emerald Vein 1052,1,600000,60000 +008-3-0,204,116,0,0 monster Emerald Vein 1052,1,600000,60000 +008-3-0,89,168,0,0 monster Diamond Vein 1045,1,600000,60000 +008-3-0,132,192,0,0 monster Sapphire Vein 1053,1,600000,60000 +008-3-0,39,174,0,0 monster Amethyst Vein 1055,1,600000,60000 +008-3-0,44,174,0,0 monster Topaz Vein 1054,1,600000,60000 +008-3-0,118,196,0,0 monster Emerald Vein 1052,1,600000,60000 +008-3-0,65,105,0,0 monster Diamond Vein 1045,1,600000,60000 +008-3-0,143,139,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,156,121,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,155,166,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,125,162,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,107,141,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,77,148,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,62,119,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-0,162,95,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-0,157,66,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-0,112,60,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-0,66,54,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-0,63,91,0,0 monster Gold Veinbloc 1070,1,600000,60000 +008-3-0,76,127,0,0 monster Gold Veinbloc 1070,1,600000,60000 +008-3-0,111,148,0,0 monster Gold Veinbloc 1070,1,600000,60000 +008-3-0,101,27,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,165,28,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,199,67,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,199,109,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,197,194,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,133,199,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,34,194,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,26,111,3,4 monster Poison Skull 1100,1,35000,60000 +008-3-0,88,48,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-0,100,49,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-0,130,44,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-0,67,47,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-0,124,94,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-0,158,60,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-0,56,53,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-0,55,98,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-0,62,103,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-0,69,125,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-0,62,153,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-0,96,145,0,0 monster Iron Vein 1047,1,600000,60000 diff --git a/npc/008-3-1/_mobs.txt b/npc/008-3-1/_mobs.txt index 8a09426c..b741a714 100644 --- a/npc/008-3-1/_mobs.txt +++ b/npc/008-3-1/_mobs.txt @@ -1,7 +1,7 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. // Map 008-3-1: Bat Cave mobs -008-3-1,42,35,7,5 monster Crafty 1018,10,1000,120000 -008-3-1,44,54,4,2 monster Crafty 1018,5,10000,75000 +008-3-1,42,35,7,5 monster Crafty 1018,7,1000,120000 +008-3-1,44,54,4,2 monster Crafty 1018,4,10000,75000 008-3-1,43,39,5,2 monster Spider 1044,1,4000,8000 008-3-1,46,53,5,2 monster Spider 1044,2,2000,7500 008-3-1,52,31,0,0 monster Iron Vein 1047,1,600000,60000 diff --git a/npc/008-3-2/_import.txt b/npc/008-3-2/_import.txt new file mode 100644 index 00000000..580a8f40 --- /dev/null +++ b/npc/008-3-2/_import.txt @@ -0,0 +1,5 @@ +// Map 008-3-2: Calamity Dungeon +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-3-2/_mobs.txt", +"npc/008-3-2/_warps.txt", +"npc/008-3-2/boss.txt", diff --git a/npc/008-3-2/_mobs.txt b/npc/008-3-2/_mobs.txt new file mode 100644 index 00000000..4c0dfbd0 --- /dev/null +++ b/npc/008-3-2/_mobs.txt @@ -0,0 +1,7 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-2: Calamity Dungeon mobs +008-3-2,106,73,73,63 monster Cave Maggot 1027,80,30000,2500 +008-3-2,136,71,47,50 monster Thief Slime 1105,35,50000,2500 +008-3-2,101,83,73,30 monster AngryCrafty 1103,60,50000,2500 +008-3-2,100,79,32,31 monster Black Scorpion 1104,14,45000,2500 +008-3-2,94,98,11,9 monster Green Slime 1024,4,500,2500 diff --git a/npc/008-3-2/_warps.txt b/npc/008-3-2/_warps.txt new file mode 100644 index 00000000..e69305bc --- /dev/null +++ b/npc/008-3-2/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-2: Calamity Dungeon warps +008-3-2,175,19,0 warp #008-3-2_175_19 2,0,008-1,165,170 diff --git a/npc/008-3-2/boss.txt b/npc/008-3-2/boss.txt new file mode 100644 index 00000000..5a296ce9 --- /dev/null +++ b/npc/008-3-2/boss.txt @@ -0,0 +1,65 @@ +// Evol Script +// Author: +// Jesusalva +// Description: +// Controls the boss on 008-3-2 and the Master Book Learning +// see npc/items/master_skillbook.txt for explanation about variables + +008-3-2,0,0,0 script #BossCtrl_008-3-2 NPC_HIDDEN,{ + end; + +// Test server: 15 minutes only +OnTimer900000: + if (!debug) + end; + +// Otherwise, respawn every hour +OnTimer3600000: + stopnpctimer; +OnInit: + $@MB_00832=0; + monster "008-3-2", 67, 30, strmobinfo(1, SpiderQueen), SpiderQueen, 1, "#BossCtrl_008-3-2::OnBossDeath"; + end; + +OnBossDeath: + initnpctimer; + // Only the party which defeated the boss can learn the skill + getmapxy(.@m$, .@x, .@y, 0); + .@party=getcharid(1); + if (.@party > 0) + { + $@MB_00832=.@party; + areatimer("008-3-2", .@x-15, .@y-15, .@x+15, .@y+15, 10, "#BossCtrl_008-3-2::OnBossCheck"); + mapannounce "008-3-2", "Boss deafeated by Party: " + getpartyname(.@party), bc_all; + } + else + { + $@MB_00832=-2; + areatimer("008-3-2", .@x-15, .@y-15, .@x+15, .@y+15, 10, "#BossCtrl_008-3-2::OnBossCheck"); + addtimer(20, "#BossCtrl_008-3-2::OnBegin"); + mapannounce "008-3-2", "Boss deafeated by: " + strcharinfo(0), bc_all; + } + end; + +OnBossCheck: + @mb_BossId=-1; + // TODO: Check if you really fought or was just lurking + // Check if party is correct + if (getcharid(1) != $@MB_00832) + end; +OnBegin: + @mb_BossId=SpiderQueen; + @mb_SkillId=TF_POISON; + @mb_ItemId=MagicFeather; // Placeholder + @mb_ItemAm=1; + addtimer(15000, "#BossCtrl_008-3-2::OnFinish"); + end; + +OnFinish: + @mb_BossId=0; + @mb_SkillId=0; + @mb_ItemId=0; + @mb_ItemAm=0; + end; + +} diff --git a/npc/008-3-3/_import.txt b/npc/008-3-3/_import.txt new file mode 100644 index 00000000..96cc09c9 --- /dev/null +++ b/npc/008-3-3/_import.txt @@ -0,0 +1,4 @@ +// Map 008-3-3: Bat Cave +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-3-3/_mobs.txt", +"npc/008-3-3/_warps.txt", diff --git a/npc/008-3-3/_mobs.txt b/npc/008-3-3/_mobs.txt new file mode 100644 index 00000000..4ff0ff2d --- /dev/null +++ b/npc/008-3-3/_mobs.txt @@ -0,0 +1,9 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-3: Obelisk Cave mobs +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-3: Bat Cave mobs +008-3-3,57,36,12,7 monster Crafty 1018,5,1000,120000 +008-3-3,31,43,4,5 monster Crafty 1018,3,1000,120000 +008-3-3,49,38,20,16 monster Cave Maggot 1027,12,500,2000 +008-3-3,60,49,5,3 monster Ratto 1005,2,35000,15000 +008-3-3,53,24,5,2 monster Ratto 1005,2,35000,15000 diff --git a/npc/008-3-3/_warps.txt b/npc/008-3-3/_warps.txt new file mode 100644 index 00000000..871c897c --- /dev/null +++ b/npc/008-3-3/_warps.txt @@ -0,0 +1,5 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-3: Obelisk Cave warps +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-3: Bat Cave warps +008-3-3,37,57,0 warp #008-3-3_37_57 1,0,008-1,283,27 diff --git a/npc/008-3-4/_import.txt b/npc/008-3-4/_import.txt new file mode 100644 index 00000000..e0815f43 --- /dev/null +++ b/npc/008-3-4/_import.txt @@ -0,0 +1,4 @@ +// Map 008-3-4: North Mine +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-3-4/_mobs.txt", +"npc/008-3-4/_warps.txt", diff --git a/npc/008-3-4/_mobs.txt b/npc/008-3-4/_mobs.txt new file mode 100644 index 00000000..db3cc108 --- /dev/null +++ b/npc/008-3-4/_mobs.txt @@ -0,0 +1,32 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-4: North Mine mobs +008-3-4,84,55,19,25 monster Cave Maggot 1027,15,2000,20000 +008-3-4,73,100,53,17 monster Cave Maggot 1027,10,1000,15000 +008-3-4,139,58,20,21 monster Cave Maggot 1027,5,5000,25000 +008-3-4,87,78,75,12 monster Crafty 1018,12,2500,35000 +008-3-4,89,79,21,35 monster Ratto 1005,18,5000,10000 +008-3-4,133,55,16,9 monster Spider 1044,1,4000,8000 +008-3-4,49,91,29,17 monster Black Scorpion 1104,4,4000,8000 +008-3-4,138,57,16,17 monster Spider 1044,3,4000,8000 +008-3-4,54,37,16,17 monster Spider 1044,3,4000,8000 +008-3-4,85,67,49,39 monster Thief Slime 1105,3,20000,100000 +008-3-4,82,42,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-4,74,51,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-4,104,41,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-4,62,61,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-4,128,71,0,0 monster Coal Veinbloc 1071,1,600000,60000 +008-3-4,118,46,0,0 monster Coal Vein 1048,1,600000,60000 +008-3-4,108,90,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-4,72,84,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-4,47,98,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-4,50,74,0,0 monster Iron Vein 1047,1,600000,60000 +008-3-4,135,53,0,0 monster Diamond Vein 1045,1,600000,60000 +008-3-4,43,96,0,0 monster Amethyst Vein 1055,1,600000,60000 +008-3-4,102,91,0,0 monster Topaz Vein 1054,1,600000,60000 +008-3-4,33,102,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-4,154,56,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-4,53,31,0,0 monster Gem Veinbloc 1069,1,600000,60000 +008-3-4,83,44,14,9 monster Red Slime 1074,5,10000,50000 +008-3-4,115,67,13,29 monster Red Slime 1074,4,10000,50000 +008-3-4,37,79,24,27 monster Yellow Slime 1073,4,10000,50000 +008-3-4,111,67,13,29 monster Red Slime 1074,8,20000,75000 diff --git a/npc/008-3-4/_warps.txt b/npc/008-3-4/_warps.txt new file mode 100644 index 00000000..d62d5fb5 --- /dev/null +++ b/npc/008-3-4/_warps.txt @@ -0,0 +1,5 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-4: North Mine warps +008-3-4,88,78,0 warp #008-3-4_88_78 0,0,008-1,249,24 +008-3-4,21,85,0 warp #008-3-4_21_85 0,2,008-3-5,157,72 +008-3-4,91,119,0 warp #008-3-4_91_119 3,0,008-3-6,62,22 diff --git a/npc/008-3-5/_import.txt b/npc/008-3-5/_import.txt new file mode 100644 index 00000000..55e17985 --- /dev/null +++ b/npc/008-3-5/_import.txt @@ -0,0 +1,4 @@ +// Map 008-3-5: Bandit Cave +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-3-5/_mobs.txt", +"npc/008-3-5/_warps.txt", diff --git a/npc/008-3-5/_mobs.txt b/npc/008-3-5/_mobs.txt new file mode 100644 index 00000000..de960072 --- /dev/null +++ b/npc/008-3-5/_mobs.txt @@ -0,0 +1,12 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-5: Bandit Cave mobs +008-3-5,87,83,22,16 monster Cave Maggot 1027,8,2000,20000 +008-3-5,79,68,54,12 monster Crafty 1018,12,2500,35000 +008-3-5,71,62,49,39 monster Thief Slime 1105,3,20000,100000 +008-3-5,90,70,13,29 monster Red Slime 1074,8,20000,75000 +008-3-5,79,82,21,15 monster Bandit 1063,3,2000,20000 +008-3-5,74,66,38,21 monster Snake 1075,3,10000,100000 +008-3-5,54,41,26,21 monster Robin Bandit 1064,2,2000,20000 +008-3-5,44,51,13,33 monster Cave Maggot 1027,7,2000,20000 +008-3-5,49,41,38,21 monster Bandit 1063,2,2000,20000 +008-3-5,133,72,24,9 monster Ratto 1005,6,5000,10000 diff --git a/npc/008-3-5/_warps.txt b/npc/008-3-5/_warps.txt new file mode 100644 index 00000000..be81f002 --- /dev/null +++ b/npc/008-3-5/_warps.txt @@ -0,0 +1,6 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-5: Bandit Cave warps +008-3-5,158,72,0 warp #008-3-5_158_72 0,2,008-3-4,22,85 +008-3-5,109,67,0 warp #008-3-5_109_67 0,2,008-3-5,101,68 +008-3-5,102,68,0 warp #008-3-5_102_68 0,2,008-3-5,110,67 +008-3-5,92,108,0 warp #008-3-5_92_108 0,0,008-1,109,83 diff --git a/npc/008-3-6/_import.txt b/npc/008-3-6/_import.txt new file mode 100644 index 00000000..41b51532 --- /dev/null +++ b/npc/008-3-6/_import.txt @@ -0,0 +1,4 @@ +// Map 008-3-6: Hurnscald Cave +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/008-3-6/_mobs.txt", +"npc/008-3-6/_warps.txt", diff --git a/npc/008-3-6/_mobs.txt b/npc/008-3-6/_mobs.txt new file mode 100644 index 00000000..91e614fe --- /dev/null +++ b/npc/008-3-6/_mobs.txt @@ -0,0 +1,11 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-6: Hurnscald Cave mobs +008-3-6,54,73,18,19 monster Red Slime 1074,5,10000,50000 +008-3-6,67,44,35,8 monster Yellow Slime 1073,3,10000,50000 +008-3-6,86,43,23,22 monster Red Slime 1074,4,10000,50000 +008-3-6,86,76,24,13 monster Yellow Slime 1073,4,10000,50000 +008-3-6,75,65,24,27 monster Cave Maggot 1027,8,2000,20000 +008-3-6,56,62,10,7 monster Ratto 1005,3,5000,10000 +008-3-6,71,77,10,7 monster Ratto 1005,3,5000,10000 +008-3-6,96,53,15,11 monster Ratto 1005,4,5000,10000 +008-3-6,95,63,15,21 monster Black Scorpion 1104,1,4000,8000 diff --git a/npc/008-3-6/_warps.txt b/npc/008-3-6/_warps.txt new file mode 100644 index 00000000..95dd673a --- /dev/null +++ b/npc/008-3-6/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 008-3-6: Hurnscald Cave warps +008-3-6,64,21,0 warp #008-3-6_64_21 3,0,008-3-4,90,118 diff --git a/npc/008-4-1/_mobs.txt b/npc/008-4-1/_mobs.txt deleted file mode 100644 index ad992a8d..00000000 --- a/npc/008-4-1/_mobs.txt +++ /dev/null @@ -1,7 +0,0 @@ -// This file is generated automatically. All manually added changes will be removed when running the Converter. -// Map 008-4-1: Cave Of Trials mobs -008-4-1,106,73,73,63 monster Cave Maggot 1027,80,30000,2500 -008-4-1,136,71,47,50 monster Thief Slime 1105,35,50000,2500 -008-4-1,101,83,73,30 monster AngryCrafty 1103,60,50000,2500 -008-4-1,100,79,32,31 monster Black Scorpion 1104,14,45000,2500 -008-4-1,94,98,11,9 monster Green Slime 1024,4,500,2500 diff --git a/npc/008-4-1/boss.txt b/npc/008-4-1/boss.txt deleted file mode 100644 index 17b04880..00000000 --- a/npc/008-4-1/boss.txt +++ /dev/null @@ -1,62 +0,0 @@ -// Evol Script -// Author: -// Jesusalva -// Description: -// Controls the boss on 008-4-1 and the Master Book Learning -// see npc/items/master_skillbook.txt for explanation about variables - -008-4-1,0,0,0 script #BossCtrl_008-4-1 NPC_HIDDEN,{ - end; - -// Test server: 15 minutes only -OnTimer900000: - if (!debug) - end; - -// Otherwise, respawn every hour -OnTimer3600000: - stopnpctimer; -OnInit: - $@MB_00841=0; - monster "008-4-1", 67, 30, strmobinfo(1, GameBalance), GameBalance, 1, "#BossCtrl_008-4-1::OnBossDeath"; - end; - -OnBossDeath: - initnpctimer; - // Only the party which defeated the boss can learn the skill - getmapxy(.@m$, .@x, .@y, 0); - .@party=getcharid(1); - if (.@party > 0) - { - $@MB_00841=.@party; - areatimer("008-4-1", .@x-15, .@y-15, .@x+15, .@y+15, 10, "#BossCtrl_008-4-1::OnBossCheck"); - mapannounce "008-4-1", "Boss deafeated by Party: " + getpartyname(.@party), bc_all; - } - else - { - addtimer(10, "#BossCtrl_008-4-1::OnBegin"); - mapannounce "008-4-1", "Boss deafeated by: " + strcharinfo(0), bc_all; - } - end; - -OnBossCheck: - // TODO: Check if you really fought or was just lurking - // Check if party is correct - if (getcharid(1) != $@MB_00841) - end; -OnBegin: - @mb_BossId=GameBalance; - @mb_SkillId=MG_COLDBOLT; - @mb_ItemId=Manana; // Placeholder - @mb_ItemAm=1; - addtimer(15000, "#BossCtrl_008-4-1::OnFinish"); - end; - -OnFinish: - @mb_BossId=0; - @mb_SkillId=0; - @mb_ItemId=0; - @mb_ItemAm=0; - end; - -} diff --git a/npc/012-1/_import.txt b/npc/012-1/_import.txt new file mode 100644 index 00000000..363a65e9 --- /dev/null +++ b/npc/012-1/_import.txt @@ -0,0 +1,15 @@ +// Map 012-1: Candor Island +// 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/aahna.txt", +"npc/012-1/aidan.txt", +"npc/012-1/ayasha.txt", +"npc/012-1/crasmande.txt", +"npc/012-1/hasan.txt", +"npc/012-1/ishi.txt", +"npc/012-1/kaan.txt", +"npc/012-1/liana.txt", +"npc/012-1/prawors.txt", +"npc/012-1/vincent.txt", +"npc/012-1/zegas.txt", diff --git a/npc/012-1/_mobs.txt b/npc/012-1/_mobs.txt new file mode 100644 index 00000000..d00ebaaa --- /dev/null +++ b/npc/012-1/_mobs.txt @@ -0,0 +1,8 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-1: Candor Island mobs +012-1,77,78,30,25 monster Mana Bug 1035,8,10000,10000 +012-1,62,95,19,15 monster Butterfly 1032,5,100000,10000 +012-1,78,103,38,12 monster Maggot 1026,10,500,10000 +012-1,57,57,20,14 monster Grass Snake 1042,5,3000,12000 +012-1,106,42,16,7 monster Scorpion 1043,4,15000,50000 +012-1,115,123,14,7 monster Scorpion 1043,4,15000,40000 diff --git a/npc/012-1/_warps.txt b/npc/012-1/_warps.txt new file mode 100644 index 00000000..e7f8b126 --- /dev/null +++ b/npc/012-1/_warps.txt @@ -0,0 +1,9 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-1: Candor Island warps +012-1,38,115,0 warp #012-1_38_115 0,0,012-2-1,52,38 +012-1,50,104,0 warp #012-1_50_104 0,0,012-2-6,26,38 +012-1,65,105,0 warp #012-1_65_105 0,0,012-2-5,29,43 +012-1,64,95,0 warp #012-1_64_95 0,0,012-2-3,33,36 +012-1,51,93,0 warp #012-1_51_93 0,0,012-2-7,30,34 +012-1,57,101,0 warp #012-1_57_101 0,0,012-2-4,31,43 +012-1,49,67,0 warp #012-1_49_67 1,0,012-3-1,37,40 diff --git a/npc/012-1/aahna.txt b/npc/012-1/aahna.txt new file mode 100644 index 00000000..12df0924 --- /dev/null +++ b/npc/012-1/aahna.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Aahna, a low quality NPC ;) +// THIS IS A PLACEHOLDER! + +012-1,99,64,0 script Aahna NPC_AAHNA,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/012-1/aidan.txt b/npc/012-1/aidan.txt new file mode 100644 index 00000000..1ff47e45 --- /dev/null +++ b/npc/012-1/aidan.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Aidan, a dawdler in Candor. +// THIS IS A PLACEHOLDER! + +012-1,52,114,0 script Aidan NPC_AIDAN,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-1/ayasha.txt b/npc/012-1/ayasha.txt new file mode 100644 index 00000000..623954f6 --- /dev/null +++ b/npc/012-1/ayasha.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Vincent, a child at the Candor beach. +// THIS IS A PLACEHOLDER! + +012-1,65,111,0 script Ayasha NPC_AYASHA,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/012-1/crasmande.txt b/npc/012-1/crasmande.txt new file mode 100644 index 00000000..5aef9e89 --- /dev/null +++ b/npc/012-1/crasmande.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Crasmande, the scared man. +// THIS IS A PLACEHOLDER! + +012-1,41,44,0 script Crasmande NPC_CRASMANDE,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-1/hasan.txt b/npc/012-1/hasan.txt new file mode 100644 index 00000000..52a53f18 --- /dev/null +++ b/npc/012-1/hasan.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Hasan, the bad guy. +// THIS IS A PLACEHOLDER! + +012-1,39,44,0 script Hasan NPC_HASAN,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-1/ishi.txt b/npc/012-1/ishi.txt new file mode 100644 index 00000000..c2390d4a --- /dev/null +++ b/npc/012-1/ishi.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Ishi, former trade-in for monster points. +// THIS IS A PLACEHOLDER! + +012-1,53,114,0 script Ishi NPC_ISHI,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/012-1/kaan.txt b/npc/012-1/kaan.txt new file mode 100644 index 00000000..4ce8b3ab --- /dev/null +++ b/npc/012-1/kaan.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Kaan, a guy good for nothing. +// THIS IS A PLACEHOLDER! + +012-1,53,110,0 script Kaan NPC_KAAN,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-1/liana.txt b/npc/012-1/liana.txt new file mode 100644 index 00000000..e2d318be --- /dev/null +++ b/npc/012-1/liana.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Liana. +// THIS IS A PLACEHOLDER! + +012-1,65,117,0 script Liana NPC_LIANA,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/012-1/prawors.txt b/npc/012-1/prawors.txt new file mode 100644 index 00000000..3ee9159a --- /dev/null +++ b/npc/012-1/prawors.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Prawors, the captain in Candor. +// THIS IS A PLACEHOLDER! + +012-1,53,122,0 script Prawors NPC_PRAWORS,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-1/vincent.txt b/npc/012-1/vincent.txt new file mode 100644 index 00000000..63f1268e --- /dev/null +++ b/npc/012-1/vincent.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Vincent, a child at the Candor beach. +// THIS IS A PLACEHOLDER! + +012-1,121,126,0 script Vincent NPC_VINCENT,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-1/zegas.txt b/npc/012-1/zegas.txt new file mode 100644 index 00000000..12437d57 --- /dev/null +++ b/npc/012-1/zegas.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Zegas, the guy who want you to clean storage room. +// THIS IS A PLACEHOLDER! + +012-1,48,105,0 script Zegas NPC_ZEGAS,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-1/_import.txt b/npc/012-2-1/_import.txt new file mode 100644 index 00000000..13ff23d2 --- /dev/null +++ b/npc/012-2-1/_import.txt @@ -0,0 +1,5 @@ +// Map 012-2-1: Sorfina's Home +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-1/_warps.txt", +"npc/012-2-1/jessie.txt", +"npc/012-2-1/tanisha.txt", diff --git a/npc/012-2-1/_warps.txt b/npc/012-2-1/_warps.txt new file mode 100644 index 00000000..4ccc3898 --- /dev/null +++ b/npc/012-2-1/_warps.txt @@ -0,0 +1,4 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-1: Sorfina's Home warps +012-2-1,52,39,0 warp #012-2-1_52_39 0,0,012-1,38,116 +012-2-1,53,30,0 warp #012-2-1_53_30 0,0,012-2-2,30,34 diff --git a/npc/012-2-1/jessie.txt b/npc/012-2-1/jessie.txt new file mode 100644 index 00000000..c00e868d --- /dev/null +++ b/npc/012-2-1/jessie.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Jessie, Sorfina's old husband. +// THIS IS A PLACEHOLDER! + +012-2-1,38,30,0 script Jessie NPC_JESSIE,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-1/tanisha.txt b/npc/012-2-1/tanisha.txt new file mode 100644 index 00000000..94848971 --- /dev/null +++ b/npc/012-2-1/tanisha.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Tanisha, the little girl in Sorfina's house. +// THIS IS A PLACEHOLDER! + +012-2-1,48,34,0 script Tanisha NPC_TANISHA,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/012-2-2/_import.txt b/npc/012-2-2/_import.txt new file mode 100644 index 00000000..3990e3db --- /dev/null +++ b/npc/012-2-2/_import.txt @@ -0,0 +1,5 @@ +// Map 012-2-2: Sleeping Room +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-2/_savepoints.txt", +"npc/012-2-2/_warps.txt", +"npc/012-2-2/sorfina.txt", diff --git a/npc/012-2-2/_savepoints.txt b/npc/012-2-2/_savepoints.txt new file mode 100644 index 00000000..1aedace4 --- /dev/null +++ b/npc/012-2-2/_savepoints.txt @@ -0,0 +1,28 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-2: Sleeping Room saves +012-2-2,25,27,0 script #save_012-2-2_25_27 NPC_SAVE_POINT,0,0,{ + savepointparticle .map$, .x, .y, NO_INN; + close; + +OnInit: + .distance = 2; + .sex = G_OTHER; + end; + +OnTouch: + bedTouch(); + end; +} +012-2-2,28,27,0 script #save_012-2-2_28_27 NPC_SAVE_POINT,0,0,{ + savepointparticle .map$, .x, .y, NO_INN; + close; + +OnInit: + .distance = 2; + .sex = G_OTHER; + end; + +OnTouch: + bedTouch(); + end; +} diff --git a/npc/012-2-2/_warps.txt b/npc/012-2-2/_warps.txt new file mode 100644 index 00000000..f174dc7c --- /dev/null +++ b/npc/012-2-2/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-2: Sleeping Room warps +012-2-2,30,35,0 warp #012-2-2_30_35 0,0,012-2-1,53,31 diff --git a/npc/012-2-2/sorfina.txt b/npc/012-2-2/sorfina.txt new file mode 100644 index 00000000..682fa38d --- /dev/null +++ b/npc/012-2-2/sorfina.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Sorfina, the former starting NPC. Could need a new job. +// THIS IS A PLACEHOLDER! + +012-2-2,26,30,0 script Sorfina NPC_SORFINA,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/012-2-3/_import.txt b/npc/012-2-3/_import.txt new file mode 100644 index 00000000..e04ba715 --- /dev/null +++ b/npc/012-2-3/_import.txt @@ -0,0 +1,5 @@ +// Map 012-2-3: Candor Shop +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-3/_warps.txt", +"npc/012-2-3/cynric.txt", +"npc/012-2-3/nyle.txt", diff --git a/npc/012-2-3/_warps.txt b/npc/012-2-3/_warps.txt new file mode 100644 index 00000000..a64e4ecb --- /dev/null +++ b/npc/012-2-3/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-3: Candor Shop warps +012-2-3,33,37,0 warp #012-2-3_33_37 0,0,012-1,64,96 diff --git a/npc/012-2-3/cynric.txt b/npc/012-2-3/cynric.txt new file mode 100644 index 00000000..83e2c00b --- /dev/null +++ b/npc/012-2-3/cynric.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Cynric, Candor's banker. +// THIS IS A PLACEHOLDER! + +012-2-3,27,28,0 script Cynric NPC_CYNRIC,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-3/nyle.txt b/npc/012-2-3/nyle.txt new file mode 100644 index 00000000..0c81127a --- /dev/null +++ b/npc/012-2-3/nyle.txt @@ -0,0 +1,18 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Nyle, Candor's shopkeeper. +// THIS IS A PLACEHOLDER! + +012-2-3,42,30,0 script Nyle NPC_NYLE,{ + speech + l("Welcome."), + l("Someone was too lazy to even write a placeholder text, so please come back later"); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-4/_import.txt b/npc/012-2-4/_import.txt new file mode 100644 index 00000000..659fdc67 --- /dev/null +++ b/npc/012-2-4/_import.txt @@ -0,0 +1,5 @@ +// Map 012-2-4: Alchemy Hut +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-4/_warps.txt", +"npc/012-2-4/morgan.txt", +"npc/012-2-4/zitoni.txt", diff --git a/npc/012-2-4/_warps.txt b/npc/012-2-4/_warps.txt new file mode 100644 index 00000000..156a6e54 --- /dev/null +++ b/npc/012-2-4/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-4: Alchemy Hut warps +012-2-4,31,44,0 warp #012-2-4_31_44 0,0,012-1,57,102 diff --git a/npc/012-2-4/morgan.txt b/npc/012-2-4/morgan.txt new file mode 100644 index 00000000..23e97aaf --- /dev/null +++ b/npc/012-2-4/morgan.txt @@ -0,0 +1,21 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Rosen, the salesman in Candor smith. +// THIS IS A PLACEHOLDER! + +012-2-4,26,37,0 script Morgan NPC_MORGAN,{ + speech + l("Hello Wanderer."), + l("I am Morgan, the alchimist."), + l("(People do not like to hear the word 'witch' so much, as we live close to Hurnscald)."), + l("Unfortunately my apprentice Zitoni does not bring fresh potions, so if you need something you should come back later."); + + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-4/zitoni.txt b/npc/012-2-4/zitoni.txt new file mode 100644 index 00000000..7b94cba3 --- /dev/null +++ b/npc/012-2-4/zitoni.txt @@ -0,0 +1,77 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Zitoni, Morgan's apprentice. +// THIS IS A PLACEHOLDER! + +012-2-4,40,37,0 script Zitoni NPC_ZITONI,{ + +OnTalk: + mesn "The man shivers"; + mesq l("The world is so cruel! Oh, cruel world!"); + next; + + menu + lg("I do not like whiners."), -, + lg("What is your problem?"), L_toams; + + close; + +L_toams: + mesn "He looks at you."; + mesq l("I would so much like to brew potions, but..."); + next; + mesq l("I CANNOT WALK!"); + next; + mesq l("Please, please try to find a guy named toams - he is capable to make me walk again! Please!"); + next; + + menu + lg("Ok, I can try."), -, + lg("Ok, but do you have something else?"), L_jez; + + close; + +L_jez: + mesq l("Oh, yes! So kind that you ask"); + next; + mesq l("I forgot my tasks to do!"); + next; + mesq l("If only I remembered what I was supposed to do!"); + next; + mesq l("Please, can you look for a guy named Jesusalva? I am very sure he remembers what kind of quest I was going to accomplish."); + next; + + menu + lg("Ok, I will do that, but now I must leave."), -, + lg("Is that all, or do you have more problems?"), L_wildx; + close; + +L_wildx: + mesq l("Unfortunately yes."); + next; + mesq l("I totally forgot why I am here, and what I am doing here!"); + next; + mesq l("Please, please find WildX. He will explain to me what my role in this world has been."); + + menu + lg("Ok, but all that will keep me busy for a while. So, goodbye."), -, + lg("You do not have more problems, do you?"), L_mick; + close; + +L_mick: + mesq l("Sure I have one more problem."); + next; + mesq l("Did you ever look at me?!? That ugly robe, that weird whatever I hold in my hand, my strange face and all that!"); + next; + mesq l("Can you do a last task for me and try to find Micksha? He sure can help me to look a bit less ugly."); + next; + mesq("That would be so helpful! Please return soon to tell me about your progress."); + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-5/_import.txt b/npc/012-2-5/_import.txt new file mode 100644 index 00000000..1a36bb4d --- /dev/null +++ b/npc/012-2-5/_import.txt @@ -0,0 +1,5 @@ +// Map 012-2-5: Candor Smith +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-5/_warps.txt", +"npc/012-2-5/rosen.txt", +"npc/012-2-5/toichi.txt", diff --git a/npc/012-2-5/_warps.txt b/npc/012-2-5/_warps.txt new file mode 100644 index 00000000..d5a52d94 --- /dev/null +++ b/npc/012-2-5/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-5: Candor Smith warps +012-2-5,29,44,0 warp #012-2-5_29_44 0,0,012-1,65,106 diff --git a/npc/012-2-5/rosen.txt b/npc/012-2-5/rosen.txt new file mode 100644 index 00000000..3fa332c9 --- /dev/null +++ b/npc/012-2-5/rosen.txt @@ -0,0 +1,21 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Rosen, the salesman in Candor smith. +// THIS IS A PLACEHOLDER! + +012-2-5,31,34,0 script Rosen NPC_ROSEN,{ + speech + l("Welcome."), + l("I am Rosen, I am selling the best weapons and armor you can get on this island."), + l("If only Toichi would work harder, I could even offer you something. But meh. Like things are, you must try to return at a later point."), + l("Toichi, go to work! Stop drinking beer!"); + + close; + +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-5/toichi.txt b/npc/012-2-5/toichi.txt new file mode 100644 index 00000000..255c140a --- /dev/null +++ b/npc/012-2-5/toichi.txt @@ -0,0 +1,21 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// Toichi, the smith in Candor island. +// THIS IS A PLACEHOLDER! + +012-2-5,40,35,0 script Toichi NPC_TOICHI,{ + speech + l("Hi there."), + l("My name is Toichi, and it seems I am the only one working on this lazy island."); + next; + l("So I kindly request you not to listen to that stupid Rosen, saying 'Toichi is lazy'."); + next; + l("At least I am doing something!"); + close; +OnInit: + .sex = G_MALE; + .distance = 2; + end; +} diff --git a/npc/012-2-6/_import.txt b/npc/012-2-6/_import.txt new file mode 100644 index 00000000..e239ad17 --- /dev/null +++ b/npc/012-2-6/_import.txt @@ -0,0 +1,3 @@ +// Map 012-2-6: Storage Room +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-6/_warps.txt", diff --git a/npc/012-2-6/_warps.txt b/npc/012-2-6/_warps.txt new file mode 100644 index 00000000..a56767e0 --- /dev/null +++ b/npc/012-2-6/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-6: Storage Room warps +012-2-6,26,39,0 warp #012-2-6_26_39 0,0,012-1,50,105 diff --git a/npc/012-2-7/_import.txt b/npc/012-2-7/_import.txt new file mode 100644 index 00000000..fe642729 --- /dev/null +++ b/npc/012-2-7/_import.txt @@ -0,0 +1,4 @@ +// Map 012-2-7: Small House +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-2-7/_savepoints.txt", +"npc/012-2-7/_warps.txt", diff --git a/npc/012-2-7/_savepoints.txt b/npc/012-2-7/_savepoints.txt new file mode 100644 index 00000000..0230a227 --- /dev/null +++ b/npc/012-2-7/_savepoints.txt @@ -0,0 +1,15 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-7: Small House saves +012-2-7,26,31,0 script #save_012-2-7_26_31 NPC_SAVE_POINT,0,0,{ + savepointparticle .map$, .x, .y, NO_INN; + close; + +OnInit: + .distance = 2; + .sex = G_OTHER; + end; + +OnTouch: + bedTouch(); + end; +} diff --git a/npc/012-2-7/_warps.txt b/npc/012-2-7/_warps.txt new file mode 100644 index 00000000..29b5aab2 --- /dev/null +++ b/npc/012-2-7/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-2-7: Small House warps +012-2-7,30,35,0 warp #012-2-7_30_35 0,0,012-1,51,94 diff --git a/npc/012-3-1/_import.txt b/npc/012-3-1/_import.txt new file mode 100644 index 00000000..8856cef8 --- /dev/null +++ b/npc/012-3-1/_import.txt @@ -0,0 +1,4 @@ +// Map 012-3-1: Cador Cave +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-3-1/_mobs.txt", +"npc/012-3-1/_warps.txt", diff --git a/npc/012-3-1/_mobs.txt b/npc/012-3-1/_mobs.txt new file mode 100644 index 00000000..60055f77 --- /dev/null +++ b/npc/012-3-1/_mobs.txt @@ -0,0 +1,8 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-1: Cador Cave mobs +012-3-1,47,44,17,18 monster Spider 1044,5,4000,8000 +012-3-1,47,47,23,18 monster Cave Maggot 1027,8,2000,20000 +012-3-1,41,30,13,6 monster Green Slime 1024,3,20000,75000 +012-3-1,51,56,15,7 monster Black Scorpion 1104,1,4000,8000 +012-3-1,60,48,11,14 monster AngryCrafty 1103,3,50000,2500 +012-3-1,36,43,11,7 monster AngryCrafty 1103,2,50000,2500 diff --git a/npc/012-3-1/_warps.txt b/npc/012-3-1/_warps.txt new file mode 100644 index 00000000..4de4ef4a --- /dev/null +++ b/npc/012-3-1/_warps.txt @@ -0,0 +1,5 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-1: Cador Cave warps +012-3-1,43,44,0 warp #012-3-1_43_44 1,0,012-3-3,44,97 +012-3-1,68,62,0 warp #012-3-1_68_62 0,2,012-3-2,22,45 +012-3-1,37,41,0 warp #012-3-1_37_41 2,0,012-1,48,68 diff --git a/npc/012-3-2/_import.txt b/npc/012-3-2/_import.txt new file mode 100644 index 00000000..1aaa4813 --- /dev/null +++ b/npc/012-3-2/_import.txt @@ -0,0 +1,4 @@ +// Map 012-3-2: Candor Cave +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-3-2/_mobs.txt", +"npc/012-3-2/_warps.txt", diff --git a/npc/012-3-2/_mobs.txt b/npc/012-3-2/_mobs.txt new file mode 100644 index 00000000..ee085d8d --- /dev/null +++ b/npc/012-3-2/_mobs.txt @@ -0,0 +1,8 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-2: Parua Cave mobs +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-2: Candor Cave mobs +012-3-2,55,39,13,14 monster Spider 1044,5,4000,8000 +012-3-2,54,41,15,12 monster Black Scorpion 1104,4,4000,8000 +012-3-2,56,41,17,10 monster AngryCrafty 1103,3,50000,2500 +012-3-2,48,40,26,6 monster Cave Maggot 1027,6,2000,20000 diff --git a/npc/012-3-2/_warps.txt b/npc/012-3-2/_warps.txt new file mode 100644 index 00000000..25b3477a --- /dev/null +++ b/npc/012-3-2/_warps.txt @@ -0,0 +1,5 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-2: Parua Cave warps +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-2: Candor Cave warps +012-3-2,21,46,0 warp #012-3-2_21_46 0,1,012-3-1,67,61 diff --git a/npc/012-3-3/_import.txt b/npc/012-3-3/_import.txt new file mode 100644 index 00000000..ee48f7ee --- /dev/null +++ b/npc/012-3-3/_import.txt @@ -0,0 +1,5 @@ +// Map 012-3-3: Mana Tree Cave +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/012-3-3/_mobs.txt", +"npc/012-3-3/_warps.txt", +"npc/012-3-3/manatree.txt", diff --git a/npc/012-3-3/_mobs.txt b/npc/012-3-3/_mobs.txt new file mode 100644 index 00000000..f2da13cd --- /dev/null +++ b/npc/012-3-3/_mobs.txt @@ -0,0 +1,7 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-3: Mana Tree Cave mobs +012-3-3,40,28,13,3 monster Green Slime 1024,4,20000,75000 +012-3-3,41,55,15,31 monster Crafty 1018,7,2500,35000 +012-3-3,36,35,9,7 monster Mana Bug 1035,5,10000,10000 +012-3-3,42,39,8,12 monster Silkworm 1040,5,3000,6000 +012-3-3,42,35,7,6 monster Moubi 1072,1,500000,1000000 diff --git a/npc/012-3-3/_warps.txt b/npc/012-3-3/_warps.txt new file mode 100644 index 00000000..c0e6bf40 --- /dev/null +++ b/npc/012-3-3/_warps.txt @@ -0,0 +1,3 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 012-3-3: Mana Tree Cave warps +012-3-3,44,98,0 warp #012-3-3_44_98 0,0,012-3-1,42,45 diff --git a/npc/012-3-3/manatree.txt b/npc/012-3-3/manatree.txt new file mode 100644 index 00000000..985ac2a8 --- /dev/null +++ b/npc/012-3-3/manatree.txt @@ -0,0 +1,20 @@ +// Evol scripts. +// Author: +// Micksha +// Description: +// The Manatree. +// THIS IS A PLACEHOLDER! + +012-3-3,39,33,0 script Manatree#012-3-3 NPC_MANATREE,{ + speech + l("Magic is all around."), + l("You just must listen to it, and feel it deep inside."), + lg("Now go, search for the unknown."); + + close; + +OnInit: + .sex = G_FEMALE; + .distance = 2; + end; +} diff --git a/npc/_anchors.txt b/npc/_anchors.txt index 1ca080cb..36315554 100644 --- a/npc/_anchors.txt +++ b/npc/_anchors.txt @@ -36,6 +36,7 @@ OnInit: htput(.ht, "^START2$", "000-0-0 26 28"); htput(.ht, "^START3$", "000-0-1 26 28"); htput(.ht, "^START|^BEGIN", "000-0 22 24"); - htput(.ht, "^VEIN", "008-3-0 85 172"); + htput(.ht, "^VEIN", "008-3-0 87 172"); htput(.ht, "^WARE", "001-2-18 37 31"); + htput(.ht, "^WEST|PORT", "008-1-1 52 60"); } diff --git a/npc/_import.txt b/npc/_import.txt index 23aef7f4..cf56b97e 100644 --- a/npc/_import.txt +++ b/npc/_import.txt @@ -55,7 +55,9 @@ @include "npc/001-2-9/_import.txt" @include "npc/001-3-0/_import.txt" @include "npc/001-3-1/_import.txt" +@include "npc/001-3-2/_import.txt" @include "npc/008-1-1/_import.txt" +@include "npc/008-1-2/_import.txt" @include "npc/008-1/_import.txt" @include "npc/008-2-0/_import.txt" @include "npc/008-2-1/_import.txt" @@ -82,6 +84,8 @@ @include "npc/008-2-29/_import.txt" @include "npc/008-2-3/_import.txt" @include "npc/008-2-30/_import.txt" +@include "npc/008-2-31/_import.txt" +@include "npc/008-2-32/_import.txt" @include "npc/008-2-4/_import.txt" @include "npc/008-2-5/_import.txt" @include "npc/008-2-6/_import.txt" @@ -90,7 +94,23 @@ @include "npc/008-2-9/_import.txt" @include "npc/008-3-0/_import.txt" @include "npc/008-3-1/_import.txt" -@include "npc/008-4-1/_import.txt" +@include "npc/008-3-2/_import.txt" +@include "npc/008-3-3/_import.txt" +@include "npc/008-3-4/_import.txt" +@include "npc/008-3-5/_import.txt" +@include "npc/008-3-6/_import.txt" +@include "npc/012-1/_import.txt" +@include "npc/012-2-1/_import.txt" +@include "npc/012-2-2/_import.txt" +@include "npc/012-2-3/_import.txt" +@include "npc/012-2-4/_import.txt" +@include "npc/012-2-5/_import.txt" +@include "npc/012-2-6/_import.txt" +@include "npc/012-2-7/_import.txt" +@include "npc/012-3-1/_import.txt" +@include "npc/012-3-2/_import.txt" +@include "npc/012-3-3/_import.txt" +@include "npc/sec_pri/_import.txt" @include "npc/test/_import.txt" @include "npc/testbg/_import.txt" "npc/_anchors.txt", diff --git a/npc/commands/debug-look.txt b/npc/commands/debug-look.txt index 79bf8699..23acc4da 100644 --- a/npc/commands/debug-look.txt +++ b/npc/commands/debug-look.txt @@ -1,22 +1,19 @@ function script BarberDebug { function setGender { - //clear; - //setnpcdialogtitle l("Appearance Debug - Sex Change"); - //mes l("Please choose the desired gender:"); - //next; - //menuint - // l("Male"), G_MALE, - // l("Female"), G_FEMALE, - // l("Non-binary"), G_OTHER; + clear(); + setnpcdialogtitle(l("Appearance Debug - Gender Change")); + mes(l("Warning: changing your gender will send you back to the character selection screen.")); + mes(""); + mes(l("Please choose the desired gender:")); + next(); + menuint( + l("Male"), GENDER_MALE, + l("Female"), GENDER_FEMALE, + l("Non-binary"), GENDER_HIDDEN); - //Sex = @menuret; // FIXME: make this work like in tmwAthena - //return; - - - // ^ Future code, Doesn't work yet - closeclientdialog; - changecharsex; + Gender = @menuret; + return; } function setStyle { clear; @@ -41,7 +38,7 @@ function script BarberDebug { function setRace { clear; setnpcdialogtitle l("Appearance Debug - Race"); - mes l("Race") + ": " + Class; + mes l("Race") + ": " + Class + " (" + get_race(GETRACE_FULL) + ")"; next; mes l("Please enter the desired race") + " (0-32767)"; input .@r, 0, 0x7FFF; @@ -57,10 +54,10 @@ function script BarberDebug { mes ""; mes "---"; - mes l("Gender") + ": " + Sex; + mes l("Gender") + ": " + genderToString(Gender); mes l("Hair style") + ": " + getlook(LOOK_HAIR); mes l("Hair color") + ": " + getlook(LOOK_HAIR_COLOR); - mes l("Race") + ": " + Class; + mes l("Race") + ": " + Class + " (" + get_race() + ")";; mes "---"; next; diff --git a/npc/commands/debug-quest.txt b/npc/commands/debug-quest.txt index 1c3e0b5c..34bdf63b 100644 --- a/npc/commands/debug-quest.txt +++ b/npc/commands/debug-quest.txt @@ -80,7 +80,8 @@ function script GlobalQuestDebug { "Fexil", ArtisQuests_Fexil, "Lloyd", ArtisQuests_Lloyd, l("Mona's dad"), ArtisQuests_MonaDad, - l("Artis legion progress"), Artis_Legion_Progress; + l("Artis legion progress"), Artis_Legion_Progress, + l("Legion training"), ArtisQuests_TrainingLegion; switch (@menuret) { @@ -130,7 +131,8 @@ function script GlobalQuestDebug { "Rumly", General_Rumly, l("Narrator"), General_Narrator, "Janus", General_Janus, - l("Cooking"), General_Cooking; + l("Cooking"), General_Cooking, + l("Brotherhood"), General_Brotherhood; switch (@menuret) { diff --git a/npc/commands/gender.txt b/npc/commands/gender.txt new file mode 100644 index 00000000..b852beb0 --- /dev/null +++ b/npc/commands/gender.txt @@ -0,0 +1,35 @@ +// @gender atcommand +// changes or returns the gender + +- script @gender 32767,{ + end; + +OnCall: + if (.@atcmd_parameters$[0] == "") { + dispbottom("Your current gender is " + genderToString()); + end; + } + + .@desired = stringToGender(.@atcmd_parameters$[0]); + + if (.@desired == Gender) { + dispbottom("Your gender is already " + genderToString()); + } else { + Gender = .@desired; + dispbottom("Gender changed to " + genderToString()); + } + end; + +OnInit: + bindatcmd("gender", "@gender::OnCall", 99, 99, false); + add_group_command("gender", 40, true, false); + add_group_command("gender", 50, true, true); + add_group_command("gender", 60, true, true); + add_group_command("gender", 80, true, true); + + bindatcmd("changesex", "@gender::OnCall", 99, 99, false); + add_group_command("changesex", 40, true, false); + add_group_command("changesex", 50, true, true); + add_group_command("changesex", 60, true, true); + add_group_command("changesex", 80, true, true); +} diff --git a/npc/commands/gm.txt b/npc/commands/gm.txt new file mode 100644 index 00000000..b402cda8 --- /dev/null +++ b/npc/commands/gm.txt @@ -0,0 +1,41 @@ +// @showgm/@hidegm atcommand +// TEMPORALY hides GM level (or revert it) +// +// group lv: 20+ +// group char lv: 99 +// log: False +// +// usage: +// @showgm +// #showgm "char" <delta> +// + +- script @group 32767,{ + end; + +OnHide: + .@gm=getgroupid(); + if (.@gm < 20) end; + if (.@gm % 10 != 0) end; + setgroupid(.@gm+1); + dispbottom "hidelevel : "+l("Your GM level is now hidden."); + end; + +OnShow: + .@gm=getgroupid(); + if (.@gm < 20) end; + if (.@gm % 10 != 1) end; + setgroupid(.@gm-1); + dispbottom "showlevel : "+l("Your GM level is now visible."); + end; + +OnInit: + bindatcmd "showgroup", "@group::OnShow", 20, 99, 0; + bindatcmd "showgm", "@group::OnShow", 20, 99, 0; + bindatcmd "showlevel", "@group::OnShow", 20, 99, 0; + + bindatcmd "hidegroup", "@group::OnHide", 20, 99, 0; + bindatcmd "hidegm", "@group::OnHide", 20, 99, 0; + bindatcmd "hidelevel", "@group::OnHide", 20, 99, 0; + end; +} diff --git a/npc/commands/mobinfo.txt b/npc/commands/mobinfo.txt new file mode 100644 index 00000000..691bfb68 --- /dev/null +++ b/npc/commands/mobinfo.txt @@ -0,0 +1,29 @@ +// The Mana World Script +// +// @monsterinfo <monsterAegis> +// Sends @mobinfo with a delay (moved from atcommand.conf) +// Requires EVOL_MONSTER_IDENTIFY +// +- script @monsterinfo 32767,{ + end; + +OnCall: + // Check for skill level + if (!getskilllv(EVOL_MONSTER_IDENTIFY)) + end; + + // ... + if (@rsync_delay > gettimetick(2)) { + dispbottom l("Not doing that to prevent flood."); + end; + } + + // Send @mobinfo and set a cooldown of 3 seconds. + atcommand("@mobinfo " + implode(.@atcmd_parameters$, " ")); + @rsync_delay=gettimetick(2)+3; + end; + +OnInit: + bindatcmd "monsterinfo", "@monsterinfo::OnCall", 0, 60, 0; + end; +} diff --git a/npc/commands/motd.txt b/npc/commands/motd.txt index e21d7539..2f6a5e2a 100644 --- a/npc/commands/motd.txt +++ b/npc/commands/motd.txt @@ -174,7 +174,14 @@ OnCall: closeclientdialog; end; -OnPCLoginEvent: +OnInit: + MOTD_debug_text; + .size = getarraysize($MOTD_Messages$); + .dsize = getarraysize($@Debug_Messages$); + bindatcmd "motd", "@motd::OnCall", 0, 99, 0; +} + +function script ReceiveMOTD { if ($MOTD_Disabled < 1) { displayMOTD; @@ -183,11 +190,5 @@ OnPCLoginEvent: { dispbottom "##7<<##B @@help://test-server|" + col(l("Click here for instructions on how to use the test server."),6) + "@@ ##7>>"; } - end; - -OnInit: - MOTD_debug_text; - .size = getarraysize($MOTD_Messages$); - .dsize = getarraysize($@Debug_Messages$); - bindatcmd "motd", "@motd::OnCall", 0, 99, 0; + return; } diff --git a/npc/commands/python.txt b/npc/commands/python.txt new file mode 100644 index 00000000..e2fdc5bf --- /dev/null +++ b/npc/commands/python.txt @@ -0,0 +1,24 @@ +// The Mana World script +// Author: Gumi <gumi@themanaworld.org> +// Author: Jesusalva <jesusalva@themanaworld.org> +// +// Stomp stomp stomp (use with caution) + +- script @python 32767,{ + end; + +// Soft Resync +OnCall: + specialeffect(69, AREA, playerattached()); + addtimer 380, .name$+"::OnKill"; + end; + +OnKill: + percentheal -100, -100; + //dispbottom l("Oh look, it is Cupid!"); + end; + +OnInit: + bindatcmd "python", "@python::OnCall", 20, 20, 1; + end; +} diff --git a/npc/commands/resync.txt b/npc/commands/resync.txt index 63b2d290..a535a343 100644 --- a/npc/commands/resync.txt +++ b/npc/commands/resync.txt @@ -35,6 +35,6 @@ OnCall: // Anyone can call @resync, but only support and upwards for other players. // ie. GMs can try to fix lag for other people. OnInit: - bindatcmd "resync", "@resync::OnCall", 0, 2, 0; + bindatcmd "resync", "@resync::OnCall", 0, 20, 0; end; } diff --git a/npc/commands/scheduled-broadcasts.txt b/npc/commands/scheduled-broadcasts.txt index 972a0cf2..720651b3 100644 --- a/npc/commands/scheduled-broadcasts.txt +++ b/npc/commands/scheduled-broadcasts.txt @@ -213,13 +213,15 @@ OnCall: closeclientdialog; end; -OnPCLoginEvent: +OnInit: + bindatcmd "sched", "@sched::OnCall", 0, 99, 0; +} + +function script ReceiveScheduledBroadcast { if ($@SCHED_Opt[0] && $@SCHED_Msg$ != "") { announce $@SCHED_Msg$, bc_self; } - end; - -OnInit: - bindatcmd "sched", "@sched::OnCall", 0, 99, 0; + return; } + diff --git a/npc/commands/super-menu.txt b/npc/commands/super-menu.txt index 8102dd32..5ed7ced3 100644 --- a/npc/commands/super-menu.txt +++ b/npc/commands/super-menu.txt @@ -46,21 +46,23 @@ OnCall: closeclientdialog; end; -OnPCLoginEvent: +OnInit: + bindatcmd "super", "@super::OnCall", 0, 99, 0; + bindatcmd "numa", "@super::OnCall", 0, 99, 0; // alias for those used to TMW's @numa +} + +function script GrantSuperSkill { .@debug_skill = getskilllv(EVOL_SUPER_MENU); if (.@debug_skill > 0 && !debug) { - skill EVOL_SUPER_MENU, 0, 0; // remove debug skill + skill EVOL_SUPER_MENU, 0, 0; // remove debug skill. Not needed (skill tree) } else if (.@debug_skill < 1 && debug) { skill EVOL_SUPER_MENU, 1, 0; // give debug skill } - end; - -OnInit: - bindatcmd "super", "@super::OnCall", 0, 99, 0; - bindatcmd "numa", "@super::OnCall", 0, 99, 0; // alias for those used to TMW's @numa + return; } + diff --git a/npc/commands/warp.txt b/npc/commands/warp.txt index 318489d7..22eeda39 100644 --- a/npc/commands/warp.txt +++ b/npc/commands/warp.txt @@ -70,21 +70,22 @@ OnCall: } slide_or_warp(.@map$, .@x, .@y); + updateSpotlight(); end; OnInit: if (debug > 0) { - bindatcmd("w", "@w::OnCall", 0, 2, 0); - bindatcmd("go", "@w::OnCall", 0, 2, 0); - bindatcmd("to", "@w::OnCall", 0, 2, 0); - bindatcmd("warp", "@w::OnCall", 0, 2, 0); + bindatcmd("w", "@w::OnCall", 0, 20, 0); + bindatcmd("go", "@w::OnCall", 0, 20, 0); + bindatcmd("to", "@w::OnCall", 0, 20, 0); + bindatcmd("warp", "@w::OnCall", 0, 20, 0); } else { - bindatcmd("w", "@w::OnCall", 2, 2, 1); - bindatcmd("go", "@w::OnCall", 2, 2, 1); - bindatcmd("to", "@w::OnCall", 2, 2, 1); - bindatcmd("warp", "@w::OnCall", 2, 2, 1); + bindatcmd("w", "@w::OnCall", 20, 60, 1); + bindatcmd("go", "@w::OnCall", 20, 60, 1); + bindatcmd("to", "@w::OnCall", 20, 60, 1); + bindatcmd("warp", "@w::OnCall", 20, 60, 1); } } diff --git a/npc/commands/zeny.txt b/npc/commands/zeny.txt index 77f6d2de..944c1bb9 100644 --- a/npc/commands/zeny.txt +++ b/npc/commands/zeny.txt @@ -94,5 +94,5 @@ OnInit: end; } - bindatcmd "esp", "@esp::OnCall", 3, 99, 1; + bindatcmd "esp", "@esp::OnCall", 99, 99, 1; } diff --git a/npc/dev/test.txt b/npc/dev/test.txt index e9058aee..f98651df 100644 --- a/npc/dev/test.txt +++ b/npc/dev/test.txt @@ -730,10 +730,10 @@ function script HerculesSelfTestHelper { callsub(OnCheckStr, "sprintf (positional)", sprintf("'%2$s' '%1$c'", "First", "Second"), "'Second' 'F'"); if (.errors) { - debugmes "Script engine self-test [ \033[0;31mFAILED\033[0m ]"; - debugmes "**** The test was completed with " + .errors + " errors. ****"; + consolemes(CONSOLEMES_DEBUG, "Script engine self-test [ \033[0;31mFAILED\033[0m ]"); + consolemes(CONSOLEMES_ERROR, "**** The test was completed with " + .errors + " errors. ****"); } else { - debugmes "Script engine self-test [ \033[0;32mPASSED\033[0m ]"; + consolemes(CONSOLEMES_DEBUG, "Script engine self-test [ \033[0;32mPASSED\033[0m ]"); } return .errors; end; @@ -778,8 +778,8 @@ OnReportError: .@val$ = getarg(1,""); .@ref$ = getarg(2,""); if (.errors == 1) - debugmes "**** WARNING: Any self-test results past this point are unreliable because of previous errors. ****"; - debugmes "Error: "+.@msg$+": '"+.@val$+"' (found) != '"+.@ref$+"' (expected)"; + consolemes(CONSOLEMES_ERROR, "**** WARNING: Any self-test results past this point are unreliable because of previous errors. ****"); + consolemes(CONSOLEMES_ERROR, "Error: "+.@msg$+": '"+.@val$+"' (found) != '"+.@ref$+"' (expected)"); ++.errors; //end; return; diff --git a/npc/functions/RNGesus.txt b/npc/functions/RNGesus.txt index 6883f8f1..7224977c 100644 --- a/npc/functions/RNGesus.txt +++ b/npc/functions/RNGesus.txt @@ -1,16 +1,30 @@ // Evol functions. // Authors: // gumi +// jesusalva // Description: // Randomization helper functions. +// pseudo-fix randomness +// rand2( min, max ) +function script rand2 { + if (getargcount() == 2) { + .@min=getarg(0)*100; + .@max=getarg(1)*100+99; + } else { + .@min=0; + .@max=getarg(0)*100-1; + } + return rand(.@min, .@max)/100; +} + // any(<arg>{, ...<arg>}) // returns one argument randomly function script any { - return getarg(rand(getargcount())); + return getarg(rand2(getargcount())); } @@ -19,7 +33,7 @@ function script any { // returns any member of the array function script any_of { - return getelementofarray(getarg(0), getarrayindex(getarg(0)) + rand(getarraysize(getarg(0)) - getarrayindex(getarg(0)))); + return getelementofarray(getarg(0), getarrayindex(getarg(0)) + rand2(getarraysize(getarg(0)) - getarrayindex(getarg(0)))); } @@ -54,7 +68,7 @@ function script relative_array_random { set(getelementofarray(getarg(0), 0), .@total_prob); } - .@target_sum = rand(0, .@total_prob); + .@target_sum = rand2(0, .@total_prob); for (.@i = .@initial_index; .@sum < .@target_sum; .@i += 2) { if (.@is_str) { diff --git a/npc/functions/barber.txt b/npc/functions/barber.txt index 370285b7..1df0a307 100644 --- a/npc/functions/barber.txt +++ b/npc/functions/barber.txt @@ -108,3 +108,18 @@ function script BarberChangeColor { return; } + +function script BarberChangeGender { + mesn("Warning"); + mes(b(l("Changing your gender will send you back to the character selection screen."))); + next(); + + mes(l("Please select the desired gender:")); + menuint( + l("Female"), GENDER_FEMALE, + l("Male"), GENDER_MALE, + l("Non-binary"), GENDER_HIDDEN); + + Gender = @menuret; + return; +} diff --git a/npc/functions/fishing.txt b/npc/functions/fishing.txt index dcf4ac02..fee0acb7 100644 --- a/npc/functions/fishing.txt +++ b/npc/functions/fishing.txt @@ -44,8 +44,7 @@ OnBite: OnCleanUp: dispbottom l("You waited too long and lost the bait..."); specialeffect(getvariableofnpc(.failure_fx, @fishing_spot$), SELF, playerattached()); // event fail -OnPCLogoutEvent: - fishing_cleanup @fishing_spot$; + fishing_cleanup(@fishing_spot$); @fishing_spot$ = ""; // unbind fishing npc end; } diff --git a/npc/functions/gender.txt b/npc/functions/gender.txt new file mode 100644 index 00000000..0f153c53 --- /dev/null +++ b/npc/functions/gender.txt @@ -0,0 +1,13 @@ +function script stringToGender { + .@short$ = strtolower(charat(getarg(0, ""), 0)); + + return .@short$ == "f" ? GENDER_FEMALE : + .@short$ == "m" ? GENDER_MALE : GENDER_HIDDEN; +} + +function script genderToString { + .@gender = getarg(0, Gender); + + return .@gender == GENDER_FEMALE ? l("female") : + .@gender == GENDER_MALE ? l("male") : l("non-binary"); +} diff --git a/npc/functions/global_event_handler.txt b/npc/functions/global_event_handler.txt new file mode 100644 index 00000000..c66637ef --- /dev/null +++ b/npc/functions/global_event_handler.txt @@ -0,0 +1,65 @@ +// The Mana World scripts. +// Author: +// The Mana World Team +// Description: +// Controls most, if not all, global events on this server. +// Please only use callfunc("") here; This script is loaded +// early on and direct function assignment will cause fails. +// TODO: Move "new quest" notification here. (Or deprecate) + +// Helper function for scripted Monster Kills. +function script fix_mobkill { + killedrid=getarg(0); + doevent "#GlobalHandler::OnNPCKillEvent"; + return; +} + +- script #GlobalHandler NPC_HIDDEN,{ + end; + + +OnPCLoginEvent: + callfunc("updateSpotlight"); + callfunc("ReceiveMOTD"); + callfunc("ReceiveScheduledBroadcast"); + callfunc("FixBankVault"); + callfunc("GrantSuperSkill"); + end; + +OnPCLogoutEvent: + callfunc("UnequipCookie"); + callfunc("MundaneLogout"); + callfunc("fishing_cleanup", @fishing_spot$); + + // Variable cleanup + @fishing_spot$ = ""; + end; + +OnPCDieEvent: + callfunc("ForcedUnmount"); + callfunc("MundaneDeath"); + end; + +OnPCBaseLvUpEvent: + //callfunc("newquestwarning"); + end; + +OnNPCKillEvent: + $MONSTERS_KILLED+=1; + MONSTERS_KILLED+=1; + callfunc("EnoraKills"); + if ($MONSTERS_KILLED % 1000000 == 0) + callfunc("GetBeanieCopter"); + end; + +OnPCKillEvent: + $PLAYERS_KILLED+=1; + PLAYERS_KILLED+=1; + end; + +OnSkillInvoke: + callfunc("SkillInvoked"); + end; + +} + diff --git a/npc/functions/inventoryplace.txt b/npc/functions/inventoryplace.txt index 4a5e08ca..c7eff88b 100644 --- a/npc/functions/inventoryplace.txt +++ b/npc/functions/inventoryplace.txt @@ -13,7 +13,7 @@ function script inventoryplace { if (.@argc % 2 != 0) { - debugmes "inventoryplace: Wrong argument count."; + consolemes(CONSOLEMES_ERROR, "inventoryplace: Wrong argument count."); close; } diff --git a/npc/functions/main.txt b/npc/functions/main.txt index e31b02d0..c8a37b1c 100644 --- a/npc/functions/main.txt +++ b/npc/functions/main.txt @@ -146,7 +146,7 @@ function script speech { // Show debug message if .debug variable of NPC is set to 1 function script npcdebug { if (getvariableofnpc(.debug, strnpcinfo(3))) - debugmes strnpcinfo(3) + ": " + getarg(0); + consolemes(CONSOLEMES_DEBUG, strnpcinfo(3) + ": " + getarg(0)); return; } diff --git a/npc/functions/manhole.txt b/npc/functions/manhole.txt index 54449d78..3af18537 100644 --- a/npc/functions/manhole.txt +++ b/npc/functions/manhole.txt @@ -59,7 +59,7 @@ function script manhole_interact { // Would be nice to customize but not needed atm // 1 mob for every 30 levels (level 99 players spawn 4 mobs) // Note that food type is currently disregarded (and it accepts any healing item) - .@monsterId=any(slime, Croc, LittleBlub, CaveMaggot); + .@monsterId=any(Slime, Croc, LittleBlub, CaveMaggot); .@mobGID = monster(.@m$, .@x, .@y, strmobinfo(1, .@monsterId), .@monsterId, (BaseLevel/30)+1); unitattack(.@mobGID, getcharid(CHAR_ID_ACCOUNT)); // "It's not aggressive"? We don't care. } diff --git a/npc/functions/marriage.txt b/npc/functions/marriage.txt deleted file mode 100644 index d9e48bf5..00000000 --- a/npc/functions/marriage.txt +++ /dev/null @@ -1,293 +0,0 @@ -// Evol functions. -// Author: -// 4144 -// Description: -// Functions for marriage - -// check is player is near marriage npc -// args: -// 0 - player name -// returns: -// true if player located near npc. -function script marriagecheckname { - .@name$ = getarg(0); - if (.@name$ == "") - { - // no other registrand - return false; - } - .@id = getcharid(0, .@name$); - .@accoundId = getcharid(3, .@name$); - if (isloggedin(.@accoundId, .@id) == false) - { - // registrant not logged in - return false; - } - getmapxy(.@mapname$, .@x, .@y, 0, .@name$); - if (.@mapname$ != strnpcinfo(4)) - { - // registrant on other map - return false; - } - if (distance(.@x, .@y, .x, .y) > .distance) - { - // registrant too far - return false; - } - return true; -} - -// return player name registered with same gender like attached player -function script getmarriageregistrant { - if (Sex) - { - .@name$ = getvariableofnpc(.maleName$, strnpcinfo(3)); - } - else - { - .@name$ = getvariableofnpc(.femaleName$, strnpcinfo(3)); - } - return .@name$; -} - -// return registered marriage partner name -function script getmarriagepartner { - if (Sex) - { - .@name$ = getvariableofnpc(.femaleName$, strnpcinfo(3)); - } - else - { - .@name$ = getvariableofnpc(.maleName$, strnpcinfo(3)); - } - if (marriagecheckname(.@name$)) - return .@name$; - return ""; -} - -// register attached player as partner for marriage -function script marriageregisterself { - if (Sex) - { - set getvariableofnpc(.maleName$, strnpcinfo(3)), strcharinfo(0); - set getvariableofnpc(.maleName_partner$, strnpcinfo(3)), ""; - } - else - { - set getvariableofnpc(.femaleName$, strnpcinfo(3)), strcharinfo(0); - set getvariableofnpc(.femaleName_partner$, strnpcinfo(3)), ""; - } - return; -} - -// return player name what was accepted by partner -function script getmarriagepartneraccepted { - if (Sex) - { - .@name$ = getvariableofnpc(.femaleName_partner$, strnpcinfo(3)); - } - else - { - .@name$ = getvariableofnpc(.maleName_partner$, strnpcinfo(3)); - } - return .@name$; -} - -// return true if partner present near and partner accepted you -function script ismarriagepartneraccepted { - .@partner$ = getmarriagepartner(); - if (.@partner$ == "") - return false; - .@name$ = getmarriagepartneraccepted(); - if (.@name$ == strcharinfo(0)) - return true; - return false; -} - -// accept for attached player his/her partner -// args: -// 0 - partner name -function script marriageacceptpartner { - .@name$ = getarg(0); - if (Sex) - { - set getvariableofnpc(.maleName_partner$, strnpcinfo(3)), .@name$; - } - else - { - set getvariableofnpc(.femaleName_partner$, strnpcinfo(3)), .@name$; - } - return; -} - -function script askmarry { - speech l("Do you want to marry @@?", getarg(0)); - if (askyesno() == ASK_YES) - return true; - return false; -} - -// start marriage registration process -function script marriageregister { - .@partner$ = getmarriagepartner(); - if (.@partner$ == "") - { // no partner registered - speech l("Ok I add your name... @@...", strcharinfo(0)); - marriageregisterself(); - next; - speech lg("Now wait for your partner, then talk to me again."); - npctalk l("@@ registered for marriage. Waiting for partner...", strcharinfo(0)); - close; - } - else - { // partner already registered - if (askmarry(.@partner$) == true) - { - marriageregisterself(); - marriageacceptpartner(.@partner$); - npctalk l("@@ registered for marriage and accepted partner @@!", strcharinfo(0), .@partner$); - npctalk l("Waiting for @@...", .@partner$); - close; - } - else - { - close; - } - } - return; -} - -// remove all marriage registations -function script marriageclear { - set getvariableofnpc(.maleName$, strnpcinfo(3)), ""; - set getvariableofnpc(.femaleName$, strnpcinfo(3)), ""; - set getvariableofnpc(.maleName_partner$, strnpcinfo(3)), ""; - set getvariableofnpc(.femaleName_partner$, strnpcinfo(3)), ""; - return; -} - -// do actual marriage -function script domarriage { - .@name$ = strcharinfo(0); - .@partner$ = getarg(0); - if (marriage(.@partner$)) - { - speech l("You got married to @@!", .@partner$); - npctalk l("@@ and @@ just got married!", .@name$, .@partner$); - } - else - { - npctalk l("Marriage failed."); - } - marriageclear(); - return; -} - -// marry main code -function script marriagemarry { - .@registrant$ = getmarriageregistrant(); - if (marriagecheckname(.@registrant$) == true) - { - if (.@registrant$ == strcharinfo(0)) - { - if (ismarriagepartneraccepted()) - { - .@partner$ = getmarriagepartner(); - if (marriagecheckname(.@partner$) == false) - { - speech l("Partner not ready."); - } - else if (askmarry(.@partner$) == true) - { - domarriage(.@partner$); - } - } - else - { - speech l("You already registered. Waiting for your partner..."); - } - } - else - { - speech l("Sorry, I'm busy with other registrations."), - l("Come after a little while."); - } - close; - } - - speech l("What can I do for you?"); - switch (select(l("I want to register for marriage."), - l("Nothing"))) - { - case 1: - marriageregister; - break; - case 2: - break; - } - return; -} - -// divorce main code -function script marriagedivorce { - speech l("What can I do for you?"); - switch (select(l("I want to divorce."), - l("Nothing"))) - { - case 1: - speech lg("Are you sure?"); - if (askyesno() == ASK_YES) - { - if (divorce()) - { - speech l("You are now divorced!"), - l("Good look."); - npctalk l("@@ divorced!", strcharinfo(0)); - } - else - { - speech l("Divorce error!"); - } - } - break; - case 2: - break; - } - return; -} - -// main function for marriage -function script marriagemain { - if (Sex > 1) - { - speech l("Sorry i can't help you. Go away!"); - close; - } - - if (getpartnerid() != 0) - { // have partner - marriagedivorce(); - } - else - { // no partner - marriagemarry(); - } - - return; -} - -// check registration list by timer -function script marriagecheck { - .@name$ = getvariableofnpc(.maleName$, strnpcinfo(3)); - if (.@name$ != "" && marriagecheckname(.@name) == false) - { - set getvariableofnpc(.maleName$, strnpcinfo(3)), ""; - set getvariableofnpc(.maleName_partner$, strnpcinfo(3)), ""; - } - .@name$ = getvariableofnpc(.femaleName$, strnpcinfo(3)); - if (.@name$ != "" && marriagecheckname(.@name) == false) - { - set getvariableofnpc(.femaleName$, strnpcinfo(3)), ""; - set getvariableofnpc(.femaleName_partner$, strnpcinfo(3)), ""; - } -} diff --git a/npc/functions/masks.txt b/npc/functions/masks.txt index 9fb54919..4b28bfc7 100644 --- a/npc/functions/masks.txt +++ b/npc/functions/masks.txt @@ -1,68 +1,43 @@ // Evol functions. // Author: // Reid +// Jesusalva // Description: // Triggers functions to add and remove masks. // Variables: -// none +// 4 - Top Mask +// 8 - Bottom Mask +// Default mask: 13 (Top + Bottom + Display mask) // Artis Aemil's Legion -function script artisALRemTopMask { - if ((getareausers("001-2-33", 23, 27, 45, 31) >= 1) || - (getareausers("001-2-33", 23, 32, 26, 38) >= 1) || - (getareausers("001-2-33", 42, 32, 45, 38) >= 1)) - { - removemapmask "001-2-33", 4; - } +function script artisALResetMask { + .@m=getmapmask("001-2-33"); + sendmapmask(.@m); return 0; } -function script artisALAddTopMask { - if ((getareausers("001-2-33", 23, 27, 45, 31) == 0) && - (getareausers("001-2-33", 23, 32, 26, 38) == 0) && - (getareausers("001-2-33", 42, 32, 45, 38) == 0)) - { - addmapmask "001-2-33", 4; - } +function script artisALTopMask { + addtimer 30, "artisALTopMaskDO::OnDoIt"; return 0; } -function script artisALRemBotMask { - if (getareausers("001-2-33", 23, 32, 45, 46) >= 1) - { - removemapmask "001-2-33", 8; - } +function script artisALBottomMask { + addtimer 30, "artisALBottomMaskDO::OnDoIt"; return 0; } -function script artisALAddBotMask { - if (getareausers("001-2-33", 23, 32, 45, 46) == 0) - { - addmapmask "001-2-33", 8; - } - return 0; +// Show bottom mask is the same as hiding top mask +- script artisALBottomMaskDO NPC_HIDDEN,{ +OnDoIt: + .@m=getmapmask("001-2-33"); + sendmapmask(.@m^4); } -function script artisALUpdateMask { - if (getareausers("001-2-33", 23, 32, 45, 46) >= 1) - { - removemapmask "001-2-33", 8; - } - else - { - addmapmask "001-2-33", 8; - } - if ((getareausers("001-2-33", 23, 27, 45, 31) >= 1) || - (getareausers("001-2-33", 23, 32, 26, 38) >= 1) || - (getareausers("001-2-33", 42, 32, 45, 38) >= 1)) - { - removemapmask "001-2-33", 4; - } - else - { - addmapmask "001-2-33", 4; - } - - return 0; +// Show top mask is the same as hiding bottom mask +- script artisALTopMaskDO NPC_HIDDEN,{ +OnDoIt: + .@m=getmapmask("001-2-33"); + sendmapmask(.@m^8); } + diff --git a/npc/functions/math.txt b/npc/functions/math.txt index 004125c7..357407da 100644 --- a/npc/functions/math.txt +++ b/npc/functions/math.txt @@ -2,6 +2,7 @@ // Authors: // 4144 // Reid +// Jesusalva // Description: // Math functions @@ -38,3 +39,12 @@ function script lognbaselvl { return .@ret; } + + +// result is: lower < target <= higher +// is_between ( lower, higher, target) +function script is_between { + .@val=getarg(2); + return (getarg(0) < .@val && getarg(1) >= .@val); +} + diff --git a/npc/functions/npcmovegraph.txt b/npc/functions/npcmovegraph.txt index d03f15c5..54e4e783 100644 --- a/npc/functions/npcmovegraph.txt +++ b/npc/functions/npcmovegraph.txt @@ -35,12 +35,12 @@ function script initmovegraph { function script findmovegraphlabel { if (!getargcount()) { - debugmes "findmovegraphlabel: no argument"; + consolemes(CONSOLEMES_DEBUG, "findmovegraphlabel: no argument"); return -1; } if (!isstr(getarg(0))) { - debugmes "findmovegraphlabel: need string argument"; + consolemes(CONSOLEMES_DEBUG, "findmovegraphlabel: need string argument"); return -1; } @@ -144,7 +144,7 @@ function script execmovecmd { } else { - debugmes "execmovecmd: unknown WARP destination label: " + .@cmd$[1]; + consolemes(CONSOLEMES_DEBUG, "execmovecmd: unknown WARP destination label: " + .@cmd$[1]); } } else if (.@cmd$[0] == "call") @@ -152,7 +152,7 @@ function script execmovecmd { switch (getarraysize(.@cmd$)) { case 1: - debugmes "execmovecmd: CALL command needs some parameters"; + consolemes(CONSOLEMES_DEBUG, "execmovecmd: CALL command needs some parameters"); return 0; case 2: return callfunc(.@cmd$[1]); @@ -176,7 +176,7 @@ function script execmovecmd { else if (.@cmd$[0] == "debugmes") { deletearray .@cmd$[0], 1; - debugmes implode(.@cmd$, " "); + consolemes(CONSOLEMES_DEBUG, implode(.@cmd$, " ")); } else if (.@cmd$[0] == "flags") { @@ -196,7 +196,7 @@ function script execmovecmd { } else { - debugmes "Unknown move graph cmd: " + .@cmd$[0]; + consolemes(CONSOLEMES_DEBUG, "Unknown move graph cmd: " + .@cmd$[0]); } return 0; } @@ -226,7 +226,7 @@ function script getnextmovecmd { function script getrandompoint { if (getargcount() < 4) { - debugmes "error: getrandompoint(x1, y1, x2, y2) takes 4 arguments"; + consolemes(CONSOLEMES_DEBUG, "error: getrandompoint(x1, y1, x2, y2) takes 4 arguments"); return -1; } @@ -264,7 +264,7 @@ function script getrandompoint { goto L_Found; // finally, if we don't find anything - debugmes "error: getrandompoint: cannot find walkable cell in rectangle [(" + .@x1 + "," + .@y1 + ") , (" + .@x2 + "," + .@y2 + ")]"; + consolemes(CONSOLEMES_DEBUG, "error: getrandompoint: cannot find walkable cell in rectangle [(" + .@x1 + "," + .@y1 + ") , (" + .@x2 + "," + .@y2 + ")]"); return -1; L_Found: @@ -282,7 +282,7 @@ L_Found: function script mg_npcwalkto { if (getargcount() < 2) { - debugmes "usage: mg_npcwalkto(x1,y1[,x2,y2])"; + consolemes(CONSOLEMES_DEBUG, "usage: mg_npcwalkto(x1,y1[,x2,y2])"); return -1; } diff --git a/npc/functions/permissions.txt b/npc/functions/permissions.txt index 62e0da6b..96e69fde 100644 --- a/npc/functions/permissions.txt +++ b/npc/functions/permissions.txt @@ -31,5 +31,5 @@ function script is_evtc { // game master function script is_gm { return is_admin(getarg(0, getcharid(CHAR_ID_ACCOUNT))) || - has_permission("send_gm", getarg(0, getcharid(CHAR_ID_ACCOUNT))); + can_use_command("@jail", getarg(0, getcharid(CHAR_ID_ACCOUNT))); } diff --git a/npc/functions/quest-debug/006-ShipQuests_ArpanMoney.txt b/npc/functions/quest-debug/006-ShipQuests_ArpanMoney.txt index 00e2fbea..0f77c1b9 100644 --- a/npc/functions/quest-debug/006-ShipQuests_ArpanMoney.txt +++ b/npc/functions/quest-debug/006-ShipQuests_ArpanMoney.txt @@ -15,7 +15,8 @@ function script QuestDebug6 { GenericQuestDebug ShipQuests_ArpanMoney, l("Does not have the quest"), 0, l("Elmo told about money"), 1, - l("Arpan gave money"), 2; + l("Arpan gave money"), 2, + l("Arpan gave clothes"), 3; if (@menuret < 0) { diff --git a/npc/functions/quest-debug/032-ArtisQuests_MonaDad.txt b/npc/functions/quest-debug/032-ArtisQuests_MonaDad.txt index 68ba67fe..bda45b90 100644 --- a/npc/functions/quest-debug/032-ArtisQuests_MonaDad.txt +++ b/npc/functions/quest-debug/032-ArtisQuests_MonaDad.txt @@ -14,7 +14,8 @@ function script QuestDebug32 { GenericQuestDebug ArtisQuests_MonaDad, l("Does not have the quest"), 0, - l("Mona's dad is missing"), 1; + l("Mona's dad is missing"), 1, + l("Mona's dad was rescued"), 3; if (@menuret < 0) { diff --git a/npc/functions/quest-debug/033-Artis_Legion_Progress.txt b/npc/functions/quest-debug/033-Artis_Legion_Progress.txt index c4ea5558..ff6f1d16 100644 --- a/npc/functions/quest-debug/033-Artis_Legion_Progress.txt +++ b/npc/functions/quest-debug/033-Artis_Legion_Progress.txt @@ -19,7 +19,8 @@ function script QuestDebug33 { l("Finished training"), 2, l("Sent to battle"), 3, l("Finished battle"), 4, - l("Sent to Q'Anon"), 5; + l("Sent to Q'Anon"), 5, + l("Indefinite Traning"), 6; if (@menuret < 0) { diff --git a/npc/functions/quest-debug/034-ArtisQuests_TrainingLegion.txt b/npc/functions/quest-debug/034-ArtisQuests_TrainingLegion.txt new file mode 100644 index 00000000..ba72fd07 --- /dev/null +++ b/npc/functions/quest-debug/034-ArtisQuests_TrainingLegion.txt @@ -0,0 +1,28 @@ +// Training Legion quest +// Authors: +// omatt + +function script QuestDebug34 { + do + { + clear; + setnpcdialogtitle l("Quest debug"); + mes "ArtisQuests_TrainingLegion"; + mes "---"; + mes l("Quest state: @@", getq(ArtisQuests_TrainingLegion)); + next; + + GenericQuestDebug ArtisQuests_TrainingLegion, + l("Does not have the quest"), 0, + l("Finished sword training"), 1, + l("Finished bow training"), 2, + l("Both sword and bow training are finished"), 3, + l("Skill training finished, end of quest"), 4; + + if (@menuret < 0) + { + return; + } + + } while (1); +} diff --git a/npc/functions/quest-debug/042-General_Brotherhood.txt b/npc/functions/quest-debug/042-General_Brotherhood.txt new file mode 100644 index 00000000..3eb3683b --- /dev/null +++ b/npc/functions/quest-debug/042-General_Brotherhood.txt @@ -0,0 +1,27 @@ +// Mona quest debug +// Authors: +// gumi +// monwarez +// jesusalva + +function script QuestDebug42 { + do + { + clear; + setnpcdialogtitle l("Quest debug"); + mes "General_Brotherhood"; + mes "---"; + mes l("Quest state: @@", getq(General_Brotherhood)); + next; + + GenericQuestDebug General_Brotherhood, + l("Does not have the quest"), 0, + l("Contacted by Sopiahalla"), 1; + + if (@menuret < 0) + { + return; + } + + } while (1); +} diff --git a/npc/functions/scoreboards.txt b/npc/functions/scoreboards.txt new file mode 100644 index 00000000..0dd54b23 --- /dev/null +++ b/npc/functions/scoreboards.txt @@ -0,0 +1,218 @@ +// Moubootaur Legends Script +// Author: +// Jesusalva +// Description: +// Leaderboards + +// Scoreboard functions +function script HallOfGuild { + mes ""; + mes l("##BHall Of Guild Level: TOP5##b"); + mesf("1. %s (%d)", $@hoguild_name$[0], $@hoguild_value[0]); + mesf("2. %s (%d)", $@hoguild_name$[1], $@hoguild_value[1]); + mesf("3. %s (%d)", $@hoguild_name$[2], $@hoguild_value[2]); + mesf("4. %s (%d)", $@hoguild_name$[3], $@hoguild_value[3]); + mesf("5. %s (%d)", $@hoguild_name$[4], $@hoguild_value[4]); + return; +} + +function script HallOfFortune { + mes ""; + mes l("##BHall Of Fortune: TOP15##b"); + mesf("1. %s (%s E)", $@hofortune_name$[0],format_number($@hofortune_value[0])); + mesf("2. %s (%s E)", $@hofortune_name$[1],format_number($@hofortune_value[1])); + mesf("3. %s (%s E)", $@hofortune_name$[2],format_number($@hofortune_value[2])); + mesf("4. %s (%s E)", $@hofortune_name$[3],format_number($@hofortune_value[3])); + mesf("5. %s (%s E)", $@hofortune_name$[4],format_number($@hofortune_value[4])); + mesf("6. %s (%s E)", $@hofortune_name$[5],format_number($@hofortune_value[5])); + mesf("7. %s (%s E)", $@hofortune_name$[6],format_number($@hofortune_value[6])); + mesf("8. %s (%s E)", $@hofortune_name$[7],format_number($@hofortune_value[7])); + mesf("9. %s (%s E)", $@hofortune_name$[8],format_number($@hofortune_value[8])); + mesf("10. %s (%s E)", $@hofortune_name$[9],format_number($@hofortune_value[9])); + mesf("11. %s (%s E)", $@hofortune_name$[10],format_number($@hofortune_value[10])); + mesf("12. %s (%s E)", $@hofortune_name$[11],format_number($@hofortune_value[11])); + mesf("13. %s (%s E)", $@hofortune_name$[12],format_number($@hofortune_value[12])); + mesf("14. %s (%s E)", $@hofortune_name$[13],format_number($@hofortune_value[13])); + mesf("15. %s (%s E)", $@hofortune_name$[14],format_number($@hofortune_value[14])); + return; +} + +function script HallOfLevel { + mes ""; + mes l("##BHall Of Level: TOP15##b"); + mesf("1. %s (%d)", $@hoblvl_name$[0], $@hoblvl_value[0]); + mesf("2. %s (%d)", $@hoblvl_name$[1], $@hoblvl_value[1]); + mesf("3. %s (%d)", $@hoblvl_name$[2], $@hoblvl_value[2]); + mesf("4. %s (%d)", $@hoblvl_name$[3], $@hoblvl_value[3]); + mesf("5. %s (%d)", $@hoblvl_name$[4], $@hoblvl_value[4]); + mesf("6. %s (%d)", $@hoblvl_name$[5], $@hoblvl_value[5]); + mesf("7. %s (%d)", $@hoblvl_name$[6], $@hoblvl_value[6]); + mesf("8. %s (%d)", $@hoblvl_name$[7], $@hoblvl_value[7]); + mesf("9. %s (%d)", $@hoblvl_name$[8], $@hoblvl_value[8]); + mesf("10. %s (%d)", $@hoblvl_name$[9], $@hoblvl_value[9]); + mesf("11. %s (%d)", $@hoblvl_name$[10], $@hoblvl_value[10]); + mesf("12. %s (%d)", $@hoblvl_name$[11], $@hoblvl_value[11]); + mesf("13. %s (%d)", $@hoblvl_name$[12], $@hoblvl_value[12]); + mesf("14. %s (%d)", $@hoblvl_name$[13], $@hoblvl_value[13]); + mesf("15. %s (%d)", $@hoblvl_name$[14], $@hoblvl_value[14]); + return; +} + +function script HallOfJob { + mes ""; + mes l("##BHall Of Job Level: TOP15##b"); + mesf("1. %s (%d)", $@hojlvl_name$[0], $@hojlvl_value[0]); + mesf("2. %s (%d)", $@hojlvl_name$[1], $@hojlvl_value[1]); + mesf("3. %s (%d)", $@hojlvl_name$[2], $@hojlvl_value[2]); + mesf("4. %s (%d)", $@hojlvl_name$[3], $@hojlvl_value[3]); + mesf("5. %s (%d)", $@hojlvl_name$[4], $@hojlvl_value[4]); + mesf("6. %s (%d)", $@hojlvl_name$[5], $@hojlvl_value[5]); + mesf("7. %s (%d)", $@hojlvl_name$[6], $@hojlvl_value[6]); + mesf("8. %s (%d)", $@hojlvl_name$[7], $@hojlvl_value[7]); + mesf("9. %s (%d)", $@hojlvl_name$[8], $@hojlvl_value[8]); + mesf("10. %s (%d)", $@hojlvl_name$[9], $@hojlvl_value[9]); + mesf("11. %s (%d)", $@hojlvl_name$[10], $@hojlvl_value[10]); + mesf("12. %s (%d)", $@hojlvl_name$[11], $@hojlvl_value[11]); + mesf("13. %s (%d)", $@hojlvl_name$[12], $@hojlvl_value[12]); + mesf("14. %s (%d)", $@hojlvl_name$[13], $@hojlvl_value[13]); + mesf("15. %s (%d)", $@hojlvl_name$[14], $@hojlvl_value[14]); + return; +} + +function script HallOfAcorns { + mes ""; + mes l("##BHall Of Acorns: TOP15##b"); + mesc l("Only %s in storage will be counted.", getitemlink(Acorn)); + mesf("1. %s (%d)", $@hoa_name$[0], $@hoa_value[0]); + mesf("2. %s (%d)", $@hoa_name$[1], $@hoa_value[1]); + mesf("3. %s (%d)", $@hoa_name$[2], $@hoa_value[2]); + mesf("4. %s (%d)", $@hoa_name$[3], $@hoa_value[3]); + mesf("5. %s (%d)", $@hoa_name$[4], $@hoa_value[4]); + mesf("6. %s (%d)", $@hoa_name$[5], $@hoa_value[5]); + mesf("7. %s (%d)", $@hoa_name$[6], $@hoa_value[6]); + mesf("8. %s (%d)", $@hoa_name$[7], $@hoa_value[7]); + mesf("9. %s (%d)", $@hoa_name$[8], $@hoa_value[8]); + mesf("10. %s (%d)", $@hoa_name$[9], $@hoa_value[9]); + mesf("11. %s (%d)", $@hoa_name$[10], $@hoa_value[10]); + mesf("12. %s (%d)", $@hoa_name$[11], $@hoa_value[11]); + mesf("13. %s (%d)", $@hoa_name$[12], $@hoa_value[12]); + mesf("14. %s (%d)", $@hoa_name$[13], $@hoa_value[13]); + mesf("15. %s (%d)", $@hoa_name$[14], $@hoa_value[14]); + return; +} + +// HallOfGame() +function script HallOfGame { + if ($MOST_HEROIC$) + mes l("World hero: %s", $MOST_HEROIC$); + + if ($TREE_PLANTED) + mes l("Planted Trees: %s", format_number($TREE_PLANTED)); // FIXME + + mes l("Players Killed in PvP: %s", format_number($PLAYERS_KILLED)); + mes l("Monsters Killed in PvE: %s", format_number($MONSTERS_KILLED)); + mes ""; + .@s$=(season_direction() == WINTER ? l("Winter") : .@s$); + .@s$=(season_direction() == AUTUMN ? l("Autumn") : .@s$); + .@s$=(season_direction() == SUMMER ? l("Summer") : .@s$); + .@s$=(season_direction() == SPRING ? l("Spring") : .@s$); + mes l("Current Season: %s", .@s$); + // weather ; game time ; world story ; etc. + mes ""; + mes l("Notable mentions and thanks for our [@@https://www.patreon.com/themanaworld|sponsors@@] for their continued support."); + mes ""; + return; +} + + +// Main script handler for scoreboards +- script @scoreboard NPC_HIDDEN,{ + end; +OnHour00: +OnHour01: +OnHour02: +OnHour03: +OnHour04: +OnHour05: +OnHour06: +OnHour07: +OnHour08: +OnHour09: +OnHour10: +OnHour11: +OnHour12: +OnHour13: +OnHour14: +OnHour15: +OnHour16: +OnHour17: +OnHour18: +OnHour19: +OnHour20: +OnHour21: +OnHour22: +OnHour23: +OnInit: + consolemes(CONSOLEMES_DEBUG, "Reloading scoreboards..."); + .@nb = query_sql("select name, zeny from `char` ORDER BY zeny DESC LIMIT 15", $@hofortune_name$, $@hofortune_value); + .@nb = query_sql("select name, base_level from `char` ORDER BY base_level DESC LIMIT 15", $@hoblvl_name$, $@hoblvl_value); + .@nb = query_sql("select name, job_level from `char` ORDER BY job_level DESC LIMIT 15", $@hojlvl_name$, $@hojlvl_value); + .@nb = query_sql("select name, guild_lv from `guild` ORDER BY guild_lv DESC LIMIT 5", $@hoguild_name$, $@hoguild_value); + .@nb = query_sql("SELECT c.name, i.amount FROM `storage` AS i, `char` AS c WHERE i.nameid="+Acorn+" AND i.account_id=c.account_id ORDER BY i.amount DESC LIMIT 15", $@hoa_name$, $@hoa_value); + consolemes(CONSOLEMES_DEBUG, "Scoreboards reloaded"); + if (!$@SCOREBOARD_BIND) { + bindatcmd "scoreboard", "@scoreboard::OnCall", 0, 100, 0; + bindatcmd "scoreboards", "@scoreboard::OnCall", 0, 100, 0; + $@SCOREBOARD_BIND=true; + } + end; + +OnCall: + do { + clear; + //HallOfSponsor(true); + mes l("The Mana World - rEvolt"); + mesc l("All scoreboards are updated hourly."), 1; + mes ""; + select + l("Hall Of Fortune"), + l("Hall Of Base Level"), + l("Hall Of Job Level"), + l("Hall Of Guilds"), + l("Hall Of Acorns"), + l("Game Statistics"), + l("Quit"); + mes ""; + switch (@menu) { + case 1: + HallOfFortune(); + next; + break; + case 2: + HallOfLevel(); + next; + break; + case 3: + HallOfJob(); + next; + break; + case 4: + HallOfGuild(); + next; + break; + case 5: + HallOfAcorns(); + next; + break; + case 6: + HallOfGame(); + next; + break; + default: + close; + } + } while (true); + end; +} + + diff --git a/npc/functions/skills.txt b/npc/functions/skills.txt new file mode 100644 index 00000000..568c97d9 --- /dev/null +++ b/npc/functions/skills.txt @@ -0,0 +1,13 @@ +// The Mana World scripts. +// Author: +// The Mana World Team +// Description: +// Controls script-based skills (which are rare); + +function script SkillInvoked { + // Record to database that you used the skill + skillInvoke[@skillId] = skillInvoke[@skillId] + 1; + + return; +} + diff --git a/npc/functions/spotlight.txt b/npc/functions/spotlight.txt new file mode 100644 index 00000000..fb0c697e --- /dev/null +++ b/npc/functions/spotlight.txt @@ -0,0 +1,92 @@ +// Evol functions. +// Author: +// Jesusalva +// Micksha +// Description: +// Update spotlight on caves +// Variables: +// 2 - the darkest mask +// 4 - the average mask +// 8 - the lightest mask + +// forced_update - if set to true, will ignore if the map is known as valid +// (required for instance maps) +// updateSpotlight ( {forced_update} ) +function script updateSpotlight { + // A small delay of 80 ms in case player is changing map + // It will be cast twice when switching caves. This sleep prevents obscure bugs. + sleep2(80); + + getmapxy(.@m$, .@x, .@y, 0); + + // Is your map valid (or is the check skipped) + if (!getarg(0,false)) + { + if (strpos(getmapname(), "-3-") < 0) + return; + } + + // Retrieve default map masks + .@ms=getmapmask(.@m$); + + // Which equipments provide bonuses? + setarray .@b_head, CandleHelmet; + setarray .@b_weapon, ManaTorch, TrainingWand, Torch; + + // Calc your lighting score (it should NOT start on zero) + .@score=1; + if (array_find(.@b_head, getequipid(EQI_HEAD_TOP)) >= 0) + .@score+=1; + if (array_find(.@b_weapon, getequipid(EQI_HAND_R)) >= 0) + .@score+=1; + // TODO: Lighting scrolls + + //debugmes "Score: %d", .@score; + //debugmes "Equips: %d and %d", getequipid(EQI_HEAD_TOP), getequipid(EQI_HAND_R); + //debugmes "Headvalue: %d", .@b_head[0]; + //debugmes "Weappnvalue: %d, %d, %d", .@b_weapon[0], .@b_weapon[1], .@b_weapon[2]; + // Sanitize score + .@score=min(3, .@score); + + // Calculate and send new map mask + .@ms=.@ms|(2**.@score); + sendmapmask(.@ms); + return; +} + +// MAIN FUNCTION - DO NOT REMOVE +// Every NPC will be duplicating this one +001-3-0,0,0,0 script #SpotlightMaster NPC_HIDDEN,0,0,{ +OnTouch: + updateSpotlight(true); + end; +} + + +// I'm too lazy to do this in different files and in the right spot..... + +// npc/001-3-0/_warps.txt +001-3-0,196,35,0 duplicate(#SpotlightMaster) #SPOT001-3-0_196_35 NPC_HIDDEN,2,2 +001-3-0,172,41,0 duplicate(#SpotlightMaster) #SPOT001-3-0_172_41 NPC_HIDDEN,2,2 +001-3-0,162,40,0 duplicate(#SpotlightMaster) #SPOT001-3-0_162_40 NPC_HIDDEN,2,2 +001-3-0,198,60,0 duplicate(#SpotlightMaster) #SPOT001-3-0_198_60 NPC_HIDDEN,2,2 +001-3-0,152,55,0 duplicate(#SpotlightMaster) #SPOT001-3-0_152_55 NPC_HIDDEN,2,2 +001-3-0,85,130,0 duplicate(#SpotlightMaster) #SPOT001-3-0_85_130 NPC_HIDDEN,2,2 + +// npc/001-3-1/_warps.txt +001-3-1,24,58,0 duplicate(#SpotlightMaster) #SPOT001-3-1_24_58 NPC_HIDDEN,2,2 +001-3-1,35,59,0 duplicate(#SpotlightMaster) #SPOT001-3-1_35_59 NPC_HIDDEN,2,2 +001-3-1,30,19,0 duplicate(#SpotlightMaster) #SPOT001-3-1_30_19 NPC_HIDDEN,2,2 + +// npc/001-3-2/_warps.txt +001-3-2,30,117,0 duplicate(#SpotlightMaster) #SPOT001-3-2_30_117 NPC_HIDDEN,2,2 + +// npc/008-3-0/_warps.txt +008-3-0,130,113,0 duplicate(#SpotlightMaster) #SPOT008-3-0_130_113 NPC_HIDDEN,2,2 + +// npc/008-3-1/_warps.txt +008-3-1,34,34,0 duplicate(#SpotlightMaster) #SPOT008-3-1_34_34 NPC_HIDDEN,2,2 + +// npc/008-3-2/_warps.txt +008-3-2,175,18,0 duplicate(#SpotlightMaster) #SPOT008-3-2_175_18 NPC_HIDDEN,2,2 + diff --git a/npc/functions/treasure.txt b/npc/functions/treasure.txt new file mode 100644 index 00000000..785dd4a0 --- /dev/null +++ b/npc/functions/treasure.txt @@ -0,0 +1,134 @@ +// Moubootaur Legends functions. +// Author: +// Jesusalva +// Description: +// Random Treasure Box Utils + +function script TreasureBox { + .@id=getnpcid(); + if (RNGTREASURE_DATE[.@id] > gettimetick(2)) { + mesc l("The chest is unlocked and empty."); + close; + } + + mesc l("Open the chest?"); + mesc l("Cost: 1 %s", getitemlink(TreasureKey)), 1; + if (!countitem(TreasureKey)) + close; + next; + if (askyesno() == ASK_NO) + close; + + delitem TreasureKey, 1; + mesc l("You open the chest!"); + RNGTREASURE_DATE[.@id]=gettimetick(2)+CHEST_WAITTIME; // Minimum 15 minutes + + .@empty=getvariableofnpc(.empty, strnpcinfo(0)); + if (!.@empty) { + TREASURE_OPEN=TREASURE_OPEN+1; + .@t=TREASURE_OPEN; + .@r=rand(0,10000)-(readbattleparam(getcharid(3), UDT_LUK)*2); + + // Select treasure list + // You're warranted a rare (5%) every 25 open chests + // There's also uncommons (20%) and commons (75%) + if (.@t == 1) + .@loot=WoodenBow; + else if (.@t % 25 == 0 || .@r < 500) // Rare: 5% + .@loot=any(AtroposMixture, ElixirOfLife, BigHealing, BigMana, DeathPotion, MagicFeather); + else if (.@r < 2500) // Uncommon: 20% + .@loot=any(FatesPotion, ClothoLiquor, LachesisBrew, RedPlushWine, TreasureMap, MediumHealing, MediumMana); + else // Common: 75% + .@loot=any(Bread, Fungus, Cheese, Aquada, Croconut, PiberriesInfusion, Carrot, SmallHealing, SmallMana); + + + inventoryplace .@loot, 1; + mesc l("You find %s inside!", getitemlink(.@loot)); + getitem .@loot, 1; + } else { + mesc l("You find %s inside!", l("nothing")); + } + return; +} + +// Animation code by Evol Team +// 4144, gumi, Hal9000, Reid +// (Random) Treasure Chest +// Authored by Jesusalva +// Regenerates every 6 hours +001-3-0,0,0,0 script #chest_001-3-0 NPC_CHEST,{ + /* + // Extract the map name - Seems unused + explode(.@ni$, .name$, "_"); + .@map$=.@ni$[1]; + //if (.@map$ == "") debugmes "Error"; + */ + + // Conditionals + if (!.busy) { + TreasureBox(); + + specialeffect(.dir == 0 ? 24 : 25, AREA, getnpcid()); // closed ? opening : closing + .dir = .dir == 0 ? 2 : 6; // closed ? opening : closing + .busy = true; // lock until available again + initnpctimer; + } else { + mesc l("Someone looted this treasure box already..."); + } + close; + +OnTimer160: + .dir = .dir == 6 ? 0 : 4; // closing ? closed : open + end; + +OnTimer500: + // It's closed: Make available and stop timer + if (.dir == 0) { + .busy = false; + stopnpctimer; + } + end; + +// Autoclose +OnTimer60000: + .dir = 6; // closing + specialeffect(25, AREA, getnpcid()); // closing + setnpctimer 0; + end; + +OnInit: + .busy = false; + .distance = 2; + +OnClock0156: +OnClock0756: +OnClock1356: +OnClock1956: + // Try to warp randomly to a walkable spot, up to 20 attempts + // Otherwise, it'll stay where it already is (but will close and refill). + .@e=0; .@x=0; .@y=0; + while (!checkcell(.map$, .@x, .@y, cell_chkpass)) + { + if (.@e == 20) { + .@x=.x; + .@y=.y; + break; + } + // Remember the +20 -20 margin adjustment + .@x = rand2(20, getmapinfo(MAPINFO_SIZE_X, .map$)-20); + .@y = rand2(20, getmapinfo(MAPINFO_SIZE_X, .map$)-20); + ++.@e; + } + .busy=false; + movenpc .name$, .@x, .@y, 0; + end; +} + +// Lets bring some treasure to The Mana World +008-3-4,0,0,0 duplicate(#chest_001-3-0) #chest_008-3-4 NPC_TREASURE +008-3-5,0,0,0 duplicate(#chest_001-3-0) #chest_008-3-5 NPC_TREASURE +008-3-6,0,0,0 duplicate(#chest_001-3-0) #chest_008-3-6 NPC_TREASURE + +012-3-1,0,0,0 duplicate(#chest_001-3-0) #chest_012-3-1 NPC_TREASURE +012-3-3,0,0,0 duplicate(#chest_001-3-0) #chest_012-3-3 NPC_TREASURE + diff --git a/npc/functions/util.txt b/npc/functions/util.txt index 2cb28573..8e263eb0 100644 --- a/npc/functions/util.txt +++ b/npc/functions/util.txt @@ -8,17 +8,19 @@ // season_direction({day, month}) // returns the direction that represents our current season (approximation) -// DOWN: Winter, 21/12 -// DOWNLEFT: Spring, 20/03 -// LEFT: Summer, 21/06 -// UPLEFT: Autumn, 22/09 +// Note: You may also use WINTER/SPRING/SUMMER/AUTUMN constants for scripts +// where the direction is not important, but the season is. (Readability) +// DOWN: Winter, 21/12 WINTER +// DOWNLEFT: Spring, 20/03 SPRING +// LEFT: Summer, 21/06 SUMMER +// UPLEFT: Autumn, 22/09 AUTUMN function script season_direction { - .@current_month = getarg(0, gettime(GETTIME_MONTH)); + .@current_month = getarg(1, gettime(GETTIME_MONTH)); if (.@current_month % 3 == 0) { - .@current_day = getarg(1, gettime(GETTIME_DAYOFMONTH)); + .@current_day = getarg(0, gettime(GETTIME_DAYOFMONTH)); switch (.@current_month) { @@ -36,7 +38,7 @@ function script season_direction { } // This is part of Jesusalva script toolkit to make his life easier when writing -// quests. Many of these are actually redudant functions. +// quests. Many of these are actually redundant functions. // Four different flavours of setq() to quickly preserve old values function script setq1 { @@ -63,14 +65,79 @@ function script setqtime { return; } -// Function to quickly disregard part of getmapxy(). -// If you use this function too much, you'll lose efficiency, and it'll be better -// to use getmapxy() normally to save to temporary variables. -// Can take one optional argument (unittype argument). +// Shortcut for getmapname() function script getmap { - if (getmapxy(.@mapName$, .@xpos, .@ypos, getarg(0,0)) != 0) - return false; - return .@mapName$; + return getmapname(); } +// Returns the player race in plain text +// GETRACE_RACE - returns player race (default) +// GETRACE_SKIN - returns player skin +// GETRACE_FULL - returns player skin + race +// Can take an optional 2nd param with the class +// get_race( {Flag, {Class}} ) +function script get_race { + .@m=getarg(0, GETRACE_RACE); + .@g=getarg(1, Class); + // We also allow this to run without player attached for... science. + if (playerattached()) + { + setarray .@allraces$, l("Human"), l("Ukar"), l("Kralog"), + l("Raijin"), l("Kralog"), l("Raijin"), l("Tritan"), + l("Human"), l("Human"), l("Tritan"), l("Ukar"); + setarray .@allskins$, l("Kaizei"), l("Cave"), l("Fire"), + l("Light"), l("Frost"), l("Dark"), l("Sea"), l("Argaes"), + l("Tonori"), l("Lake"), l("Mountain"); + } + else + { + setarray .@allraces$, "Human", "Ukar", "Kralog", "Raijin", + "Kralog", "Raijin", "Tritan", "Human", "Human", "Tritan", "Ukar"; + setarray .@allskins$, "Kaizei", "Cave", "Fire", "Light", + "Frost", "Dark", "Sea", "Argaes", "Tonori", "Lake", "Mountain"; + } + + if (.@m == GETRACE_RACE) + return .@allraces$[.@g]; + else if (.@m == GETRACE_SKIN) + return .@allskins$[.@g]; + else + return .@allskins$[.@g] + " " + .@allraces$[.@g]; +} + +// gettimeparam(GETTIME_X) +// Returns the number of seconds/minutes/hours/days/months/years since 01/01/1970 +// This is for truly daily quests, which doesn't imposes a timed wait in hours +function script gettimeparam { + .@p=getarg(0, GETTIME_MINUTE); + + // Seconds (same as gettimetick(2) - use that instead) + .@t=gettimetick(2); + if (.@p == GETTIME_SECOND) + return .@t; + + // Minutes (default) + .@t=.@t/60; + if (.@p == GETTIME_MINUTE) + return .@t; + + // Hours + .@t=.@t/60; + if (.@p == GETTIME_HOUR) + return .@t; + + // Days + .@t=.@t/24; + if (.@p == GETTIME_DAYOFMONTH) + return .@t; + + // Months (estimative) + .@t=.@t/30; + if (.@p == GETTIME_MONTH) + return .@t; + + // Years (estimative, unused, fallback) + .@t=.@t/12; + return .@t; +} diff --git a/npc/functions/warp.txt b/npc/functions/warp.txt index df7b76b0..46c390ad 100644 --- a/npc/functions/warp.txt +++ b/npc/functions/warp.txt @@ -38,7 +38,7 @@ function script slide_or_warp { if (!isloggedin(.@aid)) { if ((.@aid = playerattached()) == 0) { - debugmes("slide_or_warp: no player attached!"); + consolemes(CONSOLEMES_DEBUG, "slide_or_warp: no player attached!"); return false; } } diff --git a/npc/items/cookie.txt b/npc/items/cookie.txt new file mode 100644 index 00000000..e451e844 --- /dev/null +++ b/npc/items/cookie.txt @@ -0,0 +1,22 @@ +// Evol script. +// Author: +// Jesusalva +// Reid (?) +// Description: +// Prevents cookie from being used for too long + +function script UnequipCookie { + if (getequipid(EQI_HEAD_MID) == DeliciousCookie) + unequip(EQI_HEAD_MID); + return; +} + +- script #DeliciousCookie NPC_HIDDEN,{ + end; + +OnUnequip: + UnequipCookie(); + end; + +} + diff --git a/npc/items/master_skillbook.txt b/npc/items/master_skillbook.txt index d7e7de14..e00a1abc 100644 --- a/npc/items/master_skillbook.txt +++ b/npc/items/master_skillbook.txt @@ -6,7 +6,7 @@ // Contains master skills which can only be learnt after killing boss // See also: <link to tmw forum topic> // Notes: -// Not exactly equal as Elvano proposal. I actually care for restrictions you know... +// Not exactly as Elvano proposal. I actually care for restrictions you know... // Variables: // PERMANENT: // MASTERBOOK_PAGES - How many pages your Master Book have. @@ -16,7 +16,7 @@ // TEMPORARY: // @mb_BossId - Contains the MobID of the boss your party killed. // @mb_SkillId - Contains the SkillID which can be learnt with the boss. -// @mb_ItemId - Contains the Ink Id to write (or whatever) +// @mb_ItemId - Contains the Feather Id to write (or whatever) // @mb_ItemAm - How many ink is required to write the skill // Remember: @mb_BossId will be reset to zero after 15 seconds from boss death. // Or upon logout. Or when changing maps. Temporary variables aren't reliable. @@ -25,8 +25,8 @@ // Remember: A dialog prevents timer events from happening, but doesn't stops the timer. // TODO: Currently no way to get skill name from database (add getskillinfo() to server-plugin please) // TODO: Reset @mb_* when register_skill() finish -// TODO: Add Magic Ink -// TODO: When another party/player kills the boss, book should say so. +// TODO: You cannot get Magic Feather anywhere in the game (yet) +// TODO: See if the time (15s) is enough. - script #MasterBook NPC_HIDDEN,{ @@ -35,19 +35,30 @@ setnpcdialogtitle l(.book_name$); + // If boss is set, but is negative, this means somebody else defeated it + if (@mb_BossId < 0) + { + mesc l("You did not defeat the boss, you can't learn any skills."); + @mb_BossId=0; + close; + } + + // Report the boss you killed, and the boss level .@mb_lvl=strmobinfo(3, @mb_BossId); mesc l("You just defeated the following boss: @@ (Lv. @@)", strmobinfo(1, @mb_BossId), .@mb_lvl); - // Check if all reqs are met + // The boss must have a skill if (!@mb_SkillId) { mesc l("But there is no skill to be learnt from this boss."); + @mb_BossId=0; close; } // You must have free pages if (array_entries(MASTERBOOK_SKILL) >= MASTERBOOK_PAGES) { mesc l("But you ran out of empty pages on this book."); + @mb_BossId=0; close; } // TODO: Party Level Range @@ -55,12 +66,14 @@ if (BaseLevel+30 < .@mb_lvl) { mesc l("But you are out of the boss level range."); + @mb_BossId=0; close; } // You must have enough materials if (countitem(@mb_ItemId) < @mb_ItemAm) { mesc l("But you do not have enough Magic Ink. (You need: @@ @@)", @mb_ItemAm, getitemlink(@mb_ItemId)); + //@mb_BossId=0; close; } @@ -79,6 +92,7 @@ closeclientdialog; dispbottom l("You have learnt the skill."); } + @mb_BossId=0; close; } diff --git a/npc/items/shovel.txt b/npc/items/shovel.txt index 81c0d22e..ac1cd50c 100644 --- a/npc/items/shovel.txt +++ b/npc/items/shovel.txt @@ -1,6 +1,7 @@ // Evol scripts. // Author: // Travolta +// Jesusalva // Description: // NPC to use shovel (dig, bury etc) @@ -9,10 +10,12 @@ function CheckDigLocation { getmapxy(.@map$, .@x, .@y, 0); - if (getunits(BL_NPC, .@units, 1, .@map$, .@x - 1, .@y, .@x + 1, .@y + 1)) - { - dispbottom(l("You cannot bury under a NPC!")); - return false; + if (.@map$ != "001-1") { + if (getunits(BL_NPC, .@units, 1, .@map$, .@x - 1, .@y, .@x + 1, .@y + 1)) + { + dispbottom(l("You cannot bury under a NPC!")); + return false; + } } // TODO: we should have a way to check for GROUNDTOP collisions too @@ -36,7 +39,7 @@ function AddDigRect { if (getargcount() < 5) { - debugmes "usage: AddDigRect(map$,x1,y1,x2,y2)"; + consolemes(CONSOLEMES_ERROR, "usage: AddDigRect(map$,x1,y1,x2,y2)"); return 0; } .@map$ = str(getarg(0)); @@ -53,6 +56,13 @@ return 1; } + function AddMapDigRect { + .@m$=getarg(0); + .@x=getmapinfo(MAPINFO_SIZE_X, .@m$)-20; + .@y=getmapinfo(MAPINFO_SIZE_Y, .@m$)-20; + return AddDigRect(.@m$, 20, 20, .@x, .@y); + } + function PlayerIsTired { if (is_evtc()) return false; // event coordinators are never tired @@ -96,21 +106,28 @@ } function Bury { - narrator(S_FIRST_BLANK_LINE | S_LAST_NEXT, - l("What would you like to bury?")); + narrator S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, l("What would you like to bury?"); + .@items$ = ""; + + mes "##B" + l("Drag and drop an item from your inventory.") + "##b"; - mes("##B" + l("Drag and drop an item from your inventory.") + "##b"); .@id = requestitem(); - // You cannot bury: Items you don't have, your shovel, Bound Items, and items which are not dropped by any mobs. - // The "item not dropped by any mob" is temporary, and should be replaced by "items with trade restrictions" later. [JESUS] - // event coordinators can always bury - if (!is_evtc() && (.@id < 1 || countitem(.@id) < 1 || - compare(getitemname(.@id), "shovel") || checkbound(.@id) || - !getiteminfo(.@id, ITEMINFO_MAXCHANCE))) - { - mesc(l("You cannot bury this item!")); - return false; + // If ID is invalid, there's not enough items, it is an Iron Shovel, it is bound = Cannot bury + // NOBODY bypass notrade check. (ITR_NONE is 0) + if (.@id < 1) close; + if (.@id < 1 || countitem(.@id) < 1 || .@id == IronShovel || checkbound(.@id) || + (!getiteminfo(.@id, ITEMINFO_TRADE)) + ) { + @ShovelLastUsed = 0; + if (.@id == IronShovel || .@id == SteelShovel || checkbound(.@id)) + mesc l("You cannot bury this item!"); + else if (!getiteminfo(.@id, ITEMINFO_TRADE)) + mesc l("This item is too precious, you cannot part with it!"); + else + mesc l("You give up."); + close; + return; } .@amount = 1; @@ -193,7 +210,17 @@ OnHour00: OnInit: .PlayerTiredTime = 20; - AddDigRect("001-1", 172, 26, 200, 48); + + // Partial maps + AddDigRect("001-1", 172, 26, 200, 48); + AddDigRect("008-1-1", 32, 42, 46, 88); + AddDigRect("008-1-2", 40, 52, 114, 146); + AddDigRect("012-1", 44, 21, 139, 47); + + // Whole maps + AddMapDigRect("008-1"); + AddMapDigRect("008-3-5"); + AddMapDigRect("012-3-1"); end; } @@ -201,7 +228,7 @@ OnInit: function script shovel_addquest { if (getargcount() < 4) { - debugmes "usage: shovel_addquest(map$,x,y,func$)"; + consolemes(CONSOLEMES_ERROR, "usage: shovel_addquest(map$,x,y,func$)"); return 0; } .@map$ = str(getarg(0)); @@ -219,7 +246,7 @@ function script shovel_addquest { function script shovel_adddigrect { if (getargcount() < 5) { - debugmes "usage: shovel_adddigrect(map$,x1,y1,x2,y2)"; + consolemes(CONSOLEMES_ERROR, "usage: shovel_adddigrect(map$,x1,y1,x2,y2)"); return 0; } .@map$ = str(getarg(0)); @@ -235,3 +262,97 @@ function script shovel_adddigrect { set getvariableofnpc(.WorldDigRect_y2[.@size], strnpcinfo(3)), .@y2; return 1; } + +// [Treasure Map] functions + +function script shovel_getcity { + .@a$=getarg(0); + + // else is not required (return prevails) + if (.@a$ == "001-1") + return l("Artis Hills"); + if (.@a$ == "008-1") + return l("East Woodlands"); + if (.@a$ == "008-1-1") + return l("West Woodland Beach"); + if (.@a$ == "008-1-2") + return l("Swamps"); + if (.@a$ == "008-3-5") + return l("Hurnscald Bandit Cave"); + if (.@a$ == "012-1") + return l("Candor North"); + if (.@a$ == "012-3-1") + return l("Candor Main Cave"); + + return .@a$; +} + +function script shovel_randomtreasure { + .@id=any(TreasureKey,CoinBag,CoinBag,CoinBag,Coal, + Diamond,Ruby,Emerald,Sapphire,Topaz,Amethyst, + MaggotSlimePotion, LargeMana, LargeHealing); + delitem TreasureMap, 1; + .@amount=any(1,1,2); + // Very Commons + if (.@id == CoinBag || .@id == MaggotSlimePotion || .@id == TreasureKey) + .@amount+=any(0,1,0,1,2); + // Super commons + if (.@id == LargeMana || .@id == LargeHealing) + .@amount+=rand2(0,8); + // Rares + if (.@id == Coal) + .@amount=1; + getitem .@id, .@amount; + ShovelQuests_AssignedMAP$=""; + ShovelQuests_AssignedX=0; + ShovelQuests_AssignedY=0; + + mesn strcharinfo(0); + mesc l("You found something!"); + mesc l("It's %d %s.", .@amount, getitemlink(.@id)); + next; + closeclientdialog; + return; +} + +function script shovel_genrandtreasure { + .@m$=any("008-1", "008-1-1", "008-1-2", "008-3-5", + "012-1", "012-3-1"); + + // Prepare good defaults + .@x1=.@y1=20; + .@x2=getmapinfo(MAPINFO_SIZE_X, .@m$)-20; + .@y2=getmapinfo(MAPINFO_SIZE_Y, .@m$)-20; + + // Default overrides + if (.@m$ == "008-1-1") { + // West Woodland Beach + .@x1=32; .@y1=42; + .@x2=46; .@y2=88; + } else if (.@m$ == "008-1-2") { + // Swamps + .@x1=40; .@y1=52; + .@x2=114; .@y2=146; + } else if (.@m$ == "012-1") { + // Candor North + .@x1=44; .@y1=139; + .@x2=21; .@y2=47; + } + + // Dangerous, but I never had issues with this + do { + .@x=rand2(.@x1, .@x2); + .@y=rand2(.@y1, .@y2); + } while (!checkcell(.@m$, .@x, .@y, cell_chkpass)); + + // Success + if (checkcell(.@m$, .@x, .@y, cell_chkpass)) { + shovel_addquest(.@m$, .@x, .@y, "shovel_randomtreasure"); + ShovelQuests_AssignedMAP$=shovel_getcity(.@m$); + ShovelQuests_AssignedX=.@x; + ShovelQuests_AssignedY=.@y; + } + return; +} + + diff --git a/npc/scripts.conf b/npc/scripts.conf index a7f39836..f14c29d0 100644 --- a/npc/scripts.conf +++ b/npc/scripts.conf @@ -12,6 +12,7 @@ "npc/functions/RNGesus.txt", "npc/functions/math.txt", "npc/functions/warp.txt", +"npc/functions/gender.txt", // Misc functions "npc/functions/main.txt", @@ -20,14 +21,15 @@ "npc/functions/clientversion.txt", "npc/functions/doors.txt", "npc/functions/goodbye.txt", +"npc/functions/global_event_handler.txt", "npc/functions/hammocks.txt", "npc/functions/harbours.txt", "npc/functions/hello.txt", "npc/functions/inventoryplace.txt", "npc/functions/legiontalk.txt", -"npc/functions/marriage.txt", "npc/functions/npcmove.txt", "npc/functions/masks.txt", +"npc/functions/spotlight.txt", "npc/functions/openbook.txt", "npc/functions/questgen.txt", "npc/functions/sailordialogue.txt", @@ -45,10 +47,13 @@ "npc/functions/riddle.txt", "npc/functions/bank.txt", "npc/functions/confused-tree-dict.txt", -"npc/functions/util.txt", +"npc/functions/treasure.txt", // May rely on custom functions and thus must be handled by last +"npc/functions/util.txt", +"npc/functions/scoreboards.txt", "npc/functions/manhole.txt", +"npc/functions/skills.txt", // quest debug "npc/functions/quest-debug/functions.txt", @@ -86,7 +91,7 @@ "npc/functions/quest-debug/031-General_Janus.txt", "npc/functions/quest-debug/032-ArtisQuests_MonaDad.txt", "npc/functions/quest-debug/033-Artis_Legion_Progress.txt", -// 034: ??? +"npc/functions/quest-debug/034-ArtisQuests_TrainingLegion.txt", // 035: ??? "npc/functions/quest-debug/036-HurnscaldQuests_Hinnak.txt", "npc/functions/quest-debug/037-HurnscaldQuests_Soup.txt", @@ -94,8 +99,10 @@ "npc/functions/quest-debug/039-HurnscaldQuests_ForestBow.txt", "npc/functions/quest-debug/040-HurnscaldQuests_WoodenShield.txt", "npc/functions/quest-debug/041-General_Cooking.txt", +"npc/functions/quest-debug/042-General_Brotherhood.txt", // Item functions +"npc/items/cookie.txt", "npc/items/croconut.txt", "npc/items/shovel.txt", "npc/items/rand_sc_heal.txt", @@ -103,11 +110,13 @@ "npc/items/master_skillbook.txt", // custom atcommands +"npc/commands/gm.txt", "npc/commands/music.txt", "npc/commands/warp.txt", "npc/commands/zeny.txt", "npc/commands/motd-debug-text.txt", "npc/commands/motd.txt", +"npc/commands/mobinfo.txt", "npc/commands/scheduled-broadcasts.txt", "npc/commands/rate-management.txt", "npc/commands/event.txt", @@ -118,6 +127,8 @@ "npc/commands/debug.txt", "npc/commands/super-menu.txt", "npc/commands/resync.txt", +"npc/commands/python.txt", +"npc/commands/gender.txt", // config script "npc/config/hairstyle_config.txt", diff --git a/npc/sec_pri/_import.txt b/npc/sec_pri/_import.txt new file mode 100644 index 00000000..e6c274dd --- /dev/null +++ b/npc/sec_pri/_import.txt @@ -0,0 +1,3 @@ +// Map sec_pri: Jail +// This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/sec_pri/redirect.txt", diff --git a/npc/sec_pri/redirect.txt b/npc/sec_pri/redirect.txt new file mode 100644 index 00000000..bd46b987 --- /dev/null +++ b/npc/sec_pri/redirect.txt @@ -0,0 +1,12 @@ +// The Mana World Script +// Author: +// Jesusalva +// Controls additional jail cells + +sec_pri,49,75,0 script #JailIntWarp NPC_HIDDEN,0,0,{ + end; + +OnTouch: + slide any(29, 33), 75; + end; +} diff --git a/npc/test/_import.txt b/npc/test/_import.txt index 6c7f7e71..69324674 100644 --- a/npc/test/_import.txt +++ b/npc/test/_import.txt @@ -8,6 +8,5 @@ "npc/test/npc4.txt", "npc/test/npc5.txt", "npc/test/npc6.txt", -"npc/test/npcmarriage.txt", "npc/test/test1.txt", "npc/test/test2.txt", diff --git a/npc/test/npc1.txt b/npc/test/npc1.txt index 38a03142..4754e4ed 100644 --- a/npc/test/npc1.txt +++ b/npc/test/npc1.txt @@ -704,14 +704,10 @@ OnWhisperGlobal: mes "cmd: " + @whispervar0$; close; -OnSkillInvoke: - skillInvoke[@skillId] = skillInvoke[@skillId] + 1; - end; - OnReadyCheck: - debugmes "OnReadyCheck"; + consolemes(CONSOLEMES_DEBUG, "OnReadyCheck"); $@bgid1 = waitingroom2bg("testbg", 10, 10, "bgnpc1::OnLogout","bgnpc1:OnDie"); - debugmes "bgid=" + str($@bgid1); + consolemes(CONSOLEMES_DEBUG, "bgid=" + str($@bgid1)); setbgteam $@bgid1, 1; bg_warp $@bgid1, "testbg", 10, 10; } diff --git a/npc/test/npcmarriage.txt b/npc/test/npcmarriage.txt deleted file mode 100644 index 1b7497bd..00000000 --- a/npc/test/npcmarriage.txt +++ /dev/null @@ -1,19 +0,0 @@ -// Evol scripts. -// Author: -// 4144 -// Description: -// npc marriage - -test,25,14,0 script marriage1 NPC_PLAYER,{ - marriagemain(); - close; - -OnTimer30000: - marriagecheck(); - end; - -OnInit: - .sex = G_MALE; - .distance = 3; - initnpctimer; -} |