Fix bug #23712: Mage of Light halo not drawing correctly

The halo is recreated when the mage starts to move, and it's initially
placed in the top-left corner of the screen. On the next frame the game
corrects its position. Correcting the position clears the list of hexes the
halo overlaps, which essentially means "the overlapped hexes aren't known,
update them when the halo is redrawn". However, the game also uses the list
of overlapped hexes to determine when the halo should be invalidated, and
thus redrawn: because the list was empty, the halo was never invalidated,
and it stayed at the top-left corner.

Fixed by placing the halo in the right position to begin with. This commit
includes my previous fixes as well, though, because the code was simply
incorrect before (even if it doesn't break anything any more).
This commit is contained in:
Jyrki Vesterinen 2016-06-25 17:07:13 +03:00
parent 9db9a26143
commit 0bc068113a
4 changed files with 17 additions and 5 deletions

View file

@ -26,6 +26,8 @@ Version 1.13.4+dev:
* Various design improvements to GUI2 widgets
* New simpler GUI2 loading screen
* New colored cursor graphics
* Fixed Mage of Light halo appearing in the top-left corner of the screen
while the mage is moving (bug #23712).
* Fixed Observers icon appearing behind other top bar items in MP games on
horizontal UI resolutions < 1024 (bug #24455).
* Fixed ToD schedule progress indicator appearing behind other top bar items

View file

@ -14,6 +14,8 @@ Version 1.13.4+dev:
Portuguese, RACV, Russian, Scottish Gaelic, Spanish.
* User interface:
* Fixed Mage of Light halo appearing in the top-left corner of the screen
while the mage is moving (bug #23712).
* Fixed Observers icon appearing behind other top bar items in MP games on
horizontal UI resolutions < 1024 (bug #24455).
* Fixed ToD schedule progress indicator appearing behind other top bar items

View file

@ -48,6 +48,7 @@ public:
bool need_update() const { return images_.need_update(); }
bool does_change() const { return !images_.does_not_change(); }
bool on_location(const std::set<map_location>& locations) const;
bool location_not_known() const;
void add_overlay_location(std::set<map_location>& locations);
private:
@ -143,8 +144,8 @@ halo_impl::effect::effect(display * screen, int xpos, int ypos, const animated<i
const map_location& loc, ORIENTATION orientation, bool infinite) :
images_(img),
orientation_(orientation),
x_(xpos),
y_(ypos),
x_(0),
y_(0),
surf_(nullptr),
buffer_(nullptr),
rect_(sdl::empty_rect),
@ -165,6 +166,7 @@ void halo_impl::effect::set_location(int x, int y)
int new_x = x - disp->get_location_x(map_location::ZERO());
int new_y = y - disp->get_location_y(map_location::ZERO());
if (new_x != x_ || new_y != y_) {
unrender();
x_ = new_x;
y_ = new_y;
buffer_.assign(nullptr);
@ -219,7 +221,7 @@ bool halo_impl::effect::render()
// If rendered the first time, need to determine the area affected.
// If a halo changes size, it is not updated.
if(overlayed_hexes_.empty()) {
if(location_not_known()) {
display::rect_of_hexes hexes = disp->hexes_under_rect(rect);
display::rect_of_hexes::iterator i = hexes.begin(), end = hexes.end();
for (;i != end; ++i) {
@ -294,6 +296,11 @@ bool halo_impl::effect::on_location(const std::set<map_location>& locations) con
return false;
}
bool halo_impl::effect::location_not_known() const
{
return overlayed_hexes_.empty();
}
void halo_impl::effect::add_overlay_location(std::set<map_location>& locations)
{
for(std::vector<map_location>::const_iterator itor = overlayed_hexes_.begin();
@ -396,7 +403,8 @@ void halo_impl::unrender(std::set<map_location> invalidated_locations)
// Test all haloes not yet in the set
// which match one of the locations
if(invalidated_haloes.find(itor->first) == invalidated_haloes.end() &&
itor->second.on_location(invalidated_locations)) {
(itor->second.location_not_known() ||
itor->second.on_location(invalidated_locations))) {
// If found, add all locations which the halo invalidates,
// and add it to the set

View file

@ -161,7 +161,7 @@ void unit_drawer::redraw_unit (const unit & u) const
bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
if(!has_halo && !u.image_halo().empty()) {
ac.unit_halo_ = halo_man.add(0, 0, u.image_halo()+u.TC_image_mods(), map_location(-1, -1));
ac.unit_halo_ = halo_man.add(x, y - height_adjust, u.image_halo()+u.TC_image_mods(), map_location(-1, -1));
}
if(has_halo && u.image_halo().empty()) {
halo_man.remove(ac.unit_halo_);