Re: [wizs] 幾個東西
看板mud_sanc (Sanctuary - 聖殿)作者laechan (揮淚斬馬雲)時間2周前 (2025/02/08 04:45)推噓0(0推 0噓 4→)留言4則, 1人參與討論串3/3 (看更多)
再來講任務的隨機性部份,因為這篇可能有點長就跟前一篇切開。
(前一篇也可能還有啥要補充的)
任務受限於我在撰寫時的架構,使得它之後要弄一些東西時變得礙
手礙腳(比方 nonseq 就是一例)。後面我也想了很多方法要來突破
這些架構上的障礙,最近才想到怎麼做。
首先是任務進行中的 input_to 做法,這個我在
/open/cmds/quest/l/l002 有實驗過是可行的,然後鍊金術士轉職
任務 l011 也有這樣的應用:
write("請十秒內回答將空格應輸入的符號列出:\n"+datas[0]);
input_to("cala_over",0,ppl,datas[1],0,str);
因為任務的隨機性裡頭很常遇到「讓玩家先做出某種選擇,然後才
依玩家的選擇產生不同的路線或結果」這樣的情況,所以這部份先
提(包括範例在哪)。
那簡單的說,假設我們希望任務第 n 步驟有隨機性,這裡提供一個
超級簡單的做法,就是「自訂第 n 步驟」即可,就是土法煉鋼去模
擬第 n 步驟的進行。
以 quest 指令進行第 n 步驟的流程是
1. stepn_check
2. 通過 stepn_check 後的對話演示
3. stepn_end
玩家會獲得完成第 n 步驟的任務標記
那所謂 土法煉鋼去模擬第 n 步驟的進行 的意思就是
1. stepn_check
這裡就直接呼叫所在房間的某函數
2. 讓某函數利用 call_out 去跑任務對話
然後在某函數裡面 wiz 就想做什麼變化都可以
3. stepn_end
玩家會獲得完成第 n 步驟的任務標記
然後把 選擇 跟 土法煉鋼寫函數 切開,弄成兩個步驟,比方先在
前一步驟讓玩家選擇,然後才進行下一步驟跑自定函數,並在自定
函數中依玩家在前一步驟的選擇,跑不同的流程或結果。
然後不管如何玩家都會獲得完成任務第 n 步驟的標記,因此若想讓
玩家在前一步驟依選擇的不同,可能某些選擇是無法完成該任務步
驟時,那就應該在前一個流程的選擇那邊,就直接擋掉。
比方玩家選 1 或選 2 是錯的,那就要在選擇後就直接擋掉,或是
亦可在選擇後的次一步驟的 stepn_check 時擋掉。
(畢竟 stepn_check 函數也可以自訂)
接著是模擬對話,語速通常兩秒跑一次,因此先把一串對話打好
mixed chats=({
"對話1",
"對話2",
.
.
.
});
i=0;
foreach(tmp in chats)
call_out("show_talk",i++2,tmp);
void show_talk(string tmp)
{
write(tmp);
}
以上是最基本的土法煉鋼對話模擬,那建議參考
/open/cmds/quest/quest_data/quest_data.c
的 heart_beat 函數中關於 msg_buf 的部份:
msgs=msg_buf[tmps[i]];
jj=sizeof(msgs);
for(ii=0;ii<jj;ii++)
{
if(msgs[ii][0] && msgs[ii][1] &&
environment(msgs[ii][0])==msgs[ii][1])
tell_object(msgs[ii][0],""+msgs[ii][2]+"\n");
也就是玩家若提早離開房間,是否仍持續顯示,wiz 可自行
決定,預設的 msg_buf 是玩家若提早離開房間就不會再繼續
看到對話。
然後隨機性指的就是,比方第 n 步驟,透過土法鍊鋼,就能
告知玩家,任務指定要的東西或是需達成的條件,擁有兩種以
上可能的情況,這時玩家若不完整看完對話,就可能有不知道
到底要達成的是哪一種的情況,但沒關係,可以在 n+1 步驟
的 check 告知
第 n+1 步驟: stepX_check,這裡先判斷第 n 步驟 npc 要玩
家滿足的條件或是要取得的東西是什麼,然後就
在這裡告訴玩家即可。
這樣玩家就算跳過對話(第 n 步驟已完成),也可以透過 quest
指令得知剛剛那個步驟,它要滿足的條件或取得的東西是什麼。
雖然麻煩了些,但土法鍊鋼應用在這部份上面好處多多,可突
破 quest 既有架構的先天限制,並且可讓 wiz 隨心所欲。
我最近就會將這東西應用在 /open/cmds/quest/l/l013 絕頂改
裝上頭:
.
.
$N讀完 Page.49 後,將書本闔上後放回原位。
$N: 以蘋果做成的美味甜點嗎......##
step6_npc=/u/l/laechan/special/mob/zero##
step6_msg=
$M: 你來啦? 吾輩一直在等你哪
$N: 是的,魔女大人,這就是以蘋果做成的美味甜點。
$M: 喔喔,這...這是!! (≧▽≦)b
$M雙眼發亮,很快地收下了你準備的蘋果派
.
.
目前零固定要求玩家獻上蘋果派,但若自寫函數來模擬第 5 步
驟,就可以要求玩家獻上不同的東西,然後
step6_check()
{
先讀取 step5 裡頭它隨機要求的東西是什麼;
再判斷玩家是否滿足條件:
若不滿足就告知玩家需滿足什麼條件;
}
以零那格的寫法因為零不是 NPC 因此自訂函數我寫在零上面,
或是零所在的那格都可以。
這東西因為與鍊金術士有關,若寫好我也會回鍊金術士討論串
那篇文,來說明絕頂改裝任務改版後的流程說明。
到時就有範例,然後 wiz 也可以先自行實驗,雖說目前僅止於
理論,但應該是可行的,就任務標記要自行追加,以及要用一
些欄位來紀錄隨機這部份,比方魔女要求蘋果派時,如何讓這
個要求被記住:
1. 建議仍是用 record_data
2. 或是 myhome 的 my_data
3. 或是撰寫玩家可重新回到隨機前狀態或是重接任務的機制
說到這個,讓玩家重接任務或是倒回第 n 步驟,建議可使用
void init()
的指令宣告方式,看要寫在哪,提示玩家可透過去哪裡下什麼
指令來重新接取這個任務、或是倒回第 n 步驟。若以這東西
的存在為前提時,則比方蘋果派的任務就能設定在 temp_data
區,玩家知道三種要求的東西裡面,蘋果派最難,他希望能放
棄重選時,玩家只要去某地方下某指令即可。
(當然前提是玩家必須知道去哪裡、下什麼指令)
Laechan
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.33.120.231 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/mud_sanc/M.1738961155.A.C61.html
補充,讀取、設定任務標記的做法
quest query laechan l013
quest: ({ "l013", 5, 0, "2023/07/01", 1688199903 })
UNDEFINED
任務編號 l013
完成了第幾步驟 5
該任務是否done 0 若是 1,該任務除非有 repeat 參數不然不能再接
任務更新標記 "2023/07/01"
任務完成時間 1688199903 這兩個也可能顛倒,反正平常用不到
在 /open/cmds/quest/quest_data/quest_data.c 裡頭
主要看 quested 函數:
varargs mixed quested(string kind,string names,string quest_num,mixed vars)
{
switch(kind)
{
case "set":
// 採嚴格設定法,沒有列入的參數均不准設
if((string)vars[0]=="times" && intp(vars[1]))
set_quest_data(names,quest_num,qq[1],vars[1],qq[3]);
else if((string)vars[0]=="steps" && intp(vars[1]))
set_quest_data(names,quest_num,vars[1],qq[2],qq[3]);
else
return -1;
case "check":
// 第一種 check: 確認 names 有沒有解過 quest_num, 以及有沒有滿足解到幾次
if((string)vars[0]=="times")
// 第二種 check: 確認 names 是否已經解 quest_num 解到第 n 步驟
// vars 沒給第二參數時就預設判斷有沒有解第一步驟
if((string)vars[0]=="steps")
該 quested 可用 questing 全域函數來呼叫,後面接的參數都一樣,
所以以 set 為例,語法是
questing("set","玩家id","任務編號",
({"times",1 })); // 設定任務解了幾次
({"steps",5 })); // 設定任務已解了第幾步驟
以 check 為例,語法市
questing("check","玩家id","任務編號",
({"times",1 })); // 該任務已解次數是否為 1
({"steps",5 })); // 該任務是否已解到第 5 步驟
check 可不需要第 2 參數,比方
questing("check","玩家id","任務編號",({"times"})); // 判斷有無解過
questing("check","玩家id","任務編號",({"steps"})); // 判斷有無完成第1步驟
以上供參,也是備忘,因為我自己很容易忘記這些東西^^;
※ 編輯: laechan (114.33.120.231 臺灣), 02/08/2025 10:08:16
我剛剛看 quested 函數,裡面有關於 msg_buf 的部份
case "msg_buf":
switch(names)
{
case "add":
if(ob=find_player(quest_num))
{
if(tmp_ob=environment(ob))
{
if(stringp(vars))
add_msg_buf(ob,tmp_ob,({vars}));
else if(arrayp(vars))
add_msg_buf(ob,tmp_ob,vars);
}
}
break;
}
break;
我原本以為這是 query msg_buf,但反正它只有 "add",或許我之後
會新增 query 的部份,理論上是
questing("msg_buf","query","任務編號",({可能第幾步驟}));
說到這個我想起我好像有寫任務對話總覽的指令
quest check_msg 腳本編號 msg 確認
j=quest_ob->query_quest_steps();
for(i=1;i<=j;i++)
{
if(steps>0 && steps!=i) continue;
if(tmps=quest_ob->query_quest_msg(i))
看起來就是若已讀取了 quest_ob 物件就直接取得 steps 及 msg,
反之,若不想讀 quest_ob 就以 questing 呼叫,而寫在questing
內的判斷就必須包含 steps 的可用範圍判斷。
※ 編輯: laechan (114.33.120.231 臺灣), 02/08/2025 12:06:28
→
02/08 12:06,
2周前
, 1F
02/08 12:06, 1F
→
02/08 12:07,
2周前
, 2F
02/08 12:07, 2F
→
02/08 12:08,
2周前
, 3F
02/08 12:08, 3F
→
02/08 12:08,
2周前
, 4F
02/08 12:08, 4F
討論串 (同標題文章)
mud_sanc 近期熱門文章
PTT遊戲區 即時熱門文章
2
10