// TMW2 scripts. // Authors: // Jesusalva // Description: // Controls world events so Saulc and I can take vacations. // See also: seasons.txt, command/event.txt, aurora.txt // 003-1/events.txt, soulmenhir.txt and, of course, the event maps (if any). // Schedule, if needed to change, can be found in the OnInit loop. // An event, obviously, cannot last more than 7... 15 days at WORST. // Therefore, month checks aren't included in day checks. - script sPatrick NPC_HIDDEN,{ OnInit: setarray .maps$, "005-1", "013-1", "014-1", "014-2", "014-3", "014-4", "014-5", "017-1", "018-2", "018-4", "018-5", "soren"; end; OnMyMobDeath: end; OnClock0000: OnClock6000: OnClock1200: OnClock1500: OnClock1800: OnClock2100: .@d=gettime(GETTIME_DAYOFMONTH); // Patrick Day should work only in 2 luck days according to Saulc // If this is required use $PATRICK_DAYCTRL so the days before $@PATRICK_DAYMAX // act with 100% chances (determinism). // As it is being spawn 4 times at a day (like TMW-BR events), because it is // flatly and outright IMPOSSIBLE to add a permanent spawn, that is not required. if ($EVENT$ == "Patrick" && .@d <= $@PATRICK_DAYMAX) { for (.@i=0; .@i < getarraysize(.maps$); .@i++) { .@m$=.maps$[.@i]; .@x=getmapinfo(MAPINFO_SIZE_X, .@m$)-20; .@y=getmapinfo(MAPINFO_SIZE_Y, .@m$)-20; // Remove previously spawned clovers killmonster(.@m$, "sPatrick::OnMyMobDeath"); // It is one clover for each 225 tiles (about a 25x25 square) .@maparea=(.@x-20)*(.@y-20); .@mobs=max(1, .@maparea/225); areamonster .@m$, 20, 20, .@x, .@y, strmobinfo(1, StPatricksClover), StPatricksClover, .@mobs, "sPatrick::OnMyMobDeath"; } } end; // Remove previously spawned clovers for event end // And then disables the NPC OnCleanUp: for (.@i=0; .@i < getarraysize(.maps$); .@i++) { .@m$=.maps$[.@i]; killmonster(.@m$, "sPatrick::OnMyMobDeath"); } disablenpc "sPatrick"; donpcevent "Aurora::OnRestore"; end; } - script sDreamTower NPC_HIDDEN,{ OnWarpTo: if ($EVENT$ != "Tower") end; if (!playerattached()) end; if (!countitem(EventDreamTicket)) end; // Reset progress if (DTOWER_DAY != gettimeparam(GETTIME_DAYOFMONTH) || DTOWER_FLOOR < 1) { DTOWER_DAY=gettimeparam(GETTIME_DAYOFMONTH); DTOWER_FLOOR=1; dispbottom l("A new Dream Tower opens its gates before you..."); } // Create maze and populate CreateMaze(IOT_CHAR); .@mx=getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$)-20; .@my=getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$)-20; .@tl=(20-.@mx)*(20-.@my) * 3 / 10; // Total tiles + collision guess .@tl=.@tl / rand2(9,14) + 1; // Monster density is a bit random /* *** Copied from 006-5/groata.txt & 018-2-2/main.txt! *** */ /* ********* Spawn monsters based on DTOWER_FLOOR ********* */ .@lv = (BaseLevel/10) + DTOWER_FLOOR * 5; .@mb[0] = MagicGoblin; .@mb[1] = CaveMaggot; // Artillery & Chests if (.@lv > 10) array_push(.@mb, BronzeChest); if (.@lv > 20) array_push(.@mb, SmallMagicBif); if (.@lv > 30) array_push(.@mb, Bif); if (.@lv > 40) array_push(.@mb, RobinBandit); if (.@lv > 45) array_push(.@mb, SilverChest); if (.@lv > 50) array_push(.@mb, DustGatling); if (.@lv > 55) array_push(.@mb, MagicBif); if (.@lv > 60) array_push(.@mb, DustRifle); if (.@lv > 70) array_push(.@mb, DustRevolver); if (.@lv > 75) array_push(.@mb, GoldenChest); if (.@lv > 80) array_push(.@mb, DustBoss); if (.@lv > 85) array_push(.@mb, BigMagicBif); if (.@lv > 90) array_push(.@mb, GreatMoubooSlime); if (.@lv > 100) array_push(.@mb, Jhon); if (.@lv > 105) array_push(.@mb, PrismChest); // Monsters if (is_between2(0, .@lv, 30)) { array_push(.@mb, Piou); array_push(.@mb, Piousse); array_push(.@mb, Squirrel); array_push(.@mb, ManaPiou); array_push(.@mb, ForestPiou); array_push(.@mb, RedButterfly); array_push(.@mb, Maggot); array_push(.@mb, CandorScorpion); array_push(.@mb, HouseMaggot); array_push(.@mb, LittleYellowSlime); array_push(.@mb, Ratto); array_push(.@mb, RudolphSlime); array_push(.@mb, MoubooSlime); array_push(.@mb, Croc); array_push(.@mb, Scorpion); array_push(.@mb, SmallFrog); } if (is_between2(10, .@lv, 40)) { array_push(.@mb, BigFrog); array_push(.@mb, Lavern); array_push(.@mb, LittleRedSlime); array_push(.@mb, ChocolateSlime); array_push(.@mb, Blub); array_push(.@mb, Duck); array_push(.@mb, Bat); array_push(.@mb, CaveMaggot); array_push(.@mb, ManaGhost); array_push(.@mb, ManaBug); array_push(.@mb, Fluffy); array_push(.@mb, FireGoblin); array_push(.@mb, ViciousSquirrel); array_push(.@mb, RedScorpion); array_push(.@mb, WhiteSlime); array_push(.@mb, AzulSlime); array_push(.@mb, DesertLogHead); } if (is_between2(20, .@lv, 50)) { array_push(.@mb, RedSlime); array_push(.@mb, PoisonSpikyMushroom); array_push(.@mb, DesertBandit); array_push(.@mb, OceanCroc); array_push(.@mb, ToppyBlub); array_push(.@mb, Sarracenus); array_push(.@mb, IceMaggot); array_push(.@mb, VampireBat); array_push(.@mb, Bandit); array_push(.@mb, Pinkie); array_push(.@mb, LivingPotato); array_push(.@mb, Assassin); array_push(.@mb, Skeleton); } if (is_between2(30, .@lv, 60)) { array_push(.@mb, CaveSnake); array_push(.@mb, GreenSlime); array_push(.@mb, CopperSlime); array_push(.@mb, YellowSlime); array_push(.@mb, SantaSlime); array_push(.@mb, LavaSlime); array_push(.@mb, Bluepar); array_push(.@mb, DeathCat); array_push(.@mb, Moggun); array_push(.@mb, SeaSlime); array_push(.@mb, RedMushroom); array_push(.@mb, Mouboo); array_push(.@mb, LogHead); array_push(.@mb, CandiedSlime); array_push(.@mb, OldSnake); array_push(.@mb, GrassSnake); } if (is_between2(40, .@lv, 70)) { array_push(.@mb, GiantMaggot); array_push(.@mb, IcedFluffy); array_push(.@mb, Snake); array_push(.@mb, BlackSlime); array_push(.@mb, Tipiou); array_push(.@mb, AlphaMouboo); array_push(.@mb, Pollet); array_push(.@mb, PiouKnight); array_push(.@mb, Shrewboo); } if (is_between2(40, .@lv, 80)) { array_push(.@mb, Wolvern); array_push(.@mb, FireSkull); array_push(.@mb, DarkLizard); } if (is_between2(50, .@lv, 90)) { array_push(.@mb, ArmoredSkeleton); array_push(.@mb, BlackScorpion); array_push(.@mb, ElectroWorm); array_push(.@mb, EarthFairy); array_push(.@mb, FireFairy); array_push(.@mb, WaterFairy); array_push(.@mb, WindFairy); array_push(.@mb, PoisonFairy); array_push(.@mb, MountainSnake); array_push(.@mb, HoodedNinja); array_push(.@mb, ForestMushroom); array_push(.@mb, GoldenScorpion); } if (is_between2(60, .@lv, 100)) { array_push(.@mb, Yeti); array_push(.@mb, FallenGuard1); array_push(.@mb, GreenSlimeMother); array_push(.@mb, SnowFlower); array_push(.@mb, BlueSlimeMother); array_push(.@mb, WickedMushroom); array_push(.@mb, CopperSlimeMother); array_push(.@mb, YellowSlimeMother); array_push(.@mb, RedSlimeMother); array_push(.@mb, ChocolateSlimeMother); array_push(.@mb, WhiteSlimeMother); array_push(.@mb, Archant); array_push(.@mb, Scar); } if (is_between2(70, .@lv, 110)) { array_push(.@mb, AzulSlimeMother); array_push(.@mb, SeaSlimeMother); array_push(.@mb, LavaSlimeMother); array_push(.@mb, BlackSlimeMother); array_push(.@mb, Crafty); array_push(.@mb, Forain); array_push(.@mb, GreenDragon); array_push(.@mb, Michel); array_push(.@mb, Troll); } if (is_between2(80, .@lv, 120)) { array_push(.@mb, EliteDuck); array_push(.@mb, AzulSkullSlime); array_push(.@mb, Moonshroom); array_push(.@mb, RedSkullSlime); array_push(.@mb, Terranite); array_push(.@mb, JackO); array_push(.@mb, BlackMamba); array_push(.@mb, GreenSkullSlime); array_push(.@mb, BloodyMouboo); array_push(.@mb, Centaur); array_push(.@mb, GoboBear); } if (is_between2(90, .@lv, 130)) { array_push(.@mb, CopperSkullSlime); array_push(.@mb, LavaSkullSlime); array_push(.@mb, BlackSkullSlime); array_push(.@mb, GiantCaveMaggot); array_push(.@mb, TerraniteProtector); array_push(.@mb, VanityPixie); array_push(.@mb, HolyPixie); } if (is_between2(100, .@lv, 140)) { array_push(.@mb, ShadowPixie); array_push(.@mb, NulityPixie); array_push(.@mb, Reaper); array_push(.@mb, NightmareDragon); array_push(.@mb, Snail); array_push(.@mb, WhirlyBird); } if (is_between2(110, .@lv, 150)) { array_push(.@mb, PinkieSuseran); array_push(.@mb, Mandragora); array_push(.@mb, PinkieMaximus); } if (.@lv > 120) { array_push(.@mb, Junglefowl); array_push(.@mb, Tengu); array_push(.@mb, Moubi); } if (.@lv > 130) { array_push(.@mb, SuperiorShroom); array_push(.@mb, Nutcracker); array_push(.@mb, Golem); } if (.@lv > 140) { array_push(.@mb, SiegeTower); array_push(.@mb, GreenhornAbomination); array_push(.@mb, ShadowTortuga); array_push(.@mb, FireElement); array_push(.@mb, WaterElement); array_push(.@mb, EarthElement); array_push(.@mb, WindElement); } if (.@lv > 150) { array_push(.@mb, SacredWisp); array_push(.@mb, EvilWisp); array_push(.@mb, PanthomWisp); array_push(.@mb, EpiphanyWisp); } if (.@lv > 175) array_push(.@mb, Tortuga); /* Spawn them and make hostile */ freeloop(true); for (.@i = 0; .@i < 1+(.@tl); .@i++) { .@mid = any_of(.@mb); .@m=areamonster(MAZE_MAP$, 20, 20, .@mx, .@my, strmobinfo(1, .@mid), .@mid, 1); set_aggro(.@m); } freeloop(false); // Spawn & Configure the boss monster .@mob=areamonster(MAZE_MAP$, 20, 20, .@mx, .@my, "Gatekeeper", MonsterSergeant, 1, "sDreamTower::OnBossDie"); setunitdata(.@mob, UDT_LEVEL, DTOWER_FLOOR * 5); setunitdata(.@mob, UDT_STR, DTOWER_FLOOR * 2); setunitdata(.@mob, UDT_AGI, DTOWER_FLOOR * 2); setunitdata(.@mob, UDT_VIT, DTOWER_FLOOR * 3); setunitdata(.@mob, UDT_INT, DTOWER_FLOOR * 1); setunitdata(.@mob, UDT_DEX, DTOWER_FLOOR * 3); setunitdata(.@mob, UDT_LUK, DTOWER_FLOOR * 2); setunitdata(.@mob, UDT_ADELAY, max(640, 1672-(DTOWER_FLOOR * 24))); setunitdata(.@mob, UDT_MAXHP, 2000+DTOWER_FLOOR*120); setunitdata(.@mob, UDT_HP, 2000+DTOWER_FLOOR*120); setunitdata(.@mob, UDT_ATKMIN, 20+DTOWER_FLOOR*4); setunitdata(.@mob, UDT_ATKMAX, 40+DTOWER_FLOOR*4); setunitdata(.@mob, UDT_DEF, 10+DTOWER_FLOOR*3); setunitdata(.@mob, UDT_MDEF, 5+DTOWER_FLOOR); setunitdata(.@mob, UDT_HIT, (BaseLevel+DTOWER_FLOOR)*32/10); setunitdata(.@mob, UDT_FLEE, (BaseLevel+DTOWER_FLOOR)*24/10); setunitdata(.@mob, UDT_CRIT, rand2(40, min(120, 40+DTOWER_FLOOR))); // TODO: Spawn more treasure chests? (exp, gp, items) // Consume the ticket and begin the maze delitem EventDreamTicket, 1; InitMaze(3600); dispbottom col(l("Reminder : Defeat the %s to win.", b("Gatekeeper")), 2); dispbottom l("Mana Plane - Dream Tower, %dº floor. Time limit: 60 minutes or death.", DTOWER_FLOOR); end; // Dream Tower cleared OnBossDie: dispbottom l("Mana Plane - Dream Tower, %dº floor %s", DTOWER_FLOOR, b(l("CLEAR!"))); DTOWER_FLOOR+=1; if ($EVENT$ == "Tower") getitem BrokenMedal, 1; unitskilluseid(getcharid(3), BS_GREED, 1, getcharid(3)); sleep2(500); teleporthome(); end; } - script sThankAeros NPC_HIDDEN,{ OnInit: .users=getusers(1); .score=0; .event=0; .quota=300; OnTimer90000: // Abort event and reset score if (.event && .event < gettimetick(2)) { .event=0; .score=0; $@GM_EVENT=0; $@MK_SCENE=MK_NONE; killmonsterall("001-1"); mapwarp("001-1", "000-1", 22, 22, 0); announce ("The event is over!"), bc_all|bc_npc; } // Skip processment until current event ends if (.event) { initnpctimer; end; } // Stop counting or update scores if ($EVENT$ != "Thanksgiving") end; .users=getusers(1); .score+=.users; .quota = limit(300, 500 - (.users * 25), 500); // Do event (lasts 45 minutes) if (!.event && !$@MK_SCENE && !$@GM_EVENT && .score > .quota && (.users >= 4 || $@GM_OVERRIDE)) { /* Reserve Aeros */ $@MK_SCENE=MK_LOCKED; /* Setup the event */ $@AEROS_SPWN=(.users > 6 ? 2 : any(0, 1)); $@AEROS_AUTOSPAWN=.users+rand2(1, .users); donpcevent("Mana Being#001-1::OnAutoSched"); /* Open the event */ $@GM_EVENT = 2; .event = gettimetick(2) + 2700; announce ("The mana bridge to Aeros is open! To participate on event, talk to ##BSoul Menhir##b!"), bc_all|bc_npc; announce ("##1THANKSGIVING SPECIAL. TIME LIMIT: ##B45 MINUTES.##b##0"), bc_all|bc_npc; channelmes("#world", "An event is happening on Aeros! Hurry up!"); } initnpctimer; end; OnForceInit: .score+=9999; goto OnTimer90000; } function script sThanksgiving { // Variables: // #THANKS_DAY // #THANKS_STREAK // @thanks_card // Already spinned if (#THANKS_DAY == gettime(5) || $EVENT$ != "Thanksgiving") return; // Not spinned yet showavatar 1102; mes l(".:: Thanksgiving ::."); mesc l("Spin daily the card to get prizes!"); select l("SPIN!"), l("Later"); mes ""; if (@menu == 2) { setskin ""; closeclientdialog; return; } // Spin it // Your prize is saved in .@luck. Rigged against fruits .@luck=rand2(0,11); .@luck=(.@luck == 10 ? rand2(0,11) : .@luck); // A fruit before 10 days: rig to Arcmage or to blueprint if (.@luck == 10 && #THANKS_STREAK < 10) .@luck+=any(-1,1); // A fruit before 20 days: Lower chances from 4% to 2% if (.@luck == 10 && #THANKS_STREAK < 20) .@luck=rand2(0,11); // Extra spins .@extra=rand2(1,3); .@spins=.@extra*11+.@luck; //.@extra=0; // Show the spins for (.@i=0;.@i<=.@spins;.@i++) { .@cur=(.@i%11); showavatar 1103+.@cur; sleep2(60); } mes l(".:: Congratulations ::."); #THANKS_DAY = gettime(5); #THANKS_STREAK+=1; if (debug || $@GM_OVERRIDE) { mes l("You got a %d", .@luck); mesf "Spins: %d/%d (cur %d extra %d)", .@i, .@spins, .@cur, .@extra; mes ""; //.@luck=$@GM_OVERRIDE; } // Switch the reward .@blv = BaseLevel + TOP3AVERAGELVL() / 2; switch (.@luck) { case 0: // EXP .@p=.@blv*#THANKS_STREAK; .@p*=3; getexp .@p, 0; mes l("You got %d EXP!", .@p); break; case 1: // JEXP .@p=.@blv*#THANKS_STREAK; .@p=.@p*15/10; getexp 0, .@p; mes l("You got %d JEXP!", .@p); break; case 2: // GP .@p=.@blv*#THANKS_STREAK; Zeny+=.@p; mes l("You got %d GP!", .@p); break; case 3: // MOBPT .@p=.@blv*#THANKS_STREAK; Mobpt+=.@p; mes l("You got %d Monster Points!", .@p); break; case 4: // RES .@p=.@blv*#THANKS_STREAK; .@p*=3; REAL_ESTATE_CREDITS+=.@p; mes l("You got %d Real Estate Credits!", .@p); break; case 5: // GIFT .@p=BronzeGift; .@p=(#THANKS_STREAK > 7 ? SilverGift : .@p); .@p=(#THANKS_STREAK > 15 ? GoldenGift : .@p); .@p=(#THANKS_STREAK > 22 ? PrismGift : .@p); .@p=(#THANKS_STREAK > 27 ? SupremeGift : .@p); mes l("You got a(n) %s gift!", getitemlink(.@p)); getitem .@p, 1; break; case 6: // STR C .@p=#THANKS_STREAK; getitem StrangeCoin, .@p; mes l("You got %d %s!", .@p, getitemlink(StrangeCoin)); break; case 7: // HERO C .@p=#THANKS_STREAK; .@p+=getq2(LoFQuest_HH)*max(1,#THANKS_STREAK/10); getitem HeroCoin, .@p; mes l("You got %d %s!", .@p, getitemlink(HeroCoin)); break; case 8: // MERC .@p=any(MercCard_GonzoDark, MercCard_Rosa, MercCard_Soren, MercCard_Apane); .@p=(#THANKS_STREAK > 7 ? any(MercCard_EarthWitch, MercCard_Demure, MercCard_Jesusalva, MercCard_Pookie) : .@p); .@p=(#THANKS_STREAK > 14 ? any(MercCard_Arthur, MercCard_LawnCable, MercCard_Crazyfefe, MercCard_Saulc) : .@p); .@p=(#THANKS_STREAK > 21 ? any(MercCard_Swezanne, MercCard_DragonStar, MercCard_Msawis, MercCard_Aisen) : .@p); .@p=(#THANKS_STREAK > 27 ? any(MercCard_Xanthem, MercCard_Woody, MercCard_Lilanna) : .@p); getitem .@p, 1; mes l("You got a %s!", getitemlink(.@p)); break; case 9: // CARD .@p=any(NatureCard, NinjaCard, MageCard, DruidCard, ClericCard, KnightCard, HeroCard, NecromancerCard); .@p=(#THANKS_STREAK > 24 ? any(SpeedCard, ReflectCard, PowerCard, WallCard) : .@p); getitem .@p, 1; mes l("You got a %s!", getitemlink(.@p)); break; case 10: // FRUIT .@p=MysteriousFruit; getitem .@p, 1; mes l("You got a %s!", getitemlink(.@p)); break; case 11: // BLUE .@p=any(EquipmentBlueprintA, EquipmentBlueprintA, AlchemyBlueprintA); .@p=(#THANKS_STREAK > 7 ? any(EquipmentBlueprintB, EquipmentBlueprintB, AlchemyBlueprintB) : .@p); .@p=(#THANKS_STREAK > 14 ? any(EquipmentBlueprintC, EquipmentBlueprintC, AlchemyBlueprintC) : .@p); .@p=(#THANKS_STREAK > 21 ? any(EquipmentBlueprintD, EquipmentBlueprintD, AlchemyBlueprintD) : .@p); .@p=(#THANKS_STREAK > 27 ? any(EquipmentBlueprintE, EquipmentBlueprintE, AlchemyBlueprintE) : .@p); getitem .@p, 1; mes l("You got a %s!", getitemlink(.@p)); break; } // Special bonus if (#THANKS_STREAK % 7 == 0) { getitem StrangeCoin, 10; mesc l("%d day streak! Gained %d bonus %s!", #THANKS_STREAK, 10, getitemlink(StrangeCoin)); } // Close next; setskin ""; closeclientdialog; return; } // ChocolateDay() function script ChocolateDay { if (!playerattached()) return; // Date check if (gettime(6) != JULY) return; if (gettime(5) != 7) return; // Max. 80% chances, 0.4% per monster level .@lv=min(200, getmonsterinfo(killedrid, MOB_LV)); if (rand2(10000) < (.@lv*40)) { // Chocolate Bar: 73%; Chocolate Dye: 6.7% .@choco=any(ChocolateBar, ChocolateBar, ChocolateBar, ChocolateBar, ChocolateMouboo, ChocolateBiscuit, ChocolateBunny, ChocolateBar, ChocolateBar, ChocolateBar, ChocolateBar, ChocolateDye, ChocolateBar, ChocolateBar, ChocolateBar); getmapxy(.@m$, .@x, .@y, 0); .@x+=rand2(-1,1); .@y+=rand2(-1,1); makeitem(.@choco, 1, .@m$, .@x, .@y); } return; } // CoffeeDay() function script CoffeeDay { if (!playerattached()) return; // Date check if (gettime(6) != OCTOBER) return; if (gettime(5) != 1) return; // Max. 22% chances, 0.1% per monster level .@lv=min(200, getmonsterinfo(killedrid, MOB_LV)); if (rand2(10000) < (.@lv*11)) { getmapxy(.@m$, .@x, .@y, 0); .@x+=rand2(-1,1); .@y+=rand2(-1,1); makeitem(Coffee, 1, .@m$, .@x, .@y); } return; } // FSFDay() function script FSFDay { if (!playerattached()) return; // Date check if (gettime(6) != SEPTEMBER) return; if (gettime(5) != 9) return; // Max. 0.16% chances, 0.008% per monster level .@lv=min(200, getmonsterinfo(killedrid, MOB_LV)); if (rand(1000000) < (.@lv*8)) { getmapxy(.@m$, .@x, .@y, 0); .@x+=rand2(-1,1); .@y+=rand2(-1,1); // Ancient 50%, Equipment 25%, Alchemy 25% .@bp = any(AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, AncientBlueprint, EquipmentBlueprintA, EquipmentBlueprintB, EquipmentBlueprintC, EquipmentBlueprintD, EquipmentBlueprintE, AlchemyBlueprintA, AlchemyBlueprintB, AlchemyBlueprintC, AlchemyBlueprintD, AlchemyBlueprintE); makeitem(.@bp, 1, .@m$, .@x, .@y); } return; } // CraftmasterDay() function script CraftmasterDay { if (!playerattached()) return; // Date check if (!$BETASERVER) return; if (gettime(7) != 2021) return; if (gettime(6) != JUNE) return; if (gettime(5) != 21) return; if (getmap() != "018-3") return; // Scored a Blue Print (2.5%) if (rand2(10000) < 250) { if (BaseLevel > 80 && REBIRTH) getitem any(EquipmentBlueprintE, AlchemyBlueprintE, EquipmentBlueprintD, AlchemyBlueprintD, EquipmentBlueprintC, AlchemyBlueprintC, EquipmentBlueprintB, AlchemyBlueprintB, EquipmentBlueprintA, AlchemyBlueprintA), 1; else if (BaseLevel > 70) getitem any(EquipmentBlueprintD, AlchemyBlueprintD, EquipmentBlueprintC, AlchemyBlueprintC, EquipmentBlueprintB, AlchemyBlueprintB, EquipmentBlueprintA, AlchemyBlueprintA), 1; else if (BaseLevel > 45) getitem any(EquipmentBlueprintC, AlchemyBlueprintC, EquipmentBlueprintB, AlchemyBlueprintB, EquipmentBlueprintA, AlchemyBlueprintA), 1; else if (BaseLevel > 20) getitem any(EquipmentBlueprintB, AlchemyBlueprintB, EquipmentBlueprintA, AlchemyBlueprintA), 1; else getitem any(EquipmentBlueprintA, AlchemyBlueprintA), 1; return; } // Scored Monster Points (9%) if (rand2(10000) < 900) { .@mpt=rand2(BaseLevel*10, BaseLevel*100); // 600~6000 usually Mobpt+=.@mpt; dispbottom l("Acquired: %s Monster Points", fnum(.@mpt)); return; } // Autocraft (1%) if (rand2(10000) < 100) { .@rc=any(rand2(51, 62), 65, 66, rand2(72, 76), rand2(77, 81), 82, 98, 99, 100, rand2(93, 97), rand2(88, 91), rand(83, 87), 92, 101, rand2(102,117), any(122, 112), rand2(125, 134), rand2(135, 143)); // Retrieve ID .@it=getcraftcode(.@rc); if (.@it <= 0) return; // Mark the crafting in your score variable CRAFTING_SCORE_COMPLETE+=getiteminfo(.@it, ITEMINFO_ELV); // Update your score book CRAFTING_SCORE=(CRAFTING_SCORE_COMPLETE/40); // Receive item getitembound(.@it, 1, 1); // Apply options if possible if (getskilllv(TMW2_CRAFT)) { delinventorylist(); // Needed, because we'll rely on rfind() getinventorylist(); .@index=array_rfind(@inventorylist_id, .@it); // Just to be sure, if this have an option, get something else if (getitemoptionparambyindex(.@index, 0)) { .@index=array_find(@inventorylist_id, .@it); } callfunc("csys_Apply", .@index); } dispbottom l("Successfully Crafted: %s", getitemname(.@it)); return; } return; } 000-0,0,0,0 script #EventCore NPC_HIDDEN,{ end; // confEvent(event ID, stday, stmon, endday, endmon) function confEvent { setd("."+getarg(0)+"_stday", getarg(1)); setd("."+getarg(0)+"_stmon", getarg(2)); setd("."+getarg(0)+"_endday", getarg(3)); setd("."+getarg(0)+"_endmon", getarg(4)); // Save the event key? //.@confname=".conf_"+getarg(2)+"$"; //setd(.@confname+"["+getarraysize(.@confname)+"]", getarg(0)); // Save only the day? (And use if statement) .@confname$=".conf_"+getarg(2); .@size=getarraysize(getd(.@confname$)); setd(.@confname$+"["+.@size+"]", getarg(1)); //debugmes "CONFIGURE EVENT, %s[%d] = %d", .@confname$, .@size, getarg(1); //debugmes "CNAME: %s", getarg(0); return; } // Event Schedule (all dates are inclusive) // NEVER, ever, include the last day of the month. OnInit: confEvent("valentine", 13, FEBRUARY, 16, FEBRUARY); confEvent("tmw2day", 1, MARCH, 7, MARCH); confEvent("patrick", 15, MARCH, 19, MARCH); confEvent("easter", 17, APRIL, 24, APRIL); confEvent("worker", 27, APRIL, 3, MAY); confEvent("thanks", 1, NOVEMBER, 29, NOVEMBER); // NEVER use the last day of the month here confEvent("xmas", 19, DECEMBER, 2, JANUARY); // Some setup .@isinit=true; disablenpc "sPatrick"; FYE_Normalize(); // Check for events every midnight OnClock0000: // No events on test server if (debug && !$@GM_OVERRIDE) end; // Prepare variables .@d=gettime(GETTIME_DAYOFMONTH); .@m=gettime(GETTIME_MONTH); .@o=gettime(GETTIME_WEEKDAY); // Resets at 0 (sunday) debugmes "A new day begins! Today is %02d/%02d", .@d, .@m; // Override the server-wide randomness resetrng(); // Initialize the event core if ($@DEBUG_OD) .@d=$@DEBUG_OD; if ($@DEBUG_OM) .@m=$@DEBUG_OM; consoleinfo "EVENT CORE, the %02d/%02d", .@d, .@m; // Is there another event this week? if (!$HARDCORE && .@o == MONDAY && !.@isinit) { .@dofy=true; .@confname$=".conf_"+.@m; // NOTE: Maybe make a single .annuals array and cycle it // Gather the ST variable from interest...? for (.@i=0;.@i < getarraysize(getd(.@confname$)); .@i++) { .@val=getd(.@confname$+"["+.@i+"]"); //debugmes "Looping, %d = %d", .@i, .@val; // Erm. if (.@val == 0) continue; // This script has a weakness: It cannot predict events starting // at the start or the end of the month. // So they might still overlap. // A possible solution is to, eventually, record start and end date. // And only inhibit FY event if the MONDAY is within the event...? // XXX: Now it inhibits by itself; But it should NOT begin a FYE if // another (annual) event is scheduled for the same week. // Namely: TMW2 Day and Thanksgiving debugmes "%d >= %d && %d <= %d", .@val, .@d-6, .@val, .@d+6; // In this case there's already an event! // .@d == .@val <= .@d+6 AND if ( .@val >= .@d-6 && .@val <= .@d+6 ) { .@dofy=false; break; } // continue... } // Stop previous event FYStopEvent(); // Trigger event framework if (.@dofy && $EVENT$ == "") FYNewEvent(); else debugmes "\033[1mAnother event is scheduled!"; } // Handle Valentine Day if (.@m >=.valentine_stmon && .@m <= .valentine_endmon) { // It's tomorrow: Send out an announcement if (.@d == .valentine_stday - 1) { kamibroadcast("Valentine Day will start tomorrow!"); } // Last Day: Send out an announcement if (.@d == .valentine_endday) { kamibroadcast("It's the last day for Valentine Event! Hurry up!"); } // Begin the event if (.@d == .valentine_stday) { kamibroadcast("Valentine Day begun!"); if ($EVENT$ != "") FYStopEvent(); $EVENT$="Valentine"; $@VALENTINE_LOVELETTER = htnew(); $@VALENTINE_GIFTSTACKS = htnew(); } // End the event the day after if (.@d == .valentine_endday+1) { kamibroadcast("Valentine Day ended!"); sClear(); $EVENT$=""; } } // Handle TMW2 Day if (.@m >=.tmw2day_stmon && .@m <= .tmw2day_endmon) { // It's tomorrow: Send out an announcement if (.@d == .tmw2day_stday - 1) { kamibroadcast("Moubootaur Legends Anniversary will start tomorrow!"); } // Last Day: Send out an announcement if (.@d == .tmw2day_endday) { kamibroadcast("It's the last day of our Anniversary Event! Hurry up!"); } // Begin the event if (.@d == .tmw2day_stday) { kamibroadcast("Moubootaur Legends Anniversary Event begun!"); if ($EVENT$ != "Anniversary") $BCONFB_EXPR+=50; $EVENT$="Anniversary"; } // End the event the day after if (.@d == .tmw2day_endday+1) { kamibroadcast("Our Special Anniversary Event ended! Thanks!"); sClear(); $EVENT$=""; } } // Handle St. Patrick Day // During this day, a special four leaf clover is spawned daily, at 4 times in the day // in all forests: 6:00, 12:00, 18:00 and 00:00. // $PATRICK_DAYMAX if (.@m >=.patrick_stmon && .@m <= .patrick_endmon) { // It's tomorrow: Send out an announcement if (.@d == .patrick_stday - 1) { kamibroadcast("St. Patrick Day will start tomorrow!"); } // Last Day: Send out an announcement else if (.@d == .patrick_endday) { kamibroadcast("It's the last day for St. Patrick Event! Hurry up!"); } // Begin the event else if (.@d == .patrick_stday) { kamibroadcast("St. Patrick Day begun!"); if ($EVENT$ != "") FYStopEvent(); $EVENT$="Patrick"; $@PATRICK_DAYMAX=.patrick_endday; enablenpc "sPatrick"; setnpcdisplay("Aurora", "Patrick Saulc", NPC_WEIRDGREEN); enablenpc "St. Patrick Gold Pot"; donpcevent "St. Patrick Gold Pot::OnForcedMove"; } // End the event the day after else if (.@d == .patrick_endday+1) { kamibroadcast("St. Patrick Day ended!"); sClear(); $EVENT$=""; donpcevent "sPatrick::OnCleanUp"; } } // Handle Easter if (.@m >=.easter_stmon && .@m <= .easter_endmon) { // It's tomorrow: Send out an announcement if (.@d == .easter_stday - 1 && .@m == .easter_stmon) { kamibroadcast("Easter will start tomorrow!"); } // Last Day: Send out an announcement else if (.@d == .easter_endday && .@m == .easter_endmon) { kamibroadcast("It's the last day for Easter Event! Hurry up!"); } // Begin the event else if (.@d == .easter_stday && .@m == .easter_stmon) { kamibroadcast("Easter begun!"); if ($EVENT$ != "") FYStopEvent(); sEaster(); } // End the event the day after else if (.@d == .easter_endday+1 && .@m == .easter_endmon) { kamibroadcast("Easter ended!"); sClear(); $EVENT$=""; } } // Handle Worker Day if (.@m >=.worker_stmon && .@m <= .worker_endmon) { // It's tomorrow: Send out an announcement if (.@d == .worker_stday - 1 && .@m == .worker_stmon) { kamibroadcast("Worker Day will start tomorrow!"); } // Last Day: Send out an announcement else if (.@d == .worker_endday && .@m == .worker_endmon) { kamibroadcast("It's the last day for Worker Day Event! Hurry up!"); } // Begin the event else if (.@d == .worker_stday && .@m == .worker_stmon) { kamibroadcast("Worker Day begun!"); if ($EVENT$ != "") FYStopEvent(); $EVENT$="Worker"; } // End the event the day after else if (.@d == .worker_endday+1 && .@m == .worker_endmon) { kamibroadcast("Worker Day ended!"); sClear(); $EVENT$=""; } } // Handle Thanksgiving Day if (.@m >=.thanks_stmon && .@m <= .thanks_endmon) { // It's tomorrow: Send out an announcement if (.@d == .thanks_stday - 1 && .@m == .thanks_stmon) { kamibroadcast("Thanksgiving will start tomorrow!"); } // Last Day: Send out an announcement else if (.@d == .thanks_endday && .@m == .thanks_endmon) { kamibroadcast("It's the last day for Thanksgiving Event! Hurry up!"); } // Begin the event else if (.@d == .thanks_stday && .@m == .thanks_stmon) { kamibroadcast("Thanksgiving begun!"); if ($EVENT$ != "") FYStopEvent(); $EVENT$="Thanksgiving"; donpcevent("sThankAeros::OnTimer90000"); } // End the event the day after else if (.@d == .thanks_endday+1 && .@m == .thanks_endmon) { kamibroadcast("Thanksgiving ended!"); sClear(); $EVENT$=""; } } // Handle Christmas. It goes past the year so the rule is different, BEWARE if (.@m == .xmas_stmon || .@m == .xmas_endmon) { // It's tomorrow: Send out an announcement if (.@d == .xmas_stday - 1 && .@m == .xmas_stmon) { kamibroadcast("Christmas will start tomorrow!"); } // Last Day: Send out an announcement else if (.@d == .xmas_endday && .@m == .xmas_endmon) { kamibroadcast("It's the last day for Christmas Event! Hurry up!"); } // Begin the event else if (.@d == .xmas_stday && .@m == .xmas_stmon) { kamibroadcast("Christmas begun!"); if ($EVENT$ != "") FYStopEvent(); $EVENT$="Christmas"; DelQuestFromEveryPlayer(SQuest_Christmas); sChristmas(); } // End the event the day after else if (.@d == .xmas_endday+1 && .@m == .xmas_endmon) { kamibroadcast("Christmas ended!"); sClear(); $EVENT$=""; } } debugmes "EVENT CORE has finished"; end; }