diff options
Diffstat (limited to 'hammer/op_flags.cpp')
| -rw-r--r-- | hammer/op_flags.cpp | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/hammer/op_flags.cpp b/hammer/op_flags.cpp new file mode 100644 index 0000000..642c3d6 --- /dev/null +++ b/hammer/op_flags.cpp @@ -0,0 +1,316 @@ +//========= 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(); +} |