Esempio n. 1
0
void cMonster::MoveToWayPoint(cChunk & a_Chunk)
{
	if ((m_NextWayPointPosition - GetPosition()).SqrLength() < WAYPOINT_RADIUS * WAYPOINT_RADIUS)
	{
		return;
	}


	if (m_JumpCoolDown == 0)
	{
		if (DoesPosYRequireJump(FloorC(m_NextWayPointPosition.y)))
		{
			if (((IsOnGround()) && (GetSpeed().SqrLength() == 0.0f)) ||
			(IsSwimming()))
			{
				m_bOnGround = false;
				m_JumpCoolDown = 20;
				// TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport
				AddPosY(1.6);  // Jump!!
				SetSpeedX(3.2 * (m_NextWayPointPosition.x - GetPosition().x));  // Move forward in a preset speed.
				SetSpeedZ(3.2 * (m_NextWayPointPosition.z - GetPosition().z));  // The numbers were picked based on trial and error and 1.6 and 3.2 are perfect.
			}
		}
	}
	else
	{
		--m_JumpCoolDown;
	}

	Vector3d Distance = m_NextWayPointPosition - GetPosition();
	if ((Distance.x != 0.0f) || (Distance.z != 0.0f))
	{
		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;
		/* Reduced default speed.
		Close to Vanilla, easier for mobs to follow m_NextWayPointPositions, hence
		better pathfinding. */
		Distance *= 0.5;
		AddSpeedX(Distance.x);
		AddSpeedZ(Distance.z);
	}
}
Esempio n. 2
0
bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
{
    cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == NULL) ? -1 : m_Attachee->GetUniqueID()));
    int ChunkX, ChunkZ;
    cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ);
    m_World->ForEachEntityInChunk(ChunkX, ChunkZ, MinecartCollisionCallback);

    if (!MinecartCollisionCallback.FoundIntersection())
    {
        return false;
    }

    switch (a_RailMeta)
    {
    case E_META_RAIL_ZM_ZP:
    {
        if (MinecartCollisionCallback.GetCollidedEntityPosition().z >= GetPosZ())
        {
            if ((-GetSpeedZ() * 0.4) < 0.01)
            {
                AddSpeedZ(-4);
            }
            else
            {
                SetSpeedZ(-GetSpeedZ() * 0.4);
            }
        }
        else
        {
            if ((GetSpeedZ() * 0.4) < 0.01)
            {
                AddSpeedZ(4);
            }
            else
            {
                SetSpeedZ(GetSpeedZ() * 0.4);
            }
        }
        return true;
    }
    case E_META_RAIL_XM_XP:
    {
        if (MinecartCollisionCallback.GetCollidedEntityPosition().x >= GetPosX())
        {
            if ((-GetSpeedX() * 0.4) < 0.01)
            {
                AddSpeedX(-4);
            }
            else
            {
                SetSpeedX(-GetSpeedX() * 0.4);
            }
        }
        else
        {
            if ((GetSpeedX() * 0.4) < 0.01)
            {
                AddSpeedX(4);
            }
            else
            {
                SetSpeedX(GetSpeedX() * 0.4);
            }
        }
        return true;
    }
    case E_META_RAIL_CURVED_ZM_XM:
    case E_META_RAIL_CURVED_ZP_XP:
    {
        Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ());

        // Prevent division by small numbers
        if (abs(Distance.z) < 0.001)
        {
            Distance.z = 0.001;
        }

        /* Check to which side the minecart is to be pushed.
        Let's consider a z-x-coordinate system where the minecart is the center (0/0).
        The minecart moves along the line x = -z, the perpendicular line to this is x = z.
        In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */
        if (
            ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) ||
            ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1))
        )
        {
            // Moving -X +Z
            if ((-GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01)
            {
                // ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump!
                AddSpeedX(-4 / sqrt(2.0));
                AddSpeedZ(4 / sqrt(2.0));
            }
            else
            {
                // ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit.
                SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
                SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
            }
        }
        else if ((GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01)
        {
            // Moving +X -Z
            // ~ SpeedX <= 0 Immobile or not moving in the "right" direction
            AddSpeedX(4 / sqrt(2.0));
            AddSpeedZ(-4 / sqrt(2.0));
        }
        else
        {
            // ~ SpeedX > 0 Moving in the "right" direction
            SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
            SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
        }
        break;
    }
    case E_META_RAIL_CURVED_ZM_XP:
    case E_META_RAIL_CURVED_ZP_XM:
    {
        Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ());

        // Prevent division by small numbers
        if (abs(Distance.z) < 0.001)
        {
            Distance.z = 0.001;
        }

        /* Check to which side the minecart is to be pushed.
        Let's consider a z-x-coordinate system where the minecart is the center (0/0).
        The minecart moves along the line x = z, the perpendicular line to this is x = -z.
        In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */
        if (
            ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) ||
            ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1))
        )
        {
            // Moving +X +Z
            if ((GetSpeedX() * 0.4) < 0.01)
            {
                // ~ SpeedX <= 0 Immobile or not moving in the "right" direction
                AddSpeedX(4 / sqrt(2.0));
                AddSpeedZ(4 / sqrt(2.0));
            }
            else
            {
                // ~ SpeedX > 0 Moving in the "right" direction
                SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
                SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
            }
        }
        else if ((-GetSpeedX() * 0.4) < 0.01)
        {
            // Moving -X -Z
            // ~ SpeedX >= 0 Immobile or not moving in the "right" direction
            AddSpeedX(-4 / sqrt(2.0));
            AddSpeedZ(-4 / sqrt(2.0));
        }
        else
        {
            // ~ SpeedX < 0 Moving in the "right" direction
            SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
            SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
        }
        break;
    }
    default:
        break;
    }

    return false;
}
Esempio n. 3
0
void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
{
    // Initialise to 'slow down' values
    int AccelDecelSpeed = -2;
    int AccelDecelNegSpeed = 2;

    if ((a_RailMeta & 0x8) == 0x8)
    {
        // Rail powered - set variables to 'speed up' values
        AccelDecelSpeed = 1;
        AccelDecelNegSpeed = -1;
    }

    switch (a_RailMeta & 0x07)
    {
    case E_META_RAIL_ZM_ZP:  // NORTHSOUTH
    {
        SetYaw(270);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);
        SetSpeedX(0);

        bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta);
        if (EntCol || BlckCol) return;

        if (GetSpeedZ() != 0)
        {
            if (GetSpeedZ() > 0)
            {
                AddSpeedZ(AccelDecelSpeed);
            }
            else
            {
                AddSpeedZ(AccelDecelNegSpeed);
            }
        }
        break;
    }
    case E_META_RAIL_XM_XP:  // EASTWEST
    {
        SetYaw(180);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);
        SetSpeedZ(0);

        bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta);
        if (EntCol || BlckCol) return;

        if (GetSpeedX() != 0)
        {
            if (GetSpeedX() > 0)
            {
                AddSpeedX(AccelDecelSpeed);
            }
            else
            {
                AddSpeedX(AccelDecelNegSpeed);
            }
        }
        break;
    }
    case E_META_RAIL_ASCEND_XM:  // ASCEND EAST
    {
        SetYaw(180);
        SetSpeedZ(0);

        if (GetSpeedX() >= 0)
        {
            if (GetSpeedX() <= MAX_SPEED)
            {
                AddSpeedX(AccelDecelSpeed);
                SetSpeedY(-GetSpeedX());
            }
        }
        else
        {
            AddSpeedX(AccelDecelNegSpeed);
            SetSpeedY(-GetSpeedX());
        }
        break;
    }
    case E_META_RAIL_ASCEND_XP:  // ASCEND WEST
    {
        SetYaw(180);
        SetSpeedZ(0);

        if (GetSpeedX() > 0)
        {
            AddSpeedX(AccelDecelSpeed);
            SetSpeedY(GetSpeedX());
        }
        else
        {
            if (GetSpeedX() >= MAX_SPEED_NEGATIVE)
            {
                AddSpeedX(AccelDecelNegSpeed);
                SetSpeedY(GetSpeedX());
            }
        }
        break;
    }
    case E_META_RAIL_ASCEND_ZM:  // ASCEND NORTH
    {
        SetYaw(270);
        SetSpeedX(0);

        if (GetSpeedZ() >= 0)
        {
            if (GetSpeedZ() <= MAX_SPEED)
            {
                AddSpeedZ(AccelDecelSpeed);
                SetSpeedY(-GetSpeedZ());
            }
        }
        else
        {
            AddSpeedZ(AccelDecelNegSpeed);
            SetSpeedY(-GetSpeedZ());
        }
        break;
    }
    case E_META_RAIL_ASCEND_ZP:  // ASCEND SOUTH
    {
        SetYaw(270);
        SetSpeedX(0);

        if (GetSpeedZ() > 0)
        {
            AddSpeedZ(AccelDecelSpeed);
            SetSpeedY(GetSpeedZ());
        }
        else
        {
            if (GetSpeedZ() >= MAX_SPEED_NEGATIVE)
            {
                AddSpeedZ(AccelDecelNegSpeed);
                SetSpeedY(GetSpeedZ());
            }
        }
        break;
    }
    default:
        ASSERT(!"Unhandled powered rail metadata!");
        break;
    }
}
Esempio n. 4
0
void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt)
{
    /*
    NOTE: Please bear in mind that taking away from negatives make them even more negative,
    adding to negatives make them positive, etc.
    */

    switch (a_RailMeta)
    {
    case E_META_RAIL_ZM_ZP:  // NORTHSOUTH
    {
        SetYaw(270);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);  // Don't move vertically as on ground
        SetSpeedX(0);  // Correct diagonal movement from curved rails

        // Execute both the entity and block collision checks
        bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta);
        if (EntCol || BlckCol) return;

        if (GetSpeedZ() != 0)  // Don't do anything if cart is stationary
        {
            if (GetSpeedZ() > 0)
            {
                // Going SOUTH, slow down
                AddSpeedZ(-0.1);
            }
            else
            {
                // Going NORTH, slow down
                AddSpeedZ(0.1);
            }
        }
        break;
    }
    case E_META_RAIL_XM_XP:  // EASTWEST
    {
        SetYaw(180);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);
        SetSpeedZ(0);

        bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta);
        if (EntCol || BlckCol) return;

        if (GetSpeedX() != 0)
        {
            if (GetSpeedX() > 0)
            {
                AddSpeedX(-0.1);
            }
            else
            {
                AddSpeedX(0.1);
            }
        }
        break;
    }
    case E_META_RAIL_ASCEND_ZM:  // ASCEND NORTH
    {
        SetYaw(270);
        SetSpeedX(0);

        if (GetSpeedZ() >= 0)
        {
            // SpeedZ POSITIVE, going SOUTH
            if (GetSpeedZ() <= MAX_SPEED)  // Speed limit
            {
                AddSpeedZ(0.5);  // Speed up
                SetSpeedY(-GetSpeedZ());  // Downward movement is negative (0 minus positive numbers is negative)
            }
        }
        else
        {
            // SpeedZ NEGATIVE, going NORTH
            AddSpeedZ(1);  // Slow down
            SetSpeedY(-GetSpeedZ());  // Upward movement is positive (0 minus negative number is positive number)
        }
        break;
    }
    case E_META_RAIL_ASCEND_ZP:  // ASCEND SOUTH
    {
        SetYaw(270);
        SetSpeedX(0);

        if (GetSpeedZ() > 0)
        {
            // SpeedZ POSITIVE, going SOUTH
            AddSpeedZ(-1);  // Slow down
            SetSpeedY(GetSpeedZ());  // Upward movement positive
        }
        else
        {
            if (GetSpeedZ() >= MAX_SPEED_NEGATIVE)  // Speed limit
            {
                // SpeedZ NEGATIVE, going NORTH
                AddSpeedZ(-0.5);  // Speed up
                SetSpeedY(GetSpeedZ());  // Downward movement negative
            }
        }
        break;
    }
    case E_META_RAIL_ASCEND_XM:  // ASCEND EAST
    {
        SetYaw(180);
        SetSpeedZ(0);

        if (GetSpeedX() >= 0)
        {
            if (GetSpeedX() <= MAX_SPEED)
            {
                AddSpeedX(0.5);
                SetSpeedY(-GetSpeedX());
            }
        }
        else
        {
            AddSpeedX(1);
            SetSpeedY(-GetSpeedX());
        }
        break;
    }
    case E_META_RAIL_ASCEND_XP:  // ASCEND WEST
    {
        SetYaw(180);
        SetSpeedZ(0);

        if (GetSpeedX() > 0)
        {
            AddSpeedX(-1);
            SetSpeedY(GetSpeedX());
        }
        else
        {
            if (GetSpeedX() >= MAX_SPEED_NEGATIVE)
            {
                AddSpeedX(-0.5);
                SetSpeedY(GetSpeedX());
            }
        }
        break;
    }
    case E_META_RAIL_CURVED_ZM_XM:  // Ends pointing NORTH and WEST
    {
        SetYaw(315);  // Set correct rotation server side
        SetPosY(floor(GetPosY()) + 0.55);  // Levitate dat cart
        SetSpeedY(0);

        TestBlockCollision(a_RailMeta);
        TestEntityCollision(a_RailMeta);

        // SnapToRail handles turning

        break;
    }
    case E_META_RAIL_CURVED_ZM_XP:  // Curved NORTH EAST
    {
        SetYaw(225);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);

        TestBlockCollision(a_RailMeta);
        TestEntityCollision(a_RailMeta);

        break;
    }
    case E_META_RAIL_CURVED_ZP_XM:  // Curved SOUTH WEST
    {
        SetYaw(135);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);

        TestBlockCollision(a_RailMeta);
        TestEntityCollision(a_RailMeta);

        break;
    }
    case E_META_RAIL_CURVED_ZP_XP:  // Curved SOUTH EAST
    {
        SetYaw(45);
        SetPosY(floor(GetPosY()) + 0.55);
        SetSpeedY(0);

        TestBlockCollision(a_RailMeta);
        TestEntityCollision(a_RailMeta);

        break;
    }
    default:
    {
        ASSERT(!"Unhandled rail meta!");  // Dun dun DUN!
        break;
    }
    }
}
Esempio n. 5
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();
}