From fdcfbb3445e5307587ff8ec99fb410063967bf03 Mon Sep 17 00:00:00 2001 From: Omar Aglan Date: Wed, 12 Aug 2026 00:15:43 +0300 Subject: [PATCH 1/2] unify(polygontrigger): Merge PolygonTrigger and map versions --- .../Include/Common/MapReaderWriterInfo.h | 2 ++ .../Include/GameLogic/PolygonTrigger.h | 12 ++++++++++ .../Source/GameLogic/Map/PolygonTrigger.cpp | 24 +++++++++++++++++++ .../Source/GameLogic/Map/PolygonTrigger.cpp | 8 +++++++ 4 files changed, 46 insertions(+) diff --git a/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h b/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h index c370ac5b3c0..9385f32ac0d 100644 --- a/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h +++ b/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h @@ -39,6 +39,7 @@ #define K_BLEND_TILE_VERSION_5 5 // Added custom cliff u/v coordinates. #define K_BLEND_TILE_VERSION_6 6 // Added extra blend layer for 3 textures in cell. #define K_BLEND_TILE_VERSION_7 7 // Added flag for painting passable/impassable to cells. +#define K_BLEND_TILE_VERSION_8 8 // Added flag for painting passable/impassable to cells. #define K_OBJECTS_VERSION_1 1 // no dict #define K_OBJECTS_VERSION_2 2 // includes dict #define K_OBJECTS_VERSION_3 3 // includes dict @@ -48,6 +49,7 @@ #define K_TRIGGERS_VERSION_1 1 #define K_TRIGGERS_VERSION_2 2 // Added m_isWaterArea #define K_TRIGGERS_VERSION_3 3 // Added m_isRiver & m_riverStart +#define K_TRIGGERS_VERSION_4 4 // Added layer name. #define K_LIGHTING_VERSION_1 1 #define K_LIGHTING_VERSION_2 2 // Added 2 additional global lights for objects. #define K_LIGHTING_VERSION_3 3 // Added 2 additional global lights for terrain. diff --git a/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h b/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h index d3e133834fc..5fc206228cf 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h +++ b/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h @@ -81,6 +81,9 @@ class PolygonTrigger : public MemoryPoolObject, Bool m_exportWithScripts; Bool m_isWaterArea; ///< Used to specify water areas in the map. Bool m_isRiver; ///< Used to specify that a water area is a river. + AsciiString m_layerName; ///< Used to specify the layer in the World Builder. + Bool m_shouldRender; + Bool m_selected; static PolygonTrigger* ThePolygonTriggerListPtr; static Int s_currentID; ///< Current id for new triggers. @@ -116,6 +119,15 @@ class PolygonTrigger : public MemoryPoolObject, void deletePoint(Int ndx); void setTriggerName(AsciiString name) {m_triggerName = name;}; + void setLayerName(AsciiString name) {m_layerName = name;}; + AsciiString getLayerName() const {return m_layerName;} + + void setShouldRender(Bool toggle) {m_shouldRender = toggle;} + Bool getShouldRender() {return m_shouldRender;} + + void setSelected(Bool toggle) {m_selected = toggle;} + Bool getSelected() {return m_selected;} + void getCenterPoint(Coord3D* pOutCoord) const; Real getRadius() const; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp index 6cea7c6227a..218e4fd105e 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp @@ -48,6 +48,8 @@ m_numPoints(0), m_sizePoints(0), m_exportWithScripts(false), m_isWaterArea(false), +m_shouldRender(true), +m_selected(false), m_isRiver(FALSE), m_riverStart(0) { @@ -140,6 +142,7 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu Bool isRiver; Int riverStart; AsciiString triggerName; + AsciiString layerName; // Remove any existing polygon triggers, if any. PolygonTrigger::deleteTriggers(); // just in case. PolygonTrigger *pPrevTrig = nullptr; @@ -148,6 +151,9 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu while (count>0) { count--; triggerName = file.readAsciiString(); + if (info->version >= K_TRIGGERS_VERSION_4) { + layerName = file.readAsciiString(); + } triggerID = file.readInt(); isWater = false; if (info->version >= K_TRIGGERS_VERSION_2) { @@ -163,6 +169,9 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu numPoints = file.readInt(); PolygonTrigger *pTrig = newInstance(PolygonTrigger)(numPoints+1); pTrig->setTriggerName(triggerName); + if (info->version >= K_TRIGGERS_VERSION_4) { + pTrig->setLayerName(layerName); + } pTrig->setWaterArea(isWater); pTrig->setRiver(isRiver); pTrig->setRiverStart(riverStart); @@ -177,6 +186,14 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu loc.z = file.readInt(); pTrig->addPoint(loc); } +#if RTS_ZEROHOUR + if (numPoints<2) { + DEBUG_LOG(("Deleting polygon trigger '%s' with %d points.", + pTrig->getTriggerName().str(), numPoints)); + deleteInstance(pTrig); + continue; + } +#endif if (pPrevTrig) { pPrevTrig->setNextPoly(pTrig); } else { @@ -224,7 +241,11 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu */ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) { +#if RTS_GENERALS chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_3); +#else + chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_4); +#endif PolygonTrigger *pTrig; Int count = 0; @@ -234,6 +255,9 @@ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) chunkWriter.writeInt(count); for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { chunkWriter.writeAsciiString(pTrig->getTriggerName()); +#if RTS_ZEROHOUR + chunkWriter.writeAsciiString(pTrig->getLayerName()); +#endif chunkWriter.writeInt(pTrig->getID()); chunkWriter.writeByte(pTrig->isWaterArea()); chunkWriter.writeByte(pTrig->isRiver()); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp index 4f19ee9cfc2..8d9494a9203 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp @@ -186,12 +186,14 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu loc.z = file.readInt(); pTrig->addPoint(loc); } +#if RTS_ZEROHOUR if (numPoints<2) { DEBUG_LOG(("Deleting polygon trigger '%s' with %d points.", pTrig->getTriggerName().str(), numPoints)); deleteInstance(pTrig); continue; } +#endif if (pPrevTrig) { pPrevTrig->setNextPoly(pTrig); } else { @@ -239,7 +241,11 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu */ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) { +#if RTS_GENERALS + chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_3); +#else chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_4); +#endif PolygonTrigger *pTrig; Int count = 0; @@ -249,7 +255,9 @@ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) chunkWriter.writeInt(count); for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { chunkWriter.writeAsciiString(pTrig->getTriggerName()); +#if RTS_ZEROHOUR chunkWriter.writeAsciiString(pTrig->getLayerName()); +#endif chunkWriter.writeInt(pTrig->getID()); chunkWriter.writeByte(pTrig->isWaterArea()); chunkWriter.writeByte(pTrig->isRiver()); From 2c9beea62e145210bd35349edc95456e18f59654 Mon Sep 17 00:00:00 2001 From: Omar Aglan Date: Wed, 12 Aug 2026 00:17:06 +0300 Subject: [PATCH 2/2] unify(polygontrigger): Move PolygonTrigger and map versions to Core --- Core/GameEngine/CMakeLists.txt | 6 +- .../Include/Common/MapReaderWriterInfo.h | 0 .../Include/GameLogic/PolygonTrigger.h | 0 .../Source/GameLogic/Map/PolygonTrigger.cpp | 0 Generals/Code/GameEngine/CMakeLists.txt | 6 +- .../Include/Common/MapReaderWriterInfo.h | 126 ---- .../Include/GameLogic/PolygonTrigger.h | 152 ----- .../Source/GameLogic/Map/PolygonTrigger.cpp | 568 ------------------ GeneralsMD/Code/GameEngine/CMakeLists.txt | 6 +- scripts/cpp/unify_move_files.py | 4 + 10 files changed, 13 insertions(+), 855 deletions(-) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/MapReaderWriterInfo.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/GameLogic/PolygonTrigger.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp (100%) delete mode 100644 Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h delete mode 100644 Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h delete mode 100644 Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index 0f36ff63383..0914df8d33a 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -70,7 +70,7 @@ set(GAMEENGINE_SRC Include/Common/LocalFile.h Include/Common/LocalFileSystem.h Include/Common/MapObject.h -# Include/Common/MapReaderWriterInfo.h + Include/Common/MapReaderWriterInfo.h Include/Common/MessageStream.h Include/Common/MiniDumper.h Include/Common/MiniLog.h @@ -485,7 +485,7 @@ set(GAMEENGINE_SRC # Include/GameLogic/ObjectScriptStatusBits.h # Include/GameLogic/ObjectTypes.h # Include/GameLogic/PartitionManager.h -# Include/GameLogic/PolygonTrigger.h + Include/GameLogic/PolygonTrigger.h # Include/GameLogic/Powers.h Include/GameLogic/RankInfo.h # Include/GameLogic/ScriptActions.h @@ -851,7 +851,7 @@ set(GAMEENGINE_SRC # Source/GameLogic/AI/AITNGuard.cpp # Source/GameLogic/AI/Squad.cpp # Source/GameLogic/AI/TurretAI.cpp -# Source/GameLogic/Map/PolygonTrigger.cpp + Source/GameLogic/Map/PolygonTrigger.cpp # Source/GameLogic/Map/SidesList.cpp # Source/GameLogic/Map/TerrainLogic.cpp # Source/GameLogic/Object/Armor.cpp diff --git a/GeneralsMD/Code/GameEngine/Include/Common/MapReaderWriterInfo.h b/Core/GameEngine/Include/Common/MapReaderWriterInfo.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/MapReaderWriterInfo.h rename to Core/GameEngine/Include/Common/MapReaderWriterInfo.h diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/PolygonTrigger.h b/Core/GameEngine/Include/GameLogic/PolygonTrigger.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameLogic/PolygonTrigger.h rename to Core/GameEngine/Include/GameLogic/PolygonTrigger.h diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp b/Core/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp rename to Core/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt index 138424cf0d3..a8781d83f60 100644 --- a/Generals/Code/GameEngine/CMakeLists.txt +++ b/Generals/Code/GameEngine/CMakeLists.txt @@ -62,7 +62,7 @@ set(GAMEENGINE_SRC # Include/Common/LocalFile.h # Include/Common/LocalFileSystem.h # Include/Common/MapObject.h - Include/Common/MapReaderWriterInfo.h +# Include/Common/MapReaderWriterInfo.h # Include/Common/MessageStream.h # Include/Common/MiniLog.h # Include/Common/MiscAudio.h @@ -437,7 +437,7 @@ set(GAMEENGINE_SRC Include/GameLogic/ObjectScriptStatusBits.h Include/GameLogic/ObjectTypes.h Include/GameLogic/PartitionManager.h - Include/GameLogic/PolygonTrigger.h +# Include/GameLogic/PolygonTrigger.h Include/GameLogic/Powers.h # Include/GameLogic/RankInfo.h Include/GameLogic/ScriptActions.h @@ -787,7 +787,7 @@ set(GAMEENGINE_SRC Source/GameLogic/AI/AITNGuard.cpp Source/GameLogic/AI/Squad.cpp Source/GameLogic/AI/TurretAI.cpp - Source/GameLogic/Map/PolygonTrigger.cpp +# Source/GameLogic/Map/PolygonTrigger.cpp Source/GameLogic/Map/SidesList.cpp Source/GameLogic/Map/TerrainLogic.cpp Source/GameLogic/Object/Armor.cpp diff --git a/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h b/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h deleted file mode 100644 index 9385f32ac0d..00000000000 --- a/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -** Command & Conquer Generals(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 . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// MapReaderWriterInfo.h -// Version and interface info for map file writers and reader. -// Author: John Ahlquist, October 2001 - -#pragma once - -#define K_HEIGHT_MAP_VERSION_1 1 // Height map cell = 5.0 -#define K_HEIGHT_MAP_VERSION_2 2 // Height map cell = 10.0 -#define K_HEIGHT_MAP_VERSION_3 3 // Added m_borderSize -#define K_HEIGHT_MAP_VERSION_4 4 // Major rev. See comments at bottom of file. -#define K_BLEND_TILE_VERSION_1 1 // Height map cell = 5.0 -#define K_BLEND_TILE_VERSION_2 2 // Height map cell = 10.0 -#define K_BLEND_TILE_VERSION_3 3 // Added long diagonal blends. -#define K_BLEND_TILE_VERSION_4 4 // Added custom edge blends. -#define K_BLEND_TILE_VERSION_5 5 // Added custom cliff u/v coordinates. -#define K_BLEND_TILE_VERSION_6 6 // Added extra blend layer for 3 textures in cell. -#define K_BLEND_TILE_VERSION_7 7 // Added flag for painting passable/impassable to cells. -#define K_BLEND_TILE_VERSION_8 8 // Added flag for painting passable/impassable to cells. -#define K_OBJECTS_VERSION_1 1 // no dict -#define K_OBJECTS_VERSION_2 2 // includes dict -#define K_OBJECTS_VERSION_3 3 // includes dict -#define K_MAP_OBJECT_VERSION_1 1 -#define K_WAYPOINTS_VERSION_1 1 -#define K_PLAYERLIST_VERSION_1 1 -#define K_TRIGGERS_VERSION_1 1 -#define K_TRIGGERS_VERSION_2 2 // Added m_isWaterArea -#define K_TRIGGERS_VERSION_3 3 // Added m_isRiver & m_riverStart -#define K_TRIGGERS_VERSION_4 4 // Added layer name. -#define K_LIGHTING_VERSION_1 1 -#define K_LIGHTING_VERSION_2 2 // Added 2 additional global lights for objects. -#define K_LIGHTING_VERSION_3 3 // Added 2 additional global lights for terrain. -#define K_WORLDDICT_VERSION_1 1 -#define K_MAPPREVIEW_VERSION_1 1 -/** Virtual helper class, so that we can write map data using FILE* or CFile. */ -class OutputStream { -public: - virtual Int write(const void *pData, Int numBytes) = 0; -}; - -/** Virtual helper class, so that we can read in tile and map data from a -variety of sources, such as FILE* or CFile. */ -class InputStream { -public: - virtual Int read(void *pData, Int numBytes) = 0; -}; - -/** Virtual helper class, so that we can read in tile and map data from a -variety of sources, such as FILE* or CFile. */ -class ChunkInputStream : public InputStream{ -public: - virtual Int read(void *pData, Int numBytes) = 0; - virtual UnsignedInt tell() = 0; - virtual Bool absoluteSeek(UnsignedInt pos) = 0; - virtual Bool eof() = 0; -}; - -/** An instance of InputStream that uses a FILE* to read data. */ -class CachedFileInputStream : public ChunkInputStream -{ -protected: - int m_size; - char* m_buffer; - int m_pos; -public: - CachedFileInputStream(); - ~CachedFileInputStream(); - Bool open(AsciiString path); ///< Returns true if open succeeded. - void close(); ///< Explict close. Destructor closes if file is left open. - virtual Int read(void *pData, Int numBytes) override; - virtual UnsignedInt tell() override; - virtual Bool absoluteSeek(UnsignedInt pos) override; - virtual Bool eof() override; - void rewind(); -}; - -/** An instance of InputStream that uses a FILE* to read data. */ -/* Always using Cached version, as that lets us do compression, etc easily -class FileInputStream : public ChunkInputStream -{ -protected: - File *m_file; -public: - FileInputStream(); - ~FileInputStream(); - Bool open(AsciiString path); ///< Returns true if open succeeded. - void close(); ///< Explict close. Destructor closes if file is left open. - virtual Int read(void *pData, Int numBytes); - virtual UnsignedInt tell(); - virtual Bool absoluteSeek(UnsignedInt pos); - virtual Bool eof(); - void rewind(); -}; -*/ - -/* - rev K_HEIGHT_MAP_VERSION_4 - - This is a major rev of the heightmap chunk. Here's the basic overview of what has happened: - We now support multiple boundary areas. They are stored in a vector of ICoord2Ds. The lower- - left corner is always (0,0), and the ICoord2D specifies the top-right coordinate. - The boundary also contains a name. -*/ diff --git a/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h b/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h deleted file mode 100644 index 5fc206228cf..00000000000 --- a/Generals/Code/GameEngine/Include/GameLogic/PolygonTrigger.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -** Command & Conquer Generals(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 . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - - -// PolygonTrigger.h -// Class to encapsulate polygon triggers for maps. -// Note - Polygons are used for two reasons - one is area triggers for -// scripts, so units can be tested for entering or exiting areas, and -// second to specify areas that are filled with water in the map. -// See the m_isWaterArea to differentiate. -// Author: John Ahlquist, November 2001 - -#pragma once - -#include "Common/GameMemory.h" -#include "Common/Snapshot.h" -#include "Common/STLTypedefs.h" - -class DataChunkInput; -class DataChunkOutput; -struct DataChunkInfo; -class PolygonTrigger; -class Xfer; - -// ------------------------------------------------------------------------------------------------ -/** Water handles are used to represent instances of areas of water, no matter which type - * of implementation the water is (grid, trigger area, etc) */ -// ------------------------------------------------------------------------------------------------ -class WaterHandle -{ - -public: - - WaterHandle() { m_polygon = nullptr; } - - ///@todo we need to formalize the water systems - PolygonTrigger *m_polygon; ///< valid when water is a polygon area, nullptr if water is a grid - -}; - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -class PolygonTrigger : public MemoryPoolObject, - public Snapshot -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(PolygonTrigger, "PolygonTrigger") - -protected: - PolygonTrigger* m_nextPolygonTrigger; ///< linked list. - AsciiString m_triggerName; ///< The name of this polygon area. - Int m_triggerID; ///< Unique int id for the trigger. - WaterHandle m_waterHandle; ///< handle to use this polygon as a water table - ICoord3D* m_points; ///< Points that are the polygon. - Int m_numPoints; ///< Num points in m_points. - Int m_sizePoints; ///< Space allocated for m_points. - mutable IRegion2D m_bounds; ///< 2D bounding box for quick checks. - mutable Real m_radius; - Int m_riverStart; ///< Identifies the start point of the river. - mutable Bool m_boundsNeedsUpdate; - Bool m_exportWithScripts; - Bool m_isWaterArea; ///< Used to specify water areas in the map. - Bool m_isRiver; ///< Used to specify that a water area is a river. - AsciiString m_layerName; ///< Used to specify the layer in the World Builder. - Bool m_shouldRender; - Bool m_selected; - - static PolygonTrigger* ThePolygonTriggerListPtr; - static Int s_currentID; ///< Current id for new triggers. - -protected: - void reallocate(); - void updateBounds() const; - - // snapshot methods - virtual void crc( Xfer *xfer ) override; - virtual void xfer( Xfer *xfer ) override; - virtual void loadPostProcess() override; - -public: - PolygonTrigger(Int initialAllocation); - //~PolygonTrigger(); ///< Note that deleting the head of a list deletes all linked objects in the list. - -public: - static PolygonTrigger *getFirstPolygonTrigger() {return ThePolygonTriggerListPtr;} - static PolygonTrigger *getPolygonTriggerByID(Int triggerID); - static Bool ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData); - /// Writes Triggers Info - static void WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter); - static void deleteTriggers(); - -public: - static void addPolygonTrigger(PolygonTrigger *pTrigger); - static void removePolygonTrigger(PolygonTrigger *pTrigger); - void setNextPoly(PolygonTrigger *nextPoly) {m_nextPolygonTrigger = nextPoly;} ///< Link the next map object. - void addPoint(const ICoord3D &point); - void setPoint(const ICoord3D &point, Int ndx); - void insertPoint(const ICoord3D &point, Int ndx); - void deletePoint(Int ndx); - void setTriggerName(AsciiString name) {m_triggerName = name;}; - - void setLayerName(AsciiString name) {m_layerName = name;}; - AsciiString getLayerName() const {return m_layerName;} - - void setShouldRender(Bool toggle) {m_shouldRender = toggle;} - Bool getShouldRender() {return m_shouldRender;} - - void setSelected(Bool toggle) {m_selected = toggle;} - Bool getSelected() {return m_selected;} - - void getCenterPoint(Coord3D* pOutCoord) const; - Real getRadius() const; - -public: - const ICoord3D *getPoint(Int ndx) const {if (ndx<0) ndx=0; if (ndx>=m_numPoints) ndx=m_numPoints-1; return m_points+ndx;} ///< Get a point. - Int getNumPoints() const {return m_numPoints;} - Int getID() const {return m_triggerID;} - PolygonTrigger *getNext() {return m_nextPolygonTrigger;} - const PolygonTrigger *getNext() const {return m_nextPolygonTrigger;} - const AsciiString& getTriggerName() const {return m_triggerName;} ///< Gets the trigger name. - Bool pointInTrigger(ICoord3D &point) const; - Bool doExportWithScripts() const {return m_exportWithScripts;} - void setDoExportWithScripts(Bool val) {m_exportWithScripts = val;} - Bool isWaterArea() const {return m_isWaterArea;} - void setWaterArea(Bool val) {m_isWaterArea = val;} - Bool isRiver() const {return m_isRiver;} - void setRiver(Bool val) {m_isRiver = val;} - Int getRiverStart() const {return m_riverStart;} - void setRiverStart(Int val) {m_riverStart = val;} - const WaterHandle* getWaterHandle() const; - Bool isValid() const; -}; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp deleted file mode 100644 index 218e4fd105e..00000000000 --- a/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp +++ /dev/null @@ -1,568 +0,0 @@ -/* -** Command & Conquer Generals(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 . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// PolygonTrigger.cpp -// Class to encapsulate polygon trigger areas. -// Author: John Ahlquist, November 2001 - -#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine - -#include "Common/DataChunk.h" -#include "Common/MapObject.h" -#include "Common/MapReaderWriterInfo.h" -#include "Common/Xfer.h" -#include "GameLogic/PolygonTrigger.h" -#include "GameLogic/TerrainLogic.h" - -/* ********* PolygonTrigger class ****************************/ -PolygonTrigger *PolygonTrigger::ThePolygonTriggerListPtr = nullptr; -Int PolygonTrigger::s_currentID = 1; -/** - PolygonTrigger - Constructor. -*/ -PolygonTrigger::PolygonTrigger(Int initialAllocation) : -m_nextPolygonTrigger(nullptr), -m_points(nullptr), -m_numPoints(0), -m_sizePoints(0), -m_exportWithScripts(false), -m_isWaterArea(false), -m_shouldRender(true), -m_selected(false), -m_isRiver(FALSE), -m_riverStart(0) -{ - if (initialAllocation < 2) initialAllocation = 2; - m_points = NEW ICoord3D[initialAllocation]; // pool[]ify - m_sizePoints = initialAllocation; - m_triggerID = s_currentID++; - - m_waterHandle.m_polygon = this; - -} - - -/** - PolygonTrigger - Destructor - note - if linked, deletes linked items. -*/ -PolygonTrigger::~PolygonTrigger() -{ - delete [] m_points; - m_points = nullptr; - - if (m_nextPolygonTrigger) { - PolygonTrigger *cur = m_nextPolygonTrigger; - PolygonTrigger *next; - while (cur) { - next = cur->getNext(); - cur->setNextPoly(nullptr); // prevents recursion. - deleteInstance(cur); - cur = next; - } - } -} - - -/** - PolygonTrigger::reallocate - increases the size of the points list. - NOTE: It is expected that this will only get called in the editor, as in the game - the poly triggers don't change. -*/ -void PolygonTrigger::reallocate() -{ - DEBUG_ASSERTCRASH(m_numPoints <= m_sizePoints, ("Invalid m_numPoints.")); - if (m_numPoints == m_sizePoints) { - if (m_sizePoints > INT_MAX / 2) { - DEBUG_CRASH(("Too many points to allocate.")); - return; - } - // Reallocate. - m_sizePoints += m_sizePoints; - ICoord3D *newPts = NEW ICoord3D[m_sizePoints]; - Int i; - for (i=0; igetNext() ) - if( poly->getID() == triggerID ) - return poly; - - // not found - return nullptr; - -} - -/** -* PolygonTrigger::ParsePolygonTriggersDataChunk - read a polygon triggers chunk. -* Format is the newer CHUNKY format. -* See PolygonTrigger::WritePolygonTriggersDataChunk for the writer. -* Input: DataChunkInput -* -*/ -Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - Int count; - Int numPoints; - Int triggerID; - Int maxTriggerId = 0; - Bool isWater; - Bool isRiver; - Int riverStart; - AsciiString triggerName; - AsciiString layerName; - // Remove any existing polygon triggers, if any. - PolygonTrigger::deleteTriggers(); // just in case. - PolygonTrigger *pPrevTrig = nullptr; - ICoord3D loc; - count = file.readInt(); - while (count>0) { - count--; - triggerName = file.readAsciiString(); - if (info->version >= K_TRIGGERS_VERSION_4) { - layerName = file.readAsciiString(); - } - triggerID = file.readInt(); - isWater = false; - if (info->version >= K_TRIGGERS_VERSION_2) { - isWater = file.readByte(); - } - isRiver = false; - riverStart = 0; - if (info->version >= K_TRIGGERS_VERSION_3) { - isRiver = file.readByte(); - riverStart = file.readInt(); - } - - numPoints = file.readInt(); - PolygonTrigger *pTrig = newInstance(PolygonTrigger)(numPoints+1); - pTrig->setTriggerName(triggerName); - if (info->version >= K_TRIGGERS_VERSION_4) { - pTrig->setLayerName(layerName); - } - pTrig->setWaterArea(isWater); - pTrig->setRiver(isRiver); - pTrig->setRiverStart(riverStart); - pTrig->m_triggerID = triggerID; - if (triggerID > maxTriggerId) { - maxTriggerId = triggerID; - } - Int i; - for (i=0; iaddPoint(loc); - } -#if RTS_ZEROHOUR - if (numPoints<2) { - DEBUG_LOG(("Deleting polygon trigger '%s' with %d points.", - pTrig->getTriggerName().str(), numPoints)); - deleteInstance(pTrig); - continue; - } -#endif - if (pPrevTrig) { - pPrevTrig->setNextPoly(pTrig); - } else { - PolygonTrigger::addPolygonTrigger(pTrig); - } - pPrevTrig = pTrig; - } - if (info->version == K_TRIGGERS_VERSION_1) - { - // before water areas existed, so create a default one. - PolygonTrigger *pTrig = newInstance(PolygonTrigger)(4); - pTrig->setWaterArea(true); -#ifdef RTS_DEBUG - pTrig->setTriggerName("AutoAddedWaterAreaTrigger"); -#endif - pTrig->m_triggerID = maxTriggerId++; - loc.x = -30*MAP_XY_FACTOR; - loc.y = -30*MAP_XY_FACTOR; - loc.z = 7; // The old water position. - pTrig->addPoint(loc); - loc.x = 30*MAP_XY_FACTOR + TheGlobalData->m_waterExtentX; - pTrig->addPoint(loc); - loc.y = 30*MAP_XY_FACTOR + TheGlobalData->m_waterExtentY; - pTrig->addPoint(loc); - loc.x = -30*MAP_XY_FACTOR; - pTrig->addPoint(loc); - if (pPrevTrig) { - pPrevTrig->setNextPoly(pTrig); - } else { - PolygonTrigger::addPolygonTrigger(pTrig); - } - pPrevTrig = pTrig; - } - s_currentID = maxTriggerId+1; - DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Incorrect data file length.")); - return true; -} - -/** -* PolygonTrigger::WritePolygonTriggersDataChunk - Writes a Polygon triggers chunk. -* Format is the newer CHUNKY format. -* See PolygonTrigger::ParsePolygonTriggersDataChunk for the reader. -* Input: DataChunkInput -* -*/ -void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) -{ -#if RTS_GENERALS - chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_3); -#else - chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_4); -#endif - - PolygonTrigger *pTrig; - Int count = 0; - for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { - count++; - } - chunkWriter.writeInt(count); - for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { - chunkWriter.writeAsciiString(pTrig->getTriggerName()); -#if RTS_ZEROHOUR - chunkWriter.writeAsciiString(pTrig->getLayerName()); -#endif - chunkWriter.writeInt(pTrig->getID()); - chunkWriter.writeByte(pTrig->isWaterArea()); - chunkWriter.writeByte(pTrig->isRiver()); - chunkWriter.writeInt(pTrig->getRiverStart()); - chunkWriter.writeInt(pTrig->getNumPoints()); - Int i; - for (i=0; igetNumPoints(); i++) { - ICoord3D loc = *pTrig->getPoint(i); - chunkWriter.writeInt( loc.x); - chunkWriter.writeInt( loc.y); - chunkWriter.writeInt( loc.z); - } - } - - chunkWriter.closeDataChunk(); -} - -/** - PolygonTrigger::updateBounds - Updates the bounds. -*/ -void PolygonTrigger::updateBounds() const -{ - const Int BIG_INT=0x7ffff0; - m_bounds.lo.x = m_bounds.lo.y = BIG_INT; - m_bounds.hi.x = m_bounds.hi.y = -BIG_INT; - Int i; - for (i=0; i m_bounds.hi.x) m_bounds.hi.x = m_points[i].x; - if (m_points[i].y > m_bounds.hi.y) m_bounds.hi.y = m_points[i].y; - } - m_boundsNeedsUpdate = 0; - Real halfWidth = (m_bounds.hi.x - m_bounds.lo.x) / 2.0f; - Real halfHeight = (m_bounds.hi.y + m_bounds.lo.y) / 2.0f; - - m_radius = sqrt(halfHeight*halfHeight + halfWidth*halfWidth); -} - - -/** - PolygonTrigger::addPolygonTrigger adds a trigger to the list of triggers. -*/ -void PolygonTrigger::addPolygonTrigger(PolygonTrigger *pTrigger) -{ - for (PolygonTrigger *pTrig=getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { - DEBUG_ASSERTCRASH(pTrig != pTrigger, ("Attempting to add trigger already in list.")); - if (pTrig==pTrigger) return; - } - pTrigger->m_nextPolygonTrigger = ThePolygonTriggerListPtr; - ThePolygonTriggerListPtr = pTrigger; -} - -/** - PolygonTrigger::removePolygonTrigger removes a trigger to the list of - triggers. note - does NOT delete pTrigger. -*/ -void PolygonTrigger::removePolygonTrigger(PolygonTrigger *pTrigger) -{ - PolygonTrigger *pPrev = nullptr; - PolygonTrigger *pTrig=getFirstPolygonTrigger(); - for (; pTrig; pTrig = pTrig->getNext()) { - if (pTrig==pTrigger) break; - pPrev = pTrig; - } - DEBUG_ASSERTCRASH(pTrig, ("Attempting to remove a polygon not in the list.")); - if (pTrig) { - if (pPrev) { - DEBUG_ASSERTCRASH(pTrigger==pPrev->m_nextPolygonTrigger, ("Logic error. jba.")); - pPrev->m_nextPolygonTrigger = pTrig->m_nextPolygonTrigger; - } else { - DEBUG_ASSERTCRASH(pTrigger==ThePolygonTriggerListPtr, ("Logic error. jba.")); - ThePolygonTriggerListPtr = pTrig->m_nextPolygonTrigger; - } - } - pTrigger->m_nextPolygonTrigger = nullptr; -} - -/** - PolygonTrigger::deleteTriggers Deletes list of triggers. -*/ -void PolygonTrigger::deleteTriggers() -{ - PolygonTrigger *pList = ThePolygonTriggerListPtr; - ThePolygonTriggerListPtr = nullptr; - s_currentID = 1; - deleteInstance(pList); -} - -/** - PolygonTrigger::addPoint adds a point at the end of the polygon. - NOTE: It is expected that this will only get called in the editor, as in the game - the poly triggers don't change. -*/ -void PolygonTrigger::addPoint(const ICoord3D &point) -{ - DEBUG_ASSERTCRASH(m_numPoints <= m_sizePoints, ("Invalid m_numPoints.")); - if (m_numPoints == m_sizePoints) { - reallocate(); - } - m_points[m_numPoints] = point; - m_numPoints++; - m_boundsNeedsUpdate = true; -} - -/** - PolygonTrigger::setPoint sets the point at index ndx. - NOTE: It is expected that this will only get called in the editor, as in the game - the poly triggers don't change. -*/ -void PolygonTrigger::setPoint(const ICoord3D &point, Int ndx) -{ - DEBUG_ASSERTCRASH(ndx>=0 && ndx <= m_numPoints, ("Invalid ndx.")); - if (ndx<0) return; - if (ndx == m_numPoints) { // we are setting first available unused point - addPoint(point); - return; - } - if (ndx>m_numPoints) { // Can't skip points. - return; - } - m_points[ndx] = point; - m_boundsNeedsUpdate = true; -} - -/** - PolygonTrigger::insertPoint . - NOTE: It is expected that this will only get called in the editor, as in the game - the poly triggers don't change. -*/ -void PolygonTrigger::insertPoint(const ICoord3D &point, Int ndx) -{ - DEBUG_ASSERTCRASH(ndx>=0 && ndx <= m_numPoints, ("Invalid ndx.")); - if (ndx<0) return; - if (ndx == m_numPoints) { // we are setting first available unused point - addPoint(point); - return; - } - if (m_numPoints == m_sizePoints) { - reallocate(); - } - Int i; - for (i=m_numPoints; i>ndx; i--) { - m_points[i] = m_points[i-1]; - } - m_points[ndx] = point; - m_numPoints++; - m_boundsNeedsUpdate = true; -} - -/** - PolygonTrigger::deletePoint . - NOTE: It is expected that this will only get called in the editor, as in the game - the poly triggers don't change. -*/ -void PolygonTrigger::deletePoint(Int ndx) -{ - DEBUG_ASSERTCRASH(ndx>=0 && ndx < m_numPoints, ("Invalid ndx.")); - if (ndx<0 || ndx>=m_numPoints) return; - Int i; - for (i=ndx; igetGroundHeight(pOutCoord->x, pOutCoord->y); -} - -Real PolygonTrigger::getRadius() const -{ - if (m_boundsNeedsUpdate) { - updateBounds(); - } - return m_radius; -} - - -/** - PolygonTrigger - pointInTrigger. -*/ -Bool PolygonTrigger::pointInTrigger(ICoord3D &point) const -{ - if (m_boundsNeedsUpdate) { - updateBounds(); - } - if (point.x < m_bounds.lo.x) return false; - if (point.y < m_bounds.lo.y) return false; - if (point.x > m_bounds.hi.x) return false; - if (point.y > m_bounds.hi.y) return false; - - Bool inside = false; - Int i; - for (i=0; i= point.y && pt2.y >= point.y) continue; - if (pt1.xinfinity. - Int dy = pt2.y-pt1.y; - Int dx = pt2.x-pt1.x; - - Real intersectionX = pt1.x + (dx * (point.y-pt1.y)) / ((Real)dy); - if (intersectionX >= point.x) { - inside = !inside; - } - } - return inside; -} - -// ------------------------------------------------------------------------------------------------ -const WaterHandle* PolygonTrigger::getWaterHandle() const -{ - - if( isWaterArea() ) - return &m_waterHandle; - - return nullptr; // this polygon trigger is not a water area - -} - -Bool PolygonTrigger::isValid() const -{ - if (m_numPoints == 0) { - return FALSE; - } - - return TRUE; -} - -// ------------------------------------------------------------------------------------------------ -/** CRC */ -// ------------------------------------------------------------------------------------------------ -void PolygonTrigger::crc( Xfer *xfer ) -{ - -} - -// ------------------------------------------------------------------------------------------------ -/** Xfer method - * Version Info: - * 1: Initial version */ -// ------------------------------------------------------------------------------------------------ -void PolygonTrigger::xfer( Xfer *xfer ) -{ - - // version - XferVersion currentVersion = 1; - XferVersion version = currentVersion; - xfer->xferVersion( &version, currentVersion ); - - // number of data points - xfer->xferInt( &m_numPoints ); - - // xfer all data points - ICoord3D *point; - for( Int i = 0; i < m_numPoints; ++i ) - { - - // get this point - point = &m_points[ i ]; - - // xfer point - xfer->xferICoord3D( point ); - - } - - // bounds - xfer->xferIRegion2D( &m_bounds ); - - // radius - xfer->xferReal( &m_radius ); - - // bounds need update - xfer->xferBool( &m_boundsNeedsUpdate ); - -} - -// ------------------------------------------------------------------------------------------------ -/** Load post process */ -// ------------------------------------------------------------------------------------------------ -void PolygonTrigger::loadPostProcess() -{ - -} diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index e5b82e2db38..425ed8a58ee 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -65,7 +65,7 @@ set(GAMEENGINE_SRC # Include/Common/LocalFile.h # Include/Common/LocalFileSystem.h # Include/Common/MapObject.h - Include/Common/MapReaderWriterInfo.h +# Include/Common/MapReaderWriterInfo.h # Include/Common/MessageStream.h # Include/Common/MiniLog.h # Include/Common/MiscAudio.h @@ -477,7 +477,7 @@ set(GAMEENGINE_SRC Include/GameLogic/ObjectScriptStatusBits.h Include/GameLogic/ObjectTypes.h Include/GameLogic/PartitionManager.h - Include/GameLogic/PolygonTrigger.h +# Include/GameLogic/PolygonTrigger.h Include/GameLogic/Powers.h # Include/GameLogic/RankInfo.h Include/GameLogic/ScriptActions.h @@ -834,7 +834,7 @@ set(GAMEENGINE_SRC Source/GameLogic/AI/AITNGuard.cpp Source/GameLogic/AI/Squad.cpp Source/GameLogic/AI/TurretAI.cpp - Source/GameLogic/Map/PolygonTrigger.cpp +# Source/GameLogic/Map/PolygonTrigger.cpp Source/GameLogic/Map/SidesList.cpp Source/GameLogic/Map/TerrainLogic.cpp Source/GameLogic/Object/Armor.cpp diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index 8c399c3d1d0..c12aeb76dc3 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -689,6 +689,10 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/Common/W3DConvert.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/Common/W3DConvert.h") #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/Common/W3DConvert.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/Common/W3DConvert.cpp") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/Common/MapReaderWriterInfo.h", Game.CORE, "GameEngine/Include/Common/MapReaderWriterInfo.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameLogic/PolygonTrigger.h", Game.CORE, "GameEngine/Include/GameLogic/PolygonTrigger.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp", Game.CORE, "GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp") + return