Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2187496
fixed reload/reset buttons
SimGamerJen Jul 18, 2026
9872fbc
fixed reload/reset buttons
SimGamerJen Jul 18, 2026
24ad377
Update README.md
SimGamerJen Jul 18, 2026
119bc15
Update HelperPayroll role configuration
SimGamerJen Jul 28, 2026
d0ed8b2
Update HelperPayroll version and API description
SimGamerJen Jul 28, 2026
4664343
Stage verified HelperPayroll Lua payload 1/8
SimGamerJen Jul 28, 2026
2cb11e0
Stage verified HelperPayroll Lua payload 2/8
SimGamerJen Jul 28, 2026
3b9938b
Stage verified HelperPayroll Lua payload 3/8
SimGamerJen Jul 28, 2026
0d1368c
Stage verified HelperPayroll Lua payload 5/8
SimGamerJen Jul 28, 2026
f55a89f
Stage verified HelperPayroll Lua payload 6/8
SimGamerJen Jul 28, 2026
5bf12cd
Stage verified HelperPayroll Lua payload 7/8
SimGamerJen Jul 28, 2026
334c941
Stage verified HelperPayroll Lua payload 8/8
SimGamerJen Jul 28, 2026
f25eec4
Trigger source verification diagnostic
SimGamerJen Jul 28, 2026
c886ba7
Record HelperPayroll transfer diagnostic
github-actions[bot] Jul 28, 2026
1a925d3
Stage missing HelperPayroll Lua payload 4/8
SimGamerJen Jul 28, 2026
14c5f51
Record HelperPayroll transfer diagnostic
github-actions[bot] Jul 28, 2026
67bd7fa
Trigger final verified source recovery
SimGamerJen Jul 28, 2026
212757d
Remove malformed HelperPayroll transfer segment
SimGamerJen Jul 28, 2026
27b821e
Stage corrected HelperPayroll segment 3a
SimGamerJen Jul 28, 2026
e6615cf
Stage corrected HelperPayroll segment 3b
SimGamerJen Jul 28, 2026
4e87f4d
Restore exact HelperPayroll role API source
github-actions[bot] Jul 28, 2026
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
Binary file added HelperPayroll_icon.dds
Binary file not shown.
539 changes: 432 additions & 107 deletions README.md

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions config/defaultPayrollConfig.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<helperPayroll>
<settings>
<debug>true</debug>
<suppressVanillaAIWorkerCosts>true</suppressVanillaAIWorkerCosts>
<enableCustomWorkerCosts>true</enableCustomWorkerCosts>

<!-- Public/default profile. This mod uses the savegame's own money display settings. -->
<activePayrollProfile>default</activePayrollProfile>

<!--
roleType = vanilla-friendly mode; all AI jobs use selectedRole for payroll.
helperSlot = advanced/roleplay mode; detected vanilla helper slot A-J resolves to helperSlots below.
-->
<payrollMode>roleType</payrollMode>
<selectedRole>standard</selectedRole>
<fallbackRole>standard</fallbackRole>

<!-- Optional fallback only. Leave blank unless you deliberately want every job assigned to one slot. -->
<defaultHelperSlot></defaultHelperSlot>

<chargeCustomWorkerCosts>true</chargeCustomWorkerCosts>
<billingMode>onJobFinish</billingMode>
<payrollHour>18</payrollHour>
<minimumWorkerCharge>5.00</minimumWorkerCharge>
<workerCalloutFee>0.00</workerCalloutFee>
<roundWorkerCharges>true</roundWorkerCharges>
<roleSelectorDebounceMs>450</roleSelectorDebounceMs>
<logLevel>normal</logLevel>
<debugAllMoneyTransactions>false</debugAllMoneyTransactions>
<helperProfilesDiagnostics>false</helperProfilesDiagnostics>
<helperProfilesDiagnosticLimit>12</helperProfilesDiagnosticLimit>
</settings>

<profiles>
<profile id="default" name="Default Helper Payroll" economyMultiplier="1.00" />
<profile id="uk_tenant" name="UK Tenant Farm Example" economyMultiplier="1.00" />
<profile id="us_ranch" name="US Ranch Example" economyMultiplier="1.00" />
</profiles>

<workerRates profile="default">
<worker id="owner" name="Owner Labour" payBasis="hourly" rate="0" minimumCallout="0" />
<worker id="trainee" name="Trainee Helper" payBasis="hourly" rate="10" minimumCallout="5" />
<worker id="standard" name="Standard Helper" payBasis="hourly" rate="18" minimumCallout="5" />
<worker id="skilled" name="Skilled Operator" payBasis="hourly" rate="22" minimumCallout="5" />
<worker id="contractor" name="Contractor" payBasis="hourly" rate="30" minimumCallout="5" />
</workerRates>

<workerRates profile="uk_tenant">
<worker id="owner" name="Owner Labour" payBasis="hourly" rate="0" minimumCallout="0" />
<worker id="trainee" name="Trainee Helper" payBasis="hourly" rate="10" minimumCallout="5" />
<worker id="standard" name="General Farmhand" payBasis="hourly" rate="14" minimumCallout="5" />
<worker id="skilled" name="Skilled Operator" payBasis="hourly" rate="18" minimumCallout="5" />
<worker id="manager" name="Farm Manager" payBasis="hourly" rate="24" minimumCallout="5" />
<worker id="contractor" name="External Contractor" payBasis="hourly" rate="28" minimumCallout="5" />
</workerRates>

<workerRates profile="us_ranch">
<worker id="owner" name="Owner Labour" payBasis="hourly" rate="0" minimumCallout="0" />
<worker id="trainee" name="Trainee Ranch Hand" payBasis="hourly" rate="14" minimumCallout="5" />
<worker id="standard" name="Ranch Hand" payBasis="hourly" rate="18" minimumCallout="5" />
<worker id="skilled" name="Skilled Operator" payBasis="hourly" rate="24" minimumCallout="5" />
<worker id="manager" name="Ranch Manager" payBasis="hourly" rate="30" minimumCallout="5" />
<worker id="contractor" name="External Contractor" payBasis="hourly" rate="35" minimumCallout="5" />
</workerRates>

<!-- Advanced mode only: used when payrollMode="helperSlot". -->
<helperSlots profile="default">
<helper slot="A" name="Helper A" role="Standard Helper" workerRate="standard" />
<helper slot="B" name="Helper B" role="Standard Helper" workerRate="standard" />
<helper slot="C" name="Helper C" role="Standard Helper" workerRate="standard" />
<helper slot="D" name="Helper D" role="Standard Helper" workerRate="standard" />
<helper slot="E" name="Helper E" role="Standard Helper" workerRate="standard" />
<helper slot="F" name="Helper F" role="Standard Helper" workerRate="standard" />
<helper slot="G" name="Helper G" role="Standard Helper" workerRate="standard" />
<helper slot="H" name="Helper H" role="Standard Helper" workerRate="standard" />
<helper slot="I" name="Helper I" role="Standard Helper" workerRate="standard" />
<helper slot="J" name="Helper J" role="Standard Helper" workerRate="standard" />
</helperSlots>

<!-- Example roleplay setup for use with HelperProfiles-style helper slot identities. -->
<helperSlots profile="uk_tenant">
<helper slot="A" name="Marty" role="Farm Manager" workerRate="manager" />
<helper slot="B" name="Rhys" role="Skilled Operator" workerRate="skilled" />
<helper slot="C" name="Ellie" role="General Farmhand" workerRate="standard" />
<helper slot="D" name="Graham" role="Contractor" workerRate="contractor" />
</helperSlots>

<helperSlots profile="us_ranch">
<helper slot="A" name="Riley" role="Skilled Operator" workerRate="skilled" />
<helper slot="B" name="Jed" role="Neighbour / Mates Rate" workerRate="standard" />
<helper slot="C" name="Miguel" role="Ranch Hand" workerRate="standard" />
<helper slot="D" name="External Contractor" role="Contractor" workerRate="contractor" />
</helperSlots>
</helperPayroll>
69 changes: 69 additions & 0 deletions gui/HelperPayrollMenu.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<GUI name="HelperPayrollMenu" onOpen="onOpen" onClose="onClose" onCreate="onCreate" onEscPressed="onClickBack">
<Bitmap profile="fs25_fullScreenBackground" id="background" imageColor="0.01681 0.01764 0.016 0.98"/>
<Bitmap profile="baseReference" position="80px 78px" size="1760px 895px" imageColor="0.025 0.028 0.025 0.92"/>

<GuiElement profile="fs25_menuContainer">
<GuiElement profile="fs25_menuHeaderPanel">
<Bitmap profile="fs25_menuHeaderIconBg">
<Bitmap profile="fs25_menuHeaderIcon"/>
</Bitmap>
<Text profile="fs25_menuHeaderTitle" id="titleElement" text="HELPER PAYROLL"/>
</GuiElement>

<BoxLayout profile="fs25_subCategorySelectorTabbedBox" id="subCategoryBox">
<Button profile="fs25_subCategorySelectorTabbedTab" id="subCategoryTabs[1]" text="OVERVIEW" onClick="onClickOverview"><ThreePartBitmap profile="fs25_subCategorySelectorTabbedTabBg" name="background"/></Button>
<Button profile="fs25_subCategorySelectorTabbedTab" id="subCategoryTabs[2]" text="BILLING" onClick="onClickBilling"><ThreePartBitmap profile="fs25_subCategorySelectorTabbedTabBg" name="background"/></Button>
<Button profile="fs25_subCategorySelectorTabbedTab" id="subCategoryTabs[3]" text="ROLES" onClick="onClickRoles"><ThreePartBitmap profile="fs25_subCategorySelectorTabbedTabBg" name="background"/></Button>
<Button profile="fs25_subCategorySelectorTabbedTab" id="subCategoryTabs[4]" text="WORKERS" onClick="onClickWorkers"><ThreePartBitmap profile="fs25_subCategorySelectorTabbedTabBg" name="background"/></Button>
<Button profile="fs25_subCategorySelectorTabbedTab" id="subCategoryTabs[5]" text="LEDGER" onClick="onClickLedger"><ThreePartBitmap profile="fs25_subCategorySelectorTabbedTabBg" name="background"/></Button>
<Button profile="fs25_subCategorySelectorTabbedTab" id="subCategoryTabs[6]" text="HELP" onClick="onClickHelp"><ThreePartBitmap profile="fs25_subCategorySelectorTabbedTabBg" name="background"/></Button>
</BoxLayout>
<ThreePartBitmap profile="fs25_lineSeparatorTopHighlighted" position="0px -57px"/>

<GuiElement profile="fs25_subCategorySelectorTabbedContainer" id="hpayMainPage">
<Bitmap position="-20px 150px" size="1525px 615px" imageColor="0.015 0.017 0.015 0.28"/>
<Text id="hintText" text="HelperPayroll management | Worker mappings are stored per save | APPLY writes current save payroll settings" position="0px 12px" size="1480px 25px" textSize="15px" textColor="0.55 0.63 0.50 1" textVerticalAlignment="middle" textAlignment="left"/>

<Text id="bodyTextElement" text="" position="40px 150px" size="1480px 585px" textSize="16px" textColor="0.88 0.90 0.86 1" textVerticalAlignment="top" textAlignment="left" textMaxNumLines="36"/>

<GuiElement id="tableContainer" visible="false" position="0px 240px" size="1520px 545px">
<GuiElement id="tableListArea" position="0px 0px" size="1520px 545px">
<GuiElement profile="fs25_statisticsHeaderBox" position="0px -18px" size="1465px 38px">
<Text profile="hpayColumnHeader" position="20px -3px" size="420px 34px" text="Item"/>
<Text profile="hpayColumnHeader" position="470px -3px" size="285px 34px" text="Value"/>
<Text profile="hpayColumnHeader" position="805px -3px" size="220px 34px" text="Status"/>
<Text profile="hpayColumnHeader" position="1065px -3px" size="360px 34px" text="Source"/>
</GuiElement>

<SmoothList id="itemList" profile="hpayListWide" position="0px -70px" size="1465px 430px" listItemSpacing="-1px">
<ListItem profile="hpayListItem">
<ThreePartBitmap profile="hpayListItemGradient" name="alternating"/>
<Text profile="hpayRowCellLeft" position="20px 0px" size="420px 34px" name="cellItem"/>
<Button profile="hpayInlineAdjustButton" position="470px -3px" size="38px 30px" name="cellPrev" text="&lt;" onClick="onClickCellPrev"/>
<Text profile="hpayRowCellValue" position="520px 0px" size="185px 34px" name="cellValue"/>
<Button profile="hpayInlineAdjustButton" position="717px -3px" size="38px 30px" name="cellNext" text="&gt;" onClick="onClickCellNext"/>
<Text profile="hpayRowCellCenter" position="805px 0px" size="220px 34px" name="cellStatus"/>
<Text profile="hpayRowCellCenter" position="1065px 0px" size="360px 34px" name="cellSource"/>
</ListItem>
</SmoothList>

<ThreePartBitmap profile="hpaySliderBoxTall" position="1475px -70px" size="6px 430px" id="itemListSliderBox"><Slider profile="fs25_listSlider" dataElementId="itemList"/></ThreePartBitmap>

<Text profile="hpayDetailsInfo" id="rowHelpText" position="20px -520px" size="1020px 44px" text="Select an editable row, then use the left/right controls in the Value column. APPLY writes the current save payroll settings."/>
<Text profile="hpayDetailsDirty" id="dirtyText" position="20px -575px" size="1020px 42px" text=""/>
<Button profile="hpayActionButton" id="applyButton" position="1085px -522px" size="180px 36px" text="APPLY" onClick="onClickApply"/>
<Button profile="hpayActionButton" id="discardButton" position="1285px -522px" size="180px 36px" text="DISCARD" onClick="onClickDiscard"/>
</GuiElement>
</GuiElement>
</GuiElement>

<BoxLayout profile="fs25_dialogButtonBox">
<Button profile="buttonMenuPrev" text="PREV TAB" onClick="onPagePrevious" id="prevTabButton"/>
<Button profile="buttonMenuNext" text="NEXT TAB" onClick="onPageNext" id="nextTabButton"/>
<Button profile="buttonExtra1" text="RELOAD SAVE" onClick="onClickReload" id="reloadButton"/>
<Button profile="hpayActionButton" text="RESET SAVE" onClick="onClickReset" id="resetButton"/>
<Button profile="buttonBack" text="$l10n_button_back" onClick="onClickBack" id="backButton"/>
</BoxLayout>
</GuiElement>
</GUI>
182 changes: 182 additions & 0 deletions gui/guiProfiles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<GUIProfiles>
<Profile name="hpayColumnHeader" extends="baseReference" with="anchorTopLeft">
<imageColor value="0 0 0 0"/>
<textSize value="13px"/>
<textBold value="true"/>
<textUpperCase value="true"/>
<textColor value="$preset_colorWhite_50"/>
<textAlignment value="center"/>
<textVerticalAlignment value="middle"/>
</Profile>

<Profile name="hpayList" extends="emptyPanel" with="pivotTopLeft">
<size value="1060px 493px"/>
</Profile>

<Profile name="hpayListItem" extends="fs25_calendarListItem">
<height value="34px"/>
<imageColor value="$preset_fs25_colorGrey"/>
<imageSelectedColor value="$preset_fs25_colorMainHighlight"/>
<alternateBackgroundColor value="$preset_fs25_colorGreyDark_50"/>
</Profile>

<Profile name="hpayListItemGradient" extends="fs25_calendarListItemBg">
<imageSelectedColor value="$preset_fs25_colorMainHighlight"/>
<startImageSelectedColor value="$preset_fs25_colorMainHighlight"/>
<endImageSelectedColor value="$preset_fs25_colorMainHighlight"/>
</Profile>

<Profile name="hpayRowCellLeft" extends="baseReference" with="anchorStretchingYLeft">
<textBold value="false"/>
<textSize value="14px"/>
<textAlignment value="left"/>
<textVerticalAlignment value="middle"/>
<textColor value="$preset_fs25_colorMainLight"/>
<textSelectedColor value="$preset_fs25_colorMainDark"/>
<textDisabledColor value="$preset_colorDisabled"/>
</Profile>

<Profile name="hpayRowCellCenter" extends="hpayRowCellLeft">
<textAlignment value="center"/>
<textBold value="true"/>
</Profile>

<Profile name="hpayRowCellRight" extends="hpayRowCellLeft">
<textAlignment value="right"/>
<textBold value="true"/>
</Profile>

<Profile name="hpaySliderBox" extends="fs25_listSliderBox" with="anchorTopRight">
<width value="6px"/>
<height value="493px"/>
</Profile>

<Profile name="hpayDetailsHeader" extends="baseReference" with="anchorTopLeft">
<textSize value="14px"/>
<textBold value="true"/>
<textUpperCase value="true"/>
<textColor value="$preset_colorWhite_50"/>
<textAlignment value="left"/>
<textVerticalAlignment value="middle"/>
</Profile>

<Profile name="hpayDetailsTitle" extends="baseReference" with="anchorTopLeft">
<textSize value="20px"/>
<textBold value="true"/>
<textUpperCase value="true"/>
<textColor value="$preset_fs25_colorMainLight"/>
<textAlignment value="left"/>
<textVerticalAlignment value="middle"/>
</Profile>

<Profile name="hpayDetailsLabel" extends="baseReference" with="anchorTopLeft">
<textSize value="14px"/>
<textBold value="false"/>
<textColor value="$preset_colorWhite_50"/>
<textAlignment value="left"/>
<textVerticalAlignment value="middle"/>
</Profile>

<Profile name="hpayDetailsValue" extends="baseReference" with="anchorTopLeft">
<textSize value="14px"/>
<textBold value="true"/>
<textColor value="$preset_fs25_colorMainLight"/>
<textAlignment value="right"/>
<textVerticalAlignment value="middle"/>
</Profile>

<Profile name="hpayDetailsInfo" extends="baseReference" with="anchorTopLeft">
<textSize value="14px"/>
<textBold value="false"/>
<textColor value="0.72 0.76 0.68 1"/>
<textAlignment value="left"/>
<textVerticalAlignment value="top"/>
<textMaxNumLines value="7"/>
</Profile>

<Profile name="hpayDetailsDirty" extends="hpayDetailsInfo">
<textColor value="$preset_fs25_colorMainHighlight"/>
<textBold value="true"/>
<textMaxNumLines value="3"/>
</Profile>

<Profile name="hpayEditButton" extends="buttonBase" with="anchorTopLeft">
<size value="84px 28px"/>
<textSize value="13px"/>
<textBold value="true"/>
<textUpperCase value="true"/>
<textColor value="$preset_fs25_colorMainLight"/>
<textFocusedColor value="$preset_fs25_colorMainLight"/>
<textHighlightedColor value="$preset_fs25_colorMainLight"/>
<textPressedColor value="$preset_fs25_colorMainLight"/>
<textDisabledColor value="$preset_colorDisabled"/>
<textAlignment value="center"/>
<textVerticalAlignment value="middle"/>
<imageSliceId value="gui.empty"/>
<imageColor value="0 0 0 0"/>
<imageFocusedColor value="$preset_fs25_colorMainHighlight"/>
<imageHighlightedColor value="$preset_fs25_colorMainHighlight"/>
<imagePressedColor value="$preset_fs25_colorMainHighlight"/>
<imageDisabledColor value="0.08 0.09 0.08 0.30"/>
<clickSound value="DEFAULT_CLICK"/>
<sendActionOnRelease value="true"/>
</Profile>

<Profile name="hpayEditButtonWide" extends="hpayEditButton">
<size value="180px 28px"/>
</Profile>

<Profile name="hpaySelectorOption" extends="fs25_multiTextOption" with="anchorTopLeft">
<size value="180px 28px"/>
<focusOnHighlight value="true"/>
<wrap value="false"/>
<hideButtonOnLimitReached value="true"/>
</Profile>



<Profile name="hpayListWide" extends="hpayList">
<size value="1465px 430px"/>
</Profile>

<Profile name="hpaySliderBoxTall" extends="hpaySliderBox">
<height value="430px"/>
</Profile>

<Profile name="hpayRowCellValue" extends="hpayRowCellRight">
<textAlignment value="center"/>
<textBold value="true"/>
</Profile>

<Profile name="hpayInlineAdjustButton" extends="hpayEditButton">
<size value="38px 30px"/>
<textSize value="15px"/>
<imageColor value="0.08 0.09 0.08 0.64"/>
<imageFocusedColor value="$preset_fs25_colorMainHighlight"/>
<imageHighlightedColor value="$preset_fs25_colorMainHighlight"/>
<imagePressedColor value="$preset_fs25_colorMainHighlight"/>
</Profile>

<Profile name="hpayActionButton" extends="buttonBase" with="anchorTopLeft">
<size value="190px 36px"/>
<textSize value="14px"/>
<textBold value="true"/>
<textUpperCase value="true"/>
<textColor value="$preset_fs25_colorMainLight"/>
<textFocusedColor value="$preset_fs25_colorMainLight"/>
<textHighlightedColor value="$preset_fs25_colorMainLight"/>
<textPressedColor value="$preset_fs25_colorMainLight"/>
<textDisabledColor value="$preset_colorDisabled"/>
<textAlignment value="center"/>
<textVerticalAlignment value="middle"/>
<imageSliceId value="gui.empty"/>
<imageColor value="0.08 0.09 0.08 0.88"/>
<imageFocusedColor value="0.68 0.96 0.08 0.30"/>
<imageHighlightedColor value="0.68 0.96 0.08 0.30"/>
<imagePressedColor value="0.68 0.96 0.08 0.42"/>
<imageDisabledColor value="0.08 0.09 0.08 0.30"/>
<clickSound value="DEFAULT_CLICK"/>
<sendActionOnRelease value="true"/>
</Profile>
</GUIProfiles>
Loading