Advertisement
Robert_Ordis

CVHodLua ver0.2 without fillbox

Sep 14th, 2012
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.33 KB | None | 0 0
  1. --[[
  2. Castlevania Harmony of Dissonance
  3. Showing Judgement of enemies/weapons/player Script
  4. Created by Robert_Ordis
  5. 自機座標、
  6. 自機のスピード、
  7. 自機ダメージ判定、
  8. 自機攻撃判定、
  9. グリッド、
  10. 敵機のダメージ/はじき判定
  11. 敵機の判定
  12. HP持ちの敵機の無敵時間を2つとHP
  13. を表示します。
  14.  
  15. 「白夜の協奏曲TASをやるならこれを標準装備としよう」となることを目標に作成しましたが、
  16. ちょっとごちゃごちゃしすぎたのかもしれません。
  17.  
  18. ---更新履歴---
  19. Created date was forgotten ver 0.001
  20. ->グリッドと敵の画面上座標、自機の各種情報及び攻撃判定もどきを表示。多分2年とちょっとぐらい前に作成。
  21. ただし、Aria of Sorrowのものにうっかり上書きしてしまったためにコードの大半は失われることに。
  22.  
  23. Created in 2012/09/11(TUE) ver 0.01
  24. ->やる気を起こしてとりあえず2年前の物とある程度同じになるよう復元。敵機の攻撃判定はまだ無し。
  25.  
  26. Updated in 2012/09/12(WED) ver 0.02
  27. ->敵機攻撃判定実装。
  28.  
  29. Updated in 2012/09/12(WED) ver 0.03
  30. ->自機の被接触判定の表示見直し。壁との被接触判定とスプライトの攻撃/接触判定に対する非接触判定の区別をつけるようにした。
  31.  
  32. Updated in 2012/09/13(THU) ver 0.035
  33. ->スプライト?の判定表示方法を変更。グリッドに座標の値をつけるようにした。
  34.  
  35. Updated in 2012/09/13(THU) ver 0.04
  36. ->敵の無敵時間表示の機能を付けた。最大2つまでであり、3種類の攻撃を
  37. 前2つの無敵時間が終わらないうちに当てると最後の3つ目は無敵時間が続く限り連続ヒットする。
  38. これが連続ヒットバグの正体である。
  39. ちなみに、なぜだか知らないが地上の基本攻撃と空中の基本攻撃は別攻撃扱いらしい。…なぜ。
  40.  
  41. Updated in 2012/09/14(FRI) ver 0.1
  42. ->とりあえず実践で使える出来になったのでRC版とします。
  43. ->不要な判定は表示しない仕組みの実装。例えばハートに対して攻撃受理判定とかろうそくに対して攻撃/接触判定とか。
  44. 同時に、被接触判定において、「攻撃を素直に受ける場合」は赤で、「攻撃をはじく場合」は青で表示するようにした。
  45. ->これでもまだちょっとだけ不満はあったりするので解決策を見つけ次第何とかする予定です。
  46. でもこれで一応満足するだけの出来にはなりましたので、このスクリプトの開発は一段落したものとします。
  47.  
  48. Updated in 2012/09/14(FRI) ver 0.15
  49. ->スプライトの当たり判定の範囲を示す数値の扱いが符号ありだったのを符号なしに変更。
  50. これにより、ドラキュラファントム2のゲロビの攻撃/接触判定が表示されるように。
  51. ->不要な敵のHP表示を抑えた。
  52.  
  53. Updated in 2012/09/14(FRI) ver 0.16
  54. ->マイナーアップデート。持ってるサブウェポンとあと何回使えるかの表示を追加。
  55. スペースの都合上、ステラソード投げはShurikenと表記しました。
  56.  
  57. Updated in 2012/09/15(SAT) ver 0.2 without fillbox
  58. ->他機との干渉属性を示すアドレス(byte)のうち、下位ビットしかわかっていなかったのが上位ビットまで
  59. その役割が分かったため、その辺の事実装しました。
  60. ->とりあえずfillboxが排除されたエミュレータ―において動くようにコードを修正しました。
  61. 非常に納得いかないけど。というのも、fillboxって便利ジャン。
  62.  
  63. ]]--
  64.  
  65. while (true) do
  66.    
  67.  
  68.     --カメラのXとYを読み込んでグリッド表示
  69.     --どっちでもいいんだろうけど今回はgocha先生が特定したアドレスを使わせてもらいました。
  70.     --CameraX=memory.readwordsigned(0x03072B2C)
  71.     --CameraY=memory.readwordsigned(0x03072B2E)
  72.     CameraX=memory.readwordsigned(0x0200A446)
  73.     CameraY=memory.readwordsigned(0x0200A44A)
  74.     gridx=CameraX%16
  75.     gridy=CameraY%16
  76.     for line=0,255,16 do
  77.         gui.text(line-gridx,153,CameraX-gridx+line)
  78.         gui.text(0,line-gridy-3,CameraY-gridy+line)
  79.         gui.line(0,line-gridy,255,line-gridy,0x00FFFF88)
  80.         gui.line(line-gridx,0,line-gridx,255,0x00FFFF88)
  81.         gui.line(0,line-gridy+8,255,line-gridy+8,0x00FFFF33)
  82.         gui.line(line-gridx+8,0,line-gridx+8,255,0x00FFFF33)
  83.     end
  84.  
  85.     --自機の各種ステータス
  86.  
  87.     --自機のHPを読み込みます。最大HPもついでです。
  88.     currentHP=memory.readword(0x0201854E)
  89.     MaxHP=memory.readword(0x02018786)
  90.  
  91.     --自機のMPを読み込みます。最大MPもついでです。
  92.     currentMP=memory.readword(0x02018550)
  93.     MaxMP=memory.readword(0x02018788)
  94.  
  95.     --自機のハート数を表示します。最大数もついでです。
  96.     currentHeart=memory.readword(0x02018794)
  97.     MaxHeart=memory.readword(0x0201878A)
  98.    
  99.     --自機のサブウェポンを読み取ります。
  100.     currentSubWeapon=memory.readbyte(0x0201877E)
  101.  
  102.     --自機の向き
  103.     RightLeft=memory.readbyte(0x02000478) --0x40以上がLeft
  104.  
  105.     --自機のスピードを表示。
  106.     myspeedx=memory.readwordsigned(0x0200046A)
  107.     myspeedy=memory.readwordsigned(0x0200046E)
  108.     myspeeddotx=(memory.readword(0x02000468))/65536
  109.     myspeeddoty=(memory.readword(0x0200046C))/65536
  110.  
  111.     --自機の基本攻撃判定の元
  112.     mt1=memory.readbytesigned(0x03001A28)
  113.     mt2=memory.readbytesigned(0x03001A29)
  114.     mt3=memory.readbytesigned(0x03001A2A)
  115.     mt4=memory.readbytesigned(0x03001A2B)
  116.  
  117.     --自機の被接触判定の元
  118.     MyJudgeLeftEdge=memory.readwordsigned(0x03001A20)
  119.     MyJudgeRightEdge=memory.readwordsigned(0x03001A24)
  120.     MyJudgeUpEdge=memory.readwordsigned(0x03001A22)
  121.     MyJudgeDownEdge=memory.readwordsigned(0x03001A26)
  122.  
  123.  
  124.  
  125.     --HP表示のための整列用変数
  126.     j=0
  127.     k=0
  128.     --敵・・・のつもりだったんだけど各種スプライト?オブジェクト?の意味が強くなりました。
  129.     for i=10,247,1 do
  130.         hpflag=0
  131.         --+78→左右どっちを向いている?
  132.         --03001A20+0x00000008*(ObjNumber+1)でとりあえずは当たり判定のアドレスが求められればよかった…。けどそんなことなかった
  133.         ObjNumber=memory.readbyte(0x0200008B+(i*0x00000080))
  134.  
  135.         --スプライトの外部干渉に関するステータス。詳しくは資料の方を見てください。
  136.         eneStatus=memory.readbyte(0x0200008A+i*0x00000080)
  137.  
  138.         --敵の無敵時間
  139.         eneInvis1=memory.readbytesigned(0x0200008E+i*0x00000080)
  140.         eneInvis2=memory.readbytesigned(0x0200008F+i*0x00000080)
  141.  
  142.         --画面上の座標を求めます。
  143.         enedispx=memory.readwordsigned(0x02000062+(i*0x00000080))
  144.         enedispsubx=memory.readword(0x02000060+(i*0x00000080))/65536
  145.         enedispsuby=memory.readword(0x02000060+4+(i*0x00000080))/65536
  146.         enedispy=memory.readwordsigned(0x02000062+4+(i*0x00000080))
  147.  
  148.         --何でもいいからオブジェクトだかスプライトだかの位置を知らせます。邪魔にならない程度に。
  149.         gui.box(enedispx-1,enedispy-1,enedispx+1,enedispy+1,"#ffff0066","#ffff0066")
  150.  
  151.         --残りHPです。
  152.         enehp=memory.readwordsigned(0x02000054+(i*0x00000080))
  153.        
  154.         --敵機の攻撃/接触判定です。自分で発射した飛び道具の攻撃判定も表示できます。
  155.        
  156.         eneAJudgeStartX=memory.readbytesigned(0x030019E8+i*0x00000008)
  157.         eneAJudgeStartY=memory.readbytesigned(0x030019E9+i*0x00000008)
  158.         eneAJudgeRangeX=memory.readbytesigned(0x030019EA+i*0x00000008)
  159.         eneAJudgeRangeY=memory.readbytesigned(0x030019EB+i*0x00000008)
  160.  
  161.         --敵機の被接触判定です。
  162.         eneJudgeStartX=memory.readbytesigned(0x030019EC+i*0x00000008)
  163.         eneJudgeStartY=memory.readbytesigned(0x030019ED+i*0x00000008)
  164.         eneJudgeRangeX=memory.readbytesigned(0x030019EE+i*0x00000008)
  165.         eneJudgeRangeY=memory.readbytesigned(0x030019EF+i*0x00000008)
  166.        
  167.  
  168.         --構造体チックなもののメンバから判定を格納したアドレス特定できるのが一番よかったんだけどなぁ…
  169.         --[[
  170.         eneAJudgeStartX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+0)
  171.         eneAJudgeStartY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+1)
  172.         eneAJudgeRangeX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+2)
  173.         eneAJudgeRangeY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+3)
  174.         eneJudgeStartX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+4)
  175.         eneJudgeStartY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+5)
  176.         eneJudgeRangeX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+6)
  177.         eneJudgeRangeY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+7)
  178.         ]]--
  179.  
  180.  
  181.  
  182.         --HP及び無敵時間表示部分。自機と何かしら関わることが出来てかつHPを持つ者のみを敵と認識する感じです。ただしシャドウはモニタリング不可
  183.        
  184.  
  185.  
  186.  
  187.  
  188.  
  189.         --例によって右か左かで処理が変わります。
  190.         eneRightLeft=memory.readbyte(0x02000078+(i*0x00000080))  
  191.    
  192.         --最下位ビットが1であればこの時点で自機と何かしら関わることが出来ると判断します。
  193.         --最下位ビットが0だった場合はただの見せ物で、自機とは何も関わらないと判断します。
  194.         --gui.text(enedispx,enedispy,string.format("%xAddress\n0x%08x\n0x%08x\n%x",eneStatus,0x02000010+i*0x00000080,0x030019E8+i*0x00000008,ObjNumber))
  195.         if(eneStatus%2==1) then
  196.             hpflag=1
  197.            
  198.         GuardColor=0x0000ff00
  199.            
  200.             --最上位ビットの判定。よく分からない。
  201.             if(eneStatus>0x00000080) then
  202.                 --紫色で表示する。
  203.                 GuardColor=0xff00ff00
  204.                 eneStatus=eneStatus-0x00000080
  205.             end
  206.             --7ビット目の判定。およそすべての攻撃が弾かれるはず
  207.             if(eneStatus>0x00000040) then
  208.                 --黒で表示する
  209.                 GuardColor=0x00000000
  210.                 eneStatus=eneStatus-0x00000040
  211.  
  212.             end
  213.             --6ビット目の判定。溜め打ちのみ通す
  214.             if(eneStatus>0x00000020) then
  215.                 --白で表示する
  216.                 GuardColor=0xffffff00
  217.                 eneStatus=eneStatus-0x00000020
  218.             end
  219.             --5ビット目の判定。溜め打ちと基本攻撃のみ通す
  220.             if(eneStatus>0x00000010) then
  221.                 --水色で表示する
  222.                 GuardColor=0x00ffff00
  223.                 eneStatus=eneStatus-0x00000010
  224.             end
  225.            
  226.  
  227.  
  228.             --敵の被接触判定表示カラー。ダメージ通る時は赤、通らず弾かれるときは青です。
  229.             --4ビット目が1だった場合には攻撃をはじくと判断します。0なら素直に攻撃を受けます。
  230.             if(eneStatus>=8) then
  231.                 --弾きます
  232.                 eneStatus=eneStatus-8
  233.                 eneRecvCol=GuardColor
  234.             else
  235.                 --弾きません
  236.                 eneRecvCol=0xff000000
  237.             end
  238.             if(eneRightLeft<0x40) then
  239.  
  240.                 --攻撃/接触判定を四角形で表示したいのでその四隅を作る
  241.                 eneAJudgeX1=enedispx+eneAJudgeStartX-1
  242.                 eneAJudgeX2=eneAJudgeX1+eneAJudgeRangeX
  243.                 eneAJudgeY1=enedispy+eneAJudgeStartY
  244.                 eneAJudgeY2=eneAJudgeY1+eneAJudgeRangeY
  245.  
  246.                 --被接触判定を四角形で表示したいのでその四隅を作る
  247.                 eneJudgeX1=enedispx+eneJudgeStartX-1
  248.                 eneJudgeX2=eneJudgeX1+eneJudgeRangeX
  249.                 eneJudgeY1=enedispy+eneJudgeStartY
  250.                 eneJudgeY2=eneJudgeY1+eneJudgeRangeY
  251.  
  252.                 --eneStatusを2進にしたときに3ケタ目が1だった場合は被接触判定は表示しません。
  253.                 --その際のカラーはeneRecvColとして4ビット目読み込み処理で決めています。
  254.                 if(eneStatus<4) then
  255.                     --被接触判定表示
  256.                     gui.box(eneJudgeX1+1,eneJudgeY1+1,eneJudgeX2-1,eneJudgeY2-1,string.format("#%08x",eneRecvCol+0x00000066),string.format("#%08x",eneRecvCol+0x000000aa))
  257.  
  258.                 else
  259.                     --表示せず、次の下位ビットの判定のために引き算しておきます。
  260.                     eneStatus=eneStatus-4
  261.                 end
  262.  
  263.                 --eneStatusを2進にしたときに2ケタ目が1だった場合は、攻撃/接触判定を表示しません。
  264.                 if(eneStatus>=2) then
  265.                     --何も表示しない上にこれ以下のビットはもう見ないので何も書かない。
  266.                 else
  267.                     --攻撃/接触判定表示
  268.                     gui.box(eneAJudgeX1,eneAJudgeY1,eneAJudgeX2,eneAJudgeY2,"#00ff0044","#0x00ff00aa")
  269.                 end
  270.  
  271.             else
  272.                 --右向き
  273.                 --↑と同じなのでコメントは省略します。
  274.                 eneAJudgeX1=enedispx-eneAJudgeStartX
  275.                 eneAJudgeX2=eneAJudgeX1-eneAJudgeRangeX
  276.                 eneAJudgeY1=enedispy+eneAJudgeStartY
  277.                 eneAJudgeY2=eneAJudgeY1+eneAJudgeRangeY
  278.  
  279.                 eneJudgeX1=enedispx-eneJudgeStartX
  280.                 eneJudgeX2=eneJudgeX1-eneJudgeRangeX
  281.                 eneJudgeY1=enedispy+eneJudgeStartY
  282.                 eneJudgeY2=eneJudgeY1+eneJudgeRangeY
  283.                 if(eneStatus<4) then
  284.                     gui.box(eneJudgeX1-1,eneJudgeY1+1,eneJudgeX2+1,eneJudgeY2-1,string.format("#%08x",eneRecvCol+0x00000066),string.format("#%08x",eneRecvCol+0x000000aa))
  285.                    
  286.                 else
  287.                     eneStatus=eneStatus-4
  288.                 end                    
  289.                 if(eneStatus<2) then
  290.                     gui.box(eneAJudgeX1,eneAJudgeY1,eneAJudgeX2,eneAJudgeY2,"#00ff0044","#0x00ff00aa")
  291.                 end
  292.             end
  293.         end
  294.  
  295.         if( enehp>0) then
  296.                                          
  297.             if( j>16 ) then
  298.                 k=k+1
  299.             end
  300.  
  301.             --HPが残っている敵機がいたら順次表示します。
  302.             gui.text(30+k*48,16+j*8,string.format("%d,%d,%d",enehp,eneInvis1,eneInvis2))
  303.             --gui.text(enedispx,enedispy,enehp,0x00ffffff)
  304.             j=j+1
  305.         end
  306.  
  307.     end
  308.  
  309.     --自機の情報開示。
  310.  
  311.     --右向きか左向きかで処理は変わりますよっと
  312.     if( RightLeft>=64 ) then
  313.         --左向き
  314.  
  315.         --自機のスプライトに対する被接触判定を白枠で表示します。
  316.         gui.box(MyJudgeRightEdge-1,MyJudgeUpEdge+1,MyJudgeLeftEdge,MyJudgeDownEdge,"#00000000","#ffffffff")
  317.  
  318.         --自機の壁との接触判定をピンク枠で表示します。ただし、右端と下端は白いのとかぶってます。
  319.         gui.box(MyJudgeRightEdge-1,MyJudgeUpEdge+3,MyJudgeLeftEdge+2,MyJudgeDownEdge,"#00000000","#ff00ffff")
  320.  
  321.         --自機の基本攻撃判定を緑枠で表示します。
  322.         hanteir=MyJudgeRightEdge-mt1-6-1
  323.         hanteiu=MyJudgeDownEdge+(mt2)+1
  324.         hanteil=hanteir-mt3+1
  325.         hanteid=hanteiu+(mt4)-1
  326.         gui.box(hanteil-1,hanteiu-1,hanteir+1,hanteid+1,"#00000000","#00ff00ff")
  327.    
  328.     else
  329.         --右向き
  330.         --以下左向きと同じ
  331.         gui.box(MyJudgeLeftEdge,MyJudgeUpEdge+1,MyJudgeRightEdge-1,MyJudgeDownEdge,"#00000000","#ffffffff")
  332.         gui.box(MyJudgeLeftEdge+2,MyJudgeUpEdge+3,MyJudgeRightEdge-1,MyJudgeDownEdge,"#00000000","#ff00ffff")
  333.  
  334.         hanteil=MyJudgeLeftEdge+mt1+6
  335.         hanteiu=MyJudgeDownEdge+(mt2)+1
  336.         hanteir=hanteil+mt3-1
  337.         hanteid=hanteiu+(mt4)-1
  338.         gui.box(hanteil-1,hanteiu-1,hanteir+1,hanteid+1,"#00000000","#00ff00ff")
  339.     end
  340.  
  341.  
  342.     gui.text(16,0,"X Speed:" .. myspeedx+myspeeddotx)
  343.     gui.text(16,8,"Y Speed:" .. myspeedy+myspeeddoty)
  344.     gui.text(126,0,"HP    : " .. currentHP .. "/" .. MaxHP)
  345.     gui.text(126,8,"MP    : " .. currentMP .. "/" .. MaxMP)
  346.     gui.text(126,16,"Heart : " .. currentHeart .. "/" .. MaxHeart)
  347.     if(currentSubWeapon==1) then
  348.         WeaponStr=string.format("Weapon: %d knives remain",currentHeart/1)
  349.     elseif(currentSubWeapon==2) then
  350.         WeaponStr=string.format("Weapon: %d axes remain",currentHeart/4)
  351.     elseif(currentSubWeapon==3) then
  352.         WeaponStr=string.format("Weapon: %d crosses remain",currentHeart/5)
  353.     elseif(currentSubWeapon==4) then
  354.         WeaponStr=string.format("Weapon: %d Water remain",currentHeart/3)
  355.     elseif(currentSubWeapon==5) then
  356.         WeaponStr=string.format("Weapon: %d Bible remain",currentHeart/3)
  357.     elseif(currentSubWeapon==6) then
  358.         WeaponStr=string.format("Weapon: %d knackles remain",currentHeart/8)
  359.     elseif(currentSubWeapon==7) then
  360.         WeaponStr=string.format("Weapon: %d Shuriken remain",currentHeart/5)
  361.     else
  362.         WeaponStr=string.format("Weapon: No Weapons")
  363.     end
  364.     gui.text(126,24,WeaponStr)
  365.    
  366.     --フレーム等の情報も自分で開いちゃいました。
  367.     if (vba.lagged()==true) then
  368.         gui.text(22,138,"Frames:" .. vba.framecount() .. ":*" .. vba.lagcount(),string.format("#%08x",0xff0000ff))
  369.     else
  370.         gui.text(22,138,"Frames:" .. vba.framecount() .. ":" .. vba.lagcount())
  371.     end
  372.  
  373.     if(movie.active()==false) then
  374.         --ムービーがロードされていないとこうです。
  375.         --gui.drawbox(0,0,500,500,0x00000088,0x00000088)
  376.         --gui.text(50,50,"Movie is NOT LOADED!!")
  377.     end
  378.     vba.frameadvance()
  379. end
  380.      
  381. --[[
  382.  
  383. 現行の問題点
  384. ・デビルのゲロビが表示されない。
  385. ->仕組みがいまだに分かっておらず、お手上げ状態
  386.  
  387. ・きょだいはんぎょじんの回転時の謎の判定が消えない。
  388. ->残しても別にいいんだけどなんか気持ち悪い
  389.  
  390. ・マクシームのくるくる回転やライダーキックの判定が、別のアクションをするまで消えない。
  391. ->残すべきだった。マジで残すべき。理由は現行最速TASを見ると分かる。
  392. くるくる判定が残ってる状態でライダーキックやると一瞬だけくるくるの判定でキックが行われるので、
  393. その状態を見るためにも残すべき。というか「その発想はなかった」
  394. (追記)のりおサン曰く、ただの偶然らしいです…。
  395.  
  396. ・ゴーレムの落石攻撃で被接触判定なんて必要ないはずなのに表示される問題。
  397. ->ちゃんと被接触判定がありました。何でこうなってんの
  398.  
  399. ・シャドウのHP表示ができない。
  400. ->これは以前からの謎。余裕があれば原因を探っていきたいところ。
  401.      
  402. 今後やってみたいこと
  403. ・クリティカルヒットってどういう条件でおこるもの?
  404.  
  405. ]]--
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement