summaryrefslogtreecommitdiff
path: root/npc/006-10/logic.txt
diff options
context:
space:
mode:
Diffstat (limited to 'npc/006-10/logic.txt')
-rw-r--r--npc/006-10/logic.txt485
1 files changed, 393 insertions, 92 deletions
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