微信扫一扫 分享朋友圈

已有 7238 人浏览分享

[服務器教學] 潮流轉蛋機 NPC 腳本分享(優化版)

  [複製鏈接]
匿名
匿名  發表於 2022-6-22 19:17:05 | 閱讀模式
本帖最後由 leseigk 於 2022-6-22 20:11 編輯

如果程式碼邏輯有問題、有BUG、註釋不清楚或者針對程式碼有更好的優化建議的話都歡迎回復指出~
希望能跟大家一起交流一起進步。

本著利玩家主義優化了一下自己很久以前寫的轉蛋機NPC腳本,優化的內容如下:

  • 單抽十抽
  • 有獎池查看功能。
  • 可連續轉蛋、從單抽轉到十抽、從十抽轉到單抽、返回主菜單和結束轉蛋。
  • 抽中指定道具可上綠廣。
  • 十抽會根據剩餘的背包欄位數和轉蛋卷數量決定要幾抽,如果轉蛋卷不足十張或者欄位數不足十個就會根據哪個剩餘的數量較小就轉幾次,避免被吞。
  • 會判斷抽到的是哪個類別的道具,檢查對應類別的欄位數。

效果演示


程式碼

/*
 * 轉蛋機 NPC
 * 2022/06/19 優化版
 */
var status = -1;
var req = [5220000, 1];

// 獎池
var itemList = [
  1322060, 1332073, 1372044, 1382057, 1072355, 1072356, 1072357, 1112478,
  1462085, 1001059, 1051201, 1012173, 1012174, 1122023, 1012157, 1492073,
  1482073, 1402085, 1122034, 1102004, 1102040, 1102041, 1002931, 1052190,
  1122035, 1002932, 1002933, 1372071, 1382093, 1312056, 1412055, 1322084,
];

// 特殊獎品, 會上綠廣的
var gachItem = [1122034, 1122035, 1012173, 1012174];

function start() {
  action(1, 0, 0);
}

var rewards = ""; // 獎品列表
var times = 0; // 消耗的轉蛋卷數
var haveSpace = true; // 還有沒有空間
var haveItem = true; // 還有沒有轉蛋卷
var stop; // result = -1;  => SRC : gainGachaponItem 方法裡面的 addbyId_Gachapon 如果有某個類別欄位已滿會回傳 -1

/* 重置 */
function init() {
  rewards = "";
  times = 0;
  haveSpace = true;
  haveItem = true;
}

/* 轉蛋 */
function draw() {
  var result;
  var random = Math.floor(Math.random() * itemList.length); // 產生亂數抽取獎池其中一個道具
  var item = itemList[random]; // 抽中的道具

  if (cm.getPlayer().itemQuantity(req[0]) - times < 1) {
    // 情況1: 剩餘轉蛋卷不足
    haveItem = false;
  } else if (!cm.getPlayer().haveSpaceForId(item)) {
    // 情況2: 剩餘空間不足
    haveSpace = false;
  } else {
    var special = gachItem.indexOf(item) !== -1;

    // 中了特殊獎
    if (special) {
      result = cm.gainGachaponItem(item, 1, true);
    } else if (!special) { // 一般獎
      result = cm.gainItem(item, 1);
    }

    if (result === -1) {
      stop = true;
    } else {
      rewards += "#i" + item + "#";
      times++;
    }
  }
}

/**
 * 結算
 * @param {*} type 0: 單抽 1: 十抽
 */
function finish(type) {
  if (times > 0) {
    var msg = type === 1 ? "\r\n#L996##b繼續十抽#l #L997##b前往單抽#l" : "\r\n#L997##b繼續單抽#l #L996##b前往十抽#l";
    cm.gainItem(req[0], -times);
    cm.sendNext("恭喜獲得\r\n" + rewards + msg + "\r\n#L998##r結束轉蛋#l #L999##d返回上一頁#l");
  } else if (!haveSpace || stop) {
    cm.sendOk("不好意思,請確認您的背包是否有空位。");
  } else if (!haveItem) {
    cm.sendOk("不好意思,您身上的#b#t" + req[0] + "##i" + req[0] + "##k不足!");
  }
  init();
}

function action(mode, type, selection) {
  if (mode == 1) {
    status++;
  } else {
    cm.dispose();
    return;
  }

  if (status === 0) {
    /* 檢查身上是否有轉蛋卷 */
    if (cm.haveItem(req[0], req[1])) {
      var msg = "您身上有#b#t" + req[0] +"##i" + req[0] + "##k可以進行轉蛋。\r\n你確定要使用 #b#p" + cm.getNpc() + "##k 進行轉蛋嗎?\r\n #L0#我要單抽! #l \r\n #L1#我要一次抽#r十個#k!#l \r\n #L2##b查看轉蛋機內容物!#l";
      cm.sendYesNo(msg);
    } else {
      cm.sendOk("不好意思!您沒有#b#t" + req[0] + "##i" + req[0] + "##k,無法進行轉蛋。");
      cm.dispose();
    }
  } else if (status === 1) {
    /* 根據選擇擇的選項做對應的事情 */
    switch (selection) {
      // 單抽
      case 0:
        if (!stop && haveSpace) {
          draw();
        }
        finish(0);
        break;
      // 十抽
      case 1:
        for (var counts = 0; counts < 10; counts++) {
          if (stop || !haveSpace) {
            break;
          }
          draw();
        }
        finish(1);
        break;
      // 確認獎池
      case 2:
        var msg = "";
        for (var i = 0; i < itemList.length; i++) {
          if (i % 8 == 0) {
            msg += "\r\n";
          }
          msg += "#i" + itemList + "#";
        }
        cm.sendSimple("" + msg + "\r\n #L999##r退回上一頁#l");
        break;
    }
  } else if (status === 2) {
    switch (selection) {
      // 繼續十抽
      case 996:
        status = 0;
        action(1, 0, 1);
        break;
      // 繼續單抽
      case 997:
        status = 0;
        action(1, 0, 0);
        break;
      // 退出轉蛋
      case 998:
        cm.dispose();
        break;
      // 退回菜單重選
      case 999:
        status = -1;
        action(1, 0, 0);
        break;
      default:
        cm.dispose();
        break;
    }
  } else {
    cm.dispose();
  }
}

這個的邏輯有比較複雜一點所以寫得有點亂,有時間會再思考一下怎麼精簡。

下次分享一下純 JS 的樂透系統 NPC 跟 EVENT 腳本好了,還在優化中...有點懶
共收到 0 金錢
打賞榜
暫無
暫無
暫無
暫無
----
暫無
----
暫無
----
暫無
----

站長

2553

威望

4810

金錢

1

A幣
主題
1337
回帖
1169
精華
3
綜合社群主題發文量
273
電玩社群主題發文量
1
娛樂社群主題發文量
4
技術社群主題發文量
32
閱讀權限
200
註冊時間
2013-1-28

我是傳奇贊助感謝勳章精華作者勳章

  • TA的每日心情
    無聊
    2026-6-23 16:59
  • 簽到天數: 471 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    TWAICL 發表於 2022-6-23 15:21:51 | 顯示全部樓層
    這篇腳本寫的很不錯,滿多服都會需要能連續轉的功能,寫法也能用在很多需要重複兌換的腳本上,方便度提升很多,感謝無私分享!!

    小有建樹

    1704

    威望

    1萬

    金錢

    111

    A幣
    主題
    11
    回帖
    173
    精華
    0
    綜合社群主題發文量
    62
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    10
    閱讀權限
    70
    註冊時間
    2022-3-25
  • TA的每日心情

    12 小時前
  • 簽到天數: 1397 天

    連續簽到: 5 天

    [LV.10]以壇為家III

    SMILE1202 發表於 2022-6-23 19:49:01 | 顯示全部樓層
    NPC 腳本錯誤. 它ID為 : 9300008:javax.script.ScriptException: TypeError: cm.getPlayer().haveSpaceForId is not a function in <eval> at line number 55


    請問抽獎出現這個錯誤
    是哪裡有誤嗎??

    集團新軍

    171

    威望

    93

    金錢

    0

    A幣
    主題
    2
    回帖
    28
    精華
    0
    綜合社群主題發文量
    1
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    1
    閱讀權限
    10
    註冊時間
    2017-6-16
  • TA的每日心情
    擦汗
    2022-4-26 09:24
  • 簽到天數: 43 天

    連續簽到: 1 天

    [LV.5]常住居民I

    aa806878 發表於 2022-6-23 20:38:31 | 顯示全部樓層
    SMILE1202 發表於 2022-6-23 19:49
    請問抽獎出現這個錯誤
    是哪裡有誤嗎??

    每個端口的寫法不一樣

    } else if (!cm.getPlayer().haveSpaceForId(item)) {
        // 情況2: 剩餘空間不足

    如我的端口是用! cm.canHold()來判斷空間不足,你可以試試看  再不行開src去找

      } else if (! cm.canHold()) {
        // 情況2: 剩餘空間不足

    初窺門道

    212

    威望

    418

    金錢

    19

    A幣
    主題
    10
    回帖
    66
    精華
    0
    綜合社群主題發文量
    5
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    10
    閱讀權限
    20
    註冊時間
    2021-8-6
  • TA的每日心情
    開心
    2022-7-11 11:36
  • 簽到天數: 14 天

    連續簽到: 1 天

    [LV.3]偶爾看看II

    leo1245 發表於 2022-6-24 14:08:25 | 顯示全部樓層
    遇到 npc錯誤的跳這個 } else if (!cm.getPlayer().haveSpaceForId(item)) { 語法的話  直接改成   } else if (!cm.canHold()) { 這語法就能用了

    小有建樹

    1704

    威望

    1萬

    金錢

    111

    A幣
    主題
    11
    回帖
    173
    精華
    0
    綜合社群主題發文量
    62
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    10
    閱讀權限
    70
    註冊時間
    2022-3-25
  • TA的每日心情

    12 小時前
  • 簽到天數: 1397 天

    連續簽到: 5 天

    [LV.10]以壇為家III

    SMILE1202 發表於 2022-6-24 17:18:41 | 顯示全部樓層
    本帖最後由 SMILE1202 於 2022-6-24 17:52 編輯

    測試可以 又學到了
    多謝兩位熱心幫助

    集團新軍

    25

    威望

    80

    金錢

    0

    A幣
    主題
    0
    回帖
    16
    精華
    0
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    0
    閱讀權限
    10
    註冊時間
    2021-8-29
  • TA的每日心情
    開心
    2022-6-24 22:32
  • 簽到天數: 1 天

    連續簽到: 1 天

    [LV.1]初來乍到

    simonliao 發表於 2022-6-24 22:31:35 | 顯示全部樓層
    請問一下,
    我替換腳本後,查看獎池部分都只能全部顯示第一個道具(放15個道具全部都是顯示第一位置的道具)
    請問有無解決辦法呢?

    集團新軍

    91

    威望

    210

    金錢

    291

    A幣
    主題
    1
    回帖
    19
    精華
    0
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    0
    閱讀權限
    10
    註冊時間
    2023-6-19

    該用戶從未簽到

    s9103756 發表於 2023-6-28 19:20:51 | 顯示全部樓層
    請問大大  我腳本放道具都只顯示第一個 是迴圈部分哪裡有問題嗎

    集團新軍

    18

    威望

    49

    金錢

    0

    A幣
    主題
    0
    回帖
    11
    精華
    0
    綜合社群主題發文量
    0
    電玩社群主題發文量
    0
    娛樂社群主題發文量
    0
    技術社群主題發文量
    0
    閱讀權限
    10
    註冊時間
    2023-8-30

    該用戶從未簽到

    Dragon 發表於 2023-9-13 03:15:41 | 顯示全部樓層
    請問可以更改機率嗎
    您需要登錄後才可以回帖 登錄 | 註冊會員

    本版積分規則

    13

    發文

    64

    金錢

    51

    A幣

    ----------榮譽勳章----------

    熱門推薦
    圖文推薦
    • 聯繫我們

    手機版|小黑屋|AICL社群娛樂集團

    GMT+8, 2026-7-4 20:07 , 網路刷新 0.149435 秒 .

    歡迎來到 AICL網路社群

    版權AICL社群所有 2011-2021.

    Total:123 Today:213 Online:322