Fw: [閒聊] 戰爭/戰役系統

作者: laechan (揮淚斬馬雲)   2015-12-21 10:22:29
※ [本文轉錄自 mud 看板 #1MTs8EMm ]
作者: laechan (小太保) 看板: mud
標題: [閒聊] 戰爭/戰役系統
時間: Mon Dec 21 10:20:58 2015
戰爭系統有幾個關鍵元素
1.戰爭腳本檔及腳本物件
腳本檔應包含怪物/npc的召喚及命名,盡可能把戰爭所需的一切設定
都寫在腳本內,讓一個腳本=一場戰爭,這樣類似的戰爭以後就僅需
複製腳本檔來改即可。
另外,腳本檔的架構也應單純,易懂,好理解。這樣即便是玩家,看
 過腳本檔後也可以有能力提供戰爭腳本。
然後再透過寫好的工具,將腳本檔→腳本物件,則一場戰爭基本上就
 是讀取腳本物件的資料來進行。
2.戰爭管理指令
例如假設指令為 war,則比方 war read 腳本檔,就是讀取腳本檔的
 資料,轉成物件檔來儲存;war half 腳本名,則可以暫時中斷某一場
戰爭的進行;war stop 腳本名,則可以中止一場戰爭;war test 腳
本名,則可以進行一場戰爭腳本的相關測試等;....
對 wiz 來說,撰寫這些語法就能對戰爭做各種管理;對玩家來說,例
 如 war check 語法,可讓玩家查詢正在進行中的戰爭;war list,可
讓玩家查詢 mud 內目前共有哪些戰爭可以玩、各戰爭的基本資訊為何
 等等。
3.怪物/npc 繼承檔
戰爭中召喚出的怪物或 npc 與一般的怪物/npc是不一樣的,因此需有
 自訂的繼承檔讓這些怪物或 npc 來繼承。
其中,最為關鍵的就是「召喚出的怪物/npc 在腳本檔內的定義方式」。
例如以直覺的想法來說,腳本檔內的怪物定義區可以這樣子定:
等級 種族 怪物名 ....
mobs=
mob1:90,beast,魔獸戰隊,...
mob2:92,dragon,魔龍戰隊,...
.
.
##
然後,我在 sanc 撰寫任務系統時,在腳本內導入了 macro,在 macro
欄位內的東西會原封不動變成腳本物件內的 #define 區,例如
// 這一區可由玩家提供資料,由 wiz 來進行設定
macro=
#define MOBS ([\
"mob1":({90,"beast","魔獸戰隊",...}),\
"mob2":({92,"dragon","魔龍戰隊",...}),\
])
#define ROOMS ([\
"church":"/area/town/church",\
])##
上面的東西在 xxx.c 腳本物件內就會放在檔頭的 #define 區。
這樣一來,例如戰爭的第 n 步驟,是召喚魔獸戰隊跟魔龍戰隊進攻城鎮
內的教堂:
war_n=
魔王軍進攻了城鎮內的教堂!!
clone_mob("mob1",5,"church")
clone_mob("mob2",5,"church")##
接著,假設玩家必須清掉 church 内的所有怪物,戰爭才會往下一步驟
進行時,就必然會有一個 check 機制:
war_check_n=
war_check("check_mob","WAR_MONSTER","church")##
上面的意思是說,war_check 是一個寫在腳本物件繼承檔內的函數,各腳
本都可以使用的,而在 war_check 這個函數內則定義了各種的 check 判
斷,例如 "check_mob","WAR_MONSTER","church" 這一組資料就是用來判
斷 "church" 這個房間的 WAR_MONSTER 怪物死光了沒:
int war_check(string kind,string mob_name,string room_name)
{
switch(kind)
{
case "check_mob":
// 抓不到房間資料就當做怪物已打死
if(!room=find_object(ROOMS[room_name])) return 1;
// 在 room 裡面找不到 id 為 mob_name 的怪物就當作怪物已死光
if(!present(mob_name,room)) return 1;
return 0;
break;
.
.
}
}
這樣當戰爭管理系統對 war_n 做定期判斷時,只要 war_check_n 回傳的
值不等於 1,戰爭就永遠停留在第 n 步驟,直到怪物被打死或消失。
以這種型式所寫成的戰爭系統,依個人經驗,它也可以支援「攻城戰」,
例如一座在 mud 內早已存在的城,有城門及城內區域等,假設攻城戰必須
由 wiz 開啟(例如每個禮拜六晚上),則第一步驟就是召喚出「城門 mob」
,例如它是一隻打不還手的 mob,血量有一億,而線上最強的玩家每秒可
以給予該城門 mob 的傷害值最多就是 1 萬時:
那如果只有一名玩家攻城,他要打 10000 秒才能把城門打破
反之,如果有 30 名玩家參與攻城,可能就只需幾百秒就能把城門打破
war_check_1=
war_check("check_mob","WAR_MONSTER","castle_door")##
這樣當城門被攻破(打死)時,war_check_1 找不到城門怪了,戰爭管理系
統就會開始呼叫 war_2 進行下一步驟。
上面有提到一個「戰爭管理系統」,這東西其實可以跟「戰爭管理指令」
寫在一起,例如指令檔的本身也兼管理檔,或是指令檔、管理檔分開寫亦
可。
它主要是做進行中的戰爭的流程控管、戰爭的自動開啟與否、以及下次戰
爭需要再等多久才能開啟等等,它亦可做「戰爭成就歷史資料統計與查詢
」,例如說:
1.某一場戰爭最快被結束的時間
2.單一玩家在某一場戰爭中最多的殺怪數
3.單一隊伍在某一場戰爭中最多的殺怪數
4.戰爭中的最終階段BOSS被KO的最短時間
.
.
以上,一點分享。我正在 sanc 撰寫這樣的系統。
Laechan@Sanc

Links booklink

Contact Us: admin [ a t ] ucptt.com