unify(worldbuilder): Merge Generals and Zero Hour WorldBuilder - #3025
unify(worldbuilder): Merge Generals and Zero Hour WorldBuilder#3025OmarAglan wants to merge 2 commits into
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/Tools/WorldBuilder/src/LayersList.cpp | Adds polygon-trigger layer membership and active-layer behavior, and now synchronizes persisted assignments when layers are renamed. |
| Generals/Code/Tools/WorldBuilder/src/ScriptDialog.cpp | Expands script verification and side-bundle handling while retaining the existing version-3 polygon-trigger bundle format. |
| Generals/Code/Tools/WorldBuilder/src/WaypointOptions.cpp | Safely removes invalid triggers from layer membership before unlinking them from the global trigger list. |
| Generals/Code/Tools/WorldBuilder/src/WaterOptions.cpp | Applies the corresponding layer-membership cleanup when invalid water triggers are removed. |
| Generals/Code/GameEngine/Source/GameLogic/Map/PolygonTrigger.cpp | Adds trigger-layer serialization support while preserving retail Generals map compatibility through conditional version selection. |
Reviews (10): Last reviewed commit: "unify(worldbuilder): Merge WorldBuilder" | Re-trigger Greptile
c56bc00 to
bc2980a
Compare
bc2980a to
0a40354
Compare
0a40354 to
44c1641
Compare
| /***************POLYGON TRIGGERS DATA ***************/ | ||
| chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_3); | ||
| // Version 4 preserves polygon trigger layer assignments in script bundles. | ||
| chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_4); |
There was a problem hiding this comment.
well, as the added comments says version 4 is required because this record now contains the layer name and The updated reader only consumes it for version 4 and continues to load versions 1 to 3. note that old builds will not understand newly written version 4 bundles. so it probably safe.
There was a problem hiding this comment.
more explanation: adding layerName changes the serialized record layout, so keeping version 3 would cause the following trigger ID and flags to be read at the wrong offsets. Both writers and readers are updated together, and the reader only consumes layerName for version 4 or newer, so existing version 1–3 bundles still load.
The expected limitation is that older WorldBuilder builds cannot read bundles written in version 4.
this can be another pr that fix this, if needed
There was a problem hiding this comment.
I think that the retail version of vanilla Generals will not be able to open the maps saved with the version 4.
Could be discussed first but I suggest to introduce a new macro in GameDefines.h RETAIL_COMPATIBLE_WORLDBUILDER (enabled by default). So for PolygonTriggers it should keep using version 3 for generalsv when saving maps when that macro is enabled.
There was a problem hiding this comment.
Another option would be to keep the existing PolygonTriggers chunk at version 3 and store layer assignments in a separate optional chunk instead of changing the original record layout.
For example:
PolygonTriggers (version 3)
trigger count
trigger name
trigger ID
water and river flags
points
...
PolygonTriggerLayers (version 1)
assignment count
trigger name
layer name
...
The new WorldBuilder would write and register parsers for both chunks. It would load the version 3 triggers first, then apply the layer assignments from PolygonTriggerLayers.
Trigger names would probably be the safest key here because WorldBuilder already treats them as unique identifiers, and the script-bundle importer does not preserve the serialized trigger IDs.
The existing DataChunkInput::parse() implementation skips chunks for which no parser is registered, so retail WorldBuilder should read the version 3 PolygonTriggers data and ignore PolygonTriggerLayers. This would need to be confirmed with an actual retail WorldBuilder test.
The same extension chunk could be used for exported script bundles, allowing their main PolygonTriggers chunk to remain at version 3 as well.
it has big tradeoffs like for example, Saving the map again with retail WorldBuilder would remove the unsupported layer-assignment chunk, and Both the map loader and script-bundle importer would need to register the new parser.
we also should consider missing or invalid trigger names would need to fall back safely to the default trigger layer, and we would need to test maps and script bundles in both the new and retail WorldBuilder builds.
this would preserve retail readability without requiring users to disable a compatibility macro, while Zero Hour could retain its existing version 4 format.
But its complex, and im not in favor of it really, a clean change would be a macro as you suggested, we need another opinion,
There was a problem hiding this comment.
Why is this logic added to GeneralsMD, while Generals doesn't have a version 4? This doesn't seem right
7f8a34a to
09aa190
Compare
|
While reviewing the code yesterday, I found a few issues that are worth addressing. I don’t think they all need to be fixed in this PR unless they are required for correctness; the remaining items could be handled in one or two focused follow up PRs. This points to the Generals implementation, but the corresponding Zero Hour files should be checked as well.
|
Skyaero42
left a comment
There was a problem hiding this comment.
I stopped reviewing at some point
- There are quite a few issues with the merge.
- Particularly, I see code added to GeneralsMD files that I'm unable to find in Generals.
- The size of this review (> 10k changes) makes it hard to review. I recommend smaller changes.
| while (count>0) { | ||
| count--; | ||
| triggerName = file.readAsciiString(); | ||
| if (info->version >= K_TRIGGERS_VERSION_4) { |
There was a problem hiding this comment.
I think @stephanmeesters mentioned it already (but I don't see his comment appear here), this needs to be behind ZH guards or the Generals World Builder will no longer work properly.
#if RTS_ZEROHOUR
if (info->version >= K_TRIGGERS_VERSION_4) {
layerName = file.readAsciiString();
}
#endifThere was a problem hiding this comment.
I kept the reader version gated rather than Zero Hour-only. With the updated writer logic in #3024, Generals writes version 3 by default, but it can still write version 4 when RETAIL_COMPATIBLE_WORLDBUILDER is disabled. The Generals reader therefore still needs to understand version 4. Zero Hour continues writing and reading version 4.
| numPoints = file.readInt(); | ||
| PolygonTrigger *pTrig = newInstance(PolygonTrigger)(numPoints+1); | ||
| pTrig->setTriggerName(triggerName); | ||
| if (info->version >= K_TRIGGERS_VERSION_4) { |
There was a problem hiding this comment.
Needs to be behind RTS_ZEROHOUR guards
There was a problem hiding this comment.
The same reasoning applies here. Generals can receive version 4 data when compatibility is disabled, so it needs to apply the serialized layer name. The version check ensures that version 1–3 files retain their existing layout and behavior.
| void PolygonTrigger::WritePolygonTriggersDataChunk(DataChunkOutput &chunkWriter) | ||
| { | ||
| chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_3); | ||
| chunkWriter.openDataChunk("PolygonTriggers", K_TRIGGERS_VERSION_4); |
There was a problem hiding this comment.
Needs to be behind RTS_ZEROHOUR guards
There was a problem hiding this comment.
Updated in #3024. Both writer implementations now use RETAIL_COMPATIBLE_WORLDBUILDER && RTS_GENERALS: Generals writes version 3 by default, while Zero Hour and non-compatible Generals builds write version 4.
| chunkWriter.writeInt(count); | ||
| for (pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) { | ||
| chunkWriter.writeAsciiString(pTrig->getTriggerName()); | ||
| chunkWriter.writeAsciiString(pTrig->getLayerName()); |
There was a problem hiding this comment.
Needs to be behind RTS_ZEROHOUR guards
There was a problem hiding this comment.
Updated alongside the version selection. layerName is written only when the version 4 branch is selected, using !(RETAIL_COMPATIBLE_WORLDBUILDER && RTS_GENERALS) in both games.
| "include/WaypointTool.h" | ||
| "include/WBFrameWnd.h" | ||
| "include/WBHeightMap.h" | ||
| "include/WBPopupSlider.h" |
There was a problem hiding this comment.
Am I missing something or is this file not actually being added in this PR?
There was a problem hiding this comment.
WBPopupSlider.h already exists in both WorldBuilder trees on main, This PR only adds the existing header to the CMake source list, so there is no new file in this diff.
| pNextTrig = pTrig->getNext(); | ||
| pTrig->setNextPoly(nullptr); | ||
| // Register the imported trigger with its serialized WorldBuilder layer. | ||
| TheLayersList->addPolygonTriggerToLayersList(pTrig, pTrig->getLayerName()); |
There was a problem hiding this comment.
Why is this added to a GeneralsMD (zerohour) file, while it is a feature not present in Generals?
| count--; | ||
| Bool isWater = false; | ||
| triggerName = file.readAsciiString(); | ||
| if (info->version >= K_TRIGGERS_VERSION_4) { |
There was a problem hiding this comment.
Why is this added to a GeneralsMD (zerohour) file, while it is a feature not present in Generals?
| numPoints = file.readInt(); | ||
| PolygonTrigger *pTrig = newInstance(PolygonTrigger)(numPoints+1); | ||
| pTrig->setTriggerName(triggerName); | ||
| if (info->version >= K_TRIGGERS_VERSION_4) { |
There was a problem hiding this comment.
Why is this added to a GeneralsMD (zerohour) file, while it is a feature not present in Generals?
Ok i can spilt this pr to small review able pr, the question is how much? |
c30ce18 to
68d5ff3
Compare
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
68d5ff3 to
54a07b7
Compare
54a07b7 to
854debb
Compare
Merge with Rebase
Generals and Zero Hour currently maintain separate WorldBuilder implementations that have drifted apart. They need to be aligned before the duplicate editor trees can be moved to Core.
This pull merges the two implementations:
RTS_GENERALSandRTS_ZEROHOUR.No WorldBuilder files move to Core here. That remains the final pull in the series.
This branch is based on #3024, so GitHub will show the prerequisite commit until #3024 is merged with rebase.
Testing
git diff --check