// 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 (!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;
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;
// Do event (lasts 45 minutes)
if (!.event && !$@MK_SCENE && .score > 300 && (.users >= 3 || $@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
switch (.@luck) {
case 0: // EXP
.@p=BaseLevel*#THANKS_STREAK;
.@p*=3;
getexp .@p, 0;
mes l("You got %d EXP!", .@p);
break;
case 1: // JEXP
.@p=BaseLevel*#THANKS_STREAK;
.@p=.@p*15/10;
getexp 0, .@p;
mes l("You got %d JEXP!", .@p);
break;
case 2: // GP
.@p=BaseLevel*#THANKS_STREAK;
Zeny+=.@p;
mes l("You got %d GP!", .@p);
break;
case 3: // MOBPT
.@p=BaseLevel*#THANKS_STREAK;
Mobpt+=.@p;
mes l("You got %d Monster Points!", .@p);
break;
case 4: // RES
.@p=BaseLevel*#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;
}