#apply
#include "../_include.txt"
#include "../../define/_vector2.txt"
#include "../../define/_const_pinball.txt"

/*
@param
レイヤー
転がり係数
反射係数
加速係数
基準となるイベント番号
形状(円形,線分,線分+端)
半径
始点x/中心点x
始点y/中心点y
終点x
終点y

@return
玉のID
反射の勢い
*/
cev[CEV_PB_UPDATE_BUMPER] .name(">>バンパーを更新する") {
    defv {
        r_id = TV_RETURN
        r_dot

        a_layer = TV_PB_UPDATE_BUMPER
        a_fri
        a_ref
        a_pow
        a_event
        a_sharp
        a_rad
        a_sx
        a_sy
        a_ex
        a_ey

        ptr
        idx
        rad
        time
        hitId
        hitDot
        ax
        ay
        bx
        by
        cx
        cy
        nx
        ny
        wx
        wy//25
    }
    
    def {
        BUMPER_RANDOM = UNIT_POS * 5 / 100
    }

    //返り値を初期化
    r_id = -1
    r_dot = 0

    //玉がロックされていると判定しない
    @if `eventMode && hitStopTimer > 0 bl {
        @ev.abort
    }

    //位置
    @if a_event > 0 bl {
        V2_setEventCenter(ax, a_event)
        V2_asAdd(a_sx, ax)
        V2_asAdd(a_ex, ax)
    }

    //簡易判定
    //円形
    @if a_sharp == SHARP_CIRCLE bl {
        V2_set(ax,
            (a_sx - a_rad) / MAPTILE_SIZE,
            (a_sy - a_rad) / MAPTILE_SIZE
        )
        V2_set(bx,
            (a_sx + a_rad) / MAPTILE_SIZE,
            (a_sy + a_rad) / MAPTILE_SIZE
        )
        V2_ifRectOverlap(ax, bx, ballAreaMinX, ballAreaMaxX, 0, EMPTY_BLOCK, ABORT_BLOCK)
    //線分
    } .elif `a_sharp == SHARP_SEGMENT_ONLY || a_sharp == SHARP_SEGMENT bl {
        rad = a_rad / MAPTILE_SIZE + 1
        V2_divScalar(ax, a_sx, MAPTILE_SIZE)
        V2_divScalar(bx, a_ex, MAPTILE_SIZE)
        V2_ifRectOverlap_ex(ax, bx, ballAreaMinX, ballAreaMaxX, rad, EMPTY_BLOCK, ABORT_BLOCK)
    //例外
    } .else bl {
        @ev.abort
    }

    //ループ用返り値
    hitId = -1
    hitDot = 0

    //半径
    rad = a_rad * UNIT_POS
    V2_mulScalar(ax, a_sx, UNIT_POS)
    V2_mulScalar(bx, a_ex, UNIT_POS)
    
    @loop MAX_BALL .dst(idx) bl {
        getBallPtr(ptr, idx)
        //状態
        @if `v[ptr + MB_STATE] != BA_ST_ENABLE bl {
            @continue
        }
        //レイヤー
        @if `v[ptr + MB_LAYER] != a_layer bl {
            @continue
        }
        time = -1
        //円形
        @if a_sharp == SHARP_CIRCLE bl {
            circleToCircle(time, cx, cy, unusedV, unusedV, nx, ny, unusedV, unusedV,
            v[ptr + MB_X], v[ptr + MB_Y], v[ptr + MB_NX], v[ptr + MB_NY], BA_RADxUNIT, BA_MASS,
            ax, ay, ax, ay, rad, BA_MASS
            )
        //線分
        } .elif `a_sharp == SHARP_SEGMENT_ONLY || a_sharp == SHARP_SEGMENT bl {
            circleToSegment(time, cx, cy, nx, ny, unusedV, unusedV,
            v[ptr + MB_X], v[ptr + MB_Y], v[ptr + MB_NX], v[ptr + MB_NY], BA_RADxUNIT,
            ax, ay, bx, by, rad
            )
            //線分の端とも判定を行う
            @if a_sharp == SHARP_SEGMENT bl {
                @if time < 0 bl {
                    circleToCircle(time, cx, cy, unusedV, unusedV, nx, ny, unusedV, unusedV,
                    v[ptr + MB_X], v[ptr + MB_Y], v[ptr + MB_NX], v[ptr + MB_NY], BA_RADxUNIT, BA_MASS,
                    ax, ay, ax, ay, rad, BA_MASS
                    )
                }
                @if time < 0 bl {
                    circleToCircle(time, cx, cy, unusedV, unusedV, nx, ny, unusedV, unusedV,
                    v[ptr + MB_X], v[ptr + MB_Y], v[ptr + MB_NX], v[ptr + MB_NY], BA_RADxUNIT, BA_MASS,
                    bx, by, bx, by, rad, BA_MASS
                    )
                }
            }
        }

        @if time >= 0 bl {
            //射出速度
            V2_muldiv(wx, nx, a_pow, UNIT_NORMAL)
            //乱数を足す
            wx += rnd(-BUMPER_RANDOM, BUMPER_RANDOM)
            wy += rnd(-BUMPER_RANDOM, BUMPER_RANDOM)
            //反射
            pbBallReflection(hitDot,
            idx, time, cx, cy, nx, ny, wx, wy, a_fri, a_ref)
            //衝突した玉のID
            hitId = idx
        }
    }
    //返り値を代入
    r_id = hitId
    r_dot = hitDot
}