Files
firestorm/Gameleap/code/mw4/Code/MW4/AI_FocusFireSquad.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

292 lines
7.2 KiB
C++

#include "MW4Headers.hpp"
#include "AI_FocusFireSquad.hpp"
#include "AI_Groups.hpp"
#include "AI_UserConstants.hpp"
#include "ai_squadorders.hpp"
#include "CombatAI.hpp"
#include <Adept\NameTable.hpp>
#include "Sensor.hpp"
#pragma warning(disable : 4284)
#pragma warning (push)
#include <stlport\set>
#pragma warning (pop)
using namespace MW4AI;
using namespace MW4AI::Squad;
using namespace MechWarrior4;
const Stuff::Scalar min_target_update_time = 2.0f;
//________________________________________________________________________________________________________________
namespace MW4AI
{
namespace Squad
{
class FocusFireSquad;
};
};
class FocusFireSquadOrders
: public SquadOrders
{
public:
FocusFireSquadOrders(FocusFireSquad& squad, MechWarrior4::Group& group, int alignment);
virtual void Update();
virtual bool PointIsValid(const Stuff::Point3D& point) const;
virtual void IssueCommand(Stuff::Auto_Ptr<LancemateCommands::LancemateCommand>& command);
virtual void NotifyShotFired();
virtual MWObject* GetAutoTarget() const;
virtual bool GetExtendedSensorData(std::vector<MWObject*>& sensor_data_list) const;
virtual Stuff::Scalar GetLeastSquaredSensorDistance(const Stuff::Point3D& point) const;
private:
FocusFireSquad& m_Squad;
MechWarrior4::Group& m_Group;
int m_Alignment;
};
FocusFireSquadOrders::FocusFireSquadOrders(FocusFireSquad& squad, MechWarrior4::Group& group, int alignment)
: m_Squad(squad)
, m_Group(group)
, m_Alignment(alignment)
{
}
void FocusFireSquadOrders::Update()
{
}
bool FocusFireSquadOrders::PointIsValid(const Stuff::Point3D& point) const
{
return (true);
}
void FocusFireSquadOrders::IssueCommand(Stuff::Auto_Ptr<LancemateCommands::LancemateCommand>& command)
{
}
void FocusFireSquadOrders::NotifyShotFired()
{
}
MWObject* FocusFireSquadOrders::GetAutoTarget() const
{
return (m_Squad.GetAutoTarget());
}
bool FocusFireSquadOrders::GetExtendedSensorData(std::vector<MWObject*>& sensor_data_list) const
{
std::vector<MWObject*> members;
m_Group.GetMembers(members);
{for (std::vector<MWObject*>::const_iterator i_members = members.begin();
i_members != members.end();
++i_members)
{
if ((*i_members)->GetSensor() != 0)
{
{for (int i_sensor = 0;
i_sensor < (*i_members)->GetSensor()->RefreshAndGetSensorData().GetLength();
++i_sensor)
{
MechWarrior4::SensorData* d = (*i_members)->GetSensor()->RefreshAndGetSensorData()[i_sensor];
if (d != 0)
{
Adept::Entity* current = d->object.GetCurrent();
if ((current != 0) &&
(current->IsDestroyed() == false) &&
(current->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* target = Cast_Object(MWObject*,current);
if ((target->GetAlignment() != m_Alignment) &&
(std::find(members.begin(),members.end(),target) == members.end()) &&
(std::find(sensor_data_list.begin(),sensor_data_list.end(),target) == sensor_data_list.end()))
{
sensor_data_list.push_back(target);
}
}
}
}}
}
}}
return (true);
}
Stuff::Scalar FocusFireSquadOrders::GetLeastSquaredSensorDistance(const Stuff::Point3D& point) const
{
std::vector<MWObject*> members;
m_Group.GetMembers(members);
Stuff::Scalar least_distance = 0;
{for (std::vector<MWObject*>::const_iterator i_members = members.begin();
i_members != members.end();
++i_members)
{
Stuff::Scalar distance(GetLengthSquared((Stuff::Point3D)((*i_members)->GetLocalToWorld()),point));
if ((least_distance == 0) ||
(distance < least_distance))
{
least_distance = distance;
}
}}
return (least_distance);
}
//________________________________________________________________________________________________________________
FocusFireSquad::FocusFireSquad()
: m_AutoTarget(-2)
, m_LastTargetUpdateTime(0)
{
}
ID FocusFireSquad::GetID() const
{
return (GROUPAI_FOCUSFIRESQUAD);
}
template <class X>
X GetMostFrequentElement(const std::multiset<X>& m)
{
std::set<X> s(m.begin(),m.end());
std::multiset<X>::size_type best_count = 0;
X best_element = 0;
{for (std::set<X>::const_iterator i = s.begin();
i != s.end();
++i)
{
std::multiset<X>::size_type count = m.count(*i);
if (count > best_count)
{
best_element = *i;
best_count = count;
}
}}
return (best_element);
}
void FocusFireSquad::Update(MechWarrior4::Group& group, MechWarrior4::CombatAI& combat_ai)
{
inherited::Update(group,combat_ai);
if (m_LastTargetUpdateTime + min_target_update_time > (Stuff::Scalar)gos_GetElapsedTime())
{
return;
}
m_LastTargetUpdateTime = (Stuff::Scalar)gos_GetElapsedTime();
m_AutoTarget = -2;
std::multiset<Adept::ObjectID> potential_targets;
std::vector<MWObject*> members;
group.GetMembers(members);
{for (std::vector<MWObject*>::iterator i = members.begin();
i != members.end();
++i)
{
if (((*i)->GetAI() != 0) &&
((*i)->GetAI()->IsDerivedFrom(CombatAI::DefaultData) == true))
{
CombatAI* combat_ai = Cast_Object(CombatAI*,(*i)->GetAI());
MWObject* target = combat_ai->FindBestAutoTarget();
if (target != 0)
{
potential_targets.insert(target->objectID);
}
}
}}
if (potential_targets.size() == 0)
{
return;
}
m_AutoTarget = GetMostFrequentElement<Adept::ObjectID>(potential_targets);
}
void FocusFireSquad::NotifyShot(MechWarrior4::Group& group, Adept::ObjectID id)
{
inherited::NotifyShot(group,id);
}
void FocusFireSquad::NotifyShotFired(MechWarrior4::Group& group, const Stuff::Line3D& line, MechWarrior4::MWObject& at_who, MechWarrior4::MWObject& shooter)
{
inherited::NotifyShotFired(group,line,at_who,shooter);
}
void FocusFireSquad::NotifyMemberAdded(MechWarrior4::Group& group, MechWarrior4::MWObject& who)
{
inherited::NotifyMemberAdded(group,who);
if ((who.GetAI() != 0) &&
(who.GetAI()->IsDerivedFrom(CombatAI::DefaultData) == true))
{
CombatAI* combat_ai = Cast_Object(CombatAI*,who.GetAI());
#pragma warning(disable:4239)
FocusFireSquadOrders* new_squad_orders = new FocusFireSquadOrders(*this,group,who.GetAlignment());
combat_ai->SetSquadOrders(Stuff::Auto_Ptr<SquadOrders>(new_squad_orders));
#pragma warning(default:4239)
}
}
void FocusFireSquad::NotifyMemberRemoved(MechWarrior4::Group& group, MechWarrior4::MWObject& who)
{
inherited::NotifyMemberRemoved(group,who);
if ((who.GetAI() != 0) &&
(who.GetAI()->IsDerivedFrom(CombatAI::DefaultData) == true))
{
CombatAI* combat_ai = Cast_Object(CombatAI*,who.GetAI());
#pragma warning(disable:4239)
combat_ai->SetSquadOrders(Stuff::Auto_Ptr<SquadOrders>(0));
#pragma warning(default:4239)
}
}
void FocusFireSquad::SetEntityToIgnore(Adept::ObjectID objectid)
{
}
MWObject* FocusFireSquad::GetAutoTarget()
{
if (m_AutoTarget < 0)
{
return (0);
}
Entity* entity = Adept::NameTable::GetInstance()->FindData(m_AutoTarget);
if ((entity == 0) ||
(entity->IsDestroyed() == true) ||
(entity->IsDerivedFrom(MWObject::DefaultData) == false))
{
m_AutoTarget = -2;
return (0);
}
return (Cast_Object(MWObject*,entity));
}