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