示例#1
0
文件: undo.cpp 项目: Wedge009/wesnoth
/**
 * Applies the pending fog/shroud changes from the undo stack.
 * Does nothing if the the current side does not use fog or shroud.
 * @returns  true if shroud  or fog was cleared.
 */
bool undo_list::apply_shroud_changes() const
{
	game_display &disp = *resources::screen;
	team &tm = resources::gameboard->teams()[side_ - 1];
	// No need to do clearing if fog/shroud has been kept up-to-date.
	if ( tm.auto_shroud_updates()  ||  !tm.fog_or_shroud() ) {
		return false;
	}
	shroud_clearer clearer;
	bool cleared_shroud = false;
	const size_t list_size = undos_.size();


	// Loop through the list of undo_actions.
	for( size_t i = 0; i != list_size; ++i ) {
		if (const shroud_clearing_action* action = dynamic_cast<const shroud_clearing_action*>(&undos_[i])) {
			LOG_NG << "Turning an undo...\n";

			// Clear the hexes this unit can see from each hex occupied during
			// the action.
			std::vector<map_location>::const_iterator step;
			for (step = action->route.begin(); step != action->route.end(); ++step) {
				// Clear the shroud, collecting new sighted events.
				// (This can be made gradual by changing "true" to "false".)
				if ( clearer.clear_unit(*step, tm, action->view_info, true) ) {
					cleared_shroud = true;
				}
			}
		}
	}


	if (!cleared_shroud) {
		return false;
	}
	// If we clear fog or shroud outside a synced context we get OOS
	// Note that it can happen that we call this function from ouside a synced context
	// when we reload  a game and want to prevent undoing. But in this case this is
	// preceeded by a manual update_shroud call so that cleared_shroud is false.
	assert(synced_context::is_synced());

	// The entire stack needs to be cleared in order to preserve replays.
	// (The events that fired might depend on current unit positions.)
	// (Also the events that did not fire might depend on unit positions (they whould have fired if the unit would have standed on different positions, for example this can happen if they have a [have_unit] in [filter_condition]))

	// Update the display before pumping events.
	clearer.invalidate_after_clear();
	disp.draw();

	// Fire sighted events
	if ( clearer.fire_events() ) {
		// Fix up the display in case WML changed stuff.
		clear_shroud(side_);
		disp.invalidate_unit();
		disp.draw();
	}

	return true;
}
示例#2
0
/**
 * Applies the pending fog/shroud changes from the undo stack.
 * Does nothing if the the current side does not use fog or shroud.
 * @returns  an index (into undos_) pointing to the first undoable action
 *           that can be kept (or undos_.size() if none can be kept).
 */
size_t undo_list::apply_shroud_changes() const
{
	game_display &disp = *resources::screen;
	team &tm = (*resources::teams)[side_ - 1];
	// No need to do clearing if fog/shroud has been kept up-to-date.
	if ( tm.auto_shroud_updates()  ||  !tm.fog_or_shroud() )
		return 0;


	shroud_clearer clearer;
	bool cleared_shroud = false;  // for optimization
	size_t erase_to = 0;
	size_t list_size = undos_.size();


	// Loop through the list of undo_actions.
	for( size_t i = 0; i != list_size; ++i ) {
		const undo_action & action = undos_[i];
		// Only actions with vision data are relevant.
		if ( !action.view_info )
			continue;
		LOG_NG << "Turning an undo...\n";

		// Clear the hexes this unit can see from each hex occupied during
		// the action.
		std::vector<map_location>::const_iterator step;
		for (step = action.route.begin(); step != action.route.end(); ++step) {
			// Clear the shroud, collecting new sighted events.
			// (This can be made gradual by changing "true" to "false".)
			if ( clearer.clear_unit(*step, tm, *action.view_info, true) ) {
				cleared_shroud = true;
				erase_to = i + 1;
			}
		}
	}

	// Optimization: if nothing was cleared, then there is nothing to redraw.
	if ( cleared_shroud ) {
		// Update the display before pumping events.
		clearer.invalidate_after_clear();
		disp.draw();
	}

	// Fire sighted events
	if ( clearer.fire_events() ) {
		// Fix up the display in case WML changed stuff.
		clear_shroud(side_);
		disp.invalidate_unit();
		disp.draw();
		// The entire stack needs to be cleared in order to preserve replays.
		// (The events that fired might depend on current unit positions.)
		erase_to = list_size;
	}

	return erase_to;
}