您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
武神传说 MUD
当前为
// ==UserScript== // @name wsmud_Raid // @namespace cqv // @version 0.5.6 // @date 23/12/2018 // @modified 28/12/2018 // @homepage https://gf.qytechs.cn/zh-CN/scripts/375851 // @description 武神传说 MUD // @author Bob.cn // @match http://game.wsmud.com/* // @match http://www.wsmud.com/* // @run-at document-end // @require https://cdn.staticfile.org/vue/2.2.2/vue.min.js // @grant unsafeWindow // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function () { 'use strict'; var WG = unsafeWindow.WG; var messageAppend = undefined; var messageClear = undefined; var T = null; //--------------------------------------------------------------------------- // Work Item and it's subclass //--------------------------------------------------------------------------- var Message = { append: function(msg) { messageAppend(msg); }, clean: function() { messageClear(); } }; // Work Item class WorkItem2 { /** * @param {string} name * @param {Function} run function(params) * @param {*} [defaultParams] * @param {Function} [assert] function()->Bool * @param {Function} [finish] function() */ constructor(name, run, defaultParams, assert, finish) { this.name = name; this.run = run; this.params = defaultParams; this.assert = assert; this.finish = finish; } } // Workflow2 class Workflow2 extends WorkItem2 { /** * @param {string} name * @param {WorkItem2[]} items * @param {number} [count] * @param {number} [interval] */ constructor(name, items, count, interval) { super(name, function(params) { Message.clean(); Message.append("□ 即将开始运行工作流【" + this.name + "】..."); this._run(0, 0); }, null, null, null); this.items = items; this.count = count == null ? 1 : count; this.interval = interval == null ? 1000 : interval; } _run(number, index) { var realIndex = index; var realNumber = number; if (realIndex >= this.items.length) { Message.append("● 已经完成工作流【" + this.name +"】的第 " + (realNumber + 1) + "/" + this.count + " 次运行;"); realNumber += 1; realIndex = 0; } if (realNumber >= this.count) { Message.append("■ 已经完成工作流【" + this.name + "】的全部运行。"); if (this.finish) this.finish(); return; } var item = this.items[realIndex]; if (item.assert != null && item.assert() == false) { this._run(realNumber, realIndex + 1); return; } var theSelf = this; item.finish = function () { setTimeout(function () { theSelf._run(realNumber, realIndex + 1); }, theSelf.interval); }; item.run(item.params); } } // --------------------------------------------------------------------------- // Assert Holder class AssertHolder { /** * @param {Function} match function(expression)->Bool * @param {Function} assert function()->Bool */ constructor(match, assert) { this.match = match; this.assert = assert; } } var AssertHolderCenter = { /** * @param {AssertHolder} holder */ addAssertHolder: function(holder) { this._assertHolders.push(holder); }, get: function(expression) { var theSelf = this; var relationIndex = expression.search(/&|\|/g); if (relationIndex != -1) { var relation = expression[relationIndex]; var left = expression.substring(0, relationIndex); var right = expression.substring(relationIndex + 1); var assert = function() { Debug.print("relation: " + relation); var leftAssert = theSelf.get(left); var rightAssert = theSelf.get(right); switch (relation) { case "&": return leftAssert() && rightAssert(); case "|": return leftAssert() || rightAssert(); } }; return assert; } var not = expression[0]; if (not == "!") { var assert = function() { return !theSelf.get(expression.substring(1))(); } return assert; } for (let i = 0; i < this._assertHolders.length; i++) { const holder = this._assertHolders[i]; if (holder.match(expression)) { return holder.assert; } } return null; }, _assertHolders: [] }; // Command Handler var CommandHandleStatus = { pass: 0, defer: 1, over: 2, }; var CommandHandlerPriority = { lowest: 0, low: 1, ordinary: 5, hight: 8, highest: 9 }; class CommandHandler { /** * @param {Function} handle function(command: Command, callback: function(command: Command, status: CommandHandleStatus)) * @param {number} priority CommandHandlerPriority */ constructor(handle, priority) { this.handle = handle; this.priority = priority == null ? CommandHandlerPriority.ordinary : priority; } } var CommandHandlerCenter = { addHandler: function(handler) { this._handlers.push(handler); this._handlers.sort(function(a, b) { return b.priority - a.priority; }); }, /** * @param {string} cmd * @param {Function} callback function(status: CommandHandleStatus) */ handle: function(command, callback) { CommandHandlerCenter._handle(0, command, callback); }, _handle: function(index, command, callback) { if (index >= CommandHandlerCenter._handlers.length) { callback(CommandHandleStatus.pass); return; } var handler = CommandHandlerCenter._handlers[index]; handler.handle(command, function(command1, status) { switch (status) { case CommandHandleStatus.over: callback(status); break; case CommandHandleStatus.pass: CommandHandlerCenter._handle(index + 1, command1, callback); break; case CommandHandleStatus.defer: callback(status); break; } }); }, _handlers: [ ], }; // Command class Command extends WorkItem2 { /** * @param {string} text * @param {number} [again] After the command execution is blocked, try again after <again> millisecond. */ constructor(text, again) { var name = "[perform]: " + text; super(name, null, null, null, null); this.text = text; this.run = this._run; this.again = again == null ? 1000 : again; this._preprocess(); } _preprocess() { var patt = /\[.*?\]/g; var result = patt.exec(this.text); if (result == null || result.length <= 0) { this.assert = null; return; } var value = result[0]; var expression = value.substring(1, value.length - 1); var assert = AssertHolderCenter.get(expression); this.assert = assert; this.text = this.text.substring(value.length); } _run() { var theSelf = this; var callback = function (status) { switch (status) { case CommandHandleStatus.over: case CommandHandleStatus.pass: theSelf.finish(); break; case CommandHandleStatus.defer: setTimeout(function () { theSelf.run(); }, theSelf.again); break; } }; CommandHandlerCenter.handle(this, callback); } } // Command Workflow2 class CommandWorkflow2 extends Workflow2 { /** * @param {string} name * @param {string[]} cmds * @param {number} [count] * @param {number} [interval] * @param {number} [commandAgain] */ constructor(name, cmds, count, interval, commandAgain) { var realCommandAgain = commandAgain == null ? interval : commandAgain; var items = []; for (var i = 0; i < cmds.length; i++) { var cmd = cmds[i]; var item = new Command(cmd, realCommandAgain); items.push(item); } var realCount = count == null ? 1 : count; super(name, items, realCount, interval); } } (function addSendCommandHandler() { var handle = function(command, callback) { WG.SendCmd(command.text); callback(command, CommandHandleStatus.over); }; var handler = new CommandHandler(handle, CommandHandlerPriority.lowest); CommandHandlerCenter.addHandler(handler); })(); var Role = { id: undefined, name: undefined, hp: 0, maxHp: 0, mp: 0, maxMp: 0, status: [], equipments: [], init: function() { WG.add_hook("login", function(data) { Role.id = data.id; Role.status = []; }); $("li[command=SelectRole]").on("click", function () { Role.name = $('.role-list .select').text().replace(/[\s]+/,"."); }); Role._monitorHpMp(); Role._monitorStatus(); Role._monitorEquipments(); Role._monitorSkillCD(); Role._monitorLocation(); Role._monitorItemsInRoom(); }, hasStatus: function(s) { return Role.status.indexOf(s) != -1; }, isFree: function() { return !Role.hasStatus("busy") && !Role.hasStatus("faint") && !Role.hasStatus("rash"); }, atPath: function(p) { switch (arguments.length) { case 0: return Role._roomPath; case 1: return p == Role._roomPath; } }, inRoom: function(n) { switch (arguments.length) { case 0: return Role._roomName; case 1: return n == Role._roomName; } }, renew: function(callback) { if (!Role.isFree) { window.setTimeout(function() { Role.renew(callback) }, 2000); return; } switch (Role._renewStatus) { case "resting": WG.go("扬州城-武庙"); if (Role._renewHookIndex) WG.remove_hook(Role._renewHookIndex); Role._renewHookIndex = WG.add_hook("text", function(data) { let patt1 = new RegExp("你运功完毕,深深吸了口气,站了起来。"); let count1 = patt1.exec(data.msg); if (count1) { Role._renewStatus = "dazuo finish"; return; } let patt2 = new RegExp("你目前气血充沛,没有受到任何伤害。|你疗伤完毕,深深吸了口气,脸色看起来好了很多。"); let count2 = patt2.exec(data.msg); if (count2) { Role._renewStatus = "liaoshang finish"; return; } }); Role._renewStatus = "liaoshang doing"; WG.SendCmd("stopstate;liaoshang"); break; case "liaoshang finish": if (Role.mp/Role.maxMp < 0.7) { Role._lastWeapon = Role.equipments[0]; Role._renewStatus = "dazuo doing"; WG.SendCmd("stopstate;dazuo"); } break; case "liaoshang doing": case "dazuo doing": case "dazuo finish": break; } if (Role._renewStatus == "liaoshang finish" || Role._renewStatus == "dazuo finish") { if (Role._renewStatus == "liaoshang finish") { if (callback) callback(); } else if (Role._renewStatus == "dazuo finish") { window.setTimeout(function() { WG.SendCmd("stopstate"); Role.getDressed([Role._lastWeapon]); if (callback) callback(); }, 4500); } WG.remove_hook(Role._renewHookIndex); Role._renewHookIndex = undefined; Role._renewStatus = "resting"; return; } window.setTimeout(function() { Role.renew(callback); }, 2000); }, cleanBag: function(callback) { WG.clean_all(); if (callback) callback(); }, tidyBag: function(callback) { Role._tidyBag(0, callback); }, getDressed: function(equipments) { for (var i = equipments.length - 1; i >= 0; i--) { let e = equipments[i]; if (e == null) { WG.SendCmd("uneq " + Role.equipments[i]); } else { WG.SendCmd("eq " + e); } } }, hasCoolingSkill: function() { return Role._coolingSkills.length > 0; }, findItem: function(name) { for (var i = 0; i < Role._itemsInRoom.length; i++) { let item = Role._itemsInRoom[i]; if (item.name == name) { return item.id; } } return null; }, _renewHookIndex: undefined, _renewStatus: "resting", _coolingSkills: [], _itemsInRoom: {}, _tidyBag: function(counter, callback) { if (counter == 0) WG.sell_all(); if (!WG.packup_listener) { window.setTimeout(callback, 2000); return; } if (counter > 5) { if (WG.packup_listener) WG.sell_all(); callback(); return; } window.setTimeout(function() { Role._tidyBag(counter + 1, callback); }, 1000); }, _monitorHpMp: function() { WG.add_hook(["items", "sc", "itemadd"], function(data) { switch (data.type) { case "items": if (data.items == undefined) break; for (var i = data.items.length - 1; i >= 0; i--) { let item = data.items[i] if (item.id == Role.id) { Role.hp = item.hp; Role.maxHp = item.max_hp; Role.mp = item.mp; Role.maxMp = item.max_mp; break; } } break; case "itemadd": case "sc": if (data.id != Role.id) break; if (data.hp != undefined) Role.hp = data.hp; if (data.max_hp != undefined) Role.maxHp = data.max_hp; if (data.mp != undefined) Role.mp = data.mp; if (data.max_mp != undefined) Role.maxMp = data.max_mp; break; } }); }, _monitorStatus: function() { WG.add_hook(["items", "status", "itemadd"], function(data) { switch (data.type) { case "items": if (data.items == undefined) break; for (var i = data.items.length - 1; i >= 0; i--) { let item = data.items[i]; if (item.id != Role.id) continue; if (item.status == undefined) break; Role.status = []; for (var j = item.status.length - 1; j >= 0; j--) { let s = item.status[j]; Role.status.push(s.sid); } break; } break; case "status": if (data.id != Role.id) break; if (data.action == "add") { Role.status.push(data.sid); } else if (data.action == "remove") { let index = Role.status.indexOf(data.sid); if (index == -1) return; Role.status.splice(index,1); } break; case "itemadd": if (data.id != Role.id) break; if (data.status == undefined) break; Role.status = []; for (var k = data.status.length - 1; k >= 0; k--) { let s = data.status[k]; Role.status.push(s.sid); } break; } }); }, _monitorEquipments: function() { WG.add_hook("dialog", function(data) { if (data.dialog != "pack") return; if (data.eqs != undefined) { for (var i = 0; i < data.eqs.length; i++) { let eq = data.eqs[i]; if (eq != null && eq.id != null) { Role.equipments.push(eq.id); } else { Role.equipments.push(null); } } } else if (data.uneq != undefined) { Role.equipments[data.uneq] = null; } else if (data.eq != undefined) { Role.equipments[data.eq] = data.id; } else { return; } }); }, _monitorSkillCD: function() { WG.add_hook("dispfm", function(data) { let timestamp = Date.parse(new Date()); let mark = data.id + "_" + timestamp; Role._coolingSkills.push(mark); window.setTimeout(function() { let index = Role._coolingSkills.indexOf(mark); if (index != -1) Role._coolingSkills.splice(index, 1); }, data.distime); }); }, _monitorLocation: function() { WG.add_hook("room", function(data) { Role._roomName = data.name; Role._roomPath = data.path; }); }, _monitorItemsInRoom: function() { WG.add_hook(["items", "itemadd", "itemremove"], function(data) { switch (data.type) { case "items": if (data.items == undefined) break; Role._itemsInRoom = []; for (var i = 0; i < data.items.length; i++) { let item = data.items[i]; if (item.name == undefined || item.id == undefined) continue; Role._itemsInRoom.push(item); } break; case "itemadd": if (data.name == undefined || data.id == undefined) break; Role._itemsInRoom.push(data); break; case "itemremove": for (var i = 0; i < Role._itemsInRoom.length; i++) { let item = Role._itemsInRoom[i]; if (item.id == data.id) { Role._itemsInRoom.splice(i, 1); } } break; } }); }, }; var Config = { hpThresholdInDungeon: function() { return GM_getValue(Role.id + "@hpThresholdInRaid", "50"); }, setHpThresholdInDungeon: function(value) { GM_setValue(Role.id + "@hpThresholdInRaid", value); }, waitSkillCD: function() { return GM_getValue(Role.id + "@waitSkillCD", "no"); }, setWaitSkillCD: function(value) { GM_setValue(Role.id + "@waitSkillCD", value); }, // none, clean, tidy bagCleanWay: function() { return GM_getValue(Role.id + "@bagCleanWay", "clean"); }, setBagCleanWay: function(value) { GM_setValue(Role.id + "@bagCleanWay", value); }, cmdInterval: function() { return GM_getValue(Role.id + "@cmdInterval", 1000); }, setCmdInterval: function(value) { GM_setValue(Role.id + "@cmdInterval", value); }, /* hpThresholdInRaid: function(raid) { return GM_getValue(Role.id + "@hpThresholdInRaid@" + raid, "50"); }, setHpThresholdInRaid: function(raid, value) { GM_setValue(Role.id + "@hpThresholdInRaid@" + raid, value); }, waitSkillCD: function(raid) { return GM_getValue(Role.id + "@waitSkillCD@" + raid, "no"); }, setWaitSkillCD: function(raid, value) { GM_setValue(Role.id + "@waitSkillCD@" + raid, value); }, */ wudaota: { autoToFloor: function() { return GM_getValue(Role.id + "@wudao.autoToFloor", 0); }, setAutoToFloor: function(value) { GM_setValue(Role.id + "@wudao.autoToFloor", value); }, fastCombatOpening: function() { return GM_getValue(Role.id + "@wudao.fastCombatOpening", "no"); }, setFastCombatOpening: function(value) { GM_setValue(Role.id + "@wudao.fastCombatOpening", value); }, hpThresholdInRaid: function() { return GM_getValue(Role.id + "@wudao.hpThresholdInRaid", "50"); }, setHpThresholdInRaid: function(value) { GM_setValue(Role.id + "@wudao.hpThresholdInRaid", value); }, waitSkillCDFrom: function() { return GM_getValue(Role.id + "@wudao.waitSkillCDFrom", 100); }, setWaitSkillCDFrom: function(value) { GM_setValue(Role.id + "@wudao.waitSkillCDFrom", value); }, }, }; /* ------------------------ CmdExecuter ------------------------ *\ \* ------------------------------------------------------------- */ function CmdExecuter(cmds, willStartExecute, didFinishExecute, willPerformCmd, didPerformCmd, interval) { this.cmds = cmds; this.willStartExecute = willStartExecute; this.didFinishExecute = didFinishExecute; this.willPerformCmd = willPerformCmd; this.didPerformCmd = didPerformCmd; this.interval = interval ? interval : 1000; } CmdExecuter.prototype.execute = function() { if (this.isWorking) return; this.isWorking = true; if (this.willStartExecute) this.willStartExecute(); this._monitorItemsInRoom(); this._performCmd(0); }; CmdExecuter.prototype._performCmd = function(index) { if (index >= this.cmds.length) { this._finishExecute(); return; } if (!Role.isFree()) { this._delayPerformCmd(index); return; } var cmd = this.cmds[index]; if (this.willPerformCmd) { var lastCmd = null; if (index > 0) lastCmd = this.cmds[index - 1]; let valid = this.willPerformCmd(lastCmd, cmd); if (!valid) { this._delayPerformCmd(index); return; } cmd = valid; } // kill?开头,询问击杀是否完成命令 if (cmd.indexOf("kill?") != -1) { let items = cmd.substring(5).split(";"); if (CmdExecuter._removedItems == undefined) { this._delayPerformCmd(index); return; } var removedItems = CmdExecuter._removedItems.slice(); for (var i = 0; i < items.length; i++) { let item = items[i]; let k = removedItems.indexOf(item); if (k == -1) { // 尚存在未击杀对象 WG.SendCmd("kill " + Role.findItem(item)); this._delayPerformCmd(index); return; } removedItems.splice(k, 1); } CmdExecuter._removedItems = []; } // {item.name} 会被该 item 的 id 替换 let patt = /\{.*?\}/g; var placeholders = []; var result = patt.exec(cmd); while(result != null) { placeholders.push(result[0]); result = patt.exec(cmd); } var realCmd = cmd; for (var j = 0; j < placeholders.length; j++) { let placeholder = placeholders[j]; let item = Role.findItem(placeholder.substring(1, placeholder.length - 1)); if (item == null) { this._delayPerformCmd(index); return; } realCmd = realCmd.replace(placeholder, item); } cmd = realCmd; // @开头,虚命令,不真正执行 if (cmd.indexOf("@") == -1 && cmd.indexOf("kill?") == -1) { console.log("执行命令:" + cmd); WG.SendCmd(cmd); } if (this.didPerformCmd) { this.didPerformCmd(cmd); } // [exit] 保留命令,立即退出执行器 if (cmd.indexOf("[exit]") != -1) { this._finishExecute(); return; } else { this._delayPerformCmd(index + 1); } }; CmdExecuter.prototype._delayPerformCmd = function(index) { let executer = this; window.setTimeout(function() { executer._performCmd(index); }, executer.interval); }; CmdExecuter.prototype._monitorItemsInRoom = function() { CmdExecuter._hookIndex = WG.add_hook(["items", "itemadd", "itemremove"], function(data) { switch (data.type) { case "items": if (data.items == undefined) break; CmdExecuter._itemsInRoom = []; CmdExecuter._removedItems = []; for (var i = 0; i < data.items.length; i++) { let item = data.items[i]; if (item.name == undefined || item.id == undefined) continue; CmdExecuter._itemsInRoom.push(item); } break; case "itemadd": if (CmdExecuter._itemsInRoom == undefined) break; if (data.name == undefined || data.id == undefined) break; CmdExecuter._itemsInRoom.push(data); break; case "itemremove": if (CmdExecuter._itemsInRoom == undefined) break; for (var i = 0; i < CmdExecuter._itemsInRoom.length; i++) { let item = CmdExecuter._itemsInRoom[i]; if (item.id == data.id) { CmdExecuter._itemsInRoom.splice(i, 1); CmdExecuter._removedItems.push(item.name); } } break; } }); }; CmdExecuter.prototype._finishExecute = function() { this.isWorking = false; WG.remove_hook(CmdExecuter._hookIndex); if (this.didFinishExecute) this.didFinishExecute(); }; /* ------------------------ Workflow ------------------------ *\ \* ---------------------------------------------------------- */ function WorkItem(name, run, defaultParams) { this.name = name; this.run = run; this._params = defaultParams; this.description = function() { return this.name; }; } WorkItem.prototype.didFinish = function() { this._didFinish(); }; // 可以为 WorkItem 设置 assert (function()),若返回 false 则该 WorkItem 不会被执行 WorkItem.prototype.setAssert = function(assert) { this._assert = assert; }; // 可以为 WorkItem 设置 params,如果该 WorkItem 需要的话 WorkItem.prototype.setParams = function(params) { this._params = params; }; var WorkItemCenter = { register: function(value, key) { if (typeof value == "function") { WorkItemCenter._items[key] = value; } else { WorkItemCenter._items[value.name] = value; } }, take: function(key) { return WorkItemCenter._items[key]; }, allKey: function() { return Object.keys(WorkItemCenter._items); }, _items: {}, }; WorkItemCenter.register(new WorkItem("回满状态", function() { let item = this; Role.renew(function() { item.didFinish(); }); })); WorkItemCenter.register(new WorkItem("清理背包", function() { let item = this; Role.cleanBag(function() { item.didFinish(); }); })); WorkItemCenter.register(new WorkItem("整理背包", function() { let item = this; Role.tidyBag(function() { item.didFinish(); }); })); WorkItemCenter.register(new WorkItem("通用结束动作", function() { WG.go("练功房"); let item = this; window.setTimeout(function() { WG.SendCmd("stopstate;dazuo"); item.didFinish(); }, 1000); })); WorkItemCenter.register(new WorkItem("等待技能冷却", function() { var timer; let item = this; timer = window.setInterval(function() { if (!Role.hasCoolingSkill()) { window.clearInterval(timer); item.didFinish(); } }, 1000); })); WorkItemCenter.register(new WorkItem("等待时间", function() { let item = this; window.setTimeout(function() { item.didFinish(); }, item._params); }), 1000); var Workflow = { name: undefined, items: [], willStartWorkflow: undefined, didFinishWorkflow: undefined, willStartWorkItem: undefined, // optional: function(item.name) didFinishWorkItem: undefined, // optional: function(item.name) start: function() { WG.SendCmd('stopstate'); WG.stopAllAuto(); messageClear() messageAppend("正在运行工作流 " + Workflow.name + "..."); messageAppend("* 运行工作流期间会暂时关闭 自动Boss 和 自动婚宴。"); messageAppend("* 如需要立即中断,请刷新网页。"); if (Workflow.willStartWorkflow) Workflow.willStartWorkflow(); Workflow._start(0); }, _start: function(number) { if (number >= Workflow.items.length) { Workflow._finish(); return; } let item = Workflow.items[number]; if (item._assert && item._assert() == false) { Workflow._start(number + 1); return; } item._didFinish = function() { if (Workflow.didFinishWorkItem) Workflow.didFinishWorkItem(item); messageAppend("▶ " + item.description() + "执行完毕。"); window.setTimeout(function() { Workflow._start(number + 1); }, 2000); }; if (Workflow.willStartWorkItem) Workflow.willStartWorkItem(item); messageAppend("▷ 正在运行 " + item.description() + "..."); item.run(item._params); }, _finish: function() { let name = Workflow.name; Workflow.name = undefined; Workflow.items = []; Workflow.willStart = undefined; let didFinishWorkflow = Workflow.didFinishWorkflow; Workflow.didFinish = undefined; Workflow.willStartWorkItem = undefined; Workflow.didFinishWorkItem = undefined; messageAppend("顺利完成工作流 " + name + "。"); WG.reSetAllAuto(); if (didFinishWorkflow) didFinishWorkflow(); } }; /* ------------------------ Dungeon ------------------------ *\ \* --------------------------------------------------------- */ function Dungeon(name, description, cmds, willStartDungeon, didFinishDungeon, willPerformCmd, didPerformCmd) { this.name = name; this.description = description; this.cmds = cmds; this.willStartDungeon = willStartDungeon; this.didFinishDungeon = didFinishDungeon; this.willPerformCmd = willPerformCmd; var totalCmds = this.cmds.slice(); totalCmds.push("cr;cr over"); let dungeon = this; let didFinishExecute = function() { if (dungeon.didFinishDungeon) dungeon.didFinishDungeon(); }; let executerWillPerformCmd = function(lastCmd, cmd) { return dungeon._willPerformCmd(lastCmd, cmd); }; this.executer = new CmdExecuter( totalCmds, undefined, didFinishExecute, executerWillPerformCmd, didPerformCmd, Config.cmdInterval() ); } Dungeon.prototype.enter = function() { this._reset(); if (this.willStartDungeon) { this.willStartDungeon(); } this.executer.execute(); }; Dungeon.prototype._reset = function() { this._liaoshangDoing = false; this._waitingSkillCD = false; this._noneEnemy = false; }; Dungeon.prototype._willPerformCmd = function(lastCmd, cmd) { if (this._liaoshangDoing) { if (Role.hp/Role.maxHp < 0.99) { WG.SendCmd("liaoshang"); return null; } else { this._liaoshangDoing = false; WG.SendCmd("stopstate"); } } if (Role.hp/Role.maxHp < Config.hpThresholdInDungeon()/100 && !this._noneEnemy) { WG.SendCmd("stopstate;liaoshang"); this._liaoshangDoing = true; return null; } // #结尾,表明执行完此命令将会遇到 Boss if (cmd.indexOf("#") != -1) { if (Config.waitSkillCD() == "yes" && Role.hasCoolingSkill()) { if (!this._waitingSkillCD) { messageAppend("! 前方高能,等待技能冷却再战..."); this._waitingSkillCD = true; } return null; } cmd = cmd.substring(0, cmd.length - 1); } this._waitingSkillCD = false; // $结尾,表明之后的命令不再会遇敌 var index = cmd.indexOf("$"); if (index != -1 && index != 0) { this._noneEnemy = true; cmd = cmd.substring(0, cmd.length - 1); } if (this.willPerformCmd) cmd = this.willPerformCmd(lastCmd, cmd); return cmd; }; // Dungeon Config let DungeonConfig = { "移花宫": { "shared": { willStartDungeon: function() { let index1 = WG.add_hook("item", function(data) { if (data.desc == undefined) return; let patt = new RegExp("你数了下大概有\\d(?=朵花。)"); let result = patt.exec(data.desc); if (result) { let text = result.toString(); let count = text[text.length - 1]; ToRaid.leftPush = count; } }); let index2 = WG.add_hook("exits", function(data) { if (data.items == undefined || data.items.down == undefined) return; if (data.items.down == "密道") { ToRaid.didFindSecretPath = true; } }); ToRaid.indexes = [index1, index2]; ToRaid.leftPush = 0; ToRaid.didFindSecretPath = false; }, didFinishDungeon: function() { for (var i = ToRaid.indexes.length - 1; i >= 0; i--) { let index = ToRaid.indexes[i]; WG.remove_hook(index); } }, willPerformCmd: function(lastCmd, cmd) { if (lastCmd == "look hua" && (ToRaid.leftPush == undefined || ToRaid.leftPush == 0)) { return null; } if (lastCmd == "look bed" && !ToRaid.didFindSecretPath) { WG.SendCmd("pushstart bed"); for (var i = ToRaid.leftPush - 1; i >= 0; i--) { WG.SendCmd("pushleft bed"); } for (var j = 7; j >= 0; j--) { WG.SendCmd("pushright bed"); } return null; } return cmd; }, }, "困难": { number: 222, cmds: [ "jh fb 22 start2;cr huashan/yihua/shandao 1 0", "go south;go south;go south;go south;go south;go south;go south", "go south;go south;go south;go south;go south;go south;go south", "kill?花月奴", "go south;go south", "kill?移花宫女弟子;移花宫女弟子", "go south", "kill?移花宫女弟子;移花宫女弟子", "go southeast#", "kill?移花宫二宫主 涟星;移花宫大宫主 邀月", "go northwest;go southwest", "look hua", "go southeast", "look bed", "go down;fire;go west", "kill?移花宫少宫主 花无缺", "look xia;open xia", "@wait" ], }, "简单": { number: 221, cmds: [ "jh fb 22 start1;cr huashan/yihua/shandao", "go south;go south;go south;go south;go south;go south;go south", "go south;go south;go south;go south;go south;go south;go south", "kill?花月奴", "go south;go south", "kill?移花宫女弟子;移花宫女弟子", "go south", "kill?移花宫女弟子;移花宫女弟子", "go southeast#", "kill?移花宫二宫主 涟星", "go northwest;go southwest#", "kill?移花宫大宫主 邀月", "look hua", "go southeast", "look bed", "go down;fire;go west", "kill?移花宫少宫主 花无缺", "look xia;open xia", "@wait" ], }, }, "白驼山": { "shared": { cmds: [ "jh fb 19 start3;cr baituo/damen 2 0", "go north;go north;go north", "kill?白驼山少庄主 欧阳克;白衣少女", "go north#", "kill?<hiy>西毒</hiy> 欧阳锋", "go south;go south;go south;go west;go west;go west", "kill?毒蛇", "go north", "kill?毒蛇", "go north;go north", "kill?蟒蛇$" ], }, "组队": { number: 193, } }, "燕子坞": { "简单": { number: 231, cmds: [ "jh fb 23 start1;cr murong/anbian", "go east;go east", "kill?金凤庄庄主 包不同", "go east;go south;go east;go south;go south", "kill?曼佗罗山庄庄主 王夫人", "go north;go north;go west;go north", "go east;go east;go east#", "kill?姑苏慕容公子 慕容复", "go west;go north", "look pai;bai pai;bai pai;bai pai", "go north;search", "go south#", "kill?慕容博$" ], }, "困难": { number: 232, cmds: [ "jh fb 23 start1;cr murong/anbian", "go east;go east", "kill?金凤庄庄主 包不同", "go east;go south;go east;go south;go south", "kill?曼佗罗山庄庄主 王夫人", "go north;go north;go west;go north", "go east;go east;go east#", "kill?姑苏慕容公子 慕容复", "go west;go north", "look pai;bai pai;bai pai;bai pai", "go north;search", "go south#", "kill?慕容博$" ], }, "偷书": { number: 233, description: "👏 <hiy>感谢 Airson 提供本副本代码。</hiy>", cmds: [ "jh fb 23 start1;cr murong/anbian", "go east;go east", "kill?金凤庄庄主 包不同$", "go east;go east;go east;go north", "look pai;bai pai;bai pai;bai pai", "go north;search", ], }, }, "华山论剑": { "shared": { number: 300, description: "👏 <hiy>感谢 koyodakla、freesunny 对本副本代码提供的帮助。</hiy>", cmds: [ "jh fb 30 start1;cr huashan/lunjian/leitaixia", "go up#", "kill?<hiy>东邪</hiy> 黄药师;<hiy>南帝</hiy> 一灯大师;<hiy>西毒</hiy> 欧阳锋;<hiy>北丐</hiy> 洪七公;<hiy>中神通</hiy> 王重阳$", "jump bi", "@get box", "@wait" ], willPerformCmd: function(lastCmd, cmd) { if (cmd == "@get box") WG.get_all(); return cmd; }, }, }, "温府": { ">2k闪避": { number: 103, description: "👏 <hiy>感谢 JiaQi Wan 提供本副本代码。</hiy>", cmds: [ "jh fb 23 start2;cr cd/wen/damen", "look tree;climb tree;go north;go northeast;go north;go north;go northwest;go north", "look zhuang;tiao zhuang", "kill?温家老二 温方义;温家老三 温方山;温家老四 温方施;温家老五 温方南;温家老大 温方达", "look zhuang;tiao zhuang#", "kill?<hiy>金蛇郎君</hiy> 夏雪宜", "go north", "kill?温家小姐 温仪$" ], } }, "桃花岛": { "困难": { number: 182, cmds: [ "jh fb 18 start2;cr taohua/haitan 1 0", "go south", "@look 1", "@look 5", "go south;go south", "kill?桃花岛四弟子 陆乘风", "go east;go east", "kill?桃花岛大弟子 曲灵风", "go east;go north#", "kill?<hiy>东邪</hiy> 黄药师$", ], willStartDungeon: function() { TaohuaIsland._monitorMaze(); }, didFinishDungeon: function() { TaohuaIsland._cancelMonitorMaze(); }, willPerformCmd: function(lastCmd, cmd) { if (cmd == "@look 1") { if (TaohuaIsland._goCenterCmd) { return TaohuaIsland._goCenterCmd; } else { return null; } } if (cmd == "@look 5") { if (TaohuaIsland._decodedMaze) { return TaohuaIsland._outMazeCmd(); } else { return null; } } return cmd; } } }, "财主家": { "简单": { number: 21, cmds: [ "jh fb 1 start1;cr yz/cuifu/caizhu", "kill?大狼狗;大狼狗", "go north", "kill?管家;家丁;家丁", "go north#", "kill?财主 崔员外", "look men;open men;go east", "ok {丫鬟}", "go west;go south;go south", "go north;go north;go west", "select {财主女儿 崔莺莺};ask {财主女儿 崔莺莺} about 东厢", "kill?财主女儿 崔莺莺$", "go east;go east;look gui;search gui" ], }, "困难": { number: 22, cmds: [ "jh fb 1 start2;cr yz/cuifu/caizhu 1 0", "kill?大狼狗;大狼狗", "go north", "kill?管家;家丁;家丁", "go north#", "kill?财主 崔员外", "look men;open men;go east", "ok {丫鬟}", "go west;go south;go south", "go north;go north;go west", "select {财主女儿 崔莺莺};ask {财主女儿 崔莺莺} about 东厢", "kill?财主女儿 崔莺莺$", "go east;go east;look gui;search gui" ], } }, "星宿海": { "shared": { number: 200, cmds: [ "jh fb 20 start1;cr xingxiu/xxh6", "go northeast", "kill?星宿派八师兄 出尘子", "go north", "kill?星宿派小师妹 阿紫", "go northwest", "kill?星宿派二师兄 狮吼子", "go southwest", "kill?星宿派大师兄 摘星子", "go south", "kill?星宿派三师兄 天狼子", "go north;go northeast;go north#", "kill?星宿老怪 丁春秋$" ], }, } }; function parseDungeonConfig() { var result = []; for (var key in DungeonConfig) { let value = DungeonConfig[key]; let count = Object.keys(value).length; var shared = value["shared"]; if (shared && count > 1) { for (var subkey in value) { if (subkey == "shared") continue; var item = { }; for (var sharedKey in shared) { item[sharedKey] = shared[sharedKey]; } let subvalue = value[subkey]; for (var itemKey in subvalue) { item[itemKey] = subvalue[itemKey]; } item.name = key + "(" + subkey + ")"; result.push(item); } } else if (shared && count == 1) { shared.name = key; result.push(shared); } else if (count > 0) { for (var subkey in value) { var item = { }; let subvalue = value[subkey]; for (var itemKey in subvalue) { item[itemKey] = subvalue[itemKey]; } item.name = key + "(" + subkey + ")"; result.push(item); } } } result.sort(function(a, b) { return b.number - a.number; }); return result; } let ParsedDungeonConfig = parseDungeonConfig(); (function registerDungeonWorkItems() { let item = new WorkItem("扫荡副本", function(dungeonName) { var config; for (var i = 0; i < ParsedDungeonConfig.length; i++) { let c = ParsedDungeonConfig[i]; if (c.name == dungeonName) { config = c; break; } } let dungeon = new Dungeon( config.name, config.description, config.cmds, config.willStartDungeon, undefined, config.willPerformCmd, config.didPerformCmd ); let didFinishDungeon = config.didFinishDungeon; let item = this; dungeon.didFinishDungeon = function() { if (didFinishDungeon) didFinishDungeon(); item.didFinish(); }; dungeon.enter(); }, "副本名称"); item.description = function() { return "扫荡" + this._params; }; WorkItemCenter.register(item); })(); /* ------------------------ Raid ------------------------ *\ \* ------------------------------------------------------ */ var Raid = { repeatRun: function(name) { let num = prompt("输入自动【" + name + "】副本次数,例如:\"1\"", '1'); if (num > 0) { Raid._repeatTotal = num; Raid._repeatCounter = 0; } else { return; } Workflow.name = "自动扫荡副本 <" + name + "> " + num + "次"; var items = []; let toDungeon = WorkItemCenter.take("扫荡副本"); toDungeon.setParams(name); let cleanBagItem = Raid._cleanBagItem(); for (var i = 0; i < num; i++) { items.push(WorkItemCenter.take("回满状态")); if (cleanBagItem) items.push(cleanBagItem); items.push(toDungeon); } if (cleanBagItem) items.push(cleanBagItem); items.push(WorkItemCenter.take("通用结束动作")); Workflow.items = items; Workflow.willStartWorkItem = function(item) { if (item.name == "扫荡副本") { Raid._repeatCounter += 1; messageAppend("- 自动扫荡进度:正在进行 " + Raid._repeatCounter + "/" + Raid._repeatTotal + "..."); } }; Workflow.start(); }, _cleanBagItem: function() { switch (Config.bagCleanWay()) { case "clean": return WorkItemCenter.take("清理背包"); case "tidy": return WorkItemCenter.take("整理背包"); default: return null; } }, _repeatTotal: 1, _repeatCounter: 0, }; var Wudaota2 = { run: function() { Workflow.name = "自动扫荡武道塔"; var items = []; items.push(WorkItemCenter.take("清理背包")); items.push(Wudaota2._reset); items.push(Wudaota2._fastFight); items.push(WorkItemCenter.take("通用结束动作")); Workflow.items = items; Workflow.start(); }, _reset: new WorkItem("重置武道塔", function() { let cmds = [ "jh fam 0 start;jh fam 8 start", "@reset", ]; let item = this; let didFinishExecute = function() { item.didFinish(); }; let willPerformCmd = function(lastCmd, cmd) { if (cmd == "@reset") { let butler = Role.findItem("守护人"); return "select " + butler + ";ask1 " + butler; } return cmd; }; let executer = new CmdExecuter(cmds, willStartExecute, didFinishExecute, willPerformCmd); executer.execute(); }), _fight: new WorkItem("挑战守护者", function() { }), _fastFight: new WorkItem("快速挑战守护者(扫荡符)", function() { }), }; /* ------------------------ UI ------------------------ *\ \* ---------------------------------------------------- */ let HighlightedRaids = ["移花宫(简单)", "移花宫(困难)"]; var MoreRaid = new Vue({ el: '#MoreRaid', data: { items: [], }, methods: { getItems: function() { var result = [{name: "< 返回"}]; for (var i = 0; i < ParsedDungeonConfig.length; i++) { let config = ParsedDungeonConfig[i]; if (HighlightedRaids.indexOf(config.name) != -1) continue; result.push(config); } return result; }, createSpan: function(createElement, item) { return createElement( 'span', { attrs: { class: "zdy-item" }, style: { width: "120px" }, on: { click: function() { if (item.name == "< 返回") { UI.home(); } else { Raid.repeatRun(item.name); } }, }, }, item.name, ); }, }, render: function(createElement, item) { let theSelf = this; var subNodes = [ createElement("br"), "⛩ ", createElement("hic", ["更多副本"]), createElement("br"), createElement("br"), ]; let spans = this.items.map(function(item) { return theSelf.createSpan(createElement, item); }); subNodes.push(spans); return createElement( "div", { attrs: { class: "item-commands" }, style: { "text-align": "center" }, }, subNodes, ); } }); MoreRaid.items = MoreRaid.getItems(); var UI = { home: function() { messageClear(); var html = ` <div class = "item-commands" style="text-align:center"> </br>🏮 <ord>恭祝 2019(己亥年) 新春大吉、万事如意!</ord>🏮</br></br> <span class = "zdy-item yihua" style="width:120px"> 移花宫(简单) </span> <span class = "zdy-item yihuaH" style="width:120px"> 移花宫(困难) </span> <span class = "zdy-item steal" style="width:120px"> 🌝 偷渡副本 </span> <span class = "zdy-item raidSetting" style="width:120px"> ⚙ 副本设置 </span> <span class = "zdy-item wudaota" style="width:120px"> 🏯 <hio>武道塔</hio> </span> <span class = "zdy-item xiangyang" style="width:120px"> ⚔ <hiy>守卫襄阳</hiy> </span> <span class = "zdy-item shortcut" style="width:120px"> 🚀 <hig>捷径</hig> </span> <span class = "zdy-item moreRaid" style="width:120px"> ⛩ <hic>更多副本</hic> </span> <div> </br><a href="https://gf.qytechs.cn/zh-CN/scripts/375851-wsmud-raid/feedback" style="font-size:1em">(版本: ${GM_info.script.version})</a> </div> </div>`; messageAppend(html); $(".yihua").on('click',function(){ Raid.repeatRun("移花宫(简单)"); }); $(".yihuaH").on('click', function () { Raid.repeatRun("移花宫(困难)"); }); $(".steal").on('click', function () { UI.steal(); }); $(".raidSetting").on('click', function () { UI.setting(); }); $(".wudaota").on('click', function () { UI.wudaota(); }); $(".xiangyang").on('click', function () { UI.xiangyang(); }); $(".shortcut").on('click', function () { UI.shortcut(); }); $(".moreRaid").on('click', function () { UI.moreRaid(); }); }, steal: function() { messageClear(); var html = ` <div class = "item-commands" style="text-align:center"> </br>🌝 偷渡副本</br> <span style='border:solid 0px gray'> <label for="selectSteal">◆ 选择预置副本: </label><select style='width:120px' id="selectSteal"> <option value="yihuaH">移花宫(困难)</option> <option value="gumuH">古墓派(困难)</option> </select> </span> </br> <textarea class = "settingbox hide" style = "display: inline-block;font-size:0.8em" id = "stealCmd"></textarea> </br> <span class = "zdy-item stealBack" style="width:120px"> < 返回 </span> <span class = "zdy-item stealStart" style="width:120px"> 开始偷渡 </span> </div>`; messageAppend(html); var yihuaHCmd = "jh fb 22 start2;cr huashan/yihua/shandao 1 0;cr;cr over"; $("#selectSteal").change(function () { var selected = $("#selectSteal").val(); switch (selected) { case "yihuaH": $('#stealCmd').val(yihuaHCmd); break; case "gumuH": $('#stealCmd').val("jh fb 29 start2;cr gumu/gumukou 1 0;cr;cr over"); break; default: $('#stealCmd').val(""); break; } }); $("#selectSteal").val("yihuaH"); $('#stealCmd').val(yihuaHCmd); $(".stealBack").on('click', function () { UI.home(); }); $(".stealStart").on('click', function () { let num = prompt("输入偷渡次数,例如:\"1\"", '1'); if (num <= 0) return; var cmd = $('#stealCmd').val(); console.log(cmd); if (cmd.search(/[^\s]/g) == -1) return; var flow = new CommandWorkflow2("偷渡副本", [cmd], num, 2000); flow.run(); }); }, setting: function() { messageClear(); var html = ` <div class = "item-commands" style="text-align:center"> </br>⚙ 副本设置</br></br> <span style='border:solid 0px gray'> <label for="liaoshangInRaid">◆ 副本内疗伤,当气血低于: </label><select style='width:80px' id="liaoshangInRaid"> <option value="100">100%</option> <option value="90">90%</option> <option value="80">80%</option> <option value="70">70%</option> <option value="60">60%</option> <option value="50">50%</option> <option value="40">40%</option> <option value="30">30%</option> <option value="20">20%</option> <option value="10">10%</option> </select> </span> <span style='border:solid 0px gray'> <label for="waitSkillCD">◆ Boss战前等待技能冷却: </label><select style='width:80px' id = "waitSkillCD"> <option value="no">关闭</option> <option value="yes">开启</option> </select> </span> <span style='border:solid 0px gray'> <label for="bagCleanWay">◆ 背包清理方案: </label><select style='width:80px' id = "bagCleanWay"> <option value="none">不清理</option> <option value="clean">售卖</option> <option value="tidy">存仓&售卖</option> </select> </span> <span style='border:solid 0px gray'> <label for="cmdInterval">◆ 命令间隔时间: </label><select style='width:80px' id = "cmdInterval"> <option value=1000>1秒(推荐)</option> <option value=2000>2秒</option> <option value=3000>3秒</option> <option value=4000>4秒</option> </select> </span> <!-- <span style='border:solid 0px gray'> <label for="autoArm">自动换装备&技能: </label><select style='width:80px' id = "autoArm"> <option value="no">关闭</option> <option value="yes">开启</option> </select><button>更新为当前</button> </span> --> </br> <span class = "zdy-item settingBack" style="width:120px"> < 返回 </span> </div>`; messageAppend(html); $('#liaoshangInRaid').val(Config.hpThresholdInDungeon()); $("#liaoshangInRaid").change(function () { Config.setHpThresholdInDungeon($("#liaoshangInRaid").val()); }); $('#waitSkillCD').val(Config.waitSkillCD()); $("#waitSkillCD").change(function () { Config.setWaitSkillCD($("#waitSkillCD").val()); }); $('#bagCleanWay').val(Config.bagCleanWay()); $("#bagCleanWay").change(function () { Config.setBagCleanWay($("#bagCleanWay").val()); }); $('#cmdInterval').val(Config.cmdInterval()); $("#cmdInterval").change(function () { Config.setCmdInterval($("#cmdInterval").val()); }); $(".settingBack").on('click', function () { UI.home(); }); }, wudaota: function() { messageClear(); var html = ` <div class = "item-commands" style="text-align:center"> </br>🏯 <hio>武道塔</hio></br></br> <!-- <span style='border:solid 0px gray;width:100%'> <label>◆ 自动战斗到第 </label><input type="number" id="wudaotaAutoToFloor" style="text-align:center;width:60px"><label> 层,</label><label for="wudaotaFastCombatOpening">剩余层扫荡符处理 </label><select style='width:60px' id = "wudaotaFastCombatOpening"> <option value="no">关闭</option> <option value="yes">开启</option> </select><label>。</label> </span> <span style='border:solid 0px gray;width:100%'> <label for="wudaotaHpThreshold">◆ 疗伤,当气血小于 </label><select style='width:60px' id="wudaotaHpThreshold"> <option value="100">100%</option> <option value="90">90%</option> <option value="80">80%</option> <option value="70">70%</option> <option value="60">60%</option> <option value="50">50%</option> <option value="40">40%</option> <option value="30">30%</option> <option value="20">20%</option> <option value="10">10%</option> </select><label>;从第 </label><input type="number" id="wudaotaWaitSkillCDFrom" style="text-align:center;width:60px"><label for="waitSkillCD"> 层开始,战前等待技能冷却。</label> </span> --> 即将开放... </br> <span class = "zdy-item wudaoBack" style="width:120px"> < 返回 </span> <!--<span class = "zdy-item wudaoStart" style="width:120px"> 开始爬塔 </span>--> </div>`; messageAppend(html); $('#wudaotaAutoToFloor').val(Config.wudaota.autoToFloor()); $('#wudaotaAutoToFloor').focusout(function () { let autoToFloor = $('#wudaotaAutoToFloor').val(); if (autoToFloor >= 0 && autoToFloor <= 100) { Config.wudaota.setAutoToFloor(autoToFloor); } else { $('#wudaotaAutoToFloor').val(Config.wudaota.autoToFloor()); } }); $('#wudaotaFastCombatOpening').val(Config.wudaota.fastCombatOpening()); $("#wudaotaFastCombatOpening").change(function () { Config.wudaota.setFastCombatOpening($("#wudaotaFastCombatOpening").val()); }); $('#wudaotaHpThreshold').val(Config.wudaota.hpThresholdInRaid()); $("#wudaotaHpThreshold").change(function () { Config.wudaota.setHpThresholdInRaid($("#wudaotaHpThreshold").val()); }); $('#wudaotaWaitSkillCDFrom').val(Config.wudaota.waitSkillCDFrom()); $('#wudaotaWaitSkillCDFrom').focusout(function () { let from = $('#wudaotaWaitSkillCDFrom').val(); if (from >= 0 && from <= 100) { Config.wudaota.setWaitSkillCDFrom(from); } else { $('#wudaotaWaitSkillCDFrom').val(Config.wudaota.waitSkillCDFrom()); } }); $(".wudaoBack").on('click', function () { UI.home(); }); $(".wudaoStart").on('click', function () { Wudaota.run(); }); }, xiangyang: function() { messageClear(); var html = ` <div class = "item-commands" style="text-align:center"> </br>⚔ <hiy>守卫襄阳</hiy></br></br> <span class = "zdy-item xiangyangBack" style="width:120px"> < 返回 </span> <span class = "zdy-item xiangyangStart" style="width:120px"> <hiy>提开发建议=></hiy> </span> </div>`; messageAppend(html); $(".xiangyangBack").on('click', function () { UI.home(); }); $(".xiangyangStart").on('click', function () { window.open("https://gf.qytechs.cn/zh-CN/forum/discussion/48858/%E5%AE%88%E5%8D%AB%E8%A5%84%E9%98%B3%E5%BC%80%E5%8F%91%E5%BB%BA%E8%AE%AE/p1?new=1", '_blank').location; }); }, moreRaid: function() { messageClear(); let wg_log = document.getElementsByClassName("WG_log")[0]; let pre = wg_log.getElementsByTagName("pre")[0]; pre.appendChild(MoreRaid.$el); }, shortcut: function() { messageClear(); var html = ` <div class = "item-commands" style="text-align:center"> </br>🚀 <hig>捷径</hig></br></br> <span class = "zdy-item shortcutBack" style="width:120px"> < 返回 </span> <span class = "zdy-item outMaze" style="width:120px"> 走出桃花林 </span> <span class = "zdy-item zhoubotong" style="width:120px"> 找到周伯通 </span> </div>`; messageAppend(html); $(".shortcutBack").on('click', function () { UI.home(); }); $(".outMaze").on('click', function () { WG.SendCmd('stopstate'); TaohuaIsland.outMaze(); }); $(".zhoubotong").on('click', function () { WG.SendCmd('stopstate'); TaohuaIsland.zhoubotong(); }); } }; var ToRaid = { menu :UI.home }; var TaohuaIsland = { outMaze: function() { if (!Role.atPath("taohua/haitan")) { messageAppend("只有在 桃花岛的海滩 才能使用此虫洞。"); return; } let cmds = [ "go south", "@look 1", "@look 5" ]; let willStartExecute = function() { TaohuaIsland._monitorMaze(); }; let willPerformCmd = function(lastCmd, cmd) { if (cmd == "@look 1") { if (TaohuaIsland._goCenterCmd) { return TaohuaIsland._goCenterCmd; } else { return null; } } if (cmd == "@look 5") { if (TaohuaIsland._decodedMaze) { return TaohuaIsland._outMazeCmd(); } else { return null; } } return cmd; }; let executer = new CmdExecuter( cmds, willStartExecute, TaohuaIsland._cancelMonitorMaze, willPerformCmd, undefined, 1000 ); executer.execute(); }, zhoubotong: function() { if (!Role.atPath("taohua/wofang")) { messageAppend("只有在 蓉儿的卧室 才能使用此虫洞。"); return; } let cmds = [ "go south;go west;go west;go west;go north;go north;go north", "go west;go east;go west;go east;go west", "go south", "@look 1", "@look 5", "@go 2", "@go 3", "@go 4", "@go 6", "@go 7", "@go 8", ]; let willStartExecute = function() { TaohuaIsland._monitorMaze(); TaohuaIsland._exitsHookIndex = WG.add_hook("exits", function(data) { if (TaohuaIsland._lastCoord == undefined || TaohuaIsland._lastCoord == [0, 0]) return; if (Object.keys(data.items).length != 4) return; for(var key in data.items) { if (data.items[key] != "桃花林") return; } let normalExistMap = [ [["north", "northeast", "east"], ["east", "north", "south"], ["east", "south", "southeast"],], [["east", "north", "west"], [], ["west", "east", "south"],], [["west", "northwest", "north"], ["west", "south", "north"], ["west", "southwest", "south"],] ]; let x = TaohuaIsland._lastCoord[0] + 1; let y = TaohuaIsland._lastCoord[1] + 1; let normalExists = normalExistMap[x][y]; for(var key2 in data.items) { if (normalExists.indexOf(key2) != -1) continue; TaohuaIsland._goCave = "go " + key2; return; } }); }; let didFinishExecute = function() { TaohuaIsland._lastCoord = undefined; TaohuaIsland._lastGo = undefined; TaohuaIsland._goCave = undefined; TaohuaIsland._cancelMonitorMaze(); WG.remove_hook(TaohuaIsland._exitsHookIndex); }; let willPerformCmd = function(lastCmd, cmd) { if (TaohuaIsland._goCave) return TaohuaIsland._goCave + ";go west;[exit]"; var number = 0; switch (cmd) { case "@look 1": if (TaohuaIsland._goCenterCmd) { return TaohuaIsland._goCenterCmd; } else { return null; } break; case "@look 5": if (!TaohuaIsland._decodedMaze) return null; break; case "@go 2": TaohuaIsland._lastCoord = TaohuaIsland._mazeCoords[2]; TaohuaIsland._lastGo = TaohuaIsland._mazePath(TaohuaIsland._lastCoord); return TaohuaIsland._lastGo; case "@go 3": number = 3; break; case "@go 4": number = 4; break; case "@go 6": number = 6; break; case "@go 7": number = 7; break; case "@go 8": number = 8; break; } if (number != 0) { let back = TaohuaIsland._mazeBackPath(TaohuaIsland._lastGo); TaohuaIsland._lastCoord = TaohuaIsland._mazeCoords[number]; TaohuaIsland._lastGo = TaohuaIsland._mazePath(TaohuaIsland._lastCoord); return back + ";" + TaohuaIsland._lastGo; } return cmd; }; let executer = new CmdExecuter( cmds, willStartExecute, didFinishExecute, willPerformCmd, undefined, 1000 ); executer.execute(); }, _outMazeCmd: function() { var cmd = ""; for (var i = 2; i <= 9; i++) { let coord = TaohuaIsland._mazeCoords[i]; let go = TaohuaIsland._mazePath(coord); if (i == 9) { cmd += go + ";" + go; } else { cmd += go + ";" + TaohuaIsland._mazeBackPath(go) + ";"; } } cmd += ";go south"; return cmd; }, _mazePath: function(coord) { let pathMap = [ ["go southwest", "go west", "go northwest"], ["go south", "", "go north"], ["go southeast", "go east", "go northeast"] ]; let x = coord[0] + 1; let y = coord[1] + 1; return pathMap[x][y]; }, _mazeBackPath: function(path) { let backMap = { "": "", "go southwest": "go northeast", "go west": "go east", "go northwest": "go southeast", "go south": "go north", "go north": "go south", "go southeast": "go northwest", "go east": "go west", "go northeast": "go southwest" }; return backMap[path]; }, _monitorMaze: function() { TaohuaIsland._mazeCoords = [ [2, 2], // unused [2, 2], [2, 2], [2, 2], [2, 2], [0, 0], [2, 2], [2, 2], [2, 2], [2, 2] ]; TaohuaIsland._atFirst = false; TaohuaIsland._goCenterCmd = undefined; TaohuaIsland._decodedMaze = false; let index1 = WG.add_hook(["room", "exits"], function(data) { if (TaohuaIsland._goCenterCmd != undefined) return; if (data.type == "room") { if (data.desc == undefined) return; let patt = new RegExp("四周栽了大概有一棵桃树"); let result = patt.exec(data.desc); if (result) TaohuaIsland._atFirst = true; } else if (data.type == "exits") { if (data.items == undefined) return; if (TaohuaIsland._atFirst) { if (data.items.north && data.items.south) { if (data.items.west) { TaohuaIsland._mazeCoords[1] = [1, 0]; TaohuaIsland._goCenterCmd = "go west" } else { TaohuaIsland._mazeCoords[1] = [-1, 0]; TaohuaIsland._goCenterCmd = "go east" } } else if (data.items.west && data.items.east) { if (data.items.north) { TaohuaIsland._mazeCoords[1] = [0, -1]; TaohuaIsland._goCenterCmd = "go north" } else { TaohuaIsland._mazeCoords[1] = [0, 1]; TaohuaIsland._goCenterCmd = "go south" } } } } }); let index2 = WG.add_hook("room", function(data) { if (TaohuaIsland._decodedMaze) return; if (data.desc == undefined) return; let patt = new RegExp("能看到东南方向大概有.(?=棵桃树)"); let count = patt.exec(data.desc); if (!count) return; let text = count.toString(); switch (text.substring(text.length - 1)) { case "二": TaohuaIsland._mazeCoords[2] = [1, -1]; break; case "四": TaohuaIsland._mazeCoords[4] = [1, -1]; break; case "六": TaohuaIsland._mazeCoords[6] = [1, -1]; break; case "八": TaohuaIsland._mazeCoords[8] = [1, -1]; break; } TaohuaIsland._mazeCoords[9] = [-TaohuaIsland._mazeCoords[1][0], -TaohuaIsland._mazeCoords[1][1]]; while (true) { if (TaohuaIsland._mazeCoords[2][0] != 2) { TaohuaIsland._mazeCoords[8] = [-TaohuaIsland._mazeCoords[2][0], -TaohuaIsland._mazeCoords[2][1]]; } if (TaohuaIsland._mazeCoords[8][0] != 2) { if (TaohuaIsland._mazeCoords[8][0] == TaohuaIsland._mazeCoords[1][0]) { TaohuaIsland._mazeCoords[6] = [TaohuaIsland._mazeCoords[8][0], -TaohuaIsland._mazeCoords[8][1]]; } else { TaohuaIsland._mazeCoords[6] = [-TaohuaIsland._mazeCoords[8][0], TaohuaIsland._mazeCoords[8][1]]; } } if (TaohuaIsland._mazeCoords[6][0] != 2) { TaohuaIsland._mazeCoords[4] = [-TaohuaIsland._mazeCoords[6][0], -TaohuaIsland._mazeCoords[6][1]]; } if (TaohuaIsland._mazeCoords[4][0] != 2) { if (TaohuaIsland._mazeCoords[4][0] == TaohuaIsland._mazeCoords[9][0]) { TaohuaIsland._mazeCoords[2] = [TaohuaIsland._mazeCoords[4][0], -TaohuaIsland._mazeCoords[4][1]]; } else { TaohuaIsland._mazeCoords[2] = [-TaohuaIsland._mazeCoords[4][0], TaohuaIsland._mazeCoords[4][1]]; } } if (TaohuaIsland._mazeCoords[2][0] != 2 && TaohuaIsland._mazeCoords[4][0] != 2 && TaohuaIsland._mazeCoords[6][0] != 2 && TaohuaIsland._mazeCoords[8][0] != 2) { break; } } if (TaohuaIsland._mazeCoords[8][0] == TaohuaIsland._mazeCoords[4][0]) { TaohuaIsland._mazeCoords[3] = [TaohuaIsland._mazeCoords[8][0], 0]; } else { TaohuaIsland._mazeCoords[3] = [0, TaohuaIsland._mazeCoords[8][1]]; } TaohuaIsland._mazeCoords[7] = [-TaohuaIsland._mazeCoords[3][0], -TaohuaIsland._mazeCoords[3][1]]; TaohuaIsland._decodedMaze = true; }); TaohuaIsland._mazeHookIndexes = [index1, index2]; }, _cancelMonitorMaze: function() { for (var i = TaohuaIsland._mazeHookIndexes.length - 1; i >= 0; i--) { let index = TaohuaIsland._mazeHookIndexes[i]; WG.remove_hook(index); } }, }; let ChineseToNumber = { run: function(text) { var rtn = 0; var section = 0; var number = 0; var secUnit = false; var str = text.split(''); for (var i = 0; i < str.length; i++) { var num = ChineseToNumber.chnNumChar[str[i]]; if (typeof num !== 'undefined') { number = num; if (i === str.length - 1){ section += number; } }else{ var unit = ChineseToNumber.chnNameValue[str[i]].value; secUnit = ChineseToNumber.chnNameValue[str[i]].secUnit; if (secUnit){ section = (section + number) * unit; rtn += section; section = 0; } else { section += (number * unit); } number = 0; } } return rtn + section; }, chnNumChar: { 零:0, 一:1, 二:2, 三:3, 四:4, 五:5, 六:6, 七:7, 八:8, 九:9 }, chnNameValue: { 十:{value:10, secUnit:false}, 百:{value:100, secUnit:false}, 千:{value:1000, secUnit:false}, 万:{value:10000, secUnit:true}, 亿:{value:100000000, secUnit:true} } }; $(document).ready(function () { WG = unsafeWindow.WG; messageAppend = unsafeWindow.messageAppend; messageClear = unsafeWindow.messageClear; T = unsafeWindow.T; unsafeWindow.ToRaid = ToRaid; unsafeWindow.Role = Role; Role.init(); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址