Skip to content

Commit

Permalink
list-agreements overhaul (#393)
Browse files Browse the repository at this point in the history
* list-agreements overhaul

+ handling of Deity names (as mentioned in #390)

+ age of petitions

+ added status 'expired' for outstanding petitions more than 1 year old

+ race specific guild professions

+ formatting characters to reduce mid-wo
rd wrapping

- consolidated functions for output and name lookup

- minimised repeated work within if...elseif... blocks

* #393 review1 changes

+run arguments handler for `all` and `help`
+localised variables
+culling resolved agreements by default
+general good practices implemented

* Update changelog.txt

Co-authored-by: Myk <[email protected]>

* further review changes (#393)

* standardise default fn return (#393)

* Update list-agreements.lua

* fix syntax in help text

Co-authored-by: Myk <[email protected]>
  • Loading branch information
Hevlikn and myk002 authored Jun 3, 2022
1 parent b70dec0 commit 3a59e56
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 57 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ that repo.

## Misc Improvements
- `deteriorate`: new ``now`` command immediately deteriorates all items of the specified types.
- `list-agreements`: now displays translated Guild Names, worshiped Deity, age of petition, and "man" to race-specific professions (e.g. "Craftsman" -> "Craftsdwarf")

## Removed
- `devel/unforbidall`: please use `unforbid` instead. You can silence the output with ``unforbid all --quiet``
Expand Down
216 changes: 159 additions & 57 deletions list-agreements.lua
Original file line number Diff line number Diff line change
@@ -1,120 +1,222 @@
-- Lists all guildhall and temple agreements
-- list location agreements with guilds or religions

--[====[
list-agreements
===============
Lists all guildhall and temple agreements in fortress mode.
Lists Guildhall and Temple agreements in fortress mode.
In addition:
]====]
* Translates names of the associated Guilds and Orders respectively
* Displays worshiped Professions and Deities respectively
* Petition age and status satisfied, denied or expired, or blank for outstanding
Usage::
list-agreements [options]
Examples:
``list-agreements``
List outstanding, unfullfilled location agreements.
``list-agreements all``
Lists all location agreements, whether satisfied, denied, or expired.
Options:
:all: list all agreements; past and present
:help: shows this help screen
]====]
local playerfortid = df.global.ui.site_id -- Player fortress id
local templeagreements = {} -- Table of agreements for temples in player fort
local guildhallagreements = {} -- Table of agreements for guildhalls in player fort

function get_location_tier(agr)
loctier = agr.details[0].data.Location.tier
return loctier
function get_location_name(loctier,loctype)
local locstr = "Unknown Location"
if loctype == df.abstract_building_type.TEMPLE and loctier == 1 then
locstr = "Temple"
elseif loctype == df.abstract_building_type.TEMPLE and loctier == 2 then
locstr = "Temple Complex"
elseif loctype == df.abstract_building_type.GUILDHALL and loctier == 1 then
locstr = "Guildhall"
elseif loctype == df.abstract_building_type.GUILDHALL and loctier == 2 then
locstr = "Grand Guildhall"
end
return locstr
end

function get_location_type(agr)
loctype = agr.details[0].data.Location.type
return loctype
end

function get_location_name(agr)
if get_location_type(agr) == df.abstract_building_type.TEMPLE and get_location_tier(agr) == 1 then
return "temple"
elseif get_location_type(agr) == df.abstract_building_type.TEMPLE and get_location_tier(agr) == 2 then
return "temple complex"
elseif get_location_type(agr) == df.abstract_building_type.GUILDHALL and get_location_tier(agr) == 1 then
return "guildhall"
elseif get_location_type(agr) == df.abstract_building_type.GUILDHALL and get_location_tier(agr) == 2 then
return "grand guildhall"
end
function get_petition_date(agr)
local agr_year = agr.details[0].year
local agr_year_tick = agr.details[0].year_tick
local julian_day = math.floor(agr_year_tick / 1200) + 1
local agr_month = math.floor(julian_day / 28) + 1
local agr_day = julian_day % 28
return string.format("%03d-%02d-%02d",agr_year, agr_month, agr_day)
end

function get_petition_date(agr)
agr_year = agr.details[0].year
agr_year_tick = agr.details[0].year_tick
julian_day = math.floor(agr_year_tick / 1200) + 1
agr_month = math.floor(julian_day / 28) + 1
agr_day = julian_day % 28
return agr_year.."-"..agr_month.."-"..agr_day
function get_petition_age(agr)
local agr_year_tick = agr.details[0].year_tick
local agr_year = agr.details[0].year
local cur_year_tick = df.global.cur_year_tick
local cur_year = df.global.cur_year
local del_year, del_year_tick
--delta, check to prevent off by 1 error, not validated
if cur_year_tick > agr_year_tick then
del_year = cur_year - agr_year
del_year_tick = cur_year_tick - agr_year_tick
else
del_year = cur_year - agr_year - 1
del_year_tick = agr_year_tick - cur_year_tick
end
local julian_day = math.floor(del_year_tick / 1200) + 1
local del_month = math.floor(julian_day / 28)
local del_day = julian_day % 28
return {del_year,del_month,del_day}
end

function get_guildhall_profession(agr)
prof = agr.details[0].data.Location.profession
profname = string.lower(df.profession[prof])
local prof = agr.details[0].data.Location.profession
local profname = string.lower(df.profession[prof])
-- *VERY* important code follows
if string.find(profname, "man") then
profname = string.gsub(profname,"man",string.lower(dfhack.units.getRaceNameById(df.global.ui.race_id)))
end
if not profname then
profname = 'profession-less'
end
return profname:gsub("_", " ")
end

function get_religion_name(agr)
religion_id = agr.details[0].data.Location.deity_data.Religion
religion_name = dfhack.TranslateName(df.global.world.entities.all[religion_id].name, true)
return religion_name
function get_agr_party_name(agr)
--assume party 0 is guild/order, 1 is local government as siteid = playerfortid
local party_id = agr.parties[0].entity_ids[0]
local party_name = dfhack.TranslateName(df.global.world.entities.all[party_id].name, true)
if not party_name then
party_name = 'An Unknown Entity or Group'
end
return party_name
end

function is_satisfied(agr)
satisfied = agr.flags.convicted_accepted
return satisfied
function get_deity_name(agr)
local religion_id = agr.details[0].data.Location.deity_data.Religion
local deities = df.global.world.entities.all[religion_id].relations.deities
if #deities == 0 then return 'An Unknown Deity' end
return dfhack.TranslateName(df.global.world.history.figures[deities[0]].name,true)
end

function is_denied(agr)
denied = agr.flags.petition_not_accepted
return denied
--get resolution status, and string
function is_resolved(agr)
local res = false
local res_str = 'outstanding'

if agr.flags.convicted_accepted then
res = true
res_str = 'satisfied'
elseif agr.flags.petition_not_accepted then
res = true
res_str = 'denied'
elseif get_petition_age(agr)[1] ~= 0 then
res = true
res_str = 'expired'
end
return res,res_str
end

function generate_output_guild(agr)
if is_satisfied(agr) == true then
print("Establish a "..get_location_name(agr).." for the "..get_guildhall_profession(agr).." guild, as agreed on "..get_petition_date(agr).." (satisfied)")
elseif is_denied(agr) == true then
print("Establish a "..get_location_name(agr).." for the "..get_guildhall_profession(agr).." guild, as agreed on "..get_petition_date(agr).." (denied)")
--universal handler
function generate_output(agr,loctype)
local loc_name = get_location_name(agr.details[0].data.Location.tier,loctype)
local agr_age = get_petition_age(agr)
local output_str = 'Establish a '.. loc_name..' for "'..get_agr_party_name(agr)
local resolved, resolution_string = is_resolved(agr)

if loctype == df.abstract_building_type.TEMPLE then
output_str = output_str..'" worshiping "'..get_deity_name(agr)..',"'
elseif loctype == df.abstract_building_type.GUILDHALL then
output_str = output_str..'", a '..get_guildhall_profession(agr)..' guild,'
else
print("Establish a "..get_location_name(agr).." for the "..get_guildhall_profession(agr).." guild, as agreed on "..get_petition_date(agr))
print("Agreement with unknown org")
return
end

output_str = output_str..'\n\tas agreed on '..get_petition_date(agr)..'. \t'..agr_age[1]..'y, '..agr_age[2]..'m, '..agr_age[3]..'d ago'

-- can print '(outstanding)' status here, but imho none is cleaner
if not resolved then
print(output_str)
else
print(output_str..' ('..resolution_string..')')
end
end

function generate_output_temple(agr)
if is_satisfied(agr) == true then
print("Establish a "..get_location_name(agr).." for "..get_religion_name(agr)..", as agreed on "..get_petition_date(agr).." (satisfied)")
elseif is_denied(agr) == true then
print("Establish a "..get_location_name(agr).." for "..get_religion_name(agr)..", as agreed on "..get_petition_date(agr).." (denied)")
---------------------------------------------------------------------------
-- Main Script operation
---------------------------------------------------------------------------

local args = {...}
local cmd = args[1]
local cull_resolved = true

-- args handler
if cmd then
if cmd == "all" then
cull_resolved = false
elseif cmd == "help" then
print(dfhack.script_help())
return
else
print("Establish a "..get_location_name(agr).." for "..get_religion_name(agr)..", as agreed on "..get_petition_date(agr))
print('argument ``'..cmd..'`` not supported')
print(dfhack.script_help())
return
end
end

for _, agr in pairs(df.agreement.get_vector()) do
if agr.details[0].data.Location.site == playerfortid then
if get_location_type(agr) == df.abstract_building_type.TEMPLE then
table.insert(templeagreements, agr)
elseif get_location_type(agr) == df.abstract_building_type.GUILDHALL then
table.insert(guildhallagreements, agr)
if not is_resolved(agr) or not cull_resolved then
if get_location_type(agr) == df.abstract_building_type.TEMPLE then
table.insert(templeagreements, agr)
elseif get_location_type(agr) == df.abstract_building_type.GUILDHALL then
table.insert(guildhallagreements, agr)
end
end
end
end

print "-----------------------"
print "Agreements for temples:"
print "Agreements for Temples:"
print "-----------------------"
if next(templeagreements) == nil then
print "No agreements"
if cull_resolved then
print "No outstanding agreements"
else
print "No agreements"
end
else
for _, agr in pairs(templeagreements) do
generate_output_temple(agr)
generate_output(agr,df.abstract_building_type.TEMPLE)
end
end

print ""
print "--------------------------"
print "Agreements for guildhalls:"
print "Agreements for Guildhalls:"
print "--------------------------"
if next(guildhallagreements) == nil then
print "No agreements"
if cull_resolved then
print "No outstanding agreements"
else
print "No agreements"
end
else
for _, agr in pairs(guildhallagreements) do
generate_output_guild(agr)
generate_output(agr,df.abstract_building_type.GUILDHALL)
end
end

0 comments on commit 3a59e56

Please sign in to comment.