Ejemplo n.º 1
0
time_of_day tod_manager::time_of_day_at(const unit_map& units,const map_location& loc, const gamemap& map) const
{
	int lighten = std::max<int>(map.get_terrain_info(map.get_terrain(loc)).light_modification() , 0);
	int darken = std::min<int>(map.get_terrain_info(map.get_terrain(loc)).light_modification() , 0);

	time_of_day tod = get_time_of_day(lighten + darken,loc);

	if(loc.valid()) {
		map_location locs[7];
		locs[0] = loc;
		get_adjacent_tiles(loc,locs+1);

		for(int i = 0; i != 7; ++i) {
			const unit_map::const_iterator itor = units.find(locs[i]);
			if(itor != units.end() &&
			    itor->second.get_ability_bool("illuminates") &&
			    !itor->second.incapacitated())
			{
				unit_ability_list illum = itor->second.get_abilities("illuminates");
				unit_abilities::effect illum_effect(illum,lighten,false);
				int mod = illum_effect.get_composite_value();
				if(mod + tod.lawful_bonus > illum.highest("max_value").first) {
					mod = illum.highest("max_value").first - tod.lawful_bonus;
				}
				lighten = std::max<int>(mod, lighten);
				darken = std::min<int>(mod, darken);
			}
		}
	}
	tod = get_time_of_day(lighten + darken,loc);

	return tod;
}
Ejemplo n.º 2
0
bool basic_unit_filter_impl::matches(const unit & u, const map_location& loc, const unit * u2) const
{
	bool matches = true;

	if(loc.valid()) {
		scoped_xy_unit auto_store("this_unit", loc, fc_.get_disp_context().units());
		if (u2) {
			const map_location& loc2 = u2->get_location();
			scoped_xy_unit auto_store("other_unit", loc2, fc_.get_disp_context().units());
			matches = internal_matches_filter(u, loc, u2);
		} else {
			matches = internal_matches_filter(u, loc, u2);
		}
	} else {
		// If loc is invalid, then this is a recall list unit (already been scoped)
		matches = internal_matches_filter(u, loc, nullptr);
	}

	// Handle [and], [or], and [not] with in-order precedence
	for (size_t i = 0; i < cond_children_.size(); i++) {
		switch (cond_child_types_[i].v) {
			case conditional::TYPE::AND:
				matches = matches && cond_children_[i].matches(u,loc);
				break;
			case conditional::TYPE::OR:
				matches = matches || cond_children_[i].matches(u,loc);
				break;
			case conditional::TYPE::NOT:
				matches = matches && !cond_children_[i].matches(u,loc);
		}
	}
	return matches;
}
Ejemplo n.º 3
0
void game_display::select_hex(map_location hex)
{
	if(hex.valid() && fogged(hex)) {
		return;
	}
	display::select_hex(hex);

	display_unit_hex(hex);
}
Ejemplo n.º 4
0
// Notice: caller must make sure loc of parameter is centor location of desired erase unit!
bool base_map::erase(const map_location& loc, bool overlay)
{
	if (!loc.valid()) {
		return false;
	}
	base_unit* u = overlay? coor_map_[index(loc.x, loc.y)].overlay: coor_map_[index(loc.x, loc.y)].base;
	if (!u) {
		return false;
	}
	return erase2(u);
}
Ejemplo n.º 5
0
void game_display::display_unit_hex(map_location hex)
{
	if (!hex.valid())
		return;

	wb::future_map future; /**< Lasts for whole method. */

	const unit *u = resources::gameboard->get_visible_unit(hex, dc_->teams()[viewing_team()], !dont_show_all_);
	if (u) {
		displayedUnitHex_ = hex;
		invalidate_unit();
	}
}
Ejemplo n.º 6
0
void game_display::display_unit_hex(map_location hex)
{
	if (!hex.valid())
		return;

	wb::future_map future; //< Lasts for whole method.

	const unit *u = get_visible_unit(hex, (*teams_)[viewing_team()], !viewpoint_);
	if (u) {
		displayedUnitHex_ = hex;
		invalidate_unit();
	}
}
Ejemplo n.º 7
0
void highlighter::set_mouseover_hex(const map_location& hex)
{
	clear();

	if(!hex.valid()) {
		return;
	}

	real_map ensure_real_map;
	mouseover_hex_ = hex;
	//if we're right over a unit, just highlight all of this unit's actions
	unit_map::iterator it = get_unit_map().find(hex);
	if(it != get_unit_map().end()) {
		selection_candidate_ = it.get_shared_ptr();

		if(resources::gameboard->teams().at(it->side()-1).get_side_actions()->unit_has_actions(*it)) {
			owner_unit_ = it.get_shared_ptr();
		}

		//commented code below is to also select the first action of this unit as
		//the main highlight; it doesn't fit too well in the UI
//		side_actions::iterator action_it = side_actions_->find_first_action_of(*it);
//		if(action_it != side_actions_->end()) {
//			main_highlight_ = *action_it;
//		}
	}

	//Set the execution/deletion/bump targets.
	if(owner_unit_) {
		side_actions::iterator itor = side_actions_->find_first_action_of(*owner_unit_);
		if(itor != side_actions_->end()) {
			selected_action_ = *itor;
		}
	}

	//Overwrite the above selected_action_ if we find a better one
	if(side_actions_->empty()) {
		return;
	}
	for(action_ptr act : boost::adaptors::reverse(*side_actions_)) {
		/**@todo "is_numbering_hex" is not the "correct" criterion by which to
		 * select the hightlighted/selected action. It's just convenient for me
		 * to use at the moment since it happens to coincide with the "correct"
		 * criterion, which is to use find_main_highlight.*/
		if(act->is_numbering_hex(hex)) {
			selected_action_ = act;
			break;
		}
	}
}
Ejemplo n.º 8
0
config replay_helper::get_event(const std::string& name, const map_location& loc, const map_location*  last_select_loc)
{
	config ev;
	ev["raise"] = name;
	if(loc.valid()) {
		config& source = ev.add_child("source");
		loc.write(source);
	}
	if(last_select_loc != nullptr && last_select_loc->valid())
	{
		config& source = ev.add_child("last_select");
		last_select_loc->write(source);
	}
	return ev;
}
Ejemplo n.º 9
0
void gamemap::set_special_location(const std::string& id, const map_location& loc)
{
	bool valid = loc.valid();
	auto it_left = starting_positions_.left.find(id);
	if (it_left != starting_positions_.left.end()) {
		if (valid) {
			starting_positions_.left.replace_data(it_left, loc);
		}
		else {
			starting_positions_.left.erase(it_left);
		}
	}
	else {
		starting_positions_.left.insert(it_left, std::make_pair(id, loc));
	}
}
Ejemplo n.º 10
0
const time_of_day tod_manager::get_illuminated_time_of_day(const map_location& loc, int for_turn) const
{
	// get ToD ignoring illumination
	time_of_day tod = get_time_of_day(loc, for_turn);

	// now add illumination
	const gamemap& map = *resources::game_map;
	const unit_map& units = *resources::units;
	int light_modif =  map.get_terrain_info(map.get_terrain(loc)).light_modification();

	int light = tod.lawful_bonus + light_modif;
	int illum_light = light;

	if(loc.valid()) {
		map_location locs[7];
		locs[0] = loc;
		get_adjacent_tiles(loc,locs+1);

		for(int i = 0; i != 7; ++i) {
			const unit_map::const_iterator itor = units.find(locs[i]);
			if(itor != units.end() &&
			    itor->get_ability_bool("illuminates") &&
			    !itor->incapacitated())
			{
				unit_ability_list illum = itor->get_abilities("illuminates");
				unit_abilities::effect illum_effect(illum, light, false);

				illum_light = light + illum_effect.get_composite_value();
				//max_value and min_value control the final result
				//unless ToD + terrain effect is stronger
				int max = std::max(light, illum.highest("max_value").first);
				int min = std::min(light, illum.lowest("min_value").first);
				if(illum_light > max) {
					illum_light = max;
				} else if (illum_light < min) {
					illum_light = min;
				}

			}
		}
	}

	tod.bonus_modified = illum_light - tod.lawful_bonus;
	tod.lawful_bonus = illum_light;

	return tod;
}
Ejemplo n.º 11
0
void base_map::insert(const map_location loc, base_unit* u)
{
	std::stringstream err;
	if (!loc.valid()) {
		err << "Trying to add " << u->name() << " at an invalid location; Discarding.";
		delete u;
		VALIDATE(false, err.str());
	}
	bool base = u->base();

	if ((base && coor_map_[index(loc.x, loc.y)].base) ||
		(!base && coor_map_[index(loc.x, loc.y)].overlay)) {
		err << "trying to overwrite existing unit at (" << loc.x << ", " << loc.y << ")";
		delete u;
		VALIDATE(false, err.str());
	}

	// some application maybe require coor_map_ valid before set_location.
	// but touch_locs is got after set_location. only valid on center location.
	if (base) {
		coor_map_[index(loc.x, loc.y)].base = u;
	} else {
		coor_map_[index(loc.x, loc.y)].overlay = u;
	}

	u->set_location(loc);

	// it is called after set_location directly, use touch_locs safely.
	const std::set<map_location>& touch_locs = u->get_touch_locations();
	if (touch_locs.size() != 1) {
		for (std::set<map_location>::const_iterator itor = touch_locs.begin(); itor != touch_locs.end(); ++ itor) {
			if (base) {
				coor_map_[index(itor->x, itor->y)].base = u;
			} else {
				coor_map_[index(itor->x, itor->y)].overlay = u;
			}
		}
	}

	// insert p into time-axis.*
	u->map_index_ = map_vsize_;
	map_[map_vsize_ ++] = u;
	if (u->require_sort()) {
		sort_map(*u);
	}
}
Ejemplo n.º 12
0
time_of_day tod_manager::get_time_of_day(int illuminated, const map_location& loc, int n_turn) const
{
	time_of_day res = get_time_of_day_turn(n_turn);

	if(loc.valid()) {
		for(std::vector<area_time_of_day>::const_iterator i = areas_.begin(); i != areas_.end(); ++i) {
			if(i->hexes.count(loc) == 1) {

				VALIDATE(i->times.size(), _("No time of day has been defined."));

				res = i->times[(n_turn-1)%i->times.size()];
				break;
			}
		}
	}

	if(illuminated) {
		res.bonus_modified=illuminated;
		res.lawful_bonus += illuminated;
	}
	return res;
}
Ejemplo n.º 13
0
bool gamemap::on_board(const map_location& loc) const
{
	return loc.valid() && loc.x < w_ && loc.y < h_;
}
Ejemplo n.º 14
0
pathfind::plain_route pathfind::a_star_search(const map_location& src, const map_location& dst,
                            double stop_at, const cost_calculator *calc, const size_t width,
                            const size_t height,
                            const teleport_map *teleports) {
	//----------------- PRE_CONDITIONS ------------------
	assert(src.valid(width, height));
	assert(dst.valid(width, height));
	assert(calc != NULL);
	assert(stop_at <= calc->getNoPathValue());
	//---------------------------------------------------

	DBG_PF << "A* search: " << src << " -> " << dst << '\n';

	if (calc->cost(dst, 0) >= stop_at) {
		LOG_PF << "aborted A* search because Start or Dest is invalid\n";
		pathfind::plain_route locRoute;
		locRoute.move_cost = int(calc->getNoPathValue());
		return locRoute;
	}

	// increment search_counter but skip the range equivalent to uninitialized
	search_counter += 2;
	if (search_counter - bad_search_counter <= 1u)
		search_counter += 2;

	static std::vector<node> nodes;
	nodes.resize(width * height);  // this create uninitalized nodes

	indexer index(width, height);
	comp node_comp(nodes);

	nodes[index(dst)].g = stop_at + 1;
	nodes[index(src)] = node(0, src, map_location::null_location, dst, true, teleports);

	std::vector<int> pq;
	pq.push_back(index(src));

	while (!pq.empty()) {
		node& n = nodes[pq.front()];

		n.in = search_counter;

		std::pop_heap(pq.begin(), pq.end(), node_comp);
		pq.pop_back();

		if (n.t >= nodes[index(dst)].g) break;

		std::vector<map_location> locs;

		int i;
		if (teleports && !teleports->empty()) {

			std::set<map_location> allowed_teleports;
			teleports->get_adjacents(allowed_teleports, n.curr);

			i = allowed_teleports.size() +6;
			locs = std::vector<map_location>(i);

			std::copy(allowed_teleports.begin(), allowed_teleports.end(), locs.begin() + 6);
		} else
		{ locs = std::vector<map_location>(6); i = 6;}

		get_adjacent_tiles(n.curr, &locs[0]);

		for (; i-- > 0;) {
			if (!locs[i].valid(width, height)) continue;
			if (locs[i] == n.curr) continue;
			node& next = nodes[index(locs[i])];

			double thresh = (next.in - search_counter <= 1u) ? next.g : stop_at + 1;
			// cost() is always >= 1  (assumed and needed by the heuristic)
			if (n.g + 1 >= thresh) continue;
			double cost = n.g + calc->cost(locs[i], n.g);
			if (cost >= thresh) continue;

			bool in_list = next.in == search_counter + 1;

			next = node(cost, locs[i], n.curr, dst, true, teleports);

			if (in_list) {
				std::push_heap(pq.begin(), std::find(pq.begin(), pq.end(), static_cast<int>(index(locs[i]))) + 1, node_comp);
			} else {
				pq.push_back(index(locs[i]));
				std::push_heap(pq.begin(), pq.end(), node_comp);
			}
		}
	}

	pathfind::plain_route route;
	if (nodes[index(dst)].g <= stop_at) {
		DBG_PF << "found solution; calculating it...\n";
		route.move_cost = static_cast<int>(nodes[index(dst)].g);
		for (node curr = nodes[index(dst)]; curr.prev != map_location::null_location; curr = nodes[index(curr.prev)]) {
			route.steps.push_back(curr.curr);
		}
		route.steps.push_back(src);
		std::reverse(route.steps.begin(), route.steps.end());
	} else {
		LOG_PF << "aborted a* search  " << "\n";
		route.move_cost = static_cast<int>(calc->getNoPathValue());
	}

	return route;
}