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

1378 lines
33 KiB
C++

// ObjectManager.cpp: implementation of the ObjectManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MW4GameEd2.h"
#include "ObjectManager.h"
#include "EdGUIObject.h"
#include "ObjCreateInfo.h"
#include "NVGameObject.h"
#include "GUICamera.h"
#include "GUIDropZone.h"
#include "GUILattice.h"
#include "EdObjective.h"
#include "ObjPanelDlg.h"
#include "MissionPropsPanel.h"
#include "FogPropertiesPanel.h"
#include "FogColorProps.h"
#include "GameTypesPanel.h"
#include "ObjectiveListDlg.h"
#include "ObjProps.h"
#include "GUILight.h"
#include "GUIFXGenerator.h"
#include <GameOS\ToolOS.hpp>
#include <Stuff\Stuff.hpp>
#include <direct.h>
#include "CameraController.h"
#include"UndoManager.h"
#define GetTme() (GetTickCount()/1000.0)
const char *ObjectManager::MPGameTypeNames[] =
{
"SinglePlayer",
"Destruction",
"TeamDestruction",
"Attrition",
"TeamAttrition",
"CaptureTheFlag",
"KingOfTheHill",
"TeamKingOfTheHill",
"StealTheBacon",
"CaptureBase" ,
"Escort",
"MasterTrial",
"SiegeAssault",
"CustomDestruction" ,
"CustomTeamDestruction" ,
"CustomAttrition" ,
"CustomTeamAttrition",
"CustomCaptureTheFlag" ,
"CustomKingOfTheHill",
"CustomTeamKingOfTheHill" ,
"CustomTerritories" ,
"CustomStealTheBacon",
"CustomCaptureBase" ,
"CustomDestroyObjective",
"CustomEscort" ,
"CustomMasterTrial",
"CustomSiegeAssault",
"CustomCampaign",
"CustomUndefined"
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ObjectManager::ObjectManager():GUIObjectList("Map")
, m_CameraController(0)
{
MapLoaded=false;
Modified=false;
DefaultAlignment=0;
SourceMission="";
SetName(CString("Map"));
AddInfo=NULL;
MissionBound=NULL;
WarningBound=NULL;
Lattice=NULL;
UndoMan=NULL;
LLight=NULL;
MakeBounds();
TagFlags=TAG_NAME;
MapSize=Point3D(100,0,100);
m_CameraController = new CameraController(*this);
TerrainTexture.CreateSolid(10,10,ImgRGBColor(128,128,128),ITYPE_RGB,24);
HField.CreateSolid(10,10,ImgRGBColor(0,0,128),ITYPE_RGB,24);
SlopeMap.CreateSolid(10,10,ImgRGBColor(128,0,0),ITYPE_RGB,24);
}
void ObjectManager::DeleteAllObjects()
{
GUIObjectList::DeleteAllObjects();
MissionBound=NULL;
WarningBound=NULL;
Lattice=NULL;
LLight=NULL;
MakeBounds();
}
void ObjectManager::MakeBounds()
{
Verify(MissionBound==NULL);
Verify(WarningBound==NULL);
MissionBound=new GUIBound("Mission Bounds");
WarningBound=new GUIBound("Warning Bounds");
AddObject(MissionBound);
AddObject(WarningBound);
}
ObjectManager::~ObjectManager()
{
while(GetObjectCount()>3) //need to leave the boundsand lattice
DeleteObject(0);
if(UndoMan) {delete UndoMan; UndoMan=NULL;}
if (m_CameraController != 0)
{
delete m_CameraController;
m_CameraController = 0;
}
}
void ObjectManager::DeleteObject(int i)
{
Verify(i<GetObjectCount());
if(GetObject(i)==MissionBound ||
GetObject(i)==WarningBound ||
GetObject(i)==Lattice ||
GetObject(i)==LLight
) return;
GUIObjectList::DeleteObject(i);
}
void ObjectManager::ClearSelection()
{
int i;
EdGUIObject *gobj;
EdGUIObject::DeSelect();
for(i=0;i<GetObjectCount();i++)
{
gobj=GetObject(i);
gobj->DeSelect();
}
}
bool ObjectManager::CutSelection()
{
if(!CopySelection()) return false;
DeleteSelection();
return true;
}
bool ObjectManager::CopySelection()
{
ClipBoard.DeleteAllObjects();
Point3D low,high;
GetSelectionExtents(&low,&high);
CopyPos.x=low.x+(high.x-low.x)*0.5f;
CopyPos.z=low.z+(high.z-low.z)*0.5f;
CopyPos.y=0.0f;
try
{
CopySelectionToList(&ClipBoard);
}
catch(...)
{
ClipBoard.DeleteAllObjects();
return false;
}
return true;
}
void ObjectManager::PasteClipBoardAt(Point3D pos)
{
if(ClipBoard.GetObjectCount()<=0) return;
Point3D offset;
offset.x=pos.x-CopyPos.x;
offset.y=0.0f;
offset.z=pos.z-CopyPos.z;
PasteClipBoard(offset);
}
void ObjectManager::PasteClipBoard(Point3D offset)
{
if(ClipBoard.GetObjectCount()<=0) return;
int i;
EdGUIObject *gobj;
Modify();
AddCommand *addcom=NULL;
ClearSelection();
for(i=0;i<ClipBoard.GetObjectCount();i++)
{
gobj=ClipBoard.GetObject(i)->Clone();
gobj->Select();
AddObject(gobj);
if(!addcom) addcom=new AddCommand(gobj);
else
addcom->Attach(new AddCommand(gobj));
}
Verify(addcom!=NULL);
UndoMan->AddCommand(addcom);
SPEW(("tsteinke","Offset Paste relative to Viewwindow, but safely"));
OffsetSelection(offset);
if(ClipBoard.GetObjectCount()>0) Modify();
}
EdGUIObject *ObjectManager::AddNode(Point3D &pnt,DWORD *show_flag,bool insert)
{
EdGUIObject *ret;
if((ret=AddNodeIfSelected(pnt,insert))==NULL)
{
GUIPath *path;
path=new GUIPath(CString("Path"));
AddObject(path);
path->AddNodeAtEnd(pnt);
*show_flag|=SHOW_PATHS;
ret=path;
}
return ret;
}
EdGUIObject *ObjectManager::AddGameObject(ObjCreateInfo *inf,EdGameObject *gmeobj,DWORD *show_flag,Point3D &pnt)
{
CString base_name=inf->Path;
base_name=base_name.Left(base_name.ReverseFind('.'));
base_name=base_name.Mid(base_name.ReverseFind('\\')+1);
gmeobj->SetPos(pnt);
gmeobj->SetSnapToGround(true);
gmeobj->BuildFrom(inf->Path,base_name);
gmeobj->SetAlignment(DefaultAlignment);
AddObject(gmeobj);
gmeobj->MakeVisible(show_flag);
return gmeobj;
}
void ObjectManager::SetObjectName(EdGUIObject *gobj,CString &name)
{
if(gobj==MissionBound ||
gobj==WarningBound ||
gobj==Lattice ||
gobj==LLight ) return;
Verify(InTree(gobj));
UndoMan->AddCommand(new RenameCommand(gobj));
gobj->SetName(name);
}
EdGUIObject *ObjectManager::AddAt(ObjCreateInfo *inf,AddCommand **com,DWORD *show_flag,bool flag,Point3D pnt,YawPitchRoll rot)
{
Verify(IsLoaded());
if(inf==NULL) return NULL;
Modify();
EdGUIObject *gobj=NULL;
switch(inf->CreateType)
{
case ObjCreateInfo::OT_GAMEOBJ:
gobj=AddGameObject(inf,new EdGameObject(),show_flag,pnt);
break;
case ObjCreateInfo::OT_NVGAMEOBJ:
gobj=AddGameObject(inf,new NVGameObject(),show_flag,pnt);
break;
case ObjCreateInfo::OT_NODE:
gobj=AddNode(pnt,show_flag,flag);
break;
case ObjCreateInfo::OT_DROPZONE:
gobj=AddDropZone(pnt);
*show_flag|=SHOW_DROPZONES;
break;
case ObjCreateInfo::OT_CAMERA:
gobj=AddCamera(pnt);
*show_flag|=SHOW_CAMERASHIPS;
break;
case ObjCreateInfo::OT_LIGHT:
gobj=AddLight(inf->SubType,pnt);
*show_flag|=SHOW_LIGHTS;
break;
case ObjCreateInfo::OT_FX:
gobj=AddFX(pnt);
*show_flag|=SHOW_FX;
break;
case ObjCreateInfo::OT_CLIPBOARD:
PasteClipBoardAt(pnt);
break;
}
if(gobj!=NULL)
{
UnitQuaternion quatrot;
quatrot=rot;
gobj->SetRot(quatrot);
if(*com==NULL)
{
*com=new AddCommand(gobj);
}
else
{
(*com)->Attach(new AddCommand(gobj));
}
}
return gobj;
}
EdGUIObject *ObjectManager::AddAt(AddCommand **com,DWORD *show_flag,bool flag,Point3D pnt,YawPitchRoll rot)
{
return AddAt(AddInfo,com,show_flag,flag,pnt,rot);
}
bool ObjectManager::AddAt(Point3D &pnt,DWORD *show_flag,bool flag)
{
if(!IsLoaded()) return true;
Modify();
AddCommand *com=NULL;
EdGUIObject *gobj;
try
{
gobj=AddAt(&com,show_flag,flag,pnt);
}
catch(...)
{
return false;
}
if(gobj) UndoMan->AddCommand(com);
return true;
}
EdGUIObject *ObjectManager::AddLight(int subt,Point3D &pnt)
{
GUILight *lgt=NULL;
switch(subt)
{
case ObjCreateInfo::LST_POINT:
lgt=new GUIPointLight("Point_Light",pnt);
break;
case ObjCreateInfo::LST_SPOT:
lgt=new GUISpotLight("Spot_Light",pnt);
break;
case ObjCreateInfo::LST_INFINITE:
lgt=new GUIInfiniteLight("Infinite_Light");
break;
case ObjCreateInfo::LST_AMBIENT:
lgt=new GUIAmbientLight("Ambient_Light");
break;
default:
STOP(("Invalid Light Type"));
}
lgt->Build();
AddObject(lgt);
return lgt;
}
EdGUIObject *ObjectManager::AddCamera(Point3D &pnt)
{
GUICamera *cam=new GUICamera(CString("CameraShip"),pnt);
AddObject(cam);
return cam;
}
EdGUIObject *ObjectManager::AddFX(Point3D &pnt)
{
GUIFXGenerator *fx=new GUIFXGenerator(CString("Effect"),pnt);
AddObject(fx);
return fx;
}
EdGUIObject *ObjectManager::AddDropZone(Point3D &pnt)
{
GUIDropZone *obj=new GUIDropZone("DropZone",pnt);
AddObject(obj);
return obj;
}
void ObjectManager::SetProperties(Point3D &pnt,CWnd *parent)
{
EdGUIObject *gobj;
gobj=GetObjAtPoint(pnt);
SetProperties(gobj,parent);
}
void ObjectManager::SetProperties(EdGUIObject *gobj,CWnd *parent)
{
if(gobj!=NULL && IsLoaded())
{
CObjPanelDlg pan_dlg(parent);
UndoCommand *com=NULL;
gobj->AddPanel(&pan_dlg,&com);
pan_dlg.DoModal();
OffsetSelection(Point3D(0.0f,0.0f,0.0f)); // This will make Paths and Drop Nodes Sync up.
if(com!=NULL)
UndoMan->AddCommand(com);
}
}
void ObjectManager::SetPropertiesOfSelected(CWnd *parent)
{
int selcount=SelectionCount();
if(selcount>0)
{
UndoCommand *com=NULL;
if(selcount==1)
{
SetProperties(FindFirstSelected(),parent);
}
else
{
CObjPanelDlg pan_dlg(parent);
CObjProps mprops;
GetMultiPropsIfSelected(&mprops);
mprops.AddPanel(&pan_dlg);
if(pan_dlg.DoModal()==IDOK)
{
SetMultiPropsIfSelected(&mprops,&com);
}
}
if(com!=NULL)
UndoMan->AddCommand(com);
}
}
void ObjectManager::SaveTextInfo(NotationFile *not_file)
{
SortChildren();
GUIObjectList::SaveTextInfo(not_file);
}
void ObjectManager::LoadTextInfo()
{
SortChildren();
CString mis_name=GetName();
NotationFile not_file((LPCSTR)("Content\\Missions\\"+GetName()+"\\"+GetName()+".ini"));
Page *mis_page=not_file.FindPage((LPCSTR)mis_name);
if(!mis_page) return;
DefaultExtraData();
BuildGroup(this,mis_page);
LoadNFOFile();
}
void ObjectManager::BuildGroup(GUIObjectList *new_list,Page *group_page)
{
NotationFile mem_file;
group_page->GetEntry("Members",&mem_file);
NotationFile ::PageIterator *member_list=mem_file.MakePageIterator();
Check_Object(member_list);
Page *member_page;
member_list->First();
while((member_page=member_list->ReadAndNext())!=NULL)
{
Check_Object(member_page);
const char *tmpstr;
member_page->GetEntry("Type",&tmpstr);
CString type(tmpstr);
CString member_name(member_page->GetName());
if(!type.CompareNoCase("Group"))
{
GUIObjectList *next_list=new GUIObjectList;
next_list->SetName(member_name);
AddObject(next_list);
BuildGroup(next_list,member_page);
}
else
{
int idx=FindObjectIdxByName(member_name);
if(idx!=-1)
{
EdGUIObject *gobj=GetObject(idx);
gobj->SetInfo(member_page);
if(new_list!=this)
{
RemoveObject(gobj);
new_list->AddObject(gobj);
}
}
}
}
}
void ObjectManager::Draw(DrawInfo &dinf)
{
for(int i=0;i<GetObjectCount();i++)
GetObject(i)->Draw(dinf);
}
void ObjectManager::DrawTag(DrawInfo &dinf, unsigned long tag_flags)
{
for(int i=0;i<GetObjectCount();i++)
GetObject(i)->DrawTag(dinf,tag_flags);
}
void ObjectManager::UnGroupSelected()
{
if(!IsLoaded()) return;
UndoCommand *cmd=NULL;
GUIObjectList::UnGroupSelected(&cmd);
RemoveObject(MissionBound);
RemoveObject(WarningBound);
RemoveObject(Lattice);
RemoveObject(LLight);
PruneEmpty(&cmd);
AddObject(MissionBound);
AddObject(WarningBound);
AddObject(Lattice);
AddObject(LLight);
if(cmd) UndoMan->AddCommand(cmd);
}
int ObjectManager::GroupSelected()
{
if(!IsLoaded()) return true;
int ret;
UndoCommand *cmd=NULL;
RemoveObject(MissionBound);
RemoveObject(WarningBound);
RemoveObject(Lattice);
RemoveObject(LLight);
ret=GUIObjectList::GroupSelected(&cmd);
AddObject(MissionBound);
AddObject(WarningBound);
AddObject(Lattice);
AddObject(LLight);
if(cmd) UndoMan->AddCommand(cmd);
return ret;
}
bool ObjectManager::CanOffsetSelection(Point3D &vect)
{
Point3D tl,br,msze;
GetSelectionExtents(&tl,&br);
if((vect.x+br.x)>=(MapSize.x*0.5f) ||
(vect.z+br.z)>=(MapSize.z*0.5f) ||
(vect.x+tl.x)<(-MapSize.x*0.5f) ||
(vect.z+tl.z)<(-MapSize.z*0.5f))
return false;
return true;
}
void ObjectManager::CreateLattice()
{
if(!IsLoaded()) return;
Verify(Lattice!=NULL);
Lattice->CreateLattice((int)(MapSize.x*MapSize.z)/60000);
}
void ObjectManager::RecalcLatticeLinks()
{
if(!IsLoaded()) return;
Verify(Lattice!=NULL);
Lattice->CalcLinksOnSelected();
}
void ObjectManager::ResetBounds()
{
WarningBound->ResetTo(Point3D((-MapSize.x*0.5f)+(MapSize.x/10),0.0f,(-MapSize.z*0.5f)+(MapSize.z/10)),
Point3D((MapSize.x*0.5f)-(MapSize.x/10),0.0f,(MapSize.z*0.5f)-(MapSize.z/10)));
MissionBound->ResetTo(Point3D((-MapSize.x*0.5f)+(MapSize.x/15),0.0f,(-MapSize.z*0.5f)+(MapSize.z/15)),
Point3D((MapSize.x*0.5f)-(MapSize.x/15),0.0f,(MapSize.z*0.5f)-(MapSize.z/15)));
}
void ObjectManager::CheckAlternativeScripts()
{
for(int i=0;i<GT_TOTALGAMES;i++)
{
if(MPGames[i].Supported)
{
for(int j=0;j<MPGames[i].ScriptTotal;j++)
{
CheckAlternativeScript(MPGames[i].ScriptPaths[j]);
}
}
}
}
void ObjectManager::CheckAlternativeScript(CString sname)
{
if(sname=="") return;
char errMessage[500];
CString errstr;
CString filename;
CString cmdline,line;
CString spath="Content\\Missions\\"+GetName()+"\\scripts\\"+sname+".abl";
ABL::ABLError error;
long missionScriptHandle = ABL::ABLi_preProcess((char *)(LPCSTR)spath, &error,NULL,NULL);
if (missionScriptHandle < 0)
{
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;
}
}
void ObjectManager::SaveToReg()
{
int tdat;
CRect rct;
CString name="ObjectMan";
tdat=GetDefaultAlignment(); gos_SaveDataToRegistry((char *)(LPCSTR)(name+"DefaultAlignment"),&tdat,sizeof(tdat));
gos_SaveDataToRegistry((char *)(LPCSTR)(name+"Tags"),&TagFlags,sizeof(TagFlags));
m_CameraController->SaveToReg();
// bool res=GetCameraController()->GetAnimatedCamera();
// gos_SaveDataToRegistry((char *)(LPCSTR)(name+"Animated Camera"),&res,sizeof(res));
}
void ObjectManager::LoadFromReg()
{
int tdat;
unsigned long size;
CRect rct;
CString name="ObjectMan";
size=sizeof(tdat);
gos_LoadDataFromRegistry((char *)(LPCSTR)(name+"DefaultAlignment"),&tdat,&size);
if(size) SetDefaultAlignment(tdat);
size=sizeof(TagFlags);
gos_LoadDataFromRegistry((char *)(LPCSTR)(name+"Tags"),&TagFlags,&size);
m_CameraController->LoadFromReg();
// size = sizeof(m_AnimatedCamera);
// gos_LoadDataFromRegistry((char *)(LPCSTR)(name+"Animated Camera"),&m_AnimatedCamera,&size);
}
Stuff::Point3D ObjectManager::GetMapSize() const
{
return (MapSize);
}
void ObjectManager::ResetCamera()
{
if (m_CameraController != 0)
{
m_CameraController->Reset();
}
}
void ObjectManager::RotateSelection( UnitQuaternion &pnt)
{
GUIObjectList::RotateSelection(pnt);
}
void ObjectManager::OffsetSelection(Point3D &vct)
{
if(CanOffsetSelection(vct))
{
GUIObjectList::OffsetSelection(vct);
}
}
void ObjectManager::SavePosForUndo()
{
UndoCommand *com=NULL;
SavePosIfSelected(&com);
SaveRotIfSelected(&com);
if(com!=NULL) UndoMan->AddCommand(com);
}
bool ObjectManager::CanUndo()
{
if(UndoMan==NULL) return false;
return UndoMan->CanUndo();
}
bool ObjectManager::CanRedo()
{
if(UndoMan==NULL) return false;
return UndoMan->CanRedo();
}
void ObjectManager::Undo() { if(UndoMan->CanUndo()) {UndoMan->Undo(); SyncData();} }
void ObjectManager::Redo() { if(UndoMan->CanRedo()) {UndoMan->Redo(); SyncData();} }
void ObjectManager::DeleteSelection()
{
UndoCommand *cmd=NULL;
DeleteSelected(&cmd);
if(cmd!=NULL)
UndoMan->AddCommand(cmd);
}
void ObjectManager::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
GUIObjectList::AddPanel(pnl,cmd);
pnl->AddPanel((CPanelDlg *)new CMissionPropsPanel(this,cmd,pnl));
pnl->AddPanel((CPanelDlg *)new CFogColorProps(this,cmd,pnl));
pnl->AddPanel((CPanelDlg *)new CFogPropertiesPanel(this,cmd,pnl));
pnl->NameOverride="Mission Properties";
}
void ObjectManager::EditObjectives(CWnd *parent)
{
UndoCommand *com=NULL;
CObjectiveListDlg dlg(this,&com,parent);
dlg.DoModal();
if(com!=NULL)
UndoMan->AddCommand(com);
}
void ObjectManager::SaveUndoCommand(UndoCommand *cmd)
{
UndoMan->AddCommand(cmd);
}
void ObjectManager::AddObjective()
{
if(!IsLoaded()) return;
ObjectiveList.AddObject(new EdObjective("NewObjective"));
}
void ObjectManager::LoadNFOFile()
{
int i;
for(i=0;i<GT_TOTALGAMES;i++)
{
MPGames[i].Alignment=MPGames[i].Team=1;
MPGames[i].Supported=false;
}
CString nfo_fname="Resource\\UserMissions\\"+GetName()+".nfo";
if(! gos_DoesFileExist(nfo_fname))
{
MPGames[GT_SinglePlayer].Supported=true;
return;
}
NotationFile nfo_file(nfo_fname);
Page *page=nfo_file.FindPage("ruleset");
int idx=0;
if(page)
{
Page::NoteIterator *ruleset_notes = page->MakeNoteIterator();
Check_Object(ruleset_notes);
Note *ruleset_note;
while ((ruleset_note = ruleset_notes->ReadAndNext()) != NULL)
{
if(!strcmpi(ruleset_note->GetName(),"type"))
{
int type;
ruleset_note->GetEntry(&type);
idx=GTTypeToEnum(type);
MPGames[idx].Supported=true;
MPGames[idx].ScriptTotal=0;
}
else if(!strcmpi(ruleset_note->GetName(),"team"))
{
ruleset_note->GetEntry(&MPGames[idx].Team);
}
else if(!strcmpi(ruleset_note->GetName(),"Alignment"))
{
ruleset_note->GetEntry(&MPGames[idx].Alignment);
}
else if(!strcmpi(ruleset_note->GetName(),"ScriptName"))
{
const char *tcc;
CString tpath;
ruleset_note->GetEntry(&tcc);
tpath=tcc;
tpath=tpath.Left(tpath.GetLength()-4);
tpath=tpath.Mid(tpath.ReverseFind('\\')+1);
MPGames[idx].ScriptPaths[MPGames[idx].ScriptTotal++]=tpath;
}
}
}
}
void ObjectManager::CreateNFOFile()
{
CString nfo_fname="Resource\\UserMissions\\"+GetName()+".nfo";
NotationFile nfo_file(nfo_fname, NotationFile::Raw, true);
Page *page=nfo_file.SetPage("");
page->SetEntry("!include","Content\\GameTypes.h");
page->SetEntry("!preservecase","true");
page=nfo_file.SetPage("info");
page->SetEntry("author","YourNameHere");
page->SetEntry("info","Standard Mission");
page->SetEntry("link","www.yourwebsite.com");
page->SetEntry("longname",GetName());
nfo_file.Save();
}
void ObjectManager::UpdateNFOFile()
{
CString nfo_fname="Resource\\UserMissions\\"+GetName()+".nfo";
if(! gos_DoesFileExist(nfo_fname)) CreateNFOFile();
NotationFile nfo_file(nfo_fname);
Page *page=nfo_file.SetPage("ruleset");
page->DeleteAllNotes();
Stuff::Page *bang_page = nfo_file.SetPage("");
bang_page->AppendEntry("!include", "Content\\GameTypes.h");
bang_page->AppendEntry("!preservecase", "true");
Stuff::Page *sc_page = nfo_file.SetPage("scenarios");
for(int i=0;i<GT_TOTALGAMES;i++)
{
CString type="$("+GTEnumToType((MPGameTypes)i)+")";
if(MPGames[i].Supported)
{
page->AddNote("type")->SetEntry(type);
page->AddNote("Teams")->SetEntry(MPGames[i].Team);
page->AddNote("Alignment")->SetEntry(MPGames[i].Alignment);
for(int sidx=0;sidx<MPGames[i].ScriptTotal;sidx++)
{
page->AddNote("scriptname")->SetEntry("Content\\Missions\\"+GetName()+"\\Scripts\\"+MPGames[i].ScriptPaths[sidx]+".abl");
}
}
if(MPGames[i].AddScenario && i!=GT_SinglePlayer)
{
Page::NoteIterator *notes=sc_page->MakeNoteIterator();
Note *note;
bool noadd=false;
while(note=(Note *)notes->ReadAndNext())
{
NotationFile tfile;
note->GetEntry(&tfile);
Page *page=tfile.GetPage("server");
if(page)
{
int itype;
page->GetEntry("ruleset",&itype);
if(GTTypeToEnum(itype)==i) noadd=true;
}
}
if(!noadd)
{
NotationFile sc;
Page *serverpage=sc.SetPage("server");
serverpage->SetEntry("name",GetName());
serverpage->SetEntry("ruleset",type);
if(IsTeamGame((MPGameTypes)i))
serverpage->SetEntry("TeamAllowed",1);
else
serverpage->SetEntry("TeamAllowed",0);
if(IsTeamGame((MPGameTypes)i))
serverpage->SetEntry("TeamCount",MPGames[i].Team);
else
serverpage->SetEntry("TeamCount",0);
if(MPGames[i].ScriptTotal>0)
serverpage->SetEntry("ScriptName","Content\\Missions\\"+GetName()+"\\Scripts\\"+MPGames[i].ScriptPaths[0]+".abl");
/*
CString script_name="Content\\Missions\\"+GetName()+"\\Scripts\\"+GetName()+"_"+GTEnumToType((MPGameTypes)i)+".abl";
CopyFile("Content\\AblScripts\\GenericScripts\\CustomTemplate.abl",script_name,NULL);
serverpage->SetEntry("scriptname",script_name);
*/
CString str;
str.Format("%s%i",GTEnumToType((MPGameTypes)i),rand());
sc_page->SetEntry(str,&sc);
sc.IgnoreChanges();
}
}
}
nfo_file.Save();
}
CString ObjectManager::GTEnumToType(MPGameTypes type)
{
switch(type)
{
case GT_SinglePlayer :return "SinglePlayer" ; break;
case GT_StockDestruction :return "StockDestruction" ; break;
case GT_StockTeamDestruction :return "StockTeamDestruction" ; break;
case GT_StockAttrition :return "StockAttrition" ; break;
case GT_StockTeamAttrition :return "StockTeamAttrition" ; break;
case GT_StockCaptureTheFlag :return "StockCaptureTheFlag" ; break;
case GT_StockKingOfTheHill :return "StockKingOfTheHill" ; break;
case GT_StockTeamKingOfTheHill :return "StockTeamKingOfTheHill"; break;
case GT_StockTerritories :return "StockTerritories" ; break;
case GT_StockStealTheBacon :return "StockStealTheBacon" ; break;
case GT_StockCaptureBase :return "StockCaptureBase" ; break;
case GT_StockDestroyObjective :return "StockDestroyObjective"; break;
case GT_StockEscort :return "StockEscort" ; break;
case GT_StockMasterTrial :return "StockMasterTrial" ; break;
case GT_StockSiegeAssault :return "StockSiegeAssault" ; break;
case GT_StockCampaign :return "StockCampaign" ; break;
case GT_CustomDestruction :return "CustomDestruction" ; break;
case GT_CustomTeamDestruction :return "CustomTeamDestruction"; break;
case GT_CustomAttrition :return "CustomAttrition" ; break;
case GT_CustomTeamAttrition :return "CustomTeamAttrition" ; break;
case GT_CustomCaptureTheFlag :return "CustomCaptureTheFlag" ; break;
case GT_CustomKingOfTheHill :return "CustomKingOfTheHill" ; break;
case GT_CustomTeamKingOfTheHill :return "CustomTeamKingOfTheHill"; break;
case GT_CustomTerritories :return "CustomTerritories" ; break;
case GT_CustomStealTheBacon :return "CustomStealTheBacon" ; break;
case GT_CustomCaptureBase :return "CustomCaptureBase" ; break;
case GT_CustomDestroyObjective :return "CustomDestroyObjective"; break;
case GT_CustomEscort :return "CustomEscort" ; break;
case GT_CustomMasterTrial :return "CustomMasterTrial" ; break;
case GT_CustomSiegeAssault :return "CustomSiegeAssault" ; break;
case GT_CustomCampaign :return "CustomCampaign" ; break;
case GT_CustomUndefined :return "CustomUndefined" ; break;
}
return "CustomUndefined";
}
ObjectManager::MPGameTypes ObjectManager::GTTypeToEnum(int type)
{
switch(type)
{
case 0: return GT_StockDestruction ; break;
case 1 :return GT_StockTeamDestruction ; break;
case 2 :return GT_StockAttrition; break;
case 3 :return GT_StockTeamAttrition; break;
case 4 :return GT_StockCaptureTheFlag; break;
case 5 :return GT_StockKingOfTheHill; break;
case 6 :return GT_StockTeamKingOfTheHill; break;
case 7 :return GT_StockTerritories ; break;
case 8 :return GT_StockStealTheBacon ; break;
case 9 :return GT_StockCaptureBase ; break;
case 10 :return GT_StockDestroyObjective; break;
case 11 :return GT_StockEscort ; break;
case 12 :return GT_StockMasterTrial; break;
case 13 :return GT_StockSiegeAssault; break;
case 14 :return GT_StockCampaign; break;
case 15 :return GT_CustomDestruction ; break;
case 16 :return GT_CustomTeamDestruction; break;
case 17 :return GT_CustomAttrition ; break;
case 18 :return GT_CustomTeamAttrition ; break;
case 19 :return GT_CustomCaptureTheFlag; break;
case 20 :return GT_CustomKingOfTheHill ; break;
case 21 :return GT_CustomTeamKingOfTheHill; break;
case 22 :return GT_CustomTerritories; break;
case 23 :return GT_CustomStealTheBacon ; break;
case 24 :return GT_CustomCaptureBase; break;
case 25 :return GT_CustomDestroyObjective; break;
case 26 :return GT_CustomEscort; break;
case 27 :return GT_CustomMasterTrial; break;
case 28 :return GT_CustomSiegeAssault; break;
case 29 :return GT_CustomCampaign; break;
case 30 :return GT_CustomUndefined; break;
case 31 :return GT_SinglePlayer; break;
}
return GT_TOTALGAMES;
}
bool ObjectManager::AddEssentialObjects(CString &msg)
{
AddCommand *cmd=NULL;
DWORD showflag;
ObjCreateInfo inf;
bool ret=false;
CString nav_point_names[256];
int navcount=0;
CString drop_names[256];
int drop_points[256];
int dropcount=0;
int flagstoadd=0;
bool anymulti=false;
int i;
msg="The following changes have been made to this mission:\n";
for(i=0;i<GT_TOTALGAMES && !anymulti;i++) anymulti=MPGames[i].Supported;
if(!anymulti) return false; //no multiplayer games supported
nav_point_names[navcount++]="Nav Center";
drop_names[dropcount]="PlayerStart"; drop_points[dropcount++]=36;
if(MPGames[GT_StockDestruction].Supported ||
MPGames[GT_StockAttrition].Supported
)
{
}
if(MPGames[GT_StockTeamDestruction].Supported ||
MPGames[GT_StockTeamAttrition].Supported
)
{
int tval=MPGames[GT_StockTeamDestruction].Team>MPGames[GT_StockTeamAttrition].Team?MPGames[GT_StockTeamDestruction].Team:MPGames[GT_StockTeamAttrition].Team;
for(int tidx=1;tidx<=tval;tidx++)
{
CString str;
str.Format("Team %i Drop Zone",tidx);
nav_point_names[navcount++]=str;
str.Format("DropTeam%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=18;
}
}
if(MPGames[GT_StockMasterTrial].Supported)
{
for(int tidx=1;tidx<=MPGames[GT_StockMasterTrial].Team;tidx++)
{
CString str;
str.Format("Team %i Drop Zone",tidx);
nav_point_names[navcount++]=str;
str.Format("DropTeam%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=18;
}
}
if(MPGames[GT_StockSiegeAssault].Supported)
{
for(int tidx=1;tidx<=MPGames[GT_StockSiegeAssault].Team;tidx++)
{
CString str;
str.Format("Team %i Drop Zone",tidx);
nav_point_names[navcount++]=str;
str.Format("DropTeam%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=18;
}
}
if(MPGames[GT_StockCaptureTheFlag].Supported)
{
for(int tidx=1;tidx<=MPGames[GT_StockCaptureTheFlag].Team;tidx++)
{
CString str;
str.Format("Team %i Drop Zone",tidx);
nav_point_names[navcount++]=str;
str.Format("DropTeam%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=18;
str.Format("TeamCapture%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=0;
}
flagstoadd=4;
}
if(MPGames[GT_StockKingOfTheHill].Supported)
{
nav_point_names[navcount++]="The Hill";
drop_names[dropcount]="Hill"; drop_points[dropcount++]=0;
}
if(MPGames[GT_StockTeamKingOfTheHill].Supported)
{
for(int tidx=1;tidx<=MPGames[GT_StockTeamKingOfTheHill].Team;tidx++)
{
CString str;
str.Format("Team %i Drop Zone",tidx);
nav_point_names[navcount++]=str;
str.Format("DropTeam%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=18;
}
nav_point_names[navcount++]="The Hill";
drop_names[dropcount]="Hill"; drop_points[dropcount++]=0;
}
if(MPGames[GT_StockStealTheBacon].Supported)
{
nav_point_names[navcount++]="The Hill";
drop_names[dropcount]="Hill"; drop_points[dropcount++]=0;
flagstoadd=1;
}
if(MPGames[GT_StockEscort].Supported)
{
nav_point_names[navcount++]="Nav Alpha";
nav_point_names[navcount++]="Nav Beta";
nav_point_names[navcount++]="The Hill";
MPGames[GT_StockEscort].Team=4;
MPGames[GT_StockEscort].Alignment=2;
for(int tidx=1;tidx<=MPGames[GT_StockEscort].Team;tidx++)
{
CString str;
str.Format("DropTeam%i",tidx);
drop_names[dropcount]=str; drop_points[dropcount++]=18;
}
}
int nidx,pidx;
bool added=false;
for(nidx=0;nidx<navcount;nidx++)
{
EdGUIObject *new_obj=NULL;
EdGUIObject *obj=GetObjectByName(nav_point_names[nidx]);
if(obj)
{
if(!obj->GetTypeName().CompareNoCase(("NavPoint")) )
new_obj=obj;
else
{
msg+="Object \""+obj->GetName()+"\" renamed to \"";
obj->SetName("renamed_"+obj->GetName());
msg+=obj->GetName()+"\"\n";
}
}
if(!new_obj)
{
inf.CreateType=ObjCreateInfo::OT_NVGAMEOBJ;
inf.Path="misc\\navpoint\\navpoint.instance";
new_obj=AddAt(&inf,&cmd,&showflag);
new_obj->SetName(nav_point_names[nidx]);
new_obj->UseLocalizedName(true);
msg+="NavPoint \""+new_obj->GetName()+"\" Added\n";
added=true;
}
}
for(nidx=0;nidx<dropcount;nidx++)
{
GUIDropZone *dropzone=NULL;
EdGUIObject *obj=GetObjectByName(drop_names[nidx]);
if(obj)
{
if(!obj->GetTypeName().CompareNoCase(("DropZone")) )
dropzone=(GUIDropZone *)obj;
else
{
msg+="Object \""+obj->GetName()+"\" renamed to \"";
obj->SetName("renamed_"+obj->GetName());
msg+=obj->GetName()+"\"\n";
}
}
if(!dropzone)
{ // Object Missing
inf.CreateType=ObjCreateInfo::OT_DROPZONE;
inf.Path="misc\\dropzone\\dropzone.instance";
dropzone=(GUIDropZone *)AddAt(&inf,&cmd,&showflag);
dropzone->SetName(drop_names[nidx]);
msg+="DropZone \""+dropzone->GetName()+"\" Added\n";
added=true;
}
Verify(dropzone!=NULL);
int pointstoadd=drop_points[nidx]-dropzone->GetObjectCount();
if(pointstoadd>0)
{
CString tstr;
tstr.Format("%i DropPoints Added to DropZone \"%s\"\n",pointstoadd,dropzone->GetName());
msg+=tstr;
}
if(pointstoadd)
{
float rad=350.0f,deg=0.0f,deginc=Stuff::Two_Pi/pointstoadd;
for(pidx=0;pidx<pointstoadd;pidx++)
{
dropzone->AddDropPoint(Point3D((float)(rad*cos(deg)),0,(float)(rad*sin(deg))));
added=true;
deg+=deginc;
}
}
}
for(nidx=1;nidx<=flagstoadd;nidx++)
{
CString resname,flagname;
flagname.Format("Flag_Team%i",nidx);
EdGUIObject *new_obj=NULL;
EdGUIObject *obj=GetObjectByName(flagname);
if(obj)
{
if(!obj->GetTypeName().CompareNoCase(("Flag")) )
new_obj=obj;
else
{
msg+="Object \""+obj->GetName()+"\" renamed to \"";
obj->SetName("renamed_"+obj->GetName());
msg+=obj->GetName()+"\"\n";
}
}
if(!new_obj)
{
inf.Path="misc\\"+flagname+"\\"+flagname+".instance";
inf.CreateType=ObjCreateInfo::OT_GAMEOBJ;
new_obj=AddAt(&inf,&cmd,&showflag);
new_obj->UseLocalizedName(true);
msg+="Flag \""+new_obj->GetName()+"\" Added\n";
added=true;
}
}
return added;
}
void ObjectManager::SaveOverViewMap(CString fname,CSize size)
{
if(!IsLoaded()) return;
Image finalimage;
finalimage.CreateBlank(size.cx,size.cy,ITYPE_RGB,24,RGBMask(0xff0000,0x00ff00,0x0000ff));
finalimage.Blt(TerrainTexture,
CRect(
0,
0,
finalimage.GetWidth(),
finalimage.GetHeight()
),
CRect(
0,
0,
TerrainTexture.GetWidth(),
TerrainTexture.GetHeight()
)
);
finalimage.SaveTga((char *)(LPCSTR)fname);
}
bool ObjectManager::IsTeamGame(MPGameTypes idx)
{
return (
idx==ObjectManager::GT_StockTeamDestruction ||
idx==ObjectManager::GT_StockTeamAttrition ||
idx==ObjectManager::GT_StockTeamKingOfTheHill ||
idx==ObjectManager::GT_CustomTeamDestruction ||
idx==ObjectManager::GT_CustomTeamAttrition ||
idx==ObjectManager::GT_CustomTeamKingOfTheHill
);
}