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.
3177 lines
80 KiB
C++
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;
|
|
}
|