// ==UserScript==
// @name wsmud_Raid
// @namespace cqv
// @version 0.5.0
// @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 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.Send("stopstate;liaoshang");
break;
case "liaoshang finish":
if (Role.mp/Role.maxMp < 0.7) {
Role._lastWeapon = Role.equipments[0];
Role._renewStatus = "dazuo doing";
WG.Send("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.Send("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.Send("uneq " + Role.equipments[i]);
} else {
WG.Send("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.Send("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.Send(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.Send("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.Send('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) {
return null;
} else {
this._liaoshangDoing = false;
WG.Send("stopstate");
}
}
if (Role.hp/Role.maxHp < Config.hpThresholdInDungeon()/100 && !this._noneEnemy) {
WG.Send("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;
// $结尾,表明之后的命令不再会遇敌
if (cmd.indexOf("$") != -1) {
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.Send("pushstart bed");
for (var i = ToRaid.leftPush - 1; i >= 0; i--) {
WG.Send("pushleft bed");
}
for (var j = 7; j >= 0; j--) {
WG.Send("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 lunjian" 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("移花宫(困难)");
});
$(".lunjian").on('click', function () {
Raid.repeatRun("华山论剑");
});
$(".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();
});
},
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.Send('stopstate');
TaohuaIsland.outMaze();
});
$(".zhoubotong").on('click', function () {
WG.Send('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;
unsafeWindow.ToRaid = ToRaid;
unsafeWindow.Role = Role;
Role.init();
});
})();