LunaDLL
対応
ここではLunaDLLについて解説していきます
もくじ。
- 初心者のためのQ&A
- チュートリアル
- Lunadll.txtを使う
- 条件
- アクション
- はじめにすること
- コードの構造
- 条件「#」
- コメント
- コマンド
- 最後に
- コードの例
- 基本的なブロックその1
- 基本的なブロックその2
- 基本的なブロックその3
- 悪い例
- 複数のプレイヤーキャラクターをブロックする
- チートの入力をブロックする(lunadll version 7+)
- ほかいろいろ
- ボスのHPを変更する
- イベントを実行する(lunadll version 7+)
- ちゃんと動いてる?
- 残機を二倍にしちゃう?
- カスタムイベント(翻訳中)
- コードの例
- 重力を変えるコード
- 質問や要望はこちら
初心者のためのQ&A
Q.LunaDLLってなに!?
A.SMBXの機能を拡張するものです。Luna GameやLunar Magicとは一切関係ありません。
Q.どこでDLするんじゃ
A.ここのLunaDLL.dllをクリックしましょう。
Q.どうやってインストールするの
A.smbx.exeが置いてあるフォルダにおいてくださいね。
Q.セキュリティソフトが反応してるんだけど
A.安全です。無視してください。
Q.どうやってステージにLunaDllを適用するの
A.ステージのフォルダ(素材とか入れるところ)を作ってその中に「lunadll.txt」というテキストファイルを作る。
そしてそのテキストファイルにコードを打ち込む。
Q.何も起きないんだけど
A.「DebugPrint,0,0,0,0,0,0」というコードを書いてステージをプレイしてください。
画面左下に文字列が表示されたらコードに問題があります。されなければ配置場所などが正しくない可能性があります。
チュートリアル
ここにあるチュートリアルの翻訳です。
誤訳や直訳もあるのであくまで参考程度に。
というか英語読めるくらいじゃないとこれ難しいと思う。
ツクールかウディタを使いこなせていたら楽にできるかもしれない。
...
Lunadll.txtを使う
まずは何をしたいのか考えましょう。
最初の方は簡単なことを考えた方がいいでしょうね。
条件とアクションで考えていきましょう。
メイドイン俺で言うきっかけとアクションですね。
条件
・ステージをロードした時に
・常に
・セクション1にいるときに
・セクション2にいるときに
・特定のブロックに触れている時に
・特定の文字列を入力した時に
アクション
・プレイヤーキャラクターを変える
・状態を変える
・ストックの中身を変える
・効果音を鳴らす
・BGMを変える
・文字列を表示する
はじめにすること
上にも書いてあるようにLunaDLLを使いたいステージのフォルダを作り、その中に「lunadll.txt」というテキストファイルを作ってください。
コードの構造
大きく分けて四つあります。
下のほうに書いてあるコードの例と合わせて見るとわかりやすいかも?
条件「#」
ステージをロードした時にとか、そういうの。
#の後ろには数字を入れます。
#-1 はステージをロードした時に
#0 は常に
#1 はセクション1にいるときに
#2 はセクション2にいるときに
…
#21 はセクション21にいるときに
#22から#1000まではイベントやブロックを指定する高度な設定です。詳しくはわかりません(´・ω・`)
コメント
「//」はREMを書く。
ということは後ろは読み込まれません。
つまりメモに使えるわけです。
複雑なスクリプトはコメントを入れおくと管理が楽になるでしょう。
コマンド
コマンドはLunaDLLで最も重要で最も複雑な部分です。
全てのコマンドを覚えるのは難しいでしょう。
表などを見て慣れていくのがいいと思います。
Kill,0,0,0,0,0,0
↑コマンドの例
"Kill" この最初の部分はコマンド名です。
コマンドは何をするかを示します。
"Kill" は何かを殺す。
このコマンドを "Infinite flying"(無限に飛ぶ)にした場合、プレイヤーは無限に飛ぶことができるようになり…ません。
コマンド名の横にある六つの数字を変えなければなりません。
各数字にはそれぞれ意味があります。
1.ターゲット [#ze4e93f3]
左から一番目の数字はターゲット、つまりスクリプトの対象を示します。
プレイヤーは常に0であり、NPCはそれぞれのIDの数字です。
例えばNPCの"Key"(SMWのカギ)にしたい場合、ID番号38を入力しなければなりません。
NPCのIDはこちら
もっと見やすいのはこちら(英語です)
2.3.4.オプション
左から二、三、四番目の数字はオプションを設定します。
コマンドによって意味は違います。
コマンドリファレンスを確認してください。
5.実行時間
左から五番目の数字は実行時間をフレームで指定します。
0の場合、ずっと続きます。
SMBXは一秒60フレームですので、三秒間実行したい場合、60×3で180と入力します。
6.その他
左から五番目の数字は主に文字を入力します。
特に使うことがない場合は0にしておいてください。
最後に
コードの最後には#ENDをつけましょう。
コードの例
使えそうなコードを解説付きで置いておきます。
...
基本的なブロックその1
#-1
FilterToBig,0,0,0,0,0,0
#END
FilterToBigはキノコ状態以上のとき、強制的にキノコ状態にするコマンド。
#-1とついているのでステージを読み込むときだけ実行されます。
基本的なブロックその2
#-1
FilterMount,0,0,0,0,0,0
#END
Mountとはヨッシーとくつとクッパクラウンのこと
FilterMountはヨッシーとくつとクッパクラウンを強制的に消去するコマンドです。
基本的なブロックその3
#2
FilterReservePowerup,0,0,0,0,180,0
#END
FilterReservePowerupはストックのアイテムを強制的に消去するコマンドです。
#2とついているのでセクション2にいるときのみ実行されます。
左から五番目の数字が180なので三秒間実行されます。
悪い例
#-1
InfiniteFlying,0,0,0,0,0,0
#END
これは悪い例ですね。
InfiniteFlyingはしっぽ/たぬきで無限に空を飛べるようにするコマンドです。
しかし#-1だとステージ読み込み時のみ実行される。
つまり読み込む時しか無限に空を飛べません。
結果的に無限に空を飛ぶことはできません。
このようにコマンドによって条件はよく考えましょう。
複数のプレイヤーキャラクターをブロックする
#-1
// キノピオを強制的にマリオに変える
FilterPlayer,0,4,1,0,0,0
// ピーチを強制的にマリオに変える
FilterPlayer,0,3,1,0,0,0
#END
この例ではプレイヤーキャラクターがキノピオかピーチ姫の場合、強制的にマリオに変えます。
FilterPlayerは特定のプレイヤーキャラクターを別のプレイヤーキャラクターに変えるコマンドで、
左から二番目の数字にはブロックするプレイヤーキャラクターのID番号を、
左から三番面の数字にはブロックしたあと強制的に変えるプレイヤーキャラクターのID番号を入力します。
ID表はこちら
キャラクター | ID番号 |
マリオ | 1 |
ルイージ | 2 |
ピーチ姫 | 3 |
キノピオ | 4 |
リンク | 5 |
チートの入力をブロックする(lunadll version 7+)
#0
ClearInputString,0,0,0,0,0,0
#END
ClearInputStringはキーボード入力バッファを消去します
つまり、チートの入力をブロックします。
ほかいろいろ
#-1
FilterPlayer,0,1,5,0,0,0
#0
ShowText,0,300,300,3,0,HI
#1
ShowText,0,200,400,3,0,ISN'T IT HARD TO SEE WITH ALL THIS TEXT IN THE WAY?
#2
SFX,10,0,0,0,0,0
FilterToSmall,0,0,0,0,1,0
FilterReservePowerup,0,0,0,0,1,0
FilterMount,0,0,0,0,1,0
#END
いろいろなコマンド。
効果音はSMBXに入ってるもの以外も使うことができる。
文字列のフォントは3種類ある。
ボスのHPを変更する
#1
// Set the hit counter of NPCs of type 209 (mother brains) in section 1 to 9 hits
AT_SetHits,209,1,9,0,1,0
#END
※私のPCだとエラーが発生しました。動作した方解説を書いてくださいお願いします。
イベントを実行する(lunadll version 7+)
#1
TriggerSMBXEvent,0,0,0,0,1,MyEvent
#END
「MyEvent」という名前のイベントを実行します。
簡単ですね。
ちゃんと動いてる?
#0
// スクリプトに関する情報を画面左下に表示します。
DebugPrint,0,0,0,0,0,0
#END
DebugPrintはスクリプトに関する情報を画面左下に表示するコマンド。
単にLunaDLLが動いているかどうか確認するのにも使えますね。
残機を二倍にしちゃう?
#1
// メモリ場所 0x00B2C5AC の値を二倍にします
MemAssign,0x00B2C5AC,2,3,0,1,f
#END
これはメモリの操作命令で最も複雑なことです。
MemAssignはグローバル変数で選択されたメモリ位置への操作を行います。
SMBXはあらゆるデータをメモリで記憶しています。
例えば、残機の数とか、コインの枚数とか、スコアとか、何のモードかとか
残念ながらメモリが何を含んでいるか確認する方法はありません。
デバッガなどを使えばできるかもしれませんね。
0x00B2C5ACは残機のメモリです。
メモリの内容がなにかわかっていればある程度操作することができます。
左から二番目の数字はオペランド、左から三番目の数字は操作内容です
数字 | |
0 | 代入 |
1 | 加算 |
2 | 減算 |
3 | 乗算 |
4 | 除算 |
5 | XOR |
MemAssign,0x00B2C5AC,2,3 の場合、 0x00B2C5AC の値を二倍します。.
MemAssign,0x00B2C5AC,2,2 の場合、0x00B2C5ACの値から2ひきます
MemAssign,0x00B2C5AC,2,1 の場合、0x00B2C5ACの値に2足します
MemAssign,0x00B2C5AC,2,0 の場合、0x00B2C5ACの値を2にします
MemAssign,0x00B2C5AC,2,3,0 左から四番目の数字は未使用なので0にします。
MemAssign,0x00B2C5AC,2,3,0,1 左から五番目は実行する時間です。1にしておかないと値が吹っ飛ぶように変わります。
MemAssign,0x00B2C5AC,2,3,0,1,f 操作するメモリのサイズによって入れる文字が変わります。
文字 | サイズ |
b | 1バイト |
w | 2バイト(ワード) |
dw | 4バイト(ダブルワード) |
f | 4バイトの小数点/浮動小数点 |
df | 8バイトの小数点/浮動小数点 |
1バイトはほぼ使われていません。
2バイトは様々なことに使われています。
4バイトはほぼ使われず、小数型は座標などに使われています
カスタムイベント(翻訳中)
There are many actions you can do with all these commands, but the "time" part
the equation will be lacking unless there are more ways to trigger them besides
entering sections.
Any commands designated under a section header higher than 999 will be marked
as a custom event block.
#1000
SFX,10,0,0,0,0,0
#1001
SFX,11,0,0,0,0,0
Kill,0,0,0,0,1,0
DeleteEventsFrom,1001,0,0,0,1,0
These are two examples of custom event blocks. They need something to trigger
them though. There are many commands that trigger custom events on a condition.
Trigger - All it does is trigger a custom event.
Timer - It can trigger a custom event when it counts down to 0.
BlockTrigger - It can trigger an event when the target touches a certain block.
OnInput - Trigger an event when you press a certain something (lunadll 7+)
OnCustomCheat - Trigger an event when you type something (lunadll 7+)
#0
OnCustomCheat,0,0,0,1000,0,go
#1000
LayerXSpeed,3,0,0,0,0,2.5
#END
Really it's self explanatory. Just type "go" and the layer command is run.
By the way, layer 0 is "default" layer, so 3 is the first custom layer you can
make.
There's actually a terrible problem here. The layer command is set to have
infinite time. If you type "go" about 15,000 times, your game will start
to lag because there are 15,000 commands being run per frame. When you
trigger a custom event, it actually means the event is copied into the
"always section", so events are like blueprints. The solution is to lower the
active time. 1 is fine since the layer doesn't stop.
#0
OnInput,0,1,1,1000,0,0
#1000
OnInput,0,1,1,1001,10,0
#1001
CyclePlayerRight,0,0,0,0,1,0
SFX,0,13,0,0,0,0
#END
Now it's getting complicated.
OnInput triggers when you press a certain button. Param2 is 1, which is "up".
Param3 is also 1, which means it only detects the key press, not holding them
down. With this behavior you can simulate the detection of double taps (or more).
In this code, When you push up the first time, another OnInput (event 1000) is
activated for 10 frames. This also waits for an up key press. If you successfully
double tap, finally, event 1001 is triggered, which switches the character.
#0
OnInput,0,1,1,1000,0,0
#1000
OnInput,0,2,1,1001,20,0
#1001
OnInput,0,3,1,1002,20,0
#1002
OnInput,0,4,1,1003,20,0
#1003
OnInput,0,6,1,1004,20,0
#1004
Kill,0,0,0,0,1,0
DeleteEventsFrom,1003,0,0,0,1,0
#END
A big button sequence. Just a more contrived version of the last one.
#0
Timer,0,1000,1,0,600,0
#1000
Kill,0,0,0,0,1,0
#END
This is mainly about Timer. Timer is a useful command for automatic
repetition or... timing. It activates the custom event specified in its 2nd
param whenever it reaches 0. Param 3 specifies whether or not to display
the timer at the top right of the screen. Param 4 specifies whether or not
the timer should reset itself whenever it reaches 0. 5 is both the frame
countdown time and the time it should reset itself to if it's set to reset.
#0
DeccelerateLayerX,3,0,0,0,0,0.02
BlockTrigger,0,1,2,1000,0,0
BlockTrigger,0,1,4,1001,0,0
#1000
AccelerateLayerX,3,-2,0,0,2,-0.1
#1001
AccelerateLayerX,3,2,0,0,2,0.1
#END
If you put some wood blocks (Block ID 1) on layer 3, this script will
create the illusion that you're pushing them around by running into them
from the sides.
DeccelerateLayerX when active slows a layer (towards 0) by the amount in
param 6. This simulates something like friction/air resistance.
BlockTrigger triggers custom events when the target interacts with a certain
block type from a certain direction.
BlockTrigger,0,1,2,1000,0,0
0 = player triggers the event, 1+ would be NPC IDS
1 = the Block ID
2 = The direction the block should be touched from to trigger. 1=U 2=R 3=D 4=L
1000 = The event to trigger
0 = active time (forever)
0 = unused
Accelerate layer is just the opposite of deccelerate. The second param is the
max speed it'll be allowed to accelerate to.
#0
IfNPC,178,2,0,1000,0,once
#1000
SFX,0,0,0,0,1,kefka.wav
#END
IfNPC triggers an event based on an NPC condition. 178 means the condition is
for axe NPCs. 2 means "no longer exists", so it triggers once the axe is gone.
#0
Trigger,0,1000,0,0,0,0
#1000
Timer,0,1001,1,0,200,0
NPCMemSet,-1,0x46,0xFFFF,0,200,short
ShowText,0,400,550,3,200,YAY!
#1001
Timer,0,1000,1,0,200,0
NPCMemSet,-1,0x46,0x0000,0,200,short
ShowText,0,400,550,3,200,GRR!
#END
Starts the friendly enemy event, which calls the unfriendly enemy event when it
ends, which calls the friendly enemy event again when that ends. Loops forever.
Check the reference to be sure about NPCMemSet and IfNPC.
#0
OnGlobalMem,0x00B2C8C4,0xFFFF,0,1000,0,w
OnGlobalMem,0x00B2C8C4,0,0,1001,0,w
#1000
ShowText,0,100,250,3,1,THOU HATH CHEATED
#1001
ShowText,0,100,250,3,1,THOU HATH NOT CHEATED
#END
OnGlobalMem is a powerful trigger command that activates events based on whatever
memory location you like. It just so happens that 0x00B2C8C4 is an address which
contains a two byte value that represents whether or not you've entered a
cheat code before. This is the memory that's checked to see if you can save,
and it's cleared by the cheat which lets you save again.
OnGlobalMem,0x00B2C8C4,0xFFFF,0,1000,0,w
0x00B2C8C4 = address
0xFFFF = value to check
0 = "equals" operation. 1 checks "greater than", 2 checks "less than"
1000 = activate #1000 if the check is true
0 = last forever
w = check it like a 2 byte value
Remember that either trigger is constantly being activated every frame because
the test is either true or untrue, so one ShowText will be copied per frame.
The ShowText commands must not have an active time of 0, because then the old
ones would never expire while new ones are constantly being added ever frame.
You'd end up with thousands of identical showtext commands being spawned and you
would lag out really quickly.
#0
OnPlayerMem,0xF0,3,1,1000,0,w
#1000
TriggerSMBXEvent,0,0,0,0,1,layerhide
#END
It's almost the same as OnGlobalMem, but the player doesn't have a fixed memory
address, so you use a short offset this time. It just so happens that 0xF0 is the
offset to the memory which contains what character you currently are. To find more
offsets, check the reference at the end of the document.
First, keep in mind that these are the character IDs
0 = invalid
1 = demo
2 = iris
3 = princess
4 = raocow
5 = sheath
OnPlayerMem,0xF0,3,1,1000,0,w
0xF0 = target is player memory offset 0xF0, which contains the character ID
3 = value to test against is 3
1 = operation to perform is "greater than"
1000 = 1000 is the event to trigger if the character ID is greater than 3
0 = active forever
w = check the memory like it's a 2 byte word
#0
InfIniteFlying,0,0,0,0,0,0
PlayerMemSet,0,+0x170,50,0,0,w
These both do the exact same thing. InfiniteFlying is just an easier to understand
wrapper around the same operation.
#-1
MemAssign,0x00B2C5A8,0,0,0,1,w
#0
OnGlobalMem,0x00B2C5A8,0,1,1000,0,w
MemAssign,0x00B2C5A8,0,0,0,0,w
#1000
TriggerRandom,1001,1002,1003,1003,1,0
#1001
FilterToSmall,0,0,0,0,1,0
ShowText,0,200,200,3,60,TRIGGERING 1001
#1002
PlayerMemSet,0,0x112,2,0,1,w
ShowText,0,200,300,3,60,TRIGGERING 1002
#1003
PlayerMemSet,0,0x112,3,0,1,w
ShowText,0,200,400,3,60,TRIGGERING 1003
#END
The comments explain it all.
#0
ShowText,0,300,700,3,0,FAREWELL...
ShowText,0,300,700,3,0,FAREWELL?
ModParam,3,1,2,0,0,FAREWELL...
#END
ModParam is a powerful command that can also totally foul everything up beyond
imagining. It changes the params of other commands. The challenge is identifying
the commands. Param 4 and 6 are used to specify which command you're looking for.
Param 4 is which # section the command is in, and Param 6 must match the text
exactly of the command you want to modify. Since most commands don't use text
you can just write anything in them and then match it later with ModParam.
ModParam,3,1,2,0,0,FAREWELL...
3 = modify the third param (ShowText's Y coordinate)
1 = amount to modify by
2 = modify by subtracting
0 = look in #0 for the command to modify
0 = modify forever
FAREWELL... = the command to modify will have this in the text field
コードの例
ここでは投稿されたコードや筆者が作ったコードなどを書いていきます。
重力を変えるコード
...
#0
MemAssign,0x00B2C6E2,40,0,0,0,w
#0
MemAssign,0x00B2C6DC,40,0,0,0,w
#0
MemAssign,0x00B2C6F4,8,0,0,0,w
#END
ジャンプの高さなどを変えて擬似的に重力が軽いような状態を作ります。
オペランドをいじれば様々な重力を作るとができます。
工事中・・・
質問や要望はこちら
- 最終更新:2016-11-29 00:22:12