void Player::CalculateFacingAngle() { DirectX::XMFLOAT3 v1 = DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f); DirectX::XMFLOAT3 v2 = GetAttackDirection(); float x = (v1.x * v2.z) - (v2.x * v1.z); float y = (v1.x * v2.x) - (v1.z * v2.z); float faceAngle = atan2(y, x) - 1.57079632679f; SetFacingDirection(DirectX::XMFLOAT3(GetFacingDirection().x, faceAngle, GetFacingDirection().z)); }
f32 Vessel::GetTurnDirection(guVector* Vec) { f32 DirectionToFaceTarget = M_PI - atan2( Vec->x - GetX(), Vec->y - GetY() ); float diff = DirectionToFaceTarget - GetFacingDirection(); if (diff > M_PI) // shortest turn is always less than PI diff -= 2*M_PI; // get shorter turn direction else if (diff < -M_PI) diff += 2*M_PI; // get shorter turn direction return diff; }
bool CNPC_Infected::OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval ) { // required movement direction float flMoveYaw = UTIL_VecToYaw( move.dir ); // FIXME: move this up to navigator so that path goals can ignore these overrides. Vector dir; float flInfluence = GetFacingDirection( dir ); dir = move.facing * (1 - flInfluence) + dir * flInfluence; VectorNormalize( dir ); // ideal facing direction float idealYaw = UTIL_AngleMod( UTIL_VecToYaw( dir ) ); // FIXME: facing has important max velocity issues GetMotor()->SetIdealYawAndUpdate( idealYaw ); // find movement direction to compensate for not being turned far enough float flDiff = UTIL_AngleDiff( flMoveYaw, GetLocalAngles().y ); // Setup the 9-way blend parameters based on our speed and direction. Vector2D vCurMovePose( 0, 0 ); vCurMovePose.x = cos( DEG2RAD( flDiff ) ) * 1.0f; //flPlaybackRate; vCurMovePose.y = -sin( DEG2RAD( flDiff ) ) * 1.0f; //flPlaybackRate; SetPoseParameter( gm_nMoveXPoseParam, vCurMovePose.x ); SetPoseParameter( gm_nMoveYPoseParam, vCurMovePose.y ); // ==== Update Lean pose parameters if ( gm_nLeanYawPoseParam >= 0 ) { float targetLean = GetPoseParameter( gm_nMoveYPoseParam ) * 30.0f; float curLean = GetPoseParameter( gm_nLeanYawPoseParam ); if( curLean < targetLean ) curLean += MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*12.0f); //was 15.0f else curLean -= MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*12.0f); //was 15.0f SetPoseParameter( gm_nLeanYawPoseParam, curLean ); } if( gm_nLeanPitchPoseParam >= 0 ) { float targetLean = GetPoseParameter( gm_nMoveXPoseParam ) * -20.0f; //was -30.0f float curLean = GetPoseParameter( gm_nLeanPitchPoseParam ); if( curLean < targetLean ) curLean += MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*10.0f); //was 15.0f else curLean -= MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*10.0f); //was 15.0f SetPoseParameter( gm_nLeanPitchPoseParam, curLean ); } return true; }
void Unit::Order_NukeGround() { unk_move_waypoint = order_target_pos; int sight_range = GetSightRange(false) * 32; int dist = Distance(exact_position, Point32(order_target_pos) * 256 + Point32(128, 128)) / 256; if (ai && dist <= sight_range * 3) Ai_Cloak(); if (dist > sight_range) { if (move_target_update_timer == 0) ChangeMovementTarget(order_target_pos); // What, it is not moving? } else { StopMoving(this); if (position != unk_move_waypoint) { int diff = facing_direction - GetFacingDirection(sprite->position.x, sprite->position.y, unk_move_waypoint.x, unk_move_waypoint.y); if (diff < -1 || diff > 1) return; } Unit *silo = nullptr; for (Unit *unit : bw::first_player_unit[player]) { if (unit->unit_id == NuclearSilo && unit->silo.has_nuke) { silo = unit; break; } } if (!silo) { OrderDone(); return; } Unit *nuke = silo->silo.nuke; silo->silo.nuke = nullptr; silo->silo.has_nuke = 0; PlaySound(Sound::NukeLaser, this, 1, 0); IssueOrderTargetingGround(nuke, Order::NukeLaunch, order_target_pos.x, order_target_pos.y); related = nuke; nuke->related = this; nuke->sprite->SetDirection32(0); ShowUnit(nuke); IssueOrderTargetingGround(this, Order::NukeTrack, sprite->position.x, sprite->position.y); if (!IsDisabled() || units_dat_flags[unit_id] & UnitFlags::Building) // Huh? buttons = 0xed; RefreshUi(); } }
void CAI_Motor::MoveFacing( const AILocalMoveGoal_t &move ) { if ( GetOuter()->OverrideMoveFacing( move, GetMoveInterval() ) ) return; // required movement direction float flMoveYaw = UTIL_VecToYaw( move.dir ); int nSequence = GetSequence(); float fSequenceMoveYaw = GetSequenceMoveYaw( nSequence ); if ( fSequenceMoveYaw == NOMOTION ) { fSequenceMoveYaw = 0; } if (!HasPoseParameter( nSequence, "move_yaw" )) { SetIdealYawAndUpdate( UTIL_AngleMod( flMoveYaw - fSequenceMoveYaw ) ); } else { // FIXME: move this up to navigator so that path goals can ignore these overrides. Vector dir; float flInfluence = GetFacingDirection( dir ); dir = move.facing * (1 - flInfluence) + dir * flInfluence; VectorNormalize( dir ); // ideal facing direction float idealYaw = UTIL_AngleMod( UTIL_VecToYaw( dir ) ); // FIXME: facing has important max velocity issues SetIdealYawAndUpdate( idealYaw ); // find movement direction to compensate for not being turned far enough float flDiff = UTIL_AngleDiff( flMoveYaw, GetLocalAngles().y ); SetPoseParameter( "move_yaw", flDiff ); /* if ((GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT)) { Msg( "move %.1f : diff %.1f : ideal %.1f\n", flMoveYaw, flDiff, m_IdealYaw ); } */ } }