Exemplo n.º 1
0
int Game_Character::GetRealY() const {
	int y = GetY() * SCREEN_TILE_WIDTH;

	if (IsMoving()) {
		int d = GetDirection();
		if (d == Down || d == DownRight || d == DownLeft)
			y -= remaining_step;
		else if (d == Up || d == UpRight || d == UpLeft)
			y += remaining_step;
	} else if (IsJumping())
		y -= (GetY() - jump_y) * remaining_step;

	return y;
}
Exemplo n.º 2
0
int Game_Character::GetRealX() const {
	int x = GetX() * SCREEN_TILE_WIDTH;

	if (IsMoving()) {
		int d = GetDirection();
		if (d == Right || d == UpRight || d == DownRight)
			x -= remaining_step;
		else if (d == Left || d == UpLeft || d == DownLeft)
			x += remaining_step;
	} else if (IsJumping())
		x -= ((GetX() - jump_x) * remaining_step);

	return x;
}
Exemplo n.º 3
0
bool Game_Event::CheckEventTriggerTouch(int x, int y) {
	if (Game_Map::GetInterpreter().IsRunning())
		return false;

	if ((trigger == RPG::EventPage::Trigger_collision) && (Main_Data::game_player->IsInPosition(x, y))) {

		// TODO check over trigger VX differs from XP here
		if (!IsJumping()) {
			Start();
		}
	}

	return true;
}
Exemplo n.º 4
0
int Game_Character::GetScreenY() const {
	int y = GetRealY() / TILE_SIZE - Game_Map::GetDisplayY() / TILE_SIZE + TILE_SIZE;

	if (Game_Map::LoopVertical()) {
		int map_height = Game_Map::GetHeight() * TILE_SIZE;
		y = (y + map_height) % map_height;
	}

	if (IsJumping()) {
		int jump_height = (remaining_step > SCREEN_TILE_WIDTH / 2 ? SCREEN_TILE_WIDTH - remaining_step : remaining_step) / 8;
		y -= (jump_height < 5 ? jump_height * 2 : jump_height < 13 ? jump_height + 4 : 16);
	}

	return y;
}
Exemplo n.º 5
0
bool Game_Player::IsMovable() const {
	if (IsMoving() || IsJumping())
		return false;
	if (Graphics::IsTransitionPending())
		return false;
	if (IsMoveRouteOverwritten())
		return false;
	if (location.boarding || location.unboarding)
		return false;
	if (Game_Message::message_waiting)
		return false;
	if (InAirship() && !GetVehicle()->IsMovable())
		return false;
    return true;
}
Exemplo n.º 6
0
void Game_Vehicle::SyncWithPlayer() {
	SetX(Main_Data::game_player->GetX());
	SetY(Main_Data::game_player->GetY());
	SetRemainingStep(Main_Data::game_player->GetRemainingStep());
	SetJumping(Main_Data::game_player->IsJumping());
	SetBeginJumpX(Main_Data::game_player->GetBeginJumpX());
	SetBeginJumpY(Main_Data::game_player->GetBeginJumpY());
	if (!IsAscendingOrDescending()) {
		SetDirection(Main_Data::game_player->GetDirection());
		SetSpriteDirection(Main_Data::game_player->GetSpriteDirection());
	} else {
		if (!IsMoving() && !IsJumping()) {
			SetDirection(Left);
			SetSpriteDirection(Left);
		}
	}
}
Exemplo n.º 7
0
void Game_Player::UpdateScroll() {
	int center_x = DisplayUi->GetWidth() / 2 - TILE_SIZE / 2 - Game_Map::GetPanX() / (SCREEN_TILE_WIDTH / TILE_SIZE);
	int center_y = DisplayUi->GetHeight() / 2 + TILE_SIZE / 2 - Game_Map::GetPanY() / (SCREEN_TILE_WIDTH / TILE_SIZE);
	int dx = 0;
	int dy = 0;

	if (!Game_Map::IsPanLocked()) {
		if (IsMoving()) {
			int d = GetDirection();
			if ((d == Right || d == UpRight || d == DownRight) && GetScreenX() >= center_x)
				dx = 1;
			else if ((d == Left || d == UpLeft || d == DownLeft) && GetScreenX() <= center_x)
				dx = -1;
			dx <<= 1 + GetMoveSpeed();

			if ((d == Down || d == DownRight || d == DownLeft) && GetScreenY() >= center_y)
				dy = 1;
			else if ((d == Up || d == UpRight || d == UpLeft) && GetScreenY() <= center_y)
				dy = -1;
			dy <<= 1 + GetMoveSpeed();
		} else if (IsJumping()) {
			int move_speed = GetMoveSpeed();
			int diff = move_speed < 5 ? 48 / (2 + pow(2.0, 3 - move_speed)) : 64 / (7 - move_speed);
			dx += (GetX() - jump_x) * diff;
			dy += (GetY() - jump_y) * diff;
		}
	}

	if (Game_Map::GetPanX() != last_pan_x || Game_Map::GetPanY() != last_pan_y) {
		dx += Game_Map::GetPanX() - last_pan_x;
		dy += Game_Map::GetPanY() - last_pan_y;

		last_pan_x = Game_Map::GetPanX();
		last_pan_y = Game_Map::GetPanY();
	}

	if (dx > 0)
		Game_Map::ScrollRight(dx);
	else if (dx < 0)
		Game_Map::ScrollLeft(-dx);
	if (dy > 0)
		Game_Map::ScrollDown(dy);
	else if (dy < 0)
		Game_Map::ScrollUp(-dy);
}
Exemplo n.º 8
0
void CHostageImprov::SetKnownGoodPosition(const Vector &pos)
{
	if (IsJumping() || IsCrouching())
		return;

	if (m_hasKnownGoodPos)
	{
		if (m_priorKnownGoodPosTimer.IsElapsed())
		{
			m_hasPriorKnownGoodPos = true;
			m_priorKnownGoodPos = m_knownGoodPos;
			m_priorKnownGoodPosTimer.Start(1);
		}
	}

	m_hasKnownGoodPos = true;
	m_knownGoodPos = pos;
}
Exemplo n.º 9
0
void Game_Character::UpdateSprite() {
	if (IsJumping()) {
		UpdateJump();
		if (IsSpinning())
			anime_count++;
	} else if (IsMoving()) {
		remaining_step -= min(1 << (1 + GetMoveSpeed()), remaining_step);
		if (IsSpinning() || (animation_type != RPG::EventPage::AnimType_fixed_graphic && walk_animation))
			anime_count++;
	} else {
		stop_count++;
		if ((walk_animation && (IsSpinning() || IsContinuous())) || pattern != original_pattern)
			anime_count++;
	}

	if (anime_count >= GetSteppingSpeed()) {
		if (IsSpinning()) {
			SetSpriteDirection((GetSpriteDirection() + 1) % 4);
		} else if (!IsContinuous() && IsStopping()) {
			pattern = original_pattern;
			last_pattern = last_pattern == RPG::EventPage::Frame_left ? RPG::EventPage::Frame_right : RPG::EventPage::Frame_left;
		} else {
			if (last_pattern == RPG::EventPage::Frame_left) {
				if (pattern == RPG::EventPage::Frame_right) {
					pattern = RPG::EventPage::Frame_middle;
					last_pattern = RPG::EventPage::Frame_right;
				} else {
					pattern = RPG::EventPage::Frame_right;
				}
			} else {
				if (pattern == RPG::EventPage::Frame_left) {
					pattern = RPG::EventPage::Frame_middle;
					last_pattern = RPG::EventPage::Frame_left;
				} else {
					pattern = RPG::EventPage::Frame_left;
				}
			}
		}

		anime_count = 0;
	}
}
Exemplo n.º 10
0
// Check if we need to jump due to height change
bool CHostageImprov::DiscontinuityJump(float ground, bool onlyJumpDown, bool mustJump)
{
	// Don't try to jump if in the air or crouching.
	if (IsJumping() || IsCrouching() || IsUsingLadder())
		return false;

	float dz = ground - GetFeet().z;

	if (dz > StepHeight && !onlyJumpDown)
	{
		Jump();
		return true;
	}
	else if (dz < -JumpHeight)
	{
		Jump();
		return true;
	}

	return false;
}
Exemplo n.º 11
0
bool Game_Event::CheckEventTriggerTouch(int x, int y) {
	if (Game_Map::GetInterpreter().IsRunning())
		return false;

	if (trigger == RPG::EventPage::Trigger_collision && !IsJumping()) {
		if (Main_Data::game_player->IsInPosition(GetX(), GetY()) && GetLayer() == RPG::EventPage::Layers_same) {
			return false;
		}

		if (Main_Data::game_player->IsInPosition(x, y) && !Main_Data::game_player->IsBlockedByMoveRoute()) {
			if (Main_Data::game_player->InAirship() && GetLayer() == RPG::EventPage::Layers_same) {
				return false;
			}

			Start();
			return true;
		}
	}

	return false;
}
Exemplo n.º 12
0
bool Game_Character::IsStopping() const {
	return !(IsMoving() || IsJumping());
}
Exemplo n.º 13
0
bool Game_Character::IsMoving() const {
	return !IsJumping() && remaining_step > 0;
}
Exemplo n.º 14
0
// Move along the path. Return false if end of path reached.
CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
{
	if (m_pathLength == 0)
		return PATH_FAILURE;

	if (cv_bot_walk.value != 0.0f)
		Walk();

	// If we are navigating a ladder, it overrides all other path movement until complete
	if (UpdateLadderMovement())
		return PROGRESSING;

	// ladder failure can destroy the path
	if (m_pathLength == 0)
		return PATH_FAILURE;

	// we are not supposed to be on a ladder - if we are, jump off
	if (IsOnLadder())
		Jump(MUST_JUMP);

	assert(m_pathIndex < m_pathLength);

	// Check if reached the end of the path
	bool nearEndOfPath = false;
	if (m_pathIndex >= m_pathLength - 1)
	{
		Vector toEnd(pev->origin.x, pev->origin.y, GetFeetZ());
		Vector d = GetPathEndpoint() - toEnd; // can't use 2D because path end may be below us (jump down)

		const float walkRange = 200.0f;

		// walk as we get close to the goal position to ensure we hit it
		if (d.IsLengthLessThan(walkRange))
		{
			// don't walk if crouching - too slow
			if (allowSpeedChange && !IsCrouching())
				Walk();

			// note if we are near the end of the path
			const float nearEndRange = 50.0f;
			if (d.IsLengthLessThan(nearEndRange))
				nearEndOfPath = true;

			const float closeEpsilon = 20.0f;
			if (d.IsLengthLessThan(closeEpsilon))
			{
				// reached goal position - path complete
				DestroyPath();

				// TODO: We should push and pop walk state here, in case we want to continue walking after reaching goal
				if (allowSpeedChange)
					Run();

				return END_OF_PATH;
			}
		}
	}

	// To keep us moving smoothly, we will move towards
	// a point farther ahead of us down our path.
	int prevIndex = 0;				// closest index on path just prior to where we are now
	const float aheadRange = 300.0f;
	int newIndex = FindPathPoint(aheadRange, &m_goalPosition, &prevIndex);

	// BOTPORT: Why is prevIndex sometimes -1?
	if (prevIndex < 0)
		prevIndex = 0;

	// if goal position is near to us, we must be about to go around a corner - so look ahead!
	const float nearCornerRange = 100.0f;
	if (m_pathIndex < m_pathLength - 1 && (m_goalPosition - pev->origin).IsLengthLessThan(nearCornerRange))
	{
		ClearLookAt();
		InhibitLookAround(0.5f);
	}

	// if we moved to a new node on the path, setup movement
	if (newIndex > m_pathIndex)
	{
		SetPathIndex(newIndex);
	}

	if (!IsUsingLadder())
	{
		// Crouching

		// if we are approaching a crouch area, crouch
		// if there are no crouch areas coming up, stand
		const float crouchRange = 50.0f;
		bool didCrouch = false;
		for (int i = prevIndex; i < m_pathLength; i++)
		{
			const CNavArea *to = m_path[i].area;

			// if there is a jump area on the way to the crouch area, don't crouch as it messes up the jump
			// unless we are already higher than the jump area - we must've jumped already but not moved into next area
			if ((to->GetAttributes() & NAV_JUMP)/* && to->GetCenter()->z > GetFeetZ()*/)
				break;

			Vector close;
			to->GetClosestPointOnArea(&pev->origin, &close);

			if ((close - pev->origin).Make2D().IsLengthGreaterThan(crouchRange))
				break;

			if (to->GetAttributes() & NAV_CROUCH)
			{
				Crouch();
				didCrouch = true;
				break;
			}
		}

		if (!didCrouch && !IsJumping())
		{
			// no crouch areas coming up
			StandUp();
		}
		// end crouching logic
	}

	// compute our forward facing angle
	m_forwardAngle = UTIL_VecToYaw(m_goalPosition - pev->origin);

	// Look farther down the path to "lead" our view around corners
	Vector toGoal;

	if (m_pathIndex == 0)
	{
		toGoal = m_path[1].pos;
	}
	else if (m_pathIndex < m_pathLength)
	{
		toGoal = m_path[m_pathIndex].pos - pev->origin;

		// actually aim our view farther down the path
		const float lookAheadRange = 500.0f;
		if (!m_path[m_pathIndex].ladder && !IsNearJump() && toGoal.Make2D().IsLengthLessThan(lookAheadRange))
		{
			float along = toGoal.Length2D();
			int i;
			for (i = m_pathIndex + 1; i < m_pathLength; i++)
			{
				Vector delta = m_path[i].pos - m_path[i - 1].pos;
				float segmentLength = delta.Length2D();

				if (along + segmentLength >= lookAheadRange)
				{
					// interpolate between points to keep look ahead point at fixed distance
					float t = (lookAheadRange - along) / (segmentLength + along);
					Vector target;

					if (t <= 0.0f)
						target = m_path[i - 1].pos;
					else if (t >= 1.0f)
						target = m_path[i].pos;
					else
						target = m_path[i - 1].pos + t * delta;

					toGoal = target - pev->origin;
					break;
				}

				// if we are coming up to a ladder or a jump, look at it
				if (m_path[i].ladder || (m_path[i].area->GetAttributes() & NAV_JUMP))
				{
					toGoal = m_path[i].pos - pev->origin;
					break;
				}

				along += segmentLength;
			}

			if (i == m_pathLength)
			{
				toGoal = GetPathEndpoint() - pev->origin;
			}
		}
	}
	else
	{
		toGoal = GetPathEndpoint() - pev->origin;
	}

	m_lookAheadAngle = UTIL_VecToYaw(toGoal);

	// initialize "adjusted" goal to current goal
	Vector adjustedGoal = m_goalPosition;

	// Use short "feelers" to veer away from close-range obstacles
	// Feelers come from our ankles, just above StepHeight, so we avoid short walls, too
	// Don't use feelers if very near the end of the path, or about to jump
	// TODO: Consider having feelers at several heights to deal with overhangs, etc.
	if (!nearEndOfPath && !IsNearJump() && !IsJumping())
	{
		FeelerReflexAdjustment(&adjustedGoal);
	}

	// draw debug visualization
	if ((cv_bot_traceview.value == 1.0f && IsLocalPlayerWatchingMe()) || cv_bot_traceview.value == 10.0f)
	{
		DrawPath();

		const Vector *pos = &m_path[m_pathIndex].pos;
		UTIL_DrawBeamPoints(*pos, *pos + Vector(0, 0, 50), 1, 255, 255, 0);
		UTIL_DrawBeamPoints(adjustedGoal, adjustedGoal + Vector(0, 0, 50), 1, 255, 0, 255);
		UTIL_DrawBeamPoints(pev->origin, adjustedGoal + Vector(0, 0, 50), 1, 255, 0, 255);
	}

	// dont use adjustedGoal, as it can vary wildly from the feeler adjustment
	if (!IsAttacking() && IsFriendInTheWay(&m_goalPosition))
	{
		if (!m_isWaitingBehindFriend)
		{
			m_isWaitingBehindFriend = true;

			const float politeDuration = 5.0f - 3.0f * GetProfile()->GetAggression();
			m_politeTimer.Start(politeDuration);
		}
		else if (m_politeTimer.IsElapsed())
		{
			// we have run out of patience
			m_isWaitingBehindFriend = false;
			ResetStuckMonitor();

			// repath to avoid clump of friends in the way
			DestroyPath();
		}
	}
	else if (m_isWaitingBehindFriend)
	{
		// we're done waiting for our friend to move
		m_isWaitingBehindFriend = false;
		ResetStuckMonitor();
	}

	// Move along our path if there are no friends blocking our way,
	// or we have run out of patience
	if (!m_isWaitingBehindFriend || m_politeTimer.IsElapsed())
	{
		// Move along path
		MoveTowardsPosition(&adjustedGoal);

		// Stuck check
		if (m_isStuck && !IsJumping())
		{
			Wiggle();
		}
	}

	// if our goal is high above us, we must have fallen
	bool didFall = false;
	if (m_goalPosition.z - GetFeetZ() > JumpCrouchHeight)
	{
		const float closeRange = 75.0f;
		Vector2D to(pev->origin.x - m_goalPosition.x, pev->origin.y - m_goalPosition.y);
		if (to.IsLengthLessThan(closeRange))
		{
			// we can't reach the goal position
			// check if we can reach the next node, in case this was a "jump down" situation
			if (m_pathIndex < m_pathLength - 1)
			{
				if (m_path[m_pathIndex + 1].pos.z - GetFeetZ() > JumpCrouchHeight)
				{
					// the next node is too high, too - we really did fall of the path
					didFall = true;
				}
			}
			else
			{
				// fell trying to get to the last node in the path
				didFall = true;
			}
		}
	}

	// This timeout check is needed if the bot somehow slips way off
	// of its path and cannot progress, but also moves around
	// enough that it never becomes "stuck"
	const float giveUpDuration = 5.0f; // 4.0f
	if (didFall || gpGlobals->time - m_areaEnteredTimestamp > giveUpDuration)
	{
		if (didFall)
		{
			PrintIfWatched("I fell off!\n");
		}

		// if we havent made any progress in a long time, give up
		if (m_pathIndex < m_pathLength - 1)
		{
			PrintIfWatched("Giving up trying to get to area #%d\n", m_path[m_pathIndex].area->GetID());
		}
		else
		{
			PrintIfWatched("Giving up trying to get to end of path\n");
		}

		Run();
		StandUp();
		DestroyPath();

		return PATH_FAILURE;
	}

	return PROGRESSING;
}
Exemplo n.º 15
0
bool ANimModCharacter::IsInAir() const
{
	return IsFalling() || IsJumping();
}
Exemplo n.º 16
0
void CHostageImprov::MoveTowards(const Vector &pos, float deltaT)
{
	Vector move;
	float_precision accelRate;
	const float crouchWalkRate = 250.0f;

	// Jump up on ledges
	// Because we may not be able to get to our goal position and enter the next
	// area because our extent collides with a nearby vertical ledge, make sure
	// we look far enough ahead to avoid this situation.
	// Can't look too far ahead, or bots will try to jump up slopes.
	//
	// NOTE: We need to do this frequently to catch edges at the right time
	// TODO: Look ahead *along path* instead of straight line
	ClearPath();

	if ((m_lastKnownArea == NULL || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP))
		&& !IsUsingLadder() && !IsJumping() && IsOnGround() && !IsCrouching())
	{
		float ground;
		Vector aheadRay(pos.x - GetFeet().x, pos.y - GetFeet().y, 0);
		aheadRay.NormalizeInPlace();

		bool jumped = false;
		if (IsRunning())
		{
			const float farLookAheadRange = 80.0f;
			Vector normal;
			Vector stepAhead = GetFeet() + farLookAheadRange * aheadRay;
			stepAhead.z += HumanHeight;

			if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground, &normal ))
			{
				if (normal.z > 0.9f)
					jumped = DiscontinuityJump(ground, HOSTAGE_ONLY_JUMP_DOWN);
			}
		}

		if (!jumped)
		{
			// close up jumping
			// cant be less or will miss jumps over low walls
			const float lookAheadRange = 30.0f;
			Vector stepAhead = GetFeet() + lookAheadRange * aheadRay;
			stepAhead.z += HumanHeight;

			if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground))
			{
				jumped = DiscontinuityJump(ground);
			}
		}

		if (!jumped)
		{
			// about to fall gap-jumping
			const float lookAheadRange = 10.0f;
			Vector stepAhead = GetFeet() + lookAheadRange * aheadRay;
			stepAhead.z += HumanHeight;

			if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground))
			{
				jumped = DiscontinuityJump(ground, HOSTAGE_ONLY_JUMP_DOWN, HOSTAGE_MUST_JUMP);
			}
		}
	}

	move = (pos - GetFeet());
	move.z = 0;

	if (!move.IsZero())
	{
		move.NormalizeInPlace();
	}

	switch (m_moveType)
	{
	case Stopped:
		accelRate = 0;
		break;
	case Walking:
		if (IsCrouching())
			accelRate = crouchWalkRate;
		else
			accelRate = 400;
		break;
	case Running:
		if (IsCrouching())
			accelRate = crouchWalkRate;
		else
			accelRate = 1000;
		break;
	}

	m_vel.x = move.x * accelRate * deltaT + m_vel.x;
	m_vel.y = move.y * accelRate * deltaT + m_vel.y;
}
Exemplo n.º 17
0
void Game_Player::Update() {
	int cur_frame_count = Player::GetFrames();
	// Only update the event once per frame
	if (cur_frame_count == frame_count_at_last_update_parallel) {
		return;
	}
	frame_count_at_last_update_parallel = cur_frame_count;

	bool last_moving = IsMoving() || IsJumping();

	// Workaround: If a blocking move route ends in this frame, Game_Player::CancelMoveRoute decides
	// which events to start. was_blocked is used to avoid triggering events the usual way.
	bool was_blocked = IsBlockedByMoveRoute();
	Game_Character::Update();

	if (!Game_Map::GetInterpreter().IsRunning() && !Game_Map::IsAnyEventStarting()) {
		if (IsMovable()) {
			switch (Input::dir4) {
				case 2:
					Move(Down);
					break;
				case 4:
					Move(Left);
					break;
				case 6:
					Move(Right);
					break;
				case 8:
					Move(Up);
			}
		}

		// ESC-Menu calling
		if (Game_System::GetAllowMenu() && !Game_Message::message_waiting && Input::IsTriggered(Input::CANCEL)) {
			Game_Temp::menu_calling = true;
		}
	}

	Game_Character::UpdateSprite();
	UpdateScroll();

	if (location.aboard)
		GetVehicle()->SyncWithPlayer();

	if (IsMoving() || was_blocked) return;

	if (last_moving && location.boarding) {
		// Boarding completed
		location.aboard = true;
		location.boarding = false;
		SetMoveSpeed(GetVehicle()->GetMoveSpeed());
		SetDirection(GetVehicle()->GetDirection());
		return;
	}

	if (last_moving && location.unboarding) {
		// Unboarding completed
		location.unboarding = false;
		location.vehicle = Game_Vehicle::None;
		CheckTouchEvent();
		return;
	}

	if (InAirship() && !GetVehicle()->IsInUse()) {
		// Airship has landed
		Unboard();
		location.vehicle = Game_Vehicle::None;
		SetDirection(RPG::EventPage::Direction_down);

	}

	if (last_moving && CheckTouchEvent()) return;

	if (!Game_Map::GetInterpreter().IsRunning() && !Game_Map::IsAnyEventStarting()) {
		if (!Game_Message::visible && Input::IsTriggered(Input::DECISION)) {
			if ( GetOnOffVehicle() ) return;
			if ( CheckActionEvent() ) return;
		}
	}

	if (last_moving)
		Game_Map::UpdateEncounterSteps();
}
Exemplo n.º 18
0
void CCSBot::StuckCheck()
{
	if (m_isStuck)
	{
		// we are stuck - see if we have moved far enough to be considered unstuck
		Vector delta = pev->origin - m_stuckSpot;

		const float unstuckRange = 75.0f;
		if (delta.IsLengthGreaterThan(unstuckRange))
		{
			// we are no longer stuck
			ResetStuckMonitor();
			PrintIfWatched("UN-STUCK\n");
		}
	}
	else
	{
		// check if we are stuck
		// compute average velocity over a short period (for stuck check)
		Vector vel = pev->origin - m_lastOrigin;

		// if we are jumping, ignore Z
		if (IsJumping())
			vel.z = 0.0f;

		// cannot be Length2D, or will break ladder movement (they are only Z)
		float moveDist = vel.Length();
		float deltaT = g_flBotFullThinkInterval;

		m_avgVel[ m_avgVelIndex++ ] = moveDist / deltaT;

		if (m_avgVelIndex == MAX_VEL_SAMPLES)
			m_avgVelIndex = 0;

		if (m_avgVelCount < MAX_VEL_SAMPLES)
		{
			m_avgVelCount++;
		}
		else
		{
			// we have enough samples to know if we're stuck
			float avgVel = 0.0f;
			for (int t = 0; t < m_avgVelCount; ++t)
				avgVel += m_avgVel[t];

			avgVel /= m_avgVelCount;

			// cannot make this velocity too high, or bots will get "stuck" when going down ladders
			float stuckVel = (IsUsingLadder()) ? 10.0f : 20.0f;

			if (avgVel < stuckVel)
			{
				// we are stuck - note when and where we initially become stuck
				m_stuckTimestamp = gpGlobals->time;
				m_stuckSpot = pev->origin;
				m_stuckJumpTimestamp = gpGlobals->time + RANDOM_FLOAT(0.0f, 0.5f);

				PrintIfWatched("STUCK\n");
				if (IsLocalPlayerWatchingMe() && cv_bot_debug.value > 0.0f)
				{
					EMIT_SOUND(ENT(pev), CHAN_ITEM, "buttons/button11.wav", VOL_NORM, ATTN_NORM);
				}

				m_isStuck = true;
			}
		}
	}

	// always need to track this
	m_lastOrigin = pev->origin;
}
Exemplo n.º 19
0
void CHostageImprov::UpdatePosition(float deltaT)
{
	CNavArea *area = TheNavAreaGrid.GetNavArea(&m_hostage->pev->origin);

	if (area != NULL)
	{
		m_lastKnownArea = area;
	}

	DrawAxes(m_moveGoal, 255, 255, 0);

	if (IsJumping())
	{
		Vector dir;
		const float pushSpeed = 100.0f;

		if (!m_hasJumped)
		{
			m_hasJumped = true;
			m_hasJumpedIntoAir = false;
			m_hostage->pev->velocity.z += 300.0f;
		}
		else
			ResetJump();

		dir = m_jumpTarget - GetFeet();
		dir.z = 0;

#ifndef PLAY_GAMEDLL
		// TODO: fix test demo
		dir.NormalizeInPlace();

		m_hostage->pev->velocity.x = dir.x * pushSpeed;
		m_hostage->pev->velocity.y = dir.y * pushSpeed;
#else
		Vector vecRet = NormalizeMulScalar<float_precision, float_precision, float_precision, float>(dir, pushSpeed);
		m_hostage->pev->velocity.x = vecRet.x;
		m_hostage->pev->velocity.y = vecRet.y;
#endif

		m_hostage->SetBoneController(0);
		m_hostage->SetBoneController(1);

		FaceTowards(m_jumpTarget, deltaT);
		return;
	}

	if (m_isLookingAt)
	{
		Vector angles = UTIL_VecToAngles(m_viewGoal - GetEyes());
		float_precision pitch = angles.x - m_hostage->pev->angles.x;
		float_precision yaw = angles.y - m_hostage->pev->angles.y;

		while (yaw > 180.0f)
			yaw -= 360.0f;

		while (yaw < -180.0f)
			yaw += 360.0f;

		while (pitch > 180.0f)
			pitch -= 360.0f;

		while (pitch < -180.0f)
			pitch += 360.0f;

		m_hostage->SetBoneController(0, yaw);
		m_hostage->SetBoneController(1, -pitch);

		if (IsAtMoveGoal() && !HasFaceTo())
		{
			if (yaw < -45.0f || yaw > 45.0f)
			{
				FaceTowards(m_viewGoal, deltaT);
			}
		}
	}
	else
	{
		m_hostage->SetBoneController(0);
		m_hostage->SetBoneController(1);
	}

	if (HasFaceTo() && FaceTowards(m_faceGoal, deltaT))
		ClearFaceTo();

	if (!IsAtMoveGoal() || m_path.GetSegmentCount() > 0)
	{
		if (m_path.GetSegmentCount() <= 0)
		{
			HostagePathCost pathCost;
			if (m_path.Compute(&GetFeet(), &m_moveGoal, pathCost))
			{
				m_follower.SetPath(&m_path);
				m_follower.SetImprov(this);

				m_follower.Reset();
				m_follower.Debug(cv_hostage_debug.value > 0.0);
			}
		}

		m_follower.Update(deltaT, m_inhibitObstacleAvoidance.IsElapsed());

		if (m_moveType == Stopped)
		{
			m_follower.ResetStuck();
		}

		if (m_follower.IsStuck())
		{
			Wiggle();
		}
	}

	const float friction = 3.0f;

	m_vel.x += m_vel.x * -friction * deltaT;
	m_vel.y += m_vel.y * -friction * deltaT;

	float_precision speed = m_vel.NormalizeInPlace();

	const float maxSpeed = 285.0f;
	if (speed > maxSpeed)
	{
		speed = maxSpeed;
	}

	m_vel.x = m_vel.x * speed;
	m_vel.y = m_vel.y * speed;

	KeepPersonalSpace spacer(this);
	ForEachPlayer(spacer);

	if (g_pHostages != NULL)
	{
		g_pHostages->ForEachHostage(spacer);
	}

	m_hostage->pev->velocity.x = m_vel.x;
	m_hostage->pev->velocity.y = m_vel.y;

	m_moveFlags = 0;
}
Exemplo n.º 20
0
void Game_Player::UpdateScroll() {
	// First, update for the player's movement...

	int center_x = DisplayUi->GetWidth() / 2 - TILE_SIZE / 2 - actual_pan_x / (SCREEN_TILE_WIDTH / TILE_SIZE);
	int center_y = DisplayUi->GetHeight() / 2 + TILE_SIZE / 2 - actual_pan_y / (SCREEN_TILE_WIDTH / TILE_SIZE);

	int dx = 0;
	int dy = 0;

	if (!Game_Map::IsPanLocked()) {
		if (IsMoving() || last_remaining_move > 0) {
			if (last_remaining_move == 0)
				last_remaining_move = SCREEN_TILE_WIDTH;

			int d = GetDirection();
			if ((d == Right || d == UpRight || d == DownRight) && GetScreenX() > center_x)
				dx = 1;
			else if ((d == Left || d == UpLeft || d == DownLeft) && GetScreenX() < center_x)
				dx = -1;
			dx *= last_remaining_move - remaining_step;

			if ((d == Down || d == DownRight || d == DownLeft) && GetScreenY() > center_y)
				dy = 1;
			else if ((d == Up || d == UpRight || d == UpLeft) && GetScreenY() < center_y)
				dy = -1;
			dy *= last_remaining_move - remaining_step;
			last_remaining_move = remaining_step;

		} else if (IsJumping() || last_remaining_jump > 0) {
			if (last_remaining_jump == 0)
				last_remaining_jump = SCREEN_TILE_WIDTH;

			if ((GetX() > jump_x && GetScreenX() > center_x) || (GetX() < jump_x && GetScreenX() < center_x))
				dx = (GetX() - jump_x) * (last_remaining_jump - remaining_step);
			if ((GetY() > jump_y && GetScreenY() > center_y) || (GetY() < jump_y && GetScreenY() < center_y))
				dy = (GetY() - jump_y) * (last_remaining_jump - remaining_step);
			last_remaining_jump = remaining_step;
		}
	}

	Game_Map::ScrollRight(dx);
	Game_Map::ScrollDown(dy);

	// Second, update for the change in pan...

	int pan_x = Game_Map::GetPanX();
	int pan_y = Game_Map::GetPanY();
	int pan_dx = pan_x - last_pan_x;
	int pan_dy = pan_y - last_pan_y;
	last_pan_x = pan_x;
	last_pan_y = pan_y;

	// Change pan_dx/pan_dy to account for hitting the edges
	int screen_x = Game_Map::GetPositionX();
	int screen_y = Game_Map::GetPositionY();
	Game_Map::AddScreenX(screen_x, pan_dx);
	Game_Map::AddScreenY(screen_y, pan_dy);

	// Only move for the pan if we're closer to the target pan than we were before.
	if (std::abs(actual_pan_x + pan_dx - Game_Map::GetTargetPanX()) < std::abs(actual_pan_x - Game_Map::GetTargetPanX())) {
		Game_Map::ScrollRight(pan_dx);
		actual_pan_x += pan_dx;
	}
	if (std::abs(actual_pan_y + pan_dy - Game_Map::GetTargetPanY()) < std::abs(actual_pan_y - Game_Map::GetTargetPanY())) {
		Game_Map::ScrollDown(pan_dy);
		actual_pan_y += pan_dy;
	}
}