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.
1041 lines
25 KiB
1041 lines
25 KiB
//========= 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(); |
|
} |
|
}
|
|
|