//----------------
//玉の出現位置
//説明文の表示も行う
mev[MEV_SUPPLYBALL] .name("玉の出現位置") .pos(PLUNGER_MAP_X, PLUNGER_MAP_Y-3)
mep[1] .parallel bl {
    //簡易判定
    @if `!ROUGHLY_CHECK_BALL_PLUNGER bl {
        @ev.abort
    }

    pbBallToArea(temA, unusedV,
    GIM_LAYER_MID, self.id, SHARP_RECT, 0, 0, -8, -8, 8, 32)
    @if temA >= 0 bl {
        //操作説明
        pseudoSwitchState(pbControllMode,
        [   CTRL_TYPE_A, bl {
                strLine.asg(CTRL_DESC_A)
            },
            CTRL_TYPE_B, bl {
                strLine.asg(CTRL_DESC_B)
            },
            CTRL_TYPE_C, bl {
                strLine.asg(CTRL_DESC_C)
            }
        ],
        bl {
            strLine.asg("error")
        } )

        //ピクチャを設置する
        @pic.show [PIC_DESC_BG] .pos(DESC_X + 320, DESC_Y) .topLeft dpHoriBgPicCmd
        @pic.move[PIC_DESC_BG] .relative .pos(-352, 0) .scale(0) .trans(0) .time(2) .keepBlend
        @pic.strpic [PIC_DESC] strLine .pos(DESC_X + 320, DESC_Y + 1) .topLeft dpStrPicCmd

        //玉が範囲外に出るまで待つ
        descScrollX = 320
        @loop bl {
            @wait(0)
            pbBallToArea(temA, unusedV,
            GIM_LAYER_MID, self.id, SHARP_RECT, 0, 0, -8, -8, 8, 32)
            @if temA < 0 bl {
                @break
            }
            //スクロール
            descScrollX -= 1
            @if descScrollX < -DESC_LEN bl {
                descScrollX = 320
            }
            //ピクチャ移動
            temA = DESC_X + descScrollX
            temB = DESC_Y + 2
            @pic.move[PIC_DESC] .pos(temA, temB) .topLeft .keepBlend
        }

        //ピクチャをどかす
        @pic.move[PIC_DESC_BG] .relative .pos(0, 20) .scale(0) .trans(100) .time(2) .keepBlend
        @pic.move[PIC_DESC] .relative .pos(0, 20) .scale(0) .trans(100) .time(2) .keepBlend
        @wait(2)
    }
}

//--------------------------------
//プランジャー
def {
    PLUNGER_MAP_X = 18
    PLUNGER_MAP_Y = 25
    PLUNGER_STEP = 16//速度1/4のフレーム数
    PLUNGER_MAX_STEP = 3
    PLUNGER_MAX_POW  = 16 * PLUNGER_MAX_STEP
    PLUNGER_MAX_VEL  = 10 * UNIT_POS
}
mev[MEV_PLUNGER] .name("プランジャー") .pos(PLUNGER_MAP_X, PLUNGER_MAP_Y)
mep[1] .body(CHARSET_FRAME, 0) .dir.up .anim.fixDir .priority.high .parallel bl {
    //入力されるまで待つ
    @if plungerInput == FALSE bl {
        @ev.abort
    }
    //イベント中は無効化
    @if `eventMode bl {
        @ev.abort
    }

    //速度を指定する
    @ev.setAction .self .freq(8) .skippable .act {
        .beginThrough
    }
    @ev.addAction .speed(SPEED_ACT_HALF)
    @wait(0)
    //力を貯める
    plungerPower = 0
    @while plungerInput > 0 bl {
        @if plungerPower < PLUNGER_MAX_POW bl {
            plungerPower += 1
            //最大まで貯めると音が鳴り、離すまで待つ
            @if plungerPower >= PLUNGER_MAX_POW bl {
                @ev.flash .self .rgbv(31, 31, 31, 31) .time(5)
                @se.play "Buff" .opt(100, 100, 50)
            } .elif `plungerPower <= 1 || plungerPower % PLUNGER_STEP == 0 bl {
                //少しずつ後ろに下がる
                @ev.setAction .self .freq(8) .skippable .act {
                    .moveDown
                }
            }
        }
        //ループ内で待機
        @wait(0)
    }

    //あまり溜まっていない場合は、何もしない
    @if plungerPower < PLUNGER_STEP bl {
        //動いていないはずだが、念のために元の位置に戻す
        @ev.setPos .self .pos(PLUNGER_MAP_X, PLUNGER_MAP_Y) .retain
    //戻る
    } .else bl {
        //歩数
        temA = min(plungerPower / PLUNGER_STEP, PLUNGER_MAX_STEP)

        resetEventPosition(0)
        @ev.setAction .self .freq(8) .skippable .act {
            .faceRight
        }
        @ev.addAction .speed(SPEED_ACT_QUADRUPLE)
        @ev.addAction .moveUp(temA)
        @se.play "voice_soiya" .opt(100, 100, 50)

        //動作が終わるまで待つ
        temB = temA * 2 - 1//速度4のフレーム数 * 移動マス数 - 1
        @wait .frame(temB)

        //元の状態に戻す
        @ev.setPos .self .pos(PLUNGER_MAP_X, PLUNGER_MAP_Y) .retain
        @ev.setAction .self .freq(8) .skippable .act {
            .faceUp
        }
        @ev.addAction .speed(SPEED_ACT_HALF)

        //衝突判定
        pbBallToArea(temA, unusedV,
        GIM_LAYER_MID, self.id, SHARP_RECT, 0, 0, -8, -56, 8, 0)
        @if temA >= 0 bl {
            //打ち出す速度
            temB = muldiv(plungerPower, PLUNGER_MAX_VEL, PLUNGER_MAX_POW)
            pbBallFunction(BA_FUNC_SET_VEL, temA, temB, -90 * UNIT_ANGLE, 0, 0)
            @se.play "Blow4" .opt(100, 100, 50)
        }
    }
}

//--------------------------------
//イジェクター
def {
    EJECTER_X = 18
    EJECTER_Y = 20
}
mev[MEV_EJECTER] .pos(EJECTER_X, EJECTER_Y) .name("イジェクター")
mep[1] .body(CHARSET_FRAME, 1) .dir.left .anim .priority.high .parallel bl {
    //簡易判定
    @if `!ROUGHLY_CHECK_BALL_PLUNGER bl {
        @ev.abort
    }

    //上から下へ
    //a:hit id b:dot
    pbBallToArea(temA, temB,
    GIM_LAYER_MID, self.id, SHARP_RECT, 90, 0, -8, -16, 8, 8)
    @if `temA >= 0 && temB >= 0 bl {
        ejecterCatchId = temA

        //スキルショット判定
        @if skillShotLevel > 0 bl {
            skillShotState = GIM_ST_EVENT
        }

        //玉を隠す
        pbBallFunction(BA_FUNC_HIDE, ejecterCatchId, 0, 0, 0, 0)

        //演出
        @se.play "Sea2" .opt(90, 100, 50)
        @ev.flash .self .rgbv(31, 31, 31, 31) .time(5)

        //左に移送する
        @ev.setAction .self .freq(8) .skippable .act {
            .beginThrough
            .faceLeft
            .speedUp
            .moveLeft
            .moveLeft
            .moveLeft
            .moveLeft
            .moveLeft
            .speedDown
            .moveLeft
            .moveLeft
        }

        //動作が終わるまで待機
        @wait(15)

        //球を移動させ、解放する
        pbBallFunction(BA_FUNC_SET_POS, ejecterCatchId, self.id, GIM_LAYER_MID, 0, 0)
        pbBallFunction(BA_FUNC_UNLOCK, ejecterCatchId, 0, 0, 0, 0)
        ejecterCatchId = -1

        //効果音
        @se.play "Evade1" .opt(100, 100, 50)
        @wait(2)

        //左へ戻る
        @ev.setAction .self .freq(8) .skippable .act {
            .faceRight
            .beginJump
            .moveRight//4歩
            .moveRight
            .moveRight
            .moveRight
            .moveRight
            .moveRight
            .moveRight
            .endJump
            .faceLeft
        }

        //動作が終わるまで待機
        @wait(10)
    }
}

//--------------------------------
//スキルショット
def {
    MAX_SKILLSHOT_LEVEL = 3
    SKILLSHOT_X = 18
    SKILLSHOT_Y = 14
}
mev[MEV_SKILLSHOT] .name("スキルショット") .pos(SKILLSHOT_X, SKILLSHOT_Y)
mep[1] bl {}
mep[2] .body(CHARSET_FRAME, 2) .dir.up .anim.fixDir.step .priority.high .cond(v[__id(skillShotState)] == GIM_ST_ACTIVATED) .parallel bl {
    //簡易判定
    @if `!ROUGHLY_CHECK_BALL_PLUNGER bl {
        @ev.abort
    }

    //触れると上に上がる
    @if skillShotLevel < MAX_SKILLSHOT_LEVEL bl {
        pbBallToArea(temA, temB,
        GIM_LAYER_MID, self.id, SHARP_RECT,-90, 0, -8, -16, 8, 8)
        @if `temA >= 0 && temB > 0 bl {
            skillShotLevel += 1

            //移動する
            temA = [18, 18, 16, 18][skillShotLevel]
            temB = [14,  9,  4, 14][skillShotLevel]
            @ev.setPos .self .pos(temA, temB)

            temA = [90, 120, 150, 180][skillShotLevel]
            @se.play "Cursor2" .opt(80, temA, 50)
        }
    }
}
mep[3] .body(CHARSET_FRAME, 2) .dir.up .anim.fixDir.step .priority.high .cond(v[__id(skillShotState)] == GIM_ST_EVENT) .parallel bl {
    //スコア
    temA = [0, BONUS_SKILLSHOT_1, BONUS_SKILLSHOT_2, BONUS_SKILLSHOT_3][skillShotLevel]
    
    pbAddScore(NUM_TYPE_BONUS, temA, 0)
    pbDisplay(DI_ST_ZOOM, __str("\c[2]スキルショット！ Lv\", skillShotLevel))

    //演出
    @ev.setPos .self .pos(EJECTER_X, EJECTER_Y)
    @ev.setAction .self .freq(8) .act {
        .beginThrough
        .faceUp
        .beginJump
        .moveLeft
        .moveDown
        .endJump
    }
    @ev.addAction .face(skillShotLevel)

    @ev.flash .self .rgbv(31, 31, 31, 31) .time(5)

    //レベル3のみ声が入る
    @if skillShotLevel == 3 bl {
        @se.play "voice_atui" .opt(90, 100, 50)
    } .else bl {
        @se.play "Flash2" .opt(90, 100, 50)
    }

    //ずっと待機
    @loop bl {
        @wait(20)
    }
}

//--------------------------------
//トップストッパー
def {
    TOP_STOPPER_X = 8
    TOP_STOPPER_Y = 2
    TOP_STOPPER_FRI = 900
    TOP_STOPPER_REF = 500
}
mev[MEV_TOP_STOPPER] .pos(TOP_STOPPER_X, TOP_STOPPER_Y) .name("トップストッパー")
mep[1] bl {}
mep[2] .body(CHARSET_FRAME, 4) .dir.down .anim.fixDir.step .priority.middle .cond(v[__id(topStopperState)] == GIM_ST_ACTIVATED) .parallel bl {
    //初期化する
    @ev.setPos .self .pos(TOP_STOPPER_X, TOP_STOPPER_Y)
    @ev.setAction .self .freq(8) .act {
        .beginThrough
        .setBody(CHARSET_FRAME, 4)
        .resumeAnim
        .faceDown
    }

    //衝突するまでループする
    @loop bl {
        @wait(0)
        //簡易判定
        @if `ROUGHLY_CHECK_BALL_HIGH bl {
            //a:hit id
            pbUpdateBumper(temA, unusedV,
            GIM_LAYER_MID, TOP_STOPPER_FRI, TOP_STOPPER_REF, 0,
            self.id, SHARP_CIRCLE, 12, 0, 0, 0, 0)
            @if temA >= 0 bl {
                pbAddScore(NUM_TYPE_BONUS, BONUS_TOP_STOPPER, 0)

                //マッスルポーズをとり、藪に隠れる
                @ev.setAction .self .freq(8) .act {
                    .setBody(CHARSET_FRAME, 5)
                    .pauseAnim
                    .turnRandom
                }
                @se.play "hit_db" .opt(80, 120, 50)
                @ev.flash .self .rgbv(31, 31, 31, 31) .time(2)
                @wait(5)
                @ev.setAction .self .freq(8) .act {
                    .setBody(CHARSET_FRAME, 4)
                    .faceDown
                    .beginJump
                    .moveDown
                    .endJump
                }
                @wait(3)
                //ページを変える
                topStopperState = GIM_ST_HIDE
                @ev.abort
            }
        }
    }
}