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

3177 lines
80 KiB
C++

//===========================================================================//
// File: MWMission.cpp //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/09/98 JSE Inital base class based off of Shadowrun/Adept //
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "MWMission.hpp"
#include "VehicleInterface.hpp"
#include "Narc.hpp"
#include "MWGUIManager.hpp"
#include "MWGame.hpp"
#include "rail_move.hpp"
#include "move_formation.hpp"
#include "abl.h"
#include "obstacle.hpp"
#include "ai.hpp"
#include "gameinfo.hpp"
#include "AI_CombatTacticInterface.hpp"
#include "cameraship.hpp"
#include "ai_groups.hpp"
#include "data_client.hpp"
#include "AI_Statistics.hpp"
#include "AI_UserConstants.hpp"
#include "AI_Types.hpp"
#include "MWDebugHelper.hpp"
#include "MWApplication.hpp"
#include "GameTypes.h"
#include "MWObject.hpp"
#include "CombatAI.hpp"
#include "mwguimanager.hpp"
#include "hudcomm.hpp"
#include "DamageDispatch.hpp"
#include "ABLAudio.hpp"
#include "MWPlayer.hpp"
#include "HeatManager.hpp"
#include <Adept\Tool.hpp>
#include <Adept\Mission.hpp>
#include <Adept\Controls.hpp>
// MSL 5.02 headshot
#include <Adept\DamageObject.hpp>
#include <Adept\VideoRenderer.hpp>
#include <Adept\CameraComponent.hpp>
#include <Adept\Map.hpp>
#include "NavPoint.hpp"
#include "mech.hpp"
#include "Team.hpp"
#include <ElementRenderer\StateChange.hpp>
#include <MLR\MLRTexturePool.hpp>
#include <MLR\MLRTexture.hpp>
#include <MissionLang\Resource.h>
#include <mbstring.h>
#define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c))
#include "bucket.hpp"
// ngLog addition // JKK
#if !defined(NO_LOG)
#include "nglog_mw4.hpp"
#endif // !defined(NO_LOG)
#include "windows.h"
#include "ctcls.h" // jcem
#include "ctcl.h" // jcem
#include "recscore.h" // jcem
extern int g_nMR;
#ifdef LAB_ONLY
extern float frameRate;
extern DWORD PrimitivesRendered;
extern DWORD PointsRendered;
extern DWORD LinesRendered;
extern DWORD TrianglesRendered;
extern DWORD QuadsRendered;
extern DWORD TextureKUsed,AlphaTextureKUsed,TextureVKUsed;
extern DWORD MidLevelRenderer::LitVertices;
#endif
extern int GetScore4Player(int& nKills, int& nDeaths);
namespace ABL
{
bool ObjectIDisGroup(long object_id);
Group::identifier ObjectIDtoGroupID(long object_id);
};
#pragma warning (push)
#include <vector>
#pragma warning (pop)
DECLARE_TIMER(static, Mission_Script_Time);
const Stuff::Scalar nav_refresh_delay = 2.0f;
//#############################################################################
//############################### MWMission #############################
//#############################################################################
MWMission::ClassData*
MWMission::DefaultData = NULL;
void ABL_Debug_func (char *s);
namespace ABL
{
extern TypePtr IntegerTypePtr;
TypePtr execStandardRoutineCall (SymTableNodePtr routineIdPtr);
};
namespace MW4AI
{
extern __int64 tABLTime;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
MWMissionClassID,
"MechWarrior4::MWMission",
Mission::DefaultData,
0, NULL,
(Entity::Factory)Make,
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
ExecutionStateEngine::DefaultData,
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
NULL,
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
(Entity::GameModel::ModelSave)GameModel::SaveGameModel
);
Register_Object(DefaultData);
CUSTOM_DIRECT_ATTRIBUTE(MWMission,
StartMusicStatus,startMusicStatus,int,IntClassID);
CUSTOM_DIRECT_ATTRIBUTE(MWMission,
TransMusicStatus,transMusicStatus,int,IntClassID);
Initialize_Timer(Mission_Script_Time, "Mission_Script_Time");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
bool MWMission::ReloadABL(ABL::ABLError *err)
{
UnloadABL ();
ABL::ABLi_init(767999, //AblSymbolTableHeapSize,
511999, //AblStackHeapSize,
307199, //AblCodeHeapSize,
20479, //AblRunTimeStackSize,
51199, //AblMaxCodeBlockSize,
200, //AblMaxRegisteredModules,
100, //AblMaxStaticVariables,
#ifdef LAB_ONLY
ABL_Debug_func,
true,
true,
true
#else
NULL,
false,
false,
false
#endif
);
char filename[128];
Str_Copy(filename, "content\\ablscripts\\miscfuncs.abl", ELEMENTS(filename));
if (ABL::ABLi_loadLibrary(filename, err,NULL,NULL) < 0)
return false;
return true;
}
void MWMission::UnloadABL(void)
{
ABL::ABLi_close ();
}
void MWMission::UnloadScript (void)
{
if (missionBrain)
{
Check_Pointer (missionBrain);
delete missionBrain;
missionBrain = NULL;
}
}
bool MWMission::ReloadScript (ABL::ABLError *err)
{
UnloadScript ();
ABLConstNameTable ();
MW4AI::InitFormation ();
char name[128];
missionBrain = NULL;
m_FirstFrame = true;
if (scriptName[0] != 0)
{
Str_Copy(name, scriptName, ELEMENTS(name));
missionScriptHandle = ABL::ABLi_preProcess(name, err,NULL,NULL);
if (missionScriptHandle <0)
return false;
gosASSERT(missionScriptHandle >= 0);
missionBrain = new ABL::ABLModule;
gosASSERT(missionBrain != NULL);
long brainErr = missionBrain->init(missionScriptHandle);
gosASSERT(brainErr == 0);
if (brainErr)
STOP(("1???")); // todo fix this to proper exit.
missionBrain->setName("MW4Mission");
}
else
{
missionScriptHandle = 0;
missionBrain = NULL;
scriptName[0] = 0;
}
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWMission*
MWMission::Make(
CreateMessage *message,
ReplicatorID *base_id
)
{
Check_Object(message);
if (MW4AI::Statistics::Enabled() == true)
{
InitDataClient(0);
}
gos_PushCurrentHeap(s_Heap);
Verify(message->m_mapResourceID == ResourceID(MapResourceFileID,1));
MWMission *new_entity =
new MWMission(DefaultData, message, base_id, NULL);
gos_PopCurrentHeap();
Check_Object(new_entity);
return new_entity;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::CreateMessage*
MWMission::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
{
Check_Object(this);
Check_Object(stream);
stream->AllocateBytes(sizeof(CreateMessage));
Mission::SaveMakeMessage(stream, res_file);
CreateMessage *message = Cast_Pointer(CreateMessage*, stream->GetPointer());
message->messageLength = sizeof(*message);
message->railgraphStreamResourceID = railgraphStreamResourceID;
Str_Copy (message->scriptName,scriptName,ELEMENTS(message->scriptName));
return message;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool OldMission(const char *mission_name)
{
#if 1 // jcem - no old missions^^
MString lower_mission_name = mission_name;
lower_mission_name.ToLower();
// these are exact matches as opposed to substrings like in the rest of the function
if (0 == strcmp(lower_mission_name,"jungle"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"tropical"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"gladiatorpit"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"rubblepile"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"manorhouseassault"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"paradisehold"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"tumbleweedassault"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"royalguard"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"defianceholds"))
{
return true;
}
if (0 == strcmp(lower_mission_name,"griffonbase"))
{
return true;
}
if (strstr(lower_mission_name,"equinox"))
{
return true;
}
if (strstr(lower_mission_name,"highlands"))
{
return true;
}
if (strstr(lower_mission_name,"hogsback"))
{
return true;
}
if (strstr(lower_mission_name,"polartundra"))
{
return true;
}
if (strstr(lower_mission_name,"snowbound"))
{
return true;
}
if (strstr(lower_mission_name,"wetlands"))
{
return true;
}
if (strstr(lower_mission_name,"scrub"))
{
return true;
}
if (strstr(lower_mission_name,"lakefront"))
{
return true;
}
if (strstr(lower_mission_name,"bigcity"))
{
return true;
}
if (strstr(lower_mission_name,"centralpark"))
{
return true;
}
if (strstr(lower_mission_name,"dustbowl"))
{
return true;
}
if (strstr(lower_mission_name,"frostbite"))
{
return true;
}
if (strstr(lower_mission_name,"gatorbait"))
{
return true;
}
if (strstr(lower_mission_name,"innercity"))
{
return true;
}
if (strstr(lower_mission_name,"lunacy"))
{
return true;
}
if (strstr(lower_mission_name,"palacegates"))
{
return true;
}
if (strstr(lower_mission_name,"snowjob"))
{
return true;
}
if (strstr(lower_mission_name,"timberline"))
{
return true;
}
if (strstr(lower_mission_name,"coliseum"))
{
return true;
}
if (strstr(lower_mission_name,"factory"))
{
return true;
}
if (strstr(lower_mission_name,"canyon"))
{
return true;
}
if (strstr(lower_mission_name, "ghosthighway"))
{
return true;
}
if (strstr(lower_mission_name, "spaceport"))
{
return true;
}
if (strstr(lower_mission_name, "rubble"))
{
return true;
}
if (strstr(lower_mission_name, "vbase"))
{
return true;
}
if (strstr(lower_mission_name, "aspen"))
{
return true;
}
if (strstr(lower_mission_name, "cantina"))
{
return true;
}
if (strstr (lower_mission_name, "minehq"))
{
return true;
}
if (strstr (lower_mission_name, "riogrande"))
{
return true;
}
if (strstr (lower_mission_name, "mechworks"))
{
return true;
}
if (strstr (lower_mission_name, "lakeside"))
{
return true;
}
if (strstr (lower_mission_name, "lakesidehold"))
{
return true;
}
if (strstr (lower_mission_name, "mountain"))
{
return true;
}
if (strstr (lower_mission_name, "mountainhold"))
{
return true;
}
if (strstr (lower_mission_name, "hideaway"))
{
return true;
}
if (strstr (lower_mission_name, "hotplate"))
{
return true;
}
if (strstr (lower_mission_name, "freezer"))
{
return true;
}
if (strstr (lower_mission_name, "grassland"))
{
return true;
}
if (strstr (lower_mission_name, "peaks"))
{
return true;
}
#endif // jcem
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWMission::MWMission(
ClassData *class_data,
CreateMessage *message,
ReplicatorID *base_id,
ElementRenderer::Element *element
):
Mission(class_data, message, base_id, element),
m_CheckChain (NULL),
m_narcs(NULL, true),
m_ChanceLancematesEject(-1),
m_ChanceLancematesOKWhenEjecting(-1),
m_ChanceLancematesInjuredWhenEjecting(-1),
animatedTextures(NULL),
animatedTexturesMultipliers(NULL),
m_textureAnimInstances(NULL),
m_textureAnimIterators(NULL),
animatedTextureNames(NULL),
m_LancemateChain (NULL),
m_reactionSpheres(NULL),
m_playerOnlyReactionSpheres(NULL),
m_LastNavRefresh(0),
m_FlagCaptureEnabled(true),
m_FlagsAsNavPoints(false),
m_ConstraintTopLeft(Point3D::Identity),
m_ConstraintBottomRight(Point3D::Identity),
m_b30notified(false), m_b60notified(false), // jcem - 30/60 seconds to mission termination
m_fShouldBeStopped(0.0f), // jcem - no abrupt ending for "No Return" game...
m_bOrgBoundsStored(false),
m_bBoundsWarningsEnabled(false)
//m_warningPolygonOld,
//m_missionPolygonOld,
//m_ConstraintTopLeftOld,
//m_ConstraintBottomRightOld,
{
InitCOOP(); // jcem
Check_Pointer(this);
Check_Object(message);
m_MissionSuccess = false;
m_BucketManager = new CBucketManager ();
//m_BucketManager->SetupTrack (CBucketManager::KILLS);
//m_BucketManager->SetupTrack (CBucketManager::DEATHS);
lastShutdownTest = (float)gos_GetElapsedTime();;
shutDownTimer = (float)gos_GetElapsedTime();;
m_numberOfAnims = 0;
iteratorManager = NULL;
m_MaxFlagsCarried = 1;
m_FlagDropReturnTime = 30;
m_FlagCaptureReturnTime = 0;
m_FlagsEnabled = FLAGS_HIDE;
MW4AI::UserConstants::IncrementRefCount();
MW4AI::Types::IncrementRefCount();
ABL::AudioManager::IncrementRefCount();
char missname[255];
memset (missname,0,255);
{
Check_Object(this);
char *loc,*loc2;
const char *name;
name = GetModelName ();
Verify (name);
loc = __mbsrchr (name,'\\');
if (loc)
{
loc2 = strchr (loc,'.');
if (loc2)
{
Verify ((loc2 - loc) < 255);
strncpy (missname,loc+1,loc2 - loc-1);
missname[255-1] = 0;
AddCreationData ("Mission", (const char *) missname,0);
}
else
{
strncpy (missname,loc,255);
missname[255-1] = 0;
AddCreationData ("Mission", (const char *) missname,0);
}
}
else
{
strncpy (missname,name,255);
missname[255-1] = 0;
AddCreationData ("Mission", (const char *) missname,0);
}
}
// Determine if this mission needs the special crowd noise support
// Note, for Mercs, the designers have made all the single-player missions play
// sounds, etc. by hand in .ABL scripts instead of using this code, so the
// below matches only the multiplayer maps.
MString lower_mission_name = missname;
lower_mission_name.ToLower();
if (0 == strcmp(lower_mission_name,"coliseum"))
m_missionType = MISSIONTYPE_COLISEUM;
else if (0 == strcmp(lower_mission_name,"factory"))
m_missionType = MISSIONTYPE_FACTORY;
else if (0 == strcmp(lower_mission_name,"gladiatorpit"))
m_missionType = MISSIONTYPE_COLISEUM;
else if (0 == strcmp(lower_mission_name,"rubblepile"))
m_missionType = MISSIONTYPE_FACTORY;
else if (0 == strcmp(lower_mission_name,"grassland"))
m_missionType = MISSIONTYPE_JUNGLE;
else if (0 == strcmp(lower_mission_name,"jungle"))
m_missionType = MISSIONTYPE_JUNGLE;
else if (0 == strcmp(lower_mission_name,"tropical"))
m_missionType = MISSIONTYPE_JUNGLE;
else if (0 == strcmp(lower_mission_name,"snowjob"))
m_missionType = MISSIONTYPE_ARCTIC;
else if (0 == strcmp(lower_mission_name,"frostbite"))
m_missionType = MISSIONTYPE_ARCTIC;
else if (0 == strcmp(lower_mission_name,"freezer"))
m_missionType = MISSIONTYPE_ARCTIC;
else if (0 == strcmp(lower_mission_name,"gatorbait"))
m_missionType = MISSIONTYPE_SWAMP;
else if (0 == strcmp(lower_mission_name,"hotplate"))
m_missionType = MISSIONTYPE_HOTPLATE;
else
m_missionType = MISSIONTYPE_UNSPECIFIED;
#if 0
// this key mapping is a little odd
// it is in MWMission so that you don't
// need an player/vehicle/interface
// to get a pause menu
// Dedicated servers run without local players.
Check_Object(ControlsManager::Instance);
ControlsManager::Instance->CreateMapping(
NULL,
0,
Application::GetInstance(),
Application::PauseGameMessageID,
Application::GetInstance(),
-1,
ControlsManager::VirtualButtonGroupID,
KEY_ESCAPE,
false,
1,
1
);
#endif
MechWarrior4::AI::CreateGraveyard();
MoverAI::g_AlwaysIgnoreObstacles = false;
ABLConstNameTable ();
MW4AI::InitFormation ();
m_DistanceCheck = message->distanceCheck;
missionBrain = NULL;
m_FirstFrame = true;
ABL::ABLError err;
if (message->scriptName[0] != 0 && Network::GetInstance()->AmIServer())
{
MString script_name;
Str_Copy(scriptName,message->scriptName,ELEMENTS(scriptName));
script_name = scriptName;
NetMissionParameters::MWNetMissionParameters* net_params = MWApplication::GetInstance()->GetLocalNetParams();
if (net_params != 0 && MWApplication::GetInstance()->networkingFlag)
{
if (OldMission(missname))
{
switch (net_params->m_ruleType)
{
case StockDestruction:
script_name.StripExtension();
script_name += "_Destruction.abl";
break;
case StockTeamDestruction:
script_name.StripExtension();
script_name += "_TeamDestruction.abl";
break;
case StockAttrition:
script_name.StripExtension();
script_name += "_Attrition.abl";
break;
case StockTeamAttrition:
script_name.StripExtension();
script_name += "_TeamAttrition.abl";
break;
case StockCaptureTheFlag:
script_name.StripExtension();
script_name += "_CTF.abl";
break;
case StockKingOfTheHill:
script_name.StripExtension();
script_name += "_KOTH.abl";
break;
case StockTeamKingOfTheHill:
script_name.StripExtension();
script_name += "_TKOTH.abl";
break;
case StockTerritories:
script_name.StripExtension();
script_name += "_Territories.abl";
break;
case StockStealTheBacon:
script_name.StripExtension();
script_name += "_STB.abl";
break;
case StockCaptureBase:
script_name.StripExtension();
script_name += "_CaptureBase.abl";
break;
case StockDestroyObjective:
script_name.StripExtension();
script_name += "_DestroyObjective.abl";
break;
case StockEscort:
script_name.StripExtension();
script_name += "_Escort.abl";
break;
case StockMasterTrial:
script_name.StripExtension();
script_name += "_MasterTrial.abl";
break;
case StockSiegeAssault:
script_name.StripExtension();
script_name += "_SiegeAssault.abl";
break;
}
}
else
{
switch (net_params->m_ruleType)
{
case StockDestruction:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_Destruction.abl";
break;
case StockTeamDestruction:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_TeamDestruction.abl";
break;
case StockAttrition:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_Attrition.abl";
break;
case StockTeamAttrition:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_TeamAttrition.abl";
break;
case StockCaptureTheFlag:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_CTF.abl";
break;
case StockKingOfTheHill:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_KOTH.abl";
break;
case StockTeamKingOfTheHill:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_TKOTH.abl";
break;
case StockTerritories:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_Territories.abl";
break;
case StockStealTheBacon:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_STB.abl";
break;
case StockCaptureBase:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_CaptureBase.abl";
break;
case StockDestroyObjective:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_DestroyObjective.abl";
break;
case StockEscort:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_Escort.abl";
break;
case StockMasterTrial:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_MasterTrial.abl";
break;
case StockSiegeAssault:
script_name = "Content\\ABLScripts\\StockScripts\\Stock_SiegeAssault.abl";
break;
}
}
switch (net_params->m_ruleType)
{
case CustomDestruction:
case CustomTeamDestruction:
case CustomAttrition:
case CustomTeamAttrition:
case CustomCaptureTheFlag:
case CustomKingOfTheHill:
case CustomTeamKingOfTheHill:
case CustomTerritories:
case CustomStealTheBacon:
case CustomCaptureBase:
case CustomDestroyObjective:
case CustomEscort:
case CustomMasterTrial:
case CustomSiegeAssault:
case CustomCampaign:
case CustomUndefined:
script_name = net_params->m_scriptName;
}
}
missionScriptHandle = ABL::ABLi_preProcess(script_name, &err,NULL,NULL);
if (missionScriptHandle < 0)
{
ablREPORT (missionScriptHandle >= 0,err.Details ());
missionScriptHandle = 0;
missionBrain = NULL;
}
else
{
missionBrain = new ABL::ABLModule;
gosASSERT(missionBrain != NULL);
long brainErr = missionBrain->init(missionScriptHandle);
gosASSERT(brainErr == 0);
if (brainErr)
STOP(("1???")); // todo fix this to proper exit.
missionBrain->setName("MW4Mission");
}
}
else
{
missionScriptHandle = 0;
missionBrain = NULL;
scriptName[0] = 0;
}
//////////////////////////////////////////
// Load the rail graph
//////////////////////////////////////////
railgraphStreamResourceID = message->railgraphStreamResourceID;
MW4AI::g_MissionGraph = NULL;
if (message->railgraphStreamResourceID != ResourceID::Null)
{
Resource stream(railgraphStreamResourceID);
Verify(stream.DoesResourceExist());
RegisteredClass::ClassID class_id;
stream >> class_id;
MW4AI::CRailGraph::ClassData *class_data = Cast_Pointer(MW4AI::CRailGraph::ClassData*, RegisteredClass::FindClassData(class_id));
Check_Object(class_data);
gos_PushCurrentHeap(Heap);
MW4AI::g_MissionGraph = new MW4AI::CRailGraph(class_data,&stream);
gos_PopCurrentHeap();
Check_Object(MW4AI::g_MissionGraph);
stream.UnloadData();
}
ABL::SetABLExecFunction (ABL::execStandardRoutineCall);
startMusicStatus = 1;
transMusicStatus = 0;
MW4AI::SetupPermRects ();
MW4AI::SetupAIStagger ();
MW4AI::ResetGlobalTriggers();
#ifdef LAB_ONLY
MW4AI::CombatTacticInterface::g_DisableMovement = false;
MW4AI::CombatTacticInterface::g_DisableFiring = false;
MechWarrior4::DebugHelper::m_AIOff = false;
#endif
m_numberOfAnims = 0;
m_numberOfMovies = 0;
Building::AddAllBuildingsToSensorCellMap();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MWMission::~MWMission()
{
Check_Object(this);
Check_Object(MWApplication::GetInstance());
HeatManager::g_OverrideHeatOption = false;
InputTrainer::GetInstance()->SetEnabled(InputTrainer::ALL,true);
if(MWPlayer::GetInstance())
{
Check_Object(MWPlayer::GetInstance());
if(MWPlayer::GetInstance()->vehicle)
{
ScoreObject *score_object = GetScoreMember(MWPlayer::GetInstance()->vehicle->GetReplicatorID());
if(score_object)
{
MWApplication::GetInstance()->m_lastMissionDeaths = score_object->GetDeaths();
MWApplication::GetInstance()->m_lastMissionKills = score_object->GetKills();
}
}
}
Building::RemoveAllBuildingsFromSensorCellMap();
ABL::AudioManager::DecrementRefCount();
MW4AI::UserConstants::DecrementRefCount();
MW4AI::Types::DecrementRefCount();
#ifdef LAB_ONLY
if (MW4AI::Statistics::Enabled() == true)
{
MW4AI::Statistics::Quit();
}
#endif
MW4AI::KillPermRects ();
if (MW4AI::g_MissionGraph)
{
Check_Object(MW4AI::g_MissionGraph);
delete MW4AI::g_MissionGraph;
MW4AI::g_MissionGraph = NULL;
}
MW4AI::g_PathManager->CleanRequests ();
if (missionBrain)
{
Check_Pointer (missionBrain);
delete missionBrain;
missionBrain = NULL;
}
MW4AI::ClearFormation ();
MechWarrior4::AI::DestroyGraveyard();
if (MW4AI::Statistics::Enabled() == true)
{
KillDataClient ();
}
m_textureAnimInstances.DeletePlugs();
m_textureAnimIterators.DeletePlugs();
if(iteratorManager)
delete iteratorManager;
int size,i;
size = animatedTextureNames.GetLength ();
for (i=0;i<size;i++)
{
delete animatedTextureNames[i];
}
size = movieTextureNames.GetLength ();
for (i=0;i<size;i++)
{
delete movieTextureNames[i];
}
movieTextureNames.SetLength(0);
size = movieTextures.GetLength ();
for (i=0;i<size;i++)
{
delete movieTextures[i];
}
movieTextures.SetLength(0);
movieTexturesFrameTime.SetLength(0);
delete m_BucketManager;
m_BucketManager = NULL;
m_reactionSpheres.DeletePlugs();
m_playerOnlyReactionSpheres.DeletePlugs();
ExitCOOP(); // jcem
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::PreCollisionExecute(Time till)
{
Check_Object(this);
PRECOLLISION_LOGIC("MWMission");
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (app->GetApplicationState() != ApplicationStateEngine::PreRenderState)
{
// don't run abl mission stuff
gos_PushCurrentHeap(Heap);
NetMissionParameters::MWNetMissionParameters *params = app->GetLocalNetParams();
bool join_in_progress_check = false;
if (!params->m_joinInProgress)
{
join_in_progress_check = true;
}
if ((params->m_joinInProgressCutOff) && GetMissionTime() > params->m_joinInProgressCutOffTime*60)
{
join_in_progress_check = true;
}
if (app->networkingFlag == true)
{
if (params->m_respawnLimit)
{
if ((float)gos_GetElapsedTime() - lastShutdownTest > 2.0f)
{
lastShutdownTest = (float)gos_GetElapsedTime();
if (!TestForGameShutDown(ReplicatorID::Null))
{
shutDownTimer = (float)gos_GetElapsedTime();
}
// MSL 5.02 No Return
// Timer After fade to black for No Return
// we haven't been told to not shut down in one minute...
if (gos_GetElapsedTime() - shutDownTimer > 3.0f)
{
app->QueStopGame();
}
}
}
else if (join_in_progress_check)
{
if ((float)gos_GetElapsedTime() - lastShutdownTest > 2.0f)
{
lastShutdownTest = (float)gos_GetElapsedTime();
if (!TestForGameShutDownUnlimitedRespawn())
{
shutDownTimer = (float)gos_GetElapsedTime();
}
// MSL 5.02 No Return
// Timer After fade to black for No Return
// we haven't been told to not shut down in one minute...
if (gos_GetElapsedTime() - shutDownTimer > 3.0f)
{
app->QueStopGame();
}
}
}
}
if(m_FirstFrame)
{
#ifdef LAB_ONLY
AddDebugData ("FrameRate",&frameRate,hud_float_type);
// AddDebugData ("Video Mem used",&TextureKUsed,hud_int_type);
AddDebugData ("Lit vertices",&MidLevelRenderer::LitVertices,hud_int_type);
AddDebugData ("Primitives Rendered",&PrimitivesRendered,hud_int_type);
AddDebugData ("Active Mechs",&AI::m_LastActiveMechAI,hud_int_type);
AddDebugData ("Active Vehicles",&AI::m_LastActiveVehicleAI,hud_int_type);
AddDebugData ("BoardGame Mechs",&AI::m_LastBoardGameMechAI,hud_int_type);
AddDebugData ("BoardGame Vehicles",&AI::m_LastBoardGameVehicleAI,hud_int_type);
#endif
CreateLancemateGroups ();
const GameModel *model = GetGameModel();
Check_Object(model);
if(model->m_animatedTexturesResourceID != ResourceID::Null)
{
InitializeTextureAnimations(model->m_animatedTexturesResourceID);
}
if(model->m_movieTexturesResourceID != ResourceID::Null)
{
InitializeTextureMovies(model->m_movieTexturesResourceID);
}
}
Scalar time_slice = GetTimeSlice(till);
if ((m_BucketManager) &&
(app->networkingFlag == true))
{
m_BucketManager->UpdateFrame (time_slice);
}
PlayAnimations(time_slice);
PlayTextureMovies(time_slice);
ChainIteratorOf<Entity *> iterator(&m_CheckChain);
Entity *ent;
while((ent = iterator.ReadAndNext()) != NULL)
{
m_CheckChain.Remove (ent);
}
int j,size,current,ia;
NameTable *table = NameTable::GetInstance();
size = table->nameTableArray[NameTable::PlayerArray].GetLength ();
current = 0;
stlport::vector<MWObject *> lance;
stlport::vector<bool> lanceadd;
stlport::vector<MWObject *>::iterator iter;
stlport::vector<bool>::iterator iter2;
MW4AI::Groups::GetLancemates (lance);
lanceadd.assign (lance.size (),false);
for (j=0;j<size;j++)
{
NameTableEntry *data;
data = &table->nameTableArray [NameTable::PlayerArray][j];
ent = data->dataPointer->GetCurrent ();
if (!ent)
continue;
m_CheckChain.Add (ent);
ia=0;
for (iter = lance.begin ();iter!=lance.end ();iter++)
{
if (!(*iter)->IsWithin (ent,100))
lanceadd[ia] = true;
ia++;
}
}
ia = 0;
for (iter2 = lanceadd.begin ();iter2!=lanceadd.end ();iter2++)
{
if (*iter2)
m_CheckChain.Add (lance[ia]);
ia++;
}
if (CameraShipManager::Instance)
{
Entity *ent = CameraShipManager::Instance->GetActiveCamera();
if (ent)
m_CheckChain.Add (ent);
}
MW4AI::g_AIExecutionNumber++;
MW4AI::g_AIExecutionNumber %= MW4AI::AIExecutionDelta;
#ifdef LAB_ONLY
if (MW4AI::g_AIExecutionNumber == 0)
{
AI::m_LastBoardGameMechAI = AI::m_BoardGameMechAI;
AI::m_LastBoardGameVehicleAI = AI::m_BoardGameVehicleAI;
AI::m_LastActiveMechAI = AI::m_ActiveMechAI;
AI::m_LastActiveVehicleAI = AI::m_ActiveVehicleAI;
AI::m_BoardGameMechAI = 0;
AI::m_BoardGameVehicleAI = 0;
AI::m_ActiveMechAI = 0;
AI::m_ActiveVehicleAI = 0;
}
#endif
if ((missionBrain) && (!m_FirstFrame))
{
PRECOLLISION_LOGIC("Mission::Script");
__int64 subtime = GetCycles ();
Start_Timer(Mission_Script_Time);
#ifdef LAB_ONLY
try
{
missionBrain->execute ();
}
catch (...)
{
ablREPORT (false,ABL::ablERROR ("Critical failure in abl mission script, turning off script. Continue at your own risk"));
delete missionBrain;
missionBrain = NULL;
}
#else
missionBrain->execute();
#endif
MW4AI::tABLTime+=GetCycles()-subtime;
Stop_Timer(Mission_Script_Time);
}
else if (m_FirstFrame)
{
#ifdef LAB_ONLY
MWGameInfo::InitMissionInfo ();
if (MW4AI::Statistics::Enabled() == true)
{
MW4AI::Statistics::Init();
}
#endif
}
if (m_EndMissionTimer.Running ()) {
Scalar fCurTime = m_EndMissionTimer.CurrTime ();
if (g_nMR != 2) {
// jcem - 30/60 seconds to mission termination
if (!m_b30notified) {
Scalar fRemain = m_EndTime - fCurTime;
if (fRemain > 0.0f) {
if (!m_b60notified) {
if ((58.0 <= fRemain) && (fRemain < 60.9)) {
AudioCommand *asdf = AudioCommand::Create(AudioRenderer::MechanicalType, "vo\\created\\end60.wav{handle}", 1.0f, 1.0f);
if (asdf) {
Check_Object(asdf);
asdf->Play();
}
m_b60notified = true;
}
}
if ((29.0 <= fRemain) && (fRemain < 30.9)) {
AudioCommand *asdf = AudioCommand::Create(AudioRenderer::MechanicalType, "vo\\created\\end30.wav{handle}", 1.0f, 1.0f);
Check_Object(asdf);
asdf->Play();
m_b30notified = true;
}
}
}
}
if (Application::GetInstance()->serverFlag) {
#ifdef _DEBUG
if (g_nMR != 2) {
#endif // _DEBUG
if (fCurTime >= m_EndTime)
{
DisconnectLancemates ();
Check_Object (Application::GetInstance());
//Just incase the player dies even though he succeeded the goals before the mission ends
if(MWPlayer::GetInstance())
{
if(MWPlayer::GetInstance()->vehicle)
{
if(MWPlayer::GetInstance()->vehicle->IsDestroyed())
{
EndMissionState(false);
}
}
}
app->m_currentMissionStatus = EndMissionState();
if(MWGame::GetInstance())
MWGame::GetInstance()->ReactToEndMission(EndMissionState());
Application::GetInstance()->QueStopGame ();
}
#ifdef _DEBUG
}
#endif // _DEBUG
}
}
m_FirstFrame = false;
gos_PopCurrentHeap();
}
ABL::AudioManager::GetInstance()->Update();
ResolveReactionSpheres();
Mission::PreCollisionExecute(till);
}
void MWMission::CreateLancemateGroups()
{
VehicleInterface* vehicle_interface = VehicleInterface::GetInstance();
if ((vehicle_interface != 0) &&
(vehicle_interface->vehicle != 0) &&
(vehicle_interface->vehicle->IsDerivedFrom(Mech::DefaultData) == true))
{
// make sure the player's vehicle is in the group
Mech* player_mech = Cast_Object(Mech*,vehicle_interface->vehicle);
AddToLancemateGroup(player_mech,player_mech->GetTeam());
}
ChainIteratorOf<AI *> iterator(&m_LancemateChain);
AI *ai;
while((ai = iterator.ReadAndNext()) != NULL)
{
if ((ai->getEntity() != 0) &&
(ai->getEntity()->IsDestroyed() == false) &&
(ai->getEntity()->IsDerivedFrom(Mech::DefaultData) == true))
{
Mech *mech = Cast_Object (Mech *,ai->getEntity ());
if (MWApplication::GetAlignmentSchema() != MWApplication::MP_NON_TEAMPLAY)
{
AddToLancemateGroup(mech,mech->GetTeam());
}
}
}
MWGUIManager *gui;
gui = MWGUIManager::GetInstance ();
if (gui)
{
if (gui->Component (MWGUIManager::HUD_COMM))
{
HUDComm *comm;
comm = Cast_Object (HUDComm *,gui->Component (MWGUIManager::HUD_COMM));
if (comm)
{
comm->SetupLancemates ();
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWMission::AddToLancemateGroup(Mech *lancemate, int team_number)
{
Verify (lancemate);
if (lancemate == 0)
{
return;
}
if ((Adept::Mission::GetInstance() != 0) &&
(Adept::Mission::GetInstance()->IsDerivedFrom(MWMission::DefaultData) == true))
{
MWMission* mwmission = Cast_Object(MWMission*,Adept::Mission::GetInstance());
GroupContainer& group_container = mwmission->GetGroupContainer();
Group::identifier group_id;
if (team_number == MWApplication::No_Team)
{
group_id = 1;
}
else
{
group_id = 950 + team_number;
}
// create the group if it doesn't exist
if (group_container.GroupExists(group_id) == false)
{
group_container.AddObjectToGroup(*lancemate,group_id);
}
Verify(group_container.GroupExists(group_id) == true);
if (group_container.GroupExists(group_id) == false)
{
return;
}
// add us to the group if we're not in it
Group& group = group_container.GetGroup(group_id);
if (std::find(lancemate->GetGroups().begin(),lancemate->GetGroups().end(),group_id) == lancemate->GetGroups().end())
{
lancemate->GetGroups().push_back(group_id);
}
std::vector<MWObject*> members;
group.GetMembers(members);
if (std::find(members.begin(),members.end(),lancemate) == members.end())
{
group.AddObject(lancemate->objectID);
}
bool bSetSquadAI;
if (MWApplication::GetInstance()->networkingFlag == false) {
bSetSquadAI = true;
} else {
if (Application::GetInstance()->serverFlag)
bSetSquadAI = true;
else
bSetSquadAI = false;
}
// make sure the group has a GROUPAI_LANCEMATE AI type
if (bSetSquadAI)
{
if ((group.GetAI() == 0) ||
(group.GetAI()->GetID() != MW4AI::Squad::GROUPAI_LANCEMATE))
{
Stuff::Auto_Ptr<MW4AI::Squad::AI> ai_ptr(MW4AI::Squad::CreateAI((MW4AI::Squad::ID)MW4AI::Squad::GROUPAI_LANCEMATE));
group.SetSquadAI(ai_ptr);
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWMission::AddLancemate(AI *lancemate)
{
m_LancemateChain.Add (lancemate);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWMission::DisconnectLancemates(void)
{
ChainIteratorOf<AI *> iterator(&m_LancemateChain);
AI *ai;
while((ai = iterator.ReadAndNext()) != NULL)
{
ai->DisconnectLancemate ();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::ResetMissionLights()
{
Check_Object(this);
Check_Object(VideoRenderer::Instance);
Mission::ResetMissionLights();
#if 0
const GameModel *model = GetGameModel();
Check_Object(model);
Adept::CameraComponent *camera = VideoRenderer::Instance->GetSecondaryCamera(1);
if (camera)
{
Check_Object(camera);
ElementRenderer::StateChange *view_states = camera->GetElement()->GetViewingStateChange();
view_states->EnableChildLightingControl();
if(m_isNightMission)
{
view_states->SetFogColor(model->m_nightFogColor);
if(m_nightSky)
camera->GetElement()->AdoptSkyElement(m_nightSky);
}
}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::SetLightAmpMissionLights()
{
Check_Object(this);
Check_Object(VideoRenderer::Instance);
Mission::SetLightAmpMissionLights();
#if 0
const GameModel *model = GetGameModel();
Check_Object(model);
Adept::CameraComponent *camera = VideoRenderer::Instance->GetSecondaryCamera(1);
if (camera)
{
Check_Object(camera);
ElementRenderer::StateChange *view_states = camera->GetElement()->GetViewingStateChange();
view_states->DisableChildLightingControl();
view_states->SetFogColor(model->m_fogColor);
camera->GetElement()->AdoptSkyElement(m_sky);
}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::AddNarc(Narc *narc, int alignment)
{
Check_Object(this);
Check_Object(narc);
//Verify(alignment < Entity::LastAlignment);
Narc *current_narc = m_narcs.Find(alignment);
if(current_narc)
{
m_narcs.Remove(current_narc);
current_narc->SentenceToDeathRow();
}
m_narcs.AddValue(narc, alignment);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Narc
*MWMission::GetNarc(int alignment)
{
Check_Object(this);
return m_narcs.Find(alignment);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::InitializeTextureAnimations(const ResourceID& anim_resource_id)
{
Check_Object(this);
if(anim_resource_id != ResourceID::Null)
{
Resource stream(anim_resource_id);
Verify(stream.DoesResourceExist());
int size;
stream >> size;
animatedTextures.SetLength(size);
animatedTexturesMultipliers.SetLength(size);
animatedTextureNames.SetLength(size);
m_numberOfAnims = 0;
for(int i=0; i<size; i++)
{
animatedTextures[i] = NULL;
}
for(i=0; i<size; i++)
{
animatedTexturesMultipliers[i] = 1.0f;
}
for(i=0; i<size; i++)
{
MString texture_name;
stream >> texture_name;
animatedTextureNames[i] = new PlugOf<MString>(texture_name);
MidLevelRenderer::MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)((const char *)texture_name);
if(texture)
{
texture->SetAnimateTexture(true);
}
animatedTextures[i] = texture;
MString animation_name;
stream >> animation_name;
MW4Animation::AnimInstance *anim_instance = MW4Animation::AnimInstanceManager::Anim_Instance_Manager->MakeAnimInstance(
animation_name,
(MW4Animation::AnimInstanceManager::UserDefinedSearchFunction)FindIndex,
(void *)this
);
m_textureAnimInstances.Add(anim_instance);
Scalar anim_speed;
stream >> anim_speed;
animatedTexturesMultipliers[i] = anim_speed;
MW4Animation::AnimIterator *anim_iterator = new MW4Animation::AnimIterator(anim_instance);
anim_iterator->ResetStart();
m_textureAnimIterators.Add(anim_iterator);
m_numberOfAnims ++;
}
iteratorManager = new MW4Animation::AnimHierarchyIteratorManager(
(MW4Animation::AnimHierarchyIteratorManager::UserDefinedApplyChannelFunction)MWMission::ApplyChannel,
this
);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::ApplyChannel(
MW4Animation::ChannelApplication &channel_data,
int joint_index,
void *user_data
)
{
MWMission *mission;
mission = Cast_Object(MWMission*, user_data);
MidLevelRenderer::MLRTexture *texture = mission->animatedTextures[joint_index];
//If we didn't find it then it must not be loaded yet...try to load it
if(!texture)
{
MString texture_name = mission->animatedTextureNames[joint_index]->GetItem();
texture = (*MidLevelRenderer::MLRTexturePool::Instance)((const char *)texture_name);
if(texture)
{
texture->SetAnimateTexture(true);
mission->animatedTextures[joint_index] = texture;
}
}
//We have the texture and we are going to animate
if(texture)
{
Scalar anim_speed = mission->animatedTexturesMultipliers[joint_index];
texture->SetAnimateTexture(true);
Stuff::AffineMatrix4D *texture_matrix = texture->GetTextureMatrix();
Verify(channel_data.hasPosition);
texture_matrix->entries[3] = channel_data.positionValue.x * anim_speed;
texture_matrix->entries[7] = channel_data.positionValue.z * anim_speed;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MWMission::FindIndex(const char *joint_name, void *user_data)
{
MWMission *mission;
mission = Cast_Object(MWMission*, user_data);
return mission->m_numberOfAnims;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::PlayAnimations(Scalar time_slice)
{
Check_Object(this);
MW4Animation::AnimIterator *anim_iterator;
ChainIteratorOf<MW4Animation::AnimIterator *> iterator(&m_textureAnimIterators);
time_slice *= 0.07f;
if(iteratorManager)
{
Check_Object(iteratorManager);
iteratorManager->PushLayer(1.0f);
while((anim_iterator = iterator.ReadAndNext()) != NULL)
{
if (anim_iterator->IncrementTime(time_slice))
{
// anim ended so restart it and add the carryover
Scalar carryOver = anim_iterator->GetCarryOverTime();
anim_iterator->SetPosition(carryOver);
}
iteratorManager->AddAnimToCurrentLayer(anim_iterator);
}
iteratorManager->PopLayer();
iteratorManager->BlendAndApply(m_numberOfAnims);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::InitializeTextureMovies(const ResourceID& movie_resource_id)
{
Check_Object(this);
if(movie_resource_id != ResourceID::Null)
{
Resource stream(movie_resource_id);
Verify(stream.DoesResourceExist());
int size;
stream >> size;
movieTextures.SetLength(size);
movieTexturesFrameTime.SetLength(size);
movieTextureNames.SetLength(size);
m_numberOfMovies = 0;
for(int i=0; i<size; i++)
{
movieTextures[i] = NULL;
}
for(i=0; i<size; i++)
{
movieTexturesFrameTime[i] = 0.01f;
}
for(i=0; i<size; i++)
{
MString texture_name;
stream >> texture_name;
stream >> movieTexturesFrameTime[i];
movieTextureNames[i] = new PlugOf<MString>(texture_name);
MidLevelRenderer::MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)((const char *)texture_name);
if(texture)
{
movieTextures[i] = Cast_Object(MidLevelRenderer::MLRMovieTexture *, texture);
movieTextures[i]->SetFrameTime(movieTexturesFrameTime[i]);
}
m_numberOfMovies ++;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::PlayTextureMovies(Scalar time_slice)
{
Check_Object(this);
for(int i=0;i<m_numberOfMovies;i++)
{
if(movieTextures[i]==NULL)
{
MString texture_name = movieTextureNames[i]->GetItem();
MidLevelRenderer::MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)((const char *)texture_name);
if(texture)
{
movieTextures[i] = Cast_Object(MidLevelRenderer::MLRMovieTexture *, texture);
movieTextures[i]->SetFrameTime(movieTexturesFrameTime[i]);
movieTextures[i]->RollAFrame(time_slice);
}
}
else
{
movieTextures[i]->RollAFrame(time_slice);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GroupContainer&
MWMission::GetGroupContainer()
{
return m_GroupContainer;
}
const GroupContainer&
MWMission::GetGroupContainer() const
{
return m_GroupContainer;
}
void MWMission::ABLConstNameTable (void)
{
int i,j,size;
char prefix[5];
NameTable *table = NameTable::GetInstance();
Check_Object (table);
prefix[4] = 0;
for (i=NameTable::DefaultArray;i<NameTable::TableSize;i++)
{
if (i == NameTable::PlayerArray)
{
continue;
}
switch (i)
{
case NameTable::VehicleArray:
strncpy (prefix,"eve_",4);
break;
case NameTable::BuildingArray:
strncpy (prefix,"ebu_",4);
break;
case NameTable::SoundArray:
strncpy (prefix,"eso_",4);
break;
case NameTable::PathArray:
strncpy (prefix,"epa_",4);
break;
case NameTable::NavArray:
strncpy (prefix,"ena_",4);
break;
case NameTable::ObjectiveArray:
strncpy (prefix,"eob_",4);
break;
case NameTable::DropZoneArray:
strncpy (prefix,"edr_",4);
break;
case NameTable::AIArray:
strncpy (prefix,"eai_",4);
break;
case NameTable::TurretArray:
strncpy (prefix,"etu_",4);
break;
case NameTable::CameraShipArray:
strncpy (prefix,"eca_",4);
break;
case NameTable::FlagArray:
strncpy (prefix,"efl_",4);
break;
default:
strncpy (prefix,"ede_",4);
break;
}
size = table->nameTableArray[i].GetLength ();
for (j=0;j<size;j++)
{
NameTableEntry *data;
char name[256];
char *temp;
data = &table->nameTableArray [i][j];
ABL::SymTableNodePtr constantIdPtr;
sprintf (name,"%s%s",prefix,(char *) data->objectName);
temp = name;
while (*temp != 0)
{
*temp = (char) tolower (*temp);
if (*temp == ' ')
{
*temp = '_';
}
temp++;
}
if ((constantIdPtr = ABL::searchSymTable(name, ABL::SymTableDisplay[0])) == NULL)
constantIdPtr = ABL::enterSymTable(name, &ABL::SymTableDisplay[0]);
constantIdPtr->defn.key = ABL::DFN_CONST;
constantIdPtr->library = NULL;
constantIdPtr->typePtr = ABL::setType(ABL::IntegerTypePtr);
constantIdPtr->defn.info.constant.value.integer = data->GetObjectID ();
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Stuff::Scalar GetTonnage(const Adept::ReplicatorID& rep_id)
{
Connection *connection = Network::GetInstance()->GetConnection(rep_id.connectionID);
if (connection == 0)
{
return (-1);
}
Check_Object(connection);
Replicator* rep = connection->FindReplicator(rep_id);
if (rep == 0)
{
return (-1);
}
Entity *ent = Cast_Object(Entity*,rep);
if (ent->IsDerivedFrom(MWObject::DefaultData) == false)
{
return (-1);
}
MWObject* mwobject = Cast_Object(MWObject*,ent);
return (mwobject->GetTonage());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// MSL 5.02 headshot
//void MWMission::ScoringReactToMechDeath(const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id)
void MWMission::ScoringReactToMechDeath(const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id, int damageMode)
{
if (!Application::GetInstance()->serverFlag)
return;
ReplicatorID inflicting_id2 = inflicting_id;
Mech* pMech2 = MechFromRepId(inflicting_id2);
Connection *connection = Network::GetInstance()->GetConnection(inflicting_id2.connectionID);
if (connection != 0)
{
Check_Object(connection);
Replicator* rep = connection->FindReplicator(inflicting_id2);
if (rep != 0)
{
Entity* ent = Cast_Object(Entity*,rep);
if (ent->IsDerivedFrom(Mech::DefaultData) == true)
{
Mech* inflicting_mech = Cast_Object(Mech*,ent);
if ((inflicting_mech->IsDestroyed() == true) &&
(inflicting_mech->m_whoShotMeLast != ReplicatorID::Null))
{
inflicting_id2 = inflicting_mech->m_whoShotMeLast;
pMech2 = MechFromRepId(inflicting_id2);
}
}
}
}
Mech* pMechVictim = MechFromRepId(victim_id);
// MSL 5.05
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
//
// ReplicatorID inflicting_id2 = inflicting_id;
// Mech* pMech2 = MechFromRepId(inflicting_id2);
// if (pMech2) {
// if (pMech2->IsDestroyed() && (pMech2->m_whoShotMeLast != ReplicatorID::Null))
// {
// inflicting_id2 = pMech2->m_whoShotMeLast;
// pMech2 = MechFromRepId(inflicting_id2);
// }
// }
// Mech* pMechVictim = MechFromRepId(victim_id);
/*
if (CTCL_IsConsoleX() && (g_nMR != 2)) { // jcem
if ((inflicting_id2 != Adept::ReplicatorID::Null) && (victim_id != Adept::ReplicatorID::Null)) {
if (inflicting_id2 != victim_id) {
bool player_audio_event = false;
if ((VehicleInterface::GetInstance() != 0) &&
(VehicleInterface::GetInstance()->vehicle != 0) &&
(VehicleInterface::GetInstance()->vehicle->GetReplicatorID() == inflicting_id2))
{
player_audio_event = true;
}
if (app->TeamsAreFriendly(inflicting_id2,victim_id) == true)
{
if ((victim_id != inflicting_id2) ||
(inflicting_id != inflicting_id2))
{
if (player_audio_event == true)
{
VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::TEAMMATEDESTROYED);
}
}
}
else
{
if (player_audio_event == true)
{
VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::KILLAWARDED);
}
}
}
}
} // jcem
*/
// MSL 5.05
// if (!app->serverFlag)
// return;
// MSL 5.02 headshot
Mission::ScoringReactToMechDeath (inflicting_id2,victim_id,damageMode);
if ((inflicting_id2 != Adept::ReplicatorID::Null) &&
(victim_id != Adept::ReplicatorID::Null))
{
std::string s;
ScoreObject* victim_score_object = m_scoringChain.Find(victim_id);
ScoreObject* inflicting_score_object = m_scoringChain.Find(inflicting_id2);
if ((victim_score_object != 0) &&
(inflicting_score_object != 0))
{
// MSL 5.02 Merc Bug Fix
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (inflicting_id2 != victim_id)
{
s += inflicting_score_object->GetName();
s += " ";
// MSL 5.02 headshot
// s += app->GetLocString(IDS_MISSION_CPP_DESTROYED);
if (damageMode == InternalDamageObject::HeadShotDamageMode)
s += app->GetLocString(IDS_MISSION_CPP_HEAD_SHOT_ON); //head shot damage mode addition
else
s += app->GetLocString(IDS_MISSION_CPP_DESTROYED);
s += " ";
s += victim_score_object->GetName();
// MSL 5.03 Teammate Chat message added
if (app->TeamsAreFriendly(inflicting_id2,victim_id) == true)
{
s += " (TeamMate)";
}
app->SendChat(Connection::Local->GetID(),
MWApplication::SystemBroadcast,
0,
(char*)s.c_str());
}
else
{
if (victim_id == inflicting_id2)
{
s += victim_score_object->GetName();
s += " ";
s += app->GetLocString(IDS_MISSION_CPP_SUICIDE);
app->SendChat(Connection::Local->GetID(),
MWApplication::SystemBroadcast,
0,
(char*)s.c_str());
}
}
}
if (pMechVictim && pMech2)
{
if (inflicting_id2 != victim_id)
{
Mech_CheckDamage(pMechVictim, pMech2, true);
}
else if (inflicting_id == inflicting_id2)
{
Mech_CheckDamage(pMechVictim, pMech2, true);
}
}
}
NetMissionParameters::MWNetMissionParameters *params = app->GetLocalNetParams();
if (params->m_killLimit)
{
ScoreObject *inflicting = m_scoringChain.Find(inflicting_id2);
if ((inflicting != 0) &&
(inflicting->GetKills() >= params->m_killLimitNumber))
{
Check_Object (Application::GetInstance());
app->m_iaDisplayGameType = 1;
app->QueStopGame ();
}
}
// Notify the player's group that a 'Mech was destroyed
GroupContainer& group_container = GetGroupContainer();
if (group_container.GroupExists(1) == true)
{
Group& group = group_container.GetGroup(1);
group.NotifyMechDestroyed(inflicting_id2,victim_id);
}
Verify (m_BucketManager);
//SPEWALWAYS(("jerryeds", "RULE CHECK-----------"));
if ((app->networkingFlag == true) || app->IsCampCOOP()) // jcem IsCampCOOP()
{
if (params->m_respawnLimit && !app->IsCampCOOP()) // jcem IsCampCOOP()
{
if (TestForGameShutDown(victim_id))
{
app->QueStopGame ();
}
}
if ((inflicting_id2 != victim_id) && (inflicting_id2 != ReplicatorID::Null))
{
m_BucketManager->NotifyAction (CBucketManager::KILL_LINK,inflicting_id2,1);
m_BucketManager->NotifyAction (CBucketManager::KILLS,inflicting_id2,1);
g_RSF.RecScore(CBucketManager::KILLS, inflicting_id2, victim_id); // jcem
}
else
{
// MSL 5.04 Bug Fix?
// if (inflicting_id == inflicting_id2)
if (victim_id == inflicting_id2)
{
m_BucketManager->NotifyAction(CBucketManager::SUICIDES,victim_id,1,victim_id);
g_RSF.RecScore(CBucketManager::SUICIDES, victim_id); // jcem
}
}
m_BucketManager->NotifyAction (CBucketManager::DEATH_LINK,victim_id,1);
m_BucketManager->NotifyAction (CBucketManager::DEATHS,victim_id,1);
int inflicting_tonnage = (int)GetTonnage(inflicting_id2);
int victim_tonnage = (int)GetTonnage(victim_id);
int tonnage_delta = 0;
if ((inflicting_tonnage != -1) &&
(victim_tonnage != -1) &&
(victim_tonnage > inflicting_tonnage))
{
tonnage_delta = (victim_tonnage - inflicting_tonnage);
}
// PAUSE(("Tonnage delta: %d - inf:%d, vit:%d\n", tonnage_delta, inflicting_tonnage, victim_tonnage));
if (tonnage_delta != 0)
{
m_BucketManager->NotifyAction(CBucketManager::KILLS_BY_TONNAGE,inflicting_id2,tonnage_delta);
}
/*
bool player_audio_event = false;
if (!CTCL_IsConsoleX()) { // jcem
if ((VehicleInterface::GetInstance() != 0) &&
(VehicleInterface::GetInstance()->vehicle != 0) &&
(VehicleInterface::GetInstance()->vehicle->GetReplicatorID() == inflicting_id2))
{
player_audio_event = true;
}
} // jcem
*/
// MSL 5.03 If I destroy myself thru splash, I should get a Suicide, not teammatedestroyed
if (app->TeamsAreFriendly(inflicting_id2,victim_id) == true)
{
// MSL 5.04 Bug Fix?
// if (victim_id != inflicting_id2)
if (victim_id != inflicting_id2)
{
if (g_nMR != 2)
app->SendSound(inflicting_id2, VehicleInterface::TEAMMATEDESTROYED);
m_BucketManager->NotifyAction(CBucketManager::FRIENDLY_KILLS,inflicting_id2,1,victim_id);
if (tonnage_delta != 0)
{
m_BucketManager->NotifyAction(CBucketManager::FRIENDLY_KILLS_BY_TONNAGE,inflicting_id2,tonnage_delta,victim_id);
}
}
}
else
{
if (g_nMR != 2)
app->SendSound(inflicting_id2, VehicleInterface::KILLAWARDED);
m_BucketManager->NotifyAction(CBucketManager::ENEMY_KILLS,inflicting_id2,1,victim_id);
if (tonnage_delta != 0)
{
m_BucketManager->NotifyAction(CBucketManager::ENEMY_KILLS_BY_TONNAGE,inflicting_id2,tonnage_delta,victim_id);
}
}
}
}
void MWMission::ScoringReactToTurretDeath (const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id)
{
if (!Application::GetInstance()->serverFlag)
return;
ReplicatorID inflicting_id2 = inflicting_id;
Connection *connection = Network::GetInstance()->GetConnection(inflicting_id2.connectionID);
if (connection != 0)
{
Check_Object(connection);
Replicator* rep = connection->FindReplicator(inflicting_id2);
if (rep != 0)
{
Entity* ent = Cast_Object(Entity*,rep);
if (ent->IsDerivedFrom(Mech::DefaultData) == true)
{
Mech* inflicting_mech = Cast_Object(Mech*,ent);
if ((inflicting_mech->IsDestroyed() == true) &&
(inflicting_mech->m_whoShotMeLast != ReplicatorID::Null))
{
inflicting_id2 = inflicting_mech->m_whoShotMeLast;
}
}
}
}
if ((inflicting_id2 != Adept::ReplicatorID::Null) &&
(victim_id != Adept::ReplicatorID::Null))
{
std::string s;
ScoreObject* inflicting_score_object = m_scoringChain.Find(inflicting_id2);
if (inflicting_score_object != NULL)
{
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (inflicting_id2 != victim_id)
{
s += inflicting_score_object->GetName();
s += " ";
s += app -> GetLocString (IDS_MISSION_CPP_DESTROYED_TURRET);
app->SendChat(Connection::Local->GetID(),
MWApplication::SystemBroadcast,
0,
(char*)s.c_str());
}
}
}
MWApplication* mwapplication = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (mwapplication->TeamsAreFriendly(inflicting_id2,victim_id) == true)
{
if ((victim_id != inflicting_id2) ||
(inflicting_id != inflicting_id2))
{
m_BucketManager->NotifyAction(CBucketManager::FRIENDLY_TURRET_KILLS,inflicting_id2,1);
}
}
else
{
m_BucketManager->NotifyAction(CBucketManager::ENEMY_TURRET_KILLS,inflicting_id2,1);
}
}
void MWMission::ScoringReactToBuildingDeath (const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id)
{
if (!Application::GetInstance()->serverFlag)
return;
ReplicatorID inflicting_id2 = inflicting_id;
Connection *connection = Network::GetInstance()->GetConnection(inflicting_id2.connectionID);
if (connection != 0)
{
Check_Object(connection);
Replicator* rep = connection->FindReplicator(inflicting_id2);
if (rep != 0)
{
Entity* ent = Cast_Object(Entity*,rep);
if (ent->IsDerivedFrom(Mech::DefaultData) == true)
{
Mech* inflicting_mech = Cast_Object(Mech*,ent);
if ((inflicting_mech->IsDestroyed() == true) &&
(inflicting_mech->m_whoShotMeLast != ReplicatorID::Null))
{
inflicting_id2 = inflicting_mech->m_whoShotMeLast;
}
}
}
}
MWApplication* mwapplication = Cast_Object(MWApplication*,MWApplication::GetInstance());
int chatMessageID = IDS_MISSION_CPP_DESTROYED_ENEMY_BUILDING;
if (mwapplication->TeamsAreFriendly(inflicting_id2,victim_id) == true)
{
if ((victim_id != inflicting_id2) ||
(inflicting_id != inflicting_id2))
{
m_BucketManager->NotifyAction(CBucketManager::FRIENDLY_BUILDING_KILLS,inflicting_id2,1);
g_RSF.RecScore(CBucketManager::FRIENDLY_BUILDING_KILLS, inflicting_id2, victim_id); // jcem
chatMessageID = IDS_MISSION_CPP_DESTROYED_FRIENDLY_BUILDING;
}
}
else
{
m_BucketManager->NotifyAction(CBucketManager::ENEMY_BUILDING_KILLS,inflicting_id2,1);
g_RSF.RecScore(CBucketManager::ENEMY_BUILDING_KILLS, inflicting_id2, victim_id); // jcem
chatMessageID = IDS_MISSION_CPP_DESTROYED_ENEMY_BUILDING;
}
if ((inflicting_id2 != Adept::ReplicatorID::Null) &&
(victim_id != Adept::ReplicatorID::Null))
{
std::string s;
ScoreObject* inflicting_score_object = m_scoringChain.Find(inflicting_id2);
if (inflicting_score_object != NULL)
{
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (inflicting_id2 != victim_id)
{
s += inflicting_score_object->GetName();
s += " ";
s += app -> GetLocString (chatMessageID);
app->SendChat(Connection::Local->GetID(),
MWApplication::SystemBroadcast,
0,
(char*)s.c_str());
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MWMission::TestForGameShutDown (ReplicatorID victim_id)
{
if (0.0f < m_fShouldBeStopped) {
if (CheckEndMissionTime() <= 0.0f)
return true;
} else {
if (real_TestForGameShutDown(victim_id)) {
m_fShouldBeStopped = GetMissionTime() + 10.0f;
}
}
return false;
}
bool MWMission::real_TestForGameShutDown(ReplicatorID victim_id)
{
if (GetMissionTime() < 30.0f)
return false;
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
if (!params->m_teamAllowed)
{
int players_left = 0;
for (int i = 0; i < Maximum_Players; ++i)
{
if (app->servedConnectionData[i].clientConnected)
{
if (app->servedConnectionData[i].clientPlayer && app->servedConnectionData[i].clientPlayer->vehicle)
{
Vehicle *veh = Cast_Object(Vehicle*, app->servedConnectionData[i].clientPlayer->vehicle);
if (veh->GetClassID() == MechClassID)
{
if (victim_id != veh->GetReplicatorID())
{
if (veh->IsDestroyed() && veh->respawnCount < params->m_respawnLimitNumber)
{
players_left++;
}
else if (!veh->IsDestroyed())
{
players_left++;
}
}
else
{
if (veh->respawnCount < params->m_respawnLimitNumber)
{
players_left++;
}
}
}
}
}
}
for (i = 0; i < Maximum_Lancemates; ++i)
{
if (app->lancemateConnectionData[i].lancemateMech)
{
if (victim_id != app->lancemateConnectionData[i].lancemateMech->GetReplicatorID())
{
if (app->lancemateConnectionData[i].lancemateMech->IsDestroyed() && app->lancemateConnectionData[i].lancemateMech->respawnCount < params->m_respawnLimitNumber)
{
players_left++;
}
else if (!app->lancemateConnectionData[i].lancemateMech->IsDestroyed())
{
players_left++;
}
}
else
{
if (app->lancemateConnectionData[i].lancemateMech->respawnCount < params->m_respawnLimitNumber)
{
players_left++;
}
}
}
}
if (players_left <= 1)
{
return true;
}
}
else
{
//SPEWALWAYS(("jerryeds", "TEAMS"));
int team_alive[8];
for (int i = 0; i < 8; ++i)
{
team_alive[i] = 0;
}
for (i = 0; i < Maximum_Players; ++i)
{
if (app->servedConnectionData[i].clientConnected)
{
if (app->servedConnectionData[i].clientPlayer && app->servedConnectionData[i].clientPlayer->vehicle)
{
Vehicle *veh = Cast_Object(Vehicle*, app->servedConnectionData[i].clientPlayer->vehicle);
if (veh->GetClassID() == MechClassID)
{
//SPEWALWAYS(("jerryeds", "CHECK PLAYER %d:%d", veh->GetTeam(), i));
if (victim_id != veh->GetReplicatorID())
{
if (veh->IsDestroyed() && veh->respawnCount < params->m_respawnLimitNumber)
{
team_alive[veh->GetTeam()]++;
//SPEWALWAYS(("jerryeds", "ALIVE 1"));
}
else if (!veh->IsDestroyed())
{
team_alive[veh->GetTeam()]++;
//SPEWALWAYS(("jerryeds", "ALIVE 2"));
}
}
else
{
if (veh->respawnCount < params->m_respawnLimitNumber)
{
team_alive[veh->GetTeam()]++;
//SPEWALWAYS(("jerryeds", "ALIVE 3"));
}
}
}
}
}
}
for (i = 0; i < Maximum_Lancemates; ++i)
{
if (app->lancemateConnectionData[i].lancemateMech)
{
//SPEWALWAYS(("jerryeds", "CHECK LANCE %d:%d", app->lancemateConnectionData[i].lancemateMech->GetTeam(), i));
if (victim_id != app->lancemateConnectionData[i].lancemateMech->GetReplicatorID())
{
if (app->lancemateConnectionData[i].lancemateMech->IsDestroyed() && app->lancemateConnectionData[i].lancemateMech->respawnCount < params->m_respawnLimitNumber)
{
//SPEWALWAYS(("jerryeds", "ALIVE 1"));
team_alive[app->lancemateConnectionData[i].lancemateMech->GetTeam()]++;
}
else if (!app->lancemateConnectionData[i].lancemateMech->IsDestroyed())
{
//SPEWALWAYS(("jerryeds", "ALIVE 2"));
team_alive[app->lancemateConnectionData[i].lancemateMech->GetTeam()]++;
}
}
else
{
if (app->lancemateConnectionData[i].lancemateMech->respawnCount < params->m_respawnLimitNumber)
{
//SPEWALWAYS(("jerryeds", "ALIVE 3"));
team_alive[app->lancemateConnectionData[i].lancemateMech->GetTeam()]++;
}
}
}
}
//If we are playing an escort game teams 3 and 4 (-1) are the VIP's.
//if they are dead and out of lives than the game is over in limited respawn
if (params->m_ruleType == StockEscort)
{
if (!team_alive[2])
{
return true;
}
if (!team_alive[3])
{
return true;
}
}
MWApplication *app = MWApplication::GetInstance();
bool teams_have_same_alignemnt = true;
//for (i = 0; i < 8; ++i)
//{
// SPEWALWAYS(("jerryeds", "TEAM : %d:%d", i, team_alive[i]));
//}
for (i = 0; i < 8; ++i)
{
if (team_alive[i])
{
//SPEWALWAYS(("jerryeds", "START TEAM ALIVE: %d", i));
int alignment_check = app->teams[i]->GetCurrent()->GetTeamAlignment();
for (int j = 0; j < 8; ++j)
{
if (team_alive[j])
{
//SPEWALWAYS(("jerryeds", "CHECK TEAM ALIVE: %d", j));
int alignment = app->teams[j]->GetCurrent()->GetTeamAlignment();
//SPEWALWAYS(("jerryeds", "ALIGN CHECK: %d - %d", alignment_check, alignment));
if (alignment_check != alignment)
{
teams_have_same_alignemnt = false;
break;
}
}
}
break;
}
}
if (teams_have_same_alignemnt)
{
//SPEWALWAYS(("jerryeds", "STOP GAME"));
return true;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MWMission::TestForGameShutDownUnlimitedRespawn ()
{
if (GetMissionTime() < 30.0f)
return false;
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
NetMissionParameters::MWNetMissionParameters *params = MWApplication::GetInstance()->GetLocalNetParams();
if (!params->m_teamAllowed)
{
int players_left = 0;
for (int i = 0; i < Maximum_Players; ++i)
{
if (app->servedConnectionData[i].clientConnected)
{
if (app->servedConnectionData[i].clientPlayer && app->servedConnectionData[i].clientPlayer->vehicle)
{
Vehicle *veh = Cast_Object(Vehicle*, app->servedConnectionData[i].clientPlayer->vehicle);
if (veh->GetClassID() == MechClassID)
{
players_left++;
}
}
}
}
for (i = 0; i < Maximum_Lancemates; ++i)
{
if (app->lancemateConnectionData[i].lancemateMech)
{
players_left++;
}
}
if (players_left <= 1)
{
return true;
}
}
else
{
//SPEWALWAYS(("jerryeds", "TEAMS"));
int team_alive[8];
for (int i = 0; i < 8; ++i)
{
team_alive[i] = 0;
}
for (i = 0; i < Maximum_Players; ++i)
{
if (app->servedConnectionData[i].clientConnected)
{
if (app->servedConnectionData[i].clientPlayer && app->servedConnectionData[i].clientPlayer->vehicle)
{
Vehicle *veh = Cast_Object(Vehicle*, app->servedConnectionData[i].clientPlayer->vehicle);
if (veh->GetClassID() == MechClassID)
{
//SPEWALWAYS(("jerryeds", "CHECK PLAYER %d:%d", veh->GetTeam(), i));
team_alive[veh->GetTeam()]++;
}
}
}
}
for (i = 0; i < Maximum_Lancemates; ++i)
{
if (app->lancemateConnectionData[i].lancemateMech)
{
//SPEWALWAYS(("jerryeds", "CHECK LANCE %d:%d", app->lancemateConnectionData[i].lancemateMech->GetTeam(), i));
team_alive[app->lancemateConnectionData[i].lancemateMech->GetTeam()]++;
}
}
//If we are playing an escort game teams 3 and 4 (-1) are the VIP's.
//if they are dead and out of lives than the game is over in limited respawn
if (params->m_ruleType == StockEscort)
{
if (!team_alive[2])
{
return true;
}
if (!team_alive[3])
{
return true;
}
}
MWApplication *app = MWApplication::GetInstance();
bool teams_have_same_alignemnt = true;
//for (i = 0; i < 8; ++i)
//{
// SPEWALWAYS(("jerryeds", "TEAM : %d:%d", i, team_alive[i]));
//}
for (i = 0; i < 8; ++i)
{
if (team_alive[i])
{
//SPEWALWAYS(("jerryeds", "START TEAM ALIVE: %d", i));
int alignment_check = app->teams[i]->GetCurrent()->GetTeamAlignment();
for (int j = 0; j < 8; ++j)
{
if (team_alive[j])
{
//SPEWALWAYS(("jerryeds", "CHECK TEAM ALIVE: %d", j));
int alignment = app->teams[j]->GetCurrent()->GetTeamAlignment();
//SPEWALWAYS(("jerryeds", "ALIGN CHECK: %d - %d", alignment_check, alignment));
if (alignment_check != alignment)
{
teams_have_same_alignemnt = false;
break;
}
}
}
break;
}
}
if (teams_have_same_alignemnt)
{
//SPEWALWAYS(("jerryeds", "STOP GAME"));
return true;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWMission::AddScoreMember (const Adept::ReplicatorID& member, const Stuff::MString& name)
{
Verify (m_BucketManager);
Mission::AddScoreMember (member,name);
//int id;
//id = m_BucketManager->AddBucket (CBucketManager::KILL_LINK,member);
//m_BucketManager->ShowBucket (id);
//id = m_BucketManager->AddBucket (CBucketManager::DEATH_LINK,member);
//m_BucketManager->ShowBucket (id);
m_BucketManager->NotifyAddPlayer (member);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MWMission::RemoveScoreMember (const Adept::ReplicatorID& member)
{
Verify (m_BucketManager);
Mission::RemoveScoreMember (member);
//m_BucketManager->KillBucket (CBucketManager::KILL_LINK,member);
//m_BucketManager->KillBucket (CBucketManager::DEATH_LINK,member);
m_BucketManager->NotifyRemovePlayer (member);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::EndMissionState(bool succeeded)
{
Check_Object(this);
m_MissionSuccess = succeeded;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MW4AI::DiagnosticsInterface&
MWMission::GetDiagnosticsInterface()
{
return (m_DiagnosticsInterface);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const MW4AI::DiagnosticsInterface&
MWMission::GetDiagnosticsInterface() const
{
return (m_DiagnosticsInterface);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::ProcessReactionSpheres(Mech *target_mech)
{
Check_Object(this);
Check_Object(target_mech);
ChainIteratorOf<ReactionSphere *> iterator(&m_reactionSpheres);
ReactionSphere *reaction_sphere;
Point3D target_point;
target_point = target_mech->GetLocalToWorld();
while((reaction_sphere = iterator.ReadAndNext()) != NULL)
{
Check_Object(reaction_sphere);
if(reaction_sphere->DoesEffect(target_point))
reaction_sphere->ApplyEffect(target_mech);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::ProcessPlayerReactionSpheres(Mech *target_mech)
{
Check_Object(this);
Check_Object(target_mech);
ChainIteratorOf<ReactionSphere *> iterator(&m_playerOnlyReactionSpheres);
ReactionSphere *reaction_sphere;
Point3D target_point;
target_point = target_mech->GetLocalToWorld();
while((reaction_sphere = iterator.ReadAndNext()) != NULL)
{
Check_Object(reaction_sphere);
if(reaction_sphere->DoesEffect(target_point))
reaction_sphere->ApplyEffect(target_mech);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::ResolveReactionSpheres()
{
Check_Object(this);
ChainIteratorOf<ReactionSphere *> iterator(&m_reactionSpheres);
ReactionSphere *reaction_sphere;
while((reaction_sphere = iterator.ReadAndNext()) != NULL)
{
Check_Object(reaction_sphere);
if(reaction_sphere->IsOver())
delete reaction_sphere;
}
ChainIteratorOf<ReactionSphere *> player_iterator(&m_playerOnlyReactionSpheres);
while((reaction_sphere = player_iterator.ReadAndNext()) != NULL)
{
Check_Object(reaction_sphere);
if(reaction_sphere->IsOver())
delete reaction_sphere;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::CreateNewHeatSphere(const Stuff::Point3D& center, Scalar radius, Scalar secs, Scalar heat_e)
{
Check_Object(this);
HeatReactionSphere *heat_sphere;
heat_sphere = new HeatReactionSphere(center, radius, secs, heat_e);
Check_Object(heat_sphere);
m_reactionSpheres.Add(heat_sphere);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::CreateNewRadarSphere(const Stuff::Point3D& center, Scalar radius, Scalar secs, Scalar radar_e)
{
Check_Object(this);
RadarReactionSphere *radar_sphere;
radar_sphere = new RadarReactionSphere(center, radius, secs, radar_e);
Check_Object(radar_sphere);
m_reactionSpheres.Add(radar_sphere);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::CreateNewInstantHeatSphere(const Stuff::Point3D& center, Scalar radius, Scalar heat_amount)
{
Check_Object(this);
InstantHeatReactionSphere *heat_sphere;
heat_sphere = new InstantHeatReactionSphere(center, radius, 0.0f, heat_amount);
Check_Object(heat_sphere);
m_reactionSpheres.Add(heat_sphere);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::CreateNewFogSphere(const Stuff::Point3D& center, Scalar radius, Scalar secs)
{
Check_Object(this);
FogReactionSphere *fog_sphere;
fog_sphere = new FogReactionSphere(center, radius, secs);
Check_Object(fog_sphere);
m_playerOnlyReactionSpheres.Add(fog_sphere);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::RespawnMission()
{
Check_Object(this);
if (propListResourceID != ResourceID::Null)
{
Resource prop_stream(propListResourceID);
prop_stream.AdvancePointer(sizeof(WORD));
Verify(prop_stream.DoesResourceExist());
ChainIteratorOf<Entity *> iterator(&m_respawnProps);
Entity *entity;
while ((prop_stream.GetBytesRemaining() > 0) && ((entity = iterator.ReadAndNext()) != NULL))
{
Entity::CreateMessage *message =
Cast_Pointer(Entity::CreateMessage*, prop_stream.GetPointer());
Check_Object(message);
entity->Respawn(message);
if(entity->m_deathEntity.GetCurrent())
{
entity->m_deathEntity.GetCurrent()->SentenceToDeathRow();
}
entity->SyncMatrices(true);
prop_stream.AdvancePointer(message->messageLength);
}
prop_stream.UnloadData();
}
Mission::RespawnMission();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MWMission::SetEndMissionTime (Stuff::Scalar seconds)
{
if (!m_EndMissionTimer.Running ())
{
m_EndMissionTimer.Start();
}
MWApplication* app = Cast_Object(MWApplication*,MWApplication::GetInstance());
if (app->networkingFlag)
{
m_EndTime = (Stuff::Scalar)m_EndMissionTimer.CurrTime()+seconds;
if (seconds > 60.0f) {// jcem
m_b30notified = m_b60notified = false;
} else {
m_b60notified = true;
if (seconds > 30.0f) // jcem
m_b30notified = false;
else
m_b30notified = true;
}
}
else
{
m_b30notified = m_b60notified = true; // jcem
m_EndTime = seconds;
}
}
Stuff::Scalar MWMission::CheckEndMissionTime ()
{
Stuff::Scalar fTime = GetEndMissionTime ();
if (0.0f < m_fShouldBeStopped) {
Stuff::Scalar fTime2 = GetMissionTime();
if (m_fShouldBeStopped <= fTime2)
return 0.0f;
fTime2 = m_fShouldBeStopped - fTime2;
if (fTime2 < fTime)
fTime = fTime2;
}
return fTime;
}
void MWMission::StoreOriginalBounds()
{
if (!m_bOrgBoundsStored) {
m_bBoundsWarningsEnabled = VehicleInterface::GetInstance()->GetBoundsWarningsEnabled();
GetWarningPolygon(m_warningPolygonOld);
GetMissionPolygon(m_missionPolygonOld);
m_ConstraintTopLeftOld = m_ConstraintTopLeft;
m_ConstraintBottomRightOld = m_ConstraintBottomRight;
m_bOrgBoundsStored = true;
}
}
void MWMission::RestoreOriginalBounds()
{
gosASSERT(m_bOrgBoundsStored);
VehicleInterface::GetInstance()->SetBoundsWarningsEnabled(m_bBoundsWarningsEnabled);
SetWarningPolygon(m_warningPolygonOld);
SetMissionPolygon(m_missionPolygonOld);
m_ConstraintTopLeft = m_ConstraintTopLeftOld;
m_ConstraintBottomRight = m_ConstraintBottomRightOld;
}
void MWMission::SetBoundsFromPaths(const MechWarrior4::Path& PathMission, const MechWarrior4::Path& PathWarning)
{
gosASSERT(&PathMission);
StoreOriginalBounds();
PathMission.SaveAs2DPoly(missionPolygon);
if (&PathWarning) {
PathWarning.SaveAs2DPoly(warningPolygon);
VehicleInterface::GetInstance()->SetBoundsWarningsEnabled(true);
} else {
DynamicArrayOf<Vector2DOf<Scalar> >& bounds_list = warningPolygon;
bounds_list.SetLength(4);
bounds_list[0].x = 0;
bounds_list[0].y = 0;
bounds_list[1].x = 0;
bounds_list[1].y = 0.0001f;
bounds_list[2].x = 0.0001f;
bounds_list[2].y = 0.0001f;
bounds_list[3].x = 0.0001f;
bounds_list[3].y = 0;
VehicleInterface::GetInstance()->SetBoundsWarningsEnabled(false);
}
m_ConstraintTopLeft = Point3D::Identity;
m_ConstraintBottomRight = Point3D::Identity;
}
void MWMission::InitCOOP()
{
memset(&m_naCOOPs[0], 0, sizeof(m_naCOOPs));
m_naCOOPs[COOP_ENEMY_GROUP] = -1;
m_naCOOPs[COOP_ENEMY_GROUP_OLD] = -1;
}
void MWMission::ExitCOOP()
{
}
int MWMission::GetCOOP(int nIdx, void* pDest/* = (void*)NULL*/)
{
int nParam;
switch(nIdx)
{
case -1:
case -2:
{
extern int MAX_CAMP_STAGES;
MWApplication *app = MWApplication::GetInstance ();
int nStage = app->m_nCamp_Stage;
nStage--;
if (nIdx == -1) {
nStage %= MAX_CAMP_STAGES;
nStage++;
} else {
nStage /= MAX_CAMP_STAGES;
}
return nStage;
}
case COOP_SUBSTAGE_SCORE_OLD:
case COOP_MODAL_IS_ENDED:
return m_naCOOPs[nIdx];
case COOP_ENEMY_GROUP:
case COOP_ENEMY_GROUP_OLD:
nParam = m_naCOOPs[nIdx];
if ((nParam != -1) && (ABL::ObjectIDisGroup(nParam) == true)) {
Group::identifier group_id = ABL::ObjectIDtoGroupID(nParam);
((POINT*)pDest)->x = MW4AI::Groups::NumDead(group_id);
((POINT*)pDest)->y = MW4AI::Groups::Size(group_id);
return +1;
}
break;
default:
//gosASSERT(FALSE);
gosASSERT((0 <= nIdx) && (nIdx < MAX_COOP_VARS));
return m_naCOOPs[nIdx];
}
return 0;
}
int MWMission::SetCOOP(int nIdx, int nParam)
{
switch(nIdx)
{
case COOP_SUBSTAGE_SCORE_OLD:
gosASSERT(FALSE);
break;
case COOP_ENEMY_GROUP:
if (nParam != -1) {
gosASSERT(ABL::ObjectIDisGroup(nParam) == true);
int nScore, nKills, nDeaths;
nScore = GetScore4Player(nKills, nDeaths);
MWApplication *app = MWApplication::GetInstance ();
nScore += app->m_nCamp_Score;
nKills += app->m_nCamp_Kills;
nDeaths += app->m_nCamp_Deaths;
m_naCOOPs[COOP_SUBSTAGE_SCORE_OLD] = nScore;
}
m_naCOOPs[COOP_ENEMY_GROUP] = nParam;
break;
case COOP_ENEMY_GROUP_OLD:
if (nParam != -1) {
gosASSERT(ABL::ObjectIDisGroup(nParam) == true);
}
m_naCOOPs[COOP_ENEMY_GROUP_OLD] = nParam;
break;
case COOP_MODAL_START:
//gosASSERT(!m_naCOOPs[COOP_MODAL_START]);
m_naCOOPs[COOP_MODAL_START] = nParam;
m_naCOOPs[COOP_MODAL_IS_ENDED] = 0;
break;
default:
//gosASSERT(FALSE);
gosASSERT((0 <= nIdx) && (nIdx < MAX_COOP_VARS));
m_naCOOPs[nIdx] = nParam;
break;
}
return 0;
}