Merge pull request #3693 from caelaislinn/accounts_updates

Economy/Accounts updates
This commit is contained in:
Chinsky
2013-09-24 10:15:10 -07:00
16 changed files with 601 additions and 664 deletions

392
code/modules/Economy/ATM.dm Normal file
View File

@@ -0,0 +1,392 @@
/*
TODO:
give money an actual use (QM stuff, vending machines)
send money to people (might be worth attaching money to custom database thing for this, instead of being in the ID)
log transactions
*/
#define NO_SCREEN 0
#define CHANGE_SECURITY_LEVEL 1
#define TRANSFER_FUNDS 2
#define VIEW_TRANSACTION_LOGS 3
/obj/item/weapon/card/id/var/money = 2000
/obj/machinery/atm
name = "NanoTrasen Automatic Teller Machine"
desc = "For all your monetary needs!"
icon = 'icons/obj/terminals.dmi'
icon_state = "atm"
anchored = 1
use_power = 1
idle_power_usage = 10
var/datum/money_account/authenticated_account
var/number_incorrect_tries = 0
var/previous_account_number = 0
var/max_pin_attempts = 3
var/ticks_left_locked_down = 0
var/ticks_left_timeout = 0
var/machine_id = ""
var/obj/item/weapon/card/held_card
var/editing_security_level = 0
var/view_screen = NO_SCREEN
/obj/machinery/atm/New()
..()
machine_id = "[station_name()] RT #[num_financial_terminals++]"
/obj/machinery/atm/process()
if(stat & NOPOWER)
return
if(ticks_left_timeout > 0)
ticks_left_timeout--
if(ticks_left_timeout <= 0)
authenticated_account = null
if(ticks_left_locked_down > 0)
ticks_left_locked_down--
if(ticks_left_locked_down <= 0)
number_incorrect_tries = 0
for(var/obj/item/weapon/spacecash/S in src)
S.loc = src.loc
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
break
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/card))
var/obj/item/weapon/card/id/idcard = I
if(!held_card)
usr.drop_item()
idcard.loc = src
held_card = idcard
if(authenticated_account && held_card.associated_account_number != authenticated_account.account_number)
authenticated_account = null
else if(authenticated_account)
if(istype(I,/obj/item/weapon/spacecash))
//consume the money
authenticated_account.money += I:worth
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit deposit"
T.amount = I:worth
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
user << "<span class='info'>You insert [I] into [src].</span>"
src.attack_hand(user)
del I
else
..()
/obj/machinery/atm/attack_hand(mob/user as mob)
if(istype(user, /mob/living/silicon))
user << "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005."
return
if(get_dist(src,user) <= 1)
//check to see if the user has low security enabled
scan_user(user)
//js replicated from obj/machinery/computer/card
var/dat = "<h1>NanoTrasen Automatic Teller Machine</h1>"
dat += "For all your monetary needs!<br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting NanoTrasen IT Support</i><br/>"
dat += "Card: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card.name : "------"]</a><br><br>"
if(ticks_left_locked_down > 0)
dat += "<span class='alert'>Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled.</span>"
else if(authenticated_account)
if(authenticated_account.suspended)
dat += "\red<b>Access to this account has been suspended, and the funds within frozen.</b>"
else
switch(view_screen)
if(CHANGE_SECURITY_LEVEL)
dat += "Select a new security level for this account:<br><hr>"
var/text = "Zero - Either the account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
if(authenticated_account.security_level != 0)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=0'>[text]</a>"
dat += "[text]<hr>"
text = "One - An account number and pin must be manually entered to access this account and process transactions."
if(authenticated_account.security_level != 1)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=1'>[text]</a>"
dat += "[text]<hr>"
text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
if(authenticated_account.security_level != 2)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=2'>[text]</a>"
dat += "[text]<hr><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
if(VIEW_TRANSACTION_LOGS)
dat += "<b>Transaction logs</b><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
if(TRANSFER_FUNDS)
dat += "<b>Account balance:</b> $[authenticated_account.money]<br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a><br><br>"
dat += "<form name='transfer' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='transfer'>"
dat += "Target account number: <input type='text' name='target_acc_number' value='' style='width:200px; background-color:white;'><br>"
dat += "Funds to transfer: <input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><br>"
dat += "Transaction purpose: <input type='text' name='purpose' value='Funds transfer' style='width:200px; background-color:white;'><br>"
dat += "<input type='submit' value='Transfer funds'><br>"
dat += "</form>"
else
dat += "Welcome, <b>[authenticated_account.owner_name].</b><br/>"
dat += "<b>Account balance:</b> $[authenticated_account.money]"
dat += "<form name='withdrawal' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='withdrawal'>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw funds'><br>"
dat += "</form>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=1'>Change account security level</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=2'>Make transfer</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=3'>View transaction log</a><br>"
dat += "<A href='?src=\ref[src];choice=balance_statement'>Print balance statement</a><br>"
dat += "<A href='?src=\ref[src];choice=logout'>Logout</a><br>"
else
dat += "<form name='atm_auth' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='attempt_auth'>"
dat += "<b>Account:</b> <input type='text' id='account_num' name='account_num' style='width:250px; background-color:white;'><br>"
dat += "<b>PIN:</b> <input type='text' id='account_pin' name='account_pin' style='width:250px; background-color:white;'><br>"
dat += "<input type='submit' value='Submit'><br>"
dat += "</form>"
user << browse(dat,"window=atm;size=550x650")
else
user << browse(null,"window=atm")
/obj/machinery/atm/Topic(var/href, var/href_list)
if(href_list["choice"])
switch(href_list["choice"])
if("transfer")
if(authenticated_account)
var/transfer_amount = text2num(href_list["funds_amount"])
if(transfer_amount <= 0)
alert("That is not a valid amount.")
else if(transfer_amount <= authenticated_account.money)
var/target_account_number = text2num(href_list["target_acc_number"])
var/transfer_purpose = href_list["purpose"]
if(charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
usr << "\icon[src]<span class='info'>Funds transfer successful.</span>"
authenticated_account.money -= transfer_amount
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = "Account #[target_account_number]"
T.purpose = transfer_purpose
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
T.amount = "([transfer_amount])"
authenticated_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>Funds transfer failed.</span>"
else
usr << "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>"
if("view_screen")
view_screen = text2num(href_list["view_screen"])
if("change_security_level")
if(authenticated_account)
var/new_sec_level = max( min(text2num(href_list["new_security_level"]), 2), 0)
authenticated_account.security_level = new_sec_level
if("attempt_auth")
if(!ticks_left_locked_down)
var/tried_account_num = text2num(href_list["account_num"])
if(!tried_account_num)
tried_account_num = held_card.associated_account_number
var/tried_pin = text2num(href_list["account_pin"])
authenticated_account = attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
if(!authenticated_account)
number_incorrect_tries++
if(previous_account_number == tried_account_num)
if(number_incorrect_tries > max_pin_attempts)
//lock down the atm
ticks_left_locked_down = 30
playsound(src, 'sound/machines/buzz-two.ogg', 50, 1)
//create an entry in the account transaction log
var/datum/money_account/failed_account = get_account(tried_account_num)
if(failed_account)
var/datum/transaction/T = new()
T.target_name = failed_account.owner_name
T.purpose = "Unauthorised login attempt"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
failed_account.transaction_log.Add(T)
else
usr << "\red \icon[src] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining."
previous_account_number = tried_account_num
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1)
else
usr << "\red \icon[src] incorrect pin/account combination entered."
number_incorrect_tries = 0
else
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
ticks_left_timeout = 120
view_screen = NO_SCREEN
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Remote terminal access"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
usr << "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'"
previous_account_number = tried_account_num
if("withdrawal")
var/amount = max(text2num(href_list["funds_amount"]),0)
if(amount <= 0)
alert("That is not a valid amount.")
else if(authenticated_account && amount > 0)
if(amount <= authenticated_account.money)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
//remove the money
authenticated_account.money -= amount
withdraw_arbitrary_sum(amount)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit withdrawal"
T.amount = "([amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>"
if("balance_statement")
if(authenticated_account)
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "Account balance: [authenticated_account.owner_name]"
R.info = "<b>NT Automated Teller Account Statement</b><br><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Balance:</i> $[authenticated_account.money]<br>"
R.info += "<i>Date and time:</i> [worldtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
if("insert_card")
if(held_card)
held_card.loc = src.loc
authenticated_account = null
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(held_card)
held_card = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
held_card = I
if("logout")
authenticated_account = null
//usr << browse(null,"window=atm")
src.attack_hand(usr)
//create the most effective combination of notes to make up the requested amount
/obj/machinery/atm/proc/withdraw_arbitrary_sum(var/arbitrary_sum)
while(arbitrary_sum >= 1000)
arbitrary_sum -= 1000
new /obj/item/weapon/spacecash/c1000(src)
while(arbitrary_sum >= 500)
arbitrary_sum -= 500
new /obj/item/weapon/spacecash/c500(src)
while(arbitrary_sum >= 200)
arbitrary_sum -= 200
new /obj/item/weapon/spacecash/c200(src)
while(arbitrary_sum >= 100)
arbitrary_sum -= 100
new /obj/item/weapon/spacecash/c100(src)
while(arbitrary_sum >= 50)
arbitrary_sum -= 50
new /obj/item/weapon/spacecash/c50(src)
while(arbitrary_sum >= 20)
arbitrary_sum -= 20
new /obj/item/weapon/spacecash/c20(src)
while(arbitrary_sum >= 10)
arbitrary_sum -= 10
new /obj/item/weapon/spacecash/c10(src)
while(arbitrary_sum >= 1)
arbitrary_sum -= 1
new /obj/item/weapon/spacecash(src)
//stolen wholesale and then edited a bit from newscasters, which are awesome and by Agouri
/obj/machinery/atm/proc/scan_user(mob/living/carbon/human/human_user as mob)
if(!authenticated_account)
if(human_user.wear_id)
var/obj/item/weapon/card/id/I
if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
I = human_user.wear_id
else if(istype(human_user.wear_id, /obj/item/device/pda) )
var/obj/item/device/pda/P = human_user.wear_id
I = P.id
if(I)
authenticated_account = attempt_account_access(I.associated_account_number)
if(authenticated_account)
human_user << "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'"
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Remote terminal access"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)

View File

@@ -0,0 +1,113 @@
/datum/money_account
var/owner_name = ""
var/account_number = 0
var/remote_access_pin = 0
var/money = 0
var/list/transaction_log = list()
var/suspended = 0
var/security_level = 1 //0 - auto-identify from worn ID, require only account number
//1 - require manual login / account number and pin
//2 - require card and manual login
/datum/transaction
var/target_name = ""
var/purpose = ""
var/amount = 0
var/date = ""
var/time = ""
var/source_terminal = ""
/proc/create_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/obj/machinery/account_database/source_db)
//create a new account
var/datum/money_account/M = new()
M.owner_name = new_owner_name
M.remote_access_pin = rand(1111, 111111)
M.money = starting_funds
//create an entry in the account transaction log for when it was created
var/datum/transaction/T = new()
T.target_name = new_owner_name
T.purpose = "Account creation"
T.amount = starting_funds
if(!source_db)
//set a random date, time and location some time over the past few decades
T.date = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 25[rand(10,56)]"
T.time = "[rand(0,24)]:[rand(11,59)]"
T.source_terminal = "NTGalaxyNet Terminal #[rand(111,1111)]"
M.account_number = rand(111111, 999999)
else
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = source_db.machine_id
M.account_number = next_account_number
next_account_number += rand(1,25)
//create a sealed package containing the account details
var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(source_db.loc)
var/obj/item/weapon/paper/R = new /obj/item/weapon/paper(P)
P.wrapped = R
R.name = "Account information: [M.owner_name]"
R.info = "<b>Account details (confidential)</b><br><hr><br>"
R.info += "<i>Account holder:</i> [M.owner_name]<br>"
R.info += "<i>Account number:</i> [M.account_number]<br>"
R.info += "<i>Account pin:</i> [M.remote_access_pin]<br>"
R.info += "<i>Starting balance:</i> $[M.money]<br>"
R.info += "<i>Date and time:</i> [worldtime2text()], [current_date_string]<br><br>"
R.info += "<i>Creation terminal ID:</i> [source_db.machine_id]<br>"
R.info += "<i>Authorised NT officer overseeing creation:</i> [source_db.held_card.registered_name]<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the Accounts Database.</i>"
//add the account
M.transaction_log.Add(T)
all_money_accounts.Add(M)
return M
/proc/charge_to_account(var/attempt_account_number, var/source_name, var/purpose, var/terminal_id, var/amount)
for(var/datum/money_account/D in all_money_accounts)
if(D.account_number == attempt_account_number && !D.suspended)
D.money += amount
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = source_name
T.purpose = purpose
if(amount < 0)
T.amount = "([amount])"
else
T.amount = "[amount]"
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = terminal_id
D.transaction_log.Add(T)
return 1
break
return 0
//this returns the first account datum that matches the supplied accnum/pin combination, it returns null if the combination did not match any account
/proc/attempt_account_access(var/attempt_account_number, var/attempt_pin_number, var/security_level_passed = 0)
for(var/datum/money_account/D in all_money_accounts)
if(D.account_number == attempt_account_number)
if( D.security_level <= security_level_passed && (!D.security_level || D.remote_access_pin == attempt_pin_number) )
return D
break
/proc/get_account(var/account_number)
for(var/datum/money_account/D in all_money_accounts)
if(D.account_number == account_number)
return D

View File

@@ -0,0 +1,169 @@
/obj/machinery/account_database
name = "Accounts uplink console"
desc = "Access transaction logs, account data and all kinds of other financial records."
icon = 'icons/obj/computer.dmi'
icon_state = "aiupload"
density = 1
req_one_access = list(access_hop, access_captain, access_cent_captain)
var/receipt_num
var/machine_id = ""
var/obj/item/weapon/card/id/held_card
var/access_level = 0
var/datum/money_account/detailed_account_view
var/creating_new_account = 0
/obj/machinery/account_database/New()
..()
machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
/obj/machinery/account_database/attack_hand(mob/user as mob)
if(get_dist(src,user) <= 1)
var/dat = "<b>Accounts Database</b><br>"
dat += "<i>[machine_id]</i><br>"
dat += "Confirm identity: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card : "-----"]</a><br>"
if(access_level > 0)
dat += "You may not edit accounts at this terminal, only create and view them.<br>"
if(creating_new_account)
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=view_accounts_list;'>Return to accounts list</a>"
dat += "<form name='create_account' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='finalise_create_account'>"
dat += "<b>Holder name:</b> <input type='text' id='holder_name' name='holder_name' style='width:250px; background-color:white;'><br>"
dat += "<b>Initial funds:</b> <input type='text' id='starting_funds' name='starting_funds' style='width:250px; background-color:white;'> (subtracted from station account)<br>"
dat += "<i>New accounts are automatically assigned a secret number and pin, which are printed separately in a sealed package.</i><br>"
dat += "<input type='submit' value='Create'><br>"
dat += "</form>"
else
if(detailed_account_view)
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=view_accounts_list;'>Return to accounts list</a><hr>"
dat += "<b>Account number:</b> #[detailed_account_view.account_number]<br>"
dat += "<b>Account holder:</b> [detailed_account_view.owner_name]<br>"
dat += "<b>Account balance:</b> $[detailed_account_view.money]<br>"
if(access_level > 1)
dat += "<b><a href='?src=\ref[src];choice=add_funds'>Silently add funds (no transaction log)</a><br>"
dat += "<b><a href='?src=\ref[src];choice=remove_funds'>Silently remove funds (no transaction log)</a><br>"
dat += "<b><a href='?src=\ref[src];choice=toggle_suspension'>[detailed_account_view.suspended ? "Unsuspend account" : "Suspend account"]</a><br>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in detailed_account_view.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
else
dat += "<a href='?src=\ref[src];choice=create_account;'>Create new account</a><br><br>"
dat += "<table border=1 style='width:100%'>"
for(var/i=1, i<=all_money_accounts.len, i++)
var/datum/money_account/D = all_money_accounts[i]
dat += "<tr>"
dat += "<td>#[D.account_number]</td>"
dat += "<td>[D.owner_name]</td>"
dat += "<td>[D.suspended ? "SUSPENDED" : ""]</td>"
dat += "<td><a href='?src=\ref[src];choice=view_account_detail;account_index=[i]'>View in detail</a></td>"
dat += "</tr>"
dat += "</table>"
user << browse(dat,"window=account_db;size=700x650")
else
user << browse(null,"window=account_db")
/obj/machinery/account_database/attackby(O as obj, user as mob)//TODO:SANITY
if(istype(O, /obj/item/weapon/card))
var/obj/item/weapon/card/id/idcard = O
if(!held_card)
usr.drop_item()
idcard.loc = src
held_card = idcard
if(access_cent_captain in idcard.access)
access_level = 2
else if(access_hop in idcard.access || access_captain in idcard.access)
access_level = 1
else
..()
/obj/machinery/account_database/Topic(var/href, var/href_list)
if(href_list["choice"])
switch(href_list["choice"])
if("create_account")
creating_new_account = 1
if("add_funds")
var/amount = input("Enter the amount you wish to add", "Silently add funds") as num
if(detailed_account_view)
detailed_account_view.money += amount
if("remove_funds")
var/amount = input("Enter the amount you wish to remove", "Silently remove funds") as num
if(detailed_account_view)
detailed_account_view.money -= amount
if("toggle_suspension")
if(detailed_account_view)
if(detailed_account_view.suspended)
detailed_account_view.suspended = 0
else
detailed_account_view.suspended = 1
if("finalise_create_account")
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
create_account(account_name, starting_funds, src)
if(starting_funds > 0)
//subtract the money
station_account.money -= starting_funds
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = account_name
T.purpose = "New account funds initialisation"
T.amount = "([starting_funds])"
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = machine_id
station_account.transaction_log.Add(T)
creating_new_account = 0
if("insert_card")
if(held_card)
held_card.loc = src.loc
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(held_card)
held_card = null
access_level = 0
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = I
usr.drop_item()
C.loc = src
held_card = C
if(access_cent_captain in C.access)
access_level = 2
else if(access_hop in C.access || access_captain in C.access)
access_level = 1
if("view_account_detail")
var/index = text2num(href_list["account_index"])
if(index && index <= all_money_accounts.len)
detailed_account_view = all_money_accounts[index]
if("view_accounts_list")
detailed_account_view = null
creating_new_account = 0
src.attack_hand(usr)

View File

@@ -0,0 +1,240 @@
/obj/item/device/eftpos
name = "EFTPOS scanner"
desc = "Swipe your ID card to make purchases electronically."
icon = 'icons/obj/device.dmi'
icon_state = "eftpos"
var/machine_id = ""
var/eftpos_name = "Default EFTPOS scanner"
var/transaction_locked = 0
var/transaction_paid = 0
var/transaction_amount = 0
var/transaction_purpose = "Default charge"
var/access_code = 0
var/datum/money_account/linked_account
/obj/item/device/eftpos/New()
..()
machine_id = "[station_name()] EFTPOS #[num_financial_terminals++]"
access_code = rand(1111,111111)
spawn(0)
print_reference()
//create a short manual as well
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "Steps to success: Correct EFTPOS Usage"
R.info += "<b>When first setting up your EFTPOS device:</b>"
R.info += "1. Memorise your EFTPOS command code (provided with all EFTPOS devices).<br>"
R.info += "2. Confirm that your EFTPOS device is connected to your local accounts database. For additional assistance with this step, contact NanoTrasen IT Support<br>"
R.info += "3. Confirm that your EFTPOS device has been linked to the account that you wish to recieve funds for all transactions processed on this device.<br>"
R.info += "<b>When starting a new transaction with your EFTPOS device:</b>"
R.info += "1. Ensure the device is UNLOCKED so that new data may be entered.<br>"
R.info += "2. Enter a sum of money and reference message for the new transaction.<br>"
R.info += "3. Lock the transaction, it is now ready for your customer.<br>"
R.info += "4. If at this stage you wish to modify or cancel your transaction, you may simply reset (unlock) your EFTPOS device.<br>"
R.info += "5. Give your EFTPOS device to the customer, they must authenticate the transaction by swiping their ID card and entering their PIN number.<br>"
R.info += "6. If done correctly, the transaction will be logged to both accounts with the reference you have entered, the terminal ID of your EFTPOS device and the money transferred across accounts.<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the EFTPOS device.</i>"
//by default, connect to the station account
//the user of the EFTPOS device can change the target account though, and no-one will be the wiser (except whoever's being charged)
linked_account = station_account
/obj/item/device/eftpos/proc/print_reference()
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "Reference: [eftpos_name]"
R.info = "<b>[eftpos_name] reference</b><br><br>"
R.info += "Access code: [access_code]<br><br>"
R.info += "<b>Do not lose or misplace this code.</b><br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the EFTPOS device.</i>"
var/obj/item/smallDelivery/D = new(R.loc)
R.loc = D
D.wrapped = R
D.name = "small parcel - 'EFTPOS access code'"
/obj/item/device/eftpos/attack_self(mob/user as mob)
if(get_dist(src,user) <= 1)
var/dat = "<b>[eftpos_name]</b><br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting NanoTrasen IT Support</i><br>"
if(transaction_locked)
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Reset[transaction_paid ? "" : " (authentication required)"]</a><br><br>"
dat += "Transaction purpose: <b>[transaction_purpose]</b><br>"
dat += "Value: <b>$[transaction_amount]</b><br>"
dat += "Linked account: <b>[linked_account ? linked_account.owner_name : "None"]</b><hr>"
if(transaction_paid)
dat += "<i>This transaction has been processed successfully.</i><hr>"
else
dat += "<i>Swipe your card below the line to finish this transaction.</i><hr>"
dat += "<a href='?src=\ref[src];choice=scan_card'>\[------\]</a>"
else
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Lock in new transaction</a><br><br>"
dat += "Transaction purpose: <a href='?src=\ref[src];choice=trans_purpose'>[transaction_purpose]</a><br>"
dat += "Value: <a href='?src=\ref[src];choice=trans_value'>$[transaction_amount]</a><br>"
dat += "Linked account: <a href='?src=\ref[src];choice=link_account'>[linked_account ? linked_account.owner_name : "None"]</a><hr>"
dat += "<a href='?src=\ref[src];choice=change_code'>Change access code</a><br>"
dat += "<a href='?src=\ref[src];choice=change_id'>Change EFTPOS ID</a><br>"
dat += "Scan card to reset access code <a href='?src=\ref[src];choice=reset'>\[------\]</a>"
user << browse(dat,"window=eftpos")
else
user << browse(null,"window=eftpos")
/obj/item/device/eftpos/attackby(O as obj, user as mob)
if(istype(O, /obj/item/weapon/card))
if(linked_account)
var/obj/item/weapon/card/I = O
scan_card(I)
else
usr << "\icon[src]<span class='warning'>Unable to connect to linked account.</span>"
else
..()
/obj/item/device/eftpos/Topic(var/href, var/href_list)
if(href_list["choice"])
switch(href_list["choice"])
if("change_code")
var/attempt_code = input("Re-enter the current EFTPOS access code", "Confirm old EFTPOS code") as num
if(attempt_code == access_code)
var/trycode = input("Enter a new access code for this device (4-6 digits, numbers only)", "Enter new EFTPOS code") as num
if(trycode >= 1000 && trycode <= 999999)
access_code = trycode
else
alert("That is not a valid code!")
print_reference()
else
usr << "\icon[src]<span class='warning'>Incorrect code entered.</span>"
if("change_id")
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code"))
if(attempt_code == access_code)
eftpos_name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") + " EFTPOS scanner"
print_reference()
else
usr << "\icon[src]<span class='warning'>Incorrect code entered.</span>"
if("link_account")
var/attempt_account_num = input("Enter account number to pay EFTPOS charges into", "New account number") as num
var/attempt_pin = input("Enter pin code", "Account pin") as num
linked_account = attempt_account_access(attempt_account_num, attempt_pin, 1)
if(linked_account.suspended)
linked_account = null
usr << "\icon[src]<span class='warning'>Account has been suspended.</span>"
if("trans_purpose")
transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
if("trans_value")
var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount") as num
if(try_num < 0)
alert("That is not a valid amount!")
else
transaction_amount = try_num
if("toggle_lock")
if(transaction_locked)
var/attempt_code = input("Enter EFTPOS access code", "Reset Transaction") as num
if(attempt_code == access_code)
transaction_locked = 0
transaction_paid = 0
else if(linked_account)
transaction_locked = 1
else
usr << "\icon[src] <span class='warning'>No account connected to send transactions to.</span>"
if("scan_card")
if(linked_account)
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card))
scan_card(I)
else
usr << "\icon[src]<span class='warning'>Unable to link accounts.</span>"
if("reset")
//reset the access code - requires HoP/captain access
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card))
var/obj/item/weapon/card/id/C = I
if(access_cent_captain in C.access || access_hop in C.access || access_captain in C.access)
access_code = 0
usr << "\icon[src]<span class='info'>Access code reset to 0.</span>"
else if (istype(I, /obj/item/weapon/card/emag))
access_code = 0
usr << "\icon[src]<span class='info'>Access code reset to 0.</span>"
src.attack_self(usr)
/obj/item/device/eftpos/proc/scan_card(var/obj/item/weapon/card/I)
if (istype(I, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = I
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
if(transaction_locked && !transaction_paid)
if(linked_account)
if(!linked_account.suspended)
var/attempt_pin = input("Enter pin code", "EFTPOS transaction") as num
var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2)
if(D)
if(!D.suspended)
if(transaction_amount <= D.money)
playsound(src, 'sound/machines/chime.ogg', 50, 1)
src.visible_message("\icon[src] The [src] chimes.")
transaction_paid = 1
//transfer the money
D.money -= transaction_amount
linked_account.money += transaction_amount
//create entries in the two account transaction logs
var/datum/transaction/T = new()
T.target_name = "[linked_account.owner_name] (via [eftpos_name])"
T.purpose = transaction_purpose
if(transaction_amount > 0)
T.amount = "([transaction_amount])"
else
T.amount = "[transaction_amount]"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
D.transaction_log.Add(T)
//
T = new()
T.target_name = D.owner_name
T.purpose = transaction_purpose
T.amount = "[transaction_amount]"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
linked_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>You don't have that much money!</span>"
else
usr << "\icon[src]<span class='warning'>Your account has been suspended.</span>"
else
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
else
usr << "\icon[src]<span class='warning'>Connected account has been suspended.</span>"
else
usr << "\icon[src]<span class='warning'>EFTPOS is not connected to an account.</span>"
else if (istype(I, /obj/item/weapon/card/emag))
if(transaction_locked)
if(transaction_paid)
usr << "\icon[src]<span class='info'>You stealthily swipe [I] through [src].</span>"
transaction_locked = 0
transaction_paid = 0
else
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
playsound(src, 'sound/machines/chime.ogg', 50, 1)
src.visible_message("\icon[src] The [src] chimes.")
transaction_paid = 1
else
..()
//emag?

View File

@@ -0,0 +1,105 @@
/datum/event/economic_event
endWhen = 50 //this will be set randomly, later
announceWhen = 15
var/event_type = 0
var/list/cheaper_goods = list()
var/list/dearer_goods = list()
var/datum/trade_destination/affected_dest
/datum/event/economic_event/start()
affected_dest = pickweight(weighted_randomevent_locations)
if(affected_dest.viable_random_events.len)
endWhen = rand(60,300)
event_type = pick(affected_dest.viable_random_events)
if(!event_type)
return
switch(event_type)
if(RIOTS)
dearer_goods = list(SECURITY)
cheaper_goods = list(MINERALS, FOOD)
if(WILD_ANIMAL_ATTACK)
cheaper_goods = list(ANIMALS)
dearer_goods = list(FOOD, BIOMEDICAL)
if(INDUSTRIAL_ACCIDENT)
dearer_goods = list(EMERGENCY, BIOMEDICAL, ROBOTICS)
if(BIOHAZARD_OUTBREAK)
dearer_goods = list(BIOMEDICAL, GAS)
if(PIRATES)
dearer_goods = list(SECURITY, MINERALS)
if(CORPORATE_ATTACK)
dearer_goods = list(SECURITY, MAINTENANCE)
if(ALIEN_RAIDERS)
dearer_goods = list(BIOMEDICAL, ANIMALS)
cheaper_goods = list(GAS, MINERALS)
if(AI_LIBERATION)
dearer_goods = list(EMERGENCY, GAS, MAINTENANCE)
if(MOURNING)
cheaper_goods = list(MINERALS, MAINTENANCE)
if(CULT_CELL_REVEALED)
dearer_goods = list(SECURITY, BIOMEDICAL, MAINTENANCE)
if(SECURITY_BREACH)
dearer_goods = list(SECURITY)
if(ANIMAL_RIGHTS_RAID)
dearer_goods = list(ANIMALS)
if(FESTIVAL)
dearer_goods = list(FOOD, ANIMALS)
for(var/good_type in dearer_goods)
affected_dest.temp_price_change[good_type] = rand(1,100)
for(var/good_type in cheaper_goods)
affected_dest.temp_price_change[good_type] = rand(1,100) / 100
/datum/event/economic_event/announce()
//copy-pasted from the admin verbs to submit new newscaster messages
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = "Tau Ceti Daily"
newMsg.is_admin_message = 1
//see if our location has custom event info for this event
newMsg.body = affected_dest.get_custom_eventstring()
if(!newMsg.body)
switch(event_type)
if(RIOTS)
newMsg.body = "[pick("Riots have","Unrest has")] broken out on planet [affected_dest.name]. Authorities call for calm, as [pick("various parties","rebellious elements","peacekeeping forces","\'REDACTED\'")] begin stockpiling weaponry and armour. Meanwhile, food and mineral prices are dropping as local industries attempt empty their stocks in expectation of looting."
if(WILD_ANIMAL_ATTACK)
newMsg.body = "Local [pick("wildlife","animal life","fauna")] on planet [affected_dest.name] has been increasing in agression and raiding outlying settlements for food. Big game hunters have been called in to help alleviate the problem, but numerous injuries have already occurred."
if(INDUSTRIAL_ACCIDENT)
newMsg.body = "[pick("An industrial accident","A smelting accident","A malfunction","A malfunctioning piece of machinery","Negligent maintenance","A cooleant leak","A ruptured conduit")] at a [pick("factory","installation","power plant","dockyards")] on [affected_dest.name] resulted in severe structural damage and numerous injuries. Repairs are ongoing."
if(BIOHAZARD_OUTBREAK)
newMsg.body = "[pick("A \'REDACTED\'","A biohazard","An outbreak","A virus")] on [affected_dest.name] has resulted in quarantine, stopping much shipping in the area. Although the quarantine is now lifted, authorities are calling for deliveries of medical supplies to treat the infected, and gas to replace contaminated stocks."
if(PIRATES)
newMsg.body = "[pick("Pirates","Criminal elements","A [pick("Syndicate","Donk Co.","Waffle Co.","\'REDACTED\'")] strike force")] have [pick("raided","blockaded","attempted to blackmail","attacked")] [affected_dest.name] today. Security has been tightened, but many valuable minerals were taken."
if(CORPORATE_ATTACK)
newMsg.body = "A small [pick("pirate","Cybersun Industries","Gorlex Marauders","Syndicate")] fleet has precise-jumped into proximity with [affected_dest.name], [pick("for a smash-and-grab operation","in a hit and run attack","in an overt display of hostilities")]. Much damage was done, and security has been tightened since the incident."
if(ALIEN_RAIDERS)
if(prob(20))
newMsg.body = "The Tiger Co-operative have raided [affected_dest.name] today, no doubt on orders from their enigmatic masters. Stealing wildlife, farm animals, medical research materials and kidnapping civilians. NanoTrasen authorities are standing by to counter attempts at bio-terrorism."
else
newMsg.body = "[pick("The alien species designated \'United Exolitics\'","The alien species designated \'REDACTED\'","An unknown alien species")] have raided [affected_dest.name] today, stealing wildlife, farm animals, medical research materials and kidnapping civilians. It seems they desire to learn more about us, so the Navy will be standing by to accomodate them next time they try."
if(AI_LIBERATION)
newMsg.body = "A [pick("\'REDACTED\' was detected on","S.E.L.F operative infiltrated","malignant computer virus was detected on","rogue [pick("slicer","hacker")] was apprehended on")] [affected_dest.name] today, and managed to infect [pick("\'REDACTED\'","a sentient sub-system","a class one AI","a sentient defence installation")] before it could be stopped. Many lives were lost as it systematically begin murdering civilians, and considerable work must be done to repair the affected areas."
if(MOURNING)
newMsg.body = "[pick("The popular","The well-liked","The eminent","The well-known")] [pick("professor","entertainer","singer","researcher","public servant","administrator","ship captain","\'REDACTED\'")], [pick( random_name(pick(MALE,FEMALE)), 40; "\'REDACTED\'" )] has [pick("passed away","committed suicide","been murdered","died in a freakish accident")] on [affected_dest.name] today. The entire planet is in mourning, and prices have dropped for industrial goods as worker morale drops."
if(CULT_CELL_REVEALED)
newMsg.body = "A [pick("dastardly","blood-thirsty","villanous","crazed")] cult of [pick("The Elder Gods","Nar'sie","an apocalyptic sect","\'REDACTED\'")] has [pick("been discovered","been revealed","revealed themselves","gone public")] on [affected_dest.name] earlier today. Public morale has been shaken due to [pick("certain","several","one or two")] [pick("high-profile","well known","popular")] individuals [pick("performing \'REDACTED\' acts","claiming allegiance to the cult","swearing loyalty to the cult leader","promising to aid to the cult")] before those involved could be brought to justice. The editor reminds all personnel that supernatural myths will not be tolerated on NanoTrasen facilities."
if(SECURITY_BREACH)
newMsg.body = "There was [pick("a security breach in","an unauthorised access in","an attempted theft in","an anarchist attack in","violent sabotage of")] a [pick("high-security","restricted access","classified","\'REDACTED\'")] [pick("\'REDACTED\'","section","zone","area")] this morning. Security was tightened on [affected_dest.name] after the incident, and the editor reassures all NanoTrasen personnel that such lapses are rare."
if(ANIMAL_RIGHTS_RAID)
newMsg.body = "[pick("Militant animal rights activists","Members of the terrorist group Animal Rights Consortium","Members of the terrorist group \'REDACTED\'")] have [pick("launched a campaign of terror","unleashed a swathe of destruction","raided farms and pastures","forced entry to \'REDACTED\'")] on [affected_dest.name] earlier today, freeing numerous [pick("farm animals","animals","\'REDACTED\'")]. Prices for tame and breeding animals have spiked as a result."
if(FESTIVAL)
newMsg.body = "A [pick("festival","week long celebration","day of revelry","planet-wide holiday")] has been declared on [affected_dest.name] by [pick("Governor","Commissioner","General","Commandant","Administrator")] [random_name(pick(MALE,FEMALE))] to celebrate [pick("the birth of their [pick("son","daughter")]","coming of age of their [pick("son","daughter")]","the pacification of rogue military cell","the apprehension of a violent criminal who had been terrorising the planet")]. Massive stocks of food and meat have been bought driving up prices across the planet."
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "Tau Ceti Daily")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("Tau Ceti Daily")
/datum/event/economic_event/end()
for(var/good_type in dearer_goods)
affected_dest.temp_price_change[good_type] = 1
for(var/good_type in cheaper_goods)
affected_dest.temp_price_change[good_type] = 1

View File

@@ -0,0 +1,233 @@
/datum/event/mundane_news
endWhen = 10
/datum/event/mundane_news/announce()
var/datum/trade_destination/affected_dest = pickweight(weighted_mundaneevent_locations)
var/event_type = 0
if(affected_dest.viable_mundane_events.len)
event_type = pick(affected_dest.viable_mundane_events)
if(!event_type)
return
//copy-pasted from the admin verbs to submit new newscaster messages
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = "Tau Ceti Daily"
newMsg.is_admin_message = 1
//see if our location has custom event info for this event
newMsg.body = affected_dest.get_custom_eventstring()
if(!newMsg.body)
newMsg.body = ""
switch(event_type)
if(RESEARCH_BREAKTHROUGH)
newMsg.body = "A major breakthough in the field of [pick("plasma research","super-compressed materials","nano-augmentation","bluespace research","volatile power manipulation")] \
was announced [pick("yesterday","a few days ago","last week","earlier this month")] by a private firm on [affected_dest.name]. \
NanoTrasen declined to comment as to whether this could impinge on profits."
if(ELECTION)
newMsg.body = "The pre-selection of an additional candidates was announced for the upcoming [pick("supervisors council","advisory board","governership","board of inquisitors")] \
election on [affected_dest.name] was announced earlier today, \
[pick("media mogul","web celebrity", "industry titan", "superstar", "famed chef", "popular gardener", "ex-army officer", "multi-billionaire")] \
[random_name(pick(MALE,FEMALE))]. In a statement to the media they said '[pick("My only goal is to help the [pick("sick","poor","children")]",\
"I will maintain NanoTrasen's record profits","I believe in our future","We must return to our moral core","Just like... chill out dudes")]'."
if(RESIGNATION)
newMsg.body = "NanoTrasen regretfully announces the resignation of [pick("Sector Admiral","Division Admiral","Ship Admiral","Vice Admiral")] [random_name(pick(MALE,FEMALE))]."
if(prob(25))
var/locstring = pick("Segunda","Salusa","Cepheus","Andromeda","Gruis","Corona","Aquila","Asellus") + " " + pick("I","II","III","IV","V","VI","VII","VIII")
newMsg.body += " In a ceremony on [affected_dest.name] this afternoon, they will be awarded the \
[pick("Red Star of Sacrifice","Purple Heart of Heroism","Blue Eagle of Loyalty","Green Lion of Ingenuity")] for "
if(prob(33))
newMsg.body += "their actions at the Battle of [pick(locstring,"REDACTED")]."
else if(prob(50))
newMsg.body += "their contribution to the colony of [locstring]."
else
newMsg.body += "their loyal service over the years."
else if(prob(33))
newMsg.body += " They are expected to settle down in [affected_dest.name], where they have been granted a handsome pension."
else if(prob(50))
newMsg.body += " The news was broken on [affected_dest.name] earlier today, where they cited reasons of '[pick("health","family","REDACTED")]'"
else
newMsg.body += " Administration Aerospace wishes them the best of luck in their retirement ceremony on [affected_dest.name]."
if(CELEBRITY_DEATH)
newMsg.body = "It is with regret today that we announce the sudden passing of the "
if(prob(33))
newMsg.body += "[pick("distinguished","decorated","veteran","highly respected")] \
[pick("Ship's Captain","Vice Admiral","Colonel","Lieutenant Colonel")] "
else if(prob(50))
newMsg.body += "[pick("award-winning","popular","highly respected","trend-setting")] \
[pick("comedian","singer/songwright","artist","playwright","TV personality","model")] "
else
newMsg.body += "[pick("successful","highly respected","ingenious","esteemed")] \
[pick("academic","Professor","Doctor","Scientist")] "
newMsg.body += "[random_name(pick(MALE,FEMALE))] on [affected_dest.name] [pick("last week","yesterday","this morning","two days ago","three days ago")]\
[pick(". Assassination is suspected, but the perpetrators have not yet been brought to justice",\
" due to Syndicate infiltrators (since captured)",\
" during an industrial accident",\
" due to [pick("heart failure","kidney failure","liver failure","brain hemorrhage")]")]"
if(BARGAINS)
newMsg.body += "BARGAINS! BARGAINS! BARGAINS! Commerce Control on [affected_dest.name] wants you to know that everything must go! Across all retail centres, \
all goods are being slashed, and all retailors are onboard - so come on over for the \[shopping\] time of your life."
if(SONG_DEBUT)
newMsg.body += "[pick("Singer","Singer/songwriter","Saxophonist","Pianist","Guitarist","TV personality","Star")] [random_name(pick(MALE,FEMALE))] \
announced the debut of their new [pick("single","album","EP","label")] '[pick("Everyone's","Look at the","Baby don't eye those","All of those","Dirty nasty")] \
[pick("roses","three stars","starships","nanobots","cyborgs","Skrell","Sren'darr")] \
[pick("on Venus","on Reade","on Moghes","in my hand","slip through my fingers","die for you","sing your heart out","fly away")]' \
with [pick("pre-puchases available","a release tour","cover signings","a launch concert")] on [affected_dest.name]."
if(MOVIE_RELEASE)
newMsg.body += "From the [pick("desk","home town","homeworld","mind")] of [pick("acclaimed","award-winning","popular","stellar")] \
[pick("playwright","author","director","actor","TV star")] [random_name(pick(MALE,FEMALE))] comes the latest sensation: '\
[pick("Deadly","The last","Lost","Dead")] [pick("Starships","Warriors","outcasts","Tajarans","Unathi","Skrell")] \
[pick("of","from","raid","go hunting on","visit","ravage","pillage","destroy")] \
[pick("Moghes","Earth","Biesel","Ahdomai","S'randarr","the Void","the Edge of Space")]'.\
. Own it on webcast today, or visit the galactic premier on [affected_dest.name]!"
if(BIG_GAME_HUNTERS)
newMsg.body += "Game hunters on [affected_dest.name] "
if(prob(33))
newMsg.body += "were surprised when an unusual species experts have since identified as \
[pick("a subclass of mammal","a divergent abhuman species","an intelligent species of lemur","organic/cyborg hybrids")] turned up. Believed to have been brought in by \
[pick("alien smugglers","early colonists","syndicate raiders","unwitting tourists")], this is the first such specimen discovered in the wild."
else if(prob(50))
newMsg.body += "were attacked by a vicious [pick("nas'r","diyaab","samak","predator which has not yet been identified")]\
. Officials urge caution, and locals are advised to stock up on armaments."
else
newMsg.body += "brought in an unusually [pick("valuable","rare","large","vicious","intelligent")] [pick("mammal","predator","farwa","samak")] for inspection \
[pick("today","yesterday","last week")]. Speculators suggest they may be tipped to break several records."
if(GOSSIP)
newMsg.body += "[pick("TV host","Webcast personality","Superstar","Model","Actor","Singer")] [random_name(pick(MALE,FEMALE))] "
if(prob(33))
newMsg.body += "and their partner announced the birth of their [pick("first","second","third")] child on [affected_dest.name] early this morning. \
Doctors say the child is well, and the parents are considering "
if(prob(50))
newMsg.body += capitalize(pick(first_names_female))
else
newMsg.body += capitalize(pick(first_names_male))
newMsg.body += " for the name."
else if(prob(50))
newMsg.body += "announced their [pick("split","break up","marriage","engagement")] with [pick("TV host","webcast personality","superstar","model","actor","singer")] \
[random_name(pick(MALE,FEMALE))] at [pick("a society ball","a new opening","a launch","a club")] on [affected_dest.name] yesterday, pundits are shocked."
else
newMsg.body += "is recovering from plastic surgery in a clinic on [affected_dest.name] for the [pick("second","third","fourth")] time, reportedly having made the decision in response to "
newMsg.body += "[pick("unkind comments by an ex","rumours started by jealous friends",\
"the decision to be dropped by a major sponsor","a disasterous interview on Tau Ceti Tonight")]."
if(TOURISM)
newMsg.body += "Tourists are flocking to [affected_dest.name] after the surprise announcement of [pick("major shopping bargains by a wily retailer",\
"a huge new ARG by a popular entertainment company","a secret tour by popular artiste [random_name(pick(MALE,FEMALE))]")]. \
Tau Ceti Daily is offering discount tickets for two to see [random_name(pick(MALE,FEMALE))] live in return for eyewitness reports and up to the minute coverage."
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "Tau Ceti Daily")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("Tau Ceti Daily")
/datum/event/trivial_news
endWhen = 10
/datum/event/trivial_news/announce()
//copy-pasted from the admin verbs to submit new newscaster messages
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = "Editor Mike Hammers"
//newMsg.is_admin_message = 1
var/datum/trade_destination/affected_dest = pick(weighted_mundaneevent_locations)
newMsg.body = pick(
"Tree stuck in tajaran; firefighters baffled.",\
"Armadillos want aardvarks removed from dictionary claims 'here first'.",\
"Angel found dancing on pinhead ordered to stop; cited for public nuisance.",\
"Letters claim they are better than number; 'Always have been'.",\
"Pens proclaim pencils obsolete, 'lead is dead'.",\
"Rock and paper sues scissors for discrimination.",\
"Steak tell-all book reveals he never liked sitting by potato.",\
"Woodchuck stops counting how many times he<68>s chucked 'Never again'.",\
"[affected_dest.name] clerk first person able to pronounce '@*$%!'.",\
"[affected_dest.name] delis serving boiled paperback dictionaries, 'Adjectives chewy' customers declare.",\
"[affected_dest.name] weather deemed 'boring'; meteors and rad storms to be imported.",\
"Most [affected_dest.name] security officers prefer cream over sugar.",\
"Palindrome speakers conference in [affected_dest.name]; 'Wow!' says Otto.",\
"Question mark worshipped as deity by ancient [affected_dest.name] dwellers.",\
"Spilled milk causes whole [affected_dest.name] populace to cry.",\
"World largest carp patty at display on [affected_dest.name].",\
"'Here kitty kitty' no longer preferred tajaran retrieval technique.",\
"Man travels 7000 light years to retrieve lost hankie, 'It was my favourite'.",\
"New bowling lane that shoots mini-meteors at bowlers very popular.",\
"[pick("Unathi","Spacer")] gets tattoo of Tau Ceti on chest '[pick("CentComm","star","starship","asteroid")] tickles most'.",\
"Skrell marries computer; wedding attended by 100 modems.",\
"Chef reports successfully using harmonica as cheese grater.",\
"NanoTrasen invents handkerchief that says 'Bless you' after sneeze.",\
"Clone accused of posing for other clones<65>s school photo.",\
"Clone accused of stealing other clones<65>s employee of the month award.",\
"Woman robs station with hair dryer; crewmen love new style.",\
"This space for rent.",\
"[affected_dest.name] Baker Wins Pickled Crumpet Toss Three Years Running",\
"Skrell Scientist Discovers Abacus Can Be Used To Dry Towels",\
"Survey: 'Cheese Louise' Voted Best Pizza Restaurant In Tau Ceti",\
"I Was Framed, jokes [affected_dest.name] artist",\
"Mysterious Loud Rumbling Noises In [affected_dest.name] Found To Be Mysterious Loud Rumblings",\
"Alien ambassador becomes lost on [affected_dest.name], refuses to ask for directions",\
"Swamp Gas Verified To Be Exhalations Of Stars--Movie Stars--Long Passed",\
"Tainted Broccoli Weapon Of Choice For Syndicate Assassins",\
"Chefs Find Broccoli Effective Tool For Cutting Cheese",\
"Broccoli Found To Cause Grumpiness In Monkeys",\
"Survey: 80% Of People on [affected_dest.name] Love Clog-Dancing",\
"Giant Hairball Has Perfect Grammar But Rolls rr's Too Much, Linguists Say",\
"[affected_dest.name] Phonebooks Print All Wrong Numbers; Results In 15 New Marriages",\
"Tajaran Burglar Spotted on [affected_dest.name], Mistaken For Dalmatian",\
"Gibson Gazette Updates Frequently Absurd, Poll Indicates",\
"Esoteric Verbosity Culminates In Communicative Ennui, [affected_dest.name] Academics Note",\
"Taj Demand Longer Breaks, Cleaner Litter, Slower Mice",\
"Survey: 3 Out Of 5 Skrell Loathe Modern Art",\
"Skrell Scientist Discovers Gravity While Falling Down Stairs",\
"Boy Saves Tajaran From Tree on [affected_dest.name], Thousands Cheer",\
"Shipment Of Apples Overturns, [affected_dest.name] Diner Offers Applesauce Special",\
"Spotted Owl Spotted on [affected_dest.name]",\
"Humans Everywhere Agree: Purring Tajarans Are Happy Tajarans",\
"From The Desk Of Wise Guy Sammy: One Word In This Gazette Is Sdrawkcab",\
"From The Desk Of Wise Guy Sammy: It's Hard To Have Too Much Shelf Space",\
"From The Desk Of Wise Guy Sammy: Wine And Friendships Get Better With Age",\
"From The Desk Of Wise Guy Sammy: The Insides Of Golf Balls Are Mostly Rubber Bands",\
"From The Desk Of Wise Guy Sammy: You Don't Have To Fool All The People, Just The Right Ones",\
"From The Desk Of Wise Guy Sammy: If You Made The Mess, You Clean It Up",\
"From The Desk Of Wise Guy Sammy: It Is Easier To Get Forgiveness Than Permission",\
"From The Desk Of Wise Guy Sammy: Check Your Facts Before Making A Fool Of Yourself",\
"From The Desk Of Wise Guy Sammy: You Can't Outwait A Bureaucracy",\
"From The Desk Of Wise Guy Sammy: It's Better To Yield Right Of Way Than To Demand It",\
"From The Desk Of Wise Guy Sammy: A Person Who Likes Cats Can't Be All Bad",\
"From The Desk Of Wise Guy Sammy: Help Is The Sunny Side Of Control",\
"From The Desk Of Wise Guy Sammy: Two Points Determine A Straight Line",\
"From The Desk Of Wise Guy Sammy: Reading Improves The Mind And Lifts The Spirit",\
"From The Desk Of Wise Guy Sammy: Better To Aim High And Miss Then To Aim Low And Hit",\
"From The Desk Of Wise Guy Sammy: Meteors Often Strike The Same Place More Than Once",\
"Tommy B. Saif Sez: Look Both Ways Before Boarding The Shuttle",\
"Tommy B. Saif Sez: Hold On; Sudden Stops Sometimes Necessary",\
"Tommy B. Saif Sez: Keep Fingers Away From Moving Panels",\
"Tommy B. Saif Sez: No Left Turn, Except Shuttles",\
"Tommy B. Saif Sez: Return Seats And Trays To Their Proper Upright Position",\
"Tommy B. Saif Sez: Eating And Drinking In Docking Bays Is Prohibited",\
"Tommy B. Saif Sez: Accept No Substitutes, And Don't Be Fooled By Imitations",\
"Tommy B. Saif Sez: Do Not Remove This Tag Under Penalty Of Law",\
"Tommy B. Saif Sez: Always Mix Thoroughly When So Instructed",\
"Tommy B. Saif Sez: Try To Keep Six Month's Expenses In Reserve",\
"Tommy B. Saif Sez: Change Not Given Without Purchase",\
"Tommy B. Saif Sez: If You Break It, You Buy It",\
"Tommy B. Saif Sez: Reservations Must Be Cancelled 48 Hours Prior To Event To Obtain Refund",\
"Doughnuts: Is There Anything They Can't Do",\
"If Tin Whistles Are Made Of Tin, What Do They Make Foghorns Out Of?",\
"Broccoli discovered to be colonies of tiny aliens with murder on their minds"\
)
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "The Gibson Gazette")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("The Gibson Gazette")

View File

@@ -0,0 +1,70 @@
var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian")
// The department the job belongs to.
/datum/job/var/department = null
// Whether this is a head position
/datum/job/var/head_position = 0
/datum/job/captain/department = "Command"
/datum/job/captain/head_position = 1
/datum/job/hop/department = "Civilian"
/datum/job/hop/head_position = 1
/datum/job/assistant/department = "Civilian"
/datum/job/bartender/department = "Civilian"
/datum/job/chef/department = "Civilian"
/datum/job/hydro/department = "Civilian"
/datum/job/mining/department = "Civilian"
/datum/job/janitor/department = "Civilian"
/datum/job/librarian/department = "Civilian"
/datum/job/lawyer/department = "Civilian"
/datum/job/chaplain/department = "Civilian"
/datum/job/qm/department = "Cargo"
/datum/job/qm/head_position = 1
/datum/job/cargo_tech/department = "Cargo"
/datum/job/chief_engineer/department = "Engineering"
/datum/job/chief_engineer/head_position = 1
/datum/job/engineer/department = "Engineering"
/datum/job/atmos/department = "Engineering"
/datum/job/cmo/department = "Medical"
/datum/job/cmo/head_position = 1
/datum/job/doctor/department = "Medical"
/datum/job/chemist/department = "Medical"
/datum/job/geneticist/department = "Medical"
/datum/job/psychiatrist/department = "Medical"
/datum/job/rd/department = "Science"
/datum/job/rd/head_position = 1
/datum/job/scientist/department = "Science"
/datum/job/roboticist/department = "Science"
/datum/job/hos/department = "Security"
/datum/job/hos/head_position = 1
/datum/job/warden/department = "Security"
/datum/job/detective/department = "Security"
/datum/job/officer/department = "Security"

View File

@@ -0,0 +1,156 @@
#define RIOTS 1
#define WILD_ANIMAL_ATTACK 2
#define INDUSTRIAL_ACCIDENT 3
#define BIOHAZARD_OUTBREAK 4
#define WARSHIPS_ARRIVE 5
#define PIRATES 6
#define CORPORATE_ATTACK 7
#define ALIEN_RAIDERS 8
#define AI_LIBERATION 9
#define MOURNING 10
#define CULT_CELL_REVEALED 11
#define SECURITY_BREACH 12
#define ANIMAL_RIGHTS_RAID 13
#define FESTIVAL 14
#define RESEARCH_BREAKTHROUGH 15
#define BARGAINS 16
#define SONG_DEBUT 17
#define MOVIE_RELEASE 18
#define BIG_GAME_HUNTERS 19
#define ELECTION 20
#define GOSSIP 21
#define TOURISM 22
#define CELEBRITY_DEATH 23
#define RESIGNATION 24
#define DEFAULT 1
#define ADMINISTRATIVE 2
#define CLOTHING 3
#define SECURITY 4
#define SPECIAL_SECURITY 5
#define FOOD 6
#define ANIMALS 7
#define MINERALS 8
#define EMERGENCY 9
#define GAS 10
#define MAINTENANCE 11
#define ELECTRICAL 12
#define ROBOTICS 13
#define BIOMEDICAL 14
#define GEAR_EVA 15
//---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel:
//Corporation NanoTrasen - Generalised / high tech research and plasma exploitation.
//Corporation Vessel Contracting - Ship and station construction, materials research.
//Corporation Osiris Atmospherics - Atmospherics machinery construction and chemical research.
//Corporation Second Red Cross Society - 26th century Red Cross reborn as a dominating economic force in biomedical science (research and materials).
//Corporation Blue Industries - High tech and high energy research, in particular into the mysteries of bluespace manipulation and power generation.
//Corporation Kusanagi Robotics - Founded by robotics legend Kaito Kusanagi in the 2070s, they have been on the forefront of mechanical augmentation and robotics development ever since.
//Corporation Free traders - Not so much a corporation as a loose coalition of spacers, Free Traders are a roving band of smugglers, traders and fringe elements following a rigid (if informal) code of loyalty and honour. Mistrusted by most corporations, they are tolerated because of their uncanny ability to smell out a profit.
//---- Descriptions of destination types
//Space stations can be purpose built for a number of different things, but generally require regular shipments of essential supplies.
//Corvettes are small, fast warships generally assigned to border patrol or chasing down smugglers.
//Battleships are large, heavy cruisers designed for slugging it out with other heavies or razing planets.
//Yachts are fast civilian craft, often used for pleasure or smuggling.
//Destroyers are medium sized vessels, often used for escorting larger ships but able to go toe-to-toe with them if need be.
//Frigates are medium sized vessels, often used for escorting larger ships. They will rapidly find themselves outclassed if forced to face heavy warships head on.
var/global/current_date_string
var/global/datum/money_account/vendor_account
var/global/datum/money_account/station_account
var/global/list/datum/money_account/department_accounts = list()
var/global/num_financial_terminals = 1
var/global/next_account_number = 0
var/global/list/all_money_accounts = list()
var/global/economy_init = 0
/proc/setup_economy()
if(economy_init)
return 2
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = "Tau Ceti Daily"
newChannel.author = "CentComm Minister of Information"
newChannel.locked = 1
newChannel.is_admin_channel = 1
news_network.network_channels += newChannel
newChannel = new /datum/feed_channel
newChannel.channel_name = "The Gibson Gazette"
newChannel.author = "Editor Mike Hammers"
newChannel.locked = 1
newChannel.is_admin_channel = 1
news_network.network_channels += newChannel
for(var/loc_type in typesof(/datum/trade_destination) - /datum/trade_destination)
var/datum/trade_destination/D = new loc_type
weighted_randomevent_locations[D] = D.viable_random_events.len
weighted_mundaneevent_locations[D] = D.viable_mundane_events.len
create_station_account()
for(var/department in station_departments)
create_department_account(department)
create_department_account("Vendor")
vendor_account = department_accounts["Vendor"]
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
economy_init = 1
return 1
/proc/create_station_account()
if(!station_account)
next_account_number = rand(111111, 999999)
station_account = new()
station_account.owner_name = "[station_name()] Station Account"
station_account.account_number = rand(111111, 999999)
station_account.remote_access_pin = rand(1111, 111111)
station_account.money = 75000
//create an entry in the account transaction log for when it was created
var/datum/transaction/T = new()
T.target_name = station_account.owner_name
T.purpose = "Account creation"
T.amount = 75000
T.date = "2nd April, 2555"
T.time = "11:24"
T.source_terminal = "Biesel GalaxyNet Terminal #277"
//add the account
station_account.transaction_log.Add(T)
all_money_accounts.Add(station_account)
/proc/create_department_account(department)
next_account_number = rand(111111, 999999)
var/datum/money_account/department_account = new()
department_account.owner_name = "[department] Account"
department_account.account_number = rand(111111, 999999)
department_account.remote_access_pin = rand(1111, 111111)
department_account.money = 5000
//create an entry in the account transaction log for when it was created
var/datum/transaction/T = new()
T.target_name = department_account.owner_name
T.purpose = "Account creation"
T.amount = department_account.money
T.date = "2nd April, 2555"
T.time = "11:24"
T.source_terminal = "Biesel GalaxyNet Terminal #277"
//add the account
department_account.transaction_log.Add(T)
all_money_accounts.Add(department_account)
department_accounts[department] = department_account

View File

@@ -0,0 +1,110 @@
var/list/weighted_randomevent_locations = list()
var/list/weighted_mundaneevent_locations = list()
/datum/trade_destination
var/name = ""
var/description = ""
var/distance = 0
var/list/willing_to_buy = list()
var/list/willing_to_sell = list()
var/can_shuttle_here = 0 //one day crew from the exodus will be able to travel to this destination
var/list/viable_random_events = list()
var/list/temp_price_change[BIOMEDICAL]
var/list/viable_mundane_events = list()
/datum/trade_destination/proc/get_custom_eventstring(var/event_type)
return null
//distance is measured in AU and co-relates to travel time
/datum/trade_destination/centcomm
name = "CentComm"
description = "NanoTrasen's administrative centre for Tau Ceti."
distance = 1.2
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(SECURITY_BREACH, CORPORATE_ATTACK, AI_LIBERATION)
viable_mundane_events = list(ELECTION, RESIGNATION, CELEBRITY_DEATH)
/datum/trade_destination/anansi
name = "NSS Anansi"
description = "Medical station ran by Second Red Cross (but owned by NT) for handling emergency cases from nearby colonies."
distance = 1.7
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(SECURITY_BREACH, CULT_CELL_REVEALED, BIOHAZARD_OUTBREAK, PIRATES, ALIEN_RAIDERS)
viable_mundane_events = list(RESEARCH_BREAKTHROUGH, RESEARCH_BREAKTHROUGH, BARGAINS, GOSSIP)
/datum/trade_destination/anansi/get_custom_eventstring(var/event_type)
if(event_type == RESEARCH_BREAKTHROUGH)
return "Thanks to research conducted on the NSS Anansi, Second Red Cross Society wishes to announce a major breakthough in the field of \
[pick("mind-machine interfacing","neuroscience","nano-augmentation","genetics")]. NanoTrasen is expected to announce a co-exploitation deal within the fortnight."
return null
/datum/trade_destination/icarus
name = "NMV Icarus"
description = "Corvette assigned to patrol NSS Exodus local space."
distance = 0.1
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(SECURITY_BREACH, AI_LIBERATION, PIRATES)
/datum/trade_destination/redolant
name = "OAV Redolant"
description = "Osiris Atmospherics station in orbit around the only gas giant insystem. They retain tight control over shipping rights, and Osiris warships protecting their prize are not an uncommon sight in Tau Ceti."
distance = 0.6
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(INDUSTRIAL_ACCIDENT, PIRATES, CORPORATE_ATTACK)
viable_mundane_events = list(RESEARCH_BREAKTHROUGH, RESEARCH_BREAKTHROUGH)
/datum/trade_destination/redolant/get_custom_eventstring(var/event_type)
if(event_type == RESEARCH_BREAKTHROUGH)
return "Thanks to research conducted on the OAV Redolant, Osiris Atmospherics wishes to announce a major breakthough in the field of \
[pick("plasma research","high energy flux capacitance","super-compressed materials","theoretical particle physics")]. NanoTrasen is expected to announce a co-exploitation deal within the fortnight."
return null
/datum/trade_destination/beltway
name = "Beltway mining chain"
description = "A co-operative effort between Beltway and NanoTrasen to exploit the rich outer asteroid belt of the Tau Ceti system."
distance = 7.5
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(PIRATES, INDUSTRIAL_ACCIDENT)
viable_mundane_events = list(TOURISM)
/datum/trade_destination/biesel
name = "Biesel"
description = "Large ship yards, strong economy and a stable, well-educated populace, Biesel largely owes allegiance to Sol / Vessel Contracting and begrudgingly tolerates NT. Capital is Lowell City."
distance = 2.3
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(RIOTS, INDUSTRIAL_ACCIDENT, BIOHAZARD_OUTBREAK, CULT_CELL_REVEALED, FESTIVAL, MOURNING)
viable_mundane_events = list(BARGAINS, GOSSIP, SONG_DEBUT, MOVIE_RELEASE, ELECTION, TOURISM, RESIGNATION, CELEBRITY_DEATH)
/datum/trade_destination/new_gibson
name = "New Gibson"
description = "Heavily industrialised rocky planet containing the majority of the planet-bound resources in the system, New Gibson is torn by unrest and has very little wealth to call it's own except in the hands of the corporations who jostle with NT for control."
distance = 6.6
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(RIOTS, INDUSTRIAL_ACCIDENT, BIOHAZARD_OUTBREAK, CULT_CELL_REVEALED, FESTIVAL, MOURNING)
viable_mundane_events = list(ELECTION, TOURISM, RESIGNATION)
/datum/trade_destination/luthien
name = "Luthien"
description = "A small colony established on a feral, untamed world (largely jungle). Savages and wild beasts attack the outpost regularly, although NT maintains tight military control."
distance = 8.9
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(WILD_ANIMAL_ATTACK, CULT_CELL_REVEALED, FESTIVAL, MOURNING, ANIMAL_RIGHTS_RAID, ALIEN_RAIDERS)
viable_mundane_events = list(ELECTION, TOURISM, BIG_GAME_HUNTERS, RESIGNATION)
/datum/trade_destination/reade
name = "Reade"
description = "A cold, metal-deficient world, NT maintains large pastures in whatever available space in an attempt to salvage something from this profitless colony."
distance = 7.5
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(WILD_ANIMAL_ATTACK, CULT_CELL_REVEALED, FESTIVAL, MOURNING, ANIMAL_RIGHTS_RAID, ALIEN_RAIDERS)
viable_mundane_events = list(ELECTION, TOURISM, BIG_GAME_HUNTERS, RESIGNATION)

View File

@@ -1,35 +1,22 @@
/var/global/account_hack_attempted = 0
/datum/event/money_hacker
endWhen = 10000
var/time_duration = 0
var/time_start = 0
var/datum/money_account/affected_account
var/obj/machinery/account_database/affected_db
endWhen = 100
var/end_time
/datum/event/money_hacker/setup()
end_time = world.time + 6000
if(all_money_accounts.len)
for(var/obj/machinery/account_database/DB in world)
if( DB.z == 1 && !(DB.stat&NOPOWER) && DB.activated )
affected_db = DB
break
if(affected_db)
affected_account = pick(all_money_accounts)
account_hack_attempted = 1
else
kill()
return
time_start = world.time
time_duration = rand(3000, 18000)
endWhen = time_duration * 10 //a big enough buffer so that we should timeout before we run out of ticks
account_hack_attempted = 1
/datum/event/money_hacker/start()
return
/datum/event/money_hacker/announce()
var/message = "A brute force hack has been detected (in progress since [worldtime2text()]). The target of the attack is: Financial account #[affected_account.account_number], \
without intervention this attack will succeed in [time_duration / 600] minutes. Required intervention: complete shutdown of affected accounts databases until the attack has ceased. \
without intervention this attack will succeed in approximately 10 minutes. Required intervention: temporary suspension of affected accounts until the attack has ceased. \
Notifications will be sent as updates occur.<br>"
var/my_department = "[station_name()] firewall subroutines"
var/sending = message + "<font color='blue'><b>Message dispatched by [my_department].</b></font>"
@@ -58,64 +45,62 @@
Console.messages += "<B><FONT color='red'>High Priority message from [my_department]</FONT></B><BR>[sending]"
/datum/event/money_hacker/tick()
if(world.time > time_start + time_duration)
var/message
if(affected_account && affected_db && affected_db.activated && !(affected_db.stat & (NOPOWER|BROKEN)) )
//hacker wins
message = "The hack attempt has succeeded."
if(world.time >= end_time)
endWhen = activeFor
else
endWhen = activeFor + 10
//subtract the money
var/lost = affected_account.money * 0.8 + (rand(2,4) - 2) / 10
affected_account.money -= lost
//create a taunting log entry
var/datum/transaction/T = new()
T.target_name = pick("","yo brotha from anotha motha","el Presidente","chieF smackDowN")
T.purpose = pick("Ne$ ---ount fu%ds init*&lisat@*n","PAY BACK YOUR MUM","Funds withdrawal","pWnAgE","l33t hax","liberationez")
T.amount = pick("","([rand(0,99999)])","alla money","9001$","HOLLA HOLLA GET DOLLA","([lost])")
var/date1 = "31 December, 1999"
var/date2 = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [rand(1000,3000)]"
T.date = pick("", current_date_string, date1, date2)
var/time1 = rand(0, 99999999)
var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? add_zero(time1 / 600 % 60, 1) : time1 / 600 % 60]"
T.time = pick("", worldtime2text(), time2)
T.source_terminal = pick("","[pick("Biesel","New Gibson")] GalaxyNet Terminal #[rand(111,999)]","your mums place","nantrasen high CommanD")
affected_account.transaction_log.Add(T)
else
//crew wins
message = "The attack has ceased, the affected databases can now be brought online."
var/my_department = "[station_name()] firewall subroutines"
var/sending = message + "<font color='blue'><b>Message dispatched by [my_department].</b></font>"
var/pass = 0
for(var/obj/machinery/message_server/MS in world)
if(!MS.active) continue
// /obj/machinery/message_server/proc/send_rc_message(var/recipient = "",var/sender = "",var/message = "",var/stamp = "", var/id_auth = "", var/priority = 1)
MS.send_rc_message("Engineering/Security/Bridge", my_department, message, "", "", 2)
pass = 1
if(pass)
var/keyed_dpt1 = ckey("Engineering")
var/keyed_dpt2 = ckey("Security")
var/keyed_dpt3 = ckey("Bridge")
for (var/obj/machinery/requests_console/Console in allConsoles)
var/keyed_department = ckey(Console.department)
if(keyed_department == keyed_dpt1 || keyed_department == keyed_dpt2 || keyed_department == keyed_dpt3)
if(Console.newmessagepriority < 2)
Console.newmessagepriority = 2
Console.icon_state = "req_comp2"
if(!Console.silent)
playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(5, Console.loc))
O.show_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [my_department]'"))
Console.messages += "<B><FONT color='red'>High Priority message from [my_department]</FONT></B><BR>[sending]"
kill()
//shouldn't ever hit this, but this is here just in case
/datum/event/money_hacker/end()
if(affected_account && affected_db)
endWhen += time_duration
var/message
if(affected_account && !affected_account)
//hacker wins
message = "The hack attempt has succeeded."
//subtract the money
var/lost = affected_account.money * 0.8 + (rand(2,4) - 2) / 10
affected_account.money -= lost
//create a taunting log entry
var/datum/transaction/T = new()
T.target_name = pick("","yo brotha from anotha motha","el Presidente","chieF smackDowN")
T.purpose = pick("Ne$ ---ount fu%ds init*&lisat@*n","PAY BACK YOUR MUM","Funds withdrawal","pWnAgE","l33t hax","liberationez")
T.amount = pick("","([rand(0,99999)])","alla money","9001$","HOLLA HOLLA GET DOLLA","([lost])")
var/date1 = "31 December, 1999"
var/date2 = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [rand(1000,3000)]"
T.date = pick("", current_date_string, date1, date2)
var/time1 = rand(0, 99999999)
var/time2 = "[round(time1 / 36000)+12]:[(time1 / 600 % 60) < 10 ? add_zero(time1 / 600 % 60, 1) : time1 / 600 % 60]"
T.time = pick("", worldtime2text(), time2)
T.source_terminal = pick("","[pick("Biesel","New Gibson")] GalaxyNet Terminal #[rand(111,999)]","your mums place","nantrasen high CommanD")
affected_account.transaction_log.Add(T)
else
//crew wins
message = "The attack has ceased, the affected accounts can now be brought online."
var/my_department = "[station_name()] firewall subroutines"
var/sending = message + "<font color='blue'><b>Message dispatched by [my_department].</b></font>"
var/pass = 0
for(var/obj/machinery/message_server/MS in world)
if(!MS.active) continue
// /obj/machinery/message_server/proc/send_rc_message(var/recipient = "",var/sender = "",var/message = "",var/stamp = "", var/id_auth = "", var/priority = 1)
MS.send_rc_message("Engineering/Security/Bridge", my_department, message, "", "", 2)
pass = 1
if(pass)
var/keyed_dpt1 = ckey("Engineering")
var/keyed_dpt2 = ckey("Security")
var/keyed_dpt3 = ckey("Bridge")
for (var/obj/machinery/requests_console/Console in allConsoles)
var/keyed_department = ckey(Console.department)
if(keyed_department == keyed_dpt1 || keyed_department == keyed_dpt2 || keyed_department == keyed_dpt3)
if(Console.newmessagepriority < 2)
Console.newmessagepriority = 2
Console.icon_state = "req_comp2"
if(!Console.silent)
playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(5, Console.loc))
O.show_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [my_department]'"))
Console.messages += "<B><FONT color='red'>High Priority message from [my_department]</FONT></B><BR>[sending]"

View File

@@ -1,6 +1,4 @@
/datum/event/money_lotto
endWhen = 301
announceWhen = 300
var/winner_name = "John Smith"
var/winner_sum = 0
var/deposit_success = 0
@@ -9,18 +7,20 @@
winner_sum = pick(5000, 10000, 50000, 100000, 500000, 1000000, 1500000)
if(all_money_accounts.len)
var/datum/money_account/D = pick(all_money_accounts)
D.money += winner_sum
winner_name = D.owner_name
if(!D.suspended)
D.money += winner_sum
var/datum/transaction/T = new()
T.target_name = "Tau Ceti Daily Grand Slam -Stellar- Lottery"
T.purpose = "Winner!"
T.amount = winner_sum
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = "Biesel TCD Terminal #[rand(111,333)]"
D.transaction_log.Add(T)
else
kill()
var/datum/transaction/T = new()
T.target_name = "Tau Ceti Daily Grand Slam -Stellar- Lottery"
T.purpose = "Winner!"
T.amount = winner_sum
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = "Biesel TCD Terminal #[rand(111,333)]"
D.transaction_log.Add(T)
deposit_success = 1
/datum/event/money_lotto/announce()
var/datum/feed_message/newMsg = new /datum/feed_message
@@ -29,7 +29,7 @@
newMsg.body = "TC Daily wishes to congratulate <b>[winner_name]</b> for recieving the Tau Ceti Stellar Slam Lottery, and receiving the out of this world sum of [winner_sum] credits!"
if(!deposit_success)
newMsg.body += "<br>Unfortunately, we were unable to verify the account details provided, so we were unable to transfer the money. Send a cheque containing the sum of $500 to TCD 'Stellar Slam' office on Biesel Prime containing updated details, and it'll be resent within the month."
newMsg.body += "<br>Unfortunately, we were unable to verify the account details provided, so we were unable to transfer the money. Send a cheque containing the sum of $500 to TCD 'Stellar Slam' office on Biesel Prime containing updated details, and your winnings'll be resent within the month."
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "Tau Ceti Daily")