７. 撲殺バットMODの作成（独自ギミック追加２）

# 概要
前回、Lua実装で独自ギミックを追加しました。
実はもう１つだけ未実装の機能があるので、Luaでの実装を続けます。
ただし、今回はソース紹介とポイントのみの解説となります。[^1]

※ 今回もLuaによる実装の解説になりますので、読み飛ばして頂いても構いません。
　 LuaによるMOD開発を進めたい方は、参考までにご参照ください。

# １. 独自ギミックについて
撲殺バットは全部で３グレードあり、ティア１とティア２はレシピによるアップグレードで取得可能な仕様を実装しました。ただ、ティア３についてはレシピでの入手も無く、またレシピ本の時のような湧き設定もしていません。そこで、ティア３は「とある場所に固定で１つだけ湧く」といったギミックを実装したいと思います。

:::note info
今回の湧きギミックは私が個人的に開発したものです。
これ以外の方法もあると思いますので、参考程度としてください。
:::

# ２. アイテム固定湧きの実装
今回の独自ギミックは、前回のLuaファイルとは別のファイルに実装しました。

```\media\lua\client\P4BokusatsuBatSpwan.lua
local P4BokusatsuBatSpawn = {}

P4BokusatsuBatSpawn.isEventAdded = false

P4BokusatsuBatSpawn.spawnList = {
	-- [Bokusatsu Bat] Art Gallery of Louisville
	{ id="bbt3", item="P4BokusatsuBat.P4BokusatsuBatT3", locx=12522, locy=1417, locz=2, x=1.0, y=1.0, z=0.85, r=0.0 },
}

-- *****************************************************************************
-- * ModData functions
-- *****************************************************************************

P4BokusatsuBatSpawn.getSpawnReserves = function()
	local modData = ModData.getOrCreate("P4BokusatsuBatSpawn")
	if not modData.spawnReserves then
		modData.spawnReserves = {}
	end
	return modData.spawnReserves
end

P4BokusatsuBatSpawn.getReserveResults = function()
	local modData = ModData.getOrCreate("P4BokusatsuBatSpawn")
	if not modData.reserveResults then
		modData.reserveResults = {}
	end
	return modData.reserveResults
end

P4BokusatsuBatSpawn.reserveSpawn = function()
	local spawnReserves = P4BokusatsuBatSpawn.getSpawnReserves()
	local reserveResults = P4BokusatsuBatSpawn.getReserveResults()
	for _,spawnData in ipairs(P4BokusatsuBatSpawn.spawnList) do
		local needsReserve = true
		for _,reservedId in ipairs(reserveResults) do
			if reservedId == spawnData.id then
				needsReserve = false
				break
			end
		end
		if needsReserve then
			table.insert(spawnReserves, spawnData)
			table.insert(reserveResults, spawnData.id)
		end
	end

	local needsEventAdd = false
	for k,v in pairs(spawnReserves) do
		if v then
			needsEventAdd = true
			break
		end
	end
	if needsEventAdd and not P4BokusatsuBatSpawn.isEventAdded then
		Events.EveryTenMinutes.Add(P4BokusatsuBatSpawn.CheckSpawn)
		P4BokusatsuBatSpawn.isEventAdded = true
	end
end

-- *****************************************************************************
-- * Event trigger functions
-- *****************************************************************************

P4BokusatsuBatSpawn.OnGameStart = function()
	P4BokusatsuBatSpawn.reserveSpawn()
end
Events.OnGameStart.Add(P4BokusatsuBatSpawn.OnGameStart)

P4BokusatsuBatSpawn.CheckSpawn = function()
	local spawnReserves = P4BokusatsuBatSpawn.getSpawnReserves()
	for k,v in pairs(spawnReserves) do
		local square = getSquare(v.locx, v.locy, v.locz)
		if square then
			local spawnItem = square:AddWorldInventoryItem(v.item, v.x, v.y, v.z)
			spawnItem:setWorldZRotation(v.r)
			spawnItem:getWorldItem():setIgnoreRemoveSandbox(true)
			spawnItem:getWorldItem():transmitCompleteItemToServer()
			spawnReserves[k] = nil
		end
	end
end
```
前回解説した技術と同じものしか使っていませんので、宜しければソースを追って内容を理解してみてください。なお、実装時のポイントは下記になります。

## グローバルMODデータの利用
湧き設定や湧き状態はMODデータで保持していますが、「セーブデータで１回だけ湧かせる」ために、グローバルMODデータを利用しています。こうすることで、同じセーブデータで別キャラを作成した場合も、撲殺バット（ティア３）が湧くのは最初の１回だけとなり、世界に１つだけの武器となります。

## 湧き処理の性能対策
実際の湧き処理は「CheckSpawn」関数で実施しており、「EveryTenMinutes」イベントで定期的に呼び出しています。アイテムを湧かすためには、ゲーム内でそのスクエア（＝タイル）が読み込まれている必要があります。「LoadGridsquare」イベントを使えば、マップのスクエアが読み込まれた際に処理ができ、読み込まれたスクエアが対象かどうか判定することができます。ただし、このスクエアの読込はかなりの頻度で発生するため、マップロードの度にラグが生じやすくなります。

そこで、リアルタイム性は犠牲になりますが、湧き処理はゲーム内時間で10分に一回とし、また湧き対象のグリッドが存在しているか（＝読み込まれているか）どうかを、湧き予定タイルごとに調べる方式にしています。

また、既に湧き予定の全てのアイテムが湧いた場合は、10分に一回の湧きチェックも不要となりますので、「Events.EveryTenMinutes」に登録しないようにフラグ制御をしています。

# ３. 独自ギミックの確認
今回追加したアイテム固定湧きの確認をします。指定した湧き場所に行ってみると、ティア３の撲殺バットが湧いていることが確認できます。
![07-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2481343/e44cbd53-7e54-d43b-e677-7ee668ce3077.png)

# あとがき
これで全ての機能の実装が完了し、MOD公開できる状態になりました。
次回はWorkshopへのMOD公開について解説します。

---
索引：[Project ZomboidのMODを開発する](https://qiita.com/PePePePePeil/items/5db632d902eb91847541)
前：[６. 撲殺バットMODの作成（独自ギミック追加１）](https://qiita.com/PePePePePeil/items/4365bbd374eaf334d416) 
次：[８. 撲殺バットMODの作成（MOD公開）](https://qiita.com/PePePePePeil/items/eaf56f74f90f640bdbe6) 

[^1]: 今回の内容を反映したMODファイルは下記。
💾 [P4BokusatsuBat_07.zip](https://www.pepepepe.com/zomboid/Qiita/P4BokusatsuBat_07.zip)（MD5チェックサム：BF617DB120134C3C416B531E18579AB6）