· 6 years ago · Dec 31, 2019, 03:00 PM
1// ==UserScript==
2// @name minimap test
3// @namespace http://tampermonkey.net/
4// @version 0.1
5// @description try to take over the world!
6// @author You
7// @match http://*.margonem.pl/
8// @grant none
9// ==/UserScript==
10
11//3.3.1 - dodanie przycisku otwierania mapy na konsoli PS4 (Mozilla/5.0 (PlayStation 4 7.00) AppleWebKit/605.1.15 (KHTML, like Gecko))
12//3.3 - naprawiony bug z nieĹadowaniem postaci gracza po wejĹciu na nowÄ
mapÄ do momentu zrobienia kroku, dodano "mas/exit-h64c.gif" to listy grafik npc-drzwi, dodano pokazywanie "mgĹy wojny"
13//3.2
14//-(SI) ppm na gracza na minimapie -> menu takie jakie by siÄ otworzyĹo po klikniÄciu na mapie
15//-kompatybilnoĹÄ z dodatkiem ccarderra pokazujÄ
cym graczy z innych ĹwiatĂłw
16//-naprawiony bug z grobami
17//3.1.9b - nowe respy
18//3.1.9 - oczywiĹcie Ĺźe 3.1.8 coĹ popsuĹo :^)
19//3.1.8 - uzupeĹniono elity do questa dziennego na .com
20//3.1.7 - czemu kaĹźdÄ
aktualizacjÄ
coĹ psujÄ
21//3.1.6 - to coĹ z cookie __mExts i kompatybilnoĹÄ z jednÄ
rzeczÄ
ktĂłrÄ
robiÄ (w wersji 2.x byĹa ale zapomniaĹem robiÄ
c 3.0)
22//3.1.5 - wersja na stary silnik xd
23//3.1.4 - ciÄ
gle coĹ psujÄ
24//3.1.3 - ._.' warto uĹźywaÄ isset
25//3.1.2 - zmiany w chodzeniu postaci po klikniÄciu punktu na mapie (teraz moze iĹÄ gdziekolwiek sie kliknie), optymalizacje dla urzÄ
dzeĹ mobilnych (toucheventy majÄ
mniejsze opóźnienie)
26//3.1.1 - naprawa gĹupiego bĹÄdu prezez ktĂłry minimapa psuĹa grÄ
27//3.1 - pokazywanie qm przy npc na minimapie, poprawione wartoĹci przy ktĂłrych elementy dolnego paska sÄ
chowane, licznik instalacji (przez dislike niepublicznego dodatku)
28//3.0 - dodatek napisany od nowa
29class AStar{
30 constructor(collisionsString, width, height, start, end , additionalCollisions){
31 this.width = width;
32 this.height = height;
33 this.collisions = this.parseCollisions(collisionsString, width, height);
34 this.additionalCollisions = additionalCollisions || {};
35 this.start = this.collisions[start.x][start.y];
36 this.end = this.collisions[end.x][end.y];
37 this.start.beginning = true;
38 this.start.g = 0;
39 this.start.f = heuristic(this.start,this.end);
40 this.end.target = true;
41 this.end.g = 0;
42 //if(this.start.collision) throw new Error('Start point cannot be a collision!');
43 //if(this.end.collision) throw new Error('End point cannot be a collision!');
44 this.addNeighbours();
45 this.openSet = [];
46 this.closedSet = [];
47 this.openSet.push(this.start);
48 }
49
50 parseCollisions(collisionsString, width, height){
51 const collisions = new Array(width);
52 for(let w = 0; w < width; w++){
53 collisions[w] = new Array(height);
54 for(let h = 0; h < height; h++){
55 collisions[w][h] = new Point(w, h, collisionsString.charAt(w+h*width) === '1');
56 }
57 }
58 return collisions;
59 }
60
61 addNeighbours(){
62 for(let i = 0; i < this.width; i++){
63 for(let j = 0; j < this.height; j++){
64 this.addPointNeighbours(this.collisions[i][j])
65 }
66 }
67 }
68
69 addPointNeighbours(point){
70 const x = point.x, y = point.y;
71 const neighbours = [];
72 if(x > 0) neighbours.push(this.collisions[x-1][y]);
73 if(y > 0) neighbours.push(this.collisions[x][y-1]);
74 if(x < this.width - 1) neighbours.push(this.collisions[x+1][y]);
75 if(y < this.height -1) neighbours.push(this.collisions[x][y+1]);
76 point.neighbours = neighbours;
77 }
78
79 anotherFindPath(){
80 while(this.openSet.length > 0){
81 let currentIndex = this.getLowestF();
82 let current = this.openSet[currentIndex];
83 if(current === this.end) return this.reconstructPath();
84 else{
85 this.openSet.splice(currentIndex,1);
86 this.closedSet.push(current);
87 for(const neighbour of current.neighbours){
88 if(this.closedSet.includes(neighbour)) continue;
89 else{
90 const tentative_score = current.g + 1;
91 let isBetter = false;
92 if(this.end == this.collisions[neighbour.x][neighbour.y] || (!this.openSet.includes(neighbour) && !neighbour.collision && !this.additionalCollisions[neighbour.x+256*neighbour.y])){
93 this.openSet.push(neighbour);
94 neighbour.h = heuristic(neighbour, this.end);
95 isBetter = true;
96 }else if(tentative_score < neighbour.g && !neighbour.collision){
97 isBetter = true;
98 }
99 if(isBetter){
100 neighbour.previous = current;
101 neighbour.g = tentative_score;
102 neighbour.f = neighbour.g + neighbour.h;
103 }
104 }
105 }
106 }
107 }
108 }
109
110 getLowestF(){
111 let lowestFIndex = 0;
112 for(let i = 0; i< this.openSet.length; i++){
113 if(this.openSet[i].f < this.openSet[lowestFIndex].f) lowestFIndex = i;
114 }
115 return lowestFIndex;
116 }
117
118 reconstructPath(){
119 const path = [];
120 let currentNode = this.end;
121 while(currentNode !== this.start){
122 path.push(currentNode);
123 currentNode = currentNode.previous;
124 }
125 return path;
126 }
127 }
128
129 class Point{
130 constructor(x, y, collision){
131 this.x = x;
132 this.y = y;
133 this.collision = collision;
134 this.g = 10000000;
135 this.f = 10000000;
136 this.neighbours = [];
137 this.beginning = false;
138 this.target = false;
139 this.previous = undefined;
140 }
141 }
142 function heuristic(p1, p2){
143 return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
144 }
145
146 function getWay(x,y, point){
147 return (new AStar(map.col, map.x, map.y, {x: point.x, y: point.y}, {x: x, y: y}, g.npccol)).anotherFindPath();
148 }
149 var debug = false;
150 function goToo(x,y){
151 let _road_ = getWay(x,y,hero);
152 console.log(_road_);
153 if(!Array.isArray(_road_)) return;
154 window.road = _road_;
155 }
156
157
158window.miniMapPlus = new (function() {
159 var interface = (function() {
160 if (typeof API != "undefined" && typeof Engine != "undefined" && typeof margoStorage == "undefined") {
161 return "new"; //NI
162 } else if (typeof dbget == "undefined" && typeof proceed == "undefined") {
163 return "old"; //SI
164 } else {
165 return "superold"; //Stary silnik
166 };
167 })();
168 var self = this;
169 var masks = ["obj/cos.gif", "mas/nic32x32.gif", "mas/nic64x64.gif"];
170 var gws = ["mas/exit-ith.gif", "mas/exit-ith1.gif", "mas/exit.gif", "mas/drzwi.gif", "obj/drzwi.gif", "mas/exit-h64c.gif"];
171 var oldPos = {x: -1, y: -1};
172 var otherRanks = ["Administrator", "Super Mistrz Gry", "Mistrz Gry", "Moderator Chatu", "Super Moderator Chatu"];
173 var $map,
174 $wrapper,
175 $info,
176 $search,
177 $userStyle,
178 objScale,
179 objSize,
180 $chatInput,
181 $searchTxt;
182 var search = {
183 type: "",
184 data: ""
185 };
186 var manualMode = false;
187 var innerDotKeys = ["friend", "enemy", "clan", "ally"];
188 this.version = "3.3";
189
190 var settings = new (function() {
191 var path = "mmp";
192 var Storage = interface != "old" ? API.Storage : margoStorage;
193 this.set = function(p, val) {
194 Storage.set(path + p, val);
195 };
196 this.get = function(p) {
197 return Storage.get(path + p);
198 };
199 this.remove = function(p) {
200 try {
201 Storage.remove(path + p);
202 } catch (e) {};
203 };
204 this.exist = function() {
205 return Storage.get(path) != null;
206 };
207 })();
208
209 let mobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
210 let consoleDevice = (/PlayStation 4/i).test(navigator.userAgent) || settings.get("/forceMobileMode"); // TODO: add more consoles
211
212 const $visibility = (function() {
213 let $div = document.createElement("div");
214 $div.classList.add("mmp-visibility");
215 return $div;
216 })();
217
218 this.initSettings = function() {
219 if (!settings.exist()) {
220 this.setDefaultSettings();
221 } else {
222 this.fixSettings();
223 };
224 };
225
226 this.fixSettings = function() {
227 var loaded = settings.get("");
228 var def = this.getDefaultSettings();
229 var overwrite = false;
230 for (var key in def) {
231 if (!isset(loaded[key])) {
232 loaded[key] = def[key];
233 overwrite = true;
234 };
235 };
236 if (overwrite) settings.set("", loaded);
237 };
238
239 this.setDefaultSettings = function() {
240 settings.set("", this.getDefaultSettings());
241 };
242
243 this.convertOldSettings = function(json) {
244 var sett = JSON.parse(json);
245 sett.darkmode = false;
246 sett.altmobilebtt = false;
247 sett.mapsize = 1;
248 sett.minlvl = parseInt(sett.minlvl);
249 sett.opacity = 1 - sett.opacity;
250 if (isNaN(sett.minlvl)) sett.minlvl = 1;
251 localStorage.removeItem("miniMapPlus");
252 return sett;
253 };
254
255 this.getDefaultSettings = function() {
256 var oldVersion = localStorage.getItem("miniMapPlus");
257 if (oldVersion) return this.convertOldSettings(oldVersion);
258 return {
259 show: 82,
260 minlvl: "1",
261 colors: {
262 hero: "#FF0000",
263 other: "#FFFFFF",
264 friend: "#08ad00",
265 enemy: "#FF0000",
266 clan: "#08ad00",
267 ally: "#9eff91",
268 npc: "#ddff00",
269 mob: "#222222",
270 elite: "#00ffe9",
271 elite2: "#039689",
272 elite3: "#007500",
273 heros: "#c6ba35",
274 titan: "#809912",
275 item: "#f56bff",
276 gw: "#0000FF",
277 },
278 trackedNpcs: [],
279 trackedItems: [],
280 maxlvl: 13,
281 mapsize: 1,
282 opacity: 1,
283 interpolerate: true,
284 darkmode: false,
285 showqm: true,
286 showevonetwork: true
287 };
288 };
289
290 this.getInstallSource = function() {
291 if (interface != "old") return "addon";
292 var panelAddons = getCookie("__mExts");
293 if (panelAddons == null) return "addon";
294 var srcs = {
295 p: "panel dodatkĂłw (pub.)",
296 d: "dev",
297 v: "panel dodatkĂłw"
298 };
299 for (var i in srcs) {
300 if (panelAddons.indexOf(i+"64196") > -1) return srcs[i];
301 };
302 return "addon";
303 };
304
305 this.initHTML = function() {
306 $wrapper = document.createElement("div");
307 $wrapper.classList.add("mmpWrapper");
308
309 $map = document.createElement("div");
310 $map.classList.add("mmpMap");
311 if (!mobileDevice) $map.addEventListener("click", this.goTo);
312 else $map.addEventListener("touchstart", this.goTo);
313 $map.addEventListener("contextmenu", this.rclick);
314
315 var $bottombar = document.createElement("div");
316 $bottombar.classList.add("mmpBottombar");
317 $info = document.createElement("span");
318 $info.innerHTML = "miniMapPlus by <a href='https://www.margonem.pl/?task=profile&id=3779166' target='_blank'>Priweejt</a> | ";
319 $bottombar.appendChild($info);
320 $searchTxt = document.createElement("span");
321 $searchTxt.innerHTML = "Szukaj: ";
322 $bottombar.appendChild($searchTxt);
323 $search = document.createElement("input");
324 $search.addEventListener("keyup", this.searchBarHandler);
325 $bottombar.appendChild($search);
326 var $settings = document.createElement("img");
327 $settings.src = "http://i.imgur.com/S7FugOv.png";
328 $settings.classList.add("mmpSettingIcon");
329 $settings.addEventListener("click", niceSettings.toggle);
330 $settings.setAttribute(interface == "new" ? "data-tip" : "tip", "Ustawienia");
331 $bottombar.appendChild($settings);
332
333 $wrapper.appendChild($map);
334 $wrapper.appendChild($bottombar);
335
336 if (interface == "new") document.querySelector(".game-window-positioner").appendChild($wrapper);
337 else if (interface == "old") document.querySelector("#centerbox2").appendChild($wrapper);
338 else document.querySelector("body").appendChild($wrapper);
339
340 this.appendMainStyles();
341 this.initEventListener();
342 };
343
344 this.appendMobileButton = function() {
345 if (interface == "old" && (mobileDevice || consoleDevice)) {
346 //przycisk otwierania mapy dla urzÄ
dzeĹ mobilnych/konsol
347 var $btt = document.createElement("div");
348 $btt.innerHTML = "MM+";
349 $btt.classList.add("mmpMobileButton");
350 $btt.addEventListener(mobileDevice ? "touchstart" : "click", event => {
351 self.toggleView();
352 event.preventDefault();
353 });
354 document.getElementById("centerbox2").appendChild($btt);
355 };
356 };
357
358 this.initEventListener = function() {
359 document.addEventListener("keydown", function(e) {
360 if (e.target.tagName != "INPUT" && e.target.tagName != "TEXTAREA" && e.keyCode == settings.get("/show")) {
361 self.toggleView();
362 };
363 }, false);
364 };
365
366 this.appendMainStyles = function() {
367 var $style = document.createElement("style");
368 var css = `
369 .mmpMobileButton {
370 z-index: 390;
371 border: 1px solid black;
372 opacity: 0.7;
373 background: white;
374 position: absolute;
375 top: 240px;
376 left: -1px;
377 width: 32px;
378 height: 32px;
379 color: gray;
380 text-align: center;
381 line-height: 32px;
382 font-size: 80%;
383 border-radius: 3px;
384 border-top-right-radius: 8px;
385 }
386 .mmpWrapper {
387 position: absolute;
388 z-index: 380;
389 border: 3px solid black;
390 border-radius: 5px;
391 border-bottom-left-radius: 20px;
392 overflow: hidden;
393 display: none;
394 }
395 .mmpWrapper .mmpMap {
396 overflow: hidden;
397 background-size: 100%;
398 position: relative;
399 }
400 .mmpWrapper .mmpBottombar {
401 height: 19px;
402 background: #CCCCCC;
403 border-top: 1px solid black;
404 color: #232323;
405 padding-left: 8px;
406 line-height: 19px;
407 }
408 .mmpWrapper .mmpBottombar input {
409 height: 11px;
410 width: 130px;
411 }
412 .mmpWrapper .mmpBottombar .mmpSettingIcon {
413 height: 15px;
414 width: 15px;
415 float: right;
416 background: rgba(100,100,100,.8);
417 border-radius: 5px;
418 cursor: pointer;
419 margin-top: 2px;
420 }
421 .mmpMapObject {
422 position: absolute;
423 }
424 .mmpMapObject.hidden {
425 display: none;
426 }
427 .mmpMapObject.hiddenBySearch {
428 display: none;
429 }
430 .mmpMapObject .innerDot{
431 position: absolute;
432 }
433 .mmpMapObject.evoNetwork {
434 opacity: 0.5 !important;
435 }
436 .mmp-visibility {
437 pointer-events: none;
438 border: 1px solid yellow;
439 box-sizing: border-box;
440 }
441 `;
442 $style.innerHTML = css;
443 document.head.appendChild($style);
444 };
445
446 this.onSettingsUpdate = function() {
447 self.appendUserStyles();
448 self.objectMgr.manageDisplay();
449 self.resetQtrack();
450 message("<span style='color:white;'>Zapisano</span>");
451 };
452
453 this.appendUserStyles = function() {
454 if (!$userStyle) {
455 $userStyle = document.createElement("style");
456 document.head.appendChild($userStyle);
457 };
458 $userStyle.innerHTML = this.generateUserCss();
459 };
460
461 this.generateUserCss = function() {
462 var css = "";
463 var colors = settings.get("/colors");
464 for (var name in colors) {
465 css += this.getSingleCssLine(name, colors[name]);
466 };
467 css += ".mmpWrapper { opacity: "+settings.get("/opacity")+"; }\n"
468 if (settings.get("/interpolerate")) css += ".mmpMapObject { transition: all .5s ease-in-out; }\n";
469 if (settings.get("/darkmode")) {
470 css += ".mmpWrapper .mmpBottombar { background: #222222; color: #CCCCCC; }\n";
471 css += ".mmpWrapper .mmpBottombar input {background: black; border: 1px solid #333333; color: white;}\n";
472 css += ".mmpWrapper .mmpBottombar a {color: #009c9c;}\n"
473 css += ".mmpMobileButton {background: #222222; color: #CCCCCC;}\n"
474 };
475 if (settings.get("/altmobilebtt")) {
476 css += ".mmpMobileButton { top: 470px; left: 665px; }\n";
477 };
478 if (!settings.get("/showqm")) {
479 css += ".mmpQM { display: none; }\n";
480 } else {
481 css += ".mmpQM { display: block; position: absolute; top: -200%;}\n";
482 };
483 if (settings.get("/novisibility")) {
484 css += ".mmp-visibility { display: none }";
485 }
486
487 return css;
488 };
489
490 this.getSingleCssLine = function(name, val) {
491 if (innerDotKeys.indexOf(name) > -1) {
492 return ".mmpMapObject .innerDot.mmp-"+name+" { background: "+val+";}\n";
493 } else {
494 return ".mmpMapObject.mmp-"+name+" { background: "+val+";}\n";
495 };
496 };
497
498 //functionality
499 this.rclick = function(e) {
500 if (interface != "old") return; //TODO: support other interfaces
501 var tar = false
502 if (e.target.classList.contains("mmp-other")) tar = e.target;
503 else if (e.target.parentElement.classList.contains("mmp-other")) tar = e.target.parentElement; //for others with innerdot
504 if (tar) {
505 var obj = self.objectMgr.getByElem(tar);
506 if (obj.d.evoNetwork) return;
507 var id = obj.d.id;
508 id = id.split("-")[1]; //id = OTHER-rid, where rid = char id of the other player
509 var $other = document.querySelector("#other"+id);
510 //hacky solution
511 var sm = window.showMenu;
512 var otherMenu = false;
513 window.showMenu = function(e, menu) {
514 otherMenu = menu;
515 window.showMenu = sm;
516 };
517 $other.click();
518 if (otherMenu) {
519 for (var i in otherMenu) {
520 //idk it doesn't hide automatically for whatever reason (I mean it does, but only after it has been clicked 2 times)
521 otherMenu[i][1] += ";hideMenu();";
522 };
523 window.showMenu(e, otherMenu, true);
524 };
525 e.preventDefault();
526 };
527 };
528
529 this.goTo = function(e) {
530 if (e.type == "touchstart") {
531 var offsets = self.getOffsets(e.target);
532 e.offsetX = e.touches[0].pageX - offsets[0];
533 e.offsetY = e.touches[0].pageY - offsets[1];
534 e.stopPropagation();
535 };
536
537 var coords = self.getCoordsFromEvent(e);
538 if (interface == "new") {
539 Engine.hero.autoGoTo({x: coords.x, y: coords.y});
540 } else if (interface == "old") {
541 goToo(coords.x, coords.y);
542 } else {
543 self.oldMargoGoTo(coords.x, coords.y);
544 };
545 };
546
547 this.oldMargoGoTo = function(x, y) {
548 //window,hero.setMousePos(x*32,y*32);
549 window.hero.mx = x;
550 window.hero.my = y;
551 window.global.movebymouse = true;
552 this.cancelMouseMovement = true;
553 };
554
555 this.getCoordsFromEvent = function(e) {
556 if (e.target == $map) {
557 return {
558 x: Math.round(e.offsetX/(objScale*32)),
559 y: Math.round(e.offsetY/(objScale*32))
560 };
561 } else {
562 var obj = this.objectMgr.getByElem(e.target);
563 return {
564 x: obj.d.x,
565 y: obj.d.y
566 };
567 };
568 };
569
570 this.getOffsets = function($el, offs) {
571 var offsets = offs ? offs : [0,0];
572 offsets[0] += $el.offsetLeft;
573 offsets[1] += $el.offsetTop;
574 if ($el.parentElement != null) {
575 this.getOffsets($el.parentElement, offsets);
576 };
577 return offsets;
578 };
579
580 this.searchBarHandler = function(e) {
581 //keyup event handler
582 var input = $search.value;
583 var noSpace = input.replace(/ /g, "");
584 self.objectMgr.resetSearch();
585 if (/([0-9]+)-([0-9]+)/.test(noSpace)) {
586 self.parseRangeSearch(noSpace);
587 } else if (/([0-9]+),([0-9]+)/.test(noSpace)) {
588 self.parseCoordSearch(noSpace);
589 } else {
590 self.parseStringSearch(input);
591 };
592 };
593 this.parseRangeSearch = function(str) {
594 var nums = str.split("-");
595 this.objectMgr.filterByLvl(parseInt(nums[0]), parseInt(nums[1]));
596 };
597 this.parseCoordSearch = function(str) {
598 var coords = str.split(",");
599 this.objectMgr.createCoordMarker(parseInt(coords[0]), parseInt(coords[1]));
600 };
601 this.parseStringSearch = function(str) {
602 this.objectMgr.filterByString(str);
603 };
604
605 this.makeTip = function(data) {
606 var tip = data.nocenter ? "" : "<center>";
607 tip += data.txt+"<div style='text-align: center;color: gray'>("+data.x+","+data.y+")</div>";
608 return tip + (data.nocenter ? "" : "</center>");
609 };
610
611 this.toggleView = function() {
612 $wrapper.style["display"] = $wrapper.style["display"] == "block" ? "none" : "block";
613 };
614
615 this.initResponseParser = function() {
616 if (interface == "new") {
617 API.priw.emmiter.on("before-game-response", data => {
618 if (!manualMode) this.parseInput(data);
619 })
620 } else if (interface == "old") {
621 var _parseInput = parseInput;
622 parseInput = function(data) {
623 if (!manualMode) self.parseInput(data);
624 return _parseInput.apply(this, arguments);
625 };
626 } else {
627 API.emmiter.on("response", data => {
628 if (!manualMode) self.parseInput(self.parseOldMargonemData(data));
629 })
630 };
631 };
632
633 self.arr2obj = function(arr) {
634 var ret = {};
635 for (var i=0; i<arr.length; i++) {
636 ret[arr[i].id] = arr[i];
637 };
638 return ret;
639 };
640
641 self.parseOldMargonemData = function(data) {
642 //data.gw2 = [];
643 //data.townname = {};
644 /*if (data.elements) {
645 if (data.elements.npc) Object.assign(data.npc, this.arr2obj(data.elements.npc));
646 if (data.elements.other) Object.assign(data.other, this.arr2obj(data.elements.other));
647 }
648 if (data.delete) {
649 if (data.delete.npc) Object.assign(data.npc, this.arr2obj(data.delete.npc));
650 if (data.delete.other) Object.assign(data.other, this.arr2obj(data.delete.other));
651 }
652 if (data.othermove) {
653 Object.assign(data.other, this.arr2obj(data.othermove));
654 console.log(data.othermove);
655 };*/
656 return data;
657 };
658
659 this.enableManualMode = function() { //tryb w ktĂłrym ignoruje wszystkie dane z silnika gry; na potrzeby mojego dodatku klanowego
660 manualMode = true;
661 };
662 this.disableManualMode = function() {
663 manualMode = false;
664 };
665
666 this.parseInput = function(data) {
667 for (var i in data) {
668 if (typeof this.eventHandlers[i] == "function") this.eventHandlers[i](data[i]);
669 };
670 if (data.townname) this.eventHandlers.gateways(data.gw2, data.townname);
671 };
672
673 this.eventHandlers = {
674 town: function(town) {
675 self.loadMap(town);
676 },
677 npc: function(npc) {
678 self.parseNpc(npc);
679 },
680 gateways: function(gws, townname) {
681 self.parseGws(gws, townname);
682 },
683 other: function(others) {
684 self.parseOther(others);
685 },
686 item: function(items) {
687 self.parseItem(items);
688 },
689 rip: function(rip) {
690 self.parseRip(rip);
691 }
692 };
693
694 this.resetQtrack = function() {
695 qTrack.reset();
696 var npc = settings.get("/trackedNpcs");
697 for (var i=0; i<npc.length; i++) {
698 qTrack.add({
699 type: "NPC",
700 name: npc[i]
701 });
702 };
703 var item = settings.get("/trackedItems");
704 for (i=0; i<item.length; i++) {
705 qTrack.add({
706 type: "ITEM",
707 name: item[i]
708 });
709 };
710 };
711
712 this.loadMap = function(town) {
713 if (interface == "superold") town.file = town.img;
714 this.resetQtrack();
715 this.objectMgr.deleteAll();
716 var mapsize = interface == "new" ? 700 : 440;
717 mapsize = mapsize*settings.get("/mapsize");
718 if (town.x > town.y) {
719 var height = Math.floor(town.y/town.x * mapsize);
720 var width = mapsize;
721 } else {
722 var width = Math.floor(town.x/town.y * mapsize);
723 var height = mapsize;
724 };
725 objScale = width/(town.x*32);
726 objSize = Math.round(objScale*32);
727
728 var left = 0;
729 var top = 0;
730 if (interface != "new") {
731 top = -30;
732 left = -144;
733 };
734
735 Object.assign($wrapper.style, {
736 //$map will stretch the $wrapper
737 //width: width + "px",
738 //height: (height+20) + "px",
739 left: "calc(50% - "+(width/2 - left)+"px)",
740 top: "calc(50% - "+(height/2 - top)+"px)"
741 });
742 Object.assign($map.style, {
743 width: width + "px",
744 height: height + "px",
745 });
746 if (width < 385) $info.style["display"] = "none";
747 else $info.style["display"] = "inline-block";
748 if (width < 210) $searchTxt.style["display"] = "none";
749 else $searchTxt.style["display"] = "inline-block";
750
751 this.loadMapImg(town.file);
752 if (interface != "superold") {
753 this.addSpawnsToMap(herosDB, true, town.name, town.id);
754 this.addSpawnsToMap(eliteDB, false, town.name, town.id);
755 };
756 this.updateVisibility(town.visibility, objScale);
757 this.updateHero(true);
758 };
759
760 this.updateVisibility = function(n, scale) {
761 if (n) {
762 let size = (n*2 + 1)*scale*32;
763 Object.assign($visibility.style, {
764 width: size + "px",
765 height: size + "px",
766 "margin-top": (size/-2) + "px",
767 "margin-left": (size/-2) + "px",
768 opacity: 1
769 });
770 } else {
771 $visibility.style.opacity = 0;
772 }
773 }
774
775 this.loadMapImg = function(file) {
776 $map.style["background-image"] = "";
777 $map.style["background"] = "#444444";
778 var miniMapImg = new Image();
779 if (file.indexOf("http") == -1) {
780 var mpath = interface == "old" ? g.mpath : "/obrazki/miasta/";
781 miniMapImg.src = (interface == "superold" ? "http://oldmargonem.pl" : "") + mpath + file;
782 } else {
783 miniMapImg.src = file;
784 };
785 miniMapImg.onload = function() {
786 $map.style["background"] = "";
787 $map.style["background-image"] = "url("+miniMapImg.src+")";
788 };
789 };
790
791 this.parseNpc = function(npcs) {
792 for (var id in npcs) {
793 var npc = npcs[id];
794 if (!npc.del) {
795 this.addNewNpcToMap(npc, id);
796 } else {
797 this.objectMgr.updateObject({
798 id: "NPC-"+id,
799 del: 1
800 });
801 if (npcTrack[id]) {
802 qTrack.remove({
803 type: "NPC",
804 nick: npcTrack[id].nick
805 });
806 delete npcTrack[id];
807 };
808 };
809 };
810 };
811 this.addNewNpcToMap = function(npc, id) {
812 var {type, flash} = this.getNpcType(npc, id);
813 if (type == undefined) return;
814 var {tip, ctip} = this.getNpcTip(npc, type, flash);
815 var data = {
816 id: "NPC-"+id,
817 type: type,
818 flash: flash,
819 tip: tip,
820 ctip: ctip,
821 x: npc.x,
822 y: npc.y,
823 qm: npc.qm || (npc.actions && npc.actions & 128)
824 };
825 if (type != "npc" && type != "gw" && type != "item") {
826 data.lvl = npc.lvl;
827 };
828 this.objectMgr.updateObject(data)
829 };
830 this.getNpcTip = function(npc, type, important) {
831 var tip = "";
832 var mask = false;
833 for (var i=0; i<masks.length; i++) {
834 if (masks[i].indexOf(npc.icon) > -1) mask = true;
835 };
836 if (!mask) tip += "<img src='"+this.npcIconHTML(npc.icon)+"'>";
837 var ctip = "t_npc";
838 if (type == "gw") {
839 ctip = false;
840 tip = this.makeTip({
841 txt: npc.nick + "<br>",
842 x: npc.x,
843 y: npc.y
844 })
845 } else if (type == "item") {
846 ctip = "t_item";
847 tip = this.makeTip({
848 x: npc.x,
849 y: npc.y,
850 txt: tip + "<br>" + npc.nick
851 })
852 } else {
853 tip = this.normalNpcTip(npc, type, important, tip);
854 };
855 return {
856 tip: tip,
857 ctip: ctip
858 }
859 };
860 this.npcIconHTML = function(icon) {
861 if (icon.indexOf("://") > -1 || icon.indexOf("obrazki/") > -1) return icon; //zapomniaĹem o kompatybilnoĹci z jednÄ
rzeczÄ
ktĂłrÄ
robiÄ xd
862 else if (interface == "superold") return "http://oldmargonem.pl/obrazki/npc/"+icon;
863 else return (interface == "old" ? g.opath : "/obrazki/")+"npc/"+icon;
864 };
865 this.oldNpcTip = function(npc, type, eve) {
866 var icon = npc.icon;
867 npc.icon = "kappa";
868 if (type == "elite2" && !eve) {
869 npc.wt = 30;
870 };
871
872 if (!g.tips.npc) newNpc();
873 var tip = g.tips.npc(npc);
874
875 if (type == "elite2") {
876 if (!eve) {
877 npc.wt = 20;
878 tip = tip.replace("elita III", "elita II");
879 } else {
880 tip = tip.replace("elita", "specjalna elita");
881 };
882 };
883 npc.icon = icon;
884 return typeof tip == "string" ? tip : "";
885 };
886 this.newNpcTip = function(npc, type, eve) {
887 var nick = "<div><strong>"+npc.nick+"</strong></div>";
888 switch (type) {
889 case "titan":
890 var type = "<i>tytan</i>";
891 break;
892 case "heros":
893 var type = "<i>heros</i>";
894 break;
895 case "elite3":
896 var type = "<i>elita III</i>";
897 break;
898 case "elite2":
899 if (eve) {
900 var type = "<i>specjalna elita</i>";
901 } else {
902 var type = "<i>elita II</i>";
903 }
904 break;
905 case "elite":
906 var type = "<i>elita</i>";
907 break;
908 default:
909 var type = "";
910 break;
911 };
912 var lvl = npc.lvl ? npc.lvl + " lvl" : "";
913 var grp = npc.grp ? " grp" : "";
914 var lvlgrp = "<span>"+lvl+grp+"</span>";
915 return nick + type + lvlgrp;
916 };
917 this.oldMargoNpcTip = function(npc, type, eve) {
918 var nick = "<b style='color:orange;'>"+npc.nick+"</b>";
919 switch (type) {
920 case "titan":
921 var type = "<i>tytan</i><br>";
922 break;
923 case "heros":
924 var type = "<i>heros</i><br>";
925 break;
926 case "elite3":
927 var type = "<i>elita III</i><br>";
928 break;
929 case "elite2":
930 if (eve) {
931 var type = "<i>specjalna elita</i><br>";
932 } else {
933 var type = "<i>elita II</i><br>";
934 }
935 break;
936 case "elite":
937 var type = "<i>elita</i><br>";
938 break;
939 default:
940 var type = "";
941 break;
942 };
943 var lvl = npc.lvl ? "Lvl: "+npc.lvl : "";
944 var grp = npc.grp ? " grp" : "";
945 var lvlgrp = "<span>"+lvl+grp+"</span>";
946 return nick + type + lvlgrp;
947 };
948 this.normalNpcTip = function(npc, type, important, before) {
949 if (interface == "old") {
950 var tip = this.oldNpcTip(npc, type, important).replace("<span ></span><br>", "").replace("<span ></span>", "");
951 } else if (interface == "new") {
952 var tip = this.newNpcTip(npc, type, important);
953 } else {
954 var tip = this.oldMargoNpcTip(npc, type, important);
955 };
956 if (npc.lvl > 0) tip += "<br>";
957 return this.makeTip({
958 txt: before+tip,
959 x: npc.x,
960 y: npc.y
961 });
962 };
963 var npcTrack = {};
964 this.addNpcToTrack = function(npc, id, heros) {
965 npcTrack[id] = npc;
966 qTrack.add({
967 type: "NPC",
968 name: npc.nick
969 });
970 if (interface != "superold") this.checkForUnknownResp(npc, heros);
971 };
972 this.checkForUnknownResp = function(npc, heros) {
973 var map = interface == "new" ? Engine.map.d : window.map;
974 var db = heros ? herosDB : eliteDB;
975 if (db[npc.nick] && db[npc.nick].spawns) {
976 var spawns = db[npc.nick].spawns;
977 if (spawns[map.name] || spawns[map.id]) {
978 var spawnsOnMap = spawns[map.name] ? spawns[map.name] : spawns[map.id];
979 if (spawns[map.name]) this.unknownMapId(map.name, map.id, heros);
980 if (!this.coordsExistInSpawns(spawnsOnMap, npc.x, npc.y)) this.unknownResp(npc, map, heros);
981 };
982 };
983 };
984 this.coordsExistInSpawns = function(spawns, x, y) {
985 for (var i=0; i<spawns.length; i++) {
986 if (spawns[i][0] == x && spawns[i][1] == y) return true;
987 };
988 return false;
989 };
990 this.unknownResp = function(npc, map, heros) {
991 var log = interface == "new" ? API.priw.console.log : window.log;
992 log("<hr>"+(heros ? "Heros" : "Elita")+" znajduje siÄ na respie, ktĂłry nie jest w bazie danych minimapy.",1);
993 log("ProsiĹbym o zamieszczenie poniĹźszej informacji w <a style='color: gold' href='https://www.margonem.pl/?task=forum&show=posts&id=488564' target='_blank'>tym temacie</a><br><br>miniMap+ - Nieznany resp: "+npc.nick+", "+map.name+"(ID: "+map.id+")("+npc.x+","+npc.y+")<br><hr>");
994 };
995 this.unknownMapId = function(name, id, heros) {
996 var log = interface == "new" ? API.priw.console.log : window.log;
997 log("<hr>"+"Mapa, na ktĂłrej "+(heros ? "zrespiĹ siÄ heros" : "zrespiĹa siÄ elita")+", nie jest zapisana w bazie danych po ID.",1);
998 log("ProsiĹbym o zamieszczenie poniĹźszej informacji w <a style='color: gold' href='https://www.margonem.pl/?task=forum&show=posts&id=488564' target='_blank'>tym temacie</a><br><br>miniMap+ - nieznane ID mapy - '"+name+"'="+id+"<br><hr>");
999 };
1000 this.getNpcType = function(npc, id) {
1001 if (npc.type == 2 || npc.type == 3) {
1002 var flash = false;
1003 if (npc.wt > 99) {
1004 //tytan
1005 var type = "titan";
1006 } else if (npc.wt > 79) {
1007 //heros
1008 var type = "heros";
1009 this.addNpcToTrack(npc, id, true);
1010 flash = true;
1011 } else if (eliteDB[npc.nick]) {
1012 //specjalna elita
1013 var type = "elite2";
1014 this.addNpcToTrack(npc, id, false);
1015 flash = true;
1016 } else if (npc.wt > 29) {
1017 //e3
1018 var type = "elite3";
1019 } else if (npc.wt > 19) {
1020 //e2
1021 var type = "elite2";
1022 } else if (npc.wt > 9) {
1023 //e
1024 var type = "elite";
1025 } else {
1026 //nub
1027 var type = "mob";
1028 };
1029 } else if (npc.type == 0 || npc.type == 5) {
1030 if (gws.indexOf(npc.icon) == -1) {
1031 var type = "npc";
1032 } else {
1033 var type = "gw";
1034 };
1035 } else if (_l() == "en" && npc.type == 7) {
1036 var type = "item";
1037 };
1038 return {
1039 type: type,
1040 flash: flash
1041 };
1042 };
1043
1044 this.initHeroUpdating = function() {
1045 if (interface != "new") {
1046 var _run = hero.run;
1047 hero.run = function() {
1048 self.updateHero();
1049 var ret = _run.apply(this, arguments);
1050 if (interface == "superold" && self.cancelMouseMovement) {
1051 self.cancelMouseMovement = false;
1052 window.global.movebymouse = false;
1053 }
1054 return ret;
1055 };
1056 } else if (interface == "new") {
1057 var _draw = Engine.map.draw;
1058 Engine.map.draw = function() {
1059 self.updateHero();
1060 return _draw.apply(this, arguments);
1061 };
1062 };
1063 };
1064
1065 this.updateHero = function(ignore) {
1066 qTrack.update();
1067 if (interface == "new") var hero = Engine.hero.d;
1068 else var hero = window.hero;
1069 if (!ignore && oldPos.x == hero.x && oldPos.y == hero.y) return;
1070 this.objectMgr.updateObject({
1071 id: "HERO",
1072 x: hero.x,
1073 y: hero.y,
1074 tip: "Moja postaÄ",
1075 type: "hero",
1076 children: [$visibility]
1077 });
1078 oldPos.x = hero.x;
1079 oldPos.y = hero.y;
1080 };
1081
1082 this.parseGws = function(gws, townname) {
1083 for (var i=0; i<gws.length; i+=5) {
1084 var tip = townname[gws[i]];
1085 if (gws[i+3]) {
1086 if (gws[i+3] == 2) {
1087 tip += interface != "superold" ? "<br>("+_t("require_key", null , "gtw")+")" : "<br>(wymaga klucza)";
1088 };
1089 };
1090 if (gws[i+4]) {
1091 var min = (parseInt(gws[i+4]) & 65535);
1092 var max = ((parseInt(gws[i+4]) >> 16) & 65535);
1093 tip += "<br>" + _t("gateway_availavle", null , "gtw");
1094 tip += min ? _t("from_lvl %lvl%", {"%lvl%": min }, "gtw") : "";
1095 tip += max >= 1000 ? "" : _t("to_lvl %lvl%", { "%lvl%": max }, "gtw") + _t("lvl_lvl", null , "gtw");
1096 };
1097 this.objectMgr.updateObject({
1098 tip: this.makeTip({
1099 txt: tip + "<br>",
1100 x: gws[i+1],
1101 y: gws[i+2]
1102 }),
1103 type: "gw",
1104 x: gws[i+1],
1105 y: gws[i+2],
1106 id: "GW-"+gws[i]+"-"+i
1107 });
1108 };
1109 };
1110
1111 this.parseOther = function(others) {
1112 for (var id in others) {
1113 var other = others[id];
1114 if (!other.del) {
1115 if ((interface != "new" && !g.other[id]) || (interface == "new" && !Engine.others.getById(id))) {
1116 if (interface != "superold" || other.nick) this.addNewOtherToMap(other, id); //dumb fix
1117 } else {
1118 this.updateOther(other, id);
1119 };
1120 } else {
1121 this.objectMgr.updateObject({
1122 id: "OTHER-"+id,
1123 del: 1
1124 });
1125 };
1126 }
1127 };
1128 this.updateOther = function(other, id) {
1129 var evoNetwork = this.checkIfOtherFromEvoNetwork(id);
1130 var data = {};
1131 var canLoadImgFromCache = !other.icon;
1132 var previousData = interface == "new" ? Engine.others.getById(id).d : g.other[id];
1133 var other = Object.assign({}, previousData, other);
1134 if (isset(other.x)) data.x = other.x;
1135 if (isset(other.y)) data.y = other.y;
1136 var {tip, ctip} = this.getOtherTip(other, evoNetwork);
1137 if (canLoadImgFromCache && this.otherImgCache[id]) {
1138 var img = this.otherImgCache[id];
1139 tip = '<center><div style="background-image: url('+img.src+'); width: '+(img.width/4)+'px; height: '+(img.height/4)+'px"></div></center>' + tip;
1140 } else {
1141 this.loadOtherImg(other, id, tip);
1142 }
1143 data.tip = tip;
1144 data.ctip = ctip;
1145 data.id = "OTHER-"+id;
1146 this.objectMgr.updateObject(data);
1147 };
1148 this.otherImgCache = {};
1149 this.checkIfOtherFromEvoNetwork = function(id) {
1150 //rozpoznawanie postaci z innych ĹwiatĂłw dodawanych przez dodatek ccarederra
1151 return String(id).split("_")[1] == "wsync";
1152 };
1153 this.addNewOtherToMap = function(other, id) {
1154 var type;
1155 var evoNetwork = this.checkIfOtherFromEvoNetwork(id);
1156 if (evoNetwork && !settings.get("/showevonetwork")) return;
1157 switch (other.relation) {
1158 case "": //obcy
1159 type = "other";
1160 break;
1161 case "cl-fr": //sojusznik
1162 case "fr-fr": //fraction friend
1163 type = "ally";
1164 break;
1165 case "cl": //klanowicz
1166 type = "clan";
1167 break;
1168 case "fr": //znajomy
1169 type = "friend";
1170 break;
1171 case "en": //wrĂłg
1172 case "cl-en": //wrogi klan
1173 case "fr-en": //fraction enemy
1174 type = "enemy";
1175 break;
1176 default:
1177 type = "other";
1178 break;
1179 };
1180 if (evoNetwork) type = "evoNetwork";
1181 var {tip, ctip} = this.getOtherTip(other, evoNetwork);
1182 this.objectMgr.updateObject({
1183 tip: tip,
1184 ctip: ctip,
1185 type: "other",
1186 type2: type,
1187 x: other.x,
1188 y: other.y,
1189 id: "OTHER-"+id,
1190 evoNetwork: evoNetwork,
1191 click: function() {
1192 if (evoNetwork) return; //gdy ccarderr zrobi jakieĹ kanaĹy prywatne w swoim chacie to klikniÄcie gracza bÄdzie taki otwieraÄ
1193 if (interface != "old") {
1194 $chatInput.value = "@" + other.nick.replace(/ /g, "_") + " ";
1195 $chatInput.focus();
1196 if (interface == "superold") {
1197 //switch from eq to chat
1198 if (window.chat.style.display == "none") {
1199 var btt = document.querySelector("#eqbutton");
1200 btt.click();
1201 btt.style["background-position"] = "";
1202 };
1203 };
1204 } else if (interface == "old") {
1205 chatTo(other.nick);
1206 };
1207 }
1208 });
1209 this.loadOtherImg(other, id, tip);
1210 };
1211 this.loadOtherImg = function(other, id, tip) {
1212 var img = new Image();
1213 img.src = (interface == "superold" ? "http://oldmargonem.pl" : "") + "/obrazki/postacie/"+other.icon;
1214 img.onload = function() {
1215 self.otherImgCache[id] = img;
1216 tip = '<center><div style="background-image: url('+img.src+'); width: '+(img.width/4)+'px; height: '+(img.height/4)+'px"></div></center>' + tip;
1217 self.objectMgr.updateObject({
1218 tip: tip,
1219 id: "OTHER-"+id
1220 });
1221 };
1222 }
1223 this.getOtherTip = function(other, evoNetwork) {
1224 if (interface == "old") {
1225 var tip = this.oldOtherTip(other);
1226 } else if (interface == "new") {
1227 var tip = this.newOtherTip(other);
1228 } else {
1229 var tip = this.oldMargoOtherTip(other);
1230 };
1231 if (evoNetwork) {
1232 tip += "<i>PostaÄ z dodatku World Sync</i>";
1233 };
1234 return {
1235 tip: this.makeTip({
1236 txt: tip + (evoNetwork ? "" : "<br>"),
1237 x: other.x,
1238 y: other.y
1239 }),
1240 ctip: "t_other" + (other.relation != "" && interface != "new" ? " t_"+other.relation : "")
1241 };
1242 };
1243 this.oldOtherTip = function(other) {
1244 if (!g.tips.other) newOther({0:{}});newOther({0:{del:1}});
1245 var tip = g.tips.other(other);
1246 return tip.replace(/'/g, "'")
1247 };
1248 this.newOtherTip = function(other) {
1249 //pre-wrapper
1250 if (other.rights) {
1251 var rank;
1252 if (other.rights & 1) rank = 0;
1253 else if (other.rights & 16) rank = 1;
1254 else if (other.rights & 2) rank = 2;
1255 else if (other.rights & 4) rank = 4;
1256 else rank = 3;
1257 rank = "<div class='rank'>"+otherRanks[rank]+"</div>";
1258 } else {
1259 var rank = "";
1260 };
1261 var guest = isset(other.guest) ? "<div class='rank'>ZastÄpca</div>" : "";
1262 var preWrapper = rank + guest;
1263 //wrapper
1264 var nick = "<div class='nick'>" + other.nick + "</div>";
1265 var prof = "<div class='profs-icon "+other.prof+"'></div>";
1266 var bless = isset(other.ble) ? "<div class='bless'></div>" : "";
1267 var infoWrapper = "<div class='info-wrapper'>" + nick + bless + prof + "</div>";
1268 //post-wrapper
1269 var wanted = isset(other.wanted) ? "<div class='wanted'></div>" : "";
1270 var clan = (isset(other.clan) && other.clan.name != "") ? "<div class='clan-in-tip'>"+other.clan.name+"</div><div class='line'></div>" : "";
1271 var lvl = isset(other.lvl) ? "<div class='lvl'>"+other.lvl+" lvl</div>" : "";
1272 var mute = (other.attr & 1) ? "<div class='mute'></div>" : "";
1273 var postWrapper = wanted + clan + lvl + mute;
1274
1275 return preWrapper + infoWrapper + postWrapper;
1276 };
1277 this.oldMargoOtherTip = function(other) {
1278 var tip = "<b style='color:yellow'>"+other.nick+"</b>";
1279 if (other.clan) tip += "<span style='color:#fd9;'>["+g.clanname[other.clan]+"]</span><br>";
1280 tip += "Lvl: "+other.lvl+other.prof;
1281 return tip;
1282
1283 };
1284
1285 this.parseItem = function(items) {
1286 for (var id in items) {
1287 var item = items[id];
1288 if (item.loc == "m") {
1289 this.addNewItemToMap(item, id);
1290 } else {
1291 var previousData = interface == "new" ? Engine.items.getItemById(id) : g.item[id];
1292 if (interface == "new" && previousData) previousData = previousData.d;
1293 if (previousData && previousData.loc == "m") {
1294 this.objectMgr.updateObject({
1295 id: "ITEM-"+id,
1296 del: 1
1297 });
1298 };
1299 }
1300 }
1301 };
1302 this.addNewItemToMap = function(item, id) {
1303 var tip = this.getItemTip(item);
1304 this.objectMgr.updateObject({
1305 id: "ITEM-"+id,
1306 tip: tip,
1307 ctip: "t_item",
1308 x: item.x,
1309 y: item.y,
1310 type: "item"
1311 });
1312 };
1313 this.oldMargoItemTip = function(item) {
1314 return "<b>"+item.name+"</b>"+item.stats;
1315 };
1316 this.getItemTip = function(item) {
1317 var nocenter = true;
1318 var tip = interface == "new" ? MargoTipsParser.getTip(item) : (interface == "old" ? itemTip(item) : this.oldMargoItemTip(item));
1319 if (interface == "old" && tip.indexOf("tip-section") == -1) { //kompatybilnoĹÄ z moim dodatkiem na nowe tipy
1320 tip = "<img src='"+(interface == "superold" ? "http://oldmargonem.pl" : "") +"/obrazki/itemy/"+item.icon+"'>" + tip;
1321 nocenter = false;
1322 };
1323 return this.makeTip({
1324 txt: tip,
1325 x: item.x,
1326 y: item.y,
1327 nocenter: nocenter
1328 });
1329 };
1330 var ripCount = 0;
1331 this.parseRip = function(rips) {
1332 for (var i=0; i<rips.length; i+=8) {
1333 this.addNewRipToMap({
1334 nick: rips[i],
1335 lvl: rips[i+1],
1336 prof: rips[i+2],
1337 x: parseInt(rips[i+3]),
1338 y: parseInt(rips[i+4]),
1339 ts: parseInt(rips[i+5]),
1340 desc1: rips[i+6],
1341 desc2: rips[i+7]
1342 });
1343 ripCount++;
1344 };
1345 };
1346 this.addNewRipToMap = function(rip) {
1347 var isHerosRip = false;
1348 var timeToDisappear = 300 + rip.ts - unix_time();
1349 if (timeToDisappear <= 0) return;
1350 var tip = "<b>" + _t("rip_prefix") + " " + htmlspecialchars(rip.nick) + "</b>Lvl: " + rip.lvl + rip.prof + "<i>" + htmlspecialchars(rip.desc1) + "</i><i>" + htmlspecialchars(rip.desc2) + "</i>";
1351 this.objectMgr.updateObject({
1352 tip: this.makeTip({
1353 txt: tip,
1354 x: rip.x,
1355 y: rip.y
1356 }),
1357 type: "other",
1358 x: rip.x,
1359 y: rip.y,
1360 circle: true,
1361 border: true,
1362 id: "RIP-"+ripCount,
1363 ctip: "t_rip"
1364 });
1365 var id = "RIP-"+ripCount;
1366 var nick;
1367 if (nick = this.checkHerosRip(rip.desc1)) {
1368 qTrack.add({type: "COORDS", name: "GrĂłb gracza zabitego przez herosa "+nick+"<br>MoĹźliwe, Ĺźe heros tam stoi!", coords: [rip.x, rip.y] });
1369 isHerosRip = true;
1370 message("Na mapie znajduje siÄ grĂłb gracza zabitego przez herosa "+nick);
1371 };
1372 setTimeout(() => {
1373 self.objectMgr.updateObject({
1374 id: id,
1375 del: 1
1376 });
1377 if (isHerosRip) qTrack.remove({type: "COORDS", name: "GrĂłb gracza zabitego przez herosa "+nick+"<br>MoĹźliwe, Ĺźe heros tam stoi!"});
1378 }, timeToDisappear*1000);
1379 };
1380 this.checkHerosRip = function(desc) {
1381 for (var nick in herosDB) {
1382 var needle = nick + "(" + herosDB[nick].lvl + herosDB[nick].prof + ")";
1383 if (desc.indexOf(needle) > -1) {
1384 return nick;
1385 };
1386 };
1387 return false;
1388 };
1389
1390 this.objectMgr = new (function() {
1391 var self = this;
1392 var mgr = this;
1393 var objs = {};
1394 var flashables = [];
1395 function MapObject(data) {
1396 var self = this;
1397 this.d = data;
1398 var currentColor = settings.get("/colors")[this.d.type];
1399
1400 this.initHTML = function() {
1401 this.$ = document.createElement("div");
1402 this.$.classList.add("mmpMapObject", "mmp-"+data.type);
1403 if (innerDotKeys.indexOf(data.type2) != -1) {
1404 var $dot = document.createElement("div");
1405 $dot.classList.add("innerDot", "mmp-"+data.type2);
1406 Object.assign($dot.style, {
1407 left: objSize/4 + "px",
1408 top: objSize/4 + "px",
1409 width: objSize/2 + "px",
1410 height: objSize/2 + "px"
1411 });
1412 this.$.appendChild($dot);
1413 } else if (data.type2 == "evoNetwork") {
1414 this.$.classList.add("evoNetwork");
1415 };
1416 if (data.children) {
1417 // append extra children to the object
1418 for (let i=0; i<data.children.length; i++) {
1419 this.$.appendChild(data.children[i]);
1420 }
1421 }
1422 var left = data.x * objScale * 32;
1423 var top = data.y * objScale * 32;
1424 Object.assign(this.$.style, {
1425 top: top + "px",
1426 left: left + "px",
1427 width: objSize + "px",
1428 height: objSize + "px",
1429 opacity: "0"
1430 });
1431 setTimeout(() => this.$.style.opacity = "1.0", 1);
1432 if (interface != "new") {
1433 this.$.setAttribute("tip", data.tip);
1434 if (data.ctip) this.$.setAttribute("ctip", data.ctip);
1435 } else {
1436 this.$.setAttribute("data-tip", data.tip);
1437 if (data.ctip) this.$.setAttribute("data-tip-type", data.ctip);
1438 };
1439 if (data.circle) {
1440 this.$.style["border-radius"] = objScale*18 + "px";
1441 };
1442 if (data.border) {
1443 this.$.style["border"] = "1px solid black";
1444 };
1445 if (data.qm) {
1446 this.$.innerHTML = "<img class='mmpQM' width='"+objSize+"' height='"+objSize*2+"' src='http://jaruna.margonem.pl/img/quest-mark.gif'>";
1447 };
1448 $map.appendChild(this.$);
1449 };
1450
1451 this.invertColor = function() {
1452 var c = currentColor;
1453 var c1 = (255 - parseInt("0x"+c.substring(1,3))).toString(16);
1454 var c2 = (255 - parseInt("0x"+c.substring(3,5))).toString(16);
1455 var c3 = (255 - parseInt("0x"+c.substring(5,7))).toString(16);
1456 if (c1.length < 2) c1 = "0" + c1;
1457 if (c2.length < 2) c2 = "0" + c2;
1458 if (c3.length < 2) c3 = "0" + c3;
1459 currentColor = "#"+c1+c2+c3;
1460 this.$.style.background = currentColor;
1461 };
1462
1463 this.remove = function() {
1464 if (this.d.flash) flashables.splice(flashables.indexOf(this), 1);
1465 this.$.style["opacity"] = "0";
1466 if (settings.get("/interpolerate")) setTimeout(() => this.$.remove(), 500);
1467 else this.$.remove();
1468 };
1469
1470 this.update = function(data) {
1471 Object.assign(this.d, data);
1472 if (data.x) {
1473 this.$.style["left"] = data.x * objScale * 32 + "px";
1474 };
1475 if (data.y) {
1476 this.$.style["top"] = data.y * objScale * 32 + "px";
1477 };
1478 if (data.tip) {
1479 this.$.setAttribute(interface == "new" ? "data-tip" : "tip", data.tip);
1480 };
1481 if (data.invertColor) {
1482 this.invertColor();
1483 };
1484 };
1485
1486 this.initEventListener = function() {
1487 if (data.click) {
1488 var type = mobileDevice ? "touchstart" : "click";
1489 this.$.addEventListener(type, e => {
1490 data.click(e);
1491 e.stopPropagation();
1492 });
1493 };// else {
1494 //this.$.addEventListener("click", this.goTo);
1495 //}
1496 };
1497
1498 //this.goTo = function() {
1499 // if (newInterface) {
1500 // Engine.hero.autoGoTo({x :self.d.x, y: self.d.y});
1501 // } else {
1502 // self.searchPath.call(window.hero, self.d.x, self.d.y);
1503 // };
1504 //};
1505
1506 this.manageDisplay = function() {
1507 if (!this.d.flash && isset(this.d.lvl) && this.d.lvl < settings.get("/minlvl")) {
1508 this.$.classList.add("hidden");
1509 } else {
1510 this.$.classList.remove("hidden");
1511 };
1512 };
1513
1514 this.checkStringSearch = function(str) {
1515 if (this.d.tip.toLowerCase().indexOf(str) == -1 && this.d.type != "hero") {
1516 this.$.classList.add("hiddenBySearch");
1517 };
1518 };
1519
1520 this.checkRangeSearch = function(n1, n2) {
1521 if (isset(this.d.lvl)) {
1522 if (this.d.lvl < n1 || this.d.lvl > n2) {
1523 this.$.classList.add("hiddenBySearch");
1524 };
1525 };
1526 };
1527
1528 this.manageFilters = function() {
1529 if (search.type == "string" && search.data != "") {
1530 this.checkStringSearch(search.data);
1531 } else if (search.type == "lvl") {
1532 this.checkRangeSearch(search.data[0], search.data[1]);
1533 };
1534 };
1535
1536 this.init = function() {
1537 if (data.flash) flashables.push(this);
1538 this.initHTML();
1539 this.initEventListener();
1540 this.manageDisplay();
1541 this.manageFilters();
1542 };
1543 this.init();
1544 };
1545 this.getByElem = function($el) {
1546 for (var i in objs) {
1547 if (objs[i].$ == $el) return objs[i];
1548 };
1549 };
1550 this.deleteAll = function() {
1551 for (var i in objs) {
1552 objs[i].remove();
1553 delete objs[i];
1554 };
1555 };
1556 this.updateObject = function(data) {
1557 if (!objs[data.id] && !data.del) {
1558 if (!data.dontCreate) objs[data.id] = new MapObject(data);
1559 } else if (data.del) {
1560 if (objs[data.id]) {
1561 objs[data.id].remove();
1562 delete objs[data.id];
1563 };
1564 } else {
1565 objs[data.id].update(data);
1566 }
1567 };
1568 this.resetSearch = function() {
1569 this.removeCoordMarker();
1570 for (var id in objs) {
1571 objs[id].$.classList.remove("hiddenBySearch");
1572 };
1573 };
1574 this.filterByLvl = function(n1, n2) {
1575 search.type = "lvl",
1576 search.data = [n1, n2];
1577 for (var id in objs) {
1578 objs[id].checkRangeSearch(n1, n2);
1579 };
1580 };
1581 this.filterByString = function(str) {
1582 str = str.toLowerCase();
1583 search.type = "string",
1584 search.data = str;
1585 for (var id in objs) {
1586 objs[id].checkStringSearch(str);
1587 };
1588 };
1589 this.removeCoordMarker = function() {
1590 this.updateObject({
1591 id: "COORDS",
1592 del: 1
1593 });
1594 };
1595 this.createCoordMarker = function(x, y) {
1596 this.updateObject({
1597 id: "COORDS",
1598 x: x,
1599 y: y,
1600 tip: "koordy "+x+","+y,
1601 circle: true,
1602 type: "hero",
1603 flash: true
1604 })
1605 };
1606 this.manageDisplay = function() {
1607 for (var id in objs) {
1608 objs[id].manageDisplay();
1609 };
1610 };
1611 this.invertFlashables = function() {
1612 for (var i=0; i<flashables.length; i++) {
1613 flashables[i].update({
1614 invertColor: true
1615 });
1616 };
1617 };
1618 setInterval(this.invertFlashables, 500);
1619 })();
1620
1621 this.addSpawnsToMap = function(db, heros, map, mapId) {
1622 map = map.toLowerCase();
1623 var maxlvl = settings.get("/maxlvl");
1624 var hero = interface == "new" ? Engine.hero.d : window.hero;
1625 for (var i in db) {
1626 var mob = db[i];
1627 if (mob.ver && mob.ver != _l()) continue;
1628 var minlvl = Math.max(mob.lvl/2, mob.lvl-50);
1629 if ((maxlvl+mob.lvl >= hero.lvl && minlvl <= hero.lvl) || mob.lvl >= 242 || mob.lvl == -1) {
1630 for (var loc in mob.spawns) {
1631 if (loc.toLowerCase() == map || loc == mapId) {
1632 var spawns = mob.spawns[loc];
1633 for (var j=0; j<spawns.length; j++) {
1634 var x = spawns[j][0];
1635 var y = spawns[j][1];
1636 this.objectMgr.updateObject({
1637 id: "SPAWN-"+i+"-"+j,
1638 tip: this.makeTip({
1639 txt: "Resp " + (heros ? "herosa " : "elity ") + i,
1640 x: x,
1641 y: y
1642 }),
1643 x: x,
1644 y: y,
1645 type: heros ? "heros" : "elite2",
1646 circle: true
1647 });
1648 };
1649 };
1650 };
1651 };
1652 };
1653 };
1654
1655 this.init = function() {
1656 this.initSettings();
1657 this.initHTML();
1658 this.appendUserStyles();
1659 this.initResponseParser();
1660 this.initHeroUpdating();
1661 this.appendMobileButton();
1662 this.installationCounter.count();
1663 if (interface == "old") this.searchPath = function(a,t){if(this.isBlockedSearchPath())return this.blockedInfoSearchPath();for(var h=[],i=128&hero.opt?8:20,r=Math.max(0,Math.min(a,this.x)-i),s=Math.min(map.x-1,Math.max(a,this.x)+i),o=Math.max(0,Math.min(t,this.y)-i),e=Math.min(map.y-1,Math.max(t,this.y)+i),d=r-1;s+1>=d;d++){h[d]=[];for(var x=o-1;e+1>=x;x++)h[d][x]=!(d>=r&&s>=d&&x>=o&&e>=x)||isset(g.npccol[d+256*x])||map.col&&"0"!=map.col.charAt(d+x*map.x)?-2:-1}h[this.x][this.y]=0,b=-1,road=[];for(var c={x:-1,y:-1,dist:99},y=1;s-r+e-o+3>y;y++)for(var d=r;s>=d;d++)for(var x=o;e>=x;x++){if(-1!=h[d][x]||h[d][x-1]!=y-1&&h[d][x+1]!=y-1&&h[d-1][x]!=y-1&&h[d+1][x]!=y-1||(h[d][x]=y),h[a][t]>0){d=s+1;break}c.dist2=Math.abs(a-d)+Math.abs(t-x),h[d][x]==y&&c.dist2<c.dist&&(c.x=d,c.y=x,c.dist=c.dist2)}if(c.hdist=Math.abs(a-hero.x)+Math.abs(t-hero.y),h[a][t]>0||c.dist<c.hdist){h[a][t]<0&&(a>c.x?b=2:a<c.x?b=1:t>c.y?b=0:t<c.y&&(b=3),a=c.x,t=c.y),road[0]={x:a,y:t};for(var f=h[a][t]-1,l=a,m=t;f>0;f--)h[l][m-1]==f?m--:h[l][m+1]==f?m++:h[l-1][m]==f?l--:h[l+1][m]==f?l++:f=0,f&&(road[h[a][t]-f]={x:l,y:m})}road.length>1&&null==g.playerCatcher.follow&&$("#target").stop().css({left:32*a,top:32*t,display:"block",opacity:1}).fadeOut(1e3)};
1664 $chatInput = interface == "new" ? document.querySelector("[data-section='chat'] .input-wrapper input") : (interface == "superold" ? document.querySelector("#chatIn") : null);
1665 };
1666
1667 //questtrack (fuzja kodu z wersji minimapy na SI i NI wiÄc wyglÄ
da jak wyglÄ
da)
1668 var qTrack = new (function() {
1669 var self = this;
1670 var hero = interface == "new" ? Engine.hero : window.hero;
1671 var $hero = interface == "old" ? $("#hero") : (interface == "superold" ? document.querySelector("#oHero") : null);
1672 var $canvas = interface == "new" ? $("#GAME_CANVAS") : null;
1673 if (interface == "new") {
1674 this.npcs = {};
1675 API.addCallbackToEvent("newNpc", function(npc) {
1676 if (npc) self.npcs[npc.d.id] = npc.d;
1677 });
1678 API.addCallbackToEvent("removeNpc", function(npc) {
1679 if (npc) delete self.npcs[npc.d.id];
1680 });
1681 };
1682 this.getOldMargoHeroPos = function() {
1683 return {
1684 left: $hero.offsetLeft,
1685 top: $hero.offsetTop
1686 };
1687 };
1688 this.getHeroPos = function() {
1689 if (interface == "old") return $hero.position();
1690 if (interface == "superold") return this.getOldMargoHeroPos();
1691 if (!Engine.map.size) return {x: 0, y: 0};
1692 var tilesX = $canvas.width()/32;
1693 var tilesY = $canvas.height()/32;
1694 var pos = {
1695 x: Engine.hero.rx,
1696 y: Engine.hero.ry
1697 };
1698 var actualPos = {};
1699 if (pos.x < tilesX/2) {
1700 actualPos.x = pos.x*32;
1701 } else if (Engine.map.size.x - pos.x < tilesX/2) {
1702 actualPos.x = (pos.x - (Engine.map.size.x - tilesX/2) + tilesX/2)*32;
1703 } else {
1704 actualPos.x = (tilesX/2)*32;
1705 };
1706 if (pos.y < tilesY/2) {
1707 actualPos.y = pos.y*32;
1708 } else if (Engine.map.size.y - pos.y < tilesY/2) {
1709 actualPos.y = (pos.y - (Engine.map.size.y - tilesY/2) + tilesY/2)*32;
1710 } else {
1711 actualPos.y = (tilesY/2)*32;
1712 };
1713 var canvasOffset = $canvas.offset();
1714 return {
1715 left: actualPos.x + canvasOffset.left,
1716 top: actualPos.y + canvasOffset.top
1717 };
1718 };
1719 this.update = function() {
1720 for (var i=0; i<this.arrows.length; i++) {
1721 this.drawArrow(this.arrows[i]);
1722 };
1723 };
1724 this.drawArrow = function(objective) {
1725 if (objective.type == "NPC") {
1726 var nameKey = "nick";
1727 var obj = interface == "new" ? this.npcs : g.npc;
1728 var item = false;
1729 } else if (objective.type == "ITEM") { //item
1730 var nameKey = "name";
1731 if (interface == "new") {
1732 var itemArr = Engine.items.fetchLocationItems("m");
1733 var obj = {};
1734 for (var i in itemArr) {
1735 var it = itemArr[i];
1736 if (it.id) obj[it.id] = it;
1737 else obj[it.hid] = it;
1738 };
1739 } else {
1740 var obj = g.item;
1741 };
1742 var item = true;
1743 } else if (objective.type == "COORDS") { //coords
1744 var coords = objective.coords;
1745 var size = [32, 32];
1746 var x = Math.abs(hero.rx-coords[0]);
1747 var y = Math.abs(hero.ry-coords[1]);
1748 var closest = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
1749 };
1750 if (objective.type != "COORDS") {
1751 var closest = Infinity;
1752 var coords = false;
1753 var size = false;
1754 for (var i in obj) {
1755 var entity = obj[i];
1756 if (entity[nameKey] == objective.name && (!item || entity.loc == "m")) {
1757 var x = Math.abs(hero.rx-entity.x);
1758 var y = Math.abs(hero.ry-entity.y);
1759 var dist = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
1760 if (dist < closest) {
1761 closest = dist;
1762 coords = [entity.x, entity.y];
1763 size = item ? [32,32] : [entity.fw, entity.fh];
1764 };
1765 };
1766 };
1767 };
1768 if (coords) {
1769 var cos = (coords[0] - hero.rx)/closest;
1770 var sin = (coords[1] - hero.ry)/closest;
1771 var heropos = this.getHeroPos();
1772 var top = 150*sin;
1773 var left = 150*cos;
1774 var opacity = 1;
1775 if (closest < 9) {
1776 top = top*Math.pow(closest/9, 1.8);
1777 left = left*Math.pow(closest/9, 1.8);
1778 opacity = Math.pow(closest/9, 2.1);
1779 };
1780 if (interface != "new") top+=20;
1781 left+= interface == "new" ? -12 : 4;
1782 if ((cos >= 0 && sin >= 0) || (cos >= 0 && sin <= 0)) {
1783 var angle = Math.asin(sin) * 180 / Math.PI;
1784 } else {
1785 var angle = 180+Math.asin(0-sin) * 180 / Math.PI;
1786 };
1787 objective.$.css({
1788 top: top + heropos.top,
1789 left: left + heropos.left,
1790 display: opacity > 0.09 ? "block" : "none",
1791 "-ms-transform": "rotate("+angle+"deg)",
1792 "-webkit-transform": "rotate("+angle+"deg)",
1793 transform: "rotate("+angle+"deg)",
1794 opacity: opacity
1795 });
1796 if (interface == "old") {
1797 objective.$highlight.css({
1798 left: coords[0]*32 - 11,
1799 top: coords[1]*32 + 14,
1800 display: "block",
1801 opacity: 1-opacity
1802 });
1803 };
1804 } else {
1805 objective.$.hide();
1806 if (interface == "old") objective.$highlight.hide();
1807 };
1808 };
1809 this.arrows = [];
1810 this.add = function(objective) {
1811 for (var i in this.arrows) {
1812 if (objective.type == this.arrows[i].type && objective.name == this.arrows[i].name) return;
1813 };
1814 objective.$ = this.arrowTemplate.clone().appendTo(interface == "old" ? "#centerbox" : (interface == "new" ? ".game-window-positioner" : "#oMap"));
1815 objective.$.attr(interface == "new" ? "data-tip" : "tip", objective.name);
1816 if (interface == "old") objective.$highlight = this.highlightTemplate.clone().appendTo(interface == "old" ? "#ground" : "#oMap");
1817 objective.index = this.arrows.push(objective) -1;
1818 objective.remove = function() {
1819 self.arrows.splice(this.index, 1);
1820 for (var i=this.index; i<self.arrows.length; i++) {
1821 self.arrows[i].index--;
1822 };
1823 this.$.remove();
1824 if (interface == "old") this.$highlight.remove();
1825 };
1826 this.update();
1827 };
1828 this.remove = function(objective) {
1829 for (var i=0; i<this.arrows.length; i++) {
1830 if (this.arrows[i].name == objective.name && this.arrows[i].type == objective.type) this.arrows[i].remove();
1831 };
1832 };
1833 this.reset = function() {
1834 while (this.arrows.length) {
1835 this.arrows[0].remove();
1836 };
1837 };
1838 this.arrowTemplate = $("<div>").css({
1839 background: "url(http://priweejt.ct8.pl/addons/img/qt-arrow-red.gif)",
1840 width: 24,
1841 height: 24,
1842 zIndex: 250,
1843 position: "absolute"
1844 });
1845 this.highlightTemplate = $("<div>").css({
1846 background: "url(/img/glow-blue.png)",
1847 position: "absolute",
1848 width: 52,
1849 height: 24,
1850 zIndex: 1
1851 });
1852 })();
1853
1854 this.installationCounter = new (function() {
1855 var self = this;
1856 var id = 87771;
1857
1858 this.count = function() {
1859 if (interface == "superold") return;
1860 if (!settings.get("/counted")) {
1861 //extManager.toggleLike(id, 'unlike')
1862 $.ajax({
1863 url: "/tools/addons.php?task=details&id="+id,
1864 type: "POST",
1865 data: {like: "unlike"}
1866 });
1867 settings.set("/counted", true);
1868 };
1869 };
1870 this.get = function(clb) {
1871 if (interface == "superold") return clb("<span tip='NiedostÄpne dla oldmargonem'>-</span>");
1872 $.ajax({
1873 url: "/tools/addons.php?task=details&id="+id,
1874 datatype: "json",
1875 success: function(r) {
1876 clb(-r.addon.points);
1877 }
1878 });
1879 };
1880 })();
1881
1882 //databases
1883 //porzuciĹem rÄczne edytowanie tego wiÄc w jednej linii jest bo tak wypluwa skrypt
1884 var herosDB = {"Domina Ecclesiae":{"lvl":21,"prof":"b","spawns":{"3":[[53,11],[50,23]],"169":[[14,8],[8,9]],"171":[[25,26],[7,28],[15,29],[8,8],[22,9]],"175":[[12,4]],"217":[[7,35],[22,13],[37,39]],"249":[[12,5]],"251":[[11,10],[10,13]],"290":[[11,8],[16,5]],"298":[[7,10]],"300":[[7,8]],"2070":[[6,4],[10,29],[7,17]],"2071":[[42,5],[17,4],[37,9]],"2073":[[21,9]],"2546":[[44,43],[33,10],[41,14],[50,5],[25,28],[9,11]],"2710":[[6,11],[24,6],[8,15]],"2712":[[5,7],[9,7],[7,12]],"2713":[[10,6],[8,12]],"2714":[[8,5],[27,10],[7,8],[16,8]],"2715":[[24,17],[6,13],[5,18],[32,18]],"2718":[[23,8],[15,8]],"2719":[[7,35],[4,10]],"2721":[[4,5],[29,15],[20,15],[15,9]],"2722":[[8,22],[8,7]],"2879":[[12,7],[7,20],[11,13]],"2880":[[10,19]],"2885":[[38,57],[11,22],[23,56],[48,36]],"2886":[[41,57],[13,46],[12,12],[29,60],[24,12]],"PrzeklÄty Zamek p.1":[[12,4]],"StraĹźnica pĂłĹnocno-wschodnia":[[8,3]],"StraĹźnica pĂłĹnocno-zachodnia":[[8,3]],"Mury - zbrojownia - piwnica":[[12,11]],"Mury - skrzydĹo wschodnie":[[12,13]],"Mury - kwatera gĹĂłwna":[[10,11]],"Opuszczony dom":[[5,8]],"Posterunek":[[9,10]],"Posterunek - piwnica":[[11,4]],"Podziemia siedziby maga p.1 - sala 1":[[22,28],[13,9]],"Podziemia siedziby maga p.1 - sala 2":[[10,9]],"Fortyfikacja p.1":[[13,6],[7,16]],"Fortyfikacja p.5":[[9,9]],"PrzeklÄta StraĹźnica p.1":[[9,10]]}},"Mroczny Patryk":{"lvl":35,"prof":"w","spawns":{"3":[[31,58],[19,71],[11,47],[58,46],[19,21],[2,49],[14,7],[19,52],[54,71],[33,62],[57,75],[7,17],[48,79],[52,27],[28,3],[56,4],[10,84]],"4":[[45,51],[52,39],[54,66],[17,15],[35,14],[3,87],[38,59],[55,78],[25,44],[3,68],[42,18],[45,84],[59,92],[21,25],[5,27],[2,21],[6,4]],"8":[[5,40],[15,24],[58,18],[40,36],[24,54],[52,29],[26,6],[15,44],[7,10],[38,26],[54,45],[51,55],[51,5],[48,16],[42,22],[26,29],[4,56],[37,54]],"11":[[37,11],[61,22],[14,4],[52,50],[45,28],[5,75],[55,19],[56,94],[10,47],[9,30],[21,15],[37,71],[39,51],[48,83],[25,6],[55,32],[54,65],[11,17],[57,93]],"12":[[53,47],[76,17],[5,9],[21,41],[65,15],[10,31],[74,17]],"19":[[9,10]],"110":[[20,41],[52,23],[22,24],[60,23],[41,40],[36,11],[55,3],[52,77],[30,8],[39,61],[17,89],[9,8],[29,42],[46,83],[31,21],[54,51],[0,23],[27,65],[48,2],[5,85],[31,50],[19,78],[55,12],[3,4],[4,77],[31,21],[53,77],[25,39],[18,2]],"111":[[49,20],[60,3],[11,19],[9,47],[18,58],[22,28],[42,55],[30,2]],"115":[[41,43],[52,29],[21,10],[8,19],[57,48],[34,36],[38,43],[7,55],[49,43]],"634":[[26,7]],"1110":[[52,59],[32,9],[18,24],[11,13],[35,22]],"3402":[[37,24],[47,52],[5,27],[53,11]]}},"Karmazynowy MĹciciel":{"lvl":45,"prof":"m","spawns":{"121":[[47,26],[3,2],[2,54],[41,12],[48,75],[12,39],[5,65]],"128":[[3,87],[4,55],[33,18],[42,88],[52,55],[12,18],[51,19]],"132":[[11,17]],"133":[[13,18]],"134":[[8,13]],"135":[[10,11],[12,8]],"136":[[14,8]],"151":[[12,6],[26,5],[58,37],[46,60],[22,54],[37,57],[55,5],[39,13],[47,7],[19,34],[16,4],[45,52]],"182":[[8,5]],"183":[[14,9]],"198":[[53,56],[60,5],[10,44],[10,7],[57,22],[43,4],[37,2],[24,7],[14,19],[28,62],[9,6],[58,38],[9,33],[34,37],[9,45]],"226":[[13,37],[15,71],[20,90]],"227":[[10,35],[14,35]],"228":[[51,21],[50,24]],"229":[[36,82],[45,6],[8,70],[20,14]]}},"ZĹodziej":{"lvl":50,"prof":"h","spawns":{"1180":[[12,8],[11,8]],"1188":[[6,6]],"1247":[[9,9]],"1278":[[8,6]],"1280":[[8,6]],"1320":[[8,8]],"1335":[[10,8]],"1382":[[7,8]],"1407":[[8,7],[9,7]],"1423":[[8,7]],"1433":[[7,8]],"1438":[[12,6]],"1489":[[7,8]],"1493":[[7,8]],"1500":[[10,8]],"1542":[[28,6]],"1566":[[4,11]],"1567":[[7,6]],"1568":[[4,8]],"1589":[[6,8]],"1590":[[4,7],[4,6]],"1605":[[4,10]],"Chata Ficjusza":[[3,8]]}},"ZĹodziej znajduje siÄ w tym domu (parter)":{"lvl":50,"spawns":{"589":[[39,14],[40,14],[62,14],[63,14],[74,38],[52,54],[53,54]],"630":[[69,40],[44,41]],"1233":[[68,29],[75,16]],"1262":[[52,9],[53,9]]}},"ZĹodziej znajduje siÄ w tym domu (2. piÄtro)":{"lvl":50,"spawns":{"589":[[31,33],[83,36],[84,36]]}},"ZĹodziej znajduje siÄ w tej latarnii (2. piÄtro) (uwaga na kraby przy dochodzeniu tutaj)":{"lvl":50,"spawns":{"1262":[[20,54]]}},"ZĹodziej znajduje siÄ w tym domu (1. piÄtro)":{"lvl":50,"spawns":{"589":[[17,33],[33,17]],"630":[[40,27],[41,27]],"1262":[[61,17],[62,17]]}},"ZĹodziej znajduje siÄ w tym domu (piwnica)":{"lvl":50,"spawns":{"589":[[57,14],[43,54]],"630":[[78,17],[77,17],[81,28],[82,28],[88,23]],"1233":[[57,39]]}},"ZĹodziej znajduje siÄ w tym domu (pokĂłj Grety)":{"lvl":50,"spawns":{"589":[[59,29],[60,29]]}},"ZĹy Przewodnik":{"lvl":63,"prof":"w","spawns":{"116":[[5,26],[40,35],[35,3],[52,30],[10,44],[54,43],[18,8],[28,57],[37,8],[7,17],[35,3],[53,31],[39,34],[34,2],[27,56]],"122":[[35,20],[19,6],[54,18],[32,7],[54,25]],"140":[[26,54],[44,29],[56,27],[10,49],[49,2]],"150":[[57,3],[18,4],[3,34],[40,38],[89,51],[27,50],[40,37],[57,3]],"180":[[54,28],[22,20],[15,6],[14,44],[31,4],[34,17],[4,19]],"2730":[[19,13],[28,38],[12,23],[53,6],[49,15],[38,58],[6,46],[38,58]]}},"Piekielny KoĹciej":{"lvl":74,"prof":"w","spawns":{"Labirynt Margorii":[[15,38],[49,24],[57,55],[35,18],[34,46]],"Margoria Sala KrĂłlewska":[[23,61],[10,77],[51,24],[38,82],[22,30]],"Kopalnia Margorii":[[30,22],[53,62],[11,39],[50,12],[52,40],[27,38],[8,49]],"Zdradzieckie PrzejĹcie":[[21,6],[22,56],[67,38]]}},"OpÄtany Paladyn":{"lvl":85,"prof":"w","spawns":{"180":[[49,28]],"203":[[15,28],[31,9]],"204":[[18,27]],"205":[[18,27]],"210":[[84,7],[33,45],[54,11],[78,25],[15,26]],"211":[[19,38],[19,11],[45,57]],"601":[[17,41],[87,5],[25,55],[59,35],[92,54],[22,21]],"602":[[40,31],[6,58],[4,16]],"Podziemia ĹwiÄ
tyni":[[28,5],[54,32]],"Zbrojownia Andarum":[[25,59],[7,35],[7,20]]}},"Kochanka Nocy":{"lvl":100,"prof":"m","spawns":{"246":[[12,8],[28,60],[77,60]],"253":[[88,34],[77,46],[80,59],[6,34],[6,41],[34,22],[60,7],[90,20]],"268":[[83,6],[10,15],[34,47]],"330":[[6,8],[88,6],[60,24],[14,43],[45,40],[16,19]],"331":[[22,12],[5,58],[82,41],[82,8]],"332":[[77,13],[64,7],[35,19],[19,36]],"339":[[91,41],[81,1],[44,9],[39,33],[45,56],[67,59]],"3765":[[70,34],[83,51],[9,43],[29,37]],"3766":[[5,46],[11,11],[60,11],[72,52],[53,55]]}},"Perski KsiÄ
ĹźÄ":{"lvl":116,"prof":"b","spawns":{"Dolina Pustynnych KrÄgĂłw":[[11,89],[11,89],[10,21]],"Piachy Zniewolonych":[[33,23],[11,7],[75,30]],"Ruchome Piaski":[[79,54],[63,29],[15,16]],"Korsarska Nora - sala 2":[[4,22]],"Korsarska Nora - sala 4":[[10,6]],"Korsarska Nora p.2":[[11,6]],"Ukryta Grota Morskich DiabĹĂłw":[[51,32],[25,16]],"Ukryta Grota Morskich DiabĹĂłw - arsenaĹ":[[4,14]],"Ukryta Grota Morskich DiabĹĂłw - skarbiec":[[8,4]],"Oaza Siedmiu WichrĂłw":[[61,15],[42,24]],"Ruiny Pustynnych Burz":[[42,46],[9,7],[42,79]],"Dolina Suchych Ĺez":[[71,16],[41,22],[61,55]]}},"Baca Bez Ĺowiec":{"lvl":123,"prof":"h","spawns":{"WyjÄ
cy WÄ
wĂłz":[[58,30],[7,10],[58,51],[35,3],[52,72],[8,75],[58,18],[54,50],[21,41],[50,32],[50,7],[44,71],[40,87],[14,36],[23,71],[38,53]],"WyjÄ
ca Jaskinia":[[14,61],[35,28],[54,27],[23,51],[4,19],[24,19],[50,32],[10,18],[32,7],[17,60],[50,25]],"NiedĹşwiedzie Urwisko":[[20,6],[34,8],[33,23]],"Babi wzgĂłrek":[[36,43],[55,7],[40,4],[54,78],[41,2],[34,54],[41,78],[56,67],[60,36],[12,60],[19,22],[15,88],[38,25],[38,33]],"GĂłralska Pieczara p.1":[[19,17],[19,22],[25,24],[35,4],[34,12]],"GĂłralska Pieczara p.2":[[7,5],[15,20],[5,31]],"GĂłralska Pieczara p.3":[[16,28],[24,38]],"GĂłralskie przejĹcie":[[29,2],[38,46],[28,19],[48,87],[48,70],[42,64],[60,70],[3,46],[7,9],[22,39],[18,53],[56,5],[47,2],[33,27],[8,72],[6,46]],"Grota Halnego Wiatru p.1":[[4,12]],"Grota Halnego Wiatru p.2":[[26,27],[5,31],[7,5],[13,17]]}},"Lichwiarz Grauhaz":{"lvl":129,"prof":"w","spawns":{"286":[[7,16],[50,48]],"287":[[26,30]],"594":[[29,18]],"1192":[[55,48],[30,54]],"1227":[[6,43],[54,10],[51,21],[49,42]],"1228":[[8,51],[51,3],[5,18],[42,37]],"1229":[[53,9],[11,43],[8,13],[7,16],[37,40]],"1231":[[39,58],[33,47],[12,11]],"1232":[[41,14],[33,7],[58,11],[42,25]],"1234":[[21,19],[46,53],[5,39],[6,23]],"3468":[[32,32]],"3469":[[13,14]],"3470":[[18,27],[30,5],[21,31],[59,56]],"3471":[[39,6]],"3472":[[44,50]],"3473":[[36,43],[66,9]],"ĹnieĹźna Grota p.2":[[34,10]],"KrysztaĹowa Sala Smutku":[[16,7]],"PrzejĹcie magicznego mrozu":[[41,49]],"PrzejĹcie lodowatego wiatru":[[6,33]],"Szlak Thorpa p.2":[[32,32]],"Zasypane Ograbar-Dun":[[55,48],[30,54]],"PrzejĹcie zamarzniÄtych koĹci":[29,18]}},"ObĹÄ
kany Ĺowca OrkĂłw":{"lvl":144,"prof":"w","spawns":{"344":[[25,8],[61,36],[45,23],[86,4],[25,38],[45,61],[14,4],[24,40],[85,33],[19,10]],"ZĹudny Trakt":[[38,13],[58,17],[17,5],[9,51],[21,6],[7,59],[32,16],[37,9]],"Orcza WyĹźyna":[[74,47],[16,16],[52,12],[59,35],[87,7]],"Grota Orczych SzamanĂłw":[[12,19]],"Osada Czerwonych OrkĂłw":[[18,24],[19,23],[14,25],[62,42],[35,27],[41,78],[43,4],[60,47]],"Siedziba Rady OrkĂłw":[[11,25]],"Nawiedzone Kazamaty p.1":[[19,33],[45,13],[10,44],[42,39],[6,43],[45,9],[12,6],[32,16],[10,16],[25,7],[40,38],[16,16],[36,7]],"Nawiedzone Kazamaty p.3":[[27,22],[26,22]],"Nawiedzone Kazamaty p.4":[[19,36],[12,13],[48,19],[4,9],[9,9],[31,18],[7,25],[45,39],[31,19],[16,22],[34,30],[41,41],[6,45],[29,42],[48,38],[32,10],[5,30]],"Nawiedzone Kazamaty p.5":[[4,41],[26,13],[49,27],[9,33],[6,15],[31,35],[10,20],[4,43],[41,26],[8,16]],"Nawiedzone Kazamaty p.6":[[27,36]]}},"CzarujÄ
ca Atalia":{"lvl":157,"prof":"m","spawns":{"1293":[[5,5],[46,56],[10,59],[82,4],[62,50],[89,24]],"1294":[[34,11],[54,12],[27,16],[46,40],[19,51]],"1297":[[45,4],[55,11],[44,54],[75,33],[1,43]],"1298":[[7,7],[9,16]],"1299":[[17,7],[23,13],[19,6]],"1300":[[5,8]],"1301":[[6,8],[2,6]],"1303":[[15,10],[11,13]],"1308":[[4,5],[9,10]]}},"ĹwiÄty Braciszek":{"lvl":165,"prof":"b","spawns":{"Dom Rumiry i Dobromira p.1":[[5,7]],"Sklep z winem":[[5,7]],"Dom Wazira":[[6,6]],"Magazyn win p.1":[[6,5]],"Jezioro WaĹźek":[[17,11],[86,9],[7,57],[59,43]],"PachnÄ
cy GÄ
szcz":[[88,43],[26,44],[28,5]],"Las Zadumy":[[11,30],[46,47],[85,23]],"Agia Triada":[[67,38],[18,57],[34,21],[59,43]],"Grota DrÄ
ĹźÄ
cych Kropli p.1":[],"Grota DrÄ
ĹźÄ
cych Kropli p.2":[[11,8]],"Klasztor RóşanitĂłw - korytarz wejĹciowy":[[6,8],[5,8]],"Klasztor RóşanitĂłw - pomieszczenie gospodarcze":[[9,12]],"Klasztor RóşanitĂłw - klasztorny browar":[[12,6]],"Klasztor RóşanitĂłw - klasztorna piekarnia":[[2,10]],"Klasztor RóşanitĂłw - warsztat":[[12,6]],"Klasztor RóşanitĂłw - wirydarz":[[8,14]],"Klasztor RóşanitĂłw - dormitoria":[[13,15]],"Klasztor RóşanitĂłw - refektarz":[[4,22]],"Klasztor RóşanitĂłw - fraternia":[[5,15]],"Klasztor RóşanitĂłw - dzwonnica":[[11,8]],"Klasztor RóşanitĂłw - piwniczka":[[6,6]],"Klasztor RóşanitĂłw - lawaterz":[[3,10]],"Klasztor RóşanitĂłw - klatka schodowa":[[8,8],[8,12]],"Klasztor RóşanitĂłw - kapitularz":[[3,15]],"Klasztor RóşanitĂłw - ĹwiÄ
tynia":[[44,25],[8,14]],"Klasztor RóşanitĂłw - magazyn ksiÄ
g":[[11,5]],"Klasztor RóşanitĂłw - cela opata":[[10,6]],"Klasztor RóşanitĂłw - wieĹźa pĹn.-zach. p.1":[[9,12]],"Klasztor RóşanitĂłw - wieĹźa pĹn.-zach. p.2":[[10,12]],"Klasztor RóşanitĂłw - wieĹźa pĹn.-wsch. p.1":[[4,11]],"Klasztor RóşanitĂłw - strych p.1":[[20,12]],"Klasztor RóşanitĂłw - strych p.2":[[31,6],[22,20]],"Tunel pod SkaĹÄ
p.1":[[14,53],[13,54]],"Tunel pod SkaĹÄ
p.2":[[45,41]],"Tunel pod SkaĹÄ
p.3":[[10,24]],"Ogrza kawerna p.1":[[26,4]],"Ogrza kawerna p.2":[[49,18]],"Ogrza kawerna p.3":[[26,16],[52,8]]}},"Viviana Nandid":{"lvl":184,"prof":"h","spawns":{"2056":[[16,6],[85,13],[68,46],[85,51],[8,26],[8,9],[56,14],[63,5],[22,23]],"Rozlewisko Kai":[[1,8],[28,14],[41,8],[12,32],[14,14],[71,62],[21,48],[13,55],[27,53],[75,26],[46,50],[42,14]],"Ruiny Tass Zhil":[[37,5],[57,21],[21,7],[55,40],[67,18],[50,12],[80,1],[10,45],[8,10],[59,52],[5,41],[37,5],[14,58],[62,58]],"BĹota Sham Al":[[31,3],[51,11],[35,26],[5,40],[6,26],[32,38],[30,10]],"Gvar Hamryd":[[15,6],[72,5],[50,37],[63,19],[73,50],[3,27],[86,39],[6,44],[16,60],[90,27],[32,60],[25,26],[32,37],[53,35],[44,57],[77,60],[39,35]]}},"Mulher Ma":{"lvl":197,"prof":"b","spawns":{"114":[[71,4],[33,44],[25,18]],"574":[[22,3]],"575":[[14,53]],"730":[[90,9],[93,61]],"731":[[91,33],[14,4]],"865":[[11,5]],"1992":[[19,18]],"2002":[[4,17]],"2020":[[22,36],[48,41],[15,40],[76,58],[70,37],[74,58]],"2056":[[13,49],[65,38],[89,41]],"2063":[[18,48],[52,11]],"2126":[[7,6]],"2127":[[8,13]],"2163":[[6,8]],"2183":[[10,11],[18,14]],"2432":[[4,5]]}},"Demonis Pan NicoĹci":{"lvl":210,"prof":"m","spawns":{"971":[[14,15],[30,41],[30,32],[59,34],[15,34],[33,7],[15,17]],"973":[[48,33],[73,24],[89,49],[48,53],[48,14],[24,30],[23,30],[48,13],[48,34],[88,50],[73,23]],"974":[[15,27]],"975":[[18,11],[44,33],[18,12]],"976":[[32,44],[50,45],[50,46]],"977":[[47,45]]}},"Vapor Veneno":{"lvl":227,"prof":"w","spawns":{"1399":[[14,10],[63,9]],"1448":[[63,50],[63,23],[81,36],[53,7],[91,10],[40,37]],"1449":[[81,34],[86,52],[57,34],[53,51],[14,50],[32,33],[87,59],[27,35]],"1458":[[30,20],[2,25],[77,42],[51,29]],"1464":[[9,18]],"2902":[[20,23],[37,26]],"3135":[[50,57],[11,24],[29,47],[14,4],[17,45],[34,19],[58,34]],"3136":[[40,84],[47,11],[29,7],[24,74],[24,43],[12,52],[57,28],[54,76],[37,53],[43,29]],"3137":[[57,50],[49,39],[57,14],[33,29],[23,9]],"3138":[[37,83],[38,56],[18,57],[47,46],[50,87]],"3209":[[55,80],[52,60],[24,46],[39,51],[10,7],[8,78],[8,49],[31,78]]}},"DÄboroĹźec":{"lvl":242,"prof":"w","spawns":{"3594":[[28,28],[41,46],[11,21],[80,50]],"3595":[[33,28],[75,27],[85,50]],"3596":[[40,8],[58,26],[60,50]],"3597":[[31,83],[2,31]],"3598":[[34,11],[46,48]],"3610":[[39,11],[7,57],[52,45]],"3611":[[30,9]],"3612":[[19,17],[17,17]],"3613":[[21,8],[52,22]],"3614":[[11,15]],"3615":[[13,11]],"3620":[[7,13]],"3621":[[11,18]],"3622":[[36,22]],"3623":[[17,17]],"3624":[[12,19]],"3625":[[23,27]],"3626":[[9,12]],"3627":[[20,23]]}},"Tepeyollotl":{"lvl":260,"prof":"b","spawns":{"1901":[[50,11],[18,71],[45,20],[24,33],[19,49]],"1924":[[10,7],[70,22],[76,47]],"1926":[[8,76],[11,16],[12,87],[5,76]],"1963":[[9,6]],"1964":[[17,7]],"1966":[[16,27]],"1982":[[13,19]],"3029":[[8,10]],"3030":[[10,20]],"3031":[[10,13]],"3032":[[49,22],[11,15],[17,35]],"3033":[[12,40],[70,40]],"3034":[[19,19]],"3035":[[31,31]],"3036":[[13,40],[14,40],[16,19],[16,8]],"3037":[[30,26],[37,13]],"3038":[[24,6],[21,32]],"3039":[[32,72]],"3040":[[12,12]],"3041":[[17,15],[15,12]],"3042":[[21,25],[22,24]],"3043":[[22,41],[32,11],[54,9],[9,19]]}},"MĹody Smok":{"lvl":282,"prof":"m","spawns":{"Pustynia Shaiharrud - wschĂłd":[[5,2],[47,24],[24,61],[4,38],[21,76]],"Pustynia Shaiharrud - zachĂłd":[[4,19],[26,8],[52,38],[22,85]],"Urwisko Vapora":[[64,37],[83,48],[29,46],[20,58]],"Jaskinia SÄpa s.1":[[27,11]],"Jaskinia Piaskowej Burzy s.1":[[16,8]],"Jaskinia Smoczej Paszczy p.1":[[31,34]],"Jaskinia Smoczej Paszczy p.2":[[25,27]],"Jurta Nomadzka":[[3,6]],"Jaskinia Piaskowej Burzy s.2":[[5,20]],"ĹwiÄ
tynia Hebrehotha - przedsionek":[[26,12]],"SkaĹy UmarĹych":[[31,87],[54,70],[60,30],[30,31]],"Jaskinia PrĂłby":[[14,19]],"Jaskinia Odwagi":[[31,40],[29,11]],"Smocze Skalisko":[[52,50],[67,27]],"SÄpiarnia":[[7,5]],"Grota PoĹwiÄcenia":[[4,21]]}}};
1885 var eliteDB = {
1886 //elity do dziennego questa w margonem.com
1887 "Masked Blaise": {
1888 lvl: -1,
1889 ver: "en",
1890 //spawns: {196:[[8,5]]} w sumie to ich na caĹÄ
mapÄ Ĺaduje wiÄc bez sensu
1891 },
1892 "Cula Joshua": {
1893 lvl: -1,
1894 ver: "en",
1895 spawns: {}
1896 },
1897 "Mola Nito": {
1898 lvl: -1,
1899 ver: "en",
1900 spawns: {}
1901 },
1902 "Toto Acirfa": {
1903 lvl: -1,
1904 ver: "en",
1905 spawns: {}
1906 },
1907 "Masked Roman": {
1908 lvl: -1,
1909 ver: "en",
1910 spawns: {}
1911 },
1912 "Possessed Fissit": {
1913 lvl: -1,
1914 ver: "en",
1915 spawns: {}
1916 },
1917 "Soda": {
1918 lvl: -1,
1919 ver: "en",
1920 spawns: {}
1921 },
1922 "Molybdenum Matityahu": {
1923 lvl: -1,
1924 ver: "en",
1925 spawns: {}
1926 },
1927 "Hummopapa": {
1928 lvl: -1,
1929 ver: "en",
1930 spawns: {}
1931 },
1932 "Shponder":{
1933 lvl: -1,
1934 ver:"en",
1935 spawns:{}
1936 },
1937 "Mobile Jeecus":{
1938 lvl: -1,
1939 ver:"en",
1940 spawns:{}
1941 }
1942 };
1943
1944 this.getHerosDB = function() {
1945 return herosDB;
1946 };
1947
1948 var niceSettings = new (function(options) {
1949 var self = this;
1950 var {get, set, data, header, onSave} = options;
1951 var panels = {};
1952 var $currentPanel = false;
1953 var $activeLPanelEntry;
1954 var $rpanel;
1955 var $wrapper;
1956 var shown = false;
1957 this.toggle = function() {
1958 var lock = interface == "new" ? Engine.lock : (interface == "old" ? g.lock : null);
1959 if (shown) {
1960 if (lock) lock.remove("ns-"+header);
1961 else global.dontmove = false;
1962 $wrapper.style["display"] = "none";
1963 } else {
1964 if (lock) lock.add("ns-"+header);
1965 else global.dontmove = true;
1966 $wrapper.style["display"] = "block";
1967 };
1968 shown = !shown;
1969 };
1970 this.initHTML = function() {
1971 $wrapper = document.createElement("div");
1972 $wrapper.classList.add("ns-wrapper");
1973 document.body.appendChild($wrapper);
1974
1975 var $header = document.createElement("div");
1976 $header.innerHTML = header + " - ustawienia";
1977 $header.classList.add("ns-header");
1978 $wrapper.appendChild($header);
1979
1980 var $close = document.createElement("div");
1981 $close.innerHTML = "X";
1982 $close.classList.add("ns-close");
1983 $close.addEventListener("click", this.toggle);
1984 $wrapper.appendChild($close);
1985
1986 var $panels = document.createElement("div");
1987 $panels.classList.add("ns-panels");
1988 $wrapper.appendChild($panels);
1989
1990 var $lpanel = document.createElement("div");
1991 $lpanel.addEventListener("click", this.lPanelClick);
1992 $lpanel.classList.add("ns-lpanel");
1993 $panels.appendChild($lpanel);
1994
1995 $rpanel = document.createElement("div");
1996 $rpanel.classList.add("ns-rpanel");
1997 $rpanel.addEventListener("click", this.globalRpanelHandler);
1998 $panels.appendChild($rpanel);
1999
2000 $lpanel.innerHTML = this.generateLpanelHtml();
2001 this.genereteRpanels();
2002 };
2003 this.lPanelClick = function(e) {
2004 if (e.target.dataset["name"]) {
2005 self.togglePanel(e.target.dataset["name"]);
2006 if ($activeLPanelEntry) $activeLPanelEntry.classList.remove("active");
2007 $activeLPanelEntry = e.target;
2008 $activeLPanelEntry.classList.add("active");
2009 };
2010 };
2011 this.globalRpanelHandler = function(e) {
2012 var tar = e.target;
2013 if (tar.dataset["listbtt"]) {
2014 var key = tar.dataset["listbtt"];
2015 var $content = document.querySelector(".ns-list-content[data-list='"+key+"']");
2016 var $input = document.querySelector("input[data-list='"+key+"']");
2017 self.adddContentToList($content, $input);
2018 } else if (tar.dataset["listitem"]) {
2019 tar.remove();
2020 };
2021 };
2022 this.adddContentToList = function($content, $input) {
2023 var val = $input.value;
2024 if (val == "") return;
2025 $input.value = "";
2026 var items = this.getContentItems($content);
2027 if (items.indexOf(val) > -1) return
2028 var $div = document.createElement("div");
2029 $div.classList.add("ns-list-item");
2030 $div.dataset["listitem"] = "1";
2031 $div.innerText = val;
2032 $content.appendChild($div);
2033 };
2034 this.getContentItems = function($content) {
2035 var items = [];
2036 for (var i=0; i<$content.children.length; i++) {
2037 items.push($content.children[i].innerHTML);
2038 };
2039 return items;
2040 };
2041 this.togglePanel = function(name) {
2042 if ($currentPanel) $currentPanel.remove();
2043 $currentPanel = panels[name];
2044 $rpanel.appendChild($currentPanel);
2045 this.setAsyncPanelContent(name);
2046 };
2047 this.setAsyncPanelContent = function(name) {
2048 var entries = options.data[name];
2049 for (var i=0; i<entries.length; i++) {
2050 var entry = entries[i];
2051 if (entry.asyncid) {
2052 entry.fun(val => {
2053 var el = document.getElementById(entry.asyncid);
2054 if (el) el.innerHTML = val;
2055 });
2056 };
2057 };
2058 };
2059 this.genereteRpanels = function() {
2060 for (var name in data) {
2061 this.generateRpanel(name, data[name]);
2062 };
2063 };
2064 this.generateRpanel = function(name, content) {
2065 var $panel = document.createElement("div");
2066 panels[name] = $panel;
2067 var html = "";
2068 for (var i=0; i<content.length; i++) {
2069 html += this.generateRpanelEntryHtml(content[i]);
2070 };
2071 $panel.innerHTML = html;
2072 var $btt = document.createElement("div");
2073 $btt.innerHTML = "Zapisz";
2074 $btt.classList.add("ns-save-button");
2075 $btt.addEventListener("click", () => this.savePanel(name));
2076 $panel.appendChild($btt);
2077 };
2078 this.generateRpanelEntryHtml = function(entry) {
2079 var {type, special} = this.getEntryType(entry.type);
2080 if (!special) {
2081 var input = "<input data-key='"+entry.key+"' type='"+type+"' value='"+get(entry.key)+"'></input>";
2082 return this.getRpanelEntry(entry.name, input, entry.tip);
2083 } else {
2084 if (type == "range") {
2085 var input = "<input data-key='"+entry.key+"' type='"+type+"' value='"+get(entry.key)*100+"' min='"+entry.data[0]*100+"' max='"+entry.data[1]*100+"'></input>";
2086 return this.getRpanelEntry(entry.name, input, entry.tip);
2087 } else if (type == "checkbox") {
2088 var input = "<input data-key='"+entry.key+"' type='"+type+"' "+(get(entry.key) ? "checked" : "")+"></input>";
2089 return this.getRpanelEntry(entry.name, input, entry.tip);
2090 } else if (special == "char") {
2091 var input = "<input data-key='"+entry.key+"' type='"+type+"' value='"+String.fromCharCode(get(entry.key))+"' maxlength='1' style='width: 10px; text-align: center'></input>";
2092 return this.getRpanelEntry(entry.name, input, entry.tip);
2093 } else if (special == "noinput") {
2094 if (type != "async") {
2095 return this.getRpanelEntry(entry.t1, entry.t2, entry.tip);
2096 } else {
2097 var id = "NS-async-"+Math.random()*10;
2098 entry.asyncid = id;
2099 return this.getRpanelEntry(entry.t1, "<div id='"+id+"'>"+entry.placeholder+"</div>", entry.tip);
2100 };
2101 } else if (type == "list") {
2102 return this.generateListInput(entry);
2103 };
2104 };
2105 };
2106 this.generateListInput = function(entry) {
2107 var list = get(entry.key);
2108 var html;
2109 html = "<div class='ns-list-wrapper'>";
2110 html += "<div class='ns-list-header'>"+entry.name+"</div>";
2111 html += "<div class='ns-list-content' data-list='"+entry.key+"'>";
2112 for (var i=0; i<list.length; i++) {
2113 html += "<div class='ns-list-item' data-listitem='1'>"+list[i]+"</div>";
2114 };
2115 html += "</div>";
2116 html += "<div class='ns-list-bottombar'>";
2117 html += "<div class='ns-list-input'><input data-list='"+entry.key+"' type='text'></div>";
2118 html += "<div class='ns-list-addbtt' data-listbtt='"+entry.key+"'>+</div>";
2119 html += "</div>";
2120 html += "</div>";
2121 return html;
2122 };
2123 this.getRpanelEntry = function(txt, input, tip) {
2124 return "<div "+(tip ? (interface == "new" ? "data-tip" : "tip") + "='"+tip+"'" : "")+" class='ns-rpanel-entry'><div class='ns-rpanel-entry-left'>"+txt+"</div><div class='ns-rpanel-entry-right'>"+input+"</div></div>";
2125 };
2126 this.getEntryType = function(entrytype) {
2127 var special = false;
2128 switch (entrytype) {
2129 case "string":
2130 var type = "text";
2131 break;
2132 case "color":
2133 var type = "color";
2134 break;
2135 case "range":
2136 special = true;
2137 var type = "range";
2138 break;
2139 case "check":
2140 special = true;
2141 var type = "checkbox";
2142 break;
2143 case "char":
2144 special = "char";
2145 var type = "text";
2146 break;
2147 case "list":
2148 special = true;
2149 var type = "list";
2150 break;
2151 case "numstring":
2152 var type = "number";
2153 break;
2154 case "info-async":
2155 var type = "async";
2156 special = "noinput";
2157 break;
2158 default:
2159 special = "noinput";
2160 };
2161 return {
2162 type: type,
2163 special: special
2164 };
2165 }
2166 this.generateLpanelHtml = function() {
2167 var html = "";
2168 for (var name in data) {
2169 html += "<div class='ns-lpanel-entry' data-name='"+name+"'>"+name+"</div>";
2170 };
2171 return html;
2172 };
2173 this.savePanel = function(name) {
2174 var panel = data[name];
2175 for (var i=0; i<panel.length; i++) {
2176 this.savePanelEntry(panel[i]);
2177 };
2178 onSave();
2179 };
2180 this.savePanelEntry = function(entry) {
2181 var {type, special} = this.getEntryType(entry.type);
2182 if (!special) {
2183 var val = this.getEntryValue(entry.key);
2184 if (type == "number") {
2185 val = parseInt(val);
2186 if (isNaN(val)) return;
2187 };
2188 set(entry.key, val);
2189 } else {
2190 if (type == "range") {
2191 set(entry.key, this.getEntryValue(entry.key)/100);
2192 } else if (type == "checkbox") {
2193 set(entry.key, this.getCheckboxState(entry.key));
2194 } else if (special == "char") {
2195 var val = this.getEntryValue(entry.key).toUpperCase().charCodeAt(0);
2196 if (isNaN(val)) return;
2197 set(entry.key, val);
2198 } else if (type == "list") {
2199 var $content = document.querySelector(".ns-list-content[data-list='"+entry.key+"']");
2200 var items = this.getContentItems($content);
2201 set(entry.key, items);
2202 };
2203 };
2204 };
2205 this.getEntryValue = function(key) {
2206 return document.querySelector("input[data-key='"+key+"']").value;
2207 };
2208 this.getCheckboxState = function(key) {
2209 return document.querySelector("input[data-key='"+key+"']").checked;
2210 };
2211 this.initCss = function() {
2212 var css = `
2213 .ns-wrapper {
2214 width: 600px;
2215 height: 600px;
2216 background: rgba(0,0,0,.8);
2217 border: 2px solid #222222;
2218 border-radius: 20px;
2219 position: absolute;
2220 left: calc(50% - 300px);
2221 top: calc(50% - 300px);
2222 z-index: 500;
2223 color: white;
2224 display: none;
2225 ${interface == "superold" ? "transform: scale(0.8, 0.8);" : ""}
2226 }
2227 .ns-wrapper .ns-close {
2228 width: 30px;
2229 height: 30px;
2230 font-size: 20px;
2231 line-height: 30px;
2232 text-align: center;
2233 background: rgba(0,0,0,.6);
2234 transition: background .1s ease-in-out;
2235 position: absolute;
2236 right: 3px;
2237 top: 3px;
2238 cursor: pointer;
2239 }
2240 .ns-wrapper .ns-close:hover {
2241 background: rgba(0,0,0,.9);
2242 }
2243 .ns-wrapper .ns-header {
2244 border-bottom: 1px solid #333333;
2245 font-size: 26px;
2246 padding-left: 15px;
2247 color: white;
2248 height: 39px;
2249 line-height: 40px;
2250 background: rgba(50,50,50,.8);
2251 }
2252 .ns-wrapper .ns-panels {
2253 height: 560px;
2254 }
2255 .ns-wrapper .ns-panels .ns-lpanel {
2256 height: 560px;
2257 width: 200px;
2258 border-right: 1px solid #333333;
2259 float: left;
2260 }
2261 .ns-wrapper .ns-panels .ns-lpanel .ns-lpanel-entry {
2262 width: 75%;
2263 height: 30px;
2264 line-height: 30px;
2265 font-size: 19px;
2266 padding-left: 5px;
2267 background: linear-gradient(to right, rgba(100,100,100,0.45) , rgba(100,100,100,0));
2268 transition: all .15s ease-in-out;
2269 cursor: pointer;
2270 margin-bottom: 1px;
2271 }
2272 .ns-wrapper .ns-panels .ns-lpanel .ns-lpanel-entry.active {
2273 background: linear-gradient(to right, rgba(150,150,150,0.45) , rgba(150,150,150,0));
2274 width: 100%;
2275 padding-left: 13px;
2276 }
2277 .ns-wrapper .ns-panels .ns-lpanel .ns-lpanel-entry:hover {
2278 width: 100%;
2279 padding-left: 13px;
2280 }
2281 .ns-wrapper .ns-panels .ns-rpanel {
2282 height: 560px;
2283 width: 390px;
2284 float: left;
2285 }
2286 .ns-wrapper .ns-panels .ns-rpanel .ns-rpanel-entry {
2287 height: 30px;
2288 margin: 3px;
2289 line-height: 30px;
2290 background: rgba(50,50,50,0.5);
2291 }
2292 .ns-panels .ns-rpanel .ns-rpanel-entry .ns-rpanel-entry-left {
2293 float: left;
2294 height: 30px;
2295 width: 180px;
2296 padding-left: 6px;
2297 }
2298 .ns-panels .ns-rpanel .ns-rpanel-entry .ns-rpanel-entry-right {
2299 float: right;
2300 height: 30px;
2301 width: 180px;
2302 text-align: right;
2303 padding-right: 6px;
2304 }
2305 .ns-rpanel .ns-rpanel-entry .ns-rpanel-entry-right input[type='color'] {
2306 background: black;
2307 border: none;
2308 transition: background .15s ease-in-out;
2309 }
2310 .ns-rpanel .ns-rpanel-entry .ns-rpanel-entry-right input[type='color']:hover {
2311 background: #282828;
2312 }
2313 .ns-rpanel .ns-rpanel-entry .ns-rpanel-entry-right input[type='text'], .ns-rpanel .ns-rpanel-entry .ns-rpanel-entry-right input[type='number'] {
2314 background: rgba(0,0,0,0.8);
2315 border: 1px solid black;
2316 width: 80px;
2317 color: #CCCCCC;
2318 text-align: right;
2319 }
2320 .ns-rpanel .ns-save-button {
2321 position: absolute;
2322 bottom: 10px;
2323 right: 10px;
2324 height: 30px;
2325 width: 70px;
2326 font-size: 20px;
2327 line-height: 30px;
2328 text-align: center;
2329 border: 1px solid #333333;
2330 background: rgba(50,50,50,0.5);
2331 cursor: pointer;
2332 transition: background .1s ease-in-out;
2333 }
2334 .ns-rpanel .ns-save-button:hover {
2335 background: rgba(50,50,50,0.7);
2336 }
2337 .ns-list-wrapper {
2338 background: rgba(50,50,50,0.5);
2339 width: 350px;
2340 margin: 10px;
2341 border: 1px solid #333333;
2342 }
2343 .ns-list-wrapper .ns-list-header {
2344 text-align: center;
2345 height: 20px;
2346 font-size: 15px;
2347 line-height: 20px;
2348 }
2349 .ns-list-wrapper .ns-list-content {
2350 min-height: 80px;
2351 max-height: 1700px;
2352 overflow-y: auto;
2353 border-top: 1px solid #333333;
2354 border-bottom: 1px solid #333333;
2355 }
2356 .ns-list-wrapper .ns-list-content .ns-list-item {
2357 cursor: pointer;
2358 margin: 1px;
2359 background: rgba(50,50,50,0.4);
2360 text-align: center;
2361 height: 15px;
2362 line-height: 15px;
2363 font-size: 12px;
2364 }
2365 .ns-list-wrapper .ns-list-bottombar {
2366 height: 20px;
2367 }
2368 .ns-list-wrapper .ns-list-bottombar .ns-list-input {
2369 float: left;
2370 width: 270px;
2371 }
2372 .ns-list-wrapper .ns-list-bottombar .ns-list-input input {
2373 background: rgba(0,0,0,0.8);
2374 border: 1px solid black;
2375 color: #CCCCCC;
2376 width: 320px;
2377 }
2378 .ns-list-wrapper .ns-list-bottombar .ns-list-addbtt {
2379 width: 20px;
2380 float: right;
2381 text-align: center;
2382 line-height: 20px;
2383 background: rgba(50,50,50,0.6);
2384 cursor: pointer;
2385 }
2386 .ns-list-wrapper .ns-list-bottombar .ns-list-addbtt:hover {
2387 background: rgba(50,50,50,0.9);
2388 }
2389 `;
2390 var $style = document.createElement("style");
2391 $style.innerHTML = css;
2392 document.head.appendChild($style);
2393 };
2394 this.init = function() {
2395 this.initHTML();
2396 this.initCss();
2397 };
2398})({
2399 get: settings.get,
2400 set: settings.set,
2401 onSave: this.onSettingsUpdate,
2402 header: "miniMapPlus",
2403 data: {
2404 "Kolory": [
2405 {
2406 key: "/colors/hero",
2407 name: "Twoja postaÄ",
2408 type: "color"
2409 },
2410 {
2411 key: "/colors/other",
2412 name: "Inni gracze",
2413 type: "color"
2414 },
2415 {
2416 key: "/colors/friend",
2417 name: "Znajomi",
2418 type: "color"
2419 },
2420 {
2421 key: "/colors/enemy",
2422 name: "Wrogowie",
2423 type: "color"
2424 },
2425 {
2426 key: "/colors/clan",
2427 name: "Klanowicze",
2428 type: "color"
2429 },
2430 {
2431 key: "/colors/ally",
2432 name: "Sojusznicy",
2433 type: "color"
2434 },
2435 {
2436 key: "/colors/npc",
2437 name: "ZwykĹy NPC",
2438 type: "color"
2439 },
2440 {
2441 key: "/colors/mob",
2442 name: "ZwykĹy mob",
2443 type: "color"
2444 },
2445 {
2446 key: "/colors/elite",
2447 name: "Elita",
2448 type: "color"
2449 },
2450 {
2451 key: "/colors/elite2",
2452 name: "Elita II/eventowa",
2453 type: "color"
2454 },
2455 {
2456 key: "/colors/elite3",
2457 name: "Elita III",
2458 type: "color"
2459 },
2460 {
2461 key: "/colors/heros",
2462 name: "Heros",
2463 type: "color"
2464 },
2465 {
2466 key: "/colors/titan",
2467 name: "Tytan",
2468 type: "color"
2469 },
2470 {
2471 key: "/colors/item",
2472 name: "Przedmiot",
2473 type: "color"
2474 },
2475 {
2476 key: "/colors/gw",
2477 name: "PrzejĹcie",
2478 type: "color"
2479 }
2480 ],
2481 "WyglÄ
d mapy": [
2482 {
2483 key: "/mapsize",
2484 name: "Rozmiar mapy",
2485 type: "range",
2486 tip: "Zmiany widoczne po odĹwieĹźeniu gry",
2487 data: [0.6, 1.4]
2488 },
2489 {
2490 key: "/opacity",
2491 name: "WidocznoĹÄ mapy",
2492 type: "range",
2493 data: [0.5, 1]
2494 },
2495 {
2496 key: "/darkmode",
2497 name: "Motyw ciemny",
2498 type: "check"
2499 }
2500 ],
2501 "Tracking": [
2502 {
2503 type: "info",
2504 t1: "Co to jest?",
2505 t2: "",
2506 tip: "Tracking (tropienie) to alternatywna opcja wyszukiwania NPC/itemĂłw na mapie. Polega na tym, Ĺźe gdy na mapie pojawi siÄ coĹ z poniĹźszej listy, w oknie gry ukaĹźe siÄ strzaĹka, ktĂłra bÄdzie wzkazywaĹa drogÄ do tej rzeczy.<br>Dodatkowo gdy na mapie pojawia siÄ heros, automatycznie uruchamia siÄ tracking na niego, co jest przydatne np. w podchodzeniu do herosĂłw eventowych."
2507 },
2508 {
2509 key: "/trackedNpcs",
2510 name: "Tracking NPC",
2511 type: "list"
2512 },
2513 {
2514 key: "/trackedItems",
2515 name: "Tracking itemĂłw",
2516 type: "list"
2517 }
2518
2519 ],
2520 "Inne": [
2521 {
2522 key: "/minlvl",
2523 name: "Min. lvl potworkĂłw",
2524 type: "numstring"
2525 },
2526 {
2527 key: "/maxlvl",
2528 name: "Max. przewaga",
2529 tip: "Maksymalna róşnica poziomĂłw miÄdzy TobÄ
a potworkiem przy ktĂłrej nie niszczy siÄ loot na Ĺwiecie na ktĂłrym grasz. JeĹli nie wiesz co to, zostaw 13.",
2530 type: "numstring"
2531 },
2532 {
2533 key: "/show",
2534 name: "Hotkey",
2535 type: "char"
2536 },
2537 {
2538 key: "/altmobilebtt",
2539 name: "PrzesuĹ przycisk mobilny",
2540 type: "check",
2541 tip: "Przesuwa przycisk widoczny na urzÄ
dzeniach mobilnych pomiÄdzy torby"
2542 },
2543 {
2544 key: "/forceMobileMode",
2545 name: "WymuĹ przycisk mobilny",
2546 type: "check",
2547 tip: "Pokazuje przycisk mobilny nawet, jeĹli nie jest siÄ na odpowiednim urzÄ
dzeniu"
2548 },
2549 {
2550 key: "/interpolerate",
2551 name: "Animacje na mapie",
2552 type: "check"
2553 },
2554 {
2555 key: "/showqm",
2556 name: "Zaznaczaj questy",
2557 type: "check"
2558 },
2559 {
2560 key: "/novisibility",
2561 name: "Nie pokazuj \"mgĹy wojny\"",
2562 type: "check",
2563 tip: "WyĹÄ
cza pokazywanie widzianego obszaru na czerwonych mapach.<br>Nie pozdrawiam klanu Game Over (Jaruna), ktĂłry utrudniaĹ testowanie tej funkcjonalnoĹci dedajÄ
c mnie bez powodu."
2564 }
2565 /*,
2566 {
2567 key: "/showevonetwork",
2568 name: "Pokazuj postacie z WSync",
2569 tip: "World Sync to dodatek stworzony przez CcarderRa, ktĂłry pozwala widzieÄ graczy z innych ĹwiatĂłw. Jest czÄĹciÄ
Evolution Managera, ktĂłrego moĹźna znaleĹşÄ na forum w dziale Dodatki do gry.",
2570 type: "check"
2571 }*/
2572 ],
2573 "Informacje": [
2574 {
2575 type: "info",
2576 t1: "Wersja",
2577 t2: "v"+this.version+(interface == "new" ? " NI" : (interface == "old" ? " SI" : " OM"))
2578 },
2579 {
2580 type: "info",
2581 t1: "ĹšrĂłdĹo instalacji",
2582 t2: this.getInstallSource()
2583 },
2584 {
2585 type: "info-async",
2586 t1: "Licznik instalacji",
2587 placeholder: "wczytywanie...",
2588 tip: "Liczy od wersji 3.1 minimapy",
2589 fun: this.installationCounter.get
2590 }
2591 ]
2592 }
2593});
2594 this.init();
2595 niceSettings.init();
2596})();