Bonus * -> std::shared_ptr<Bonus>
This cures the following problems:
1) Memory corruption at exit. Some Bonus-es were deleted twice (mods?).
2) Memory leaks. Some Bonuses were not deleted.
3) Reduce the number of "Orphaned child" messages.
Valgrind reports 0 leaked memory now and no invalid reads/writes.
When hero is in water walking layer he can only exit to accessible or visitable land tiles, but not objects that have blocking visit and leave hero standing on water.
This is different than default flying behaviour because hero in air layer can only transit into accessible land layer without any blocking or visitable objects on them.
With old embark cost calculation pathfinder may end up thinking that hero can embark/disembark while have less movement points than base movement cost is. Now hero would be only able to embark / disembark if we have enough movement points to step on that tile. This rule is also valid for situation when hero have Admiral's Hat as in H3 even if hero don't have embark penalty he still use move points for embark and disembark.
Problem was found as it's was causing infitite loop in AI. Server of course rejected attempt to embark with less than 100 movement points while pathfinder tell AI that it's can still embark with 93 movement points.
Related movement code for client and AI is plumbed as well. Though at moment code still not finished because it's not teleport hero to the exit tile if he won battle.
Subterranean Gates unlike Monolith allow to visit hero standing on other exit. So of course pathfinder allowed that, but it's also allowed future movement through that hero which caused infinite loop for AI.
Bonus system even with caching add too big overhead so we'll only use it once for these bonuses.
Still I'm like it to be transparent for external code so it's a bit hacky code.
Original idea behind options is that options should only be set on pathfinder object creation (or via some special method in case pathfinder become persistent).
This way it's more clear that it's pointer to object on tile and not path node.
It's important because air layer nodes don't have visitable objects while tile under them can have one.
TurnInfo contain information about what movement-related bonuses and MP hero going to have on certain turn.
This way we can collect this information once for each turn so it's huge performance boost.
Initially wanter to name main class differently and back then getCost make sense.
Then renamed class to CPathfinderHelper, but forgot to rename function back.
Now pathfinder take into account different bonuses for different tuns. So if you only have FLYING_MOVEMENT bonus from Fly spell for one turn then pathfinder will only let you use air layer within one turn only.
That work for cost calculations too. Let's say you have two bonuses:
- FLYING_MOVEMENT with 20% penalty for next 2 turns
- FLYING_MOVEMENT with 40% penalty for 5 turns
Now pathfinder using correct penalty for each turn so movements in air layer going to be more expensive on 3-5 turns.
Now when oneTurnSpecialLayersLimit is enabled hero won't be able to stop on blocked or water tiles between turns.
It's default H3 mechanics so it's enabled by default.
CTerrainRect::showPath behaviour changed so it's will only add cross path graphics on embark/disembark and path ending.
We want continuous paths for flying and water walking even when land<-> water transition occur.
No action going to simplify isMovementAfterDestPossible and should be as well useful for cost calculations.
It's can be also used by client interface to show appropriate cursors and path.
There is two exceptions:
- Hero start movement from guarded tile.
- Hero that embarking into boat that standing on guarded tile.
In other cases future movement is impossible.
It's should be possible to go into air layer from visitable object (but opposite isn't allowed).
And when walking on water player can't really interact with any object at all so future movement always possible.
This way we can avoid layer checks when calculating paths by ignoring unitialized tiles entirely.
Also at this point pathfinder and movement actually works for everything except flying.
This still need investigation, but likely most of external code shouldn't be aware of layers in order to work properly because only LAND and SAIL can be targeted and single tile can't have both of these layers.