Пример #1
0
void cave_map_generator::cave_map_generator_job::place_passage(const passage& p)
{
	const std::string& chance = p.cfg["chance"];
	if(chance != "" && int(rng_()%100) < atoi(chance.c_str())) {
		return;
	}


	int windiness = p.cfg["windiness"];
	double laziness = std::max<double>(1.0, p.cfg["laziness"].to_double());

	passage_path_calculator calc(map_, params.wall_, laziness, windiness, rng_);

	pathfind::plain_route rt = a_star_search(p.src, p.dst, 10000.0, &calc, params.width_, params.height_);

	int width = std::max<int>(1, p.cfg["width"].to_int());
	int jagged = p.cfg["jagged"];

	for(std::vector<map_location>::const_iterator i = rt.steps.begin(); i != rt.steps.end(); ++i) {
		std::set<map_location> locs;
		build_chamber(*i,locs,width,jagged);
		for(std::set<map_location>::const_iterator j = locs.begin(); j != locs.end(); ++j) {
			set_terrain(*j, params.clear_);
		}
	}
}
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_);
	}
}
Пример #3
0
void cave_map_generator::cave_map_generator_job::place_chamber(const chamber& c)
{
	for(std::set<map_location>::const_iterator i = c.locs.begin(); i != c.locs.end(); ++i) {
		set_terrain(*i,params.clear_);
	}

	if (c.items == nullptr || c.locs.empty()) return;

	size_t index = 0;
	for (const config::any_child &it : c.items->all_children_range())
	{
		config cfg = it.cfg;
		config &filter = cfg.child("filter");
		config* object_filter = nullptr;
		if (config &object = cfg.child("object")) {
			if (config &of = object.child("filter"))
				object_filter = &of;
		}

		if (!it.cfg["same_location_as_previous"].to_bool()) {
			index = rng_()%c.locs.size();
		}
		std::string loc_var = it.cfg["store_location_as"];

		std::set<map_location>::const_iterator loc = c.locs.begin();
		std::advance(loc,index);

		cfg["x"] = loc->x + 1;
		cfg["y"] = loc->y + 1;

		if (filter) {
			filter["x"] = loc->x + 1;
			filter["y"] = loc->y + 1;
		}

		if (object_filter) {
			(*object_filter)["x"] = loc->x + 1;
			(*object_filter)["y"] = loc->y + 1;
		}

		// If this is a side, place a castle for the side
		if (it.key == "side" && !it.cfg["no_castle"].to_bool()) {
			place_castle(it.cfg["side"].to_int(-1), *loc);
		}

		res_.add_child(it.key, cfg);

		if(!loc_var.empty()) {
			config &temp = res_.add_child("event");
			temp["name"] = "prestart";
			config &xcfg = temp.add_child("set_variable");
			xcfg["name"] = loc_var + "_x";
			xcfg["value"] = loc->x + 1;
			config &ycfg = temp.add_child("set_variable");
			ycfg["name"] = loc_var + "_y";
			ycfg["value"] = loc->y + 1;
		}
	}
}
Пример #4
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_);
	}
}
void setup() {
   set_room_size( 20 );
   set_terrain( "tutorial_mountain" );
   set_short( "tree in the mountains" );
   set_long( "This tree has defied all the odds, and grows straight and "
            "tall in the blustery wastes." );
   add_extra_look( this_object() );
   
   add_property( "climate", ({ -40, 50, 40 }) );
void setup() {
   set_terrain( "tutorial_mountain" );
   set_short( "mountain cabin attic" );
   set_long( "This is the second floor of a comfortable mountain cabin.  "
            "The bed occupying most of this room would seem to indicate "
            "that this is a bedroom.\n" );
   add_item( "bed", ({
      "long", "A big king-sized bed with a nice, thick, comforter on top.",
      "position", "the bed" }), 0 );
Пример #7
0
bool xmove::stick_on_ground()
{
	assert(m_agent->parent);
	xvec2f_t pos;
	wyc::xcollision_agent *collidee = _detect_stand_point(pos);
	if(!collidee)
		return false;
	m_agent->set_position(pos.x, pos.y);
	m_agent->update_aabb();
	set_terrain(collidee);
	return true;
}
void setup() {
   set_terrain( "tutorial_desert" );
   set_short( "desert oasis" );
   set_long( "The trees in this oasis provide welcome relief from the harsh "
            "sunlight of the desert.\n" );
   add_item( "sand", 
      "It's sand.  There isn't much to say about it other than "
      "that it's much moister here than elsewhere in the desert." );
   add_item( "tree", 
      "The palm trees grow majestically all around you, "
      "providing all the shade you could want." );
   
   add_property( "climate", ({ 10, -100, -100 }) );
void setup() {
   set_terrain( "tutorial_desert" );
   set_short( "outside tent" );
   set_long( "This is just outside the front flap of a canvas tent, set "
      "in the middle of a huge desert waste.  Nothing but sand as far "
      "as the eye can see.\n" );
   add_item( "sand", 
      "It's sand.  There isn't much to say about it." );
   add_item( "tent", 
      "This is a plain, white canvas tent, that reflects the harsh "
      "glare of the sun harmlessly away from its occupants." );
   
   add_exit( "tent", PATH "foyer", "corridor" );
   
   add_property( "climate", ({ 40, -100, -100 }) );
Пример #10
0
void gamemap::overlay(const gamemap& m, const config& rules_cfg, int xpos, int ypos, bool border)
{
	const config::const_child_itors &rules = rules_cfg.child_range("rule");
	int actual_border = (m.border_size() == border_size()) && border ? border_size() : 0;

	const int xstart = std::max<int>(-actual_border, -xpos - actual_border);
	const int ystart = std::max<int>(-actual_border, -ypos - actual_border - ((xpos & 1) ? 1 : 0));
	const int xend = std::min<int>(m.w() + actual_border, w() + actual_border - xpos);
	const int yend = std::min<int>(m.h() + actual_border, h() + actual_border - ypos);
	for(int x1 = xstart; x1 < xend; ++x1) {
		for(int y1 = ystart; y1 < yend; ++y1) {
			const int x2 = x1 + xpos;
			const int y2 = y1 + ypos +
				((xpos & 1) && (x1 & 1) ? 1 : 0);

			const t_translation::t_terrain t = m[x1][y1 + m.border_size_];
			const t_translation::t_terrain current = (*this)[x2][y2 + border_size_];

			if(t == t_translation::FOGGED || t == t_translation::VOID_TERRAIN) {
				continue;
			}

			// See if there is a matching rule
			config::const_child_iterator rule = rules.first;
			for( ; rule != rules.second; ++rule)
			{
				static const std::string src_key = "old", dst_key = "new";
				const config &cfg = *rule;
				const t_translation::t_list& src = t_translation::read_list(cfg[src_key]);

				if(!src.empty() && t_translation::terrain_matches(current, src) == false) {
					continue;
				}

				const t_translation::t_list& dst = t_translation::read_list(cfg[dst_key]);

				if(!dst.empty() && t_translation::terrain_matches(t, dst) == false) {
					continue;
				}

				break;
			}


			if (rule != rules.second)
			{
				const config &cfg = *rule;
				const t_translation::t_list& terrain = t_translation::read_list(cfg["terrain"]);

				terrain_type_data::tmerge_mode mode = terrain_type_data::BOTH;
				if (cfg["layer"] == "base") {
					mode = terrain_type_data::BASE;
				}
				else if (cfg["layer"] == "overlay") {
					mode = terrain_type_data::OVERLAY;
				}

				t_translation::t_terrain new_terrain = t;
				if(!terrain.empty()) {
					new_terrain = terrain[0];
				}

				if (!cfg["use_old"].to_bool()) {
					set_terrain(map_location(x2, y2), new_terrain, mode, cfg["replace_if_failed"].to_bool());
				}

			} else {
				set_terrain(map_location(x2,y2),t);
			}
		}
	}

	for(const map_location* pos = m.startingPositions_;
			pos != m.startingPositions_ + sizeof(m.startingPositions_)/sizeof(*m.startingPositions_);
			++pos) {

		if(pos->valid()) {
			startingPositions_[pos - m.startingPositions_] = *pos;
		}
	}
}
Пример #11
0
xcollision_agent* xmove::fall (float &t, xvec2f_t &speed, float accy, unsigned extra_filter, unsigned max_iteration)
{
	m_kpos.clear();
	if( m_terrain || speed.y>0 || (speed.y==0 && accy==0) ) {
		return 0;
	}
	float tfall, tleft = 0; 
	if(accy>0)
	{
		tfall = -speed.y / accy;
		if(tfall<t)
		{
			tleft = t-tfall;
			t = tfall;
		}
	}
	xvec2f_t pos = m_agent->get_position(), offset, collide_normal;
	float dt;
	xcollision_agent *collidee = 0;
	unsigned group_filter = ms_standon_filter | extra_filter;
	bool is_on_ground = false;
	for(unsigned iteration = 0; iteration<max_iteration; ++iteration)
	{
		offset.x = speed.x * t;
		offset.y = speed.y * t + 0.5f * accy * t * t;

		collidee = _detect_collision(offset,group_filter,dt,collide_normal,ms_platform_filter);
		if(collidee)
		{ // hit something
			offset.x *= dt;
			offset.y *= dt;
			pos += offset;
			tfall = solve_quadratic(0.5f*accy, speed.y, -offset.y);
			t -= tfall;
			speed.y += accy * tfall;
			if(collidee->get_mask() & ms_standon_filter)
			{ // hit terrain
				speed.x = 0;
				if(collide_normal.y < EPSILON)
				{
					pos.x += ms_drawback * collide_normal.x;
					pos.y += ms_drawback * collide_normal.y;
					m_agent->set_position(pos.x, pos.y);
					PUSH_KPOS_WITH_SPEED(m_kpos, tfall, pos.x, pos.y, speed.x, speed.y);
					continue;
				}
				// fall on ground
				pos.y += ms_drawback;
				speed.y= 0;
				is_on_ground = true;
			}
		}
		else 
		{
			speed.y += accy * t;
			pos += offset;
			tfall = t;
			t = 0;
		}
		m_agent->set_position(pos.x,pos.y);
		if(is_on_ground) 
			set_terrain(collidee);
		PUSH_KPOS_WITH_SPEED(m_kpos, tfall, pos.x, pos.y, speed.x, speed.y);
		break;
	} // for
	t += tleft;
	m_agent->update_aabb();
	return collidee;
}
Пример #12
0
xcollision_agent* xmove::walk (float &t, float speed, unsigned extra_filter, unsigned max_iteration)
{
	m_kpos.clear();
	if(!m_terrain || !speed) {
		// not on ground
		return 0;
	}
	char d, s;
	if(speed<0)
	{
		d = -1;
		s = -1;
	}
	else
	{
		d = 1;
		s = 0;
	}
	xvec2f_t kp = m_agent->get_position();
	float spdx, spdy;
	xcollision_agent *collidee = 0;
	unsigned group_filter = ms_standon_filter | extra_filter;
	for(unsigned iteration = 0; iteration<max_iteration; ++iteration)
	{
		const xvec2f_t &terrain_normal = m_terrain->get_slope_normal();
		if(m_apex>0 && m_cursec!=m_apex) // move on slope
		{
			spdx =  terrain_normal.y * speed;
			spdy = -terrain_normal.x * speed;
		}
		else 
		{
			spdx = speed;
			spdy = 0;
		}
		xvec2f_t offset;
		offset.set(m_inflections[m_cursec+s]-m_agent->get_position().x, 0);
		float tmove = offset.x/spdx;
		xvec2f_t collide_normal;
		float dt;
		if(tmove>0)
		{
			bool in_same_section = tmove>t;
			if(in_same_section)
			{
				tmove = t;
				offset.x = tmove * spdx;
			}
			offset.y = tmove * spdy;
			collidee = _detect_collision(offset, group_filter, dt, collide_normal);
			if(!collidee)
			{
				t -= tmove;
				kp.x += offset.x;
				kp.y += offset.y;
				m_agent->set_position(kp.x,kp.y);
				PUSH_KPOS_WALK(m_kpos, tmove, kp.x, kp.y);
				if(in_same_section) {
					break;
				}
			}
		}

		if(!collidee)
		{
			m_cursec += d;
			if(m_cursec == 0 || m_cursec == m_cntsec) // leave terrain 
			{
				collidee = _detect_stand_point(kp);
				if(collidee && m_agent->get_position().y-kp.y<=ms_stair_height)
				{
					m_agent->set_position(kp.x, kp.y);
					PUSH_KPOS_WALK(m_kpos, 0, kp.x, kp.y);
					set_terrain(collidee);
				}
				else // falling
				{
					m_terrain = 0;
					collidee = 0;
					break;
				}
			}
			collidee = 0;
			continue;
		}

		tmove *= dt;
		t -= tmove;
		offset *= dt;
		kp.x += offset.x;
		kp.y += offset.y;
		
		// collide special objects
		if(collidee->get_mask() & extra_filter)
		{
			m_agent->set_position(kp.x,kp.y);
			PUSH_KPOS_WALK(m_kpos, tmove, kp.x, kp.y);
			break;
		}

		// collide terrain
		if(collide_normal.x && collide_normal.y/std::fabs(collide_normal.x)<ms_slope_can_stand)
		{ // steep slope or stair
			float stair_y = collidee->get_upper().y;
			int type = collidee->agent_type();
			if(type==AGENT_SLOPE_LEFT_BOTTOM || type==AGENT_SLOPE_RIGHT_BOTTOM) {
				const xvec2f_t &collidee_normal = collidee->get_slope_normal();
				if((kp.x-collidee->get_position().x)*collidee_normal.x>0)
					stair_y = collidee->get_lower().y;
			}
			if(stair_y - (kp.y-m_agent->get_radius().y) > ms_stair_height)
			{
				kp.x -= ms_drawback*terrain_normal.y*d;
				kp.y += ms_drawback*terrain_normal.x*d;
				m_agent->set_position(kp.x,kp.y);
				PUSH_KPOS_WALK(m_kpos, tmove, kp.x, kp.y);
				break;
			}
			PUSH_KPOS_WALK(m_kpos, tmove, kp.x, kp.y);
			kp.x += ms_drawback*d;
			kp.y  = stair_y+m_agent->get_radius().y+ms_drawback;
		}
		else
		{
			PUSH_KPOS_WALK(m_kpos, tmove, kp.x, kp.y);
			kp.y += ms_drawback;
		}
		m_agent->set_position(kp.x,kp.y);
		PUSH_KPOS_WALK(m_kpos, 0, kp.x, kp.y);
		set_terrain(collidee);
		collidee = 0;
	} // for
	m_agent->update_aabb();
	return collidee;
}