Files
firestorm/Gameleap/code/mw4/Code/MW4/lancemate.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

539 lines
16 KiB
C++

//===========================================================================//
// File: bridge.cpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 01/12/2000 AHF Inital base class
//===========================================================================//
#include "MW4Headers.hpp"
#include "Lancemate.hpp"
#include "AI_UserConstants.hpp"
#include "MWMission.hpp"
#include "MWTool.hpp"
using namespace MW4AI;
//#############################################################################
//############################ LancemateManager #########################
//#############################################################################
LancemateManager::ClassData* LancemateManager::DefaultData = NULL;
LancemateManager *LancemateManager::Instance = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
LancemateManagerClassID,
"MechWarrior4::LancemateManager",
Receiver::DefaultData,
0,
NULL
);
Check_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LancemateManager::LancemateManager(MemoryStream *stream)
: Receiver(DefaultData),
m_lancemates(NULL)
{
Check_Pointer(stream);
int number,i;
*stream >> number;
for (i = 0;i<number;i++)
{
LancematePlug *lance;
lance = new LancematePlug (stream);
Check_Object(lance);
m_lancemates.Add(lance);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LancemateManager::~LancemateManager()
{
Check_Object(this);
m_lancemates.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LancemateManager* LancemateManager::MakeNewLancemateManager(const char *lancematemanager_name)
{
Check_Pointer(lancematemanager_name);
Resource lancematemanager_resource(lancematemanager_name);
Verify(lancematemanager_resource.DoesResourceExist());
lancematemanager_resource.LoadData();
LancemateManager *new_lancematemanager;
new_lancematemanager = new LancemateManager(&lancematemanager_resource);
Check_Object(new_lancematemanager);
return new_lancematemanager;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LancemateManager* LancemateManager::MakeNewLancemateManager(Adept::ResourceID lancemate_id)
{
Resource lancematemanager_resource(lancemate_id);
Verify(lancematemanager_resource.DoesResourceExist());
LancemateManager *new_lancematemanager;
new_lancematemanager = new LancemateManager(&lancematemanager_resource);
Check_Object(new_lancematemanager);
return new_lancematemanager;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::ConstructLancemateStream(MemoryStream *stream,NotationFile *notation_file)
{
Check_Pointer(stream);
Check_Object (notation_file);
NotationFile::PageIterator *pages = notation_file->MakePageIterator();
Check_Object(pages);
*stream << pages->GetSize ();
Page *page_entry;
while ((page_entry = pages->ReadAndNext()) != NULL)
{
Check_Object(page_entry);
LancematePlug::ConstructStream (stream,page_entry);
}
delete pages;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::Save(MemoryStream *stream)
{
ChainIteratorOf<LancematePlug *> iterator(&m_lancemates);
LancematePlug *lancemate_plug;
*stream << m_lancemates.GetSize();
while((lancemate_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(lancemate_plug);
lancemate_plug->Save (stream);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::WriteToText(const char *file_name)
{
Stuff::NotationFile file (file_name);
ChainIteratorOf<LancematePlug *> iterator(&m_lancemates);
LancematePlug *lancemate_plug;
while((lancemate_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(lancemate_plug);
lancemate_plug->WriteToText (file);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//#############################################################################
//########################## LancematePlug ##############################
//#############################################################################
LancematePlug::LancematePlug(Stuff::MemoryStream *stream) : Plug(Plug::DefaultData)
{
MW4AI::UserConstants::IncrementRefCount();
*stream >> m_lancemateName;
*stream >> m_TalkerSuffix;
*stream >> m_lanceDataListID;
*stream >> m_MustSurvive;
int state;
*stream >> state;
m_CurrentState = (LANCEMATE_STATE) state;
*stream >> m_Joined;
*stream >> m_GunnerySkill;
*stream >> m_PilotSkill;
*stream >> m_EliteSkill;
*stream >> m_MinHeatSkill;
*stream >> m_MaxHeatSkill;
*stream >> m_SensorSkill;
*stream >> m_BlindFightingSkill;
*stream >> m_LongRangeGunnerySkill;
*stream >> m_ShortRangeGunnerySkill;
*stream >> m_TowardsPilotSkill;
*stream >> m_TowardsGunnerySkill;
*stream >> m_TowardsEliteSkill;
*stream >> m_StartGunnerySkill;
*stream >> m_StartPilotSkill;
*stream >> m_StartEliteSkill;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LancematePlug::~LancematePlug()
{
MW4AI::UserConstants::DecrementRefCount();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancematePlug::WriteToText(Stuff::NotationFile& file)
{
Check_Object(this);
Check_Object(&file);
Stuff::Page *page = file.AddPage (m_lancemateName);
page->AppendEntry ("Name",m_lancemateName);
Resource model_resource(m_lanceDataListID);
Verify(model_resource.DoesResourceExist());
page->AppendEntry("TalkerSuffix",m_TalkerSuffix);
page->AppendEntry ("Model", model_resource.GetName());
page->AppendEntry("MustSurvive",m_MustSurvive);
page->AppendEntry("CurrentState",m_CurrentState);
page->AppendEntry("Joined",m_Joined);
page->AppendEntry("Gunnery",m_GunnerySkill);
page->AppendEntry("Pilot",m_PilotSkill);
page->AppendEntry("Elite",m_EliteSkill);
page->AppendEntry("MinHeat",m_MinHeatSkill);
page->AppendEntry("MaxHeat",m_MaxHeatSkill);
page->AppendEntry("Sensor",m_SensorSkill);
page->AppendEntry("BlindFight",m_BlindFightingSkill);
page->AppendEntry("LongRange",m_LongRangeGunnerySkill);
page->AppendEntry("ShortRange",m_ShortRangeGunnerySkill);
page->AppendEntry("TowardsPilot",m_TowardsPilotSkill);
page->AppendEntry("TowardsGunnery",m_TowardsGunnerySkill);
page->AppendEntry("TowardsElite",m_TowardsEliteSkill);
page->AppendEntry("StartGunnery",m_StartGunnerySkill);
page->AppendEntry("StartPilot",m_StartPilotSkill);
page->AppendEntry("StartElite",m_StartEliteSkill);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancematePlug::Save(MemoryStream *stream)
{
*stream << m_lancemateName;
*stream << m_TalkerSuffix;
*stream << m_lanceDataListID;
*stream << m_MustSurvive;
*stream << ((int) m_CurrentState);
*stream << m_Joined;
*stream << m_GunnerySkill;
*stream << m_PilotSkill;
*stream << m_EliteSkill;
*stream << m_MinHeatSkill;
*stream << m_MaxHeatSkill;
*stream << m_SensorSkill;
*stream << m_BlindFightingSkill;
*stream << m_LongRangeGunnerySkill;
*stream << m_ShortRangeGunnerySkill;
*stream << m_TowardsPilotSkill;
*stream << m_TowardsGunnerySkill;
*stream << m_TowardsEliteSkill;
*stream << m_StartGunnerySkill;
*stream << m_StartPilotSkill;
*stream << m_StartEliteSkill;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T>
T GetPageValue(Stuff::Page *page, const char* name, T default_value)
{
T temp = default_value;
page->GetEntry(name,&temp,false);
return (temp);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancematePlug::ConstructStream(MemoryStream *stream,Stuff::Page *page)
{
Check_Object (stream);
Check_Object (page);
// *stream << page->GetName ();
MString name;
const char *name_string;
page->GetEntry("Name", &name_string, true);
name = name_string;
*stream << name;
MString talker_suffix;
const char *suffix;
page->GetEntry("TalkerSuffix", &suffix, true);
talker_suffix = suffix;
*stream << talker_suffix;
//Get the model and make sure that it is made...
const char *resource_name;
page->GetEntry("Model", &resource_name);
Resource model_resource;
Tool::Instance->ConstructDataList(&model_resource, resource_name);
Check_Object(&model_resource);
Verify(model_resource.DoesResourceExist());
*stream << model_resource.GetResourceID();
*stream << GetPageValue<bool>(page,"MustSurvive",false);
*stream << GetPageValue<int>(page,"CurrentState",0);
*stream << GetPageValue<bool>(page,"Joined",false);
*stream << GetPageValue<int>(page,"Gunnery",-1);
*stream << GetPageValue<int>(page,"Pilot",-1);
*stream << GetPageValue<int>(page,"Elite",-1);
*stream << GetPageValue<int>(page,"MinHeat",-1);
*stream << GetPageValue<int>(page,"MaxHeat",-1);
*stream << GetPageValue<int>(page,"Sensor",-1);
*stream << GetPageValue<int>(page,"BlindFight",-1);
*stream << GetPageValue<int>(page,"LongRange",-1);
*stream << GetPageValue<int>(page,"ShortRange",-1);
*stream << GetPageValue<int>(page,"TowardsPilot",-1);
*stream << GetPageValue<int>(page,"TowardsGunnery",-1);
*stream << GetPageValue<int>(page,"TowardsElite",-1);
*stream << GetPageValue<int>(page,"StartGunnery",-1);
*stream << GetPageValue<int>(page,"StartPilot",-1);
*stream << GetPageValue<int>(page,"StartElite",-1);
}
int LancematePlug::GetLanceIDBasedOnSuffix()
{
Check_Object(this);
//This is hardcoded for our game
if(!_stricmp((const char *)m_TalkerSuffix, "_GON"))
return 1;
if(!_stricmp((const char *)m_TalkerSuffix, "_CAS"))
return 4;
if(!_stricmp((const char *)m_TalkerSuffix, "_JEN"))
return 2;
if(!_stricmp((const char *)m_TalkerSuffix, "_TER"))
return 0;
if(!_stricmp((const char *)m_TalkerSuffix, "_DAM"))
return 3;
return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Skills
int DefaultedSkill(int skill_value, MW4AI::UserConstants::ID id)
{
Verify(MW4AI::UserConstants::Instance());
if (skill_value == -1)
{
return ((int)MW4AI::UserConstants::Instance ()->Get(id));
}
return skill_value;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::GunnerySkill (void) const
{
return m_GunnerySkill;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::PilotSkill (void) const
{
return m_PilotSkill;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::SensorSkill (void) const
{
return m_SensorSkill;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::BlindFightingSkill (void) const
{
return m_BlindFightingSkill;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::LongRangeGunnerySkill (void) const
{
return (DefaultedSkill(m_LongRangeGunnerySkill,MW4AI::UserConstants::default_longrange));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::ShortRangeGunnerySkill (void) const
{
return (DefaultedSkill(m_ShortRangeGunnerySkill,MW4AI::UserConstants::default_shortrange));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::EliteSkill (void) const
{
return (DefaultedSkill(m_EliteSkill,MW4AI::UserConstants::default_elite));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::MinHeatSkill (void) const
{
return (DefaultedSkill(m_MinHeatSkill,MW4AI::UserConstants::default_minheat));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int LancematePlug::MaxHeatSkill (void) const
{
return (DefaultedSkill(m_MaxHeatSkill,MW4AI::UserConstants::default_maxheat));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Stuff::Scalar GetConstantOrMissionValue(int mission_value, UserConstants::ID constant)
{
if (mission_value == -1)
{
return (UserConstants::Instance()->Get(UserConstants::eject_chance_for_lancemate) * 0.01f);
}
return (((Stuff::Scalar)mission_value) * 0.01f);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool LancematePlug::ShouldEjectSafely()
{
#if 0
if (m_MustSurvive == true)
{
m_CurrentState = OK;
return (true);
}
#endif
MechWarrior4::MWMission *mission = Cast_Object(MechWarrior4::MWMission*,MechWarrior4::MWMission::GetInstance());
Check_Object (mission);
Stuff::Scalar normalized_chance_to_eject = GetConstantOrMissionValue(mission->m_ChanceLancematesEject,
UserConstants::eject_chance_for_lancemate);
if (Stuff::Random::GetFraction() < normalized_chance_to_eject)
{
Stuff::Scalar normalized_chance_to_be_ok = GetConstantOrMissionValue(mission->m_ChanceLancematesOKWhenEjecting,
UserConstants::eject_chance_ok_when_ejected);
Stuff::Scalar normalized_chance_to_be_injured = GetConstantOrMissionValue(mission->m_ChanceLancematesInjuredWhenEjecting,
UserConstants::eject_chance_injured_when_ejected);
Stuff::Scalar random = Stuff::Random::GetFraction();
if (random < normalized_chance_to_be_ok)
{
m_CurrentState = OK;
}
else
{
if (random < normalized_chance_to_be_injured + normalized_chance_to_be_ok)
{
m_CurrentState = INJURED;
}
else
{
if (m_MustSurvive)
m_CurrentState = INJURED;
else
m_CurrentState = MIA;
}
}
return (true);
}
if (m_MustSurvive)
m_CurrentState = INJURED;
else
m_CurrentState = KIA;
return (false);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::RevealLancemate (char *name)
{
LancematePlug *plug;
plug = FindLancemate (name,false);
Verify (plug);
plug->Joined (true);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void LancemateManager::HideLancemate (char *name)
{
LancematePlug *plug;
plug = FindLancemate (name,false);
Verify (plug);
plug->Joined (false);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LancematePlug*
LancemateManager::FindLancemate(MString lance_name,bool case_sensitive)
{
//
// We can't use sorted chain or the data doesn't appear in the same order as the
// campaign source file. But the normal chain does not have a find value.
//
Verify(lance_name);
ChainIteratorOf<LancematePlug *> find_iterator(&m_lancemates);
LancematePlug *cur_lance;
while ((cur_lance = find_iterator.ReadAndNext()) != NULL)
{
if (case_sensitive)
{
if (cur_lance->m_lancemateName == lance_name)
break;
}
else
{
if (!strnicmp ((char *) cur_lance->m_lancemateName,lance_name,sizeof (lance_name)))
break;
}
}
return cur_lance;
}