You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1042 lines
25 KiB
1042 lines
25 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "hammer.h"
|
||
|
#include "ObjectBar.h"
|
||
|
#include "Options.h"
|
||
|
#include "ControlBarIDs.h"
|
||
|
#include "Prefabs.h"
|
||
|
#include "Prefab3D.h"
|
||
|
#include "StockSolids.h"
|
||
|
#include "mainfrm.h"
|
||
|
#include "MapSolid.h"
|
||
|
#include "MapWorld.h"
|
||
|
#include "MapDoc.h"
|
||
|
#include "GlobalFunctions.h"
|
||
|
#include "ArchDlg.h"
|
||
|
#include "TorusDlg.h"
|
||
|
#include "ToolManager.h"
|
||
|
#include "mathlib/vector.h"
|
||
|
#include "mapview2d.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include <tier0/memdbgon.h>
|
||
|
|
||
|
|
||
|
#pragma warning( disable : 4355 )
|
||
|
|
||
|
|
||
|
CMapClass *CreateArch(BoundBox *pBox, float fStartAngle, int iSides, float fArc,
|
||
|
int iWallWidth, int iAddHeight, BOOL bPreview);
|
||
|
|
||
|
CMapClass *CreateTorus(BoundBox *pBox, float fStartAngle, int iSides, float fArc, int iWallWidth, float flCrossSectionalRadius,
|
||
|
float fRotationStartAngle, int iRotationSides, float fRotationArc, int iAddHeight, BOOL bPreview);
|
||
|
|
||
|
|
||
|
static int _iNewObjIndex = 0;
|
||
|
static char _szNewObjName[128];
|
||
|
|
||
|
struct SolidTypeInfo_t
|
||
|
{
|
||
|
LPCTSTR pszName;
|
||
|
UINT nFaces;
|
||
|
UINT nFacesMin;
|
||
|
UINT nFacesMax;
|
||
|
bool bEnableFaceControl;
|
||
|
};
|
||
|
|
||
|
|
||
|
SolidTypeInfo_t SolidTypes[] =
|
||
|
{
|
||
|
{"block", 0, 6, 6, false},
|
||
|
{"wedge", 0, 5, 5, false},
|
||
|
{"cylinder", 8, 3, 32, true},
|
||
|
{"spike", 4, 3, 32, true},
|
||
|
{"sphere", 8, 3, 16, true},
|
||
|
{"arch", 8, 3, 128, true},
|
||
|
{"torus", 0, 4, 128, false},
|
||
|
};
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CObjectBar, CHammerBar)
|
||
|
ON_UPDATE_COMMAND_UI(IDC_CREATELIST, UpdateControl)
|
||
|
ON_UPDATE_COMMAND_UI(IDC_CATEGORYLIST, UpdateControl)
|
||
|
ON_UPDATE_COMMAND_UI(IDC_FACES, UpdateFaceControl)
|
||
|
ON_UPDATE_COMMAND_UI(IDC_FACESSPIN, UpdateFaceControl)
|
||
|
ON_UPDATE_COMMAND_UI(ID_TOOLS_CREATEPREFAB, UpdateControl)
|
||
|
ON_UPDATE_COMMAND_UI(ID_CREATEOBJECT, UpdateControl)
|
||
|
ON_CBN_SELCHANGE(IDC_CATEGORYLIST, OnChangeCategory)
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Get the index of the specified solid type.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static int FindSolidType( const char *pName )
|
||
|
{
|
||
|
for ( int i=0; i < ARRAYSIZE( SolidTypes ); i++ )
|
||
|
{
|
||
|
if ( Q_stricmp( pName, SolidTypes[i].pszName ) == 0 )
|
||
|
return i;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Get the index of the specified GDClass.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static int FindGameDataClass( const char *pName )
|
||
|
{
|
||
|
extern GameData *pGD;
|
||
|
if( pGD != NULL )
|
||
|
{
|
||
|
int nCount = pGD->GetClassCount();
|
||
|
for (int i = 0; i < nCount; i++)
|
||
|
{
|
||
|
GDclass *pc = pGD->GetClass(i);
|
||
|
if ( Q_stricmp( pName, pc->GetName() ) == 0 )
|
||
|
return i;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CObjectBar::CObjectBar()
|
||
|
: CHammerBar(), m_CreateList( this )
|
||
|
{
|
||
|
for(int i = 0; i < MAX_PREV_SEL; i++)
|
||
|
{
|
||
|
m_PrevSel[i].dwGameID = 0;
|
||
|
}
|
||
|
|
||
|
m_dwPrevGameID = (unsigned long)-1;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CObjectBar::UseRandomYawOnEntityPlacement()
|
||
|
{
|
||
|
return ::SendMessage( ::GetDlgItem( GetSafeHwnd(), IDC_RANDOMYAW ), BM_GETCHECK, 0, 0 ) == BST_CHECKED;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : pDX -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::DoDataExchange(CDataExchange *pDX)
|
||
|
{
|
||
|
CHammerBar::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(COP_Entity)
|
||
|
DDX_Control(pDX, IDC_CREATELIST, m_CreateList);
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Returns the bounds of the current 3D prefab object.
|
||
|
// Input : *pBox -
|
||
|
// Output : Returns TRUE on success, FALSE on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL CObjectBar::GetPrefabBounds(BoundBox *pBox)
|
||
|
{
|
||
|
if (ListType != listPrefabs)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
CPrefab3D *pPrefab = (CPrefab3D *)CPrefab::FindID(_iNewObjIndex);
|
||
|
if (pPrefab != NULL)
|
||
|
{
|
||
|
if (pPrefab->GetType() != pt3D)
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!pPrefab->IsLoaded())
|
||
|
{
|
||
|
pPrefab->Load();
|
||
|
}
|
||
|
|
||
|
if (!pPrefab->IsLoaded())
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
CMapWorld *pWorld = pPrefab->GetWorld();
|
||
|
|
||
|
Vector mins;
|
||
|
Vector maxs;
|
||
|
pWorld->GetRender2DBox(mins, maxs);
|
||
|
pBox->SetBounds(mins, maxs);
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Find the specified prefab.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CPrefab* CObjectBar::FindPrefabByName( const char *pName )
|
||
|
{
|
||
|
CPrefabLibrary *pLibrary = CPrefabLibrary::FindID( m_CategoryList.GetItemData(m_CategoryList.GetCurSel() ) );
|
||
|
if ( pLibrary )
|
||
|
{
|
||
|
POSITION p = ENUM_START;
|
||
|
CPrefab *pPrefab = pLibrary->EnumPrefabs( p );
|
||
|
while( pPrefab )
|
||
|
{
|
||
|
if ( Q_stricmp( pName, pPrefab->GetName() ) == 0 )
|
||
|
return pPrefab;
|
||
|
|
||
|
pPrefab = pLibrary->EnumPrefabs( p );
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : pBox -
|
||
|
// pAxes -
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CMapClass *CObjectBar::CreateInBox(BoundBox *pBox, CMapView *pView)
|
||
|
{
|
||
|
// primitives:
|
||
|
|
||
|
int axHorz = 0;
|
||
|
int axVert = 1;
|
||
|
|
||
|
CMapView2D *pView2D = dynamic_cast<CMapView2D*>(pView);
|
||
|
|
||
|
if ( pView2D )
|
||
|
{
|
||
|
axHorz = pView2D->axHorz;
|
||
|
axVert = pView2D->axVert;
|
||
|
}
|
||
|
|
||
|
if(ListType == listPrimitives)
|
||
|
{
|
||
|
int nFaces;
|
||
|
char szBuf[128];
|
||
|
m_Faces.GetWindowText(szBuf, 128);
|
||
|
nFaces = atoi(szBuf);
|
||
|
|
||
|
//
|
||
|
// The index into the solid types array is stored in the item data.
|
||
|
//
|
||
|
int nSolidIndex = _iNewObjIndex;
|
||
|
|
||
|
int nFacesMin = SolidTypes[nSolidIndex].nFacesMin;
|
||
|
int nFacesMax = SolidTypes[nSolidIndex].nFacesMax;
|
||
|
|
||
|
//
|
||
|
// Insure that the face count is within legal range (if applicable).
|
||
|
//
|
||
|
if ((SolidTypes[nSolidIndex].bEnableFaceControl) && (nFaces < nFacesMin || nFaces > nFacesMax))
|
||
|
{
|
||
|
CString str;
|
||
|
str.Format("The face count for a %s must be in the range of %d to %d.",
|
||
|
SolidTypes[nSolidIndex].pszName, nFacesMin, nFacesMax);
|
||
|
AfxMessageBox(str);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if(nSolidIndex < 5)
|
||
|
{
|
||
|
StockSolid *pStock = NULL;
|
||
|
|
||
|
switch(nSolidIndex)
|
||
|
{
|
||
|
case 0:
|
||
|
pStock = new StockBlock;
|
||
|
break;
|
||
|
case 1:
|
||
|
pStock = new StockWedge;
|
||
|
break;
|
||
|
case 2:
|
||
|
pStock = new StockCylinder;
|
||
|
pStock->SetFieldData(StockCylinder::fieldSideCount, nFaces);
|
||
|
break;
|
||
|
case 3:
|
||
|
pStock = new StockSpike;
|
||
|
pStock->SetFieldData(StockSpike::fieldSideCount, nFaces);
|
||
|
break;
|
||
|
default:
|
||
|
pStock = new StockSphere;
|
||
|
pStock->SetFieldData(StockSphere::fieldSideCount, nFaces);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// create a solid
|
||
|
CMapSolid *pSolid = new CMapSolid;
|
||
|
pStock->SetFromBox(pBox);
|
||
|
pStock->CreateMapSolid(pSolid, Options.GetTextureAlignment());
|
||
|
pSolid->SetTexture(GetDefaultTextureName());
|
||
|
delete pStock; // done with you! done!
|
||
|
|
||
|
// return new solid
|
||
|
return pSolid;
|
||
|
}
|
||
|
else if (nSolidIndex == 5)
|
||
|
{
|
||
|
// arch
|
||
|
CArchDlg dlg(pBox->bmins, pBox->bmaxs);
|
||
|
Vector sizebounds;
|
||
|
pBox->GetBoundsSize(sizebounds);
|
||
|
dlg.m_iSides = nFaces;
|
||
|
dlg.SetMaxWallWidth(min((int)sizebounds[axHorz], (int)sizebounds[axVert]));
|
||
|
if(dlg.DoModal() != IDOK)
|
||
|
return NULL;
|
||
|
|
||
|
// save values for next use of arch
|
||
|
dlg.SaveValues();
|
||
|
|
||
|
CMapClass *pArch = CreateArch(pBox, dlg.m_fAngle,
|
||
|
dlg.m_iSides, dlg.m_fArc, dlg.m_iWallWidth,
|
||
|
dlg.m_iAddHeight, FALSE);
|
||
|
|
||
|
const CMapObjectList &SolidList = *pArch->GetChildren();
|
||
|
FOR_EACH_OBJ( SolidList, nSolid )
|
||
|
{
|
||
|
CMapSolid *pSolid = dynamic_cast<CMapSolid *>(SolidList[nSolid]);
|
||
|
if ( pSolid )
|
||
|
pSolid->SetTexture(GetDefaultTextureName());
|
||
|
}
|
||
|
|
||
|
return pArch;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Torus
|
||
|
CTorusDlg dlg( pBox->bmins, pBox->bmaxs );
|
||
|
Vector sizebounds;
|
||
|
pBox->GetBoundsSize( sizebounds );
|
||
|
dlg.SetMaxWallWidth(min((int)sizebounds[axHorz], (int)sizebounds[axVert]));
|
||
|
if(dlg.DoModal() != IDOK)
|
||
|
return NULL;
|
||
|
|
||
|
// save values for next use of arch
|
||
|
dlg.SaveValues();
|
||
|
|
||
|
CMapClass *pTorus = CreateTorus(pBox, dlg.m_fAngle, dlg.m_iSides, dlg.m_fArc, dlg.m_iWallWidth,
|
||
|
dlg.GetTorusCrossSectionRadius(),
|
||
|
dlg.m_fRotationAngle, dlg.m_iRotationSides, dlg.m_fRotationArc, dlg.m_iAddHeight, FALSE);
|
||
|
|
||
|
const CMapObjectList &SolidList = *pTorus->GetChildren();
|
||
|
FOR_EACH_OBJ( SolidList, nSolid )
|
||
|
{
|
||
|
CMapSolid *pSolid = dynamic_cast<CMapSolid *>(SolidList[nSolid]);
|
||
|
if ( pSolid )
|
||
|
pSolid->SetTexture(GetDefaultTextureName());
|
||
|
}
|
||
|
|
||
|
return pTorus;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CPrefab *pPrefab = CPrefab::FindID(_iNewObjIndex);
|
||
|
if (pPrefab != NULL)
|
||
|
{
|
||
|
return(pPrefab->CreateInBox(pBox));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Returns the classname of the default entity for the entity creation tool.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
LPCTSTR CObjectBar::GetDefaultEntityClass(void)
|
||
|
{
|
||
|
return _szNewObjName;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CMapClass *CObjectBar::BuildPrefabObjectAtPoint( Vector const &HitPos )
|
||
|
{
|
||
|
//
|
||
|
// find prefab
|
||
|
//
|
||
|
CPrefab3D *pPrefab = ( CPrefab3D* )CPrefab::FindID( _iNewObjIndex );
|
||
|
if( !pPrefab )
|
||
|
return NULL;
|
||
|
|
||
|
//
|
||
|
// create prefab bounding box -- centered at hit pos
|
||
|
//
|
||
|
return pPrefab->CreateAtPointAroundOrigin( HitPos );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CObjectBar::IsEntityToolCreatingPrefab( void )
|
||
|
{
|
||
|
if( ( m_iLastTool == TOOL_ENTITY ) && ( m_CategoryList.GetCurSel() != 0 ) )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CObjectBar::IsEntityToolCreatingEntity( void )
|
||
|
{
|
||
|
if( ( m_iLastTool == TOOL_ENTITY ) && ( m_CategoryList.GetCurSel() == 0 ) )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::OnChangeCategory()
|
||
|
{
|
||
|
switch (ListType)
|
||
|
{
|
||
|
case listPrimitives:
|
||
|
{
|
||
|
iBlockSel = -1;
|
||
|
LoadBlockItems();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case listPrefabs:
|
||
|
{
|
||
|
if (m_iLastTool == TOOL_BLOCK)
|
||
|
{
|
||
|
iBlockSel = -1;
|
||
|
LoadBlockItems();
|
||
|
}
|
||
|
else if (m_iLastTool == TOOL_ENTITY)
|
||
|
{
|
||
|
iEntitySel = -1;
|
||
|
LoadEntityItems();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case listEntities:
|
||
|
{
|
||
|
iEntitySel = -1;
|
||
|
LoadEntityItems();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DoHideControls();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : pParentWnd -
|
||
|
// Output : Returns TRUE on success, FALSE on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL CObjectBar::Create(CWnd *pParentWnd)
|
||
|
{
|
||
|
if (!CHammerBar::Create(pParentWnd, IDD_OBJECTBAR, CBRS_RIGHT, IDCB_OBJECTBAR))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
SetWindowText("New Objects");
|
||
|
|
||
|
|
||
|
// set up controls
|
||
|
|
||
|
// We only want it to return values that are in our list of suggestions.
|
||
|
m_CreateList.SubclassDlgItem(IDC_CREATELIST, this);
|
||
|
m_CreateList.SetOnlyProvideSuggestions( true );
|
||
|
|
||
|
m_CategoryList.SubclassDlgItem(IDC_CATEGORYLIST, this);
|
||
|
m_Faces.SubclassDlgItem(IDC_FACES, this);
|
||
|
m_FacesSpin.SubclassDlgItem(IDC_FACESSPIN, this);
|
||
|
m_FacesSpin.SetBuddy(&m_Faces);
|
||
|
|
||
|
iBlockSel = -1;
|
||
|
iEntitySel = -1;
|
||
|
m_iLastTool = -1;
|
||
|
|
||
|
LoadBlockCategories();
|
||
|
|
||
|
// outta here
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Load the category list with the list of primitives and object libraries.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::LoadBlockCategories( void )
|
||
|
{
|
||
|
m_CategoryList.SetRedraw(FALSE);
|
||
|
|
||
|
// first item is the primitive list
|
||
|
m_CategoryList.ResetContent();
|
||
|
m_CategoryList.AddString("Primitives");
|
||
|
|
||
|
// the next items are the prefab categories (libraries)
|
||
|
LoadPrefabCategories();
|
||
|
|
||
|
// redraw category list
|
||
|
m_CategoryList.SetRedraw(TRUE);
|
||
|
m_CategoryList.Invalidate();
|
||
|
|
||
|
// set initial state
|
||
|
m_CategoryList.SetCurSel( 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::LoadEntityCategories( void )
|
||
|
{
|
||
|
m_CategoryList.SetRedraw( FALSE );
|
||
|
|
||
|
// first item is the primitive list
|
||
|
m_CategoryList.ResetContent();
|
||
|
m_CategoryList.AddString( "Entities" );
|
||
|
|
||
|
// the next items are the prefab categories (libraries)
|
||
|
LoadPrefabCategories();
|
||
|
|
||
|
// redraw category list
|
||
|
m_CategoryList.SetRedraw( TRUE );
|
||
|
m_CategoryList.Invalidate();
|
||
|
|
||
|
// set initial state
|
||
|
m_CategoryList.SetCurSel( 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::LoadPrefabCategories( void )
|
||
|
{
|
||
|
//
|
||
|
// if a long list -- don't update every time
|
||
|
//
|
||
|
m_CategoryList.SetRedraw( FALSE );
|
||
|
|
||
|
//
|
||
|
// add all prefab object libraries to the category list
|
||
|
//
|
||
|
POSITION p = ENUM_START;
|
||
|
CPrefabLibrary *pLibrary = CPrefabLibrary::EnumLibraries( p );
|
||
|
while( pLibrary )
|
||
|
{
|
||
|
int iIndex = m_CategoryList.AddString( pLibrary->GetName() );
|
||
|
m_CategoryList.SetItemData( iIndex, pLibrary->GetID() );
|
||
|
pLibrary = CPrefabLibrary::EnumLibraries( p );
|
||
|
}
|
||
|
|
||
|
m_CategoryList.SetRedraw(TRUE);
|
||
|
m_CategoryList.Invalidate();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::LoadBlockItems( void )
|
||
|
{
|
||
|
//
|
||
|
// verify the block categories are loaded
|
||
|
//
|
||
|
if( m_CategoryList.GetCurSel() == CB_ERR )
|
||
|
{
|
||
|
LoadBlockCategories();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// load primitive items
|
||
|
//
|
||
|
if( m_CategoryList.GetCurSel() == 0 )
|
||
|
{
|
||
|
// set list type (primitives)
|
||
|
ListType = listPrimitives;
|
||
|
|
||
|
// set list type (primitives)
|
||
|
CUtlVector<CString> suggestions;
|
||
|
for( int i = 0; i < sizeof( SolidTypes ) / sizeof( SolidTypes[0] ); i++)
|
||
|
suggestions.AddToTail( SolidTypes[i].pszName );
|
||
|
|
||
|
m_CreateList.SetSuggestions( suggestions );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LoadPrefabItems();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::LoadEntityItems( void )
|
||
|
{
|
||
|
//
|
||
|
// verify the block categories are loaded
|
||
|
//
|
||
|
if( m_CategoryList.GetCurSel() == CB_ERR )
|
||
|
{
|
||
|
LoadEntityCategories();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// load entity items
|
||
|
//
|
||
|
if( m_CategoryList.GetCurSel() == 0 )
|
||
|
{
|
||
|
// set list type (markers)???
|
||
|
ListType = listEntities;
|
||
|
|
||
|
CUtlVector<CString> suggestions;
|
||
|
extern GameData *pGD;
|
||
|
if( pGD != NULL )
|
||
|
{
|
||
|
int nCount = pGD->GetClassCount();
|
||
|
for (int i = 0; i < nCount; i++)
|
||
|
{
|
||
|
GDclass *pc = pGD->GetClass(i);
|
||
|
if( !pc->IsBaseClass() && !pc->IsSolidClass() )
|
||
|
{
|
||
|
suggestions.AddToTail( pc->GetName() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_CreateList.SetSuggestions( suggestions );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LoadPrefabItems();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::LoadPrefabItems( void )
|
||
|
{
|
||
|
// set list type (prefabs)
|
||
|
ListType = listPrefabs;
|
||
|
|
||
|
CUtlVector<CString> suggestions;
|
||
|
|
||
|
// get the active library and add the prefabs from it
|
||
|
CPrefabLibrary *pLibrary = CPrefabLibrary::FindID( m_CategoryList.GetItemData(m_CategoryList.GetCurSel() ) );
|
||
|
|
||
|
POSITION p = ENUM_START;
|
||
|
CPrefab *pPrefab = pLibrary->EnumPrefabs( p );
|
||
|
while( pPrefab )
|
||
|
{
|
||
|
suggestions.AddToTail( pPrefab->GetName() );
|
||
|
pPrefab = pLibrary->EnumPrefabs( p );
|
||
|
}
|
||
|
|
||
|
m_CreateList.SetSuggestions( suggestions );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::DoHideControls()
|
||
|
{
|
||
|
// hide controls based on which mode is selected...
|
||
|
if(ListType == listPrimitives)
|
||
|
{
|
||
|
GetDlgItem(ID_INSERTPREFAB_ORIGINAL)->ShowWindow(SW_HIDE);
|
||
|
m_Faces.ShowWindow(SW_SHOW);
|
||
|
m_FacesSpin.ShowWindow(SW_SHOW);
|
||
|
GetDlgItem(IDC_FACESPROMPT)->ShowWindow(SW_SHOW);
|
||
|
}
|
||
|
else if(ListType == listPrefabs)
|
||
|
{
|
||
|
m_Faces.ShowWindow(SW_HIDE);
|
||
|
m_FacesSpin.ShowWindow(SW_HIDE);
|
||
|
GetDlgItem(IDC_FACESPROMPT)->ShowWindow(SW_HIDE);
|
||
|
GetDlgItem(ID_INSERTPREFAB_ORIGINAL)->ShowWindow(SW_SHOW);
|
||
|
}
|
||
|
else if(ListType == listEntities)
|
||
|
{
|
||
|
m_Faces.ShowWindow(SW_HIDE);
|
||
|
m_FacesSpin.ShowWindow(SW_HIDE);
|
||
|
GetDlgItem(IDC_FACESPROMPT)->ShowWindow(SW_HIDE);
|
||
|
GetDlgItem(ID_INSERTPREFAB_ORIGINAL)->ShowWindow(SW_HIDE);
|
||
|
}
|
||
|
|
||
|
// Show the "random yaw" button?
|
||
|
bool bShow = (ListType == listEntities);
|
||
|
GetDlgItem( IDC_RANDOMYAW )->ShowWindow( bShow ? SW_SHOW : SW_HIDE );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *pCmdUI -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::UpdateControl(CCmdUI *pCmdUI)
|
||
|
{
|
||
|
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
|
||
|
|
||
|
switch (pCmdUI->m_nID)
|
||
|
{
|
||
|
case ID_INSERTPREFAB_ORIGINAL:
|
||
|
{
|
||
|
pCmdUI->Enable(ListType == listPrefabs);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case IDC_CREATELIST:
|
||
|
case IDC_CATEGORYLIST:
|
||
|
{
|
||
|
BOOL bEnable = FALSE;
|
||
|
if (pDoc)
|
||
|
{
|
||
|
int nTool = pDoc->GetTools()->GetActiveToolID();
|
||
|
if ((nTool == TOOL_ENTITY) || (nTool == TOOL_BLOCK))
|
||
|
{
|
||
|
bEnable = TRUE;
|
||
|
}
|
||
|
}
|
||
|
pCmdUI->Enable(bEnable);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
pCmdUI->Enable( pDoc ? TRUE : FALSE);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *pWnd -
|
||
|
// bModifyWnd -
|
||
|
// Output : Returns TRUE on success, FALSE on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL CObjectBar::EnableFaceControl(CWnd *pWnd, BOOL bModifyWnd)
|
||
|
{
|
||
|
BOOL bEnable = CMapDoc::GetActiveMapDoc() ? TRUE : FALSE;
|
||
|
|
||
|
if(bEnable)
|
||
|
{
|
||
|
bEnable = FALSE;
|
||
|
|
||
|
//
|
||
|
// Enable the control only if we are dealing with an object the
|
||
|
// that has adjustable faces.
|
||
|
//
|
||
|
if (ListType == listPrimitives)
|
||
|
{
|
||
|
int nSolidIndex = iBlockSel;
|
||
|
if (SolidTypes[nSolidIndex].bEnableFaceControl)
|
||
|
{
|
||
|
bEnable = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(bModifyWnd)
|
||
|
pWnd->EnableWindow(bEnable);
|
||
|
|
||
|
return bEnable;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *pCmdUI -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::UpdateFaceControl(CCmdUI *pCmdUI)
|
||
|
{
|
||
|
pCmdUI->Enable(EnableFaceControl(GetDlgItem(pCmdUI->m_nID), FALSE));
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Called when a new item has been selected in the combo box.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::OnTextChanged( const char *pSelection )
|
||
|
{
|
||
|
char szBuf[128];
|
||
|
|
||
|
switch (ListType)
|
||
|
{
|
||
|
case listPrimitives:
|
||
|
{
|
||
|
_iNewObjIndex = FindSolidType( pSelection );
|
||
|
Assert( _iNewObjIndex != -1 );
|
||
|
|
||
|
//
|
||
|
// Save current value from the faces edit control. The next time this primitive is
|
||
|
// selected the value will be restored.
|
||
|
//
|
||
|
if (iBlockSel != -1)
|
||
|
{
|
||
|
int nSolidIndex = iBlockSel;
|
||
|
m_Faces.GetWindowText(szBuf, 128);
|
||
|
SolidTypes[nSolidIndex].nFaces = atoi(szBuf);
|
||
|
}
|
||
|
iBlockSel = _iNewObjIndex;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case listPrefabs:
|
||
|
{
|
||
|
CPrefab *pPrefab = FindPrefabByName( pSelection );
|
||
|
Assert( pPrefab );
|
||
|
if ( pPrefab )
|
||
|
{
|
||
|
_iNewObjIndex = pPrefab->GetID();
|
||
|
|
||
|
if (m_iLastTool == TOOL_BLOCK )
|
||
|
{
|
||
|
iBlockSel = _iNewObjIndex;
|
||
|
}
|
||
|
else if( m_iLastTool == TOOL_ENTITY )
|
||
|
{
|
||
|
iEntitySel = _iNewObjIndex;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case listEntities:
|
||
|
{
|
||
|
_iNewObjIndex = FindGameDataClass( pSelection );
|
||
|
Assert( _iNewObjIndex != -1 );
|
||
|
if ( _iNewObjIndex != -1 )
|
||
|
{
|
||
|
Q_strncpy( _szNewObjName, pSelection, sizeof( _szNewObjName ) );
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ListType != listPrimitives)
|
||
|
return;
|
||
|
|
||
|
EnableFaceControl(&m_Faces, TRUE);
|
||
|
EnableFaceControl(&m_FacesSpin, TRUE);
|
||
|
|
||
|
int nSolidIndex = _iNewObjIndex;
|
||
|
|
||
|
m_FacesSpin.SetRange(SolidTypes[nSolidIndex].nFacesMin, SolidTypes[nSolidIndex].nFacesMax);
|
||
|
m_FacesSpin.SetPos(SolidTypes[nSolidIndex].nFaces);
|
||
|
|
||
|
itoa(SolidTypes[nSolidIndex].nFaces, szBuf, 10);
|
||
|
m_Faces.SetWindowText(szBuf);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : dwGameID -
|
||
|
// piNewIndex -
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CObjectBar::GetPrevSelIndex(DWORD dwGameID, int *piNewIndex)
|
||
|
{
|
||
|
for(int i = 0; i < MAX_PREV_SEL; i++)
|
||
|
{
|
||
|
if(m_PrevSel[i].dwGameID == 0 && piNewIndex)
|
||
|
*piNewIndex = i;
|
||
|
|
||
|
if(m_PrevSel[i].dwGameID == dwGameID)
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : pMsg -
|
||
|
// Output : Returns TRUE on success, FALSE on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL CObjectBar::PreTranslateMessage(MSG* pMsg)
|
||
|
{
|
||
|
//
|
||
|
// See if the message is a keydown and the current focus window is the
|
||
|
// ComboBox in the ObjectBar!
|
||
|
//
|
||
|
/*static BOOL bRecurse = FALSE;
|
||
|
|
||
|
if (pMsg->message == WM_KEYDOWN && !bRecurse)
|
||
|
{
|
||
|
if (GetFocus() == &m_CreateList)
|
||
|
{
|
||
|
//AfxMessageBox("Ok");
|
||
|
bRecurse = TRUE;
|
||
|
m_CreateList.SendMessage(WM_CHAR, pMsg->wParam, pMsg->lParam);
|
||
|
bRecurse = FALSE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
return CHammerBar::PreTranslateMessage(pMsg);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : iTool -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CObjectBar::UpdateListForTool( int iTool )
|
||
|
{
|
||
|
//
|
||
|
// initialize for new "game config"
|
||
|
//
|
||
|
int iPrevSel = 0;
|
||
|
if (m_dwPrevGameID != g_pGameConfig->dwID)
|
||
|
{
|
||
|
//
|
||
|
// save current game id and save
|
||
|
//
|
||
|
m_dwPrevGameID = g_pGameConfig->dwID;
|
||
|
GetPrevSelIndex( g_pGameConfig->dwID, &iPrevSel );
|
||
|
m_PrevSel[iPrevSel].dwGameID = g_pGameConfig->dwID;
|
||
|
|
||
|
m_PrevSel[iPrevSel].block.strCategory = "Primitives";
|
||
|
m_PrevSel[iPrevSel].block.strItem = "block";
|
||
|
|
||
|
m_PrevSel[iPrevSel].entity.strCategory = "Entities";
|
||
|
m_PrevSel[iPrevSel].entity.strItem = g_pGameConfig->szDefaultPoint;
|
||
|
}
|
||
|
|
||
|
// get game id previously selected data index
|
||
|
iPrevSel = GetPrevSelIndex( m_dwPrevGameID );
|
||
|
if (iPrevSel == -1)
|
||
|
return;
|
||
|
|
||
|
//
|
||
|
// Save last known selection state for previous tool
|
||
|
//
|
||
|
if (m_iLastTool == TOOL_BLOCK)
|
||
|
{
|
||
|
int iCategory = m_CategoryList.GetCurSel();
|
||
|
if( iCategory != -1 )
|
||
|
{
|
||
|
m_CategoryList.GetLBText( iCategory, m_PrevSel[iPrevSel].block.strCategory );
|
||
|
m_PrevSel[iPrevSel].block.strItem = m_CreateList.GetCurrentItem();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_PrevSel[iPrevSel].block.strCategory = "";
|
||
|
m_PrevSel[iPrevSel].block.strItem = "";
|
||
|
}
|
||
|
}
|
||
|
else if (m_iLastTool == TOOL_ENTITY)
|
||
|
{
|
||
|
int iCategory = m_CategoryList.GetCurSel();
|
||
|
if( iCategory != -1 )
|
||
|
{
|
||
|
m_CategoryList.GetLBText( iCategory, m_PrevSel[iPrevSel].entity.strCategory );
|
||
|
m_PrevSel[iPrevSel].entity.strItem = m_CreateList.GetCurrentItem();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_PrevSel[iPrevSel].entity.strCategory = "";
|
||
|
m_PrevSel[iPrevSel].entity.strItem = "";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// save tool for next pass
|
||
|
m_iLastTool = iTool;
|
||
|
|
||
|
//
|
||
|
// update new for new tool
|
||
|
//
|
||
|
if (iTool == TOOL_BLOCK)
|
||
|
{
|
||
|
//
|
||
|
// load block categories and items
|
||
|
//
|
||
|
LoadBlockCategories();
|
||
|
m_CategoryList.SelectString( -1, m_PrevSel[iPrevSel].block.strCategory );
|
||
|
LoadBlockItems();
|
||
|
|
||
|
m_CreateList.SelectItem( m_PrevSel[iPrevSel].block.strItem );
|
||
|
OnTextChanged( m_PrevSel[iPrevSel].block.strItem );
|
||
|
iBlockSel = FindSolidType( m_PrevSel[iPrevSel].block.strItem );
|
||
|
Assert( iBlockSel >= 0 );
|
||
|
|
||
|
// hide/show appropriate controls
|
||
|
DoHideControls();
|
||
|
|
||
|
//
|
||
|
// enable/disable face controls
|
||
|
//
|
||
|
EnableFaceControl( &m_Faces, TRUE );
|
||
|
EnableFaceControl( &m_FacesSpin, TRUE );
|
||
|
}
|
||
|
else if (iTool == TOOL_ENTITY)
|
||
|
{
|
||
|
//
|
||
|
// load entity categories and items
|
||
|
//
|
||
|
LoadEntityCategories();
|
||
|
m_CategoryList.SelectString( -1, m_PrevSel[iPrevSel].entity.strCategory );
|
||
|
LoadEntityItems();
|
||
|
|
||
|
m_CreateList.SelectItem( m_PrevSel[iPrevSel].entity.strItem );
|
||
|
OnTextChanged( m_PrevSel[iPrevSel].entity.strItem );
|
||
|
iEntitySel = FindGameDataClass( m_PrevSel[iPrevSel].entity.strItem );
|
||
|
|
||
|
// hide/show appropriate controls
|
||
|
DoHideControls();
|
||
|
|
||
|
//
|
||
|
// enable/disable face controls
|
||
|
//
|
||
|
EnableFaceControl( &m_Faces, TRUE );
|
||
|
EnableFaceControl( &m_FacesSpin, TRUE );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_CategoryList.ResetContent();
|
||
|
m_CreateList.Clear();
|
||
|
DoHideControls();
|
||
|
}
|
||
|
}
|