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"); } }
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; }
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; }
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; }
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; }
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; }
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; } }