Advertisement
Robert_Ordis

Castlevania Harmony of Dissonance Lua Script by R_O

Sep 14th, 2012
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.86 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. ]]--
  58.  
  59. while (true) do
  60.    
  61.  
  62.     --カメラのXとYを読み込んでグリッド表示
  63.     --どっちでもいいんだろうけど今回はgocha先生が特定したアドレスを使わせてもらいました。
  64.     --CameraX=memory.readwordsigned(0x03072B2C)
  65.     --CameraY=memory.readwordsigned(0x03072B2E)
  66.     CameraX=memory.readwordsigned(0x0200A446)
  67.     CameraY=memory.readwordsigned(0x0200A44A)
  68.     gridx=CameraX%16
  69.     gridy=CameraY%16
  70.     for line=0,255,16 do
  71.         gui.text(line-gridx,153,CameraX-gridx+line)
  72.         gui.text(0,line-gridy-3,CameraY-gridy+line)
  73.         gui.line(0,line-gridy,255,line-gridy,0x00FFFF88)
  74.         gui.line(line-gridx,0,line-gridx,255,0x00FFFF88)
  75.         gui.line(0,line-gridy+8,255,line-gridy+8,0x00FFFF33)
  76.         gui.line(line-gridx+8,0,line-gridx+8,255,0x00FFFF33)
  77.     end
  78.  
  79.     --自機の各種ステータス
  80.  
  81.     --自機のHPを読み込みます。最大HPもついでです。
  82.     currentHP=memory.readword(0x0201854E)
  83.     MaxHP=memory.readword(0x02018786)
  84.  
  85.     --自機のMPを読み込みます。最大MPもついでです。
  86.     currentMP=memory.readword(0x02018550)
  87.     MaxMP=memory.readword(0x02018788)
  88.  
  89.     --自機のハート数を表示します。最大数もついでです。
  90.     currentHeart=memory.readword(0x02018794)
  91.     MaxHeart=memory.readword(0x0201878A)
  92.    
  93.     --自機のサブウェポンを読み取ります。
  94.     currentSubWeapon=memory.readbyte(0x0201877E)
  95.  
  96.     --自機の向き
  97.     RightLeft=memory.readbyte(0x02000478) --0x40以上がLeft
  98.  
  99.     --自機のスピードを表示。
  100.     myspeedx=memory.readwordsigned(0x0200046A)
  101.     myspeedy=memory.readwordsigned(0x0200046E)
  102.     myspeeddotx=(memory.readword(0x02000468))/65536
  103.     myspeeddoty=(memory.readword(0x0200046C))/65536
  104.  
  105.     --自機の基本攻撃判定の元
  106.     mt1=memory.readbytesigned(0x03001A28)
  107.     mt2=memory.readbytesigned(0x03001A29)
  108.     mt3=memory.readbytesigned(0x03001A2A)
  109.     mt4=memory.readbytesigned(0x03001A2B)
  110.  
  111.     --自機の被接触判定の元
  112.     MyJudgeLeftEdge=memory.readwordsigned(0x03001A20)
  113.     MyJudgeRightEdge=memory.readwordsigned(0x03001A24)
  114.     MyJudgeUpEdge=memory.readwordsigned(0x03001A22)
  115.     MyJudgeDownEdge=memory.readwordsigned(0x03001A26)
  116.  
  117.  
  118.  
  119.     --HP表示のための整列用変数
  120.     j=0
  121.     k=0
  122.     --敵・・・のつもりだったんだけど各種スプライト?オブジェクト?の意味が強くなりました。
  123.     for i=10,247,1 do
  124.         hpflag=0
  125.         --+78→左右どっちを向いている?
  126.         --03001A20+0x00000008*(ObjNumber+1)でとりあえずは当たり判定のアドレスが求められればよかった…。けどそんなことなかった
  127.         ObjNumber=memory.readbyte(0x02000028+(i*0x00000080))
  128.  
  129.         --スプライトの外部干渉に関するステータス。詳しくは資料の方を見てください。
  130.         eneStatus=memory.readbyte(0x0200008A+i*0x00000080)
  131.  
  132.         --敵の無敵時間
  133.         eneInvis1=memory.readbytesigned(0x0200008E+i*0x00000080)
  134.         eneInvis2=memory.readbytesigned(0x0200008F+i*0x00000080)
  135.  
  136.         --画面上の座標を求めます。
  137.         enedispx=memory.readwordsigned(0x02000062+(i*0x00000080))
  138.         enedispsubx=memory.readword(0x02000060+(i*0x00000080))/65536
  139.         enedispsuby=memory.readword(0x02000060+4+(i*0x00000080))/65536
  140.         enedispy=memory.readwordsigned(0x02000062+4+(i*0x00000080))
  141.  
  142.         --何でもいいからオブジェクトだかスプライトだかの位置を知らせます。邪魔にならない程度に。
  143.         gui.fillbox(enedispx-1,enedispy-1,enedispx+1,enedispy+1,0xffff0066)
  144.  
  145.         --残りHPです。
  146.         enehp=memory.readwordsigned(0x02000054+(i*0x00000080))
  147.  
  148.         --敵機の攻撃/接触判定です。自分で発射した飛び道具の攻撃判定も表示できます。
  149.         eneAJudgeStartX=memory.readbytesigned(0x030019E8+i*0x00000008)
  150.         eneAJudgeStartY=memory.readbytesigned(0x030019E9+i*0x00000008)
  151.         eneAJudgeRangeX=memory.readbyte(0x030019EA+i*0x00000008)
  152.         eneAJudgeRangeY=memory.readbyte(0x030019EB+i*0x00000008)
  153.  
  154.         --敵機の被接触判定です。
  155.         eneJudgeStartX=memory.readbytesigned(0x030019EC+i*0x00000008)
  156.         eneJudgeStartY=memory.readbytesigned(0x030019ED+i*0x00000008)
  157.         eneJudgeRangeX=memory.readbyte(0x030019EE+i*0x00000008)
  158.         eneJudgeRangeY=memory.readbyte(0x030019EF+i*0x00000008)
  159.  
  160.         --構造体チックなもののメンバから判定を格納したアドレス特定できるのが一番よかったんだけどなぁ…
  161.         --[[
  162.         eneAJudgeStartX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+0)
  163.         eneAJudgeStartY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+1)
  164.         eneAJudgeRangeX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+2)
  165.         eneAJudgeRangeY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+3)
  166.         eneJudgeStartX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+4)
  167.         eneJudgeStartY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+5)
  168.         eneJudgeRangeX=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+6)
  169.         eneJudgeRangeY=memory.readbytesigned(0x03001A20+0x00000008*(ObjNumber+1)+7)
  170.         ]]--
  171.  
  172.         --例によって右か左かで処理が変わります。
  173.         eneRightLeft=memory.readbyte(0x02000078+(i*0x00000080))  
  174.    
  175.         --最下位ビットが1であればこの時点で自機と何かしら関わることが出来ると判断します。
  176.         --最下位ビットが0だった場合はただの見せ物で、自機とは何も関わらないと判断します。
  177.         if(eneStatus%2==1) then
  178.             hpflag=1
  179.  
  180.             --敵の被接触判定表示カラー。ダメージ通る時は赤、通らず弾かれるときは青です。
  181.             --4ビット目が1だった場合には攻撃をはじくと判断します。0なら素直に攻撃を受けます。
  182.             if(eneStatus>=8) then
  183.                 eneStatus=eneStatus-8
  184.                 eneRecvCol=0x0000ff00
  185.             else
  186.                 eneRecvCol=0xff000000
  187.             end
  188.             if(eneRightLeft<0x40) then
  189.  
  190.                 --攻撃/接触判定を四角形で表示したいのでその四隅を作る
  191.                 eneAJudgeX1=enedispx+eneAJudgeStartX-1
  192.                 eneAJudgeX2=eneAJudgeX1+eneAJudgeRangeX
  193.                 eneAJudgeY1=enedispy+eneAJudgeStartY
  194.                 eneAJudgeY2=eneAJudgeY1+eneAJudgeRangeY
  195.  
  196.                 --被接触判定を四角形で表示したいのでその四隅を作る
  197.                 eneJudgeX1=enedispx+eneJudgeStartX-1
  198.                 eneJudgeX2=eneJudgeX1+eneJudgeRangeX
  199.                 eneJudgeY1=enedispy+eneJudgeStartY
  200.                 eneJudgeY2=eneJudgeY1+eneJudgeRangeY
  201.  
  202.                 --eneStatusを2進にしたときに3ケタ目が1だった場合は被接触判定は表示しません。
  203.                 --その際のカラーはeneRecvColとして4ビット目読み込み処理で決めています。
  204.                 if(eneStatus<4) then
  205.                     --被接触判定表示
  206.                     gui.fillbox(eneJudgeX1+1,eneJudgeY1+1,eneJudgeX2-1,eneJudgeY2-1,eneRecvCol+0x00000066)
  207.                     gui.box(eneJudgeX1+1,eneJudgeY1+1,eneJudgeX2-1,eneJudgeY2-1,eneRecvCol+0x000000aa)
  208.                     hpflag=1
  209.                 else
  210.                     --表示せず、次の下位ビットの判定のために引き算しておきます。
  211.                     eneStatus=eneStatus-4
  212.                 end
  213.  
  214.                 --eneStatusを2進にしたときに2ケタ目が1だった場合は、攻撃/接触判定を表示しません。
  215.                 if(eneStatus>=2) then
  216.                     --何も表示しない上にこれ以下のビットはもう見ないので何も書かない。
  217.                 else
  218.                     --攻撃/接触判定表示
  219.                     gui.fillbox(eneAJudgeX1,eneAJudgeY1,eneAJudgeX2,eneAJudgeY2,0x00ff0044)
  220.                     gui.box(eneAJudgeX1,eneAJudgeY1,eneAJudgeX2,eneAJudgeY2,0x00ff00aa)
  221.                 end
  222.  
  223.             else
  224.                 --↑と同じなのでコメントは省略します。
  225.                 eneAJudgeX1=enedispx-eneAJudgeStartX
  226.                 eneAJudgeX2=eneAJudgeX1-eneAJudgeRangeX
  227.                 eneAJudgeY1=enedispy+eneAJudgeStartY
  228.                 eneAJudgeY2=eneAJudgeY1+eneAJudgeRangeY
  229.  
  230.                 eneJudgeX1=enedispx-eneJudgeStartX
  231.                 eneJudgeX2=eneJudgeX1-eneJudgeRangeX
  232.                 eneJudgeY1=enedispy+eneJudgeStartY
  233.                 eneJudgeY2=eneJudgeY1+eneJudgeRangeY
  234.                 if(eneStatus<4) then
  235.                     gui.fillbox(eneJudgeX1-1,eneJudgeY1+1,eneJudgeX2+1,eneJudgeY2-1,eneRecvCol+0x00000066)
  236.                     gui.box(eneJudgeX1-1,eneJudgeY1+1,eneJudgeX2+1,eneJudgeY2-1,eneRecvCol+0x000000aa)
  237.                    
  238.                 else
  239.                     eneStatus=eneStatus-4
  240.                 end                    
  241.                 if(eneStatus<2) then
  242.                     gui.fillbox(eneAJudgeX1,eneAJudgeY1,eneAJudgeX2,eneAJudgeY2,0x00ff0044)
  243.                     gui.box(eneAJudgeX1,eneAJudgeY1,eneAJudgeX2,eneAJudgeY2,0x00ff00aa)
  244.                 end
  245.             end
  246.         end
  247.  
  248.         --HP及び無敵時間表示部分。自機と何かしら関わることが出来てかつHPを持つ者のみを敵と認識する感じです。ただしシャドウはモニタリング不可
  249.         if( enehp>0 and hpflag==1) then
  250.                                          
  251.             if( j>16 ) then
  252.                 k=k+1
  253.             end
  254.  
  255.             --HPが残っている敵機がいたら順次表示します。
  256.             gui.text(30+k*48,16+j*8,string.format("%d,%d,%d",enehp,eneInvis1,eneInvis2))
  257.             --gui.text(enedispx,enedispy,enehp,0x00ffffff)
  258.             j=j+1
  259.         end
  260.     end
  261.  
  262.     --自機の情報開示。
  263.  
  264.     --右向きか左向きかで処理は変わりますよっと
  265.     if( RightLeft>=64 ) then
  266.         --左向き
  267.  
  268.         --自機のスプライトに対する被接触判定を白枠で表示します。
  269.         gui.box(MyJudgeRightEdge-1,MyJudgeUpEdge+1,MyJudgeLeftEdge,MyJudgeDownEdge,0xffffffff)
  270.  
  271.         --自機の壁との接触判定をピンク枠で表示します。ただし、右端と下端は白いのとかぶってます。
  272.         gui.box(MyJudgeRightEdge-1,MyJudgeUpEdge+3,MyJudgeLeftEdge+2,MyJudgeDownEdge,0xff00ffff)
  273.  
  274.         --自機の基本攻撃判定を緑枠で表示します。
  275.         hanteir=MyJudgeRightEdge-mt1-6-1
  276.         hanteiu=MyJudgeDownEdge+(mt2)+1
  277.         hanteil=hanteir-mt3+1
  278.         hanteid=hanteiu+(mt4)-1
  279.         gui.box(hanteil-1,hanteiu-1,hanteir+1,hanteid+1,0x00ff00ff)
  280.    
  281.     else
  282.         --右向き
  283.         --以下左向きと同じ
  284.         gui.box(MyJudgeLeftEdge,MyJudgeUpEdge+1,MyJudgeRightEdge-1,MyJudgeDownEdge,0xffffffff)
  285.         gui.box(MyJudgeLeftEdge+2,MyJudgeUpEdge+3,MyJudgeRightEdge-1,MyJudgeDownEdge,0xff00ffff)
  286.  
  287.         hanteil=MyJudgeLeftEdge+mt1+6
  288.         hanteiu=MyJudgeDownEdge+(mt2)+1
  289.         hanteir=hanteil+mt3-1
  290.         hanteid=hanteiu+(mt4)-1
  291.         gui.box(hanteil-1,hanteiu-1,hanteir+1,hanteid+1,0x00ff00ff)
  292.     end
  293.  
  294.  
  295.     gui.text(16,0,"X Speed:" .. myspeedx+myspeeddotx)
  296.     gui.text(16,8,"Y Speed:" .. myspeedy+myspeeddoty)
  297.     gui.text(126,0,"HP    : " .. currentHP .. "/" .. MaxHP)
  298.     gui.text(126,8,"MP    : " .. currentMP .. "/" .. MaxMP)
  299.     gui.text(126,16,"Heart : " .. currentHeart .. "/" .. MaxHeart)
  300.     if(currentSubWeapon==1) then
  301.         WeaponStr=string.format("Weapon: %d knives remain",currentHeart/1)
  302.     elseif(currentSubWeapon==2) then
  303.         WeaponStr=string.format("Weapon: %d axes remain",currentHeart/4)
  304.     elseif(currentSubWeapon==3) then
  305.         WeaponStr=string.format("Weapon: %d crosses remain",currentHeart/5)
  306.     elseif(currentSubWeapon==4) then
  307.         WeaponStr=string.format("Weapon: %d Water remain",currentHeart/3)
  308.     elseif(currentSubWeapon==5) then
  309.         WeaponStr=string.format("Weapon: %d Bible remain",currentHeart/3)
  310.     elseif(currentSubWeapon==6) then
  311.         WeaponStr=string.format("Weapon: %d knackles remain",currentHeart/8)
  312.     elseif(currentSubWeapon==7) then
  313.         WeaponStr=string.format("Weapon: %d Shuriken remain",currentHeart/5)
  314.     else
  315.         WeaponStr=string.format("Weapon: No Weapons")
  316.     end
  317.     gui.text(126,24,WeaponStr)
  318.    
  319.     --フレーム等の情報も自分で開いちゃいました。
  320.     if (vba.lagged()==true) then
  321.         gui.text(22,138,"Frames:" .. vba.framecount() .. ":*" .. vba.lagcount(),0xff0000ff)
  322.     else
  323.         gui.text(22,138,"Frames:" .. vba.framecount() .. ":" .. vba.lagcount())
  324.     end
  325.  
  326.     if(movie.active()==false) then
  327.         --ムービーがロードされていないとこうです。
  328.         gui.fillbox(0,0,500,500,0x00000088)
  329.         gui.text(50,50,"Movie is NOT LOADED!!")
  330.     end
  331.     vba.frameadvance()
  332. end
  333.      
  334. --[[
  335.  
  336. 現行の問題点
  337. ・デビルのゲロビが表示されない。
  338. ->仕組みがいまだに分かっておらず、お手上げ状態
  339.  
  340. ・きょだいはんぎょじんの回転時の謎の判定が消えない。
  341. ->残しても別にいいんだけどなんか気持ち悪い
  342.  
  343. ・マクシームのくるくる回転やライダーキックの判定が、別のアクションをするまで消えない。
  344. ->残すべきだった。マジで残すべき。理由は現行最速TASを見ると分かる。
  345. くるくる判定が残ってる状態でライダーキックやると一瞬だけくるくるの判定でキックが行われるので、
  346. その状態を見るためにも残すべき。というか「その発想はなかった」
  347. (追記)のりおサン曰く、ただの偶然らしいです…。
  348.  
  349. ・ゴーレムの落石攻撃で被接触判定なんて必要ないはずなのに表示される問題。
  350. ->以前と比べれば量はそんなないので無視したいとこだけど…
  351.  
  352. ・シャドウのHP表示ができない。
  353. ->これは以前からの謎。余裕があれば原因を探っていきたいところ。
  354.      
  355. 今後やってみたいこと
  356. ・クリティカルヒットってどういう条件でおこるもの?
  357.  
  358. ]]--
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement