示例#1
0
bool M_PathFinding::StepUp()
{
	bool ret = true;
	if (!pathFinished)
	{
		if (openList.count() > 0)
		{
			if (!newLowest)
			{
				lowestFNode = GetLowestF();
				lowestF = lowestFNode->data->f;
			}
			newLowest = false;
			if (AddChilds(lowestFNode, endTile))
			{
				FinishPathFinding(path);
			}
		}
		else
		{
			if (pathStarted)
				LOG("-- Pathfinding: Could not find a path --");
			pathFinished = true;
			pathStarted = false;

		}
	}
	return ret;
}
示例#2
0
void cMonster::MoveToPosition(const Vector3d & a_Position)
{
	FinishPathFinding();

	m_FinalDestination = a_Position;
	m_bMovingToDestination = true;
	TickPathFinding();
}
示例#3
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	if ((m_Target != NULL) && m_Target->IsDestroyed())
		m_Target = NULL;

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		if (m_bOnGround)
		{
			m_Destination.y = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z);

			if (DoesPosYRequireJump((int)floor(m_Destination.y)))
			{
				m_bOnGround = false;
				AddPosY(1.5); // Jump!!
			}
		}

		Vector3f Distance = m_Destination - GetPosition();
		if(!ReachedDestination() && !ReachedFinalDestination()) // If we haven't reached any sort of destination, move
		{
			Distance.y = 0;
			Distance.Normalize();
			Distance *= 5;
			SetSpeedX(Distance.x);
			SetSpeedZ(Distance.z);

			if (m_EMState == ESCAPING)
			{	//Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
		}
		else
		{
			if (ReachedFinalDestination()) // If we have reached the ultimate, final destination, stop pathfinding and attack if appropriate
			{
				FinishPathFinding();
			}
			else
			{
				TickPathFinding(); // We have reached the next point in our path, calculate another point
			}
		}
	}

	SetPitchAndYawFromDestination();
	HandleFalling();

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}	
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}	
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
	}  // switch (m_EMState)

	BroadcastMovementUpdate();
}
示例#4
0
void cMonster::TickPathFinding()
{
	const int PosX = POSX_TOINT;
	const int PosY = POSY_TOINT;
	const int PosZ = POSZ_TOINT;

	m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z);

	std::vector<Vector3d> m_PotentialCoordinates;
	m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ));

	static const struct // Define which directions to try to move to
	{
		int x, z;
	} gCrossCoords[] =
	{
		{ 1, 0},
		{-1, 0},
		{ 0, 1},
		{ 0,-1},
	} ;
	
	if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */)
	{
		// Too low/high, can't really do anything
		FinishPathFinding();
		return;
	}

	for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
	{
		if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ)))
		{
			continue;
		}

		BLOCKTYPE BlockAtY = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ);
		BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ);
		BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ);
		int LowestY = FindFirstNonAirBlockPosition(gCrossCoords[i].x + PosX, gCrossCoords[i].z + PosZ);
		BLOCKTYPE BlockAtLowestY = m_World->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ);

		if (
			(!cBlockInfo::IsSolid(BlockAtY)) &&
			(!cBlockInfo::IsSolid(BlockAtYP)) &&
			(!IsBlockLava(BlockAtLowestY)) &&
			(BlockAtLowestY != E_BLOCK_CACTUS) &&
			(PosY - LowestY < FALL_DAMAGE_HEIGHT)
			)
		{
			m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ));
		}
		else if (
			(cBlockInfo::IsSolid(BlockAtY)) &&
			(BlockAtY != E_BLOCK_CACTUS) &&
			(!cBlockInfo::IsSolid(BlockAtYP)) &&
			(!cBlockInfo::IsSolid(BlockAtYPP)) &&
			(BlockAtY != E_BLOCK_FENCE) &&
			(BlockAtY != E_BLOCK_FENCE_GATE)
			)
		{
			m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ));
		}
	}

	if (!m_PotentialCoordinates.empty())
	{
		Vector3f ShortestCoords = m_PotentialCoordinates.front();
		for (std::vector<Vector3d>::const_iterator itr = m_PotentialCoordinates.begin(); itr != m_PotentialCoordinates.end(); ++itr)
		{
			Vector3f Distance = m_FinalDestination - ShortestCoords;
			Vector3f Distance2 = m_FinalDestination - *itr;
			if (Distance.SqrLength() > Distance2.SqrLength())
			{
				ShortestCoords = *itr;
			}
		}

		m_Destination = ShortestCoords;
		m_Destination.z += 0.5f;
		m_Destination.x += 0.5f;
	}
	else
	{
		FinishPathFinding();
	}
}
示例#5
0
void cMonster::TickPathFinding()
{
	int PosX = (int)floor(GetPosX());
	int PosY = (int)floor(GetPosY());
	int PosZ = (int)floor(GetPosZ());

	m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z);

	std::vector<Vector3d> m_PotentialCoordinates;
	m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ));

	static const struct // Define which directions to try to move to
	{
		int x, z;
	} gCrossCoords[] =
	{
		{ 1, 0},
		{-1, 0},
		{ 0, 1},
		{ 0,-1},
	} ;

	for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
	{
		if ((gCrossCoords[i].x + PosX == PosX) && (gCrossCoords[i].z + PosZ == PosZ))
		{
			continue;
		}

		if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ)))
		{
			continue;
		}

		BLOCKTYPE BlockAtY = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ);
		BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ);
		BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ);
		BLOCKTYPE BlockAtYM = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY - 1, gCrossCoords[i].z + PosZ);

		if ((!g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE))
		{
			m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ));
		}
		else if ((g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!g_BlockIsSolid[BlockAtYPP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE))
		{
			m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ));
		}
	}

	if (!m_PotentialCoordinates.empty())
	{
		Vector3f ShortestCoords = m_PotentialCoordinates.front();
		for (std::vector<Vector3d>::const_iterator itr = m_PotentialCoordinates.begin(); itr != m_PotentialCoordinates.end(); ++itr)
		{
			Vector3f Distance = m_FinalDestination - ShortestCoords;
			Vector3f Distance2 = m_FinalDestination - *itr;
			if (Distance.SqrLength() > Distance2.SqrLength())
			{
				ShortestCoords = *itr;
			}
		}

		m_Destination = ShortestCoords;
		m_Destination.z += 0.5f;
		m_Destination.x += 0.5f;
	}
	else
	{
		FinishPathFinding();
	}
}
示例#6
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	if ((m_Target != NULL) && m_Target->IsDestroyed())
		m_Target = NULL;

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		if (m_bOnGround)
		{
			if (DoesPosYRequireJump((int)floor(m_Destination.y)))
			{
				m_bOnGround = false;

				// TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport
				AddPosY(1.2);  // Jump!!
			}
		}

		Vector3d Distance = m_Destination - GetPosition();
		if (!ReachedDestination() && !ReachedFinalDestination())  // If we haven't reached any sort of destination, move
		{
			Distance.y = 0;
			Distance.Normalize();

			if (m_bOnGround)
			{
				Distance *= 2.5f;
			}
			else if (IsSwimming())
			{
				Distance *= 1.3f;
			}
			else
			{
				// Don't let the mob move too much if he's falling.
				Distance *= 0.25f;
			}

			// Apply walk speed:
			Distance *= m_RelativeWalkSpeed;

			AddSpeedX(Distance.x);
			AddSpeedZ(Distance.z);

			// It's too buggy!
			/*
			if (m_EMState == ESCAPING)
			{
				// Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
			*/
		}
		else
		{
			if (ReachedFinalDestination())  // If we have reached the ultimate, final destination, stop pathfinding and attack if appropriate
			{
				FinishPathFinding();
			}
			else
			{
				TickPathFinding();  // We have reached the next point in our path, calculate another point
			}
		}
	}

	SetPitchAndYawFromDestination();
	HandleFalling();

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
			
		case ATTACKING: break;
	}  // switch (m_EMState)

	BroadcastMovementUpdate();
}