示例#1
0
void debug_check_entity_solidity(const level& lvl, const entity& e)
{
	if(!e.allow_level_collisions() && entity_collides_with_level(lvl, e, MOVE_NONE, NULL)) {
		const solid_info* s = e.solid();
		ASSERT_LOG(s, "ENTITY COLLIDES BUT DOES NOT HAVE SOLID");
		const frame& f = e.current_frame();
		const rect& area = s->area();

		int min_x = INT_MIN, max_x = INT_MIN, min_y = INT_MIN, max_y = INT_MIN;
		std::set<point> solid_points;

		foreach(const const_solid_map_ptr& m, s->solid()) {
			const std::vector<point>& points = m->dir(MOVE_NONE);
			foreach(const point& p, points) {
				const int x = e.x() + (e.face_right() ? p.x : (f.width() - 1 - p.x));
				const int y = e.y() + p.y;

				if(min_x == INT_MIN || x < min_x) {
					min_x = x;
				}

				if(max_x == INT_MIN || x > max_x) {
					max_x = x;
				}

				if(min_y == INT_MIN || y < min_y) {
					min_y = y;
				}

				if(max_y == INT_MIN || y > max_y) {
					max_y = y;
				}

				solid_points.insert(point(x, y));
			}
		}

		std::cerr << "COLLIDING OBJECT MAP:\n";
		for(int y = min_y - 5; y < max_y + 5; ++y) {
			for(int x = min_x - 5; x < max_x + 5; ++x) {
				const bool lvl_solid = lvl.solid(x, y, NULL);
				const bool char_solid = solid_points.count(point(x, y));
				if(lvl_solid && char_solid) {
					std::cerr << "X";
				} else if(lvl_solid) {
					std::cerr << "L";
				} else if(char_solid) {
					std::cerr << "C";
				} else {
					std::cerr << "-";
				}
			}

			std::cerr << "\n";
		}
		std::cerr << "\n";

		ASSERT_LOG(false, "ENTITY " << e.debug_description() << " COLLIDES WITH LEVEL");
	}
}
示例#2
0
bool entity_collides_with_entity(const entity& e, const entity& other, collision_info* info)
{
	if((e.solid_dimensions()&other.weak_solid_dimensions()) == 0 &&
	   (e.weak_solid_dimensions()&other.solid_dimensions()) == 0) {
		return false;
	}

	const rect& our_rect = e.solid_rect();
	const rect& other_rect = other.solid_rect();

	if(!rects_intersect(our_rect, other_rect)) {
		return false;
	}

	if(other.destroyed()) {
		return false;
	}

	const rect area = intersection_rect(our_rect, other_rect);

	const solid_info* our_solid = e.solid();
	const solid_info* other_solid = other.solid();
	assert(our_solid && other_solid);

	const frame& our_frame = e.current_frame();
	const frame& other_frame = other.current_frame();

	for(int y = area.y(); y <= area.y2(); ++y) {
		for(int x = area.x(); x < area.x2(); ++x) {
			const int our_x = e.face_right() ? x - e.x() : (e.x() + our_frame.width()-1) - x;
			const int our_y = y - e.y();
			if(our_solid->solid_at(our_x, our_y, info ? &info->area_id : NULL)) {
				const int other_x = other.face_right() ? x - other.x() : (other.x() + other_frame.width()-1) - x;
				const int other_y = y - other.y();
				if(other_solid->solid_at(other_x, other_y, info ? &info->collide_with_area_id : NULL)) {
					return true;
				}
			}
		}
	}

	return false;
}
示例#3
0
bool entity_collides_with_level(const level& lvl, const entity& e, MOVE_DIRECTION dir, collision_info* info)
{
	const solid_info* s = e.solid();
	if(!s) {
		return false;
	}

	if(e.face_right() == false) {
		if(dir == MOVE_RIGHT) {
			dir = MOVE_LEFT;
		} else if(dir == MOVE_LEFT) {
			dir = MOVE_RIGHT;
		}
	}

	const frame& f = e.current_frame();

	const rect& area = s->area();
	if(e.face_right()) {
		rect solid_area(e.x() + area.x(), e.y() + area.y(), area.w(), area.h());
		if(!lvl.may_be_solid_in_rect(solid_area)) {
			return false;
		}
	} else {
		rect solid_area(e.x() + f.width() - area.x() - area.w(), e.y() + area.y(), area.w(), area.h());
		if(!lvl.may_be_solid_in_rect(solid_area)) {
			return false;
		}
	}

	foreach(const const_solid_map_ptr& m, s->solid()) {
		if(lvl.solid(e, m->dir(dir), info ? &info->surf_info : NULL)) {
			if(info) {
				info->read_surf_info();
			}

			return true;
		}
	}

	return false;
}
示例#4
0
bool non_solid_entity_collides_with_level(const level& lvl, const entity& e)
{
	const frame& f = e.current_frame();
	if(!lvl.may_be_solid_in_rect(rect(e.x(), e.y(), f.width(), f.height()))) {
		return false;
	}

	const int increment = e.face_right() ? 2 : -2;
	for(int y = 0; y < f.height(); y += 2) {
		std::vector<bool>::const_iterator i = f.get_alpha_itor(0, y, e.time_in_frame(), e.face_right());
		for(int x = 0; x < f.width(); x += 2) {
			if(i == f.get_alpha_buf().end() || i == f.get_alpha_buf().begin()) {
				continue;
			}
			if(!*i && lvl.solid(e.x() + x, e.y() + y)) {
				return true;
			}

			i += increment;
		}
	}

	return false;
}
示例#5
0
bool non_solid_entity_collides_with_level(const level& lvl, const entity& e)
{
	const frame& f = e.current_frame();
	if(!lvl.may_be_solid_in_rect(rect(e.x(), e.y(), f.width(), f.height()))) {
		return false;
	}

	for(int y = 0; y < f.height(); ++y) {
		for(int x = 0; x < f.width(); ++x) {
			if(!f.is_alpha(e.face_right() ? x : f.width() - x - 1, y, e.time_in_frame(), true)) {
				if(lvl.solid(e.x() + x, e.y() + y)) {
					return true;
				}
			}
		}
	}

	return false;
}
示例#6
0
int entity_collides_with_level_count(const level& lvl, const entity& e, MOVE_DIRECTION dir)
{
	const solid_info* s = e.solid();
	if(!s) {
		return 0;
	}

	const frame& f = e.current_frame();
	int count = 0;
	foreach(const const_solid_map_ptr& m, s->solid()) {
		const std::vector<point>& points = m->dir(dir);
		foreach(const point& p, points) {
			const int xpos = e.face_right() ? e.x() + p.x : e.x() + f.width() - 1 - p.x;
			if(lvl.solid(xpos, e.y() + p.y)) {
				++count;
			}
		}
	}

	return count;
}
示例#7
0
	void process(const entity& e) {
		particle_generation_ += generation_rate_millis_;

		particles_.erase(std::remove_if(particles_.begin(), particles_.end(), particle_destroyed), particles_.end());

		for(std::vector<particle>::iterator p = particles_.begin();
		    p != particles_.end(); ++p) {
			p->pos_x += p->velocity_x;
			p->pos_y += p->velocity_y;
			if(e.face_right()) {
				p->velocity_x += info_.accel_x/1000.0;
			} else {
				p->velocity_x -= info_.accel_x/1000.0;
			}
			p->velocity_y += info_.accel_y/1000.0;
			p->rgba[0] += info_.rgba_delta[0];
			p->rgba[1] += info_.rgba_delta[1];
			p->rgba[2] += info_.rgba_delta[2];
			p->rgba[3] += info_.rgba_delta[3];
			p->ttl--;
		}

		while(particle_generation_ >= 1000) {
			//std::cerr << "PARTICLE X ORIGIN: " << pos_x_;
			particles_.push_back(particle());
			particle& p = particles_.back();
			p.ttl = info_.time_to_live;
			if(info_.time_to_live_max != info_.time_to_live) {
				p.ttl += rand()%(info_.time_to_live_max - info_.time_to_live);
			}

			p.velocity_x = info_.velocity_x;
			p.velocity_y = info_.velocity_y;

			if(info_.velocity_x_rand) {
				p.velocity_x += rand()%info_.velocity_x_rand;
			}

			if(info_.velocity_y_rand) {
				p.velocity_y += rand()%info_.velocity_y_rand;
			}

			p.pos_x = e.x()*1024 + pos_x_;
			p.pos_y = e.y()*1024 + pos_y_;

			if(pos_x_rand_) {
				p.pos_x += rand()%pos_x_rand_;
			}
			
			if(pos_y_rand_) {
				p.pos_y += rand()%pos_y_rand_;
			}

			p.rgba[0] = info_.rgba[0];
			p.rgba[1] = info_.rgba[1];
			p.rgba[2] = info_.rgba[2];
			p.rgba[3] = info_.rgba[3];

			if(info_.rgba_rand[0]) {
				p.rgba[0] += rand()%info_.rgba_rand[0];
			}

			if(info_.rgba_rand[1]) {
				p.rgba[1] += rand()%info_.rgba_rand[1];
			}

			if(info_.rgba_rand[2]) {
				p.rgba[2] += rand()%info_.rgba_rand[2];
			}

			if(info_.rgba_rand[3]) {
				p.rgba[3] += rand()%info_.rgba_rand[3];
			}

			particle_generation_ -= 1000;
		}
	}