// TMW2 scripts. // Authors: // Jesusalva // Description: // AURORA EVENT FRAMEWORK // Previously known as FY:Event System // // Controls weekly events so Saulc, seeds and I can take vacations. // See also: seasons.txt, command/event.txt, event.txt, 003-1/events.txt // soulmenhir.txt, scoreboards.txt and, of course, the event maps (if any). // Aurora Event Framework functions are called by event.txt // specs override and is overriden by those defined in commands/event.txt // Variables: // $MOST_HEROIC$ // Updated every 2 weeks, the top 1 from previous event // Only the hero may begin sieges against Fortress Town. // Every NPC will recognize them, and Lightbringer will also // pay special attention to them. // $FYEVENT_CYCLE // Current cycle. I thought in using gettimeparam(WEEK) but gave up. // Q_AuroraEvent // Quest Variable: DayCtrl, Score, ClaimedControl // // Event Specific Variables: // $REGNUM_BLESSMAP$ // Map under Regnum's Blessing // $REGNUM_BLESSMAP_H$ // Human-readable form of the map under Regnum's Blessing // // $FYREWARD_PT // Array with minimum points for rewards (primary key) // $FYREWARD_ID // Array with claimable reward IDs // $FYREWARD_AM // Array with the amount of the reward ID you'll receive // $FYLOGIN_PTS // How many event score boost you'll receive for daily login // // $WORLDEXPO_ENEMY$ // Name of the enemy responsible for ruining the World's Expo // AEF: BEGIN function script FYNewEvent { debugmes "\033[1mFY event is set to happen...\033[0m"; // Aurora Events only begin after Liberation Day if ($GAME_STORYLINE < 1) return; // Update the loop $FYEVENT_CYCLE+=1; // Overrides standard event system $EVENT$=""; // Delayed cleanup (Just in case) DelQuestFromEveryPlayer(Q_AuroraEvent); DelItemFromEveryPlayer(EventTreasure1); DelItemFromEveryPlayer(EventTreasure2); DelItemFromEveryPlayer(EventTreasure3); DelItemFromEveryPlayer(EventFish); DelItemFromEveryPlayer(EventOre); // Select the event switch ($FYEVENT_CYCLE % 12) { case 1: $EVENT$="Kamelot"; kamibroadcast("Kamelot Season is now open!", "Aurora Events"); break; case 2: $EVENT$="Expo"; callfunc("FYEConf_Expo"); kamibroadcast("World Expo is now open!", "Aurora Events"); break; case 3: $EVENT$="Regnum"; callfunc("FYEConf_Regnum"); kamibroadcast("Regnum's Blessing: "+$REGNUM_BLESSMAP_H$+" is now blessed!", "Aurora Events"); break; case 4: $EVENT$="Fishing"; callfunc("FYEConf_Fishing"); kamibroadcast("Catch the Golden Fish is now open!", "Aurora Events"); break; case 5: $EVENT$="Candor"; kamibroadcast("Candor Battle Season is now open!", "Aurora Events"); break; case 6: $EVENT$="Mining"; callfunc("FYEConf_Mining"); kamibroadcast("Minion Union's Research Request is now open!", "Aurora Events"); break; case 7: // FIXME: PLACEHOLDER $EVENT$="Kamelot"; kamibroadcast("Kamelot Season is now open!", "Aurora Events"); break; case 8: // FIXME: PLACEHOLDER $EVENT$="Expo"; callfunc("FYEConf_Expo"); kamibroadcast("World Expo is now open!", "Aurora Events"); break; case 9: // FIXME: PLACEHOLDER $EVENT$="Regnum"; callfunc("FYEConf_Regnum"); kamibroadcast("Regnum's Blessing: "+$REGNUM_BLESSMAP_H$+" is now blessed!", "Aurora Events"); break; case 10: // FIXME: PLACEHOLDER $EVENT$="Fishing"; callfunc("FYEConf_Fishing"); kamibroadcast("Catch the Golden Fish is now open!", "Aurora Events"); break; case 11: // FIXME: PLACEHOLDER $EVENT$="Candor"; kamibroadcast("Candor Battle Season is now open!", "Aurora Events"); break; default: // FIXME: PLACEHOLDER $EVENT$="Mining"; callfunc("FYEConf_Mining"); kamibroadcast("Minion Union's Research Request is now open!", "Aurora Events"); break; } donpcevent "Aurora::OnRestore"; return; } // Returns an item: (type, lv). Used by the function below (FYE_Autoset) // types: misc, bp, warp, pot, heal, ore, magic, gift // maxlv: 3 5 2 3 - 6 - 5 function script FYT { .@t=getarg(0); .@l=getarg(1, 0); switch (.@t) { case FY_MISC: switch (.@l) { case 1: return any(SmokeGrenade, ScentGrenade, Grenade, Lockpicks); case 2: return any(MysteriousBottle, TreasureMap); case 3: return any(ArcmageBoxset, MercBoxA); } break; case FY_BP: switch (.@l) { case 1: return any(EquipmentBlueprintA, AlchemyBlueprintA); case 2: return any(EquipmentBlueprintB, AlchemyBlueprintB); case 3: return any(EquipmentBlueprintC, AlchemyBlueprintC); case 4: return any(EquipmentBlueprintD, AlchemyBlueprintD); case 5: return any(EquipmentBlueprintE, AlchemyBlueprintE); } break; case FY_WARP: switch (.@l) { case 1: return any(TulimWarpCrystal, CandorWarpCrystal, HurnsWarpCrystal, LoFWarpCrystal); case 2: return any(HalinWarpCrystal, NivalWarpCrystal, FrostiaWarpCrystal); } break; case FY_POT: switch (.@l) { case 1: return any(LukPotionA, DexPotionA, IntPotionA, VitPotionA, AgiPotionA, HastePotion, StrengthPotion); case 2: return any(LukPotionB, DexPotionB, IntPotionB, VitPotionB, AgiPotionB, MoveSpeedPotion, PrecisionPotion, DodgePotion); case 3: return any(SacredImmortalityPotion, SacredLifePotion, SacredManaPotion); } break; case FY_ORE: switch (.@l) { case 1: return any(CopperIngot, IronIngot); case 2: return any(SilverIngot, GoldIngot); case 3: return any(TinIngot, LeadIngot); case 4: return any(TitaniumIngot, TerraniteIngot); case 5: return any(IridiumIngot, PlatinumIngot); case 6: return any(Diamond, Ruby, Emerald, Sapphire, Topaz, Amethyst); } break; case FY_GIFT: switch (.@l) { case 1: return BronzeGift; case 2: return SilverGift; case 3: return GoldenGift; case 4: return PrismGift; case 5: return SupremeGift; } break; // Single cases doesn't needs break case FY_HEAL: return any(SpearmintTea, Coffee, ClothoLiquor); case FY_MAGIC: return any(FluoPowder, Quill, ScholarshipBadge);; } return Exception("Invalid cast to FYEIT: "+.@t+" (Lv "+.@l+")", RB_IRCBROADCAST|RB_DEBUGMES|RB_GLOBALANNOUNCE, Bread); } function script FYE_Autoset { // Sets 30 ranked rewards .@b=FY_BP; .@g=FY_GIFT; .@h=FY_HEAL; .@m=FY_MISC; .@mg=FY_MAGIC; .@o=FY_ORE; .@p=FY_POT; .@w=FY_WARP; setarray $FYREWARD_ID, FYT(.@g, 1), StrangeCoin, FYT(.@m, 1), FYT(.@b, 1), FYT(.@p, 1), FYT(.@h, 1), FYT(.@o, 1), FYT(.@o, 6), FYT(.@g, 2), FYT(.@w, 1), FYT(.@b, 2), FYT(.@m, 2), FYT(.@o, 2), FYT(.@p, 2), FYT(.@o, 3), FYT(.@b, 3), FYT(.@m, 3), StrangeCoin, FYT(.@mg, 1), FYT(.@g, 3), FYT(.@w, 2), StrangeCoin, FYT(.@b, 4), FYT(.@p, 3), AncientBlueprint, FYT(.@g, 4), FYT(.@o, 4), FYT(.@b, 5), FYT(.@o, 5), FYT(.@g, 5); // Item Amount Table .@hv=rand2(1,3); .@p1=any(1,2); .@p2=(.@p1 == 1 ? 2 : 1); setarray $FYREWARD_AM, 1, 20, 1, 1, .@p1, .@hv, 1, 1, 1, 1, 1, 1, 1, .@p2, 1, 1, 1, 60, 1, 1, 1, 100, 1, 1, 1, 1, 1, 1, 1, 1; return; } // Modify Kamelot function script FYE_Kamelot { .@g=getcharid(2); if ($@FYE_KAMELOT[.@g] != gettimeparam(GETTIME_DAYOFMONTH)) { mesc l("Kamelot Season is open!"); // Instance still exists if (instanceowner($@KAMELOT_ID[.@g]) == .@g) { mesc l("However, your guild just challenged Kamelot Dungeons."); mesc l("Please wait a while."); return false; } mesc l("Should we?"); next; askyesno(); closeclientdialog(); // Not going? Spoilsport if (@menu == ASK_NO) return false; // Someone began while you waited if (instanceowner($@KAMELOT_ID[.@g]) == .@g) return true; // Begin //callfunc("KamelotCleanup", .@g); // Not needed $KAMELOT_COOLDOWN[.@g] = ($KAMELOT_COOLDOWN[.@g] ? 1 : 0); $@FYE_KAMELOT[.@g] = gettimeparam(GETTIME_DAYOFMONTH); mesc l("Have fun!"); next; closeclientdialog(); return true; } return false; } // Configure Regnum Blessing function script FYEConf_Regnum { setarray .@ma$, "004-1", "007-1", "004-2", "010-2", "014-3", "014-5", "015-5", "018-3", "019-1", "025-2", "025-2-1", "soren"; setarray .@mb$, "Tulimshar Outskirts", "Tulimshar Mines", "Tulimshar (West) Canyon", "Halinarzo (East) Canyon", "Central Woodlands", "North Woodlands", "Abandoned Mines (Woodlands)", "Somber Caves (LoF)", "Snow Field", "Fortress Island - South", "Fortress Island South Cave", "Soren Island"; .@m=rand2(getarraysize(.@ma$)); $REGNUM_BLESSMAP$=.@ma$[.@m]; $REGNUM_BLESSMAP_H$=.@mb$[.@m]; // Apply the blessing setmapflag(.@ma$[.@m], mf_bexp, 300); return; } // Configure World Expo function script FYEConf_Expo { $WORLDEXPO_ENEMY$=any("Xakabael the Dark", "Isbamuth", "Saulc", "SUSAN", "Terogan"); setarray $FYREWARD_PT, 100, 220, 440, 880, 1320, 1760, 2640, 3520, 5280, 7040, 10560, 14080, 21120, 28160, 35200, 42240, 56320, 70400, 84480, 112640, 140800, 168960, 197120, 225280, 281160, 337920, 394240, 450560, 550000, 675000; // PS. Max Est. 225280 pts (#24 - Before Ancient Blueprint) FYE_Autoset(); $FYLOGIN_PTS=rand2(18,22); return; } // Modify Treasure Chests function script FYE_Expo { // TODO: Merit-based random formula getitem EventTreasure1, 1+rand2(15); // 15 getitem EventTreasure2, rand2(6); // 15 getitem EventTreasure3, rand2(4); // 15 // Total: (15+15+15)=1~45 points [AVG: 22 pts] return; } // Configure Fishing function script FYEConf_Fishing { setarray $FYREWARD_PT, 42, 63, 94, 141, 212, 318, 478, 717, 1076, 1345, 1614, 2020, 2421, 3026, 3632, 4540, 5449, 6811, 8174, 10217, 12261, 15326, 18391, 21456, 24522; // PS. Max Est. 14400 pts (#21 - Before 100 Strange Coins) FYE_Autoset(); $FYLOGIN_PTS=rand2(6,8); return; } // Modify Fishing function script FYE_Fishing { // TODO: Merit-based random formula [AVG: 3.5] about 10pts/min getitem EventFish, rand2(1, 6); return; } // Configure Mining Union Research Event function script FYEConf_Mining { setarray $FYREWARD_PT, 100, 220, 440, 880, 1320, 1760, 2640, 3520, 5275, 7040, 10560, 14080, 21120, 28160, 35200, 42240, 57000, 70400, 85000, 112640, 140800, 169000, 197120, 225300, 281160, 337920, 394240, 450560, 550000, 675000; // PS. Max Est. 705740 pts (overflow) FYE_Autoset(); $FYLOGIN_PTS=rand2(16,20); return; } // Modify Bifs function script FYE_Mining { .@mob=getarg(0, killedrid); // Only ores if (getmonsterinfo(.@mob, MOB_RACE) != RC_Mineral) return; // TODO: Merit-based random formula [AVG: 5] about 70pts/min // TODO: Big vs Small bifs (regex OK, size OK) .@ore=rand2(3, 6); if (.@mob == EleniumBif) .@ore-=1; getitem EventOre, .@ore; return; } // "Submit" button from 003-1/events.txt // Don't forget to enable it in npc/utils.txt as well!! function script FYE_Submit { .@day=getq(Q_AuroraEvent); .@pts=getq2(Q_AuroraEvent); // Handle daily login score rewards if (.@day != gettimeparam(GETTIME_DAYOFMONTH)) { setq1 Q_AuroraEvent, gettimeparam(GETTIME_DAYOFMONTH); setq2 Q_AuroraEvent, .@pts+$FYLOGIN_PTS; .@pts=getq2(Q_AuroraEvent); if ($FYLOGIN_PTS) dispbottom l("Daily Event Bonus: %d Points!", $FYLOGIN_PTS); } // Give you points if ($EVENT$ == "Expo") { // .:: WORLD EXPO EVENT ::. .@pts+=countitem(EventTreasure1)*1; .@pts+=countitem(EventTreasure2)*3; .@pts+=countitem(EventTreasure3)*5; setq2 Q_AuroraEvent, .@pts; delitem EventTreasure1, countitem(EventTreasure1); delitem EventTreasure2, countitem(EventTreasure2); delitem EventTreasure3, countitem(EventTreasure3); } else if ($EVENT$ == "Fishing") { // .:: CATCH THE GOLD FISH EVENT ::. .@pts+=countitem(EventFish)*1; setq2 Q_AuroraEvent, .@pts; delitem EventFish, countitem(EventFish); } else if ($EVENT$ == "Mining") { // .:: MINION UNION'S RESEARCH REQUEST EVENT ::. .@pts+=countitem(EventOre)*1; setq2 Q_AuroraEvent, .@pts; delitem EventOre, countitem(EventOre); } else { // Wut? This is not an Aurora Event Exception($EVENT$+" is NOT a valid Aurora Event; Misdefinition.\n\nPlease ensure that it is defined in utils, aurora, news, and command/event.\n\nFYE_Submit - FYEventUsesRanking - FYE_* - FYEConf_* - FYStopEvent", RB_DEFAULT|RB_ISFATAL); } return; } // Stops any Aurora Event function script FYStopEvent { setarray .@av$, "Kamelot", "Regnum", "Expo", "Fishing", "Candor", "Mining"; if (array_find(.@av$, $EVENT$) >= 0) { sClear(); $EVENT$=""; } return; } // Handle the ending of Aurora Events (see also functions/util.txt) function script FYRewardEvent { if (FYEventUsesRanking()) { debugmes("Rewards are due"); // This code absolutely can't fail: .@nb = query_sql("SELECT c.name, i.count2, c.char_id FROM `quest` AS i, `char` AS c WHERE i.quest_id="+Q_AuroraEvent+" AND i.char_id=c.char_id ORDER BY i.count2 DESC LIMIT 10", $@aurora_name$, $@aurora_value, $@aurora_charid); $MOST_HEROIC$=$@aurora_name$[0]; for (.@i=0;.@i < getarraysize($@aurora_charid);.@i++) { switch (.@i+1) { case 1: .@prize=120; break; case 2: .@prize=100; break; case 3: .@prize=80; break; case 4: case 5: .@prize=60; break; case 6: case 7: .@prize=40; break; default: .@prize=20; } rodex_sendmail($@aurora_charid[.@i], "Aurora Events", $EVENT$+" Reward!", "Final Ranking: #"+(.@i+1)+". Congratulations on making "+$@aurora_value[.@i]+" points on the event!", 0, StrangeCoin, .@prize); } // Destroy the quest DelQuestFromEveryPlayer(Q_AuroraEvent); deletearray $@aurora_name$; deletearray $@aurora_value; /* DelItemFromEveryPlayer(EventTreasure1); DelItemFromEveryPlayer(EventTreasure2); DelItemFromEveryPlayer(EventTreasure3); DelItemFromEveryPlayer(EventFish); DelItemFromEveryPlayer(EventOre); */ } return; } // Modify Mob Killing // Serves for multiple events, preserves killedrid function script AuroraMobkill { if ($EVENT$ == "Mining") FYE_Mining(killedrid); return; } // Normalize Aurora Event after a server restart function script FYE_Normalize { if ($EVENT$ == "Regnum") { // Reapply the Regnum's blessing setmapflag($REGNUM_BLESSMAP$, mf_bexp, 300); } return; }