#include "MW4Headers.hpp" #include "AI_Condition.hpp" #include "AI_Weapons.hpp" #include "MWPlayer.hpp" #include "VehicleInterface.hpp" #include "Torso.hpp" #include "MWMission.hpp" #include "JumpJet.hpp" using namespace MW4AI; using namespace MW4AI::Conditions; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::HittingSomethingElse(TacticInterface& i) { AILOGFUNC("Conditions::HittingSomethingElse"); if (i.GetUnableToFireDuration(4.0f) == true) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AnyWeaponReady // Fuzzy Conditions::AnyWeaponReady(TacticInterface& i) { AILOGFUNC("Conditions::AnyWeaponReady"); if (MW4AI::AnyWeaponReady(i.GetSelf()) == true) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::ProjectileApproaching(TacticInterface& i, Stuff::Scalar min_distance) { AILOGFUNC("Conditions::ProjectileApproaching"); AILOG1(min_distance); if (i.ProjectileApproaching() == true) { Stuff::Point3D delta; delta.Subtract(i.GetProjectileOrigin(),(Stuff::Point3D)i.GetSelf().GetLocalToWorld()); if (delta.GetLengthSquared() < min_distance * min_distance) { LOG_AND_RETURN(0); } LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::Fired(TacticInterface& i, Stuff::Scalar within_when) { AILOGFUNC("Conditions::Fired"); AILOG1(within_when); if (i.FiredWithin(within_when) == true) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::TargetedByEnemy(TacticInterface& i, Stuff::Scalar duration) { AILOGFUNC("Conditions::TargetedByEnemy"); AILOG1(duration); if (i.GetTimeTargetedByEnemy() >= duration) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::Rammed(TacticInterface& i, Stuff::Scalar duration) { AILOGFUNC("Conditions::Rammed"); AILOG1(duration); if (i.GetLastTimeRammedTarget() + duration > gos_GetElapsedTime()) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::InsideRadiusOfTarget(TacticInterface& i, Stuff::Scalar radius) { AILOGFUNC("Conditions::InsideRadiusOfTarget"); AILOG1(radius); if (i.GetDistanceFromTargetSquared() <= radius * radius) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::InsideRadiusOfTarget(TacticInterface&i, Stuff::Scalar radius, Stuff::Scalar when) { AILOGFUNC("Conditions::InsideRadiusOfTarget"); AILOG2(radius,when); Stuff::Point3D my_pos(i.GetSelf().GetLocalToWorld()); Stuff::Point3D target_pos; i.GetTarget().EstimateFuturePosition(&target_pos,(Scalar)when,true); my_pos.y = 0; target_pos.y = 0; if (GetLengthSquared(my_pos,target_pos) <= radius * radius) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::InsideRadiusOfRamTarget(TacticInterface& i, Stuff::Scalar radius) { AILOGFUNC("Conditions::InsideRadiusOfRamTarget"); AILOG(radius); Verify(i.GetSelf_AsVehicle() != 0); Stuff::Scalar time_to_reach = GetApproximateLength((Stuff::Point3D)i.GetSelf().GetLocalToWorld(), (Stuff::Point3D)i.GetTarget().GetLocalToWorld()) / i.GetSelf_AsVehicle()->GetGameModel()->maxSpeed; Stuff::Point3D target_pos; i.GetTarget().EstimateFuturePosition(&target_pos,time_to_reach,false); Stuff::Point3D my_pos((Stuff::Point3D)i.GetSelf().GetLocalToWorld()); my_pos.y = 0; target_pos.y = 0; if (GetLengthSquared(my_pos,target_pos) <= radius * radius) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy MW4AI::Conditions::InsideWeaponsRadiusOfTarget(TacticInterface& i, TacticInterface::WR_WHO who, TacticInterface::WR_QUALIFIER type, Stuff::Scalar multiplier) { AILOGFUNC("Conditions::InsideWeaponsRadiusOfTarget"); AILOG3(who,type,multiplier); Stuff::Scalar radius = i.WeaponRange(who,type) * multiplier; if (i.GetDistanceFromTargetSquared() <= radius * radius) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy MW4AI::Conditions::InsidePercentileRangeOf(TacticInterface& i, Stuff::Scalar percentile_range, bool nearest_enemy) { AILOGFUNC("Conditions::InsidePercentileRangeOfTarget"); AILOG2(percentile_range,nearest_enemy); Stuff::Scalar radius = i.GetCombatRadiusForRange(percentile_range); if (nearest_enemy == true) { Adept::Entity* nearest = i.GetNearest(true); if (nearest == 0) { nearest = &i.GetTarget(); } if (GetLengthSquared((Stuff::Point3D)i.GetSelf().GetLocalToWorld(), (Stuff::Point3D)nearest->GetLocalToWorld()) <= radius * radius) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } if (i.GetDistanceFromTargetSquared() <= radius * radius) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::VehicleMoving(TacticInterface& i) { AILOGFUNC("Conditions::VehicleMoving"); if (i.Moving() == true) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VehicleCrouching // Fuzzy Conditions::VehicleCrouching(TacticInterface& i) { AILOGFUNC("Conditions::VehicleCrouching"); if (i.Crouching() == true) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::FacingTarget(TacticInterface& i) { AILOGFUNC("Conditions::FacingTarget"); const Stuff::LinearMatrix4D& my_matrix = i.GetSelf().GetLocalToWorld(); Stuff::Point3D target_pos(i.GetTarget().GetLocalToWorld()); Stuff::UnitVector3D my_forward; my_matrix.GetLocalForwardInWorld(&my_forward); Stuff::Point3D forward(my_forward); forward += (Stuff::Point3D)my_matrix; Stuff::UnitVector3D my_backward; my_matrix.GetLocalBackwardInWorld(&my_backward); Stuff::Point3D backward(my_backward); backward += (Stuff::Point3D)my_matrix; if (GetLengthSquared(forward,target_pos) < GetLengthSquared(backward,target_pos)) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::InFrontOfTarget(TacticInterface& i, bool fUseTorso) { AILOGFUNC("Conditions::InFrontOfTarget"); AILOG1(fUseTorso); LinearMatrix4D relative_to; if ((fUseTorso == true) && (i.GetTarget().GetTorso() != 0) && (i.GetTarget().GetTorso()->twistJoint != 0)) { Check_Object(i.GetTarget().GetTorso()); relative_to = i.GetTarget().GetTorso()->twistJoint->GetLocalToWorld(); } else { relative_to = i.GetTarget().GetLocalToWorld(); } Stuff::Point3D delta; delta.Subtract((Stuff::Point3D)i.GetSelf().GetLocalToWorld(),(Stuff::Point3D)relative_to); Stuff::UnitVector3D delta_normalized(delta); Stuff::UnitVector3D local_forward; relative_to.GetLocalForwardInWorld(&local_forward); Stuff::Scalar bearing = delta_normalized * local_forward; bearing += 1; bearing *= 0.5f; if (bearing >= 0.5f) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); // TODO: bearing is already a fuzzy; should return it as a Fuzzy! } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::JumpedWithin(TacticInterface& i, Stuff::Scalar duration) { AILOGFUNC("Conditions::JumpedWithin"); AILOG1(duration); if (i.GetLastTimeJumped() + duration >= gos_GetElapsedTime()) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool Conditions::Jumping(TacticInterface& i) { AILOGFUNC("Conditions::Jumping"); if (i.GetSelf().IsDerivedFrom(Mech::DefaultData) == true) { Mech* mech = Cast_Object(Mech*,&(i.GetSelf())); if ((mech->GetJumpJet() != 0) && (mech->GetJumpJet()->executionState->GetState() == JumpJet::ExecutionStateEngine::JumpingState)) { LOG_AND_RETURN(true); } } LOG_AND_RETURN(false); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::CanBeSeenByTarget(TacticInterface& i, Stuff::Scalar within_distance) { AILOGFUNC("Conditions::CanBeSeenByTarget"); const Stuff::Scalar distance = GetApproximateLength((Stuff::Point3D)i.GetSelf().GetLocalToWorld(), (Stuff::Point3D)i.GetTarget().GetLocalToWorld()); if (distance > within_distance) { LOG_AND_RETURN(0); } if ((MWMission::GetInstance() != 0) && (MWMission::GetInstance()->GetGameModel() != 0)) { const Adept::Mission::GameModel* game_model = MWMission::GetInstance()->GetGameModel(); if (distance > game_model->m_generalFogEnd) { LOG_AND_RETURN(0); } } FireData fire_data(i.GetSelf(), i.GetSelf().GetLineOfSight(), i.GetTarget().GetLineOfSight()); fire_data.Project(); if (fire_data.GetHitResult(&i.GetTarget()) == FireData::HIT_TARGET) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::IsHighOffGround(TacticInterface& i) { AILOGFUNC("Conditions::IsHighOffGround"); const Stuff::Point3D my_pos(i.GetSelf().GetLocalToWorld()); BYTE tempmaterial; if (my_pos.y - 10 > GetMapY(my_pos.x,my_pos.z,&i.GetSelf(),tempmaterial)) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::PlayerWillHitMe(TacticInterface& i, Stuff::Scalar seconds, Stuff::Scalar threshold) { AILOGFUNC("Conditions::PlayerWillHitMe"); AILOG2(seconds,threshold); if ((Adept::Player::GetInstance() == 0) || (i.GetSelf_AsVehicle() == 0)) { LOG_AND_RETURN(0); } MechWarrior4::MWPlayer* player = Cast_Object(MechWarrior4::MWPlayer*,Adept::Player::GetInstance()); Check_Object(player); if (player->GetInterface() == 0) { LOG_AND_RETURN(0); } Adept::Entity* player_entity = player->GetInterface()->vehicle; if ((player_entity == 0) || (player_entity->GetAlignment() == i.GetSelf().GetAlignment()) || (player_entity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) == false)) { LOG_AND_RETURN(0); } threshold *= threshold; MechWarrior4::Vehicle* player_vehicle = Cast_Object(MechWarrior4::Vehicle*,player_entity); if (GetLengthSquared((Stuff::Point3D)player_vehicle->GetLocalToWorld(), (Stuff::Point3D)i.GetSelf().GetLocalToWorld()) < threshold) { LOG_AND_RETURN(1); } Stuff::Point3D next_player_pos; player_vehicle->EstimateFuturePosition(&next_player_pos, (Scalar)seconds); Stuff::Point3D next_self_pos; i.GetSelf_AsVehicle()->EstimateFuturePosition(&next_self_pos, (Scalar)seconds); if (GetLengthSquared(next_self_pos, next_player_pos) < threshold) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::ClusterFuckingSomeone(TacticInterface& i, Stuff::Scalar radius) { AILOGFUNC("Conditions::ClusterFuckingSomeone"); AILOG1(radius); if (i.GetLastTimeRammedTarget() + 1.0f > gos_GetElapsedTime()) { LOG_AND_RETURN(1); } Adept::Entity* entity = i.GetNearest(); if (entity != 0) { if (i.GetSelf().IsDerivedFrom(Mech::DefaultData) == false) { radius *= 0.8f; // this is to ensure that vehicles smaller than mechs have smaller dodge radii } if (GetLengthSquared((Stuff::Point3D)i.GetSelf().GetLocalToWorld(), (Stuff::Point3D)entity->GetLocalToWorld()) < radius * radius) { LOG_AND_RETURN(1); } } LOG_AND_RETURN(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::EliteLevelBetween(TacticInterface& i, UserConstants::ID min, UserConstants::ID max) { AILOGFUNC("Conditions::EliteLevelBetween"); AILOG2(min,max); int int_min = (int)UserConstants::Instance()->Get(min); int int_max = (int)UserConstants::Instance()->Get(max); Verify(int_min <= int_max); Verify(int_min >= 0); Verify(int_max <= 100); LOG_AND_RETURN((i.GetEliteLevel() >= int_min) && (i.GetEliteLevel() <= int_max)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fuzzy Conditions::AttackThrottleBetween(TacticInterface& i, Stuff::Scalar min, Stuff::Scalar max) { AILOGFUNC("Conditions::AttackThrottleBetween"); AILOG2(min,max); Verify(min >= 0); Verify(max <= 100); if ((i.GetAttackThrottle() >= min) && (i.GetAttackThrottle() <= max)) { LOG_AND_RETURN(1); } LOG_AND_RETURN(0); }