bool BasicAbstractGame::sub_step()

in procgen/src/basic-abstract-game.cpp [270:372]


bool BasicAbstractGame::sub_step(const std::shared_ptr<Entity> &obj, float _vx, float _vy, int depth) {
    if (obj->will_erase)
        return false;

    float ny = obj->y + _vy;
    float nx = obj->x + _vx;

    float margin = 0.98f;

    bool is_horizontal = _vx != 0;

    bool block = false;
    bool reflect = false;

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            int type2 = get_obj_from_floats(nx + obj->rx * margin * (2 * i - 1), ny + obj->ry * margin * (2 * j - 1));
            block = block || is_blocked(obj, type2, is_horizontal);
            reflect = reflect || will_reflect(obj->type, type2);
        }
    }

    if (reflect) {
        if (is_horizontal) {
            float delta;

            if (_vx < 0) {
                delta = ceil(nx - obj->rx) - (nx - obj->rx);
            } else {
                delta = floor(nx + obj->rx) - (nx + obj->rx);
            }

            obj->vx = -1 * obj->vx;
            nx = nx + 2 * delta;
        } else {
            float delta;

            if (_vy < 0) {
                delta = ceil(ny - obj->ry) - (ny - obj->ry);
            } else {
                delta = floor(ny + obj->ry) - (ny + obj->ry);
            }

            obj->vy = -1 * obj->vy;
            ny = ny + 2 * delta;
        }
    } else if (block) {
        if (is_horizontal) {
            if (grid_step) {
                nx = obj->x;
            } else {
                nx = _vx > 0 ? (floor(nx + obj->rx) - obj->rx) : (ceil(nx - obj->rx) + obj->rx);
            }
        } else {
            if (grid_step) {
                ny = obj->y;
            } else {
                ny = _vy > 0 ? (floor(ny + obj->ry) - obj->ry) : (ceil(ny - obj->ry) + obj->ry);
            }
        }
    }

    obj->x = nx;
    obj->y = ny;

    bool block2 = false;

    for (int i = (int)(entities.size()) - 1; i >= 0; i--) {
        auto m = entities[i];

        if (m == obj || m->will_erase) {
            continue;
        }

        bool curr_block = false;

        if (has_collision(obj, m, POS_EPS)) {
            if (is_blocked_ents(obj, m, is_horizontal)) {
                curr_block = true;
            } else if (will_reflect(obj->type, m->type)) {
                if (is_horizontal) {
                    float delx = m->x - obj->x;
                    float rsum = m->rx + obj->rx;
                    obj->x += _vx > 0 ? -2 * (rsum - delx) : 2 * (rsum + delx);
                    obj->vx = -1 * obj->vx;
                } else {
                    float dely = m->y - obj->y;
                    float rsum = m->ry + obj->ry;
                    obj->y += _vy > 0 ? -2 * (rsum - dely) : 2 * (rsum + dely);
                    obj->vy = -1 * obj->vy;
                }
            }

            if (curr_block) {
                push_obj(m, obj, is_horizontal, depth);
            }
        }

        block2 = block2 || curr_block;
    }

    return block || block2;
}