// ==UserScript==
// @name wsmud_Raid
// @namespace cqv
// @version 0.2.1
// @date 23/12/2018
// @modified 25/12/2018
// @homepage https://greasyfork.org/zh-CN/scripts/375851
// @description 武神传说 MUD
// @author Bob.cn
// @match http://game.wsmud.com/*
// @match http://www.wsmud.com/*
// @run-at document-end
// @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,
hp: 0,
maxHp: 0,
mp: 0,
maxMp: 0,
status: [],
equipments: [],
init: function() {
WG.add_hook("login", function(data) {
Role.id = data.id;
Role.status = [];
});
Role._monitorHpMp();
Role._monitorStatus();
Role._monitorEquipments();
Role._monitorSkillCD();
Role._monitorLocation();
},
hasStatus: function(s) {
return Role.status.indexOf(s) != -1;
},
isFree: function() {
return !Role.hasStatus("busy") && !Role.hasStatus("faint");
},
atPath: function(p) {
return p == Role._roomPath;
},
atRoom: function(n) {
return n == Role._roomName;
},
renew: function(callback) {
if (!Role.isFree) {
window.setTimeout(function() { Role.renew(callback) }, 2000);
return;
}
switch (Role._renewStatus) {
case "resting":
messageAppend("正在为角色回复状态...");
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);
},
clearBag: function(callback) {
Role._clearBag(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;
},
_renewHookIndex: undefined,
_renewStatus: "resting",
_coolingSkills: [],
_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;
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;
});
},
_clearBag: 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._clearBag(counter + 1, callback); }, 1000);
},
};
var Config = {
hpThresholdInRaid: function() {
return GM_getValue(Role.id + "@hpThresholdInRaid", "50");
},
setHpThresholdInRaid: function(t) {
GM_setValue(Role.id + "@hpThresholdInRaid", t);
},
waitSkillCD: function() {
return GM_getValue(Role.id + "@waitSkillCD", "no");
},
setWaitSkillCD: function(w) {
GM_setValue(Role.id + "@waitSkillCD", w);
},
};
var Executer = {
interval: undefined,
cmds: [],
willExecuteCmd: undefined, // optional: function(lastCmd, cmd)
didExecuteCmd: undefined, // optional: function(cmd)
didFinishExecute: undefined, // optional: function()
isWorking: false,
execute: function() {
if (Executer.isWorking) return false;
Executer.isWorking = true;
if (Executer.interval == undefined) Executer.interval = Executer._defaultInterval;
Executer._executeCmd(0);
return true;
},
_defaultInterval: 2000,
_executeCmd: function(index) {
if (index >= Executer.cmds.length) {
Executer._finish();
return;
}
if (!Role.isFree()) { Executer._delayExecuteCmd(index); return; }
var cmd = Executer.cmds[index];
if (Executer.willExecuteCmd) {
var lastCmd = null;
if (index > 0) lastCmd = Executer.cmds[index - 1];
let valid = Executer.willExecuteCmd(lastCmd, cmd);
if (!valid) { Executer._delayExecuteCmd(index); return; }
cmd = valid;
}
// @开头,虚命令,不真正执行
if (cmd.indexOf("@") == -1) {
console.log("执行命令:" + cmd);
WG.Send(cmd);
}
if (Executer.didExecuteCmd) { Executer.didExecuteCmd(cmd); }
// [exit] 保留虚命令,立即退出执行器
if (cmd.indexOf("[exit]") != -1) {
Executer._finish();
return;
} else {
Executer._delayExecuteCmd(index + 1);
}
},
_delayExecuteCmd: function(index) {
window.setTimeout(function() { Executer._executeCmd(index); }, Executer.interval);
},
_finish() {
Executer.interval = Executer._defaultInterval;
Executer.cmds = [];
Executer.willExecuteCmd = undefined;
Executer.didExecuteCmd = undefined;
let finish = Executer.didFinishExecute;
Executer.didFinishExecute = undefined;
Executer.isWorking = false;
if (finish) finish();
},
};
var Raid = {
/* public */
name: "副本名称",
cmds: [],
enemyNames: [],
willStartRun: undefined, // optional: function()
didFinishRun: undefined, // optional: function()
willStartOnceRun: undefined, // optional: function(number)
didEndOnceRun: undefined, // optional: function(number)
willExecuteCmd: undefined, // optional: function(lastCmd, cmd)
didExecuteCmd: undefined, // optional: function(cmd)
repeatRun: function() {
let num = prompt("输入自动【" + Raid.name + "】副本次数,例如:\"1\"", '1');
if (num > 0) {
Raid._repeatTotal = num;
Raid._repeatCounter = 0;
} else {
return;
}
messageClear();
messageAppend("正在运行自动 " + Raid.name + "...");
messageAppend("* 自动副本期间会暂时关闭 自动Boss 和 自动婚宴。");
messageAppend("* 如需要立即中断,请刷新网页。");
WG.stopAllAuto();
Raid._cleanForRepeatRun();
Raid._indexes.push(Raid._monitorEnemy());
Raid._indexes.push(Raid._monitorAddEnemy());
Raid._indexes.push(Raid._monitorEnemyDie());
if (Raid.willStartRun) { Raid.willStartRun(); }
Raid._onceRun();
},
/* private */
_indexes: [],
_repeatTotal: 1,
_repeatCounter: 0,
_liaoshangDoing: false,
_waitingSkillCD: false,
_noneEnemy: false,
_enemyIds: undefined, // 当前房间的敌人id
_enemyCounter: 0, // 当前房间剩余的敌人
_onceRun: function() {
Raid._cleanForOnceRun();
messageAppend("正在第 " + (Raid._repeatCounter + 1) + "/"+ Raid._repeatTotal +" 次运行自动 " + Raid.name + "...");
let clearBagCallback = function() {
window.setTimeout(function() {
messageAppend("元气满满,进入副本...");
if (Raid.willStartOnceRun) { Raid.willStartOnceRun(Raid._repeatCounter); }
var totalCmds = Raid.cmds.slice(); totalCmds.push("cr;cr over");
Executer.cmds = totalCmds;
console.log(Executer.cmds);
Executer.willExecuteCmd = function(lastCmd, cmd) {
return Raid._willExecuteCmd(lastCmd, cmd);
};
Executer.didExecuteCmd = Raid.didExecuteCmd;
Executer.didFinishExecute = Raid._finishOnceRun;
Executer.execute();
}, 1000);
};
let renewCallback = function() {
window.setTimeout(function() {
Role.clearBag(clearBagCallback);
}, 1000);
};
Role.renew(renewCallback);
},
_cleanForRepeatRun: function() {
for (var i = Raid._indexes.length - 1; i >= 0; i--) {
let index = Raid._indexes[i];
WG.remove_hook(index);
}
Raid._indexes = [];
WG.reSetAllAuto();
},
_cleanForOnceRun: function() {
Raid._enemyIds = undefined;
Raid._enemyCounter = 0;
Raid._liaoshangDoing = false;
Raid._waitingSkillCD = false;
Raid._noneEnemy = false;
},
_finishOnceRun: function() {
if (Raid.didEndOnceRun) { Raid.didEndOnceRun(Raid._repeatCounter); }
messageClear();
messageAppend("已完成第 " + (Raid._repeatCounter + 1) + "/"+ Raid._repeatTotal + " 次自动 " + Raid.name);
Raid._repeatCounter += 1;
if (Raid._repeatCounter < Raid._repeatTotal) {
window.setTimeout(Raid._onceRun, 2000);
} else {
Raid._cleanForRepeatRun();
if (Raid.didFinishRun) { Raid.didFinishRun(); }
window.setTimeout(function() {
WG.go("练功房");
WG.Send("stopstate;dazuo");
messageAppend("已经全部完成自动 " + Raid.name + "。");
}, 1000);
}
},
_willExecuteCmd: function(lastCmd, cmd) {
if (Raid._enemyCounter > 0) {
Raid._killEnemy();
return null;
}
if (Raid._liaoshangDoing) {
if (Role.hp/Role.maxHp < 0.99) {
return null;
} else {
Raid._liaoshangDoing = false;
WG.Send("stopstate");
}
}
if (Role.hp/Role.maxHp < Config.hpThresholdInRaid()/100 && !Raid._noneEnemy) {
WG.Send("liaoshang");
Raid._liaoshangDoing = true;
return null;
}
// #开头,表明执行完此命令将会遇到 Boss
if (cmd.indexOf("#") != -1) {
if (Config.waitSkillCD() == "yes" && Role.hasCoolingSkill()) {
if (!Raid._waitingSkillCD) {
messageAppend("前方高能,等待技能冷却再战...");
Raid._waitingSkillCD = true;
}
return null;
}
cmd = cmd.substring(1);
}
Raid._waitingSkillCD = false;
// $结尾,表明之后的命令不再会遇敌
if (cmd.indexOf("$") != -1) {
Raid._noneEnemy = true;
cmd = cmd.substring(0, cmd.length - 1);
}
if (Raid.willExecuteCmd) cmd = Raid.willExecuteCmd(lastCmd, cmd);
return cmd;
},
_killEnemy: function() {
if (Raid._enemyIds == undefined) { return }
for (var i = 0; i < Raid._enemyIds.length; i++) {
let enemyId = Raid._enemyIds[i];
WG.Send("kill " + enemyId);
}
},
_monitorEnemy: function() {
let index = WG.add_hook("items", function(data) {
if (data.items == undefined) return;
var enemyIds = [];
for (var i = 0; i < data.items.length; i++) {
let item = data.items[i];
if (item.id == undefined || item.name == undefined) continue;
if (Raid.enemyNames.indexOf(item.name) >= 0) {
enemyIds.push(item.id);
}
}
Raid._enemyIds = enemyIds;
Raid._enemyCounter = enemyIds.length;
});
return index;
},
_monitorAddEnemy: function() {
let index = WG.add_hook("itemadd", function(data) {
if (data.name == undefined) return;
if (Raid.enemyNames.indexOf(data.name) == -1) return;
if (Raid._enemyIds) {
Raid._enemyIds.push(data.id);
Raid._enemyCounter += 1;
} else {
Raid._enemyIds = [data.id];
Raid._enemyCounter = 1;
}
});
return index;
},
_monitorEnemyDie: function() {
let index = WG.add_hook("sc", function(data) {
if (data.id == undefined || !Raid._enemyIds) return;
if (WG.inArray(data.id, Raid._enemyIds) && data.hp == 0) {
Raid._enemyCounter -= 1;
}
});
return index;
},
};
var ToRaid = {
menu :function(){
messageClear();
var html = `
<div style='text-align:center;width:100%'>
⛑ 欢迎前往 <a href="https://greasyfork.org/zh-CN/scripts/375851-wsmud-raid/feedback">Greasy Fork</a> 反馈意见和建议。(版本: ${GM_info.script.version})
<div class = "item-commands" >
<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>
</div>
<div class = "item-commands" >
<span class = "zdy-item yihua" style="width:120px"> 移花宫(简单) </span>
<span class = "zdy-item yihuaH" style="width:120px"> 移花宫(困难) </span>
<span class = "zdy-item whiteteam" style="width:120px"> 白驼山(组队) </span>
<span class = "zdy-item yanziwu" style="width:120px"> 燕子坞(简单) </span>
<span class = "zdy-item yanziwuH" style="width:120px"> 燕子坞(困难) </span>
<span class = "zdy-item lunjian" style="width:120px"> 华山论剑<hig>(测试)</hig> </span>
<span class = "zdy-item outMaze" style="width:120px"> 走出桃花林 </span>
<span class = "zdy-item zhoubotong" style="width:120px"> 找到周伯通 </span>
<!--<span class = "zdy-item test" style="width:120px"> 测试专用 </span>-->
</div>
</div> `;
messageAppend(html);
$('#liaoshangInRaid').val(Config.hpThresholdInRaid());
$("#liaoshangInRaid").change(function () {
Config.setHpThresholdInRaid($("#liaoshangInRaid").val());
});
$('#waitSkillCD').val(Config.waitSkillCD());
$("#waitSkillCD").change(function () {
Config.setWaitSkillCD($("#waitSkillCD").val());
});
$(".yihua").on('click',function(){
WG.Send('stopstate');
ToRaid.yihua(false);
});
$(".yihuaH").on('click', function () {
WG.Send('stopstate');
ToRaid.yihua(true);
});
$(".whiteteam").on('click', function () {
WG.Send('stopstate');
ToRaid.baituo();
});
$(".yanziwu").on('click',function(){
WG.Send('stopstate');
ToRaid.yanziwu(false);
});
$(".yanziwuH").on('click', function () {
WG.Send('stopstate');
ToRaid.yanziwu(true);
});
$(".lunjian").on('click', function () {
WG.Send('stopstate');
ToRaid.huashanlunjian();
});
$(".outMaze").on('click', function () {
WG.Send('stopstate');
TaohuaIsland.outMaze();
});
$(".zhoubotong").on('click', function () {
WG.Send('stopstate');
TaohuaIsland.zhoubotong();
});
$(".test").on('click', function () {
// Role.renew(function() {
// alert("Hello, Bob!");
// });
console.log(Role._coolingSkills);
console.log(Role.hasCoolingSkill());
});
},
yihua: function(hard) {
if (hard) {
Raid.name = "移花宫(困难)";
Raid.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",
"go south;go south",
"go south",
"#go southeast",
"go northwest;go southwest",
"look hua",
"go southeast",
"look bed",
"go down",
"fire;go west$",
"look xia;open xia"
];
} else {
Raid.name = "移花宫(简单)";
Raid.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",
"go south;go south",
"go south",
"#go southeast",
"#go northwest;go southwest",
"look hua",
"go southeast",
"look bed",
"go down",
"fire;go west$",
"look xia;open xia"
];
}
Raid.enemyNames = [
"花月奴",
"移花宫女弟子",
"移花宫二宫主 涟星",
"移花宫大宫主 邀月",
"移花宫少宫主 花无缺"
];
Raid.willStartOnceRun = function(number) {
ToRaid.leftPush = 0;
ToRaid.didFindSecretPath = false;
};
Raid.willStartRun = 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];
};
Raid.didFinishRun = function() {
for (var i = ToRaid.indexes.length - 1; i >= 0; i--) {
let index = ToRaid.indexes[i];
WG.remove_hook(index);
}
};
Raid.willExecuteCmd = 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
};
Raid.repeatRun();
},
hardTaohua: function() {
Raid.name = "桃花岛-困难";
Raid.cmds = [
"jh fb 18 start2;cr taohua/haitan 1 0",
"go south",
"@look 1",
"@look 5",
"go south;go south",
"go east;go east",
"#go east;go north$",
"@wait"
];
Raid.enemyNames = [
"桃花岛四弟子 陆乘风",
"桃花岛大弟子 曲灵风",
"<hiy>东邪</hiy> 黄药师"
];
Raid.willStartOnceRun = function(number) {
ToRaid.mazeCoords = [
[2, 2],
[2, 2],
[2, 2],
[2, 2],
[2, 2],
[0, 0],
[2, 2],
[2, 2],
[2, 2],
[2, 2]
];
ToRaid.foundFirst = false;
ToRaid.goCenterCmd = undefined;
ToRaid.paths = undefined;
};
Raid.willStartRun = function() {
let index1 = WG.add_hook(["room", "exits"], function(data) {
if (ToRaid.foundFirst) return;
if (data.type == "room") {
if (data.desc == undefined) return;
let patt = new RegExp("四周栽了大概有一棵桃树");
let result = patt.exec(data.desc);
if (result) ToRaid.atFirst = true;
} else if (data.type == "exits") {
if (data.items == undefined) return;
if (ToRaid.atFirst) {
if (data.items.north && data.items.south) {
if (data.items.west) {
ToRaid.mazeCoords[1] = [1, 0];
ToRaid.goCenterCmd = "go west"
} else {
ToRaid.mazeCoords[1] = [-1, 0];
ToRaid.goCenterCmd = "go east"
}
ToRaid.foundFirst = true;
} else if (data.items.west && data.items.east) {
if (data.items.north) {
ToRaid.mazeCoords[1] = [0, -1];
ToRaid.goCenterCmd = "go north"
} else {
ToRaid.mazeCoords[1] = [0, 1];
ToRaid.goCenterCmd = "go south"
}
ToRaid.foundFirst = true;
}
}
}
});
let index2 = WG.add_hook("room", function(data) {
if (ToRaid.paths) return;
if (data.desc == undefined) return;
let patt = new RegExp("(?<=能看到东南方向大概有).(?=棵桃树)");
let count = patt.exec(data.desc);
if (!count) return;
switch (count.toString()) {
case "二":
ToRaid.mazeCoords[2] = [1, -1]; break;
case "四":
ToRaid.mazeCoords[4] = [1, -1]; break;
case "六":
ToRaid.mazeCoords[6] = [1, -1]; break;
case "八":
ToRaid.mazeCoords[8] = [1, -1]; break;
}
ToRaid.mazeCoords[9] = [-ToRaid.mazeCoords[1][0], -ToRaid.mazeCoords[1][1]];
while (true) {
if (ToRaid.mazeCoords[2][0] != 2) {
ToRaid.mazeCoords[8] = [-ToRaid.mazeCoords[2][0], -ToRaid.mazeCoords[2][1]];
}
if (ToRaid.mazeCoords[8][0] != 2) {
if (ToRaid.mazeCoords[8][0] == ToRaid.mazeCoords[1][0]) {
ToRaid.mazeCoords[6] = [ToRaid.mazeCoords[8][0], -ToRaid.mazeCoords[8][1]];
} else {
ToRaid.mazeCoords[6] = [-ToRaid.mazeCoords[8][0], ToRaid.mazeCoords[8][1]];
}
}
if (ToRaid.mazeCoords[6][0] != 2) {
ToRaid.mazeCoords[4] = [-ToRaid.mazeCoords[6][0], -ToRaid.mazeCoords[6][1]];
}
if (ToRaid.mazeCoords[4][0] != 2) {
if (ToRaid.mazeCoords[4][0] == ToRaid.mazeCoords[9][0]) {
ToRaid.mazeCoords[2] = [ToRaid.mazeCoords[4][0], -ToRaid.mazeCoords[4][1]];
} else {
ToRaid.mazeCoords[2] = [-ToRaid.mazeCoords[4][0], ToRaid.mazeCoords[4][1]];
}
}
if (ToRaid.mazeCoords[2][0] != 2
&& ToRaid.mazeCoords[4][0] != 2
&& ToRaid.mazeCoords[6][0] != 2
&& ToRaid.mazeCoords[8][0] != 2) {
break;
}
}
if (ToRaid.mazeCoords[8][0] == ToRaid.mazeCoords[4][0]) {
ToRaid.mazeCoords[3] = [ToRaid.mazeCoords[8][0], 0];
} else {
ToRaid.mazeCoords[3] = [0, ToRaid.mazeCoords[8][1]];
}
ToRaid.mazeCoords[7] = [-ToRaid.mazeCoords[3][0], -ToRaid.mazeCoords[3][1]];
let pathMap = [
["go southwest", "go west", "go northwest"],
["go south", "", "go north"],
["go southeast", "go east", "go northeast"]
];
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"
};
var paths = "";
for (var i = 2; i <= 9; i++) {
let j = ToRaid.mazeCoords[i][0] + 1;
let k = ToRaid.mazeCoords[i][1] + 1;
let path = pathMap[j][k];
if (i == 9) {
paths += path + ";" + path;
} else {
paths += path + ";" + backMap[path] + ";";
}
}
ToRaid.paths = paths;
});
ToRaid.indexes = [index1, index2];
};
Raid.didFinishRun = function() {
for (var i = ToRaid.indexes.length - 1; i >= 0; i--) {
let index = ToRaid.indexes[i];
WG.remove_hook(index);
}
};
Raid.willExecuteCmd = function(lastCmd, cmd) {
if (cmd == "@look 1") {
if (ToRaid.foundFirst) {
return ToRaid.goCenterCmd;
} else {
return null;
}
}
if (cmd == "@look 5") {
if (ToRaid.paths) {
return ToRaid.paths;
} else {
return null;
}
}
return cmd;
};
Raid.repeatRun();
},
baituo: function() {
Raid.name = "白驼山(组队)";
Raid.cmds = [
"jh fb 19 start3;cr baituo/damen 2 0",
"go north;go north;go north",
"#go north",
"go south;go south;go south;go west;go west;go west",
"go north",
"go north;go north$",
"@wait",
];
Raid.enemyNames = [
"白驼山少庄主 欧阳克",
"白衣少女",
"<hiy>西毒</hiy> 欧阳锋",
"毒蛇",
"蟒蛇"
];
Raid.repeatRun();
},
yanziwu: function(hard) {
if (hard) {
Raid.name = "燕子坞(困难)";
Raid.cmds = ["jh fb 23 start2;cr murong/anbian 1 0"];
} else {
Raid.name = "燕子坞(简单)";
Raid.cmds = ["jh fb 23 start1;cr murong/anbian"];
}
Raid.cmds.push(
"go east;go east",
"go east;go south;go east;go south;go south",
"go north;go north;go west;go north",
"#go east;go east;go east",
"go west;go north",
"look pai;bai pai;bai pai;bai pai",
"go north",
"search",
"#go south$",
"@wait",
);
Raid.enemyNames = [
"金凤庄庄主 包不同",
"曼佗罗山庄庄主 王夫人",
"姑苏慕容公子 慕容复",
"慕容博"
];
Raid.repeatRun();
},
huashanlunjian: function() {
Raid.name = "华山论剑(测试)";
Raid.cmds = [
"jh fb 30 start1;cr huashan/lunjian/leitaixia",
"go up",
"jump bi",
"@get box",
];
Raid.enemyNames = [
"<hiy>东邪</hiy> 黄药师",
"<hiy>南帝</hiy> 一灯大师",
"<hiy>西毒</hiy> 欧阳锋",
"<hiy>北丐</hiy> 洪七公",
"<hiy>中神通</hiy> 王重阳"
];
Raid.willStartOnceRun = function(number) {
ToRaid.remainingBossCount = 5;
};
Raid.willStartRun = function() {
let index = WG.add_hook("itemadd", function(data) {
let corpses = [
"<wht>黄药师的尸体</wht>",
"<wht>一灯大师的尸体</wht>",
"<wht>欧阳锋的尸体</wht>",
"<wht>洪七公的尸体</wht>",
"<wht>王重阳的尸体</wht>"
];
if (data.name != undefined && corpses.indexOf(data.name) != -1) {
ToRaid.remainingBossCount -= 1;
}
});
ToRaid.indexes = [index];
};
Raid.didFinishRun = function() {
for (var i = ToRaid.indexes.length - 1; i >= 0; i--) {
let index = ToRaid.indexes[i];
WG.remove_hook(index);
}
};
Raid.willExecuteCmd = function(lastCmd, cmd) {
if (cmd == "jump bi" && ToRaid.remainingBossCount != 0) return null;
if (cmd == "@get box") WG.get_all();
return cmd;
};
Raid.repeatRun();
}
};
var TaohuaIsland = {
outMaze: function() {
if (!Role.atPath("taohua/haitan")) {
messageAppend("只能在 桃花岛的海滩 才能使用此虫洞。");
return;
}
Executer.interval = 1000;
Executer.cmds = [
"go south",
"@look 1",
"@look 5"
];
Executer.willExecuteCmd = 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;
};
Executer.didFinishExecute = TaohuaIsland._cancelMonitorMaze;
TaohuaIsland._monitorMaze();
Executer.execute();
},
zhoubotong: function() {
if (!Role.atPath("taohua/wofang")) {
messageAppend("只能在 蓉儿的卧室 才能使用此虫洞。");
return;
}
Executer.interval = 1000;
Executer.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 index = 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;
}
});
Executer.willExecuteCmd = 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;
};
Executer.didFinishExecute = function() {
TaohuaIsland._lastCoord = undefined;
TaohuaIsland._lastGo = undefined;
TaohuaIsland._goCave = undefined;
TaohuaIsland._cancelMonitorMaze();
};
TaohuaIsland._monitorMaze();
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;
switch (count.toString()) {
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);
}
},
};
$(document).ready(function () {
WG = unsafeWindow.WG;
messageAppend = unsafeWindow.messageAppend;
messageClear = unsafeWindow.messageClear;
unsafeWindow.ToRaid = ToRaid;
unsafeWindow.Role = Role;
Role.init();
});
})();