void instance_activate_circle(int x, int y, int r, int inside) { std::map<int,enigma::inst_iter*>::iterator iter = enigma::instance_deactivated_list.begin(); while (iter != enigma::instance_deactivated_list.end()) { enigma::object_collisions* const inst = ((enigma::object_collisions*)(iter->second->inst)); if (inst->sprite_index == -1 && (inst->mask_index == -1)) { //no sprite/mask then no collision ++iter; continue; } const bbox_rect_t &box = inst->$bbox_relative(); const double x1 = inst->x, y1 = inst->y, xscale = inst->image_xscale, yscale = inst->image_yscale, ia = inst->image_angle; int left, top, right, bottom; get_border(&left, &right, &top, &bottom, box.left, box.top, box.right, box.bottom, x1, y1, xscale, yscale, ia); const bool intersects = line_ellipse_intersects(r, r, left-x, top-y, bottom-y) || line_ellipse_intersects(r, r, right-x, top-y, bottom-y) || line_ellipse_intersects(r, r, top-y, left-x, right-x) || line_ellipse_intersects(r, r, bottom-y, left-x, right-x) || (x >= left && x <= right && y >= top && y <= bottom); // Circle inside bbox. bool removed = false; if (intersects) { if (inside) { inst->activate(); enigma::instance_deactivated_list.erase(iter++); removed = true; } } else { if (!inside) { inst->activate(); enigma::instance_deactivated_list.erase(iter++); removed = true; } } if (!removed) { ++iter; } } }
void instance_deactivate_circle(int x, int y, int r, int inside, bool notme) { for (enigma::iterator it = enigma::instance_list_first(); it; ++it) { if (notme && (*it)->id == enigma::instance_event_iterator->inst->id) continue; enigma::object_collisions* const inst = ((enigma::object_collisions*)*it); if (inst->sprite_index == -1 && (inst->mask_index == -1)) //no sprite/mask then no collision continue; const bbox_rect_t &box = inst->$bbox_relative(); const double x1 = inst->x, y1 = inst->y, xscale = inst->image_xscale, yscale = inst->image_yscale, ia = inst->image_angle; int left, top, right, bottom; get_border(&left, &right, &top, &bottom, box.left, box.top, box.right, box.bottom, x1, y1, xscale, yscale, ia); const bool intersects = line_ellipse_intersects(r, r, left-x, top-y, bottom-y) || line_ellipse_intersects(r, r, right-x, top-y, bottom-y) || line_ellipse_intersects(r, r, top-y, left-x, right-x) || line_ellipse_intersects(r, r, bottom-y, left-x, right-x) || (x >= left && x <= right && y >= top && y <= bottom); // Circle inside bbox. if (intersects) { if (inside) { inst->deactivate(); enigma::instance_deactivated_list.insert(inode_pair((*it)->id,it.it)); } } else { if (!inside) { inst->deactivate(); enigma::instance_deactivated_list.insert(inode_pair((*it)->id,it.it)); } } } }
enigma::object_collisions* const collide_inst_ellipse(int object, bool solid_only, bool prec, bool notme, int x1, int y1, double rx, double ry) { if (rx == 0 || ry == 0) return 0; for (enigma::iterator it = enigma::fetch_inst_iter_by_int(object); it; ++it) { enigma::object_collisions* const inst = (enigma::object_collisions*)*it; if (notme && inst->id == enigma::instance_event_iterator->inst->id) continue; if (solid_only && !inst->solid) continue; if (inst->sprite_index == -1 && inst->mask_index == -1) // No sprite/mask then no collision. continue; const bbox_rect_t &box = inst->$bbox_relative(); const double x = inst->x, y = inst->y, xscale = inst->image_xscale, yscale = inst->image_yscale, ia = inst->image_angle; int left, top, right, bottom; get_border(&left, &right, &top, &bottom, box.left, box.top, box.right, box.bottom, x, y, xscale, yscale, ia); const bool intersects = line_ellipse_intersects(rx, ry, left-x1, top-y1, bottom-y1) || line_ellipse_intersects(rx, ry, right-x1, top-y1, bottom-y1) || line_ellipse_intersects(ry, rx, top-y1, left-x1, right-x1) || line_ellipse_intersects(ry, rx, bottom-y1, left-x1, right-x1) || (x1 >= left && x1 <= right && y1 >= top && y1 <= bottom); // Ellipse inside bbox. if (intersects) { if (!prec) { return inst; } const int collsprite_index = inst->mask_index != -1 ? inst->mask_index : inst->sprite_index; enigma::sprite* sprite = enigma::spritestructarray[collsprite_index]; const int usi = ((int) inst->image_index) % sprite->subcount; unsigned char* pixels = (unsigned char*) (sprite->colldata[usi]); if (pixels == 0) { // Bounding Box. return inst; } else { // Precise. // Intersection. const int ins_left = max(left, (int)(x1-rx)); const int ins_right = min(right, (int)(x1+rx)); const int ins_top = max(top, (int)(y1-ry)); const int ins_bottom = min(bottom, (int)(y1+ry)); // Check per pixel. const int w = sprite->width; const int h = sprite->height; const double xoffset = sprite->xoffset; const double yoffset = sprite->yoffset; const bool coll_result = precise_collision_ellipse( ins_left, ins_right, ins_top, ins_bottom, x, y, xscale, yscale, ia, pixels, w, h, xoffset, yoffset, x1, y1, rx, ry ); if (coll_result) { return inst; } } } } return NULL; }