mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user