since the treeview nodes are not owned by the treeview but by the
content grid, they get destroyed after the treeview so accesing the
treeview in the nodes dtor might result in UB.
Also UB happend in playsingle_controller and unit_drawer::unit_drawer
in case that the teams vector was empty.
It occurred when a fight was simulated for a
* slowed unit
* that can level up after the fight
* using Monte Carlo simulation.
Monte_carlo_combat_matrix clears the matrix in constructor because it uses
the matrix in a different way than probability_combat_matrix. Clearing was
unnecessarily thorough and marked all the rows and columns as unused.
If the unit was slowed before the fight, no values were ever placed to
plane 0 (neither unit slowed). Thus, all the rows/columns in plane 0 were
still marked as unused even after the simulation.
After the Monte Carlo simulation, the simulation code considered the
possibility that the unit may have leveled up. It does that by moving all
the values that mean "combatant B dead" into the last row of plane 0, that
means "combatant A full HP and not slowed".
The code that moves the values assumes that at least one row and column is
used. If none are, then it dereferences an invalid iterator and corrupts
memory.
I fixed the bug my making prob_matrix::clear() leave row and column 0 as
used.
After applying this fix, I can't reproduce the assertion failure @mattsc
reported or the hang @GregoryLundberg reported. Those problems were likely
caused by the memory corruption.
Without this, multiple selections could occur in the Faction Select dialog. However, somehow the
next option immediately to the disabled one gets selected instead of the first available selection
as expected. While this fixes the FLG dialog, it might have repercussions for the Create Unit dialog.
It's possible this issue has something to do with the ordering of the map. Will have to investigate
further after this.
Changing to warning was done previously for all other messages of this
type but forgotten for this one (commit 7185d6cc80). Also, there’s not
been any recorded bug caused by this in many years, so there is no need
to keep the second part of the text.
It's only use was to pass refresh_lobby on process_gamelist_diff fail. It makes more sense to
delegate that to the caller - in this case, the lobby. This also means the chatbox widget owns
a twesnothd_connection pointer so the chatbox can be used in situations where no server connection
is present.
This can happen when enemy units are hidden under fog or have the hides
ability. Either way, enemy units always blocks the tunnel.
Invisible allied units may or may not block the tunnel, depending on
the setting of pass_allied_units in the [tunnel] tag. It is therefore
necessary to get and check the full teleport map during a unit’s move
through a teleport, but with see_all=true (while the path finding uses
see_all=false).
This commit fixes the behavior and reinstates the ‘failed teleport’
message.
If you have already killed Agadla by turn 4, instead of offering a choice, the three who appear simply join your forces.
This means it is possible to never get the Thieves, and not be able to recruit them. But you'd have to win before turn 4; so it's not possible unless you're cheating.
It is possible to take Elesenfar without ever capturing a village. To allow for this, and ensure the player always gets the Theives, they appear when Agadla dies as well as upon capturing a village.
Instead of a moveto, use a capture event so the theives only appear when actually capturing a village on the island.
Instead of listing the position of each village, use a radius so we can move them around, or add or remove a village more easily.
There was an old designer's note that killing the leaders in S01 ('The Elves Besieged') should reduce the number of ambushers hiding in S07 ('Crossroads').