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

1369 lines
36 KiB
C++

#include "MW4Headers.hpp"
#include "MWCampaign.hpp"
#include "MWMission.hpp"
#include "MW4Shell.hpp"
#include "MWApplication.hpp"
#include <Adept\Tool.hpp>
#include <Stuff\NameList.hpp>
//#############################################################################
//#################### MWMissionMapPoint ################################
//#############################################################################
void
MWMissionMapPoint::ConstructMissionMapPointStream(Stuff::Page *page, Stuff::MemoryStream *stream)
{
Check_Object(page);
Check_Pointer(stream);
const char *type_string;
int type = 0;
page->GetEntry("Type", &type_string, true);
if(!_stricmp(type_string, "NavPoint"))
type = NavPointType;
else if(!_stricmp(type_string, "DropPoint"))
type = DropPointType;
else if(!_stricmp(type_string, "InfoPoint"))
type = InfoPointType;
else if(!_stricmp(type_string, "GeneralInfoPoint"))
type = GeneralInfoPointType;
else
STOP(("%s Is not a valid map point type", type_string));
*stream << type;
int value;
page->GetEntry("XLocation", &value, true);
*stream << value;
page->GetEntry("YLocation", &value, true);
*stream << value;
page->GetEntry("Width", &value, true);
*stream << value;
page->GetEntry("Height", &value, true);
*stream << value;
page->GetEntry("PointNameIndex", &value, true);
*stream << value;
page->GetEntry("RollOverIndex", &value, true);
*stream << value;
page->GetEntry("RightClickIndex", &value, true);
*stream << value;
if(type >= InfoPointType)
{
const char *icon_name;
MString icon_mstring;
page->GetEntry("IconName", &icon_name, true);
icon_mstring = icon_name;
*stream << icon_mstring;
}
}
//#############################################################################
//#################### MWCampaignInterfacePlug ##########################
//#############################################################################
MWCampaignInterfacePlug::MWCampaignInterfacePlug(Stuff::MemoryStream *stream) :
Plug(Plug::DefaultData),
m_navPoints(NULL),
m_dropPoints(NULL),
m_infoPoints(NULL),
m_generalInfoPoints(NULL)
{
*stream >> m_xLoc;
*stream >> m_yLoc;
*stream >> m_height;
*stream >> m_width;
*stream >> m_ID;
*stream >> m_rollOverID;
*stream >> m_rightClickID;
*stream >> m_iconName;
*stream >> m_mapTextureName;
//read in the mission point streams
int point_count;
*stream >> point_count;
for(int i=0; i< point_count; i++)
{
MWMissionMapPoint *map_point = new MWMissionMapPoint(stream);
Check_Object(map_point);
switch(map_point->m_pointType)
{
case MWMissionMapPoint::NavPointType:
m_navPoints.Add(map_point);
break;
case MWMissionMapPoint::DropPointType:
m_dropPoints.Add(map_point);
break;
case MWMissionMapPoint::InfoPointType:
m_infoPoints.Add(map_point);
case MWMissionMapPoint::GeneralInfoPointType:
m_generalInfoPoints.Add(map_point);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWCampaignInterfacePlug::~MWCampaignInterfacePlug()
{
m_navPoints.DeletePlugs();
m_dropPoints.DeletePlugs();
m_infoPoints.DeletePlugs();
m_generalInfoPoints.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaignInterfacePlug::ConstructCampaignInterfaceStream(MemoryStream *stream, Page *page)
{
Check_Object(page);
Check_Pointer(stream);
int value = 0;
page->GetEntry("MissionRegionXLocation", &value);
*stream << value;
value = 0;
page->GetEntry("MissionRegionYLocation", &value);
*stream << value;
value = 0;
page->GetEntry("MissionRegionHeight", &value);
*stream << value;
value = 0;
page->GetEntry("MissionRegionWidth", &value);
*stream << value;
value = 0;
page->GetEntry("DisplayNameIndex", &value);
*stream << value;
value = 0;
page->GetEntry("RollOverIndex", &value);
*stream << value;
value = 0;
page->GetEntry("RightClickIndex", &value);
*stream << value;
const char *name;
MString m_string = " ";
if(page->GetEntry("MapIconName", &name))
m_string = name;
*stream << m_string;
m_string = " ";
if(page->GetEntry("MapTextureName", &name))
m_string = name;
*stream << m_string;
//Now we need to build in all the mission parameters
const char *map_info_file;
int point_count = 0;
if(page->GetEntry("MissionMapInfo", &map_info_file))
{
NotationFile *note_file = new NotationFile(map_info_file);
Check_Object(note_file);
NotationFile::PageIterator *pages = note_file->MakePageIterator();
Page *point_page;
Check_Object(pages);
*stream << pages->GetSize();
while((point_page = pages->ReadAndNext()) != NULL)
{
Check_Object(point_page);
MWMissionMapPoint::ConstructMissionMapPointStream(point_page, stream);
}
delete pages;
delete note_file;
}
else
{
*stream << point_count;
}
}
//#############################################################################
//#################### CampaignMissionPlug ##############################
//#############################################################################
CampaignMissionPlug::CampaignMissionPlug(const char *mission_name) :
Plug(Plug::DefaultData),
m_missionsNeededToDisplay(NULL)
{
Check_Pointer(mission_name);
m_missionName = mission_name;
m_status = -1;
m_type = MWCampaign::NormalMissionType;
m_triggerPercentage = 100;
m_triggerMission = NULL;
m_opNumber = -1;
m_displayNameIndex = -1;
m_NumLancemates = 1;
m_interfacePlugID = ResourceID::Null;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CampaignMissionPlug::~CampaignMissionPlug()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CampaignMissionPlug::SetTriggerMission(CampaignMissionPlug *mission_plug, int percent)
{
Check_Object(this);
Check_Object(mission_plug);
m_triggerMission = mission_plug;
m_triggerPercentage = percent;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CampaignMissionPlug::AddDisplayDependancy(CampaignMissionPlug *mission_plug)
{
Check_Object(this);
Check_Object(mission_plug);
m_missionsNeededToDisplay.Add(mission_plug);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CampaignMissionPlug::RemoveDisplayDependancy(CampaignMissionPlug *mission_plug)
{
Check_Object(this);
Check_Object(mission_plug);
m_missionsNeededToDisplay.Remove(mission_plug);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CampaignMissionPlug::WriteToText(Stuff::Page *page)
{
Check_Object(this);
Check_Pointer(page);
page->SetEntry("Status", MWCampaign::StatusAsciiToText(m_status));
page->SetEntry("NumLancemates", m_NumLancemates);
page->SetEntry("Type", MWCampaign::MissionTypeAsciiToText(m_type));
if(m_triggerMission)
{
page->SetEntry("TriggerMission", m_triggerMission->m_missionName);
page->SetEntry("TriggerPercentage", m_triggerPercentage);
}
ChainIteratorOf<CampaignMissionPlug *> iterator(&m_missionsNeededToDisplay);
CampaignMissionPlug *mission_plug;
while((mission_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(mission_plug);
page->AppendEntry("MissionNeededToDisplay", mission_plug->m_missionName);
}
}
//#############################################################################
//#################### OperationPlug ####################################
//#############################################################################
void
OperationPlug::ConstructOperationStream(Page *page, MemoryStream *stream)
{
Check_Pointer(page);
Check_Pointer(stream);
int name_index = -1;
page->GetEntry("OperationNameIndex", &name_index, true);
*stream << name_index;
const char *texture_name;
MString texture_string;
page->GetEntry("MapTextureName", &texture_name, true);
texture_string = texture_name;
*stream << texture_string;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
OperationPlug::SaveToStream(Stuff::MemoryStream *stream)
{
Check_Pointer(stream);
*stream << m_nameIndex;
*stream << m_mapTextureName;
}
//#############################################################################
//#################### MoviePlug ########################################
//#############################################################################
void
MoviePlug::ConstructMoviePlugStream(Page *page, MemoryStream *stream)
{
Check_Pointer(page);
Check_Pointer(stream);
const char *temp_string;
MString stream_string;
page->GetEntry("MovieName", &temp_string, true);
stream_string = temp_string;
*stream << stream_string;
int type;
page->GetEntry("Type", &temp_string, true);
type = MovieTypeStringToAscii(temp_string);
*stream << type;
int delay = 0;
page->GetEntry("Delay", &delay);
*stream << delay;
//This is just needed to fill the default stream since this will always be false
bool has_played = false;
*stream << has_played;
page->GetEntry("TriggerName", &temp_string, true);
stream_string = temp_string;
*stream << stream_string;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MoviePlug::SaveToStream(MemoryStream *stream)
{
Check_Object(this);
Check_Pointer(stream);
*stream << m_movieName;
*stream << m_type;
*stream << m_delay;
*stream << m_hasPlayed;
*stream << m_triggerName;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MoviePlug::MovieTypeStringToAscii(const char *type_string)
{
if(!_stricmp(type_string, "MissionSuccess"))
return MissionSuccessType;
if(!_stricmp(type_string, "MissionSelection"))
return MissionSelectionType;
if(!_stricmp(type_string, "LancemateDeath"))
return LancemateDeathType;
if(!_stricmp(type_string, "LancemateReturn"))
return LancemateReturnType;
PAUSE(("That is a Movie Plug Type: %s", type_string));
return -1;
}
//#############################################################################
//#################### MovieManager #####################################
//#############################################################################
MWMovieManager::MWMovieManager() :
m_successMovies(NULL),
m_selectionMovies(NULL),
m_lancemateDeathMovies(NULL),
m_lancemateReturnMovies(NULL),
m_delayedMovies(NULL, false)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWMovieManager::~MWMovieManager()
{
m_successMovies.DeletePlugs();
m_selectionMovies.DeletePlugs();
m_lancemateDeathMovies.DeletePlugs();
m_lancemateReturnMovies.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::ExecuteMissionSuccess(const char *mission_name)
{
Check_Pointer(mission_name);
//Ok here we want to run through and play all movies in the success chain
ChainIteratorOf<MoviePlug *> iterator(&m_successMovies);
MoviePlug *movie_plug;
while((movie_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
if(!stricmp(movie_plug->GetTriggerName(), mission_name))
{
if(MW4Shell::Instance)
StartMovie(movie_plug);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::ExecuteMissionSelection(const char *mission_name)
{
Check_Pointer(mission_name);
ChainIteratorOf<MoviePlug *> iterator(&m_selectionMovies);
MoviePlug *movie_plug;
while((movie_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
if(!stricmp(movie_plug->GetTriggerName(), mission_name))
{
if((MW4Shell::Instance) && (!movie_plug->m_playedThisSelection))
{
StartMovie(movie_plug);
movie_plug->m_playedThisSelection = true;
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::ExecuteLancemateDeath(const char *lance_name)
{
Check_Pointer(lance_name);
ChainIteratorOf<MoviePlug *> iterator(&m_lancemateDeathMovies);
MoviePlug *movie_plug;
while((movie_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
if(!stricmp(movie_plug->GetTriggerName(), lance_name))
{
if(MW4Shell::Instance)
StartMovie(movie_plug);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::ExecuteLancemateReturn(const char *lance_name)
{
Check_Pointer(lance_name);
ChainIteratorOf<MoviePlug *> iterator(&m_lancemateReturnMovies);
MoviePlug *movie_plug;
while((movie_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
if(!stricmp(movie_plug->GetTriggerName(), lance_name))
{
if(MW4Shell::Instance)
StartMovie(movie_plug);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::StartMovie(MoviePlug *movie_plug)
{
Check_Object(movie_plug);
Time execute_time = gos_GetElapsedTime();
execute_time += movie_plug->GetMovieDelay();
m_delayedMovies.AddValue(movie_plug, execute_time);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::Execute()
{
Time now_time = gos_GetElapsedTime();
SortedChainIteratorOf<MoviePlug *, Time> iterator(&m_delayedMovies);
while((iterator.GetCurrent() != NULL) && (iterator.GetValue() <= now_time))
{
MoviePlug *movie_plug;
Time execute_time = iterator.GetValue();
movie_plug = iterator.GetCurrent();
iterator.Remove();
if((!MW4Shell::Instance->m_moviePlaying) && (!MW4Shell::Instance->m_moviesStopped))
{
MW4Shell::Instance->m_moviePlaying = 1;
MW4Shell::Instance->AddNewMovie(movie_plug->GetMovieName());
}
else
m_delayedMovies.AddValue(movie_plug, execute_time + 0.28f);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::AddMoviePlug(MoviePlug *new_movie)
{
Check_Object(new_movie);
switch(new_movie->GetMovieType())
{
case MoviePlug::MissionSuccessType:
m_successMovies.Add(new_movie);
break;
case MoviePlug::MissionSelectionType:
m_selectionMovies.Add(new_movie);
break;
case MoviePlug::LancemateDeathType:
m_lancemateDeathMovies.Add(new_movie);
break;
case MoviePlug::LancemateReturnType:
m_lancemateReturnMovies.Add(new_movie);
break;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMovieManager::SaveToStream(MemoryStream *stream)
{
Check_Pointer(stream);
int num_movies = 0;
num_movies += m_successMovies.GetSize();
num_movies += m_selectionMovies.GetSize();
num_movies += m_lancemateDeathMovies.GetSize();
num_movies += m_lancemateReturnMovies.GetSize();
*stream << num_movies;
ChainIteratorOf<MoviePlug *> success_iterator(&m_successMovies);
ChainIteratorOf<MoviePlug *> selection_iterator(&m_selectionMovies);
ChainIteratorOf<MoviePlug *> lance_death_iterator(&m_lancemateDeathMovies);
ChainIteratorOf<MoviePlug *> lance_return_iterator(&m_lancemateReturnMovies);
MoviePlug *movie_plug;
while((movie_plug = success_iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
movie_plug->SaveToStream(stream);
}
while((movie_plug = selection_iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
movie_plug->SaveToStream(stream);
}
while((movie_plug = lance_death_iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
movie_plug->SaveToStream(stream);
}
while((movie_plug = lance_return_iterator.ReadAndNext()) != NULL)
{
Check_Object(movie_plug);
movie_plug->SaveToStream(stream);
}
}
//#############################################################################
//########################### Campaign ###################################
//#############################################################################
MWCampaign::ClassData*
MWCampaign::DefaultData = NULL;
MWCampaign*
MWCampaign::Instance = NULL;
MWCampaign*
MWCampaign::TrainingInstance = NULL;
MWCampaign*
MWCampaign::WaveInstance = NULL;
MWCampaign*
MWCampaign::MasterTrialsInstance = NULL;
HGOSHEAP
MWCampaign::s_Heap = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::InitializeClass()
{
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("MWCampaign", 0, g_LibraryHeap);
Check_Pointer(s_Heap);
Verify(!DefaultData);
DefaultData =
new ClassData(
MWCampaignClassID,
"MechWarrior4::MWCampaign",
Receiver::DefaultData,
0,
NULL
);
Check_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWCampaign::MWCampaign(MemoryStream *stream):
Receiver(DefaultData),
m_missions(NULL),
m_operations(NULL, true)
{
Check_Pointer(stream);
//Load the movies
m_movieManager = new MWMovieManager();
int num_movies;
*stream >> num_movies;
for(int i=0; i<num_movies; i++)
{
MoviePlug *movie_plug = new MoviePlug(stream);
Check_Object(movie_plug);
m_movieManager->AddMoviePlug(movie_plug);
}
//Load the Ops
int num_ops;
*stream >> num_ops;
for(i=0; i<num_ops; i++)
{
OperationPlug *op_plug = new OperationPlug(stream);
Check_Object(op_plug);
op_plug->SetID(i);
m_operations.AddValue(op_plug, i);
}
*stream >> m_currentOp;
//Load the missions
int num_missions;
*stream >> num_missions;
for(i=0; i<num_missions; i++)
{
MString mission_name;
*stream >> mission_name;
CampaignMissionPlug *mission_plug =
new CampaignMissionPlug((const char *)mission_name);
m_missions.AddPlug(mission_plug);
}
ChainIteratorOf<CampaignMissionPlug *> iterator(&m_missions);
CampaignMissionPlug *mission_plug;
while((mission_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(mission_plug);
int display_index;
*stream >> display_index;
mission_plug->SetDisplayNameIndex(display_index);
int status;
*stream >> status;
mission_plug->SetStatus(status);
int numlance;
*stream >> numlance;
mission_plug->SetNumLancemates (numlance);
int type;
*stream >> type;
mission_plug->SetType(type);
int op_number;
*stream >> op_number;
mission_plug->SetOpNumber(op_number);
int advance_to_op;
*stream >> advance_to_op;
mission_plug->SetAdvanceToOperation(advance_to_op);
OperationPlug *op_plug = m_operations.Find(op_number);
if(op_plug)
op_plug->m_missions.AddPlug(op_plug);
ResourceID interface_id;
*stream >> interface_id;
mission_plug->SetInterfacePlugID(interface_id);
int does_end;
*stream >> does_end;
mission_plug->m_doesEnd = does_end;
MString end_movie;
*stream >> end_movie;
mission_plug->m_finalMovieName = end_movie;
int change_time;
*stream >> change_time;
mission_plug->m_canChangeTime = change_time;
bool has_trigger;
*stream >> has_trigger;
if(has_trigger)
{
MString trigger_mission_name;
int percentage;
*stream >> trigger_mission_name;
*stream >> percentage;
CampaignMissionPlug *trigger_mission;
trigger_mission = FindMission(trigger_mission_name);
Check_Object(trigger_mission);
mission_plug->SetTriggerMission(trigger_mission, percentage);
}
int mission_num;
*stream >> mission_num;
for(int i=0; i<mission_num; i++)
{
MString dependant_mission_name;
*stream >> dependant_mission_name;
CampaignMissionPlug *dependant_mission;
dependant_mission = FindMission(dependant_mission_name);
if(dependant_mission)
mission_plug->AddDisplayDependancy(dependant_mission);
#if defined(LAB_ONLY)
else
PAUSE(("There is no mission with the name %s", (const char *)dependant_mission_name));
#endif
}
}
MString last_mission_name;
*stream >> last_mission_name;
*stream >> m_finalMovieName;
m_lastMissionPlug = FindMission(last_mission_name);
m_missionsIterator = new ChainIteratorOf<CampaignMissionPlug*>(&m_missions);
//Now walk the iterator to be at the current mission plug
//DAVE HERE!!!!
CampaignMissionPlug *temp_plug = m_missionsIterator->GetCurrent();
if(temp_plug)
{
while((temp_plug != NULL) && ((temp_plug->m_status == Completed) || (temp_plug->m_opNumber != m_currentOp)))
{
if(temp_plug->m_status == Completed)
m_lastMissionPlug = temp_plug;
temp_plug = m_missionsIterator->GetCurrent();
if(temp_plug)
m_missionsIterator->Next();
}
}
//Now do our set for the next mission
m_currentMissionPlug = temp_plug;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CampaignMissionPlug*
MWCampaign::FindMission(MString mission_name)
{
//
// 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(mission_name);
mission_name.ToLower();
ChainIteratorOf<CampaignMissionPlug *> find_iterator(&m_missions);
CampaignMissionPlug *cur_mission;
while ((cur_mission = find_iterator.ReadAndNext()) != NULL)
{
if (cur_mission->m_missionName == mission_name)
break;
}
return cur_mission;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CampaignMissionPlug*
MWCampaign::FindMission(int display_index)
{
ChainIteratorOf<CampaignMissionPlug *> find_iterator(&m_missions);
CampaignMissionPlug *cur_mission;
while ((cur_mission = find_iterator.ReadAndNext()) != NULL)
{
if (cur_mission->m_displayNameIndex == display_index)
break;
}
return cur_mission;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWCampaign::~MWCampaign()
{
Check_Object(this);
m_missionsIterator->DeletePlugs();
m_operations.DeletePlugs();
delete m_missionsIterator;
delete m_movieManager;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWCampaign*
MWCampaign::MakeNewCampaign(const char *campaign_name)
{
Check_Pointer(campaign_name);
Resource campaign_resource(campaign_name);
Verify(campaign_resource.DoesResourceExist());
campaign_resource.LoadData();
gos_PushCurrentHeap(s_Heap);
MWCampaign *new_campaign;
new_campaign = new MWCampaign(&campaign_resource);
Check_Object(new_campaign);
gos_PopCurrentHeap();
return new_campaign;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWCampaign*
MWCampaign::MakeNewCampaign(const ResourceID& campaign_id)
{
Verify(campaign_id != ResourceID::Null);
Resource campaign_resource(campaign_id);
Verify(campaign_resource.DoesResourceExist());
campaign_resource.LoadData();
gos_PushCurrentHeap(s_Heap);
MWCampaign *new_campaign;
new_campaign = new MWCampaign(&campaign_resource);
Check_Object(new_campaign);
gos_PopCurrentHeap();
return new_campaign;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::ConstructCampaignStream(
MemoryStream *stream,
NotationFile *notation_file
)
{
Check_Pointer(stream);
NotationFile::PageIterator *pages = notation_file->MakePageIterator();
Check_Object(pages);
Page *page;
int op_size = 0;
int mission_size = 0;
int movie_size = 0;
//First figure out the sizes
while((page = pages->ReadAndNext()) != NULL)
{
Check_Object(page);
const char *page_name = page->GetName();
if(strstr(page_name, "operation"))
op_size ++;
else if(strstr(page_name, "movie"))
movie_size ++;
else
mission_size ++;
}
//First we do the movies
*stream << movie_size;
pages->First();
while((page = pages->ReadAndNext()) != NULL)
{
Check_Pointer(page);
const char *page_name = page->GetName();
if(strstr(page_name, "movie"))
{
MoviePlug::ConstructMoviePlugStream(page, stream);
}
}
//Second we do the Operations
*stream << op_size;
pages->First();
while((page = pages->ReadAndNext()) != NULL)
{
Check_Pointer(page);
const char *page_name = page->GetName();
if(strstr(page_name, "operation"))
{
OperationPlug::ConstructOperationStream(page, stream);
}
}
int current_op = 0;
*stream << current_op;
//Now do the missions
*stream << mission_size;
pages->First();
while((page = pages->ReadAndNext()) != NULL)
{
Check_Pointer(page);
const char *page_name = page->GetName();
if((!strstr(page_name, "operation")) && (!strstr(page_name, "movie")))
{
MString instance_string = page_name;
*stream << instance_string;
}
}
pages->First();
MString first_mission_name;
while((page = pages->ReadAndNext()) != NULL)
{
Check_Pointer(page);
const char *page_name = page->GetName();
if((!strstr(page_name, "operation")) && (!strstr(page_name, "movie")))
{
if(!first_mission_name)
first_mission_name = page_name;
int display_index = -1;
page->GetEntry("DisplayNameIndex", &display_index);
*stream << display_index;
const char *status_string;
page->GetEntry("Status", &status_string, true);
*stream << StatusTextToAscii(status_string);
int numlance = 1;
page->GetEntry("NumLancemates",&numlance);
*stream << numlance;
const char *type_string;
int type = NormalMissionType;
if(page->GetEntry("Type", &type_string))
{
type = MissionTypeTextToAscii(type_string);
}
*stream << type;
int op_number = 0;
page->GetEntry("OPNumber", &op_number);
*stream << op_number;
int advance_to_op = op_number;
page->GetEntry("AdvanceToOpNumber", &advance_to_op);
*stream << advance_to_op;
DynamicMemoryStream interface_stream;
MWCampaignInterfacePlug::ConstructCampaignInterfaceStream(&interface_stream, page);
if(interface_stream.GetSize() > 0)
{
MString interface_resource_name = page_name;
interface_resource_name += "{CampaignInterfacePlug}";
Resource campaign_interface_resource(interface_resource_name);
FileDependencies dependencies(*notation_file->GetFileDependencies());
campaign_interface_resource.Save(&interface_stream, &dependencies);
*stream << campaign_interface_resource.GetResourceID();
}
else
{
*stream << ResourceID::Null;
}
int does_end = 0;
page->GetEntry("DoesEndCampaign", &does_end);
*stream << does_end;
const char *end_movie = "";
MString end_movie_string;
page->GetEntry("TriggerEndMovieName", &end_movie);
end_movie_string = end_movie;
*stream << end_movie_string;
int change_time = 1;
page->GetEntry("CanChangeTime", &change_time);
*stream << change_time;
const char *trigger_mission_name;
if(page->GetEntry("TriggerMission", &trigger_mission_name))
{
MString trigger_name = trigger_mission_name;
int percentage = 100;
bool has_trigger = true;
page->GetEntry("TriggerPercentage", &percentage);
*stream << has_trigger;
*stream << trigger_name;
*stream << percentage;
}
else
{
bool has_trigger = false;
*stream << has_trigger;
}
ChainOf<Note*> *missions = page->MakeNoteChain("RevealOnComplete");
Check_Object(missions);
Page::NoteIterator mission_list(missions);
Note *mission_entry;
*stream << mission_list.GetSize();
while ((mission_entry = mission_list.ReadAndNext()) != NULL)
{
Check_Object(mission_entry);
const char *mission_data = NULL;
mission_entry->GetEntry(&mission_data);
Check_Pointer(mission_data);
MString mission_name = mission_data;
*stream << mission_name;
}
delete missions;
}
}
//Save out the first mission name
*stream << first_mission_name;
MString end_movie_name;
*stream << end_movie_name;
delete pages;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::Save(MemoryStream *stream)
{
Check_Object(this);
Check_Pointer(stream);
//First save all the movies in the movie manager
m_movieManager->SaveToStream(stream);
//Second save all the operations
SortedChainIteratorOf<OperationPlug *, int> op_iterator(&m_operations);
OperationPlug *op_plug;
int op_size = op_iterator.GetSize();
*stream << op_size;
while((op_plug = op_iterator.ReadAndNext()) != NULL)
{
Check_Object(op_plug);
op_plug->SaveToStream(stream);
}
*stream << m_currentOp;
//Last save all the mission data
ChainIteratorOf<CampaignMissionPlug*> iterator(&m_missions);
CampaignMissionPlug *mission_plug;
int size = iterator.GetSize();
*stream << size;
while((mission_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(mission_plug);
*stream << mission_plug->m_missionName;
}
iterator.First();
while((mission_plug = iterator.ReadAndNext()) != NULL)
{
Check_Object(mission_plug);
*stream << mission_plug->m_displayNameIndex;
*stream << mission_plug->m_status;
*stream << mission_plug->m_NumLancemates;
*stream << mission_plug->m_type;
*stream << mission_plug->m_opNumber;
*stream << mission_plug->m_advacnceToOperation;
*stream << mission_plug->m_interfacePlugID;
*stream << mission_plug->m_doesEnd;
*stream << mission_plug->m_finalMovieName;
*stream << mission_plug->m_canChangeTime;
bool does_trigger_mission = false;
if(mission_plug->m_triggerMission != NULL)
{
does_trigger_mission = true;
}
*stream << does_trigger_mission;
if(does_trigger_mission)
{
*stream << mission_plug->m_triggerMission->m_missionName;
*stream << mission_plug->m_triggerPercentage;
}
ChainIteratorOf<CampaignMissionPlug *> display_missions(&mission_plug->m_missionsNeededToDisplay);
CampaignMissionPlug *display_plug;
size = display_missions.GetSize();
*stream << size;
while ((display_plug = display_missions.ReadAndNext()) != NULL)
{
Check_Object(display_plug);
*stream << display_plug->m_missionName;
}
}
*stream << m_currentMissionPlug->m_missionName;
*stream << m_finalMovieName;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::WriteToText(const char *file_name)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MWCampaign::StatusTextToAscii(const char *status_string)
{
if(!_stricmp(status_string, "Hidden"))
return Hidden;
if(!_stricmp(status_string, "Displayed"))
return Displayed;
if(!_stricmp(status_string, "Completed"))
return Completed;
PAUSE(("That is not a valid status string %s", status_string));
return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char *
MWCampaign::StatusAsciiToText(int status)
{
switch(status)
{
case Hidden:
return "Hidden";
case Displayed:
return "Displayed";
case Completed:
return "Completed";
}
PAUSE(("That is not a valid status value"));
return "Bad";
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MWCampaign::MissionTypeTextToAscii(const char *type_string)
{
if(!_stricmp(type_string, "Normal"))
return NormalMissionType;
if(!_stricmp(type_string, "Defend"))
return DefendMissionType;
if(!_stricmp(type_string, "Rescue"))
return RescueMissionType;
PAUSE(("That is not a valid mission type string %s", type_string));
return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char *
MWCampaign::MissionTypeAsciiToText(int type)
{
switch(type)
{
case NormalMissionType:
return "Normal";
case DefendMissionType:
return "Defend";
case RescueMissionType:
return "Rescue";
}
PAUSE(("That is not a valid Mission Type"));
return "Bad";
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char *
MWCampaign::GetNextMission()
{
Check_Object(this);
CampaignMissionPlug *mission;
mission = m_missionsIterator->GetCurrent();
m_missionsIterator->Next();
if(!m_missionsIterator->GetCurrent())
m_missionsIterator->First();
return mission->m_missionName;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CampaignMissionPlug*
MWCampaign::GetNextMissionPlug()
{
Check_Object(this);
CampaignMissionPlug *mission;
mission = m_missionsIterator->GetCurrent();
if(mission)
{
m_missionsIterator->Next();
}
if(!m_missionsIterator->GetCurrent())
m_missionsIterator->First();
//This means that there is only one mission in the chain
if(!mission)
mission = m_missionsIterator->GetCurrent();
return mission;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::MissionSuccess()
{
Check_Object(this);
if(m_currentMissionPlug)
{
m_currentMissionPlug->SetStatus(Completed);
m_currentOp = m_currentMissionPlug->m_advacnceToOperation;
if(!m_currentMissionPlug->m_doesEnd)
m_finalMovieName = m_currentMissionPlug->m_finalMovieName;
//
//--------------------------------------
//Check if we need to rescue a lancemate
//--------------------------------------
//
if(m_currentMissionPlug->m_triggerMission)
{
if((m_currentMissionPlug->m_triggerMission->m_type == RescueMissionType) &&
(m_currentMissionPlug->m_triggerMission->m_status != Completed))
//&& we lost a lancemate
{
m_currentMissionPlug->m_triggerMission->SetStatus(Displayed);
}
}
//
//-----------------------------------------------------
//Run Through the missions and check their dependancies
//-----------------------------------------------------
//
CampaignMissionPlug *mission;
ChainIteratorOf<CampaignMissionPlug *> iterator(&m_missions);
while((mission = iterator.ReadAndNext()) != NULL)
{
Check_Object(mission);
if(mission->m_missionsNeededToDisplay.IsPlugMember(m_currentMissionPlug))
{
mission->m_missionsNeededToDisplay.Remove(m_currentMissionPlug);
if(mission->m_missionsNeededToDisplay.IsEmpty())
mission->SetStatus(Displayed);
}
}
//
//-----------------------------------------------------------------
//Check to see if we are going to be attacked...if so set the timer
//-----------------------------------------------------------------
//
if(m_currentMissionPlug->m_triggerMission)
{
if((m_currentMissionPlug->m_triggerMission->m_type == DefendMissionType) &&
(m_currentMissionPlug->m_triggerMission->m_status != Completed))
//&& we lost a lancemate
{
//We need to some how set a timer here....and then launch!
m_currentMissionPlug->m_triggerMission->SetStatus(Displayed);
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MWCampaign::GetOPMissionCount()
{
Check_Object(this);
CampaignMissionPlug *mission;
ChainIteratorOf<CampaignMissionPlug *> iterator(&m_missions);
int mission_count = 0;
while((mission = iterator.ReadAndNext()) != NULL)
{
Check_Object(mission);
if((mission->m_status != Hidden) && (mission->m_opNumber == m_currentOp))
mission_count ++;
}
return mission_count;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWCampaign::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}