// TMW2 scripts.
// Authors:
// Jesusalva
// Description:
// Protect Hurnscald
012-1,71,24,0 script Lieutenant Paul NPC_PLAYER,{
.@q=getq(HurnscaldQuest_Lieutenant);
.@k=getq2(HurnscaldQuest_Lieutenant);
// The Monster King guild have a special menu
if (!$HURNS_LIBDATE && is_admin()) goto L_Admus;
if (strcharinfo(2) == "Monster King") goto L_MKControl;
mesn;
mesq l("We are @@ since the last great attack from the Monster King.", FuzzyTime($HURNS_LIBDATE,1,2));
next;
mesn;
mesq l("Many citzens are still in fear. Paths are closed, economy is a disaster, things are not here.");
next;
mesn;
mesq l("But we are working day and night. We hope that soon, more people come out and this place gets lively again.");
if (BaseLevel >= 20 && MPQUEST && .@q < 10) goto L_Quest;
close;
// Paul's quest
L_Quest:
next;
// Quest State, Legacy value
@fc=0;
if (.@q == 0 && BaseLevel >= 20) @fc=1;
if (.@q == 1 && BaseLevel >= 22) @fc=2;
if (.@q == 2 && BaseLevel >= 24) @fc=3;
if (.@q == 3 && BaseLevel >= 26) @fc=4;
if (.@q == 4 && BaseLevel >= 28) @fc=5;
if (.@q == 5 && BaseLevel >= 30) @fc=6;
if (.@q == 6 && BaseLevel >= 32) @fc=7;
if (.@q == 7 && BaseLevel >= 34) @fc=8;
if (.@q == 8 && BaseLevel >= 36) @fc=9;
if (.@q == 9 && BaseLevel >= 38) @fc=10;
if (.@q == 10 && BaseLevel >= 40) @fc=11;
if (@fc)
goto L_Assign;
mesn;
mesq l("I see you are a Monster Hunting Quest Participant, right? I don't need your help right now, but maybe later, who knows?");
close;
L_Assign:
// 2 ** 0 = 1 * 100 = 100 mob points
// 2 ** 1 = 2 * 99 = 198 mob points
// 2 ** 2 = 4 * 98 = 392 mob points
// ...
@rq=(2**(@fc-1))*(101-@fc);
// Check if you already met objective
if (.@k > 0 && Mobpt >= .@k+@rq) {
setq HurnscaldQuest_Lieutenant, @fc, 0;
Mobpt-=@rq;
mesn;
mesq l("Good job collecting the monster points for me. Here's your reward.");
@xp=1000;
// reward is 30% from reference level exp to level up
switch (@fc) {
case 1: @xp=486; break;
case 2: @xp=597; break;
case 3: @xp=751; break;
case 4: @xp=1028; break;
case 5: @xp=1342; break;
case 6: @xp=2399; break;
case 7: @xp=3128; break;
case 8: @xp=4190; break;
case 9: @xp=5303; break;
case 10: @xp=6532; break;
case 11: @xp=10234; break;
}
getexp @xp, @fc*3;
Zeny=Zeny+@fc*15+@fc;
mesc l("* Gained @@ EXP and @@ Job Exp", @xp, @fc*3);
mesc l("* Gained @@ GP", @fc*15+@fc);
close;
}
// Assign quest
else if (.@k == 0) {
mesn;
mesq l("Maybe you can help our city guard. I see you are a Monster Hunting Quest Participant, right?");
next;
mesn;
mesq l("So, I'm placing a special bounty for @@ Mob Points.", @rq);
mesq l("You currently have @@, so if you accept and come back later with @@ Mob Points, I'll mark the bounty as complete.", Mobpt, Mobpt+@rq);
next;
mesc l("Accept quest?");
if (askyesno() == ASK_YES) {
setq HurnscaldQuest_Lieutenant, @fc-1, Mobpt;
}
}
// Resume quest
else {
// Reset if needed
if (Mobpt-.@k < 0) {
setq2 HurnscaldQuest_Lieutenant, Mobpt;
.@k=0;
}
mesn;
mesq l("You have collected and additional of @@/@@ Mob Points.", Mobpt-.@k, @rq);
}
close;
// Liberation Day facility
L_Admus:
mesc l("Protip: Use @hide to don't interfer.");
mes l("Determine Team Size (If everyone is ready and stdby at Tulimshar, use: @@. Minimum 2 players.)", getusers(1)-1);
input $@BG1_SIZE;
if ($@BG1_SIZE < 2) close;
$@BG1_SIZE=$@BG1_SIZE+1;
kickwaitingroomall("Hurnsguard");
setmapflagnosave("012-1", "000-1", 22, 22);
//setmapflag("012-1", mf_nocommand); // This is just too powerful!
setmapflag("012-1", mf_battleground);
setmapflag("012-1", mf_nopenalty);
setmapflag("012-1",mf_bexp,126);
enablenpc "Hurnsguard";
donpcevent "Hurnsguard::OnSet";
donpcevent "Lieutenant Paul::OnSet";
addmapmask "012-1", MASK_MATTACK;
addmapmask "012-1", MASK_EVILSANCTUM;
pvpon("012-1");
disablenpc "#012-1_22_62";
disablenpc "#012-1_79_17";
disablenpc "#012-1_79_102";
disablenpc "#012-1_132_101";
disablenpc "#012-1_65_55";
disablenpc "#012-1_89_58";
disablenpc "#012-1_101_55";
disablenpc "#012-1_121_71";
disablenpc "#012-1_116_66";
disablenpc "#012-1_110_56";
disablenpc "#012-1_102_69";
disablenpc "Andrei Sakar";
disablenpc "Dyrin The Traveler";
disablenpc "Gwendolyn";
disablenpc "Jack";
disablenpc "Locamit";
disablenpc "Richard";
disablenpc "Soul Menhir#hurns";
disablenpc "HurnsShip";
disablenpc "Hinnak";
disablenpc "Tezzerin";
disablenpc "Luffyx";
disablenpc "Shoppa Kep";
announce "##1Hear ya, hear ya! There are "+str($@BG1_SIZE-1)+" vacant slots at Hurnsguard to LIBERATE HURNSCALD!", bc_all | bc_npc;
mesc "You are assigned to Monster Forces. Do not leave Hurnscald.", 1;
close;
// Monster King Siege (deprecated)
L_MKControl:
mesn;
mes l("Oh noes! You've found the Hurnscald control panel!");
close;
// Hurnscald Liberation Day Core Logic
OnSet:
.CYCLES=0;
waitingroom("Monster Army", 2, "start#hurns_lib::OnReadyCheck", 1);
end;
OnEnterBG:
debugmes "Paul::OnEnterBG";
$@FK_Team2 = waitingroom2bg("012-1",141, 65,"start#hurns_lib::OnPlayer2Quit","start#hurns_lib::OnPlayer2Death");
setbgteam $@FK_Team2, 2;
end;
OnInit:
.sex = G_MALE;
.distance = 4;
.@npcId = getnpcid(.name$);
setunitdata(.@npcId, UDT_HEADTOP, Bull);
setunitdata(.@npcId, UDT_HEADMIDDLE, LieutenantArmor);
setunitdata(.@npcId, UDT_HEADBOTTOM, RaidTrousers);
setunitdata(.@npcId, UDT_SHIELD, LousyMoccasins); // TODO FIXME: Display Boots
setunitdata(.@npcId, UDT_WEAPON, Backsword);
setunitdata(.@npcId, UDT_HAIRSTYLE, 12);
setunitdata(.@npcId, UDT_HAIRCOLOR, 15);
end;
}
// Liberation Day Script
003-1,122,25,0 script Hurnsguard NPC_PLAYER,{
query_sql("SELECT online FROM `char` WHERE name='Saulc GM'", .@online);
if (!.@online) {
mesn;
mesq l("We are planning to take over Hurnscald from the Monster King, and we will need everybody's help.");
next;
mesn;
mesq l("As soon that Saulc GM get back, we can start.");
close;
}
mesc l("Hurnscald Liberation Day special event"), 3;
mes "";
mesc l("The objective of this event is to ##Bslay the Monster Admiral##b.");
mesc l("If you die, you ##Bwon't##b be able to rejoin, but you won't suffer the penalty.");
next;
mesc l("If all players there die, Hurnscald WON'T BE LIBERATED.");
mesc l("This basically means that it'll be another day without it.");
mesc l("Also, the more players survive, the better rewards will be given.");
next;
mesc l("Right click on this NPC to join the Hurnscald Alliance."), 3;
mesc l("The number of players must be precise, meaning if someone doesn't joins,");
mesc l("the event won't start and HURNSCALD WON'T BE LIBERATED.");
next;
mesc l("Once you join the Alliance, you won't be able to talk with people outside it.");
mesc l("Additionaly, all your movement will be restricted until either you're warped or log out.");
close;
OnSet:
waitingroom("Hurnscald Alliance", $@BG1_SIZE, "start#hurns_lib::OnReadyCheck", $@BG1_SIZE-1);
end;
OnInit:
.CYCLES=0;
.@npcId = getnpcid(.name$);
setunitdata(.@npcId, UDT_HEADTOP, GoldenWarlordPlate); // Light armor
setunitdata(.@npcId, UDT_HEADMIDDLE, JeansChaps); // Pants
setunitdata(.@npcId, UDT_HEADBOTTOM, DeepBlackBoots); // Shoes
setunitdata(.@npcId, UDT_WEAPON, BugSlayer);
setunitdata(.@npcId, UDT_HAIRSTYLE, 13);
setunitdata(.@npcId, UDT_HAIRCOLOR, 7);
disablenpc(.name$);
end;
OnEnterBG:
debugmes "Alliance::OnEnterBG";
$@FK_Team1 = waitingroom2bg("012-1",141, 65,"start#hurns_lib::OnPlayerQuit","start#hurns_lib::OnPlayerDeath");
setbgteam $@FK_Team1, 1;
end;
OnDoEvent:
debugmes "OnDoEvent";
mapannounce("012-1", "Find and slay the Monster Admiral! DO NOT ATTACK GUARDS. Don't let everyone die!", bc_map);
.@Pl=getmapusers("012-1");
.CYCLES=0;
// Guards won't attack the Monster Staff
areamonster("012-1", 52, 45, 127, 80, "Monster Sergeant", Forain, .@Pl/3+1, "Hurnsguard::OnXtreem");
areamonster("012-1", 52, 45, 127, 80, "Monster Sergeant", Moonshroom, .@Pl/2+1, "Hurnsguard::OnXtreem");
areamonster("012-1", 52, 45, 127, 80, "Monster Soldier", AngryScorpion, .@Pl, "Hurnsguard::OnSkip");
for (.@i = 0; .@i < .@Pl; .@i++)
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Friendly Guard", FallenGuard1, "Cassia::OnSkip");
initnpctimer();
end;
OnSkip:
// Here, coins drop rate are based on REMAINING PLAYERS and DEFEATED MONSTER LEVEL.
// A level 100 monster can have a 5% drop bonus against a level 0 monster.
// You have 1.2% of base chance, plus 0.5% each player + 0.05% each monster level.
if (rand(10000) <= 120 + (getmapusers("012-1")*50) + (strmobinfo(3,killedrid)*5))
getmapxy(.@m$, .@x, .@y, 0);
makeitem(any(Plushroom, Chagashroom, Bread, HalfCroconut, Aquada, CasinoCoins, CactusCocktail, AppleCocktail, CherryCocktail), any(1,1,2), "012-1", .@x, .@y);
end;
OnTimer300000:
.@Pl=getmapusers("012-1")+mobcount("012-1", "Cassia:OnSkip")-1;
.@Pla=getmapusers("012-1");
.@Mb=mobcount("012-1", "Hurnsguard:OnSkip")+mobcount("012-1", "Hurnsguard::OnXtreem")+2; // Saulc GM is an enemy for server code
for (.@i = 0; .@i < .@Pla; .@i++)
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Friendly Guard", FallenGuard1, "Cassia::OnSkip");
// See if we need extra guards, depending on how outnumbered allied forces are.
if ((.@Mb / .@Pl) > 7) {
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
}
if ((.@Mb / .@Pl) > 6) {
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
}
if ((.@Mb / .@Pl) > 5) {
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
}
if ((.@Mb / .@Pl) > 4) {
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
}
if ((.@Mb / .@Pl) > 3) {
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
}
.@Pl=getmapusers("012-1")+mobcount("012-1", "Cassia:OnSkip")-1;
.@Pla=getmapusers("012-1")-1;
mapannounce("012-1", "Survivors: "+.@Pla+" Hurnscald Alliance: "+.@Pl+" Monsters: "+.@Mb, bc_map);
initnpctimer;
end;
OnTimer10000:
OnTimer120000:
OnTimer240000:
.CYCLES=.CYCLES+1;
// Scripted monsters
if (.CYCLES == 2) {
mapannounce("012-1", "Monster Lieutenant appears! Watch out!", bc_map);
bg_monster($@FK_Team2, "012-1", 65, 71, "Monster Lieutenant", NightScorpion, "Hurnsguard::OnXtreem");
} else if (.CYCLES == 3) {
mapannounce("012-1", "Monster Admiral appears! Kill it to liberate Hurns!", bc_map);
bg_monster($@FK_Team2, "012-1", 65, 71, "Monster Admiral", GiantMutatedBat, "Hurnsguard::OnVictory");
}
// One monster per user alive
.@Pl=getmapusers("012-1");
for (.@i = 0; .@i < .@Pl; .@i++) {
.@mid=rand(1,17);
switch (.@mid) {
case 1:
.@monsterId = CaveMaggot ; break;
case 2:
.@monsterId = RedSlime ; break;
case 3:
.@monsterId = LavaSlime ; break;
case 4:
.@monsterId = BlackScorpion ; break;
case 5:
.@monsterId = AngryRedScorpion ; break;
case 6:
.@monsterId = Sarracenus ; break;
case 7:
.@monsterId = Snake ; break;
case 8:
.@monsterId = MountainSnake ; break;
case 9:
.@monsterId = GreenSlime ; break;
case 10:
.@monsterId = Bandit ; break;
case 11:
.@monsterId = BlackScorpion ; break;
case 12:
.@monsterId = rand(HouseMaggot, AngryScorpion) ; break; // Lucky bonus, probably a Bif
case 13:
.@monsterId = Pinkie ; break;
case 14:
.@monsterId = MagicGoblin ; break;
case 15:
.@monsterId = Mouboo ; break;
case 16:
.@monsterId = Scorpion ; break;
default: // case 13:
.@monsterId = Yeti ; break;
}
bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", .@monsterId, "Hurnsguard::OnSkip");
// 40% odds of having an extra monster spawned (player loop)
if (rand(1,5) % 2 == 0)
bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", .@monsterId, "Hurnsguard::OnSkip");
}
// One slime blast per general
.@Mgg=mobcount("012-1", "Hurnsguard::OnXtreem");
for (.@i = 0; .@i < .@Mgg; .@i++) {
bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", SlimeBlast, "Cassia::OnSkip");
}
// One Magic Goblin or Pinkie per cycle
for (.@i = 0; .@i < .CYCLES; .@i++) {
if (rand(1,2) == 1)
bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", Pinkie, "Hurnsguard::OnSkip");
else
bg_monster($@FK_Team2, "012-1", rand(69, 136), rand(83, 74), "Monster Soldier", MagicGoblin, "Hurnsguard::OnSkip");
}
// Spawn Angry Scorpions on the whole map. These monsters are neutral!
areamonster("012-1", 33, 16, 137, 100, "Monster Soldier", AngryScorpion, .CYCLES, "Hurnsguard::OnSkip");
// One extra guard on every summon
bg_monster($@FK_Team1, "012-1", rand(131, 136), rand(64, 80), "Additional Guard", FallenGuard2, "Cassia::OnSkip");
end;
OnXtreem:
if (rand(0,100) <= 50)
Karma=Karma+1;
else
getitem StrangeCoin, 2;
// Here, the drop is a Bronze Gift, based on living players and players nearby.
// You have 0.1% of base chance, plus 0.2% each fighting player + 1% each near player.
getmapxy(.@m$, .@x, .@y, 0);
if (rand(10000) <= 10 + (getmapusers("012-1")*20) + (getareausers("012-1", .@x-8, .@x+8, .@y-8, .@y+8)*100))
makeitem(BronzeGift, 1, "012-1", .@x, .@y);
end;
OnVictory:
$HURNS_LIBDATE=gettimetick(2);
removemapflag("012-1", mf_nosave);
disablenpc "Hurnsguard";
pvpoff("012-1");
removemapmask "012-1", MASK_MATTACK;
removemapmask "012-1", MASK_EVILSANCTUM;
//removemapflag("012-1", mf_nocommand);
removemapflag("012-1", mf_battleground);
removemapflag("012-1", mf_bexp);
enablenpc "#012-1_22_62";
enablenpc "#012-1_79_17";
enablenpc "#012-1_79_102";
enablenpc "#012-1_132_101";
enablenpc "#012-1_65_55";
enablenpc "#012-1_89_58";
enablenpc "#012-1_101_55";
enablenpc "#012-1_121_71";
enablenpc "#012-1_116_66";
enablenpc "#012-1_110_56";
enablenpc "#012-1_102_69";
enablenpc "Andrei Sakar";
enablenpc "Dyrin The Traveler";
enablenpc "Gwendolyn";
enablenpc "Jack";
enablenpc "Locamit";
enablenpc "Richard";
enablenpc "Soul Menhir#hurns";
enablenpc "HurnsShip";
enablenpc "Hinnak";
enablenpc "Tezzerin";
enablenpc "Luffyx";
enablenpc "Shoppa Kep";
announce "##2Hurnscald was recovered!", bc_all | bc_npc;
killmonster("012-1", "All");
changemusic "012-1", "tws_birds_in_the_sunrise.ogg"; // Play a more peaceful tune.
stopnpctimer;
maptimer("012-1", 10, "Hurnsguard::OnReward");
// Here, coins drop rate are based on REMAINING PLAYERS and DEFEATED MONSTER LEVEL.
// You have $coinsrate of base chance, plus 2% for each living player.
// $coinsrate is set on Aeros Event Master, and defaults to 6%
if (rand(10000) <= $coinsrate + (getmapusers("012-1")*200))
getmapxy(.@m$, .@x, .@y, 0);
makeitem(StrangeCoin, 1, "012-1", .@x, .@y);
Karma=Karma+1;
$MOST_HEROIC$=strcharinfo(0);
bg_destroy(1);
bg_destroy(2);
end;
OnReward:
bg_leave();
// Let's say we have 5 players for reference. Subtract a Game Master, he doesn't counts.
.@Pl=getmapusers("012-1")-1;
getexp .@Pl*600, .@Pl*30; // 3,000 exp, 150 jxp
Zeny=Zeny+.@Pl*300; // 1,500 gp
end;
}
//== Battleground Engine ======================
012-1,0,0,0 script start#hurns_lib NPC_HIDDEN,{
OnInit:
end;
OnEnable:
end;
OnPlayerQuit:
OnPlayerDeath:
OnPlayer2Quit:
OnPlayer2Death:
bg_leave();
// Check if we are done for.
warp "000-1", 22, 22;
.@Pl=getmapusers("012-1");
if (.@Pl <= 1) {
announce "##1Hurnscald is lost!", bc_all | bc_npc;
disablenpc "Hurnsguard";
pvpoff("012-1");
removemapmask "012-1", 10;
removemapflag("012-1", mf_nocommand);
removemapflag("012-1", mf_battleground);
killmonster("012-1", "All");
bg_destroy(1);
bg_destroy(2);
}
end;
OnReadyCheck:
.@Alliance = getwaitingroomstate(0,"Hurnsguard");
debugmes "Check:" +str(.@Alliance)+"<"+ str($@BG1_SIZE-1);
if ( .@Alliance < $@BG1_SIZE-1 )
end;
donpcevent "Hurnsguard::OnEnterBG";
donpcevent "Lieutenant Paul::OnEnterBG";
debugmes "Prepare Warp";
bg_warp $@FK_Team1,"012-1",141, 65;
bg_warp $@FK_Team2,"012-1",69, 71;
changemusic "012-1", "misuse.ogg";
donpcevent "Hurnsguard::OnDoEvent";
//initnpctimer;
end;
}
// Handle Guard's logic
function script CheckpointGuard {
mesn;
mesq l("I am stationed here to protect Hurnscald from monsters.");
next;
mesn;
mesq l("If the Monster King attack, I will try to control inbound monsters here.");
close;
return;
}
012-1,81,18,0 script Checkpoint Guard#1 NPC_GUARD2,{
CheckpointGuard();
end;
OnInit:
.sex = G_FEMALE;
.distance = 5;
end;
}
012-1,26,60,0 script Checkpoint Guard#2 NPC_GUARD1,{
CheckpointGuard();
end;
OnInit:
.sex = G_MALE;
.distance = 5;
end;
}
012-1,80,98,0 script Checkpoint Guard#3 NPC_GUARD2,{
CheckpointGuard();
end;
OnInit:
.sex = G_FEMALE;
.distance = 5;
end;
}
012-1,134,98,0 script Checkpoint Guard#4 NPC_GUARD1,{
CheckpointGuard();
end;
OnInit:
.sex = G_MALE;
.distance = 5;
end;
}
012-1,94,56,0 script Guard#012-1.1 NPC_GUARD1,{
legiontalk;
end;
OnInit:
.sex = G_MALE;
.distance = 5;
end;
}
012-1,112,65,0 script Guard#012-1.2 NPC_GUARD2,{
legiontalk;
end;
OnInit:
.sex = G_FEMALE;
.distance = 5;
end;
}