Skip to content

Reimplement 17 more BuildingsState functions that are 100% - #280

Merged
gynt merged 8 commits into
sourcehold:mainfrom
6and8:buildingsstate-100-2
Oct 28, 2026
Merged

gynt merged 8 commits into
sourcehold:mainfrom
6and8:buildingsstate-100-2

Conversation

@6and8

@6and8 6and8 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

18 more Map::Buildings::BuildingsState functions from #273 that now measure 100% with reccmp --resolve-wrapped-calls (struct and function resolvers enabled locally, not committed), with their status entries. Same split as #274: #273 keeps the 23 that are still below 100%.

canUnitReachAdjacentTile, canUnitReachBuildingPerimeter, countPlayerResources, extinguishBuildingFire, findClosestReachableAlliedBuilding, findFreeCathedralAssemblyTile, findFreeEngineerAssemblyTile, getPriceForDisbandedUnitType, growWheat, isSpaceAvailableAtUnitRallyPoint, processBuildingIDsNeedPeasantsQueue, processDamageToUnitsOnBuilding, processResourceLoss, setNewOnFarmDestination, setupBarracksCampgroundPositions, setupMercenaryPostCampgroundPositions, spawnRandomFireEffectOnBuilding, updateBuildingAreaTileGraphics.

Measured on top of current main: all 18 measure 100%, and before the sync the branch built alone (141 BuildingsState sources) had all 141 at 100%, including processWallBuildingLoss, whose tail call into processResourceLoss now resolves. canUnitReachBuildingPerimeter and processResourceLoss are built with /GL (cmake/compiler-flags-gl.txt), as in #273.

Updated for the Ghidra sync on main

main is merged in. It now has the two void return types this PR needed (the header commit here becomes a no-op). The follow-up commit adapts the sources to the new header: someFarmRelatedState instead of padding_0x26e, mercenaryOutpostCampgroundLocations[formation][piece][i] in setupMercenaryPostCampgroundPositions, and casts made redundant by the new short/int types dropped. It also renames the Building fields in main's own users (field202_0x2c8 -> field201_0x2c8 in countFarms / countBuildingsForPlayer / aiPlaceAIVBuilding, field162_0x280 -> field161_0x280, ...), which no longer compiled. extinguishBuildingFire moved here from #273 after reaching 100% (the second loop's row tile plus x as a local gives the original's add order). The style commits fix the files the clang-format 22 check flagged.

Faithful quirks, commented in the source: findFreeCathedralAssemblyTile reads SearchRelatedXYOffsets_1[3] on every iteration, and canUnitReachAdjacentTile compares a tile's height with itself.

Cheat sheet candidates

  • If the original adjusts a parameter after copying it, adjust the parameter, not a copy (isSpaceAvailableAtUnitRallyPoint: the requested group is copied first, then the parameter is changed).
  • instance - this kept in a stack slot means one field is read through DAT_X::instance inside an otherwise this-> loop (setupBarracksCampgroundPositions).
  • If/else chain order follows the original's first test: when it jumps straight into a body, that arm comes first (countPlayerResources).
  • Declaration order of two locals can swap their stack slots (canUnitReachAdjacentTile).

Built with the bundled MSVC1400-SP1, natively on Windows.

🤖 Generated with Claude Code

loamifi-jake and others added 2 commits October 27, 2026 17:07
…rn void

Both originals leave whatever is in eax: updateBuildingAreaTileGraphics ends on a dead
lea of the last MiscDisplayLayer address (which Ghidra took as a ushort* return),
spawnCrowForBuilding on the last call's result. The only callers (deleteBuilding,
UpdateDairyFarm) ignore the value. Returning void drops the xor eax, eax our
reimplementations would otherwise add.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
17 functions from sourcehold#273 that now match the original exactly (reccmp 100%, with
--resolve-wrapped-calls), with their status lines. canUnitReachBuildingPerimeter
and processResourceLoss are built with /GL, as in sourcehold#273.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gynt
gynt previously approved these changes Oct 27, 2026
@gynt

gynt commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

@6and8 Just one comment!

The original's add/cmp/ja is MSVC's folded range check, so
damage < 14 || damage > 27 and damage < 0 || damage > 1 give the same code as
the unsigned casts (still 100%).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
loamifi-jake and others added 5 commits October 28, 2026 09:19
Renamed Building fields (field202_0x2c8 -> field201, field162_0x280 -> field161, ...),
someFarmRelatedState instead of padding_0x26e, mercenaryOutpostCampgroundLocations as [6][3][24],
and casts made redundant by the short/int types dropped. The renames also cover main's own
users so the BuildingsState sources compile again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second loop's row tile plus x goes through a local, which gives the original's add order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6and8 pushed a commit to 6and8/OpenSHC that referenced this pull request Oct 28, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gynt
gynt self-requested a review October 28, 2026 19:40
@gynt
gynt merged commit f35e657 into sourcehold:main Oct 28, 2026
1 check passed
gynt added a commit that referenced this pull request Oct 28, 2026
* reimplement: 28 Map::Buildings Update* functions at 100%

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* buildings: follow main's header renames in main's own users

field202_0x2c8 -> field201_0x2c8, field201_0x2c6 -> field200_0x2c6, field162_0x280 -> field161_0x280:
these files no longer compiled after the Ghidra sync. Same change as in #280 and #273.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* cmake: build the BuildingsState callees of the /GL Update* functions with /GL

Without LTCG knowledge of updateVisuallyActiveState, validateBuildingTetheredUnits,
buildingHasSpaceForResource and getBuildingResourceAmountByUid the eight /GL Update*
functions keep the building ID across those calls and do not match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Revert the resolver flags committed by mistake in the previous commit

The /GL list change stays; the Globals/*.hpp and *.func.hpp edits were local reccmp flags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Jake Vawter <jake.vawter@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gynt <gynt@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants