diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm
index d450db15f1a..8e58a93627e 100644
--- a/code/game/objects/items/weapons/storage/wallets.dm
+++ b/code/game/objects/items/weapons/storage/wallets.dm
@@ -98,3 +98,9 @@
/obj/item/weapon/storage/wallet/trader/New()
..()
dispense_cash(rand(150,250),src)
+
+/obj/item/weapon/storage/wallet/nt
+ icon_state = "wallet-NT"
+
+/obj/item/weapon/storage/wallet/nt/update_icon()
+ return
diff --git a/code/modules/Economy/Accounts.dm b/code/modules/Economy/Accounts.dm
index eb91a50d5bb..1bfb84693db 100644
--- a/code/modules/Economy/Accounts.dm
+++ b/code/modules/Economy/Accounts.dm
@@ -15,6 +15,8 @@ var/datum/money_account/trader_account
var/station_allowance = 0//This is what Nanotrasen will send to the Station Account after every salary, as provision for the next salary.
var/latejoiner_allowance = 0//Added to station_allowance and reset before every wage payout.
+var/station_funding = 0 //A bonus to the station allowance that persists between cycles. Admins can set this on the database.
+var/station_bonus = 0 //A bonus to station allowance that gets reset after wage payout. Admins can boost this too.
/proc/create_station_account()
if(!station_account)
@@ -245,7 +247,11 @@ var/latejoiner_allowance = 0//Added to station_allowance and reset before every
if(access_level > 0 || isAdminGhost(user) || is_malf_owner(user))
dat += {"[activated ? "Disable" : "Enable"] remote access
- Combined department and personnel budget is currently [station_allowance] credits. A total of [global.requested_payroll_amount] credits were requested during the last payroll cycle.
"}
+ Combined department and personnel budget is currently [station_allowance+station_bonus+station_funding] credits. A total of [global.requested_payroll_amount] credits were requested during the last payroll cycle.
"}
+ if(station_bonus || isAdminGhost(user))
+ dat += "The budget was increased by a bonus of [station_bonus] this cycle. [isAdminGhost(user) ? "Adjust" : ""]
"
+ if(station_funding || isAdminGhost(user))
+ dat += "Central Command has earmarked an additional [station_funding] for the budget. [isAdminGhost(user) ? "Adjust" : ""]
"
if(creating_new_account)
dat += {"
@@ -404,6 +410,16 @@ var/latejoiner_allowance = 0//Added to station_allowance and reset before every
if("view_accounts_list")
detailed_account_view = null
creating_new_account = 0
+ if("addfunding")
+ if(!isAdminGhost(usr))
+ return
+ var/new_funding = input(usr, "Adjust the budget for ALL cycles", "Adjust by", station_funding) as null|num
+ station_funding = new_funding
+ if("addbonus")
+ if(!isAdminGhost(usr))
+ return
+ var/new_bonus = input(usr, "Adjust the budget for THIS cycles", "Adjust by", station_bonus) as null|num
+ station_bonus = new_bonus
if("toggle_account")
if(detailed_account_view)
detailed_account_view.disabled = detailed_account_view.disabled ? 0 : 2
diff --git a/code/modules/Economy/Wages.dm b/code/modules/Economy/Wages.dm
index 275cff2c0ef..c9ccb3b6df1 100644
--- a/code/modules/Economy/Wages.dm
+++ b/code/modules/Economy/Wages.dm
@@ -68,7 +68,11 @@ If all wages are decreased bellow 100%, for example due to the AI spending all t
if(!station_account)
message_admins("Station allowance skipped, no station account found.")
return
- station_account.money += station_allowance + WageBonuses()
+
+ for(var/obj/machinery/computer/accounting/A in machines)
+ A.new_cycle()
+ station_account.money += station_allowance + WageBonuses() + station_funding + station_bonus
+ station_bonus = 0
new /datum/transaction(station_account,"Nanotrasen station allowance","[station_allowance]","Nanotrasen Payroll Server",send2PDAs=FALSE)
diff --git a/code/modules/library/computers/accounting.dm b/code/modules/library/computers/accounting.dm
new file mode 100644
index 00000000000..ac091923be7
--- /dev/null
+++ b/code/modules/library/computers/accounting.dm
@@ -0,0 +1,143 @@
+/obj/machinery/computer/accounting
+ name = "accounting computer"
+ desc = "For virtual bookkeeping. This computer is used in the calculation of overages."
+ pass_flags = PASSTABLE
+ machine_flags = WRENCHMOVE | FIXED2WORK
+ icon = 'icons/obj/library.dmi'
+ icon_state = "computer"
+ req_access = list(access_library)
+ var/savings = 0 //Total savings this cycle
+ var/oldgood = -1 //Was our last calculation correct? -1 indicates no last query this cycle, resets to -1 at cycle end, 0 is bad, 1 is good
+ var/oldentry = 0 //Our last attempted difference
+
+ var/minuend
+ var/subtrahend
+ var/oldquery
+ var/currentqueryname
+ var/nextmin
+ var/nextsub
+ var/entryinfo = "Accounting Report
"
+ var/list/contributors = list()
+
+/obj/machinery/computer/accounting/New()
+ ..()
+ generatenext()
+ readynext()
+
+/obj/machinery/computer/accounting/Destroy()
+ contributors.Cut()
+ ..()
+
+/obj/machinery/computer/accounting/attack_hand(mob/user as mob)
+ if(..())
+ return
+ if(stat & (NOPOWER|BROKEN|FORCEDISABLE))
+ return
+ ui_interact(user)
+
+/obj/machinery/computer/accounting/ui_interact(mob/user, ui_key="main", datum/nanoui/ui=null, var/force_open=NANOUI_FOCUS)
+ user.set_machine(src)
+
+ var/data[0]
+ data["src"] = "\ref[src]"
+ data["savings"] = savings
+ data["oldgood"] = oldgood
+ data["oldquery"] = oldquery
+ data["oldentry"] = oldentry
+ data["minuend"] = minuend
+ data["subtrahend"] = subtrahend
+ data["currentqueryname"] = currentqueryname
+ data["nextquery"] = "[nextmin] - [nextsub]"
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "accounting.tmpl", src.name, 600, 500)
+ ui.set_initial_data(data)
+ ui.open()
+
+/obj/machinery/computer/accounting/Topic(href, href_list)
+ if(..())
+ return 1
+ if(!allowed(usr))
+ to_chat(usr, "You do not have accounting clearance.")
+ return
+ if(href_list["reg"])
+ if(!in_range(src, usr))
+ return 1
+ var/sol = text2num(href_list["reg"])
+ if(isnull(sol))
+ visible_message("[src] buzzes rudely.")
+ playsound(src, 'sound/machines/buzz-two.ogg', 50, 0)
+ return 1
+ solve_query(sol)
+ if(!(usr.name in contributors))
+ contributors += usr.name
+ nanomanager.update_uis(src)
+ return 1
+
+/obj/machinery/computer/accounting/proc/solve_query(var/sol)
+ playsound(loc, "sound/effects/typing[pick(1,2,3)].ogg", 50, 1)
+ var/diff = minuend - subtrahend
+ if(sol == diff)
+ oldgood = TRUE
+ savings += sol
+ entryinfo += "[currentqueryname]: $[sol] overage saved
"
+ else
+ oldgood = FALSE
+
+ spawn(1 SECONDS)
+ playsound(loc, oldgood ? 'sound/machines/ding2.ogg': 'sound/machines/buzz-sigh.ogg', 50, 1)
+
+ oldquery = "[minuend] - [subtrahend]"
+ oldentry = sol
+ readynext()
+
+
+/obj/machinery/computer/accounting/proc/readynext()
+ currentqueryname = buildname()
+ minuend = nextmin
+ subtrahend = nextsub
+ generatenext()
+ nanomanager.update_uis(src)
+
+/obj/machinery/computer/accounting/proc/new_cycle()
+ if(!savings)
+ return
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc)
+ P.name = "accounting report for [worldtime2text()]"
+ P.info = "[entryinfo]" + "Total savings: $[savings]
Prepared in part by: [english_list(contributors)]
This document is to be verified by Internal Affairs and faxed to Central Command.
"
+ var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
+ stampoverlay.icon_state = "paper_stamp-cent"
+ if(!P.stamped)
+ P.stamped = new
+ P.stamped += /obj/item/weapon/stamp
+ P.overlays += stampoverlay
+ P.stamps += "