【0066】アイテム画面を作る⑥
アイテム画面作るの手順が多いというか必要な子要素が多すぎて
目的を見失いそうです…。
前回、アイテムIDを渡すと
アイテムマスタにあるアイテム情報から名称と説明を取得して返す機能
を作りましたが、
アイテムマスタをアイテムIDで舐める機能がまだ出来ておらず、
今は固定で「八卦炉」を返すようにしていました。
というわけで今回はアイテムIDを元にアイテムマスタをなめて
アイテムマスタ配列の添字とアイテムIDが不一致となるケースでも
正しいアイテム情報を取得できるようにしようと思います。
#args=($(echo "$(getItemInfo $itemID)"|xargs))
args=($(echo '0000 CSM 000 nomod 八卦炉 激しくマーライオンする'|xargs))
前回の一部です。
argsとして取得するアイテム情報を、
スタブ的に固定値にしています。
コメントアウトしている行の「getItemInfo」というのを作り、
引数として「itemID」を受け取るようにします。
すべきことは
・アイテムマスタの要素分だけ以下を反復する
・引数.アイテムID=参照中のアイテム情報.アイテムIDであれば
呼び出し元にアイテム情報を返却する(標準出力)
・引数.アイテムID≠参照中のアイテム情報.アイテムIDであれば
次のアイテムに進む
・すべてのアイテムを参照したが
引数.アイテムID=参照中のアイテム情報.アイテムID
になるものがなかったとき、エラーアイテムのアイテム情報を返却する
という感じ。
: 'アイテム情報取得' && {
###########################################
##getItemInfo
## アイテムIDをもとにアイテムテーブルの行内容を取得し、
## 標準出力で返却する。受け取り側で、xargsなど使用してパースすること。
## 該当IDのアイテムが登録されていなければ、エラーアイテムが返却される。
## $1:アイテムID
###########################################
function getItemInfo(){
declare itemID="$(printf "%04d" $1)"
declare cntTblItem=0
declare tmpArr
declare retItemInfo
declare args
##引数の個数
if [ $# -ne 1 ] ; then
sysOut 'e' $LINENO '引数は1つ指定してください。'
return
fi
#アイテムテーブルは全部で何件あるか確認
cntTblItem=${#TBL_ITM_INFO[@]}
#アイテムIDとアイテムテーブルのインデクスが一致するとは限らないため
#アイテムテーブルをなめる(性能確認はしていない)。
for ((i=0; i<$cntTblItem; i++)) {
retItemInfo="${TBL_ITM_INFO[i]}"
#アイテムテーブルの行を半角スペースでパースして1要素目(アイテムID)を取得する
args=($(echo "${retItemInfo}"|xargs))
#引数のアイテムIDとアイテムテーブル内のIDが一致したら
#必要な修正を施して返却
if [ "${args[0]}" = "$itemID" ] ; then
#標準出力で返却、関数を抜ける
echo "$retItemInfo"
break #要る?
fi
}
#渡されたアイテムIDがアイテムテーブルに存在しないとき、
#エラーアイテムを返却する(エラーアイテムIDを対象のアイテムIDに置換する)
echo "${TBL_ITM_INFO_ERR/ZZZZ/$itemID}"
}
}
こんな感じです。
#アイテムIDとアイテムテーブルのインデクスが一致するとは限らないため
#アイテムテーブルをなめる(性能確認はしていない)。
for ((i=0; i<${#TBL_ITM_INFO[@]}; i++)) {
…
イテレータでのループがどうにもうまく行かないんですけど
どうしてでしょうか。
まあ動けば良いので、これでいっちゃいます。
retItemInfo="${TBL_ITM_INFO[i]}"
#アイテムテーブルの行を半角スペースでパースして1要素目(アイテムID)を取得する
args=($(echo "${retItemInfo}"|xargs))
現在処理中のアイテム情報を返却候補「retItemInfo」として切り出します。
これはあくまでもスペース区切りのひと続きの文字列なのでそれを
args=($(echo "${retItemInfo}"|xargs))
ってやってバラして一時的な「args」配列に詰め直します。
やりたいのは、
こうして作った「args」配列からアイテムIDに該当する要素を参照して
引数のitemIDと一致するかの判断です。
argsに詰め直さなくても
文字列変数の桁数指定展開でも良かったかなと思いますが…
#引数のアイテムIDとアイテムテーブル内のIDが一致したら
#必要な修正を施して返却
if [ "${args[0]}" = "$itemID" ] ; then
#標準出力で返却、関数を抜ける
echo "$retItemInfo"
break #要る?
fi
というわけで、args[0]つまりitemIDが、引数と一致している場合に、
上記で一旦返却候補として切り出した「retItemInfo」を標準出力にはいて
ループをブレイクしています。
#渡されたアイテムIDがアイテムテーブルに存在しないとき、
#エラーアイテムを返却する(エラーアイテムIDを対象のアイテムIDに置換する)
echo "${TBL_ITM_INFO_ERR/ZZZZ/$itemID}"
その下では、ループを抜けた後にこうした記述をしています。
ここに到達するということは
上記のようにアイテムIDが一致するアイテム情報にヒットしなかったから
です。
ここまで来た場合は、
アイテム情報にはエラーアイテムの情報を返却します。
大昔にアイテムマスタを作るときに、
エラーアイテムというのを作ったと思います。
これを想定していたわけですね。
#エラーアイテム
TBL_ITM_INFO_ERR=('ZZZZ ERR +99 該当アイテムなし 該当アイテムなし 該当IDのアイテムは登録されていません')
ただ、返却の文字列変数の展開がこうなっています。
echo "${TBL_ITM_INFO_ERR//ZZZZ/$itemID}"
TBL_ITM_INFO_ERRの文字の内、
「ZZZZ」という部分を、$itemIDに変換しています。
と、今この記事を書いていて思いついたところがあるので
変更させてください。
#エラーアイテム
TBL_ITM_INFO_ERR=('ZZZZ ERR +99 該当アイテムなし 該当アイテムなし 該当IDのアイテムは登録されていません')
↓
TBL_ITM_INFO_ERR=('ZZZZ ERR ERR エラーアイテム ID:ZZZZ ID:ZZZZのアイテムは存在しません')
あとアイテム表示情報を取得する関数でも
エラーアイテムが帰ってきた場合のスペシャルコードが入っていたんですが
これを消します。
スペシャルコードにしなくても、
普通にエラーアイテム返すだけで十分でした。
ただエラーアイテムのアイテムIDは半角なので表示が崩れます。
まあエラーなので崩しといてもいいんですが…。
以前半角カタカナを全角カタカナに置換する必要があって
nkfというものを使ってたんですが
これが入っていない環境でエラーになるので
依存を解消するために
半角カタカナ→全角カタカナの置換関数を作りました。
なので、こいつに半角数字→全角数字も混ぜ込んでしまいます。
: '半角カナ・数字置換' && {
##################################################
##repMonoKanaSuzi
## 半角カタカナを全角カタカナに置換する
## ついでだから数字も全角にする
## 返却は標準出力
## $1:入力文字
##################################################
function repMonoKanaSuzi(){
#バリデーション
##引数の個数
if [ $# -ne 1 ] ; then
sysOut 'e' $LINENO '引数は1設定してください。'
return
fi
declare cnvstr=$1
declare tgtDakuten=('ガ' 'ギ' 'グ' 'ゲ' 'ゴ' 'ザ' 'ジ' 'ズ' 'ゼ' 'ゾ' 'ダ' 'ヂ' 'ヅ' 'デ' 'ド' 'バ' 'ビ' 'ブ' 'ベ' 'ボ' 'ヴ' 'パ' 'ピ' 'プ' 'ペ' 'ポ')
declare dstDakuten=('ガ' 'ギ' 'グ' 'ゲ' 'ゴ' 'ザ' 'ジ' 'ズ' 'ゼ' 'ゾ' 'ダ' 'ヂ' 'ヅ' 'デ' 'ド' 'バ' 'ビ' 'ブ' 'ベ' 'ボ' 'パ' 'ピ' 'プ' 'ペ' 'ポ')
declare tgtAll=('ア' 'イ' 'ウ' 'エ' 'オ' 'カ' 'キ' 'ク' 'ケ' 'コ' 'サ' 'シ' 'ス' 'セ' 'ソ' 'タ' 'チ' 'ツ' 'テ' 'ト' 'ナ' 'ニ' 'ヌ' 'ネ' 'ノ' 'ハ' 'ヒ' 'フ' 'ヘ' 'ホ' 'マ' 'ミ' 'ム' 'メ' 'モ' 'ヤ' 'ユ' 'ヨ' 'ラ' 'リ' 'ル' 'レ' 'ロ' 'ワ' 'ヲ' 'ン' 'ァ' 'ィ' 'ゥ' 'ェ' 'ォ' 'ッ' 'ャ' 'ュ' 'ョ')
declare dstAll=('ア' 'イ' 'ウ' 'エ' 'オ' 'カ' 'キ' 'ク' 'ケ' 'コ' 'サ' 'シ' 'ス' 'セ' 'ソ' 'タ' 'チ' 'ツ' 'テ' 'ト' 'ナ' 'ニ' 'ヌ' 'ネ' 'ノ' 'ハ' 'ヒ' 'フ' 'ヘ' 'ホ' 'マ' 'ミ' 'ム' 'メ' 'モ' 'ヤ' 'ユ' 'ヨ' 'ラ' 'リ' 'ル' 'レ' 'ロ' 'ワ' 'ヲ' 'ン' 'ァ' 'ィ' 'ゥ' 'ェ' 'ォ' 'ッ' 'ャ' 'ュ' 'ョ')
declare tgtSuzi=('0' '1' '2' '3' '4' '5' '6' '7' '8' '9')
declare dstSuzi=('0' '1' '2' '3' '4' '5' '6' '7' '8' '9')
#2文字結合の必要があるので、先に濁点半濁点を殺す
for i in ${!tgtDakuten[@]}
do
cnvstr=${cnvstr//"${tgtDakuten[i]}"/"${dstDakuten[i]}"}
done
#半角カタカナ平音を殺す
for i in ${!tgtAll[@]}
do
cnvstr=${cnvstr//"${tgtAll[i]}"/"${dstAll[i]}"}
done
#半角数字を殺す
for i in ${!tgtSuzi[@]}
do
cnvstr=${cnvstr//"${tgtSuzi[i]}"/"${dstSuzi[i]}"}
done
echo "$cnvstr"
}
}
べたべたな書き方…。
で、該当アイテムIDが見つからなかった場合は
アイテム情報としてエラーアイテムを返すだけでなく、
この関数も通します。
#渡されたアイテムIDがアイテムテーブルに存在しないとき、
#エラーアイテムを返却する(エラーアイテムIDを対象のアイテムIDに置換する)
echo "${TBL_ITM_INFO_ERR//ZZZZ/`repMonoKanaSuzi $itemID`}"
エラーアイテムに記載されたZZZZ部分は
引数として渡されてきたアイテムIDに置換された上、
更に全角数字に置き直されて標準出力に渡されます
(呼び出し元に返却されます)
さて、
これでアイテム表示情報を要求されたら
アイテム表示情報取得>アイテムマスタから検索
のひと続きが出来ました。
: 'アイテム表示取得' && {
###########################################
##getItemDisp
## アイテムの表示を編集して標準出力で返却する。
## $1:表示区分(0:名称/1:説明)
## $2:アイテムID
###########################################
function getItemDisp(){
##引数の個数
if [ $# -ne 2 ] ; then
sysOut 'e' $LINENO '引数は2つ指定してください。'
return
fi
declare mode=$1
declare itemId=$2
declare retStr=''
declare args=()
args=($(echo "$(getItemInfo $itemID)"|xargs))
#args=($(echo '0000 CSM 000 nomod 八卦炉 激しくマーライオンする'|xargs))
case $mode in
'0')
#補正値が000の時、名称に含めない
if [ "${args[2]}" = '000' ] ; then
retStr=' '
else
retStr="${args[2]}"
fi
#補正値が000の時、名称に含めない
if [ "${args[3]}" != 'nomod' ] ; then
retStr="$retStr${args[3]}"
fi
retStr="$retStr${args[4]}"
;;
'1')
retStr="$retStr${args[5]}"
;;
esac
echo "$retStr"
}
}
: 'アイテム情報取得' && {
###########################################
##getItemInfo
## アイテムIDをもとにアイテムテーブルの行内容を取得し、
## 標準出力で返却する。受け取り側で、xargsなど使用してパースすること。
## 該当IDのアイテムが登録されていなければ、エラーアイテムが返却される。
## $1:アイテムID
###########################################
function getItemInfo(){
declare itemID="$(printf "%04d" $1)"
declare tmpArr
declare retItemInfo
declare args
##引数の個数
if [ $# -ne 1 ] ; then
sysOut 'e' $LINENO '引数は1つ指定してください。'
return
fi
#アイテムIDとアイテムテーブルのインデクスが一致するとは限らないため
#アイテムテーブルをなめる(性能確認はしていない)。
for ((i=0; i<${#TBL_ITM_INFO[@]}; i++)) {
retItemInfo="${TBL_ITM_INFO[i]}"
#アイテムテーブルの行を半角スペースでパースして1要素目(アイテムID)を取得する
args=($(echo "${retItemInfo}"|xargs))
#引数のアイテムIDとアイテムテーブル内のIDが一致したら
#必要な修正を施して返却
if [ "${args[0]}" = "$itemID" ] ; then
#標準出力で返却、関数を抜ける
echo "$retItemInfo"
break #要る?
fi
}
#渡されたアイテムIDがアイテムテーブルに存在しないとき、
#エラーアイテムを返却する(エラーアイテムIDを対象のアイテムIDに置換する)
echo "${TBL_ITM_INFO_ERR//ZZZZ/`repMonoKanaSuzi $itemID`}"
}
}
また、エラーアイテムを構えて、
仮に存在しないアイテムIDが渡された場合にはそちらを返すようにします。
#エラーアイテム
TBL_ITM_INFO_ERR=('ZZZZ ERR ERR エラーアイテム ID:ZZZZ ID:ZZZZのアイテムは存在しません')
エラーアイテムをアイテム表示情報として返却する際には
アイテムIDの半角数字は都合が悪いので、全角に変換する必要があり
半角カタカナの置換関数に数字の置換機能も追加しました。
: '半角カナ・数字置換' && {
##################################################
##repMonoKanaSuzi
## 半角カタカナを全角カタカナに置換する
## ついでだから数字も全角にする
## 返却は標準出力
## $1:入力文字
##################################################
function repMonoKanaSuzi(){
#バリデーション
##引数の個数
if [ $# -ne 1 ] ; then
sysOut 'e' $LINENO '引数は1設定してください。'
return
fi
declare cnvstr=$1
declare tgtDakuten=('ガ' 'ギ' 'グ' 'ゲ' 'ゴ' 'ザ' 'ジ' 'ズ' 'ゼ' 'ゾ' 'ダ' 'ヂ' 'ヅ' 'デ' 'ド' 'バ' 'ビ' 'ブ' 'ベ' 'ボ' 'ヴ' 'パ' 'ピ' 'プ' 'ペ' 'ポ')
declare dstDakuten=('ガ' 'ギ' 'グ' 'ゲ' 'ゴ' 'ザ' 'ジ' 'ズ' 'ゼ' 'ゾ' 'ダ' 'ヂ' 'ヅ' 'デ' 'ド' 'バ' 'ビ' 'ブ' 'ベ' 'ボ' 'パ' 'ピ' 'プ' 'ペ' 'ポ')
declare tgtAll=('ア' 'イ' 'ウ' 'エ' 'オ' 'カ' 'キ' 'ク' 'ケ' 'コ' 'サ' 'シ' 'ス' 'セ' 'ソ' 'タ' 'チ' 'ツ' 'テ' 'ト' 'ナ' 'ニ' 'ヌ' 'ネ' 'ノ' 'ハ' 'ヒ' 'フ' 'ヘ' 'ホ' 'マ' 'ミ' 'ム' 'メ' 'モ' 'ヤ' 'ユ' 'ヨ' 'ラ' 'リ' 'ル' 'レ' 'ロ' 'ワ' 'ヲ' 'ン' 'ァ' 'ィ' 'ゥ' 'ェ' 'ォ' 'ッ' 'ャ' 'ュ' 'ョ')
declare dstAll=('ア' 'イ' 'ウ' 'エ' 'オ' 'カ' 'キ' 'ク' 'ケ' 'コ' 'サ' 'シ' 'ス' 'セ' 'ソ' 'タ' 'チ' 'ツ' 'テ' 'ト' 'ナ' 'ニ' 'ヌ' 'ネ' 'ノ' 'ハ' 'ヒ' 'フ' 'ヘ' 'ホ' 'マ' 'ミ' 'ム' 'メ' 'モ' 'ヤ' 'ユ' 'ヨ' 'ラ' 'リ' 'ル' 'レ' 'ロ' 'ワ' 'ヲ' 'ン' 'ァ' 'ィ' 'ゥ' 'ェ' 'ォ' 'ッ' 'ャ' 'ュ' 'ョ')
declare tgtSuzi=('0' '1' '2' '3' '4' '5' '6' '7' '8' '9')
declare dstSuzi=('0' '1' '2' '3' '4' '5' '6' '7' '8' '9')
#2文字結合の必要があるので、先に濁点半濁点を殺す
for i in ${!tgtDakuten[@]}
do
cnvstr=${cnvstr//"${tgtDakuten[i]}"/"${dstDakuten[i]}"}
done
#半角カタカナ平音を殺す
for i in ${!tgtAll[@]}
do
cnvstr=${cnvstr//"${tgtAll[i]}"/"${dstAll[i]}"}
done
#半角数字を殺す
for i in ${!tgtSuzi[@]}
do
cnvstr=${cnvstr//"${tgtSuzi[i]}"/"${dstSuzi[i]}"}
done
echo "$cnvstr"
}
}
という前段を構えた上で、アイテム画面の表示はこうなります。
##################################################
## joinFrameOnItem
## 画面フレームと、アイテム表示枠を結合する
## lnSeedのマップ枠の中にlnItemInfoをはめ込む。
## また、所持アイテムの情報をはめ込んでいく。
##################################################
function joinFrameOnItem (){
selCrsrID=1
declare spCnt1=0 #アイテム名称の後の半角相当SP数
declare spCnt2=0 #アイテム説明の後の半角相当SP数
declare itemName=''
declare itemExplain=''
#現在の表示内容を退避し、アイテム枠を表示する。
##アイテム枠で上書き
for ((i = 0; i <= 19; i++)) {
lnSeed[i]="${lnItemInfo[i]}"
}
psnItemList=(1 2 3 999)
for ((i=0; i<${#psnItemList[*]}; i++)) {
#アイテム情報取得関数
itemID=${psnItemList[i]}
itemName="$(getItemDisp 0 $itemID)"
itemExplain="$(getItemDisp 1 $itemID)"
spCnt1=$(( (24-(${#itemName}))*2 ))
spCnt2=$(( (23-${#itemExplain})*2 ))
eval 'lnSeed[i+3]="${lnSeed[i+3]:0:4}'"$itemName"'`printf %${spCnt1}s`|$itemExplain`printf %${spCnt2}s`|`printf "%2s" $i`|"'
}
#カーソル設置
lnSeed[3]="${lnSeed[3]:0:2}>${lnSeed[3]:3}"
}
}
この中には仮の持ち物リストを持っています。
psnItemList=(1 2 3 999)
持ち物は基本的には「拾う」ことで増えていきますが、
まだ「拾う」コマンドは未実装なので
しばらくこの仮アイテムを生存させます。
アイテムにまつわる機能があまりにも多くて死にそうですが
(「拾う」コマンドは書きましたが、
他にも使うとか装備するとか投げるとかあまりにも道のりが遠いです…)
一旦この状態で実行してみます。
よさそうです。
つぎは…拾うコマンドかな…