Пример #1
0
void get_tiles_radius(gamemap const &map, std::vector<map_location> const &locs,
                      size_t radius, std::set<map_location> &res, xy_pred *pred)
{
	typedef std::set<map_location> location_set;
	location_set not_visited(locs.begin(), locs.end()), must_visit, filtered_out;
	++radius;

	for(;;) {
		location_set::const_iterator it = not_visited.begin(), it_end = not_visited.end();
		std::copy(it,it_end,std::inserter(res,res.end()));
		for(; it != it_end; ++it) {
			map_location adj[6];
			get_adjacent_tiles(*it, adj);
			for(size_t i = 0; i != 6; ++i) {
				map_location const &loc = adj[i];
				if(map.on_board(loc) && !res.count(loc) && !filtered_out.count(loc)) {
					if(!pred || (*pred)(loc)) {
						must_visit.insert(loc);
					} else {
						filtered_out.insert(loc);
					}
				}
			}
		}

		if(--radius == 0 || must_visit.empty()) {
			break;
		}

		not_visited.swap(must_visit);
		must_visit.clear();
	}
}
Пример #2
0
/**
 * Clears shroud (and fog) at the provided location and its immediate neighbors.
 * This is an aid for the [teleport] action, allowing the destination to be
 * cleared before teleporting, while the unit's full visual range gets cleared
 * after.
 * The @a viewer is needed for correct firing of sighted events.
 *
 * @return whether or not information was uncovered (i.e. returns true if the
 *         locations in question were fogged/shrouded under shared vision/maps).
 */
bool shroud_clearer::clear_dest(const map_location &dest, const unit &viewer)
{
	team & viewing_team = resources::gameboard->get_team(viewer.side());
	// A pair of dummy variables needed to simplify some logic.
	std::size_t enemies, friends;

	// Abort if there is nothing to clear.
	if ( !viewing_team.fog_or_shroud() )
		return false;

	// Cache some values.
	const map_location & real_loc = viewer.get_location();
	const std::size_t viewer_id = viewer.underlying_id();

	// Clear the destination.
	bool cleared_something = clear_loc(viewing_team, dest, dest, real_loc,
	                                   viewer_id, true, enemies, friends);

	// Clear the adjacent hexes (will be seen even if vision is 0, and the
	// graphics do not work so well for an isolated cleared hex).
	adjacent_loc_array_t adjacent;
	get_adjacent_tiles(dest, adjacent.data());
	for (unsigned i = 0; i < adjacent.size(); ++i )
		if ( clear_loc(viewing_team, adjacent[i], dest, real_loc, viewer_id,
		               true, enemies, friends) )
			cleared_something = true;

	if ( cleared_something )
		invalidate_after_clear();

	return cleared_something;
}
Пример #3
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;
}
Пример #4
0
bool display_context::would_be_discovered(const map_location & loc, int side_num, bool see_all)
{
	map_location adjs[6];
	get_adjacent_tiles(loc,adjs);

	for (const map_location &u_loc : adjs)
	{
		unit_map::const_iterator u_it = units().find(u_loc);
		if (!u_it.valid()) {
			continue;
		}
		const unit & u = *u_it;
		if (get_team(side_num).is_enemy(u.side()) && !u.incapacitated()) {
			// Enemy spotted in adjacent tiles, check if we can see him.
			// Watch out to call invisible with see_all=true to avoid infinite recursive calls!
			if(see_all) {
				return true;
			} else if (!get_team(side_num).fogged(u_loc)
			&& !u.invisible(u_loc, *this, true)) {
				return true;
			}
		}
	}
	return false;
}
Пример #5
0
void gamemap::set_terrain(const map_location& loc, const t_translation::t_terrain & terrain, const terrain_type_data::tmerge_mode mode, bool replace_if_failed) {
	if(!on_board_with_border(loc)) {
		// off the map: ignore request
		return;
	}

	t_translation::t_terrain new_terrain = tdata_->merge_terrains(get_terrain(loc), terrain, mode, replace_if_failed);

	if(new_terrain == t_translation::NONE_TERRAIN) {
		return;
	}

	if(on_board(loc)) {
		const bool old_village = is_village(loc);
		const bool new_village = tdata_->is_village(new_terrain);

		if(old_village && !new_village) {
			villages_.erase(std::remove(villages_.begin(),villages_.end(),loc),villages_.end());
		} else if(!old_village && new_village) {
			villages_.push_back(loc);
		}
	}

	tiles_[loc.x + border_size_][loc.y + border_size_] = new_terrain;

	// Update the off-map autogenerated tiles
	map_location adj[6];
	get_adjacent_tiles(loc,adj);

	for(int n = 0; n < 6; ++n) {
		remove_from_border_cache(adj[n]);
	}
}
Пример #6
0
bool display_context::unit_can_move(const unit &u) const
{
	if(!u.attacks_left() && u.movement_left()==0)
		return false;

	// Units with goto commands that have already done their gotos this turn
	// (i.e. don't have full movement left) should have red globes.
	if(u.has_moved() && u.has_goto()) {
		return false;
	}

	const team &current_team = get_team(u.side());

	map_location locs[6];
	get_adjacent_tiles(u.get_location(), locs);
	for(int n = 0; n != 6; ++n) {
		if (map().on_board(locs[n])) {
			const unit_map::const_iterator i = units().find(locs[n]);
			if (i.valid() && !i->incapacitated() &&
			    current_team.is_enemy(i->side())) {
				return true;
			}

			if (u.movement_cost(map()[locs[n]]) <= u.movement_left()) {
				return true;
			}
		}
	}

	return false;
}
Пример #7
0
// "flood fill" a tile name to adjacent tiles of certain terrain
static void flood_name(const map_location& start, const std::string& name, std::map<map_location,std::string>& tile_names,
	const t_translation::t_match& tile_types, const terrain_map& terrain,
	unsigned width, unsigned height,
	size_t label_count, std::map<map_location,std::string>* labels, const std::string& full_name) {
	map_location adj[6];
	get_adjacent_tiles(start,adj);
	size_t n;
	//if adjacent tiles are tiles and unnamed, name them
	for (n = 0; n < 6; n++) {
		//we do not care for tiles outside the middle part
		//cast to unsigned to skip x < 0 || y < 0 as well.
		if (unsigned(adj[n].x) >= width / 3 || unsigned(adj[n].y) >= height / 3) {
			continue;
		}

		const t_translation::t_terrain terr = terrain[adj[n].x + (width / 3)][adj[n].y + (height / 3)];
		const location loc(adj[n].x, adj[n].y);
		if((t_translation::terrain_matches(terr, tile_types)) && (tile_names.find(loc) == tile_names.end())) {
			tile_names.insert(std::pair<location, std::string>(loc, name));
			//labeling decision: this is result of trial and error on what looks best in game
			if (label_count % 6 == 0) { //ensure that labels do not occur more often than every 6 recursions
				labels->insert(std::pair<map_location, std::string>(loc, full_name));
				label_count++; //ensure that no adjacent tiles get labeled
			}
			flood_name(adj[n], name, tile_names, tile_types, terrain, width, height, label_count++, labels, full_name);
		}
	}
}
Пример #8
0
bool can_generate(const gamemap& map, const std::vector<team>& teams, const unit_map& units, const unit& u, const map_location& loc)
{
	if (!map.on_board(loc)) {
		return false;
	}
	if (u.movement_cost(map[loc]) == unit_movement_type::UNREACHABLE) {
		return false;
	}
	unit_map::const_iterator it = units.find(loc, false);
	if (it.valid() && !it->can_stand(u)) {
		return false;
	}

	map_location locs[6];
	get_adjacent_tiles(loc, locs);
	for (int i = 0; i != 6; ++i) {
		if (!map.on_board(locs[i])) {
			continue;
		}
		if (u.movement_cost(map[locs[i]]) != unit_movement_type::UNREACHABLE) {
			return true;
		}
	}
	return false;
}
Пример #9
0
bool backstab_check(const map_location& attacker_loc,
                    const map_location& defender_loc,
                    const unit_map& units, const std::vector<team>& teams)
{
	const unit_map::const_iterator defender = units.find(defender_loc);
	if(defender == units.end()) return false; // No defender

	map_location adj[6];
	get_adjacent_tiles(defender_loc, adj);
	int i;
	for(i = 0; i != 6; ++i) {
		if(adj[i] == attacker_loc)
			break;
	}
	if(i >= 6) return false;  // Attack not from adjacent location

	const unit_map::const_iterator opp =
		units.find(adj[(i+3)%6]);
	if(opp == units.end()) return false; // No opposite unit
	if (opp->incapacitated()) return false;
	if (size_t(defender->side() - 1) >= teams.size() || size_t(opp->side() - 1) >= teams.size())
		return true; // If sides aren't valid teams, then they are enemies
	if (teams[defender->side() - 1].is_enemy(opp->side()))
		return true; // Defender and opposite are enemies
	return false; // Defender and opposite are friends
}
Пример #10
0
static void move_unit_between(const map_location& a, const map_location& b, unit& temp_unit,unsigned int step_num,unsigned int step_left)
{
	game_display* disp = game_display::get_singleton();
	if(!disp || disp->video().update_locked() || disp->video().faked() || (disp->fogged(a) && disp->fogged(b))) {
		return;
	}

	temp_unit.set_location(a);
	disp->invalidate(temp_unit.get_location());
	temp_unit.set_facing(a.get_relative_dir(b));
	unit_animator animator;
	animator.replace_anim_if_invalid(&temp_unit,"movement",a,b,step_num,
			false,"",0,unit_animation::INVALID,NULL,NULL,step_left);
	animator.start_animations();
        animator.pause_animation();
	disp->scroll_to_tiles(a,b,game_display::ONSCREEN,true,0.0,false);
        animator.restart_animation();

	// useless now, previous short draw() just did one
	// new_animation_frame();

	int target_time = animator.get_animation_time_potential();

		// target_time must be short to avoid jumpy move
		// std::cout << "target time: " << target_time << "\n";
	// we round it to the next multile of 200
	target_time += 200;
	target_time -= target_time%200;

	// This code causes backwards teleport because the time > 200 causes offset > 1.0
	// which will not match with the following -1.0
	// if(  target_time - animator.get_animation_time_potential() < 100 ) target_time +=200;

	animator.wait_until(target_time);
		// debug code, see unit_frame::redraw()
		// std::cout << "   end\n";
	map_location arr[6];
	get_adjacent_tiles(a, arr);
	unsigned int i;
	for (i = 0; i < 6; ++i) {
		disp->invalidate(arr[i]);
	}
	get_adjacent_tiles(b, arr);
	for (i = 0; i < 6; ++i) {
		disp->invalidate(arr[i]);
	}
}
Пример #11
0
void terrain_analyze::get_village_terrain() {
	BOOST_FOREACH(const map_location& loc, village_location_) {
		map_location adj[6];
		get_adjacent_tiles(loc,adj);

		for(int i = 0; i < 6; i++) {
			add_village_battle(loc, adj[i]);
		}
	}
Пример #12
0
/**
 * River generation.
 *
 * Rivers have a source, and then keep on flowing until they meet another body
 * of water, which they flow into, or until they reach the edge of the map.
 * Rivers will always flow downhill, except that they can flow a maximum of
 * 'river_uphill' uphill.  This is to represent the water eroding the higher
 * ground lower.
 *
 * Every possible path for a river will be attempted, in random order, and the
 * first river path that can be found that makes the river flow into another
 * body of water or off the map will be used.
 *
 * If no path can be found, then the river's generation will be aborted, and
 * false will be returned.  true is returned if the river is generated
 * successfully.
 */
static bool generate_river_internal(const height_map& heights,
	terrain_map& terrain, int x, int y, std::vector<location>& river,
	std::set<location>& seen_locations, int river_uphill)
{
	const bool on_map = x >= 0 && y >= 0 &&
		x < static_cast<long>(heights.size()) &&
		y < static_cast<long>(heights.back().size());

	if(on_map && !river.empty() && heights[x][y] >
			heights[river.back().x][river.back().y] + river_uphill) {

		return false;
	}

	// If we're at the end of the river
	if(!on_map || terrain[x][y] == t_translation::SHALLOW_WATER ||
			terrain[x][y] == t_translation::DEEP_WATER) {

		LOG_NG << "generating river...\n";

		// Generate the river
		for(std::vector<location>::const_iterator i = river.begin();
		    i != river.end(); ++i) {
			terrain[i->x][i->y] = t_translation::SHALLOW_WATER;
		}

		LOG_NG << "done generating river\n";

		return true;
	}

	location current_loc(x,y);
	location adj[6];
	get_adjacent_tiles(current_loc,adj);
	static int items[6] = {0,1,2,3,4,5};
	std::random_shuffle(items,items+4);

	// Mark that we have attempted from this location
	seen_locations.insert(current_loc);
	river.push_back(current_loc);
	for(int a = 0; a != 6; ++a) {
		const location& loc = adj[items[a]];
		if(seen_locations.count(loc) == 0) {
			const bool res = generate_river_internal(heights,terrain,loc.x,loc.y,river,seen_locations,river_uphill);
			if(res) {
				return true;
			}

		}
	}

	river.pop_back();

	return false;
}
Пример #13
0
static map_location place_village(const t_translation::t_map& map,
	const size_t x, const size_t y, const size_t radius, const config& cfg,
	tcode_list_cache &adj_liked_cache)
{
	const map_location loc(x,y);
	std::set<map_location> locs;
	get_tiles_radius(loc,radius,locs);
	map_location best_loc;
	int best_rating = 0;
	for(std::set<map_location>::const_iterator i = locs.begin();
			i != locs.end(); ++i) {

		if(i->x < 0 || i->y < 0 || i->x >= static_cast<long>(map.size()) ||
				i->y >= static_cast<long>(map[i->x].size())) {

			continue;
		}

		const t_translation::t_terrain t = map[i->x][i->y];
		const std::string str = t_translation::write_terrain_code(t);
		if (const config &child = cfg.find_child("village", "terrain", str)) {
			tcode_list_cache::iterator l = adj_liked_cache.find(t);
			t_translation::t_list *adjacent_liked;
			if (l != adj_liked_cache.end()) {
				adjacent_liked = &(l->second);
			} else {
				adj_liked_cache[t] = t_translation::read_list(child["adjacent_liked"]);
				adjacent_liked = &(adj_liked_cache[t]);
			}

			int rating = child["rating"];
			map_location adj[6];
			get_adjacent_tiles(map_location(i->x,i->y),adj);
			for(size_t n = 0; n != 6; ++n) {
				if(adj[n].x < 0 || adj[n].y < 0 ||
						adj[n].x >= static_cast<long>(map.size()) ||
						adj[n].y >= static_cast<long>(map[adj[n].x].size())) {

					continue;
				}

				const t_translation::t_terrain t2 = map[adj[n].x][adj[n].y];
				rating += std::count(adjacent_liked->begin(),adjacent_liked->end(),t2);
			}

			if(rating > best_rating) {
				best_loc = map_location(i->x,i->y);
				best_rating = rating;
			}
		}
	}

	return best_loc;
}
Пример #14
0
boost::shared_ptr<attacks_vector> aspect_attacks::analyze_targets() const
{
    const move_map& srcdst = get_srcdst();
    const move_map& dstsrc = get_dstsrc();
    const move_map& enemy_srcdst = get_enemy_srcdst();
    const move_map& enemy_dstsrc = get_enemy_dstsrc();

    boost::shared_ptr<attacks_vector> res(new attacks_vector());
    unit_map& units_ = *resources::units;

    std::vector<map_location> unit_locs;
    for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
        if (i->side() == get_side() && i->attacks_left() && !(i->can_recruit() && get_passive_leader())) {
            if (!i->matches_filter(vconfig(filter_own_), i->get_location())) {
                continue;
            }
            unit_locs.push_back(i->get_location());
        }
    }

    bool used_locations[6];
    std::fill(used_locations,used_locations+6,false);

    moves_map dummy_moves;
    move_map fullmove_srcdst, fullmove_dstsrc;
    calculate_possible_moves(dummy_moves,fullmove_srcdst,fullmove_dstsrc,false,true);

    unit_stats_cache().clear();

    for(unit_map::const_iterator j = units_.begin(); j != units_.end(); ++j) {

        // Attack anyone who is on the enemy side,
        // and who is not invisible or petrified.
        if (current_team().is_enemy(j->side()) && !j->incapacitated() &&
                !j->invisible(j->get_location()))
        {
            if (!j->matches_filter(vconfig(filter_enemy_), j->get_location())) {
                continue;
            }
            map_location adjacent[6];
            get_adjacent_tiles(j->get_location(), adjacent);
            attack_analysis analysis;
            analysis.target = j->get_location();
            analysis.vulnerability = 0.0;
            analysis.support = 0.0;
            do_attack_analysis(j->get_location(), srcdst, dstsrc,
                               fullmove_srcdst, fullmove_dstsrc, enemy_srcdst, enemy_dstsrc,
                               adjacent,used_locations,unit_locs,*res,analysis, current_team());
        }
    }
    return res;
}
bool default_map_generator_job::generate_river_internal(const height_map& heights,
	terrain_map& terrain, int x, int y, std::vector<map_location>& river,
	std::set<map_location>& seen_locations, int river_uphill)
{
	const bool on_map = x >= 0 && y >= 0 &&
		x < static_cast<long>(heights.size()) &&
		y < static_cast<long>(heights.back().size());

	if(on_map && !river.empty() && heights[x][y] >
			heights[river.back().x][river.back().y] + river_uphill) {

		return false;
	}

	// If we're at the end of the river
	if(!on_map || terrain[x][y] == t_translation::SHALLOW_WATER ||
			terrain[x][y] == t_translation::DEEP_WATER) {

		LOG_NG << "generating river...\n";

		// Generate the river
		for(auto i : river) {
			terrain[i.x][i.y] = t_translation::SHALLOW_WATER;
		}

		LOG_NG << "done generating river\n";

		return true;
	}

	map_location current_loc(x,y);
	map_location adj[6];
	get_adjacent_tiles(current_loc,adj);
	std::shuffle(std::begin(adj), std::end(adj), rng_);

	// Mark that we have attempted from this map_location
	seen_locations.insert(current_loc);
	river.push_back(current_loc);
	for(const map_location& loc : adj) {
		if(seen_locations.count(loc) == 0) {
			const bool res = generate_river_internal(heights,terrain,loc.x,loc.y,river,seen_locations,river_uphill);
			if(res) {
				return true;
			}

		}
	}

	river.pop_back();

	return false;
}
Пример #16
0
/**
 * Expose map_location get_adjacent_tiles
 */
int intf_get_adjacent_tiles(lua_State* L)
{
	map_location l1 = pop_map_location(L);

	map_location locs[6];
	get_adjacent_tiles(l1, locs);

	for (int i = 0; i < 6; ++i) {
		push_map_location(L, locs[i]);
	}

	return 12;
}
Пример #17
0
map_location pathfind::find_vacant_tile(const gamemap& map,
				const unit_map& units,
				const map_location& loc,
				pathfind::VACANT_TILE_TYPE vacancy,
				const unit* pass_check)
{
	if (!map.on_board(loc)) return map_location();
	std::set<map_location> pending_tiles_to_check, tiles_checked;
	pending_tiles_to_check.insert(loc);
	// Iterate out 50 hexes from loc
	for (int distance = 0; distance < 50; ++distance) {
		if (pending_tiles_to_check.empty())
			return map_location();
		//Copy over the hexes to check and clear the old set
		std::set<map_location> tiles_checking;
		tiles_checking.swap(pending_tiles_to_check);
		//Iterate over all the hexes we need to check
		foreach (const map_location &loc, tiles_checking)
		{
			//If this area is not a castle but should, skip it.
			if (vacancy == pathfind::VACANT_CASTLE && !map.is_castle(loc)) continue;
			const bool pass_check_and_unreachable = pass_check
				&& pass_check->movement_cost(map[loc]) == unit_movement_type::UNREACHABLE;
			//If the unit can't reach the tile and we have searched
			//an area of at least radius 10 (arbitrary), skip the tile.
			//Neccessary for cases such as an unreachable
			//starting hex surrounded by 6 other unreachable hexes, in which case
			//the algorithm would not even search distance==1
			//even if there's a reachable hex for distance==2.
			if (pass_check_and_unreachable && distance > 10) continue;
			//If the hex is empty and we do either no pass check or the hex is reachable, return it.
			if (units.find(loc) == units.end() && !pass_check_and_unreachable) return loc;
			map_location adjs[6];
			get_adjacent_tiles(loc,adjs);
			foreach (const map_location &loc, adjs)
			{
				if (!map.on_board(loc)) continue;
				// Add the tile to be checked if it hasn't already been and
				// isn't being checked.
				if (tiles_checked.find(loc) == tiles_checked.end() &&
				    tiles_checking.find(loc) == tiles_checking.end())
				{
					pending_tiles_to_check.insert(loc);
				}
			}
		}
		tiles_checked.swap(tiles_checking);
	}
	return map_location();
}
Пример #18
0
void cave_map_generator::cave_map_generator_job::build_chamber(map_location loc, std::set<map_location>& locs, size_t size, size_t jagged)
{
	if(size == 0 || locs.count(loc) != 0 || !params.on_board(loc))
		return;

	locs.insert(loc);

	map_location adj[6];
	get_adjacent_tiles(loc,adj);
	for(size_t n = 0; n != 6; ++n) {
		if(int(rng_() % 100) < (100l - static_cast<long>(jagged))) {
			build_chamber(adj[n],locs,size-1,jagged);
		}
	}
}
Пример #19
0
/**
 * Expose map_location get_adjacent_tiles
 */
int intf_get_adjacent_tiles(lua_State* L)
{
	map_location l1;
	if(!luaW_tolocation(L, 1, l1)) {
		return luaL_argerror(L, 1, "expected a location");
	}

	map_location locs[6];
	get_adjacent_tiles(l1, locs);

	for (int i = 0; i < 6; ++i) {
		luaW_pushlocation(L, locs[i]);
	}

	return 6;
}
void cave_map_generator::place_castle(int starting_position, const map_location &loc)
{
	if (starting_position != -1) {
		set_terrain(loc, keep_);

		t_translation::coordinate coord =
			{ loc.x + gamemap::default_border, loc.y + gamemap::default_border };
		starting_positions_[starting_position] = coord;
	}

	map_location adj[6];
	get_adjacent_tiles(loc,adj);
	for(size_t n = 0; n != 6; ++n) {
		set_terrain(adj[n],castle_);
	}
}
Пример #21
0
void tile::calculate_corner(int n)
{
	const DIRECTION neighbour_a = static_cast<DIRECTION>(n);
	const DIRECTION neighbour_b = static_cast<DIRECTION>((n+1)%6);

	const int point_a = (n+2)%6;
	const int point_b = (n+4)%6;

	const tile* adja = neighbours_[neighbour_a];
	const tile* adjb = neighbours_[neighbour_b];

	if(adja != NULL && adja->corners_[point_a].init) {
		corners_[n] = adja->corners_[point_a];
		return;
	}

	if(adjb != NULL && adjb->corners_[point_b].init) {
		corners_[n] = adjb->corners_[point_b];
		return;
	}

	location adj[6];
	get_adjacent_tiles(loc_,adj);

	corners_[n].position.x() = (translate_x(loc_) +
	                            translate_x(adj[neighbour_a]) +
	                            translate_x(adj[neighbour_b]))/3.0;
	corners_[n].position.y() = (translate_y(loc_) +
	                            translate_y(adj[neighbour_a]) +
	                            translate_y(adj[neighbour_b]))/3.0;

	int sum = height_;
	int num = 1;
	if(adja != NULL) {
		sum += adja->height_;
		++num;
	}

	if(adjb != NULL) {
		sum += adjb->height_;
		++num;
	}

	sum /= num;
	corners_[n].position.z() = translate_height(sum);
	corners_[n].init = true;
}
Пример #22
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;
}
Пример #23
0
map_location find_vacant_tile(const gamemap& map,
				const unit_map& units,
				const map_location& loc,
				VACANT_TILE_TYPE vacancy,
				const unit* pass_check)
{
	std::set<map_location> pending_tiles_to_check;
	std::set<map_location> tiles_checked;
	pending_tiles_to_check.insert( loc );
	// Iterate out 50 hexes from loc
	for (int distance = 0; distance < 50; ++distance) {
		if (pending_tiles_to_check.empty())
			return map_location();
		//Copy over the hexes to check and clear the old set
		std::set<map_location> tiles_checking = pending_tiles_to_check;
		std::set<map_location>::const_iterator tc_itor = tiles_checking.begin();
		pending_tiles_to_check.clear();
		//Iterate over all the hexes we need to check
		for ( ; tc_itor != tiles_checking.end(); ++tc_itor )
		{
			//If the unit cannot reach this area or it's not a castle but should, skip it.
			if ((vacancy == VACANT_CASTLE && !map.is_castle(*tc_itor))
			|| (pass_check && pass_check->movement_cost(map[*tc_itor])
					== unit_movement_type::UNREACHABLE))
				continue;
			//If the hex is empty, return it.
			if (map.on_board(*tc_itor) && units.find(*tc_itor) == units.end())
				return (*tc_itor);
			map_location adjs[6];
			get_adjacent_tiles(*tc_itor,adjs);
			for (int i = 0; i != 6; ++i)
			{
				//Add the tile to be checked if it hasn't already been and isn't already
				//pending to be checked
				if (pending_tiles_to_check.find(adjs[i]) == pending_tiles_to_check.end() &&
					tiles_checked.find(adjs[i]) == tiles_checked.end() &&
					tiles_checking.find(adjs[i]) == tiles_checking.end())
				{
					pending_tiles_to_check.insert(adjs[i]);
				}
			}
		}
		tiles_checked = tiles_checking;
	}
	return map_location();
}
Пример #24
0
void cave_map_generator::cave_map_generator_job::place_castle(int starting_position, const map_location &loc)
{
	if (starting_position != -1) {
		set_terrain(loc, params.keep_);

		t_translation::coordinate coord(
				  loc.x + gamemap::default_border
				, loc.y + gamemap::default_border);
		starting_positions_.insert(t_translation::tstarting_positions::value_type(std::to_string(starting_position), coord));
	}

	map_location adj[6];
	get_adjacent_tiles(loc,adj);
	for(size_t n = 0; n != 6; ++n) {
		set_terrain(adj[n], params.castle_);
	}
}
map_location pathfind::find_vacant_tile(const gamemap& map,
				const unit_map& units,
				const map_location& loc,
				pathfind::VACANT_TILE_TYPE vacancy,
				const unit* pass_check)
{
	if (!map.on_board(loc)) return map_location();
	std::set<map_location> pending_tiles_to_check, tiles_checked;
	pending_tiles_to_check.insert(loc);
	// Iterate out 50 hexes from loc
	for (int distance = 0; distance < 50; ++distance) {
		if (pending_tiles_to_check.empty())
			return map_location();
		//Copy over the hexes to check and clear the old set
		std::set<map_location> tiles_checking;
		tiles_checking.swap(pending_tiles_to_check);
		//Iterate over all the hexes we need to check
		foreach (const map_location &loc, tiles_checking)
		{
			//If the unit cannot reach this area or it's not a castle but should, skip it.
			if ((vacancy == pathfind::VACANT_CASTLE && !map.is_castle(loc))
			|| (pass_check && pass_check->movement_cost(map[loc])
					== unit_movement_type::UNREACHABLE))
				continue;
			//If the hex is empty, return it.
			if (units.find(loc) == units.end())
				return loc;
			map_location adjs[6];
			get_adjacent_tiles(loc,adjs);
			foreach (const map_location &loc, adjs)
			{
				if (!map.on_board(loc)) continue;
				// Add the tile to be checked if it hasn't already been and
				// isn't being checked.
				if (tiles_checked.find(loc) == tiles_checked.end() &&
				    tiles_checking.find(loc) == tiles_checking.end())
				{
					pending_tiles_to_check.insert(loc);
				}
			}
		}
		tiles_checked.swap(tiles_checking);
	}
	return map_location();
}
Пример #26
0
bool enemy_zoc(unit_map const &units, std::vector<team> const &teams,
	map_location const &loc, team const &viewing_team, int side, bool see_all)
{
	map_location locs[6];
	const team &current_team = teams[side-1];
	get_adjacent_tiles(loc,locs);
	for (int i = 0; i != 6; ++i)
	{
		const unit *u = get_visible_unit(units, locs[i], viewing_team, see_all);
		if (u && u->side() != side && current_team.is_enemy(u->side()) &&
		    u->emits_zoc())
		{
			return true;
		}
	}

	return false;
}
Пример #27
0
static void get_tiles_radius_internal(const map_location& a, size_t radius,
	std::set<map_location>& res, std::map<map_location,int>& visited)
{
	visited[a] = radius;
	res.insert(a);

	if(radius == 0) {
		return;
	}

	map_location adj[6];
	get_adjacent_tiles(a,adj);
	for(size_t i = 0; i != 6; ++i) {
		if(visited.count(adj[i]) == 0 || visited[adj[i]] < int(radius)-1) {
			get_tiles_radius_internal(adj[i],radius-1,res,visited);
		}
	}
}
void mouse_action_unit::move(editor_display& disp, const map_location& hex)
{
	if (hex != previous_move_hex_) {

		update_brush_highlights(disp, hex);

		std::set<map_location> adjacent_set;
		map_location adjacent[6];
		get_adjacent_tiles(previous_move_hex_, adjacent);

		for (int i = 0; i < 6; i++)
			adjacent_set.insert(adjacent[i]);

		disp.invalidate(adjacent_set);
		previous_move_hex_ = hex;

		const unit_map& units = disp.get_units();
		const unit_map::const_unit_iterator unit_it = units.find(hex);
		if (unit_it != units.end()) {

			disp.set_mouseover_hex_overlay(NULL);

			SDL_Rect rect;
			rect.x = disp.get_location_x(hex);
			rect.y = disp.get_location_y(hex);
			rect.h = disp.hex_size();
			rect.w = disp.hex_size();
			std::stringstream str;
			str << N_("Identifier: ") << unit_it->id()     << "\n"
				<< N_("Name: ")    << unit_it->name()      << "\n"
				<< N_("Type: ")    << unit_it->type_name() << "\n"
				<< N_("Level: ")   << unit_it->level()     << "\n"
				<< N_("Cost: ")    << unit_it->cost()      << "\n"
				<< N_("Recruit: ") << utils::join(unit_it->recruits()) << "\n";
			tooltips::clear_tooltips();
			tooltips::add_tooltip(rect, str.str());
		}
		else {
			set_mouse_overlay(disp);
		}
	}
}
Пример #29
0
void mouse_action_item::move(editor_display& disp, const map_location& hex)
{
	if (hex != previous_move_hex_) {

		update_brush_highlights(disp, hex);

		std::set<map_location> adjacent_set;
		map_location adjacent[6];
		get_adjacent_tiles(previous_move_hex_, adjacent);

		for (int i = 0; i < 6; i++)
			adjacent_set.insert(adjacent[i]);

		disp.invalidate(adjacent_set);
		previous_move_hex_ = hex;

	//	const item_map& items = disp.get_items();
	//	const item_map::const_item_iterator item_it = items.find(hex);
//		if (item_it != items.end()) {
//
//			disp.set_mouseover_hex_overlay(nullptr);
//
//			SDL_Rect rect;
//			rect.x = disp.get_location_x(hex);
//			rect.y = disp.get_location_y(hex);
//			rect.h = disp.hex_size();
//			rect.w = disp.hex_size();
//			std::stringstream str;
//			str << N_("ID: ")   << item_it->id()   << "\n"
//				<< N_("Name: ") << item_it->name() << "\n"
//				<< N_("Type: ") << item_it->type_name();
//			tooltips::clear_tooltips();
//			tooltips::add_tooltip(rect, str.str());
//		}
//		else {
//			set_mouse_overlay(disp);
//		}
	}
}
Пример #30
0
std::set<map_location> editor_map::get_contiguous_terrain_tiles(const map_location& start) const
{
	t_translation::t_terrain terrain = get_terrain(start);
	std::set<map_location> result;
	std::deque<map_location> queue;
	result.insert(start);
	queue.push_back(start);
	//this is basically a breadth-first search along adjacent hexes
	do {
		map_location adj[6];
		get_adjacent_tiles(queue.front(), adj);
		for (int i = 0; i < 6; ++i) {
			if (on_board_with_border(adj[i]) && get_terrain(adj[i]) == terrain
			&& result.find(adj[i]) == result.end()) {
				result.insert(adj[i]);
				queue.push_back(adj[i]);
			}
		}
		queue.pop_front();
	} while (!queue.empty());
	return result;
}