summaryrefslogtreecommitdiff
path: root/world/map/npc
diff options
context:
space:
mode:
Diffstat (limited to 'world/map/npc')
-rw-r--r--world/map/npc/001-1/_warps.txt1
-rw-r--r--world/map/npc/001-2/_warps.txt2
-rw-r--r--world/map/npc/080-1/_import.txt6
-rw-r--r--world/map/npc/080-1/_mobs.txt3
-rw-r--r--world/map/npc/080-1/_nodes.txt4
-rw-r--r--world/map/npc/080-1/_warps.txt3
-rw-r--r--world/map/npc/080-3/_import.txt6
-rw-r--r--world/map/npc/080-3/_mobs.txt3
-rw-r--r--world/map/npc/080-3/_nodes.txt4
-rw-r--r--world/map/npc/080-3/_warps.txt4
-rw-r--r--world/map/npc/081-1/_import.txt6
-rw-r--r--world/map/npc/081-1/_mobs.txt3
-rw-r--r--world/map/npc/081-1/_nodes.txt4
-rw-r--r--world/map/npc/081-1/_warps.txt6
-rw-r--r--world/map/npc/081-2/_import.txt6
-rw-r--r--world/map/npc/081-2/_mobs.txt3
-rw-r--r--world/map/npc/081-2/_nodes.txt4
-rw-r--r--world/map/npc/081-2/_warps.txt5
-rw-r--r--world/map/npc/081-3/_import.txt6
-rw-r--r--world/map/npc/081-3/_mobs.txt3
-rw-r--r--world/map/npc/081-3/_nodes.txt4
-rw-r--r--world/map/npc/081-3/_warps.txt5
-rw-r--r--world/map/npc/082-2/_import.txt6
-rw-r--r--world/map/npc/082-2/_mobs.txt3
-rw-r--r--world/map/npc/082-2/_nodes.txt4
-rw-r--r--world/map/npc/082-2/_warps.txt9
-rw-r--r--world/map/npc/082-3/_import.txt6
-rw-r--r--world/map/npc/082-3/_mobs.txt3
-rw-r--r--world/map/npc/082-3/_nodes.txt4
-rw-r--r--world/map/npc/082-3/_warps.txt4
-rw-r--r--world/map/npc/_import.txt10
-rw-r--r--world/map/npc/fermi/_import.txt6
-rw-r--r--world/map/npc/fermi/_mobs.txt3
-rw-r--r--world/map/npc/fermi/_nodes.txt4
-rw-r--r--world/map/npc/fermi/_warps.txt5
-rw-r--r--world/map/npc/functions/teleport_manager.txt121
-rw-r--r--world/map/npc/functions/treasure_hunt.txt469
-rw-r--r--world/map/npc/guild/_import.txt6
-rw-r--r--world/map/npc/guild/_mobs.txt3
-rw-r--r--world/map/npc/guild/_nodes.txt4
-rw-r--r--world/map/npc/guild/_warps.txt3
-rw-r--r--world/map/npc/items/maps.txt3
-rw-r--r--world/map/npc/items/shovel.txt4
-rw-r--r--world/map/npc/magic/_procedures.txt53
-rw-r--r--world/map/npc/magic/event-boss-powerup-flee.txt14
-rw-r--r--world/map/npc/magic/event-summon-managuardian.txt12
-rw-r--r--world/map/npc/magic/event-summon-manatyrant.txt12
-rw-r--r--world/map/npc/magic/event-summon-stonegolem.txt12
-rw-r--r--world/map/npc/magic/event-summon-sunshroom.txt15
-rw-r--r--world/map/npc/magic/level1-grow-alizarin.txt10
-rw-r--r--world/map/npc/magic/level1-grow-cobalt.txt10
-rw-r--r--world/map/npc/magic/level1-grow-gamboge.txt10
-rw-r--r--world/map/npc/magic/level1-grow-mauve.txt10
-rw-r--r--world/map/npc/magic/level1-grow-shadow.txt10
-rw-r--r--world/map/npc/magic/level1-summon-maggots.txt15
-rw-r--r--world/map/npc/magic/level2-summon-fluffies.txt15
-rw-r--r--world/map/npc/magic/level2-summon-mouboo.txt15
-rw-r--r--world/map/npc/magic/level2-summon-pinkie.txt15
-rw-r--r--world/map/npc/magic/level2-summon-snakes.txt26
-rw-r--r--world/map/npc/magic/level2-summon-spiky-mushroom.txt15
-rw-r--r--world/map/npc/magic/level2-summon-wickedmushroom.txt27
-rw-r--r--world/map/npc/prison/_import.txt6
-rw-r--r--world/map/npc/prison/_mobs.txt3
-rw-r--r--world/map/npc/prison/_nodes.txt4
-rw-r--r--world/map/npc/prison/_warps.txt4
-rw-r--r--world/map/npc/scripts.conf1
66 files changed, 814 insertions, 271 deletions
diff --git a/world/map/npc/001-1/_warps.txt b/world/map/npc/001-1/_warps.txt
index 2b3f2dfd..8c648d70 100644
--- a/world/map/npc/001-1/_warps.txt
+++ b/world/map/npc/001-1/_warps.txt
@@ -7,6 +7,7 @@
001-1,52,71|warp|-1,-1,001-2,28,27
001-1,49,71|warp|-1,-1,001-2,25,27
001-1,114,99|warp|-1,-1,001-2,25,64
+001-1,114,82|warp|-1,-1,001-2,57,52
001-1,27,32|warp|-1,-1,001-2,28,101
001-1,37,32|warp|-1,-1,001-2,71,101
001-1,55,34|warp|0,-1,001-2,104,101
diff --git a/world/map/npc/001-2/_warps.txt b/world/map/npc/001-2/_warps.txt
index 07ebce6d..9eef0564 100644
--- a/world/map/npc/001-2/_warps.txt
+++ b/world/map/npc/001-2/_warps.txt
@@ -16,3 +16,5 @@
001-2,57,90|warp|-1,-1,001-2,35,94
001-2,36,95|warp|-1,0,001-2,58,90
001-2,65,26|warp|-1,-1,001-1,59,99
+001-2,60,50|warp|-1,-1,prison,46,23
+001-2,57,53|warp|-1,-1,001-1,114,83
diff --git a/world/map/npc/080-1/_import.txt b/world/map/npc/080-1/_import.txt
new file mode 100644
index 00000000..cafaba0c
--- /dev/null
+++ b/world/map/npc/080-1/_import.txt
@@ -0,0 +1,6 @@
+// Map 080-1: Mysterious Glade
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 080-1
+npc: npc/080-1/_mobs.txt
+npc: npc/080-1/_nodes.txt
+npc: npc/080-1/_warps.txt
diff --git a/world/map/npc/080-1/_mobs.txt b/world/map/npc/080-1/_mobs.txt
new file mode 100644
index 00000000..6fc52fa7
--- /dev/null
+++ b/world/map/npc/080-1/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Mysterious Glade mobs
+
diff --git a/world/map/npc/080-1/_nodes.txt b/world/map/npc/080-1/_nodes.txt
new file mode 100644
index 00000000..449b6975
--- /dev/null
+++ b/world/map/npc/080-1/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Mysterious Glade nodes
+
+// (no nodes)
diff --git a/world/map/npc/080-1/_warps.txt b/world/map/npc/080-1/_warps.txt
new file mode 100644
index 00000000..97de0f6f
--- /dev/null
+++ b/world/map/npc/080-1/_warps.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Mysterious Glade warps
+
diff --git a/world/map/npc/080-3/_import.txt b/world/map/npc/080-3/_import.txt
new file mode 100644
index 00000000..593a5e46
--- /dev/null
+++ b/world/map/npc/080-3/_import.txt
@@ -0,0 +1,6 @@
+// Map 080-3: Forgotten Glade
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 080-3
+npc: npc/080-3/_mobs.txt
+npc: npc/080-3/_nodes.txt
+npc: npc/080-3/_warps.txt
diff --git a/world/map/npc/080-3/_mobs.txt b/world/map/npc/080-3/_mobs.txt
new file mode 100644
index 00000000..5fce2024
--- /dev/null
+++ b/world/map/npc/080-3/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Forgotten Glade mobs
+
diff --git a/world/map/npc/080-3/_nodes.txt b/world/map/npc/080-3/_nodes.txt
new file mode 100644
index 00000000..c809d136
--- /dev/null
+++ b/world/map/npc/080-3/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Forgotten Glade nodes
+
+// (no nodes)
diff --git a/world/map/npc/080-3/_warps.txt b/world/map/npc/080-3/_warps.txt
new file mode 100644
index 00000000..e6ecce07
--- /dev/null
+++ b/world/map/npc/080-3/_warps.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Forgotten Glade warps
+
+080-3,84,155|warp|0,-1,081-3,44,23
diff --git a/world/map/npc/081-1/_import.txt b/world/map/npc/081-1/_import.txt
new file mode 100644
index 00000000..f35b3648
--- /dev/null
+++ b/world/map/npc/081-1/_import.txt
@@ -0,0 +1,6 @@
+// Map 081-1: Aethyr
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 081-1
+npc: npc/081-1/_mobs.txt
+npc: npc/081-1/_nodes.txt
+npc: npc/081-1/_warps.txt
diff --git a/world/map/npc/081-1/_mobs.txt b/world/map/npc/081-1/_mobs.txt
new file mode 100644
index 00000000..27f6cc97
--- /dev/null
+++ b/world/map/npc/081-1/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Aethyr mobs
+
diff --git a/world/map/npc/081-1/_nodes.txt b/world/map/npc/081-1/_nodes.txt
new file mode 100644
index 00000000..4eb18abe
--- /dev/null
+++ b/world/map/npc/081-1/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Aethyr nodes
+
+// (no nodes)
diff --git a/world/map/npc/081-1/_warps.txt b/world/map/npc/081-1/_warps.txt
new file mode 100644
index 00000000..e56660cc
--- /dev/null
+++ b/world/map/npc/081-1/_warps.txt
@@ -0,0 +1,6 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Aethyr warps
+
+081-1,68,30|warp|-1,-1,081-2,90,298
+081-1,58,104|warp|-1,-1,020-1,84,75
+081-1,44,89|warp|-1,-1,082-2,88,25
diff --git a/world/map/npc/081-2/_import.txt b/world/map/npc/081-2/_import.txt
new file mode 100644
index 00000000..60017ade
--- /dev/null
+++ b/world/map/npc/081-2/_import.txt
@@ -0,0 +1,6 @@
+// Map 081-2: Northern Lights
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 081-2
+npc: npc/081-2/_mobs.txt
+npc: npc/081-2/_nodes.txt
+npc: npc/081-2/_warps.txt
diff --git a/world/map/npc/081-2/_mobs.txt b/world/map/npc/081-2/_mobs.txt
new file mode 100644
index 00000000..fa19192a
--- /dev/null
+++ b/world/map/npc/081-2/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Northern Lights mobs
+
diff --git a/world/map/npc/081-2/_nodes.txt b/world/map/npc/081-2/_nodes.txt
new file mode 100644
index 00000000..b4162204
--- /dev/null
+++ b/world/map/npc/081-2/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Northern Lights nodes
+
+// (no nodes)
diff --git a/world/map/npc/081-2/_warps.txt b/world/map/npc/081-2/_warps.txt
new file mode 100644
index 00000000..0f47357f
--- /dev/null
+++ b/world/map/npc/081-2/_warps.txt
@@ -0,0 +1,5 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Northern Lights warps
+
+081-2,90,20|warp|-1,-1,081-3,44,50
+081-2,90,299|warp|-1,-1,081-1,68,31
diff --git a/world/map/npc/081-3/_import.txt b/world/map/npc/081-3/_import.txt
new file mode 100644
index 00000000..237a93c5
--- /dev/null
+++ b/world/map/npc/081-3/_import.txt
@@ -0,0 +1,6 @@
+// Map 081-3: Existential Frontier
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 081-3
+npc: npc/081-3/_mobs.txt
+npc: npc/081-3/_nodes.txt
+npc: npc/081-3/_warps.txt
diff --git a/world/map/npc/081-3/_mobs.txt b/world/map/npc/081-3/_mobs.txt
new file mode 100644
index 00000000..6493e765
--- /dev/null
+++ b/world/map/npc/081-3/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Existential Frontier mobs
+
diff --git a/world/map/npc/081-3/_nodes.txt b/world/map/npc/081-3/_nodes.txt
new file mode 100644
index 00000000..5ca051db
--- /dev/null
+++ b/world/map/npc/081-3/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Existential Frontier nodes
+
+// (no nodes)
diff --git a/world/map/npc/081-3/_warps.txt b/world/map/npc/081-3/_warps.txt
new file mode 100644
index 00000000..fcca59a7
--- /dev/null
+++ b/world/map/npc/081-3/_warps.txt
@@ -0,0 +1,5 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Existential Frontier warps
+
+081-3,44,22|warp|-1,-1,080-3,84,154
+081-3,44,51|warp|-1,-1,081-2,90,21
diff --git a/world/map/npc/082-2/_import.txt b/world/map/npc/082-2/_import.txt
new file mode 100644
index 00000000..5d5646d1
--- /dev/null
+++ b/world/map/npc/082-2/_import.txt
@@ -0,0 +1,6 @@
+// Map 082-2: Porthos - Frontier
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 082-2
+npc: npc/082-2/_mobs.txt
+npc: npc/082-2/_nodes.txt
+npc: npc/082-2/_warps.txt
diff --git a/world/map/npc/082-2/_mobs.txt b/world/map/npc/082-2/_mobs.txt
new file mode 100644
index 00000000..689ad2b7
--- /dev/null
+++ b/world/map/npc/082-2/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Porthos - Frontier mobs
+
diff --git a/world/map/npc/082-2/_nodes.txt b/world/map/npc/082-2/_nodes.txt
new file mode 100644
index 00000000..9b2e0796
--- /dev/null
+++ b/world/map/npc/082-2/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Porthos - Frontier nodes
+
+// (no nodes)
diff --git a/world/map/npc/082-2/_warps.txt b/world/map/npc/082-2/_warps.txt
new file mode 100644
index 00000000..249afc27
--- /dev/null
+++ b/world/map/npc/082-2/_warps.txt
@@ -0,0 +1,9 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Porthos - Frontier warps
+
+082-2,81,13|warp|-1,-1,000-1,22,22
+082-2,44,13|warp|-1,-1,000-1,22,22
+082-2,55,33|warp|-1,-1,000-1,22,22
+082-2,57,12|warp|-1,-1,000-1,22,22
+082-2,28,16|warp|-1,-1,082-3,111,35
+082-2,88,26|warp|-1,-1,081-1,44,90
diff --git a/world/map/npc/082-3/_import.txt b/world/map/npc/082-3/_import.txt
new file mode 100644
index 00000000..6f883e7e
--- /dev/null
+++ b/world/map/npc/082-3/_import.txt
@@ -0,0 +1,6 @@
+// Map 082-3: Aether Caves
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: 082-3
+npc: npc/082-3/_mobs.txt
+npc: npc/082-3/_nodes.txt
+npc: npc/082-3/_warps.txt
diff --git a/world/map/npc/082-3/_mobs.txt b/world/map/npc/082-3/_mobs.txt
new file mode 100644
index 00000000..9d8f3638
--- /dev/null
+++ b/world/map/npc/082-3/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Aether Caves mobs
+
diff --git a/world/map/npc/082-3/_nodes.txt b/world/map/npc/082-3/_nodes.txt
new file mode 100644
index 00000000..1de2e9c5
--- /dev/null
+++ b/world/map/npc/082-3/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Aether Caves nodes
+
+// (no nodes)
diff --git a/world/map/npc/082-3/_warps.txt b/world/map/npc/082-3/_warps.txt
new file mode 100644
index 00000000..8bfc67ad
--- /dev/null
+++ b/world/map/npc/082-3/_warps.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Aether Caves warps
+
+082-3,111,34|warp|-1,-1,082-2,28,17
diff --git a/world/map/npc/_import.txt b/world/map/npc/_import.txt
index 2e832cdb..835d6613 100644
--- a/world/map/npc/_import.txt
+++ b/world/map/npc/_import.txt
@@ -122,6 +122,13 @@ import: npc/058-2/_import.txt
import: npc/069-2/_import.txt
import: npc/070-1/_import.txt
import: npc/070-3/_import.txt
+import: npc/080-1/_import.txt
+import: npc/080-3/_import.txt
+import: npc/081-1/_import.txt
+import: npc/081-2/_import.txt
+import: npc/081-3/_import.txt
+import: npc/082-2/_import.txt
+import: npc/082-3/_import.txt
import: npc/099-1/_import.txt
import: npc/099-2/_import.txt
import: npc/099-3/_import.txt
@@ -131,3 +138,6 @@ import: npc/099-6/_import.txt
import: npc/099-7/_import.txt
import: npc/099-8/_import.txt
import: npc/botcheck/_import.txt
+import: npc/fermi/_import.txt
+import: npc/guild/_import.txt
+import: npc/prison/_import.txt
diff --git a/world/map/npc/fermi/_import.txt b/world/map/npc/fermi/_import.txt
new file mode 100644
index 00000000..3860cda1
--- /dev/null
+++ b/world/map/npc/fermi/_import.txt
@@ -0,0 +1,6 @@
+// Map fermi: Three Fermi Land
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: fermi
+npc: npc/fermi/_mobs.txt
+npc: npc/fermi/_nodes.txt
+npc: npc/fermi/_warps.txt
diff --git a/world/map/npc/fermi/_mobs.txt b/world/map/npc/fermi/_mobs.txt
new file mode 100644
index 00000000..d49b9534
--- /dev/null
+++ b/world/map/npc/fermi/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Three Fermi Land mobs
+
diff --git a/world/map/npc/fermi/_nodes.txt b/world/map/npc/fermi/_nodes.txt
new file mode 100644
index 00000000..2f3e21fc
--- /dev/null
+++ b/world/map/npc/fermi/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Three Fermi Land nodes
+
+// (no nodes)
diff --git a/world/map/npc/fermi/_warps.txt b/world/map/npc/fermi/_warps.txt
new file mode 100644
index 00000000..a8a14cb8
--- /dev/null
+++ b/world/map/npc/fermi/_warps.txt
@@ -0,0 +1,5 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Three Fermi Land warps
+
+fermi,29,19|warp|-1,-1,017-9,32,31
+fermi,21,19|warp|-1,-1,009-1,42,44
diff --git a/world/map/npc/functions/teleport_manager.txt b/world/map/npc/functions/teleport_manager.txt
index 529bd5e0..7a9d8980 100644
--- a/world/map/npc/functions/teleport_manager.txt
+++ b/world/map/npc/functions/teleport_manager.txt
@@ -126,32 +126,33 @@ OnCmdHelp:
// 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 (.inactive) goto L_CantPass; // If gate deactivated -> can't pass
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+200, 100000; // Slow player temporarily to avoid movement VS warp DCs
- addtimer .fx_time, strnpcinfo(0)+"::OnTeleport"; // time before teleporting away
+ if (.cookie) set teleport_cookie, 0; // Clear teleport cookie of player on teleport use.
+ sc_start SC_SLOWMOVE, .fx_time+400, 100000; // Slow player temporarily to avoid DCs onwarp
misceffect .fx; // Default .fx set in teleport_add, other code can override it.
+ addtimer .fx_time, strnpcinfo(0)+"::OnTeleport"; // Defer warp to play FX
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.
+// Deferred teleportation timer event (attached to player). Queued by OnTouch.
OnTeleport:
warp .dstmap$, .dst_x, .dst_y;
- addtimer 3000, strnpcinfo(0)+"::OnWarpDone"; // Mostly to clean up SC icon
+ addtimer 6000, strnpcinfo(0)+"::OnTeleportDone"; // Mostly to clean up SC icon
end;
-// Mostly used to remove slow icon that sticks in some cases.
-OnWarpDone:
- sc_end SC_SLOWMOVE;
+// Invoked after teleportation complete.
+OnTeleportDone:
+ sc_start SC_SLOWMOVE, 1, 100000; // If client been slow to load map
+ sc_end SC_SLOWMOVE; // and missed sc_end, force toggle to remove icon
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.
+ addnpctimer (.fx_time + 7000), strnpcinfo(0)+"::OnTeleportShutdown"; // Give time to in-flight players to teleport.
end;
// Does actual teleport shutdown.
@@ -174,39 +175,27 @@ OnInit:
// 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.
+// Inputs: see code below.
+// Return: On success: NPC ID of teleport created, > 0
// 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 .@map$, getarg(0, ""); // Teleport's map.
+ set .@x, getarg(1, -10); // Teleport's X
+ set .@y, getarg(2, -10); // Teleport's Y
+ set .@name$, getarg(3, ""); // Teleport's NPC label
+ set .@sprite, getarg(4, -10); // Teleport's NPC sprite ID
+ set .@xsz, getarg(5, -10); // Teleport's X size
+ set .@ysz, getarg(6, -10); // Teleport's Y size
+ set .@dstmap$, getarg(7, -10); // Destination map name.
+ set .@dst_x, getarg(8, -10); // Destination X
+ set .@dst_y, getarg(9, -10); // Destination Y
+ set .@lifetime, getarg(10, -10); // Teleport lifetime (> 0 or -1 = forever)
+ set .@cookie, getarg(11, -10); // Magic cookie, 0 = everyone allowed, otherwise TP checks match.
+ set .@managed, getarg(12, -10); // Mmanaged? 0:unmanaged, >0: tracked by TP Manager
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 !(mapexists(.@map$)) goto L_Fail; // Validate src map$
+ if !(mapexists(.@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
@@ -404,7 +393,7 @@ function|script|teleportadd_parseargs
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?
+ if !(mapexists(@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?
@@ -454,58 +443,6 @@ L_DisplayHelp:
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.
diff --git a/world/map/npc/functions/treasure_hunt.txt b/world/map/npc/functions/treasure_hunt.txt
new file mode 100644
index 00000000..0e97adce
--- /dev/null
+++ b/world/map/npc/functions/treasure_hunt.txt
@@ -0,0 +1,469 @@
+// Pirate Treasures Hunt quest (c) 2025 Hello=)
+
+// This NPC handles treasure placement
+-|script|TreasureHunt|32767
+{
+ end;
+
+OnTreasurePlace:
+ if (GM < 60) end;
+ gmlog strcharinfo(0) + " shuffled treasure placement";
+ wgm strcharinfo(0) + " shuffled treasure placement";
+ set $TREASURE_X, 0; // To force reinit
+ void call("treasure_place");
+ end;
+
+OnInit:
+ registercmd "@treasure_place", "TreasureHunt::OnTreasurePlace";
+ void call("treasure_place");
+ end;
+}
+
+// Applies defaults to global vars if unconfigured
+function|script|treasure_place
+{
+ if ($TREASURE_MAP$ == "") || !($TREASURE_X) || !($TREASURE_Y) // Not looks configured?
+ goto L_Setup;
+ return;
+
+L_Setup:
+ // Apply defaults
+ set $TREASURE_REWARD, Eyepatch; // main reward
+ set $TREASURE_BOOTY, 200; // max amount of booty (worst case anti-milking cap)
+ set $TREASURE_DIFFICULTY, 100; // common rounds difficulty
+ set $TREASURE_DIFFICULTY2, 100; // extra rounds difficulty (if player found treasure)
+ set $TREASURE_MAP$, "003-4"; // Map to use. Ships are hardwired so far, beware.
+ set $TREASURE_X1, 97; // Rectangle
+ set $TREASURE_X2, 104;
+ set $TREASURE_Y1, 61;
+ set $TREASURE_Y2, 100;
+ // $TREASURE_DEBUG // Debug mode, a lot of battle flow/trace spam.
+ // $TREASURE_TURBO // Play battle real fast. You'll need @hide and GM Hat to survive.
+ goto L_TryPlacement;
+
+L_TryPlacement:
+ // Try placement
+ set $TREASURE_X, rand($TREASURE_X1, $TREASURE_X2); // Choose exact spot
+ set $TREASURE_Y, rand($TREASURE_Y1, $TREASURE_Y2);
+ if (iscollision($TREASURE_MAP$, $TREASURE_X, $TREASURE_Y))
+ goto L_TryPlacement; // do not place trasure on collisions
+ debugmes "treasure_place: treasure placed and configured";
+ return;
+}
+
+// Handler to be invoked from item usage attempt of shovels.
+// This function supposed to be called with player RID attached (its item use by player)
+// Input: Arg0: shovel name from item use handler function.
+// Return: 1 = item use handled (swallowed) by quest, 0 = not handled.
+function|script|treasure_try_shovel
+{
+ set .@shovel$, getarg(0, "");
+ set .@handled, 0;
+ if ($TREASURE_DEBUG) debugmes "treasure_try_shovel, shovel=" + .@shovel$;
+ if (.@shovel$ == "LegendaryShovel") set .@handled, 1; // TH handles everything about Legendary Shovel
+ if (!(.@handled) && (getmap() == $TREASURE_MAP$)) // Hint player they need different shovel on treasure map
+ message strcharinfo(0), "There're rocks in these sands. You'll need different shovel here...";
+ if ($TREASURE_DEBUG) debugmes "treasure_try_shovel, .@handled=" + .@handled;
+ if (.@handled) addtimer 0, "TreasureDig::OnDig", BL_ID; // Request NPC to do its thing just like #treasuredig.
+ return .@handled;
+}
+
+// Handler to be invoked from item usage attempt of maps.
+// This function supposed to be called with player RID attached (its item use by player)
+// Input: Arg0: map name from item use handler function.
+// Return: 1 = item use handled (swallowed) by quest, 0 = not handled.
+function|script|treasure_try_map
+{
+ set .@mapname$, getarg(0, "");
+ if ($TREASURE_DEBUG) debugmes "treasure_try_map, map=" + .@mapname$;
+ set .@handled, 0;
+ if (.@mapname$ == "LegendaryTreasureMap") set .@handled, 1; // TH handles everything about Legendary Treasure Map
+ if ($TREASURE_DEBUG) debugmes "treasure_try_map, .@handled=" + .@handled;
+ if ((getmap() != $TREASURE_MAP$) && (.@handled))
+ message strcharinfo(0), "Treasure Map : This place doesn't looks like one on map.";
+ if ((getmap() == $TREASURE_MAP$) && (.@handled) &&
+ !(isin($TREASURE_MAP$, $TREASURE_X1, $TREASURE_Y1, $TREASURE_X2, $TREASURE_Y2)))
+ message strcharinfo(0), "Treasure Map : This place looks right! Yet [X] mark isn't where you stand.";
+ if ((getmap() == $TREASURE_MAP$) && (.@handled) &&
+ (isin($TREASURE_MAP$, $TREASURE_X1, $TREASURE_Y1, $TREASURE_X2, $TREASURE_Y2)))
+ message strcharinfo(0), "Treasure Map : Aha! Right spot! Unfortunately X mark is big and crude. Promising area is " +
+ "(" + $TREASURE_X1 +"," + $TREASURE_Y1 + ")<->(" + $TREASURE_X2 + "," + $TREASURE_Y2 + ")";
+ return .@handled;
+}
+
+// This NPC handles traeasure dig.
+-|script|TreasureDig|32767
+{
+ end;
+
+OnDig:
+ if ($TREASURE_DISABLE) message strcharinfo(0), "Tough luck, seems there's no booty at this time!";
+ if ($TREASURE_DISABLE) end;
+ set @treasureMobs,
+ mobcount($TREASURE_MAP$, "TreasureDigAux::OnMobKill") +
+ mobcount($TREASURE_MAP$, "TreasureDigAux::OnPirateKill");
+ if ($TREASURE_DEBUG) debugmes "OnDig: mob count = " + @treasureMobs;
+ if (@treasureMobs > 300) message strcharinfo(0), "Its too crowded here to dig! Perhaps kill some mob first?";
+ if (@treasureMobs > 300) end; // Do not let users spam server by mobs indefinitely
+ set .@puppet$, "#"+strnpcinfo(0)+"#"+BL_ID;
+ set .@puppet, puppet(getmap(), POS_X, POS_Y, .@puppet$, 127);
+ if (.@puppet < 1) end; // It also denies player launching N instances at once.
+ // Set up instance of treasure hunt attempt
+ set .digger, BL_ID, .@puppet;
+ set .diggernm$, strcharinfo(0), .@puppet;
+ set .delay, 1000, .@puppet; // Initial round delay
+ set .tiles, TILES_WALKED, .@puppet;
+ if ($TREASURE_DEBUG) debugmes "OnDig: starting";
+ npctalk .@puppet$, "Digging : " + strcharinfo(0) + " starts digging in hope to find something..";
+ if ($TREASURE_MAP$ == getmap())
+ addnpctimer 4000, .@puppet$+"::OnDiggingRound"; // Start digging rounds.
+ else
+ addnpctimer 12000, .@puppet$+"::OnDiggingRound"; // Start digging rounds - fake - slow 'em a bit.
+ addnpctimer 700000, .@puppet$+"::OnDestroy"; // Failsafe quest shutdown on timeout
+ end;
+
+OnDiggingRound:
+ set .dig_round, .dig_round + 1;
+ if ($TREASURE_DEBUG) debugmes "OnDiggingRound: my name=" + strnpcinfo(0) + " digger=" + .digger;
+ if ($TREASURE_DEBUG) debugmes "OnDiggingRound: PLAYER: POSX=" + get(POS_X, .digger) + " POSY=" + get(POS_Y, .digger) + " MAP=" + getmap(.digger) + " TILES=" + get(TILES_WALKED, .digger);
+ if ($TREASURE_DEBUG) debugmes "OnDiggingRound: NPC: POSX=" + getnpcx() + " POSY=" + getnpcy() + " MAP=" + strnpcinfo(3) + " TILES=" + .tiles;
+ if (!(isloggedin(.digger))) set .failed, 2; // Treasure digger disappeared?
+ if (get(Hp, .digger) < 1) set .failed, 3; // Digger digger died?
+ if ((getmap(.digger) != strnpcinfo(3)) || // Digger left map?
+ (get(POS_X, .digger) != getnpcx()) ||
+ (get(POS_Y, .digger) != getnpcy()) ||
+ (get(TILES_WALKED, .digger) != .tiles))
+ set .failed, 4; // Has digger moved?
+ if ($TREASURE_MAP$ != strnpcinfo(3)) set .failed, 9; // Trying to dig on wrong map? Side effects avoidance.
+ if ($TREASURE_DEBUG) debugmes "OnDiggingRound: failed1=" + .failed;
+ if (.failed) goto L_DiggFail;
+ // Basic checks ok -> next round starts
+ misceffect FX_CHANNELLING_RAISE_RED, strcharinfo(0, .digger);
+ set .failed, call("treasure_dig_round", .dig_round); // core function of digging
+ if ($TREASURE_DEBUG) debugmes "OnDiggingRound: failed2=" + .failed;
+ if !($TREASURE_TURBO) set .delay, .delay + 1000; // Turbo == "skip AI moves" for test/debug: FAST battle, @hide+gm map to observe
+ if ((.failed == 9) && call("treasure_is_here") && ($TREASURE_REWARD != 0))
+ goto L_DiggFound; // MaxRound && Found treasure?! Its WIN, not .fail :)
+ if ((.failed == 9) && call("treasure_is_here") && ($TREASURE_REWARD == 0))
+ set .failed, 10; // Found it - but someone got there first? How unfortunate.
+ if (.failed) goto L_DiggFail; // catches e.g. (running to max round && no treasure)
+ else addnpctimer .delay, strnpcinfo(0)+"::OnDiggingRound";
+ end;
+
+// Invoked when digging failed for any reason, by both OnDiggingRound and OnBootyRound.
+L_DiggFail:
+ if ($TREASURE_DEBUG) debugmes "TreasureDig: digging done, .failed=" + .failed;
+ if (.failed == 2) npctalk strnpcinfo(0), "Digging : ##3##BDigger " + .diggernm$ + " disappeared... strange...";
+ elif (.failed == 3) npctalk strnpcinfo(0), "Digging : ##3##BDigger " + .diggernm$ + " haven't made it, digging site collapsed";
+ elif (.failed == 4) npctalk strnpcinfo(0), "Digging : ##3##BDigger " + .diggernm$ + " has lost focus and digging site collapsed";
+ elif (.failed == 9) npctalk strnpcinfo(0), "Digging : ##3##BDoh! Seems there's no treasure on this spot!";
+ elif (.failed == 10) npctalk strnpcinfo(0), "Digging : ##3##BDoh! Someone already digged treasure out!";
+ else /*error, etc*/ npctalk strnpcinfo(0), "Digging : ##3##BDigger " + .diggernm$ + " something went wrong, digging site collapsed";
+ destroy;
+
+L_DiggFound:
+ if !($TREASURE_TURBO) set .delay, 16000; // Configure booty rounds
+ else set .delay, 3000;
+ set .failed, 0;
+ set .round, 1;
+ monster $TREASURE_MAP$, 94, 74, "Pirates!", MontBlanc, 1, "TreasureDigAux::OnPirateKill"; // FIXME hardwired thing
+ monster $TREASURE_MAP$, 95, 66, "Pirates!", MontBlanc, 1, "TreasureDigAux::OnPirateKill";
+ monster $TREASURE_MAP$, 97, 91, "Pirates!", MontBlanc, 1, "TreasureDigAux::OnPirateKill";
+ mapannounce strnpcinfo(3), "Emo : WHAT DO WE HAVE HERE?! Contenders for OUR booty?! Pirates! Kill them all! YARRR!!", 0;
+ addnpctimer .delay, strnpcinfo(0)+"::OnBootyRound"; // Hand over -> OnBootyRound but do not destroy puppet.
+ end;
+
+// Invoked when digger survived initial digging && found treasure. Called when OnDiggRound rounds end.
+OnBootyRound:
+ if ($TREASURE_DEBUG) debugmes "OnBootyRound ->";
+ if (!(isloggedin(.digger))) set .failed, 2; // Treasure digger disappeared?
+ if (get(Hp, .digger) < 1) set .failed, 3; // Digger digger died?
+ if ((getmap(.digger) != strnpcinfo(3)) || // Digger left map?
+ (get(POS_X, .digger) != getnpcx()) ||
+ (get(POS_Y, .digger) != getnpcy()) ||
+ (get(TILES_WALKED, .digger) != .tiles))
+ set .failed, 4; // Has digger moved?
+ if (.failed) goto L_DiggFail; // Reuse digg failure handling above.
+ if (.round > 8) goto L_Finalize;
+ npctalk strnpcinfo(0), "Digging : ##3##B [TREASURE] [" + .round + "] "+ .diggernm$ + " found treasure, keep digger alive to collect collateral!";
+ if ($TREASURE_BOOTY > 0)
+ addtimer 0, "TreasureDigAux::OnCollateral10", .digger; // Collateral for supporters
+ set $TREASURE_BOOTY, $TREASURE_BOOTY - 10; // anti-milking cap, total ~20 rounds with booty top (configurable)
+ set .@round_power, call("treasure_estimate_team"); // get team level
+ if ($TREASURE_DEBUG) debugmes "treasure_dig_round: round power B0=" + .@round_power;
+ set .@round_power, (.@round_power * $TREASURE_DIFFICULTY2) / 170 + (.round / 7) + rand(3); // Adjust & randomize
+ if ($TREASURE_DEBUG) debugmes "treasure_dig_round: round power B1=" + .@round_power;
+ if (.round == 1) set .@mob, Emo; // Guy who yelled
+ else set .@mob, Ratto; // His ship ratto, also treasure contender
+ void call("spawn_in_radius", strnpcinfo(3), getnpcx(), getnpcy(), 2, .@mob, 1, "TreasureDigAux::OnPirateKill");
+ void call("spawn_in_radius", strnpcinfo(3), getnpcx(), getnpcy(), 4, Swashbuckler, .@round_power, "TreasureDigAux::OnPirateKill");
+ void call("spawn_in_radius", strnpcinfo(3), getnpcx(), getnpcy(), 4, Grenadier, .@round_power, "TreasureDigAux::OnPirateKill");
+ void call("spawn_in_radius", strnpcinfo(3), getnpcx(), getnpcy(), 4, Thug, .@round_power, "TreasureDigAux::OnPirateKill");
+ void call("spawn_in_radius", strnpcinfo(3), getnpcx(), getnpcy(), 4, Ratto, 5, "TreasureDigAux::OnPirateKill");
+ set .round, .round + 1;
+ addnpctimer .delay, strnpcinfo(0)+"::OnBootyRound"; // Hand over -> OnBootyRound but do not destroy puppet.
+ end;
+
+L_Finalize:
+ addtimer 0, "TreasureDigAux::OnMainBooty", .digger; // Hand over to final reward handler.
+ mapannounce strnpcinfo(3), "Treasure : Digger " + .diggernm$ + " found treasure!", 0;
+ npctalk strnpcinfo(0), "Digging : ##3##B [TREASURE] Victory! Treasure hunter " + .diggernm$ + " got booty!";
+ destroy;
+
+OnDestroy:
+ debugmes "TreasureDig: GLOBAL TIME OUT, this shouldn't happen"; // Failsafe logic
+ npctalk strnpcinfo(0), "Digging : ##3##BSomething went wrong, your digging site has collapsed";
+ destroy;
+
+OnInit:
+ end;
+}
+
+// This function only meant to be called by TreasureDig's puppet.
+// Main digging round handling logic happens here, spawns + dig fallouts
+// Input: Arg0: round #
+// Arg1: players str
+// Returns: 0 if all ok, 1 = failure, 9 = max round reached.
+function|script|treasure_dig_round
+{
+ set .@round, getarg(0, -1);
+ set .@res, 0; // > 0 halts next rounds, 1 = failure, 9 = "failed to find treasure"
+ set .@rounds0, 2; // # of rounds configuration.
+ set .@rounds1, 6;
+ set .@rounds2, 12;
+ set .@rounds3, 18;
+ set .@rounds4, 22;
+ if ($TREASURE_DEBUG) debugmes "treasure_digg_round: round # " +.@round + " r4=" + .@rounds4;
+ if (.@round < 1) goto L_Failed;
+ if ((.@round >= .@rounds4)) goto L_Done;
+ setarray .@mobs_0[0], CaveMaggot, HouseMaggot, VoidMaggot, Ratto; // Mobs for round spawns
+ setarray .@mobs_1[0], AngryScorpion, Hyvern, Snake, Spider, Archant, RedSlime, AngrySeaSlime, AngryGreenSlime;
+ setarray .@mobs_2[0], VoidSnake, MountainSnake, GrassSnake, SoulSnake, BlackScorpion, CrotcherScorpion, VoidBat, HuntsmanSpider;
+ setarray .@mobs_3[0], Skeleton, LadySkeleton, Wight, RedBone, SoulEater;
+ setarray .@mobs_4[0], Thug, Swashbuckler, Grenadier;
+ if (.@round <= .@rounds0) set .@mobID, .@mobs_0[rand(getarraysize(.@mobs_0))]; // Pick random mob for i-th round
+ elif (.@round <= .@rounds1) set .@mobID, .@mobs_1[rand(getarraysize(.@mobs_1))]; // Make mobs progressiveky harder
+ elif (.@round <= .@rounds2) set .@mobID, .@mobs_2[rand(getarraysize(.@mobs_2))];
+ elif (.@round <= .@rounds3) set .@mobID, .@mobs_3[rand(getarraysize(.@mobs_3))];
+ elif (.@round <= .@rounds4) set .@mobID, .@mobs_4[rand(getarraysize(.@mobs_4))];
+ else set .@mobID, MobMoubootaur; // Failsafe :)
+ set .@rand, rand(1, 100); // Does digging site blows up, releases poison or stays stable?
+ if (.@rand < 22) set .@dig_action$, "treasure_dig_poison";
+ elif (.@rand > 78) set .@dig_action$, "treasure_dig_blowup";
+ else /* 30..70 */ set .@dig_action$, "treasure_dig_stable";
+ if ($TREASURE_DEBUG) debugmes "treasure_digg_round: round # " + .dig_round + " .@rand=" + .@rand + " .@dig_action$=" + .@dig_action$;
+ void call(.@dig_action$, .dig_round); // Avoids goto spaghetti but chosen func MUST exist, or server WILL crash!
+ set .@round_power, call("treasure_estimate_team"); // get team level
+ if ($TREASURE_DEBUG) debugmes "treasure_dig_round: round power0=" + .@round_power;
+ set .@round_power, (.@round_power * $TREASURE_DIFFICULTY) / 130 + (.@round / 7) + rand(3); // Adjust & randomize
+ if ($TREASURE_DEBUG) debugmes "treasure_dig_round: round power1=" + .@round_power;
+ addtimer 0, "TreasureDigAux::OnCollateral1", .digger;
+ void call("spawn_in_radius", strnpcinfo(3), getnpcx(), getnpcy(), 4, .@mobID, .@round_power, "TreasureDigAux::OnMobKill");
+ // Show some fancy messages
+ if (.@round <= .@rounds2) npctalk strnpcinfo(0), "Digging : [" +.@round + "] " + .diggernm$ + " hit monster nest!";
+ elif (.@round <= .@rounds3) npctalk strnpcinfo(0), "Digging : [" +.@round + "] " + .diggernm$ + " Yuck! Skeleton I found moves!";
+ elif (.@round <= .@rounds4) npctalk strnpcinfo(0), "Digging : [" +.@round + "] " + .diggernm$ + " pirates got curious what this noise all about";
+ else npctalk strnpcinfo(0), "Digging : [" +.@round + "] " + .diggernm$ + " ?!?!?!";
+ return 0;
+
+L_Done:
+ if ($TREASURE_DEBUG) debugmes "treasure_digg_round: rounds done";
+ return 9; // Inform quest max rounds reached and no treasure been found.
+
+L_Failed:
+ debugmes "treasure_digg_round: call failed, arg0=" + getarg(0) + "arg1=" + getarg(1);
+ return 1;
+}
+
+// This spawns mobs in a given radius. Fallbacks to spot it it not fits map.
+// This function can be called in any context.
+// Input: Arg0: map where to spawn
+// Arg1: X
+// Arg2: Y
+// Arg3: Radius
+// Arg4: Mob id
+// Arg5: # of mobs
+// Arg6: Event for mob death (must be given, even as "")
+function|script|spawn_in_radius
+{
+ set .@map$, getarg(0, "");
+ set .@x, getarg(1, -1);
+ set .@y, getarg(2, -1);
+ set .@r, getarg(3, -1);
+ set .@mob, getarg(4, -1);
+ set .@qty, getarg(5, -1);
+ set .@evt$, getarg(6, "");
+ // Args check.
+ if ((.@map$ == "") || (.@evt$ == "6") || (.@mob < 1) ||
+ (.@x < 1) || (.@x > getmapmaxx(.@map$)) || (.@r < 1) || (.@qty < 1) ||
+ (.@y < 1) || (.@y > getmapmaxy(.@map$)))
+ goto L_Fail;
+ // Does (x-r, y-r, x+r, y+r) rectangle fits map?
+ if ((.@x > .@r) && (.@y > .@r) &&
+ ((.@x + .@r) < getmapmaxx(.@map$)) &&
+ ((.@y + .@r) < getmapmaxy(.@map$))) //Enough room? Use area.
+ areamonster .@map$, (.@x-.@r), (.@y-.@r), (.@x+.@r), .@y+.@r, "", .@mob, .@qty, .@evt$;
+ else // Rectangle does not fits, fallback
+ monster .@map$, .@x, .@y, "", .@mob, .@qty, .evt$;
+ return;
+
+L_Fail:
+ debugmes "spawn_in_radius: call failed, arg0=" + getarg(0) + " arg1=" + getarg(1) +
+ " arg2=" + getarg(2) + " arg3=" + getarg(3) + " arg4=" + getarg(4) +
+ " arg5=" + getarg(5)+ " arg6=" + getarg(6);
+ return;
+}
+
+// This function meant to be run in context of TreasureDig's *puppet* only
+function|script|treasure_dig_poison
+{
+ if ($TREASURE_DEBUG) debugmes "TreasureDigg: dig_poison";
+ npctalk strnpcinfo(0), "Digging : ["+getarg(0)+"] attempt to dig released poisonous gas!"; // Next throws events in digger (player) context
+ foreach 0, strnpcinfo(3), (getnpcx() - 7), (getnpcy() - 7), (getnpcx() + 7), (getnpcy() + 7), "TreasureDigAux::OnPoisonousGasPlayer", .digger;
+ foreach 2, strnpcinfo(3), (getnpcx() - 4), (getnpcy() - 4), (getnpcx() + 4), (getnpcy() + 4), "TreasureDigAux::OnPoisonousGasMob", .digger;
+ return;
+}
+
+// This function meant to be run in context of TreasureDig's *puppet* only
+function|script|treasure_dig_blowup
+{
+ if ($TREASURE_DEBUG) debugmes "TreasureDigg: dig_blowup";
+ npctalk strnpcinfo(0), "Digging : ["+getarg(0)+"] underground gas bubble blows up!"; // Next throws events in digger (player) context
+ foreach 0, strnpcinfo(3), (getnpcx() - 7), (getnpcy() - 7), (getnpcx() + 7), (getnpcy() + 7), "TreasureDigAux::OnBlowUpPlayer", .digger;
+ foreach 2, strnpcinfo(3), (getnpcx() - 4), (getnpcy() - 4), (getnpcx() + 4), (getnpcy() + 4), "TreasureDigAux::OnBlowUpMob", .digger;
+ return;
+}
+
+// This function meant to be run in context of TreasureDig's *puppet* only
+function|script|treasure_dig_stable
+{
+ if ($TREASURE_DEBUG) debugmes "TreasureDigg: dig_stable";
+ return;
+}
+
+// This function meant to be run in context of TreasureDig's *puppet* only
+function|script|treasure_is_here
+{
+ if ($TREASURE_DEBUG) debugmes "treasure_is_here ->";
+ set .@res, 0;
+ if (($TREASURE_MAP$ == strnpcinfo(3)) &&
+ ($TREASURE_X == getnpcx()) &&
+ ($TREASURE_Y == getnpcy()))
+ set .@res, 1;
+ if ($TREASURE_DEBUG) debugmes "treasure_is_here <- .@res=" + .@res;
+ return .@res;
+}
+
+// This function meant to be run in context of TreasureDig's *puppet* only
+function|script|treasure_estimate_team
+{
+ if ($TREASURE_DEBUG) debugmes "treasure_estimate_team: ->";
+ set @treasure_estimate_team, 1, .digger; // Prepare digger's context
+ if ($TREASURE_DEBUG) debugmes "team_est0 = " + get(@treasure_estimate_team, .digger); // This throws events in digger's context
+ foreach 0, strnpcinfo(3), (getnpcx() - 7), (getnpcy() - 7), (getnpcx() + 7), (getnpcy() + 7), "TreasureDigAux::OnPlayerEstimate", .digger;
+ if ($TREASURE_DEBUG) debugmes "team_est1 = " + get(@treasure_estimate_team, .digger); // This throws events in digger's context
+ return get(@treasure_estimate_team, .digger);
+}
+
+// This NPC handles aux things like poisoning, blow up, statuses cleanup, items placement, ...
+-|script|TreasureDigAux|32767
+{
+ end;
+
+// This cleans players statues like leftovers of poison or blowup stunning.
+// Invoked by timer set by site blowup/poison gas handlers
+OnPlayerStatusCleanup:
+ if ($TREASURE_DEBUG) debugmes "TreasureDigAux: status cleanup, BL ID=" + BL_ID;
+ if (sc_check(SC_POISON)) sc_end SC_POISON;
+ if (sc_check(SC_SLOWMOVE)) sc_end SC_SLOWMOVE;
+ if (sc_check(SC_HALT_REGENERATE)) sc_end SC_HALT_REGENERATE;
+ end;
+
+// Dig site poisonous gas - invoked per player (hurts players)
+OnPoisonousGasPlayer:
+// debugmes "TreasureDigAux: poison/player, target ID=" + @target_id;
+ misceffect FX_EMOTE_DISGUST, strcharinfo(0, @target_id);
+ sc_start SC_POISON, 1, 60, @target_id; // Poison player
+ sc_start SC_HALT_REGENERATE, 5000, 0; // Even if fails, at least halt regen.
+ addtimer 5000, "TreasureDigAux::OnPlayerStatusCleanup"; // clean PC statuses
+ end;
+
+// Dig site poisonous gas - invoked per mob (aggravates mobs)
+OnPoisonousGasMob:
+// debugmes "TreasureDigAux: poison/mob, target ID=" + @target_id;
+ set .@type, get(Class, @target_id); // Dont poison undead
+ if ((.@type != Skeleton) && (.@type != LadySkeleton) && (.@type != Wight) &&
+ (.@type != RedBone) && (.@type != SoulEater))
+ sc_start SC_POISON, 1, 10, @target_id; // Poison MOBS, too.
+ aggravate @target_id; // This aggravates mobs.
+ end;
+
+// Dig site blow up - invoked per player (hurts players)
+OnBlowUpPlayer:
+// debugmes "TreasureDigAux: blowup/player, target ID=" + @target_id;
+ misceffect FX_MEDIUM_SMOKE, strcharinfo(0, @target_id); // Show slow effect
+ sc_start SC_SLOWMOVE, 3000, 300, @target_id; // Slow player temporarily
+ sc_start SC_HALT_REGENERATE, 5000, 0; // Stop regen temporarily
+ set Hp, (get(Hp, @target_id) * 2 / 3), @target_id; // Yes explosion hurts.
+ addtimer 5000, "TreasureDigAux::OnPlayerStatusCleanup"; // clean statuses
+ end;
+
+// Dig site blow up - invoked per mob (aggravates mobs)
+OnBlowUpMob:
+// debugmes "TreasureDigAux: blowup/mob, target ID=" + @target_id;
+ injure BL_ID, @target_id, get(Hp, @target_id) / 3; // Yes, explosion can hurt mobs, too!
+ aggravate @target_id; // This aggravates them!
+ end;
+
+// Event thrown when quest mobs die.
+OnMobKill:
+ if ($TREASURE_DEBUG) debugmes "TreasureDigAux: mob killed, @mobID=" + @mobID;
+ end;
+
+OnPirateKill:
+ if ($TREASURE_DEBUG) debugmes "TreasureDigAux: pirate killed, @mobID=" + @mobID;
+ end;
+
+// Event invoked by team estimation function.
+OnPlayerEstimate:
+ if (get(Hp, @target_id) > 0) set @treasure_estimate_team, @treasure_estimate_team + (get(BaseLevel, @target_id) / 10);
+ if ($TREASURE_DEBUG) debugmes "TreasureDigAux: player_estimate: @treasure_estimate_team=" + @treasure_estimate_team;
+ end;
+
+// Emit few collateral items spawner
+OnCollateral1:
+ if ($TREASURE_DEBUG) debugmes "OnCollateral1";
+ setarray .@items1[0], SulphurPowder, IronPowder, BlackScorpionStinger, TreasureKey, Bone, Skull;
+ set .@itemID, .@items1[rand(getarraysize(.@items1))]; // random collateral
+ if ($TREASURE_DEBUG) debugmes "OnCollateral1 .@itemID=" + .@itemID;
+ makeitem .@itemID, 1, getmap(), rand(POS_X-2,POS_X+2), rand(POS_Y-2,POS_Y+2);
+ end;
+
+// Emit plenty of collateral items spawner (treasure reward mode)
+OnCollateral10:
+ if ($TREASURE_DEBUG) debugmes "OnCollateral10";
+ setarray .@items10[0], Pearl, Sapphire, Amethyst, GoldenTooth, GoldOre, CoinBag;
+ set .@count, 0;
+ goto L_RandomItems;
+
+L_RandomItems:
+ set .@itemID, .@items10[rand(getarraysize(.@items10))]; // random collateral
+ makeitem .@itemID, 4+rand(16), getmap(), rand(POS_X-3,POS_X+3), rand(POS_Y-3,POS_Y+3);
+ set .@count, .@count + 1;
+ if (.@count < 25) goto L_RandomItems;
+ end;
+
+// Hand over rewards + extra "collateral"
+// This handler invoked on digger who initiated digging session and won.
+OnMainBooty:
+ addtimer 0, "TreasureDigAux::OnCollateral10";
+ gmlog strcharinfo(0) + " found treasure!";
+ wgm strcharinfo(0) + " found treasure!";
+ getitem $TREASURE_REWARD, 1;
+ message strcharinfo(0), "Treasure Hunt : Success! You found [" + getitemlink($TREASURE_REWARD) + "]";
+ set $TREASURE_REWARD, 0; // Deny re-runs, treasure acquired
+ end;
+
+OnInit:
+ end;
+}
diff --git a/world/map/npc/guild/_import.txt b/world/map/npc/guild/_import.txt
new file mode 100644
index 00000000..80ea053b
--- /dev/null
+++ b/world/map/npc/guild/_import.txt
@@ -0,0 +1,6 @@
+// Map guild: Guild Bot Area
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: guild
+npc: npc/guild/_mobs.txt
+npc: npc/guild/_nodes.txt
+npc: npc/guild/_warps.txt
diff --git a/world/map/npc/guild/_mobs.txt b/world/map/npc/guild/_mobs.txt
new file mode 100644
index 00000000..5faafe87
--- /dev/null
+++ b/world/map/npc/guild/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Guild Bot Area mobs
+
diff --git a/world/map/npc/guild/_nodes.txt b/world/map/npc/guild/_nodes.txt
new file mode 100644
index 00000000..629ccce8
--- /dev/null
+++ b/world/map/npc/guild/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Guild Bot Area nodes
+
+// (no nodes)
diff --git a/world/map/npc/guild/_warps.txt b/world/map/npc/guild/_warps.txt
new file mode 100644
index 00000000..748604a3
--- /dev/null
+++ b/world/map/npc/guild/_warps.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Guild Bot Area warps
+
diff --git a/world/map/npc/items/maps.txt b/world/map/npc/items/maps.txt
index 29d54e7d..c7f33d83 100644
--- a/world/map/npc/items/maps.txt
+++ b/world/map/npc/items/maps.txt
@@ -1,5 +1,6 @@
function|script|readMap
-{
+{ // call Treasure Hunt quest. If quest handled use, skip message. See "treasure_hunt.txt"
+ if (call("treasure_try_map", @MapName$)) goto L_Return;
message strcharinfo(0), "You have no clue how to use this item yet.";
goto L_Return;
diff --git a/world/map/npc/items/shovel.txt b/world/map/npc/items/shovel.txt
index 8dcbd175..7023f2ec 100644
--- a/world/map/npc/items/shovel.txt
+++ b/world/map/npc/items/shovel.txt
@@ -1,5 +1,7 @@
function|script|useShovel
-{
+{ // call Treasure Hunt quest. If quest handled use, skip message. See "treasure_hunt.txt"
+ if (call("treasure_try_shovel", @ShovelName$)) goto L_Return;
+ // More quests can be plugged in here.
message strcharinfo(0), "You have no clue how to use this item yet.";
goto L_Return;
diff --git a/world/map/npc/magic/_procedures.txt b/world/map/npc/magic/_procedures.txt
index 517373e2..b3f8b8c4 100644
--- a/world/map/npc/magic/_procedures.txt
+++ b/world/map/npc/magic/_procedures.txt
@@ -339,6 +339,7 @@ L_LvCkFail:
// This function used to lock out spell.
// Input: arg0 - length of cooldown.
// Input: arg1 - optional: custom SC_COOLDOWN ID to use.
+// Return: nothing, but configures spell lockout mechanics going.
function|script|magic_block
{
if (getarg(0) <= 0) goto L_Block_Fail;
@@ -356,3 +357,55 @@ L_Block_Fail:
debugmes "bug: magic_block needs arg(0) > 0";
return; // Called wrong way -> spell bug.
}
+
+// magic_summon_all function can be called in any context with or without player
+// This function SUMMONS one or more requested creature around given spot
+// Its effectively wrapper to summon builtin to summon >= 1 beings, in area
+// Inputs: see code below.
+// Return: GID of last summoned mob, 0 on failure.
+// TODO: "real" return of GID (after TMWA call actually patched).
+function|script|magic_summon_all
+{
+ set .@map$, getarg(0, ""); // Map where to summon.
+ set .@x, getarg(1, -1); // X where to summon.
+ set .@y, getarg(2, -1); // Y where to summon
+ set .@r, getarg(3, -1); // Mob spread radius (X-R),(Y-R) <-> (X+R),(Y+R)
+ set .@qty, getarg(4, -1); // # of mobs to summon
+ set .@owner, getarg(5, -1); // owner of mob to set
+ set .@name$, getarg(6, ""); // mob display name
+ set .@mobID, getarg(7, -1); // ID of mob to summon
+ set .@mobAI, getarg(8, -1); // AI (mode) of mob to use
+ set .@lifetime, getarg(9, -1); // Mob's lifetime.
+ set .@event$, getarg(10, ""); // Custom event on mob death (use "" if not needed)
+
+ if ((.@map$ == "") || (.@r < 0) || // FIXME: better map validity check?
+ (.@x <= .@r) || (.@y <= .@r) || // No spawns outside of map
+ (.@x > (getmapmaxx(.@map$) + .@r)) || // No spawns outside of map
+ (.@y > (getmapmaxy(.@map$) + .@r)) || // No spawns outside of map
+ (.@qty < 1) || (.@owner < 1) || (.@lifetime < 0) ||
+ (.@event$ == "10")) // no event been given, not even ""
+ goto L_Fail;
+ goto L_Summon;
+
+L_Summon:
+ set .@qty, .@qty - 1;
+ set .@realx, rand(.@x-.@r, .@x+.@r); // Pick spot around (x,y)
+ set .@realy, rand(.@y-.@r, .@y+.@r);
+ if !(iscollision(.@map$, .@realx, .@realy)) goto L_SummonHere; // Spot ok?
+ set .@realx, .@x; // Fallback to (x, y) on collision (typically player x,y)
+ set .@realy, .@y;
+ goto L_SummonHere;
+
+L_SummonHere:
+ set .@mobGID, 1; // TODO: now its just placeholder for future summon() call prototype change
+ summon .@map$, .@realx, .@realy, .@owner, .@name$, .@mobID, .@mobAI, .@lifetime, .@event$;
+ if (.@qty > 0) goto L_Summon;
+ return .@mobGID;
+
+L_Fail:
+ debugmes "magic_summon_all: call failed, .@map$="+.@map$+" .@x="+.@x+" .@y="+.@y+
+ " .@r="+.@r+" .@qty="+.@qty+" .@owner="+.@owner+" .@name$="+.@name$+
+ " .@mobID="+.@mobID+" .@mobAI="+.@mobAI+" .@lifetime="+.@lifetime+
+ " .@event$="+.@event$+"getarg(10)=" + getarg(10);
+ return 0;
+}
diff --git a/world/map/npc/magic/event-boss-powerup-flee.txt b/world/map/npc/magic/event-boss-powerup-flee.txt
index ee0e68a3..8faf9251 100644
--- a/world/map/npc/magic/event-boss-powerup-flee.txt
+++ b/world/map/npc/magic/event-boss-powerup-flee.txt
@@ -16,11 +16,11 @@ OnCast:
end;
L_EscPlanFail1:
- message strcharinfo(0), "[#bossflee] : Escape plan status: fail! (bad destination?)";
+ message strcharinfo(0), "[bossflee] : Escape plan status: fail! (bad destination?)";
end;
L_EscPlanFail2:
- message strcharinfo(0), "[#bossflee] : Escape plan status: fail! (teleport creation failed)";
+ message strcharinfo(0), "[bossflee] : Escape plan status: fail! (teleport creation failed)";
end;
// Puppet (teleportation pads) logic below.
@@ -64,7 +64,7 @@ function|script|bossflee_parseargs
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?
+ if !(mapexists(@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?
@@ -77,18 +77,18 @@ function|script|bossflee_parseargs
return 0; // Everything OK
L_FailBadmap:
- message strcharinfo(0), "[#bossflee] : unknown flee map:" + @DSTMAP$;
+ 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;
+ 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;
+ 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)";
+ 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-summon-managuardian.txt b/world/map/npc/magic/event-summon-managuardian.txt
index 8e7f13cb..fb7e1916 100644
--- a/world/map/npc/magic/event-summon-managuardian.txt
+++ b/world/map/npc/magic/event-summon-managuardian.txt
@@ -40,17 +40,11 @@ OnSummon:
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:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, 1, .master, "Mana Guardian Summon", ManaGuard, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Mana Guardian Summon", ManaGuard, 2, .lifetime;
+OnDestroy:
destroy;
L_Cooldown:
diff --git a/world/map/npc/magic/event-summon-manatyrant.txt b/world/map/npc/magic/event-summon-manatyrant.txt
index ff082930..0a9f97cb 100644
--- a/world/map/npc/magic/event-summon-manatyrant.txt
+++ b/world/map/npc/magic/event-summon-manatyrant.txt
@@ -42,17 +42,11 @@ OnSummon:
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:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, 1, .master, "Mana Tyrant Summon", ManaTyrant, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Mana Tyrant Summon", ManaTyrant, 2, .lifetime;
+OnDestroy:
destroy;
L_Cooldown:
diff --git a/world/map/npc/magic/event-summon-stonegolem.txt b/world/map/npc/magic/event-summon-stonegolem.txt
index 3608514a..325ded6a 100644
--- a/world/map/npc/magic/event-summon-stonegolem.txt
+++ b/world/map/npc/magic/event-summon-stonegolem.txt
@@ -40,17 +40,11 @@ OnSummon:
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:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, 1, .master, "Stone Golem Summon", StoneGolem, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Stone Golem Summon", StoneGolem, 2, .lifetime;
+OnDestroy:
destroy;
L_Cooldown:
diff --git a/world/map/npc/magic/event-summon-sunshroom.txt b/world/map/npc/magic/event-summon-sunshroom.txt
index 6c01c1c8..52f7619e 100644
--- a/world/map/npc/magic/event-summon-sunshroom.txt
+++ b/world/map/npc/magic/event-summon-sunshroom.txt
@@ -39,20 +39,11 @@ OnSummon:
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:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, .count, .master, "Sunshroom Summon", Sunshroom, 2, .lifetime, "");
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;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level1-grow-alizarin.txt b/world/map/npc/magic/level1-grow-alizarin.txt
index d82288cd..d07e9448 100644
--- a/world/map/npc/magic/level1-grow-alizarin.txt
+++ b/world/map/npc/magic/level1-grow-alizarin.txt
@@ -14,22 +14,16 @@
set CASTS, CASTS + 1;
if (CASTS < 0) set CASTS, 1; // overflow
misceffect FX_MAGIC_GROW_CAST, strcharinfo(0);
- setarray @summon[0], 0, (getskilllv(.school)/2)+1;
callfunc "magic_exp";
addtimer 4000-(@spellpower-9), strnpcinfo(0)+"::OnSummon";
end;
OnSummon:
misceffect FX_MAGIC_GROW_SPAWN, strcharinfo(0);
- callsub S_SummonAll;
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", getmap(), POS_X, POS_Y, 2, (getskilllv(.school)/2)+1, BL_ID, "Alizarin Plant Summon2", AlizarinPlant, 1, (@spellpower*50)+10000, "");
end;
-S_SummonAll:
- summon getmap(), rand(POS_X-2,POS_X+2), rand(POS_Y-2,POS_Y+2), BL_ID, "Alizarin Plant Summon", AlizarinPlant, 1, (@spellpower*50)+10000;
- set @summon[0], @summon[0] + 1;
- if (@summon[0] < @summon[1]) goto S_SummonAll;
- return;
-
OnInit:
set .school, SKILL_MAGIC_NATURE;
set .invocation$, chr(MAGIC_SYMBOL) + "modriphoo"; // used in npcs that refer to this spell
diff --git a/world/map/npc/magic/level1-grow-cobalt.txt b/world/map/npc/magic/level1-grow-cobalt.txt
index 58028e8c..bed01002 100644
--- a/world/map/npc/magic/level1-grow-cobalt.txt
+++ b/world/map/npc/magic/level1-grow-cobalt.txt
@@ -14,22 +14,16 @@
set CASTS, CASTS + 1;
if (CASTS < 0) set CASTS, 1; // overflow
misceffect FX_MAGIC_GROW_CAST, strcharinfo(0);
- setarray @summon[0], 0, (getskilllv(.school)/2)+1;
callfunc "magic_exp";
addtimer 4000-(@spellpower-9), strnpcinfo(0)+"::OnSummon";
end;
OnSummon:
misceffect FX_MAGIC_GROW_SPAWN, strcharinfo(0);
- callsub S_SummonAll;
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", getmap(), POS_X, POS_Y, 2, (getskilllv(.school)/2)+1, BL_ID, "Cobalt Plant Summon", CobaltPlant, 1, (@spellpower*50)+10000, "");
end;
-S_SummonAll:
- summon getmap(), rand(POS_X-2,POS_X+2), rand(POS_Y-2,POS_Y+2), BL_ID, "Cobalt Plant Summon", CobaltPlant, 1, (@spellpower*50)+10000;
- set @summon[0], @summon[0] + 1;
- if (@summon[0] < @summon[1]) goto S_SummonAll;
- return;
-
OnInit:
set .school, SKILL_MAGIC_NATURE;
set .invocation$, chr(MAGIC_SYMBOL) + "modrisump"; // used in npcs that refer to this spell
diff --git a/world/map/npc/magic/level1-grow-gamboge.txt b/world/map/npc/magic/level1-grow-gamboge.txt
index fae2cf7d..674da14f 100644
--- a/world/map/npc/magic/level1-grow-gamboge.txt
+++ b/world/map/npc/magic/level1-grow-gamboge.txt
@@ -14,22 +14,16 @@
set CASTS, CASTS + 1;
if (CASTS < 0) set CASTS, 1; // overflow
misceffect FX_MAGIC_GROW_CAST, strcharinfo(0);
- setarray @summon[0], 0, (getskilllv(.school)/2)+1;
callfunc "magic_exp";
addtimer 4000-(@spellpower-9), strnpcinfo(0)+"::OnSummon";
end;
OnSummon:
misceffect FX_MAGIC_GROW_SPAWN, strcharinfo(0);
- callsub S_SummonAll;
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", getmap(), POS_X, POS_Y, 2, (getskilllv(.school)/2)+1, BL_ID, "Gamboge Plant Summon", GambogePlant, 1, (@spellpower*50)+10000, "");
end;
-S_SummonAll:
- summon getmap(), rand(POS_X-2,POS_X+2), rand(POS_Y-2,POS_Y+2), BL_ID, "Gamboge Plant Summon", GambogePlant, 1, (@spellpower*50)+10000;
- set @summon[0], @summon[0] + 1;
- if (@summon[0] < @summon[1]) goto S_SummonAll;
- return;
-
OnInit:
set .school, SKILL_MAGIC_NATURE;
set .invocation$, chr(MAGIC_SYMBOL) + "modriyikam"; // used in npcs that refer to this spell
diff --git a/world/map/npc/magic/level1-grow-mauve.txt b/world/map/npc/magic/level1-grow-mauve.txt
index af8f54d8..dbc64e59 100644
--- a/world/map/npc/magic/level1-grow-mauve.txt
+++ b/world/map/npc/magic/level1-grow-mauve.txt
@@ -14,22 +14,16 @@
set CASTS, CASTS + 1;
if (CASTS < 0) set CASTS, 1; // overflow
misceffect FX_MAGIC_GROW_CAST, strcharinfo(0);
- setarray @summon[0], 0, (getskilllv(.school)/2)+1;
callfunc "magic_exp";
addtimer 4000-(@spellpower-9), strnpcinfo(0)+"::OnSummon";
end;
OnSummon:
misceffect FX_MAGIC_GROW_SPAWN, strcharinfo(0);
- callsub S_SummonAll;
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", getmap(), POS_X, POS_Y, 2, (getskilllv(.school)/2)+1, BL_ID, "Mauve Plant Summon", MauvePlant, 1, (@spellpower*50)+10000, "");
end;
-S_SummonAll:
- summon getmap(), rand(POS_X-2,POS_X+2), rand(POS_Y-2,POS_Y+2), BL_ID, "Mauve Plant Summon", MauvePlant, 1, (@spellpower*50)+10000;
- set @summon[0], @summon[0] + 1;
- if (@summon[0] < @summon[1]) goto S_SummonAll;
- return;
-
OnInit:
set .school, SKILL_MAGIC_NATURE;
set .invocation$, chr(MAGIC_SYMBOL) + "modrilax"; // used in npcs that refer to this spell
diff --git a/world/map/npc/magic/level1-grow-shadow.txt b/world/map/npc/magic/level1-grow-shadow.txt
index fff821db..945e0577 100644
--- a/world/map/npc/magic/level1-grow-shadow.txt
+++ b/world/map/npc/magic/level1-grow-shadow.txt
@@ -14,22 +14,16 @@
set CASTS, CASTS + 1;
if (CASTS < 0) set CASTS, 1; // overflow
misceffect FX_MAGIC_GROW_CAST, strcharinfo(0);
- setarray @summon[0], 0, (getskilllv(.school)/2)+1;
callfunc "magic_exp";
addtimer 4000-(@spellpower-9), strnpcinfo(0)+"::OnSummon";
end;
OnSummon:
misceffect FX_MAGIC_GROW_SPAWN, strcharinfo(0);
- callsub S_SummonAll;
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", getmap(), POS_X, POS_Y, 2, (getskilllv(.school)/2)+1, BL_ID, "Shadow Plant Summon", ShadowPlant, 1, (@spellpower*50)+10000, "");
end;
-S_SummonAll:
- summon getmap(), rand(POS_X-2,POS_X+2), rand(POS_Y-2,POS_Y+2), BL_ID, "Shadow Plant Summon", ShadowPlant, 1, (@spellpower*50)+10000;
- set @summon[0], @summon[0] + 1;
- if (@summon[0] < @summon[1]) goto S_SummonAll;
- return;
-
OnInit:
set .school, SKILL_MAGIC_NATURE;
set .invocation$, chr(MAGIC_SYMBOL) + "modrisha"; // used in npcs that refer to this spell
diff --git a/world/map/npc/magic/level1-summon-maggots.txt b/world/map/npc/magic/level1-summon-maggots.txt
index ce95422c..c87193da 100644
--- a/world/map/npc/magic/level1-summon-maggots.txt
+++ b/world/map/npc/magic/level1-summon-maggots.txt
@@ -37,20 +37,11 @@ OnSummon:
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 .@i, 0;
- set .@x, getnpcx();
- set .@y, getnpcy();
- set .@map$, strnpcinfo(3);
- callsub S_SummonAll;
- end;
-
-OnDestroy:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, .count, .master, "Maggot Summon", Maggot, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Maggot Summon", Maggot, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level2-summon-fluffies.txt b/world/map/npc/magic/level2-summon-fluffies.txt
index fef40a17..b94fd3ba 100644
--- a/world/map/npc/magic/level2-summon-fluffies.txt
+++ b/world/map/npc/magic/level2-summon-fluffies.txt
@@ -38,20 +38,11 @@ OnSummon:
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_FLUFFY_SPAWN;
- set .@i, 0;
- set .@x, getnpcx();
- set .@y, getnpcy();
- set .@map$, strnpcinfo(3);
- callsub S_SummonAll;
- end;
-
-OnDestroy:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, .count, .master, "Fluffy Summon", Fluffy, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Fluffy Summon", Fluffy, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level2-summon-mouboo.txt b/world/map/npc/magic/level2-summon-mouboo.txt
index 8a8603c6..bb45f96f 100644
--- a/world/map/npc/magic/level2-summon-mouboo.txt
+++ b/world/map/npc/magic/level2-summon-mouboo.txt
@@ -38,20 +38,11 @@ OnSummon:
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_MOUBOO_SPAWN;
- set .@i, 0;
- set .@x, getnpcx();
- set .@y, getnpcy();
- set .@map$, strnpcinfo(3);
- callsub S_SummonAll;
- end;
-
-OnDestroy:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, .count, .master, "Mouboo Summon", Mouboo, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Mouboo Summon", Mouboo, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level2-summon-pinkie.txt b/world/map/npc/magic/level2-summon-pinkie.txt
index b4774584..08d03dca 100644
--- a/world/map/npc/magic/level2-summon-pinkie.txt
+++ b/world/map/npc/magic/level2-summon-pinkie.txt
@@ -38,20 +38,11 @@ OnSummon:
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_PINKY_SPAWN;
- set .@i, 0;
- set .@x, getnpcx();
- set .@y, getnpcy();
- set .@map$, strnpcinfo(3);
- callsub S_SummonAll;
- end;
-
-OnDestroy:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, .count, .master, "Pinkie Summon", Pinkie, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Pinkie Summon", Pinkie, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level2-summon-snakes.txt b/world/map/npc/magic/level2-summon-snakes.txt
index 5815cef5..6549b7e7 100644
--- a/world/map/npc/magic/level2-summon-snakes.txt
+++ b/world/map/npc/magic/level2-summon-snakes.txt
@@ -39,25 +39,19 @@ OnSummon:
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_SNAKE_SPAWN;
- set .@i, 0;
- set .@x, getnpcx();
- set .@y, getnpcy();
- set .@map$, strnpcinfo(3);
- callsub S_SummonAll;
- end;
+ setarray .@mobs[0], CaveSnake, Snake, MountainSnake, GrassSnake; // Which snake to summon?
+ goto L_SummonRandom; // Spawn one by one to randomize
-OnDestroy:
+L_SummonRandom:
+ set .count, .count - 1;
+ set .mob, .@mobs[rand(getarraysize(.@mobs))]; // Pick random mob
+ set .nm$, mobinfo(.mob, MOB_ENG_NAME) + " Summon"; // Get mob's name + add Summon
+ // map X Y Rad QTY OWNER Disp MobID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, 1, .master, .nm$, .mob, 2, .lifetime, "");
+ if (.count > 0) goto L_SummonRandom;
destroy;
-S_SummonAll:
- set .@sn, rand(0, 3);
-
- if (.@sn == 0) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Cave Snake Summon", CaveSnake, 2, .lifetime;
- elif (.@sn == 1) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Snake Summon", Snake, 2, .lifetime;
- elif (.@sn == 2) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Mountain Snake Summon", MountainSnake, 2, .lifetime;
- elif (.@sn == 3) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Grass Snake Summon", GrassSnake, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level2-summon-spiky-mushroom.txt b/world/map/npc/magic/level2-summon-spiky-mushroom.txt
index 0f884185..9e305313 100644
--- a/world/map/npc/magic/level2-summon-spiky-mushroom.txt
+++ b/world/map/npc/magic/level2-summon-spiky-mushroom.txt
@@ -38,20 +38,11 @@ OnSummon:
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:
+ // map X Y Rad QTY OWNER DisplayName Mob ID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, .count, .master, "Spiky Mushroom Summon", SpikyMushroom, 2, .lifetime, "");
destroy;
-S_SummonAll:
- summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Spiky Mushroom Summon", SpikyMushroom, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/magic/level2-summon-wickedmushroom.txt b/world/map/npc/magic/level2-summon-wickedmushroom.txt
index 7d0e93c1..9ee4406a 100644
--- a/world/map/npc/magic/level2-summon-wickedmushroom.txt
+++ b/world/map/npc/magic/level2-summon-wickedmushroom.txt
@@ -39,24 +39,21 @@ OnSummon:
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_WICKED_SPAWN;
- set .@i, 0;
- set .@x, getnpcx();
- set .@y, getnpcy();
- set .@map$, strnpcinfo(3);
- callsub S_SummonAll;
- end;
+ goto L_SummonRandom; // Spawn one by one to randomize
-OnDestroy:
+L_SummonRandom:
+ set .count, .count - 1;
+ set .rnd, rand(0, 9);
+ if (.rnd < 6) set .mob, WickedMushroom;
+ elif (.rnd < 9) set .mob, Moonshroom;
+ else set .mob, EvilMushroom;
+ set .nm$, mobinfo(.mob, MOB_ENG_NAME) + " Summon"; // Get mob's name + add Summon
+ // map X Y Rad QTY OWNER Disp MobID AI Lifetime (no custom event)
+ void call("magic_summon_all", strnpcinfo(3), getnpcx(), getnpcy(), 2, 1, .master, .nm$, .mob, 2, .lifetime, "");
+ if (.count > 0) goto L_SummonRandom;
destroy;
-S_SummonAll:
- set .@rnd, rand(0, 9);
-
- if (.@rnd < 6) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Wicked Mushroom Summon", WickedMushroom, 2, .lifetime;
- elif (.@rnd < 9) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Moonshroom Summon", Moonshroom, 2, .lifetime;
- elif (.@rnd == 9) summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Evil Mushroom Summon", EvilMushroom, 2, .lifetime;
- set .@i, .@i + 1;
- if (.@i < .count) goto S_SummonAll;
+OnDestroy:
destroy;
L_SpecialRules6:
diff --git a/world/map/npc/prison/_import.txt b/world/map/npc/prison/_import.txt
new file mode 100644
index 00000000..ba495023
--- /dev/null
+++ b/world/map/npc/prison/_import.txt
@@ -0,0 +1,6 @@
+// Map prison: Prison
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+map: prison
+npc: npc/prison/_mobs.txt
+npc: npc/prison/_nodes.txt
+npc: npc/prison/_warps.txt
diff --git a/world/map/npc/prison/_mobs.txt b/world/map/npc/prison/_mobs.txt
new file mode 100644
index 00000000..5f4bbb79
--- /dev/null
+++ b/world/map/npc/prison/_mobs.txt
@@ -0,0 +1,3 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Prison mobs
+
diff --git a/world/map/npc/prison/_nodes.txt b/world/map/npc/prison/_nodes.txt
new file mode 100644
index 00000000..fcfcd7e3
--- /dev/null
+++ b/world/map/npc/prison/_nodes.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Prison nodes
+
+// (no nodes)
diff --git a/world/map/npc/prison/_warps.txt b/world/map/npc/prison/_warps.txt
new file mode 100644
index 00000000..26f3dd9d
--- /dev/null
+++ b/world/map/npc/prison/_warps.txt
@@ -0,0 +1,4 @@
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+// Prison warps
+
+prison,46,22|warp|-1,-1,001-2,60,49
diff --git a/world/map/npc/scripts.conf b/world/map/npc/scripts.conf
index b2565af8..66606bd8 100644
--- a/world/map/npc/scripts.conf
+++ b/world/map/npc/scripts.conf
@@ -37,6 +37,7 @@ npc: npc/functions/ghost.txt
npc: npc/functions/vault.txt
npc: npc/functions/global_event_handler.txt
npc: npc/functions/teleport_manager.txt
+npc: npc/functions/treasure_hunt.txt
npc: npc/functions/spawns_on_mobkill.txt
// Item Functions