
//定数
def {
    NUM_OF_VAR = 400
    NUM_OF_STR = 4
    NUM_OF_PIC = 256

    //レイヤー
    LAY_RESULT = 7
    LAY_UI = 7
    //玉
    LAY_BALL_LOW = 2
    LAY_BALL_MID = 3
    LAY_BALL_HI  = 4
    //ステージマップ
    LAY_STAGE_LOW = 2
    LAY_STAGE_MID = 4//イベントに合わせてずらす
    LAY_STAGE_HI  = 5
    //衝突マップ
    LAY_COLLMAP = 2
    //フリッパー
    LAY_FLIPPER = 3

    //歩行グラフィック
    CHARSET_FRAME      = "pb_frame"
    CHARSET_SAVER      = "pb_saver"
    CHARSET_SLINGSHOT  = "pb_slingshot"
    CHARSET_LANE       = "pb_lane"
    CHARSET_TOP_BUMPER = "pb_topBumper"
    CHARSET_SPINNER    = "pb_spinner"
    CHARSET_ENEMY_1    = "pb_enemy1"
    CHARSET_LEADER_1   = "pb_leader1"
    CHARSET_LEADER_2   = "pb_leader2"
    CHARSET_SLOT       = "pb_slot"
    CHARSET_TARGET_1   = "pb_target1"
    CHARSET_EVENT_1    = "pb_event1"
    CHARSET_HOLE       = "pb_hole"
    CHARSET_SPEC       = "pb_performer"
    CHARSET_BOSS_1     = "pb_boss1"
    
    //パス
    PATH_HORI_BG     = "pb\hz"
    PATH_SCORE_BG    = "pb\sc"
    PATH_FLIPPER     = "pb\fl"
    PATH_BALL_BODY   = "pb\ba"
    PATH_BALL_SHADOW = "pb\bs"
    PATH_BALL_AFTER  = "pb\be"
    PATH_SLOT_CELL   = "pb\sl"
    PATH_SLOT_BASE   = "pb\slb"
    PATH_ICON        = "pb\ic"

    //ピクチャ
    PIC_HEAD        = 1
    PIC_COLLMAP     = 2   //+0_+3
    PIC_STAGE       = 6   //+0_+3
    PIC_BALL_SHADOW = 18  //+0_+1
    PIC_BALL_AFTER  = 20  //+0_+15
    PIC_BALL_BODY   = 36  //+0_+1
    PIC_FLIPPER     = 40  //+0_+4
    PIC_SLOT_CELL   = 50//+0_+5
    PIC_SLOT_BASE   = 56
    PIC_BOSS        = 59
    PIC_ATTACK      = 60//+0_+63
    PIC_DAMAGE      = 129
    PIC_ICON        = 130//+0_+7
    PIC_DESC_BG     = 140
    PIC_DESC        = 141
    PIC_SCORE_BG    = 142
    PIC_LOG         = 143
    PIC_SCORE       = 144
    PIC_BONUS       = 145
    PIC_MULTIPLIER  = 146
    PIC_CHANCE      = 147
    PIC_TIMER       = 148
    PIC_POWERUP     = 149
    PIC_TIMEBONUS   = 150
    PIC_DISPLAY_BG  = 151
    PIC_DISPLAY     = 152
    PIC_SELECT_BG   = 153
    PIC_SELECT      = 154
    //PIC_VIDEOMODE = 160

    //ゲームの状態
    SC_ST_ENTER = 0
    SC_ST_ENTER_BONUSSTAGE
    SC_ST_EXIT_BONUSSTAGE
    SC_ST_VIDEOMODE
    SC_ST_PLAY
    SC_ST_LOAD
    SC_ST_LIQUID
    SC_ST_CHANCE
    SC_ST_GAMEOVER
    SC_ST_WINS

    //フラグ
    SC_BIT_SCORE     = 1 << 0
    SC_BIT_BONUS     = 1 << 1
    SC_BIT_MULTI     = 1 << 2
    SC_BIT_CHANCE    = 1 << 3
    SC_BIT_TIMER     = 1 << 4
    SC_BIT_LOG       = 1 << 5
    SC_BIT_POWERUP   = 1 << 6
    SC_BIT_ICON      = 1 << 7
    SC_BIT_TIMEBONUS = 1 << 8

    //単位
    UNIT_ANGLE = 10                  //角度
    UNIT_LOOP  = (360 * UNIT_ANGLE)  //一回転
    UNIT_POS   = 100                 //玉や仕掛けの座標の倍率

    //共通ステート
    GIM_ST_HIDE = 0
    GIM_ST_ACTIVATED
    GIM_ST_EVENT

    //ボーナスゲーム
    BONUSGAME_NINNIN = 0
    BONUSGAME_MAOU

    //玉
    MAX_BALL       = 2
    BA_RADxUNIT    = 8 * UNIT_POS         //玉の半径
    BA_RAD         = 8
    BA_NUMBER      = 2                    //玉の最大数
    BA_MASS        = 1                    //玉の重さ(未使用)
    BA_CORRECT     = UNIT_POS / 2
    BA_MAX_CELL    = 16
    BA_FRI         = 1000
    BA_REF         = 100                  //質量を無視した反射なのでここで調節しなければならない
    BA_REF_CORRECT = UNIT_POS * 10 / 100  //補正量
    BA_ACC_SPIN    = 6 * UNIT_ANGLE       //最大回転加速度
    BA_MAX_SPIN    = 15 * UNIT_ANGLE      //最大回転速度
    BA_REACT_MAP   = 10                   //マップとの衝突判定に使用する補正係数
    BA_MAX_AFTER   = 8                    //残像の数

    //玉の汎用処理
    BA_FUNC_APPEAR = 0
    BA_FUNC_DELETE
    BA_FUNC_UNLOCK
    BA_FUNC_LOCK
    BA_FUNC_HIDE
    BA_FUNC_SET_POS
    BA_FUNC_SET_VEL
    BA_FUNC_SET_LAYER
    
    BA_ST_NONE = 0
    BA_ST_DELETE
    BA_ST_ENABLE
    BA_ST_HIDE
    BA_ST_LOCK

    MB_STATE = 0
    MB_LAYER
    MB_ANGLE
    MB_SPIN
    MB_X//現在位置
    MB_Y
    MB_NX//次Fの位置
    MB_NY
    MB_VX//速度
    MB_VY
    SIZE_OF_BALL

    //フリッパー
    MAX_FLIPPER = 4

    FL_STEP            = 1
    FL_MAX_STEP        = 3
    FL_OFFSET_X        = -16
    FL_OFFSET_Y        = -26
    FL_START_ANGLE     = 24 * UNIT_ANGLE
    FL_END_ANGLE       = -35 * UNIT_ANGLE
    FL_FRI             = 1000
    FL_REF             = 300
    FL_LEN_NORMAL      = 30 * UNIT_POS
    FL_LEN_SMALL       = 17 * UNIT_POS
    FL_RAD_ROOT_NORMAL = 6 * UNIT_POS
    FL_RAD_ROOT_SMALL  = 5 * UNIT_POS
    FL_RAD_TIP_NORMAL  = 4 * UNIT_POS
    FL_RAD_TIP_SMALL   = 3 * UNIT_POS

    FL_BIT_HREV  = 1 << 0
    FL_BIT_SMALL = 1 << 1

    FL_FUNC_APPEAR = 0
    FL_FUNC_DELETE

    FL_ST_NONE = 0
    FL_ST_DELETE
    FL_ST_ENABLE
    FL_ST_DAMAGE

    MF_STATE = 0
    MF_BIT
    MF_LAYER
    MF_STEP
    MF_X
    MF_Y
    SIZE_OF_FLIPPER

    //敵
    MAX_ENEMY = 8

    EN_ST_NONE = 0
    EN_ST_INIT
    EN_ST_JUMP
    EN_ST_ENABLE
    EN_ST_DEFEAT

    ME_STATE = 0
    ME_TIMER
    ME_PATTERN
    ME_HP
    SIZE_OF_ENEMY

    EN_PAT_NONE = 0
    EN_PAT_LEFT
    EN_PAT_RIGHT
    EN_PAT_CENTER

    //弾丸
    MAX_ATTACK = 32

    AT_ST_NONE = 0
    AT_ST_DELETE
    AT_ST_DEFEAT
    AT_ST_INIT
    AT_ST_ENABLE

    MA_STATE = 0//位置はピクチャから取得する
    MA_TIMER
    MA_TYPE
    MA_PARAM
    SIZE_OF_ATTACK

    AT_TY_NONE = 0
    AT_TY_ALTER
    AT_TY_ALTER_BODY
    AT_TY_ALTER_ITEM
    AT_TY_EXPLO_EFF
    AT_TY_DARKNESS_EFF
    AT_TY_FLAME
    AT_TY_SPARK
    AT_TY_TORNADE

    //ナッジング
    NU_TIMER1 = UNIT_FPS * 2
    NU_TIMER2 = 5
    NU_VX1    = -200
    NU_VX2    = 40 - 20
    NU_VY1    = 200
    NU_VY2    = -40

    //強制終了
    ABORT_KEY = 11
    ABORT_TIMER = 60

    //チート
    CHEAT_KEY = 14
    CHEAT_VEL = 4 * UNIT_POS

    //スクロール
    SCROLL_SLIDE    = -16
    SCROLL_SLIDE_EX = -64
    SCROLL_EXTRA    = 24
    SCROLL_EASE_DIV = 2

    //ディスプレイ
    DI_ST_NONE = 0
    DI_ST_NORMAL
    DI_ST_ZOOM
    DI_ST_LIQUID
    DI_ST_CENTER
    DI_ST_SELECT
    
    //マップ
    MAP_FRI = 1000
    MAP_REF = 400

    //形状
    SHARP_RECT = 0
    SHARP_CIRCLE
    SHARP_SEGMENT_ONLY//端との判定なし
    SHARP_SEGMENT

    //ギミックのレイヤー
    GIM_LAYER_LOW = 0
    GIM_LAYER_MID
    GIM_LAYER_HI

    //スコアの種類
    NUM_TYPE_SCORE = 0
    NUM_TYPE_BONUS
    NUM_TYPE_MULTI
    NUM_TYPE_CHANCE

    NUM_BIT_MULTI = 1 << 0
    NUM_BIT_REEL  = 1 << 1

    //戦闘アニメのバッファ
    ANIM_BUFFER_BALL = 0
    ANIM_BUFFER_EFFECT
    ANIM_BUFFER_EVENT

    //スコア
    MAX_TIME          = 60 * 60 * 60 * 99  //99時間
    MAX_SCORE         = 99999999           //スコアの最大値
    MAX_BONUS         = 9999999            //ボーナスの最大値
    MAX_MULTI         = 999                //マルチプライヤーの最大値
    MAX_CHANCE        = 3                  //エクストラボールの最大値
    MAX_POWERUP_TIMER = 60 * UNIT_FPS
    MAX_LOG           = 5

    //アイコン
    ICON_BIT_DAERO   = 1 << 0
    ICON_BIT_GOSEI   = 1 << 1
    ICON_BIT_MUSYA   = 1 << 2
    ICON_BIT_NASU    = 1 << 3
    ICON_BIT_NIN     = 1 << 4
    ICON_BIT_EXTRA   = 1 << 5
    ICON_BIT_VIDEO   = 1 << 6
    ICON_BIT_POWERUP = 1 << 7

    ICON_WIDTH = 16
    ICON_HEIGHT= 8
    MAX_ICON   = 8

    //ディスプレイ
    SCORE_BG_X  = 320
    SCORE_BG_Y  = 240
    SCORE_X     = 320 - 4
    SCORE_Y     = 240 - 2
    BONUS_X     = 320 - 4
    BONUS_Y     = 240 - 16
    MULTI_X     = 320 - 40
    MULTI_Y     = 240 - 30
    CHANCE_X    = 320 - 4
    CHANCE_Y    = 240 - 30
    TIMER_X     = 320 - 2
    TIMER_Y     = 2
    POWERUP_X   = 320 - 2
    POWERUP_Y   = 2 + 14
    TIMEBONUS_X = 320 - 2
    TIMEBONUS_Y = 2 + 28
    LOG_X       = 320 - 2
    LOG_Y       = 240 - 48
    DESC_X      = 0
    DESC_Y      = 240 - 16
    DESC_LEN    = 720
    DISPLAY_X   = 0
    DISPLAY_Y   = 0
    ICON_X      = 0
    ICON_Y      = 176

    //定数
    OUT_RANGE         = -320
    INITAL_CHANCE     = 3                   //初期残機数
    MAX_VELOCITY      = 14 * UNIT_POS       //最大速
    GRAVITY_X         = 0                   //重力
    GRAVITY_Y         = UNIT_POS * 8 / 100
    SCORE_REEL_MIN    = 100

    //実績
    ACHIEVE_SCORE_1 = 10000
    ACHIEVE_SCORE_2 = 50000
    ACHIEVE_SCORE_3 = 200000
}

//変数
defv {
    varHead = TV_PINBALL
    
    triggerFlg
    sceneState
    sceneTimer
    bonusGameMode
    iconFlag
    gameTimer
    hitStopTimer
    powerupTimer
    timeBonusTimer
    enableScore
    enableIcon
    score
    bonus
    multiplier
    chance
    bumperPattern
    falconSuccess

    initHead//これ以降の変数はマップ移動で初期化される

    ptrA//一時変数 他のマップやコモンイベントの変数と名前が被ると困る
    ptrB
    idxA
    idxB
    temA
    temB
    temC
    temD
    temE
    temF
    temG
    temH
    temI

    anyInput
    abortInput
    cheatInput
    plungerInput
    leftFlipperInput
    rightFlipperInput
    leftNudgeInput
    rightNudgeInput
    nudgeTimer
    nudgeDir
    ballCount
    eventMode
    maxVelocity

    bgmType
    bgmTimer

    ballAreaMinX//簡易判定に使用する(mapTile)
    ballAreaMinY
    ballAreaMaxX
    ballAreaMaxY

    gravityX
    gravityY
    cameraX
    cameraY

    logCount
    descScrollX
    displayState
    displayTimer
    displaySelect
    scoreDisplay
    scoreStep
    
    effectTimer
    subFlipperFlag
    plungerPower
    ejecterCatchId
    skillShotState
    skillShotLevel
    topStopperState
    freezeState
    freezeTimer
    freezeSwitch
    centerPostState
    centerPostTimer
    leftKickBackState
    rightKickBackState
    enryuState
    enryuTimer
    slotState
    slotCatchId
    slotPlayState
    slotPlayStep
    slotPlayLeft
    slotPlayCenter
    slotPlayRight
    underLaneFlag
    underReelFlag
    topLaneFlag
    railTermCount
    rightLaneCount
    leftLaneCount
    jumpSwitchrState
    jumpSwitchrCatchId
    slingshotCount
    boardDir
    topBumperLevel
    topBumperPos
    topBumperSwitchCount
    topBumperTimer
    spinnerLevel
    spinnerSpeed
    spinnerAngle
    middleCurveFlag
    middleCurveTimer
    middleOutLaneCount
    brianState
    brianCount
    worldState
    worldTimer
    centerHoleCatchId
    bonusHoleCatchId
    rooftopKeeperCatchId
    rooftopKeeperHp
    underTargetState
    underTargetTimer
    middleRolloverState
    middleRolloverCount
    exitGateCatchId
    exitGateState
    exitGateCount
    falconState
    falconTimer
    falconFlag
    falconArea
    daeroHp
    goseiHp
    musyaHp
    nasuHp
    gateKeeperState
    bossAttackCount
    bossState
    bossTimer
    bossDamage
    bossHp
    bossPos
    bossPattern
    bossX
    bossY
    temp01
    temp02
    temp03
    temp04

    ballHead 
    flipperHead = __id(ballHead) + MAX_BALL * SIZE_OF_BALL
    enemyHead   = __id(flipperHead) + MAX_FLIPPER * SIZE_OF_FLIPPER
    attackHead  = __id(enemyHead) + MAX_ENEMY * SIZE_OF_ENEMY
    varFoot     = __id(attackHead) + MAX_ATTACK * SIZE_OF_ATTACK
}

deft {
    strLine = TS_MINIGAME
    strLog
    strDisplay
}

def {
    basePicCmd = bl {
        .chromakey(1)
        .eraseWhenTransfer
        .affectedByTint
        .affectedByFlash
        .affectedByShake
    }

    dpBasePicCmd = bl {
        .chromakey(1)
        .mapLayer(LAY_UI)
        .eraseWhenTransfer
    }

    dpStrPicCmd = bl {
        .font("", 12)
        .skin "" .nobg .noframe .noPadding
        .size(0, 0)
        .spacing(0, 4)
        dpBasePicCmd
    }

    dpMiddleStrPicCmd = bl {
        .font("", 14)
        .skin "" .nobg .noframe .noPadding
        .size(0, 0)
        .spacing(0, 4)
        dpBasePicCmd
    }

    dpLargeStrPicCmd = bl {
        .font("", 16)
        .skin "" .nobg .noframe .noPadding
        .size(0, 0)
        .spacing(0, 4)
        dpBasePicCmd
    }

    dpScoreBgPicCmd = bl {
        PATH_SCORE_BG
        .multi
        dpBasePicCmd
    }

    dpHoriBgPicCmd = bl {
        PATH_HORI_BG
        .multi
        dpBasePicCmd
    }

    dpIconPicCmd = bl {
        PATH_ICON
        .grid(1, 8)
        dpBasePicCmd
    }

    strPicCmd = bl {
        .font("", 12)
        .skin "" .nobg .noframe .noPadding
        .size(0, 0)
        .spacing(0, 4)
        basePicCmd
    }

    flipperPicCmd = bl {
        PATH_FLIPPER
        .mapLayer(LAY_FLIPPER)
        .grid(4, 2)
        .scrollWithMap
        basePicCmd
    }

    ballBodyPicCmd = bl {
        PATH_BALL_BODY
        .grid(16, 12)
        .scrollWithMap
        basePicCmd
    }

    ballShadowPicCmd = bl {
        PATH_BALL_SHADOW
        .scrollWithMap
        basePicCmd
    }

    ballAfterPicCmd = bl {
        PATH_BALL_AFTER
        .scrollWithMap
        .add
        basePicCmd
    }

    slotBasePicCmd = bl {
        PATH_SLOT_BASE
        .scrollWithMap
        .mapLayer(LAY_STAGE_LOW)
        basePicCmd
    }

    slotCellPicCmd = bl {
        PATH_SLOT_CELL
        .grid(4, 3)
        .mapLayer(LAY_STAGE_LOW)
        basePicCmd
    }
}

//シーンの状態を変える
__fn changeSceneState $state bl {
    v[__id(sceneState)..__id(sceneTimer)] = [$state, -1]
}

//ディスプレイの状態を変える
__fn changeDisplayState $state bl {
    v[__id(displayState)..__id(displayTimer)] = [$state, -1]
}

//他のピンボール台へ移動する
__fn goToPinballStage $map bl {
    @map[$map].setPlayerPos .pos(9, 7)
}

//中継マップへ移動する
__fn goToRelayMap bl {
    @scr.hide(FADE_FLASH)
    @map[MAP_RELAY].setPlayerPos .pos(0, 0)
}

//衝突マップ用ピクチャを設置する
//カメラの位置を事前に合わせる必要がある
__fn showCollisionMapPicture $id $path $x $y {
    @pic.show [$id] {
        $path
        .pos($x, $y) .topLeft
        .scale(100)
        .trans(100)//半透明
        .mapLayer(LAY_COLLMAP)
        .chromakey(0)
        .eraseWhenTransfer
        .scrollWithMap
        .affectedByTint
        .affectedByFlash
        .affectedByShake
    }
}

//ステージ用ピクチャを設置する
__fn showStageMapPicture $id $path $layer $x $y {
    @pic.show [$id] {
        $path
        .pos($x, $y) .topLeft
        .scale(100)
        .trans(0)
        .chromakey(1)
        .mapLayer($layer)
        .eraseWhenTransfer
        .scrollWithMap
        .affectedByTint
        .affectedByFlash
        .affectedByShake
    }
}

//ボールのポインタを取得する
__fn getBallPtr $dvPtr $idx bl {
    v[__id($dvPtr)] = __id(ballHead) + ($idx) * SIZE_OF_BALL
}

//ボールを設置する
__fn initBall $ptr $block {
    $block
    v[$ptr..$ptr + SIZE_OF_BALL - 1] = [$state, $layer, $angle, $spin, $x, $y, $nx, $ny, $vx, $vy]
}

//フリッパーのポインタを取得する
__fn getFlipperPtr $dvPtr $idx bl {
    v[__id($dvPtr)] = __id(flipperHead) + ($idx) * SIZE_OF_FLIPPER
}

//フリッパーを設置する
__fn initFlipper $ptr $block {
    $block
    v[$ptr..$ptr + SIZE_OF_FLIPPER - 1] = [$state, $bit, $layer, $step, $x, $y]
}

//敵のポインタを取得する
__fn getEnemyPtr $dvPtr $idx bl {
    v[__id($dvPtr)] = __id(enemyHead) + ($idx) * SIZE_OF_ENEMY
}

//敵を設置する
__fn initEnemy $ptr $block {
    $block
    v[$ptr..$ptr + SIZE_OF_ENEMY - 1] = [$state, $timer, $pattern, $hp]
}

//敵の状態を変える
__fn changeEnemyState $ptr $state $timer bl {
    v[$ptr + ME_STATE..$ptr + ME_TIMER] = [$state, $timer]
}

//攻撃のポインタを取得する
__fn getAttackPtr $dvPtr $idx bl {
    v[__id($dvPtr)] = __id(attackHead) + ($idx) * SIZE_OF_ATTACK
}

//攻撃を設置する
__fn initAttack $ptr $block {
    $block
    v[$ptr..$ptr + SIZE_OF_ATTACK - 1] = [$state, $timer, $type, $param]
}

//攻撃の状態を変える
__fn changeAttackState $ptr $state bl {
    v[$ptr + MA_STATE..$ptr + MA_TIMER] = [$state, -1]
}

//ボスの状態を変える
__fn changeBossState $state {
    v[__id(bossState)..__id(bossState) + 1] = [$state, -1]
}

//カウントダウンと点滅
__fn countDownEvent $dvTimer $eventId {
    @if `$dvTimer > 0 && !eventMode bl {
        v[__id($dvTimer)] -= 1
        //時間切れ
        @if $dvTimer <= 0 bl {
        //点滅
        } .elif `$dvTimer < UNIT_FPS * 5 && $dvTimer % 30 == 0 bl {
            @ev.flash[$eventId] .rgbv(31, 31, 31, 24) .time(2)
        }
    }
}

__fn countDownAndChangeState $dvState $dvTimer $eventId $setState {
    @if `$dvTimer > 0 && !eventMode bl {
        v[__id($dvTimer)] -= 1
        //時間切れ
        @if $dvTimer <= 0 bl {            
            v[__id($dvState)] = $setState
            @se.play "Ice2" .opt(80, 100, 50)
            @ev.flash[$eventId] .rgbv(0, 0, 0, 31) .time(2)
            @ev.abort
        //点滅
        } .elif `$dvTimer < UNIT_FPS * 5 && $dvTimer % 30 == 0 bl {
            @ev.flash[$eventId] .rgbv(31, 31, 31, 24) .time(2)
        }
    }
}

//パワーアップ
__fn addPowerUpTimer $sec bl {
    powerupTimer = min(powerupTimer + ($sec) * UNIT_FPS, MAX_POWERUP_TIMER)
}

//アイコン
__fn iconOn $bit bl {
    bitOn(iconFlag, $bit)
    bitOn(triggerFlg, SC_BIT_ICON)
}

__fn iconOff $bit bl {
    bitOff(iconFlag, $bit)
    bitOn(triggerFlg, SC_BIT_ICON)
}

//イベントモード
//スクロール絡みの処理でウェイトが必要になる
__fn startEventMode bl {
    eventMode = TRUE
    @wait(0)
}

__fn endEventMode bl {
    eventMode = FALSE
}