Exemple #1
0
/**
 * Clears shroud from a single location.
 * This also records sighted events for later firing.
 *
 * In a few cases, this will also clear corner hexes that otherwise would
 * not normally get cleared.
 * @param tm               The team whose fog/shroud is affected.
 * @param loc              The location to clear.
 * @param view_loc         The location viewer is assumed at (for sighted events).
 * @param event_non_loc    The unit at this location cannot be sighted
 *                         (used to prevent a unit from sighting itself).
 * @param viewer_id        The underlying ID of the unit doing the sighting (for events).
 * @param check_units      If false, there is no checking for an uncovered unit.
 * @param enemy_count      Incremented if an enemy is uncovered.
 * @param friend_count     Incremented if a friend is uncovered.
 * @param spectator        Will be told if a unit is uncovered.
 *
 * @return whether or not information was uncovered (i.e. returns true if
 *         the specified location was fogged/ shrouded under shared vision/maps).
 */
bool shroud_clearer::clear_loc(team &tm, const map_location &loc,
                               const map_location &view_loc,
                               const map_location &event_non_loc,
                               std::size_t viewer_id, bool check_units,
                               std::size_t &enemy_count, std::size_t &friend_count,
                               move_unit_spectator * spectator)
{
	const gamemap &map = resources::gameboard->map();
	// This counts as clearing a tile for the return value if it is on the
	// board and currently fogged under shared vision. (No need to explicitly
	// check for shrouded since shrouded implies fogged.)
	bool was_fogged = tm.fogged(loc);
	bool result = was_fogged && map.on_board(loc);

	// Clear the border as well as the board, so that the half-hexes
	// at the edge can also be cleared of fog/shroud.
	if ( map.on_board_with_border(loc) ) {
		// Both functions should be executed so don't use || which
		// uses short-cut evaluation.
		// (This is different than the return value because shared vision does
		// not apply here.)
		if ( tm.clear_shroud(loc) | tm.clear_fog(loc) ) {
			// If we are near a corner, the corner might also need to be cleared.
			// This happens at the lower-left corner and at either the upper- or
			// lower- right corner (depending on the width).

			// Lower-left corner:
			if ( loc.x == 0  &&  loc.y == map.h()-1 ) {
				const map_location corner(-1, map.h());
				tm.clear_shroud(corner);
				tm.clear_fog(corner);
			}
			// Lower-right corner, odd width:
			else if ( is_odd(map.w())  &&  loc.x == map.w()-1  &&  loc.y == map.h()-1 ) {
				const map_location corner(map.w(), map.h());
				tm.clear_shroud(corner);
				tm.clear_fog(corner);
			}
			// Upper-right corner, even width:
			else if ( is_even(map.w())  &&  loc.x == map.w()-1  &&  loc.y == 0) {
				const map_location corner(map.w(), -1);
				tm.clear_shroud(corner);
				tm.clear_fog(corner);
			}
		}
	}

	// Possible screen invalidation.
	if ( was_fogged ) {
		display::get_singleton()->invalidate(loc);
		// Need to also invalidate adjacent hexes to get rid of the
		// "fog edge" graphics.
		adjacent_loc_array_t adjacent;
		get_adjacent_tiles(loc, adjacent.data());
		for (unsigned i = 0; i < adjacent.size(); ++i )
			display::get_singleton()->invalidate(adjacent[i]);
	}

	// Check for units?
	if ( result  &&  check_units  &&  loc != event_non_loc ) {
		// Uncovered a unit?
		unit_map::const_iterator sight_it = resources::gameboard->find_visible_unit(loc, tm);
		if ( sight_it.valid() ) {
			record_sighting(*sight_it, loc, viewer_id, view_loc);

			// Track this?
			if ( !sight_it->get_state(unit::STATE_PETRIFIED) ) {
				if ( tm.is_enemy(sight_it->side()) ) {
					++enemy_count;
					if ( spectator )
						spectator->add_seen_enemy(sight_it);
				} else {
					++friend_count;
					if ( spectator )
						spectator->add_seen_friend(sight_it);
				}
			}
		}
	}

	return result;
}