diff options
Diffstat (limited to 'world/map/npc')
114 files changed, 1689 insertions, 238 deletions
diff --git a/world/map/npc/001-1/stat_reset.txt b/world/map/npc/001-1/stat_reset.txt index e8c61ca3..78835d1a 100644 --- a/world/map/npc/001-1/stat_reset.txt +++ b/world/map/npc/001-1/stat_reset.txt @@ -5,4 +5,8 @@ set @npcname$, "Malivox"; callfunc "StatReset"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/001-2/_nodes.txt b/world/map/npc/001-2/_nodes.txt index 33eaa51b..bea02442 100644 --- a/world/map/npc/001-2/_nodes.txt +++ b/world/map/npc/001-2/_nodes.txt @@ -7,7 +7,7 @@ OnInit: setarray .m$, "_N-Alchemy", "001-2", "001-2", "001-2", "001-2"; setarray .x1, "_N-Alchemy", 92, 98, 92, 98; - setarray .y1, "_N-Alchemy", 89, 76, 76, 89; + setarray .y1, "_N-Alchemy", 89, 89, 76, 76; setarray .x2, "_N-Alchemy", 0, 0, 0, 0; setarray .y2, "_N-Alchemy", 0, 0, 0, 0; setarray .id, "_N-Alchemy", 0, 0, 0, 0; diff --git a/world/map/npc/001-2/pauline.txt b/world/map/npc/001-2/pauline.txt index 497116f6..8c67e00d 100644 --- a/world/map/npc/001-2/pauline.txt +++ b/world/map/npc/001-2/pauline.txt @@ -283,6 +283,10 @@ L_Close: S_Update_Mask: set QUEST_MAGIC2, (QUEST_MAGIC2 & ~(@Pauline_MASK)) | (@pauline_state << @Pauline_SHIFT); return; + +OnInit: + set .IS_MAGIC, 1; + end; } 001-2,79,74,0|script|PaulineDebug|208 diff --git a/world/map/npc/001-2/tondar.txt b/world/map/npc/001-2/tondar.txt index cb3a1070..e36cb66a 100644 --- a/world/map/npc/001-2/tondar.txt +++ b/world/map/npc/001-2/tondar.txt @@ -55,4 +55,8 @@ L_nopay: L_end: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/001-2/wizards.txt b/world/map/npc/001-2/wizards.txt index e51e7a66..aedeaa7b 100644 --- a/world/map/npc/001-2/wizards.txt +++ b/world/map/npc/001-2/wizards.txt @@ -11,7 +11,7 @@ close; OnInit: - if (puppet("001-2", 104, 19, "Desert Mana Seed#_M", 166) < 1) mapexit; + if (puppet("001-2", 104, 19, "Desert Mana Seed", 166) < 1) mapexit; if (puppet("001-2", 99, 22, "Wizard#1", 355) < 1) mapexit; if (puppet("001-2", 92, 24, "Wizard#2", 356) < 1) mapexit; if (puppet("001-2", 92, 30, "Wizard#3", 357) < 1) mapexit; @@ -21,5 +21,16 @@ OnInit: if (puppet("001-2", 117, 30, "Wizard#7", 361) < 1) mapexit; if (puppet("001-2", 110, 32, "Wizard#8", 362) < 1) mapexit; if (puppet("001-2", 104, 27, "Arch-Wizard#9", 354) < 1) mapexit; + set .IS_MAGIC, 1, getnpcid("Desert Mana Seed"); + set .IS_MAGIC, 1, getnpcid("Wizard#1"); + set .IS_MAGIC, 1, getnpcid("Wizard#2"); + set .IS_MAGIC, 1, getnpcid("Wizard#3"); + set .IS_MAGIC, 1, getnpcid("Wizard#4"); + set .IS_MAGIC, 1, getnpcid("Wizard#5"); + set .IS_MAGIC, 1, getnpcid("Wizard#6"); + set .IS_MAGIC, 1, getnpcid("Wizard#7"); + set .IS_MAGIC, 1, getnpcid("Wizard#8"); + set .IS_MAGIC, 1, getnpcid("Arch-Wizard#9"); end; + } diff --git a/world/map/npc/002-1/elanore.txt b/world/map/npc/002-1/elanore.txt index 15e8439e..3d398454 100644 --- a/world/map/npc/002-1/elanore.txt +++ b/world/map/npc/002-1/elanore.txt @@ -36,7 +36,7 @@ L_Return: return; } -002-1,75,62,0|script|Elanore#_M|108 +002-1,75,62,0|script|Elanore|108 { set @has_magic, getskilllv(SKILL_MAGIC); @@ -619,4 +619,8 @@ L_Close: S_update_var: set QUEST_MAGIC2, (QUEST_MAGIC2 & ~(@Q_MASK) | (@Q_status << @Q_SHIFT)); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/002-1/soul-menhir.txt b/world/map/npc/002-1/soul-menhir.txt index fa2a4508..06387baf 100644 --- a/world/map/npc/002-1/soul-menhir.txt +++ b/world/map/npc/002-1/soul-menhir.txt @@ -14,4 +14,8 @@ set @x, 0; set @y, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/002-1/traveler.txt b/world/map/npc/002-1/traveler.txt index 975786ae..dadbeff0 100644 --- a/world/map/npc/002-1/traveler.txt +++ b/world/map/npc/002-1/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@tulimshar_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/002-3/traveler.txt b/world/map/npc/002-3/traveler.txt index 48175be8..ebaf07da 100644 --- a/world/map/npc/002-3/traveler.txt +++ b/world/map/npc/002-3/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@tul_mine_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/003-4/time-traveler.txt b/world/map/npc/003-4/time-traveler.txt index 00a875f5..148ab95e 100644 --- a/world/map/npc/003-4/time-traveler.txt +++ b/world/map/npc/003-4/time-traveler.txt @@ -11,6 +11,10 @@ L_Warp: close2; warp "003-4", 171, 76; close; + +OnInit: + set .IS_MAGIC, 1; + end; } 003-4,165,73,0|script|Time Traveler#34|184 @@ -30,4 +34,8 @@ L_What: L_Leave: mes "Walk East from here to escape the time dilation bubble."; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/006-1/spirit.txt b/world/map/npc/006-1/spirit.txt index 4796121a..3c464383 100644 --- a/world/map/npc/006-1/spirit.txt +++ b/world/map/npc/006-1/spirit.txt @@ -282,14 +282,22 @@ S_update_var: return; } -006-1,67,68,0|script|#EarthImp0#_M|400 +006-1,67,68,0|script|#EarthImp0|400 { callfunc "EarthImpTouch"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } -006-1,68,68,0|script|#EarthImp1#_M|400 +006-1,68,68,0|script|#EarthImp1|400 { callfunc "EarthImpTouch"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/006-1/traveler.txt b/world/map/npc/006-1/traveler.txt index 7c84e040..a2f02b24 100644 --- a/world/map/npc/006-1/traveler.txt +++ b/world/map/npc/006-1/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@pachua_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/006-1/tree.txt b/world/map/npc/006-1/tree.txt index 57209d24..ef5fb113 100644 --- a/world/map/npc/006-1/tree.txt +++ b/world/map/npc/006-1/tree.txt @@ -155,8 +155,12 @@ L_Close: } -006-1,82,59,0|script|#DruidTree0#_M|400 +006-1,82,59,0|script|#DruidTree0|400 { callfunc "QuestTreeTouch"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/008-1/diryn.txt b/world/map/npc/008-1/diryn.txt index 6570f1d8..7e27e4e0 100644 --- a/world/map/npc/008-1/diryn.txt +++ b/world/map/npc/008-1/diryn.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@hurnscald_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/009-1/soul-menhir.txt b/world/map/npc/009-1/soul-menhir.txt index 3b8c5cee..da8a1224 100644 --- a/world/map/npc/009-1/soul-menhir.txt +++ b/world/map/npc/009-1/soul-menhir.txt @@ -1,5 +1,4 @@ // - 009-1,53,40,0|script|Soul Menhir#hurnscald|344 { set @map$, "009-1"; @@ -14,4 +13,8 @@ set @x, 0; set @y, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/009-2/trader.txt b/world/map/npc/009-2/trader.txt index 46ccafac..d66968e0 100644 --- a/world/map/npc/009-2/trader.txt +++ b/world/map/npc/009-2/trader.txt @@ -62,6 +62,7 @@ L_Trademenu: "Do you have Iron Powder?", L_Iron, "How about Sulphur Powder?", L_Sulphur, "I need Medium Healing Potions.", L_Healpots, + "I'd like to acquire an Enchanter's Amulet.", L_Eamulet, "I think I have everything I need, thanks.", L_Close; L_Iron: @@ -85,6 +86,13 @@ L_Healpots: "Alright.", L_Pots, "Whoa, that's way too much.", L_Close; +L_Eamulet: + mes "[Trader]"; + mes "\"These amulets are quite rare. Two times as rare as a Magic Ring, they say. I do have one though and would trade it off for two Magic Rings and thirteen Blood Stones. I've had a hard time finding those stones.\""; + menu + "Alright.", L_GetEamuletConfirm, + "I'd better check the shops out first.", L_Close; + L_Ipowder: if (countitem("IronOre") < 1) goto L_Missing; if (Zeny < @Ironprice) goto L_NotEnoughMoney; @@ -127,6 +135,27 @@ L_Pots: "Yes.", L_Trademenu, "No.", L_No; +L_GetEamuletConfirm: + mes "[Trader]"; + mes "\"Are you sure you wish to trade for the Enchanter's Amulet? All trades are final.\""; + menu + "No, I'd better think this over a bit more.", L_No, + "No thanks. I've changed my mind. What else do you trade, again?", L_Trademenu, + "Yes, I'm positive.", L_GetEamulet; + +L_GetEamulet: + if (countitem("MagicRing") < 2) goto L_Missing; + if (countitem("Bloodstone") < 13) goto L_Missing; + delitem "MagicRing", 1; + delitem "MagicRing", 1; + delitem "Bloodstone", 13; + getitem "EnchantersAmulet", 1; + mes "[Trader]"; + mes "\"Make good use of your new amulet. Would you like to trade anything else?\""; + menu + "Yes.", L_Trademenu, + "No.", L_No; + L_Full: mes "[Trader]"; mes "\"You must have been making a lot of trades...your bag is completely full! Come back after you've made some room.\""; diff --git a/world/map/npc/009-2/wyara.txt b/world/map/npc/009-2/wyara.txt index 1b912019..51e2ada6 100644 --- a/world/map/npc/009-2/wyara.txt +++ b/world/map/npc/009-2/wyara.txt @@ -1,7 +1,7 @@ // ---------------------------------------- // Wyara the Hurnscald witch // ---------------------------------------- -009-2,121,26,0|script|Wyara#_M|103 +009-2,121,26,0|script|Wyara|103 { set @Q_MASK, NIBBLE_2_MASK; set @Q_SHIFT, NIBBLE_2_SHIFT; @@ -554,4 +554,8 @@ L_Close: S_update_var: set QUEST_MAGIC2, (QUEST_MAGIC2 & ~(@Q_MASK) | (@Q_status << @Q_SHIFT)); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/009-3/sword.txt b/world/map/npc/009-3/sword.txt index 1a427731..9649d730 100644 --- a/world/map/npc/009-3/sword.txt +++ b/world/map/npc/009-3/sword.txt @@ -1,4 +1,4 @@ -009-3,26,100,0|script|#MysticSword#_M|400 +009-3,26,100,0|script|#MysticSword|400 { if (getskilllv(SKILL_MAGIC)) goto L_message; @@ -173,4 +173,8 @@ L_farewell: S_update_var: set QUEST_MAGIC, (QUEST_MAGIC & ~(@Q_MASK) | (@Q_status << @Q_SHIFT)); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/009-4/orum.txt b/world/map/npc/009-4/orum.txt index df9ac2d9..f7fea706 100644 --- a/world/map/npc/009-4/orum.txt +++ b/world/map/npc/009-4/orum.txt @@ -591,6 +591,10 @@ L_Close: set @Torch, 0; set @TorchColor, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } function|script|SetUpOrumQuest { @@ -626,4 +630,8 @@ function|script|SetUpOrumQuest callfunc "SetTorchColor"; callfunc "SetTorchIntensity"; return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/009-4/waric.txt b/world/map/npc/009-4/waric.txt index aa366318..075c340c 100644 --- a/world/map/npc/009-4/waric.txt +++ b/world/map/npc/009-4/waric.txt @@ -19,6 +19,10 @@ next; mes "\"Your fate is up to Waric now... don't expect me to do anything else for you.\""; close; + +OnInit: + set .IS_MAGIC, 1; + end; } 009-4,118,42,0|script|Waric#trap|153 @@ -94,4 +98,8 @@ L_Explain: L_Close: set @EXP_LEARNED_ALOT, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/011-1/auldsbel.txt b/world/map/npc/011-1/auldsbel.txt index 8f8fe66c..a289f86a 100644 --- a/world/map/npc/011-1/auldsbel.txt +++ b/world/map/npc/011-1/auldsbel.txt @@ -1,7 +1,7 @@ // Auldsbel the Wizard // Transmutation Magic expert -011-1,50,68,0|script|Auldsbel#_M|168 +011-1,50,68,0|script|Auldsbel|168 { set @mexp, MAGIC_EXPERIENCE & 65535; @@ -943,7 +943,7 @@ L_Next8: mes "\"I suggest that you run.\""; next; misceffect sfx_magic_transmute; - monster "this", 50, 68, "", 1034, 4, "Auldsbel#_M::OnSnakeDeath"; + monster "this", 50, 68, "", 1034, 4, "Auldsbel::OnSnakeDeath"; close; OnSnakeDeath: @@ -1287,4 +1287,8 @@ S_update_var: (QUEST_MAGIC & ~(@Q_MASK) | (@Q_status << @Q_SHIFT)); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/012-1/flowerpentagram2.txt b/world/map/npc/012-1/flowerpentagram2.txt index 3ce479e9..715b2611 100644 --- a/world/map/npc/012-1/flowerpentagram2.txt +++ b/world/map/npc/012-1/flowerpentagram2.txt @@ -94,4 +94,8 @@ L_PlacedFifthFlower: L_Close: set @localMonsterCount, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/012-3/mana-seed.txt b/world/map/npc/012-3/mana-seed.txt index 057665e0..73e1828f 100644 --- a/world/map/npc/012-3/mana-seed.txt +++ b/world/map/npc/012-3/mana-seed.txt @@ -1,4 +1,4 @@ -012-3,62,130,0|script|Forest Mana Seed#_M|166 +012-3,62,130,0|script|Forest Mana Seed|166 { setarray @magic_exp_needed, 0, // level 0 @@ -279,4 +279,8 @@ L_magic_destroy: L_end: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/012-3/traveler.txt b/world/map/npc/012-3/traveler.txt index b3c158ea..9f497dab 100644 --- a/world/map/npc/012-3/traveler.txt +++ b/world/map/npc/012-3/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@terranite_cave_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/013-1/flowerpentagram.txt b/world/map/npc/013-1/flowerpentagram.txt index 001b7e0a..5c5ec79b 100644 --- a/world/map/npc/013-1/flowerpentagram.txt +++ b/world/map/npc/013-1/flowerpentagram.txt @@ -86,6 +86,10 @@ S_CleanUp: killmonster "013-1", "#FlowerPentagram::OnAScorpionDeath"; killmonster "013-1", "#FlowerPentagram::OnBScorpionDeath"; return; + +OnInit: + set .IS_MAGIC, 1; + end; } function|script|FlowerPentagramCount diff --git a/world/map/npc/013-1/sagatha.txt b/world/map/npc/013-1/sagatha.txt index fe2a4e6f..07348181 100644 --- a/world/map/npc/013-1/sagatha.txt +++ b/world/map/npc/013-1/sagatha.txt @@ -72,7 +72,7 @@ L_next: } //---------------------------------------- -013-1,131,24,0|script|Sagatha#_M|167 +013-1,131,24,0|script|Sagatha|167 { callfunc "SagathaStatus"; @@ -444,4 +444,8 @@ S_update_var: (QUEST_MAGIC & ~(@Q_MASK) | (@Q_status << @Q_SHIFT)); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/013-1/traveler.txt b/world/map/npc/013-1/traveler.txt index 7439b8d8..acbe4d29 100644 --- a/world/map/npc/013-1/traveler.txt +++ b/world/map/npc/013-1/traveler.txt @@ -4,4 +4,8 @@ set @NpcTravelBit, $@magic_house_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/013-2/notes.txt b/world/map/npc/013-2/notes.txt index 3a0215b9..f412668b 100644 --- a/world/map/npc/013-2/notes.txt +++ b/world/map/npc/013-2/notes.txt @@ -39,6 +39,10 @@ L_Close: set @fixedMirror, 1; callfunc "useMirror"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Warp to wood clearings @@ -72,6 +76,10 @@ L_PlaceThree: L_Close: set @dest, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Warp to desert @@ -104,6 +112,10 @@ L_PlaceThree: L_Close: set @dest, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Warp to snow area @@ -135,6 +147,10 @@ L_Cave: L_Close: set @dest, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Warp to Inns @@ -166,6 +182,10 @@ L_PlaceThree: L_Close: set @dest, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Warp to mines @@ -197,6 +217,10 @@ L_PlaceThree: L_Close: set @dest, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Death @@ -208,6 +232,10 @@ L_Close: next; heal -Hp, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // Naked @@ -219,4 +247,8 @@ L_Close: next; nude; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/013-2/wizard.txt b/world/map/npc/013-2/wizard.txt index 13f3fc9c..7a3fd822 100644 --- a/world/map/npc/013-2/wizard.txt +++ b/world/map/npc/013-2/wizard.txt @@ -1,4 +1,4 @@ -013-2,66,39,0|script|Old Wizard#_W|116 +013-2,66,39,0|script|Old Wizard|116 { set @has_magic, getskilllv(SKILL_MAGIC); set MAGIC_FLAGS, MAGIC_FLAGS | MFLAG_KNOWS_OLD_WIZARD; @@ -155,4 +155,8 @@ L_Agree: L_Close: set @has_magic, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/013-3/barrier.txt b/world/map/npc/013-3/barrier.txt index d7875009..680bb0a4 100644 --- a/world/map/npc/013-3/barrier.txt +++ b/world/map/npc/013-3/barrier.txt @@ -1,6 +1,6 @@ // -013-3,71,21,0|script|#DemonMineBarrier1#_M|32767,1,0 +013-3,71,21,0|script|#DemonMineBarrier1|32767,1,0 { set @state, ((QUEST_Hurnscald & NIBBLE_2_MASK) >> NIBBLE_2_SHIFT); @@ -26,4 +26,8 @@ L_End: S_Update_Mask: set QUEST_Hurnscald, (QUEST_Hurnscald & ~(NIBBLE_2_MASK)) | (@state << NIBBLE_2_SHIFT); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/015-1/sword.txt b/world/map/npc/015-1/sword.txt index be23e23a..bbf60b72 100644 --- a/world/map/npc/015-1/sword.txt +++ b/world/map/npc/015-1/sword.txt @@ -1,4 +1,4 @@ -015-1,97,97,0|script|#MagicSword#_M|400 +015-1,97,97,0|script|#MagicSword|400 { if (getskilllv(SKILL_MAGIC)) goto L_message; @@ -321,4 +321,8 @@ S_update_var: (QUEST_MAGIC & ~(@Q_MASK) | (@Q_status << @Q_SHIFT)); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/017-1/flowerpentagram1.txt b/world/map/npc/017-1/flowerpentagram1.txt index 64128b4b..5480ad60 100644 --- a/world/map/npc/017-1/flowerpentagram1.txt +++ b/world/map/npc/017-1/flowerpentagram1.txt @@ -79,4 +79,8 @@ L_PlacedFifthFlower: L_Close: set @localMonsterCount, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/017-1/flowerpentagram5.txt b/world/map/npc/017-1/flowerpentagram5.txt index f8947dbd..628a9433 100644 --- a/world/map/npc/017-1/flowerpentagram5.txt +++ b/world/map/npc/017-1/flowerpentagram5.txt @@ -137,4 +137,8 @@ L_PlacedFifthFlower: L_Close: set @localMonsterCount, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/017-4/guardingspirit.txt b/world/map/npc/017-4/guardingspirit.txt index 8fef95ed..06dc0a6b 100644 --- a/world/map/npc/017-4/guardingspirit.txt +++ b/world/map/npc/017-4/guardingspirit.txt @@ -1,6 +1,6 @@ // Author: Jenalya -017-4,173,47,0|script|#Guarding Spirit#_M|204,0,0 +017-4,173,47,0|script|#Guarding Spirit|204,0,0 { goto L_Talk; @@ -94,4 +94,8 @@ OnTouch: goto L_Block; warp "017-4", 201, 26; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/017-4/orum.txt b/world/map/npc/017-4/orum.txt index 213f14af..58c605a4 100644 --- a/world/map/npc/017-4/orum.txt +++ b/world/map/npc/017-4/orum.txt @@ -840,4 +840,8 @@ L_Close: set @REWARD_MONEY, 0; set @REWARD_EXP, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/017-4/waric.txt b/world/map/npc/017-4/waric.txt index 1fc489f3..55b794c8 100644 --- a/world/map/npc/017-4/waric.txt +++ b/world/map/npc/017-4/waric.txt @@ -383,6 +383,10 @@ L_Close: set @SUP_lvl, 0; set @SUP_xp, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } 017-1,74,32,0|script|DebugFlowerP|153 diff --git a/world/map/npc/018-1/flowerpentagram3.txt b/world/map/npc/018-1/flowerpentagram3.txt index 857c412d..7f90965e 100644 --- a/world/map/npc/018-1/flowerpentagram3.txt +++ b/world/map/npc/018-1/flowerpentagram3.txt @@ -108,4 +108,8 @@ L_PlacedFifthFlower: L_Close: set @localMonsterCount, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/018-1/sword.txt b/world/map/npc/018-1/sword.txt index 8d5dc827..885c9532 100644 --- a/world/map/npc/018-1/sword.txt +++ b/world/map/npc/018-1/sword.txt @@ -1,4 +1,4 @@ -018-1,110,43,0|script|#IceSword#_M|400 +018-1,110,43,0|script|#IceSword|400 { if (getskilllv(SKILL_MAGIC)) goto L_message; @@ -8,4 +8,8 @@ L_message: mes "[Sword in Pond]"; mes "\"Zzzzzz.....\""; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/018-3/evil-obelisk.txt b/world/map/npc/018-3/evil-obelisk.txt index 4ecc00b3..1d4cea7d 100644 --- a/world/map/npc/018-3/evil-obelisk.txt +++ b/world/map/npc/018-3/evil-obelisk.txt @@ -15,4 +15,8 @@ set @x1, 0; set @y1, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/018-3/sword.txt b/world/map/npc/018-3/sword.txt index 83e9c6f2..5dfbedbf 100644 --- a/world/map/npc/018-3/sword.txt +++ b/world/map/npc/018-3/sword.txt @@ -1,4 +1,4 @@ -018-3,71,127,0|script|#DemonSword#_M|400 +018-3,71,127,0|script|#DemonSword|400 { if (getskilllv(SKILL_MAGIC)) goto L_message; @@ -8,4 +8,8 @@ L_message: mes "[Sword in Rock]"; mes "\"Ouch... my head...\""; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/020-1/soul-menhir.txt b/world/map/npc/020-1/soul-menhir.txt index c8f7740a..d9471f2b 100644 --- a/world/map/npc/020-1/soul-menhir.txt +++ b/world/map/npc/020-1/soul-menhir.txt @@ -14,4 +14,8 @@ set @x, 0; set @y, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/020-1/traveler.txt b/world/map/npc/020-1/traveler.txt index 421ed0e7..a5a5b9cf 100644 --- a/world/map/npc/020-1/traveler.txt +++ b/world/map/npc/020-1/traveler.txt @@ -4,4 +4,8 @@ set @NpcTravelBit, $@nivalis_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/025-4/battlecaves.txt b/world/map/npc/025-4/battlecaves.txt index 8acebf2a..8c281a35 100644 --- a/world/map/npc/025-4/battlecaves.txt +++ b/world/map/npc/025-4/battlecaves.txt @@ -75,6 +75,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 1 Checker ---------------------------- @@ -167,6 +170,10 @@ L_Close: L_no_root: mes "I don't have any roots in my inventory!"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 2 Checker ---------------------------- @@ -258,6 +265,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 3 Checker ---------------------------- @@ -351,6 +361,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 4 Checker ---------------------------- @@ -445,6 +458,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 5 Checker ---------------------------- @@ -539,6 +555,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 6 Checker ---------------------------- @@ -635,6 +654,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 7 Checker ---------------------------- @@ -731,6 +753,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 8 Checker ---------------------------- @@ -827,6 +852,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Cave 9 Checker ---------------------------- @@ -945,6 +973,9 @@ L_no_root: mes "I don't have any roots in my inventory!"; close; +OnInit: + set .IS_MAGIC, 1; + end; } // --------------------- Boss Cave Checker ---------------------------- @@ -1015,4 +1046,3 @@ L_Save: message strcharinfo(0), "You can't leave Julia here, all alone!"; end; } - diff --git a/world/map/npc/026-1/headless_man.txt b/world/map/npc/026-1/headless_man.txt index f922406d..96c8cd49 100644 --- a/world/map/npc/026-1/headless_man.txt +++ b/world/map/npc/026-1/headless_man.txt @@ -59,18 +59,21 @@ L_Quest_ask: L_Quest_start: mes "[Thurstan]"; mes "\"Great! I will need the following things.\""; - mes "\"" + @Wisp_Powder + " Wisp Powder,\""; - mes "\"" + @Polt_Powder + " Poltergeist Powder,\""; - mes "\"" + @Spec_Powder + " Spectre Powder,\""; - mes "\"" + @Iron_Pot + " Iron Potion,\""; - mes "\"" + @Conc_Pot + " Concentration Potion,\""; - mes "\"" + @Red_Dye + " vials of Red Dye,\""; - mes "\"" + @Yellow_Dye + " vials of Yellow Dye,\""; + mes "\"" + @Wisp_Powder + " [@@"+WispPowder+"|@@],\""; + mes "\"" + @Polt_Powder + " [@@"+PoltergeistPowder+"|@@],\""; + mes "\"" + @Spec_Powder + " [@@"+SpectrePowder+"|@@],\""; + mes "\"" + @Iron_Pot + " [@@"+IronPotion+"|@@],\""; + mes "\"" + @Conc_Pot + " [@@"+ConcentrationPotion+"|@@],\""; + mes "\"" + @Red_Dye + " vials of [@@"+RedDye+"|@@],\""; + mes "\"" + @Yellow_Dye + " vials of [@@"+YellowDye+"|@@],\""; mes "\"and...\""; - mes "\"" + @LB_Dye + " vials of Light Blue Dye,\""; + mes "\"" + @LB_Dye + " vials of [@@"+LightBlueDye+"|@@],\""; next; mes "[Thurstan]"; - mes "\"My friend also said that I should use a metal bowl instead of a wooden one. I don't have one and I think a cauldron from the kitchen would be too big. Perhaps we could use an Infantry Helmet to serve that task.\""; + mes "\"My friend also said that I should use a metal bowl instead of a wooden one. I don't have one and I think a cauldron from the kitchen would be too big. Perhaps we could use an [@@"+InfantryHelmet+"|@@] to serve that task.\""; + next; + mes "[Thurstan]"; + mes "\"He also said that a [@@"+PinkieHat+"|@@] is a perfect whisk for stirring this recipe since the glue does not stick to it.\""; next; mes "[Thurstan]"; mes "\"I know it probably doesn't seem like that much to you, but it is a really big deal for me. I will try to find something to compensate you for your efforts.\""; @@ -100,6 +103,7 @@ L_Quest_check: || countitem("RedDye") < @Red_Dye || countitem("YellowDye") < @Yellow_Dye || countitem("LightBlueDye") < @LB_Dye + || countitem("PinkieHat") < 1 || countitem("InfantryHelmet") < 1) goto L_Quest_notenough; @@ -111,6 +115,7 @@ L_Quest_check: delitem "RedDye", @Red_Dye; delitem "YellowDye", @Yellow_Dye; delitem "LightBlueDye", @LB_Dye; + delitem "PinkieHat", 1; delitem "InfantryHelmet", 1; getexp @Glue_Exp, 0; mes "[Thurstan]"; @@ -146,15 +151,15 @@ L_Quest_notenough: L_Quest_items: mes "[Thurstan]"; - mes "\"" + @Wisp_Powder + " Wisp Powder,\""; - mes "\"" + @Polt_Powder + " Poltergeist Powder,\""; - mes "\"" + @Spec_Powder + " Spectre Powder,\""; - mes "\"" + @Iron_Pot + " Iron Potion,\""; - mes "\"" + @Conc_Pot + " Concentration Potion,\""; - mes "\"" + @Red_Dye + " vials of Red Dye,\""; - mes "\"" + @Yellow_Dye + " vials of Yellow Dye,\""; - mes "\"" + @LB_Dye + " vials of Light Blue Dye,\""; - mes "\"We'll also need 1 Infantry Helmet to use as a bowl for mixing everything together.\""; + mes "\"" + @Wisp_Powder + " [@@"+WispPowder+"|@@],\""; + mes "\"" + @Polt_Powder + " [@@"+PoltergeistPowder+"|@@],\""; + mes "\"" + @Spec_Powder + " [@@"+SpectrePowder+"|@@],\""; + mes "\"" + @Iron_Pot + " [@@"+IronPotion+"|@@],\""; + mes "\"" + @Conc_Pot + " [@@"+ConcentrationPotion+"|@@],\""; + mes "\"" + @Red_Dye + " vials of [@@"+RedDye+"|@@],\""; + mes "\"" + @Yellow_Dye + " vials of [@@"+YellowDye+"|@@],\""; + mes "\"" + @LB_Dye + " vials of [@@"+LightBlueDye+"|@@],\""; + mes "\"We'll also need 1 [@@"+InfantryHelmet+"|@@] to use as a bowl for mixing everything together and 1 [@@"+PinkieHat+"|@@] as whisk for stirring since the glue does not stick to it.\""; goto L_Close; L_Quest_finished: diff --git a/world/map/npc/026-1/traveler.txt b/world/map/npc/026-1/traveler.txt index de743c14..ab905120 100644 --- a/world/map/npc/026-1/traveler.txt +++ b/world/map/npc/026-1/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@graveyard_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/026-2/golbenez.txt b/world/map/npc/026-2/golbenez.txt index 6cf76de1..2bcd29c6 100644 --- a/world/map/npc/026-2/golbenez.txt +++ b/world/map/npc/026-2/golbenez.txt @@ -416,7 +416,7 @@ S_Reidsmem: next; mes "It seems you're not only seeing Reid's memories, but also feeling them!"; next; - mes "Reid turns away from Savaric's door and walks to her rooms quickly. She is shivering. You feel her heart pounding."; + mes "Reid turns away from Savaric's door and walks to her room quickly. She is shivering. You feel her heart pounding."; next; mes "She enters the room and pulls a red dress out of a chest and changes into it. As you feel her heart pounding even faster, you recognize the dress as the one her ghost is wearing."; next; diff --git a/world/map/npc/027-5/_mobs.txt b/world/map/npc/027-5/_mobs.txt index 97c66e24..589f6e5a 100644 --- a/world/map/npc/027-5/_mobs.txt +++ b/world/map/npc/027-5/_mobs.txt @@ -6,8 +6,8 @@ 027-5,57,143,3,1|monster|Fallen|1045,1,30000ms,4000ms 027-5,62,141,2,1|monster|TheLost|1073,1,300000ms,8000ms 027-5,21,136,7,5|monster|Stalker|1075,4,60000ms,4000ms -027-5,69,42,97,41|monster|Wight|1124,6,60000ms,8000ms +027-5,70,39,100,34|monster|Wight|1124,6,60000ms,8000ms 027-5,69,56,97,69|monster|VampireBat|1066,30,100000ms,30000ms -027-5,68,42,97,40|monster|RedBone|1074,6,60000ms,8000ms -027-5,70,80,98,34|monster|PoisonSkull|1024,8,60000ms,8000ms -027-5,69,80,99,36|monster|FireSkull|1023,8,60000ms,8000ms +027-5,70,39,100,35|monster|RedBone|1074,6,60000ms,8000ms +027-5,70,73,98,24|monster|PoisonSkull|1024,8,60000ms,8000ms +027-5,69,73,99,24|monster|FireSkull|1023,8,60000ms,8000ms diff --git a/world/map/npc/029-1/soul-menhir.txt b/world/map/npc/029-1/soul-menhir.txt index 8113d9c5..702356bf 100644 --- a/world/map/npc/029-1/soul-menhir.txt +++ b/world/map/npc/029-1/soul-menhir.txt @@ -14,4 +14,8 @@ set @x, 0; set @y, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/029-1/traveler.txt b/world/map/npc/029-1/traveler.txt index befa8eef..0add5765 100644 --- a/world/map/npc/029-1/traveler.txt +++ b/world/map/npc/029-1/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@candor_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/029-2/morgan.txt b/world/map/npc/029-2/morgan.txt index c6dfa306..c5d48b43 100644 --- a/world/map/npc/029-2/morgan.txt +++ b/world/map/npc/029-2/morgan.txt @@ -23,7 +23,7 @@ OnInit: disablenpc "MorganDebug"; end; } -029-2,101,57,0|script|Morgan#_M|355 +029-2,101,57,0|script|Morgan|355 { callfunc "PCtoNPCRange"; if(@npc_check) end; @@ -137,6 +137,10 @@ L_LearningDone: L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } 029-2,113,59,0|shop|Zitoni|103,CactusDrink:*1,CactusPotion:*1,TinyManaElixir:*5,SmallManaElixir:*5,EnlighteningElixir:*1,ManaDust:*1 diff --git a/world/map/npc/029-2/stat_reset.txt b/world/map/npc/029-2/stat_reset.txt index d66cd2f9..17be61b9 100644 --- a/world/map/npc/029-2/stat_reset.txt +++ b/world/map/npc/029-2/stat_reset.txt @@ -48,4 +48,8 @@ L_Sorry: L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/029-4/time-traveler.txt b/world/map/npc/029-4/time-traveler.txt index 1242e7c4..1407e949 100644 --- a/world/map/npc/029-4/time-traveler.txt +++ b/world/map/npc/029-4/time-traveler.txt @@ -11,6 +11,10 @@ L_Warp: close2; warp "029-4", 24, 38; close; + +OnInit: + set .IS_MAGIC, 1; + end; } 029-4,26,36,0|script|Time Traveler#294|184 @@ -28,4 +32,8 @@ L_What: L_Leave: mes "Walk West from here to escape the time dilation bubble."; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/030-1/time-traveler.txt b/world/map/npc/030-1/time-traveler.txt index a79b812d..7c6aba65 100644 --- a/world/map/npc/030-1/time-traveler.txt +++ b/world/map/npc/030-1/time-traveler.txt @@ -11,6 +11,10 @@ L_Warp: close2; warp "030-1", 61, 29; close; + +OnInit: + set .IS_MAGIC, 1; + end; } 030-1,64,33,0|script|Time Traveler#30|184 @@ -31,4 +35,8 @@ L_What: L_Leave: mes "Walk North from here to exit the time dilation bubble."; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/030-2/avalia.txt b/world/map/npc/030-2/avalia.txt index 818fabae..9c5034d4 100644 --- a/world/map/npc/030-2/avalia.txt +++ b/world/map/npc/030-2/avalia.txt @@ -187,6 +187,10 @@ L_ThankYou: L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } 030-2,190,64,0|script|Milis|330 diff --git a/world/map/npc/030-3/orum_homunculus.txt b/world/map/npc/030-3/orum_homunculus.txt index 503374ff..0208d331 100644 --- a/world/map/npc/030-3/orum_homunculus.txt +++ b/world/map/npc/030-3/orum_homunculus.txt @@ -473,4 +473,8 @@ L_ThankYou: L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/033-1/traveler.txt b/world/map/npc/033-1/traveler.txt index 462e2586..11f93bcf 100644 --- a/world/map/npc/033-1/traveler.txt +++ b/world/map/npc/033-1/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@barbarians_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/048-2/sageNikolai.txt b/world/map/npc/048-2/sageNikolai.txt index fdc6e76d..fb121552 100644 --- a/world/map/npc/048-2/sageNikolai.txt +++ b/world/map/npc/048-2/sageNikolai.txt @@ -283,4 +283,8 @@ L_Close: set @bookpages, 0; set @slimes, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/048-2/traveler.txt b/world/map/npc/048-2/traveler.txt index 7b654d85..9f323eac 100644 --- a/world/map/npc/048-2/traveler.txt +++ b/world/map/npc/048-2/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@blue_sage_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/055-1/flowerpentagram4.txt b/world/map/npc/055-1/flowerpentagram4.txt index 1fdd64cf..cc2d5191 100644 --- a/world/map/npc/055-1/flowerpentagram4.txt +++ b/world/map/npc/055-1/flowerpentagram4.txt @@ -122,4 +122,8 @@ L_PlacedFifthFlower: L_Close: set @localMonsterCount, 0; close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/055-1/traveler.txt b/world/map/npc/055-1/traveler.txt index 1f36de77..233671bf 100644 --- a/world/map/npc/055-1/traveler.txt +++ b/world/map/npc/055-1/traveler.txt @@ -8,4 +8,8 @@ set @NpcTravelBit, $@hurns_farms_bit; callfunc "Traveler"; end; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/056-2/barrier.txt b/world/map/npc/056-2/barrier.txt index 956dc630..9552623f 100644 --- a/world/map/npc/056-2/barrier.txt +++ b/world/map/npc/056-2/barrier.txt @@ -14,5 +14,4 @@ L_Block: L_Weak: message strcharinfo(0), "I can't enter because this magic field is too strong. Maybe I should train some more...."; end; - } diff --git a/world/map/npc/056-2/mirak.txt b/world/map/npc/056-2/mirak.txt index e1a37347..8719e4b4 100644 --- a/world/map/npc/056-2/mirak.txt +++ b/world/map/npc/056-2/mirak.txt @@ -149,4 +149,8 @@ S_Update_Mask: (QUEST_Mirak & ~(@Mirak_MASK)) | (@talk << @Mirak_SHIFT); return; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/058-1/griffen.txt b/world/map/npc/058-1/griffen.txt index 4b81e9a6..8f794c55 100644 --- a/world/map/npc/058-1/griffen.txt +++ b/world/map/npc/058-1/griffen.txt @@ -42,4 +42,8 @@ L_Quest: L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/058-2/griffen.txt b/world/map/npc/058-2/griffen.txt index c6bce716..d2824dc8 100644 --- a/world/map/npc/058-2/griffen.txt +++ b/world/map/npc/058-2/griffen.txt @@ -40,4 +40,8 @@ L_Quest: L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/069-2/wizard.txt b/world/map/npc/069-2/wizard.txt index c94258ec..f3b71df4 100644 --- a/world/map/npc/069-2/wizard.txt +++ b/world/map/npc/069-2/wizard.txt @@ -131,6 +131,11 @@ L_Task: L_Doomsday: mes "[Rodium]"; + mes "\"No sorry the universe is too unstable at the moment. I can't warp you back in time in this state you must wait until it has calmed down.\""; + goto L_Menu2; + +/* + mes "[Rodium]"; mes "\"Yes. The Doomsday is how the third rewrite happened and the fourth timeline began. You can get a [@@"+SaviorArmor+"|@@] if you can watch until the very end, but I must warn you...\""; next; mes "[Rodium]"; @@ -169,7 +174,12 @@ OnWarp: mes "\"Please make your decision.\""; menu "I don't know what you're talking about, old man!", L_Close, "Yeah, they're my friend, please warp me!", L_Warp; +*/ L_Close: close; + +OnInit: + set .IS_MAGIC, 1; + end; } diff --git a/world/map/npc/099-1/main.txt b/world/map/npc/099-1/main.txt index cbe03c7c..75881ba5 100644 --- a/world/map/npc/099-1/main.txt +++ b/world/map/npc/099-1/main.txt @@ -12,7 +12,7 @@ callfunc "PCtoNPCRange"; if(@npc_check) end; - mes ".:: Keshlam's Adventurer Guild ::."; + mes ".:: Keshlam's Adventurer Guild ::."; mes ""; mes "Welcome to the Adventurers Guild!"; mes "Sorry I could not wait for you. It's your fault for being late."; @@ -43,7 +43,7 @@ next; mes "Signed,"; mes "Xakelbael the Dark"; - close; + close; } @@ -53,10 +53,10 @@ callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "Walk here to go to the ##BFinal Showdown##b."; + mes "Walk here to go to the ##BFinal Showdown##b."; mes ""; mes "##1##BWARNING:##b##0 Come prepared!"; - close; + close; L_Busy: mes "This warp cannot be used while players are on the other side!"; @@ -69,7 +69,7 @@ L_Menu: if ($@DD5_STATUS > 1) goto L_Busy; - mes "##BGo to the final showdown?##b"; + mes "##BGo to the final showdown?##b"; mes "You cannot return from there!"; mes ""; mes "##1Warning: Warp will be unavailable during fights!"; @@ -86,5 +86,8 @@ L_Yes: if (!$@DD5_STATUS) donpcevent "#TMWFinalExam::OnWarn0"; close; -} +OnInit: + set .IS_MAGIC, 1; + end; +} diff --git a/world/map/npc/099-2/logic.txt b/world/map/npc/099-2/logic.txt index 29d7e96d..6b4667cd 100644 --- a/world/map/npc/099-2/logic.txt +++ b/world/map/npc/099-2/logic.txt @@ -111,12 +111,12 @@ OnJanitor: if(@npc_check) end; mes ".:: V0id Flower ::."; - mes "This orange flower is dangerous!"; + mes "This orange flower is dangerous!"; mes "Do not disturb them - they have great range and damage!"; mes ""; mes "Whoever designed this artifical flower must have been crazy!"; mes "Killing it is not fast enough, avoid its nectar at all costs!"; - close; + close; } 099-2,123,128,0|script|???#099-2_123_128|400 @@ -126,10 +126,10 @@ OnJanitor: if(@npc_check) end; mes ".:: V0id Slime ::."; - mes "A crazy combat unit made in a crazy laboratory."; + mes "A crazy combat unit made in a crazy laboratory."; mes "If you can, just avoid it. It is slow enough."; mes "It can be slain, but have a decent defense, so use magic."; - close; + close; } 099-2,95,122,0|script|???#099-2_95_122|400 @@ -139,9 +139,9 @@ OnJanitor: if(@npc_check) end; mes ".:: V0id Snake ::."; - mes "If I find who designed these monsters ... Grr..."; + mes "If I find who designed these monsters ... Grr..."; mes "They are fast. And powerful. Goes down quickly, though."; - close; + close; } 099-2,28,122,0|script|???#099-2_28_122|400 @@ -150,13 +150,13 @@ OnJanitor: callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "Last night, we were attacked by Xakelbael the Dark."; + mes "Last night, we were attacked by Xakelbael the Dark."; mes "Our attacks could barely do him any harm, and then..."; mes "He cast \"Fourth Fall\". All our buffed soldiers fell down the same instant."; mes ""; mes "I am gravely injured, but I'm leaving this note here."; mes "Comrades, please avenge me!"; - close; + close; } 099-2,91,92,0|script|???#099-2_91_92|400 @@ -166,11 +166,11 @@ OnJanitor: if(@npc_check) end; mes ".:: Sasquatch ::."; - mes "Developed for protection of the Earth Crystal."; + mes "Developed for protection of the Earth Crystal."; mes "They are extreme power houses capable to smash intruders."; mes "They have very meh defense, though."; mes "Also, even then could not harm Xakelbael the Dark."; - close; + close; } 099-2,62,43,0|script|???#099-6_62_43|400 @@ -179,7 +179,7 @@ OnJanitor: callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "Zax De'Kagen trademark skill, the Bliss of Oblivion."; + mes "Zax De'Kagen trademark skill, the Bliss of Oblivion."; mes "A powerful skill which dispels mana around himself."; mes "Monsters will perish the very moment he cast it, and anyone too close"; mes "will have their mana drained as well, and might die from it."; @@ -187,7 +187,7 @@ OnJanitor: mes "Not only that, but he may become immune to certain sources of damage."; mes "It is a killer move which also allows him to assemble an army right after."; mes "I do believe there is a weakness, though. Something about excessive fur growth?"; - close; + close; } 099-6,57,17,0|script|???#099-6_57_17|400 @@ -197,11 +197,11 @@ OnJanitor: if(@npc_check) end; mes ".:: V0id Soldier ::."; - mes "These units can endure a lot of pain and use bows."; - mes "They are not dangerous, but do not let they become fodder."; - mes "A lot of soldiers can be very difficult to kill later on."; + mes "These units can endure a lot of pain and use bows."; + mes "They are not dangerous, but do not let they become fodder."; + mes "A lot of soldiers can be very difficult to kill later on."; mes "Random trivia: They are afraid of bone arrows and knifes."; - close; + close; } 099-6,123,128,0|script|???#099-6_123_128|400 @@ -211,10 +211,10 @@ OnJanitor: if(@npc_check) end; mes ".:: V0id Mouboo ::."; - mes "A solid all rounder unit, it has decent health and damage."; + mes "A solid all rounder unit, it has decent health and damage."; mes "But it proved useless as a security biopart."; mes "Figures out, we could not subvert its peaceful nature."; - close; + close; } 099-6,95,122,0|script|???#099-6_95_122|400 @@ -224,10 +224,10 @@ OnJanitor: if(@npc_check) end; mes ".:: Tengu ::."; - mes "Developed for protection of the Earth Crystal."; + mes "Developed for protection of the Earth Crystal."; mes "There shouldn't be any here, but they have a high defense."; mes "They turned out vulnerable to magic, unfortunately."; - close; + close; } 099-6,28,122,0|script|???#099-6_28_122|400 @@ -237,12 +237,12 @@ OnJanitor: if(@npc_check) end; mes ".:: V0id Bat ::."; - mes "They fly very fast and can quickly swarm you."; + mes "They fly very fast and can quickly swarm you."; mes "Their damage and health is not important."; mes "But if not careful, they will overwhelm you."; mes "Also, did you hear about lay on hands on overlapping dimensions?"; mes "This have nothing to do with bats but is a cool fact!"; - close; + close; } 099-6,91,92,0|script|???#099-6_91_92|400 @@ -252,10 +252,10 @@ OnJanitor: if(@npc_check) end; mes ".:: Mana Slayer ::."; - mes "An anti-magic unit, made to run and slay mages."; + mes "An anti-magic unit, made to run and slay mages."; mes "They look so much like us, that we are afraid of them all time."; mes "Not strong against physical damage, but can resist magic pretty well."; - close; + close; } 099-6,62,43,0|script|???#099-6_92_43|400 @@ -264,7 +264,7 @@ OnJanitor: callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "Do not neglect the potions which you deemed useless until now."; + mes "Do not neglect the potions which you deemed useless until now."; mes "Our foe is formidable. Our knowledge is being tested, here."; mes "The same techniques which worked for years simply do not apply."; mes ""; @@ -272,7 +272,7 @@ OnJanitor: mes "I think what should sense magic, might sense mana devoid-ness as well."; mes "In this case, such would be the only way to know how far of killing we are."; mes "But I'm not sure if such trick would work except on support role."; - close; + close; } @@ -287,7 +287,7 @@ OnJanitor: mes "Reading this is as hard as finding a needle in a haystack."; if (debug) goto L_Close; if (countitem(FlawedLens) < 1) goto L_Tools; - mes "Although the painting also has no artistic value on its own..."; + mes "Although the painting also has no artistic value on its own..."; mes "Something tells you there is something ominous with it."; next; mes "##9 Use [Flawed Lens] on the painting? ##0"; @@ -318,10 +318,14 @@ L_UseLens: mes "Rest in Peace. Damnatio memoriae. Effective immediately."; // ;-- TRANSLATORS: Damnatio memoriae - "condemnation of memory", indicating that a person is to be excluded from official accounts. History rewrite if required. next; - //mes "The lens break! They were not only poorly effective but also of bad quality."; + //mes "The lens breaks! It was not only poorly effective, but also of bad quality."; mes "If only we could make the real Lens, we would have been able to find out"; - mes "what is up with this ominous, eerie feeling this picture gives."; + mes "What is up with this ominous, eerie feeling this picture gives?"; close; + +OnInit: + set .IS_MAGIC, 1; + end; } 099-1,35,22,0|script|Fireplace#099-1|400 @@ -330,13 +334,13 @@ L_UseLens: callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "##9 There is something interesting on this fireplace. ##0"; - mes "##9 It doesn't seems to fit this building. ##0"; - mes "##9 As if it have been taken from another world and put here. ##0"; + mes "##9 There is something interesting on this fireplace. ##0"; + mes "##9 It doesn't seems to fit this building. ##0"; + mes "##9 As if it have been taken from another world and put here. ##0"; next; - mes "##9 After searching it, you found nothing. ##0"; - mes "##9 It is just a common fireplace, after all. ##0"; - close; + mes "##9 After searching it, you found nothing. ##0"; + mes "##9 It is just a common fireplace, after all. ##0"; + close; } /////////////////////////////// @@ -348,14 +352,14 @@ L_UseLens: if(@npc_check) end; mes ".:: V0id Scorpion ::."; - mes "The most basic combat unit in Keshlam."; + mes "The most basic combat unit in Keshlam."; mes "They have decent health, damage, and speed."; mes ""; mes ".:: V0id Mushroom ::."; - mes "The most basic combat unit in Keshlam."; + mes "The most basic combat unit in Keshlam."; mes "They have decent health, damage, and speed, and a higher range."; mes "Unlike the scorpions, they can move faster, but attack is slower."; - close; + close; } 099-1,45,22,0|script|Bookcase#099-1b|400 @@ -365,13 +369,13 @@ L_UseLens: if(@npc_check) end; mes ".:: V0id Maggot ::."; - mes "They are pathetic individually, and slow, a failed experiment."; + mes "They are pathetic individually, and slow, a failed experiment."; mes "But do not let them overwhelm you, togheter they are formidable!"; mes ""; mes ".:: V0id Archant ::."; - mes "An advanced combat unit, without weak points."; + mes "An advanced combat unit, without weak points."; mes "They are slow in movement, but other than that, they are good."; - close; + close; } /////////////////////////////// @@ -382,7 +386,7 @@ L_UseLens: callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "There is a nice score here."; + mes "There is a nice score here."; mes "I assume important info will be sent by SFX only."; next; mes "Also, the time beats of this score are all in 600ms intervals."; @@ -391,7 +395,11 @@ L_UseLens: mes "However, potions will still work, hmm."; mes "There is also a spell here: \"##B#storage##b\"."; mes "I assume it only works at specific times."; - close; + close; + +OnInit: + set .IS_MAGIC, 1; + end; } 099-3,39,46,0|script|Outstanding Book#099-3|400 @@ -400,22 +408,22 @@ L_UseLens: callfunc "PCtoNPCRange"; if(@npc_check) end; - mes "Zax De'Kagen's Diary, entry #27"; + mes "Zax De'Kagen's Diary, entry #27"; mes ""; mes "##9 I am all soaking wet. They found my weak point. ##0"; mes "##9 However it was too late, Fourth Fall brought the end to this. ##0"; mes "##9 I did not even had to cancel my illusion. ##0"; next; - mes "Zax De'Kagen's Diary, entry #34"; + mes "Zax De'Kagen's Diary, entry #34"; mes ""; mes "##9 Today my Rubber Bat flew away. Probably shouldn't have given life to it. ##0"; mes "##9 I'll miss it, my dear friend, I hope one day he returns? ##0"; next; - mes "Zax De'Kagen's Diary, entry #42"; + mes "Zax De'Kagen's Diary, entry #42"; mes ""; mes "##9 What I wouldn't give for some pickled beets right now... ##0"; mes "##9 Meh, whatever. I'm not going to Dimond's Cove ever again! ##0"; - close; + close; } 099-3,64,62,0|script|Pan#099-3|400 @@ -429,20 +437,19 @@ L_UseLens: goto L_Potion; L_Shock: - mes "Some was trying to make Shock Sweets here."; - mes "However, it doesn't seems to have been finished."; + mes "Someone was trying to make Shock Sweets here."; + mes "However, they don't seem to be finished."; next; - mes "There are the initials \"To stop F.F.\" nearby."; + mes "An inscription reads, \"To stop F.F.\", nearby."; mes "One can only wonder who or what F.F. is."; - close; + close; L_Potion: - mes "Some was trying to make a Mana Potion here."; - mes "However, it doesn't seems to have been finished."; + mes "Someone was trying to make a Mana Potion here."; + mes "However, it doesn't seem to have been finished."; next; - mes "There are the initials \"To stop Bob\" nearby."; - mes "Well, I assume it is \"Bob\", text is fainted."; - mes "it could be \"boo\" as well. Maybe from Mouboo?"; - close; + mes "An inscription reads, \"To stop Bob\", nearby."; + mes "Well, I assume it is \"Bob\". The text is faded."; + mes "It could be \"boo\", as well. Maybe from Mouboo?"; + close; } - diff --git a/world/map/npc/099-5/boss.txt b/world/map/npc/099-5/boss.txt index 1ab584fd..1c282d8b 100644 --- a/world/map/npc/099-5/boss.txt +++ b/world/map/npc/099-5/boss.txt @@ -46,9 +46,9 @@ // bool // $@DD5_DEFCON - Defensive mode of Zax De'Kagen // 0 - Defenseless (#------- TRANSPARENT) -// 1 - Invencible (except to shearing) (#CC79A7 PURPLE) +// 1 - Invincible (except to shearing) (#CC79A7 PURPLE) // 2 - All damage is halved (#E69F00 ORANGE) -// 3 - Immune to potion'ed attackers (#D55E00 BROWN) +// 3 - Immune to potioned attackers (#D55E00 BROWN) // 4 - Vulnerable only when wet (#56B4E9 CYAN) // 5 - Vulnerable only to melee (#999999 GRAY) // 6 - Vulnerable to Bone Knife/Bone Arrow (#FFFFFF WHITE) @@ -89,12 +89,7 @@ 099-4|mapflag|resave|009-1,52,40 // Additional mapflags -099-3|mapflag|nosave|099-7,75,36 -099-3|mapflag|resave|099-7,75,36 -099-2|mapflag|nosave|099-7,75,36 -099-2|mapflag|resave|099-7,75,36 -099-1|mapflag|nosave|099-7,75,36 -099-1|mapflag|resave|099-7,75,36 +// 099-1/2/3/6 no flags set means: after relog you respawn at the same spot you logged off, on death you respawn at the last soul menhir 099-5,0,0,0|script|#TMWFinalExam|32767 { @@ -1302,6 +1297,7 @@ L_Return: end; OnInit: disablenpc strnpcinfo(0); + set .IS_MAGIC, 1; end; } @@ -1312,6 +1308,7 @@ OnInit: end; OnInit: disablenpc strnpcinfo(0); + set .IS_MAGIC, 1; end; } @@ -1322,6 +1319,7 @@ OnInit: end; OnInit: disablenpc strnpcinfo(0); + set .IS_MAGIC, 1; end; } @@ -1332,6 +1330,7 @@ OnInit: end; OnInit: disablenpc strnpcinfo(0); + set .IS_MAGIC, 1; end; } @@ -1525,6 +1524,7 @@ L_TooEarly: OnInit: disablenpc "Gema III"; + set .IS_MAGIC, 1; end; } ///////////////////////////////////////////////////// @@ -1535,6 +1535,7 @@ OnInit: end; OnInit: disablenpc "Xakelbael the Dark#0"; + set .IS_MAGIC, 1; end; OnTimer50000: @@ -1562,6 +1563,7 @@ OnDisable: end; OnInit: disablenpc "Zax De'Kagen#0"; + set .IS_MAGIC, 1; end; OnTimer18000: diff --git a/world/map/npc/099-7/boss.txt b/world/map/npc/099-7/boss.txt index 7d68bca8..b572c7cc 100644 --- a/world/map/npc/099-7/boss.txt +++ b/world/map/npc/099-7/boss.txt @@ -532,8 +532,8 @@ L_Off: if (!#CRYPT_PASSWORD) end; mes "There's an inscription on the gate."; next; - mes "\"The candle shall lit you, but if you mess up, a different light will show."; - mes "Alas did you knew, that Razha came before Krukan?\""; + mes "\"The candle should be lit, but if you mess up a different light will show."; + mes "Alas, did you know that Razha came before Krukan?\""; close; } @@ -552,7 +552,7 @@ L_Off: mes "There's an inscription on the gate."; next; mes "\"The master's candlesticks are like the fingers of his hand."; - mes "And if it is not to kill, they will never move.\""; + mes "And if they are not to kill, they will never move.\""; close; } @@ -563,9 +563,9 @@ L_Off: next; mes "\"##B"+get(.invocation$, "reapercry")+"##b\""; next; - mes "##9You hear the sounds of battle. Candle lights shines in distance."; + mes "##9You hear the sounds of battle. Candle light shines in the distance."; next; - mes "##9However, when you turn towards the source - both the light as the sound have already stopped."; + mes "##9However, when you turn towards the source, the light, as the sound, have already stopped."; next; mes "##9Is this a clue of some sort?"; close; @@ -581,7 +581,7 @@ L_Off: mes "Thanks to the lens on your inventory, you can read this:"; mes ""; mes "\"Nu'rem perished here, after the fight with Jande, Tal and Di'Tal."; - mes "For this very reason, this land is plagued forever. We shall give Nu'Rem a proper burrial.\""; + mes "For this very reason, this land is plagued forever. We shall give Nu'Rem a proper burial.\""; next; mes "-- The Sparron"; close; @@ -590,7 +590,7 @@ L_Tools: mes "It is too faint to read without some good lens, but you can make the following words out of the engraving:"; next; mes "\"Nu'rem .... here .... fight .... Jande ...."; - mes ".... land .... plagued forever. .... Nu'Rem .... proper burrial.\""; + mes ".... land .... plagued forever. .... Nu'Rem .... proper burial.\""; next; mes "-- The ...."; close; @@ -694,8 +694,8 @@ L_FlawedLens: L_Rare: getexp 15000000, 0; set KESHLAM_STATE, KESHLAM_STATE | FLAG_KESHLAM_RAREDROP; - if (rand(4) == 1) goto L_Amulet; // 25% chance - goto L_Ring; // 75% chance + if (rand(3) == 1) goto L_Amulet; // 33.33% chance + goto L_Ring; // 66.66% chance L_Amulet: getitem "EnchantersAmulet", 1; @@ -704,9 +704,9 @@ L_Amulet: close; L_Ring: - getitem "MageRing", 1; + getitem "MagicRing", 1; mes "[Chest]"; - mes "You opened it and found...! A Mage Ring! Lucky!"; + mes "You opened it and found...! A Magic Ring! Lucky!"; close; L_Not_Enough: @@ -786,4 +786,3 @@ L_No: warp "099-7", 92, 36; end; } - diff --git a/world/map/npc/099-7/chronos.txt b/world/map/npc/099-7/chronos.txt index c0e0c9e8..6ca56cf8 100644 --- a/world/map/npc/099-7/chronos.txt +++ b/world/map/npc/099-7/chronos.txt @@ -64,7 +64,7 @@ L_MaxedMedals: mes "I just reached out telepatically to the invisible forces that keep this world into motion and told them what happened to you, so they are aware of your situation.\""; next; goto L_Question; - + L_ExededMaxMedals: set @cur, CHRONOS_BOSS_MEDALS_MAX - (@BOSS_MEDALS - @dif); set @BOSS_MEDALS, CHRONOS_BOSS_MEDALS_MAX; @@ -287,18 +287,18 @@ OnInit: "Candy-Caned Anti-Grinch-Rifle 2020"; setarray $@chronos_2_medal$, "Eyepatch", "TopHat", "FunkyHat", "MushHat", "ShroomHat", "ChristmasElfHat", "FaceMask", "CaptainsHat", "TamOShanter", "BunnyEars", "PanHat", "PilotHat", - "CarbonGasMask", "GroovyHat", "JazzyHat", "AnniversaryHat", "ChicSantaHat", "ReadingGlasses", "EggshellHat", "Pipe", "ScarabArmlet", + "CarbonGasMask", "GroovyHat", "JazzyHat", "AnniversaryHat", "ChicSantaHat", "ReadingGlasses", "EggshellHat", "Pipe", "ScarabArmlet", "Scissors", "LeprechaunHead", "BlinkingEvil", "BlinkingEvilRed", "BlinkingEvilBlue", "BlinkingEvilPink", "BlinkingEvilYellow", "BlinkingHocus", "GoldenPlatemail", "Earmuffs"; setarray $@chronos_2_medal_n$, "Eyepatch", "Top Hat", "Funky Hat", "Mush Hat", "Shroom Hat", "Christmas Elf Hat", "Face Mask", "Captain's Hat", "Tam O' Shanter", "Bunny Ears", "Pan Hat", "Pilot Hat", - "Carbon Gas Mask", "Groovy Hat", "Jazzy Hat", "Anniversary Hat", "Chic Santa Hat", "Reading Glasses", "Eggshell Hat", "Smoking Pipe", "Scarab Armlet", + "Carbon Gas Mask", "Groovy Hat", "Jazzy Hat", "Anniversary Hat", "Chic Santa Hat", "Reading Glasses", "Eggshell Hat", "Smoking Pipe", "Scarab Armlet", "Scissors", "Leprechaun Head", "Mask of Blinking Evil (Green)", "Mask of Blinking Evil (Red)", "Mask of Blinking Evil (Blue)", "Mask of Blinking Evil (Pink)", "Mask of Blinking Evil (Yellow)", "Mask of Blinking Hocus", "Golden Platemail", "Earmuffs"; - setarray $@chronos_3_medal$, "BlinkingEvilHalloween", "MoonshroomHat", "WhiteEvokersRobeBlue", "BlackEvokersRobeBlue", "ApprenticeRobe", "GoldenWarlordPlate", "MageRing"; - setarray $@chronos_3_medal_n$, "Mask of Blinking Evil (Orange)", "Moonshroom Hat", "White Evoker's Robe (Blue)", "Black Evoker's Robe (Blue)", "Apprentice Robe", "Golden Warlord Plate", "Magic Ring"; + setarray $@chronos_3_medal$, "BlinkingEvilHalloween", "MoonshroomHat", "SunshroomHat", "WhiteEvokersRobeBlue", "BlackEvokersRobeBlue", "ApprenticeRobe", "GoldenWarlordPlate", "MagicRing", "Rainerang"; + setarray $@chronos_3_medal_n$, "Mask of Blinking Evil (Orange)", "Moonshroom Hat", "Sunshroom Hat", "White Evoker's Robe (Blue)", "Black Evoker's Robe (Blue)", "Apprentice Robe", "Golden Warlord Plate", "Magic Ring", "Rainerang"; - setarray $@chronos_4_medal$, "OverlordsHelmet", "DarkTalisman", "Aureole", "PaladinsHelmet", "EnchantersAmulet", + setarray $@chronos_4_medal$, "OverlordsHelmet", "DarkTalisman", "Aureole", "PaladinsHelmet", "EnchantersAmulet", "DragonShield", "HeartOfIsis", "BansheeBow", "BullHelmet", "AssassinShirt", "LazuriteRobe", "DarkHelm", "UnderworldMask", "Phylactery"; - setarray $@chronos_4_medal_n$, "Overlord's Helmet", "Dark Talisman", "Prsm Aura", "Paladin's Helmet", "Enchanter's Amulet", + setarray $@chronos_4_medal_n$, "Overlord's Helmet", "Dark Talisman", "Prsm Aura", "Paladin's Helmet", "Enchanter's Amulet", "Dragon Shield", "Heart of Isis", "Banshee Bow", "Bull Helmet", "Assassin Shirt", "Lazurite Robe", "Dark Helm", "Underworld Mask", "Phylactery"; end; } diff --git a/world/map/npc/099-8/mobs.txt b/world/map/npc/099-8/mobs.txt index b46efc08..c7c998a3 100644 --- a/world/map/npc/099-8/mobs.txt +++ b/world/map/npc/099-8/mobs.txt @@ -163,7 +163,7 @@ OnBoss: next; mes "##9The controls seems to have been destroyed!"; mes "##9The panel says the situtation is critical."; - mes "##9Why the final defensive measures didn't engage?"; + mes "##9Why didn't the final defensive measures engage?"; next; mes "What's happening?"; close; @@ -211,7 +211,7 @@ OnBoss: mes "##9The controls seems to have been destroyed!"; mes "##9I wonder where these three rooms are."; mes "##9What sort of research was being conducted?"; - mes "##9What is a Crystal Room? I don't saw any passage."; + mes "##9What is a Crystal Room? I didn't see any passage."; next; mes "What's happening?"; close; @@ -234,4 +234,3 @@ OnBoss: mes "What's happening?"; close; } - diff --git a/world/map/npc/annuals/2022.txt b/world/map/npc/annuals/2022.txt index 4752b137..d5595d48 100644 --- a/world/map/npc/annuals/2022.txt +++ b/world/map/npc/annuals/2022.txt @@ -88,6 +88,3 @@ OnInit: registercmd "#crcend", strnpcinfo(0)+"::OnEndEv"; end; } - - - diff --git a/world/map/npc/annuals/xmas/2020.txt b/world/map/npc/annuals/xmas/2020.txt index 0490d1a7..dc7a66d8 100644 --- a/world/map/npc/annuals/xmas/2020.txt +++ b/world/map/npc/annuals/xmas/2020.txt @@ -402,6 +402,10 @@ OnClock2124: OnClock0024: goto OnClock2359; */ + +OnInit: + set .IS_MAGIC, 1; + end; } @@ -832,4 +836,3 @@ OnNearbyNpc: set @nearby, @nearby + 1; end; } - diff --git a/world/map/npc/commands/_import.txt b/world/map/npc/commands/_import.txt index 6e2f0cc2..0b28a3ea 100644 --- a/world/map/npc/commands/_import.txt +++ b/world/map/npc/commands/_import.txt @@ -22,3 +22,4 @@ npc: npc/commands/divorce.txt npc: npc/commands/exp.txt npc: npc/commands/dailypoints.txt npc: npc/commands/mobpoints.txt +npc: npc/commands/labyrinth-reset.txt diff --git a/world/map/npc/commands/destroynpc.txt b/world/map/npc/commands/destroynpc.txt index 1ebede9e..552f9693 100644 --- a/world/map/npc/commands/destroynpc.txt +++ b/world/map/npc/commands/destroynpc.txt @@ -22,7 +22,7 @@ L_Confirm: end; L_Failed: - message strcharinfo(0), "destroynpc : Impossible to find the target npc. Did you try putting the name in \"quotation marks\"? Some npcs also have an invisible postfix in their name, ie `#_M`."; + message strcharinfo(0), "destroynpc : Impossible to find the target npc. Did you try putting the name in \"quotation marks\"? Some npcs also have an invisible postfix in their name, ie `#barrier`."; end; L_GM: diff --git a/world/map/npc/commands/hug.txt b/world/map/npc/commands/hug.txt index f97c81e4..af8bd6e1 100644 --- a/world/map/npc/commands/hug.txt +++ b/world/map/npc/commands/hug.txt @@ -18,8 +18,9 @@ close; OnInit: - set .tree_id, getnpcid("#DruidTree0#_M"); + set .tree_id, getnpcid("#DruidTree0"); registercmd "*hugs", strnpcinfo(0); // eq: /me hugs (target) registercmd "*hugs*", strnpcinfo(0); // eq: /me hugs + set .IS_MAGIC, 1; end; } diff --git a/world/map/npc/commands/labyrinth-reset.txt b/world/map/npc/commands/labyrinth-reset.txt new file mode 100644 index 00000000..e95eb3ee --- /dev/null +++ b/world/map/npc/commands/labyrinth-reset.txt @@ -0,0 +1,23 @@ +-|script|labyrinth-reset|32767 +{ + if (GM < 60) goto L_GM; + gmlog "(Labyrinth XP Chest state reset) @labyrinth-reset " + @args$; + wgm "labyrinth-reset : " + strcharinfo(0) + " invoked @labyrinth-reset (Labyrinth XP Chest state cleaner) " + @args$; + set .@i, 0; + goto L_CleanSlot; + +L_CleanSlot: + set $DD5A_EXPCHEST$[.@i], ""; + set .@i, (.@i + 1); + if (.@i > 99) message strcharinfo(0), "labyrinth-reset : complete!"; + if (.@i > 99) end; + goto L_CleanSlot; + +L_GM: + message strcharinfo(0), "labyrinth-reset : GM command is level 60, but you are level " + GM; + end; + +OnInit: + registercmd chr(ATCMD_SYMBOL) + "labyrinth-reset", strnpcinfo(0); + end; +} diff --git a/world/map/npc/functions/doomsday.txt b/world/map/npc/functions/doomsday.txt index bba08e75..2be517c3 100644 --- a/world/map/npc/functions/doomsday.txt +++ b/world/map/npc/functions/doomsday.txt @@ -979,7 +979,3 @@ OnDeathAct4: end; } - - - - diff --git a/world/map/npc/functions/global_event_handler.txt b/world/map/npc/functions/global_event_handler.txt index d169f3c7..dfc7966f 100644 --- a/world/map/npc/functions/global_event_handler.txt +++ b/world/map/npc/functions/global_event_handler.txt @@ -19,11 +19,14 @@ OnPCLoginEvent: callfunc "ConvertChristmas21"; // Christmas 2021 callfunc "VaultLogin"; // Mirror Lake Protocol biddings callfunc "VaultLogout"; // Clean some stuff, to be safe + if (WEIGHT_LIMIT) set MaxWeightOverride, WEIGHT_LIMIT; // If this char var set, override max weight (tradebots, etc) + if (PC_BOSS_REWARD) set @PC_BOSS_REWARD, PC_BOSS_REWARD; // Load tempvar from per-acct var (needed by maybe_reward_boss_kill) // add more here set @login_event, 2; end; OnPCKillEvent: + callfunc "maybe_reward_boss_kill"; callfunc "elanore_decrease_exp"; // decrease heal exp for doing bad things callfunc "SweetTooth"; end; @@ -45,7 +48,7 @@ OnPCDieEvent: end; OnPCLogoutEvent: -// if (getnpcid("#Upmarmu#" + getcharid(3)) >= 1) addnpctimer 0, "#Upmarmu#" + getcharid(3) + "::OnDestroy"; // @upmarmu_spell_npc_name$ is already lost at this point so it must be done like this + if (getnpcid("#Upmarmu#" + getcharid(3)) >= 1) addnpctimer 0, "#Upmarmu#" + getcharid(3) + "::OnDestroy"; // @upmarmu_spell_npc_name$ is already lost at this point so it must be done like this callfunc "VaultLogout"; end; @@ -58,3 +61,18 @@ OnDay0411: callfunc "MaybeAnnounceBirthday"; end; } + +// Inputs: nothing, but assumes RID attached and @victimrid set on PK kill +// Return: nothing, but adjusts BOSS_POINTS +// TODO: move this func somewhere else maybe? +function|script|maybe_reward_boss_kill +{ // not here or lacks reward for head -> skip rewarding. + if ((@victimrid < 1) || !(isloggedin(@victimrid)) || (get(@PC_BOSS_REWARD, @victimrid)) < 1) goto L_SkipReward; + set BOSS_POINTS, (BOSS_POINTS + get(@PC_BOSS_REWARD, @victimrid)); + message strcharinfo(0), "[boss reward] : you killed eventer-controlled boss and gained " + get(@PC_BOSS_REWARD, @victimrid) + + " boss points, for total of " + BOSS_POINTS + " boss points"; + return; + +L_SkipReward: + return; +} diff --git a/world/map/npc/functions/teleport_manager.txt b/world/map/npc/functions/teleport_manager.txt new file mode 100644 index 00000000..bb5441b6 --- /dev/null +++ b/world/map/npc/functions/teleport_manager.txt @@ -0,0 +1,547 @@ +// GateBuilders toolkit aka "arbitrary teleports". +// Author: Hello=). Credits go to Freeyorp and HoraK for some insights. + +// This lacks limits of previously existing teleport systems. +// * New teleports can be instatiated as needed, running side by side. +// * Teleports can have finite lifetime, disappearing themself. +// * Teleports can be removed, leaving no side effects. +// * No leftovers or side effects after teleport removed. +// * Up to about 100 teleports can coexist. +// * Flexible condition check based on cookie. If some gate got cookie set +// then it only lets players with matching variable to pass. +// * Aspects like timeout, FX and their timing, etc can be customized. +// * Teleports meant to be registered in TeleportManager. However, its +// possible to create "unmanaged" teleports (e.g. for spells). +// * In future it can allow custom hooks/checks on teleporters (planned) + +// Technically, TeleportManager NPC keeps teleports as array of integers. +// with structure .teleports[.index] = Teleport's NPC ID. +// Up to 100 teleports allowed (.index = 1..100, .index = 0 is unused). +// if .teleports[.index] = 0 -> empty/reusable slot. +// All teleport specific data stored in puppet NPC itself. +// Teleport NPCs are puppets of TeleportManager and inherit its code. + +// Attempt will be made to make it reasonably robust. That is, +// * Try to handle usage bugs/bogus data/etc. +// * No actions causing big server side fallouts. +// * No out of bounds, nonexistent NPC references, etc. + +// Teleports have the following variables (some are set on teleport_create) +// .srcmap$ - source map of teleport's npc +// .src_x - source map of teleport's npc, X coord +// .src_y - source map of teleport's npc, Y coord +// .dstmap$ - destination map of teleport's npc +// .dst_x - destination map of teleport's npc, X coord +// .dst_y - destination map of teleport's npc, Y coord +// .lifetime - teleport's lifetime, in ms. 0 = permanent (until server restart) +// .cookie - if set, only teleport players with teleport_cookie == NPC's .cookie +// .fx, - FX effect to play on teleport. +// .fx_time, - Time FX allowed to play before teleport actually happens. +// .IS_MANAGER - Indicates TeleportManager NPC. Puppets wouldnst have that. +// .managed - Indicates its teleport managed by TeleportManager. Its possible to +// create unmanaged teleports, e.g. transient teleports by spells. +// .teleport - Set to 1 to be able to distinguish teleport NPCs from other NPCs +// .info$ - Description, shown to user when clicking NPC +// .inactive - set to disable OnTouch reaction. Useful for staged shutdown or +// e.g. temporarily deactivating teleport for whatever reason. + +// Key functcions: teleport_add and teleport_del. Rest are "helpers". + +// Main NPC code, runs on both TeleportManager and teleport puppets. +// Do not rename NPC: functions below rely on NPC name. +-|script|TeleportManager|32767 +{ + message strcharinfo(0), .info$; // Display info about teleport, var allows message change. + end; + +// Manager code below - puppets dont use OnCmd* events +// Invoked when someone adds teleport via @teleportadd +OnCmdAdd: + if (call("teleport_access_check")) end; // Not allowed to use this. + set .@idx, call("teleport_find_slot", 0); // Try to find empty slot (containing 0) + if (.@idx <= 0) goto L_AddNoRoom; // No empty slots? NB: teleports[0] not used. + if (call ("teleportadd_parseargs") <= 0) goto L_AddArgsFail; // @VARs like @POS_X, @NAME$, etc set by teleportadd_parseargs() +// Create actual teleport NPC ------- src map - src x src y --- name - NPC ---- Sz Sz dst map - dst x - dst y -- time - cook managed? + set .@tp, call("teleport_create", getmap(), @POS_X, @POS_Y, @NAME$, @NPCSPRITE, 0, 0, @DSTMAP$, @DST_X, @DST_Y, @TIMEOUT, 0, 1); + if (.@tp <= 0) goto L_AddPuppetFail; // Has puppet() failed? + set .teleports[.@idx], .@tp; // Store NPC ID -> .teleports[.@idx] slot. Access safe: teleport_find_slot() == 1..100 + gmlog strcharinfo(0) + " accessed TeleportManager: @teleportadd " + @args$; + wgm strcharinfo(0) + " accessed TeleportManager: @teleportadd " + @args$; + message strcharinfo(0), "[TeleportManager] : Added: [" + .@idx + "] " + + (get(.srcmap$, .@tp)) + " " + (get(.src_x, .@tp)) + "," + (get(.src_y, .@tp)) + + " -> " + (get(.dstmap$, .@tp)) + " " + (get(.dst_x, .@tp)) + "," + (get(.dst_y, .@tp)) + + " lifetime:" + ((get(.lifetime, .@tp)) / 1000) + "s, Name:" + strnpcinfo(0, .@tp) + " (" + .@tp + ")"; + end; + +L_AddNoRoom: + message strcharinfo(0), "[TeleportManager] : Too many teleports open, max 100 tracked teleports"; + message strcharinfo(0), "[TeleportManager] : use @teleportlist to list and @teleportdel to remove some."; + end; + +L_AddArgsFail: + if (@DSTMAP$ != "help") message strcharinfo(0), "[TeleportManager] : try @teleportadd help or @teleporthelp"; + end; + +L_AddPuppetFail: + message strcharinfo(0), "[TeleportManager] : failed to add teleport, check params. Duplicate NPC name maybe?"; + end; + +// Invoked when someone removes teleport via @teleportdel +OnCmdDel: + if (call("teleport_access_check")) end; // Not allowed to use this. + callfunc "argv_splitter"; + if (@argv[0] <= 0) goto L_DelFail; + if (call("teleport_delete", @argv[0]) <= 0) goto L_DelNotFound; + message strcharinfo(0), "[TeleportManager] : requested teleport ID [" + @argv[0] + "] to terminate"; + gmlog strcharinfo(0) + " accessed TeleportManager: @teleportdel " + @args$; + wgm strcharinfo(0) + " accessed TeleportManager: @teleportdel " + @args$; + end; + +L_DelNotFound: + message strcharinfo(0), "[TeleportManager] : teleport ID [" + @argv[0] + "] not found."; + end; + +L_DelFail: + message strcharinfo(0), "[TeleportManager] : Bad parameters."; + callfunc("teleport_help_del"); + end; + +// Invoked when someone lists teleports via @teleportlist +OnCmdList: + if (call("teleport_access_check")) end; // Not allowed to use this. + callfunc("teleports_list"); + gmlog strcharinfo(0) + " accessed TeleportManager: @teleporlist" + @args$; + end; + +// Invoked when someone requests help via @teleporthelp +// (doesn't needs access checks - does nothing dangerous) +OnCmdHelp: + message strcharinfo(0), "[TeleportManager] : Commands: @teleportadd @teleportdel @teleportlist @teleporthelp"; + message strcharinfo(0), "[TeleportManager] : @teleportlist - display list of active teleports"; + callfunc("teleport_help_del"); + callfunc("teleport_help_add"); + end; + +// Puppets (teleportation pads) logic below. +// Invoked when player steps on npc. Manager NPC ignores this. +OnTouch: + if (.IS_MANAGER) end; // Manager NPC isnt teleport -> no interaction. + if (.inactive) end; // If gate deactivated -> no interaction. + if ((.cookie) && (teleport_cookie != .cookie)) goto L_CantPass; + set teleport_cookie, 0; // Clear teleport cookie of player on teleport use. + sc_start SC_SLOWMOVE, .fx_time+100, 100000; // Slow player temporarily to avoid movement VS warp DCs + addtimer .fx_time, strnpcinfo(0)+"::OnTeleport"; // time before teleporting away + misceffect .fx; // Default .fx set in teleport_add, other code can override it. + end; +L_CantPass: + message strcharinfo(0), .cantpass$; // NPC var allows to change message. + end; // "keyed" teleport and player didnt had proper cookie. + +// Teleportation timer event (attached to player). Queued by OnTouch. +OnTeleport: + warp .dstmap$, .dst_x, .dst_y; + end; + +// Invoked on timed teleport's NPC timer expired. +OnTeleportExpired: + set .inactive, 1; // Flag shutdown so OnTouch ignores incoming players. + addnpctimer (.fx_time + 1000), strnpcinfo(0)+"::OnTeleportShutdown"; // Give time to in-flight players to teleport. + end; + +// Does actual teleport shutdown. +OnTeleportShutdown: + void call("teleport_mgr_clean"); // Cleanups adequately both "managed" and "unmanaged" teleports. + if !(.IS_MANAGER) destroy; // Dont ever try to destroy manager npc. + end; + +OnInit: + set .IS_MANAGER, 1; // Only Manager NPC would have this, puppets wouldnt. + set .info$, "TeleportManager : This thing is unlike anything you've seen before"; // Manager's NPC message on click. + registercmd "@teleportadd", "TeleportManager::OnCmdAdd"; + registercmd "@teleportdel", "TeleportManager::OnCmdDel"; + registercmd "@teleportlist", "TeleportManager::OnCmdList"; + registercmd "@teleporthelp", "TeleportManager::OnCmdHelp"; + registercmd "@teleport", "TeleportManager::OnCmdHelp"; + end; +} + +// PUBLIC API. Creates requested teleport NPC. Arg 0..6 are like puppet(). +// This function designed to run in ANY context, whether RID attached or not. +// It creates puppet + setups all relevant data in created NPC. +// arg(0): Teleport's map. +// arg(1): Teleport's X +// arg(2): Teleport's Y +// arg(3): Teleport's NPC label +// arg(4): Teleport's NPC sprite ID +// arg(5): Teleport's X size +// arg(6): Teleport's Y size +// arg(7): Destination map name. +// arg(8): Destination X +// arg(9): Destination Y +// arg(10):Teleport lifetime ( > 0 or -1 = indefinite) +// arg(11):Teleport magic cookie, 0 = everyone allowed, otherwise checks match. +// arg(12):Whether teleport managed, 0 = unmanaged, != 0 means it is. +// Return: On success: NPC ID of teleport created. +// On failure: 0 if puppet failed, -1 if arg check failed. +function|script|teleport_create +{ + set .@map$, getarg(0, ""); // Get args (+failsafe defailts) + set .@x, getarg(1, -10); // Get args (+failsafe defailts) + set .@y, getarg(2, -10); // Get args (+failsafe defailts) + set .@name$, getarg(3, ""); // Get args (+failsafe defailts) + set .@sprite, getarg(4, -10); // Get args (+failsafe defailts) + set .@xsz, getarg(5, -10); // Get args (+failsafe defailts) + set .@ysz, getarg(6, -10); // Get args (+failsafe defailts) + set .@dstmap$, getarg(7, -10); // Get args (+failsafe defailts) + set .@dst_x, getarg(8, -10); // Get args (+failsafe defailts) + set .@dst_y, getarg(9, -10); // Get args (+failsafe defailts) + set .@lifetime, getarg(10, -10); // Get args (+failsafe defailts) + set .@cookie, getarg(11, -10); // Get args (+failsafe defailts) + set .@managed, getarg(12, -10); // Get args (+failsafe defailts) + set .@res, -1; // Validate what caller gave + if !(call("teleport_map_valid", .@map$ )) goto L_Fail; // Validate src map$ + if !(call("teleport_map_valid", .@dstmap$)) goto L_Fail; // Validate dst map$ + if ((.@x < 0) || (.@y < 0)) goto L_Fail; // SRC X/Y cant be < 0 + if ((.@dst_x < 0) || (.@dst_y < 0)) goto L_Fail; // DST X/Y cant be < 0 + if ((.@xsz < 0) || (.@ysz < 0)) goto L_Fail; // NPC X/Y size cant be <= 0 + if (.@name$ == "") goto L_Fail; // NPC name cant be empty + if (.@sprite <= 0) goto L_Fail; // NPC sprite cant be <= 0 + if (.@lifetime < -1 || (.@lifetime) == 0) goto L_Fail; // Lifetime either > 0 or -1 = infinite + if ((.@cookie < 0) || (.@managed < 0)) goto L_Fail; // Cookie and managed cant be < 0 + set .@res, puppet(.@map$, .@x, .@y, .@name$, .@sprite, .@xsz, .@ysz); // instatiate teleport NPC + if (.@res <= 0) goto L_Fail; + //NPC's var value NPC ID -- teleport defaults + set .srcmap$, .@map$, .@res; // set .srcmap$ of NPC + set .src_x, .@x, .@res; // set .src_x of NPC + set .src_y, .@y, .@res; // set .src_y of NPC + set .dstmap$, .@dstmap$, .@res; // set .dstmap$ of NPC + set .dst_x, .@dst_x, .@res; // set .dst_x of NPC + set .dst_y, .@dst_y, .@res; // set .dst_y of NPC + set .lifetime, .@lifetime, .@res; // set .lifetime of NPC + set .cookie, .@cookie, .@res; // set .cookie of NPC + set .fx, 41, .@res; // set default teleport FX + set .fx_time, 350, .@res; // set default FX time (warp delay) + set .managed, .@managed, .@res; // If > 0, npc managed by TeleportManager (unmanaged temp TPs can be e.g. spells) + set .teleport, 1, .@res; // All teleports created by teleport_create have this. + set .info$, "Teleport : strange structure of unknown origins", .@res; // Default on-click message. + set .cantpass$, "Teleport : structure seems to ignore you", .@res; // Default "can't pass" message. + // If timeout requested, set up teardown timer. + if (.@lifetime > 0) addnpctimer .@lifetime, .@name$+"::OnTeleportExpired"; + return .@res; + +L_Fail: + return .@res; +} + +// PUBLIC API. This function deletes teleport. +// This function designed to run in ANY context, whether RID attached or not. +// Teleport removed by NPC destroy + setting its .teleports[.index] = 0. +// Inputs: arg[0] is either slot index (1..100) or NPC ID to remove. +// Return: 1 on success, <= 0 on failure. +function|script|teleport_delete +{ + set .@npctodel, getarg(0, -1); // This is either slot # or NPC ID + if (.@npctodel <= 0) goto L_Error; + if (.@npctodel > 100) goto L_GotNpcId; // If > 100 assume its NPC ID, not slot. + set .@npctodel, call("teleport_get_slot_val", .@npctodel); // Get NPC id from teleport manager slot. + if (.@npctodel <= 0) goto L_Error; // Failed to get NPC ID? + goto L_GotNpcId; + +L_GotNpcId: + if !(get(.teleport, .@npctodel)) goto L_Error; // Sanity check its teleport NPC indeed + donpcevent strnpcinfo(0, .@npctodel)+"::OnTeleportShutdown"; // Request teleport NPC to perform shutdown. + return 1; + +L_Error: + return 0; +} + +// This function prints teleports known to TeleportManager. +// This function MUST run in player context with RID attached to send messages. +// Inputs: nothing, all data taken from TeleportManager NPC. +// Return: nothing, just prints info as it iterates manager's slots. +function|script|teleports_list +{ + set .@idx, 0; + freeloop 1; // Loops via 100 slots -> can time out. + message strcharinfo(0), "[TeleportManager] : ---- Active teleports ----"; + goto L_NextSlot; + +L_NextSlot: + set .@idx, (.@idx+1); + if (.@idx > 100) goto L_Done; // Iterated whole array. + set .@npc, call("teleport_get_slot_val", .@idx); + if (.@npc < 0) goto L_Error; // Abort iteration on error and report it. + if (.@npc > 0) goto L_PrintSlot; // Print slot data. + goto L_NextSlot; // .@npc == 0 // just iterate to next slot + +L_PrintSlot: + if !(get(.managed, .@npc)) goto L_Error; // Sanity check its really "managed teleport" NPC + // Display info about teleport, data taken from NPC. + message strcharinfo(0), "[TeleportManager] : [" + .@idx + "] " + + (get(.srcmap$, .@npc)) + " " + (get(.src_x, .@npc)) + "," + (get(.src_y, .@npc)) + + " -> " + (get(.dstmap$, .@npc)) + " " + (get(.dst_x, .@npc)) + "," + (get(.dst_y, .@npc)) + + " lifetime:" + ((get(.lifetime, .@npc)) / 1000) + "s, Name:" + strnpcinfo(0, .@npc) + " (" + .@npc + ")"; + goto L_NextSlot; + +L_Done: + freeloop 0; + message strcharinfo(0), "[TeleportManager] : ---- End ----"; + return; + +L_Error: + freeloop 0; + message strcharinfo(0), "[TeleportManager] : Error iterating TeleportManager slots (bug?!)"; + return; +} + +// This function finds slot in TeleportManager with given NPC ID. +// This function designed to run in ANY context, whether RID attached or not. +// Inputs: arg[0]: NPC ID to find, 0 means "find free slot", +// Return: slot index in 1..100 range if slot found, <= 0 on fail. +function|script|teleport_find_slot +{ + if (getarg(0) < 0) goto L_Fail; // Caller gave some crap? + set .@wanted, getarg(0); // NPC ID to find (or 0 to find free slot) + set .@manager, getnpcid("TeleportManager"); + if (.@manager <= 0) goto L_Fail; // Manager NPC not found? + set .@i, 1; // 0 slot not used. + freeloop 1; + goto L_TrySlot; // Start iterating via teleport slots on TeleportManager. + +L_TrySlot: + set .@npcid, get(.teleports[.@i], .@manager); + if (.@npcid == .@wanted) goto L_Found; //.teleports[.@i] == desired ID? + if (.@i > 100) goto L_Fail; // No free slots in teleports[1..100] + set .@i, (.@i + 1); goto L_TrySlot; // Try next slot + +L_Found: + freeloop 0; + return .@i; + +L_Fail: + freeloop 0; + return 0; +} + +// This function returns value in TeleportManager's slot with given indes. +// This function designed to run in ANY context, whether RID attached or not. +// Inputs: arg[0]: slot ID, must be 1 .. 100; +// Return: -1 on error, 0 on empty slot, or NPC ID of teleport in given sslot. +function|script|teleport_get_slot_val +{ + if ((getarg(0) < 1) || (getarg (0) > 100)) goto L_Fail; // Bogus index? + set .@index, getarg(0); + set .@manager, getnpcid("TeleportManager"); + if (.@manager <= 0) goto L_Fail; // Manager NPC not found? + set .@ret, get(.teleports[.@index], .@manager); + return .@ret; + +L_Fail: + return -1; +} + +// This function sets slot in TeleportManager with given value. +// This function designed to run in ANY context, whether RID attached or not. +// Inputs: arg[0]: slot ID, must be 1 .. 100; +// arg[1]: value to store to slot; +// Return: 1 on success, <= 0 on failure. +function|script|teleport_set_slot_val +{ + if ((getarg(0) < 1) || (getarg (0) > 100)) goto L_Fail; // Bogus index? + if (getarg(1) < 0) goto L_Fail; // TP slots are NPC ID or 0 for empty + set .@index, getarg(0); + set .@val, getarg(1); + set .@manager, getnpcid("TeleportManager"); + if (.@manager <= 0) goto L_Fail; // Manager NPC not found? + set .teleports[.@i], .@val, .@manager; + return 1; + +L_Fail: + return 0; +} + +// PRIVATE: This function cleans up slot in TeleportManager on teleport shutdown. +// This function ONLY meant to be invoked by teleport NPC puppet on shutdown! +// Inputs: nothing. Gets data from its calling NPC. +// Return: 1 on success, <= 0 on failure. +function|script|teleport_mgr_clean +{ + if !(.managed) goto L_RetOk; // Teleport not managed by TeleportManager -> no cleanup + set .@my_id, getnpcid(); + if (.@my_id <= 0) goto L_RetFail; // Give up on cleanup, slot will leak + // Call chaining OK: teleport_set_slot_val() checks slot # sanity, so teleport_find_slot() fail handled. + set .@res, call("teleport_set_slot_val", call("teleport_find_slot", .@my_id), 0); + if (.@res != 1) goto L_RetFail; + goto L_RetOk; +L_RetOk: + return 1; + +L_RetFail: + debugmes "teleport_mgr_clean: TeleportManager cleanup failure -> slot leak. Likely bug! .@my_id=" + .@my_id + ".@res=" + .@res; + return 0; +} + +// PRIVATE: This function validates @teleportadd args and prepares for teleport_add() call. +// This function MUST be invoked with player RID attached, by TeleportManager NPC +// Inputs: nothing, but assumes args$ set. +// Return: <= 0 on failure, 1 on success. +// Return: sets @POS_X, @POS_X, @DSTMAP$, @DST_X, @DST_Y, +function|script|teleportadd_parseargs +{ + callfunc "argv_splitter"; + set @DSTMAP$, @argv$[0]; // Destination map + set @DST_X, @argv[1]; // Dst warp coordinates + set @DST_Y, @argv[2]; // Dst warp coordinates + set @NAME$, @argv$[3]; // Teleport's label + set @TIMEOUT, @argv[4]; // Teleport's lifetime + set @NPCSPRITE, @argv[5]; // Teleport's NPC sprite (optional) + // Check DST map is okay + if ((@DSTMAP$ == "help") || (@DSTMAP$ == "")) goto L_DisplayHelp; // @teleportadd help or @teleportadd + if !(call("teleport_map_valid", @DSTMAP$)) goto L_FailBadmap; // DST: invalid map? + // Check DST X,Y sane + if ((@DST_X <= 0) || (@DST_Y <= 0)) goto L_FailBadDstXY1; // DST: invalids coords <= 0? + if ((getmapmaxx(@DSTMAP$) < @DST_X) || (getmapmaxy(@DSTMAP$) < @DST_Y)) goto L_FailBadDstXY2; // Outside of map? + // Check if DST is collision + if (iscollision(@DSTMAP$, @DST_X, @DST_Y)) goto L_FailDstCollide; + // Try adaptive NPC placement. Above caller if there's room or on caller if not. + set @POS_X, POS_X; + if ((POS_Y > 2) && !(iscollision(getmap(), POS_X, (POS_Y-2)))) set @POS_Y, (POS_Y - 2); + else set @POS_Y, POS_Y; // Overhead placement failed, use caller's tile + // NPC name checks + if (@NAME$ == "") goto L_FailNPCName; + // TIMEOUT checks and setup + if ((@TIMEOUT < -1) || (@TIMEOUT == 0) || (@TIMEOUT > 2000000)) goto L_FailTimeout; + if (@TIMEOUT > 0) set @TIMEOUT, (@TIMEOUT * 1000); // translate seconds -> ms to make more wieldy numbers + // NPC SPRITE configuration + if ((@NPCSPRITE != 424) && (@NPCSPRITE != 369) && (@NPCSPRITE != 368) + && (NPCSPRITE != 325) && (@NPCSPRITE != 324)) set @NPCSPRITE, 424; + // All checks complete + return 1; // Everything OK + +L_FailBadmap: + message strcharinfo(0), "[TeleportManager] : @teleportadd: unknown destination map:" + @DSTMAP$; + return -1; + +L_FailBadDstXY1: + message strcharinfo(0), "[TeleportManager] : @teleportadd: destination X,Y must be > 0! Given X=" + @DST_X + " Y=" + @DST_Y; + return -2; + +L_FailBadDstXY2: + message strcharinfo(0), "[TeleportManager] : @teleportadd: destination X,Y outside of map! Given X=" + @DST_X+ " Y=" + @DST_Y; + return -3; + +L_FailDstCollide: + message strcharinfo(0), "[TeleportManager] : @teleportadd: destination MAP=" + @DSTMAP$ + " X=" + @DST_X + " Y=" + @DST_Y + " is a collision (impassable)"; + return -4; + +L_FailNPCName: + message strcharinfo(0), "[TeleportManager] : @teleportadd: NPCNAME can't be empty!"; + return -5; + +L_FailTimeout: + message strcharinfo(0), "[TeleportManager] : @teleportadd: timeout must be either -1, or > 0 and < 2000000 (seconds)"; + return -6; + +L_DisplayHelp: + void call("teleport_help_add"); + return -7; +} + +// PUBLIC API: This function checks if map name known and OK to use. +// This function designed to run in any context. +// Inputs: arg$[0] is map name to check for sanity. +// Return: 1 for known maps, 0 for unknown +function|script|teleport_map_valid +{ + set .@inputmap$, getarg(0, ""); + set .@i, 0; + setarray .@maps1$, "001-1", "001-2", "001-3", "002-1", "002-2", "002-3", + "002-4", "002-5", "003-1", "003-4", "004-1", "004-3", + "004-4", "004-5", "005-3", "006-1", "006-2", "006-3", + "007-1", "007-2", "008-1", "009-1", "009-2", "009-3", + "009-4", "009-5", "009-6", "009-7", "009-8", "010-1", + "010-2", "011-1", "011-3", "011-4", "011-6", "012-1", + "012-3", "012-4", "013-1", "013-2", "013-3", "014-1", + "014-3", "015-1", "015-3", "016-1", "016-2", "017-1", + "017-2", "017-3", "017-4", "017-9", "018-1", "018-2", + "018-3", "019-1", "019-3", "019-4", "020-1", "020-2", + "020-3", "021-3", "023-1", "023-2", "023-3", "025-1", + "025-3", "025-4", "026-1", "026-2", "027-1", "027-2", + "027-3", "027-4", "027-5", "027-6", "027-7", "027-8", + "028-1", "028-3", "029-1", "029-2", "029-3", "029-4", + "030-1", "030-2", "030-3", "030-4", "031-1", "031-2", + "031-3", "031-4", "032-3", "033-1", "034-1", "034-2", + "035-2", "036-2", "041-1", "042-1", "043-1", "043-3", + "043-4", "045-1", "046-1", "046-3", "047-1", "047-3"; +// Had to split to 2 arrays as its too big for array initializer + setarray .@maps2$, "048-2", "051-1", "051-3", "052-1", "052-2", "055-1", + "055-3", "056-2", "057-1", "058-1", "058-2", "069-2", + "070-1", "070-3", "099-1", "099-2", "099-3", "099-4", + "099-5", "099-6", "099-7", "099-8", "botcheck"; + set .@arr_sz1, getarraysize(.@maps1$[0]); + set .@arr_sz2, getarraysize(.@maps2$[0]); + freeloop 1; // Needed to iterate over array of about 150 maps + goto L_NextMap; // Start iterating over array of maps. + +L_NextMap: + if (.@inputmap$ == .@maps1$[.@i]) goto L_Found; // Found map in arr 1? + if (.@inputmap$ == .@maps2$[.@i]) goto L_Found; // Found map in arr 2? + set .@i, (.@i + 1); // increment .@maps$[] index + if ((.@i >= .@arr_sz1) && (.@i >= .@arr_sz2)) goto L_NotFound; // Abort if whole arrays scanned + goto L_NextMap; // Try next map in .@maps$[] + +L_NotFound: + freeloop 0; + return 0; + +L_Found: + freeloop 0; + return 1; +} + +// PRIVATE: This function displays usage help for TeleportManager - @teleportadd +// This function should be invoked by TeleportManager with RID attached. +// Inputs: nothing. +// Return: nothing, just shows usage -> caller. +function|script|teleport_help_add +{ + message strcharinfo(0), "[TeleportManager] : @teleportadd <MAP> <X> <Y> <NPCNAME> <TIMEOUT> [sprite]"; + message strcharinfo(0), "[TeleportManager] : <MAP> <X> <Y>: teleport's destination map and coordinates"; + message strcharinfo(0), "[TeleportManager] : <NPCNAME>: name of NPC, unique and nonempty. If it stats with # its hidden"; + message strcharinfo(0), "[TeleportManager] : <TIMEOUT>: teleport lifetime (sec), < 2 000 000 sec, -1 = persistent"; + message strcharinfo(0), "[TeleportManager] : [sprite]: optional, NPC sprite (424,369,368,325 and 324 accepted)"; + message strcharinfo(0), "[TeleportManager] : Example: @teleportadd 009-1 52 39 Hurns -1 adds permanent teleport to Hurns menhir"; + message strcharinfo(0), "[TeleportManager] : Example: @teleportadd 009-1 52 39 Hurns 600 324 - same but 10 min, and red circle"; + return; +} + +// PRIVATE: This function displays usage help for TeleportManager - @teleportdel +// This function should be invoked by TeleportManager with RID attached. +// Inputs: nothing. +// Return: nothing, just shows usage -> caller. +function|script|teleport_help_del +{ + message strcharinfo(0), "[TeleportManager] : @teleportdel <ID>"; + message strcharinfo(0), "[TeleportManager] : ID either slot# (1..100) or teleport NPC ID"; + return; +} + +// Access checks for TeleportManager. Based on cut-down BossPowers checks. +function|script|teleport_access_check +{ + if ($BP_DISABLE) goto L_Killswitch; // If things go wrong, TeleportManager can be disabled. + if (#BP_DISABLE) goto L_Killswitch; // If someone abuses feature, there's _per-account_ DENY flag. + if (GM >= 40) goto L_Allowed; // GM >= 40 can use boss actions. + if (IS_EVENTER == 42) goto L_Allowed; // Trusted player(s) could be allowed to access Eventer "magic" +// if (debug) goto L_Allowed; // Allow on debug. + message strcharinfo(0), "[TeleportManager] : You can't use this feature at this time. Sorry. [1]"; + return 1; // Not allowed by default. + +L_Allowed: + return 0; // Whoever gets here allowed to invoke BossPowers spells + +L_Killswitch: + message strcharinfo(0), "[TeleportManager] : You can't use this feature at this time. Sorry. [2]"; + return 2; +} diff --git a/world/map/npc/items/anchor_stone.txt b/world/map/npc/items/anchor_stone.txt new file mode 100644 index 00000000..c1ea722b --- /dev/null +++ b/world/map/npc/items/anchor_stone.txt @@ -0,0 +1,56 @@ +function|script|useAnchorStone +{ + addtimer 0, "AS_Core::OnUse"; + return; +} + +-|script|AS_Core|32767 +{ + end; + +OnUse: + if ( @StoneName$ == "AnchorStone" ) goto L_AnchorStone; + if ( @StoneName$ == "AnchoredAnchorStone" ) goto L_AnchoredAnchorStone; + goto L_Close; + +L_AnchorStone: + mes "\"You really want to bind the [@@" + AnchorStone + "|@@] to this place?\""; + menu + "No", L_Close, + "Yes", L_AS_Yes; + +L_AS_Yes: + set AnchorStoneDest, getmaphash(getmap()); // since a hash could be negative I take a separate variable for that since shifting would destroy the sign bit and create a different hash + set AnchorStoneDestCoord, gety() << AS_Y_SHIFT | getx() << AS_X_SHIFT; + + delitem AnchorStone, 1; + getitem AnchoredAnchorStone, 1; + close; + +L_AnchoredAnchorStone: + if ((AnchorStoneDest < 1) && (AnchorStoneDest > -1)) goto L_AAS_Error; + mes "\"You want to recall to the place the [@@" + AnchoredAnchorStone + "|@@] is bound to?\""; + menu + "No", L_Close, + "Yes", L_AAS_Yes; + +L_AAS_Yes: + warp getmapnamefromhash(AnchorStoneDest), (AnchorStoneDestCoord & AS_X_MASK >> AS_X_SHIFT), (AnchorStoneDestCoord & AS_Y_MASK >> AS_Y_SHIFT); + + goto L_AAStoAS; + +L_AAS_Error: + mes "\"Something went wrong the [@@" + AnchoredAnchorStone + "|@@] lost its destination and turns back to normal.\""; + goto L_AAStoAS; + +L_AAStoAS: + set AnchorStoneDest, 0; + set AnchorStoneDestCoord, 0; + + delitem AnchoredAnchorStone, 1; + getitem AnchorStone, 1; + close; + +L_Close: + close; +} diff --git a/world/map/npc/items/magicring_item.txt b/world/map/npc/items/magicring_item.txt new file mode 100644 index 00000000..eeb1aee6 --- /dev/null +++ b/world/map/npc/items/magicring_item.txt @@ -0,0 +1,27 @@ +// Variables passed to this script: +// @slotId The slot in which the item would have been equipped in. This is passed automagically when called in an equip script. + +function|script|MagicRingItem +{ + + set @debug_mask, 65535; + set @debug_shift, 0; + set @mexp, ((MAGIC_EXPERIENCE & @debug_mask) >> @debug_shift); + + set @magicring_mexp_needed, 5404; + + if ( @mexp >= @magicring_mexp_needed ) + goto L_Return; + + message strcharinfo(0), "You are not experienced enough to use the Magic Ring."; + + // This is for debug + if (debug) + goto L_Return; + + callfunc "UnequipLater"; + goto L_Return; + +L_Return: + return; +} diff --git a/world/map/npc/items/manapearl_item.txt b/world/map/npc/items/manapearl_item.txt index 9c1f1c04..2d7ce428 100644 --- a/world/map/npc/items/manapearl_item.txt +++ b/world/map/npc/items/manapearl_item.txt @@ -15,7 +15,7 @@ function|script|ManaPearlItem if ( @mexp >= @manapearl_mexp_needed ) goto L_Return; - message strcharinfo(0), "You are not expirienced enough to keep up the mana flow that is needed to stay in resonance with the Mana Pearl."; + message strcharinfo(0), "You are not experienced enough to keep up the mana flow that is needed to stay in resonance with the Mana Pearl."; // This is for debug if (debug) diff --git a/world/map/npc/magic/_import.txt b/world/map/npc/magic/_import.txt index 4c5dc1ed..42f316fe 100644 --- a/world/map/npc/magic/_import.txt +++ b/world/map/npc/magic/_import.txt @@ -47,6 +47,8 @@ npc: npc/magic/level2-make-shirt.txt npc: npc/magic/level3-necromancy.txt npc: npc/magic/event-summon-managuardian.txt npc: npc/magic/event-summon-manatyrant.txt +//npc: npc/magic/event-summon-stonegolem.txt +//npc: npc/magic/event-summon-sunshroom.txt npc: npc/magic/event-boss-powerup-lifedrain.txt npc: npc/magic/event-boss-powerup-manadrain.txt npc: npc/magic/event-boss-powerup-poison.txt @@ -56,3 +58,5 @@ npc: npc/magic/event-boss-powerup-tothecrypt.txt npc: npc/magic/event-boss-powerup-disarm.txt npc: npc/magic/event-boss-powerup-grenades.txt npc: npc/magic/event-boss-powerup-headshot.txt +npc: npc/magic/event-boss-powerup-massslow.txt +npc: npc/magic/event-boss-powerup-flee.txt diff --git a/world/map/npc/magic/_procedures.txt b/world/map/npc/magic/_procedures.txt index 601d5b15..517373e2 100644 --- a/world/map/npc/magic/_procedures.txt +++ b/world/map/npc/magic/_procedures.txt @@ -94,50 +94,49 @@ L_Return: return 0; } - -// this function is call()-only // Custom version of checks for Dungeon Masters boss "powerups". // Both GMs and player eventers MAY eventually call "boss powerups". // By default, only GMs >= 40 can use BossPowers, but: -// - If someone abuses BossPowers, setting #BOSS_POWERS_DISABLED = 1 on them locks them out. -// - Some (trusted) player can be allowed to invoke this by setting #IS_EVENTER = 42 on them. +// - If someone abuses BossPowers, setting #BP_DISABLED = 1 on them locks them out. +// - Some (trusted) player can be allowed to invoke this by setting BP_EVENTER = 42 on them. // On TMWA these changes need GM Lv 80 to issue @setvar, so access can only be changed by Lv 80. // Advantage of this permissions system is: no need to shuffle GM levels, nor there's need to restart server. - function|script|boss_powerup_checks { - set .@flags, getarg(0); - set .@nonmagic, .@flags & (1<<0); - - if ($BOSS_KILLSWITCH) goto L_Killswitch; // If things go wrong, boss powers can be completely disabled. - if (#BOSS_POWERS_DISABLED) goto L_Killswitch; // If someone abuses BossPowers they can get DENY flag set. - if (HIDDEN) goto L_Hidden; // can not cast with @hide - if (@_M_BLOCK) goto L_Blocked; // check if last debuff ended - if (Hp < 1) goto L_Dead; // can not cast when dead - if (GM >= 40) goto L_Allowed; // GM >= 40 can use boss actions - if (#IS_EVENTER == 42) goto L_Allowed; // Trusted player(s) could be allowed to access Eventer "magic": - // Use @setvar #IS_EVENTER 0 42 Nick (GM Lv 80 command) to do it. + if (HIDDEN) goto L_Hidden; // can not cast with @hide + if (Hp < 1) goto L_Dead; // can not cast when dead + if (@_M_BLOCK) goto L_Blocked; // check if last debuff ended + if ($BP_DISABLE) goto L_Killswitch1; // If things go wrong, boss powers can be completely disabled. + if (#BP_DISABLE) goto L_Killswitch2; // If someone abuses BossPowers there's _per-account_ DENY flag. + if (GM >= 40) goto L_Allowed; // GM >= 40 can use boss actions. + if (IS_EVENTER == 42) goto L_Allowed; // Trusted player(s) could be allowed to access Eventer "magic": + // Use @setvar BP_EVENTER 0 42 Nick (GM Lv 80 command). smsg SMSG_FAILURE, "BossPowers: Only few of mere mortals may try to enter the twilight zone"; - return 1; // Not allowed by default. + return 1; // Not allowed by default. L_Allowed: - return 0; // Whoever gets here allowed to invoke BossPowers spells + return 0; // Whoever gets here allowed to invoke BossPowers spells -L_Killswitch: - smsg SMSG_FAILURE, "BossPowers: disabled by kill switch!"; +L_Dead: + smsg SMSG_FAILURE, "BossPowers: you're dead!"; return 2; L_Hidden: smsg SMSG_FAILURE, "BossPowers: can't be used when hidden!"; return 3; -L_Blocked: - smsg SMSG_FAILURE, "BossPowers: cooldown is in effect. Please wait."; +L_Killswitch1: + smsg SMSG_FAILURE, "BossPowers: unavailable at the moment (KillSwitch 1)"; return 4; -L_Dead: - smsg SMSG_FAILURE, "BossPowers: you're dead!"; +L_Killswitch2: + smsg SMSG_FAILURE, "BossPowers: unavailable at the moment (KillSwitch 2)"; return 5; + +L_Blocked: + smsg SMSG_FAILURE, "BossPowers: cooldown is in effect. Please wait."; + return 6; + } function|script|elt_damage @@ -286,3 +285,74 @@ function|script|gain_heal_xp L_Return: return 0; } + +// magic_activity should be called with player RID attached. +// This function used to keep track of magic activity. +function|script|magic_activity +{ + set CASTS, CASTS + 1; + if (CASTS < 0) set CASTS, 1; // overflow + return; +} + +// consume_sp must be called with player RID attached. +// Params: arg(0): amount of XP to consume. +// Return: 0 on success. On failure: nonzero + message to caster. +function|script|consume_sp +{ + if (getarg(0) <= 0) goto L_SpArgFail; // Usage bug? Function fails. + if (Sp < getarg(0)) goto L_NoSp; // Caster lacks enough Sp, fail. + set Sp, (Sp - getarg(0)); // Consume Sp and return success. + callfunc "magic_activity"; // Call activity here to unclutter spells. + return 0; + +L_NoSp: + message strcharinfo(0), "Magic : ##3##BNot enough Mana!"; + return 1; + +L_SpArgFail: + debugmes "bug: consume_sp needs arg(0) > 0"; + return 2; +} + +// spell_lv_checks helper must be called by spell NPC, with player RID attached. +// It expects "typical" spell NPC structure with .level ans .school +// Params: no args. Data taken from spell NPC. +// Return: 0 on success. On failure: nonzero + message to caster. +function|script|lvl_and_school_check +{ + if ((.level <= 0) || (.school <= 0)) goto L_LvCkFail; // Weird/missing school/level on NPC? + if (getskilllv(SKILL_MAGIC) < .level) goto L_LvCkReqs; // General magic < required level? + if (getskilllv(.school) < .level) goto L_LvCkReqs; // Magic school < required level? + return 0; // All checks passed -> success. + +L_LvCkReqs: + message strcharinfo(0), "Magic : ##3##BThis spell too hard for you yet."; + return 1; // User below spell requirements set on spell's NPC + +L_LvCkFail: + debugmes "bug: lvl_and_school_check needs .school and .level > 0 on spell NPC"; + return 2; // NPC bug or not called by spell NPC -> fail +} + +// magic_cooldown helper should be called with player RID attached. +// This function used to lock out spell. +// Input: arg0 - length of cooldown. +// Input: arg1 - optional: custom SC_COOLDOWN ID to use. +function|script|magic_block +{ + if (getarg(0) <= 0) goto L_Block_Fail; + set @_M_BLOCK, 1; // block casting, until the timer clears it + addtimer getarg(0), "Magic Timer::OnClear"; // Disable spell casting + if (getarg(1) > 0) goto L_CustomCool; // Custom cooldown ID given? + sc_start SC_COOLDOWN, getarg(0), 0, BL_ID; // If not -> default SC_COOLDOWN + return; + +L_CustomCool: + sc_start getarg(1), getarg(0), 0, BL_ID; // Apply custom cooldown. + return; + +L_Block_Fail: + debugmes "bug: magic_block needs arg(0) > 0"; + return; // Called wrong way -> spell bug. +} diff --git a/world/map/npc/magic/event-boss-powerup-flee.txt b/world/map/npc/magic/event-boss-powerup-flee.txt new file mode 100644 index 00000000..ee0e68a3 --- /dev/null +++ b/world/map/npc/magic/event-boss-powerup-flee.txt @@ -0,0 +1,94 @@ +// Opens transient teleport to allow boss to flee! +-|script|powerup-flee|32767 +{ + end; + +OnCast: + if (call("boss_powerup_checks")) end; + if (call("bossflee_parseargs")) goto L_EscPlanFail1; // @VARs like @POS_X set by bossflee_parseargs() +// Create actual teleport NPC ------- src map - src x src y --- name --- -NPC- Sz Sz dst map - dst x - dst y --time----cookie---managed? + set .@tp, call("teleport_create", getmap(), @POS_X, @POS_Y, "#bossflee", 324, 0, 0, @DSTMAP$, @DST_X, @DST_Y, 7000, 0xBADB055, 0); + if (.@tp <= 0) goto L_EscPlanFail2; // Has puppet() failed? + set .info$, "Teleport : Boss escapes!", .@tp; // on-click message. + set .cantpass$, "Teleport : somehow structure ignores you", .@tp; // "can't pass" message. + set teleport_cookie, 0xBADB055; // Allow caller (boss) to use teleport + mapannounce getmap(), strcharinfo(0)+" : Catch me, if you can!", 0; + end; + +L_EscPlanFail1: + message strcharinfo(0), "[#bossflee] : Escape plan status: fail! (bad destination?)"; + end; + +L_EscPlanFail2: + message strcharinfo(0), "[#bossflee] : Escape plan status: fail! (teleport creation failed)"; + end; + +// Puppet (teleportation pads) logic below. +// Invoked when player steps on npc. +OnTouch: + if ((.cookie) && (teleport_cookie != .cookie)) goto L_CantPass; + set teleport_cookie, 0; // Clear teleport cookie of player on teleport use. + sc_start SC_SLOWMOVE, .fx_time+100, 100000; // Slow player temporarily to avoid movement VS warp DCs + addtimer .fx_time, strnpcinfo(0)+"::OnTeleport"; // time before teleporting away + misceffect .fx; // Default .fx set in teleport_add, other code can override it. + end; + +L_CantPass: + message strcharinfo(0), .cantpass$; // NPC var allows to change message. + end; // "keyed" teleport and player didnt had proper cookie. + +// Teleportation timer event (attached to player). Queued by OnTouch. +OnTeleport: + warp .dstmap$, .dst_x, .dst_y; + end; + +// Invoked on timed teleport's NPC timer expired. +OnTeleportExpired: + destroy; + +OnInit: + set .invocation$, chr(MAGIC_SYMBOL) + "bossflee"; // used in npcs that refer to this spell + void call("magic_register", "OnCast"); + end; +} + +// Based on TeleportManager code - with +// This function MUST be invoked with player RID attached by powerup-flee +// Inputs: nothing, but assumes args$ set. +// Return: <= 0 on failure, 1 on success. +// Return: sets @POS_X, @POS_X, @DSTMAP$, @DST_X, @DST_Y, @NPCSPRITE, @TIMEOUT +function|script|bossflee_parseargs +{ + callfunc "argv_splitter"; + set @DSTMAP$, @argv$[0]; // Destination map + set @DST_X, @argv[1]; // Dst warp coordinates + set @DST_Y, @argv[2]; // Dst warp coordinates + // Check DST map is okay + if !(call("teleport_map_valid", @DSTMAP$)) goto L_FailBadmap; // DST: invalid map? + // Check DST X,Y sane + if ((@DST_X <= 0) || (@DST_Y <= 0)) goto L_FailBadDstXY1; // DST: invalids coords <= 0? + if ((getmapmaxx(@DSTMAP$) < @DST_X) || (getmapmaxy(@DSTMAP$) < @DST_Y)) goto L_FailBadDstXY2; // Outside of map? + // Check if DST is collision + if (iscollision(@DSTMAP$, @DST_X, @DST_Y)) goto L_FailDstCollide; + // Try adaptive NPC placement. Above caller if there's room or on caller if not. + set @POS_X, POS_X; + if ((POS_Y > 2) && !(iscollision(getmap(), POS_X, (POS_Y-2)))) set @POS_Y, (POS_Y - 2); + else set @POS_Y, POS_Y; // Overhead placement failed, use caller's tile + return 0; // Everything OK + +L_FailBadmap: + message strcharinfo(0), "[#bossflee] : unknown flee map:" + @DSTMAP$; + return 1; + +L_FailBadDstXY1: + message strcharinfo(0), "[#bossflee] : flee map X,Y must be > 0! Given X=" + @DST_X + " Y=" + @DST_Y; + return 2; + +L_FailBadDstXY2: + message strcharinfo(0), "[#bossflee] : flee map X,Y outside of map! Given X=" + @DST_X+ " Y=" + @DST_Y; + return 3; + +L_FailDstCollide: + message strcharinfo(0), "[#bossflee] : flee MAP=" + @DSTMAP$ + " X=" + @DST_X + " Y=" + @DST_Y + " is a collision (impassable)"; + return 4; +} diff --git a/world/map/npc/magic/event-boss-powerup-grenades.txt b/world/map/npc/magic/event-boss-powerup-grenades.txt index 0a692314..bf4d30c7 100644 --- a/world/map/npc/magic/event-boss-powerup-grenades.txt +++ b/world/map/npc/magic/event-boss-powerup-grenades.txt @@ -6,8 +6,8 @@ OnCast: if(call("boss_powerup_checks")) end; if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 16000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 16000, 0, BL_ID; + addtimer 12000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 12000, 0, BL_ID; misceffect FX_MEDIUM_EXPLOSION, strcharinfo(0); set @dist, 5; foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; @@ -22,6 +22,7 @@ OnHit: OnGrenadeHit: misceffect FX_MEDIUM_SMOKE, strcharinfo(0); + sc_start SC_SLOWMOVE, 2000, 900, @target_id; // Slow (almost stun) player temporarily heal (0 - rand(Hp)), 0; set Sp, (Sp / 3); end; diff --git a/world/map/npc/magic/event-boss-powerup-headshot.txt b/world/map/npc/magic/event-boss-powerup-headshot.txt index 5e3dc4f9..546ab32f 100644 --- a/world/map/npc/magic/event-boss-powerup-headshot.txt +++ b/world/map/npc/magic/event-boss-powerup-headshot.txt @@ -11,8 +11,8 @@ OnCast: if ((get(Hp, @target_id)) < 1) goto L_Too_dead; // Do not touch dead if (target(BL_ID, @target_id, 0x20) != 0x20) goto L_No_los; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 16000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 16000, 0, BL_ID; + addtimer 10000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 10000, 0, BL_ID; misceffect FX_MEDIUM_EXPLOSION, strcharinfo(0); misceffect FX_CHANNELLING_CAST_RED, @target_id; @@ -20,6 +20,7 @@ OnCast: set Sp, 1, @target_id; // Hurt target if (@tgthp < 1500) set @tgthp, 1; // Boss or not? (>3000 HP) set Hp, @tgthp, @target_id; // Hurt target + sc_start SC_SLOWMOVE, 3000, 5000; // Slow player temporarily message strcharinfo(0, @target_id), "[boss-headshot] : "+strcharinfo(0, BL_ID)+" shot you!"; set @tgthp, 0; end; diff --git a/world/map/npc/magic/event-boss-powerup-lifedrain.txt b/world/map/npc/magic/event-boss-powerup-lifedrain.txt index 5399ea37..aa4e7181 100644 --- a/world/map/npc/magic/event-boss-powerup-lifedrain.txt +++ b/world/map/npc/magic/event-boss-powerup-lifedrain.txt @@ -6,8 +6,8 @@ OnCast: if(call("boss_powerup_checks")) end; if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 30000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 30000, 0, BL_ID; + addtimer 12000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 12000, 0, BL_ID; misceffect FX_PENTAGRAM_BURST, strcharinfo(0); set @dist, 12; foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; diff --git a/world/map/npc/magic/event-boss-powerup-manadrain.txt b/world/map/npc/magic/event-boss-powerup-manadrain.txt index b6f7f835..8c42bde9 100644 --- a/world/map/npc/magic/event-boss-powerup-manadrain.txt +++ b/world/map/npc/magic/event-boss-powerup-manadrain.txt @@ -6,8 +6,8 @@ OnCast: if(call("boss_powerup_checks")) end; if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 20000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 20000, 0, BL_ID; + addtimer 12000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 12000, 0, BL_ID; misceffect FX_CHANNELLING_CAST_BLUE, strcharinfo(0); set @dist, 16; foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; diff --git a/world/map/npc/magic/event-boss-powerup-massslow.txt b/world/map/npc/magic/event-boss-powerup-massslow.txt new file mode 100644 index 00000000..6c10cfa3 --- /dev/null +++ b/world/map/npc/magic/event-boss-powerup-massslow.txt @@ -0,0 +1,35 @@ +-|script|powerup-massslow|32767 +{ + end; + +OnCast: + if(call("boss_powerup_checks")) end; + if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; + set @_M_BLOCK, 1; // block casting, until the timer clears it + addtimer 10000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 10000, 0, BL_ID; + misceffect FX_PENTAGRAM_BURST, strcharinfo(0); + set @dist, 12; + foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; + end; + +OnHit: + if (@target_id == BL_ID) end; // Do not slow caster + if (get(Hp, @target_id) <= 0) end; // Dont slow dead. + message strcharinfo(0, @target_id), "[boss-massslow] : "+strcharinfo(0, BL_ID)+" cast slow spell on you!"; + misceffect 23, strcharinfo(0, @target_id); // Show slow effect + sc_start SC_SLOWMOVE, 5000, 300, @target_id; // Slow player temporarily + end; + +L_Fail_town: + message strcharinfo(0), "[boss-massslow] : city protected by strong magic, your spell dissipates"; + end; + +OnInit: + set .school, SKILL_MAGIC; + set .invocation$, chr(MAGIC_SYMBOL) + "mapmassslow"; // used in npcs that refer to this spell + void call("magic_register", "OnCast"); + set .level, 0; + set .exp_gain, 0; + end; +} diff --git a/world/map/npc/magic/event-boss-powerup-poison.txt b/world/map/npc/magic/event-boss-powerup-poison.txt index a37f5aa9..777930c1 100644 --- a/world/map/npc/magic/event-boss-powerup-poison.txt +++ b/world/map/npc/magic/event-boss-powerup-poison.txt @@ -6,8 +6,8 @@ OnCast: if (call("boss_powerup_checks")) end; if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 16000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 16000, 0, BL_ID; + addtimer 10000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 10000, 0, BL_ID; misceffect FX_MAGIC_SNAKE_CAST, strcharinfo(0); set @dist, 12; foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; diff --git a/world/map/npc/magic/event-boss-powerup-tormenta.txt b/world/map/npc/magic/event-boss-powerup-tormenta.txt index 52e6f42f..a5b47fdf 100644 --- a/world/map/npc/magic/event-boss-powerup-tormenta.txt +++ b/world/map/npc/magic/event-boss-powerup-tormenta.txt @@ -6,6 +6,7 @@ OnCast: if(call("boss_powerup_checks")) end; bonus bMaxHP, 20000; set Hp, (Hp+20000), BL_ID; + set @oldclass, get(Class, BL_ID); set Class, 1137, BL_ID; warp getmap(), POS_X, POS_Y; // Refresh witch appearance addtimer 1500, strnpcinfo(0)+"::OnFix"; @@ -23,9 +24,11 @@ OnFix: L_done: message strcharinfo(0, BL_ID), "[boss-tormenta] : Tormenta impersonation ended!"; set @fix_count, 0; - set Class, 0, BL_ID; + set Class, @oldclass, BL_ID; bonus bMaxHP, 0; set Hp, 100, BL_ID; + sc_start SC_SLOWMOVE, 500, 10000; // Slow player temporarily to avoid movement VS warp DCs + warp getmap(), POS_X, POS_Y; // warp (under char's RID!) end; OnInit: diff --git a/world/map/npc/magic/event-boss-powerup-totheabyss.txt b/world/map/npc/magic/event-boss-powerup-totheabyss.txt index d215db8b..c271a260 100644 --- a/world/map/npc/magic/event-boss-powerup-totheabyss.txt +++ b/world/map/npc/magic/event-boss-powerup-totheabyss.txt @@ -9,8 +9,8 @@ OnCast: if (call("boss_powerup_checks")) end; if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 60000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 60000, 0, BL_ID; + addtimer 30000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 30000, 0, BL_ID; misceffect FX_RED_MAGIC_CAST, strcharinfo(0); set @dist, 25; foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; @@ -18,24 +18,25 @@ OnCast: OnHit: if ((get(Hp, @target_id)) < 1) end; // Do not touch dead - set Sp, 1, @target_id; // Hurt target - set Hp, min(((Hp/2)), 100), @target_id; // Hurt target - sc_start SC_POISON, 1, 10, @target_id; // Poison target message strcharinfo(0, @target_id), "[boss-to-the-abyss] : "+strcharinfo(0, BL_ID)+" ##B PULLS YOU TO THE ABYSS!!"; misceffect FX_RED_MAGIC_CAST, strcharinfo(0, @target_id); - addtimer 1000, strnpcinfo(0)+"::OnTeleport", @target_id; + sc_start SC_SLOWMOVE, 6000, 10000; // Slow player temporarily to avoid movement VS warp DCs + addtimer 500+rand(500), strnpcinfo(0)+"::OnTeleport", @target_id; end; // Runs attached to player, beware. Dont try access vars from former code! OnTeleport: warp "070-3", 40+rand(5), 25+rand(5); // warp (under char's RID!) - addtimer 1500, strnpcinfo(0)+"::OnArrival"; // To play FX after player's arrival -> map + set Sp, 1; // Hurt target + set Hp, (Hp/4); // Hurt target + sc_start SC_POISON, 1, 10; // Poison target + addtimer 1000, strnpcinfo(0)+"::OnArrival"; // To play FX after player's arrival -> map end; // Done. // Runs attached to player, beware. Dont try access vars from former code! OnArrival: misceffect 50, strcharinfo(0); // Unfortunately hell glow lacks const. - addtimer 15000, strnpcinfo(0)+"::OnClean"; // To cancel former "infinite" FX. + addtimer 2800, strnpcinfo(0)+"::OnClean"; // To cancel former "infinite" FX. end; // Done. // Runs attached to player, beware. Dont try access vars from former code! diff --git a/world/map/npc/magic/event-boss-powerup-tothecrypt.txt b/world/map/npc/magic/event-boss-powerup-tothecrypt.txt index 8ae4b3b6..cf189fb4 100644 --- a/world/map/npc/magic/event-boss-powerup-tothecrypt.txt +++ b/world/map/npc/magic/event-boss-powerup-tothecrypt.txt @@ -9,8 +9,8 @@ OnCast: if (call("boss_powerup_checks")) end; if (getmapflag(getmap(), MF_TOWN)) goto L_Fail_town; set @_M_BLOCK, 1; // block casting, until the timer clears it - addtimer 60000, "Magic Timer::OnClear"; // set the new debuff - sc_start SC_COOLDOWN, 60000, 0, BL_ID; + addtimer 30000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 30000, 0, BL_ID; misceffect FX_BLUE_MAGIC_CAST, strcharinfo(0); set @dist, 25; foreach 0, getmap(), (POS_X - @dist), (POS_Y - @dist), (POS_X + @dist), (POS_Y + @dist), strnpcinfo(0) + "::OnHit"; @@ -19,23 +19,24 @@ OnCast: OnHit: if ((get(Hp, @target_id)) < 1) end; // Do not touch dead set Sp, 1, @target_id; // Hurt target - set Hp, min(((Hp/2)), 100), @target_id; // Hurt target + set Hp, (Hp/4), @target_id; // Hurt target sc_start SC_POISON, 1, 10, @target_id; // Poison target message strcharinfo(0, @target_id), "[boss-to-the-crypt] : "+strcharinfo(0, BL_ID)+" ##B PULLS YOU TO THE CRYPT!!"; misceffect FX_CHANNELLING_RAISE, strcharinfo(0, @target_id); - addtimer 1000, strnpcinfo(0)+"::OnTeleport", @target_id; + sc_start SC_SLOWMOVE, 6000, 10000; // Slow player temporarily to avoid movement VS warp DCs + addtimer 500+rand(500), strnpcinfo(0)+"::OnTeleport", @target_id; end; // Runs attached to player, beware. Dont try access vars from former code! OnTeleport: warp "027-5", 71+rand(3), 51+rand(3); // warp (under char's RID!) - addtimer 1500, strnpcinfo(0)+"::OnArrival"; // To play FX after player's arrival -> map + addtimer 1000, strnpcinfo(0)+"::OnArrival"; // To play FX after player's arrival -> map end; // Done. // Runs attached to player, beware. Dont try access vars from former code! OnArrival: misceffect 50, strcharinfo(0); // Unfortunately hell glow lacks const. - addtimer 15000, strnpcinfo(0)+"::OnClean"; // To cancel former "infinite" FX. + addtimer 2800, strnpcinfo(0)+"::OnClean"; // To cancel former "infinite" FX. end; // Done. // Runs attached to player, beware. Dont try access vars from former code! diff --git a/world/map/npc/magic/event-summon-managuardian.txt b/world/map/npc/magic/event-summon-managuardian.txt index e66c3eb7..1aa172ad 100644 --- a/world/map/npc/magic/event-summon-managuardian.txt +++ b/world/map/npc/magic/event-summon-managuardian.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; // FIXME: Incomplete check, should still work during sieges - if (getmapflag(getmap(), MF_TOWN)) end; if (Sp < 100) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (countitem("TinyManaElixir") < 1) end; diff --git a/world/map/npc/magic/event-summon-manatyrant.txt b/world/map/npc/magic/event-summon-manatyrant.txt index bf2634c5..ff082930 100644 --- a/world/map/npc/magic/event-summon-manatyrant.txt +++ b/world/map/npc/magic/event-summon-manatyrant.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if ($DOOMSDAY_SUMMON < 2) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (Sp < 100) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (countitem("LargeManaElixir") < 1) end; diff --git a/world/map/npc/magic/event-summon-stonegolem.txt b/world/map/npc/magic/event-summon-stonegolem.txt new file mode 100644 index 00000000..873f4c1c --- /dev/null +++ b/world/map/npc/magic/event-summon-stonegolem.txt @@ -0,0 +1,75 @@ +-|script|summon-sgolem|32767 +{ + end; + +OnCast: + if(call("magic_checks")) end; + // FIXME: Incomplete check, should still work during sieges + if (getmapflag(getmap(), MF_TOWN)) end; + if (Sp < 100) end; + if (getskilllv(SKILL_MAGIC) < .level) end; + if (countitem("Stone") < 5) end; +// if (!$DOOMSDAY_SUMMON) end; +// if (@ddcooldown > gettimetick(2)) goto L_Cooldown; + if (sc_check(SC_COOLDOWN_SG)) goto L_Cooldown; + if (getmap() == "033-1") goto L_SpecialRules6; + goto L_Pay; + +L_Pay: + delitem "Stone", 5; + set @_M_BLOCK, 1; // block casting, until the timer clears it + addtimer 15000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 15000, 0, BL_ID; + callfunc "adjust_spellpower"; + set Sp, Sp - 100; + set CASTS, CASTS + 1; + if (CASTS < 0) set CASTS, 1; // overflow + misceffect FX_MAGIC_MAGGOT_CAST, strcharinfo(0); + callfunc "magic_exp"; + set .@puppet$, "#"+strnpcinfo(0)+"#"+BL_ID; + set .@puppet, puppet(getmap(), POS_X, POS_Y, .@puppet$, 127); + if (.@puppet < 1) end; + set .master, BL_ID, .@puppet; + set .lifetime, (@spellpower*9)+60000, .@puppet; +// set @ddcooldown, gettimetick(2)+70; // This is measured in seconds + sc_start SC_COOLDOWN_SG, (@spellpower*9)+70000, 0, BL_ID; // .lifetime + OnSummon + addnpctimer 10000, .@puppet$+"::OnSummon"; + addnpctimer 11000, .@puppet$+"::OnDestroy"; + end; + +OnSummon: + if (!(isloggedin(.master))) destroy; + if(get(Hp, .master) < 1) destroy; // destroy if master is missing + if(getmap(.master) != strnpcinfo(3)) destroy; // destroy if master left the map + specialeffect FX_MAGIC_MAGGOT_SPAWN; + set .@x, getnpcx(); + set .@y, getnpcy(); + set .@map$, strnpcinfo(3); + callsub S_SummonAll; + end; + +OnDestroy: + destroy; + +S_SummonAll: + summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Stone Golem Summon", StoneGolem, 2, .lifetime; + destroy; + +L_Cooldown: + message strcharinfo(0), "This skill is in forced cooldown; Please wait your first summon to expire."; + end; + +L_SpecialRules6: + if ($@KIMARR_EVENT < 1) goto L_Pay; + if ($@Fluffy_FighterID == BL_ID) goto L_Pay; + message strcharinfo(0), "You can't summon here unless hunting fluffies."; + end; + +OnInit: + set .school, SKILL_MAGIC_ASTRAL; + set .invocation$, chr(MAGIC_SYMBOL) + "stogolis"; // used in npcs that refer to this spell + void call("magic_register", "OnCast"); + set .level, 1; + set .exp_gain, 1; + end; +} diff --git a/world/map/npc/magic/event-summon-sunshroom.txt b/world/map/npc/magic/event-summon-sunshroom.txt new file mode 100644 index 00000000..6c01c1c8 --- /dev/null +++ b/world/map/npc/magic/event-summon-sunshroom.txt @@ -0,0 +1,71 @@ +-|script|smsunmushrooms|32767 +{ + end; + +OnCast: + if(call("magic_checks")) end; + if (Sp < 66) end; + if (getmapflag(getmap(), MF_TOWN)) end; + if (getskilllv(SKILL_MAGIC) < .level) end; + if (getskilllv(.school) < .level) end; + if (countitem("SmallMushroom") < 1 || countitem("Root") < 1) end; + if (getmap() == "033-1") goto L_SpecialRules6; + goto L_Pay; + +L_Pay: + delitem "SmallMushroom", 1; + delitem "Root", 1; + set @_M_BLOCK, 1; // block casting, until the timer clears it + addtimer 20000, "Magic Timer::OnClear"; // set the new debuff + sc_start SC_COOLDOWN, 20000, 0, BL_ID; + callfunc "adjust_spellpower"; + set Sp, Sp - 33; + set CASTS, CASTS + 1; + if (CASTS < 0) set CASTS, 1; // overflow + misceffect FX_MAGIC_SPIKY_CAST, strcharinfo(0); + callfunc "magic_exp"; + set .@puppet$, "#"+strnpcinfo(0)+"#"+BL_ID; + set .@puppet, puppet(getmap(), POS_X, POS_Y, .@puppet$, 127); + if (.@puppet < 1) end; + set .count, (@spellpower/120)+1, .@puppet; + set .master, BL_ID, .@puppet; + set .lifetime, @spellpower*400, .@puppet; + addnpctimer 5000-(@spellpower*9), .@puppet$+"::OnSummon"; + addnpctimer 6000, .@puppet$+"::OnDestroy"; + end; + +OnSummon: + if (!(isloggedin(.master))) destroy; + if(get(Hp, .master) < 1) destroy; // destroy if master is missing + if(getmap(.master) != strnpcinfo(3)) destroy; // destroy if master left the map + specialeffect FX_MAGIC_SPIKY_SPAWN; + set .@i, 0; + set .@x, getnpcx(); + set .@y, getnpcy(); + set .@map$, strnpcinfo(3); + callsub S_SummonAll; + end; + +OnDestroy: + destroy; + +S_SummonAll: + summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Sunshroom Summon", Sunshroom, 2, .lifetime; + set .@i, .@i + 1; + if (.@i < .count) goto S_SummonAll; + destroy; + +L_SpecialRules6: + if ($@KIMARR_EVENT < 1) goto L_Pay; + if ($@Fluffy_FighterID == BL_ID) goto L_Pay; + message strcharinfo(0), "You can't summon here unless hunting fluffies."; + end; + +OnInit: + set .school, SKILL_MAGIC_ASTRAL; + set .invocation$, chr(MAGIC_SYMBOL) + "kalsun"; // used in npcs that refer to this spell + void call("magic_register", "OnCast"); + set .level, 2; + set .exp_gain, 1; + end; +} diff --git a/world/map/npc/magic/level1-detect-magic.txt b/world/map/npc/magic/level1-detect-magic.txt index 33597d02..420b457c 100644 --- a/world/map/npc/magic/level1-detect-magic.txt +++ b/world/map/npc/magic/level1-detect-magic.txt @@ -12,6 +12,9 @@ if (CASTS < 0) set CASTS, 1; // overflow misceffect FX_MAGIC_DETECT_CAST, strcharinfo(0); set .@range, (@spellpower/50)+1; + set .caster, getcharid(3); + foreach 0, getmap(), POS_X - .@range, POS_Y - .@range, POS_X + .@range, POS_Y + .@range, + strnpcinfo(0) + "::OnNearbyPlayer"; foreach 1, getmap(), POS_X - .@range, POS_Y - .@range, POS_X + .@range, POS_Y + .@range, strnpcinfo(0) + "::OnNearbyNpc"; if (getmap() == "099-4") @@ -21,9 +24,17 @@ callfunc "magic_exp"; end; +OnNearbyPlayer: + if (@target_id == BL_ID) end; // Dont do lookups on caster. + if (sc_check(SC_HIDE, @target_id)) end; // Also skip hidden (anwiltyp) players. + if (attachrid(@target_id) < 1) end; // Switch context -> found player (to look up focused skills) + if (call("is_magician")) misceffect FX_MAGIC_DETECT_HIT, BL_ID; // BL_ID because now attached to target + if (attachrid(.caster) < 1) end; // Try to reattach back -> caster (is it needed?) + end; + OnNearbyNpc: set .@e$, strnpcinfo(2,@target_id); - if(.@e$ == "#_M" || .@e$ == "#MAGIC" || get(.IS_MAGIC, @target_id)) + if(.@e$ == "#_M" || .@e$ == "#MAGIC" || get(.IS_MAGIC, @target_id)) //#_M and #MAGIC can be used for problematic situations, like shops misceffect FX_MAGIC_DETECT_HIT, @target_id; end; @@ -35,3 +46,23 @@ OnInit: set .exp_gain, 0; end; } + +// This function tests if current RID is a magician (Astral soul skill Lv 9). +function|script|is_magician +{ + getactivatedpoolskilllist; + if (@skilllist_count != 0) goto L_iterate_focused; // Had some focused skills -> look further + goto L_focus_notfound; // No focused skills at all -> bail out. + +L_iterate_focused: + set @skilllist_count, @skilllist_count-1; + if ((@skilllist_id[@skilllist_count] == SKILL_ASTRAL_SOUL) && (getskilllv(SKILL_ASTRAL_SOUL) >= 2)) goto L_focus_found; + if (@skilllist_count == 0) goto L_focus_notfound; + goto L_iterate_focused; // iterate via array of focused skills. + +L_focus_found: + return 1; + +L_focus_notfound: + return 0; +} diff --git a/world/map/npc/magic/level1-summon-maggots.txt b/world/map/npc/magic/level1-summon-maggots.txt index 05cadbc8..ce95422c 100644 --- a/world/map/npc/magic/level1-summon-maggots.txt +++ b/world/map/npc/magic/level1-summon-maggots.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 21) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (countitem("InsectSlime") < 1 || countitem("Root") < 1) end; if (getmap() == "033-1") goto L_SpecialRules6; diff --git a/world/map/npc/magic/level2-magic-knuckles.txt b/world/map/npc/magic/level2-magic-knuckles.txt index a67941cf..92ee07a5 100644 --- a/world/map/npc/magic/level2-magic-knuckles.txt +++ b/world/map/npc/magic/level2-magic-knuckles.txt @@ -1,7 +1,7 @@ -|script|magic-knuckles|32767 { if @_U_BLOCK >= 1 goto L_Still_Exhausted; -/* + set @upmarmu_spell_npc_name$, "#Upmarmu#" + getcharid(3); // make a unique puppet name for every player set .upmarmu_spell_npc, getnpcid(@upmarmu_spell_npc_name$); if ( .upmarmu_spell_npc >= 1 ) goto L_NPC_Exists; // if this npc already exist reuse it so that idle recovery timer does not get destroyed @@ -12,7 +12,6 @@ goto L_NPC_Exists; L_NPC_Exists: -*/ if (call("magic_checks")) end; if (Sp < 20) end; if (getskilllv(SKILL_MAGIC) < .level) end; @@ -49,35 +48,29 @@ OnAttack: if (target(BL_ID, @target_id, 22) != 22) goto L_FreeRecast; // 0x10 | 0x02 | 0x04 void call("elt_damage", @upmarmuspell[0], (@upmarmuspell[3] + @upmarmuspell[4]), ELT_WATER, ELT_FIRE, FX_NONE); -// addtimer 0, @upmarmu_spell_npc_name$ + "::OnResetTimer"; + addtimer 0, @upmarmu_spell_npc_name$ + "::OnResetTimer"; set @upmarmuspell[1], @upmarmuspell[1] - 1; + + if @num_upmarmu_hits >= UPMARMU_HITS_TILL_EXHAUST goto L_FreeRecast; set @num_upmarmu_hits, @num_upmarmu_hits + 1; + if @num_upmarmu_hits >= UPMARMU_HITS_TILL_EXHAUST set .exhausted, 1, .upmarmu_spell_npc; - if @num_upmarmu_hits >= UPMARMU_HITS_TILL_EXHAUST goto L_Exhausted; goto L_FreeRecast; L_FreeRecast: if (@upmarmuspell[1] > 0) addtimer 0, strnpcinfo(0) + "::OnSetRecast"; + else + addtimer 0, @upmarmu_spell_npc_name$ + "::OnExhausted"; end; -L_Exhausted: - set @_U_BLOCK, 1; - set @upmarmuspell[1], 0; - misceffect FX_MAGIC_DISCHARGE, strcharinfo(0); - overrideattack; - addtimer UPMARMU_EXHAUST_DURATION, "Upmarmu Exhaust Timer::OnClear"; // set the exhaustion time - sc_start SC_COOLDOWN_UPMARMU, UPMARMU_EXHAUST_DURATION, 0, BL_ID; - smsg SMSG_FAILURE, "Magic: You are too exhausted to use this spell for a while!"; - goto L_StopTimer; - L_Still_Exhausted: smsg SMSG_FAILURE, "Magic: You are still too exhausted to use this spell for a while!"; end; L_StopTimer: -// addtimer 0, @upmarmu_spell_npc_name$ + "::OnStopTimer"; + addtimer 0, @upmarmu_spell_npc_name$ + "::OnStopTimer"; end; OnDischarge: @@ -91,7 +84,6 @@ OnSetRecast: overrideattack (@upmarmuspell[2] * @upmarmuspell[2]), 1, ATTACK_ICON_GENERIC, OVERRIDE_KNUCKLES, strnpcinfo(0)+"::OnAttack", @upmarmuspell[1]; // delay needs to be squared end; -/* OnResetTimer: // This timer is if you stopped somewhere below max hits then after 25sec you recover fully and start at 0 hits again stopnpctimer; @@ -117,9 +109,20 @@ OnTimer25000: setnpctimer 0; end; +OnExhausted: + if (.exhausted < 1) end; + + set @_U_BLOCK, 1; + set @upmarmuspell[1], 0; + set @num_upmarmu_hits, 0; + set .exhausted, 0; + addtimer UPMARMU_EXHAUST_DURATION, "Upmarmu Exhaust Timer::OnClear"; // set the exhaustion time + sc_start SC_COOLDOWN_UPMARMU, UPMARMU_EXHAUST_DURATION, 0, BL_ID; + smsg SMSG_FAILURE, "Magic: You are too exhausted to use this spell for a while!"; + goto L_StopTimer; + OnDestroy: destroy; -*/ OnInit: set .school, SKILL_MAGIC_WAR; @@ -136,6 +139,5 @@ OnInit: OnClear: set @_U_BLOCK, 0; - set @num_upmarmu_hits, 0; end; } diff --git a/world/map/npc/magic/level2-make-bones.txt b/world/map/npc/magic/level2-make-bones.txt index bc9bc6e5..b84cae6c 100644 --- a/world/map/npc/magic/level2-make-bones.txt +++ b/world/map/npc/magic/level2-make-bones.txt @@ -25,7 +25,7 @@ L_Resume: set CASTS, CASTS + 1; if (CASTS < 0) set CASTS, 1; // overflow misceffect FX_MAGIC_ARROW_CAST, strcharinfo(0); - setarray @create_params[0], (@spellpower/32)+1+(rand(max(1,(800-@spellpower)))/80), 500; + setarray @create_params[0], (@spellpower/6)+1+(rand(max(1,(800-@spellpower)))/80), 500; setarray @create_items$[0], "BoneArrows", "IronArrow"; callfunc "magic_create_item"; callfunc "magic_exp"; diff --git a/world/map/npc/magic/level2-protect.txt b/world/map/npc/magic/level2-protect.txt index 7abc9a1a..5447f4e0 100644 --- a/world/map/npc/magic/level2-protect.txt +++ b/world/map/npc/magic/level2-protect.txt @@ -1,17 +1,18 @@ -|script|protect|32767 { - if(call("magic_checks")) end; - if (Sp < 14) end; - set .@level, getskilllv(.school); - if (.@level < .level) end; - if (getskilllv(SKILL_MAGIC) < .level) end; - if (.@level <= 3 && countitem("HardSpike") < 1) end; set @target_id, getcharid(3, @args$); if (@target_id < 1 || !(isloggedin(@target_id)) || get(INVISIBLE, @target_id) == 1) set @target_id, BL_ID; // fallback to self callfunc "adjust_spellpower"; if (distance(BL_ID, @target_id) >= (@spellpower/30)+2) set @target_id, BL_ID; if (BL_ID == @target_id) set @args$, strcharinfo(0); + if (sc_check(SC_PHYS_SHIELD_ITEM, @target_id)) goto L_Itsanc; // itsanc has top priority and can't be overwritten by betsanc + if(call("magic_checks")) end; + if (Sp < 14) end; + set .@level, getskilllv(.school); + if (.@level < .level) end; + if (getskilllv(SKILL_MAGIC) < .level) end; + if (.@level <= 3 && countitem("HardSpike") < 1) end; if (get(GM, @target_id) == 1) end; if (get(Hp, @target_id) < 1) end; if (getequipid(equip_head, strcharinfo(0, @target_id)) == 888) end; @@ -44,6 +45,19 @@ OnEnd: misceffect FX_MAGIC_SHIELD_ENDS, strcharinfo(0); end; +L_Itsanc: + if (BL_ID == @target_id) goto L_ItsancSelf; + goto L_ItsancOther; + +L_ItsancSelf: + message strcharinfo(0), "Shield : You are still itsanced, This blocks your spell."; + end; + +L_ItsancOther: + message strcharinfo(0), "Shield : Your target is still itsanced, This blocks your spell."; + end; + + L_SpecialRules6: if ($@KIMARR_EVENT < 1) goto L_Pay; if (@target_id == BL_ID) goto L_Pay; diff --git a/world/map/npc/magic/level2-rain.txt b/world/map/npc/magic/level2-rain.txt index 6a7f288b..291af009 100644 --- a/world/map/npc/magic/level2-rain.txt +++ b/world/map/npc/magic/level2-rain.txt @@ -102,9 +102,18 @@ OnHit: if(get(Hp, .caster) < 1) destroy; // destroy if caster is missing if(getmap(.caster) != strnpcinfo(3)) destroy; // destroy if caster left the map if(target(.caster, @target_id, 16) != 16 && .caster != @target_id) end; - if((get(BL_TYPE, @target_id) & 1) == 0) end; // either mob or pc + if((get(BL_TYPE, @target_id) & 1) == 0) end; // either mob or pc if(get(ELTTYPE, @target_id) == ELT_FIRE) injure .caster, @target_id, ((rand((@spellpower/15)+5)+2) * (100 - get(MDEF1, @target_id))) / 100; + if ($NO_RAIN_SPAWNS) end; // server-wide killswitch for rain pranks if spawns logic would backfire. + if (mobcount(getmap(), "rain::OnRainSpawnDeath") > 30) end; // Abort if too crowded. + if(get(Class, @target_id) == EntAbomination) // Rain hit Ent? This scores little perk! + monster getmap(), getnpcx(), getnpcy(), "", LogHead, 1+rand(1+(.max/150)), "rain::OnRainSpawnDeath"; + if((get(Class, @target_id) == LogHead) && (rand(5) == 3)) // Rain hit LogHead? Little perk as well (plants) + monster getmap(), getnpcx(), getnpcy(), "", MauvePlant+rand(5), 1, "rain::OnRainSpawnDeath"; + end; + +OnRainSpawnDeath: end; OnDestroy: diff --git a/world/map/npc/magic/level2-summon-fluffies.txt b/world/map/npc/magic/level2-summon-fluffies.txt index f10a86b5..fef40a17 100644 --- a/world/map/npc/magic/level2-summon-fluffies.txt +++ b/world/map/npc/magic/level2-summon-fluffies.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 39) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (getskilllv(.school) < .level) end; if (countitem("WhiteFur") < 1 || countitem("Root") < 1) end; diff --git a/world/map/npc/magic/level2-summon-mouboo.txt b/world/map/npc/magic/level2-summon-mouboo.txt index c692e9cf..8a8603c6 100644 --- a/world/map/npc/magic/level2-summon-mouboo.txt +++ b/world/map/npc/magic/level2-summon-mouboo.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 35) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (getskilllv(.school) < .level) end; if (countitem("MoubooFigurine") < 1 || countitem("Root") < 1) end; diff --git a/world/map/npc/magic/level2-summon-pinkie.txt b/world/map/npc/magic/level2-summon-pinkie.txt index 61af9eed..b4774584 100644 --- a/world/map/npc/magic/level2-summon-pinkie.txt +++ b/world/map/npc/magic/level2-summon-pinkie.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 35) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (getskilllv(.school) < .level) end; if (countitem("PinkAntenna") < 1 || countitem("Root") < 1) end; diff --git a/world/map/npc/magic/level2-summon-snakes.txt b/world/map/npc/magic/level2-summon-snakes.txt index 0723961b..5815cef5 100644 --- a/world/map/npc/magic/level2-summon-snakes.txt +++ b/world/map/npc/magic/level2-summon-snakes.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 40) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (getskilllv(.school) < .level) end; if (countitem("DarkCrystal") < 1 || countitem("SnakeEgg") < 1) end; diff --git a/world/map/npc/magic/level2-summon-spiky-mushroom.txt b/world/map/npc/magic/level2-summon-spiky-mushroom.txt index 701648d5..0f884185 100644 --- a/world/map/npc/magic/level2-summon-spiky-mushroom.txt +++ b/world/map/npc/magic/level2-summon-spiky-mushroom.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 33) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (getskilllv(.school) < .level) end; if (countitem("HardSpike") < 1 || countitem("Root") < 1) end; diff --git a/world/map/npc/magic/level2-summon-wickedmushroom.txt b/world/map/npc/magic/level2-summon-wickedmushroom.txt index 014a5d80..7d0e93c1 100644 --- a/world/map/npc/magic/level2-summon-wickedmushroom.txt +++ b/world/map/npc/magic/level2-summon-wickedmushroom.txt @@ -5,7 +5,6 @@ OnCast: if(call("magic_checks")) end; if (Sp < 42) end; - if (getmapflag(getmap(), MF_TOWN)) end; if (getskilllv(SKILL_MAGIC) < .level) end; if (getskilllv(.school) < .level) end; if (countitem("DarkCrystal") < 1 || countitem("SmallMushroom") < 1) end; diff --git a/world/map/npc/mobs/miner_mania.txt b/world/map/npc/mobs/miner_mania.txt index 445c82e0..a496697d 100644 --- a/world/map/npc/mobs/miner_mania.txt +++ b/world/map/npc/mobs/miner_mania.txt @@ -53,7 +53,7 @@ Note: setarray $@slime_mine_maps_y0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1; setarray $@slime_mine_maps_x1, -1, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 173, -1; setarray $@slime_mine_maps_y1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 170, -1; - setarray $@slimes, CopperSlime, SilverSlime, BromenalSlime, GoldSlime, IronSlime, CoalSlime; + setarray $@slimes, CopperSlime, SilverSlime, BromenalSlime, GoldSlime, IronSlime, CoalSlime, StoneSlime; // Bifs ----------------------------- diff --git a/world/map/npc/mobs/mob_points.txt b/world/map/npc/mobs/mob_points.txt index d0ede2f1..cd827b0b 100644 --- a/world/map/npc/mobs/mob_points.txt +++ b/world/map/npc/mobs/mob_points.txt @@ -232,7 +232,14 @@ function|script|MobPoints 1, // 1221 SmallRubyBif 1, // 1222 SmallSapphireBif 1, // 1223 SmallTopazBif - 200 // 1224 CoalGolem + 200, // 1224 CoalGolem + 25, // 1225 StoneSlime + 200, // 1226 StoneGolem + 1, // 1227 Grass + 1, // 1228 Spelt + 95, // 1229 WarlordSkull + 110, // 1230 GoldenSkull + 100 // 1231 Sunshroom ; // END // the following mobs where replaced by other mobs: diff --git a/world/map/npc/scripts.conf b/world/map/npc/scripts.conf index 17045566..7fbe10b4 100644 --- a/world/map/npc/scripts.conf +++ b/world/map/npc/scripts.conf @@ -36,6 +36,7 @@ npc: npc/functions/motdconfig.txt npc: npc/functions/ghost.txt npc: npc/functions/vault.txt npc: npc/functions/global_event_handler.txt +npc: npc/functions/teleport_manager.txt // Item Functions npc: npc/items/purification_potion.txt @@ -59,11 +60,13 @@ npc: npc/items/drugs.txt npc: npc/items/max_stat.txt npc: npc/items/nobow_item.txt npc: npc/items/love_potion.txt +npc: npc/items/magicring_item.txt npc: npc/items/manapearl_item.txt npc: npc/items/underworld_troll.txt npc: npc/items/silver_bell.txt npc: npc/items/shovel.txt npc: npc/items/maps.txt +npc: npc/items/anchor_stone.txt // Mob Functions npc: npc/mobs/miner_mania.txt |