Files
firestorm/Gameleap/code/mw4/Code/MW4/MWMission.hpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

813 lines
20 KiB
C++

//===========================================================================//
// File: SRMission.hpp //
//---------------------------------------------------------------------------//
// 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 //
//===========================================================================//
#pragma once
#include "MW4.hpp"
#include <Adept\Mission.hpp>
#include "abl.h"
#include "aiutils.hpp"
#include "GroupContainer.hpp"
#include "AI_Log.hpp"
#include "MW4AnimationSystem.hpp"
#include "Mech.hpp"
#include "HeatManager.hpp"
#include "VehicleInterface.hpp"
#include "SensorCellMap.hpp"
#include "AI_DebugRenderer.hpp"
#include "path.hpp"
#include "MLR\MLRMovieTexture.hpp"
//#include "bucket.hpp"
namespace MidLevelRenderer
{
class MLRTexture;
class MLRTexturePool;
};
namespace MechWarrior4
{
class CBucketManager;
class Narc;
//##########################################################################
//######################## Reaction Sphere ###########################
//##########################################################################
class ReactionSphere:
public Stuff::Plug
{
public:
ReactionSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs):
Plug(Plug::DefaultData)
{
m_sphere.center = center;
m_sphere.radius = radius;
m_endTime = gos_GetElapsedTime() + secs;
m_hasRun = false;
m_markedOnce = false;
//By entering the time to be 0.0f will cause it to be a one time thing!
if(secs <= 0.0f)
m_markedOnce = true;
}
~ReactionSphere(){}
Stuff::Time
GetEndTime()
{Check_Object(this); return m_endTime;}
void
SetHasRun()
{Check_Object(this); m_hasRun = true;}
bool
DoesEffect(const Stuff::Point3D& target_point)
{Check_Object(this); SetHasRun(); return m_sphere.Contains(target_point);}
virtual void
ApplyEffect(Mech *mech){}
bool
IsOver()
{
Check_Object(this);
if(m_markedOnce)
return m_hasRun;
return gos_GetElapsedTime() >= GetEndTime();
}
private:
Stuff::Sphere
m_sphere;
Stuff::Time
m_endTime;
bool
m_markedOnce;
bool
m_hasRun;
};
//##########################################################################
//###################### Instance Heat Sphere #########################
//##########################################################################
class InstantHeatReactionSphere:
public ReactionSphere
{
public:
InstantHeatReactionSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs, Stuff::Scalar amount):
ReactionSphere(center, radius, secs)
{
m_heatAmount = amount;
}
~InstantHeatReactionSphere(){}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplyEffect(Mech *mech)
{
Check_Object(this);
mech->m_heatManager->AddHeat(m_heatAmount);
}
private:
Stuff::Scalar
m_heatAmount;
};
//##########################################################################
//###################### Reaction Heat Sphere #########################
//##########################################################################
class HeatReactionSphere:
public ReactionSphere
{
public:
HeatReactionSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs, Stuff::Scalar percent):
ReactionSphere(center, radius, secs)
{
m_heatEfficiency = percent;
}
~HeatReactionSphere(){}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplyEffect(Mech *mech)
{
Check_Object(this);
mech->m_heatMaterialMultiplier += m_heatEfficiency;
}
private:
Stuff::Scalar
m_heatEfficiency;
};
//##########################################################################
//####################### Fog Reaction Sphere #########################
//##########################################################################
class FogReactionSphere:
public ReactionSphere
{
public:
FogReactionSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs):
ReactionSphere(center, radius, secs)
{
}
~FogReactionSphere(){}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplyEffect(Mech *mech)
{
Check_Object(this);
mech->vehicleInterface->fNeedSmoke = true;
}
};
//##########################################################################
//###################### Radar Reaction Sphere ########################
//##########################################################################
class RadarReactionSphere:
public ReactionSphere
{
public:
RadarReactionSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs, Stuff::Scalar percent):
ReactionSphere(center, radius, secs)
{
m_radarMultiplier = percent;
}
~RadarReactionSphere(){}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ApplyEffect(Mech *mech)
{
Check_Object(this);
mech->m_sensorDinstanceMultiplier += m_radarMultiplier;
}
private:
Stuff::Scalar
m_radarMultiplier;
};
const int MAX_MISSION_TIMERS = 32;
//##########################################################################
//################## MWMission::CreateMessage ########################
//##########################################################################
class MWMission__CreateMessage:
public Adept::Mission__CreateMessage
{
public:
ResourceID railgraphStreamResourceID;
char scriptName[128];
Scalar distanceCheck;
MWMission__CreateMessage(
size_t length,
int priority,
int message_flags,
Stuff::RegisteredClass::ClassID class_id,
int replicator_flags,
const ResourceID& instance_id,
const Stuff::LinearMatrix4D &creation_matrix,
Stuff::Scalar age,
int execution_state,
int name_id,
int entity_alignment,
const Adept::ResourceID &prop_stream_id,
const Adept::ResourceID &map_id,
const Adept::ResourceID &armory_id,
const Adept::ResourceID &name_table_id,
const Adept::ResourceID &sky_id,
const Adept::ResourceID &night_sky_id,
const ResourceID &warning_id,
const ResourceID &mission_id,
bool is_night,
const Adept::ResourceID &rail_graph_id,
const char *script_name,
Scalar distance_check
):
Adept::Mission__CreateMessage(
length,
priority,
message_flags,
class_id,
replicator_flags,
instance_id,
creation_matrix,
age,
execution_state,
name_id,
entity_alignment,
prop_stream_id,
map_id,
armory_id,
name_table_id,
sky_id,
night_sky_id,
warning_id,
mission_id,
is_night
),
railgraphStreamResourceID(rail_graph_id),
distanceCheck (distance_check)
{
Check_Pointer(script_name);
scriptName[0] = 0;
Str_Copy(scriptName, script_name, sizeof(scriptName));
}
static void
ConstructCreateMessage(Script *script);
};
//##########################################################################
//#################### MWMission::ModelResource ######################
//##########################################################################
class MWMission__GameModel:
public Adept::Mission__GameModel
{
public:
Adept::ResourceID
m_animatedTexturesResourceID,
m_movieTexturesResourceID;
static void
ConstructGameModel(Script *script);
static void
SaveGameModel(
MWMission__GameModel *model,
Stuff::NotationFile *data_file
);
};
//##########################################################################
//########################## MWMission ###############################
//##########################################################################
class MWMission:
public Adept::Mission
{
public:
static void
InitializeClass();
static void
TerminateClass();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Inheritance Support
//
typedef MWMission__CreateMessage CreateMessage;
typedef MWMission__GameModel GameModel;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Run-time Construction and Destruction Support
//
public:
static MWMission*
Make(
CreateMessage *message,
ReplicatorID *base_id
);
Adept::Replicator::CreateMessage*
SaveMakeMessage(Stuff::MemoryStream *stream, Adept::ResourceFile *res_file);
void
RespawnMission();
protected:
MWMission(
ClassData *class_data,
CreateMessage *message,
ReplicatorID *base_id,
ElementRenderer::Element *element
);
~MWMission();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Game Model Support
//
public:
const GameModel*
GetGameModel()
{
Check_Object(this);
return Cast_Pointer(const GameModel*,gameModelResource.GetPointer());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Execution Support
//
public:
Adept::ResourceID railgraphStreamResourceID;
Stuff::ChainOf<Entity *> m_CheckChain;
Stuff::Scalar m_DistanceCheck;
void
PreCollisionExecute(Stuff::Time till);
void ABLConstNameTable (void);
char scriptName[128];
long missionScriptHandle;
ABL::ABLModulePtr missionBrain;
void UnloadScript (void);
bool ReloadScript (ABL::ABLError *err);
static bool ReloadABL(ABL::ABLError *err);
static void UnloadABL(void);
ABL::ABLModulePtr Brain (void)
{ return missionBrain; }
void
ResetMissionLights();
void
SetLightAmpMissionLights();
//-----------------------
//Reaction Sphere support
//-----------------------
public:
//This one is used by mechs who are checking
void
ProcessReactionSpheres(Mech *target_mech);
void
ProcessPlayerReactionSpheres(Mech *target_mech);
//This one is used by mission to resolve which ones can stay
void
ResolveReactionSpheres();
void
CreateNewHeatSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs, Stuff::Scalar heat_e);
void
CreateNewInstantHeatSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar heat_amount);
void
CreateNewRadarSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs, Stuff::Scalar radar_e);
void
CreateNewFogSphere(const Stuff::Point3D& center, Stuff::Scalar radius, Stuff::Scalar secs);
Stuff::ChainOf<ReactionSphere *>
m_reactionSpheres;
Stuff::ChainOf<ReactionSphere *>
m_playerOnlyReactionSpheres;
//------------
//Flag settings Support
//------------
public:
enum FLAG_ENABLE_STATE
{
// NOTE: these must EXACTLY match the constants in MWCONST.ABI
FLAGS_HIDE = 0x0,
FLAGS_TEAM_ONLY = 0x1,
FLAGS_UNIVERSAL_ONLY = 0x2,
FLAGS_SHOW_ALL = 0x3
};
void
SetMaxFlagsCarried(int max_flags)
{ m_MaxFlagsCarried = max_flags; }
int
GetMaxFlagsCarried() const
{ return (m_MaxFlagsCarried); }
void
SetFlagDropReturnTime(int return_time)
{ m_FlagDropReturnTime = return_time; }
int
GetFlagDropReturnTime() const
{ return (m_FlagDropReturnTime); }
void
SetFlagCaptureReturnTime(int return_time)
{ m_FlagCaptureReturnTime = return_time; }
int
GetFlagCaptureReturnTime() const
{ return (m_FlagCaptureReturnTime); }
void
SetFlagsEnabled(FLAG_ENABLE_STATE state)
{ m_FlagsEnabled = state; }
bool
GetFlagCaptureEnabled() const
{ return (m_FlagCaptureEnabled); }
void
SetFlagCaptureEnabled(bool enabled)
{ m_FlagCaptureEnabled = enabled; }
FLAG_ENABLE_STATE
GetFlagsEnabled() const
{ return (m_FlagsEnabled); }
void
SetFlagsAsNavPoints(bool show)
{ m_FlagsAsNavPoints = show; }
bool
GetFlagsAsNavPoints() const
{ return (m_FlagsAsNavPoints); }
private:
int
m_MaxFlagsCarried;
int
m_FlagDropReturnTime;
int
m_FlagCaptureReturnTime;
FLAG_ENABLE_STATE
m_FlagsEnabled;
bool
m_FlagCaptureEnabled;
bool
m_FlagsAsNavPoints;
//------------
//Narc Support
//------------
public:
void
AddNarc(Narc *narc, int alignment);
Narc
*GetNarc(int alignment);
Stuff::SortedChainOf<Narc *, int>
m_narcs;
SensorCellMap
m_VehicleAndTurretCellMap;
SensorCellMap
m_BuildingCellMap;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Public Data
//
protected:
MW4AI::CTimeServer m_Timers[MAX_MISSION_TIMERS];
MW4AI::CTimeServer m_EndMissionTimer;
MW4AI::CTimeServer m_missionTimer;
Stuff::Scalar m_EndTime;
GroupContainer
m_GroupContainer;
MW4AI::DiagnosticsInterface
m_DiagnosticsInterface;
bool m_MissionSuccess;
Stuff::ChainOf<AI *> m_LancemateChain;
void DisconnectLancemates (void);
void CreateLancemateGroups ();
void AddToLancemateGroup(Mech* lancemate, int team_number);
private:
Stuff::Scalar
m_LastNavRefresh;
public:
void AddLancemate (AI *lancemate);
CBucketManager *m_BucketManager;
MW4AI::CTimeServer& Timer (int id)
{
Verify (id >= 0);
Verify (id<MAX_MISSION_TIMERS);
return m_Timers[id];
}
void EndMissionState (bool succeeded);
bool EndMissionState (void) const
{ return m_MissionSuccess; }
void SetEndMissionTime (Stuff::Scalar seconds);
void SetNetworkTime (Stuff::Scalar seconds)
{
m_EndMissionTimer.SetTime(seconds);
}
void StartMissionTimer()
{
m_missionTimer.Start();
}
bool EndMissionTimerRunning()
{
return (m_EndMissionTimer.Running());
}
//»óÈÆ
Stuff::Scalar GetMissionDuration ()
{
if (!m_EndMissionTimer.Running ())
return 0;
return m_EndTime;
}
Stuff::Scalar GetEndMissionTime ()
{
if (!m_EndMissionTimer.Running ())
return 0;
return m_EndTime - (Stuff::Scalar)m_EndMissionTimer.CurrTime();
}
Stuff::Scalar GetMissionTime ()
{
if (!m_missionTimer.Running ())
return 0;
return (Stuff::Scalar)m_missionTimer.CurrTime();
}
Scalar lastShutdownTest;
Scalar shutDownTimer;
bool TestForGameShutDown(ReplicatorID victim_id);
bool TestForGameShutDownUnlimitedRespawn();
// MSL 5.02 headshot
// virtual void ScoringReactToMechDeath(const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id);
virtual void ScoringReactToMechDeath(const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id, int damageMode);
virtual void
ScoringReactToTurretDeath (const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id);
virtual void
ScoringReactToBuildingDeath (const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id);
virtual void AddScoreMember (const Adept::ReplicatorID& member, const Stuff::MString& name);
virtual void RemoveScoreMember (const Adept::ReplicatorID& member);
virtual void
SaveInstanceText(Stuff::Page *page);
GroupContainer&
GetGroupContainer();
const GroupContainer&
GetGroupContainer() const;
MW4AI::DiagnosticsInterface&
GetDiagnosticsInterface();
const MW4AI::DiagnosticsInterface&
GetDiagnosticsInterface() const;
int
m_ChanceLancematesEject;
int
m_ChanceLancematesOKWhenEjecting;
int
m_ChanceLancematesInjuredWhenEjecting;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Stuff::Point3D
m_ConstraintTopLeft;
Stuff::Point3D
m_ConstraintBottomRight;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Texture Animation Support
//
public:
void
InitializeTextureAnimations(const Adept::ResourceID& anim_resource_id);
void
PlayAnimations(Stuff::Scalar time_slice);
void
PlayTextureMovies(Stuff::Scalar time_slice);
static int
FindIndex(
const char *joint_name,
void *user_data
);
static void
ApplyChannel
(
MW4Animation::ChannelApplication &channel_data,
int joint_index,
void *user_data
);
Stuff::DynamicArrayOf<PlugOf<MString> *>
animatedTextureNames;
Stuff::DynamicArrayOf<MidLevelRenderer::MLRTexture *>
animatedTextures;
Stuff::DynamicArrayOf<Stuff::Scalar>
animatedTexturesMultipliers;
Stuff::ChainOf<MW4Animation::AnimInstance *>
m_textureAnimInstances;
Stuff::ChainOf<MW4Animation::AnimIterator *>
m_textureAnimIterators;
MW4Animation::AnimHierarchyIteratorManager
*iteratorManager;
int
m_numberOfAnims;
Stuff::DynamicArrayOf<PlugOf<MString> *>
movieTextureNames;
Stuff::DynamicArrayOf<MidLevelRenderer::MLRMovieTexture *>
movieTextures;
Stuff::DynamicArrayOf<Stuff::Scalar>
movieTexturesFrameTime;
int
m_numberOfMovies;
MW4AI::DebugRenderer m_AIDebugRenderer;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Coliseum Support
//
private:
int
m_missionType;
public:
enum {
MISSIONTYPE_UNSPECIFIED=0,
MISSIONTYPE_ARCTIC,
MISSIONTYPE_SWAMP,
MISSIONTYPE_HOTPLATE,
MISSIONTYPE_COLISEUM,
MISSIONTYPE_FACTORY,
MISSIONTYPE_JUNGLE
};
int
GetMissionType()
{ return m_missionType;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Texture Animation Support
//
void
InitializeTextureMovies(const Adept::ResourceID& movie_resource_id);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
public:
enum {
StartMusicStatusAttributeID=0,
TransMusicStatusAttributeID,
NumMissionAttributes
};
public:
//
// Attributes
//
int startMusicStatus;
int transMusicStatus;
public: // jcem - 30/60 seconds to mission termination
bool m_b30notified;
bool m_b60notified;
public: // jcem - no abrupt ending for "No Return" game...
Stuff::Scalar m_fShouldBeStopped;
public: // jcem - no abrupt ending for "No Return" game...
Stuff::Scalar CheckEndMissionTime ();
protected: // jcem - no abrupt ending for "No Return" game...
bool real_TestForGameShutDown(ReplicatorID victim_id); // jcem
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test Support
//
public:
void
TestInstance() const;
public: // jcem
bool m_bOrgBoundsStored;
bool m_bBoundsWarningsEnabled;
Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> >
m_warningPolygonOld,
m_missionPolygonOld;
Stuff::Point3D m_ConstraintTopLeftOld;
Stuff::Point3D m_ConstraintBottomRightOld;
public: // jcem
void StoreOriginalBounds();
void RestoreOriginalBounds();
void SetBoundsFromPaths(const MechWarrior4::Path& PathMission, const MechWarrior4::Path& PathWarning);
public: // COOP <-> ablxstd <-> *.abl
enum {
COOP_MISC_START = 0,
MAX_COOP_MISCS = 100,
COOP_SUBSTAGE_SCORE_OLD,
COOP_ENEMY_GROUP,
COOP_ENEMY_GROUP_OLD,
COOP_MODAL_START,
COOP_MODAL_IS_ENDED,
COOP_SUBSTAGE_TIMEGOAL,
COOP_SUBSTAGE_NUMBER,
MAX_COOP_VARS,
};
int m_naCOOPs[MAX_COOP_VARS];
public:
void InitCOOP();
void ExitCOOP();
int GetCOOP(int nIdx, void* pDest = (void*)NULL);
int SetCOOP(int nIdx, int nParam);
};
}