";
$("#w_textarea").find("td:last").after(submitbutton).after(voicebutton);
this.switchInputMode();
this.switchAliveFilter();
let _this = this;
$("#toggleButton").on("click", () => {
$("#memoContainer").toggle();
});
$("#importButton").on("click", () => {
this.import();
this.refresh();
});
$("#resetButton").on("click", () => {
if (!window.confirm("ログをすべてリセットします。本当によろしいですか?"))
return false;
this.reset();
this.refresh();
});
$("#reloadButton").on("click", function () {
$("textarea").val("");
document.forms[0].submit();
});
$("div.tab").on("click", function () {
let mode = $(this).data("value");
_this.switchDispArea(mode);
});
$("div.select.filter").on("click", function () {
let mode = $(this).data("value");
_this.switchAliveFilter(mode);
});
$("div.select.inputmode").on("click", function () {
let mode = $(this).data("value");
_this.switchInputMode(mode);
});
$("#toolArea").hover(() => {
$("#toolArea_hid").show();
}, () => {
$("#toolArea_hid").hide();
});
$("textarea").eq(0).focus();
$("div.voice").on("click", function () {
$("select").eq(0).val($(this).data("value"));
$("div.voice").removeClass("voice_selected");
$(this).addClass("voice_selected");
});
$(window).on("keydown", function (e) {
if (e.keyCode == 27) {
$("#memoContainer").hide();
}
});
this.refresh();
}
toggleAutoReload() {
this.isAutoReload = !this.isAutoReload;
this.save();
}
get villageNo() {
return $("title").text().slice(0, 6);
}
load() {
let sdata = localStorage.getItem("memodata");
if (!sdata)
return false;
let memodata = JSON.parse(sdata);
this.isAutoReload = memodata.isAutoReload;
if (memodata.villageNo != this.villageNo)
return false;
this.playerManager.load(memodata.playerInfo);
this.log.load(memodata.discussLog);
if (memodata.filterSetting) {
this.filterSetting = memodata.filterSetting;
}
this.newestImportDay = memodata.newestImportDay || 0;
this.save();
}
save() {
let data = {
villageNo: this.villageNo,
playerInfo: this.playerManager.forSave(),
discussLog: this.log.forSave(),
filterSetting: this.filterSetting,
isAutoReload: this.isAutoReload,
newestImportDay: this.newestImportDay,
};
localStorage.setItem("memodata", JSON.stringify(data));
}
filterLog(no = 99, day = 99) {
if (no < 99) {
$("#discussLogTable tr").hide();
$("tr.systemlog").show();
$("tr.talk_player" + no).show();
}
else {
$("#discussLogTable tr").show();
}
if (day < 99) {
$("#discussLogTable tbody").hide();
$("#log_day" + day).show();
}
else {
$("#discussLogTable tbody").show();
}
}
get today() {
var day = /(\d{1,2})/.exec($("body").html());
return day ? +day[1] - 1 : 0;
}
get newestDay() {
return Math.max(this.today, this.log.list.length - 1);
}
get isDaytime() {
return $("body").attr("bgcolor") != "#000000";
}
get isStart() {
return this.log.list.length >= 2;
}
}
class Player {
constructor(data) {
this.no = data.no || 0;
this.name = data.name || "";
this.vital = data.vital || "alive";
this.job = data.job || "gray";
this.reasoning = data.reasoning || "gray";
this.jobresult = data.jobresult || [];
this.vote = data.vote || [];
this.death = data.death || { reason: null, day: null, cantco: 99 };
}
static wakameteHTMLof(no, html) {
let name = html.split(" ")[0];
let vital = /生存中/.test(html) ? "alive" : "death";
return new Player({
no: no,
name: name,
vital: vital,
});
}
forSave() {
return {
name: this.name,
no: this.no,
vital: this.vital,
job: this.job,
reasoning: this.reasoning,
jobresult: this.jobresult,
vote: this.vote,
deathDetail: this.death,
};
}
updateVital(vital) {
this.vital = vital;
}
setJudge(day, judge) {
this.jobresult.fillundef({ target: 99, judge: "notinput" }, +day);
this.jobresult[day].judge = judge;
}
setTarget(day, target) {
if (!target)
return false;
this.jobresult.fillundef({ target: 99, judge: "notinput" }, +day);
this.jobresult[day].target = target;
}
}
class PlayerManager {
constructor(memo) {
this.list = [];
this.indexOfName = {};
this.memo = memo;
}
reset() {
this.list = [];
this.indexOfName = {};
}
load(data) {
if (!data)
return false;
this.list = [];
this.indexOfName = {};
for (let p of data) {
let player = new Player(p);
this.list.push(player);
this.indexOfName[player.name] = player.no;
}
}
pick(name) {
if (name in this.indexOfName) {
return this.list[this.indexOfName[name]];
}
else {
return null;
}
}
forSave() {
return this.list.map((player) => player.forSave());
}
filter(mode) {
for (var player of this.list) {
if (mode == "All" || player.vital == "alive" || player.job != "gray") {
$("td.player_" + player.no).show();
}
else {
$("td.player_" + player.no).hide();
}
}
}
import() {
this.update();
this.import_vote_wakamete();
this.import_death_wakamete();
}
update() {
switch (this.memo.serverName) {
case "wakamete":
let isStart = this.memo.isStart;
if (isStart) {
this.vitalCheck_wakamete();
}
else {
this.update_wakamete();
}
break;
}
}
no(name) {
if (name in this.indexOfName) {
return this.indexOfName[name];
}
else {
return "";
}
}
vitalCheck_wakamete() {
$("#w_player")
.find("td:odd")
.each((i, v) => {
if (!$(v).html())
return false;
this.list[i].updateVital(/生存中/.test($(v).html()) ? "alive" : "death");
});
}
update_wakamete() {
this.list = [];
this.indexOfName = {};
$("#w_player")
.find("td:odd")
.each((i, v) => {
let html = $(v).html();
if (!html)
return false;
let player = Player.wakameteHTMLof(i, html);
this.list.push(player);
this.indexOfName[player.name] = i;
});
}
import_death_wakamete() {
let deathList = [];
$("#w_discuss")
.find("td[colspan='2']")
.each((i, tr) => {
if (/(で発見|結果処刑|突然死|猫又の呪い)/.test($(tr).text())) {
deathList.push(tr);
}
});
let day = this.memo.today;
let cantco = this.memo.today;
let isdaytime = this.memo.isDaytime;
for (let log of deathList) {
let player = this.pick($(log).find("b").eq(0).text());
let text = $(log).text();
let reason = "";
if (/無残な姿/.test(text))
reason = "bite";
if (/死体で発見/.test(text))
reason = "note";
if (/村民協議の結果|猫又の呪い/.test(text)) {
reason = "exec";
isdaytime ? day-- : cantco++;
}
if (/突然死/.test(text)) {
reason = "sudden";
cantco++;
}
player.death = {
reason: reason,
cantco: cantco,
day: day,
};
}
}
import_vote_wakamete() {
let votelog = [];
$("#w_discuss")
.find("td[colspan='2']")
.each(function (i, v) {
if (/\d{1,2}日目 投票結果。/.test($(v).text())) {
votelog.unshift(v);
}
});
if (!votelog.length)
return false;
let daystr = $(votelog[0])
.text()
.match(/(\d{1,2})日目 投票結果。/);
if (!daystr)
return false;
let day = +daystr[1] - 1;
for (let player of this.list) {
player.vote.fillundef(["-"], day);
player.vote[day].fillundef("-", votelog.length - 1);
}
for (let times = 0; times < votelog.length; times++) {
$(votelog[times])
.find("tr")
.each((i, vote) => {
let voter = this.pick($(vote).find("b").eq(0).text());
let target = $(vote).find("b").eq(1).text();
if (voter)
voter.vote[day][times] = target;
});
}
}
listforSelect() {
let playersList = { 99: "" };
for (let player of this.list) {
playersList[player.no] = player.name;
}
return playersList;
}
refresh() {
this.refreshPlayer();
this.refreshVote();
this.refreshSummary();
}
refreshPlayer() {
let playerInfoTable = $("#playerInfoTable");
playerInfoTable.empty();
if (!this.list.length)
return false;
let playersList = this.listforSelect();
let newestDay = this.memo.newestDay;
let namerow = new Tr("", "namerow");
namerow.add("全ログ");
for (let player of this.list) {
namerow.add(`${player.name}`, `player_${player.no}`);
}
namerow.appendTo(playerInfoTable);
let jobrow = new Tr("", "jobrow");
jobrow.add("CO");
for (let player of this.list) {
let select = createSelectBox(joblist, player.job, {
id: `player_${player.no}_job`,
class: "jobselect",
});
jobrow.add(select, "player_" + player.no);
}
jobrow.appendTo(playerInfoTable);
jobrow = new Tr("", "jobrow");
jobrow.add("推理");
for (let player of this.list) {
let select = createSelectBox(reasoninglist, player.reasoning, {
id: `player_${player.no}_reasoning`,
class: "reasoningselect",
});
jobrow.add(select, "player_" + player.no);
}
playerInfoTable.append(jobrow.text());
for (let day = 1; day <= newestDay; day++) {
let row = new Tr("", "talknumrow");
row.add(`${day + 1}日目`);
for (let player of this.list) {
let no = player.no;
let talknum = this.memo.log.talknum(player.name, day) || "";
row.add(`${talknum}`, `player_${no}`);
}
row.appendTo(playerInfoTable);
}
for (let day = 1; day <= newestDay; day++) {
let resultrow = new Tr("result_" + day, "resultrow");
resultrow.add(`占霊結果 ${day + 1}日目`);
for (let player of this.list) {
if ((player.job == "fortune" && day < player.death.cantco) ||
(player.job == "necro" && day < player.death.cantco && day > 1)) {
let select1 = createSelectBox(playersList, 99, {
id: `target_${player.no}_${day}`,
class: "jobtarget",
});
let select2 = createSelectBox(resultlist, "notinput", {
id: `judge_${player.no}_${day}`,
class: "jobjudge",
});
resultrow.add(select1 + select2, "player_" + player.no);
}
else {
resultrow.add("", "player_" + player.no);
}
}
playerInfoTable.append(resultrow.text());
}
this.refreshJobResult();
this.memo.switchAliveFilter();
this.memo.switchInputMode();
this.coloringGray();
let _this = this;
$("#playerInfoTable a").on("click", function (e) {
let id = $(this).attr("id");
if (!id)
return false;
let no = +id.split("_")[1];
let day = +id.split("_")[2];
_this.memo.filterLog(no, day);
});
$("select.jobselect").on("change", function (e) {
let id = $(this).attr("id");
if (!id)
return false;
let [i, no, day] = id.split("_");
_this.list[+no].job = String($(this).val());
_this.refresh();
_this.refreshJobInitial();
_this.coloring();
_this.memo.save();
});
$("select.reasoningselect").on("change", function (e) {
let id = $(this).attr("id");
if (!id)
return false;
let [i, no, day] = id.split("_");
_this.list[+no].reasoning = String($(this).val());
_this.refreshJobInitial();
_this.coloring();
_this.memo.save();
});
$("select.jobtarget").on("change", function (e) {
let id = $(this).attr("id");
if (!id)
return false;
let no = +id.split("_")[1];
let day = +id.split("_")[2];
let target = +$(this).val();
_this.list[no].setTarget(day, target);
_this.refreshSummary();
_this.coloringGray();
_this.memo.save();
});
$("select.jobjudge").on("change", function (e) {
let id = $(this).attr("id");
if (!id)
return false;
let [i, no, day] = id.split("_");
let judge = String($(this).val());
_this.list[+no].setJudge(+day, judge);
_this.refreshSummary();
_this.coloringGray();
_this.memo.save();
});
}
refreshVote() {
if (!this.list.length)
return false;
let voteTable = $("#voteTable");
let newestDay = this.memo.newestDay;
voteTable.empty();
var tr = new Tr();
tr.add("プレイヤー");
for (var day = 1; day <= newestDay; day++) {
if (!this.list[0].vote[day])
continue;
let colspan = this.list[0].vote[day].length;
tr.add(`${day + 1}日目`, "", colspan);
}
voteTable.append(tr.text());
for (var player of this.list) {
tr = new Tr();
tr.add(player.name);
for (day = 1; day <= newestDay; day++) {
if (!player.vote[day])
continue;
for (let vote of player.vote[day]) {
tr.add(vote);
}
}
voteTable.append(tr.text());
}
}
refreshJobResult() {
let newestDay = this.memo.newestDay;
let fortunes = this.list.filter((p) => p.job == "fortune");
for (let fortune of fortunes) {
for (let day = 1; day < Math.min(fortune.death.cantco, newestDay + 1); day++) {
if (!fortune.jobresult[day])
continue;
$("#target_" + fortune.no + "_" + day).val(fortune.jobresult[day].target);
$("#judge_" + fortune.no + "_" + day).val(fortune.jobresult[day].judge);
}
}
let necros = this.list.filter((p) => p.job == "necro");
for (let necro of necros) {
for (let day = 2; day < Math.min(necro.death.cantco, newestDay + 1); day++) {
let exec = this.list.filter((p) => p.death.day == day - 1 && p.death.reason == "exec");
if (necro.jobresult[day]) {
$("#target_" + necro.no + "_" + day).val(necro.jobresult[day].target);
$("#judge_" + necro.no + "_" + day).val(necro.jobresult[day].judge);
}
else if (exec) {
$("#target_" + necro.no + "_" + day).val(exec[0].no);
}
}
}
}
refreshSummary() {
let summaryTable = $("#summaryTable");
let newestDay = this.memo.newestDay;
summaryTable.empty();
var tr = new Tr();
tr.add("", "", 2);
for (var day = 1; day <= newestDay; day++) {
tr.add("" + (day + 1) + "日目");
}
tr.appendTo(summaryTable);
var fortunes = this.list.filter((p) => p.job == "fortune");
let necros = this.list.filter((p) => p.job == "necro");
let ability = fortunes.concat(necros);
for (let player of ability) {
tr = new Tr();
tr.add(player.job == "fortune" ? "占い師" : "霊能者");
tr.add(player.name);
for (day = 1; day <= newestDay; day++) {
let name = "", judge = "";
if (player.jobresult[day] && player.jobresult[day].target != 99) {
let result = player.jobresult[day];
name = this.list[result.target].name;
judge = resultlist[result.judge];
}
tr.add(name + judge);
}
tr.appendTo(summaryTable);
}
for (var reason in reasonflavor) {
let deaths = this.list.filter((p) => p.death.reason == reason);
if (!deaths.length)
continue;
tr = new Tr();
tr.add(reasonflavor[reason], "", 2);
for (day = 1; day <= newestDay; day++) {
let cn = deaths.filter((p) => p.death.day == day).map((p) => p.name);
let text = cn.length ? cn.join(" ") : "-";
tr.add(text);
}
tr.appendTo(summaryTable);
}
}
refreshJobInitial() {
for (let player of this.list) {
let job = jobinitial[player.reasoning] + jobinitial[player.job];
$("tr.talk_player" + player.no + " span").html(job);
}
}
coloringGray() {
let co = this.list.filter((p) => p.job != "gray").map((p) => p.no);
var fortunes = this.list.filter((p) => p.job == "fortune");
if (this.memo.settingIs("grayregion")) {
fortunes = fortunes.filter((f) => f.reasoning == "gray" || f.reasoning == "real");
}
let fortuned = fortunes.map((f) => f.jobresult.map((r) => +r.target)).flat();
let notgray = co.concat(fortuned);
$("tr.namerow td").removeClass("death").removeClass("gray");
for (var player of this.list) {
if (player.vital == "death") {
$("tr.namerow .player_" + player.no).addClass("death");
}
else if (!notgray.includes(player.no)) {
$("tr.namerow .player_" + player.no).addClass("gray");
}
}
}
coloring() {
if (!this.memo.settingIs("coloringName"))
return false;
$("#w_discuss b").each((i, e) => {
let name = $(e).text();
let player = this.pick(name);
if (player) {
let job = player.job;
let color = this.memo.colorSetting.pick(job);
$(e).removeClass().addClass(color);
}
});
}
}
class Log {
constructor(data) {
this.name = data.name;
this.color = data.color;
this.content = data.content;
}
forSave() {
return {
name: this.name,
color: this.color,
content: this.content,
};
}
}
class LogManager {
constructor(memo) {
this.memo = memo;
this.list = [];
}
reset() {
this.list = [];
}
load(data) {
if (!data)
return false;
this.list = [];
data.forEach((logs) => {
let logofday = [];
logs.forEach((d) => {
let log = new Log(d);
logofday.push(log);
});
this.list.push(logofday);
});
}
forSave() {
let result = [];
this.list.forEach((logs) => {
let l = logs.map((log) => log.forSave());
result.push(l);
});
return result;
}
talknum(name, day) {
if (!this.list[day])
return 0;
return this.list[day].filter((l) => l.name == name).length;
}
import() {
switch (this.memo.serverName) {
case "wakamete":
this.import_wakamete();
break;
}
this.memo.filterLog();
}
import_wakamete() {
this.import_discuss_wakamete();
}
import_discuss_wakamete() {
let today = this.memo.today;
let isDaytime = this.memo.isDaytime;
if (!isDaytime)
return false;
this.list.fillundef([], today);
this.list[today] = [];
$("#w_discuss")
.find("tr")
.each((i, tr) => {
if ($(tr).children().length == 2) {
let name = $(tr).children().eq(0).find("b").eq(0).html();
let content = $(tr).children().eq(1).html();
let namehtml = $(tr).children().eq(0).html();
let color = namehtml.match(/color="(.+?)"/)[1];
let log = new Log({
name: name,
color: color,
content: content,
});
this.list[today].push(log);
}
});
}
refresh() {
let discussLogTable = $("#discussLogTable");
discussLogTable.empty();
if (!this.list.length)
return false;
this.list.forEach((logs, day) => {
if (!logs)
return;
let tbody = $("", { id: "log_day" + day });
let trs = `
${day + 1}日目
`;
for (let log of logs) {
let cl = "talk_player" + this.memo.playerManager.no(log.name);
let name = `◆${log.name}さん`;
if (log.name == "ゲームマスター") {
name = `◆${log.name}`;
}
trs += `