mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-11-27 06:32:27 +00:00
c3d480afe4
Minimum required Windows version is XP again (instead of Win10). Win_GetWindowScalingFactor() tries to use two dynamically loaded functions from newer windows versions (8.1+, Win10 1607+) and has a fallback for older versions that also seems to work (at least if all displays have the same DPI). Moved the function to win_main.cpp so the dynamically loaded functions can be loaded at startup; so edit_gui_common.cpp could be removed again.
1385 lines
36 KiB
C++
1385 lines
36 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "tools/edit_gui_common.h"
|
|
|
|
|
|
#include "qe3.h"
|
|
#include "Radiant.h"
|
|
#include "GLWidget.h"
|
|
#include "PropertyList.h"
|
|
#include "entitydlg.h"
|
|
#include "PreviewDlg.h"
|
|
#include "CurveDlg.h"
|
|
|
|
#include "../../renderer/model_local.h" // for idRenderModelPrt
|
|
|
|
void Select_Ungroup();
|
|
|
|
// CEntityDlg dialog
|
|
|
|
IMPLEMENT_DYNAMIC(CEntityDlg, CDialog)
|
|
CEntityDlg::CEntityDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CEntityDlg::IDD, pParent)
|
|
{
|
|
editEntity = NULL;
|
|
multipleEntities = false;
|
|
currentAnimation = NULL;
|
|
}
|
|
|
|
CEntityDlg::~CEntityDlg()
|
|
{
|
|
}
|
|
|
|
void CEntityDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
DDX_Control(pDX, IDC_LIST_KEYVAL, listKeyVal);
|
|
DDX_Control(pDX, IDC_COMBO_CLASS, comboClass);
|
|
DDX_Control(pDX, IDC_EDIT_KEY, editKey);
|
|
DDX_Control(pDX, IDC_EDIT_VAL, editVal);
|
|
DDX_Control(pDX, IDC_STATIC_TITLE, staticTitle);
|
|
DDX_Control(pDX, IDC_STATIC_KEY, staticKey);
|
|
DDX_Control(pDX, IDC_STATIC_VAL, staticVal);
|
|
DDX_Control(pDX, IDC_BUTTON_BROWSE, btnBrowse);
|
|
DDX_Control(pDX, IDC_E_135, btn135);
|
|
DDX_Control(pDX, IDC_E_90, btn90);
|
|
DDX_Control(pDX, IDC_E_45, btn45);
|
|
DDX_Control(pDX, IDC_E_180, btn180);
|
|
DDX_Control(pDX, IDC_E_0, btn360);
|
|
DDX_Control(pDX, IDC_E_225, btn225);
|
|
DDX_Control(pDX, IDC_E_270, btn270);
|
|
DDX_Control(pDX, IDC_E_315, btn315);
|
|
DDX_Control(pDX, IDC_E_UP, btnUp);
|
|
DDX_Control(pDX, IDC_E_DOWN, btnDown);
|
|
DDX_Control(pDX, IDC_BUTTON_MODEL, btnModel);
|
|
DDX_Control(pDX, IDC_BUTTON_SOUND, btnSound);
|
|
DDX_Control(pDX, IDC_BUTTON_GUI, btnGui);
|
|
DDX_Control(pDX, IDC_BUTTON_PARTICLE, btnParticle);
|
|
DDX_Control(pDX, IDC_BUTTON_SKIN, btnSkin);
|
|
DDX_Control(pDX, IDC_BUTTON_CURVE, btnCurve);
|
|
DDX_Control(pDX, IDC_BUTTON_CREATE, btnCreate);
|
|
DDX_Control(pDX, IDC_LIST_VARS, listVars);
|
|
DDX_Control(pDX, IDC_ENTITY_ANIMATIONS , cbAnimations);
|
|
DDX_Control(pDX, IDC_ANIMATION_SLIDER , slFrameSlider);
|
|
DDX_Control(pDX, IDC_ENTITY_CURRENT_ANIM , staticFrame);
|
|
DDX_Control(pDX, IDC_ENTITY_PLAY_ANIM , btnPlayAnim);
|
|
DDX_Control(pDX, IDC_ENTITY_STOP_ANIM , btnStopAnim);
|
|
}
|
|
|
|
|
|
|
|
BOOL CEntityDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
listKeyVal.SetUpdateInspectors(true);
|
|
listKeyVal.SetDivider(100);
|
|
listVars.SetDivider(100);
|
|
staticFrame.SetWindowText ( "0" );
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
INT_PTR CEntityDlg::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const
|
|
{
|
|
// TODO: Add your specialized code here and/or call the base class
|
|
|
|
return CDialog::OnToolHitTest(point, pTI);
|
|
}
|
|
|
|
|
|
void CEntityDlg::AddClassNames() {
|
|
comboClass.ResetContent();
|
|
for (eclass_t *pec = eclass; pec; pec = pec->next) {
|
|
comboClass.AddString(pec->name);
|
|
}
|
|
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CEntityDlg, CDialog)
|
|
ON_WM_SIZE()
|
|
ON_CBN_SELCHANGE(IDC_COMBO_CLASS, OnCbnSelchangeComboClass)
|
|
ON_LBN_SELCHANGE(IDC_LIST_KEYVAL, OnLbnSelchangeListkeyval)
|
|
ON_BN_CLICKED(IDC_E_135, OnBnClickedE135)
|
|
ON_BN_CLICKED(IDC_E_90, OnBnClickedE90)
|
|
ON_BN_CLICKED(IDC_E_45, OnBnClickedE45)
|
|
ON_BN_CLICKED(IDC_E_180, OnBnClickedE180)
|
|
ON_BN_CLICKED(IDC_E_0, OnBnClickedE0)
|
|
ON_BN_CLICKED(IDC_E_225, OnBnClickedE225)
|
|
ON_BN_CLICKED(IDC_E_270, OnBnClickedE270)
|
|
ON_BN_CLICKED(IDC_E_315, OnBnClickedE315)
|
|
ON_BN_CLICKED(IDC_E_UP, OnBnClickedEUp)
|
|
ON_BN_CLICKED(IDC_E_DOWN, OnBnClickedEDown)
|
|
ON_BN_CLICKED(IDC_BUTTON_MODEL, OnBnClickedButtonModel)
|
|
ON_BN_CLICKED(IDC_BUTTON_SOUND, OnBnClickedButtonSound)
|
|
ON_BN_CLICKED(IDC_BUTTON_GUI, OnBnClickedButtonGui)
|
|
ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse)
|
|
ON_CBN_DBLCLK(IDC_COMBO_CLASS, OnCbnDblclkComboClass)
|
|
ON_BN_CLICKED(IDC_BUTTON_CREATE, OnBnClickedButtonCreate)
|
|
ON_LBN_DBLCLK(IDC_LIST_KEYVAL, OnLbnDblclkListkeyval)
|
|
ON_LBN_SELCHANGE(IDC_LIST_VARS, OnLbnSelchangeListVars)
|
|
ON_LBN_DBLCLK(IDC_LIST_VARS, OnLbnDblclkListVars)
|
|
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_ANIMATION_SLIDER, OnNMReleasedcaptureSlider1)
|
|
ON_BN_CLICKED(IDC_BUTTON_PARTICLE, OnBnClickedButtonParticle)
|
|
ON_BN_CLICKED(IDC_BUTTON_SKIN, OnBnClickedButtonSkin)
|
|
ON_BN_CLICKED(IDC_BUTTON_CURVE, OnBnClickedButtonCurve)
|
|
ON_CBN_SELCHANGE(IDC_ENTITY_ANIMATIONS, OnCbnAnimationChange)
|
|
ON_BN_CLICKED(IDC_ENTITY_PLAY_ANIM , OnBnClickedStartAnimation)
|
|
ON_BN_CLICKED(IDC_ENTITY_STOP_ANIM , OnBnClickedStopAnimation)
|
|
ON_WM_TIMER()
|
|
ON_BN_CLICKED(IDOK, OnOK)
|
|
END_MESSAGE_MAP()
|
|
|
|
void CEntityDlg::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
if (staticTitle.GetSafeHwnd() == NULL) {
|
|
return;
|
|
}
|
|
CDialog::OnSize(nType, cx, cy);
|
|
CRect rect, crect, crect2;
|
|
GetClientRect(rect);
|
|
float scaling_factor = Win_GetWindowScalingFactor(staticTitle.GetSafeHwnd());
|
|
|
|
int s2 = int( 2 * scaling_factor);
|
|
int s8 = int( 8 * scaling_factor);
|
|
int s4 = int( 4 * scaling_factor);
|
|
int s6 = int( 6 * scaling_factor);
|
|
int s12 = int( 12 * scaling_factor);
|
|
int s16 = int( 16 * scaling_factor);
|
|
|
|
int bh = (float)rect.Height() * (rect.Height() - (210* scaling_factor)) / rect.Height() / 2;
|
|
staticTitle.GetWindowRect(crect);
|
|
staticTitle.SetWindowPos(NULL, s4, s4, rect.Width() - s8, crect.Height(), SWP_SHOWWINDOW);
|
|
int top = crect.Height() + s8;
|
|
comboClass.GetWindowRect(crect);
|
|
btnCreate.GetWindowRect(crect2);
|
|
comboClass.SetWindowPos(NULL, s4, top, rect.Width() - s12 - crect2.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
btnCreate.SetWindowPos(NULL, rect.Width() - crect2.Width() - 4, top, crect2.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
top += crect.Height() + s4;
|
|
listVars.SetWindowPos(NULL, s4, top, rect.Width() - s8, bh, SWP_SHOWWINDOW);
|
|
top += bh + s4;
|
|
listKeyVal.SetWindowPos(NULL, s4, top, rect.Width() - s8, bh, SWP_SHOWWINDOW);
|
|
top += bh + s4;
|
|
staticKey.GetWindowRect(crect);
|
|
staticKey.SetWindowPos(NULL, s4, top + s2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
int left = crect.Width() + s8;
|
|
int pad = crect.Width();
|
|
editKey.GetWindowRect(crect);
|
|
editKey.SetWindowPos(NULL, left, top, rect.Width() - s12 - pad, crect.Height(), SWP_SHOWWINDOW);
|
|
top += crect.Height() + s4;
|
|
staticVal.GetWindowRect(crect);
|
|
staticVal.SetWindowPos(NULL, s4, top + s2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
editVal.GetWindowRect(crect);
|
|
bh = crect.Height();
|
|
editVal.SetWindowPos(NULL, left, top, rect.Width() - s16 - bh - pad, crect.Height(), SWP_SHOWWINDOW);
|
|
btnBrowse.SetWindowPos(NULL, rect.right - s4 - bh, top, bh, bh, SWP_SHOWWINDOW);
|
|
top += crect.Height() + s8;
|
|
btnModel.GetWindowRect(crect);
|
|
btnModel.SetWindowPos(NULL, rect.right - s4 - crect.Width(), top + s8, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
btnSound.SetWindowPos(NULL, rect.right - s4 - crect.Width(), top + s12 + crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
btnGui.SetWindowPos(NULL, rect.right - s4 - crect.Width(), top + s16 + crect.Height() * 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
btnParticle.SetWindowPos(NULL, rect.right - s8 - (crect.Width() * 2), top + s16 + crect.Height() * 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
|
|
btnSkin.SetWindowPos( NULL, rect.right - s8 - ( crect.Width() * 2 ), top + s12 + crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW );
|
|
btnCurve.SetWindowPos( NULL, rect.right - s8 - ( crect.Width() * 2 ), top + s8, crect.Width(), crect.Height(), SWP_SHOWWINDOW );
|
|
|
|
//*************************************
|
|
//animation controls
|
|
//*************************************
|
|
int rightAnimAreaBorder = rect.right - (75 * scaling_factor) -crect.Width(); /*models, etc button width*/
|
|
|
|
btnStopAnim.GetWindowRect(crect);
|
|
btnStopAnim.SetWindowPos(NULL,rightAnimAreaBorder - crect.Width (),
|
|
top + 8 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
|
|
|
|
left = rightAnimAreaBorder - crect.Width() - s4;
|
|
btnPlayAnim.GetWindowRect(crect);
|
|
btnPlayAnim.SetWindowPos(NULL,left-crect.Width () ,top + s8 , crect.Width(),crect.Height(),SWP_SHOWWINDOW);
|
|
|
|
left -= crect.Width() + s4;
|
|
cbAnimations.GetWindowRect(crect);
|
|
cbAnimations.SetWindowPos(NULL,left-crect.Width (),top + s8 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
|
|
|
|
staticFrame.GetWindowRect(crect);
|
|
staticFrame.SetWindowPos(NULL,rightAnimAreaBorder - crect.Width (),
|
|
top + (34 * scaling_factor) ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
|
|
|
|
left = rightAnimAreaBorder - crect.Width () - s4;
|
|
|
|
slFrameSlider.GetWindowRect(crect);
|
|
slFrameSlider.SetWindowPos(NULL,left - crect.Width (),
|
|
top + (32 * scaling_factor) ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
|
|
|
|
//*************************************
|
|
//*************************************
|
|
|
|
btn135.GetWindowRect(crect);
|
|
bh = crect.Width();
|
|
btn135.SetWindowPos(NULL, s4, top, bh, bh, SWP_SHOWWINDOW);
|
|
btn90.SetWindowPos(NULL, s4 + s2 + bh, top, bh, bh, SWP_SHOWWINDOW);
|
|
btn45.SetWindowPos(NULL, s4 + s2 + s2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW);
|
|
btnUp.SetWindowPos(NULL, s4 + s2 + s2 + s6 + bh * 3, top + bh / 2,bh,bh, SWP_SHOWWINDOW);
|
|
btnDown.SetWindowPos(NULL, s4 + s2 + s2 + s6 + bh *3, top + bh / 2 + bh + s2,bh,bh, SWP_SHOWWINDOW);
|
|
top += bh + s2;
|
|
btn180.SetWindowPos(NULL, s4, top, bh, bh, SWP_SHOWWINDOW);
|
|
btn360.SetWindowPos(NULL, s4 + s2 + s2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW);
|
|
top += bh + s2;
|
|
btn225.SetWindowPos(NULL, s4, top, bh, bh, SWP_SHOWWINDOW);
|
|
btn270.SetWindowPos(NULL, s4 + s2 + bh, top, bh, bh, SWP_SHOWWINDOW);
|
|
btn315.SetWindowPos(NULL, s4 + s2 + s2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW);
|
|
Invalidate();
|
|
}
|
|
|
|
void CEntityDlg::OnCbnSelchangeComboClass()
|
|
{
|
|
int index = comboClass.GetCurSel();
|
|
if (index != LB_ERR) {
|
|
CString str;
|
|
comboClass.GetLBText(index, str);
|
|
eclass_t *ent = Eclass_ForName (str, false);
|
|
if (ent) {
|
|
if (selected_brushes.next == &selected_brushes) {
|
|
editEntity = world_entity;
|
|
multipleEntities = false;
|
|
} else {
|
|
editEntity = selected_brushes.next->owner;
|
|
for (brush_t *b = selected_brushes.next->next; b != &selected_brushes; b = b->next) {
|
|
if (b->owner != editEntity) {
|
|
multipleEntities = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
listVars.ResetContent();
|
|
CPropertyItem *pi = new CPropertyItem("Usage:", ent->desc.c_str(), PIT_VAR, "");
|
|
listVars.AddPropItem(pi);
|
|
|
|
int c = ent->vars.Num();
|
|
for (int i = 0; i < c; i++) {
|
|
pi = new CPropertyItem(ent->vars[i].name.c_str(), ent->vars[i].desc.c_str(), PIT_VAR, "");
|
|
pi->SetData(ent->vars[i].type);
|
|
listVars.AddPropItem(pi);
|
|
}
|
|
listVars.Invalidate();
|
|
SetKeyValPairs();
|
|
}
|
|
}
|
|
}
|
|
|
|
const char *CEntityDlg::TranslateString(const char *buf) {
|
|
static char buf2[32768];
|
|
int i, l;
|
|
char *out;
|
|
|
|
l = strlen(buf);
|
|
out = buf2;
|
|
for (i = 0; i < l; i++) {
|
|
if (buf[i] == '\n') {
|
|
*out++ = '\r';
|
|
*out++ = '\n';
|
|
}
|
|
else {
|
|
*out++ = buf[i];
|
|
}
|
|
}
|
|
|
|
*out++ = 0;
|
|
|
|
return buf2;
|
|
|
|
}
|
|
|
|
void CEntityDlg::UpdateFromListBox() {
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
int c = listKeyVal.GetCount();
|
|
for (int i = 0 ; i < c; i++) {
|
|
CPropertyItem* pItem = (CPropertyItem*)listKeyVal.GetItemDataPtr(i);
|
|
if (pItem) {
|
|
editEntity->epairs.Set(pItem->m_propName, pItem->m_curValue);
|
|
}
|
|
}
|
|
SetKeyValPairs();
|
|
}
|
|
|
|
void CEntityDlg::SetKeyValPairs( bool updateAnims ) {
|
|
if (editEntity) {
|
|
listKeyVal.ResetContent();
|
|
int c = editEntity->epairs.GetNumKeyVals();
|
|
for (int i = 0; i < c; i++) {
|
|
const idKeyValue *kv = editEntity->epairs.GetKeyVal(i);
|
|
CPropertyItem *pi = new CPropertyItem(kv->GetKey().c_str(), kv->GetValue().c_str(), PIT_EDIT, "");
|
|
bool found = false;
|
|
int vc = editEntity->eclass->vars.Num();
|
|
for (int j = 0; j < vc; j++) {
|
|
if (editEntity->eclass->vars[j].name.Icmp(kv->GetKey()) == 0) {
|
|
switch (editEntity->eclass->vars[j].type) {
|
|
case EVAR_STRING :
|
|
case EVAR_INT :
|
|
case EVAR_FLOAT :
|
|
pi->m_nItemType = PIT_EDIT;
|
|
break;
|
|
case EVAR_BOOL :
|
|
pi->m_nItemType = PIT_EDIT;
|
|
//pi->m_cmbItems = "0|1";
|
|
break;
|
|
case EVAR_COLOR :
|
|
pi->m_nItemType = PIT_COLOR;
|
|
break;
|
|
case EVAR_MATERIAL :
|
|
pi->m_nItemType = PIT_MATERIAL;
|
|
break;
|
|
case EVAR_MODEL :
|
|
pi->m_nItemType = PIT_MODEL;
|
|
break;
|
|
case EVAR_GUI :
|
|
pi->m_nItemType = PIT_GUI;
|
|
break;
|
|
case EVAR_SOUND :
|
|
pi->m_nItemType = PIT_SOUND;
|
|
break;
|
|
}
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
if (kv->GetKey().Icmp("model") == 0) {
|
|
pi->m_nItemType = PIT_MODEL;
|
|
}
|
|
if (kv->GetKey().Icmp("_color") == 0) {
|
|
pi->m_nItemType = PIT_COLOR;
|
|
}
|
|
if (kv->GetKey().Icmp("gui") == 0) {
|
|
pi->m_nItemType = PIT_GUI;
|
|
}
|
|
if (kv->GetKey().Icmp("gui2") == 0) {
|
|
pi->m_nItemType = PIT_GUI;
|
|
}
|
|
if (kv->GetKey().Icmp("gui3") == 0) {
|
|
pi->m_nItemType = PIT_GUI;
|
|
}
|
|
if (kv->GetKey().Icmp("s_shader") == 0) {
|
|
pi->m_nItemType = PIT_SOUND;
|
|
}
|
|
}
|
|
listKeyVal.AddPropItem(pi);
|
|
}
|
|
|
|
if ( updateAnims ) {
|
|
int i, num;
|
|
|
|
cbAnimations.ResetContent();
|
|
num = gameEdit->ANIM_GetNumAnimsFromEntityDef( &editEntity->eclass->defArgs );
|
|
for( i = 0; i < num; i++ ) {
|
|
cbAnimations.AddString( gameEdit->ANIM_GetAnimNameFromEntityDef( &editEntity->eclass->defArgs, i ) );
|
|
}
|
|
|
|
const idKeyValue* kv = editEntity->epairs.FindKey ( "anim" );
|
|
if ( kv ) {
|
|
int selIndex = cbAnimations.FindStringExact( 0 , kv->GetValue().c_str() );
|
|
if ( selIndex != -1 ) {
|
|
cbAnimations.SetCurSel( selIndex );
|
|
OnCbnAnimationChange ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::UpdateEntitySel(eclass_t *ent) {
|
|
assert ( ent );
|
|
assert ( ent->name );
|
|
int index = comboClass.FindString(-1, ent->name);
|
|
if (index != LB_ERR) {
|
|
comboClass.SetCurSel(index);
|
|
OnCbnSelchangeComboClass();
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnLbnSelchangeListkeyval()
|
|
{
|
|
int index = listKeyVal.GetCurSel();
|
|
if (index != LB_ERR) {
|
|
CString str;
|
|
listKeyVal.GetText(index, str);
|
|
int i;
|
|
for (i = 0; str[i] != '\t' && str[i] != '\0'; i++) {
|
|
}
|
|
|
|
idStr key = str.Left(i);
|
|
while (str[i] == '\t' && str[i] != '\0') {
|
|
i++;
|
|
}
|
|
|
|
idStr val = str.Right(str.GetLength() - i);
|
|
|
|
editKey.SetWindowText(key);
|
|
editVal.SetWindowText(val);
|
|
}
|
|
}
|
|
|
|
static int TabOrder[] = {
|
|
IDC_COMBO_CLASS,
|
|
IDC_BUTTON_CREATE,
|
|
//IDC_EDIT_INFO,
|
|
IDC_LIST_KEYVAL,
|
|
IDC_EDIT_KEY,
|
|
IDC_EDIT_VAL,
|
|
IDC_BUTTON_BROWSE,
|
|
IDC_E_135,
|
|
IDC_E_90,
|
|
IDC_E_45,
|
|
IDC_E_180,
|
|
IDC_E_0,
|
|
IDC_E_225,
|
|
IDC_E_270,
|
|
IDC_E_315,
|
|
IDC_E_UP,
|
|
IDC_E_DOWN,
|
|
IDC_BUTTON_MODEL,
|
|
IDC_BUTTON_SOUND,
|
|
IDC_BUTTON_GUI,
|
|
IDC_ENTITY_ANIMATIONS
|
|
};
|
|
|
|
int TabCount = sizeof(TabOrder) / sizeof(int);
|
|
|
|
void CEntityDlg::DelProp() {
|
|
CString key;
|
|
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
|
|
editKey.GetWindowText(key);
|
|
if (multipleEntities) {
|
|
for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) {
|
|
DeleteKey(b->owner, key);
|
|
Entity_UpdateCurveData( b->owner );
|
|
}
|
|
} else {
|
|
DeleteKey(editEntity, key);
|
|
Entity_UpdateCurveData( editEntity );
|
|
}
|
|
|
|
// refresh the prop listbox
|
|
SetKeyValPairs();
|
|
Sys_UpdateWindows( W_ENTITY | W_XY | W_CAMERA );
|
|
}
|
|
|
|
|
|
BOOL CEntityDlg::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
|
|
if (pMsg->hwnd == editVal.GetSafeHwnd()) {
|
|
if (pMsg->message == WM_LBUTTONDOWN) {
|
|
editVal.SetFocus();
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (pMsg->hwnd == editKey.GetSafeHwnd()) {
|
|
if (pMsg->message == WM_LBUTTONDOWN) {
|
|
editKey.SetFocus();
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (GetFocus() == &editVal || GetFocus() == &editKey) {
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
|
|
AddProp();
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
if (GetFocus() == listKeyVal.GetEditBox()) {
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
|
|
listKeyVal.OnChangeEditBox();
|
|
listKeyVal.OnSelchange();
|
|
listKeyVal.OnKillfocusEditBox();
|
|
AddProp();
|
|
SetKeyValPairs();
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (GetFocus() == &listKeyVal) {
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE && editEntity) {
|
|
DelProp();
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) {
|
|
if (pMsg->wParam == VK_ESCAPE) {
|
|
g_pParentWnd->GetCamera()->SetFocus();
|
|
Select_Deselect();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
|
|
// keeps ENTER from closing the dialog
|
|
return TRUE;
|
|
}
|
|
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB) {
|
|
if (GetFocus()) {
|
|
int id = GetFocus()->GetDlgCtrlID();
|
|
for (int i = 0; i < TabCount; i++) {
|
|
if (TabOrder[i] == id) {
|
|
i++;
|
|
if (i >= TabCount) {
|
|
i = 0;
|
|
}
|
|
CWnd *next = GetDlgItem(TabOrder[i]);
|
|
if (next) {
|
|
next->SetFocus();
|
|
if (TabOrder[i] == IDC_EDIT_VAL) {
|
|
editVal.SetSel(0, -1);
|
|
}
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RIGHT && pMsg->hwnd == slFrameSlider.GetSafeHwnd()) {
|
|
int pos = slFrameSlider.GetPos() + 1;
|
|
pos = (pos % slFrameSlider.GetRangeMax());
|
|
slFrameSlider.SetPos ( pos );
|
|
UpdateFromAnimationFrame ();
|
|
return TRUE;
|
|
}
|
|
|
|
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_LEFT && pMsg->hwnd == slFrameSlider.GetSafeHwnd()) {
|
|
int pos = slFrameSlider.GetPos() - 1;
|
|
|
|
if ( pos < 1 ) {
|
|
pos = slFrameSlider.GetRangeMax();
|
|
}
|
|
|
|
slFrameSlider.SetPos ( pos );
|
|
UpdateFromAnimationFrame ();
|
|
return TRUE;
|
|
}
|
|
|
|
return CDialog::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
|
|
/*
|
|
=======================================================================================================================
|
|
AddProp
|
|
=======================================================================================================================
|
|
*/
|
|
void CEntityDlg::AddProp() {
|
|
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
|
|
CString Key, Value;
|
|
editKey.GetWindowText(Key);
|
|
editVal.GetWindowText(Value);
|
|
|
|
bool isName = (stricmp(Key, "name") == 0);
|
|
bool isModel = static_cast<bool>((stricmp(Key, "model") == 0 && Value.GetLength() > 0));
|
|
bool isOrigin = ( idStr::Icmp( Key, "origin" ) == 0 );
|
|
|
|
if (multipleEntities) {
|
|
brush_t *b;
|
|
for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
|
|
if (isName) {
|
|
Entity_SetName(b->owner, Value);
|
|
} else {
|
|
if ( ! ( ( isModel || isOrigin ) && ( b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) {
|
|
SetKeyValue(b->owner, Key, Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (isName) {
|
|
Entity_SetName(editEntity, Value);
|
|
} else {
|
|
if ( ! ( ( isModel || isOrigin ) && ( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) {
|
|
SetKeyValue(editEntity, Key, Value);
|
|
}
|
|
}
|
|
|
|
if ( isModel && !( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) {
|
|
idBounds bo;
|
|
idVec3 mins, maxs;
|
|
|
|
selected_brushes.next->modelHandle = renderModelManager->FindModel( Value );
|
|
if ( dynamic_cast<idRenderModelPrt*>( selected_brushes.next->modelHandle ) || dynamic_cast<idRenderModelLiquid*>( selected_brushes.next->modelHandle ) ) {
|
|
bo.Zero();
|
|
bo.ExpandSelf( 12.0f );
|
|
} else {
|
|
bo = selected_brushes.next->modelHandle->Bounds( NULL );
|
|
}
|
|
|
|
VectorCopy(bo[0], mins);
|
|
VectorCopy(bo[1], maxs);
|
|
VectorAdd(mins, editEntity->origin, mins);
|
|
VectorAdd(maxs, editEntity->origin, maxs);
|
|
Brush_RebuildBrush(selected_brushes.next, mins, maxs, false);
|
|
Brush_Build ( selected_brushes.next , false, false , false, true );
|
|
}
|
|
}
|
|
|
|
// refresh the prop listbox
|
|
SetKeyValPairs();
|
|
Sys_UpdateWindows(W_ALL);
|
|
|
|
}
|
|
|
|
const char *CEntityDlg::AngleKey() {
|
|
if (editEntity == NULL) {
|
|
return "";
|
|
}
|
|
|
|
if (editEntity->eclass->nShowFlags & ECLASS_MOVER) {
|
|
return "movedir";
|
|
}
|
|
|
|
return "angle";
|
|
}
|
|
|
|
|
|
void CEntityDlg::OnBnClickedE135()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("135");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE90()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("90");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE45()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("45");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE180()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("180");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE0()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("0");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE225()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("225");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE270()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("270");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedE315()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("315");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedEUp()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("-1");
|
|
AddProp();
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedEDown()
|
|
{
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
editKey.SetWindowText(AngleKey());
|
|
editVal.SetWindowText("-2");
|
|
AddProp();
|
|
}
|
|
|
|
CPreviewDlg *CEntityDlg::ShowModelChooser() {
|
|
static CPreviewDlg modelDlg;
|
|
modelDlg.SetMode(CPreviewDlg::MODELS);
|
|
modelDlg.SetModal();
|
|
if (modelDlg.GetSafeHwnd() == NULL) {
|
|
modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
|
|
}
|
|
modelDlg.ShowWindow( SW_SHOW );
|
|
modelDlg.BringWindowToTop();
|
|
while (modelDlg.Waiting()) {
|
|
}
|
|
return &modelDlg;
|
|
}
|
|
|
|
CPreviewDlg *CEntityDlg::ShowParticleChooser() {
|
|
static CPreviewDlg modelDlg;
|
|
modelDlg.SetMode(CPreviewDlg::PARTICLES);
|
|
modelDlg.SetModal();
|
|
if (modelDlg.GetSafeHwnd() == NULL) {
|
|
modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
|
|
}
|
|
modelDlg.ShowWindow(SW_SHOW);
|
|
modelDlg.BringWindowToTop();
|
|
while (modelDlg.Waiting()) {
|
|
}
|
|
return &modelDlg;
|
|
}
|
|
|
|
CPreviewDlg *CEntityDlg::ShowSkinChooser(entity_t *ent) {
|
|
static CPreviewDlg modelDlg;
|
|
modelDlg.SetMode(CPreviewDlg::SKINS);
|
|
modelDlg.SetModal();
|
|
if (modelDlg.GetSafeHwnd() == NULL) {
|
|
modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
|
|
}
|
|
modelDlg.RebuildTree( ( ent ) ? ent->epairs.GetString( "model" ) : "" );
|
|
modelDlg.ShowWindow(SW_SHOW);
|
|
modelDlg.BringWindowToTop();
|
|
while (modelDlg.Waiting()) {
|
|
}
|
|
return &modelDlg;
|
|
}
|
|
|
|
CPreviewDlg *CEntityDlg::ShowGuiChooser() {
|
|
static CPreviewDlg guiDlg;
|
|
guiDlg.SetMode(CPreviewDlg::GUIS);
|
|
guiDlg.SetModal();
|
|
if (guiDlg.GetSafeHwnd() == NULL) {
|
|
guiDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
|
|
}
|
|
guiDlg.ShowWindow(SW_SHOW);
|
|
guiDlg.BringWindowToTop();
|
|
while (guiDlg.Waiting()) {
|
|
}
|
|
return &guiDlg;
|
|
}
|
|
|
|
CPreviewDlg *CEntityDlg::ShowSoundChooser() {
|
|
static CPreviewDlg soundDlg;
|
|
soundDlg.SetMode(CPreviewDlg::SOUNDS);
|
|
soundDlg.SetModal();
|
|
if (soundDlg.GetSafeHwnd() == NULL) {
|
|
soundDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
|
|
}
|
|
soundDlg.ShowWindow(SW_SHOW);
|
|
while (soundDlg.Waiting()) {
|
|
}
|
|
return &soundDlg;
|
|
}
|
|
|
|
CPreviewDlg *CEntityDlg::ShowMaterialChooser() {
|
|
static CPreviewDlg matDlg;
|
|
matDlg.SetMode(CPreviewDlg::MATERIALS);
|
|
matDlg.SetModal();
|
|
if (matDlg.GetSafeHwnd() == NULL) {
|
|
matDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
|
|
}
|
|
matDlg.ShowWindow(SW_SHOW);
|
|
matDlg.BringWindowToTop();
|
|
while (matDlg.Waiting()) {
|
|
}
|
|
return &matDlg;
|
|
}
|
|
|
|
void CEntityDlg::AssignModel ()
|
|
{
|
|
OnBnClickedButtonModel();
|
|
}
|
|
void CEntityDlg::OnBnClickedButtonModel() {
|
|
CPreviewDlg *dlg = ShowModelChooser();
|
|
if (dlg->returnCode == IDOK) {
|
|
editKey.SetWindowText("model");
|
|
editVal.SetWindowText(dlg->mediaName);
|
|
AddProp();
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonSound() {
|
|
CPreviewDlg *dlg = ShowSoundChooser();
|
|
if (dlg->returnCode == IDOK) {
|
|
editKey.SetWindowText("s_shader");
|
|
editVal.SetWindowText(dlg->mediaName);
|
|
AddProp();
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonGui() {
|
|
CPreviewDlg *dlg = ShowGuiChooser();
|
|
if (dlg->returnCode == IDOK) {
|
|
editKey.SetWindowText("gui");
|
|
editVal.SetWindowText(dlg->mediaName);
|
|
AddProp();
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonParticle() {
|
|
CPreviewDlg *dlg = ShowParticleChooser();
|
|
if (dlg->returnCode == IDOK) {
|
|
editKey.SetWindowText("model");
|
|
editVal.SetWindowText(dlg->mediaName);
|
|
AddProp();
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonSkin() {
|
|
CPreviewDlg *dlg = ShowSkinChooser( editEntity );
|
|
if (dlg->returnCode == IDOK) {
|
|
editKey.SetWindowText("skin");
|
|
editVal.SetWindowText(dlg->mediaName);
|
|
AddProp();
|
|
}
|
|
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonCurve() {
|
|
CCurveDlg dlg;
|
|
if ( dlg.DoModal() == IDOK ) {
|
|
if ( editEntity ) {
|
|
idStr str = "curve_" + dlg.strCurveType;
|
|
editKey.SetWindowText( str );
|
|
idVec3 org = editEntity->origin;
|
|
str = "3 ( ";
|
|
str += org.ToString();
|
|
org.x += 64;
|
|
str += " ";
|
|
str += org.ToString();
|
|
org.y += 64;
|
|
str += " ";
|
|
str += org.ToString();
|
|
str += " )";
|
|
editVal.SetWindowText( str );
|
|
AddProp();
|
|
Entity_SetCurveData( editEntity );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonBrowse() {
|
|
DelProp();
|
|
}
|
|
|
|
void CEntityDlg::OnCbnDblclkComboClass()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
}
|
|
|
|
//
|
|
// =======================================================================================================================
|
|
// CreateEntity Creates a new entity based on the currently selected brush and entity type.
|
|
// =======================================================================================================================
|
|
//
|
|
void CEntityDlg::CreateEntity() {
|
|
entity_t *petNew = NULL;
|
|
bool forceFixed = false;
|
|
|
|
// check to make sure we have a brush
|
|
CXYWnd *pWnd = g_pParentWnd->ActiveXY();
|
|
if (pWnd) {
|
|
CRect rctZ;
|
|
pWnd->GetClientRect(rctZ);
|
|
|
|
brush_t *pBrush;
|
|
if (selected_brushes.next == &selected_brushes) {
|
|
pBrush = CreateEntityBrush(g_nSmartX, rctZ.Height() - 1 - g_nSmartY, pWnd);
|
|
forceFixed = true;
|
|
}
|
|
}
|
|
else {
|
|
if (selected_brushes.next == &selected_brushes) {
|
|
MessageBox("You must have a selected brush to create an entity", "info", 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
int index = comboClass.GetCurSel();
|
|
if (index == LB_ERR) {
|
|
MessageBox("You must have a selected class to create an entity", "info", 0);
|
|
return;
|
|
}
|
|
|
|
CString str;
|
|
comboClass.GetLBText(index, str);
|
|
|
|
if (!stricmp(str, "worldspawn")) {
|
|
MessageBox("Can't create an entity with worldspawn.", "info", 0);
|
|
return;
|
|
}
|
|
|
|
eclass_t *pecNew = Eclass_ForName (str, false);
|
|
|
|
// create it
|
|
if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
|
|
// MAJOR hack for xian
|
|
extern void Brush_CopyList(brush_t *pFrom, brush_t *pTo);
|
|
brush_t temp_brushes;
|
|
temp_brushes.next = &temp_brushes;
|
|
Brush_CopyList(&selected_brushes, &temp_brushes);
|
|
Select_Deselect();
|
|
brush_t *pBrush = temp_brushes.next;
|
|
while (pBrush != NULL && pBrush != &temp_brushes) {
|
|
brush_t *pNext = pBrush->next;
|
|
Brush_RemoveFromList(pBrush);
|
|
Brush_AddToList(pBrush, &selected_brushes);
|
|
pBrush = pNext;
|
|
petNew = Entity_Create(pecNew, forceFixed);
|
|
Select_Deselect();
|
|
}
|
|
} else if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
|
|
Select_Ungroup();
|
|
petNew = Entity_Create(pecNew, forceFixed);
|
|
} else {
|
|
petNew = Entity_Create(pecNew, forceFixed);
|
|
}
|
|
|
|
if (petNew == NULL) {
|
|
MessageBox("Failed to create entity.", "info", 0);
|
|
return;
|
|
}
|
|
|
|
if (selected_brushes.next == &selected_brushes) {
|
|
editEntity = world_entity;
|
|
}
|
|
else {
|
|
editEntity = selected_brushes.next->owner;
|
|
}
|
|
|
|
SetKeyValPairs();
|
|
Select_Deselect();
|
|
Select_Brush(editEntity->brushes.onext);
|
|
Sys_UpdateWindows(W_ALL);
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedButtonCreate()
|
|
{
|
|
CreateEntity();
|
|
}
|
|
|
|
void CEntityDlg::OnLbnDblclkListkeyval()
|
|
{
|
|
CString Key, Value;
|
|
idStr work;
|
|
editKey.GetWindowText( Key );
|
|
editVal.GetWindowText( Value );
|
|
if ( stricmp( Key, "script" ) == 0 ) {
|
|
Key = Value;
|
|
Value = "script/" + Key;
|
|
if ( fileSystem->ReadFile( Value, NULL, NULL ) == -1) {
|
|
sprintf( work, "// Script for %s\n// \n\nvoid main() {\n\n}\n\n", currentmap );
|
|
fileSystem->WriteFile( Value, work.c_str(), work.Length(), "fs_devpath" );
|
|
}
|
|
work = fileSystem->RelativePathToOSPath( Value );
|
|
WinExec( va( "notepad.exe %s", work.c_str() ), SW_SHOW );
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnLbnSelchangeListVars() {
|
|
|
|
}
|
|
|
|
void CEntityDlg::OnLbnDblclkListVars() {
|
|
if (editEntity == NULL) {
|
|
return;
|
|
}
|
|
int sel = listVars.GetCurSel();
|
|
CPropertyItem *pi = (CPropertyItem*)listVars.GetItemDataPtr(sel);
|
|
if (pi) {
|
|
if (editEntity->epairs.FindKey(pi->m_propName) == NULL) {
|
|
editKey.SetWindowText(pi->m_propName);
|
|
editVal.SetWindowText("");
|
|
editVal.SetFocus();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CEntityDlg::UpdateKeyVal(const char *key, const char *val) {
|
|
if (editEntity) {
|
|
editEntity->epairs.Set(key, val);
|
|
SetKeyValPairs();
|
|
g_pParentWnd->GetCamera()->BuildEntityRenderState(editEntity, true);
|
|
Entity_UpdateSoundEmitter(editEntity);
|
|
}
|
|
}
|
|
|
|
|
|
void CEntityDlg::OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult)
|
|
{
|
|
if ( !editEntity )
|
|
{
|
|
return;
|
|
}
|
|
|
|
UpdateFromAnimationFrame ();
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
void CEntityDlg::UpdateFromAnimationFrame ( bool updateKeyValueDisplay )
|
|
{
|
|
int frame = slFrameSlider.GetPos ();
|
|
editEntity->epairs.SetInt( "frame" , frame );
|
|
SetDlgItemText ( IDC_ENTITY_CURRENT_ANIM , va ( "%i" , frame));
|
|
if ( updateKeyValueDisplay ) {
|
|
SetKeyValPairs();
|
|
}
|
|
|
|
g_pParentWnd->GetCamera ()->BuildEntityRenderState (editEntity , true );
|
|
Sys_UpdateWindows ( W_ALL );
|
|
|
|
}
|
|
|
|
void CEntityDlg::OnCbnAnimationChange ()
|
|
{
|
|
if ( !editEntity )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int sel = cbAnimations.GetCurSel();
|
|
CString animName;
|
|
currentAnimation = NULL;
|
|
int currFrame = 0;
|
|
|
|
if ( sel != -1 ) {
|
|
cbAnimations.GetLBText( sel , animName );
|
|
if ( animName.GetLength() > 0 ) {
|
|
//preserve the existing frame number
|
|
currFrame = editEntity->epairs.GetInt ( "frame" , "1" );
|
|
|
|
editEntity->epairs.Set("anim" , animName.GetBuffer(0));
|
|
SetKeyValPairs(false/*don't update anims combo box :)*/ );
|
|
|
|
//update the slider
|
|
currentAnimation = gameEdit->ANIM_GetAnimFromEntityDef(editEntity->eclass->name , animName.GetBuffer(0));
|
|
currentAnimationFrame = 0;
|
|
|
|
if ( currentAnimation ) {
|
|
slFrameSlider.SetRange( 1 , gameEdit->ANIM_GetNumFrames( currentAnimation ), TRUE );
|
|
slFrameSlider.SetPos( currFrame );
|
|
currentAnimationFrame = currFrame;
|
|
}
|
|
|
|
Sys_UpdateWindows(W_ALL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedStartAnimation()
|
|
{
|
|
if (!editEntity) {
|
|
return;
|
|
}
|
|
SetTimer ( 0 , 1000/24 , NULL );
|
|
}
|
|
|
|
void CEntityDlg::OnBnClickedStopAnimation()
|
|
{
|
|
KillTimer ( 0 );
|
|
}
|
|
|
|
void CEntityDlg::OnTimer( UINT_PTR nIDEvent )
|
|
{
|
|
if ( !editEntity ) {
|
|
OnBnClickedStopAnimation ();
|
|
return;
|
|
}
|
|
|
|
if ( currentAnimation ) {
|
|
currentAnimationFrame = ( (currentAnimationFrame++) % gameEdit->ANIM_GetNumFrames( currentAnimation ) );
|
|
editEntity->epairs.SetInt ( "frame" , currentAnimationFrame );
|
|
slFrameSlider.SetPos ( currentAnimationFrame );
|
|
UpdateFromAnimationFrame (false/*don't update key/value display*/);
|
|
|
|
Sys_UpdateWindows ( W_CAMERA | W_XY );
|
|
}
|
|
}
|
|
|
|
void CEntityDlg::AddCurvePoints() {
|
|
if ( editEntity == NULL || editEntity->curve == NULL ) {
|
|
return;
|
|
}
|
|
|
|
// add one point 64 units from the direction of the two points int he curve
|
|
int c = editEntity->curve->GetNumValues();
|
|
idVec3 start;
|
|
idVec3 end;
|
|
if ( c > 1 ) {
|
|
start = editEntity->curve->GetValue( c - 2 );
|
|
end = editEntity->curve->GetValue( c - 1 );
|
|
idVec3 dir = end - start;
|
|
dir.Normalize();
|
|
start = end + 64 * dir;
|
|
} else if ( c > 0 ) {
|
|
start = editEntity->curve->GetValue( 0 );
|
|
start.x += 64;
|
|
start.y += 64;
|
|
} else {
|
|
start = editEntity->origin;
|
|
}
|
|
|
|
editEntity->curve->AddValue( editEntity->curve->GetNumValues() * 100, start );
|
|
|
|
if ( g_qeglobals.d_select_mode == sel_editpoint ) {
|
|
g_qeglobals.d_select_mode = sel_brush;
|
|
EditCurvePoints();
|
|
}
|
|
|
|
Sys_UpdateWindows( W_CAMERA | W_XY );
|
|
|
|
}
|
|
|
|
void CEntityDlg::EditCurvePoints() {
|
|
|
|
if ( editEntity == NULL || editEntity->curve == NULL ) {
|
|
return;
|
|
}
|
|
|
|
if ( g_qeglobals.d_select_mode == sel_editpoint ) {
|
|
g_qeglobals.d_select_mode = sel_brush;
|
|
return;
|
|
}
|
|
|
|
g_qeglobals.d_select_mode = sel_editpoint;
|
|
|
|
g_qeglobals.d_numpoints = 0;
|
|
g_qeglobals.d_num_move_points = 0;
|
|
int c = editEntity->curve->GetNumValues();
|
|
for ( int i = 0; i < c; i++ ) {
|
|
if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) {
|
|
g_qeglobals.d_points[g_qeglobals.d_numpoints++] = editEntity->curve->GetValue( i );
|
|
}
|
|
}
|
|
Sys_UpdateWindows( W_XY | W_CAMERA );
|
|
|
|
}
|
|
|
|
void CEntityDlg::InsertCurvePoint() {
|
|
if ( editEntity == NULL || editEntity->curve == NULL ) {
|
|
return;
|
|
}
|
|
|
|
if ( g_qeglobals.d_select_mode != sel_editpoint ) {
|
|
return;
|
|
}
|
|
|
|
if ( g_qeglobals.d_num_move_points == 0 ) {
|
|
return;
|
|
}
|
|
|
|
for ( int i = 0; i < editEntity->curve->GetNumValues(); i++ ) {
|
|
if ( PointInMoveList( editEntity->curve->GetValueAddress( i ) ) >= 0 ) {
|
|
if ( i == editEntity->curve->GetNumValues() - 1 ) {
|
|
// just do an add
|
|
AddCurvePoints();
|
|
} else {
|
|
idCurve<idVec3> *newCurve = Entity_MakeCurve( editEntity );
|
|
|
|
if ( newCurve == NULL ) {
|
|
return;
|
|
}
|
|
|
|
for ( int j = 0; j < editEntity->curve->GetNumValues(); j++ ) {
|
|
if ( j == i ) {
|
|
idVec3 start;
|
|
idVec3 end;
|
|
if ( i > 0 ) {
|
|
start = editEntity->curve->GetValue( i - 1 );
|
|
end = editEntity->curve->GetValue( i );
|
|
start += end;
|
|
start *= 0.5f;
|
|
} else {
|
|
start = editEntity->curve->GetValue( 0 );
|
|
if ( editEntity->curve->GetNumValues() > 1 ) {
|
|
end = start;
|
|
start = editEntity->curve->GetValue ( 1 );
|
|
idVec3 dir = end - start;
|
|
dir.Normalize();
|
|
start = end + 64 * dir;
|
|
} else {
|
|
end = start;
|
|
end.x += 64;
|
|
end.y += 64;
|
|
}
|
|
}
|
|
newCurve->AddValue( newCurve->GetNumValues() * 100, start );
|
|
}
|
|
newCurve->AddValue( newCurve->GetNumValues() * 100, editEntity->curve->GetValue( j ) );
|
|
}
|
|
delete editEntity->curve;
|
|
editEntity->curve = newCurve;
|
|
}
|
|
g_qeglobals.d_num_move_points = 0;
|
|
break;
|
|
}
|
|
}
|
|
UpdateEntityCurve();
|
|
|
|
Sys_UpdateWindows( W_XY | W_CAMERA );
|
|
|
|
}
|
|
|
|
void CEntityDlg::DeleteCurvePoint() {
|
|
|
|
if ( editEntity == NULL || editEntity->curve == NULL ) {
|
|
return;
|
|
}
|
|
|
|
if ( g_qeglobals.d_select_mode != sel_editpoint ) {
|
|
return;
|
|
}
|
|
|
|
|
|
if ( g_qeglobals.d_num_move_points == 0 ) {
|
|
return;
|
|
}
|
|
|
|
for ( int i = 0; i < editEntity->curve->GetNumValues(); i++ ) {
|
|
if ( PointInMoveList( editEntity->curve->GetValueAddress( i ) ) >= 0 ) {
|
|
editEntity->curve->RemoveIndex( i );
|
|
g_qeglobals.d_num_move_points = 0;
|
|
break;
|
|
}
|
|
}
|
|
UpdateEntityCurve();
|
|
|
|
Sys_UpdateWindows( W_XY | W_CAMERA );
|
|
|
|
}
|
|
|
|
|
|
void CEntityDlg::UpdateEntityCurve() {
|
|
|
|
if ( editEntity == NULL ) {
|
|
return;
|
|
}
|
|
|
|
Entity_UpdateCurveData( editEntity );
|
|
|
|
if ( g_qeglobals.d_select_mode == sel_editpoint ) {
|
|
g_qeglobals.d_numpoints = 0;
|
|
int c = editEntity->curve->GetNumValues();
|
|
for ( int i = 0; i < c; i++ ) {
|
|
if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) {
|
|
g_qeglobals.d_points[g_qeglobals.d_numpoints++] = editEntity->curve->GetValue( i );
|
|
}
|
|
}
|
|
}
|
|
|
|
Sys_UpdateWindows( W_ENTITY );
|
|
}
|
|
|
|
|
|
void CEntityDlg::SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) {
|
|
int i, besti;
|
|
float d, bestd;
|
|
idVec3 temp;
|
|
|
|
if ( editEntity == NULL ) {
|
|
return;
|
|
}
|
|
// find the point closest to the ray
|
|
float scale = g_pParentWnd->ActiveXY()->Scale();
|
|
besti = -1;
|
|
bestd = 8 / scale / 2;
|
|
//bestd = 8;
|
|
|
|
for (i = 0; i < g_qeglobals.d_numpoints; i++) {
|
|
temp = g_qeglobals.d_points[i] - org;
|
|
d = temp * dir;
|
|
temp = org + d * dir;
|
|
temp = g_qeglobals.d_points[i] - temp;
|
|
d = temp.Length();
|
|
if ( d <= bestd ) {
|
|
bestd = d;
|
|
besti = i;
|
|
}
|
|
}
|
|
|
|
if (besti == -1) {
|
|
return;
|
|
}
|
|
|
|
g_qeglobals.d_num_move_points = 0;
|
|
assert ( besti < editEntity->curve->GetNumValues() );
|
|
g_qeglobals.d_move_points[ g_qeglobals.d_num_move_points++ ] = editEntity->curve->GetValueAddress( besti );
|
|
}
|