Compare commits
	
		
			2 Commits
		
	
	
		
			5602b59827
			...
			c279aac744
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c279aac744 | |||
| 66b971a9f4 | 
| @ -13215,448 +13215,448 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = | |||||||
|     }; |     }; | ||||||
|   }, |   }, | ||||||
|     "小地图": function () { |     "小地图": function () { | ||||||
|     // 在此增加新插件
 | 	// 在此增加新插件
 | ||||||
|     // ----- 不可自定义 杂七杂八的变量
 | 	// ----- 不可自定义 杂七杂八的变量
 | ||||||
|     /** @type {{[x: string]: BFSResult}} */ | 	/** @type {{[x: string]: BFSResult}} */ | ||||||
|     let mapCache = {}; // 地图缓存
 | 	let mapCache = {}; // 地图缓存
 | ||||||
|     let drawCache = {}; // 绘制信息缓存
 | 	let drawCache = {}; // 绘制信息缓存
 | ||||||
|     let status = "none"; // 当前的绘制状态
 | 	let status = "none"; // 当前的绘制状态
 | ||||||
|     /** @type {{[x: string]: Sprite}} */ | 	/** @type {{[x: string]: Sprite}} */ | ||||||
|     let sprites = {}; // 当前所有的sprite
 | 	let sprites = {}; // 当前所有的sprite
 | ||||||
|     /** @type {{[x: string]: Sprite}} */ | 	/** @type {{[x: string]: Sprite}} */ | ||||||
|     let canDrag = {}; // 可以拖拽的sprite
 | 	let canDrag = {}; // 可以拖拽的sprite
 | ||||||
|     /** @type {{[x: string]: Button}} */ | 	/** @type {{[x: string]: Button}} */ | ||||||
|     let areaSprite = {}; // 区域列表对应的sprite
 | 	let areaSprite = {}; // 区域列表对应的sprite
 | ||||||
|     let clicking = false; // 是否正在点击,用于拖拽判定
 | 	let clicking = false; // 是否正在点击,用于拖拽判定
 | ||||||
|     let drawingMap = ""; // 正在绘制的中心楼层
 | 	let drawingMap = ""; // 正在绘制的中心楼层
 | ||||||
|     let nowScale = 0; // 当前绘制的放缩比例
 | 	let nowScale = 0; // 当前绘制的放缩比例
 | ||||||
|     let lastTouch = {}; // 上一次的单点点击信息
 | 	let lastTouch = {}; // 上一次的单点点击信息
 | ||||||
|     let lastLength = 0; // 手机端缩放时上一次的两指间距离
 | 	let lastLength = 0; // 手机端缩放时上一次的两指间距离
 | ||||||
|     let nowDepth = 0; // 当前的遍历深度
 | 	let nowDepth = 0; // 当前的遍历深度
 | ||||||
|     let drawedThumbnail = {}; // 已经绘制过的缩略图
 | 	let drawedThumbnail = {}; // 已经绘制过的缩略图
 | ||||||
|     let moved = false; // 鼠标按下后是否移动了
 | 	let moved = false; // 鼠标按下后是否移动了
 | ||||||
|     let noBorder = false; // 是否是无边框拼接模式
 | 	let noBorder = false; // 是否是无边框拼接模式
 | ||||||
|     let lastScale = 0; // 上一次缩放,用于优化缩略图绘制
 | 	let lastScale = 0; // 上一次缩放,用于优化缩略图绘制
 | ||||||
|     let areaPage = 0; // 区域显示的当前页数
 | 	let areaPage = 0; // 区域显示的当前页数
 | ||||||
|     let nowArea = 0; // 当前区域index
 | 	let nowArea = 0; // 当前区域index
 | ||||||
|     let selecting = ""; // 选择时当前正在选择的地图
 | 	let selecting = ""; // 选择时当前正在选择的地图
 | ||||||
| 
 | 
 | ||||||
|     // ---- 不可自定义,常量
 | 	// ---- 不可自定义,常量
 | ||||||
|     /** @type {Area} */ | 	/** @type {Area} */ | ||||||
|     let areas = []; // 区域信息
 | 	let areas = []; // 区域信息
 | ||||||
|     const perPage = Math.floor((core._PY_ - 60) / 30); // 区域的每页显示数量
 | 	const perPage = Math.floor((core._PY_ - 60) / 30); // 区域的每页显示数量
 | ||||||
| 
 | 
 | ||||||
|     // ---- 可自定义,默认的切换地图的图块id
 | 	// ---- 可自定义,默认的切换地图的图块id
 | ||||||
|     const defaultChange = { | 	const defaultChange = { | ||||||
|       left: "leftPortal", // 左箭头
 | 		left: "leftPortal", // 左箭头
 | ||||||
|       up: "upPortal", // 上箭头
 | 		up: "upPortal", // 上箭头
 | ||||||
|       right: "rightPortal", // 右箭头
 | 		right: "rightPortal", // 右箭头
 | ||||||
|       down: "downPortal", // 下箭头
 | 		down: "downPortal", // 下箭头
 | ||||||
|       upFloor: "upFloor", // 上楼
 | 		upFloor: "upFloor", // 上楼
 | ||||||
|       downFloor: "downFloor", // 下楼
 | 		downFloor: "downFloor", // 下楼
 | ||||||
|     }; | 	}; | ||||||
|     // ---- 可自定义,默认数值
 | 	// ---- 可自定义,默认数值
 | ||||||
|     const defaultValue = { | 	const defaultValue = { | ||||||
|       font: "Verdana", // 默认字体
 | 		font: "Verdana", // 默认字体
 | ||||||
|       scale: 60, // 默认地图缩放比例
 | 		scale: 60, // 默认地图缩放比例
 | ||||||
|       depth: Infinity, // 默认的遍历深度
 | 		depth: Infinity, // 默认的遍历深度
 | ||||||
|     }; | 	}; | ||||||
| 
 | 
 | ||||||
|     // ---- 不可自定义,计算数据
 | 	// ---- 不可自定义,计算数据
 | ||||||
|     const dirData = { | 	const dirData = { | ||||||
|       up: [1, 0], | 		up: [1, 0], | ||||||
|       down: [-1, 0], | 		down: [-1, 0], | ||||||
|       left: [0, 1], | 		left: [0, 1], | ||||||
|       right: [0, -1], | 		right: [0, -1], | ||||||
|       upFloor: [0, 0], | 		upFloor: [0, 0], | ||||||
|       downFloor: [0, 0], | 		downFloor: [0, 0], | ||||||
|     }; | 	}; | ||||||
|     let ignoreEnemies = (this.ignoreEnemies = []); | 	let ignoreEnemies = (this.ignoreEnemies = []); | ||||||
| 
 | 
 | ||||||
|     let allChangeEntries = Object.entries(defaultChange); | 	let allChangeEntries = Object.entries(defaultChange); | ||||||
| 
 | 
 | ||||||
|     this.setq = function (floorId) { | 	this.setq = function (floorId) { | ||||||
|       core.setFlag("任务地点", floorId); | 		core.setFlag("任务地点", floorId); | ||||||
|     }; | 	}; | ||||||
| 
 | 
 | ||||||
|     const reset = core.events.resetGame; | 	const reset = core.events.resetGame; | ||||||
|     this.bfs = function () { | 	this.bfs = function () { | ||||||
|       areas = []; | 		areas = []; | ||||||
|       // 获取所有分区,使用异步函数,保证不会卡顿
 | 		// 获取所有分区,使用异步函数,保证不会卡顿
 | ||||||
|       // 原理是用bfs扫,将所有连在一起的地图合并成一个区域
 | 		// 原理是用bfs扫,将所有连在一起的地图合并成一个区域
 | ||||||
|       (async function () { | 		(async function () { | ||||||
|         let all = core.floorIds.slice(); | 			let all = core.floorIds.slice(); | ||||||
|         const scanned = { | 			const scanned = { | ||||||
|           [all[0]]: true, | 				[all[0]]: true, | ||||||
|         }; | 			}; | ||||||
|         while (all.length > 0) { | 			while (all.length > 0) { | ||||||
|           let now = all.shift(); | 				let now = all.shift(); | ||||||
|           if (core.status.maps[now].deleted) continue; | 				if (core.status.maps[now].deleted) continue; | ||||||
|           if (!now) return; | 				if (!now) return; | ||||||
|           await new Promise((res) => { | 				await new Promise((res) => { | ||||||
|             const result = core.plugin.bfsSearch(now, Infinity, true); | 					const result = core.plugin.bfsSearch(now, Infinity, true); | ||||||
|             mapCache[`${now}_Infinity_false`] = result; | 					mapCache[`${now}_Infinity_false`] = result; | ||||||
|             areas.push({ name: core.floors[now].areas, maps: result.order }); | 					areas.push({ name: core.floors[now].areas, maps: result.order }); | ||||||
|             for (const map of result.order) { | 					for (const map of result.order) { | ||||||
|               scanned[map] = true; | 						scanned[map] = true; | ||||||
|               all = all.filter((v) => !result.order.includes(v)); | 						all = all.filter((v) => !result.order.includes(v)); | ||||||
|             } | 					} | ||||||
|             res("success"); | 					res("success"); | ||||||
|           }).then(() => { | 				}).then(() => { | ||||||
|             core.setFlag("areas", areas); | 					core.setFlag("areas", areas); | ||||||
|           }); | 				}); | ||||||
|         } | 			} | ||||||
|       })(); | 		})(); | ||||||
|     }; | 	}; | ||||||
|     core.events.resetGame = function () { | 	core.events.resetGame = function () { | ||||||
|       reset.apply(core.events, arguments); | 		reset.apply(core.events, arguments); | ||||||
|       core.plugin.bfs(); | 		core.plugin.bfs(); | ||||||
|     }; | 	}; | ||||||
|     /** | 	/** | ||||||
|      * 广度优先搜索搜索地图路径 | 	 * 广度优先搜索搜索地图路径 | ||||||
|      * @param {string} center 中心地图的id | 	 * @param {string} center 中心地图的id | ||||||
|      * @param {number} depth 搜索深度 | 	 * @param {number} depth 搜索深度 | ||||||
|      * @param {boolean} noCache 是否不使用缓存 | 	 * @param {boolean} noCache 是否不使用缓存 | ||||||
|      * @returns {BFSResult} 格式:floorId_x_y_dir: floorId_x_y | 	 * @returns {BFSResult} 格式:floorId_x_y_dir: floorId_x_y | ||||||
|      */ | 	 */ | ||||||
|     this.bfsSearch = function bfsSearch(center, depth, noCache) { | 	this.bfsSearch = function bfsSearch(center, depth, noCache) { | ||||||
|       // 检查缓存
 | 		// 检查缓存
 | ||||||
|       const id = `${center}_${depth}_${noBorder}`; | 		const id = `${center}_${depth}_${noBorder}`; | ||||||
|       if (mapCache[id] && !noCache) return mapCache[id]; | 		if (mapCache[id] && !noCache) return mapCache[id]; | ||||||
|       const used = { | 		const used = { | ||||||
|         [center]: true, | 			[center]: true, | ||||||
|       }; // 搜索过的楼层
 | 		}; // 搜索过的楼层
 | ||||||
|       let queue = []; | 		let queue = []; | ||||||
|       let stack = [center]; // 当前栈
 | 		let stack = [center]; // 当前栈
 | ||||||
|       let nowDepth = -1; | 		let nowDepth = -1; | ||||||
|       const mapOrder = [center]; // 遍历顺序,顺便还能记录遍历了哪些楼层
 | 		const mapOrder = [center]; // 遍历顺序,顺便还能记录遍历了哪些楼层
 | ||||||
| 
 | 
 | ||||||
|       const res = {}; // 输出结果,格式:floorId_x_y_dir: floorId_x_y
 | 		const res = {}; // 输出结果,格式:floorId_x_y_dir: floorId_x_y
 | ||||||
|       const enemies = {}; | 		const enemies = {}; | ||||||
|       const upOrDown = {}; | 		const upOrDown = {}; | ||||||
|       const mapdir = {}; | 		const mapdir = {}; | ||||||
|       // 开始循环搜索
 | 		// 开始循环搜索
 | ||||||
|       while (nowDepth < depth && stack.length > 0) { | 		while (nowDepth < depth && stack.length > 0) { | ||||||
|         const now = stack.shift(); // 当前id
 | 			const now = stack.shift(); // 当前id
 | ||||||
|         if (core.status.maps[now].deleted) continue; | 			if (core.status.maps[now].deleted) continue; | ||||||
|         mapdir[now] = mapdir[now] ?? []; | 			mapdir[now] = mapdir[now] ?? []; | ||||||
|         const blocks = core.getMapBlocksObj(now); // 获取当前地图的每点的事件
 | 			const blocks = core.getMapBlocksObj(now); // 获取当前地图的每点的事件
 | ||||||
|         enemies[now] = {}; | 			enemies[now] = {}; | ||||||
|         // 遍历,获取可以传送的点,只检测绿点事件,因此可用红点事件进行传送来实现分区功能
 | 			// 遍历,获取可以传送的点,只检测绿点事件,因此可用红点事件进行传送来实现分区功能
 | ||||||
|         for (const i in blocks) { | 			for (const i in blocks) { | ||||||
|           const block = blocks[i]; | 				const block = blocks[i]; | ||||||
|           // 整合漏怪检测,所以要检测怪物
 | 				// 整合漏怪检测,所以要检测怪物
 | ||||||
|           if (block.event.trigger === "battle") { | 				if (block.event.trigger === "battle") { | ||||||
|             const id = block.event.id; | 					const id = block.event.id; | ||||||
|             if (ignoreEnemies.includes(id)) continue; | 					if (ignoreEnemies.includes(id)) continue; | ||||||
|             else enemies[now][i] = block.event.id; | 					else enemies[now][i] = block.event.id; | ||||||
|             continue; | 					continue; | ||||||
|           } | 				} | ||||||
|           // 检测触发器是否为切换楼层,不是则直接跳过
 | 				// 检测触发器是否为切换楼层,不是则直接跳过
 | ||||||
|           if (block.event.trigger !== "changeFloor") continue; | 				if (block.event.trigger !== "changeFloor") continue; | ||||||
|           const dirEntries = allChangeEntries.find( | 				const dirEntries = allChangeEntries.find( | ||||||
|             (v) => v[1] === block.event.id | 					(v) => v[1] === block.event.id | ||||||
|           ); | 				); | ||||||
|           // 如果不是那六种传送门,直接忽略
 | 				// 如果不是那六种传送门,直接忽略
 | ||||||
|           if (!dirEntries) continue; | 				if (!dirEntries) continue; | ||||||
|           const data = block.event.data; | 				const data = block.event.data; | ||||||
|           const dir = dirEntries[0]; | 				const dir = dirEntries[0]; | ||||||
|           const route = now + "_" + i.replace(",", "_") + "_" + dir; | 				const route = now + "_" + i.replace(",", "_") + "_" + dir; | ||||||
|           const target = data.floorId + "_" + data.loc.join("_"); | 				const target = data.floorId + "_" + data.loc.join("_"); | ||||||
| 
 | 
 | ||||||
|           mapdir[now].push(dir); | 				mapdir[now].push(dir); | ||||||
|           if (!used[data.floorId]) { | 				if (!used[data.floorId]) { | ||||||
|             if (dir === "upFloor" || dir === "downFloor") { | 					if (dir === "upFloor" || dir === "downFloor") { | ||||||
|               upOrDown[now] = upOrDown[id] ?? []; | 						upOrDown[now] = upOrDown[id] ?? []; | ||||||
|               upOrDown[now].push(dir); | 						upOrDown[now].push(dir); | ||||||
|             } | 					} | ||||||
| 
 | 
 | ||||||
|             queue.push(data.floorId); // 没有搜索过,则加入栈中
 | 					queue.push(data.floorId); // 没有搜索过,则加入栈中
 | ||||||
|             mapOrder.push(data.floorId); | 					mapOrder.push(data.floorId); | ||||||
|             used[data.floorId] = true; | 					used[data.floorId] = true; | ||||||
|           } | 				} | ||||||
|           res[route] = target; | 				res[route] = target; | ||||||
|         } | 			} | ||||||
|         if (stack.length === 0) { | 			if (stack.length === 0) { | ||||||
|           stack = queue; | 				stack = queue; | ||||||
|           queue = []; | 				queue = []; | ||||||
|           nowDepth++; | 				nowDepth++; | ||||||
|         } | 			} | ||||||
|         if (stack.length === 0 && queue.length === 0) break; | 			if (stack.length === 0 && queue.length === 0) break; | ||||||
|       } | 		} | ||||||
|       return { res, order: mapOrder, enemies, upOrDown, mapdir }; | 		return { res, order: mapOrder, enemies, upOrDown, mapdir }; | ||||||
|     }; | 	}; | ||||||
|     /** | 	/** | ||||||
|      * 获取绘制信息 | 	 * 获取绘制信息 | ||||||
|      * @param {string?} center 中心地图id | 	 * @param {string?} center 中心地图id | ||||||
|      * @param {number?} depth 搜索深度 | 	 * @param {number?} depth 搜索深度 | ||||||
|      * @param {boolean?} noCache 是否不使用缓存 | 	 * @param {boolean?} noCache 是否不使用缓存 | ||||||
|      * @returns {MapDrawInfo} | 	 * @returns {MapDrawInfo} | ||||||
|      */ | 	 */ | ||||||
|     this.getMapDrawInfo = function ( | 	this.getMapDrawInfo = function ( | ||||||
|       center = core.status.floorId, | 		center = core.status.floorId, | ||||||
|       depth = defaultValue.depth, | 		depth = defaultValue.depth, | ||||||
|       noCache = false | 		noCache = false | ||||||
|     ) { | 	) { | ||||||
|       nowDepth = depth; | 		nowDepth = depth; | ||||||
|       drawingMap = center; | 		drawingMap = center; | ||||||
|       const id = `${center}_${depth}_${noBorder}`; | 		const id = `${center}_${depth}_${noBorder}`; | ||||||
|       // 检查缓存
 | 		// 检查缓存
 | ||||||
|       if (drawCache[id] && !noCache) return drawCache[id]; | 		if (drawCache[id] && !noCache) return drawCache[id]; | ||||||
|       const map = core.plugin.bfsSearch(center, depth, noCache); | 		const map = core.plugin.bfsSearch(center, depth, noCache); | ||||||
|       mapCache[id] = map; | 		mapCache[id] = map; | ||||||
|       const res = getDrawInfo(map.res, center, map.order); | 		const res = getDrawInfo(map.res, center, map.order); | ||||||
|       res.upOrDown = map.upOrDown; | 		res.upOrDown = map.upOrDown; | ||||||
|       res.mapdir = map.mapdir; | 		res.mapdir = map.mapdir; | ||||||
|       drawCache[id] = res; | 		drawCache[id] = res; | ||||||
|       return res; | 		return res; | ||||||
|     }; | 	}; | ||||||
|     /** | 	/** | ||||||
|      * 提供地图的绘制信息 | 	 * 提供地图的绘制信息 | ||||||
|      * @param {{[x: string]: string}} map 要绘制的地图,格式:floorId_x_y_dir: floorId_x_y | 	 * @param {{[x: string]: string}} map 要绘制的地图,格式:floorId_x_y_dir: floorId_x_y | ||||||
|      * @param {string} center 中心地图的id | 	 * @param {string} center 中心地图的id | ||||||
|      * @param {string[]} order 遍历顺序 | 	 * @param {string[]} order 遍历顺序 | ||||||
|      * @returns {MapDrawInfo} 地图的绘制信息 | 	 * @returns {MapDrawInfo} 地图的绘制信息 | ||||||
|      */ | 	 */ | ||||||
| 
 | 
 | ||||||
|     function getDrawInfo(map, center, order) { | 	function getDrawInfo(map, center, order) { | ||||||
|       // 先根据地图id分类,从而确定每个地图连接哪些地图,同时方便处理
 | 		// 先根据地图id分类,从而确定每个地图连接哪些地图,同时方便处理
 | ||||||
|       const links = {}; | 		const links = {}; | ||||||
|       for (const i in map) { | 		for (const i in map) { | ||||||
|         const splitted = i.split("_"); | 			const splitted = i.split("_"); | ||||||
|         const id = splitted[0]; | 			const id = splitted[0]; | ||||||
|         if (!links[id]) links[id] = {}; | 			if (!links[id]) links[id] = {}; | ||||||
|         links[id][i] = map[i]; | 			links[id][i] = map[i]; | ||||||
|       } | 		} | ||||||
| 
 | 
 | ||||||
|       // 分类完毕,然后根据连接点先计算出各个地图的坐标,然后再进行判断
 | 		// 分类完毕,然后根据连接点先计算出各个地图的坐标,然后再进行判断
 | ||||||
|       const centerFloor = core.status.maps[center]; | 		const centerFloor = core.status.maps[center]; | ||||||
|       const visitedCenter = core.hasVisitedFloor(center); | 		const visitedCenter = core.hasVisitedFloor(center); | ||||||
|       const locs = { | 		const locs = { | ||||||
|         // 格式:[中心x, 中心y, 宽, 高, 是否到达过]
 | 			// 格式:[中心x, 中心y, 宽, 高, 是否到达过]
 | ||||||
|         [center]: [2, 2, 1, 1, visitedCenter], | 			[center]: [2, 2, 1, 1, visitedCenter], | ||||||
|       }; | 		}; | ||||||
|       // 可以上楼下楼的地图
 | 		// 可以上楼下楼的地图
 | ||||||
|       const upOrDown = {}; | 		const upOrDown = {}; | ||||||
|       for (const id of order) { | 		for (const id of order) { | ||||||
|         const now = links[id]; | 			const now = links[id]; | ||||||
|         // 遍历每一个地图的连接情况
 | 			// 遍历每一个地图的连接情况
 | ||||||
|         for (const from in now) { | 			for (const from in now) { | ||||||
|           const to = now[from]; | 				const to = now[from]; | ||||||
|           // 先根据from to计算物理位置
 | 				// 先根据from to计算物理位置
 | ||||||
|           const fromData = from.split("_"), | 				const fromData = from.split("_"), | ||||||
|             toData = to.split("_"); | 					toData = to.split("_"); | ||||||
|           const dir = fromData[3]; | 				const dir = fromData[3]; | ||||||
|           if (dir === "upFloor" || dir === "downFloor") continue; | 				if (dir === "upFloor" || dir === "downFloor") continue; | ||||||
|           if (!defaultChange[dir]) continue; | 				if (!defaultChange[dir]) continue; | ||||||
|           const v = dirData[dir][1], // 竖直数值
 | 				const v = dirData[dir][1], // 竖直数值
 | ||||||
|             h = dirData[dir][0], // 水平数值
 | 					h = dirData[dir][0], // 水平数值
 | ||||||
|             ha = Math.abs(h), | 					ha = Math.abs(h), | ||||||
|             va = Math.abs(v); | 					va = Math.abs(v); | ||||||
|           const ff = id, // fromFloorId
 | 				const ff = id, // fromFloorId
 | ||||||
|             tf = toData[0]; // toFloorId
 | 					tf = toData[0]; // toFloorId
 | ||||||
|           const fromFloor = core.status.maps[ff], | 				const fromFloor = core.status.maps[ff], | ||||||
|             toFloor = core.status.maps[tf]; | 					toFloor = core.status.maps[tf]; | ||||||
|           const fhw = Math.floor(fromFloor.width / 2), // fromFloorHalfWidth
 | 				const fhw = Math.floor(fromFloor.width / 2), // fromFloorHalfWidth
 | ||||||
|             fhh = Math.floor(fromFloor.height / 2), | 					fhh = Math.floor(fromFloor.height / 2), | ||||||
|             thw = Math.floor(toFloor.width / 2), | 					thw = Math.floor(toFloor.width / 2), | ||||||
|             thh = Math.floor(toFloor.height / 2); | 					thh = Math.floor(toFloor.height / 2); | ||||||
|           const fLoc = locs[id] ?? [0, 0]; | 				const fLoc = locs[id] ?? [0, 0]; | ||||||
|           if (!locs[ff]) continue; | 				if (!locs[ff]) continue; | ||||||
|           let x, y; | 				let x, y; | ||||||
|           if (locs && locs[tf]) { | 				if (locs && locs[tf]) { | ||||||
|             x = locs[tf][0]; | 					x = locs[tf][0]; | ||||||
|             y = locs[tf][1]; | 					y = locs[tf][1]; | ||||||
|           } else { | 				} else { | ||||||
|             // 计算坐标,公式可以通过画图推断出
 | 					// 计算坐标,公式可以通过画图推断出
 | ||||||
|             x = fLoc[0] - v; | 					x = fLoc[0] - v; | ||||||
|             y = fLoc[1] - h; | 					y = fLoc[1] - h; | ||||||
|           } | 				} | ||||||
|           locs[tf] = locs[tf] ?? [x, y, 1, 1, core.hasVisitedFloor(tf)]; | 				locs[tf] = locs[tf] ?? [x, y, 1, 1, core.hasVisitedFloor(tf)]; | ||||||
|         } | 			} | ||||||
|       } | 		} | ||||||
|       // 获取地图绘制需要的长宽
 | 		// 获取地图绘制需要的长宽
 | ||||||
|       let width = 0, | 		let width = 0, | ||||||
|         height = 0; | 			height = 0; | ||||||
|       let left, right, up, down; | 		let left, right, up, down; | ||||||
|       for (const id in locs) { | 		for (const id in locs) { | ||||||
|         const [x, y, w, h] = locs[id]; | 			const [x, y, w, h] = locs[id]; | ||||||
|         if (left === void 0) { | 			if (left === void 0) { | ||||||
|           left = right = x; | 				left = right = x; | ||||||
|           up = down = y; | 				up = down = y; | ||||||
|         } | 			} | ||||||
|         left = Math.min(x - 1, left); | 			left = Math.min(x - 1, left); | ||||||
|         right = Math.max(x + 1, right); | 			right = Math.max(x + 1, right); | ||||||
|         up = Math.min(y - 1, up); | 			up = Math.min(y - 1, up); | ||||||
|         down = Math.max(y + 1, down); | 			down = Math.max(y + 1, down); | ||||||
|       } | 		} | ||||||
|       width = right - left; | 		width = right - left; | ||||||
|       height = down - up; | 		height = down - up; | ||||||
| 
 | 
 | ||||||
|       return { locs, width, height, layer: upOrDown }; | 		return { locs, width, height, layer: upOrDown }; | ||||||
|     } | 	} | ||||||
| 
 | 
 | ||||||
|     function mapblock(mapdir) { | 	function mapblock(mapdir) { | ||||||
|       let mb = ""; | 		let mb = ""; | ||||||
|       if (mapdir.includes("up")) mb += "u"; | 		if (mapdir.includes("up")) mb += "u"; | ||||||
|       if (mapdir.includes("down")) mb += "d"; | 		if (mapdir.includes("down")) mb += "d"; | ||||||
|       if (mapdir.includes("left")) mb += "l"; | 		if (mapdir.includes("left")) mb += "l"; | ||||||
|       if (mapdir.includes("right")) mb += "r"; | 		if (mapdir.includes("right")) mb += "r"; | ||||||
|       return mb ? mb + ".webp" : "null.webp"; | 		return mb ? mb + ".webp" : "null.webp"; | ||||||
|     } | 	} | ||||||
|     core.animateFrame.globalAlphaFloor = 0; | 	core.animateFrame.globalAlphaFloor = 0; | ||||||
|     core.animateFrame.globalAlphaFloorStatus = 1; | 	core.animateFrame.globalAlphaFloorStatus = 1; | ||||||
| 
 | 
 | ||||||
|     const tesk = document.createElement("canvas"); | 	const tesk = document.createElement("canvas"); | ||||||
|     tesk.width = 300; | 	tesk.width = 300; | ||||||
|     tesk.height = 300; | 	tesk.height = 300; | ||||||
|     const teskctx = tesk.getContext("2d"); | 	const teskctx = tesk.getContext("2d"); | ||||||
| 
 | 
 | ||||||
|     let line = 50; | 	let line = 50; | ||||||
|     teskctx.strokeStyle = "green"; | 	teskctx.strokeStyle = "green"; | ||||||
|     teskctx.fillStyle = "green"; | 	teskctx.fillStyle = "green"; | ||||||
|     let now = 0; | 	let now = 0; | ||||||
|     core.registerAnimationFrame("tesk", true, function (timestamp) { | 	core.registerAnimationFrame("tesk", true, function (timestamp) { | ||||||
|       if (timestamp - now > 1000 / 60) { | 		if (timestamp - now > 1000 / 60) { | ||||||
|         now = timestamp; | 			now = timestamp; | ||||||
|         core.clearMap(teskctx); | 			core.clearMap(teskctx); | ||||||
|         teskctx.lineWidth = 150 - line; | 			teskctx.lineWidth = 150 - line; | ||||||
| 
 | 
 | ||||||
|         if (line <= 150) { | 			if (line <= 150) { | ||||||
|           teskctx.beginPath(); | 				teskctx.beginPath(); | ||||||
|           teskctx.arc(150, 150, line, 0, Math.PI * 2); | 				teskctx.arc(150, 150, line, 0, Math.PI * 2); | ||||||
|           line += 2; | 				line += 2; | ||||||
|           teskctx.stroke(); | 				teskctx.stroke(); | ||||||
|         } else { | 			} else { | ||||||
|           teskctx.beginPath(); | 				teskctx.beginPath(); | ||||||
|           teskctx.arc(150, 150, line - 150, 0, Math.PI * 2); | 				teskctx.arc(150, 150, line - 150, 0, Math.PI * 2); | ||||||
|           line += 2; | 				line += 2; | ||||||
|           teskctx.fill(); | 				teskctx.fill(); | ||||||
|           if (line >= 250) line = 50; | 				if (line >= 250) line = 50; | ||||||
|         } | 			} | ||||||
|       } | 		} | ||||||
|     }); | 	}); | ||||||
| 
 | 
 | ||||||
|     /** | 	/** | ||||||
|      * 绘制小地图 | 	 * 绘制小地图 | ||||||
|      * @param {MapDrawInfo} info 地图绘制信息 | 	 * @param {MapDrawInfo} info 地图绘制信息 | ||||||
|      * @param {number} scale 地图的绘制比例 | 	 * @param {number} scale 地图的绘制比例 | ||||||
|      */ | 	 */ | ||||||
|     this.drawSmallMap = function ( | 	this.drawSmallMap = function ( | ||||||
|       ctx, | 		ctx, | ||||||
|       info, | 		info, | ||||||
|       center, | 		center, | ||||||
|       sx, | 		sx, | ||||||
|       sy, | 		sy, | ||||||
|       sw, | 		sw, | ||||||
|       sh, | 		sh, | ||||||
|       scale = defaultValue.scale | 		scale = defaultValue.scale | ||||||
|     ) { | 	) { | ||||||
|       core.clearMap(ctx, sx, sy, sw + 40, sh + 60); | 		core.clearMap(ctx, sx, sy, sw + 40, sh + 60); | ||||||
|       if (core.domStyle.isVertical) { | 		if (core.domStyle.isVertical) { | ||||||
|         sy += 50; | 			sy += 50; | ||||||
|         sx += 15; | 			sx += 15; | ||||||
|       } else { | 		} else { | ||||||
|         sy += 60; | 			sy += 60; | ||||||
|         sx += 30; | 			sx += 30; | ||||||
|       } | 		} | ||||||
|       core.fillRect(ctx, sx, sy, sw, sh, "#000"); | 		core.fillRect(ctx, sx - 10, sy - 10, sw + 20, sh + 20, "#000"); | ||||||
|       core.strokeRect(ctx, sx, sy, sw, sh, "#fff", 5); | 		core.strokeRect(ctx, sx - 10, sy - 10, sw + 20, sh + 20, "#fff", 5); | ||||||
|       core.setTextAlign("outerUI", "center"); | 		core.setTextAlign("outerUI", "center"); | ||||||
|       core.fillBoldText1( | 		core.fillBoldText1( | ||||||
|         ctx, | 			ctx, | ||||||
|         core.status.maps[center].areas, | 			core.status.maps[center].areas, | ||||||
|         sx + sw / 2, | 			sx + sw / 2, | ||||||
|         sy - 10, | 			sy - 20, | ||||||
|         "#FFFFFF", | 			"#FFFFFF", | ||||||
|         "#000000", | 			"#000000", | ||||||
|         6, | 			6, | ||||||
|         "bold 42px Verdana" | 			"bold 42px Verdana" | ||||||
|       ); | 		); | ||||||
|       const locs = info.locs; | 		const locs = info.locs; | ||||||
|       for (const id in locs) { | 		for (const id in locs) { | ||||||
|         const loc = locs[id]; | 			const loc = locs[id]; | ||||||
|         let color = "#000"; | 			let color = "#000"; | ||||||
|         if (!loc[4]) color = "#f0f"; | 			if (!loc[4]) color = "#f0f"; | ||||||
|         const [x, y, w, h] = loc.map((v) => typeof v === "number" && v * scale); | 			const [x, y, w, h] = loc.map((v) => typeof v === "number" && v * scale); | ||||||
|         const fx = x + sx, | 			const fx = x + sx, | ||||||
|           fy = y + sy; | 				fy = y + sy; | ||||||
|         const mapdir = info.mapdir[id]; | 			const mapdir = info.mapdir[id]; | ||||||
|         const img = mapblock(mapdir); | 			const img = mapblock(mapdir); | ||||||
|         if (x < 0 || x > 4 * scale || y < 0 || y > 4 * scale) continue; | 			if (x < 0 || x > 4 * scale || y < 0 || y > 4 * scale) continue; | ||||||
|         core.drawImage(ctx, img, 0, 0, 60, 60, fx, fy, w, h); | 			core.drawImage(ctx, img, 0, 0, 60, 60, fx, fy, w, h); | ||||||
|         const layer = info.upOrDown[id]; | 			const layer = info.upOrDown[id]; | ||||||
|         const min = Math.min(w, h); | 			const min = Math.min(w, h); | ||||||
| 
 | 
 | ||||||
|         if (layer?.includes("upFloor")) | 			if (layer?.includes("upFloor")) | ||||||
|           core.drawIcon( | 				core.drawIcon( | ||||||
|             ctx, | 					ctx, | ||||||
|             defaultChange.upFloor, | 					defaultChange.upFloor, | ||||||
|             fx + min / 4, | 					fx + min / 4, | ||||||
|             fy + min / 4, | 					fy + min / 4, | ||||||
|             min / 2, | 					min / 2, | ||||||
|             min / 2 | 					min / 2 | ||||||
|           ); | 				); | ||||||
|         if (layer?.includes("downFloor")) | 			if (layer?.includes("downFloor")) | ||||||
|           core.drawIcon( | 				core.drawIcon( | ||||||
|             ctx, | 					ctx, | ||||||
|             defaultChange.downFloor, | 					defaultChange.downFloor, | ||||||
|             fx + min / 4, | 					fx + min / 4, | ||||||
|             fy + min / 4, | 					fy + min / 4, | ||||||
|             min / 2, | 					min / 2, | ||||||
|             min / 2 | 					min / 2 | ||||||
|           ); | 				); | ||||||
|         if (core.getFlag("任务地点") && core.getFlag("任务地点") === id) | 			if (core.getFlag("任务地点") && core.getFlag("任务地点") === id) | ||||||
|           ctx.drawImage(tesk, fx + min / 4, fy + min / 4, min / 2, min / 2); | 				ctx.drawImage(tesk, fx + min / 4, fy + min / 4, min / 2, min / 2); | ||||||
|         if (id === core.status.floorId) | 			if (id === core.status.floorId) | ||||||
|           core.drawImage( | 				core.drawImage( | ||||||
|             ctx, | 					ctx, | ||||||
|             "hero.webp", | 					"hero.webp", | ||||||
|             0, | 					0, | ||||||
|             0, | 					0, | ||||||
|             32, | 					32, | ||||||
|             19, | 					19, | ||||||
|             fx + min / 4, | 					fx + min / 4, | ||||||
|             fy + (min * 5) / 16, | 					fy + (min * 5) / 16, | ||||||
|             32, | 					32, | ||||||
|             19 | 					19 | ||||||
|           ); | 				); | ||||||
|         // 显示漏怪数量
 | 			// 显示漏怪数量
 | ||||||
|         if (core.getFlag("showEnemy")) { | 			if (core.getFlag("showEnemy")) { | ||||||
|           ctx.textAlign = "center"; | 				ctx.textAlign = "center"; | ||||||
|           ctx.textBaseline = "middle"; | 				ctx.textBaseline = "middle"; | ||||||
|           const c = drawingMap + "_" + nowDepth + "_" + noBorder; | 				const c = drawingMap + "_" + nowDepth + "_" + noBorder; | ||||||
|           const n = Object.keys(mapCache[c].enemies[id]).length; | 				const n = Object.keys(mapCache[c].enemies[id]).length; | ||||||
|           color = "#fff"; | 				color = "#fff"; | ||||||
|           if (n > 10) color = "#fc3"; | 				if (n > 10) color = "#fc3"; | ||||||
|           if (n > 20) color = "#f22"; | 				if (n > 20) color = "#f22"; | ||||||
|           ctx.shadowBlur = 0.6 * nowScale; | 				ctx.shadowBlur = 0.6 * nowScale; | ||||||
|           ctx.shadowColor = "#000"; | 				ctx.shadowColor = "#000"; | ||||||
|           if (n > 0) | 				if (n > 0) | ||||||
|             core.fillText( | 					core.fillText( | ||||||
|               ctx, | 						ctx, | ||||||
|               n, | 						n, | ||||||
|               fx + (w * 3) / 10, | 						fx + (w * 3) / 10, | ||||||
|               fy + (h * 7) / 10, | 						fy + (h * 7) / 10, | ||||||
|               color, | 						color, | ||||||
|               22 + "px normal" | 						22 + "px normal" | ||||||
|             ); | 					); | ||||||
|           ctx.shadowBlur = 0; | 				ctx.shadowBlur = 0; | ||||||
|         } | 			} | ||||||
|         if (!core.hasVisitedFloor(id)) { | 			if (!core.hasVisitedFloor(id)) { | ||||||
|           core.fillRect(ctx, fx, fy, w, h, "rgba(0,0,0,0.7)"); | 				core.fillRect(ctx, fx, fy, w, h, "rgba(0,0,0,0.7)"); | ||||||
|           core.fillText( | 				core.fillText( | ||||||
|             ctx, | 					ctx, | ||||||
|             "?", | 					"?", | ||||||
|             fx + min / 2, | 					fx + min / 2, | ||||||
|             fy + (min * 3) / 4, | 					fy + (min * 3) / 4, | ||||||
|             "#FFFFFF", | 					"#FFFFFF", | ||||||
|             "bold 42px Verdana" | 					"bold 42px Verdana" | ||||||
|           ); | 				); | ||||||
|         } | 			} | ||||||
|       } | 		} | ||||||
|     }; | 	}; | ||||||
|   }, | }, | ||||||
|     "楼传": function () { |     "楼传": function () { | ||||||
| 	// 在此增加新插件
 | 	// 在此增加新插件
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user