EntityDlg.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. 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.
  17. 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.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "qe3.h"
  23. #include "Radiant.h"
  24. #include "GLWidget.h"
  25. #include "PropertyList.h"
  26. #include "entitydlg.h"
  27. #include "PreviewDlg.h"
  28. #include "CurveDlg.h"
  29. #include "../../renderer/model_local.h" // for idRenderModelPrt
  30. void Select_Ungroup();
  31. // CEntityDlg dialog
  32. IMPLEMENT_DYNAMIC(CEntityDlg, CDialog)
  33. CEntityDlg::CEntityDlg(CWnd* pParent /*=NULL*/)
  34. : CDialog(CEntityDlg::IDD, pParent)
  35. {
  36. editEntity = NULL;
  37. multipleEntities = false;
  38. currentAnimation = NULL;
  39. }
  40. CEntityDlg::~CEntityDlg()
  41. {
  42. }
  43. void CEntityDlg::DoDataExchange(CDataExchange* pDX)
  44. {
  45. CDialog::DoDataExchange(pDX);
  46. DDX_Control(pDX, IDC_LIST_KEYVAL, listKeyVal);
  47. DDX_Control(pDX, IDC_COMBO_CLASS, comboClass);
  48. DDX_Control(pDX, IDC_EDIT_KEY, editKey);
  49. DDX_Control(pDX, IDC_EDIT_VAL, editVal);
  50. DDX_Control(pDX, IDC_STATIC_TITLE, staticTitle);
  51. DDX_Control(pDX, IDC_STATIC_KEY, staticKey);
  52. DDX_Control(pDX, IDC_STATIC_VAL, staticVal);
  53. DDX_Control(pDX, IDC_BUTTON_BROWSE, btnBrowse);
  54. DDX_Control(pDX, IDC_E_135, btn135);
  55. DDX_Control(pDX, IDC_E_90, btn90);
  56. DDX_Control(pDX, IDC_E_45, btn45);
  57. DDX_Control(pDX, IDC_E_180, btn180);
  58. DDX_Control(pDX, IDC_E_0, btn360);
  59. DDX_Control(pDX, IDC_E_225, btn225);
  60. DDX_Control(pDX, IDC_E_270, btn270);
  61. DDX_Control(pDX, IDC_E_315, btn315);
  62. DDX_Control(pDX, IDC_E_UP, btnUp);
  63. DDX_Control(pDX, IDC_E_DOWN, btnDown);
  64. DDX_Control(pDX, IDC_BUTTON_MODEL, btnModel);
  65. DDX_Control(pDX, IDC_BUTTON_SOUND, btnSound);
  66. DDX_Control(pDX, IDC_BUTTON_GUI, btnGui);
  67. DDX_Control(pDX, IDC_BUTTON_PARTICLE, btnParticle);
  68. DDX_Control(pDX, IDC_BUTTON_SKIN, btnSkin);
  69. DDX_Control(pDX, IDC_BUTTON_CURVE, btnCurve);
  70. DDX_Control(pDX, IDC_BUTTON_CREATE, btnCreate);
  71. DDX_Control(pDX, IDC_LIST_VARS, listVars);
  72. DDX_Control(pDX, IDC_ENTITY_ANIMATIONS , cbAnimations);
  73. DDX_Control(pDX, IDC_ANIMATION_SLIDER , slFrameSlider);
  74. DDX_Control(pDX, IDC_ENTITY_CURRENT_ANIM , staticFrame);
  75. DDX_Control(pDX, IDC_ENTITY_PLAY_ANIM , btnPlayAnim);
  76. DDX_Control(pDX, IDC_ENTITY_STOP_ANIM , btnStopAnim);
  77. }
  78. BOOL CEntityDlg::OnInitDialog()
  79. {
  80. CDialog::OnInitDialog();
  81. listKeyVal.SetUpdateInspectors(true);
  82. listKeyVal.SetDivider(100);
  83. listVars.SetDivider(100);
  84. staticFrame.SetWindowText ( "0" );
  85. return TRUE; // return TRUE unless you set the focus to a control
  86. // EXCEPTION: OCX Property Pages should return FALSE
  87. }
  88. int CEntityDlg::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  89. {
  90. // TODO: Add your specialized code here and/or call the base class
  91. return CDialog::OnToolHitTest(point, pTI);
  92. }
  93. void CEntityDlg::AddClassNames() {
  94. comboClass.ResetContent();
  95. for (eclass_t *pec = eclass; pec; pec = pec->next) {
  96. comboClass.AddString(pec->name);
  97. }
  98. }
  99. BEGIN_MESSAGE_MAP(CEntityDlg, CDialog)
  100. ON_WM_SIZE()
  101. ON_CBN_SELCHANGE(IDC_COMBO_CLASS, OnCbnSelchangeComboClass)
  102. ON_LBN_SELCHANGE(IDC_LIST_KEYVAL, OnLbnSelchangeListkeyval)
  103. ON_BN_CLICKED(IDC_E_135, OnBnClickedE135)
  104. ON_BN_CLICKED(IDC_E_90, OnBnClickedE90)
  105. ON_BN_CLICKED(IDC_E_45, OnBnClickedE45)
  106. ON_BN_CLICKED(IDC_E_180, OnBnClickedE180)
  107. ON_BN_CLICKED(IDC_E_0, OnBnClickedE0)
  108. ON_BN_CLICKED(IDC_E_225, OnBnClickedE225)
  109. ON_BN_CLICKED(IDC_E_270, OnBnClickedE270)
  110. ON_BN_CLICKED(IDC_E_315, OnBnClickedE315)
  111. ON_BN_CLICKED(IDC_E_UP, OnBnClickedEUp)
  112. ON_BN_CLICKED(IDC_E_DOWN, OnBnClickedEDown)
  113. ON_BN_CLICKED(IDC_BUTTON_MODEL, OnBnClickedButtonModel)
  114. ON_BN_CLICKED(IDC_BUTTON_SOUND, OnBnClickedButtonSound)
  115. ON_BN_CLICKED(IDC_BUTTON_GUI, OnBnClickedButtonGui)
  116. ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse)
  117. ON_CBN_DBLCLK(IDC_COMBO_CLASS, OnCbnDblclkComboClass)
  118. ON_BN_CLICKED(IDC_BUTTON_CREATE, OnBnClickedButtonCreate)
  119. ON_LBN_DBLCLK(IDC_LIST_KEYVAL, OnLbnDblclkListkeyval)
  120. ON_LBN_SELCHANGE(IDC_LIST_VARS, OnLbnSelchangeListVars)
  121. ON_LBN_DBLCLK(IDC_LIST_VARS, OnLbnDblclkListVars)
  122. ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_ANIMATION_SLIDER, OnNMReleasedcaptureSlider1)
  123. ON_BN_CLICKED(IDC_BUTTON_PARTICLE, OnBnClickedButtonParticle)
  124. ON_BN_CLICKED(IDC_BUTTON_SKIN, OnBnClickedButtonSkin)
  125. ON_BN_CLICKED(IDC_BUTTON_CURVE, OnBnClickedButtonCurve)
  126. ON_CBN_SELCHANGE(IDC_ENTITY_ANIMATIONS, OnCbnAnimationChange)
  127. ON_BN_CLICKED(IDC_ENTITY_PLAY_ANIM , OnBnClickedStartAnimation)
  128. ON_BN_CLICKED(IDC_ENTITY_STOP_ANIM , OnBnClickedStopAnimation)
  129. ON_WM_TIMER()
  130. ON_BN_CLICKED(IDOK, OnOK)
  131. END_MESSAGE_MAP()
  132. void CEntityDlg::OnSize(UINT nType, int cx, int cy)
  133. {
  134. if (staticTitle.GetSafeHwnd() == NULL) {
  135. return;
  136. }
  137. CDialog::OnSize(nType, cx, cy);
  138. CRect rect, crect, crect2;
  139. GetClientRect(rect);
  140. int bh = (float)rect.Height() * (rect.Height() - 210) / rect.Height() / 2;
  141. staticTitle.GetWindowRect(crect);
  142. staticTitle.SetWindowPos(NULL, 4, 4, rect.Width() -8, crect.Height(), SWP_SHOWWINDOW);
  143. int top = 4 + crect.Height() + 4;
  144. comboClass.GetWindowRect(crect);
  145. btnCreate.GetWindowRect(crect2);
  146. comboClass.SetWindowPos(NULL, 4, top, rect.Width() - 12 - crect2.Width(), crect.Height(), SWP_SHOWWINDOW);
  147. btnCreate.SetWindowPos(NULL, rect.Width() - crect2.Width() - 4, top, crect2.Width(), crect.Height(), SWP_SHOWWINDOW);
  148. top += crect.Height() + 4;
  149. listVars.SetWindowPos(NULL, 4, top, rect.Width() - 8, bh, SWP_SHOWWINDOW);
  150. top += bh + 4;
  151. listKeyVal.SetWindowPos(NULL, 4, top, rect.Width() - 8, bh, SWP_SHOWWINDOW);
  152. top += bh + 4;
  153. staticKey.GetWindowRect(crect);
  154. staticKey.SetWindowPos(NULL, 4, top + 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
  155. int left = 4 + crect.Width() + 4;
  156. int pad = crect.Width();
  157. editKey.GetWindowRect(crect);
  158. editKey.SetWindowPos(NULL, left, top, rect.Width() - 12 - pad, crect.Height(), SWP_SHOWWINDOW);
  159. top += crect.Height() + 4;
  160. staticVal.GetWindowRect(crect);
  161. staticVal.SetWindowPos(NULL, 4, top + 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
  162. editVal.GetWindowRect(crect);
  163. bh = crect.Height();
  164. editVal.SetWindowPos(NULL, left, top, rect.Width() - 16 - bh - pad, crect.Height(), SWP_SHOWWINDOW);
  165. btnBrowse.SetWindowPos(NULL, rect.right - 4 - bh, top, bh, bh, SWP_SHOWWINDOW);
  166. top += crect.Height() + 8;
  167. btnModel.GetWindowRect(crect);
  168. btnModel.SetWindowPos(NULL, rect.right - 4 - crect.Width(), top + 8, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
  169. btnSound.SetWindowPos(NULL, rect.right - 4 - crect.Width(), top + 12 + crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW);
  170. btnGui.SetWindowPos(NULL, rect.right - 4 - crect.Width(), top + 16 + crect.Height() * 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
  171. btnParticle.SetWindowPos(NULL, rect.right - 8 - (crect.Width() * 2), top + 16 + crect.Height() * 2, crect.Width(), crect.Height(), SWP_SHOWWINDOW);
  172. btnSkin.SetWindowPos( NULL, rect.right - 8 - ( crect.Width() * 2 ), top + 12 + crect.Height(), crect.Width(), crect.Height(), SWP_SHOWWINDOW );
  173. btnCurve.SetWindowPos( NULL, rect.right - 8 - ( crect.Width() * 2 ), top + 8, crect.Width(), crect.Height(), SWP_SHOWWINDOW );
  174. //*************************************
  175. //animation controls
  176. //*************************************
  177. int rightAnimAreaBorder = rect.right - 75 - crect.Width (); /*models, etc button width*/
  178. btnStopAnim.GetWindowRect(crect);
  179. btnStopAnim.SetWindowPos(NULL,rightAnimAreaBorder - crect.Width (),
  180. top + 8 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
  181. left = rightAnimAreaBorder - crect.Width() - 4;
  182. btnPlayAnim.GetWindowRect(crect);
  183. btnPlayAnim.SetWindowPos(NULL,left-crect.Width () ,top + 8 , crect.Width(),crect.Height(),SWP_SHOWWINDOW);
  184. left -= crect.Width() + 4;
  185. cbAnimations.GetWindowRect(crect);
  186. cbAnimations.SetWindowPos(NULL,left-crect.Width (),top + 8 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
  187. staticFrame.GetWindowRect(crect);
  188. staticFrame.SetWindowPos(NULL,rightAnimAreaBorder - crect.Width (),
  189. top + 34 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
  190. left = rightAnimAreaBorder - crect.Width () - 4;
  191. slFrameSlider.GetWindowRect(crect);
  192. slFrameSlider.SetWindowPos(NULL,left - crect.Width (),
  193. top + 32 ,crect.Width(),crect.Height(),SWP_SHOWWINDOW);
  194. //*************************************
  195. //*************************************
  196. btn135.GetWindowRect(crect);
  197. bh = crect.Width();
  198. btn135.SetWindowPos(NULL, 4, top, bh, bh, SWP_SHOWWINDOW);
  199. btn90.SetWindowPos(NULL, 4 + 2 + bh, top, bh, bh, SWP_SHOWWINDOW);
  200. btn45.SetWindowPos(NULL, 4 + 2 + 2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW);
  201. btnUp.SetWindowPos(NULL, 4 + 2 + 2 + 6 + bh * 3, top + bh / 2,bh,bh, SWP_SHOWWINDOW);
  202. btnDown.SetWindowPos(NULL, 4 + 2 + 2 + 6 + bh *3, top + bh / 2 + bh + 2,bh,bh, SWP_SHOWWINDOW);
  203. top += bh + 2;
  204. btn180.SetWindowPos(NULL, 4, top, bh, bh, SWP_SHOWWINDOW);
  205. btn360.SetWindowPos(NULL, 4 + 2 + 2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW);
  206. top += bh + 2;
  207. btn225.SetWindowPos(NULL, 4, top, bh, bh, SWP_SHOWWINDOW);
  208. btn270.SetWindowPos(NULL, 4 + 2 + bh, top, bh, bh, SWP_SHOWWINDOW);
  209. btn315.SetWindowPos(NULL, 4 + 2 + 2 + bh * 2, top, bh, bh, SWP_SHOWWINDOW);
  210. Invalidate();
  211. }
  212. void CEntityDlg::OnCbnSelchangeComboClass()
  213. {
  214. int index = comboClass.GetCurSel();
  215. if (index != LB_ERR) {
  216. CString str;
  217. comboClass.GetLBText(index, str);
  218. eclass_t *ent = Eclass_ForName (str, false);
  219. if (ent) {
  220. if (selected_brushes.next == &selected_brushes) {
  221. editEntity = world_entity;
  222. multipleEntities = false;
  223. } else {
  224. editEntity = selected_brushes.next->owner;
  225. for (brush_t *b = selected_brushes.next->next; b != &selected_brushes; b = b->next) {
  226. if (b->owner != editEntity) {
  227. multipleEntities = true;
  228. break;
  229. }
  230. }
  231. }
  232. listVars.ResetContent();
  233. CPropertyItem *pi = new CPropertyItem("Usage:", ent->desc.c_str(), PIT_VAR, "");
  234. listVars.AddPropItem(pi);
  235. int c = ent->vars.Num();
  236. for (int i = 0; i < c; i++) {
  237. pi = new CPropertyItem(ent->vars[i].name.c_str(), ent->vars[i].desc.c_str(), PIT_VAR, "");
  238. pi->SetData(ent->vars[i].type);
  239. listVars.AddPropItem(pi);
  240. }
  241. listVars.Invalidate();
  242. SetKeyValPairs();
  243. }
  244. }
  245. }
  246. const char *CEntityDlg::TranslateString(const char *buf) {
  247. static char buf2[32768];
  248. int i, l;
  249. char *out;
  250. l = strlen(buf);
  251. out = buf2;
  252. for (i = 0; i < l; i++) {
  253. if (buf[i] == '\n') {
  254. *out++ = '\r';
  255. *out++ = '\n';
  256. }
  257. else {
  258. *out++ = buf[i];
  259. }
  260. }
  261. *out++ = 0;
  262. return buf2;
  263. }
  264. void CEntityDlg::UpdateFromListBox() {
  265. if (editEntity == NULL) {
  266. return;
  267. }
  268. int c = listKeyVal.GetCount();
  269. for (int i = 0 ; i < c; i++) {
  270. CPropertyItem* pItem = (CPropertyItem*)listKeyVal.GetItemDataPtr(i);
  271. if (pItem) {
  272. editEntity->epairs.Set(pItem->m_propName, pItem->m_curValue);
  273. }
  274. }
  275. SetKeyValPairs();
  276. }
  277. void CEntityDlg::SetKeyValPairs( bool updateAnims ) {
  278. if (editEntity) {
  279. listKeyVal.ResetContent();
  280. int c = editEntity->epairs.GetNumKeyVals();
  281. for (int i = 0; i < c; i++) {
  282. const idKeyValue *kv = editEntity->epairs.GetKeyVal(i);
  283. CPropertyItem *pi = new CPropertyItem(kv->GetKey().c_str(), kv->GetValue().c_str(), PIT_EDIT, "");
  284. bool found = false;
  285. int vc = editEntity->eclass->vars.Num();
  286. for (int j = 0; j < vc; j++) {
  287. if (editEntity->eclass->vars[j].name.Icmp(kv->GetKey()) == 0) {
  288. switch (editEntity->eclass->vars[j].type) {
  289. case EVAR_STRING :
  290. case EVAR_INT :
  291. case EVAR_FLOAT :
  292. pi->m_nItemType = PIT_EDIT;
  293. break;
  294. case EVAR_BOOL :
  295. pi->m_nItemType = PIT_EDIT;
  296. //pi->m_cmbItems = "0|1";
  297. break;
  298. case EVAR_COLOR :
  299. pi->m_nItemType = PIT_COLOR;
  300. break;
  301. case EVAR_MATERIAL :
  302. pi->m_nItemType = PIT_MATERIAL;
  303. break;
  304. case EVAR_MODEL :
  305. pi->m_nItemType = PIT_MODEL;
  306. break;
  307. case EVAR_GUI :
  308. pi->m_nItemType = PIT_GUI;
  309. break;
  310. case EVAR_SOUND :
  311. pi->m_nItemType = PIT_SOUND;
  312. break;
  313. }
  314. found = true;
  315. break;
  316. }
  317. }
  318. if (!found) {
  319. if (kv->GetKey().Icmp("model") == 0) {
  320. pi->m_nItemType = PIT_MODEL;
  321. }
  322. if (kv->GetKey().Icmp("_color") == 0) {
  323. pi->m_nItemType = PIT_COLOR;
  324. }
  325. if (kv->GetKey().Icmp("gui") == 0) {
  326. pi->m_nItemType = PIT_GUI;
  327. }
  328. if (kv->GetKey().Icmp("gui2") == 0) {
  329. pi->m_nItemType = PIT_GUI;
  330. }
  331. if (kv->GetKey().Icmp("gui3") == 0) {
  332. pi->m_nItemType = PIT_GUI;
  333. }
  334. if (kv->GetKey().Icmp("s_shader") == 0) {
  335. pi->m_nItemType = PIT_SOUND;
  336. }
  337. }
  338. listKeyVal.AddPropItem(pi);
  339. }
  340. if ( updateAnims ) {
  341. int i, num;
  342. cbAnimations.ResetContent();
  343. num = gameEdit->ANIM_GetNumAnimsFromEntityDef( &editEntity->eclass->defArgs );
  344. for( i = 0; i < num; i++ ) {
  345. cbAnimations.AddString( gameEdit->ANIM_GetAnimNameFromEntityDef( &editEntity->eclass->defArgs, i ) );
  346. }
  347. const idKeyValue* kv = editEntity->epairs.FindKey ( "anim" );
  348. if ( kv ) {
  349. int selIndex = cbAnimations.FindStringExact( 0 , kv->GetValue().c_str() );
  350. if ( selIndex != -1 ) {
  351. cbAnimations.SetCurSel( selIndex );
  352. OnCbnAnimationChange ();
  353. }
  354. }
  355. }
  356. }
  357. }
  358. void CEntityDlg::UpdateEntitySel(eclass_t *ent) {
  359. assert ( ent );
  360. assert ( ent->name );
  361. int index = comboClass.FindString(-1, ent->name);
  362. if (index != LB_ERR) {
  363. comboClass.SetCurSel(index);
  364. OnCbnSelchangeComboClass();
  365. }
  366. }
  367. void CEntityDlg::OnLbnSelchangeListkeyval()
  368. {
  369. int index = listKeyVal.GetCurSel();
  370. if (index != LB_ERR) {
  371. CString str;
  372. listKeyVal.GetText(index, str);
  373. int i;
  374. for (i = 0; str[i] != '\t' && str[i] != '\0'; i++) {
  375. }
  376. idStr key = str.Left(i);
  377. while (str[i] == '\t' && str[i] != '\0') {
  378. i++;
  379. }
  380. idStr val = str.Right(str.GetLength() - i);
  381. editKey.SetWindowText(key);
  382. editVal.SetWindowText(val);
  383. }
  384. }
  385. static int TabOrder[] = {
  386. IDC_COMBO_CLASS,
  387. IDC_BUTTON_CREATE,
  388. //IDC_EDIT_INFO,
  389. IDC_LIST_KEYVAL,
  390. IDC_EDIT_KEY,
  391. IDC_EDIT_VAL,
  392. IDC_BUTTON_BROWSE,
  393. IDC_E_135,
  394. IDC_E_90,
  395. IDC_E_45,
  396. IDC_E_180,
  397. IDC_E_0,
  398. IDC_E_225,
  399. IDC_E_270,
  400. IDC_E_315,
  401. IDC_E_UP,
  402. IDC_E_DOWN,
  403. IDC_BUTTON_MODEL,
  404. IDC_BUTTON_SOUND,
  405. IDC_BUTTON_GUI,
  406. IDC_ENTITY_ANIMATIONS
  407. };
  408. int TabCount = sizeof(TabOrder) / sizeof(int);
  409. void CEntityDlg::DelProp() {
  410. CString key;
  411. if (editEntity == NULL) {
  412. return;
  413. }
  414. editKey.GetWindowText(key);
  415. if (multipleEntities) {
  416. for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  417. DeleteKey(b->owner, key);
  418. Entity_UpdateCurveData( b->owner );
  419. }
  420. } else {
  421. DeleteKey(editEntity, key);
  422. Entity_UpdateCurveData( editEntity );
  423. }
  424. // refresh the prop listbox
  425. SetKeyValPairs();
  426. Sys_UpdateWindows( W_ENTITY | W_XY | W_CAMERA );
  427. }
  428. BOOL CEntityDlg::PreTranslateMessage(MSG* pMsg)
  429. {
  430. if (pMsg->hwnd == editVal.GetSafeHwnd()) {
  431. if (pMsg->message == WM_LBUTTONDOWN) {
  432. editVal.SetFocus();
  433. return TRUE;
  434. }
  435. }
  436. if (pMsg->hwnd == editKey.GetSafeHwnd()) {
  437. if (pMsg->message == WM_LBUTTONDOWN) {
  438. editKey.SetFocus();
  439. return TRUE;
  440. }
  441. }
  442. if (GetFocus() == &editVal || GetFocus() == &editKey) {
  443. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
  444. AddProp();
  445. return TRUE;
  446. }
  447. }
  448. if (GetFocus() == listKeyVal.GetEditBox()) {
  449. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
  450. listKeyVal.OnChangeEditBox();
  451. listKeyVal.OnSelchange();
  452. listKeyVal.OnKillfocusEditBox();
  453. AddProp();
  454. SetKeyValPairs();
  455. return TRUE;
  456. }
  457. }
  458. if (GetFocus() == &listKeyVal) {
  459. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE && editEntity) {
  460. DelProp();
  461. return TRUE;
  462. }
  463. }
  464. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) {
  465. if (pMsg->wParam == VK_ESCAPE) {
  466. g_pParentWnd->GetCamera()->SetFocus();
  467. Select_Deselect();
  468. }
  469. return TRUE;
  470. }
  471. if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN ) {
  472. // keeps ENTER from closing the dialog
  473. return TRUE;
  474. }
  475. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB) {
  476. if (GetFocus()) {
  477. int id = GetFocus()->GetDlgCtrlID();
  478. for (int i = 0; i < TabCount; i++) {
  479. if (TabOrder[i] == id) {
  480. i++;
  481. if (i >= TabCount) {
  482. i = 0;
  483. }
  484. CWnd *next = GetDlgItem(TabOrder[i]);
  485. if (next) {
  486. next->SetFocus();
  487. if (TabOrder[i] == IDC_EDIT_VAL) {
  488. editVal.SetSel(0, -1);
  489. }
  490. return TRUE;
  491. }
  492. }
  493. }
  494. }
  495. }
  496. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RIGHT && pMsg->hwnd == slFrameSlider.GetSafeHwnd()) {
  497. int pos = slFrameSlider.GetPos() + 1;
  498. pos = (pos % slFrameSlider.GetRangeMax());
  499. slFrameSlider.SetPos ( pos );
  500. UpdateFromAnimationFrame ();
  501. return TRUE;
  502. }
  503. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_LEFT && pMsg->hwnd == slFrameSlider.GetSafeHwnd()) {
  504. int pos = slFrameSlider.GetPos() - 1;
  505. if ( pos < 1 ) {
  506. pos = slFrameSlider.GetRangeMax();
  507. }
  508. slFrameSlider.SetPos ( pos );
  509. UpdateFromAnimationFrame ();
  510. return TRUE;
  511. }
  512. return CDialog::PreTranslateMessage(pMsg);
  513. }
  514. /*
  515. =======================================================================================================================
  516. AddProp
  517. =======================================================================================================================
  518. */
  519. void CEntityDlg::AddProp() {
  520. if (editEntity == NULL) {
  521. return;
  522. }
  523. CString Key, Value;
  524. editKey.GetWindowText(Key);
  525. editVal.GetWindowText(Value);
  526. bool isName = (stricmp(Key, "name") == 0);
  527. bool isModel = static_cast<bool>((stricmp(Key, "model") == 0 && Value.GetLength() > 0));
  528. bool isOrigin = ( idStr::Icmp( Key, "origin" ) == 0 );
  529. if (multipleEntities) {
  530. brush_t *b;
  531. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  532. if (isName) {
  533. Entity_SetName(b->owner, Value);
  534. } else {
  535. if ( ! ( ( isModel || isOrigin ) && ( b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) {
  536. SetKeyValue(b->owner, Key, Value);
  537. }
  538. }
  539. }
  540. }
  541. else {
  542. if (isName) {
  543. Entity_SetName(editEntity, Value);
  544. } else {
  545. if ( ! ( ( isModel || isOrigin ) && ( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) {
  546. SetKeyValue(editEntity, Key, Value);
  547. }
  548. }
  549. if ( isModel && !( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) {
  550. idBounds bo;
  551. idVec3 mins, maxs;
  552. selected_brushes.next->modelHandle = renderModelManager->FindModel( Value );
  553. if ( dynamic_cast<idRenderModelPrt*>( selected_brushes.next->modelHandle ) || dynamic_cast<idRenderModelLiquid*>( selected_brushes.next->modelHandle ) ) {
  554. bo.Zero();
  555. bo.ExpandSelf( 12.0f );
  556. } else {
  557. bo = selected_brushes.next->modelHandle->Bounds( NULL );
  558. }
  559. VectorCopy(bo[0], mins);
  560. VectorCopy(bo[1], maxs);
  561. VectorAdd(mins, editEntity->origin, mins);
  562. VectorAdd(maxs, editEntity->origin, maxs);
  563. Brush_RebuildBrush(selected_brushes.next, mins, maxs, false);
  564. Brush_Build ( selected_brushes.next , false, false , false, true );
  565. }
  566. }
  567. // refresh the prop listbox
  568. SetKeyValPairs();
  569. Sys_UpdateWindows(W_ALL);
  570. }
  571. const char *CEntityDlg::AngleKey() {
  572. if (editEntity == NULL) {
  573. return "";
  574. }
  575. if (editEntity->eclass->nShowFlags & ECLASS_MOVER) {
  576. return "movedir";
  577. }
  578. return "angle";
  579. }
  580. void CEntityDlg::OnBnClickedE135()
  581. {
  582. if (editEntity == NULL) {
  583. return;
  584. }
  585. editKey.SetWindowText(AngleKey());
  586. editVal.SetWindowText("135");
  587. AddProp();
  588. }
  589. void CEntityDlg::OnBnClickedE90()
  590. {
  591. if (editEntity == NULL) {
  592. return;
  593. }
  594. editKey.SetWindowText(AngleKey());
  595. editVal.SetWindowText("90");
  596. AddProp();
  597. }
  598. void CEntityDlg::OnBnClickedE45()
  599. {
  600. if (editEntity == NULL) {
  601. return;
  602. }
  603. editKey.SetWindowText(AngleKey());
  604. editVal.SetWindowText("45");
  605. AddProp();
  606. }
  607. void CEntityDlg::OnBnClickedE180()
  608. {
  609. if (editEntity == NULL) {
  610. return;
  611. }
  612. editKey.SetWindowText(AngleKey());
  613. editVal.SetWindowText("180");
  614. AddProp();
  615. }
  616. void CEntityDlg::OnBnClickedE0()
  617. {
  618. if (editEntity == NULL) {
  619. return;
  620. }
  621. editKey.SetWindowText(AngleKey());
  622. editVal.SetWindowText("0");
  623. AddProp();
  624. }
  625. void CEntityDlg::OnBnClickedE225()
  626. {
  627. if (editEntity == NULL) {
  628. return;
  629. }
  630. editKey.SetWindowText(AngleKey());
  631. editVal.SetWindowText("225");
  632. AddProp();
  633. }
  634. void CEntityDlg::OnBnClickedE270()
  635. {
  636. if (editEntity == NULL) {
  637. return;
  638. }
  639. editKey.SetWindowText(AngleKey());
  640. editVal.SetWindowText("270");
  641. AddProp();
  642. }
  643. void CEntityDlg::OnBnClickedE315()
  644. {
  645. if (editEntity == NULL) {
  646. return;
  647. }
  648. editKey.SetWindowText(AngleKey());
  649. editVal.SetWindowText("315");
  650. AddProp();
  651. }
  652. void CEntityDlg::OnBnClickedEUp()
  653. {
  654. if (editEntity == NULL) {
  655. return;
  656. }
  657. editKey.SetWindowText(AngleKey());
  658. editVal.SetWindowText("-1");
  659. AddProp();
  660. }
  661. void CEntityDlg::OnBnClickedEDown()
  662. {
  663. if (editEntity == NULL) {
  664. return;
  665. }
  666. editKey.SetWindowText(AngleKey());
  667. editVal.SetWindowText("-2");
  668. AddProp();
  669. }
  670. CPreviewDlg *CEntityDlg::ShowModelChooser() {
  671. static CPreviewDlg modelDlg;
  672. modelDlg.SetMode(CPreviewDlg::MODELS);
  673. modelDlg.SetModal();
  674. if (modelDlg.GetSafeHwnd() == NULL) {
  675. modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
  676. }
  677. modelDlg.ShowWindow( SW_SHOW );
  678. modelDlg.BringWindowToTop();
  679. while (modelDlg.Waiting()) {
  680. }
  681. return &modelDlg;
  682. }
  683. CPreviewDlg *CEntityDlg::ShowParticleChooser() {
  684. static CPreviewDlg modelDlg;
  685. modelDlg.SetMode(CPreviewDlg::PARTICLES);
  686. modelDlg.SetModal();
  687. if (modelDlg.GetSafeHwnd() == NULL) {
  688. modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
  689. }
  690. modelDlg.ShowWindow(SW_SHOW);
  691. modelDlg.BringWindowToTop();
  692. while (modelDlg.Waiting()) {
  693. }
  694. return &modelDlg;
  695. }
  696. CPreviewDlg *CEntityDlg::ShowSkinChooser(entity_t *ent) {
  697. static CPreviewDlg modelDlg;
  698. modelDlg.SetMode(CPreviewDlg::SKINS);
  699. modelDlg.SetModal();
  700. if (modelDlg.GetSafeHwnd() == NULL) {
  701. modelDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
  702. }
  703. modelDlg.RebuildTree( ( ent ) ? ent->epairs.GetString( "model" ) : "" );
  704. modelDlg.ShowWindow(SW_SHOW);
  705. modelDlg.BringWindowToTop();
  706. while (modelDlg.Waiting()) {
  707. }
  708. return &modelDlg;
  709. }
  710. CPreviewDlg *CEntityDlg::ShowGuiChooser() {
  711. static CPreviewDlg guiDlg;
  712. guiDlg.SetMode(CPreviewDlg::GUIS);
  713. guiDlg.SetModal();
  714. if (guiDlg.GetSafeHwnd() == NULL) {
  715. guiDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
  716. }
  717. guiDlg.ShowWindow(SW_SHOW);
  718. guiDlg.BringWindowToTop();
  719. while (guiDlg.Waiting()) {
  720. }
  721. return &guiDlg;
  722. }
  723. CPreviewDlg *CEntityDlg::ShowSoundChooser() {
  724. static CPreviewDlg soundDlg;
  725. soundDlg.SetMode(CPreviewDlg::SOUNDS);
  726. soundDlg.SetModal();
  727. if (soundDlg.GetSafeHwnd() == NULL) {
  728. soundDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
  729. }
  730. soundDlg.ShowWindow(SW_SHOW);
  731. while (soundDlg.Waiting()) {
  732. }
  733. return &soundDlg;
  734. }
  735. CPreviewDlg *CEntityDlg::ShowMaterialChooser() {
  736. static CPreviewDlg matDlg;
  737. matDlg.SetMode(CPreviewDlg::MATERIALS);
  738. matDlg.SetModal();
  739. if (matDlg.GetSafeHwnd() == NULL) {
  740. matDlg.Create(MAKEINTRESOURCE(IDD_DIALOG_PREVIEW));
  741. }
  742. matDlg.ShowWindow(SW_SHOW);
  743. matDlg.BringWindowToTop();
  744. while (matDlg.Waiting()) {
  745. }
  746. return &matDlg;
  747. }
  748. void CEntityDlg::AssignModel ()
  749. {
  750. OnBnClickedButtonModel();
  751. }
  752. void CEntityDlg::OnBnClickedButtonModel() {
  753. CPreviewDlg *dlg = ShowModelChooser();
  754. if (dlg->returnCode == IDOK) {
  755. editKey.SetWindowText("model");
  756. editVal.SetWindowText(dlg->mediaName);
  757. AddProp();
  758. }
  759. }
  760. void CEntityDlg::OnBnClickedButtonSound() {
  761. CPreviewDlg *dlg = ShowSoundChooser();
  762. if (dlg->returnCode == IDOK) {
  763. editKey.SetWindowText("s_shader");
  764. editVal.SetWindowText(dlg->mediaName);
  765. AddProp();
  766. }
  767. }
  768. void CEntityDlg::OnBnClickedButtonGui() {
  769. CPreviewDlg *dlg = ShowGuiChooser();
  770. if (dlg->returnCode == IDOK) {
  771. editKey.SetWindowText("gui");
  772. editVal.SetWindowText(dlg->mediaName);
  773. AddProp();
  774. }
  775. }
  776. void CEntityDlg::OnBnClickedButtonParticle() {
  777. CPreviewDlg *dlg = ShowParticleChooser();
  778. if (dlg->returnCode == IDOK) {
  779. editKey.SetWindowText("model");
  780. editVal.SetWindowText(dlg->mediaName);
  781. AddProp();
  782. }
  783. }
  784. void CEntityDlg::OnBnClickedButtonSkin() {
  785. CPreviewDlg *dlg = ShowSkinChooser( editEntity );
  786. if (dlg->returnCode == IDOK) {
  787. editKey.SetWindowText("skin");
  788. editVal.SetWindowText(dlg->mediaName);
  789. AddProp();
  790. }
  791. }
  792. void CEntityDlg::OnBnClickedButtonCurve() {
  793. CCurveDlg dlg;
  794. if ( dlg.DoModal() == IDOK ) {
  795. if ( editEntity ) {
  796. idStr str = "curve_" + dlg.strCurveType;
  797. editKey.SetWindowText( str );
  798. idVec3 org = editEntity->origin;
  799. str = "3 ( ";
  800. str += org.ToString();
  801. org.x += 64;
  802. str += " ";
  803. str += org.ToString();
  804. org.y += 64;
  805. str += " ";
  806. str += org.ToString();
  807. str += " )";
  808. editVal.SetWindowText( str );
  809. AddProp();
  810. Entity_SetCurveData( editEntity );
  811. }
  812. }
  813. }
  814. void CEntityDlg::OnBnClickedButtonBrowse() {
  815. DelProp();
  816. }
  817. void CEntityDlg::OnCbnDblclkComboClass()
  818. {
  819. // TODO: Add your control notification handler code here
  820. }
  821. //
  822. // =======================================================================================================================
  823. // CreateEntity Creates a new entity based on the currently selected brush and entity type.
  824. // =======================================================================================================================
  825. //
  826. void CEntityDlg::CreateEntity() {
  827. entity_t *petNew;
  828. bool forceFixed = false;
  829. // check to make sure we have a brush
  830. CXYWnd *pWnd = g_pParentWnd->ActiveXY();
  831. if (pWnd) {
  832. CRect rctZ;
  833. pWnd->GetClientRect(rctZ);
  834. brush_t *pBrush;
  835. if (selected_brushes.next == &selected_brushes) {
  836. pBrush = CreateEntityBrush(g_nSmartX, rctZ.Height() - 1 - g_nSmartY, pWnd);
  837. forceFixed = true;
  838. }
  839. }
  840. else {
  841. if (selected_brushes.next == &selected_brushes) {
  842. MessageBox("You must have a selected brush to create an entity", "info", 0);
  843. return;
  844. }
  845. }
  846. int index = comboClass.GetCurSel();
  847. if (index == LB_ERR) {
  848. MessageBox("You must have a selected class to create an entity", "info", 0);
  849. return;
  850. }
  851. CString str;
  852. comboClass.GetLBText(index, str);
  853. if (!stricmp(str, "worldspawn")) {
  854. MessageBox("Can't create an entity with worldspawn.", "info", 0);
  855. return;
  856. }
  857. eclass_t *pecNew = Eclass_ForName (str, false);
  858. // create it
  859. if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
  860. // MAJOR hack for xian
  861. extern void Brush_CopyList(brush_t *pFrom, brush_t *pTo);
  862. brush_t temp_brushes;
  863. temp_brushes.next = &temp_brushes;
  864. Brush_CopyList(&selected_brushes, &temp_brushes);
  865. Select_Deselect();
  866. brush_t *pBrush = temp_brushes.next;
  867. while (pBrush != NULL && pBrush != &temp_brushes) {
  868. brush_t *pNext = pBrush->next;
  869. Brush_RemoveFromList(pBrush);
  870. Brush_AddToList(pBrush, &selected_brushes);
  871. pBrush = pNext;
  872. petNew = Entity_Create(pecNew, forceFixed);
  873. Select_Deselect();
  874. }
  875. } else if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
  876. Select_Ungroup();
  877. petNew = Entity_Create(pecNew, forceFixed);
  878. } else {
  879. petNew = Entity_Create(pecNew, forceFixed);
  880. }
  881. if (petNew == NULL) {
  882. MessageBox("Failed to create entity.", "info", 0);
  883. return;
  884. }
  885. if (selected_brushes.next == &selected_brushes) {
  886. editEntity = world_entity;
  887. }
  888. else {
  889. editEntity = selected_brushes.next->owner;
  890. }
  891. SetKeyValPairs();
  892. Select_Deselect();
  893. Select_Brush(editEntity->brushes.onext);
  894. Sys_UpdateWindows(W_ALL);
  895. }
  896. void CEntityDlg::OnBnClickedButtonCreate()
  897. {
  898. CreateEntity();
  899. }
  900. void CEntityDlg::OnLbnDblclkListkeyval()
  901. {
  902. CString Key, Value;
  903. idStr work;
  904. editKey.GetWindowText( Key );
  905. editVal.GetWindowText( Value );
  906. if ( stricmp( Key, "script" ) == 0 ) {
  907. Key = Value;
  908. Value = "script/" + Key;
  909. if ( fileSystem->ReadFile( Value, NULL, NULL ) == -1) {
  910. sprintf( work, "// Script for %s\n// \n\nvoid main() {\n\n}\n\n", currentmap );
  911. fileSystem->WriteFile( Value, work.c_str(), work.Length(), "fs_devpath" );
  912. }
  913. work = fileSystem->RelativePathToOSPath( Value );
  914. WinExec( va( "notepad.exe %s", work.c_str() ), SW_SHOW );
  915. }
  916. }
  917. void CEntityDlg::OnLbnSelchangeListVars() {
  918. }
  919. void CEntityDlg::OnLbnDblclkListVars() {
  920. if (editEntity == NULL) {
  921. return;
  922. }
  923. int sel = listVars.GetCurSel();
  924. CPropertyItem *pi = (CPropertyItem*)listVars.GetItemDataPtr(sel);
  925. if (pi) {
  926. if (editEntity->epairs.FindKey(pi->m_propName) == NULL) {
  927. editKey.SetWindowText(pi->m_propName);
  928. editVal.SetWindowText("");
  929. editVal.SetFocus();
  930. }
  931. }
  932. }
  933. void CEntityDlg::UpdateKeyVal(const char *key, const char *val) {
  934. if (editEntity) {
  935. editEntity->epairs.Set(key, val);
  936. SetKeyValPairs();
  937. g_pParentWnd->GetCamera()->BuildEntityRenderState(editEntity, true);
  938. Entity_UpdateSoundEmitter(editEntity);
  939. }
  940. }
  941. void CEntityDlg::OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult)
  942. {
  943. if ( !editEntity )
  944. {
  945. return;
  946. }
  947. UpdateFromAnimationFrame ();
  948. *pResult = 0;
  949. }
  950. void CEntityDlg::UpdateFromAnimationFrame ( bool updateKeyValueDisplay )
  951. {
  952. int frame = slFrameSlider.GetPos ();
  953. editEntity->epairs.SetInt( "frame" , frame );
  954. SetDlgItemText ( IDC_ENTITY_CURRENT_ANIM , va ( "%i" , frame));
  955. if ( updateKeyValueDisplay ) {
  956. SetKeyValPairs();
  957. }
  958. g_pParentWnd->GetCamera ()->BuildEntityRenderState (editEntity , true );
  959. Sys_UpdateWindows ( W_ALL );
  960. }
  961. void CEntityDlg::OnCbnAnimationChange ()
  962. {
  963. if ( !editEntity )
  964. {
  965. return;
  966. }
  967. int sel = cbAnimations.GetCurSel();
  968. CString animName;
  969. currentAnimation = NULL;
  970. int currFrame = 0;
  971. if ( sel != -1 ) {
  972. cbAnimations.GetLBText( sel , animName );
  973. if ( animName.GetLength() > 0 ) {
  974. //preserve the existing frame number
  975. currFrame = editEntity->epairs.GetInt ( "frame" , "1" );
  976. editEntity->epairs.Set("anim" , animName.GetBuffer(0));
  977. SetKeyValPairs(false/*don't update anims combo box :)*/ );
  978. //update the slider
  979. currentAnimation = gameEdit->ANIM_GetAnimFromEntityDef(editEntity->eclass->name , animName.GetBuffer(0));
  980. currentAnimationFrame = 0;
  981. if ( currentAnimation ) {
  982. slFrameSlider.SetRange( 1 , gameEdit->ANIM_GetNumFrames( currentAnimation ), TRUE );
  983. slFrameSlider.SetPos( currFrame );
  984. currentAnimationFrame = currFrame;
  985. }
  986. Sys_UpdateWindows(W_ALL);
  987. }
  988. }
  989. }
  990. void CEntityDlg::OnBnClickedStartAnimation()
  991. {
  992. if (!editEntity) {
  993. return;
  994. }
  995. SetTimer ( 0 , 1000/24 , NULL );
  996. }
  997. void CEntityDlg::OnBnClickedStopAnimation()
  998. {
  999. KillTimer ( 0 );
  1000. }
  1001. void CEntityDlg::OnTimer(UINT nIDEvent)
  1002. {
  1003. if ( !editEntity ) {
  1004. OnBnClickedStopAnimation ();
  1005. return;
  1006. }
  1007. if ( currentAnimation ) {
  1008. currentAnimationFrame = ( (currentAnimationFrame++) % gameEdit->ANIM_GetNumFrames( currentAnimation ) );
  1009. editEntity->epairs.SetInt ( "frame" , currentAnimationFrame );
  1010. slFrameSlider.SetPos ( currentAnimationFrame );
  1011. UpdateFromAnimationFrame (false/*don't update key/value display*/);
  1012. Sys_UpdateWindows ( W_CAMERA | W_XY );
  1013. }
  1014. }
  1015. void CEntityDlg::AddCurvePoints() {
  1016. if ( editEntity == NULL || editEntity->curve == NULL ) {
  1017. return;
  1018. }
  1019. // add one point 64 units from the direction of the two points int he curve
  1020. int c = editEntity->curve->GetNumValues();
  1021. idVec3 start;
  1022. idVec3 end;
  1023. if ( c > 1 ) {
  1024. start = editEntity->curve->GetValue( c - 2 );
  1025. end = editEntity->curve->GetValue( c - 1 );
  1026. idVec3 dir = end - start;
  1027. dir.Normalize();
  1028. start = end + 64 * dir;
  1029. } else if ( c > 0 ) {
  1030. start = editEntity->curve->GetValue( 0 );
  1031. start.x += 64;
  1032. start.y += 64;
  1033. } else {
  1034. start = editEntity->origin;
  1035. }
  1036. editEntity->curve->AddValue( editEntity->curve->GetNumValues() * 100, start );
  1037. if ( g_qeglobals.d_select_mode == sel_editpoint ) {
  1038. g_qeglobals.d_select_mode = sel_brush;
  1039. EditCurvePoints();
  1040. }
  1041. Sys_UpdateWindows( W_CAMERA | W_XY );
  1042. }
  1043. void CEntityDlg::EditCurvePoints() {
  1044. if ( editEntity == NULL || editEntity->curve == NULL ) {
  1045. return;
  1046. }
  1047. if ( g_qeglobals.d_select_mode == sel_editpoint ) {
  1048. g_qeglobals.d_select_mode = sel_brush;
  1049. return;
  1050. }
  1051. g_qeglobals.d_select_mode = sel_editpoint;
  1052. g_qeglobals.d_numpoints = 0;
  1053. g_qeglobals.d_num_move_points = 0;
  1054. int c = editEntity->curve->GetNumValues();
  1055. for ( int i = 0; i < c; i++ ) {
  1056. if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) {
  1057. g_qeglobals.d_points[g_qeglobals.d_numpoints++] = editEntity->curve->GetValue( i );
  1058. }
  1059. }
  1060. Sys_UpdateWindows( W_XY | W_CAMERA );
  1061. }
  1062. void CEntityDlg::InsertCurvePoint() {
  1063. if ( editEntity == NULL || editEntity->curve == NULL ) {
  1064. return;
  1065. }
  1066. if ( g_qeglobals.d_select_mode != sel_editpoint ) {
  1067. return;
  1068. }
  1069. if ( g_qeglobals.d_num_move_points == 0 ) {
  1070. return;
  1071. }
  1072. for ( int i = 0; i < editEntity->curve->GetNumValues(); i++ ) {
  1073. if ( PointInMoveList( editEntity->curve->GetValueAddress( i ) ) >= 0 ) {
  1074. if ( i == editEntity->curve->GetNumValues() - 1 ) {
  1075. // just do an add
  1076. AddCurvePoints();
  1077. } else {
  1078. idCurve<idVec3> *newCurve = Entity_MakeCurve( editEntity );
  1079. if ( newCurve == NULL ) {
  1080. return;
  1081. }
  1082. for ( int j = 0; j < editEntity->curve->GetNumValues(); j++ ) {
  1083. if ( j == i ) {
  1084. idVec3 start;
  1085. idVec3 end;
  1086. if ( i > 0 ) {
  1087. start = editEntity->curve->GetValue( i - 1 );
  1088. end = editEntity->curve->GetValue( i );
  1089. start += end;
  1090. start *= 0.5f;
  1091. } else {
  1092. start = editEntity->curve->GetValue( 0 );
  1093. if ( editEntity->curve->GetNumValues() > 1 ) {
  1094. end = start;
  1095. start = editEntity->curve->GetValue ( 1 );
  1096. idVec3 dir = end - start;
  1097. dir.Normalize();
  1098. start = end + 64 * dir;
  1099. } else {
  1100. end = start;
  1101. end.x += 64;
  1102. end.y += 64;
  1103. }
  1104. }
  1105. newCurve->AddValue( newCurve->GetNumValues() * 100, start );
  1106. }
  1107. newCurve->AddValue( newCurve->GetNumValues() * 100, editEntity->curve->GetValue( j ) );
  1108. }
  1109. delete editEntity->curve;
  1110. editEntity->curve = newCurve;
  1111. }
  1112. g_qeglobals.d_num_move_points = 0;
  1113. break;
  1114. }
  1115. }
  1116. UpdateEntityCurve();
  1117. Sys_UpdateWindows( W_XY | W_CAMERA );
  1118. }
  1119. void CEntityDlg::DeleteCurvePoint() {
  1120. if ( editEntity == NULL || editEntity->curve == NULL ) {
  1121. return;
  1122. }
  1123. if ( g_qeglobals.d_select_mode != sel_editpoint ) {
  1124. return;
  1125. }
  1126. if ( g_qeglobals.d_num_move_points == 0 ) {
  1127. return;
  1128. }
  1129. for ( int i = 0; i < editEntity->curve->GetNumValues(); i++ ) {
  1130. if ( PointInMoveList( editEntity->curve->GetValueAddress( i ) ) >= 0 ) {
  1131. editEntity->curve->RemoveIndex( i );
  1132. g_qeglobals.d_num_move_points = 0;
  1133. break;
  1134. }
  1135. }
  1136. UpdateEntityCurve();
  1137. Sys_UpdateWindows( W_XY | W_CAMERA );
  1138. }
  1139. void CEntityDlg::UpdateEntityCurve() {
  1140. if ( editEntity == NULL ) {
  1141. return;
  1142. }
  1143. Entity_UpdateCurveData( editEntity );
  1144. if ( g_qeglobals.d_select_mode == sel_editpoint ) {
  1145. g_qeglobals.d_numpoints = 0;
  1146. int c = editEntity->curve->GetNumValues();
  1147. for ( int i = 0; i < c; i++ ) {
  1148. if ( g_qeglobals.d_numpoints < MAX_POINTS - 1 ) {
  1149. g_qeglobals.d_points[g_qeglobals.d_numpoints++] = editEntity->curve->GetValue( i );
  1150. }
  1151. }
  1152. }
  1153. Sys_UpdateWindows( W_ENTITY );
  1154. }
  1155. void CEntityDlg::SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) {
  1156. int i, besti;
  1157. float d, bestd;
  1158. idVec3 temp;
  1159. if ( editEntity == NULL ) {
  1160. return;
  1161. }
  1162. // find the point closest to the ray
  1163. float scale = g_pParentWnd->ActiveXY()->Scale();
  1164. besti = -1;
  1165. bestd = 8 / scale / 2;
  1166. //bestd = 8;
  1167. for (i = 0; i < g_qeglobals.d_numpoints; i++) {
  1168. temp = g_qeglobals.d_points[i] - org;
  1169. d = temp * dir;
  1170. temp = org + d * dir;
  1171. temp = g_qeglobals.d_points[i] - temp;
  1172. d = temp.Length();
  1173. if ( d <= bestd ) {
  1174. bestd = d;
  1175. besti = i;
  1176. }
  1177. }
  1178. if (besti == -1) {
  1179. return;
  1180. }
  1181. g_qeglobals.d_num_move_points = 0;
  1182. assert ( besti < editEntity->curve->GetNumValues() );
  1183. g_qeglobals.d_move_points[ g_qeglobals.d_num_move_points++ ] = editEntity->curve->GetValueAddress( besti );
  1184. }