he01204046 發表於 2011-5-31 22:40:28

自動撿取指定道具到手推車存放~

本帖最後由 he01204046 於 2011-6-1 03:46 PM 編輯

注意事項:
1.角色必須持有手推車。
2.必須開啟@autoloot 自動撿取指令。
3.使用方式:@alootidtocart <物品名稱或編號>。
4.當手推車存放數量或重量已滿,將不會自動放進。
5.使用的原碼為:3ceam r

首先,第一步,新增GM指令:
利用搜尋@alootid,找到GM指令中,自動撿取物品掉落的地方,會找到atcommand.c裡面的
PS:因為我有翻成中文,所以你們找到的應該會是英文,另外這邊的搜尋都是使用整個方案下去搜尋。

/*==========================================
* @alootid
*------------------------------------------*/
ACMD_FUNC(autolootitem)
{
        struct item_data *item_data = NULL;

        if (!message || !*message) {
                if (sd->state.autoloot==0) {
                        sd->state.autolootid = 0;
                        clif_displaymessage(fd, "要先打開@autoloot才有辦法使用本指令。");
                } else {
                        clif_displaymessage(fd, "請輸入要指定撿取物品名稱或編號。");
                        clif_displaymessage(fd, "格式: @alootid <物品名稱或編號>。");
                }
                return -1;
        }

        if ((item_data = itemdb_exists(atoi(message))) == NULL)
                item_data = itemdb_searchname(message);

        if (!item_data) {
                // No items founds in the DB with Id or Name
                clif_displaymessage(fd, "錯誤的物品編號或名稱。"); //顯示訊息
                return -1;
        }

        sd->state.autolootid = item_data->nameid; // Autoloot Activated

        sprintf(atcmd_output, "自動撿取: 「'%s'/'%s' (%d)」。",
                item_data->name, item_data->jname, item_data->nameid);
        clif_displaymessage(fd, atcmd_output); //顯示訊息

        return 0;
}

將整個函數都複製起來,貼在
/*==========================================
* @alootid
*------------------------------------------*/
的上面,並改為

/*==========================================
* @alootidtocart
*------------------------------------------*/
ACMD_FUNC(autolootitemtocart)
{
        struct item_data *item_data = NULL;

        if (!message || !*message) {
                if (sd->state.autoloot==0) {
                        sd->state.autolootidtocart = 0;
                        clif_displaymessage(fd, "要先打開@autoloot才有辦法使用本指令。");
                } else {
                        clif_displaymessage(fd, "請輸入要指定自動撿取並放入手推車的物品名稱或編號。");
                        clif_displaymessage(fd, "格式: @alootitocart <物品名稱或編號>。");
                }
                return -1;
        }

        if ((item_data = itemdb_exists(atoi(message))) == NULL)
                item_data = itemdb_searchname(message);

        if (!item_data) {
                // No items founds in the DB with Id or Name
                clif_displaymessage(fd, "錯誤的物品編號或名稱。"); //顯示訊息
                return -1;
        }

        sd->state.autolootidtocart = item_data->nameid; // Autoloot Activated

        sprintf(atcmd_output, "自動撿取並放入手推車: 「'%s'/'%s' (%d)」。",
                item_data->name, item_data->jname, item_data->nameid);
        clif_displaymessage(fd, atcmd_output); //顯示訊息

        return 0;
}
/*==========================================
* @alootid
*------------------------------------------*/
ACMD_FUNC(autolootitem)
{
        struct item_data *item_data = NULL;

        if (!message || !*message) {
                if (sd->state.autoloot==0) {
                        sd->state.autolootid = 0;
                        clif_displaymessage(fd, "要先打開@autoloot才有辦法使用本指令。");
                } else {
                        clif_displaymessage(fd, "請輸入要指定撿取物品名稱或編號。");
                        clif_displaymessage(fd, "格式: @alootid <物品名稱或編號>。");
                }
                return -1;
        }

        if ((item_data = itemdb_exists(atoi(message))) == NULL)
                item_data = itemdb_searchname(message);

        if (!item_data) {
                // No items founds in the DB with Id or Name
                clif_displaymessage(fd, "錯誤的物品編號或名稱。"); //顯示訊息
                return -1;
        }

        sd->state.autolootid = item_data->nameid; // Autoloot Activated

        sprintf(atcmd_output, "自動撿取: 「'%s'/'%s' (%d)」。",
                item_data->name, item_data->jname, item_data->nameid);
        clif_displaymessage(fd, atcmd_output); //顯示訊息

        return 0;
}

然後你會發現sd->state.autolootidtocart這一段報錯,原因很簡單,沒定義。

因此,我們再搜尋autolootid 會找到pc.h裡面的這一段

unsigned short autolootid; //

一樣,複製一份,改成下面這樣,並貼到上方


unsigned short autolootidtocart; // 配合自動撿取指定物品並放入手推車
unsigned short autolootid; //

這樣一來,報錯的訊息就消失了,然後繼續搜尋autolootitem,會找到。

{ "alootid",           10,10,     atcommand_autolootitem },

一樣複製修改並貼到上面

{ "alootidtocart",           10,10,     atcommand_autolootitemtocart },
        { "alootid",           10,10,     atcommand_autolootitem },

接下來第一步就完成了,記得要到\conf\atcommand_athena.conf裡面新增唷

// 開啟/關閉自動拾取指定道具到手推車
alootidtocart: 0,100

第二步,將GM指令實際套用到物品掉落程式中:

要找物品掉落,當然要從autoloot開始搜尋嚕~然後物品掉落是從怪物掉落,所以很快就會找到mob.c裡面的這一段

        if( sd
                && (drop_rate <= sd->state.autoloot || ditem->item_data.nameid == sd->state.autolootid

這還不是我們要的,我們要找到給玩家物品的那一段判斷式,把畫面往下拉,會看到

        ) {        //Autoloot.
                if (party_share_loot(party_search(sd->status.party_id),
                        sd, &ditem->item_data, sd->status.char_id) == 0
                ) {
                        ers_free(item_drop_ers, ditem);
                        return;
                }
        }

Bingo~找到了

這一段就是給物品的判斷式,二話不說,直接搜尋這一段party_share_loot(或是反白後點選右鍵,移至定義),會找到

//Does party loot. first_charid holds the charid of the player who has time priority to take the item.
int party_share_loot(struct party_data* p, struct map_session_data* sd, struct item* item_data, int first_charid)
{

恩,又中獎了,往下拉,找到。

        if(log_config.enable_logs&0x8) //Logs items, taken by (P)layers
                log_pick_pc(target, "P", item_data->nameid, item_data->amount, item_data);

這一段是訊息記錄,不用裡他,在他的下面新增

    if(log_config.enable_logs&0x8) //Logs items, taken by (P)layers
        log_pick_pc(target, "P", item_data->nameid, item_data->amount, item_data);

    //用於自動將物品放入手推車
    if (pc_iscarton(sd) && item_data->nameid == sd->state.autolootidtocart){ //判斷物品編號是否是指定物品
        for( i = 0; i < MAX_INVENTORY; i++ ) //取得道具在道具欄位中的位置
        {
            if(sd->status.inventory.nameid == item_data->nameid){ //判斷物品編號是否是指定物品
                pc_putitemtocart(sd,i,item_data->amount); //呼叫將物品放入手推車的函數
                break;
            }
        }
    }

完成~接下來就馬上編譯後覆蓋到架設資料夾中,然後啟動到遊戲中測試吧~

首先要輸入"@AUTOLOOT"開啟自動撿取,接下來輸入"@alootidtocart 物品名稱或編號"

舉例,我輸入@AUTOLOOT後再輸入@ALOOTIDTOCART 粘稠液體

然後去租用手推車一台

再去打波利,會發現很神奇的一件事情,就是你打到的黏稠液體,都自動幫你存到手推車中呢了~

以上,完成。

應觀眾要求,附上圖片。

這是手推車上的黏稠液體數量
http://www.badongo.com/t/800/13067991.jpg


這是輸入指令後,打怪取得粘稠液體並自動放入手推車(注意取得道具的地方和手推車上的數量以及身上的數量)

http://www.badongo.com/t/800/13067992.jpg
ngo.com/t/800/13067992.jpg

goddameit 發表於 2011-5-31 22:41:35

回復 1# he01204046


有 附 圖 會 更 好 , 也 比 較 有 說 服 力

he01204046 發表於 2011-5-31 23:00:53

回復  he01204046


有 附 圖 會 更 好 , 也 比 較 有 說 服 力
goddameit 發表於 2011-5-31 10:41 PM http://www.okayro.com/images/common/back.gif


    補上圖片了

devil19891101 發表於 2011-5-31 23:22:07

很不錯的分享和教學唷!

===========

晚點來寫寫直接丟倉或直接賣 - ˇ -

dreamunreal 發表於 2011-5-31 23:22:30

很详细.
但是我看着很头疼- -.
特别是处理塞车那里- -.

code /code 的缩进让我情何以堪`.

he01204046 發表於 2011-6-1 00:21:44

很详细.
但是我看着很头疼- -.
特别是处理塞车那里- -.

c ...
dreamunreal 發表於 2011-5-31 11:22 PM http://www.okayro.com/images/common/back.gif


你可以複製起來貼到筆記上看

為私服而開 發表於 2011-6-1 06:03:57

寫得太複雜了...而且直接用 @alootid/@autoloot  然後再 @alootidtocart

在 @alootid/@autoloot 那裡做手腳, 直接把撿來的自動放到車裡去就好了

he01204046 發表於 2011-6-1 08:44:27

你這樣選擇性會變少...

相信有些人不希望這種自動放手推車的GM指令被人隨意使用吧?

另外自動撿物這點,應該是私服的必備指令了

如果把兩者結合,就真的讓使用的人不知所措了。

而且如果你要整合再一起,相信會改的人自己會去改吧。

畢竟設定上都教給你了,只是小地方修一下。

為私服而開 發表於 2011-6-1 10:26:37

仔細看一下, 有2個問題, 身上帶有原物品, 然後撿到那物品會把原物品一起放到車上

在判定物品卻判定多8個永遠是0的變量

he01204046 發表於 2011-6-1 15:48:17

仔細看一下, 有2個問題, 身上帶有原物品, 然後撿到那物品會把原物品一起放到車上

在判定物品卻判定多8個 ...
為私服而開 發表於 2011-6-1 10:26 AM http://www.okayro.com/images/common/back.gif


1.已經修正
2.抱歉,我忘記改好就放上我在用的那個(我自己用的是設定10組可以自動存放...)...現在已經修正了。

haocong3919 發表於 2011-6-10 15:07:06

希望可以用 謝謝分享

fantasy83115 發表於 2013-4-16 11:42:59

支持一下, 永久收藏=D
印象中3ceam 你有開放這個
{:soso_e113:}
頁: [1]
查看完整版本: 自動撿取指定道具到手推車存放~