mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-27 07:54:51 +01:00
2035 lines
77 KiB
C++
2035 lines
77 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
|
|
|
// PropertyComboBar.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "PropertyComboBar.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef new
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPropertyComboBar dialog
|
|
|
|
BOOL CPropertyComboBar::Create( CWnd* pParentWnd, UINT nIDTemplate,
|
|
UINT nStyle, UINT nID, BOOL bChange)
|
|
{
|
|
if(!CDialogBar::Create(pParentWnd,nIDTemplate,nStyle,nID))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_Size = m_sizeDefault;
|
|
|
|
// subclass property combo box
|
|
m_PropertyComboBox.SubclassDlgItem( IDC_PROPERTYCOMBO, this);
|
|
// subclass enum combo box
|
|
m_EditEnumComboBox.SubclassDlgItem( IDC_EDIT_ENUM, this);
|
|
// subclass edit string control
|
|
m_EditStringCtrl.SubclassDlgItem( IDC_EDIT_STRING, this);
|
|
// subclass edit float control
|
|
m_EditFloatCtrl.SubclassDlgItem( IDC_EDIT_FLOAT, this);
|
|
// for andgle 3D
|
|
m_EditHeading.SubclassDlgItem( IDC_EDIT_HEADING, this);
|
|
m_EditPitch.SubclassDlgItem( IDC_EDIT_PITCH, this);
|
|
m_EditBanking.SubclassDlgItem( IDC_EDIT_BANKING, this);
|
|
// subclass edit BBox control
|
|
m_XCtrlAxisRadio.SubclassDlgItem( IDC_AXIS_X, this);
|
|
m_YCtrlAxisRadio.SubclassDlgItem( IDC_AXIS_Y, this);
|
|
m_ZCtrlAxisRadio.SubclassDlgItem( IDC_AXIS_Z, this);
|
|
m_EditBBoxMinCtrl.SubclassDlgItem( IDC_EDIT_BBOX_MIN, this);
|
|
m_EditBBoxMaxCtrl.SubclassDlgItem( IDC_EDIT_BBOX_MAX, this);
|
|
// subclass edit index control
|
|
m_EditIndexCtrl.SubclassDlgItem( IDC_EDIT_INDEX, this);
|
|
// subclass edit boolean control
|
|
m_EditBoolCtrl.SubclassDlgItem( IDC_EDIT_BOOL, this);
|
|
// subclass edit color control
|
|
m_EditColorCtrl.SetPickerType( CColoredButton::PT_MFC);
|
|
m_EditColorCtrl.SubclassDlgItem( IDC_EDIT_COLOR, this);
|
|
|
|
// subclass flag field property ctrl
|
|
m_ctrlEditFlags.SubclassDlgItem( ID_FLAGS_PROPERTY, this);
|
|
|
|
// subclass browse file control
|
|
m_BrowseFileCtrl.SubclassDlgItem( IDC_BROWSE_FILE, this);
|
|
|
|
// subclass difficulty spawn flags
|
|
m_EditEasySpawn.SubclassDlgItem( IDC_EASY, this);
|
|
m_EditNormalSpawn.SubclassDlgItem( IDC_NORMAL, this);
|
|
m_EditHardSpawn.SubclassDlgItem( IDC_HARD, this);
|
|
m_EditExtremeSpawn.SubclassDlgItem( IDC_EXTREME, this);
|
|
m_EditDifficulty_1.SubclassDlgItem( IDC_DIFFICULTY_1, this);
|
|
m_EditDifficulty_2.SubclassDlgItem( IDC_DIFFICULTY_2, this);
|
|
m_EditDifficulty_3.SubclassDlgItem( IDC_DIFFICULTY_3, this);
|
|
m_EditDifficulty_4.SubclassDlgItem( IDC_DIFFICULTY_4, this);
|
|
m_EditDifficulty_5.SubclassDlgItem( IDC_DIFFICULTY_5, this);
|
|
|
|
// subclass game mode spawn flags
|
|
m_EditSingleSpawn.SubclassDlgItem( IDC_SINGLE, this);
|
|
m_EditCooperativeSpawn.SubclassDlgItem( IDC_COOPERATIVE, this);
|
|
m_EditDeathMatchSpawn.SubclassDlgItem( IDC_DEATHMATCH, this);
|
|
m_EditGameMode_1.SubclassDlgItem( IDC_GAME_MODE_1, this);
|
|
m_EditGameMode_2.SubclassDlgItem( IDC_GAME_MODE_2, this);
|
|
m_EditGameMode_3.SubclassDlgItem( IDC_GAME_MODE_3, this);
|
|
m_EditGameMode_4.SubclassDlgItem( IDC_GAME_MODE_4, this);
|
|
m_EditGameMode_5.SubclassDlgItem( IDC_GAME_MODE_5, this);
|
|
m_EditGameMode_6.SubclassDlgItem( IDC_GAME_MODE_6, this);
|
|
|
|
// set dialog ptrs to controls
|
|
m_PropertyComboBox.SetDialogPtr( this);
|
|
m_EditEnumComboBox.SetDialogPtr( this);
|
|
m_EditStringCtrl.SetDialogPtr( this);
|
|
m_EditFloatCtrl.SetDialogPtr( this);
|
|
m_EditHeading.SetDialogPtr( this);
|
|
m_EditPitch.SetDialogPtr( this);
|
|
m_EditBanking.SetDialogPtr( this);
|
|
m_EditIndexCtrl.SetDialogPtr( this);
|
|
m_EditBBoxMinCtrl.SetDialogPtr( this);
|
|
m_EditBBoxMaxCtrl.SetDialogPtr( this);
|
|
m_XCtrlAxisRadio.SetDialogPtr( this);
|
|
m_YCtrlAxisRadio.SetDialogPtr( this);
|
|
m_ZCtrlAxisRadio.SetDialogPtr( this);
|
|
m_EditBoolCtrl.SetDialogPtr( this);
|
|
m_BrowseFileCtrl.SetDialogPtr( this);
|
|
|
|
m_EditEasySpawn.SetDialogPtr( this);
|
|
m_EditNormalSpawn.SetDialogPtr( this);
|
|
m_EditHardSpawn.SetDialogPtr( this);
|
|
m_EditExtremeSpawn.SetDialogPtr( this);
|
|
m_EditDifficulty_1.SetDialogPtr( this);
|
|
m_EditDifficulty_2.SetDialogPtr( this);
|
|
m_EditDifficulty_3.SetDialogPtr( this);
|
|
m_EditDifficulty_4.SetDialogPtr( this);
|
|
m_EditDifficulty_5.SetDialogPtr( this);
|
|
|
|
m_EditSingleSpawn.SetDialogPtr( this);
|
|
m_EditCooperativeSpawn.SetDialogPtr( this);
|
|
m_EditDeathMatchSpawn.SetDialogPtr( this);
|
|
m_EditGameMode_1.SetDialogPtr( this);
|
|
m_EditGameMode_2.SetDialogPtr( this);
|
|
m_EditGameMode_3.SetDialogPtr( this);
|
|
m_EditGameMode_4.SetDialogPtr( this);
|
|
m_EditGameMode_5.SetDialogPtr( this);
|
|
m_EditGameMode_6.SetDialogPtr( this);
|
|
m_ctrlEditFlags.SetDialogPtr( this);
|
|
|
|
// set font for properties combo
|
|
m_PropertyComboBox.SetFont(&theApp.m_Font);
|
|
// set font for enum combo
|
|
m_EditEnumComboBox.SetFont(&theApp.m_Font);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CPropertyComboBar, CDialogBar)
|
|
//{{AFX_MSG_MAP(CPropertyComboBar)
|
|
ON_WM_HSCROLL()
|
|
//}}AFX_MSG_MAP
|
|
ON_UPDATE_COMMAND_UI(IDC_BROWSE_FILE, OnUpdateBrowseFile)
|
|
ON_UPDATE_COMMAND_UI(IDC_NO_FILE, OnUpdateNoFile)
|
|
ON_UPDATE_COMMAND_UI(IDC_NO_TARGET, OnUpdateNoTarget)
|
|
ON_UPDATE_COMMAND_UI(IDC_EDIT_COLOR, OnUpdateEditColor)
|
|
ON_UPDATE_COMMAND_UI(ID_FLAGS_PROPERTY, OnUpdateEditFlags)
|
|
ON_COMMAND(IDC_NO_FILE, OnNoFile)
|
|
ON_COMMAND(IDC_NO_TARGET, OnNoTarget)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPropertyComboBar message handlers
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
void CPropertyComboBar::SelectAxisRadio(CWnd *pwndToSelect)
|
|
{
|
|
// deselect all three axis radios
|
|
m_XCtrlAxisRadio.SetCheck( 0);
|
|
m_YCtrlAxisRadio.SetCheck( 0);
|
|
m_ZCtrlAxisRadio.SetCheck( 0);
|
|
// select right one
|
|
if( pwndToSelect == &m_XCtrlAxisRadio) {m_XCtrlAxisRadio.SetCheck( 1); m_iXYZAxis=1;};
|
|
if( pwndToSelect == &m_YCtrlAxisRadio) {m_YCtrlAxisRadio.SetCheck( 1); m_iXYZAxis=2;};
|
|
if( pwndToSelect == &m_ZCtrlAxisRadio) {m_ZCtrlAxisRadio.SetCheck( 1); m_iXYZAxis=3;};
|
|
}
|
|
|
|
void CPropertyComboBar::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// if dialog is recieving data
|
|
if( pDX->m_bSaveAndValidate == FALSE)
|
|
{
|
|
SetIntersectingEntityClassName();
|
|
SetIntersectingFileName();
|
|
// set spawn flags...
|
|
// obtain selected property ID ptr
|
|
CPropertyID *ppidProperty = GetSelectedProperty();
|
|
// if there is valid property selected
|
|
if( ppidProperty != NULL)
|
|
{
|
|
// reset selection entities spawn on and off masks
|
|
ULONG ulSpawnOn = MAX_ULONG;
|
|
ULONG ulSpawnOff = MAX_ULONG;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// intersect current mask with spawn mask of all selected entities
|
|
ulSpawnOn &= iten->GetSpawnFlags();
|
|
ulSpawnOff&= ~iten->GetSpawnFlags();
|
|
}
|
|
|
|
#define SET_SPAWN_FLAG( flag, ctrl) \
|
|
if((ulSpawnOn & (flag)) && !(ulSpawnOff & (flag))) ctrl.SetCheck( 1); \
|
|
else if(!(ulSpawnOn & (flag)) && (ulSpawnOff & (flag))) ctrl.SetCheck( 0); \
|
|
else ctrl.SetCheck( 2);
|
|
|
|
// set states of all spawn flags using calculated selected entities masks
|
|
SET_SPAWN_FLAG( SPF_EASY, m_EditEasySpawn);
|
|
SET_SPAWN_FLAG( SPF_NORMAL, m_EditNormalSpawn);
|
|
SET_SPAWN_FLAG( SPF_HARD, m_EditHardSpawn);
|
|
SET_SPAWN_FLAG( SPF_EXTREME, m_EditExtremeSpawn);
|
|
SET_SPAWN_FLAG( SPF_EXTREME<<1, m_EditDifficulty_1);
|
|
SET_SPAWN_FLAG( SPF_EXTREME<<2, m_EditDifficulty_2);
|
|
SET_SPAWN_FLAG( SPF_EXTREME<<3, m_EditDifficulty_3);
|
|
SET_SPAWN_FLAG( SPF_EXTREME<<4, m_EditDifficulty_4);
|
|
SET_SPAWN_FLAG( SPF_EXTREME<<5, m_EditDifficulty_5);
|
|
|
|
SET_SPAWN_FLAG( SPF_SINGLEPLAYER, m_EditSingleSpawn);
|
|
SET_SPAWN_FLAG( SPF_DEATHMATCH, m_EditDeathMatchSpawn);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE, m_EditCooperativeSpawn);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE<<1, m_EditGameMode_1);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE<<2, m_EditGameMode_2);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE<<3, m_EditGameMode_3);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE<<4, m_EditGameMode_4);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE<<5, m_EditGameMode_5);
|
|
SET_SPAWN_FLAG( SPF_COOPERATIVE<<6, m_EditGameMode_6);
|
|
}
|
|
}
|
|
|
|
DDX_Text(pDX, IDC_FLOAT_RANGE_T, m_strFloatRange);
|
|
DDX_Text(pDX, IDC_INDEX_RANGE_T, m_strIndexRange);
|
|
DDX_Text(pDX, IDC_CHOOSE_COLOR_T, m_strChooseColor);
|
|
DDX_Text(pDX, IDC_FILE_NAME_T, m_strFileName);
|
|
DDX_Text(pDX, IDC_ENTITY_CLASS, m_strEntityClass);
|
|
DDX_Text(pDX, IDC_ENTITY_NAME, m_strEntityName);
|
|
DDX_Text(pDX, IDC_ENTITY_DESCRIPTION, m_strEntityDescription);
|
|
|
|
if( m_EditBBoxMinCtrl.IsWindowVisible())
|
|
{
|
|
DDX_SkyFloat(pDX, IDC_EDIT_BBOX_MIN, m_fEditingBBoxMin);
|
|
DDX_SkyFloat(pDX, IDC_EDIT_BBOX_MAX, m_fEditingBBoxMax);
|
|
}
|
|
if( m_EditStringCtrl.IsWindowVisible())
|
|
{
|
|
DDX_Text(pDX, IDC_EDIT_STRING, m_strEditingString);
|
|
}
|
|
if( m_EditFloatCtrl.IsWindowVisible())
|
|
{
|
|
DDX_SkyFloat(pDX, IDC_EDIT_FLOAT, m_fEditingFloat);
|
|
}
|
|
if( m_EditHeading.IsWindowVisible())
|
|
{
|
|
DDX_SkyFloat(pDX, IDC_EDIT_HEADING, m_fEditingHeading);
|
|
}
|
|
if( m_EditPitch.IsWindowVisible())
|
|
{
|
|
DDX_SkyFloat(pDX, IDC_EDIT_PITCH, m_fEditingPitch);
|
|
}
|
|
if( m_EditBanking.IsWindowVisible())
|
|
{
|
|
DDX_SkyFloat(pDX, IDC_EDIT_BANKING, m_fEditingBanking);
|
|
}
|
|
if( m_EditIndexCtrl.IsWindowVisible())
|
|
{
|
|
DDX_Text(pDX, IDC_EDIT_INDEX, m_iEditingIndex);
|
|
}
|
|
|
|
// if dialog is giving data
|
|
if( pDX->m_bSaveAndValidate != FALSE)
|
|
{
|
|
// obtain selected property ID ptr
|
|
CPropertyID *ppidProperty = GetSelectedProperty();
|
|
// if there is valid property selected
|
|
if( ppidProperty != NULL)
|
|
{
|
|
// see type of changing property
|
|
switch( ppidProperty->pid_eptType)
|
|
{
|
|
// if we are changing flag field
|
|
case CEntityProperty::EPT_FLAGS:
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new flag value
|
|
m_ctrlEditFlags.ApplyChange( ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ULONG));
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
// if we are changing enum property
|
|
case CEntityProperty::EPT_ENUM:
|
|
{
|
|
// get currently selected combo member
|
|
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
|
|
// it must exist
|
|
if( iSelectedComboMember == CB_ERR) return;
|
|
// get enum ID to be set for all entities
|
|
INDEX iSelectedEnumID = m_EditEnumComboBox.GetItemData(iSelectedComboMember);
|
|
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new enum value
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iSelectedEnumID;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_ANIMATION:
|
|
{
|
|
// get currently selected combo member
|
|
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
|
|
// it must exist
|
|
if( iSelectedComboMember == CB_ERR) return;
|
|
// get animation to be set for all entities
|
|
INDEX iSelectedAnimation = m_EditEnumComboBox.GetItemData(iSelectedComboMember);
|
|
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new animation
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iSelectedAnimation;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
// if we are changing illumination type property
|
|
case CEntityProperty::EPT_ILLUMINATIONTYPE:
|
|
{
|
|
// get currently selected combo member
|
|
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
|
|
// it must exist
|
|
if( iSelectedComboMember == CB_ERR) return;
|
|
// get illumination type to be set for all entities
|
|
INDEX iIlluminationType = m_EditEnumComboBox.GetItemData(iSelectedComboMember);
|
|
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new illumination type value
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iIlluminationType;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
// if we are changing string property
|
|
case CEntityProperty::EPT_STRING:
|
|
case CEntityProperty::EPT_STRINGTRANS:
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new string
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTString) = CStringA(m_strEditingString);
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
// mark that document changed so that OnIdle on CSG destination combo would
|
|
// refresh combo entries (because we could be changing world name)
|
|
pDoc->m_chDocument.MarkChanged();
|
|
break;
|
|
}
|
|
// if we are changing float, range or angle property
|
|
case CEntityProperty::EPT_FLOAT:
|
|
case CEntityProperty::EPT_RANGE:
|
|
case CEntityProperty::EPT_ANGLE:
|
|
case CEntityProperty::EPT_ANGLE3D:
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// discard old entity settings
|
|
iten->End();
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if we are editing angle property
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE3D)
|
|
{
|
|
// set new angle 3d
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D) =
|
|
ANGLE3D(AngleDeg(m_fEditingHeading), AngleDeg(m_fEditingPitch),
|
|
AngleDeg(m_fEditingBanking));
|
|
}
|
|
else if(ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE)
|
|
{
|
|
// set new angle
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT) = AngleDeg(m_fEditingFloat);
|
|
}
|
|
else
|
|
{
|
|
// set new float or range
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT) = m_fEditingFloat;
|
|
}
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_FLOATAABBOX3D:
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// get old (pre-changed) value for bounding box
|
|
FLOATaabbox3D bboxOld = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset,
|
|
FLOATaabbox3D);
|
|
// get its min and max vectors
|
|
FLOAT3D vMin = bboxOld.Min();
|
|
FLOAT3D vMax = bboxOld.Max();
|
|
// set new min and max bbox values for currently selected axis
|
|
vMin( m_iXYZAxis) = m_fEditingBBoxMin;
|
|
vMax( m_iXYZAxis) = m_fEditingBBoxMax;
|
|
// create new bbox and set it into property
|
|
FLOATaabbox3D bboxNew( vMin, vMax);
|
|
// discard old entity settings
|
|
iten->End();
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOATaabbox3D) = bboxNew;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_INDEX:
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
INDEX iNewValue = m_iEditingIndex;
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new index
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iNewValue;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
break;
|
|
}
|
|
// if we are changing file name property
|
|
case CEntityProperty::EPT_FILENAME:
|
|
{
|
|
// file name changing function is done inside CBrowseFile.cpp
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_COLOR:
|
|
{
|
|
break;
|
|
}
|
|
// if we are changing bool property
|
|
case CEntityProperty::EPT_BOOL:
|
|
{
|
|
// get state of check box
|
|
INDEX iCheckBox = m_EditBoolCtrl.GetCheck();
|
|
// must be 0 or 1
|
|
if( iCheckBox != 2)
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new boolean value
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, BOOL) = iCheckBox;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
// if we are changing entity ptr property
|
|
case CEntityProperty::EPT_ENTITYPTR:
|
|
case CEntityProperty::EPT_PARENT:
|
|
{
|
|
// get currently selected combo member
|
|
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
|
|
// it must exist
|
|
if( iSelectedComboMember == CB_ERR) return;
|
|
// get entity ptr to be set for all entities
|
|
CEntity *penEntity = (CEntity *)m_EditEnumComboBox.GetItemData(iSelectedComboMember);
|
|
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT)
|
|
{
|
|
iten->SetParent( penEntity);
|
|
}
|
|
else
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new entity ptr value
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer) = penEntity;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
// if we are changing entity ptr property
|
|
case CEntityProperty::EPT_SPAWNFLAGS:
|
|
{
|
|
// obtain spawn on and off masks
|
|
ULONG ulBitsToClear = MAX_ULONG;
|
|
ULONG ulBitsToSet = 0;
|
|
|
|
#define GET_SPAWN_MASKS( flag, ctrl) \
|
|
if( ctrl.GetCheck() == 0) ulBitsToClear &= ~(flag); \
|
|
if( ctrl.GetCheck() == 1) ulBitsToSet |= (flag);
|
|
|
|
// look at spawn checks and create masks of bits to set and to clear
|
|
GET_SPAWN_MASKS( SPF_EASY, m_EditEasySpawn);
|
|
GET_SPAWN_MASKS( SPF_NORMAL, m_EditNormalSpawn);
|
|
GET_SPAWN_MASKS( SPF_HARD, m_EditHardSpawn);
|
|
GET_SPAWN_MASKS( SPF_EXTREME, m_EditExtremeSpawn);
|
|
GET_SPAWN_MASKS( SPF_EXTREME<<1, m_EditDifficulty_1);
|
|
GET_SPAWN_MASKS( SPF_EXTREME<<2, m_EditDifficulty_2);
|
|
GET_SPAWN_MASKS( SPF_EXTREME<<3, m_EditDifficulty_3);
|
|
GET_SPAWN_MASKS( SPF_EXTREME<<4, m_EditDifficulty_4);
|
|
GET_SPAWN_MASKS( SPF_EXTREME<<5, m_EditDifficulty_5);
|
|
|
|
GET_SPAWN_MASKS( SPF_SINGLEPLAYER, m_EditSingleSpawn);
|
|
GET_SPAWN_MASKS( SPF_DEATHMATCH, m_EditDeathMatchSpawn);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE, m_EditCooperativeSpawn);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE<<1, m_EditGameMode_1);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE<<2, m_EditGameMode_2);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE<<3, m_EditGameMode_3);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE<<4, m_EditGameMode_4);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE<<5, m_EditGameMode_5);
|
|
GET_SPAWN_MASKS( SPF_COOPERATIVE<<6, m_EditGameMode_6);
|
|
|
|
// for each of the selected entities set spawn flags
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// clear and set curently selected spawn flags to all selected entities
|
|
iten->SetSpawnFlags(iten->GetSpawnFlags() & ulBitsToClear);
|
|
iten->SetSpawnFlags(iten->GetSpawnFlags() | ulBitsToSet);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ASSERTALWAYS("Unknown property type");
|
|
}
|
|
}
|
|
// mark that document is changed
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
// redraw all views
|
|
pDoc->UpdateAllViews( NULL);
|
|
}
|
|
}
|
|
|
|
CDialogBar::DoDataExchange(pDX);
|
|
}
|
|
//--------------------------------------------------------------------------------------------
|
|
CSize CPropertyComboBar::CalcDynamicLayout(int nLength, DWORD nMode)
|
|
{
|
|
CSize csResult;
|
|
// Return default if it is being docked or floated
|
|
if ((nMode & LM_VERTDOCK) || (nMode & LM_HORZDOCK))
|
|
{
|
|
if (nMode & LM_STRETCH) // if not docked stretch to fit
|
|
{
|
|
csResult = CSize((nMode & LM_HORZ) ? 32767 : m_Size.cx,
|
|
(nMode & LM_HORZ) ? m_Size.cy : 32767);
|
|
}
|
|
else
|
|
{
|
|
csResult = m_Size;
|
|
}
|
|
}
|
|
else if (nMode & LM_MRUWIDTH)
|
|
{
|
|
csResult = m_Size;
|
|
}
|
|
// In all other cases, accept the dynamic length
|
|
else
|
|
{
|
|
if (nMode & LM_LENGTHY)
|
|
{
|
|
// Note that we don't change m_Size.cy because we disabled vertical sizing
|
|
csResult = CSize( m_Size.cx, m_Size.cy = nLength);
|
|
}
|
|
else
|
|
{
|
|
csResult = CSize( m_Size.cx = nLength, m_Size.cy);
|
|
}
|
|
}
|
|
|
|
#define CTRLS_LINE_H 22
|
|
#define CTRLS_RW 40
|
|
#define CTRLS_RH 44
|
|
#define CTRLS_YS 38+CTRLS_RH
|
|
#define CTRLS_YE (CTRLS_YS+CTRLS_LINE_H)
|
|
#define CTRLS_YRS 28+CTRLS_RH
|
|
#define CTRLS_YRE (CTRLS_YRS+CTRLS_RH)
|
|
#define CTRLS_YTS 44+CTRLS_RH
|
|
#define CTRLS_YTE (CTRLS_YTS+CTRLS_LINE_H)
|
|
#define CTRLS_YCMRS CTRLS_YS-4 // y color radio mode start
|
|
#define CTRLS_YCSS CTRLS_YCMRS+26 // y color sliders start
|
|
#define CTRLS_YNTS 64+CTRLS_RH // no target button
|
|
#define CTRLS_YNTE (CTRLS_YNTS+CTRLS_LINE_H)
|
|
#define CTRLS_BUTTONW 40
|
|
// set entity class text position
|
|
GetDlgItem( IDC_ENTITY_CLASS)->MoveWindow( CRect( 8, 4, csResult.cx - 8, 4+14));
|
|
// set entity name text position
|
|
GetDlgItem( IDC_ENTITY_NAME)->MoveWindow( CRect( 8, 18, csResult.cx - 8, 18+14));
|
|
// set entity description text position
|
|
GetDlgItem( IDC_ENTITY_DESCRIPTION)->MoveWindow( CRect( 8, 32, csResult.cx - 8, 32+14));
|
|
// set property combo size and position
|
|
m_PropertyComboBox.MoveWindow( CRect( 8, 5+CTRLS_RH, csResult.cx - 8, 120+CTRLS_RH));
|
|
// set enum combo size and position
|
|
m_EditEnumComboBox.MoveWindow( CRect( 8, CTRLS_YS, csResult.cx - 8, 120+CTRLS_RH));
|
|
// set edit string control size and position
|
|
m_EditStringCtrl.MoveWindow( CRect( 8, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
|
|
// set edit float control size and position
|
|
m_EditFloatCtrl.MoveWindow( CRect( csResult.cx/2, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
|
|
// set edit BBox controls size and position
|
|
GetDlgItem( IDC_AXIS_X)->MoveWindow( CRect( csResult.cx/2-CTRLS_RW*3/2, CTRLS_YRS,
|
|
csResult.cx/2-CTRLS_RW/2, CTRLS_YRE));
|
|
GetDlgItem( IDC_AXIS_Y)->MoveWindow( CRect( csResult.cx/2-CTRLS_RW/2, CTRLS_YRS,
|
|
csResult.cx/2+CTRLS_RW/2, CTRLS_YRE) );
|
|
GetDlgItem( IDC_AXIS_Z)->MoveWindow( CRect( csResult.cx/2+CTRLS_RW/2, CTRLS_YRS,
|
|
csResult.cx/2+CTRLS_RW*3/2, CTRLS_YRE) );
|
|
m_EditBBoxMinCtrl.MoveWindow( CRect( 8, CTRLS_YRE,
|
|
csResult.cx/2-8, CTRLS_YRE+CTRLS_LINE_H) );
|
|
m_EditBBoxMaxCtrl.MoveWindow( CRect( csResult.cx/2+8, CTRLS_YRE,
|
|
csResult.cx-8, CTRLS_YRE+CTRLS_LINE_H) );
|
|
// select x axis by default for editing bbox
|
|
SelectAxisRadio( &m_XCtrlAxisRadio);
|
|
// set edit index control size and position
|
|
m_EditIndexCtrl.MoveWindow( CRect( csResult.cx/2, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
|
|
// set float range description message size and position
|
|
GetDlgItem( IDC_FLOAT_RANGE_T)->MoveWindow( CRect( 8, CTRLS_YTS, csResult.cx/2, CTRLS_YTE));
|
|
// set index range description message size and position
|
|
GetDlgItem( IDC_INDEX_RANGE_T)->MoveWindow( CRect( 8, CTRLS_YTS, csResult.cx/2, csResult.cy));
|
|
// set edit boolean control size and position
|
|
m_EditBoolCtrl.MoveWindow( CRect( 8, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
|
|
|
|
// set float range description message size and position
|
|
GetDlgItem( IDC_ANGLE3D_T)->MoveWindow( CRect( 8, CTRLS_YTS+4, csResult.cx/4-4, CTRLS_YTE+4));
|
|
GetDlgItem( IDC_EDIT_HEADING)->MoveWindow( CRect( csResult.cx/4-4, CTRLS_YTS, csResult.cx/4*2-4, CTRLS_YTE));
|
|
GetDlgItem( IDC_EDIT_PITCH)->MoveWindow( CRect( csResult.cx/4*2-4, CTRLS_YTS, csResult.cx/4*3-4, CTRLS_YTE));
|
|
GetDlgItem( IDC_EDIT_BANKING)->MoveWindow( CRect( csResult.cx/4*3-4, CTRLS_YTS, csResult.cx-4, CTRLS_YTE));
|
|
|
|
// set size and position of color picker
|
|
m_EditColorCtrl.MoveWindow( CRect( 8, CTRLS_YCMRS, 128, CTRLS_YCMRS+(CTRLS_LINE_H*1.25)));
|
|
|
|
// set size and position of flags array
|
|
m_ctrlEditFlags.MoveWindow( CRect( 8, CTRLS_YCMRS+12, csResult.cx-4, CTRLS_YCMRS+(CTRLS_LINE_H*1.0)+12));
|
|
|
|
// set color description message size and position
|
|
GetDlgItem( IDC_CHOOSE_COLOR_T)->MoveWindow( CRect( 4, CTRLS_YCSS-4, 16, csResult.cy-4));
|
|
// set browse file button size and position
|
|
m_BrowseFileCtrl.MoveWindow( CRect( csResult.cx-CTRLS_BUTTONW-16, CTRLS_YS, csResult.cx - 24, CTRLS_YE));
|
|
GetDlgItem( IDC_NO_FILE)->MoveWindow( CRect( csResult.cx-24, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
|
|
GetDlgItem( IDC_NO_TARGET)->MoveWindow( CRect( 8, CTRLS_YNTS, csResult.cx - 8, CTRLS_YNTE));
|
|
// set browse file description message size and position
|
|
GetDlgItem( IDC_FILE_NAME_T)->MoveWindow( CRect( 8, CTRLS_YTS, csResult.cx - CTRLS_BUTTONW-16, CTRLS_YTE));
|
|
return csResult;
|
|
}
|
|
|
|
CPropertyID *CPropertyComboBar::GetSelectedProperty()
|
|
{
|
|
INDEX iSelectedProperty = m_PropertyComboBox.GetCurSel();
|
|
if( (iSelectedProperty == CB_ERR) || ( iSelectedProperty < 0) )
|
|
{
|
|
//ASSERTALWAYS( "GetSelectedProperty() must not be called if there are no joined properties");
|
|
return NULL;
|
|
}
|
|
CPropertyID *ppidProperty = (CPropertyID *)
|
|
m_PropertyComboBox.GetItemData( iSelectedProperty);
|
|
ASSERT( ppidProperty != (CPropertyID *) -1);
|
|
return ppidProperty;
|
|
}
|
|
|
|
void CPropertyComboBar::SetFirstValidEmptyTargetProperty(CEntity *penTarget)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL) return;
|
|
|
|
for( INDEX iItem=0; iItem<m_PropertyComboBox.GetCount(); iItem++)
|
|
{
|
|
CPropertyID *ppidProperty = (CPropertyID *) m_PropertyComboBox.GetItemData( iItem);
|
|
ASSERT( ppidProperty != (CPropertyID *) -1);
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR)
|
|
{
|
|
// for each of the selected entities
|
|
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// check that all entities with this property target NULL and that supposed target is valid
|
|
CEntity *penOldTarget = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer);
|
|
BOOL bValidTarget = iten->IsTargetValid( penpProperty->ep_slOffset, penTarget);
|
|
// if this ptr is already set
|
|
if( penOldTarget==penTarget)
|
|
{
|
|
// don't do anything
|
|
return;
|
|
}
|
|
// stop checking if ptr isn't NULL or if not valid target
|
|
if( penOldTarget!=NULL || !bValidTarget)
|
|
{
|
|
continue;
|
|
}
|
|
// for each of the selected entities
|
|
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// discard old entity settings
|
|
iten->End();
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// set clicked entity as one that selected entity points to
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer) = penTarget;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}}
|
|
m_PropertyComboBox.SetCurSel(iItem);
|
|
m_PropertyComboBox.SelectProperty();
|
|
pDoc->m_chSelections.MarkChanged();
|
|
return;
|
|
}}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPropertyComboBar::SelectPreviousEmptyTarget(void)
|
|
{
|
|
CircleTargetProperties( -1, TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::SelectPreviousProperty(void)
|
|
{
|
|
CircleTargetProperties( -1, FALSE);
|
|
}
|
|
|
|
void CPropertyComboBar::SelectNextEmptyTarget(void)
|
|
{
|
|
CircleTargetProperties( 1, TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::SelectNextProperty(void)
|
|
{
|
|
CircleTargetProperties( 1, FALSE);
|
|
}
|
|
|
|
void CPropertyComboBar::CircleTargetProperties(INDEX iDirection, BOOL bOnlyEmptyTargets)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL)
|
|
{
|
|
return;
|
|
}
|
|
INDEX ctProperties = m_PropertyComboBox.GetCount();
|
|
// if no properties
|
|
if( ctProperties == 0) return;
|
|
// if selected is invalid
|
|
INDEX iSelectedProperty = m_PropertyComboBox.GetCurSel();
|
|
if( (iSelectedProperty == CB_ERR) || ( iSelectedProperty < 0) ) return;
|
|
// set invalid result
|
|
INDEX iToSelect = -1;
|
|
// browse trough entities
|
|
for( INDEX iItem=1; iItem<ctProperties; iItem++)
|
|
{
|
|
// we will use next/previos item for selecting
|
|
INDEX iToTest = (iSelectedProperty+ctProperties+iDirection*iItem)%ctProperties;
|
|
// if there is valid property selected
|
|
CPropertyID *ppidProperty = (CPropertyID *) m_PropertyComboBox.GetItemData( iToTest);
|
|
if( ppidProperty == NULL)
|
|
{
|
|
ASSERTALWAYS("Null property found!");
|
|
return;
|
|
}
|
|
// if null-ptr target is requested
|
|
if( bOnlyEmptyTargets)
|
|
{
|
|
// if this is entity pointer property
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR)
|
|
{
|
|
// obtain property ptr
|
|
CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
|
|
CEntityProperty *penpProperty = ppidProperty->pid_penpProperty;
|
|
CEntity *penTarget = ENTITYPROPERTY( pen, penpProperty->ep_slOffset, CEntityPointer);
|
|
// if it is NULL
|
|
if( penTarget == NULL)
|
|
{
|
|
// set this property as one to select
|
|
iToSelect = iToTest;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if null-ptr target isn't requested, each property is valid
|
|
iToSelect = iToTest;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// if we have valid result
|
|
if( iToSelect != -1)
|
|
{
|
|
// select it
|
|
m_PropertyComboBox.SetCurSel( iToSelect);
|
|
m_PropertyComboBox.SelectProperty();
|
|
}
|
|
}
|
|
|
|
void CPropertyComboBar::SetIntersectingFileName()
|
|
{
|
|
if( m_BrowseFileCtrl.IsWindowVisible())
|
|
{
|
|
// get entity selection's intesecting file name
|
|
CTFileName fnIntersectingFile = m_BrowseFileCtrl.GetIntersectingFile();
|
|
if( fnIntersectingFile != "")
|
|
{
|
|
m_strFileName = "...\\" + fnIntersectingFile.FileName() + fnIntersectingFile.FileExt();
|
|
}
|
|
else
|
|
{
|
|
m_strFileName = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPropertyComboBar::SetColorPropertyToEntities( COLOR colNewColor)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
// obtain curently selected property ID
|
|
CPropertyID *ppidProperty = GetSelectedProperty();
|
|
if( ppidProperty == NULL) return;
|
|
// change curently selected color property in the selected entities
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
// set new color value
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, COLOR) = colNewColor;
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
// mark that document is changed
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
}
|
|
|
|
BOOL CPropertyComboBar::OnIdle(LONG lCount)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
m_PropertyComboBox.OnIdle( lCount);
|
|
|
|
// if we are curently changing color
|
|
if( m_EditColorCtrl.IsWindowVisible())
|
|
{
|
|
COLOR colCurrentColor = m_EditColorCtrl.GetColor();
|
|
if( colCurrentColor != m_colLastColor)
|
|
{
|
|
SetColorPropertyToEntities( colCurrentColor);
|
|
m_colLastColor = colCurrentColor;
|
|
// update all views
|
|
pDoc->UpdateAllViews( NULL);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* Arranges (using show/hide) controls depending upon editing property type
|
|
*/
|
|
void CPropertyComboBar::ArrangeControls()
|
|
{
|
|
// array to receive description message
|
|
char strMessage[ 128];
|
|
|
|
// spawn flags are grayed
|
|
BOOL bEnableSpawn = FALSE;
|
|
|
|
// mark all controls for hiding
|
|
int iEnum = SW_HIDE;
|
|
int iString = SW_HIDE;
|
|
int iFloat = SW_HIDE;
|
|
int iBBox = SW_HIDE;
|
|
int iIndex = SW_HIDE;
|
|
int iBool = SW_HIDE;
|
|
int iColor = SW_HIDE;
|
|
int iBrowse = SW_HIDE;
|
|
int iX = SW_HIDE;
|
|
int iNoTarget = SW_HIDE;
|
|
int iFloatRangeText = SW_HIDE;
|
|
int iAngle3D = SW_HIDE;
|
|
int iIndexRangeText = SW_HIDE;
|
|
int iChooseColorText = SW_HIDE;
|
|
int iFileNameText = SW_HIDE;
|
|
int iFlags = SW_HIDE;
|
|
|
|
// get active document
|
|
CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
|
|
// if view does not exist, return
|
|
if( pDoc != NULL)
|
|
{
|
|
m_strFloatRange = "";
|
|
m_strChooseColor = "";
|
|
m_strFileName = "";
|
|
|
|
// obtain selected property ID ptr
|
|
INDEX iSelectedProperty = m_PropertyComboBox.GetCurSel();
|
|
CPropertyID *ppidProperty = (CPropertyID *) m_PropertyComboBox.GetItemData( iSelectedProperty);
|
|
// if there is valid property selected
|
|
if( ppidProperty != NULL)
|
|
{
|
|
// show controls acording to property type
|
|
switch( ppidProperty->pid_eptType)
|
|
{
|
|
case CEntityProperty::EPT_FLAGS:
|
|
{
|
|
iFlags = SW_SHOW;
|
|
CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
|
|
CEntityProperty *penpProperty = pen->PropertyForName( ppidProperty->pid_strName);
|
|
m_ctrlEditFlags.SetFlags( ENTITYPROPERTY( pen, penpProperty->ep_slOffset, ULONG));
|
|
|
|
// obtain enum property description object
|
|
CEntityPropertyEnumType *epEnum = penpProperty->ep_pepetEnumType;
|
|
// create mask of editable bits
|
|
ULONG ulEditable=0;
|
|
// for all enumerated members
|
|
for( INDEX iEnum = 0; iEnum<epEnum->epet_ctValues; iEnum++)
|
|
{
|
|
if( epEnum->epet_aepevValues[ iEnum].epev_strName!="")
|
|
{
|
|
ulEditable|=(1UL)<<epEnum->epet_aepevValues[ iEnum].epev_iValue;
|
|
CTString strBitName=epEnum->epet_aepevValues[ iEnum].epev_strName;
|
|
m_ctrlEditFlags.SetBitDescription(iEnum, strBitName);
|
|
}
|
|
}
|
|
m_ctrlEditFlags.SetEditableMask(ulEditable);
|
|
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// it is, get string as one that others will compare with
|
|
m_ctrlEditFlags.MergeFlags( ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ULONG));
|
|
}
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_ENUM:
|
|
case CEntityProperty::EPT_ENTITYPTR:
|
|
case CEntityProperty::EPT_PARENT:
|
|
case CEntityProperty::EPT_ANIMATION:
|
|
case CEntityProperty::EPT_ILLUMINATIONTYPE:
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = ppidProperty->pid_penpProperty;
|
|
// remove all combo entries
|
|
m_EditEnumComboBox.ResetContent();
|
|
// combo control is to be shown
|
|
iEnum = SW_SHOW;
|
|
// for enum type of property
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENUM)
|
|
{
|
|
// obtain enum property description object
|
|
CEntityPropertyEnumType *epEnum = penpProperty->ep_pepetEnumType;
|
|
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
|
|
BOOL bAllEntitiesHaveSameEnum = TRUE;
|
|
INDEX iCurrentEnumID;
|
|
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, set its value as one that others will compare with
|
|
iCurrentEnumID = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
|
|
}
|
|
else
|
|
{
|
|
// if value of entity enum variable is different from first one
|
|
if( iCurrentEnumID != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
|
|
{
|
|
// mark that all entities do not have same enum
|
|
bAllEntitiesHaveSameEnum = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
|
|
// invalid choosed enum ID
|
|
INDEX iSelectedEnumID = -1;
|
|
// for all enumerated members
|
|
for( INDEX iEnum = 0; iEnum< epEnum->epet_ctValues; iEnum++)
|
|
{
|
|
// add enum member into combo box
|
|
// add descriptive string
|
|
INDEX iAddedAs = m_EditEnumComboBox.AddString(
|
|
CString(epEnum->epet_aepevValues[ iEnum].epev_strName));
|
|
// get looping enum id
|
|
INDEX iLoopingEnumID = epEnum->epet_aepevValues[ iEnum].epev_iValue;
|
|
// connect descriptive string with enum value itself
|
|
m_EditEnumComboBox.SetItemData( iAddedAs, iLoopingEnumID);
|
|
|
|
// if all entities have same enum and this is joint enumerated value
|
|
if( bAllEntitiesHaveSameEnum && (iCurrentEnumID == iLoopingEnumID) )
|
|
{
|
|
// remember its index to set as selected combo value
|
|
iSelectedEnumID = iCurrentEnumID;
|
|
}
|
|
}
|
|
// if entities have same enum there must be valid selected enum ID
|
|
if( bAllEntitiesHaveSameEnum)
|
|
{
|
|
ASSERT(iSelectedEnumID != -1);
|
|
}
|
|
|
|
// if all entities have same enum
|
|
if( bAllEntitiesHaveSameEnum)
|
|
{
|
|
// after inserting combo members, they can be sorted so adding order does not work
|
|
// any more, combo member indices are not same any more
|
|
// mark invalid combo entry as selected
|
|
INDEX iSelectedCombo = -1;
|
|
// for all combo members
|
|
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
|
|
{
|
|
// if this entry has same enum ID as selected one
|
|
if( m_EditEnumComboBox.GetItemData( iCombo) == (DWORD) iSelectedEnumID)
|
|
{
|
|
// set its index as one to be selected
|
|
iSelectedCombo = iCombo;
|
|
break;
|
|
}
|
|
}
|
|
// there must be selected entry
|
|
ASSERT( iSelectedCombo != -1);
|
|
// select combo member
|
|
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
|
|
}
|
|
}
|
|
// else if this is entity ptr property
|
|
else if( (ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR) ||
|
|
(ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT) )
|
|
{
|
|
BOOL bParentProperty = ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT;
|
|
// for all entities in the world
|
|
{FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
|
|
{
|
|
CTString strEntityName = iten->GetName();
|
|
CBrushSector *pbscSector = iten->GetFirstSector();
|
|
BOOL bSectorVisible = (pbscSector == NULL) ||
|
|
!(pbscSector->bsc_ulFlags & BSCF_HIDDEN);
|
|
|
|
BOOL bValidTarget = TRUE;
|
|
// for each entity in selection
|
|
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, itenSel)
|
|
{
|
|
CEntityProperty *penpProperty = ppidProperty->pid_penpProperty;
|
|
if(penpProperty != NULL)
|
|
{
|
|
// see if target is valid
|
|
if( !itenSel->IsTargetValid( penpProperty->ep_slOffset, iten))
|
|
{
|
|
bValidTarget = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}}
|
|
|
|
// if entity is targetable, not hidden, and is not selected
|
|
if( (iten->IsTargetable() || bParentProperty) &&
|
|
(bSectorVisible) &&
|
|
bValidTarget &&
|
|
//(!iten->IsSelected(ENF_SELECTED)) &&
|
|
!(iten->en_ulFlags&ENF_HIDDEN))
|
|
{
|
|
INDEX iAddedAs;
|
|
if( strEntityName != "")
|
|
{
|
|
// add it to combo
|
|
iAddedAs = m_EditEnumComboBox.AddString( CString(strEntityName));
|
|
}
|
|
else
|
|
{
|
|
// add it to combo
|
|
iAddedAs = m_EditEnumComboBox.AddString( L"Unnamed");
|
|
}
|
|
// set entity ptr as item's data
|
|
m_EditEnumComboBox.SetItemData( iAddedAs, (ULONG) &*iten);
|
|
}
|
|
}}
|
|
|
|
// set NULL entity name
|
|
INDEX iAddedAs = m_EditEnumComboBox.InsertString( 0, L"None");
|
|
// set NULL entity ptr as item's data
|
|
m_EditEnumComboBox.SetItemData( iAddedAs, NULL);
|
|
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
|
|
// to hold intersecting entity ptr
|
|
CEntity *penEntity;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, set its value as one that others will compare with
|
|
if( bParentProperty)
|
|
penEntity = iten->GetParent();
|
|
else
|
|
penEntity = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer);
|
|
|
|
}
|
|
else
|
|
{
|
|
// get current entity ptr
|
|
CEntity *penCurrent;
|
|
if( bParentProperty) penCurrent = iten->GetParent();
|
|
else penCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer);
|
|
|
|
// if value of entity ptr is different from first one
|
|
if( penEntity != penCurrent)
|
|
{
|
|
// mark that all entities do not have same entity ptr
|
|
penEntity = (CEntity *) -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
|
|
if( penEntity != (CEntity *)-1)
|
|
{
|
|
INDEX iSelectedCombo = 0;
|
|
// for all combo members
|
|
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
|
|
{
|
|
// if this entry has same entity ptr as selected one
|
|
if( penEntity == (CEntity *) m_EditEnumComboBox.GetItemData( iCombo) )
|
|
{
|
|
// set its index as one to be selected
|
|
iSelectedCombo = iCombo;
|
|
break;
|
|
}
|
|
}
|
|
// select combo member
|
|
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
|
|
}
|
|
|
|
// show x button
|
|
iNoTarget = SW_SHOW;
|
|
}
|
|
// else if we should initialize animation property
|
|
else if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANIMATION)
|
|
{
|
|
// get first selected entity
|
|
pDoc->m_selEntitySelection.Lock();
|
|
CEntity *penFirst = pDoc->m_selEntitySelection.Pointer(0);
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
CAnimData *pAD = penFirst->GetAnimData( penpProperty->ep_slOffset);
|
|
if( pAD != NULL)
|
|
{
|
|
// add all animations into combo box
|
|
for( INDEX iAnimation=0;iAnimation<pAD->GetAnimsCt();iAnimation++)
|
|
{
|
|
// obtain information about animation
|
|
CAnimInfo aiInfo;
|
|
pAD->GetAnimInfo(iAnimation, aiInfo);
|
|
// add animation to combo
|
|
INDEX iAddedAs = m_EditEnumComboBox.AddString( CString(aiInfo.ai_AnimName));
|
|
// set animation number as item's data
|
|
m_EditEnumComboBox.SetItemData( iAddedAs, (ULONG) iAnimation);
|
|
}
|
|
}
|
|
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
INDEX iJointAnimation = -1;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get light animation as one that others will compare with
|
|
iJointAnimation = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
|
|
}
|
|
else
|
|
{
|
|
if( iJointAnimation!=ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
|
|
{
|
|
iJointAnimation = -1;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
|
|
if( iJointAnimation != -1)
|
|
{
|
|
INDEX iSelectedCombo = -1;
|
|
// for all combo members
|
|
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
|
|
{
|
|
// if this entry has same entity ptr as selected one
|
|
if( iJointAnimation == (INDEX) m_EditEnumComboBox.GetItemData( iCombo) )
|
|
{
|
|
// set its index as one to be selected
|
|
iSelectedCombo = iCombo;
|
|
break;
|
|
}
|
|
}
|
|
// if there is joint animation but is not found in combo
|
|
if( iSelectedCombo == -1)
|
|
{
|
|
iSelectedCombo = 0;
|
|
}
|
|
// select combo member
|
|
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
|
|
}
|
|
}
|
|
// else if we should initialize illumination type property
|
|
else if( ppidProperty->pid_eptType == CEntityProperty::EPT_ILLUMINATIONTYPE)
|
|
{
|
|
// add all illumination types into combo box
|
|
for( INDEX iIllumination=0;iIllumination<255; iIllumination++)
|
|
{
|
|
// get illumination name
|
|
CTString strIlluminationName =
|
|
pDoc->m_woWorld.wo_aitIlluminationTypes[iIllumination].it_strName;
|
|
// name must not be <none> except for first illumination
|
|
if(strIlluminationName == "")
|
|
{
|
|
break;
|
|
}
|
|
// add illumination type to combo
|
|
INDEX iAddedAs = m_EditEnumComboBox.AddString( CString(strIlluminationName));
|
|
// set illumination type number as item's data
|
|
m_EditEnumComboBox.SetItemData( iAddedAs, (ULONG) iIllumination);
|
|
}
|
|
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
|
|
INDEX iJointIllumination = -1;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get illumination as one that others will compare with
|
|
iJointIllumination = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
|
|
}
|
|
else
|
|
{
|
|
if( iJointIllumination!=ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
|
|
{
|
|
iJointIllumination = -1;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
|
|
if( iJointIllumination != -1)
|
|
{
|
|
INDEX iSelectedCombo = -1;
|
|
// for all combo members
|
|
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
|
|
{
|
|
// if this entry has same entity ptr as selected one
|
|
if( iJointIllumination == (INDEX) m_EditEnumComboBox.GetItemData( iCombo) )
|
|
{
|
|
// set its index as one to be selected
|
|
iSelectedCombo = iCombo;
|
|
break;
|
|
}
|
|
}
|
|
// if there is joint illumination but is not found in combo
|
|
if( iSelectedCombo == -1)
|
|
{
|
|
iSelectedCombo = 0;
|
|
}
|
|
// select combo member
|
|
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ASSERTALWAYS("Illegal entity \"combo\"-type property found !");
|
|
}
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_STRING:
|
|
case CEntityProperty::EPT_STRINGTRANS:
|
|
{
|
|
// edit string control is to be shown
|
|
iString = SW_SHOW;
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get string as one that others will compare with
|
|
m_strEditingString = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTString);
|
|
}
|
|
else
|
|
{
|
|
CTString strString = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTString);
|
|
// if string is different from first one
|
|
if( CTString( CStringA(m_strEditingString)) != strString)
|
|
{
|
|
// all selected entities do not share same string
|
|
m_strEditingString = "";
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_FLOAT:
|
|
case CEntityProperty::EPT_RANGE:
|
|
case CEntityProperty::EPT_ANGLE:
|
|
{
|
|
iFloat = SW_SHOW;
|
|
iFloatRangeText = SW_SHOW;
|
|
|
|
pDoc->m_selEntitySelection.Lock();
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE)
|
|
{
|
|
m_fEditingFloat = DegAngle( ENTITYPROPERTY(
|
|
&*iten, penpProperty->ep_slOffset, ANGLE));
|
|
}
|
|
else
|
|
{
|
|
m_fEditingFloat = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLOAT fCurrentFloat;
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE)
|
|
{
|
|
fCurrentFloat = DegAngle( ENTITYPROPERTY(
|
|
&*iten, penpProperty->ep_slOffset, ANGLE));
|
|
}
|
|
else
|
|
{
|
|
fCurrentFloat = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
|
|
}
|
|
if( m_fEditingFloat != fCurrentFloat )
|
|
{
|
|
m_fEditingFloat = 0.0f;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
|
|
sprintf( strMessage, "Float");
|
|
m_strFloatRange = strMessage;
|
|
if( ppidProperty->pid_eptType == CEntityProperty::EPT_RANGE)
|
|
{
|
|
pDoc->UpdateAllViews( NULL);
|
|
}
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_ANGLE3D:
|
|
{
|
|
iAngle3D = SW_SHOW;
|
|
pDoc->m_selEntitySelection.Lock();
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
ANGLE3D aAngle = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D);
|
|
m_fEditingHeading = DegAngle( aAngle(1));
|
|
m_fEditingPitch = DegAngle( aAngle(2));
|
|
m_fEditingBanking = DegAngle( aAngle(3));
|
|
}
|
|
else
|
|
{
|
|
ANGLE3D aCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D);
|
|
if( m_fEditingHeading != DegAngle( aCurrent(1))) m_fEditingHeading = 0.0f;
|
|
if( m_fEditingPitch != DegAngle( aCurrent(2))) m_fEditingPitch = 0.0f;
|
|
if( m_fEditingBanking != DegAngle( aCurrent(3))) m_fEditingBanking = 0.0f;
|
|
}
|
|
}
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_FLOATAABBOX3D:
|
|
{
|
|
iBBox = SW_SHOW;
|
|
// mark that all entities have same value for current bbox axis
|
|
BOOL bAllHaveSameBBoxValue = TRUE;
|
|
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// get first entity's bbox min and max values for selected axis
|
|
FLOATaabbox3D bboxCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset,
|
|
FLOATaabbox3D);
|
|
// get its min and max vectors
|
|
FLOAT3D vMin = bboxCurrent.Min();
|
|
FLOAT3D vMax = bboxCurrent.Max();
|
|
// remember min and max ranges for current axis for other entities in selection
|
|
// to compare with
|
|
m_fEditingBBoxMin = vMin( m_iXYZAxis);
|
|
m_fEditingBBoxMax = vMax( m_iXYZAxis);
|
|
}
|
|
else
|
|
{
|
|
// get first entity's bbox min and max values for selected axis
|
|
FLOATaabbox3D bboxCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset,
|
|
FLOATaabbox3D);
|
|
// get its min and max vectors
|
|
FLOAT3D vMin = bboxCurrent.Min();
|
|
FLOAT3D vMax = bboxCurrent.Max();
|
|
// compare min and max ranges for current axis with those from first entity
|
|
if( (m_fEditingBBoxMin != vMin( m_iXYZAxis)) ||
|
|
(m_fEditingBBoxMax != vMax( m_iXYZAxis)) )
|
|
{
|
|
// all selected entities do not share same number so mark it
|
|
bAllHaveSameBBoxValue = FALSE;
|
|
m_fEditingBBoxMin = 0.0f;
|
|
m_fEditingBBoxMax = 0.0f;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
// refresh views
|
|
pDoc->UpdateAllViews( NULL);
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_INDEX:
|
|
{
|
|
iIndex = SW_SHOW;
|
|
iIndexRangeText = SW_SHOW;
|
|
|
|
// mark that all entities have same index property value
|
|
BOOL bAllHaveSameIndex = TRUE;
|
|
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get this number as one that others will compare with
|
|
m_iEditingIndex = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
|
|
}
|
|
else
|
|
{
|
|
// if number is different from first one
|
|
if( m_iEditingIndex != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
|
|
{
|
|
// all selected entities do not share same number so mark it
|
|
bAllHaveSameIndex = FALSE;
|
|
m_iEditingIndex = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
sprintf( strMessage, "Integer");
|
|
m_strIndexRange = strMessage;
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_BOOL:
|
|
{
|
|
m_EditBoolCtrl.SetWindowText( CString(ppidProperty->pid_strName));
|
|
iBool = SW_SHOW;
|
|
// variable to receive state of check box
|
|
INDEX iCheckBox;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get boolean as one that others will compare with
|
|
iCheckBox = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, BOOL);
|
|
}
|
|
else
|
|
{
|
|
// if this boolean is different from first one
|
|
if( iCheckBox != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, BOOL) )
|
|
{
|
|
// selected entities do not share same boolean, set undefined state
|
|
iCheckBox = 2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// set calculated boolean state (or undefined)
|
|
m_EditBoolCtrl.SetCheck( iCheckBox);
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_COLOR:
|
|
{
|
|
// intersecting color
|
|
COLOR colIntersected;
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get this color as one that others will compare with
|
|
colIntersected = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, COLOR);
|
|
// set button's color
|
|
m_EditColorCtrl.SetColor( colIntersected);
|
|
// remember this color as the last
|
|
m_colLastColor = colIntersected;
|
|
}
|
|
else
|
|
{
|
|
// if color is different from first one
|
|
if( colIntersected != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, COLOR) )
|
|
{
|
|
// all selected entities do not share same color
|
|
m_EditColorCtrl.SetMixedColor();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
iChooseColorText = SW_SHOW;
|
|
iColor = SW_SHOW;
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_FILENAME:
|
|
case CEntityProperty::EPT_FILENAMENODEP:
|
|
{
|
|
SetIntersectingFileName();
|
|
iFileNameText = SW_SHOW;
|
|
iBrowse = SW_SHOW;
|
|
iX = SW_SHOW;
|
|
m_BrowseFileCtrl.m_bFileNameNoDep =
|
|
(ppidProperty->pid_eptType == CEntityProperty::EPT_FILENAMENODEP);
|
|
break;
|
|
}
|
|
case CEntityProperty::EPT_SPAWNFLAGS:
|
|
{
|
|
bEnableSpawn = TRUE;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ASSERTALWAYS("Unknown property type");
|
|
}
|
|
}
|
|
}
|
|
// update all views
|
|
pDoc->UpdateAllViews( NULL);
|
|
}
|
|
|
|
m_EditEasySpawn.EnableWindow( bEnableSpawn);
|
|
m_EditNormalSpawn.EnableWindow( bEnableSpawn);
|
|
m_EditHardSpawn.EnableWindow( bEnableSpawn);
|
|
m_EditExtremeSpawn.EnableWindow( bEnableSpawn);
|
|
m_EditDifficulty_1.EnableWindow( bEnableSpawn);
|
|
m_EditDifficulty_2.EnableWindow( bEnableSpawn);
|
|
m_EditDifficulty_3.EnableWindow( bEnableSpawn);
|
|
m_EditDifficulty_4.EnableWindow( bEnableSpawn);
|
|
m_EditDifficulty_5.EnableWindow( bEnableSpawn);
|
|
|
|
m_EditSingleSpawn.EnableWindow( bEnableSpawn);
|
|
m_EditCooperativeSpawn.EnableWindow( bEnableSpawn);
|
|
m_EditDeathMatchSpawn.EnableWindow( bEnableSpawn);
|
|
m_EditGameMode_1.EnableWindow( bEnableSpawn);
|
|
m_EditGameMode_2.EnableWindow( bEnableSpawn);
|
|
m_EditGameMode_3.EnableWindow( bEnableSpawn);
|
|
m_EditGameMode_4.EnableWindow( bEnableSpawn);
|
|
m_EditGameMode_5.EnableWindow( bEnableSpawn);
|
|
m_EditGameMode_6.EnableWindow( bEnableSpawn);
|
|
|
|
GetDlgItem( IDC_EASY_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_NORMAL_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_HARD_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_EXTREME_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_1_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_2_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_3_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_4_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_5_T)->EnableWindow( bEnableSpawn);
|
|
|
|
GetDlgItem( IDC_SINGLE_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_COOPERATIVE_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DEATHMATCH_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_1_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_2_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_3_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_4_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_5_T)->EnableWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_6_T)->EnableWindow( bEnableSpawn);
|
|
|
|
m_EditEasySpawn.ShowWindow( bEnableSpawn);
|
|
m_EditNormalSpawn.ShowWindow( bEnableSpawn);
|
|
m_EditHardSpawn.ShowWindow( bEnableSpawn);
|
|
m_EditExtremeSpawn.ShowWindow( bEnableSpawn);
|
|
m_EditDifficulty_1.ShowWindow( bEnableSpawn);
|
|
m_EditDifficulty_2.ShowWindow( bEnableSpawn);
|
|
m_EditDifficulty_3.ShowWindow( bEnableSpawn);
|
|
m_EditDifficulty_4.ShowWindow( bEnableSpawn);
|
|
m_EditDifficulty_5.ShowWindow( bEnableSpawn);
|
|
|
|
m_EditSingleSpawn.ShowWindow( bEnableSpawn);
|
|
m_EditCooperativeSpawn.ShowWindow( bEnableSpawn);
|
|
m_EditDeathMatchSpawn.ShowWindow( bEnableSpawn);
|
|
m_EditGameMode_1.ShowWindow( bEnableSpawn);
|
|
m_EditGameMode_2.ShowWindow( bEnableSpawn);
|
|
m_EditGameMode_3.ShowWindow( bEnableSpawn);
|
|
m_EditGameMode_4.ShowWindow( bEnableSpawn);
|
|
m_EditGameMode_5.ShowWindow( bEnableSpawn);
|
|
m_EditGameMode_6.ShowWindow( bEnableSpawn);
|
|
|
|
|
|
GetDlgItem( IDC_EASY_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_NORMAL_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_HARD_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_EXTREME_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_1_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_2_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_3_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_4_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DIFFICULTY_5_T)->ShowWindow( bEnableSpawn);
|
|
|
|
GetDlgItem( IDC_SINGLE_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_DEATHMATCH_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_COOPERATIVE_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_1_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_2_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_3_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_4_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_5_T)->ShowWindow( bEnableSpawn);
|
|
GetDlgItem( IDC_GAME_MODE_6_T)->ShowWindow( bEnableSpawn);
|
|
|
|
// show controls that are necessary to edit current property
|
|
m_EditEnumComboBox.ShowWindow( iEnum);
|
|
m_EditStringCtrl.ShowWindow( iString);
|
|
m_EditFloatCtrl.ShowWindow( iFloat);
|
|
m_EditBBoxMinCtrl.ShowWindow( iBBox);
|
|
m_EditBBoxMaxCtrl.ShowWindow( iBBox);
|
|
GetDlgItem( IDC_AXIS_X)->ShowWindow( iBBox);
|
|
GetDlgItem( IDC_AXIS_Y)->ShowWindow( iBBox);
|
|
GetDlgItem( IDC_AXIS_Z)->ShowWindow( iBBox);
|
|
m_EditIndexCtrl.ShowWindow( iIndex);
|
|
m_EditBoolCtrl.ShowWindow( iBool);
|
|
m_BrowseFileCtrl.ShowWindow( iBrowse);
|
|
GetDlgItem( IDC_NO_FILE)->ShowWindow( iX);
|
|
GetDlgItem( IDC_NO_TARGET)->ShowWindow( iNoTarget);
|
|
|
|
m_EditColorCtrl.ShowWindow( iColor);
|
|
m_ctrlEditFlags.ShowWindow( iFlags);
|
|
|
|
GetDlgItem( IDC_FLOAT_RANGE_T)->ShowWindow( iFloatRangeText);
|
|
GetDlgItem( IDC_INDEX_RANGE_T)->ShowWindow( iIndexRangeText);
|
|
GetDlgItem( IDC_FILE_NAME_T)->ShowWindow( iFileNameText);
|
|
|
|
GetDlgItem( IDC_ANGLE3D_T)->ShowWindow( iAngle3D);
|
|
GetDlgItem( IDC_EDIT_HEADING)->ShowWindow( iAngle3D);
|
|
GetDlgItem( IDC_EDIT_PITCH)->ShowWindow( iAngle3D);
|
|
GetDlgItem( IDC_EDIT_BANKING)->ShowWindow( iAngle3D);
|
|
|
|
GetDlgItem( IDC_ENTITY_CLASS)->ShowWindow( SW_SHOW);
|
|
GetDlgItem( IDC_ENTITY_NAME)->ShowWindow( SW_SHOW);
|
|
GetDlgItem( IDC_ENTITY_DESCRIPTION)->ShowWindow( SW_SHOW);
|
|
|
|
GetDlgItem( IDC_ENTITY_CLASS)->EnableWindow( m_PropertyComboBox.IsWindowEnabled());
|
|
GetDlgItem( IDC_ENTITY_NAME)->EnableWindow( m_PropertyComboBox.IsWindowEnabled());
|
|
GetDlgItem( IDC_ENTITY_DESCRIPTION)->EnableWindow( m_PropertyComboBox.IsWindowEnabled());
|
|
|
|
// update dialog data (so new data could be loaded into dialog)
|
|
UpdateData( FALSE);
|
|
}
|
|
|
|
void CPropertyComboBar::OnUpdateBrowseFile(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable( TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::OnUpdateEditColor(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable( TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::OnUpdateEditFlags(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable( TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::SetIntersectingEntityClassName(void)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
// lock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Lock();
|
|
// string to contain intersecting class name
|
|
CTString strIntersectingClass = "No entity class";
|
|
CTString strIntersectingName = "No name";
|
|
CTString strIntersectingDescription = "No description";
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// get class of this entity
|
|
CEntityClass *pencEntityClass = iten->GetClass();
|
|
// get file name of clas file
|
|
CTFileName fnClassFileName = pencEntityClass->GetName().FileName();
|
|
// get name
|
|
CTString strEntityName = iten->GetName();
|
|
// get description
|
|
CTString strEntityDescription = iten->GetDescription();
|
|
// if this is first entity in dynamic container
|
|
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
|
|
{
|
|
// it is, get file name as one that others will compare with
|
|
strIntersectingClass = fnClassFileName;
|
|
// remember name
|
|
strIntersectingName = strEntityName;
|
|
// and description
|
|
strIntersectingDescription = strEntityDescription;
|
|
}
|
|
else
|
|
{
|
|
// if any of the selected entities has different class
|
|
if( strIntersectingClass != fnClassFileName)
|
|
{
|
|
// set multi class message
|
|
strIntersectingClass = "Multi class";
|
|
}
|
|
if( strIntersectingName != iten->GetName())
|
|
{
|
|
// set multi class message
|
|
strIntersectingName = "Multi name";
|
|
}
|
|
// if any of the selected entities has different class description
|
|
if( strIntersectingDescription != iten->GetDescription())
|
|
{
|
|
// set multi class description message
|
|
strIntersectingDescription = "Multi description";
|
|
}
|
|
}
|
|
}
|
|
m_strEntityClass = strIntersectingClass;
|
|
m_strEntityName = strIntersectingName;
|
|
m_strEntityDescription = strIntersectingDescription;
|
|
// unlock selection's dynamic container
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
}
|
|
|
|
void CPropertyComboBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
CDialogBar::OnHScroll(nSBCode, nPos, pScrollBar);
|
|
// copy color to selected entities
|
|
SetColorPropertyToEntities( m_EditColorCtrl.GetColor());
|
|
|
|
// refresh views
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
// mark that document is changed
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
// redraw all views
|
|
pDoc->UpdateAllViews( NULL);
|
|
}
|
|
|
|
CEntity *CPropertyComboBar::GetSelectedEntityPtr(void)
|
|
{
|
|
// obtain selected property ID ptr
|
|
CPropertyID *ppidProperty = GetSelectedProperty();
|
|
// if there is valid property selected
|
|
if( (ppidProperty == NULL) ||
|
|
((ppidProperty->pid_eptType != CEntityProperty::EPT_ENTITYPTR) &&
|
|
(ppidProperty->pid_eptType != CEntityProperty::EPT_PARENT)) )
|
|
{
|
|
return NULL;
|
|
}
|
|
// get currently selected combo member
|
|
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
|
|
// it must exist
|
|
ASSERT( iSelectedComboMember != CB_ERR);
|
|
// get entity ptr to be set for all entities
|
|
CEntity *penEntity = (CEntity *)m_EditEnumComboBox.GetItemData(iSelectedComboMember);
|
|
return penEntity;
|
|
}
|
|
|
|
void CPropertyComboBar::OnUpdateNoFile(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable( TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::OnUpdateNoTarget(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable( TRUE);
|
|
}
|
|
|
|
void CPropertyComboBar::OnNoFile(void)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL) return;
|
|
|
|
// obtain curently selected property ID
|
|
CPropertyID *ppidProperty = GetSelectedProperty();
|
|
if( ppidProperty == NULL) return;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
switch( ppidProperty->pid_eptType)
|
|
{
|
|
case CEntityProperty::EPT_FILENAMENODEP:
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTFileNameNoDep) = CTFileNameNoDep("");
|
|
break;
|
|
case CEntityProperty::EPT_FILENAME:
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTFileName) = CTFileName(CTString(""));
|
|
break;
|
|
}
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
// mark that document is changed
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
pDoc->UpdateAllViews( NULL);
|
|
pDoc->m_chSelections.MarkChanged();
|
|
// reload data to dialog
|
|
UpdateData( FALSE);
|
|
}
|
|
|
|
void CPropertyComboBar::ClearAllTargets(CEntity *penClicked)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL) return;
|
|
if( penClicked == NULL) return;
|
|
|
|
// if it is selected
|
|
if( penClicked->IsSelected( ENF_SELECTED))
|
|
{
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// discard old entity settings
|
|
iten->End();
|
|
// obtain entity class ptr
|
|
CDLLEntityClass *pdecDLLClass = iten->GetClass()->ec_pdecDLLClass;
|
|
// for all classes in hierarchy of this entity
|
|
for(; pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
|
|
{
|
|
// for all properties
|
|
for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
|
|
{
|
|
CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
|
|
if( epProperty.ep_eptType == CEntityProperty::EPT_ENTITYPTR)
|
|
{
|
|
// clear entity ptr
|
|
ENTITYPROPERTY( &*iten, epProperty.ep_slOffset, CEntityPointer) = NULL;
|
|
}
|
|
}
|
|
}
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
}
|
|
// if is not selected
|
|
else
|
|
{
|
|
// discard old entity settings
|
|
penClicked->End();
|
|
// obtain entity class ptr
|
|
CDLLEntityClass *pdecDLLClass = penClicked->GetClass()->ec_pdecDLLClass;
|
|
// for all classes in hierarchy of this entity
|
|
for(; pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
|
|
{
|
|
// for all properties
|
|
for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
|
|
{
|
|
CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
|
|
if( epProperty.ep_eptType == CEntityProperty::EPT_ENTITYPTR)
|
|
{
|
|
// clear entity ptr
|
|
ENTITYPROPERTY( &*penClicked, epProperty.ep_slOffset, CEntityPointer) = NULL;
|
|
}
|
|
}
|
|
}
|
|
// apply new entity settings
|
|
penClicked->Initialize();
|
|
}
|
|
pDoc->m_chSelections.MarkChanged();
|
|
UpdateData( FALSE);
|
|
}
|
|
|
|
void CPropertyComboBar::SelectProperty(CEntityProperty *penpToMatch)
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL) return;
|
|
|
|
if( pDoc->m_selEntitySelection.Count() != 1)return;
|
|
|
|
CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
|
|
if( pen == NULL) return;
|
|
|
|
// note selection change
|
|
m_PropertyComboBox.OnIdle( 0);
|
|
|
|
for( INDEX iItem=0; iItem<m_PropertyComboBox.GetCount(); iItem++)
|
|
{
|
|
CPropertyID *ppid = (CPropertyID *) m_PropertyComboBox.GetItemData( iItem);
|
|
CEntityProperty *penpProperty = pen->PropertyForName( ppid->pid_strName);
|
|
if( penpProperty == penpToMatch)
|
|
{
|
|
m_PropertyComboBox.SetCurSel(iItem);
|
|
m_PropertyComboBox.SelectProperty();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPropertyComboBar::OnNoTarget()
|
|
{
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
if( pDoc == NULL) return;
|
|
|
|
// obtain curently selected property ID
|
|
CPropertyID *ppidProperty = GetSelectedProperty();
|
|
if( ppidProperty == NULL) return;
|
|
// for each of the selected entities
|
|
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
{
|
|
// obtain property ptr
|
|
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
|
|
// discard old entity settings
|
|
iten->End();
|
|
switch( ppidProperty->pid_eptType)
|
|
{
|
|
case CEntityProperty::EPT_ENTITYPTR:
|
|
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer) = NULL;
|
|
break;
|
|
case CEntityProperty::EPT_PARENT:
|
|
iten->SetParent( NULL);
|
|
break;
|
|
}
|
|
// apply new entity settings
|
|
iten->Initialize();
|
|
}
|
|
// mark that document is changed
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
pDoc->UpdateAllViews( NULL);
|
|
pDoc->m_chSelections.MarkChanged();
|
|
// reload data to dialog
|
|
UpdateData( FALSE);
|
|
}
|