Lua スクリプティングクックブック
Lua API に慣れて、使い方を学ぶのに役立つコードスニペットです。 これらのサンプルをテストするには、バッククォート(``)キーを押してゲーム内Luaコンソールにコードを貼り付けてください。
アイテム
インベントリ内の全ての装備および着用アイテムのリストを取得する
local you = gapi.get_avatar()
local items = you:all_items(false)
for _, item in pairs(items) do
local status = ""
if you:is_wielding(item) then
status = "装備中: "
elseif you:is_wearing(item) then
status = "着用中: "
end
print(status .. item:tname(1, false, 0))
end
出力例
装備中: スマートフォン
着用中: ブラジャー
着用中: パンティー
着用中: ソックス
着用中: ジーンズ
着用中: 長袖シャツ
着用中: スニーカー
着用中: メッセンジャーバッグ
着用中: 腕時計
ポケットナイフ
マッチ本
きれいな水(プラスチック製ボトル)
きれいな水
モンスター
プレイヤーの近くに犬をスポーンする
local avatar = gapi.get_avatar()
local coords = avatar:get_pos_ms()
local dog_mtype = MtypeId.new("mon_dog_bcollie")
local doggy = gapi.place_monster_around(dog_mtype, coords, 5)
if doggy == nil then
gdebug.log_info("犬をスポーンできませんでした :(")
else
gdebug.log_info(string.format("犬を %s にスポーンしました", doggy:get_pos_ms()))
end
戦闘
格闘技が使用された時に詳細情報を表示する
まずは関数を定義します。
on_creature_performed_technique = function(params)
local char = params.char
local technique = params.technique
local target = params.target
local damage_instance = params.damage_instance
local move_cost = params.move_cost
gdebug.log_info(
string.format(
"%s が %s を %s に対して使用しました (DI: %s , MC: %s)",
char:get_name(),
technique.name,
target:get_name(),
damage_instance:total_damage(),
move_cost
)
)
end
その後、フックを関数に一度だけ接続します。
table.insert(game.hooks.on_creature_performed_technique, function(...) return on_creature_performed_technique(...) end)
出力例
Ramiro Waters が Power Hit を zombie に対して使用しました (DI: 27.96 , MC: 58)
アイテムの耐久性
アイテムのダメージをチェックして修正する
local you = gapi.get_avatar()
local wielding = you:all_items(false)[1]
print(wielding:get_damage())
print(wielding:get_damage_level(4))
wielding:mod_damage(2000)
print(wielding:get_damage_level(4))
モンスター
モンスターのインベントリにアイテムを追加する
local target_monster = -- [[ あなたのモンスター参照 ]]
local scraps = gapi.create_item(ItypeId.new("scrap"), 3)
target_monster:as_monster():add_item(scraps)
天気フック
天気の変化に反応する
まず、preload.lua でフックをセットアップします:
local mod = game.mod_runtime[game.current_mod]
table.insert(game.hooks.on_weather_changed, function(...) mod.weather_changed_alert(...) end)
table.insert(game.hooks.on_weather_updated, function(...) mod.weather_report(...) end)
次に、main.lua でハンドラーを定義します:
local mod = game.mod_runtime[game.current_mod]
-- 天気が変わる時に呼び出される(例: 晴れ -> 雨)
mod.weather_changed_alert = function(params)
local msg = string.format(
"天気が %s から %s に変わりました!",
params.old_weather_id,
params.weather_id
)
gdebug.log_info(msg)
end
-- 5分ごとに現在の天気データと共に呼び出される
mod.weather_report = function(params)
local msg = string.format(
"現在の天気: %s, 温度: %.1f°C, 風: %d, 湿度: %d%%",
params.weather_id,
params.temperature,
params.windspeed,
params.humidity
)
gdebug.log_info(msg)
end
遠距離戦闘
発砲と投げたアイテムに反応する
まず、preload.lua でフックをセットアップします:
local mod = game.mod_runtime[game.current_mod]
table.insert(game.hooks.on_shoot, function(...) return mod.on_shoot_fun(...) end)
table.insert(game.hooks.on_throw, function(...) return mod.on_throw_fun(...) end)
次に、main.lua でハンドラーを定義します:
local mod = game.mod_runtime[game.current_mod]
mod.on_shoot_fun = function(params)
---@type Item
local gun = params.gun
---@type Item
local ammo_item = params.ammo
local ammo = ItypeId.NULL_ID()
if not ammo_item then
ammo = gun:ammo_current()
else
ammo = ammo_item:get_type()
end
local shoot_noise = ammo:obj():slot_ammo().loudness
gdebug.log_info(string.format("銃音: %d.", shoot_noise))
end
mod.on_throw_fun = function(params)
---@type Character
local thrower = params.thrower
---@type Item
local thrown = params.item
if thrown:is_gun() then
gdebug.log_info("おい!銃は投げるものではないぞ!")
end
end
オーバーマップクエリ
オーバーマップ上のアイテムを検索して操作する
-- 特定の場所のオーバーマップ上の全てのアイテムを検索
local om_pos = OmPos.new(0, 0, 0)
local items = gapi.overmap_find_items_around(om_pos, 0)
-- マップからアイテムを取得して、マップがアンロードされても Lua に保持
local map_pos = MapPos.new(100, 100, 0)
local item = gapi.get_map():find_item_at(map_pos)
if item then
local detached = gapi.create_detached_item(item)
-- 後で位置に再度アタッチできます
local reattached = gapi.reattach_item(detached, map_pos)
end
-- 同じマップ内でアイテムを移動
local source_pos = MapPos.new(100, 100, 0)
local dest_pos = MapPos.new(110, 110, 0)
gapi.get_map():move_item_at(source_pos, dest_pos)
死亡フック
モンスターの死亡をトラッキング
-- preload.lua 内
local mod = game.mod_runtime[game.current_mod]
table.insert(game.hooks.on_mon_death, function(...) return mod.on_mon_death(...) end)
-- main.lua 内
local mod = game.mod_runtime[game.current_mod]
mod.on_mon_death = function(params)
---@type Creature
local monster = params.creature
---@type Character|nil
local killer = params.killer
local killer_name = killer and killer:get_name() or "不明"
gdebug.log_info(string.format("%s は %s に殺されました", monster:get_name(), killer_name))
end
キャラクターの死亡をトラッキング
-- preload.lua 内
local mod = game.mod_runtime[game.current_mod]
table.insert(game.hooks.on_char_death, function(...) return mod.on_char_death(...) end)
-- main.lua 内
local mod = game.mod_runtime[game.current_mod]
mod.on_char_death = function(params)
---@type Character
local char = params.char
---@type Character|nil
local killer = params.killer
if char == gapi.get_avatar() then
gdebug.log_info("あなたは死にました!")
end
end
キャラクターのコンバットスタッツ
攻撃とスタミナのコストを取得する
local you = gapi.get_avatar()
local items = you:all_items(false)
for _, item in pairs(items) do
print(
item:tname(1, false, 0)
.. " { 攻撃コスト: " .. item:attack_cost()
.. ", スタミナコスト: " .. item:stamina_cost()
.. ", 近接スタミナコスト: " .. you:get_melee_stamina_cost(item)
.. " }"
)
end
-- 特殊能力をチェック
print("Uncanny dodge: " .. (you:uncanny_dodge() and "はい" or "いいえ"))
ダイナミックアイテムアクション
Lua でカスタムアイテム使用関数を作成する
-- tick と can_use 関数でアイテムの使用動作を定義
game.iuse_functions["my_custom_item"] = {
use = function(params)
local user = params.user
local item = params.item
gdebug.log_info("使用中: " .. item:tname(1))
return 0 -- 移動単位での時間コストを返す
end,
can_use = function(params)
local user = params.user
local item = params.item
-- 使用を許可する場合は true、禁止する場合は false を返す
return true
end,
tick = function(params)
local user = params.user
local item = params.item
-- アイテムがアクティブ状態の間、定期的に呼び出される
if item:get_countdown() == 0 then
gdebug.log_info("アイテムのカウントダウンが完了しました!")
end
end
}
-- 周期的なティックをトリガーするためにアイテムにカウントダウンを設定
local item = gapi.create_item(ItypeId.new("some_item"), 1)
item:set_countdown(100) -- 100ターンティック
より多くのコンバットフック
回避、ブロック、および技のイベントに反応する
-- preload.lua 内
local mod = game.mod_runtime[game.current_mod]
table.insert(game.hooks.on_creature_dodged, function(...) return mod.on_creature_dodged(...) end)
table.insert(game.hooks.on_creature_blocked, function(...) return mod.on_creature_blocked(...) end)
table.insert(game.hooks.on_creature_performed_technique, function(...) return mod.on_creature_performed_technique(...) end)
table.insert(game.hooks.on_creature_melee_attacked, function(...) return mod.on_creature_melee_attacked(...) end)
-- main.lua 内
local mod = game.mod_runtime[game.current_mod]
mod.on_creature_dodged = function(params)
---@type Character
local char = params.char
---@type Creature
local source = params.source
local difficulty = params.difficulty
gdebug.log_info(string.format("%s は %s を回避しました (DC: %d)", char:get_name(), source:get_name(), difficulty))
end
mod.on_creature_blocked = function(params)
---@type Character
local char = params.char
---@type Creature
local source = params.source
local bodypart_id = params.bodypart_id
local damage_blocked = params.damage_blocked
gdebug.log_info(string.format(
"%s は %s を %s でブロックしました (ブロック: %.1f ダメージ)",
char:get_name(),
source:get_name(),
bodypart_id,
damage_blocked
))
end
mod.on_creature_melee_attacked = function(params)
---@type Character
local char = params.char
---@type Creature
local target = params.target
if params.success then
gdebug.log_info(string.format("%s は %s にヒットしました", char:get_name(), target:get_name()))
else
gdebug.log_info(string.format("%s は %s をミスしました", char:get_name(), target:get_name()))
end
end
アイテムタイプ情報
ItypeId 経由のアイテムタイププロパティのクエリ
local item_type = ItypeId.new("9mm")
-- アイテムタイプオブジェクト(ItypeRaw)を取得
local itype_raw = item_type:obj()
-- アイテムタイプ固有のデータにアクセス(例: 弾薬)
if itype_raw:slot_ammo() then
local ammo_data = itype_raw:slot_ammo()
print("弾薬ダメージ: " .. ammo_data.damage)
print("弾薬射程: " .. ammo_data.range)
end
-- コンテナの場合
if itype_raw:slot_container() then
local container_data = itype_raw:slot_container()
print("容量: " .. container_data.capacity)
end
-- ツールの場合
if itype_raw:slot_tool() then
local tool_data = itype_raw:slot_tool()
print("ツール品質: " .. tool_data.quality)
end