diff --git a/Generals/Code/Tools/WorldBuilder/CMakeLists.txt b/Generals/Code/Tools/WorldBuilder/CMakeLists.txt
index 1a65bb55d3d..24fbc8605a0 100644
--- a/Generals/Code/Tools/WorldBuilder/CMakeLists.txt
+++ b/Generals/Code/Tools/WorldBuilder/CMakeLists.txt
@@ -60,6 +60,8 @@ set(WORLDBUILDER_SRC
"src/RampTool.cpp"
"src/RoadOptions.cpp"
"src/RoadTool.cpp"
+ "src/RulerOptions.cpp"
+ "src/RulerTool.cpp"
"src/SaveMap.cpp"
"src/ScorchOptions.cpp"
"src/ScorchTool.cpp"
@@ -75,6 +77,7 @@ set(WORLDBUILDER_SRC
"src/TeamBehavior.cpp"
"src/TeamGeneric.cpp"
"src/TeamIdentity.cpp"
+ "src/TeamObjectProperties.cpp"
"src/TeamReinforcement.cpp"
"src/teamsdialog.cpp"
"src/TerrainMaterial.cpp"
@@ -156,6 +159,8 @@ set(WORLDBUILDER_SRC
"include/RampTool.h"
"include/RoadOptions.h"
"include/RoadTool.h"
+ "include/RulerOptions.h"
+ "include/RulerTool.h"
"include/SaveMap.h"
"include/ScorchOptions.h"
"include/ScorchTool.h"
@@ -171,6 +176,7 @@ set(WORLDBUILDER_SRC
"include/TeamBehavior.h"
"include/TeamGeneric.h"
"include/TeamIdentity.h"
+ "include/TeamObjectProperties.h"
"include/TeamReinforcement.h"
"include/teamsdialog.h"
"include/TerrainMaterial.h"
@@ -184,6 +190,7 @@ set(WORLDBUILDER_SRC
"include/WaypointTool.h"
"include/WBFrameWnd.h"
"include/WBHeightMap.h"
+ "include/WBPopupSlider.h"
"include/wbview.h"
"include/wbview3d.h"
"include/WHeightMapEdit.h"
diff --git a/Generals/Code/Tools/WorldBuilder/include/AutoEdgeOutTool.h b/Generals/Code/Tools/WorldBuilder/include/AutoEdgeOutTool.h
index 9ce0a98413f..c255f07878a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/AutoEdgeOutTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/AutoEdgeOutTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BaseBuildProps.h b/Generals/Code/Tools/WorldBuilder/include/BaseBuildProps.h
index 5d904bfa423..0837afac79d 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BaseBuildProps.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BaseBuildProps.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BlendEdgeTool.h b/Generals/Code/Tools/WorldBuilder/include/BlendEdgeTool.h
index 354dc25c9ff..b6fc5d087cf 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BlendEdgeTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BlendEdgeTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BlendMaterial.h b/Generals/Code/Tools/WorldBuilder/include/BlendMaterial.h
index da4d6558e02..963cd6d3c45 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BlendMaterial.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BlendMaterial.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BorderTool.h b/Generals/Code/Tools/WorldBuilder/include/BorderTool.h
index 8991e5cdbca..9a1e5c43631 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BorderTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BorderTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BrushTool.h b/Generals/Code/Tools/WorldBuilder/include/BrushTool.h
index 57cb0161792..1f028ca1fd3 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BrushTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BrushTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BuildList.h b/Generals/Code/Tools/WorldBuilder/include/BuildList.h
index cdfbe5604eb..7a2205c7b24 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BuildList.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BuildList.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/BuildListTool.h b/Generals/Code/Tools/WorldBuilder/include/BuildListTool.h
index 9f15f6feacf..774cd5e7db4 100644
--- a/Generals/Code/Tools/WorldBuilder/include/BuildListTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/BuildListTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/CButtonShowColor.h b/Generals/Code/Tools/WorldBuilder/include/CButtonShowColor.h
index 41626175d87..689f82f18c1 100644
--- a/Generals/Code/Tools/WorldBuilder/include/CButtonShowColor.h
+++ b/Generals/Code/Tools/WorldBuilder/include/CButtonShowColor.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/CFixTeamOwnerDialog.h b/Generals/Code/Tools/WorldBuilder/include/CFixTeamOwnerDialog.h
index 0bf23c6a1c9..b05d5383cbf 100644
--- a/Generals/Code/Tools/WorldBuilder/include/CFixTeamOwnerDialog.h
+++ b/Generals/Code/Tools/WorldBuilder/include/CFixTeamOwnerDialog.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,8 @@
** along with this program. If not, see .
*/
+
+
#include "Common/AsciiString.h"
class TeamsInfo;
class SidesList;
diff --git a/Generals/Code/Tools/WorldBuilder/include/CUndoable.h b/Generals/Code/Tools/WorldBuilder/include/CUndoable.h
index e136336dac1..9aae72df161 100644
--- a/Generals/Code/Tools/WorldBuilder/include/CUndoable.h
+++ b/Generals/Code/Tools/WorldBuilder/include/CUndoable.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -384,3 +384,27 @@ class DeletePolygonUndoable : public Undoable
virtual void Do() override;
virtual void Undo() override;
};
+
+/// MultipleUndoable
+/**
+ * An undoable that doesn't do anything; it just consolidates a number of other
+ * Undoables in a single logical undo step.
+ */
+class MultipleUndoable : public Undoable
+{
+protected:
+ Undoable * m_undoableList; //< The head of the list of undoables, in the order they should be done. Reverse order for undoes
+public:
+ MultipleUndoable();
+ // destructor.
+ virtual ~MultipleUndoable() override;
+
+ /** Add other undoables in the order you would want them UNdone; e.g. in the reverse order you want them done
+ * The MultipleUndoable object will then own the pointers.
+ */
+ void addUndoable( Undoable * undoable );
+
+ virtual void Do() override;
+ virtual void Undo() override;
+ virtual void Redo() override;
+};
diff --git a/Generals/Code/Tools/WorldBuilder/include/CameraOptions.h b/Generals/Code/Tools/WorldBuilder/include/CameraOptions.h
index f336a35c636..db805549d6b 100644
--- a/Generals/Code/Tools/WorldBuilder/include/CameraOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/CameraOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -53,6 +53,8 @@ class CameraOptions : public CDialog, public PopupSliderOwner
// Generated message map functions
//{{AFX_MSG(CameraOptions)
afx_msg void OnCameraReset();
+ afx_msg void OnDropWaypointButton();
+ afx_msg void OnCenterOnSelectedButton();
afx_msg void OnMove(int x, int y);
virtual BOOL OnInitDialog() override;
afx_msg void OnChangePitchEdit();
diff --git a/Generals/Code/Tools/WorldBuilder/include/CellWidth.h b/Generals/Code/Tools/WorldBuilder/include/CellWidth.h
index 7618374ebf4..ee16757e00b 100644
--- a/Generals/Code/Tools/WorldBuilder/include/CellWidth.h
+++ b/Generals/Code/Tools/WorldBuilder/include/CellWidth.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ContourOptions.h b/Generals/Code/Tools/WorldBuilder/include/ContourOptions.h
index 87386b4b592..90f74267260 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ContourOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ContourOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/DrawObject.h b/Generals/Code/Tools/WorldBuilder/include/DrawObject.h
index f1416d97e0b..197291e1c11 100644
--- a/Generals/Code/Tools/WorldBuilder/include/DrawObject.h
+++ b/Generals/Code/Tools/WorldBuilder/include/DrawObject.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -34,6 +34,8 @@
class MeshClass;
class PolygonTrigger;
class WaterRenderObjClass;
+class MapObject;
+class Render2DClass;
//
// DrawObject: Draws 3d feedback for tools & objects.
//
@@ -77,12 +79,14 @@ class DrawObject : public RenderObjClass
// void Set_Flag(unsigned int flag, Bool onoff) { Flags &= (~flag); if (onoff) Flags |= flag; }
Int freeMapResources();
+ int initData();
- void setDrawObjects(Bool val, Bool waypoints, Bool poly) { m_drawObjects = val; m_drawWaypoints=waypoints; m_drawPolygonAreas = poly;}
+ void setDrawObjects(Bool val, Bool waypoints, Bool poly, Bool bounding, Bool sight, Bool weapon, Bool sound, Bool testart, Bool letterbox) { m_drawObjects = val; m_drawWaypoints=waypoints; m_drawPolygonAreas = poly; m_drawBoundingBoxes = bounding; m_drawSightRanges = sight; m_drawWeaponRanges = weapon; m_drawSoundRanges = sound; m_drawTestArtHighlight = testart, m_drawLetterbox = letterbox;}
static void setDoBrushFeedback(Bool val) { m_toolWantsFeedback = val; m_meshFeedback=false;}
static void setDoMeshFeedback(Bool val) { m_meshFeedback = val; }
static void setDoRampFeedback(Bool val) { m_rampFeedback = val; }
static void setDoBoundaryFeedback(Bool val) { m_boundaryFeedback = val; }
+
static void setDoAmbientSoundFeedback(Bool val) { m_ambientSoundFeedback = val; }
static void setBrushFeedbackParms(Bool square, Int width, Int featherWidth)
@@ -122,6 +126,12 @@ class DrawObject : public RenderObjClass
Bool m_drawObjects;
Bool m_drawWaypoints;
Bool m_drawPolygonAreas;
+ Bool m_drawBoundingBoxes;
+ Bool m_drawSightRanges;
+ Bool m_drawWeaponRanges;
+ Bool m_drawSoundRanges;
+ Bool m_drawTestArtHighlight;
+ Bool m_drawLetterbox;
DX8VertexBufferClass *m_vertexFeedback; ///< Vertex buffer for brush feedback.
DX8IndexBufferClass *m_indexFeedback; ///< indices defining a triangle strip for the feedback on terrain
@@ -132,6 +142,8 @@ class DrawObject : public RenderObjClass
MeshClass *m_moldMesh; ///< W3D mesh model for the mold.
SphereClass m_moldMeshBounds; ///< Bounding sphere for mold mesh.
+ Render2DClass *m_lineRenderer; //< Used to render 2D lines for bounding boxes.
+ CPoint m_winSize; //< Holds the size of the window.
protected: // static state vars.
static Bool m_squareFeedback; ///< True for square brush feedback, false for round.
@@ -155,7 +167,7 @@ class DrawObject : public RenderObjClass
static Real m_rampWidth;
protected:
- int initData();
+ void addCircleToLineRenderer( const Coord3D & center, Real radius, Real width, unsigned long color, CameraClass* camera );
Int updateVB(DX8VertexBufferClass *vertexBufferTile, Int color, Bool doArrow, Bool doDiamond);
void updatePolygonVB(PolygonTrigger *pTrig, Bool selected, Bool isOpen);
void updateFeedbackVB();
@@ -165,6 +177,12 @@ class DrawObject : public RenderObjClass
void updateForWater();
void updateBoundaryVB();
void updateAmbientSoundVB();
+ void updateVBWithBoundingBox(MapObject *pMapObj, CameraClass* camera);
+ void updateVBWithSightRange(MapObject *pMapObj, CameraClass* camera);
+ void updateVBWithWeaponRange(MapObject *pMapObj, CameraClass* camera);
+ void updateVBWithTestArtHighlight(MapObject *pMapObj, CameraClass* camera);
+ void updateVBWithSoundRanges(MapObject *pMapObj, CameraClass* camera);
+ bool worldToScreen(const Coord3D *w, ICoord2D *s, CameraClass* camera);
};
diff --git a/Generals/Code/Tools/WorldBuilder/include/EditAction.h b/Generals/Code/Tools/WorldBuilder/include/EditAction.h
index cfae6a683bd..2e64f151d05 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EditAction.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EditAction.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -62,6 +62,7 @@ class EditAction : public CDialog
CRichEditCtrl m_myEditCtrl;
CHARRANGE m_curLinkChrg;
Int m_curEditParameter;
+ CTreeCtrl m_actionTreeView;
protected:
diff --git a/Generals/Code/Tools/WorldBuilder/include/EditCondition.h b/Generals/Code/Tools/WorldBuilder/include/EditCondition.h
index cbd29f3282e..90da61f7733 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EditCondition.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EditCondition.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -24,6 +24,13 @@
class Condition;
class SidesList;
+
+class CMyTreeCtrl : public CTreeCtrl
+{
+public:
+ virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ) override;
+};
+
/////////////////////////////////////////////////////////////////////////////
// EditCondition dialog
@@ -61,6 +68,7 @@ class EditCondition : public CDialog
CRichEditCtrl m_myEditCtrl;
CHARRANGE m_curLinkChrg;
Int m_curEditParameter;
+ CTreeCtrl m_conditionTreeView;
protected:
diff --git a/Generals/Code/Tools/WorldBuilder/include/EditCoordParameter.h b/Generals/Code/Tools/WorldBuilder/include/EditCoordParameter.h
index 87b2bf2c9fd..9959dd1a379 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EditCoordParameter.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EditCoordParameter.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/EditGroup.h b/Generals/Code/Tools/WorldBuilder/include/EditGroup.h
index 8993f79b0e4..c4cdeb5bd62 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EditGroup.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EditGroup.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/EditObjectParameter.h b/Generals/Code/Tools/WorldBuilder/include/EditObjectParameter.h
index 901d64d2744..da951f252e4 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EditObjectParameter.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EditObjectParameter.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -44,6 +44,7 @@ friend class EditParameter;
//{{AFX_VIRTUAL(EditObjectParameter)
protected:
virtual void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support
+ virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) override;
//}}AFX_VIRTUAL
// Implementation
diff --git a/Generals/Code/Tools/WorldBuilder/include/EditParameter.h b/Generals/Code/Tools/WorldBuilder/include/EditParameter.h
index 02172ec544d..3220d9a1862 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EditParameter.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EditParameter.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -50,8 +50,8 @@ class EditParameter : public CDialog
// Implementation
public:
- static Int edit( Parameter *pParm, AsciiString unitName = AsciiString::TheEmptyString );
- static AsciiString getWarningText(Parameter *pParm);
+ static Int edit( Parameter *pParm, Int keyPressed, AsciiString unitName = AsciiString::TheEmptyString );
+ static AsciiString getWarningText(Parameter *pParm, Bool isAction);
static AsciiString getInfoText(Parameter *pParm);
static void setCurSidesList(SidesList *sidesListP) {m_sidesListP = sidesListP;};
static Bool loadScripts(CComboBox *pCombo, Bool subr, AsciiString match = AsciiString::TheEmptyString);
@@ -93,10 +93,10 @@ class EditParameter : public CDialog
static Bool loadEmoticons( CComboBox *pCombo, AsciiString match = AsciiString::TheEmptyString );
static AsciiString getCreatedUnitTemplateName(AsciiString unitName);
- void loadCounters(CComboBox *pCombo);
- void loadConditionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo);
- void loadActionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo);
- void loadFlags(CComboBox *pCombo);
+ static Bool loadCounters(CComboBox *pCombo, AsciiString match = AsciiString::TheEmptyString);
+ static void loadConditionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo);
+ static Bool loadActionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo, AsciiString match);
+ static Bool loadFlags(CComboBox *pCombo, AsciiString match = AsciiString::TheEmptyString);
protected:
@@ -106,11 +106,15 @@ class EditParameter : public CDialog
Int m_int;
Real m_real;
+ Int m_key; // key pressed to invoke the edit parameter dialog.
+
static SidesList *m_sidesListP;
static AsciiString m_selectedLocalizedString;
protected:
+ Bool scanReal(CEdit *pEdit, Real scale);
+protected:
// Generated message map functions
//{{AFX_MSG(EditParameter)
afx_msg void OnChangeEdit();
diff --git a/Generals/Code/Tools/WorldBuilder/include/ExportScriptsOptions.h b/Generals/Code/Tools/WorldBuilder/include/ExportScriptsOptions.h
index c78869d01ae..06377f25507 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ExportScriptsOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ExportScriptsOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -50,12 +50,14 @@ class ExportScriptsOptions : public CDialog
static Bool m_waypoints;
static Bool m_triggers;
static Bool m_allScripts;
+ static Bool m_sides;
public:
Bool getDoUnits() {return m_units;}
Bool getDoWaypoints() {return m_waypoints;}
Bool getDoTriggers() {return m_triggers;}
Bool getDoAllScripts() {return m_allScripts;}
+ Bool getDoSides() {return m_sides;}
protected:
diff --git a/Generals/Code/Tools/WorldBuilder/include/EyedropperTool.h b/Generals/Code/Tools/WorldBuilder/include/EyedropperTool.h
index bdfca2216f4..8138b416ede 100644
--- a/Generals/Code/Tools/WorldBuilder/include/EyedropperTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/EyedropperTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/FeatherOptions.h b/Generals/Code/Tools/WorldBuilder/include/FeatherOptions.h
index 452b981dc89..f50ccc3a3fe 100644
--- a/Generals/Code/Tools/WorldBuilder/include/FeatherOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/FeatherOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/FeatherTool.h b/Generals/Code/Tools/WorldBuilder/include/FeatherTool.h
index 75271e7de19..8b9d301630f 100644
--- a/Generals/Code/Tools/WorldBuilder/include/FeatherTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/FeatherTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/FenceOptions.h b/Generals/Code/Tools/WorldBuilder/include/FenceOptions.h
index 63d388d382e..baa7c259422 100644
--- a/Generals/Code/Tools/WorldBuilder/include/FenceOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/FenceOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/FenceTool.h b/Generals/Code/Tools/WorldBuilder/include/FenceTool.h
index fd6c77e5879..1418c84b361 100644
--- a/Generals/Code/Tools/WorldBuilder/include/FenceTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/FenceTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/FloodFillTool.h b/Generals/Code/Tools/WorldBuilder/include/FloodFillTool.h
index 09fe3e2cfd8..fd49b3b83e0 100644
--- a/Generals/Code/Tools/WorldBuilder/include/FloodFillTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/FloodFillTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/GlobalLightOptions.h b/Generals/Code/Tools/WorldBuilder/include/GlobalLightOptions.h
index 20366ab9310..9b4a8871f2a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/GlobalLightOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/GlobalLightOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/GroveOptions.h b/Generals/Code/Tools/WorldBuilder/include/GroveOptions.h
index f6775966e7b..0e70e91697e 100644
--- a/Generals/Code/Tools/WorldBuilder/include/GroveOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/GroveOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/GroveTool.h b/Generals/Code/Tools/WorldBuilder/include/GroveTool.h
index a59b6812e14..a57425159a5 100644
--- a/Generals/Code/Tools/WorldBuilder/include/GroveTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/GroveTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/HandScrollTool.h b/Generals/Code/Tools/WorldBuilder/include/HandScrollTool.h
index 4aab1c503a7..7a54b4b18d8 100644
--- a/Generals/Code/Tools/WorldBuilder/include/HandScrollTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/HandScrollTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ImpassableOptions.h b/Generals/Code/Tools/WorldBuilder/include/ImpassableOptions.h
index 8621c3da58b..c0a70433005 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ImpassableOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ImpassableOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/LayersList.h b/Generals/Code/Tools/WorldBuilder/include/LayersList.h
index 6f4079a6026..5280b3a574a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/LayersList.h
+++ b/Generals/Code/Tools/WorldBuilder/include/LayersList.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -42,15 +42,20 @@
// FORWARD DECLARATIONS ///////////////////////////////////////////////////////
class MapObject;
+class PolygonTrigger;
// TYPE DEFINES ///////////////////////////////////////////////////////////////
typedef std::list ListMapObjectPtr;
typedef ListMapObjectPtr::iterator ListMapObjectPtrIt;
+typedef std::list ListPolygonTriggerPtr;
+typedef ListPolygonTriggerPtr::iterator ListPolygonTriggerPtrIt;
+
struct Layer
{
AsciiString layerName;
ListMapObjectPtr objectsInLayer;
+ ListPolygonTriggerPtr polygonTriggersInLayer;
Bool show;
};
@@ -86,9 +91,12 @@ class LayersList : public CDialog
void resetLayers();
void addMapObjectToLayersList(IN MapObject *objToAdd, AsciiString layerToAddTo = AsciiString(TheDefaultLayerName.c_str()));
+ void addPolygonTriggerToLayersList(IN PolygonTrigger *triggerToAdd, AsciiString layerToAddTo = AsciiString(TheDefaultLayerName.c_str()));
AsciiString removeMapObjectFromLayersList(IN MapObject *objToRemove);
+ AsciiString removePolygonTriggerFromLayersList(IN PolygonTrigger *triggerToRemove);
void changeMapObjectLayer(IN MapObject *objToChange, AsciiString layerToPlaceOn);
+ void changePolygonTriggerLayer(IN PolygonTrigger *triggerToChange, AsciiString layerToPlaceOn);
void addLayerNamed(IN AsciiString layerToAdd);
void removeLayerNamed(IN AsciiString layerToRemove);
@@ -105,29 +113,40 @@ class LayersList : public CDialog
const ListLayer& GetAllLayers() const { return mLayers; }
static MapObject *findObjectByUID(AsciiString objectIDToFind);
+ static PolygonTrigger *findPolygonTriggerByUID(AsciiString objectIDToFind);
+ static Bool findAndSelectMapObject(AsciiString selectedItemAsciiString);
+ static Bool findAndSelectPolygonTrigger(AsciiString selectedItemAsciiString);
+ static void unselectAllMapObjects();
+ static void unselectAllPolygonTriggers();
+
+ public:
+ // This is a string because making it an AsciiString makes us barf on construction. :-(
+ static std::string TheDefaultLayerName;
+ static std::string ThePolygonTriggerLayerName;
+ static std::string TheDefaultNewLayerName;
+ static std::string TheActiveLayerName;
+ static const std::string TheUnmutableDefaultLayerName;
protected:
AsciiString mCurrentlyEditingLabel;
+
ListLayer mLayers;
CLLTreeCtrl *mTree;
CImageList mImageList;
Bool m_performUpdates;
+ Bool m_activatedLayer;
HTREEITEM findTreeLayerNamed(const AsciiString& nameToFind);
HTREEITEM findTreeObjectNamed(const AsciiString& objectToFind, HTREEITEM layerItem);
- // This is a string because making it an AsciiString makes us barf on construction. :-(
- static std::string TheDefaultLayerName;
- static std::string TheDefaultNewLayerName;
- static const std::string TheUnmutableDefaultLayerName;
-
// This function takes an MapObject, and does one of the following:
// 1) Return true if the MapObject can be found, and
// layerIt points to a valid layer iterator in which the MapObject was found
// MapObjectIt points to a valid MapObject iterator on the layerIts MapObjectsInLayer member
// 2) Returns false if the MapObject cannot be found.
Bool findMapObjectAndList(IN MapObject *MapObjectToFind, OUT ListLayerIt *layerIt = nullptr, OUT ListMapObjectPtrIt *MapObjectIt = nullptr);
+ Bool findPolygonTriggerAndList(IN PolygonTrigger *PolygonTriggerToFind, OUT ListLayerIt *layerIt = nullptr, OUT ListPolygonTriggerPtrIt *PolygonTriggerIt = nullptr);
// This function takes a layer name, and does one of the following:
// 1) Return true if the layer can be found, and
@@ -136,7 +155,11 @@ class LayersList : public CDialog
Bool findLayerNamed(IN AsciiString layerName, OUT ListLayerIt *layerIt = nullptr);
void addMapObjectToLayer(IN MapObject *objToAdd, IN ListLayerIt *layerIt);
+ void addPolygonTriggerToLayer(IN PolygonTrigger *objToAdd, IN ListLayerIt *layerIt);
void removeMapObjectFromLayer(IN MapObject *objToRemove, IN ListLayerIt *layerIt = nullptr, IN ListMapObjectPtrIt *MapObjectIt = nullptr);
+ void removePolygonTriggerFromLayer(IN PolygonTrigger *triggerToRemove, IN ListLayerIt *layerIt = nullptr, IN ListPolygonTriggerPtrIt *PolygonTriggerIt = nullptr);
+ void updateObjectRenderFlags(IN ListLayerIt *layerIt);
+ void updateTreeImages();
protected:
virtual void OnOK() override;
@@ -149,8 +172,10 @@ class LayersList : public CDialog
afx_msg void OnMergeLayer(UINT commandID);
afx_msg void OnMergeObject(UINT commandID);
afx_msg void OnMergeViewSelection(UINT commandID);
+ afx_msg void OnSelectActiveLayer();
+ afx_msg void OnSelectLayerObject();
afx_msg void OnNewLayer();
afx_msg void OnDeleteLayer();
afx_msg void OnHideShowLayer();
diff --git a/Generals/Code/Tools/WorldBuilder/include/LightOptions.h b/Generals/Code/Tools/WorldBuilder/include/LightOptions.h
index c6b8aeadbab..f44ea50f267 100644
--- a/Generals/Code/Tools/WorldBuilder/include/LightOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/LightOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MainFrm.h b/Generals/Code/Tools/WorldBuilder/include/MainFrm.h
index bc37892cf45..eb83809b740 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MainFrm.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MainFrm.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -45,12 +45,13 @@
#include "CameraOptions.h"
#include "ScorchOptions.h"
#include "BuildList.h"
+#include "RulerOptions.h"
#define TWO_D_WINDOW_SECTION "TwoDWindow"
#define MAIN_FRAME_SECTION "MainFrame"
class LayersList;
-
+class ScriptDialog;
class CMainFrame : public CFrameWnd
{
@@ -87,6 +88,7 @@ class CMainFrame : public CFrameWnd
void adjustWindowSize();
Bool isAutoSaving() {return m_autoSaving;};
void handleCameraChange();
+ void onEditScripts();
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
@@ -113,7 +115,8 @@ class CMainFrame : public CFrameWnd
GlobalLightOptions m_globalLightOptions;
CameraOptions m_cameraOptions;
LayersList* m_layersList;
-
+ ScriptDialog* m_scriptDialog;
+ RulerOptions m_rulerOptions;
CWnd *m_curOptions;
Int m_curOptionsX;
diff --git a/Generals/Code/Tools/WorldBuilder/include/MapPreview.h b/Generals/Code/Tools/WorldBuilder/include/MapPreview.h
index f44e16fe43c..47f82577383 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MapPreview.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MapPreview.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MapSettings.h b/Generals/Code/Tools/WorldBuilder/include/MapSettings.h
index 0a0d8b3d529..d40335d3e49 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MapSettings.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MapSettings.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MeshMoldOptions.h b/Generals/Code/Tools/WorldBuilder/include/MeshMoldOptions.h
index ba2dec4127d..7eb1c3c263a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MeshMoldOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MeshMoldOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MeshMoldTool.h b/Generals/Code/Tools/WorldBuilder/include/MeshMoldTool.h
index e56928da369..c2f96107e5a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MeshMoldTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MeshMoldTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MoundOptions.h b/Generals/Code/Tools/WorldBuilder/include/MoundOptions.h
index 9ce5e94d88f..8a6cda92ba1 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MoundOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MoundOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MoundTool.h b/Generals/Code/Tools/WorldBuilder/include/MoundTool.h
index 718959d6d7d..1d873838776 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MoundTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MoundTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/MyToolbar.h b/Generals/Code/Tools/WorldBuilder/include/MyToolbar.h
index 0f71e3eeecb..b2a7c2a86b8 100644
--- a/Generals/Code/Tools/WorldBuilder/include/MyToolbar.h
+++ b/Generals/Code/Tools/WorldBuilder/include/MyToolbar.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/NewHeightMap.h b/Generals/Code/Tools/WorldBuilder/include/NewHeightMap.h
index 3430d6c6d93..8ecf703dee3 100644
--- a/Generals/Code/Tools/WorldBuilder/include/NewHeightMap.h
+++ b/Generals/Code/Tools/WorldBuilder/include/NewHeightMap.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ObjectOptions.h b/Generals/Code/Tools/WorldBuilder/include/ObjectOptions.h
index 59ebdacc488..fe4fc594694 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ObjectOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ObjectOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ObjectPreview.h b/Generals/Code/Tools/WorldBuilder/include/ObjectPreview.h
index a1791971a94..9169b23dd48 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ObjectPreview.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ObjectPreview.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ObjectTool.h b/Generals/Code/Tools/WorldBuilder/include/ObjectTool.h
index 3460463ccfe..29929d98fca 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ObjectTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ObjectTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/OpenMap.h b/Generals/Code/Tools/WorldBuilder/include/OpenMap.h
index 15a848c9698..02e0c48704d 100644
--- a/Generals/Code/Tools/WorldBuilder/include/OpenMap.h
+++ b/Generals/Code/Tools/WorldBuilder/include/OpenMap.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/OptionsPanel.h b/Generals/Code/Tools/WorldBuilder/include/OptionsPanel.h
index d34051cb6d0..648b9795dbe 100644
--- a/Generals/Code/Tools/WorldBuilder/include/OptionsPanel.h
+++ b/Generals/Code/Tools/WorldBuilder/include/OptionsPanel.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/PickUnitDialog.h b/Generals/Code/Tools/WorldBuilder/include/PickUnitDialog.h
index 25b26a7cde5..885f875a319 100644
--- a/Generals/Code/Tools/WorldBuilder/include/PickUnitDialog.h
+++ b/Generals/Code/Tools/WorldBuilder/include/PickUnitDialog.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/PointerTool.h b/Generals/Code/Tools/WorldBuilder/include/PointerTool.h
index ce7e4a19979..ea207e939ff 100644
--- a/Generals/Code/Tools/WorldBuilder/include/PointerTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/PointerTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/PolygonTool.h b/Generals/Code/Tools/WorldBuilder/include/PolygonTool.h
index 69d8b436ad1..52a03ca1520 100644
--- a/Generals/Code/Tools/WorldBuilder/include/PolygonTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/PolygonTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/RampOptions.h b/Generals/Code/Tools/WorldBuilder/include/RampOptions.h
index e6d83754449..e9993d4c427 100644
--- a/Generals/Code/Tools/WorldBuilder/include/RampOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/RampOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/RampTool.h b/Generals/Code/Tools/WorldBuilder/include/RampTool.h
index 345054581f2..135c4a790b7 100644
--- a/Generals/Code/Tools/WorldBuilder/include/RampTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/RampTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/RoadOptions.h b/Generals/Code/Tools/WorldBuilder/include/RoadOptions.h
index 832c82a6260..616dd382e49 100644
--- a/Generals/Code/Tools/WorldBuilder/include/RoadOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/RoadOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/RoadTool.h b/Generals/Code/Tools/WorldBuilder/include/RoadTool.h
index bf11a057f5b..f0a091a72a7 100644
--- a/Generals/Code/Tools/WorldBuilder/include/RoadTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/RoadTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/RulerOptions.h b/Generals/Code/Tools/WorldBuilder/include/RulerOptions.h
new file mode 100644
index 00000000000..ce6e8a0ec27
--- /dev/null
+++ b/Generals/Code/Tools/WorldBuilder/include/RulerOptions.h
@@ -0,0 +1,73 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+// RulerOptions.h : header file
+//
+#include "OptionsPanel.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// RulerOptions dialog
+
+class RulerOptions : public COptionsPanel
+{
+
+// Construction
+public:
+
+ RulerOptions(CWnd* pParent = nullptr); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(RulerOptions)
+ enum { IDD = IDD_RULER_OPTIONS };
+ // NOTE: the ClassWizard will add data members here
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(RulerOptions)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support
+ virtual void OnOK() override {return;}; //!< Modeless dialogs don't OK, so eat this for modeless.
+ virtual void OnCancel() override {return;}; //!< Modeless dialogs don't close on ESC, so eat this for modeless.
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(RulerOptions)
+ virtual BOOL OnInitDialog() override;
+ afx_msg void OnChangeWidthEdit();
+ afx_msg void OnChangeCheckRuler();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+protected:
+ static RulerOptions *m_staticThis; ///< Reference to the floating panel so SetWidth and SetFeather can be static.
+
+ Bool m_updating; ///.
+*/
+
+// RulerTool.h
+// Author: Mike Lytle, January 2003
+
+#pragma once
+
+#include "Tool.h"
+
+class RulerTool : public Tool
+{
+protected:
+ Coord3D m_downPt3d;
+ int m_rulerType;
+ WbView* m_View;
+ Real m_savedLength;
+
+ static RulerTool* m_staticThis;
+
+public:
+ RulerTool();
+ virtual ~RulerTool() override;
+
+public:
+ /// Clear the selection on activate or deactivate.
+ virtual void activate() override;
+ virtual void deactivate() override;
+
+ virtual void setCursor() override;
+ virtual void mouseDown(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldBuilderDoc *pDoc) override;
+ virtual void mouseMoved(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldBuilderDoc *pDoc) override;
+ virtual Bool followsTerrain() override {return false;};
+
+ static void setLength(Real length);
+ static Bool switchType();
+ static int getType();
+ static Real getLength();
+
+};
diff --git a/Generals/Code/Tools/WorldBuilder/include/SaveMap.h b/Generals/Code/Tools/WorldBuilder/include/SaveMap.h
index 9bd68806c70..09afb838d51 100644
--- a/Generals/Code/Tools/WorldBuilder/include/SaveMap.h
+++ b/Generals/Code/Tools/WorldBuilder/include/SaveMap.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScorchOptions.h b/Generals/Code/Tools/WorldBuilder/include/ScorchOptions.h
index 6b7c1d5930b..20cbae58e0d 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScorchOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScorchOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScorchTool.h b/Generals/Code/Tools/WorldBuilder/include/ScorchTool.h
index 4fc1e43277a..3b968ddd0a7 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScorchTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScorchTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScriptActionsFalse.h b/Generals/Code/Tools/WorldBuilder/include/ScriptActionsFalse.h
index 3c990b1e470..fb8648ed473 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScriptActionsFalse.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScriptActionsFalse.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScriptActionsTrue.h b/Generals/Code/Tools/WorldBuilder/include/ScriptActionsTrue.h
index 71214acee26..84d95a510ff 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScriptActionsTrue.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScriptActionsTrue.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScriptConditions.h b/Generals/Code/Tools/WorldBuilder/include/ScriptConditions.h
index 4d02757a5c5..006aeacec78 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScriptConditions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScriptConditions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScriptDialog.h b/Generals/Code/Tools/WorldBuilder/include/ScriptDialog.h
index 34737b5c09a..d7f51f2d782 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScriptDialog.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScriptDialog.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -80,9 +80,13 @@ class ScriptDialog : public CDialog
// Implementation
public:
- static void updateWarnings();
+ static void updateWarnings(Bool forceUpdate=false);
static void updateScriptWarning(Script *pScript);
+ static void patchScriptParametersForGC(Script *pScript);
+ static void checkParametersForGC();
+
+
/// To allow CSDTreeCtrl access to these member functions of ScriptDialog
Script *friend_getCurScript();
ScriptGroup *friend_getCurGroup();
@@ -94,6 +98,8 @@ class ScriptDialog : public CDialog
static ScriptDialog *m_staticThis;
CSDTreeCtrl *mTree;
Bool m_draggingTreeView;
+ Bool m_autoUpdateWarnings; ///< flag whether we should updateWarnings on script editor actions.
+
HTREEITEM m_dragItem;
MapObject *m_firstReadObject;
@@ -138,6 +144,9 @@ class ScriptDialog : public CDialog
afx_msg void OnEditScript();
afx_msg void OnCopyScript();
afx_msg void OnDelete();
+ afx_msg void OnVerify();
+ afx_msg void OnPatchGC();
+ afx_msg void OnAutoVerify();
afx_msg void OnSave();
afx_msg void OnLoad();
afx_msg void OnDblclkScriptTree(NMHDR* pNMHDR, LRESULT* pResult);
diff --git a/Generals/Code/Tools/WorldBuilder/include/ScriptProperties.h b/Generals/Code/Tools/WorldBuilder/include/ScriptProperties.h
index 62148a16f20..167efdde693 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ScriptProperties.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ScriptProperties.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/SelectMacrotexture.h b/Generals/Code/Tools/WorldBuilder/include/SelectMacrotexture.h
index f2bed8d6467..bd21f74fa36 100644
--- a/Generals/Code/Tools/WorldBuilder/include/SelectMacrotexture.h
+++ b/Generals/Code/Tools/WorldBuilder/include/SelectMacrotexture.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/ShadowOptions.h b/Generals/Code/Tools/WorldBuilder/include/ShadowOptions.h
index 257f977798b..9902f78055c 100644
--- a/Generals/Code/Tools/WorldBuilder/include/ShadowOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/ShadowOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/SplashScreen.h b/Generals/Code/Tools/WorldBuilder/include/SplashScreen.h
index 49d935e0403..f492f825f5d 100644
--- a/Generals/Code/Tools/WorldBuilder/include/SplashScreen.h
+++ b/Generals/Code/Tools/WorldBuilder/include/SplashScreen.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/StdAfx.h b/Generals/Code/Tools/WorldBuilder/include/StdAfx.h
index 2570c641763..2b9de438d01 100644
--- a/Generals/Code/Tools/WorldBuilder/include/StdAfx.h
+++ b/Generals/Code/Tools/WorldBuilder/include/StdAfx.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TeamBehavior.h b/Generals/Code/Tools/WorldBuilder/include/TeamBehavior.h
index 4ac4e1c5e6d..bc553f79f50 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TeamBehavior.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TeamBehavior.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TeamGeneric.h b/Generals/Code/Tools/WorldBuilder/include/TeamGeneric.h
index 5ea5a062f3e..c8c79ac1b61 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TeamGeneric.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TeamGeneric.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TeamIdentity.h b/Generals/Code/Tools/WorldBuilder/include/TeamIdentity.h
index 1ca51663abb..a1ab9376eb6 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TeamIdentity.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TeamIdentity.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TeamObjectProperties.h b/Generals/Code/Tools/WorldBuilder/include/TeamObjectProperties.h
new file mode 100644
index 00000000000..87fc7f27fad
--- /dev/null
+++ b/Generals/Code/Tools/WorldBuilder/include/TeamObjectProperties.h
@@ -0,0 +1,106 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+// TeamObjectProperties.h
+// Mike Lytle
+// January, 2003
+// (c) Electronic Arts 2003
+
+#pragma once
+
+#include "resource.h"
+
+// Forward declarations.
+class Dict;
+
+
+// External Defines
+
+class TeamObjectProperties : public CPropertyPage
+{
+// Construction
+public:
+ TeamObjectProperties(Dict* dictToEdit = nullptr);
+ virtual ~TeamObjectProperties() override;
+
+// Dialog Data
+ //{{AFX_DATA(MapObjectProps)
+ enum { IDD = IDD_TeamObjectProperties };
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(TeamObjectProperties)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support
+ virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam) override;
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ Dict* m_dictToEdit;
+
+#if 0 // Keys not implemented yet. jba. [3/26/2003]//
+ void updateTheUI(void);
+
+ // Generated message map functions
+ //{{AFX_MSG(TeamObjectProperties)
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ afx_msg void _HealthToDict(void);
+ afx_msg void _EnabledToDict(void);
+ afx_msg void _IndestructibleToDict(void);
+ afx_msg void _UnsellableToDict(void);
+ afx_msg void _PoweredToDict(void);
+ afx_msg void _AggressivenessToDict(void);
+ afx_msg void _VisibilityToDict(void);
+ afx_msg void _VeterancyToDict(void);
+ afx_msg void _ShroudClearingDistanceToDict(void);
+ afx_msg void _RecruitableAIToDict(void);
+ afx_msg void _SelectableToDict(void);
+ afx_msg void _WeatherToDict(void);
+ afx_msg void _TimeToDict(void);
+ afx_msg void _HPsToDict();
+ afx_msg void _StoppingDistanceToDict(void);
+ afx_msg void _UpdateTeamMembers(void);
+ //}}AFX_MSG
+
+ DECLARE_MESSAGE_MAP()
+
+ void _DictToHealth(void);
+ void _DictToHPs(void);
+ void _DictToEnabled(void);
+ void _DictToDestructible(void);
+ void _DictToUnsellable(void);
+ void _DictToPowered(void);
+ void _DictToAggressiveness(void);
+ void _DictToVisibilityRange(void);
+ void _DictToVeterancy(void);
+ void _DictToShroudClearingDistance(void);
+ void _DictToRecruitableAI();
+ void _DictToSelectable(void);
+ void _DictToWeather(void);
+ void _DictToTime(void);
+ void _DictToStoppingDistance(void);
+ void _PropertiesToDict(void);
+#endif
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
diff --git a/Generals/Code/Tools/WorldBuilder/include/TeamReinforcement.h b/Generals/Code/Tools/WorldBuilder/include/TeamReinforcement.h
index 0748649e572..fde0bc9de5b 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TeamReinforcement.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TeamReinforcement.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TerrainMaterial.h b/Generals/Code/Tools/WorldBuilder/include/TerrainMaterial.h
index 9808eb5d000..4974c8540ab 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TerrainMaterial.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TerrainMaterial.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TerrainModal.h b/Generals/Code/Tools/WorldBuilder/include/TerrainModal.h
index 85b073e8082..89c23708e93 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TerrainModal.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TerrainModal.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TerrainSwatches.h b/Generals/Code/Tools/WorldBuilder/include/TerrainSwatches.h
index 63d069a67fa..2c9e599882b 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TerrainSwatches.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TerrainSwatches.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/TileTool.h b/Generals/Code/Tools/WorldBuilder/include/TileTool.h
index 8fe8a0ee1d0..a75350fccb5 100644
--- a/Generals/Code/Tools/WorldBuilder/include/TileTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/TileTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/Tool.h b/Generals/Code/Tools/WorldBuilder/include/Tool.h
index 8aa9b8baa71..1198341693d 100644
--- a/Generals/Code/Tools/WorldBuilder/include/Tool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/Tool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WBFrameWnd.h b/Generals/Code/Tools/WorldBuilder/include/WBFrameWnd.h
index 1527c7a79ad..37d682543f6 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WBFrameWnd.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WBFrameWnd.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WBHeightMap.h b/Generals/Code/Tools/WorldBuilder/include/WBHeightMap.h
index b680e82bbdf..57f0f640c1b 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WBHeightMap.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WBHeightMap.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -18,9 +18,14 @@
#pragma once
+#include "W3DDevice/GameClient/FlatHeightMap.h"
#include "W3DDevice/GameClient/HeightMap.h"
-
+#define dont_USE_FLAT_HEIGHT_MAP // Use the original height map for mission disk. jba. [4/15/2003]
+#ifdef USE_FLAT_HEIGHT_MAP
+class WBHeightMap : public FlatHeightMapRenderObjClass
+#else
class WBHeightMap : public HeightMapRenderObjClass
+#endif
{
public:
diff --git a/Generals/Code/Tools/WorldBuilder/include/WBPopupSlider.h b/Generals/Code/Tools/WorldBuilder/include/WBPopupSlider.h
index cdd459b5b02..2fbfb9a456b 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WBPopupSlider.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WBPopupSlider.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WHeightMapEdit.h b/Generals/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
index e923b87c432..68b1044ef4e 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -137,8 +137,8 @@ class WorldHeightMapEdit : public WorldHeightMap
void showTileStatusInfo(); ///< pops up a dialog box with tile mem usage.
- Bool selectDuplicates(); ///< Selects any dupicate map objects.
- Bool selectSimilar(); ///< Selects any dupicate map objects.
+ Bool selectDuplicates(); ///< Selects any duplicate map objects.
+ Bool selectSimilar(); ///< Selects any duplicate map objects.
Bool selectInvalidTeam(); ///< Selects any objects with invalid teams.
Bool resize(Int newXSize, Int newYSize, Int newHeight, Int newBorder, Bool anchorTop, Bool anchorBottom,
diff --git a/Generals/Code/Tools/WorldBuilder/include/WaterOptions.h b/Generals/Code/Tools/WorldBuilder/include/WaterOptions.h
index be33616feef..d8b27bdf4e2 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WaterOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WaterOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WaterTool.h b/Generals/Code/Tools/WorldBuilder/include/WaterTool.h
index ab9d9b5768f..506fc8caf0e 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WaterTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WaterTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WaypointOptions.h b/Generals/Code/Tools/WorldBuilder/include/WaypointOptions.h
index 82cef5f241a..193d2791dd7 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WaypointOptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WaypointOptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WaypointTool.h b/Generals/Code/Tools/WorldBuilder/include/WaypointTool.h
index bed8c54f862..85c649b4986 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WaypointTool.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WaypointTool.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WorldBuilder.h b/Generals/Code/Tools/WorldBuilder/include/WorldBuilder.h
index d4d4d90cf57..5d4f8295497 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WorldBuilder.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WorldBuilder.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -51,6 +51,7 @@
#include "BuildListTool.h"
#include "RampTool.h"
#include "ScorchTool.h"
+#include "RulerTool.h"
#include "Common/Debug.h"
/////////////////////////////////////////////////////////////////////////////
@@ -93,7 +94,7 @@ class CWorldBuilderApp : public CWinApp
protected:
- enum {NUM_VIEW_TOOLS=24};
+ enum {NUM_VIEW_TOOLS=25};
Tool *m_tools[NUM_VIEW_TOOLS]; ///< array of tool pointers.
Tool *m_curTool; ///< Currently active tool.
@@ -122,6 +123,7 @@ class CWorldBuilderApp : public CWinApp
RampTool m_rampTool; ///< Ramp tool.
ScorchTool m_scorchTool; ///< Scorch tool.
BorderTool m_borderTool; ///< Border tool.
+ RulerTool m_rulerTool; ///< Ruler tool.
Int m_lockCurTool;
@@ -154,7 +156,7 @@ class CWorldBuilderApp : public CWinApp
/// Set the tool that will be active.
void setActiveTool(Tool *newTool);
- /// Sets the current directry for file opens.
+ /// Sets the current directory for file opens.
void setCurrentDirectory(AsciiString dir) {m_currentDirectory = dir;};
Tool *getCurTool() { return m_curTool; }
diff --git a/Generals/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h b/Generals/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h
index 687dc81f96e..4bd88712af4 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WorldBuilderDoc.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/WorldBuilderView.h b/Generals/Code/Tools/WorldBuilder/include/WorldBuilderView.h
index e1f2e6c29d3..bf0a66e963c 100644
--- a/Generals/Code/Tools/WorldBuilder/include/WorldBuilderView.h
+++ b/Generals/Code/Tools/WorldBuilder/include/WorldBuilderView.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/addplayerdialog.h b/Generals/Code/Tools/WorldBuilder/include/addplayerdialog.h
index 115b77ca71e..e1200daa304 100644
--- a/Generals/Code/Tools/WorldBuilder/include/addplayerdialog.h
+++ b/Generals/Code/Tools/WorldBuilder/include/addplayerdialog.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/brushoptions.h b/Generals/Code/Tools/WorldBuilder/include/brushoptions.h
index 4d76ba32534..0d1145e4187 100644
--- a/Generals/Code/Tools/WorldBuilder/include/brushoptions.h
+++ b/Generals/Code/Tools/WorldBuilder/include/brushoptions.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/mapobjectprops.h b/Generals/Code/Tools/WorldBuilder/include/mapobjectprops.h
index 2f15bcf5fa6..a448ec7582a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/mapobjectprops.h
+++ b/Generals/Code/Tools/WorldBuilder/include/mapobjectprops.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -27,6 +27,9 @@
class MapObject;
class ModifyObjectUndoable;
+class MultipleUndoable;
+class CWorldBuilderDoc;
+class MapObject;
/////////////////////////////////////////////////////////////////////////////
// External Defines
@@ -65,35 +68,62 @@ class MapObjectProps : public COptionsPanel, public PopupSliderOwner
static MapObjectProps *TheMapObjectProps;
+ // Data common to all property pages
Dict* m_dictToEdit;
std::vector m_allSelectedDicts;
const char* m_title;
MapObject *m_selectedObject;
+ MapObject *m_dictSource; // Source object for m_dictToEdit. m_selectedObject is not always the current source
+ // of m_dictToEdit, and I don't understand why, so I'm making another MapObject pointer
+ // which is always kept in sync.
- void updateTheUI();
- void enableButtons();
- int getSel();
- WBPopupSliderButton m_heightSlider;
- WBPopupSliderButton m_angleSlider;
Real m_angle;
Real m_height;
+ Real m_scale;
+
+ WBPopupSliderButton m_heightSlider;
+ WBPopupSliderButton m_angleSlider;
+ WBPopupSliderButton m_scaleSlider;
+
+ Int m_defaultEntryIndex; //< Index in the sound combobox of the entry labelled "default"
+ Bool m_defaultIsNone; //< The default for this object is no sound
+ AsciiString m_defaultEntryName; //< The original name of the default entry
+
ModifyObjectUndoable *m_posUndoable;
+ Coord3D m_position;
+
+ void deletePages();
+ void updateTheUI();
+ void enableButtons();
+ int getSel();
+
// Generated message map functions
//{{AFX_MSG(MapObjectProps)
- afx_msg void OnSelchangeProperties();
virtual BOOL OnInitDialog() override;
+ virtual void OnOK() override;
+ virtual void OnCancel() override;
+ afx_msg void OnSelchangeProperties();
afx_msg void OnEditprop();
afx_msg void OnNewprop();
afx_msg void OnRemoveprop();
afx_msg void OnDblclkProperties();
- virtual void OnOK() override;
- virtual void OnCancel() override;
+
afx_msg void _TeamToDict();
afx_msg void _NameToDict();
+ afx_msg void _ScriptToDict();
+ afx_msg void _WeatherToDict();
+ afx_msg void _TimeToDict();
+ afx_msg void _ScaleToDict();
+ afx_msg void SetZOffset();
+ afx_msg void SetAngle();
+ afx_msg void SetPosition();
+ afx_msg void OnScaleOn();
+ afx_msg void OnScaleOff();
+ afx_msg void OnKillfocusMAPOBJECTXYPosition();
+ afx_msg void _PrebuiltUpgradesToDict();
afx_msg void _HealthToDict();
afx_msg void _EnabledToDict();
- afx_msg void _ScriptToDict();
afx_msg void _IndestructibleToDict();
afx_msg void _UnsellableToDict();
afx_msg void _TargetableToDict();
@@ -104,23 +134,32 @@ class MapObjectProps : public COptionsPanel, public PopupSliderOwner
afx_msg void _ShroudClearingDistanceToDict();
afx_msg void _RecruitableAIToDict();
afx_msg void _SelectableToDict();
- afx_msg void _WeatherToDict();
- afx_msg void _TimeToDict();
- afx_msg void _PrebuiltUpgradesToDict();
- afx_msg void SetZOffset();
- afx_msg void SetAngle();
afx_msg void _HPsToDict();
afx_msg void _StoppingDistanceToDict();
- //}}AFX_MSG
+ afx_msg void attachedSoundToDict();
+ afx_msg void customizeToDict();
+ afx_msg void enabledToDict();
+ afx_msg void loopingToDict();
+ afx_msg void loopCountToDict();
+ afx_msg void minVolumeToDict();
+ afx_msg void volumeToDict();
+ afx_msg void minRangeToDict();
+ afx_msg void maxRangeToDict();
+ afx_msg void priorityToDict();
+ //}}AFX_MSG
DECLARE_MESSAGE_MAP()
- void _DictToTeam();
void _DictToName();
+ void _DictToTeam();
+ void _DictToScript();
+ void _DictToScale();
+ void _DictToWeather();
+ void _DictToTime();
+ void _DictToPrebuiltUpgrades();
void _DictToHealth();
void _DictToHPs();
void _DictToEnabled();
- void _DictToScript();
void _DictToDestructible();
void _DictToUnsellable();
void _DictToTargetable();
@@ -132,21 +171,38 @@ class MapObjectProps : public COptionsPanel, public PopupSliderOwner
void _DictToShroudClearingDistance();
void _DictToRecruitableAI();
void _DictToSelectable();
- void _DictToWeather();
- void _DictToTime();
+ void _DictToStoppingDistance();
void ShowZOffset(MapObject* pMapObj);
void ShowAngle(MapObject* pMapObj);
- void _DictToStoppingDistance();
- void _DictToPrebuiltUpgrades();
-
-public:
+ void ShowPosition(MapObject* pMapObj);
+ void dictToAttachedSound();
+ void dictToCustomize();
+ void dictToEnabled();
+ void dictToLooping();
+ void dictToLoopCount();
+ void dictToMinVolume();
+ void dictToVolume();
+ void dictToMinRange();
+ void dictToMaxRange();
+ void dictToPriority();
+
+ void clearCustomizeFlag( CWorldBuilderDoc* pDoc, MultipleUndoable * ownerUndoable );
+
+ // Implementation of PopupSliderOwner callbacks
virtual void GetPopSliderInfo(const long sliderID, long *pMin, long *pMax, long *pLineSize, long *pInitial) override;
virtual void PopSliderChanged(const long sliderID, long theVal) override;
virtual void PopSliderFinished(const long sliderID, long theVal) override;
+public:
static MapObject *getSingleSelectedMapObject();
static void update();
+private:
+ /// Disallow copying: Object is not set up to be copied
+ MapObjectProps( const MapObjectProps & other ); // Deliberately undefined
+ MapObjectProps & operator=( const MapObjectProps & other ); // Deliberately undefined
+ void updateTheUI(MapObject *pMapObj);
+ void InitSound();
};
//{{AFX_INSERT_LOCATION}}
diff --git a/Generals/Code/Tools/WorldBuilder/include/playerlistdlg.h b/Generals/Code/Tools/WorldBuilder/include/playerlistdlg.h
index f71fbab636a..26f8c78503d 100644
--- a/Generals/Code/Tools/WorldBuilder/include/playerlistdlg.h
+++ b/Generals/Code/Tools/WorldBuilder/include/playerlistdlg.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/propedit.h b/Generals/Code/Tools/WorldBuilder/include/propedit.h
index 9adbb2d68a7..8eccbc3892a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/propedit.h
+++ b/Generals/Code/Tools/WorldBuilder/include/propedit.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/teamsdialog.h b/Generals/Code/Tools/WorldBuilder/include/teamsdialog.h
index 7999ee053ce..84d22cf5c35 100644
--- a/Generals/Code/Tools/WorldBuilder/include/teamsdialog.h
+++ b/Generals/Code/Tools/WorldBuilder/include/teamsdialog.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/include/wbview.h b/Generals/Code/Tools/WorldBuilder/include/wbview.h
index 5ef83521269..38699a0555a 100644
--- a/Generals/Code/Tools/WorldBuilder/include/wbview.h
+++ b/Generals/Code/Tools/WorldBuilder/include/wbview.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -34,6 +34,12 @@ enum TPickedStatus {
PICK_ARROW
};
+enum RulerTypeEnum {
+ RULER_NONE,
+ RULER_LINE,
+ RULER_CIRCLE,
+};
+
/////////////////////////////////////////////////////////////////////////////
// WbView view
@@ -77,6 +83,9 @@ class WbView : public CView
// Box feedback.
RECT m_feedbackBox;
Bool m_doRectFeedback;
+ int m_doRulerFeedback;
+ Coord3D m_rulerPoints[2];
+ Real m_rulerLength;
// Light direction feedback
Coord3D m_lightDirection[3]; //direction of all 3 lights
@@ -88,6 +97,8 @@ class WbView : public CView
public:
void doRectFeedback(Bool doFeedback, RECT &rect) {m_feedbackBox=rect;m_doRectFeedback = doFeedback;};
+ void doRulerFeedback(int doRulerFeedback) {m_doRulerFeedback = doRulerFeedback;}
+ void rulerFeedbackInfo(Coord3D &point1, Coord3D &point2, Real dist);
void doLightFeedback(Bool doFeedback, Coord3D direction, Int lightIndex) { m_doLightFeedback=doFeedback; if (m_doLightFeedback) m_lightDirection[lightIndex]=direction;}
diff --git a/Generals/Code/Tools/WorldBuilder/include/wbview3d.h b/Generals/Code/Tools/WorldBuilder/include/wbview3d.h
index e6c7befa7a0..7439499c471 100644
--- a/Generals/Code/Tools/WorldBuilder/include/wbview3d.h
+++ b/Generals/Code/Tools/WorldBuilder/include/wbview3d.h
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
** along with this program. If not, see .
*/
+
// WbView3d.h
// Class to encapsulate height map.
// Author: Steven Johnson, Aug 2001
@@ -137,6 +138,16 @@ class WbView3d : public WbView, public DX8_CleanupHook
afx_msg void OnUpdateViewPartialmapsize128x128(CCmdUI* pCmdUI);
afx_msg void OnViewShowModels();
afx_msg void OnUpdateViewShowModels(CCmdUI* pCmdUI);
+ afx_msg void OnViewBoundingBoxes();
+ afx_msg void OnUpdateViewBoundingBoxes(CCmdUI* pCmdUI);
+ afx_msg void OnViewSightRanges();
+ afx_msg void OnUpdateViewSightRanges(CCmdUI* pCmdUI);
+ afx_msg void OnViewWeaponRanges();
+ afx_msg void OnUpdateViewWeaponRanges(CCmdUI* pCmdUI);
+ afx_msg void OnHighlightTestArt();
+ afx_msg void OnUpdateHighlightTestArt(CCmdUI* pCmdUI);
+ afx_msg void OnShowLetterbox();
+ afx_msg void OnUpdateShowLetterbox(CCmdUI* pCmdUI);
afx_msg void OnViewLayersList();
afx_msg void OnUpdateViewLayersList(CCmdUI* pCmdUI);
afx_msg void OnViewGarrisoned();
@@ -145,7 +156,9 @@ class WbView3d : public WbView, public DX8_CleanupHook
afx_msg void OnUpdateViewShowMapBoundaries(CCmdUI* pCmdUI);
afx_msg void OnViewShowAmbientSounds();
afx_msg void OnUpdateViewShowAmbientSounds(CCmdUI* pCmdUI);
- //}}AFX_MSG
+ afx_msg void OnViewShowSoundCircles();
+ afx_msg void OnUpdateViewShowSoundCircles(CCmdUI* pCmdUI);
+ //}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
@@ -199,6 +212,12 @@ class WbView3d : public WbView, public DX8_CleanupHook
Bool m_showLayersList; ///< Flag whether the layers list is visible or not.
Bool m_showMapBoundaries; ///< Flag whether to show all the map boundaries or not
Bool m_showAmbientSounds; ///< Flag whether to show all the ambient sounds or not
+ Bool m_showSoundCircles; ///< Flag whether to show the minimum and maximum radii of the ambient sounds attached to the selected object
+ Bool m_showBoundingBoxes;
+ Bool m_showSightRanges;
+ Bool m_showWeaponRanges;
+ Bool m_highlightTestArt;
+ Bool m_showLetterbox;
ID3DXFont* m3DFont;
@@ -211,6 +230,7 @@ class WbView3d : public WbView, public DX8_CleanupHook
void init3dScene();
void initAssets();
void initWW3D();
+ void drawCircle( HDC hdc, const Coord3D & centerPoint, Real radius, COLORREF color );
void drawLabels(HDC hdc);
void drawLabels();
void shutdownWW3D();
@@ -220,6 +240,7 @@ class WbView3d : public WbView, public DX8_CleanupHook
void updateHysteresis();
void updateLights();
void updateScorches();
+ void updateTrees();
public:
virtual Bool viewToDocCoords(CPoint curPt, Coord3D *newPt, Bool constrain=true) override;
@@ -247,10 +268,12 @@ class WbView3d : public WbView, public DX8_CleanupHook
virtual void pitchCamera(Real delta) override;
void setCameraPitch(Real absolutePitch);
Real getCameraPitch();
+ Real getCurrentZoom(); //WST 10/17/2002
Real getHeightAboveGround() { return m_actualHeightAboveGround; }
Vector3 getCameraSource() { return m_cameraSource; }
Vector3 getCameraTarget() { return m_cameraTarget; }
Real getCameraAngle() { return m_cameraAngle; }
+ CPoint getActualWinSize() {return m_actualWinSize;}
virtual MapObject *picked3dObjectInView(CPoint viewPt) override;
virtual BuildListInfo *pickedBuildObjectInView(CPoint viewPt) override;
@@ -290,6 +313,16 @@ class WbView3d : public WbView, public DX8_CleanupHook
void togglePitchAndRotation() { m_doPitch = !m_doPitch; }
virtual Bool isDoingPitch() override { return m_doPitch; }
+ void setShowBoundingBoxes(Bool toggle) {m_showBoundingBoxes = toggle;}
+ Bool getShowBoundingBoxes() { return m_showBoundingBoxes;}
+ void setShowSightRanges(Bool toggle) {m_showSightRanges = toggle;}
+ Bool getShowSightRanges() { return m_showSightRanges;}
+ void setShowWeaponRanges(Bool toggle) {m_showWeaponRanges = toggle;}
+ Bool getShowWeaponRanges() { return m_showWeaponRanges;}
+ void setHighlightTestArt(Bool toggle) {m_highlightTestArt = toggle;}
+ Bool getHighlightTestArt() { return m_highlightTestArt;}
+ void setShowLetterbox(Bool toggle) {m_showLetterbox = toggle;}
+ Bool getShowLetterbox() { return m_showLetterbox;}
};
inline UINT WbView3d::getLastDrawTime() { return m_time; }
diff --git a/Generals/Code/Tools/WorldBuilder/res/Toolbar.bmp b/Generals/Code/Tools/WorldBuilder/res/Toolbar.bmp
index 4f12bc25b9e..61478f4f724 100644
Binary files a/Generals/Code/Tools/WorldBuilder/res/Toolbar.bmp and b/Generals/Code/Tools/WorldBuilder/res/Toolbar.bmp differ
diff --git a/Generals/Code/Tools/WorldBuilder/res/WorldBuilder.rc b/Generals/Code/Tools/WorldBuilder/res/WorldBuilder.rc
index 4755a373920..0918509c0ea 100644
--- a/Generals/Code/Tools/WorldBuilder/res/WorldBuilder.rc
+++ b/Generals/Code/Tools/WorldBuilder/res/WorldBuilder.rc
@@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE
//
-1 TEXTINCLUDE DISCARDABLE
+1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
-2 TEXTINCLUDE DISCARDABLE
+2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
-3 TEXTINCLUDE DISCARDABLE
+3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
@@ -99,8 +99,8 @@ BEGIN
BUTTON ID_EDIT_CUT
BUTTON ID_EDIT_COPY
BUTTON ID_EDIT_PASTE
- BUTTON ID_FILE_PRINT
SEPARATOR
+ BUTTON ID_RULER_TOOL
BUTTON ID_POINTER_TOOL
BUTTON ID_LOCK_HORIZONTAL
BUTTON ID_BRUSH_TOOL
@@ -130,10 +130,8 @@ BEGIN
BUTTON ID_POLYGON_TOOL
BUTTON ID_BORDERTOOL
SEPARATOR
- BUTTON ID_LOOK_NORTH
- BUTTON ID_LOOK_SOUTH
- BUTTON ID_LOOK_WEST
- BUTTON ID_LOOK_EAST
+ BUTTON ID_SCRIPT_EDIT
+ BUTTON ID_TEAM_EDIT
SEPARATOR
BUTTON ID_APP_ABOUT
END
@@ -173,7 +171,7 @@ END
// Menu
//
-IDR_MAPDOC MENU PRELOAD DISCARDABLE
+IDR_MAPDOC MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
@@ -184,7 +182,7 @@ BEGIN
MENUITEM "Save &As...", ID_FILE_SAVE_AS
MENUITEM "&Jump to Game\tCtrl+J", ID_FILE_JUMPTOGAME
MENUITEM SEPARATOR
- MENUITEM "Resize Map", ID_FILE_RESIZE
+ MENUITEM "Resize...", ID_FILE_RESIZE
MENUITEM SEPARATOR
MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
MENUITEM "Print Pre&view", ID_FILE_PRINT_PREVIEW
@@ -207,7 +205,7 @@ BEGIN
MENUITEM "Delete\tDel", ID_EDIT_DELETE
MENUITEM SEPARATOR
MENUITEM "Select Duplicate Objects", ID_EDIT_SELECTDUP
- MENUITEM "Select Bad Team Objects", ID_EDIT_SELECTINVALIDTEAM
+ MENUITEM "Select Objects w/bad teams", ID_EDIT_SELECTINVALIDTEAM
MENUITEM "Select Si&milar\tCtrl+M", ID_EDIT_SELECTSIMILAR
MENUITEM "Select Macrotexture...", ID_EDIT_SELECTMACROTEXTURE
MENUITEM "Replace Selected...", ID_EDIT_REPLACE
@@ -233,8 +231,8 @@ BEGIN
MENUITEM "Edit Shadows...", ID_EDIT_SHADOWS
MENUITEM "Edit Map Settings...", ID_EDIT_MAPSETTINGS
MENUITEM SEPARATOR
- MENUITEM "Edit Player List...", ID_EDIT_PLAYERLIST
MENUITEM "Edit Teams...", ID_EDIT_TEAMLIST
+ MENUITEM "Edit Player List...", ID_EDIT_PLAYERLIST
END
POPUP "&View"
BEGIN
@@ -248,11 +246,18 @@ BEGIN
MENUITEM "Show Shadows", ID_VIEW_SHOWSHADOWS
MENUITEM "Show Labels", ID_VIEW_LABELS
MENUITEM "Show Objects", ID_VIEW_SHOWMODELS
+ MENUITEM "Show Bounding Boxes", ID_VIEW_BOUNDINGBOXES
+ MENUITEM "Show Sight Ranges", ID_VIEW_SIGHTRANGES
+ MENUITEM "Show Weapon Ranges", ID_VIEW_WEAPONRANGES
MENUITEM "Show Garrisoned", ID_VIEW_GARRISONED
MENUITEM "Show Map Boundaries", ID_VIEW_SHOWMAPBOUNDARIES
+ MENUITEM "Show Letterbox", ID_SHOW_LETTERBOX
MENUITEM "Show Sound Flags", ID_VIEW_SHOWAMBIENTSOUNDS
+ MENUITEM "Show Sound Circles", ID_VIEW_SHOW_SOUND_CIRCLES
MENUITEM SEPARATOR
- MENUITEM "Show Impassable Areas\tCtrl+I",
+ MENUITEM "Highlight Test Art", ID_HIGHLIGHT_TESTART
+ MENUITEM SEPARATOR
+ MENUITEM "Show Impassable Areas\tCtrl+I",
ID_VIEW_SHOWIMPASSABLEAREAS
MENUITEM "Impassable Area Options...", ID_VIEW_IMPASSABLEAREAOPTIONS
@@ -272,6 +277,13 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "Show Wireframe 3D View\tCtrl+W", ID_VIEW_SHOWWIREFRAME
MENUITEM "Show From Top Down View\tCtrl+F", ID_VIEW_SHOWTOPDOWNVIEW
+ POPUP "Camera Direction"
+ BEGIN
+ MENUITEM "Look North", ID_LOOK_NORTH
+ MENUITEM "Look South", ID_LOOK_SOUTH
+ MENUITEM "Look West", ID_LOOK_WEST
+ MENUITEM "Look East", ID_LOOK_EAST
+ END
MENUITEM "Show 3-Way Blends in White", ID_VIEW_SHOWEXTRABLENDS
MENUITEM "Show Clouds\tCtrl+U", ID_VIEW_SHOWCLOUDS
MENUITEM "Show Soft Water", ID_VIEW_SHOWSOFTWATER
@@ -302,10 +314,10 @@ BEGIN
BEGIN
MENUITEM "Map Cliff Textures", ID_TEXTURESIZING_MAPCLIFFTEXTURES
- MENUITEM "Remove Cliff Textures", ID_TEXTURESIZING_REMOVECLIFFTEXMAPPING
+ MENUITEM "Remove Cliff Tex Mapping", ID_TEXTURESIZING_REMOVECLIFFTEXMAPPING
MENUITEM SEPARATOR
- MENUITEM "Optimize Tile Usage", ID_TS_CANONICAL
+ MENUITEM "Optimize tiles and blend tiles.", ID_TS_CANONICAL
MENUITEM SEPARATOR
MENUITEM "Remap Textures...", ID_TS_REMAP
MENUITEM SEPARATOR
@@ -327,10 +339,13 @@ BEGIN
END
END
-IDR_LAYERSLISTPOPUP MENU DISCARDABLE
+IDR_LAYERSLISTPOPUP MENU DISCARDABLE
BEGIN
POPUP "Layers List"
BEGIN
+ MENUITEM "Select Object", ID_SELECTLAYEROBJECT
+ MENUITEM "Select Active Layer", ID_SELECTACTIVELAYER
+ MENUITEM SEPARATOR
MENUITEM "Insert New Layer", ID_INSERTNEWLAYER
MENUITEM "Delete Current Layer", ID_DELETECURRENTLAYER
POPUP "Merge Layer into"
@@ -353,7 +368,7 @@ BEGIN
END
END
-IDR_SCRIPTDIALOGPOPUP MENU DISCARDABLE
+IDR_SCRIPTDIALOGPOPUP MENU DISCARDABLE
BEGIN
POPUP "Layers List"
BEGIN
@@ -367,7 +382,7 @@ END
// Accelerator
//
-IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
+IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"0", ID_EDIT_PICKANYTHING, VIRTKEY, CONTROL, NOINVERT
"1", ID_EDIT_PICKSTRUCTS, VIRTKEY, CONTROL, NOINVERT
@@ -386,7 +401,7 @@ BEGIN
"F", ID_TOGGLE_PITCH_AND_ROTATE, VIRTKEY, NOINVERT
"F", ID_VIEW_SHOWTOPDOWNVIEW, VIRTKEY, CONTROL, NOINVERT
"G", IDM_ShowGrid, VIRTKEY, CONTROL, NOINVERT
- "G", ID_VIEW_SNAPTOGRID, VIRTKEY, SHIFT, CONTROL,
+ "G", ID_VIEW_SNAPTOGRID, VIRTKEY, SHIFT, CONTROL,
NOINVERT
"I", ID_VIEW_SHOWIMPASSABLEAREAS, VIRTKEY, CONTROL, NOINVERT
"J", ID_FILE_JUMPTOGAME, VIRTKEY, CONTROL, NOINVERT
@@ -410,7 +425,7 @@ BEGIN
"W", ID_VIEW_SHOWWIREFRAME, VIRTKEY, CONTROL, NOINVERT
"X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
- "Z", ID_EDIT_REDO, VIRTKEY, SHIFT, CONTROL,
+ "Z", ID_EDIT_REDO, VIRTKEY, SHIFT, CONTROL,
NOINVERT
END
@@ -454,23 +469,23 @@ BEGIN
EDITTEXT IDC_INITIAL_HEIGHT,75,58,26,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
- CONTROL "",IDC_TOP_LEFT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_TOP_LEFT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,53,83,20,18
- CONTROL "",IDC_TOP,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_TOP,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,73,83,20,18
- CONTROL "",IDC_TOP_RIGHT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_TOP_RIGHT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,93,83,20,18
- CONTROL "",IDC_CENTER_LEFT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_CENTER_LEFT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,53,101,20,18
- CONTROL "",IDC_CENTER,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_CENTER,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,73,101,20,18
- CONTROL "",IDC_CENTER_RIGHT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_CENTER_RIGHT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,93,101,20,18
- CONTROL "",IDC_BOTTOM_LEFT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_BOTTOM_LEFT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,53,119,20,18
- CONTROL "",IDC_BOTTOM,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_BOTTOM,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,73,119,20,18
- CONTROL "",IDC_BOTTOM_RIGHT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_BOTTOM_RIGHT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,93,119,20,18
LTEXT "Initial height (0-255):",IDC_STATIC,7,59,67,9
LTEXT "Vert (y) size:",IDC_STATIC,7,25,42,9
@@ -508,15 +523,15 @@ BEGIN
LTEXT "35 FT.",IDC_FEATHER_LABEL,71,68,41,8
END
-IDD_TERRAIN_MATERIAL DIALOG DISCARDABLE 0, 0, 200, 298
+IDD_TERRAIN_MATERIAL DIALOG DISCARDABLE 0, 0, 200, 286
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Terrain Material Options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,126
PUSHBUTTON "Swap",IDC_SWAP_TEXTURES,138,138,25,16
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,67,137,65,55
LTEXT "Gravel",IDC_TERRAIN_NAME,70,197,86,9
EDITTEXT IDC_SIZE_EDIT,53,217,17,12,ES_AUTOHSCROLL
@@ -532,7 +547,7 @@ BEGIN
27,270,98,10
END
-IDD_MOUND_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 183
+IDD_MOUND_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 146
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Terrain Brush Options"
FONT 8, "MS Sans Serif"
@@ -559,16 +574,16 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Object Selection Opts"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,0,5,199,126
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,80,137,57,49
LTEXT "Light Tank",IDC_OBJECT_NAME,65,205,67,9
EDITTEXT IDC_OBJECT_HEIGHT_EDIT,106,191,26,12,ES_AUTOHSCROLL
LTEXT "Height (0==on terrain)",IDC_STATIC,13,193,74,8
LTEXT "Object Name:",IDC_STATIC,13,205,42,9
LTEXT "Default Owner:",IDC_STATIC,13,219,48,8
- COMBOBOX IDC_OWNINGTEAM,13,229,162,104,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_OWNINGTEAM,13,229,162,104,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
END
@@ -593,9 +608,9 @@ STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Replace "
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,174,126
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,15,201,65,55
LTEXT "Gravel",IDC_TERRAIN_NAME,44,185,83,10
DEFPUSHBUTTON "OK",IDOK,129,231,50,14
@@ -635,7 +650,7 @@ BEGIN
LTEXT "This tool has no options.",IDC_STATIC,15,34,89,43
END
-IDD_FEATHER_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 218
+IDD_FEATHER_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 186
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Feather Brush Options"
FONT 8, "MS Sans Serif"
@@ -664,10 +679,10 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Mesh Mold Options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_MESHMOLD_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_MESHMOLD_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,93
PUSHBUTTON "Apply",IDC_APPLY_MESH,5,224,56,17
- CONTROL "Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | WS_TABSTOP,147,225,40,10
RTEXT "Angle (deg)",IDC_STATIC,5,142,41,10
EDITTEXT IDC_ANGLE_EDIT,50,140,29,12,ES_AUTOHSCROLL
@@ -692,7 +707,7 @@ STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Mactotexture"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TEXTURE_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TEXTURE_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,136,126
DEFPUSHBUTTON "OK",IDOK,5,140,50,14
END
@@ -756,7 +771,7 @@ BEGIN
PUSHBUTTON "Restore To Default",IDC_GlobalLightingReset,4,4,75,14
END
-IDD_LIGHT_OPTIONS DIALOG DISCARDABLE 0, 0, 122, 189
+IDD_LIGHT_OPTIONS DIALOG DISCARDABLE 0, 0, 122, 156
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Light Options"
FONT 8, "MS Sans Serif"
@@ -781,13 +796,13 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,196,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,215,50,14
- LISTBOX IDC_OPEN_LIST,15,26,155,162,LBS_SORT |
+ LISTBOX IDC_OPEN_LIST,15,26,155,162,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
LTEXT "Open Map:",IDC_STATIC,15,15,36,8
PUSHBUTTON "Browse...",IDC_BROWSE,16,195,61,16
- CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,58,6,54,16
- CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,115,6,55,16
END
@@ -798,93 +813,25 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,197,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,214,50,14
- LISTBOX IDC_SAVE_LIST,13,25,157,136,LBS_SORT |
+ LISTBOX IDC_SAVE_LIST,13,25,157,136,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Browse...",IDC_BROWSE,7,197,50,14
GROUPBOX "Map name:",IDC_STATIC,7,166,172,27
EDITTEXT IDC_SAVE_MAP_EDIT,13,175,157,12,ES_AUTOHSCROLL
- CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,66,6,54,16
- CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,123,6,55,16
LTEXT "Existing maps:",IDC_STATIC,13,15,46,8
END
-IDD_MAPOBJECT_PROPS DIALOG DISCARDABLE 0, 0, 200, 311
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
-CAPTION "Object Properties"
-FONT 8, "MS Sans Serif"
-BEGIN
- COMBOBOX IDC_MAPOBJECT_Team,31,19,166,141,CBS_DROPDOWNLIST |
- CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Team:",IDC_STATICTEAMCAPTION,3,21,21,8
- LTEXT "Name:",IDC_STATIC,3,6,22,8
- EDITTEXT IDC_MAPOBJECT_Name,31,3,166,14,ES_AUTOHSCROLL
- LTEXT "Initial Health %",IDC_STATIC,3,52,58,8
- COMBOBOX IDC_MAPOBJECT_StartingHealth,71,50,95,71,
- CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- EDITTEXT IDC_MAPOBJECT_StartingHealthEdit,172,50,25,14,
- ES_AUTOHSCROLL
- CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,3,81,58,10
- CONTROL "Indestructible",IDC_MAPOBJECT_Indestructible,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,3,106,58,10
- CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,71,81,58,10
- CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,3,93,58,10
- COMBOBOX IDC_MAPOBJECT_Script,31,34,166,67,CBS_DROPDOWNLIST |
- WS_DISABLED | WS_VSCROLL | WS_TABSTOP
- LTEXT "Script:",IDC_STATIC,3,36,21,8,WS_DISABLED
- LTEXT "Aggressiveness:",IDC_STATIC,3,122,66,8
- COMBOBOX IDC_MAPOBJECT_Aggressiveness,71,120,126,73,
- CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- EDITTEXT IDC_MAPOBJECT_VisionDistance,169,204,27,14,
- ES_AUTOHSCROLL
- LTEXT "Targetting Distance:",IDC_STATIC,82,207,83,8
- CONTROL "AI Recruitable",IDC_MAPOBJECT_RecruitableAI,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,71,105,69,10
- LTEXT "Shroud Clearing Distance:",IDC_STATIC,82,226,83,8
- EDITTEXT IDC_MAPOBJECT_ShroudClearingDistance,169,222,27,14,
- ES_AUTOHSCROLL
- LTEXT "Veterancy:",IDC_STATIC,3,138,66,8
- COMBOBOX IDC_MAPOBJECT_Veterancy,71,136,126,73,CBS_DROPDOWNLIST |
- WS_VSCROLL | WS_TABSTOP
- EDITTEXT IDC_MAPOBJECT_ZOffset,25,188,24,14,ES_AUTOHSCROLL
- LTEXT "Z:",IDC_STATIC,13,191,8,8
- EDITTEXT IDC_MAPOBJECT_Angle,25,204,24,14,ES_AUTOHSCROLL
- LTEXT "Angle:",IDC_STATIC,3,207,19,8
- PUSHBUTTON "1",IDC_HEIGHT_POPUP,51,188,8,12,BS_BITMAP
- PUSHBUTTON "1",IDC_ANGLE_POPUP,51,205,8,12,BS_BITMAP
- COMBOBOX IDC_MAPOBJECT_Weather,71,153,126,76,CBS_DROPDOWNLIST |
- WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_Time,71,169,126,65,CBS_DROPDOWNLIST |
- WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_HitPoints,71,66,126,52,CBS_DROPDOWN |
- CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Max Hitpoints",IDC_STATIC,3,67,58,8
- EDITTEXT IDC_MAPOBJECT_StoppingDistance,169,186,27,14,
- ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Stopping Distance:",IDC_STATIC,82,188,83,8
- CONTROL "Selectable",IDC_MAPOBJECT_Selectable,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,71,93,58,10
- LTEXT "Weather:",IDC_STATIC,3,155,66,8
- LTEXT "Time:",IDC_STATIC,3,171,66,8
- LISTBOX IDC_MAPOBJECT_BuildWithUpgrades,9,253,182,51,
- LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
- WS_TABSTOP
- GROUPBOX "Pre-built upgrades",IDC_STATIC,3,242,194,66
- CONTROL "Targetable",IDC_MAPOBJECT_Targetable,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,139,81,58,10
-END
-
IDD_PROPEDIT DIALOG DISCARDABLE 0, 0, 200, 84
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Property Edit"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_KEYNAME,38,7,107,14,ES_AUTOHSCROLL
- COMBOBOX IDC_KEYTYPE,38,30,107,153,CBS_DROPDOWNLIST | WS_VSCROLL |
+ COMBOBOX IDC_KEYTYPE,38,30,107,153,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_VALUE,38,50,107,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,162,7,31,14
@@ -901,24 +848,24 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Player List"
FONT 8, "MS Sans Serif"
BEGIN
- LISTBOX IDC_PLAYERS,7,7,275,69,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ LISTBOX IDC_PLAYERS,7,7,275,69,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
WS_HSCROLL | WS_TABSTOP
PUSHBUTTON "New Player",IDC_NEWPLAYER,7,254,45,14
PUSHBUTTON "Remove Player",IDC_REMOVEPLAYER,56,254,56,14
DEFPUSHBUTTON "OK",IDOK,177,274,51,14
LTEXT "Allies:",IDC_STATIC,7,133,68,8
LTEXT "Enemies:",IDC_STATIC,153,133,78,8
- LISTBOX IDC_ALLIESLIST,7,144,129,40,LBS_SORT | LBS_MULTIPLESEL |
+ LISTBOX IDC_ALLIESLIST,7,144,129,40,LBS_SORT | LBS_MULTIPLESEL |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
- LISTBOX IDC_ENEMIESLIST,153,144,129,40,LBS_SORT |
- LBS_MULTIPLESEL | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ LISTBOX IDC_ENEMIESLIST,153,144,129,40,LBS_SORT |
+ LBS_MULTIPLESEL | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
WS_TABSTOP
- LISTBOX IDC_PLAYER_ATTITUDE_OUT,7,203,129,40,NOT LBS_NOTIFY |
- LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
+ LISTBOX IDC_PLAYER_ATTITUDE_OUT,7,203,129,40,NOT LBS_NOTIFY |
+ LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
WS_TABSTOP
LTEXT "How Player Regard Others:",IDC_STATIC,7,192,86,8
- LISTBOX IDC_PLAYER_ATTITUDE_IN,153,203,129,40,NOT LBS_NOTIFY |
- LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
+ LISTBOX IDC_PLAYER_ATTITUDE_IN,153,203,129,40,NOT LBS_NOTIFY |
+ LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
WS_TABSTOP
LTEXT "How Others Regard Player:",IDC_STATIC,153,192,94,8
PUSHBUTTON "Cancel",IDCANCEL,232,274,50,14
@@ -927,10 +874,10 @@ BEGIN
EDITTEXT IDC_PLAYERDISPLAYNAME,82,100,84,14,ES_AUTOHSCROLL
CONTROL "Is Player computer-controlled?",IDC_PLAYERISCOMPUTER,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,163,87,110,10
- COMBOBOX IDC_PLAYERFACTION,178,110,96,105,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PLAYERFACTION,178,110,96,105,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "",IDC_PlayerColor,8,116,14,12
- COMBOBOX IDC_PlayerColorCombo,51,116,83,120,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PlayerColorCombo,51,116,83,120,CBS_DROPDOWNLIST |
WS_TABSTOP
PUSHBUTTON "Set Name",IDC_CHANGE_NAME,15,88,36,9
PUSHBUTTON "Add Skirmish Players",IDC_ADDSKIRMISHPLAYERS,42,274,71,
@@ -945,20 +892,20 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Build List"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_SIDES_COMBO,9,10,184,133,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_SIDES_COMBO,9,10,184,133,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Side:",IDC_STATIC,2,0,195,28
- LISTBOX IDC_BUILD_LIST,9,42,183,125,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_BUILD_LIST,9,42,183,125,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Build List",IDC_STATIC,2,31,196,167
- CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN |
+ CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN |
WS_DISABLED,16,224,177,16
GROUPBOX "Power Used:",IDC_STATIC,7,214,190,28,WS_DISABLED
CONTROL "Structure Already Built",IDC_ALREADY_BUILD,"Button",
BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_RIGHT | WS_TABSTOP,
100,169,90,10
RTEXT "Rebuilds:",IDC_STATIC,111,184,35,8
- COMBOBOX IDC_REBUILDS,149,182,43,64,CBS_DROPDOWN | WS_VSCROLL |
+ COMBOBOX IDC_REBUILDS,149,182,43,64,CBS_DROPDOWN | WS_VSCROLL |
WS_TABSTOP
PUSHBUTTON "Up",IDC_MOVE_UP,9,172,22,11
PUSHBUTTON "Down",IDC_MOVE_DOWN,9,184,22,11
@@ -1006,15 +953,19 @@ BEGIN
PUSHBUTTON "&Delete",IDC_DELETE,403,152,50,14
PUSHBUTTON "Import Scripts...",IDC_LOAD,386,309,60,14
PUSHBUTTON "Export Script(s)...",IDC_SAVE,317,309,60,14
- CONTROL "Tree1",IDC_SCRIPT_TREE,"SysTreeView32",TVS_HASBUTTONS |
- TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
+ CONTROL "Tree1",IDC_SCRIPT_TREE,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
WS_TABSTOP,7,7,386,193,WS_EX_CLIENTEDGE
PUSHBUTTON "New &Folder...",IDC_NEW_FOLDER,403,46,50,14
- EDITTEXT IDC_SCRIPT_DESCRIPTION,208,206,187,99,ES_MULTILINE |
+ EDITTEXT IDC_SCRIPT_DESCRIPTION,208,206,187,99,ES_MULTILINE |
ES_READONLY | WS_VSCROLL | WS_HSCROLL
PUSHBUTTON "Cancel",IDCANCEL,403,253,50,14
- EDITTEXT IDC_SCRIPT_COMMENT,7,206,195,99,ES_MULTILINE |
+ EDITTEXT IDC_SCRIPT_COMMENT,7,206,195,99,ES_MULTILINE |
ES_READONLY | WS_VSCROLL
+ CONTROL "Auto Verify",IDC_AUTO_VERIFY,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,261,311,52,8
+ PUSHBUTTON "&Verify",IDC_VERIFY,403,22,50,14
+ PUSHBUTTON "&Patch ""GC_""",IDC_PATCH_GC,403,169,50,14
END
IDD_ScriptTabWindow DIALOG DISCARDABLE 0, 0, 391, 255
@@ -1032,7 +983,7 @@ STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Script Conditions"
FONT 8, "MS Sans Serif"
BEGIN
- LISTBOX IDC_CONDITION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_CONDITION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Conditions for this script:",IDC_STATIC,7,14,81,8
PUSHBUTTON "New...",IDC_NEW,319,32,50,14
@@ -1050,7 +1001,7 @@ STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Actions if true."
FONT 8, "MS Sans Serif"
BEGIN
- LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Actions to take if conditions are true:",IDC_STATIC,7,
14,139,8
@@ -1070,7 +1021,7 @@ FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Actions to take if conditions are false:",IDC_STATIC,7,
14,120,8
- LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "New...",IDC_NEW,319,32,50,14
PUSHBUTTON "Edit...",IDC_EDIT,319,48,50,14
@@ -1095,11 +1046,11 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,11,69,108,10
CONTROL "Easy",IDC_EASY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
157,41,31,10
- CONTROL "Normal",IDC_NORMAL,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Normal",IDC_NORMAL,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,157,56,38,10
CONTROL "Hard",IDC_HARD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
157,71,31,10
- EDITTEXT IDC_SCRIPT_COMMENT,7,100,320,98,ES_MULTILINE |
+ EDITTEXT IDC_SCRIPT_COMMENT,7,100,320,98,ES_MULTILINE |
WS_VSCROLL
LTEXT "Script Name:",IDC_STATIC,7,12,43,8
GROUPBOX "Active in:",IDC_STATIC,151,30,58,54
@@ -1114,20 +1065,22 @@ BEGIN
LTEXT "seconds.",IDC_STATIC,283,60,30,8
END
-IDD_ScriptCondition DIALOG DISCARDABLE 0, 0, 271, 149
+IDD_ScriptCondition DIALOG DISCARDABLE 0, 0, 311, 450
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Edit Condition:"
FONT 8, "MS Sans Serif"
BEGIN
- DEFPUSHBUTTON "OK",IDOK,153,128,50,14
- PUSHBUTTON "Cancel",IDCANCEL,214,128,50,14
+ DEFPUSHBUTTON "OK",IDOK,197,429,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,254,428,50,14
CONTROL "",IDC_RICH_EDIT_HERE,"Static",SS_BLACKFRAME | SS_SUNKEN,
- 7,29,257,57
- COMBOBOX IDC_CONDITION_TYPE,7,7,257,271,CBS_DROPDOWNLIST |
- CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Warnings:",IDC_WARNINGS_CAPTION,7,89,257,36
- LTEXT "These are the freaking warnings.",IDC_WARNINGS,9,99,210,
- 26
+ 7,319,297,59
+ GROUPBOX "Warnings:",IDC_WARNINGS_CAPTION,7,378,297,45
+ LTEXT "These are the freaking warnings.",IDC_WARNINGS,9,388,
+ 210,30
+ CONTROL "Tree1",IDC_CONDITION_TREE,"SysTreeView32",
+ TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
+ TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS |
+ TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,7,7,297,308
END
IDD_EDIT_PARAMETER DIALOG DISCARDABLE 0, 0, 281, 74
@@ -1138,28 +1091,30 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,171,52,50,14
PUSHBUTTON "Cancel",IDCANCEL,224,52,50,14
GROUPBOX "Parameter:",IDC_CAPTION,7,7,267,41
- COMBOBOX IDC_COMBO,15,21,250,87,CBS_DROPDOWN | CBS_SORT |
+ COMBOBOX IDC_COMBO,15,21,250,87,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_EDIT,19,21,190,12,ES_AUTOHSCROLL
- COMBOBOX IDC_LIST,19,21,190,84,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_LIST,19,21,190,84,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
- DEFPUSHBUTTON "Preview Sound",IDC_PREVIEWSOUND,7,52,62,14
+ PUSHBUTTON "Preview Sound",IDC_PREVIEWSOUND,7,52,62,14
END
-IDD_ScriptAction DIALOG DISCARDABLE 0, 0, 270, 149
+IDD_ScriptAction DIALOG DISCARDABLE 0, 0, 311, 450
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Edit Action:"
FONT 8, "MS Sans Serif"
BEGIN
- DEFPUSHBUTTON "OK",IDOK,152,128,50,14
- PUSHBUTTON "Cancel",IDCANCEL,213,128,50,14
+ DEFPUSHBUTTON "OK",IDOK,197,429,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,254,428,50,14
CONTROL "",IDC_RICH_EDIT_HERE,"Static",SS_BLACKFRAME | SS_SUNKEN,
- 7,29,256,59
- COMBOBOX IDC_CONDITION_TYPE,7,7,256,276,CBS_DROPDOWNLIST |
- CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Warnings:",IDC_WARNINGS_CAPTION,7,89,256,36
- LTEXT "These are the freaking warnings.",IDC_WARNINGS,9,99,210,
- 26
+ 7,319,297,59
+ GROUPBOX "Warnings:",IDC_WARNINGS_CAPTION,7,378,297,45
+ LTEXT "These are the freaking warnings.",IDC_WARNINGS,9,388,
+ 210,30
+ CONTROL "Tree1",IDC_ACTION_TREE,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
+ TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_TRACKSELECT |
+ WS_BORDER | WS_TABSTOP,7,7,297,308
END
IDD_TEAMS_DIALOG DIALOG DISCARDABLE 0, 0, 515, 294
@@ -1171,9 +1126,9 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,458,273,50,14
PUSHBUTTON "Add New Team",IDC_NEWTEAM,7,273,56,14
PUSHBUTTON "Delete Team",IDC_DELETETEAM,121,273,54,14
- LISTBOX IDC_PLAYER_LIST,7,7,105,263,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_PLAYER_LIST,7,7,105,263,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
- CONTROL "List1",IDC_TEAMS_LIST,"SysListView32",LVS_REPORT |
+ CONTROL "List1",IDC_TEAMS_LIST,"SysListView32",LVS_REPORT |
LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,116,7,392,263
PUSHBUTTON "Copy Team",IDC_COPYTEAM,67,273,50,14
PUSHBUTTON "Select Team Members...",IDC_SelectTeamMembers,179,273,
@@ -1221,7 +1176,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,29,157,50,14
PUSHBUTTON "Cancel",IDCANCEL,88,157,50,14
GROUPBOX "Object:",IDC_CAPTION,7,7,131,145
- CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,15,20,114,126
END
@@ -1232,38 +1187,38 @@ FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_MAX,177,2,27,14,ES_AUTOHSCROLL
RTEXT "Home Position:",IDC_STATIC,2,37,53,8
- COMBOBOX IDC_HOME_WAYPOINT,58,36,113,228,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_HOME_WAYPOINT,58,36,113,228,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Min:",IDC_STATIC,6,122,14,8
LTEXT "Max:",IDC_STATIC,24,122,16,8
LTEXT "Unit Type:",IDC_STATIC,50,122,91,8
EDITTEXT IDC_MIN_UNIT1,2,131,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT1,24,131,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE1,47,131,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE1,47,131,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT2,2,145,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT2,23,145,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE2,47,145,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE2,47,145,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT3,2,159,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT3,24,159,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE3,47,159,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE3,47,159,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT4,2,173,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT4,24,173,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE4,47,173,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE4,47,173,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT5,2,187,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT5,24,187,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE5,47,187,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE5,47,187,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT6,2,201,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT6,24,201,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE6,47,201,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE6,47,201,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT7,2,215,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT7,24,215,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE7,47,215,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE7,47,215,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Team Description:",IDC_STATIC,0,285,213,38
EDITTEXT IDC_DESCRIPTION,8,294,195,27,ES_AUTOHSCROLL
@@ -1275,7 +1230,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,255,164,9
LTEXT "Maximum Quantity:",IDC_STATIC,116,4,59,8
RTEXT "Condition:",IDC_STATIC,11,62,47,8
- COMBOBOX IDC_PRODUCTION_CONDITION,64,59,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PRODUCTION_CONDITION,64,59,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Production:",IDC_STATIC,1,53,212,66
RTEXT "Priority:",IDC_STATIC,3,89,24,8
@@ -1292,7 +1247,7 @@ BEGIN
PUSHBUTTON "...",IDC_UNIT_TYPE6_BUTTON,197,201,12,12
PUSHBUTTON "...",IDC_UNIT_TYPE7_BUTTON,197,215,12,12
EDITTEXT IDC_TEAM_NAME,2,1,107,14,ES_AUTOHSCROLL
- COMBOBOX IDC_TEAMOWNER,58,20,113,176,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_TEAMOWNER,58,20,113,176,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
RTEXT "Owner:",IDC_STATIC,2,24,53,8
CONTROL "Team created once and only once.",IDC_TEAM_SINGLETON,
@@ -1301,7 +1256,7 @@ BEGIN
EDITTEXT IDC_TEAM_BUILD_FRAMES,32,101,25,12,ES_AUTOHSCROLL
LTEXT "frames.",IDC_STATIC,58,103,24,9
CONTROL "Execute associated actions",
- IDC_PRODUCTION_EXECUTEACTIONS,"Button",BS_AUTOCHECKBOX |
+ IDC_PRODUCTION_EXECUTEACTIONS,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,63,76,103,10
END
@@ -1311,22 +1266,22 @@ CAPTION "Reinforcement"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "If reinforcing, then:",IDC_STATIC,13,7,184,87
- CONTROL "Deploy by",IDC_DEPLOY_BY,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Deploy by",IDC_DEPLOY_BY,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,19,23,44,9
- COMBOBOX IDC_TRANSPORT_COMBO,66,21,126,140,CBS_DROPDOWN |
+ COMBOBOX IDC_TRANSPORT_COMBO,66,21,126,140,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Veterancy Level",IDC_STATIC,15,109,141,42
- COMBOBOX IDC_VETERANCY,23,124,124,60,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_VETERANCY,23,124,124,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
CONTROL "Transports exit map after unloading.",
- IDC_TRANSPORTS_EXIT,"Button",BS_AUTOCHECKBOX |
+ IDC_TRANSPORTS_EXIT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,66,36,124,11
CONTROL "Load members into transports (if applicable).",
- IDC_TEAM_STARTS_FULL,"Button",BS_AUTOCHECKBOX |
+ IDC_TEAM_STARTS_FULL,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,19,78,166,11
GROUPBOX "Start team or transports at waypoint:",IDC_STATIC,19,50,
171,26
- COMBOBOX IDC_WAYPOINT_COMBO,25,60,160,176,CBS_DROPDOWN | CBS_SORT |
+ COMBOBOX IDC_WAYPOINT_COMBO,25,60,160,176,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
END
@@ -1338,36 +1293,36 @@ BEGIN
GROUPBOX "Behavior Script Triggers:",IDC_STATIC,7,7,216,107
GROUPBOX "Behavior Options",IDC_STATIC,7,141,216,106
RTEXT "On Create:",IDC_STATIC,23,25,51,8
- COMBOBOX IDC_ON_CREATE_SCRIPT,85,22,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_CREATE_SCRIPT,85,22,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
RTEXT "On Enemy Sighted:",IDC_STATIC,13,44,61,8
- COMBOBOX IDC_ON_ENEMY_SIGHTED,85,43,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_ENEMY_SIGHTED,85,43,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_ON_DESTROYED,85,80,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_DESTROYED,85,80,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
RTEXT "On Destroyed %",IDC_STATIC,10,81,51,8
EDITTEXT IDC_PERCENT_DESTROYED,62,80,18,12,ES_AUTOHSCROLL
- COMBOBOX IDC_ENEMY_INTERACTIONS,19,182,159,69,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ENEMY_INTERACTIONS,19,182,159,69,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Initial Team Behavior",IDC_STATIC,15,172,172,27
CONTROL "Transports return to base after unloading.",
- IDC_TRANSPORTS_RETURN,"Button",BS_AUTOCHECKBOX |
+ IDC_TRANSPORTS_RETURN,"Button",BS_AUTOCHECKBOX |
WS_DISABLED | WS_TABSTOP,15,151,179,8
CONTROL "Team avoids threats.",IDC_AVOID_THREATS,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,15,162,179,8
RTEXT "On All Clear:",IDC_STATIC,13,59,61,8
- COMBOBOX IDC_ON_ALL_CLEAR,85,58,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_ALL_CLEAR,85,58,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "",IDC_STATIC,7,36,216,37
RTEXT "On Idle:",IDC_STATIC,23,99,51,8
- COMBOBOX IDC_ON_IDLE_SCRIPT,85,96,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_IDLE_SCRIPT,85,96,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Behavior Scirpt Triggers:",IDC_STATIC,7,7,216,131
RTEXT "On Unit Destroyed:",IDC_STATIC,13,119,61,8
COMBOBOX IDC_ON_UNIT_DESTROYED_SCRIPT,85,116,132,173,
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "Does this team focus on a single target at a time ",
- IDC_ATTACK_COMMON_TARGET,"Button",BS_AUTOCHECKBOX |
+ IDC_ATTACK_COMMON_TARGET,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,22,215,173,8
GROUPBOX "Attack:",IDC_STATIC,15,204,181,34
LTEXT "in Hard and Brutal (never in Normal)?",IDC_STATIC,35,
@@ -1379,8 +1334,8 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Export Script Options"
FONT 8, "MS Sans Serif"
BEGIN
- DEFPUSHBUTTON "OK",IDOK,69,132,50,14
- PUSHBUTTON "Cancel",IDCANCEL,129,132,50,14
+ DEFPUSHBUTTON "OK",IDOK,69,152,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,129,152,50,14
CONTROL "Include waypoints and waypoint paths.",IDC_WAYPOINTS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,20,150,8
CONTROL "Include trigger areas.",IDC_TRIGGERS,"Button",
@@ -1388,37 +1343,39 @@ BEGIN
CONTROL "Include units and buildings.",IDC_UNITS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,12,61,154,9
GROUPBOX "Include items referenced in the scripts:",IDC_STATIC,7,
- 7,172,73
+ 7,172,88
CONTROL "Export all scripts.",IDC_ALL_SCRIPTS,"Button",
- BS_AUTORADIOBUTTON,15,94,97,8
+ BS_AUTORADIOBUTTON,15,115,97,8
CONTROL "Export selected scripts.",IDC_SELECTED_SCRIPTS,"Button",
- BS_AUTORADIOBUTTON,15,106,99,8
- GROUPBOX "Export Mode:",IDC_STATIC,7,83,172,39
+ BS_AUTORADIOBUTTON,15,127,99,8
+ GROUPBOX "Export Mode:",IDC_STATIC,7,104,172,39
+ CONTROL "Include sides.",IDC_SIDES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,12,79,154,9
END
-IDD_GROVE_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 173
+IDD_GROVE_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 166
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Grove Options"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_Grove_Type1,32,21,164,81,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type1,32,21,164,81,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
LTEXT "%",IDC_STATIC,15,11,8,8
EDITTEXT IDC_Grove_Per1,8,21,20,13,ES_AUTOHSCROLL | ES_NUMBER
- COMBOBOX IDC_Grove_Type2,32,36,164,80,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type2,32,36,164,80,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per2,8,36,20,13,ES_AUTOHSCROLL | ES_NUMBER
- COMBOBOX IDC_Grove_Type3,32,51,164,77,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type3,32,51,164,77,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per3,8,51,20,13,ES_AUTOHSCROLL | ES_NUMBER
- COMBOBOX IDC_Grove_Type4,32,66,164,78,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type4,32,66,164,78,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per4,8,66,20,13,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Tree Type",IDC_STATIC,34,11,34,8
- EDITTEXT IDC_Grove_PerTotal,8,97,20,13,ES_AUTOHSCROLL |
+ EDITTEXT IDC_Grove_PerTotal,8,97,20,13,ES_AUTOHSCROLL |
ES_READONLY | ES_NUMBER
LTEXT "% Total",IDC_STATIC,33,99,24,8
- COMBOBOX IDC_Grove_Type5,32,81,164,77,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type5,32,81,164,77,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per5,8,81,20,13,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_Grove_NumberTrees,8,115,40,14,ES_AUTOHSCROLL
@@ -1429,12 +1386,12 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,146,81,10
END
-IDD_FENCE_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 245
+IDD_FENCE_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 206
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Fence options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,126
EDITTEXT IDC_FENCE_SPACING_EDIT,146,143,49,12,ES_AUTOHSCROLL
LTEXT "Fence spacing:",IDC_STATIC,74,145,68,8
@@ -1442,14 +1399,14 @@ BEGIN
179,190,25
END
-IDD_BLEND_MATERIAL DIALOG DISCARDABLE 0, 0, 200, 245
+IDD_BLEND_MATERIAL DIALOG DISCARDABLE 0, 0, 200, 217
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Blend Material Options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,126
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,65,137,65,55
LTEXT "Gravel",IDC_TERRAIN_NAME,67,197,86,9
END
@@ -1461,9 +1418,9 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,19,76,50,14
PUSHBUTTON "Cancel",IDCANCEL,79,76,50,14
- LTEXT "Which faction does the player use?",IDC_STATIC,7,7,143,
- 36
- COMBOBOX IDC_COMBO1,7,46,143,260,CBS_DROPDOWNLIST | CBS_SORT |
+ LTEXT "Which of the following PlayerTemplates shall I use to add the Player you need?",
+ IDC_STATIC,7,7,143,36
+ COMBOBOX IDC_COMBO1,7,46,143,260,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
END
@@ -1474,7 +1431,7 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,210,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,210,24,50,14
- CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,7,7,198,284
END
@@ -1492,7 +1449,7 @@ BEGIN
ES_AUTOHSCROLL | WS_DISABLED
CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,71,131,10
- COMBOBOX IDC_MAPOBJECT_Script,41,31,166,67,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Script,41,31,166,67,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Script:",IDC_STATIC,7,34,21,8
END
@@ -1515,12 +1472,12 @@ BEGIN
LTEXT "Ramp Width:",IDC_STATIC,7,15,42,14,SS_CENTERIMAGE
END
-IDD_SCORCH_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 181
+IDD_SCORCH_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 86
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Scorch Options"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_SCORCHTYPE,7,15,186,88,CBS_DROPDOWNLIST | WS_VSCROLL |
+ COMBOBOX IDC_SCORCHTYPE,7,15,186,88,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_SIZE_EDIT,60,37,17,12,ES_AUTOHSCROLL
PUSHBUTTON "1",IDC_SIZE_POPUP,79,37,8,12,BS_BITMAP
@@ -1535,18 +1492,18 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,70,242,50,14
PUSHBUTTON "Cancel",IDCANCEL,138,242,50,14
- COMBOBOX IDC_MAP_WEATHER,62,54,112,104,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAP_WEATHER,62,54,112,104,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
RTEXT "Time",IDC_STATIC,7,40,49,8
- COMBOBOX IDC_MAP_TIMEOFDAY,62,38,112,97,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAP_TIMEOFDAY,62,38,112,97,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
RTEXT "Weather",IDC_STATIC,8,56,49,8
EDITTEXT IDC_MAP_TITLE,62,7,112,12,ES_AUTOHSCROLL
- EDITTEXT IDC_MAP_DESCRIPTION,7,73,181,155,ES_MULTILINE |
+ EDITTEXT IDC_MAP_DESCRIPTION,7,73,181,155,ES_MULTILINE |
ES_AUTOHSCROLL | WS_VSCROLL | WS_HSCROLL
RTEXT "Map Name",IDC_STATIC,7,7,49,10
RTEXT "Compression",IDC_STATIC,7,24,49,8
- COMBOBOX IDC_MAP_COMPRESSION,62,22,112,97,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAP_COMPRESSION,62,22,112,97,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
END
@@ -1555,8 +1512,8 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Layers List"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "Tree1",IDC_LL_TREE,"SysTreeView32",TVS_HASBUTTONS |
- TVS_LINESATROOT | TVS_EDITLABELS | TVS_DISABLEDRAGDROP |
+ CONTROL "Tree1",IDC_LL_TREE,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_LINESATROOT | TVS_EDITLABELS | TVS_DISABLEDRAGDROP |
WS_TABSTOP,7,7,207,148
END
@@ -1567,7 +1524,7 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,210,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,210,24,50,14
- CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,7,24,198,267
LTEXT "Static",IDC_MISSINGLABEL,7,7,195,8
END
@@ -1578,7 +1535,7 @@ CAPTION "Water Options"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "Water Area Name:",IDC_STATIC,1,1,195,34
- COMBOBOX IDC_WATERNAME_EDIT,7,15,186,88,CBS_DROPDOWN | CBS_SORT |
+ COMBOBOX IDC_WATERNAME_EDIT,7,15,186,88,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Water Height:",IDC_WATER_HEIGHT1,1,40,195,33
EDITTEXT IDC_HEIGHT_EDIT,70,52,17,12,ES_AUTOHSCROLL
@@ -1586,40 +1543,43 @@ BEGIN
PUSHBUTTON "1",IDC_HEIGHT_POPUP,89,52,8,12,BS_BITMAP
CONTROL "Create Water Polygon",IDC_WATER_POLYGON,"Button",
BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,31,89,99,16
- CONTROL "River",IDC_MAKE_RIVER,"Button",BS_AUTOCHECKBOX |
+ CONTROL "River",IDC_MAKE_RIVER,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,31,119,98,16
GROUPBOX "Point spacing for water polygons and rivers.",
IDC_STATIC,13,140,168,29
EDITTEXT IDC_SPACING,49,153,63,12,ES_AUTOHSCROLL
END
-IDD_CAMERA_OPTIONS DIALOG DISCARDABLE 0, 0, 142, 94
+IDD_CAMERA_OPTIONS DIALOG DISCARDABLE 0, 0, 144, 162
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Camera Options"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_PITCH_EDIT,89,11,27,12,ES_AUTOHSCROLL
PUSHBUTTON "1",IDC_PITCH_POPUP,121,11,9,12,BS_BITMAP
- GROUPBOX "Pitch",-1,83,1,55,29
+ GROUPBOX "Pitch",-1,85,1,55,29
PUSHBUTTON "Restore To Default",IDC_CameraReset,4,4,75,14
LTEXT "Height above ground:",-1,7,33,73,10
LTEXT "Zoom:",-1,7,44,25,10
- LTEXT "(1.0 = max, 0.0 = min)",-1,58,44,80,10
+ LTEXT "(1.0 == max, 0.0 == min)",-1,60,44,80,10
LTEXT "",IDC_ZOOMTEXT,29,44,27,10
- LTEXT "",IDC_HEIGHTTEXT,84,33,54,10
+ LTEXT "",IDC_HEIGHTTEXT,86,33,54,10
LTEXT "Position:",-1,7,66,28,10
- LTEXT "",IDC_POSTEXT,35,65,103,10
+ LTEXT "",IDC_POSTEXT,37,65,103,10
LTEXT "Target:",-1,7,76,28,10
- LTEXT "",IDC_TARGETTEXT,35,75,103,10
+ LTEXT "",IDC_TARGETTEXT,37,75,103,10
+ PUSHBUTTON "Drop Waypoint",IDC_DROP_WAYPOINT_BUTTON,33,97,82,14
+ PUSHBUTTON "Center Camera On Selected Object",
+ IDC_CENTER_ON_SELECTED,13,128,116,14
END
-IDD_WAYPOINT_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 212
+IDD_WAYPOINT_OPTIONS DIALOG DISCARDABLE 0, 0, 200, 186
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Waypoint Options"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "Waypoint Name:",IDC_WAYPOINT_CAPTION1,1,1,195,34
- COMBOBOX IDC_WAYPOINTNAME_EDIT,7,15,186,88,CBS_DROPDOWN |
+ COMBOBOX IDC_WAYPOINTNAME_EDIT,7,15,186,88,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_WAYPOINTLABEL1_EDIT,7,119,182,12,ES_AUTOHSCROLL
EDITTEXT IDC_WAYPOINTLABEL2_EDIT,8,134,182,12,ES_AUTOHSCROLL
@@ -1633,7 +1593,7 @@ BEGIN
EDITTEXT IDC_WAYPOINT_LOCATIONY,111,50,69,12,ES_AUTOHSCROLL
GROUPBOX "List of Current Waypoints:",IDC_LIST_WAYPOINTS,1,74,195,
28
- COMBOBOX IDC_LIST_OF_WAYPOINT_NAMES,7,85,183,88,CBS_DROPDOWN |
+ COMBOBOX IDC_LIST_OF_WAYPOINT_NAMES,7,85,183,88,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "Bi-Directional",IDC_WAYPOINT_BIDIRECTIONAL,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,11,172,132,9
@@ -1647,7 +1607,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,99,110,50,14
PUSHBUTTON "Cancel",IDCANCEL,152,110,50,14
LTEXT "REPLACEIT",IDC_REPLACETHISTEXT,7,7,195,19
- LISTBOX IDC_VALIDTEAMLIST,7,27,195,82,LBS_SORT |
+ LISTBOX IDC_VALIDTEAMLIST,7,27,195,82,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
@@ -1656,62 +1616,62 @@ STYLE WS_CHILD | WS_CAPTION
CAPTION "Generic"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_TeamGeneric_Script1,58,13,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script1,58,13,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 1:",IDC_SCRIPT_PREFIX1,6,14,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script2,58,31,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script2,58,31,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 2:",IDC_SCRIPT_PREFIX2,6,32,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script3,58,49,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script3,58,49,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 3:",IDC_SCRIPT_PREFIX3,6,50,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script4,58,67,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script4,58,67,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 4:",IDC_SCRIPT_PREFIX4,6,68,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script5,58,85,160,67,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script5,58,85,160,67,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 5:",IDC_SCRIPT_PREFIX5,6,86,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script6,58,103,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script6,58,103,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 6:",IDC_SCRIPT_PREFIX6,6,104,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script7,58,121,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script7,58,121,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 7:",IDC_SCRIPT_PREFIX7,6,122,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script8,58,139,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script8,58,139,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 8:",IDC_SCRIPT_PREFIX8,6,140,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script9,58,157,160,67,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script9,58,157,160,67,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 9:",IDC_SCRIPT_PREFIX9,6,158,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script10,58,175,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script10,58,175,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 10:",IDC_SCRIPT_PREFIX10,6,176,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script11,58,193,160,65,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script11,58,193,160,65,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 11:",IDC_SCRIPT_PREFIX11,6,194,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script12,58,211,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script12,58,211,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 12:",IDC_SCRIPT_PREFIX12,6,212,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script13,58,229,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script13,58,229,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 13:",IDC_SCRIPT_PREFIX13,6,230,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script14,58,247,160,65,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script14,58,247,160,65,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 14:",IDC_SCRIPT_PREFIX14,6,248,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script15,58,265,160,67,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script15,58,265,160,67,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 15:",IDC_SCRIPT_PREFIX15,6,266,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script16,58,283,160,73,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script16,58,283,160,73,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 16:",IDC_SCRIPT_PREFIX16,6,284,47,12,
SS_CENTERIMAGE
@@ -1729,6 +1689,180 @@ BEGIN
DEFPUSHBUTTON "Preview",IDC_PREVIEW,7,52,50,14
END
+IDD_RULER_OPTIONS DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
+CAPTION "Ruler Options"
+FONT 8, "MS Sans Serif"
+BEGIN
+ LTEXT "Diameter:",IDC_STATIC,39,25,35,9
+ EDITTEXT IDC_RULER_WIDTH,83,21,54,14,ES_AUTOHSCROLL
+ CONTROL "Circular Measurements:",IDC_CHECK_RULER,"Button",
+ BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,40,51,95,14
+END
+
+IDD_TeamObjectProperties DIALOG DISCARDABLE 0, 0, 213, 327
+STYLE DS_MODALFRAME | WS_CHILD | WS_DISABLED | WS_CAPTION | WS_SYSMENU
+CAPTION "Common Object Properties"
+FONT 8, "MS Sans Serif"
+BEGIN
+ LTEXT "Initial Health %",IDC_STATIC,11,57,58,8,WS_DISABLED
+ COMBOBOX IDC_MAPOBJECT_StartingHealth,79,54,95,71,
+ CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_MAPOBJECT_StartingHealthEdit,180,54,25,14,
+ ES_AUTOHSCROLL | WS_DISABLED
+ CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
+ WS_DISABLED | WS_TABSTOP,11,86,58,10
+ CONTROL "Indestructible",IDC_MAPOBJECT_Indestructible,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,11,110,58,10
+ CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,79,86,58,10
+ CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
+ WS_DISABLED | WS_TABSTOP,11,97,58,10
+ LTEXT "Aggressiveness:",IDC_STATIC,11,126,66,8,WS_DISABLED
+ COMBOBOX IDC_MAPOBJECT_Aggressiveness,79,124,126,73,
+ CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_MAPOBJECT_VisionDistance,177,209,27,14,
+ ES_AUTOHSCROLL | WS_DISABLED
+ LTEXT "Targetting Distance:",IDC_STATIC,90,211,83,8,
+ WS_DISABLED
+ CONTROL "AI Recruitable",IDC_MAPOBJECT_RecruitableAI,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,79,110,69,10
+ LTEXT "Shroud Clearing Distance:",IDC_STATIC,90,230,83,8,
+ WS_DISABLED
+ EDITTEXT IDC_MAPOBJECT_ShroudClearingDistance,177,226,27,14,
+ ES_AUTOHSCROLL | WS_DISABLED
+ LTEXT "Veterancy:",IDC_STATIC,11,142,66,8,WS_DISABLED
+ COMBOBOX IDC_MAPOBJECT_Veterancy,79,140,126,73,CBS_DROPDOWNLIST |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_Weather,79,158,126,76,CBS_DROPDOWNLIST |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_Time,79,174,126,65,CBS_DROPDOWNLIST |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_HitPoints,79,70,126,52,CBS_DROPDOWN |
+ CBS_SORT | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Max Hitpoints",IDC_STATIC,11,71,58,8,WS_DISABLED
+ EDITTEXT IDC_MAPOBJECT_StoppingDistance,177,190,27,14,
+ ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED
+ LTEXT "Stopping Distance:",IDC_STATIC,90,193,83,8,WS_DISABLED
+ CONTROL "Selectable",IDC_MAPOBJECT_Selectable,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,79,97,58,10
+ LTEXT "Weather:",IDC_STATIC,11,159,66,8,WS_DISABLED
+ LTEXT "Time:",IDC_STATIC,11,175,66,8,WS_DISABLED
+ DEFPUSHBUTTON "Update Team Members",IDC_UPDATE_TEAM_MEMBERS,53,278,107,
+ 14,WS_DISABLED | WS_GROUP
+END
+
+IDD_MAPOBJECT_PROPS DIALOG DISCARDABLE 0, 0, 205, 382
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
+CAPTION "Object Properties"
+FONT 8, "MS Sans Serif"
+BEGIN
+ EDITTEXT IDC_MAPOBJECT_Name,33,11,160,12,ES_AUTOHSCROLL |
+ WS_GROUP
+ COMBOBOX IDC_MAPOBJECT_Team,33,26,160,141,CBS_DROPDOWNLIST |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_Script,33,40,160,67,CBS_DROPDOWNLIST |
+ WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_StartingHealth,64,64,34,71,
+ CBS_DROPDOWNLIST | WS_VSCROLL | WS_GROUP | WS_TABSTOP
+ EDITTEXT IDC_MAPOBJECT_StartingHealthEdit,101,64,25,14,
+ ES_AUTOHSCROLL
+ COMBOBOX IDC_MAPOBJECT_HitPoints,63,83,66,52,CBS_DROPDOWN |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_Aggressiveness,63,101,65,73,
+ CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_Veterancy,63,119,65,73,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,133,63,42,10
+ CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,133,73,49,10
+ CONTROL "Targetable",IDC_MAPOBJECT_Targetable,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,133,83,50,10
+ CONTROL "Indestructible",IDC_MAPOBJECT_Indestructible,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,133,93,58,10
+ CONTROL "AI Recruitable",IDC_MAPOBJECT_RecruitableAI,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,133,103,61,10
+ CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,133,113,44,10
+ CONTROL "Selectable",IDC_MAPOBJECT_Selectable2,"Button",
+ BS_AUTO3STATE | WS_TABSTOP,133,123,49,10
+ EDITTEXT IDC_MAPOBJECT_StoppingDistance,41,140,27,12,
+ ES_AUTOHSCROLL | ES_NUMBER | WS_GROUP
+ EDITTEXT IDC_MAPOBJECT_VisionDistance,105,140,27,12,
+ ES_AUTOHSCROLL
+ EDITTEXT IDC_MAPOBJECT_ShroudClearingDistance,163,140,27,12,
+ ES_AUTOHSCROLL
+ EDITTEXT IDC_MAPOBJECT_XYPosition,38,172,93,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_MAPOBJECT_ZOffset,158,172,24,12,ES_AUTOHSCROLL
+ PUSHBUTTON "1",IDC_HEIGHT_POPUP,185,171,8,12,BS_BITMAP
+ EDITTEXT IDC_MAPOBJECT_Angle,158,188,24,12,ES_AUTOHSCROLL
+ PUSHBUTTON "1",IDC_ANGLE_POPUP,185,188,8,12,BS_BITMAP
+ COMBOBOX IDC_MAPOBJECT_Weather,39,188,93,76,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_GROUP | WS_TABSTOP
+ COMBOBOX IDC_MAPOBJECT_Time,39,204,93,65,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_SOUND_COMBO,66,232,127,160,CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_GROUP |
+ WS_TABSTOP
+ CONTROL "Customize",IDC_CUSTOMIZE_CHECKBOX,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,14,247,55,10
+ CONTROL "Enabled",IDC_ENABLED_CHECKBOX,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,78,247,50,10
+ CONTROL "Looping",IDC_LOOPING_CHECKBOX,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,142,247,50,10
+ EDITTEXT IDC_LOOPCOUNT_EDIT,53,258,40,12,ES_AUTOHSCROLL |
+ ES_NUMBER
+ COMBOBOX IDC_PRIORITY_COMBO,127,258,65,70,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_VOLUME_EDIT,53,274,40,12,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_MIN_VOLUME_EDIT,146,274,45,12,ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_MIN_RANGE_EDIT,53,290,40,12,ES_AUTOHSCROLL |
+ ES_NUMBER
+ EDITTEXT IDC_MAX_RANGE_EDIT,146,290,45,12,ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "No Scale",IDC_SCALE_OFF,"Button",BS_AUTORADIOBUTTON |
+ NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,120,207,45,10
+ CONTROL "z",IDC_SCALE_ON,"Button",BS_AUTORADIOBUTTON | NOT
+ WS_VISIBLE | WS_DISABLED | WS_TABSTOP,153,208,8,10
+ EDITTEXT IDC_MAPOBJECT_Scale,163,204,24,14,ES_AUTOHSCROLL | NOT
+ WS_VISIBLE | WS_DISABLED
+ PUSHBUTTON "1",IDC_SCALE_POPUP,189,206,8,12,BS_BITMAP | NOT
+ WS_VISIBLE | WS_DISABLED
+ LISTBOX IDC_MAPOBJECT_BuildWithUpgrades,7,318,184,50,
+ LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
+ WS_GROUP | WS_TABSTOP
+ GROUPBOX "General",IDC_STATIC_MAPOBJECT_GENERAL,4,2,193,54
+ GROUPBOX "Logical",IDC_STATIC_MAPOBJECT_LOGICAL,4,56,193,105
+ GROUPBOX "Sound",IDC_STATIC_MAPOBJECT_SOUND,4,223,193,82
+ GROUPBOX "Visual",IDC_STATIC_MAPOBJECT_VISUAL,4,163,193,58
+ LTEXT "Attached Sound:",IDC_STATIC,10,234,54,8
+ LTEXT "Loop Count:",IDC_STATIC,8,258,40,8
+ LTEXT "Volume:",IDC_STATIC,22,276,26,8
+ LTEXT "Min Volume:",IDC_STATIC,102,276,40,8
+ LTEXT "Min Range:",IDC_STATIC,10,294,38,8
+ LTEXT "Max Range:",IDC_STATIC,102,294,40,8
+ LTEXT "Priority:",IDC_STATIC,102,258,24,8
+ LTEXT "Initial Health %",IDC_STATIC,13,67,47,8
+ LTEXT "Max HP",IDC_STATIC,34,84,26,8
+ RTEXT "Aggressiveness:",IDC_STATIC,8,102,52,8
+ RTEXT "Veterancy:",IDC_STATIC,25,120,35,8
+ LTEXT "Stopping:",IDC_STATIC,10,143,31,8
+ LTEXT "Targeting:",IDC_STATIC,72,143,33,8
+ LTEXT "Shroud:",IDC_STATIC,136,143,26,8
+ GROUPBOX "Distance",IDC_MAPOBJECT_DISTANCE,7,131,188,27
+ LTEXT "Name:",IDC_STATIC,9,13,22,8
+ LTEXT "Team:",IDC_STATICTEAMCAPTION,9,28,21,8
+ LTEXT "Script:",IDC_STATIC,9,42,21,8,WS_DISABLED
+ RTEXT "Weather:",IDC_STATIC,7,191,30,8
+ RTEXT "Time:",IDC_STATIC,19,206,18,8
+ LTEXT "Angle:",IDC_STATIC,136,191,21,8
+ LTEXT "Z:",IDC_STATIC,146,174,8,8
+ GROUPBOX "Pre-built upgrades",IDC_STATIC,4,307,193,67
+ RTEXT "XY Pos:",IDC_STATIC,8,174,26,8
+END
+
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
@@ -1782,7 +1916,7 @@ END
//
#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE
+GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
@@ -1818,7 +1952,7 @@ BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 195
TOPMARGIN, 5
- BOTTOMMARGIN, 294
+ BOTTOMMARGIN, 282
END
IDD_MOUND_OPTIONS, DIALOG
@@ -1826,7 +1960,7 @@ BEGIN
LEFTMARGIN, 1
RIGHTMARGIN, 196
TOPMARGIN, 1
- BOTTOMMARGIN, 180
+ BOTTOMMARGIN, 143
END
IDD_OBJECT_OPTIONS, DIALOG
@@ -1871,7 +2005,7 @@ BEGIN
LEFTMARGIN, 1
RIGHTMARGIN, 196
TOPMARGIN, 1
- BOTTOMMARGIN, 215
+ BOTTOMMARGIN, 183
END
IDD_MESHMOLD_OPTIONS, DIALOG
@@ -1903,7 +2037,7 @@ BEGIN
LEFTMARGIN, 1
RIGHTMARGIN, 118
TOPMARGIN, 1
- BOTTOMMARGIN, 186
+ BOTTOMMARGIN, 153
END
IDD_OPEN_MAP, DIALOG
@@ -1922,14 +2056,6 @@ BEGIN
BOTTOMMARGIN, 227
END
- IDD_MAPOBJECT_PROPS, DIALOG
- BEGIN
- LEFTMARGIN, 3
- RIGHTMARGIN, 197
- TOPMARGIN, 3
- BOTTOMMARGIN, 308
- END
-
IDD_PROPEDIT, DIALOG
BEGIN
LEFTMARGIN, 7
@@ -2026,9 +2152,9 @@ BEGIN
IDD_ScriptAction, DIALOG
BEGIN
LEFTMARGIN, 7
- RIGHTMARGIN, 263
+ RIGHTMARGIN, 304
TOPMARGIN, 7
- BOTTOMMARGIN, 142
+ BOTTOMMARGIN, 443
END
IDD_TEAMS_DIALOG, DIALOG
@@ -2097,7 +2223,7 @@ BEGIN
LEFTMARGIN, 2
RIGHTMARGIN, 196
TOPMARGIN, 7
- BOTTOMMARGIN, 166
+ BOTTOMMARGIN, 159
END
IDD_FENCE_OPTIONS, DIALOG
@@ -2105,7 +2231,7 @@ BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 195
TOPMARGIN, 5
- BOTTOMMARGIN, 241
+ BOTTOMMARGIN, 202
END
IDD_BLEND_MATERIAL, DIALOG
@@ -2113,7 +2239,7 @@ BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 195
TOPMARGIN, 5
- BOTTOMMARGIN, 241
+ BOTTOMMARGIN, 213
END
IDD_ADDPLAYER, DIALOG
@@ -2153,7 +2279,7 @@ BEGIN
LEFTMARGIN, 1
RIGHTMARGIN, 196
TOPMARGIN, 1
- BOTTOMMARGIN, 177
+ BOTTOMMARGIN, 82
END
IDD_MAP_SETTINGS, DIALOG
@@ -2201,7 +2327,7 @@ BEGIN
LEFTMARGIN, 1
RIGHTMARGIN, 196
TOPMARGIN, 1
- BOTTOMMARGIN, 208
+ BOTTOMMARGIN, 182
END
IDD_CHANGE_TEAM_OWNER, DIALOG
@@ -2227,6 +2353,27 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 66
END
+
+ IDD_RULER_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+
+ IDD_TeamObjectProperties, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 321
+ END
+
+ IDD_MAPOBJECT_PROPS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 197
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 374
+ END
END
#endif // APSTUDIO_INVOKED
@@ -2274,186 +2421,201 @@ IDC_SCORCH CURSOR DISCARDABLE "IDC_Scorch.cur"
IDD_PROPEDIT DLGINIT
BEGIN
IDC_KEYTYPE, 0x403, 5, 0
-0x6f42, 0x6c6f, "\000"
+0x6f42, 0x6c6f, "\000"
IDC_KEYTYPE, 0x403, 4, 0
-0x6e49, 0x0074,
+0x6e49, 0x0074,
IDC_KEYTYPE, 0x403, 5, 0
-0x6552, 0x6c61, "\000"
+0x6552, 0x6c61, "\000"
IDC_KEYTYPE, 0x403, 6, 0
-0x7341, 0x6963, 0x0069,
+0x7341, 0x6963, 0x0069,
IDC_KEYTYPE, 0x403, 8, 0
-0x6e55, 0x6369, 0x646f, 0x0065,
+0x6e55, 0x6369, 0x646f, 0x0065,
0
END
IDD_BUILD_LIST_PANEL DLGINIT
BEGIN
IDC_REBUILDS, 0x403, 5, 0
-0x6f4e, 0x656e, "\000"
+0x6f4e, 0x656e, "\000"
IDC_REBUILDS, 0x403, 2, 0
-0x0031,
+0x0031,
IDC_REBUILDS, 0x403, 2, 0
-0x0032,
+0x0032,
IDC_REBUILDS, 0x403, 2, 0
-0x0033,
+0x0033,
IDC_REBUILDS, 0x403, 2, 0
-0x0034,
+0x0034,
IDC_REBUILDS, 0x403, 2, 0
-0x0035,
+0x0035,
IDC_REBUILDS, 0x403, 10, 0
-0x6e55, 0x696c, 0x696d, 0x6574, 0x0064,
- 0
-END
-
-IDD_ScriptCondition DLGINIT
-BEGIN
- IDC_CONDITION_TYPE, 0x403, 6, 0
-0x654e, 0x6576, 0x0072,
- IDC_CONDITION_TYPE, 0x403, 29, 0
-0x6f43, 0x6e75, 0x6574, 0x2072, 0x6f63, 0x706d, 0x7261, 0x6465, 0x7420,
-0x206f, 0x2061, 0x6176, 0x756c, 0x2e65, "\000"
- IDC_CONDITION_TYPE, 0x403, 26, 0
-0x6c46, 0x6761, 0x6320, 0x6d6f, 0x6170, 0x6572, 0x2064, 0x6f74, 0x6120,
-0x7620, 0x6c61, 0x6575, 0x002e,
- IDC_CONDITION_TYPE, 0x403, 7, 0
-0x6c41, 0x6177, 0x7379, "\000"
- 0
-END
-
-IDD_ScriptAction DLGINIT
-BEGIN
- IDC_CONDITION_TYPE, 0x403, 18, 0
-0x6544, 0x7562, 0x2067, 0x654d, 0x7373, 0x6761, 0x2065, 0x6f42, 0x0078,
-
- IDC_CONDITION_TYPE, 0x403, 21, 0
-0x6553, 0x2074, 0x6c66, 0x6761, 0x7420, 0x206f, 0x2061, 0x6176, 0x756c,
-0x2e65, "\000"
- IDC_CONDITION_TYPE, 0x403, 24, 0
-0x6553, 0x2074, 0x6f63, 0x6e75, 0x6574, 0x2072, 0x6f74, 0x6120, 0x7620,
-0x6c61, 0x6575, 0x002e,
- IDC_CONDITION_TYPE, 0x403, 8, 0
-0x6956, 0x7463, 0x726f, 0x0079,
- IDC_CONDITION_TYPE, 0x403, 7, 0
-0x6544, 0x6566, 0x7461, "\000"
- IDC_CONDITION_TYPE, 0x403, 14, 0
-0x6f4e, 0x6f20, 0x6570, 0x6172, 0x6974, 0x6e6f, 0x002e,
+0x6e55, 0x696c, 0x696d, 0x6574, 0x0064,
0
END
IDD_TeamReinforcement DLGINIT
BEGIN
IDC_TRANSPORT_COMBO, 0x403, 11, 0
-0x6548, 0x696c, 0x6f63, 0x7470, 0x7265, "\000"
+0x6548, 0x696c, 0x6f63, 0x7470, 0x7265, "\000"
IDC_VETERANCY, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_VETERANCY, 0x403, 8, 0
-0x6556, 0x6574, 0x6172, 0x006e,
+0x6556, 0x6574, 0x6172, 0x006e,
IDC_VETERANCY, 0x403, 6, 0
-0x6c45, 0x7469, 0x0065,
+0x6c45, 0x7469, 0x0065,
IDC_VETERANCY, 0x403, 7, 0
-0x6548, 0x6f72, 0x6369, "\000"
+0x6548, 0x6f72, 0x6369, "\000"
IDC_WAYPOINT_COMBO, 0x403, 9, 0
-0x6157, 0x7079, 0x696f, 0x746e, "\000"
+0x6157, 0x7079, 0x696f, 0x746e, "\000"
0
END
IDD_TeamBehavior DLGINIT
BEGIN
IDC_ENEMY_INTERACTIONS, 0x403, 6, 0
-0x6c53, 0x6565, 0x0070,
+0x6c53, 0x6565, 0x0070,
IDC_ENEMY_INTERACTIONS, 0x403, 8, 0
-0x6150, 0x7373, 0x7669, 0x0065,
+0x6150, 0x7373, 0x7669, 0x0065,
IDC_ENEMY_INTERACTIONS, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_ENEMY_INTERACTIONS, 0x403, 6, 0
-0x6c41, 0x7265, 0x0074,
+0x6c41, 0x7265, 0x0074,
IDC_ENEMY_INTERACTIONS, 0x403, 11, 0
-0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
+0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
0
END
-IDD_MAPOBJECT_PROPS DLGINIT
+IDD_SCORCH_OPTIONS DLGINIT
+BEGIN
+ IDC_SCORCHTYPE, 0x403, 9, 0
+0x6353, 0x726f, 0x6863, 0x3120, "\000"
+ IDC_SCORCHTYPE, 0x403, 9, 0
+0x6353, 0x726f, 0x6863, 0x3220, "\000"
+ IDC_SCORCHTYPE, 0x403, 9, 0
+0x6353, 0x726f, 0x6863, 0x3320, "\000"
+ IDC_SCORCHTYPE, 0x403, 9, 0
+0x6353, 0x726f, 0x6863, 0x3420, "\000"
+ IDC_SCORCHTYPE, 0x403, 13, 0
+0x6f52, 0x6e75, 0x2064, 0x6853, 0x6461, 0x776f, "\000"
+ IDC_SCORCHTYPE, 0x403, 12, 0
+0x7243, 0x6361, 0x206b, 0x614d, 0x6b72, 0x0073,
+ 0
+END
+
+IDD_WATER_OPTIONS DLGINIT
+BEGIN
+ IDC_WATERNAME_EDIT, 0x403, 22, 0
+0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
+0x6f69, 0x006e,
+ 0
+END
+
+IDD_WAYPOINT_OPTIONS DLGINIT
+BEGIN
+ IDC_WAYPOINTNAME_EDIT, 0x403, 22, 0
+0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
+0x6f69, 0x006e,
+ IDC_LIST_OF_WAYPOINT_NAMES, 0x403, 1, 0
+"\000"
+ 0
+END
+
+IDD_TeamObjectProperties DLGINIT
BEGIN
IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
-0x6544, 0x6461, "\000"
+0x6544, 0x6461, "\000"
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3532, 0x0025,
+0x3532, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3035, 0x0025,
+0x3035, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3537, 0x0025,
+0x3537, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
-0x3031, 0x2530, "\000"
+0x3031, 0x2530, "\000"
IDC_MAPOBJECT_StartingHealth, 0x403, 6, 0
-0x744f, 0x6568, 0x0072,
+0x744f, 0x6568, 0x0072,
IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
-0x6c53, 0x6565, 0x0070,
+0x6c53, 0x6565, 0x0070,
IDC_MAPOBJECT_Aggressiveness, 0x403, 8, 0
-0x6150, 0x7373, 0x7669, 0x0065,
+0x6150, 0x7373, 0x7669, 0x0065,
IDC_MAPOBJECT_Aggressiveness, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
-0x6c41, 0x7265, 0x0074,
+0x6c41, 0x7265, 0x0074,
IDC_MAPOBJECT_Aggressiveness, 0x403, 11, 0
-0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
+0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_MAPOBJECT_Veterancy, 0x403, 8, 0
-0x6556, 0x6574, 0x6172, 0x006e,
+0x6556, 0x6574, 0x6172, 0x006e,
IDC_MAPOBJECT_Veterancy, 0x403, 6, 0
-0x6c45, 0x7469, 0x0065,
+0x6c45, 0x7469, 0x0065,
IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
-0x6548, 0x6f72, 0x6369, "\000"
+0x6548, 0x6f72, 0x6369, "\000"
IDC_MAPOBJECT_Weather, 0x403, 16, 0
-0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
+0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
IDC_MAPOBJECT_Weather, 0x403, 17, 0
-0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
+0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
IDC_MAPOBJECT_Weather, 0x403, 15, 0
-0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
+0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
IDC_MAPOBJECT_Time, 0x403, 13, 0
-0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
+0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
IDC_MAPOBJECT_Time, 0x403, 14, 0
-0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
+0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
IDC_MAPOBJECT_Time, 0x403, 16, 0
-0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
+0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
IDC_MAPOBJECT_HitPoints, 0x403, 19, 0
-0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
-"\000"
- 0
-END
-
-IDD_SCORCH_OPTIONS DLGINIT
-BEGIN
- IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3120, "\000"
- IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3220, "\000"
- IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3320, "\000"
- IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3420, "\000"
- IDC_SCORCHTYPE, 0x403, 13, 0
-0x6f52, 0x6e75, 0x2064, 0x6853, 0x6461, 0x776f, "\000"
- IDC_SCORCHTYPE, 0x403, 12, 0
-0x7243, 0x6361, 0x206b, 0x614d, 0x6b72, 0x0073,
- 0
-END
-
-IDD_WATER_OPTIONS DLGINIT
-BEGIN
- IDC_WATERNAME_EDIT, 0x403, 22, 0
-0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
-0x6f69, 0x006e,
+0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
+"\000"
0
END
-IDD_WAYPOINT_OPTIONS DLGINIT
+IDD_MAPOBJECT_PROPS DLGINIT
BEGIN
- IDC_WAYPOINTNAME_EDIT, 0x403, 22, 0
-0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
-0x6f69, 0x006e,
- IDC_LIST_OF_WAYPOINT_NAMES, 0x403, 1, 0
-"\000"
+ IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
+0x6544, 0x6461, "\000"
+ IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
+0x3532, 0x0025,
+ IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
+0x3035, 0x0025,
+ IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
+0x3537, 0x0025,
+ IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
+0x3031, 0x2530, "\000"
+ IDC_MAPOBJECT_StartingHealth, 0x403, 6, 0
+0x744f, 0x6568, 0x0072,
+ IDC_MAPOBJECT_HitPoints, 0x403, 19, 0
+0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
+"\000"
+ IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
+0x6c53, 0x6565, 0x0070,
+ IDC_MAPOBJECT_Aggressiveness, 0x403, 8, 0
+0x6150, 0x7373, 0x7669, 0x0065,
+ IDC_MAPOBJECT_Aggressiveness, 0x403, 7, 0
+0x6f4e, 0x6d72, 0x6c61, "\000"
+ IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
+0x6c41, 0x7265, 0x0074,
+ IDC_MAPOBJECT_Aggressiveness, 0x403, 11, 0
+0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
+ IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
+0x6f4e, 0x6d72, 0x6c61, "\000"
+ IDC_MAPOBJECT_Veterancy, 0x403, 8, 0
+0x6556, 0x6574, 0x6172, 0x006e,
+ IDC_MAPOBJECT_Veterancy, 0x403, 6, 0
+0x6c45, 0x7469, 0x0065,
+ IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
+0x6548, 0x6f72, 0x6369, "\000"
+ IDC_MAPOBJECT_Weather, 0x403, 16, 0
+0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
+ IDC_MAPOBJECT_Weather, 0x403, 17, 0
+0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
+ IDC_MAPOBJECT_Weather, 0x403, 15, 0
+0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
+ IDC_MAPOBJECT_Time, 0x403, 13, 0
+0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
+ IDC_MAPOBJECT_Time, 0x403, 14, 0
+0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
+ IDC_MAPOBJECT_Time, 0x403, 16, 0
+0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
0
END
@@ -2463,19 +2625,19 @@ END
// String Table
//
-STRINGTABLE PRELOAD DISCARDABLE
+STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME "Generals World Builder\nMission\nMission\n Missions (*.map)\n.map\nGeneralsMap\n Generals Mission Map"
IDS_SKELETON "SkeletonWindow"
END
-STRINGTABLE PRELOAD DISCARDABLE
+STRINGTABLE PRELOAD DISCARDABLE
BEGIN
AFX_IDS_APP_TITLE "WorldBuilder"
AFX_IDS_IDLEMESSAGE "Ready"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_INDICATOR_EXT "EXT"
ID_INDICATOR_CAPS "CAP"
@@ -2485,7 +2647,7 @@ BEGIN
ID_INDICATOR_REC "REC"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_NEW "Create a new document\nNew"
ID_FILE_OPEN "Open an existing document\nOpen"
@@ -2498,13 +2660,13 @@ BEGIN
ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_MRU_FILE1 "Open this document"
ID_FILE_MRU_FILE2 "Open this document"
@@ -2524,13 +2686,13 @@ BEGIN
ID_FILE_MRU_FILE16 "Open this document"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_WINDOW_NEW "Open another window for the active document\nNew Window"
ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
@@ -2540,7 +2702,7 @@ BEGIN
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_CLEAR "Erase the selection\nErase"
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
@@ -2555,13 +2717,13 @@ BEGIN
ID_EDIT_REDO "Redo the previously undone action\nRedo"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCSIZE "Change the window size"
AFX_IDS_SCMOVE "Change the window position"
@@ -2572,14 +2734,14 @@ BEGIN
AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCRESTORE "Restore the window to normal size"
AFX_IDS_SCTASKLIST "Activate Task List"
AFX_IDS_MDICHILD "Activate this window"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"
IDS_NEW "New"
@@ -2594,18 +2756,53 @@ BEGIN
IDS_FILE_IS_READONLY "The file is read-only. Change the protection, or use Save As to save to another file."
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_REPLACEFILE "%s already exists. Do you want to replace it?"
+ IDS_ONLY_ONE_FILE "Sorry, only one map may be open at a time."
+ IDS_NO_AUTOSAVE "Unable to autosave file."
+ IDS_TOO_MANY_TILES "Warning - too many textures to fit in map."
+ IDS_TOO_MANY_BLENDS "Warning - too many blends to fit in map."
+ IDS_TEXTURE_TOO_LARGE "There is not room to add this texture to the map. You can use the paintbucket tool to replace another texture with this one."
+ IDS_ALPHA_BLEND "Alpha Blend"
+ IDS_SCRIPT_INFORMATION "Information:"
+ IDS_SCRIPT_WARNINGS "Warnings:"
+ IDS_SCRIPT_NOWARNINGS "No Warnings"
+ IDS_CONFIRM_REPLACE_TEXTURE "Replace all occurences of texture %s?"
+ ID_RAMPTOOL "Place Ramps on the map\nRamp"
+ IDS_CONFIRM_REMOVE_CLIFF_MAPPING
+ "Remove all cliff mapping in the entire map?"
+ IDS_NUM_SELECTED_ON_TEAM "For team %s, %d units selected."
+ IDS_MAX_OBJECTS "The object count has exceeded %d. Please reduce the number of objects in this map or performance will suffer."
+ IDS_REPLACEOWNER "Team %s has an invalid owner. Please select a valid owner from the list below:"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_SPLASH_LOADING "Loading..."
+ IDS_SINGLE_SELECTION_ONLY "Single Selection Only"
+ IDS_NO_UPGRADES "No Upgrades Available"
+ IDS_TEAMS_FIXED "One or more teams have been fixed. Please save and re-open the file."
+ IDS_MAPOBJECT_PROPS_TITLE "Object Properties"
+ IDS_NO_PROBLEMS "No problems were detected."
+ IDS_DUPLICATE_TEAM_REMOVED "Duplicate instance of team ""%s"" removed."
+ IDS_PLAYERLESS_TEAM_REMOVED
+ "Team ""%s"" was on non-existent player ""%s"". Team removed."
+ IDS_NEED_TO_FIX_TEAMS "One or more objects had invalid teams. Please run Validation>Fix Teams to correct this."
+END
+
+STRINGTABLE DISCARDABLE
BEGIN
ID_BRUSH_TOOL "Draw the height on the height map.\nHeight Brush"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FEATHERTOOL "Smooths the height levels in the height map.\nSmooth Height"
ID_BIG_TILE_TOOL "Draws a Brush Options Size block of the current texture tile. \nLarge Tile"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_BRUSH_ADD_TOOL "Adds height to (raises) the height map.\nMound"
ID_BRUSH_SUBTRACT_TOOL "Removes height from (lowers) the height map.\nDig"
@@ -2614,7 +2811,7 @@ BEGIN
ID_AUTO_EDGE_OUT_TOOL "Auto edges the current texture area outward.\nAuto Edge Out"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_EYEDROPPER_TOOL "Hot key ALT. Selects the foreground texture by picking on the texture in the edit windows.\nEyedropper"
ID_PLACE_OBJECT_TOOL "Places the current object in Object Selection panel. Drag to orient.\nPlace Object"
@@ -2623,10 +2820,9 @@ BEGIN
ID_GROVE_TOOL "Click to place random foliage, drag to place foliage in a rectangular area.\nGrove"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
- ID_LOOK_WEST "Rotate the camera to look West.\nLook West"
- ID_LOOK_EAST "Rotate the camera to look East.\nLook East"
+ ID_TEAM_EDIT "Edit teams.\nEdit Teams"
ID_LOCK_HORIZONTAL "Lock tool movement to 45 degree increment.\nLock Angle"
ID_LOCK_VERTICAL "Lock tool movement to up and down.\nLock Vertical"
ID_WAYPOINT_TOOL "Add and connect waypoints.\nWaypoint Tool"
@@ -2635,75 +2831,52 @@ BEGIN
ID_HAND_SCROLL_TOOL "Hot key space bar. Scrolls the map.\nScroll"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_ROAD_TOOL "Click and Drag to make Roads.\nRoad"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_MOLD_TOOL "Shapes the terrain using a 3D mesh.\nMesh Mold Tool"
- ID_LOOK_NORTH "Sets the camera angle to look North.\nLook North"
- ID_LOOK_SOUTH "Rotate the camera to look South.\nLook South"
+ ID_RULER_TOOL "Measure distance between two points. \nRuler Tool"
+ ID_SCRIPT_EDIT "Edit scripts.\nEdit Scripts"
END
-STRINGTABLE DISCARDABLE
-BEGIN
- IDS_REPLACEFILE "%s already exists. Do you want to replace it?"
- IDS_ONLY_ONE_FILE "Sorry, only one map may be open at a time."
- IDS_NO_AUTOSAVE "Unable to autosave file."
- IDS_TOO_MANY_TILES "Warning - too many textures to fit in map."
- IDS_TOO_MANY_BLENDS "Warning - too many blends to fit in map."
- IDS_TEXTURE_TOO_LARGE "There is not room to add this texture to the map. You can use the paintbucket tool to replace another texture with this one."
- IDS_ALPHA_BLEND "Alpha Blend"
- IDS_SCRIPT_INFORMATION "Information:"
- IDS_SCRIPT_WARNINGS "Warnings:"
- IDS_SCRIPT_NOWARNINGS "No Warnings"
- IDS_CONFIRM_REPLACE_TEXTURE "Replace all occurences of texture %s?"
- ID_RAMPTOOL "Place Ramps on the map\nRamp"
- IDS_CONFIRM_REMOVE_CLIFF_MAPPING
- "Remove all cliff mapping in the entire map?"
- IDS_NUM_SELECTED_ON_TEAM "For team %s, %d units selected."
- IDS_MAX_OBJECTS "The object count has exceeded %d. Please reduce the number of objects in this map or performance will suffer."
- IDS_REPLACEOWNER "Team %s has an invalid owner. Please select a valid owner from the list below:"
-END
-
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FENCE_TOOL "Places a row of objects. Drag then use shift to stretch.\nFence"
ID_WATER_TOOL "Add and modify water areas.\nWater Tool"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_SCORCH_TOOL "Add Scorchmarks to the map\nAdd Scorchmarks"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_MAPSETTINGS "Edit Map Settings"
ID_EDIT_PICKROADS "Pick only roads"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_LAYERS_LIST "Show or hide the layers list\nToggle LayersList"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_BORDERTOOL "Add and adjust borders.\nBorder Tool"
- ID_VALIDATION_GENERATEMAPREPORT
+ ID_VALIDATION_GENERATEMAPREPORT
"Generate a report about Map validity, possible problems, etc."
ID_VALIDATION_FIXTEAMS "Adjust all teams so that they're ""Execute Associated Action"" is false."
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
- IDS_SPLASH_LOADING "Loading..."
- IDS_SINGLE_SELECTION_ONLY "Single Selection Only"
- IDS_NO_UPGRADES "No Upgrades Available"
- IDS_TEAMS_FIXED "All Teams have been fixed."
+ ID_VIEW_SHOW_SOUND_CIRCLES
+ "Show the minimum and maximum radii around objects with ambient sounds\nShow Sound Circles"
END
#endif // English (U.S.) resources
@@ -2733,4 +2906,3 @@ LANGUAGE 9, 1
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
-
diff --git a/Generals/Code/Tools/WorldBuilder/res/icon2.ico b/Generals/Code/Tools/WorldBuilder/res/icon2.ico
new file mode 100644
index 00000000000..0bec4909604
Binary files /dev/null and b/Generals/Code/Tools/WorldBuilder/res/icon2.ico differ
diff --git a/Generals/Code/Tools/WorldBuilder/res/resource.h b/Generals/Code/Tools/WorldBuilder/res/resource.h
index af7dd6d8432..977f030a095 100644
--- a/Generals/Code/Tools/WorldBuilder/res/resource.h
+++ b/Generals/Code/Tools/WorldBuilder/res/resource.h
@@ -1,3 +1,21 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by WorldBuilder.rc
@@ -114,6 +132,14 @@
#define IDD_TeamGeneric 229
#define IDD_IMPASSABLEOPTIONS 230
#define IDD_EULA_AGREEMENT 231
+#define IDD_RULER_OPTIONS 232
+#define IDD_TeamObjectProperties 233
+#define IDI_Selected 234
+#define IDD_MAPOBJECT_PROPPAGE_GENERAL 235
+#define IDD_MAPOBJECT_PROPPAGE_LOGICAL 236
+#define IDD_MAPOBJECT_PROPPAGE_VISUAL 237
+#define IDD_MAPOBJECT_PROPPAGE_UPGRADES 238
+#define IDD_MAPOBJECT_PROPPAGE_SOUND 239
#define IDC_HEIGHT_COMBO 1000
#define IDC_CELL_WIDTH 1001
#define IDC_INITIAL_HEIGHT 1002
@@ -260,8 +286,11 @@
#define IDC_COPY_SCRIPT 1125
#define IDC_DELETE 1126
#define IDC_SCRIPT_NAME 1127
+#define IDC_VERIFY 1127
#define IDC_RICH_EDIT_HERE 1128
-#define IDC_CONDITION_LIST 1129
+#define IDC_PATCH_GC 1129
+#define IDC_CONDITION_TREE 1130
+#define IDC_CONDITION_LIST 1130
#define IDC_EDIT_CONDITION 1131
#define IDC_CONDITION_TYPE 1132
#define IDC_CAPTION 1133
@@ -320,6 +349,7 @@
#define IDC_MAPOBJECT_Selectable 1166
#define IDC_PRODUCTION_EXECUTEACTIONS 1166
#define IDC_PASSABLE_CHECK 1166
+#define IDC_AUTO_VERIFY 1166
#define IDC_EASY 1167
#define IDC_CHECK2 1167
#define IDC_LR_POPUP2 1167
@@ -331,6 +361,7 @@
#define IDC_TEAM_STARTS_FULL 1168
#define IDC_WAYPOINT_BIDIRECTIONAL 1168
#define IDC_GROUP_ACTIVE 1169
+#define IDC_MAPOBJECT_Selectable2 1169
#define IDC_PLAYERDISPLAYNAME 1170
#define IDC_CHECK4 1170
#define IDC_TRANSPORTS_RETURN 1170
@@ -382,12 +413,14 @@
#define IDC_TeamGeneric_Script2 1199
#define IDC_PASSABLE 1199
#define IDC_EVERY_FRAME 1199
+#define IDC_SCALE_OFF 1199
#define IDC_MIN_UNIT7 1200
#define IDC_RADIO2 1200
#define IDC_USERMAPS 1200
#define IDC_TeamGeneric_Script3 1200
#define IDC_IMPASSABLE 1200
#define IDC_EVERY_SECOND 1200
+#define IDC_SCALE_ON 1200
#define IDC_MAX_UNIT7 1201
#define IDC_RADIO3 1201
#define IDC_TeamGeneric_Script4 1201
@@ -517,6 +550,31 @@
#define IDC_SCRIPT_PREFIX15 1313
#define IDC_SCRIPT_PREFIX16 1314
#define IDC_TeamGeneric_Script1 1315
+#define IDC_DROP_WAYPOINT_BUTTON 1316
+#define IDC_ACTION_TREE 1326
+#define IDC_CENTER_ON_SELECTED 1327
+#define IDC_CHECK_RULER 1328
+#define IDC_SIDES 1329
+#define IDC_RULER_WIDTH 1330
+#define IDC_UPDATE_TEAM_MEMBERS 1331
+#define IDC_USE_TEAM_DEFAULTS 1332
+#define IDC_LOOPING_CHECKBOX 1333
+#define IDC_ENABLED_CHECKBOX 1334
+#define IDC_CUSTOMIZE_CHECKBOX 1335
+#define IDC_MAPOBJECT_Scale 1336
+#define IDC_SOUND_COMBO 1346
+#define IDC_LOOPCOUNT_EDIT 1347
+#define IDC_MIN_VOLUME_EDIT 1348
+#define IDC_PRIORITY_COMBO 1349
+#define IDC_MIN_RANGE_EDIT 1350
+#define IDC_MAX_RANGE_EDIT 1351
+#define IDC_VOLUME_EDIT 1352
+#define IDC_MAPOBJECT_XYPosition 1353
+#define IDC_STATIC_MAPOBJECT_GENERAL 1379
+#define IDC_STATIC_MAPOBJECT_LOGICAL 1380
+#define IDC_STATIC_MAPOBJECT_SOUND 1381
+#define IDC_STATIC_MAPOBJECT_VISUAL 1382
+#define IDC_MAPOBJECT_DISTANCE 1383
#define ID_BRUSH_TOOL 32771
#define IDM_ShowGrid 32772
#define ID_FEATHERTOOL 32791
@@ -575,10 +633,9 @@
#define ID_MOLD_TOOL 32955
#define ID_VIEW_SHOWMACROTEXTURE 32956
#define ID_EDIT_SELECTMACROTEXTURE 32957
-#define ID_LOOK_NORTH 32958
-#define ID_LOOK_SOUTH 32959
-#define ID_LOOK_WEST 32960
-#define ID_LOOK_EAST 32961
+#define ID_RULER_TOOL 32958
+#define ID_SCRIPT_EDIT 32959
+#define ID_TEAM_EDIT 32960
#define ID_LOCK_HORIZONTAL 32962
#define ID_LOCK_VERTICAL 32963
#define ID_WAYPOINT_TOOL 32964
@@ -622,6 +679,11 @@
#define ID_EDIT_SELECTINVALIDTEAM 33005
#define ID_FILE_DUMPTOFILE 33006
#define ID_SCORCH_TOOL 33007
+#define ID_VIEW_BOUNDINGBOXES 33008
+#define ID_VIEW_SIGHTRANGES 33009
+#define ID_VIEW_WEAPONRANGES 33010
+#define ID_HIGHLIGHT_TESTART 33011
+#define ID_SHOW_LETTERBOX 33012
#define ID_TEXTURESIZING_REMOVECLIFFTEXMAPPING 33014
#define ID_VIEW_LAYERS_LIST 33015
#define ID_INSERTNEWLAYER 33017
@@ -653,6 +715,13 @@
#define ID_EDIT_PICKSOUNDS 33341
#define ID_VIEW_SHOW_TERRAIN 33342
#define ID_VIEW_IMPASSABLEAREAOPTIONS 33343
+#define ID_SELECTLAYEROBJECT 33344
+#define ID_SELECTACTIVELAYER 33345
+#define ID_VIEW_SHOW_SOUND_CIRCLES 33346
+#define ID_LOOK_NORTH 33347
+#define ID_LOOK_SOUTH 33348
+#define ID_LOOK_WEST 33349
+#define ID_LOOK_EAST 33350
#define IDS_NEW 61446
#define IDS_RESIZE 61447
#define IDS_REMOVING_INUSE_TEAM 61448
@@ -689,15 +758,20 @@
#define IDS_EULA_AGREEMENT3 61478
#define IDS_EULA_AGREEMENT4 61479
#define IDS_EULA_AGREEMENT5 61480
+#define IDS_MAPOBJECT_PROPS_TITLE 61481
+#define IDS_NO_PROBLEMS 61482
+#define IDS_DUPLICATE_TEAM_REMOVED 61483
+#define IDS_PLAYERLESS_TEAM_REMOVED 61484
+#define IDS_NEED_TO_FIX_TEAMS 61485
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 232
-#define _APS_NEXT_COMMAND_VALUE 33344
-#define _APS_NEXT_CONTROL_VALUE 1326
+#define _APS_NEXT_RESOURCE_VALUE 242
+#define _APS_NEXT_COMMAND_VALUE 33351
+#define _APS_NEXT_CONTROL_VALUE 1354
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/Generals/Code/Tools/WorldBuilder/src/AutoEdgeOutTool.cpp b/Generals/Code/Tools/WorldBuilder/src/AutoEdgeOutTool.cpp
index b60f45a1d24..4fa4184e28a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/AutoEdgeOutTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/AutoEdgeOutTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/BaseBuildProps.cpp b/Generals/Code/Tools/WorldBuilder/src/BaseBuildProps.cpp
index f0630a84b99..1fe9c60f0ae 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BaseBuildProps.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BaseBuildProps.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/BlendEdgeTool.cpp b/Generals/Code/Tools/WorldBuilder/src/BlendEdgeTool.cpp
index 8f29f96b9da..c1129b7f4b0 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BlendEdgeTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BlendEdgeTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp b/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp
index c1a19b1cfa4..3981689ac4f 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BlendMaterial.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/BorderTool.cpp b/Generals/Code/Tools/WorldBuilder/src/BorderTool.cpp
index 73aa050139f..1db6efb14da 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BorderTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BorderTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -124,7 +124,7 @@ void BorderTool::mouseDown(TTrackingMode m, CPoint viewPt, WbView* pView, CWorld
return;
}
- static Coord3D zero = {0.0f, 0.0f, 0.0f};
+ //static Coord3D zero = {0.0f, 0.0f, 0.0f};
Coord3D groundPt;
pView->viewToDocCoords(viewPt, &groundPt);
@@ -138,10 +138,24 @@ void BorderTool::mouseDown(TTrackingMode m, CPoint viewPt, WbView* pView, CWorld
Int motion;
pDoc->findBoundaryNear(&groundPt, BOUNDARY_PICK_DISTANCE, &m_modifyBorderNdx, &motion);
- if (motion == 0) {
+
+ // if bottom left boundary grabbed
+ if (motion == 0)
+ {
// modifying the bottom left is not allowed.
m_modifyBorderNdx = -1;
- } else {
+ }
+ // else if no boundary is near
+ else if (motion == -1)
+ {
+ // add a boundary
+ m_addingNewBorder = true;
+
+ ICoord2D initialBoundary = { 1, 1 };
+ pDoc->addBoundary(&initialBoundary);
+ }
+ else
+ {
m_modificationType = (ModificationType) motion;
}
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/BrushTool.cpp b/Generals/Code/Tools/WorldBuilder/src/BrushTool.cpp
index b6da31f7bcc..27b8e758660 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BrushTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BrushTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
// Texture tiling tool for worldbuilder.
// Author: John Ahlquist, April 2001
+
#include "StdAfx.h"
#include "resource.h"
diff --git a/Generals/Code/Tools/WorldBuilder/src/BuildList.cpp b/Generals/Code/Tools/WorldBuilder/src/BuildList.cpp
index 34dc1374e7f..12b1d28219c 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BuildList.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BuildList.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -737,15 +737,15 @@ void BuildList::OnExport()
static FILE *theLogFile = nullptr;
Bool open = false;
try {
- char buffer[ _MAX_PATH ];
- ::GetModuleFileName( nullptr, buffer, sizeof( buffer ) );
- if (char *pEnd = strrchr(buffer, '\\'))
+ char buffer[_MAX_PATH];
+ ::GetModuleFileName(nullptr, buffer, sizeof(buffer));
+ if (char* pEnd = strrchr(buffer, '\\'))
{
*(pEnd + 1) = 0;
}
- SidesInfo *pSide = TheSidesList->getSideInfo(m_curSide);
- Dict *d = TheSidesList->getSideInfo(m_curSide)->getDict();
+ SidesInfo* pSide = TheSidesList->getSideInfo(m_curSide);
+ Dict* d = TheSidesList->getSideInfo(m_curSide)->getDict();
AsciiString name = d->getAsciiString(TheKey_playerName);
strlcat(buffer, name.str(), ARRAY_SIZE(buffer));
strlcat(buffer, "_BuildList.ini", ARRAY_SIZE(buffer));
diff --git a/Generals/Code/Tools/WorldBuilder/src/BuildListTool.cpp b/Generals/Code/Tools/WorldBuilder/src/BuildListTool.cpp
index d0d84c1f038..e935114202d 100644
--- a/Generals/Code/Tools/WorldBuilder/src/BuildListTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/BuildListTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/CButtonShowColor.cpp b/Generals/Code/Tools/WorldBuilder/src/CButtonShowColor.cpp
index 590c8ef381d..c90376306ca 100644
--- a/Generals/Code/Tools/WorldBuilder/src/CButtonShowColor.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/CButtonShowColor.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/CFixTeamOwnerDialog.cpp b/Generals/Code/Tools/WorldBuilder/src/CFixTeamOwnerDialog.cpp
index 34bfd217067..fca3eb953f0 100644
--- a/Generals/Code/Tools/WorldBuilder/src/CFixTeamOwnerDialog.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/CFixTeamOwnerDialog.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/CUndoable.cpp b/Generals/Code/Tools/WorldBuilder/src/CUndoable.cpp
index 9e79467c778..93d9ee1ce0e 100644
--- a/Generals/Code/Tools/WorldBuilder/src/CUndoable.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/CUndoable.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -792,9 +792,9 @@ void DictItemUndoable::Do()
*m_dictToModify[i] = m_newDictData;
else
m_dictToModify[i]->copyPairFrom(m_newDictData, m_key);
- MapObjectProps::update(); // ugh, hack to update panel
- ObjectOptions::update(); // ditto
}
+ MapObjectProps::update(); // ugh, hack to update panel
+ ObjectOptions::update(); // ditto
if (m_inval && m_pDoc) {
WbView3d *p3View = m_pDoc->GetActive3DView();
p3View->resetRenderObjects();
@@ -809,9 +809,9 @@ void DictItemUndoable::Undo()
*m_dictToModify[i] = m_oldDictData[i];
else
m_dictToModify[i]->copyPairFrom(m_oldDictData[i], m_key);
- MapObjectProps::update(); // ugh, hack to update panel
- ObjectOptions::update(); // ditto
}
+ MapObjectProps::update(); // ugh, hack to update panel
+ ObjectOptions::update(); // ditto
if (m_inval && m_pDoc) {
WbView3d *p3View = m_pDoc->GetActive3DView();
p3View->resetRenderObjects();
@@ -1067,6 +1067,8 @@ AddPolygonUndoable::AddPolygonUndoable(PolygonTrigger *pTrig):
//
void AddPolygonUndoable::Do()
{
+ // The call to LayersList must be done here because only the WorldBuilder knows about Layers.
+ TheLayersList->addPolygonTriggerToLayersList(m_trigger, m_trigger->getLayerName());
PolygonTrigger::addPolygonTrigger(m_trigger);
m_isTriggerInList = true;
}
@@ -1076,6 +1078,8 @@ void AddPolygonUndoable::Do()
//
void AddPolygonUndoable::Undo()
{
+ // The call to LayersList must be done here because only the WorldBuilder knows about Layers.
+ TheLayersList->removePolygonTriggerFromLayersList(m_trigger);
PolygonTrigger::removePolygonTrigger(m_trigger);
m_isTriggerInList = false;
}
@@ -1335,6 +1339,7 @@ DeletePolygonUndoable::DeletePolygonUndoable(PolygonTrigger *pTrig):
//
void DeletePolygonUndoable::Do()
{
+ TheLayersList->removePolygonTriggerFromLayersList(m_trigger);
PolygonTrigger::removePolygonTrigger(m_trigger);
m_isTriggerInList = false;
}
@@ -1345,8 +1350,96 @@ void DeletePolygonUndoable::Do()
void DeletePolygonUndoable::Undo()
{
PolygonTrigger::addPolygonTrigger(m_trigger);
+ TheLayersList->addPolygonTriggerToLayersList(m_trigger, m_trigger->getLayerName());
m_isTriggerInList = true;
}
+/*************************************************************************
+** MultipleUndoable
+***************************************************************************/
+//
+// MultipleUndoable - constructor.
+//
+MultipleUndoable::MultipleUndoable()
+ : m_undoableList( nullptr )
+{
+}
+
+//
+// MultipleUndoable - destructor
+//
+MultipleUndoable::~MultipleUndoable()
+{
+ if ( m_undoableList )
+ {
+ REF_PTR_RELEASE(m_undoableList);
+ }
+}
+
+//
+// Add another undo to the list.
+//
+void MultipleUndoable::addUndoable( Undoable * undoable )
+{
+ undoable->LinkNext( m_undoableList );
+
+ REF_PTR_SET( m_undoableList, undoable );
+}
+
+
+//
+/// Do all the list's actions.
+//
+void MultipleUndoable::Do()
+{
+ Undoable * undoable = m_undoableList;
+
+ while ( undoable != nullptr )
+ {
+ Undoable * next = undoable->GetNext();
+ undoable->Do();
+ undoable = next;
+ }
+}
+
+
+//
+// Recursive function to help traverse a singly-linked list in reverse order
+//
+static void undoHelper(Undoable * undoable)
+{
+ if ( undoable == nullptr )
+ return;
+
+ undoHelper( undoable->GetNext() );
+
+ undoable->Undo();
+}
+
+//
+// Undo all the list's actions. This is harder, because we need to do it in reverse order, for a
+// singly linked list
+//
+void MultipleUndoable::Undo()
+{
+ undoHelper(m_undoableList);
+}
+
+
+//
+/// Redo all the list's actions.
+//
+void MultipleUndoable::Redo()
+{
+ Undoable * undoable = m_undoableList;
+
+ while ( undoable != nullptr )
+ {
+ Undoable * next = undoable->GetNext();
+ undoable->Redo();
+ undoable = next;
+ }
+}
+
diff --git a/Generals/Code/Tools/WorldBuilder/src/CameraOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/CameraOptions.cpp
index 8057093f5e5..220e3d5f22d 100644
--- a/Generals/Code/Tools/WorldBuilder/src/CameraOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/CameraOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
// CameraOptions.cpp : implementation file
//
+
#include "StdAfx.h"
#include "resource.h"
#include "WorldBuilder.h"
@@ -26,6 +27,10 @@
#include "wbview3d.h"
#include "WorldBuilderDoc.h"
+
+#include "WaypointOptions.h" //WST 10/7/2002
+#include "CUndoable.h" //WST 10/7/2002
+
/////////////////////////////////////////////////////////////////////////////
// CameraOptions dialog
@@ -52,12 +57,15 @@ void CameraOptions::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(CameraOptions, CDialog)
//{{AFX_MSG_MAP(CameraOptions)
ON_BN_CLICKED(IDC_CameraReset, OnCameraReset)
+ ON_BN_CLICKED(IDC_DROP_WAYPOINT_BUTTON, OnDropWaypointButton)
+ ON_BN_CLICKED(IDC_CENTER_ON_SELECTED, OnCenterOnSelectedButton)
ON_WM_MOVE()
ON_EN_CHANGE(IDC_PITCH_EDIT, OnChangePitchEdit)
ON_WM_SHOWWINDOW()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
+
/////////////////////////////////////////////////////////////////////////////
// CameraOptions message handlers
@@ -71,6 +79,65 @@ void CameraOptions::OnCameraReset()
}
}
+//WST 10/7/2002 - Drop waypoint button for Adam Isgreen -----------
+void CameraOptions::OnDropWaypointButton()
+{
+ //The following code is taken from waypointTool.cpp. On mouse down.
+ WbView3d * p3View = CWorldBuilderDoc::GetActive3DView();
+ Coord3D docPt;
+ CWorldBuilderDoc *pDoc = CWorldBuilderDoc::GetActiveDoc();
+
+ Vector3 camTarget = p3View->getCameraTarget();
+ docPt.x = camTarget.X;
+ docPt.y = camTarget.Y;
+ docPt.z = MAGIC_GROUND_Z;
+
+ //
+ // MBL CNC3 INCURSION 10.29.2002 - Fix compile error w/ 10-15-2002 Drop
+ //
+ // MapObject *pNew = new MapObject(docPt, "*Waypoints/Waypoint", 0, 0, nullptr, nullptr );
+ MapObject *pNew = newInstance(MapObject)(docPt, "*Waypoints/Waypoint", 0, 0, nullptr, nullptr );
+
+ Int id = pDoc->getNextWaypointID();
+ AsciiString name = WaypointOptions::GenerateUniqueName(id);
+ pNew->setSelected(true);
+ pNew->setIsWaypoint();
+ pNew->setWaypointID(id);
+ pNew->setWaypointName(name);
+ pNew->getProperties()->setAsciiString(TheKey_originalOwner, "team");
+ AddObjectUndoable *pUndo = new AddObjectUndoable(pDoc, pNew);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ pNew = nullptr; // undoable owns it now.
+}
+
+//WST 11/25/2002 - New Center Camera button for Designers -----------
+void CameraOptions::OnCenterOnSelectedButton()
+{
+ // Center camera on the selected map object
+
+ int count = 0;
+ const Coord3D *objectPosition;
+
+ MapObject *mapObject = MapObject::getFirstMapObject();
+ while (mapObject) {
+ if (mapObject->isSelected()) {
+ objectPosition = mapObject->getLocation();
+ count++;
+ }
+ mapObject = mapObject->getNext();
+ }
+
+ if (count==1) {
+ // Only center if there is only one object selected on map
+ WbView3d * p3View = CWorldBuilderDoc::GetActive3DView();
+ if (p3View) {
+ p3View->setCenterInView(objectPosition->x/MAP_XY_FACTOR,objectPosition->y/MAP_XY_FACTOR);
+ }
+ }
+}
+
+
void CameraOptions::OnMove(int x, int y)
{
CDialog::OnMove(x, y);
@@ -139,7 +206,9 @@ void CameraOptions::stuffValuesIntoFields()
m_updating = false;
Real height = p3View->getHeightAboveGround();
- Real zoom = height/TheGlobalData->m_maxCameraHeight;
+ //WST 10/11/2002 This is inaccurate Real zoom = height/TheGlobalData->m_maxCameraHeight;
+ Real zoom = p3View->getCurrentZoom(); //WST 10.11.2002
+
putReal(IDC_ZOOMTEXT, zoom);
putReal(IDC_HEIGHTTEXT, height);
diff --git a/Generals/Code/Tools/WorldBuilder/src/CellWidth.cpp b/Generals/Code/Tools/WorldBuilder/src/CellWidth.cpp
index a2fd1b0a95d..35277afd30b 100644
--- a/Generals/Code/Tools/WorldBuilder/src/CellWidth.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/CellWidth.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ContourOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/ContourOptions.cpp
index d4d0b00c39e..63109221a7e 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ContourOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ContourOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -108,7 +108,7 @@ BOOL ContourOptions::OnInitDialog()
/// Handles slider ui messages.
/** Gets the info, determines if it is the feather or width slider,
- gets the new value, and updates the correspondig edit control
+ gets the new value, and updates the corresponding edit control
and the brush tool. */
void ContourOptions::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
diff --git a/Generals/Code/Tools/WorldBuilder/src/DrawObject.cpp b/Generals/Code/Tools/WorldBuilder/src/DrawObject.cpp
index a342e337161..0fe8c567085 100644
--- a/Generals/Code/Tools/WorldBuilder/src/DrawObject.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/DrawObject.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -39,7 +39,6 @@
#include "WW3D2/meshmdl.h"
#include "WW3D2/shader.h"
#include "Common/MapObject.h"
-#include "Common/ThingTemplate.h"
#include "GameLogic/PolygonTrigger.h"
#include "GameLogic/SidesList.h"
#include "resource.h"
@@ -52,6 +51,11 @@
#include "LayersList.h"
#include "Common/WellKnownKeys.h"
#include "Common/BorderColors.h"
+#include "Common/ThingTemplate.h"
+#include "W3DDevice/Common/W3DConvert.h"
+#include "WW3D2/render2d.h"
+#include "GameLogic/Weapon.h"
+#include "Common/AudioEventInfo.h"
#ifdef RTS_DEBUG
#define NO_INTENSE_DEBUG 1
@@ -95,7 +99,6 @@ Bool DrawObject::m_meshFeedback = false;
Bool DrawObject::m_rampFeedback = false;
Bool DrawObject::m_boundaryFeedback = false;
Bool DrawObject::m_ambientSoundFeedback = false;
-
Coord3D DrawObject::m_feedbackPoint;
CPoint DrawObject::m_cellCenter;
@@ -131,6 +134,8 @@ void DrawObject::stopWaypointDragFeedback()
DrawObject::~DrawObject()
{
freeMapResources();
+ REF_PTR_RELEASE(m_waterDrawObject);
+ TheWaterRenderObj = nullptr;
}
DrawObject::DrawObject() :
@@ -144,8 +149,9 @@ DrawObject::DrawObject() :
m_vertexFeedback(nullptr),
m_indexFeedback(nullptr),
m_indexWater(nullptr),
- m_moldMesh(nullptr)
-
+ m_moldMesh(nullptr),
+ m_lineRenderer(nullptr),
+ m_drawSoundRanges(false)
{
m_feedbackPoint.x = 20;
m_feedbackPoint.y = 20;
@@ -153,6 +159,9 @@ DrawObject::DrawObject() :
m_waterDrawObject = new WaterRenderObjClass;
m_waterDrawObject->init(0, 0, 0, nullptr, WaterRenderObjClass::WATER_TYPE_0_TRANSLUCENT);
TheWaterRenderObj=m_waterDrawObject;
+
+ //(gth) this was needed to fix the extents bug that is based off water and too small for our maps
+ Set_Force_Visible(true);
}
@@ -178,14 +187,19 @@ DrawObject & DrawObject::operator = (const DrawObject & that)
void DrawObject::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
{
+ // (gth) CNC3 these bounds don't actually work for all levels...
+ // we set the "force visible" flag for this object since it encapsulates all of the UI
+ // gadgets for the whole level anyway.
Vector3 ObjSpaceCenter(TheGlobalData->m_waterExtentX,TheGlobalData->m_waterExtentY,50*MAP_XY_FACTOR);
float length = ObjSpaceCenter.Length();
-
sphere.Init(ObjSpaceCenter, length);
}
void DrawObject::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
{
+ // (gth) CNC3 these bounds don't actually work for all levels...
+ // we set the "force visible" flag for this object since it encapsulates all of the UI
+ // gadgets for the whole level anyway.
Vector3 minPt(-2*TheGlobalData->m_waterExtentX,-2*TheGlobalData->m_waterExtentY,0);
Vector3 maxPt(2*TheGlobalData->m_waterExtentX,2*TheGlobalData->m_waterExtentY,100*MAP_XY_FACTOR);
box.Init(minPt,maxPt);
@@ -214,8 +228,9 @@ Int DrawObject::freeMapResources()
REF_PTR_RELEASE(m_indexFeedback);
REF_PTR_RELEASE(m_indexWater);
REF_PTR_RELEASE(m_moldMesh);
- REF_PTR_RELEASE(m_waterDrawObject);
- TheWaterRenderObj = nullptr;
+
+ delete m_lineRenderer;
+ m_lineRenderer = nullptr;
return 0;
}
@@ -237,10 +252,10 @@ Int DrawObject::initData()
freeMapResources(); //free old data and ib/vb
m_numTriangles = 2*NUM_TRI;
- m_indexBuffer=NEW_REF(DX8IndexBufferClass,(m_numTriangles*3));
+ m_indexBuffer=NEW_REF(DX8IndexBufferClass,(m_numTriangles*3, DX8IndexBufferClass::USAGE_DYNAMIC));
// Fill up the IB
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBuffer);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBuffer, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
for (i=0; i<3*m_numTriangles; i+=3)
@@ -252,11 +267,11 @@ Int DrawObject::initData()
ib+=3; //skip the 3 indices we just filled
}
- m_vertexBufferTile1=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_numTriangles*3,DX8VertexBufferClass::USAGE_DEFAULT));
- m_vertexBufferTile2=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_numTriangles*3,DX8VertexBufferClass::USAGE_DEFAULT));
+ m_vertexBufferTile1=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_numTriangles*3,DX8VertexBufferClass::USAGE_DYNAMIC));
+ m_vertexBufferTile2=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_numTriangles*3,DX8VertexBufferClass::USAGE_DYNAMIC));
- m_vertexFeedback=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,NUM_FEEDBACK_VERTEX,DX8VertexBufferClass::USAGE_DEFAULT));
- m_indexFeedback=NEW_REF(DX8IndexBufferClass,(NUM_FEEDBACK_INDEX));
+ m_vertexFeedback=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,NUM_FEEDBACK_VERTEX,DX8VertexBufferClass::USAGE_DYNAMIC));
+ m_indexFeedback=NEW_REF(DX8IndexBufferClass,(NUM_FEEDBACK_INDEX,DX8IndexBufferClass::USAGE_DYNAMIC));
//go with a preset material for now.
m_vertexMaterialClass=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
@@ -306,11 +321,11 @@ void DrawObject::updateMeshVB()
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -398,7 +413,7 @@ void DrawObject::updateMeshVB()
Int numPoly = m_moldMesh->Get_Model()->Get_Polygon_Count();
- const Vector3i *pPoly =m_moldMesh->Get_Model()->Get_Polygon_Array();
+ const TriIndex *pPoly =m_moldMesh->Get_Model()->Get_Polygon_Array();
if (3*numPoly+9 >= NUM_FEEDBACK_INDEX) {
return;
}
@@ -434,11 +449,11 @@ void DrawObject::updateRampVB()
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -550,11 +565,11 @@ void DrawObject::updateBoundaryVB()
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -606,11 +621,11 @@ void DrawObject::updateBoundaryVB()
endPt.z = TheTerrainRenderObject->getHeightMapHeight(endPt.x, endPt.y, nullptr);
}
- if ((m_feedbackVertexCount + 8) > NUM_FEEDBACK_VERTEX) {
+ if (m_feedbackVertexCount + 8 > NUM_FEEDBACK_VERTEX) {
return;
}
- if ((m_feedbackIndexCount + 12) > NUM_FEEDBACK_INDEX) {
+ if (m_feedbackIndexCount + 12 > NUM_FEEDBACK_INDEX) {
return;
}
@@ -726,11 +741,11 @@ void DrawObject::updateAmbientSoundVB()
{
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -828,7 +843,6 @@ void DrawObject::updateAmbientSoundVB()
}
}
-
/** updateMeshVB puts waypoint path triangles into m_vertexFeedback. */
void DrawObject::updateWaypointVB()
@@ -837,11 +851,11 @@ void DrawObject::updateWaypointVB()
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -1075,11 +1089,11 @@ void DrawObject::updatePolygonVB(PolygonTrigger *pTrig, Bool selected, Bool isOp
green = green<<8;
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -1169,11 +1183,11 @@ void DrawObject::updateFeedbackVB()
const Int theAlpha = 64;
m_feedbackVertexCount = 0;
m_feedbackIndexCount = 0;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback);
+ DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexFeedback, D3DLOCK_DISCARD);
UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
UnsignedShort *curIb = ib;
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexFeedback, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
VertexFormatXYZDUV1 *curVb = vb;
@@ -1378,7 +1392,7 @@ Int DrawObject::updateVB(DX8VertexBufferClass *pVB, Int color, Bool doArrow, Boo
if (pVB )
{
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(pVB);
+ DX8VertexBufferClass::WriteLockClass lockVtxBuffer(pVB, D3DLOCK_DISCARD);
VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
const Real theZ = 0.0f;
@@ -1387,6 +1401,10 @@ Int DrawObject::updateVB(DX8VertexBufferClass *pVB, Int color, Bool doArrow, Boo
if (doDiamond) {
theRadius *= 5.0;
}
+ else
+ {
+ theRadius *= 2.0;
+ }
Int limit = NUM_TRI-(NUM_ARROW_TRI+NUM_SELECT_TRI);
float curAngle = 0;
@@ -1432,8 +1450,12 @@ Int DrawObject::updateVB(DX8VertexBufferClass *pVB, Int color, Bool doArrow, Boo
vb++;
}
curAngle += deltaAngle;
+ }
+ if (!doDiamond) {
+ theRadius /= 2.0;
}
+
if (!doArrow) {
theRadius /= 20;
halfLineWidth /= 20;
@@ -1533,6 +1555,7 @@ Int DrawObject::updateVB(DX8VertexBufferClass *pVB, Int color, Bool doArrow, Boo
curAngle += deltaAngle;
}
+
#if 0
// Now do the highlight triangle. This is in yellow.
for (k=0; k<3; k++) {
@@ -1582,6 +1605,417 @@ Int DrawObject::updateVB(DX8VertexBufferClass *pVB, Int color, Bool doArrow, Boo
return -1;
}
+#define BOUNDING_BOX_LINE_WIDTH 2.0f
+/** Draw an object's bounding box into the vertex buffer. **/
+// MLL C&C3
+void DrawObject::updateVBWithBoundingBox(MapObject *pMapObj, CameraClass* camera)
+{
+ if (!pMapObj || !m_lineRenderer || !pMapObj->getThingTemplate()) {
+ return;
+ }
+
+ unsigned long color = 0xFFAA00AA; // Purple
+
+ GeometryInfo ginfo = pMapObj->getThingTemplate()->getTemplateGeometryInfo();
+
+ Coord3D pos = *pMapObj->getLocation();
+ if (TheTerrainRenderObject) {
+ // Make sure that the position is on the terrain.
+ pos.z += TheTerrainRenderObject->getHeightMapHeight(pos.x, pos.y, nullptr);
+ }
+
+ switch (ginfo.getGeomType())
+ {
+ //---------------------------------------------------------------------------------------------
+ case GEOMETRY_BOX:
+ {
+ Real angle = pMapObj->getAngle();
+ Real c = (Real)cos(angle);
+ Real s = (Real)sin(angle);
+ Real exc = ginfo.getMajorRadius()*c;
+ Real eyc = ginfo.getMinorRadius()*c;
+ Real exs = ginfo.getMajorRadius()*s;
+ Real eys = ginfo.getMinorRadius()*s;
+ Coord3D pts[4];
+ pts[0].x = pos.x - exc - eys;
+ pts[0].y = pos.y + eyc - exs;
+ pts[0].z = 0;
+ pts[1].x = pos.x + exc - eys;
+ pts[1].y = pos.y + eyc + exs;
+ pts[1].z = 0;
+ pts[2].x = pos.x + exc + eys;
+ pts[2].y = pos.y - eyc + exs;
+ pts[2].z = 0;
+ pts[3].x = pos.x - exc + eys;
+ pts[3].y = pos.y - eyc - exs;
+ pts[3].z = 0;
+ Real z = pos.z;
+ for (int i = 0; i < 2; i++) {
+ for (int corner = 0; corner < 4; corner++) {
+ ICoord2D start, end;
+ pts[corner].z = z;
+ pts[(corner+1)&3].z = z;
+ bool shouldStart = worldToScreen(&pts[corner], &start, camera);
+ bool shouldEnd = worldToScreen(&pts[(corner+1)&3], &end, camera);
+ if (shouldStart && shouldEnd) {
+ m_lineRenderer->Add_Line(Vector2(start.x, start.y), Vector2(end.x, end.y), BOUNDING_BOX_LINE_WIDTH, color);
+ }
+ }
+
+ z += ginfo.getMaxHeightAbovePosition();
+ }
+ break;
+ }
+
+ //---------------------------------------------------------------------------------------------
+ case GEOMETRY_SPHERE: // not quite right, but close enough
+ case GEOMETRY_CYLINDER:
+ {
+ Real angle, inc = PI/4.0f;
+ Real radius = ginfo.getMajorRadius();
+ Coord3D pnt, lastPnt;
+ ICoord2D start, end;
+ Real z = pos.z;
+
+ bool shouldEnd, shouldStart;
+ // Draw the cylinder.
+ for (int i=0; i<2; i++) {
+ angle = 0.0f;
+ lastPnt.x = pos.x + radius * (Real)cos(angle);
+ lastPnt.y = pos.y + radius * (Real)sin(angle);
+ lastPnt.z = z;
+ shouldEnd = worldToScreen(&lastPnt, &end, camera);
+
+ for( angle = inc; angle <= 2.0f * PI; angle += inc ) {
+ pnt.x = pos.x + radius * (Real)cos(angle);
+ pnt.y = pos.y + radius * (Real)sin(angle);
+ pnt.z = z;
+ shouldStart = worldToScreen(&pnt, &start, camera);
+ if (shouldStart && shouldEnd) {
+ m_lineRenderer->Add_Line(Vector2(start.x, start.y), Vector2(end.x, end.y), BOUNDING_BOX_LINE_WIDTH, color);
+ }
+ lastPnt = pnt;
+ end = start;
+ shouldEnd = shouldStart;
+ }
+
+ // Next time around, draw the top of the cylinder.
+ z += ginfo.getMaxHeightAbovePosition();
+ }
+
+ // Draw centerline
+ pnt.x = pos.x;
+ pnt.y = pos.y;
+ pnt.z = pos.z;
+ shouldStart = worldToScreen( &pnt, &start, camera);
+ pnt.z = pos.z + ginfo.getMaxHeightAbovePosition();
+ shouldEnd = worldToScreen( &pnt, &end, camera);
+ if (shouldStart && shouldEnd) {
+ m_lineRenderer->Add_Line(Vector2(start.x, start.y), Vector2(end.x, end.y), BOUNDING_BOX_LINE_WIDTH, color);
+ }
+ break;
+ }
+ }
+}
+
+/** Draw a "circle" into the m_lineRenderer, e.g. to visualize weapon range, sight range, sound range **/
+void DrawObject::addCircleToLineRenderer( const Coord3D & center, Real radius, Real width, unsigned long color, CameraClass* camera )
+{
+ Real angle, inc = PI/4.0f;
+ Coord3D pnt, lastPnt;
+ ICoord2D start, end;
+ Real z = center.z;
+
+ // Draw the circle.
+ angle = 0.0f;
+ lastPnt.x = center.x + radius * (Real)cos(angle);
+ lastPnt.y = center.y + radius * (Real)sin(angle);
+ lastPnt.z = z;
+ bool shouldEnd = worldToScreen(&lastPnt, &end, camera);
+
+ for( angle = inc; angle <= 2.0f * PI; angle += inc ) {
+ pnt.x = center.x + radius * (Real)cos(angle);
+ pnt.y = center.y + radius * (Real)sin(angle);
+ pnt.z = z;
+
+ bool shouldStart = worldToScreen(&pnt, &start, camera);
+ if (shouldStart && shouldEnd) {
+ m_lineRenderer->Add_Line(Vector2(start.x, start.y), Vector2(end.x, end.y), width, color);
+ }
+
+ lastPnt = pnt;
+ end = start;
+ shouldEnd = shouldStart;
+ }
+
+}
+
+#define SIGHT_RANGE_LINE_WIDTH 2.0f
+/** Draw an object's sight range into the vertex buffer. **/
+// MLL C&C3
+void DrawObject::updateVBWithSightRange(MapObject *pMapObj, CameraClass* camera)
+{
+ if (!pMapObj || !m_lineRenderer || !pMapObj->getThingTemplate()) {
+ return;
+ }
+
+ const unsigned long color = 0xFFF0F0F0; // Light blue.
+
+ Real radius = pMapObj->getThingTemplate()->friend_calcVisionRange();
+
+ Coord3D pos = *pMapObj->getLocation();
+ if (TheTerrainRenderObject) {
+ // Make sure that the position is on the terrain.
+ pos.z += TheTerrainRenderObject->getHeightMapHeight(pos.x, pos.y, nullptr);
+ }
+
+ addCircleToLineRenderer(pos, radius, SIGHT_RANGE_LINE_WIDTH, color, camera );
+}
+
+#define WEAPON_RANGE_LINE_WIDTH 1.0f
+/** Draw an object's weapon range into the vertex buffer. **/
+// MLL C&C3
+void DrawObject::updateVBWithWeaponRange(MapObject *pMapObj, CameraClass* camera)
+{
+ if (!pMapObj || !m_lineRenderer || !pMapObj->getThingTemplate()) {
+ return;
+ }
+
+ const unsigned long colors[WEAPONSLOT_COUNT] = {0xFF00FF00, 0xFFE0F00A, 0xFFFF0000}; // Green, Yellow, Red
+
+
+ Coord3D pos = *pMapObj->getLocation();
+ if (TheTerrainRenderObject) {
+ // Make sure that the position is on the terrain.
+ pos.z += TheTerrainRenderObject->getHeightMapHeight(pos.x, pos.y, nullptr);
+ }
+
+ const WeaponTemplateSetVector& weapons = pMapObj->getThingTemplate()->getWeaponTemplateSets();
+
+ for (WeaponTemplateSetVector::const_iterator it = weapons.begin(); it != weapons.end(); ++it) {
+ if (it->hasAnyWeapons() == false) {
+ continue;
+ }
+
+ for (int i = 0; i < WEAPONSLOT_COUNT; i++) {
+ const WeaponTemplate* tmpl = it->getNth((WeaponSlotType)i);
+
+ if (tmpl == nullptr) {
+ continue;
+ }
+
+ Real radius = tmpl->getUnmodifiedAttackRange();
+
+ addCircleToLineRenderer(pos, radius, WEAPON_RANGE_LINE_WIDTH, colors[i], camera );
+ }
+ }
+}
+
+#define SOUND_RANGE_LINE_WIDTH 1.0f
+/** Draw an object's min & max sound ranges into the vertex buffer. **/
+// MLL C&C3
+void DrawObject::updateVBWithSoundRanges(MapObject *pMapObj, CameraClass* camera)
+{
+ if (!pMapObj || !m_lineRenderer) {
+ return;
+ }
+
+ const unsigned long colors[2] = {0xFF0000FF, 0xFFFF00FF}; // Blue and purple
+ // Colors match those used in W3DView.cpp
+
+
+ Coord3D pos = *pMapObj->getLocation();
+ if (TheTerrainRenderObject) {
+ // Make sure that the position is on the terrain.
+ pos.z += TheTerrainRenderObject->getHeightMapHeight(pos.x, pos.y, nullptr);
+ }
+
+ // Does this object actually have an attached sound?
+ const AudioEventInfo * audioInfo = nullptr;
+
+ Dict * properties = pMapObj->getProperties();
+
+ Bool exists = false;
+ AsciiString ambientName = properties->getAsciiString( TheKey_objectSoundAmbient, &exists );
+
+ if ( exists )
+ {
+ if ( ambientName.isEmpty() )
+ {
+ // User has removed normal sound
+ return;
+ }
+ else
+ {
+ if ( TheAudio == nullptr )
+ {
+ DEBUG_CRASH( ("TheAudio is null! Can't draw sound circles") );
+ return;
+ }
+
+ audioInfo = TheAudio->findAudioEventInfo( ambientName );
+
+ if ( audioInfo == nullptr )
+ {
+ DEBUG_CRASH( ("Override audio named %s is missing; Can't draw sound circles", ambientName.str() ) );
+ return;
+ }
+ }
+ }
+ else
+ {
+ const ThingTemplate * thingTemplate = pMapObj->getThingTemplate();
+ if ( thingTemplate == nullptr )
+ {
+ // No sound if no template
+ return;
+ }
+
+ if ( !thingTemplate->hasSoundAmbient() )
+ {
+ return;
+ }
+
+ const AudioEventRTS * event = thingTemplate->getSoundAmbient();
+
+ if ( event == nullptr )
+ {
+ return;
+ }
+
+ audioInfo = event->getAudioEventInfo();
+
+ if ( audioInfo == nullptr )
+ {
+ // May just not be set up yet
+ if ( TheAudio == nullptr )
+ {
+ DEBUG_CRASH( ("TheAudio is null! Can't draw sound circles") );
+ return;
+ }
+
+ audioInfo = TheAudio->findAudioEventInfo( event->getEventName() );
+
+ if ( audioInfo == nullptr )
+ {
+ DEBUG_CRASH( ("Default ambient sound %s has no info; Can't draw sound circles", event->getEventName().str() ) );
+ return;
+ }
+ }
+ }
+
+ // Should have set up audioInfo or returned by now
+ DEBUG_ASSERTCRASH( audioInfo != nullptr, ("Managed to finish setting up audio info without setting it?!?" ) );
+ if ( audioInfo == nullptr )
+ {
+ return;
+ }
+
+ // Get the current radius (could be overridden)
+ Real minRadius = audioInfo->m_minDistance;
+ Real maxRadius = audioInfo->m_maxDistance;
+ Bool customized = properties->getBool( TheKey_objectSoundAmbientCustomized, &exists );
+ if ( exists && customized )
+ {
+ Real valReal;
+
+ valReal = properties->getReal( TheKey_objectSoundAmbientMinRange, &exists );
+ if ( exists )
+ {
+ minRadius = valReal;
+ }
+ valReal = properties->getReal( TheKey_objectSoundAmbientMaxRange, &exists );
+ if ( exists )
+ {
+ maxRadius = valReal;
+ }
+ }
+ addCircleToLineRenderer(pos, minRadius, SOUND_RANGE_LINE_WIDTH, colors[0], camera );
+ addCircleToLineRenderer(pos, maxRadius, SOUND_RANGE_LINE_WIDTH, colors[1], camera );
+}
+
+
+#define TEST_ART_HIGHLIGHT_LINE_WIDTH 5.0f
+/** Draw test art with an X on it. **/
+// MLL C&C3
+void DrawObject::updateVBWithTestArtHighlight(MapObject *pMapObj, CameraClass* camera)
+{
+ if (!pMapObj || !m_lineRenderer || pMapObj->getThingTemplate() || pMapObj->isScorch()) {
+ // It is test art if it doesn't have a ThingTemplate.
+ return;
+ }
+
+ unsigned long color = 0xFFA000A0; // Purple
+
+
+ Coord3D pos = *pMapObj->getLocation();
+ if (TheTerrainRenderObject) {
+ // Make sure that the position is on the terrain.
+ pos.z += TheTerrainRenderObject->getHeightMapHeight(pos.x, pos.y, nullptr);
+ }
+
+ Real angle, inc = PI/2.0f;
+ Coord3D pnt, lastPnt;
+ ICoord2D start, end;
+ Real z = pos.z;
+ Real radius = 30.0f;
+
+ // Draw the diamond.
+ angle = 0.0f;
+ lastPnt.x = pos.x + radius * (Real)cos(angle);
+ lastPnt.y = pos.y + radius * (Real)sin(angle);
+ lastPnt.z = z;
+ bool shouldEnd = worldToScreen(&lastPnt, &end, camera);
+
+ for( angle = inc; angle <= 2.0f * PI; angle += inc ) {
+ pnt.x = pos.x + radius * (Real)cos(angle);
+ pnt.y = pos.y + radius * (Real)sin(angle);
+ pnt.z = z;
+
+ bool shouldStart = worldToScreen(&pnt, &start, camera);
+ if (shouldStart && shouldEnd) {
+ m_lineRenderer->Add_Line(Vector2(start.x, start.y), Vector2(end.x, end.y), TEST_ART_HIGHLIGHT_LINE_WIDTH, color);
+ }
+
+ lastPnt = pnt;
+ end = start;
+ shouldEnd = shouldStart;
+ }
+
+}
+
+
+/** Transform a 3D Coordinate into 2D screen space **/
+// MLL C&C3
+bool DrawObject::worldToScreen(const Coord3D *w, ICoord2D *s, CameraClass* camera)
+{
+
+ if ((w == nullptr) || (s == nullptr) || (camera == nullptr)) {
+ return false;
+ }
+
+ Vector3 world;
+ Vector3 screen;
+
+ world.Set(w->x, w->y, w->z);
+ camera->Project(screen, world);
+
+ //
+ // note that the screen coord returned from the project W3D camera
+ // gave us a screen coords that range from (-1,-1) bottom left to
+ // (1,1) top right ... we are turning that into (0,0) upper left
+ // coords now
+ //
+ W3DLogicalScreenToPixelScreen(screen.X, screen.Y, &s->x, &s->y, m_winSize.x, m_winSize.y);
+
+ if ((screen.X > 2.0f) || (screen.Y > 2.0f) || (screen.X < -2.0f) || (screen.Y < -2.0f)) {
+ // Too far off the screen.
+ return false;
+ }
+
+ return (true);
+}
+
/** Tells drawobject where the tool is located, so it can draw feedback. */
void DrawObject::setFeedbackPos(Coord3D pos)
{
@@ -1620,25 +2054,55 @@ void DrawObject::setRampFeedbackParms(const Coord3D *start, const Coord3D *end,
}
+bool _skip_drawobject_render = false;
+
/** Render draws into the current 3d context. */
void DrawObject::Render(RenderInfoClass & rinfo)
{
+//DEBUG!
+if (_skip_drawobject_render) {
+ return;
+}
+
+ if (m_lineRenderer == nullptr) {
+ // This can't be created in init because the doc hasn't been created yet.
+ m_lineRenderer = new Render2DClass();
+ ASSERT(m_lineRenderer);
+ CWorldBuilderDoc *pDoc = CWorldBuilderDoc::GetActiveDoc();
+ ASSERT(pDoc);
+ WbView3d *pView = pDoc->Get3DView();
+ ASSERT(pView);
+ m_winSize = pView->getActualWinSize();
+ m_lineRenderer->Set_Coordinate_Range(RectClass(0, 0, m_winSize.x, m_winSize.y));
+ m_lineRenderer->Reset();
+ m_lineRenderer->Enable_Texturing(FALSE);
+ }
+
DX8Wrapper::Apply_Render_State_Changes();
DX8Wrapper::Set_Material(m_vertexMaterialClass);
DX8Wrapper::Set_Shader(m_shaderClass);
DX8Wrapper::Set_Texture(0, nullptr);
+ DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
DX8Wrapper::Apply_Render_State_Changes();
Int count=0;
Int i;
+ bool linesToRender = false;
+
curHighlight++;
if (curHighlight >= NUM_HIGHLIGHT) {
curHighlight = 0;
}
m_waterDrawObject->update();
- if (m_drawObjects || m_drawWaypoints) {
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferTile1);
+ if (m_drawObjects || m_drawWaypoints || m_drawBoundingBoxes || m_drawSightRanges || m_drawWeaponRanges || m_drawSoundRanges || m_drawTestArtHighlight) {
//Apply the shader and material
+ //WST Variables below are for optimization to reduce VB updates which are extremely slow
+ // Optimization strategy is to remember last setting and avoid re-updating unless it changed
+ int rememberLastSettingVB1 = -99999;
+ int rememberLastSettingVB2 = -99999;
+
MapObject *pMapObj;
for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
// simple Draw test.
@@ -1646,15 +2110,19 @@ void DrawObject::Render(RenderInfoClass & rinfo)
continue;
}
+// DEBUG!
+if (pMapObj->isSelected()) {
+ Transform.Get_Translation();
+}
Coord3D loc = *pMapObj->getLocation();
if (TheTerrainRenderObject) {
loc.z += TheTerrainRenderObject->getHeightMapHeight(loc.x, loc.y, nullptr);
}
// Cull.
- SphereClass bounds(Vector3(loc.x, loc.y, loc.z), THE_RADIUS);
- if (rinfo.Camera.Cull_Sphere(bounds)) {
- continue;
- }
+ //SphereClass bounds(Vector3(loc.x, loc.y, loc.z), THE_RADIUS);
+ //if (rinfo.Camera.Cull_Sphere(bounds)) {
+ // continue;
+ //}
Bool doArrow = true;
if (pMapObj->getFlag(FLAG_ROAD_FLAGS) || pMapObj->getFlag(FLAG_BRIDGE_FLAGS) || pMapObj->isWaypoint())
{
@@ -1667,6 +2135,31 @@ void DrawObject::Render(RenderInfoClass & rinfo)
continue;
}
} else {
+ // MLL C&C3
+ if (pMapObj->isSelected()) {
+ if (doArrow && m_drawBoundingBoxes) {
+ linesToRender = true;
+ updateVBWithBoundingBox(pMapObj, &rinfo.Camera);
+ }
+ if (doArrow && m_drawSightRanges) {
+ linesToRender = true;
+ updateVBWithSightRange(pMapObj, &rinfo.Camera);
+ }
+ if (doArrow && m_drawWeaponRanges) {
+ linesToRender = true;
+ updateVBWithWeaponRange(pMapObj, &rinfo.Camera);
+ }
+ if (doArrow && m_drawSoundRanges) {
+ linesToRender = true;
+ updateVBWithSoundRanges(pMapObj, &rinfo.Camera);
+ }
+ }
+
+ if (doArrow && m_drawTestArtHighlight) {
+ linesToRender = true;
+ updateVBWithTestArtHighlight(pMapObj, &rinfo.Camera);
+ }
+
if (!m_drawObjects) {
continue;
}
@@ -1676,13 +2169,38 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
if (count&1) {
- updateVB(m_vertexBufferTile1, pMapObj->getColor(), doArrow, doDiamond);
+ int setting = pMapObj->getColor();
+
+ if (doArrow) {
+ setting |= (1<<25);
+ }
+ if (doDiamond) {
+ setting |= (1<<26);
+ }
+
+ if (setting != rememberLastSettingVB1) {
+ rememberLastSettingVB1 = setting;
+ updateVB(m_vertexBufferTile1,pMapObj->getColor(), doArrow, doDiamond);
+ }
DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferTile1);
+
} else {
- updateVB(m_vertexBufferTile2, pMapObj->getColor(), doArrow, doDiamond);
+ int setting = pMapObj->getColor();
+
+ if (doArrow) {
+ setting |= (1<<25);
+ }
+ if (doDiamond) {
+ setting |= (1<<26);
+ }
+
+ if (setting != rememberLastSettingVB2) {
+ rememberLastSettingVB2 = setting;
+ updateVB(m_vertexBufferTile2, pMapObj->getColor(), doArrow, doDiamond);
+ }
DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferTile2);
}
- count++;
+
///@todo - remove the istree stuff, or get the info from the thing template. jba.
Bool isTree = false;
@@ -1699,24 +2217,22 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
DX8Wrapper::Set_Transform(D3DTS_WORLD,tm);
- DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
-
if (isTree) {
DX8Wrapper::Draw_Triangles( NUM_TRI*3,polyCount, 0, (m_numTriangles*3));
} else {
DX8Wrapper::Draw_Triangles( 0,polyCount, 0, (m_numTriangles*3));
}
+
+ count++;
}
}
-
- DX8Wrapper::Set_Vertex_Buffer(nullptr); //release reference to vertex buffer
- DX8Wrapper::Set_Index_Buffer(nullptr,0); //release reference to vertex buffer
-
if (m_drawPolygonAreas) {
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
Int selected;
for (selected = 0; selected < 2; selected++) {
for (PolygonTrigger *pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) {
DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
+ if (!pTrig->getShouldRender()) continue;
Bool polySelected = PolygonTool::isSelected(pTrig);
if (polySelected && !selected) continue;
if (!polySelected && selected) continue;
@@ -1775,8 +2291,6 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
}
- DX8Wrapper::Set_Vertex_Buffer(nullptr); //release reference to vertex buffer
- DX8Wrapper::Set_Index_Buffer(nullptr,0); //release reference to vertex buffer
if (BuildListTool::isActive()) for (i=0; igetNumSides(); i++) {
SidesInfo *pSide = TheSidesList->getSideInfo(i);
@@ -1816,16 +2330,15 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
#if 1
- DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
DX8Wrapper::Set_Transform(D3DTS_WORLD,tmXX);
DX8Wrapper::Draw_Triangles( 0,polyCountA, 0, (m_numTriangles*3));
#endif
+
}
}
- DX8Wrapper::Set_Vertex_Buffer(nullptr); //release reference to vertex buffer
- DX8Wrapper::Set_Index_Buffer(nullptr,0); //release reference to vertex buffer
-
+ DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
Matrix3D tmReset(Transform);
DX8Wrapper::Set_Transform(D3DTS_WORLD,tmReset);
@@ -1836,13 +2349,12 @@ void DrawObject::Render(RenderInfoClass & rinfo)
DX8Wrapper::Set_Index_Buffer(m_indexFeedback,0);
DX8Wrapper::Set_Shader(m_shaderClass);
DX8Wrapper::Draw_Triangles( 0, m_feedbackIndexCount/3, 0, m_feedbackVertexCount);
-// DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
- // DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
+ DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
}
}
- DX8Wrapper::Set_Vertex_Buffer(nullptr); //release reference to vertex buffer
- DX8Wrapper::Set_Index_Buffer(nullptr,0); //release reference to vertex buffer
+
#if 1
if (m_meshFeedback) {
@@ -1865,9 +2377,6 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
#endif
- DX8Wrapper::Set_Vertex_Buffer(nullptr); //release reference to vertex buffer
- DX8Wrapper::Set_Index_Buffer(nullptr,0); //release reference to vertex buffer
-
#if 1
if (m_rampFeedback) {
updateRampVB();
@@ -1882,9 +2391,6 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
#endif
- DX8Wrapper::Set_Vertex_Buffer(nullptr); //release reference to vertex buffer
- DX8Wrapper::Set_Index_Buffer(nullptr,0); //release reference to vertex buffer
-
#if 1
if (m_boundaryFeedback) {
updateBoundaryVB();
@@ -1917,13 +2423,31 @@ void DrawObject::Render(RenderInfoClass & rinfo)
}
}
- DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
+ DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
if (m_waterDrawObject) {
m_waterDrawObject->renderWater();
}
+ if (m_drawLetterbox) {
+ int w = m_winSize.x;
+ int h = m_winSize.y;
+ int size = (int)((h - (9.0f / 16.0f * w)) * 0.5f);
+ RectClass rect(0, 0, w, size);
+ m_lineRenderer->Add_Quad(rect, 0xFF000000);
+ rect.Set(0, h - size, w, h);
+ m_lineRenderer->Add_Quad(rect, 0xFF000000);
+ linesToRender = true;
+ }
+
+ // Render any lines that have been added, like bounding boxes.
+ // MLL C&C3
+ if (linesToRender && m_lineRenderer) {
+ m_lineRenderer->Render();
+ // Clear the old lines.
+ m_lineRenderer->Reset();
+ }
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/EditAction.cpp b/Generals/Code/Tools/WorldBuilder/src/EditAction.cpp
index c7bce6af8ef..53b43357247 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EditAction.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EditAction.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -50,11 +50,42 @@ void EditAction::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(EditAction, CDialog)
//{{AFX_MSG_MAP(EditAction)
- ON_CBN_SELCHANGE(IDC_CONDITION_TYPE, OnSelchangeScriptActionType)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
+/** Locate the child item in tree item parent with name pLabel. If not
+found, add it. Either way, return child. */
+static HTREEITEM findOrAdd(CTreeCtrl *tree, HTREEITEM parent, const char *pLabel)
+{
+ TVINSERTSTRUCT ins;
+ char buffer[_MAX_PATH];
+ ::memset(&ins, 0, sizeof(ins));
+ HTREEITEM child = tree->GetChildItem(parent);
+ while (child != nullptr) {
+ ins.item.mask = TVIF_HANDLE|TVIF_TEXT;
+ ins.item.hItem = child;
+ ins.item.pszText = buffer;
+ ins.item.cchTextMax = sizeof(buffer)-2;
+ tree->GetItem(&ins.item);
+ if (strcmp(buffer, pLabel) == 0) {
+ return(child);
+ }
+ child = tree->GetNextSiblingItem(child);
+ }
+
+ // not found, so add it.
+ ::memset(&ins, 0, sizeof(ins));
+ ins.hParent = parent;
+ ins.hInsertAfter = TVI_SORT;
+ ins.item.mask = TVIF_PARAM|TVIF_TEXT;
+ ins.item.lParam = -1;
+ ins.item.pszText = (char*)pLabel;
+ ins.item.cchTextMax = strlen(pLabel);
+ child = tree->InsertItem(&ins);
+ return(child);
+}
+
/////////////////////////////////////////////////////////////////////////////
// EditAction message handlers
@@ -65,39 +96,117 @@ BOOL EditAction::OnInitDialog()
// CDC *pDc =GetDC();
+ CRect rect;
+
+ CTreeCtrl *pTree = (CTreeCtrl *)GetDlgItem(IDC_ACTION_TREE);
+ pTree->GetWindowRect(&rect);
+
+ ScreenToClient(&rect);
+ m_actionTreeView.Create(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|
+ TVS_SHOWSELALWAYS|TVS_DISABLEDRAGDROP|WS_TABSTOP, rect, this, IDC_ACTION_TREE);
+ m_actionTreeView.ShowWindow(SW_SHOW);
+ pTree->DestroyWindow();
CWnd *pWnd = GetDlgItem(IDC_RICH_EDIT_HERE);
- CRect rect;
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);
rect.DeflateRect(2,2,2,2);
- m_myEditCtrl.Create(WS_CHILD | ES_MULTILINE, rect, this, IDC_RICH_EDIT_HERE+1);
+ m_myEditCtrl.Create(WS_CHILD | WS_TABSTOP | ES_MULTILINE, rect, this, IDC_RICH_EDIT_HERE+1);
m_myEditCtrl.ShowWindow(SW_SHOW);
- m_myEditCtrl.SetEventMask(m_myEditCtrl.GetEventMask() | ENM_LINK | ENM_SELCHANGE);
+ m_myEditCtrl.SetEventMask(m_myEditCtrl.GetEventMask() | ENM_LINK | ENM_SELCHANGE | ENM_KEYEVENTS);
- CComboBox *pCmbo = (CComboBox *)GetDlgItem(IDC_CONDITION_TYPE);
- pCmbo->ResetContent();
Int i;
+ HTREEITEM selItem = nullptr;
for (i=0; igetActionTemplate(i);
- Int ndx = pCmbo->AddString(pTemplate->getName().str());
+ char prefix[_MAX_PATH];
+ const char *name = pTemplate->getName().str();
+
+ Int count = 0;
+ HTREEITEM parent = TVI_ROOT;
+ do {
+ count = 0;
+ const char *nameStart = name;
+ while (*name && *name != '/') {
+ count++;
+ name++;
+ }
+ if (*name=='/') {
+ count++;
+ name++;
+ } else {
+ name = nameStart;
+ count = 0;
+ }
+ if (count>0) {
+ strlcpy(prefix, nameStart, count);
+ parent = findOrAdd(&m_actionTreeView, parent, prefix);
+ }
+ } while (count>0);
+
+ TVINSERTSTRUCT ins;
+ ::memset(&ins, 0, sizeof(ins));
+ ins.hParent = parent;
+ ins.hInsertAfter = TVI_SORT;
+ ins.item.mask = TVIF_PARAM|TVIF_TEXT;
+ ins.item.lParam = i;
+ ins.item.pszText = (char*)name;
+ ins.item.cchTextMax = 0;
+ HTREEITEM item = m_actionTreeView.InsertItem(&ins);
if (i == m_action->getActionType()) {
- pCmbo->SetCurSel(ndx);
+ selItem = item;
}
+
+#if RTS_ZEROHOUR
+ name = pTemplate->getName2().str();
+ count = 0;
+ if (pTemplate->getName2().isEmpty()) continue;
+ parent = TVI_ROOT;
+ do {
+ count = 0;
+ const char *nameStart = name;
+ while (*name && *name != '/') {
+ count++;
+ name++;
+ }
+ if (*name=='/') {
+ count++;
+ name++;
+ } else {
+ name = nameStart;
+ count = 0;
+ }
+ if (count>0) {
+ strlcpy(prefix, nameStart, count);
+ parent = findOrAdd(&m_actionTreeView, parent, prefix);
+ }
+ } while (count>0);
+
+ ::memset(&ins, 0, sizeof(ins));
+ ins.hParent = parent;
+ ins.hInsertAfter = TVI_SORT;
+ ins.item.mask = TVIF_PARAM|TVIF_TEXT;
+ ins.item.lParam = i;
+ ins.item.pszText = (char*)name;
+ ins.item.cchTextMax = 0;
+ m_actionTreeView.InsertItem(&ins);
+#endif
}
+ m_actionTreeView.Select(selItem, TVGN_FIRSTVISIBLE);
+ m_actionTreeView.SelectItem(selItem);
m_action->setWarnings(false);
m_myEditCtrl.SetWindowText(m_action->getUiText().str());
m_myEditCtrl.SetSel(-1, -1);
- formatScriptActionText(-1);
+ formatScriptActionText(0);
+ m_actionTreeView.SetFocus();
- return TRUE; // return TRUE unless you set the focus to a control
+ return FALSE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
-void EditAction::formatScriptActionText(Int parameterNdx)
-{
+void EditAction::formatScriptActionText(Int parameterNdx) {
CHARFORMAT2 cf;
m_updating = true;
long startSel, endSel;
@@ -114,12 +223,13 @@ void EditAction::formatScriptActionText(Int parameterNdx)
m_myEditCtrl.SetSel(0, 1000);
m_myEditCtrl.SetSelectionCharFormat(cf);
- m_myEditCtrl.SetReadOnly();
+ //m_myEditCtrl.SetReadOnly();
// Set up the links.
cf.dwMask = CFE_UNDERLINE | CFM_LINK | CFM_COLOR;
cf.dwEffects = CFE_LINK | CFE_UNDERLINE;
cf.crTextColor = RGB(0,0,255);
+ m_curEditParameter = parameterNdx;
AsciiString strings[MAX_PARMS];
Int curChar = 0;
@@ -133,10 +243,13 @@ void EditAction::formatScriptActionText(Int parameterNdx)
curChar += strings[i].getLength();
}
if (igetNumParameters()) {
- warningText.concat(EditParameter::getWarningText(m_action->getParameter(i)));
+ warningText.concat(EditParameter::getWarningText(m_action->getParameter(i), false));
informationText.concat(EditParameter::getInfoText(m_action->getParameter(i)));
numChars = m_action->getParameter(i)->getUiText().getLength();
- if (numChars==0) continue;
+ if (curChar==0) {
+ curChar++;
+ numChars--;
+ }
m_myEditCtrl.SetSel(curChar, curChar+numChars);
if (i==parameterNdx) {
startSel = curChar;
@@ -175,6 +288,8 @@ void EditAction::formatScriptActionText(Int parameterNdx)
m_modifiedTextColor = false;
m_myEditCtrl.SetSel(startSel, endSel);
+ m_curLinkChrg.cpMax = endSel;
+ m_curLinkChrg.cpMin = startSel;
m_updating = false;
}
@@ -182,125 +297,159 @@ void EditAction::formatScriptActionText(Int parameterNdx)
BOOL EditAction::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
- if (LOWORD(wParam) == IDC_RICH_EDIT_HERE+1)
- {
+ NMTREEVIEW *pHdr = (NMTREEVIEW *)lParam;
+
+ // Handle events from the tree control.
+ if (pHdr->hdr.idFrom == IDC_ACTION_TREE) {
+ if (pHdr->hdr.code == TVN_SELCHANGED) {
+ char buffer[_MAX_PATH];
+ HTREEITEM hItem = m_actionTreeView.GetSelectedItem();
+ TVITEM item;
+ ::memset(&item, 0, sizeof(item));
+ item.mask = TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT|TVIF_STATE;
+ item.hItem = hItem;
+ item.pszText = buffer;
+ item.cchTextMax = sizeof(buffer)-2;
+ m_actionTreeView.GetItem(&item);
+ if (item.lParam >= 0) {
+ enum ScriptAction::ScriptActionType actionType = (enum ScriptAction::ScriptActionType)item.lParam;
+ if (m_action->getActionType() != actionType) {
+ m_action->setActionType( actionType );
+ m_myEditCtrl.SetWindowText(m_action->getUiText().str());
+ formatScriptActionText(0);
+ }
+ }
+ } else if (pHdr->hdr.code == TVN_KEYDOWN) {
+ NMTVKEYDOWN *pKey = (NMTVKEYDOWN*)lParam;
+ Int key = pKey->wVKey;
+ if (key==VK_SHIFT || key==VK_SPACE) {
+ HTREEITEM hItem = m_actionTreeView.GetSelectedItem();
+ if (!m_actionTreeView.ItemHasChildren(hItem)) {
+ hItem = m_actionTreeView.GetParentItem(hItem);
+ }
+ m_actionTreeView.Expand(hItem, TVE_TOGGLE);
+ return 0;
+ }
+ return 0;
+ }
+ return TRUE;
+ }
+
+ // Handle events from the rich edit control containing the action pieces.
+ if (LOWORD(wParam) == IDC_RICH_EDIT_HERE+1) {
NMHDR *pHdr = (NMHDR *)lParam;
- if (pHdr->hwndFrom == m_myEditCtrl.m_hWnd && pHdr->code == EN_LINK)
- {
- ENLINK *pLink = (ENLINK *)pHdr;
- CHARRANGE chrg = pLink->chrg;
- if (pLink->msg == WM_LBUTTONDOWN)
- {
+ if (pHdr->hwndFrom == m_myEditCtrl.m_hWnd) {
+ if (pHdr->code == EN_LINK) {
+ ENLINK *pLink = (ENLINK *)pHdr;
+ CHARRANGE chrg = pLink->chrg;
// Determine which parameter.
Int numChars = 0;
Int curChar = 0;
AsciiString strings[MAX_PARMS];
Int numStrings = m_action->getUiStrings(strings);
Int i;
- for (i=0; igetNumParameters())
- {
+ if (igetNumParameters()) {
numChars = m_action->getParameter(i)->getUiText().getLength();
- if (curChar == chrg.cpMin && curChar+numChars == chrg.cpMax)
- {
- //Kris:
- //Before we edit the parameter, there is a new prerequisite for parameters
- //but only a few will ever care. We will store what we perceive as the unit,
- //and for simplicity, we'll store the first occurrence of the unit, although
- //this can change in the future should the need arise.
- AsciiString unitName;
- for( int j = 0; j < MAX_PARMS; j++ )
- {
- Parameter *parameter = m_action->getParameter( j );
- if( parameter && parameter->getParameterType() == Parameter::UNIT )
- {
- unitName = parameter->getString();
- break;
- }
- }
-
- if( EditParameter::edit( m_action->getParameter(i), unitName ) == IDOK )
- {
- m_myEditCtrl.SetWindowText(m_action->getUiText().str());
- m_curEditParameter = i;
- this->PostMessage(WM_TIMER, 0, 0);
- }
- return true;
+ match = (curChar+numChars/2 > chrg.cpMin && curChar+numChars/2 < chrg.cpMax);
+ if (match) {
+ m_curEditParameter = i;
+ break;
}
curChar += numChars;
}
}
- }
- CHARRANGE curChrg;
- m_myEditCtrl.GetSel(curChrg);
- if (curChrg.cpMin == chrg.cpMin && curChrg.cpMax == chrg.cpMax)
- {
- return true;
- }
- if (m_modifiedTextColor)
- {
- formatScriptActionText(-1);
- }
- m_curLinkChrg = chrg;
- m_myEditCtrl.SetSel(chrg.cpMin, chrg.cpMax);
- CHARFORMAT cf;
- memset(&cf, 0, sizeof(cf));
- cf.cbSize = sizeof(cf);
- cf.dwMask = CFM_COLOR;
- cf.crTextColor = RGB(0,0,0);
- m_myEditCtrl.SetSelectionCharFormat(cf);
- m_modifiedTextColor = true;
- return true;
- }
- else if (pHdr->hwndFrom == m_myEditCtrl.m_hWnd && pHdr->code == EN_SELCHANGE)
- {
- if (m_updating)
- {
- return true;
- }
- CHARRANGE curChrg;
- m_myEditCtrl.GetSel(curChrg);
- if (curChrg.cpMin == m_curLinkChrg.cpMin && curChrg.cpMax == m_curLinkChrg.cpMax)
- {
+ if (pLink->msg == WM_LBUTTONDOWN)
+ {
+ // Determine which parameter.
+ if (match)
+ {
+ if( m_action->getParameter( m_curEditParameter )->getParameterType() == Parameter::COMMANDBUTTON_ABILITY )
+ {
+ EditParameter::edit(m_action->getParameter(m_curEditParameter), 0, m_action->getParameter(0)->getString() );
+ }
+ else
+ {
+ EditParameter::edit(m_action->getParameter(m_curEditParameter), 0 );
+ }
+ m_myEditCtrl.SetWindowText(m_action->getUiText().str());
+ this->PostMessage(WM_TIMER, 0, 0);
+ return true;
+ }
+ }
+ CHARRANGE curChrg;
+ m_myEditCtrl.GetSel(curChrg);
+ if (curChrg.cpMin == chrg.cpMin && curChrg.cpMax == chrg.cpMax) {
+ return true;
+ }
+ if (m_modifiedTextColor) {
+ formatScriptActionText(m_curEditParameter);
+ }
+ m_curLinkChrg = chrg;
+ m_myEditCtrl.SetSel(chrg.cpMin, chrg.cpMax);
+ m_myEditCtrl.SetFocus();
+ CHARFORMAT cf;
+ memset(&cf, 0, sizeof(cf));
+ cf.cbSize = sizeof(cf);
+ cf.dwMask = CFM_COLOR;
+ cf.crTextColor = RGB(0,0,0);
+ m_myEditCtrl.SetSelectionCharFormat(cf);
+ m_modifiedTextColor = true;
return true;
- }
- if (m_modifiedTextColor)
- {
- formatScriptActionText(-1);
+ } else if (pHdr->code == EN_SETFOCUS) {
+ this->PostMessage(WM_TIMER, 0, 0);
+ } else if (pHdr->code == EN_SELCHANGE) {
+ if (m_updating) {
+ return true;
+ }
+ CHARRANGE curChrg;
+ m_myEditCtrl.GetSel(curChrg);
+ if (curChrg.cpMin == m_curLinkChrg.cpMin && curChrg.cpMax == m_curLinkChrg.cpMax) {
+ return true;
+ }
+ m_myEditCtrl.SetSel(m_curLinkChrg.cpMin, m_curLinkChrg.cpMax);
+ if (m_modifiedTextColor) {
+ this->PostMessage(WM_TIMER, 0, 0);
+ }
+ } else if (pHdr->code == EN_MSGFILTER) {
+ MSGFILTER *pFilter = (MSGFILTER *)pHdr;
+ if (pFilter->msg == WM_CHAR) {
+ Int keyPressed = pFilter->wParam;
+ if (keyPressed==VK_RETURN) {
+ return 1;
+ }
+ if (keyPressed==VK_RETURN || keyPressed == VK_TAB) {
+ m_curEditParameter++;
+ if (m_curEditParameter >= m_action->getNumParameters()) {
+ m_curEditParameter = 0;
+ return 1;
+ }
+ this->PostMessage(WM_TIMER, 0, 0);
+ return 0;
+ }
+ EditParameter::edit(m_action->getParameter(m_curEditParameter), keyPressed);
+ m_curEditParameter++;
+ if (m_curEditParameter >= m_action->getNumParameters()) {
+ m_curEditParameter = 0;
+ }
+ this->PostMessage(WM_TIMER, 0, 0);
+ return 0;
+ }
+ return 1;
}
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
-void EditAction::OnSelchangeScriptActionType()
-{
- CComboBox *pCombo = (CComboBox *)GetDlgItem(IDC_CONDITION_TYPE);
- Int index = 0;
- CString str;
- pCombo->GetWindowText(str);
- Int i;
- for (i=0; igetActionTemplate(i);
- if (str == pTemplate->getName().str()) {
- index = i;
- break;
- }
- }
-
- m_action->setActionType((enum ScriptAction::ScriptActionType)i );
- m_myEditCtrl.SetWindowText(m_action->getUiText().str());
- formatScriptActionText(-1);
-}
-
/** Not actually a timer - just used to send a delayed message to self because rich
edit control is stupid. jba. */
void EditAction::OnTimer(UINT nIDEvent)
{
+ m_myEditCtrl.SetWindowText(m_action->getUiText().str());
formatScriptActionText(m_curEditParameter);
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/EditCondition.cpp b/Generals/Code/Tools/WorldBuilder/src/EditCondition.cpp
index 4ea362a23aa..c77b7253b6f 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EditCondition.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EditCondition.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -25,6 +25,18 @@
#include "EditParameter.h"
#include "GameLogic/ScriptEngine.h"
+
+LRESULT CMyTreeCtrl::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
+{
+ if (message==WM_KEYDOWN) {
+ Int nVirtKey = (int) wParam; // virtual-key code
+ if (nVirtKey == ' ') {
+ return 0;
+ }
+ }
+ return CTreeCtrl::WindowProc(message, wParam, lParam);
+}
+
/////////////////////////////////////////////////////////////////////////////
// EditCondition dialog
@@ -54,6 +66,38 @@ BEGIN_MESSAGE_MAP(EditCondition, CDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
+/** Locate the child item in tree item parent with name pLabel. If not
+found, add it. Either way, return child. */
+static HTREEITEM findOrAdd(CTreeCtrl *tree, HTREEITEM parent, const char *pLabel)
+{
+ TVINSERTSTRUCT ins;
+ char buffer[_MAX_PATH];
+ ::memset(&ins, 0, sizeof(ins));
+ HTREEITEM child = tree->GetChildItem(parent);
+ while (child != nullptr) {
+ ins.item.mask = TVIF_HANDLE|TVIF_TEXT;
+ ins.item.hItem = child;
+ ins.item.pszText = buffer;
+ ins.item.cchTextMax = sizeof(buffer)-2;
+ tree->GetItem(&ins.item);
+ if (strcmp(buffer, pLabel) == 0) {
+ return(child);
+ }
+ child = tree->GetNextSiblingItem(child);
+ }
+
+ // not found, so add it.
+ ::memset(&ins, 0, sizeof(ins));
+ ins.hParent = parent;
+ ins.hInsertAfter = TVI_SORT;
+ ins.item.mask = TVIF_PARAM|TVIF_TEXT;
+ ins.item.lParam = -1;
+ ins.item.pszText = (char*)pLabel;
+ ins.item.cchTextMax = strlen(pLabel);
+ child = tree->InsertItem(&ins);
+ return(child);
+}
+
/////////////////////////////////////////////////////////////////////////////
// EditCondition message handlers
@@ -64,33 +108,112 @@ BOOL EditCondition::OnInitDialog()
// CDC *pDc =GetDC();
+ CRect rect;
+
+ CTreeCtrl *pTree = (CTreeCtrl *)GetDlgItem(IDC_CONDITION_TREE);
+ pTree->GetWindowRect(&rect);
+
+ ScreenToClient(&rect);
+ m_conditionTreeView.Create(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|
+ TVS_SHOWSELALWAYS|TVS_DISABLEDRAGDROP|WS_TABSTOP, rect, this, IDC_CONDITION_TREE);
+ m_conditionTreeView.ShowWindow(SW_SHOW);
+ pTree->DestroyWindow();
CWnd *pWnd = GetDlgItem(IDC_RICH_EDIT_HERE);
- CRect rect;
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);
rect.DeflateRect(2,2,2,2);
- m_myEditCtrl.Create(WS_CHILD | ES_MULTILINE, rect, this, IDC_RICH_EDIT_HERE+1);
+ m_myEditCtrl.Create(WS_CHILD | WS_TABSTOP | ES_MULTILINE, rect, this, IDC_RICH_EDIT_HERE+1);
m_myEditCtrl.ShowWindow(SW_SHOW);
- m_myEditCtrl.SetEventMask(m_myEditCtrl.GetEventMask() | ENM_LINK | ENM_SELCHANGE);
+ m_myEditCtrl.SetEventMask(m_myEditCtrl.GetEventMask() | ENM_LINK | ENM_SELCHANGE | ENM_KEYEVENTS);
- CComboBox *pCmbo = (CComboBox *)GetDlgItem(IDC_CONDITION_TYPE);
- pCmbo->ResetContent();
Int i;
+ HTREEITEM selItem = nullptr;
for (i=0; igetConditionTemplate(i);
- Int ndx = pCmbo->AddString(pTemplate->getName().str());
+ char prefix[_MAX_PATH];
+ const char *name = pTemplate->getName().str();
+
+ Int count = 0;
+ HTREEITEM parent = TVI_ROOT;
+ do {
+ count = 0;
+ const char *nameStart = name;
+ while (*name && *name != '/') {
+ count++;
+ name++;
+ }
+ if (*name=='/') {
+ count++;
+ name++;
+ } else {
+ name = nameStart;
+ count = 0;
+ }
+ if (count>0) {
+ strlcpy(prefix, nameStart, count);
+ parent = findOrAdd(&m_conditionTreeView, parent, prefix);
+ }
+ } while (count>0);
+
+ TVINSERTSTRUCT ins;
+ ::memset(&ins, 0, sizeof(ins));
+ ins.hParent = parent;
+ ins.hInsertAfter = TVI_SORT;
+ ins.item.mask = TVIF_PARAM|TVIF_TEXT;
+ ins.item.lParam = i;
+ ins.item.pszText = (char*)name;
+ ins.item.cchTextMax = 0;
+ HTREEITEM item = m_conditionTreeView.InsertItem(&ins);
if (i == m_condition->getConditionType()) {
- pCmbo->SetCurSel(ndx);
+ selItem = item;
}
+
+#if RTS_ZEROHOUR
+ name = pTemplate->getName2().str();
+ count = 0;
+ if (pTemplate->getName2().isEmpty()) continue;
+ parent = TVI_ROOT;
+ do {
+ count = 0;
+ const char *nameStart = name;
+ while (*name && *name != '/') {
+ count++;
+ name++;
+ }
+ if (*name=='/') {
+ count++;
+ name++;
+ } else {
+ name = nameStart;
+ count = 0;
+ }
+ if (count>0) {
+ strlcpy(prefix, nameStart, count);
+ parent = findOrAdd(&m_conditionTreeView, parent, prefix);
+ }
+ } while (count>0);
+
+ ::memset(&ins, 0, sizeof(ins));
+ ins.hParent = parent;
+ ins.hInsertAfter = TVI_SORT;
+ ins.item.mask = TVIF_PARAM|TVIF_TEXT;
+ ins.item.lParam = i;
+ ins.item.pszText = (char*)name;
+ ins.item.cchTextMax = 0;
+ m_conditionTreeView.InsertItem(&ins);
+#endif
}
+ m_conditionTreeView.Select(selItem, TVGN_FIRSTVISIBLE);
+ m_conditionTreeView.SelectItem(selItem);
m_condition->setWarnings(false);
m_myEditCtrl.SetWindowText(m_condition->getUiText().str());
m_myEditCtrl.SetSel(-1, -1);
- formatConditionText(-1);
+ formatConditionText(0);
+ m_conditionTreeView.SetFocus();
- return TRUE; // return TRUE unless you set the focus to a control
+ return FALSE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
@@ -112,28 +235,34 @@ void EditCondition::formatConditionText(Int parameterNdx) {
m_myEditCtrl.SetSel(0, 1000);
m_myEditCtrl.SetSelectionCharFormat(cf);
- m_myEditCtrl.SetReadOnly();
+ //m_myEditCtrl.SetReadOnly();
// Set up the links.
cf.dwMask = CFE_UNDERLINE | CFM_LINK | CFM_COLOR;
cf.dwEffects = CFE_LINK | CFE_UNDERLINE;
cf.crTextColor = RGB(0,0,255);
+ m_curEditParameter = parameterNdx;
AsciiString strings[MAX_PARMS];
Int curChar = 0;
Int numChars = 0;
Int numStrings = m_condition->getUiStrings(strings);
- Int i;
AsciiString warningText;
+ AsciiString informationText;
+ Int i;
for (i=0; igetNumParameters()) {
+ warningText.concat(EditParameter::getWarningText(m_condition->getParameter(i), false));
+ informationText.concat(EditParameter::getInfoText(m_condition->getParameter(i)));
numChars = m_condition->getParameter(i)->getUiText().getLength();
- warningText.concat(EditParameter::getWarningText(m_condition->getParameter(i)));
+ if (curChar==0) {
+ curChar++;
+ numChars--;
+ }
m_myEditCtrl.SetSel(curChar, curChar+numChars);
- if (numChars==0) continue;
if (i==parameterNdx) {
startSel = curChar;
endSel = curChar+numChars;
@@ -148,11 +277,19 @@ void EditCondition::formatConditionText(Int parameterNdx) {
CString cstr;
if (warningText.isEmpty()) {
- if (cstr.LoadString(IDS_SCRIPT_NOWARNINGS)) {
- GetDlgItem(IDC_WARNINGS_CAPTION)->SetWindowText(cstr);
+ if (informationText.isEmpty()) {
+ if (cstr.LoadString(IDS_SCRIPT_NOWARNINGS)) {
+ GetDlgItem(IDC_WARNINGS_CAPTION)->SetWindowText(cstr);
+ }
+ GetDlgItem(IDC_WARNINGS_CAPTION)->EnableWindow(false);
+ GetDlgItem(IDC_WARNINGS)->SetWindowText("");
+ } else {
+ if (cstr.LoadString(IDS_SCRIPT_INFORMATION)) {
+ GetDlgItem(IDC_WARNINGS_CAPTION)->SetWindowText(cstr);
+ }
+ GetDlgItem(IDC_WARNINGS_CAPTION)->EnableWindow(true);
+ GetDlgItem(IDC_WARNINGS)->SetWindowText(informationText.str());
}
- GetDlgItem(IDC_WARNINGS_CAPTION)->EnableWindow(false);
- GetDlgItem(IDC_WARNINGS)->SetWindowText("");
} else {
if (cstr.LoadString(IDS_SCRIPT_WARNINGS)) {
GetDlgItem(IDC_WARNINGS_CAPTION)->SetWindowText(cstr);
@@ -163,6 +300,8 @@ void EditCondition::formatConditionText(Int parameterNdx) {
m_modifiedTextColor = false;
m_myEditCtrl.SetSel(startSel, endSel);
+ m_curLinkChrg.cpMax = endSel;
+ m_curLinkChrg.cpMin = startSel;
m_updating = false;
}
@@ -170,65 +309,140 @@ void EditCondition::formatConditionText(Int parameterNdx) {
BOOL EditCondition::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
+ NMTREEVIEW *pHdr = (NMTREEVIEW *)lParam;
+
+ // Handle events from the tree control.
+ if (pHdr->hdr.idFrom == IDC_CONDITION_TREE) {
+ if (pHdr->hdr.code == TVN_SELCHANGED) {
+ char buffer[_MAX_PATH];
+ HTREEITEM hItem = m_conditionTreeView.GetSelectedItem();
+ TVITEM item;
+ ::memset(&item, 0, sizeof(item));
+ item.mask = TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT|TVIF_STATE;
+ item.hItem = hItem;
+ item.pszText = buffer;
+ item.cchTextMax = sizeof(buffer)-2;
+ m_conditionTreeView.GetItem(&item);
+ if (item.lParam >= 0) {
+ enum Condition::ConditionType conditionType = (enum Condition::ConditionType)item.lParam;
+ if (m_condition->getConditionType() != conditionType) {
+ m_condition->setConditionType( conditionType );
+ m_myEditCtrl.SetWindowText(m_condition->getUiText().str());
+ formatConditionText(0);
+ }
+ }
+ } else if (pHdr->hdr.code == TVN_KEYDOWN) {
+ NMTVKEYDOWN *pKey = (NMTVKEYDOWN*)lParam;
+ Int key = pKey->wVKey;
+ if (key==VK_SHIFT || key==VK_SPACE) {
+ HTREEITEM hItem = m_conditionTreeView.GetSelectedItem();
+ if (!m_conditionTreeView.ItemHasChildren(hItem)) {
+ hItem = m_conditionTreeView.GetParentItem(hItem);
+ }
+ m_conditionTreeView.Expand(hItem, TVE_TOGGLE);
+ return 0;
+ }
+ return 0;
+ }
+ return TRUE;
+ }
+
+ // Handle events from the rich edit control containing the condition pieces.
if (LOWORD(wParam) == IDC_RICH_EDIT_HERE+1) {
NMHDR *pHdr = (NMHDR *)lParam;
- if (pHdr->hwndFrom == m_myEditCtrl.m_hWnd && pHdr->code == EN_LINK) {
- ENLINK *pLink = (ENLINK *)pHdr;
- CHARRANGE chrg = pLink->chrg;
- if (pLink->msg == WM_LBUTTONDOWN) {
+ if (pHdr->hwndFrom == m_myEditCtrl.m_hWnd) {
+ if (pHdr->code == EN_LINK) {
+ ENLINK *pLink = (ENLINK *)pHdr;
+ CHARRANGE chrg = pLink->chrg;
// Determine which parameter.
Int numChars = 0;
Int curChar = 0;
AsciiString strings[MAX_PARMS];
Int numStrings = m_condition->getUiStrings(strings);
Int i;
+ Bool match = false;
for (i=0; igetNumParameters()) {
numChars = m_condition->getParameter(i)->getUiText().getLength();
- if (curChar == chrg.cpMin && curChar+numChars == chrg.cpMax) {
- if (IDOK==EditParameter::edit(m_condition->getParameter(i))) {
- m_myEditCtrl.SetWindowText(m_condition->getUiText().str());
- m_curEditParameter = i;
- this->PostMessage(WM_TIMER, 0, 0);
- }
- return true;
+ match = (curChar+numChars/2 > chrg.cpMin && curChar+numChars/2 < chrg.cpMax);
+ if (match) {
+ m_curEditParameter = i;
+ break;
}
curChar += numChars;
}
}
- }
- CHARRANGE curChrg;
- m_myEditCtrl.GetSel(curChrg);
- if (curChrg.cpMin == chrg.cpMin && curChrg.cpMax == chrg.cpMax) {
- return true;
- }
- if (m_modifiedTextColor) {
- formatConditionText(-1);
- }
- m_curLinkChrg = chrg;
- m_myEditCtrl.SetSel(chrg.cpMin, chrg.cpMax);
- CHARFORMAT cf;
- memset(&cf, 0, sizeof(cf));
- cf.cbSize = sizeof(cf);
- cf.dwMask = CFM_COLOR;
- cf.crTextColor = RGB(0,0,0);
- m_myEditCtrl.SetSelectionCharFormat(cf);
- m_modifiedTextColor = true;
- return true;
- } else if (pHdr->hwndFrom == m_myEditCtrl.m_hWnd && pHdr->code == EN_SELCHANGE) {
- if (m_updating) {
- return true;
- }
- CHARRANGE curChrg;
- m_myEditCtrl.GetSel(curChrg);
- if (curChrg.cpMin == m_curLinkChrg.cpMin && curChrg.cpMax == m_curLinkChrg.cpMax) {
+ if (pLink->msg == WM_LBUTTONDOWN) {
+ // Determine which parameter.
+ if (match) {
+ EditParameter::edit(m_condition->getParameter(m_curEditParameter), 0);
+ m_myEditCtrl.SetWindowText(m_condition->getUiText().str());
+ this->PostMessage(WM_TIMER, 0, 0);
+ return true;
+ }
+ }
+ CHARRANGE curChrg;
+ m_myEditCtrl.GetSel(curChrg);
+ if (curChrg.cpMin == chrg.cpMin && curChrg.cpMax == chrg.cpMax) {
+ return true;
+ }
+ if (m_modifiedTextColor) {
+ formatConditionText(m_curEditParameter);
+ }
+ m_curLinkChrg = chrg;
+ m_myEditCtrl.SetSel(chrg.cpMin, chrg.cpMax);
+ m_myEditCtrl.SetFocus();
+ CHARFORMAT cf;
+ memset(&cf, 0, sizeof(cf));
+ cf.cbSize = sizeof(cf);
+ cf.dwMask = CFM_COLOR;
+ cf.crTextColor = RGB(0,0,0);
+ m_myEditCtrl.SetSelectionCharFormat(cf);
+ m_modifiedTextColor = true;
return true;
- }
- if (m_modifiedTextColor) {
- formatConditionText(-1);
+ } else if (pHdr->code == EN_SETFOCUS) {
+ this->PostMessage(WM_TIMER, 0, 0);
+ } else if (pHdr->code == EN_SELCHANGE) {
+ if (m_updating) {
+ return true;
+ }
+ CHARRANGE curChrg;
+ m_myEditCtrl.GetSel(curChrg);
+ if (curChrg.cpMin == m_curLinkChrg.cpMin && curChrg.cpMax == m_curLinkChrg.cpMax) {
+ return true;
+ }
+ m_myEditCtrl.SetSel(m_curLinkChrg.cpMin, m_curLinkChrg.cpMax);
+ if (m_modifiedTextColor) {
+ this->PostMessage(WM_TIMER, 0, 0);
+ }
+ } else if (pHdr->code == EN_MSGFILTER) {
+ MSGFILTER *pFilter = (MSGFILTER *)pHdr;
+ if (pFilter->msg == WM_CHAR) {
+ Int keyPressed = pFilter->wParam;
+ if (keyPressed==VK_RETURN) {
+ return 1;
+ }
+ if (keyPressed==VK_RETURN || keyPressed == VK_TAB) {
+ m_curEditParameter++;
+ if (m_curEditParameter >= m_condition->getNumParameters()) {
+ m_curEditParameter = 0;
+ return 1;
+ }
+ this->PostMessage(WM_TIMER, 0, 0);
+ return 0;
+ }
+ EditParameter::edit(m_condition->getParameter(m_curEditParameter), keyPressed);
+ m_curEditParameter++;
+ if (m_curEditParameter >= m_condition->getNumParameters()) {
+ m_curEditParameter = 0;
+ }
+ this->PostMessage(WM_TIMER, 0, 0);
+ return 0;
+ }
+ return 1;
}
}
}
@@ -251,12 +465,13 @@ void EditCondition::OnSelchangeConditionType()
}
m_condition->setConditionType((enum Condition::ConditionType)index);
m_myEditCtrl.SetWindowText(m_condition->getUiText().str());
- formatConditionText(-1);
+ formatConditionText(m_curEditParameter);
}
/** Not actually a timer - just used to send a delayed message to self because rich
edit control is stupid. jba. */
void EditCondition::OnTimer(UINT nIDEvent)
{
+ m_myEditCtrl.SetWindowText(m_condition->getUiText().str());
formatConditionText(m_curEditParameter);
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/EditCoordParameter.cpp b/Generals/Code/Tools/WorldBuilder/src/EditCoordParameter.cpp
index 31b897cfae8..67bdbd48039 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EditCoordParameter.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EditCoordParameter.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/EditGroup.cpp b/Generals/Code/Tools/WorldBuilder/src/EditGroup.cpp
index ed5052bcbb4..eb422984a62 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EditGroup.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EditGroup.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/EditObjectParameter.cpp b/Generals/Code/Tools/WorldBuilder/src/EditObjectParameter.cpp
index 5e7c6568182..4d319482548 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EditObjectParameter.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EditObjectParameter.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -233,6 +233,28 @@ HTREEITEM EditObjectParameter::findOrAdd(HTREEITEM parent, const char *pLabel)
return(child);
}
+BOOL EditObjectParameter::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
+{
+ NMTREEVIEW *pHdr = (NMTREEVIEW *)lParam;
+
+ // Handle events from the tree control.
+ if (pHdr->hdr.idFrom == IDC_TERRAIN_TREEVIEW) {
+ if (pHdr->hdr.code == TVN_KEYDOWN) {
+ NMTVKEYDOWN *pKey = (NMTVKEYDOWN*)lParam;
+ Int key = pKey->wVKey;
+ if (key==VK_SHIFT || key==VK_SPACE) {
+ HTREEITEM hItem = m_objectTreeView.GetSelectedItem();
+ if (!m_objectTreeView.ItemHasChildren(hItem)) {
+ hItem = m_objectTreeView.GetParentItem(hItem);
+ }
+ m_objectTreeView.Expand(hItem, TVE_TOGGLE);
+ return 0;
+ }
+ return 0;
+ }
+ }
+ return CDialog::OnNotify(wParam, lParam, pResult);
+}
void EditObjectParameter::OnOK()
{
diff --git a/Generals/Code/Tools/WorldBuilder/src/EditParameter.cpp b/Generals/Code/Tools/WorldBuilder/src/EditParameter.cpp
index 664cdc9505f..9366cdc45ee 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EditParameter.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EditParameter.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -105,7 +105,7 @@ END_MESSAGE_MAP()
// EditParameter message handlers
SidesList *EditParameter::m_sidesListP = nullptr;
-Int EditParameter::edit( Parameter *pParm, AsciiString unitName )
+Int EditParameter::edit( Parameter *pParm, Int keyPressed, AsciiString unitName )
{
if (pParm->getParameterType() == Parameter::COORD3D)
{
@@ -147,6 +147,7 @@ Int EditParameter::edit( Parameter *pParm, AsciiString unitName )
else
{
EditParameter editDlg;
+ editDlg.m_key = keyPressed;
editDlg.m_parameter = pParm;
//Set the name of the unit, because some parameters build information from the unit itself.
editDlg.m_unitName = unitName;
@@ -155,7 +156,7 @@ Int EditParameter::edit( Parameter *pParm, AsciiString unitName )
}
}
-AsciiString EditParameter::getWarningText(Parameter *pParm)
+AsciiString EditParameter::getWarningText(Parameter *pParm, Bool isAction)
{
AsciiString warningText;
AsciiString uiString = pParm->getString();
@@ -255,12 +256,13 @@ AsciiString EditParameter::getWarningText(Parameter *pParm)
}
break;
-
case Parameter::OBJECT_TYPE_LIST:
// No warning is possible.
break;
case Parameter::COUNTER:
- /// @todo - perhaps add more complex syntaxing for counters.
+ if (!isAction && !loadCounters(nullptr, uiString)) {
+ warningText.format("Counter/Timer '%s' does not exist.", uiString.str());
+ }
break;
case Parameter::INT:
break;
@@ -272,6 +274,10 @@ AsciiString EditParameter::getWarningText(Parameter *pParm)
break;
case Parameter::ANGLE:
break;
+#if RTS_ZEROHOUR
+ case Parameter::PERCENT:
+ break;
+#endif
case Parameter::BOOLEAN:
break;
@@ -279,7 +285,9 @@ AsciiString EditParameter::getWarningText(Parameter *pParm)
break;
case Parameter::FLAG:
- /// @todo - perhaps add more complex syntaxing for flags.
+ if (!isAction && !loadFlags(nullptr, uiString)) {
+ warningText.format("Flag '%s' is never initialized.", uiString.str());
+ }
break;
case Parameter::COMPARISON:
break;
@@ -293,7 +301,12 @@ AsciiString EditParameter::getWarningText(Parameter *pParm)
case Parameter::RADAR_EVENT_TYPE:
break;
- case Parameter::RELATION:
+#if RTS_ZEROHOUR
+ case Parameter::LEFT_OR_RIGHT:
+ break;
+#endif
+
+ case Parameter::RELATION:
break;
case Parameter::DIALOG:
@@ -377,6 +390,10 @@ AsciiString EditParameter::getWarningText(Parameter *pParm)
case Parameter::REVEALNAME:
break;
+
+ }
+ if (warningText.isNotEmpty()) {
+ warningText.concat(" ");
}
return warningText;
}
@@ -415,6 +432,9 @@ AsciiString EditParameter::getInfoText(Parameter *pParm)
case Parameter::COLOR:
case Parameter::COORD3D:
case Parameter::ANGLE:
+#if RTS_ZEROHOUR
+ case Parameter::PERCENT:
+#endif
case Parameter::BOOLEAN:
case Parameter::REAL:
case Parameter::FLAG:
@@ -441,6 +461,10 @@ AsciiString EditParameter::getInfoText(Parameter *pParm)
case Parameter::OBJECT_TYPE_LIST:
case Parameter::REVEALNAME:
case Parameter::OBJECT_PANEL_FLAG:
+#if RTS_ZEROHOUR
+ case Parameter::LEFT_OR_RIGHT:
+#endif
+
break;
case Parameter::LOCALIZED_TEXT:
@@ -478,6 +502,7 @@ void EditParameter::OnEditchangeCombo()
void EditParameter::loadConditionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo)
{
OrCondition *pOr;
+ if (pCombo==nullptr) return; // null pcombo is used in syntaxing commands. jba.
for (pOr= pScr->getOrCondition(); pOr; pOr = pOr->getNextOrCondition()) {
Condition *pCondition;
for (pCondition = pOr->getFirstAndCondition(); pCondition; pCondition = pCondition->getNext()) {
@@ -501,19 +526,26 @@ void EditParameter::loadConditionParameter(Script *pScr, Parameter::ParameterTyp
}
}
-void EditParameter::loadActionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo)
+Bool EditParameter::loadActionParameter(Script *pScr, Parameter::ParameterType type, CComboBox *pCombo, AsciiString match)
{
ScriptAction *pAction;
+ Bool found = false;
for (pAction = pScr->getAction(); pAction; pAction = pAction->getNext()) {
Int i;
for (i=0; igetNumParameters(); i++) {
if (type == pAction->getParameter(i)->getParameterType()) {
- if (CB_ERR == pCombo->FindStringExact(-1, pAction->getParameter(i)->getString().str())) {
- pCombo->AddString(pAction->getParameter(i)->getString().str());
+ if (pCombo) {
+ if (CB_ERR == pCombo->FindStringExact(-1, pAction->getParameter(i)->getString().str())) {
+ pCombo->AddString(pAction->getParameter(i)->getString().str());
+ }
+ }
+ if (match == pAction->getParameter(i)->getString()) {
+ found = true;
}
}
}
}
+ return found;
}
Bool EditParameter::loadAttackSetParameter(Script *pScr, CComboBox *pCombo, AsciiString match)
@@ -662,9 +694,10 @@ AsciiString EditParameter::getCreatedUnitTemplateName(AsciiString unitName)
return AsciiString::TheEmptyString;
}
-void EditParameter::loadCounters(CComboBox *pCombo)
+Bool EditParameter::loadCounters(CComboBox *pCombo, AsciiString match)
{
- pCombo->ResetContent();
+ Bool found = false;
+ if (pCombo) pCombo->ResetContent();
Int i;
SidesList *sidesListP = m_sidesListP;
if (sidesListP==nullptr) sidesListP = TheSidesList;
@@ -673,16 +706,21 @@ void EditParameter::loadCounters(CComboBox *pCombo)
Script *pScr;
for (pScr = pSL->getScript(); pScr; pScr=pScr->getNext()) {
loadConditionParameter(pScr, Parameter::COUNTER, pCombo);
- loadActionParameter(pScr, Parameter::COUNTER, pCombo);
+ if (loadActionParameter(pScr, Parameter::COUNTER, pCombo, match)) {
+ found = true;
+ }
}
ScriptGroup *pGroup;
for (pGroup = pSL->getScriptGroup(); pGroup; pGroup=pGroup->getNext()) {
for (pScr = pGroup->getScript(); pScr; pScr=pScr->getNext()) {
loadConditionParameter(pScr, Parameter::COUNTER, pCombo);
- loadActionParameter(pScr, Parameter::COUNTER, pCombo);
+ if (loadActionParameter(pScr, Parameter::COUNTER, pCombo, match)) {
+ found = true;
+ }
}
}
}
+ return found;
}
Bool EditParameter::loadAttackPrioritySets(CComboBox *pCombo, AsciiString match)
@@ -944,9 +982,10 @@ Bool EditParameter::loadEmoticons( CComboBox *pCombo, AsciiString match )
}
//-------------------------------------------------------------------------------------------------
-void EditParameter::loadFlags(CComboBox *pCombo)
+Bool EditParameter::loadFlags(CComboBox *pCombo, AsciiString match)
{
- pCombo->ResetContent();
+ Bool found = false;
+ if (pCombo) pCombo->ResetContent();
Int i;
SidesList *sidesListP = m_sidesListP;
if (sidesListP==nullptr) sidesListP = TheSidesList;
@@ -955,16 +994,21 @@ void EditParameter::loadFlags(CComboBox *pCombo)
Script *pScr;
for (pScr = pSL->getScript(); pScr; pScr=pScr->getNext()) {
loadConditionParameter(pScr, Parameter::FLAG, pCombo);
- loadActionParameter(pScr, Parameter::FLAG, pCombo);
+ if (loadActionParameter(pScr, Parameter::FLAG, pCombo, match)) {
+ found = true;
+ }
}
ScriptGroup *pGroup;
for (pGroup = pSL->getScriptGroup(); pGroup; pGroup=pGroup->getNext()) {
for (pScr = pGroup->getScript(); pScr; pScr=pScr->getNext()) {
loadConditionParameter(pScr, Parameter::FLAG, pCombo);
- loadActionParameter(pScr, Parameter::FLAG, pCombo);
+ if (loadActionParameter(pScr, Parameter::FLAG, pCombo, match)) {
+ found = true;
+ }
}
}
}
+ return found;
}
//-------------------------------------------------------------------------------------------------
@@ -1273,7 +1317,7 @@ Bool EditParameter::loadFontNames(CComboBox *pCombo, AsciiString match)
}
// EditParameter::readFontFile ======================================================
-/** Read the font file defintitions and load them */
+/** Read the font file definitions and load them */
//=============================================================================
void EditParameter::readFontFile( const char *filename )
{
@@ -1296,7 +1340,7 @@ void EditParameter::readFontFile( const char *filename )
for( Int i = 0; i < fontCount; i++ )
{
- // read all the font defitions
+ // read all the font definitions
char fontBuffer[ 512 ];
Int size, bold;
char c;
@@ -1813,6 +1857,14 @@ BOOL EditParameter::OnInitDialog()
showCombo = false;
break;
+#if RTS_ZEROHOUR
+ case Parameter::PERCENT:
+ captionText = "Percent:";
+ editText.Format("%.2f", m_parameter->getReal()*100.0f);
+ showCombo = false;
+ break;
+#endif
+
case Parameter::FLAG:
captionText = "Flag named:";
showCombo = true;
@@ -1820,12 +1872,13 @@ BOOL EditParameter::OnInitDialog()
break;
case Parameter::COMPARISON:
captionText = "Comparison:";
- pList->InsertString(-1, "Less Than");
- pList->InsertString(-1, "Less Than or Equal");
- pList->InsertString(-1, "Equal To");
- pList->InsertString(-1, "Greater Than or Equal");
- pList->InsertString(-1, "Greater Than");
- pList->InsertString(-1, "Not Equal To");
+ pList->InsertString(-1, "LT Less Than");
+ pList->InsertString(-1, "LE Less Than or Equal");
+ pList->InsertString(-1, "EQ Equal To");
+ pList->InsertString(-1, "GE Greater Than or Equal");
+ pList->InsertString(-1, "GT Greater Than");
+ pList->InsertString(-1, "NE Not Equal To");
+ pList->SetCurSel(m_parameter->getInt());
showList = true;
break;
@@ -1871,7 +1924,7 @@ BOOL EditParameter::OnInitDialog()
case Parameter::RADAR_EVENT_TYPE:
captionText = "Radar Event Type:";
- pList->InsertString(-1, "Construction");
+ pList->InsertString(-1,"Construction");
pList->InsertString(-1,"Upgrade");
pList->InsertString(-1,"Under Attack");
pList->InsertString(-1,"Information");
@@ -1879,6 +1932,18 @@ BOOL EditParameter::OnInitDialog()
showList = true;
break;
+
+#if RTS_ZEROHOUR
+ case Parameter::LEFT_OR_RIGHT:
+ captionText = "Evacuate Container Side Choices:";
+ pList->InsertString(-1,"Left");
+ pList->InsertString(-1,"Right");
+ pList->InsertString(-1,"Center (Default)");
+ pList->SetCurSel(m_parameter->getInt() - 1);
+ showList = true;
+ break;
+#endif
+
case Parameter::RELATION:
captionText = "Relation:";
pList->InsertString(-1, "Enemy");
@@ -2056,13 +2121,17 @@ BOOL EditParameter::OnInitDialog()
pCombo->SetCurSel(0);
}
pCombo->SetFocus();
+ if (m_key && m_key != VK_SPACE) pCombo->PostMessage(WM_CHAR, m_key, 0);
} else if (showList) {
pList->ShowWindow(SW_SHOW);
pList->SetFocus();
+ if (m_key && m_key != VK_SPACE) pList->PostMessage(WM_CHAR, m_key, 0);
} else {
pEdit->ShowWindow(SW_SHOW);
pEdit->SetWindowText(editText);
+ pEdit->SetSel(0, 999);
pEdit->SetFocus();
+ if (m_key && m_key != VK_SPACE) pEdit->PostMessage(WM_CHAR, m_key, 0);
}
pCaption->SetWindowText(captionText);
@@ -2075,6 +2144,22 @@ BOOL EditParameter::OnInitDialog()
// EXCEPTION: OCX Property Pages should return FALSE
}
+Bool EditParameter::scanReal(CEdit *pEdit, Real scale)
+{
+ CString txt;
+ Real theReal;
+
+ pEdit->GetWindowText(txt);
+ if (1==sscanf(txt, "%f", &theReal)) {
+ m_parameter->friend_setReal(theReal*scale);
+ return TRUE;
+ } else {
+ pEdit->SetFocus();
+ ::MessageBeep(MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+}
+
void EditParameter::OnOK()
{
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_COMBO);
@@ -2149,27 +2234,24 @@ void EditParameter::OnOK()
break;
case Parameter::REAL:
- pEdit->GetWindowText(txt);
- Real theReal;
- if (1==sscanf(txt, "%f", &theReal)) {
- m_parameter->friend_setReal(theReal);
- } else {
- pEdit->SetFocus();
- ::MessageBeep(MB_ICONEXCLAMATION);
+ if (! scanReal(pEdit, 1.0f)) {
return;
}
break;
case Parameter::ANGLE:
- pEdit->GetWindowText(txt);
- if (1==sscanf(txt, "%f", &theReal)) {
- m_parameter->friend_setReal(theReal*PI/180);
- } else {
- pEdit->SetFocus();
- ::MessageBeep(MB_ICONEXCLAMATION);
+ if (! scanReal(pEdit, PI/180.0f)) {
+ return;
+ }
+ break;
+
+#if RTS_ZEROHOUR
+ case Parameter::PERCENT:
+ if (! scanReal(pEdit, 1.0f/100.0f)) {
return;
}
break;
+#endif
case Parameter::BOOLEAN:
case Parameter::COMPARISON:
@@ -2194,6 +2276,14 @@ void EditParameter::OnOK()
case Parameter::RADAR_EVENT_TYPE:
m_parameter->friend_setInt(pList->GetCurSel() + RADAR_EVENT_CONSTRUCTION);
break;
+
+
+#if RTS_ZEROHOUR
+ case Parameter::LEFT_OR_RIGHT:
+ m_parameter->friend_setInt(pList->GetCurSel() + 1);
+ break;
+#endif
+
case Parameter::LOCALIZED_TEXT:
pCombo->GetWindowText(txt);
comboText = AsciiString(txt);
diff --git a/Generals/Code/Tools/WorldBuilder/src/ExportScriptsOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/ExportScriptsOptions.cpp
index 1fcad1a76eb..227df718459 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ExportScriptsOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ExportScriptsOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -29,6 +29,7 @@ Bool ExportScriptsOptions::m_units = true;
Bool ExportScriptsOptions::m_waypoints = true;
Bool ExportScriptsOptions::m_triggers = true;
Bool ExportScriptsOptions::m_allScripts = false;
+Bool ExportScriptsOptions::m_sides = true;
ExportScriptsOptions::ExportScriptsOptions(CWnd* pParent /*=nullptr*/)
: CDialog(ExportScriptsOptions::IDD, pParent)
@@ -68,6 +69,9 @@ void ExportScriptsOptions::OnOK()
m_triggers = pButton->GetCheck()==1;
pButton = (CButton*)GetDlgItem(IDC_ALL_SCRIPTS);
m_allScripts = pButton->GetCheck()==1;
+ pButton = (CButton*)GetDlgItem(IDC_SIDES);
+ m_sides = pButton->GetCheck()==1;
+
CDialog::OnOK();
}
@@ -86,6 +90,8 @@ BOOL ExportScriptsOptions::OnInitDialog()
pButton->SetCheck(m_allScripts?1:0);
pButton = (CButton*)GetDlgItem(IDC_SELECTED_SCRIPTS);
pButton->SetCheck(m_allScripts?0:1);
+ pButton = (CButton*)GetDlgItem(IDC_SIDES);
+ pButton->SetCheck(m_sides?1:0);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
diff --git a/Generals/Code/Tools/WorldBuilder/src/EyedropperTool.cpp b/Generals/Code/Tools/WorldBuilder/src/EyedropperTool.cpp
index 1fe7b77d501..1fbbe91a7b6 100644
--- a/Generals/Code/Tools/WorldBuilder/src/EyedropperTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/EyedropperTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/FeatherOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/FeatherOptions.cpp
index e19a98632b4..08755866b46 100644
--- a/Generals/Code/Tools/WorldBuilder/src/FeatherOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/FeatherOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/FeatherTool.cpp b/Generals/Code/Tools/WorldBuilder/src/FeatherTool.cpp
index 54e3b5a0105..b4cfeb0b5ce 100644
--- a/Generals/Code/Tools/WorldBuilder/src/FeatherTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/FeatherTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
// Texture tiling tool for worldbuilder.
// Author: John Ahlquist, April 2001
+
#include "StdAfx.h"
#include "resource.h"
diff --git a/Generals/Code/Tools/WorldBuilder/src/FenceOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/FenceOptions.cpp
index a77295fb302..d28033102f8 100644
--- a/Generals/Code/Tools/WorldBuilder/src/FenceOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/FenceOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/FenceTool.cpp b/Generals/Code/Tools/WorldBuilder/src/FenceTool.cpp
index 984f6d4cb05..0a9a354aa2a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/FenceTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/FenceTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/FloodFillTool.cpp b/Generals/Code/Tools/WorldBuilder/src/FloodFillTool.cpp
index e5fcd2cab97..97b4084cdd3 100644
--- a/Generals/Code/Tools/WorldBuilder/src/FloodFillTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/FloodFillTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
// Texture tiling tool for worldbuilder.
// Author: John Ahlquist, April 2001
+
#include "StdAfx.h"
#include "resource.h"
diff --git a/Generals/Code/Tools/WorldBuilder/src/GlobalLightOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/GlobalLightOptions.cpp
index 1eaa4ba4f2c..02b654bcf9d 100644
--- a/Generals/Code/Tools/WorldBuilder/src/GlobalLightOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/GlobalLightOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -937,7 +937,7 @@ void GlobalLightOptions::OnShowWindow(BOOL bShow, UINT nStatus)
stuffValuesIntoFields(K_SUN);
stuffValuesIntoFields(K_ACCENT1);
stuffValuesIntoFields(K_ACCENT2);
- if (!IsWindowVisible()) {
+ if (!bShow) {
WbView3d * pView = CWorldBuilderDoc::GetActive3DView();
if (pView) {
Coord3D lightRay;
diff --git a/Generals/Code/Tools/WorldBuilder/src/GroveOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/GroveOptions.cpp
index 67c7fb93ddd..6171aef302e 100644
--- a/Generals/Code/Tools/WorldBuilder/src/GroveOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/GroveOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/GroveTool.cpp b/Generals/Code/Tools/WorldBuilder/src/GroveTool.cpp
index b39858b2791..b60c9d662a6 100644
--- a/Generals/Code/Tools/WorldBuilder/src/GroveTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/GroveTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/HandScrollTool.cpp b/Generals/Code/Tools/WorldBuilder/src/HandScrollTool.cpp
index d8bbef6b6ed..e74cd4ad878 100644
--- a/Generals/Code/Tools/WorldBuilder/src/HandScrollTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/HandScrollTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ImpassableOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/ImpassableOptions.cpp
index 5f48de02ae1..2c59f005242 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ImpassableOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ImpassableOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/LayersList.cpp b/Generals/Code/Tools/WorldBuilder/src/LayersList.cpp
index a7b52ca12ac..f96502efd14 100644
--- a/Generals/Code/Tools/WorldBuilder/src/LayersList.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/LayersList.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -42,9 +42,11 @@
#include "PointerTool.h"
#include "WorldBuilderDoc.h"
+#include "GameLogic/PolygonTrigger.h"
#include
+
static int newLayerNum = 1;
// CLLTreeCtrl Implementation /////////////////////////////////////////////////////////////////////
@@ -68,6 +70,18 @@ void CLLTreeCtrl::buildMoveMenu(CMenu* moveMenu, UINT firstID)
}
}
+enum LayersListMenuSelectionsEnum {
+ LAYERS_LIST_SELECT_OBJECT,
+ LAYERS_LIST_SELECT_ACTIVE_LAYER,
+ LAYERS_LIST_BREAK_1,
+ LAYERS_LIST_INSERT_NEW_LAYER,
+ LAYERS_LIST_DELETE_CURRENT_LAYER,
+ LAYERS_LIST_MERGE_LAYER_INTO,
+ LAYERS_LIST_MERGE_OBJECT_INTO,
+ LAYERS_LIST_MERGE_VIEW_SELECTION_INTO,
+ LAYERS_LIST_BREAK_2,
+ LAYERS_LIST_HIDE_CURRENT_LAYER,
+};
void CLLTreeCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
// first, if there's something under the mouse, select it.
@@ -98,34 +112,50 @@ void CLLTreeCtrl::OnRButtonDown(UINT nFlags, CPoint point)
}
ClientToScreen(&point);
- CMenu *moveViewSelectionMenu = pPopup->GetSubMenu(4);
- moveViewSelectionMenu ->RemoveMenu(0, MF_BYPOSITION);
+ CMenu *moveViewSelectionMenu = pPopup->GetSubMenu(LAYERS_LIST_MERGE_VIEW_SELECTION_INTO);
+ moveViewSelectionMenu->RemoveMenu(0, MF_BYPOSITION);
buildMoveMenu(moveViewSelectionMenu, ID_LAYERSLIST_MERGEVIEWSELECTIONINTO_BEGIN);
if (item) {
if (contextIsLayer) {
- LayersList *ll = (LayersList*) GetParent();
- pPopup->RemoveMenu(3, MF_BYPOSITION);
- Bool hidden = ll->isLayerHidden(AsciiString(GetItemText(item)));
- pPopup->CheckMenuItem(ID_HIDECURRENTLAYER, MF_BYCOMMAND | (hidden ? MF_CHECKED : MF_UNCHECKED));
+ CString itemText = GetItemText(item);
+ if ((itemText.CompareNoCase(LayersList::TheActiveLayerName.c_str()) == 0) ||
+ ((LayersList::TheActiveLayerName.c_str() == nullptr) &&
+ (LayersList::TheUnmutableDefaultLayerName.compare(LayersList::TheDefaultLayerName) == 0))) {
+ // Don't allow the current layer to be hidden.
+ // Because the objects will immediately disappear when placed.
+ pPopup->EnableMenuItem(ID_HIDECURRENTLAYER, MF_GRAYED);
+ } else {
+ LayersList *ll = (LayersList*) GetParent();
+ Bool hidden = ll->isLayerHidden(AsciiString(itemText));
+ pPopup->CheckMenuItem(ID_HIDECURRENTLAYER, MF_BYCOMMAND | (hidden ? MF_CHECKED : MF_UNCHECKED));
+ }
- CMenu *moveMenu = pPopup->GetSubMenu(2);
+ CMenu *moveMenu = pPopup->GetSubMenu(LAYERS_LIST_MERGE_LAYER_INTO);
moveMenu->RemoveMenu(0, MF_BYPOSITION);
buildMoveMenu(moveMenu, ID_LAYERSLIST_MERGELAYERINTO_BEGIN);
+
+ pPopup->RemoveMenu(LAYERS_LIST_MERGE_VIEW_SELECTION_INTO, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_MERGE_OBJECT_INTO, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_SELECT_OBJECT, MF_BYPOSITION);
+
} else {
pPopup->EnableMenuItem(ID_DELETECURRENTLAYER, MF_GRAYED);
- pPopup->RemoveMenu(2, MF_BYPOSITION);
- pPopup->RemoveMenu(ID_HIDECURRENTLAYER, MF_BYCOMMAND);
+ pPopup->EnableMenuItem(ID_HIDECURRENTLAYER, MF_GRAYED);
- CMenu* moveMenu = pPopup->GetSubMenu(2);
+ CMenu* moveMenu = pPopup->GetSubMenu(LAYERS_LIST_MERGE_OBJECT_INTO);
moveMenu->RemoveMenu(0, MF_BYPOSITION);
buildMoveMenu(moveMenu, ID_LAYERSLIST_MERGEOBJECTINTO_BEGIN);
+
+ pPopup->RemoveMenu(LAYERS_LIST_MERGE_LAYER_INTO, MF_BYPOSITION);
}
} else {
- pPopup->EnableMenuItem(ID_DELETECURRENTLAYER, MF_GRAYED);
- pPopup->RemoveMenu(3, MF_BYPOSITION);
- pPopup->RemoveMenu(2, MF_BYPOSITION);
- pPopup->RemoveMenu(ID_HIDECURRENTLAYER, MF_BYCOMMAND);
+ pPopup->RemoveMenu(LAYERS_LIST_HIDE_CURRENT_LAYER, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_MERGE_OBJECT_INTO, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_MERGE_LAYER_INTO, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_DELETE_CURRENT_LAYER, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_SELECT_ACTIVE_LAYER, MF_BYPOSITION);
+ pPopup->RemoveMenu(LAYERS_LIST_SELECT_OBJECT, MF_BYPOSITION);
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, GetParent());
@@ -140,6 +170,7 @@ END_MESSAGE_MAP()
LayersList::LayersList(UINT nIDTemplate, CWnd *parentWnd) : CDialog(nIDTemplate, parentWnd)
{
mTree = nullptr;
+ m_activatedLayer = false;
resetLayers();
}
@@ -160,6 +191,8 @@ void LayersList::resetLayers()
defaultLayer.show = true;
mLayers.clear();
mLayers.push_back(defaultLayer);
+ defaultLayer.layerName = AsciiString(ThePolygonTriggerLayerName.c_str());
+ mLayers.push_back(defaultLayer);
TheLayersList = this;
if (mTree) {
mTree->DeleteAllItems();
@@ -179,9 +212,12 @@ void LayersList::addMapObjectToLayersList(MapObject *objToAdd, AsciiString layer
// try to add a layer of that name.
addLayerNamed(layerToAddTo);
if (!findLayerNamed(layerToAddTo, &layerIt)) {
- // if we still can't find that layer name, then try adding it to the default layer.
- if (!findLayerNamed(AsciiString(TheDefaultLayerName.c_str()), &layerIt)) {
- return;
+ // Try to place it in the active layer.
+ if (!findLayerNamed(AsciiString(TheActiveLayerName.c_str()), &layerIt)) {
+ // if we still can't find that layer name, then try adding it to the default layer.
+ if (!findLayerNamed(AsciiString(TheDefaultLayerName.c_str()), &layerIt)) {
+ return;
+ }
}
}
}
@@ -189,6 +225,32 @@ void LayersList::addMapObjectToLayersList(MapObject *objToAdd, AsciiString layer
addMapObjectToLayer(objToAdd, &layerIt);
}
+void LayersList::addPolygonTriggerToLayersList(PolygonTrigger *triggerToAdd, AsciiString layerToAddTo)
+{
+ if (!triggerToAdd || findPolygonTriggerAndList(triggerToAdd)) {
+ DEBUG_CRASH(("PolygonTrigger added was null or object already in Layers List. jkmcd"));
+ return;
+ }
+ ListLayerIt layerIt;
+
+ if (!findLayerNamed(layerToAddTo, &layerIt)) {
+ // try to add a layer of that name.
+ addLayerNamed(layerToAddTo);
+ if (!findLayerNamed(layerToAddTo, &layerIt)) {
+ // Try to place it in the active layer.
+ if (!findLayerNamed(AsciiString(TheActiveLayerName.c_str()), &layerIt)) {
+ // if we still can't find that layer name, then try adding it to the trigger layer.
+ if (!findLayerNamed(AsciiString(ThePolygonTriggerLayerName.c_str()), &layerIt)) {
+ return;
+ }
+ }
+ }
+ }
+
+ addPolygonTriggerToLayer(triggerToAdd, &layerIt);
+}
+
+
AsciiString LayersList::removeMapObjectFromLayersList(MapObject *objToRemove)
{
ListLayerIt layerIt;
@@ -202,6 +264,20 @@ AsciiString LayersList::removeMapObjectFromLayersList(MapObject *objToRemove)
return layerIt->layerName;
}
+AsciiString LayersList::removePolygonTriggerFromLayersList(PolygonTrigger *triggerToRemove)
+{
+ ListLayerIt layerIt;
+ ListPolygonTriggerPtrIt triggerIt;
+ if (!triggerToRemove || !findPolygonTriggerAndList(triggerToRemove, &layerIt, &triggerIt)) {
+ DEBUG_CRASH(("Couldn't find that polygon trigger in the layers list. jkmcd"));
+ return AsciiString::TheEmptyString;
+ }
+
+ removePolygonTriggerFromLayer(triggerToRemove, &layerIt, &triggerIt);
+ return layerIt->layerName;
+}
+
+
void LayersList::changeMapObjectLayer(MapObject *objToChange, AsciiString layerToPlaceOn)
{
if (!objToChange) {
@@ -213,6 +289,17 @@ void LayersList::changeMapObjectLayer(MapObject *objToChange, AsciiString layerT
addMapObjectToLayersList(objToChange, layerToPlaceOn);
}
+void LayersList::changePolygonTriggerLayer(PolygonTrigger *triggerToChange, AsciiString layerToPlaceOn)
+{
+ if (!triggerToChange) {
+ DEBUG_CRASH(("Attempted to change location of null object. jkmcd"));
+ return;
+ }
+
+ removePolygonTriggerFromLayersList(triggerToChange);
+ addPolygonTriggerToLayersList(triggerToChange, layerToPlaceOn);
+}
+
void LayersList::addLayerNamed(IN AsciiString layerToAdd)
{
if (findLayerNamed(layerToAdd)) {
@@ -238,6 +325,12 @@ void LayersList::removeLayerNamed(IN AsciiString layerToRemove)
return;
}
+ // Not allowed to remove the Default trigger layer
+ if (layerToRemove.compareNoCase(ThePolygonTriggerLayerName.c_str()) == 0) {
+ return;
+ }
+
+
// If we can't find the layer, how can we remove it?
if (!findLayerNamed(layerToRemove, &layerIt)) {
DEBUG_CRASH(("Couldn't find layer named %s", layerToRemove.str()));
@@ -280,9 +373,25 @@ void LayersList::mergeLayerInto(IN ListLayerIt src, IN ListLayerIt dst)
changeMapObjectLayer(*mopIt, dst->layerName);
}
+ ListPolygonTriggerPtrIt ptpIt;
+ for (ptpIt = src->polygonTriggersInLayer.begin(); ptpIt != src->polygonTriggersInLayer.end(); ptpIt = src->polygonTriggersInLayer.begin()) {
+ changePolygonTriggerLayer(*ptpIt, dst->layerName);
+ }
+
+
+ // Don't remove these layers.
if (src->layerName.compareNoCase(TheDefaultLayerName.c_str()) == 0) {
return;
}
+ if (src->layerName.compareNoCase(ThePolygonTriggerLayerName.c_str()) == 0) {
+ return;
+ }
+
+ if (src->layerName.compareNoCase(TheActiveLayerName.c_str()) == 0) {
+ // The active layer is no longer available.
+ TheActiveLayerName = AsciiString::TheEmptyString.str();
+ }
+
// remove the layer from the tree view
HTREEITEM itemToRemove = findTreeLayerNamed(src->layerName);
@@ -336,6 +445,11 @@ void LayersList::updateUIFromList()
pTree->InsertItem((*objIt)->getName().str(), iconToShow, iconToShow, thisBranch);
}
}
+
+ for (ListPolygonTriggerPtrIt triggerIt = layersIt->polygonTriggersInLayer.begin(); triggerIt != layersIt->polygonTriggersInLayer.end(); ++triggerIt) {
+ const AsciiString& uniqueID = (*triggerIt)->getTriggerName();
+ pTree->InsertItem(uniqueID.str(), iconToShow, iconToShow, thisBranch);
+ }
}
}
@@ -365,6 +479,33 @@ Bool LayersList::findMapObjectAndList(IN MapObject *objectToFind, OUT ListLayerI
return false;
}
+Bool LayersList::findPolygonTriggerAndList(IN PolygonTrigger *triggerToFind, OUT ListLayerIt *layerIt, OUT ListPolygonTriggerPtrIt *triggerIt)
+{
+ if (!triggerToFind) {
+ return false;
+ }
+
+ for (ListLayerIt layersIt = mLayers.begin(); layersIt != mLayers.end(); ++layersIt) {
+ for (ListPolygonTriggerPtrIt triggerPtrIt = layersIt->polygonTriggersInLayer.begin(); triggerPtrIt != layersIt->polygonTriggersInLayer.end(); ++triggerPtrIt) {
+ if ((*triggerPtrIt) == triggerToFind) {
+ if (layerIt) {
+ (*layerIt) = layersIt;
+ }
+
+ if (triggerIt) {
+ (*triggerIt) = triggerPtrIt;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ // if we get here, it means we didn't find the object anywhere in any of the layers
+ return false;
+}
+
+
Bool LayersList::findLayerNamed(IN AsciiString layerName, OUT ListLayerIt *layerIt)
{
if (layerName.isEmpty()) {
@@ -438,6 +579,55 @@ void LayersList::addMapObjectToLayer(IN MapObject *objectToAdd, IN ListLayerIt *
}
+void LayersList::addPolygonTriggerToLayer(IN PolygonTrigger *triggerToAdd, IN ListLayerIt *layerIt)
+{
+ if (!triggerToAdd) {
+ DEBUG_CRASH(("No trigger to add in addPolygonTriggerToLayer. This should not happen. jkmcd"));
+ return;
+ }
+
+ ListLayerIt layerToAddTo;
+ if (layerIt) {
+ layerToAddTo = *layerIt;
+ } else {
+ // By default, add to the default layer.
+ if (!findLayerNamed(AsciiString(ThePolygonTriggerLayerName.c_str()), &layerToAddTo)) {
+ // If we couldn't find that layer, then we're fuxored.
+ return;
+ }
+ }
+
+ if (layerToAddTo->layerName.compareNoCase(AsciiString(ThePolygonTriggerLayerName.c_str())) == 0) {
+ triggerToAdd->setLayerName(AsciiString::TheEmptyString);
+ } else {
+ triggerToAdd->setLayerName(layerToAddTo->layerName);
+ }
+
+ // layerToAddTo now has a valid layer to add to.
+ layerToAddTo->polygonTriggersInLayer.push_back(triggerToAdd);
+
+ // only update this object.
+ HTREEITEM hItem = findTreeLayerNamed(layerToAddTo->layerName);
+ if (hItem) {
+ const AsciiString& triggerName = triggerToAdd->getTriggerName();
+ int iconToShow = (layerToAddTo->show ? 0 : 1);
+ mTree->InsertItem(triggerName.str(), iconToShow, iconToShow, hItem);
+ }
+
+ CWorldBuilderDoc *pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if (!pDoc) {
+ return;
+ }
+
+ if (!layerToAddTo->show) {
+ triggerToAdd->setShouldRender(false);
+ } else {
+ triggerToAdd->setShouldRender(true);
+ }
+
+}
+
+
void LayersList::removeMapObjectFromLayer(IN MapObject *objectToRemove, IN ListLayerIt *layerIt, IN ListMapObjectPtrIt *objectIt)
{
if (!objectToRemove) {
@@ -478,6 +668,46 @@ void LayersList::removeMapObjectFromLayer(IN MapObject *objectToRemove, IN ListL
}
+void LayersList::removePolygonTriggerFromLayer(IN PolygonTrigger *triggerToRemove, IN ListLayerIt *layerIt, IN ListPolygonTriggerPtrIt *triggerIt)
+{
+ if (!triggerToRemove) {
+ DEBUG_CRASH(("Attempted to remove null trigger from layers list. jkmcd"));
+ return;
+ }
+
+ ListLayerIt layerToRemoveFrom;
+ ListPolygonTriggerPtrIt triggerBeingRemove;
+
+ if (layerIt && triggerIt) {
+ layerToRemoveFrom = (*layerIt);
+ triggerBeingRemove = (*triggerIt);
+ } else {
+ if (!findPolygonTriggerAndList(triggerToRemove, &layerToRemoveFrom, &triggerBeingRemove)) {
+ DEBUG_CRASH(("Couldn't find the object anywhere. Why did we try to remove it? jkmcd"));
+ return;
+ }
+ }
+
+ // only remove this object
+ HTREEITEM layer = findTreeLayerNamed(layerToRemoveFrom->layerName);
+ if (layer) {
+ const AsciiString& triggerUID = (*triggerBeingRemove)->getTriggerName();
+ HTREEITEM itemToDelete = findTreeObjectNamed(triggerUID.str(), layer);
+ if (itemToDelete) {
+ mTree->DeleteItem(itemToDelete);
+ }
+ }
+
+ // don't need to update the layer in the object because only 1 of 2 things can be happening:
+ // 1. We are about to delete the object
+ // 2. The object is about to be moved to the default layer (and will be updated anyways.)
+
+ // layerToRemoveFrom and objectToRemove are now valid. Remove em.
+ layerToRemoveFrom->polygonTriggersInLayer.erase(triggerBeingRemove);
+
+}
+
+
BOOL LayersList::OnInitDialog()
{
// call the parent first
@@ -502,10 +732,12 @@ BOOL LayersList::OnInitDialog()
pTree = (CTreeCtrl*) GetDlgItem(IDC_LL_TREE);
// pTree should == mTree now.
- mImageList.Create(16, 16, ILC_COLOR8, 2, 2);
+ mImageList.Create(16, 16, ILC_COLOR8, 3, 3);
+ // If the order of these are changed, please update the enum in updateTreeImages.
mImageList.Add(LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_Show)));
mImageList.Add(LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_Hide)));
+ mImageList.Add(LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_Selected)));
pTree->SetImageList(&mImageList, LVSIL_NORMAL);
pTree->InsertItem(TheDefaultLayerName.c_str(), 0, 0);
@@ -536,6 +768,13 @@ void LayersList::OnBeginEditLabel(NMHDR *pNotifyStruct, LRESULT* pResult)
return;
}
+ if (strcmp(ptvdi->item.pszText, ThePolygonTriggerLayerName.c_str()) == 0) {
+ // Can't edit the default polygon trigger layer name.
+ (*pResult) = 1;
+ return;
+ }
+
+
CString str = pTree->GetItemText(ptvdi->item.hItem);
// if we can't find the layer of that name, then
if (!findLayerNamed(AsciiString(str))) {
@@ -577,6 +816,7 @@ void LayersList::OnEndEditLabel(NMHDR *pNotifyStruct, LRESULT* pResult)
mCurrentlyEditingLabel = AsciiString::TheEmptyString;
}
+
void LayersList::OnNewLayer()
{
CTreeCtrl *pTree = (CTreeCtrl*) GetDlgItem(IDC_LL_TREE);
@@ -614,13 +854,31 @@ void LayersList::OnDeleteLayer()
return;
}
+ if (asciiCatToDelete.compareNoCase(AsciiString(ThePolygonTriggerLayerName.c_str())) == 0) {
+ return;
+ }
+
ListLayerIt srcLayerIt, dstLayerIt;
if (!findLayerNamed(asciiCatToDelete, &srcLayerIt)) {
return;
}
- if (!findLayerNamed(AsciiString(TheDefaultLayerName.c_str()), &dstLayerIt)) {
- return;
+
+ if (asciiCatToDelete.compareNoCase(TheActiveLayerName.c_str()) == 0) {
+ // The active layer is being deleted.
+ TheActiveLayerName = AsciiString::TheEmptyString.str();
+ updateTreeImages();
+
+ if (!findLayerNamed(AsciiString(TheDefaultLayerName.c_str()), &dstLayerIt)) {
+ return;
+ }
+ } else {
+
+ if (!findLayerNamed(AsciiString(TheActiveLayerName.c_str()), &dstLayerIt)) {
+ if (!findLayerNamed(AsciiString(TheDefaultLayerName.c_str()), &dstLayerIt)) {
+ return;
+ }
+ }
}
mergeLayerInto(srcLayerIt, dstLayerIt);
@@ -683,28 +941,8 @@ void LayersList::OnHideShowLayer()
}
layerIt->show = !layerIt->show;
-
- ListMapObjectPtrIt it;
- for (it = layerIt->objectsInLayer.begin(); it != layerIt->objectsInLayer.end(); ++it) {
- if (layerIt->show) {
- (*it)->clearFlag(FLAG_DONT_RENDER);
- } else {
- (*it)->setFlag(FLAG_DONT_RENDER);
- }
- pDoc->invalObject((*it));
- }
-
- int iconToShow = (layerIt->show ? 0 : 1);
- HTREEITEM item = mTree->GetSelectedItem();
- if (item) {
- mTree->SetItemImage(item, iconToShow, iconToShow);
- item = mTree->GetChildItem(item);
- while (item) {
- mTree->SetItemImage(item, iconToShow, iconToShow);
- item = mTree->GetNextSiblingItem(item);
- }
- }
-
+ updateObjectRenderFlags(&layerIt);
+ updateTreeImages();
//PointerTool::clearSelection();
}
@@ -795,6 +1033,102 @@ void LayersList::OnMergeObject(UINT commandID)
MapObject *objToMove = findObjectByUID(lastClickedObj);
if (objToMove) {
changeMapObjectLayer(objToMove, layerIt->layerName);
+ } else {
+ PolygonTrigger* triggerToMove = findPolygonTriggerByUID(lastClickedObj);
+ changePolygonTriggerLayer(triggerToMove, layerIt->layerName);
+ }
+}
+
+void LayersList::OnSelectActiveLayer()
+{
+ AsciiString lastClickedLayer = mTree->getLastClickedLayer();
+ ListLayerIt srclayerIt = mLayers.begin();
+ while (srclayerIt != mLayers.end() && srclayerIt->layerName.compareNoCase(lastClickedLayer) != 0) {
+ ++srclayerIt;
+ }
+
+ if (srclayerIt == mLayers.end()) {
+ return;
+ }
+
+ if (srclayerIt->layerName.compareNoCase(TheActiveLayerName.c_str()) == 0) {
+ // No layer is selected as default.
+ TheActiveLayerName = AsciiString::TheEmptyString.str();
+ } else {
+ // Select this layer to be the default as new objects and triggers are added.
+ TheActiveLayerName = srclayerIt->layerName.str();
+ // The active layer has to be shown.
+ srclayerIt->show = true;
+
+ updateObjectRenderFlags(&srclayerIt);
+ }
+
+ updateTreeImages();
+}
+
+void LayersList::updateObjectRenderFlags(ListLayerIt *updateLayer)
+{
+ ListLayerIt layerIt = *updateLayer;
+
+ ListMapObjectPtrIt it;
+ for (it = layerIt->objectsInLayer.begin(); it != layerIt->objectsInLayer.end(); ++it) {
+ if (layerIt->show) {
+ (*it)->clearFlag(FLAG_DONT_RENDER);
+ } else {
+ (*it)->setFlag(FLAG_DONT_RENDER);
+ }
+
+ CWorldBuilderDoc *pDoc = CWorldBuilderDoc::GetActiveDoc();
+ pDoc->invalObject((*it));
+ }
+
+ ListPolygonTriggerPtrIt pit;
+ for (pit = layerIt->polygonTriggersInLayer.begin(); pit != layerIt->polygonTriggersInLayer.end(); ++pit) {
+ if (layerIt->show) {
+ (*pit)->setShouldRender(true);
+ } else {
+ (*pit)->setShouldRender(false);
+ }
+ //pDoc->invalObject((*it));
+ }
+}
+
+void LayersList::updateTreeImages()
+{
+ enum {
+ SHOW_ICON,
+ HIDE_ICON,
+ SELECTED_ICON,
+ };
+
+ if (!mTree) {
+ return;
+ }
+
+
+ ListLayerIt layerIt;
+
+ for (layerIt = mLayers.begin(); layerIt != mLayers.end(); layerIt++) {
+
+ HTREEITEM layer = findTreeLayerNamed(layerIt->layerName);
+ int childIcon = SHOW_ICON;
+
+ if (layerIt->layerName.compareNoCase(TheActiveLayerName.c_str()) == 0) {
+ mTree->SetItemImage(layer, SELECTED_ICON, SELECTED_ICON);
+ childIcon = SHOW_ICON;
+ } else if (layerIt->show == false) {
+ childIcon = HIDE_ICON;
+ mTree->SetItemImage(layer, HIDE_ICON, HIDE_ICON);
+ } else {
+ childIcon = SHOW_ICON;
+ mTree->SetItemImage(layer, SHOW_ICON, SHOW_ICON);
+ }
+
+ HTREEITEM item = mTree->GetChildItem(layer);
+ while (item) {
+ mTree->SetItemImage(item, childIcon, childIcon);
+ item = mTree->GetNextSiblingItem(item);
+ }
}
}
@@ -827,9 +1161,128 @@ void LayersList::OnMergeViewSelection(UINT commandID)
changeMapObjectLayer(allSelectedObjects.top(), layerIt->layerName);
allSelectedObjects.pop();
}
+
+
+ PolygonTrigger *polygonTrigger = PolygonTrigger::getFirstPolygonTrigger();
+
+ std::stack allSelectedTriggers;
+ while (polygonTrigger) {
+ if (polygonTrigger->getSelected()) {
+ allSelectedTriggers.push(polygonTrigger);
+ }
+
+ polygonTrigger = polygonTrigger->getNext();
+ }
+
+ while (!allSelectedTriggers.empty()) {
+ changePolygonTriggerLayer(allSelectedTriggers.top(), layerIt->layerName);
+ allSelectedTriggers.pop();
+ }
}
+//WST 11/23/2002
+void LayersList::unselectAllMapObjects()
+{
+ MapObject *mapObject = MapObject::getFirstMapObject();
+ while (mapObject) {
+ mapObject->setSelected(false);
+ mapObject = mapObject->getNext();
+ }
+}
+
+void LayersList::unselectAllPolygonTriggers()
+{
+ PolygonTrigger *trigger = PolygonTrigger::getFirstPolygonTrigger();
+ while (trigger) {
+ trigger->setSelected(false);
+ trigger = trigger->getNext();
+ }
+}
+
+
+//WST 11/23/2002
+Bool LayersList::findAndSelectMapObject(AsciiString selectedItemAsciiString)
+{
+ MapObject *mapObject = MapObject::getFirstMapObject();
+
+ while (mapObject) {
+ Bool dontcare;
+ AsciiString mapObjectName = (mapObject)->getProperties()->getAsciiString(TheKey_uniqueID, &dontcare);
+
+ if (mapObjectName.compareNoCase(selectedItemAsciiString) == 0) {
+ // Found it... select this object
+ mapObject->setSelected(true);
+ return (true);
+ }
+ mapObject = mapObject->getNext();
+ }
+
+ return (false);
+}
+
+
+Bool LayersList::findAndSelectPolygonTrigger(AsciiString selectedItemAsciiString)
+{
+ PolygonTrigger *trigger = PolygonTrigger::getFirstPolygonTrigger();
+
+ while (trigger) {
+ const AsciiString& triggerName = trigger->getTriggerName();
+
+ if (triggerName.compareNoCase(selectedItemAsciiString) == 0) {
+ // Found it... select this object
+ trigger->setSelected(true);
+ return (true);
+ }
+ trigger = trigger->getNext();
+ }
+ return (false);
+}
+
+
+
+//WST 11/21/02 New Design team request to select objects from layer view box
+void LayersList::OnSelectLayerObject()
+{
+ CTreeCtrl *pTree = (CTreeCtrl*) GetDlgItem(IDC_LL_TREE);
+ if (!pTree) {
+ return;
+ }
+
+ HTREEITEM item = pTree->GetSelectedItem();
+ if (!item) {
+ return;
+ }
+
+
+ CString selectedItemCString = pTree->GetItemText(item);
+ AsciiString selectedItemAsciiString(selectedItemCString.GetBuffer(0));
+
+ //Unselect everything on the map and get ready to find the one user wanted
+ unselectAllMapObjects();
+ unselectAllPolygonTriggers();
+
+ // Lets check and see if this is a layer that user selected or individual items
+ ListLayerIt srcLayerIt;
+ if (findLayerNamed(selectedItemAsciiString, &srcLayerIt)) {
+ // Ok, User selected the Layer, lets select all map objects in the layer
+ ListMapObjectPtrIt mopIt;
+ for (mopIt = srcLayerIt->objectsInLayer.begin(); mopIt != srcLayerIt->objectsInLayer.end(); ++mopIt) {
+ (*mopIt)->setSelected(true);
+ }
+
+ ListPolygonTriggerPtrIt ptpIt;
+ for (ptpIt = srcLayerIt->polygonTriggersInLayer.begin(); ptpIt != srcLayerIt->polygonTriggersInLayer.end(); ++ptpIt) {
+ (*ptpIt)->setSelected(true);
+ }
+ }
+ else {
+ // User selected individual items
+ if (!findAndSelectMapObject(selectedItemAsciiString)) {
+ findAndSelectPolygonTrigger(selectedItemAsciiString);
+ }
+ }
+}
MapObject *LayersList::findObjectByUID(AsciiString objectIDToFind)
{
@@ -849,12 +1302,30 @@ MapObject *LayersList::findObjectByUID(AsciiString objectIDToFind)
return nullptr;
}
+PolygonTrigger* LayersList::findPolygonTriggerByUID(AsciiString triggerIDToFind)
+{
+ PolygonTrigger *trigger = PolygonTrigger::getFirstPolygonTrigger();
+
+ while (trigger) {
+ const AsciiString& triggerName = trigger->getTriggerName();
+
+ if (triggerName.compareNoCase(triggerIDToFind) == 0) {
+ return (trigger);
+ }
+ trigger = trigger->getNext();
+ }
+
+ return (nullptr);
+}
+
BEGIN_MESSAGE_MAP(LayersList, CDialog)
ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_LL_TREE, OnBeginEditLabel)
ON_NOTIFY(TVN_ENDLABELEDIT, IDC_LL_TREE, OnEndEditLabel)
+ ON_COMMAND(ID_SELECTLAYEROBJECT, OnSelectLayerObject)
ON_COMMAND(ID_INSERTNEWLAYER, OnNewLayer)
ON_COMMAND(ID_DELETECURRENTLAYER, OnDeleteLayer)
ON_COMMAND(ID_HIDECURRENTLAYER, OnHideShowLayer)
+ ON_COMMAND(ID_SELECTACTIVELAYER, OnSelectActiveLayer)
ON_COMMAND_RANGE(ID_LAYERSLIST_MERGELAYERINTO_BEGIN, ID_LAYERSLIST_MERGELAYERINTO_END, OnMergeLayer)
ON_COMMAND_RANGE(ID_LAYERSLIST_MERGEOBJECTINTO_BEGIN, ID_LAYERSLIST_MERGEOBJECTINTO_END, OnMergeObject)
ON_COMMAND_RANGE(ID_LAYERSLIST_MERGEVIEWSELECTIONINTO_BEGIN, ID_LAYERSLIST_MERGEVIEWSELECTIONINTO_END, OnMergeViewSelection)
@@ -864,7 +1335,9 @@ END_MESSAGE_MAP()
// for purposes of linking.
// TheDefaultLayerName is NOT constant, because it is okay to change it.
-std::string LayersList::TheDefaultLayerName = "Default Layer";
+std::string LayersList::TheDefaultLayerName = "Default Object Layer";
std::string LayersList::TheDefaultNewLayerName = "New Layer";
-const std::string LayersList::TheUnmutableDefaultLayerName = "Default Layer";
+std::string LayersList::ThePolygonTriggerLayerName = "Default Trigger Layer";
+std::string LayersList::TheActiveLayerName;
+const std::string LayersList::TheUnmutableDefaultLayerName = "Default Object Layer";
LayersList *TheLayersList = nullptr;
diff --git a/Generals/Code/Tools/WorldBuilder/src/LightOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/LightOptions.cpp
index b9d4b25e4a7..3505989b30f 100644
--- a/Generals/Code/Tools/WorldBuilder/src/LightOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/LightOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/MainFrm.cpp b/Generals/Code/Tools/WorldBuilder/src/MainFrm.cpp
index 26125e89382..6395b3b4439 100644
--- a/Generals/Code/Tools/WorldBuilder/src/MainFrm.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/MainFrm.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -32,6 +32,7 @@
#include "WorldBuilderDoc.h"
#include "WorldBuilderView.h"
+#include "ScriptDialog.h"
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
@@ -71,11 +72,16 @@ CMainFrame::CMainFrame()
m_hAutoSaveTimer = 0;
m_autoSaving = false;
m_layersList = nullptr;
+ m_scriptDialog = nullptr;
}
CMainFrame::~CMainFrame()
{
delete m_layersList;
+ m_layersList = nullptr;
+
+ delete m_scriptDialog;
+ m_scriptDialog = nullptr;
SaveBarState("MainFrame");
TheMainFrame = nullptr;
@@ -178,6 +184,12 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
if (m_optionsPanelWidth < frameRect.Width()) m_optionsPanelWidth = frameRect.Width();
if (m_optionsPanelHeight < frameRect.Height()) m_optionsPanelHeight = frameRect.Height();
+ m_rulerOptions.Create(IDD_RULER_OPTIONS, this);
+ m_rulerOptions.SetWindowPos(nullptr, frameRect.left, frameRect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
+ m_rulerOptions.GetWindowRect(&frameRect);
+ if (m_optionsPanelWidth < frameRect.Width()) m_optionsPanelWidth = frameRect.Width();
+ if (m_optionsPanelHeight < frameRect.Height()) m_optionsPanelHeight = frameRect.Height();
+
m_objectOptions.Create(IDD_OBJECT_OPTIONS, this);
m_objectOptions.SetWindowPos(nullptr, frameRect.left, frameRect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
m_objectOptions.GetWindowRect(&frameRect);
@@ -373,6 +385,7 @@ void CMainFrame::showOptionsDialog(Int dialogID)
case IDD_MAPOBJECT_PROPS: newOptions = &m_mapObjectProps; break;
case IDD_ROAD_OPTIONS:newOptions = &m_roadOptions; break;
case IDD_MOUND_OPTIONS:newOptions = &m_moundOptions; break;
+ case IDD_RULER_OPTIONS:newOptions = &m_rulerOptions; break;
case IDD_FEATHER_OPTIONS:newOptions = &m_featherOptions; break;
case IDD_MESHMOLD_OPTIONS:newOptions = &m_meshMoldOptions; break;
case IDD_WAYPOINT_OPTIONS:newOptions = &m_waypointOptions; break;
@@ -409,6 +422,22 @@ void CMainFrame::OnEditGloballightoptions()
m_globalLightOptions.ShowWindow(SW_SHOWNA);
}
+void CMainFrame::onEditScripts()
+{
+ delete m_scriptDialog;
+
+ CRect frameRect;
+ GetWindowRect(&frameRect);
+
+ // Setup the Script Dialog.
+ // This needs to be recreated each time so that it will have the current data.
+ m_scriptDialog = new ScriptDialog(this);
+ m_scriptDialog->Create(IDD_ScriptDialog, this);
+ m_scriptDialog->SetWindowPos(nullptr, frameRect.left, frameRect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
+ m_scriptDialog->GetWindowRect(&frameRect);
+ m_scriptDialog->ShowWindow(SW_SHOWNA);
+}
+
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
@@ -496,4 +525,3 @@ void CMainFrame::handleCameraChange()
{
m_cameraOptions.update();
}
-
diff --git a/Generals/Code/Tools/WorldBuilder/src/MapPreview.cpp b/Generals/Code/Tools/WorldBuilder/src/MapPreview.cpp
index 835fec70a54..d232f729992 100644
--- a/Generals/Code/Tools/WorldBuilder/src/MapPreview.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/MapPreview.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/MapSettings.cpp b/Generals/Code/Tools/WorldBuilder/src/MapSettings.cpp
index 1801d404e8f..3c1b832903a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/MapSettings.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/MapSettings.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp
index 7a04ba1cd2b..d97e2bfc42d 100644
--- a/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/MeshMoldOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -101,6 +101,12 @@ BOOL MeshMoldOptions::OnInitDialog()
fileBuf[i] = 0;
}
}
+ char *nameStart = fileBuf;
+ for (i=0; iCreate_Render_Obj(modelName.str());
diff --git a/Generals/Code/Tools/WorldBuilder/src/ObjectTool.cpp b/Generals/Code/Tools/WorldBuilder/src/ObjectTool.cpp
index 083262ee557..a95f4af1388 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ObjectTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ObjectTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/OpenMap.cpp b/Generals/Code/Tools/WorldBuilder/src/OpenMap.cpp
index 015a5b091df..c003e493bd0 100644
--- a/Generals/Code/Tools/WorldBuilder/src/OpenMap.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/OpenMap.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/OptionsPanel.cpp b/Generals/Code/Tools/WorldBuilder/src/OptionsPanel.cpp
index ea5f1df381f..c9973f81464 100644
--- a/Generals/Code/Tools/WorldBuilder/src/OptionsPanel.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/OptionsPanel.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp b/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp
index 0a7e9a7e186..10413a61100 100644
--- a/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/PickUnitDialog.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/PointerTool.cpp b/Generals/Code/Tools/WorldBuilder/src/PointerTool.cpp
index dda7df218fc..9e80a811c99 100644
--- a/Generals/Code/Tools/WorldBuilder/src/PointerTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/PointerTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/PolygonTool.cpp b/Generals/Code/Tools/WorldBuilder/src/PolygonTool.cpp
index 74429fce8a4..f4882ce322b 100644
--- a/Generals/Code/Tools/WorldBuilder/src/PolygonTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/PolygonTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/RampOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/RampOptions.cpp
index 4b9cc441d49..6553580b6f9 100644
--- a/Generals/Code/Tools/WorldBuilder/src/RampOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/RampOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/RampTool.cpp b/Generals/Code/Tools/WorldBuilder/src/RampTool.cpp
index 572684b34c6..4e2cf875af8 100644
--- a/Generals/Code/Tools/WorldBuilder/src/RampTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/RampTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -30,6 +30,8 @@
/* Revision History: */
/* 4/19/2002 : Initial creation */
/*---------------------------------------------------------------------------*/
+
+
#include "StdAfx.h"
#include "RampTool.h"
diff --git a/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp
index 360d32c6be0..3e52ecb5864 100644
--- a/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/RoadOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/RoadTool.cpp b/Generals/Code/Tools/WorldBuilder/src/RoadTool.cpp
index e5d9d1dfc69..39ea5558efd 100644
--- a/Generals/Code/Tools/WorldBuilder/src/RoadTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/RoadTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/RulerOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/RulerOptions.cpp
new file mode 100644
index 00000000000..735305edcb6
--- /dev/null
+++ b/Generals/Code/Tools/WorldBuilder/src/RulerOptions.cpp
@@ -0,0 +1,131 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+// Mike Lytle
+// 01/07/03
+// RulerOptions.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "Lib/BaseType.h"
+#include "RulerOptions.h"
+#include "WorldBuilderView.h"
+#include "RulerTool.h"
+
+RulerOptions* RulerOptions::m_staticThis = nullptr;
+
+/////////////////////////////////////////////////////////////////////////////
+RulerOptions::RulerOptions(CWnd* pParent /*=nullptr*/)
+{
+ //{{AFX_DATA_INIT(RulerOptions)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+}
+
+/// Windows default stuff.
+void RulerOptions::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(RulerOptions)
+ // NOTE: the ClassWizard will add DDX and DDV calls here
+ //}}AFX_DATA_MAP
+}
+
+
+/** Update the value in the edit control. */
+void RulerOptions::setWidth(Real width)
+{
+ CString buf;
+ // Multiply by 2 because we are changing from radius to diameter.
+ buf.Format("%f", width * 2.0f);
+ if (m_staticThis && !m_staticThis->m_updating) {
+ CWnd *pEdit = m_staticThis->GetDlgItem(IDC_RULER_WIDTH);
+ if (pEdit && pEdit->IsWindowEnabled()) {
+ pEdit->SetWindowText(buf);
+ }
+ }
+}
+
+
+/// Dialog UI initialization.
+BOOL RulerOptions::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ m_staticThis = this;
+ m_updating = false;
+ if (RulerTool::getType() != RULER_CIRCLE) {
+ CWnd *pEdit = GetDlgItem(IDC_RULER_WIDTH);
+ if (pEdit) {
+ // Disable the edit box since the ruler isn't a circle.
+ pEdit->EnableWindow(false);
+ }
+ } else {
+ // Only the circle rulers use the edit box to change the size.
+ setWidth(RulerTool::getLength());
+ }
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void RulerOptions::OnChangeWidthEdit()
+{
+ if (m_updating) return;
+ CWnd *pEdit = GetDlgItem(IDC_RULER_WIDTH);
+ char buffer[_MAX_PATH];
+ if (pEdit) {
+ pEdit->GetWindowText(buffer, sizeof(buffer));
+ float width;
+ m_updating = true;
+ // Pull out the length from the text.
+ if (1 == sscanf(buffer, "%f", &width)) {
+ // Change from diameter to radius.
+ RulerTool::setLength(width / 2.0f);
+ }
+ m_updating = false;
+ }
+}
+
+void RulerOptions::OnChangeCheckRuler()
+{
+ if (m_updating) return;
+ CWnd *pCheck = GetDlgItem(IDC_CHECK_RULER);
+ if (pCheck) {
+ if (RulerTool::switchType()) {
+ CWnd *pEdit = GetDlgItem(IDC_RULER_WIDTH);
+ if (pEdit) {
+ // The edit box is disabled when the ruler is a line.
+ pEdit->EnableWindow(!pEdit->IsWindowEnabled());
+ // Make sure that the length is updated.
+ if (pEdit->IsWindowEnabled()) {
+ setWidth(RulerTool::getLength());
+ }
+ }
+ }
+ }
+}
+
+
+
+
+BEGIN_MESSAGE_MAP(RulerOptions, COptionsPanel)
+ //{{AFX_MSG_MAP(RulerOptions)
+ ON_EN_CHANGE(IDC_RULER_WIDTH, OnChangeWidthEdit)
+ ON_BN_CLICKED(IDC_CHECK_RULER, OnChangeCheckRuler)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
diff --git a/Generals/Code/Tools/WorldBuilder/src/RulerTool.cpp b/Generals/Code/Tools/WorldBuilder/src/RulerTool.cpp
new file mode 100644
index 00000000000..de425122d29
--- /dev/null
+++ b/Generals/Code/Tools/WorldBuilder/src/RulerTool.cpp
@@ -0,0 +1,187 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+// RulerTool.cpp
+// Author: Mike Lytle, January 2003
+
+
+#include "StdAfx.h"
+#include "resource.h"
+
+#include "RulerTool.h"
+#include "MainFrm.h"
+#include "WorldBuilderDoc.h"
+#include "WorldBuilderView.h"
+#include "wbview3d.h"
+#include "ObjectTool.h"
+
+
+// Saved off so that static functions can access its members.
+RulerTool* RulerTool::m_staticThis = nullptr;
+
+/// Constructor
+RulerTool::RulerTool() :
+Tool(ID_RULER_TOOL, IDC_POINTER)
+{
+ m_downPt3d.set(0.0f, 0.0f, 0.0f);
+ m_rulerType = RULER_LINE;
+ m_View = nullptr;
+ m_staticThis = this;
+}
+
+/// Destructor
+RulerTool::~RulerTool()
+{
+}
+
+// Activate.
+void RulerTool::activate()
+{
+ Tool::activate();
+ CMainFrame::GetMainFrame()->showOptionsDialog(IDD_RULER_OPTIONS);
+ if (m_View != nullptr) {
+ // Is it dangerous to assume that the pointer is still good?
+ m_View->doRulerFeedback(m_rulerType);
+ }
+}
+
+// Deactivate.
+void RulerTool::deactivate()
+{
+ Tool::deactivate();
+
+ if (m_View != nullptr) {
+ m_View->doRulerFeedback(RULER_NONE);
+ }
+
+}
+
+/** Set the cursor. */
+void RulerTool::setCursor()
+{
+ Tool::setCursor();
+}
+
+
+/** Execute the tool on mouse down */
+void RulerTool::mouseDown(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldBuilderDoc *pDoc)
+{
+ if (m != TRACK_L) return;
+
+ if (m_View == nullptr) {
+ // Save so that when we are done the view can stop drawing the rulers.
+ m_View = pView;
+ }
+
+ Coord3D cpt;
+ pView->viewToDocCoords(viewPt, &cpt);
+
+ m_downPt3d = cpt;
+ pView->snapPoint(&m_downPt3d);
+}
+
+/// Left button move code.
+void RulerTool::mouseMoved(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldBuilderDoc *pDoc)
+{
+ if (m != TRACK_L) return;
+
+ if (m_View == nullptr) {
+ // Save so that when we are done the view can stop drawing the rulers.
+ m_View = pView;
+ }
+
+ Coord3D cpt;
+ pView->viewToDocCoords(viewPt, &cpt, false);
+
+ if (m_rulerType == RULER_CIRCLE) {
+ Coord3D pt;
+ pt.x = cpt.x + m_savedLength;
+ pt.y = cpt.y + m_savedLength;
+ pt.z = cpt.z;
+ RulerOptions::setWidth(m_savedLength);
+ pView->doRulerFeedback(RULER_CIRCLE);
+ pView->rulerFeedbackInfo(cpt, pt, m_savedLength);
+ pView->Invalidate();
+ } else { //m_rulerType == RULER_LINE
+ Coord3D diff;
+ diff.set(cpt);
+ diff.sub(m_downPt3d);
+ m_savedLength = diff.length();
+ RulerOptions::setWidth(m_savedLength);
+ pView->doRulerFeedback(RULER_LINE);
+ pView->rulerFeedbackInfo(cpt, m_downPt3d, m_savedLength);
+ pView->Invalidate();
+ }
+
+ pDoc->updateAllViews();
+}
+
+void RulerTool::setLength(Real length)
+{
+ if (!m_staticThis || (m_staticThis->m_rulerType != RULER_CIRCLE)) {
+ // This should only be called when the ruler type is a circle.
+ // Line rulers are always extended by the mouse.
+ return;
+ }
+
+ m_staticThis->m_savedLength = length;
+ if (m_staticThis->m_View) {
+ m_staticThis->m_View->rulerFeedbackInfo(m_staticThis->m_downPt3d, m_staticThis->m_downPt3d, length);
+ m_staticThis->m_View->Invalidate();
+ }
+
+ CString str;
+ str.Format("Diameter (in feet): %f", length * 2.0f);
+ CMainFrame::GetMainFrame()->SetMessageText(str);
+}
+
+Bool RulerTool::switchType()
+{
+ if (!m_staticThis) {
+ return (FALSE);
+ }
+
+ if (m_staticThis->m_rulerType == RULER_LINE) {
+ m_staticThis->m_rulerType = RULER_CIRCLE;
+ } else {
+ m_staticThis->m_rulerType = RULER_LINE;
+ }
+ if (m_staticThis->m_View != nullptr) {
+ m_staticThis->m_View->doRulerFeedback(m_staticThis->m_rulerType);
+ }
+
+ return (TRUE);
+}
+
+int RulerTool::getType()
+{
+ if (!m_staticThis) {
+ return (RULER_NONE);
+ }
+
+ return (m_staticThis->m_rulerType);
+}
+
+Real RulerTool::getLength()
+{
+ if (m_staticThis) {
+ return m_staticThis->m_savedLength;
+ }
+
+ return (0.0f);
+}
diff --git a/Generals/Code/Tools/WorldBuilder/src/SaveMap.cpp b/Generals/Code/Tools/WorldBuilder/src/SaveMap.cpp
index 9640f4e4483..dd6ea4751fb 100644
--- a/Generals/Code/Tools/WorldBuilder/src/SaveMap.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/SaveMap.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScorchOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/ScorchOptions.cpp
index 528d994c751..32b7ddd5f97 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScorchOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScorchOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScorchTool.cpp b/Generals/Code/Tools/WorldBuilder/src/ScorchTool.cpp
index 11029ffacd3..f2868efdb7a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScorchTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScorchTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScriptActionsFalse.cpp b/Generals/Code/Tools/WorldBuilder/src/ScriptActionsFalse.cpp
index 2dd20f41c20..d91367f6180 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScriptActionsFalse.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScriptActionsFalse.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScriptActionsTrue.cpp b/Generals/Code/Tools/WorldBuilder/src/ScriptActionsTrue.cpp
index b2fb20c70af..b71cdebebeb 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScriptActionsTrue.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScriptActionsTrue.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScriptConditions.cpp b/Generals/Code/Tools/WorldBuilder/src/ScriptConditions.cpp
index 44639e9a2f7..e7bb1d89337 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScriptConditions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScriptConditions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScriptDialog.cpp b/Generals/Code/Tools/WorldBuilder/src/ScriptDialog.cpp
index 0264bf1ae37..9644c190c17 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScriptDialog.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScriptDialog.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -42,6 +42,7 @@
#include "WaypointOptions.h"
#include "Common/UnicodeString.h"
+
static const Int K_LOCAL_TEAMS_VERSION_1 = 1;
#define SCRIPT_DIALOG_SECTION "ScriptDialog"
@@ -153,6 +154,7 @@ ScriptDialog::ScriptDialog(CWnd* pParent /*=nullptr*/)
: CDialog(ScriptDialog::IDD, pParent)
{
m_draggingTreeView = false;
+ m_autoUpdateWarnings = true;
//{{AFX_DATA_INIT(ScriptDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
@@ -182,6 +184,9 @@ BEGIN_MESSAGE_MAP(ScriptDialog, CDialog)
ON_BN_CLICKED(IDC_EDIT_SCRIPT, OnEditScript)
ON_BN_CLICKED(IDC_COPY_SCRIPT, OnCopyScript)
ON_BN_CLICKED(IDC_DELETE, OnDelete)
+ ON_BN_CLICKED(IDC_VERIFY, OnVerify)
+ ON_BN_CLICKED(IDC_PATCH_GC, OnPatchGC)
+ ON_BN_CLICKED(IDC_AUTO_VERIFY, OnAutoVerify)
ON_BN_CLICKED(IDC_SAVE, OnSave)
ON_BN_CLICKED(IDC_LOAD, OnLoad)
ON_NOTIFY(NM_DBLCLK, IDC_SCRIPT_TREE, OnDblclkScriptTree)
@@ -314,7 +319,7 @@ void ScriptDialog::updateScriptWarning(Script *pScript)
Int i;
for (i=0; igetNumParameters(); i++) {
AsciiString warning;
- warning = EditParameter::getWarningText(pCondition->getParameter(i));
+ warning = EditParameter::getWarningText(pCondition->getParameter(i), FALSE);
if (!warning.isEmpty()) {
pScript->setWarnings(true);
pCondition->setWarnings(true);
@@ -328,7 +333,7 @@ void ScriptDialog::updateScriptWarning(Script *pScript)
Int i;
for (i=0; igetNumParameters(); i++) {
AsciiString warning;
- warning = EditParameter::getWarningText(pAction->getParameter(i));
+ warning = EditParameter::getWarningText(pAction->getParameter(i), TRUE);
if (!warning.isEmpty()) {
pScript->setWarnings(true);
pAction->setWarnings(true);
@@ -337,9 +342,42 @@ void ScriptDialog::updateScriptWarning(Script *pScript)
}
}
+void ScriptDialog::OnPatchGC()
+{
+ checkParametersForGC();
+ updateIcons(TVI_ROOT);
+/* //Put up a dialog asking for search/replace parameters instead of hard-coded GC_ prefix.
+ ReplaceParameter editDlg();
+ if (IDOK==editDlg.DoModal())
+ {
+
+ }*/
+}
+
+/**Force a pass over all the scripts to make sure no warnings. I moved this
+to user control because this function is VERY slow. 7-15-03 -MW*/
+void ScriptDialog::OnVerify()
+{
+ updateWarnings(true); //force an update of warnings
+ updateIcons(TVI_ROOT);
+}
+
+void ScriptDialog::OnAutoVerify()
+{
+ CButton *pButton = (CButton*)GetDlgItem(IDC_AUTO_VERIFY);
+ m_autoUpdateWarnings=(pButton->GetCheck()==1);
+ ::AfxGetApp()->WriteProfileInt(SCRIPT_DIALOG_SECTION, "AutoVerifyScripts", m_autoUpdateWarnings?1:0);
+ //if user wants to check warnings manually, enable the verify button
+ CWnd *pWnd = GetDlgItem(IDC_VERIFY);
+ pWnd->EnableWindow(!m_autoUpdateWarnings);
+}
+
/** Updates the warning flags in the scripts, script groups & script conditions & actions. */
-void ScriptDialog::updateWarnings()
+void ScriptDialog::updateWarnings(Bool forceUpdate)
{
+ if (m_staticThis && m_staticThis->m_autoUpdateWarnings == false && forceUpdate == false)
+ return; //user has disabled warnings to speed up the script editor
+
SidesList *sidesListP = TheSidesList;
Int i;
if (m_staticThis) sidesListP = &m_staticThis->m_sides;
@@ -362,10 +400,124 @@ void ScriptDialog::updateWarnings()
}
}
+extern AsciiString ConvertToNonGCName(AsciiString name, Bool checkTemplate=true);
+
+void ScriptDialog::patchScriptParametersForGC(Script *pScript)
+{
+ AsciiString swapString;
+ pScript->setWarnings(false);
+ OrCondition *pOr;
+ for (pOr= pScript->getOrCondition(); pOr; pOr = pOr->getNextOrCondition()) {
+ Condition *pCondition;
+ for (pCondition = pOr->getFirstAndCondition(); pCondition; pCondition = pCondition->getNext()) {
+ pCondition->setWarnings(false);
+ Int i;
+ for (i=0; igetNumParameters(); i++) {
+ AsciiString warning;
+ Parameter *pParm = pCondition->getParameter(i);
+ warning = EditParameter::getWarningText(pParm, FALSE);
+ if (!warning.isEmpty()) {
+ if (pParm->getParameterType() == Parameter::OBJECT_TYPE)
+ { //see if removing the GC prefix fixes this warning:
+ AsciiString uiString = pParm->getString();
+ if (uiString.isEmpty())
+ uiString = "???";
+ if (uiString.startsWith("GC_"))
+ { swapString = ConvertToNonGCName(uiString, false);
+ pParm->friend_setString(swapString);
+ warning = EditParameter::getWarningText(pParm, FALSE);
+ if (!warning.isEmpty())
+ { //Removing GC prefix didn't help, so restore original
+ pParm->friend_setString(uiString);
+ }
+ else
+ continue; //warning was fixed so leave swapped parameter.
+ }
+ }
+ pScript->setWarnings(true);
+ pCondition->setWarnings(true);
+ }
+ }
+ }
+ }
+ ScriptAction *pAction;
+ for (pAction = pScript->getAction(); pAction; pAction = pAction->getNext()) {
+ pAction->setWarnings(false);
+ Int i;
+ for (i=0; igetNumParameters(); i++) {
+ AsciiString warning;
+ Parameter *pParm=pAction->getParameter(i);
+ warning = EditParameter::getWarningText(pParm, TRUE);
+ if (!warning.isEmpty()) {
+ if (pParm->getParameterType() == Parameter::OBJECT_TYPE)
+ { //see if removing the GC prefix fixes this warning:
+ AsciiString uiString = pParm->getString();
+ if (uiString.isEmpty())
+ uiString = "???";
+ if (uiString.startsWith("GC_"))
+ { swapString = ConvertToNonGCName(uiString,false);
+ pParm->friend_setString(swapString);
+ warning = EditParameter::getWarningText(pParm, FALSE);
+ if (!warning.isEmpty())
+ { //Removing GC prefix didn't help, so restore original
+ pParm->friend_setString(uiString);
+ }
+ else
+ continue; //warning was fixed so leave swapped parameter.
+ }
+ }
+ pScript->setWarnings(true);
+ pAction->setWarnings(true);
+ }
+ }
+ }
+}
+
+/*Checks all script parameters for obsolete values (example: mission disk using GC_ templates)*/
+void ScriptDialog::checkParametersForGC()
+{
+ SidesList *sidesListP = TheSidesList;
+ Int i;
+ if (m_staticThis) sidesListP = &m_staticThis->m_sides;
+ for (i=0; igetNumSides(); i++) {
+ ScriptList *pSL = sidesListP->getSideInfo(i)->getScriptList();
+ Script *pScr;
+ for (pScr = pSL->getScript(); pScr; pScr=pScr->getNext()) {
+ updateScriptWarning(pScr);
+ if (pScr->hasWarnings())
+ { //check if this is using invalid GC parameters
+ patchScriptParametersForGC(pScr);
+ }
+ }
+ ScriptGroup *pGroup;
+ for (pGroup = pSL->getScriptGroup(); pGroup; pGroup=pGroup->getNext()) {
+ pGroup->setWarnings(false);
+ for (pScr = pGroup->getScript(); pScr; pScr=pScr->getNext()) {
+ updateScriptWarning(pScr);
+ if (pScr->hasWarnings()) {
+ //check if this is using invalid GC parameters.
+ patchScriptParametersForGC(pScr);
+ if (pScr->hasWarnings()) //patching may have removed warning
+ pGroup->setWarnings(true);
+ }
+ }
+ }
+ }
+}
+
BOOL ScriptDialog::OnInitDialog()
{
CDialog::OnInitDialog();
+ m_autoUpdateWarnings=::AfxGetApp()->GetProfileInt(SCRIPT_DIALOG_SECTION, "AutoVerifyScripts", 1);
+
+ CButton *pButton = (CButton*)GetDlgItem(IDC_AUTO_VERIFY);
+ pButton->SetCheck(m_autoUpdateWarnings ? 1:0);
+
+ //if user wants to check warnings manually, enable the verify button
+ CWnd *pWnd = GetDlgItem(IDC_VERIFY);
+ pWnd->EnableWindow(!m_autoUpdateWarnings);
+
m_staticThis = this;
CTreeCtrl *pTree = (CTreeCtrl*)GetDlgItem(IDC_SCRIPT_TREE);
@@ -388,7 +540,7 @@ BOOL ScriptDialog::OnInitDialog()
m_sides = *TheSidesList;
EditParameter::setCurSidesList(&m_sides);
Int i;
- updateWarnings();
+ updateWarnings(true);
if (pTree) {
m_imageList.Create(IDB_FOLDERSCRIPT, 16, 2, ILC_COLOR4);
pTree->SetImageList(&m_imageList, TVSIL_STATE);
@@ -1100,6 +1252,7 @@ void ScriptDialog::scanForWaypointsAndTeams(Script *pScript, Bool doUnits, Bool
}
#define K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_1 1
+#define K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_2 2
/** Write out selected scripts, and possibly waypoints, trigger areas & teams. */
void ScriptDialog::OnSave()
@@ -1108,6 +1261,7 @@ void ScriptDialog::OnSave()
Bool doTriggerAreas = true;
Bool doUnits = true;
Bool doAllScripts = true;
+ Bool doSides = true;
Int i;
ExportScriptsOptions optionsDlg;
@@ -1118,6 +1272,7 @@ void ScriptDialog::OnSave()
doUnits = optionsDlg.getDoUnits();
doTriggerAreas = optionsDlg.getDoTriggers();
doAllScripts = optionsDlg.getDoAllScripts();
+ doSides = optionsDlg.getDoSides();
Script *pScript = getCurScript();
ScriptGroup *pGroup = getCurGroup();
@@ -1211,12 +1366,19 @@ void ScriptDialog::OnSave()
ScriptList::WriteScriptsDataChunk(chunkWriter, scripts, numScriptLists);
/***************Players DATA ***************/
- chunkWriter.openDataChunk("ScriptsPlayers", K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_1);
- if (doAllScripts) {
+ chunkWriter.openDataChunk("ScriptsPlayers", K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_2);
+ chunkWriter.writeInt(doSides);
+ if (doAllScripts || doSides) {
chunkWriter.writeInt(m_sides.getNumSides());
for (i=0; igetDict()->getAsciiString(TheKey_playerName);
chunkWriter.writeAsciiString(name);
+
+ if (doSides) {
+ // The user has requested that the sides get exported.
+ chunkWriter.writeDict(*m_sides.getSideInfo(i)->getDict());
+ }
+
}
} else {
chunkWriter.writeInt(1);
@@ -1410,6 +1572,7 @@ void ScriptDialog::OnLoad()
} else {
Int j;
for (j=0; jgetDict()->getAsciiString(TheKey_playerName);
if (name == m_readPlayerNames[j]) {
curSide = j;
@@ -1455,13 +1618,21 @@ void ScriptDialog::OnLoad()
scripts[i]->discard(); /* Frees the script list, but none of it's children, as they have been
copied into the current scripts. */
scripts[i] = nullptr;
- reloadPlayer(curSide, pSL);
+ //reloadPlayer(curSide, pSL);
} else {
deleteInstance(scripts[i]);
scripts[i] = nullptr;
}
}
+ for (i = 0; i < m_sides.getNumSides(); i++) {
+ // Make sure that the dialog tree is updated.
+ ScriptList *pSL = m_sides.getSideInfo(i)->getScriptList();
+ reloadPlayer(i, pSL);
+ updateIcons(TVI_ROOT);
+ }
+
+
} catch(...) {
DEBUG_CRASH(("threw exception in ScriptDialog::OnLoad"));
}
@@ -1607,15 +1778,19 @@ Bool ScriptDialog::ParseTeamsDataChunk(DataChunkInput &file, DataChunkInfo *info
TeamsInfo ti;
ti.init(&teamDict);
CFixTeamOwnerDialog fix(&ti, &pThis->m_sides);
+ bool nameSet = false;
if (fix.DoModal() == IDOK) {
if (fix.pickedValidTeam()) {
teamDict.setAsciiString(TheKey_teamOwner, fix.getSelectedOwner());
+ nameSet = true;
}
}
- AsciiString neutralPlayerName; // neutral player name is empty string
- // player doesn't exist, so add it to the neutral player.
- teamDict.setAsciiString(TheKey_teamOwner, neutralPlayerName);
+ if (nameSet == false) {
+ AsciiString neutralPlayerName; // neutral player name is empty string
+ // player doesn't exist, so add it to the neutral player.
+ teamDict.setAsciiString(TheKey_teamOwner, neutralPlayerName);
+ }
pThis->m_sides.addTeam(&teamDict);
}
}
@@ -1632,11 +1807,38 @@ Bool ScriptDialog::ParseTeamsDataChunk(DataChunkInput &file, DataChunkInfo *info
Bool ScriptDialog::ParsePlayersDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData)
{
ScriptDialog *pThis = (ScriptDialog *)userData;
+ Int readDicts = 0;
+ if (info->version >= K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_2) {
+ readDicts = file.readInt();
+ }
Int numNames = file.readInt();
Int i;
for (i=0; i=MAX_PLAYER_COUNT) break;
pThis->m_readPlayerNames[i] = file.readAsciiString();
+ if (readDicts) {
+ Dict sideDict = file.readDict();
+ bool nameFound = false;
+ for (Int j=0; j < pThis->m_sides.getNumSides(); j++) {
+ AsciiString name = pThis->m_sides.getSideInfo(j)->getDict()->getAsciiString(TheKey_playerName);
+
+ if (name == pThis->m_readPlayerNames[i]) {
+ // The side already exists so don't add it or overwrite the old data.
+ nameFound = true;
+ break;
+ }
+ }
+ if (nameFound == false) {
+ // This side doesn't currently exist, so add it.
+ pThis->m_sides.addSide(&sideDict);
+ ScriptList* pList = newInstance(ScriptList);
+ SidesInfo* sides = pThis->m_sides.findSideInfo(pThis->m_readPlayerNames[i]);
+ // A script list must be created.
+ sides->setScriptList(pList);
+ // Update the dialog.
+ pThis->addPlayer(i);
+ }
+ }
}
DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Unexpected data left over."));
return true;
diff --git a/Generals/Code/Tools/WorldBuilder/src/ScriptProperties.cpp b/Generals/Code/Tools/WorldBuilder/src/ScriptProperties.cpp
index 68e403d43d0..4f5cda9d1df 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ScriptProperties.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ScriptProperties.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp b/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp
index 23bbfa673e7..9bb7546994a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/SelectMacrotexture.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/ShadowOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/ShadowOptions.cpp
index 673c1b1cf22..451f24aacf2 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ShadowOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ShadowOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/SplashScreen.cpp b/Generals/Code/Tools/WorldBuilder/src/SplashScreen.cpp
index 8f139382d02..ba08c559812 100644
--- a/Generals/Code/Tools/WorldBuilder/src/SplashScreen.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/SplashScreen.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
** along with this program. If not, see .
*/
+
#include "StdAfx.h"
#include "SplashScreen.h"
diff --git a/Generals/Code/Tools/WorldBuilder/src/StdAfx.cpp b/Generals/Code/Tools/WorldBuilder/src/StdAfx.cpp
index ca51b326075..27b9a90ba32 100644
--- a/Generals/Code/Tools/WorldBuilder/src/StdAfx.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/StdAfx.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TeamBehavior.cpp b/Generals/Code/Tools/WorldBuilder/src/TeamBehavior.cpp
index 27cfbe551a8..8e7a08076ea 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TeamBehavior.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TeamBehavior.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TeamGeneric.cpp b/Generals/Code/Tools/WorldBuilder/src/TeamGeneric.cpp
index 76ae9a5c0f4..77f2a89f60d 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TeamGeneric.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TeamGeneric.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
** along with this program. If not, see .
*/
+
#include "StdAfx.h"
#include "resource.h"
diff --git a/Generals/Code/Tools/WorldBuilder/src/TeamIdentity.cpp b/Generals/Code/Tools/WorldBuilder/src/TeamIdentity.cpp
index 02ab748547f..e495b235f1b 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TeamIdentity.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TeamIdentity.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp b/Generals/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp
new file mode 100644
index 00000000000..cb8df0b90a3
--- /dev/null
+++ b/Generals/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp
@@ -0,0 +1,684 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+// TeamObjectProperties.cpp
+// Mike Lytle
+// January, 2003
+// (c) Electronic Arts 2003
+
+#include "StdAfx.h"
+#include "TeamObjectProperties.h"
+#include "Common/MapObject.h"
+#include "Common/WellKnownKeys.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// TeamObjectProperties dialog
+
+TeamObjectProperties::TeamObjectProperties(Dict* dictToEdit)
+ : CPropertyPage(TeamObjectProperties::IDD),
+ m_dictToEdit(dictToEdit)
+{
+ //{{AFX_DATA_INIT(TeamObjectProperties)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+}
+
+TeamObjectProperties::~TeamObjectProperties()
+{
+}
+
+void TeamObjectProperties::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(TeamObjectProperties)
+ // NOTE: the ClassWizard will add DDX and DDV calls here
+ //}}AFX_DATA_MAP
+}
+
+#if 0
+BEGIN_MESSAGE_MAP(TeamObjectProperties, CPropertyPage)
+ //{{AFX_MSG_MAP(TeamObjectProperties)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_StartingHealth, _HealthToDict)
+ ON_CBN_SELENDOK(IDC_MAPOBJECT_HitPoints, _HPsToDict)
+ ON_CBN_KILLFOCUS(IDC_MAPOBJECT_HitPoints, _HPsToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Enabled, _EnabledToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Indestructible, _IndestructibleToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Unsellable, _UnsellableToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Powered, _PoweredToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Aggressiveness, _AggressivenessToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_VisionDistance, _VisibilityToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_ShroudClearingDistance, _ShroudClearingDistanceToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Veterancy, _VeterancyToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_RecruitableAI, _RecruitableAIToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Selectable, _SelectableToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Weather, _WeatherToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Time, _TimeToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_StoppingDistance, _StoppingDistanceToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_StartingHealthEdit, _HealthToDict)
+ ON_BN_CLICKED(IDC_UPDATE_TEAM_MEMBERS, _UpdateTeamMembers)
+
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// TeamObjectProperties message handlers
+
+BOOL TeamObjectProperties::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+ updateTheUI();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void TeamObjectProperties::OnOK()
+{
+ _PropertiesToDict();
+}
+
+void TeamObjectProperties::updateTheUI()
+{
+ _DictToHealth();
+ _DictToHPs();
+ _DictToEnabled();
+ _DictToDestructible();
+ _DictToPowered();
+ _DictToUnsellable();
+ _DictToAggressiveness();
+ _DictToVisibilityRange();
+ _DictToVeterancy();
+ _DictToWeather();
+ _DictToTime();
+ _DictToShroudClearingDistance();
+ _DictToRecruitableAI();
+ _DictToSelectable();
+ _DictToStoppingDistance();
+}
+
+void TeamObjectProperties::_DictToHealth()
+{
+ Int value = 100;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_teamObjectInitialHealth, &exists);
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_StartingHealth);
+ CWnd* pItem2 = GetDlgItem(IDC_MAPOBJECT_StartingHealthEdit);
+ if (pItem && pItem2) {
+ if (value == 0) {
+ pItem->SelectString(-1, "0%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else if (value == 25) {
+ pItem->SelectString(-1, "25%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else if (value == 50) {
+ pItem->SelectString(-1, "50%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else if (value == 75) {
+ pItem->SelectString(-1, "75%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else if (value == 100) {
+ pItem->SelectString(-1, "100%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else {
+ pItem->SelectString(-1, "Other");
+ static char buff[12];
+ snprintf(buff, ARRAY_SIZE(buff), "%d", value);
+ pItem2->SetWindowText(buff);
+ pItem2->EnableWindow(TRUE);
+ }
+ }
+}
+
+void TeamObjectProperties::_DictToHPs()
+{
+ Int value = -1;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_teamObjectMaxHPs, &exists);
+ if (!exists)
+ value = -1;
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_HitPoints);
+ pItem->ResetContent();
+ CString str;
+ str.Format("Default For Unit");
+ pItem->InsertString(-1, str);
+
+ if (value != -1) {
+ str.Format("%d", value);
+ pItem->InsertString(-1, str);
+ pItem->SetCurSel(1);
+ } else {
+ pItem->SetCurSel(0);
+ }
+}
+
+void TeamObjectProperties::_DictToEnabled()
+{
+ Bool enabled = true;
+ Bool exists;
+ if (m_dictToEdit) {
+ enabled = m_dictToEdit->getBool(TheKey_teamObjectEnabled, &exists);
+ }
+
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Enabled);
+ if (pItem) {
+ pItem->SetCheck(enabled);
+ }
+}
+
+void TeamObjectProperties::_DictToDestructible()
+{
+ Bool destructible = true;
+ Bool exists;
+ if (m_dictToEdit) {
+ destructible = m_dictToEdit->getBool(TheKey_teamObjectIndestructible, &exists);
+ }
+
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Indestructible);
+ if (pItem) {
+ pItem->SetCheck(destructible);
+ }
+}
+
+void TeamObjectProperties::_DictToUnsellable()
+{
+ Bool unsellable = false;
+ Bool exists;
+ if (m_dictToEdit) {
+ unsellable = m_dictToEdit->getBool(TheKey_teamObjectUnsellable, &exists);
+ }
+
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Unsellable);
+ if (pItem) {
+ pItem->SetCheck(unsellable);
+ }
+}
+
+void TeamObjectProperties::_DictToPowered()
+{
+ Bool powered = true;
+ Bool exists;
+ if (m_dictToEdit) {
+ powered = m_dictToEdit->getBool(TheKey_teamObjectPowered, &exists);
+ }
+
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Powered);
+ if (pItem) {
+ pItem->SetCheck(powered);
+ }
+
+}
+
+void TeamObjectProperties::_DictToAggressiveness()
+{
+ Int value = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_teamObjectAggressiveness, &exists);
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Aggressiveness);
+ if (pItem) {
+ if (value == -2) {
+ pItem->SelectString(-1, "Sleep");
+ } else if (value == -1) {
+ pItem->SelectString(-1, "Passive");
+ } else if (value == 0) {
+ pItem->SelectString(-1, "Normal");
+ } else if (value == 1) {
+ pItem->SelectString(-1, "Alert");
+ } else if (value == 2) {
+ pItem->SelectString(-1, "Aggressive");
+ }
+ }
+}
+
+void TeamObjectProperties::_DictToVisibilityRange()
+{
+ Int distance = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ distance = m_dictToEdit->getInt(TheKey_teamObjectVisualRange, &exists);
+ }
+
+ CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_VisionDistance);
+ if (pItem) {
+ static char buff[12];
+ snprintf(buff, ARRAY_SIZE(buff), "%d", distance);
+ if (distance == 0) {
+ pItem->SetWindowText("");
+ } else {
+ pItem->SetWindowText(buff);
+ }
+ }
+}
+
+void TeamObjectProperties::_DictToVeterancy()
+{
+ Int value = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_teamObjectVeterancy, &exists);
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Veterancy);
+ if (pItem) {
+ pItem->SetCurSel(value);
+ }
+}
+
+void TeamObjectProperties::_DictToWeather()
+{
+ Int value = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_teamObjectWeather, &exists);
+ if (!exists)
+ value = 0;
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Weather);
+ pItem->SetCurSel(value);
+}
+
+void TeamObjectProperties::_DictToTime()
+{
+ Int value = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_teamObjectTime, &exists);
+ if (!exists)
+ value = 0;
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Time);
+ pItem->SetCurSel(value);
+}
+
+void TeamObjectProperties::_DictToShroudClearingDistance()
+{
+ Int distance = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ distance = m_dictToEdit->getInt(TheKey_teamObjectShroudClearingDistance, &exists);
+ }
+
+ CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_ShroudClearingDistance);
+ if (pItem) {
+ static char buff[12];
+ snprintf(buff, ARRAY_SIZE(buff), "%d", distance);
+ if (distance == 0) {
+ pItem->SetWindowText("");
+ } else {
+ pItem->SetWindowText(buff);
+ }
+ }
+}
+
+void TeamObjectProperties::_DictToRecruitableAI()
+{
+ Bool recruitableAI = true;
+ Bool exists;
+ if (m_dictToEdit) {
+ recruitableAI = m_dictToEdit->getBool(TheKey_teamObjectRecruitableAI, &exists);
+ }
+
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
+ if (pItem) {
+ pItem->SetCheck(recruitableAI);
+ }
+}
+
+void TeamObjectProperties::_DictToSelectable()
+{
+ Bool selectable = true;
+ Bool exists;
+ if (m_dictToEdit) {
+ selectable = m_dictToEdit->getBool(TheKey_teamObjectSelectable, &exists);
+ }
+
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
+ if (pItem) {
+ pItem->SetCheck(selectable);
+ }
+}
+
+void TeamObjectProperties::_DictToStoppingDistance()
+{
+ Real stoppingDistance = 1.0f;
+ Bool exists = false;
+ if (m_dictToEdit) {
+ stoppingDistance = m_dictToEdit->getReal(TheKey_teamObjectStoppingDistance, &exists);
+ }
+
+ CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_StoppingDistance);
+ if (pItem) {
+ static char buff[64];
+ sprintf(buff, ARRAY_SIZE(buff), "%g", stoppingDistance);
+ if (stoppingDistance == 0) {
+ pItem->SetWindowText("");
+ } else {
+ pItem->SetWindowText(buff);
+ }
+ }
+}
+
+void TeamObjectProperties::_HealthToDict()
+{
+ Int value;
+ static char buf[1024];
+
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_StartingHealth);
+ owner->GetWindowText(buf, sizeof(buf)-2);
+ if (strcmp(buf, "Dead") == 0) {
+ value = 0;
+ } else if (strcmp(buf, "25%") == 0) {
+ value = 25;
+ } else if (strcmp(buf, "50%") == 0) {
+ value = 50;
+ } else if (strcmp(buf, "75%") == 0) {
+ value = 75;
+ } else if (strcmp(buf, "100%") == 0) {
+ value = 100;
+ } else if (strcmp(buf, "Other") == 0) {
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_StartingHealthEdit);
+ edit->EnableWindow(TRUE);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (cstr.IsEmpty()) {
+ return;
+ }
+ value = atoi(cstr.GetBuffer(0));
+ }
+
+ m_dictToEdit->setInt(TheKey_teamObjectInitialHealth, value);
+}
+
+void TeamObjectProperties::_EnabledToDict()
+{
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Enabled);
+ Bool isChecked = (owner->GetCheck() != 0);
+
+ m_dictToEdit->setBool(TheKey_teamObjectEnabled, isChecked);
+}
+
+
+void TeamObjectProperties::_IndestructibleToDict()
+{
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Indestructible);
+ Bool isChecked = (owner->GetCheck() != 0);
+
+ m_dictToEdit->setBool(TheKey_teamObjectIndestructible, isChecked);
+}
+
+void TeamObjectProperties::_UnsellableToDict()
+{
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Unsellable);
+ Bool isChecked = (owner->GetCheck() != 0);
+
+ m_dictToEdit->setBool(TheKey_teamObjectUnsellable, isChecked);
+}
+
+void TeamObjectProperties::_PoweredToDict()
+{
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Powered);
+ Bool isChecked = (owner->GetCheck() != 0);
+
+ m_dictToEdit->setBool(TheKey_teamObjectPowered, isChecked);
+}
+
+void TeamObjectProperties::_AggressivenessToDict()
+{
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Aggressiveness);
+ static char buf[1024];
+ owner->GetWindowText(buf, sizeof(buf)-2);
+ int value = 0;
+
+ if (strcmp(buf, "Sleep") == 0) {
+ value = -2;
+ } else if (strcmp(buf, "Passive") == 0) {
+ value = -1;
+ } else if (strcmp(buf, "Normal") == 0) {
+ value = 0;
+ } else if (strcmp(buf, "Alert") == 0) {
+ value = 1;
+ } else if (strcmp(buf, "Aggressive") == 0) {
+ value = 2;
+ }
+
+ m_dictToEdit->setInt(TheKey_teamObjectAggressiveness, value);
+}
+
+void TeamObjectProperties::_VisibilityToDict()
+{
+ int value = -1;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_VisionDistance);
+ edit->EnableWindow(TRUE);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ value = atoi(cstr.GetBuffer(0));
+ }
+
+ if (value != -1) {
+ m_dictToEdit->setInt(TheKey_teamObjectVisualRange, value);
+ }
+}
+
+void TeamObjectProperties::_VeterancyToDict()
+{
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Veterancy);
+ static char buf[1024];
+ int curSel = owner->GetCurSel();
+ int value = 0;
+ if (curSel >= 0) {
+ value=curSel;
+ }
+
+ m_dictToEdit->setInt(TheKey_teamObjectVeterancy, value);
+}
+
+void TeamObjectProperties::_WeatherToDict()
+{
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Weather);
+ static char buf[1024];
+ int curSel = owner->GetCurSel();
+
+ m_dictToEdit->setInt(TheKey_teamObjectWeather, curSel);
+}
+
+void TeamObjectProperties::_TimeToDict()
+{
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Time);
+ static char buf[1024];
+ int curSel = owner->GetCurSel();
+
+ m_dictToEdit->setInt(TheKey_teamObjectTime, curSel);
+}
+
+void TeamObjectProperties::_ShroudClearingDistanceToDict()
+{
+ int value = -1;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ShroudClearingDistance);
+ edit->EnableWindow(TRUE);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ value = atoi(cstr.GetBuffer(0));
+ }
+
+ if (value != -1) {
+ m_dictToEdit->setInt(TheKey_teamObjectShroudClearingDistance, value);
+ }
+}
+
+void TeamObjectProperties::_RecruitableAIToDict()
+{
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
+ Bool isChecked = (owner->GetCheck() != 0);
+
+ m_dictToEdit->setBool(TheKey_teamObjectRecruitableAI, isChecked);
+}
+
+void TeamObjectProperties::_SelectableToDict()
+{
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
+ Bool isChecked = (owner->GetCheck() != 0);
+
+ m_dictToEdit->setBool(TheKey_teamObjectSelectable, isChecked);
+}
+
+void TeamObjectProperties::_HPsToDict()
+{
+ Int value;
+ static char buf[1024];
+
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_HitPoints);
+ owner->GetWindowText(buf, sizeof(buf)-2);
+ value = atoi(buf);
+ if (value == 0)
+ value = -1;
+
+ m_dictToEdit->setInt(TheKey_teamObjectMaxHPs, value);
+}
+
+void TeamObjectProperties::_StoppingDistanceToDict()
+{
+ Real value;
+ static char buf[1024];
+
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_StoppingDistance);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (cstr.IsEmpty()) {
+ return;
+ }
+ value = atof(cstr.GetBuffer(0));
+
+ m_dictToEdit->setReal(TheKey_teamObjectStoppingDistance, value);
+}
+
+void TeamObjectProperties::_UpdateTeamMembers()
+{
+ CString msg;
+ msg.Format("Are you sure you want to change the team members?");
+ if (::AfxMessageBox(msg, MB_YESNO) == IDNO) {
+ return;
+ }
+
+ AsciiString teamName = m_dictToEdit->getAsciiString(TheKey_teamName);
+
+ MapObject *pObj;
+ for (pObj=MapObject::getFirstMapObject(); pObj; pObj=pObj->getNext()) {
+ Dict* objectDict = pObj->getProperties();
+ DEBUG_ASSERTCRASH(objectDict, ("objectDict shouldn't be null"));
+
+ AsciiString objectsTeam = objectDict->getAsciiString(TheKey_originalOwner);
+
+ if (teamName == objectsTeam) {
+ DEBUG_ASSERTCRASH(m_dictToEdit, ("m_dictToEdit shouldn't be null"));
+ Bool exists;
+
+ Int value = m_dictToEdit->getInt(TheKey_teamObjectInitialHealth, &exists);
+ objectDict->setInt(TheKey_objectInitialHealth, value);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectMaxHPs, &exists);
+ objectDict->setInt(TheKey_objectMaxHPs, value);
+
+ Bool enabled = m_dictToEdit->getBool(TheKey_teamObjectEnabled, &exists);
+ objectDict->setBool(TheKey_objectEnabled, enabled);
+
+ enabled = m_dictToEdit->getBool(TheKey_teamObjectIndestructible, &exists);
+ objectDict->setBool(TheKey_objectIndestructible, enabled);
+
+ enabled = m_dictToEdit->getBool(TheKey_teamObjectUnsellable, &exists);
+ objectDict->setBool(TheKey_objectUnsellable, enabled);
+
+ enabled = m_dictToEdit->getBool(TheKey_teamObjectPowered, &exists);
+ objectDict->setBool(TheKey_objectPowered, enabled);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectAggressiveness, &exists);
+ objectDict->setInt(TheKey_objectAggressiveness, value);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectVisualRange, &exists);
+ objectDict->setInt(TheKey_objectVisualRange, value);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectVeterancy, &exists);
+ objectDict->setInt(TheKey_objectVeterancy, value);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectWeather, &exists);
+ objectDict->setInt(TheKey_objectWeather, value);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectTime, &exists);
+ objectDict->setInt(TheKey_objectTime, value);
+
+ value = m_dictToEdit->getInt(TheKey_teamObjectShroudClearingDistance, &exists);
+ objectDict->setInt(TheKey_objectShroudClearingDistance, value);
+
+ enabled = m_dictToEdit->getBool(TheKey_teamObjectRecruitableAI, &exists);
+ objectDict->setBool(TheKey_objectRecruitableAI, enabled);
+
+ enabled = m_dictToEdit->getBool(TheKey_teamObjectSelectable, &exists);
+ objectDict->setBool(TheKey_objectSelectable, enabled);
+
+ Real dist = m_dictToEdit->getReal(TheKey_teamObjectStoppingDistance, &exists);
+ objectDict->setReal(TheKey_objectStoppingDistance, dist);
+
+ }
+ }
+}
+
+
+void TeamObjectProperties::_PropertiesToDict()
+{
+ // Make sure that the attributes are in the dictionary.
+ _HealthToDict();
+ _HPsToDict();
+ _EnabledToDict();
+ _IndestructibleToDict();
+ _UnsellableToDict();
+ _PoweredToDict();
+ _AggressivenessToDict();
+ _VisibilityToDict();
+ _ShroudClearingDistanceToDict();
+ _VeterancyToDict();
+ _RecruitableAIToDict();
+ _SelectableToDict();
+ _WeatherToDict();
+ _TimeToDict();
+ _StoppingDistanceToDict();
+ _HealthToDict();
+}
+
+#endif
+
+BOOL TeamObjectProperties::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+ return CPropertyPage::OnCommand(wParam, lParam);
+}
diff --git a/Generals/Code/Tools/WorldBuilder/src/TeamReinforcement.cpp b/Generals/Code/Tools/WorldBuilder/src/TeamReinforcement.cpp
index 36cbba5c4f4..ac5045b099a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TeamReinforcement.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TeamReinforcement.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp b/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp
index 6f56c51fd31..92e828d7138 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TerrainMaterial.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp b/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp
index 25dee84ad33..031155d7a4a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TerrainModal.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TerrainSwatches.cpp b/Generals/Code/Tools/WorldBuilder/src/TerrainSwatches.cpp
index d01ddc7ed7d..f95f55c2574 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TerrainSwatches.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TerrainSwatches.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/TileTool.cpp b/Generals/Code/Tools/WorldBuilder/src/TileTool.cpp
index f9d9aa9217a..aa2688ecb2a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/TileTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/TileTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -83,11 +83,12 @@ void TileTool::mouseDown(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldBu
void TileTool::mouseUp(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldBuilderDoc *pDoc)
{
if (m != TRACK_L && m != TRACK_R) return;
-
+#define DONT_DO_FULL_UPDATE
+#ifdef DO_FULL_UPDATE
m_htMapEditCopy->optimizeTiles(); // force to optimize tileset
IRegion2D partialRange = {0,0,0,0};
pDoc->updateHeightMap(m_htMapEditCopy, false, partialRange);
-
+#endif
WBDocUndoable *pUndo = new WBDocUndoable(pDoc, m_htMapEditCopy);
pDoc->AddAndDoUndoable(pUndo);
REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
@@ -166,6 +167,9 @@ void TileTool::mouseMoved(TTrackingMode m, CPoint viewPt, WbView* pView, CWorldB
partialRange.hi.x = totalMaxX+1;
partialRange.lo.y = totalMinY;
partialRange.hi.y = totalMaxY+1;
+ if (fullUpdate) {
+ m_htMapEditCopy->optimizeTiles(); // force to optimize tileset
+ }
pDoc->updateHeightMap(m_htMapEditCopy, !fullUpdate, partialRange);
}
pView->UpdateWindow();
diff --git a/Generals/Code/Tools/WorldBuilder/src/Tool.cpp b/Generals/Code/Tools/WorldBuilder/src/Tool.cpp
index b186cf483f7..c179749f17f 100644
--- a/Generals/Code/Tools/WorldBuilder/src/Tool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/Tool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WBFrameWnd.cpp b/Generals/Code/Tools/WorldBuilder/src/WBFrameWnd.cpp
index ddea4384636..878a03f1909 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WBFrameWnd.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WBFrameWnd.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WBHeightMap.cpp b/Generals/Code/Tools/WorldBuilder/src/WBHeightMap.cpp
index faa11da19ad..c013a07b049 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WBHeightMap.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WBHeightMap.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -45,7 +45,7 @@
#include
#include
-
+#define dontUSE_FLAT_HEIGHT_MAP
//-----------------------------------------------------------------------------
// Private Data
//-----------------------------------------------------------------------------
@@ -68,9 +68,11 @@ void WBHeightMap::setFlattenHeights(Bool flat)
{
if (m_flattenHeights != flat) {
m_flattenHeights = flat;
+#ifndef USE_FLAT_HEIGHT_MAP
m_originX = 0;
m_originY = 0;
updateBlock(0, 0, m_x-1, m_y-1, m_map, nullptr);
+#endif
}
}
@@ -83,6 +85,7 @@ void WBHeightMap::setFlattenHeights(Bool flat)
/** Flattens the terrain for the top down view.. */
//=============================================================================
void WBHeightMap::flattenHeights() {
+#ifndef USE_FLAT_HEIGHT_MAP
Real theZ = THE_Z;
Int i, j;
for (j=0; jgetXExtent()+overhang),
MAP_XY_FACTOR*(m_map->getYExtent()+overhang), MAP_HEIGHT_SCALE*m_map->getMaxHeightValue()+MAP_XY_FACTOR);
@@ -300,7 +304,11 @@ void WBHeightMap::Render(RenderInfoClass & rinfo)
if (m_flattenHeights) {
flattenHeights();
}
+#ifdef USE_FLAT_HEIGHT_MAP
+ FlatHeightMapRenderObjClass::Render(rinfo);
+#else
HeightMapRenderObjClass::Render(rinfo);
+#endif
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/WBPopupSlider.cpp b/Generals/Code/Tools/WorldBuilder/src/WBPopupSlider.cpp
index ceceb6328fa..1d2d782a920 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WBPopupSlider.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WBPopupSlider.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp b/Generals/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
index 933c664aa69..89af322f931 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -43,6 +43,7 @@
#include "Common/DataChunk.h"
+
int WorldHeightMapEdit::m_numGlobalTextureClasses=0;
TGlobalTextureClass WorldHeightMapEdit::m_globalTextureClasses[NUM_TEXTURE_CLASSES];
/** Destructor -.
@@ -120,7 +121,7 @@ WorldHeightMapEdit::WorldHeightMapEdit(Int width, Int height, UnsignedByte initi
// Note - we have one less cell than the width & height. But for paranoia, allocate
// extra row. jba.
//
- Int numBytesX = (m_width+1)/8; //how many bytes to fit all bitflags
+ Int numBytesX = (m_width+7)/8; //how many bytes to fit all bitflags
Int numBytesY = m_height;
m_flipStateWidth=numBytesX;
@@ -209,7 +210,7 @@ m_warnTooManyBlend(false)
// Note - we have one less cell than the width & height. But for paranoia, allocate
// extra row. jba.
//
- Int numBytesX = (m_width+1)/8; //how many bytes to fit all bitflags
+ Int numBytesX = (m_width+7)/8; //how many bytes to fit all bitflags
Int numBytesY = m_height;
m_flipStateWidth=numBytesX;
@@ -433,8 +434,7 @@ void WorldHeightMapEdit::loadDirectoryOfImages(const char *pFilePath)
FilenameList::iterator it = filenameList.begin();
do {
AsciiString filename = *it;
-
- snprintf(fileBuf, ARRAY_SIZE(fileBuf), "%s%s", dirBuf, filename.str());
+ strlcpy(fileBuf, filename.str(), ARRAY_SIZE(fileBuf));
loadBitmap(fileBuf, filename.str());
++it;
@@ -506,39 +506,30 @@ void WorldHeightMapEdit::loadImagesFromTerrainType( TerrainType *terrain )
}
-
-Bool WorldHeightMapEdit::getRawTileData(Short tileNdx, Int width,
- UnsignedByte *buffer, Int bufLen)
+Bool WorldHeightMapEdit::getRawTileData(Short tileNdx, Int width, UnsignedByte *buffer, Int bufLen)
{
TileData *pSrc = nullptr;
- if (tileNdx/4 < NUM_SOURCE_TILES) {
- pSrc = m_sourceTiles[tileNdx/4];
+ if (tileNdx / 4 < NUM_SOURCE_TILES) {
+ pSrc = m_sourceTiles[tileNdx / 4];
}
- if (bufLen < (width*width*TILE_BYTES_PER_PIXEL)) {
- return(false);
+ if (bufLen < (width * width * TILE_BYTES_PER_PIXEL)) {
+ return false;
}
- if (pSrc && pSrc->hasRGBDataForWidth(2*width)) {
- Int j;
- UnsignedByte *pSrcData = pSrc->getRGBDataForWidth(2*width);
- Int xOffset=0;
- Int yOffset=0;
- if (tileNdx & 1) xOffset = width;
- if (tileNdx & 2) yOffset = width;
- for (j=0; jhasRGBDataForWidth(2 * width)) {
+ UnsignedByte *pSrcData = pSrc->getRGBDataForWidth(2 * width);
+ Int xOffset = (tileNdx & 1) ? width : 0;
+ Int yOffset = (tileNdx & 2) ? width : 0;
+ for (Int j = 0; j < width; ++j) {
+ UnsignedByte *pDestData = buffer + j * width * TILE_BYTES_PER_PIXEL;
+ UnsignedByte *pSrcRow = pSrcData + (j + yOffset) * width * TILE_BYTES_PER_PIXEL * 2;
+ pSrcRow += xOffset * TILE_BYTES_PER_PIXEL;
+ memcpy(pDestData, pSrcRow, width * TILE_BYTES_PER_PIXEL);
+ }
+ return true;
}
- return(false);
+ return false;
}
-
-
UnsignedByte * WorldHeightMapEdit::getPointerToClassTileData(Int texClass)
{
TileData *pSrc = nullptr;
@@ -633,7 +624,11 @@ void WorldHeightMapEdit::saveToFile(DataChunkOutput &chunkWriter)
chunkWriter.closeDataChunk();
/***************BLEND TILE DATA ***************/
+#if RTS_GENERALS
chunkWriter.openDataChunk("BlendTileData", K_BLEND_TILE_VERSION_7);
+#else
+ chunkWriter.openDataChunk("BlendTileData", K_BLEND_TILE_VERSION_8);
+#endif
chunkWriter.writeInt(m_dataSize);
chunkWriter.writeArrayOfBytes((char*)m_tileNdxes, m_dataSize*sizeof(Short));
chunkWriter.writeArrayOfBytes((char*)m_blendTileNdxes, m_dataSize*sizeof(Short));
@@ -1130,7 +1125,7 @@ void WorldHeightMapEdit::blendSpecificTiles(Int xIndex, Int yIndex, Int srcXInde
blendInfo.customBlendEdgeClass = edgeClass;
//Check if there is already a blend tile at the destination and record its flip state.
- //We need to know this so that we don't accidentally apply a third blend layer with with
+ //We need to know this so that we don't accidentally apply a third blend layer with
//a different flip and introduce z-fighting over this tile.
Bool baseNeedsFlip = false;
UnsignedByte baseIsDiagonal = 0;
@@ -1200,7 +1195,12 @@ void WorldHeightMapEdit::blendSpecificTiles(Int xIndex, Int yIndex, Int srcXInde
//force the primary layer to flip if the extra blend layer needs flip.
//we only do this on vertical/horizontal base blends because they work in either flip cases.
if (flipped && !baseIsDiagonal)
- m_blendedTiles[m_blendTileNdxes[ndx]].inverted |= FLIPPED_MASK;
+ { //Find a new tile so as not to affect other cells using the base one.
+ TBlendTileInfo tempBlendTileInfo=m_blendedTiles[m_blendTileNdxes[ndx]];
+ tempBlendTileInfo.inverted |= FLIPPED_MASK;
+ Short newNdx = findOrCreateBlendTile(&tempBlendTileInfo);
+ m_blendTileNdxes[ndx] = newNdx; //remap this tile to use a new one.
+ }
}
else
m_blendTileNdxes[ndx] = newNdx;
@@ -1886,7 +1886,7 @@ Bool WorldHeightMapEdit::resize(Int newXSize, Int newYSize, Int newHeight, Int n
m_dataSize = newDataSize;
delete(m_cellCliffState);
delete(m_cellFlipState);
- Int numBytesX = (m_width+1)/8; //how many bytes to fit all bitflags
+ Int numBytesX = (m_width+7)/8; //how many bytes to fit all bitflags
m_flipStateWidth=numBytesX;
m_cellFlipState = MSGNEW("WorldHeightMapEdit::resize") UnsignedByte[numBytesX*m_height];
@@ -3444,6 +3444,5 @@ void WorldHeightMapEdit::findBoundaryNear(Coord3D *pt, float okDistance, Int *ou
}
(*outNdx) = -1;
+ (*outHandle) = -1;
}
-
-
diff --git a/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp
index 9e3d04144d0..04e0f463ea9 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WaterTool.cpp b/Generals/Code/Tools/WorldBuilder/src/WaterTool.cpp
index 643c253bae1..aa52fa42821 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WaterTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WaterTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp b/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp
index 4b16a953ab3..4ce35b40e57 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WaypointTool.cpp b/Generals/Code/Tools/WorldBuilder/src/WaypointTool.cpp
index b425501566d..7a469ef50c4 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WaypointTool.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WaypointTool.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
index c122151259d..888d8ef5c4e 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -229,6 +229,7 @@ CWorldBuilderApp::CWorldBuilderApp() :
m_tools[21] = &m_rampTool;
m_tools[22] = &m_scorchTool;
m_tools[23] = &m_borderTool;
+ m_tools[24] = &m_rulerTool;
// set up initial values.
m_brushTool.setHeight(16);
@@ -255,6 +256,7 @@ CWorldBuilderApp::~CWorldBuilderApp()
m_tools[i] = nullptr;
}
}
+ _exit(0);
}
/////////////////////////////////////////////////////////////////////////////
@@ -271,13 +273,21 @@ static LONG WINAPI UnHandledExceptionFilter(struct _EXCEPTION_POINTERS* e_info)
BOOL CWorldBuilderApp::InitInstance()
{
+ ApplicationHWnd = GetDesktopWindow();
+
// initialization
SetUnhandledExceptionFilter(UnHandledExceptionFilter);
// initialize the memory manager early
initMemoryManager();
+#ifdef DEBUG_LOGGING
+ // Turn on console output jba [3/20/2003]
+ DebugSetFlags(DebugGetFlags() | DEBUG_FLAG_LOG_TO_CONSOLE);
+#endif
+
DEBUG_LOG(("starting Worldbuilder."));
+
#ifdef RTS_DEBUG
DEBUG_LOG(("RTS_DEBUG defined."));
#endif
@@ -333,9 +343,10 @@ BOOL CWorldBuilderApp::InitInstance()
#endif
#ifdef DEBUG_CRASHING
- TheWritableGlobalData->m_debugIgnoreAsserts = true;
+ TheWritableGlobalData->m_debugIgnoreAsserts = false;
#endif
+ DEBUG_LOG(("TheWritableGlobalData %x", TheWritableGlobalData));
#if 1
// srj sez: put INI into our user data folder, not the ap dir
free((void*)m_pszProfileName);
@@ -366,6 +377,14 @@ BOOL CWorldBuilderApp::InitInstance()
WorldHeightMapEdit::init();
initSubsystem(TheScriptEngine, (ScriptEngine*)(new ScriptEngine()));
+
+#if RTS_ZEROHOUR
+ TheScriptEngine->turnBreezeOff(); // stop the tree sway.
+#endif
+
+ // [2/11/2003]
+ ini.loadFileDirectory( "Data\\Scripts\\Scripts", INI_LOAD_OVERWRITE, nullptr );
+
initSubsystem(TheAudio, (AudioManager*)new MilesAudioManager());
initSubsystem(TheVideoPlayer, (VideoPlayerInterface*)(new VideoPlayer()));
initSubsystem(TheModuleFactory, (ModuleFactory*)(new W3DModuleFactory()));
@@ -526,7 +545,7 @@ void CWorldBuilderApp::setActiveTool(Tool *pNewTool)
// CWorldBuilderApp::updateCurTool
//=============================================================================
/** Checks to see if any key modifiers (ctrl or alt) are pressed. If so,
-selectes the appropriate tool, else uses the normal tool. */
+selects the appropriate tool, else uses the normal tool. */
//=============================================================================
void CWorldBuilderApp::updateCurTool(Bool forceHand)
{
@@ -638,6 +657,9 @@ int CWorldBuilderApp::ExitInstance()
#ifdef MEMORYPOOL_CHECKPOINTING
TheMemoryPoolFactory->debugMemoryReport(REPORT_FACTORYINFO | REPORT_CP_LEAKS | REPORT_CP_STACKTRACE, gFirstCP, lastCP);
#endif
+ #ifdef MEMORYPOOL_DEBUG
+ TheMemoryPoolFactory->debugMemoryReport(REPORT_POOLINFO | REPORT_POOL_OVERFLOW | REPORT_SIMPLE_LEAKS, 0, 0);
+ #endif
shutdownMemoryManager();
return CWinApp::ExitInstance();
diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp
index 14032945d3b..185b81dd1b2 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -59,6 +59,7 @@
#include "WorldBuilderView.h"
#include "MapPreview.h"
+
// Can't currently have multiple open... jba.
#define notONLY_ONE_AT_A_TIME
@@ -107,6 +108,7 @@ BEGIN_MESSAGE_MAP(CWorldBuilderDoc, CDocument)
ON_UPDATE_COMMAND_UI(ID_WINDOW_2DWINDOW, OnUpdateWindow2dwindow)
ON_COMMAND(ID_VIEW_RELOADTEXTURES, OnViewReloadtextures)
ON_COMMAND(ID_EDIT_SCRIPTS, OnEditScripts)
+ ON_COMMAND(ID_SCRIPT_EDIT, OnEditScripts)
ON_COMMAND(ID_VIEWHOME, OnViewHome)
ON_COMMAND(ID_TEXTURESIZING_TILE4X4, OnTexturesizingTile4x4)
ON_UPDATE_COMMAND_UI(ID_TEXTURESIZING_TILE4X4, OnUpdateTexturesizingTile4x4)
@@ -393,6 +395,16 @@ void CWorldBuilderDoc::Serialize(CArchive& ar)
}
pMapObj = pMapObj->getNext();
}
+
+ PolygonTrigger* polyTrigger = PolygonTrigger::getFirstPolygonTrigger();
+ // Add the triggers to the layers list.
+ while (polyTrigger) {
+ layerName = polyTrigger->getLayerName();
+ TheLayersList->addPolygonTriggerToLayersList(polyTrigger, layerName);
+
+ polyTrigger = polyTrigger->getNext();
+ }
+
TheLayersList->enableUpdates();
TerrainMaterial::updateTextures(m_heightMap);
@@ -420,6 +432,25 @@ void CWorldBuilderDoc::Serialize(CArchive& ar)
}
}
+AsciiString ConvertToNonGCName(AsciiString name, Bool checkTemplate=true)
+{
+ const char* replacePrefix = "GC_";
+ const size_t offset = name.startsWith(replacePrefix) ? strlen(replacePrefix) : 0u;
+ char newName[256];
+ strlcpy(newName, name.str() + offset, ARRAY_SIZE(newName));
+ AsciiString swapName;
+ swapName.set(newName);
+ if (checkTemplate)
+ {
+ const ThingTemplate *tt = TheThingFactory->findTemplate(swapName);
+ if (tt) {
+ return swapName;
+ }
+ return AsciiString::TheEmptyString;
+ }
+ return swapName;
+}
+
AsciiString ConvertName(AsciiString name)
{
const char* replacePrefix = "Fundamentalist";
@@ -460,14 +491,20 @@ void CWorldBuilderDoc::validate()
Bool changed = false;
AsciiString swapName;
+ Bool needToFixTeams = false;
+
// verify/fix the build lists
for (int side=0; sidegetNumSides(); side++) {
SidesInfo *pSide = TheSidesList->getSideInfo(side);
AsciiString tmplname = pSide->getDict()->getAsciiString(TheKey_playerFaction);
+ AsciiString playername = pSide->getDict()->getAsciiString(TheKey_playerName);
+ if (tmplname.isEmpty()) {
+ continue; // Neutral player has empty template. jba. [8/8/2003]
+ }
const PlayerTemplate* pt = ThePlayerTemplateStore->findPlayerTemplate(NAMEKEY(tmplname));
if (!pt) {
- DEBUG_LOG(("Faction %s could not be found in sides list!", tmplname.str()));
+ DEBUG_LOG(("Player '%s' Faction '%s' could not be found in sides list!", playername.str(), tmplname.str()));
if (tmplname.startsWith("FactionFundamentalist")) {
swapName = ConvertFaction(tmplname);
if (swapName != AsciiString::TheEmptyString) {
@@ -550,6 +587,15 @@ void CWorldBuilderDoc::validate()
}
}
+ // quick hack to remove "GC_" objects from Generals mission disk maps.
+ if (name.startsWith("GC_")) {
+ swapName = ConvertToNonGCName(name);
+ if (swapName != AsciiString::TheEmptyString) {
+ swapDict.setAsciiString(NAMEKEY(name), swapName);
+ exists = true;
+ }
+ }
+
if (!exists) {
ReplaceUnitDialog dlg;
dlg.setMissing(name);
@@ -590,9 +636,13 @@ void CWorldBuilderDoc::validate()
if (pSide) {
// Bool hasColor = false;
AsciiString tmplname = pSide->getDict()->getAsciiString(TheKey_playerFaction);
+ AsciiString playername = pSide->getDict()->getAsciiString(TheKey_playerName);
+ if (tmplname.isEmpty()) {
+ continue; // Neutral player has empty template. jba. [8/8/2003]
+ }
const PlayerTemplate* pt = ThePlayerTemplateStore->findPlayerTemplate(NAMEKEY(tmplname));
if (!pt) {
- DEBUG_LOG(("Faction %s could not be found in sides list!", tmplname.str()));
+ DEBUG_LOG(("Player '%s' Faction '%s' could not be found in sides list!", playername.str(), tmplname.str()));
if (tmplname.startsWith("FactionFundamentalist")) {
swapName = ConvertFaction(tmplname);
if (swapName != AsciiString::TheEmptyString) {
@@ -602,15 +652,21 @@ void CWorldBuilderDoc::validate()
}
}
} else {
- DEBUG_LOG(("Side %s could not be found in sides list!", teamOwner.str()));
+ needToFixTeams = true;
+ DEBUG_LOG(("Side '%s' could not be found in sides list!", teamOwner.str()));
}
} else {
- DEBUG_LOG(("Team %s could not be found in sides list!", teamName.str()));
+ needToFixTeams = true;
+ DEBUG_LOG(("Team '%s' could not be found in sides list!", teamName.str()));
}
} else {
- DEBUG_LOG(("Object %s does not have a team at all!", name.str()));
+ needToFixTeams = true;
+ DEBUG_LOG(("Object '%s' does not have a team at all!", name.str()));
}
}
+ if (needToFixTeams) {
+ AfxMessageBox(IDS_NEED_TO_FIX_TEAMS, MB_OK|MB_ICONERROR);
+ }
}
void CWorldBuilderDoc::OnJumpToGame()
@@ -1235,6 +1291,7 @@ BOOL CWorldBuilderDoc::OnNewDocument()
PolygonTrigger *pTrig = newInstance(PolygonTrigger)(4);
ICoord3D loc;
pTrig->setWaterArea(true);
+ pTrig->setTriggerName("Default Water");
loc.x = -hi.borderWidth*MAP_XY_FACTOR;
loc.y = -hi.borderWidth*MAP_XY_FACTOR;
loc.z = TheGlobalData->m_waterPositionZ;
@@ -1246,7 +1303,7 @@ BOOL CWorldBuilderDoc::OnNewDocument()
loc.x = -hi.borderWidth*MAP_XY_FACTOR;
pTrig->addPoint(loc);
PolygonTrigger::addPolygonTrigger(pTrig);
-
+ TheLayersList->addPolygonTriggerToLayersList(pTrig, pTrig->getLayerName());
SetHeightMap(m_heightMap, true);
TerrainMaterial::updateTextures(m_heightMap);
@@ -1886,8 +1943,8 @@ void CWorldBuilderDoc::OnViewReloadtextures()
void CWorldBuilderDoc::OnEditScripts()
{
- ScriptDialog script;
- script.DoModal();
+ ASSERT(CMainFrame::GetMainFrame());
+ CMainFrame::GetMainFrame()->onEditScripts();
}
/* when "home" key is pressed, goes to the initial camera waypoint or if
diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderView.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderView.cpp
index 01907cece98..671787ff327 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderView.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderView.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/addplayerdialog.cpp b/Generals/Code/Tools/WorldBuilder/src/addplayerdialog.cpp
index 7372b0d42e4..f1ca63b41b6 100644
--- a/Generals/Code/Tools/WorldBuilder/src/addplayerdialog.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/addplayerdialog.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/brushoptions.cpp b/Generals/Code/Tools/WorldBuilder/src/brushoptions.cpp
index 98bdca3e072..bcbb966fa22 100644
--- a/Generals/Code/Tools/WorldBuilder/src/brushoptions.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/brushoptions.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/mapobjectprops.cpp b/Generals/Code/Tools/WorldBuilder/src/mapobjectprops.cpp
index 0e8ff0f3185..deb3bb4da35 100644
--- a/Generals/Code/Tools/WorldBuilder/src/mapobjectprops.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/mapobjectprops.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -31,6 +31,7 @@
#include "Common/ThingTemplate.h"
#include "Common/UnicodeString.h"
#include "Common/WellKnownKeys.h"
+#include "Common/AudioEventInfo.h"
#include "GameLogic/Module/UpgradeModule.h"
#include "GameLogic/Module/GenerateMinefieldBehavior.h"
@@ -39,6 +40,7 @@ const char* NEUTRAL_TEAM_UI_STR = "(neutral)";
const char* NEUTRAL_TEAM_INTERNAL_STR = "team";
+
/////////////////////////////////////////////////////////////////////////////
// MapObjectProps dialog
@@ -51,21 +53,39 @@ void MapObjectProps::makeMain()
TheMapObjectProps = this;
}
+
MapObjectProps::MapObjectProps(Dict* dictToEdit, const char* title, CWnd* pParent /*=nullptr*/) :
COptionsPanel(MapObjectProps::IDD, pParent),
m_dictToEdit(dictToEdit),
m_title(title),
- m_selectedObject(nullptr)
+ m_selectedObject(nullptr),
+ m_dictSource(nullptr),
+ m_scale( 1.0f ),
+ m_height( 0 ),
+ m_posUndoable( nullptr ),
+ m_angle( 0 ),
+ m_defaultEntryIndex(0),
+ m_defaultIsNone(true)
{
- //{{AFX_DATA_INIT(MapObjectProps)
+
+
+ //{{AFX_DATA_INIT(MapObjectProps)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
MapObjectProps::~MapObjectProps()
{
- if (TheMapObjectProps == this)
+ if (TheMapObjectProps == this)
TheMapObjectProps = nullptr;
+
+ if ( m_posUndoable != nullptr )
+ {
+ REF_PTR_RELEASE( m_posUndoable );
+ }
+
+ if ( m_hWnd )
+ DestroyWindow();
}
void MapObjectProps::DoDataExchange(CDataExchange* pDX)
@@ -79,73 +99,85 @@ void MapObjectProps::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(MapObjectProps, CDialog)
//{{AFX_MSG_MAP(MapObjectProps)
- ON_LBN_SELCHANGE(IDC_PROPERTIES, OnSelchangeProperties)
+ ON_BN_CLICKED(IDC_CUSTOMIZE_CHECKBOX, customizeToDict)
ON_BN_CLICKED(IDC_EDITPROP, OnEditprop)
- ON_BN_CLICKED(IDC_NEWPROP, OnNewprop)
- ON_BN_CLICKED(IDC_REMOVEPROP, OnRemoveprop)
- ON_LBN_DBLCLK(IDC_PROPERTIES, OnDblclkProperties)
- ON_CBN_SELCHANGE(IDC_MAPOBJECT_Team, _TeamToDict)
- ON_EN_KILLFOCUS(IDC_MAPOBJECT_Name, _NameToDict)
- ON_CBN_SELCHANGE(IDC_MAPOBJECT_StartingHealth, _HealthToDict)
- ON_CBN_SELENDOK(IDC_MAPOBJECT_HitPoints, _HPsToDict)
- ON_CBN_KILLFOCUS(IDC_MAPOBJECT_HitPoints, _HPsToDict)
+ ON_BN_CLICKED(IDC_ENABLED_CHECKBOX, enabledToDict)
+ ON_BN_CLICKED(IDC_LOOPING_CHECKBOX, loopingToDict)
ON_BN_CLICKED(IDC_MAPOBJECT_Enabled, _EnabledToDict)
- ON_CBN_SELCHANGE(IDC_MAPOBJECT_Script, _ScriptToDict)
ON_BN_CLICKED(IDC_MAPOBJECT_Indestructible, _IndestructibleToDict)
- ON_BN_CLICKED(IDC_MAPOBJECT_Unsellable, _UnsellableToDict)
- ON_BN_CLICKED(IDC_MAPOBJECT_Targetable, _TargetableToDict)
ON_BN_CLICKED(IDC_MAPOBJECT_Powered, _PoweredToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_RecruitableAI, _RecruitableAIToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Selectable, _SelectableToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Targetable, _TargetableToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_Unsellable, _UnsellableToDict)
+ ON_BN_CLICKED(IDC_NEWPROP, OnNewprop)
+ ON_BN_CLICKED(IDC_REMOVEPROP, OnRemoveprop)
+ ON_BN_CLICKED(IDC_SCALE_OFF, OnScaleOff)
+ ON_BN_CLICKED(IDC_SCALE_ON, OnScaleOn)
+ ON_CBN_KILLFOCUS(IDC_MAPOBJECT_HitPoints, _HPsToDict)
ON_CBN_SELCHANGE(IDC_MAPOBJECT_Aggressiveness, _AggressivenessToDict)
- ON_EN_KILLFOCUS(IDC_MAPOBJECT_VisionDistance, _VisibilityToDict)
- ON_EN_KILLFOCUS(IDC_MAPOBJECT_ShroudClearingDistance, _ShroudClearingDistanceToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Script, _ScriptToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_StartingHealth, _HealthToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Team, _TeamToDict)
+ ON_CBN_SELCHANGE(IDC_MAPOBJECT_Time, _TimeToDict)
ON_CBN_SELCHANGE(IDC_MAPOBJECT_Veterancy, _VeterancyToDict)
- ON_BN_CLICKED(IDC_MAPOBJECT_RecruitableAI, _RecruitableAIToDict)
- ON_BN_CLICKED(IDC_MAPOBJECT_Selectable, _SelectableToDict)
ON_CBN_SELCHANGE(IDC_MAPOBJECT_Weather, _WeatherToDict)
- ON_CBN_SELCHANGE(IDC_MAPOBJECT_Time, _TimeToDict)
- ON_EN_KILLFOCUS(IDC_MAPOBJECT_ZOffset, SetZOffset)
+ ON_CBN_SELCHANGE(IDC_PRIORITY_COMBO, priorityToDict)
+ ON_CBN_SELCHANGE(IDC_SOUND_COMBO, attachedSoundToDict)
+ ON_CBN_SELENDOK(IDC_MAPOBJECT_HitPoints, _HPsToDict)
+ ON_EN_KILLFOCUS(IDC_LOOPCOUNT_EDIT, loopCountToDict)
ON_EN_KILLFOCUS(IDC_MAPOBJECT_Angle, SetAngle)
- ON_EN_KILLFOCUS(IDC_MAPOBJECT_StoppingDistance, _StoppingDistanceToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_Name, _NameToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_Scale, _ScaleToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_ShroudClearingDistance, _ShroudClearingDistanceToDict)
ON_EN_KILLFOCUS(IDC_MAPOBJECT_StartingHealthEdit, _HealthToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_StoppingDistance, _StoppingDistanceToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_VisionDistance, _VisibilityToDict)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_XYPosition, OnKillfocusMAPOBJECTXYPosition)
+ ON_EN_KILLFOCUS(IDC_MAPOBJECT_ZOffset, SetZOffset)
+ ON_EN_KILLFOCUS(IDC_MAX_RANGE_EDIT, maxRangeToDict)
+ ON_EN_KILLFOCUS(IDC_MIN_RANGE_EDIT, minRangeToDict)
+ ON_EN_KILLFOCUS(IDC_MIN_VOLUME_EDIT, minVolumeToDict)
+ ON_EN_KILLFOCUS(IDC_VOLUME_EDIT, volumeToDict)
+ ON_LBN_DBLCLK(IDC_PROPERTIES, OnDblclkProperties)
ON_LBN_SELCHANGE(IDC_MAPOBJECT_BuildWithUpgrades, _PrebuiltUpgradesToDict)
+ ON_LBN_SELCHANGE(IDC_PROPERTIES, OnSelchangeProperties)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
-/////////////////////////////////////////////////////////////////////////////
-// MapObjectProps message handlers
static AsciiString getNthKeyStr(const Dict* d, int i)
{
- NameKeyType k = d->getNthKey(i);
- AsciiString kstr = TheNameKeyGenerator->keyToName(k);
- return kstr;
+ NameKeyType k = d->getNthKey(i);
+ AsciiString kstr = TheNameKeyGenerator->keyToName(k);
+ return kstr;
}
static AsciiString getNthValueStr(const Dict* d, int i, Bool* enquote)
{
- *enquote = false;
- AsciiString vstr;
- switch(d->getNthType(i))
- {
+ *enquote = false;
+ AsciiString vstr;
+ switch(d->getNthType(i))
+ {
case Dict::DICT_BOOL:
- vstr.format("%s", d->getNthBool(i) ? "true" : "false");
- break;
- case Dict::DICT_INT:
- vstr.format("%d", d->getNthInt(i), d->getNthInt(i));
- break;
- case Dict::DICT_REAL:
- vstr.format("%f", d->getNthReal(i));
- break;
- case Dict::DICT_ASCIISTRING:
- vstr.format("%s", d->getNthAsciiString(i).str());
- *enquote = true;
- break;
- case Dict::DICT_UNICODESTRING:
- vstr.format("%ls", d->getNthUnicodeString(i).str());
- *enquote = true;
- break;
- }
- return vstr;
+ vstr.format("%s", d->getNthBool(i) ? "true" : "false");
+ break;
+ case Dict::DICT_INT:
+ vstr.format("%d", d->getNthInt(i), d->getNthInt(i));
+ break;
+ case Dict::DICT_REAL:
+ vstr.format("%f", d->getNthReal(i));
+ break;
+ case Dict::DICT_ASCIISTRING:
+ vstr.format("%s", d->getNthAsciiString(i).str());
+ *enquote = true;
+ break;
+ case Dict::DICT_UNICODESTRING:
+ vstr.format("%ls", d->getNthUnicodeString(i).str());
+ *enquote = true;
+ break;
+ }
+ return vstr;
}
int MapObjectProps::getSel()
@@ -157,257 +189,688 @@ int MapObjectProps::getSel()
// return sel;
}
-void MapObjectProps::enableButtons()
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToTeam()
{
- // do nothing
+ int i;
+
+ AsciiString name;
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Team);
+ owner->ResetContent();
+ for (i = 0; i < TheSidesList->getNumTeams(); i++)
+ {
+ name = TheSidesList->getTeamInfo(i)->getDict()->getAsciiString(TheKey_teamName);
+ if (name == NEUTRAL_TEAM_INTERNAL_STR)
+ name = NEUTRAL_TEAM_UI_STR;
+ owner->AddString(name.str());
+ }
+ // re-find, since the list is sorted
+ i = -1;
+ if (m_dictToEdit)
+ {
+ name = m_dictToEdit->getAsciiString(TheKey_originalOwner);
+ if (name == NEUTRAL_TEAM_INTERNAL_STR)
+ name = NEUTRAL_TEAM_UI_STR;
+ i = owner->FindStringExact(-1, name.str());
+ DEBUG_ASSERTLOG(i >= 0, ("missing team '%s'. Non-fatal (jkmcd)", name.str()));
+
+ }
+ owner->SetCurSel(i);
}
-void MapObjectProps::OnSelchangeProperties()
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToName()
{
+ AsciiString name;
+ Bool exists;
+ if (m_dictToEdit)
+ {
+ name = m_dictToEdit->getAsciiString(TheKey_objectName, &exists);
+ }
+ CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_Name);
+ if (pItem)
+ {
+ pItem->SetWindowText(name.str());
+ }
}
-BOOL MapObjectProps::OnInitDialog()
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToScript()
{
- CDialog::OnInitDialog();
-
- if (m_title)
- SetWindowText(m_title);
+ if (!m_dictToEdit)
+ {
+ return;
+ }
- m_heightSlider.SetupPopSliderButton(this, IDC_HEIGHT_POPUP, this);
- m_angleSlider.SetupPopSliderButton(this, IDC_ANGLE_POPUP, this);
- m_posUndoable = nullptr;
- m_angle = 0;
- m_height = 0;
-
- updateTheUI();
+ Bool exists;
+ CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Script);
+ // Load the subroutine scripts into the combo box.
+ EditParameter::loadScripts(pCombo, true);
+ /*Int stringNdx =*/ pCombo->AddString("");
+ AsciiString script = m_dictToEdit->getAsciiString(TheKey_objectScriptAttachment, &exists);
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
+ if (script.isEmpty()) {
+ pCombo->SelectString(-1, "");
+ } else {
+ pCombo->SelectString(-1, script.str());
+ }
}
-/*static*/ void MapObjectProps::update()
+/// Move data from dialog controls to object
+void MapObjectProps::_TeamToDict()
{
- if (TheMapObjectProps)
- {
- TheMapObjectProps->updateTheUI();
- }
+ getAllSelectedDicts();
+
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Team);
+ static char buf[1024];
+ owner->GetWindowText(buf, sizeof(buf)-2);
+ if (strcmp(buf, NEUTRAL_TEAM_UI_STR)==0)
+ strlcpy(buf, NEUTRAL_TEAM_INTERNAL_STR, ARRAY_SIZE(buf));
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ Dict newDict;
+ newDict.setAsciiString(TheKey_originalOwner, AsciiString(buf));
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
}
-void MapObjectProps::updateTheUI()
+/// Move data from dialog controls to object
+void MapObjectProps::_NameToDict()
{
- if (this != TheMapObjectProps) {
- return;
- }
-
- for (MapObject *pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
- if (!pMapObj->isSelected() || pMapObj->isWaypoint() || pMapObj->isLight()) {
- continue;
- }
+ getAllSelectedDicts();
- m_dictToEdit = pMapObj ? pMapObj->getProperties() : nullptr;
-
- _DictToTeam();
- _DictToName();
- _DictToHealth();
- _DictToHPs();
- _DictToEnabled();
- _DictToScript();
- _DictToDestructible();
- _DictToPowered();
- _DictToAggressiveness();
- _DictToVisibilityRange();
- _DictToVeterancy();
- _DictToWeather();
- _DictToTime();
- _DictToShroudClearingDistance();
- _DictToRecruitableAI();
- _DictToSelectable();
- _DictToStoppingDistance();
- _DictToPrebuiltUpgrades();
- _DictToUnsellable();
- _DictToTargetable();
- ShowZOffset(pMapObj);
- ShowAngle(pMapObj);
+ CWnd *owner = GetDlgItem(IDC_MAPOBJECT_Name);
+ CString cstr;
+ owner->GetWindowText(cstr);
- // simply break after the first one that's selected
- break;
- }
+ // Note: when starting up, this is called before a document exists. Just ignore such
+ // calls, since there can't be an object to affect.
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ Dict newDict;
+ newDict.setAsciiString(TheKey_objectName, cstr.GetBuffer(0));
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
}
-/*static*/ MapObject *MapObjectProps::getSingleSelectedMapObject()
+/// Move data from dialog controls to object
+void MapObjectProps::_ScriptToDict()
{
- MapObject *pMapObj;
- MapObject *theMapObj = nullptr;
-// Bool found = false;
- Int selCount=0;
- for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
- if (pMapObj->isSelected()) {
- if (!pMapObj->isWaypoint() && !pMapObj->isLight())
- {
- theMapObj = pMapObj;
- }
- selCount++;
- }
- }
- if (selCount==1 && theMapObj) {
- return theMapObj;
- }
- return(nullptr);
+ getAllSelectedDicts();
+
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Script);
+ static char buf[1024];
+ owner->GetWindowText(buf, sizeof(buf)-2);
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ Dict newDict;
+ newDict.setAsciiString(TheKey_objectScriptAttachment, AsciiString(buf));
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToScale()
+{
+// Currently not in the Mission Disk.
+#if 0
+ m_scale = 1;
+ Bool exists;
+ if (m_dictToEdit) {
+ m_scale = m_dictToEdit->getReal(TheKey_objectPrototypeScale, &exists);
+ }
+ if (!exists) {
+ m_scale = 1;
+ }
+
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Scale);
+ CString cstr;
+ cstr.Format("%.2f", m_scale);
+ edit->SetWindowText(cstr);
+
+ CButton *off = (CButton*) GetDlgItem(IDC_SCALE_OFF);
+ CButton *on = (CButton*) GetDlgItem(IDC_SCALE_ON);
+ if (!exists) {
+ off->SetCheck(1);
+ on->SetCheck(0);
+ edit->EnableWindow(false);
+ GetDlgItem(IDC_SCALE_POPUP)->EnableWindow(false);
+ } else {
+ off->SetCheck(0);
+ on->SetCheck(1);
+ edit->EnableWindow(TRUE);
+ GetDlgItem(IDC_SCALE_POPUP)->EnableWindow(true);
+ }
+#endif
+
}
-void MapObjectProps::OnEditprop()
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToWeather()
{
- int sel = getSel();
- if (sel == -1 || !m_dictToEdit)
- return;
+ Int value = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_objectWeather, &exists);
+ if (!exists)
+ value = 0;
+ }
- Bool enquote;
- AsciiString kstr = getNthKeyStr(m_dictToEdit, sel);
- AsciiString vstr = getNthValueStr(m_dictToEdit, sel, &enquote);
- Dict::DataType type = m_dictToEdit->getNthType(sel);
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Weather);
+ pItem->SetCurSel(value);
+}
- PropEdit propDlg(&kstr, &type, &vstr, true, this);
- if (propDlg.DoModal() == IDOK)
- {
- Dict newDict = DictItemUndoable::buildSingleItemDict(kstr, type, vstr);
- if (this == TheMapObjectProps)
- {
- // it's the floating panel; use an undoable
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, newDict.getNthKey(0));
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- }
- else
- {
- // we're running modal; just slam it in the dict
- m_dictToEdit->copyPairFrom(newDict, newDict.getNthKey(0));
- }
- updateTheUI();
- }
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToTime()
+{
+ Int value = 0;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_objectTime, &exists);
+ if (!exists)
+ value = 0;
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Time);
+ pItem->SetCurSel(value);
}
-void MapObjectProps::OnNewprop()
+/// Move data from dialog controls to object
+void MapObjectProps::_WeatherToDict()
{
- if (!m_dictToEdit)
- return;
+ getAllSelectedDicts();
- // TODO: Add your control notification handler code here
- static Dict::DataType lastNewType = Dict::DICT_BOOL;
- AsciiString key, value;
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Weather);
+ static char buf[1024];
+ int curSel = owner->GetCurSel();
- PropEdit propDlg(&key, &lastNewType, &value, false, this);
- if (propDlg.DoModal() == IDOK)
- {
- Dict newDict = DictItemUndoable::buildSingleItemDict(key, lastNewType, value);
- if (this == TheMapObjectProps)
- {
- // it's the floating panel; use an undoable
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, newDict.getNthKey(0));
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- }
- else
- {
- // we're running modal; just slam it in the dict
- m_dictToEdit->copyPairFrom(newDict, newDict.getNthKey(0));
- }
- updateTheUI();
- }
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ Dict newDict;
+ newDict.setInt(TheKey_objectWeather, curSel);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
}
-void MapObjectProps::OnRemoveprop()
+/// Move data from dialog controls to object
+void MapObjectProps::_TimeToDict()
{
- int sel = getSel();
- if (sel == -1)
- return;
-
- NameKeyType k = m_dictToEdit->getNthKey(sel);
- if (this == TheMapObjectProps)
- {
- // it's the floating panel; use an undoable
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict; // empty dict
- DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, k);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- }
- else
- {
- // we're running modal; just slam it in the dict
- m_dictToEdit->remove(k);
- }
- updateTheUI();
+ getAllSelectedDicts();
+
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Time);
+ static char buf[1024];
+ int curSel = owner->GetCurSel();
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ Dict newDict;
+ newDict.setInt(TheKey_objectTime, curSel);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_ScaleToDict()
+{
+// Currently not in mission disk.
+#if 0
+ getAllSelectedDicts();
+
+ Real value = 0.0f;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Scale);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ value = atof(cstr);
+ }
+ m_scale = value;
+
+ CButton *off = (CButton*) GetDlgItem(IDC_SCALE_OFF);
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ Dict newDict;
+ if (off->GetCheck() == 1) {
+ newDict.remove(TheKey_objectPrototypeScale);
+ } else {
+ newDict.setReal(TheKey_objectPrototypeScale, m_scale);
+ }
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+#endif
}
-void MapObjectProps::OnDblclkProperties()
+/// Move data from object to dialog controls
+void MapObjectProps::ShowZOffset(MapObject *pMapObj)
{
- OnEditprop();
+ const Coord3D *loc = pMapObj->getLocation();
+ static char buff[32];
+ m_height = loc->z;
+ snprintf(buff, ARRAY_SIZE(buff), "%0.2f", loc->z);
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
+ edit->SetWindowText(buff);
}
-void MapObjectProps::_DictToTeam()
+/// Move data from dialog controls to object
+void MapObjectProps::SetZOffset()
+{
+ Real value = 0.0f;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ value = atof(cstr);
+ }
+ m_height = value;
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ ModifyObjectUndoable *pUndo = new ModifyObjectUndoable(pDoc);
+ pDoc->AddAndDoUndoable(pUndo);
+ pUndo->SetZOffset(value);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::ShowAngle(MapObject *pMapObj)
{
- int i;
+ m_angle = pMapObj->getAngle() * 180 / PI;
+ static char buff[32];
+ snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_angle);
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Angle);
+ edit->SetWindowText(buff);
+ m_angle = atof(buff);
+}
- AsciiString name;
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Team);
- owner->ResetContent();
- for (i = 0; i < TheSidesList->getNumTeams(); i++)
- {
- name = TheSidesList->getTeamInfo(i)->getDict()->getAsciiString(TheKey_teamName);
- if (name == NEUTRAL_TEAM_INTERNAL_STR)
- name = NEUTRAL_TEAM_UI_STR;
- owner->AddString(name.str());
- }
- // re-find, since the list is sorted
- i = -1;
- if (m_dictToEdit)
- {
- name = m_dictToEdit->getAsciiString(TheKey_originalOwner);
- if (name == NEUTRAL_TEAM_INTERNAL_STR)
- name = NEUTRAL_TEAM_UI_STR;
- i = owner->FindStringExact(-1, name.str());
- DEBUG_ASSERTLOG(i >= 0, ("missing team '%s'. Non-fatal (jkmcd)", name.str()));
- }
- owner->SetCurSel(i);
+/// Move data from object to dialog controls
+void MapObjectProps::ShowPosition(MapObject *pMapObj)
+{
+ m_position = *pMapObj->getLocation();
+ static char buff[64];
+ snprintf(buff, ARRAY_SIZE(buff), "%0.2f, %0.2f", m_position.x, m_position.y);
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_XYPosition);
+ edit->SetWindowText(buff);
+ sscanf(buff, "%f,%f", &m_position.x, &m_position.y);
}
-void MapObjectProps::_DictToName()
+/// Move data from dialog controls to object
+void MapObjectProps::SetAngle()
{
- AsciiString name;
- Bool exists;
- if (m_dictToEdit) {
- name = m_dictToEdit->getAsciiString(TheKey_objectName, &exists);
- }
+ Real angle = m_angle;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Angle);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ angle = atof(cstr);
+ }
+ if (m_selectedObject==nullptr) return;
+ if (m_angle!=angle)
+ {
+ m_angle = angle;
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ ModifyObjectUndoable *pUndo = new ModifyObjectUndoable(pDoc);
+ pDoc->AddAndDoUndoable(pUndo);
+ pUndo->RotateTo(angle * PI/180);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::SetPosition()
+{
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_XYPosition);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ Coord3D loc;
+ loc = m_position;
+ if (m_selectedObject==nullptr) return;
+ if (!cstr.IsEmpty()) {
+ if (sscanf(cstr, "%f, %f", &loc.x, &loc.y)!=2)
+ loc = m_position;
+ }
+ if (loc.x!=m_position.x || loc.y != m_position.y) {
+ m_position = loc;
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc )
+ {
+ ModifyObjectUndoable *pUndo = new ModifyObjectUndoable(pDoc);
+ pDoc->AddAndDoUndoable(pUndo);
+ if (m_selectedObject) {
+ loc = *m_selectedObject->getLocation();
+ }
+ pUndo->SetOffset(m_position.x-loc.x, m_position.y-loc.y);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+ }
+}
+
+/// Slider control
+void MapObjectProps::GetPopSliderInfo(const long sliderID, long *pMin, long *pMax, long *pLineSize, long *pInitial)
+{
+ switch (sliderID) {
- CWnd* pItem = GetDlgItem(IDC_MAPOBJECT_Name);
- if (pItem) {
- pItem->SetWindowText(name.str());
+ case IDC_HEIGHT_POPUP:
+ *pMin = -50;
+ *pMax = 50;
+ *pInitial = m_height;
+ *pLineSize = 1;
+ break;
+
+ case IDC_ANGLE_POPUP:
+ *pMin = 0;
+ *pMax = 360;
+ *pInitial = m_angle;
+ *pLineSize = 1;
+ break;
+
+ case IDC_SCALE_POPUP:
+ *pMin = 1;
+ *pMax = 500;
+ *pInitial = m_scale*100;
+ *pLineSize = 1;
+ break;
+
+ default:
+ // uh-oh!
+ DEBUG_CRASH(("Slider message from unknown control"));
+ break;
}
}
-void MapObjectProps::_DictToHealth()
+/// Slider control
+void MapObjectProps::PopSliderChanged(const long sliderID, long theVal)
{
- Int value = 100;
- Bool exists;
- if (m_dictToEdit) {
- value = m_dictToEdit->getInt(TheKey_objectInitialHealth, &exists);
- }
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc == nullptr )
+ return;
- CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_StartingHealth);
- CWnd* pItem2 = GetDlgItem(IDC_MAPOBJECT_StartingHealthEdit);
- if (pItem && pItem2) {
- if (value == 0) {
- pItem->SelectString(-1, "0%");
- pItem2->SetWindowText("");
- pItem2->EnableWindow(FALSE);
- } else if (value == 25) {
- pItem->SelectString(-1, "25%");
- pItem2->SetWindowText("");
- pItem2->EnableWindow(FALSE);
- } else if (value == 50) {
+ CWnd* edit;
+ static char buff[32];
+ switch (sliderID) {
+ case IDC_HEIGHT_POPUP:
+ if (!m_posUndoable) {
+ m_posUndoable = new ModifyObjectUndoable(pDoc);
+ pDoc->AddAndDoUndoable(m_posUndoable);
+ }
+ m_posUndoable->SetZOffset(theVal);
+ m_height = theVal;
+ snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_height);
+ edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
+ edit->SetWindowText(buff);
+ break;
+
+ case IDC_ANGLE_POPUP:
+ if (!m_posUndoable) {
+ m_posUndoable = new ModifyObjectUndoable(pDoc);
+ pDoc->AddAndDoUndoable(m_posUndoable);
+ }
+ m_posUndoable->RotateTo(theVal * PI/180);
+ m_angle = theVal;
+ snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_angle);
+ edit = GetDlgItem(IDC_MAPOBJECT_Angle);
+ edit->SetWindowText(buff);
+ break;
+
+ case IDC_SCALE_POPUP:
+ m_scale = theVal/100.0f;
+ snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_scale);
+ edit = GetDlgItem(IDC_MAPOBJECT_Scale);
+ edit->SetWindowText(buff);
+ break;
+
+ default:
+ // uh-oh!
+ DEBUG_CRASH(("Slider message from unknown control"));
+ break;
+ }
+}
+
+/// Slider control
+void MapObjectProps::PopSliderFinished(const long sliderID, long theVal)
+{
+ switch (sliderID) {
+ case IDC_HEIGHT_POPUP:
+ case IDC_ANGLE_POPUP:
+ if ( m_posUndoable != nullptr )
+ {
+ REF_PTR_RELEASE(m_posUndoable); // belongs to pDoc now.
+ }
+ m_posUndoable = nullptr;
+ break;
+
+ case IDC_SCALE_POPUP:
+ _ScaleToDict();
+ break;
+
+ default:
+ // uh-oh!
+ DEBUG_CRASH(("Slider message from unknown control"));
+ break;
+ }
+
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_PrebuiltUpgradesToDict()
+{
+ getAllSelectedDicts();
+
+ CListBox *pBox = (CListBox *) GetDlgItem(IDC_MAPOBJECT_BuildWithUpgrades);
+ if (!pBox) {
+ return;
+ }
+
+ // We only work for single selections
+ if (m_allSelectedDicts.size() != 1) {
+ return;
+ }
+
+ if (m_selectedObject) {
+ if ( !m_selectedObject->getThingTemplate() ) {
+ return;
+ }
+ }
+
+ Bool exists;
+ int upgradeNum = 0;
+ AsciiString upgradeString;
+
+ // We're going to sub this entire dict for the existing entire dict.
+ Dict newDict = *m_allSelectedDicts[0];
+
+ // First, clear out any existing notions of what we should upgrade.
+ do {
+ AsciiString keyName;
+ keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
+ upgradeString = newDict.getAsciiString(NAMEKEY(keyName), &exists);
+
+ if (exists) {
+ newDict.remove(NAMEKEY(keyName));
+ }
+
+ ++upgradeNum;
+ } while (!upgradeString.isEmpty());
+
+ upgradeNum = 0;
+ // We've now removed them, so lets add the ones that are selected now.
+ Int countOfItems = pBox->GetCount();
+ for (Int i = 0; i < countOfItems; ++i) {
+ if (pBox->GetSel(i) > 0) {
+ CString selTxt;
+ // This thing is selected. Get its text, and add it to the dict.
+ pBox->GetText(i, selTxt);
+
+ AsciiString keyName;
+ keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
+ newDict.setAsciiString(NAMEKEY(keyName), AsciiString(selTxt.GetBuffer(0)));
+ ++upgradeNum;
+ }
+ }
+
+ // Now, do the Undoable
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, NAMEKEY_INVALID, m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToPrebuiltUpgrades()
+{
+ getAllSelectedDicts();
+
+ CListBox *pBox = (CListBox*) GetDlgItem(IDC_MAPOBJECT_BuildWithUpgrades);
+ if (!pBox) {
+ return;
+ }
+
+ // First, clear out the list
+ pBox->ResetContent();
+ CString cstr;
+
+ // Then, if there's multiple units selected, add the Single Selection Only string
+ if (m_allSelectedDicts.size() > 1) {
+ cstr.LoadString(IDS_SINGLE_SELECTION_ONLY);
+ pBox->AddString(cstr);
+ return;
+ }
+
+ if (m_selectedObject == nullptr) {
+ return;
+ }
+
+ // Otherwise, fill it with the upgrades available for this unit
+ const ThingTemplate *tt = m_selectedObject->getThingTemplate();
+ if (tt == nullptr) {
+ // This is valid. For instance, Scorch marks do not have thing templates.
+ return;
+ }
+
+ Bool noUpgrades = false;
+
+ // Now do any behaviors that are also upgrades.
+ const ModuleInfo& mi = tt->getBehaviorModuleInfo();
+ if (mi.getCount() == 0) {
+ if (noUpgrades) {
+ cstr.LoadString(IDS_NO_UPGRADES);
+ pBox->AddString(cstr);
+ return;
+ }
+ } else {
+ Int numBehaviorModules = mi.getCount();
+
+ Int numBehaviorsWithUpgrades = 0;
+
+ for (int i = 0; i < numBehaviorModules; ++i) {
+ if (mi.getNthName(i).compareNoCase("GenerateMinefieldBehavior") == 0) {
+ const GenerateMinefieldBehaviorModuleData *gmbmd = (const GenerateMinefieldBehaviorModuleData *)mi.getNthData(i);
+ if (!gmbmd) {
+ continue;
+ }
+ if (!gmbmd->m_upgradeMuxData.m_activationUpgradeNames.empty()) {
+ cstr = gmbmd->m_upgradeMuxData.m_activationUpgradeNames[0].str();
+ if (pBox->FindString(-1, cstr) == LB_ERR) {
+ pBox->AddString(cstr);
+ ++numBehaviorsWithUpgrades;
+ }
+ }
+ }
+ }
+
+ if (numBehaviorsWithUpgrades == 0) {
+ if (noUpgrades) {
+ cstr.LoadString(IDS_NO_UPGRADES);
+ pBox->AddString(cstr);
+ return;
+ }
+ }
+ }
+
+ // Finally, walk through the upgrades that he already has, and select the appropriate members
+ // from the list
+
+ Bool exists;
+ int upgradeNum = 0;
+ AsciiString upgradeString;
+
+ do {
+ AsciiString keyName;
+ keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
+ upgradeString = m_dictToEdit->getAsciiString(NAMEKEY(keyName), &exists);
+
+ if (exists) {
+ Int selNdx = pBox->FindStringExact(-1, upgradeString.str());
+ if (selNdx == LB_ERR) {
+ DEBUG_CRASH(("Object claims '%s', but it wasn't found in the list of possible upgrades.", upgradeString.str()));
+ ++upgradeNum;
+ continue;
+ }
+ pBox->SetSel(selNdx);
+
+ } else {
+ upgradeString.clear();
+ }
+
+ ++upgradeNum;
+ } while (!upgradeString.isEmpty());
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::_DictToHealth()
+{
+ Int value = 100;
+ Bool exists;
+ if (m_dictToEdit) {
+ value = m_dictToEdit->getInt(TheKey_objectInitialHealth, &exists);
+ }
+
+ CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_StartingHealth);
+ CWnd* pItem2 = GetDlgItem(IDC_MAPOBJECT_StartingHealthEdit);
+ if (pItem && pItem2) {
+ if (value == 0) {
+ pItem->SelectString(-1, "0%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else if (value == 25) {
+ pItem->SelectString(-1, "25%");
+ pItem2->SetWindowText("");
+ pItem2->EnableWindow(FALSE);
+ } else if (value == 50) {
pItem->SelectString(-1, "50%");
pItem2->SetWindowText("");
pItem2->EnableWindow(FALSE);
@@ -429,6 +892,8 @@ void MapObjectProps::_DictToHealth()
}
}
+
+/// Move data from object to dialog controls
void MapObjectProps::_DictToHPs()
{
Int value = -1;
@@ -454,6 +919,7 @@ void MapObjectProps::_DictToHPs()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToEnabled()
{
Bool enabled = true;
@@ -468,26 +934,8 @@ void MapObjectProps::_DictToEnabled()
}
}
-void MapObjectProps::_DictToScript()
-{
- if (!m_dictToEdit) {
- return;
- }
-
- Bool exists;
- CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Script);
- // Load the subroutine scripts into the combo box.
- EditParameter::loadScripts(pCombo, true);
- /*Int stringNdx =*/ pCombo->AddString("");
- AsciiString script = m_dictToEdit->getAsciiString(TheKey_objectScriptAttachment, &exists);
-
- if (script.isEmpty()) {
- pCombo->SelectString(-1, "");
- } else {
- pCombo->SelectString(-1, script.str());
- }
-}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToDestructible()
{
Bool destructible = true;
@@ -502,6 +950,7 @@ void MapObjectProps::_DictToDestructible()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToUnsellable()
{
Bool unsellable = false;
@@ -516,6 +965,7 @@ void MapObjectProps::_DictToUnsellable()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToTargetable()
{
Bool targetable = false;
@@ -532,6 +982,7 @@ void MapObjectProps::_DictToTargetable()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToPowered()
{
Bool powered = true;
@@ -547,6 +998,7 @@ void MapObjectProps::_DictToPowered()
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToAggressiveness()
{
Int value = 0;
@@ -571,6 +1023,7 @@ void MapObjectProps::_DictToAggressiveness()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToVisibilityRange()
{
Int distance = 0;
@@ -591,6 +1044,7 @@ void MapObjectProps::_DictToVisibilityRange()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToVeterancy()
{
Int value = 0;
@@ -605,34 +1059,7 @@ void MapObjectProps::_DictToVeterancy()
}
}
-void MapObjectProps::_DictToWeather()
-{
- Int value = 0;
- Bool exists;
- if (m_dictToEdit) {
- value = m_dictToEdit->getInt(TheKey_objectWeather, &exists);
- if (!exists)
- value = 0;
- }
-
- CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Weather);
- pItem->SetCurSel(value);
-}
-
-void MapObjectProps::_DictToTime()
-{
- Int value = 0;
- Bool exists;
- if (m_dictToEdit) {
- value = m_dictToEdit->getInt(TheKey_objectTime, &exists);
- if (!exists)
- value = 0;
- }
-
- CComboBox* pItem = (CComboBox*) GetDlgItem(IDC_MAPOBJECT_Time);
- pItem->SetCurSel(value);
-}
-
+/// Move data from object to dialog controls
void MapObjectProps::_DictToShroudClearingDistance()
{
Int distance = 0;
@@ -653,6 +1080,7 @@ void MapObjectProps::_DictToShroudClearingDistance()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToRecruitableAI()
{
Bool recruitableAI = true;
@@ -667,12 +1095,16 @@ void MapObjectProps::_DictToRecruitableAI()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToSelectable()
{
- Bool selectable = true;
- Bool exists;
+ Int selectable = true;
+ Bool exists=false;
if (m_dictToEdit) {
- selectable = m_dictToEdit->getBool(TheKey_objectSelectable, &exists);
+ selectable = m_dictToEdit->getBool(TheKey_objectSelectable, &exists);
+ }
+ if (!exists) {
+ selectable = 2;
}
CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
@@ -681,6 +1113,7 @@ void MapObjectProps::_DictToSelectable()
}
}
+/// Move data from object to dialog controls
void MapObjectProps::_DictToStoppingDistance()
{
Real stoppingDistance = 1.0f;
@@ -697,142 +1130,8 @@ void MapObjectProps::_DictToStoppingDistance()
}
}
-void MapObjectProps::_DictToPrebuiltUpgrades()
-{
- getAllSelectedDicts();
-
- CListBox *pBox = (CListBox*) GetDlgItem(IDC_MAPOBJECT_BuildWithUpgrades);
- if (!pBox) {
- return;
- }
-
- // First, clear out the list
- pBox->ResetContent();
- CString cstr;
-
- // Then, if there's multiple units selected, add the Single Selection Only string
- if (m_allSelectedDicts.size() > 1) {
- cstr.LoadString(IDS_SINGLE_SELECTION_ONLY);
- pBox->AddString(cstr);
- return;
- }
-
- if (m_selectedObject == nullptr) {
- return;
- }
-
- // Otherwise, fill it with the upgrades available for this unit
- const ThingTemplate *tt = m_selectedObject->getThingTemplate();
- if (tt == nullptr) {
- // This is valid. For instance, Scorch marks do not have thing templates.
- return;
- }
-
- Bool noUpgrades = false;
-
- // Now do any behaviors that are also upgrades.
- const ModuleInfo& mi = tt->getBehaviorModuleInfo();
- if (mi.getCount() == 0) {
- if (noUpgrades) {
- cstr.LoadString(IDS_NO_UPGRADES);
- pBox->AddString(cstr);
- return;
- }
- } else {
- Int numBehaviorModules = mi.getCount();
-
- Int numBehaviorsWithUpgrades = 0;
-
- for (int i = 0; i < numBehaviorModules; ++i) {
- if (mi.getNthName(i).compareNoCase("GenerateMinefieldBehavior") == 0) {
- const GenerateMinefieldBehaviorModuleData *gmbmd = (const GenerateMinefieldBehaviorModuleData *)mi.getNthData(i);
- if (!gmbmd) {
- continue;
- }
- if (!gmbmd->m_upgradeMuxData.m_activationUpgradeNames.empty()) {
- cstr = gmbmd->m_upgradeMuxData.m_activationUpgradeNames[0].str();
- if (pBox->FindString(-1, cstr) == LB_ERR) {
- pBox->AddString(cstr);
- ++numBehaviorsWithUpgrades;
- }
- }
- }
- }
-
- if (numBehaviorsWithUpgrades == 0) {
- if (noUpgrades) {
- cstr.LoadString(IDS_NO_UPGRADES);
- pBox->AddString(cstr);
- return;
- }
- }
- }
-
- // Finally, walk through the upgrades that he already has, and select the appropriate members
- // from the list
-
- Bool exists;
- int upgradeNum = 0;
- AsciiString upgradeString;
-
- do {
- AsciiString keyName;
- keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
- upgradeString = m_dictToEdit->getAsciiString(NAMEKEY(keyName), &exists);
-
- if (exists) {
- Int selNdx = pBox->FindStringExact(-1, upgradeString.str());
- if (selNdx == LB_ERR) {
- DEBUG_CRASH(("Object claims '%s', but it wasn't found in the list of possible upgrades.", upgradeString.str()));
- ++upgradeNum;
- continue;
- }
- pBox->SetSel(selNdx);
-
- } else {
- upgradeString.clear();
- }
-
- ++upgradeNum;
- } while (!upgradeString.isEmpty());
-}
-
-void MapObjectProps::_TeamToDict()
-{
- getAllSelectedDicts();
-
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Team);
- static char buf[1024];
- owner->GetWindowText(buf, sizeof(buf)-2);
- if (strcmp(buf, NEUTRAL_TEAM_UI_STR)==0)
- strcpy(buf, NEUTRAL_TEAM_INTERNAL_STR);
-
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setAsciiString(TheKey_originalOwner, AsciiString(buf));
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
-
-void MapObjectProps::_NameToDict()
-{
- getAllSelectedDicts();
-
- CWnd *owner = GetDlgItem(IDC_MAPOBJECT_Name);
- CString cstr;
- owner->GetWindowText(cstr);
-
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setAsciiString(TheKey_objectName, cstr.GetBuffer(0));
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
+/// Move data from dialog controls to object
void MapObjectProps::_HealthToDict()
{
getAllSelectedDicts();
@@ -863,456 +1162,1679 @@ void MapObjectProps::_HealthToDict()
value = atoi(cstr.GetBuffer(0));
}
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setInt(TheKey_objectInitialHealth, value);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setInt(TheKey_objectInitialHealth, value);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
}
-void MapObjectProps::_PrebuiltUpgradesToDict()
+
+/// Move data from dialog controls to object
+void MapObjectProps::_EnabledToDict()
{
getAllSelectedDicts();
- CListBox *pBox = (CListBox *) GetDlgItem(IDC_MAPOBJECT_BuildWithUpgrades);
- if (!pBox) {
- return;
- }
-
- // We only work for single selections
- if (m_allSelectedDicts.size() != 1) {
- return;
- }
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Enabled);
+ Bool isChecked = (owner->GetCheck() != 0);
- if (m_selectedObject) {
- if ( !m_selectedObject->getThingTemplate() ) {
- return;
- }
- }
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setBool(TheKey_objectEnabled, isChecked);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_IndestructibleToDict()
+{
+ getAllSelectedDicts();
- Bool exists;
- int upgradeNum = 0;
- AsciiString upgradeString;
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Indestructible);
+ Bool isChecked = (owner->GetCheck() != 0);
- // We're going to sub this entire dict for the existing entire dict.
- Dict newDict = *m_allSelectedDicts[0];
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setBool(TheKey_objectIndestructible, isChecked);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_UnsellableToDict()
+{
+ getAllSelectedDicts();
- // First, clear out any existing notions of what we should upgrade.
- do {
- AsciiString keyName;
- keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
- upgradeString = newDict.getAsciiString(NAMEKEY(keyName), &exists);
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Unsellable);
+ Bool isChecked = (owner->GetCheck() != 0);
- if (exists) {
- newDict.remove(NAMEKEY(keyName));
- }
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setBool(TheKey_objectUnsellable, isChecked);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_TargetableToDict()
+{
+ getAllSelectedDicts();
- ++upgradeNum;
- } while (!upgradeString.isEmpty());
-
- upgradeNum = 0;
- // We've now removed them, so lets add the ones that are selected now.
- Int countOfItems = pBox->GetCount();
- for (Int i = 0; i < countOfItems; ++i) {
- if (pBox->GetSel(i) > 0) {
- CString selTxt;
- // This thing is selected. Get its text, and add it to the dict.
- pBox->GetText(i, selTxt);
-
- AsciiString keyName;
- keyName.format("%s%d", TheNameKeyGenerator->keyToName(TheKey_objectGrantUpgrade).str(), upgradeNum);
- newDict.setAsciiString(NAMEKEY(keyName), AsciiString(selTxt.GetBuffer(0)));
- ++upgradeNum;
- }
- }
+ CButton *owner = (CButton*)GetDlgItem( IDC_MAPOBJECT_Targetable );
+ Bool isChecked = owner->GetCheck() != 0;
- // Now, do the Undoable
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, NAMEKEY_INVALID, m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setBool( TheKey_objectTargetable, isChecked );
+ DictItemUndoable *pUndo = new DictItemUndoable( getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size() );
+ pDoc->AddAndDoUndoable( pUndo );
+ REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
+ // Update is called by Do
+ }
}
-void MapObjectProps::_EnabledToDict()
+
+/// Move data from dialog controls to object
+void MapObjectProps::_PoweredToDict()
{
getAllSelectedDicts();
- CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Enabled);
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Powered);
Bool isChecked = (owner->GetCheck() != 0);
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool(TheKey_objectEnabled, isChecked);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
-
-void MapObjectProps::_ScriptToDict()
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setBool(TheKey_objectPowered, isChecked);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_AggressivenessToDict()
{
getAllSelectedDicts();
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Script);
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Aggressiveness);
static char buf[1024];
owner->GetWindowText(buf, sizeof(buf)-2);
+ int value = 0;
+
+ if (strcmp(buf, "Sleep") == 0) {
+ value = -2;
+ } else if (strcmp(buf, "Passive") == 0) {
+ value = -1;
+ } else if (strcmp(buf, "Normal") == 0) {
+ value = 0;
+ } else if (strcmp(buf, "Alert") == 0) {
+ value = 1;
+ } else if (strcmp(buf, "Aggressive") == 0) {
+ value = 2;
+ }
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setAsciiString(TheKey_objectScriptAttachment, AsciiString(buf));
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setInt(TheKey_objectAggressiveness, value);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_VisibilityToDict()
+{
+ getAllSelectedDicts();
-void MapObjectProps::_IndestructibleToDict()
+ int value = -1;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_VisionDistance);
+ edit->EnableWindow(TRUE);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ value = atoi(cstr.GetBuffer(0));
+ }
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ if (value != -1) {
+ newDict.setInt(TheKey_objectVisualRange, value);
+ }
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, TheKey_objectVisualRange, m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_VeterancyToDict()
{
getAllSelectedDicts();
- CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Indestructible);
- Bool isChecked = (owner->GetCheck() != 0);
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Veterancy);
+ static char buf[1024];
+ int curSel = owner->GetCurSel();
+ int value = 0;
+ if (curSel >= 0) {
+ value=curSel;
+ }
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool(TheKey_objectIndestructible, isChecked);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setInt(TheKey_objectVeterancy, value);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_ShroudClearingDistanceToDict()
+{
+ getAllSelectedDicts();
-void MapObjectProps::_UnsellableToDict()
+ int value = -1;
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ShroudClearingDistance);
+ edit->EnableWindow(TRUE);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (!cstr.IsEmpty()) {
+ value = atoi(cstr.GetBuffer(0));
+ }
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ if (value != -1) {
+ newDict.setInt(TheKey_objectShroudClearingDistance, value);
+ }
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, TheKey_objectShroudClearingDistance, m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_RecruitableAIToDict()
{
getAllSelectedDicts();
- CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Unsellable);
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
Bool isChecked = (owner->GetCheck() != 0);
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool(TheKey_objectUnsellable, isChecked);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setBool(TheKey_objectRecruitableAI, isChecked);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_SelectableToDict()
+{
+ getAllSelectedDicts();
+
+ CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
+ Bool isChecked = (owner->GetCheck() == 1);
+ Bool isTristate = (owner->GetCheck() == 2);
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ if (isTristate) {
+ newDict.remove(TheKey_objectSelectable);
+ } else {
+ newDict.setBool(TheKey_objectSelectable, isChecked);
+ }
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Do
+ }
+}
+
+/// Move data from dialog controls to object
+void MapObjectProps::_HPsToDict()
+{
+ getAllSelectedDicts();
+
+ Int value;
+ static char buf[1024];
+
+ CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_HitPoints);
+ owner->GetWindowText(buf, sizeof(buf)-2);
+ value = atoi(buf);
+ if (value == 0)
+ value = -1;
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setInt(TheKey_objectMaxHPs, value);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
}
-void MapObjectProps::_TargetableToDict()
+/// Move data from dialog controls to object
+void MapObjectProps::_StoppingDistanceToDict()
{
getAllSelectedDicts();
- CButton *owner = (CButton*)GetDlgItem( IDC_MAPOBJECT_Targetable );
- Bool isChecked = owner->GetCheck() != 0;
+ Real value;
+ static char buf[1024];
+
+ CWnd* edit = GetDlgItem(IDC_MAPOBJECT_StoppingDistance);
+ CString cstr;
+ edit->GetWindowText(cstr);
+ if (cstr.IsEmpty()) {
+ return;
+ }
+ value = atof(cstr.GetBuffer(0));
CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool( TheKey_objectTargetable, isChecked );
- DictItemUndoable *pUndo = new DictItemUndoable( getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size() );
- pDoc->AddAndDoUndoable( pUndo );
- REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
- // Update is called by Do
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+ newDict.setReal(TheKey_objectStoppingDistance, value);
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_PoweredToDict()
+void MapObjectProps::OnEditprop()
{
- getAllSelectedDicts();
+ int sel = getSel();
+ if (sel == -1 || !m_dictToEdit)
+ return;
+
+ Bool enquote;
+ AsciiString kstr = getNthKeyStr(m_dictToEdit, sel);
+ AsciiString vstr = getNthValueStr(m_dictToEdit, sel, &enquote);
+ Dict::DataType type = m_dictToEdit->getNthType(sel);
+
+ PropEdit propDlg(&kstr, &type, &vstr, true, this);
+ if (propDlg.DoModal() == IDOK)
+ {
+ Dict newDict = DictItemUndoable::buildSingleItemDict(kstr, type, vstr);
+ if (this == TheMapObjectProps)
+ {
+ // it's the floating panel; use an undoable
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, newDict.getNthKey(0));
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+ else
+ {
+ // we're running modal; just slam it in the dict
+ m_dictToEdit->copyPairFrom(newDict, newDict.getNthKey(0));
+ }
+ updateTheUI();
+ }
+}
+
+void MapObjectProps::OnNewprop()
+{
+ if (!m_dictToEdit)
+ return;
+
+ // TODO: Add your control notification handler code here
+ static Dict::DataType lastNewType = Dict::DICT_BOOL;
+ AsciiString key, value;
+
+ PropEdit propDlg(&key, &lastNewType, &value, false, this);
+ if (propDlg.DoModal() == IDOK)
+ {
+ Dict newDict = DictItemUndoable::buildSingleItemDict(key, lastNewType, value);
+ if (this == TheMapObjectProps)
+ {
+ // it's the floating panel; use an undoable
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, newDict.getNthKey(0));
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+ else
+ {
+ // we're running modal; just slam it in the dict
+ m_dictToEdit->copyPairFrom(newDict, newDict.getNthKey(0));
+ }
+ updateTheUI();
+ }
+}
+
+void MapObjectProps::OnRemoveprop()
+{
+ int sel = getSel();
+ if (sel == -1)
+ return;
+
+ NameKeyType k = m_dictToEdit->getNthKey(sel);
+ if (this == TheMapObjectProps)
+ {
+ // it's the floating panel; use an undoable
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ Dict newDict; // empty dict
+ DictItemUndoable *pUndo = new DictItemUndoable(&m_dictToEdit, newDict, k);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ }
+ else
+ {
+ // we're running modal; just slam it in the dict
+ m_dictToEdit->remove(k);
+ }
+ updateTheUI();
+}
+
+void MapObjectProps::OnDblclkProperties()
+{
+ OnEditprop();
+}
+
+
+static const Char NO_SOUND_STRING[] = "(None)";
+static const Char BASE_DEFAULT_STRING[] = "Default";
+
+void MapObjectProps::OnSelchangeProperties()
+{
+
+}
+
+/// Initialize dialog, especially drop down lists
+BOOL MapObjectProps::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ if (m_title)
+ SetWindowText(m_title);
+
+ m_heightSlider.SetupPopSliderButton(this, IDC_HEIGHT_POPUP, this);
+ m_angleSlider.SetupPopSliderButton(this, IDC_ANGLE_POPUP, this);
+ m_scaleSlider.SetupPopSliderButton(this, IDC_SCALE_POPUP, this);
+ m_posUndoable = nullptr;
+ m_angle = 0;
+ m_height = 0;
+ m_scale = 1.0f;
- CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Powered);
- Bool isChecked = (owner->GetCheck() != 0);
+ InitSound();
+ updateTheUI();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool(TheKey_objectPowered, isChecked);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ return TRUE;
+}
+//---------------------------------------------------------------------------------------------------
+/*static*/ void MapObjectProps::update()
+{
+ if (TheMapObjectProps)
+ {
+ TheMapObjectProps->updateTheUI();
+ }
}
-void MapObjectProps::_AggressivenessToDict()
+void MapObjectProps::updateTheUI()
{
- getAllSelectedDicts();
+ if (this != TheMapObjectProps) {
+ return;
+ }
+ for (MapObject *pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
+ if (!pMapObj->isSelected() || pMapObj->isWaypoint() || pMapObj->isLight()) {
+ continue;
+ }
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Aggressiveness);
- static char buf[1024];
- owner->GetWindowText(buf, sizeof(buf)-2);
- int value = 0;
+ m_dictSource = pMapObj;
+ // Select correct dictionary
+ m_dictToEdit = m_dictSource ? m_dictSource->getProperties() : nullptr;
- if (strcmp(buf, "Sleep") == 0) {
- value = -2;
- } else if (strcmp(buf, "Passive") == 0) {
- value = -1;
- } else if (strcmp(buf, "Normal") == 0) {
- value = 0;
- } else if (strcmp(buf, "Alert") == 0) {
- value = 1;
- } else if (strcmp(buf, "Aggressive") == 0) {
- value = 2;
+ updateTheUI(m_dictSource);
+
+ // simply break after the first one that's selected
+ break;
}
+}
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setInt(TheKey_objectAggressiveness, value);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+/// Move *all* data from object to dialog controls
+void MapObjectProps::updateTheUI(MapObject *pMapObj)
+{
+ _DictToName();
+ _DictToTeam();
+ _DictToScript();
+ _DictToWeather();
+ _DictToTime();
+ _DictToScale();
+ _DictToPrebuiltUpgrades();
+ _DictToHealth();
+ _DictToHPs();
+ _DictToEnabled();
+ _DictToDestructible();
+ _DictToPowered();
+ _DictToAggressiveness();
+ _DictToVisibilityRange();
+ _DictToVeterancy();
+ _DictToShroudClearingDistance();
+ _DictToRecruitableAI();
+ _DictToSelectable();
+ _DictToStoppingDistance();
+ _DictToUnsellable();
+ _DictToTargetable();
+ ShowZOffset(pMapObj);
+ ShowAngle(pMapObj);
+ ShowPosition(pMapObj);
+
+ // Warning: order is important. dictToAttachedSound() must come before dictToCustomize(),
+ // dictToCustomize() must come before any of the customization controls, dictToLooping()
+ // must come before dictToLoopCount(), and dictToLooping() and dictToLoopCount() must
+ // come before dictToEnabled().
+ dictToAttachedSound();
+ dictToCustomize();
+ dictToLooping();
+ dictToLoopCount();
+ dictToEnabled();
+ dictToMinVolume();
+ dictToVolume();
+ dictToMinRange();
+ dictToMaxRange();
+ dictToPriority();
+}
+
+//---------------------------------------------------------------------------------------------------
+
+void MapObjectProps::InitSound()
+{
+ CComboBox * priorityComboBox = (CComboBox *)GetDlgItem(IDC_PRIORITY_COMBO);
+ DEBUG_ASSERTCRASH( priorityComboBox != nullptr, ("Cannot find sound priority combobox" ) );
+
+ if ( priorityComboBox != nullptr )
+ {
+ Int i;
+ for ( i = 0; i <= AP_CRITICAL; i++ )
+ {
+ Int index = priorityComboBox->InsertString( i,theAudioPriorityNames[i] );
+ (void)index;
+ DEBUG_ASSERTCRASH( index == i, ("insert string returned %d, expected %d", index, i ) );
+ }
+ }
+
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ DEBUG_ASSERTCRASH( soundComboBox != nullptr, ("Cannot find sound combobox" ) );
+ m_defaultEntryIndex = 0;
+ m_defaultIsNone = true;
+
+ // Load up combobox
+ if ( soundComboBox != nullptr )
+ {
+ // Add all the sound names in order. Since the combobox has the SORTED style,
+ // we can just add the strings in and let the combo box sort them
+ const AudioEventInfoHash & audioEventHash = TheAudio->getAllAudioEvents();
+
+ AudioEventInfoHash::const_iterator it;
+ for ( it = audioEventHash.begin(); it != audioEventHash.end(); it++ )
+ {
+ if ( it->second->m_soundType == AT_SoundEffect )
+ {
+ // Hmm, should we be filtering the list in any other way? Oh well.
+ soundComboBox->AddString( it->second->m_audioName.str() );
+ }
+ }
+
+ m_defaultEntryIndex = soundComboBox->InsertString( 0, BASE_DEFAULT_STRING );
+ m_defaultEntryName = NO_SOUND_STRING;
+ m_defaultIsNone = true;
+
+ soundComboBox->InsertString( 1, NO_SOUND_STRING );
+ }
+
+}
+
+
+// Adds a series of Undoable's to the given MultipleUndoable which clears the
+// objectSoundAmbientCustomized flag and all the customization flags out of
+// all the selected dictionaries.
+// NOTE: assumes getAllSelectedDicts() has already been called
+void MapObjectProps::clearCustomizeFlag( CWorldBuilderDoc* pDoc, MultipleUndoable * ownerUndoable )
+{
+ Dict empty;
+
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientCustomized, m_allSelectedDicts.size(), pDoc, true);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ // Note: we can set all the undoes in between the first and last undo to not invalidate,
+ // since the first (last for doing) and last invalidate after these changes anyway
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientMaxRange, m_allSelectedDicts.size(), pDoc, false);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientMinVolume, m_allSelectedDicts.size(), pDoc, false);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientVolume, m_allSelectedDicts.size(), pDoc, false);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientMinRange, m_allSelectedDicts.size(), pDoc, false);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientLooping, m_allSelectedDicts.size(), pDoc, false);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientLoopCount, m_allSelectedDicts.size(), pDoc, false);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+
+ pUndo = new DictItemUndoable(getAllSelectedDictsData(), empty, TheKey_objectSoundAmbientPriority, m_allSelectedDicts.size(), pDoc, true);
+ ownerUndoable->addUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to ownerUndoable now.
+}
+
+/// Move data from dialog controls to object(s)
+void MapObjectProps::attachedSoundToDict()
+{
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ return;
+
+ getAllSelectedDicts();
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ MultipleUndoable *pUndo = new MultipleUndoable;
+
+ Dict newDict;
+
+ // For the default, erase the objectSoundAmbient key
+ if ( soundComboBox->GetCurSel() != m_defaultEntryIndex )
+ {
+ CString selectionText;
+ soundComboBox->GetLBText( soundComboBox->GetCurSel(), selectionText );
+ if ( selectionText == NO_SOUND_STRING )
+ {
+ newDict.setAsciiString(TheKey_objectSoundAmbient, "");
+ // Can't customize the null sound
+ clearCustomizeFlag( pDoc, pUndo );
+ }
+ else
+ {
+ newDict.setAsciiString(TheKey_objectSoundAmbient, static_cast< const char * >( selectionText) );
+ }
+ }
+ else if ( m_defaultIsNone )
+ {
+ // Can't customize the null sound
+ clearCustomizeFlag( pDoc, pUndo );
+ }
+
+ DictItemUndoable *pDictUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, TheKey_objectSoundAmbient, m_allSelectedDicts.size(), pDoc, true);
+ pUndo->addUndoable( pDictUndo );
+ pDoc->AddAndDoUndoable( pUndo );
+ REF_PTR_RELEASE( pDictUndo ); // belongs to pUndo
+ REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_VisibilityToDict()
+/// Move data from dialog controls to object(s)
+void MapObjectProps::customizeToDict()
{
- getAllSelectedDicts();
+ CButton * customizeCheckbox = (CButton *)GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr )
+ return;
- int value = -1;
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_VisionDistance);
- edit->EnableWindow(TRUE);
- CString cstr;
- edit->GetWindowText(cstr);
- if (!cstr.IsEmpty()) {
- value = atoi(cstr.GetBuffer(0));
- }
+ getAllSelectedDicts();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- if (value != -1) {
- newDict.setInt(TheKey_objectVisualRange, value);
- }
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, TheKey_objectVisualRange, m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+
+ // For space reasons, erase key instead of added "false" key. Should be treated the same
+ if ( customizeCheckbox->GetCheck() == 1 )
+ {
+ newDict.setBool( TheKey_objectSoundAmbientCustomized, true );
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, TheKey_objectSoundAmbientCustomized, m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
+ else
+ {
+ MultipleUndoable *pUndo = new MultipleUndoable;
+ clearCustomizeFlag( pDoc, pUndo );
+ pDoc->AddAndDoUndoable( pUndo );
+ REF_PTR_RELEASE( pUndo ); // belongs to pDoc now.
+ // Update is called by Doc
+ }
+ }
}
-void MapObjectProps::_VeterancyToDict()
+/// Move data from dialog controls to object(s)
+void MapObjectProps::enabledToDict()
{
- getAllSelectedDicts();
+ CButton * enabledCheckbox = (CButton *)GetDlgItem(IDC_ENABLED_CHECKBOX);
+ if ( enabledCheckbox == nullptr )
+ return;
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Veterancy);
- static char buf[1024];
- int curSel = owner->GetCurSel();
- int value = 0;
- if (curSel >= 0) {
- value=curSel;
- }
+ getAllSelectedDicts();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setInt(TheKey_objectVeterancy, value);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
-}
+ newDict.setBool( TheKey_objectSoundAmbientEnabled, enabledCheckbox->GetCheck() != 0 );
-void MapObjectProps::_WeatherToDict()
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
+}
+
+/// Move data from dialog controls to object(s)
+void MapObjectProps::loopingToDict()
{
- getAllSelectedDicts();
+ CButton * loopingCheckbox = (CButton *)GetDlgItem(IDC_LOOPING_CHECKBOX);
+ if ( loopingCheckbox == nullptr )
+ return;
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Weather);
- static char buf[1024];
- int curSel = owner->GetCurSel();
+ getAllSelectedDicts();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setInt(TheKey_objectWeather, curSel);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+
+ newDict.setBool( TheKey_objectSoundAmbientLooping, loopingCheckbox->GetCheck() != 0 );
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_TimeToDict()
+/// Move data from dialog controls to object(s)
+void MapObjectProps::loopCountToDict()
{
- getAllSelectedDicts();
+ CEdit * loopCountEdit = (CEdit *)GetDlgItem(IDC_LOOPCOUNT_EDIT);
+ if ( loopCountEdit == nullptr )
+ return;
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_Time);
- static char buf[1024];
- int curSel = owner->GetCurSel();
+ getAllSelectedDicts();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setInt(TheKey_objectTime, curSel);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+
+ CString loopCountString;
+ loopCountEdit->GetWindowText(loopCountString);
+ newDict.setInt( TheKey_objectSoundAmbientLoopCount, atoi( loopCountString ) );
+
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_ShroudClearingDistanceToDict()
+/// Move data from dialog controls to object(s)
+void MapObjectProps::minVolumeToDict()
{
- getAllSelectedDicts();
+ CEdit * minVolumeEdit = (CEdit *)GetDlgItem(IDC_MIN_VOLUME_EDIT);
+ if ( minVolumeEdit == nullptr )
+ return;
- int value = -1;
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ShroudClearingDistance);
- edit->EnableWindow(TRUE);
- CString cstr;
- edit->GetWindowText(cstr);
- if (!cstr.IsEmpty()) {
- value = atoi(cstr.GetBuffer(0));
- }
+ getAllSelectedDicts();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- if (value != -1) {
- newDict.setInt(TheKey_objectShroudClearingDistance, value);
- }
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, TheKey_objectShroudClearingDistance, m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
-void MapObjectProps::_RecruitableAIToDict()
-{
- getAllSelectedDicts();
+ CString minVolumeString;
+ minVolumeEdit->GetWindowText(minVolumeString);
- CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
- Bool isChecked = (owner->GetCheck() != 0);
+ // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
+ newDict.setReal( TheKey_objectSoundAmbientMinVolume, INT_TO_REAL( atoi( minVolumeString ) ) / 100.0f );
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool(TheKey_objectRecruitableAI, isChecked);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_SelectableToDict()
+/// Move data from dialog controls to object(s)
+void MapObjectProps::volumeToDict()
{
- getAllSelectedDicts();
+ CEdit * volumeEdit = (CEdit *)GetDlgItem(IDC_VOLUME_EDIT);
+ if ( volumeEdit == nullptr )
+ return;
- CButton *owner = (CButton*) GetDlgItem(IDC_MAPOBJECT_Selectable);
- Bool isChecked = (owner->GetCheck() != 0);
+ getAllSelectedDicts();
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setBool(TheKey_objectSelectable, isChecked);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+
+ CString volumeString;
+ volumeEdit->GetWindowText(volumeString);
+
+ // Note: volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
+ newDict.setReal( TheKey_objectSoundAmbientVolume, INT_TO_REAL( atoi( volumeString ) ) / 100.0f );
+
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_HPsToDict()
+
+/// Move data from dialog controls to object(s)
+void MapObjectProps::minRangeToDict()
{
- getAllSelectedDicts();
+ CEdit * minRangeEdit = (CEdit *)GetDlgItem(IDC_MIN_RANGE_EDIT);
+ if ( minRangeEdit == nullptr )
+ return;
- Int value;
- static char buf[1024];
+ getAllSelectedDicts();
- CComboBox *owner = (CComboBox*)GetDlgItem(IDC_MAPOBJECT_HitPoints);
- owner->GetWindowText(buf, sizeof(buf)-2);
- value = atoi(buf);
- if (value == 0)
- value = -1;
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
+ CString minRangeString;
+ minRangeEdit->GetWindowText(minRangeString);
- newDict.setInt(TheKey_objectMaxHPs, value);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size());
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ newDict.setReal( TheKey_objectSoundAmbientMinRange, INT_TO_REAL( atoi( minRangeString ) ) );
+
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::_StoppingDistanceToDict()
+/// Move data from dialog controls to object(s)
+void MapObjectProps::maxRangeToDict()
{
- getAllSelectedDicts();
+ CEdit * maxRangeEdit = (CEdit *)GetDlgItem(IDC_MAX_RANGE_EDIT);
+ if ( maxRangeEdit == nullptr )
+ return;
- Real value;
- static char buf[1024];
+ getAllSelectedDicts();
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_StoppingDistance);
- CString cstr;
- edit->GetWindowText(cstr);
- if (cstr.IsEmpty()) {
- return;
- }
- value = atof(cstr.GetBuffer(0));
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- Dict newDict;
- newDict.setReal(TheKey_objectStoppingDistance, value);
- DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Update is called by Do
-}
+ CString maxRangeString;
+ maxRangeEdit->GetWindowText(maxRangeString);
-void MapObjectProps::OnOK()
-{
+ newDict.setReal( TheKey_objectSoundAmbientMaxRange, INT_TO_REAL( atoi( maxRangeString ) ) );
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
}
-void MapObjectProps::OnCancel()
-{
+/// Move data from dialog controls to object(s)
+void MapObjectProps::priorityToDict()
+{
+ CComboBox * priorityComboBox = (CComboBox *)GetDlgItem(IDC_PRIORITY_COMBO);
+ if ( priorityComboBox == nullptr )
+ return;
+
+ getAllSelectedDicts();
+
+ CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
+ if ( pDoc != nullptr )
+ {
+ Dict newDict;
+
+ newDict.setInt( TheKey_objectSoundAmbientPriority, priorityComboBox->GetCurSel() );
+
+ DictItemUndoable *pUndo = new DictItemUndoable(getAllSelectedDictsData(), newDict, newDict.getNthKey(0), m_allSelectedDicts.size(), pDoc, true);
+ pDoc->AddAndDoUndoable(pUndo);
+ REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Update is called by Doc
+ }
+}
+
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToAttachedSound()
+{
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ return;
+
+ // Update the string for the "default" entry
+ m_defaultIsNone = true;
+ m_defaultEntryName = NO_SOUND_STRING;
+ soundComboBox->DeleteString(m_defaultEntryIndex);
+ const ThingTemplate * thingTemplate = nullptr;
+ if (m_dictSource)
+ {
+ thingTemplate = m_dictSource->getThingTemplate();
+ }
+
+ if ( thingTemplate )
+ {
+ AsciiString string( BASE_DEFAULT_STRING );
+
+ const AudioEventRTS * defaultAudioEvent;
+
+ // Note: getSoundAmbient will return a non-null pointer even if there is no real sound attached to the object
+ if ( thingTemplate->hasSoundAmbient() )
+ {
+ defaultAudioEvent = thingTemplate->getSoundAmbient();
+ }
+ else
+ {
+ defaultAudioEvent = nullptr;
+ }
+
+ if ( defaultAudioEvent == nullptr || defaultAudioEvent == TheAudio->getValidSilentAudioEvent() )
+ {
+ string.concat( " " );
+ }
+ else
+ {
+ string.concat( " <" );
+ string.concat( defaultAudioEvent->getEventName() );
+ string.concat( '>' );
+ m_defaultEntryName = defaultAudioEvent->getEventName();
+ m_defaultIsNone = false;
+ }
+ m_defaultEntryIndex = soundComboBox->InsertString(0, string.str());
+ }
+ else
+ {
+ m_defaultEntryIndex = soundComboBox->InsertString(0, BASE_DEFAULT_STRING);
+ }
+
+ // Now select the correct entry in the list box
+ AsciiString sound;
+ Bool exists = false;
+ if (m_dictToEdit)
+ {
+ sound = m_dictToEdit->getAsciiString(TheKey_objectSoundAmbient, &exists);
+ }
+
+ if ( !exists )
+ {
+ // Use the "default" entry
+ soundComboBox->SetCurSel( m_defaultEntryIndex );
+ return;
+ }
+
+ if ( sound.isEmpty() )
+ {
+ // Use the entry "(None)"
+ sound = NO_SOUND_STRING;
+ }
+
+ // Note: better than SelectString because we want the exact string not a prefix
+ Int index = soundComboBox->FindStringExact( -1, sound.str() );
+ if ( index > -1 )
+ {
+ soundComboBox->SetCurSel( index );
+ }
+ else
+ {
+ DEBUG_CRASH( ("Could not find existing sound's name %s in combo box", sound.str() ) );
+ soundComboBox->SetCurSel( m_defaultEntryIndex );
+ }
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToCustomize()
+{
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr )
+ return;
+
+ // If the current sound is "none", disable the customize button
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ return;
+
+ int index = soundComboBox->GetCurSel();
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING ||
+ ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ customizeCheckbox->SetCheck( 0 );
+ customizeCheckbox->EnableWindow( false );
+ return;
+ }
+
+ // Sound is not "none", so we can customize if we wish
+ customizeCheckbox->EnableWindow( true );
+
+ Bool exists = false;
+ Bool customized = false;
+ if (m_dictToEdit)
+ {
+ customized = m_dictToEdit->getBool(TheKey_objectSoundAmbientCustomized, &exists);
+ }
+
+ customizeCheckbox->SetCheck( exists && customized ? 1 : 0 );
+}
+
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToLooping()
+{
+ CButton * loopingCheckbox = ( CButton * )GetDlgItem(IDC_LOOPING_CHECKBOX);
+ if ( loopingCheckbox == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 )
+ {
+ loopingCheckbox->EnableWindow( false );
+ }
+ else
+ {
+ loopingCheckbox->EnableWindow( true );
+
+ // If customization is enabled, look to see if the looping flag has already been
+ // customized
+ Bool exists = false;
+ Bool looping = false;
+ if (m_dictToEdit)
+ {
+ looping = m_dictToEdit->getBool(TheKey_objectSoundAmbientLooping, &exists);
+ }
+
+ if ( exists )
+ {
+ loopingCheckbox->SetCheck( looping ? 1 : 0 );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the looping checkbox
+
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ loopingCheckbox->SetCheck( 0 );
+ return;
+ }
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ loopingCheckbox->SetCheck( 0 );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ loopingCheckbox->SetCheck( ( audioEventInfo && ( audioEventInfo->m_control & AC_LOOP ) ) ? 1 : 0 );
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToLoopCount()
+{
+ CEdit * loopCountEdit = ( CEdit * )GetDlgItem(IDC_LOOPCOUNT_EDIT);
+ if ( loopCountEdit == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ // If the looping checkbox is off, the loop count control is disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ CButton * loopingCheckbox = ( CButton * )GetDlgItem(IDC_LOOPING_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 ||
+ loopingCheckbox == nullptr || loopingCheckbox->GetCheck() == 0 )
+ {
+ loopCountEdit->EnableWindow( false );
+ }
+ else
+ {
+ loopCountEdit->EnableWindow( true );
+
+ // If customization is enabled, look to see if the loop count has already been
+ // customized
+ Bool exists = false;
+ Int loopCount = 0;
+ if (m_dictToEdit)
+ {
+ loopCount = m_dictToEdit->getInt(TheKey_objectSoundAmbientLoopCount, &exists);
+ }
+
+ if ( exists )
+ {
+ CString loopCountText;
+ loopCountText.Format( "%d", loopCount );
+ loopCountEdit->SetWindowText( loopCountText );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the loop count
+
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ loopCountEdit->SetWindowText( "0" );
+ return;
+ }
+
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ loopCountEdit->SetWindowText( "0" );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ if ( audioEventInfo == nullptr )
+ {
+ loopCountEdit->SetWindowText( "0" );
+ return;
+ }
+
+ CString loopCountText;
+ loopCountText.Format( "%d", audioEventInfo->m_loopCount );
+ loopCountEdit->SetWindowText( loopCountText );
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToEnabled()
+{
+ CButton * enableCheckbox = ( CButton * )GetDlgItem(IDC_ENABLED_CHECKBOX);
+ if ( enableCheckbox == nullptr )
+ return;
+
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+
+ // If we don't have a sound, we can't enable it
+ CString currentString;
+ if ( soundComboBox == nullptr )
+ {
+ enableCheckbox->EnableWindow( false );
+ enableCheckbox->SetCheck( 0 );
+ return;
+ }
+
+ Int soundIndex = soundComboBox->GetCurSel();
+ soundComboBox->GetLBText( soundIndex, currentString );
+ if ( currentString == NO_SOUND_STRING ||
+ ( soundIndex == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ enableCheckbox->SetCheck( 0 );
+ enableCheckbox->EnableWindow( false );
+ return;
+ }
+ else
+ {
+ enableCheckbox->EnableWindow( true );
+
+ // Look to see if the enabled flag has already been customized
+ Bool exists = false;
+ Bool enabled = false;
+ if (m_dictToEdit)
+ {
+ enabled = m_dictToEdit->getBool(TheKey_objectSoundAmbientEnabled, &exists);
+ }
+
+ if ( exists )
+ {
+ enableCheckbox->SetCheck( enabled ? 1 : 0 );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the enabled checkbox
+
+ // Look up sound and see if it's looping. Looping-forever sounds start enabled;
+ // non-looping ones don't.
+ // Actually, by now, dictToLooping and dictToLoopCount will have looked up the
+ // info we need for us
+ // NOTE: This test should match the tests done in Object::updateObjValuesFromMapProperties()
+ // when it decided whether or not to enable a customized sound
+ CButton * loopingCheckbox = (CButton *)GetDlgItem(IDC_LOOPING_CHECKBOX);
+ CEdit * loopCountEdit = (CEdit *)GetDlgItem(IDC_LOOPCOUNT_EDIT);
+ if ( loopingCheckbox && loopCountEdit && loopingCheckbox->GetCheck() == 1 )
+ {
+ CString loopCount;
+ loopCountEdit->GetWindowText( loopCount );
+
+ if ( atoi(loopCount) == 0 )
+ {
+ enableCheckbox->SetCheck( 1 );
+ return;
+ }
+ }
+
+ enableCheckbox->SetCheck( 0 );
+}
+
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToMinVolume()
+{
+ CEdit * minVolumeEdit = ( CEdit * )GetDlgItem(IDC_MIN_VOLUME_EDIT);
+ if ( minVolumeEdit == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 )
+ {
+ minVolumeEdit->EnableWindow( false );
+ }
+ else
+ {
+ minVolumeEdit->EnableWindow( true );
+
+ // If customization is enabled, look to see if the minimum volume has already been
+ // customized
+ Bool exists = false;
+ Real minVolume = 0.0f;
+ if (m_dictToEdit)
+ {
+ minVolume = m_dictToEdit->getReal(TheKey_objectSoundAmbientMinVolume, &exists);
+ }
+
+ if ( exists )
+ {
+ // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
+ CString minVolumeText;
+ minVolumeText.Format( "%d", REAL_TO_INT( ( minVolume * 100.0f ) + 0.5 ) );
+ minVolumeEdit->SetWindowText( minVolumeText );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the minimum volume
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ minVolumeEdit->SetWindowText( "40" );
+ return;
+ }
+
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ minVolumeEdit->SetWindowText( "40" );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ if ( audioEventInfo == nullptr )
+ {
+ minVolumeEdit->SetWindowText( "40" );
+ return;
+ }
+
+ // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
+ CString minVolumeText;
+ minVolumeText.Format( "%d", REAL_TO_INT( ( audioEventInfo->m_minVolume * 100.0f ) + 0.5 ) );
+ minVolumeEdit->SetWindowText( minVolumeText );
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToVolume()
+{
+ CEdit * volumeEdit = ( CEdit * )GetDlgItem(IDC_VOLUME_EDIT);
+ if ( volumeEdit == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 )
+ {
+ volumeEdit->EnableWindow( false );
+ }
+ else
+ {
+ volumeEdit->EnableWindow( true );
+
+ // If customization is enabled, look to see if the volume has already been
+ // customized
+ Bool exists = false;
+ Real volume = 0.0f;
+ if (m_dictToEdit)
+ {
+ volume = m_dictToEdit->getReal(TheKey_objectSoundAmbientVolume, &exists);
+ }
+
+ if ( exists )
+ {
+ // Note: min volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
+ CString volumeText;
+ volumeText.Format( "%d", REAL_TO_INT( ( volume * 100.0f ) + 0.5 ) );
+ volumeEdit->SetWindowText( volumeText );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the volume
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ volumeEdit->SetWindowText( "100" );
+ return;
+ }
+
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ volumeEdit->SetWindowText( "100" );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ if ( audioEventInfo == nullptr )
+ {
+ volumeEdit->SetWindowText( "100" );
+ return;
+ }
+
+ // Note: volume is stored as Real between 0.0 and 1.0, but displayed as a percentage from 0 to 100
+ CString volumeText;
+ volumeText.Format( "%d", REAL_TO_INT( ( audioEventInfo->m_volume * 100.0f ) + 0.5 ) );
+ volumeEdit->SetWindowText( volumeText );
+}
+
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToMinRange()
+{
+ CEdit * minRangeEdit = ( CEdit * )GetDlgItem(IDC_MIN_RANGE_EDIT);
+ if ( minRangeEdit == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 )
+ {
+ minRangeEdit->EnableWindow( false );
+ }
+ else
+ {
+ minRangeEdit->EnableWindow( true );
+
+ // If customization is enabled, look to see if the minimum range has already been
+ // customized
+ Bool exists = false;
+ Real minRange = 0.0f;
+ if (m_dictToEdit)
+ {
+ minRange = m_dictToEdit->getReal(TheKey_objectSoundAmbientMinRange, &exists);
+ }
+
+ if ( exists )
+ {
+ CString minRangeText;
+ minRangeText.Format( "%d", REAL_TO_INT(minRange) );
+ minRangeEdit->SetWindowText( minRangeText );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the minimum range
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ minRangeEdit->SetWindowText( "175" );
+ return;
+ }
+
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ minRangeEdit->SetWindowText( "175" );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ if ( audioEventInfo == nullptr )
+ {
+ minRangeEdit->SetWindowText( "175" );
+ return;
+ }
+
+ CString minRangeText;
+ minRangeText.Format( "%d", REAL_TO_INT( audioEventInfo->m_minDistance ) );
+ minRangeEdit->SetWindowText( minRangeText );
+}
+
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToMaxRange()
+{
+ CEdit * maxRangeEdit = ( CEdit * )GetDlgItem(IDC_MAX_RANGE_EDIT);
+ if ( maxRangeEdit == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 )
+ {
+ maxRangeEdit->EnableWindow( false );
+ }
+ else
+ {
+ maxRangeEdit->EnableWindow( true );
+
+ // If customization is enabled, look to see if the maximum range has already been
+ // customized
+ Bool exists = false;
+ Real maxRange = 0.0f;
+ if (m_dictToEdit)
+ {
+ maxRange = m_dictToEdit->getReal(TheKey_objectSoundAmbientMaxRange, &exists);
+ }
+
+ if ( exists )
+ {
+ CString maxRangeText;
+ maxRangeText.Format( "%d", REAL_TO_INT( maxRange ) );
+ maxRangeEdit->SetWindowText( maxRangeText );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the minimum range
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ maxRangeEdit->SetWindowText( "600" );
+ return;
+ }
+
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ maxRangeEdit->SetWindowText( "600" );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ if ( audioEventInfo == nullptr )
+ {
+ maxRangeEdit->SetWindowText( "600" );
+ return;
+ }
+
+ CString maxRangeText;
+ maxRangeText.Format( "%d", REAL_TO_INT( audioEventInfo->m_maxDistance ) );
+ maxRangeEdit->SetWindowText( maxRangeText );
+}
+
+/// Move data from object to dialog controls
+void MapObjectProps::dictToPriority()
+{
+ CComboBox * priorityComboBox = ( CComboBox * )GetDlgItem(IDC_PRIORITY_COMBO);
+ if ( priorityComboBox == nullptr )
+ return;
+
+ // If the customized checkbox is off, all customization controls are disabled
+ CButton * customizeCheckbox = ( CButton * )GetDlgItem(IDC_CUSTOMIZE_CHECKBOX);
+ if ( customizeCheckbox == nullptr || customizeCheckbox->GetCheck() == 0 )
+ {
+ priorityComboBox->EnableWindow( false );
+ }
+ else
+ {
+ priorityComboBox->EnableWindow( true );
+
+ // If customization is enabled, look to see if the maximum range has already been
+ // customized
+ Bool exists = false;
+ Int priorityEnum = AP_LOWEST;
+ if (m_dictToEdit)
+ {
+ priorityEnum = m_dictToEdit->getInt(TheKey_objectSoundAmbientPriority, &exists);
+ }
+
+ if ( exists )
+ {
+ if ( priorityEnum < 0 || priorityEnum > AP_CRITICAL )
+ {
+ DEBUG_CRASH( ("Bad soundAmbientPriority key %d", priorityEnum ) );
+ priorityEnum = AP_LOWEST;
+ }
+
+ // Note: indexes of priority combobox map to priority enum
+ priorityComboBox->SetCurSel( priorityEnum );
+
+ // Don't use defaults, just return
+ return;
+ }
+ }
+
+ // If we get here, we need the default for the priority
+ CComboBox * soundComboBox = (CComboBox *)GetDlgItem(IDC_SOUND_COMBO);
+ if ( soundComboBox == nullptr )
+ {
+ priorityComboBox->SetCurSel( AP_LOWEST );
+ return;
+ }
+
+ Int index = soundComboBox->GetCurSel();
+
+ CString currentString;
+ soundComboBox->GetLBText( index, currentString );
+ if ( currentString == NO_SOUND_STRING || ( index == m_defaultEntryIndex && m_defaultIsNone ) )
+ {
+ priorityComboBox->SetCurSel( AP_LOWEST );
+ return;
+ }
+
+ if ( index == m_defaultEntryIndex )
+ {
+ // Correct the current string e.g. remove "Default <" and ">"
+ currentString = m_defaultEntryName.str();
+ }
+
+ AudioEventInfo * audioEventInfo = TheAudio->findAudioEventInfo(static_cast< const char * >( currentString ) );
+
+ if ( audioEventInfo == nullptr )
+ {
+ priorityComboBox->SetCurSel( AP_LOWEST );
+ return;
+ }
+
+ priorityComboBox->SetCurSel( audioEventInfo->m_priority );
+}
+
+
+// Special message to handle pages being resized to new sheet size
+// see knowledge base article Q143291
+const Int RESIZE_PAGE_MESSAGE = WM_USER + 117;
-}
+/////////////////////////////////////////////////////////////////////////////
+// MapObjectProps message handlers
-void MapObjectProps::ShowZOffset(MapObject *pMapObj)
+
+
+void MapObjectProps::enableButtons()
{
- const Coord3D *loc = pMapObj->getLocation();
- static char buff[32];
- m_height = loc->z;
- snprintf(buff, ARRAY_SIZE(buff), "%0.2f", loc->z);
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
- edit->SetWindowText(buff);
+ // do nothing
}
-void MapObjectProps::SetZOffset()
+
+/*static*/ MapObject *MapObjectProps::getSingleSelectedMapObject()
{
- Real value = 0.0f;
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
- CString cstr;
- edit->GetWindowText(cstr);
- if (!cstr.IsEmpty()) {
- value = atof(cstr);
+ MapObject *pMapObj;
+ MapObject *theMapObj = nullptr;
+// Bool found = false;
+ Int selCount=0;
+ for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
+ if (pMapObj->isSelected()) {
+ if (!pMapObj->isWaypoint() && !pMapObj->isLight())
+ {
+ theMapObj = pMapObj;
+ }
+ selCount++;
+ }
}
- m_height = value;
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- ModifyObjectUndoable *pUndo = new ModifyObjectUndoable(pDoc);
- pDoc->AddAndDoUndoable(pUndo);
- pUndo->SetZOffset(value);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ if (selCount==1 && theMapObj) {
+ return theMapObj;
+ }
+ return(nullptr);
}
-void MapObjectProps::ShowAngle(MapObject *pMapObj)
-{
- m_angle = pMapObj->getAngle() * 180 / PI;
- static char buff[32];
- snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_angle);
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Angle);
- edit->SetWindowText(buff);
+
+
+
+void MapObjectProps::OnOK()
+{
+ // Make sure CPropertySheet functions don't close the window
}
-void MapObjectProps::SetAngle()
+void MapObjectProps::OnCancel()
{
- Real angle = 0.0f;
- CWnd* edit = GetDlgItem(IDC_MAPOBJECT_Angle);
- CString cstr;
- edit->GetWindowText(cstr);
- if (!cstr.IsEmpty()) {
- angle = atof(cstr);
- }
- m_angle = angle;
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- ModifyObjectUndoable *pUndo = new ModifyObjectUndoable(pDoc);
- pDoc->AddAndDoUndoable(pUndo);
- pUndo->RotateTo(angle * PI/180);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
+ // Make sure CPropertySheet functions don't close the window
}
+
+
void MapObjectProps::getAllSelectedDicts()
{
m_allSelectedDicts.clear();
@@ -1351,82 +2873,20 @@ Dict** MapObjectProps::getAllSelectedDictsData()
#endif
}
-void MapObjectProps::GetPopSliderInfo(const long sliderID, long *pMin, long *pMax, long *pLineSize, long *pInitial)
+/// Move data from dialog controls to object
+void MapObjectProps::OnScaleOn()
{
- switch (sliderID) {
-
- case IDC_HEIGHT_POPUP:
- *pMin = -50;
- *pMax = 50;
- *pInitial = m_height;
- *pLineSize = 1;
- break;
-
- case IDC_ANGLE_POPUP:
- *pMin = 0;
- *pMax = 360;
- *pInitial = m_angle;
- *pLineSize = 1;
- break;
-
- default:
- // uh-oh!
- DEBUG_CRASH(("Slider message from unknown control"));
- break;
- }
+ _ScaleToDict();
}
-void MapObjectProps::PopSliderChanged(const long sliderID, long theVal)
+/// Move data from dialog controls to object
+void MapObjectProps::OnScaleOff()
{
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- CWnd* edit;
- static char buff[32];
- switch (sliderID) {
- case IDC_HEIGHT_POPUP:
- if (!m_posUndoable) {
- m_posUndoable = new ModifyObjectUndoable(pDoc);
- pDoc->AddAndDoUndoable(m_posUndoable);
- }
- m_posUndoable->SetZOffset(theVal);
- m_height = theVal;
- snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_height);
- edit = GetDlgItem(IDC_MAPOBJECT_ZOffset);
- edit->SetWindowText(buff);
- break;
-
- case IDC_ANGLE_POPUP:
- if (!m_posUndoable) {
- m_posUndoable = new ModifyObjectUndoable(pDoc);
- pDoc->AddAndDoUndoable(m_posUndoable);
- }
- m_posUndoable->RotateTo(theVal * PI/180);
- m_angle = theVal;
- snprintf(buff, ARRAY_SIZE(buff), "%0.2f", m_angle);
- edit = GetDlgItem(IDC_MAPOBJECT_Angle);
- edit->SetWindowText(buff);
- break;
-
- default:
- // uh-oh!
- DEBUG_CRASH(("Slider message from unknown control"));
- break;
- }
+ _ScaleToDict();
}
-void MapObjectProps::PopSliderFinished(const long sliderID, long theVal)
+/// Move data from dialog controls to object
+void MapObjectProps::OnKillfocusMAPOBJECTXYPosition()
{
- switch (sliderID) {
- case IDC_HEIGHT_POPUP:
- case IDC_ANGLE_POPUP:
- REF_PTR_RELEASE(m_posUndoable); // belongs to pDoc now.
- m_posUndoable = nullptr;
- break;
-
- default:
- // uh-oh!
- DEBUG_CRASH(("Slider message from unknown control"));
- break;
- }
-
+ SetPosition();
}
-
diff --git a/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp b/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp
index ce79975e5e8..ec228afedaa 100644
--- a/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/playerlistdlg.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -339,6 +339,7 @@ void PlayerListDlg::OnEditplayer()
AfxMessageBox("Implement me. (Sorry.)");
return;
+#if 0
Dict *playerDict = m_sides.getSideInfo(m_curPlayerIdx)->getDict();
AsciiString pnameold = playerDict->getAsciiString(TheKey_playerName);
Bool isneutral = pnameold.isEmpty();
@@ -372,11 +373,11 @@ void PlayerListDlg::OnEditplayer()
fixDefaultTeamName(m_sides, pnameold, pnamenew);
Bool modified = m_sides.validateSides();
- (void)modified;
DEBUG_ASSERTLOG(!modified,("had to clean up sides in PlayerListDlg::OnEditplayer"));
updateTheUI();
}
+#endif
}
void PlayerListDlg::OnRemoveplayer()
@@ -843,97 +844,47 @@ void PlayerListDlg::OnChangePlayerdisplayname()
updateTheUI();
}
-void PlayerListDlg::OnAddskirmishplayers()
+static void addSide(SidesList *sides, AsciiString faction,
+ AsciiString playerName, const wchar_t *playerUName)
{
- // PlyrCivilian
-
- AsciiString addedPTName = "FactionCivilian";
- AsciiString pname = "PlyrCivilian";
- UnicodeString pnameu;
- pnameu = L"PlyrCivilian";
-
- if (!m_sides.findSideInfo(pname)) {
-
- Dict newPlayerDict;
- newPlayerDict.setAsciiString(TheKey_playerName, pname);
- newPlayerDict.setBool(TheKey_playerIsHuman, false);
- newPlayerDict.setUnicodeString(TheKey_playerDisplayName, pnameu);
- newPlayerDict.setAsciiString(TheKey_playerFaction, addedPTName);
- newPlayerDict.setAsciiString(TheKey_playerEnemies, "");
- newPlayerDict.setAsciiString(TheKey_playerAllies, "");
-
- ensureValidPlayerName(&newPlayerDict);
- m_sides.addSide(&newPlayerDict);
-
- Bool modified = m_sides.validateSides();
- (void)modified;
- DEBUG_ASSERTLOG(!modified,("had to clean up sides in PlayerListDlg::OnNewplayer"));
- }
-
- addedPTName = "FactionAmerica";
- pname = "SkirmishAmerica";
- pnameu = L"SkirmishAmerica";
-
- if (!m_sides.findSideInfo(pname)) {
-
- Dict newPlayerDict;
- newPlayerDict.setAsciiString(TheKey_playerName, pname);
- newPlayerDict.setBool(TheKey_playerIsHuman, false);
- newPlayerDict.setUnicodeString(TheKey_playerDisplayName, pnameu);
- newPlayerDict.setAsciiString(TheKey_playerFaction, addedPTName);
- newPlayerDict.setAsciiString(TheKey_playerEnemies, "");
- newPlayerDict.setAsciiString(TheKey_playerAllies, "");
-
- ensureValidPlayerName(&newPlayerDict);
- m_sides.addSide(&newPlayerDict);
-
- Bool modified = m_sides.validateSides();
- (void)modified;
- DEBUG_ASSERTLOG(!modified,("had to clean up sides in PlayerListDlg::OnNewplayer"));
- }
-
- addedPTName = "FactionChina";
- pname = "SkirmishChina";
- pnameu = L"SkirmishChina";
-
- if (!m_sides.findSideInfo(pname)) {
+ if (!sides->findSideInfo(playerName)) {
Dict newPlayerDict;
- newPlayerDict.setAsciiString(TheKey_playerName, pname);
+ UnicodeString playerUStr;
+ playerUStr = playerUName;
+ newPlayerDict.setAsciiString(TheKey_playerName, playerName);
newPlayerDict.setBool(TheKey_playerIsHuman, false);
- newPlayerDict.setUnicodeString(TheKey_playerDisplayName, pnameu);
- newPlayerDict.setAsciiString(TheKey_playerFaction, addedPTName);
+ newPlayerDict.setUnicodeString(TheKey_playerDisplayName, playerUStr);
+ newPlayerDict.setAsciiString(TheKey_playerFaction, faction);
newPlayerDict.setAsciiString(TheKey_playerEnemies, "");
newPlayerDict.setAsciiString(TheKey_playerAllies, "");
ensureValidPlayerName(&newPlayerDict);
- m_sides.addSide(&newPlayerDict);
+ sides->addSide(&newPlayerDict);
- Bool modified = m_sides.validateSides();
+ Bool modified = sides->validateSides();
(void)modified;
DEBUG_ASSERTLOG(!modified,("had to clean up sides in PlayerListDlg::OnNewplayer"));
}
+}
- addedPTName = "FactionGLA";
- pname = "SkirmishGLA";
- pnameu = L"SkirmishGLA";
-
- if (!m_sides.findSideInfo(pname)) {
-
- Dict newPlayerDict;
- newPlayerDict.setAsciiString(TheKey_playerName, pname);
- newPlayerDict.setBool(TheKey_playerIsHuman, false);
- newPlayerDict.setUnicodeString(TheKey_playerDisplayName, pnameu);
- newPlayerDict.setAsciiString(TheKey_playerFaction, addedPTName);
- newPlayerDict.setAsciiString(TheKey_playerEnemies, "");
- newPlayerDict.setAsciiString(TheKey_playerAllies, "");
-
- ensureValidPlayerName(&newPlayerDict);
- m_sides.addSide(&newPlayerDict);
+void PlayerListDlg::OnAddskirmishplayers()
+{
+ // PlyrCivilian
- Bool modified = m_sides.validateSides();
- (void)modified;
- DEBUG_ASSERTLOG(!modified,("had to clean up sides in PlayerListDlg::OnNewplayer"));
- }
+ addSide(&m_sides, "FactionCivilian", "PlyrCivilian", L"PlyrCivilian");
+ addSide(&m_sides, "FactionAmerica", "SkirmishAmerica", L"SkirmishAmerica");
+ addSide(&m_sides, "FactionChina", "SkirmishChina", L"SkirmishChina");
+ addSide(&m_sides, "FactionGLA", "SkirmishGLA", L"SkirmishGLA");
+
+ addSide(&m_sides, "FactionAmericaAirForceGeneral", "SkirmishAmericaAirForceGeneral", L"SkirmishAmericaAirForceGeneral");
+ addSide(&m_sides, "FactionAmericaLaserGeneral", "SkirmishAmericaLaserGeneral", L"SkirmishAmericaLaserGeneral");
+ addSide(&m_sides, "FactionAmericaSuperWeaponGeneral", "SkirmishAmericaSuperWeaponGeneral", L"SkirmishAmericaSuperWeaponGeneral");
+ addSide(&m_sides, "FactionChinaTankGeneral", "SkirmishChinaTankGeneral", L"SkirmishChinaTankGeneral");
+ addSide(&m_sides, "FactionChinaNukeGeneral", "SkirmishChinaNukeGeneral", L"SkirmishChinaNukeGeneral");
+ addSide(&m_sides, "FactionChinaInfantryGeneral", "SkirmishChinaInfantryGeneral", L"SkirmishChinaInfantryGeneral");
+ addSide(&m_sides, "FactionGLADemolitionGeneral", "SkirmishGLADemolitionGeneral", L"SkirmishGLADemolitionGeneral");
+ addSide(&m_sides, "FactionGLAToxinGeneral", "SkirmishGLAToxinGeneral", L"SkirmishGLAToxinGeneral");
+ addSide(&m_sides, "FactionGLAStealthGeneral", "SkirmishGLAStealthGeneral", L"SkirmishGLAStealthGeneral");
updateTheUI();
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/propedit.cpp b/Generals/Code/Tools/WorldBuilder/src/propedit.cpp
index fbf93717a8e..266f0b48c33 100644
--- a/Generals/Code/Tools/WorldBuilder/src/propedit.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/propedit.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
diff --git a/Generals/Code/Tools/WorldBuilder/src/teamsdialog.cpp b/Generals/Code/Tools/WorldBuilder/src/teamsdialog.cpp
index 63b62e8f2d9..f8e2189b643 100644
--- a/Generals/Code/Tools/WorldBuilder/src/teamsdialog.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/teamsdialog.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include "TeamGeneric.h"
#include "TeamIdentity.h"
#include "TeamReinforcement.h"
+#include "TeamObjectProperties.h"
#include "WorldBuilderDoc.h"
#include "CUndoable.h"
#include "wbview3d.h"
@@ -296,7 +297,7 @@ void CTeamsDialog::OnDeleteteam()
void CTeamsDialog::OnEditTemplate()
{
CPropertySheet editDialog;
- editDialog.Construct("Edit Team:");
+ editDialog.Construct("Edit Team Template.");
TeamIdentity identity;
identity.setTeamDict(m_sides.getTeamInfo(m_curTeam)->getDict());
identity.setSidesList(&m_sides);
@@ -308,10 +309,13 @@ void CTeamsDialog::OnEditTemplate()
TeamGeneric generic;
generic.setTeamDict(m_sides.getTeamInfo(m_curTeam)->getDict());
+ TeamObjectProperties object(m_sides.getTeamInfo(m_curTeam)->getDict());
+
editDialog.AddPage(&identity);
editDialog.AddPage(&reinforcements);
editDialog.AddPage(&behavior);
editDialog.AddPage(&generic);
+ editDialog.AddPage(&object);
if (IDOK == editDialog.DoModal()) {
}
diff --git a/Generals/Code/Tools/WorldBuilder/src/wbview.cpp b/Generals/Code/Tools/WorldBuilder/src/wbview.cpp
index a087a7cb8f9..5796898fd7a 100644
--- a/Generals/Code/Tools/WorldBuilder/src/wbview.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/wbview.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -20,7 +20,9 @@
//
#include "StdAfx.h"
+#include "resource.h"
#include "CUndoable.h"
+#include "CFixTeamOwnerDialog.h"
#include "WorldBuilder.h"
#include "WorldBuilderDoc.h"
#include "wbview.h"
@@ -32,6 +34,7 @@
#include "GlobalLightOptions.h"
#include "playerlistdlg.h"
#include "teamsdialog.h"
+#include "LayersList.h"
Bool WbView::m_snapToGrid = false;
@@ -46,7 +49,8 @@ WbView::WbView() :
m_hysteresis(0),
m_lockAngle(false),
m_doLightFeedback(FALSE),
- m_pickConstraint(ES_NONE)
+ m_pickConstraint(ES_NONE),
+ m_doRulerFeedback(RULER_NONE)
{
Int showWay = ::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowWaypoints", 1);
m_showWaypoints = (showWay!=0);
@@ -105,6 +109,7 @@ BEGIN_MESSAGE_MAP(WbView, CView)
ON_COMMAND(ID_EDIT_PLAYERLIST, OnEditPlayerlist)
ON_COMMAND(ID_EDIT_WORLDINFO, OnEditWorldinfo)
ON_COMMAND(ID_EDIT_TEAMLIST, OnEditTeamlist)
+ ON_COMMAND(ID_TEAM_EDIT, OnEditTeamlist)
ON_UPDATE_COMMAND_UI(ID_OBJECTPROPERTIES_REFLECTSINMIRROR, OnUpdateObjectpropertiesReflectsinmirror)
ON_COMMAND(ID_EDIT_PICKSTRUCTS, OnPickStructures)
ON_UPDATE_COMMAND_UI(ID_EDIT_PICKSTRUCTS, OnUpdatePickStructures)
@@ -208,6 +213,19 @@ void WbView::mouseMove(TTrackingMode m, CPoint viewPt)
if (CMainFrame::GetMainFrame()->isAutoSaving()) {
return;
}
+
+ if (m_doRulerFeedback != RULER_NONE) {
+ // If the user is measuring stuff, no need to do the rest of the text.
+ CString str;
+ if (m_doRulerFeedback == RULER_CIRCLE) {
+ str.Format("Diameter (in feet): %f", m_rulerLength * 2.0f);
+ } else {
+ str.Format("Length (in feet): %f", m_rulerLength);
+ }
+ CMainFrame::GetMainFrame()->SetMessageText(str);
+ return;
+ }
+
// Generate the status text display with coordinates and height.
Coord3D cpt;
viewToDocCoords(viewPt, &cpt);
@@ -244,7 +262,12 @@ void WbView::mouseMove(TTrackingMode m, CPoint viewPt)
}
Real height = TheTerrainRenderObject->getHeightMapHeight(cpt.x, cpt.y, nullptr);
CString str, str2, str3;
- str.Format("%d object(s), ", totalObjects);
+ // If a layer has been activated, display it.
+ if (strcmp(AsciiString::TheEmptyString.str(), LayersList::TheActiveLayerName.c_str()) != 0) {
+ str.Format("Active Layer: (%s) %d object(s), ", LayersList::TheActiveLayerName.c_str(), totalObjects);
+ } else {
+ str.Format("%d object(s), ", totalObjects);
+ }
str2.Format("%d waypoint(s), ", totalWaypoints);
str3.Format("(%.2f,%.2f), height %.2f", cpt.x, cpt.y, height);
str += str2;
@@ -910,25 +933,116 @@ void WbView::OnUpdateShowNames(CCmdUI* pCmdUI)
void WbView::OnValidationFixTeams()
{
- std::vector allTeamDicts;
- Int numTeams = TheSidesList->getNumTeams();
- // Get all team dicts in the map
- for (Int i = 0; i < numTeams; ++i)
+ Bool anyFixes = false;
+ Int i;
+ // Check for duplicate teams.
+ for (i = 0; i < TheSidesList->getNumTeams(); ++i)
{
- allTeamDicts.push_back(TheSidesList->getTeamInfo(i)->getDict());
+ Dict *d = TheSidesList->getTeamInfo(i)->getDict();
+
+ AsciiString tname = d->getAsciiString(TheKey_teamName);
+ Int j;
+ for (j=0; jgetTeamInfo(j)->getDict();
+ if (prevd->getAsciiString(TheKey_teamName).compare(tname)==0) {
+ anyFixes = true;
+ CString msg;
+ msg.Format(IDS_DUPLICATE_TEAM_REMOVED, tname.str());
+ AfxMessageBox(msg, MB_OK);
+ TheSidesList->removeTeam(i);
+ i--;
+ break;
+ }
+ }
}
- Dict newDict;
- newDict.setBool(TheKey_teamExecutesActionsOnCreate, false);
+ // Check for teams with invalid owners.
+ for (i = 0; i < TheSidesList->getNumTeams(); ++i)
+ {
+ Dict *d = TheSidesList->getTeamInfo(i)->getDict();
+ AsciiString oname = d->getAsciiString(TheKey_teamOwner);
+ AsciiString tname = d->getAsciiString(TheKey_teamName);
+ SidesInfo* pSide = TheSidesList->findSideInfo(oname);
+ Bool found = pSide!=nullptr;
+ if (!found) {
+ CString msg;
+ msg.Format(IDS_PLAYERLESS_TEAM_REMOVED, tname.str(), oname.str());
+ AfxMessageBox(msg, MB_OK);
+ anyFixes = true;
+ TheSidesList->removeTeam(i);
+ i--;
+ }
+ }
+
+ // Check for objects with invalid teams. [8/8/2003]
+ MapObject *pMapObj;
+ for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext())
+ {
+ // there is no validation code for these items as of yet.
+ if (pMapObj->isScorch() || pMapObj->isWaypoint() || pMapObj->isLight() || pMapObj->getFlag(FLAG_ROAD_FLAGS) || pMapObj->getFlag(FLAG_BRIDGE_FLAGS))
+ {
+ continue;
+ }
+
+ if (pMapObj->getThingTemplate()==nullptr) {
+ continue; // Objects that don't have templates don't need teams. [8/8/2003]
+ }
+ // at this point, only objects with models and teams should be left to process
+
+ AsciiString name = pMapObj->getName();
+ AsciiString tmplName = pMapObj->getThingTemplate()->getName();
+
+ // the following code verifies and fixes the team name, player name, and faction linkages
+ Bool teamExists;
+ AsciiString teamName = pMapObj->getProperties()->getAsciiString(TheKey_originalOwner, &teamExists);
+ if (teamExists) {
+ TeamsInfo *teamInfo = TheSidesList->findTeamInfo(teamName);
+ if (teamInfo) {
+ AsciiString teamOwner = teamInfo->getDict()->getAsciiString(TheKey_teamOwner);
+ SidesInfo* pSide = TheSidesList->findSideInfo(teamOwner);
+ if (!pSide) {
+ teamExists = false;
+ DEBUG_LOG(("Side '%s' could not be found in sides list!", teamOwner.str()));
+ }
+ } else {
+ // Couldn't find team. [8/8/2003]
+ teamExists = false;
+ }
+ } else {
+ // Object doesn't even have a team name at all. bad. jba. [8/8/2003]
+ teamExists = false;
+ }
+ if (!teamExists) {
+ // Query the user for a player, and stick it on the default team. [8/8/2003]
+ AsciiString warning;
+ warning.format("Object '%s' named '%s' on team '%s' - team doesn't exist. Select player for object...",
+ tmplName.str(), name.str(), teamName.str());
+
+ anyFixes = true;
+ ::AfxMessageBox(warning.str(), MB_OK);
+ TeamsInfo ti;
+ CFixTeamOwnerDialog fix(&ti, TheSidesList);
+ if (fix.DoModal() == IDOK) {
+ if (fix.pickedValidTeam()) {
+ AsciiString team;
+ team.set("team");
+ team.concat(fix.getSelectedOwner());
+ if (TheSidesList->findTeamInfo(team)==nullptr) {
+ team.set("team"); // neutral.
+ }
+ pMapObj->getProperties()->setAsciiString(TheKey_originalOwner, team);
+ }
+ }
+ }
+ }
- // Now, do the Undoable
- CWorldBuilderDoc* pDoc = CWorldBuilderDoc::GetActiveDoc();
- DictItemUndoable *pUndo = new DictItemUndoable(&allTeamDicts.front(), newDict, newDict.getNthKey(0), allTeamDicts.size(), pDoc, true);
- pDoc->AddAndDoUndoable(pUndo);
- REF_PTR_RELEASE(pUndo); // belongs to pDoc now.
- // Show a message indicating success.
- AfxMessageBox(IDS_TEAMS_FIXED);
+ if (anyFixes) {
+ // Show a message indicating success.
+ AfxMessageBox(IDS_TEAMS_FIXED, MB_OK|MB_ICONWARNING);
+ } else {
+ AfxMessageBox(IDS_NO_PROBLEMS, MB_OK);
+ }
}
void WbView::OnShowTerrain()
@@ -963,3 +1077,9 @@ int WbView::OnCreate(LPCREATESTRUCT lpcs)
return CView::OnCreate(lpcs);
}
+void WbView::rulerFeedbackInfo(Coord3D &point1, Coord3D &point2, Real dist)
+{
+ m_rulerPoints[0] = point1;
+ m_rulerPoints[1] = point2;
+ m_rulerLength = dist;
+}
diff --git a/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp b/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp
index 1d824b032f0..ccfe7c33acb 100644
--- a/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp
@@ -1,5 +1,5 @@
/*
-** Command & Conquer Generals(tm)
+** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
@@ -29,6 +29,7 @@
#include "WW3D2/intersec.h"
#include "W3DDevice/GameClient/W3DAssetManager.h"
#include "W3DDevice/GameClient/Module/W3DModelDraw.h"
+#include "W3DDevice/GameClient/Module/W3DTreeDraw.h"
#include "WW3D2/agg_def.h"
#include "WW3D2/part_ldr.h"
#include "WW3D2/hanim.h"
@@ -203,17 +204,17 @@ class PlaceholderView : public View
virtual void initHeightForMap() override {}; ///< Init the camera height for the map at the current position.
virtual void scrollBy( Coord2D *delta ){}; ///< Shift the view by the given delta
virtual void moveCameraTo(const Coord3D *o, Int frames, Int shutter,
- Bool orient) {lookAt(o);};
+ Bool orient, Real easeIn, Real easeOut) override {lookAt(o);};
virtual void moveCameraAlongWaypointPath(Waypoint *way, Int frames, Int shutter,
- Bool orient) {};
+ Bool orient, Real easeIn, Real easeOut) override {};
virtual Bool isCameraMovementFinished() override {return true;};
- virtual void resetCamera(const Coord3D *location, Int frames) {}; ///< Move camera to location, and reset to default angle & zoom.
- virtual void rotateCamera(Real rotations, Int frames) {}; ///< Rotate camera about current viewpoint.
- virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds) {}; ///< Rotate camera to face an object, and hold on it
- virtual void cameraModFinalZoom(Real finalZoom){}; ///< Final zoom for current camera movement.
+ virtual void resetCamera(const Coord3D *location, Int frames, Real easeIn, Real easeOut) override {}; ///< Move camera to location, and reset to default angle & zoom.
+ virtual void rotateCamera(Real rotations, Int frames, Real easeIn, Real easeOut) override {}; ///< Rotate camera about current viewpoint.
+ virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds, Real easeIn, Real easeOut) override {}; ///< Rotate camera to face an object, and hold on it
+ virtual void cameraModFinalZoom(Real finalZoom, Real easeIn, Real easeOut) override {}; ///< Final zoom for current camera movement.
virtual void cameraModRollingAverage(Int framesToAverage) override {}; ///< Number of frames to average movement for current camera movement.
virtual void cameraModFinalTimeMultiplier(Int finalMultiplier) override {}; ///< Final time multiplier for current camera movement.
- virtual void cameraModFinalPitch(Real finalPitch){}; ///< Final pitch for current camera movement.
+ virtual void cameraModFinalPitch(Real finalPitch, Real easeIn, Real easeOut) override {}; ///< Final pitch for current camera movement.
virtual void cameraModFreezeTime() override {} ///< Freezes time during the next camera movement.
virtual void cameraModFreezeAngle() override {} ///< Freezes time during the next camera movement.
virtual void cameraModLookToward(Coord3D *pLoc) override {} ///< Sets a look at point during camera movement.
@@ -223,8 +224,8 @@ class PlaceholderView : public View
virtual Int getTimeMultiplier() override {return 1;}; ///< Get the time multiplier.
virtual void setTimeMultiplier(Int multiple) override {}; ///< Set the time multiplier.
virtual void setDefaultView(Real pitch, Real angle, Real maxHeight) override {};
- virtual void zoomCamera( Real finalZoom, Int milliseconds ) {};
- virtual void pitchCamera( Real finalPitch, Int milliseconds ) {};
+ virtual void zoomCamera( Real finalZoom, Int milliseconds, Real easeIn, Real easeOut ) override {};
+ virtual void pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real easeOut ) override {};
virtual void setAngle( Real angle ) override {}; ///< Rotate the view around the up axis to the given angle
virtual Real getAngle() override { return 0; }
@@ -399,7 +400,13 @@ WbView3d::WbView3d() :
m_curTrackingZ(10),
m_ww3dInited(false),
m_showLayersList(false),
- m_showMapBoundaries(false)
+ m_showMapBoundaries(false),
+ m_showBoundingBoxes(false),
+ m_showSightRanges(false),
+ m_showWeaponRanges(false),
+ m_highlightTestArt(false),
+ m_showLetterbox(false),
+ m_showSoundCircles(false)
{
TheTacticalView = &bogusTacticalView;
m_actualWinSize.x = ::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "Width", THREE_D_VIEW_WIDTH);
@@ -416,10 +423,17 @@ WbView3d::WbView3d() :
m_showEntireMap = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowEntireMap", 1) != 0);
m_projection = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowTopDownView", 0) != 0);
m_showShadows = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowShadows", 1) != 0);
+ TheWritableGlobalData->m_useShadowDecals = m_showShadows;
+ TheWritableGlobalData->m_useShadowVolumes = m_showShadows;
TheWritableGlobalData->m_showSoftWaterEdge = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowSoftWater", 1) != 0);
TheWritableGlobalData->m_use3WayTerrainBlends = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowExtraBlends", 1) > 1 ? 2 : 1);
setShowModels(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowModels", 1) != 0);
+ setShowBoundingBoxes(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowBoundingBoxes", 0) != 0);
+ setShowSightRanges(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowSightRanges", 0) != 0);
+ setShowWeaponRanges(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowWeaponRanges", 0) != 0);
setShowGarrisoned(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowGarrisoned", 0) != 0);
+ setHighlightTestArt(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "HighlightTestArt", 0) != 0);
+ setShowLetterbox(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowLetterbox", 0) != 0);
}
// ----------------------------------------------------------------------------
@@ -432,13 +446,27 @@ WbView3d::~WbView3d()
REF_PTR_RELEASE(m_lightFeedbackMesh[i]);
}
}
-
+ REF_PTR_RELEASE(m_drawObject) ;
+ REF_PTR_RELEASE(m_heightMapRenderObj);
W3DShaderManager::shutdown();
shutdownWW3D();
}
// ----------------------------------------------------------------------------
void WbView3d::shutdownWW3D()
{
+ delete m_intersector;
+ m_intersector = nullptr;
+
+ delete m_layer;
+ m_layer = nullptr;
+
+ delete m_buildLayer;
+ m_buildLayer = nullptr;
+
+ if (m3DFont) {
+ m3DFont->Release();
+ m3DFont = nullptr;
+ }
if (m_ww3dInited) {
m_lightList.Reset_List();
@@ -473,20 +501,6 @@ void WbView3d::shutdownWW3D()
WWMath::Shutdown();
}
m_ww3dInited = false;
-
- delete m_intersector;
- m_intersector = nullptr;
-
- delete m_layer;
- m_layer = nullptr;
-
- delete m_buildLayer;
- m_buildLayer = nullptr;
-
- if (m3DFont) {
- m3DFont->Release();
- m3DFont = nullptr;
- }
}
//=============================================================================
@@ -503,6 +517,9 @@ void WbView3d::ReleaseResources()
m3DFont->Release();
}
m3DFont = nullptr;
+ if (m_drawObject) {
+ m_drawObject->freeMapResources();
+ }
}
//=============================================================================
@@ -517,6 +534,7 @@ void WbView3d::ReAcquireResources()
TheTerrainRenderObject->loadRoadsAndBridges(nullptr,FALSE);
TheTerrainRenderObject->worldBuilderUpdateBridgeTowers( m_assetManager, m_scene );
}
+ m_drawObject->initData();
IDirect3DDevice8* pDev = DX8Wrapper::_Get_D3D_Device8();
if (pDev) {
@@ -637,7 +655,7 @@ void WbView3d::setupCamera()
pos.y = m_centerPt.Y* MAP_XY_FACTOR;
pos.z = m_centerPt.Z* MAP_XY_FACTOR;
- Real groundLevel = getHeightAroundPos(m_heightMapRenderObj, pos.x, pos.y);
+ Real groundLevel = m_heightMapRenderObj?getHeightAroundPos(m_heightMapRenderObj, pos.x, pos.y) : 0;
// set position of camera itself
/*
@@ -703,7 +721,7 @@ void WbView3d::setupCamera()
// build new camera transform
camtransform.Make_Identity();
- if (factor+zOffset < 0) {
+ if (factor < 0) { //WST 11/11/02. Fix camera flipping over when near the ground too early
targetPos = sourcePos + (sourcePos-targetPos);
}
camtransform.Look_At( sourcePos, targetPos, 0 );
@@ -715,17 +733,21 @@ void WbView3d::setupCamera()
m_camera->Get_Clip_Planes(nearZ, farZ);
m_camera->Set_Clip_Planes(lookDistance/200, lookDistance*3);
- if (m_projection) {
- camtransform.Make_Identity();
- camtransform.Set_Translation(Vector3(targetPos.X, targetPos.Y, lookDistance));
- m_heightMapRenderObj->setFlattenHeights(true);
- //m_camera->Set_Projection_Type(CameraClass::ORTHO);
- } else {
- m_heightMapRenderObj->setFlattenHeights(false);
- //m_camera->Set_Projection_Type(CameraClass::PERSPECTIVE);
+ if (m_heightMapRenderObj) {
+ if (m_projection) {
+ camtransform.Make_Identity();
+ camtransform.Set_Translation(Vector3(targetPos.X, targetPos.Y, lookDistance));
+ m_heightMapRenderObj->setFlattenHeights(true);
+ //m_camera->Set_Projection_Type(CameraClass::ORTHO);
+ } else {
+ m_heightMapRenderObj->setFlattenHeights(false);
+ //m_camera->Set_Projection_Type(CameraClass::PERSPECTIVE);
+ }
}
m_camera->Set_Transform( camtransform );
- m_heightMapRenderObj->setDrawEntireMap(m_showEntireMap);
+ if (m_heightMapRenderObj) {
+ m_heightMapRenderObj->setDrawEntireMap(m_showEntireMap);
+ }
// not needed, handled in OnSize
// m_camera->Set_Aspect_Ratio((float)m_actualWinSize.x/(float)m_actualWinSize.y);
}
@@ -823,8 +845,11 @@ void WbView3d::resetRenderObjects()
TheW3DShadowManager->Reset();
updateLights();
- if (m_heightMapRenderObj)
+ if (m_heightMapRenderObj) {
m_scene->Add_Render_Object(m_heightMapRenderObj);
+ m_heightMapRenderObj->removeAllTrees();
+ m_heightMapRenderObj->removeAllProps();
+ }
}
// ----------------------------------------------------------------------------
@@ -978,6 +1003,40 @@ void WbView3d::updateScorches()
}
}
+// ----------------------------------------------------------------------------
+void WbView3d::updateTrees()
+{
+ TheTerrainRenderObject->removeAllTrees();
+ TheTerrainRenderObject->removeAllProps();
+ MapObject *pMapObj;
+ for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext())
+ {
+ const ThingTemplate *tTemplate;
+
+ tTemplate = pMapObj->getThingTemplate();
+ if (tTemplate && tTemplate->isKindOf(KINDOF_OPTIMIZED_TREE) )
+ {
+ Real scale = tTemplate->getAssetScale();
+ const ModuleInfo& mi = tTemplate->getDrawModuleInfo();
+ if (mi.getCount() > 0)
+ {
+ const ModuleData* mdd = mi.getNthData(0);
+ AsciiString name = KEYNAME(mdd->getModuleTagNameKey());
+ const W3DTreeDrawModuleData* md = mdd ? mdd->getAsW3DTreeDrawModuleData(): nullptr;
+ if (md)
+ {
+ Coord3D pos = *pMapObj->getLocation();
+ if (m_heightMapRenderObj) {
+ pos.z += m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, nullptr);
+ TheTerrainRenderObject->addTree((DrawableID)(Int)pMapObj, pos, scale, pMapObj->getAngle(),
+ 0.0f /*no random scaling*/, md);
+ }
+ }
+ }
+ }
+ }
+}
+
// ----------------------------------------------------------------------------
void WbView3d::invalidateCellInView(int xIndex, int yIndex)
{
@@ -1001,7 +1060,7 @@ void WbView3d::updateFenceListObjects(MapObject *pObject)
AsciiString modelName = getModelNameAndScale(pMapObj, &scale, BODY_PRISTINE);
// set render object, or create if we need to
if( renderObj == nullptr && modelName.isEmpty() == FALSE &&
- strncmp( modelName.str(), "No ", 3 ) != 0 )
+ strncmp( modelName.str(), "No ", 3 ) )
{
renderObj = m_assetManager->Create_Render_Obj( modelName.str(), scale, 0);
@@ -1061,6 +1120,14 @@ AsciiString WbView3d::getBestModelName(const ThingTemplate* tt, const ModelCondi
{
return md->getBestModelNameForWB(c);
}
+
+ // TheSuperHackers @bugfix ViTeXFTW 15/02/2026 Fix tree objects not showing a preview in
+ // WB object placer. The W3DTreeDraw module stores its model name differently from W3DModelDraw.
+ const W3DTreeDrawModuleData* treeData = mdd ? mdd->getAsW3DTreeDrawModuleData() : nullptr;
+ if (treeData)
+ {
+ return treeData->m_modelName;
+ }
}
}
// removing this crash as sounds can (and should) have no model - jkmcd
@@ -1127,7 +1194,7 @@ void WbView3d::invalBuildListItemInView(BuildListInfo *pBuildToInval)
}
// set render object, or create if we need to
if( renderObj == nullptr && modelName.isEmpty() == FALSE &&
- strncmp( modelName.str(), "No ", 3 ) != 0 )
+ strncmp( modelName.str(), "No ", 3 ) )
{
renderObj = m_assetManager->Create_Render_Obj( modelName.str(), scale, playerColor);
@@ -1289,6 +1356,7 @@ AsciiString WbView3d::getModelNameAndScale(MapObject *pMapObj, Real *scale, Body
void WbView3d::invalObjectInView(MapObject *pMapObjIn)
{
++m_updateCount;
+ Bool updateAllTrees = false;
if (m_heightMapRenderObj == nullptr) {
m_heightMapRenderObj = NEW_REF(WBHeightMap,());
@@ -1306,6 +1374,7 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn)
MapObject *pMapObj;
for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext())
{
+ if (found) break;
if (pMapObjIn == pMapObj)
found = true;
if (pMapObjIn != nullptr && !found) {
@@ -1330,6 +1399,15 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn)
Coord3D loc = *pMapObj->getLocation();
loc.z += m_heightMapRenderObj->getHeightMapHeight(loc.x, loc.y, nullptr);
+ const ThingTemplate *tTemplate = pMapObj->getThingTemplate();
+ if (tTemplate && tTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) {
+ if (!m_heightMapRenderObj->updateTreePosition((DrawableID)(Int)pMapObj, loc, pMapObj->getAngle())) {
+ // Couldn't find it, so update them all. [5/27/2003]
+ updateAllTrees = true;
+ }
+ if (found) break;
+ }
+
RenderObjClass *renderObj=nullptr;
Shadow *shadowObj=nullptr;
@@ -1337,62 +1415,60 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn)
Int playerColor = 0xFFFFFF;
BodyDamageType curDamageState = BODY_PRISTINE;
Bool isVehicle = false;
- if (pMapObj)
+
+ Bool exists;
+ if (tTemplate && !(pMapObj->getFlags() & FLAG_DONT_RENDER))
{
- Bool exists;
- const ThingTemplate* tt = pMapObj->getThingTemplate();
- if (tt && !(pMapObj->getFlags() & FLAG_DONT_RENDER))
- {
- isVehicle = tt->isKindOf(KINDOF_VEHICLE);
- AsciiString objectTeamName = pMapObj->getProperties()->getAsciiString(TheKey_originalOwner, &exists);
- if (exists) {
- TeamsInfo *teamInfo = TheSidesList->findTeamInfo(objectTeamName);
- if (teamInfo) {
- AsciiString teamOwner = teamInfo->getDict()->getAsciiString(TheKey_teamOwner);
- SidesInfo* pSide = TheSidesList->findSideInfo(teamOwner);
- if (pSide) {
- Bool hasColor = false;
- Int color = pSide->getDict()->getInt(TheKey_playerColor, &hasColor);
- if (hasColor) {
- playerColor = color;
- } else {
- AsciiString tmplname = pSide->getDict()->getAsciiString(TheKey_playerFaction);
- const PlayerTemplate* pt = ThePlayerTemplateStore->findPlayerTemplate(NAMEKEY(tmplname));
- if (pt) {
- playerColor = pt->getPreferredColor()->getAsInt();
- }
+ isVehicle = tTemplate->isKindOf(KINDOF_VEHICLE);
+ AsciiString objectTeamName = pMapObj->getProperties()->getAsciiString(TheKey_originalOwner, &exists);
+ if (exists) {
+ TeamsInfo *teamInfo = TheSidesList->findTeamInfo(objectTeamName);
+ if (teamInfo) {
+ AsciiString teamOwner = teamInfo->getDict()->getAsciiString(TheKey_teamOwner);
+ SidesInfo* pSide = TheSidesList->findSideInfo(teamOwner);
+ if (pSide) {
+ Bool hasColor = false;
+ Int color = pSide->getDict()->getInt(TheKey_playerColor, &hasColor);
+ if (hasColor) {
+ playerColor = color;
+ } else {
+ AsciiString tmplname = pSide->getDict()->getAsciiString(TheKey_playerFaction);
+ const PlayerTemplate* pt = ThePlayerTemplateStore->findPlayerTemplate(NAMEKEY(tmplname));
+ if (pt) {
+ playerColor = pt->getPreferredColor()->getAsInt();
}
}
}
}
}
- Int health = 100;
- health = pMapObj->getProperties()->getInt(TheKey_objectInitialHealth, &exists);
- Real ratio = health/100.0;
- if (ratio > TheGlobalData->m_unitDamagedThresh)
- {
- curDamageState = BODY_PRISTINE;
- }
- else if (ratio > TheGlobalData->m_unitReallyDamagedThresh)
- {
- curDamageState = BODY_DAMAGED;
- }
- else if (ratio > 0.0f)
- {
- curDamageState = BODY_REALLYDAMAGED;
- }
- else
- {
- curDamageState = BODY_RUBBLE;
- }
-
}
+ Int health = 100;
+ health = pMapObj->getProperties()->getInt(TheKey_objectInitialHealth, &exists);
+ Real ratio = health/100.0;
+ if (ratio > TheGlobalData->m_unitDamagedThresh)
+ {
+ curDamageState = BODY_PRISTINE;
+ }
+ else if (ratio > TheGlobalData->m_unitReallyDamagedThresh)
+ {
+ curDamageState = BODY_DAMAGED;
+ }
+ else if (ratio > 0.0f)
+ {
+ curDamageState = BODY_REALLYDAMAGED;
+ }
+ else
+ {
+ curDamageState = BODY_RUBBLE;
+ }
+
+
if (!renderObj) {
Real scale = 1.0;
AsciiString modelName = getModelNameAndScale(pMapObj, &scale, curDamageState);
// set render object, or create if we need to
if( renderObj == nullptr && modelName.isEmpty() == FALSE &&
- strncmp( modelName.str(), "No ", 3 ) != 0 )
+ strncmp( modelName.str(), "No ", 3 ) )
{
if (!getShowModels()) {
@@ -1404,7 +1480,6 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn)
Shadow::ShadowTypeInfo shadowInfo;
shadowInfo.allowUpdates=FALSE; //shadow image will never update
shadowInfo.allowWorldAlign=TRUE; //shadow image will wrap around world objects
- const ThingTemplate *tTemplate = pMapObj->getThingTemplate();
if (tTemplate && tTemplate->getShadowType() != SHADOW_NONE && !(pMapObj->getFlags() & FLAG_DONT_RENDER))
{ //add correct type of shadow
strlcpy(shadowInfo.m_ShadowName, tTemplate->getShadowTextureName().str(), ARRAY_SIZE(shadowInfo.m_ShadowName));
@@ -1456,6 +1531,10 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn)
if (pMapObjIn->getFlags() & (FLAG_ROAD_FLAGS|FLAG_BRIDGE_FLAGS)) {
isRoad = true;
}
+ const ThingTemplate *tTemplate = pMapObjIn->getThingTemplate();
+ if (tTemplate && tTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) {
+ updateAllTrees = true;
+ }
}
if (!found && pMapObjIn && pMapObjIn->getRenderObj()) {
if( m_showShadows ) {
@@ -1471,6 +1550,9 @@ void WbView3d::invalObjectInView(MapObject *pMapObjIn)
if (isRoad) {
m_needToLoadRoads = true; // load roads next time we redraw.
}
+ if (updateAllTrees) {
+ updateTrees();
+ }
if (isLight) {
updateLights();
}
@@ -1488,7 +1570,6 @@ void WbView3d::updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const
{
if (htMap == nullptr)
return;
-
++m_updateCount;
if (m_heightMapRenderObj == nullptr) {
@@ -1675,7 +1756,7 @@ Bool WbView3d::viewToDocCoords(CPoint curPt, Coord3D *newPt, Bool constrain)
if (WbApp()->isCurToolLocked()) {
followTerrain = WbApp()->getCurTool()->followsTerrain();
}
- if (followTerrain) {
+ if (followTerrain && TheTerrainRenderObject) {
CastResultStruct castResult;
RayCollisionTestClass rayCollide(ray, &castResult) ;
if( TheTerrainRenderObject->Cast_Ray(rayCollide) )
@@ -1905,6 +1986,7 @@ void WbView3d::updateHysteresis()
// ----------------------------------------------------------------------------
Bool WbView3d::docToViewCoords(Coord3D curPt, CPoint* newPt)
{
+ Bool coordInsideFrustum = true;
Vector3 world;
Vector3 screen;
newPt->x = -1000;
@@ -1914,7 +1996,11 @@ Bool WbView3d::docToViewCoords(Coord3D curPt, CPoint* newPt)
}
world.Set( curPt.x, curPt.y, curPt.z );
- if (m_camera->Project( screen, world ) != CameraClass::INSIDE_FRUSTUM) return false;
+ if (m_camera->Project( screen, world ) != CameraClass::INSIDE_FRUSTUM) {
+ coordInsideFrustum = false;
+ } else {
+ coordInsideFrustum = true;
+ }
CRect rClient;
GetClientRect(&rClient);
@@ -1933,7 +2019,7 @@ Bool WbView3d::docToViewCoords(Coord3D curPt, CPoint* newPt)
newPt->x = rClient.left + sx;
newPt->y = rClient.top + sy;
- return true;
+ return coordInsideFrustum;
}
// ----------------------------------------------------------------------------
@@ -1965,6 +2051,7 @@ void WbView3d::redraw()
Int curTicks = GetTickCount();
RefRenderObjListIterator lightListIt(&m_lightList);
m_heightMapRenderObj->updateCenter(m_camera, &m_cameraTarget, &lightListIt);
+ m_heightMapRenderObj->On_Frame_Update();
--m_updateCount;
curTicks = GetTickCount()-curTicks;
@@ -1975,7 +2062,8 @@ void WbView3d::redraw()
if (m_drawObject) {
m_drawObject->setDrawObjects(m_showObjects,
m_showWaypoints || WaypointTool::isActive(),
- m_showPolygonTriggers || PolygonTool::isActive());
+ m_showPolygonTriggers || PolygonTool::isActive(),
+ m_showBoundingBoxes, m_showSightRanges, m_showWeaponRanges, m_showSoundCircles, m_highlightTestArt, m_showLetterbox);
}
WW3D::Update_Logic_Frame_Time(TheFramePacer->getLogicTimeStepMilliseconds());
@@ -2109,6 +2197,16 @@ BEGIN_MESSAGE_MAP(WbView3d, WbView)
ON_UPDATE_COMMAND_UI(ID_VIEW_PARTIALMAPSIZE_128X128, OnUpdateViewPartialmapsize128x128)
ON_COMMAND(ID_VIEW_SHOWMODELS, OnViewShowModels)
ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWMODELS, OnUpdateViewShowModels)
+ ON_COMMAND(ID_VIEW_BOUNDINGBOXES, OnViewBoundingBoxes)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_BOUNDINGBOXES, OnUpdateViewBoundingBoxes)
+ ON_COMMAND(ID_VIEW_SIGHTRANGES, OnViewSightRanges)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SIGHTRANGES, OnUpdateViewSightRanges)
+ ON_COMMAND(ID_VIEW_WEAPONRANGES, OnViewWeaponRanges)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_WEAPONRANGES, OnUpdateViewWeaponRanges)
+ ON_COMMAND(ID_HIGHLIGHT_TESTART, OnHighlightTestArt)
+ ON_UPDATE_COMMAND_UI(ID_HIGHLIGHT_TESTART, OnUpdateHighlightTestArt)
+ ON_COMMAND(ID_SHOW_LETTERBOX, OnShowLetterbox)
+ ON_UPDATE_COMMAND_UI(ID_SHOW_LETTERBOX, OnUpdateShowLetterbox)
ON_COMMAND(ID_VIEW_GARRISONED, OnViewGarrisoned)
ON_UPDATE_COMMAND_UI(ID_VIEW_GARRISONED, OnUpdateViewGarrisoned)
ON_COMMAND(ID_VIEW_LAYERS_LIST, OnViewLayersList)
@@ -2117,6 +2215,8 @@ BEGIN_MESSAGE_MAP(WbView3d, WbView)
ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWMAPBOUNDARIES, OnUpdateViewShowMapBoundaries)
ON_COMMAND(ID_VIEW_SHOWAMBIENTSOUNDS, OnViewShowAmbientSounds)
ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWAMBIENTSOUNDS, OnUpdateViewShowAmbientSounds)
+ ON_COMMAND(ID_VIEW_SHOW_SOUND_CIRCLES, OnViewShowSoundCircles)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHOW_SOUND_CIRCLES, OnUpdateViewShowSoundCircles)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -2258,6 +2358,7 @@ int WbView3d::OnCreate(LPCREATESTRUCT lpCreateStruct)
m_showLayersList = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowLayersList", 0);
m_showMapBoundaries = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowMapBoundaries", 0);
m_showAmbientSounds = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowAmbientSounds", 0);
+ m_showSoundCircles = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowSoundCircles", 0);
DrawObject::setDoBoundaryFeedback(m_showMapBoundaries);
DrawObject::setDoAmbientSoundFeedback(m_showAmbientSounds);
@@ -2283,6 +2384,48 @@ void WbView3d::OnPaint()
}
+//////////////////////////////////////////////////////////////////////////
+/// Draw a (not very good) circle into the hdc
+void WbView3d::drawCircle( HDC hdc, const Coord3D & centerPoint, Real radius, COLORREF color )
+{
+ CPoint rulerPoints[2];
+ Coord3D pnt;
+ Real angle = 0.0f;
+ Real inc = PI/4.0f;
+
+ // Create and select a correctly colored pen. Remember the old one so that it can be restored.
+ HPEN pen = CreatePen(PS_SOLID, 2, color);
+ HPEN penOld = (HPEN)SelectObject(hdc, pen);
+
+
+ // Get the starting point on the circumference of the circle.
+ pnt.x = centerPoint.x + radius * (Real)cosf(angle);
+ pnt.y = centerPoint.y + radius * (Real)sinf(angle);
+ pnt.z = centerPoint.z;
+ docToViewCoords(pnt, &rulerPoints[0]);
+
+ angle += inc;
+ for(; angle <= 2.0f * PI; angle += inc) {
+ // Get a new point on the circumference of the circle.
+ pnt.x = centerPoint.x + radius * (Real)cosf(angle);
+ pnt.y = centerPoint.y + radius * (Real)sinf(angle);
+ pnt.z = centerPoint.z;
+
+ docToViewCoords(pnt, &rulerPoints[1]);
+
+ ::Polyline(hdc, rulerPoints, 2);
+
+ // Remember the last point to use as the starting point for the next line.
+ rulerPoints[0].x = rulerPoints[1].x;
+ rulerPoints[0].y = rulerPoints[1].y;
+ }
+
+ // Restore previous pen.
+ SelectObject(hdc, penOld);
+ // Delete new pen.
+ DeleteObject(pen);
+}
+
void WbView3d::drawLabels()
{
@@ -2329,7 +2472,7 @@ void WbView3d::drawLabels(HDC hdc)
pos = *pMapObj->getLocation();
pos.z = m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, nullptr);
} else if (pMapObj->getThingTemplate() && !(pMapObj->getFlags() & (FLAG_ROAD_FLAGS|FLAG_BRIDGE_FLAGS)) &&
- pMapObj->getRenderObj() == nullptr) {
+ pMapObj->getRenderObj() == nullptr && !pMapObj->getThingTemplate()->isKindOf(KINDOF_OPTIMIZED_TREE)) {
name = pMapObj->getThingTemplate()->getName();
pos = *pMapObj->getLocation();
pos.z += m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, nullptr);
@@ -2344,7 +2487,7 @@ void WbView3d::drawLabels(HDC hdc)
case 3: name = pMapObj->getProperties()->getAsciiString(TheKey_waypointPathLabel3, &exists); break;
default: name.clear();
}
- if (!name.isEmpty()) {
+ if (!name.isEmpty() && m_showWaypoints) {
CPoint pt;
Vector3 world, screen;
world.Set( pos.x+MAP_XY_FACTOR/2, pos.y, pos.z );
@@ -2414,6 +2557,28 @@ void WbView3d::drawLabels(HDC hdc)
::FrameRect(hdc, &m_feedbackBox, (HBRUSH)brush.GetSafeHandle());
}
+ if (hdc && m_doRulerFeedback) {
+ if (m_doRulerFeedback == RULER_LINE) {
+ // Change world coords to screen viewport coords.
+ CPoint rulerPoints[2];
+ docToViewCoords(m_rulerPoints[0], &rulerPoints[0]);
+ docToViewCoords(m_rulerPoints[1], &rulerPoints[1]);
+
+ // Create and select a green pen. Remember the old one so that it can be restored.
+ HPEN pen = CreatePen(PS_SOLID, 2, RGB(0,255,0));
+ HPEN penOld = (HPEN)SelectObject(hdc, pen);
+ // Draw the line ruler.
+ ::Polyline(hdc, rulerPoints, 2);
+
+ // Restore previous pen.
+ SelectObject(hdc, penOld);
+ // Delete new pen.
+ DeleteObject(pen);
+ } else if (m_doRulerFeedback == RULER_CIRCLE) {
+ drawCircle( hdc, m_rulerPoints[0], m_rulerLength, RGB( 0, 255, 0 ) );
+ }
+ }
+
if (hdc && m_doLightFeedback)
{ //Draw Lines to indicate the direction of each light source
// Int LightColors[MAX_GLOBAL_LIGHTS]={RGB(255,0,0),RGB(0,255,0),RGB(0,0,255)};
@@ -2481,7 +2646,7 @@ void WbView3d::drawLabels(HDC hdc)
}
else
{ if (!m_doLightFeedback)
- { //not in light feedback mode. Make sure the temporary feeback models are gone
+ { //not in light feedback mode. Make sure the temporary feedback models are gone
for (Int lIndex=0; lIndex 2.0f)
+ {
+ m_mouseWheelOffset += zDelta;
+ }
+ else if (getCurrentZoom() > 1.0f)
+ {
+ m_mouseWheelOffset += zDelta/2;
+ }
+ else
+ {
+ m_mouseWheelOffset += zDelta/8;
+ }
+
MSG msg;
while (::PeekMessage(&msg, m_hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE)) {
zDelta = (short) HIWORD(msg.wParam); // wheel rotation
@@ -2616,6 +2795,32 @@ Real WbView3d::getCameraPitch()
return m_FXPitch;
}
+
+//WST 10.17.2002 ----------------------------------------------------------------------------
+Real WbView3d::getCurrentZoom()
+{
+ float zOffset = - m_mouseWheelOffset / 1200; //WST 11/21/02 new triple speed camera zoom.
+ Real zoom = 1.0f;
+ if (zOffset != 0) {
+ Real zPos = (m_cameraOffset.length()-m_groundLevel)/m_cameraOffset.length();
+ Real zAbs = zOffset + zPos;
+ if (zAbs<0) zAbs = -zAbs;
+ if (zAbs<0.01) zAbs = 0.01f;
+ //DEBUG_LOG(("zOffset = %.2f, zAbs = %.2f, zPos = %.2f", zOffset, zAbs, zPos));
+ if (zOffset > 0) {
+ zOffset *= zAbs;
+ } else if (zOffset < -0.3f) {
+ zOffset = -0.15f + zOffset/2.0f;
+ }
+ if (zOffset < -0.6f) {
+ zOffset = -0.3f + zOffset/2.0f;
+ }
+ //DEBUG_LOG(("zOffset = %.2f", zOffset));
+ zoom = zAbs;
+ }
+ return zoom;
+}
+
// ----------------------------------------------------------------------------
void WbView3d::OnTimer(UINT nIDEvent)
{
@@ -2734,12 +2939,12 @@ void WbView3d::OnEditSelectmacrotexture()
void WbView3d::OnLookEast()
{
- m_cameraAngle = -PI/2;
+ m_cameraAngle = -PI / 2;
}
void WbView3d::OnUpdateLookEast(CCmdUI* pCmdUI)
{
- pCmdUI->SetCheck(m_cameraAngle==-PI/2?1:0);
+ pCmdUI->SetCheck(m_cameraAngle == -PI / 2 ? 1 : 0);
}
void WbView3d::OnLookNorth()
@@ -2749,28 +2954,27 @@ void WbView3d::OnLookNorth()
void WbView3d::OnUpdateLookNorth(CCmdUI* pCmdUI)
{
- pCmdUI->SetCheck(m_cameraAngle==0?1:0);
+ pCmdUI->SetCheck(m_cameraAngle == 0 ? 1 : 0);
}
void WbView3d::OnLookSouth()
{
m_cameraAngle = PI;
-
}
void WbView3d::OnUpdateLookSouth(CCmdUI* pCmdUI)
{
- pCmdUI->SetCheck(m_cameraAngle==PI?1:0);
+ pCmdUI->SetCheck(m_cameraAngle == PI ? 1 : 0);
}
void WbView3d::OnLookWest()
{
- m_cameraAngle = PI/2;
+ m_cameraAngle = PI / 2;
}
void WbView3d::OnUpdateLookWest(CCmdUI* pCmdUI)
{
- pCmdUI->SetCheck(m_cameraAngle==PI/2?1:0);
+ pCmdUI->SetCheck(m_cameraAngle == PI / 2 ? 1 : 0);
}
void WbView3d::OnViewShowshadows()
@@ -2791,6 +2995,8 @@ void WbView3d::OnViewShowshadows()
} else {
TheW3DShadowManager->removeAllShadows();
}
+ TheWritableGlobalData->m_useShadowDecals = m_showShadows;
+ TheWritableGlobalData->m_useShadowVolumes = m_showShadows;
::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowShadows", m_showShadows?1:0);
}
@@ -2862,6 +3068,77 @@ void WbView3d::OnUpdateViewShowModels(CCmdUI* pCmdUI)
pCmdUI->SetCheck(getShowModels()?1:0);
}
+// MLL C&C3
+void WbView3d::OnViewBoundingBoxes()
+{
+ setShowBoundingBoxes(!getShowBoundingBoxes());
+ ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowBoundingBoxes", getShowBoundingBoxes()?1:0);
+ resetRenderObjects();
+ invalObjectInView(nullptr);
+}
+// MLL C&C3
+void WbView3d::OnUpdateViewBoundingBoxes(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(getShowBoundingBoxes()?1:0);
+}
+
+
+// MLL C&C3
+void WbView3d::OnViewSightRanges()
+{
+ setShowSightRanges(!getShowSightRanges());
+ ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowSightRanges", getShowSightRanges()?1:0);
+ resetRenderObjects();
+ invalObjectInView(nullptr);
+}
+// MLL C&C3
+void WbView3d::OnUpdateViewSightRanges(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(getShowSightRanges()?1:0);
+}
+
+// MLL C&C3
+void WbView3d::OnViewWeaponRanges()
+{
+ setShowWeaponRanges(!getShowWeaponRanges());
+ ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowWeaponRanges", getShowWeaponRanges()?1:0);
+ resetRenderObjects();
+ invalObjectInView(nullptr);
+}
+// MLL C&C3
+void WbView3d::OnUpdateViewWeaponRanges(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(getShowWeaponRanges()?1:0);
+}
+
+// MLL C&C3
+void WbView3d::OnHighlightTestArt()
+{
+ setHighlightTestArt(!getHighlightTestArt());
+ ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "HighlightTestArt", getHighlightTestArt()?1:0);
+ resetRenderObjects();
+ invalObjectInView(nullptr);
+}
+// MLL C&C3
+void WbView3d::OnUpdateHighlightTestArt(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(getHighlightTestArt()?1:0);
+}
+
+
+// MLL C&C3
+void WbView3d::OnShowLetterbox()
+{
+ setShowLetterbox(!getShowLetterbox());
+ ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowLetterBox", getShowLetterbox()?1:0);
+}
+// MLL C&C3
+void WbView3d::OnUpdateShowLetterbox(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(getShowLetterbox()?1:0);
+}
+
+
void WbView3d::OnViewGarrisoned()
{
setShowGarrisoned(!getShowGarrisoned());
@@ -3018,3 +3295,16 @@ void WbView3d::OnUpdateViewShowAmbientSounds(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_showAmbientSounds ? 1 : 0);
}
+
+void WbView3d::OnViewShowSoundCircles()
+{
+ m_showSoundCircles = !m_showSoundCircles;
+ ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowSoundCircles", m_showSoundCircles ? 1 : 0);
+ resetRenderObjects();
+ invalObjectInView(nullptr);
+}
+
+void WbView3d::OnUpdateViewShowSoundCircles(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_showSoundCircles ? 1 : 0);
+}
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt b/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt
index c377a85c87c..414a3ce89ad 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt
+++ b/GeneralsMD/Code/Tools/WorldBuilder/CMakeLists.txt
@@ -176,6 +176,7 @@ set(WORLDBUILDER_SRC
"include/TeamBehavior.h"
"include/TeamGeneric.h"
"include/TeamIdentity.h"
+ "include/TeamObjectProperties.h"
"include/TeamReinforcement.h"
"include/teamsdialog.h"
"include/TerrainMaterial.h"
@@ -189,6 +190,7 @@ set(WORLDBUILDER_SRC
"include/WaypointTool.h"
"include/WBFrameWnd.h"
"include/WBHeightMap.h"
+ "include/WBPopupSlider.h"
"include/wbview.h"
"include/wbview3d.h"
"include/WHeightMapEdit.h"
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/include/WHeightMapEdit.h b/GeneralsMD/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
index c51ffb3a4d0..68b1044ef4e 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
+++ b/GeneralsMD/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
@@ -147,6 +147,8 @@ class WorldHeightMapEdit : public WorldHeightMap
void reloadTextures(); ///< Reloads textures from disk.
void resetResources(); ///< Releases textures in preparation for device reset.
+ Bool getRawTileData(Short tileNdx, Int width, UnsignedByte *buffer, Int bufLen);
+
void dbgVerifyAfterUndo(); ///< Verifies the structures are still consistent.
Bool doCliffAdjustment(Int xIndex, Int yIndex);
Bool removeCliffMapping();
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h b/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h
index 953fd38c154..7439499c471 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h
+++ b/GeneralsMD/Code/Tools/WorldBuilder/include/wbview3d.h
@@ -109,6 +109,14 @@ class WbView3d : public WbView, public DX8_CleanupHook
afx_msg void OnViewShowmacrotexture();
afx_msg void OnUpdateViewShowmacrotexture(CCmdUI* pCmdUI);
afx_msg void OnEditSelectmacrotexture();
+ afx_msg void OnLookEast();
+ afx_msg void OnUpdateLookEast(CCmdUI* pCmdUI);
+ afx_msg void OnLookNorth();
+ afx_msg void OnUpdateLookNorth(CCmdUI* pCmdUI);
+ afx_msg void OnLookSouth();
+ afx_msg void OnUpdateLookSouth(CCmdUI* pCmdUI);
+ afx_msg void OnLookWest();
+ afx_msg void OnUpdateLookWest(CCmdUI* pCmdUI);
afx_msg void OnViewShowshadows();
afx_msg void OnUpdateViewShowshadows(CCmdUI* pCmdUI);
afx_msg void OnViewShowSoftWater();
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/res/WorldBuilder.rc b/GeneralsMD/Code/Tools/WorldBuilder/res/WorldBuilder.rc
index 6cbb57e5ac1..0918509c0ea 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/res/WorldBuilder.rc
+++ b/GeneralsMD/Code/Tools/WorldBuilder/res/WorldBuilder.rc
@@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE
//
-1 TEXTINCLUDE DISCARDABLE
+1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
-2 TEXTINCLUDE DISCARDABLE
+2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
-3 TEXTINCLUDE DISCARDABLE
+3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
@@ -171,7 +171,7 @@ END
// Menu
//
-IDR_MAPDOC MENU PRELOAD DISCARDABLE
+IDR_MAPDOC MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
@@ -257,7 +257,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "Highlight Test Art", ID_HIGHLIGHT_TESTART
MENUITEM SEPARATOR
- MENUITEM "Show Impassable Areas\tCtrl+I",
+ MENUITEM "Show Impassable Areas\tCtrl+I",
ID_VIEW_SHOWIMPASSABLEAREAS
MENUITEM "Impassable Area Options...", ID_VIEW_IMPASSABLEAREAOPTIONS
@@ -277,6 +277,13 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "Show Wireframe 3D View\tCtrl+W", ID_VIEW_SHOWWIREFRAME
MENUITEM "Show From Top Down View\tCtrl+F", ID_VIEW_SHOWTOPDOWNVIEW
+ POPUP "Camera Direction"
+ BEGIN
+ MENUITEM "Look North", ID_LOOK_NORTH
+ MENUITEM "Look South", ID_LOOK_SOUTH
+ MENUITEM "Look West", ID_LOOK_WEST
+ MENUITEM "Look East", ID_LOOK_EAST
+ END
MENUITEM "Show 3-Way Blends in White", ID_VIEW_SHOWEXTRABLENDS
MENUITEM "Show Clouds\tCtrl+U", ID_VIEW_SHOWCLOUDS
MENUITEM "Show Soft Water", ID_VIEW_SHOWSOFTWATER
@@ -332,7 +339,7 @@ BEGIN
END
END
-IDR_LAYERSLISTPOPUP MENU DISCARDABLE
+IDR_LAYERSLISTPOPUP MENU DISCARDABLE
BEGIN
POPUP "Layers List"
BEGIN
@@ -361,7 +368,7 @@ BEGIN
END
END
-IDR_SCRIPTDIALOGPOPUP MENU DISCARDABLE
+IDR_SCRIPTDIALOGPOPUP MENU DISCARDABLE
BEGIN
POPUP "Layers List"
BEGIN
@@ -375,7 +382,7 @@ END
// Accelerator
//
-IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
+IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"0", ID_EDIT_PICKANYTHING, VIRTKEY, CONTROL, NOINVERT
"1", ID_EDIT_PICKSTRUCTS, VIRTKEY, CONTROL, NOINVERT
@@ -394,7 +401,7 @@ BEGIN
"F", ID_TOGGLE_PITCH_AND_ROTATE, VIRTKEY, NOINVERT
"F", ID_VIEW_SHOWTOPDOWNVIEW, VIRTKEY, CONTROL, NOINVERT
"G", IDM_ShowGrid, VIRTKEY, CONTROL, NOINVERT
- "G", ID_VIEW_SNAPTOGRID, VIRTKEY, SHIFT, CONTROL,
+ "G", ID_VIEW_SNAPTOGRID, VIRTKEY, SHIFT, CONTROL,
NOINVERT
"I", ID_VIEW_SHOWIMPASSABLEAREAS, VIRTKEY, CONTROL, NOINVERT
"J", ID_FILE_JUMPTOGAME, VIRTKEY, CONTROL, NOINVERT
@@ -418,7 +425,7 @@ BEGIN
"W", ID_VIEW_SHOWWIREFRAME, VIRTKEY, CONTROL, NOINVERT
"X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
- "Z", ID_EDIT_REDO, VIRTKEY, SHIFT, CONTROL,
+ "Z", ID_EDIT_REDO, VIRTKEY, SHIFT, CONTROL,
NOINVERT
END
@@ -462,23 +469,23 @@ BEGIN
EDITTEXT IDC_INITIAL_HEIGHT,75,58,26,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
- CONTROL "",IDC_TOP_LEFT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_TOP_LEFT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,53,83,20,18
- CONTROL "",IDC_TOP,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_TOP,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,73,83,20,18
- CONTROL "",IDC_TOP_RIGHT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_TOP_RIGHT,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,93,83,20,18
- CONTROL "",IDC_CENTER_LEFT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_CENTER_LEFT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,53,101,20,18
- CONTROL "",IDC_CENTER,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_CENTER,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,73,101,20,18
- CONTROL "",IDC_CENTER_RIGHT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_CENTER_RIGHT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,93,101,20,18
- CONTROL "",IDC_BOTTOM_LEFT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_BOTTOM_LEFT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,53,119,20,18
- CONTROL "",IDC_BOTTOM,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
+ CONTROL "",IDC_BOTTOM,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE |
WS_TABSTOP,73,119,20,18
- CONTROL "",IDC_BOTTOM_RIGHT,"Button",BS_AUTOCHECKBOX |
+ CONTROL "",IDC_BOTTOM_RIGHT,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,93,119,20,18
LTEXT "Initial height (0-255):",IDC_STATIC,7,59,67,9
LTEXT "Vert (y) size:",IDC_STATIC,7,25,42,9
@@ -521,10 +528,10 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Terrain Material Options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,126
PUSHBUTTON "Swap",IDC_SWAP_TEXTURES,138,138,25,16
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,67,137,65,55
LTEXT "Gravel",IDC_TERRAIN_NAME,70,197,86,9
EDITTEXT IDC_SIZE_EDIT,53,217,17,12,ES_AUTOHSCROLL
@@ -567,16 +574,16 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Object Selection Opts"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,0,5,199,126
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,80,137,57,49
LTEXT "Light Tank",IDC_OBJECT_NAME,65,205,67,9
EDITTEXT IDC_OBJECT_HEIGHT_EDIT,106,191,26,12,ES_AUTOHSCROLL
LTEXT "Height (0==on terrain)",IDC_STATIC,13,193,74,8
LTEXT "Object Name:",IDC_STATIC,13,205,42,9
LTEXT "Default Owner:",IDC_STATIC,13,219,48,8
- COMBOBOX IDC_OWNINGTEAM,13,229,162,104,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_OWNINGTEAM,13,229,162,104,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
END
@@ -601,9 +608,9 @@ STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Replace "
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,174,126
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,15,201,65,55
LTEXT "Gravel",IDC_TERRAIN_NAME,44,185,83,10
DEFPUSHBUTTON "OK",IDOK,129,231,50,14
@@ -672,10 +679,10 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Mesh Mold Options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_MESHMOLD_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_MESHMOLD_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,93
PUSHBUTTON "Apply",IDC_APPLY_MESH,5,224,56,17
- CONTROL "Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | WS_TABSTOP,147,225,40,10
RTEXT "Angle (deg)",IDC_STATIC,5,142,41,10
EDITTEXT IDC_ANGLE_EDIT,50,140,29,12,ES_AUTOHSCROLL
@@ -700,7 +707,7 @@ STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Mactotexture"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TEXTURE_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TEXTURE_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,136,126
DEFPUSHBUTTON "OK",IDOK,5,140,50,14
END
@@ -789,13 +796,13 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,196,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,215,50,14
- LISTBOX IDC_OPEN_LIST,15,26,155,162,LBS_SORT |
+ LISTBOX IDC_OPEN_LIST,15,26,155,162,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
LTEXT "Open Map:",IDC_STATIC,15,15,36,8
PUSHBUTTON "Browse...",IDC_BROWSE,16,195,61,16
- CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,58,6,54,16
- CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,115,6,55,16
END
@@ -806,14 +813,14 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,197,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,214,50,14
- LISTBOX IDC_SAVE_LIST,13,25,157,136,LBS_SORT |
+ LISTBOX IDC_SAVE_LIST,13,25,157,136,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Browse...",IDC_BROWSE,7,197,50,14
GROUPBOX "Map name:",IDC_STATIC,7,166,172,27
EDITTEXT IDC_SAVE_MAP_EDIT,13,175,157,12,ES_AUTOHSCROLL
- CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "System Maps",IDC_SYSTEMMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,66,6,54,16
- CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "User Maps",IDC_USERMAPS,"Button",BS_AUTORADIOBUTTON |
BS_PUSHLIKE,123,6,55,16
LTEXT "Existing maps:",IDC_STATIC,13,15,46,8
END
@@ -824,7 +831,7 @@ CAPTION "Property Edit"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_KEYNAME,38,7,107,14,ES_AUTOHSCROLL
- COMBOBOX IDC_KEYTYPE,38,30,107,153,CBS_DROPDOWNLIST | WS_VSCROLL |
+ COMBOBOX IDC_KEYTYPE,38,30,107,153,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_VALUE,38,50,107,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,162,7,31,14
@@ -841,24 +848,24 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Player List"
FONT 8, "MS Sans Serif"
BEGIN
- LISTBOX IDC_PLAYERS,7,7,275,69,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ LISTBOX IDC_PLAYERS,7,7,275,69,LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
WS_HSCROLL | WS_TABSTOP
PUSHBUTTON "New Player",IDC_NEWPLAYER,7,254,45,14
PUSHBUTTON "Remove Player",IDC_REMOVEPLAYER,56,254,56,14
DEFPUSHBUTTON "OK",IDOK,177,274,51,14
LTEXT "Allies:",IDC_STATIC,7,133,68,8
LTEXT "Enemies:",IDC_STATIC,153,133,78,8
- LISTBOX IDC_ALLIESLIST,7,144,129,40,LBS_SORT | LBS_MULTIPLESEL |
+ LISTBOX IDC_ALLIESLIST,7,144,129,40,LBS_SORT | LBS_MULTIPLESEL |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
- LISTBOX IDC_ENEMIESLIST,153,144,129,40,LBS_SORT |
- LBS_MULTIPLESEL | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
+ LISTBOX IDC_ENEMIESLIST,153,144,129,40,LBS_SORT |
+ LBS_MULTIPLESEL | LBS_NOINTEGRALHEIGHT | WS_VSCROLL |
WS_TABSTOP
- LISTBOX IDC_PLAYER_ATTITUDE_OUT,7,203,129,40,NOT LBS_NOTIFY |
- LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
+ LISTBOX IDC_PLAYER_ATTITUDE_OUT,7,203,129,40,NOT LBS_NOTIFY |
+ LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
WS_TABSTOP
LTEXT "How Player Regard Others:",IDC_STATIC,7,192,86,8
- LISTBOX IDC_PLAYER_ATTITUDE_IN,153,203,129,40,NOT LBS_NOTIFY |
- LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
+ LISTBOX IDC_PLAYER_ATTITUDE_IN,153,203,129,40,NOT LBS_NOTIFY |
+ LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
WS_TABSTOP
LTEXT "How Others Regard Player:",IDC_STATIC,153,192,94,8
PUSHBUTTON "Cancel",IDCANCEL,232,274,50,14
@@ -867,10 +874,10 @@ BEGIN
EDITTEXT IDC_PLAYERDISPLAYNAME,82,100,84,14,ES_AUTOHSCROLL
CONTROL "Is Player computer-controlled?",IDC_PLAYERISCOMPUTER,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,163,87,110,10
- COMBOBOX IDC_PLAYERFACTION,178,110,96,105,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PLAYERFACTION,178,110,96,105,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "",IDC_PlayerColor,8,116,14,12
- COMBOBOX IDC_PlayerColorCombo,51,116,83,120,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PlayerColorCombo,51,116,83,120,CBS_DROPDOWNLIST |
WS_TABSTOP
PUSHBUTTON "Set Name",IDC_CHANGE_NAME,15,88,36,9
PUSHBUTTON "Add Skirmish Players",IDC_ADDSKIRMISHPLAYERS,42,274,71,
@@ -885,20 +892,20 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Build List"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_SIDES_COMBO,9,10,184,133,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_SIDES_COMBO,9,10,184,133,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Side:",IDC_STATIC,2,0,195,28
- LISTBOX IDC_BUILD_LIST,9,42,183,125,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_BUILD_LIST,9,42,183,125,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Build List",IDC_STATIC,2,31,196,167
- CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN |
+ CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN |
WS_DISABLED,16,224,177,16
GROUPBOX "Power Used:",IDC_STATIC,7,214,190,28,WS_DISABLED
CONTROL "Structure Already Built",IDC_ALREADY_BUILD,"Button",
BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_RIGHT | WS_TABSTOP,
100,169,90,10
RTEXT "Rebuilds:",IDC_STATIC,111,184,35,8
- COMBOBOX IDC_REBUILDS,149,182,43,64,CBS_DROPDOWN | WS_VSCROLL |
+ COMBOBOX IDC_REBUILDS,149,182,43,64,CBS_DROPDOWN | WS_VSCROLL |
WS_TABSTOP
PUSHBUTTON "Up",IDC_MOVE_UP,9,172,22,11
PUSHBUTTON "Down",IDC_MOVE_DOWN,9,184,22,11
@@ -946,16 +953,16 @@ BEGIN
PUSHBUTTON "&Delete",IDC_DELETE,403,152,50,14
PUSHBUTTON "Import Scripts...",IDC_LOAD,386,309,60,14
PUSHBUTTON "Export Script(s)...",IDC_SAVE,317,309,60,14
- CONTROL "Tree1",IDC_SCRIPT_TREE,"SysTreeView32",TVS_HASBUTTONS |
- TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
+ CONTROL "Tree1",IDC_SCRIPT_TREE,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
WS_TABSTOP,7,7,386,193,WS_EX_CLIENTEDGE
PUSHBUTTON "New &Folder...",IDC_NEW_FOLDER,403,46,50,14
- EDITTEXT IDC_SCRIPT_DESCRIPTION,208,206,187,99,ES_MULTILINE |
+ EDITTEXT IDC_SCRIPT_DESCRIPTION,208,206,187,99,ES_MULTILINE |
ES_READONLY | WS_VSCROLL | WS_HSCROLL
PUSHBUTTON "Cancel",IDCANCEL,403,253,50,14
- EDITTEXT IDC_SCRIPT_COMMENT,7,206,195,99,ES_MULTILINE |
+ EDITTEXT IDC_SCRIPT_COMMENT,7,206,195,99,ES_MULTILINE |
ES_READONLY | WS_VSCROLL
- CONTROL "Auto Verify",IDC_AUTO_VERIFY,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Auto Verify",IDC_AUTO_VERIFY,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,261,311,52,8
PUSHBUTTON "&Verify",IDC_VERIFY,403,22,50,14
PUSHBUTTON "&Patch ""GC_""",IDC_PATCH_GC,403,169,50,14
@@ -976,7 +983,7 @@ STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Script Conditions"
FONT 8, "MS Sans Serif"
BEGIN
- LISTBOX IDC_CONDITION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_CONDITION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Conditions for this script:",IDC_STATIC,7,14,81,8
PUSHBUTTON "New...",IDC_NEW,319,32,50,14
@@ -994,7 +1001,7 @@ STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Actions if true."
FONT 8, "MS Sans Serif"
BEGIN
- LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Actions to take if conditions are true:",IDC_STATIC,7,
14,139,8
@@ -1014,7 +1021,7 @@ FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Actions to take if conditions are false:",IDC_STATIC,7,
14,120,8
- LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_ACTION_LIST,7,29,306,104,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "New...",IDC_NEW,319,32,50,14
PUSHBUTTON "Edit...",IDC_EDIT,319,48,50,14
@@ -1039,11 +1046,11 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,11,69,108,10
CONTROL "Easy",IDC_EASY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
157,41,31,10
- CONTROL "Normal",IDC_NORMAL,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Normal",IDC_NORMAL,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,157,56,38,10
CONTROL "Hard",IDC_HARD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
157,71,31,10
- EDITTEXT IDC_SCRIPT_COMMENT,7,100,320,98,ES_MULTILINE |
+ EDITTEXT IDC_SCRIPT_COMMENT,7,100,320,98,ES_MULTILINE |
WS_VSCROLL
LTEXT "Script Name:",IDC_STATIC,7,12,43,8
GROUPBOX "Active in:",IDC_STATIC,151,30,58,54
@@ -1071,8 +1078,8 @@ BEGIN
LTEXT "These are the freaking warnings.",IDC_WARNINGS,9,388,
210,30
CONTROL "Tree1",IDC_CONDITION_TREE,"SysTreeView32",
- TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
- TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS |
+ TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
+ TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS |
TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,7,7,297,308
END
@@ -1084,10 +1091,10 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,171,52,50,14
PUSHBUTTON "Cancel",IDCANCEL,224,52,50,14
GROUPBOX "Parameter:",IDC_CAPTION,7,7,267,41
- COMBOBOX IDC_COMBO,15,21,250,87,CBS_DROPDOWN | CBS_SORT |
+ COMBOBOX IDC_COMBO,15,21,250,87,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_EDIT,19,21,190,12,ES_AUTOHSCROLL
- COMBOBOX IDC_LIST,19,21,190,84,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_LIST,19,21,190,84,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Preview Sound",IDC_PREVIEWSOUND,7,52,62,14
END
@@ -1104,9 +1111,9 @@ BEGIN
GROUPBOX "Warnings:",IDC_WARNINGS_CAPTION,7,378,297,45
LTEXT "These are the freaking warnings.",IDC_WARNINGS,9,388,
210,30
- CONTROL "Tree1",IDC_ACTION_TREE,"SysTreeView32",TVS_HASBUTTONS |
- TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
- TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_TRACKSELECT |
+ CONTROL "Tree1",IDC_ACTION_TREE,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
+ TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_TRACKSELECT |
WS_BORDER | WS_TABSTOP,7,7,297,308
END
@@ -1119,9 +1126,9 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,458,273,50,14
PUSHBUTTON "Add New Team",IDC_NEWTEAM,7,273,56,14
PUSHBUTTON "Delete Team",IDC_DELETETEAM,121,273,54,14
- LISTBOX IDC_PLAYER_LIST,7,7,105,263,LBS_NOINTEGRALHEIGHT |
+ LISTBOX IDC_PLAYER_LIST,7,7,105,263,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
- CONTROL "List1",IDC_TEAMS_LIST,"SysListView32",LVS_REPORT |
+ CONTROL "List1",IDC_TEAMS_LIST,"SysListView32",LVS_REPORT |
LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,116,7,392,263
PUSHBUTTON "Copy Team",IDC_COPYTEAM,67,273,50,14
PUSHBUTTON "Select Team Members...",IDC_SelectTeamMembers,179,273,
@@ -1169,7 +1176,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,29,157,50,14
PUSHBUTTON "Cancel",IDCANCEL,88,157,50,14
GROUPBOX "Object:",IDC_CAPTION,7,7,131,145
- CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,15,20,114,126
END
@@ -1180,38 +1187,38 @@ FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_MAX,177,2,27,14,ES_AUTOHSCROLL
RTEXT "Home Position:",IDC_STATIC,2,37,53,8
- COMBOBOX IDC_HOME_WAYPOINT,58,36,113,228,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_HOME_WAYPOINT,58,36,113,228,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Min:",IDC_STATIC,6,122,14,8
LTEXT "Max:",IDC_STATIC,24,122,16,8
LTEXT "Unit Type:",IDC_STATIC,50,122,91,8
EDITTEXT IDC_MIN_UNIT1,2,131,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT1,24,131,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE1,47,131,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE1,47,131,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT2,2,145,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT2,23,145,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE2,47,145,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE2,47,145,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT3,2,159,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT3,24,159,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE3,47,159,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE3,47,159,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT4,2,173,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT4,24,173,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE4,47,173,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE4,47,173,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT5,2,187,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT5,24,187,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE5,47,187,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE5,47,187,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT6,2,201,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT6,24,201,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE6,47,201,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE6,47,201,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MIN_UNIT7,2,215,17,12,ES_AUTOHSCROLL
EDITTEXT IDC_MAX_UNIT7,24,215,17,12,ES_AUTOHSCROLL
- COMBOBOX IDC_UNIT_TYPE7,47,215,144,210,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_UNIT_TYPE7,47,215,144,210,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Team Description:",IDC_STATIC,0,285,213,38
EDITTEXT IDC_DESCRIPTION,8,294,195,27,ES_AUTOHSCROLL
@@ -1223,7 +1230,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,255,164,9
LTEXT "Maximum Quantity:",IDC_STATIC,116,4,59,8
RTEXT "Condition:",IDC_STATIC,11,62,47,8
- COMBOBOX IDC_PRODUCTION_CONDITION,64,59,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PRODUCTION_CONDITION,64,59,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Production:",IDC_STATIC,1,53,212,66
RTEXT "Priority:",IDC_STATIC,3,89,24,8
@@ -1240,7 +1247,7 @@ BEGIN
PUSHBUTTON "...",IDC_UNIT_TYPE6_BUTTON,197,201,12,12
PUSHBUTTON "...",IDC_UNIT_TYPE7_BUTTON,197,215,12,12
EDITTEXT IDC_TEAM_NAME,2,1,107,14,ES_AUTOHSCROLL
- COMBOBOX IDC_TEAMOWNER,58,20,113,176,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_TEAMOWNER,58,20,113,176,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
RTEXT "Owner:",IDC_STATIC,2,24,53,8
CONTROL "Team created once and only once.",IDC_TEAM_SINGLETON,
@@ -1249,7 +1256,7 @@ BEGIN
EDITTEXT IDC_TEAM_BUILD_FRAMES,32,101,25,12,ES_AUTOHSCROLL
LTEXT "frames.",IDC_STATIC,58,103,24,9
CONTROL "Execute associated actions",
- IDC_PRODUCTION_EXECUTEACTIONS,"Button",BS_AUTOCHECKBOX |
+ IDC_PRODUCTION_EXECUTEACTIONS,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,63,76,103,10
END
@@ -1259,22 +1266,22 @@ CAPTION "Reinforcement"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "If reinforcing, then:",IDC_STATIC,13,7,184,87
- CONTROL "Deploy by",IDC_DEPLOY_BY,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Deploy by",IDC_DEPLOY_BY,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,19,23,44,9
- COMBOBOX IDC_TRANSPORT_COMBO,66,21,126,140,CBS_DROPDOWN |
+ COMBOBOX IDC_TRANSPORT_COMBO,66,21,126,140,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Veterancy Level",IDC_STATIC,15,109,141,42
- COMBOBOX IDC_VETERANCY,23,124,124,60,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_VETERANCY,23,124,124,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
CONTROL "Transports exit map after unloading.",
- IDC_TRANSPORTS_EXIT,"Button",BS_AUTOCHECKBOX |
+ IDC_TRANSPORTS_EXIT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,66,36,124,11
CONTROL "Load members into transports (if applicable).",
- IDC_TEAM_STARTS_FULL,"Button",BS_AUTOCHECKBOX |
+ IDC_TEAM_STARTS_FULL,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,19,78,166,11
GROUPBOX "Start team or transports at waypoint:",IDC_STATIC,19,50,
171,26
- COMBOBOX IDC_WAYPOINT_COMBO,25,60,160,176,CBS_DROPDOWN | CBS_SORT |
+ COMBOBOX IDC_WAYPOINT_COMBO,25,60,160,176,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
END
@@ -1286,36 +1293,36 @@ BEGIN
GROUPBOX "Behavior Script Triggers:",IDC_STATIC,7,7,216,107
GROUPBOX "Behavior Options",IDC_STATIC,7,141,216,106
RTEXT "On Create:",IDC_STATIC,23,25,51,8
- COMBOBOX IDC_ON_CREATE_SCRIPT,85,22,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_CREATE_SCRIPT,85,22,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
RTEXT "On Enemy Sighted:",IDC_STATIC,13,44,61,8
- COMBOBOX IDC_ON_ENEMY_SIGHTED,85,43,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_ENEMY_SIGHTED,85,43,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_ON_DESTROYED,85,80,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_DESTROYED,85,80,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
RTEXT "On Destroyed %",IDC_STATIC,10,81,51,8
EDITTEXT IDC_PERCENT_DESTROYED,62,80,18,12,ES_AUTOHSCROLL
- COMBOBOX IDC_ENEMY_INTERACTIONS,19,182,159,69,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ENEMY_INTERACTIONS,19,182,159,69,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Initial Team Behavior",IDC_STATIC,15,172,172,27
CONTROL "Transports return to base after unloading.",
- IDC_TRANSPORTS_RETURN,"Button",BS_AUTOCHECKBOX |
+ IDC_TRANSPORTS_RETURN,"Button",BS_AUTOCHECKBOX |
WS_DISABLED | WS_TABSTOP,15,151,179,8
CONTROL "Team avoids threats.",IDC_AVOID_THREATS,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,15,162,179,8
RTEXT "On All Clear:",IDC_STATIC,13,59,61,8
- COMBOBOX IDC_ON_ALL_CLEAR,85,58,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_ALL_CLEAR,85,58,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "",IDC_STATIC,7,36,216,37
RTEXT "On Idle:",IDC_STATIC,23,99,51,8
- COMBOBOX IDC_ON_IDLE_SCRIPT,85,96,132,173,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_ON_IDLE_SCRIPT,85,96,132,173,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Behavior Scirpt Triggers:",IDC_STATIC,7,7,216,131
RTEXT "On Unit Destroyed:",IDC_STATIC,13,119,61,8
COMBOBOX IDC_ON_UNIT_DESTROYED_SCRIPT,85,116,132,173,
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "Does this team focus on a single target at a time ",
- IDC_ATTACK_COMMON_TARGET,"Button",BS_AUTOCHECKBOX |
+ IDC_ATTACK_COMMON_TARGET,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,22,215,173,8
GROUPBOX "Attack:",IDC_STATIC,15,204,181,34
LTEXT "in Hard and Brutal (never in Normal)?",IDC_STATIC,35,
@@ -1342,7 +1349,7 @@ BEGIN
CONTROL "Export selected scripts.",IDC_SELECTED_SCRIPTS,"Button",
BS_AUTORADIOBUTTON,15,127,99,8
GROUPBOX "Export Mode:",IDC_STATIC,7,104,172,39
- CONTROL "Include sides.",IDC_SIDES,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Include sides.",IDC_SIDES,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,12,79,154,9
END
@@ -1351,24 +1358,24 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Grove Options"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_Grove_Type1,32,21,164,81,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type1,32,21,164,81,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
LTEXT "%",IDC_STATIC,15,11,8,8
EDITTEXT IDC_Grove_Per1,8,21,20,13,ES_AUTOHSCROLL | ES_NUMBER
- COMBOBOX IDC_Grove_Type2,32,36,164,80,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type2,32,36,164,80,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per2,8,36,20,13,ES_AUTOHSCROLL | ES_NUMBER
- COMBOBOX IDC_Grove_Type3,32,51,164,77,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type3,32,51,164,77,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per3,8,51,20,13,ES_AUTOHSCROLL | ES_NUMBER
- COMBOBOX IDC_Grove_Type4,32,66,164,78,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type4,32,66,164,78,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per4,8,66,20,13,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "Tree Type",IDC_STATIC,34,11,34,8
- EDITTEXT IDC_Grove_PerTotal,8,97,20,13,ES_AUTOHSCROLL |
+ EDITTEXT IDC_Grove_PerTotal,8,97,20,13,ES_AUTOHSCROLL |
ES_READONLY | ES_NUMBER
LTEXT "% Total",IDC_STATIC,33,99,24,8
- COMBOBOX IDC_Grove_Type5,32,81,164,77,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_Grove_Type5,32,81,164,77,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_Grove_Per5,8,81,20,13,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_Grove_NumberTrees,8,115,40,14,ES_AUTOHSCROLL
@@ -1384,7 +1391,7 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Fence options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,126
EDITTEXT IDC_FENCE_SPACING_EDIT,146,143,49,12,ES_AUTOHSCROLL
LTEXT "Fence spacing:",IDC_STATIC,74,145,68,8
@@ -1397,9 +1404,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Blend Material Options"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,5,5,190,126
- CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_TERRAIN_SWATCHES,"Static",SS_BLACKFRAME |
SS_SUNKEN,65,137,65,55
LTEXT "Gravel",IDC_TERRAIN_NAME,67,197,86,9
END
@@ -1413,7 +1420,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,79,76,50,14
LTEXT "Which of the following PlayerTemplates shall I use to add the Player you need?",
IDC_STATIC,7,7,143,36
- COMBOBOX IDC_COMBO1,7,46,143,260,CBS_DROPDOWNLIST | CBS_SORT |
+ COMBOBOX IDC_COMBO1,7,46,143,260,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
END
@@ -1424,7 +1431,7 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,210,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,210,24,50,14
- CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,7,7,198,284
END
@@ -1442,7 +1449,7 @@ BEGIN
ES_AUTOHSCROLL | WS_DISABLED
CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,71,131,10
- COMBOBOX IDC_MAPOBJECT_Script,41,31,166,67,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Script,41,31,166,67,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Script:",IDC_STATIC,7,34,21,8
END
@@ -1470,7 +1477,7 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Scorch Options"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_SCORCHTYPE,7,15,186,88,CBS_DROPDOWNLIST | WS_VSCROLL |
+ COMBOBOX IDC_SCORCHTYPE,7,15,186,88,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_SIZE_EDIT,60,37,17,12,ES_AUTOHSCROLL
PUSHBUTTON "1",IDC_SIZE_POPUP,79,37,8,12,BS_BITMAP
@@ -1485,18 +1492,18 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,70,242,50,14
PUSHBUTTON "Cancel",IDCANCEL,138,242,50,14
- COMBOBOX IDC_MAP_WEATHER,62,54,112,104,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAP_WEATHER,62,54,112,104,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
RTEXT "Time",IDC_STATIC,7,40,49,8
- COMBOBOX IDC_MAP_TIMEOFDAY,62,38,112,97,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAP_TIMEOFDAY,62,38,112,97,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
RTEXT "Weather",IDC_STATIC,8,56,49,8
EDITTEXT IDC_MAP_TITLE,62,7,112,12,ES_AUTOHSCROLL
- EDITTEXT IDC_MAP_DESCRIPTION,7,73,181,155,ES_MULTILINE |
+ EDITTEXT IDC_MAP_DESCRIPTION,7,73,181,155,ES_MULTILINE |
ES_AUTOHSCROLL | WS_VSCROLL | WS_HSCROLL
RTEXT "Map Name",IDC_STATIC,7,7,49,10
RTEXT "Compression",IDC_STATIC,7,24,49,8
- COMBOBOX IDC_MAP_COMPRESSION,62,22,112,97,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAP_COMPRESSION,62,22,112,97,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
END
@@ -1505,8 +1512,8 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Layers List"
FONT 8, "MS Sans Serif"
BEGIN
- CONTROL "Tree1",IDC_LL_TREE,"SysTreeView32",TVS_HASBUTTONS |
- TVS_LINESATROOT | TVS_EDITLABELS | TVS_DISABLEDRAGDROP |
+ CONTROL "Tree1",IDC_LL_TREE,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_LINESATROOT | TVS_EDITLABELS | TVS_DISABLEDRAGDROP |
WS_TABSTOP,7,7,207,148
END
@@ -1517,7 +1524,7 @@ FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,210,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,210,24,50,14
- CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
+ CONTROL "",IDC_OBJECT_TREEVIEW,"Static",SS_BLACKFRAME |
SS_SUNKEN,7,24,198,267
LTEXT "Static",IDC_MISSINGLABEL,7,7,195,8
END
@@ -1528,7 +1535,7 @@ CAPTION "Water Options"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "Water Area Name:",IDC_STATIC,1,1,195,34
- COMBOBOX IDC_WATERNAME_EDIT,7,15,186,88,CBS_DROPDOWN | CBS_SORT |
+ COMBOBOX IDC_WATERNAME_EDIT,7,15,186,88,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Water Height:",IDC_WATER_HEIGHT1,1,40,195,33
EDITTEXT IDC_HEIGHT_EDIT,70,52,17,12,ES_AUTOHSCROLL
@@ -1536,7 +1543,7 @@ BEGIN
PUSHBUTTON "1",IDC_HEIGHT_POPUP,89,52,8,12,BS_BITMAP
CONTROL "Create Water Polygon",IDC_WATER_POLYGON,"Button",
BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,31,89,99,16
- CONTROL "River",IDC_MAKE_RIVER,"Button",BS_AUTOCHECKBOX |
+ CONTROL "River",IDC_MAKE_RIVER,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,31,119,98,16
GROUPBOX "Point spacing for water polygons and rivers.",
IDC_STATIC,13,140,168,29
@@ -1572,7 +1579,7 @@ CAPTION "Waypoint Options"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "Waypoint Name:",IDC_WAYPOINT_CAPTION1,1,1,195,34
- COMBOBOX IDC_WAYPOINTNAME_EDIT,7,15,186,88,CBS_DROPDOWN |
+ COMBOBOX IDC_WAYPOINTNAME_EDIT,7,15,186,88,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_WAYPOINTLABEL1_EDIT,7,119,182,12,ES_AUTOHSCROLL
EDITTEXT IDC_WAYPOINTLABEL2_EDIT,8,134,182,12,ES_AUTOHSCROLL
@@ -1586,7 +1593,7 @@ BEGIN
EDITTEXT IDC_WAYPOINT_LOCATIONY,111,50,69,12,ES_AUTOHSCROLL
GROUPBOX "List of Current Waypoints:",IDC_LIST_WAYPOINTS,1,74,195,
28
- COMBOBOX IDC_LIST_OF_WAYPOINT_NAMES,7,85,183,88,CBS_DROPDOWN |
+ COMBOBOX IDC_LIST_OF_WAYPOINT_NAMES,7,85,183,88,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "Bi-Directional",IDC_WAYPOINT_BIDIRECTIONAL,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,11,172,132,9
@@ -1600,7 +1607,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,99,110,50,14
PUSHBUTTON "Cancel",IDCANCEL,152,110,50,14
LTEXT "REPLACEIT",IDC_REPLACETHISTEXT,7,7,195,19
- LISTBOX IDC_VALIDTEAMLIST,7,27,195,82,LBS_SORT |
+ LISTBOX IDC_VALIDTEAMLIST,7,27,195,82,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
@@ -1609,62 +1616,62 @@ STYLE WS_CHILD | WS_CAPTION
CAPTION "Generic"
FONT 8, "MS Sans Serif"
BEGIN
- COMBOBOX IDC_TeamGeneric_Script1,58,13,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script1,58,13,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 1:",IDC_SCRIPT_PREFIX1,6,14,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script2,58,31,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script2,58,31,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 2:",IDC_SCRIPT_PREFIX2,6,32,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script3,58,49,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script3,58,49,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 3:",IDC_SCRIPT_PREFIX3,6,50,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script4,58,67,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script4,58,67,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 4:",IDC_SCRIPT_PREFIX4,6,68,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script5,58,85,160,67,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script5,58,85,160,67,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 5:",IDC_SCRIPT_PREFIX5,6,86,47,12,SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script6,58,103,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script6,58,103,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 6:",IDC_SCRIPT_PREFIX6,6,104,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script7,58,121,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script7,58,121,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 7:",IDC_SCRIPT_PREFIX7,6,122,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script8,58,139,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script8,58,139,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 8:",IDC_SCRIPT_PREFIX8,6,140,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script9,58,157,160,67,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script9,58,157,160,67,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 9:",IDC_SCRIPT_PREFIX9,6,158,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script10,58,175,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script10,58,175,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 10:",IDC_SCRIPT_PREFIX10,6,176,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script11,58,193,160,65,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script11,58,193,160,65,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 11:",IDC_SCRIPT_PREFIX11,6,194,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script12,58,211,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script12,58,211,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 12:",IDC_SCRIPT_PREFIX12,6,212,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script13,58,229,160,66,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script13,58,229,160,66,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 13:",IDC_SCRIPT_PREFIX13,6,230,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script14,58,247,160,65,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script14,58,247,160,65,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 14:",IDC_SCRIPT_PREFIX14,6,248,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script15,58,265,160,67,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script15,58,265,160,67,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 15:",IDC_SCRIPT_PREFIX15,6,266,47,12,
SS_CENTERIMAGE
- COMBOBOX IDC_TeamGeneric_Script16,58,283,160,73,CBS_DROPDOWN |
+ COMBOBOX IDC_TeamGeneric_Script16,58,283,160,73,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Script 16:",IDC_SCRIPT_PREFIX16,6,284,47,12,
SS_CENTERIMAGE
@@ -1703,13 +1710,13 @@ BEGIN
CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_MAPOBJECT_StartingHealthEdit,180,54,25,14,
ES_AUTOHSCROLL | WS_DISABLED
- CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
WS_DISABLED | WS_TABSTOP,11,86,58,10
CONTROL "Indestructible",IDC_MAPOBJECT_Indestructible,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,11,110,58,10
CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,79,86,58,10
- CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
WS_DISABLED | WS_TABSTOP,11,97,58,10
LTEXT "Aggressiveness:",IDC_STATIC,11,126,66,8,WS_DISABLED
COMBOBOX IDC_MAPOBJECT_Aggressiveness,79,124,126,73,
@@ -1725,13 +1732,13 @@ BEGIN
EDITTEXT IDC_MAPOBJECT_ShroudClearingDistance,177,226,27,14,
ES_AUTOHSCROLL | WS_DISABLED
LTEXT "Veterancy:",IDC_STATIC,11,142,66,8,WS_DISABLED
- COMBOBOX IDC_MAPOBJECT_Veterancy,79,140,126,73,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Veterancy,79,140,126,73,CBS_DROPDOWNLIST |
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_Weather,79,158,126,76,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Weather,79,158,126,76,CBS_DROPDOWNLIST |
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_Time,79,174,126,65,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Time,79,174,126,65,CBS_DROPDOWNLIST |
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_HitPoints,79,70,126,52,CBS_DROPDOWN |
+ COMBOBOX IDC_MAPOBJECT_HitPoints,79,70,126,52,CBS_DROPDOWN |
CBS_SORT | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
LTEXT "Max Hitpoints",IDC_STATIC,11,71,58,8,WS_DISABLED
EDITTEXT IDC_MAPOBJECT_StoppingDistance,177,190,27,14,
@@ -1750,23 +1757,23 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Object Properties"
FONT 8, "MS Sans Serif"
BEGIN
- EDITTEXT IDC_MAPOBJECT_Name,33,11,160,12,ES_AUTOHSCROLL |
+ EDITTEXT IDC_MAPOBJECT_Name,33,11,160,12,ES_AUTOHSCROLL |
WS_GROUP
- COMBOBOX IDC_MAPOBJECT_Team,33,26,160,141,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Team,33,26,160,141,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_Script,33,40,160,67,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Script,33,40,160,67,CBS_DROPDOWNLIST |
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_MAPOBJECT_StartingHealth,64,64,34,71,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_GROUP | WS_TABSTOP
EDITTEXT IDC_MAPOBJECT_StartingHealthEdit,101,64,25,14,
ES_AUTOHSCROLL
- COMBOBOX IDC_MAPOBJECT_HitPoints,63,83,66,52,CBS_DROPDOWN |
+ COMBOBOX IDC_MAPOBJECT_HitPoints,63,83,66,52,CBS_DROPDOWN |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_MAPOBJECT_Aggressiveness,63,101,65,73,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_Veterancy,63,119,65,73,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Veterancy,63,119,65,73,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Enabled",IDC_MAPOBJECT_Enabled,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,133,63,42,10
CONTROL "Unsellable",IDC_MAPOBJECT_Unsellable,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,133,73,49,10
@@ -1776,7 +1783,7 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,133,93,58,10
CONTROL "AI Recruitable",IDC_MAPOBJECT_RecruitableAI,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,133,103,61,10
- CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Powered",IDC_MAPOBJECT_Powered,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,133,113,44,10
CONTROL "Selectable",IDC_MAPOBJECT_Selectable2,"Button",
BS_AUTO3STATE | WS_TABSTOP,133,123,49,10
@@ -1791,40 +1798,40 @@ BEGIN
PUSHBUTTON "1",IDC_HEIGHT_POPUP,185,171,8,12,BS_BITMAP
EDITTEXT IDC_MAPOBJECT_Angle,158,188,24,12,ES_AUTOHSCROLL
PUSHBUTTON "1",IDC_ANGLE_POPUP,185,188,8,12,BS_BITMAP
- COMBOBOX IDC_MAPOBJECT_Weather,39,188,93,76,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Weather,39,188,93,76,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_GROUP | WS_TABSTOP
- COMBOBOX IDC_MAPOBJECT_Time,39,204,93,65,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_MAPOBJECT_Time,39,204,93,65,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
- COMBOBOX IDC_SOUND_COMBO,66,232,127,160,CBS_DROPDOWNLIST |
- CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_GROUP |
+ COMBOBOX IDC_SOUND_COMBO,66,232,127,160,CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_GROUP |
WS_TABSTOP
CONTROL "Customize",IDC_CUSTOMIZE_CHECKBOX,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,14,247,55,10
- CONTROL "Enabled",IDC_ENABLED_CHECKBOX,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Enabled",IDC_ENABLED_CHECKBOX,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,78,247,50,10
- CONTROL "Looping",IDC_LOOPING_CHECKBOX,"Button",BS_AUTOCHECKBOX |
+ CONTROL "Looping",IDC_LOOPING_CHECKBOX,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,142,247,50,10
- EDITTEXT IDC_LOOPCOUNT_EDIT,53,258,40,12,ES_AUTOHSCROLL |
+ EDITTEXT IDC_LOOPCOUNT_EDIT,53,258,40,12,ES_AUTOHSCROLL |
ES_NUMBER
- COMBOBOX IDC_PRIORITY_COMBO,127,258,65,70,CBS_DROPDOWNLIST |
+ COMBOBOX IDC_PRIORITY_COMBO,127,258,65,70,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_VOLUME_EDIT,53,274,40,12,ES_AUTOHSCROLL | ES_NUMBER
- EDITTEXT IDC_MIN_VOLUME_EDIT,146,274,45,12,ES_AUTOHSCROLL |
+ EDITTEXT IDC_MIN_VOLUME_EDIT,146,274,45,12,ES_AUTOHSCROLL |
ES_NUMBER
- EDITTEXT IDC_MIN_RANGE_EDIT,53,290,40,12,ES_AUTOHSCROLL |
+ EDITTEXT IDC_MIN_RANGE_EDIT,53,290,40,12,ES_AUTOHSCROLL |
ES_NUMBER
- EDITTEXT IDC_MAX_RANGE_EDIT,146,290,45,12,ES_AUTOHSCROLL |
+ EDITTEXT IDC_MAX_RANGE_EDIT,146,290,45,12,ES_AUTOHSCROLL |
ES_NUMBER
- CONTROL "No Scale",IDC_SCALE_OFF,"Button",BS_AUTORADIOBUTTON |
+ CONTROL "No Scale",IDC_SCALE_OFF,"Button",BS_AUTORADIOBUTTON |
NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,120,207,45,10
- CONTROL "z",IDC_SCALE_ON,"Button",BS_AUTORADIOBUTTON | NOT
+ CONTROL "z",IDC_SCALE_ON,"Button",BS_AUTORADIOBUTTON | NOT
WS_VISIBLE | WS_DISABLED | WS_TABSTOP,153,208,8,10
- EDITTEXT IDC_MAPOBJECT_Scale,163,204,24,14,ES_AUTOHSCROLL | NOT
+ EDITTEXT IDC_MAPOBJECT_Scale,163,204,24,14,ES_AUTOHSCROLL | NOT
WS_VISIBLE | WS_DISABLED
- PUSHBUTTON "1",IDC_SCALE_POPUP,189,206,8,12,BS_BITMAP | NOT
+ PUSHBUTTON "1",IDC_SCALE_POPUP,189,206,8,12,BS_BITMAP | NOT
WS_VISIBLE | WS_DISABLED
LISTBOX IDC_MAPOBJECT_BuildWithUpgrades,7,318,184,50,
- LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
+ LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_GROUP | WS_TABSTOP
GROUPBOX "General",IDC_STATIC_MAPOBJECT_GENERAL,4,2,193,54
GROUPBOX "Logical",IDC_STATIC_MAPOBJECT_LOGICAL,4,56,193,105
@@ -1909,7 +1916,7 @@ END
//
#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE
+GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
@@ -2414,201 +2421,201 @@ IDC_SCORCH CURSOR DISCARDABLE "IDC_Scorch.cur"
IDD_PROPEDIT DLGINIT
BEGIN
IDC_KEYTYPE, 0x403, 5, 0
-0x6f42, 0x6c6f, "\000"
+0x6f42, 0x6c6f, "\000"
IDC_KEYTYPE, 0x403, 4, 0
-0x6e49, 0x0074,
+0x6e49, 0x0074,
IDC_KEYTYPE, 0x403, 5, 0
-0x6552, 0x6c61, "\000"
+0x6552, 0x6c61, "\000"
IDC_KEYTYPE, 0x403, 6, 0
-0x7341, 0x6963, 0x0069,
+0x7341, 0x6963, 0x0069,
IDC_KEYTYPE, 0x403, 8, 0
-0x6e55, 0x6369, 0x646f, 0x0065,
+0x6e55, 0x6369, 0x646f, 0x0065,
0
END
IDD_BUILD_LIST_PANEL DLGINIT
BEGIN
IDC_REBUILDS, 0x403, 5, 0
-0x6f4e, 0x656e, "\000"
+0x6f4e, 0x656e, "\000"
IDC_REBUILDS, 0x403, 2, 0
-0x0031,
+0x0031,
IDC_REBUILDS, 0x403, 2, 0
-0x0032,
+0x0032,
IDC_REBUILDS, 0x403, 2, 0
-0x0033,
+0x0033,
IDC_REBUILDS, 0x403, 2, 0
-0x0034,
+0x0034,
IDC_REBUILDS, 0x403, 2, 0
-0x0035,
+0x0035,
IDC_REBUILDS, 0x403, 10, 0
-0x6e55, 0x696c, 0x696d, 0x6574, 0x0064,
+0x6e55, 0x696c, 0x696d, 0x6574, 0x0064,
0
END
IDD_TeamReinforcement DLGINIT
BEGIN
IDC_TRANSPORT_COMBO, 0x403, 11, 0
-0x6548, 0x696c, 0x6f63, 0x7470, 0x7265, "\000"
+0x6548, 0x696c, 0x6f63, 0x7470, 0x7265, "\000"
IDC_VETERANCY, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_VETERANCY, 0x403, 8, 0
-0x6556, 0x6574, 0x6172, 0x006e,
+0x6556, 0x6574, 0x6172, 0x006e,
IDC_VETERANCY, 0x403, 6, 0
-0x6c45, 0x7469, 0x0065,
+0x6c45, 0x7469, 0x0065,
IDC_VETERANCY, 0x403, 7, 0
-0x6548, 0x6f72, 0x6369, "\000"
+0x6548, 0x6f72, 0x6369, "\000"
IDC_WAYPOINT_COMBO, 0x403, 9, 0
-0x6157, 0x7079, 0x696f, 0x746e, "\000"
+0x6157, 0x7079, 0x696f, 0x746e, "\000"
0
END
IDD_TeamBehavior DLGINIT
BEGIN
IDC_ENEMY_INTERACTIONS, 0x403, 6, 0
-0x6c53, 0x6565, 0x0070,
+0x6c53, 0x6565, 0x0070,
IDC_ENEMY_INTERACTIONS, 0x403, 8, 0
-0x6150, 0x7373, 0x7669, 0x0065,
+0x6150, 0x7373, 0x7669, 0x0065,
IDC_ENEMY_INTERACTIONS, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_ENEMY_INTERACTIONS, 0x403, 6, 0
-0x6c41, 0x7265, 0x0074,
+0x6c41, 0x7265, 0x0074,
IDC_ENEMY_INTERACTIONS, 0x403, 11, 0
-0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
+0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
0
END
IDD_SCORCH_OPTIONS DLGINIT
BEGIN
IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3120, "\000"
+0x6353, 0x726f, 0x6863, 0x3120, "\000"
IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3220, "\000"
+0x6353, 0x726f, 0x6863, 0x3220, "\000"
IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3320, "\000"
+0x6353, 0x726f, 0x6863, 0x3320, "\000"
IDC_SCORCHTYPE, 0x403, 9, 0
-0x6353, 0x726f, 0x6863, 0x3420, "\000"
+0x6353, 0x726f, 0x6863, 0x3420, "\000"
IDC_SCORCHTYPE, 0x403, 13, 0
-0x6f52, 0x6e75, 0x2064, 0x6853, 0x6461, 0x776f, "\000"
+0x6f52, 0x6e75, 0x2064, 0x6853, 0x6461, 0x776f, "\000"
IDC_SCORCHTYPE, 0x403, 12, 0
-0x7243, 0x6361, 0x206b, 0x614d, 0x6b72, 0x0073,
+0x7243, 0x6361, 0x206b, 0x614d, 0x6b72, 0x0073,
0
END
IDD_WATER_OPTIONS DLGINIT
BEGIN
IDC_WATERNAME_EDIT, 0x403, 22, 0
-0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
-0x6f69, 0x006e,
+0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
+0x6f69, 0x006e,
0
END
IDD_WAYPOINT_OPTIONS DLGINIT
BEGIN
IDC_WAYPOINTNAME_EDIT, 0x403, 22, 0
-0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
-0x6f69, 0x006e,
+0x6e49, 0x7469, 0x6169, 0x436c, 0x6d61, 0x7265, 0x5061, 0x736f, 0x7469,
+0x6f69, 0x006e,
IDC_LIST_OF_WAYPOINT_NAMES, 0x403, 1, 0
-"\000"
+"\000"
0
END
IDD_TeamObjectProperties DLGINIT
BEGIN
IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
-0x6544, 0x6461, "\000"
+0x6544, 0x6461, "\000"
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3532, 0x0025,
+0x3532, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3035, 0x0025,
+0x3035, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3537, 0x0025,
+0x3537, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
-0x3031, 0x2530, "\000"
+0x3031, 0x2530, "\000"
IDC_MAPOBJECT_StartingHealth, 0x403, 6, 0
-0x744f, 0x6568, 0x0072,
+0x744f, 0x6568, 0x0072,
IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
-0x6c53, 0x6565, 0x0070,
+0x6c53, 0x6565, 0x0070,
IDC_MAPOBJECT_Aggressiveness, 0x403, 8, 0
-0x6150, 0x7373, 0x7669, 0x0065,
+0x6150, 0x7373, 0x7669, 0x0065,
IDC_MAPOBJECT_Aggressiveness, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
-0x6c41, 0x7265, 0x0074,
+0x6c41, 0x7265, 0x0074,
IDC_MAPOBJECT_Aggressiveness, 0x403, 11, 0
-0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
+0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_MAPOBJECT_Veterancy, 0x403, 8, 0
-0x6556, 0x6574, 0x6172, 0x006e,
+0x6556, 0x6574, 0x6172, 0x006e,
IDC_MAPOBJECT_Veterancy, 0x403, 6, 0
-0x6c45, 0x7469, 0x0065,
+0x6c45, 0x7469, 0x0065,
IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
-0x6548, 0x6f72, 0x6369, "\000"
+0x6548, 0x6f72, 0x6369, "\000"
IDC_MAPOBJECT_Weather, 0x403, 16, 0
-0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
+0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
IDC_MAPOBJECT_Weather, 0x403, 17, 0
-0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
+0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
IDC_MAPOBJECT_Weather, 0x403, 15, 0
-0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
+0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
IDC_MAPOBJECT_Time, 0x403, 13, 0
-0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
+0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
IDC_MAPOBJECT_Time, 0x403, 14, 0
-0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
+0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
IDC_MAPOBJECT_Time, 0x403, 16, 0
-0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
+0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
IDC_MAPOBJECT_HitPoints, 0x403, 19, 0
-0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
-"\000"
+0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
+"\000"
0
END
IDD_MAPOBJECT_PROPS DLGINIT
BEGIN
IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
-0x6544, 0x6461, "\000"
+0x6544, 0x6461, "\000"
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3532, 0x0025,
+0x3532, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3035, 0x0025,
+0x3035, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 4, 0
-0x3537, 0x0025,
+0x3537, 0x0025,
IDC_MAPOBJECT_StartingHealth, 0x403, 5, 0
-0x3031, 0x2530, "\000"
+0x3031, 0x2530, "\000"
IDC_MAPOBJECT_StartingHealth, 0x403, 6, 0
-0x744f, 0x6568, 0x0072,
+0x744f, 0x6568, 0x0072,
IDC_MAPOBJECT_HitPoints, 0x403, 19, 0
-0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
-"\000"
+0x6544, 0x6166, 0x6c75, 0x2074, 0x6948, 0x2074, 0x6f50, 0x6e69, 0x7374,
+"\000"
IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
-0x6c53, 0x6565, 0x0070,
+0x6c53, 0x6565, 0x0070,
IDC_MAPOBJECT_Aggressiveness, 0x403, 8, 0
-0x6150, 0x7373, 0x7669, 0x0065,
+0x6150, 0x7373, 0x7669, 0x0065,
IDC_MAPOBJECT_Aggressiveness, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_MAPOBJECT_Aggressiveness, 0x403, 6, 0
-0x6c41, 0x7265, 0x0074,
+0x6c41, 0x7265, 0x0074,
IDC_MAPOBJECT_Aggressiveness, 0x403, 11, 0
-0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
+0x6741, 0x7267, 0x7365, 0x6973, 0x6576, "\000"
IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
-0x6f4e, 0x6d72, 0x6c61, "\000"
+0x6f4e, 0x6d72, 0x6c61, "\000"
IDC_MAPOBJECT_Veterancy, 0x403, 8, 0
-0x6556, 0x6574, 0x6172, 0x006e,
+0x6556, 0x6574, 0x6172, 0x006e,
IDC_MAPOBJECT_Veterancy, 0x403, 6, 0
-0x6c45, 0x7469, 0x0065,
+0x6c45, 0x7469, 0x0065,
IDC_MAPOBJECT_Veterancy, 0x403, 7, 0
-0x6548, 0x6f72, 0x6369, "\000"
+0x6548, 0x6f72, 0x6369, "\000"
IDC_MAPOBJECT_Weather, 0x403, 16, 0
-0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
+0x7355, 0x2065, 0x614d, 0x2070, 0x6557, 0x7461, 0x6568, 0x0072,
IDC_MAPOBJECT_Weather, 0x403, 17, 0
-0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
+0x7355, 0x2065, 0x6f4e, 0x6d72, 0x6c61, 0x4d20, 0x646f, 0x6c65, "\000"
IDC_MAPOBJECT_Weather, 0x403, 15, 0
-0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
+0x7355, 0x2065, 0x6e53, 0x776f, 0x4d20, 0x646f, 0x6c65, "\000"
IDC_MAPOBJECT_Time, 0x403, 13, 0
-0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
+0x7355, 0x2065, 0x614d, 0x2070, 0x6954, 0x656d, "\000"
IDC_MAPOBJECT_Time, 0x403, 14, 0
-0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
+0x7355, 0x2065, 0x6144, 0x2079, 0x6f4d, 0x6564, 0x006c,
IDC_MAPOBJECT_Time, 0x403, 16, 0
-0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
+0x7355, 0x2065, 0x694e, 0x6867, 0x2074, 0x6f4d, 0x6564, 0x006c,
0
END
@@ -2618,19 +2625,19 @@ END
// String Table
//
-STRINGTABLE PRELOAD DISCARDABLE
+STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME "Generals World Builder\nMission\nMission\n Missions (*.map)\n.map\nGeneralsMap\n Generals Mission Map"
IDS_SKELETON "SkeletonWindow"
END
-STRINGTABLE PRELOAD DISCARDABLE
+STRINGTABLE PRELOAD DISCARDABLE
BEGIN
AFX_IDS_APP_TITLE "WorldBuilder"
AFX_IDS_IDLEMESSAGE "Ready"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_INDICATOR_EXT "EXT"
ID_INDICATOR_CAPS "CAP"
@@ -2640,7 +2647,7 @@ BEGIN
ID_INDICATOR_REC "REC"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_NEW "Create a new document\nNew"
ID_FILE_OPEN "Open an existing document\nOpen"
@@ -2653,13 +2660,13 @@ BEGIN
ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_MRU_FILE1 "Open this document"
ID_FILE_MRU_FILE2 "Open this document"
@@ -2679,13 +2686,13 @@ BEGIN
ID_FILE_MRU_FILE16 "Open this document"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_WINDOW_NEW "Open another window for the active document\nNew Window"
ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
@@ -2695,7 +2702,7 @@ BEGIN
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_CLEAR "Erase the selection\nErase"
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
@@ -2710,13 +2717,13 @@ BEGIN
ID_EDIT_REDO "Redo the previously undone action\nRedo"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCSIZE "Change the window size"
AFX_IDS_SCMOVE "Change the window position"
@@ -2727,14 +2734,14 @@ BEGIN
AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCRESTORE "Restore the window to normal size"
AFX_IDS_SCTASKLIST "Activate Task List"
AFX_IDS_MDICHILD "Activate this window"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"
IDS_NEW "New"
@@ -2749,7 +2756,7 @@ BEGIN
IDS_FILE_IS_READONLY "The file is read-only. Change the protection, or use Save As to save to another file."
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
IDS_REPLACEFILE "%s already exists. Do you want to replace it?"
IDS_ONLY_ONE_FILE "Sorry, only one map may be open at a time."
@@ -2763,14 +2770,14 @@ BEGIN
IDS_SCRIPT_NOWARNINGS "No Warnings"
IDS_CONFIRM_REPLACE_TEXTURE "Replace all occurences of texture %s?"
ID_RAMPTOOL "Place Ramps on the map\nRamp"
- IDS_CONFIRM_REMOVE_CLIFF_MAPPING
+ IDS_CONFIRM_REMOVE_CLIFF_MAPPING
"Remove all cliff mapping in the entire map?"
IDS_NUM_SELECTED_ON_TEAM "For team %s, %d units selected."
IDS_MAX_OBJECTS "The object count has exceeded %d. Please reduce the number of objects in this map or performance will suffer."
IDS_REPLACEOWNER "Team %s has an invalid owner. Please select a valid owner from the list below:"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
IDS_SPLASH_LOADING "Loading..."
IDS_SINGLE_SELECTION_ONLY "Single Selection Only"
@@ -2779,23 +2786,23 @@ BEGIN
IDS_MAPOBJECT_PROPS_TITLE "Object Properties"
IDS_NO_PROBLEMS "No problems were detected."
IDS_DUPLICATE_TEAM_REMOVED "Duplicate instance of team ""%s"" removed."
- IDS_PLAYERLESS_TEAM_REMOVED
+ IDS_PLAYERLESS_TEAM_REMOVED
"Team ""%s"" was on non-existent player ""%s"". Team removed."
IDS_NEED_TO_FIX_TEAMS "One or more objects had invalid teams. Please run Validation>Fix Teams to correct this."
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_BRUSH_TOOL "Draw the height on the height map.\nHeight Brush"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FEATHERTOOL "Smooths the height levels in the height map.\nSmooth Height"
ID_BIG_TILE_TOOL "Draws a Brush Options Size block of the current texture tile. \nLarge Tile"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_BRUSH_ADD_TOOL "Adds height to (raises) the height map.\nMound"
ID_BRUSH_SUBTRACT_TOOL "Removes height from (lowers) the height map.\nDig"
@@ -2804,7 +2811,7 @@ BEGIN
ID_AUTO_EDGE_OUT_TOOL "Auto edges the current texture area outward.\nAuto Edge Out"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_EYEDROPPER_TOOL "Hot key ALT. Selects the foreground texture by picking on the texture in the edit windows.\nEyedropper"
ID_PLACE_OBJECT_TOOL "Places the current object in Object Selection panel. Drag to orient.\nPlace Object"
@@ -2813,7 +2820,7 @@ BEGIN
ID_GROVE_TOOL "Click to place random foliage, drag to place foliage in a rectangular area.\nGrove"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_TEAM_EDIT "Edit teams.\nEdit Teams"
ID_LOCK_HORIZONTAL "Lock tool movement to 45 degree increment.\nLock Angle"
@@ -2824,51 +2831,51 @@ BEGIN
ID_HAND_SCROLL_TOOL "Hot key space bar. Scrolls the map.\nScroll"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_ROAD_TOOL "Click and Drag to make Roads.\nRoad"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_MOLD_TOOL "Shapes the terrain using a 3D mesh.\nMesh Mold Tool"
ID_RULER_TOOL "Measure distance between two points. \nRuler Tool"
ID_SCRIPT_EDIT "Edit scripts.\nEdit Scripts"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_FENCE_TOOL "Places a row of objects. Drag then use shift to stretch.\nFence"
ID_WATER_TOOL "Add and modify water areas.\nWater Tool"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_SCORCH_TOOL "Add Scorchmarks to the map\nAdd Scorchmarks"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_MAPSETTINGS "Edit Map Settings"
ID_EDIT_PICKROADS "Pick only roads"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_LAYERS_LIST "Show or hide the layers list\nToggle LayersList"
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
ID_BORDERTOOL "Add and adjust borders.\nBorder Tool"
- ID_VALIDATION_GENERATEMAPREPORT
+ ID_VALIDATION_GENERATEMAPREPORT
"Generate a report about Map validity, possible problems, etc."
ID_VALIDATION_FIXTEAMS "Adjust all teams so that they're ""Execute Associated Action"" is false."
END
-STRINGTABLE DISCARDABLE
+STRINGTABLE DISCARDABLE
BEGIN
- ID_VIEW_SHOW_SOUND_CIRCLES
+ ID_VIEW_SHOW_SOUND_CIRCLES
"Show the minimum and maximum radii around objects with ambient sounds\nShow Sound Circles"
END
@@ -2899,4 +2906,3 @@ LANGUAGE 9, 1
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
-
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/res/resource.h b/GeneralsMD/Code/Tools/WorldBuilder/res/resource.h
index f2f8982adf0..977f030a095 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/res/resource.h
+++ b/GeneralsMD/Code/Tools/WorldBuilder/res/resource.h
@@ -718,6 +718,10 @@
#define ID_SELECTLAYEROBJECT 33344
#define ID_SELECTACTIVELAYER 33345
#define ID_VIEW_SHOW_SOUND_CIRCLES 33346
+#define ID_LOOK_NORTH 33347
+#define ID_LOOK_SOUTH 33348
+#define ID_LOOK_WEST 33349
+#define ID_LOOK_EAST 33350
#define IDS_NEW 61446
#define IDS_RESIZE 61447
#define IDS_REMOVING_INUSE_TEAM 61448
@@ -766,7 +770,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 242
-#define _APS_NEXT_COMMAND_VALUE 33347
+#define _APS_NEXT_COMMAND_VALUE 33351
#define _APS_NEXT_CONTROL_VALUE 1354
#define _APS_NEXT_SYMED_VALUE 101
#endif
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp
index 86ee3342469..0fe8c567085 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp
@@ -2227,7 +2227,7 @@ if (pMapObj->isSelected()) {
}
}
if (m_drawPolygonAreas) {
- DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
Int selected;
for (selected = 0; selected < 2; selected++) {
for (PolygonTrigger *pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) {
@@ -2338,7 +2338,7 @@ if (pMapObj->isSelected()) {
}
DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
- DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
Matrix3D tmReset(Transform);
DX8Wrapper::Set_Transform(D3DTS_WORLD,tmReset);
@@ -2350,7 +2350,7 @@ if (pMapObj->isSelected()) {
DX8Wrapper::Set_Shader(m_shaderClass);
DX8Wrapper::Draw_Triangles( 0, m_feedbackIndexCount/3, 0, m_feedbackVertexCount);
DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
- DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
+ DX8Wrapper::Set_Vertex_Buffer(m_vertexBufferWater);
}
}
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/EditAction.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/EditAction.cpp
index e1e31053733..53b43357247 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/EditAction.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/EditAction.cpp
@@ -158,6 +158,7 @@ BOOL EditAction::OnInitDialog()
selItem = item;
}
+#if RTS_ZEROHOUR
name = pTemplate->getName2().str();
count = 0;
if (pTemplate->getName2().isEmpty()) continue;
@@ -190,6 +191,7 @@ BOOL EditAction::OnInitDialog()
ins.item.pszText = (char*)name;
ins.item.cchTextMax = 0;
m_actionTreeView.InsertItem(&ins);
+#endif
}
m_actionTreeView.Select(selItem, TVGN_FIRSTVISIBLE);
m_actionTreeView.SelectItem(selItem);
@@ -221,7 +223,7 @@ void EditAction::formatScriptActionText(Int parameterNdx) {
m_myEditCtrl.SetSel(0, 1000);
m_myEditCtrl.SetSelectionCharFormat(cf);
- //m_myEditCtrl.SetReadOnly();
+ //m_myEditCtrl.SetReadOnly();
// Set up the links.
cf.dwMask = CFE_UNDERLINE | CFM_LINK | CFM_COLOR;
@@ -346,7 +348,7 @@ BOOL EditAction::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
AsciiString strings[MAX_PARMS];
Int numStrings = m_action->getUiStrings(strings);
Int i;
- Bool match = false;
+ Bool match = false;
for (i=0; igetName2().str();
count = 0;
if (pTemplate->getName2().isEmpty()) continue;
@@ -202,6 +203,7 @@ BOOL EditCondition::OnInitDialog()
ins.item.pszText = (char*)name;
ins.item.cchTextMax = 0;
m_conditionTreeView.InsertItem(&ins);
+#endif
}
m_conditionTreeView.Select(selItem, TVGN_FIRSTVISIBLE);
m_conditionTreeView.SelectItem(selItem);
@@ -233,7 +235,7 @@ void EditCondition::formatConditionText(Int parameterNdx) {
m_myEditCtrl.SetSel(0, 1000);
m_myEditCtrl.SetSelectionCharFormat(cf);
- //m_myEditCtrl.SetReadOnly();
+ //m_myEditCtrl.SetReadOnly();
// Set up the links.
cf.dwMask = CFE_UNDERLINE | CFM_LINK | CFM_COLOR;
@@ -358,7 +360,7 @@ BOOL EditCondition::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
AsciiString strings[MAX_PARMS];
Int numStrings = m_condition->getUiStrings(strings);
Int i;
- Bool match = false;
+ Bool match = false;
for (i=0; igetReal()*100.0f);
showCombo = false;
break;
+#endif
case Parameter::FLAG:
captionText = "Flag named:";
@@ -1923,7 +1933,8 @@ BOOL EditParameter::OnInitDialog()
break;
- case Parameter::LEFT_OR_RIGHT:
+#if RTS_ZEROHOUR
+ case Parameter::LEFT_OR_RIGHT:
captionText = "Evacuate Container Side Choices:";
pList->InsertString(-1,"Left");
pList->InsertString(-1,"Right");
@@ -1931,7 +1942,7 @@ BOOL EditParameter::OnInitDialog()
pList->SetCurSel(m_parameter->getInt() - 1);
showList = true;
break;
-
+#endif
case Parameter::RELATION:
captionText = "Relation:";
@@ -2234,11 +2245,13 @@ void EditParameter::OnOK()
}
break;
+#if RTS_ZEROHOUR
case Parameter::PERCENT:
if (! scanReal(pEdit, 1.0f/100.0f)) {
return;
}
break;
+#endif
case Parameter::BOOLEAN:
case Parameter::COMPARISON:
@@ -2265,10 +2278,11 @@ void EditParameter::OnOK()
break;
- case Parameter::LEFT_OR_RIGHT:
- m_parameter->friend_setInt(pList->GetCurSel() + 1);
- break;
-
+#if RTS_ZEROHOUR
+ case Parameter::LEFT_OR_RIGHT:
+ m_parameter->friend_setInt(pList->GetCurSel() + 1);
+ break;
+#endif
case Parameter::LOCALIZED_TEXT:
pCombo->GetWindowText(txt);
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/MainFrm.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/MainFrm.cpp
index 183d9e45233..6395b3b4439 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/MainFrm.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/MainFrm.cpp
@@ -434,7 +434,7 @@ void CMainFrame::onEditScripts()
m_scriptDialog = new ScriptDialog(this);
m_scriptDialog->Create(IDD_ScriptDialog, this);
m_scriptDialog->SetWindowPos(nullptr, frameRect.left, frameRect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
- m_scriptDialog->GetWindowRect(&frameRect);
+ m_scriptDialog->GetWindowRect(&frameRect);
m_scriptDialog->ShowWindow(SW_SHOWNA);
}
@@ -525,4 +525,3 @@ void CMainFrame::handleCameraChange()
{
m_cameraOptions.update();
}
-
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/RulerOptions.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/RulerOptions.cpp
index 98ee923eb86..735305edcb6 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/RulerOptions.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/RulerOptions.cpp
@@ -129,4 +129,3 @@ BEGIN_MESSAGE_MAP(RulerOptions, COptionsPanel)
ON_BN_CLICKED(IDC_CHECK_RULER, OnChangeCheckRuler)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
-
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/RulerTool.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/RulerTool.cpp
index 894650e5dcb..de425122d29 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/RulerTool.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/RulerTool.cpp
@@ -146,7 +146,7 @@ void RulerTool::setLength(Real length)
}
CString str;
- str.Format("Diameter (in feet): %f", length * 2.0f);
+ str.Format("Diameter (in feet): %f", length * 2.0f);
CMainFrame::GetMainFrame()->SetMessageText(str);
}
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/ScriptDialog.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/ScriptDialog.cpp
index 27af92ec44a..9644c190c17 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/ScriptDialog.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/ScriptDialog.cpp
@@ -1634,7 +1634,7 @@ void ScriptDialog::OnLoad()
} catch(...) {
- DEBUG_CRASH(("threw exception in ScriptDialog::OnLoad"));
+ DEBUG_CRASH(("threw exception in ScriptDialog::OnLoad"));
}
}
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp
index fb03c2a5e98..cb8df0b90a3 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/TeamObjectProperties.cpp
@@ -65,7 +65,7 @@ BEGIN_MESSAGE_MAP(TeamObjectProperties, CPropertyPage)
ON_EN_KILLFOCUS(IDC_MAPOBJECT_VisionDistance, _VisibilityToDict)
ON_EN_KILLFOCUS(IDC_MAPOBJECT_ShroudClearingDistance, _ShroudClearingDistanceToDict)
ON_CBN_SELCHANGE(IDC_MAPOBJECT_Veterancy, _VeterancyToDict)
- ON_BN_CLICKED(IDC_MAPOBJECT_RecruitableAI, _RecruitableAIToDict)
+ ON_BN_CLICKED(IDC_MAPOBJECT_RecruitableAI, _RecruitableAIToDict)
ON_BN_CLICKED(IDC_MAPOBJECT_Selectable, _SelectableToDict)
ON_CBN_SELCHANGE(IDC_MAPOBJECT_Weather, _WeatherToDict)
ON_CBN_SELCHANGE(IDC_MAPOBJECT_Time, _TimeToDict)
@@ -343,14 +343,14 @@ void TeamObjectProperties::_DictToShroudClearingDistance()
void TeamObjectProperties::_DictToRecruitableAI()
{
- Bool recruitableAI = true;
- Bool exists;
- if (m_dictToEdit) {
+ Bool recruitableAI = true;
+ Bool exists;
+ if (m_dictToEdit) {
recruitableAI = m_dictToEdit->getBool(TheKey_teamObjectRecruitableAI, &exists);
- }
+ }
- CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
- if (pItem) {
+ CButton* pItem = (CButton*) GetDlgItem(IDC_MAPOBJECT_RecruitableAI);
+ if (pItem) {
pItem->SetCheck(recruitableAI);
}
}
@@ -682,4 +682,3 @@ BOOL TeamObjectProperties::OnCommand(WPARAM wParam, LPARAM lParam)
{
return CPropertyPage::OnCommand(wParam, lParam);
}
-
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
index 3aeba787257..89af322f931 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
@@ -506,6 +506,30 @@ void WorldHeightMapEdit::loadImagesFromTerrainType( TerrainType *terrain )
}
+Bool WorldHeightMapEdit::getRawTileData(Short tileNdx, Int width, UnsignedByte *buffer, Int bufLen)
+{
+ TileData *pSrc = nullptr;
+ if (tileNdx / 4 < NUM_SOURCE_TILES) {
+ pSrc = m_sourceTiles[tileNdx / 4];
+ }
+ if (bufLen < (width * width * TILE_BYTES_PER_PIXEL)) {
+ return false;
+ }
+ if (pSrc && pSrc->hasRGBDataForWidth(2 * width)) {
+ UnsignedByte *pSrcData = pSrc->getRGBDataForWidth(2 * width);
+ Int xOffset = (tileNdx & 1) ? width : 0;
+ Int yOffset = (tileNdx & 2) ? width : 0;
+ for (Int j = 0; j < width; ++j) {
+ UnsignedByte *pDestData = buffer + j * width * TILE_BYTES_PER_PIXEL;
+ UnsignedByte *pSrcRow = pSrcData + (j + yOffset) * width * TILE_BYTES_PER_PIXEL * 2;
+ pSrcRow += xOffset * TILE_BYTES_PER_PIXEL;
+ memcpy(pDestData, pSrcRow, width * TILE_BYTES_PER_PIXEL);
+ }
+ return true;
+ }
+ return false;
+}
+
UnsignedByte * WorldHeightMapEdit::getPointerToClassTileData(Int texClass)
{
TileData *pSrc = nullptr;
@@ -600,7 +624,11 @@ void WorldHeightMapEdit::saveToFile(DataChunkOutput &chunkWriter)
chunkWriter.closeDataChunk();
/***************BLEND TILE DATA ***************/
+#if RTS_GENERALS
+ chunkWriter.openDataChunk("BlendTileData", K_BLEND_TILE_VERSION_7);
+#else
chunkWriter.openDataChunk("BlendTileData", K_BLEND_TILE_VERSION_8);
+#endif
chunkWriter.writeInt(m_dataSize);
chunkWriter.writeArrayOfBytes((char*)m_tileNdxes, m_dataSize*sizeof(Short));
chunkWriter.writeArrayOfBytes((char*)m_blendTileNdxes, m_dataSize*sizeof(Short));
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
index 5f19126638a..888d8ef5c4e 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
@@ -378,7 +378,9 @@ BOOL CWorldBuilderApp::InitInstance()
initSubsystem(TheScriptEngine, (ScriptEngine*)(new ScriptEngine()));
+#if RTS_ZEROHOUR
TheScriptEngine->turnBreezeOff(); // stop the tree sway.
+#endif
// [2/11/2003]
ini.loadFileDirectory( "Data\\Scripts\\Scripts", INI_LOAD_OVERWRITE, nullptr );
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp
index 8b2eb251fe1..deb3bb4da35 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/mapobjectprops.cpp
@@ -665,7 +665,7 @@ void MapObjectProps::PopSliderFinished(const long sliderID, long theVal)
case IDC_ANGLE_POPUP:
if ( m_posUndoable != nullptr )
{
- REF_PTR_RELEASE(m_posUndoable); // belongs to pDoc now.
+ REF_PTR_RELEASE(m_posUndoable); // belongs to pDoc now.
}
m_posUndoable = nullptr;
break;
@@ -2890,4 +2890,3 @@ void MapObjectProps::OnKillfocusMAPOBJECTXYPosition()
{
SetPosition();
}
-
diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp
index 5f42dc261fa..ccfe7c33acb 100644
--- a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp
+++ b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp
@@ -2168,6 +2168,14 @@ BEGIN_MESSAGE_MAP(WbView3d, WbView)
ON_COMMAND(ID_VIEW_SHOWMACROTEXTURE, OnViewShowmacrotexture)
ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWMACROTEXTURE, OnUpdateViewShowmacrotexture)
ON_COMMAND(ID_EDIT_SELECTMACROTEXTURE, OnEditSelectmacrotexture)
+ ON_COMMAND(ID_LOOK_EAST, OnLookEast)
+ ON_UPDATE_COMMAND_UI(ID_LOOK_EAST, OnUpdateLookEast)
+ ON_COMMAND(ID_LOOK_NORTH, OnLookNorth)
+ ON_UPDATE_COMMAND_UI(ID_LOOK_NORTH, OnUpdateLookNorth)
+ ON_COMMAND(ID_LOOK_SOUTH, OnLookSouth)
+ ON_UPDATE_COMMAND_UI(ID_LOOK_SOUTH, OnUpdateLookSouth)
+ ON_COMMAND(ID_LOOK_WEST, OnLookWest)
+ ON_UPDATE_COMMAND_UI(ID_LOOK_WEST, OnUpdateLookWest)
ON_COMMAND(ID_VIEW_SHOWSOFTWATER, OnViewShowSoftWater)
ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWEXTRABLENDS, OnUpdateViewShowExtraBlends)
ON_COMMAND(ID_VIEW_SHOWEXTRABLENDS, OnViewExtraBlends)
@@ -2929,6 +2937,46 @@ void WbView3d::OnEditSelectmacrotexture()
}
+void WbView3d::OnLookEast()
+{
+ m_cameraAngle = -PI / 2;
+}
+
+void WbView3d::OnUpdateLookEast(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_cameraAngle == -PI / 2 ? 1 : 0);
+}
+
+void WbView3d::OnLookNorth()
+{
+ m_cameraAngle = 0;
+}
+
+void WbView3d::OnUpdateLookNorth(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_cameraAngle == 0 ? 1 : 0);
+}
+
+void WbView3d::OnLookSouth()
+{
+ m_cameraAngle = PI;
+}
+
+void WbView3d::OnUpdateLookSouth(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_cameraAngle == PI ? 1 : 0);
+}
+
+void WbView3d::OnLookWest()
+{
+ m_cameraAngle = PI / 2;
+}
+
+void WbView3d::OnUpdateLookWest(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_cameraAngle == PI / 2 ? 1 : 0);
+}
+
void WbView3d::OnViewShowshadows()
{
m_showShadows = !m_showShadows;
@@ -3260,4 +3308,3 @@ void WbView3d::OnUpdateViewShowSoundCircles(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_showSoundCircles ? 1 : 0);
}
-