diff options
author | Jesusaves <cpntb1@ymail.com> | 2020-07-22 22:44:30 +0000 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2020-07-22 22:44:30 +0000 |
commit | 3bd2e1e10b046414a01836bcee2694fa68724e32 (patch) | |
tree | 8d6904848420a5d0ae6b6d1966e3bb99178adbd0 | |
parent | 1932765753bf35d38681d1cdd8d9837cbab8e7c8 (diff) | |
parent | fd13b7893ebb7affaacfcdc1bfa016de516f8d2d (diff) | |
download | serverdata-3bd2e1e10b046414a01836bcee2694fa68724e32.tar.gz serverdata-3bd2e1e10b046414a01836bcee2694fa68724e32.tar.bz2 serverdata-3bd2e1e10b046414a01836bcee2694fa68724e32.tar.xz serverdata-3bd2e1e10b046414a01836bcee2694fa68724e32.zip |
Merge branch 'ElderQuestStage2' into 'master'
Add second and third stages for Elder Quest.
See merge request TMW2/serverdata!40
-rw-r--r-- | db/re/mob_db.conf | 49 | ||||
-rw-r--r-- | npc/018-5-4/elder.txt | 192 | ||||
-rw-r--r-- | npc/functions/hub.txt | 17 |
3 files changed, 250 insertions, 8 deletions
diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index a271903ff..cc64601ac 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -9995,6 +9995,55 @@ mob_db: ( Bows: 2000 } }, +{ + Id: 1248 + SpriteName: "EliteDuck" + Name: "Elite Duck" + Lv: 75 + Hp: 10000 + Sp: 0 + Exp: 1800 + JExp: 60 + AttackRange: 2 + Attack: [170, 195] + Def: 50 + Mdef: 180 + WalkMask: "WALK_WATER" + Stats: { + Str: 200 + Agi: 250 + Vit: 10 + Int: 42 + Dex: 48 + Luk: 200 + } + ViewRange: 5 + ChaseRange: 12 + Race: 2 + Element: (3, 1) + Mode: { + CanMove: true + Looter: true + Aggressive: true + CanAttack: true + CastSensorChase: true + ChangeChase: true + } + MoveSpeed: 225 + AttackDelay: 500 + AttackMotion: 472 + DamageMotion: 200 + Drops: { + CherryCake: 1005 + BugLeg: 400 + Moss: 375 + DuckFeather: 100 + CommonCarp: 52 + GrassCarp: 11 + Lightsaber: 1 + PowerfulLightsaber: 1 + } +}, // WARNING: ID 1250~1400 PERMANENTLY RESERVED - USE PROHIBTED // Reserved diff --git a/npc/018-5-4/elder.txt b/npc/018-5-4/elder.txt index 7d148b913..6ed4b4db4 100644 --- a/npc/018-5-4/elder.txt +++ b/npc/018-5-4/elder.txt @@ -4,8 +4,8 @@ // Description: // Duck Elder is a friendly npc. // The first stage of the Elder's quest consists of a supply restock -// Second stage of the quest will be a pirate attack (WIP) -// Third stage will consist of planting mage acorns around the island (WIP) +// Second/third stage of the quest consists of a pirate attack +// Fourth (last) stage will be the Duck Dungeon, an HH-like training ground for initiates of the Duck Side (WIP) // Variables: // LilitQuest_PiratesOfSARAH @@ -14,14 +14,22 @@ function elderSupplyList; function elderSupplyGive; function elderPirateAttack; + function elderPirateVictory; + function elderPirateDefeat; + function elderPirateReward; function elderAbout; function elderAboutSarah; function elderClose; + .@q=getq(LilitQuest_PiratesOfSARAH); mesn; mesq l("Hello %s. What brings you here?", get_race()); next; select - l("I've heard tidings of strange goings-on in this area..."), + rif (.@q == 0, l("I've heard tidings of strange goings-on in this area...")), + rif (.@q == 1, l("I'm here to help you restock...")), + rif (.@q == 2, l("What did the Council of Elders say? Is there any news of the pirates?")), + rif (.@q == 3, l("Have the pirates been routed? Will they return?")), + rif (.@q == 4, l("I'm here as an Initiate. May I enter Duck Dungeon?")), l("Oh, I'm just exploring. What can you tell me about this island?"), l("I came to enjoy a beautiful day with some ducks!"); mes ""; @@ -39,7 +47,7 @@ close; function elderQuest { - if(BaseLevel < 50) { + if (BaseLevel < 50) { mesn; mesq l("Unfortunately, a mere fledgling like you is not strong enough to help us."); next; @@ -83,6 +91,12 @@ function elderQuest { elderPirateAttack(); break; case 3: + elderPirateReward(); + break; + case 4: + mesn; + mesq l("We are deliberating. Some do not... approve of your initiation. Leave."); + mesc "* "+l("Kolchak and dangerDuck are working to finish Duck Dungeon. Contact them for updates..."); break; } close; @@ -99,6 +113,7 @@ function elderSupplyList { mesq l("%d/%d %s", countitem(CrystallizedMaggot), 1, getitemlink(CrystallizedMaggot)); next; mesq l("Of course, we'll find a way to reward you for your efforts."); + close; return; } @@ -133,20 +148,182 @@ function elderSupplyGive { mesn; mesq l("If you're ever in need, you may use it to call upon the aid of the ducks."); next; - if(BaseLevel < 75) { + if (BaseLevel < 75) { mesn; mesq l("Go now, with the blessing of ducks. There may come a time when we require your aid once again, O %s.", get_race()); } else { mesn; - mesq l("We may require your aid again soon. The tritan pirates are amassing and we fear they are planning a siege of Duck Island. I must speak with the council..."); + mesq l("We may require your aid again soon. The tritan pirates are amassing and we fear they are planning a siege of Duck Island. I must speak with the Council of Elders..."); } close; } function elderPirateAttack { + // Level requeriment + if (BaseLevel < 75) { + mesn; + mesq l("The pirates amass for their siege, but they will not attack yet. Return when you are stronger. King DD is working to find a solution."); + return; + } + if (!is_staff()) { + mesn; + mesc l("I'm afraid King DD did not finish his testing on this!"), 1; + return; + } + mesn; + mesq l("The pirates have been surrounding our island for many sun rises. We expect they will attack any time."); + next; + mesn; + mesq l("The Council of Elders has enlisted ducks of our island into a militia. In addition, the masters of the Duck Side have seen fit to spare %d Duck initiates to assist us.", (BaseLevel/20)); + next; + mesn; + mesq l("Please be careful when fighting. A mighty warrior such as yourself can harm their allies with any AoE effects they may use."); + next; + mesc l("Accept quest?"), 1; + if (askyesno() == ASK_NO) + return; + + // Build instance if it doesn't exists or has been reallocated + if (instanceowner(@duckinst) != getcharid(3)) { + .@mapn$="duck@"+getcharid(0); + @duckinst = instance_create("duck@a"+getcharid(0), getcharid(3), IOT_CHAR); + instance_attachmap("018-5-4", @duckinst, false, .@mapn$); + // Instance lasts 6 minutes + instance_set_timeout(360, 360, @duckinst); + instance_init(@duckinst); + } else { + // Restart instance timer if it already exists + instance_set_timeout(360, 360, @duckinst); + } + getmapxy(.@m$, .@x, .@y, 0); + warp .@mapn$, .@x, .@y; + addtimer(300, instance_npcname(.name$, @duckinst)+"::OnBegin"); + closeclientdialog; + close; + return; +} + +OnBegin: + killmonsterall(getmap()); + + .pLvl = BaseLevel; + .pirate_killed = 0; + .duck_killed = 0; + .total_pirates = 0; + .total_ducks = 0; + setnpcdisplay .name$, NPC_NO_SPRITE; + sleep2(1000); + mapannounce(getmap(), "Duck Elder : Here they come...", bc_map); + sleep2(1000); + mapannounce(getmap(), "Duck Elder : DUCKS TO ARMS! KILL ALL, SHOW NO MERCY!", bc_map); + sleep2(1000); + mapannounce(getmap(), "##2Victory: Kill all pirates within 5 minutes. Protect the duck fighters.", bc_map); + mapannounce(getmap(), "##1Defeat: All ducks are slain.", bc_map); + + // Spawn Monsters + // FIXME MIGHT NOT WORK WITH COORDINATES ZERO (for several reasons) + // PLEASE PREFER AREAMONSTER + monster("018-5-4", 0, 0, "Ocean Pirate", OceanPirate, (.pLvl*4), "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl*4); + monster("018-5-4", 0, 0, "Pirate Captain", OceanPirate, (.pLvl/10), "Duck Elder::OnPirateKilled"); // FIXME + .total_pirates+=(.pLvl/10); + monster("018-5-4", 0, 0, "Desert Pirate", DesertBandit, .pLvl, "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl); + monster("018-5-4", 0, 0, "Marsh Pirate", Bandit, .pLvl, "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl); + monster("018-5-4", 0, 0, "Buccaneer", Sarracenus, (.pLvl/5), "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl/5); + monster("018-5-4", 0, 0, "Corsair", RobinBandit, (.pLvl/5), "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl/5); + monster("018-5-4", 0, 0, "Pirate Lord", BanditLord, (.pLvl/10), "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl/10); + monster("018-5-4", 0, 0, "Pirate Assassin", HoodedAssassin, (.pLvl/25), "Duck Elder::OnPirateKilled"); + .total_pirates+=(.pLvl/25); + + // Reinforcements + for(.@i = 0; .@i < min(10, .pLvl/5); ++.@i) { + summon("Duck Soldier", Duck, 300000, "Duck Elder::OnDuckKilled"); + .total_duck++; + } + for(.@i = 0; .@i < min(5, .pLvl/20); ++.@i) { + summon("Duck Initiate", EliteDuck, 300000, "Duck Elder::OnDuckKilled"); + .total_duck++; + } + + // Begin timer + initnpctimer(); + end; + +OnPirateKilled: + .pirate_killed++; + if (.pirate_killed >= .total_pirates) { + elderPirateVictory(); + } + end; + +OnDuckKilled: + .duck_killed++; + if (.duck_killed >= .total_ducks) { + elderPirateDefeat(); + } + end; + +OnTimer300000: + elderPirateDefeat(); + end; + +// Do this even work O.o +OnTimerQuit: + elderPirateDefeat(); + end; + +function elderPirateVictory { + stopnpctimer(); + .pirate_killed = 0; + .duck_killed = -50; // Set to -50 to make sure defeat doesn't trigger when monsters are killed + announce("Duck Elder: Success! The pirates have been thwarted.", bc_self); + setnpcdisplay .name$, NPC_DUCK_ELDER; + setq(LilitQuest_PiratesOfSARAH, 3); + getmapxy(.@m$, .@x, .@y, 0); + killmonsterall(.@m$); + warp "018-5-4", .@x, .@y; + end; +} + +function elderPirateDefeat { + stopnpctimer(); + .pirate_killed = -50; // Set to -50 to make sure victory doesn't trigger when monsters are killed + .duck_killed = -50; + announce("Duck Elder: We have failed. The pirates will regroup and replenish their fallen. They will strike again, until we are defeated.", bc_self); + setnpcdisplay .name$, NPC_DUCK_ELDER; + getmapxy(.@m$, .@x, .@y, 0); + killmonsterall(.@m$); + warp "018-5-4", .@x, .@y; + end; +} + +function elderPirateReward { + mesn; + mesq l("We are no longer in danger, thanks to you. The pirates were thoroughly defeated. None survived the battle."); + next; + mesn; + mesq l("The masters of the Duck Side, The Council of Elders, and King DD himself, on behalf of all ducks, thank you for your help. We wouldn't have survived without it."); + getexp(458593, 59505); + setq(LilitQuest_PiratesOfSARAH, 4); + next; + mesn; + mesq l("The masters have decided you are to be given honorary initiation into the Duck Side. The Duck Side is powerful, much more so than you could possibly understand."); + next; mesn; - mesq l("The tritan pirates amass for their siege, but they will not attack yet. Return later. King DD is working to find a solution."); + mesq l("You must understand that this honor has never been granted to a non-duck before. You will have access to Duck Dungeon, a training grounds for Initiates."); + next; + mesn; + mesq l("As an honorary member of the Duck Side, know that we are more than we appear. The Moubootaur itself has seen fit to reward us when it awakens. Do not attempt to cross us."); + // NOTE: The Moubootaur is "evil"; Therefore, Duck Side is evil too + // (This is a de facto standard; A global truth any specie which knows + // the Moubootaur Legend is aware of) close; + return; } function elderAbout { @@ -162,6 +339,7 @@ function elderAbout { mes ""; if (@menu == 1) elderAboutSarah(); + close; return; } diff --git a/npc/functions/hub.txt b/npc/functions/hub.txt index 4a230dc43..b3a63d5e6 100644 --- a/npc/functions/hub.txt +++ b/npc/functions/hub.txt @@ -722,9 +722,24 @@ function script HUB_SkillInvoke { SK_summon(.@mobId, 4, any(4,5)); break; case TMW2_DUCKY: + .@mobId=Duck; + .@q=getq(LilitQuest_PiratesOfSARAH); if (!alignment_cansummon()) break; - SummonMagic(@skillId, Duck, 2, @skillLv); + if (abizit() > 4 && + .@q > 2 && + MAGIC_LVL >= 3) + { + // GHQ Complete: 33% chances + // Otherwise: 8% chances + if (GHMEMO[GHQ_GetQuestIDByMonsterID(Duck)] >= 10000) + .@mobId=any(Duck, Duck, EliteDuck); + else + .@mobId=any(Duck, Duck, Duck, Duck, + Duck, Duck, Duck, Duck, + Duck, Duck, Duck, EliteDuck); + } + SummonMagic(@skillId, .@mobId, 2); GetManaExp(@skillId, 1); break; |