記事一覧

収集品に光を

ファイル 347-1.jpg

ROの収入源の1つである収集品アイテム。
モンスターを倒し、戦利品として入手し、店で売ってお金を得る。
また一部の収集品は作成アイテムの材料だったりします。

しかし、Athenaではいまいち実用感が薄い収集品。
高倍率になってくると、収集品を売るよりレアな装備品などを売った方が効率的だからです。
これでは材料として集める機会も少なくなり、作成アイテムの存在感が無くなってきます。

そもそもドロップが高倍率なのに、収集品1つずつしかドロップしないのがいけません。
レアな装備品が出る確率と収集品の入手数のバランスを保つのが本来のMMOの形です。

そこで今回の改造術「収集品のドロップ率で倍率をかけた時、キャリーオーバー分を複数ドロップさせる」を紹介します。

簡単に説明すると、ドロップ率50%のアイテムで倍率5倍の場合、
50% × 5 = 250%
本来ならばここで100%ドロップで済みますが、
キャリーオーバー分150%の分も考慮しここでは2個、50%の確立で+1個という具合にします。
続き
改造対象はmob.cの1点のみ。
変更点が多いので、書き換える前にバックアップを忘れないでください。

まず、ドロップ率の倍率で、100%より上の数値を記憶させるために倍率計算部分を変更します。
mob.cの4059行目からのmob_droprate_fixブロックに、drop率が10000より上は10000に固定する部分が2箇所あります。

    if(drop > 10000) return 10000;

    if(drop_fix > 10000) drop_fix = 10000;

この2行をコメントアウトしてください(無効化します)

//   if(drop > 10000) return 10000;

//   if(drop_fix > 10000) drop_fix = 10000;

これでドロップ率100%より上の数値が記憶されるようになりました。
次に、ドロップ判定させる部分を書き換えます。
少し上に戻ってめちゃくちゃ長いmob_damageブロックの下の方に、死亡処理・経験値配分やドロップ判定させる部分があります。
まず、ドロップ数を記憶させる変数「num」を定義し、使えるようにします。
mob.cの1906行目あたり、for構文内の変数制限の部分

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

に、int型の「num」を宣言させます。
初期値は0に設定させておきます。

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

次が重要なポイントです。
ドロップ判定の際100%より上の数値の場合、numに+1していきながら再度判定、とさせます。
ここではループ構文のwhileを使います。
mob.cの1916行目あたり、ドロップ率の確率計算をする箇所

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

の2行を次のようにごっそり置き換えます。

        while(drop_rate > 10000) {
            num++;
            drop_rate-=10000;
        }
        if(drop_rate > atn_rand()%10000)
            num++;
        if(num == 0)
            continue;

numに判定でドロップさせるべき数を記憶させ、0の場合はドロップしない、という感じになりました。
次はいよいよドロップ処理です。
現在では1つずつしかドロップしない処理になっていますので、num値を使って複数個ドロップさせます。
mob.cの1921行目あたり、ドロップ情報ditemのamount部分

        ditem->amount = 1;

を次のように書き換えます。

        ditem->amount = num;

これでditemのポインタ「amount」に変数「num」の値が代入されました。
しかし、まだドロップ実行処理では1ずつしかドロップさせない頑固者が残っています。
長かったmob_damageブロックを抜け、mob_delay_item_dropブロックに移ります。
似た「mob_delay_item_drop2」とは違いますので気をつけてください。
その最後の方、床にアイテムを設置させる関数に1ずつしかドロップさせないようになってるので書き換えます。
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);

長ったらしいですが、&temp_itemの後ろの"1"に注目します。
これを先ほどドロップ数を記憶させたditem->amountに書き換えます。

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

以上、ここまででアイテムのドロップ数が複数になりました。
お疲れさまでした。

・・・と言いたいのですが、現状装備品が2個など複数個あっても、入手の際は1つずつになります。
これは仕様上仕方の無いことなので、見た目的にも装備品の場合は1つしかドロップさせないようにします。
mob.cの1926行目あたり、ドロップ数を判定させる処理の後~ditemに記憶させる処理の前の間に以下を追加します。

        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;

何のこっちゃ、かもしれませんがitemdb_typeが4の場合は武器、5は防具、8はペット装備品を指し、その場合はnumを1にするようにしてあります。

以上、ここまででアイテムを複数個ドロップさせる改造法を紹介しました。
しかし、使ってるうちに「いつも決まった個数しかドロップしない」とうんざりするかもしれません。
そこで次回、別の複数ドロップ法をお届けしたいと思います。

コメント一覧

auriga 2008年12月07日(日)21時16分 編集・削除

aurigaでは行がずれおり記述も若干違うようですがそれぞれどのようにすればaurigaで動きますか?

ななし 2008年12月25日(木)21時45分 編集・削除

aurigaの回答まだ?