前回の改造術でモンスターから複数個のアイテムドロップ法を紹介しました。
しかし、欠点は毎度同じような個数でつまらないという事です。
そこで今回は確率という概念を見直し、倍率の仕様を大幅に変えることに挑戦してみます。
説明しますと、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分 編集・削除
こんにちは。
こちらの方法をためそうとしたのですが、コンパイルするときにエラーがでてしまいました;
どうすればいいのかくわしく教えてくれませんか??