/* utils.js 工具类 */ "use strict"; function utils() { this._init(); this.scan = { 'up': {'x': 0, 'y': -1}, 'left': {'x': -1, 'y': 0}, 'down': {'x': 0, 'y': 1}, 'right': {'x': 1, 'y': 0} }; } utils.prototype._init = function () { // 定义Object.assign if (typeof Object.assign != "function") { Object.assign = function (target, varArgs) { // .length of function is 2 if (target == null) { // TypeError if undefined or null throw new TypeError('Cannot convert undefined or null to object'); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource != null) { // Skip over if undefined or null for (var nextKey in nextSource) { // Avoid bugs when hasOwnProperty is shadowed if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }; } if (typeof String.prototype.endsWith != "function") { String.prototype.endsWith = function (search, this_len) { if (this_len === undefined || this_len > this.length) { this_len = this.length; } return this.substring(this_len - search.length, this_len) === search; }; } } ////// 将文字中的${和}(表达式)进行替换 ////// utils.prototype.replaceText = function (text, need, times) { return text.replace(/\${(.*?)}/g, function (word, value) { return core.calValue(value, null, need, times); }); } ////// 计算表达式的值 ////// utils.prototype.calValue = function (value, prefix, need, times) { if (!core.isset(value)) return null; if (typeof value === 'string') { value = value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')"); value = value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')"); value = value.replace(/flag:([\w\d_]+)/g, "core.getFlag('$1', 0)"); value = value.replace(/switch:([\w\d_]+)/g, "core.getFlag('" + (prefix || "global") + "@$1', 0)"); return eval(value); } if (value instanceof Function) { return value(); } return value; } ////// 字符串自动换行的分割 ////// utils.prototype.splitLines = function (canvas, text, maxLength, font) { if (font) core.setFont(canvas, font); var contents = []; var last = 0; for (var i = 0; i < text.length; i++) { if (text.charAt(i) == '\n') { contents.push(text.substring(last, i)); last = i + 1; } else if (text.charAt(i) == '\\' && text.charAt(i + 1) == 'n') { contents.push(text.substring(last, i)); last = i + 2; } else { var toAdd = text.substring(last, i + 1); var width = core.calWidth(canvas, toAdd); if (maxLength && width > maxLength) { contents.push(text.substring(last, i)); last = i; } } } contents.push(text.substring(last)); return contents; } ////// 向某个数组前插入另一个数组或元素 ////// utils.prototype.unshift = function (a, b) { if (!(a instanceof Array) || b == null) return; if (b instanceof Array) { core.clone(b).reverse().forEach(function (e) { a.unshift(e); }); } else a.unshift(b); return a; } ////// 向某个数组后插入另一个数组或元素 ////// utils.prototype.push = function (a, b) { if (!(a instanceof Array) || b == null) return; if (b instanceof Array) { core.clone(b).forEach(function (e) { a.push(e); }); } else a.push(b); return a; } ////// 设置本地存储 ////// utils.prototype.setLocalStorage = function (key, value) { try { if (value == null) { this.removeLocalStorage(key); return; } var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) }); var compressed = lzw_encode(str); // test if we can save to localStorage localStorage.setItem("__tmp__", compressed); if (lzw_decode(localStorage.getItem("__tmp__")) == str) { localStorage.setItem(core.firstData.name + "_" + key, compressed); } else { // We cannot compress the data localStorage.setItem(core.firstData.name + "_" + key, str); } localStorage.removeItem("__tmp__"); if (key == 'autoSave') core.saves.ids[0] = true; else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true; return true; } catch (e) { main.log(e); return false; } } utils.prototype.decompress = function (value) { try { var output = lzw_decode(value); if (output) return JSON.parse(output); } catch (e) { } try { var output = LZString.decompress(value); if (output) return JSON.parse(output); } catch (e) { } try { return JSON.parse(value); } catch (e) { main.log(e); } return null; } ////// 获得本地存储 ////// utils.prototype.getLocalStorage = function (key, defaultValue) { var res = this.decompress(localStorage.getItem(core.firstData.name + "_" + key)); return res == null ? defaultValue : res; } ////// 移除本地存储 ////// utils.prototype.removeLocalStorage = function (key) { localStorage.removeItem(core.firstData.name + "_" + key); if (key == 'autoSave') delete core.saves.ids[0]; else if (/^save\d+$/.test(key)) delete core.saves.ids[parseInt(key.substring(4))]; } utils.prototype.setLocalForage = function (key, value, successCallback, errorCallback) { if (!core.platform.useLocalForage) { if (this.setLocalStorage(key, value)) { if (successCallback) successCallback(); } else { if (errorCallback) errorCallback(); } return; } if (value == null) { this.removeLocalForage(key); return; } // Save to localforage var compressed = lzw_encode(JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) })); localforage.setItem(core.firstData.name + "_" + key, compressed, function (err) { if (err) { if (errorCallback) errorCallback(err); } else { if (key == 'autoSave') core.saves.ids[0] = true; else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true; if (successCallback) successCallback(); } }); } utils.prototype.getLocalForage = function (key, defaultValue, successCallback, errorCallback) { if (!core.platform.useLocalForage) { var value = this.getLocalStorage(key, defaultValue); if (successCallback) successCallback(value); return; } localforage.getItem(core.firstData.name + "_" + key, function (err, value) { if (err) { if (errorCallback) errorCallback(err); } else { if (!successCallback) return; if (value != null) { var res = core.utils.decompress(value); successCallback(res == null ? defaultValue : res); return; } successCallback(defaultValue); } }) } utils.prototype.removeLocalForage = function (key, successCallback, errorCallback) { if (!core.platform.useLocalForage) { this.removeLocalStorage(key); if (successCallback) successCallback(); return; } localforage.removeItem(core.firstData.name + "_" + key, function (err) { if (err) { if (errorCallback) errorCallback(err); } else { if (key == 'autoSave') delete core.saves.ids[0]; else if (/^save\d+$/.test(key)) delete core.saves.ids[parseInt(key.substring(4))]; if (successCallback) successCallback(); } }) } ////// 深拷贝一个对象 ////// utils.prototype.clone = function (data) { if (!core.isset(data)) return null; // date if (data instanceof Date) { var copy = new Date(); copy.setTime(data.getTime()); return copy; } // array if (data instanceof Array) { var copy = []; // for (var i=0;i= one.val) { var v = x / one.val; return c + v.toFixed(Math.max(0, Math.floor(3 - Math.log10(v + 1)))) + one.c; } } else { if (x >= 10 * one.val) { var v = x / one.val; return c + v.toFixed(Math.max(0, Math.floor(4 - Math.log10(v + 1)))) + one.c; } } } return c + x; } ////// 数组转RGB ////// utils.prototype.arrayToRGB = function (color) { var nowR = this.clamp(parseInt(color[0]), 0, 255), nowG = this.clamp(parseInt(color[1]), 0, 255), nowB = this.clamp(parseInt(color[2]), 0, 255); return "#" + ((1 << 24) + (nowR << 16) + (nowG << 8) + nowB).toString(16).slice(1); } utils.prototype.arrayToRGBA = function (color) { if (color[3] == null) color[3] = 1; var nowR = this.clamp(parseInt(color[0]), 0, 255), nowG = this.clamp(parseInt(color[1]), 0, 255), nowB = this.clamp(parseInt(color[2]), 0, 255), nowA = this.clamp(parseFloat(color[3]), 0, 1); return "rgba(" + nowR + "," + nowG + "," + nowB + "," + nowA + ")"; } ////// 加密路线 ////// utils.prototype.encodeRoute = function (route) { var ans = "", lastMove = "", cnt = 0; route.forEach(function (t) { if (t == 'up' || t == 'down' || t == 'left' || t == 'right') { if (t != lastMove && cnt > 0) { ans += lastMove.substring(0, 1).toUpperCase(); if (cnt > 1) ans += cnt; cnt = 0; } lastMove = t; cnt++; } else { if (cnt > 0) { ans += lastMove.substring(0, 1).toUpperCase(); if (cnt > 1) ans += cnt; cnt = 0; } ans += core.utils._encodeRoute_encodeOne(t); } }); if (cnt > 0) { ans += lastMove.substring(0, 1).toUpperCase(); if (cnt > 1) ans += cnt; } return LZString.compressToBase64(ans); } utils.prototype._encodeRoute_id2number = function (id) { var number = core.maps.getNumberById(id); return number == 0 ? id : number; } utils.prototype._encodeRoute_encodeOne = function (t) { if (t.indexOf('item:') == 0) return "I" + this._encodeRoute_id2number(t.substring(5)) + ":"; else if (t.indexOf('unEquip:') == 0) return "u" + t.substring(8); else if (t.indexOf('equip:') == 0) return "e" + this._encodeRoute_id2number(t.substring(6)) + ":"; else if (t.indexOf('fly:') == 0) return "F" + t.substring(4) + ":"; else if (t.indexOf('choices:') == 0) return "C" + t.substring(8); else if (t.indexOf('shop:') == 0) return "S" + t.substring(5); else if (t == 'turn') return 'T'; else if (t.indexOf('turn:') == 0) return "t" + t.substring(5).substring(0, 1).toUpperCase() + ":"; else if (t == 'getNext') return 'G'; else if (t.indexOf('input:') == 0) return "P" + t.substring(6); else if (t.indexOf('input2:') == 0) return "Q" + t.substring(7) + ":"; else if (t == 'no') return 'N'; else if (t.indexOf('move:') == 0) return "M" + t.substring(5); else if (t.indexOf('key:') == 0) return 'K' + t.substring(4); else if (t.indexOf('random:') == 0) return 'X' + t.substring(7); return ''; } ////// 解密路线 ////// utils.prototype.decodeRoute = function (route) { if (!route) return route; // 解压缩 try { var v = LZString.decompressFromBase64(route); if (/^[a-zA-Z0-9+\/=:]*$/.test(v)) { route = v; } } catch (e) { } var decodeObj = {route: route, index: 0, ans: []}; while (decodeObj.index < decodeObj.route.length) { this._decodeRoute_decodeOne(decodeObj, decodeObj.route.charAt(decodeObj.index++)); } return decodeObj.ans; } utils.prototype._decodeRoute_getNumber = function (decodeObj, noparse) { var num = ""; while (decodeObj.index < decodeObj.route.length && !isNaN(decodeObj.route.charAt(decodeObj.index))) { num += decodeObj.route.charAt(decodeObj.index++); } if (num.length == 0) num = "1"; return noparse ? num : parseInt(num); } utils.prototype._decodeRoute_getString = function (decodeObj) { var str = ""; while (decodeObj.index < decodeObj.route.length && decodeObj.route.charAt(decodeObj.index) != ':') { str += decodeObj.route.charAt(decodeObj.index++); } decodeObj.index++; return str; } utils.prototype._decodeRoute_number2id = function (number) { if (/^\d+$/.test(number)) { var info = core.maps.blocksInfo[number]; if (info) return info.id; } return number; } utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) { var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't') ? this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj); var mp = {"U": "up", "D": "down", "L": "left", "R": "right"}; switch (c) { case "U": case "D": case "L": case "R": for (var i = 0; i < nxt; i++) decodeObj.ans.push(mp[c]); break; case "I": decodeObj.ans.push("item:" + this._decodeRoute_number2id(nxt)); break; case "u": decodeObj.ans.push("unEquip:" + nxt); break; case "e": decodeObj.ans.push("equip:" + this._decodeRoute_number2id(nxt)); break; case "F": decodeObj.ans.push("fly:" + nxt); break; case "C": decodeObj.ans.push("choices:" + nxt); break; case "S": decodeObj.ans.push("shop:" + nxt + ":" + this._decodeRoute_getNumber(decodeObj, true)); break; case "T": decodeObj.ans.push("turn"); break; case "t": decodeObj.ans.push("turn:" + mp[nxt]); break; case "G": decodeObj.ans.push("getNext"); break; case "P": decodeObj.ans.push("input:" + nxt); break; case "Q": decodeObj.ans.push("input2:" + nxt); break; case "N": decodeObj.ans.push("no"); break; case "M": ++decodeObj.index; decodeObj.ans.push("move:" + nxt + ":" + this._decodeRoute_getNumber(decodeObj)); break; case "K": decodeObj.ans.push("key:" + nxt); break; case "X": decodeObj.ans.push("random:" + nxt); break; } } ////// 判断某对象是否不为null也不为NaN ////// utils.prototype.isset = function (val) { return val != null && !(typeof val == 'number' && isNaN(val)); } ////// 获得子数组 ////// utils.prototype.subarray = function (a, b) { if (!(a instanceof Array) || !(b instanceof Array) || a.length < b.length) return null; var na = core.clone(a), nb = core.clone(b); while (nb.length > 0) { if (na.shift() != nb.shift()) return null; } return na; } utils.prototype.inArray = function (array, element) { return (array instanceof Array) && array.indexOf(element) >= 0; } utils.prototype.clamp = function (x, a, b) { var min = Math.min(a, b), max = Math.max(a, b); return Math.min(Math.max(x || 0, min), max); } utils.prototype.getCookie = function (name) { var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); return match ? match[2] : null; } utils.prototype.expandMoveSteps = function (steps) { var moveSteps = []; steps.forEach(function (e) { if (typeof e == "string") { moveSteps.push(e); } else { if (e.value == null) { moveSteps.push(e.direction) } else { for (var i = 0; i < e.value; i++) { moveSteps.push(e.direction); } } } }); return moveSteps; } ////// 设置statusBar的innerHTML,会自动斜体和放缩,也可以增加自定义css ////// utils.prototype.setStatusBarInnerHTML = function (name, value, css) { if (typeof value == 'number') value = this.formatBigNumber(value); // 判定是否斜体 var italic = /^[-a-zA-Z0-9`~!@#$%^&*()_=+\[{\]}\\|;:'",<.>\/?]*$/.test(value); var style = 'font-style: ' + (italic ? 'italic' : 'normal') + '; '; // 判定是否需要缩放 var length = this.strlen(value) || 1; style += 'font-size: ' + Math.min(1, 7 / length) + 'em; '; if (css) style += css; core.statusBar[name].innerHTML = "" + value + ""; } utils.prototype.strlen = function (str) { var count = 0; for (var i = 0, len = str.length; i < len; i++) { count += str.charCodeAt(i) < 256 ? 1 : 2; } return count; }; ////// Base64加密 ////// utils.prototype.encodeBase64 = function (str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { return String.fromCharCode(parseInt(p1, 16)) })) } ////// Base64解密 ////// utils.prototype.decodeBase64 = function (str) { return decodeURIComponent(atob(str).split('').map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); } ////// 任意进制转换 ////// utils.prototype.convertBase = function (str, fromBase, toBase) { var map = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+={}[]\\|:;<>,.?/"; if (fromBase == toBase) return str; var len = str.length, ans = ""; var t = []; for (var i = 0; i < len; i++) t[i] = map.indexOf(str.charAt(i)); t[len] = 0; while (len > 0) { for (var i = len; i >= 1; i--) { t[i - 1] += t[i] % toBase * fromBase; t[i] = parseInt(t[i] / toBase); } ans += map.charAt(t[0] % toBase); t[0] = parseInt(t[0] / toBase); while (len > 0 && t[len - 1] == 0) len--; } return ans; } utils.prototype.rand = function (num) { var rand = core.getFlag('__rand__'); rand = this.__next_rand(rand); core.setFlag('__rand__', rand); var ans = rand / 2147483647; if (num && num > 0) return Math.floor(ans * num); return ans; } ////// 生成随机数(录像方法) ////// utils.prototype.rand2 = function (num) { num = num || 2147483648; var value; if (core.isReplaying()) { var action = core.status.replay.toReplay.shift(); if (action.indexOf("random:") == 0) { value = parseInt(action.substring(7)); } else { core.stopReplay(); core.drawTip("录像文件出错"); return; } } else { value = Math.floor(Math.random() * num); } core.status.route.push("random:" + value); return value; } utils.prototype.__init_seed = function () { var rand = new Date().getTime() % 34834795 + 3534; rand = this.__next_rand(rand); rand = this.__next_rand(rand); rand = this.__next_rand(rand); core.setFlag('__seed__', rand); core.setFlag('__rand__', rand); } utils.prototype.__next_rand = function (_rand) { _rand = (_rand % 127773) * 16807 - ~~(_rand / 127773) * 2836; _rand += _rand < 0 ? 2147483647 : 0; return _rand; } ////// 读取一个本地文件内容 ////// utils.prototype.readFile = function (success, error, readType) { core.platform.successCallback = success; core.platform.errorCallback = error; if (window.jsinterface) { window.jsinterface.readFile(); return; } // step 0: 不为http/https,直接不支持 if (!core.platform.isOnline) { alert("离线状态下不支持文件读取!"); if (error) error(); return; } // Step 1: 如果不支持FileReader,直接不支持 if (core.platform.fileReader == null) { alert("当前浏览器不支持FileReader!"); if (error) error(); return; } if (core.platform.fileInput == null) { core.platform.fileInput = document.createElement("input"); core.platform.fileInput.style.opacity = 0; core.platform.fileInput.type = 'file'; core.platform.fileInput.onchange = function () { var files = core.platform.fileInput.files; if (files.length == 0) { if (core.platform.errorCallback) core.platform.errorCallback(); return; } if (!readType) core.platform.fileReader.readAsText(core.platform.fileInput.files[0]); else core.platform.fileReader.readAsDataURL(core.platform.fileInput.files[0]); core.platform.fileInput.value = ''; } } core.platform.fileInput.click(); } ////// 读取文件完毕 ////// utils.prototype.readFileContent = function (content) { var obj = null; if (content.slice(0, 4) === 'data') { if (core.platform.successCallback) core.platform.successCallback(content); return; } try { obj = JSON.parse(content); if (obj) { if (core.platform.successCallback) core.platform.successCallback(obj); return; } } catch (e) { main.log(e); alert(e); } alert("不是有效的JSON文件!"); if (core.platform.errorCallback) core.platform.errorCallback(); } ////// 下载文件到本地 ////// utils.prototype.download = function (filename, content) { if (window.jsinterface) { window.jsinterface.download(filename, content); return; } // Step 0: 不为http/https,直接不支持 if (!core.platform.isOnline) { alert("离线状态下不支持下载操作!"); return; } // Step 1: 如果是iOS平台,直接不支持 if (core.platform.isIOS) { if (core.copy(content)) { alert("iOS平台下不支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。"); } else { alert("iOS平台下不支持下载操作!"); } return; } // Step 2: 如果不是PC平台(Android),则只支持chrome if (!core.platform.isPC) { if (!core.platform.isChrome || core.platform.isQQ || core.platform.isWeChat) { // 检测chrome if (core.copy(content)) { alert("移动端只有Chrome浏览器支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。"); } else { alert("该平台或浏览器暂不支持下载操作!"); } return; } } // Step 3: 如果是Safari浏览器,则提示并打开新窗口 if (core.platform.isSafari) { alert("你当前使用的是Safari浏览器,不支持直接下载文件。\n即将打开一个新窗口为应下载内容,请自行全选复制然后创建空白文件并粘贴。"); var blob = new Blob([content], {type: 'text/plain;charset=utf-8'}); var href = window.URL.createObjectURL(blob); var opened = window.open(href, "_blank"); window.URL.revokeObjectURL(href); return; } // Step 4: 下载 var blob = new Blob([content], {type: 'text/plain;charset=utf-8'}); if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveBlob(blob, filename); } else { var href = window.URL.createObjectURL(blob); var elem = window.document.createElement('a'); elem.href = href; elem.download = filename; document.body.appendChild(elem); elem.click(); document.body.removeChild(elem); window.URL.revokeObjectURL(href); } } ////// 复制一段内容到剪切板 ////// utils.prototype.copy = function (data) { if (window.jsinterface) { window.jsinterface.copy(data); return true; } if (!core.platform.supportCopy) return false; var textArea = document.createElement("textarea"); textArea.style.position = 'fixed'; textArea.style.top = 0; textArea.style.left = 0; textArea.style.width = '2em'; textArea.style.height = '2em'; textArea.style.padding = 0; textArea.style.border = 'none'; textArea.style.outline = 'none'; textArea.style.boxShadow = 'none'; textArea.style.background = 'transparent'; textArea.value = data; document.body.appendChild(textArea); textArea.focus(); textArea.setSelectionRange(0, textArea.value.length); var successful = false; try { successful = document.execCommand('copy'); } catch (err) { successful = false; } document.body.removeChild(textArea); return successful; } ////// 动画显示某对象 ////// utils.prototype.show = function (obj, speed, callback) { obj.style.display = 'block'; if (!speed && main.mode != 'play') { obj.style.opacity = 1; if (callback) callback(); return; } obj.style.opacity = 0; var opacityVal = 0; var showAnimate = window.setInterval(function () { opacityVal += 0.03; obj.style.opacity = opacityVal; if (opacityVal > 1) { clearInterval(showAnimate); if (callback) callback(); } }, speed); } ////// 动画使某对象消失 ////// utils.prototype.hide = function (obj, speed, callback) { if (!speed || main.mode != 'play') { obj.style.display = 'none'; if (callback) callback(); return; } obj.style.opacity = 1; var opacityVal = 1; var hideAnimate = window.setInterval(function () { opacityVal -= 0.03; obj.style.opacity = opacityVal; if (opacityVal < 0) { obj.style.display = 'none'; clearInterval(hideAnimate); if (callback) callback(); } }, speed); } utils.prototype.encodeCanvas = function (ctx) { var list = []; var width = ctx.canvas.width, height = ctx.canvas.height; ctx.mozImageSmoothingEnabled = false; ctx.webkitImageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false; ctx.imageSmoothingEnabled = false; var imgData = ctx.getImageData(0, 0, width, height); for (var i = 0; i < imgData.data.length; i += 4) { list.push(Math.sign(imgData.data[i + 3])); } // compress 01 to array var prev = 0, cnt = 0, arr = []; for (var i = 0; i < list.length; i++) { if (list[i] != prev) { arr.push(cnt); prev = list[i]; cnt = 0; } cnt++; } arr.push(cnt); return arr; } ////// 解析arr数组,并绘制到tempCanvas上 ////// utils.prototype.decodeCanvas = function (arr, width, height) { // 清空tempCanvas var tempCanvas = core.bigmap.tempCanvas; tempCanvas.canvas.width = width; tempCanvas.canvas.height = height; tempCanvas.clearRect(0, 0, width, height); if (!arr) return null; // to byte array var curr = 0, list = []; arr.forEach(function (x) { for (var i = 0; i < x; i++) list.push(curr); curr = 1 - curr; }) var imgData = tempCanvas.getImageData(0, 0, width, height); for (var i = 0; i < imgData.data.length; i += 4) { var index = i / 4; if (list[index]) { imgData.data[i] = 255; imgData.data[i + 3] = 255; } } tempCanvas.putImageData(imgData, 0, 0); } utils.prototype.consoleOpened = function () { if (!core.flags.checkConsole) return false; if (window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized) return true; var threshold = 160; var zoom = Math.min(window.outerWidth / window.innerWidth, window.outerHeight / window.innerHeight); return window.outerWidth - zoom * window.innerWidth > threshold || window.outerHeight - zoom * window.innerHeight > threshold; } utils.prototype.hashCode = function (obj) { if (typeof obj == 'string') { var hash = 0, i, chr; if (obj.length === 0) return hash; for (i = 0; i < obj.length; i++) { chr = obj.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash; } return this.hashCode(JSON.stringify(obj).split("").sort().join("")); } utils.prototype.same = function (a, b) { if (a == null && b == null) return true; if (a == null || b == null) return false; if (a === b) return true; if (a instanceof Array && b instanceof Array) { if (a.length != b.length) return false; for (var i = 0; i < a.length; i++) { if (!this.same(a[i], b[i])) return false; } return true; } if (a instanceof Object && b instanceof Object) { for (var i in a) { if (!this.same(a[i], b[i])) return false; } for (var i in b) { if (!this.same(a[i], b[i])) return false; } return true; } return false; } utils.prototype._export = function (floorIds) { if (!floorIds) floorIds = [core.status.floorId]; else if (floorIds == 'all') floorIds = core.clone(core.floorIds); else if (typeof floorIds == 'string') floorIds = [floorIds]; var monsterMap = {}; // map var content = floorIds.length + "\n" + core.__SIZE__ + " " + core.__SIZE__ + "\n\n"; floorIds.forEach(function (floorId) { var arr = core.maps.getMapArray(core.status.maps[floorId].blocks, 13, 13); content += arr.map(function (x) { // check monster x.forEach(function (t) { var block = core.maps.initBlock(null, null, t); if (block.event.cls.indexOf("enemy") == 0) { monsterMap[t] = block.event.id; } }) return x.join("\t"); }).join("\n") + "\n\n"; }) // values content += ["redJewel", "blueJewel", "greenJewel", "redPotion", "bluePotion", "yellowPotion", "greenPotion", "sword1", "shield1"].map(function (x) { return core.values[x] }).join(" ") + "\n\n"; // monster content += Object.keys(monsterMap).length + "\n"; for (var t in monsterMap) { var id = monsterMap[t], monster = core.material.enemys[id]; content += t + " " + monster.hp + " " + monster.atk + " " + monster.def + " " + monster.money + " " + monster.special + "\n"; } content += "\n0 0 0 0 0 0\n\n"; content += core.status.hero.hp + " " + core.status.hero.atk + " " + core.status.hero.def + " " + core.status.hero.mdef + " " + core.status.hero.money + " " + core.itemCount('yellowKey') + " " + core.itemCount("blueKey") + " " + core.itemCount("redKey") + " 0 " + core.status.hero.loc.x + " " + core.status.hero.loc.y + "\n"; console.log(content); } utils.prototype.http = function (type, url, formData, success, error, mimeType, responseType) { var xhr = new XMLHttpRequest(); xhr.open(type, url, true); if (mimeType) xhr.overrideMimeType(mimeType); if (responseType) xhr.responseType = responseType; xhr.onload = function (e) { if (xhr.status == 200) { if (success) success(xhr.response); } else { if (error) error("HTTP " + xhr.status); } }; xhr.onabort = function () { if (error) error("Abort"); } xhr.ontimeout = function () { if (error) error("Timeout"); } xhr.onerror = function () { if (error) error("Error on Connection"); } if (formData) xhr.send(formData); else xhr.send(); } // LZW-compress // https://gist.github.com/revolunet/843889 function lzw_encode(s) { var dict = {}; var data = (s + "").split(""); var out = []; var currChar; var phrase = data[0]; var code = 256; for (var i = 1; i < data.length; i++) { currChar = data[i]; if (dict[phrase + currChar] != null) { phrase += currChar; } else { out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); dict[phrase + currChar] = code; code++; phrase = currChar; } } out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); for (var i = 0; i < out.length; i++) { out[i] = String.fromCharCode(out[i]); } return out.join(""); } // Decompress an LZW-encoded string function lzw_decode(s) { var dict = {}; var data = (s + "").split(""); var currChar = data[0]; var oldPhrase = currChar; var out = [currChar]; var code = 256; var phrase; for (var i = 1; i < data.length; i++) { var currCode = data[i].charCodeAt(0); if (currCode < 256) { phrase = data[i]; } else { phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar); } out.push(phrase); currChar = phrase.charAt(0); dict[code] = oldPhrase + currChar; code++; oldPhrase = phrase; } return out.join(""); }