ソース

// ==UserScript==
// @name           bro3_map_tool_TA
// @namespace      http://blog.livedoor.jp/froo/
// @include        http://*.3gokushi.jp/map.php*
// @include        http://*.3gokushi.jp/alliance/info.php*
// @include        http://*.3gokushi.jp/user/*
// @description    ブラウザ三国志 地図ツール by 浮浪プログラマ 改変 by た。
// ==/UserScript==

// 公開ページ: http://blog.livedoor.jp/froo/archives/51365945.html
// 使い方: 全体地図ページ左下「地図ツール」の各リンクをクリック

var VERSION = "2.21T-1.35";
var RADIUS = 25; //半径(中域)
var RADIUS_L = 125; //半径(広域)
var CELL_SIZE_M = 14; //中域地図の1マスサイズ(px)
var CELL_SIZE_L = 3; //広域地図の1マスサイズ(px)
var FONT_SIZE = "10px"; //中域地図のマス内文字サイズ
var HI_POWER = 4; //高☆領地基準
var HI_POPUL = 600; //高人口拠点基準
var MAX_XY = 700; //座標絶対値最大
var DELIMIT = "#$%";
var DELIMIT2 = "&?@";
var NPC_ALLY = "-";

//保存データインデックス(マス)
var IDX_VILLAGE_NAME = 0; //地名
var IDX_USER_NAME = 1; //君主名
var IDX_POPULATION = 2; //人口
var IDX_ALLIANCER = 3; //同盟名
var IDX_POWER = 4; //戦力
var IDX_WOOD = 5; //森
var IDX_STONE = 6; //岩
var IDX_IRON = 7; //鉄
var IDX_RICE = 8; //穀
var IDX_NPC_FLG = 9; //NPCフラグ
var IDX_TIME_BEFORE = 10;
var IDX_USER_BEFORE = 11;
var IDX_ALLY_BEFORE = 12;
var IDX_LAST_UPDATE = 13;
var IDX_CAPITAL_FLG = 14; //本拠地フラグ

//保存データインデックス(同盟)
var IDX_ALLY_PARENT = 0; //親同盟
var IDX_ALLY_CHILDREN = 1; //子同盟リスト
var IDX_ALLY_MEMBERS = 2; //同盟員リスト

//保存データインデックス(君主)
var IDX_USER_VILLAGES = 0; //拠点リスト
var IDX_USER_ALLY = 1; //所属同盟

//地図モード
var MAP_MODE_S = ""; //狭域地図
var MAP_MODE_M = "1"; //中域地図
var MAP_MODE_L = "2"; //広域地図

//入力モード
var INPUT_MODE_NAME = "1"; //名称
var INPUT_MODE_COLOR = "2"; //色

//デフォルト色定義
var USER_COLORS_DEF = new Array("#0000a0", "#a00000", "#00a000", "#808000", 
	"#008080", "#505050", "#505050", "#505050", "#505050", "#505050");
var ALLY_COLORS_DEF = new Array("#a0a0ff", "#ffa0a0", "#a0ffa0", "#ffff80", 
	"#80ffff", "#ff80ff", "#40c0ff", "#ffc040", "#c0ff40", "#b0b0b0");
var NPC_COLOR = "purple";
var ETC_COLOR = "lightgrey";

//CSV出力
var CSV_RADIUS_S = 25; //半径S
var CSV_RADIUS_L = 100; //半径L

//グローバル変数
var USERS; //君主名
var ALLYS; //同盟名
var USER_COLORS; //君主色
var ALLY_COLORS; //同盟色
var CENTER_X; //中心X座標
var CENTER_Y; //中心Y座標
var MY_X = 0; //自拠点X座標
var MY_Y = 0; //自拠点Y座標
var BASE_TIME = ""; //基準時刻
var MAP_MODE = MAP_MODE_S; //地図モード(狭域/中域/広域)
var INPUT_MODE = INPUT_MODE_NAME; //入力モード(名称/色)
var MATCH_FULL = false; //完全一致フラグ
var MAP_SCALE; //地図幅
var LOADED_MAPS = new Array();
var CELLS_CACHE = new Array();
var ALLYS_CACHE = new Array();
var USERS_CACHE = new Array();
var ALLYS_INDEX = new Array();
var USERS_INDEX = new Array();

//マウスドラッグ用
var MOUSE_DRAGGING = false;
var MOUSE_DRAG_START_X;
var MOUSE_DRAG_START_Y;

//main
(function(){
	BASE_TIME = getBaseTime();
	ALLYS_INDEX = GM_getValue(location.hostname + "ALLYS_INDEX", "").split(DELIMIT);
	USERS_INDEX = GM_getValue(location.hostname + "USERS_INDEX", "").split(DELIMIT);
	
	//地図ページ
	if (location.pathname == "/map.php") {
		
		//地図サイズ
		MAP_SCALE = getMapScale();
		
		//中心座標取得
		CENTER_X = parseInt(getParameter("x"));
		if (isNaN(CENTER_X)) CENTER_X = 0;
		CENTER_Y = parseInt(getParameter("y"));
		if (isNaN(CENTER_Y)) CENTER_Y = 0;
		
		//マップモード取得
		MAP_MODE = GM_getValue(location.hostname + "MAP_MODE", "");
		GM_setValue(location.hostname + "MAP_MODE", "");
		
		//自拠点座標取得
		var xy = getMyXY();
		if (xy == "") {
			MY_X = 0;
			MY_Y = 0;
		} else {
			MY_X = parseInt(xy.split(",")[0]);
			MY_Y = parseInt(xy.split(",")[1]);
		}
		
		//名称取得
		USERS = loadNames("USERS");
		ALLYS = loadNames("ALLYS");
		
		//色取得
		USER_COLORS = loadColors("USER_COLORS", USER_COLORS_DEF);
		ALLY_COLORS = loadColors("ALLY_COLORS", ALLY_COLORS_DEF);
		
		//完全一致フラグ
		MATCH_FULL = GM_getValue(location.hostname + "MATCH_FULL", false);
		
		saveMapData();
		window.setTimeout(saveCapital, 0);
		window.setTimeout(saveAllyForMap, 0);
		window.setTimeout(markChangeArea, 0);
		window.setTimeout(defaultTargets, 0);
		window.setTimeout(addMapHtml, 0);
		window.setTimeout(changeMap, 0);
		
	//同盟トップページ
	} else if (location.pathname == "/alliance/info.php") {
		saveAllyForAllyInfo();
		
	//君主プロフィールページ
	} else if (location.pathname == "/user/" || location.pathname == "/user/index.php") {
		saveUserForProf();
	}
	
	window.setTimeout(saveAllysIndex, 0);
	window.setTimeout(saveUsersIndex, 0);
})();

//地図データ保存
function saveMapData() {
	var areas = document.evaluate('//*[@id="mapOverlayMap"]//area/@onmouseover',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	for (var i = 0; i < areas.snapshotLength; i++) {
		rowText = areas.snapshotItem(i).textContent;
		rowText = rowText.replace(/^.*mapInfoView/, "mapInfoViewCustom");
		rowText = rowText.replace(/^.*rewrite/, "mapInfoViewCustom");
		rowText = rowText.replace(/\);.*$/, ");");
		eval(rowText);
	}
}
function mapInfoViewCustom(h,k,g,l,e,c,b,f,j,d,i,a) {
	window.setTimeout(function() {
		var key = location.hostname + l;
		var xy = l.replace(/^\((-?[0-9]+\,-?[0-9]+)\)$/, "$1");
		
		//前セルデータ取得
		var data = loadCellData(key);
		
		//保存データ作成
		data = updateMapCellBefore(data);
		data[IDX_VILLAGE_NAME] = h; //地名
		data[IDX_USER_NAME] = k; //君主名
		data[IDX_POPULATION] = (g=="-") ? "" : g; //人口
		data[IDX_ALLIANCER] = e; //同盟名
		data[IDX_POWER] = c; //戦力
		data[IDX_WOOD] = f; //森
		data[IDX_STONE] = j; //岩
		data[IDX_IRON] = d; //鉄
		data[IDX_RICE] = i; //穀
		data[IDX_NPC_FLG] = a; //NPC拠点
		data[IDX_CAPITAL_FLG] = "";
		
		//Greasemonkey領域に永続保存
		saveCellData(key, data);
		
		//同盟⇔君主→拠点関係性情報更新
		if (data[IDX_USER_NAME] != "") {
			//君主所属同盟情報更新
			updateAllyMember(data[IDX_USER_NAME], data[IDX_ALLIANCER]);
			
			//拠点情報更新
			if (data[IDX_POPULATION] != "" || data[IDX_NPC_FLG] == 1) {
				var userData = getUserDataCache(data[IDX_USER_NAME]);
				if (searchArrayItem(userData[IDX_USER_VILLAGES], xy) < 0) {
					userData[IDX_USER_VILLAGES].push(xy);
					saveUserData(data[IDX_USER_NAME], userData);
				}
			}
		}
	}, 0);
}

//前所有者情報が基準時刻より古かったら更新
function updateMapCellBefore(data) {
	if (data[IDX_TIME_BEFORE] == undefined || 
		data[IDX_TIME_BEFORE] < BASE_TIME) {
		
		data[IDX_TIME_BEFORE] = getCurrentTime2(); //前所有者更新時刻
		data[IDX_USER_BEFORE] = data[IDX_USER_NAME]; //前君主
		data[IDX_ALLY_BEFORE] = data[IDX_ALLIANCER]; //前同盟
	}
	return data;
}

//地図のマスデータを保存
function saveCellData(key, data) {
	
	//初回表示時の変更チェックを回避
	if (data[IDX_USER_BEFORE] == undefined) {
		data[IDX_USER_BEFORE] = data[IDX_USER_NAME];
	}
	if (data[IDX_ALLY_BEFORE] == undefined) {
		data[IDX_ALLY_BEFORE] = data[IDX_ALLIANCER];
	}
	
	//最終更新日時
	data[IDX_LAST_UPDATE] = getCurrentTime();
	
	//Greasemonkey領域に永続保存
	GM_setValue(key, genDelimitString(data, DELIMIT));
//console.log(key + ": " + data);
	CELLS_CACHE[key] = data;
}

//地図のマスデータを読み込み
function loadCellData(key) {
	var data = new Array();
	
	//Greasemonkey領域から取得
	var dataStr = GM_getValue(key);
	if (dataStr != undefined) {
		data = dataStr.split(DELIMIT);
	}
	
	return data;
}

//地図のマスデータのキャッシュを取得
function getCellDataCache(key) {
	if (CELLS_CACHE[key] == undefined) {
		CELLS_CACHE[key] = loadCellData(key);
	}
	return CELLS_CACHE[key];
}

//本拠地フラグ保存
function saveCapital() {
	var myAlly;
	var imgs = document.evaluate('//*[@id="mapsAll"]//img',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	for (var i = 0; i < imgs.snapshotLength; i++) {
		var className = imgs.snapshotItem(i).className;
		var src = imgs.snapshotItem(i).src;
		
		if (!className.match(/mapAll[0-9]+/)) {
			continue;
		}
		
		if (src.match(/capital_[a-z]+_[a-z]+\.png$/)) {
			var xy = getXyFromMapClass(className);
			var key = generateCellKey(xy[0], xy[1]);
			var data = getCellDataCache(key);
			data[IDX_CAPITAL_FLG] = "1";
			saveCellData(key, data);
		}
	}
}

//配下同盟データ保存(全体地図ページ)
function saveAllyForMap() {
	var myAlly;
	var depAllys = new Array(); //自同盟の配下である同盟
	var aloneAllys = new Array(); //自同盟の配下でない同盟
	var imgs = document.evaluate('//*[@id="mapsAll"]//img',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	for (var i = 0; i < imgs.snapshotLength; i++) {
		var className = imgs.snapshotItem(i).className;
		var src = imgs.snapshotItem(i).src;
		
		if (!className.match(/mapAll[0-9]+/)) {
			continue;
		}
		
		if (src.match(/_b_.\.png$/) || src.match(/_g_.\.png$/)) {
			if (myAlly == undefined) {
				myAlly = getAllyFromMapClass(className);
			}
		} else if (src.match(/_bk_.\.png$/)) {
			var allyName = getAllyFromMapClass(className);
			depAllys[allyName] = allyName;
		} else {
			var allyName = getAllyFromMapClass(className);
			aloneAllys[allyName] = allyName;
		}
	}
	
	//Greasemonkey領域に永続保存
	if (myAlly != undefined && myAlly != "") {
		
		//自同盟の配下である同盟
		for (var i in depAllys) {
			updateParentAlly(i, myAlly);
		}
		
		//自同盟の配下でない同盟
		for (var i in aloneAllys) {
			var before = getParentAlly(i);
			
			//かつては自同盟配下だった同盟
			if (before == myAlly) {
				updateParentAlly(i, "");
			}
		}
	}
}

//配下同盟データ保存(同盟情報ページ)
function saveAllyForAllyInfo() {
	
	//「略称」欄取得
	var myAlly = "";
	var myAllyElem = document.evaluate(
		'//*[@id="gray02Wrapper"]//table/tbody/tr[3]/td',
		document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	if (myAllyElem.snapshotLength == 0) return;
	myAlly = myAllyElem.snapshotItem(0).innerHTML;
	
	//「状態」欄取得
	var parentAlly = "";
	var statElem = document.evaluate(
		'//*[@id="gray02Wrapper"]//table/tbody/tr[6]/td',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	
	if (statElem.snapshotItem(0).innerHTML.match(/親同盟/)) {
		var parentAllyElem = document.evaluate(
			'//*[@id="gray02Wrapper"]//table/tbody/tr[6]/td/a',
			document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		if (parentAllyElem.snapshotLength >= 1) {
			parentAlly = parentAllyElem.snapshotItem(0).innerHTML;
		}
	}
	
	//Greasemonkey領域に永続保存
	updateParentAlly(myAlly, parentAlly);
}

//君主領地データ保存(プロフィールページ)
function saveUserForProf() {
	
	//「君主」欄取得
	var user = "";
	var userElem = document.evaluate(
		'//*[@id="gray02Wrapper"]//table/tbody/tr[2]/td[2]',
		document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	user = userElem.snapshotItem(0).innerHTML;
	
	//「同盟」欄取得
	var ally = "";
	var allyElem = document.evaluate(
		'//*[@id="gray02Wrapper"]//table/tbody/tr[3]/td[4]/a',
		document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	ally = allyElem.snapshotItem(0).innerHTML;
	
	//「国情報」欄取得
	var landElems = document.evaluate(
		'//*[@id="gray02Wrapper"]//table/tbody/tr',
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var isLandList =false;
	var villages = new Array();
	for (var i=0; i" + csvSizeS + "x" + csvSizeS + "";
	linkElemCsvS.style.backgroundColor = "black";
	linkElemCsvS.style.padding = "2px 4px";
	linkElemCsvS.style.margin = "2px 2px";
	addElem.appendChild(linkElemCsvS);
	
	//aタグ(CSV出力L)
	var csvSizeL = CSV_RADIUS_L * 2 + 1;
	var linkElemCsvL =  document.createElement("a");
	linkElemCsvL.id = "maptoolCsvL";
	linkElemCsvL.href = "javascript:void(0);";
	linkElemCsvL.innerHTML = "CSV" + 
		"" + csvSizeL + "x" + csvSizeL + "";
	linkElemCsvL.style.backgroundColor = "black";
	linkElemCsvL.style.padding = "2px 4px";
	linkElemCsvL.style.margin = "2px 2px";
	addElem.appendChild(linkElemCsvL);
	
	//aタグ(★データ集計)
	var linkElemStar =  document.createElement("a");
	linkElemStar.id = "maptoolStar";
	linkElemStar.href = "javascript:void(0);";
	linkElemStar.innerHTML = "★集計";
	linkElemStar.style.backgroundColor = "black";
	linkElemStar.style.padding = "2px 4px";
	linkElemStar.style.margin = "2px 2px";
	var linkElemStar2 = document.createElement("span");
	linkElemStar2.style.fontSize = "9px";

	linkElemStar2.innerHTML =<>
	始点x: y: 終点x: y: 
	;
	addElem.appendChild(linkElemStar);
	addElem.appendChild(linkElemStar2);

	
	//イベントリスナー(中域地図)
	linkElem.addEventListener("click",
		function() {
			MAP_MODE = MAP_MODE_M;
			changeMap();
		},
		true);
	
	//イベントリスナー(広域地図)
	linkElem2.addEventListener("click",
		function() {
			MAP_MODE = MAP_MODE_L;
			changeMap();
		},
		true);
	
	//イベントリスナー(CSV出力S)
	linkElemCsvS.addEventListener("click",
		function() {
			outputMapCsvS();
		},
		true);
	
	//イベントリスナー(CSV出力L)
	linkElemCsvL.addEventListener("click",
		function() {
			outputMapCsvL();
		},
		true);

	//イベントリスナー(★集計)
	linkElemStar.addEventListener("click",
		function() {
			outputStarData();
		},
		true);
}

//ヘッダ部HTML追加
function addHeadHtml(parentElem) {
	var addElem = document.createElement("div");
	parentElem.appendChild(addElem);
	
	addElem.id = "maptoolHead";
	addElem.style.margin = "2px 2px";
	addElem.innerHTML = <>
		
狭域 入力モード 名称 完全一致
君主 NPC その他
同盟
移動 移動速度   スキルによる移動上昇 %(半角入力)  強襲
; //バージョン document.getElementById("version").innerHTML = "Ver." + VERSION; //基準時刻 var baseTime = BASE_TIME; if (baseTime.length == 8) baseTime += "000000"; document.getElementById("base_time").innerHTML = baseTime.substr(4, 2) + "/" + baseTime.substr(6, 2) + " " + baseTime.substr(8, 2) + ":" + baseTime.substr(10, 2); //完全一致 document.getElementById("maptoolMatchFull").checked = MATCH_FULL; //項目背景着色 setFieldColors(); //君主、同盟を表示 setInputNames(); //移動速度イベントリスナー document.getElementById('move1').addEventListener("change", function() { //地図変更 LOADED_MAPS = new Array(); changeMap(); }, true); document.getElementById('move2').addEventListener("change", function() { //地図変更 LOADED_MAPS = new Array(); changeMap(); }, true); document.getElementById('move3').addEventListener("change", function() { //地図変更 LOADED_MAPS = new Array(); changeMap(); }, true); //イベントリスナー登録(保存ボタン) document.getElementById('maptoolSave').addEventListener("click", function() { //入力値をGreasemonkey領域に保存 if (INPUT_MODE == INPUT_MODE_NAME) { saveInputUsers("USERS"); saveInputAllys("ALLYS"); USERS = loadNames("USERS"); ALLYS = loadNames("ALLYS"); defaultTargets(); setInputNames(); } else if (INPUT_MODE == INPUT_MODE_COLOR) { saveInputUsers("USER_COLORS"); saveInputAllys("ALLY_COLORS"); USER_COLORS = loadColors("USER_COLORS", USER_COLORS_DEF); ALLY_COLORS = loadColors("ALLY_COLORS", ALLY_COLORS_DEF); setInputColors(); setFieldColors(); } //地図変更 LOADED_MAPS = new Array(); changeMap(); }, true); //イベントリスナー登録(基準時更新ボタン) document.getElementById('maptoolTime').addEventListener("click", function() { //基準時間として現在時刻をGreasemonkey領域に保存 GM_setValue(location.hostname + "BASE_TIME", getCurrentTime2()); //ページリロード GM_setValue(location.hostname + "MAP_MODE", MAP_MODE); location.reload(); }, true); //イベントリスナー登録(狭域地図リンク) document.getElementById('maptoolClose').addEventListener("click", function() { MAP_MODE = MAP_MODE_S; changeMap(); }, true); //イベントリスナー登録(中域/広域地図リンク) document.getElementById('maptoolSwitch').addEventListener("click", function() { MAP_MODE = (MAP_MODE == MAP_MODE_L ? MAP_MODE_M : MAP_MODE_L); changeMap(); }, true); //イベントリスナー登録(←↑↓→リンク) document.getElementById('maptoolMoveLeft').addEventListener("click", function() { shiftMap(-1, 0); }, true); document.getElementById('maptoolMoveUp').addEventListener("click", function() { shiftMap(0, 1); }, true); document.getElementById('maptoolMoveDown').addEventListener("click", function() { shiftMap(0, -1); }, true); document.getElementById('maptoolMoveRight').addEventListener("click", function() { shiftMap(1, 0); }, true); //イベントリスナー登録(名称設定・色設定) document.getElementById('maptoolModeName').addEventListener("click", function() { setInputNames(); }, true); document.getElementById('maptoolModeColor').addEventListener("click", function() { setInputColors(); }, true); //イベントリスナー登録(完全一致チェックボックス) document.getElementById('maptoolMatchFull').addEventListener("click", function() { changeMatchMode(this.checked); }, true); } //本体部HTML追加 function addBodyHtml(parentElem) { //中域地図div var addElem = document.createElement("div"); parentElem.appendChild(addElem); addElem.id = "maptoolBody"; addElem.style.display = "none"; //広域地図div var addElem2 = document.createElement("div"); parentElem.appendChild(addElem2); addElem2.id = "maptoolBodyL"; addElem2.style.display = "none"; //中域/広域地図ドラッグ&ドロップイベントリスナー var elems = new Array(); elems.push(addElem); elems.push(addElem2); for (var i=0; i 5) { var cellSize; if (MAP_MODE == MAP_MODE_M) cellSize = CELL_SIZE_M; else if (MAP_MODE == MAP_MODE_L) cellSize = CELL_SIZE_L; if (cellSize != undefined) { moveMap(CENTER_X - Math.round(offsetX / cellSize), CENTER_Y + Math.round(offsetY / cellSize)); } } event.preventDefault(); }, false); } } //地図(中域)本体部HTML生成 function genBodyHtml() { var bodyHtml = ""; bodyHtml += "\n"; //各マス作成 for (var y=CENTER_Y+RADIUS; y>=CENTER_Y-RADIUS; y--) { bodyHtml += "\n"; for (var x=CENTER_X-RADIUS; x<=CENTER_X+RADIUS; x++) { bodyHtml += generateMapCellHtml(x, y); } bodyHtml += "\n"; } bodyHtml += "
\n"; return bodyHtml; } //地図(広域)本体部HTML生成 function genBodyHtmlL() { var bodyHtml = ""; var width = (RADIUS_L * 2 + 1) * CELL_SIZE_L; bodyHtml += "
\r\n"; //中心線 bodyHtml += "
"; bodyHtml += "
"; //同盟単位 for (var i = ALLYS.length - 1; i >= 0; i--) { var allySub = ALLYS[i]; if (allySub == "") { continue; } //名称が部分一致する同盟が対象 var matchAllys = searchArrayString(ALLYS_INDEX, allySub); for (var j=0; j= 0; i--) { var userSub = USERS[i]; if (userSub == "") { continue; } //名称が部分一致する君主が対象 var matchUsers = searchArrayString(USERS_INDEX, userSub); for (var j=0; j CENTER_X+RADIUS_L) return ""; if (y < CENTER_Y-RADIUS_L || y > CENTER_Y+RADIUS_L) return ""; //マスデータ取得 var data = loadCellData(generateCellKey(x, y)); //既に拠点がない場合はスキップ if ((data[IDX_POPULATION] == undefined || data[IDX_POPULATION] == "" || data[IDX_USER_NAME] != user) && data[IDX_ALLIANCER] != NPC_ALLY) { return ""; } //四角形のサイズを決定 var size; if (data[IDX_NPC_FLG] == "1") { if (data[IDX_POWER].length <= 3) size = 3; else if (data[IDX_POWER].length <= 6) size = 4; else size = 5; } else { var population = parseInt(data[IDX_POPULATION]); if (population < 100) size = 1; else if (population < 250) size = 2; else if (population < 600) size = 3; else if (population < 1000) size = 4; else size = 5; } var borderWidth = 1; var width = (size + 1) * 2 + 1 - borderWidth * 2; var left = (x - (CENTER_X - RADIUS_L)) * CELL_SIZE_L - (width-CELL_SIZE_L)/2; var top = ((CENTER_Y + RADIUS_L) - y) * CELL_SIZE_L - (width-CELL_SIZE_L)/2; var zIndex = priority * 10 + (9 - size); var popupText = genPopupText(data, x, y); var ret = "" + "
" + "
"; return ret; } //説明ポップアップ初期化 function initPopup() { //CSS addGlobalStyle( ".popup{"+ "position:absolute; left:0px; top:0px; visibility:hidden; "+ "font-size:9pt; color:#0099FF; "+ "background-color:#FFFFFF; layer-background-color:#FFFFFF; "+ "border:1px solid #0099FF; padding:5; z-index:255;"+ "}" ); //表示関数 var funcHTML = 'function onPopup(text, nX, nY) {\n'+ 'var sX = -10, sY = 24;\n'+ 'var msgElem = document.getElementById("popup");\n'+ 'msgElem.innerHTML = text;\n'+ 'msgElem.style.visibility = "visible";\n'+ 'msgElem.style.left = (nX + sX) + "px";\n'+ 'msgElem.style.top = (nY + sY) + "px";\n'+ '}\n'+ 'function offPopup() {\n'+ 'document.getElementById("popup").style.visibility = "hidden";\n'+ '}\n'; var scriptElem = document.createElement("script"); scriptElem.type = "text/javascript"; scriptElem.innerHTML = funcHTML; document.getElementsByTagName("head")[0].appendChild(scriptElem); //HTMLタグ追加 var popupElem = document.createElement('span'); popupElem.id = "popup"; popupElem.className = "popup"; var mapElem = document.evaluate('//*[@id="maptool"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); mapElem.snapshotItem(0).appendChild(popupElem); //イベントリスナー登録 popupElem.addEventListener("mouseover", function() { this.style.visibility = "hidden" }, true); } //所有者が変わった領地に印 function markChangeArea() { var markHtml = ""; var mapElem = document.evaluate('//*[@id="mapsAll"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0); var baseX = CENTER_X - Math.floor((MAP_SCALE-1)/2); var baseY = CENTER_Y + Math.floor((MAP_SCALE-1)/2); for (var x = baseX; x <= baseX + MAP_SCALE - 1; x++) { for (var y = baseY; y >= baseY - MAP_SCALE + 1; y--) { //保存データ取得 var data = getCellDataCache(generateCellKey(x, y)); var userBefore = data[IDX_USER_BEFORE]; var userAfter = data[IDX_USER_NAME]; if (userBefore == userAfter) { continue; } //チェック画像 var areaNo = (x - baseX) * MAP_SCALE + (baseY - y) + 1; var addElem = document.createElement("img"); addElem.className = "mapAll" + padZero(areaNo); addElem.alt = "change"; addElem.src = "data:image/gif;base64,"+ "R0lGODlhPAA8AHcAMSH+GlNvZnR3YXJlOiBNaWNyb3NvZnQgT2ZmaWNlACH5BAEAAAAALBMAHgAZ"+ "ABQAgAAAAP4AAAIyhI+ZwayPmoRUOvpswFDzbH2KJy5TGZ2oQa5AyF0HjKltddK1pn58s/q5eC5W"+ "byhDFQAAOw=="; mapElem.appendChild(addElem); } } } //地図幅の取得 function getMapScale() { var sort15 = document.evaluate('//*[@id="changemapscale"]/ul/li[@class="sort15 now"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); if (sort15.snapshotLength != 0) { return 15; } var sort20 = document.evaluate('//*[@id="changemapscale"]/ul/li[@class="sort20 now"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); if (sort20.snapshotLength != 0) { return 20; } return 11; } //君主、同盟の指定がない場合は中心座標の君主をデフォルト function defaultTargets() { if (USERS[0] != "" || ALLYS[0] != "") { return; } var data = getCellDataCache(generateCellKey(CENTER_X, CENTER_Y)); if (data.length > 0) { USERS[0] = data[IDX_USER_NAME]; ALLYS[0] = data[IDX_ALLIANCER]; } } //名称入力欄設定 function setInputNames() { INPUT_MODE = INPUT_MODE_NAME; setInputLink("maptoolModeName"); setInputs(USERS, ALLYS, ""); } //色入力欄設定 function setInputColors() { INPUT_MODE = INPUT_MODE_COLOR; setInputLink("maptoolModeColor"); setInputs(USER_COLORS, ALLY_COLORS, "monospace"); } //リンク背景色設定 function setInputLink(id) { var linkIds = new Array("maptoolModeName", "maptoolModeColor"); for (var i = 0; i < linkIds.length; i++) { var elem = document.getElementById(linkIds[i]); if (linkIds[i] == id) { elem.style.backgroundColor = "dimgray"; } else { elem.style.backgroundColor = ""; } } } //入力欄設定 function setInputs(users, allys, fontFamily) { //各テキストボックスを初期化 for (var i = 0; i < USER_COLORS.length; i++) { var field = document.getElementById("user" + (i+1)); field.value = ""; field.style.fontFamily = fontFamily; } for (var i = 0; i < ALLY_COLORS.length; i++) { var field = document.getElementById("ally" + (i+1)); field.value = ""; field.style.fontFamily = fontFamily; } //各テキストボックスに設定 for (var i = 0; i < users.length; i++) { document.getElementById("user" + (i+1)).value = users[i]; } for (var i = 0; i < allys.length; i++) { document.getElementById("ally" + (i+1)).value = allys[i]; } } //入力欄背景色設定 function setFieldColors() { for (var i = 0; i < USER_COLORS.length; i++) { document.getElementById("fld_user" + (i+1)).style.backgroundColor = USER_COLORS[i]; } for (var i = 0; i < ALLY_COLORS.length; i++) { document.getElementById("fld_ally" + (i+1)).style.backgroundColor = ALLY_COLORS[i]; } } //地図1マス生成 function generateMapCellHtml(x, y) { var cellHtml = ""; //保存データ取得 var data = loadCellData(generateCellKey(x, y)); var user = data[IDX_USER_NAME]; var population = data[IDX_POPULATION]; var ally = data[IDX_ALLIANCER]; var power = data[IDX_POWER]; var npcFlg = data[IDX_NPC_FLG]; var capitalFlg = data[IDX_CAPITAL_FLG]; var timeBefore = data[IDX_TIME_BEFORE]; var userBefore = data[IDX_USER_BEFORE]; var parentAlly = getParentAlly(ally); //背景色 var bgColor; var reverse = false; if (user == undefined) { bgColor = "gray"; } else if (user == "") { bgColor = "white"; } else if (ally == NPC_ALLY) { bgColor = NPC_COLOR; reverse = true; } if (bgColor == undefined) { for (var i=0; i= BASE_TIME); //所有者変更有無チェック var isDiff = (userBefore != user && isNewData); //ポップアップ内容 var popupText = genPopupText(data, x, y); //データが古いマスに目印 var borderStyle = ""; if (!isNewData) { if (reverse) { borderStyle = "border: solid lightgrey 1px;"; } else { borderStyle = "border: solid gray 1px;" } } //中心マスに目印 if (x==CENTER_X && y==CENTER_Y) { var borderColor; if (reverse) borderColor = "black"; else borderColor = "black"; borderStyle = "border: solid "+borderColor+" 2px;"; } //☆多領地、人口多拠点を強調 var hiPowerStyle, textColor; if ((power != undefined && power.length >= HI_POWER) || (population != undefined && parseInt(population) > HI_POPUL)) { hiPowerStyle = "font-weight:bold;"; if (reverse) textColor = "white"; else textColor = "black"; } else { hiPowerStyle = ""; if (reverse) textColor = "lightgray"; else textColor = "dimgray"; } //配下同盟表示 var anchorStyle = ""; if (ally != "" && parentAlly != "" && !reverse) { anchorStyle += "background-color:whitesmoke;"; } //本拠地表示 if (capitalFlg == "1") { anchorStyle += "border:dotted 1px " + textColor + ";"; } //所有者変更表示 if (isDiff) { if (reverse) textColor = "pink"; else textColor = "red"; } //tdタグ cellHtml += ""; //座標リンク cellHtml += ""; "onMouseOver='onPopup(\"" + popupText + "\", event.pageX, event.pageY)' " + "onMouseOut='offPopup()'>"; //☆数(領地) 、「P」(PC)、「N」(NPC) if (data.length == 0) cellHtml += " "; else if (npcFlg == "1") cellHtml += "N"; else if (population != "") cellHtml += "P"; else if (power == "") cellHtml += "?"; else cellHtml += power.length; cellHtml += ""; cellHtml += "\n"; return cellHtml; } //ポップアップテキスト生成 function genPopupText(data, x, y) { var village = data[IDX_VILLAGE_NAME]; var user = data[IDX_USER_NAME]; var population = data[IDX_POPULATION]; var ally = data[IDX_ALLIANCER]; var power = data[IDX_POWER]; var material = "森"+data[IDX_WOOD] + " 岩"+data[IDX_STONE] + " 鉄"+data[IDX_IRON] + " 穀"+data[IDX_RICE]; var npcFlg = data[IDX_NPC_FLG]; var userBefore = data[IDX_USER_BEFORE]; var allyBefore = data[IDX_ALLY_BEFORE]; var lastUpdate = data[IDX_LAST_UPDATE]; var parentAlly = getParentAlly(ally); //自拠点からの距離 var distance = -1; if (MY_X != 0 && MY_Y != 0) { distance = Math.sqrt((MY_X-x)*(MY_X-x)+(MY_Y-y)*(MY_Y-y)); distance = Math.round(distance * 100) / 100; } //予測兵数 if(power != undefined && power != ""){ var powerRate = power.length; var catArray = new Array(4); for(i = 0; i < 4; i++) { catArray[i] = new Array(); } catArray[0]= ["森",data[IDX_WOOD]]; catArray[1]= ["岩",data[IDX_STONE]]; catArray[2]= ["鉄",data[IDX_IRON]]; catArray[3]= ["穀",data[IDX_RICE]]; catArray.sort(function(a,b){ return((a[1]-b[1])*(-1)); }); var soldier=new Array(7); var maxSoldier = 0; var minSoldier = 0; for(i = 0; i < 7; i++) { soldier[i] = 0; } if (powerRate == 1){ soldier[0] = Math.ceil(distance*1.5+15); }else if (powerRate == 2){ minSoldier = Math.ceil(distance*0.15+1.5); maxSoldier = Math.ceil(distance*1.2+12); for(i = 1; i < 4; i++) { soldier[i] = minSoldier; } if (catArray[0][0] == "森"){ soldier[2] = maxSoldier; }else if (catArray[0][0] == "岩"){ soldier[1] = maxSoldier; }else if (catArray[0][0] == "鉄"){ soldier[3] = maxSoldier; } }else if (powerRate == 3){ maxSoldier = Math.ceil(distance*1.8+18); soldier[1] = maxSoldier; soldier[2] = maxSoldier; soldier[3] = maxSoldier; }else if (powerRate == 4){ if (data[IDX_RICE] == 2){ maxSoldier = Math.ceil(distance*3.75+37.5); }else{ maxSoldier = Math.ceil(distance*3.3+33); } minSoldier = Math.ceil(maxSoldier*0.6); soldier[1] = maxSoldier+"~"+minSoldier; soldier[2] = maxSoldier+"~"+minSoldier; soldier[3] = maxSoldier+"~"+minSoldier; }else if (powerRate == 5){ minSoldier = Math.ceil(distance*3+30); maxSoldier = Math.ceil(distance*12+120); for(i = 1; i < 4; i++) { soldier[i] = minSoldier; } if (catArray[0][0] == "森"){ soldier[2] = maxSoldier; }else if (catArray[0][0] == "岩"){ soldier[1] = maxSoldier; }else if (catArray[0][0] == "鉄"){ soldier[3] = maxSoldier; } }else if (powerRate == 6){ minSoldier = Math.ceil(distance*4.5+45); maxSoldier = Math.ceil(distance*22.5+225); for(i = 1; i < 4; i++) { soldier[i] = minSoldier; } if (catArray[0][0] == "森"){ soldier[1] = maxSoldier; }else if (catArray[0][0] == "岩"){ soldier[2] = maxSoldier; }else if (catArray[0][0] == "鉄"){ soldier[3] = maxSoldier; } }else if (powerRate == 7){ maxSoldier = Math.ceil(distance*15+150); minSoldier = Math.ceil(maxSoldier*0.6); for(i = 4; i < 7; i++) { soldier[i] = maxSoldier+"~"+minSoldier; } }else if (powerRate == 8){ maxSoldier = Math.ceil(distance*30+300); minSoldier = Math.ceil(maxSoldier*0.6); for(i = 4; i < 7; i++) { soldier[i] = maxSoldier+"~"+minSoldier; } }else if (powerRate == 9){ maxSoldier = Math.ceil(distance*45+450); minSoldier = Math.ceil(maxSoldier*0.6); for(i = 4; i < 7; i++) { soldier[i] = maxSoldier+"~"+minSoldier; } } material += "
" + "剣" + soldier[0] + " 槍" + soldier[1] + " 弓" + soldier[2] + " 騎" + soldier[3] + " 矛" + soldier[4] + " 弩" + soldier[5] + " 近" + soldier[6] ; } //移動時間 var moveTime = 0; var moveRate = document.getElementById("move1").value; var moveSkillHosei = document.getElementById("move2").value; var moveSkill = 100 + parseFloat(moveSkillHosei); var kyoshuChk = document.getElementById("move3").value; if(document.getElementById("move3").checked){ moveSkill += 20; } moveSkill = moveSkill/100 moveTime = distance * 3600; moveTime = Math.floor(moveTime/(moveRate*moveSkill)); moveTime = Math.floor(moveTime/3600)+":"+Math.floor(moveTime%3600/60)+":"+Math.floor(moveTime%60); //[地名]([座標])/[[距離]] if (village == undefined) village = "不明"; var popupText = ""; popupText += village; popupText += "(" + x + "," + y + ")" if (distance >= 0) { popupText += " / " popupText += "[" + distance + "]" } popupText += "
"; popupText += "移動時間:"+moveTime; popupText += "
"; //[君主名]@[同盟名]@[親同盟]([前君主名]@[同盟名]) var exists = false; if (user != undefined && user != "") { popupText += user + "@" + ally; if (parentAlly != "") popupText += "@" + parentAlly; exists = true; } if (userBefore != user && userBefore != undefined && userBefore != "") { popupText += "(" + userBefore + "@" + allyBefore + ")"; exists = true; } if (exists) { popupText += "
"; } //NPC戦力 if (npcFlg == "1") { popupText += power + "
"; //資源 } else if (power != undefined && power != "" && npcFlg != "1") { popupText += material + "
"; //人口 } else if (population != undefined && population != "") { popupText += "人" + population + "
"; } //最終更新日時 if (lastUpdate != undefined) { var dateText = lastUpdate; dateText = dateText.replace(/^[0-9]{4}\//, ""); dateText = dateText.replace(/:[0-9]{2}$/, ""); popupText += dateText; } return popupText; } //地図切り替え function changeMap() { //現在の表示を消去 if (MAP_MODE != MAP_MODE_S) { document.getElementById("mapAll").style.display = "none"; document.getElementById("maptoolLink").style.display = "none"; } else { document.getElementById("maptoolHead").style.display = "none"; } if (MAP_MODE != MAP_MODE_M) { document.getElementById("maptoolBody").style.display = "none"; } if (MAP_MODE != MAP_MODE_L) { document.getElementById("maptoolBodyL").style.display = "none"; } //地図ツール共通部表示 if (MAP_MODE != MAP_MODE_S) { document.getElementById("maptoolHead").style.display = "block"; var switchName; if (MAP_MODE == MAP_MODE_M) switchName = "広域"; if (MAP_MODE == MAP_MODE_L) switchName = "中域"; document.getElementById("maptoolSwitch").innerHTML = switchName; if (MAP_MODE == MAP_MODE_L) { document.getElementById("maptoolTime").disabled = true; } else { document.getElementById("maptoolTime").disabled = false; } } //時間がかかるので別スレッド化(一旦描画して砂時計を表示させる) setWaitCursor(); window.setTimeout(function() { //地図ツール個別部表示 if (MAP_MODE == MAP_MODE_M) { //中域地図 document.getElementById("maptoolBody").style.display = "block"; } else if (MAP_MODE == MAP_MODE_L) { //広域地図 document.getElementById("maptoolBodyL").style.display = "block"; } else { //狭域地図 var x = parseInt(getParameter("x")); if (isNaN(x)) x = 0; var y = parseInt(getParameter("y")); if (isNaN(y)) y = 0; if (x == CENTER_X && y == CENTER_Y) { document.getElementById("mapAll").style.display = "block"; document.getElementById("maptoolLink").style.display = "block"; window.scroll(0,0); } else { //ページリロード GM_setValue(location.hostname + "MAP_MODE", MAP_MODE); location.href = getMapUrl(CENTER_X, CENTER_Y); } } //未表示の場合はHTML生成 if (LOADED_MAPS[MAP_MODE] != "1") { //console.log((new Date()).getTime()); if (MAP_MODE == MAP_MODE_M) { document.getElementById("maptoolBody").innerHTML = genBodyHtml(); } else if (MAP_MODE == MAP_MODE_L) { document.getElementById("maptoolBodyL").innerHTML = genBodyHtmlL(); } //console.log((new Date()).getTime()); LOADED_MAPS[MAP_MODE] = "1"; } resetCursor(); }, 0); } //同盟データ読み込み function loadAllyData(ally) { var ret = new Array(); var src = GM_getValue(generateAllyKey(ally), ""); var array1 = src.split(DELIMIT); ret[IDX_ALLY_PARENT] = array1[IDX_ALLY_PARENT]; if (ret[IDX_ALLY_PARENT] == undefined) ret[IDX_ALLY_PARENT] = ""; var chiliren = new Array(); if (array1[IDX_ALLY_CHILDREN] != undefined && array1[IDX_ALLY_CHILDREN] != "") { chiliren = array1[IDX_ALLY_CHILDREN].split(DELIMIT2); } ret[IDX_ALLY_CHILDREN] = chiliren; var members = new Array(); if (array1[IDX_ALLY_MEMBERS] != undefined && array1[IDX_ALLY_MEMBERS] != "") { members = array1[IDX_ALLY_MEMBERS].split(DELIMIT2); } ret[IDX_ALLY_MEMBERS] = members; return ret; } //同盟データ保存 function saveAllyData(ally, data) { var dataArray = new Array(); dataArray[IDX_ALLY_PARENT] = data[IDX_ALLY_PARENT]; dataArray[IDX_ALLY_CHILDREN] = genDelimitString(data[IDX_ALLY_CHILDREN], DELIMIT2); dataArray[IDX_ALLY_MEMBERS] = genDelimitString(data[IDX_ALLY_MEMBERS], DELIMIT2); GM_setValue(generateAllyKey(ally), genDelimitString(dataArray, DELIMIT)); //console.log(generateAllyKey(ally) +":"+ genDelimitString(dataArray, DELIMIT)); ALLYS_CACHE[ally] = data; if (searchArrayItem(ALLYS_INDEX, ally) < 0) { ALLYS_INDEX.push(ally); } } //同盟データキャッシュ取得 function getAllyDataCache(ally) { if (ALLYS_CACHE[ally] == undefined) { ALLYS_CACHE[ally] = loadAllyData(ally); } return ALLYS_CACHE[ally]; } //親同盟取得 function getParentAlly(ally) { parentAlly = getAllyDataCache(ally)[IDX_ALLY_PARENT]; if (parentAlly == undefined) { parentAlly = ""; } return parentAlly; } //親同盟更新 function updateParentAlly(child, parent) { var childData = getAllyDataCache(child); var beforeParent = childData[IDX_ALLY_PARENT]; //子同盟のデータを更新 childData[IDX_ALLY_PARENT] = parent; saveAllyData(child, childData); //親同盟の子同盟リストに追加 if (parent != "") { //TODO } //親同盟が変わった場合、元親の子同盟リストから削除 if (beforeParent != "" && beforeParent != parent) { //TODO } } //同盟所属君主のデータを更新 function updateAllyMember(user, ally) { //所属同盟のデータを更新 { var afterAllyData = getAllyDataCache(ally); var members = afterAllyData[IDX_ALLY_MEMBERS]; if (searchArrayItem(members, user) < 0) { members.push(user); afterAllyData[IDX_ALLY_MEMBERS] = members; saveAllyData(ally, afterAllyData); } } //君主データの同盟情報を取得 var userData = getUserDataCache(user); var beforeAlly = userData[IDX_USER_ALLY]; //君主データがなかったら作成 if (beforeAlly == "") { userData[IDX_USER_ALLY] = ally; saveUserData(user, userData); //君主の所属同盟が変化した場合 } else if (beforeAlly != ally) { //同盟データの所属君主情報を更新 var beforeAllyData = getAllyDataCache(beforeAlly); var members = beforeAllyData[IDX_ALLY_MEMBERS]; var itemIdx = searchArrayItem(members, user); if (itemIdx >= 0) { members.splice(itemIdx, 1); beforeAllyData[IDX_ALLY_MEMBERS] = members; saveAllyData(beforeAlly, beforeAllyData); } //君主データの同盟情報を更新 userData[IDX_USER_ALLY] = ally; saveUserData(user, userData); } } //君主データ読み込み function loadUserData(user) { var ret = new Array(); var src = GM_getValue(generateUserKey(user), ""); var array1 = src.split(DELIMIT); var villages = new Array(); if (array1[IDX_USER_VILLAGES] != undefined && array1[IDX_USER_VILLAGES] != "") { villages = array1[IDX_USER_VILLAGES].split("|"); } ret[IDX_USER_VILLAGES] = villages; ret[IDX_USER_ALLY] = array1[IDX_USER_ALLY]; if (ret[IDX_USER_ALLY] == undefined) ret[IDX_USER_ALLY] = ""; return ret; } //君主データ保存 function saveUserData(user, data) { var dataArray = new Array(); dataArray[IDX_USER_VILLAGES] = genDelimitString(data[IDX_USER_VILLAGES], "|"); dataArray[IDX_USER_ALLY] = data[IDX_USER_ALLY]; GM_setValue(generateUserKey(user), genDelimitString(dataArray, DELIMIT)); //console.log(generateUserKey(user) + ": " + genDelimitString(dataArray, DELIMIT)); USERS_CACHE[user] = data; if (searchArrayItem(USERS_INDEX, user) < 0) { USERS_INDEX.push(user); } } //君主データキャッシュ取得 function getUserDataCache(user) { if (USERS_CACHE[user] == undefined) { USERS_CACHE[user] = loadUserData(user); } return USERS_CACHE[user]; } //検索用索引保存 function saveAllysIndex() { GM_setValue(location.hostname + "ALLYS_INDEX", genDelimitString(ALLYS_INDEX, DELIMIT)); } function saveUsersIndex() { GM_setValue(location.hostname + "USERS_INDEX", genDelimitString(USERS_INDEX, DELIMIT)); } //完全一致/部分一致変更 function changeMatchMode(checked) { GM_setValue(location.hostname + "MATCH_FULL", checked); //console.log(location.hostname + "MATCH_FULL: " + checked); MATCH_FULL = checked; //地図変更 LOADED_MAPS = new Array(); changeMap(); } //名称定義読み込み function loadNames(key) { var result = GM_getValue(location.hostname + key, "").split(DELIMIT); return result; } //色定義読み込み function loadColors(key, defaults) { var result = new Array(); var inputs = GM_getValue(location.hostname + key, "").split(DELIMIT) for (var i = 0; i < defaults.length; i++) { if (inputs[i] == undefined || inputs[i] == "") { result[i] = defaults[i]; } else { result[i] = inputs[i]; } } return result; } //入力値を保存 function saveInputAllys(key) { saveInputValues(key, ALLY_COLORS.length, "ally"); } function saveInputUsers(key) { saveInputValues(key, USER_COLORS.length, "user"); } function saveInputValues(key, length, id) { var newAllys = new Array(); //テキストボックスから入力値を取得 for (var i = 0; i < length; i++) { newAllys[i] = trim(document.getElementById(id + (i+1)).value); } //Greasemonkey領域に永続保存 trimArray(newAllys); GM_setValue(location.hostname + key, genDelimitString(newAllys, DELIMIT)); //console.log(location.hostname + key + ":" + genDelimitString(newAllys, DELIMIT)); } //配列空項目削除 function trimArray(ary) { for (var i = ary.length - 1; i >= 0; i--) { if (ary[i] != undefined && ary[i] != "") break; ary.splice(i, 1); } } //★データ集計 function outputStarData(){ document.getElementById("mapAll").style.display = "none"; document.getElementById("maptoolLink").style.display = "none"; var frameElem = document.createElement("iframe"); frameElem.id = "maptoolCsvFrame"; frameElem.style.width = "100%"; frameElem.style.height = "540px"; var mapElem = document.evaluate('//*[@id="mapboxInner"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); mapElem.snapshotItem(0).insertBefore( frameElem, document.getElementById("mapAll").nextSibling); var y1 = document.getElementById("star1").value; var y2 = document.getElementById("star2").value; var x1 = document.getElementById("star3").value; var x2 = document.getElementById("star4").value; var starRate = document.getElementById("star5").value; if (!y1 || !y2 || !x1 || !x2){ alert('座標入力は必須です'); return false; } var numChk = 0; if(x1.search(/^[-]?\d+(\.\d+)?$/) == -1 || x2.search(/^[-]?\d+(\.\d+)?$/) == -1 || y1.search(/^[-]?\d+(\.\d+)?$/) == -1 || y2.search(/^[-]?\d+(\.\d+)?$/) == -1 ) { alert('座標は半角数字で入力してください'); return false; } //時間がかかるので別スレッド化(一旦描画して砂時計を表示させる) setWaitCursor(); window.setTimeout(function() { y1 = parseInt(y1) y2 = parseInt(y2) x1 = parseInt(x1) x2 = parseInt(x2) if (y2 > y1){ var y3 = y1 y1 = y2 y2 = y3 } if (x2 > x1){ var x3 = x1 x1 = x2 x2 = x3 } var frameDoc = document.getElementById("maptoolCsvFrame").contentDocument; var addElem = frameDoc.createElement("table"); addElem.id = "maptoolCsv"; addElem.style.fontSize = "12px"; addElem.style.width = "100%"; addElem.setAttribute("border", "1"); frameDoc.body.appendChild(addElem); var csvText = ""; var dataNull = 0; //各マス行 for (var y=y1; y>=y2; y--) { for (var x=x2; x<=x1; x++) { //保存データ取得 var data = loadCellData(generateCellKey(x, y)); if (data.length == 0) { dataNull = 1; continue; } if (starRate == "砦"){ if (data[IDX_USER_NAME].match(/守衛/)){ csvText += ""; csvText += ""; csvText += ""; csvText += "(" + x + "," + y + ")"; csvText += ""; csvText += " "; csvText += ""; csvText += data[IDX_VILLAGE_NAME]; csvText += " "; csvText += ""; csvText += data[IDX_USER_NAME]; csvText += " "; csvText += ""; csvText += data[IDX_POPULATION]; csvText += " "; csvText += ""; csvText += data[IDX_ALLIANCER]; csvText += " "; csvText += ""; csvText += data[IDX_POWER]; csvText += " "; csvText += ""; csvText += data[IDX_WOOD]; csvText += ","; csvText += data[IDX_STONE]; csvText += ","; csvText += data[IDX_IRON]; csvText += ","; csvText += data[IDX_RICE]; csvText += " "; csvText += ""; csvText += data[IDX_NPC_FLG]; csvText += " "; csvText += ""; } }else{ if (starRate == data[IDX_POWER]){ csvText += ""; csvText += ""; csvText += ""; csvText += "(" + x + "," + y + ")"; csvText += ""; csvText += " "; csvText += ""; csvText += data[IDX_VILLAGE_NAME]; csvText += " "; csvText += ""; csvText += data[IDX_USER_NAME]; csvText += " "; csvText += ""; csvText += data[IDX_POPULATION]; csvText += " "; csvText += ""; csvText += data[IDX_ALLIANCER]; csvText += " "; csvText += ""; csvText += data[IDX_POWER]; csvText += " "; csvText += ""; csvText += data[IDX_WOOD]; csvText += ","; csvText += data[IDX_STONE]; csvText += ","; csvText += data[IDX_IRON]; csvText += ","; csvText += data[IDX_RICE]; csvText += " "; csvText += ""; csvText += data[IDX_NPC_FLG]; csvText += " "; csvText += ""; } } } } if (dataNull == 1){ addElem.innerHTML = "指定範囲内にMAP未取得のエリアがあります"; } addElem.innerHTML += csvText; resetCursor(); }, 0);} //地図データCSV出力 function outputMapCsvS() { outputMapCsv(CSV_RADIUS_S); } function outputMapCsvL() { outputMapCsv(CSV_RADIUS_L); } function outputMapCsv(radius) { document.getElementById("mapAll").style.display = "none"; document.getElementById("maptoolLink").style.display = "none"; var frameElem = document.createElement("iframe"); frameElem.id = "maptoolCsvFrame"; frameElem.style.width = "100%"; frameElem.style.height = "540px"; var mapElem = document.evaluate('//*[@id="mapboxInner"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); mapElem.snapshotItem(0).insertBefore( frameElem, document.getElementById("mapAll").nextSibling); //時間がかかるので別スレッド化(一旦描画して砂時計を表示させる) setWaitCursor(); window.setTimeout(function() { var frameDoc = document.getElementById("maptoolCsvFrame").contentDocument; var addElem = frameDoc.createElement("pre"); addElem.id = "maptoolCsv"; addElem.style.fontSize = "12px"; frameDoc.body.appendChild(addElem); //タイトル行 var csvText = ""; csvText += "X,Y,VILLAGE_NAME,USER_NAME,POPULATION,X_Y,ALLIANCER,POWER,"; csvText += "WOOD,STONE,IRON,RICE,NPC_FLAG,LAST_UPDATE\n"; //各マス行 for (var y=CENTER_Y+radius; y>=CENTER_Y-radius; y--) { for (var x=CENTER_X-radius; x<=CENTER_X+radius; x++) { //保存データ取得 var data = loadCellData(generateCellKey(x, y)); if (data.length == 0) { continue; } csvText += x; csvText += ","; csvText += y; csvText += ","; csvText += convCsvString(data[IDX_VILLAGE_NAME]); csvText += ","; csvText += convCsvString(data[IDX_USER_NAME]); csvText += ","; csvText += data[IDX_POPULATION]; csvText += ","; csvText += convCsvString("(" + x + "," + y + ")"); csvText += ","; csvText += convCsvString(data[IDX_ALLIANCER]); csvText += ","; csvText += data[IDX_POWER]; csvText += ","; csvText += data[IDX_WOOD]; csvText += ","; csvText += data[IDX_STONE]; csvText += ","; csvText += data[IDX_IRON]; csvText += ","; csvText += data[IDX_RICE]; csvText += ","; csvText += data[IDX_NPC_FLG]; csvText += ","; csvText += data[IDX_LAST_UPDATE]; csvText += "\n"; } } addElem.innerHTML = csvText; resetCursor(); }, 0); } //マスデータキー生成 function generateCellKey(x, y) { return location.hostname + "(" + x + "," + y + ")"; } //同盟データキー生成 function generateAllyKey(allyName) { return location.hostname + "_ally_" + escape(allyName); } //君主データキー生成 function generateUserKey(userName) { return location.hostname + "_user_" + escape(userName); } //基準時刻取得 function getBaseTime() { var res = GM_getValue(location.hostname + "BASE_TIME", ""); if (res == "") { var date = new Date(); res = "" + date.getFullYear() + padZero(date.getMonth() + 1) + padZero(date.getDate()); } return res; } //自拠点座標取得 function getMyXY() { var elems = document.evaluate('//*[@id="sidebar"]//div[2]/div[2]/ul', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); if (elems.snapshotLength == 0 || elems.snapshotItem(0).childNodes == undefined) { console.log("自拠点座標取得エラー"); return ""; } for (var i = 0; i < elems.snapshotItem(0).childNodes.length; i++) { var item = elems.snapshotItem(0).childNodes[i]; if (item.nodeName.toLowerCase() == "li" && item.className == "on") { var srcText = getChildElement(item, 0).title; var ret = srcText.replace(/^.+\((-?[0-9]+\,-?[0-9]+)\)$/, "$1"); return ret; } } return ""; } //地図シフト function shiftMap(shiftX, shiftY) { var r; //半径 if (MAP_MODE == MAP_MODE_M) r = RADIUS; else if (MAP_MODE == MAP_MODE_L) r = RADIUS_L; //移動先座標算出 var x = CENTER_X + ((r*2 + 1) * shiftX); var y = CENTER_Y + ((r*2 + 1) * shiftY); //地図移動 moveMap(x, y); } //地図移動 function moveMap(x, y) { if (isNaN(x) || isNaN(y)) return; CENTER_X = x; CENTER_Y = y; //範囲外に出ないように CENTER_X = (CENTER_X > MAX_XY ? MAX_XY: CENTER_X); CENTER_X = (CENTER_X < -MAX_XY ? -MAX_XY: CENTER_X); CENTER_Y = (CENTER_Y > MAX_XY ? MAX_XY: CENTER_Y); CENTER_Y = (CENTER_Y < -MAX_XY ? -MAX_XY: CENTER_Y); //地図表示 LOADED_MAPS = new Array(); changeMap(); } //地図画面URL取得 function getMapUrl(x, y) { return "/map.php?x=" + x + "&y=" + y; } //カーソル変更 function setWaitCursor() { document.getElementsByTagName("body")[0].style.cursor = "wait"; } function resetCursor() { document.getElementsByTagName("body")[0].style.cursor = "auto"; } //CSS追加 function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName("head")[0]; if (!head) { return; } style = document.createElement("style"); style.type = "text/css"; style.innerHTML = css; head.appendChild(style); } //URLパラメータ取得 function getParameter(key) { var str = location.search.split("?"); if (str.length < 2) { return ""; } var params = str[1].split("&"); for (var i = 0; i < params.length; i++) { var keyVal = params[i].split("="); if (keyVal[0] == key && keyVal.length == 2) { return decodeURIComponent(keyVal[1]); } } return ""; } //子Element取得 function getChildElement(parentNode, position) { var current = 0; for (var i = 0; i < parentNode.childNodes.length; i++){ var childNode = parentNode.childNodes[i]; if (childNode.nodeType == 1) { if (current == position) { return childNode; } current++; } } return undefined; } //現在時刻取得(yyyy/mm/dd hh:mm:ss) function getCurrentTime() { var date = new Date(); var res = "" + date.getFullYear() + "/" + padZero(date.getMonth() + 1) + "/" + padZero(date.getDate()) + " " + padZero(date.getHours()) + ":" + padZero(date.getMinutes()) + ":" + padZero(date.getSeconds()); return res; } //現在時刻取得2(yyyymmddhhmmss) function getCurrentTime2() { var date = new Date(); var res = "" + date.getFullYear() + padZero(date.getMonth() + 1) + padZero(date.getDate()) + padZero(date.getHours()) + padZero(date.getMinutes()) + padZero(date.getSeconds()); return res; } //先頭ゼロ付加 function padZero(num) { var result; if (num < 10) { result = "0" + num; } else { result = "" + num; } return result; } //先頭ゼロ除去 function trimZero(str) { var res = str.replace(/^0*/, ""); if (res == "") res = "0"; return res; } //空白除去 function trim(str) { return str.replace(/^[  \t\r\n]+|[  \t\r\n]+$/g, ""); } //CSV用文字列変換 function convCsvString(str) { var result; //「"」を「""」に変換 result = str.replace(/\"/g, "\"\""); //「,」を含む場合は全体を「"」で囲む if (result.indexOf(",") >= 0) { result = "\"" + result + "\"" } return result; } //デリミタ区切り文字列生成 function genDelimitString(dataArray, delimiter) { var ret = ""; for (var i=0; i < dataArray.length; i++) { if (dataArray[i] != undefined) ret += dataArray[i]; if (i < dataArray.length-1) ret += delimiter; } return ret; } //完全一致/部分一致チェック function matchString(target, sub) { if (target == undefined || sub == undefined) { return false; } target = target.toLowerCase(); sub = sub.toLowerCase(); if (sub != "") { if (MATCH_FULL) { if (target == sub) return true; } else { if (target.indexOf(sub) >= 0) return true; } } return false; } function searchArrayString(targets, sub) { var ret = new Array(); for (var i=0; i