見出し画像

【実例紹介】マイクラBEにナイト実装!?コマンドを駆使して聖騎士を目指せ!

割引あり

今回は統合版Minecraftのコマンド機能を利用して、RPG等で良くあるナイトを再現してみました!

本記事を参考にコマンドを実装すると、以下のような実装が可能です:

耐久値を自在に設定
カウンター攻撃による戦略性
使用回数に応じた段階的強化

また、本記事ではコマンドのコピー&ペーストを推奨するため、PCによる操作をお勧めしています。

⚠️注意⚠️
Nintendo Switchの場合、コマンド入力に500文字の制限があり、コマンドや仕組みを一部改変する必要があります。

キーワード:シフト/スニーク検知、耐久値検知


■騎士の定義付け


初めに作りたいもののイメージを湧かせましょう。イメージは具体的であればあるほど良いです!

本記事では騎士は騎士でも、特に聖騎士Paradin)として考えてみました。ネザライト装備を身に纏って暗黒騎士とかもいいですね!一応、PvP(対人)想定でバランス調整しています:

【剣・盾 共通】

  • 一定回数の使用制限あり

  • 一定回数の使用でバフ

【盾】

  • 防御直後の攻撃力上昇(カウンター)

  • 防御し続ける行為に制限

【剣】

  • [アンデッド特攻][火属性][ノックバック]の段階的付与


■機構の全体像


今回実装していく機構は、ざっくり言えば

  1. 使用量[%]の計算と表示

  2. 防御・攻撃の検知と処理

  3. バフの付与

の3種類に分けられます(実際には不可分で互いに連動)。

特に「2」について、技術的には

  • 盾の構え -> シフト検知機構

  • 剣/盾の攻防 -> 耐久値検知機構

により実装されます。


■コマンドの初期設定


まずは大前提として、設定から[チートの実行]及び[コマンドブロックが有効]はONにしましょう。肝心なコマンドブロックは、

/give @s command_block

を実行して受け取りましょう。コマンドブロックはクリエイティブで設置、設定を行います。初期設定では使いません!

次に使用量[%]を計算するために、スコアボードを以下の通り設定しましょう(一行ずつチャットで実行):

/scoreboard objectives add SneakingTick dummy
/scoreboard objectives add SneakingLimit dummy
/scoreboard objectives add SneakingPercent dummy

/scoreboard objectives add WeaponCount dummy
/scoreboard objectives add WeaponLimit dummy
/scoreboard objectives add WeaponPercent dummy

/scoreboard objectives add _Tmp dummy
/scoreboard objectives add _CONST dummy

意味合いとしては、上段3行が盾用変数、中段3行が剣用変数、下段2行が共用変数で、「これから使うよー」という宣言を行っています。

最後に聖騎士となるプレイヤーへの各種パラメータの設定です。聖騎士への転職及び初期化はNPCを介して行います。NPCの名前はテキトーに"転職支援"とでもしておいて、呼び出しましょう:

/summon npc 転職支援 ~~~

NPCの[詳細設定]を開き、聖騎士の志願者にタグ付けスコアの設定を行います。『聖騎士』ボタンの押下時や終了時の処理について書き込んでいきます(見た目、メッセージのカスタムはお好みで!):

【押下時】

/tag @initiator add Paladin

/scoreboard players set @initiator SneakingTick 0
/scoreboard players set @initiator SneakingLimit 600
/scoreboard players set @initiator SneakingPercent 100

/scoreboard players set @initiator WeaponCount 0
/scoreboard players set @initiator WeaponLimit 30
/scoreboard players set @initiator WeaponPercent 100

/scoreboard players set @initiator _Tmp 0
/scoreboard players set @initiator _CONST 0

/replaceitem entity @initiator slot.weapon.offhand 0 shield 1 0 {"item_lock":{"mode":"lock_in_slot"}}

/replaceitem entity @initiator slot.weapon.mainhand 0 golden_sword 1 0
{"rawtext":[{"text":"聖騎士"}]}

Point🔍
SneakingLimit及びWeaponLimitで上限値を決めており、上記では盾が600tick(=30秒)、剣が30回で破損します。変えるならココです。

【終了時】

/enchant @initiator[tag=Paladin,hasitem={item=golden_sword,data=0,location=slot.weapon.mainhand}] smite 1

Point🔍
付与した金の剣(新品)に/enchantによりエンチャントを行っています。実は、新品を渡したと同時に/enchantを実行すると、正しく反映されません!渡してから少し間を置くようにするのがコツです。まぁ、これでも時折失敗しますが。

入力結果・実行結果は以下の通りです:

NPCの[詳細設定]に関するPNG
NPCによる[聖騎士]への転職時の挙動GIF


■%計算機構


ここからは、コマンドブロックをフル活用していきます!今回、使用量の百分率[%]は、カウントダウン形式で考えます。つまりは100%(=新品)の状態から使うほど減少し、最終的には0%(=破損)となります。

考える使用量[%]は以下の式で与えられます:

$$
\newcommand{\st}{\mathrm{SneakingTick}}
\newcommand{\sl}{\mathrm{SneakingLimit}}
\newcommand{\wc}{\mathrm{WeaponCount}}
\newcommand{\wl}{\mathrm{WeaponLimit}}
\begin{align*}
使用量[\%]&=100-\frac{(計数値)}{(上限値)}\times100\\[3.0mm]
&=\left(1-\frac{(計数値)}{(上限値)}\right)\times100\\[3.0mm]
&=\frac{(上限値)-(計数値)}{(上限値)}\times100
\end{align*}\\[3.0mm]
\begin{cases}
(計数値)&=\st,\wc\\
(上限値)&=\sl,\wl
\end{cases}
$$

コマンドの性質上、最後の式が利用しやすいためそれに従います(基本が代入演算子であるため)。コマンドは以下の通りです:

盾(上部)/剣(下部)
%計算機構の配置PNG

【盾】

先頭:[リピート][無条件][動力が必要][遅延0]
後続:[チェーン][条件付き][常時実行][遅延0]

/execute as @a[tag=Paladin] 
run scoreboard players set 
@s _CONST 100
/execute as @a[tag=Paladin] 
run scoreboard players operation 
@s _Tmp = @s SneakingLimit
/execute as @a[tag=Paladin] 
run scoreboard players operation 
@s _Tmp -= @s SneakingTick
/execute as @a[tag=Paladin] 
run scoreboard players operation 
@s _Tmp *= @s _CONST
/execute as @a[tag=Paladin] 
run scoreboard players operation 
@s _Tmp /= @s SneakingLimit
/execute as @a[tag=Paladin] 
run scoreboard players operation 
@s SneakingPercent = @s _Tmp
/execute as @a[tag=Paladin] 
if score @s SneakingTick > @s SneakingLimit 
run scoreboard players operation 
@s SneakingTick = @s SneakingLimit

Point🔍
何が目的のコマンド群であるか、外見からでは判断が付かないため、先頭のコマンドブロックの『ポイントしたときの注意』に「【盾】%表示機構」などと書き入れると分かりやすくなります。

【剣】

上記【盾】のコマンド群を
SneakingTick -> WeaponCount
SneakingLimit -> WeaponLimit
と置き換えて同様に作成。

Point🔍
PCであれば「Sneaking+マウスホイール押下」でコマンドブロックのコピーが可能です。つまりは楽ができます。

レッドストーンの動力を与えればこのように表示されているはずです:

%計算機構のログPNG

ログが鬱陶しい場合には以下のコマンドで対処しましょう:

/gamerule commandblockoutput false
/gamerule sendcommandfeedback false


■%表示機構


アクションバーに盾/剣の使用量[%]を表示させておきましょう!使用量に応じて段階的にバフを掛けていくため、残量をそれっぽく色分けします:

  • (§a): 51~100[%]

  • (§b):  21~50[%]

  • (§6):    1~20[%]

  • (§c):          0[%]

ただ、表示するパラメータが盾と剣の2種類があるため、愚直に全パターンを実装しようとすると総数$${_4\mathrm{C}_1+{}_4\mathrm{P}_2=16}$$個ものコマンドブロックが必要になります。

しかしながらとても便利なことに、以下の通りに設定を行うことでコマンドブロック1個で済みます:

%表示機構の配置PNG

【剣・盾 共通】

[リピート][無条件][動力が必要][遅延0]

/execute as @a[tag=Paladin] 
run titleraw @s actionbar 
{"rawtext":
[
{"translate":"盾:%%7",
"with":
{"rawtext":[
{"selector":"@s[scores={SneakingPercent=0}]"},
{"selector":"@s[scores={SneakingPercent=0..9}]"},
{"selector":"@s[scores={SneakingPercent=0..20}]"},
{"selector":"@s[scores={SneakingPercent=0..50}]"},
{"selector":"@s[scores={SneakingPercent=0..99}]"},
{"selector":"@s[scores={SneakingPercent=0..100}]"},
{"text":"    §c"},
{"text":"    §6"},
{"text":"  §6"},
{"text":"  §b"},
{"text":"  §a"},
{"text":"§a"}
]}
},
{"score":{"name":"@s","objective":"SneakingPercent"}},
{"text":"§r/100[%]"},
{"text":" | "},
{"translate":"剣:%%7",
"with":
{"rawtext":[
{"selector":"@s[scores={WeaponPercent=0}]"},
{"selector":"@s[scores={WeaponPercent=0..9}]"},
{"selector":"@s[scores={WeaponPercent=0..20}]"},
{"selector":"@s[scores={WeaponPercent=0..50}]"},
{"selector":"@s[scores={WeaponPercent=0..99}]"},
{"selector":"@s[scores={WeaponPercent=0..100}]"},
{"text":"    §c"},
{"text":"    §6"},
{"text":"  §6"},
{"text":"  §b"},
{"text":"  §a"},
{"text":"§a"}
]}
},
{"score":{"name":"@s","objective":"WeaponPercent"}},
{"text":"§r/100[%]"}
]}

Point🔍
"translate"及び"with"により、1個のコマンドブロックで全組合せを網羅的に実装しています!詳しくは本記事の#参考資料を参考にして下さい。

実行結果は以下の通りです(実行時に赤石を忘れずに!):

%表示機構のアクションバー反映PNG


■検知と破損処理


この工程が一番の肝です!!!

盾はシフト状態、剣は耐久値減少をトリガーとして、使用限界を迎えたかの処理を加えます。破損処理を行うか否かの判断基準は百分率が0%以下であるか否かとしています:

盾(上部)/剣(下部)
検知と破損処理の配置PNG

【盾】

先頭:[リピート][無条件][動力が必要][遅延0]
後続:[チェーン][条件付き][常時実行][遅延0]

/execute as @a[tag=Paladin] at @s 
if entity @s[hasitem={item=shield,
location=slot.weapon.offhand}] 
if entity @s[y=~1.4,dx=0] 
unless entity @s[y=~1.5,dx=0] 
run scoreboard players add @s SneakingTick 1
/execute as @a[tag=Paladin] at @s 
if entity @s[hasitem={item=shield,
location=slot.weapon.offhand}] 
if entity @s[scores={SneakingPercent=..0}] 
run playsound random.break @s ~~~ 100
/execute as @a[tag=Paladin] 
if entity @s[hasitem={item=shield,
location=slot.weapon.offhand}] 
if entity @s[scores={SneakingPercent=..0}] 
run replaceitem entity @s 
slot.weapon.offhand 0 air 1 0

Point🔍
シフト/スニーク検知の定型文は
/execute as @a at @s if entity @s[y=~1.4,dx=0] unless entity @s[y=~1.5,dx=0] run say
であり、当たり判定がスニークにより変化することを利用しています。

【剣】

[リピート][無条件][動力が必要][遅延0]

/execute as @a[tag=Paladin] 
if entity @s[hasitem={item=golden_sword,
location=slot.weapon.mainhand}] 
unless entity @s[hasitem={item=golden_sword,data=0,
location=slot.weapon.mainhand}] 
run scoreboard players add @s WeaponCount 1

[チェーン][条件付き][常時実行][遅延0]

/execute as @a[tag=Paladin] 
if entity @s[hasitem={item=golden_sword,
location=slot.weapon.mainhand}] 
unless entity @s[hasitem={item=golden_sword,data=0,
location=slot.weapon.mainhand}] 
if entity @s[scores={WeaponPercent=..100}] 
run replaceitem entity @s 
slot.weapon.mainhand 0 air 1 0

⚠️遅延注意⚠️
[チェーン][条件付き][常時実行][遅延

/execute as @a[tag=Paladin] 
unless entity @s[hasitem={item=golden_sword,
location=slot.weapon.offhand}] 
if entity @s[scores={WeaponPercent=..100}] 
run replaceitem entity @s 
slot.weapon.mainhand 0 golden_sword 1 0

⚠️条件注意⚠️
[チェーン][無条件][常時実行][遅延0]

/execute as @a[tag=Paladin] at @s 
if entity @s[hasitem={item=golden_sword,
location=slot.weapon.mainhand}] 
if entity @s[scores={WeaponPercent=..0}] 
run playsound random.break @s ~~~ 100

[チェーン][条件付き][常時実行][遅延0]

/execute as @a[tag=Paladin] 
if entity @s[hasitem={item=golden_sword,
location=slot.weapon.mainhand}] 
if entity @s[scores={WeaponPercent=..0}] 
run replaceitem entity @s 
slot.weapon.mainhand 0 air 1 0

Point🔍
耐久値検知の定型文は
/execute as @a if entity @s[hasitem={item=itemName}] unless entity @s[hasitem={item=itemName,data=0}] run say
であり、耐久値がデータ値により管理されていることを利用しています。

特に注意として3番目のチェーンは[遅延5](tick)としておきましょう(即時実行と設定した場合には、後のエンチャント処理が時折失敗する)。

※今回の耐久値検知においては『hasBrokenSword』
といったタグによって管理する方がスマートですが、
何故かエンチャント処理が失敗してしまいます。
有識者の方が居ましたらお教え頂けると幸いです。

動力を与えた後、サバイバル(或いはアドベンチャー)に変更して動作の確認をしましょう!以下のようになれば成功です:

剣/盾の使用検知と処理GIF


■バフの付与


これが最後の工程です!!

盾は防御時(耐久値減少時)にポーション効果として、剣は常にエンチャント効果として、バフの付与を行います。

ここから先は

4,148字 / 4画像

期間限定 PayPay支払いすると抽選でお得に!

この記事が参加している募集

最後までお読み頂き、誠にありがとうございます。記事の内容にご満足頂けましたら、是非ともサポートのご検討をお願いしたく思います! もしご支援頂ければ、細々と書き綴るnote活動に豊かさが生まれます。頂きました支援金は、存続のための活動資金として大切にお使いしたく思います。