Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
mapobjectprops.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program 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**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19// mapobjectprops.cpp : implementation file
20//
21
22#include "stdafx.h"
23#include "worldbuilder.h"
24#include "WorldBuilderDoc.h"
25#include "wbview.h"
26#include "mapobjectprops.h"
27#include "propedit.h"
28#include "cundoable.h"
29#include "EditParameter.h"
30
35
38
39const char* NEUTRAL_TEAM_UI_STR = "(neutral)";
40const char* NEUTRAL_TEAM_INTERNAL_STR = "team";
41
42#ifdef _INTERNAL
43// for occasional debugging...
44//#pragma optimize("", off)
45//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
46#endif
47
48
50// MapObjectProps dialog
51
53
55{
56 DEBUG_ASSERTCRASH(TheMapObjectProps == NULL, ("already have a main props"));
58 TheMapObjectProps = this;
59}
60
61
62MapObjectProps::MapObjectProps(Dict* dictToEdit, const char* title, CWnd* pParent /*=NULL*/) :
64 m_dictToEdit(dictToEdit),
65 m_title(title),
68 m_scale( 1.0f ),
69 m_height( 0 ),
71 m_angle( 0 ),
74{
75
76
77 //{{AFX_DATA_INIT(MapObjectProps)
78 // NOTE: the ClassWizard will add member initialization here
79 //}}AFX_DATA_INIT
80}
81
83{
84 if (TheMapObjectProps == this)
86
87 if ( m_posUndoable != NULL )
88 {
90 }
91
92 if ( m_hWnd )
93 DestroyWindow();
94}
95
96void MapObjectProps::DoDataExchange(CDataExchange* pDX)
97{
98 CDialog::DoDataExchange(pDX);
99 //{{AFX_DATA_MAP(MapObjectProps)
100 // NOTE: the ClassWizard will add DDX and DDV calls here
101 //}}AFX_DATA_MAP
102}
103
104
105BEGIN_MESSAGE_MAP(MapObjectProps, CDialog)
106 //{{AFX_MSG_MAP(MapObjectProps)
107 ON_BN_CLICKED(IDC_CUSTOMIZE_CHECKBOX, customizeToDict)
108 ON_BN_CLICKED(IDC_EDITPROP, OnEditprop)
109 ON_BN_CLICKED(IDC_ENABLED_CHECKBOX, enabledToDict)
110 ON_BN_CLICKED(IDC_LOOPING_CHECKBOX, loopingToDict)
111 ON_BN_CLICKED(IDC_MAPOBJECT_Enabled, _EnabledToDict)
112 ON_BN_CLICKED(IDC_MAPOBJECT_Indestructible, _IndestructibleToDict)
113 ON_BN_CLICKED(IDC_MAPOBJECT_Powered, _PoweredToDict)
114 ON_BN_CLICKED(IDC_MAPOBJECT_RecruitableAI, _RecruitableAIToDict)
115 ON_BN_CLICKED(IDC_MAPOBJECT_Selectable, _SelectableToDict)
116 ON_BN_CLICKED(IDC_MAPOBJECT_Targetable, _TargetableToDict)
117 ON_BN_CLICKED(IDC_MAPOBJECT_Unsellable, _UnsellableToDict)
118 ON_BN_CLICKED(IDC_NEWPROP, OnNewprop)
119 ON_BN_CLICKED(IDC_REMOVEPROP, OnRemoveprop)
120 ON_BN_CLICKED(IDC_SCALE_OFF, OnScaleOff)
121 ON_BN_CLICKED(IDC_SCALE_ON, OnScaleOn)
122 ON_CBN_KILLFOCUS(IDC_MAPOBJECT_HitPoints, _HPsToDict)
123 ON_CBN_SELCHANGE(IDC_MAPOBJECT_Aggressiveness, _AggressivenessToDict)
124 ON_CBN_SELCHANGE(IDC_MAPOBJECT_Script, _ScriptToDict)
125 ON_CBN_SELCHANGE(IDC_MAPOBJECT_StartingHealth, _HealthToDict)
126 ON_CBN_SELCHANGE(IDC_MAPOBJECT_Team, _TeamToDict)
127 ON_CBN_SELCHANGE(IDC_MAPOBJECT_Time, _TimeToDict)
128 ON_CBN_SELCHANGE(IDC_MAPOBJECT_Veterancy, _VeterancyToDict)
129 ON_CBN_SELCHANGE(IDC_MAPOBJECT_Weather, _WeatherToDict)
130 ON_CBN_SELCHANGE(IDC_PRIORITY_COMBO, priorityToDict)
131 ON_CBN_SELCHANGE(IDC_SOUND_COMBO, attachedSoundToDict)
132 ON_CBN_SELENDOK(IDC_MAPOBJECT_HitPoints, _HPsToDict)
133 ON_EN_KILLFOCUS(IDC_LOOPCOUNT_EDIT, loopCountToDict)
134 ON_EN_KILLFOCUS(IDC_MAPOBJECT_Angle, SetAngle)
135 ON_EN_KILLFOCUS(IDC_MAPOBJECT_Name, _NameToDict)
136 ON_EN_KILLFOCUS(IDC_MAPOBJECT_Scale, _ScaleToDict)
137 ON_EN_KILLFOCUS(IDC_MAPOBJECT_ShroudClearingDistance, _ShroudClearingDistanceToDict)
138 ON_EN_KILLFOCUS(IDC_MAPOBJECT_StartingHealthEdit, _HealthToDict)
139 ON_EN_KILLFOCUS(IDC_MAPOBJECT_StoppingDistance, _StoppingDistanceToDict)
140 ON_EN_KILLFOCUS(IDC_MAPOBJECT_VisionDistance, _VisibilityToDict)
141 ON_EN_KILLFOCUS(IDC_MAPOBJECT_XYPosition, OnKillfocusMAPOBJECTXYPosition)
142 ON_EN_KILLFOCUS(IDC_MAPOBJECT_ZOffset, SetZOffset)
143 ON_EN_KILLFOCUS(IDC_MAX_RANGE_EDIT, maxRangeToDict)
144 ON_EN_KILLFOCUS(IDC_MIN_RANGE_EDIT, minRangeToDict)
145 ON_EN_KILLFOCUS(IDC_MIN_VOLUME_EDIT, minVolumeToDict)
146 ON_EN_KILLFOCUS(IDC_VOLUME_EDIT, volumeToDict)
147 ON_LBN_DBLCLK(IDC_PROPERTIES, OnDblclkProperties)
148 ON_LBN_SELCHANGE(IDC_MAPOBJECT_BuildWithUpgrades, _PrebuiltUpgradesToDict)
149 ON_LBN_SELCHANGE(IDC_PROPERTIES, OnSelchangeProperties)
150 //}}AFX_MSG_MAP
151END_MESSAGE_MAP()
152
153
154static AsciiString getNthKeyStr(const Dict* d, int i)
155{
156 NameKeyType k = d->getNthKey(i);
157 AsciiString kstr = TheNameKeyGenerator->keyToName(k);
158 return kstr;
159}
160
161static AsciiString getNthValueStr(const Dict* d, int i, Bool* enquote)
162{
163 *enquote = false;
164 AsciiString vstr;
165 switch(d->getNthType(i))
166 {
167 case Dict::DICT_BOOL:
168 vstr.format("%s", d->getNthBool(i) ? "true" : "false");
169 break;
170 case Dict::DICT_INT:
171 vstr.format("%d", d->getNthInt(i), d->getNthInt(i));
172 break;
173 case Dict::DICT_REAL:
174 vstr.format("%f", d->getNthReal(i));
175 break;
177 vstr.format("%s", d->getNthAsciiString(i).str());
178 *enquote = true;
179 break;
181 vstr.format("%ls", d->getNthUnicodeString(i).str());
182 *enquote = true;
183 break;
184 }
185 return vstr;
186}
187
189{
190// CListBox *list = (CListBox*)GetDlgItem(IDC_PROPERTIES);
191// int sel = list->GetCurSel();
192// if (!m_dictToEdit || sel == LB_ERR || sel < 0 || sel >= m_dictToEdit->getPairCount())
193 return -1;
194// return sel;
195}
196
199{
200 int i;
201
202 AsciiString name;
203 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Team);
204 owner->ResetContent();
205 for (i = 0; i < TheSidesList->getNumTeams(); i++)
206 {
207 name = TheSidesList->getTeamInfo(i)->getDict()->getAsciiString(TheKey_teamName);
208 if (name == NEUTRAL_TEAM_INTERNAL_STR)
209 name = NEUTRAL_TEAM_UI_STR;
210 owner->AddString(name.str());
211 }
212 // re-find, since the list is sorted
213 i = -1;
214 if (m_dictToEdit)
215 {
216 name = m_dictToEdit->getAsciiString(TheKey_originalOwner);
217 if (name == NEUTRAL_TEAM_INTERNAL_STR)
218 name = NEUTRAL_TEAM_UI_STR;
219 i = owner->FindStringExact(-1, name.str());
220 DEBUG_ASSERTLOG(i >= 0, ("missing team '%s'. Non-fatal (jkmcd)\n", name.str()));
221
222 }
223 owner->SetCurSel(i);
224}
225
228{
229 AsciiString name = "";
230 Bool exists;
231 if (m_dictToEdit)
232 {
233 name = m_dictToEdit->getAsciiString(TheKey_objectName, &exists);
234 }
235
236 CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_Name);
237 if (pItem)
238 {
239 pItem->SetWindowText(name.str());
240 }
241}
242
245{
246 if (!m_dictToEdit)
247 {
248 return;
249 }
250
251 Bool exists;
252 CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Script);
253 // Load the subroutine scripts into the combo box.
254 EditParameter::loadScripts(pCombo, true);
255 /*Int stringNdx =*/ pCombo->AddString("<none>");
256 AsciiString script = m_dictToEdit->getAsciiString(TheKey_objectScriptAttachment, &exists);
257
258 if (script.isEmpty()) {
259 pCombo->SelectString(-1, "<none>");
260 } else {
261 pCombo->SelectString(-1, script.str());
262 }
263}
264
267{
269
270 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Team);
271 static char buf[1024];
272 owner->GetWindowText(buf, sizeof(buf)-2);
273 if (strcmp(buf, NEUTRAL_TEAM_UI_STR)==0)
274 strcpy(buf, NEUTRAL_TEAM_INTERNAL_STR);
275
277 if ( pDoc )
278 {
279 Dict newDict;
280 newDict.setAsciiString(TheKey_originalOwner, AsciiString(buf));
281 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
282 pDoc->AddAndDoUndoable(pUndo);
283 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
284 // Update is called by Do
285 }
286}
287
290{
292
293 CWnd *owner = GetDlgItem(IDC_MAPOBJECT_Name);
294 CString cstr;
295 owner->GetWindowText(cstr);
296
297 // Note: when starting up, this is called before a document exists. Just ignore such
298 // calls, since there can't be an object to affect.
300 if ( pDoc )
301 {
302 Dict newDict;
303 newDict.setAsciiString(TheKey_objectName, cstr.GetBuffer(0));
304 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
305 pDoc->AddAndDoUndoable(pUndo);
306 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
307 // Update is called by Do
308 }
309}
310
313{
315
316 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Script);
317 static char buf[1024];
318 owner->GetWindowText(buf, sizeof(buf)-2);
319
321 if ( pDoc )
322 {
323 Dict newDict;
324 newDict.setAsciiString(TheKey_objectScriptAttachment, AsciiString(buf));
325 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
326 pDoc->AddAndDoUndoable(pUndo);
327 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
328 // Update is called by Do
329 }
330}
331
332
335{
336// Currently not in the Mission Disk.
337#if 0
338 m_scale = 1;
339 Bool exists;
340 if (m_dictToEdit) {
341 m_scale = m_dictToEdit->getReal(TheKey_objectPrototypeScale, &exists);
342 }
343 if (!exists) {
344 m_scale = 1;
345 }
346
347 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Scale);
348 CString cstr;
349 cstr.Format("%.2f", m_scale);
350 edit->SetWindowText(cstr);
351
352 CButton *off = (CButton*) GetDlgItem(IDC_SCALE_OFF);
353 CButton *on = (CButton*) GetDlgItem(IDC_SCALE_ON);
354 if (!exists) {
355 off->SetCheck(1);
356 on->SetCheck(0);
357 edit->EnableWindow(false);
358 GetDlgItem(IDC_SCALE_POPUP)->EnableWindow(false);
359 } else {
360 off->SetCheck(0);
361 on->SetCheck(1);
362 edit->EnableWindow(TRUE);
363 GetDlgItem(IDC_SCALE_POPUP)->EnableWindow(true);
364 }
365#endif
366
367}
368
371{
372 Int value = 0;
373 Bool exists;
374 if (m_dictToEdit) {
375 value = m_dictToEdit->getInt(TheKey_objectWeather, &exists);
376 if (!exists)
377 value = 0;
378 }
379
380 CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Weather);
381 pItem->SetCurSel(value);
382}
383
386{
387 Int value = 0;
388 Bool exists;
389 if (m_dictToEdit) {
390 value = m_dictToEdit->getInt(TheKey_objectTime, &exists);
391 if (!exists)
392 value = 0;
393 }
394
395 CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Time);
396 pItem->SetCurSel(value);
397}
398
401{
403
404 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Weather);
405 static char buf[1024];
406 int curSel = owner->GetCurSel();
407
409 if ( pDoc )
410 {
411 Dict newDict;
412 newDict.setInt(TheKey_objectWeather, curSel);
413 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
414 pDoc->AddAndDoUndoable(pUndo);
415 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
416 // Update is called by Do
417 }
418}
419
422{
424
425 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Time);
426 static char buf[1024];
427 int curSel = owner->GetCurSel();
428
430 if ( pDoc )
431 {
432 Dict newDict;
433 newDict.setInt(TheKey_objectTime, curSel);
434 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
435 pDoc->AddAndDoUndoable(pUndo);
436 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
437 // Update is called by Do
438 }
439}
440
443{
444// Currently not in mission disk.
445#if 0
447
448 Real value = 0.0f;
449 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Scale);
450 CString cstr;
451 edit->GetWindowText(cstr);
452 if (!cstr.IsEmpty()) {
453 value = atof(cstr);
454 }
455 m_scale = value;
456
457 CButton *off = (CButton*) GetDlgItem(IDC_SCALE_OFF);
458
460 if ( pDoc )
461 {
462 Dict newDict;
463 if (off->GetCheck() == 1) {
464 newDict.remove(TheKey_objectPrototypeScale);
465 } else {
466 newDict.setReal(TheKey_objectPrototypeScale, m_scale);
467 }
468 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
469 pDoc->AddAndDoUndoable(pUndo);
470 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
471 // Update is called by Do
472 }
473#endif
474}
475
478{
479 const Coord3D *loc = pMapObj->getLocation();
480 static char buff[12];
481 m_height = loc->z;
482 sprintf(buff, "%0.2f", loc->z);
483 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
484 edit->SetWindowText(buff);
485}
486
489{
490 Real value = 0.0f;
491 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
492 CString cstr;
493 edit->GetWindowText(cstr);
494 if (!cstr.IsEmpty()) {
495 value = atof(cstr);
496 }
497 m_height = value;
499 if ( pDoc )
500 {
502 pDoc->AddAndDoUndoable(pUndo);
503 pUndo->SetZOffset(value);
504 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
505 }
506}
507
510{
511 m_angle = pMapObj->getAngle() * 180 / PI;
512 static char buff[12];
513 sprintf(buff, "%0.2f", m_angle);
514 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Angle);
515 edit->SetWindowText(buff);
516 m_angle = atof(buff);
517}
518
521{
522 m_position = *pMapObj->getLocation();
523 static char buff[12];
524 sprintf(buff, "%0.2f, %0.2f", m_position.x, m_position.y);
525 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_XYPosition);
526 edit->SetWindowText(buff);
527 sscanf(buff, "%f,%f", &m_position.x, &m_position.y);
528}
529
532{
533 Real angle = m_angle;
534 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Angle);
535 CString cstr;
536 edit->GetWindowText(cstr);
537 if (!cstr.IsEmpty()) {
538 angle = atof(cstr);
539 }
540 if (m_selectedObject==NULL) return;
541 if (m_angle!=angle)
542 {
543 m_angle = angle;
545 if ( pDoc )
546 {
548 pDoc->AddAndDoUndoable(pUndo);
549 pUndo->RotateTo(angle * PI/180);
550 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
551 }
552 }
553}
554
557{
558 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_XYPosition);
559 CString cstr;
560 edit->GetWindowText(cstr);
561 Coord3D loc;
562 loc = m_position;
563 if (m_selectedObject==NULL) return;
564 if (!cstr.IsEmpty()) {
565 if (sscanf(cstr, "%f, %f", &loc.x, &loc.y)!=2)
566 loc = m_position;
567 }
568 if (loc.x!=m_position.x || loc.y != m_position.y) {
569 m_position = loc;
571 if ( pDoc )
572 {
574 pDoc->AddAndDoUndoable(pUndo);
575 if (m_selectedObject) {
576 loc = *m_selectedObject->getLocation();
577 }
578 pUndo->SetOffset(m_position.x-loc.x, m_position.y-loc.y);
579 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
580 }
581 }
582}
583
585void MapObjectProps::GetPopSliderInfo(const long sliderID, long *pMin, long *pMax, long *pLineSize, long *pInitial)
586{
587 switch (sliderID) {
588
589 case IDC_HEIGHT_POPUP:
590 *pMin = -50;
591 *pMax = 50;
592 *pInitial = m_height;
593 *pLineSize = 1;
594 break;
595
596 case IDC_ANGLE_POPUP:
597 *pMin = 0;
598 *pMax = 360;
599 *pInitial = m_angle;
600 *pLineSize = 1;
601 break;
602
603 case IDC_SCALE_POPUP:
604 *pMin = 1;
605 *pMax = 500;
606 *pInitial = m_scale*100;
607 *pLineSize = 1;
608 break;
609
610 default:
611 // uh-oh!
612 DEBUG_CRASH(("Slider message from unknown control"));
613 break;
614 } // switch
615}
616
618void MapObjectProps::PopSliderChanged(const long sliderID, long theVal)
619{
621 if ( pDoc == NULL )
622 return;
623
624 CWnd* edit;
625 static char buff[36];
626 switch (sliderID) {
627 case IDC_HEIGHT_POPUP:
628 if (!m_posUndoable) {
631 }
632 m_posUndoable->SetZOffset(theVal);
633 m_height = theVal;
634 sprintf(buff, "%0.2f", m_height);
635 edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
636 edit->SetWindowText(buff);
637 break;
638
639 case IDC_ANGLE_POPUP:
640 if (!m_posUndoable) {
643 }
644 m_posUndoable->RotateTo(theVal * PI/180);
645 m_angle = theVal;
646 sprintf(buff, "%0.2f", m_angle);
647 edit = GetDlgItem(IDC_MAPOBJECT_Angle);
648 edit->SetWindowText(buff);
649 break;
650
651 case IDC_SCALE_POPUP:
652 m_scale = theVal/100.0f;
653 sprintf(buff, "%0.2f", m_scale);
654 edit = GetDlgItem(IDC_MAPOBJECT_Scale);
655 edit->SetWindowText(buff);
656 break;
657
658 default:
659 // uh-oh!
660 DEBUG_CRASH(("Slider message from unknown control"));
661 break;
662 } // switch
663}
664
666void MapObjectProps::PopSliderFinished(const long sliderID, long theVal)
667{
668 switch (sliderID) {
669 case IDC_HEIGHT_POPUP:
670 case IDC_ANGLE_POPUP:
671 if ( m_posUndoable != NULL )
672 {
673 REF_PTR_RELEASE(m_posUndoable); // belongs to pDoc now.
674 }
676 break;
677
678 case IDC_SCALE_POPUP:
679 _ScaleToDict();
680 break;
681
682 default:
683 // uh-oh!
684 DEBUG_CRASH(("Slider message from unknown control"));
685 break;
686 } // switch
687
688}
689
692{
694
695 CListBox *pBox = (CListBox *) GetDlgItem(IDC_MAPOBJECT_BuildWithUpgrades);
696 if (!pBox) {
697 return;
698 }
699
700 // We only work for single selections
701 if (m_allSelectedDicts.size() != 1) {
702 return;
703 }
704
705 if (m_selectedObject) {
706 if ( !m_selectedObject->getThingTemplate() ) {
707 return;
708 }
709 }
710
711 Bool exists;
712 int upgradeNum = 0;
713 AsciiString upgradeString;
714
715 // We're going to sub this entire dict for the existing entire dict.
716 Dict newDict = *m_allSelectedDicts[0];
717
718 // First, clear out any existing notions of what we should upgrade.
719 do {
720 AsciiString keyName;
721 keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
722 upgradeString = newDict.getAsciiString(NAMEKEY(keyName), &exists);
723
724 if (exists) {
725 newDict.remove(NAMEKEY(keyName));
726 }
727
728 ++upgradeNum;
729 } while (!upgradeString.isEmpty());
730
731 upgradeNum = 0;
732 // We've now removed them, so lets add the ones that are selected now.
733 Int countOfItems = pBox->GetCount();
734 for (Int i = 0; i < countOfItems; ++i) {
735 if (pBox->GetSel(i) > 0) {
736 CString selTxt;
737 // This thing is selected. Get its text, and add it to the dict.
738 pBox->GetText(i, selTxt);
739
740 AsciiString keyName;
741 keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
742 newDict.setAsciiString(NAMEKEY(keyName), AsciiString(selTxt.GetBuffer(0)));
743 ++upgradeNum;
744 }
745 }
746
747 // Now, do the Undoable
749 if ( pDoc != NULL )
750 {
751 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, NAMEKEY_INVALID, m_allSelectedDicts.size(), pDoc, true);
752 pDoc->AddAndDoUndoable(pUndo);
753 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
754 }
755}
756
759{
761
762 CListBox *pBox = (CListBox*) GetDlgItem(IDC_MAPOBJECT_BuildWithUpgrades);
763 if (!pBox) {
764 return;
765 }
766
767 // First, clear out the list
768 pBox->ResetContent();
769 CString cstr;
770
771 // Then, if there's multiple units selected, add the Single Selection Only string
772 if (m_allSelectedDicts.size() > 1) {
773 cstr.LoadString(IDS_SINGLE_SELECTION_ONLY);
774 pBox->AddString(cstr);
775 return;
776 }
777
778 if (m_selectedObject == NULL) {
779 return;
780 }
781
782 // Otherwise, fill it with the upgrades available for this unit
783 const ThingTemplate *tt = m_selectedObject->getThingTemplate();
784 if (tt == NULL) {
785 // This is valid. For instance, Scorch marks do not have thing templates.
786 return;
787 }
788
789 Bool noUpgrades = false;
790
791 // Now do any behaviors that are also upgrades.
792 const ModuleInfo& mi = tt->getBehaviorModuleInfo();
793 if (mi.getCount() == 0) {
794 if (noUpgrades) {
795 cstr.LoadString(IDS_NO_UPGRADES);
796 pBox->AddString(cstr);
797 return;
798 }
799 } else {
800 Int numBehaviorModules = mi.getCount();
801
802 Int numBehaviorsWithUpgrades = 0;
803
804 for (int i = 0; i < numBehaviorModules; ++i) {
805 if (mi.getNthName(i).compareNoCase("GenerateMinefieldBehavior") == 0) {
807 if (!gmbmd) {
808 continue;
809 }
810 if (gmbmd->m_upgradeMuxData.m_activationUpgradeNames.size() > 0) {
811 cstr = gmbmd->m_upgradeMuxData.m_activationUpgradeNames[0].str();
812 if (pBox->FindString(-1, cstr) == LB_ERR) {
813 pBox->AddString(cstr);
814 ++numBehaviorsWithUpgrades;
815 }
816 }
817 }
818 }
819
820 if (numBehaviorsWithUpgrades == 0) {
821 if (noUpgrades) {
822 cstr.LoadString(IDS_NO_UPGRADES);
823 pBox->AddString(cstr);
824 return;
825 }
826 }
827 }
828
829 // Finally, walk through the upgrades that he already has, and select the appropriate members
830 // from the list
831
832 Bool exists;
833 int upgradeNum = 0;
834 AsciiString upgradeString;
835
836 do {
837 AsciiString keyName;
838 keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
839 upgradeString = m_dictToEdit->getAsciiString(NAMEKEY(keyName), &exists);
840
841 if (exists) {
842 Int selNdx = pBox->FindStringExact(-1, upgradeString.str());
843 if (selNdx == LB_ERR) {
844 DEBUG_CRASH(("Object claims '%s', but it wasn't found in the list of possible upgrades.", upgradeString.str()));
845 ++upgradeNum;
846 continue;
847 }
848 pBox->SetSel(selNdx);
849
850 } else {
851 upgradeString.clear();
852 }
853
854 ++upgradeNum;
855 } while (!upgradeString.isEmpty());
856}
857
860{
861 Int value = 100;
862 Bool exists;
863 if (m_dictToEdit) {
864 value = m_dictToEdit->getInt(TheKey_objectInitialHealth, &exists);
865 }
866
867 CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_StartingHealth);
868 CWnd* pItem2 = GetDlgItem(IDC_MAPOBJECT_StartingHealthEdit);
869 if (pItem && pItem2) {
870 if (value == 0) {
871 pItem->SelectString(-1, "0%");
872 pItem2->SetWindowText("");
873 pItem2->EnableWindow(FALSE);
874 } else if (value == 25) {
875 pItem->SelectString(-1, "25%");
876 pItem2->SetWindowText("");
877 pItem2->EnableWindow(FALSE);
878 } else if (value == 50) {
879 pItem->SelectString(-1, "50%");
880 pItem2->SetWindowText("");
881 pItem2->EnableWindow(FALSE);
882 } else if (value == 75) {
883 pItem->SelectString(-1, "75%");
884 pItem2->SetWindowText("");
885 pItem2->EnableWindow(FALSE);
886 } else if (value == 100) {
887 pItem->SelectString(-1, "100%");
888 pItem2->SetWindowText("");
889 pItem2->EnableWindow(FALSE);
890 } else {
891 pItem->SelectString(-1, "Other");
892 static char buff[12];
893 sprintf(buff, "%d", value);
894 pItem2->SetWindowText(buff);
895 pItem2->EnableWindow(TRUE);
896 }
897 }
898}
899
900
903{
904 Int value = -1;
905 Bool exists;
906 if (m_dictToEdit) {
907 value = m_dictToEdit->getInt(TheKey_objectMaxHPs, &exists);
908 if (!exists)
909 value = -1;
910 }
911
912 CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_HitPoints);
913 pItem->ResetContent();
914 CString str;
915 str.Format("Default For Unit");
916 pItem->InsertString(-1, str);
917
918 if (value != -1) {
919 str.Format("%d", value);
920 pItem->InsertString(-1, str);
921 pItem->SetCurSel(1);
922 } else {
923 pItem->SetCurSel(0);
924 }
925}
926
929{
930 Bool enabled = true;
931 Bool exists;
932 if (m_dictToEdit) {
933 enabled = m_dictToEdit->getBool(TheKey_objectEnabled, &exists);
934 }
935
936 CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Enabled);
937 if (pItem) {
938 pItem->SetCheck(enabled);
939 }
940}
941
942
945{
946 Bool destructible = true;
947 Bool exists;
948 if (m_dictToEdit) {
949 destructible = m_dictToEdit->getBool(TheKey_objectIndestructible, &exists);
950 }
951
952 CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Indestructible);
953 if (pItem) {
954 pItem->SetCheck(destructible);
955 }
956}
957
960{
961 Bool unsellable = false;
962 Bool exists;
963 if (m_dictToEdit) {
964 unsellable = m_dictToEdit->getBool(TheKey_objectUnsellable, &exists);
965 }
966
967 CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Unsellable);
968 if (pItem) {
969 pItem->SetCheck(unsellable);
970 }
971}
972
975{
976 Bool targetable = false;
977 Bool exists;
978 if( m_dictToEdit )
979 {
980 targetable = m_dictToEdit->getBool( TheKey_objectTargetable, &exists );
981 }
982
983 CButton* pItem = (CButton*) GetDlgItem( IDC_MAPOBJECT_Targetable );
984 if( pItem )
985 {
986 pItem->SetCheck( targetable );
987 }
988}
989
992{
993 Bool powered = true;
994 Bool exists;
995 if (m_dictToEdit) {
996 powered = m_dictToEdit->getBool(TheKey_objectPowered, &exists);
997 }
998
999 CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Powered);
1000 if (pItem) {
1001 pItem->SetCheck(powered);
1002 }
1003
1004}
1005
1008{
1009 Int value = 0;
1010 Bool exists;
1011 if (m_dictToEdit) {
1012 value = m_dictToEdit->getInt(TheKey_objectAggressiveness, &exists);
1013 }
1014
1015 CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Aggressiveness);
1016 if (pItem) {
1017 if (value == -2) {
1018 pItem->SelectString(-1, "Sleep");
1019 } else if (value == -1) {
1020 pItem->SelectString(-1, "Passive");
1021 } else if (value == 0) {
1022 pItem->SelectString(-1, "Normal");
1023 } else if (value == 1) {
1024 pItem->SelectString(-1, "Alert");
1025 } else if (value == 2) {
1026 pItem->SelectString(-1, "Aggressive");
1027 }
1028 }
1029}
1030
1033{
1034 Int distance = 0;
1035 Bool exists;
1036 if (m_dictToEdit) {
1037 distance = m_dictToEdit->getInt(TheKey_objectVisualRange, &exists);
1038 }
1039
1040 CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_VisionDistance);
1041 if (pItem) {
1042 static char buff[12];
1043 sprintf(buff, "%d", distance);
1044 if (distance == 0) {
1045 pItem->SetWindowText("");
1046 } else {
1047 pItem->SetWindowText(buff);
1048 }
1049 }
1050}
1051
1054{
1055 Int value = 0;
1056 Bool exists;
1057 if (m_dictToEdit) {
1058 value = m_dictToEdit->getInt(TheKey_objectVeterancy, &exists);
1059 }
1060
1061 CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Veterancy);
1062 if (pItem) {
1063 pItem->SetCurSel(value);
1064 }
1065}
1066
1069{
1070 Int distance = 0;
1071 Bool exists;
1072 if (m_dictToEdit) {
1073 distance = m_dictToEdit->getInt(TheKey_objectShroudClearingDistance, &exists);
1074 }
1075
1076 CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_ShroudClearingDistance);
1077 if (pItem) {
1078 static char buff[12];
1079 sprintf(buff, "%d", distance);
1080 if (distance == 0) {
1081 pItem->SetWindowText("");
1082 } else {
1083 pItem->SetWindowText(buff);
1084 }
1085 }
1086}
1087
1090{
1091 Bool recruitableAI = true;
1092 Bool exists;
1093 if (m_dictToEdit) {
1094 recruitableAI = m_dictToEdit->getBool(TheKey_objectRecruitableAI, &exists);
1095 }
1096
1097 CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
1098 if (pItem) {
1099 pItem->SetCheck(recruitableAI);
1100 }
1101}
1102
1105{
1106 Int selectable = true;
1107 Bool exists=false;
1108 if (m_dictToEdit) {
1109 selectable = m_dictToEdit->getBool(TheKey_objectSelectable, &exists);
1110 }
1111 if (!exists) {
1112 selectable = 2;
1113 }
1114
1115 CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
1116 if (pItem) {
1117 pItem->SetCheck(selectable);
1118 }
1119}
1120
1123{
1124 Real stoppingDistance = 1.0f;
1125 Bool exists = false;
1126 if (m_dictToEdit) {
1127 stoppingDistance = m_dictToEdit->getReal(TheKey_objectStoppingDistance, &exists);
1128 }
1129
1130 CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_StoppingDistance);
1131 if (pItem) {
1132 static char buff[12];
1133 sprintf(buff, "%g", stoppingDistance);
1134 pItem->SetWindowText(buff);
1135 }
1136}
1137
1138
1141{
1143
1144 Int value;
1145 static char buf[1024];
1146
1147 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_StartingHealth);
1148 owner->GetWindowText(buf, sizeof(buf)-2);
1149 if (strcmp(buf, "Dead") == 0) {
1150 value = 0;
1151 } else if (strcmp(buf, "25%") == 0) {
1152 value = 25;
1153 } else if (strcmp(buf, "50%") == 0) {
1154 value = 50;
1155 } else if (strcmp(buf, "75%") == 0) {
1156 value = 75;
1157 } else if (strcmp(buf, "100%") == 0) {
1158 value = 100;
1159 } else if (strcmp(buf, "Other") == 0) {
1160 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_StartingHealthEdit);
1161 edit->EnableWindow(TRUE);
1162 CString cstr;
1163 edit->GetWindowText(cstr);
1164 if (cstr.IsEmpty()) {
1165 return;
1166 }
1167 value = atoi(cstr.GetBuffer(0));
1168 }
1170 if ( pDoc != NULL )
1171 {
1172 Dict newDict;
1173 newDict.setInt(TheKey_objectInitialHealth, value);
1174 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1175 pDoc->AddAndDoUndoable(pUndo);
1176 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1177 // Update is called by Do
1178 }
1179}
1180
1181
1184{
1186
1187 CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Enabled);
1188 Bool isChecked = (owner->GetCheck() != 0);
1189
1191 if ( pDoc != NULL )
1192 {
1193 Dict newDict;
1194 newDict.setBool(TheKey_objectEnabled, isChecked);
1195 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1196 pDoc->AddAndDoUndoable(pUndo);
1197 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1198 // Update is called by Do
1199 }
1200}
1201
1204{
1206
1207 CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Indestructible);
1208 Bool isChecked = (owner->GetCheck() != 0);
1209
1211 if ( pDoc != NULL )
1212 {
1213 Dict newDict;
1214 newDict.setBool(TheKey_objectIndestructible, isChecked);
1215 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1216 pDoc->AddAndDoUndoable(pUndo);
1217 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1218 // Update is called by Do
1219 }
1220}
1221
1224{
1226
1227 CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Unsellable);
1228 Bool isChecked = (owner->GetCheck() != 0);
1229
1231 if ( pDoc != NULL )
1232 {
1233 Dict newDict;
1234 newDict.setBool(TheKey_objectUnsellable, isChecked);
1235 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1236 pDoc->AddAndDoUndoable(pUndo);
1237 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1238 // Update is called by Do
1239 }
1240}
1241
1244{
1246
1247 CButton *owner = (CButton*)GetDlgItem( IDC_MAPOBJECT_Targetable );
1248 Bool isChecked = owner->GetCheck() != 0;
1249
1251 if ( pDoc != NULL )
1252 {
1253 Dict newDict;
1254 newDict.setBool( TheKey_objectTargetable, isChecked );
1255 DictItemUndoable *pUndo = new DictItemUndoable( m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size() );
1256 pDoc->AddAndDoUndoable( pUndo );
1257 REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
1258 // Update is called by Do
1259 }
1260}
1261
1262
1265{
1267
1268 CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Powered);
1269 Bool isChecked = (owner->GetCheck() != 0);
1270
1272 if ( pDoc != NULL )
1273 {
1274 Dict newDict;
1275 newDict.setBool(TheKey_objectPowered, isChecked);
1276 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1277 pDoc->AddAndDoUndoable(pUndo);
1278 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1279 // Update is called by Do
1280 }
1281}
1282
1285{
1287
1288 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Aggressiveness);
1289 static char buf[1024];
1290 owner->GetWindowText(buf, sizeof(buf)-2);
1291 int value = 0;
1292
1293 if (strcmp(buf, "Sleep") == 0) {
1294 value = -2;
1295 } else if (strcmp(buf, "Passive") == 0) {
1296 value = -1;
1297 } else if (strcmp(buf, "Normal") == 0) {
1298 value = 0;
1299 } else if (strcmp(buf, "Alert") == 0) {
1300 value = 1;
1301 } else if (strcmp(buf, "Aggressive") == 0) {
1302 value = 2;
1303 }
1304
1306 if ( pDoc != NULL )
1307 {
1308 Dict newDict;
1309 newDict.setInt(TheKey_objectAggressiveness, value);
1310 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1311 pDoc->AddAndDoUndoable(pUndo);
1312 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1313 // Update is called by Do
1314 }
1315}
1316
1319{
1321
1322 int value = -1;
1323 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_VisionDistance);
1324 edit->EnableWindow(TRUE);
1325 CString cstr;
1326 edit->GetWindowText(cstr);
1327 if (!cstr.IsEmpty()) {
1328 value = atoi(cstr.GetBuffer(0));
1329 }
1330
1332 if ( pDoc != NULL )
1333 {
1334 Dict newDict;
1335 if (value != -1) {
1336 newDict.setInt(TheKey_objectVisualRange, value);
1337 }
1338 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, TheKey_objectVisualRange, m_allSelectedDicts.size());
1339 pDoc->AddAndDoUndoable(pUndo);
1340 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1341 // Update is called by Do
1342 }
1343}
1344
1347{
1349
1350 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Veterancy);
1351 static char buf[1024];
1352 int curSel = owner->GetCurSel();
1353 int value = 0;
1354 if (curSel >= 0) {
1355 value=curSel;
1356 }
1357
1359 if ( pDoc != NULL )
1360 {
1361 Dict newDict;
1362 newDict.setInt(TheKey_objectVeterancy, value);
1363 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1364 pDoc->AddAndDoUndoable(pUndo);
1365 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1366 // Update is called by Do
1367 }
1368}
1369
1372{
1374
1375 int value = -1;
1376 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ShroudClearingDistance);
1377 edit->EnableWindow(TRUE);
1378 CString cstr;
1379 edit->GetWindowText(cstr);
1380 if (!cstr.IsEmpty()) {
1381 value = atoi(cstr.GetBuffer(0));
1382 }
1383
1385 if ( pDoc != NULL )
1386 {
1387 Dict newDict;
1388 if (value != -1) {
1389 newDict.setInt(TheKey_objectShroudClearingDistance, value);
1390 }
1391 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, TheKey_objectShroudClearingDistance, m_allSelectedDicts.size());
1392 pDoc->AddAndDoUndoable(pUndo);
1393 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1394 // Update is called by Do
1395 }
1396}
1397
1400{
1402
1403 CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
1404 Bool isChecked = (owner->GetCheck() != 0);
1405
1407 if ( pDoc != NULL )
1408 {
1409 Dict newDict;
1410 newDict.setBool(TheKey_objectRecruitableAI, isChecked);
1411 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1412 pDoc->AddAndDoUndoable(pUndo);
1413 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1414 // Update is called by Do
1415 }
1416}
1417
1420{
1422
1423 CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
1424 Bool isChecked = (owner->GetCheck() == 1);
1425 Bool isTristate = (owner->GetCheck() == 2);
1426
1428 if ( pDoc != NULL )
1429 {
1430 Dict newDict;
1431 if (isTristate) {
1432 newDict.remove(TheKey_objectSelectable);
1433 } else {
1434 newDict.setBool(TheKey_objectSelectable, isChecked);
1435 }
1436 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1437 pDoc->AddAndDoUndoable(pUndo);
1438 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1439 // Update is called by Do
1440 }
1441}
1442
1445{
1447
1448 Int value;
1449 static char buf[1024];
1450
1451 CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_HitPoints);
1452 owner->GetWindowText(buf, sizeof(buf)-2);
1453 value = atoi(buf);
1454 if (value == 0)
1455 value = -1;
1456
1458 if ( pDoc != NULL )
1459 {
1460 Dict newDict;
1461
1462 newDict.setInt(TheKey_objectMaxHPs, value);
1463 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
1464 pDoc->AddAndDoUndoable(pUndo);
1465 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1466 }
1467}
1468
1471{
1473
1474 Real value;
1475 static char buf[1024];
1476
1477 CWnd* edit = GetDlgItem(IDC_MAPOBJECT_StoppingDistance);
1478 CString cstr;
1479 edit->GetWindowText(cstr);
1480 if (cstr.IsEmpty()) {
1481 return;
1482 }
1483 value = atof(cstr.GetBuffer(0));
1484
1486 if ( pDoc != NULL )
1487 {
1488 Dict newDict;
1489 newDict.setReal(TheKey_objectStoppingDistance, value);
1490 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1491 pDoc->AddAndDoUndoable(pUndo);
1492 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1493 // Update is called by Doc
1494 }
1495}
1496
1497
1499{
1500 int sel = getSel();
1501 if (sel == -1 || !m_dictToEdit)
1502 return;
1503
1504 Bool enquote;
1505 AsciiString kstr = getNthKeyStr(m_dictToEdit, sel);
1506 AsciiString vstr = getNthValueStr(m_dictToEdit, sel, &enquote);
1507 Dict::DataType type = m_dictToEdit->getNthType(sel);
1508
1509 PropEdit propDlg(&kstr, &type, &vstr, true, this);
1510 if (propDlg.DoModal() == IDOK)
1511 {
1512 Dict newDict = DictItemUndoable::buildSingleItemDict(kstr, type, vstr);
1513 if (this == TheMapObjectProps)
1514 {
1515 // it's the floating panel; use an undoable
1517 DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, newDict.getNthKey(0));
1518 pDoc->AddAndDoUndoable(pUndo);
1519 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1520 }
1521 else
1522 {
1523 // we're running modal; just slam it in the dict
1524 m_dictToEdit->copyPairFrom(newDict, newDict.getNthKey(0));
1525 }
1526 updateTheUI();
1527 }
1528}
1529
1531{
1532 if (!m_dictToEdit)
1533 return;
1534
1535 // TODO: Add your control notification handler code here
1536 static Dict::DataType lastNewType = Dict::DICT_BOOL;
1537 AsciiString key, value;
1538
1539 PropEdit propDlg(&key, &lastNewType, &value, false, this);
1540 if (propDlg.DoModal() == IDOK)
1541 {
1542 Dict newDict = DictItemUndoable::buildSingleItemDict(key, lastNewType, value);
1543 if (this == TheMapObjectProps)
1544 {
1545 // it's the floating panel; use an undoable
1547 DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, newDict.getNthKey(0));
1548 pDoc->AddAndDoUndoable(pUndo);
1549 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1550 }
1551 else
1552 {
1553 // we're running modal; just slam it in the dict
1554 m_dictToEdit->copyPairFrom(newDict, newDict.getNthKey(0));
1555 }
1556 updateTheUI();
1557 }
1558}
1559
1561{
1562 int sel = getSel();
1563 if (sel == -1)
1564 return;
1565
1566 NameKeyType k = m_dictToEdit->getNthKey(sel);
1567 if (this == TheMapObjectProps)
1568 {
1569 // it's the floating panel; use an undoable
1571 Dict newDict; // empty dict
1572 DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, k);
1573 pDoc->AddAndDoUndoable(pUndo);
1574 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1575 }
1576 else
1577 {
1578 // we're running modal; just slam it in the dict
1579 m_dictToEdit->remove(k);
1580 }
1581 updateTheUI();
1582}
1583
1588
1589
1590static const Char NO_SOUND_STRING[] = "(None)";
1591static const Char BASE_DEFAULT_STRING[] = "Default";
1592
1597
1600{
1601 CDialog::OnInitDialog();
1602
1603 if (m_title)
1604 SetWindowText(m_title);
1605
1606 m_heightSlider.SetupPopSliderButton(this, IDC_HEIGHT_POPUP, this);
1607 m_angleSlider.SetupPopSliderButton(this, IDC_ANGLE_POPUP, this);
1608 m_scaleSlider.SetupPopSliderButton(this, IDC_SCALE_POPUP, this);
1610 m_angle = 0;
1611 m_height = 0;
1612 m_scale = 1.0f;
1613
1614 InitSound();
1615 updateTheUI();
1616
1617 return TRUE;
1618}
1619
1620//---------------------------------------------------------------------------------------------------
1621/*static*/ void MapObjectProps::update(void)
1622{
1623 if (TheMapObjectProps)
1624 {
1625 TheMapObjectProps->updateTheUI();
1626 }
1627}
1628
1630{
1631 if (this != TheMapObjectProps) {
1632 return;
1633 }
1634 for (MapObject *pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
1635 if (!pMapObj->isSelected() || pMapObj->isWaypoint() || pMapObj->isLight()) {
1636 continue;
1637 }
1638
1639 m_dictSource = pMapObj;
1640 // Select correct dictionary
1641 m_dictToEdit = m_dictSource ? m_dictSource->getProperties() : NULL;
1642
1644
1645 // simply break after the first one that's selected
1646 break;
1647 }
1648}
1649
1652{
1653 _DictToName();
1654 _DictToTeam();
1655 _DictToScript();
1657 _DictToTime();
1658 _DictToScale();
1660 _DictToHealth();
1661 _DictToHPs();
1674 ShowZOffset(pMapObj);
1675 ShowAngle(pMapObj);
1676 ShowPosition(pMapObj);
1677
1678 // Warning: order is important. dictToAttachedSound() must come before dictToCustomize(),
1679 // dictToCustomize() must come before any of the customization controls, dictToLooping()
1680 // must come before dictToLoopCount(), and dictToLooping() and dictToLoopCount() must
1681 // come before dictToEnabled().
1684 dictToLooping();
1686 dictToEnabled();
1688 dictToVolume();
1692}
1693
1694//---------------------------------------------------------------------------------------------------
1695
1696void MapObjectProps::InitSound(void)
1697{
1698 CComboBox * priorityComboBox = (CComboBox *)GetDlgItem(IDC_PRIORITY_COMBO);
1699 DEBUG_ASSERTCRASH( priorityComboBox != NULL, ("Cannot find sound priority combobox" ) );
1700
1701 if ( priorityComboBox != NULL )
1702 {
1703 Int i;
1704 for ( i = 0; i <= AP_CRITICAL; i++ )
1705 {
1706 Int index = priorityComboBox->InsertString( i,theAudioPriorityNames[i] );
1707 DEBUG_ASSERTCRASH( index == i, ("insert string returned %d, expected %d", index, i ) );
1708 }
1709 }
1710
1711 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
1712 DEBUG_ASSERTCRASH( soundComboBox != NULL, ("Cannot find sound combobox" ) );
1714 m_defaultIsNone = true;
1715
1716 // Load up combobox
1717 if ( soundComboBox != NULL )
1718 {
1719 // Add all the sound names in order. Since the combobox has the SORTED style,
1720 // we can just add the strings in and let the combo box sort them
1721 const AudioEventInfoHash & audioEventHash = TheAudio->getAllAudioEvents();
1722
1723 AudioEventInfoHash::const_iterator it;
1724 for ( it = audioEventHash.begin(); it != audioEventHash.end(); it++ )
1725 {
1726 if ( it->second->m_soundType == AT_SoundEffect )
1727 {
1728 // Hmm, should we be filtering the list in any other way? Oh well.
1729 soundComboBox->AddString( it->second->m_audioName.str() );
1730 }
1731 }
1732
1733 m_defaultEntryIndex = soundComboBox->InsertString( 0, BASE_DEFAULT_STRING );
1734 m_defaultEntryName = NO_SOUND_STRING;
1735 m_defaultIsNone = true;
1736
1737 soundComboBox->InsertString( 1, NO_SOUND_STRING );
1738 }
1739
1740} // end InitSound
1741
1742
1743// Adds a series of Undoable's to the given MultipleUndoable which clears the
1744// objectSoundAmbientCustomized flag and all the customization flags out of
1745// all the selected dictionaries.
1746// NOTE: assumes getAllSelectedDicts() has already been called
1748{
1749 Dict empty;
1750
1751 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientCustomized, m_allSelectedDicts.size(), pDoc, true);
1752 ownerUndoable->addUndoable(pUndo);
1753 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1754
1755 // Note: we can set all the undoes in between the first and last undo to not invalidate,
1756 // since the first (last for doing) and last invalidate after these changes anyway
1757 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientMaxRange, m_allSelectedDicts.size(), pDoc, false);
1758 ownerUndoable->addUndoable(pUndo);
1759 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1760
1761 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientMinVolume, m_allSelectedDicts.size(), pDoc, false);
1762 ownerUndoable->addUndoable(pUndo);
1763 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1764
1765 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientVolume, m_allSelectedDicts.size(), pDoc, false);
1766 ownerUndoable->addUndoable(pUndo);
1767 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1768
1769 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientMinRange, m_allSelectedDicts.size(), pDoc, false);
1770 ownerUndoable->addUndoable(pUndo);
1771 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1772
1773 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientLooping, m_allSelectedDicts.size(), pDoc, false);
1774 ownerUndoable->addUndoable(pUndo);
1775 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1776
1777 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientLoopCount, m_allSelectedDicts.size(), pDoc, false);
1778 ownerUndoable->addUndoable(pUndo);
1779 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1780
1781 pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), empty, TheKey_objectSoundAmbientPriority, m_allSelectedDicts.size(), pDoc, true);
1782 ownerUndoable->addUndoable(pUndo);
1783 REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
1784}
1785
1788{
1789 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
1790 if ( soundComboBox == NULL )
1791 return;
1792
1794
1796 if ( pDoc != NULL )
1797 {
1799
1800 Dict newDict;
1801
1802 // For the default, erase the objectSoundAmbient key
1803 if ( soundComboBox->GetCurSel() != m_defaultEntryIndex )
1804 {
1805 CString selectionText;
1806 soundComboBox->GetLBText( soundComboBox->GetCurSel(), selectionText );
1807 if ( selectionText == NO_SOUND_STRING )
1808 {
1809 newDict.setAsciiString(TheKey_objectSoundAmbient, "");
1810 // Can't customize the null sound
1811 clearCustomizeFlag( pDoc, pUndo );
1812 }
1813 else
1814 {
1815 newDict.setAsciiString(TheKey_objectSoundAmbient, static_cast< const char * >( selectionText) );
1816 }
1817 }
1818 else if ( m_defaultIsNone )
1819 {
1820 // Can't customize the null sound
1821 clearCustomizeFlag( pDoc, pUndo );
1822 }
1823
1824 DictItemUndoable *pDictUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, TheKey_objectSoundAmbient, m_allSelectedDicts.size(), pDoc, true);
1825 pUndo->addUndoable( pDictUndo );
1826 pDoc->AddAndDoUndoable( pUndo );
1827 REF_PTR_RELEASE( pDictUndo ); // belongs to pUndo
1828 REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
1829 // Update is called by Doc
1830 }
1831}
1832
1835{
1836 CButton * customizeCheckbox = (CButton *)GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
1837 if ( customizeCheckbox == NULL )
1838 return;
1839
1841
1843 if ( pDoc != NULL )
1844 {
1845 Dict newDict;
1846
1847 // For space reasons, erase key instead of added "false" key. Should be treated the same
1848 if ( customizeCheckbox->GetCheck() == 1 )
1849 {
1850 newDict.setBool( TheKey_objectSoundAmbientCustomized, true );
1851 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, TheKey_objectSoundAmbientCustomized, m_allSelectedDicts.size(), pDoc, true);
1852 pDoc->AddAndDoUndoable(pUndo);
1853 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1854 // Update is called by Doc
1855 }
1856 else
1857 {
1859 clearCustomizeFlag( pDoc, pUndo );
1860 pDoc->AddAndDoUndoable( pUndo );
1861 REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
1862 // Update is called by Doc
1863 }
1864 }
1865}
1866
1869{
1870 CButton * enabledCheckbox = (CButton *)GetDlgItem(IDC_ENABLED_CHECKBOX);
1871 if ( enabledCheckbox == NULL )
1872 return;
1873
1875
1877 if ( pDoc != NULL )
1878 {
1879 Dict newDict;
1880
1881 newDict.setBool( TheKey_objectSoundAmbientEnabled, enabledCheckbox->GetCheck() != 0 );
1882
1883 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1884 pDoc->AddAndDoUndoable(pUndo);
1885 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1886 // Update is called by Doc
1887 }
1888}
1889
1892{
1893 CButton * loopingCheckbox = (CButton *)GetDlgItem(IDC_LOOPING_CHECKBOX);
1894 if ( loopingCheckbox == NULL )
1895 return;
1896
1898
1900 if ( pDoc != NULL )
1901 {
1902 Dict newDict;
1903
1904 newDict.setBool( TheKey_objectSoundAmbientLooping, loopingCheckbox->GetCheck() != 0 );
1905
1906 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1907 pDoc->AddAndDoUndoable(pUndo);
1908 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1909 // Update is called by Doc
1910 }
1911}
1912
1915{
1916 CEdit * loopCountEdit = (CEdit *)GetDlgItem(IDC_LOOPCOUNT_EDIT);
1917 if ( loopCountEdit == NULL )
1918 return;
1919
1921
1923 if ( pDoc != NULL )
1924 {
1925 Dict newDict;
1926
1927 CString loopCountString;
1928 loopCountEdit->GetWindowText(loopCountString);
1929
1930 newDict.setInt( TheKey_objectSoundAmbientLoopCount, atoi( loopCountString ) );
1931
1932 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1933 pDoc->AddAndDoUndoable(pUndo);
1934 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1935 // Update is called by Doc
1936 }
1937}
1938
1941{
1942 CEdit * minVolumeEdit = (CEdit *)GetDlgItem(IDC_MIN_VOLUME_EDIT);
1943 if ( minVolumeEdit == NULL )
1944 return;
1945
1947
1949 if ( pDoc != NULL )
1950 {
1951 Dict newDict;
1952
1953 CString minVolumeString;
1954 minVolumeEdit->GetWindowText(minVolumeString);
1955
1956 // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
1957 newDict.setReal( TheKey_objectSoundAmbientMinVolume, INT_TO_REAL( atoi( minVolumeString ) ) / 100.0f );
1958
1959 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1960 pDoc->AddAndDoUndoable(pUndo);
1961 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1962 // Update is called by Doc
1963 }
1964}
1965
1968{
1969 CEdit * volumeEdit = (CEdit *)GetDlgItem(IDC_VOLUME_EDIT);
1970 if ( volumeEdit == NULL )
1971 return;
1972
1974
1976 if ( pDoc != NULL )
1977 {
1978 Dict newDict;
1979
1980 CString volumeString;
1981 volumeEdit->GetWindowText(volumeString);
1982
1983 // Note: volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
1984 newDict.setReal( TheKey_objectSoundAmbientVolume, INT_TO_REAL( atoi( volumeString ) ) / 100.0f );
1985
1986 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
1987 pDoc->AddAndDoUndoable(pUndo);
1988 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
1989 // Update is called by Doc
1990 }
1991}
1992
1993
1996{
1997 CEdit * minRangeEdit = (CEdit *)GetDlgItem(IDC_MIN_RANGE_EDIT);
1998 if ( minRangeEdit == NULL )
1999 return;
2000
2002
2004 if ( pDoc != NULL )
2005 {
2006 Dict newDict;
2007
2008 CString minRangeString;
2009 minRangeEdit->GetWindowText(minRangeString);
2010
2011 newDict.setReal( TheKey_objectSoundAmbientMinRange, INT_TO_REAL( atoi( minRangeString ) ) );
2012
2013 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
2014 pDoc->AddAndDoUndoable(pUndo);
2015 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
2016 // Update is called by Doc
2017 }
2018}
2019
2022{
2023 CEdit * maxRangeEdit = (CEdit *)GetDlgItem(IDC_MAX_RANGE_EDIT);
2024 if ( maxRangeEdit == NULL )
2025 return;
2026
2028
2030 if ( pDoc != NULL )
2031 {
2032 Dict newDict;
2033
2034 CString maxRangeString;
2035 maxRangeEdit->GetWindowText(maxRangeString);
2036
2037 newDict.setReal( TheKey_objectSoundAmbientMaxRange, INT_TO_REAL( atoi( maxRangeString ) ) );
2038
2039 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
2040 pDoc->AddAndDoUndoable(pUndo);
2041 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
2042 // Update is called by Doc
2043 }
2044}
2045
2048{
2049 CComboBox * priorityComboBox = (CComboBox *)GetDlgItem(IDC_PRIORITY_COMBO);
2050 if ( priorityComboBox == NULL )
2051 return;
2052
2054
2056 if ( pDoc != NULL )
2057 {
2058 Dict newDict;
2059
2060 newDict.setInt( TheKey_objectSoundAmbientPriority, priorityComboBox->GetCurSel() );
2061
2062 DictItemUndoable *pUndo = new DictItemUndoable(m_allSelectedDicts.begin(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
2063 pDoc->AddAndDoUndoable(pUndo);
2064 REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
2065 // Update is called by Doc
2066 }
2067}
2068
2069
2072{
2073 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2074 if ( soundComboBox == NULL )
2075 return;
2076
2077 // Update the string for the "default" entry
2078 m_defaultIsNone = true;
2079 m_defaultEntryName = NO_SOUND_STRING;
2080 soundComboBox->DeleteString(m_defaultEntryIndex);
2081 const ThingTemplate * thingTemplate = NULL;
2082 if (m_dictSource)
2083 {
2084 thingTemplate = m_dictSource->getThingTemplate();
2085 }
2086
2087 if ( thingTemplate )
2088 {
2089 AsciiString string( BASE_DEFAULT_STRING );
2090
2091 const AudioEventRTS * defaultAudioEvent;
2092
2093 // Note: getSoundAmbient will return a non-NULL pointer even if there is no real sound attached to the object
2094 if ( thingTemplate->hasSoundAmbient() )
2095 {
2096 defaultAudioEvent = thingTemplate->getSoundAmbient();
2097 }
2098 else
2099 {
2100 defaultAudioEvent = NULL;
2101 }
2102
2103 if ( defaultAudioEvent == NULL || defaultAudioEvent == TheAudio->getValidSilentAudioEvent() )
2104 {
2105 string.concat( " <None>" );
2106 }
2107 else
2108 {
2109 string.concat( " <" );
2110 string.concat( defaultAudioEvent->getEventName() );
2111 string.concat( '>' );
2112 m_defaultEntryName = defaultAudioEvent->getEventName();
2113 m_defaultIsNone = false;
2114 }
2115 m_defaultEntryIndex = soundComboBox->InsertString(0, string.str());
2116 }
2117 else
2118 {
2119 m_defaultEntryIndex = soundComboBox->InsertString(0, BASE_DEFAULT_STRING);
2120 }
2121
2122 // Now select the correct entry in the list box
2123 AsciiString sound;
2124 Bool exists = false;
2125 if (m_dictToEdit)
2126 {
2127 sound = m_dictToEdit->getAsciiString(TheKey_objectSoundAmbient, &exists);
2128 }
2129
2130 if ( !exists )
2131 {
2132 // Use the "default" entry
2133 soundComboBox->SetCurSel( m_defaultEntryIndex );
2134 return;
2135 }
2136
2137 if ( sound.isEmpty() )
2138 {
2139 // Use the entry "(None)"
2140 sound = NO_SOUND_STRING;
2141 }
2142
2143 // Note: better than SelectString because we want the exact string not a prefix
2144 Int index = soundComboBox->FindStringExact( -1, sound.str() );
2145 if ( index > -1 )
2146 {
2147 soundComboBox->SetCurSel( index );
2148 }
2149 else
2150 {
2151 DEBUG_CRASH( ("Could not find existing sound's name %s in combo box", sound.str() ) );
2152 soundComboBox->SetCurSel( m_defaultEntryIndex );
2153 }
2154}
2155
2158{
2159 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2160 if ( customizeCheckbox == NULL )
2161 return;
2162
2163 // If the current sound is "none", disable the customize button
2164 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2165 if ( soundComboBox == NULL )
2166 return;
2167
2168 int index = soundComboBox->GetCurSel();
2169 CString currentString;
2170 soundComboBox->GetLBText( index, currentString );
2171 if ( currentString == NO_SOUND_STRING ||
2172 ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2173 {
2174 customizeCheckbox->SetCheck( 0 );
2175 customizeCheckbox->EnableWindow( false );
2176 return;
2177 }
2178
2179 // Sound is not "none", so we can customize if we wish
2180 customizeCheckbox->EnableWindow( true );
2181
2182 Bool exists = false;
2183 Bool customized = false;
2184 if (m_dictToEdit)
2185 {
2186 customized = m_dictToEdit->getBool(TheKey_objectSoundAmbientCustomized, &exists);
2187 }
2188
2189 customizeCheckbox->SetCheck( exists && customized ? 1 : 0 );
2190}
2191
2192
2195{
2196 CButton * loopingCheckbox = ( CButton * )GetDlgItem(IDC_LOOPING_CHECKBOX);
2197 if ( loopingCheckbox == NULL )
2198 return;
2199
2200 // If the customized checkbox is off, all customization controls are disabled
2201 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2202 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 )
2203 {
2204 loopingCheckbox->EnableWindow( false );
2205 }
2206 else
2207 {
2208 loopingCheckbox->EnableWindow( true );
2209
2210 // If customization is enabled, look to see if the looping flag has already been
2211 // customized
2212 Bool exists = false;
2213 Bool looping = false;
2214 if (m_dictToEdit)
2215 {
2216 looping = m_dictToEdit->getBool(TheKey_objectSoundAmbientLooping, &exists);
2217 }
2218
2219 if ( exists )
2220 {
2221 loopingCheckbox->SetCheck( looping ? 1 : 0 );
2222
2223 // Don't use defaults, just return
2224 return;
2225 }
2226 }
2227
2228 // If we get here, we need the default for the looping checkbox
2229
2230 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2231 if ( soundComboBox == NULL )
2232 {
2233 loopingCheckbox->SetCheck( 0 );
2234 return;
2235 }
2236 Int index = soundComboBox->GetCurSel();
2237
2238 CString currentString;
2239 soundComboBox->GetLBText( index, currentString );
2240 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2241 {
2242 loopingCheckbox->SetCheck( 0 );
2243 return;
2244 }
2245
2246 if ( index == m_defaultEntryIndex )
2247 {
2248 // Correct the current string e.g. remove "Default <" and ">"
2249 currentString = m_defaultEntryName.str();
2250 }
2251
2252 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2253
2254 loopingCheckbox->SetCheck( ( audioEventInfo && ( audioEventInfo->m_control & AC_LOOP ) ) ? 1 : 0 );
2255}
2256
2259{
2260 CEdit * loopCountEdit = ( CEdit * )GetDlgItem(IDC_LOOPCOUNT_EDIT);
2261 if ( loopCountEdit == NULL )
2262 return;
2263
2264 // If the customized checkbox is off, all customization controls are disabled
2265 // If the looping checkbox is off, the loop count control is disabled
2266 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2267 CButton * loopingCheckbox = ( CButton * )GetDlgItem(IDC_LOOPING_CHECKBOX);
2268 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 ||
2269 loopingCheckbox == NULL || loopingCheckbox->GetCheck() == 0 )
2270 {
2271 loopCountEdit->EnableWindow( false );
2272 }
2273 else
2274 {
2275 loopCountEdit->EnableWindow( true );
2276
2277 // If customization is enabled, look to see if the loop count has already been
2278 // customized
2279 Bool exists = false;
2280 Int loopCount = 0;
2281 if (m_dictToEdit)
2282 {
2283 loopCount = m_dictToEdit->getInt(TheKey_objectSoundAmbientLoopCount, &exists);
2284 }
2285
2286 if ( exists )
2287 {
2288 CString loopCountText;
2289 loopCountText.Format( "%d", loopCount );
2290 loopCountEdit->SetWindowText( loopCountText );
2291
2292 // Don't use defaults, just return
2293 return;
2294 }
2295 }
2296
2297 // If we get here, we need the default for the loop count
2298
2299 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2300 if ( soundComboBox == NULL )
2301 {
2302 loopCountEdit->SetWindowText( "0" );
2303 return;
2304 }
2305
2306 Int index = soundComboBox->GetCurSel();
2307
2308 CString currentString;
2309 soundComboBox->GetLBText( index, currentString );
2310 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2311 {
2312 loopCountEdit->SetWindowText( "0" );
2313 return;
2314 }
2315
2316 if ( index == m_defaultEntryIndex )
2317 {
2318 // Correct the current string e.g. remove "Default <" and ">"
2319 currentString = m_defaultEntryName.str();
2320 }
2321
2322 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2323
2324 if ( audioEventInfo == NULL )
2325 {
2326 loopCountEdit->SetWindowText( "0" );
2327 return;
2328 }
2329
2330 CString loopCountText;
2331 loopCountText.Format( "%d", audioEventInfo->m_loopCount );
2332 loopCountEdit->SetWindowText( loopCountText );
2333}
2334
2337{
2338 CButton * enableCheckbox = ( CButton * )GetDlgItem(IDC_ENABLED_CHECKBOX);
2339 if ( enableCheckbox == NULL )
2340 return;
2341
2342 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2343
2344 // If we don't have a sound, we can't enable it
2345 CString currentString;
2346 if ( soundComboBox == NULL )
2347 {
2348 enableCheckbox->EnableWindow( false );
2349 enableCheckbox->SetCheck( 0 );
2350 return;
2351 }
2352
2353 Int soundIndex = soundComboBox->GetCurSel();
2354 soundComboBox->GetLBText( soundIndex, currentString );
2355 if ( currentString == NO_SOUND_STRING ||
2356 ( soundIndex == m_defaultEntryIndex && m_defaultIsNone ) )
2357 {
2358 enableCheckbox->SetCheck( 0 );
2359 enableCheckbox->EnableWindow( false );
2360 return;
2361 }
2362 else
2363 {
2364 enableCheckbox->EnableWindow( true );
2365
2366 // Look to see if the enabled flag has already been customized
2367 Bool exists = false;
2368 Bool enabled = false;
2369 if (m_dictToEdit)
2370 {
2371 enabled = m_dictToEdit->getBool(TheKey_objectSoundAmbientEnabled, &exists);
2372 }
2373
2374 if ( exists )
2375 {
2376 enableCheckbox->SetCheck( enabled ? 1 : 0 );
2377
2378 // Don't use defaults, just return
2379 return;
2380 }
2381 }
2382
2383 // If we get here, we need the default for the enabled checkbox
2384
2385 // Look up sound and see if it's looping. Looping-forever sounds start enabled;
2386 // non-looping ones don't.
2387 // Actually, by now, dictToLooping and dictToLoopCount will have looked up the
2388 // info we need for us
2389 // NOTE: This test should match the tests done in Object::updateObjValuesFromMapProperties()
2390 // when it decided whether or not to enable a customized sound
2391 CButton * loopingCheckbox = (CButton *)GetDlgItem(IDC_LOOPING_CHECKBOX);
2392 CEdit * loopCountEdit = (CEdit *)GetDlgItem(IDC_LOOPCOUNT_EDIT);
2393 if ( loopingCheckbox && loopCountEdit && loopingCheckbox->GetCheck() == 1 )
2394 {
2395 CString loopCount;
2396 loopCountEdit->GetWindowText( loopCount );
2397
2398 if ( atoi(loopCount) == 0 )
2399 {
2400 enableCheckbox->SetCheck( 1 );
2401 return;
2402 }
2403 }
2404
2405 enableCheckbox->SetCheck( 0 );
2406}
2407
2408
2411{
2412 CEdit * minVolumeEdit = ( CEdit * )GetDlgItem(IDC_MIN_VOLUME_EDIT);
2413 if ( minVolumeEdit == NULL )
2414 return;
2415
2416 // If the customized checkbox is off, all customization controls are disabled
2417 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2418 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 )
2419 {
2420 minVolumeEdit->EnableWindow( false );
2421 }
2422 else
2423 {
2424 minVolumeEdit->EnableWindow( true );
2425
2426 // If customization is enabled, look to see if the minimum volume has already been
2427 // customized
2428 Bool exists = false;
2429 Real minVolume = 0.0f;
2430 if (m_dictToEdit)
2431 {
2432 minVolume = m_dictToEdit->getReal(TheKey_objectSoundAmbientMinVolume, &exists);
2433 }
2434
2435 if ( exists )
2436 {
2437 // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
2438 CString minVolumeText;
2439 minVolumeText.Format( "%d", REAL_TO_INT( ( minVolume * 100.0f ) + 0.5 ) );
2440 minVolumeEdit->SetWindowText( minVolumeText );
2441
2442 // Don't use defaults, just return
2443 return;
2444 }
2445 }
2446
2447 // If we get here, we need the default for the minimum volume
2448 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2449 if ( soundComboBox == NULL )
2450 {
2451 minVolumeEdit->SetWindowText( "40" );
2452 return;
2453 }
2454
2455 Int index = soundComboBox->GetCurSel();
2456
2457 CString currentString;
2458 soundComboBox->GetLBText( index, currentString );
2459 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2460 {
2461 minVolumeEdit->SetWindowText( "40" );
2462 return;
2463 }
2464
2465 if ( index == m_defaultEntryIndex )
2466 {
2467 // Correct the current string e.g. remove "Default <" and ">"
2468 currentString = m_defaultEntryName.str();
2469 }
2470
2471 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2472
2473 if ( audioEventInfo == NULL )
2474 {
2475 minVolumeEdit->SetWindowText( "40" );
2476 return;
2477 }
2478
2479 // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
2480 CString minVolumeText;
2481 minVolumeText.Format( "%d", REAL_TO_INT( ( audioEventInfo->m_minVolume * 100.0f ) + 0.5 ) );
2482 minVolumeEdit->SetWindowText( minVolumeText );
2483}
2484
2487{
2488 CEdit * volumeEdit = ( CEdit * )GetDlgItem(IDC_VOLUME_EDIT);
2489 if ( volumeEdit == NULL )
2490 return;
2491
2492 // If the customized checkbox is off, all customization controls are disabled
2493 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2494 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 )
2495 {
2496 volumeEdit->EnableWindow( false );
2497 }
2498 else
2499 {
2500 volumeEdit->EnableWindow( true );
2501
2502 // If customization is enabled, look to see if the volume has already been
2503 // customized
2504 Bool exists = false;
2505 Real volume = 0.0f;
2506 if (m_dictToEdit)
2507 {
2508 volume = m_dictToEdit->getReal(TheKey_objectSoundAmbientVolume, &exists);
2509 }
2510
2511 if ( exists )
2512 {
2513 // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
2514 CString volumeText;
2515 volumeText.Format( "%d", REAL_TO_INT( ( volume * 100.0f ) + 0.5 ) );
2516 volumeEdit->SetWindowText( volumeText );
2517
2518 // Don't use defaults, just return
2519 return;
2520 }
2521 }
2522
2523 // If we get here, we need the default for the volume
2524 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2525 if ( soundComboBox == NULL )
2526 {
2527 volumeEdit->SetWindowText( "100" );
2528 return;
2529 }
2530
2531 Int index = soundComboBox->GetCurSel();
2532
2533 CString currentString;
2534 soundComboBox->GetLBText( index, currentString );
2535 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2536 {
2537 volumeEdit->SetWindowText( "100" );
2538 return;
2539 }
2540
2541 if ( index == m_defaultEntryIndex )
2542 {
2543 // Correct the current string e.g. remove "Default <" and ">"
2544 currentString = m_defaultEntryName.str();
2545 }
2546
2547 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2548
2549 if ( audioEventInfo == NULL )
2550 {
2551 volumeEdit->SetWindowText( "100" );
2552 return;
2553 }
2554
2555 // Note: volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
2556 CString volumeText;
2557 volumeText.Format( "%d", REAL_TO_INT( ( audioEventInfo->m_volume * 100.0f ) + 0.5 ) );
2558 volumeEdit->SetWindowText( volumeText );
2559}
2560
2561
2564{
2565 CEdit * minRangeEdit = ( CEdit * )GetDlgItem(IDC_MIN_RANGE_EDIT);
2566 if ( minRangeEdit == NULL )
2567 return;
2568
2569 // If the customized checkbox is off, all customization controls are disabled
2570 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2571 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 )
2572 {
2573 minRangeEdit->EnableWindow( false );
2574 }
2575 else
2576 {
2577 minRangeEdit->EnableWindow( true );
2578
2579 // If customization is enabled, look to see if the minimum range has already been
2580 // customized
2581 Bool exists = false;
2582 Real minRange = 0.0f;
2583 if (m_dictToEdit)
2584 {
2585 minRange = m_dictToEdit->getReal(TheKey_objectSoundAmbientMinRange, &exists);
2586 }
2587
2588 if ( exists )
2589 {
2590 CString minRangeText;
2591 minRangeText.Format( "%d", REAL_TO_INT(minRange) );
2592 minRangeEdit->SetWindowText( minRangeText );
2593
2594 // Don't use defaults, just return
2595 return;
2596 }
2597 }
2598
2599 // If we get here, we need the default for the minimum range
2600 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2601 if ( soundComboBox == NULL )
2602 {
2603 minRangeEdit->SetWindowText( "175" );
2604 return;
2605 }
2606
2607 Int index = soundComboBox->GetCurSel();
2608
2609 CString currentString;
2610 soundComboBox->GetLBText( index, currentString );
2611 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2612 {
2613 minRangeEdit->SetWindowText( "175" );
2614 return;
2615 }
2616
2617 if ( index == m_defaultEntryIndex )
2618 {
2619 // Correct the current string e.g. remove "Default <" and ">"
2620 currentString = m_defaultEntryName.str();
2621 }
2622
2623 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2624
2625 if ( audioEventInfo == NULL )
2626 {
2627 minRangeEdit->SetWindowText( "175" );
2628 return;
2629 }
2630
2631 CString minRangeText;
2632 minRangeText.Format( "%d", REAL_TO_INT( audioEventInfo->m_minDistance ) );
2633 minRangeEdit->SetWindowText( minRangeText );
2634}
2635
2636
2639{
2640 CEdit * maxRangeEdit = ( CEdit * )GetDlgItem(IDC_MAX_RANGE_EDIT);
2641 if ( maxRangeEdit == NULL )
2642 return;
2643
2644 // If the customized checkbox is off, all customization controls are disabled
2645 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2646 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 )
2647 {
2648 maxRangeEdit->EnableWindow( false );
2649 }
2650 else
2651 {
2652 maxRangeEdit->EnableWindow( true );
2653
2654 // If customization is enabled, look to see if the maximum range has already been
2655 // customized
2656 Bool exists = false;
2657 Real maxRange = 0.0f;
2658 if (m_dictToEdit)
2659 {
2660 maxRange = m_dictToEdit->getReal(TheKey_objectSoundAmbientMaxRange, &exists);
2661 }
2662
2663 if ( exists )
2664 {
2665 CString maxRangeText;
2666 maxRangeText.Format( "%d", REAL_TO_INT( maxRange ) );
2667 maxRangeEdit->SetWindowText( maxRangeText );
2668
2669 // Don't use defaults, just return
2670 return;
2671 }
2672 }
2673
2674 // If we get here, we need the default for the minimum range
2675 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2676 if ( soundComboBox == NULL )
2677 {
2678 maxRangeEdit->SetWindowText( "600" );
2679 return;
2680 }
2681
2682 Int index = soundComboBox->GetCurSel();
2683
2684 CString currentString;
2685 soundComboBox->GetLBText( index, currentString );
2686 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2687 {
2688 maxRangeEdit->SetWindowText( "600" );
2689 return;
2690 }
2691
2692 if ( index == m_defaultEntryIndex )
2693 {
2694 // Correct the current string e.g. remove "Default <" and ">"
2695 currentString = m_defaultEntryName.str();
2696 }
2697
2698 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2699
2700 if ( audioEventInfo == NULL )
2701 {
2702 maxRangeEdit->SetWindowText( "600" );
2703 return;
2704 }
2705
2706 CString maxRangeText;
2707 maxRangeText.Format( "%d", REAL_TO_INT( audioEventInfo->m_maxDistance ) );
2708 maxRangeEdit->SetWindowText( maxRangeText );
2709}
2710
2713{
2714 CComboBox * priorityComboBox = ( CComboBox * )GetDlgItem(IDC_PRIORITY_COMBO);
2715 if ( priorityComboBox == NULL )
2716 return;
2717
2718 // If the customized checkbox is off, all customization controls are disabled
2719 CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
2720 if ( customizeCheckbox == NULL || customizeCheckbox->GetCheck() == 0 )
2721 {
2722 priorityComboBox->EnableWindow( false );
2723 }
2724 else
2725 {
2726 priorityComboBox->EnableWindow( true );
2727
2728 // If customization is enabled, look to see if the maximum range has already been
2729 // customized
2730 Bool exists = false;
2731 Int priorityEnum = AP_LOWEST;
2732 if (m_dictToEdit)
2733 {
2734 priorityEnum = m_dictToEdit->getInt(TheKey_objectSoundAmbientPriority, &exists);
2735 }
2736
2737 if ( exists )
2738 {
2739 if ( priorityEnum < 0 || priorityEnum > AP_CRITICAL )
2740 {
2741 DEBUG_CRASH( ("Bad soundAmbientPriority key %d", priorityEnum ) );
2742 priorityEnum = AP_LOWEST;
2743 }
2744
2745 // Note: indexes of priority combobox map to priority enum
2746 priorityComboBox->SetCurSel( priorityEnum );
2747
2748 // Don't use defaults, just return
2749 return;
2750 }
2751 }
2752
2753 // If we get here, we need the default for the priority
2754 CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
2755 if ( soundComboBox == NULL )
2756 {
2757 priorityComboBox->SetCurSel( AP_LOWEST );
2758 return;
2759 }
2760
2761 Int index = soundComboBox->GetCurSel();
2762
2763 CString currentString;
2764 soundComboBox->GetLBText( index, currentString );
2765 if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
2766 {
2767 priorityComboBox->SetCurSel( AP_LOWEST );
2768 return;
2769 }
2770
2771 if ( index == m_defaultEntryIndex )
2772 {
2773 // Correct the current string e.g. remove "Default <" and ">"
2774 currentString = m_defaultEntryName.str();
2775 }
2776
2777 AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
2778
2779 if ( audioEventInfo == NULL )
2780 {
2781 priorityComboBox->SetCurSel( AP_LOWEST );
2782 return;
2783 }
2784
2785 priorityComboBox->SetCurSel( audioEventInfo->m_priority );
2786}
2787
2788
2789// Special message to handle pages being resized to new sheet size
2790// see knowledge base article Q143291
2791const Int RESIZE_PAGE_MESSAGE = WM_USER + 117;
2792
2793
2795// MapObjectProps message handlers
2796
2797
2798
2800{
2801 // do nothing
2802}
2803
2804
2806{
2807 MapObject *pMapObj;
2808 MapObject *theMapObj = NULL;
2809// Bool found = false;
2810 Int selCount=0;
2811 for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
2812 if (pMapObj->isSelected()) {
2813 if (!pMapObj->isWaypoint() && !pMapObj->isLight())
2814 {
2815 theMapObj = pMapObj;
2816 }
2817 selCount++;
2818 }
2819 }
2820 if (selCount==1 && theMapObj) {
2821 return theMapObj;
2822 }
2823 return(NULL);
2824}
2825
2826
2827
2828
2829
2831{
2832 // Make sure CPropertySheet functions don't close the window
2833}
2834
2836{
2837 // Make sure CPropertySheet functions don't close the window
2838}
2839
2840
2841
2843{
2844 m_allSelectedDicts.clear();
2845
2846 for (MapObject *pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
2847
2848 /* If a bridge exists, and either end is selected, do both ends. */
2849 if (pMapObj->getFlag(FLAG_BRIDGE_POINT1)) {
2850 MapObject *pMapObj2 = pMapObj->getNext();
2851 if (pMapObj2 && pMapObj2->getFlag(FLAG_BRIDGE_POINT2)) {
2852 // Got a bridge.
2853 if (pMapObj->isSelected() || pMapObj2->isSelected()) {
2854 m_allSelectedDicts.push_back(pMapObj->getProperties());
2855 m_allSelectedDicts.push_back(pMapObj2->getProperties());
2856 pMapObj = pMapObj2;
2857 continue;
2858 }
2859 }
2860 }
2861
2862
2863 if (!pMapObj->isSelected() || pMapObj->isWaypoint() || pMapObj->isLight()) {
2864 continue;
2865 }
2866 m_allSelectedDicts.push_back(pMapObj->getProperties());
2867 m_selectedObject = pMapObj;
2868 }
2869}
2870
2871
2874{
2875 _ScaleToDict();
2876}
2877
2880{
2881 _ScaleToDict();
2882}
2883
2889
@ AT_SoundEffect
char * theAudioPriorityNames[]
@ AP_LOWEST
@ AP_CRITICAL
@ AC_LOOP
#define NULL
Definition BaseType.h:92
#define REAL_TO_INT(x)
Definition BaseType.h:231
#define PI
Definition BaseType.h:86
bool Bool
Definition BaseType.h:132
char Char
Signed character (ASCII)
Definition BaseType.h:131
int Int
Signed integer value.
Definition BaseType.h:125
#define TRUE
Definition BaseType.h:109
#define FALSE
Definition BaseType.h:113
#define INT_TO_REAL(x)
Definition BaseType.h:240
float Real
Definition BaseType.h:124
void const char * value
std::hash_map< AsciiString, AudioEventInfo *, rts::hash< AsciiString >, rts::equal_to< AsciiString > > AudioEventInfoHash
Definition GameAudio.h:72
AudioManager * TheAudio
#define DEBUG_ASSERTLOG(c, m)
Definition Debug.h:158
#define DEBUG_ASSERTCRASH(c, m)
Definition Debug.h:193
#define DEBUG_CRASH(m)
Definition Debug.h:192
@ true
Definition bool.h:59
@ FLAG_BRIDGE_POINT2
If set, is the second point in a bridge.
Definition MapObject.h:71
@ FLAG_BRIDGE_POINT1
If set, is the first point in a bridge.
Definition MapObject.h:70
NameKeyGenerator * TheNameKeyGenerator
just one namespace for now
NameKeyType NAMEKEY(const AsciiString &name)
NameKeyType
@ NAMEKEY_INVALID
SidesList * TheSidesList
singleton instance of SidesList
#define IDC_MAPOBJECT_Enabled
Definition resource.h:477
#define IDC_ANGLE_POPUP
Definition resource.h:325
#define IDC_EDITPROP
Definition resource.h:237
#define IDC_LOOPCOUNT_EDIT
Definition resource.h:566
#define IDC_MAPOBJECT_Team
Definition resource.h:308
#define IDC_MAPOBJECT_Selectable
Definition resource.h:349
#define IDC_MAPOBJECT_Angle
Definition resource.h:492
#define IDC_MAPOBJECT_ShroudClearingDistance
Definition resource.h:488
#define IDC_VOLUME_EDIT
Definition resource.h:571
#define IDC_MAPOBJECT_StartingHealth
Definition resource.h:483
#define IDC_MAPOBJECT_Scale
Definition resource.h:564
#define IDC_REMOVEPROP
Definition resource.h:239
#define IDC_MAPOBJECT_HitPoints
Definition resource.h:518
#define IDC_NEWPROP
Definition resource.h:170
#define IDC_MAPOBJECT_RecruitableAI
Definition resource.h:317
#define IDC_MAX_RANGE_EDIT
Definition resource.h:570
#define IDC_MAPOBJECT_StartingHealthEdit
Definition resource.h:476
#define IDC_HEIGHT_POPUP
Definition resource.h:189
#define IDC_MIN_RANGE_EDIT
Definition resource.h:569
#define IDC_MAPOBJECT_Targetable
Definition resource.h:535
#define IDC_MAPOBJECT_Time
Definition resource.h:517
#define IDC_LOOPING_CHECKBOX
Definition resource.h:561
#define IDC_MAPOBJECT_Veterancy
Definition resource.h:490
#define IDC_MAPOBJECT_Name
Definition resource.h:489
#define IDC_ENABLED_CHECKBOX
Definition resource.h:562
#define IDC_MAPOBJECT_StoppingDistance
Definition resource.h:493
#define IDC_MAPOBJECT_XYPosition
Definition resource.h:572
#define IDC_MAPOBJECT_Script
Definition resource.h:310
#define IDC_PRIORITY_COMBO
Definition resource.h:568
#define IDC_SCALE_OFF
Definition resource.h:416
#define IDS_SINGLE_SELECTION_ONLY
Definition resource.h:749
#define IDS_NO_UPGRADES
Definition resource.h:750
#define IDC_SOUND_COMBO
Definition resource.h:565
#define IDC_MAPOBJECT_Powered
Definition resource.h:316
#define IDC_PROPERTIES
Definition resource.h:229
#define IDC_MIN_VOLUME_EDIT
Definition resource.h:567
#define IDC_MAPOBJECT_VisionDistance
Definition resource.h:484
#define IDC_SCALE_ON
Definition resource.h:423
#define IDC_MAPOBJECT_Unsellable
Definition resource.h:534
#define IDC_MAPOBJECT_Weather
Definition resource.h:515
#define IDC_SCALE_POPUP
Definition resource.h:330
#define IDC_CUSTOMIZE_CHECKBOX
Definition resource.h:563
#define IDC_MAPOBJECT_ZOffset
Definition resource.h:491
#define IDC_MAPOBJECT_Indestructible
Definition resource.h:479
#define IDC_MAPOBJECT_Aggressiveness
Definition resource.h:485
#define IDC_MAPOBJECT_BuildWithUpgrades
Definition resource.h:266
#define BOOL
Definition Wnd_File.h:57
int compareNoCase(const AsciiString &stringSrc) const
const char * str() const
void format(AsciiString format,...)
Bool isEmpty() const
const AsciiString & getEventName(void) const
virtual const AudioEventInfoHash & getAllAudioEvents() const
Definition GameAudio.h:300
COptionsPanel(Int dlgid=0, CWnd *pParent=NULL)
static CWorldBuilderDoc * GetActiveDoc()
void AddAndDoUndoable(Undoable *pUndo)
Definition Dict.h:67
Real getNthReal(Int n) const
Definition Dict.cpp:374
AsciiString getNthAsciiString(Int n) const
Definition Dict.cpp:389
DataType
Definition Dict.h:75
@ DICT_REAL
Definition Dict.h:79
@ DICT_BOOL
Definition Dict.h:77
@ DICT_ASCIISTRING
Definition Dict.h:80
@ DICT_INT
Definition Dict.h:78
@ DICT_UNICODESTRING
Definition Dict.h:81
void setAsciiString(NameKeyType key, const AsciiString &value)
Definition Dict.cpp:496
Bool getNthBool(Int n) const
Definition Dict.cpp:344
DataType getNthType(Int n) const
Definition Dict.h:359
void setBool(NameKeyType key, Bool value)
Definition Dict.cpp:466
Bool remove(NameKeyType key)
Definition Dict.cpp:516
Int getNthInt(Int n) const
Definition Dict.cpp:359
UnicodeString getNthUnicodeString(Int n) const
Definition Dict.cpp:404
NameKeyType getNthKey(Int n) const
Definition Dict.h:351
void setInt(NameKeyType key, Int value)
Definition Dict.cpp:476
void setReal(NameKeyType key, Real value)
Definition Dict.cpp:486
AsciiString getAsciiString(NameKeyType key, Bool *exists=NULL) const
Definition Dict.cpp:314
static Dict buildSingleItemDict(AsciiString k, Dict::DataType t, AsciiString v)
static Bool loadScripts(CComboBox *pCombo, Bool subr, AsciiString match=AsciiString::TheEmptyString)
Bool isLight(void) const
Definition MapObject.h:147
const Coord3D * getLocation(void) const
Get the center point.
Definition MapObject.h:126
Dict * getProperties()
return the object's property sheet.
Definition MapObject.h:123
static MapObject * getFirstMapObject(void)
Definition MapObject.h:182
Bool getFlag(Int flag) const
Definition MapObject.h:141
Bool isWaypoint(void) const
Definition MapObject.h:148
MapObject * getNext(void) const
Next map object in the list. Not a copy, don't delete it.
Definition MapObject.h:134
Real getAngle(void) const
Get the angle.
Definition MapObject.h:127
Bool isSelected(void) const
Definition MapObject.h:144
void _DictToPrebuiltUpgrades(void)
Move data from object to dialog controls.
MapObject * m_selectedObject
void ShowZOffset(MapObject *pMapObj)
Move data from object to dialog controls.
afx_msg void OnSelchangeProperties()
MapObject * m_dictSource
afx_msg void minRangeToDict(void)
Move data from dialog controls to object(s)
void dictToAttachedSound(void)
Move data from object to dialog controls.
WBPopupSliderButton m_scaleSlider
afx_msg void _AggressivenessToDict(void)
Move data from dialog controls to object.
void ShowPosition(MapObject *pMapObj)
Move data from object to dialog controls.
void dictToCustomize(void)
Move data from object to dialog controls.
afx_msg void _NameToDict(void)
Move data from dialog controls to object.
virtual void PopSliderFinished(const long sliderID, long theVal)
Slider control.
void dictToPriority(void)
Move data from object to dialog controls.
void _DictToHPs(void)
Move data from object to dialog controls.
void _DictToUnsellable(void)
Move data from object to dialog controls.
ModifyObjectUndoable * m_posUndoable
afx_msg void _RecruitableAIToDict(void)
Move data from dialog controls to object.
afx_msg void _EnabledToDict(void)
Move data from dialog controls to object.
void _DictToTeam(void)
Move data from object to dialog controls.
const char * m_title
virtual BOOL OnInitDialog()
Initialize dialog, especially drop down lists.
afx_msg void OnKillfocusMAPOBJECTXYPosition()
Move data from dialog controls to object.
WBPopupSliderButton m_angleSlider
afx_msg void _TeamToDict(void)
Move data from dialog controls to object.
afx_msg void _TimeToDict(void)
Move data from dialog controls to object.
void _DictToDestructible(void)
Move data from object to dialog controls.
afx_msg void OnRemoveprop()
std::vector< Dict * > m_allSelectedDicts
afx_msg void _HPsToDict()
Move data from dialog controls to object.
afx_msg void _PoweredToDict(void)
Move data from dialog controls to object.
afx_msg void attachedSoundToDict(void)
Move data from dialog controls to object(s)
void _DictToEnabled(void)
Move data from object to dialog controls.
void _DictToPowered(void)
Move data from object to dialog controls.
void _DictToTime(void)
Move data from object to dialog controls.
void dictToMinVolume(void)
Move data from object to dialog controls.
afx_msg void _ScaleToDict(void)
Move data from dialog controls to object.
afx_msg void OnScaleOn()
Move data from dialog controls to object.
void _DictToTargetable(void)
Move data from object to dialog controls.
afx_msg void loopCountToDict(void)
Move data from dialog controls to object(s)
static MapObject * getSingleSelectedMapObject(void)
virtual void PopSliderChanged(const long sliderID, long theVal)
Slider control.
afx_msg void SetAngle(void)
Move data from dialog controls to object.
afx_msg void _SelectableToDict(void)
Move data from dialog controls to object.
afx_msg void _VisibilityToDict(void)
Move data from dialog controls to object.
afx_msg void maxRangeToDict(void)
Move data from dialog controls to object(s)
afx_msg void OnEditprop()
void _DictToStoppingDistance(void)
Move data from object to dialog controls.
void _DictToSelectable(void)
Move data from object to dialog controls.
afx_msg void _ShroudClearingDistanceToDict(void)
Move data from dialog controls to object.
void clearCustomizeFlag(CWorldBuilderDoc *pDoc, MultipleUndoable *ownerUndoable)
afx_msg void loopingToDict(void)
Move data from dialog controls to object(s)
afx_msg void _HealthToDict(void)
Move data from dialog controls to object.
void _DictToShroudClearingDistance(void)
Move data from object to dialog controls.
void _DictToVisibilityRange(void)
Move data from object to dialog controls.
afx_msg void _UnsellableToDict(void)
Move data from dialog controls to object.
afx_msg void _StoppingDistanceToDict(void)
Move data from dialog controls to object.
virtual void OnCancel()
void _DictToScale(void)
Move data from object to dialog controls.
virtual void DoDataExchange(CDataExchange *pDX)
afx_msg void _IndestructibleToDict(void)
Move data from dialog controls to object.
void getAllSelectedDicts(void)
afx_msg void priorityToDict(void)
Move data from dialog controls to object(s)
void dictToEnabled(void)
Move data from object to dialog controls.
void _DictToWeather(void)
Move data from object to dialog controls.
void _DictToHealth(void)
Move data from object to dialog controls.
virtual void OnOK()
WBPopupSliderButton m_heightSlider
MapObjectProps(Dict *dictToEdit=NULL, const char *title=NULL, CWnd *pParent=NULL)
void _DictToScript(void)
Move data from object to dialog controls.
afx_msg void SetZOffset(void)
Move data from dialog controls to object.
static MapObjectProps * TheMapObjectProps
void _DictToVeterancy(void)
Move data from object to dialog controls.
static void update(void)
void dictToLooping(void)
Move data from object to dialog controls.
afx_msg void _VeterancyToDict(void)
Move data from dialog controls to object.
afx_msg void _WeatherToDict(void)
Move data from dialog controls to object.
void dictToLoopCount(void)
Move data from object to dialog controls.
void _DictToAggressiveness(void)
Move data from object to dialog controls.
afx_msg void _PrebuiltUpgradesToDict(void)
Move data from dialog controls to object.
afx_msg void OnNewprop()
afx_msg void enabledToDict(void)
Move data from dialog controls to object(s)
afx_msg void volumeToDict(void)
Move data from dialog controls to object(s)
void _DictToName(void)
Move data from object to dialog controls.
void dictToVolume(void)
Move data from object to dialog controls.
afx_msg void customizeToDict(void)
Move data from dialog controls to object(s)
afx_msg void SetPosition(void)
Move data from dialog controls to object.
afx_msg void _TargetableToDict()
Move data from dialog controls to object.
afx_msg void minVolumeToDict(void)
Move data from dialog controls to object(s)
AsciiString m_defaultEntryName
afx_msg void OnDblclkProperties()
void _DictToRecruitableAI()
Move data from object to dialog controls.
void ShowAngle(MapObject *pMapObj)
Move data from object to dialog controls.
afx_msg void _ScriptToDict(void)
Move data from dialog controls to object.
afx_msg void OnScaleOff()
Move data from dialog controls to object.
virtual void GetPopSliderInfo(const long sliderID, long *pMin, long *pMax, long *pLineSize, long *pInitial)
Slider control.
void dictToMaxRange(void)
Move data from object to dialog controls.
void dictToMinRange(void)
Move data from object to dialog controls.
void SetZOffset(Real z)
void SetOffset(Real x, Real y)
Sets the offset for all the objects in the move list, and moves them there.
void RotateTo(Real angle)
Set the angle for all objects in the move list.
AsciiString getNthName(Int i) const
Int getCount() const
const ModuleData * getNthData(Int i) const
MultipleUndoable.
Definition CUndoable.h:398
void addUndoable(Undoable *undoable)
Bool hasSoundAmbient() const
const ModuleInfo & getBehaviorModuleInfo() const
const AudioEventRTS * getSoundAmbient() const
const WideChar * str() const
std::vector< AsciiString > m_activationUpgradeNames
const Int RESIZE_PAGE_MESSAGE
const char * NEUTRAL_TEAM_INTERNAL_STR
const char * NEUTRAL_TEAM_UI_STR
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
AudioPriority m_priority
UnsignedInt m_control
Real x
Definition BaseType.h:333
Real y
Definition BaseType.h:333
Real z
Definition BaseType.h:333