Esempio n. 1
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);
    }
}
Esempio n. 2
0
void cCreeper::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 (((GetTarget() == nullptr) || !TargetIsInRange()) && !m_BurnedWithFlintAndSteel)
	{
		if (m_bIsBlowing)
		{
			m_ExplodingTimer = 0;
			m_bIsBlowing = false;
			m_World->BroadcastEntityMetadata(*this);
		}
	}
	else
	{
		if (m_bIsBlowing)
		{
			m_ExplodingTimer += 1;
		}

		if ((m_ExplodingTimer == 30) && (GetHealth() > 0.0))  // only explode when not already dead
		{
			m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this);
			Destroy();  // Just in case we aren't killed by the explosion
		}
	}
}
Esempio n. 3
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);
	}
}
Esempio n. 4
0
void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
	if (!IsAngry())
	{
		cMonster::Tick(a_Dt, a_Chunk);
		if (m_NotificationCooldown > 0)
		{
			m_NotificationCooldown -= 1;
		}
	}
	else
	{
		super::Tick(a_Dt, a_Chunk);
	}

	if (!IsTicking())
	{
		// The base class tick destroyed us
		return;
	}

	if (GetTarget() == nullptr)
	{
		m_World->DoWithNearestPlayer(GetPosition(), static_cast<float>(m_SightDistance), [&](cPlayer & a_Player) -> bool
		{
			switch (a_Player.GetEquippedItem().m_ItemType)
			{
				case E_ITEM_BONE:
				case E_ITEM_RAW_BEEF:
				case E_ITEM_STEAK:
				case E_ITEM_RAW_CHICKEN:
				case E_ITEM_COOKED_CHICKEN:
				case E_ITEM_ROTTEN_FLESH:
				case E_ITEM_RAW_PORKCHOP:
				case E_ITEM_COOKED_PORKCHOP:
				{
					if (!IsBegging())
					{
						SetIsBegging(true);
						m_World->BroadcastEntityMetadata(*this);
					}

					m_FinalDestination = a_Player.GetPosition();  // So that we will look at a player holding food

					// Don't move to the player if the wolf is sitting.
					if (!IsSitting())
					{
						MoveToPosition(a_Player.GetPosition());
					}

					break;
				}
				default:
				{
					if (IsBegging())
					{
						SetIsBegging(false);
						m_World->BroadcastEntityMetadata(*this);
					}
				}
			}

			return true;
		});
	}
	else
	{
		if (IsSitting())
		{
			SetTarget(nullptr);
		}
		else
		{
			MoveToPosition(GetTarget()->GetPosition());
			if (TargetIsInRange())
			{
				Attack(a_Dt);
			}
		}
	}

	if (IsTame() && !IsSitting())
	{
		TickFollowPlayer();
	}
	else if (IsSitting())
	{
		StopMovingToPosition();
	}
}