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

583 lines
10 KiB
C++

// GUIPath.cpp: implementation of the GUIPath class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MW4GameEd2.h"
#include "GUINode.h"
#include "DrawInfo.h"
#include "GUIPath.h"
#include "GameInterface.h"
#include <MW4\Path.hpp>
#include <Adept\Entity.hpp>
#include <Adept\EntityClassData.hpp>
#include <Adept\Resource.hpp>
#include <Adept\Map.hpp>
using namespace Adept;
using namespace MechWarrior4;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Path
GUIPath::GUIPath(CString &name):GUIObjectList(name)
{
MyPath=NULL;
SetName(name);
Build();
AddToMap();
}
void GUIPath::Build()
{
Adept::Resource res((LPCSTR)"Misc\\Path\\Path.Instance");
res.LoadData();
Check_Object(Connection::Local);
ReplicatorID base_id = Connection::Local->GetNextReplicatorID();
MyPath = Cast_Object(Path*,Entity::CreateEntity(&res,&base_id));
Check_Object(MyPath);
MyPath->instanceName=(LPCSTR)GetName();
}
EdGUIObject *GUIPath::Clone()
{
GUIPath *obj=new GUIPath;
obj->Copy(*this);
return obj;
}
void GUIPath::Copy(GUIPath &obj)
{
GUIObjectList::Copy(obj);
if(MyPath)
{
RemoveFromMap();
delete Cast_Object(Stuff::Plug *,MyPath);
MyPath=NULL;
}
Build();
Check_Object(MyPath);
for(int i=0;i<GetObjectCount();i++)
{
MyPath->pathPoints.push_back(GetObject(i)->GetPos());
}
Verify(MyPath->pathPoints.size()==GetObjectCount());
}
GUIPath::GUIPath():GUIObjectList("Path")
{
MyPath=NULL;
InMap=false;
}
void GUIPath::AssociateTo(MechWarrior4::Path *path)
{
MyPath=path;
Check_Object(MyPath);
CString name=(char *)MyPath->instanceName;
InMap=true;
EdGUIObject::SetName(name);
CString node_name=GetName()+"Node";
int i,size=MyPath->pathPoints.size();
for(i=0;i<size;i++)
{
AddObject(new GUINode(node_name,MyPath->pathPoints[i]));
}
}
void GUIPath::SetName(CString &name)
{
EdGUIObject::SetName(name);
if(InMap && MyPath!=NULL)
{
Check_Object(MyPath);
RemoveEntityFromNameTable(MyPath);
MyPath->instanceName=(LPCSTR)GetName();
AddEntityToNameTable(MyPath);
}
for(int i=0;i<GetObjectCount();i++) GetObject(i)->SetName(GetName()+"Node");
}
EdGUIObject *GUIPath::AddNodeAtEnd(Point3D &pnt)
{
CString node_name=GetName()+"Node";
GUINode *ret;
AddObject(ret=new GUINode(node_name,pnt));
if(MyPath!=NULL)
{
Check_Object(MyPath);
MyPath->pathPoints.push_back(pnt);
Verify(MyPath->pathPoints.size()==GetObjectCount());
}
return ret;
}
void GUIPath::Draw(DrawInfo &dinf)
{
if(IsHidden()) return;
SetPen(dinf);
if(GetObjectCount()>0)
{
dinf.GetDC()->MoveTo(dinf.vinf.DataToScreen(GetObject(0)->GetPos()));
for(int i=1;i<GetObjectCount();i++)
dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(GetObject(i)->GetPos()));
}
GUIObjectList::Draw(dinf);
}
bool GUIPath::DeleteSelected(UndoCommand **delcom)
{
bool ret=GUIObjectList::DeleteSelected(delcom);
SyncData();
return ret;
}
EdGUIObject *GUIPath::InsertNodeAt(int idx,Point3D &pnt)
{
if(IsHidden()) return NULL;
GUINode *ret;
InsertObjectAt(idx,ret=new GUINode(GetName()+"Node",pnt));
return ret;
}
void GUIPath::InsertObjectAt(int idx,EdGUIObject *gobj)
{
GUIObjectList::InsertObjectAt(idx,gobj);
if(MyPath!=NULL)
{
Check_Object(MyPath);
MyPath->pathPoints.push_back(gobj->GetPos());
Verify(MyPath->pathPoints.size()==GetObjectCount());
SyncDataToNodes();
}
}
void GUIPath::SaveTextInfo(NotationFile *not_file)
{
Page *page=not_file->SetPage((char *)(LPCSTR)GetName());
page->SetEntry("Type","Path");
}
GUIPath::~GUIPath()
{
DeleteAllObjects();
if(MyPath)
{
RemoveFromMap();
delete Cast_Object(Stuff::Plug *,MyPath);
}
}
EdGUIObject *GUIPath::AddNodeIfSelected(Point3D &pnt,bool insert)
{
if(IsHidden()) return NULL;
if(!IsSelected()) return NULL;
if(GetObjectCount()<=1 || !insert)
{
return AddNodeAtEnd(pnt);
}
EdGUIObject *ret;
Point3D cp,np;
Scalar lowdist,d;
int lowpoint,i;
lowdist=(Scalar)sqrt(GetObject(0)->DistSquTo(pnt));
lowpoint=0;
np=GetObject(0)->GetPos();
for(i=1;i<GetObjectCount();i++)
{
cp=np;
np=GetObject(i)->GetPos();
d=DistToPoint(cp,np,pnt);
if(d<lowdist)
{
lowdist=d;
lowpoint=i;
}
}
d=(Scalar)sqrt(GetObject(GetObjectCount()-1)->DistSquTo(pnt));
if(d<=lowdist)
{
ret=AddNodeAtEnd(pnt);
}
else
{
ret=InsertNodeAt(lowpoint,pnt);
}
return ret;
}
void GUIPath::SyncNodesToData()
{
Check_Object(MyPath);
int i,size=MyPath->pathPoints.size();
Verify(size==GetObjectCount());
GUINode *gobj;
for(i=0;i<size;i++)
{
gobj=(GUINode *)GetObject(i);
gobj->SetPos(MyPath->pathPoints[i]);
}
for(i=0;i<GetObjectCount();i++) GetObject(i)->SetName(GetName()+"Node");
}
void GUIPath::SyncDataToNodes()
{
Check_Object(MyPath);
int i,size=MyPath->pathPoints.size();
Verify(size==GetObjectCount());
GUINode *gobj;
for(i=0;i<size;i++)
{
gobj=(GUINode *)GetObject(i);
MyPath->pathPoints[i]=gobj->GetPos();
}
}
void GUIPath::OffsetSelection(Point3D &vct)
{
if(IsHidden()) return ;
GUIObjectList::OffsetSelection(vct);
SyncDataToNodes();
}
void GUIPath::RemoveObject(int idx)
{
GUIObjectList::RemoveObject(idx);
Check_Object(MyPath);
MyPath->ErasePoint(idx);
SyncDataToNodes();
}
void GUIPath::RemoveFromMap()
{
if(InMap)
RemoveEntityFromMap(MyPath);
GUIObjectList::RemoveFromMap();
}
void GUIPath::AddToMap()
{
if(!InMap)
AddEntityToMap(MyPath,GetMat());
GUIObjectList::AddToMap();
}
HTREEITEM GUIPath::AddToBranch(CTreeCtrl *tree,HTREEITEM itm)
{
return EdGUIObject::AddToBranch(tree,itm);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bound
GUIBound::GUIBound(CString name):GUIObjectList(name)
{
}
void GUIBound::SetBoundData(DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > &BDat)
{
DeleteAllObjects();
MyBound=BDat;
int i;
Point3D pnt;
pnt.y=0.0f;
CString node_name=GetName()+"_Node";
for(i=0;i<MyBound.GetLength();i++)
{
pnt.x=MyBound[i].x;
pnt.z=MyBound[i].y;
AddObject(new GUINode(node_name,pnt));
}
}
bool GUIBound::DeleteSelected(UndoCommand **delcom)
{
if(GetObjectCount()<=3) return false;
bool ret=GUIObjectList::DeleteSelected(delcom);
SyncData();
return ret;
}
void GUIBound::Draw(DrawInfo &dinf)
{
if(IsHidden()) return;
SetPen(dinf);
if(GetObjectCount()>0)
{
dinf.GetDC()->MoveTo(dinf.vinf.DataToScreen(GetObject(0)->GetPos()));
for(int i=1;i<GetObjectCount();i++)
dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(GetObject(i)->GetPos()));
dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(GetObject(0)->GetPos()));
}
GUIObjectList::Draw(dinf);
}
EdGUIObject *GUIBound::Clone()
{
GUIBound *obj=new GUIBound;
obj->Copy(*this);
return obj;
}
EdGUIObject *GUIBound::AddNodeIfSelected(Point3D &pnt,bool insert)
{
if(IsHidden()) return NULL;
if(!IsSelected()) return NULL;
Point3D cp,np;
Scalar lowdist,d;
int lowpoint,i;
cp=GetObject(0)->GetPos();
np=GetObject(1)->GetPos();
lowdist=DistToPoint(cp,np,pnt);
lowpoint=1;
for(i=2;i<GetObjectCount();i++)
{
cp=np;
np=GetObject(i)->GetPos();
d=DistToPoint(cp,np,pnt);
if(d<lowdist)
{
lowdist=d;
lowpoint=i;
}
}
cp=np;
np=GetObject(0)->GetPos();
d=DistToPoint(cp,np,pnt);
if(d<lowdist)
{
lowdist=d;
lowpoint=0;
}
return InsertNodeAt(lowpoint,pnt);
}
void GUIBound::RemoveObject(int idx)
{
GUIObjectList::RemoveObject(idx);
MyBound.SetLength(MyBound.GetLength()-1);
SyncDataToNodes();
}
EdGUIObject *GUIBound::InsertNodeAt(int idx,Point3D &pnt)
{
if(IsHidden()) return NULL;
GUINode *ret;
CString node_name=GetName()+"_Node";
InsertObjectAt(idx,ret=new GUINode(node_name,pnt));
return ret;
}
void GUIBound::OffsetSelection(Point3D &vct)
{
if(IsHidden()) return;
GUIObjectList::OffsetSelection(vct);
if(!IsConcave())
{
Point3D pnt2;
pnt2.x=-vct.x;
pnt2.y=-vct.y;
pnt2.z=-vct.z;
GUIObjectList::OffsetSelection(pnt2);
}
if(!IsConcave())
{
Point3D tl,br;
GetExtents(&tl,&br);
ResetTo(tl,br);
}
SyncDataToNodes();
}
bool GUIBound::IsConcave()
{
int i;
Point3D p1,p2,p3;
p1=GetObject(GetObjectCount()-1)->GetPos();
p2=GetObject(GetObjectCount()-2)->GetPos();
p2.y=p1.y=0;
Vector3D v1,v2,rvct;
int sign=-1;
for(i=0;i<GetObjectCount();i++)
{
p3=p2;
p2=p1;
p1=GetObject(i)->GetPos();
p1.y=0;
/*
p1.x/=(float)fabs(p1.x);
p2.x/=(float)fabs(p1.x);
p3.x/=(float)fabs(p1.x);
p1.y/=(float)fabs(p1.x);
p2.y/=(float)fabs(p1.x);
p3.y/=(float)fabs(p1.x);
*/
v1.Subtract(p3,p2);
v2.Subtract(p1,p2);
rvct.Cross(v1,v2);
if(rvct.y!=0.0f)
{
if(sign==-1)
{
sign=rvct.y>0?1:0;
}
if((sign==1 && rvct.y<0) || (sign==0 && rvct.y>0) )
return false;
}
}
return true;
}
void GUIBound::SyncNodesToData()
{
int i,size=MyBound.GetLength();
Verify(size==GetObjectCount());
GUINode *gobj;
for(i=0;i<size;i++)
{
Point3D pnt;
pnt.y=0.0f;
pnt.x=MyBound[i].x;
pnt.z=MyBound[i].y;
gobj=(GUINode *)GetObject(i);
gobj->SetPos(pnt);
}
}
void GUIBound::SyncDataToNodes()
{
int i,size=MyBound.GetLength();
Verify(size==GetObjectCount());
Point3D pnt;
for(i=0;i<size;i++)
{
pnt=GetObject(i)->GetPos();
MyBound[i].x=pnt.x;
MyBound[i].y=pnt.z;
}
}
void GUIBound::ResetTo(Point3D tl,Point3D br)
{
MyBound.SetLength(4);
MyBound[0].x=tl.x;
MyBound[0].y=tl.z;
MyBound[3].x=br.x;
MyBound[3].y=tl.z;
MyBound[2].x=br.x;
MyBound[2].y=br.z;
MyBound[1].x=tl.x;
MyBound[1].y=br.z;
SetBoundData(MyBound);
}
void GUIBound::SaveTextInfo(NotationFile *not_file)
{
Page *page=not_file->SetPage((char *)(LPCSTR)GetName());
page->SetEntry("Type","Bound");
}
GUIBound::~GUIBound()
{
DeleteAllObjects();
}
void GUIBound::InsertObjectAt(int idx,EdGUIObject *gobj)
{
GUIObjectList::InsertObjectAt(idx,gobj);
MyBound.SetLength(MyBound.GetLength()+1);
SyncDataToNodes();
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Global Helper Functions