WSN追加案(関数):所持金、体力、KC

Issue #907 new
Kohaku Utakata created an issue

関数のご提案です。

・ MONEY() = パーティの所持金

・ HP(キャラクター番号),MAXHP(キャラクター番号) = 現在の体力、最大体力

・ FINDKC(文字列) = 選択カードのキーコードに文字列に一致するものがあればキーコード番号を返す

・ KCTEXT(キーコード番号) = 選択カードのキーコード番号のキーコードのテキストを返す

よろしければご検討ください。

Comments (54)

  1. k4nagatsuki repo owner

    ご提案ありがとうございます。

    MONEY()は、パーティの所持金である事を明示するためにPARTYMONEY()の方がいいのではないかと思います。

    また、キーコード関係も、略さずKEYCODEの文言を使った方がよさそうに思えます。また、効果系カードを扱う関数を追加する前に#809の結論を出す必要があります。選択カードのみを対象とすると話は簡単になりますが、その分使える用途がかなり減ってしまいます。

    最後に体力(生命点)についてなのですが、具体的な数値を取れるようにするとなると、CardWirthの数値隠蔽コンセプトをどう考えるか、という問題が絡んでくるので、ちょっと慎重になる必要がありそうです。

    数値隠蔽については、ユーザごとに様々な捉え方がされていて、ほとんど神聖視するような見方から全くこだわらないという見方まで様々です。過去には、エディタでのキャラクターごとの各種適性の表示のような、私にとっては問題無さそうに思えた機能に対しても強硬な反対を経験しています。厄介なのは、これはユーザごとの感覚の問題なので、根本的に結論が出ない事です。

    一度具体的な数値を取れるようにすると引き返せません。いきなりそのような関数を追加するのではなく、少し曖昧性のあるものを用意した方がいいかもしれません。たとえばLIFERATIO(<キャスト番号>) → 最大生命点に対する現在生命点の割合(0-1)といったようなものです。

  2. Kohaku Utakata reporter

    ご回答ありがとうございます。

    ご無理のない範囲で検討頂けましたら幸いです。

  3. ハルキゲニア

    体力に限らず、数値隠蔽のコンセプトとはシナリオ側、つまりゲームマスターにまで必要なのでしょうか?

    エディタを触ってみて、PCの能力値がわからないとまともにカードは作れないと思いました、その為に体力や能力値、カードのダメージ測定を追加したりしました。

    攻撃力がカードの効果量で決定され、能力値の影響がほぼ無いため、行動順と耐久力にかかわる能力値以外、システム的にほぼ死んでいます。特に知力は悲惨で魔術師をイメージしてキャラをつくった場合、耐久力が非常に低く行動順が遅い上に抵抗力まで低いキャラになりますよね。

    能力値が取れれば、高い知力評価するカード、たとえば知力の大きさで効果量を変化させ、特定の能力値の高いPCが使えば疑似的なダメージボーナスの様な効果が可能になります。性格等かわった能力値を評価して上げたりすることも可能です。

    パーティ全員の筋力の合計値で判定とか、正直でないと出現しない選択肢、能力値の合計が低い事を評価するカードやシナリオ、シナリオ開始時の役割設定を能力値から算出等、出来る事がものすごく増えます。

    クーポンやキーコードは無限に増殖し、必ず有るわけでも無い、能力値はどんなキャラにもあります。

    能力測定のシナリオが存在します。シナリオ以外にもありますよね。

  4. k4nagatsuki repo owner

    私もそこまで隠蔽する必要はないと思うのですが、しなければならないという人もいて、それはもはや信念の話になっています。

    一度取れるようにしたら元に戻せないので、私の一存で決めることはできません。状況を動かすのは大量の意見です。考えがある方はどんどん意見を出していただければと思います。

  5. Cassava_cw

    個人的には各種数値を取れるようにして欲しいですね。数値の隠ぺいというのはプレイヤーから隠されるという事だと思いますし。今作ってるシナリオで永続召喚獣カードが攻撃対象選択する際に条件設定できる機能を追加して、選択条件を重症の敵を優先して選択と健康・負傷状態の敵を優先して選択の2種類用意したんですが。HPの数値と最大HPとの割合を取れるようになると色々とはかどります。

  6. k4nagatsuki repo owner

    今現在、数値相当のものを確認できるものは全て取得できてよいと思います。反対の余地は少ないでしょう。

    ライフの場合、暴露すると割合が確認できるので、割合の取得は問題ないと思います。

  7. tachi gigas

    お疲れ様です。

    体力の取得については否定的な考え方を持っています。その根拠は不自由であるからこそ創意工夫が働くものだという古臭い考え方によるものでして、僕の意見は参考にはすべきではないです。実装されたら、多分使います。軟弱者ですね。

    割合での取得は良い方法と思います。

  8. k4nagatsuki repo owner

    とりあえず必要になりそうな情報取得関数を思いつくままに列挙してみます。

    どう考えても最終的にはこの3倍以上の量になります。ほしいものがあったら提案してください。

    • PARTYMONEY() → 数値 …… パーティの所持金
    • PARTYNAME() → 文字列 …… パーティ名
    • YADONAME() → 文字列 …… 拠点名
    • STATUSVALUE(character, status) → 数値 …… characterの状態statusの強度・修正値
    • STATUSROUND(character, status) → 数値 …… characterの状態statusの残ラウンド数
    • LIFERATIO(character) → 数値 …… characterの生命点/最大生命点(0~1.0)
    • COUPONVALUE(character, coupon) → 数値 …… characterの称号couponの点数
    • CARDPRICE(card) → 数値 …… cardの価格
    • CARDRARITY(card) → 数値 …… cardの希少度
    • FINDKEYCODE(card, pattern[, pos]) → 数値 …… cardのキーコードをpatternで検索して見つかった位置を返す
    • KEYCODETEXT(card, pos) → 文字列 …… cardのキーコード(pos番目)を返す
    • BATTLEROUND() …… 現在のバトルラウンド

  9. k4nagatsuki repo owner

    いくつか追加します。

    • CASTLEVEL(character) …… キャラクターのレベル
    • CARDLEVEL(card) …… カードレベル
    • CARDREMAINING(card) …… カードの残り使用回数
    • PARTYNUMBER() …… パーティ人数

  10. k4nagatsuki repo owner

    #855と内容が重複しているのでこちらに統合します。

    なお#855にはBATTLEROUND()の異常値は-1でなければならない(バトル開始イベントが0であるため)と書いてあります。

  11. tachi gigas

    お疲れ様です。

    pull request #233

    #997 にて宣言しましたが、微力ではありますが、間に合う限りできそうなものを実装します。とりあえず所持金取得という一番簡単なもので恐れ入りますが、ご確認をよろしくお願いします。

  12. k4nagatsuki repo owner

    上記Pull Requestをマージさせていただきました。重ね重ねありがとうございます。

    今回言うのを忘れていたのですが、関数をそれぞれ実装すると作業が重複してしまう可能性もあるので、なにを実装するか宣言しておいた方がいいかもしれません。

    私もよくどうせ他に作業者いないし……みたいに思って黙ってやってしまうのですが、これは本来よくないです。

  13. tachi gigas

    確かにどの関数を実装するかは言っていなかったですね。仰る通りで、失礼しました。

    あまり小刻みにやってもビルド作業に負担がかかりそうなので、
    次の作業はPARTYNUMBERYADONAMECASTLEVELBATTLEROUNDを予約しようと思います。

    下調べしていた所、PARTYNAMEは既に #808 で実装済みでした。

  14. tachi gigas

    pull request #234

    一応今度は手許でもflake8で検査するようにしました。とは言え別の見落としもあり得ますので、お忙しい所恐れ入りますが、ご確認お願いします。

  15. ルンバ

    体力は割合で量る方式もあるに越した事はないですが、
    例えば食らったダメージと同量とかあるいは倍返しとかで反撃してくる敵のギミックを作りたい場合
    割合方式でダメージを再現すると、HP10の策士型は、HP30の豪傑型よりも少ない数値しかくらわないことになります。
    (1割なら 策士型は1 豪傑型は3になるので)
    この場合は割合ではなく、実数を計測し再現する必要があります。

    逆に割合方式の方が都合よい操作もあるでしょうから双方あるに越した事はないと思います。

  16. tachi gigas

    お疲れ様です。申し訳ありません、時間が空いてしまいました。

    残っている関数の候補を軽く下見しましたが、いくつか議論が必要そうな点がありました。

    • 選択状態にあるカードの通し番号を取得するコモン関数を実装しないと、細かい例外を考える以前に、実装に取り掛かれない関数が大半となってます。ちょっと僕には想像できませんが、この仕様をどうするか決める必要があります。別Issue立てるべき?
    • STATUSVALUESTATUSROUNDは、与えるstatus引数のenum列挙体を決めなければいけないように見えます。コモン関数でenumを扱うならこれも別Issueが必要になりそうです。
    • COUPONVALUEで、指定された称号が存在しない場合はどの数値を返すかを決める必要があります。

    残ったLIFERATIOは、まだ予約しませんが、仕様の議論は必要なさそうです。

    お忙しいところ恐縮ですが、ご意見を拝借できればと思います。

    体力の実測値での取得について。僕は上述通り古い考えの人間なので、いくら何でもエンジン内ではCardWirthが持つ数値隠蔽のゲームバランスは担保するべきだと思います。もし今後の議論次第で体力の実数値を取るべきだという結論になった場合、議論の結果を尊重します。ただ単に僕はやりません。

  17. k4nagatsuki repo owner
    • issue #910 式で定義済み定数を使えるようにする
    • issue #809 効果系カードの取り扱い
    • issue ##1020 限定的に構造体/複合値/オブジェクトを扱えるようにする

    このあたりを参照してください。ただ状態の数値についていえば、CWのデータ内の数値をそのまま流用してもいいと思います。

    COUPONVALUEで称号がない場合の戻り値は0でいいのではないかと思います。有無は他の方法で確認できます。

  18. tachi gigas

    Issueの下調べが甘かったですね。お手数をおかけして申し訳ありません。

    取り急ぎLIFERATIOCOUPONVALUEを予約します。

  19. k4nagatsuki repo owner

    ありがとうございます。いくつかコメントしました。

    LIFERATIOの小数点以下はどうするべきか、四捨五入か……などと考えていましたが、よく考えたらコモンと式の数値は実数でしたね。

  20. tachi gigas

    cwxeditorの方にも書きましたが、ご指摘の点を修正しました。僕は日本語が弱いので申し訳ないですが、ご確認お願いします。

    ただ状態の数値についていえば、CWのデータ内の数値をそのまま流用してもいいと思います。

    というのは、cw/binary/base.pyconv_statustype関数の引数を参考にすればよいとのことでしょうか。

  21. k4nagatsuki repo owner

    マージさせていただきました。いつも助かっています。本当にありがとうございます。

    というのは、cw/binary/base.pyconv_statustype関数の引数を参考にすればよいとのことでしょうか。

    そうですね。そこにあるのがCWのステータス情報のIDです。

  22. k4nagatsuki repo owner

    pull request #1020

    カード操作の土台を作りました。今後単独のカードを相手にする関数を実装します。

    ところでカードの使用回数ですが、CARDREMAININGというのはいかにも変に見えます。CARDCOUNT辺りにした方がいいのではないかと思うんですが、正直これも妥当とは思えませんし、調べてもよく分かりません。英語力のなさが恨めしいところです。さしあたってはCARDCOUNTで実装してみます。

  23. tachi gigas

    お疲れ様です。

    4月はドタバタしていて放置状態でした面目ありません。GWも半分が過ぎましたが、STATUSVALUESTATUSROUNDFINDKEYCODEKEYCODETEXTを予約します。これで現在挙がっているコモン変数と本来の課題は全て解決する形になります。

  24. k4nagatsuki repo owner

    CARDRARITYの結果を一般=1,レア=2,プレミア=3にしましたが、#910の実装を検討していたところ、一般を0(レアリティ無し)にしてレア=1,プレミア=2にした方がおさまりがよさそうに思えてきました。RAREPREMIERという定数を実装する事は問題ありませんが、NORMALのような定数が必要になるというのはあまりぞっとしません。

    どちらの方が筋がいいかはちょっと考え中です。

  25. tachi gigas

    pull request #258

    少し改造が入ってしまいましたが、ご確認をお願いします。

    キーコード検索するロジックはキーコード所持分岐コンテント用の関数が元からあるのですが、今回の改修と比較して、与える引数と返す戻り値が違うため、別関数を用意した方がよいと判断しました。共通化できるものがあれば共通化した方がいいかも知れないのですが……。この辺の判断の正誤判定もお手数ですがお願いします。

    レアリティについては、ちょっと判断が難しいです。識別アイコンが希少品と貴重品にしかつかないこと、`NORMAL`だとカードのレアリティ用途以外に使うかも知れない定数である事を考えると、確かにそうかもとは思います。

  26. k4nagatsuki repo owner

    これはちょっと考えないといけないところだと思うのですが:

    1. キーコード空欄の取り扱い。*等の検索で引っかかるようにするべきか? 空欄はただのパディングとして使っている人も多く、特別な意味を持たせるべきではないという考え方もあると思います(私もその考えです)。ただ、!のようなマッチングでイベントを発火させる事もできてしまい、CWのシステム的には多少の意味を持ってしまっています(仕様の考慮漏れに近いと思いますが)。
    2. カード名が引っかかるようにするべきか。これは従来のキーコード分岐でも引っかかるので、それ自体は問題ないと思うのですが、キーコード分岐には順序の概念がありませんでした。何番目に引っかかるべきかは決めてしまわなければなりません(pull request #258の実装は末尾になっています。順序にあまり意味はなさそうですし、私はそれで問題ないと思います)。

    2.はともかく1.は思案が必要です。空欄が引っかかるようにすると使っていたシナリオ作者が驚く事になるかもしれません(KEYCODETEXTの例外値も空文字列なので)。

  27. tachi gigas

    むむむ。考慮が漏れておりましたね。無い頭で考えておりましたが……。

    • キーコードが空文字列も返す → !を利用したキーコード発火の仕様と矛盾しない。もしFINDKEYCODEで正しく位置が取れた上で取得したKEYCODETEXTが空文字列だと都合が悪い場合はシナリオ側でLEN取って弾いてもらう。シナリオ作者の手間が増える
    • キーコードが空文字列の時は返さないようにする → !を利用したキーコード発火の仕様と矛盾する。でも*でパターンマッチングして空文字列が欲しいケースが特に思いつかない。次善策?
    • いっそパターンマッチングをやめて完全一致検索にする → 一番無難だが不便。そもそもコモン関数は2個も要らない?

    カード名は1.28以降で実際に発火しますし、末尾にあれば1.20の互換性が最低限保てるように考えましたので、テストしても特に気にしておりませんでした。

  28. k4nagatsuki repo owner

    キーコード分岐では空文字列は指定できませんし、無視されます。そもそも×で発火するイベントの方がおかしいはずです。

  29. tachi gigas

    ではキーコード分岐の仕様に揃え、空文字列は返さない仕様にしましょうか?問題やご意見がなければそれで進めます。

    調べた所、1.20の時点で×に空キーコードが反応しますね(キーコードが5個全部埋まってないカードは全部反応する)。これは思った以上に根が深い仕様です。

  30. k4nagatsuki repo owner

    その挙動自体は数年前に発見されており、不具合を招かずに利用する方法はないと書いた覚えがあります。数年後の今でもそう思います。

    空文字列はキーコードが存在しないのと同じ扱いにするのがベターかと思います。

    番号は飛ばすのがいいでしょう。万が一どうしても途中の空キーコード欄を検出したいというケースが発生しても、番号が飛んだことで認識する事ができます。

  31. tachi gigas

    両方のpull requestを訂正しました。日本語をどうするかで気の迷いがあり、時間がかかりまして申し訳ありません。

  32. k4nagatsuki repo owner

    呪縛~魔法無効化がある時のSTATUSVALUE1になりますが、これは持続時間をそのまま返すかあるいはこの関数では取り扱わない方がいいのではないでしょうか。

  33. k4nagatsuki repo owner

    同じ事が言えますね。

    ステータス異常の値のややこしさはラウンド数と効果値が両方あるもの、効果値のみがあるもの、残りラウンドのみがあるものがそれぞれ存在する事で、元々ひとまとめにするのに無理があり、本来それぞれのタイプ別に関数を用意するべきなですが、便宜を考えるとせいぜいふたつくらいにまとめざるを得ません。

    そのようにまとめるのであれば、VALUEとROUNDで両方効果時間を取れるくらいまで便宜をはかってもいいんじゃないかと思います。

    逆方向に振るなら、中毒と麻痺はVALUEのみで値を返すべきです(これらの強度は残りラウンドではないため)。

  34. tachi gigas

    そのように取り計らいました。両方のpull requestを訂正しましたのでお手隙の際にご確認をお願いします。

    っと、言葉足らずでしたが、強度・修正値を持たない状態の場合は残ラウンド数を返すようにしました。該当する状態にかかっているのに、何も返さないのは却って不親切なように思えました。

  35. k4nagatsuki repo owner

    能力上昇・低下はマイナス値を使えばまとめられそうな気もしますが、どっちの方が使い勝手がいいでしょうか。

    ちょっと利用シーンが思い浮かびません。

  36. tachi gigas

    cw/binary/base.pyconv_statustype関数の引数を参考にすると良いとのことでしたので、つまり現状の状態判定分岐コンテントもそうなっております。

    今の組み方で能力上昇と能力低下の両方を組み合わせて判定したいという場合でも、STATUSVALUE(SELECTED(), 18) - STATUSVALUE(SELECTED(), 22)あたりで実現可能です。仕様ととっつきやすさのどちらを優先するかは議論のしどころがありそうです。上昇だけ取りたい、低下だけ取りたいという場合もシナリオやカードによっては考えられます。

    両者を組み合わせたいとしますと、どういう仕様が好ましいでしょうか?状態番号23~26について、亡き者にするか、それとも状態番号18~22を与えた時と正負を逆にするか(それだとSTATUSROUNDとの整合性がとれない?)。

  37. k4nagatsuki repo owner

    上昇と下降を分割するとしたら

    • 上昇または下降がある事を検出する …… 0 < (STATUSVALUE(n, upstatus) - STATUSVALUE(n, downstatus))
    • 上昇がある事を検出する …… 0 < STATUSVALUE(n, upstatus)
    • 下降がある事を検出する …… 0 < STATUSVALUE(n, downstatus)
    • 上昇絶対値をとる …… STATUSVALUE(n, upstatus)
    • 下降絶対値をとる …… STATUSVALUE(n, downstatus)
    • 上昇または下降のラウンド数を取る …… MAX(STATUSROUND(n upstatus), STATUSROUND(n, downstatus))
    • 上昇のラウンド数を取る …… STATUSROUND(n upstatus)
    • 下降のラウンド数を取る …… STATUSROUND(n downstatus)

    共通にするとしたら

    • 上昇または下降がある事を検出する …… 0 <> STATUSVALUE(n, status)
    • 上昇がある事を検出する …… 0 < STATUSVALUE(n, status)
    • 下降がある事を検出する …… 0 > STATUSVALUE(n, status)
    • 上昇絶対値をとる …… STATUSVALUE(n, status)
    • 下降絶対値をとる …… -STATUSVALUE(n, status)
    • 上昇または下降のラウンド数を取る …… STATUSROUND(n status)
    • 上昇のラウンド数を取る …… IF(0 < STATUSVALUE(n, status), STATUSROUND(n status), 0)
    • 下降のラウンド数を取る …… IF(0 > STATUSVALUE(n, status), STATUSROUND(n status), 0)

    個別に取れるようにして、かつ負数を返すようにするとしたら

    • 上昇または下降がある事を検出する …… 0 <> STATUSVALUE(n, upstatus)または0 <> STATUSVALUE(n, downstatus)
    • 上昇がある事を検出する …… 0 < STATUSVALUE(n, upstatus)または0 > STATUSVALUE(n, downstatus)
    • 下降がある事を検出する …… 0 < STATUSVALUE(n, downstatus)または0 > STATUSVALUE(n, upstatus)
    • 上昇絶対値をとる …… STATUSVALUE(n, upstatus)または-STATUSVALUE(n, downstatus)
    • 下降絶対値をとる ……-STATUSVALUE(n, downstatus)または-STATUSVALUE(n, upstatus)
    • 上昇または下降のラウンド数を取る …… マイナス値を返す側がどういう挙動になるか別途決める必要あり
    • 上昇のラウンド数を取る …… STATUSROUND(n upstatus)
    • 下降のラウンド数を取る …… STATUSROUND(n downstatus)

    一番上は修正があること自体を取るのがやや面倒です。一番下は選択肢の多さが分かりにくさに繋がりそうな感じがします。

    また、ステータスの種類は数値ではなくシンボルによって指定する事が望ましいです。上昇と下降を統一するとシンボルの数を減らす事ができます(シンボルの実装はすぐできます)。UPACTIONDOWNACTIONに分割されているか、ENHACTIONの一つになるかです。

    統一する場合、上昇のみ、下降のみのラウンド数を取るのが少々面倒です。実際の使用シーンでどれくらいそういうケースがあるかが問題です(これは全てについて言える事ですが)。

    STATUSROUNDも考え方は同じです。

    以上から、私としては共通にするのが使い勝手的によいのではないかと考えています。

  38. tachi gigas

    では

    状態番号23~26について、亡き者にする

    で組んでみますが、シンボルという言葉をIssue内を検索してもぱっと出てこなくて仰っている意味が申し訳ないですが分かりません。単語を察するに Issue #910 で言うところの定義済み定数のことでしょうか。

  39. k4nagatsuki repo owner

    すみませんそれです。今回の関数がマージされたら実装を出します。

  40. tachi gigas

    両方のpull requestを訂正しましたのでお手隙の際にご確認をお願いします。他にご指摘がありましたら何なりとよろしくお願いします。

  41. k4nagatsuki repo owner

    ありがとうございます。それぞれマージしました。

    これからシンボル・定数を追加します。

  42. 暗黒 騎士

    「LIFERATIO」について、現状、たとえば瀕死にしたレベル10PCをLIFERATIO(SELECTED())すると「0.21428571」みたいな値が取れます。

    これはなんというか、すごくローレベル(Low-Level APIとかの意味です。念のため)な実装に見えます。自分の感覚としては100%~0%までの整数が返ってくるのを期待するのが普通に感じます。もちろんそういう値が取りたければINT(LIFERATIO(SELECTED())*100)とすれば取れる一方で、逆はできないのでこの実装の方が便利ではありますが、覚悟の上なんでしょうか?

  43. k4nagatsuki repo owner

    すみません、最初の提案からここまで一度も説明していませんでしたが、以下が私の考えです。

    結果を百分率にすると、0.4%の場合は0に、99.5%の場合は100になります。四捨五入をやめて小数点以下を切り捨てても切り上げてもこの問題は残ります。

    デバッガ等ではこれを回避するべく0~1%を1、99~100未満を99と表記するような小細工をしていますが、実数の存在する世界ではこの細工は通用しません。

    小数点以下を値として出すなら、百倍してもあまり意味がありません。

  44. Cassava_cw

    情報取得関数の提案ですが、身体能力・精神傾向を個別に返す関数などいかがしょうか?

    店シナリオなどで効果系カードの適性診断を簡単に作れるようになりますし、冒険者の中から一番正直性が高いキャラを選び出すなど、特定の身体能力・精神傾向が高い/低いキャラを選び出せるようになるのでシナリオ中のイベントや会話のパターンを広げられるのでは?と愚考します。

  45. k4nagatsuki repo owner

    個人的にはあった方がいいと思いますが、このIssueの上のほうでも書いた通り、エディタにおける適性表示だけでも強硬な反対にぶつかった経験があるのでなかなかやりづらいというのが正直なところです。

  46. Cassava_cw

    返答ありがとうございます。個人的には数値の隠ぺいはプレイヤーにキャラの能力値やダメージなどの数値を直接見せない事で、シナリオやカードイベントなどの内部処理で使う分には問題ないと思っているんですが難しいところだと思います。

  47. k4nagatsuki repo owner

    私はあった方がいいと思います。隠蔽云々の他に名前が問題ですね。

  48. Cassava_cw

    返答ありがとうございます、こちらの返答遅くなってすいません。
    名前の問題がありましたか、個人的には用語決めたりとかそういうの苦手なのであまり力になれないのが心苦しいです。
    ただ、関数で対属性取れるようになると対属性を条件分岐の対象に出来るようになって色々出来るのでぜひ実装していただきたいですね。

  49. Log in to comment