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.
454 lines
11 KiB
C++
454 lines
11 KiB
C++
// MapShifterDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "MapShifter.h"
|
|
#include "MapShifterDlg.h"
|
|
#include "ProgDlg.h"
|
|
|
|
#include <Adept\Adept.hpp>
|
|
#include <Adept\Zone.hpp>
|
|
using namespace Stuff;
|
|
|
|
|
|
extern bool __stdcall gos_DoesFileExist( const char* FileName );
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMapShifterDlg dialog
|
|
|
|
CMapShifterDlg::CMapShifterDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CMapShifterDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CMapShifterDlg)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
|
}
|
|
|
|
void CMapShifterDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CMapShifterDlg)
|
|
DDX_Control(pDX, IDC_MAPLIST, m_MapList);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CMapShifterDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CMapShifterDlg)
|
|
ON_WM_PAINT()
|
|
ON_WM_QUERYDRAGICON()
|
|
ON_BN_CLICKED(IDC_SHIFT, OnShift)
|
|
ON_BN_CLICKED(IDC_SELECTALL, OnSelectall)
|
|
ON_BN_CLICKED(IDC_CLEAR, OnClear)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMapShifterDlg message handlers
|
|
|
|
BOOL CMapShifterDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
SetIcon(m_hIcon, TRUE); // Set big icon
|
|
SetIcon(m_hIcon, FALSE); // Set small icon
|
|
|
|
int mapcount=0;
|
|
|
|
WIN32_FIND_DATA file_data;
|
|
HANDLE mission_search = FindFirstFile("Content\\Missions\\*.*" , &file_data);
|
|
|
|
if(mission_search != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
CString map_name(file_data.cFileName);
|
|
if(map_name.CompareNoCase(".") && map_name.CompareNoCase(".."))
|
|
m_MapList.AddString(file_data.cFileName);
|
|
mapcount++;
|
|
}
|
|
while (FindNextFile(mission_search,&file_data));
|
|
}
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
// If you add a minimize button to your dialog, you will need the code below
|
|
// to draw the icon. For MFC applications using the document/view model,
|
|
// this is automatically done for you by the framework.
|
|
|
|
void CMapShifterDlg::OnPaint()
|
|
{
|
|
if (IsIconic())
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
|
|
|
|
// Center icon in client rectangle
|
|
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
CRect rect;
|
|
GetClientRect(&rect);
|
|
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
|
|
// Draw the icon
|
|
dc.DrawIcon(x, y, m_hIcon);
|
|
}
|
|
else
|
|
{
|
|
CDialog::OnPaint();
|
|
}
|
|
}
|
|
|
|
HCURSOR CMapShifterDlg::OnQueryDragIcon()
|
|
{
|
|
return (HCURSOR) m_hIcon;
|
|
}
|
|
|
|
void CMapShifterDlg::OnCancel()
|
|
{
|
|
|
|
// CDialog::OnCancel();
|
|
}
|
|
|
|
void CMapShifterDlg::OnOK()
|
|
{
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
|
|
void ConvertMoveRectToZeroCenter (const char *filename,Stuff::Scalar xoffset,Stuff::Scalar zoffset)
|
|
{
|
|
if (!filename)
|
|
return;
|
|
|
|
DWORD *file;
|
|
DWORD filesize;
|
|
DWORD *data;
|
|
int numrects,i;
|
|
struct TRect
|
|
{
|
|
Scalar left,right,top,bottom;
|
|
int building;
|
|
bool vertical;
|
|
};
|
|
TRect *rects;
|
|
|
|
if(!gos_DoesFileExist(filename)) return;
|
|
gos_GetFile(filename,(unsigned char **) &file,&filesize);
|
|
data = file;
|
|
numrects = *((int*) data);
|
|
data++;
|
|
rects = (TRect *) data;
|
|
|
|
Stuff::FileStream stream(filename,Stuff::FileStream::WriteOnly);
|
|
stream << numrects;
|
|
|
|
for (i=0;i<numrects;i++)
|
|
{
|
|
rects->bottom += zoffset;
|
|
rects->top += zoffset;
|
|
rects->left += xoffset;
|
|
rects->right += xoffset;
|
|
stream.WriteBytes (rects,sizeof (TRect));
|
|
rects++;
|
|
}
|
|
|
|
gos_Free (file);
|
|
}
|
|
|
|
|
|
void CMapShifterDlg::ProcessMap(CString mis_name)
|
|
{
|
|
CProgDlg progdlg;
|
|
progdlg.Create(IDD_PROGDLG,this);
|
|
CString tmpstr;
|
|
tmpstr="Processing ";
|
|
tmpstr+=mis_name;
|
|
progdlg.SetWindowText(mis_name);
|
|
progdlg.ShowWindow(SW_SHOW);
|
|
progdlg.m_Msg="Collecting Mission Info";
|
|
progdlg.UpdateData(FALSE);
|
|
|
|
CString mis_path,con_path,inst_path,map_inst_path,map_name,mbounds_name,wbounds_name;
|
|
mis_path.Format("Content\\Missions\\%s",mis_name);
|
|
inst_path=mis_path+"\\"+mis_name+".instance";
|
|
|
|
NotationFile instance_file((LPCSTR)inst_path);
|
|
Page *page=instance_file.SetPage(mis_name);
|
|
const char *tstr;
|
|
tstr="";
|
|
page->GetEntry("Map",&tstr);
|
|
map_inst_path=tstr;
|
|
map_name=map_inst_path;
|
|
map_name=map_name.Left(map_name.ReverseFind('.'));
|
|
map_name=map_name.Mid(map_name.ReverseFind('\\')+1);
|
|
|
|
tstr="";
|
|
page->GetEntry("MissionBounds",&tstr);
|
|
mbounds_name=tstr;
|
|
|
|
tstr="";
|
|
page->GetEntry("WarningBounds",&tstr);
|
|
wbounds_name=tstr;
|
|
|
|
|
|
Scalar map_size_x,map_size_z;
|
|
GetMapSize(map_name,&map_size_x,&map_size_z);
|
|
|
|
Point3D org_offset;
|
|
org_offset.y=0.0f;
|
|
org_offset.x=-map_size_x*0.5f;
|
|
org_offset.z=-map_size_z*0.5f;
|
|
|
|
|
|
|
|
con_path=mis_path+"\\"+mis_name+".contents";
|
|
NotationFile contents_file((LPCSTR)con_path);
|
|
NotationFile::PageIterator *entity_page_list = contents_file.MakePageIterator();
|
|
Check_Object(entity_page_list);
|
|
|
|
progdlg.m_Msg="Offsetting Entities";
|
|
progdlg.UpdateData(FALSE);
|
|
|
|
Page *entity_page;
|
|
Point3D trans,newtrans;
|
|
while ((entity_page = entity_page_list->ReadAndNext()) != NULL)
|
|
{
|
|
entity_page->GetEntry("Translation",&trans);
|
|
newtrans=trans;
|
|
newtrans+=org_offset;
|
|
entity_page->SetEntry("Translation",newtrans);
|
|
}
|
|
|
|
contents_file.Save();
|
|
|
|
|
|
progdlg.m_Msg="Offsetting Paths";
|
|
progdlg.UpdateData(FALSE);
|
|
//Do Paths
|
|
CString paths_path;
|
|
paths_path=mis_path+"\\Paths";
|
|
|
|
WIN32_FIND_DATA file_data;
|
|
HANDLE path_search = FindFirstFile(paths_path+"\\*.contents" , &file_data);
|
|
|
|
if(path_search != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
{
|
|
NotationFile path_file((paths_path+"\\"+file_data.cFileName));
|
|
Page *path_page=path_file.GetPage("Path");
|
|
Note *point_note;
|
|
Check_Object(path_page);
|
|
|
|
Page::NoteIterator *path_list=path_page->MakeNoteIterator();
|
|
|
|
while ((point_note = path_list->ReadAndNext()) != NULL)
|
|
{
|
|
point_note->GetEntry(&trans);
|
|
newtrans=trans;
|
|
newtrans+=org_offset;
|
|
point_note->SetEntry(newtrans);
|
|
}
|
|
|
|
path_file.Save();
|
|
}
|
|
while (FindNextFile(path_search,&file_data));
|
|
}
|
|
|
|
progdlg.m_Msg="Offsetting DropZones";
|
|
progdlg.UpdateData(FALSE);
|
|
//Do Paths
|
|
CString drop_path;
|
|
paths_path=mis_path+"\\dropzones";
|
|
|
|
NotationFile pstart_file((paths_path+"\\"+"PlayerStart.contents"));
|
|
|
|
Page *drop_page=pstart_file.GetPage("DropPoints");
|
|
Note *point_note;
|
|
Check_Object(drop_page);
|
|
|
|
Page::NoteIterator *drop_list=drop_page->MakeNoteIterator();
|
|
|
|
while ((point_note = drop_list->ReadAndNext()) != NULL)
|
|
{
|
|
point_note->GetEntry(&trans);
|
|
newtrans=trans;
|
|
newtrans+=org_offset;
|
|
point_note->SetEntry(newtrans);
|
|
}
|
|
|
|
pstart_file.Save();
|
|
|
|
|
|
progdlg.m_Msg="Offsetting Graph";
|
|
progdlg.UpdateData(FALSE);
|
|
//Do Graphs
|
|
CString graph_path;
|
|
graph_path=mis_path+"\\"+mis_name+"Graph.data";
|
|
NotationFile graph_file((LPCSTR)graph_path);
|
|
NotationFile::PageIterator *node_list = graph_file.MakePageIterator();
|
|
Check_Object(node_list);
|
|
|
|
Page *node_page;
|
|
while ((node_page = node_list->ReadAndNext()) != NULL)
|
|
{
|
|
CString page_name=node_page->GetName();
|
|
|
|
if(!page_name.Left(strlen("Node")).CompareNoCase("Node"))
|
|
{
|
|
node_page->GetEntry("Location",&trans);
|
|
newtrans=trans;
|
|
newtrans+=org_offset;
|
|
node_page->SetEntry("Location",newtrans);
|
|
}
|
|
}
|
|
|
|
graph_file.Save();
|
|
|
|
progdlg.m_Msg="Offsetting Bounds";
|
|
progdlg.UpdateData(FALSE);
|
|
/*
|
|
//Do Bounds
|
|
CString mbounds_path,wbounds_path;
|
|
mbounds_path.Format("%s\\%s",mis_path,mbounds_name);
|
|
wbounds_path.Format("%s\\%s",mis_path,wbounds_name);
|
|
|
|
FileStream bound_file;
|
|
DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > bound;
|
|
|
|
int i;
|
|
if(mbounds_name.GetLength()>0 && gos_DoesFileExist((LPCSTR)mbounds_path))
|
|
{
|
|
bound_file.Open((LPCSTR)mbounds_path,FileStream::ReadOnly);
|
|
MemoryStreamIO_Read(&bound_file, &bound);
|
|
bound_file.Close();
|
|
for (i = 0; i < bound.GetLength(); i++)
|
|
{
|
|
bound[i].x += org_offset.x/Adept::c_ZoneSize;
|
|
bound[i].y += org_offset.z/Adept::c_ZoneSize;
|
|
}
|
|
|
|
bound_file.Open((LPCSTR)mbounds_path,FileStream::WriteOnly);
|
|
MemoryStreamIO_Write(&bound_file, &bound);
|
|
bound_file.Close();
|
|
}
|
|
|
|
if(wbounds_name.GetLength()>0 && gos_DoesFileExist((LPCSTR)wbounds_path))
|
|
{
|
|
bound_file.Open((LPCSTR)wbounds_path,FileStream::ReadOnly);
|
|
MemoryStreamIO_Read(&bound_file, &bound);
|
|
bound_file.Close();
|
|
|
|
for (i = 0; i < bound.GetLength(); i++)
|
|
{
|
|
bound[i].x += org_offset.x/Adept::c_ZoneSize;
|
|
bound[i].y += org_offset.z/Adept::c_ZoneSize;
|
|
}
|
|
|
|
bound_file.Open((LPCSTR)wbounds_path,FileStream::WriteOnly);
|
|
MemoryStreamIO_Write(&bound_file, &bound);
|
|
bound_file.Close();
|
|
}
|
|
*/
|
|
progdlg.m_Msg="Offsetting Rect Grid";
|
|
progdlg.UpdateData(FALSE);
|
|
//Do Rect Grid
|
|
CString move_rect_name;
|
|
move_rect_name=mis_path+"\\"+mis_name+"RectGrid.data";
|
|
ConvertMoveRectToZeroCenter(move_rect_name,org_offset.x,org_offset.z);
|
|
|
|
progdlg.m_Msg="Offsetting Lights";
|
|
progdlg.UpdateData(FALSE);
|
|
//Do Lights
|
|
CString light_path;
|
|
light_path=mis_path+"\\"+mis_name+".lights";
|
|
|
|
NotationFile lights_file((LPCSTR)light_path);
|
|
NotationFile::PageIterator *light_list = lights_file.MakePageIterator();
|
|
Check_Object(light_list);
|
|
|
|
Page *light_page;
|
|
Note *pos_note;
|
|
while ((light_page = light_list->ReadAndNext()) != NULL)
|
|
{
|
|
pos_note=light_page->FindNote("Position");
|
|
if(pos_note!=NULL)
|
|
{
|
|
pos_note->GetEntry(&trans);
|
|
newtrans=trans;
|
|
newtrans+=org_offset;
|
|
pos_note->SetEntry(newtrans);
|
|
}
|
|
}
|
|
|
|
lights_file.Save();
|
|
}
|
|
|
|
|
|
void CMapShifterDlg::OnShift()
|
|
{
|
|
int selCount = m_MapList.GetSelCount();
|
|
int* selected = new int [selCount];
|
|
m_MapList.GetSelItems(selCount,selected);
|
|
for (int i = 0; i < selCount; i++)
|
|
{
|
|
CString text;
|
|
m_MapList.GetText(selected[i],text);
|
|
ProcessMap(text);
|
|
}
|
|
|
|
delete selected;
|
|
}
|
|
|
|
void CMapShifterDlg::OnSelectall()
|
|
{
|
|
for (int i = 0; i < m_MapList.GetCount(); i++)
|
|
m_MapList.SetSel(i,true);
|
|
}
|
|
|
|
void CMapShifterDlg::OnClear()
|
|
{
|
|
for (int i = 0; i < m_MapList.GetCount(); i++)
|
|
m_MapList.SetSel(i,false);
|
|
}
|
|
|
|
void CMapShifterDlg::GetMapSize(CString map_name, float *xsize, float *zsize)
|
|
{
|
|
CString map_path;
|
|
|
|
map_path.Format("Content\\Maps\\%s",map_name);
|
|
|
|
int rows,cols;
|
|
|
|
rows=cols=0;
|
|
|
|
//count rows
|
|
CString erf_name;
|
|
erf_name.Format("%s\\%cA.erf",map_path,'A'+rows);
|
|
|
|
while(gos_DoesFileExist(erf_name))
|
|
{
|
|
rows++;
|
|
erf_name.Format("%s\\%cA.erf",map_path,'A'+rows);
|
|
}
|
|
|
|
erf_name.Format("%s\\A%c.erf",map_path,'A'+cols);
|
|
|
|
while(gos_DoesFileExist(erf_name))
|
|
{
|
|
cols++;
|
|
erf_name.Format("%s\\A%c.erf",map_path,'A'+cols);
|
|
}
|
|
|
|
*xsize=cols*Adept::c_ZoneSize;
|
|
*zsize=rows*Adept::c_ZoneSize;
|
|
|
|
}
|