Example #1
0
void hero::add_modification(unit_map& units, hero_map& heros, std::vector<team>& teams, const config& mod, unit* u, hero* leader)
{
	foreach (const config &effect, mod.child_range("effect")) {
		const std::string &apply_to = effect["apply_to"];

		if (apply_to == "loyalty") {
			int increase = effect["increase"].to_int();

			if (increase) {
				increase_catalog(-1 * increase, *leader);
				if (!u->is_artifical()) {
					u->adjust();
				}
				// play animation
				std::stringstream str;
				str << dgettext("wesnoth", "loyalty") << "\n";
				std::vector<unit*> touchers;
				if (artifical* city = units.city_from_loc(u->get_location())) {
					touchers.push_back((unit*)(city));
				} else {
					touchers.push_back(u);
				}
				unit_display::unit_touching(u->get_location(), touchers, increase, str.str());
			}			
		} else if (apply_to == "office") {
			artifical* selected_city = unit_2_artifical(u);

			status_ = hero_status_backing;
			side_ = selected_city->side() - 1;
			selected_city->finish_heros().push_back(this);
			std::vector<hero*>& wander_heros = selected_city->wander_heros();
			wander_heros.erase(std::find(wander_heros.begin(), wander_heros.end(), this));

			std::string message = _("Let me join in. I will do my best to maintenance our honor.");
			show_hero_message(this, selected_city, message, game_events::INCIDENT_RECOMMENDONESELF);

			map_location loc2(MAGIC_HERO, number_);
			game_events::fire("post_recommend", selected_city->get_location(), loc2);

		} else if (apply_to == "wande") {
			std::vector<hero*> captains;
			if (artifical* city = units.city_from_loc(u->get_location())) {
				// fresh/finish/reside troop
				if (u->is_city()) {
					for (int type = 0; type < 3; type ++) { 
						std::vector<hero*>* list;
						if (type == 0) {
							list = &city->fresh_heros();
						} else if (type == 1) {
							list = &city->finish_heros();
						} else {
							list = &city->wander_heros();
						}
						std::vector<hero*>::iterator i2 = std::find(list->begin(), list->end(), this);
						if (i2 != list->end()) {
							list->erase(i2);
							break;
						}
					}
				} else {
					std::vector<unit*>& reside_troops = city->reside_troops();
					int index = 0;
					for (std::vector<unit*>::iterator i2 = reside_troops.begin(); i2 != reside_troops.end(); ++ i2, index ++) {
						if (*i2 != u) {
							continue;
						}
						u->replace_captains_internal(*this, captains);
						if (captains.empty()) {
							city->troop_go_out(index);
						} else {
							u->replace_captains(captains);
						}
						break;
					}
				}
			} else {
				// field troop
				u->replace_captains_internal(*this, captains);
				if (captains.empty()) {
					units.erase(u);
				} else {
					u->replace_captains(captains);
				}
			}
			// select one city in myself side
			artifical* to_city = units.city_from_cityno(leader->city_);
			to_city->wander_into(*this);

		} else if (apply_to == "communicate") {
			int increase = effect["increase"].to_int();
			std::vector<std::pair<int, unit*> > pairs;

			for (hero_map::iterator i = heros.begin(); i != heros.end(); ++ i) {
				const hero& h = *i;
				if (h.side_ != side_ || h.number_ == number_) {
					continue;
				}
				unit* u = find_unit(units, h);
				if (u->is_city() && h.number_ == u->master().number_) {
					continue;
				}
				pairs.push_back(std::make_pair<size_t, unit*>(h.number_, u));
			}
			if (increase && !pairs.empty()) {
				// display hero selection dialog
				gui2::thero_selection dlg(&teams, &units, heros, pairs, side_ + 1, "");
				try {
					dlg.show(resources::screen->video());
				} catch(twml_exception& e) {
					e.show(*resources::screen);
					return;
				}
				const std::set<size_t>& checked_pairs = dlg.checked_pairs();
				if (dlg.get_retval() != gui2::twindow::OK || checked_pairs.empty()) {
					return;
				}
				hero& to = heros[pairs[*checked_pairs.begin()].first];
				utils::string_map symbols;
				symbols["first"] = name();
				symbols["second"] = to.name();
				game_events::show_hero_message(&heros[214], NULL, vgettext("Feeling between $first and $second is increased.", symbols), game_events::INCIDENT_INVALID);
				
				// adjust troop if needed.
				increase_feeling_each(units, heros, to, increase);
			}
		}
	}
}