コード例 #1
0
void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, MobMovementMode mode)
{
	PathfinderOptions opts;
	opts.smooth_path = true;
	opts.step_size = RuleR(Pathing, NavmeshStepSize);
	opts.offset = who->GetZOffset();
	opts.flags = PathingNotDisabled ^ PathingZoneLine;

	//This is probably pointless since the nav mesh tool currently sets zonelines to disabled anyway
	auto partial = false;
	auto stuck = false;
	auto route = zone->pathing->FindPath(
		glm::vec3(who->GetX(), who->GetY(), who->GetZ()),
		glm::vec3(x, y, z),
		partial,
		stuck,
		opts);

	auto eiter = _impl->Entries.find(who);
	auto &ent = (*eiter);

	if (route.size() == 0) {
		HandleStuckBehavior(who, x, y, z, mode);
		return;
	}

	AdjustRoute(route, who);
	   
	
	
	//avoid doing any processing if the mob is stuck to allow normal stuck code to work.
	if (!stuck)
	{

		//there are times when the routes returned are no differen than where the mob is currently standing. What basically happens
		//is a mob will get 'stuck' in such a way that it should be moving but the 'moving' place is the exact same spot it is at. 
		//this is a problem and creates an area of ground that if a mob gets to, will stay there forever. If socal this creates a 
		//"Ball of Death" (tm). This code tries to prevent this by simply warping the mob to the requested x/y. Better to have a warp than 
		//have stuck mobs.

		auto routeNode = route.begin();
		bool noValidPath = true;
		while (routeNode != route.end() && noValidPath == true) {
			auto &currentNode = (*routeNode);

			if (routeNode == route.end())
			{
				continue;
			}

			if (!(currentNode.pos.x == who->GetX() && currentNode.pos.y == who->GetY()))
			{
				//if one of the nodes to move to, is not our current node, pass it.
				noValidPath = false;
				break;
			}
			//move to the next node
			routeNode++;

		}

		if (noValidPath)
		{
			//we are 'stuck' in a path, lets just get out of this by 'teleporting' to the next position.
			PushTeleportTo(ent.second, x, y, z,
				CalculateHeadingAngleBetweenPositions(who->GetX(), who->GetY(), x, y));
			return;
		}

	}
	
	auto iter = route.begin();
	glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ());
	bool first_node = true;


	while (iter != route.end()) {
		auto &current_node = (*iter);
	
		iter++;
	
		if (iter == route.end()) {
			continue;
		}
	
		previous_pos = current_node.pos;
		auto &next_node = (*iter);
	
		if (first_node) {
	
			if (mode == MovementWalking) {
				auto h = who->CalculateHeadingToTarget(next_node.pos.x, next_node.pos.y);
				PushRotateTo(ent.second, who, h, mode);
			}
	
			first_node = false;
		}
	
		//move to / teleport to node + 1
		if (next_node.teleport && next_node.pos.x != 0.0f && next_node.pos.y != 0.0f) {
			PushTeleportTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z,
				CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y));
		}
		else {
			if (zone->watermap->InLiquid(previous_pos)) {
				PushSwimTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
			}
			else {
				PushMoveTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
			}
		}
	}

	if (stuck) {
		HandleStuckBehavior(who, x, y, z, mode);
	}
	else {
		PushStopMoving(ent.second);
	}
}
コード例 #2
0
void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode mode)
{
	auto eiter = _impl->Entries.find(who);
	auto &ent = (*eiter);
	if (zone->watermap->InLiquid(who->GetPosition()) && zone->watermap->InLiquid(glm::vec3(x, y, z)) && zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z))) {
		PushSwimTo(ent.second, x, y, z, mode);
		PushStopMoving(ent.second);
		return;
	}

	PathfinderOptions opts;
	opts.smooth_path = true;
	opts.step_size = RuleR(Pathing, NavmeshStepSize);
	opts.offset = who->GetZOffset();
	opts.flags = PathingNotDisabled ^ PathingZoneLine;

	auto partial = false;
	auto stuck = false;
	auto route = zone->pathing->FindPath(
		glm::vec3(who->GetX(), who->GetY(), who->GetZ()),
		glm::vec3(x, y, z),
		partial,
		stuck,
		opts);

	if (route.size() == 0) {
		HandleStuckBehavior(who, x, y, z, mode);
		return;
	}

	AdjustRoute(route, who);

	auto iter = route.begin();
	glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ());
	bool first_node = true;

	while (iter != route.end()) {
		auto &current_node = (*iter);

		if (!zone->watermap->InLiquid(current_node.pos)) {
			stuck = true;

			while (iter != route.end()) {
				iter = route.erase(iter);
			}

			break;
		}
		else {
			iter++;
		}
	}

	if (route.size() == 0) {
		HandleStuckBehavior(who, x, y, z, mode);
		return;
	}

	iter = route.begin();

	while (iter != route.end()) {
		auto &current_node = (*iter);

		iter++;

		if (iter == route.end()) {
			continue;
		}

		previous_pos = current_node.pos;
		auto &next_node = (*iter);

		if (first_node) {

			if (mode == MovementWalking) {
				auto h = who->CalculateHeadingToTarget(next_node.pos.x, next_node.pos.y);
				PushRotateTo(ent.second, who, h, mode);
			}

			first_node = false;
		}

		//move to / teleport to node + 1
		if (next_node.teleport && next_node.pos.x != 0.0f && next_node.pos.y != 0.0f) {
			PushTeleportTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z,
				CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y));
		}
		else {
			PushSwimTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode);
		}
	}

	if (stuck) {
		HandleStuckBehavior(who, x, y, z, mode);
	}
	else {
		PushStopMoving(ent.second);
	}
}
コード例 #3
0
mvtype get_computer_move(struct postype brd)
{
  int i,j,oldval;
  time_t seconds;
  int top, bottom, prevscore;
  struct movelist moves;
  char goagain;
  mvtype legalmove, openmove;
  struct pathtype curr,path;
  struct postype newpos;
  int thismove, movesleft;
  char todepth;
  mainmover=brd.mvr;
#ifdef windowsearch
  prevscore=0;
#endif
  if (options.game!=REGULARCHESS || !options.library || no_more_openings || !get_opening(&openmove))
  {
	 //if (options.analysis)
	 show_blue_tiles();
	 if (!options.analysis) analoffmessg();
	 computer_move_displays();
	 show_mouse();
	 moves=get_children(&brd);
	 for (i=0; i<40; i++) dontmove[i].f=0;
	 game.movenum=game.movenum+1;
	 draws=0;
	 for (i=1; i<=moves.amount && draws<39; i++)
	 {
		 legalmove=moves.move[i];
		 alter(&brd,legalmove,&newpos);
		 if (previous_pos(newpos, game, 1))	dontmove[draws++]=legalmove;
	 }
	 // check for moves that may draw a position on next move
	 game.movenum=game.movenum-1;
	 nodes=0;
	 nomore=FALSE;
	 for (i=0; i<=11; i++) curr.move[i].f=0;
	 path.value=0;
	 nomore=FALSE;
	 make_current=TRUE;
	 switch (options.playstyle)
	 {
		case FIXEDLEVEL:todepth=options.maxdepth; break;
		case FIXEDTIME:todepth=16; maxtime=options.maxtime; break;
		case CHAMPIONSHIP:todepth=16; maxtime=(options.champtime*60/options.champmoves);
		     break;

	 }
	 g_depth=1;
	 for (i=0; i<32; i++) best_at[i].f=0;
	 for (iteration=1; iteration<=todepth && !nomore; iteration++)
	 {
	  oldval=path.value;
	  if (iteration<=2) quiescence_depth=0; else
			quiescence_depth=iteration+2;

	  path.move[0].f=0;

#ifdef windowsearch
	  top=prevscore+50;
	  bottom=prevscore-50;
	  do
	  {
	    goagain=0;
#else
	  top=32700;
	  bottom=-32700;
#endif
	    switch(options.game)
	    {
		 case KINGLET:kinglet_minimax(&brd,0,top,bottom,curr,&path,0); break;
		 case GIVEAWAY:giveaway_minimax(&brd,0,top,bottom,curr,&path,0); break;
		 case SHATRANJ:shatranj_minimax(&brd,0,top,bottom,curr,&path,FALSE,0); break;
		 case REGULARCHESS:minimax(&brd,0,top,bottom,curr,&path,FALSE,0);
	    }
	    for (i=0; path.move[i].f!=0 && i<8; i++) best_at[i]=path.move[i];
	    best_at[i].f=0;
	    if (path.value>9900)
	    {
		nomore=TRUE;
		make_current=TRUE;
	    }
#ifdef windowsearch
/*	    if (!(path.value>bottom && path.value<top))
	    {
	      top=32700;
	      bottom=-32700;
	      goagain=1;
	    } */
	    if (path.value<bottom)
	    {
	      bottom=-32700;
	      top=path.value;
	      goagain=1;
	    }
	    if (path.value>top)
	    {
	      top=32700;
	      bottom=path.value;
	      goagain=1;
	    }
	  } while (goagain);
	  prevscore=path.value;
#endif
	 }
  } else
  {
	 path.move[0]=openmove;
	 alter(&current, openmove, &newpos);
	 if (mainmover=='b')
		path.move[0].check=check(&newpos, newpos.wking[0]); else
		path.move[0].check=check(&newpos, newpos.bking[0]);
	 path.move[0].lastwin=current.brd[openmove.t];
	 make_current=TRUE;
  }
  if (path.move[0].f==0) make_current=FALSE; // if user requests to make current move then ensure that there is one!
  if (path.value<-10000)
  {
	  path.value=oldval;
  }
  if (nomore && !make_current)
  {
	 path.move[0].t=0;
  } else
  {
	 seconds=time(NULL)-starttime;
	 seconds+=seconds==0;
	 g_path=path;
	 g_seconds=seconds;
  }
  hide_mouse();
  if (options.analysis) display_score_slab(nodes,path.value);
  return(path.move[0]);
}