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.
525 lines
16 KiB
C++
525 lines
16 KiB
C++
//===========================================================================//
|
|
// File: MW4EdApplication.cpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 12/02/97 DPB Infrastructure changes. //
|
|
// 11/03/98 SMJ MW4 changes. //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1995-97, Virtual World Entertainment, Inc. //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
#include "stdafx.h"
|
|
#include "MW4GameEd.h"
|
|
#include "MW4GameEdApplication.hpp"
|
|
#include <MW4\MWApplication.hpp>
|
|
#include <Adept\Map.hpp>
|
|
#include <ElementRenderer\GridElement.hpp>
|
|
#include <MW4\VehicleInterface.hpp>
|
|
#include <Adept\Player.hpp>
|
|
#include "MainFrm.h"
|
|
#include <MW4\Rail_move.hpp>
|
|
#include <mw4\mwmission.hpp>
|
|
#include <Adept\DropZone.hpp>
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <io.h>
|
|
#include <Adept\Mission.hpp>
|
|
#include "DisplayWindow.h"
|
|
#include "OverviewWindow.h"
|
|
#include "InstanceWindow.h"
|
|
#include <MW4\MWTool.hpp>
|
|
#include <BuildNum\BuildNum.h>
|
|
#include <Adept\ResourceEffectLibrary.hpp>
|
|
#include <MW4\MWPlayer.hpp>
|
|
|
|
#define __mbschr(s,c) (char*)_mbschr((const unsigned char*)(s),(c))
|
|
#define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c))
|
|
|
|
extern CMW4GameEdApp theApp;
|
|
using namespace MW4AI;
|
|
|
|
//#############################################################################
|
|
//######################## MW4GameEdApplication ######################
|
|
//#############################################################################
|
|
|
|
//#############################################################################
|
|
// Message Support
|
|
//
|
|
const Receiver::MessageEntry
|
|
MW4GameEdApplication::MessageEntries[]=
|
|
{
|
|
MESSAGE_ENTRY(MW4GameEdApplication, PauseGame)
|
|
};
|
|
|
|
MW4GameEdApplication::ClassData*
|
|
MW4GameEdApplication::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MW4GameEdApplication::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
MW4GameEdApplicationClassID,
|
|
"MW4GameEdApplication",
|
|
MWApplication::DefaultData,
|
|
ELEMENTS(MessageEntries),
|
|
MessageEntries
|
|
);
|
|
Check_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MW4GameEdApplication::TerminateClass()
|
|
{
|
|
Check_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MW4GameEdApplication*
|
|
MW4GameEdApplication::Make()
|
|
{
|
|
return new MW4GameEdApplication;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MW4GameEdApplication::MW4GameEdApplication():
|
|
MWApplication(DefaultData,false)
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MW4GameEdApplication::~MW4GameEdApplication()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MW4GameEdApplication::LoadGameMessageHandler(int connection, Stuff::MemoryStream *message)
|
|
{
|
|
Check_Object(this);
|
|
|
|
theApp.m_NumObjectives = 0;
|
|
|
|
MWApplication::LoadGameMessageHandler(connection, message);
|
|
|
|
theApp.overviewWindow->LoadImageFromMissionInstance(theApp.missionFileName);
|
|
|
|
BYTE r, c;
|
|
Scalar rowcell, colcell, offset = 0;
|
|
|
|
Check_Object(Map::Instance);
|
|
Map::Instance->GetElement()->GetSize(&r, &c);
|
|
Map::Instance->GetElement()->GetDimensions(&offset,&offset,&rowcell,&colcell);
|
|
theApp.displayWindow->mapX = c * colcell;
|
|
theApp.displayWindow->mapZ = r * rowcell;
|
|
theApp.overviewWindow->mapWidth = int(theApp.displayWindow->mapX);
|
|
theApp.overviewWindow->mapHeight = int(theApp.displayWindow->mapZ);
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
//We need to create a drop zone with the name PlayerStart
|
|
//-------------------------------------------------------
|
|
//
|
|
if(NameTable::Instance->FindID("PlayerStart") == NameTable::NullObjectID)
|
|
{
|
|
Resource model_resource;
|
|
SPEW(("scottjan","Get rid of the hard coded data file"));
|
|
NotationFile dropzone_file("Content\\Misc\\DropZone.data");
|
|
Tool::Instance->ConstructDataList(&model_resource, &dropzone_file);
|
|
Check_Object(&model_resource);
|
|
Verify(model_resource.DoesResourceExist());
|
|
|
|
Entity::ClassID class_ID;
|
|
class_ID = Entity::GetClassIDFromDataListID(model_resource.GetResourceID());
|
|
Verify(class_ID != NullClassID);
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
// Point3D translation(500.0, 0.0, 500.0);
|
|
Scalar f;
|
|
f = -45.0f;
|
|
Point3D translation(f, 0.0, f);
|
|
matrix.BuildTranslation(translation);
|
|
|
|
Adept::DropZone::CreateMessage drop_zone_message(
|
|
sizeof(Adept::DropZone::CreateMessage),
|
|
DefaultEventPriority,
|
|
Adept::DropZone::CreateMessage::DefaultFlags,
|
|
class_ID,
|
|
Adept::DropZone::DefaultFlags,
|
|
model_resource.GetResourceID(),
|
|
matrix,
|
|
0.0f,
|
|
Entity__ExecutionStateEngine::NeverExecuteState,
|
|
NameTable::NullObjectID,
|
|
Entity::DefaultAlignment,
|
|
ResourceID::Null
|
|
);
|
|
|
|
MemoryStream stream(&drop_zone_message, drop_zone_message.messageLength);
|
|
|
|
ReplicatorID Path_id = Connection::Local->GetNextReplicatorID();
|
|
Entity* entity;
|
|
entity = Entity::CreateEntity(&stream, &Path_id, false);
|
|
Check_Object(entity);
|
|
Verify(entity->IsDerivedFrom(DropZone::DefaultData));
|
|
|
|
//Check_Object(EntityManager::Instance);
|
|
//EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
entity->instanceName = "PlayerStart";
|
|
//EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
|
|
Check_Object(Map::Instance);
|
|
Map::Instance->AddChild(entity);
|
|
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
entity->SyncMatrices(true);
|
|
|
|
Verify(entity->IsDerivedFrom(DropZone::DefaultData));
|
|
NameTable::Instance->AddEntry(entity, NameTable::DropZoneArray);
|
|
NameTable::Instance->IsValid();
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
Map::Instance->UpdateZone(entity);
|
|
}
|
|
theApp.m_MissionSaved = true;
|
|
MWMission *mission = Cast_Object (MWMission *,Mission::Instance);
|
|
theApp.m_ScriptName = mission->scriptName;
|
|
|
|
theApp.ambientLightIndex = -1;
|
|
theApp.keyLightIndex = -1;
|
|
theApp.fillLightIndex = -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MW4GameEdApplication::EnterRunningGameState(void* data)
|
|
{
|
|
Check_Object(this);
|
|
|
|
|
|
MWApplication::EnterRunningGameState(data);
|
|
|
|
// CMenu* m = theApp.m_pMainWnd->GetMenu();
|
|
// m->EnableMenuItem(3,MF_ENABLED | MF_BYPOSITION);
|
|
theApp.m_pMainWnd->DrawMenuBar();
|
|
theApp.toolBar->EnableButton(ID_FILE_SAVE);
|
|
|
|
theApp.m_editorState = CMW4GameEdApp::SelectingObjectState;
|
|
|
|
if (!MW4AI::g_MissionGraph)
|
|
{
|
|
MW4AI::g_MissionGraph = new CRailGraph(CRailGraph::DefaultData);
|
|
|
|
// write RailGraph=xGraph.data in mission.instance
|
|
// CreateMissionResource(missionname);
|
|
}
|
|
|
|
theApp.LoadLattice();
|
|
|
|
theApp.m_showLattice = true;
|
|
theApp.OnToolsMovementlattice(); // this will set m_showLattice to false
|
|
|
|
theApp.m_showDropZones = true;
|
|
theApp.OnToolsMovmentlayerShowdropzones();
|
|
theApp.m_showAI = true;
|
|
theApp.OnToolsMovmentlayerShowobjectives();
|
|
|
|
theApp.m_CurPath = NULL;
|
|
theApp.m_CurPathNodeCount = 0;
|
|
|
|
// Create editor iface objects for paths
|
|
theApp.LoadPaths();
|
|
theApp.LoadLights();
|
|
theApp.LoadObjectives();
|
|
theApp.LoadCameras();
|
|
|
|
int i;
|
|
Adept::Mission::Instance->GetMissionPolygon(theApp.missionBoundary);
|
|
Adept::Mission::Instance->GetWarningPolygon(theApp.warningBoundary);
|
|
|
|
for (i = 0; i < theApp.missionBoundary.GetLength(); i++)
|
|
{
|
|
theApp.missionBoundary[i].x /= Map::Instance->GetColumnZoneScale();
|
|
theApp.missionBoundary[i].y /= Map::Instance->GetRowZoneScale();
|
|
theApp.missionBoundary[i].x-=theApp.overviewWindow->mapWidth*0.5f;
|
|
theApp.missionBoundary[i].y-=theApp.overviewWindow->mapHeight*0.5f;
|
|
}
|
|
|
|
for ( i = 0; i < theApp.warningBoundary.GetLength(); i++)
|
|
{
|
|
theApp.warningBoundary[i].x /= Map::Instance->GetColumnZoneScale();
|
|
theApp.warningBoundary[i].y /= Map::Instance->GetRowZoneScale();
|
|
theApp.warningBoundary[i].x-=theApp.overviewWindow->mapWidth*0.5f;
|
|
theApp.warningBoundary[i].y-=theApp.overviewWindow->mapHeight*0.5f;
|
|
}
|
|
|
|
theApp.LoadBoundary();
|
|
theApp.LoadDropZones();
|
|
|
|
// Load any predefined camera positions
|
|
|
|
_finddata_t filedata;
|
|
char path[MAX_PATH],tmpString[MAX_PATH],*p;
|
|
strcpy(tmpString,theApp.missionFileName);
|
|
p = strrchr(tmpString,'.');
|
|
*p = 0;
|
|
sprintf(path,"%s.editcameras",tmpString);
|
|
|
|
if (_findfirst(path,&filedata) == -1) // no presets file
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
theApp.m_DefCameraPos[i] = Stuff::LinearMatrix4D::Identity;
|
|
theApp.m_DefCameraName[i][0] = (char)('0' + (char)i);
|
|
theApp.m_DefCameraName[i][1] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Stuff::Point3D trans;
|
|
Stuff::YawPitchRoll rot;
|
|
Stuff::LinearMatrix4D matrix = Stuff::LinearMatrix4D::Identity;
|
|
|
|
NotationFile infile(path);
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
Page *page = infile.FindPage(itoa(i,tmpString,10));
|
|
if (page)
|
|
{
|
|
page->GetEntry("Translation",&trans);
|
|
page->GetEntry("YawPitchRoll",&rot);
|
|
const char * ptr = NULL;
|
|
page->GetEntry("CameraName", &(ptr), FALSE);
|
|
if (ptr)
|
|
lstrcpy(theApp.m_DefCameraName[i], ptr);
|
|
}
|
|
|
|
if (!page || (trans.x == 0.0f && trans.y == 0.0f && trans.z == 0.0f &&
|
|
rot.yaw == 0.0f && rot.pitch == 0.0f && rot.roll == 0.0f))
|
|
{
|
|
theApp.m_DefCameraPos[i] = Stuff::LinearMatrix4D::Identity;
|
|
theApp.m_DefCameraName[i][0] = (char)('0' + (char)i);
|
|
theApp.m_DefCameraName[i][1] = 0;
|
|
}
|
|
else
|
|
{
|
|
matrix.BuildTranslation(trans);
|
|
matrix.BuildRotation(rot);
|
|
|
|
theApp.m_DefCameraPos[i] = matrix;
|
|
}
|
|
}
|
|
theApp.UpdateCameraMenus(-1);
|
|
}
|
|
|
|
MW4AI::g_MissionGraph->m_SaveLineElementMemory = true;
|
|
VehicleInterface *temp_interface =
|
|
Cast_Object(VehicleInterface *, Player::Instance->playerInterface);
|
|
|
|
temp_interface->cameraOffset = Point3D::Identity;
|
|
|
|
LinearMatrix4D new_local_to_parent = LinearMatrix4D::Identity;
|
|
Point3D new_position = Point3D::Identity;
|
|
YawPitchRoll new_rotation = YawPitchRoll::Identity;
|
|
|
|
new_position.x = 0.0f;
|
|
new_position.z = 0.0f;
|
|
new_position.y = theApp.displayWindow->GetMapPointVertical(new_position.x,new_position.z) + theApp.cameraHeight;
|
|
new_rotation.yaw = 0;
|
|
new_local_to_parent.BuildTranslation(new_position);
|
|
new_local_to_parent.BuildRotation(new_rotation);
|
|
Player::Instance->SetNewLocalToParent(new_local_to_parent);
|
|
Player::Instance->SyncMatrices(true);
|
|
theApp.overviewWindow->UpdateCamera();
|
|
theApp.overviewWindow->DrawWindow();
|
|
|
|
theApp.OnToolsCameraheightMechheight10m();
|
|
theApp.instanceWindow->ResetInstanceLists();
|
|
}
|
|
|
|
void
|
|
MW4GameEdApplication::PauseGameMessageHandler(const PauseGameMessage *message)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(message);
|
|
Verify(message->messageID == PauseGameMessageID);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
void
|
|
MW4GameEdApplication::LoadMissionResources(const char *mission_name)
|
|
{
|
|
|
|
//
|
|
//---------------------------------------------------------
|
|
// Get the mission instance name and the resource file name
|
|
//---------------------------------------------------------
|
|
//
|
|
Stuff::MString mission_instance = mission_name;
|
|
Stuff::MString res_name = "Resources\\";
|
|
res_name += __mbschr(mission_instance,'\\')+1;
|
|
char *p = __mbsrchr(res_name, '\\');
|
|
Check_Pointer(p);
|
|
Str_Copy(p, ".mw4", res_name.GetLength() - (p - res_name));
|
|
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// Open up the resource file as a database and access record 0. This
|
|
// will contain the list of resource files this one is dependant on
|
|
//-------------------------------------------------------------------
|
|
//
|
|
Stuff::DatabaseHandle *database =
|
|
new Stuff::DatabaseHandle(res_name, false, VER_CONTENTVERSION);
|
|
Stuff::RecordHandle record;
|
|
record.m_databaseHandle = database;
|
|
record.m_ID = ResourceID::BuildDependenciesRecordID;
|
|
#if defined(_ARMOR)
|
|
bool result =
|
|
#endif
|
|
record.FindID();
|
|
Verify(result);
|
|
|
|
//
|
|
//-------------------------
|
|
// Load up the core effects
|
|
//-------------------------
|
|
//
|
|
Verify(!gosFX::EffectLibrary::Instance);
|
|
gosFX::EffectLibrary::Instance = new ResourceEffectLibrary;
|
|
Resource core_libraries("{effects}");
|
|
Verify(core_libraries.DoesResourceExist());
|
|
ResourceID *lib = Cast_Pointer(ResourceID*, core_libraries.GetPointer());
|
|
for (unsigned i=0; i<core_libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
|
|
{
|
|
Resource library(*lib);
|
|
gosFX::EffectLibrary::Instance->Load(&library);
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// The data points to a series of null terminated strings. Step through
|
|
// them until done
|
|
//----------------------------------------------------------------------
|
|
//
|
|
const char* data = reinterpret_cast<const char*>(record.m_data);
|
|
int level=MapResourceFileID;
|
|
for (DWORD count=0; count<record.m_length; ++level)
|
|
{
|
|
if (!data[count])
|
|
break;
|
|
|
|
MString depstr=data+count;
|
|
strcpy(strrchr(depstr,'.')+1,"dep");
|
|
//
|
|
//---------------------------
|
|
// Load this resource file up
|
|
//---------------------------
|
|
//
|
|
ResourceManager::Instance->OpenResourceFile(
|
|
data+count,
|
|
depstr,
|
|
level,
|
|
VER_CONTENTVERSION,
|
|
true,
|
|
false
|
|
);
|
|
|
|
//
|
|
//----------------------------
|
|
// Load up this file's effects
|
|
//----------------------------
|
|
//
|
|
Resource libraries("{effects}");
|
|
if (libraries.DoesResourceExist() && libraries.GetResourceID().GetFileID() == level)
|
|
{
|
|
ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer());
|
|
for (unsigned i=0; i<libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
|
|
{
|
|
Resource library(*lib);
|
|
gosFX::EffectLibrary::Instance->Load(&library);
|
|
}
|
|
}
|
|
|
|
count += strlen(data+count)+1;
|
|
}
|
|
|
|
//
|
|
//---------------------------------
|
|
// Now create our own resource file
|
|
//---------------------------------
|
|
//
|
|
MString depstr=res_name;
|
|
strcpy(strrchr(depstr,'.')+1,"dep");
|
|
|
|
ResourceManager::Instance->OpenResourceFile(database,
|
|
depstr,
|
|
level,
|
|
VER_CONTENTVERSION,
|
|
true,
|
|
false);
|
|
Resource libraries("{effects}");
|
|
if (libraries.DoesResourceExist() && libraries.GetResourceID().GetFileID() == level)
|
|
{
|
|
ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer());
|
|
for (unsigned i=0; i<libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
|
|
{
|
|
Resource library(*lib);
|
|
gosFX::EffectLibrary::Instance->Load(&library);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
Entity::CreateMessage *
|
|
MW4GameEdApplication::MakePlayerCreationMessage(int player_id)
|
|
{
|
|
|
|
Resource vehicle_instance("Content\\Mechs\\ShadowCat\\shadowcat.instance");
|
|
MString interface_name = "Interfaces\\SimpleInterface\\SimpleInterface.instance";
|
|
Resource interface_instance(interface_name);
|
|
Resource player_data("Players\\TestPlayer\\TestPlayer.data");
|
|
|
|
|
|
MWPlayer::CreateMessage *player_message =
|
|
new MWPlayer::CreateMessage(
|
|
sizeof(MWPlayer::CreateMessage),
|
|
DefaultEventPriority,
|
|
MWPlayer::CreateMessage::DefaultFlags,
|
|
MWPlayerClassID,
|
|
0,
|
|
player_data.GetResourceID(),
|
|
LinearMatrix4D::Identity,
|
|
0.0f,
|
|
MWPlayer::ExecutionStateEngine::AlwaysExecuteState,
|
|
NameTableEntry::BuildObjectID(NameTable::PlayerArray, 0),
|
|
Entity::Player,
|
|
vehicle_instance.GetResourceID(),
|
|
interface_instance.GetResourceID(),
|
|
NameTable::NullObjectID,
|
|
0,
|
|
DefaultSkinPrefix,
|
|
0,
|
|
0
|
|
);
|
|
Check_Object(player_message);
|
|
|
|
return player_message;
|
|
|
|
}
|