記事一覧

収集品に光を その2

ファイル 348-1.jpg

前回の改造術でモンスターから複数個のアイテムドロップ法を紹介しました。
しかし、欠点は毎度同じような個数でつまらないという事です。
そこで今回は確率という概念を見直し、倍率の仕様を大幅に変えることに挑戦してみます。

説明しますと、50%確率のアイテムで倍率5倍のドロップ率で、今までの倍率では
50% * 5 = 250%
でした。
しかし今回は、「倍率の回数分ドロップ判定を行う」という仕様にします。
50% * 5回判定 = 0~5
これである程度バラつきを再現し、本来の"確率"の概念を活かすことができます。
続き
改造対象はmob.c、前回の改造点は考慮しないで真っさらな状態で説明します。
今回はmob_droprate_fixは使いません。
何も手を加えず次に飛びます。

mob_damageブロック、アイテムドロップの部分でまずは変数の宣言をします。
今回はドロップ数を示す「num」の他に、繰り返し回数を示す「j」も宣言します。
mob.cの1906行目あたり、for構文内の変数制限の部分

	for(i=0;i < ITEM_DROP_COUNT;i++){
            struct delay_item_drop *ditem;

に、新しく「num」と「j」を宣言させます。
numの初期値は0、jの初期値は考慮しなくても構いません。

        for(i=0;i < ITEM_DROP_COUNT;i++){
            struct delay_item_drop *ditem;
            int num=0,j;

次に、今回は倍率をかける処理は行いませんので、mob_droprate_fixを呼び出す部分を無効にします。
そして無効にしたあとは、等倍のドロップ率を以降の処理の円滑化のため、変数「drop_rate」に入れておきます。
mob.cの1910行目から

        if(mob_db[md->class].mexp > 0)
            drop_rate = mob_droprate_fix( mob_db[md->class].dropitem[i].nameid, mob_db[md->class].dropitem[i].p, 1 );
        else
            drop_rate = mob_droprate_fix( mob_db[md->class].dropitem[i].nameid, mob_db[md->class].dropitem[i].p, 0 );
        if(drop_rate <= 0 && battle_config.drop_rate0item)
            drop_rate = 1;

のmob_droprate_fixを呼び出してるif文をまとめてコメントアウト(無効化)させ、
等倍のドロップ率を変数「drop_rate」に代入させます。

//       if(mob_db[md->class].mexp > 0)
//           drop_rate = mob_droprate_fix( mob_db[md->class].dropitem[i].nameid, mob_db[md->class].dropitem[i].p, 1 );
//       else
//           drop_rate = mob_droprate_fix( mob_db[md->class].dropitem[i].nameid, mob_db[md->class].dropitem[i].p, 0 );
        drop_rate = mob_db[md->class].dropitem[i].p;
        if(drop_rate <= 0 && battle_config.drop_rate0item)
            drop_rate = 1;

そして今回最大のポイント、ドロップ判定の部分です。
ここでは「倍率の分だけドロップ判定を回数分判定し、正の場合にnum+1」とさせます。
今回はbattle_configのitem_rate(ドロップ率設定)をそのまま流用しますが、個別に倍率をかけたい場合はここでは説明を省きます。
また、item_rateの1の位、10の位は判定されないのでご了承ください。

mob.cの1916行目あたり、

        if(drop_rate <= atn_rand()%10000)
            continue;

をごっそり次に置き換えます。
最後には前回の最後に説明した「装備品の場合はnum=1」を忘れずに。

        for(j=battle_config.item_rate/100; j>0; j--) {
            if(drop_rate > atn_rand()%10000)
                num++;
        }
        if(num == 0)
            continue;
        if(itemdb_type(mob_db[md->class].dropitem[i].nameid) == 4 ||
        itemdb_type(mob_db[md->class].dropitem[i].nameid) == 5 ||
        itemdb_type(mob_db[md->class].dropitem[i].nameid) == 8)
            num=1;

繰り返し回数の「j」にitem_rateの100で割った値を入れ、回数分をセットさせています。
そして、回数分ドロップ判定をループさせています。

そして、最後にはドロップ処理の1つずつしかドロップさせない頑固者を変更させます。
前回にも説明したので、場所と置き換え文を簡単に書きます。

mob.cの1921行目あたり、ドロップ情報ditemのamount部分

        ditem->amount = 1;

        ditem->amount = num;

mob.cの1486行目あたり、map_addflooritem関数

        map_addflooritem(&temp_item,1,ditem->m,ditem->x,ditem->y,ditem->first_bl,ditem->second_bl,ditem->third_bl,0);

        map_addflooritem(&temp_item,ditem->amount,ditem->m,ditem->x,ditem->y,ditem->first_bl,ditem->second_bl,ditem->third_bl,0);

これでバラつきのある複数個ドロップが実現できたと思います。
確率の特性である点を活かし、極端に言えば100倍の倍率で
50%の収集品が1個も出なかった、
0.01%のカードが100個ドロップした、
とか有り得ます。確率的に恐ろしいことですが。

しかしループ回数を使っているので、すごく高い倍率の場合、処理が重くなってしまう可能性もあります。
また適用する場合、市場に大きな変化をもたらし、ゲームバランスが崩れてしまうことも考えられます。
適用の際は、慎重にお考えください。

コメント一覧

ジッタ 2007年06月25日(月)16時37分 編集・削除

こんにちは。
こちらの方法をためそうとしたのですが、コンパイルするときにエラーがでてしまいました;
どうすればいいのかくわしく教えてくれませんか??

Blaze 2007年06月25日(月)22時27分 編集・削除

ジッタさん、こんにちは。
ちょっと情報が少なくて指摘箇所が見つからないのですが・・・
使用環境・エラー内容などを書いてくださると心強いです。

参考までに、この改造術を紹介したときのAthena環境は2304を使用しています。
もう一度、弄った所などをご確認ください。

ゼル 2008年04月25日(金)19時31分 編集・削除

100倍なら100回判定となっていますが
この判定を倍率ではなく、個別にはできないでしょうか?
例えば、100倍だけど10回しか判定はしない。という事です。
これができれば、倍率を高めてもなんとかなりそうなので…
自力でやれないのに要望を出してしまってすみません。
もしやっていただけるのなら、その時はよろしくお願いします。