nR10ロール(2):戻り値をオブジェクトにしてみる

海月歩空様より頂いたコメントを参考に、というかほぼコピペで(すいません)、Rダイススクリプトの改変を試みてみました。
スクリプト本体は以下に。

スクリプト

//Rダイス呼び出し部
function event::onChannelText(prefix, channel, text)
{
    //結果返却用オブジェクト
    var achieve = new Object();
    //結果返却用オブジェクト内結果文字列用配列
    achieve.array = new Array();
    //結果返却用オブジェクト内達成値
    achieve.value = 0;
    
    if (text.match(/#\d+R\d+/ig)){

        //該当文字列を配列matchedTextに格納
        var matchedText = text.match(/#(\d+)R(\d+)/i);
         
        //サブファンクションに飛ばす
        achieve = renegadeDice(matchedText[1],matchedText[2]);
        
        //結果を出力
        for (i=0; i < achieve.array.length; i++){
            send(channel, prefix.nick + ':' + achieve.array[i] );
        }

    }
}

//Rダイス計算部
function renegadeDice(diceNumber, critNumber)
{
    
    var diceRolled = 0;         //ダイス1個振った結果
    var faceDice = 10;          //ダイスの面数(DXなので10面で固定)
    var criticalDice;           //クリットしたダイスの個数をカウント
    var preAchieveValue = 0;    //プレ達成値
    var achieveValue = 0;       //達成値
    var achieveString = "";     //達成値が出るまでの過程の文字列
    var count = 0;

    //結果返却用オブジェクト
    var achieve = new Object();
    //結果返却用オブジェクト内結果文字列用配列
    achieve.array = new Array();
    //結果返却用オブジェクト内達成値
    achieve.value = 0;
    
    do {
        //変数のリセット
        criticalDice = 0;
        preAchieveValue = 0;
        achieveString =  diceNumber + 'R' + critNumber + '=[';

        //ダイス振るループ開始
        for (var i = 0; i < diceNumber; i++){
            //ダイス振る
            diceRolled = parseInt(Math.random() * faceDice)+ 1;
            
            //ダイスの出目がCRT値を上回ったかチェック
            if (diceRolled >= critNumber){
                criticalDice++;
                preAchieveValue = 10;
            }
            else if (preAchieveValue < diceRolled){
                preAchieveValue = diceRolled;
            }
            
            //振った結果のダイス目を文字列としてachieveStringに記録
            achieveString += diceRolled + ',';
        }

        //一通り振ったところで結果を格納
        achieveValue += preAchieveValue;
        achieveString = achieveString.substr(0, (achieveString.length - 1))
                        + ']=' + achieveValue;
        
        //ファンブル処理
        if (preAchieveValue == 1 && count == 0){
            achieveString += ' Fumble!!';
            criticalDice = 0;
        }
        
        //クリティカル処理
        if (criticalDice !== 0){
            achieveString += ' Critical!!';
            diceNumber = criticalDice;
        }
        
        //achieveオブジェクトの配列に達成値を出すまでの文字列を格納
        achieve.array.push(achieveString);
        count++;
        
    } while (criticalDice !== 0);
    
    achieve.value = achieveValue;
    //結果オブジェクト返却
    return(achieve);
}

すいませんほんとに言われたとおりの書きかえです。
でもすごく分かりやすかったです。ありがとうございます。

実行結果

通常。

23:03 (ten-you) #1r10
23:03 (ten-you) ten-you:1R10=[5]=5

ファンブル

23:03 (ten-you) #1r10
23:03 (ten-you) ten-you:1R10=[1]=1 Famble!!

クリティカル。

23:13 (ten-you) #5r7
23:13 (ten-you) ten-you:5R7=[4,9,3,7,7]=10 Critical!!
23:13 (ten-you) ten-you:3R7=[4,2,7]=20 Critical!!
23:13 (ten-you) ten-you:1R7=[10]=30 Critical!!
23:13 (ten-you) ten-you:1R7=[5]=35

当たり前だけど、やっぱりクリティカル値が1下がるとそれだけで全然クリティカル率が変わりますな。

var achieve = new Object();

オブジェクトを作る、という命令。リファレンスで見かけたことはあったのですが、いったいいつ使うものなのかさっぱり見当もついてませんでした。
その一方で、「ファンクションの戻り値が一つしか返せなくて不便だーprefixオブジェクトみたいに複数返せないかなー」と嘆いていた不思議。
海月歩空様ありがとうございます。

pushメソッド

もうひとつ初めて知ったのが「push」メソッド。

概要

与えられた要素を追加することによって配列を変異させ、その配列の新しい長さを返します。

Array.prototype.push() - JavaScript | MDN

配列にあとから要素を追加するメソッドだったんですね。

追記

function event::onChannelText(prefix, channel, text)
{
    //結果返却用オブジェクト
    var achieve = new Object();
    //結果返却用オブジェクト内結果文字列用配列
    achieve.array = new Array();
    //結果返却用オブジェクト内達成値
    achieve.value = 0;
    
    if (text.match(/#\d+R\d+/ig)){

        //該当文字列を配列matchedTextに格納
        var matchedText = text.match(/#(\d+)R(\d+)/i);
         
        //サブファンクションに飛ばす
        achieve = renegadeDice(matchedText[1],matchedText[2]);
        
        //結果を出力
        for (i=0; i < achieve.array.length; i++){
            send(channel, prefix.nick + ':' + achieve.array[i] );
        }

    }
}

    //結果返却用オブジェクト
    var achieve = new Object();
    //結果返却用オブジェクト内結果文字列用配列
    achieve.array = new Array();
    //結果返却用オブジェクト内達成値
    achieve.value = 0;

の部分。
オブジェクトの受け取りだから必要かと思って書いてましたが、以下のように省略してもOKでした。

function event::onChannelText(prefix, channel, text)
{
   
    if (text.match(/#\d+R\d+/ig)){

        //該当文字列を配列matchedTextに格納
        var matchedText = text.match(/#(\d+)R(\d+)/i);
         
        //サブファンクションに飛ばす
        var achieve = renegadeDice(matchedText[1],matchedText[2]);
        
        //結果を出力
        for (i=0; i < achieve.array.length; i++){
            send(channel, prefix.nick + ':' + achieve.array[i] );
        }

    }
}

サブファンクションに飛ばす時に初めてvarつけて変数として宣言してます。
これで十分動きました。柔軟だなあ。