1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FiveM(QBCore)でガチャスクリプトを開発してみた

Posted at

はじめに

FiveMの既存スクリプト(猫カフェuwu)にランダムでアイテムが排出されるガチャBOXがあったが、同じようなガチャBOXを使用したいという話をサーバ運営者と村人の会話があり、luaは初めて触るが作ってみた。備忘録も兼ねて記載する。

仕様

【初回作成時点】
・本スクリプトで複数種類のガチャを扱えること
・排出するアイテム、確率は、外部ファイルで管理できるようにすること
・機能としては、アイテムが1つ出るガチャと複数種類のアイテムがでるガチャを作ること
 (イメージとしては、通常のガチャと福袋的なイメージ)

【機能追加】
・お金をだせるようにも改修(スクラッチとして活用)
・あたりが出た際に、音声を鳴動させるように改修

実際の画面

アイテムを使うとプログレスバーの表示と箱を開けているようなモーションをして、ガチャアイテムが削除されて、排出されるアイテムが取得されます。

gacha.gif

上記で動作させているアイテムは、2つアイテムがランダムで出るように設定している。
※スクリプトの中で通常の1種類しか出ないものと、2種類出るものと使い分けています。
※Gifのアップロード容量上限の関係で早送りみたいに見えています。

ソースコード(一部紹介)

初めてのScript開発だったのと継ぎ足しで開発したりしたので、コードは汚い状態です。
(時間があるときにリファクタリング予定)
また、Scriptの配布やソースコードの公開については現在検討中。

QBCoreの公式ドキュメントに色々と載っているのでコーディングで便利です。

また、よく使うパターンなどをまとめていますので、そちらも良ければ見てみてください。

■fxmanifest.lua
スクリプトの構成は以下のluaの通りです。
ui_pageとfilesは音声を鳴動させるために、必要で追加したものです。

fxmanifest.lua
fx_version 'cerulean'
game 'gta5'

author 'KumaRider'
description 'Gacha System with Sound for QBCore'
version '1.1.0'

-- サーバースクリプト
server_scripts {
    'server/gacha.lua',
    'shared/shared.lua',
}

-- クライアントスクリプト
client_scripts {
    'client/client.lua',
}

-- QBCoreと依存関係があることを宣言
dependencies {
    'qb-core',
}

-- NUIファイル
ui_page 'html/index.html'

-- 必要なファイル
files {
    'html/index.html',
    'html/script.js',
    'html/sounds/*.ogg'
}

■ガチャの出現アイテムと確率
ガチャの出現アイテムと確率は、shard.luaで定義しています。chanceがアイテムの出現確率になります。
合計で100を超えると、100以上のアイテムは出てきません。ただ、実際の画面で映していたように2種類排出されるものについては、1種類目を除外するようにスクリプトで記載しているため、以下は合計112.5としています。

shard.lua
RandomItemCatCafeBox = {
    { item = "kira_kira_currye", count = 30, chance = 12.5 },
    { item = "strawberry_shortcake", count = 30, chance = 12.5 },
    { item = "doki_doki_pancakes", count = 30, chance = 12.5 },
    { item = "rice_balls", count = 30, chance = 12.5 },
    { item = "cat_macaroon_green", count = 30, chance = 12.5 },
    { item = "hot_chocolate", count = 30, chance = 12.5 },
    { item = "booba_milk_tea_1", count = 30, chance = 12.5 },
    { item = "sweet_herbal_tea", count = 30, chance = 12.5 },
    { item = "cat_cafe_box", count = 1, chance = 11.5 },
    { item = "cat_cafe_box", count = 5, chance = 1 }
}

■排出されるアイテムを選定する部分
shard.luaのchanceを足しこみながらヒットしたところで止めるような処理です。

gacha.lua
local randomNumber = math.random() * 100
local accumulatedChance = 0
local selectedItem = nil

for _, v in ipairs(itemList) do
    accumulatedChance = accumulatedChance + v.chance
    if randomNumber <= accumulatedChance then
        selectedItem = v
        break
    end
end

■アイテム付与部分
アイテムの付与はサーバ側の処理で実施するため、gacha.luaに記述しています。

gacha.lua
if selectedItem1 then
    Player.Functions.AddItem(selectedItem1.item, selectedItem1.count)
    TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[selectedItem1.item], "add")
    TriggerClientEvent('QBCore:Notify', src, 'You have received ' .. QBCore.Shared.Items[selectedItem1.item].label, 'success')
end

■開けるモーション部分など
TriggerClientEvent('gacha:openGacha', source, ticketType)で client.luaのgacha:openGachaを発火させています。

gacha.lua
-- ガチャアイテムを使用すると呼ばれるイベント
local function UseGachaTicket(ticketType)
    QBCore.Functions.CreateUseableItem(ticketType, function(source, item)
        local Player = QBCore.Functions.GetPlayer(source)
        
        -- チケットが1枚以上あるか確認
        if Player.Functions.GetItemByName(ticketType) then
            -- ガチャを回すイベントをトリガー
            TriggerClientEvent('gacha:openGacha', source, ticketType)
        else
            TriggerClientEvent('QBCore:Notify', source, 'You do not have a ' .. ticketType .. '.', 'error')
        end
    end)
end

--ガチャ(アイテム)を使用できるように登録(ここを増やせばガチャの種類を増やせる)
UseGachaTicket('gacha_ticket_basic')
UseGachaTicket('gacha_ticket_premium')
UseGachaTicket('cat_cafe_box')
client.lua
-- ガチャを開くイベント
RegisterNetEvent('gacha:openGacha')
AddEventHandler('gacha:openGacha', function(ticketType)
    local playerPed = PlayerPedId()
    local label = "ガチャを回しています..."

    -- 特定のチケットの場合、特別なメッセージを設定
    if ticketType == 'cat_cafe_box' then
        label = "ボックスをあけてるにゃ"
    end

    -- アニメーションをリクエスト
    RequestAnimDict("amb@prop_human_bum_bin@base")

    while not HasAnimDictLoaded("amb@prop_human_bum_bin@base") do
        Citizen.Wait(100)
    end

苦労した点

最初に構築したテストサーバは、QBCoreのバニラ環境であったが、実際に導入する本番サーバはox_lib,ox_inventoryを利用しているため、最初本番サーバでは動作しない状態だった。
ox_lib,ox_inventory用に書き換えても、アイテムの使用トリガーはQBCoreを利用しないと動かないなどがあり、自身のサーバをある程度本番サーバと同じような環境に作り上げて、検証を実施して、なんとか動作させることができた。

少し宣伝

FiveMの35VILLAGE RPというサーバで遊んでいます!

犯罪の種類が多かったり、白ジョブ、フリージョブもたくさんあるサーバです。
私が作った自作Scriptもいつくか入っているので、ぜひ遊びに来てください!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?