Example #1
0
double move_outside_object(int object, double angle, double max_dist, bool solid_only)
{
    enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst);
    if (inst1->sprite_index == -1 && (inst1->mask_index == -1)) {
        return -4;
    }

    double x = inst1->x, y = inst1->y;

    if (collide_inst_inst(object, solid_only, true, x, y) == NULL) {
        return 0;
    }

    const double DMIN = 1, DMAX = 1000; // Arbitrary max for non-positive values, 1000 fits with other implementations.
    const double contact_distance = DMIN;
    if (max_dist <= 0) { // Use the arbitrary max for non-positive values.
        max_dist = DMAX;
    }
    const double radang = (fmod(fmod(angle, 360) + 360, 360))*(M_PI/180.0);

    double current_dist;
    for (current_dist = DMIN; current_dist <= max_dist; current_dist++)
    {
        const double next_x = x + current_dist*cos(radang);
        const double next_y = y - current_dist*sin(radang);
        inst1->x = next_x;
        inst1->y = next_y;
        if (collide_inst_inst(object, solid_only, true, next_x, next_y) == NULL) {
            break;
        }
    }

    return current_dist;
}
Example #2
0
 object_basic *place_meeting_inst(double x, double y, int object)
 {
   return collide_inst_inst(object,false,true,x,y);
 }
Example #3
0
int instance_place(double x, double y, int object)
{
  enigma::object_collisions* const r = collide_inst_inst(object,false,true,x,y);
  return r == NULL ? noone : r->id;
}
Example #4
0
bool place_empty(double x,double y)
{
  return collide_inst_inst(all,false,true,x,y) == NULL;
}
Example #5
0
bool place_free(double x,double y)
{
  return collide_inst_inst(all,true,true,x,y) == NULL;
}
Example #6
0
bool move_bounce_object(int object, bool adv, bool solid_only)
{
    enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst);
    if (inst1->sprite_index == -1 && (inst1->mask_index == -1))
        return -4;

    if (collide_inst_inst(object, solid_only, true, inst1->x, inst1->y) == NULL &&
        collide_inst_inst(object, solid_only, true, inst1->x + inst1->hspeed, inst1->y + inst1->vspeed) == NULL) {
        return false;
    }

    if (collide_inst_inst(object, solid_only, true, inst1->x, inst1->y) != NULL) {
        // Return the instance to its previous position.
        inst1->x = inst1->xprevious;
        inst1->y = inst1->yprevious;
    }

    const double angle = inst1->direction, radang = angle*(M_PI/180.0), DBL_EPSILON = 0.00001;
    double sin_angle = sin(radang), cos_angle = cos(radang), pc_corner, pc_dist, max_dist = 1000000;
    int side_type = 0;
    const int quad = int(2*radang/M_PI);
    const bbox_rect_t &box = inst1->$bbox_relative();
    const double x1 = inst1->x, y1 = inst1->y,
                 xscale1 = inst1->image_xscale, yscale1 = inst1->image_yscale,
                 ia1 = inst1->image_angle;
    int left1, top1, right1, bottom1;

    get_border(&left1, &right1, &top1, &bottom1, box.left, box.top, box.right, box.bottom, x1, y1, xscale1, yscale1, ia1);

    for (enigma::iterator it = enigma::fetch_inst_iter_by_int(object); it; ++it)
    {
        const enigma::object_collisions* inst2 = (enigma::object_collisions*)*it;
        if (inst2->id == inst1->id || (solid_only && !inst2->solid))
            continue;
        if (inst2->sprite_index == -1 && (inst2->mask_index == -1))
            continue;
        const bbox_rect_t &box2 = inst2->$bbox_relative();
        const double x2 = inst2->x, y2 = inst2->y,
                     xscale2 = inst2->image_xscale, yscale2 = inst2->image_yscale,
                     ia2 = inst2->image_angle;
        int left2, top2, right2, bottom2;

        get_border(&left2, &right2, &top2, &bottom2, box2.left, box2.top, box2.right, box2.bottom, x2, y2, xscale2, yscale2, ia2);

        if (right2 >= left1 && bottom2 >= top1 && left2 <= right1 && top2 <= bottom1)
            return false;

        switch (quad)
        {
            case 0:
                if ((left2 > right1 || top1 > bottom2) &&
                direction_difference(point_direction(right1, bottom1, left2, top2),angle) >= 0  &&
                direction_difference(point_direction(left1, top1, right2, bottom2),angle) <= 0)
                {
                    pc_corner = direction_difference(point_direction(right1, top1, left2, bottom2),angle);
                    if (fabs(pc_corner) < DBL_EPSILON)
                    {
                        pc_dist = (left2 - right1)/cos_angle;
                        if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 4;
                        }
                    }
                    else if (pc_corner > 0)
                    {
                        pc_dist = (top1 - bottom2)/sin_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 2)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 1;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 1;
                        }
                    }
                    else
                    {
                        pc_dist = (left2 - right1)/cos_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 1)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 2;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 2;
                        }
                    }
                }
            break;
            case 1:
                if ((left1 > right2 || top1 > bottom2) &&
                direction_difference(point_direction(left1, bottom1, right2, top2),angle) <= 0  &&
                direction_difference(point_direction(right1, top1, left2, bottom2),angle) >= 0)
                {
                    pc_corner = direction_difference(point_direction(left1, top1, right2, bottom2),angle);

                    if (fabs(pc_corner) < DBL_EPSILON)
                    {
                        pc_dist = (left2 - right1)/cos_angle;
                        if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 4;
                        }
                    }
                    else if (pc_corner > 0)
                    {
                        pc_dist = (right2 - left1)/cos_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 1)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 2;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 2;
                        }
                    }
                    else
                    {
                        pc_dist = (top1 - bottom2)/sin_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 2)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 1;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 1;
                        }
                    }
                }
            break;
            case 2:
                if ((left1 > right2 || top2 > bottom1) &&
                direction_difference(point_direction(right1, bottom1, left2, top2),angle) <= 0  &&
                direction_difference(point_direction(left1, top1, right2, bottom2),angle) >= 0)
                {
                    pc_corner = direction_difference(point_direction(left1, bottom1, right2, top2),angle);
                    if (fabs(pc_corner) < DBL_EPSILON)
                    {
                        pc_dist = (right2 - left1)/cos_angle;
                        if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 4;
                        }
                    }
                    else if (pc_corner > 0)
                    {
                        pc_dist = (bottom1 - top2)/sin_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 2)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 1;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 1;
                        }
                    }
                    else
                    {
                        pc_dist = (right2 - left1)/cos_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 1)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 2;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 2;
                        }
                    }
                }
            break;
            case 3:
                if ((left2 > right1 || top2 > bottom1) &&
                direction_difference(point_direction(right1, top1, left2, bottom2),angle) <= 0  &&
                direction_difference(point_direction(left1, bottom1, right2, top2),angle) >= 0)
                {
                    pc_corner = direction_difference(point_direction(right1, bottom1, left2, top2),angle);
                    if (fabs(pc_corner) < DBL_EPSILON)
                    {
                        pc_dist = (bottom1 - top2)/sin_angle;
                        if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 4;
                        }
                    }
                    else if (pc_corner > 0)
                    {
                        pc_dist = (left2 - right1)/cos_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 1)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 2;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 2;
                        }
                    }
                    else
                    {
                        pc_dist = (bottom1 - top2)/sin_angle;
                        if (fabs(pc_dist - max_dist) < DBL_EPSILON)
                        {
                            if (side_type == 2)
                                side_type = 3;
                            else if (side_type != 3)
                                side_type = 1;
                        }
                        else if (pc_dist < max_dist)
                        {
                            max_dist = pc_dist;
                            side_type = 1;
                        }
                    }
                }
            break;
        }
    }

    switch (side_type)
    {
        case 0:  //no side hit
            return false;
        case 1:  //horizontal side hit
            inst1->vspeed *= -1;
        break;
        case 2:  //vertical side hit
            inst1->hspeed *= -1;
        break;
        case 3: case 4:  //corner or both horizontal and vertical side hit
            inst1->hspeed *= -1;
            inst1->vspeed *= -1;
        break;
    }
    return true;
}
Example #7
0
double move_outside_object(int object, double angle, double max_dist, bool solid_only)
{
    enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst);
    if (inst1->sprite_index == -1 && (inst1->mask_index == -1))
        return -4;
    const double DMIN = 0.000001, DMAX = 1000000;
    const double contact_distance = DMIN;
    if (max_dist <= 0)
    {
        max_dist = DMAX;
    }
    double dist = 0;
    angle = fmod(angle, 360.0);
    double radang = angle*(M_PI/180.0);
    const double sin_angle = sin(radang), cos_angle = cos(radang);
    const int quad = int(angle/90.0);
    const double    xscale1 = inst1->image_xscale, yscale1 = inst1->image_yscale,
                     ia1 = inst1->image_angle;

    const double x_start = inst1->x, y_start = inst1->y;

    bool had_collision = true;

    while (had_collision) // If there was no collision in the last iteration, we have moved outside the object.
    {
        had_collision = false;
        for (enigma::iterator it = enigma::fetch_inst_iter_by_int(object); it; ++it)
        {
            const bbox_rect_t &box = inst1->$bbox_relative();
            const double x1 = inst1->x, y1 = inst1->y;
            int left1, top1, right1, bottom1;

            get_border(&left1, &right1, &top1, &bottom1, box.left, box.top, box.right, box.bottom, x1, y1, xscale1, yscale1, ia1);

            const enigma::object_collisions* inst2 = (enigma::object_collisions*)*it;
            if (inst2->id == inst1->id || (solid_only && !inst2->solid))
                continue;
            if (inst2->sprite_index == -1 && (inst2->mask_index == -1))
                continue;
            const bbox_rect_t &box2 = inst2->$bbox_relative();
            const double x2 = inst2->x, y2 = inst2->y,
                         xscale2 = inst2->image_xscale, yscale2 = inst2->image_yscale,
                         ia2 = inst2->image_angle;
            int left2, top2, right2, bottom2;

            get_border(&left2, &right2, &top2, &bottom2, box2.left, box2.top, box2.right, box2.bottom, x2, y2, xscale2, yscale2, ia2);

            if (!(right2 >= left1 && bottom2 >= top1 && left2 <= right1 && top2 <= bottom1))
                continue;

            had_collision = true;

            // Move at least one step every time there is a collision.
            const double min_dist = dist + 1;

            switch (quad)
            {
                case 0:
                    if (direction_difference(point_direction(left1, bottom1, right2, top2),angle) < 0)
                    {
                        dist += ((bottom1) - (top2))/sin_angle;
                    }
                    else
                    {
                        dist += ((right2) - (left1))/cos_angle;
                    }
                break;
                case 1:
                    if (direction_difference(point_direction(right1, bottom1, left2, top2),angle) < 0)
                    {
                        dist += ((left2) - (right1))/cos_angle;
                    }
                    else
                    {
                        dist += ((bottom1) - (top2))/sin_angle;
                    }
                break;
                case 2:
                if (direction_difference(point_direction(right1, top1, left2, bottom2),angle) < 0)
                {
                    dist += ((top1) - (bottom2))/sin_angle;
                }
                else
                {
                    dist += ((left2) - (right1))/cos_angle;
                }
                break;
                case 3:
                    if (direction_difference(point_direction(left1, top1, right2, bottom2),angle) < 0)
                    {
                        dist += ((right2) - (left1))/cos_angle;
                    }
                    else
                    {
                        dist += ((top1) - (bottom2))/sin_angle;
                    }
                break;
            }
            dist = max(min(dist, max_dist), min_dist);
            inst1->x = x_start + cos_angle*dist;
            inst1->y = y_start - sin_angle*dist;

            for (int i = 0; i < 1; i++) // Move a single step on if the moving was not precise.
            {
                if (collide_inst_inst(inst2->id, solid_only, true, inst1->x, inst1->y) == NULL) {
                    break;
                }
                dist += 1;
                inst1->x = x_start + cos_angle*dist;
                inst1->y = y_start - sin_angle*dist;
            }
        }
    }

    return dist;
}
Example #8
0
bool move_bounce_object(int object, bool adv, bool solid_only)
{
    enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst);
    if (inst1->sprite_index == -1 && (inst1->mask_index == -1))
        return false;

    if (collide_inst_inst(object, solid_only, true, inst1->x, inst1->y) == NULL &&
        collide_inst_inst(object, solid_only, true, inst1->x + inst1->hspeed, inst1->y + inst1->vspeed) == NULL) {
        return false;
    }

    if (collide_inst_inst(object, solid_only, true, inst1->x, inst1->y) != NULL) {
        // Return the instance to its previous position.
        inst1->x = inst1->xprevious;
        inst1->y = inst1->yprevious;
    }

    const double x_start = inst1->x, y_start = inst1->y;

    const double x = inst1->x + inst1->hspeed, y = inst1->y + inst1->vspeed;

    if (adv) {
        const double angle_radial = 10.0; // The angle increment for the radials.
        const int radial_max = max(int(180/angle_radial), 1); // The maximum number of radials in one direction.

        const double effective_direction = inst1->speed >= 0 ? inst1->direction : fmod(inst1->direction+180.0, 360.0);
        const double flipped_direction = fmod(effective_direction + 180.0, 360.0);
        const double speed = abs(inst1->speed + 1);//max(1, abs(inst1->speed));

        // Find the normal direction of the collision by doing radial collisions based on the speed and flipped direction.

        int d1, d2;
        for (d1 = 0; d1 < radial_max; d1++) // Positive direction.
        {
            const double rad = (flipped_direction + d1*angle_radial)*M_PI/180.0;
            const double x1 = x + speed*cos(rad);
            const double y1 = y - speed*sin(rad);
            if (collide_inst_inst(object, solid_only, true, x1, y1) != NULL) {
                break;
            }
        }
        for (d2 = 0; d2 > -radial_max; d2--) // Negative direction.
        {
            const double rad = (flipped_direction + d2*angle_radial)*M_PI/180.0;
            const double x1 = x + speed*cos(rad);
            const double y1 = y - speed*sin(rad);
            if (collide_inst_inst(object, solid_only, true, x1, y1) != NULL) {
                break;
            }
        }

        const int d = int(round((d1 + d2)/2.0));
        const double normal_direction = fmod(flipped_direction + d*angle_radial + 360.0, 360.0);

        // Flip and then mirror the effective direction unit vector along the direction of the normal.

        const double normal_rad = normal_direction * M_PI / 180.0;
        const double normal_x = cos(normal_rad), normal_y = -sin(normal_rad);

        const double flipped_rad = flipped_direction * M_PI / 180.0;
        const double flipped_x = cos(flipped_rad), flipped_y = -sin(flipped_rad);

        const double dot_product = normal_x*flipped_x + normal_y*flipped_y;
        const double flipped_on_normal_x = dot_product*normal_x, flipped_on_normal_y = dot_product*normal_y;

        const double crossed_x = flipped_x - flipped_on_normal_x, crossed_y = flipped_y - flipped_on_normal_y;
        
        const double mirror_x = flipped_x - 2*crossed_x, mirror_y = flipped_y - 2*crossed_y;

        // Set final direction from flipped, mirrored direction unit vector.

        const double mirror_direction = fmod(atan2(-mirror_y, mirror_x) * 180.0 / M_PI + 360.0, 360.0);
        inst1->direction = inst1->speed >= 0 ? mirror_direction : fmod(mirror_direction + 180.0, 360.0);
        return true;
    }
    else {
        const double direction = inst1->speed >= 0 ? inst1->direction : fmod(inst1->direction+180.0, 360.0);
        const bool free_horizontal = collide_inst_inst(object, solid_only, true, x, y_start) == NULL;
        const bool free_vertical = collide_inst_inst(object, solid_only, true, x_start, y) == NULL;
        double new_direction;
        if (!free_horizontal && free_vertical) {
            new_direction = direction <= 180.0 ? fmod(180.0 - direction, 360.0) : fmod((360.0 - direction) + 180.0, 360.0);
        }
        else if (free_horizontal && !free_vertical) {
            new_direction = fmod(360.0 - direction, 360.0);
        }
        else {
            new_direction = fmod(direction + 180.0, 360.0);
        }
        inst1->direction = inst1->speed >= 0 ? new_direction : fmod(new_direction + 180.0, 360.0);

        return true;
    }
}
Example #9
0
double move_contact_object(int object, double angle, double max_dist, bool solid_only)
{
    enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst);
    if (inst1->sprite_index == -1 && (inst1->mask_index == -1)) {
        return -4;
    }

    const double x = inst1->x, y = inst1->y;

    if (collide_inst_inst(object, solid_only, true, x, y) != NULL) {
        return 0;
    }

    const double DMIN = 1, DMAX = 1000; // Arbitrary max for non-positive values, 1000 fits with other implementations.
    const double contact_distance = DMIN;
    double mid_dist = max_dist; // mid_dist is used for the subtraction part.
    if (max_dist <= 0) { // Use the arbitrary max for non-positive values.
        max_dist = DMAX;
    }
    mid_dist = max_dist;
    const double radang = (fmod(fmod(angle, 360) + 360, 360))*(M_PI/180.0);
    const double sin_angle = sin(radang), cos_angle = cos(radang);

    // Subtraction.

    const int quad = int(angle/90.0);

    const bbox_rect_t &box = inst1->$bbox_relative();
    const double x1 = inst1->x, y1 = inst1->y,
                 xscale1 = inst1->image_xscale, yscale1 = inst1->image_yscale,
                 ia1 = inst1->image_angle;
    int left1, top1, right1, bottom1;

    get_border(&left1, &right1, &top1, &bottom1, box.left, box.top, box.right, box.bottom, x1, y1, xscale1, yscale1, ia1);

    for (enigma::iterator it = enigma::fetch_inst_iter_by_int(object); it; ++it)
    {
        const enigma::object_collisions* inst2 = (enigma::object_collisions*)*it;
        if (inst2->sprite_index == -1 && (inst2->mask_index == -1))
            continue;
        if (inst2->id == inst1->id || (solid_only && !inst2->solid))
            continue;
        const bbox_rect_t &box2 = inst2->$bbox_relative();
        const double x2 = inst2->x, y2 = inst2->y,
                     xscale2 = inst2->image_xscale, yscale2 = inst2->image_yscale,
                     ia2 = inst2->image_angle;
        int left2, top2, right2, bottom2;

        get_border(&left2, &right2, &top2, &bottom2, box2.left, box2.top, box2.right, box2.bottom, x2, y2, xscale2, yscale2, ia2);

        if (right2 >= left1 && bottom2 >= top1 && left2 <= right1 && top2 <= bottom1)
        {
            mid_dist = DMIN;
            break;
        }

        switch (quad)
        {
            case 0:
                if ((left2 > right1 || top1 > bottom2) &&
                direction_difference(point_direction(right1, bottom1, left2, top2),angle) >= 0  &&
                direction_difference(point_direction(left1, top1, right2, bottom2),angle) <= 0)
                {
                    if (direction_difference(point_direction(right1, top1, left2, bottom2),angle) > 0)
                    {
                        mid_dist = min(mid_dist, (top1 - bottom2 - contact_distance)/sin_angle);
                    }
                    else
                    {
                        mid_dist = min(mid_dist, (left2 - right1 - contact_distance)/cos_angle);
                    }
                }
            break;
            case 1:
                if ((left1 > right2 || top1 > bottom2) &&
                direction_difference(point_direction(left1, bottom1, right2, top2),angle) <= 0  &&
                direction_difference(point_direction(right1, top1, left2, bottom2),angle) >= 0)
                {
                    if (direction_difference(point_direction(left1, top1, right2, bottom2),angle) > 0)
                    {
                        mid_dist = min(mid_dist, (right2 - left1 + contact_distance)/cos_angle);
                    }
                    else
                    {
                        mid_dist = min(mid_dist, (top1 - bottom2 - contact_distance)/sin_angle);
                    }
                }
            break;
            case 2:
                if ((left1 > right2 || top2 > bottom1) &&
                direction_difference(point_direction(right1, bottom1, left2, top2),angle) <= 0  &&
                direction_difference(point_direction(left1, top1, right2, bottom2),angle) >= 0)
                {
                    if (direction_difference(point_direction(left1, bottom1, right2, top2),angle) > 0)
                    {
                        mid_dist = min(mid_dist, (bottom1 - top2 + contact_distance)/sin_angle);
                    }
                    else
                    {
                        mid_dist = min(mid_dist, (right2 - left1 + contact_distance)/cos_angle);
                    }
                }
            break;
            case 3:
                if ((left2 > right1 || top2 > bottom1) &&
                direction_difference(point_direction(right1, top1, left2, bottom2),angle) <= 0  &&
                direction_difference(point_direction(left1, bottom1, right2, top2),angle) >= 0)
                {
                    if (direction_difference(point_direction(right1, bottom1, left2, top2),angle) > 0)
                    {
                        mid_dist = min(mid_dist, (left2 - right1 - contact_distance)/cos_angle);
                    }
                    else
                    {
                        mid_dist = min(mid_dist, (bottom1 - top2 + contact_distance)/sin_angle);
                    }
                }
            break;
        }
    }

    double current_dist = DMIN;
    {
        // Avoid moving to position which isn't free. mid_dist is not guaranteed to indicate a free position.
        double next_x = x + mid_dist*cos_angle;
        double next_y = y - mid_dist*sin_angle;
        if (collide_inst_inst(object, solid_only, true, next_x, next_y) == NULL) {
            inst1->x = next_x;
            inst1->y = next_y;
            current_dist = mid_dist;
        }
    }

    // Subtraction end.

    for (; current_dist <= max_dist; current_dist++)
    {
        const double next_x = x + current_dist*cos_angle;
        const double next_y = y - current_dist*sin_angle;
        if (collide_inst_inst(object, solid_only, true, next_x, next_y) != NULL) {
            current_dist--;
            break;
        }
        else {
            inst1->x = next_x;
            inst1->y = next_y;
        }
    }

    return current_dist;
}
 object_basic *place_meeting_inst(cs_scalar x, cs_scalar y, int object)
 {
   return collide_inst_inst(object,false,true,x,y);
 }
bool place_empty(cs_scalar x, cs_scalar y)
{
  return collide_inst_inst(all,false,true,x,y) == NULL;
}
bool place_free(cs_scalar x, cs_scalar y)
{
  return collide_inst_inst(all,true,true,x,y) == NULL;
}