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.
5476 lines
163 KiB
C++
5476 lines
163 KiB
C++
// MW4GameEd.cpp : Defines the class behaviors for the application.
|
|
//
|
|
|
|
#include <io.h>
|
|
#include <direct.h>
|
|
|
|
#include "stdafx.h"
|
|
#include "MW4GameEd.h"
|
|
#include "DisplayWindow.h"
|
|
#include "OverviewWindow.h"
|
|
#include "InstanceWindow.h"
|
|
#include "ResourceWindow.h"
|
|
#include "MainFrm.h"
|
|
#include <MLR\MLR.hpp>
|
|
#include <MLR\MLRTexturePool.hpp>
|
|
#include <MLR\MLRLight.hpp>
|
|
#include <MFCPlatform\MFCPlatform.hpp>
|
|
#include <MW4\MWTool.hpp>
|
|
#include <MW4\MWApplication.hpp>
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <Adept\Map.hpp>
|
|
#include "selection.h"
|
|
#include "startdlg.h"
|
|
#include "OpenMapFileDlg.h"
|
|
#include "GenericTextDlg.h"
|
|
#include <direct.h>
|
|
#include <errno.h>
|
|
#include <io.h>
|
|
#include "Selection.h"
|
|
#include "MoveCommand.h"
|
|
#include "MW4GameEdApplication.hpp"
|
|
#include <MW4\MWMission.hpp>
|
|
#include <MW4\MWPlayer.hpp>
|
|
#include "NewMissionDlg.h"
|
|
#include "MsgDlg.h"
|
|
#include "FileDlg.h"
|
|
#include "tipDlg.h"
|
|
#include <Adept\resource.hpp>
|
|
#include <mw4\ai.hpp>
|
|
#include "AddCommand.h"
|
|
#include <Adept\NameTable.hpp>
|
|
#include <Stuff\MemoryStream.hpp>
|
|
#include "DeleteCommand.h"
|
|
#include <Adept\NameTable.hpp>
|
|
#include <Compost\TerrainTextureLogistic.hpp>
|
|
#include <MW4\Building.hpp>
|
|
#include <mw4\EffectGenerator.hpp>
|
|
#include <MW4\SearchLight.hpp>
|
|
#include <MW4\Turret.hpp>
|
|
#include <mw4\Cultural.hpp>
|
|
#include <ElementRenderer\StateChange.hpp>
|
|
#include <mw4\mwmission.hpp>
|
|
#include <ElementRenderer\LightElement.hpp>
|
|
#include <Adept\ResourceEffectLibrary.hpp>
|
|
#include <MW4\MechLab.hpp>
|
|
#include <MW4\Rail_move.hpp>
|
|
#include "GlobalDefs.h"
|
|
#include "LightWnd.h"
|
|
#include "FogDlg.h"
|
|
#include "EditorWayPoint.h"
|
|
#include "mw4\mwmap.hpp"
|
|
#include <mw4\NavPoint.hpp>
|
|
#include <mw4\noncom.hpp>
|
|
#include <Adept\Entity.hpp>
|
|
|
|
#include "..\buildnum\buildnum.h" // current version and build number
|
|
#include <dos.h>
|
|
|
|
#include <MW4\rail_move.hpp>
|
|
#include "Splash.h"
|
|
#include "ProgDlg.h"
|
|
#include "dlgobjectproperties.h"
|
|
#include "dlgobjectbalance.h"
|
|
|
|
#define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c))
|
|
|
|
using namespace MW4AI;
|
|
extern CMW4GameEdApp theApp;
|
|
|
|
void _stdcall TerminateGameEngine();
|
|
|
|
char* Command_Line;
|
|
char Working_Directory[128];
|
|
|
|
void AddToBuildFile(CString missionName,CString map_name);
|
|
|
|
bool TestFileWrite(char* filename)
|
|
{
|
|
DWORD result = GetFileAttributes(filename);
|
|
|
|
if (result == -1)
|
|
return true;
|
|
if (result & FILE_ATTRIBUTE_READONLY) // is it marked READONLY?
|
|
{
|
|
MessageBox(NULL,"Unable to save file becuase some of the data files are marked READONLY","Save Error",MB_OK);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
CProgressDlg* ProgressDlg = NULL;
|
|
|
|
void CalcLinkProgress(float pct)
|
|
{
|
|
ProgressDlg->SetPos(int(pct));
|
|
}
|
|
|
|
bool EditMissionScriptCallback(char* filename)
|
|
{
|
|
MWMission *mission = Cast_Object (MWMission *,Mission::Instance);
|
|
strncpy(mission->scriptName,filename,127);
|
|
theApp.m_ScriptName = filename;
|
|
return true;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CMW4GameEdApp
|
|
|
|
BEGIN_MESSAGE_MAP(CMW4GameEdApp, CWinApp)
|
|
ON_COMMAND(CG_IDS_TIPOFTHEDAY, ShowTipOfTheDay)
|
|
ON_COMMAND_RANGE(ID_SET_CAMERA_POS_0, ID_SET_CAMERA_POS_9, OnSetNumberedCameraPosition )
|
|
ON_COMMAND_RANGE(ID_GOTO_CAMERA_POS_0, ID_GOTO_CAMERA_POS_9, OnGotoNumberedCameraPosition)
|
|
ON_UPDATE_COMMAND_UI_RANGE(ID_TOOLS_DEF_ALIGNMENT_1, ID_TOOLS_DEF_ALIGNMENT_10, OnUpdateDefaultAlignmentMenu)
|
|
ON_COMMAND_RANGE(ID_TOOLS_DEF_ALIGNMENT_1, ID_TOOLS_DEF_ALIGNMENT_10, OnDefaultAlignmentMenu)
|
|
//{{AFX_MSG_MAP(CMW4GameEdApp)
|
|
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
|
|
ON_COMMAND(ID_FILE_NEW, OnFileNew)
|
|
ON_COMMAND(ID_VIEW_OVERVIEWWINDOW, OnToggleOverviewWindow)
|
|
ON_COMMAND(ID_VIEW_RESOURCEWINDOW, OnToggleResourceWindow)
|
|
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
|
|
ON_COMMAND(ID_ADJUSTGRID, OnAdjustGrid)
|
|
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_OVERVIEWWINDOW, OnUpdateViewOverviewwindow)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESOURCEWINDOW, OnUpdateViewResourcewindow)
|
|
ON_COMMAND(ID_VIEW_DISPLAYWINDOW, OnViewDisplaywindow)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_DISPLAYWINDOW, OnUpdateViewDisplaywindow)
|
|
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
|
|
ON_COMMAND(ID_TOOLS_CAMERAHEIGHT_FOURTIMESMECHHEIGHT40M, OnToolsCameraheightFourtimesmechheight40m)
|
|
ON_COMMAND(ID_TOOLS_CAMERAHEIGHT_GROUND, OnToolsCameraheightGround)
|
|
ON_COMMAND(ID_TOOLS_CAMERAHEIGHT_MECHHEIGHT10M, OnToolsCameraheightMechheight10m)
|
|
ON_COMMAND(ID_TOOLS_CAMERAHEIGHT_TWICEMECHHEIGHT20M, OnToolsCameraheightTwicemechheight20m)
|
|
ON_COMMAND(ID_TOOLS_CAMERASPEED_SLOW, OnToolsCameraspeedSlow)
|
|
ON_COMMAND(ID_TOOLS_CAMERASPEED_REGULAR, OnToolsCameraspeedRegular)
|
|
ON_COMMAND(ID_TOOLS_CAMERASPEED_FAST, OnToolsCameraspeedFast)
|
|
ON_COMMAND(ID_VIEW_INSTANCEWINDOW, OnViewInstancewindow)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_INSTANCEWINDOW, OnUpdateViewInstancewindow)
|
|
ON_COMMAND(ID_TOOLS_BRIEFINGFILE, OnToolsBriefingfile)
|
|
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
|
|
ON_COMMAND(ID_TOOLS_CAMERAFOLLOWING_GROUND, OnToolsCamerafollowingGround)
|
|
ON_COMMAND(ID_TOOLS_CAMERAFOLLOWING_HIGHESTPOINT, OnToolsCamerafollowingHighestpoint)
|
|
ON_COMMAND(ID_TOOLS_CAMERAFOLLOWING_NONE, OnToolsCamerafollowingNone)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERAFOLLOWING_GROUND, OnUpdateToolsCamerafollowingGround)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERAFOLLOWING_HIGHESTPOINT, OnUpdateToolsCamerafollowingHighestpoint)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERAFOLLOWING_NONE, OnUpdateToolsCamerafollowingNone)
|
|
ON_COMMAND(ID_TOOLS_CAMERAHEIGHT_USERDEFINED, OnToolsCameraheightUserdefined)
|
|
ON_COMMAND(ID_VIEW_RESIZE1024, OnViewResize1024)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZE1024, OnUpdateViewResize1024)
|
|
ON_COMMAND(ID_VIEW_RESIZE1152, OnViewResize1152)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZE1152, OnUpdateViewResize1152)
|
|
ON_COMMAND(ID_VIEW_RESIZE1280, OnViewResize1280)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZE1280, OnUpdateViewResize1280)
|
|
ON_COMMAND(ID_VIEW_RESIZE1600, OnViewResize1600)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZE1600, OnUpdateViewResize1600)
|
|
ON_COMMAND(ID_VIEW_RESIZE640, OnViewResize640)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZE640, OnUpdateViewResize640)
|
|
ON_COMMAND(ID_VIEW_RESIZE800, OnViewResize800)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZE800, OnUpdateViewResize800)
|
|
ON_COMMAND(ID_FILE_AUTOBACKUPONSAVE, OnFileAutobackuponsave)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_AUTOBACKUPONSAVE, OnUpdateFileAutobackuponsave)
|
|
ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSaveAs)
|
|
ON_COMMAND(ID_FILE_DELETE, OnFileDelete)
|
|
ON_COMMAND(ID_TOOLS_MOVEMENTLATTICE, OnToolsMovementlattice)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVEMENTLATTICE, OnUpdateToolsMovementlattice)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWLATTICELINKS, OnToolsMovmentlayerShowlatticelinks)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWLATTICELINKS, OnUpdateToolsMovmentlayerShowlatticelinks)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_RECALCLATTICELINKS, OnToolsMovmentlayerRecalclatticelinks)
|
|
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
|
|
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWALL, OnToolsMovmentlayerShowall)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWNODERADII, OnToolsMovmentlayerShownoderadii)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWPATHS, OnToolsMovmentlayerShowpaths)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWALL, OnUpdateToolsMovmentlayerShowall)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWNODERADII, OnUpdateToolsMovmentlayerShownoderadii)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWPATHS, OnUpdateToolsMovmentlayerShowpaths)
|
|
ON_COMMAND(ID_TOOLS_MECHLAB, OnToolsMechlab)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWMISSIONBOUNDARY, OnToolsMovmentlayerShowmissionboundary)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWMISSIONBOUNDARY, OnUpdateToolsMovmentlayerShowmissionboundary)
|
|
ON_COMMAND(ID_TOOLS_VERIFYOBJECTPLACEMENT, OnToolsVerifyobjectplacement)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWDROPZONES, OnToolsMovmentlayerShowdropzones)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWDROPZONES, OnUpdateToolsMovmentlayerShowdropzones)
|
|
ON_COMMAND(ID_TOOLS_EDITMISSIONSCRIPT, OnToolsEditmissionscript)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_SHOWOBJECTIVES, OnToolsMovmentlayerShowobjectives)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MOVMENTLAYER_SHOWOBJECTIVES, OnUpdateToolsMovmentlayerShowobjectives)
|
|
ON_COMMAND(ID_VIEW_SHOWTILEBORDERS, OnViewShowtileborders)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWTILEBORDERS, OnUpdateViewShowtileborders)
|
|
ON_COMMAND(ID_TOOLS_SPECIFYMISSIONSCRIPT, OnToolsSpecifymissionscript)
|
|
ON_COMMAND(ID_TOOLS_CHECKSCRIPTS, OnToolsCheckscripts)
|
|
ON_COMMAND(ID_TOOLS_MOVMENTLAYER_CREATELATTICE, OnToolsMovmentlayerCreatelattice)
|
|
ON_COMMAND(ID_TOOLS_MOVEMENTLAYER_CREATERECTS, OnToolsMovmentlayerCreateRects)
|
|
ON_COMMAND(ID_TOOLS_MISSIONPARAMETERS_EDITFOG, OnToolsMissionparametersEditfog)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERASPEED_FAST, OnUpdateToolsCameraspeedFast)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERASPEED_REGULAR, OnUpdateToolsCameraspeedRegular)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERASPEED_SLOW, OnUpdateToolsCameraspeedSlow)
|
|
ON_COMMAND(ID_TOOLS_SNAPOBJECTSTOTERRAIN, OnToolsSnapobjectstoterrain)
|
|
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
|
|
ON_COMMAND(ID_TOOLS_WEAPONSPROPERTIES, OnToolsWeaponsProperties)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_MECHPROPERTIES, OnUpdateToolsMechProperties)
|
|
ON_COMMAND(ID_TOOLS_MECHPROPERTIES, OnToolsMechProperties)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_WEAPONSPROPERTIES, OnUpdateToolsWeaponsProperties)
|
|
ON_COMMAND(ID_TOOLS_WEAPONSBALANCING, OnToolsWeaponsBalancing)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_WEAPONSBALANCING, OnUpdateToolsWeaponsBalancing)
|
|
ON_COMMAND(ID_TOOLS_ARMORBALANCING, OnToolsArmorBalancing)
|
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_ARMORBALANCING, OnUpdateToolsArmorBalancing)
|
|
ON_COMMAND(ID_TOOLS_PLACEWITHMAP, OnToolsPlacewithmap)
|
|
ON_COMMAND(ID_TOOLS_DISPERSECULTURALWITHBITMAP, OnToolsDisperseculturalwithbitmap)
|
|
ON_COMMAND(ID_TOOLS_REMOVECULTURALS, OnToolsRemoveculturals)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CMW4GameEdApp construction
|
|
|
|
|
|
CMW4GameEdApp::CMW4GameEdApp() :
|
|
culturalList(NULL),
|
|
undoChain(NULL),
|
|
dirtyGameModelResources(NULL)
|
|
{
|
|
displayWindow = NULL;
|
|
overviewWindow = NULL;
|
|
resourceWindow = NULL;
|
|
briefingWnd = NULL;
|
|
didIdle = false;
|
|
cameraFollowing = CAMERA_FOLLOW_GROUND;
|
|
m_VideoResolution = 640;
|
|
m_VersionString = VER_PRODUCTVERSION_STR;
|
|
m_AutoBackupOnSave = false;
|
|
|
|
m_WaitCursor = NULL;
|
|
m_AllLoaded = false;
|
|
m_MechLabActive = false;
|
|
m_showTileBorder = false;
|
|
|
|
m_NumObjectives = 0;
|
|
|
|
lightDlg = NULL;
|
|
fogDlg = NULL;
|
|
|
|
memset((void *) m_4DCameraBookmark, 0, sizeof(m_4DCameraBookmark)) ;
|
|
|
|
//
|
|
// Initialize to where Enemy is in the list (constant right now)
|
|
// can be changed to a fixed location if necessary, but make sure
|
|
// that it is not set above LastAlignment value since that could
|
|
// cause an array out of bounds later on where used.
|
|
//
|
|
m_nDefaultAlignmentForPlacedObjects = (Entity::LastAlignment >= 2) ? 2 /*enemy*/ : 0;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CMW4GameEdApp::~CMW4GameEdApp()
|
|
{
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// The one and only CMW4GameEdApp object
|
|
|
|
CMW4GameEdApp theApp;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CMW4GameEdApp initialization
|
|
|
|
bool g_ScreenSaverFlag;
|
|
|
|
BOOL CMW4GameEdApp::InitInstance()
|
|
{
|
|
// CG: The following block was added by the Splash Screen component.
|
|
\
|
|
{
|
|
\
|
|
CCommandLineInfo cmdInfo;
|
|
\
|
|
ParseCommandLine(cmdInfo);
|
|
\
|
|
|
|
\
|
|
CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
|
|
\
|
|
}
|
|
// Standard initialization
|
|
// If you are not using these features and wish to reduce the size
|
|
// of your final executable, you should remove from the following
|
|
// the specific initialization routines you do not need.
|
|
|
|
#ifdef _AFXDLL
|
|
Enable3dControls(); // Call this when using MFC in a shared DLL
|
|
#else
|
|
Enable3dControlsStatic(); // Call this when linking to MFC statically
|
|
#endif
|
|
|
|
{
|
|
CString mutexstr;
|
|
mutexstr.LoadString(AFX_IDS_APP_TITLE);
|
|
CreateMutex(NULL,TRUE,mutexstr);
|
|
if(ERROR_ALREADY_EXISTS==GetLastError())
|
|
{
|
|
MessageBox(NULL,"Another Instance of this Application is Currently Running","Error...",MB_OK);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
__try
|
|
{
|
|
// Change the registry key under which our settings are stored.
|
|
// TODO: You should modify this string to be something appropriate
|
|
// such as the name of your company or organization.
|
|
SetRegistryKey(_T("MechWarrior4 Mission Editor"));
|
|
|
|
|
|
// Turn off the screen saver
|
|
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE,0,&g_ScreenSaverFlag,FALSE);
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,FALSE,NULL,FALSE);
|
|
|
|
|
|
// To create the main window, this code creates a new frame window
|
|
// object and then sets it as the application's main window object.
|
|
|
|
m_ScriptName = "";
|
|
CMDIFrameWnd* pFrame = new CMainFrame;
|
|
m_pMainWnd = pFrame;
|
|
|
|
// create main MDI frame window
|
|
if (!pFrame->LoadFrame(IDR_MAINFRAME))
|
|
return FALSE;
|
|
/*
|
|
CTitleWnd* m_TitleWnd = new CTitleWnd;
|
|
m_TitleWnd->Invalidate();
|
|
*/
|
|
// try to load shared MDI menus and accelerator table
|
|
//TODO: add additional member variables and load calls for
|
|
// additional menu types your application may need.
|
|
|
|
HINSTANCE hInst = AfxGetResourceHandle();
|
|
m_hMDIMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_MW4GAMTYPE));
|
|
m_hMDIAccel = ::LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_MW4GAMTYPE));
|
|
|
|
// Enable and disable the tools menu items instead of the root menu
|
|
// CMenu* m = theApp.m_pMainWnd->GetMenu();
|
|
// m->EnableMenuItem(3,MF_GRAYED | MF_BYPOSITION);
|
|
|
|
displayWindow = new CDisplayWindow;
|
|
ASSERT(displayWindow != NULL);
|
|
|
|
overviewWindow = new COverviewWindow;
|
|
ASSERT(overviewWindow != NULL);
|
|
|
|
InitGameOS(m_hInstance,displayWindow->m_hWnd,m_lpCmdLine);
|
|
|
|
_getcwd(Working_Directory, 128);
|
|
|
|
resourceWindow = new CResourceWindow;
|
|
ASSERT(resourceWindow != NULL);
|
|
|
|
instanceWindow = new CInstanceWindow;
|
|
ASSERT(instanceWindow != NULL);
|
|
|
|
gridOn = false;
|
|
gridValue = 15;
|
|
|
|
m_MultiDrop = true;
|
|
|
|
// The main window has been initialized, so show and update it.
|
|
pFrame->ShowWindow(m_nCmdShow);
|
|
pFrame->UpdateWindow();
|
|
toolBar->EnableButton(ID_EDIT_UNDO,FALSE);
|
|
toolBar->EnableButton(ID_FILE_SAVE,FALSE);
|
|
|
|
OnToolsCameraheightMechheight10m();
|
|
OnToolsCameraspeedRegular();
|
|
|
|
LoadWindowStates();
|
|
m_editorState = NoGameIdleState;
|
|
CSelectionList::Instance = new CSelectionList();
|
|
currentCommand = NULL;
|
|
displayWindow->timer = displayWindow->SetTimer(1, 100, NULL);
|
|
|
|
char Path[MAX_PATH];
|
|
strcpy(Path,"Content\\Editor\\bMech.ani");
|
|
// theApp.m_WaitCursor = LoadCursorFromFile(Path);
|
|
|
|
FILE* file;
|
|
if ((file = fopen("Content\\Editor\\Autotrack.data","r")) == NULL)
|
|
{
|
|
nextDamageFileID = 0;
|
|
nextSubsystemFileID = 0;
|
|
}
|
|
else
|
|
{
|
|
char buffer[32];
|
|
|
|
fgets(buffer,31,file);
|
|
nextDamageFileID = atoi(buffer);
|
|
fgets(buffer,31,file);
|
|
nextSubsystemFileID = atoi(buffer);
|
|
fclose(file);
|
|
}
|
|
|
|
extern bool g_MMInitialized;
|
|
g_MMInitialized = 0;
|
|
// delete m_TitleWnd;
|
|
g_MMInitialized = 1;
|
|
}
|
|
__except(ProcessException(GetExceptionInformation()))
|
|
{
|
|
}
|
|
|
|
ElementRenderer::Element::UseCallbackSet(ElementRenderer::Element::Callbacks);
|
|
|
|
sprintf(m_title,"MechWarrior4 Mission Editor - Version: %s - []",VER_PRODUCTVERSION_STR);
|
|
m_pMainWnd->SetWindowText(m_title);
|
|
|
|
m_AllLoaded = true;
|
|
|
|
// CG: This line inserted by 'Tip of the Day' component.
|
|
ShowTipAtStartup();
|
|
// Compost::TerrainTextureLogistic::SetResolution(0);
|
|
return TRUE;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CMW4GameEdApp message handlers
|
|
|
|
int CMW4GameEdApp::ExitInstance()
|
|
{
|
|
|
|
if (lightDlg)
|
|
{
|
|
Unregister_Pointer(lightDlg);
|
|
delete lightDlg;
|
|
lightDlg = NULL;
|
|
}
|
|
if (fogDlg)
|
|
{
|
|
Unregister_Pointer(fogDlg);
|
|
delete fogDlg;
|
|
fogDlg = NULL;
|
|
}
|
|
|
|
m_ExtraDataList.SetLength(0);
|
|
missionBoundary.SetLength(0);
|
|
warningBoundary.SetLength(0);
|
|
if(!undoChain.IsEmpty())
|
|
{
|
|
ChainIteratorOf<Command *> iterator(&undoChain);
|
|
iterator.DeletePlugs();
|
|
}
|
|
|
|
|
|
if(!dirtyGameModelResources.IsEmpty())
|
|
{
|
|
ChainIteratorOf<PlugOf<Resource*>*> iterator(&dirtyGameModelResources);
|
|
iterator.DeletePlugs();
|
|
}
|
|
|
|
// if (m_WaitCursor)
|
|
// DestroyCursor(m_WaitCursor);
|
|
|
|
TerminateGameEngine();
|
|
|
|
|
|
// turn Screen saver back on
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,g_ScreenSaverFlag,NULL,FALSE);
|
|
|
|
return CWinApp::ExitInstance();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnFileNew()
|
|
{
|
|
StopMultiPlace();
|
|
|
|
CNewMissionDlg dlg;
|
|
dlg.DoModal();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CAboutDlg dialog used for App About
|
|
|
|
class CAboutDlg : public CDialog
|
|
{
|
|
public:
|
|
CAboutDlg();
|
|
|
|
// Dialog Data
|
|
//{{AFX_DATA(CAboutDlg)
|
|
enum { IDD = IDD_ABOUTBOX };
|
|
CStatic m_VersionString;
|
|
//}}AFX_DATA
|
|
|
|
// ClassWizard generated virtual function overrides
|
|
//{{AFX_VIRTUAL(CAboutDlg)
|
|
public:
|
|
virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult);
|
|
protected:
|
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
|
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
|
//}}AFX_VIRTUAL
|
|
|
|
// Implementation
|
|
protected:
|
|
//{{AFX_MSG(CAboutDlg)
|
|
virtual BOOL OnInitDialog();
|
|
//}}AFX_MSG
|
|
DECLARE_MESSAGE_MAP()
|
|
};
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CAboutDlg)
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CAboutDlg)
|
|
DDX_Control(pDX, IDC_ABOUTVERSIONSTRING, m_VersionString);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CAboutDlg)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// App command to run the dialog
|
|
void
|
|
CMW4GameEdApp::OnAppAbout()
|
|
{
|
|
CAboutDlg aboutDlg;
|
|
aboutDlg.DoModal();
|
|
}
|
|
|
|
extern bool Immediate_Draw;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void _stdcall InitializeGameEngine()
|
|
{
|
|
//
|
|
//---------------------
|
|
// Initialize libraries
|
|
//---------------------
|
|
//
|
|
Stuff::ArmorLevel = 4;
|
|
|
|
// client=gos_CreateMemoryHeap("MFCHeap");
|
|
// gos_PushCurrentHeap(client);
|
|
|
|
Stuff::InitializeClasses();
|
|
MidLevelRenderer::InitializeClasses(NULL, 8192*16);
|
|
Compost::InitializeClasses();
|
|
gosFX::InitializeClasses();
|
|
ElementRenderer::InitializeClasses();
|
|
Adept::InitializeClasses();
|
|
Map::LoadRadius = 8;
|
|
MechWarrior4::InitializeClasses();
|
|
MW4GameEdApplication::InitializeClass();
|
|
EditorWaypoint::InitializeClass();
|
|
EditorLatticeNode::InitializeClass();
|
|
EditorPathNode::InitializeClass();
|
|
EditorBoundaryNode::InitializeClass();
|
|
EditorDropNode::InitializeClass();
|
|
EditorDropZonePoint::InitializeClass();
|
|
EditorObjectiveMarker::InitializeClass();
|
|
EditorMovementPath::InitializeClass();
|
|
EditorLight::InitializeClass();
|
|
EditorAmbientLight::InitializeClass();
|
|
EditorInfiniteLight::InitializeClass();
|
|
EditorPointLight::InitializeClass();
|
|
EditorSpotLight::InitializeClass();
|
|
EditorCameraShip::InitializeClass();
|
|
//
|
|
//----------------------------------------------------------
|
|
// Parse command line and verify that game name has been set
|
|
//----------------------------------------------------------
|
|
//
|
|
Immediate_Draw=false;
|
|
|
|
//
|
|
//------------------------------------------------
|
|
// If no path is provided, set the path to Content
|
|
//------------------------------------------------
|
|
//
|
|
|
|
#ifdef _DEBUG
|
|
#undef new
|
|
#endif
|
|
|
|
|
|
MString game_name;
|
|
MString game_file_name;
|
|
|
|
|
|
|
|
Tool::Instance = new MWTool();
|
|
Check_Object(Tool::Instance);
|
|
MW4GameEdApplication *MW4GameEd_Application = new MW4GameEdApplication;
|
|
Check_Object(MW4GameEd_Application);
|
|
Adept::Application::Instance = MW4GameEd_Application;
|
|
MW4GameEd_Application->Initialize();
|
|
|
|
|
|
// Let's do a resource check so we can handle anomolies in a friendly way.
|
|
|
|
// MW4GameEd_Application->OpenResources(false, true);
|
|
// MW4GameEd_Application->BuildEffectsLibrary("Content\\Effects\\mw.effects");
|
|
SetCurrentDirectory(Working_Directory);
|
|
Stuff::NotationFile build_script("Content\\MechWarrior4.build");
|
|
FileDependencies deps;
|
|
gos_PushCurrentHeap(gosFX::Heap);
|
|
gosFX::EffectLibrary::Instance = new ResourceEffectLibrary;
|
|
gos_PopCurrentHeap();
|
|
Tool::Instance->BuildResources(&build_script, VER_CONTENTVERSION, &deps);
|
|
delete gosFX::EffectLibrary::Instance;
|
|
Verify(!gosFX::EffectLibrary::Instance = NULL);
|
|
|
|
Verify(!Network::Instance);
|
|
Network::Instance = new Network;
|
|
Check_Object(Network::Instance);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void _stdcall TerminateGameEngine()
|
|
{
|
|
Check_Pointer(FileStreamManager::Instance);
|
|
FileStreamManager::Instance->PurgeFileCompareCache();
|
|
|
|
Check_Object(Adept::Application::Instance);
|
|
Adept::Application::Instance->StopGame();
|
|
// Adept::Application::Instance->CloseGame();
|
|
Adept::Application::Instance->Terminate();
|
|
Check_Object(Adept::Application::Instance);
|
|
delete Adept::Application::Instance;
|
|
Adept::Application::Instance = NULL;
|
|
|
|
//
|
|
//------------------------------------------------------
|
|
// If we are shutting down a tool run, kill off the tool
|
|
//------------------------------------------------------
|
|
//
|
|
if (Tool::Instance)
|
|
{
|
|
Check_Object(Tool::Instance);
|
|
delete Tool::Instance;
|
|
}
|
|
|
|
EditorCameraShip::TerminateClass();
|
|
EditorSpotLight::TerminateClass();
|
|
EditorPointLight::TerminateClass();
|
|
EditorInfiniteLight::TerminateClass();
|
|
EditorAmbientLight::TerminateClass();
|
|
EditorLight::TerminateClass();
|
|
EditorMovementPath::TerminateClass();
|
|
EditorObjectiveMarker::TerminateClass();
|
|
EditorDropZonePoint::TerminateClass();
|
|
EditorDropNode::TerminateClass();
|
|
EditorBoundaryNode::TerminateClass();
|
|
EditorPathNode::TerminateClass();
|
|
EditorLatticeNode::TerminateClass();
|
|
EditorWaypoint::TerminateClass();
|
|
|
|
MW4GameEdApplication::TerminateClass();
|
|
MechWarrior4::TerminateClasses();
|
|
Adept::TerminateClasses();
|
|
ElementRenderer::TerminateClasses();
|
|
gosFX::TerminateClasses();
|
|
MidLevelRenderer::TerminateClasses();
|
|
Stuff::TerminateClasses();
|
|
|
|
// gos_PopCurrentHeap();
|
|
// gos_DestroyMemoryHeap(client);
|
|
ExitGameOS();
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
// Setup the GameOS structure
|
|
//
|
|
void __stdcall GetGameOSEnvironment(char* CommandLine)
|
|
{
|
|
Command_Line = CommandLine;
|
|
|
|
Environment.applicationName = "MW4GameEd";
|
|
Environment.directoryPath = "code\\MW4GameEd;Binaries\\MW4";
|
|
Environment.screenWidth = 640;
|
|
Environment.screenHeight = 480;
|
|
Environment.fullScreen = FALSE;
|
|
Environment.bitDepth = 16;
|
|
Environment.debugLog = "DebugLog.txt";
|
|
Environment.spew = "GameOS_Memory"; //GROUP_ADEPT_RESOURCE;
|
|
Environment.memoryTraceLevel = 10;
|
|
Environment.TimeStampSpew = false;
|
|
Environment.DoGameLogic = &MWApplication::DoGameLogic;
|
|
Environment.UpdateRenderers = &Application::UpdateDisplay;
|
|
Environment.InitializeGameEngine = InitializeGameEngine;
|
|
Environment.TerminateGameEngine = TerminateGameEngine;
|
|
|
|
Environment.Key_FullScreen = 0;
|
|
Environment.Key_SwitchMonitors = 0; //KEY_F5;
|
|
Environment.Key_Exit = 0;
|
|
|
|
Environment.Renderer = 0;
|
|
Environment.FullScreenDevice = 0;
|
|
|
|
Environment.AntiAlias = 0; // true/false - Enable full screen antialiasing
|
|
Environment.NetworkGame = false;
|
|
Environment.NetworkMaxPlayers = 2;
|
|
|
|
Environment.Texture_S_256 = 13;
|
|
Environment.Texture_S_128 = 12;
|
|
Environment.Texture_S_64 = 1;
|
|
Environment.Texture_S_32 = 1;
|
|
Environment.Texture_S_16 = 1;
|
|
|
|
Environment.Texture_K_256 = 1;
|
|
Environment.Texture_K_128 = 1;
|
|
Environment.Texture_K_64 = 1;
|
|
Environment.Texture_K_32 = 1;
|
|
Environment.Texture_K_16 = 1;
|
|
|
|
Environment.Texture_A_256 = 1;
|
|
Environment.Texture_A_128 = 1;
|
|
Environment.Texture_A_64 = 1;
|
|
Environment.Texture_A_32 = 1;
|
|
Environment.Texture_A_16 = 1;
|
|
|
|
Environment.soundChannels = 32;
|
|
Environment.soundDisable = true;
|
|
Environment.soundHiFi = false;
|
|
|
|
Environment.MaxTimeDelta = 0.25f;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnToggleOverviewWindow()
|
|
{
|
|
|
|
if (overviewWindow)
|
|
overviewWindow->ToggleVisible();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnToggleResourceWindow()
|
|
{
|
|
if (resourceWindow)
|
|
resourceWindow->ToggleVisible();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnViewDisplaywindow()
|
|
{
|
|
if (displayWindow)
|
|
displayWindow->ToggleVisible();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnViewInstancewindow()
|
|
{
|
|
if (instanceWindow)
|
|
instanceWindow->ToggleVisible();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BOOL CMW4GameEdApp::OnIdle(LONG lCount)
|
|
{
|
|
|
|
__try
|
|
{
|
|
if (theApp.m_editorState != CMW4GameEdApp::NoGameIdleState)
|
|
{
|
|
if(RunGameOSLogic())
|
|
PostQuitMessage(0);
|
|
}
|
|
}
|
|
__except(ProcessException(GetExceptionInformation()))
|
|
{}
|
|
|
|
didIdle = true;
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BOOL CAboutDlg::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult)
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
|
|
return CDialog::OnChildNotify(message, wParam, lParam, pLResult);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BOOL CAboutDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
|
|
return CDialog::OnNotify(wParam, lParam, pResult);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnEditUndo()
|
|
{
|
|
StopMultiPlace();
|
|
//We need to undo the last thing on the chain!
|
|
if(!undoChain.IsEmpty())
|
|
{
|
|
ChainIteratorOf<Command *>iterator(&undoChain);
|
|
iterator.Last();
|
|
Command *command;
|
|
command = iterator.GetCurrent();
|
|
command->Undo();
|
|
|
|
undoChain.Remove(command);
|
|
Check_Object(command);
|
|
delete command;
|
|
}
|
|
if(undoChain.IsEmpty())
|
|
{
|
|
theApp.toolBar->EnableButton(ID_EDIT_UNDO, FALSE);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool CMW4GameEdApp::CreateNewScenario(char* missionName, char* mapPath, char* skyPath)
|
|
{
|
|
CString missionInstance;
|
|
CString missionPath = "Content\\Missions\\";
|
|
missionPath += missionName;
|
|
|
|
CString map_name=mapPath;
|
|
map_name=map_name.Left(map_name.ReverseFind('.'));
|
|
map_name=map_name.Mid(map_name.ReverseFind('\\')+1);
|
|
|
|
AddToBuildFile(missionName,map_name);
|
|
|
|
CString srcablname,destablname;
|
|
missionPath += "\\";
|
|
destablname = missionPath;
|
|
destablname += "player.abl";
|
|
missionPath += missionName;
|
|
missionInstance = missionPath + ".instance";
|
|
|
|
|
|
srcablname = "content\\ablscripts\\player.abl";
|
|
if (CopyFile (srcablname,destablname,FALSE) == 0)
|
|
{
|
|
MessageBox (NULL,"Failed to create default player.abl file. You will need to create your own for this mission","New Mission Error",MB_OK);
|
|
}
|
|
|
|
|
|
lightFileName = missionPath;
|
|
lightFileName += ".Lights";
|
|
|
|
audioFileName = missionPath;
|
|
audioFileName += ".audio";
|
|
|
|
CloseHandle(CreateFile(LPCTSTR(lightFileName),0,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,NULL));
|
|
CloseHandle(CreateFile(LPCTSTR(audioFileName),0,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,NULL));
|
|
|
|
// m_ExtraDataList.SetLength(0); // Tom: should this be cleared too?
|
|
missionBoundary.SetLength(0);
|
|
warningBoundary.SetLength(0);
|
|
|
|
CreateMissionInstanceFile(missionInstance.GetBuffer(MAX_PATH),mapPath,skyPath,true);
|
|
|
|
CString missionData = missionPath + ".data";
|
|
SaveMissionDataFile(missionData.GetBuffer(MAX_PATH));
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// Make the mission contents file
|
|
|
|
CString contentData = missionPath + ".contents";
|
|
|
|
{
|
|
NotationFile contentFile;
|
|
contentFile.SaveAs(contentData.GetBuffer(MAX_PATH));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// Make the mission audio file
|
|
//
|
|
// Leave empty for now
|
|
//
|
|
//CString audioData = missionPath + ".audio";
|
|
//
|
|
// {
|
|
// NotationFile audioFile;
|
|
// audioFile.AddPage("Audio");
|
|
// audioFile.SaveAs(audioData.GetBuffer(MAX_PATH));
|
|
// }
|
|
|
|
/*
|
|
Resource instanceResource(missionInstance);
|
|
ReplicatorID baseID = ReplicatorID::Null;
|
|
DynamicMemoryStream instanceStream;
|
|
Check_Object(Tool::Instance);
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&instanceStream,
|
|
missionInstance,
|
|
&baseID
|
|
);
|
|
instanceResource.Save(&instanceStream,NULL);
|
|
|
|
MissionNamePlug* newMissionName = new MissionNamePlug;
|
|
newMissionName->name = new char[strlen(missionName) + 1];
|
|
strcpy(newMissionName->name,missionName);
|
|
*/
|
|
// CreateMissionResource(missionInstance.GetBuffer(MAX_PATH));
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// Make the mission movement graph
|
|
|
|
return true;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::CreateMissionResource(char* missionInstance)
|
|
{
|
|
Resource instance_resource(missionInstance);
|
|
// ReplicatorID baseID = ReplicatorID::Null;
|
|
DynamicMemoryStream instance_stream;
|
|
// Check_Object(Tool::Instance);
|
|
NotationFile instance_file(missionInstance);
|
|
FileDependencies *parent = Resource::ParentFileDependencies;
|
|
FileDependencies instance_deps(*instance_file.GetFileDependencies());
|
|
Resource::ParentFileDependencies = &instance_deps;
|
|
Check_Object(Mission::Instance);
|
|
Mission::Instance->SaveMakeMessage(&instance_stream, NULL);
|
|
// Tool::Instance->ConstructCreateMessage(
|
|
// &instanceStream,
|
|
// &instance_file,
|
|
// &baseID
|
|
// );
|
|
instance_resource.Save(&instance_stream, &instance_deps);
|
|
|
|
char missionName[MAX_PATH],tmp[MAX_PATH];
|
|
_splitpath(missionInstance,tmp,tmp,missionName,tmp);
|
|
|
|
MissionNamePlug* newMissionName = new MissionNamePlug;
|
|
newMissionName->name = new char[strlen(missionName) + 1];
|
|
strcpy(newMissionName->name,missionName);
|
|
Resource::ParentFileDependencies = parent;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool CMW4GameEdApp::CreateMissionInstanceFile(char* missionPath, char* mapPath, char* skyPath, bool create_new)
|
|
{
|
|
char missionName[MAX_PATH],tmpString[MAX_PATH],tmpString2[MAX_PATH],tmpString3[MAX_PATH],tmpString4[MAX_PATH],tmpString5[MAX_PATH],*p;
|
|
|
|
if (!TestFileWrite(missionPath))
|
|
return false;
|
|
|
|
_splitpath(missionPath,tmpString,tmpString,missionName,tmpString);
|
|
|
|
NotationFile missionFile;
|
|
Page *mission_page = missionFile.AddPage(missionName);
|
|
Check_Object(mission_page);
|
|
|
|
sprintf(tmpString,"%s.data",missionName);
|
|
mission_page->AppendEntry("Model",tmpString);
|
|
mission_page->AppendEntry("Map",strstr(mapPath,"Maps"));
|
|
sprintf(tmpString,"%s.contents",missionName);
|
|
mission_page->AppendEntry("Props",tmpString);
|
|
mission_page->AppendEntry("ExecutionState","AlwaysExecuteState");
|
|
|
|
mission_page->AppendEntry("MissionBounds","Mission.bounds");
|
|
mission_page->AppendEntry("WarningBounds","Warning.bounds");
|
|
|
|
|
|
FileStream bnds;
|
|
CString mpath,str;
|
|
mpath=missionPath;
|
|
mpath=mpath.Left(mpath.ReverseFind('\\'));
|
|
|
|
int i;
|
|
if(Map::Instance)
|
|
{
|
|
for (i = 0; i < theApp.missionBoundary.GetLength(); i++)
|
|
{
|
|
theApp.missionBoundary[i].x+=theApp.overviewWindow->mapWidth*0.5f;
|
|
theApp.missionBoundary[i].y+=theApp.overviewWindow->mapHeight*0.5f;
|
|
theApp.missionBoundary[i].x *= Map::Instance->GetColumnZoneScale();
|
|
theApp.missionBoundary[i].y *= Map::Instance->GetRowZoneScale();
|
|
}
|
|
|
|
for ( i = 0; i < theApp.warningBoundary.GetLength(); i++)
|
|
{
|
|
Vector2DOf<Scalar> origin;
|
|
theApp.warningBoundary[i].x+=theApp.overviewWindow->mapWidth*0.5f;
|
|
theApp.warningBoundary[i].y+=theApp.overviewWindow->mapHeight*0.5f;
|
|
theApp.warningBoundary[i].x *= Map::Instance->GetColumnZoneScale();
|
|
theApp.warningBoundary[i].y *= Map::Instance->GetRowZoneScale();
|
|
}
|
|
|
|
Mission::Instance->SetMissionPolygon(theApp.missionBoundary);
|
|
Mission::Instance->SetWarningPolygon(theApp.warningBoundary);
|
|
}
|
|
|
|
str.Format("%s\\Mission.bounds",mpath);
|
|
bnds.Open((LPCSTR)str,FileStream::WriteOnly);
|
|
MemoryStreamIO_Write(&bnds, &theApp.missionBoundary);
|
|
bnds.Close();
|
|
|
|
str.Format("%s\\Warning.bounds",mpath);
|
|
bnds.Open((LPCSTR)str,FileStream::WriteOnly);
|
|
MemoryStreamIO_Write(&bnds, &theApp.warningBoundary);
|
|
bnds.Close();
|
|
|
|
if(Map::Instance)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
char tmpPath[MAX_PATH],tmpName[MAX_PATH];
|
|
strcpy(tmpPath,missionPath);
|
|
|
|
if (!m_ScriptName.IsEmpty ())
|
|
{
|
|
mission_page->AppendEntry("Script",(LPCTSTR) m_ScriptName);
|
|
}
|
|
|
|
CString table_name=missionName;
|
|
table_name+=".table";
|
|
mission_page->AppendEntry("NameTable",(char *)(LPCSTR)table_name);
|
|
|
|
if(create_new)
|
|
{
|
|
// create empty nametable file so we can load
|
|
CString table_path;
|
|
table_path.Format("Content\\Missions\\%s\\%s",missionName,table_name);
|
|
FILE* newfile = fopen((LPCSTR)table_path,"w");
|
|
ASSERT(newfile != NULL);
|
|
fclose(newfile);
|
|
}
|
|
|
|
p = __mbsrchr(tmpPath,'\\');
|
|
p++;
|
|
*p = 0;
|
|
strcpy(tmpString,tmpPath);
|
|
p = strstr(tmpString,"mission");
|
|
if (p)
|
|
{
|
|
*p = 0;
|
|
p = __mbsrchr(tmpString,'\\');
|
|
p++;
|
|
sprintf(tmpString2,"%s%sGraph.data",tmpPath,p);
|
|
sprintf(tmpString3,"%s%sMoveGrid.data",tmpPath,p);
|
|
sprintf(tmpString4,"%s%sRectGrid.data",tmpPath,p);
|
|
sprintf(tmpString5,"%s%sAirMoveGrid.data",tmpPath,p);
|
|
}
|
|
else
|
|
{
|
|
p = __mbsrchr(tmpPath,'\\');
|
|
*p = 0;
|
|
p = __mbsrchr(tmpPath,'\\');
|
|
p++;
|
|
strcpy(tmpName,p);
|
|
sprintf(tmpString2,"%s%sGraph.data",tmpString,tmpName);
|
|
sprintf(tmpString3,"%s%sMoveGrid.data",tmpString,tmpName);
|
|
sprintf(tmpString4,"%s%sRectGrid.data",tmpString,tmpName);
|
|
sprintf(tmpString5,"%s%sAirMoveGrid.data",tmpString,tmpName);
|
|
p = NULL;
|
|
}
|
|
m_graphName = tmpString2;
|
|
m_moveGridName = tmpString3;
|
|
m_rectGridName = tmpString4;
|
|
m_airMoveGridName = tmpString5;
|
|
mission_page->AppendEntry("RailGraph",m_graphName);
|
|
|
|
strcpy(tmpPath,tmpString2);
|
|
p = strstr(tmpPath,"Graph");
|
|
*p = 0;
|
|
|
|
_finddata_t fileData;
|
|
if (_findfirst(m_graphName,&fileData) == -1) // create missiongraph file.
|
|
{
|
|
int i = 0;
|
|
|
|
NotationFile graphFile;
|
|
Page *graph_page = graphFile.AddPage("Graph");
|
|
Check_Object(graph_page);
|
|
graph_page->AppendEntry("NumNodes",i);
|
|
graph_page->AppendEntry("NumLinks",i);
|
|
graphFile.SaveAs((LPCTSTR)m_graphName);
|
|
}
|
|
|
|
if (skyPath && strlen(skyPath))
|
|
{
|
|
p = strstr(skyPath,"Content");
|
|
if (!p) // Did they put the erf in the wrong place? Handle it.
|
|
p = skyPath;
|
|
mission_page->AppendEntry("Sky",p);
|
|
}
|
|
|
|
missionFile.SaveAs(missionPath);
|
|
return true;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnAdjustGrid()
|
|
{
|
|
CGenericTextDlg dlg;
|
|
char string[64];
|
|
|
|
dlg.m_Title = "Construction Grid Resolution";
|
|
dlg.m_MessageText = "Enter the grid size for the construction grid";
|
|
dlg.m_EditText = itoa(theApp.gridValue,string,10);
|
|
dlg.addStyle = ES_NUMBER;
|
|
|
|
dlg.editRect.left = 10;
|
|
dlg.editRect.right = 60;
|
|
|
|
if (dlg.DoModal() == IDOK)
|
|
{
|
|
int val = atoi(dlg.m_EditText);
|
|
|
|
if (val < 1)
|
|
MessageBox(NULL,"Invalid entry","Error",MB_ICONSTOP);
|
|
else if (theApp.gridValue != val)
|
|
{
|
|
theApp.gridValue = val;
|
|
((CMainFrame*)(theApp.m_pMainWnd))->DestroyGridData();
|
|
if (theApp.gridOn)
|
|
((CMainFrame*)(theApp.m_pMainWnd))->CreateGridData();
|
|
}
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int CMW4GameEdApp::Run()
|
|
{
|
|
__try
|
|
{
|
|
return CWinApp::Run();
|
|
|
|
}
|
|
__except(ProcessException(GetExceptionInformation()))
|
|
{
|
|
}
|
|
return 0;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnFileOpen()
|
|
{
|
|
StopMultiPlace();
|
|
SetCurrentDirectory(Working_Directory);
|
|
CFileDlg dlg;
|
|
if (dlg.DoModal() == IDOK)
|
|
{
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
|
|
if (theApp.m_editorState != CMW4GameEdApp::NoGameIdleState)
|
|
{
|
|
OnFileClose();
|
|
}
|
|
OpenFile(dlg.GetPathName());
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OpenFile(char* filename)
|
|
{
|
|
// SetCursor(theApp.m_WaitCursor);
|
|
|
|
RECT rect;
|
|
int w = 280, h = 130;
|
|
|
|
theApp.m_pMainWnd->GetWindowRect(&rect);
|
|
CMsgDlg msgDlg("Loading...","Arial",240,theApp.m_pMainWnd,
|
|
(rect.right - rect.left) / 2 + rect.left - w / 2,(rect.bottom - rect.top) / 2 + rect.top - h / 2,w,h);
|
|
msgDlg.ShowWindow(SW_SHOW);
|
|
msgDlg.UpdateWindow();
|
|
|
|
|
|
Check_Object(ResourceManager::Instance);
|
|
delete ResourceManager::Instance;
|
|
ResourceManager::Instance = new ResourceManager;
|
|
Check_Object(ResourceManager::Instance);
|
|
|
|
if(gosFX::EffectLibrary::Instance)
|
|
{
|
|
delete gosFX::EffectLibrary::Instance;
|
|
Verify(!gosFX::EffectLibrary::Instance);
|
|
}
|
|
gos_PushCurrentHeap(gosFX::Heap);
|
|
gosFX::EffectLibrary::Instance = new ResourceEffectLibrary;
|
|
gos_PopCurrentHeap();
|
|
SetCurrentDirectory(Working_Directory);
|
|
Stuff::NotationFile build_script("Content\\MechWarrior4.build");
|
|
FileDependencies deps;
|
|
Tool::Instance->BuildResources(&build_script, VER_CONTENTVERSION, &deps);
|
|
delete gosFX::EffectLibrary::Instance;
|
|
Verify(!gosFX::EffectLibrary::Instance);
|
|
|
|
Check_Object(Application::Instance);
|
|
missionFileName = filename;
|
|
const char *game_name;
|
|
if((game_name = strstr(missionFileName.GetBuffer(MAX_PATH), "Content")) != NULL)
|
|
{
|
|
memmove((void*)(LPCTSTR(missionFileName)),game_name,strlen(game_name) + 1);
|
|
//
|
|
//----------------------------------------------------------
|
|
// Go ahead and put the load mission message into the stream
|
|
//----------------------------------------------------------
|
|
//
|
|
#ifdef _DEBUG
|
|
#undef new
|
|
#endif
|
|
|
|
//
|
|
//----------------------------------------------------------
|
|
// Request our mech
|
|
//----------------------------------------------------------
|
|
//
|
|
DynamicMemoryStream request_vehicle_stream;
|
|
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// Open up the resource files we are going to need to construct the player
|
|
// message
|
|
//------------------------------------------------------------------------
|
|
//
|
|
|
|
{
|
|
|
|
|
|
|
|
bool custom = false;
|
|
request_vehicle_stream.WriteBytes(&custom, 1);
|
|
int file_id = 0;
|
|
int record_id = 0;
|
|
request_vehicle_stream.WriteBytes(&file_id, 4);
|
|
request_vehicle_stream.WriteBytes(&record_id, 4);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
//
|
|
//----------------------------------------
|
|
// Now, create the message for the mission
|
|
//----------------------------------------
|
|
//
|
|
|
|
MWApplication::Instance->SetMissionName(missionFileName);
|
|
|
|
|
|
//
|
|
//-------------------------------------------------------------
|
|
// We've requested our mech so we are ready
|
|
// right now there is no double checking on the mech
|
|
// status. In the future we will send this and
|
|
// wait for a reply before we send a ready message
|
|
//-------------------------------------------------------------
|
|
//
|
|
|
|
request_vehicle_stream.Rewind();
|
|
|
|
|
|
MWApplication::Instance->RequestPlayerVehicleMessageHandler(Connection::Server->GetID(), &request_vehicle_stream);
|
|
MWApplication::Instance->ReadyToLaunchMessageHandler(Connection::Server->GetID(), NULL);
|
|
|
|
|
|
// request our mech...
|
|
//Network::Instance->SendNetMessage(Connection::Server->GetID(), MWApplication::RequestPlayerVehicleMessageID, &request_vehicle_stream, true);
|
|
|
|
// technically we should wait for the server to accept our mech, but for right now it doesn't check anyway so
|
|
// we just launch it...
|
|
//Network::Instance->SendNetMessage(Connection::Server->GetID(), MWApplication::ReadyToLaunchMessageID, NULL, true);
|
|
|
|
|
|
//
|
|
//----------------------------------------
|
|
// Time to launch the game
|
|
//----------------------------------------
|
|
//
|
|
MWApplication::Instance->LaunchGame();
|
|
|
|
|
|
|
|
RouteLocalPacketsTask route_task;
|
|
while (Network::Instance->RouteLocalPacket())
|
|
{
|
|
}
|
|
|
|
|
|
m_editorState = SelectingObjectState;
|
|
Check_Object(EntityManager::Instance);
|
|
EntityManager::Instance->SuspendExecution();
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity* entity;
|
|
|
|
CString game_base_path(game_name),contents_path;
|
|
game_base_path=game_base_path.Left(game_base_path.ReverseFind('.'));
|
|
contents_path=game_base_path+".contents";
|
|
Stuff::NotationFile contentsfile((LPCSTR)contents_path);
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(NavPoint::DefaultData))
|
|
{
|
|
NavPoint*node = Cast_Object(NavPoint*,entity);
|
|
node->SetToDisplay();
|
|
|
|
}
|
|
|
|
if(entity->GetPropType() == Entity::MapPropType)
|
|
{
|
|
EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
|
|
theApp.resourceWindow->numEntitiesAdded++;
|
|
Page *page = contentsfile.FindPage((char*)entity->instanceName);
|
|
if(page)
|
|
{
|
|
CEditorEntityData *exdata=theApp.GetEntityData(entity);
|
|
page->GetEntry("EDVOffset",&(exdata->VOffset));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
STOP(("You are not giving a game file in a correct content location"));
|
|
}
|
|
CString str,tmps;
|
|
str="MechWarrior 4 Editor Version - ";
|
|
tmps=VER_PRODUCTVERSION_STR;
|
|
str+=tmps;
|
|
m_pMainWnd->SetWindowText(str);
|
|
MakeObjectsTileBased();
|
|
NameTable::Instance->IsValid();
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnUpdateViewOverviewwindow(CCmdUI* pCmdUI)
|
|
{
|
|
if (overviewWindow)
|
|
pCmdUI->SetCheck(overviewWindow->IsWindowVisible());
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnUpdateViewResourcewindow(CCmdUI* pCmdUI)
|
|
{
|
|
if (resourceWindow)
|
|
pCmdUI->SetCheck(resourceWindow->IsWindowVisible());
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnUpdateViewDisplaywindow(CCmdUI* pCmdUI)
|
|
{
|
|
if (displayWindow)
|
|
pCmdUI->SetCheck(displayWindow->IsWindowVisible());
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnUpdateViewInstancewindow(CCmdUI* pCmdUI)
|
|
{
|
|
if (instanceWindow)
|
|
pCmdUI->SetCheck(instanceWindow->IsWindowVisible());
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::SaveWindowStates()
|
|
{
|
|
CString keyname;
|
|
keyname = "MUGEMainWnd_Placement";
|
|
WINDOWPLACEMENT wp;
|
|
theApp.m_pMainWnd->GetWindowPlacement(&wp);
|
|
gos_SaveDataToRegistry((char *)(LPCSTR)keyname,&wp,sizeof(wp));
|
|
|
|
displayWindow->SaveState();
|
|
overviewWindow->SaveState();
|
|
resourceWindow->SaveState();
|
|
instanceWindow->SaveState();
|
|
|
|
keyname = "MUGEBackupStatus";
|
|
gos_SaveDataToRegistry((char *)(LPCSTR)keyname,&m_AutoBackupOnSave,sizeof(m_AutoBackupOnSave));
|
|
|
|
keyname = "MUGECameraSpeed";
|
|
gos_SaveDataToRegistry((char *)(LPCSTR)keyname,&cameraSpeed,sizeof(cameraSpeed));
|
|
|
|
keyname = "MUGECameraFollowing";
|
|
gos_SaveDataToRegistry((char *)(LPCSTR)keyname,&cameraFollowing,sizeof(cameraFollowing));
|
|
|
|
keyname = "MUGECameraBookmarks";
|
|
gos_SaveDataToRegistry((char *)(LPCSTR)keyname,&m_4DCameraBookmark,sizeof(m_4DCameraBookmark));
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::LoadWindowStates()
|
|
{
|
|
CString keyname;
|
|
keyname = "MUGEMainWnd_Placement";
|
|
|
|
WINDOWPLACEMENT wp;
|
|
DWORD size=sizeof(wp);
|
|
gos_LoadDataFromRegistry((char *)(LPCSTR)keyname,&wp,&size);
|
|
if (size == sizeof(wp))
|
|
{
|
|
theApp.m_pMainWnd->SetWindowPlacement(&wp);
|
|
}
|
|
|
|
displayWindow->LoadState();
|
|
overviewWindow->LoadState();
|
|
resourceWindow->LoadState();
|
|
instanceWindow->LoadState();
|
|
|
|
RECT r;
|
|
displayWindow->GetClientRect(&r);
|
|
if (r.right < 790)
|
|
OnViewResize640();
|
|
else if (r.right < 1142)
|
|
OnViewResize800();
|
|
else if (r.right < 1270)
|
|
OnViewResize1152();
|
|
else if (r.right < 1590)
|
|
OnViewResize1280();
|
|
else
|
|
OnViewResize1600();
|
|
|
|
keyname = "MUGEBackupStatus";
|
|
size=sizeof(m_AutoBackupOnSave);
|
|
gos_LoadDataFromRegistry((char *)(LPCSTR)keyname,&m_AutoBackupOnSave,&size);
|
|
|
|
keyname = "MUGECameraSpeed";
|
|
size=sizeof(cameraSpeed);
|
|
gos_LoadDataFromRegistry((char *)(LPCSTR)keyname,&cameraSpeed,&size);
|
|
|
|
keyname = "MUGECameraFollowing";
|
|
size=sizeof(cameraFollowing);
|
|
gos_LoadDataFromRegistry((char *)(LPCSTR)keyname,&cameraFollowing,&size);
|
|
|
|
keyname = "MUGECameraBookmarks";
|
|
size=sizeof(cameraFollowing);
|
|
gos_LoadDataFromRegistry((char *)(LPCSTR)keyname,&m_4DCameraBookmark,&size);
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void RecursiveCopy(char* srcDir, char* destDir, char* oldName, char* newName)
|
|
{
|
|
WIN32_FIND_DATA filedata;
|
|
HANDLE handle;
|
|
char oldFolder[MAX_PATH],tmp1[MAX_PATH],tmp2[MAX_PATH],newFilename[MAX_PATH],*p;
|
|
|
|
GetCurrentDirectory(MAX_PATH - 1,oldFolder);
|
|
CreateDirectory(destDir,NULL);
|
|
SetCurrentDirectory(srcDir);
|
|
|
|
handle = FindFirstFile("*.*",&filedata);
|
|
|
|
do
|
|
{
|
|
if (!strcmp(filedata.cFileName,".") || !strcmp(filedata.cFileName,".."))
|
|
continue;
|
|
|
|
if (filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
char recurseDest[MAX_PATH];
|
|
sprintf(recurseDest,"%s\\%s",destDir,filedata.cFileName);
|
|
RecursiveCopy(filedata.cFileName,recurseDest,oldName,newName);
|
|
}
|
|
|
|
strcpy(tmp1,filedata.cFileName);
|
|
p = strstr(strlwr(tmp1),strlwr(oldName));
|
|
|
|
if (p)
|
|
{
|
|
*p = 0;
|
|
p += strlen(oldName);
|
|
sprintf(tmp2,"%s%s%s",tmp1,newName,p);
|
|
}
|
|
else
|
|
{
|
|
strcpy(tmp2,filedata.cFileName);
|
|
}
|
|
|
|
sprintf(newFilename,"%s\\%s",destDir,tmp2);
|
|
CopyFile(filedata.cFileName,newFilename,FALSE);
|
|
if (filedata.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
|
SetFileAttributes(newFilename,filedata.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
|
|
|
|
// let's replace any occurances of the mission name inside the file
|
|
p = strrchr(newFilename,'.') + 1;
|
|
if (strcmp(strlwr(p),"data") == 0 || // make sure it's a notation file we want to edit
|
|
strcmp(strlwr(p),"instance") == 0)
|
|
{
|
|
NotationFile notFile(newFilename);
|
|
|
|
NotationFile::PageIterator *pageList = notFile.MakePageIterator();
|
|
Check_Object(pageList);
|
|
Page *page;
|
|
|
|
while ((page = pageList->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(page);
|
|
Page::NoteIterator *entryList = page->MakeNoteIterator();
|
|
Check_Object(entryList);
|
|
// PAUSE(("Not alphabetized..."));
|
|
// entryList = notFile.MakeAlphaEntryList(page->GetName());
|
|
|
|
Note *entry;
|
|
|
|
while ((entry = entryList->ReadAndNext()) != NULL)
|
|
{
|
|
const char* entryString;
|
|
entry->GetEntry(&entryString);
|
|
//
|
|
// There seem to be some empty entry strings in the mission that break this
|
|
//
|
|
if (entryString)
|
|
{
|
|
p = strstr(strlwr((char*)entryString),strlwr(oldName));
|
|
|
|
if (p)
|
|
{
|
|
char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
|
|
|
|
_splitpath(entryString,drive,dir,fname,ext);
|
|
|
|
if (strlen(dir) == 0) // no path we need to change the filename
|
|
{
|
|
*p = 0;
|
|
p += strlen(oldName);
|
|
sprintf(tmp2,"%s%s%s",entryString,newName,p);
|
|
entry->SetEntry(tmp2);
|
|
}
|
|
else if (strstr(dir,"missions")) // have to change the path too
|
|
{
|
|
*p = 0;
|
|
p += strlen(oldName) * 2 + 1; // major hack!!! should be very temporary
|
|
sprintf(tmp2,"%s%s\\%s%s",entryString,newName,newName,p);
|
|
entry->SetEntry(tmp2);
|
|
}
|
|
} // if (p)
|
|
} // if (entryString)
|
|
} // while
|
|
Check_Object(entryList);
|
|
delete entryList;
|
|
}
|
|
|
|
Check_Object(pageList);
|
|
delete pageList;
|
|
notFile.Save();
|
|
}
|
|
}
|
|
while (FindNextFile(handle,&filedata));
|
|
|
|
SetCurrentDirectory(oldFolder);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::OnFileSaveAs()
|
|
{
|
|
StopMultiPlace();
|
|
RemoveCulturals();
|
|
|
|
if (!m_MissionSaved)
|
|
{
|
|
if (MessageBox(NULL,"Mission has not been saved. Save now?","Unsaved Data",MB_YESNO) == IDYES) // localize
|
|
{
|
|
OnFileSave();
|
|
}
|
|
}
|
|
|
|
Start_Save_As:;
|
|
|
|
CGenericTextDlg dlg;
|
|
|
|
dlg.m_Title = "Save As";
|
|
dlg.m_MessageText = "Enter the new name of the mission";
|
|
dlg.m_EditText = "";
|
|
|
|
if (dlg.DoModal() == IDCANCEL)
|
|
return;
|
|
|
|
CString mres,mis_name;
|
|
mis_name=dlg.m_EditText;
|
|
mres.Format("Content\\Resources\\Missions\\%s.mw4",dlg.m_EditText);
|
|
if(gos_DoesFileExist(mres))
|
|
{
|
|
MessageBox(NULL,"A mission with that name already exists. Please rename the mission.","Save As Error",MB_OK); // Localize
|
|
goto Start_Save_As;
|
|
}
|
|
|
|
char newMissionPath[MAX_PATH],oldMissionName[MAX_PATH];
|
|
const char* mapPath, *cskyPath;
|
|
|
|
_splitpath(missionFileName,newMissionPath,newMissionPath,oldMissionName,newMissionPath);
|
|
sprintf(newMissionPath,"Content\\Missions\\%s",dlg.m_EditText);
|
|
|
|
if (_mkdir(newMissionPath) != 0)
|
|
{
|
|
MessageBox(NULL,"Unable to create new folder","Save Error",MB_OK); // Localize
|
|
return;
|
|
}
|
|
|
|
|
|
// Copy over everything
|
|
char tmpPath[MAX_PATH],oldFolder[MAX_PATH];
|
|
_getcwd(oldFolder,MAX_PATH - 1);
|
|
sprintf(tmpPath,"Content\\Missions\\%s",oldMissionName);
|
|
_chdir(tmpPath);
|
|
|
|
sprintf(newMissionPath,"..\\%s",dlg.m_EditText);
|
|
|
|
RecursiveCopy(tmpPath,newMissionPath,oldMissionName,dlg.m_EditText.GetBuffer(MAX_PATH));
|
|
|
|
_chdir(oldFolder);
|
|
// Build the rest of the files
|
|
sprintf(newMissionPath,"Content\\Missions\\%s\\%s",dlg.m_EditText,dlg.m_EditText);
|
|
|
|
char tmpString[MAX_PATH],tmpString2[MAX_PATH],tmpString3[MAX_PATH],tmpName[MAX_PATH];
|
|
strcpy(tmpPath,newMissionPath);
|
|
|
|
char *p = __mbsrchr(tmpPath,'\\');
|
|
p++;
|
|
*p = 0;
|
|
strcpy(tmpString,tmpPath);
|
|
p = strstr(tmpString,"mission");
|
|
if (p) // for bullshit with mission in the title
|
|
{
|
|
*p = 0;
|
|
p = __mbsrchr(tmpString,'\\');
|
|
p++;
|
|
sprintf(tmpString2,"%s%sGraph.data",tmpPath,p);
|
|
sprintf(tmpString3,"%s%sMoveGrid.data",tmpPath,p);
|
|
}
|
|
else
|
|
{
|
|
p = __mbsrchr(tmpPath,'\\');
|
|
*p = 0;
|
|
p = __mbsrchr(tmpPath,'\\');
|
|
p++;
|
|
strcpy(tmpName,p);
|
|
sprintf(tmpString2,"%s%sGraph.data",tmpString,tmpName);
|
|
sprintf(tmpString3,"%s%sMoveGrid.data",tmpString,tmpName);
|
|
p = NULL;
|
|
}
|
|
m_graphName = tmpString2;
|
|
m_moveGridName = tmpString3;
|
|
lightFileName = tmpString;
|
|
lightFileName += tmpName;
|
|
lightFileName += ".Lights";
|
|
|
|
audioFileName = tmpString;
|
|
audioFileName += tmpName;
|
|
audioFileName += ".audio";
|
|
|
|
|
|
|
|
CString filename = newMissionPath;
|
|
filename += ".data";
|
|
|
|
SaveMissionDataFile(filename.GetBuffer(MAX_PATH));
|
|
|
|
filename = newMissionPath;
|
|
filename += ".lights";
|
|
SaveLightFile(filename.GetBuffer(MAX_PATH));
|
|
|
|
filename= newMissionPath;
|
|
filename += ".audio";
|
|
SaveAudioFile(filename.GetBuffer(MAX_PATH));
|
|
|
|
CString map_name;
|
|
|
|
{
|
|
NotationFile notFile(missionFileName.GetBuffer(MAX_PATH));
|
|
char skyPath[MAX_PATH];
|
|
|
|
Page *old_mission_page = notFile.GetPage(oldMissionName);
|
|
Check_Object(old_mission_page);
|
|
|
|
old_mission_page->GetEntry("Map",&mapPath);
|
|
if (old_mission_page->GetEntry("Sky",&cskyPath))
|
|
strcpy(skyPath,(char*)cskyPath);
|
|
else
|
|
skyPath[0] = 0;
|
|
|
|
map_name=mapPath;
|
|
filename = newMissionPath;
|
|
filename += ".instance";
|
|
CreateMissionInstanceFile(filename.GetBuffer(MAX_PATH),(char*)mapPath,skyPath,false);
|
|
}
|
|
|
|
// Append resource.build file
|
|
map_name=map_name.Left(map_name.ReverseFind('.'));
|
|
map_name=map_name.Mid(map_name.ReverseFind('\\')+1);
|
|
|
|
AddToBuildFile(dlg.m_EditText,map_name);
|
|
|
|
filename = newMissionPath;
|
|
filename += ".contents";
|
|
SaveMissionContentsFile(filename.GetBuffer(MAX_PATH));
|
|
|
|
// CreateMissionResource(filename.GetBuffer(MAX_PATH));
|
|
|
|
//
|
|
//----------------------
|
|
// Stop the current game
|
|
//----------------------
|
|
//
|
|
MWApplication::Instance->StopGame();
|
|
Verify(!Network::Instance);
|
|
Network::Instance = new Network;
|
|
Check_Object(Network::Instance);
|
|
|
|
|
|
OnFileClose();
|
|
filename = newMissionPath;
|
|
filename += ".instance";
|
|
OpenFile(filename.GetBuffer(MAX_PATH));
|
|
|
|
m_MissionSaved = true;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool CMW4GameEdApp::SaveMissionDataFile(char* missionData)
|
|
{
|
|
if (!TestFileWrite(missionData))
|
|
return false;
|
|
|
|
NotationFile dataFile(missionData);
|
|
|
|
if (Mission::Instance)
|
|
{
|
|
Resource gameModelResource;
|
|
|
|
Entity::GetGameModelResourceFromDataListID(&gameModelResource,Mission::Instance->GetDataListResourceID());
|
|
Entity__GameModel *model = Cast_Pointer(Entity__GameModel*,gameModelResource.GetPointer());
|
|
|
|
Entity::ClassID class_id = Entity::GetClassIDFromDataListID(Mission::Instance->GetDataListResourceID());
|
|
Entity__ClassData* class_data = (Entity__ClassData*)Entity::FindClassData(class_id);
|
|
|
|
(*class_data->modelSaveToText)(model,&dataFile);
|
|
|
|
Page *page = dataFile.SetPage("GameData");
|
|
Check_Object(page);
|
|
page->SetEntry("Lights",LPCTSTR(lightFileName));
|
|
|
|
Page * page2 = dataFile.SetPage("Renderers");
|
|
Check_Object(page2);
|
|
page2->SetEntry("AudioRenderer", LPCTSTR(audioFileName));
|
|
|
|
}
|
|
else
|
|
{
|
|
dataFile.DeleteAllPages();
|
|
dataFile.AddPage("GameData");
|
|
|
|
Page *page = dataFile.SetPage("GameData");
|
|
Check_Object(page);
|
|
page->AppendEntry("Class","MechWarrior4::MWMission");
|
|
page->AppendEntry("Cull",LPCTSTR(m_MissionData.m_Cull));
|
|
page->AppendEntry("Fog","yes");
|
|
char tmpString[64];
|
|
sprintf(tmpString,"%f %f %f",m_MissionData.m_FogColor[0],m_MissionData.m_FogColor[1],m_MissionData.m_FogColor[2]);
|
|
page->AppendEntry("FogColor",tmpString);
|
|
page->AppendEntry("Lights",LPCTSTR(lightFileName));
|
|
|
|
Page * page2 = dataFile.SetPage("Renderers");
|
|
Check_Object(page2);
|
|
page2->SetEntry("AudioRenderer", LPCTSTR(audioFileName));
|
|
}
|
|
|
|
WriteDirtyGameModels();
|
|
dataFile.Save();
|
|
|
|
return true;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::WriteDirtyGameModels()
|
|
{
|
|
Resource* resource,gameModelResource;
|
|
ResourceID resourceID;
|
|
|
|
// Hack to make sure we're not in content directory for creating notFile
|
|
// Things get yucky if it can't file includes
|
|
char oldDir[MAX_PATH];
|
|
_getcwd(oldDir,MAX_PATH - 1);
|
|
if (strstr(oldDir,"Content"))
|
|
chdir("..");
|
|
|
|
ChainIteratorOf<PlugOf<Resource*>*> iterator(&dirtyGameModelResources);
|
|
PlugOf<Resource*> *plug;
|
|
while ((plug = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
resource = (Resource*) plug->GetItem();
|
|
{
|
|
resourceID = resource->GetResourceID();
|
|
Entity::GetGameModelResourceFromDataListID(&gameModelResource,resourceID);
|
|
|
|
Entity__GameModel *model = Cast_Pointer(Entity__GameModel*,gameModelResource.GetPointer());
|
|
|
|
Entity::ClassID class_id = Entity::GetClassIDFromDataListID(resourceID);
|
|
Entity__ClassData* class_data = (Entity__ClassData*)Entity::FindClassData(class_id);
|
|
|
|
char tmp[MAX_PATH],filename[MAX_PATH];
|
|
strcpy(tmp,gameModelResource.GetName());
|
|
char* p = strrchr(tmp,'{');
|
|
*p = 0;
|
|
sprintf(filename,"Content\\%s",tmp);
|
|
|
|
while (GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY)
|
|
{
|
|
char string[MAX_PATH];
|
|
sprintf(string,"%s is marked READONLY.",filename);
|
|
if (MessageBox(NULL,string,"File Error",MB_RETRYCANCEL) == IDCANCEL)
|
|
return;
|
|
}
|
|
|
|
NotationFile notFile(filename);
|
|
|
|
class_data->modelSaveToText(model, ¬File);
|
|
|
|
#if 0
|
|
ModelAttributeEntry *attribute_entry;
|
|
TableIteratorOf<ModelAttributeEntry *, Entity__GameModel::AttributeID> iterator(
|
|
&class_data->gameModelAttributeTable.attributesByID);
|
|
int num_attributes = iterator.GetSize();
|
|
int i;
|
|
|
|
for(i=Entity__GameModel::AnyAttributeID + 1;i<num_attributes;i++)
|
|
{
|
|
attribute_entry =
|
|
class_data->gameModelAttributeTable.GetAttributeEntry(i);
|
|
|
|
Check_Object(attribute_entry);
|
|
|
|
char* data = new char [Entity__GameModel::MaxStringLength];
|
|
Register_Pointer(data);
|
|
|
|
class_data->modelWriteToText(model, attribute_entry, &data);
|
|
|
|
notFile->SetEntry("GameData",attribute_entry->attributeName,data);
|
|
|
|
Unregister_Pointer(data);
|
|
delete [] data;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
iterator.DeletePlugs();
|
|
|
|
chdir(oldDir);
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool CMW4GameEdApp::SaveMissionContentsFile(char *prop_name)
|
|
{
|
|
Check_Pointer(prop_name);
|
|
if (!TestFileWrite(prop_name))
|
|
return false;
|
|
|
|
MakeObjectNamesUnique();
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
NotationFile notation_file(prop_name);
|
|
notation_file.DeleteAllPages();
|
|
|
|
iterator.First();
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
// bool modified;
|
|
|
|
if (entity->IsDerivedFrom(MechWarrior4::Path::DefaultData))
|
|
{
|
|
Page *page = notation_file.AddPage((char*)entity->instanceName);
|
|
Check_Object(page);
|
|
|
|
page->AppendEntry("Model","Misc\\Path.data");
|
|
page->AppendEntry("ExecutionState","NeverExecuteState");
|
|
page->AppendEntry("CollisionCallback","false");
|
|
page->AppendEntry("CollideeType","Zone");
|
|
page->AppendEntry("CollisionMask",-1);
|
|
|
|
char pathFilename[MAX_PATH],tmpString[MAX_PATH],*p;
|
|
strcpy(tmpString,prop_name);
|
|
p = __mbsrchr(tmpString,'\\');
|
|
p++; *p = 0;
|
|
sprintf(pathFilename, "%s%s\\", tmpString, "Paths");
|
|
gos_CreateDirectory(pathFilename);
|
|
sprintf(pathFilename,"%s%s\\%s.contents",tmpString,"Paths", (char*)entity->instanceName);
|
|
|
|
page->AppendEntry("PathPoints",pathFilename);
|
|
|
|
NotationFile path_notation_file;
|
|
|
|
page = path_notation_file.AddPage("Path");
|
|
|
|
Point3D point;
|
|
MechWarrior4::Path* path;
|
|
path = Cast_Object(MechWarrior4::Path*,entity);
|
|
|
|
for (int i = 0; i < path->pathPoints.size(); i++)
|
|
{
|
|
sprintf(tmpString,"Point%d",i + 1);
|
|
point = path->pathPoints[i];
|
|
page->AppendEntry(tmpString,point);
|
|
}
|
|
path_notation_file.SaveAs(pathFilename);
|
|
}
|
|
else if(entity->IsDerivedFrom(DropZone::DefaultData))
|
|
{
|
|
Page *page = notation_file.AddPage((char*)entity->instanceName);
|
|
Check_Object(page);
|
|
|
|
page->AppendEntry("Model","Misc\\DropZone.data");
|
|
page->AppendEntry("ExecutionState","NeverExecuteState");
|
|
page->AppendEntry("TileBound","false");
|
|
Point3D local_translation(entity->GetLocalToParent());
|
|
page->SetEntry("Translation", local_translation);
|
|
YawPitchRoll rotation_value(entity->GetLocalToParent());
|
|
page->SetEntry("Rotation", rotation_value);
|
|
const char *alignment_text;
|
|
alignment_text = Entity::AlignmentAsciiToText(entity->alignment);
|
|
page->SetEntry("Alignment", alignment_text);
|
|
|
|
|
|
char pathFilename[MAX_PATH],tmpString[MAX_PATH],*p;
|
|
strcpy(tmpString,prop_name);
|
|
p = __mbsrchr(tmpString,'\\');
|
|
p++; *p = 0;
|
|
sprintf(pathFilename, "%s%s\\", tmpString, "DropZones");
|
|
gos_CreateDirectory(pathFilename);
|
|
sprintf(pathFilename,"%s%s\\%s.contents",tmpString,"DropZones", (char*)entity->instanceName);
|
|
|
|
page->AppendEntry("DropPoints",pathFilename);
|
|
|
|
NotationFile drop_notation_file;
|
|
|
|
Page *drop_page = drop_notation_file.AddPage("DropPoints");
|
|
Page *rot_page = drop_notation_file.AddPage("DropRots");
|
|
|
|
Point3D point;
|
|
YawPitchRoll rot;
|
|
LinearMatrix4D mat;
|
|
Adept::DropZone* drop;
|
|
drop = Cast_Object(Adept::DropZone*,entity);
|
|
|
|
ChainIteratorOf<Adept::DropZone::MatrixPlug *> iterator(&drop->dropMats);
|
|
Adept::DropZone::MatrixPlug *drop_point;
|
|
char entry_name[256];
|
|
int count = 1;
|
|
while((drop_point = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(drop_point);
|
|
sprintf(entry_name, "Point%d", count);
|
|
mat = drop_point->GetItem ();
|
|
point = (Point3D) mat;
|
|
rot = (YawPitchRoll) mat;
|
|
drop_page->AppendEntry(entry_name, point);
|
|
sprintf(entry_name, "Rot%d", count);
|
|
rot_page->AppendEntry(entry_name, rot);
|
|
count++;
|
|
}
|
|
drop_notation_file.SaveAs(pathFilename);
|
|
|
|
}
|
|
else if (entity->GetPropType() == Entity::MissionPropType &&
|
|
!entity->IsDerivedFrom(AI::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorWaypoint::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorPathNode::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorMovementPath::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorLatticeNode::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorBoundaryNode::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorDropNode::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorDropZonePoint::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorLight::DefaultData) &&
|
|
!entity->IsDerivedFrom(EditorCameraShip::DefaultData))
|
|
{
|
|
Page *page = notation_file.AddPage((char*)entity->instanceName);
|
|
Check_Object(page);
|
|
|
|
entity->SaveInstanceText(page);
|
|
|
|
CEditorEntityData *exdata;
|
|
exdata=theApp.GetEntityData(entity);
|
|
|
|
if(exdata)
|
|
{
|
|
page->SetEntry("EDVOffset",exdata->VOffset);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
// all AI Drivers must go last & waypoints go in different file
|
|
|
|
MWMap *inst;
|
|
AI *ai;
|
|
inst = Cast_Object (MWMap *,Map::Instance);
|
|
ChainIteratorOf<AI *> iterator2(&inst->m_executingAIs);
|
|
iterator2.First ();
|
|
while((ai = iterator2.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(ai);
|
|
// bool modified;
|
|
|
|
if (!ai->IsDerivedFrom (PlayerAI::DefaultData))
|
|
{
|
|
Page *page = notation_file.AddPage((char*)ai->instanceName);
|
|
Check_Object(page);
|
|
ai->SaveInstanceText(page);
|
|
// Write out Editor only Data
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
//----------------------
|
|
//Save off the NameTable
|
|
//----------------------
|
|
//
|
|
MString table_name = prop_name;
|
|
table_name.StripExtension();
|
|
table_name += ".table";
|
|
|
|
{
|
|
|
|
NotationFile table_file(table_name);
|
|
|
|
|
|
Check_Object(NameTable::Instance);
|
|
//
|
|
// BUGBUG:: This will clear the current contents of the file and overwrite it
|
|
// with the data in this structure. We shouldn't have to do this, but if the old
|
|
// data is kept around, items aren't being removed from the file. The name table module would have
|
|
// to be rewritten to work with the new NotationFile code that allows you to modify the
|
|
// existing data if we don't want to completely overwrite the file.
|
|
//
|
|
//
|
|
table_file.DeleteAllPages();
|
|
|
|
NameTable::Instance->IsValid();
|
|
NameTable::Instance->SaveTable(&table_file);
|
|
table_file.Save();
|
|
}
|
|
|
|
//
|
|
//------------------
|
|
//Save the RailGraph
|
|
//------------------
|
|
//
|
|
char railString[MAX_PATH],tmp[MAX_PATH],*p;
|
|
strcpy(tmp,prop_name);
|
|
p = __mbsrchr(tmp,'\\') + 1;
|
|
*p = 0;
|
|
sprintf(railString,"%s",m_graphName);
|
|
|
|
NotationFile railgraph_file(railString);
|
|
Check_Object(NameTable::Instance);
|
|
MW4AI::g_MissionGraph->DumpNotationFile (&railgraph_file,(LPCTSTR) m_moveGridName,(LPCTSTR) m_rectGridName,(LPCTSTR) m_airMoveGridName);
|
|
railgraph_file.Save();
|
|
|
|
notation_file.Save();
|
|
|
|
return true;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraheightGround()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_GROUND,MF_BYCOMMAND | MF_CHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_MECHHEIGHT10M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_TWICEMECHHEIGHT20M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_FOURTIMESMECHHEIGHT40M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
cameraHeight = 1.65f;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraheightMechheight10m()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_GROUND,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_MECHHEIGHT10M,MF_BYCOMMAND | MF_CHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_TWICEMECHHEIGHT20M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_FOURTIMESMECHHEIGHT40M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_USERDEFINED,MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
cameraHeight = 10;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraheightTwicemechheight20m()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_GROUND,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_MECHHEIGHT10M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_TWICEMECHHEIGHT20M,MF_BYCOMMAND | MF_CHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_FOURTIMESMECHHEIGHT40M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_USERDEFINED,MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
cameraHeight = 40;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraheightFourtimesmechheight40m()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_GROUND,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_MECHHEIGHT10M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_TWICEMECHHEIGHT20M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_FOURTIMESMECHHEIGHT40M,MF_BYCOMMAND | MF_CHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_USERDEFINED,MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
cameraHeight = 80;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraheightUserdefined()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_GROUND,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_MECHHEIGHT10M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_TWICEMECHHEIGHT20M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_FOURTIMESMECHHEIGHT40M,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERAHEIGHT_USERDEFINED,MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
CGenericTextDlg dlg;
|
|
char string[64];
|
|
|
|
dlg.m_Title = "User Defined Camera Height";
|
|
dlg.m_MessageText = "Enter the height above the terrain you would like to set the camera.";
|
|
dlg.m_EditText = itoa(int(cameraHeight),string,10);
|
|
dlg.addStyle = ES_NUMBER;
|
|
|
|
dlg.editRect.left = 10;
|
|
dlg.editRect.right = 60;
|
|
|
|
dlg.DoModal();
|
|
|
|
cameraHeight = float(atof(dlg.m_EditText));
|
|
if (cameraHeight < 1.0f)
|
|
cameraHeight = 1.0f;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraspeedSlow()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_SLOW,MF_BYCOMMAND | MF_CHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_REGULAR,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_FAST,MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
cameraSpeed = 1;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraspeedRegular()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_SLOW,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_REGULAR,MF_BYCOMMAND | MF_CHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_FAST,MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
cameraSpeed = 4;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCameraspeedFast()
|
|
{
|
|
CMenu* menu = m_pMainWnd->GetMenu();
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_SLOW,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_REGULAR,MF_BYCOMMAND | MF_UNCHECKED);
|
|
menu->GetSubMenu(APP_MENU_TOOLS)->CheckMenuItem(ID_TOOLS_CAMERASPEED_FAST,MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
cameraSpeed = 16;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsBriefingfile()
|
|
{
|
|
StopMultiPlace();
|
|
if(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState)
|
|
{
|
|
if (!briefingWnd)
|
|
{
|
|
briefingWnd = new CEditWnd(briefingPath.GetBuffer(MAX_PATH));
|
|
RECT r;
|
|
r.left = 50;
|
|
r.top = 50;
|
|
r.right = 350;
|
|
r.bottom = 250;
|
|
briefingWnd->Create(NULL,"Mission Briefing",WS_VISIBLE,r);
|
|
}
|
|
else
|
|
briefingWnd->ShowWindow(SW_SHOW);
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OnFileSave()
|
|
{
|
|
StopMultiPlace();
|
|
Check_Object(Mission::Instance);
|
|
MakeObjectsTileBased();
|
|
RemoveCulturals();
|
|
|
|
if(!missionFileName.IsEmpty())
|
|
{
|
|
RECT rect;
|
|
int w = 280, h = 130;
|
|
|
|
theApp.m_pMainWnd->GetWindowRect(&rect);
|
|
CMsgDlg msgDlg("Saving...","Arial",240,theApp.m_pMainWnd,
|
|
(rect.right - rect.left) / 2 + rect.left - w / 2,(rect.bottom - rect.top) / 2 + rect.top - h / 2,w,h);
|
|
msgDlg.ShowWindow(SW_SHOW);
|
|
msgDlg.UpdateWindow();
|
|
|
|
// Should we backup the files first?
|
|
|
|
if (theApp.m_AutoBackupOnSave)
|
|
{
|
|
char srcPath[MAX_PATH],destPath[MAX_PATH],oldPath[MAX_PATH],srcFile[MAX_PATH],destFile[MAX_PATH],*p;
|
|
strcpy(srcPath,missionFileName.GetBuffer(MAX_PATH - 1));
|
|
p = __mbsrchr(srcPath,'\\');
|
|
*p = 0;
|
|
strcpy(destPath,srcPath);
|
|
strcat(destPath,"\\Backup");
|
|
|
|
_getcwd(oldPath,MAX_PATH - 1);
|
|
if (_chdir(destPath) != 0) // = 0 if successful, !0 if failed
|
|
{
|
|
if (_mkdir(destPath) != 0)
|
|
{
|
|
MessageBox(NULL,"Unable to create backup directory","Save Error",MB_OK);
|
|
return;
|
|
}
|
|
}
|
|
_chdir(oldPath);
|
|
|
|
sprintf(srcFile,"%s\\*.*",srcPath);
|
|
|
|
struct _finddata_t fileinfo;
|
|
long handle = _findfirst(srcFile,&fileinfo);
|
|
if (handle != -1)
|
|
{
|
|
do
|
|
{
|
|
if (fileinfo.attrib & _A_SUBDIR)
|
|
continue;
|
|
|
|
sprintf(srcFile,"%s\\%s",srcPath,fileinfo.name);
|
|
sprintf(destFile,"%s\\%s",destPath,fileinfo.name);
|
|
CopyFile(srcFile,destFile,FALSE);
|
|
}
|
|
while (_findnext(handle,&fileinfo) == 0);
|
|
}
|
|
}
|
|
const char* cmapPath, *cskyPath;
|
|
|
|
char missionContentPath[MAX_PATH],missionName[MAX_PATH],mapPath[MAX_PATH],skyPath[MAX_PATH],*p;
|
|
strcpy(missionContentPath,missionFileName.GetBuffer(MAX_PATH - 1));
|
|
|
|
p = __mbsrchr(missionContentPath,'\\');
|
|
p++;
|
|
strcpy(missionName,p);
|
|
p = __mbsrchr(missionName,'.');
|
|
*p = 0;
|
|
|
|
p = __mbsrchr(missionContentPath,'.');
|
|
|
|
sprintf(p,".instance");
|
|
|
|
NotationFile notFile(missionContentPath);
|
|
Page *mission_page = notFile.GetPage(missionName);
|
|
Check_Object(mission_page);
|
|
mission_page->GetEntry("Map",&cmapPath,true);
|
|
if (mission_page->GetEntry("Sky",&cskyPath))
|
|
strcpy(skyPath,(char*)cskyPath);
|
|
else
|
|
skyPath[0] = 0;
|
|
|
|
strcpy(mapPath,(char*)cmapPath);
|
|
|
|
if (!CreateMissionInstanceFile(missionContentPath,(char*)mapPath,(char*)skyPath,false))
|
|
return;
|
|
|
|
sprintf(p,".contents");
|
|
if (!SaveMissionContentsFile(missionContentPath))
|
|
return;
|
|
|
|
char missionData[MAX_PATH];
|
|
_splitpath(missionFileName,missionData,missionData,missionName,missionData);
|
|
sprintf(missionData,"Content\\Missions\\%s\\%s.data",missionName,missionName);
|
|
SaveMissionDataFile(missionData);
|
|
SaveLightFile();
|
|
SaveAudioFile(); // doesn't do anything yet.
|
|
|
|
// CreateMissionResource(missionFileName.GetBuffer(MAX_PATH));
|
|
}
|
|
else
|
|
OnFileSaveAs();
|
|
|
|
m_MissionSaved = true;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCamerafollowingGround()
|
|
{
|
|
if (cameraFollowing == CAMERA_FOLLOW_NONE)
|
|
{
|
|
cameraFollowing = CAMERA_FOLLOW_GROUND;
|
|
cameraHeight -= displayWindow->GetMapPointVertical();
|
|
}
|
|
cameraFollowing = CAMERA_FOLLOW_GROUND;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsCamerafollowingGround(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(cameraFollowing == CAMERA_FOLLOW_GROUND);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCamerafollowingHighestpoint()
|
|
{
|
|
if (cameraFollowing == CAMERA_FOLLOW_NONE)
|
|
{
|
|
// there is a special case if the camera is inside an object.
|
|
|
|
cameraFollowing = CAMERA_FOLLOW_HIGHESTPOINT;
|
|
cameraHeight -= displayWindow->GetMapPointVertical();
|
|
}
|
|
cameraFollowing = CAMERA_FOLLOW_HIGHESTPOINT;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsCamerafollowingHighestpoint(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(cameraFollowing == CAMERA_FOLLOW_HIGHESTPOINT);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCamerafollowingNone()
|
|
{
|
|
cameraHeight += displayWindow->GetMapPointVertical();
|
|
cameraFollowing = CAMERA_FOLLOW_NONE;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsCamerafollowingNone(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(cameraFollowing == CAMERA_FOLLOW_NONE);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
BOOL CAboutDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
m_VersionString.SetWindowText(LPCTSTR(theApp.m_VersionString)); // temporary version hack
|
|
|
|
// CG: Following block was added by System Info Component.
|
|
{
|
|
CString strFreeDiskSpace;
|
|
CString strFreeMemory;
|
|
CString strFmt;
|
|
|
|
// Fill available memory
|
|
MEMORYSTATUS MemStat;
|
|
MemStat.dwLength = sizeof(MEMORYSTATUS);
|
|
GlobalMemoryStatus(&MemStat);
|
|
strFmt.LoadString(CG_IDS_PHYSICAL_MEM);
|
|
strFreeMemory.Format(strFmt, MemStat.dwTotalPhys / 1024L);
|
|
|
|
//TODO: Add a static control to your About Box to receive the memory
|
|
// information. Initialize the control with code like this:
|
|
SetDlgItemText(IDC_PHYSICAL_MEM, strFreeMemory);
|
|
|
|
// Fill disk free information
|
|
struct _diskfree_t diskfree;
|
|
int nDrive = _getdrive(); // use current default drive
|
|
if (_getdiskfree(nDrive, &diskfree) == 0)
|
|
{
|
|
strFmt.LoadString(CG_IDS_DISK_SPACE);
|
|
strFreeDiskSpace.Format(strFmt,
|
|
(DWORD)diskfree.avail_clusters *
|
|
(DWORD)diskfree.sectors_per_cluster *
|
|
(DWORD)diskfree.bytes_per_sector / (DWORD)1024L,
|
|
nDrive-1 + _T('A'));
|
|
}
|
|
else
|
|
strFreeDiskSpace.LoadString(CG_IDS_DISK_SPACE_UNAVAIL);
|
|
|
|
//TODO: Add a static control to your About Box to receive the memory
|
|
// information. Initialize the control with code like this:
|
|
SetDlgItemText(IDC_DISK_SPACE, strFreeDiskSpace);
|
|
}
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CMW4GameEdApp::OnViewResize640()
|
|
{
|
|
gos_SetScreenMode(640,480);
|
|
RunGameOSLogic();
|
|
m_VideoResolution = 640;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewResize640(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_VideoResolution == 640);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState &&
|
|
gos_GetMachineInformation(gos_Info_ValidMode,0,640,480));
|
|
}
|
|
|
|
void CMW4GameEdApp::OnViewResize800()
|
|
{
|
|
gos_SetScreenMode(800,600);
|
|
RunGameOSLogic();
|
|
m_VideoResolution = 800;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewResize800(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_VideoResolution == 800);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState &&
|
|
gos_GetMachineInformation(gos_Info_ValidMode,0,800,600));
|
|
}
|
|
|
|
void CMW4GameEdApp::OnViewResize1024()
|
|
{
|
|
gos_SetScreenMode(1024,768);
|
|
RunGameOSLogic();
|
|
m_VideoResolution = 1024;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewResize1024(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_VideoResolution == 1024);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState &&
|
|
gos_GetMachineInformation(gos_Info_ValidMode,0,1024,768));
|
|
}
|
|
|
|
void CMW4GameEdApp::OnViewResize1152()
|
|
{
|
|
gos_SetScreenMode(1152,864);
|
|
RunGameOSLogic();
|
|
m_VideoResolution = 1152;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewResize1152(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_VideoResolution == 1152);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState &&
|
|
gos_GetMachineInformation(gos_Info_ValidMode,0,1152,864));
|
|
}
|
|
|
|
void CMW4GameEdApp::OnViewResize1280()
|
|
{
|
|
gos_SetScreenMode(1280,1024);
|
|
RunGameOSLogic();
|
|
m_VideoResolution = 1280;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewResize1280(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_VideoResolution == 1280);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState &&
|
|
gos_GetMachineInformation(gos_Info_ValidMode,0,1280,1024));
|
|
}
|
|
|
|
void CMW4GameEdApp::OnViewResize1600()
|
|
{
|
|
gos_SetScreenMode(1600,1200);
|
|
RunGameOSLogic();
|
|
m_VideoResolution = 1600;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewResize1600(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_VideoResolution == 1600);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState() == ApplicationStateEngine::RunningGameState &&
|
|
gos_GetMachineInformation(gos_Info_ValidMode,0,1600,1200));
|
|
}
|
|
|
|
void CMW4GameEdApp::OnFileAutobackuponsave()
|
|
{
|
|
StopMultiPlace();
|
|
m_AutoBackupOnSave = !m_AutoBackupOnSave;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateFileAutobackuponsave(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_AutoBackupOnSave);
|
|
}
|
|
|
|
void CMW4GameEdApp::ShowTipAtStartup(void)
|
|
{
|
|
// CG: This function added by 'Tip of the Day' component.
|
|
|
|
CCommandLineInfo cmdInfo;
|
|
ParseCommandLine(cmdInfo);
|
|
if (cmdInfo.m_bShowSplash)
|
|
{
|
|
CTipDlg dlg;
|
|
if (dlg.m_bStartup)
|
|
dlg.DoModal();
|
|
}
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::ShowTipOfTheDay(void)
|
|
{
|
|
// CG: This function added by 'Tip of the Day' component.
|
|
|
|
CTipDlg dlg;
|
|
dlg.DoModal();
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnFileClose()
|
|
{
|
|
StopMultiPlace();
|
|
if (theApp.m_editorState != CMW4GameEdApp::NoGameIdleState)
|
|
{
|
|
if (!m_MissionSaved)
|
|
{
|
|
if (MessageBox(NULL,"Mission has not been saved. Save now?","Unsaved Data",MB_YESNO) == IDYES) // localize
|
|
{
|
|
OnFileSave();
|
|
}
|
|
}
|
|
|
|
if(!undoChain.IsEmpty())
|
|
{
|
|
ChainIteratorOf<Command *> iterator(&undoChain);
|
|
iterator.DeletePlugs();
|
|
}
|
|
|
|
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
|
|
if (briefingWnd)
|
|
{
|
|
delete briefingWnd;
|
|
briefingWnd = NULL;
|
|
}
|
|
if (instanceWindow->scriptWnd)
|
|
{
|
|
delete instanceWindow->scriptWnd;
|
|
instanceWindow->scriptWnd = NULL;
|
|
}
|
|
instanceWindow->ClearInstanceLists();
|
|
instanceWindow->FillTabBox();
|
|
|
|
|
|
RemoveEditorObjects ();
|
|
|
|
|
|
MWApplication::Instance->StopGame();
|
|
|
|
//This call will eventually have to be before Stop Game
|
|
//Right now this will construct the resource from text. It should
|
|
//eventually use the loaded mission to create the create message, but for now
|
|
//it needs to be kept as the same version as the text that is saved.
|
|
// EditorConstructMissionCreateMessage();
|
|
|
|
|
|
Verify(!Network::Instance);
|
|
Network::Instance = new Network;
|
|
Check_Object(Network::Instance);
|
|
m_editorState = CMW4GameEdApp::NoGameIdleState;
|
|
overviewWindow->DrawWindow();
|
|
displayWindow->Invalidate();
|
|
|
|
// Need this to clear the back buffer
|
|
gos_SetupViewport(0,1.0,1,0xff000000,0.0,0.0,1.0,1.0);
|
|
|
|
missionFileName.Empty();
|
|
m_ScriptName.Empty();
|
|
}
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::EditorConstructMissionCreateMessage()
|
|
{
|
|
|
|
#if defined(_ARMOR)
|
|
int stack_index = Tool::Instance->GetStackLevel();
|
|
#endif
|
|
|
|
const char *instance_file_name = missionFileName.GetBuffer(MAX_PATH);
|
|
ReplicatorID base_id = ReplicatorID::Null;
|
|
Resource mission_resource(instance_file_name);
|
|
//
|
|
//---------------------------------------------------------
|
|
// Open up the instance file and push the path on the stack
|
|
//---------------------------------------------------------
|
|
//
|
|
NotationFile instance_file(instance_file_name, NotationFile::NonEmpty);
|
|
instance_file_name = instance_file.GetFileName();
|
|
Tool::Instance->PushFilePath(&instance_file);
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// For instances, assume the first page is our instance, so take whatever
|
|
// name it has
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
NotationFile::PageIterator *instance_pages = instance_file.MakePageIterator();
|
|
Check_Object(instance_pages);
|
|
Page *instance = instance_pages->GetCurrent();
|
|
Check_Object(instance);
|
|
|
|
//
|
|
//------------------------------
|
|
// Put the message into a stream
|
|
//------------------------------
|
|
//
|
|
// DynamicMemoryStream instance_stream;
|
|
// Tool::Instance->ConstructCreateMessage(
|
|
// &instance_stream,
|
|
// instance,
|
|
// &base_id
|
|
// );
|
|
// mission_resource.Save(&instance_stream, instance_file.GetFileDependencies());
|
|
|
|
//
|
|
//-------------
|
|
// Now clean up
|
|
//-------------
|
|
//
|
|
Tool::Instance->PopFilePath();
|
|
Check_Object(instance_pages);
|
|
delete instance_pages;
|
|
Verify(stack_index == Tool::Instance->GetStackLevel());
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateFileSave(CCmdUI* pCmdUI)
|
|
{
|
|
if (theApp.m_editorState == CMW4GameEdApp::NoGameIdleState)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
pCmdUI->Enable();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateFileSaveAs(CCmdUI* pCmdUI)
|
|
{
|
|
OnUpdateFileSave(pCmdUI);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnFileDelete()
|
|
{
|
|
StopMultiPlace();
|
|
SetCurrentDirectory(Working_Directory);
|
|
CFileDlg dlg;
|
|
dlg.DoModal();
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::GetGridCoords(Point3D& point)
|
|
{
|
|
Scalar sign = (point.x < 0) ? -1.0f : 1.0f;
|
|
int wholeGrid = abs(int(point.x / Scalar(theApp.gridValue)));
|
|
Scalar gridFloor = Scalar(wholeGrid * theApp.gridValue);
|
|
|
|
if ((fabs(point.x) - fabs(gridFloor)) >= (theApp.gridValue / 2))
|
|
point.x = sign * (wholeGrid + 1) * theApp.gridValue;
|
|
else
|
|
point.x = sign * wholeGrid * theApp.gridValue;
|
|
|
|
sign = (point.z < 0) ? -1.0f : 1.0f;
|
|
wholeGrid = abs(int(point.z / Scalar(theApp.gridValue)));
|
|
gridFloor = Scalar(wholeGrid * theApp.gridValue);
|
|
|
|
if ((fabs(point.z) - fabs(gridFloor)) >= (theApp.gridValue / 2))
|
|
point.z = sign * (wholeGrid + 1) * theApp.gridValue;
|
|
else
|
|
point.z = sign * wholeGrid * theApp.gridValue;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::VerifyWaypointRadius()
|
|
{
|
|
// check if anything in the selection list is too close to a waypoint
|
|
Entity* waypoint;
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
|
|
while ((waypoint = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (waypoint->IsDerivedFrom(EditorWaypoint::DefaultData))
|
|
{
|
|
CSelectionNode* selected;
|
|
ChainIteratorOf<CSelectionNode*> selections(&CSelectionList::Instance->selectionList);
|
|
|
|
while ((selected = selections.ReadAndNext()) != NULL)
|
|
{
|
|
if (selected->selectedEntity->IsDerivedFrom(EditorWaypoint::DefaultData) ||
|
|
selected->selectedEntity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
continue;
|
|
|
|
Stuff::Vector3D vector;
|
|
Stuff::Point3D waypointPos,selectedPos;
|
|
|
|
waypointPos = waypoint->GetLocalToWorld();
|
|
selectedPos = selected->selectedEntity->GetLocalToWorld();
|
|
vector.Subtract(waypointPos,selectedPos);
|
|
|
|
// if (fabs((double)vector.x) <= waypoint->radius || fabs((double)vector.z) <= waypoint->radius)
|
|
if (fabs((double)vector.x) <= 50 || fabs((double)vector.z) <= 50)
|
|
{
|
|
MessageBox(NULL,"An object has been placed within the radius of a waypoint. This is not illegal, however if too many objects are within the waypoint's bounding radius bad things can happen.", // localize
|
|
"Warning",MB_OK | MB_ICONWARNING);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::LoadLattice()
|
|
{
|
|
Check_Object(theApp.resourceWindow->objectInformation);
|
|
Check_Object(EntityManager::Instance);
|
|
Check_Object(Connection::Local);
|
|
Check_Object(Map::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity* entity;
|
|
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
CSelectionList::Instance->AddSelection(entity);
|
|
}
|
|
}
|
|
|
|
if (CSelectionList::Instance->GetSelectionCount())
|
|
{
|
|
Verify(theApp.currentCommand == NULL);
|
|
theApp.currentCommand = new DeleteCommand();
|
|
delete theApp.currentCommand;
|
|
theApp.currentCommand = NULL;
|
|
}
|
|
|
|
Page *lattice_page = theApp.resourceWindow->objectInformation->GetPage("LatticeNode");
|
|
Check_Object(lattice_page);
|
|
|
|
for (int i = 0; i < MW4AI::g_MissionGraph->NumNodes(); i++)
|
|
{
|
|
if (!MW4AI::g_MissionGraph->Node(i)) // might be NULL
|
|
continue;
|
|
|
|
// lattice_page->SetEntry("Model", "Editor\\Waypoints\\LatticeNode\\LatticeNode.data");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
lattice_page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
entity->instanceName = "LatticeNode_";
|
|
char string[32];
|
|
entity->instanceName += itoa(i,string,10);
|
|
|
|
// EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
|
|
// theApp.resourceWindow->numEntitiesAdded++;
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
CSelectionList::Instance->AddSelection(entity);
|
|
|
|
EditorLatticeNode* latticeNode = Cast_Object(EditorLatticeNode*,entity);
|
|
latticeNode->railNode = MW4AI::g_MissionGraph->Node(i);
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
Point3D pos;
|
|
|
|
pos = latticeNode->railNode->Location();
|
|
|
|
Stuff::Scalar height = theApp.displayWindow->GetMapPointVertical(pos.x,pos.z);
|
|
if (pos.y < height)
|
|
{
|
|
pos.y = height;
|
|
latticeNode->railNode->Location(pos);
|
|
}
|
|
matrix.BuildTranslation(pos);
|
|
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
|
|
latticeNode->railNode->UpdateRadiusPointData();
|
|
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
Map::Instance->UpdateZone(entity);
|
|
}
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
InitMovementLatticeData();
|
|
}
|
|
|
|
void CMW4GameEdApp::RemoveLattice()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *childEntity;
|
|
|
|
while((childEntity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (childEntity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
Map::Instance->RemoveChild(childEntity);
|
|
childEntity->SentenceToDeathRow();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::LoadPaths()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
Check_Object(theApp.resourceWindow->objectInformation);
|
|
Check_Object(Connection::Local);
|
|
Check_Object(EntityManager::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *childEntity;
|
|
|
|
while((childEntity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(childEntity);
|
|
if (childEntity->IsDerivedFrom(MechWarrior4::Path::DefaultData))
|
|
{
|
|
EditorPathNode* lastNode = NULL;
|
|
MechWarrior4::Path* path;
|
|
path = Cast_Object(MechWarrior4::Path*,childEntity);
|
|
|
|
Page *path_page = theApp.resourceWindow->objectInformation->SetPage("Content\\Editor\\Waypoints\\MovementPath\\MovementPath.data");
|
|
Check_Object(path_page);
|
|
path_page->SetEntry("MovementPath","MovementPath");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
path_page = theApp.resourceWindow->objectInformation->SetPage("MovementPath");
|
|
Check_Object(path_page);
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
path_page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
entity->instanceName = "EditorMovementPath_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded++,string,10);
|
|
|
|
EditorMovementPath* movePath;
|
|
movePath = Cast_Object(EditorMovementPath*, entity);
|
|
|
|
movePath->GetElement()->SetAlwaysCullMode();
|
|
movePath->GetElement()->Sync();
|
|
|
|
for (int i = 0; i < path->pathPoints.size(); i++)
|
|
{
|
|
path_page = theApp.resourceWindow->objectInformation->SetPage("Content\\Editor\\Reserved\\PathNode\\PathNode.data");
|
|
Check_Object(path_page);
|
|
path_page->SetEntry("PathNode","PathNode");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
path_page = theApp.resourceWindow->objectInformation->SetPage("PathNode");
|
|
Check_Object(path_page);
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
path_page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
entity->instanceName = "MovementPathNode_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded++,string,10);
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
// CSelectionList::Instance->AddSelection(entity);
|
|
|
|
EditorPathNode* pathNode = Cast_Object(EditorPathNode*,entity);
|
|
pathNode->pathSlot.Remove();
|
|
pathNode->pathSlot.Add(movePath);
|
|
pathNode->pathSlot.GetCurrent()->pathSlot.Remove();
|
|
pathNode->pathSlot.GetCurrent()->pathSlot.Add(path);
|
|
pathNode->pathSlot.GetCurrent()->pathNodes.Add(pathNode);
|
|
pathNode->index = i;
|
|
if (lastNode)
|
|
lastNode->nextnode = pathNode;
|
|
pathNode->prevnode = lastNode;
|
|
pathNode->nextnode = NULL;
|
|
lastNode = pathNode;
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
matrix.BuildTranslation(path->pathPoints[i]);
|
|
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
|
|
pathNode->CreateLink();
|
|
pathNode->ShowLink(true);
|
|
// EntityManager::Instance->RequestPostCollisionExecution(pathNode);
|
|
Map::Instance->UpdateZone(pathNode);
|
|
}
|
|
}
|
|
}
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
}
|
|
|
|
void CMW4GameEdApp::LoadBoundary()
|
|
{
|
|
// return;
|
|
Check_Object(EntityManager::Instance);
|
|
Check_Object(Map::Instance);
|
|
SetCurrentDirectory(Working_Directory);
|
|
EditorBoundaryNode* lastNode = NULL;
|
|
EditorBoundaryNode* firstBoundaryNode=NULL;
|
|
int index;
|
|
for(index = 0; index < theApp.missionBoundary.GetLength(); index++)
|
|
{
|
|
Page *page = theApp.resourceWindow->objectInformation->SetPage("BoundaryNode");
|
|
Check_Object(page);
|
|
page->SetEntry("Model", "Editor\\Reserved\\BoundaryNode\\BoundaryNode.data");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
EditorBoundaryNode* boundaryNode = Cast_Object(EditorBoundaryNode*,entity);
|
|
boundaryNode->myBoundary=&missionBoundary;
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
entity->instanceName = "BoundaryNode_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded++,string,10);
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
|
|
if (index == 0)
|
|
{
|
|
boundaryNode->prevnode = boundaryNode;
|
|
boundaryNode->nextnode = boundaryNode;
|
|
firstBoundaryNode=boundaryNode;
|
|
}
|
|
else
|
|
{
|
|
lastNode->nextnode = boundaryNode;
|
|
boundaryNode->prevnode = lastNode;
|
|
boundaryNode->nextnode = firstBoundaryNode;
|
|
}
|
|
boundaryNode->firstBoundaryNode = firstBoundaryNode;
|
|
boundaryNode->firstBoundaryNode->prevnode=boundaryNode;
|
|
|
|
boundaryNode->index = index;
|
|
lastNode = boundaryNode;
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
Point3D pos;
|
|
|
|
pos.x = theApp.missionBoundary[index].x;
|
|
pos.z = theApp.missionBoundary[index].y;
|
|
pos.y = theApp.displayWindow->GetMapPointVertical(pos.x,pos.z);
|
|
|
|
matrix.BuildTranslation(pos);
|
|
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
|
|
boundaryNode->CreateLink();
|
|
boundaryNode->ShowLink(true);
|
|
|
|
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
Map::Instance->UpdateZone(entity);
|
|
if (m_showBoundary)
|
|
boundaryNode->GetElement()->SetVolumeCullMode();
|
|
boundaryNode->GetElement()->Sync();
|
|
}
|
|
|
|
|
|
for(index = 0; index < theApp.warningBoundary.GetLength(); index++)
|
|
{
|
|
Page *page = theApp.resourceWindow->objectInformation->SetPage("BoundaryNode");
|
|
Check_Object(page);
|
|
page->SetEntry("Model", "Editor\\Reserved\\BoundaryNode\\BoundaryNode.data");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
EditorBoundaryNode* boundaryNode = Cast_Object(EditorBoundaryNode*,entity);
|
|
boundaryNode->myBoundary=&warningBoundary;
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
entity->instanceName = "WarningNode_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded++,string,10);
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
|
|
if (index == 0)
|
|
{
|
|
boundaryNode->prevnode = boundaryNode;
|
|
boundaryNode->nextnode = boundaryNode;
|
|
firstBoundaryNode=boundaryNode;
|
|
}
|
|
else
|
|
{
|
|
lastNode->nextnode = boundaryNode;
|
|
boundaryNode->prevnode = lastNode;
|
|
boundaryNode->nextnode = firstBoundaryNode;
|
|
}
|
|
|
|
boundaryNode->firstBoundaryNode = firstBoundaryNode;
|
|
boundaryNode->firstBoundaryNode->prevnode=boundaryNode;
|
|
boundaryNode->index = index;
|
|
lastNode = boundaryNode;
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
Point3D pos;
|
|
|
|
pos.x = theApp.warningBoundary[index].x;
|
|
pos.z = theApp.warningBoundary[index].y;
|
|
pos.y = theApp.displayWindow->GetMapPointVertical(pos.x,pos.z);
|
|
|
|
matrix.BuildTranslation(pos);
|
|
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
|
|
|
|
boundaryNode->CreateLink();
|
|
boundaryNode->ShowLink(true);
|
|
|
|
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
Map::Instance->UpdateZone(entity);
|
|
if (m_showBoundary)
|
|
boundaryNode->GetElement()->SetVolumeCullMode();
|
|
boundaryNode->GetElement()->Sync();
|
|
}
|
|
|
|
|
|
m_showBoundary = true;
|
|
OnToolsMovmentlayerShowmissionboundary();
|
|
}
|
|
|
|
void CMW4GameEdApp::LoadDropZones()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
Check_Object(theApp.resourceWindow->objectInformation);
|
|
Check_Object(Connection::Local);
|
|
Check_Object(EntityManager::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *childEntity;
|
|
|
|
int count = 0;
|
|
while((childEntity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(childEntity);
|
|
if (childEntity->IsDerivedFrom(Adept::DropZone::DefaultData))
|
|
{
|
|
Adept::DropZone* dropZone;
|
|
dropZone = Cast_Object(Adept::DropZone*,childEntity);
|
|
|
|
Page *page = theApp.resourceWindow->objectInformation->SetPage("DropZone");
|
|
Check_Object(page);
|
|
page->SetEntry("Model", "Editor\\Waypoints\\DropZone\\DropZone.data");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
|
|
entity->instanceName = "DropZone_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded,string,10);
|
|
|
|
// EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
|
|
theApp.resourceWindow->numEntitiesAdded++;
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
// CSelectionList::Instance->AddSelection(entity);
|
|
|
|
EditorDropNode* editorDropNode = Cast_Object(EditorDropNode*,entity);
|
|
|
|
editorDropNode->SetDropZone(dropZone);
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
Point3D point;
|
|
YawPitchRoll rot;
|
|
point = dropZone->GetLocalToWorld();
|
|
rot = (YawPitchRoll) dropZone->GetLocalToWorld ();
|
|
// make sure drop zone is not below terrain
|
|
Scalar terrain_y = displayWindow->GetMapPointVertical(point.x,point.z);
|
|
if (point.y < terrain_y)
|
|
point.y = terrain_y;
|
|
|
|
matrix.BuildRotation (rot);
|
|
matrix.BuildTranslation(point);
|
|
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
|
|
ChainIteratorOf<DropZone::MatrixPlug*> zoneIterator(&dropZone->dropMats);
|
|
DropZone::MatrixPlug *drop_point;
|
|
while((drop_point = zoneIterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(drop_point);
|
|
page = theApp.resourceWindow->objectInformation->SetPage("DropZonePoint");
|
|
Check_Object(page);
|
|
page->SetEntry("Model", "Editor\\Reserved\\DropZonePoint\\DropZonePoint.data");
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
entity->instanceName = "DropZonePoint_";
|
|
char string[32];
|
|
entity->instanceName += itoa(count, string,10);
|
|
|
|
// EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
|
|
theApp.resourceWindow->numEntitiesAdded++;
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
EditorDropZonePoint* zonePoint = Cast_Object(EditorDropZonePoint*,entity);
|
|
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
matrix = drop_point->GetItem();
|
|
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
|
|
editorDropNode->pointChain.Add(zonePoint);
|
|
zonePoint->dropNode = editorDropNode;
|
|
zonePoint->offset = editorDropNode->GetLocalToWorld();
|
|
zonePoint->offset -= point;
|
|
|
|
zonePoint->CreateLink();
|
|
zonePoint->ShowLink(true);
|
|
|
|
count++;
|
|
// EntityManager::Instance->RequestPostCollisionExecution(entity);
|
|
}
|
|
editorDropNode->UpdatePoints();
|
|
}
|
|
}
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
}
|
|
|
|
void CMW4GameEdApp::LoadLights()
|
|
{
|
|
Check_Object(Mission::Instance);
|
|
|
|
gosFX::Light* light;
|
|
Entity* entity;
|
|
EditorLight* editorLight;
|
|
|
|
ChainIteratorOf<gosFX::Light*> iterator(&Mission::Instance->m_staticLights);
|
|
|
|
while((light = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
switch (light->m_light->GetLightType())
|
|
{
|
|
case MLRLight::AmbientLight:
|
|
entity = theApp.resourceWindow->CreateNewInstance("Content\\Editor\\Waypoints\\AmbientLight\\AmbientLight.data",
|
|
"AmbientLight","AmbientLight");
|
|
break;
|
|
case MLRLight::InfiniteLight:
|
|
entity = theApp.resourceWindow->CreateNewInstance("Content\\Editor\\Waypoints\\InfiniteLight\\InfiniteLight.data",
|
|
"InfiniteLight","InfiniteLight");
|
|
break;
|
|
case MLRLight::PointLight:
|
|
entity = theApp.resourceWindow->CreateNewInstance("Content\\Editor\\Waypoints\\PointLight\\PointLight.data",
|
|
"PointLight","PointLight");
|
|
entity->SetNewLocalToParent(light->m_light->GetLightToWorldMatrix());
|
|
entity->SyncMatrices(true);
|
|
break;
|
|
case MLRLight::SpotLight:
|
|
entity = theApp.resourceWindow->CreateNewInstance("Content\\Editor\\Waypoints\\SpotLight\\SpotLight.data",
|
|
"SpotLight","SpotLight");
|
|
entity->SetNewLocalToParent(light->m_light->GetLightToWorldMatrix());
|
|
entity->SyncMatrices(true);
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
editorLight = Cast_Object(EditorLight*,entity);
|
|
editorLight->instanceName = light->m_light->GetName();
|
|
editorLight->SetLight(light);
|
|
}
|
|
|
|
char path[MAX_PATH],*p;
|
|
strncpy(path,(LPCTSTR)missionFileName,MAX_PATH - 1);
|
|
p = strrchr(path,'.');
|
|
*p = 0;
|
|
lightFileName = path;
|
|
lightFileName += ".Lights";
|
|
|
|
audioFileName = path;
|
|
audioFileName += ".audio";
|
|
}
|
|
|
|
|
|
void CMW4GameEdApp::LoadCameras()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
Check_Object(theApp.resourceWindow->objectInformation);
|
|
Check_Object(Connection::Local);
|
|
Check_Object(EntityManager::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *childEntity;
|
|
|
|
while((childEntity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(childEntity);
|
|
if (childEntity->IsDerivedFrom(MechWarrior4::CameraShip::DefaultData))
|
|
{
|
|
MechWarrior4::CameraShip* cameraShip;
|
|
cameraShip = Cast_Object(MechWarrior4::CameraShip*,childEntity);
|
|
|
|
Page *page = theApp.resourceWindow->objectInformation->SetPage("CameraShip");
|
|
Check_Object(page);
|
|
page->SetEntry("Model", "Content\\Editor\\Waypoints\\CameraShip\\CameraShip.data");
|
|
|
|
|
|
Check_Object(page);
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
EntityManager::Instance->GetNameSocket()->Remove(entity);
|
|
|
|
entity->instanceName = "EditorCameraShip_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded++,string,10);
|
|
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
|
|
|
|
EditorCameraShip* editorCameraShip = Cast_Object(EditorCameraShip*,entity);
|
|
|
|
editorCameraShip->SetCameraShip(cameraShip);
|
|
|
|
|
|
LinearMatrix4D matrix(true);
|
|
Point3D point;
|
|
point = cameraShip->GetLocalToWorld();
|
|
// make sure drop zone is not below terrain
|
|
Scalar terrain_y = displayWindow->GetMapPointVertical(point.x,point.z);
|
|
if (point.y < terrain_y)
|
|
point.y = terrain_y;
|
|
|
|
matrix.BuildTranslation(point);
|
|
|
|
editorCameraShip->SetNewLocalToParent(matrix);
|
|
editorCameraShip->SyncMatrices(true);
|
|
editorCameraShip->GetElement()->SetVolumeCullMode();
|
|
editorCameraShip->GetElement()->Sync();
|
|
editorCameraShip->cameraShip->SetNewLocalToParent(matrix);
|
|
editorCameraShip->cameraShip->SyncMatrices(true);
|
|
Map::Instance->UpdateZone(editorCameraShip);
|
|
Map::Instance->UpdateZone(cameraShip);
|
|
}
|
|
}
|
|
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
theApp.MakeObjectsTileBased();
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovementlattice()
|
|
{
|
|
m_showLattice = !m_showLattice;
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
if (m_showLattice)
|
|
{
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
entity->GetElement()->SetVolumeCullMode();
|
|
entity->GetElement()->Sync();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
EditorLatticeNode* node;
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
entity->GetElement()->SetAlwaysCullMode();
|
|
entity->GetElement()->Sync();
|
|
|
|
node = Cast_Object(EditorLatticeNode*,entity);
|
|
node->railNode->ShowRadius(false);
|
|
}
|
|
}
|
|
}
|
|
overviewWindow->DrawWindow();
|
|
instanceWindow->ResetInstanceLists();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovementlattice(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showLattice);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::InitMovementLatticeData()
|
|
{
|
|
Check_Object(MW4AI::g_MissionGraph);
|
|
m_NumLinks = MW4AI::g_MissionGraph->NumLinks();
|
|
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
|
|
// if (LatticeLinkChain.IsEmpty())
|
|
{
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity* entity;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
EditorLatticeNode* node;
|
|
node = Cast_Object(EditorLatticeNode*,entity);
|
|
|
|
CreateLatticeNodeRadius(node);
|
|
}
|
|
}
|
|
}
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
void CMW4GameEdApp::CreateLatticeNodeRadius(Entity* entity)
|
|
{
|
|
EditorLatticeNode* node;
|
|
node = Cast_Object(EditorLatticeNode*,entity);
|
|
|
|
CreateLatticeNodeRadius(node);
|
|
}
|
|
|
|
void CMW4GameEdApp::CreateLatticeNodeRadius(EditorLatticeNode* node)
|
|
{
|
|
/*
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
|
|
node->railNode->m_RadiusPointCount = 64;
|
|
node->railNode->m_RadiusLineCloud = new ElementRenderer::LineCloudElement(node->railNode->m_RadiusPointCount);
|
|
Check_Object(node->railNode->m_RadiusLineCloud);
|
|
node->railNode->UpdateRadiusPointData();
|
|
node->railNode->SetRadiusColor(Stuff::RGBAColor(192,0,0,0));
|
|
|
|
node->railNode->m_RadiusLineCloud->SetDataPointers(&node->railNode->m_RadiusPointCount, node->railNode->m_RadiusPointData, node->railNode->m_RadiusColorData);
|
|
node->railNode->m_RadiusLineCloud->localOBB.localToParent = LinearMatrix4D::Identity;
|
|
|
|
node->railNode->m_RadiusLineCloud->localOBB.sphereRadius = node->railNode->Radius() + 1;
|
|
|
|
Mission::Instance->GetElement()->AttachChild(node->railNode->m_RadiusLineCloud);
|
|
|
|
node->railNode->m_RadiusLineCloud->SetName("Line Cloud");
|
|
|
|
node->railNode->m_RadiusLineCloud->localOBB.localToParent(3,0) = node->railNode->Location().x;
|
|
node->railNode->m_RadiusLineCloud->localOBB.localToParent(3,1) = node->railNode->Location().y;
|
|
node->railNode->m_RadiusLineCloud->localOBB.localToParent(3,2) = node->railNode->Location().z;
|
|
node->railNode->m_RadiusLineCloud->NeedNewBounds();
|
|
node->railNode->m_RadiusLineCloud->NeedMatrixSync();
|
|
node->railNode->ShowRadius(false);
|
|
node->railNode->m_RadiusLineCloud->Sync();
|
|
|
|
gos_PopCurrentHeap();
|
|
*/
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShowlatticelinks()
|
|
{
|
|
m_showLatticeLinks = !m_showLatticeLinks;
|
|
MW4AI::g_MissionGraph->ShowLinks(m_showLatticeLinks);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShowlatticelinks(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showLatticeLinks);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerRecalclatticelinks()
|
|
{
|
|
RECT rect;
|
|
theApp.m_pMainWnd->GetWindowRect(&rect);
|
|
|
|
// make sure only lattice nodes are selected
|
|
CSelectionNode* selected;
|
|
ChainIteratorOf<CSelectionNode*> iterator(&CSelectionList::Instance->selectionList);
|
|
while (((selected = iterator.ReadAndNext()) != NULL))
|
|
{
|
|
if (!selected->selectedEntity->IsDerivedFrom (EditorLatticeNode::DefaultData))
|
|
{
|
|
CSelectionList::Instance->RemoveSelection(selected->selectedEntity,true);
|
|
}
|
|
}
|
|
int count = CSelectionList::Instance->GetSelectionCount();
|
|
if (count)
|
|
{
|
|
EditorLatticeNode* latticeNode;
|
|
int* nodeIDArray = new int[count],i = 0;
|
|
|
|
iterator.First();
|
|
while (((selected = iterator.ReadAndNext()) != NULL) && i < count)
|
|
{
|
|
if (selected->selectedEntity->IsDerivedFrom (EditorLatticeNode::DefaultData))
|
|
{
|
|
latticeNode = Cast_Object(EditorLatticeNode*,selected->selectedEntity);
|
|
nodeIDArray[i] = latticeNode->railNode->ID();
|
|
}
|
|
i++;
|
|
}
|
|
RemoveLattice();
|
|
|
|
if (ProgressDlg)
|
|
delete ProgressDlg;
|
|
|
|
ProgressDlg = new CProgressDlg(IDS_CALCPROGRESSTITLE);
|
|
ProgressDlg->Create();
|
|
ProgressDlg->ShowWindow(SW_SHOW);
|
|
|
|
MW4AI::g_MissionGraph->CalcLinks(nodeIDArray,count,MINLINKCALC,MAXLINKCALC,LINKDIST,CalcLinkProgress);
|
|
|
|
delete ProgressDlg;
|
|
ProgressDlg = NULL;
|
|
|
|
delete nodeIDArray;
|
|
}
|
|
else
|
|
{
|
|
RemoveLattice();
|
|
|
|
if (ProgressDlg)
|
|
delete ProgressDlg;
|
|
|
|
ProgressDlg = new CProgressDlg(IDS_CALCPROGRESSTITLE);
|
|
ProgressDlg->Create();
|
|
ProgressDlg->ShowWindow(SW_SHOW);
|
|
|
|
MW4AI::g_MissionGraph->CalcLinks(MINLINKCALC,MAXLINKCALC,LINKDIST,CalcLinkProgress);
|
|
|
|
delete ProgressDlg;
|
|
ProgressDlg = NULL;
|
|
}
|
|
|
|
LoadLattice();
|
|
// InitMovementLatticeData();
|
|
|
|
// m_showLatticeLinks = false;
|
|
// OnToolsMovmentlayerShowlatticelinks();
|
|
|
|
// m_showRadii = false;
|
|
// OnToolsMovmentlayerShownoderadii();
|
|
}
|
|
|
|
void CMW4GameEdApp::StopMultiPlace()
|
|
{
|
|
if (theApp.m_editorState == CMW4GameEdApp::AddingObjectState ||
|
|
theApp.m_editorState == CMW4GameEdApp::SprayingState)
|
|
{
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
AddCommand *add_command = (AddCommand*)currentCommand;
|
|
add_command->Undo();
|
|
|
|
m_editorState = CMW4GameEdApp::SelectingObjectState;
|
|
m_MultiDrop = false;
|
|
theApp.m_CurPath = NULL;
|
|
theApp.resourceWindow->TLDlg->m_ObjList.EnableWindow();
|
|
theApp.instanceWindow->TLDlg->m_ObjList.EnableWindow();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShowall()
|
|
{
|
|
if (m_showLattice && m_showLatticeLinks && m_showRadii && m_showPaths)
|
|
m_showLattice = m_showLatticeLinks = m_showRadii = m_showPaths = true;
|
|
else
|
|
m_showLattice = m_showLatticeLinks = m_showRadii = m_showPaths = false;
|
|
|
|
OnToolsMovementlattice();
|
|
OnToolsMovmentlayerShowlatticelinks();
|
|
OnToolsMovmentlayerShownoderadii();
|
|
OnToolsMovmentlayerShowpaths();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShownoderadii()
|
|
{
|
|
m_showRadii = !m_showRadii;
|
|
MW4AI::g_MissionGraph->ShowRadius(m_showRadii);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShowpaths()
|
|
{
|
|
m_showPaths = !m_showPaths;
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
EditorPathNode* path;
|
|
Entity *entity;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
|
|
{
|
|
path = Cast_Object(EditorPathNode*,entity);
|
|
path->ShowLink(m_showPaths);
|
|
if (m_showPaths)
|
|
entity->GetElement()->SetVolumeCullMode();
|
|
else
|
|
entity->GetElement()->SetAlwaysCullMode();
|
|
|
|
entity->GetElement()->Sync();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShowall(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showLattice && m_showLatticeLinks && m_showRadii && m_showPaths);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShownoderadii(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showRadii);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShowpaths(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showPaths);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMechlab()
|
|
{
|
|
StopMultiPlace();
|
|
CMenu* m = theApp.m_pMainWnd->GetMenu();
|
|
for (int i = 0; i < m->GetMenuItemCount(); i++)
|
|
{
|
|
m->EnableMenuItem(i,MF_GRAYED | MF_BYPOSITION);
|
|
}
|
|
m_pMainWnd->DrawMenuBar();
|
|
resourceWindow->TLDlg->m_ObjList.EnableWindow(FALSE);
|
|
instanceWindow->TLDlg->m_ObjList.EnableWindow(FALSE);
|
|
resourceWindow->EnableWindow(FALSE);
|
|
instanceWindow->EnableWindow(FALSE);
|
|
overviewWindow->EnableWindow(FALSE);
|
|
|
|
displayWindow->GetFocus();
|
|
|
|
m_MechLabActive = true;
|
|
|
|
MechLab ml;
|
|
|
|
ml.StartUp();
|
|
// ml.Execute();
|
|
ml.ShutDown();
|
|
|
|
for (i = 0; i < m->GetMenuItemCount(); i++)
|
|
{
|
|
m->EnableMenuItem(i,MF_ENABLED | MF_BYPOSITION);
|
|
}
|
|
m_pMainWnd->DrawMenuBar();
|
|
resourceWindow->TLDlg->m_ObjList.EnableWindow(TRUE);
|
|
instanceWindow->TLDlg->m_ObjList.EnableWindow(TRUE);
|
|
resourceWindow->EnableWindow(TRUE);
|
|
instanceWindow->EnableWindow(TRUE);
|
|
overviewWindow->EnableWindow(TRUE);
|
|
m_MechLabActive = false;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShowmissionboundary()
|
|
{
|
|
m_showBoundary = !m_showBoundary;
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
EditorBoundaryNode* node;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
|
|
{
|
|
if (m_showBoundary)
|
|
entity->GetElement()->SetVolumeCullMode();
|
|
else
|
|
entity->GetElement()->SetAlwaysCullMode();
|
|
|
|
entity->GetElement()->Sync();
|
|
|
|
node = Cast_Object(EditorBoundaryNode*, entity);
|
|
node->ShowLink(m_showBoundary);
|
|
}
|
|
}
|
|
overviewWindow->DrawWindow();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShowmissionboundary(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showBoundary);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::VerifyObjectPlacement(bool feedback) // Localize!!!
|
|
{
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
bool error = false;
|
|
char string[256];
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->GetSolidVolume() == NULL)
|
|
continue;
|
|
|
|
if (entity->IsMultiZone())
|
|
{
|
|
error = true;
|
|
sprintf(string,"%s, is placed on multiple Zones. This is illegal.",(char*)entity->instanceName);
|
|
if (MessageBox(NULL,string,"MultiZone Entity",MB_OKCANCEL) == IDCANCEL)
|
|
return;
|
|
}
|
|
else if (entity->IsMultiTile())
|
|
{
|
|
error = true;
|
|
sprintf(string,"%s, is placed on multiple Tiles. This is not recommended.",(char*)entity->instanceName);
|
|
if (MessageBox(NULL,string,"MultiTile Entity",MB_OKCANCEL) == IDCANCEL)
|
|
return;
|
|
}
|
|
}
|
|
if (feedback && !error)
|
|
MessageBox(NULL,"Object placement verification complete. No misplaced objects.","Verification Results",MB_OK);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsVerifyobjectplacement()
|
|
{
|
|
StopMultiPlace();
|
|
VerifyObjectPlacement(true);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShowdropzones()
|
|
{
|
|
m_showDropZones = !m_showDropZones;
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorDropNode::DefaultData) ||
|
|
entity->IsDerivedFrom(EditorDropZonePoint::DefaultData))
|
|
{
|
|
if (m_showDropZones)
|
|
entity->GetElement()->SetVolumeCullMode();
|
|
else
|
|
entity->GetElement()->SetAlwaysCullMode();
|
|
|
|
entity->GetElement()->Sync();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShowdropzones(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showDropZones);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsEditmissionscript()
|
|
{
|
|
StopMultiPlace();
|
|
if (!instanceWindow->scriptWnd)
|
|
{
|
|
instanceWindow->scriptWnd = new CEditWnd();
|
|
RECT r;
|
|
r.left = 50;
|
|
r.top = 50;
|
|
r.right = 690;
|
|
r.bottom = 530;
|
|
instanceWindow->scriptWnd->Create(NULL,"Mission Script",NULL,r);
|
|
}
|
|
|
|
char ssPath[MAX_PATH],oldDir[MAX_PATH],dir[MAX_PATH],*p;
|
|
_getcwd(oldDir,MAX_PATH - 1);
|
|
|
|
if (m_ScriptName)
|
|
strcpy(ssPath,(char*)LPCTSTR(m_ScriptName));
|
|
else
|
|
{
|
|
OnToolsSpecifymissionscript();
|
|
|
|
if (m_ScriptName)
|
|
{
|
|
strcpy(ssPath,(char*)LPCTSTR(m_ScriptName));
|
|
}
|
|
else
|
|
{
|
|
_chdir(oldDir);
|
|
_chdir(dir);
|
|
p = __mbsrchr(dir,'\\');
|
|
*p = 0;
|
|
p = __mbsrchr(dir,'\\') + 1;
|
|
sprintf(ssPath,"%s\\%s.abl",dir,p);
|
|
}
|
|
}
|
|
|
|
instanceWindow->scriptWnd->LoadFile(ssPath);
|
|
instanceWindow->scriptWnd->SetWindowText("Mission Script");
|
|
instanceWindow->scriptWnd->ShowWindow(SW_SHOW);
|
|
instanceWindow->scriptWnd->SetWindowPos (&instanceWindow->wndTop,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
|
|
instanceWindow->scriptWnd->CloseCallback = EditMissionScriptCallback;
|
|
_chdir(oldDir);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerShowobjectives()
|
|
{
|
|
m_showAI = !m_showAI;
|
|
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorDropNode::DefaultData) ||
|
|
entity->IsDerivedFrom(EditorDropZonePoint::DefaultData))
|
|
{
|
|
if (m_showAI)
|
|
entity->GetElement()->SetVolumeCullMode();
|
|
else
|
|
entity->GetElement()->SetAlwaysCullMode();
|
|
|
|
entity->GetElement()->Sync();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMovmentlayerShowobjectives(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_showAI);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
|
|
void CMW4GameEdApp::OnViewShowtileborders()
|
|
{
|
|
m_showTileBorder = !m_showTileBorder;
|
|
|
|
if (m_showTileBorder)
|
|
{
|
|
Compost::TerrainTextureLogistic::Instance->TurnOnBorder(RGBAColor(1.0f,0.0f,0.0f,0.0f));
|
|
|
|
}
|
|
else
|
|
{
|
|
Compost::TerrainTextureLogistic::Instance->TurnOffBorder();
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateViewShowtileborders(CCmdUI* pCmdUI)
|
|
{
|
|
if (theApp.m_editorState == CMW4GameEdApp::NoGameIdleState)
|
|
pCmdUI->Enable(FALSE);
|
|
else
|
|
{
|
|
pCmdUI->Enable();
|
|
pCmdUI->SetCheck(m_showTileBorder);
|
|
}
|
|
}
|
|
|
|
BOOL CMW4GameEdApp::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
// CG: The following lines were added by the Splash Screen component.
|
|
if (CSplashWnd::PreTranslateAppMessage(pMsg))
|
|
return TRUE;
|
|
|
|
return CWinApp::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsSpecifymissionscript()
|
|
{
|
|
StopMultiPlace();
|
|
OPENFILENAME ofn;
|
|
char dir[MAX_PATH],oldDir[MAX_PATH],ssPath[MAX_PATH];
|
|
|
|
strcpy(dir,missionFileName);
|
|
char* p = __mbsrchr(dir,'\\') + 1;
|
|
*p = 0;
|
|
|
|
_getcwd(oldDir,MAX_PATH - 1);
|
|
_chdir(dir);
|
|
|
|
memset(&ssPath,0,MAX_PATH);
|
|
memset(&ofn,0,sizeof(ofn));
|
|
|
|
MWMission *mission = Cast_Object (MWMission *,Mission::Instance);
|
|
if (mission->scriptName)
|
|
{
|
|
char *p,tmp[MAX_PATH];
|
|
strncpy(tmp,mission->scriptName,MAX_PATH);
|
|
p = __mbsrchr(tmp,'\\');
|
|
if (p)
|
|
strncpy(ssPath,++p,MAX_PATH);
|
|
}
|
|
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = NULL;
|
|
ofn.lpstrFilter = "ABL Scripts {*.abl}\0*.abl\0All Files {*.*}\0*.*\0\0";
|
|
ofn.lpstrFile = ssPath;
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.Flags = OFN_FILEMUSTEXIST;
|
|
ofn.lpstrDefExt = "subsystems";
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
_chdir(oldDir);
|
|
_chdir(dir);
|
|
|
|
char path[MAX_PATH],cmpPath[MAX_PATH],misPath[MAX_PATH];
|
|
|
|
strcpy(path,missionFileName);
|
|
strcpy(cmpPath,ofn.lpstrFile);
|
|
|
|
p = strrchr(path,'.');
|
|
if (p) *p = 0;
|
|
p = __mbsrchr(path,'\\');
|
|
if (p) *p = 0;
|
|
|
|
p = strrchr(cmpPath,'.');
|
|
if (p) *p = 0;
|
|
p = __mbsrchr(cmpPath,'\\');
|
|
if (p) *p = 0;
|
|
p = strstr(cmpPath,"Content");
|
|
sprintf (misPath,"%s",path);
|
|
|
|
if (strcmp(path,p) != 0)
|
|
{
|
|
strcpy(ssPath,ofn.lpstrFile);
|
|
p = __mbsrchr(ssPath,'\\') + 1;
|
|
sprintf(path,"%s",p);
|
|
|
|
if (!CopyFile(ofn.lpstrFile,path,TRUE))
|
|
{
|
|
DWORD err = GetLastError();
|
|
if (err == 80) // file exists
|
|
{
|
|
if (MessageBox(NULL,"A file of that name already exists in the mission script folder. Do you wish to overwrite that file?","File Error",MB_YESNO) == IDYES)
|
|
CopyFile(ofn.lpstrFile,ssPath,FALSE);
|
|
}
|
|
else
|
|
{
|
|
sprintf(dir,"Could not copy ABL file to current mission folder. Error %d",err);
|
|
MessageBox(NULL,dir,"File Error",MB_OK); // localize
|
|
_chdir(oldDir);
|
|
return;
|
|
}
|
|
}
|
|
if (!SetFileAttributes(ssPath,FILE_ATTRIBUTE_NORMAL))
|
|
{
|
|
DWORD err = GetLastError();
|
|
sprintf(dir,"Could not clear readonly flag on ABL file in current mission folder, please do so yourself. Error %d",err);
|
|
MessageBox(NULL,dir,"File Error",MB_OK); // localize
|
|
_chdir(oldDir);
|
|
return;
|
|
}
|
|
}
|
|
m_ScriptName = __mbsrchr(ofn.lpstrFile,'\\') + 1;
|
|
sprintf (mission->scriptName,"%s\\%s",misPath,(char*)LPCTSTR(m_ScriptName));
|
|
m_ScriptName = mission->scriptName;
|
|
// strcpy(mission->scriptName,(char*)LPCTSTR(m_ScriptName));
|
|
}
|
|
_chdir(oldDir);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsCheckscripts()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
// Entity *entity;
|
|
|
|
MWMission *mission = Cast_Object (MWMission *,Mission::Instance);
|
|
mission->UnloadScript ();
|
|
|
|
MWMap *inst;
|
|
AI *ai;
|
|
inst = Cast_Object (MWMap *,Map::Instance);
|
|
ChainIteratorOf<AI *> iterator2(&inst->m_executingAIs);
|
|
iterator2.First ();
|
|
while((ai = iterator2.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(ai);
|
|
|
|
ai->UnloadScript ();
|
|
}
|
|
|
|
ABL::ABLError error;
|
|
CString errstr;
|
|
CString filename;
|
|
CString cmdline,line;
|
|
char errMessage[500];
|
|
|
|
if (!mission->ReloadABL (&error))
|
|
{
|
|
sprintf(errMessage, "SYNTAX ERROR %s [line %d] - (type %d) %s\n", error.File (), error.Line (),error.Code (), error.String ());
|
|
|
|
MessageBox (NULL,errMessage,"ABL Error",MB_OK);
|
|
|
|
filename = error.File ();
|
|
|
|
// cmdline = "c:\\vslick\\win\\vs ";
|
|
cmdline = "vs ";
|
|
cmdline += "\"";
|
|
_getcwd (errMessage,500);
|
|
if (filename[1] != ':')
|
|
{
|
|
cmdline += errMessage;
|
|
cmdline += "\\";
|
|
}
|
|
cmdline += filename;
|
|
cmdline += "\"";
|
|
cmdline += " -#";
|
|
itoa (error.Line (),errMessage,10);
|
|
cmdline += errMessage;
|
|
|
|
// system ((LPCTSTR) cmdline);
|
|
if (WinExec ((LPCTSTR) cmdline,SW_SHOW) <= 31) // old function but it works
|
|
MessageBox (NULL,"Unable to start slickedit, make sure it's in your path","error",MB_OK);
|
|
// CreateProcess (NULL,cmdline,NULL,NULL,FALSE,0,NULL,NULL,NULL,NULL);
|
|
return;
|
|
}
|
|
|
|
if (!mission->ReloadScript (&error))
|
|
{
|
|
sprintf(errMessage, "SYNTAX ERROR %s [line %d] - (type %d) %s\n", error.File (), error.Line (),error.Code (), error.String ());
|
|
|
|
MessageBox (NULL,errMessage,"ABL Error",MB_OK);
|
|
|
|
filename = error.File ();
|
|
|
|
// cmdline = "c:\\vslick\\win\\vs ";
|
|
cmdline = "vs ";
|
|
cmdline += "\"";
|
|
_getcwd (errMessage,500);
|
|
if (filename[1] != ':')
|
|
{
|
|
cmdline += errMessage;
|
|
cmdline += "\\";
|
|
}
|
|
cmdline += filename;
|
|
cmdline += "\"";
|
|
cmdline += " -#";
|
|
itoa (error.Line (),errMessage,10);
|
|
cmdline += errMessage;
|
|
|
|
// system ((LPCTSTR) cmdline);
|
|
if (WinExec ((LPCTSTR) cmdline,SW_SHOW) <= 31) // old function but it works
|
|
MessageBox (NULL,"Unable to start slickedit, make sure it's in your path","error",MB_OK);
|
|
// CreateProcess (NULL,cmdline,NULL,NULL,FALSE,0,NULL,NULL,NULL,NULL);
|
|
return;
|
|
}
|
|
iterator2.First ();
|
|
while((ai = iterator2.ReadAndNext()) != NULL)
|
|
{
|
|
{
|
|
|
|
if (!ai->ReloadScript (&error))
|
|
{
|
|
sprintf(errMessage, "SYNTAX ERROR %s [line %d] - (type %d) %s\n", error.File (), error.Line (),error.Code (), error.String ());
|
|
|
|
MessageBox (NULL,errMessage,"ABL Error",MB_OK);
|
|
|
|
filename = error.File ();
|
|
|
|
cmdline = "vs ";
|
|
// cmdline = "c:\\vslick\\win\\vs ";
|
|
cmdline += "\"";
|
|
_getcwd (errMessage,500);
|
|
if (filename[1] != ':')
|
|
{
|
|
cmdline += errMessage;
|
|
cmdline += "\\";
|
|
}
|
|
cmdline += filename;
|
|
cmdline += "\"";
|
|
cmdline += " -#";
|
|
itoa (error.Line (),errMessage,10);
|
|
cmdline += errMessage;
|
|
|
|
// system ((LPCTSTR) cmdline);
|
|
if (WinExec ((LPCTSTR) cmdline,SW_SHOW) <= 31) // old function but it works
|
|
MessageBox (NULL,"Unable to start slickedit, make sure it's in your path","error",MB_OK);
|
|
// CreateProcess (NULL,cmdline,NULL,NULL,FALSE,0,NULL,NULL,NULL,NULL);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::CreateLightDlg()
|
|
{
|
|
if (!lightDlg)
|
|
{
|
|
lightDlg = new CLightWnd;
|
|
Register_Pointer(lightDlg);
|
|
lightDlg->Create(IDD_LIGHTDLG);
|
|
}
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerCreatelattice()
|
|
{
|
|
if (MessageBox(NULL,"This action will remove all currently existing lattice node and links. This action cannot be undone. Are you sure you want to continue?","Create Movement Lattice Confirm",MB_ICONQUESTION | MB_YESNO) == IDNO)
|
|
return;
|
|
|
|
RemoveLattice();
|
|
|
|
if (ProgressDlg)
|
|
delete ProgressDlg;
|
|
|
|
ProgressDlg = new CProgressDlg(IDS_CREATERECTSPROGRESSTITLE);
|
|
ProgressDlg->Create();
|
|
ProgressDlg->ShowWindow(SW_SHOW);
|
|
|
|
MW4AI::g_MissionGraph->CreateBasicNodes(theApp.overviewWindow->mapHeight * theApp.overviewWindow->mapWidth / 10000,CalcLinkProgress);
|
|
|
|
delete ProgressDlg;
|
|
ProgressDlg = NULL;
|
|
|
|
LoadLattice();
|
|
|
|
m_showLattice = false;
|
|
OnToolsMovementlattice();
|
|
|
|
m_showLatticeLinks = false;
|
|
OnToolsMovmentlayerShowlatticelinks();
|
|
|
|
m_showRadii = false;
|
|
OnToolsMovmentlayerShownoderadii();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMovmentlayerCreateRects()
|
|
{
|
|
if (ProgressDlg)
|
|
delete ProgressDlg;
|
|
|
|
ProgressDlg = new CProgressDlg(IDS_CREATELATTICEPROGRESSTITLE);
|
|
ProgressDlg->Create();
|
|
ProgressDlg->ShowWindow(SW_SHOW);
|
|
|
|
MW4AI::g_MissionGraph->CreateRectData(CalcLinkProgress);
|
|
|
|
delete ProgressDlg;
|
|
ProgressDlg = NULL;
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsMissionparametersEditfog()
|
|
{
|
|
if (!fogDlg)
|
|
{
|
|
fogDlg = new FogDlg;
|
|
Register_Pointer(fogDlg);
|
|
fogDlg->Create(IDD_FOGDLG);
|
|
}
|
|
fogDlg->ShowWindow(SW_SHOW);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsCameraspeedFast(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(cameraSpeed == 16);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsCameraspeedRegular(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(cameraSpeed == 4);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsCameraspeedSlow(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(cameraSpeed == 1);
|
|
pCmdUI->Enable(MWApplication::Instance->GetApplicationState()
|
|
== ApplicationStateEngine::RunningGameState);
|
|
|
|
}
|
|
|
|
bool CMW4GameEdApp::SaveAudioFile(char *fname)
|
|
{
|
|
//
|
|
// Need to fill this in with the right data to support audio files
|
|
// Currently the editor does not have a way to edit the .audio files.
|
|
// TODO
|
|
//
|
|
if (fname)
|
|
{
|
|
audioFileName = fname;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool CMW4GameEdApp::SaveLightFile(char* fname)
|
|
{
|
|
Check_Object(Map::Instance);
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity* entity;
|
|
EditorLight* editorLight;
|
|
|
|
if (fname)
|
|
{
|
|
lightFileName = fname;
|
|
}
|
|
|
|
NotationFile* dataFile = new NotationFile(LPCTSTR(lightFileName));
|
|
DWORD result = GetFileAttributes(LPCTSTR(lightFileName));
|
|
|
|
if (result == -1)
|
|
CloseHandle(CreateFile(LPCTSTR(lightFileName),0,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,NULL));
|
|
else if (result & FILE_ATTRIBUTE_READONLY) // is it marked READONLY?
|
|
{
|
|
MessageBox(NULL,"Unable to save file becuase some of the data files are marked READONLY","Save Error",MB_OK);
|
|
return false;
|
|
}
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom(EditorLight::DefaultData))
|
|
{
|
|
editorLight = Cast_Object(EditorLight*, entity);
|
|
Page *page = dataFile->SetPage((char*)entity->instanceName);
|
|
Check_Object(page);
|
|
editorLight->light->m_light->Write(page);
|
|
}
|
|
}
|
|
|
|
dataFile->Save();
|
|
delete dataFile;
|
|
|
|
return true;
|
|
}
|
|
|
|
void CMW4GameEdApp::LoadObjectives()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
Check_Object(theApp.resourceWindow->objectInformation);
|
|
Check_Object(Connection::Local);
|
|
Check_Object(EntityManager::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *childEntity;
|
|
|
|
while((childEntity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(childEntity);
|
|
if (childEntity->IsDerivedFrom(MechWarrior4::Objective::DefaultData))
|
|
{
|
|
MechWarrior4::Objective* obj;
|
|
obj = Cast_Object(MechWarrior4::Objective*,childEntity);
|
|
|
|
Page *page = theApp.resourceWindow->objectInformation->SetPage("Content\\Editor\\Waypoints\\ObjectiveMarker\\ObjectiveMarker.data");
|
|
Check_Object(page);
|
|
page->SetEntry("ObjectiveMarker", "ObjectiveMarker");
|
|
page = theApp.resourceWindow->objectInformation->GetPage("ObjectiveMarker");
|
|
Check_Object(page);
|
|
DynamicMemoryStream entity_stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
Tool::Instance->ConstructCreateMessage(
|
|
&entity_stream,
|
|
page,
|
|
&entity_id
|
|
);
|
|
|
|
entity_stream.Rewind();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
Entity *entity = Entity::CreateEntity(
|
|
&entity_stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
//Make some initial assignments for the entity
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(entity);
|
|
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
entity->instanceName = "EditorObjectiveMarker_";
|
|
char string[32];
|
|
entity->instanceName += itoa(theApp.resourceWindow->numEntitiesAdded++,string,10);
|
|
|
|
EditorObjectiveMarker* objMarker;
|
|
objMarker = Cast_Object(EditorObjectiveMarker*, entity);
|
|
|
|
objMarker->objective = obj;
|
|
objMarker->GetElement()->SetAlwaysCullMode();
|
|
objMarker->GetElement()->Sync();
|
|
|
|
Map::Instance->UpdateZone(objMarker);
|
|
}
|
|
}
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsSnapobjectstoterrain()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
Point3D point;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
|
|
LinearMatrix4D matrix(true);
|
|
Point3D target_in_world;
|
|
|
|
matrix=entity->GetLocalToParent();
|
|
point = entity->GetLocalToWorld();
|
|
point.y = theApp.displayWindow->GetMapPointVertical(point.x,point.z,Entity::CanBeWalkedOnFlag,entity);
|
|
// point.y= GetMapY(point.x,point.z);
|
|
CEditorEntityData *exdata=theApp.GetEntityData(entity);
|
|
Verify(exdata);
|
|
point.y+=exdata->VOffset;
|
|
|
|
matrix.BuildTranslation(point);
|
|
entity->SetNewLocalToParent(matrix);
|
|
entity->SyncMatrices(true);
|
|
|
|
target_in_world = entity->GetLocalToWorld();
|
|
|
|
if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
|
|
{
|
|
EditorPathNode* node;
|
|
node = Cast_Object(EditorPathNode*,entity);
|
|
node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = target_in_world;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
|
|
{
|
|
EditorBoundaryNode* node;
|
|
node = Cast_Object(EditorBoundaryNode*,entity);
|
|
theApp.missionBoundary[node->index].x = target_in_world.x;
|
|
theApp.missionBoundary[node->index].y = target_in_world.z;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
|
|
{
|
|
EditorLatticeNode* node;
|
|
node = Cast_Object(EditorLatticeNode*,entity);
|
|
node->railNode->Location(target_in_world);
|
|
node->railNode->UpdateRadiusPointData();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
CEditorEntityData *
|
|
CMW4GameEdApp::GetEntityData(Entity *entity)
|
|
|
|
{
|
|
int i;
|
|
int lastspot=m_ExtraDataList.GetLength();
|
|
|
|
for(i=0;i<lastspot;i++)
|
|
{
|
|
if(m_ExtraDataList[i]->entity==entity) return m_ExtraDataList[i];
|
|
}
|
|
|
|
CEditorEntityData *tmpdat=new CEditorEntityData;
|
|
Register_Pointer(tmpdat);
|
|
tmpdat->entity=entity;
|
|
m_ExtraDataList.SetLength(lastspot+1);
|
|
m_ExtraDataList[lastspot]=tmpdat;
|
|
|
|
return tmpdat;
|
|
}
|
|
|
|
|
|
//
|
|
// These two functions are to allow hot keys for setting/recalling camera positions
|
|
// They are currently setup for Ctrl-0 thru Ctrl-9 to set and 0 - 9 to recall.
|
|
//
|
|
void CMW4GameEdApp::OnSetNumberedCameraPosition (UINT nID)
|
|
{
|
|
ASSERT(nID >= ID_SET_CAMERA_POS_0);
|
|
ASSERT(nID <= ID_SET_CAMERA_POS_9);
|
|
if (nID > ID_SET_CAMERA_POS_9 || nID < ID_SET_CAMERA_POS_0)
|
|
return;
|
|
// Since we do math on these they have to be sequential
|
|
ASSERT(
|
|
(ID_SET_CAMERA_POS_0 == (ID_SET_CAMERA_POS_1 - 1)) &&
|
|
(ID_SET_CAMERA_POS_1 == (ID_SET_CAMERA_POS_2 - 1)) &&
|
|
(ID_SET_CAMERA_POS_2 == (ID_SET_CAMERA_POS_3 - 1)) &&
|
|
(ID_SET_CAMERA_POS_3 == (ID_SET_CAMERA_POS_4 - 1)) &&
|
|
(ID_SET_CAMERA_POS_4 == (ID_SET_CAMERA_POS_5 - 1)) &&
|
|
(ID_SET_CAMERA_POS_5 == (ID_SET_CAMERA_POS_6 - 1)) &&
|
|
(ID_SET_CAMERA_POS_6 == (ID_SET_CAMERA_POS_7 - 1)) &&
|
|
(ID_SET_CAMERA_POS_7 == (ID_SET_CAMERA_POS_8 - 1)) &&
|
|
(ID_SET_CAMERA_POS_8 == (ID_SET_CAMERA_POS_9 - 1)));
|
|
|
|
m_4DCameraBookmark[nID - ID_SET_CAMERA_POS_0] = Player::Instance->GetLocalToWorld();
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnGotoNumberedCameraPosition(UINT nID)
|
|
{
|
|
ASSERT(nID >= ID_GOTO_CAMERA_POS_0);
|
|
ASSERT(nID <= ID_GOTO_CAMERA_POS_9);
|
|
if (nID > ID_GOTO_CAMERA_POS_9 || nID < ID_GOTO_CAMERA_POS_0)
|
|
return;
|
|
// Since we do math on these they have to be sequential
|
|
ASSERT(
|
|
(ID_GOTO_CAMERA_POS_0 == (ID_GOTO_CAMERA_POS_1 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_1 == (ID_GOTO_CAMERA_POS_2 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_2 == (ID_GOTO_CAMERA_POS_3 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_3 == (ID_GOTO_CAMERA_POS_4 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_4 == (ID_GOTO_CAMERA_POS_5 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_5 == (ID_GOTO_CAMERA_POS_6 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_6 == (ID_GOTO_CAMERA_POS_7 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_7 == (ID_GOTO_CAMERA_POS_8 - 1)) &&
|
|
(ID_GOTO_CAMERA_POS_8 == (ID_GOTO_CAMERA_POS_9 - 1)));
|
|
|
|
Point3D newCameraPosition;
|
|
YawPitchRoll newCameraOrientation;
|
|
|
|
newCameraOrientation = m_4DCameraBookmark[nID - ID_GOTO_CAMERA_POS_0];
|
|
newCameraPosition = m_4DCameraBookmark[nID - ID_GOTO_CAMERA_POS_0];
|
|
|
|
if (newCameraPosition.x < -(theApp.displayWindow->mapX*0.5f))
|
|
newCameraPosition.x = -(theApp.displayWindow->mapX*0.5f)+1.0f;
|
|
else if (newCameraPosition.x > (theApp.displayWindow->mapX*0.5f))
|
|
newCameraPosition.x = (theApp.displayWindow->mapX*0.5f) - 1.0f;
|
|
|
|
if (newCameraPosition.z < -(theApp.displayWindow->mapZ*0.5f))
|
|
newCameraPosition.z = -(theApp.displayWindow->mapZ*0.5f)+1.0f;
|
|
else if (newCameraPosition.z > (theApp.displayWindow->mapZ*0.5f))
|
|
newCameraPosition.z = (theApp.displayWindow->mapZ*0.5f) - 1.0f;
|
|
|
|
m_4DCameraBookmark[nID - ID_GOTO_CAMERA_POS_0].BuildTranslation(newCameraPosition);
|
|
m_4DCameraBookmark[nID - ID_GOTO_CAMERA_POS_0].BuildRotation(newCameraOrientation);
|
|
|
|
Player::Instance->SetNewLocalToParent(m_4DCameraBookmark[nID - ID_GOTO_CAMERA_POS_0]);
|
|
Player::Instance->SyncMatrices(true);
|
|
theApp.overviewWindow->DrawWindow();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void CMW4GameEdApp::UpdateCameraMenus(int index)
|
|
{
|
|
CString strFormatString, strMenuString;
|
|
strFormatString.LoadString(IDS_CAMERA_NAME_FORMAT);
|
|
|
|
HMENU hMenu = GetMenu(theApp.m_pMainWnd->GetSafeHwnd());
|
|
ASSERT(hMenu);
|
|
|
|
if (hMenu)
|
|
{
|
|
|
|
//
|
|
// If this assert goes off, you have to make sure that the call to GetSubMenu below has the proper position for the
|
|
// tools menu
|
|
//
|
|
ASSERT(GetMenuItemCount(hMenu) == 6);
|
|
HMENU hMenuTools = GetSubMenu(hMenu, APP_MENU_TOOLS);
|
|
ASSERT(hMenuTools);
|
|
if (hMenuTools)
|
|
{
|
|
//
|
|
// If this assert goes off change the nPosition parameter below to point to the CameraSavedPositions item in the menu
|
|
// Don't forget separators
|
|
ASSERT(GetMenuItemCount(hMenuTools) == 18);
|
|
HMENU hMenuCameraPositions = GetSubMenu(hMenuTools, TOOLS_MENU_CAMERA_POSITIONS);
|
|
ASSERT(hMenuCameraPositions);
|
|
ASSERT(GetMenuItemCount(hMenuCameraPositions)== 3);
|
|
HMENU hMenuSave, hMenuGoto, hMenuName;
|
|
hMenuGoto = GetSubMenu(hMenuCameraPositions, 0);
|
|
hMenuSave = GetSubMenu(hMenuCameraPositions, 1);
|
|
hMenuName = GetSubMenu(hMenuCameraPositions, 2);
|
|
ASSERT(hMenuName && hMenuSave && hMenuName);
|
|
if (hMenuGoto && hMenuSave && hMenuName)
|
|
{
|
|
int i = 0;
|
|
// See if we are doing the whole list (index == -1) or just a single one
|
|
ASSERT(index >= -1 && index <= 9);
|
|
if (index >= 0)
|
|
{
|
|
i = index; // count from index and only do one
|
|
index++;
|
|
}
|
|
else
|
|
{
|
|
index = 10; // count from 0 to 9
|
|
}
|
|
//
|
|
// Now change the camera menus that are displayed in order to make them more usable
|
|
//
|
|
for (; i < index; i++) // index is now the max slot to count to
|
|
{
|
|
strMenuString.Format((LPCSTR) strFormatString, i, m_DefCameraName[i]);
|
|
|
|
ModifyMenu(hMenuSave, ID_SET_CAMERA_POS_0 + i, MF_BYCOMMAND | MF_STRING ,ID_SET_CAMERA_POS_0 + i, (LPCSTR) strMenuString);
|
|
ModifyMenu(hMenuGoto, ID_GOTO_CAMERA_POS_0 + i, MF_BYCOMMAND | MF_STRING ,ID_GOTO_CAMERA_POS_0 + i, (LPCSTR) strMenuString);
|
|
ModifyMenu(hMenuName, ID_NAME_CAMERA_POS_0 + i, MF_BYCOMMAND | MF_STRING ,ID_NAME_CAMERA_POS_0 + i, (LPCSTR) strMenuString);
|
|
}
|
|
if (theApp.m_pMainWnd)
|
|
theApp.m_pMainWnd->DrawMenuBar();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CMW4GameEdApp::FixPaths()
|
|
{
|
|
|
|
Check_Object(Map::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Adept::Entity *entity;
|
|
|
|
Point3D target_in_world;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
|
|
|
|
target_in_world = entity->GetLocalToWorld();
|
|
|
|
if (entity->IsDerivedFrom(EditorPathNode::DefaultData))
|
|
{
|
|
EditorPathNode* node;
|
|
node = Cast_Object(EditorPathNode*,entity);
|
|
node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = target_in_world;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
else if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
|
|
{
|
|
EditorBoundaryNode* node;
|
|
node = Cast_Object(EditorBoundaryNode*,entity);
|
|
theApp.missionBoundary[node->index].x = target_in_world.x;
|
|
theApp.missionBoundary[node->index].y = target_in_world.z;
|
|
node->UpdateLinkPointData();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::MakeObjectsTileBased()
|
|
{
|
|
|
|
Check_Object(Map::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Adept::Entity *entity;
|
|
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
|
|
if (entity->IsDerivedFrom(Building::DefaultData) ||
|
|
entity->IsDerivedFrom(Turret::DefaultData) ||
|
|
entity->IsDerivedFrom(Cultural::DefaultData) )
|
|
{
|
|
if(entity->IsDerivedFrom(Cultural::DefaultData) || !entity->IsMultiTile() )
|
|
{
|
|
entity->BindToTile();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::DeleteBoundaryNodes()
|
|
{
|
|
|
|
Check_Object(Map::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Adept::Entity *entity;
|
|
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
|
|
if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData))
|
|
{
|
|
Map::Instance->RemoveChild(entity);
|
|
NameTable::Instance->RemoveEntry(entity->objectID);
|
|
NameTable::Instance->IsValid();
|
|
delete Cast_Object(Stuff::Plug *, entity);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CMW4GameEdApp::MakeObjectsZoneBased()
|
|
{
|
|
Check_Object(Map::Instance);
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Adept::Entity *entity;
|
|
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
|
|
|
|
if (entity->IsDerivedFrom(Building::DefaultData) ||
|
|
entity->IsDerivedFrom(Turret::DefaultData) ||
|
|
entity->IsDerivedFrom(Cultural::DefaultData)
|
|
)
|
|
{
|
|
entity->BindToZone();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::OnEditPaste()
|
|
{
|
|
|
|
StopMultiPlace();
|
|
|
|
Stuff::NotationFile clipboard("Content\\MW4Editor.clipboard");
|
|
|
|
Stuff::NotationFile::PageIterator *pageit=clipboard.MakePageIterator();
|
|
Stuff::Page *page;
|
|
|
|
CSelectionList::Instance->ClearSelectionList();
|
|
|
|
while((page=pageit->ReadAndNext())!=NULL)
|
|
{
|
|
Stuff::DynamicMemoryStream stream;
|
|
ReplicatorID entity_id = ReplicatorID::Null;
|
|
|
|
FileDependencies dummy;
|
|
FileDependencies *parent = Resource::ParentFileDependencies;
|
|
Resource::ParentFileDependencies = &dummy;
|
|
|
|
Tool::Instance->ConstructCreateMessage(&stream,page,&entity_id);
|
|
stream.Rewind();
|
|
|
|
Entity::CreateMessage *message = Cast_Pointer(Entity::CreateMessage *, stream.GetPointer());
|
|
int array_index = NameTable::DefaultArray;
|
|
page->GetEntry("ArrayIndex", &array_index);
|
|
MString namestr(page->GetName());
|
|
MakeNameUnique(&namestr);
|
|
message->nameID = NameTable::Instance->AddEntry(namestr, array_index);
|
|
NameTable::Instance->IsValid();
|
|
entity_id = Connection::Local->GetNextReplicatorID();
|
|
|
|
Entity *entity = Entity::CreateEntity(
|
|
&stream,
|
|
&entity_id,
|
|
false
|
|
);
|
|
Check_Object(entity);
|
|
|
|
|
|
Check_Object(EntityManager::Instance);
|
|
EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
|
|
|
|
|
|
entity->SetPropType(Entity::MissionPropType);
|
|
Map::Instance->AddChild(entity);
|
|
MLRTexturePool::Instance->LoadImages();
|
|
|
|
Resource::ParentFileDependencies = parent;
|
|
CSelectionList::Instance->AddSelection(entity);
|
|
|
|
}
|
|
theApp.instanceWindow->ResetInstanceLists();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnEditCopy()
|
|
{
|
|
|
|
StopMultiPlace();
|
|
Stuff::NotationFile clipboard("Content\\MW4Editor.clipboard");
|
|
clipboard.DeleteAllPages();
|
|
|
|
CSelectionNode* selected;
|
|
ChainIteratorOf<CSelectionNode*> selections(&CSelectionList::Instance->selectionList);
|
|
|
|
while ((selected = selections.ReadAndNext()) != NULL)
|
|
{
|
|
if (!(selected->IsDerivedFrom(EditorWaypoint::DefaultData) ||
|
|
selected->IsDerivedFrom(EditorPathNode::DefaultData) ||
|
|
selected->IsDerivedFrom(EditorLatticeNode::DefaultData)))
|
|
{
|
|
Page *page=clipboard.AddPage(selected->selectedEntity->instanceName);
|
|
selected->selectedEntity->SaveInstanceText(page);
|
|
page->SetEntry("ArrayIndex", NameTableEntry::GetArrayIndex(selected->selectedEntity->objectID));
|
|
}
|
|
}
|
|
theApp.toolBar->EnableButton(ID_EDIT_PASTE);
|
|
|
|
clipboard.Save();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnEditCut()
|
|
{
|
|
OnEditCopy();
|
|
theApp.instanceWindow->OnObjRemoveinstance();
|
|
|
|
}
|
|
|
|
|
|
void CMW4GameEdApp::MakeObjectNamesUnique()
|
|
{
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
|
|
|
|
if( entity->IsDerivedFrom(Vehicle::DefaultData) ||
|
|
entity->IsDerivedFrom(Building::DefaultData) ||
|
|
entity->IsDerivedFrom(AI::DefaultData) ||
|
|
entity->IsDerivedFrom(DropZone::DefaultData) ||
|
|
entity->IsDerivedFrom(EditorMovementPath::DefaultData) ||
|
|
entity->IsDerivedFrom(Objective::DefaultData)
|
|
)
|
|
if(!IsNameUnique(entity->instanceName,entity))
|
|
{
|
|
NameTable::Instance->RemoveEntry(entity->objectID);
|
|
NameTable::Instance->IsValid();
|
|
MakeNameUnique(&entity->instanceName);
|
|
|
|
if(entity->IsDerivedFrom(Vehicle::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::VehicleArray);
|
|
else if(entity->IsDerivedFrom(Building::DefaultData) || entity->IsDerivedFrom(Cultural::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::BuildingArray);
|
|
else if(entity->IsDerivedFrom(NavPoint::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::NavArray);
|
|
else if(entity->IsDerivedFrom(AI::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::AIArray);
|
|
else if(entity->IsDerivedFrom(DropZone::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::DropZoneArray);
|
|
else if(entity->IsDerivedFrom(EditorMovementPath::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::PathArray);
|
|
else if(entity->IsDerivedFrom(Objective::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::ObjectiveArray);
|
|
else if(entity->IsDerivedFrom(NonCom::DefaultData))
|
|
NameTable::Instance->AddEntry(entity, NameTable::BuildingArray);
|
|
else STOP(("Unknown Array"));
|
|
NameTable::Instance->IsValid();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
bool CMW4GameEdApp::IsNameUnique(char *name,Entity *ignore)
|
|
{
|
|
if(name==NULL) return false;
|
|
|
|
ChainIteratorOf<Entity *> iterator(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
|
|
ChainIteratorOf<Entity *> subiterator(&Map::Instance->childEntityChain);
|
|
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if(entity!=ignore && entity->instanceName && entity->instanceName==name)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CMW4GameEdApp::MakeNameUnique(MString *str)
|
|
{
|
|
|
|
CString full_name((char *)*str);
|
|
CString base_name,final_name,numstr;
|
|
|
|
int idx;
|
|
|
|
idx=full_name.ReverseFind('_');
|
|
|
|
if(idx==-1)
|
|
{
|
|
base_name=full_name;
|
|
}
|
|
else
|
|
{
|
|
base_name=full_name.Left(idx);
|
|
}
|
|
|
|
final_name=full_name;
|
|
|
|
while(!IsNameUnique((char *)(LPCSTR)final_name))
|
|
{
|
|
final_name.Format("%s_%04i",base_name,(rand()*10000)/RAND_MAX);
|
|
}
|
|
|
|
*str=(char *)(LPCSTR)final_name;
|
|
}
|
|
|
|
void CMW4GameEdApp::RotateSel90CCW()
|
|
{
|
|
CSelectionNode* selected;
|
|
ChainIteratorOf<CSelectionNode*> selections(&CSelectionList::Instance->selectionList);
|
|
|
|
while ((selected = selections.ReadAndNext()) != NULL)
|
|
{
|
|
|
|
LinearMatrix4D matrix(true);
|
|
|
|
Point3D pos;
|
|
YawPitchRoll rot;
|
|
|
|
matrix = selected->selectedEntity->GetLocalToParent();
|
|
rot = matrix;
|
|
rot.yaw -= 90.0f/Degrees_Per_Radian;
|
|
matrix.BuildRotation(rot);
|
|
selected->selectedEntity->SetNewLocalToParent(matrix);
|
|
selected->selectedEntity->SyncMatrices(true);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::RotateSel90CW()
|
|
{
|
|
|
|
CSelectionNode* selected;
|
|
ChainIteratorOf<CSelectionNode*> selections(&CSelectionList::Instance->selectionList);
|
|
|
|
while ((selected = selections.ReadAndNext()) != NULL)
|
|
{
|
|
|
|
LinearMatrix4D matrix(true);
|
|
|
|
Point3D pos;
|
|
YawPitchRoll rot;
|
|
|
|
matrix = selected->selectedEntity->GetLocalToParent();
|
|
rot = matrix;
|
|
rot.yaw += 90.0f/Degrees_Per_Radian;
|
|
matrix.BuildRotation(rot);
|
|
selected->selectedEntity->SetNewLocalToParent(matrix);
|
|
selected->selectedEntity->SyncMatrices(true);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//*******************************************************************************************
|
|
//
|
|
//*******************************************************************************************
|
|
// This function is called while searching for mech property notation files. Since
|
|
// .data is not used exclusively for these, I wanted to add filter out basic.data and similar files
|
|
// also not that you can not use the allsubdirectories flag with mechs since they have .data
|
|
// files in the armaturedata subdirectories
|
|
BOOL _stdcall MechPropertyFilesFilter(LPCSTR szCurrentFileName)
|
|
{
|
|
if (!stricmp(szCurrentFileName, "basic.data"))
|
|
{
|
|
return FALSE;
|
|
}
|
|
// also don't allow .data files from _destroyed mechs
|
|
|
|
LPCSTR pszTemp = strrchr(szCurrentFileName, '_');
|
|
if (pszTemp && !stricmp(pszTemp, "_destroyed.data"))
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
void CMW4GameEdApp::OnToolsMechProperties()
|
|
{
|
|
|
|
CDlgObjectProperties dlgOP;
|
|
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * pPropertiesToEdit =
|
|
dlgOP.CreatePropertiesToEditArray(13,
|
|
efloat , "gamedata\\TiltDegree", "",
|
|
efloat , "gamedata\\TiltSpeed", "",
|
|
efloat , "gamedata\\MinStandTransitionSpeed", "",
|
|
efloat , "gamedata\\MaxGimpSpeed", "",
|
|
efloat , "gamedata\\Acceleration", "",
|
|
efloat , "gamedata\\Decceleration", "",
|
|
efloat , "gamedata\\MaxSpeed", "",
|
|
efloat , "gamedata\\MinSpeed", "",
|
|
efloat , "gamedata\\MaxReverseSpeed", "",
|
|
efloat , "gamedata\\MinReverseSpeed", "",
|
|
efloat , "gamedata\\FullStopTurnRate", "",
|
|
efloat , "gamedata\\TopSpeedTurnRate", "",
|
|
efloat , "gamedata\\MaxHeat", ""
|
|
|
|
);
|
|
dlgOP.SetFileNameToSearchSubdirectoriesFor("*.data");
|
|
dlgOP.SetFileFilterCallBack(MechPropertyFilesFilter);
|
|
dlgOP.SetObjectFilesDirectory("content\\mechs");
|
|
dlgOP.SetPropertyListToEdit(pPropertiesToEdit);
|
|
dlgOP.ShowFullObjectNames(TRUE);
|
|
dlgOP.ShowFullPropertyName(FALSE);
|
|
|
|
dlgOP.DoModal();
|
|
free(pPropertiesToEdit);
|
|
}
|
|
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsMechProperties(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
|
|
//*******************************************************************************************
|
|
//
|
|
//*******************************************************************************************
|
|
void CMW4GameEdApp::OnToolsWeaponsProperties()
|
|
{
|
|
|
|
CDlgObjectProperties dlgOP;
|
|
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * pPropertiesToEdit =
|
|
dlgOP.CreatePropertiesToEditArray(11,
|
|
eint , "gamedata\\AmmoPerShot", "",
|
|
efloat , "gamedata\\DamageAmount", "",
|
|
efloat , "gamedata\\Heat", "",
|
|
eVector3D, "gamedata\\InitialLinearAcceleration", "",
|
|
eVector3D, "gamedata\\InitialLinearVelocity", "",
|
|
eint , "gamedata\\MaxAmmo", "",
|
|
efloat , "gamedata\\MaxDistance", "",
|
|
efloat , "gamedata\\NumFire", "",
|
|
efloat , "gamedata\\ReloadTime", "",
|
|
efloat , "gamedata\\Tonage", "",
|
|
eint , "gamedata\\TotalSlotsTaken", "");
|
|
dlgOP.SetFileNameToSearchSubdirectoriesFor("*.data");
|
|
dlgOP.SetFileFilterCallBack(NULL);
|
|
dlgOP.SetObjectFilesDirectory("content\\weaponsubsystems");
|
|
dlgOP.SetPropertyListToEdit(pPropertiesToEdit);
|
|
dlgOP.ShowFullObjectNames(FALSE);
|
|
dlgOP.ShowFullPropertyName(FALSE);
|
|
|
|
dlgOP.DoModal();
|
|
free(pPropertiesToEdit);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsWeaponsProperties(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
//*******************************************************************************************
|
|
//
|
|
//*******************************************************************************************
|
|
// This function is called while searching for mech property notation files. Since
|
|
// .data is not used exclusively for these, I wanted to add filter out basic.data and similar files
|
|
// also not that you can not use the allsubdirectories flag with mechs since they have .data
|
|
// files in the armaturedata subdirectories
|
|
BOOL _stdcall MechPropertyFilesFilter2(LPCSTR szCurrentFileName)
|
|
{
|
|
// also don't allow .data files from _destroyed mechs
|
|
|
|
LPCSTR pszTemp = strrchr(szCurrentFileName, '_');
|
|
if (pszTemp && !stricmp(pszTemp, "_destroyed.damage"))
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
//*******************************************************************************************
|
|
//
|
|
//*******************************************************************************************
|
|
void CMW4GameEdApp::OnToolsArmorBalancing()
|
|
{
|
|
|
|
CDlgObjectBalance dlgOB;
|
|
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * pPropertiesToEdit =
|
|
dlgOB.CreatePropertiesToEditArray(13,
|
|
efloat , "joint_luarm\\MaxArmorValue", "L.Arm",
|
|
efloat , "joint_ruarm\\MaxArmorValue", "R.Arm",
|
|
efloat , "joint_luleg\\MaxArmorValue", "L.Leg",
|
|
efloat , "joint_ruleg\\MaxArmorValue", "R.Leg",
|
|
efloat , "joint_head\\MaxArmorValue", "Head",
|
|
efloat , "joint_righttorsofront\\MaxArmorValue", "R.T.F.",
|
|
efloat , "joint_righttorsorear\\MaxArmorValue", "R.T.R.",
|
|
efloat , "joint_lefttorsofront\\MaxArmorValue", "L.T.F.",
|
|
efloat , "joint_lefttorsorear\\MaxArmorValue", "L.T.R.",
|
|
efloat , "joint_hipbelow\\MaxArmorValue", "C.T.F.",
|
|
efloat , "joint_centertorsorear\\MaxArmorValue", "C.T.R.",
|
|
efloat , "joint_specialone\\MaxArmorValue", "Sp. 1",
|
|
efloat , "joint_specialtwo\\MaxArmorValue", "Sp. 2"
|
|
);
|
|
|
|
|
|
dlgOB.SetFileNameToSearchSubdirectoriesFor("*.damage");
|
|
dlgOB.SetFileFilterCallBack(MechPropertyFilesFilter2);
|
|
dlgOB.SetObjectFilesDirectory("content\\mechs");
|
|
|
|
dlgOB.SetHorizontalControlSize(60);
|
|
dlgOB.ShowPageOnly();
|
|
dlgOB.SetPropertyListToEdit(pPropertiesToEdit);
|
|
dlgOB.SetAllowPresentToChange(FALSE);
|
|
dlgOB.ShowFullObjectNames(FALSE);
|
|
dlgOB.ShowFullPropertyName(FALSE);
|
|
|
|
dlgOB.DoModal();
|
|
free(pPropertiesToEdit);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsArmorBalancing(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
|
|
|
|
//*******************************************************************************************
|
|
//
|
|
//*******************************************************************************************
|
|
void CMW4GameEdApp::OnToolsWeaponsBalancing()
|
|
{
|
|
|
|
CDlgObjectBalance dlgOB;
|
|
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * pPropertiesToEdit =
|
|
dlgOB.CreatePropertiesToEditArray(6,
|
|
efloat , "gamedata\\DamageAmount", "",
|
|
efloat , "gamedata\\HeatToDeal", "",
|
|
efloat , "gamedata\\SplashRadius", "",
|
|
efloat , "gamedata\\ReloadTime", "",
|
|
efloat , "gamedata\\Heat", "",
|
|
efloat , "gamedata\\Tonage", "");
|
|
|
|
|
|
dlgOB.SetFileNameToSearchSubdirectoriesFor("*.data");
|
|
dlgOB.SetFileFilterCallBack(NULL);
|
|
dlgOB.SetObjectFilesDirectory("content\\weaponsubsystems");
|
|
dlgOB.SetPropertyListToEdit(pPropertiesToEdit);
|
|
dlgOB.ShowFullObjectNames(FALSE);
|
|
dlgOB.ShowFullPropertyName(FALSE);
|
|
|
|
dlgOB.DoModal();
|
|
free(pPropertiesToEdit);
|
|
}
|
|
|
|
void CMW4GameEdApp::OnUpdateToolsWeaponsBalancing(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
// Alignment menu is setup whenever it is shown
|
|
//
|
|
//
|
|
void CMW4GameEdApp::OnUpdateDefaultAlignmentMenu(CCmdUI* pCmdUI)
|
|
{
|
|
#define OUDAM_MAX_MENU_ITEMS_FOR_ALIGNMENT 10
|
|
|
|
// determine if this is the popup menu
|
|
if (pCmdUI->m_pSubMenu)
|
|
{
|
|
// if so then we need to reinitialize the menu contents
|
|
// I have seen the removemenu calls fail and this can create an infinite loop if
|
|
// we don't protect against it.
|
|
int nMax = OUDAM_MAX_MENU_ITEMS_FOR_ALIGNMENT;
|
|
|
|
while (pCmdUI->m_pSubMenu->GetMenuItemCount() && nMax--)
|
|
{
|
|
pCmdUI->m_pSubMenu->RemoveMenu(0, MF_BYPOSITION);
|
|
}
|
|
for (int i = 0; i < Entity::LastAlignment && i < OUDAM_MAX_MENU_ITEMS_FOR_ALIGNMENT; i++)
|
|
{
|
|
pCmdUI->m_pSubMenu->AppendMenu(0, ID_TOOLS_DEF_ALIGNMENT_1 + i, Entity::AlignmentAsciiToText(i));
|
|
//
|
|
// Set the appropriate check
|
|
//
|
|
}
|
|
pCmdUI->m_pSubMenu->CheckMenuItem(ID_TOOLS_DEF_ALIGNMENT_1 + m_nDefaultAlignmentForPlacedObjects, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Changes the current alignment default for newly placed items
|
|
//
|
|
void CMW4GameEdApp::OnDefaultAlignmentMenu(UINT uiID)
|
|
{
|
|
if (uiID >= ID_TOOLS_DEF_ALIGNMENT_1 && uiID <= ID_TOOLS_DEF_ALIGNMENT_10)
|
|
{
|
|
int nTemp = uiID - ID_TOOLS_DEF_ALIGNMENT_1;
|
|
if (nTemp < Entity::LastAlignment)
|
|
{
|
|
m_nDefaultAlignmentForPlacedObjects = nTemp;
|
|
}
|
|
}
|
|
}
|
|
void CMW4GameEdApp::OnToolsPlacewithmap()
|
|
{
|
|
resourceWindow->DisperseWithBitmap();
|
|
}
|
|
|
|
void AddToBuildFile(CString missionName,CString map_name)
|
|
{
|
|
SetCurrentDirectory(Working_Directory);
|
|
|
|
CString missionPath = "Content\\Missions\\";
|
|
missionPath += missionName;
|
|
|
|
CString map_buildpath;
|
|
CString map_shortpath;
|
|
CString map_longpath;
|
|
CString mission_instancepath;
|
|
CString mission_buildpath;
|
|
map_shortpath.Format("Maps\\%s\\%s.build",map_name,map_name);
|
|
mission_buildpath.Format("Missions\\%s\\%s.build",missionName,missionName);
|
|
mission_instancepath.Format("Missions\\%s\\%s.instance",missionName,missionName);
|
|
map_longpath="Content\\"+map_shortpath;
|
|
|
|
if(!gos_DoesFileExist(map_shortpath))
|
|
{
|
|
CString str;
|
|
str.Format("Resources\\Maps\\%s.mw4",map_name);
|
|
NotationFile mapfile(map_longpath);
|
|
Page *page=mapfile.AddPage(str);
|
|
str.Format("maps\\%s\\%s.data",map_name,map_name);
|
|
page->SetEntry("data",str);
|
|
str.Format("%s was missing and was created",map_longpath);
|
|
MessageBox(NULL,str,"Missing File",MB_OK);
|
|
mapfile.Save();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// Enter the data in the build file
|
|
Verify(gos_DoesFileExist("Content\\MechWarrior4.build"));
|
|
|
|
if(gos_FileReadOnly("Content\\MechWarrior4.build"))
|
|
{
|
|
gos_FileSetReadWrite("Content\\MechWarrior4.build");
|
|
MessageBox(NULL,"MechWarrior4.build has been made writeable and modified","File Modification",MB_OK);
|
|
}
|
|
|
|
_mkdir(LPCTSTR(missionPath));
|
|
|
|
SPEW(("scottjan","Make sure I never get to touch any code again okay?"));
|
|
|
|
Stuff::NotationFile build_file("Content\\MechWarrior4.build");
|
|
Page *core_page = build_file.FindPage("");
|
|
if (core_page)
|
|
{
|
|
Check_Object(core_page);
|
|
Page::NoteIterator *core_notes = core_page->MakeNoteIterator();
|
|
Check_Object(core_notes);
|
|
Note *core_note;
|
|
while ((core_note = core_notes->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(core_note);
|
|
NotationFile map_file;
|
|
core_note->GetEntry(&map_file);
|
|
Page *maps_page = map_file.FindPage("");
|
|
Check_Object(maps_page);
|
|
Page::NoteIterator *map_notes = maps_page->MakeNoteIterator();
|
|
Check_Object(map_notes);
|
|
Note *map_note;
|
|
|
|
NotationFile mission_file;
|
|
map_note=maps_page->FindNote(map_shortpath);
|
|
if(!map_note)
|
|
{
|
|
map_note=maps_page->AddNote(map_shortpath);
|
|
Check_Object(map_note);
|
|
}
|
|
else
|
|
{
|
|
map_note->GetEntry(&mission_file);
|
|
}
|
|
|
|
Page *mission_page = mission_file.SetPage(NULL);
|
|
NotationFile mission_note;
|
|
mission_page->SetEntry(mission_buildpath,&mission_note);
|
|
|
|
map_note->SetEntry(&mission_file);
|
|
core_note->SetEntry(&map_file);
|
|
}
|
|
}
|
|
|
|
build_file.Save();
|
|
|
|
|
|
mission_buildpath="Content\\"+mission_buildpath;
|
|
NotationFile mission_build(mission_buildpath);
|
|
Page *mission_page;
|
|
CString misrespath;
|
|
misrespath.Format("Resources\\Missions\\%s.mw4",missionName);
|
|
mission_build.DeleteAllPages();
|
|
mission_page=mission_build.AddPage(misrespath);
|
|
mission_page->SetEntry("instance",mission_instancepath);
|
|
mission_build.Save();
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::DisperseCulturals()
|
|
{
|
|
RemoveCulturals();
|
|
resourceWindow->DisperseWithBitmap(true);
|
|
}
|
|
|
|
void CMW4GameEdApp::RemoveCulturals()
|
|
{
|
|
Adept::Entity *entity;
|
|
ChainIteratorOf<Entity*> iterator(&culturalList);
|
|
iterator.First();
|
|
while((entity = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Map::Instance->RemoveChild(entity);
|
|
NameTable::Instance->RemoveEntry(entity->objectID);
|
|
NameTable::Instance->IsValid();
|
|
delete Cast_Object(Stuff::Plug *, entity);
|
|
}
|
|
theApp.instanceWindow->ResetInstanceLists();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsDisperseculturalwithbitmap()
|
|
{
|
|
DisperseCulturals();
|
|
}
|
|
|
|
void CMW4GameEdApp::OnToolsRemoveculturals()
|
|
{
|
|
RemoveCulturals();
|
|
|
|
}
|
|
|
|
void CMW4GameEdApp::RemoveEditorObjects (void)
|
|
{
|
|
ChainIteratorOf<Entity*> entities(&Map::Instance->childEntityChain);
|
|
Entity *entity;
|
|
Point3D loc1(20,0,20),loc2(0,0,0);
|
|
LinearMatrix4D matrix1 = LinearMatrix4D::Identity;
|
|
LinearMatrix4D matrix2 = LinearMatrix4D::Identity;
|
|
matrix1.BuildTranslation(loc1);
|
|
matrix2.BuildTranslation(loc2);
|
|
|
|
while ((entity = entities.ReadAndNext()) != NULL)
|
|
{
|
|
if (entity->IsDerivedFrom (EditorMovementPath::DefaultData))
|
|
{
|
|
entity->GetElement()->SetNeverCullMode ();
|
|
entity->SetNewLocalToParent(matrix1);
|
|
entity->SyncMatrices(true);
|
|
entity->SetCollisionMask (Entity::NeverCollidesMask);
|
|
Map::Instance->UpdateZone(entity);
|
|
// Map::Instance->RemoveChild (entity);
|
|
}
|
|
else if (entity->IsDerivedFrom (EditorPathNode::DefaultData))
|
|
{
|
|
entity->GetElement()->SetNeverCullMode ();
|
|
entity->SetNewLocalToParent(matrix1);
|
|
entity->SyncMatrices(true);
|
|
entity->SetCollisionMask (Entity::NeverCollidesMask);
|
|
Map::Instance->UpdateZone(entity);
|
|
// Map::Instance->RemoveChild (entity);
|
|
}
|
|
else if (entity->IsDerivedFrom (EditorBoundaryNode::DefaultData))
|
|
{
|
|
entity->GetElement()->SetNeverCullMode ();
|
|
entity->SetNewLocalToParent(matrix1);
|
|
entity->SyncMatrices(true);
|
|
entity->SetCollisionMask (Entity::NeverCollidesMask);
|
|
Map::Instance->UpdateZone(entity);
|
|
// Map::Instance->RemoveChild (entity);
|
|
}
|
|
else if (entity->IsDerivedFrom (EditorDropNode::DefaultData))
|
|
{
|
|
entity->GetElement()->SetNeverCullMode ();
|
|
entity->SetNewLocalToParent(matrix1);
|
|
entity->SyncMatrices(true);
|
|
entity->SetCollisionMask (Entity::NeverCollidesMask);
|
|
Map::Instance->UpdateZone(entity);
|
|
// Map::Instance->RemoveChild (entity);
|
|
}
|
|
else if (entity->IsDerivedFrom (EditorLight::DefaultData))
|
|
{
|
|
entity->GetElement()->SetNeverCullMode ();
|
|
entity->SetNewLocalToParent(matrix1);
|
|
entity->SyncMatrices(true);
|
|
entity->SetCollisionMask (Entity::NeverCollidesMask);
|
|
Map::Instance->UpdateZone(entity);
|
|
// Map::Instance->RemoveChild (entity);
|
|
}
|
|
else if (entity->IsDerivedFrom (EditorObjectiveMarker::DefaultData))
|
|
{
|
|
entity->GetElement()->SetNeverCullMode ();
|
|
entity->SetNewLocalToParent(matrix1);
|
|
entity->SyncMatrices(true);
|
|
entity->SetCollisionMask (Entity::NeverCollidesMask);
|
|
Map::Instance->UpdateZone(entity);
|
|
// Map::Instance->RemoveChild (entity);
|
|
}
|
|
}
|
|
|
|
}
|