summaryrefslogtreecommitdiff
path: root/hammer/op_flags.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/op_flags.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'hammer/op_flags.cpp')
-rw-r--r--hammer/op_flags.cpp316
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();
+}