Skip to content

Add research-info script #1454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gui/spectate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ function Spectate:init()

create_row({t=27}, 'Job', 'J', 'job', colFollow, colHover),
create_row({t=28}, 'Activity', 'A', 'activity', colFollow, colHover),
create_row({t=27}, 'Research', 'R', 'research', colFollow, colHover),
create_row({t=29}, 'Name', 'N', 'name', colFollow, colHover),
create_row({t=30}, 'Stress', 'S', 'stress', colFollow, colHover),
create_stress_list({t=31}, colFollow, colHover),
Expand Down
126 changes: 126 additions & 0 deletions internal/research-info/info.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
-- Main module for research-info
--@ module = true

---@param unit_id df.unit.id
function getHistoricalFigure(unit_id)
for _, historical_figure in ipairs(df.global.world.history.figures) do
if historical_figure.unit_id == unit_id then
return historical_figure
end
end
print("No historical figure found for unit ID: " .. unit_id)
return nil
end

function getKnowledgeGoalCategoryInfo(category_id)
-- alt: df.scholar_knowledgest
local topic_categories = {
[-1] = "None", -- None
[0] = "Philosophy", -- PHILOSOPHY_FLAG
[1] = "Philosophy Adv", -- PHILOSOPHY_FLAG2
[2] = "Mathematics", -- MATHEMATICS_FLAG
[3] = "Mathematics Adv", -- MATHEMATICS_FLAG2
[4] = "History", -- HISTORY_FLAG
[5] = "Astronomy", -- ASTRONOMY_FLAG
[6] = "Naturalist", -- NATURALIST_FLAG
[7] = "Chemistry", -- CHEMISTRY_FLAG
[8] = "Geography", -- GEOGRAPHY_FLAG
[9] = "Medicine 1", -- MEDICINE_FLAG
[10] = "Medicine 2", -- MEDICINE_FLAG2
[11] = "Medicine 3", -- MEDICINE_FLAG3
[12] = "Engineering", -- ENGINEERING_FLAG
[13] = "Engineering Adv" -- ENGINEERING_FLAG2
}
return topic_categories[category_id] or string.format("Unknown Category: %s", category_id)
end

function getGoalInfo(goal, category)
local goal_info = ''
if not goal then
return goal_info
end

local goal_info = ""
for i = 0, 31 do
if goal[i] then
local global_flag_index = category * 32 + i -- wizards move
goal_info = string.format("%s", df.dfhack_knowledge_scholar_flag[global_flag_index]) or string.format("Unknown Flag: %s", i)
end
end
return goal_info
end

local function getTopicInfo(topic)
if not topic then
return "No topic information available."
end

local topic_info = ""

for key, value in pairs(topic) do
if type(value) == "boolean" and value then
-- Если значение булевое и равно true, выводим тему как изученную
topic_info = topic_info .. string.format("\n\t\t%s", key)
end
end

if topic_info == "" then
return "No learned topics."
end

return topic_info
end

---@param historical_figure df.historical_figure
function getHistoricKnowledge(historical_figure)
if not historical_figure then
print("Historical figure not found.")
return nil, "Historical figure not found."
end

local known_info = historical_figure.info.known_info

if not known_info then
return nil, "No known_info found."
end

local knowledge = known_info.knowledge

if not knowledge then
return nil, "No knowledge found."
end

return knowledge
end

---@param unit_id df.unit.id
function getUnitKnowledge(unit_id)
return getHistoricKnowledge(getHistoricalFigure(unit_id))
end

---@param historical_figure df.historical_figure
function getResearchData(historical_figure)
local knowledge = getHistoricKnowledge(historical_figure)
local data = {

name = dfhack.translation.translateName(historical_figure.name), --dfhack.translation.TranslateName(historical_figure.name),
knowledge_goal_category = getKnowledgeGoalCategoryInfo(knowledge.knowledge_goal_category),
--knowledge_goal = getGoalInfo(knowledge.knowledge_goal),
knowledge_goal = getGoalInfo(knowledge.knowledge_goal, knowledge.knowledge_goal_category),
research_points = knowledge.research_points,
research_percentage = string.format("%.2f", (knowledge.research_points / 100000) * 100),
times_pondered = knowledge.times_pondered,
research_topics = {}
}

for i, topic in pairs(knowledge) do
if type(topic) == "userdata" and i ~= "knowledge_goal" then
local topic_info = getTopicInfo(topic)
if topic_info ~= "\tNo topic information available." and topic_info ~= "No learned topics." then
table.insert(data.research_topics, {name = i, info = topic_info})
end
end
end

return {data}
end
43 changes: 43 additions & 0 deletions internal/research-info/overlay.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-- Spectate-Overlay module for research-info
--@ module = true

local researchInfo = reqscript("internal/research-info/info")

local function formatKnowledgeString(str)
if not str or type(str) ~= "string" or str == "" then
return str or ""
end

local parts = {}
for part in str:gmatch("[^_]+") do
-- Первую букву делаем заглавной, остальные - строчными
local formatted = part:sub(1,1):upper() .. part:sub(2):lower()
table.insert(parts, formatted)
end

return table.concat(parts, " ")
end

function GetUnitResearchInfo(unit_id)
local info = ''

historical_figure = researchInfo.getHistoricalFigure(unit_id)
local knowledge = researchInfo.getHistoricKnowledge(historical_figure)
local data = {
knowledge_goal_category = researchInfo.getKnowledgeGoalCategoryInfo(knowledge.knowledge_goal_category),
knowledge_goal = formatKnowledgeString(researchInfo.getGoalInfo(knowledge.knowledge_goal, knowledge.knowledge_goal_category)),
research_points = knowledge.research_points, --TOTAL: 100'000
research_percentage = string.format("%.2f", (knowledge.research_points / 100000) * 100),
times_pondered = knowledge.times_pondered
}

if((data.knowledge_goal ~= 'nil') and ((data.times_pondered > 0) or (knowledge.research_points > 0))) then
info = data.knowledge_goal..string.format(' %s%%', data.research_percentage)..string.format(' [%d] ', data.times_pondered)
end

return info
end

function GetUnitKnowledge(unit_id)
return researchInfo.getUnitKnowledge(unit_id)
end
69 changes: 69 additions & 0 deletions research-info.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
local researchInfo = reqscript("internal/research-info/info")

local function sortResearchDataByPercAndPondered(data_list)
table.sort(data_list, function(a, b)
if tonumber(a.research_percentage) == tonumber(b.research_percentage) then
return a.times_pondered > b.times_pondered
end
return tonumber(a.research_percentage) > tonumber(b.research_percentage)
end)

return data_list
end

local function printResearchData(data)
if not data then
print("No data to display.")
return
end

if data.research_points == 0 and data.knowledge_goal == "" and data.times_pondered == 0 then
return
end

print("==================")
print("Dwarf: " .. data.name)
print("\tKnowledge Goal Category: " .. data.knowledge_goal_category)
print("\tKnowledge Goal: " .. data.knowledge_goal)
print("\tResearch Points: " .. data.research_points .. "/100000")
print("\tResearch Percentage: " .. data.research_percentage .. "%")
print("\tTimes Pondered: " .. data.times_pondered)

if #data.research_topics > 0 then
print("Knowledge:")
for _, topic in ipairs(data.research_topics) do
print("\t" .. topic.name .. ": " .. topic.info)
end
end
end

--
local unit = dfhack.units.getCitizens()
local selected_unit = dfhack.gui.getSelectedUnit()

if unit then
local research_data_list = {}
for i, unit in pairs(dfhack.units.getCitizens()) do

if selected_unit and selected_unit.id ~= unit.id then
goto continue
end

local historical_figure = researchInfo.getHistoricalFigure(unit.id)
if historical_figure then
local research_data, error_msg = researchInfo.getResearchData(historical_figure)
if research_data then
for _, data in ipairs(research_data) do
table.insert(research_data_list, data)
end
end
end
::continue::
end

research_data_list = sortResearchDataByPercAndPondered(research_data_list)

for _, data in ipairs(research_data_list) do
printResearchData(data)
end
end