Skip to content
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

WIP New lua script: a gui pregnancy tool #873

Merged
merged 7 commits into from
Aug 13, 2024
Merged
Changes from 5 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
125 changes: 88 additions & 37 deletions gui/pregnancy.lua
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs for this script would go in docs/gui/pregnancy.rst -- see other files in that directory and copy the format.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs are still required

Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,32 @@ local widgets = require('gui.widgets')

PregnancyGui = defclass(PregnancyGui, widgets.Window)
PregnancyGui.ATTRS {
frame_title='My Window',
frame={w=50, h=45},
frame_title='Pregnancy manager',
frame={w=64, h=35},
resizable=true, -- if resizing makes sense for your dialog
resize_min={w=50, h=20}, -- try to allow users to shrink your windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these numbers still appropriate?

}

function PregnancyGui:init()
self.mother = false
if dfhack.gui.getSelectedUnit(true).sex == df.pronoun_type.she then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will throw if there is no unit selected when the UI is opened. You should check for a nil return value from getSelectedUnit() before using it

self.mother = dfhack.gui.getSelectedUnit(true)
else self.mother = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless a field is always intended to be a boolean, it's better to leave unset values unset so they are nil instead of false.

end
self.father = false
self.father_historical = false
self.msg = {}
-- self.success = false

local term_options = {}
local term_index = {}
local months
for months=0,10 do
-- table.insert(term_options,{label=('%s months'):format(months),value=months}) --I tried this to add labels, probably doing something wrong, it broke the range widget
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice below you were getting the label to index an array. this should work fine if you get the option value instead

table.insert(term_options,months) --this works though
end
for k,v in ipairs(term_options) do
term_index[v] = k
end

self:addviews{
widgets.ResizingPanel{
frame={t=0},
Expand All @@ -26,14 +40,14 @@ function PregnancyGui:init()
},
widgets.HotkeyLabel{
frame={l=0},
label="Select Mother",
label="Set mother to selected unit",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could also set enabled=function() local unit = dfhack.gui.getSelectedUnit(true) return unit and unit.sex == df.pronoun_type.she end,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and similarly for the father HotkeyLabel

key='CUSTOM_SHIFT_M',
on_activate=self:callback('selectmother'),
},
},
},
widgets.ResizingPanel{
frame={t=6},
frame={t=5},
frame_style=gui.FRAME_INTERIOR,
autoarrange_subviews=true,
subviews={
Expand All @@ -42,47 +56,82 @@ function PregnancyGui:init()
},
widgets.HotkeyLabel{
frame={l=0},
label="Select Father",
label="Set father to selected unit",
key='CUSTOM_SHIFT_F',
on_activate=self:callback('selectfather'),
},
widgets.HotkeyLabel{
frame={l=5},
label="Set Mother's spouse as the Father",
label="Set mother's spouse as the father",
key='CUSTOM_F',
on_activate=self:callback('spouseFather'),
disabled=function() return not self.mother or self.mother.relationship_ids.Spouse == -1 end
},
},
},
widgets.ResizingPanel{
frame={t=12},
widgets.Panel{
frame={t=12,h=14},
frame_style=gui.FRAME_INTERIOR,
autoarrange_subviews=1,
subviews={
widgets.HotkeyLabel{
frame={l=0},
frame={l=0, t=0},
key='CUSTOM_SHIFT_P',
label="Create pregnancy",
on_activate=self:callback('CreatePregnancy'),
enabled=function() return self.mother or self.father and self.father_historical end
Pebob marked this conversation as resolved.
Show resolved Hide resolved
},
widgets.TooltipLabel{
text_to_wrap=self.msg,
show_tooltip=true
},

widgets.ToggleHotkeyLabel{
frame={l=1, t=1},
view_id='Force',
label='Force',
label='Replace existing pregnancy',
options={{label='On', value=true, pen=COLOR_GREEN},
{label='Off', value=false, pen=COLOR_RED}},
initial_option=false
},
widgets.TooltipLabel{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use a plain Label here? The attributes you're setting seem to undo everything that makes it a TooltipLabel

frame={l=0, t=3},
text_to_wrap='Pregnancy term range (months):',
show_tooltip=true,
text_pen=COLOR_WHITE
},
widgets.CycleHotkeyLabel{
view_id='min_term',
frame={l=0, t=6, w=SLIDER_LABEL_WIDTH},
label='Min pregnancy term:',
key_back='CUSTOM_SHIFT_Z',
key='CUSTOM_SHIFT_X',
options=term_options,
initial_option=7
},
widgets.CycleHotkeyLabel{
view_id='max_term',
frame={l=30, t=6, w=SLIDER_LABEL_WIDTH},
label='Max pregnancy term:',
key_back='CUSTOM_SHIFT_Q',
key='CUSTOM_SHIFT_W',
options=term_options,
initial_option=9
},
widgets.RangeSlider{
frame={l=0, t=4},
num_stops=#term_options,
get_left_idx_fn=function()
return term_index[self.subviews.min_term:getOptionLabel()]
end,
get_right_idx_fn=function()
return term_index[self.subviews.max_term:getOptionLabel()]
end,
on_left_change=function(idx) self.subviews.min_term:setOption(idx, true) end,
on_right_change=function(idx) self.subviews.max_term:setOption(idx, true) end,
},
widgets.WrappedLabel{
frame={t=8},--, h=5},
text_to_wrap=function() return self.msg end
},
},
},
widgets.ResizingPanel{
frame={t=22},
frame={t=26},
frame_style=gui.FRAME_INTERIOR,
autoarrange_subviews=true,
subviews={
Expand All @@ -101,17 +150,17 @@ function PregnancyGui:init()
end

function PregnancyGui:selectmother()
local unit = dfhack.gui.getSelectedUnit()
local unit = dfhack.gui.getSelectedUnit(true)
if unit then
if unit.sex==0 and dfhack.units.isAdult(unit) then
if unit.sex==df.pronoun_type.she and dfhack.units.isAdult(unit) then
self.mother = unit
self:updateLayout()
end
end
end

function PregnancyGui:selectfather()
local unit = dfhack.gui.getSelectedUnit()
local unit = dfhack.gui.getSelectedUnit(true)
if unit and dfhack.units.isAdult(unit) then
self.father = unit
self.father_historical = false
Expand Down Expand Up @@ -150,7 +199,7 @@ function PregnancyGui:getMotherLabel()
NEWLINE
)
end
else return ('No mother selected - Must be a adult female')
else return ('No mother selected - Must be an adult female')
end
end

Expand Down Expand Up @@ -178,10 +227,9 @@ function PregnancyGui:getFatherLabel()
end

function PregnancyGui:findName(unit)
if unit.name.has_name then
return dfhack.TranslateName(unit.name)
elseif unit.name.nickname ~= "" then
return unit.name.nickname
local name = dfhack.TranslateName(unit.name)
if name ~= "" then
return name
else return ('Unnamed %s. (Unit id:%s)'):format(
string.upper(df.global.world.raws.creatures.all[unit.race].name[0]),
unit.id
Expand Down Expand Up @@ -239,12 +287,17 @@ function PregnancyGui:findSpouse(unit)
end

function PregnancyGui:CreatePregnancy()
local genes,father_id,father_caste,father_name
local genes,father_id,father_caste,father_name
local bypass = true
local force = self.subviews.Force:getOptionValue()

local count = #self.msg
for i=0, count do self.msg[i]=nil end --empty self.msg
self.msg = {}

if self.subviews.min_term:getOptionLabel() > self.subviews.max_term:getOptionLabel() then
table.insert(self.msg,('Min term has to be less then max term'))
self:updateLayout()
return
end

if self.father then
genes=self.father.appearance.genes:new()
Expand All @@ -262,7 +315,7 @@ function PregnancyGui:CreatePregnancy()
local og_father = df.historical_figure.find(self.mother.pregnancy_spouse)
bypass = false
if force and og_father then
table.insert(self.msg, ('SUCCESS:%sMother:%s%sFather:%s%sPrevious pregnancy with %s aborted'):format(
table.insert(self.msg, ('SUCCESS:%sMother:%s%sFather:%s%sPrevious pregnancy with %s replaced'):format(
NEWLINE,
self:findName(self.mother),
NEWLINE,
Expand Down Expand Up @@ -292,14 +345,12 @@ function PregnancyGui:CreatePregnancy()
))
end
end
-- self.success = false

if bypass or force then
--TODO add GUI to select the number of months for pregnancy timer
self.mother.pregnancy_timer=math.random(1, 13000)
self.mother.pregnancy_timer=math.random(self.subviews.min_term:getOptionLabel()*33600+1, self.subviews.max_term:getOptionLabel()*33600+1)
self.mother.pregnancy_caste=father_caste
self.mother.pregnancy_spouse=father_id
self.mother.pregnancy_genes=genes
-- self.success = true
if not force then
table.insert(self.msg, ('SUCCESS:%sMother:%s%sFather:%s'):format(
NEWLINE,
Expand All @@ -314,7 +365,7 @@ end

PregnancyScreen = defclass(PregnancyScreen, gui.ZScreen)
PregnancyScreen.ATTRS {
focus_path='PregnancyScreen',
focus_path='pregnancy',
}

function PregnancyScreen:init()
Expand All @@ -325,4 +376,4 @@ function PregnancyScreen:onDismiss()
view = nil
end

view = view and view:raise() or PregnancyScreen{}:show()
view = view and view:raise() or PregnancyScreen{}:show()
Loading