aboutsummaryrefslogtreecommitdiff
path: root/src/features/dungeonRoutes
diff options
context:
space:
mode:
authorSoopyboo32 <49228220+Soopyboo32@users.noreply.github.com>2022-09-17 19:39:05 +0800
committerSoopyboo32 <49228220+Soopyboo32@users.noreply.github.com>2022-09-17 19:39:05 +0800
commit431e4fc9d1657a50ebc34b8ac24f9bfaea06417f (patch)
tree5987bb14f38d2999c682970429f34b41eb3e5826 /src/features/dungeonRoutes
parente73f2efdf0f50aa775c540317394d46428e9704f (diff)
downloadSoopyV2-431e4fc9d1657a50ebc34b8ac24f9bfaea06417f.tar.gz
SoopyV2-431e4fc9d1657a50ebc34b8ac24f9bfaea06417f.tar.bz2
SoopyV2-431e4fc9d1657a50ebc34b8ac24f9bfaea06417f.zip
Initial move to babel + change fetch to use async/await
Diffstat (limited to 'src/features/dungeonRoutes')
-rw-r--r--src/features/dungeonRoutes/index.js481
-rw-r--r--src/features/dungeonRoutes/metadata.json8
-rw-r--r--src/features/dungeonRoutes/routesData.json1296
3 files changed, 1785 insertions, 0 deletions
diff --git a/src/features/dungeonRoutes/index.js b/src/features/dungeonRoutes/index.js
new file mode 100644
index 0000000..e59e908
--- /dev/null
+++ b/src/features/dungeonRoutes/index.js
@@ -0,0 +1,481 @@
+/// <reference types="../../../../CTAutocomplete" />
+/// <reference lib="es2015" />
+import { m } from "../../../mappings/mappings";
+import Feature from "../../featureClass/class";
+import { drawBoxAtBlock, drawBoxAtBlock2, drawFilledBox, drawLine, drawLinePoints } from "../../utils/renderUtils";
+import { calculateDistanceQuick } from "../../utils/utils";
+import SettingBase from "../settings/settingThings/settingBase";
+
+const EntityItem = Java.type("net.minecraft.entity.item.EntityItem")
+
+const EnumParticleTypes = Java.type('net.minecraft.util.EnumParticleTypes');
+
+class DungeonRoutes extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable() {
+ if (Player.getUUID().toString() !== "dc8c3964-7b29-4e03-ae9e-d13ebd65dd29") {
+ new SettingBase("Coming soontm", "maby", undefined, "coming_soontm", this)
+ return
+ }
+
+ this.recordingData = []
+ this.currentActionIndex = 0
+ this.lastLocationUpdatedTime = Date.now()
+
+ this.registerEvent("soundPlay", this.playSound)
+ this.registerEvent("worldLoad", this.worldLoad)
+ this.registerEvent("playerInteract", this.playerInteract)
+ this.registerForge(net.minecraftforge.event.entity.EntityJoinWorldEvent, this.entityJoinWorldEvent)
+ let packetRecieved = this.registerCustom("packetReceived", this.pickupItem)
+
+ try {
+ packetRecieved.trigger.setPacketClasses([net.minecraft.network.play.server.S0DPacketCollectItem])
+ } catch (e) { }//older ct version
+
+ this.registerStep(true, 5, () => {
+ let roomId = this.getCurrentRoomId()
+ if (this.lastRoomId !== roomId) {
+ this.lastRoomId = roomId
+ this.recordingData = []
+
+ this.currRoomData = this.getRoomWorldData()
+
+ this.currentRouteDisplay = this.routesIndexMap.get(this.fullRoomData[this.idMap.get(roomId)].index)?.data
+ ChatLib.chat(JSON.stringify(this.currentRouteDisplay, undefined, 2))
+ }
+
+ if (!this.recordRoute) return
+ if (!this.recordingData[this.recordingData.length - 1]) return
+ let locs = this.recordingData[this.recordingData.length - 1].locations
+ if (locs.length === 0
+ || Math.ceil(Player.getX()) !== locs[locs.length - 1][0]
+ || Math.ceil(Player.getY()) !== locs[locs.length - 1][1]
+ || Math.ceil(Player.getZ()) !== locs[locs.length - 1][2]) {
+
+ this.addRecordingPoint("locations", [Math.ceil(Player.getX()), Math.ceil(Player.getY()), Math.ceil(Player.getZ())])
+ }
+ })
+
+ this.registerEvent("renderWorld", () => {
+ if (this.recordingData && this.recordingData[this.recordingData.length - 1]) {
+ this.recordingData[this.recordingData.length - 1].etherwarps.forEach((loc) => {
+ drawFilledBox(loc[0], loc[1] - 1, loc[2], 1, 1, 1, 0, 0, 50 / 255, true)
+ drawBoxAtBlock(loc[0] - 0.5, loc[1] - 1, loc[2] - 0.5, 1, 0, 0, 1, 1, 1)
+ })
+ this.recordingData[this.recordingData.length - 1].mines.forEach((loc) => {
+ drawFilledBox(loc[0], loc[1] - 0.5, loc[2], 1, 1, 0, 1, 0, 50 / 255, true)
+ })
+ this.recordingData[this.recordingData.length - 1].tnts.forEach((loc) => {
+ drawFilledBox(loc[0], loc[1] - 0.5, loc[2], 1, 1, 1, 0, 0, 50 / 255, true)
+ })
+ this.recordingData[this.recordingData.length - 1].interacts.forEach((data) => {
+ let loc = data.loc
+ drawFilledBox(loc[0], loc[1], loc[2], 1, 1, 0, 0, 1, 50 / 255, true)
+ drawBoxAtBlock(loc[0] - 0.5, loc[1], loc[2] - 0.5, 0, 0, 1, 1, 1, 1)
+ })
+ let locs = this.recordingData[this.recordingData.length - 1].locations
+ if (locs.length >= 2) drawLinePoints(locs.map(a => [a[0] - 0.5, a[1] + 0.1, a[2] - 0.5]), 0, 0, 255, 2, false)
+ }
+
+ if (this.currRoomData) {
+ if (this.currentRouteDisplay) {
+ this.currentRouteDisplay[this.currentActionIndex].etherwarps.forEach(loc => {
+ let coords = this.toRoomCoordinates(loc[0], loc[1] - 1, loc[2])
+ drawFilledBox(coords[0], coords[1], coords[2], 1, 1, 1, 0, 0, 50 / 255, true)
+ drawBoxAtBlock(coords[0] - 0.5, coords[1], coords[2] - 0.5, 1, 0, 0, 1, 1, 1)
+ })
+ this.currentRouteDisplay[this.currentActionIndex].mines.forEach(loc => {
+ let coords = this.toRoomCoordinates(loc[0], loc[1] - 0.5, loc[2])
+ drawBoxAtBlock(coords[0] - 0.5, coords[1], coords[2] - 0.5, 1, 1, 0, 1, 1, 50 / 255)
+ })
+ this.currentRouteDisplay[this.currentActionIndex].tnts.forEach(loc => {
+ let coords = this.toRoomCoordinates(loc[0], loc[1] - 1, loc[2])
+ drawBoxAtBlock(coords[0] - 0.5, coords[1] + 0.5, coords[2] - 0.5, 1, 1, 255, 1, 1, 50 / 255)
+ })
+ this.currentRouteDisplay[this.currentActionIndex].interacts.forEach((data) => {
+ let coords = this.toRoomCoordinates(data.loc[0], data.loc[1], data.loc[2])
+ drawFilledBox(coords[0], coords[1], coords[2], 1, 1, 0, 0, 1, 50 / 255, true)
+ drawBoxAtBlock(coords[0] - 0.5, coords[1], coords[2] - 0.5, 0, 0, 1, 1, 1, 1)
+ })
+
+ // if (this.currentRouteDisplay.locations.length >= 2) drawLinePoints(this.currentRouteDisplay.locations.map(a => this.toRoomCoordinates(...a)).map(a => [a[0] - 0.5, a[1] + 0.1, a[2] - 0.5]), 0, 0, 255, 2, false)
+
+ }
+ }
+
+ })
+
+ this.tempItemIdLocs = new Map()
+
+ this.idMap = new Map()
+ this.routesIndexMap = new Map()
+ this.fullRoomData = JSON.parse(FileLib.read("SoopyV2", "data/roomdata.json"))
+ this.fullRoutesData = JSON.parse(FileLib.read("SoopyV2", "features/dungeonRoutes/routesData.json"))
+ this.fullRoomData.forEach((d, i) => {
+ d.id.forEach(id => {
+ this.idMap.set(id, i)
+ })
+ this.idMap.set(d.index, i)
+ })
+ this.fullRoutesData.forEach((d, i) => {
+ this.routesIndexMap.set(d.index, d)
+ })
+ this.lastRoomId = undefined
+
+ this.currRoomData = undefined
+ this.currentRouteDisplay = undefined
+
+ this.registerCommand("roomid", (...name) => {
+ ChatLib.chat(JSON.stringify(this.getCurrentRoomData(), undefined, 2))
+ ChatLib.chat(JSON.stringify(this.getRoomWorldData(), undefined, 2))
+ })
+ this.recordRoute = false
+
+ this.registerCommand("startroute", (...name) => {
+ this.recordRoute = true
+ this.recordingData = []
+ this.addRecordingPoint()
+ ChatLib.chat(this.FeatureManager.messagePrefix + "Started recording route!")
+ })
+
+ this.registerCommand("saveroute", () => {
+ let data = {
+ index: this.fullRoomData[this.idMap.get(this.lastRoomId)].index,
+ data: this.recordingData.map(a => {
+ a.etherwarps = a.etherwarps.map(a => this.fromRoomCoordinates(a[0], a[1], a[2]))
+ a.mines = a.mines.map(a => this.fromRoomCoordinates(a[0], a[1], a[2]))
+ a.locations = a.locations.map(a => this.fromRoomCoordinates(...a))
+ a.interacts = a.interacts.map(b => {
+ b.loc = this.fromRoomCoordinates(...b.loc)
+ return b
+ })
+ a.tnts = a.tnts.map(a => this.fromRoomCoordinates(a[0], a[1], a[2]))
+
+ return a
+ })
+ }
+ // this.recordingData.push({
+ // etherwarps: [],
+ // mines: [],
+ // locations: [],
+ // interacts: [],
+ // tnts: []
+ // })
+
+ ChatLib.chat(JSON.stringify(data, undefined, 4))
+ ChatLib.chat(this.FeatureManager.messagePrefix + "Saved route!")
+ this.recordRoute = false
+ })
+
+ this.registerStep(true, 5, () => {
+ if (this.currRoomData) {
+ if (this.currentRouteDisplay) {
+
+ if (this.currentRouteDisplay[this.currentActionIndex].locations.length >= 2) this.drawLineMultipleParticles(this.currentRouteDisplay[this.currentActionIndex].locations.map(a => this.toRoomCoordinates(a[0], a[1], a[2])))
+
+ }
+ }
+ })
+ }
+
+ addRecordingPoint(type, point) {
+ if (type) {
+ this.recordingData[this.recordingData.length - 1][type].push(point)
+ }
+ if (!type || type === "interacts") {
+ this.recordingData.push({
+ etherwarps: [],
+ mines: [],
+ locations: [],
+ interacts: [],
+ tnts: []
+ })
+ }
+ }
+ drawLineMultipleParticles(locations) {
+ let lastLoc = undefined
+ locations.forEach(loc => {
+ if (!lastLoc) {
+ lastLoc = loc
+ return
+ }
+
+ this.drawLineParticles(lastLoc, loc)
+ lastLoc = loc
+ })
+ }
+
+ drawLineParticles(loc1, loc2) {
+ let distance = Math.hypot(...loc1.map((a, i) => a - loc2[i]))
+ let maxPoints = Math.ceil(distance * 1)
+ for (let i = 0; i < maxPoints; i++) {
+ let actualI = i + Math.random()
+ let a = actualI / maxPoints
+ let loc = [loc1[0] * a + loc2[0] * (1 - a) - 0.5, loc1[1] * a + loc2[1] * (1 - a) + 0.1, loc1[2] * a + loc2[2] * (1 - a) - 0.5]
+
+ let a2 = (actualI + 0.02) / maxPoints
+ let loc3 = [loc1[0] * a2 + loc2[0] * (1 - a2) - 0.5, loc1[1] * a2 + loc2[1] * (1 - a2) + 0.1, loc1[2] * a2 + loc2[2] * (1 - a2) - 0.5]
+ loc3 = loc3.map((a, i) => loc[i] - a)
+
+ this.spawnParticleAtLocation(loc, loc3, "FLAME")
+ }
+ }
+
+ spawnParticleAtLocation(loc, velo, particle) {
+ let particleType = EnumParticleTypes.valueOf(particle);
+ let idField = particleType.getClass().getDeclaredField('field_179372_R');
+ idField.setAccessible(true);
+ let id = idField.get(particleType);
+
+ Client.getMinecraft().field_71438_f.func_174974_b(
+ id, // particleID
+ true, // shouldIgnoreRange
+ loc[0], // x
+ loc[1], // y
+ loc[2], // z
+ velo[0], // speedX
+ velo[1], // speedY
+ velo[2], // speedZ
+ );
+ }
+
+ toRoomCoordinates(x, y, z) { //From relative coords to world coords
+ if (!this.currRoomData) return null
+
+ if (this.currRoomData.rotation === 2) {
+ z *= -1;
+ [x, z] = [z, x]
+ } else if (this.currRoomData.rotation === 3) {
+ x *= -1
+ z *= -1
+ } else if (this.currRoomData.rotation === 4) {
+ x *= -1;
+ [x, z] = [z, x]
+ }
+
+ return [this.currRoomData.cx + x, y, this.currRoomData.cy + z]
+ }
+ fromRoomCoordinates(x, y, z) { //from world coords to relative coords
+ if (!this.currRoomData) return null
+
+ x -= this.currRoomData.cx
+ z -= this.currRoomData.cy
+
+ if (this.currRoomData.rotation === 2) {
+ [x, z] = [z, x]
+ z *= -1
+ } else if (this.currRoomData.rotation === 3) {
+ x *= -1
+ z *= -1
+ } else if (this.currRoomData.rotation === 4) {
+ [x, z] = [z, x]
+ x *= -1
+ }
+
+ return [x, y, z]
+ }
+
+ getRotation(x, y, width, height, roofY) {
+ let currRoomData = this.getCurrentRoomData()
+ if (!currRoomData) return -1
+
+ if (currRoomData.shape !== "L") {
+ if (this.getTopBlockAt(x, y, roofY) === 11) return 1
+ if (this.getTopBlockAt(x + width, y, roofY) === 11) return 2
+ if (this.getTopBlockAt(x + width, y + height, roofY) === 11) return 3
+ if (this.getTopBlockAt(x, y + height, roofY) === 11) return 4
+ } else {
+ let one = this.getTopBlockAt2(x + width / 2 + 1, y + height / 2, roofY)
+ let two = this.getTopBlockAt2(x + width / 2 - 1, y + height / 2, roofY)
+ let three = this.getTopBlockAt2(x + width / 2, y + height / 2 + 1, roofY)
+ let four = this.getTopBlockAt2(x + width / 2, y + height / 2 - 1, roofY)
+
+ if (one === 0 && three === 0) return 1
+ if (two === 0 && three === 0) return 2
+ if (one === 0 && four === 0) return 3
+ if (two === 0 && four === 0) return 4
+ }
+
+ return -1
+ }
+
+ getRoomWorldData() {
+ let x = Math.floor((Player.getX() + 8) / 32) * 32 - 8
+ let y = Math.floor((Player.getZ() + 8) / 32) * 32 - 8
+ let width = 30
+ let height = 30
+
+ let roofY = this.getRoofAt(x, y)
+
+ while (World.getBlockStateAt(new BlockPos(x - 1, roofY, y)).getBlockId() !== 0) {
+ x -= 32
+ width += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x, roofY, y - 1)).getBlockId() !== 0) {
+ y -= 32
+ height += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x - 1, roofY, y)).getBlockId() !== 0) { //second iteration incase of L shape
+ x -= 32
+ width += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x + width + 1, roofY, y)).getBlockId() !== 0) {
+ width += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x, roofY, y + height + 1)).getBlockId() !== 0) {
+ height += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x + width, roofY, y + height + 1)).getBlockId() !== 0) { //second iteration incase of L shape
+ height += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x + width + 1, roofY, y + height)).getBlockId() !== 0) { //second iteration incase of L shape
+ width += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x + width, roofY, y - 1)).getBlockId() !== 0) {//second iteration incase of L shape
+ y -= 32
+ height += 32
+ }
+ while (World.getBlockStateAt(new BlockPos(x - 1, roofY, y + height)).getBlockId() !== 0) { //third iteration incase of L shape
+ x -= 32
+ width += 32
+ }
+
+
+ return {
+ x,
+ y,
+ width,
+ height,
+ cx: x + width / 2,
+ cy: y + height / 2,
+ rotation: this.getRotation(x, y, width, height, roofY)
+ }
+ }
+
+ getRoofAt(x, z) {
+ let y = 255
+ while (y > 0 && World.getBlockStateAt(new BlockPos(x, y, z)).getBlockId() === 0) y--
+
+ return y
+ }
+
+ getTopBlockAt(x, z, y) {
+ if (!y) y = this.getHeightAt(x, z)
+
+ return World.getBlockStateAt(new BlockPos(x, y, z)).getMetadata()
+ }
+ getTopBlockAt2(x, z, y) {
+ if (!y) y = this.getHeightAt(x, z)
+
+ return World.getBlockStateAt(new BlockPos(x, y, z)).getBlockId()
+ }
+
+ getCurrentRoomData() {
+ let roomId = this.idMap.get(this.getCurrentRoomId())
+ if (roomId === undefined) return null
+
+ return this.fullRoomData[roomId]
+ }
+
+ getCurrentRoomId() {
+ let id = Scoreboard.getLineByIndex(Scoreboard.getLines().length - 1).getName().trim().split(" ").pop()
+
+ return id
+ }
+
+ worldLoad() {
+
+ }
+
+ entityJoinWorldEvent(event) {
+ if (event.entity instanceof EntityItem) {
+ // console.log("Blaze joined world")
+ let e = new Entity(event.entity)
+ let pos = [e.getX(), e.getY(), e.getZ()]
+
+ this.tempItemIdLocs.set(event.entity[m.getEntityId.Entity](), pos)
+ // console.log(event.entity[m.getEntityId.Entity]())
+ }
+ }
+
+ pickupItem(packet) {
+ let packetType = new String(packet.class.getSimpleName()).valueOf()
+ if (packetType === "S0DPacketCollectItem") {
+ let pos = this.tempItemIdLocs.get(packet[m.getCollectedItemEntityID]())
+
+ let data = this.currentRouteDisplay[this.currentActionIndex].interacts[0]
+ if (data && data.type === "item") {
+ let coords = this.toRoomCoordinates(data.loc[0], data.loc[1], data.loc[2])
+ if (calculateDistanceQuick(pos, coords) < 2) {
+ if (this.currentRouteDisplay.length >= this.currentActionIndex) {
+ this.currentActionIndex++
+ }
+ }
+ }
+
+ if (!this.recordRoute) return
+ if (pos) this.addRecordingPoint("interacts", { loc: pos, type: "item" })
+ }
+ }
+
+ playerInteract(action, position, event) {
+ if (action.toString() !== "RIGHT_CLICK_BLOCK") return
+
+ let pos = [Player.lookingAt().getX() + 0.5, Player.lookingAt().getY(), Player.lookingAt().getZ() + 0.5]
+
+ let id = Player.lookingAt().getType().getID()
+ if (id !== 54 && id !== 144 && id !== 69) return
+
+
+ let data = this.currentRouteDisplay[this.currentActionIndex].interacts[0]
+ if (data && data.type === "interact") {
+ let coords = this.toRoomCoordinates(data.loc[0], data.loc[1], data.loc[2])
+ console.log(coords.join(","), pos.join(","))
+ if (coords.join(",") === pos.join(",")) {
+ if (this.currentRouteDisplay.length > this.currentActionIndex) {
+ this.currentActionIndex++
+ }
+ }
+ }
+
+ if (!this.recordRoute) return
+ this.addRecordingPoint("interacts", { loc: pos, type: "interact" })
+ }
+
+ playSound(pos, name, volume, pitch, categoryName, event) {
+ if (!this.recordRoute) return
+
+ let loc = [pos.x, pos.y, pos.z]
+ let nameSplitted = name.split(".")
+ if (name === "mob.enderdragon.hit") { //etherwarp
+ this.addRecordingPoint("etherwarps", loc)
+ }
+ if (name === "random.explode" && pitch !== 1) { //tnt OR MIGHT BE spirit scepter
+ this.addRecordingPoint("tnts", loc)
+ }
+ if (name === "mob.bat.death") {
+ this.addRecordingPoint("interacts", { loc: loc, type: "bat" })
+ }
+ if (nameSplitted[0] === "dig") { //mining block
+ if (!this.recordingData[this.recordingData.length - 1].mines.some(a =>
+ a[0] === pos[0]
+ && a[1] === pos[1]
+ && a[2] === pos[2]
+ )) {
+ this.addRecordingPoint("mines", loc)
+ }
+ }
+ }
+
+ onDisable() {
+
+ }
+
+}
+
+module.exports = {
+ class: new DungeonRoutes()
+}
diff --git a/src/features/dungeonRoutes/metadata.json b/src/features/dungeonRoutes/metadata.json
new file mode 100644
index 0000000..c2f2a63
--- /dev/null
+++ b/src/features/dungeonRoutes/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Dungeon Routes",
+ "description": "Routes for dungeons (Coming soontm maby)",
+ "isHidden": false,
+ "isTogglable": true,
+ "defaultEnabled": true,
+ "sortA": 0
+} \ No newline at end of file
diff --git a/src/features/dungeonRoutes/routesData.json b/src/features/dungeonRoutes/routesData.json
new file mode 100644
index 0000000..d701fc7
--- /dev/null
+++ b/src/features/dungeonRoutes/routesData.json
@@ -0,0 +1,1296 @@
+[
+ {
+ "index": 84,
+ "data": [
+ {
+ "etherwarps": [
+ [
+ 23.5,
+ 83,
+ 12.5
+ ]
+ ],
+ "mines": [],
+ "locations": [
+ [
+ -4,
+ 68,
+ 16
+ ],
+ [
+ 23,
+ 83,
+ 13
+ ],
+ [
+ 24,
+ 84,
+ 13
+ ],
+ [
+ 24,
+ 85,
+ 13
+ ],
+ [
+ 25,
+ 85,
+ 13
+ ],
+ [
+ 25,
+ 84,
+ 12
+ ],
+ [
+ 25,
+ 84,
+ 11
+ ],
+ [
+ 26,
+ 84,
+ 11
+ ],
+ [
+ 27,
+ 84,
+ 9
+ ],
+ [
+ 26,
+ 84,
+ 6
+ ],
+ [
+ 23,
+ 84,
+ 5
+ ],
+ [
+ 19,
+ 84,
+ 5
+ ],
+ [
+ 19,
+ 85,
+ 5
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ 17.5,
+ 84,
+ 5.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [
+ [
+ -1.5,
+ 85,
+ 23.5
+ ]
+ ],
+ "mines": [
+ [
+ -2.5,
+ 84.5,
+ 23.5
+ ]
+ ],
+ "locations": [
+ [
+ 19,
+ 85,
+ 5
+ ],
+ [
+ 21,
+ 85,
+ 5
+ ],
+ [
+ 22,
+ 84,
+ 5
+ ],
+ [
+ 25,
+ 84,
+ 7
+ ],
+ [
+ 26,
+ 84,
+ 10
+ ],
+ [
+ 25,
+ 84,
+ 13
+ ],
+ [
+ 24,
+ 85,
+ 13
+ ],
+ [
+ 24,
+ 84,
+ 14
+ ],
+ [
+ 23,
+ 83,
+ 14
+ ],
+ [
+ -2,
+ 85,
+ 24
+ ],
+ [
+ -2,
+ 84,
+ 24
+ ],
+ [
+ -3,
+ 84,
+ 24
+ ],
+ [
+ -6,
+ 84,
+ 24
+ ],
+ [
+ -8,
+ 83,
+ 24
+ ],
+ [
+ -8,
+ 81,
+ 24
+ ],
+ [
+ -8,
+ 84,
+ 24
+ ],
+ [
+ -11,
+ 83,
+ 24
+ ],
+ [
+ -15,
+ 83,
+ 24
+ ],
+ [
+ -18,
+ 83,
+ 24
+ ],
+ [
+ -21,
+ 83,
+ 25
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ -21.5,
+ 83,
+ 25.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [
+ [
+ -18.5,
+ 91,
+ 24.5
+ ],
+ [
+ -9.5,
+ 83,
+ 2.5
+ ]
+ ],
+ "mines": [],
+ "locations": [
+ [
+ -21,
+ 83,
+ 25
+ ],
+ [
+ -19,
+ 92,
+ 25
+ ],
+ [
+ -19,
+ 91,
+ 25
+ ],
+ [
+ -17,
+ 91,
+ 22
+ ],
+ [
+ -17,
+ 91,
+ 21
+ ],
+ [
+ -15,
+ 91,
+ 18
+ ],
+ [
+ -16,
+ 91,
+ 21
+ ],
+ [
+ -16,
+ 91,
+ 19
+ ],
+ [
+ -15,
+ 90,
+ 17
+ ],
+ [
+ -15,
+ 88,
+ 16
+ ],
+ [
+ -14,
+ 86,
+ 13
+ ],
+ [
+ -15,
+ 86,
+ 10
+ ],
+ [
+ -15,
+ 84,
+ 8
+ ],
+ [
+ -15,
+ 83,
+ 6
+ ],
+ [
+ -16,
+ 83,
+ 4
+ ],
+ [
+ -10,
+ 84,
+ 3
+ ],
+ [
+ -10,
+ 83,
+ 3
+ ],
+ [
+ -8,
+ 83,
+ 3
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ -4.5,
+ 84,
+ 1.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [
+ [
+ -4.5,
+ 88,
+ 1.5
+ ],
+ [
+ -4.5,
+ 92,
+ 1.5
+ ]
+ ],
+ "mines": [],
+ "locations": [
+ [
+ -8,
+ 83,
+ 3
+ ],
+ [
+ -5,
+ 89,
+ 2
+ ],
+ [
+ -5,
+ 88,
+ 2
+ ],
+ [
+ -5,
+ 92,
+ 2
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ -4.5,
+ 93,
+ 1.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [],
+ "mines": [],
+ "locations": [
+ [
+ -5,
+ 92,
+ 2
+ ],
+ [
+ -8,
+ 92,
+ 2
+ ],
+ [
+ -11,
+ 92,
+ 1
+ ],
+ [
+ -11,
+ 96,
+ 1
+ ],
+ [
+ -11,
+ 97,
+ 1
+ ],
+ [
+ -13,
+ 96,
+ 1
+ ],
+ [
+ -13,
+ 97,
+ 1
+ ],
+ [
+ -13,
+ 96,
+ 1
+ ],
+ [
+ -13,
+ 92,
+ 1
+ ],
+ [
+ -13,
+ 92,
+ 2
+ ],
+ [
+ -13,
+ 92,
+ 1
+ ],
+ [
+ -13,
+ 93,
+ 1
+ ],
+ [
+ -13,
+ 92,
+ 1
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ -16.5,
+ 92,
+ 0.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [
+ [
+ -6.5,
+ 91,
+ 8.5
+ ]
+ ],
+ "mines": [],
+ "locations": [
+ [
+ -13,
+ 92,
+ 1
+ ],
+ [
+ -13,
+ 93,
+ 1
+ ],
+ [
+ -13,
+ 93,
+ 2
+ ],
+ [
+ -14,
+ 92,
+ 2
+ ],
+ [
+ -15,
+ 92,
+ 2
+ ],
+ [
+ -16,
+ 92,
+ 2
+ ],
+ [
+ -18,
+ 92,
+ 3
+ ],
+ [
+ -18,
+ 92,
+ 4
+ ],
+ [
+ -18,
+ 92,
+ 5
+ ],
+ [
+ -18,
+ 93,
+ 5
+ ],
+ [
+ -18,
+ 94,
+ 5
+ ],
+ [
+ -18,
+ 93,
+ 8
+ ],
+ [
+ -18,
+ 92,
+ 9
+ ],
+ [
+ -18,
+ 90,
+ 10
+ ],
+ [
+ -18,
+ 87,
+ 11
+ ],
+ [
+ -18,
+ 84,
+ 11
+ ],
+ [
+ -18,
+ 83,
+ 11
+ ],
+ [
+ -7,
+ 91,
+ 9
+ ],
+ [
+ -8,
+ 91,
+ 8
+ ],
+ [
+ -8,
+ 93,
+ 8
+ ],
+ [
+ -8,
+ 92,
+ 8
+ ],
+ [
+ -10,
+ 92,
+ 10
+ ],
+ [
+ -10,
+ 90,
+ 10
+ ],
+ [
+ -10,
+ 87,
+ 11
+ ],
+ [
+ -8,
+ 86,
+ 11
+ ],
+ [
+ -7,
+ 85,
+ 12
+ ],
+ [
+ -7,
+ 83,
+ 12
+ ],
+ [
+ -5,
+ 83,
+ 10
+ ],
+ [
+ -1,
+ 83,
+ 11
+ ],
+ [
+ 3,
+ 83,
+ 12
+ ],
+ [
+ 7,
+ 83,
+ 12
+ ],
+ [
+ 9,
+ 82,
+ 12
+ ],
+ [
+ 11,
+ 80,
+ 13
+ ],
+ [
+ 12,
+ 77,
+ 13
+ ],
+ [
+ 13,
+ 73,
+ 14
+ ],
+ [
+ 14,
+ 68,
+ 14
+ ],
+ [
+ 15,
+ 62,
+ 15
+ ],
+ [
+ 15,
+ 55,
+ 15
+ ],
+ [
+ 15,
+ 48,
+ 16
+ ],
+ [
+ 13,
+ 46,
+ 16
+ ],
+ [
+ 10,
+ 46,
+ 17
+ ],
+ [
+ 7,
+ 46,
+ 17
+ ],
+ [
+ 3,
+ 46,
+ 17
+ ],
+ [
+ -1,
+ 46,
+ 16
+ ],
+ [
+ -6,
+ 46,
+ 16
+ ],
+ [
+ -9,
+ 45,
+ 15
+ ],
+ [
+ -12,
+ 45,
+ 14
+ ],
+ [
+ -17,
+ 47,
+ 13
+ ],
+ [
+ -20,
+ 48,
+ 11
+ ],
+ [
+ -23,
+ 48,
+ 10
+ ],
+ [
+ -24,
+ 49,
+ 10
+ ],
+ [
+ -24,
+ 48,
+ 10
+ ],
+ [
+ -24,
+ 47,
+ 10
+ ],
+ [
+ -25,
+ 48,
+ 10
+ ],
+ [
+ -25,
+ 47,
+ 10
+ ],
+ [
+ -25,
+ 36,
+ 10
+ ],
+ [
+ -25,
+ 35,
+ 10
+ ],
+ [
+ -25,
+ 34,
+ 10
+ ],
+ [
+ -25,
+ 33,
+ 10
+ ],
+ [
+ -14,
+ 29,
+ 10
+ ],
+ [
+ -14,
+ 28,
+ 10
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ -9.5,
+ 28,
+ 9.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [],
+ "mines": [],
+ "locations": [
+ [
+ -14,
+ 28,
+ 10
+ ],
+ [
+ -25,
+ 34,
+ 10
+ ],
+ [
+ -25,
+ 35,
+ 10
+ ],
+ [
+ -25,
+ 36,
+ 10
+ ],
+ [
+ -25,
+ 47,
+ 10
+ ],
+ [
+ -25,
+ 48,
+ 10
+ ],
+ [
+ -24,
+ 48,
+ 10
+ ],
+ [
+ -24,
+ 49,
+ 10
+ ],
+ [
+ -23,
+ 48,
+ 10
+ ],
+ [
+ -21,
+ 48,
+ 10
+ ],
+ [
+ -20,
+ 47,
+ 10
+ ],
+ [
+ -19,
+ 47,
+ 11
+ ],
+ [
+ -20,
+ 47,
+ 10
+ ],
+ [
+ -20,
+ 47,
+ 9
+ ],
+ [
+ -14,
+ 48,
+ 1
+ ],
+ [
+ -13,
+ 48,
+ 0
+ ],
+ [
+ -14,
+ 49,
+ -3
+ ],
+ [
+ -15,
+ 49,
+ -7
+ ],
+ [
+ -15,
+ 49,
+ -11
+ ],
+ [
+ -14,
+ 49,
+ -15
+ ],
+ [
+ -13,
+ 49,
+ -19
+ ],
+ [
+ -13,
+ 49,
+ -23
+ ],
+ [
+ -13,
+ 50,
+ -24
+ ],
+ [
+ -13,
+ 50,
+ -26
+ ],
+ [
+ -13,
+ 50,
+ -28
+ ],
+ [
+ -11,
+ 50,
+ -27
+ ],
+ [
+ -9,
+ 50,
+ -27
+ ]
+ ],
+ "interacts": [
+ {
+ "loc": [
+ -3.5,
+ 50,
+ -26.5
+ ],
+ "type": "interact"
+ }
+ ],
+ "tnts": []
+ },
+ {
+ "etherwarps": [],
+ "mines": [],
+ "locations": [
+ [
+ -9,
+ 50,
+ -27
+ ],
+ [
+ -10,
+ 50,
+ -28
+ ],
+ [
+ -11,
+ 50,
+ -29
+ ],
+ [
+ -13,
+ 50,
+ -26
+ ],
+ [
+ -13,
+ 50,
+ -24
+ ],
+ [
+ -14,
+ 50,
+ -22
+ ],
+ [
+ -16,
+ 50,
+ -20
+ ],
+ [
+ -18,
+ 49,
+ -19
+ ],
+ [
+ -21,
+ 50,
+ -16
+ ],
+ [
+ -23,
+ 52,
+ -14
+ ],
+ [
+ -25,
+ 53,
+ -10
+ ],
+ [
+ -26,
+ 55,
+ -8
+ ],
+ [
+ -26,
+ 55,
+ -5
+ ],
+ [
+ -26,
+ 55,
+ -3
+ ],
+ [
+ -24,
+ 55,
+ -3
+ ],
+ [
+ -20,
+ 55,
+ -3
+ ],
+ [
+ -17,
+ 55,
+ -2
+ ],
+ [
+ -13,
+ 55,
+ -2
+ ],
+ [
+ -10,
+ 55,
+ -3
+ ],
+ [
+ -9,
+ 55,
+ -2
+ ],
+ [
+ -9,
+ 67,
+ -7
+ ],
+ [
+ -9,
+ 66,
+ -7
+ ],
+ [
+ -9,
+ 68,
+ -9
+ ],
+ [
+ -9,
+ 69,
+ -12
+ ],
+ [
+ -10,
+ 69,
+ -16
+ ],
+ [
+ -14,
+ 69,
+ -17
+ ],
+ [
+ -16,
+ 69,
+ -17
+ ],
+ [
+ -17,
+ 69,
+ -17
+ ],
+ [
+ -18,
+ 69,
+ -16
+ ]
+ ],
+ "interacts": [],
+ "tnts": []
+ }
+ ]
+ },
+ {
+ "index": 12,
+ "data": [
+ {
+ "etherwarps": [
+ [
+ 2.5,
+ 80,
+ -1.5
+ ]
+ ],
+ "mines": [
+ [
+ 1.5,
+ 83.5,
+ -0.5
+ ]
+ ],
+ "locations": [
+ [
+ -7,
+ 69,
+ 3
+ ],
+ [
+ -6,
+ 69,
+ 3
+ ],
+ [
+ -3,
+ 69,
+ 0
+ ],
+ [
+ -1,
+ 69,
+ -2
+ ],
+ [
+ 0,
+ 69,
+ -4
+ ],
+ [
+ 1,
+ 69,
+ -5
+ ],
+ [
+ 3,
+ 69,
+ -7
+ ],
+ [
+ 3,
+ 69,
+ -10
+ ],
+ [
+ 5,
+ 69,
+ -12
+ ],
+ [
+ 8,
+ 69,
+ -12
+ ],
+ [
+ 11,
+ 69,
+ -10
+ ],
+ [
+ 11,
+ 69,
+ -8
+ ],
+ [
+ 11,
+ 69,
+ -9
+ ],
+ [
+ 10,
+ 69,
+ -12
+ ],
+ [
+ 7,
+ 69,
+ -12
+ ],
+ [
+ 3,
+ 69,
+ -11
+ ],
+ [
+ 2,
+ 69,
+ -8
+ ],
+ [
+ 1,
+ 69,
+ -4
+ ],
+ [
+ 1,
+ 69,
+ -3
+ ],
+ [
+ 2,
+ 69,
+ -3
+ ],
+ [
+ 2,
+ 80,
+ -1
+ ],
+ [
+ 1,
+ 80,
+ 0
+ ],
+ [
+ 1,
+ 80,
+ 1
+ ],
+ [
+ 1,
+ 80,
+ 0
+ ],
+ [
+ 1,
+ 80,
+ 1
+ ],
+ [
+ 0,
+ 80,
+ 3
+ ],
+ [
+ -1,
+ 78,
+ 5
+ ],
+ [
+ -2,
+ 76,
+ 5
+ ],
+ [
+ -3,
+ 75,
+ 5
+ ],
+ [
+ -4,
+ 73,
+ 5
+ ],
+ [
+ -4,
+ 70,
+ 5
+ ],
+ [
+ -5,
+ 69,
+ 5
+ ]
+ ],
+ "interacts": [],
+ "tnts": [
+ [
+ 3.5,
+ 70.5,
+ -7.5
+ ]
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file