2019年11月20日

DQ8 最初の町でレベル99にしてみた Botのソースコード

言語はLuaです。
自分がわかればいいやという汚いコードです。そして僕はプロのプログラマーではありません。ご了承ください。
このコードを実際にどのように使うのかについてはまた色々と解説が必要になるので今は書きません。

--↓ここからソースコード --はコメントアウトです

GetLuaEngine().MenuItem5.doClick()--Clear Output
print("START")
FrameCounterAddress=0x203B34E8
ButtonAddress=0x203D1FB4
L_Stick_Y_Address=0x203D1FB8
L_Stick_X_Address=0x203D1FBC
R_Stick_Y_Address=0x203D1FC0
R_Stick_X_Address=0x203D1FC4
isScriptWorking=true
MyFrameCounter=0
ControllState=0
GoalState=0
DoIHaveBoomerang=1

createNativeThread(function(thread)
    while isScriptWorking do

        --フレーム同期
        oldFrameCount=readInteger(FrameCounterAddress)
        while readInteger(FrameCounterAddress)==oldFrameCount do
            sleep(1)
            if isKeyPressed(VK_ESCAPE) then
                isScriptWorking=false
                break
    end
        end

        ScreenState=readInteger(0x203C8B20)
        writeFloat(0x203C6140,1000)--Far Clip

        if OldScreenState~=0x00200800 then
            --戦闘開始を認識
            if ScreenState==0x00200800 then
                ControllState=1
                ControllReset()
            end
        end

        --敵を全て倒したことを認識
        if ControllState==1
          or ControllState==2 then
            iff=true
            for i=0,7 do
                if readInteger(0x20406588+i*0x5B0)>0 then
                    iff=false
                    break
                end
            end
            if iff then
                ControllState=3
                ControllReset()
            end
        end

        --フィールドぶらぶら
        if ControllState==0 then
            if readSmallInteger(0x203EA8DA)<4 then
                if DoIHaveBoomerang==0 then toGoal(32300,-25450) end
                if DoIHaveBoomerang==1 then toGoal(30350,-26500) end
            else
                --くちぶえ
                localcounter=17
                for i2=0,2 do
                PressButton(0x0020,5)
                if readFloat(0x20B34C58)>-26600 then
                    PressButton(0x2000,2)--右
                else
                    PressButton(0x8000,2)--左
                end
                PressButton(0x0020,2)
                PressButton(0x4000,2)
                PressButton(0x0020,2)
                PressButton(0x1000,2)
                PressButton(0x0020,9)
                for i=0,4 do
                PressButton(0x0080,2)
                end
                end
            end

            --HPが減っていたら宿屋へ
            if readInteger(0x203EA834)<=13
            or readInteger(0x203EA89C)<=13 then
                if DoIHaveBoomerang==0 then ControllState=4 end
                if DoIHaveBoomerang==1 then ControllState=7 end
                GoalState=0
            end

            --店が開いてる時間に所持金が貯まっていて
            --ブーメランを持っていなかったらたら店へ
            if readFloat(0x203D96D0)>=6 and readFloat(0x203D96D0)<24
            and readInteger(0x203EA800)>=426
            and DoIHaveBoomerang==0 then
                ControllState=6
                GoalState=0
                DoIHaveBoomerang=1
            end
        end

        --宿屋へ行く1
        if ControllState==4 then
            --門1
            if GoalState==0 then
                if toGoal(32273,-25621) then
                    GoalState=2
                end
            end
            if GoalState==2 then
                if toGoal(-682,-258) then
                    GoalState=3
                end
            end
            if GoalState==3 then
                if toGoal(-697,-601) then
                    GoalState=4
                end
            end
            --宿扉
            if GoalState==4 then
                if toGoal(-770,-588) then
                    GoalState=5
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    writeInteger(0x203D1FB4,0x00)
                end
            end
            --受付
            if GoalState==5 then
                if toGoal(75,25) then
                    GoalState=6
                    ControllReset()
                end
            end
            --手続き
            if GoalState==6 then
                localcounter=0
                PressButton(0x10,60)
                PressButton(0x20,50)
                PressButton(0x20,50)
                PressButton(0x20,50)
                if readSmallInteger(0x203F6786)==0x36 then
                    MyFrameCounter=10000
                end
                localcounter=10050
                PressButton(0x10,20)
                if MyFrameCounter==localcounter then
                    GoalState=7
                end
            end
            --宿を出る
            if GoalState==7 then
                if toGoal(-80,105) then
                    GoalState=8
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    writeInteger(0x203D1FB4,0x00)
                end
            end
            if GoalState==8 then
                if toGoal(-697,-601) then
                    GoalState=9
                end
            end
            if GoalState==9 then
                if toGoal(-682,-258) then
                    GoalState=10
                end
            end
            --門1
            if GoalState==10 then
                if toGoal(-10,480) then
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    GoalState=11
                    ControllReset()
                end
            end
            if GoalState==11 then
                if readSmallInteger(0x203EA8DA)>=4 then
                    if MyFrameCounter==120 then
                        ControllState=0
                        MyFrameCounter=0
                    end
                else
                    ControllState=0
                end
            end
        end

        --宿屋へ行く2
        if ControllState==7 then
            --門2
            if GoalState==0 then
                if toGoal(30460,-26592) then
                    GoalState=1
                end
            end
            if GoalState==1 then
                if toGoal(-697,-601) then
                    GoalState=2
                end
            end
            --宿扉
            if GoalState==2 then
                if toGoal(-770,-588) then
                    GoalState=3
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    writeInteger(0x203D1FB4,0x00)
                end
            end
            --受付
            if GoalState==3 then
                if toGoal(75,25) then
                    GoalState=4
                    ControllReset()
                end
            end
            --手続き
            if GoalState==4 then
                localcounter=0
                PressButton(0x0010,60)
                PressButton(0x0020,50)
                --PressButton(0x4000,10)
                PressButton(0x0020,50)
                PressButton(0x0020,50)
                if readSmallInteger(0x203F6786)==0x36 then
                    MyFrameCounter=10000
                end
                localcounter=10050
                PressButton(0x10,20)
                if MyFrameCounter==localcounter then
                    GoalState=5
                end
            end
            --宿を出る
            if GoalState==5 then
                if toGoal(-80,105) then
                    GoalState=6
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    writeInteger(0x203D1FB4,0x00)
                end
            end
            if GoalState==6 then
                if toGoal(-697,-601) then
                    GoalState=7
                end
            end
            --門2
            if GoalState==7 then
                if toGoal(-721,-1131) then
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    GoalState=8
                    ControllReset()
                end
            end
            if GoalState==8 then
                if readSmallInteger(0x203EA8DA)>=4 then
                    if MyFrameCounter==120 then
                        ControllState=0
                        MyFrameCounter=0
                    end
                else
                    ControllState=0
                end
            end
        end

        --店へ行く
        if ControllState==6 then
            --門
            if GoalState==0 then
                if toGoal(32273,-25621) then
                    GoalState=1
                end
            end
            if GoalState==1 then
                if toGoal(-130,2) then
                    GoalState=2
                end
            end
            if GoalState==2 then
                if toGoal(-96,-248) then
                    GoalState=3
                end
            end
            if GoalState==3 then
                if toGoal(-8,-376) then
                    GoalState=4
                end
            end
            if GoalState==4 then
                if toGoal(-2,-618) then
                    GoalState=5
                end
            end
            --店扉
            if GoalState==5 then
                if toGoal(64,-730) then
                    GoalState=6
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    writeInteger(0x203D1FB4,0x00)
                end
            end
            --受付
            if GoalState==6 then
                if toGoal(0,-10) then
                    GoalState=7
                    ControllReset()
                end
            end
            --手続き
            if GoalState==7 then
                localcounter=0
                PressButton(0x0010,60)--話しかける
                PressButton(0x0020,30)--どんな用
                PressButton(0x0020,10)--なにを買う
                PressButton(0x1000,10)--選択
                PressButton(0x0020,40)--決定
                PressButton(0x0020,30)--それでいい?
                PressButton(0x0020,10)--だれが持つ
                PressButton(0x0020,30)--決定
                PressButton(0x0020,40)--ここで装備?
                PressButton(0x0020,40)--装備させてもらった
                if readInteger(0x203EA800)>=10 then
                    PressButton(0x0040,10)--他に買うか?
                    PressButton(0x0040,40)--選択
                end
                PressButton(0x0040,30)--他に用は
                PressButton(0x0040,20)--また来て
                if MyFrameCounter==localcounter then
                    GoalState=8
                end
            end
            --店を出る
            if GoalState==8 then
                if toGoal(-75,-66) then
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    writeInteger(0x203D1FB4,0x00)
                    GoalState=9
                end
            end
            if GoalState==9 then
                if toGoal(-114,-629) then
                    GoalState=10
                end
            end
            if GoalState==10 then
                if toGoal(-279,-678) then
                    GoalState=11
                end
            end
            if GoalState==11 then
                if toGoal(-290,-1359) then
                    GoalState=12
                end
            end
            if GoalState==12 then
                if toGoal(-693,-1100) then
                    GoalState=13
                end
            end
            if GoalState==13 then
                if toGoal(-721,-1131) then
                    writeInteger(0x203D1FB4,0x10)
                    sleep(100)
                    GoalState=14
                    ControllReset()
                end
            end
            if GoalState==14 then
                if readSmallInteger(0x203EA8DA)>=4 then
                    if MyFrameCounter==120 then
                        ControllState=0
                        MyFrameCounter=0
                    end
                else
                    ControllState=0
                end
            end
        end

        --戦闘AI
        if ControllState==1 then
            localcounter=5
            PressButton(0x0020,5)
            PressButton(0x0020,5)
            PressButton(0x0020,5)
        end

        --リザルト画面
        if ControllState==3 then
            if MyFrameCounter%10==5 then
                writeInteger(0x203D1FB4,0x20)
            end
            if MyFrameCounter%10==6 then
                writeInteger(0x203D1FB4,0x00)
            end
            if readInteger(0x203C4C8C)==1 then
                ControllState=5
                ControllReset()
            end
            if readInteger(0x203B3794)==0 then
                ControllState=0
                ControllReset()
            end
        end

        --スキルポイント振り分け
        if ControllState==5 then
            if readInteger(0x203C4C8C)==0 then
                ControllState=3
                ControllReset()
            end

            if MyFrameCounter%10==5 then
                nokori=readSmallInteger(0x20402D62)
                  -readSmallInteger(0x20402D66)
                  -readSmallInteger(0x20402D68)
                  -readSmallInteger(0x20402D6A)
                  -readSmallInteger(0x20402D6C)
                  -readSmallInteger(0x20402D6E)
                if nokori>=1 then
                    if AddSkillP(4) then goto exit end
                    if AddSkillP(2) then goto exit end
                    if AddSkillP(0) then goto exit end
                    if AddSkillP(1) then goto exit end
                    ::exit::
                  else
                    writeInteger(0x203D1FB4,0x20)
                end
            end
            if MyFrameCounter%10==6 then
                writeInteger(0x203D1FB4,0x00)
            end
        end

        OldScreenState=ScreenState
        Old_readInteger_0x203B3794=readInteger(0x203B3794)
        MyFrameCounter=MyFrameCounter+1

        --[[if MyFrameCounter%10==0 then
            GetLuaEngine().MenuItem5.doClick()--clear output
            print("ControllState\t"..ControllState)
            print("GoalState\t"..GoalState)
            print("MyFrameCounter\t"..MyFrameCounter)
            --print("Angleabs\t"..Angleabs)
        end]]
    end

    ControllReset()
    print("END")
end)

function PressButton(type,interval)
    if MyFrameCounter==localcounter then
        writeInteger(0x203D1FB4,type)
    end
    if MyFrameCounter==localcounter+1 then
        writeInteger(0x203D1FB4,0)
    end
    localcounter=localcounter+interval
end

function AddSkillP(index)
    if readBytes(0x20402D70+index*0x1)
    +readSmallInteger(0x20402D66+index*0x2)
    <readBytes(0x20402D75) then
        abs=(index+1)-readInteger(0x209CC5A8)
        if abs>= 3 or (abs<0 and abs>-3) then
            writeInteger(0x203D1FB4,0x1000)--↑
        end
        if abs<=-3 or (abs>0 and abs< 3) then
            writeInteger(0x203D1FB4,0x4000)--↓
        end
        if abs==0 then
            writeInteger(0x203D1FB4,0x20)--○
        end
        return true
    end
    return false
end

function ControllReset()
    writeInteger(0x203D1FB4,0x00)
    writeInteger(L_Stick_Y_Address,127)
    writeInteger(L_Stick_X_Address,127)
    writeInteger(R_Stick_Y_Address,127)
    writeInteger(R_Stick_X_Address,127)
    MyFrameCounter=0
    return
end

function toGoal(GoalX,GoalY)
    Angleabs=
      math.atan2(
      readFloat(0x20B34C50)-readFloat(0x2081AC30),
      readFloat(0x20B34C58)-readFloat(0x2081AC38))-
      math.atan2(
      GoalX-readFloat(0x20B34C50),
      GoalY-readFloat(0x20B34C58))

    if Angleabs>math.pi then
        Angleabs=Angleabs-2*math.pi
    end
    if Angleabs<-math.pi then
        Angleabs=Angleabs+2*math.pi
    end

    if Angleabs> 0.04 then writeInteger(R_Stick_X_Address,  0) end
    if Angleabs<-0.04 then writeInteger(R_Stick_X_Address,255) end
    if Angleabs>=-0.04 and Angleabs<=0.04 then
        writeInteger(R_Stick_X_Address,127)
    end
    if Angleabs>=-0.2 and Angleabs<=0.2 then
        writeInteger(L_Stick_Y_Address,0)
      else
        writeInteger(L_Stick_Y_Address,127)
    end

    if math.sqrt(
      (GoalX-readFloat(0x20B34C50))^2+
      (GoalY-readFloat(0x20B34C58))^2)<10 then
        return true
      else
        return false
    end
end