// TMW 2 Script
// Author:
// Jesusalva
// Micksha
// Description:
// Part of Kamelot Guild Dungeon
// TODO: Random guard (Tezer) on the cursed soldier statues (easter egg)
042-0,58,28,0 script King Arthur NPC_KING_ARTHUR,{
function arthurSpawn;
.@g=getcharid(2);
.@pos=getguildrole(.@g, getcharid(3));
if (.@pos > GPOS_VICELEADER) goto L_Refusal;
if (!$KAMELOT_COOLDOWN[.@g]) goto L_Tutorial;
if ($KAMELOT_QUEST[.@g] & 1) goto L_Progress;
goto L_Prologue;
L_Prologue:
mesn l("King Arthur the Micksha");
mes l("Hello Adventurer.");
next;
mesn l("King Arthur the Micksha");
mes l("So good you are here. We have a huge problem.");
next;
npctalk l("JAIL THEM!!");
mesn l("King Arthur the Corrupted");
mes col(l("JAIL THEM!!"), 9)+l(" -- No, wait!");
next;
select
l("What is going on here?"),
l("Your problems are not mine. By the way, you really should consider taking a shower."),
l("[TUTORIAL]"),
l("You are weird, I have to go, sorry.");
mes "";
switch (@menu) {
case 1:
goto L_Quest;
case 2:
if (any(true, true, true, true, false))
goto L_Smash;
else
goto L_Annoyed;
case 3:
goto L_Tutorial;
case 4:
if (!any(true, true, true, true, false))
goto L_Smash;
else
goto L_Annoyed;
}
close;
L_Quest:
mesn l("King Arthur the Micksha");
mes l("Something is happening down there.");
next;
npctalk l("GUARDS! GET THEM!");
mesn l("King Arthur the Corrupted");
mes l("It is so dangerous, and it... ")+col(l("GUARDS! GET THEM!"), 9);
next;
mesn l("King Arthur the Micksha");
mes l("You must be fast! The guards are also affected.");
next;
npctalk l("OFF WITH THEIR HEADS!");
mesn l("King Arthur the Corrupted");
mes col(l("OFF WITH THEIR HEADS!"), 9)+l(" Take this key, it opens the door behind my throne.");
next;
npctalk l("AFTER THEM!!");
mesn l("King Arthur the Corrupted");
mes l("Be careful! ")+col(l("AFTER THEM!!"), 9);
next;
// Be sure the quest only starts now, and destroy any eventual artifact
KamelotCleanup(.@g);
getguildmember(.@g, 2); // 2 = count by account IDs
$KAMELOT_QUEST[.@g]=1;
$KAMELOT_MX[.@g]=getguildavg(.@g);
$KAMELOT_PC[.@g]=$@guildmembercount;
$KAMELOT_KEY[.@g]=any(1,2,4,8);
$KAMELOT_PASSCODE[.@g]=rand2(1, 31);
if (!is_admin()) // FIXME: This should be unconditional
$KAMELOT_COOLDOWN[.@g] = gettimeparam(GETTIME_WEEKDAY);
mapannounce(getmap(), "##1KAMELOT CASTLE, GUILD DUNGEON: MISSION START!", bc_map);
// Spawn a few foot soldiers
arthurSpawn(1, 25, 29, 43, 37);
arthurSpawn(3, 22, 43, 43, 73);
arthurSpawn(5, 76, 55, 98, 77);
mesc l(".:: KAMELOT CASTLE, THE GUILD DUNGEON ::."), 1;
mes "";
mes l("1. Investigate Kamelot Basements");
mes l("2. Free Kamelot from its curse!");
close;
//////////////////////////////////////////////////////////////////////////
// King manages to control himself
L_Annoyed:
npctalk l("Don't bore me.");
closeclientdialog;
close;
// King loses his coolness.
L_Smash:
npctalk l("MEEEEEERLIN!!! SMASH THEM!!");
maptimer(getmap(), 300, instance_npcname(.name$)+"::OnPreSmash");
closeclientdialog;
close;
OnPreSmash:
specialeffect FX_CUPID, AREA, getcharid(3);
addtimer(380, instance_npcname(.name$)+"::OnSmash");
end;
OnSmash:
percentheal -100, -100;
end;
//////////////////////////////////////////////////////////////////////////
L_Progress:
if ($KAMELOT_QUEST[.@g] & 64) goto L_Reward;
npctalk l("What are you still doing here?! GO!!");
mes l("Read tutorial again?");
next;
if (askyesno() == ASK_YES) goto L_Tutorial;
close;
L_Reward:
.@cn=$KAMELOT_MX[.@g]/3;
mesn;
mesq l("Thanks for vanishing the source of the curse.");
next;
mesn;
mesq l("Since Merlin left in an expedition with Morgan, strange things have been happening in Kamelot.");
next;
mesn;
mesq l("Please accept this reward from my part. And if anything else happens again, I'll leave the doors open for you and your guild.");
next;
warp "014-4", 67, 27;
if ($KAMELOT_QUEST[.@g] & 128)
goto L_DoReward2;
$KAMELOT_QUEST[.@g]=$KAMELOT_QUEST[.@g]|128;
getitem GuildCoin, .@cn;
guildgetexp(.@cn*1000);
// TODO: Make this a decent reward
getitembound any(SilverRing, GoldenRing), 1, 2;
goto L_DoReward2;
//////////////////////////////////////////////////////////////////////////
L_Tutorial:
// Update variable
if ($KAMELOT_COOLDOWN[.@g] != gettimeparam(GETTIME_WEEKDAY))
$KAMELOT_COOLDOWN[.@g]=gettimeparam(GETTIME_WEEKDAY)-1;
mes b(".:: KAMELOT CASTLE ::.");
mes "The Guild Dungeon of Kamelot Castle";
mes "";
mes l("Kamelot Castle is a GUILD DUNGEON which refreshes WEEKLY.");
mes l("Only the Guild Master and the Vice Leaders are capable of starting this quest.");
next;
mes l("An unlimited number of members can join.");
mes l("Once the quest is started, entrance will be closed.");
mes l("No one can go out during the quest, so ensure every guild member has proper equipment, potions, and time for this dungeon.");
next;
mes l("Additionally, for the optimal experience, ensure your party has at least the following members and items:");
mes "";
mes l("* Thief");
mes l("* Mage");
mes l("* %s", getitemlink(TreasureKey));
mes l("* %s", getitemlink(Lockpicks));
mes "";
next;
mes b(".:: VICTORY REWARDS ::.");
mes l("Victory prizes include guild experience, guild money, and guild bound items.");
mes "";
mes b(".:: DEFEAT PENALTIES ::.");
mes l("If your guild is defeat during the quest, you'll need to wait the weekly cooldown to expire.");
mes "";
mes "----------------- by Lancelot";
next;
clear;
if ($KAMELOT_QUEST[.@g] & 1) goto L_Progress;
goto L_Prologue;
//////////////////////////////////////////////////////////////////////////
L_Refusal:
if ($KAMELOT_QUEST[.@g] & 64) goto L_Reward2;
mesc l("This man is THE LEGENDARY KING ARTHUR!");
mes "";
mesc l("I better leave talking to him to the guild Vice Leaders and Master.");
close;
L_Reward2:
mesn;
mesq l("Thanks for your services, knight. One day, you might even deserve a seat at this castle.");
next;
L_DoReward2:
mesn;
mesq l("Farewell, until the next time. Shall we met again, and may the light guide our paths.");
warp "014-4", 67, 27;
.@cn=$KAMELOT_MX[.@g]/10;
// Penalty if you dragged the guild down
if (BaseLevel < $KAMELOT_MX[.@g]*5/10)
.@cn=.@cn*5/10;
// Penalty if you carried the guild
if (BaseLevel > $KAMELOT_MX[.@g]*15/10)
.@cn=.@cn*5/10;
// Your reward
.@cn+=1;
getitem GuildCoin, .@cn;
guildgetexp(.@cn*300);
getexp BaseLevel*10, .@cn*35;
Zeny+=.@cn*1000;
close;
OnKillMob:
if (!playerattached()) end;
.@g=getcharid(2);
if (.@g < 1) percentheal -100, -100;
getexp $KAMELOT_MX[.@g], $KAMELOT_MX[.@g]/2+1;
end;
function arthurSpawn {
.@label$=instance_npcname(.name$)+"::OnKillMob";
.@gcount=getarg(0);
.@x1=getarg(1);
.@x2=getarg(3);
.@y1=getarg(2);
.@y2=getarg(4);
.@g=getcharid(2);
if (.@g < 1) percentheal -100, -100;
.@avg=$KAMELOT_MX[.@g];
.@m$=getmap();
for (.@i=0; .@i < .@gcount; .@i++) {
.@mobId=CursedSoldier;
.@mob=areamonster(.@m$, .@x1, .@y1, .@x2, .@y2, strmobinfo(1, .@mobId), .@mobId, 1, .@label$);
// Reconfigure the monster
setunitdata(.@mob, UDT_LEVEL, .@avg);
setunitdata(.@mob, UDT_STR, 1+.@avg/6);
setunitdata(.@mob, UDT_AGI, 1+.@avg/7);
setunitdata(.@mob, UDT_VIT, 1+.@avg/6);
setunitdata(.@mob, UDT_INT, 1+.@avg/6);
setunitdata(.@mob, UDT_DEX, 1+.@avg/7);
setunitdata(.@mob, UDT_LUK, 1+.@avg/6);
setunitdata(.@mob, UDT_ADELAY, 2072);
setunitdata(.@mob, UDT_ATKRANGE, 1);
// Battle Status
setunitdata(.@mob, UDT_MAXHP, .@avg*20);
setunitdata(.@mob, UDT_HP, .@avg*20);
setunitdata(.@mob, UDT_ATKMIN, .@avg*3);
setunitdata(.@mob, UDT_ATKMAX, .@avg*5);
setunitdata(.@mob, UDT_DEF, 1+.@avg*6/10);
setunitdata(.@mob, UDT_MDEF, 1+.@avg*3/10);
setunitdata(.@mob, UDT_HIT, .@avg*35/10); // Advised: x3
setunitdata(.@mob, UDT_FLEE, .@avg*25/10); // Advised: x4
// Critical calculation
.@min=1;
.@max=max(.@min, min(15, .@avg/6));
setunitdata(.@mob, UDT_CRIT, rand2(.@min, .@max));
// Loop through
}
freeloop(false);
return;
}
OnInit:
.distance=4;
.sex=G_MALE;
npcsit;
end;
OnInstanceInit:
.distance=4;
.sex=G_MALE;
npcsit;
end;
}
042-0,69,24,0 script #K042-0_69_24 NPC_HIDDEN,0,0,{
end;
OnTouch:
.@g=getcharid(2);
if ($KAMELOT_QUEST[.@g] & 1) {
warp "042-1@"+.@g, 55, 99;
} else {
dispbottom l("The door is locked.");
end;
}
// Maybe event must be fired
if (!($KAMELOT_KEYMASK[.@g] & 16)) {
.@label$=instance_npcname("#KDoor0421", $@KAMELOT_ID[.@g])+"::OnArrival";
deltimer .@label$;
addtimer 15000, .@label$;
}
end;
}
042-0,86,27,0 script Guinevere NPC_GUINEVERE,{
function guinevereSpawn;
.@g=getcharid(2);
.@pos=getguildrole(.@g, getcharid(3));
if (.@pos > GPOS_VICELEADER) goto L_Refusal;
if ($KAMELOT_QUEST[.@g] & 1) goto L_Hint;
npctalk3 l("Oh, hello %s.", strcharinfo(0));
end;
L_Refusal:
mesn;
mesq l("Hello, %s.", strcharinfo(0));
next;
mesc "["+strcharinfo(0)+"]";
mesc l("She doesn't seems to trust me... Maybe I should bring a guild vice-leader, or even better, the guild master himself.");
close;
L_Hint:
mesc l("Guinevere is the King's Wife. If you talk to her, the King will be upset and will send soldiers to you."), 1;
next;
mesc l("However, she may have a better assessment of the current situation better than you and your allies."), 1;
next;
mesc l("Continue anyway? You'll die if your allies cannot protect you!"), 1;
next;
if (askyesno() == ASK_NO)
close;
// Okay... So here we go (again), spawning monsters
guinevereSpawn(1);
mesn;
mesq l("Ah, %s, a good thing you're here. You must help!", strcharinfo(0));
next;
guinevereSpawn(1);
mesn;
mesq l("Something very terrible happened.");
next;
guinevereSpawn(2);
mesn;
mesq l("They're back - and they took hold of your majesty - my husband - king Arthur!");
next;
guinevereSpawn(2);
mesn;
mesq l("Of course, he doesn't likes the fact you're talking to me.");
next;
guinevereSpawn(3);
mesn;
mesq l("*They* couldn't take hold of me, but I'm bound to this castle; I can't leave.");
next;
guinevereSpawn(3);
mesn;
mesq l("They are in the basement, pulling the strings from behind.");
next;
guinevereSpawn(3);
mesn;
mesq l("The way is full of dangers. Not only king soldiers, but the beast has an army of their own!");
next;
guinevereSpawn(4);
mesn;
mesq l("You need to be very careful. Use the sewers to reach... them.");
next;
guinevereSpawn(4);
mesn;
mesq l("Also, listen well, because there are traps and dangers on the whole way. Their leader sealed themselves in safety.");
next;
guinevereSpawn(5);
mesn;
mesq l("I'm afraid you'll need a key to reach them. But there's a fork on the way.");
next;
guinevereSpawn(3);
mesn;
switch ($KAMELOT_KEY[.@g]) {
case 1:
.@path$=l("West"); break;
case 2:
.@path$=l("North West"); break;
case 4:
.@path$=l("North East"); break;
case 8:
.@path$=l("East"); break;
default:
.@path$=l("ERROR, REPORT ME: Invalid: %d", $KAMELOT_KEY[.@g]); break;
}
mesq l("The key is on the sewer %s path. Be careful. May the light be with you.", b(.@path$));
if ($KAMELOT_QUEST[.@g] & 2)
close;
next;
guinevereSpawn(5);
mesn;
mesq l("And one more thing...");
next;
guinevereSpawn(2);
mesn;
mesq l("Take this with you. And please bring Arthur back, the world needs him!");
$KAMELOT_QUEST[.@g]=$KAMELOT_QUEST[.@g]|2;
// Player Reward for completing this stage
getitem SacredImmortalityPotion, 1;
getitem GuildCoin, 5;
// Guild Reward for completing this stage
.@ggp=100+$KAMELOT_MX[.@g]*4;
.@gxp=$KAMELOT_MX[.@g]*2;
$GUILD_BANK[.@g]+=.@ggp;
guildgetexp(.@gxp); // 2xp per player average level (max 200/300)
// Guild Master Notification
.@gm$=getguildmaster(.@g);
if (!getcharid(3, .@gm$)) end;
.@gma=getcharid(3, .@gm$);
.@gmb=getcharid(0, .@gm$);
if (!isloggedin(.@gma, .@gmb)) end;
message .@gm$, strcharinfo(0)+" cleared Guinevere: Guild GP +"+.@ggp+" Guild XP +"+.@gxp;
close;
OnKillMob:
if (!playerattached()) end;
.@g=getcharid(2);
if (.@g < 1) percentheal -100, -100;
getexp $KAMELOT_MX[.@g]*2, $KAMELOT_MX[.@g];
end;
function guinevereSpawn {
.@label$=instance_npcname(.name$)+"::OnKillMob";
.@gcount=getarg(0);
.@g=getcharid(2);
if (.@g < 1) percentheal -100, -100;
.@avg=$KAMELOT_MX[.@g];
.@m$=getmap();
for (.@i=0; .@i < .@gcount; .@i++) {
.@mobId=CursedSoldier;
.@mob=areamonster(.@m$, 82, 26, 90, 34, strmobinfo(1, .@mobId), .@mobId, 1, .@label$);
// Reconfigure the monster
setunitdata(.@mob, UDT_LEVEL, .@avg);
setunitdata(.@mob, UDT_STR, 1+.@avg/6);
setunitdata(.@mob, UDT_AGI, 1+.@avg/7);
setunitdata(.@mob, UDT_VIT, 1+.@avg/6);
setunitdata(.@mob, UDT_INT, 1+.@avg/6);
setunitdata(.@mob, UDT_DEX, 1+.@avg/7);
setunitdata(.@mob, UDT_LUK, 1+.@avg/6);
setunitdata(.@mob, UDT_ADELAY, 2072);
setunitdata(.@mob, UDT_ATKRANGE, 1);
// Battle Status
setunitdata(.@mob, UDT_MAXHP, .@avg*20);
setunitdata(.@mob, UDT_HP, .@avg*20);
setunitdata(.@mob, UDT_ATKMIN, .@avg*3);
setunitdata(.@mob, UDT_ATKMAX, .@avg*5);
setunitdata(.@mob, UDT_DEF, 1+.@avg*6/10);
setunitdata(.@mob, UDT_MDEF, 1+.@avg*3/10);
setunitdata(.@mob, UDT_HIT, .@avg*3); // Advised: x3
setunitdata(.@mob, UDT_FLEE, .@avg*25/10); // Advised: x4
// Critical calculation
.@min=1;
.@max=max(.@min, min(15, .@avg/6));
setunitdata(.@mob, UDT_CRIT, rand2(.@min, .@max));
// Loop through
}
freeloop(false);
return;
}
OnInit:
OnInstanceInit:
.distance=4;
.sex=G_FEMALE;
end;
}