diff options
author | Jesusaves <cpntb1@ymail.com> | 2020-12-06 19:30:53 +0000 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2020-12-06 19:30:53 +0000 |
commit | 5195432edc23040407c7ae84061e9db0c2cbebf1 (patch) | |
tree | 91a042a0d2a9735e2907bb4daec4c3b0dd368721 /npc/functions | |
parent | 3db95edc1d79e290c3d18ec6f2f6af9b42b89396 (diff) | |
download | serverdata-5195432edc23040407c7ae84061e9db0c2cbebf1.tar.gz serverdata-5195432edc23040407c7ae84061e9db0c2cbebf1.tar.bz2 serverdata-5195432edc23040407c7ae84061e9db0c2cbebf1.tar.xz serverdata-5195432edc23040407c7ae84061e9db0c2cbebf1.zip |
* Lena's quest
* Add Inn to towns
* Add Merchant Guild to towns
* Add Soul Menhir to Towns
* Add Barbers to towns
* Add General Store to towns
* Some work for blacksmith & tailoring
* Kadiya's placeholder (no quest for r1, sorry D:)
* Anwar Quest
* Joaquim Quest
* Updates on Artis Blacksmith and Julia's intro
* some work on fishing spots
* Bosses and Master Skill Book ("about" one per region)
* Asphodel Moors population (no quests and incomplete)
Diffstat (limited to 'npc/functions')
-rw-r--r-- | npc/functions/barber.txt | 67 | ||||
-rw-r--r-- | npc/functions/crafting.txt | 4 | ||||
-rw-r--r-- | npc/functions/fishing.txt | 112 | ||||
-rw-r--r-- | npc/functions/main.txt | 82 | ||||
-rw-r--r-- | npc/functions/music.txt | 58 | ||||
-rw-r--r-- | npc/functions/resetstatus.txt | 117 | ||||
-rw-r--r-- | npc/functions/soul-menhir.txt | 75 |
7 files changed, 492 insertions, 23 deletions
diff --git a/npc/functions/barber.txt b/npc/functions/barber.txt index 3d2e3014..54402750 100644 --- a/npc/functions/barber.txt +++ b/npc/functions/barber.txt @@ -7,6 +7,8 @@ // Description: // Function for supporting barber NPC. +// BarberSayStyle({what}) +// what: 1 = Style; 2 = Color; 3 = Style + Color in dialog function script BarberSayStyle { .@get_color = getlook(LOOK_HAIR_COLOR); @@ -14,7 +16,7 @@ function script BarberSayStyle { .@style_name$ = $@hairstyle$[.@get_look]; .@color_name$ = $@haircolor$[.@get_color]; - switch (getarg(0)) + switch (getarg(0, 3)) { case 1: message strcharinfo(0), l("@@", .@style_name$); @@ -59,7 +61,7 @@ function script BarberChangeStyle { } while (.@rand_hair == getlook(LOOK_HAIR)); setlook LOOK_HAIR, .@rand_hair; setlook LOOK_HAIR_COLOR, getlook(LOOK_HAIR_COLOR); - BarberSayStyle 1; + BarberSayStyle(1); break; default: // and here "- 1" because the first choice is taken by the random @@ -98,7 +100,7 @@ function script BarberChangeColor { .@rand_color = rand(0, .@hairsizearray); } while (.@rand_color == getlook(LOOK_HAIR_COLOR)); setlook LOOK_HAIR_COLOR, .@rand_color; - BarberSayStyle 2; + BarberSayStyle(2); break; default: setlook LOOK_HAIR_COLOR, (@menu - 2); @@ -138,9 +140,9 @@ function script BarberChangeRace { mes l("What's your race?"); menuint - get_race(GETRACE_FULL, KaizeiViro), KaizeiViro, - get_race(GETRACE_FULL, ArgaesViro), ArgaesViro, - get_race(GETRACE_FULL, TonoriViro), TonoriViro, + get_race(GETRACE_FULL, KaizeiTalpan), KaizeiTalpan, + get_race(GETRACE_FULL, ArgaesTalpan), ArgaesTalpan, + get_race(GETRACE_FULL, TonoriTalpan), TonoriTalpan, get_race(GETRACE_FULL, CaveUkar), CaveUkar, get_race(GETRACE_FULL, MountainUkar), MountainUkar, get_race(GETRACE_FULL, SeaTritan), SeaTritan, @@ -163,3 +165,56 @@ function script BarberChangeRace { jobchange(@menuret); // STUPID idea, but imposed by Hercules return; } + +// Jack of all trades +// Barber({intro=True}) +function script Barber { + if (getarg(0, true)) { + mesn; + mesq lg("Hello, young lady.", "Hello, young man."); + next; + } + mesq l("What would you like me to do?"); + next; + do + { + select + l("What is my current hairstyle and hair color?"), + l("I'd like to get a different style."), + l("Can you do something with my color?"), + l("How about changing my body type?"), + l("I'm fine for now, thank you."); + + switch (@menu) + { + case 1: + BarberSayStyle(); + break; + case 2: + BarberChangeStyle; + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Enjoy your new style."), + l("Anything else?"); + break; + case 3: + BarberChangeColor; + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("I hope you like this color."), + l("Anything else?"); + break; + case 4: + BarberChangeBodyType(); + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("You look fantastic."), + l("Anything else?"); + break; + case 5: + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Feel free to come visit me another time."); + + goodbye; + } + } while (true); + return; +} + diff --git a/npc/functions/crafting.txt b/npc/functions/crafting.txt index 05a9d9a6..fa5fa84e 100644 --- a/npc/functions/crafting.txt +++ b/npc/functions/crafting.txt @@ -1,6 +1,7 @@ // Moubootaur Legends Script // Author: // Jesusalva +// Gumi // Description: // Smith System (Unified) // Notes: @@ -80,7 +81,8 @@ function script SmithSystem { // I'm using the same EXP formula from Moubootaur Legends // Which is based on the item sell price .@xp=getiteminfo(.@it, ITEMINFO_SELLPRICE); - getexp .@xp+BaseLevel, (.@xp/3)+BaseLevel+JobLevel; + quest_xp(.@lv+10, .@xp+BaseLevel); + quest_jxp(.@lv+10, (.@xp/3)+BaseLevel+JobLevel); .success=true; } else { .success=false; diff --git a/npc/functions/fishing.txt b/npc/functions/fishing.txt index fee0acb7..4dcb4882 100644 --- a/npc/functions/fishing.txt +++ b/npc/functions/fishing.txt @@ -3,6 +3,8 @@ // gumi // omatt // Travolta +// Reid +// Jesusalva // Description: // Fishing functions. // Variable @@ -287,3 +289,113 @@ function script fishing { return 0; } + + +//////////////////// +// Fishing Templates + +// #fish_basic - has only carps (freshwater) +- script #fish_basic NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + GrassCarp, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5000; // must catch the fish within X ms after the line sinks + .wait_time_min = 4000; // min amount of time to wait for the line to sink + .wait_time_max = 18000; // max amount of time to wait for the line to sink + end; +} + + +// #fish_seawater - has only tuna +- script #fish_seawater NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + Tuna, 15, + Salmon, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 4000; // must catch the fish within X ms after the line sinks + .wait_time_min = 8000; // min amount of time to wait for the line to sink + .wait_time_max = 18000; // max amount of time to wait for the line to sink + end; +} + + + +// #fish_river - A balanced fishing spot for Woodlands (Trout) +- script #fish_river NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + Trout, 20, + GrassCarp, 5, + Salmon, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5500; // must catch the fish within X ms after the line sinks + .wait_time_min = 5000; // min amount of time to wait for the line to sink + .wait_time_max = 16000; // max amount of time to wait for the line to sink + end; +} + + + + +// #fish_river2 - A balanced fishing spot for Candor (Salmon) +- script #fish_river2 NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + Salmon, 20, + GrassCarp, 5, + Trout, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5500; // must catch the fish within X ms after the line sinks + .wait_time_min = 5000; // min amount of time to wait for the line to sink + .wait_time_max = 16000; // max amount of time to wait for the line to sink + end; +} + + + + +// #fish_frozen - A fishing spot with cold waters (for Nivalis) +- script #fish_frozen NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + Codfish, 20, + GrassCarp, 5, + Salmon, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5500; // must catch the fish within X ms after the line sinks + .wait_time_min = 5000; // min amount of time to wait for the line to sink + .wait_time_max = 16000; // max amount of time to wait for the line to sink + end; +} + diff --git a/npc/functions/main.txt b/npc/functions/main.txt index 3be6b6fb..28b61c7c 100644 --- a/npc/functions/main.txt +++ b/npc/functions/main.txt @@ -289,7 +289,7 @@ function script get_race { // We also allow this to run without player attached for... science. if (playerattached()) { - setarray .@allraces$, l("Viro"), l("Viro"), l("Viro"), + setarray .@allraces$, l("Human"), l("Human"), l("Human"), l("Ukar"), l("Ukar"), l("Tritan"), l("Tritan"), l("Raijin"), l("Raijin"), @@ -302,7 +302,7 @@ function script get_race { } else { - setarray .@allraces$, ("Viro"), ("Viro"), ("Viro"), + setarray .@allraces$, ("Human"), ("Human"), ("Human"), ("Ukar"), ("Ukar"), ("Tritan"), ("Tritan"), ("Raijin"), ("Raijin"), @@ -365,3 +365,81 @@ function script getmap { return getmapname(); } +// Quest Rewards +// quest_xp(maxLevel, reward, {multiplier=1}) +function script quest_xp { + //.@minLevel=getarg(0); + .@maxLevel=getarg(0); + .@reward=getarg(1); + .@mult=getarg(2, 1); + if (BaseLevel <= .@maxLevel) { + getexp .@reward*.@mult, 0; + return; + } + // You'll forsake 2% every over level + .@mult*=100; + .@mult-=((BaseLevel - .@maxLevel) * 2); + .@mult=max(10, .@mult); + getexp .@reward*.@mult/100, 0; + return; +} + +// quest_jxp(maxLevel, reward, {multiplier=1}) +function script quest_jxp { + //.@minLevel=getarg(0); + .@maxLevel=getarg(0); + .@reward=getarg(1); + .@mult=getarg(2, 1); + if (BaseLevel < .@maxLevel) { + getexp 0, .@reward*.@mult; + return; + } + // You'll forsake 2% every over level + .@mult*=100; + .@mult-=((BaseLevel - .@maxLevel) * 2); + .@mult=max(10, .@mult); + getexp 0, .@reward*.@mult/100; + return; +} + +// quest_gp(maxLevel, reward, {multiplier=1}) +function script quest_gp { + //.@minLevel=getarg(0); + .@maxLevel=getarg(0); + .@reward=getarg(1); + .@mult=getarg(2, 1); + if (BaseLevel <= .@maxLevel) { + Zeny+=.@reward*.@mult; + return; + } + // You'll forsake 2% every over level + .@mult*=100; + .@mult-=((BaseLevel - .@maxLevel) * 2); + .@mult=max(10, .@mult); + Zeny+=.@reward*.@mult/100; + return; +} + +// quest_item(maxLevel, item, {amount=1}, {bound=0}) +function script quest_item { + //.@minLevel=getarg(0); + .@maxLevel=getarg(0); + .@reward=getarg(1); + .@mult=getarg(2, 1); + .@bind=getarg(3, 0); + // Item will not be obtained if you are overlevel + if (BaseLevel > .@maxLevel && .@mult <= 1) + return; + // If it comes in pairs, you'll only get 1 + if (BaseLevel > .@maxLevel) + .@mult=1; + // Obtain item bound if needed + if (.@bind) + getitembound .@reward, .@mult, .@bind; + else + getitem .@reward, .@mult; + return; +} + + + diff --git a/npc/functions/music.txt b/npc/functions/music.txt index c8937583..18a8fbe7 100644 --- a/npc/functions/music.txt +++ b/npc/functions/music.txt @@ -2,6 +2,7 @@ // Author: // Jesusalva // Gumi +// Ledmitz // Description: // Music functions // @@ -11,18 +12,19 @@ // "jukebox"::HurnscaldPrompt(); → Makes a menuint for selecting hurns tracks // "jukebox"::JukeboxMusic(ID); → Changes music based on prompted ID // "jukebox"::BroadcastMusic(MAP, ID); → Changes music based on prompted ID +// TODO: Check if you have the music unlocked? Bitmask? Array? - script jukebox 32767,{ end; // Helpers public function JukeboxMusic { - changeplayermusic .MUSIC_ARRAY[getarg(0)]; + changeplayermusic $MUSIC_ARRAY$[getarg(0)] + ".ogg"; return; } public function BroadcastMusic { - changemusic getarg(0), .MUSIC_ARRAY[getarg(1)]; + changemusic getarg(0), $MUSIC_ARRAY$[getarg(1)] + ".ogg"; return; } @@ -32,9 +34,10 @@ public function BroadcastMusic { public function HurnscaldPrompt { menuint "Cancel", -1, - "Forest of Birches", 0, - "Adventure Begins", 1, - "Magick Real", 5; + "Johanne - Forest of Birches", 0, + "Artis - Adventure Begins", 1, + "Argaes - Dariunas' Forest", 20, + "Hurnscald - Magick Real", 5; mes ""; if (@menuret == -1) close; @@ -43,15 +46,42 @@ public function HurnscaldPrompt { // Initialize stuff which will be needed OnInit: - .MUSIC_ARRAY[0] = "bartk - in the forest of the birches.ogg"; - .MUSIC_ARRAY[1] = "bartk - the adventure begins.ogg"; - .MUSIC_ARRAY[2] = "eric matyas - ghoulish fun.ogg"; - .MUSIC_ARRAY[3] = "eric matyas - surreal place.ogg"; - .MUSIC_ARRAY[4] = "ezili - ocean sounds.ogg"; - .MUSIC_ARRAY[5] = "magick - real.ogg"; + $MUSIC_ARRAY$[0] = "johanne"; + $MUSIC_ARRAY$[1] = "artis"; + $MUSIC_ARRAY$[2] = "ghoulish"; + $MUSIC_ARRAY$[3] = "surreal"; + $MUSIC_ARRAY$[4] = "ocean"; + $MUSIC_ARRAY$[5] = "real"; + $MUSIC_ARRAY$[6] = "academy"; + $MUSIC_ARRAY$[7] = "bandit"; + $MUSIC_ARRAY$[8] = "barbarians"; + $MUSIC_ARRAY$[9] = "botcheck"; + $MUSIC_ARRAY$[10] = "candor"; + $MUSIC_ARRAY$[11] = "cavesong"; + $MUSIC_ARRAY$[12] = "chilling"; + $MUSIC_ARRAY$[13] = "cloudcall"; + $MUSIC_ARRAY$[14] = "crypt"; + $MUSIC_ARRAY$[15] = "despair"; + $MUSIC_ARRAY$[16] = "dimond"; + $MUSIC_ARRAY$[17] = "explorer"; + $MUSIC_ARRAY$[18] = "faith"; + $MUSIC_ARRAY$[19] = "fire"; + $MUSIC_ARRAY$[20] = "forest"; + $MUSIC_ARRAY$[21] = "graveyard"; + $MUSIC_ARRAY$[22] = "hurns"; + $MUSIC_ARRAY$[23] = "marine"; + $MUSIC_ARRAY$[24] = "mystique"; + $MUSIC_ARRAY$[25] = "nightcall"; + $MUSIC_ARRAY$[26] = "nivalis"; + $MUSIC_ARRAY$[27] = "ocean"; + $MUSIC_ARRAY$[28] = "peace"; + $MUSIC_ARRAY$[29] = "reid"; + $MUSIC_ARRAY$[30] = "sewer"; + $MUSIC_ARRAY$[31] = "store"; + $MUSIC_ARRAY$[32] = "swamp"; + $MUSIC_ARRAY$[33] = "thunderstorm"; + $MUSIC_ARRAY$[34] = "waterlude"; + $MUSIC_ARRAY$[35] = "xmas"; end; } - - - diff --git a/npc/functions/resetstatus.txt b/npc/functions/resetstatus.txt new file mode 100644 index 00000000..bb4b22b4 --- /dev/null +++ b/npc/functions/resetstatus.txt @@ -0,0 +1,117 @@ +// Moubootaur Legends Script. +// Authors: +// Vasily_Makarov (original from Evol) +// Jesusalva +// Description: +// Status Reset NPC utils + +// Reset status and return permanent bonuses +// StatusResetReinvest( {script=True} ) +function script StatusResetReinvest { + /* XXX: Uncommment this for ML Permanent Boost Status Fruit System :XXX + // Compulsory check + if (getarg(0, true)) { + inventoryplace NPCEyes, 6; + } else if (!checkweight(NPCEyes, 6)) { + getitembound StatusResetPotion, 1, 4; + dispbottom l("You cannot carry the fruits."); + end; // Die + } + + // Permanent boosts were now lost, return the fruits + if (STATUSUP_STR) { + getitembound StrengthFruit, STATUSUP_STR, 4; + STATUSUP_STR=0; + } + if (STATUSUP_AGI) { + getitembound AgilityFruit, STATUSUP_AGI, 4; + STATUSUP_AGI=0; + } + if (STATUSUP_VIT) { + getitembound VitalityFruit, STATUSUP_VIT, 4; + STATUSUP_VIT=0; + } + if (STATUSUP_INT) { + getitembound IntelligenceFruit, STATUSUP_INT, 4; + STATUSUP_INT=0; + } + if (STATUSUP_DEX) { + getitembound DexterityFruit, STATUSUP_DEX, 4; + STATUSUP_DEX=0; + } + if (STATUSUP_LUK) { + getitembound LuckFruit, STATUSUP_LUK, 4; + STATUSUP_LUK=0; + } + */ + resetstatus(); + return true; +} + +// Return wasSP on success, 0 on failure +// ConfirmReset( {price} ) +function script ConfirmStatusReset { + if (BaseLevel >= 15) + .@raw_price=(1000-BaseLevel*10+(BaseLevel*18)); + else if (BaseLevel >= 10) + .@raw_price=(BaseLevel*210-(10*210))/(BaseLevel/10); + else + .@raw_price=1; + + if (getarg(0,-1) >= 0) + .@raw_price=getarg(0,-1); + + //mesc l("WARNING: Permanent boosts will return to their fruit form."), 1; + mesc l("WARNING: Status resets cannot be reverted!"), 1; + + switch (select(lg("Yes, I am sure. Please reset my status!"), + lg("I need to think about it..."), + lg("I won't need it, thank you."))) + { + case 1: + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Let me just have a quick look at you. Hm... I will need %d GP to reset your stats.", .@raw_price); + + select + rif(Zeny >= .@raw_price, l("Here, take as much as you need, I have plenty!")), + rif(Zeny > 0 && Zeny < .@raw_price, l("I don't have enough money...")), + rif(Zeny == 0, l("Oh no, I don't have any money on me right now.")), + l("I have to go, sorry."); + + if (@menu > 1) { + return 0; + } + + speech S_FIRST_BLANK_LINE | S_LAST_NEXT, + l("Thank you."), + l("Now stand still... It should not take much time..."); + + // Reset status have an inventorycheck, so we charge later. + .@wasSP = StatusPoint; + StatusResetReinvest(); + + // Nothing to do: Do not charge (eg. you just got the fruits back) + if (StatusPoint == .@wasSP) { + speech S_LAST_NEXT, + l("It seems that you have no status points to reset!"), + l("Come back when you will really need me."); + } else { + Zeny-=.@raw_price; + speech S_LAST_NEXT, + l("Let's see... @@ of your status points have just been reset!", StatusPoint - .@wasSP), + l("Spend it wisely this time."), + l("But you are welcome to reset your stats again! I need the money."); + } + return .@wasSP; + + case 2: + return 0; + case 3: + return 0; + } + //Exception("Unknown Error: ConfirmStatusReset() failed"); + consolemes(CONSOLEMES_ERROR, "Unknown Error: ConfirmStatusReset() failed"); + return 0; + +} + diff --git a/npc/functions/soul-menhir.txt b/npc/functions/soul-menhir.txt new file mode 100644 index 00000000..3d4344c9 --- /dev/null +++ b/npc/functions/soul-menhir.txt @@ -0,0 +1,75 @@ +// Evol scripts. +// Author: +// gumi +// Jesusalva +// Description: +// place of power, mana refills faster when sitting nearby + +- script Soul Menhir NPC_HIDDEN,{ + 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: + @menhir_lock = false; + getmapxy(.@map$, .@x, .@y, UNITTYPE_PC); + + if (.@map$ != .map$ || distance(.x, .y, .@x, .@y) > .refill_distance || + !(issit())) + end; + + heal(0, .refill_rate); + end; + + +OnTimer500: + .@count = getunits(BL_PC, .@units[0], false, .map$, (.x - .refill_distance), + (.y - .refill_distance), (.x + .refill_distance), (.y + .refill_distance)); + + for (.@i = 0; .@i < .@count; ++.@i) + { + if (.@units[.@i] < 0) continue; // pre-check, just in case + deltimer(.name$ + "::OnRefill", .@units[.@i]); + if (gettimer(TIMER_COUNT, .@units[.@i], .name$ + "::OnRefill") > 0 || + getvariableofpc(@menhir_lock, .@units[.@i])) { + continue; + } + set(getvariableofpc(@menhir_lock, .@units[.@i]), true); + addtimer(rand(.refill_timer), .name$ + "::OnRefill", .@units[.@i]); + } + + initnpctimer(); + end; + +OnInit: + // Placeholder menhir doesn't have to run + if (.name$ == "Soul Menhir") + end; + + // "Next-Generation" parsing system + // Syntax: RATE_DISTANCE_TIMER + // Soul Menhir#town_rate_dist_timer + // example + // Soul Menhir#hurns_1_7_200 + .@n$=strnpcinfo(0, "_0_0_0"); + explode(.@ni$, .@n$, "_"); + .refill_rate=atoi(.@ni$[1]); + .refill_distance=atoi(.@ni$[2]); + .refill_timer=atoi(.@ni$[3]); + + // number of SP to give every refill + if (!.refill_rate) + .refill_rate = 1; + // max distance + if (.refill_distance < 0) + .refill_distance = 7; + // wait rand(X) ms before refill + if (.refill_timer < 1) + .refill_timer = 200; + + initnpctimer(); + end; +} |