Skip to content

Commit

Permalink
Merge pull request #1182 from Crystalwarrior/adv-rumors-plus
Browse files Browse the repository at this point in the history
Adv-Rumors additional conversation options
  • Loading branch information
myk002 authored Jul 2, 2024
2 parents 3613d69 + 052c38b commit 7301bdf
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Template for new versions:
- `gui/notify`: new notification type: injured citizens; click to zoom to injured units; also displays a warning if your hospital is not functional (or if you have no hospital)
- `prioritize`: new info panel on under-construction buildings showing if the construction job has been taken and by whom. click to zoom to builder; toggle high priority status for job if it's not yet taken and you need it to be built ASAP
- `gui/pathable`: new "Depot" mode that shows whether wagons can path to your trade depot
- `advtools`: automatically add a conversation option to "ask whereabouts of" for all your relationships (before, you could only ask whereabouts of people involved in rumors)
- `gui/design`: all-new visually-driven UI for much improved usability

## Fixes
Expand Down
5 changes: 4 additions & 1 deletion docs/advtools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ framework. They can be repositioned via `gui/overlay` or toggled via

When enabled, this overlay will automatically add additional searchable
keywords to conversation topics. In particular, topics that relate to slain
enemies will gain the ``slay`` and ``kill`` keywords.
enemies will gain the ``slay`` and ``kill`` keywords. It will also add additional
conversation options for asking whereabouts of your relationships - in vanilla,
you can only ask whereabouts of historical figures involved in rumors you personally
witnessed or heard about.
100 changes: 96 additions & 4 deletions internal/advtools/convo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ local adventure = df.global.game.main_interface.adventure
-- Gets the keywords already present on the dialog choice
local function getKeywords(choice)
local keywords = {}
for _, keyword in ipairs(choice.key_word) do
for _, keyword in ipairs(choice.keywords) do
table.insert(keywords, keyword.value:lower())
end
return keywords
Expand All @@ -22,8 +22,8 @@ end
-- Adds a keyword to the dialog choice
local function addKeyword(choice, keyword)
local keyword_ptr = df.new('string')
keyword_ptr.value = keyword
choice.key_word:insert('#', keyword_ptr)
keyword_ptr.value = dfhack.toSearchNormalized(keyword)
choice.keywords:insert('#', keyword_ptr)
end

-- Adds multiple keywords to the dialog choice
Expand All @@ -45,7 +45,7 @@ local function generateKeywordsForChoice(choice)
end

-- generate keywords from useful words in the text
for _, data in ipairs(choice.print_string.text) do
for _, data in ipairs(choice.title.text) do
for word in dfhack.toSearchNormalized(data.value):gmatch('%w+') do
-- collect additional keywords based on the special words
if word == 'slew' or word == 'slain' then
Expand All @@ -61,8 +61,95 @@ local function generateKeywordsForChoice(choice)
addKeywords(choice, new_keywords)
end

-- Helper function to create new dialog choices, returns the created choice
local function new_choice(choice_type, title, keywords)
local choice = df.adventure_conversation_choice_infost:new()
choice.cc = df.talk_choice:new()
choice.cc.type = choice_type
local text = df.new("string")
text.value = title
choice.title.text:insert("#", text)

if keywords ~= nil then
addKeywords(choice, keywords)
end
return choice
end

local function addWhereaboutsChoice(race, name, target_id, heard_of)
local title = "Ask for the whereabouts of the " .. race .. " " .. dfhack.TranslateName(name, true)
if heard_of then
title = title .. " (Heard of)"
end
local choice = new_choice(df.talk_choice_type.AskWhereabouts, title, dfhack.TranslateName(name):split())
-- insert before the last choice, which is usually "back"
adventure.conversation.conv_choice_info:insert(#adventure.conversation.conv_choice_info-1, choice)
choice.cc.invocation_target_hfid = target_id
end

local function addHistFigWhereaboutsChoice(profile)
local histfig = df.historical_figure.find(profile.histfig_id)
local race = ""
local creature = df.creature_raw.find(histfig.race)
if creature then
local caste = creature.caste[histfig.caste]
race = caste.caste_name[0]
end

addWhereaboutsChoice(race, histfig.name, histfig.id, profile._type == df.relationship_profile_hf_historicalst)
end

local function addIdentityWhereaboutsChoice(identity)
local identity_name = identity.name
local race = ""
local creature = df.creature_raw.find(identity.race)
if creature then
local caste = creature.caste[identity.caste]
race = caste.caste_name[0]
else
-- no race given for the identity, assume it's the histfig
local histfig = df.historical_figure.find(identity.histfig_id)
creature = df.creature_raw.find(histfig.race)
if creature then
local caste = creature.caste[histfig.caste]
race = caste.caste_name[0]
end
end
addWhereaboutsChoice(race, identity_name, identity.impersonated_hf)
end

-- Condense the rumor system choices
local function rumorUpdate()
local conversation_state = adventure.conversation.conv_act.events[0].menu
-- add new conversation options depending on state

-- If we're asking about directions, add ability to ask about all our relationships - visual, historical and identities.
-- In vanilla, we're only allowed to ask for directions to people we learned in anything that's added to df.global.adventure.rumor
if conversation_state == df.conversation_state_type.AskDirections then
local adventurer_figure = df.historical_figure.find(dfhack.world.getAdventurer().hist_figure_id)
local relationships = adventurer_figure.info.relationships

local visual = relationships.hf_visual
local historical = relationships.hf_historical
local identity = relationships.hf_identity

for _, profile in ipairs(visual) do
addHistFigWhereaboutsChoice(profile)
end

-- This option will likely always fail unless the false identity is impersonating someone
-- but giving away the false identity's true historical figure feels cheap.
for _, profile in ipairs(identity) do
addIdentityWhereaboutsChoice(df.identity.find(profile.identity_id))
end

-- Historical entities go last so as to not give away fake identities
for _, profile in ipairs(historical) do
addHistFigWhereaboutsChoice(profile)
end
end

-- generate extra keywords for all options
for i, choice in ipairs(adventure.conversation.conv_choice_info) do
generateKeywordsForChoice(choice)
end
Expand All @@ -78,6 +165,11 @@ AdvRumorsOverlay.ATTRS{
frame={w=0, h=0},
}

local last_first_entry = nil
function AdvRumorsOverlay:render()
-- Only update if the first entry pointer changed, this reliably indicates the list changed
if #adventure.conversation.conv_choice_info <= 0 or last_first_entry == adventure.conversation.conv_choice_info[0] then return end
-- Remember the last first entry. This entry changes even if we quit out and return on the same menu!
last_first_entry = adventure.conversation.conv_choice_info[0]
rumorUpdate()
end

0 comments on commit 7301bdf

Please sign in to comment.