From eb44e0f9eeaee41d1eaf19f5610b6e30be450733 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Tue, 3 May 2022 14:31:42 -0300 Subject: Draft for the showdown. Quest should be working now. --- db/re/mob_db.conf | 33 ++++++---- npc/034-4/exit.txt | 14 ++-- npc/034-4/lobby.txt | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 20 deletions(-) diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf index 468ee899c..68650b253 100644 --- a/db/re/mob_db.conf +++ b/db/re/mob_db.conf @@ -12306,6 +12306,7 @@ mob_db: ( CoinBag: 2000 TreasureMap: 1400 TreasureKey: 900 + BronzeBossGift: 400 GoldPieces: 200 Lockpicks: 100 Beer: 50 @@ -12362,27 +12363,27 @@ mob_db: ( Id: 1447 SpriteName: "Luvia" Name: "Luvia" - Lv: 50 - Hp: 21400 + Lv: 110 + Hp: 54000 Sp: 0 - Exp: 404 - JExp: 14 - AttackRange: 1 + Exp: 17000 + JExp: 100 + AttackRange: 8 Attack: [620, 670] - Def: 5 + Def: 45 Mdef: 127 Stats: { Str: 12 - Agi: 33 - Vit: 46 - Int: 90 - Dex: 41 - Luk: 27 + Agi: 63 + Vit: 88 + Int: 110 + Dex: 141 + Luk: 77 } ViewRange: 9 ChaseRange: 12 Race: 2 - Element: (6, 1) + Element: (7, 1) Mode: { CanMove: true CanAttack: true @@ -12391,13 +12392,17 @@ mob_db: ( ChangeTargetMelee: true ChangeChase: true CastSensorChase: true + Boss: true } - MoveSpeed: 370 + MoveSpeed: 320 AttackDelay: 2100 AttackMotion: 672 DamageMotion: 200 Drops: { - CherryCake: 60 + CoinBag: 4000 + BronzeBossGift: 1000 + SilverBossGift: 200 + GoldenBossGift: 25 } }, // System diff --git a/npc/034-4/exit.txt b/npc/034-4/exit.txt index 5efee06d1..1487f4898 100644 --- a/npc/034-4/exit.txt +++ b/npc/034-4/exit.txt @@ -7,23 +7,25 @@ 034-4,144,82,0 script #GeminiFExit NPC_HIDDEN,0,0,{ OnWumpus: - GeminiCheck(); - // TODO FIXME: Instead of 75% chance, a Wumpus Egg only on first victory? + GeminiCheck(15); + .@q = getq2(HurnscaldQuest_Gemini); // TODO: Maybe exchange an Wumpus Egg for a Sunny Crystal or Mylarin Dust? - // Or have a NPC do so, I guess. - if (any(true, true, true, false)) + // Have a NPC do so only once, for the Savior set. + if (.@q == 0 || .@q == 2 || (.@q > 5 && !(.@q % 3))) getitem WumpusEgg, 1; else getitem LightGreenDiamond, 1; getexp 0, rand2(7500, 9999); + setq2 HurnscaldQuest_Gemini, .@q + 1; @forced_sick$ = ""; end; OnTouch: - GeminiCheck(); + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(15); // Only the party leader go ahead if (strcharinfo(0) != getpartyleader(getcharid(1))) { - mes l("%s has the key.", getpartyleader(getcharid(1))); + mes l("Only %s has the key.", getpartyleader(getcharid(1))); close; } diff --git a/npc/034-4/lobby.txt b/npc/034-4/lobby.txt index 3336004f9..f0a5e6740 100644 --- a/npc/034-4/lobby.txt +++ b/npc/034-4/lobby.txt @@ -4,5 +4,187 @@ // Description: // Gemini Sisters Quest - Part C: Showdown +034-4,98,22,0 script #GeminiPartD NPC_HIDDEN,0,0,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(13); + .@p=getcharid(1); + if ($@VALIA_STATUS[.@p] < 15) { + dispbottom l("Luvia is too dangerous to be left alone."); + end; + } + if (mobcount(getmap(), "all") > 0) { + dispbottom l("I cannot leave until Luvia and her allies are dead."); + end; + } + if (mobcount(getmap(), "all") <= 0 && $@VALIA_STATUS[.@p] == 14) { + $@VALIA_STATUS[.@p]=15; + } + if ($@VALIA_STATUS[.@p] >= 15) { + slide 143, 96; + } + end; +} +// 98 36 with radius 12? +034-4,98,28,0 script #GeminiShowdown NPC_HIDDEN,2,1,{ + end; +OnTouch: + if (instance_id() < 0 || getcharid(1) < 1) end; + GeminiCheck(13); + .@p=getcharid(1); + if (strcharinfo(0) != getpartyleader(.@p)) end; + + if (!.state) { + .mp$ = getmap(); + .beats = 0; + .pid = getcharid(1); + .state = true; + initnpctimer; + killmonsterall(.mp$); // Cancel everything done thus far, incl. showdown + } + end; + +OnABC: + end; + +OnTimer1000: + .luvia = monster(.mp$, 98, 32, "Luvia Gemini", Luvia, 1); + immortal(.luvia); + setunitdata(.luvia, UDT_MODE, MD_BOSS|MD_PLANT|MD_NOKNOCKBACK); + end; + +OnTimer2500: + unittalk(.luvia, "Ara! Look at who is trying to sneak past me!"); + end; + +OnTimer6000: + unittalk(.luvia, "How silly. I prepared this party for ya, you know."); + end; + +OnTimer9500: + unittalk(.luvia, "Isbamuth wants all of you dead ─ And I'll carry out his orders."); + end; + +OnTimer13000: + unittalk(.luvia, "Long live Isbamuth... And death to traitors! Now begone!!"); + end; + +OnTimer15000: + // Create a new Luvia Gemini + unitwarp(.luvia, "034-4", 98, 32); + unitkill(.luvia); + .luvia = monster(.mp$, 98, 38, "Luvia Gemini", Luvia, 1, "#GeminiShowdown::OnABC"); + + // Grant her more HP if more players came to attack her + .@hp = getunitdata(.luvia, UDT_MAXHP) + (getmapusers(.mp$) * 10000); + setunitdata(.luvia, UDT_MAXHP, .@hp); + setunitdata(.luvia, UDT_HP, .@hp); + + // Reconfigure the AI + .@opt=getunitdata(.luvia, UDT_MODE); + // Add knockback immunity + .@opt=.@opt|MD_NOKNOCKBACK; + // Make it more op + .@opt=.@opt|MD_DETECTOR; + .@opt=.@opt|MD_CASTSENSOR_CHASE; + .@opt=.@opt|MD_CASTSENSOR_IDLE; + .@opt=.@opt|MD_CHANGECHASE; + .@opt=.@opt|MD_CHANGETARGET_MELEE; + .@opt=.@opt|MD_CHANGETARGET_CHASE; + setunitdata(.luvia, UDT_MODE, .@opt); + + + // Prepare the party, lalala! + .@pi = getmapusers(.mp$) * 2 + 1; + monster(.mp$, 117, 51, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 83, 58, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 83, 51, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 114, 29, strmobinfo(1, Scar), Scar, .@pi); + monster(.mp$, 98, 22, strmobinfo(1, Scar), Scar, .@pi); + $@VALIA_STATUS[.pid] = 14; + end; + +// The fight loops from 20k (the restart point) +// So this cycle happens every 10 seconds +OnTimer60000: +OnTimer45000: + consolewarn("Warning, fail-safe mechanism triggered to Luvia."); +OnTimer30000: + if (mobcount(.mp$, "#GeminiShowdown::OnABC") < 1) { + stopnpctimer; + end; + } + .beats+=1; + + /* Prepare some data */ + .@hp = getunitdata(.luvia, UDT_HP) * 10 / getunitdata(.luvia, UDT_MAXHP); + getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .luvia); + .@c=getunits(BL_PC, .@pcs, MAX_CYCLE_PC, .@m$); + .@mvp=0;.@rnd=0;.@def=-1; + for (.@i = 0; .@i < .@c; .@i++) { + if (!.@rnd || !rand2(.@c)) + .@rnd=.@pcs[.@i]; + if (readbattleparam(.@pcs[.@i], UDT_DEF) > .@def) { + if (readparam(Hp, .@pcs[.@i]) < 1) continue; + .@mvp=.@pcs[.@i]; + .@def=readbattleparam(.@pcs[.@i], UDT_DEF); + } + } + + // Luvia's spell casting + // She casts every ~30 seconds + switch (.beats % 18) { + case 0: + case 6: + case 12: + unittalk(.luvia, "Hahahah, die, die!"); + specialeffect(64, AREA, .luvia); + sleep(1000); + monster(.mp$, .@x, .@y, strmobinfo(1, Scar), Scar, max(1, (11 - .@hp) / 10)); + break; + case 3: + case 9: + case 15: + specialeffect(60, AREA, .luvia); + sleep(500); + switch (rand2(3)) { + case 1: + unittalk(.luvia, "I am your doom, and ##Bpoison##b is my tool!"); + .@sc = (.@hp < 1 ? SC_DPOISON : SC_POISON); + break; + case 2: + unittalk(.luvia, "You shall ##Bbleed##b, and cease!"); + .@sc = SC_BLOODING; + break; + case 3: + unittalk(.luvia, "The dead are ##Bsilent##b, just like you!"); + .@sc = SC_SILENCE; + break; + default: + unittalk(.luvia, "You won't see what killed you when ##Bblind##b!"); + .@sc = SC_BLIND; + break; + } + areasc(9, 45000, .@sc, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .luvia, 95000); + .@dmg=100 + (max(1, (11 - .@hp) / 10) * 40); + areaharm(.luvia, 9, .@dmg, HARM_MAGI, any(Ele_Water,Ele_Fire,Ele_Wind,Ele_Earth), "filter_always", BL_PC|BL_MER|BL_HOM); + break; + } + + // FIXME: Spawn other stuff as well, stronger stuff. + // Let them come from the doors + setnpctimer 20000; + end; + +OnInit: +OnInstanceInit: + .state = false; + .mp$ = ""; + .pid = 0; + .luvia = 0; + .beats = 0; + end; +} -- cgit v1.2.3-60-g2f50