LLocalIdentity 0.4.0b Export
93c07211创建于 2025年12月17日历史提交
--
-- Export all spectre monsters from game data
--
local out = io.open("../Export/Minions/SpectreList.txt", "w")
out:write('-- This file is automatically generated, do not edit!\n')
out:write('-- Gem data (c) Grinding Gear Games\n\n')

out:write('-- Some monsters have not been imported into PoB, as they have Spectre flag but they are not actually spectres in game for some reason.\n')
out:write('-- Eg. Delirium monsters like Rage/Malice/Disgust. Either we are missing a flag, or its done on their side somewhere.\n\n')

local export = false
local spectreList = {}
local notImported = {}
local duplicateName = {}
local uniqueName = {}

local importedSpectres = {}
local file = io.open("../Data/Spectres.lua", "r")

if file then
	for line in file:lines() do
		local id = line:match('minions%[%"(.-)%"%]')
		if id then
			importedSpectres[id] = true
		end
	end
	file:close()
end

for monster in dat("MonsterVarieties"):Rows() do
	if monster.NotSpectre == false
		and monster.BossHealthBar == false
		and not monster.Type.IsPlayerMinion == true
		and not monster.Id:match("NPC")
		and not monster.Name:match("DNT")
		and not monster.AIScript:match("NoAI")
		and #monster.GrantedEffects ~= 0 then
		for _, name in ipairs(uniqueName) do
			if name == monster.Name then
				table.insert(duplicateName, { id = monster.Id, name = monster.Name })
				goto continue
			end
		end
		for _, mod in ipairs(monster.Mods) do
			if mod.Id == "CannotBeUsedAsMinion" then
				goto continue
			end
		end
		for _, mod in ipairs(monster.ModsKeys2) do
			if mod.Id == "CannotBeUsedAsMinion" then
				goto continue
			end
		end
		for _, tag in ipairs(monster.Tags) do
			if tag.Id == "unusable_corpse" then
				goto continue
			end
		end
		-- Loop SpectreOverrides for matching monster.Id
		local outputId = monster.Id  -- default to monster.Id
		for override in dat("SpectreOverrides"):Rows() do
			if override.Monster.Id == monster.Id and override.Spectre then
				outputId = override.Spectre.Id
				break
			end
		end
		if not importedSpectres[outputId] then
			table.insert(notImported, { id = outputId, name = monster.Name })
		end
		table.insert(spectreList, { id = outputId, name = monster.Name })
		table.insert(uniqueName, monster.Name)
	end
	::continue::
end

-- Check imported spectres that fail the checks. Did this wrong I think, but keeping for now as it did catch the spectres that were removed.
local importedButFailChecks = {}
for id in pairsSortByKey(importedSpectres) do
	local found = false
	for monster in dat("MonsterVarieties"):Rows() do
		local outputId = monster.Id
		for override in dat("SpectreOverrides"):Rows() do
			if override.Monster.Id == monster.Id and override.Spectre then
				outputId = override.Spectre.Id
				break
			end
		end
		if outputId == id then
			found = true
			-- Repeat the checks
			if not (
				monster.NotSpectre == false
				and monster.BossHealthBar == false
				and not monster.Type.IsPlayerMinion == true
				and not monster.Id:match("NPC")
				and not monster.Name:match("DNT")
				and not monster.AIScript:match("NoAI")
				and #monster.GrantedEffects ~= 0
			) then
				table.insert(importedButFailChecks, { id = outputId, name = monster.Name })
			else
				local skip = false
				for _, mod in ipairs(monster.Mods) do
					if mod.Id == "CannotBeUsedAsMinion" then
						skip = true
						break
					end
				end
				for _, mod in ipairs(monster.ModsKeys2) do
					if mod.Id == "CannotBeUsedAsMinion" then
						skip = true
						break
					end
				end
				for _, tag in ipairs(monster.Tags) do
					if tag.Id == "unusable_corpse" then
						skip = true
						break
					end
				end
				if skip then
					table.insert(importedButFailChecks, { id = outputId, name = monster.Name })
				end
			end
			break
		end
	end
	if not found then
		table.insert(importedButFailChecks, { id = id, name = "(not found in MonsterVarieties)" })
	end
end

out:write("-- All Spectre Names --\n")
out:write("-- This is a full list of all Spectres with basic filtering.--\n\n")
for _, monster in ipairs(spectreList) do
	out:write(monster.id .. string.rep(" ", 90 - string.len(monster.id)) .. "\t\t----\t\t" .. monster.name, "\n")
end

out:write("\n-- Spectres Not Yet Imported --\n")
out:write("-- These are either false spectres, or are disabled in game currently. This is not including duplicate names, just singular copy of a Spectre name.--\n\n")
for _, monster in ipairs(notImported) do
	out:write(monster.id .. string.rep(" ", 90 - string.len(monster.id)) .. "\t\t----\t\t" .. monster.name, "\n")
end

out:write("\n-- Imported Spectres That Fail Checks --\n")
out:write("-- These spectres are currently imported, but fail the checks. New updates sometimes remove spectres.--\n")
out:write("-- Don't fully trust this, coded wrong. But it did catch some that were removed. --\n\n")
for _, monster in ipairs(importedButFailChecks) do
	out:write(monster.id .. string.rep(" ", 90 - string.len(monster.id)) .. "\t\t----\t\t" .. monster.name, "\n")
end

out:write("\n-- Duplicate Spectre Names --\n")
out:write("-- Some duplicate Spectres have been imported, like Terracotta Soldier, as there is a 10 spirit and 60 spirit version.--\n")
out:write("-- There are some spectres with the same name and reservation, but different skills. We should probably import them too.--\n\n")
for _, monster in ipairs(duplicateName) do
	out:write(monster.id .. string.rep(" ", 90 - string.len(monster.id)) .. "\t\t----\t\t" .. monster.name, "\n")
end

out:close()

print("Spectre List exported.")