// TMW2 Scripts // Evol functions. // Author: // 4144 // Jesusalva // Description: // Function checking the client version and reports if it is too old. // This also handles all updates, and usually have priority. function script clientupdater { // Bugfix if (!TUT_VAR && UPDATE) TUT_VAR=UPDATE; // Skip any update for newcomers if (compare(getmap(), "000-0") || $@NOUPDATES) { UPDATE=gettimetick(2); } // If you're in Jail, show a minor message if (getmap() == "sec_pri") { dispbottom l("You seem to be jailed. We cannot unjail offline players, so please don't logout."); dispbottom l("You have the right to defend yourself if you believe we were wrong. If we find out it's true, you'll receive an apology gift."); dispbottom l("Note: Unless you were doing something REALLY bad which is harmful to player community (eg. scamming, hacking, DDoS'ing, etc.)"); dispbottom l("Please contact a GM as soon as possible so we can make out a compromise. You should be liberated even if found guilty."); } .@dg=0; /* // New skills introduced if (UPDATE < 1531786864) { UPDATE=1531786864; skill TMW2_FAKESKILL, 1, 0; skill TMW2_FAKESKILL2, 1, 0; } // Gallery Contest and 2019-12-29 no-drop incident // ter jan 8 03:52:20 -02 2019 if (UPDATE < 1546926740) { UPDATE=1546926740; .@u$=strtolower(strcharinfo(0)); setarray .@apology$, "jesusalva", "mrhedx", "ziah", "soren xd", "warblade", "yuxin", "xtreem", "monking", "demure gm", "se francisc"; setarray .@gallery$, "jesusalva", "mishana", "bobr", "demure", "lawncable"; // Users connected during nodrop incident (2018-12-29) // Jesusalva Mrhedx Ziah "Soren xd" WarBlade // yuxin Xtreem monking "demure GM" "Se Francisc" if (array_exists(.@apology$, .@u$)) { getitembound GoldenGift, 1, 1; Zeny=Zeny+570; .@dg=1; showavatar NPC_LOF_RICH; mesn ("TMW2 Staff"); mesc l("Hello, @@! We just looked up and found out you were active during 2018-12-29!", strcharinfo(0)), 3; mesc l("And during that time, item dropped was bugged! We wanted to deliver you a token of apology!"), 3; mesc l("Sorry, and enjoy the game! Your TMW2 Staff Team."), 3; mesc l("Token Of Apology: 1x @@, 570 GP", getitemlink(GoldenGift)); next; } // 1st Gallery Contest Participants // Mishana LawnCable bObr Jesusalva demure if (array_exists(.@gallery$, .@u$)) { getitem StrangeCoin, 30; .@dg=1; showavatar NPC_LOF_RICH; mesn ("TMW2 Staff"); mesc l("Hello, @@! We are proud to announce the @@ RESULTS!", strcharinfo(0) , b(l("1° Screenshooting Contest"))), 3; mesc l("Participants: Jesusalva * mishana * bObr * demure * LawnCable"), 3; next; mesc ("Mishana Entries: Happy"), 3; mesc ("LawnCable Entries: Login Screen, TMW2 Field"), 3; mesc ("Demure Entries: Buggy Map"), 3; mesc ("Jesusalva Entries: LoF Secret Island, GM Plotting Evil Scheme For Next Event, Crazyfefe Cave"), 3; mesc ("bObr Entries: My Very Own Tiny Orchard"), 3; next; mesc l("1st Place - Mishana, LawnCable, Jesusalva, bObr"); mesc l("5th Place - Demure"); mes ""; mesc l("Hey, look, a tie happened!"); mesc l("How's that even possible? Well, 30 @@ for all contestants!", getitemlink(StrangeCoin)); next; } } // Valentine Day Event Bug // sex fev 15 18:04:00 -02 2019 if (UPDATE < 1550261040) { UPDATE=1550261040; if (#VALENTINE_POINTS) { .@dg=1; showavatar NPC_LOF_RICH; mesn ("TMW2 Staff"); mesc l("Hello, @@! We just looked up and found out you that you were affected on a Valentine Event bug!", strcharinfo(0)), 3; mesc l("Due this bug, you didn't got a proper amount of points per sent. We wanted to deliver you a token of apology!"), 3; mesc l("Sorry, and enjoy the game! Your TMW2 Staff Team."), 3; mesc l("Token Of Apology: 1x @@, 1x @@", getitemlink(SilverGift), getitemlink(MercBoxB)); getitem SilverGift, 1; getitem MercBoxB, 1; #VALENTINE_POINTS=0; next; } } // Limited bots // sex fev 15 23:22:21 -02 2019 if (UPDATE < 1550280141) { UPDATE=1550280141; .@dg=1; mesc l("Game Rules were updated!"), 1; mesc l("Use @@ to read the new version.", "@rules"), 1; mes ""; //GameRules S_NO_NPC_NAME | S_LAST_NEXT; } // Msawis bug // ter fev 19 12:15:00 -03 2019 if (UPDATE < 1550589300) { UPDATE=1550589300; // Unclaimed Rewards // 2000283 Msawis 10 points // 2000552 Mrhedx 4 points // 2000299 vilbou 1 point setarray .@apology, 2000552, 2000283, 2000299; if (array_exists(.@apology, getcharid(3)) && (#VALENTINE_SENT+#VALENTINE_OPENED) > 0) { if (getcharid(3) == 2000552) { getitem BronzeGift, 1; } else if (getcharid(3) == 2000283) { getitem GoldenGift, 1; } else if (getcharid(3) == 2000299) { getitem StrangeCoin, 1; } dispbottom l("Valentine Day Event Reward automatically claimed"); #VALENTINE_SENT=0; #VALENTINE_OPENED=0; #VALENTINE_RECEIVED=0; } } // Update Tycoon quest exp // dom mar 3 12:22:04 -03 2019 if (UPDATE < 1551626524) { UPDATE=1551626524; if (getq(MineQuest_Tycoon) >= 15) getexp 43000, 0; } // Shovel Auto-dig option // seg mai 27 21:22:55 -03 2019 if (UPDATE < 1559002975) { UPDATE=1559002975; if (countitem(IronShovel) + countitem(SteelShovel)) dispbottom l("Shovel have been changed, right-click it to bury items."); } // General Updates // sex jun 21 13:20:21 -03 2019 if (UPDATE < 1561134021) { UPDATE=1561134021; if (getq(General_Narrator) >= 3) getitem MercBoxAA, 1; // Well, you don't need this crap I hope... if (BaseLevel < 40) getitem TulimMap, 1; if (getq(TulimsharQuest_Sailors) == 4) getexp 1508, 15; .@cr=countitem(CroconutBox); if (.@cr) { getitem CroconutBox, .@cr; dispbottom l("Croconut Box magically became two in inventory. Storage unaffected."); // Too much hassle affecting storage/cart/etc. } } // General Updates // seg jul 15 16:41:35 -03 2019 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; // Fix mounts unequip(EQI_SHADOW_SHOES); setmount 0; // You got recipe book by BSS Quest - mark as complete and get Blueprint if (getq(NivalisQuest_BlueSageSlimes) == 2) { getitem any(AncientBlueprint, AlchemyBlueprintA, EquipmentBlueprintA), 1; CRAFTQUEST=1; mesc l("You got a blueprint as reward for Blue Sage Slimes Quest completion."), 3; } // If you have TMW2_CRAFT skill, you need the bonus recipe if (getskilllv(TMW2_CRAFT)) { RECIPES_EQUIPMENT[CraftDagger]=true; mesc l("Dagger Crafting recipe learnt."), 2; } // Bounty Hunter Helmet if (MERCENARY_DAILYQUEST > 100) { getitem BountyHunterHelmet, 1; mesc l("You got a @@ for completing 100+ daily bountyhunter quests!", getitemlink(BountyHunterHelmet)), 2; } // Cindy quest new rewards if (getq(NivalisQuest_Cindy) >= 3) { getexp 120000, 0; mesc l("You got 120,000 XP for completing Mercury's quest."), 2; } // Mercenary Rank removed if (MERC_RANK) { THIEF_RANK=MERC_RANK; THIEF_EXP=MERC_EXP; MERC_RANK=0; MERC_EXP=0; mesc l("Your class has been changed from %s to %s.", b(l("Merchant Police")), b(l("Thief"))), 1; } if (getskilllv(ALL_INCCARRY)) { skill TF_STEAL, getskilllv(ALL_INCCARRY); skill ALL_INCCARRY, 0, 0; mesc l("Increase Weight skill replaced with Stealing."); } // NEW MAGIC SYSTEM if (getskilllv(SN_SHARPSHOOTING)) { skill AC_CHARGEARROW, getskilllv(SN_SHARPSHOOTING); skill AC_CHARGEARROW, 0, 0; getexp 2000, 150; mesc l("Sharpshooting skill replaced with Charged Arrow."), 1; mesc l("You've got 2000 xp and 150 job xp in apology tokens."); } getskilllist(); for (.@i=0; .@i < @skilllist_count; .@i++) { // skip temporary skills if (@skilllist_flag[.@i] != 0) continue; // Only “paid” skills will result in a Scholarship Badge .@id=@skilllist_id[.@i]; .@am=0; switch (.@id) { case SM_BASH: case TMW2_DEMURE: case MG_FIREBALL: case MG_SRECOVERY: case AL_DP: .@am=1; case SM_ENDURE: case KN_AUTOCOUNTER: case KN_TWOHANDQUICKEN: case AL_ANGELUS: case CR_TRUST: case CR_DEFENDER: case AL_HOLYLIGHT: case TF_DETOXIFY: case ALL_RESURRECTION: case SM_RECOVERY: case PR_ASPERSIO: case AB_HIGHNESSHEAL: case SA_FREECAST: case SA_DRAGONOLOGY: case TMW2_SAGE: case SA_FLAMELAUNCHER: case SA_FROSTWEAPON: case SA_LIGHTNINGLOADER: case SA_SEISMICWEAPON: case MG_ENERGYCOAT: case MG_NAPALMBEAT: case MG_FIREBOLT: case MG_COLDBOLT: case MG_LIGHTNINGBOLT: case WZ_EARTHSPIKE: mesc l("A skill has been replaced with an @@.", getitemlink(ScholarshipBadge)); if (!.@am) .@am=min(5, @skilllist_lv[.@i]); getitem ScholarshipBadge, .@am; skill @skilllist_id[.@i], 0, 0; getexp 5, (@skilllist_lv[.@i]-1)*1000; break; // Free skills (AL_HEAL and mass provoke) will result in XP // Only Jakod's skills with level 3+ will result in a badge case AL_HEAL: case EVOL_MASS_PROVOKE: if (@skilllist_lv[.@i] >= 3) getitem ScholarshipBadge, 1; case SM_PROVOKE: case NV_TRICKDEAD: .@delval=@skilllist_lv[.@i]; mesc l("A skill has been removed, you got @@ job exp and @@ Strange Coin as an apology token.", .@delval*100, .@delval); skill @skilllist_id[.@i], 0, 0; getexp .@delval, .@delval*100; getitem StrangeCoin, .@delval; break; } } // Grant you AL_DP based on magic level if (MAGIC_LVL) { skill AL_DP, MAGIC_LVL, 0; mesc l("You have learnt \"Divine Protection\" level @@.", MAGIC_LVL), 3; } // Grant you Thief Skill Tier 3 if (THIEF_RANK >= 3) { skill(ALL_INCCARRY,1,0); mesc l("You have learnt \"Increase Weight\" in Thief Skills."), 2; } // If you got a Scholarship Badge, you need to travel to Tulimshar. // Give you a Warp Crystal to do so. if (countitem(ScholarshipBadge)) { getitem TulimWarpCrystal, 1; mesc l("You've obtained a @@ to visit Magic Academy.", getitemlink(TulimWarpCrystal)), 1; } // 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 2019 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; // Grant you Thief Skill Tier 4 if (THIEF_RANK >= 4) { skill(MC_OVERCHARGE,1,0); dispbottom l("You have learnt \"Barter\" in Thief Skills."); } // Update Crafting Score CRAFTING_SCORE_COMPLETE=CRAFTING_SCORE*39; // Water bug if (strcharinfo(0) == "JulieWarhawk") { .@dg=true; // Sell Bottles if (countitem(BottleOfWoodlandWater) > 1) { delitem BottleOfWoodlandWater, (countitem(BottleOfWoodlandWater)/2)+1; } if (countitem(EmptyBottle)) { delitem EmptyBottle, countitem(EmptyBottle); } if (countitem(IcedBottle)) { delitem IcedBottle, countitem(IcedBottle); } getitem ArcmageBoxset, 1; // Unjail player atcommand "@unjail "+strcharinfo(0); mesn "Jesusalva"; mesq l("You're right, you never sold any Water Bottle ever. I'm unjailing you."); mesc l("As an Apology Token, you're also receiving one @@.", getitemlink(ArcmageBoxset)); next; } // Bug reward (FF) if (strcharinfo(0) == "seeds") { getitembound LegendaryMouboo, 1, 1; } } // Old regex messed things up // All updates in August are invalid // inv ali d --:--:-- +-- ---- if (UPDATE > 1564617600 && UPDATE < 1567295999 && UPDATE != 1565385020) { UPDATE=1565039378; mesn "Narrator"; mesc l("Warning."), 1; mesc l("Warning."), 1; mesc l("Warning: Invalid UNIX EPOCH time detected."), 1; next; mesc l("We'll be correcting this bug automatically now."); mesc l("YOU WILL BE DISCONNECTED BY FORCE."), 1; mesc l("Please login right after, and this error should not happen again."); next; // Force user to disconnect atcommand "@kick "+strcharinfo(0); } // Leather Quiver price update // qua set 4 11:07:12 -03 2019 if (UPDATE < 1567606032) { UPDATE=1567606032; // Leather Quiver update if (countitem(LeatherQuiver)) { getitem TitaniumOre, countitem(LeatherQuiver)*3; getitem Coal, countitem(LeatherQuiver)*2; dispbottom l("Titanium Ore and Coal refunded on Leather Quiver update."); } // Braknar shield recipe if (getq(NivalisQuest_Baktar) >= 3) { RECIPES_EQUIPMENT[CraftBraknarShield]=true; dispbottom l("Braknar Shield Recipe unlocked!"); } // Orby's fix if (strcharinfo(0) == "Orby") { delinventorylist(); // Needed, because we'll rely on rfind() getinventorylist(); .@index=array_rfind(@inventorylist_id, IronQuiver); setitemoptionbyindex(.@index, 0, VAR_VITAMOUNT, 1); setitemoptionbyindex(.@index, 1, IOPT_RICHNESS, 1); dispbottom l("Iron Quiver stats restored"); // As Orby is Hurnscald Mayor for this term, fix Hurnscald .@df=$HURNS_TAX-100; $HURNS_MONEY+=.@df; $HURNS_TAX=100; } // Crazyfefe's fix if (strcharinfo(0) == "Crazyfefe") { CRAFTING_SCORE_COMPLETE+=30*39; CRAFTING_SCORE=CRAFTING_SCORE_COMPLETE/40; } // Karma fix (double check Karma=0; } // Baktar changes // seg out 21 19:32:55 -03 2019 if (UPDATE < 1571697175) { UPDATE=1571697175; .@q2=getq2(NivalisQuest_Baktar); if (.@q2 & 4) setq2 NivalisQuest_Baktar, .@q2^4; if (.@q2 & 2) Zeny+=1000; if (.@q2 & 1) Zeny+=1350; } // Ryan reward remaster + Monthly Reward rewrite // qua nov 6 21:15:41 -03 2019 if (UPDATE < 1573085741) { UPDATE=1573085741; // Login reward fix if (#LOGIN_ALLTIME >= 6 && #UPDATE < 1573085741) { dispbottom l("CONGRATULATIONS! For a semester worth of logins, you're getting a pet!"); makepet Piou; } #UPDATE=1573085741; // Ryan Quest if (getq(HalinarzoQuest_LifeDelight) >= 3) getitem MylarinDust, 1; // Impossible... if (getq(HalinarzoQuest_LifeDelight) >= 4) getitem SunnyCrystal, 1; } // Registration Date // sáb jan 25 18:30:00 BRT 2020 if (UPDATE < 1579987800) { UPDATE=1579987800; if (!#REG_DATE) { #REG_DATE=gettimetick(2); // 1520046000 : sáb mar 3 00:00:00 BRT 2018 // A thank-you for being with us for almost 2 years getitem StrangeCoin, 1; dispbottom l("Thank you for being with us for so long. You gained a %s as a random good-hearted action from the team!", getitemlink(StrangeCoin)); } } // Language over simplification // dom fev 16 14:54:30 BRT 2020 if (UPDATE < 1581875670) { UPDATE=1581875670; switch (Lang) { case 0: break; case 1: // Old French Lang=LANG_FR; break; case 3: // Old Spanish Lang=LANG_ES; break; case 4: // Old Portuguese Lang=LANG_PTBR; break; case 5: // Old German Lang=LANG_DE; break; default: Lang=99; break; } if (Lang > MAX_LANG) { .@dg=1; Lang=0; asklanguage(); mes l("Ok, done."); } } // AFK Time fix // dom mar 1 22:05:00 BRT 2020 if (UPDATE < 1583111100) { UPDATE=1583111100; unequipbyid(Slippers); unequipbyid(AFKCap); unequipbyid(Blanket); unequipbyid(Bathrobe); skill TMW2_SPEECH, 0, 0; // PS. All values are ÷ 3 if (AFKING >= 28800) sk_lvup(TMW2_SPEECH); // 24 hours mark if (AFKING >= 201600) sk_lvup(TMW2_SPEECH); // 7 days mark if (AFKING >= 864000) sk_lvup(TMW2_SPEECH); // 30 days mark if (AFKING >= 2592000) sk_lvup(TMW2_SPEECH); // 90 days mark } // Deprecate event points // dom abr 26 12:41:55 BRT 2020 if (UPDATE < 1587915715) { UPDATE=1587915715; if (EVENT_POINTS) { getitem StrangeCoin, EVENT_POINTS/2; EVENT_POINTS=0; } } // Magic v3 // dom jun 21 05:55:00 BRT 2020 if (UPDATE < 1592729700) { UPDATE=1592729700; #FIRST_TIME=true; if (getskilllv(TMW2_CRAFT) > 5) { // Refund part of the money spent Zeny+=35000+(getskilllv(TMW2_CRAFT) > 6 ? 40000 : 0); // Update crafting skill TMW2_CRAFT, 5, 0; dispbottom l("Crafting rules changed! Your crafting skill was lowered to Level 5, talk to Craftmaster to recover it!"); } // Rebirth Heroics if (strcharinfo(0) == "Crazyfefe") { getitem SupremeGift, 1; channelmes("#world", $REBIRTH_WINNER$+" is the first player to REBIRTH!! They are so OP! %%N"); announce "All hail ##B"+$REBIRTH_WINNER$+"##b, first player to REBIRTH and become OP!", bc_all|bc_npc; } // Mass Provoke replacement if (getskilllv(EVOL_AREA_PROVOKE)) { getitembound ScholarshipBadge, getskilllv(EVOL_AREA_PROVOKE), 4; MAGIC_PTS-=getskilllv(EVOL_AREA_PROVOKE)+1; skill EVOL_AREA_PROVOKE, 0, 0; dispbottom col(l("MSP for Area Provoke was refunded."), 1); } if (getskilllv(EVOL_MASS_PROVOKE)) { skill EVOL_AREA_PROVOKE, getskilllv(EVOL_MASS_PROVOKE), 0; skill EVOL_MASS_PROVOKE, 0, 0; dispbottom col(l("Mass Provoke replaced with Area Provoke."), 1); } // MG_LIGHTNINGBOLT and TMW2_LIGHTNINGBOLT MSP cost differ, refund if (getskilllv(MG_LIGHTNINGBOLT)) { getitembound ScholarshipBadge, getskilllv(MG_LIGHTNINGBOLT), 4; MAGIC_PTS-=getskilllv(MG_LIGHTNINGBOLT); skill MG_LIGHTNINGBOLT, 0, 0; dispbottom col(l("MSP for Lightning Strike was refunded."), 1); } // SN_WINDWALK MSP cost differ, refund if (getskilllv(SN_WINDWALK)) { getitembound ScholarshipBadge, getskilllv(SN_WINDWALK), 4; MAGIC_PTS-=getskilllv(SN_WINDWALK)+2; skill CR_TRUST, 0, 0; dispbottom col(l("MSP for Wind Walker was refunded."), 1); } // CR_TRUST MSP cost differ, refund if (getskilllv(CR_TRUST)) { getitembound ScholarshipBadge, getskilllv(CR_TRUST), 4; MAGIC_PTS-=getskilllv(CR_TRUST)+2; skill CR_TRUST, 0, 0; dispbottom col(l("MSP for Last Man Standing was refunded."), 1); } // Eisten Update if (getq(TulimsharQuest_Eistein) > 3) { getitem GraduationAlbum, 1; dispbottom l("You've got a Graduation Album for Eistein levels!"); } } // Magic v3 regression // ter jul 7 18:42:22 BRT 2020 if (UPDATE < 1594158142) { UPDATE=1594158142; for (.@i=0; .@i < getarraysize($@MSK_MAGIC) ; .@i++) { /* debugmes "Debug skill %s - Lv %d", getskillname($@MSK_MAGIC[.@i]), getskilllv($@MSK_MAGIC[.@i]); * / if (getskilllv($@MSK_MAGIC[.@i]) > 1) { .@msp=(getskilllv($@MSK_MAGIC[.@i])-1); MAGIC_PTS-=.@msp; skill $@MSK_MAGIC[.@i], 1, 0; dispbottom l("%s refunded to level 1 for %d MSP", getskillname($@MSK_MAGIC[.@i]), .@msp); } } } // AFKing bugfix // qua jul 29 06:52:00 BRT 2020 if (UPDATE < 1596016320) { UPDATE=1596016320; .@x=(AFKING >= 2592000 ? 4 : ( AFKING >= 864000 ? 3 : ( AFKING >= 201600 ? 2 : ( AFKING >= 28800 ? 1 : 0 )))); skill(TMW2_SPEECH, .@x, 0); dispbottom l("AFK skill levels fixed."); } // Magic RP bugfix // sáb ago 1 05:45:00 BRT 2020 if (UPDATE < 1596271500) { UPDATE=1596271500; .@x=(AFKING >= 2592000 ? 4 : ( AFKING >= 864000 ? 3 : ( AFKING >= 201600 ? 2 : ( AFKING >= 28800 ? 1 : 0 )))); skill(TMW2_SPEECH, .@x, 0); dispbottom l("AFK skill levels fixed."); for (.@i=0; .@i < getarraysize($@MSK_MAGIC) ; .@i++) { if (getskilllv($@MSK_MAGIC[.@i]) > 1) { .@msp=max(0, getskilllv(@menuret)-5); MAGIC_PTS-=.@msp; skill $@MSK_MAGIC[.@i], 1, 0; dispbottom l("%s removed - YOU NOOB STOP CHEATING %%e%%Q", getskillname($@MSK_MAGIC[.@i]), .@msp); } } } // Skill RP Patch [Magic v3 delayed] // ter ago 25 20:20:20 BRT 2020 if (UPDATE < 1598397620) { UPDATE=1598397620; // Skills deleted or with poor equivalence skillInvoke[EVOL_AREA_PROVOKE]+=skillInvoke[EVOL_MASS_PROVOKE]; skillInvoke[EVOL_MASS_PROVOKE]=0; skillInvoke[TMW2_LIGHTNINGBOLT]+=skillInvoke[MG_LIGHTNINGBOLT]; skillInvoke[MG_LIGHTNINGBOLT]=0; // Skills replaced skillInvoke[TMW2_FIREARROW]+=skillInvoke[MG_FIREBALL]; skillInvoke[MG_FIREBALL]=0; skillInvoke[TMW2_NAPALMBEAT]+=skillInvoke[AL_HOLYLIGHT]; skillInvoke[AL_HOLYLIGHT]=0; skillInvoke[TMW2_HOLYLIGHT]+=skillInvoke[MG_NAPALMBEAT]; skillInvoke[MG_NAPALMBEAT]=0; skillInvoke[TMW2_MAGICSTRIKE]+=skillInvoke[MG_SOULSTRIKE]; skillInvoke[MG_SOULSTRIKE]=0; skillInvoke[TMW2_METEORSTRIKE]+=skillInvoke[WZ_EARTHSPIKE]; skillInvoke[WZ_EARTHSPIKE]=0; skillInvoke[TMW2_FROSTDIVER]+=skillInvoke[MG_COLDBOLT]; skillInvoke[MG_COLDBOLT]=0; skillInvoke[TMW2_FROSTNOVA]+=skillInvoke[MG_FROSTDIVER]; skillInvoke[MG_FROSTDIVER]=0; skillInvoke[TMW2_NILFHEIM]+=skillInvoke[WZ_FROSTNOVA]; skillInvoke[WZ_FROSTNOVA]=0; skillInvoke[TMW2_FIRSTAID]+=skillInvoke[AL_HEAL]; skillInvoke[AL_HEAL]=0; skillInvoke[TMW2_HEALING]+=skillInvoke[AB_HIGHNESSHEAL]; skillInvoke[AB_HIGHNESSHEAL]=0; } // Misc bugfixes // dom nov 22 15:27:47 BRT 2020 if (UPDATE < 1606069667) { UPDATE=1606069667; if (RECIPES_EQUIPMENT[0]) { Zeny += 15000; getitem PrismGift, 1; RECIPES_EQUIPMENT[0] = false; dispbottom l("Invalid recipe from Nahrec partly reimbursed."); } } */ // Christmas Warp bug // seg dez 28 20:45:55 BRT 2020 if (UPDATE < 1609199155) { UPDATE=1609199155; if (BaseLevel < 20) { if (getsavepoint(0) != "000-1" && getsavepoint(0) != "003-1" && getsavepoint(0) != "005-1" && getsavepoint(0) != "009-1") { // Resave at Candor EnterTown("Candor"); ReturnTown(); } } // Assign the initial academic titles if (strcharinfo(0) == "Jesus Saves") ACADEMIC_RANK=ACADEMIC_GM; else if (strcharinfo(0) == "Saulc GM") ACADEMIC_RANK=ACADEMIC_GM; else if (strcharinfo(0) == "jak2") ACADEMIC_RANK=ACADEMIC_GM; else if (strcharinfo(0) == "LawnCable") ACADEMIC_RANK=ACADEMIC_BACHELOR; else if (strcharinfo(0) == "Kolchak") ACADEMIC_RANK=ACADEMIC_TECHNIC; else if (strcharinfo(0) == "dangerDuck") ACADEMIC_RANK=ACADEMIC_TECHNIC; else if (strcharinfo(0) == "Livio") ACADEMIC_RANK=ACADEMIC_TECHNIC; else if (strcharinfo(0) == "Arthur") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Mathias Cronqvist") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Manatauro") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "GoNzO") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "YuckFou") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Xanthem") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Povo") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Esteria") ACADEMIC_RANK=ACADEMIC_STUDENT; if (ACADEMIC_RANK != ACADEMIC_LAYMAN) { // Select a benefactor .@benefactor$=rand_sponsor(); // Inform yourself dispbottom l("You received the %s title from %s.", academicrank(), .@benefactor$); // Inform everyone kamibroadcast(sprintf("%s has been granted the title of %s. Thank %s!", strcharinfo(0), academicrank(), .@benefactor$)); // Log in a special log file as well logmes(sprintf("%s has been granted the title of %s.", strcharinfo(0), academicrank())); } // Gallery Contest .@dg=1; showavatar NPC_LOF_RICH; mesn ("TMW2 Staff"); mesc l("Hello, @@! We are proud to announce the @@ RESULTS!", strcharinfo(0) , b(l("2° Screenshooting Contest"))), 3; mesc l("Participants: Povo * Manatauro * Woody"), 3; next; mesc ("Povo Entries: What to do with Presents?"), 3; mesc ("Woody Entries: Lava Dungeon"), 3; mesc ("Manatauro Entries: Yuck Noob =) ; Povo :) ; Lurking GM and Me"), 3; next; mesc l("1st Place - Povo (6 likes)"); mesc l("2nd Place - Manatauro (5 likes)"); mesc l("3rd Place - Woody (4 likes)"); mes ""; next; if (strcharinfo(0) == "Povo") getitem StrangeCoin, 80; else if (strcharinfo(0) == "Manatauro") getitem StrangeCoin, 40; else if (strcharinfo(0) == "Woody") getitem StrangeCoin, 20; } // Easter Eggs // qua jul 29 06:52:00 BRT 2020 if (UPDATE < 1610083840) { UPDATE=1610083840; .@q=getq(General_EasterEggs); if (.@q) { setq General_EasterEggs, 1, .@q, bitmask_count(.@q); dispbottom l("Easter Egg quest updated. Total found: %02d/06", bitmask_count(.@q)); } } // Change variable scope // sáb jan 16 19:21:15 BRT 2021 if (UPDATE < 1610835675) { UPDATE=1610835675; #GUILDSHOP=GUILDSHOP; GUILDSHOP=0; } // Post-Fire Titulations // ter ago 17 20:02:40 BRT 2021 if (UPDATE < 1629241360) { UPDATE=1629241360; // Assign the initial academic titles if (strcharinfo(0) == "Jesus Saves") ACADEMIC_RANK=ACADEMIC_GM; else if (strcharinfo(0) == "Saulc GM") ACADEMIC_RANK=ACADEMIC_GM; else if (strcharinfo(0) == "jak1") ACADEMIC_RANK=ACADEMIC_GM; else if (strcharinfo(0) == "dangerDuck") ACADEMIC_RANK=ACADEMIC_TECHNIC; else if (strcharinfo(0) == "Livio") ACADEMIC_RANK=ACADEMIC_TECHNIC; else if (strcharinfo(0) == "Xanofire") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Arthur the King") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Mathias Cronqvist") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Mana") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Povo") ACADEMIC_RANK=ACADEMIC_STUDENT; else if (strcharinfo(0) == "Esteria") ACADEMIC_RANK=ACADEMIC_STUDENT; //else if (strcharinfo(0) == "LawnCable") // ACADEMIC_RANK=ACADEMIC_BACHELOR; //else if (strcharinfo(0) == "Kolchak") // ACADEMIC_RANK=ACADEMIC_TECHNIC; //else if (strcharinfo(0) == "GoNzO") // ACADEMIC_RANK=ACADEMIC_STUDENT; //else if (strcharinfo(0) == "YuckFou") // ACADEMIC_RANK=ACADEMIC_STUDENT; if (ACADEMIC_RANK != ACADEMIC_LAYMAN) { // Select a benefactor .@benefactor$=rand_sponsor(); // Inform yourself dispbottom l("You received the %s title from %s.", academicrank(), .@benefactor$); // Inform everyone kamibroadcast(sprintf("%s has been granted the title of %s. Thank %s!", strcharinfo(0), academicrank(), .@benefactor$)); // Log in a special log file as well logmes(sprintf("%s has been granted the title of %s.", strcharinfo(0), academicrank())); } } // Change some quest inner workings // qua set 22 12:30:40 BRT 2021 if (UPDATE < 1632324640) { UPDATE=1632324640; setq1 HalinarzoQuest_Alvasus, getq(HalinarzoQuest_Alvasus)+1; } // Christmas 2021 // ter dez 28 11:57:17 BRT 2021 if (UPDATE < 1640703437) { .@u$ = strtolower(strcharinfo(0)); setarray .@xmas21$, "jesusalva", "poppet", "jak1", "horak", "hocus pocus fidibus", "statue"; setarray .@xmas20$, "andulkat", "kolchak", "Pacman_I_I"; if (array_exists(.@xmas21$, .@u$)) { .@dg=1; showavatar NPC_LOF_RICH; mesn ("TMW2 Staff"); mesc l("Hello, %s! Congratulations for finishing the %s!", strcharinfo(0), b(l("Christmas 2021 Joint Event"))), 3; mesc l("You need to pick your prizes!"), 3; inventoryplace NPCEyes, 6, Iten, 5; next; mesc l("Select one:"), 3; menuint l("Elixir of Life"), ElixirOfLife, l("Sacred Immortality Potion"), SacredImmortalityPotion; mes ""; .@it1 = @menuret; mesc l("Select one:"), 3; menuint l("Short Gunstaff"), PynRevolver, l("Rapid Gunstaff"), PynGatling, l("Explosive Gunstaff"), PynShotgun, l("Powerful Gunstaff"), PynRifle; mes ""; .@it2 = @menuret; getitem .@it1, 5; getitembound .@it2, 1, 1; getitem GoldenBossGift, 1; getitem SupremeGift, 1; getitem MagicApple, 1; getitem Arcanum, 1; getitem StrangeCoin, 30; } else if (array_exists(.@xmas20$, .@u$)) { getitem Arcanum, 1; getitem StrangeCoin, 30; } UPDATE=1640703437; // misc fixes if (getq(LoFQuest_George) >= 3) getexp 45000, 0; if (getq(LoFQuest_George) >= 5) getexp 135000, 0; if (getq2(HalinarzoQuest_LifeDelight) >= 20) getitem Coffee, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 30) getitem Manapple, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 40) getitem LoFWarpCrystal, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 60) getitem SacredLifePotion, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 70) getitem MercBoxDD, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 80) getitem DivineApple, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 90) getitem MysteriousFruit, 1; if (getq2(HalinarzoQuest_LifeDelight) >= 21) Mobpt+=((getq2(HalinarzoQuest_LifeDelight) - 1) * (getq2(HalinarzoQuest_LifeDelight) - 20)); // Will work... Sort of } // Realm of Drops // sab set 24 15:37:15 BRT 2022 if (UPDATE < 1664044635) { UPDATE=1664044635; skill TMW2_DROPS, REBIRTH+1, 0; if (getskilllv(TMW2_SKILLPERMIT) >= 1) getitem ScholarshipBadge, 1; if (getskilllv(TMW2_SKILLPERMIT) >= 2) getexp 20000, 1000; if (getskilllv(TMW2_SKILLPERMIT) >= 3) getexp 80000, 0; // Actual value has changed, you'll be refunded in EXP if (getskilllv(TMW2_SKILLPERMIT) >= 1) #ADD_LVL+=80000; } // Dausen update // dom out 22 13:15:32 BRT 2022 if (UPDATE < 1666541732) { UPDATE=1666541732; if (getq(TulimsharQuest_MobTutorial) >= 2) Zeny+=246; if (getq(TulimsharQuest_MobTutorial) >= 4) Zeny+=616; if (getq(TulimsharQuest_MobTutorial) >= 6) Zeny+=1068; if (getq(TulimsharQuest_MobTutorial) >= 8) Zeny+=2200; } // Balance update // sáb 26 nov 2022 16:44:35 -03 if (UPDATE < 1669491875) { UPDATE=1669491875; if (getq(HurnscaldQuest_ForestBow)) getitem TrainingArrow, 220; if (getq3(TulimsharQuest_Swezanne) > 30) getitem MercCard_Swezanne, 9 * (getq3(TulimsharQuest_Swezanne)/30); if (getq(TulimsharQuest_MobTutorial) >= 4) getitem SulfurPowder, 1; if (getq(TulimsharQuest_MobTutorial) >= 8) getitem SulfurPowder, 3; if (TUT_VAR) { .@dg = true; setpcblock(PCBLOCK_HARD, true); // Allow you to choose the starting trait // However, we unset #TUTORIAL_DONE so EXP Gain and Knockback are OFF // While alts are generally allowed to have these starting traits, // there's no way for veterans select this. #TUTORIAL_DONE = false; do { mesc l("You must choose a trait now, or the opportunity will be forfeit."), 1; next; } while (!ChooseTrait()); #TUTORIAL_DONE = true; setpcblock(PCBLOCK_HARD, false); } } // Char-Server crash // sex 09 dez 2022 21:51:40 -03 if (UPDATE < 1670633500) { UPDATE=1670633500; setarray .@accid, 2000000, 2000005, 2000008, 2000114, 2000267, 2000474, 2000505, 2000539, 2000777, 2000782, 2000803, 2000816, 2000817, 2000819, 2000820, 2000821, 2000822, 2000823, 2000824, 2000825, 2000826, 2000827; if (array_exists(.@accid, getcharid(3)) && #UPDATE < 1670633500) { rodex_sendmail(getcharid(0), "TMW Team", "Char-Server Crash", "Due to a disk issue, char server died and quest progress was lost.\nThis is an apology.", 5000, MaggotSlime, 10, BugLeg, 10, Beer, 3, IronOre, 2); } #UPDATE=1670633500; } // Glados-2 disk crash // sáb 10 dez 2022 20:27:47 -03 if (UPDATE < 1670714867) { UPDATE=1670714867; if (countitem(SilverRing)) { getitem SilverIngot, 3*countitem(SilverRing); } } // :// End of Regular Update System //////////////////////////////////// // Valentine 2020 Record if (#VALENTINE20_REWARDS) { .@dg=1; // Get misc items getitem OolongTea, 3; getitem SpearmintTea, 5; getitem CrazyRum, 1; getitem DwarvenSake, 3; dispbottom col(l("THANK YOU for participating on cross-server Valentine 2020 Event! We hope you had fun!"), 7); #VALENTINE20_REWARDS=false; } // Permanent Gold Boost // #ADD_GP means the user have to right to get some gp if (#ADD_GP) { Zeny+=#ADD_GP; #ADD_GP=0; } // Permanent Strange Coins Boost // #ADD_SC means the user have to right to get some strange coins if (#ADD_SC) { logmes "[Merger] Strange Coins +"+#ADD_SC, LOGMES_ATCOMMAND; getitem StrangeCoin, #ADD_SC; #ADD_SC=0; } // Permanent Monster Points Boost // #ADD_MPT means the user have to right to get some Mobpt if (#ADD_MPT) { logmes "[Merger] Mobpt +"+#ADD_MPT, LOGMES_ATCOMMAND; Mobpt+=#ADD_MPT; #ADD_MPT=0; } // Non Permament Level Boost if (#ADD_TMP_LVL) { // Grant the level if (numdate() <= 20200216 && !#SAVED_LVL) { #SAVED_LVL=BaseLevel; BaseLevel=#ADD_TMP_LVL; dispbottom l("Level set from %d to %d", #SAVED_LVL, BaseLevel); // Welcome message .@dg=true; showavatar NPC_LOF_RICH; mesn "Moubootaur Legends Server"; mesc l("First of all: Welcome! Your level was temporaly modified, it'll be reverted once event is over."), 3; next; mesn "Moubootaur Legends Server"; mesc l("You will be able to pick basic weapons and skills at the Event Soul Menhir."), 3; next; mesn "Moubootaur Legends Server"; mesc l("Be careful during night, use \"@tutorial\" in case of doubt, use \"%s\" to go to the event, and good luck!", b("@toevent")), 3; next; // Restore the level } else if (numdate() > 20200216 && #SAVED_LVL) { dispbottom l("Level reset from %d to %d", BaseLevel, #SAVED_LVL); // Save #DEBUG_LEVEL1=#ADD_TMP_LVL; #DEBUG_LEVEL2=BaseLevel; #DEBUG_LEVEL3=#DEBUG_LEVEL2-#DEBUG_LEVEL1; #DEBUG_EXP=BaseExp; // Reset //BaseLevel=#SAVED_LVL; //#SAVED_LVL=0; #ADD_TMP_LVL=0; // Player too late for event! } else if (numdate() > 20200216) { dispbottom l("This event has already ended."); #ADD_TMP_LVL=0; } } if (.@dg) { next; closeclientdialog; } return; } // Just be sure your client version is OK // NOTE: Current master client version is 26, but M+ 1.9.3.23 is still at 25 function script checkclientversion { // Destroy Karma, regardless of version and perpetually Karma=0; // Minimum version if (ClientVersion >= 25) return; mesn "Narrator"; mesc l("Warning."), 1; mesc l("Warning."), 1; mesc l("Warning: You are using an old client."), 1; next; //mesc l("Please install the new client from [@@https://manaplus.org/|https://manaplus.org/@@]"); mesc l("Alternatively, download a bleeding edge build at [@@https://manaplus.germantmw.de/|https://manaplus.germantmw.de/@@]"); mesc l("Or use our awesome [@@https://tmw2.org/manalauncher/InstallManaLauncher.exe|Mana Launcher@@] if you're on Windows or Linux."); next; if (ClientVersion >= 24) mesc l("Compatibility Support mode enabled. Client may crash AT RANDOM, beware."); if (ClientVersion >= 24) mesc l("Crazy stuff can happen in overall. YOU HAVE BEEN WARNED TO UPDATE YOUR CLIENT."); if (ClientVersion >= 24) closeclientdialog; if (ClientVersion >= 24) return; mesc l("You won't be allowed to play this game until you have an updated client."); next; // Force user to disconnect atcommand "@kick "+strcharinfo(0); return; }