diff options
author | Jesusalva Jesusalva <jesusalva@themanaworld.org> | 2023-07-17 01:48:54 +0000 |
---|---|---|
committer | Jesusalva Jesusalva <jesusalva@themanaworld.org> | 2023-07-17 01:48:54 +0000 |
commit | 5b0a9c8ffdbac30c4ff3981167c7206ca75425c7 (patch) | |
tree | 5a82418c9f0b725fed8d5e5cf0c1fa1a6fe861bc /npc/006-10 | |
parent | cac5c770e7bbb169e9516909dfc0d44afceb1446 (diff) | |
download | serverdata-5b0a9c8ffdbac30c4ff3981167c7206ca75425c7.tar.gz serverdata-5b0a9c8ffdbac30c4ff3981167c7206ca75425c7.tar.bz2 serverdata-5b0a9c8ffdbac30c4ff3981167c7206ca75425c7.tar.xz serverdata-5b0a9c8ffdbac30c4ff3981167c7206ca75425c7.zip |
Jesusalva/00610
Diffstat (limited to 'npc/006-10')
-rw-r--r-- | npc/006-10/_config.txt | 128 | ||||
-rw-r--r-- | npc/006-10/_import.txt | 1 | ||||
-rw-r--r-- | npc/006-10/_mobs.txt | 2 | ||||
-rw-r--r-- | npc/006-10/logic.txt | 485 |
4 files changed, 524 insertions, 92 deletions
diff --git a/npc/006-10/_config.txt b/npc/006-10/_config.txt new file mode 100644 index 0000000..333acee --- /dev/null +++ b/npc/006-10/_config.txt @@ -0,0 +1,128 @@ +// This file is generated automatically. All manually added changes will be removed when running the Converter. +// Map 006-10: Fefe's Crypt conf + +006-10,68,50,0 script #006-10_68_50 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: +OnTouchNPC: + IronTrap(80, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_68_50", NPC_TRAP; end; +} + +006-10,70,51,0 script #006-10_70_51 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: +OnTouchNPC: + IronTrap(80, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_70_51", NPC_TRAP; end; +} + +006-10,72,49,0 script #006-10_72_49 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: +OnTouchNPC: + IronTrap(80, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_72_49", NPC_TRAP; end; +} + +006-10,73,52,0 script #006-10_73_52 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: +OnTouchNPC: + IronTrap(80, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_73_52", NPC_TRAP; end; +} + +006-10,75,49,0 script #006-10_75_49 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: +OnTouchNPC: + IronTrap(80, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_75_49", NPC_TRAP; end; +} + +006-10,50,27,0 script #006-10_50_27 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: + IronTrap(30, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_50_27", NPC_TRAP; end; +} + +006-10,50,28,0 script #006-10_50_28 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: + IronTrap(30, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_50_28", NPC_TRAP; end; +} + +006-10,52,27,0 script #006-10_52_27 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: + IronTrap(30, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_52_27", NPC_TRAP; end; +} + +006-10,52,28,0 script #006-10_52_28 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: + IronTrap(30, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_52_28", NPC_TRAP; end; +} + +006-10,54,27,0 script #006-10_54_27 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: + IronTrap(30, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_54_27", NPC_TRAP; end; +} + +006-10,54,28,0 script #006-10_54_28 NPC_TRAP,0,0,{ + mesn strcharinfo(0); + mesq l("Something seems off with that!"); + close; +OnTouch: + IronTrap(30, 15, 1); + end; +OnTimer15000: + stopnpctimer; setnpctimer 0; setnpcdisplay "#006-10_54_28", NPC_TRAP; end; +} diff --git a/npc/006-10/_import.txt b/npc/006-10/_import.txt index 4c0c28f..72ca523 100644 --- a/npc/006-10/_import.txt +++ b/npc/006-10/_import.txt @@ -1,5 +1,6 @@ // Map 006-10: Fefe's Crypt // This file is generated automatically. All manually added changes will be removed when running the Converter. +"npc/006-10/_config.txt", "npc/006-10/_mobs.txt", "npc/006-10/_warps.txt", "npc/006-10/logic.txt", diff --git a/npc/006-10/_mobs.txt b/npc/006-10/_mobs.txt index 16b27b7..9575b1a 100644 --- a/npc/006-10/_mobs.txt +++ b/npc/006-10/_mobs.txt @@ -1,3 +1,5 @@ // This file is generated automatically. All manually added changes will be removed when running the Converter. // Map 006-10: Fefe's Crypt mobs 006-10,54,44,24,24 monster Vampire Bat 1063,18,300000,30000 +006-10,73,28,3,1 monster Vicious Chest 1148,1,10000,10000 +006-10,71,26,3,1 monster Evil Chest 1149,1,10000,10000 diff --git a/npc/006-10/logic.txt b/npc/006-10/logic.txt index 601563d..f662b2d 100644 --- a/npc/006-10/logic.txt +++ b/npc/006-10/logic.txt @@ -2,129 +2,430 @@ // Author: // Jesusalva // Description: -// Crazyfefe's Shrine +// Crazyfefe's Shrine (remastered) 006-10 mapflag zone MMO +026-2 mapflag zone MMO // We need to refactor this warp system, replace NPC_HIDDEN, and include the boss +006-10,54,58,0 script Blanc NPC_BLANC,{ + if (getunittype(.blanc) >= 0) end; + mesc l("Isn't that Blanc? Should we attempt to capture him?"); + mesc l("Advised: 6+ players"), 1; + mesc l("Advised: 1+ mage, 1+ tanker, 2+ healers"), 1; + mesc l("No Time Limit"), 1; + mesc l("Enter/Leave after start: %s", b(l("YES"))), 1; + next; + select + l("Not yet."), + l("Bring it on!"), + rif(is_gm(), l("Bring me, my worst nightmare.")); + mes ""; + if (@menu == 1) { + closeclientdialog; + close; + } + if (@menu == 2) + .hard = false; + else + .hard = true; -006-10,46,45,0 script #00610WA NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 53, 46; end; -} + // Create the boss + .blanc = monster("006-10", 54, 61, "Blanc Halifax", Blanc, 1); + .@mlt = (.hard ? 15 : 10); -006-10,58,45,0 script #00610WB NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 54, 38; end; -} + // Basic attributes + .maxhp = (750000 * .@mlt / 10); // 750k ~ 1250k + setunitdata(.blanc, UDT_MAXHP, .maxhp); + setunitdata(.blanc, UDT_HP, .maxhp); + setunitdata(.blanc, UDT_ATKRANGE, (.hard ? 7 : 6)); -006-10,49,38,0 script #00610WC NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 42, 40; end; -} + // Reconfigure the AI + .@opt=getunitdata(.blanc, UDT_MODE); + // Disable looting + if (.@opt & MD_LOOTER) + .@opt=.@opt^MD_LOOTER; + // Add knockback immunity + .@opt=.@opt|MD_NOKNOCKBACK; + // Mark as boss + .@opt=.@opt|MD_BOSS; + // Mark as aggressive + .@opt=.@opt|MD_AGGRESSIVE; + .@opt=.@opt|MD_ANGRY; + // 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(.blanc, UDT_MODE, .@opt); -006-10,55,37,0 script #00610WD NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 45, 46; end; -} + // Nerf the damage, but never miss a hit + setunitdata(.blanc, UDT_ATKMIN, 60 * .@mlt / 10); // 60~90 dmg + setunitdata(.blanc, UDT_ATKMAX, 60 * .@mlt / 10); + setunitdata(.blanc, UDT_ADELAY, 2220 / .@mlt * 10); // 2220 or 1480ms + setunitdata(.blanc, UDT_HIT, 2400); -006-10,44,39,0 script #00610WE NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 50, 38; end; -} + // Boosting the defense is not necessary + // It nerfs weapons to 40% (bows to 20%) + // Then it resists 50% of Neutral element. + // Note it is strong against Water (25% dmg) + // And weak against Fire (snow) and Wind (100% dmg) + // Otherwise, behave as Ghost element -006-10,38,39,0 script #00610WF NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 35, 35; end; -} + // Make Blanc damn hard to damage until his reinforcements appear + sc_start SC_PRESTIGE, 5000, 120000, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE, .blanc; + // TODO: Defense and attributes are wrong? + disablenpc .name$; + initnpctimer; + closeclientdialog; + close; -006-10,30,34,0 script #00610WG NPC_HIDDEN,0,3,{ +OnRw: + dispbottom l("Mission accomplished. Well played!"); + // Mark as "done" on Mirror Lake Quest Tracker + ##01_CRQUEST = ##01_CRQUEST | MLP_CR_DEBUT; + specialeffect(FX_FANFARE, AREA, getcharid(3)); + sleep2(15000); + $@EVENT_08 = PORTHOS_UNUSED; + warp("033-1", 72, 191); end; -OnTouch: - slide 33, 25; end; -} -006-10,38,24,0 script #00610WH NPC_HIDDEN,0,3,{ +// Fail-safe Mechanism (will never happen) +OnTimer60000: + consolebug("Warning! final fail-safe mechanism triggered to Blanc."); + initnpctimer; end; -OnTouch: - slide 45, 22; end; -} +OnTimer25000: +OnTimer15000: + consolewarn("Warning, fail-safe mechanism triggered to Blanc."); +// This is the boss' core +OnTimer5000: + /* Regeneration & Defeat Loop */ + .@end = false; + // FIXME: Don't check the WHOLE map, just the current platform? + if (!getmapusers("006-10")) { + .@hp = getunitdata(.blanc, UDT_HP); + .@mh = .maxhp; + .@hp = max(.@mh, .@hp + (.@mh / 500)); // Regenerates 0.2% HP + // Fully healed, players lost + if (.@hp >= .@mh) + .@end = true; + // Regeneration + setunitdata(.blanc, UDT_HP, .@hp); + } -006-10,50,21,0 script #00610WI NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 57, 29; end; -} + /* Maybe the fight is over */ + if (!mobcount("006-10", "all") || getunittype(.blanc) < 0) { + $@EVENT_08 = PORTHOS_BUSY; + maptimer2("006-10", 10, "Blanc::OnRw"); + } + if (!mobcount("006-10", "all") || getunittype(.blanc) < 0 || .@end) { + killmonsterall("006-10"); + enablenpc .name$; + kamibroadcast("The battle is over!", "Blanc Showdown"); + .beats = 0; + stopnpctimer; + end; + } -006-10,52,28,0 script #00610WJ NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 45, 31; end; -} + /* Move platform according to HP threshold */ + .@hp = getunitdata(.blanc, UDT_HP) * 10 / .maxhp; + .@state = 9 - limit(0, .@hp, 9); // The platform ID they should be on + debugmes "HP %d / %d (%d%%) (S %d/%d) [%03d@%d]", getunitdata(.blanc, UDT_HP), .maxhp, .@hp, .@state, .state, .beats, .blanc; + if (.state != .@state) { + unittalk(.blanc, "Damn, you guys are tough! I must fall back!"); + sleep(100); + unitwarp(.blanc, "006-10", $@BLANC_X[.@state], $@BLANC_Y[.@state]); + sleep(100); + unittalk(.blanc, "Outta the way!"); + .state = .@state; + } -006-10,40,30,0 script #00610WK NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 37, 25; end; -} + /* Prepare some combat data */ + // TODO: Maybe not universal? Maybe we should impose a range? + getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .blanc); + .@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); + } + } + .beats += 1; -006-10,32,24,0 script #00610WL NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 31, 46; end; -} + /* Everyone is dead, get rid of their corpses */ + if (!.@mvp || !.@rnd) { + mapwarp("006-10", "033-1", 72, 191); + initnpctimer; + end; + } -006-10,36,45,0 script #00610WM NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 41, 46; end; -} + //debugmes "----------- Skill Loop, beat is %d", .beats % 18; + /* Decide the skill to use based on ~5s beats over 3 minutes */ + switch (.beats % 18) { + // (1/6) Summon Reinforcements (every 60s) + case 1: + case 7: + case 13: + unittalk(.blanc, "Come forth, ##BHalifax's Crew##b, do not let these fools arrest your captain!"); + specialeffect(FX_MGWARP, AREA, .blanc); // Maybe 65 would also work + sleep(1000); + // Default amount: Half players + Half magnifying HP + .@max = (getmapusers("006-10")/2) + (max(1, (11 - .@hp) / 10)/2); + // Keep boundaries: Never less than 1, never more than 10 + .@max = limit(1, .@max, 10); + for (.@i=0; .@i < .@max; .@i++) { + .@mob = any(Thug, Grenadier, Swashbuckler); + monster(.@m$, .@x, .@y, strmobinfo(1, .@mob), .@mob, 1); + } + break; + // (2/6) Tanker (~30s) + case 0: + case 4: + case 6: + case 10: + case 12: + case 16: + specialeffect(FX_ATTACK, AREA, .blanc); + sleep(1000); + if (.@hp < 3) { + // Third Attack Pattern: Judgment + unittalk(.blanc, sprintf("%s cannot stop me! ##BElectric Judgment##b!", strcharinfo(0, "cursed player", .@mvp))); + .@PW=240; .@SPW=60; .@RG=3; + } else if (.@hp < 7) { + // Second Attack Pattern: Holy Light + unittalk(.blanc, sprintf("%s, I'll show you no mercy! ##BThunder Bolt##b!", strcharinfo(0, "cursed player", .@mvp))); + .@PW=125; .@SPW=25; .@RG=1; + } else { + // First Attack Pattern: Napalm Beat + unittalk(.blanc, sprintf("This battle is over, %s! ##BThunder Neddle##b!", strcharinfo(0, "cursed player", .@mvp))); + .@PW=35; .@SPW=5; .@RG=2; + } + .@mtk = calcdmg(.blanc, .@mvp, HARM_MAGI); + .@dmg = .@mtk * .@PW / 100; + .@dsb = .@mtk * .@SPW / 100; + sleep(1000); + specialeffect(FX_LIGHTNING, AREA, .@mvp); + areaharm(.@mvp, .@RG, .@dsb, HARM_MAGI, Ele_Wind, "filter_always", BL_PC|BL_MER|BL_HOM); + harm(.@mvp, .@dmg, HARM_MAGI, Ele_Holy); + break; + // (3/6) Random Target (~60s) + case 2: + case 8: + case 14: + specialeffect(FX_SMOKE, AREA, .blanc); + sleep(1000); + .@time=rand2(18000, 36000) + 10000 - (.@hp * 1000); + // Switch between curse and disable + if (any(true,false)) { + unittalk(.blanc, sprintf("I hereby ##Bcurse##b you, %s!", strcharinfo(0, "cursed player", .@rnd))); + sc_start(SC_CURSE, .@time, 1, 10000, SCFLAG_FIXEDRATE, .@rnd); + } else { + unittalk(.blanc, sprintf("I shall ##Bdisable##b you, %s!", strcharinfo(0, "cursed player", .@rnd))); + sc_start(SC_BLIND, .@time / 2, 1, 10000, SCFLAG_FIXEDRATE, .@rnd); + sc_start(SC_SILENCE, .@time / 2, 1, 10000, SCFLAG_FIXEDRATE, .@rnd); + } + // Second pattern: Bleeding ON + if (.@hp < 7) { + sc_start(SC_BLOODING, 10000, 1, 9000-(.@hp*1000), SCFLAG_FIXEDRATE, .@rnd); + } + specialeffect(FX_LIGHTNING, AREA, .@rnd); + break; + // (4/6) Traps (~60s) + case 3: + case 9: + case 15: + // Determine if there'll be 4 or 2 AoE explosions + .@extra = (.@hp < 5 || .hard); + // Coordinates are between origin and Blanc + // ID 3 and ID 6 were disabled - the platforms are small + .@mx=$@BLANC_X[.@state]; + .@my=$@BLANC_Y[.@state]; + .@x1=rand2(.@mx, .@x); .@x2=rand2(.@mx, .@x); + .@y1=rand2(.@my, .@y); .@y2=rand2(.@my, .@y); + // TODO: Maybe replace Dummy/EnergyBall with an invisible monster? + .@t1=monster("006-10", .@x1, .@y1, "", EnergyBall, 1); + .@t2=monster("006-10", .@x2, .@y2, "", EnergyBall, 1); + specialeffect(67, AREA, .@t1); + specialeffect(67, AREA, .@t2); + immortal(.@t1); immortal(.@t2); + if (.@extra) { + .@x4=rand2(.@mx, .@x); .@x5=rand2(.@mx, .@x); + .@y4=rand2(.@my, .@y); .@y5=rand2(.@my, .@y); + .@t4=monster("006-10", .@x1, .@y1, "", EnergyBall, 1); + .@t5=monster("006-10", .@x2, .@y2, "", EnergyBall, 1); + specialeffect(67, AREA, .@t4); + specialeffect(67, AREA, .@t5); + immortal(.@t4); immortal(.@t5); + } + sleep(1500); + // This is just a prop + specialeffect(FX_LIGHTNING, AREA, .@t1); + specialeffect(FX_LIGHTNING, AREA, .@t2); + if (.@extra) { + specialeffect(FX_LIGHTNING, AREA, .@t4); + specialeffect(FX_LIGHTNING, AREA, .@t5); + } + sleep(500); + specialeffect(FX_CRITICAL, AREA, .@t1); + specialeffect(FX_CRITICAL, AREA, .@t2); + if (.@extra) { + specialeffect(FX_CRITICAL, AREA, .@t4); + specialeffect(FX_CRITICAL, AREA, .@t5); + } + areaharm(.@t1, 1, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM); + areaharm(.@t2, 1, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM); + if (.@extra) { + areaharm(.@t4, 1, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM); + areaharm(.@t5, 1, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM); + } + sleep(1000); + // FIXME: M+ fails to remove them, need @refresh (maybe @refreshall?) + // NOTE: The effect NÂș 67 (halo circle) is also not cleaned by M+ + unitkill(.@t1); unitkill(.@t2); + if (.@extra) { + unitkill(.@t4); unitkill(.@t5); + } + break; + // (5/6) Weak AOE (~60s) + case 5: + case 11: + case 17: + specialeffect(60, AREA, .blanc); + sleep(500); + switch (rand2(3)) { + case 1: + unittalk(.blanc, "Cease! I shall ##Bpoison##b all of you!"); + .@sc = (.@hp < 1 ? SC_DPOISON : SC_POISON); + break; + case 2: + unittalk(.blanc, "Cease! I shall ##Bhurt##b all of you!"); + .@sc = SC_BLOODING; + break; + case 3: + unittalk(.blanc, "Cease! I shall ##Bsilence##b all of you!"); + .@sc = SC_SILENCE; + break; + default: + unittalk(.blanc, "Cease! I shall ##Bcripple##b all of you!"); + .@sc = SC_BLIND; + break; + } + areasc((.hard ? 7 : 5), 30000, .@sc, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .blanc, 95000); + areaharm(.blanc, (.hard ? 7 : 5), 100, HARM_MAGI, Ele_Wind, "filter_always", BL_PC|BL_MER|BL_HOM); + // Forces everyone to sit, for cosmetic effect + areasc(18, 500, SC_BANANA_BOMB_SITDOWN_POSTDELAY, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .blanc); + break; + } + // Strong AOE: Every 3 minutes (case = 0) + // Stalls all other skills for a while + if (.beats % 18 == 0) { + specialeffect(66, AREA, .blanc); + unittalk(.blanc, "I am Blanc, Halifax's captain!"); + sleep((.hard ? 1000 : 1500)); + specialeffect(700, AREA, .blanc); + unittalk(.blanc, "I'll never be caught by your ilk alive!"); + sleep((.hard ? 1000 : 1500)); + specialeffect(700, AREA, .blanc); + if (.@hp < 3) { + unittalk(.blanc, "Perish! ##BRage of Hungry Thunder##b!"); + .@dmg=rand2(900, 1100); + areasc3((.hard ? 5 : 4), 11000, SC_STOMACHACHE, BL_PC|BL_HOM|BL_MER, (.hard ? 20 : 15), "filter_always", .blanc, 6000); + areasc(6, 10000, SC_BLIND, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .blanc, 2000); + } else if (.@hp < 7) { + unittalk(.blanc, "Perish! ##BVoracious Thunder Storm##b!"); + .@dmg=rand2(650, 900); + areasc3((.hard ? 4 : 3), 11000, SC_STOMACHACHE, BL_PC|BL_HOM|BL_MER, (.hard ? 15 : 10), "filter_always", .blanc, 4500); + } else { + unittalk(.blanc, "Perish! ##BEletric Needles##b!"); + .@dmg=rand2(400, 650); + } + /* Three blocks */ + specialeffect(66, AREA, .blanc); + areaharm(.blanc, (.hard ? 7 : 5), .@dmg, HARM_MAGI, Ele_Fire, "filter_always", BL_PC|BL_MER|BL_HOM); + sleep(500); + specialeffect(66, AREA, .blanc); + areaharm(.blanc, (.hard ? 15 : 10), .@dmg, HARM_MAGI, Ele_Holy, "filter_always", BL_PC|BL_MER|BL_HOM); + sleep(500); + specialeffect(66, AREA, .blanc); + specialeffect(FX_LIGHTNING, AREA, .blanc); + areaharm(.blanc, (.hard ? 24 : 18), .@dmg, HARM_MAGI, Ele_Wind, "filter_always", BL_PC|BL_MER|BL_HOM); + areasc((.hard ? 24 : 18), .@dmg*rand2(50, 100), SC_FROSTMISTY, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .blanc, 10001 - (.@hp * 1000)); // SC_FROSTMISTY - General crippling + } -006-10,30,45,0 script #00610WN NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 57, 46; end; -} -// -------------------------------------------------- -006-10,52,45,0 script #00610WO NPC_HIDDEN,0,3,{ + initnpctimer; end; -OnTouch: - slide 45, 46; end; -} -006-10,40,45,0 script #00610WP NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 35, 35; end; -} +OnInit: + .distance = 4; + .beats = 0; // Skill cooldown timer + .hard = 0; // Hard mode (for GMs) + .blanc = 0; // Boss GID + .state = 0; // Current platform ID + .maxhp = 0; // Blanc's max HP (getunitdata(.blanc, UDT_MAXHP) is broken) -006-10,36,34,0 script #00610WQ NPC_HIDDEN,0,3,{ - end; -OnTouch: - slide 40, 40; end; -} + // TODO: In general, we have no idea of platforms size + setarray $@BLANC_X, 53, 72, 71, 72, 52, 36, 34, 35, 35, 52; + setarray $@BLANC_Y, 63, 67, 53, 30, 30, 27, 48, 36, 63, 36; -006-10,58,28,0 script #00610WR NPC_HIDDEN,0,3,{ + // .@index = miller_rand(.@state, getcharid(0), 10); end; -OnTouch: - slide 49, 22; end; } -006-10,46,30,0 script #00610WS NPC_HIDDEN,0,3,{ +// Below be the warp system. Rightmost forwards, leftmost rewinds. + +006-10,51,64,0 script #00610XX NPC_HIDDEN,1,0,{ end; OnTouch: - slide 53, 29; end; + // Now... WTF are we on miller rand? + if (!@miller_fix) { + for (.@i=0;.@i<10;.@i++) { + if (miller_rand(.@i, getcharid(0), 10) == 0) { + @miller_fix = .@i; + break; + } + } + } + // Set "@state" properly + @state = @miller_fix; + end; } - -006-10,44,21,0 script #00610WT NPC_HIDDEN,0,3,{ +006-10,57,61,0 script #00610WA+ NPC_FANCY_CIRCLE,0,0,{ end; OnTouch: - slide 37, 25; end; + // All portals are the same, anyway + if (compare(strnpcinfo(2), "+")) + @state = ((@state+1) % 10); // Technically, the loop is not needed + else + @state = ((@state-1) % 10); // Technically, this loop is not needed + .@index = miller_rand(@state, getcharid(0), 10); + slide $@BLANC_X[.@index], $@BLANC_Y[.@index]; + end; } +// NOTE: Vampire Bats are aggressive, they're tasked in disposing non-fighters +006-10,49,60,0 duplicate(#00610WA+) #00610WA- NPC_FANCY_CIRCLE,0,0 +006-10,75,65,0 duplicate(#00610WA+) #00610WB+ NPC_FANCY_CIRCLE,0,0 +006-10,68,64,0 duplicate(#00610WA+) #00610WB- NPC_FANCY_CIRCLE,0,0 +006-10,75,50,0 duplicate(#00610WA+) #00610WC+ NPC_FANCY_CIRCLE,0,0 +006-10,67,49,0 duplicate(#00610WA+) #00610WC- NPC_FANCY_CIRCLE,0,0 +006-10,76,27,0 duplicate(#00610WA+) #00610WD+ NPC_FANCY_CIRCLE,0,0 +006-10,68,26,0 duplicate(#00610WA+) #00610WD- NPC_FANCY_CIRCLE,0,0 +006-10,56,27,0 duplicate(#00610WA+) #00610WE+ NPC_FANCY_CIRCLE,0,0 +006-10,48,26,0 duplicate(#00610WA+) #00610WE- NPC_FANCY_CIRCLE,0,0 +006-10,40,24,0 duplicate(#00610WA+) #00610WF+ NPC_FANCY_CIRCLE,0,0 +006-10,32,24,0 duplicate(#00610WA+) #00610WF- NPC_FANCY_CIRCLE,0,0 +006-10,37,51,0 duplicate(#00610WA+) #00610WG+ NPC_FANCY_CIRCLE,0,0 +006-10,30,45,0 duplicate(#00610WA+) #00610WG- NPC_FANCY_CIRCLE,0,0 +006-10,41,33,0 duplicate(#00610WA+) #00610WH+ NPC_FANCY_CIRCLE,0,0 +006-10,30,33,0 duplicate(#00610WA+) #00610WH- NPC_FANCY_CIRCLE,0,0 +006-10,44,63,0 duplicate(#00610WA+) #00610WI+ NPC_FANCY_CIRCLE,0,0 +006-10,35,57,0 duplicate(#00610WA+) #00610WI- NPC_FANCY_CIRCLE,0,0 +006-10,55,37,0 duplicate(#00610WA+) #00610WJ+ NPC_FANCY_CIRCLE,0,0 +006-10,49,37,0 duplicate(#00610WA+) #00610WJ- NPC_FANCY_CIRCLE,0,0 |