Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/datapack-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ jobs:
with:
GITHUB_TOKEN: ${{ github.token }}
muteSuccessResult: true
# 文字幅表は必須の引用符にも警告が出るため除外する
ignoreLintPathPattern: |
animated_java:**
core:define_gamerule
lib:text/core/tables.m

- name: Checkout Asset2
if: ${{ github.ref == 'refs/heads/master' }}
Expand Down
3 changes: 3 additions & 0 deletions TheSkyBlessing/data/core/functions/load_once.mcfunction
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ team modify NoCollision collisionRule never
# @within function settings:**
scoreboard objectives add SettingMenuResendTime dummy

#> 文字幅表を読み込む
function lib:text/core/load

#> 各Asset側のロード処理
function #asset:artifact/load
function #asset:mob/load
Expand Down
26 changes: 26 additions & 0 deletions TheSkyBlessing/data/lib/functions/text/_index.d.mcfunction
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#> lib:text/_index.d
# @private

#> Text measurement
# @within function lib:text/**
#declare storage lib:text
#declare storage lib_text_fonts:
#declare score_holder $TextResult
#declare score_holder $TextValid
#declare score_holder $TextAdvance
#declare score_holder $TextUniformAdvance
#declare score_holder $TextUniformGlyph
#declare score_holder $TextUniformEncoded
#declare score_holder $TextWidth
#declare score_holder $TextGlyph
#declare score_holder $TextBold
#declare score_holder $TextOld
#declare score_holder $TextLength
#declare score_holder $TextEncoded
#declare score_holder $TextCursor
#declare score_holder $TextStart
#declare score_holder $TextAuto
#declare score_holder $TextArg
#declare score_holder $TextDigit
#declare score_holder $TextDefaultTotal
#declare score_holder $TextUniformTotal
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#> lib:text/core/component/argument.m
# @within function lib:text/core/component/placeholder

# withの文字列をtextを持つcompoundへ変換し、Piecesへ追加する
data modify storage lib:text Component.Template.Check set value [""]
$data modify storage lib:text Component.Template.Check append from storage lib:text Component.Current.with[$(Index)]
data modify storage lib:text Component.Template.Piece set value {}
execute if data storage lib:text Component.Template.Check[1] run data modify storage lib:text Component.Template.Piece.text set from storage lib:text Component.Template.Check[1]
execute if data storage lib:text Component.Template.Check[1] run data modify storage lib:text Component.Template.Pieces append from storage lib:text Component.Template.Piece
execute if data storage lib:text Component.Template.Check[1] run return 1

# withのcompoundは装飾を含めてPiecesへ追加し、それ以外の型や欠損は拒否する
data modify storage lib:text Component.Template.Check set value [{}]
$data modify storage lib:text Component.Template.Check append from storage lib:text Component.Current.with[$(Index)]
execute unless data storage lib:text Component.Template.Check[1] run return fail
data modify storage lib:text Component.Template.Pieces append from storage lib:text Component.Template.Check[1]
return 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#> lib:text/core/component/children
# @within function
# lib:text/core/component/collect
# lib:text/core/component/children

# Childrenを末尾からNodesへ積み、先頭の子から処理できる順序にする
data modify storage lib:text Component.Node set value {}
data modify storage lib:text Component.Node.Style set from storage lib:text Component.Style
data modify storage lib:text Component.Node.Value set from storage lib:text Component.Children[-1]
data modify storage lib:text Component.Nodes append from storage lib:text Component.Node
data remove storage lib:text Component.Children[-1]
execute if data storage lib:text Component.Children[0] run function lib:text/core/component/children
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#> lib:text/core/component/collect
# @within function
# lib:text/measure_component
# lib:text/core/component/collect

# Nodesから処理対象と継承した装飾を取り出す
data modify storage lib:text Component.Current set from storage lib:text Component.Nodes[-1].Value
data modify storage lib:text Component.Style set from storage lib:text Component.Nodes[-1].Style
data remove storage lib:text Component.Nodes[-1]

# 本文の装飾を継承値へ重ねる
# 配列では最内側の先頭要素の装飾を後続要素にも継承する
data modify storage lib:text Component.Head set from storage lib:text Component.Current
execute if data storage lib:text Component.Head[0] run function lib:text/core/component/head
data modify storage lib:text Component.Style.Bold set from storage lib:text Component.Head.bold
data modify storage lib:text Component.Style.Font set from storage lib:text Component.Head.font

# 配列の要素を積み直し、入れ子も同じ入口で処理する
data modify storage lib:text Component.Children set value []
execute if data storage lib:text Component.Current[0] run data modify storage lib:text Component.Children set from storage lib:text Component.Current
execute if data storage lib:text Component.Children[0] run function lib:text/core/component/children
execute if data storage lib:text Component.Current[0] run return run function lib:text/core/component/collect

# extra を差込み本文とは別に積み、リスト間の要素型の違いを保つ
data modify storage lib:text Component.Children set from storage lib:text Component.Current.extra
execute if data storage lib:text Component.Children[0] run function lib:text/core/component/children

# 動的な本文の参照を拒否する
execute if data storage lib:text Component.Current.selector run return fail
execute if data storage lib:text Component.Current.nbt run return fail
execute if data storage lib:text Component.Current.score run return fail
execute if data storage lib:text Component.Current.keybind run return fail

# 文字列・text・translateから本文を取り出す
# 文字列型のリストへ追加し、本文として扱える文字列だけを受け取る
data modify storage lib:text Component.Check set value [""]
data modify storage lib:text Component.Check append from storage lib:text Component.Current
data modify storage lib:text Component.Check append from storage lib:text Component.Current.text
execute if data storage lib:text Component.Current.translate run data modify storage lib:text Component.Check append from storage lib:text Component.Current.translate
execute unless data storage lib:text Component.Check[1] run return fail

# 装飾付きの本文をPartsへ追加し、translateは差し込む要素へ展開する
data modify storage lib:text Component.Part set from storage lib:text Component.Style
data modify storage lib:text Component.Part.Text set from storage lib:text Component.Check[1]
execute unless data storage lib:text Component.Current.translate run data modify storage lib:text Component.Parts append from storage lib:text Component.Part
execute if data storage lib:text Component.Current.translate unless function lib:text/core/component/translate run return fail

# 差込み本文を積み、本文・extra・兄弟の順で処理する
execute if data storage lib:text Component.Children[0] run function lib:text/core/component/children
execute if data storage lib:text Component.Nodes[0] run return run function lib:text/core/component/collect
return 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#> lib:text/core/component/head
# @within function
# lib:text/core/component/collect
# lib:text/core/component/head

# 入れ子配列の先頭を辿り、兄弟へ継承する装飾の参照先を決める
data modify storage lib:text Component.Head set from storage lib:text Component.Head[0]
execute if data storage lib:text Component.Head[0] run function lib:text/core/component/head
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#> lib:text/core/component/index
# @within function
# lib:text/core/component/placeholder
# lib:text/core/component/index

# 番号末尾の $s を確認し、1始まりの番号を配列添字へ変換する
data modify storage lib:text Component.Template.Char set string storage lib:text Component.Template.Remaining 0 1
data modify storage lib:text Component.Template.IndexEnd set value false
execute if data storage lib:text Component.Template{Char:"$"} run data modify storage lib:text Component.Template.IndexEnd set value true
execute if data storage lib:text Component.Template{Char:"$"} if score $TextArg Temporary matches ..0 run return fail
execute if data storage lib:text Component.Template{Char:"$"} run data modify storage lib:text Component.Template.Remaining set string storage lib:text Component.Template.Remaining 1
execute if data storage lib:text Component.Template{Char:"$"} run scoreboard players add $TextCursor Temporary 1
execute if data storage lib:text Component.Template{Char:"$"} run scoreboard players remove $TextArg Temporary 1
execute if data storage lib:text Component.Template{Char:"$"} run data modify storage lib:text Component.Template.Char set string storage lib:text Component.Template.Remaining 0 1
execute if data storage lib:text Component.Template{IndexEnd:true,Char:"s"} run return 1
execute if data storage lib:text Component.Template{IndexEnd:true} run return fail

# 数字を1桁読み取り、数値へ変換する
scoreboard players set $TextDigit Temporary -1
execute if data storage lib:text Component.Template{Char:"0"} run scoreboard players set $TextDigit Temporary 0
execute if data storage lib:text Component.Template{Char:"1"} run scoreboard players set $TextDigit Temporary 1
execute if data storage lib:text Component.Template{Char:"2"} run scoreboard players set $TextDigit Temporary 2
execute if data storage lib:text Component.Template{Char:"3"} run scoreboard players set $TextDigit Temporary 3
execute if data storage lib:text Component.Template{Char:"4"} run scoreboard players set $TextDigit Temporary 4
execute if data storage lib:text Component.Template{Char:"5"} run scoreboard players set $TextDigit Temporary 5
execute if data storage lib:text Component.Template{Char:"6"} run scoreboard players set $TextDigit Temporary 6
execute if data storage lib:text Component.Template{Char:"7"} run scoreboard players set $TextDigit Temporary 7
execute if data storage lib:text Component.Template{Char:"8"} run scoreboard players set $TextDigit Temporary 8
execute if data storage lib:text Component.Template{Char:"9"} run scoreboard players set $TextDigit Temporary 9
execute if score $TextDigit Temporary matches -1 run return fail

# 番号を10倍して次の桁を足す前に、int上限を超えないか確認する
# $TextArg(更新後)= $TextArg(更新前)× 10 + $TextDigit <= 2147483647
execute if score $TextArg Temporary matches 214748365.. run return fail
execute if score $TextArg Temporary matches 214748364 if score $TextDigit Temporary matches 8.. run return fail
scoreboard players operation $TextArg Temporary *= $10 Const
scoreboard players operation $TextArg Temporary += $TextDigit Temporary

# 読み取った桁を消費し、次の桁または $s を調べる
data modify storage lib:text Component.Template.Remaining set string storage lib:text Component.Template.Remaining 1
scoreboard players add $TextCursor Temporary 1
execute if data storage lib:text Component.Template{Remaining:""} run return fail
return run function lib:text/core/component/index
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#> lib:text/core/component/measure
# @within function lib:text/measure_component

# 各部分を計測し、両設定の送り幅を半px単位で合計する
# 部分ごとの切り上げによる誤差を避けるため、整数幅ではなく送り幅を足す
scoreboard players set $TextDefaultTotal Temporary 0
scoreboard players set $TextUniformTotal Temporary 0
execute if data storage lib:text Component.Parts[0] unless function lib:text/core/component/part run return fail

# 通常表示の送り幅を保存し、合計を整数へ切り上げる
# 以下の合計値は剰余演算前の値で、半px単位
# Return.Default.TextAdvance = $TextDefaultTotal / 2
# $TextWidth = floor($TextDefaultTotal / 2) + ($TextDefaultTotal mod 2) = ceil($TextDefaultTotal / 2)
execute store result storage lib: Return.Default.TextAdvance double 0.5 run scoreboard players get $TextDefaultTotal Temporary
scoreboard players operation $TextWidth Temporary = $TextDefaultTotal Temporary
scoreboard players operation $TextWidth Temporary /= $2 Const
scoreboard players operation $TextDefaultTotal Temporary %= $2 Const
execute if score $TextDefaultTotal Temporary matches 1 run scoreboard players add $TextWidth Temporary 1
execute store result storage lib: Return.Default.TextWidth int 1 run scoreboard players get $TextWidth Temporary

# Unicodeフォント強制時の送り幅を保存し、合計を整数へ切り上げる
# 以下の合計値は剰余演算前の値で、半px単位
# Return.Unifont.TextAdvance = $TextUniformTotal / 2
# $TextWidth = floor($TextUniformTotal / 2) + ($TextUniformTotal mod 2) = ceil($TextUniformTotal / 2)
execute store result storage lib: Return.Unifont.TextAdvance double 0.5 run scoreboard players get $TextUniformTotal Temporary
scoreboard players operation $TextWidth Temporary = $TextUniformTotal Temporary
scoreboard players operation $TextWidth Temporary /= $2 Const
scoreboard players operation $TextUniformTotal Temporary %= $2 Const
execute if score $TextUniformTotal Temporary matches 1 run scoreboard players add $TextWidth Temporary 1
execute store result storage lib: Return.Unifont.TextWidth int 1 run scoreboard players get $TextWidth Temporary
return 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#> lib:text/core/component/part
# @within function
# lib:text/core/component/measure
# lib:text/core/component/part

# フォント名を正規化し、指定フォントで部分文字列を計測する
data modify storage lib:text Work set from storage lib:text Component.Parts[0]
execute if data storage lib:text Work{Font:"default"} run data modify storage lib:text Work.Font set value "minecraft:default"
execute if data storage lib:text Work{Font:"uniform"} run data modify storage lib:text Work.Font set value "minecraft:uniform"
execute if data storage lib:text Work{Font:"space"} run data modify storage lib:text Work.Font set value "minecraft:space"
execute unless data storage lib:text Work{Font:"minecraft:default"} unless data storage lib:text Work{Font:"minecraft:uniform"} unless data storage lib:text Work{Font:"minecraft:space"} run return fail
execute unless data storage lib:text Work{Font:"minecraft:default"} run data modify storage lib:text Work.FixedFont set from storage lib:text Work.Font
execute unless function lib:text/core/measure run return fail

# 通常表示の幅を半px単位に戻して合計し、intのオーバーフローを検出する
# $TextGlyph = Return.Default.TextAdvance × 2
# $TextDefaultTotal(更新後)= $TextDefaultTotal(更新前)+ $TextGlyph
execute store result score $TextGlyph Temporary run data get storage lib: Return.Default.TextAdvance 2
scoreboard players operation $TextOld Temporary = $TextDefaultTotal Temporary
scoreboard players operation $TextDefaultTotal Temporary += $TextGlyph Temporary
execute if score $TextGlyph Temporary matches 0.. if score $TextDefaultTotal Temporary < $TextOld Temporary run return fail
execute if score $TextGlyph Temporary matches ..-1 if score $TextDefaultTotal Temporary > $TextOld Temporary run return fail

# Unicodeフォント強制時の幅を半px単位に戻して合計し、intのオーバーフローを検出する
# $TextGlyph = Return.Unifont.TextAdvance × 2
# $TextUniformTotal(更新後)= $TextUniformTotal(更新前)+ $TextGlyph
execute store result score $TextGlyph Temporary run data get storage lib: Return.Unifont.TextAdvance 2
scoreboard players operation $TextOld Temporary = $TextUniformTotal Temporary
scoreboard players operation $TextUniformTotal Temporary += $TextGlyph Temporary
execute if score $TextGlyph Temporary matches 0.. if score $TextUniformTotal Temporary < $TextOld Temporary run return fail
execute if score $TextGlyph Temporary matches ..-1 if score $TextUniformTotal Temporary > $TextOld Temporary run return fail

# 次の部分へ進む
data remove storage lib:text Component.Parts[0]
execute if data storage lib:text Component.Parts[0] run return run function lib:text/core/component/part
return 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#> lib:text/core/component/placeholder
# @within function lib:text/core/component/translate_next

# %の直後を読み、%%なら本文に%を追加する
execute if data storage lib:text Component.Template{Remaining:""} run return fail
data modify storage lib:text Component.Template.Char set string storage lib:text Component.Template.Remaining 0 1
execute if data storage lib:text Component.Template{Char:"%"} run data modify storage lib:text Component.Template.Pieces append value {text:"%"}

# withの添字を決める
# %sだけで出現順の番号を進め、%N$sは指定番号を使う
scoreboard players operation $TextArg Temporary = $TextAuto Temporary
execute if data storage lib:text Component.Template{Char:"s"} run scoreboard players add $TextAuto Temporary 1
execute unless data storage lib:text Component.Template{Char:"%"} unless data storage lib:text Component.Template{Char:"s"} run scoreboard players set $TextArg Temporary 0
execute unless data storage lib:text Component.Template{Char:"%"} unless data storage lib:text Component.Template{Char:"s"} unless function lib:text/core/component/index run return fail

# 選んだwithの要素を差し込み、不足や未対応の型は失敗にする
execute unless data storage lib:text Component.Template{Char:"%"} store result storage lib:text Component.Template.Index int 1 run scoreboard players get $TextArg Temporary
execute unless data storage lib:text Component.Template{Char:"%"} store success score $TextValid Temporary run function lib:text/core/component/argument.m with storage lib:text Component.Template
execute unless data storage lib:text Component.Template{Char:"%"} unless score $TextValid Temporary matches 1 run return fail

# 書式指定の末尾を消費し、次に切り出す本文の開始位置を更新する
data modify storage lib:text Component.Template.Remaining set string storage lib:text Component.Template.Remaining 1
scoreboard players add $TextCursor Temporary 1
scoreboard players operation $TextStart Temporary = $TextCursor Temporary
return 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#> lib:text/core/component/slice.m
# @within function lib:text/core/component/translate_next

# 原文のStart以上End未満をtextへ切り出し、Piecesへ追加する
data modify storage lib:text Component.Template.Piece set value {}
$data modify storage lib:text Component.Template.Piece.text set string storage lib:text Component.Template.Text $(Start) $(End)
data modify storage lib:text Component.Template.Pieces append from storage lib:text Component.Template.Piece
Loading
Loading