- UID
- 71246
- 閱讀權限
- 10
- 主題
- 6
- 帖子
- 72
- 精華
- 1
- A幣
- 39
- 在線時間
- 42 小時
- 最後登錄
- 2024-5-4
集團新軍
![Rank: 1](static/image/common/star_level1.gif)
- 主題
- 6
- 帖子
- 72
- 精華
- 1
- 綜合社群主題發文量
- 16
- 電玩社群主題發文量
- 0
- 娛樂社群主題發文量
- 0
- 技術社群主題發文量
- 1
- 閱讀權限
- 10
- 註冊時間
- 2019-7-14
TA的每日心情![](source/plugin/dsu_paulsign/img/emot/no_1.gif) | 衰 2021-8-26 04:55 |
---|
簽到天數: 26 天 連續簽到: 1 天 [LV.4]偶爾看看III
|
本帖最後由 卡歐悉 於 2021-8-21 17:03 編輯
先打個預防針 老手 高手 勿噴
這邊專門寫給跟我一樣沒有程式語言基礎
自學或者剛學剛踏入這塊的小白
剩下的廢話就不說太多了
如果稍微資質聰穎的可以去看看這篇教學
https://www.namepluto.com/4548/
以下這邊會假是你是純小白
分割線******************************************
首先在你的伺服器資料夾中
點開src中的scripting資料夾
先不要管編譯軟體還是什麼的
你會看到大致上長這樣
使用任何可以編輯文字的軟體去打開
"NPCConversationManager.java"
上面看不懂的亂七八糟先不要理他
你會看到很多
public XXXX OOOOO() {
XXXXXXXXXXXXXX
}
類似這樣內容的東西
NPCConversationManager中所提到OOOOO()就是你之後NPC的JS可以動用到的內容
我們再看一下NPC Conversation Manager
簡單翻譯就是NPC對話管理
Conversation Manager簡稱就是CM
在伺服器資料夾handling\channel\handler\NPCHandler.java中
你可以看到
final NPCConversationManager cm = NPCScriptManager.getInstance().getCM(c);
基本上就是你在JS中打cm.後面接任意的OOOOO()
只要你的OOOOO()符合NPCConversationManager這個裡面定義的內容 就可以使用
沒有的話就會以很多形式報錯
這部分先理解到這邊
接下來舉例
今天以一個任意NPC的代碼
比如隆都魯這個NPC
你可以上網查 可以用你的端口自帶的功能查 以任意的方式去找到這個NPC的代碼
他的代碼是9209003基本上是一個七位數
以這個NPC為例子我們來重新寫他的內容
所以你要先到你伺服器負責管理NPC的JS的資料夾去創建一個9209003.js
資料夾路徑通常會是Libs\scripts\npc
然後接下來有幾點要注意 113的端口有些中文只支援BIG5編碼
然而很多人會把含有中文的內容寫在UTF8的編碼的JS檔案裡面
這會導致當你寫完一個正確的NPC 點了NPC卻發現類似這篇的問題
http://www.xinbiao-aicl.com/foru ... amp;page=1#pid15459
如果你不知道甚麼是BIG5編碼也無所謂
總之你就想成我們表面上看到的東西 在電腦眼裡可能是完全不一樣
所以到此為止建議是使用專業的編碼軟體或者是使用Notepad++來進行NPC的編輯
https://notepad-plus-plus.org/downloads/
打開notepad並且在上方
找到字元改成BIG5
並在存檔時確認右下方是顯示BIG5
接下來NPC編寫的部分 因為本人也是小白+自學
會有蠻多不專業解釋跟名詞的部分 在此先消毒一下
分割線******************************************
總之我們在打開了9209003.js
並在其中先KEY下以下內容
function start() {
}
function action(mode, type, selection) {
}
總之NPC的JS主體架構大概就分為這兩個部分
有更簡單的可能只有
function start() {
}
這個部分
而JS中常常使用//一串文字
來表示註記 這些註記不會被執行 單純給編寫的人方便後面查看使用 可以放在任何地方
註記的方式分為兩種 一種是// 一種是/* */
以下舉例
ABC//DEFG
ABC/*DEFG*/
以上兩行 會被程式所執行的部分只有ABC
DEFG則是註記
所以我們暫時將程式碼寫成下面
//一開始點NPC執行
function start() {
}
//後續執行
function action(mode, type, selection) {
}
以上面兩行為例 雖然之後都不會動到他們 但是還是可以稍微說明一下
紅色的部分想像成名稱
綠色的部分就是條件 沒有的話就是空 意味著沒有條件
藍色的部分就是內容
這個部分大概記一下就好 對於思考會有點幫助
我們主要將要寫的內容寫入藍色的部分{}之中
這邊先舉例一個的方式
cm.sendSimple("");
sendSimple在113裡面
就是顯是一個對話框
而兩個"中間可以夾你任何想要輸入的文字
這邊附帶一提
有些文字可能會導致NPC無法打開 比如"裏"這個字 這個可能是遊戲中的一些缺字問題 在這邊不多做解釋
不過如果你很確定你NPC寫了沒有問題 卻打不開 可以想想是否有這個可能
然後記得每一段寫完的內容後面要加上;
所以我們先在start後面的{}中寫下
cm.sendSimple("你好");
你現在的程式碼應該看起來像下面這樣:
//一開始點NPC執行
function start() {
cm.sendSimple("你好");
}
//後續執行
function action(mode, type, selection) {
}
這時候別急著按儲存
還有一個很重要的是cm.dispose();
這個代表執行到這邊 遊戲中會結束與這個NPC的對話階段
如果沒有這個東西
你就算把對話框關掉 遊戲還會判斷你還在跟NPC對話
當你要重複跟其他NPC講話或做其他動作
就會看到這個
現在你知道為什麼跟某些NPC對話完會需要EA了
代表他NPC中沒有在該有的段落加入cm.dispose();
加入後並且為了方便你了解 我加入了一點註記
你的程式碼應該長這樣
//一開始點NPC執行
function start() {
cm.sendSimple("你好");//顯示一個帶"你好"的對話框
cm.dispose();//結束對話階段
}
//後續執行
function action(mode, type, selection) {
}
儲存後你遊戲中NPC點開後應該會顯示如下
你問我為什麼是"你好"不是"HelloWolrd"
拜託不要那麼老套了
分割線******************************************
以上介紹了cm.sendSimple();的用法
換言之在NPCConversationManager中找得到的內容
你只要明白正確的用法 都可以在JS中做使用
這些用法有包含 且不限於
判斷一些玩家的狀態 或者抓取一些遊戲中的內容
而且內容間可以互相搭配與限制條件
接下來就來講一下一些條件的判斷
但在介紹之前我們先來介紹另外一樣東西
cm.haveItem()
這是用來判斷玩家背包中是否含有某樣物品
紅寶殼的物品代碼為4000016
今天假設玩家如果包包裏有紅寶殼 NPC就會說有
沒有紅寶殼 NPC就會說沒有
在這我們要學習的就是條件判斷的如果怎麼寫
如果(條件){
內容
}
又如果(條件){
內容
}
剩下{
}
寫成程式碼就是
if(cm.haveItem(4000016)){
cm.sendSimple("有");
}
else{
cm.sendSimple("沒有");
}
整段就會看起來像
//一開始點NPC執行
function start() {
if(cm.haveItem(4000016)){//如果玩家背包中有紅寶殼
cm.sendSimple("有");//顯示一個帶"有"的對話框
}
else{//例外的狀況
cm.sendSimple("沒有");//顯示一個帶"沒有"的對話框
}
cm.dispose();//結束對話階段 這段不寫在if跟else的{}之中是無論執行哪一個最後執行完都會執行這段
}
//後續執行
function action(mode, type, selection) {
}
這邊介紹一個蠻好用的網站
https://www.10bestdesign.com/dirtymarkup/js/
只要將以上的內容丟進去之後
點clean
網頁就會自動幫你的內容作排版
將我們的程式碼丟入之後 整體就會變成像下面這樣乾淨的樣子
儲存到9209003.js後NPC就會顯示如下
分割線******************************************
到目前為止 你應該已經可以讓NPC說出一些簡單的話語跟玩家交互
再來就是怎麼讓NPC做出更複雜的內容
首先任務目標
我們要讓隆都魯說出你好 並且讓他在下一句說想要把紅寶殼換成楓幣 每個紅寶殼可以換100楓幣
在這邊要介紹一個東西 var
var是變數variable的意思
總之寫程式有點像是在讀一個充滿簡化的英文內容
var的用法有很多種 總之我們先舉個栗子
var status=-1;
請理解成"把-1這個東西給status"
再來我們看到function action(mode, type, selection)
這邊大概表示action會受到mode type 跟 selection的影響
舉個例子 打開某些對話比較複雜的NPC
你會看到去除裡面的內容 他們的JS通常會長這樣
var status = -1;
function start() {
action(1, 0, 0);
}
function action(mode, type, selection) {
if (mode == 1) { status++;}
else {status--;}
}
總之我們先介紹mode
與NPC的交互中
以cm.sendSimple為例
我們會看到NPC的介面長這樣
而以cm.sendYesNo為例
我們會看到NPC的介面長這樣
這邊如果點了
是 mode就是1
否 mode就是0
停止對話mode也是0
理解到這邊 上面的程式碼就不難看懂了
var status = -1;//設定一個status變數 值是 -1
function start() {
action(1, 0, 0);//執行start時 mode為1 type為0 selection為0
}
function action(mode, type, selection) {
if (mode == 1) { status++;}//如果mode剛好等於1意味著按下了下一頁 那麼我們把status無論是多少都增加1
else {status--;}//如果mode剛好等於0意味著按下了否或停止對話 那麼我們把status無論是多少都減少1
}
所以我們曉得當沒有點NPC的時候status 為-1
當點了NPC之後執行了function start() 他默認了我們點了一次下一頁
所以我們現在的status 來到了-1+1=0
到這邊我們就繼續寫下面的部份
目前我們擁有的就是 點開NPC後status值是0
步驟1:當status剛好為0時顯示你好
程式碼:
if (status == 0) {
cm.sendYesNo("你好");
}
注意這時候我們用的是sendYesNo而不是sendSimple
而且因為對話階段沒有要結束 所以我們不用加上cm.dispose();
步驟2:當status剛好為1時顯示要用紅寶殼換100楓幣嗎?
程式碼:
else if (status == 1) {
cm.sendYesNo("用紅寶殼換100楓幣嗎?");
}
步驟3:當status剛好為2時判斷玩家有沒有紅寶殼 沒有的話顯示沒有紅寶殼 有的話玩家扣除一個紅寶殼 獲得100楓幣
程式碼:
else if (status == 2) {
if (cm.haveItem(4000016)) {
cm.gainItem(4000016, -1);
cm.gainMeso(100);
cm.dispose();
} else {
cm.sendSimple("你沒有紅寶殼");
cm.dispose();
}
}
注意最後防止玩家點擊繼續而出現status=3的情況 我們使用了sendSimple來傳送"你沒有紅寶殼"
整段JS的程式碼會如下
var status = -1;
function start() {
action(1, 0, 0);
}
function action(mode, type, selection) {
if (mode == 1) {
status++;
}
else {
status--;
}
if (status == 0) {
cm.sendYesNo("你好");
} else if (status == 1) {
cm.sendYesNo("用紅寶殼換100楓幣嗎?");
} else if (status == 2) {
if (cm.haveItem(4000016)) {
cm.gainItem(4000016, -1);
cm.gainMeso(100);
cm.dispose();
} else {
cm.sendSimple("你沒有紅寶殼");
cm.dispose();
}
}else{
cm.dispose();
}
}
加上註釋後
var status = -1;//設定一個status變數 值是 -1
function start() {//點擊NPC後會執行START
action(1, 0, 0);//執行START時 mode設定為1 type為0 selection為0
}
function action(mode, type, selection) {//start後執行的動作
if (mode == 1) {//當玩家在對話中選擇同意 下一步 或者選擇對話中的選項
status++;//使status多1
}
else {//反之{當玩家並非在對話中選擇同意 下一步 或者選擇對話中的選項)
status--;//使status少1
}
if (status == 0) {//當status正好為0
cm.sendYesNo("你好");//傳送一個帶YesNo按鈕 內容為 你好 的對話框
} else if (status == 1) {//當status正好為1
cm.sendYesNo("用紅寶殼換100楓幣嗎?");//傳送一個帶YesNo按鈕 內容為 用紅寶殼換100楓幣嗎 的對話框
} else if (status == 2) {//當status正好為2
if (cm.haveItem(4000016)) {//判斷如果玩家擁有4000016即紅寶殼
cm.gainItem(4000016, -1);//獲得-1個紅寶殼
cm.gainMeso(100);//獲得100楓幣
cm.dispose();//結束對話
} else {//判斷除了"如果玩家擁有4000016即紅寶殼"的例外狀況 在這邊即為沒有紅寶殼
cm.sendSimple("你沒有紅寶殼");//傳送一個不帶YesNo按鈕 內容為 沒有 的對話框
cm.dispose();//結束對話
}
}else{//當status 不是0 1 2 等以上狀況 在這邊剩下的可能即為status為-1
cm.dispose();//結束對話
}
}
將以上的情況都設想到之後
你就完成了一個可以用紅寶殼兌換楓幣
且可以點擊是否與停止對話
或者使用ESC直接關閉對話階段
都不會報錯或需要EA的NPC
實際執行結果
對話階段1 status為0
對話階段2 status為1
對話階段3 status為2
有紅寶殼的狀況
對話階段3 status為2
沒有紅寶殼的狀況
將對話當中的判定物品替換掉
就可以完成簡單的蒐集兌換
20210821更新
|
|