int instance_position(double x, double y, int object) { const enigma::object_collisions* r = collide_inst_point(object,false,true,x+.5,y+.5); return r == NULL ? noone : r->id; }
int collision_point(double x, double y, int obj, bool prec /*ignored*/, bool notme) { const enigma::object_collisions* r = collide_inst_point(obj,false,notme,x+.5,y+.5); //false is for solid_only, not prec return r == NULL ? noone : r->id; }
bool position_empty(double x, double y) { return collide_inst_point(all,false,true,x+.5,y+.5) == NULL; }
bool position_meeting(double x, double y, int object) { return collide_inst_point(object,false,true,x+.5,y+.5); }
bool position_free(double x,double y) { return collide_inst_point(all,true,true,x+.5,y+.5) == NULL; }
int collision_point(double x, double y, int obj, bool prec, bool notme) { const enigma::object_collisions* r = collide_inst_point(obj,false, prec,notme,x+.5,y+.5); return r == NULL ? noone : r->id; }
bool position_meeting(cs_scalar x, cs_scalar y, int object) { return collide_inst_point(object,false,true,false,x+.5,y+.5); }
bool position_empty(cs_scalar x, cs_scalar y) { return collide_inst_point(all,false,true,false,x+.5,y+.5) == NULL; }
enigma::object_collisions* const collide_inst_line(int object, bool solid_only, bool prec, bool notme, int x1, int y1, int x2, int y2) { // Ensure x1 != x2 || y1 != y2. if (x1 == x2 && y1 == y2) return collide_inst_point(object, solid_only, prec, notme, x1, y1); 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); double minX = max(min(x1,x2),left); double maxX = min(max(x1,x2),right); if (minX > maxX) continue; // Find corresponding min and max Y for min and max X we found before. double minY = y1; double maxY = y2; double dx = x2 - x1; // Do slope check of non vertical lines (dx != 0). if ((float)dx) { double a = (y2 - y1) / dx; double b = y1 - a * x1; minY = a * minX + b; maxY = a * maxX + b; } if (minY > maxY) // Swap. { double tmp = maxY; maxY = minY; minY = tmp; } // Find the intersection of the segment's and rectangle's y-projections. if (maxY > bottom) maxY = bottom; if (minY < top) minY = top; if (minY <= maxY) { // If Y-projections do not intersect then no collision. // At this point, the line segment intersects the bounding box. if (!prec) { return inst; } else { 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 == NULL) { // Bounding box. return inst; } else { // Precise. // Intersection. int ins_left = max(left, min(x1, x2)); int ins_right = min(right, max(x1, x2)); int ins_top = max(top, min(y1, y2)); int ins_bottom = min(bottom, max(y1, y2)); // Check per pixel. const int w = sprite->width; const int h = sprite->height; const double xoffset = sprite->xoffset; const double yoffset = sprite->yoffset; // x1 != x2 || y1 != y2 is true here. const bool coll_result = precise_collision_line( ins_left, ins_right, ins_top, ins_bottom, x, y, xscale, yscale, ia, pixels, w, h, xoffset, yoffset, x1, y1, x2, y2 ); if (coll_result) { return inst; } } } } } return NULL; }