[閒聊] 戰役系統
今明兩天是難得有空的時間,我今天先擬好架構,明天打算一股作氣
將系統雛形寫好。之前其實已經寫好一部份了,但因為 times_check
的關係(要改成它可以套用的),就作廢了。
寫戰役系統是為了節慶活動。傳統上舉辦活動需透過 /d/event 目錄
底下各活動物件的寫法,我覺得那個太麻煩了,所以我其實很懶得舉
辦那樣的活動,為了解決這問題才會想寫戰役系統,這樣以後只需要
寫腳本就好了,腳本的好處就是具有可複製性、容易理解、容易管理
及做出變化、...
預計這個東西寫好後,聖殿就有區域產生器、任務系統、副本系統、
戰役系統,這樣艾恩葛朗特計劃就可以實行。
假設使用 /open/cmds/times_check.c 做為驅動引擎,依照斜角巷的
書店寫法,戰役系統必包含底下函數及程式段落:
static object times_check;
void init()
{
::init();
if(!this_files)
this_files=base_name(this_object());
if(!times_check)
if(catch(times_check=find_object_or_load("/open/cmds/times_check")))
return notify_fail("目前 times_check 有問題喔.\n");
幾個供 wiz 使用的 add_action();
}
int times_check(string names,string files,mixed tmps)
{
int s,sk;
string str;
object ppl;
if(!times_check)
if(catch(times_check=find_object_or_load("/open/cmds/times_check")))
return 1;
// 這函數就是 times_check 每隔一段設定時間就會來呼叫的
times_check->set_times_check(戰役標籤,this_files,({參數群}),下一次呼叫間隔);
return 1;
}
然後當有戰役被觸發時,使用的呼叫程式段就是
times_check->set_times_check(戰役標籤,this_files,({參數群}),下一次呼叫間隔)
然後再依 /std/new_ob/boat.c 的寫法,boat 設有 plane 參數,
而 times_check 函數便是依該參數來決定每一個呼叫週期要做哪
些事情。
由上可知,可套用 times_check 的戰役系統必然也是有設定一些
東西--也就是腳本,然後 times_check 函數再依據寫好的腳本來
執行。
一般來說,總管型的戰役系統的 times_check 函數需能做到底下
判斷:
1.各戰役腳本物件的管理及資料載入
2.同一時間多場戰役的狀況顯示及流控管理
3.每一呼叫週期的
a.該做什麼事
b.滿足什麼條件之下才做下一階段的呼叫
c.否則就持續重覆該階段
d.戰役何時結束、失敗、或中止的判斷
戰役腳本物件必須包含這些設定
4.每一呼叫週期至少需可做到
a.呼叫怪物並設置於指定地點
b.進行全域或特定區域廣播
c.判斷怪物存活情況與玩家擊殺數等
.
.
因此仿 /open/cmds/quest,應該要有 /open/cmds/war 這樣的目
錄設置,在該目錄下有多個戰役腳本這樣。
但是,總管型的戰役系統並不是良策(這也是我重寫的原因之一),
因為同一戰役理論上只會在同一時間被開啟一次,因此戰役之間並
不需要「總管流控的物件」,各戰役由各戰役腳本來兼做戰役管理
即可,根據之前的實驗,套用 times_check 的物件即便被 update
也不會影響 times_check 的呼叫,因此由戰役腳本兼做戰役管理
是可行的,帶來的好處就是
1.戰役資料直接本地端存取
2.戰役所需自行編寫的相關管控函數,就直接寫在該戰役物件裡頭
,方便其它 wiz 更容易瞭解該戰役架構組成(因為都寫在同一檔)
3.仍舊可寫一個 war.c 總管物件來依需要讀取各戰役物件的狀態
4.避免 war.c 出現頻繁做資料寫入的情況
5.共通函數就寫 war_sample.c 讓各戰役腳本物件 inherit
架構大致是這樣,times_check.c 的利用我寫得算簡單,因此撰寫
可套用 times_check 的戰役系統應該不難。
腳本檔的部份,一般來說就是仿 quest 的架構,因為 quest 也是
屬於流程式的寫法,並設定有可否通過任務判斷、以及循環條件,
但是戰役系統要做的判斷較多,這部份是否適合全部腳本化,目前
仍有疑義,任務的部份因為需要較多判斷的流程較少(通常只有一兩
個流程需要),所以是採讓 wiz 可自定義函數的做法,但戰役的話
就可能落得每一個流程都需要自定義一個函數來跑,這樣就失去腳
本化的意義。
這個我今天會思考出權宜的做法。
腳本檔編好後,會由 _war.c 指定轉成戰役腳本物件,物件會繼承
sample檔,因此很多函數都會寫在 sample 檔裡頭,我預期會有很
多的內定判斷用函數並可傳值過去,用這個來做腳本檔的簡化,應
該會蠻有效的,我預期這類函數會以 check_ 做為開頭。
最後,腳本物件的資料結構部份,主資料當然以 mapping 格式,雖
然說一個戰役理論上同一時間只能發動一次(直到結束),但我還是
會預留同一時間(實際上會設定不能同一秒)被發動兩次的情況,而
以戰役標籤(就是 time() 值)當做主鍵值,其下再串被寫在腳本檔
的資料。
明天大致就依所編的這些東西來撰寫戰役系統相關檔案。我是希望
寫好後就能拿教庭戰爭來實驗,未來很多戰役的顯示格式會趨向固
定,但亦會保留給 wiz 自訂的空間。
戰役系統寫完後,下一個我預計寫的將是領地爭戰系統,我定義它
是國家系統的外掛系統,參與條件是被授予幾品官職以上,即可選
擇所屬國轄下的領地來治理,主要遊戲目的是與其它國家的領主打
仗。領地爭戰系統是很早就有的構想,但是卡在「副本系統」,必
須先完成副本系統才能實現戰場生成。
LAechan
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.223.250.36
※ 文章網址: https://www.ptt.cc/bbs/mud_sanc/M.1486354250.A.04A.html
※ 編輯: laechan (61.223.250.36), 02/06/2017 13:57:51
討論串 (同標題文章)