Files
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

908 lines
22 KiB
C++

#include "MW4Headers.hpp"
#include "AI_Lancemate.hpp"
#include "Group.hpp"
#include "CombatAI.hpp"
#include <Adept\NameTable.hpp>
#include "AIUtils.hpp"
#include "AI_CombatTacticInterface.hpp"
#include "AI_LancemateCommands.hpp"
#include "AI_FindObject.hpp"
#include "Mech.hpp"
#include "lancemate.hpp"
#include "AI_Groups.hpp"
#include "MWMission.hpp"
#include "MWApplication.hpp"
#pragma warning(push)
#include <stlport\algorithm>
#pragma warning(pop)
using namespace MW4AI;
using namespace MW4AI::Squad;
using namespace MechWarrior4;
using namespace MW4AI::LancemateAudio;
const Stuff::Scalar max_get_out_of_way_distance = 70.0f;
const Stuff::Scalar max_too_close_to_leaders_fire_distance = 40.0f;
const Stuff::Scalar max_dodge_leaders_fire_time = 8.0f;
const Stuff::Scalar max_unable_to_fire_give_up_time = 12.0f;
const Stuff::Scalar max_squared_disengage_distance = 900.0f * 900.0f;
const Stuff::Scalar target_to_avoid_refresh_time = 10.0f;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Group::element_list::size_type GetObjectIndex(MWObject& object,
const Group& group)
{
Group::element_list::const_iterator found = std::find(group.GetElements().begin(),group.GetElements().end(),object.objectID);
if (found == group.GetElements().end())
{
return (group.GetElements().size());
}
return (std::distance(group.GetElements().begin(),found));
}
inline Stuff::Scalar GetDistanceSquared(Adept::Entity& object1, Adept::Entity& object2)
{
return (GetLengthSquared((Stuff::Point3D)object1.GetLocalToWorld(),(Stuff::Point3D)object2.GetLocalToWorld()));
}
inline CombatAI* GetLeaderCombatAI(Adept::Entity* leader)
{
if (leader->IsDerivedFrom(MWObject::DefaultData) == false)
{
return (0);
}
MWObject* leader_mwobject = Cast_Object(MWObject*,leader);
Check_Object(leader_mwobject);
if ((leader_mwobject->GetAI() == 0) ||
(leader_mwobject->GetAI()->IsDerivedFrom(CombatAI::DefaultData) == false))
{
return (0);
}
CombatAI* combat_ai = Cast_Object(CombatAI*,leader_mwobject->GetAI());
Check_Object(combat_ai);
return (combat_ai);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
namespace MW4AI
{
class LancemateSquadOrders :
public SquadOrders
{
public:
LancemateSquadOrders(CombatAI& combat_ai,
Squad::Lancemate& lancemate_ai,
Group& group,
LancemateAudio::AudioManager& audio_manager);
~LancemateSquadOrders();
void Update();
bool PointIsValid(const Stuff::Point3D& point) const;
void IssueCommand(Stuff::Auto_Ptr<LancemateCommands::LancemateCommand>& command);
void NotifyShotFired();
void NotifyFriendlyFire(Adept::Entity& who);
bool CanExecuteCommands() const;
Stuff::Auto_Ptr<LancemateCommands::LancemateCommand> CreateCommand(LancemateCommands::ID command_id,Adept::Entity* pTarget2 = NULL);
bool ShouldRunScript() const;
bool GetLeaderAlignment(int& alignment);
void NotifyNoPath();
private:
int GetMyIndex() const;
MWObject* GetLeader() const;
bool UnitIsMovingToLeadersPath(MWObject& leader) const;
Stuff::Point3D GetPosition() const;
bool PointIsInLeadersPath(const Stuff::Point3D& point, MWObject& leader) const;
void UpdateLeaderAvoidance();
void UpdateShootNearbyEnemies();
void UpdateFriendlyFireFrustration();
MWObject* FindEntityToAttack(const Adept::ObjectID* except_who);
private:
CombatAI& m_CombatAI;
Squad::Lancemate& m_LancemateAI;
Group& m_Group;
LancemateAudio::AudioManager& m_AudioManager;
Stuff::Auto_Ptr<LancemateCommands::LancemateCommand> m_Command;
int m_FriendlyFireFrustration;
Stuff::Scalar m_LastTimeNoticedFriendlyFire;
Stuff::Scalar m_LastTimeFrustrationChanged;
bool m_TurnedAgainstPlayer;
};
};
Stuff::Auto_Ptr<LancemateCommands::LancemateCommand> LancemateSquadOrders::CreateCommand(LancemateCommands::ID command_id,Adept::Entity* pTarget2/* = NULL*/)
{
if ((m_Command.GetPointer() != 0) &&
(m_Command->CanInterrupt() == false))
{
if (!pTarget2)
m_AudioManager.PlayAudio(AUDIO_NO,m_CombatAI.GetTalkerSuffix());
return (0);
}
if (GetLeader() != 0)
{
return (LancemateCommands::CreateLancemateCommand(command_id,m_CombatAI,*GetLeader(),m_AudioManager,pTarget2));
}
return (0);
}
void LancemateSquadOrders::NotifyNoPath()
{
if (m_Command.GetPointer() != 0)
{
m_Command->NotifyNoPath();
}
}
LancemateSquadOrders::LancemateSquadOrders(CombatAI& combat_ai,
Squad::Lancemate& lancemate_ai,
Group& group,
LancemateAudio::AudioManager& audio_manager)
: m_CombatAI(combat_ai)
, m_LancemateAI(lancemate_ai)
, m_Group(group)
, m_AudioManager(audio_manager)
, m_FriendlyFireFrustration(0)
, m_LastTimeNoticedFriendlyFire((Stuff::Scalar)gos_GetElapsedTime())
, m_LastTimeFrustrationChanged((Stuff::Scalar)gos_GetElapsedTime())
, m_TurnedAgainstPlayer(false)
{
}
LancemateSquadOrders::~LancemateSquadOrders()
{
}
void LancemateSquadOrders::IssueCommand(Stuff::Auto_Ptr<LancemateCommands::LancemateCommand>& command)
{
if (m_TurnedAgainstPlayer == true)
{
return;
}
m_Command = command;
}
void LancemateSquadOrders::Update()
{
if ((m_TurnedAgainstPlayer == true) ||
(ShouldRunScript() == true))
{
return;
}
if (GetLeader() == &m_CombatAI.GetSelf())
{
return;
}
m_CombatAI.SetIgnoringFriendlyFire(true);
if (m_Command != 0)
{
if (m_Command->Finished() == true)
{
m_Command.Delete();
if (GetLeader() != 0)
{
#pragma warning(disable:4239)
IssueCommand(LancemateCommands::CreateLancemateCommand(LancemateCommands::LANCEMATE_DEFAULT,m_CombatAI,*(GetLeader()),m_AudioManager));
#pragma warning(default:4239)
}
}
else
{
m_Command->Update();
}
if (m_Command->CanDistract() == true)
{
if (m_CombatAI.GetAttackState() == CombatAI::ATTACKING)
{
if ((m_CombatAI.Target() == 0) ||
(m_CombatAI.GetUnableToFireDuration(max_unable_to_fire_give_up_time) == true) ||
(GetLengthSquared((Stuff::Point3D)m_CombatAI.GetSelf().GetLocalToWorld(),
(Stuff::Point3D)m_CombatAI.Target()->GetLocalToWorld()) > max_squared_disengage_distance))
{
m_CombatAI.Reset(false);
}
else
{
UpdateShootNearbyEnemies();
}
}
else
{
UpdateShootNearbyEnemies();
}
}
}
UpdateLeaderAvoidance();
UpdateFriendlyFireFrustration();
}
int LancemateSquadOrders::GetMyIndex() const
{
Verify(m_Group.GetElements().size() > 0);
return (index_of(m_Group.GetElements().begin(),m_Group.GetElements().end(),m_CombatAI.GetSelf().objectID));
}
MWObject* LancemateSquadOrders::GetLeader() const
{
if (m_Group.GetElements().size() == 0)
{
return (0);
}
Adept::Entity* entity = m_Group.IDToEntity(*(m_Group.GetElements().begin()));
if (entity == 0)
{
return (0);
}
Check_Object(entity);
if ((entity->IsDestroyed() == true) ||
(entity->IsDerivedFrom(MWObject::DefaultData) == false))
{
return (0);
}
return (Cast_Object(MWObject*,entity));
}
Stuff::Point3D LancemateSquadOrders::GetPosition() const
{
return (m_CombatAI.GetSelf().GetLocalToWorld());
}
bool LancemateSquadOrders::UnitIsMovingToLeadersPath(MWObject& leader) const
{
if (m_CombatAI.GetAttackState() != CombatAI::ATTACKING)
{
return (false);
}
CombatTacticInterface iface(m_CombatAI);
Stuff::Point3D dest(GetPosition());
iface.GetLastMoveDest(dest);
return (!PointIsValid(dest));
}
void LancemateSquadOrders::UpdateLeaderAvoidance()
{
if (m_Command.GetPointer() == 0)
{
return;
}
if (m_Command->CanDistract() == false)
{
return;
}
int index(GetMyIndex());
Verify(index < m_Group.GetElements().size()); // if this fails, the combat_ai does not belong to the group
if (index == 0)
{
return;
}
MWObject* leader = GetLeader();
if (leader == 0)
{
return; // the leader cannot be part of the formation; he dictates it
}
Check_Object(leader);
int attempt_index = 0;
CombatTacticInterface iface(m_CombatAI);
while (UnitIsMovingToLeadersPath(*leader) == true)
{
Stuff::Scalar distance = 0;
Stuff::Scalar radians = 0;
Stuff::Point3D my_pos(GetPosition());
Stuff::UnitVector3D forward_vector;
m_CombatAI.GetSelf().GetLocalToWorld().GetLocalForwardInWorld(&forward_vector);
Stuff::Point3D forward(forward_vector);
forward += my_pos;
switch (attempt_index % 4)
{
case 0: { radians = 0.0f;break; }
case 1: { radians = Stuff::Pi_Over_2; break; }
case 2: { radians = -Stuff::Pi_Over_2; break; }
case 3: { radians = Stuff::Pi; break; }
}
switch (attempt_index / 4)
{
case 0: { distance = 10.0f;break; }
case 1: { distance = 20.0f; break; }
case 2: { distance = 50.0f; break; }
case 3: { distance = 100.0f; break; }
}
Stuff::Point3D dest(RotateVector(forward,my_pos,radians,distance));
if (m_CombatAI.PointIsValid(dest) == true)
{
m_CombatAI.MoveToPoint(dest);
}
++attempt_index;
if (attempt_index >= 16)
{
return;
}
}
}
void LancemateSquadOrders::UpdateShootNearbyEnemies()
{
Verify(m_Group.GetElements().size() > 0);
Verify(m_Command.GetPointer() != 0);
if (m_CombatAI.Attacking() == true)
{
if (m_CombatAI.Target()->IsDerivedFrom(MWObject::DefaultData) == true)
{
MWObject* target = Cast_Object(MWObject*,m_CombatAI.Target());
if (target->GetTargetDesirability() > 0)
{
return;
}
if ((target->weaponChain.IsEmpty() == false) ||
(target->GetAI() != 0))
{
return;
}
}
}
if (UserConstants::Instance() == 0)
{
return;
}
Stuff::Scalar lancemate_min_radius = m_CombatAI.GetSquadTargetingRadius();
Verify(lancemate_min_radius > 0);
Adept::ObjectID id(m_LancemateAI.GetTargetToAvoid());
Adept::ObjectID* id_ptr = 0;
if (id >= 0)
{
id_ptr = &id;
}
MWObject* mwobject = m_Command->FindSomeoneToAttack(id_ptr,FindObject::FC_BEST_TARGET,lancemate_min_radius);
if ((mwobject != 0) &&
(mwobject != m_CombatAI.Target()))
{
Check_Object(mwobject);
m_CombatAI.Reset(m_Command->CanDeviateFromPath());
m_CombatAI.Target(mwobject);
m_CombatAI.OrderAttack(m_Command->CanDeviateFromPath());
}
}
bool LancemateSquadOrders::PointIsInLeadersPath(const Stuff::Point3D& point, MWObject& leader) const
{
const Stuff::LinearMatrix4D& leader_matrix = leader.GetLocalToWorld();
if (GetLengthSquared((Stuff::Point3D)leader_matrix,
point) < (max_get_out_of_way_distance * max_get_out_of_way_distance))
{
if ((GetSquaredDistToMatrixForward(point,leader_matrix) < GetSquaredDistToMatrixLeft(point,leader_matrix)) &&
(GetSquaredDistToMatrixForward(point,leader_matrix) < GetSquaredDistToMatrixRight(point,leader_matrix)))
{
return (true);
}
}
return (false);
}
bool LancemateSquadOrders::PointIsValid(const Stuff::Point3D& point) const
{
Verify(UserConstants::Instance() != 0);
int index(GetMyIndex());
Verify(index < m_Group.GetElements().size()); // if this fails, the combat_ai does not belong to the group
if (index == 0)
{
return (true);
}
MWObject* leader = GetLeader();
if (leader == 0)
{
return (true);
}
Check_Object(leader);
if ((m_Command.GetPointer() != 0) &&
(m_Command->OnLeash() == true) &&
(GetLengthSquared(point,m_Command->GetLeashPoint()) > m_Command->GetLeashRadius() * m_Command->GetLeashRadius()))
{
return (false);
}
if ((m_LancemateAI.GetLastLeaderFireTime() != 0) &&
(m_LancemateAI.GetLastLeaderFireTime() + max_dodge_leaders_fire_time > gos_GetElapsedTime()))
{
Verify(m_LancemateAI.GetLeaderFireLine() != 0);
if (LinePenetrates(*m_LancemateAI.GetLeaderFireLine(),point,max_too_close_to_leaders_fire_distance) == true)
{
return (false);
}
}
Vehicle* leader_vehicle = Cast_Object(Vehicle*,leader);
Check_Object(leader_vehicle);
if (leader_vehicle->speedDemandMPS < Stuff::SMALL)
{
return (true);
}
return (!PointIsInLeadersPath(point,*leader));
}
void LancemateSquadOrders::NotifyShotFired()
{
if ((m_CombatAI.GetSelf().GetSensor() == 0) ||
(m_TurnedAgainstPlayer == true))
{
return;
}
if ((m_Command.GetPointer() != 0) &&
(m_Command->CanDistract() == false))
{
return;
}
if ((m_CombatAI.Attacking() == false) ||
((m_LancemateAI.GetTargetToAvoid() > 0) && (m_CombatAI.Target()->objectID == m_LancemateAI.GetTargetToAvoid())))
{
Adept::ObjectID avoid_id = m_LancemateAI.GetTargetToAvoid();
Verify(m_Command.GetPointer() != 0);
MWObject* mwobject = 0;
if (avoid_id >= 0)
{
m_Command->FindSomeoneToAttack(&avoid_id);
}
else
{
m_Command->FindSomeoneToAttack(0);
}
if ((mwobject != 0) &&
(m_CombatAI.Target() != mwobject))
{
Check_Object(mwobject);
m_CombatAI.Reset(m_Command->CanDeviateFromPath());
m_CombatAI.Target(mwobject);
m_CombatAI.OrderAttack(m_Command->CanDeviateFromPath());
}
}
}
void LancemateSquadOrders::NotifyFriendlyFire(Adept::Entity& who)
{
if (m_TurnedAgainstPlayer == true)
{
MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
mission->EndMissionState (false);
return;
}
if ((m_CombatAI.GetSelf().IsPlayerVehicle() == true) ||
(who.IsPlayerVehicle() == false))
{
return;
}
// MSL 5.04 Friendly Fire Betty Changes
return;
// if ((m_LastTimeFrustrationChanged + 3.0f < gos_GetElapsedTime()) && (m_FriendlyFireFrustration < 4))
if (m_LastTimeFrustrationChanged + 3.0f < gos_GetElapsedTime())// && (m_FriendlyFireFrustration < 4))
{
++m_FriendlyFireFrustration;
m_LastTimeFrustrationChanged = (Stuff::Scalar)gos_GetElapsedTime();
// MSL 5.04 Friendly Fire Betty Changes
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
switch (m_FriendlyFireFrustration)
{
case 1:
{
app->SendSound(who.GetReplicatorID(), VehicleInterface::FRIENDLYFIREPENALTY);
// m_AudioManager.PlayAudio(AUDIO_FF1,m_CombatAI.GetTalkerSuffix());
break;
}
case 2:
{
app->SendSound(who.GetReplicatorID(), VehicleInterface::FRIENDLYFIREPENALTY);
// m_AudioManager.PlayAudio(AUDIO_FF2,m_CombatAI.GetTalkerSuffix());
break;
}
case 3:
{
app->SendSound(who.GetReplicatorID(), VehicleInterface::FRIENDLYFIREPENALTY);
// m_AudioManager.PlayAudio(AUDIO_FF3,m_CombatAI.GetTalkerSuffix());
// m_AudioManager.SetPissedOff(true);
break;
}
// MSL 5.04 Friendly Fire Betty Changes
// case 4:
// {
// m_TurnedAgainstPlayer = true;
// m_AudioManager.PlayAudio(AUDIO_FF4,m_CombatAI.GetTalkerSuffix());
// m_CombatAI.Reset(true);
// m_CombatAI.Target(&who);
// m_CombatAI.OrderAttack(true);
// MSL 5.00
// MechWarrior4::MWMission *mission = Cast_Object (MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
// Check_Object (mission);
// mission->SetEndMissionTime (30.0f);
// mission->EndMissionState (false);
// break;
// }
default:
{
app->SendSound(who.GetReplicatorID(), VehicleInterface::FRIENDLYFIREPENALTY);
break;
}
}
}
m_LastTimeNoticedFriendlyFire = (Stuff::Scalar)gos_GetElapsedTime();
}
void LancemateSquadOrders::UpdateFriendlyFireFrustration()
{
if (m_FriendlyFireFrustration > 0)
{
if (m_LastTimeNoticedFriendlyFire + 18.0f < gos_GetElapsedTime())
{
--m_FriendlyFireFrustration;
m_LastTimeNoticedFriendlyFire = (Stuff::Scalar)gos_GetElapsedTime();
}
}
}
bool LancemateSquadOrders::CanExecuteCommands() const
{
if (m_TurnedAgainstPlayer == true)
{
return (false);
}
return (true);
}
bool LancemateSquadOrders::ShouldRunScript() const
{
if ((GetLeader() != 0) &&
(GetLeader()->IsPlayerVehicle() == true))
{
return (false);
}
return (true);
}
bool LancemateSquadOrders::GetLeaderAlignment(int& alignment)
{
MWObject* leader = GetLeader();
if ((leader != 0) &&
(leader != &(m_CombatAI.GetSelf())))
{
alignment = leader->GetAlignment();
return (true);
}
return (false);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Lancemate::Lancemate()
: m_LastLeaderFireTime(0)
, m_LastPickTargetTime(0)
, m_TargetToAvoid(-2)
, m_TargetToAvoidTime(0)
{
}
Lancemate::~Lancemate()
{
{for (std::vector<CombatAI*>::iterator i = m_CombatAIsWithSquadOrders.begin();
i != m_CombatAIsWithSquadOrders.end();
++i)
{
if ((*i)->GetSquadOrders() != 0)
{
#pragma warning(disable:4239)
(*i)->SetSquadOrders(Stuff::Auto_Ptr<SquadOrders>(0));
#pragma warning(default:4239)
}
}}
}
ID Lancemate::GetID() const
{
return (GROUPAI_LANCEMATE);
}
void Lancemate::Update(Group& group, CombatAI& combat_ai)
{
if ((combat_ai.GetSquadOrders() != 0) &&
(combat_ai.GetSquadOrders()->ShouldRunScript() == true))
{
return;
}
inherited::Update(group,combat_ai);
if ((combat_ai.IsDestroyed() == true) &&
(combat_ai.GetSquadOrders() != 0))
{
NotifyMemberRemoved(group,combat_ai.GetSelf());
}
Adept::Entity* leader = GetLeader(group);
if ((leader != 0) &&
(leader->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech* mech = Cast_Object(Mech*,leader);
m_AudioManager.Update(group,*mech);
}
}
void Lancemate::NotifyShot(Group& group, Adept::ObjectID id)
{
inherited::NotifyShot(group,id);
}
void Lancemate::NotifyShotFired(Group& group,
const Stuff::Line3D& line,
MWObject& at_who,
MWObject& shooter)
{
inherited::NotifyShotFired(group,line,at_who,shooter);
Verify(&at_who != &shooter);
Verify(std::find(shooter.GetGroups().begin(),shooter.GetGroups().end(),group.GetID()) != shooter.GetGroups().end());
if (GetObjectIndex(shooter,group) != 0)
{
return;
}
Verify(std::find(at_who.GetGroups().begin(),at_who.GetGroups().end(),group.GetID()) != at_who.GetGroups().end());
if ((m_LastLeaderFireTime < gos_GetElapsedTime()) &&
(LinePenetrates(line,(Stuff::Point3D)(at_who.GetLocalToWorld()),max_too_close_to_leaders_fire_distance) == true))
{
m_LastLeaderFireTime = gos_GetElapsedTime();
Stuff::Line3D* new_line = new Stuff::Line3D;
*new_line = line;
m_LeaderFireLine.Assimilate(new_line);
}
if (m_LastPickTargetTime < gos_GetElapsedTime())
{
m_LastPickTargetTime = gos_GetElapsedTime();
Propagate_NotifyShotFired(group);
}
}
void Lancemate::Propagate_NotifyShotFired(Group& group)
{
Verify(group.GetElements().size() > 0);
// CombatAI* leader_combatai = GetLeaderCombatAI(GetLeader(group));
// TODO: get leader's target -- this will be a challenge since the "leader" can be the player
typedef std::vector<MWObject*> member_list;
member_list members;
group.GetMembers(members);
{for (member_list::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());
Check_Object(combat_ai);
if (combat_ai->GetSquadOrders() != 0)
{
combat_ai->GetSquadOrders()->NotifyShotFired();
}
}
}}
}
Stuff::Time Lancemate::GetLastLeaderFireTime() const
{
return (m_LastLeaderFireTime);
}
Stuff::Line3D* Lancemate::GetLeaderFireLine() const
{
return (m_LeaderFireLine.GetPointer());
}
void Lancemate::NotifyMemberAdded(Group& group, MWObject& who)
{
if ((who.GetAI() != 0) &&
(who.IsPlayerVehicle() == false) &&
(who.IsDestroyed() == false) &&
(who.GetAI()->IsDerivedFrom(CombatAI::DefaultData) == true))
{
CombatAI* combat_ai = Cast_Object(CombatAI*,who.GetAI());
#pragma warning(disable:4239)
LancemateSquadOrders* new_squad_orders = new LancemateSquadOrders(*combat_ai,*this,group,m_AudioManager);
combat_ai->SetSquadOrders(Stuff::Auto_Ptr<SquadOrders>(new_squad_orders));
if (std::find(m_CombatAIsWithSquadOrders.begin(),m_CombatAIsWithSquadOrders.end(),combat_ai) == m_CombatAIsWithSquadOrders.end())
{
m_CombatAIsWithSquadOrders.push_back(combat_ai);
}
Adept::Entity* leader = GetLeader(group);
if ((leader != 0) &&
(leader->IsDerivedFrom(MWObject::DefaultData) == true))
{
new_squad_orders->IssueCommand(LancemateCommands::CreateLancemateCommand(LancemateCommands::LANCEMATE_DEFAULT,*combat_ai,*(Cast_Object(MWObject*,leader)),m_AudioManager));
}
#pragma warning(default:4239)
}
}
void Lancemate::NotifyMemberRemoved(Group& group, MWObject& who)
{
Verify(who.GetAI() != 0);
Verify(who.GetAI()->IsDerivedFrom(CombatAI::DefaultData) == true);
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)
std::vector<CombatAI*>::iterator found = std::find(m_CombatAIsWithSquadOrders.begin(),m_CombatAIsWithSquadOrders.end(),combat_ai);
if (found != m_CombatAIsWithSquadOrders.end())
{
m_CombatAIsWithSquadOrders.erase(found);
}
}
}
void Lancemate::SetEntityToIgnore(Adept::ObjectID objectid)
{
SetTargetToAvoid(objectid);
}
Adept::ObjectID Lancemate::GetTargetToAvoid() const
{
if (m_TargetToAvoidTime + target_to_avoid_refresh_time > gos_GetElapsedTime())
{
return (m_TargetToAvoid);
}
return (-2);
}
void Lancemate::SetTargetToAvoid(Adept::ObjectID id)
{
m_TargetToAvoid = id;
m_TargetToAvoidTime = gos_GetElapsedTime();
}
void Lancemate::NotifyMechDestroyed(MechWarrior4::Group& group,
const Adept::ReplicatorID& inflicting_id,
const Adept::ReplicatorID& victim_id)
{
Connection *connection = Network::GetInstance()->GetConnection(victim_id.connectionID);
if (connection == 0)
{
return;
}
Replicator* rep = connection->FindReplicator(victim_id);
if (rep == 0)
{
return;
}
Entity *ent = Cast_Object(Entity*,rep);
if (ent->IsDerivedFrom(Mech::DefaultData) == false)
{
return;
}
Mech* mech = Cast_Object(Mech*,ent);
if ((mech->GetAI() == 0) ||
(mech->IsPlayerVehicle() == true))
{
return;
}
std::vector<MWObject*> lancemates;
MW4AI::Groups::GetLancemates(lancemates,false);
if (std::find(lancemates.begin(),lancemates.end(),mech) != lancemates.end())
{
m_AudioManager.PlayAudio(LancemateAudio::AUDIO_EJECT,mech->GetAI()->GetTalkerSuffix());
}
}