Пример #1
0
void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_EMState == CHASING)
	{
		CheckEventLostPlayer();
	}
	else
	{
		CheckEventSeePlayer();
	}

	if (m_Target == NULL)
		return;

	cTracer LineOfSight(GetWorld());
	Vector3d AttackDirection(m_Target->GetPosition() - GetPosition());

	if (ReachedFinalDestination() && !LineOfSight.Trace(GetPosition(), AttackDirection, (int)AttackDirection.Length()))
	{
		// Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
		Attack(a_Dt / 1000);
	}
}
Пример #2
0
void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
    super::Tick(a_Dt, a_Chunk);

    if (m_EMState == CHASING)
    {
        CheckEventLostPlayer();
    }
    else
    {
        CheckEventSeePlayer();
    }

    if (m_Target == nullptr)
    {
        return;
    }

    cTracer LineOfSight(GetWorld());
    Vector3d MyHeadPosition = GetPosition() + Vector3d(0, GetHeight(), 0);
    Vector3d AttackDirection(m_Target->GetPosition() + Vector3d(0, m_Target->GetHeight(), 0) - MyHeadPosition);


    if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) && (GetHealth() > 0.0))
    {
        // Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
        StopMovingToPosition();
        Attack(a_Dt);
    }
}
Пример #3
0
void cPassiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_EMState == ESCAPING)
	{
		CheckEventLostPlayer();
	}
	cItem FollowedItem = GetFollowedItem();
	if (FollowedItem.IsEmpty())
	{
		return;
	}
	cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance);
	if (a_Closest_Player != nullptr)
	{
		if (a_Closest_Player->GetEquippedItem().IsEqual(FollowedItem))
		{
			Vector3d PlayerPos = a_Closest_Player->GetPosition();
			MoveToPosition(PlayerPos);
		}
	}
}
Пример #4
0
void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);
	if (!IsTicking())
	{
		// The base class tick destroyed us
		return;
	}

	if (m_EMState == CHASING)
	{
		CheckEventLostPlayer();
	}
	else
	{
		CheckEventSeePlayer(a_Chunk);
	}

	auto target = GetTarget();
	if (target == nullptr)
	{
		return;
	}

	// TODO: Currently all mobs see through lava, but only Nether-native mobs should be able to.
	Vector3d MyHeadPosition = GetPosition() + Vector3d(0, GetHeight(), 0);
	Vector3d TargetPosition = target->GetPosition() + Vector3d(0, target->GetHeight(), 0);
	if (
		TargetIsInRange() &&
		cLineBlockTracer::LineOfSightTrace(*GetWorld(), MyHeadPosition, TargetPosition, cLineBlockTracer::losAirWaterLava) &&
		(GetHealth() > 0.0)
	)
	{
		// Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
		Attack(a_Dt);
	}
}
Пример #5
0
void cAggressiveMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	m_SeePlayerInterval += a_Dt;

	if (m_SeePlayerInterval > 1)
	{
		int rem = m_World->GetTickRandomNumber(3) + 1;  // Check most of the time but miss occasionally

		m_SeePlayerInterval = 0.0;
		if (rem >= 2)
		{
			if (m_EMState == CHASING)
			{
				CheckEventLostPlayer();
			}
			else
			{
				CheckEventSeePlayer();
			}
		}
	}
}
Пример #6
0
void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);
	if (!IsTicking())
	{
		// The base class tick destroyed us
		return;
	}

	if (m_EMState == ESCAPING)
	{
		CheckEventLostPlayer();
	}

	// if we have a partner, mate
	if (m_LovePartner != nullptr)
	{

		if (m_MatingTimer > 0)
		{
			// If we should still mate, keep bumping into them until baby is made
			Vector3d Pos = m_LovePartner->GetPosition();
			MoveToPosition(Pos);
		}
		else
		{
			// Mating finished. Spawn baby
			Vector3f Pos = (GetPosition() + m_LovePartner->GetPosition()) * 0.5;
			UInt32 BabyID = m_World->SpawnMob(Pos.x, Pos.y, Pos.z, GetMobType(), true);

			cPassiveMonster * Baby = nullptr;

			m_World->DoWithEntityByID(BabyID, [&](cEntity & a_Entity)
				{
					Baby = static_cast<cPassiveMonster *>(&a_Entity);
					return true;
				}
			);

			if (Baby != nullptr)
			{
				Baby->InheritFromParents(this, m_LovePartner);
			}

			m_World->SpawnExperienceOrb(Pos.x, Pos.y, Pos.z, GetRandomProvider().RandInt(1, 6));

			m_LovePartner->ResetLoveMode();
			ResetLoveMode();
		}
	}
	else
	{
		// We have no partner, so we just chase the player if they have our breeding item
		cItems FollowedItems;
		GetFollowedItems(FollowedItems);
		if (FollowedItems.Size() > 0)
		{
			cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance));
			if (a_Closest_Player != nullptr)
			{
				cItem EquippedItem = a_Closest_Player->GetEquippedItem();
				if (FollowedItems.ContainsType(EquippedItem))
				{
					Vector3d PlayerPos = a_Closest_Player->GetPosition();
					MoveToPosition(PlayerPos);
				}
			}
		}
	}

	// If we are in love mode but we have no partner, search for a partner neabry
	if (m_LoveTimer > 0)
	{
		if (m_LovePartner == nullptr)
		{
			m_World->ForEachEntityInBox(cBoundingBox(GetPosition(), 8, 8), [=](cEntity & a_Entity)
				{
					// If the entity is not a monster, don't breed with it
					// Also, do not self-breed
					if ((a_Entity.GetEntityType() != etMonster) || (&a_Entity == this))
					{
						return false;
					}

					auto & Me = static_cast<cPassiveMonster&>(*this);
					auto & PotentialPartner = static_cast<cPassiveMonster&>(a_Entity);

					// If the potential partner is not of the same species, don't breed with it
					if (PotentialPartner.GetMobType() != Me.GetMobType())
					{
						return false;
					}

					// If the potential partner is not in love
					// Or they already have a mate, do not breed with them
					if ((!PotentialPartner.IsInLove()) || (PotentialPartner.GetPartner() != nullptr))
					{
						return false;
					}

					// All conditions met, let's breed!
					PotentialPartner.EngageLoveMode(&Me);
					Me.EngageLoveMode(&PotentialPartner);
					return true;
				}
			);
		}

		m_LoveTimer--;
	}
	if (m_MatingTimer > 0)
	{
		m_MatingTimer--;
	}
	if (m_LoveCooldown > 0)
	{
		m_LoveCooldown--;
	}
}