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.
316 lines
7.8 KiB
316 lines
7.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Implements the spawnflags page of the Entity Properties dialog. |
|
// |
|
//=============================================================================// |
|
|
|
#include "stdafx.h" |
|
#include "hammer.h" |
|
#include "OP_Flags.h" |
|
#include "OP_Entity.h" |
|
#include "ObjectProperties.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
///////////////////////////////////////////////////////////////////////////// |
|
// COP_Flags property page |
|
|
|
IMPLEMENT_DYNCREATE(COP_Flags, CObjectPage) |
|
|
|
COP_Flags::COP_Flags() : CObjectPage(COP_Flags::IDD) |
|
{ |
|
//{{AFX_DATA_INIT(COP_Flags) |
|
// NOTE: the ClassWizard will add member initialization here |
|
//}}AFX_DATA_INIT |
|
m_pEditObjectRuntimeClass = RUNTIME_CLASS(editCEditGameClass); |
|
m_nNumSelectedObjects = 0; |
|
m_pEntityPage = NULL; |
|
} |
|
|
|
COP_Flags::~COP_Flags() |
|
{ |
|
} |
|
|
|
void COP_Flags::SetEntityPage( COP_Entity *pPage ) |
|
{ |
|
m_pEntityPage = pPage; |
|
} |
|
|
|
void COP_Flags::DoDataExchange(CDataExchange* pDX) |
|
{ |
|
CObjectPage::DoDataExchange(pDX); |
|
//{{AFX_DATA_MAP(COP_Flags) |
|
// NOTE: the ClassWizard will add DDX and DDV calls here |
|
//}}AFX_DATA_MAP |
|
} |
|
|
|
BEGIN_MESSAGE_MAP(COP_Flags, CObjectPage) |
|
//{{AFX_MSG_MAP(COP_Flags) |
|
ON_CLBN_CHKCHANGE(IDC_CHECKLIST, OnCheckListChange) |
|
ON_WM_SIZE() |
|
//}}AFX_MSG_MAP |
|
END_MESSAGE_MAP() |
|
|
|
///////////////////////////////////////////////////////////////////////////// |
|
// COP_Flags message handlers |
|
|
|
void COP_Flags::UpdateData( int Mode, PVOID pData, bool bCanEdit ) |
|
{ |
|
__super::UpdateData( Mode, pData, bCanEdit ); |
|
|
|
if(!IsWindow(m_hWnd) || !pData) |
|
{ |
|
return; |
|
} |
|
|
|
CEditGameClass *pObj = (CEditGameClass*) pData; |
|
|
|
if (Mode == LoadFirstData) |
|
{ |
|
UpdateForClass(pObj); |
|
|
|
} |
|
else if (Mode == LoadData) |
|
{ |
|
MergeForClass(pObj); |
|
} |
|
CreateCheckList(); |
|
|
|
m_CheckList.EnableWindow( m_bCanEdit ? TRUE : FALSE ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool COP_Flags::SaveData(void) |
|
{ |
|
if (!IsWindow(m_hWnd)) |
|
{ |
|
return(false); |
|
} |
|
|
|
// |
|
// Apply the dialog data to all the objects being edited. |
|
// |
|
FOR_EACH_OBJ( *m_pObjectList, pos ) |
|
{ |
|
CMapClass *pObject = m_pObjectList->Element(pos); |
|
CEditGameClass *pEdit = dynamic_cast <CEditGameClass *>(pObject); |
|
Assert(pEdit != NULL); |
|
|
|
if ( pEdit != NULL ) |
|
{ |
|
for ( int i = 0; i < m_CheckListItems.Count(); i++ ) |
|
{ |
|
CheckListItem currentItem = m_CheckListItems.Element( i ); |
|
// don't save tri-stated bit |
|
if ( m_CheckList.GetCheck(i) != 2 ) |
|
{ |
|
pEdit->SetSpawnFlag( currentItem.nItemBit, m_CheckList.GetCheck(i) ? TRUE : FALSE ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return(true); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: This function is used to initialize the flag checklist. |
|
// It is called to place all the flags belonging to the first |
|
// selected object into the temporary CheckListItems vector |
|
//----------------------------------------------------------------------------- |
|
|
|
void COP_Flags::UpdateForClass(CEditGameClass* pObj) |
|
{ |
|
extern GameData *pGD; |
|
|
|
GDclass * pClass = pGD->ClassForName(pObj->GetClassName()); |
|
|
|
if(!IsWindow(m_hWnd)) |
|
return; |
|
|
|
m_nNumSelectedObjects = 1; |
|
|
|
m_CheckListItems.RemoveAll(); |
|
|
|
if(pClass) |
|
{ |
|
GDinputvariable *pVar = pClass->VarForName("spawnflags"); |
|
|
|
if (pVar) |
|
{ |
|
int nItems = pVar->GetFlagCount(); |
|
|
|
for ( int i = 0; i < nItems; i++ ) |
|
{ |
|
CheckListItem newItem; |
|
newItem.nItemBit = pVar->GetFlagMask( i ); |
|
newItem.pszItemString = pVar->GetFlagCaption( i ); |
|
newItem.state = pObj->GetSpawnFlag( newItem.nItemBit ) ? 1 : 0; |
|
m_CheckListItems.AddToTail( newItem ); |
|
} |
|
} |
|
} |
|
|
|
Assert( m_CheckListItems.Count() <= 32 ); |
|
|
|
for ( int i = 0; i < 32; i++ ) |
|
{ |
|
int nBitPattern = 1 << i; |
|
// is spawnflag for this bit set? |
|
if ( pObj->GetSpawnFlag(nBitPattern) ) |
|
{ |
|
int j; |
|
// then see if its allowed to be |
|
for ( j = 0; j < m_CheckListItems.Count(); j ++ ) |
|
{ |
|
int nCheckListPattern = m_CheckListItems.Element(j).nItemBit; |
|
if ( nCheckListPattern == nBitPattern ) |
|
break; |
|
} |
|
// we fail to find it? |
|
if ( j == m_CheckListItems.Count() ) |
|
{ |
|
CheckListItem newItem; |
|
newItem.nItemBit = nBitPattern; |
|
newItem.pszItemString = "????"; |
|
newItem.state = 1; |
|
m_CheckListItems.AddToTail( newItem ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: This function is called to combine flags when multiple objects are selected |
|
// It removes flags from the CheckListItem vector that are not present in all selected objects |
|
//----------------------------------------------------------------------------- |
|
void COP_Flags::MergeForClass(CEditGameClass* pObj) |
|
{ |
|
extern GameData *pGD; |
|
GDclass * pClass = pGD->ClassForName(pObj->GetClassName()); |
|
|
|
if( !IsWindow(m_hWnd) ) |
|
return; |
|
|
|
m_nNumSelectedObjects++; |
|
|
|
if( pClass ) |
|
{ |
|
GDinputvariable *pVar = pClass->VarForName("spawnflags"); |
|
|
|
for ( int i = m_CheckListItems.Count() - 1; i >= 0; i-- ) |
|
{ |
|
bool bFound = false; |
|
CheckListItem currentItem = m_CheckListItems.Element( i ); |
|
if ( pVar ) |
|
{ |
|
for ( int j = 0; j < pVar->GetFlagCount(); j++ ) |
|
{ |
|
CheckListItem newItem; |
|
newItem.nItemBit = pVar->GetFlagMask(j); |
|
newItem.pszItemString = pVar->GetFlagCaption(j); |
|
if ( newItem == currentItem ) |
|
{ |
|
bFound = true; |
|
int nNewState = pObj->GetSpawnFlag( newItem.nItemBit ) ? 1 : 0; |
|
if ( currentItem.state != nNewState ) |
|
{ |
|
m_CheckListItems.Element( i ).state = 2; |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
if ( !bFound ) |
|
{ |
|
m_CheckListItems.FastRemove( i ); |
|
} |
|
} |
|
} |
|
Assert( m_CheckListItems.Count() <= 32 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Creates the checklist by stepping through the CheckListItems vector that |
|
// was created during Update/MergeForClass |
|
//----------------------------------------------------------------------------- |
|
void COP_Flags::CreateCheckList() |
|
{ |
|
m_CheckList.ResetContent(); |
|
|
|
if ( m_nNumSelectedObjects > 1 ) |
|
{ |
|
m_CheckList.SetCheckStyle(BS_AUTO3STATE); |
|
} |
|
|
|
for ( int i = 0; i < m_CheckListItems.Count(); i++ ) |
|
{ |
|
CheckListItem newItem = m_CheckListItems.Element(i); |
|
m_CheckList.InsertString(i, newItem.pszItemString); |
|
m_CheckList.SetCheck(i, newItem.state); |
|
} |
|
} |
|
|
|
void COP_Flags::OnUpdateSpawnFlags( unsigned long value ) |
|
{ |
|
for ( int i=0; i < m_CheckListItems.Count(); i++ ) |
|
{ |
|
CheckListItem &item = m_CheckListItems[i]; |
|
m_CheckList.SetCheck( i, (value & item.nItemBit) != 0 ); |
|
} |
|
} |
|
|
|
BOOL COP_Flags::OnInitDialog() |
|
{ |
|
CObjectPage::OnInitDialog(); |
|
|
|
m_nNumSelectedObjects = 0; |
|
|
|
// Subclass checklistbox |
|
m_CheckList.SubclassDlgItem(IDC_CHECKLIST, this); |
|
m_CheckList.SetCheckStyle(BS_AUTOCHECKBOX); |
|
m_CheckList.ResetContent(); |
|
|
|
CAnchorDef anchorDefs[] = |
|
{ |
|
CAnchorDef( IDC_CHECKLIST, k_eSimpleAnchorAllSides ) |
|
}; |
|
m_AnchorMgr.Init( GetSafeHwnd(), anchorDefs, ARRAYSIZE( anchorDefs ) ); |
|
|
|
return TRUE; |
|
} |
|
|
|
void COP_Flags::OnCheckListChange() |
|
{ |
|
if ( !m_pEntityPage ) |
|
return; |
|
|
|
unsigned long bitsSet = 0; |
|
unsigned long triStateMask = 0; |
|
|
|
// This is just like SaveData.. collect the state of all the checks. |
|
for ( int i = 0; i < m_CheckListItems.Count(); i++ ) |
|
{ |
|
CheckListItem currentItem = m_CheckListItems.Element( i ); |
|
|
|
// If multiple of the selected entities have a different value for this flag, |
|
// note that. The entity page will use triStateMask to denote flags that |
|
// it should leave alone. |
|
if ( m_CheckList.GetCheck(i) == 2 ) |
|
triStateMask |= currentItem.nItemBit; |
|
else if ( m_CheckList.GetCheck( i ) ) |
|
bitsSet |= currentItem.nItemBit; |
|
} |
|
|
|
m_pEntityPage->OnUpdateSpawnFlags( triStateMask, bitsSet ); |
|
} |
|
|
|
void COP_Flags::OnSize( UINT nType, int cx, int cy ) |
|
{ |
|
m_AnchorMgr.OnSize(); |
|
}
|
|
|