From bcf2d944dce0f84f3a2313dfded20c5757040b0b Mon Sep 17 00:00:00 2001 From: Omar Aglan Date: Sat, 22 Aug 2026 22:14:37 +0300 Subject: [PATCH 1/2] unify(map): Merge GameLogic map headers and implementations (#3189) --- Core/GameEngine/Include/Common/GameDefines.h | 6 +++ .../Include/Common/MapReaderWriterInfo.h | 2 + .../Include/GameLogic/PolygonTrigger.h | 12 +++++ .../Include/GameLogic/TerrainLogic.h | 1 + .../Source/GameLogic/Map/PolygonTrigger.cpp | 27 +++++++++- .../Source/GameLogic/Map/SidesList.cpp | 12 ++++- .../Source/GameLogic/Map/TerrainLogic.cpp | 51 ++++++++++++++++++- .../Include/Common/MapReaderWriterInfo.h | 4 +- .../Source/GameLogic/Map/PolygonTrigger.cpp | 13 ++++- .../Source/GameLogic/Map/TerrainLogic.cpp | 8 --- 10 files changed, 121 insertions(+), 15 deletions(-) diff --git a/Core/GameEngine/Include/Common/GameDefines.h b/Core/GameEngine/Include/Common/GameDefines.h index 0fcd3b1df3c..d58ffcb0306 100644 --- a/Core/GameEngine/Include/Common/GameDefines.h +++ b/Core/GameEngine/Include/Common/GameDefines.h @@ -20,6 +20,8 @@ #include "WWLib/WWDefines.h" +// Note: Retail compatibility must not be broken before this project officially does. +// Use RETAIL_COMPATIBLE_CRC, RETAIL_COMPATIBLE_DATA and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. #ifndef PRESERVE_BUILDING_RESUMPTION_DELAY #define PRESERVE_BUILDING_RESUMPTION_DELAY (0) // The fix for this unfavorable behavior was approved by the Game Design Committee. #endif @@ -103,6 +105,10 @@ #define RETAIL_COMPATIBLE_CRC (1) // Game is expected to be CRC compatible with retail Generals 1.08, Zero Hour 1.04 #endif +#ifndef RETAIL_COMPATIBLE_DATA +#define RETAIL_COMPATIBLE_DATA (1) // Game and tool data files are expected to be compatible with retail Generals 1.08 and Zero Hour 1.04 +#endif + #ifndef RETAIL_COMPATIBLE_XFER_SAVE #define RETAIL_COMPATIBLE_XFER_SAVE (1) // Game is expected to be Xfer Save compatible with retail Generals 1.08, Zero Hour 1.04 #endif diff --git a/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h b/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h index 9089411e091..a9d0e93889e 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. Added in Zero Hour. #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. Added in Zero Hour. #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/Include/GameLogic/TerrainLogic.h b/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h index ad1db103499..c9e0ddb778b 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h +++ b/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h @@ -312,6 +312,7 @@ class TerrainLogic : public Snapshot, void setActiveBoundary(Int newActiveBoundary); void flattenTerrain(Object *obj); ///< Flatten the terrain under a building. + void createCraterInTerrain(Object *obj); ///< Flatten the terrain under a building. protected: diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp index 53547241570..cf17f0f5a5e 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_GENERALS && RETAIL_COMPATIBLE_CRC) + 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,12 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu */ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) { - chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_3); +#if RTS_GENERALS && RETAIL_COMPATIBLE_DATA + const DataChunkVersionType version = K_TRIGGERS_VERSION_3; +#else + const DataChunkVersionType version = K_TRIGGERS_VERSION_4; +#endif + chunkWriter.openDataChunk("PolygonTriggers", version); PolygonTrigger *pTrig; Int count = 0; @@ -234,6 +256,9 @@ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) chunkWriter.writeInt(count); for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { chunkWriter.writeAsciiString(pTrig->getTriggerName()); + if (version >= K_TRIGGERS_VERSION_4) { + chunkWriter.writeAsciiString(pTrig->getLayerName()); + } chunkWriter.writeInt(pTrig->getID()); chunkWriter.writeByte(pTrig->isWaterArea()); chunkWriter.writeByte(pTrig->isRiver()); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp index 93bb5693832..63286156a63 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp @@ -429,13 +429,23 @@ static AsciiString static_readPlayerNames[MAX_PLAYER_COUNT]; * Input: DataChunkInput * */ +#define K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_1 1 +#define K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_2 2 + static Bool ParsePlayersDataChunk(DataChunkInput &file, DataChunkInfo *info, void *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; static_readPlayerNames[i] = file.readAsciiString(); + if (readDicts) { + Dict sideDict = file.readDict(); + } } DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Unexpected data left over.")); return true; @@ -1121,7 +1131,7 @@ void TeamsInfoRec::addTeam(const Dict* d) TEAM_ALLOC_CHUNK = 8 ///< how many teams to alloc at a time }; - DEBUG_ASSERTCRASH(m_numTeams < 1024, ("hmm, seems like an awful lot of teams...")); + DEBUG_ASSERTCRASH(m_numTeams < 2048, ("%d teams have been allocated (so far). This seems excessive.", m_numTeams )); if (m_numTeams >= m_numTeamsAllocated) { // pool[]ify diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp index c00d3096810..dff9694d14a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp @@ -2346,7 +2346,7 @@ void TerrainLogic::setWaterHeight( const WaterHandle *water, Real height, Real d Coord3D center; center.x = affectedRegion.lo.x + affectedRegion.width() / 2.0f; center.y = affectedRegion.lo.y + affectedRegion.height() / 2.0f; - center.z = 0.0f; // irrelavant + center.z = 0.0f; // irrelevant // the max radius to scan around us is the diagonal of the bounding region Real maxDist = sqrt( affectedRegion.width() * affectedRegion.width() + @@ -2828,6 +2828,55 @@ void TerrainLogic::flattenTerrain(Object *obj) } +// ------------------------------------------------------------------------------------------------ +/** Dig a deep circular gorge into the terrain beneath an object. */ +// ------------------------------------------------------------------------------------------------ +void TerrainLogic::createCraterInTerrain(Object *obj) +{ + if (obj->getGeometryInfo().getIsSmall()) + return; + + const Coord3D *pos = obj->getPosition(); + Real radius = obj->getGeometryInfo().getMajorRadius(); + + if ( radius <= 0.0f ) + return; // sanity + + ICoord2D iMin, iMax; + iMin.x = REAL_TO_INT_FLOOR( ( pos->x - radius ) / MAP_XY_FACTOR ); + iMin.y = REAL_TO_INT_FLOOR( ( pos->y - radius ) / MAP_XY_FACTOR ); + iMax.x = REAL_TO_INT_FLOOR( ( pos->x + radius ) / MAP_XY_FACTOR ); + iMax.y = REAL_TO_INT_FLOOR( ( pos->y + radius ) / MAP_XY_FACTOR ); + + Real deltaX, deltaY; + + for (Int i = iMin.x; i <= iMax.x; i++ ) + { + for ( Int j=0; j <= iMax.y; j++ ) + { + deltaX = ( i * MAP_XY_FACTOR ) - pos->x; + deltaY = ( j * MAP_XY_FACTOR ) - pos->y; + + Real distance = sqrt( sqr( deltaX ) + sqr( deltaY ) ); + + if ( distance < radius ) //inside circle + { + ICoord2D gridPos; + gridPos.x = i; + gridPos.y = j; + + + Real displacementAmount = radius * (1.0f - distance / radius ); + + Int targetHeight = MAX( 1, TheTerrainVisual->getRawMapHeight( &gridPos ) - displacementAmount ); + + TheTerrainVisual->setRawMapHeight( &gridPos, targetHeight ); + } + } + } + +} + // ------------------------------------------------------------------------------------------------ /** CRC */ // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngine/Include/Common/MapReaderWriterInfo.h b/GeneralsMD/Code/GameEngine/Include/Common/MapReaderWriterInfo.h index 773beecd74d..0d42140ef47 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/MapReaderWriterInfo.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/MapReaderWriterInfo.h @@ -39,7 +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_BLEND_TILE_VERSION_8 8 // Added flag for painting passable/impassable to cells. Added in Zero Hour. #define K_OBJECTS_VERSION_1 1 // no dict #define K_OBJECTS_VERSION_2 2 // includes dict #define K_OBJECTS_VERSION_3 3 // includes dict @@ -49,7 +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_TRIGGERS_VERSION_4 4 // Added layer name. Added in Zero Hour. #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/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp index 6f45a4cc4b9..337630511c2 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_GENERALS && RETAIL_COMPATIBLE_CRC) 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,12 @@ Bool PolygonTrigger::ParsePolygonTriggersDataChunk(DataChunkInput &file, DataChu */ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) { - chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_4); +#if RTS_GENERALS && RETAIL_COMPATIBLE_DATA + const DataChunkVersionType version = K_TRIGGERS_VERSION_3; +#else + const DataChunkVersionType version = K_TRIGGERS_VERSION_4; +#endif + chunkWriter.openDataChunk("PolygonTriggers", version); PolygonTrigger *pTrig; Int count = 0; @@ -249,7 +256,9 @@ void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) chunkWriter.writeInt(count); for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { chunkWriter.writeAsciiString(pTrig->getTriggerName()); - chunkWriter.writeAsciiString(pTrig->getLayerName()); + if (version >= K_TRIGGERS_VERSION_4) { + chunkWriter.writeAsciiString(pTrig->getLayerName()); + } chunkWriter.writeInt(pTrig->getID()); chunkWriter.writeByte(pTrig->isWaterArea()); chunkWriter.writeByte(pTrig->isRiver()); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp index f2173b15e4b..7335f4b057a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp @@ -2828,8 +2828,6 @@ void TerrainLogic::flattenTerrain(Object *obj) } - - // ------------------------------------------------------------------------------------------------ /** Dig a deep circular gorge into the terrain beneath an object. */ // ------------------------------------------------------------------------------------------------ @@ -2879,12 +2877,6 @@ void TerrainLogic::createCraterInTerrain(Object *obj) } - - - - - - // ------------------------------------------------------------------------------------------------ /** CRC */ // ------------------------------------------------------------------------------------------------ From 23c73bd0d1e5a4166fb4f117ede43c74c88d394f Mon Sep 17 00:00:00 2001 From: Omar Aglan Date: Sat, 22 Aug 2026 23:01:31 +0300 Subject: [PATCH 2/2] unify(map): Move GameLogic map headers and implementations to Core (#3189) --- Core/GameEngine/CMakeLists.txt | 14 +- .../Include/Common/MapReaderWriterInfo.h | 0 .../Include/GameLogic/PolygonTrigger.h | 0 .../GameEngine/Include/GameLogic/SidesList.h | 0 .../Include/GameLogic/TerrainLogic.h | 0 .../Source/GameLogic/Map/PolygonTrigger.cpp | 0 .../Source/GameLogic/Map/SidesList.cpp | 0 .../Source/GameLogic/Map/TerrainLogic.cpp | 0 Generals/Code/GameEngine/CMakeLists.txt | 14 +- .../Include/Common/MapReaderWriterInfo.h | 126 -- .../Include/GameLogic/PolygonTrigger.h | 152 --- .../GameEngine/Include/GameLogic/SidesList.h | 389 ------ .../Include/GameLogic/TerrainLogic.h | 379 ------ .../Source/GameLogic/Map/SidesList.cpp | 1166 ----------------- GeneralsMD/Code/GameEngine/CMakeLists.txt | 14 +- scripts/cpp/unify_move_files.py | 8 + 16 files changed, 29 insertions(+), 2233 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/Include/GameLogic/SidesList.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/GameLogic/TerrainLogic.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/GameLogic/Map/SidesList.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/GameLogic/Map/TerrainLogic.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/Include/GameLogic/SidesList.h delete mode 100644 Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h delete mode 100644 Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index c462ee691f2..cb195ba0274 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 @@ -487,16 +487,16 @@ 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 # Include/GameLogic/ScriptConditions.h # Include/GameLogic/ScriptEngine.h # Include/GameLogic/Scripts.h -# Include/GameLogic/SidesList.h + Include/GameLogic/SidesList.h # Include/GameLogic/Squad.h -# Include/GameLogic/TerrainLogic.h + Include/GameLogic/TerrainLogic.h # Include/GameLogic/TurretAI.h # Include/GameLogic/VictoryConditions.h # Include/GameLogic/Weapon.h @@ -855,9 +855,9 @@ 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/SidesList.cpp -# Source/GameLogic/Map/TerrainLogic.cpp + Source/GameLogic/Map/PolygonTrigger.cpp + Source/GameLogic/Map/SidesList.cpp + Source/GameLogic/Map/TerrainLogic.cpp # Source/GameLogic/Object/Armor.cpp # Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp # Source/GameLogic/Object/Behavior/BattleBusSlowDeathBehavior.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/Include/GameLogic/SidesList.h b/Core/GameEngine/Include/GameLogic/SidesList.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameLogic/SidesList.h rename to Core/GameEngine/Include/GameLogic/SidesList.h diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/TerrainLogic.h b/Core/GameEngine/Include/GameLogic/TerrainLogic.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameLogic/TerrainLogic.h rename to Core/GameEngine/Include/GameLogic/TerrainLogic.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/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp b/Core/GameEngine/Source/GameLogic/Map/SidesList.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp rename to Core/GameEngine/Source/GameLogic/Map/SidesList.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp b/Core/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp rename to Core/GameEngine/Source/GameLogic/Map/TerrainLogic.cpp diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt index 5ba4b5f62a5..d8133efeb61 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,16 +437,16 @@ 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 Include/GameLogic/ScriptConditions.h Include/GameLogic/ScriptEngine.h Include/GameLogic/Scripts.h - Include/GameLogic/SidesList.h +# Include/GameLogic/SidesList.h Include/GameLogic/Squad.h - Include/GameLogic/TerrainLogic.h +# Include/GameLogic/TerrainLogic.h Include/GameLogic/TurretAI.h Include/GameLogic/VictoryConditions.h Include/GameLogic/Weapon.h @@ -787,9 +787,9 @@ 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/SidesList.cpp - Source/GameLogic/Map/TerrainLogic.cpp +# Source/GameLogic/Map/PolygonTrigger.cpp +# Source/GameLogic/Map/SidesList.cpp +# Source/GameLogic/Map/TerrainLogic.cpp Source/GameLogic/Object/Armor.cpp Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp Source/GameLogic/Object/Behavior/BehaviorModule.cpp diff --git a/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h b/Generals/Code/GameEngine/Include/Common/MapReaderWriterInfo.h deleted file mode 100644 index a9d0e93889e..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. Added in Zero Hour. -#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. Added in Zero Hour. -#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) override = 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/Include/GameLogic/SidesList.h b/Generals/Code/GameEngine/Include/GameLogic/SidesList.h deleted file mode 100644 index 5ba8d205448..00000000000 --- a/Generals/Code/GameEngine/Include/GameLogic/SidesList.h +++ /dev/null @@ -1,389 +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. // -// // -//////////////////////////////////////////////////////////////////////////////// - - -// SidesList.h -// Class to encapsulate Sides and Build Lists for maps. -// Author: John Ahlquist, November 2001 - -#pragma once - -#include "Common/Dict.h" -#include "Common/Errors.h" -#include "Common/GameType.h" -#include "Common/Snapshot.h" -#include "Common/GameMemory.h" -#include "Common/STLTypedefs.h" - -class DataChunkInput; -struct DataChunkInfo; -class DataChunkOutput; -class BuildListInfo; -class RenderObjClass; -class ScriptList; -class Shadow; - -// ---------------------------------------------------------------------------------------------- -/** - This is a class that describes a Side, including build list. - Note that a side corresponds to a Player in the game. The lightweight - Side is used to give the WB Editor somewhere to hang build lists. -*/ -class SidesInfo -{ -protected: - BuildListInfo* m_pBuildList; ///< linked list. - Dict m_dict; ///< general player dict. - ScriptList *m_scripts; ///< linked list. - -public: - SidesInfo(); - SidesInfo(const SidesInfo& thatref); - ~SidesInfo(); - void init(const Dict* d); - void clear() { init(nullptr); } - Dict* getDict() { return &m_dict; } - void addToBuildList(BuildListInfo *pBuildList, Int position); - Int removeFromBuildList(BuildListInfo *pBuildList); - void reorderInBuildList(BuildListInfo *pBuildList, Int newPosition); - BuildListInfo* getBuildList() {return m_pBuildList;} ///< Gets the build list. - void releaseBuildList() {m_pBuildList=nullptr;} ///< Used when the build list is passed to class Player. - ScriptList *getScriptList() {return(m_scripts);}; - void setScriptList(ScriptList *pScriptList) {m_scripts = pScriptList;}; - - // ug, I hate having to overload stuff, but this makes it a lot easier to make copies safely - SidesInfo& operator=(const SidesInfo& that); -}; - -// ---------------------------------------------------------------------------------------------- -class TeamsInfo -{ -private: - Dict m_dict; -public: - Dict* getDict() { return &m_dict; } - void init(const Dict* d) { m_dict.clear(); if (d) m_dict = *d; } - void clear() { init(nullptr); } -}; - - -// ---------------------------------------------------------------------------------------------- -// a wrapper class to make this a little cleaner. -class TeamsInfoRec -{ -private: - Int m_numTeams; - Int m_numTeamsAllocated; - TeamsInfo* m_teams; - -public: - TeamsInfoRec(); - TeamsInfoRec(const TeamsInfoRec& thatref); - ~TeamsInfoRec(); - TeamsInfoRec& operator=(const TeamsInfoRec& thatref); - void clear(); - TeamsInfo *findTeamInfo(AsciiString name, Int* index); - void addTeam(const Dict* d); - void removeTeam(Int i); - Int getNumTeams() const { return m_numTeams; } - TeamsInfo * getTeamInfo(Int team) - { - if (team>=0&&team=0&&side=0&&side=0 && ndx < MAX_RESOURCE_GATHERERS) return m_resourceGatherers[ndx]; return INVALID_ID;} - void setGathererID(Int ndx, ObjectID id) {if (ndx>=0 && ndx < MAX_RESOURCE_GATHERERS) m_resourceGatherers[ndx] = id;} - Int getDesiredGatherers() {return m_desiredGatherers;}; - void setDesiredGatherers(Int desired) {m_desiredGatherers = desired;} - Int getCurrentGatherers() {return m_currentGatherers;}; - void setCurrentGatherers(Int cur) {m_currentGatherers = cur;} - - BuildListInfo *duplicate(); -}; - -inline void BuildListInfo::decrementNumRebuilds() -{ - if (m_numRebuilds > 0 && m_numRebuilds != UNLIMITED_REBUILDS) - m_numRebuilds--; -} - -inline void BuildListInfo::incrementNumRebuilds() -{ - if (m_numRebuilds != UNLIMITED_REBUILDS) - m_numRebuilds++; -} - -inline Bool BuildListInfo::isBuildable() -{ - if (getNumRebuilds() > 0 || getNumRebuilds() == BuildListInfo::UNLIMITED_REBUILDS) - return true; - - return false; -} diff --git a/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h b/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h deleted file mode 100644 index c9e0ddb778b..00000000000 --- a/Generals/Code/GameEngine/Include/GameLogic/TerrainLogic.h +++ /dev/null @@ -1,379 +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. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: TerrainLogic.h /////////////////////////////////////////////////////////////////////////// -// Logical terrain representation for the game logic side -// Author: Colin Day, April 2001 -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "Common/GameMemory.h" -#include "Common/Snapshot.h" -#include "Common/STLTypedefs.h" -#include "GameClient/TerrainRoads.h" - -typedef std::vector VecICoord2D; - -class DataChunkInput; -struct DataChunkInfo; -class MapObject; -class Object; -class Dict; -class PolygonTrigger; -class ThingTemplate; -class Vector3; -class Drawable; -class Matrix3D; -class WaterHandle; -class Xfer; - -enum WaypointID CPP_11(: Int) -{ - INVALID_WAYPOINT_ID = 0x7FFFFFFF -}; - -//------------------------------------------------------------------------------------------------- -// Waypoint -/** Helper class for waypoint info in terrain logic. -*/ -class Waypoint : public MemoryPoolObject -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Waypoint, "Waypoint") - -// friends do not play well with MPO (srj) -//friend class TerrainLogic; -public: - Waypoint(WaypointID id, AsciiString name, const Coord3D *pLoc, AsciiString label1, - AsciiString label2, AsciiString label3, Bool biDirectional); - //~Waypoint(); - enum {MAX_LINKS=8}; - -protected: - WaypointID m_id; ///< Unique integer identifier. - AsciiString m_name; ///< Name. - Coord3D m_location; ///< Location. - Waypoint* m_pNext; ///< Linked list of all waypoints. - Waypoint* m_links[MAX_LINKS]; ///< Directed graph of waypoints. - Int m_numLinks; ///< Number of links in m_links. - AsciiString m_pathLabel1; - AsciiString m_pathLabel2; - AsciiString m_pathLabel3; - Bool m_biDirectional; - -public: - // should be protected, but friendly access needed (srj) - void setNext(Waypoint *pNext) {m_pNext = pNext; } - //void setLink(Int ndx, Waypoint *pLink) - //{ - // if (ndx>=0 && ndx <=MAX_LINKS) m_links[ndx] = pLink; - //} - void addLink(Waypoint* pLink) - { - if (m_numLinks < MAX_LINKS) - { - m_links[m_numLinks] = pLink; - ++m_numLinks; - } - } - -public: - /// Enumerate all waypoints using getNext. - Waypoint *getNext() const {return m_pNext; } - /// Enumerate the directed links from a waypoint using this,a nd getLink. - Int getNumLinks() const {return m_numLinks; } - /// Get the n'th directed link. (May be nullptr). - Waypoint *getLink(Int ndx) const {if (ndx>=0 && ndx <= MAX_LINKS) return m_links[ndx]; return nullptr; } - /// Get the waypoint's name. - AsciiString getName() const {return m_name; } - /// Get the integer id. - WaypointID getID() const {return m_id; } - /// Get the waypoint's position - const Coord3D *getLocation() const { return &m_location; } - /// Get the waypoint's first path label - const AsciiString& getPathLabel1() const { return m_pathLabel1; } - /// Get the waypoint's second path label - const AsciiString& getPathLabel2() const { return m_pathLabel2; } - /// Get the waypoint's third path label - const AsciiString& getPathLabel3() const { return m_pathLabel3; } - /// Get bi-directionality. - Bool getBiDirectional() const { return m_biDirectional; } - - void setLocationZ(Real z) { m_location.z = z; } -}; - -//------------------------------------------------------------------------------------------------- -// Bridge -/** Helper class for bridge info in terrain logic. -*/ -class BridgeInfo -{ -public: - BridgeInfo(); - -public: - Coord3D from, to; /// The points that the bridge was drawn using. - Real bridgeWidth; /// Width of the bridge. - Coord3D fromLeft, fromRight, toLeft, toRight; /// The 4 corners of the rectangle that the bridge covers. - Int bridgeIndex; ///< The index to the drawable bridges. - BodyDamageType curDamageState; - ObjectID bridgeObjectID; - ObjectID towerObjectID[ BRIDGE_MAX_TOWERS ]; - Bool damageStateChanged; - -}; - -//------------------------------------------------------------------------------------------------- -// Bridge -/** Helper class for bridge info in terrain logic. -*/ -struct TBridgeAttackInfo -{ -public: - Coord3D attackPoint1, attackPoint2; /// The points that can be attacked.. -}; - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -class Bridge : public MemoryPoolObject -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Bridge, "Bridge") -// friends do not play well with MPO (srj) -//friend class TerrainLogic; -public: - -public: // ctor/dtor. - Bridge(BridgeInfo &theInfo, Dict *props, AsciiString bridgeTemplateName); - Bridge(Object *bridgeObj); - //~Bridge(); - -protected: - Bridge* m_next; ///< Link for traversing all bridges in the current map. - AsciiString m_templateName; ///< bridge template name - BridgeInfo m_bridgeInfo; - Region2D m_bounds; /// 2d bounds for quick screening. - PathfindLayerEnum m_layer; ///< Pathfind layer for this bridge. - -public: - // should be protected, but friendly access needed (srj) - void setNext(Bridge *pNext) {m_next = pNext; } - Object *createTower( Coord3D *worldPos, BridgeTowerType towerPos, - const ThingTemplate *towerTemplate, Object *bridge ); - -public: - /// return the bridge template name - AsciiString getBridgeTemplateName() { return m_templateName; } - /// Enumerate all bridges using getNext; - Bridge *getNext() {return m_next; } - /// Get the height for an object on bridge. Note - assumes object is on bridge. Use isPointOnBridge to check. - Real getBridgeHeight(const Coord3D *pLoc, Coord3D* normal); - /// Get the bridges logical info. - void getBridgeInfo(class BridgeInfo *pInfo) {*pInfo = m_bridgeInfo; } - /// See if the point is on the bridge. - Bool isPointOnBridge(const Coord3D *pLoc); - Drawable *pickBridge(const Vector3 &from, const Vector3 &to, Vector3 *pos); - void updateDamageState(); ///< Updates a bridge's damage info. - const BridgeInfo *peekBridgeInfo() const {return &m_bridgeInfo;} - PathfindLayerEnum getLayer() const {return m_layer;} - void setLayer(PathfindLayerEnum layer) {m_layer = layer;} - const Region2D *getBounds() const {return &m_bounds;} - Bool isCellOnEnd(const Region2D *cell); // Is pathfind cell on the sides of the bridge - Bool isCellOnSide(const Region2D *cell); // Is pathfind cell on the end of the bridge - Bool isCellEntryPoint(const Region2D *cell); // Is pathfind cell an entry point to the bridge - - void setBridgeObjectID( ObjectID id ) { m_bridgeInfo.bridgeObjectID = id; } - void setTowerObjectID( ObjectID id, BridgeTowerType which ) { m_bridgeInfo.towerObjectID[ which ] = id; } - -}; - -//------------------------------------------------------------------------------------------------- -/** Device independent implementation for some functionality of the - * logical terrain singleton */ -//------------------------------------------------------------------------------------------------- -class TerrainLogic : public Snapshot, - public SubsystemInterface -{ - -public: - - TerrainLogic(); - virtual ~TerrainLogic() override; - - virtual void init() override; ///< Init - virtual void reset() override; ///< Reset - virtual void update() override; ///< Update - - virtual Bool loadMap( AsciiString filename, Bool query ); - virtual void newMap( Bool saveGame ); ///< Initialize the logic for new map. - - virtual Real getGroundHeight( Real x, Real y, Coord3D* normal = nullptr ) const; - virtual Real getLayerHeight(Real x, Real y, PathfindLayerEnum layer, Coord3D* normal = nullptr, Bool clip = true) const; - virtual void getExtent( Region3D *extent ) const { DEBUG_CRASH(("not implemented")); } ///< @todo This should not be a stub - this should own this functionality - virtual void getExtentIncludingBorder( Region3D *extent ) const { DEBUG_CRASH(("not implemented")); } ///< @todo This should not be a stub - this should own this functionality - virtual void getMaximumPathfindExtent( Region3D *extent ) const { DEBUG_CRASH(("not implemented")); } ///< @todo This should not be a stub - this should own this functionality - virtual Coord3D findClosestEdgePoint( const Coord3D *closestTo ) const ; - virtual Coord3D findFarthestEdgePoint( const Coord3D *farthestFrom ) const ; - virtual Bool isClearLineOfSight(const Coord3D& pos, const Coord3D& posOther) const; - - virtual AsciiString getSourceFilename() { return m_filenameString; } - - virtual PathfindLayerEnum alignOnTerrain( Real angle, const Coord3D& pos, Bool stickToGround, Matrix3D& mtx); - - virtual Bool isUnderwater( Real x, Real y, Real *waterZ = nullptr, Real *terrainZ = nullptr ); ///< is point under water - virtual Bool isCliffCell( Real x, Real y) const; ///< is point cliff cell - virtual const WaterHandle* getWaterHandle( Real x, Real y ); ///< get water handle at this location - virtual const WaterHandle* getWaterHandleByName( AsciiString name ); ///< get water handle by name - virtual Real getWaterHeight( const WaterHandle *water ); ///< get height of water table - virtual void setWaterHeight( const WaterHandle *water, - Real height, - Real damageAmount, - Bool forcePathfindUpdate ); ///< set height of water table - virtual void changeWaterHeightOverTime( const WaterHandle *water, - Real finalHeight, - Real transitionTimeInSeconds, - Real damageAmount );///< change water height over time - - virtual Waypoint *getFirstWaypoint() { return m_waypointListHead; } - - /// Return the waypoint with the given name - virtual Waypoint *getWaypointByName( AsciiString name ); - - /// Return the waypoint with the given ID - virtual Waypoint *getWaypointByID( UnsignedInt id ); - - /// Return the closest waypoint on the labeled path - virtual Waypoint *getClosestWaypointOnPath( const Coord3D *pos, AsciiString label ); - - /// Return true if the waypoint path containing pWay is labeled with the label. - virtual Bool isPurposeOfPath( Waypoint *pWay, AsciiString label ); - - /// Return the trigger area with the given name - virtual PolygonTrigger *getTriggerAreaByName( AsciiString name ); - - ///Gets the first bridge. Traverse all bridges using bridge->getNext(); - virtual Bridge *getFirstBridge() const { return m_bridgeListHead; } - - /// Find the bridge at a location. null means no bridge. - virtual Bridge *findBridgeAt(const Coord3D *pLoc) const; - - /// Find the bridge at a location. null means no bridge. Note that the layer value will be used to resolve crossing bridges. - virtual Bridge *findBridgeLayerAt(const Coord3D *pLoc, PathfindLayerEnum layer, Bool clip = true) const; - - /// Returns true if the object is close enough to interact with the bridge for pathfinding. - virtual Bool objectInteractsWithBridgeLayer(Object *obj, Int layer, Bool considerBridgeHealth = true) const; - - /// Returns true if the object is close to one or the other end of the bridge. - virtual Bool objectInteractsWithBridgeEnd(Object *obj, Int layer) const; - - virtual Drawable *pickBridge(const Vector3 &from, const Vector3 &to, Vector3 *pos); - - virtual void addBridgeToLogic(BridgeInfo *pInfo, Dict *props, AsciiString bridgeTemplateName); ///< Adds a bridge's logical info. - virtual void addLandmarkBridgeToLogic(Object *bridgeObj); ///< Adds a bridge's logical info. - virtual void deleteBridge( Bridge *bridge ); ///< remove a bridge - - virtual void updateBridgeDamageStates(); ///< Updates bridge's damage info. - - Bool anyBridgesDamageStatesChanged() {return m_bridgeDamageStatesChanged; } ///< Bridge damage states updated. - Bool isBridgeRepaired(const Object *bridge); ///< Is bridge repaired? - Bool isBridgeBroken(const Object *bridge); ///< Is bridge Broken? - void getBridgeAttackPoints(const Object *bridge, TBridgeAttackInfo *info); ///< Get bridge attack points. - - PathfindLayerEnum getLayerForDestination(const Coord3D *pos); - - // this is just like getLayerForDestination, but always return the highest layer that will be <= z at that point - // (unlike getLayerForDestination, which will return the closest layer) - PathfindLayerEnum getHighestLayerForDestination(const Coord3D *pos, Bool onlyHealthyBridges = false); - - void enableWaterGrid( Bool enable ); ///< enable/disable the water grid - - // This is stuff to get the currently active boundary information - Int getActiveBoundary() { return m_activeBoundary; } - void setActiveBoundary(Int newActiveBoundary); - - void flattenTerrain(Object *obj); ///< Flatten the terrain under a building. - void createCraterInTerrain(Object *obj); ///< Flatten the terrain under a building. - -protected: - - // snapshot methods - virtual void crc( Xfer *xfer ) override; - virtual void xfer( Xfer *xfer ) override; - virtual void loadPostProcess() override; - - /// Chunk parser callback. - static Bool parseWaypointDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData); - /// Chunk parser callback. - Bool parseWaypointData(DataChunkInput &file, DataChunkInfo *info, void *userData); - /// Add a waypoint to the list. - void addWaypoint(MapObject *pMapObj); - /// Add a directed link between waypoints. - void addWaypointLink(Int id1, Int id2); - /// Deletes all waypoints. - void deleteWaypoints(); - /// Deletes all bridges. - void deleteBridges(); - - /// find the axis aligned region bounding the water table - void findAxisAlignedBoundingRect( const WaterHandle *waterHandle, Region3D *region ); - - UnsignedByte *m_mapData; ///< array of height samples - Int m_mapDX; ///< width of map samples - Int m_mapDY; ///< height of map samples - - VecICoord2D m_boundaries; - Int m_activeBoundary; - - Waypoint *m_waypointListHead; - Bridge *m_bridgeListHead; - - Bool m_bridgeDamageStatesChanged; - - AsciiString m_filenameString; ///< filename for terrain data - - Bool m_waterGridEnabled; ///< TRUE when water grid is enabled - - static WaterHandle m_gridWaterHandle; ///< water handle for the grid water (we only presently have one) - - // - // we will force a limit of MAX_DYNAMIC_WATER as the max dynamically changeable water - // tables for a map. We could use a list, but eh, this is fine and small anyway - // - enum { MAX_DYNAMIC_WATER = 64 }; - struct DynamicWaterEntry - { - const WaterHandle *waterTable; ///< handle to water table to edit - Real changePerFrame; ///< how much height to add to the water each frame (negative=lowering) - Real targetHeight; ///< the target height we want to be at - Real damageAmount; ///< amount of damage to do to objects that are underwater - Real currentHeight; ///< we need to keep track of this ourselves cause some water height are represented with ints - } m_waterToUpdate[ MAX_DYNAMIC_WATER ]; ///< water tables to dynamicall update - Int m_numWaterToUpdate; ///< how many valid entries are in m_waterToUpdate - -}; - -// EXTERNALS ////////////////////////////////////////////////////////////////////////////////////// -extern TerrainLogic *TheTerrainLogic; ///< singleton definition - -extern void makeAlignToNormalMatrix( Real angle, const Coord3D& pos, const Coord3D& normal, Matrix3D& mtx); -extern Bool LineInRegion( const Coord2D *p1, const Coord2D *p2, const Region2D *clipRegion ); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp b/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp deleted file mode 100644 index 63286156a63..00000000000 --- a/Generals/Code/GameEngine/Source/GameLogic/Map/SidesList.cpp +++ /dev/null @@ -1,1166 +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. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: SidesList.cpp ///////////////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: SidesList.cpp -// -// Created: John Ahlquist, Nov 2001 -// -// Desc: Contains the information describing Sides (player, ai, neutral etc.) -// in a scenario, including build lists for non-player sides. -// -//----------------------------------------------------------------------------- - -#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine - -#include "Common/DataChunk.h" -#include "Common/GameState.h" -#include "Common/PlayerTemplate.h" -#include "Common/WellKnownKeys.h" -#include "Common/Xfer.h" -#include "GameLogic/AI.h" -#include "GameLogic/Scripts.h" -#include "GameLogic/SidesList.h" - -static const Int K_SIDES_DATA_VERSION_1 = 1; -static const Int K_SIDES_DATA_VERSION_2 = 2; // includes Team list. -static const Int K_SIDES_DATA_VERSION_3 = 3; // includes Team list. - -/* ********* SidesInfo class ****************************/ -/** - SidesInfo - Constructor. -*/ -SidesInfo::SidesInfo() : - m_pBuildList(nullptr), - m_scripts(nullptr) -{ -} - -SidesInfo::SidesInfo(const SidesInfo& thatref) : - m_pBuildList(nullptr), - m_scripts(nullptr) -{ - *this = thatref; -} - -/** - SidesInfo - Destructor - -*/ -SidesInfo::~SidesInfo() -{ - clear(); -} - -void SidesInfo::init(const Dict* d) -{ - deleteInstance(m_pBuildList); - m_pBuildList = nullptr; - - m_dict.clear(); - - deleteInstance(m_scripts); - m_scripts = nullptr; - - if (d) - m_dict = *d; -} - -// ug, I hate having to overload stuff, but this makes it a lot easier to make copies safely -SidesInfo& SidesInfo::operator=(const SidesInfo& that) -{ - if (this != &that) - { - this->clear(); - this->m_dict = that.m_dict; - - BuildListInfo* thisBLTail = nullptr; - for (BuildListInfo* thatBL = that.m_pBuildList; thatBL; thatBL = thatBL->getNext()) - { - BuildListInfo* thisBL = newInstance( BuildListInfo ); - *thisBL = *thatBL; - thisBL->setNextBuildList(nullptr); - - if (thisBLTail) - thisBLTail->setNextBuildList(thisBL); - else - this->m_pBuildList = thisBL; - - thisBLTail = thisBL; - } - - if (that.m_scripts) - this->m_scripts = that.m_scripts->duplicate(); - else - this->m_scripts = nullptr; - } - return *this; -} - -/** -* SidesInfo::addToBuildList - Adds a build list entry as the nth entry. -* -*/ -void SidesInfo::addToBuildList(BuildListInfo *pBuildList, Int position) -{ - DEBUG_ASSERTLOG(pBuildList->getNext()==nullptr, ("WARNING***Adding already linked element.")); - BuildListInfo *pCur = nullptr; - while (position) { - position--; - if (pCur==nullptr) { - pCur = m_pBuildList; - } else { - if (pCur->getNext()) { - pCur = pCur->getNext(); - } else { - break; // at end of list. - } - } - } - if (pCur==nullptr) { - // add to front of list. - pBuildList->setNextBuildList(m_pBuildList); - m_pBuildList = pBuildList; - } else { - pBuildList->setNextBuildList(pCur->getNext()); - pCur->setNextBuildList(pBuildList); - } -} - -/** -* SidesInfo::reorderInBuildList - Reorders a build list entry as the nth entry. -* -*/ -void SidesInfo::reorderInBuildList(BuildListInfo *pBuildList, Int newPosition) -{ - /*Int oldPos =*/ removeFromBuildList(pBuildList); - addToBuildList(pBuildList, newPosition); -} - -/** -* SidesInfo::removeFromBuildList - Removes a build list entry. -* Returns the position in the list that the item occupied. -* -*/ -Int SidesInfo::removeFromBuildList(BuildListInfo *pBuildList) -{ - DEBUG_ASSERTCRASH(pBuildList, ("Removing null list.")); - if (pBuildList==nullptr) return 0; - - Int position = 0; - - if (pBuildList == m_pBuildList) { - // First item in list, so update head. - m_pBuildList = pBuildList->getNext(); - } else { - position = 1; - // Not the first item, so find the preceding list element. - BuildListInfo *pPrev = m_pBuildList; - while (pPrev && (pPrev->getNext()!=pBuildList) ) { - pPrev = pPrev->getNext(); - position++; - } - DEBUG_ASSERTCRASH(pPrev, ("Removing item not in list.")); - if (pPrev) { - pPrev->setNextBuildList(pBuildList->getNext()); - } - } - pBuildList->setNextBuildList(nullptr); - return position; -} - -/* ********* SidesList class ****************************/ -/*extern*/ SidesList *TheSidesList = nullptr; ///< singleton instance of SidesList -/** - SidesList - Constructor. -*/ -SidesList::SidesList() : m_numSides(0), m_numSkirmishSides(0) -{ -} - -/** - SidesList - Destructor - -*/ -SidesList::~SidesList() -{ -} - -/** - SidesList - reset - -*/ -void SidesList::reset() -{ - clear(); -} - -/** - SidesList - clear - -*/ -void SidesList::clear() -{ - emptySides(); - emptyTeams(); -} - - - -/** -* SidesList::ParseSidesDataChunk - read a Sides chunk. -* Format is the newer CHUNKY format. -* See SidesList::WriteSidesDataChunk for the writer. -* Input: DataChunkInput -* -*/ -Bool SidesList::ParseSidesDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - DEBUG_ASSERTCRASH(TheSidesList, ("TheSidesList is null")); - - if (TheSidesList==nullptr) - return false; - - TheSidesList->clear(); - Int count = file.readInt(); - Int i, j; - TheSidesList->emptySides(); - for (i=0; i= MAX_PLAYER_COUNT) break; - Dict d = file.readDict(); - TheSidesList->addSide(&d); - BuildListInfo* pBuildList; - Int count = file.readInt(); - for (j=0; jsetBuildingName(file.readAsciiString()); - pBuildList->setTemplateName(file.readAsciiString()); - Coord3D loc; - loc.x = file.readReal(); - loc.y = file.readReal(); - loc.z = file.readReal(); - loc.z = 0; // force to ground level - pBuildList->setLocation(loc); - pBuildList->setAngle(file.readReal()); - pBuildList->setInitiallyBuilt(file.readByte()); - pBuildList->setNumRebuilds(file.readInt()); - if (info->version >= K_SIDES_DATA_VERSION_3) - { - pBuildList->setScript(file.readAsciiString()); - pBuildList->setHealth(file.readInt()); - pBuildList->setWhiner(file.readByte()); - pBuildList->setUnsellable(file.readByte()); - pBuildList->setRepairable(file.readByte()); - } - TheSidesList->getSideInfo(i)->addToBuildList(pBuildList, j); - } - } - if (info->version >= K_SIDES_DATA_VERSION_2) - { - count = file.readInt(); - TheSidesList->emptyTeams(); - for (i=0; iaddTeam(&d); - } - } - - file.registerParser( "PlayerScriptsList", info->label, ScriptList::ParseScriptsDataChunk ); - if (!file.parse(nullptr)) { - throw(ERROR_CORRUPT_FILE_FORMAT); - } - ScriptList *scripts[MAX_PLAYER_COUNT]; - count = ScriptList::getReadScripts(scripts); - for (i=0; igetNumSides()) { - deleteInstance(TheSidesList->getSideInfo(i)->getScriptList()); - TheSidesList->getSideInfo(i)->setScriptList(scripts[i]); - scripts[i] = nullptr; - } else { - // Read in more players worth than we have. - deleteInstance(scripts[i]); - scripts[i] = nullptr; - } - } - TheSidesList->validateSides(); - - DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Incorrect data file length.")); - return true; -} - - -/** -* SidesList::WriteSidesDataChunk - Writes a Sides chunk. -* Format is the newer CHUNKY format. -* See SidesList::ParseSidesDataChunk for the reader. -* Input: DataChunkInput -* -*/ -void SidesList::WriteSidesDataChunk(DataChunkOutput &chunkWriter) -{ - DEBUG_ASSERTCRASH(TheSidesList, ("TheSidesList is null")); - if (TheSidesList==nullptr) - return; - /**********HEIGHT MAP DATA ***********************/ - chunkWriter.openDataChunk("SidesList", K_SIDES_DATA_VERSION_3); - - chunkWriter.writeInt(TheSidesList->getNumSides()); - Int i; - for (i=0; igetNumSides(); i++) { - chunkWriter.writeDict(*TheSidesList->getSideInfo(i)->getDict()); - BuildListInfo* pBuildList = TheSidesList->getSideInfo(i)->getBuildList(); - Int count = 0; - while (pBuildList) { - count++; - pBuildList = pBuildList->getNext(); - } - chunkWriter.writeInt(count); - pBuildList = TheSidesList->getSideInfo(i)->getBuildList(); - while (pBuildList) { - chunkWriter.writeAsciiString(pBuildList->getBuildingName()); - chunkWriter.writeAsciiString(pBuildList->getTemplateName()); - chunkWriter.writeReal(pBuildList->getLocation()->x); - chunkWriter.writeReal(pBuildList->getLocation()->y); - chunkWriter.writeReal(pBuildList->getLocation()->z); - chunkWriter.writeReal(pBuildList->getAngle()); - chunkWriter.writeByte(pBuildList->isInitiallyBuilt()); - chunkWriter.writeInt(pBuildList->getNumRebuilds()); - // BEGIN stuff new to K_SIDES_DATA_VERSION_3 - chunkWriter.writeAsciiString(pBuildList->getScript()); - chunkWriter.writeInt(pBuildList->getHealth()); - chunkWriter.writeByte(pBuildList->getWhiner()); - chunkWriter.writeByte(pBuildList->getUnsellable()); - chunkWriter.writeByte(pBuildList->getRepairable()); - // END stuff new to K_SIDES_DATA_VERSION_3 - - pBuildList = pBuildList->getNext(); - } - } - - // BEGIN stuff new to K_SIDES_DATA_VERSION_2 - chunkWriter.writeInt(TheSidesList->getNumTeams()); - for (i=0; igetNumTeams(); i++) { - chunkWriter.writeDict(*TheSidesList->getTeamInfo(i)->getDict()); - } - // END stuff new to K_SIDES_DATA_VERSION_2 - - ScriptList *scripts[MAX_PLAYER_COUNT]; - for (i=0; igetNumSides(); i++) { - scripts[i] = TheSidesList->getSideInfo(i)->getScriptList(); - } - ScriptList::WriteScriptsDataChunk(chunkWriter, scripts, TheSidesList->getNumSides()); - chunkWriter.closeDataChunk(); - - Bool modified = TheSidesList->validateSides(); - DEBUG_ASSERTLOG(!modified, ("*** had to clean up sideslist on read")); - modified = false; // silence compiler warnings in release build - -} - -TeamsInfo *SidesList::findTeamInfo(AsciiString name, Int* index /*= nullptr*/) -{ - return m_teamrec.findTeamInfo(name, index); -} - -SidesInfo *SidesList::findSideInfo(AsciiString name, Int* index /*= nullptr*/) -{ - for (int i = 0; i < m_numSides; i++) - { - if (m_sides[i].getDict()->getAsciiString(TheKey_playerName) == name) - { - if (index) - *index = i; - return &m_sides[i]; - } - } - return nullptr; -} - -SidesInfo *SidesList::findSkirmishSideInfo(AsciiString name, Int* index /*= nullptr*/) -{ - for (int i = 0; i < m_numSkirmishSides; i++) - { - if (m_skirmishSides[i].getDict()->getAsciiString(TheKey_playerName) == name) - { - if (index) - *index = i; - return &m_skirmishSides[i]; - } - } - return nullptr; -} - -static AsciiString static_readPlayerNames[MAX_PLAYER_COUNT]; - -/** -* ParsePlayersDataChunk - read players names data chunk. -* Format is the newer CHUNKY format. -* Input: DataChunkInput -* -*/ -#define K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_1 1 -#define K_PLAYERS_NAMES_FOR_SCRIPTS_VERSION_2 2 - -static Bool ParsePlayersDataChunk(DataChunkInput &file, DataChunkInfo *info, void *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; - static_readPlayerNames[i] = file.readAsciiString(); - if (readDicts) { - Dict sideDict = file.readDict(); - } - } - DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Unexpected data left over.")); - return true; -} - -/** -* ParseTeamsDataChunk - read teams data chunk. -* Format is the newer CHUNKY format. -* Input: DataChunkInput -* -*/ -static Bool ParseTeamsDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - SidesList *sides = (SidesList *)userData; - while (!file.atEndOfChunk()) { - Dict teamDict = file.readDict(); - AsciiString teamName = teamDict.getAsciiString(TheKey_teamName); - AsciiString player = teamDict.getAsciiString(TheKey_teamOwner); - if (sides->findSkirmishSideInfo(player)) { - // player exists, so just add it. - sides->addSkirmishTeam(&teamDict); - //DEBUG_LOG(("Adding team %s", teamName.str())); - } else { - //DEBUG_LOG(("Couldn't add team %s, no player %s", teamName.str(), player.str())); - } - } - DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Unexpected data left over.")); - return true; -} - -void SidesList::prepareForMP_or_Skirmish() -{ - m_skirmishTeamrec.clear(); - Int i; - for (i = 0; i < getNumTeams(); i++) - { - Dict *tdict = getTeamInfo(i)->getDict(); - m_skirmishTeamrec.addTeam(tdict); - } - m_teamrec.clear(); - - for (i = 0; i < MAX_PLAYER_COUNT; i++) { - m_skirmishSides[i].clear(); - } - m_numSkirmishSides = 0; - - for (i = 0; i < m_numSides; i++) - { - m_skirmishSides[m_numSkirmishSides] = m_sides[i]; - m_numSkirmishSides++; - if (m_sides[i].getDict()->getAsciiString(TheKey_playerFaction) == "FactionCivilian") { - // Don't remove FactionCivilian. - continue; - } - if (m_numSides == 1) break; // can't remove the last side. - removeSide(i); - i--; - } - Bool gotScripts = false; - for (i=0; igetAsciiString(TheKey_playerFaction) == "FactionCivilian") { - // Don't consider FactionCivilian. - continue; - } - if (m_skirmishSides[i].getScriptList()==nullptr) continue; - if (m_skirmishSides[i].getScriptList()->getScript() != nullptr || - m_skirmishSides[i].getScriptList()->getScriptGroup()!=nullptr) { - gotScripts = true; - } - } - if (!gotScripts) { - AsciiString path = "data\\Scripts\\SkirmishScripts.scb"; - DEBUG_LOG(("Skirmish map using standard scripts")); - m_skirmishTeamrec.clear(); - CachedFileInputStream theInputStream; - if (theInputStream.open(path)) { - ChunkInputStream *pStrm = &theInputStream; - DataChunkInput file( pStrm ); - file.registerParser( "PlayerScriptsList", AsciiString::TheEmptyString, ScriptList::ParseScriptsDataChunk ); - file.registerParser( "ScriptsPlayers", AsciiString::TheEmptyString, ParsePlayersDataChunk ); - file.registerParser( "ScriptTeams", AsciiString::TheEmptyString, ParseTeamsDataChunk ); - if (!file.parse(this)) { - DEBUG_LOG(("ERROR - Unable to read in skirmish scripts.")); - return; - } - ScriptList *scripts[MAX_PLAYER_COUNT]; - Int count = ScriptList::getReadScripts(scripts); - Int i; - for (i=0; igetDict()->getAsciiString(TheKey_playerName); - if (name == static_readPlayerNames[i]) { - curSide = j; - break; - } - } - if (curSide == -1) - { - deleteInstance(scripts[i]); - scripts[i] = nullptr; - continue; - } - - deleteInstance(getSkirmishSideInfo(curSide)->getScriptList()); - getSkirmishSideInfo(curSide)->setScriptList(scripts[i]); - scripts[i] = nullptr; - } - for (i=0; igetDict()->getAsciiString(TheKey_teamName); - if (tname.startsWith("team")) - { - const char* rest = tname.str() + 4; - for (int j = 0; j < m_numSides; j++) - { - AsciiString pname = m_sides[j].getDict()->getAsciiString(TheKey_playerName); - if (strcmp(pname.str(), rest) == 0) - { - return true; - } - } - } - return false; -} - -void SidesList::emptySides() -{ - Int i; - - m_numSides = 0; - m_numSkirmishSides = 0; - for (i = 0; i < MAX_PLAYER_COUNT; i++) { - m_sides[i].clear(); - m_skirmishSides[i].clear(); - } -} - -void SidesList::emptyTeams() -{ - m_teamrec.clear(); - m_skirmishTeamrec.clear(); -} - -void SidesList::addSide(const Dict* d) -{ - DEBUG_ASSERTCRASH(m_numSides < MAX_PLAYER_COUNT, ("too many players")); - if (m_numSides < MAX_PLAYER_COUNT) - m_sides[m_numSides++].init(d); -} - -void SidesList::addTeam(const Dict* d) -{ - m_teamrec.addTeam(d); -} - -void SidesList::addSkirmishTeam(const Dict* d) -{ - m_skirmishTeamrec.addTeam(d); -} - -void SidesList::removeSide(Int i) -{ - if (i < 0 || i >= m_numSides || m_numSides <= 1) - return; - - for ( ; i < m_numSides-1; i++) - m_sides[i] = m_sides[i+1]; - - for ( ; i < MAX_PLAYER_COUNT; i++) - m_sides[i].clear(); - - --m_numSides; -} - -void SidesList::removeTeam(Int i) -{ - m_teamrec.removeTeam(i); -} - -Bool SidesList::validateAllyEnemyList(const AsciiString& tname, AsciiString& allies) -{ - // owners/allies/enemies must be players. - - Bool modified = false; - - AsciiString str, newstr, token; - - str = allies; - newstr.clear(); - while (str.nextToken(&token)) - { - if (token == tname) - { - modified = true; - continue; // no allies/enemies with self - } - - SidesInfo *si = findSideInfo(token); - if (!si) - { - modified = true; - continue; // player not found. - } - - if (!newstr.isEmpty()) - newstr.concat(" "); - newstr.concat(token); - } - - allies = newstr; - return modified; -} - -void SidesList::addPlayerByTemplate(AsciiString playerTemplateName) -{ - AsciiString playerName; - UnicodeString playerDisplayName; - Bool isHuman = false; - - if (playerTemplateName.isEmpty()) - { - playerName.set(""); // magic code for "neutral" - playerDisplayName = L"Neutral"; - isHuman = false; - } - else - { - playerName.set("Plyr"); - if (playerTemplateName.startsWith("Faction")) - { - playerName.concat(playerTemplateName.str() + 7); - } - else - { - playerName.concat(playerTemplateName); - } - playerDisplayName.translate(playerName); - isHuman = true; - // special-case "civilian"... - if (playerName == "PlyrCivilian") - isHuman = false; - } - - Dict d; - - d.clear(); - d.setAsciiString(TheKey_playerName, playerName); - d.setBool(TheKey_playerIsHuman, isHuman); - d.setUnicodeString(TheKey_playerDisplayName, playerDisplayName); - d.setAsciiString(TheKey_playerFaction, playerTemplateName); - d.setAsciiString(TheKey_playerAllies, AsciiString::TheEmptyString); - d.setAsciiString(TheKey_playerEnemies, AsciiString::TheEmptyString); - - addSide(&d); - - AsciiString playerTeamName; - playerTeamName.set("team"); - playerTeamName.concat(playerName); - - d.clear(); - d.setAsciiString(TheKey_teamName, playerTeamName); - d.setAsciiString(TheKey_teamOwner, playerName); - d.setBool(TheKey_teamIsSingleton, true); - addTeam(&d); -} - -Bool SidesList::validateSides() -{ - Bool modified = false; - - // ensure we have at least one player, and at least one neutral player. - Int i; - Int neutral = -1; - Int num = getNumSides(); - for (i = 0; i < num; i++) - { - if (getSideInfo(i)->getDict()->getAsciiString(TheKey_playerName).isEmpty()) - { - neutral = i; - break; - } - } - if (neutral == -1) - { - addPlayerByTemplate(AsciiString::TheEmptyString); - modified = true; - } - - // now ensure that every player has a proper "default team" - for (i = 0; i < getNumSides(); i++) - { - Dict *pdict = getSideInfo(i)->getDict(); - AsciiString pname = pdict->getAsciiString(TheKey_playerName); - AsciiString tname("team"); - tname.concat(pname); - TeamsInfo *ti = findTeamInfo(tname); - if (ti) - { - // make sure the team owner points back to the player. - if (ti->getDict()->getAsciiString(TheKey_teamOwner) != pname) - { - DEBUG_CRASH(("hmm, team owner mismatch (%s) (%s), this should not normally be possible",ti->getDict()->getAsciiString(TheKey_teamOwner).str(), pname.str())); - ti->getDict()->setAsciiString(TheKey_teamOwner, pname); - modified = true; - } - // default teams are always singletons. - if (!ti->getDict()->getBool(TheKey_teamIsSingleton)) - { - DEBUG_CRASH(("hmm, this should not normally be possible")); - ti->getDict()->setBool(TheKey_teamIsSingleton, true); - modified = true; - } - } - else - { - DEBUG_LOG(("*** default team for player %s missing (should not be possible), adding it...",tname.str())); - Dict d; - d.setAsciiString(TheKey_teamName, tname); - d.setAsciiString(TheKey_teamOwner, pname); - d.setBool(TheKey_teamIsSingleton, true); - addTeam(&d); - modified = true; - } - - AsciiString allies = pdict->getAsciiString(TheKey_playerAllies); - AsciiString enemies = pdict->getAsciiString(TheKey_playerEnemies); - - // ensure all teams have valid allies & enemies. - // (note that owners can be teams or players, but allies/enemies can only be teams.) - if (validateAllyEnemyList(pname, allies)) - { - DEBUG_LOG(("bad allies...")); - pdict->setAsciiString(TheKey_playerAllies, allies); - modified = true; - } - - if (validateAllyEnemyList(pname, enemies)) - { - DEBUG_LOG(("bad enemies...")); - pdict->setAsciiString(TheKey_playerEnemies, enemies); - modified = true; - } - } - - // ensure there's no overlap between team names and player names. - // (if there is, the player wins and the team is whacked.) -validate_team_names: - for (i = 0; i < getNumTeams(); i++) - { - Dict *tdict = getTeamInfo(i)->getDict(); - AsciiString tname = tdict->getAsciiString(TheKey_teamName); - if (findSideInfo(tname)) - { - DEBUG_CRASH(("name %s is duplicate between player and team, removing...",tname.str())); - removeTeam(i); - modified = true; - goto validate_team_names; - } - } - - for (i = 0; i < getNumTeams(); i++) - { - Dict *tdict = getTeamInfo(i)->getDict(); - AsciiString tname = tdict->getAsciiString(TheKey_teamName); - AsciiString towner = tdict->getAsciiString(TheKey_teamOwner); - SidesInfo* si = findSideInfo(towner); - if (si == nullptr || towner == tname) - { - DEBUG_LOG(("bad owner %s; reparenting to neutral...",towner.str())); - tdict->setAsciiString(TheKey_teamOwner, AsciiString::TheEmptyString); - modified = true; - } -// if (tdict->getType(NAMEKEY("teamAllies")) != Dict::DICT_NONE) -// tdict->remove(NAMEKEY("teamAllies")); -// if (tdict->getType(NAMEKEY("teamEnemies")) != Dict::DICT_NONE) -// tdict->remove(NAMEKEY("teamEnemies")); - - } - - return modified; -} - -// ------------------------------------------------------------------------------------------------ -/** CRC */ -// ------------------------------------------------------------------------------------------------ -void SidesList::crc( Xfer *xfer ) -{ - -} - -// ------------------------------------------------------------------------------------------------ -/** Xfer method - * Version Info: - * 1: Initial version */ -// ------------------------------------------------------------------------------------------------ -void SidesList::xfer( Xfer *xfer ) -{ - - // version - XferVersion currentVersion = 1; - XferVersion version = currentVersion; - xfer->xferVersion( &version, currentVersion ); - - // xfer num sides - Int sideCount = getNumSides(); - xfer->xferInt( &sideCount ); - if( sideCount != getNumSides() ) - { - - DEBUG_CRASH(( "SidesList::xfer - The sides list size has changed, this was not supposed to happen, you must version this method and figure out how to translate between old and new versions now" )); - throw SC_INVALID_DATA; - - } - - // side data - ScriptList *scriptList; - Bool scriptListPresent; - for( Int i = 0; i < sideCount; ++i ) - { - - // xfer script list data that can change - scriptList = getSideInfo( i )->getScriptList(); - scriptListPresent = scriptList ? TRUE : FALSE; - xfer->xferBool( &scriptListPresent ); - if( (scriptList == nullptr && scriptListPresent == TRUE) || - (scriptList != nullptr && scriptListPresent == FALSE) ) - { - - DEBUG_CRASH(( "SidesList::xfer - script list missing/present mismatch" )); - throw SC_INVALID_DATA; - - } - if( scriptListPresent ) - xfer->xferSnapshot( scriptList ); - - } - -} - -// ------------------------------------------------------------------------------------------------ -/** Load post process */ -// ------------------------------------------------------------------------------------------------ -void SidesList::loadPostProcess() -{ - -} - -/* ********* BuildListInfo class ****************************/ -/** - BuildListInfo - Constructor. -*/ -BuildListInfo::BuildListInfo() : -m_nextBuildList(nullptr), -m_renderObj(nullptr), -m_shadowObj(nullptr), -m_isInitiallyBuilt(false), -m_numRebuilds(0), -m_angle(0), -m_script(AsciiString::TheEmptyString), -m_health(100), -m_whiner(true), -m_unsellable(false), -m_repairable(true), -m_objectID(INVALID_ID), -m_objectTimestamp(0), -m_underConstruction(false), -m_isSupplyBuilding(false), -m_desiredGatherers(0), -m_currentGatherers(0), -m_automaticallyBuild(true), -m_priorityBuild(false), -m_buildingName(AsciiString::TheEmptyString) -{ - m_location.zero(); - m_rallyPointOffset.x = 0.0f; - m_rallyPointOffset.y = 0.0f; - m_selected = FALSE; - - Int i; - for (i=0; igetNext(); - cur->setNextBuildList(nullptr); // prevents recursion. - deleteInstance(cur); - cur = next; - } - } -} - -void BuildListInfo::parseStructure(INI *ini, void *instance, void* /*store*/, const void* /*userData*/) -{ - const char* c = ini->getNextToken(); - AsciiString tTemplateName(c); - - static const FieldParse myFieldParse[] = - { - { "Name", INI::parseAsciiString, nullptr, offsetof( BuildListInfo, m_buildingName ) }, - { "Location", INI::parseCoord2D, nullptr, offsetof( BuildListInfo, m_location ) }, - { "Rebuilds", INI::parseInt, nullptr, offsetof( BuildListInfo, m_numRebuilds ) }, - { "Angle", INI::parseAngleReal, nullptr, offsetof( BuildListInfo, m_angle ) }, - { "InitiallyBuilt", INI::parseBool, nullptr, offsetof( BuildListInfo, m_isInitiallyBuilt ) }, - { "RallyPointOffset", INI::parseCoord2D, nullptr, offsetof( BuildListInfo, m_rallyPointOffset ) }, - { "AutomaticallyBuild", INI::parseBool, nullptr, offsetof( BuildListInfo, m_automaticallyBuild ) }, - { nullptr, nullptr, nullptr, 0 } - }; - - BuildListInfo *buildInfo = newInstance( BuildListInfo ); - buildInfo->setTemplateName(tTemplateName); - ini->initFromINI(buildInfo, myFieldParse); - ((AISideBuildList*)instance)->addInfo(buildInfo); -} - - -/** - BuildListInfo - Duplicate - note - if linked, duplicates linked items. -*/ -BuildListInfo *BuildListInfo::duplicate() -{ - BuildListInfo *first = newInstance( BuildListInfo ); - *first = *this; - first->m_nextBuildList = nullptr; - BuildListInfo *next = this->m_nextBuildList; - BuildListInfo *cur = first; - while (next) { - BuildListInfo *link = newInstance( BuildListInfo ); - *link = *next; - link->m_nextBuildList = nullptr; - cur->m_nextBuildList = link; - cur = link; - next = next->m_nextBuildList; - } - return first; -} - -// ------------------------------------------------------------------------------------------------ -/** CRC */ -// ------------------------------------------------------------------------------------------------ -void BuildListInfo::crc( Xfer *xfer ) -{ - -} - -// ------------------------------------------------------------------------------------------------ -/** Xfer method - * Version Info: - * 1: Initial version */ -// ------------------------------------------------------------------------------------------------ -void BuildListInfo::xfer( Xfer *xfer ) -{ - - // version - XferVersion currentVersion = 2; - XferVersion version = currentVersion; - xfer->xferVersion( &version, currentVersion ); - - xfer->xferAsciiString( &m_buildingName ); - xfer->xferAsciiString( &m_templateName ); - xfer->xferCoord3D( &m_location ); - xfer->xferCoord2D( &m_rallyPointOffset ); - xfer->xferReal( &m_angle ); - xfer->xferBool( &m_isInitiallyBuilt ); - xfer->xferUnsignedInt( &m_numRebuilds ); - xfer->xferAsciiString( &m_script ); - xfer->xferInt( &m_health ); - xfer->xferBool( &m_whiner ); - xfer->xferBool( &m_unsellable ); - xfer->xferBool( &m_repairable ); - xfer->xferBool( &m_automaticallyBuild ); - // m_renderObj we don't need to xfer this, its for the editor only - // m_shadowObj we don't need to xfer this, its for the editor only - // m_selected we don't need to xfer this, its for the editor only - xfer->xferObjectID( &m_objectID ); - xfer->xferUnsignedInt( &m_objectTimestamp ); - xfer->xferBool( &m_underConstruction ); - xfer->xferUser( m_resourceGatherers, sizeof( ObjectID ) * MAX_RESOURCE_GATHERERS ); - xfer->xferBool( &m_isSupplyBuilding ); - xfer->xferInt( &m_desiredGatherers ); - xfer->xferBool( &m_priorityBuild ); - if (version>=2) { - xfer->xferInt(&m_currentGatherers); - } - -} - -// ------------------------------------------------------------------------------------------------ -/** Load post process */ -// ------------------------------------------------------------------------------------------------ -void BuildListInfo::loadPostProcess() -{ - -} - -/* ********* TeamsInfoRec class ****************************/ -TeamsInfoRec::TeamsInfoRec() : - m_numTeams(0), m_numTeamsAllocated(0), m_teams(nullptr) -{ -} - -TeamsInfoRec::TeamsInfoRec(const TeamsInfoRec& thatref) : - m_numTeams(0), m_numTeamsAllocated(0), m_teams(nullptr) -{ - *this = thatref; -} - -TeamsInfoRec::~TeamsInfoRec() -{ - clear(); -} - -// ug, I hate having to overload stuff, but this makes it a lot easier to make copies safely -TeamsInfoRec& TeamsInfoRec::operator=(const TeamsInfoRec& thatref) -{ - const TeamsInfoRec* that = &thatref; - if (this != that) - { - this->clear(); - for (int i = 0; i < that->m_numTeams; i++) - { - this->addTeam(that->m_teams[i].getDict()); - } - } - return *this; -} - -void TeamsInfoRec::clear() -{ - Int i; - - for (i = 0; i < m_numTeams; ++i) - m_teams[i].clear(); - - m_numTeams = 0; - m_numTeamsAllocated = 0; - delete [] m_teams; - m_teams = nullptr; -} - -TeamsInfo *TeamsInfoRec::findTeamInfo(AsciiString name, Int* index /*= nullptr*/) -{ - for (int i = 0; i < m_numTeams; ++i) - { - if (m_teams[i].getDict()->getAsciiString(TheKey_teamName) == name) - { - if (index) - *index = i; - return &m_teams[i]; - } - } - return nullptr; -} - -void TeamsInfoRec::addTeam(const Dict* d) -{ - enum - { - TEAM_ALLOC_CHUNK = 8 ///< how many teams to alloc at a time - }; - - DEBUG_ASSERTCRASH(m_numTeams < 2048, ("%d teams have been allocated (so far). This seems excessive.", m_numTeams )); - if (m_numTeams >= m_numTeamsAllocated) - { - // pool[]ify - const Int newNumTeamsAllocated = m_numTeams + TEAM_ALLOC_CHUNK; - TeamsInfo* nti = NEW TeamsInfo[newNumTeamsAllocated]; - Int i; - - for (i = 0; i < m_numTeams; ++i) - nti[i] = m_teams[i]; - - delete [] m_teams; - m_teams = nti; - m_numTeamsAllocated = newNumTeamsAllocated; - } - - m_teams[m_numTeams].init(d); - - ++m_numTeams; -} - -void TeamsInfoRec::removeTeam(Int i) -{ - if (i < 0 || i >= m_numTeams || m_numTeams <= 1) - return; - - --m_numTeams; - - for ( ; i < m_numTeams; ++i) - m_teams[i] = m_teams[i+1]; - - m_teams[m_numTeams].clear(); -} diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 607e05e77e1..87ad9d74fe4 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,16 +477,16 @@ 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 Include/GameLogic/ScriptConditions.h Include/GameLogic/ScriptEngine.h Include/GameLogic/Scripts.h - Include/GameLogic/SidesList.h +# Include/GameLogic/SidesList.h Include/GameLogic/Squad.h - Include/GameLogic/TerrainLogic.h +# Include/GameLogic/TerrainLogic.h Include/GameLogic/TurretAI.h Include/GameLogic/VictoryConditions.h Include/GameLogic/Weapon.h @@ -834,9 +834,9 @@ 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/SidesList.cpp - Source/GameLogic/Map/TerrainLogic.cpp +# Source/GameLogic/Map/PolygonTrigger.cpp +# Source/GameLogic/Map/SidesList.cpp +# Source/GameLogic/Map/TerrainLogic.cpp Source/GameLogic/Object/Armor.cpp Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp Source/GameLogic/Object/Behavior/BattleBusSlowDeathBehavior.cpp diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index a242d9bfda7..0949b390d31 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -531,6 +531,14 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/GUI/Gadget/W3DTextEntry.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/GUI/Gadget/W3DTextEntry.cpp") #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/GUI/Gadget/W3DVerticalSlider.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/GUI/Gadget/W3DVerticalSlider.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/Include/GameLogic/SidesList.h", Game.CORE, "GameEngine/Include/GameLogic/SidesList.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameLogic/TerrainLogic.h", Game.CORE, "GameEngine/Include/GameLogic/TerrainLogic.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp", Game.CORE, "GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/Map/SidesList.cpp", Game.CORE, "GameEngine/Source/GameLogic/Map/SidesList.cpp") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/Map/TerrainLogic.cpp", Game.CORE, "GameEngine/Source/GameLogic/Map/TerrainLogic.cpp") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameLogic/CaveSystem.h", Game.CORE, "GameEngine/Include/GameLogic/CaveSystem.h") #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameLogic/CrateSystem.h", Game.CORE, "GameEngine/Include/GameLogic/CrateSystem.h") #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameLogic/Damage.h", Game.CORE, "GameEngine/Include/GameLogic/Damage.h")