Class Gashapon

java.lang.Object
server.gashapon.Gashapon

public final class Gashapon extends Object
單一轉蛋機(以 npcId 為對外鍵、id 為資料庫主鍵),持有其全部獎勵與累積機率抽選邏輯。

一台轉蛋機對應資料表 gashapons 的一列,其獎勵清單則來自 gashapon_itemsgashaponsid = id)。建構時即自行載入獎勵;獎勵以「累積機率」形式儲存於 items: 每個 Pairleft 是到該筆為止的權重累計上界,rightGashaponReward, 清單最後一筆的 left 即為權重總和。

抽獎以 generateReward() 進行:取 [0, total) 的隨機值,回傳第一個累積上界大於該值的獎勵。 全部公開方法皆 synchronized,使抽獎與單機重載(reloadItems())互斥, 避免並發時讀到「清空到一半」的清單。

  • Constructor Details

    • Gashapon

      public Gashapon(int id, int npcId, String name)
      建構一台轉蛋機並立即載入其獎勵清單。
      Parameters:
      id - 資料庫主鍵(gashapons.id),同時用於查 gashapon_items.gashaponsid
      npcId - 對應的 NPC 編號
      name - 機台名稱
  • Method Details

    • getId

      public int getId()
      Returns:
      資料庫主鍵(gashapons.id)。
    • getNpcId

      public int getNpcId()
      Returns:
      對應的 NPC 編號。
    • getName

      public String getName()
      Returns:
      機台名稱。
    • generateReward

      public GashaponReward generateReward()
      依累積機率抽出一筆獎勵。

      若獎勵清單為空會先嘗試 reloadItems();仍為空、或權重總和 <= 0 則回傳 null。 否則取 n = Math.floorMod(Randomizer.nextLong(), total)n ∈ [0, total)), 回傳第一個累積上界大於 n 的獎勵;理論上不會落空,仍以最後一筆作為防底線。

      Returns:
      抽中的獎勵,或在無可用獎勵時回傳 null
    • getRewardText

      public String getRewardText()
      取得本機台全部獎勵的道具圖示字串,依道具編號由小到大排序,供腳本以 cm.sendOk(cm.getGashapon().getRewardText()) 一次顯示所有可抽中的獎勵。

      逐筆取出 items 內每筆獎勵的道具編號,排序後串接為 #v<道具編號>:# 形式(#v 為楓之谷聊天/對話視窗的道具圖示代碼)。重複的道具編號不會去除 (一台機台可登錄多筆相同道具的獎勵)。synchronizedgenerateReward()reloadItems() 互斥,避免讀到重載中途的清單。

      Returns:
      全部獎勵的道具圖示字串;無獎勵時回傳空字串
    • reloadItems

      public void reloadItems()
      gashapon_items 重新載入本機台的獎勵清單,並重建累積機率索引。

      gashaponsid = id 查詢、依 chance ASC 排序,逐列累加權重後將 Pair(累積權重, 獎勵) 放入 items(先 clear())。讀取失敗只記錄錯誤、 不清空既有清單,待修復後再重載。synchronizedgenerateReward() 互斥。