⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbm_mlmap.d2l

📁 转载其他网站的资料与大家分享
💻 D2L
📖 第 1 页 / 共 5 页
字号:
			this.LastError = ("mlMap.FindPath - The start coord's are not walkable");
			return false;
		}

		if(!_isinrange(_dx, _dy))
		{
			mlprint("mlMap.FindSorcPath - The end coord's are out of range");
			this.LastError = ("mlMap.FindPath - The end coord's are out of range");
			return false;
		}

		if(!this.IsWalkable(_dx, _dy)) {
			var temp = this.FindClosestWalkable(_dx,_dy);
			_dx = temp.x;
			_dy = temp.y;
		}
//		{
//			mlprint("mlMap.FindPath - The end coord's are not walkable");
//			this.LastError = ("mlMap.FindPath - The end coord's are not walkable");
//			return false;
//		}

		if(typeof(_err) != "number" || _err < 0) _err = 0;
		if(typeof(_dstep) != "number" || _dstep < 1) _dstep = 1;
		if(typeof(_rstep) != "number" || _rstep < 1) _rstep = 1;
		if(typeof(_err) != "number" || _err < 0) _err = 0;
		if(typeof(_algo) != "number" || _algo < 0 || _algo > 1) _algo=0;

		if(_algo) {
			var oq = new oFIFO();
		}
		else var oq = new oHeap("h", mlHEAPLOW);

		var minx = this.minx;
		var miny = this.miny;
		var maxx = this.maxx;
		var maxy = this.maxy;
		var width = this.maxx - this.minx-1;
		var height = this.maxy - this.miny-1;

		var AreaData = this.Area;

		var ptd = new Array();
		var fp = new Array();
		var dx = _dx - minx;
		var dy = _dy - miny;
		var sx = _sx - minx;
		var sy = _sy - miny;
		var newg;
		var cx = 0;
		var cy = 0;
		var node;

		var stime = new Date();
		var nodecenters = new Array();
		var distsq = _dist * _dist;

		var _done = false;

		//node grid array used to hold references
		var ng = new Array();
		ng.length = height+1;
		for(var i = 0; i<ng.length; i++){
			ng[i] = new Array();
			ng[i].length = width+1;
		}

		//starting and ending node's
		var enode = new oNode(dx, dy);
		// var fh = this[FORWARDHEURISTICS[_fh]](dx, dy, sx, sy)*_factor;
		var fh = this.sorcheuristic(dx, dy, sx, sy, _dist);
		var snode = new oNode(sx, sy, false, true, -1, 0, fh);
		snode.f = snode.h;
		ng[snode.y][snode.x] = snode;
		oq.Insert(snode);

		// calculate a general point set with the current level of detail
		// var pointset = mbm_CalcPointSet(0, 0, _dist, _dstep, _rstep, 0);
		
		var pointset = new Array();
		var sets = 0;
		for (var d = _dist; d > 3; d -= (_dist / _dstep)) {
			pointset[sets] = new Array();
			for (var r = 0; r < _rstep; r++) {
				var angle = ((Math.PI*2) / _rstep) * r;
//				print("angle " + r + " : " + angle + " d= " + d);
				pointset[sets].push({x:(Math.cos(angle)*d),y:(Math.sin(angle)*d)});
//				print("ponit " + p2s(pointset[sets][pointset[sets].length-1]));
			}
			sets++;
		}

		//pdis = new oTerminal(100, 30, 40, 40, 6, 0);

		nextnode:
		while (node = oq.Remove())
		{
			//updateterminal(AreaData, node.x, node.y);

			if(Math.abs(node.x - enode.x) < _err && Math.abs(node.y - enode.y) < _err) {   //Found the destination
//				print("found end");
				
				_done = true;
				this.LastScore = node.f;
//				if(_reduc == 99)
//					return node.f;

				//BUILD PATH USING REFRENCED PARENTS
				var donebuild = false;
				ptd.push(node);
				if (ptd[ptd.length-1].parent!=-1) do {
					ptd.push(ptd[ptd.length-1].parent);
					if (ptd[ptd.length-1].parent==-1)
						donebuild=true;
				} while (!donebuild);
				
				// Reverse the path
				for (var d = ptd.length-1; d>=0; d--) {
					fp.push(ptd[d]);
				}								
				
				this.Path = new Array();
				//Put the offset back in and move to path
				for (var d = 0; d<fp.length; d++)
					this.Path[d] = {x:fp[d].x + minx, y:fp[d].y + miny}

//				print("Total pathing time: " + (new Date() - stime));
				return this.Path;

			}
			else {  		// look for adjacent blocks that we attach to and add them to open
				
				// Check for already visited point
//				if (AreaData[node.y][node.x] & 0x100000) continue;
				
				// Check for previous nodes... obfuscation
				for (var i = 0; i < nodecenters.length; i++) {
					if (nodecenters[i].id != node.parent.id) {
						if (mbm_PointInCircle(nodecenters[i], distsq, node)) {
							// print("in circle, skipping");
							continue nextnode;
						}
					}
				}

//				if (!_isopen(AreaData, node.x, node.y)) {
//					continue;
//				}
//				nodecenters.push(node);

//				for (i = 0; i < pointset.length; i++) {
//					points.push({x:pointset[i].x + node.x,y:pointset[i].y + node.y});
//				}
//				points = mbm_CalcPointSet(node.x, node.y, _dist, _dstep, _rstep, 0);

//				print("Adding " + points.length + " points");

				nextpoint:
				for (var i = 0; i < pointset[0].length; i++) {
					for (var dd = 0; dd < sets; dd++) {
						cx = parseInt(pointset[dd][i].x + node.x);
						cy = parseInt(pointset[dd][i].y + node.y);
						
//						print("height " + height + " cy: " + cy + " pointset["+dd+"]["+i+"]: " + p2s(pointset[dd][i]) + " d: " + dd);
					
						//check for map edge
						if (cy <= 1 || cy >= height - 1 || cx <= 1 || cx >= width - 1) continue;

						//check for walkability and small diagonal gaps that cant be passed
						if (!DontLoadRooms) {
							if (AreaData[cy][cx] == undefined) {
								if (DelayLoadRooms) {
									this.LoadPos(cx + this.minx, cy + this.miny); 
									if (AreaData[cy][cx] == undefined) continue;
								} else continue;
							}
							if (AreaData[cy][cx] & 1) continue;
							if (!_isopen(AreaData, cx, cy)) continue;
						} else {
							var v = this.RoomXY(cx + minx, cy + miny);
							if (v & 1) continue;
							if (!this.IsOpenXY(cx + minx, cy + miny)) continue;
						}
							
						// Check for previous nodes... obfuscation
	//					for (var xxx = 0; xxx < nodecenters.length; xxx++) {
	//						if (nodecenters[xxx].id == node.parent.id) {
	//							if (mbm_PointInCircle(nodecenters[xxx], distsq - 4, {x:cx,y:cy})) {
	//								// print("in circle, skipping");
	//								continue nextpoint;
	//							}
	//						}
	//					}
	
	//					if ((vx*vy) && (AreaData[cy][node.x] & 1) && (AreaData[node.y][cx] & 1)) continue;
	
						// Find an "opener" space
						// node = _findopener(AreaData, node);
						
	
	
	//					newg = node.g + points[i].dist; // SCORE[Math.abs(vx*vy)];
						newg = node.g + 1;
	
						var cnode = ng[cy][cx];
						var fh = this.sorcheuristic(dx,dy,cx,cy,_dist);
						// var fh = this[FORWARDHEURISTICS[_fh]](dx, dy, cx, cy)*_factor;
	
						if(!cnode) {
							cnode = new oNode(cx,cy,false,false,node,newg,fh);
//							cnode = new oNode(cx,cy,false,false,node,node.g+1,this.sorcheuristic(dx,dy,cx,cy,_dist));
							ng[cy][cx] = cnode;
						}
						else {
							if (cnode.g > newg){
								cnode.closed = false;
								cnode.g = newg;
								cnode.parent = node;
							}
							else continue;
						}
						cnode.f = cnode.g + cnode.h;
	
						if(!cnode.open) {
							cnode.open = true;
							oq.Insert(cnode);
							//AreaData[cnode.y][cnode.x] |= 0x200000;
						}

						continue nextpoint;						
					}
				}
				
				me.overhead(oq.getLength() + " nodes");
//				me.overhead(p2s({x:node.x + minx,y:node.y+miny}));
//				print(p2s({x:node.x + minx,y:node.y+miny}));
//				delay(30);
				node.open = false;	node.closed = true;
//				AreaData[node.y][node.x] |= 0x100000;
				nodecenters.push(node);
			}
		}
		print("Couldnt find a path to destination");
		return false;
	}




	function oMap_findscore(x1, y1, x2, y2)
	{
		return this.findpath(x1, y1, x2, y2, 0, 99, 0, 4, 1.5);
	}

	function oMap_pathmove(pathtodest, walkcallflag, pointtostart, recalcmaxdist, recalcalgotype, factor)
	{
		if(!pathtodest) pathtodest = this.Path;
		if(!pointtostart) pointtostart = 0;
		if(!recalcmaxdist) recalcmaxdist = 2;
		if(!recalcalgotype) recalcalgotype = mlASTAR;
		if(!factor) factor = 1.2;
		var failedhops = 0;
		for (var i=pointtostart; i<pathtodest.length; i++)
		{
			mlprint("moving to " + pathtodest[i].x + ", " + pathtodest[i].y);
			if(me.classid == 1 && !mlInTown(me)) var retval = mlteleportto(pathtodest[i].x, pathtodest[i].y, walkcallflag, i);
			else var retval = mlwalkto(pathtodest[i].x, pathtodest[i].y, walkcallflag, i);
			if (!retval)
			{
				if(me.area != this.AreaInitialized);
					this.InitializeMap();

				print("First destination failed, attempting recalculating a course to the next coordinate");
				var midpath = this.FindPath(me.x, me.y, pathtodest[i].x, pathtodest[i].y, recalcmaxdist, 0, recalcalgotype, 4);
				if (!midpath)
				{
					mlprint("mlMap:mlWalkThePath - Couldn't recalculate a path");
					this.LastError = "mlMap:mlWalkThePath - Couldn't recalculate a path";
					return false;
				}
				for(var k = 0; k<midpath.length; k++) {
					if(me.classid == 1 && !mlInTown(me))	retval = mlteleportto(midpath[k].x, midpath[k].y, walkcallflag, i);
					else retval = mlwalkto(midpath[k].x, midpath[k].y, walkcallflag, i);
				}
			}

			else if (retval > mlSTEPAHEAD && retval < mlSTEPBACK) {		// step ahead
					i += (retval - mlSTEPAHEAD); continue; }
			else if (retval > mlSTEPBACK)//step back
			{
				print("(retval - mlSTEPBACK):" + (retval - mlSTEPBACK));
				for (var j = i; j > i - (retval - mlSTEPBACK); j--) {
					if(me.classid == 1)	mlteleportto(pathtodest[j].x, pathtodest[j].y, false);
					else mlwalkto(pathtodest[j].x, pathtodest[j].y, false);
				}
				i -= (retval - mlSTEPBACK);
				continue;
			}
			else if (retval == mlSTOP) {					//step back
					return mlSTOP; }
			if (!retval)
			{
				print("We couldnt find a way to the next path point");
				if(failedhops == 5)
				{
					mlprint("mlMap:mlWalkThePath - had five failed destinations along this path");
					this.LastError = "mlMap:mlWalkThePath - had five failed destinations along this path";
					return false;
				}
				failedhops++;
			}
			//delay(50);
		}
		return true;
	}

	//////////////////////////////////////////////////////////////////////
	// Forward Heuristics functions - DO NOT TOUCH
	// -------------------------------------------------------------------
	//////////////////////////////////////////////////////////////////////
	this.manhattan = function(x1, y1, x2, y2) {
		return Math.abs(x2-x1) + Math.abs(y2-y1);
	}
	this.euclidian = function(x1, y1, x2, y2) {
		return Math.floor(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
	}
	this.euclidiannosqrt = function(x1, y1, x2, y2) {
		return Math.floor((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	}
	this.nofh = function(x1, y1, x2, y2) {
		return 0;
	}
	this.diagshortcut = function(x1, y1, x2, y2) {
		var dy = Math.abs(y2-y1);
		var dx = Math.abs(x2-x1);
		if (dy <= dx) return dy*0.414 + dx; else return dx*0.414 + dy;
	}
	this.maxdxdy = function(x1, y1, x2, y2) {
		var dy = Math.abs(y2-y1);
		var dx = Math.abs(x2-x1);
		return (dx>dy)?dx:dy;
	}
	this.sorcheuristic = function(x1, y1, x2, y2, teledist) {
		return Math.floor(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) / teledist);
	}
	//////////////////////////////////////////////////////////////////////
	// misc private functions
	// -------------------------------------------------------------------
	//////////////////////////////////////////////////////////////////////
	// _isinrange
	function _isinrange(_x, _y) {
		if(_x > this.maxx-1 || _x < this.minx || _y > this.maxy-1 || _y < this.miny)
			return false;
		else
			return true;
	}

	// updateterminal
	function updateterminal(area, nx, ny) {
		var mx = nx - Math.floor(pdis.Columns/2);
		var my = ny - Math.floor(pdis.Rows/2);
		for(var yy = 0; yy<pdis.Rows; yy++){
			for(var xx = 0; xx<pdis.Columns; xx++){
				if(!area[my+yy] && !area[my+yy][mx+xx]) {
					pdis.Poke(yy, xx, " ");
					continue;
				}
				if(area[my+yy][mx+xx] & 1)
					pdis.Poke(yy, xx, "X");
				else if(area[my+yy][mx+xx] & 0x10000)
					pdis.Poke(yy, xx, "1");
				else if(area[my+yy][mx+xx] & 0x20000)
					pdis.Poke(yy, xx, "2");
				else if(area[my+yy][mx+xx] & 0x40000)
					pdis.Poke(yy, xx, "3");
				else if(area[my+yy][mx+xx] & 0x80000)
					pdis.Poke(yy, xx, "4");
				else if(area[my+yy][mx+xx] & 0x100000)
					pdis.Poke(yy, xx, "+");
				else if(area[my+yy][mx+xx] & 0x200000)
					pdis.Poke(yy, xx, "-");
				else
					pdis.Poke(yy, xx, " ");
			}
		}
	}

	function _findopener(area, node)
	{
		if (_isopen(area, node.x, node.y))
			return node;
		
		for (var vy = -1; vy <= 1; vy++)
			for (var vx = -1; vx <= 1; vx++)
				if (_isopen(area, vx, vy)) {
					node.x = vx;
					node.y = vy;
					return node;
				}
		print("no opener found");
		delay(100);
		return node;
	}
	
	function _isopen(area, x, y) {
		if (x < 1) x = 1;
		if (y < 1) y = 1;
		for (var vy = y-1; vy <= y+1; vy++)
			for (var vx = x-1; vx <= x+1; vx++)
				if (area[vy][vx] & 1 || area[vy][vx] == undefined)
					return false;
		return true;
	}

	function _isopenxy(x, y) {
		if (x < 1) x = 1;
		if (y < 1) y = 1;
		var v;
		for (var vy = y-1; vy <= y+1; vy++)
			for (var vx = x-1; vx <= x+1; vx++) {
				v = this.RoomXY(vx, vy);
				if (v & 1 || v == undefined)
					return false;
			}
		return true;
	}
	
	function _xy(x, y) {
		// Todo: sort rooms & do binary search, woohoo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -