diff --git a/baystation12.dme b/baystation12.dme
index 793ff8b546..18396c4adf 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -778,8 +778,6 @@
#include "code\modules\detectivework\detective_work.dm"
#include "code\modules\detectivework\evidence.dm"
#include "code\modules\detectivework\footprints_and_rag.dm"
-#include "code\modules\detectivework\scanner.dm"
-#include "code\modules\events\alien_infestation.dm"
#include "code\modules\events\blob.dm"
#include "code\modules\events\brand_intelligence.dm"
#include "code\modules\events\carp_migration.dm"
@@ -1007,7 +1005,6 @@
#include "code\modules\mob\new_player\preferences_setup.dm"
#include "code\modules\mob\new_player\skill.dm"
#include "code\modules\mob\new_player\sprite_accessories.dm"
-#include "code\modules\mob\simple_animal\head.dm"
#include "code\modules\paperwork\clipboard.dm"
#include "code\modules\paperwork\filingcabinet.dm"
#include "code\modules\paperwork\folders.dm"
@@ -1162,14 +1159,24 @@
#include "code\WorkInProgress\autopsy.dm"
#include "code\WorkInProgress\buildmode.dm"
#include "code\WorkInProgress\explosion_particles.dm"
-#include "code\WorkInProgress\surgery.dm"
#include "code\WorkInProgress\Cael_Aislinn\energy_field.dm"
#include "code\WorkInProgress\Cael_Aislinn\external_shield_gen.dm"
#include "code\WorkInProgress\Cael_Aislinn\meteor_battery.dm"
#include "code\WorkInProgress\Cael_Aislinn\sculpture.dm"
#include "code\WorkInProgress\Cael_Aislinn\shield_capacitor.dm"
#include "code\WorkInProgress\Cael_Aislinn\shield_gen.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\areas.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_Events.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_TradeDestinations.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\falsewall.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_animals.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_plants.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_temple.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_tribe.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_turfs.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_field.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_gen.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_monitor.dm"
@@ -1186,6 +1193,7 @@
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm"
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
#include "code\WorkInProgress\Chinsky\ashtray.dm"
+#include "code\WorkInProgress\Mini\ATM.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
#include "code\WorkInProgress\Susan\susan_desert_turfs.dm"
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
new file mode 100644
index 0000000000..a69f364e0f
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
@@ -0,0 +1,298 @@
+var/global/current_date_string
+var/global/num_financial_terminals = 1
+var/global/datum/money_account/station_account
+var/global/next_account_number = 0
+
+/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 = 10000
+
+ //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 = 10000
+ 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)
+ for(var/obj/machinery/account_database/A in world)
+ A.accounts.Add(station_account)
+
+//the current ingame time (hh:mm) can be obtained by calling:
+//worldtime2text()
+
+/datum/money_account
+ var/owner_name = ""
+ var/account_number = 0
+ var/remote_access_pin = 0
+ var/money = 0
+ var/list/transaction_log = list()
+ 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 = ""
+
+/obj/machinery/account_database
+ name = "Accounts database"
+ desc = "Holds transaction logs, account data and all kinds of other financial records."
+ icon = 'virology.dmi'
+ icon_state = "analyser"
+ density = 1
+ var/list/accounts = list()
+ req_one_access = list(access_hop, access_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()
+ ..()
+ if(!station_account)
+ create_station_account()
+
+ if(!current_date_string)
+ current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
+
+ 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 = "Accounts Database
"
+ dat += "[machine_id]
"
+ dat += "Confirm identity: [held_card ? held_card : "-----"]
"
+
+ if(access_level > 0)
+ dat += "You may not edit accounts at this terminal, only create and view them.
"
+ if(creating_new_account)
+ dat += "
"
+ dat += "Return to accounts list"
+ dat += "
"
+ else
+ if(detailed_account_view)
+ dat += "
"
+ dat += "Return to accounts list
"
+ dat += "Account number: #[detailed_account_view.account_number]
"
+ dat += "Account holder: [detailed_account_view.owner_name]
"
+ dat += "Account balance: $[detailed_account_view.money]
"
+ dat += ""
+ dat += ""
+ dat += "| Date | "
+ dat += "Time | "
+ dat += "Target | "
+ dat += "Purpose | "
+ dat += "Value | "
+ dat += "Source terminal ID | "
+ dat += "
"
+ for(var/datum/transaction/T in detailed_account_view.transaction_log)
+ dat += ""
+ dat += "| [T.date] | "
+ dat += "[T.time] | "
+ dat += "[T.target_name] | "
+ dat += "[T.purpose] | "
+ dat += "$[T.amount] | "
+ dat += "[T.source_terminal] | "
+ dat += "
"
+ dat += "
"
+ else
+ dat += "Create new account Sync accounts across databases
"
+ dat += ""
+ for(var/i=1, i<=accounts.len, i++)
+ var/datum/money_account/D = accounts[i]
+ dat += ""
+ dat += "| #[D.account_number] | "
+ dat += "[D.owner_name] | "
+ dat += "View in detail | "
+ dat += "
"
+ dat += "
"
+
+ 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("sync_accounts")
+ for(var/obj/machinery/account_database/A in world)
+ for(var/datum/money_account/M in src.accounts)
+ if(!A.accounts.Find(M))
+ A.accounts.Add(M)
+ usr << "\icon[src] Accounts synched across all databases in range."
+
+ if("create_account")
+ creating_new_account = 1
+ if("finalise_create_account")
+ var/account_name = href_list["holder_name"]
+ var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
+ add_account(account_name, starting_funds)
+ 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 <= accounts.len)
+ detailed_account_view = accounts[index]
+ if("view_accounts_list")
+ detailed_account_view = null
+ creating_new_account = 0
+
+ src.attack_hand(usr)
+
+/obj/machinery/account_database/proc/add_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/pre_existing = 0)
+
+ //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(pre_existing)
+ //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 = 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(src.loc)
+
+ var/obj/item/weapon/paper/R = new(P)
+ P.wrapped = R
+ R.name = "Account information: [M.owner_name]"
+ R.info = "Account details (confidential)
"
+ R.info += "Account holder: [M.owner_name]
"
+ R.info += "Account number: [M.account_number]
"
+ R.info += "Account pin: [M.remote_access_pin]
"
+ R.info += "Starting balance: $[M.money]
"
+ R.info += "Date and time: [worldtime2text()], [current_date_string]
"
+ R.info += "Creation terminal ID: [machine_id]
"
+ R.info += "Authorised NT officer overseeing creation: [held_card.registered_name]
"
+
+ //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 += "
This paper has been stamped by the Accounts Database."
+
+
+ //add the account
+ M.transaction_log.Add(T)
+ accounts.Add(M)
+
+/obj/machinery/account_database/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 accounts)
+ if(D.account_number == attempt_account_number)
+ 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
+
+ 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
+/obj/machinery/account_database/proc/attempt_account_access(var/attempt_account_number, var/attempt_pin_number, var/security_level_passed = 0)
+ for(var/datum/money_account/D in 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
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm b/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
new file mode 100644
index 0000000000..5fc619755a
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
@@ -0,0 +1,177 @@
+/obj/item/weapon/eftpos
+ name = "EFTPOS scanner"
+ desc = "Swipe your ID card to pay electronically."
+ icon = 'icons/obj/library.dmi'
+ icon_state = "scanner"
+ 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/obj/machinery/account_database/linked_db
+ var/datum/money_account/linked_account
+
+/obj/item/weapon/eftpos/New()
+ ..()
+ machine_id = "[station_name()] EFTPOS #[num_financial_terminals++]"
+ access_code = rand(1111,111111)
+ reconnect_database()
+ print_reference()
+
+ //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/weapon/eftpos/proc/print_reference()
+ var/obj/item/weapon/paper/R = new(get_turf(src))
+ R.name = "Reference: [eftpos_name]"
+ R.info = "[eftpos_name] reference
"
+ R.info += "Access code: [access_code]
"
+ R.info += "Do not lose this code, or the device will have to be replaced.
"
+
+ //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 += "
This paper has been stamped by the EFTPOS device."
+
+/obj/item/weapon/eftpos/proc/reconnect_database()
+ for(var/obj/machinery/account_database/DB in world)
+ if(DB.z == src.z)
+ linked_db = DB
+ break
+
+/obj/item/weapon/eftpos/attack_self(mob/user as mob)
+ if(get_dist(src,user) <= 1)
+ var/dat = "[eftpos_name]
"
+ dat += "This terminal is [machine_id]. Report this code when contacting NanoTrasen IT Support
"
+ if(transaction_locked)
+ dat += "Reset[transaction_paid ? "" : " (authentication required)"]
"
+
+ dat += "Transaction purpose: [transaction_purpose]
"
+ dat += "Value: $[transaction_amount]
"
+ dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
"
+ if(transaction_paid)
+ dat += "This transaction has been processed successfully.
"
+ else
+ dat += "Swipe your card below the line to finish this transaction.
"
+ dat += "\[------\]"
+ else
+ dat += "Lock in new transaction
"
+
+ dat += "Transaction purpose: [transaction_purpose]
"
+ dat += "Value: $[transaction_amount]
"
+ dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
"
+ dat += "Change access code"
+ user << browse(dat,"window=eftpos")
+ else
+ user << browse(null,"window=eftpos")
+
+/obj/item/weapon/eftpos/attackby(O as obj, user as mob)
+ if(istype(O, /obj/item/weapon/card))
+ //attempt to connect to a new db, and if that doesn't work then fail
+ if(!linked_db)
+ reconnect_database()
+ if(linked_db && linked_account)
+ var/obj/item/weapon/card/I = O
+ scan_card(I)
+ else
+ usr << "\icon[src]Unable to connect to accounts database."
+ else
+ ..()
+
+/obj/item/weapon/eftpos/Topic(var/href, var/href_list)
+ if(href_list["choice"])
+ switch(href_list["choice"])
+ if("change_code")
+ var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm old EFTPOS code"))
+ if(attempt_code == access_code)
+ access_code = text2num(input("Enter a new access code for this device", "Enter new EFTPOS code"))
+ print_reference()
+ else
+ usr << "\icon[src]Incorrect code entered."
+ if("link_account")
+ if(linked_db)
+ var/attempt_account_num = text2num(input("Enter account number to pay EFTPOS charges into", "New account number"))
+ var/attempt_pin = text2num(input("Enter pin code", "Account pin"))
+ linked_account = linked_db.attempt_account_access(attempt_account_num, attempt_pin, 1)
+ else
+ usr << "Unable to connect to accounts database."
+ if("trans_purpose")
+ transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
+ if("trans_value")
+ transaction_amount = max(text2num(input("Enter amount for EFTPOS transaction", "Transaction amount")),0)
+ if("toggle_lock")
+ if(transaction_locked)
+ var/attempt_code = text2num(input("Enter EFTPOS access code", "Reset Transaction"))
+ if(attempt_code == access_code)
+ transaction_locked = 0
+ transaction_paid = 0
+ else if(linked_account)
+ transaction_locked = 1
+ else
+ usr << "\icon[src] No account connected to send transactions to."
+ if("scan_card")
+ //attempt to connect to a new db, and if that doesn't work then fail
+ if(!linked_db)
+ reconnect_database()
+ if(linked_db && linked_account)
+ var/obj/item/I = usr.get_active_hand()
+ if (istype(I, /obj/item/weapon/card))
+ scan_card(I)
+ else
+ usr << "\icon[src]Unable to link accounts."
+
+ src.attack_self(usr)
+
+/obj/item/weapon/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("[usr] swipes a card through [src].")
+ if(transaction_locked && !transaction_paid)
+ if(linked_account)
+ var/attempt_pin = text2num(input("Enter pin code", "EFTPOS transaction"))
+ var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2)
+ if(D)
+ if(transaction_amount <= D.money)
+ playsound(src, '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] ([eftpos_name])"
+ T.purpose = transaction_purpose
+ 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]You don't have that much money!"
+ else
+ usr << "\icon[src]EFTPOS is not connected to an account."
+ else
+ usr << "\icon[src]Unable to access account. Check security settings and try again."
+ else
+ ..()
+
+ //emag?
\ No newline at end of file
diff --git a/code/WorkInProgress/Mini/ATM.dm b/code/WorkInProgress/Mini/ATM.dm
index 17b6ef2e47..7551e96e9c 100644
--- a/code/WorkInProgress/Mini/ATM.dm
+++ b/code/WorkInProgress/Mini/ATM.dm
@@ -7,6 +7,11 @@ 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
@@ -17,72 +22,346 @@ log transactions
anchored = 1
use_power = 1
idle_power_usage = 10
+ var/obj/machinery/account_database/linked_db
+ 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()
+ ..()
+ reconnect_database()
+ machine_id = "[station_name()] RT #[num_financial_terminals++]"
+
+/obj/machinery/atm/process()
+ 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--
+
+ 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/proc/reconnect_database()
+ for(var/obj/machinery/account_database/DB in world)
+ if(DB.z == src.z)
+ linked_db = DB
+ break
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
- if(ishuman(user))
- var/obj/item/weapon/card/id/user_id = src.scan_user(user)
+ 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
+ authenticated_account = null
+ else if(authenticated_account)
if(istype(I,/obj/item/weapon/spacecash))
- user_id.money += I:worth
+ //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 << "You insert [I] into [src]."
+ 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)
- var/obj/item/weapon/card/id/user_id = src.scan_user(user)
- if(..())
- return
- var/dat = ""
- dat += "NanoTrasen Automatic Teller Machine
"
- dat += "For all your monetary needs!
"
- dat += "Welcome, [user_id.registered_name].
"
- dat += "You have $[user_id.money] in your account.
"
- dat += "Withdraw
"
- user << browse(dat,"window=atm")
+ //js replicated from obj/machinery/computer/card
+ var/dat = "NanoTrasen Automatic Teller Machine
"
+ dat += "For all your monetary needs!
"
+ dat += "This terminal is [machine_id]. Report this code when contacting NanoTrasen IT Support
"
+ dat += "Card: [held_card ? held_card.name : "------"]
"
+
+ if(ticks_left_locked_down > 0)
+ dat += "Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled."
+ else if(authenticated_account)
+ switch(view_screen)
+ if(CHANGE_SECURITY_LEVEL)
+ dat += "Select a new security level for this account:
"
+ var/text = "Zero - Only 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 = "[text]"
+ dat += "[text]
"
+ text = "One - Both an account number and pin is required to access this account and process transactions."
+ if(authenticated_account.security_level != 1)
+ text = "[text]"
+ dat += "[text]
"
+ 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 = "[text]"
+ dat += "[text]
"
+ dat += "Back"
+ if(VIEW_TRANSACTION_LOGS)
+ dat += "Transaction logs
"
+ dat += "Back"
+ dat += ""
+ dat += ""
+ dat += "| Date | "
+ dat += "Time | "
+ dat += "Target | "
+ dat += "Purpose | "
+ dat += "Value | "
+ dat += "Source terminal ID | "
+ dat += "
"
+ for(var/datum/transaction/T in authenticated_account.transaction_log)
+ dat += ""
+ dat += "| [T.date] | "
+ dat += "[T.time] | "
+ dat += "[T.target_name] | "
+ dat += "[T.purpose] | "
+ dat += "$[T.amount] | "
+ dat += "[T.source_terminal] | "
+ dat += "
"
+ dat += "
"
+ if(TRANSFER_FUNDS)
+ dat += "Account balance: $[authenticated_account.money]
"
+ dat += "Back
"
+ dat += ""
+ else
+ dat += "Welcome, [authenticated_account.owner_name].
"
+ dat += "Account balance: $[authenticated_account.money]"
+ dat += ""
+ dat += "Change account security level
"
+ dat += "Make transfer
"
+ dat += "View transaction log
"
+ dat += "Print balance statement
"
+ dat += "Logout
"
+ else if(linked_db)
+ dat += ""
+ else
+ dat += "Unable to connect to accounts database, please retry and if the issue persists contact NanoTrasen IT support."
+ reconnect_database()
+
+ user << browse(dat,"window=atm;size=500x650")
+ else
+ user << browse(null,"window=atm")
/obj/machinery/atm/Topic(var/href, var/href_list)
- if(href_list["withdraw"] && href_list["id"])
- var/amount = input("How much would you like to withdraw?", "Amount", 0) in list(1,10,20,50,100,200,500,1000, 0)
- var/obj/item/weapon/card/id/user_id = locate(href_list["id"])
- if(amount != 0 && user_id)
- if(amount <= user_id.money)
- user_id.money -= amount
- //hueg switch for giving moneh out
- switch(amount)
- if(1)
- new /obj/item/weapon/spacecash(loc)
- if(10)
- new /obj/item/weapon/spacecash/c10(loc)
- if(20)
- new /obj/item/weapon/spacecash/c20(loc)
- if(50)
- new /obj/item/weapon/spacecash/c50(loc)
- if(100)
- new /obj/item/weapon/spacecash/c100(loc)
- if(200)
- new /obj/item/weapon/spacecash/c200(loc)
- if(500)
- new /obj/item/weapon/spacecash/c500(loc)
- if(1000)
- new /obj/item/weapon/spacecash/c1000(loc)
- else
- usr << browse("You don't have that much money!
Back","window=atm")
- return
+ if(href_list["choice"])
+ switch(href_list["choice"])
+ if("transfer")
+ if(authenticated_account && linked_db)
+ var/target_account_number = text2num(href_list["target_acc_number"])
+ var/transfer_amount = text2num(href_list["funds_amount"])
+ var/transfer_purpose = href_list["purpose"]
+ if(transfer_amount <= authenticated_account.money)
+ if(linked_db.charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
+ usr << "\icon[src]Funds transfer successful."
+ 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]Funds transfer failed."
+
+ else
+ usr << "\icon[src]You don't have enough funds to do that!"
+ 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(linked_db)
+ 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 = linked_db.attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
+ if(!authenticated_account)
+ if(previous_account_number == tried_account_num)
+ if(++number_incorrect_tries > max_pin_attempts)
+ //lock down the atm
+ number_incorrect_tries = 0
+ ticks_left_locked_down = 10
+ playsound(src, 'buzz-two.ogg', 50, 1)
+
+ //create an entry in the account transaction log
+ var/datum/transaction/T = new()
+ T.target_name = authenticated_account.owner_name
+ T.purpose = "Unauthorised login attempt"
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ authenticated_account.transaction_log.Add(T)
+ else
+ previous_account_number = tried_account_num
+ number_incorrect_tries = 1
+ playsound(src, 'buzz-sigh.ogg', 50, 1)
+ else
+ playsound(src, '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)
+ if("withdrawal")
+ var/amount = max(text2num(href_list["funds_amount"]),0)
+ if(authenticated_account && amount > 0)
+ if(amount <= authenticated_account.money)
+ playsound(src, '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]You don't have enough funds to do that!"
+ 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 = "NT Automated Teller Account Statement
"
+ R.info += "Account holder: [authenticated_account.owner_name]
"
+ R.info += "Account number: [authenticated_account.account_number]
"
+ R.info += "Balance: $[authenticated_account.money]
"
+ R.info += "Date and time: [worldtime2text()], [current_date_string]
"
+ R.info += "Service terminal ID: [machine_id]
"
+
+ //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 += "
This paper has been stamped by the Automatic Teller Machine."
+
+ 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
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(human_user.wear_id)
- if(istype(human_user.wear_id, /obj/item/device/pda) )
- var/obj/item/device/pda/P = human_user.wear_id
- if(P.id)
- return P.id
- else
- return null
- else if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
- return human_user.wear_id
- else
- return null
- else
- return null
+ if(!authenticated_account && linked_db)
+ 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 = linked_db.attempt_account_access(I.associated_account_number)
diff --git a/code/WorkInProgress/mapload/dmm_suite.dm b/code/WorkInProgress/mapload/dmm_suite.dm
deleted file mode 100644
index f096d55564..0000000000
--- a/code/WorkInProgress/mapload/dmm_suite.dm
+++ /dev/null
@@ -1,246 +0,0 @@
-dmm_suite
- /*
-
- dmm_suite version 1.0
- Released January 30th, 2011.
-
- defines the object /dmm_suite
- - Provides the proc load_map()
- - Loads the specified map file onto the specified z-level.
- - provides the proc write_map()
- - Returns a text string of the map in dmm format
- ready for output to a file.
- - provides the proc save_map()
- - Returns a .dmm file if map is saved
- - Returns FALSE if map fails to save
-
- The dmm_suite provides saving and loading of map files in BYOND's native DMM map
- format. It approximates the map saving and loading processes of the Dream Maker
- and Dream Seeker programs so as to allow editing, saving, and loading of maps at
- runtime.
-
- ------------------------
-
- To save a map at runtime, create an instance of /dmm_suite, and then call
- write_map(), which accepts three arguments:
- - A turf representing one corner of a three dimensional grid (Required).
- - Another turf representing the other corner of the same grid (Required).
- - Any, or a combination, of several bit flags (Optional, see documentation).
-
- The order in which the turfs are supplied does not matter, the /dmm_writer will
- determine the grid containing both, in much the same way as DM's block() function.
- write_map() will then return a string representing the saved map in dmm format;
- this string can then be saved to a file, or used for any other purose.
-
- ------------------------
-
- To load a map at runtime, create an instance of /dmm_suite, and then call load_map(),
- which accepts two arguments:
- - A .dmm file to load (Required).
- - A number representing the z-level on which to start loading the map (Optional).
-
- The /dmm_suite will load the map file starting on the specified z-level. If no
- z-level was specified, world.maxz will be increased so as to fit the map. Note
- that if you wish to load a map onto a z-level that already has objects on it,
- you will have to handle the removal of those objects. Otherwise the new map will
- simply load the new objects on top of the old ones.
-
- Also note that all type paths specified in the .dmm file must exist in the world's
- code, and that the /dmm_reader trusts that files to be loaded are in fact valid
- .dmm files. Errors in the .dmm format will cause runtime errors.
-
- */
-
-
- verb/load_map(var/dmm_file as file, var/z_offset as num)
- // dmm_file: A .dmm file to load (Required).
- // z_offset: A number representing the z-level on which to start loading the map (Optional).
-
-
- verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num)
- // t1: A turf representing one corner of a three dimensional grid (Required).
- // t2: Another turf representing the other corner of the same grid (Required).
- // flags: Any, or a combination, of several bit flags (Optional, see documentation).
-
- // save_map is included as a legacy proc. Use write_map instead.
- verb/save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num)
- // t1: A turf representing one corner of a three dimensional grid (Required).
- // t2: Another turf representing the other corner of the same grid (Required).
- // map_name: A valid name for the map to be saved, such as "castle" (Required).
- // flags: Any, or a combination, of several bit flags (Optional, see documentation).
-
-
-#define DMM_IGNORE_AREAS 1
-#define DMM_IGNORE_TURFS 2
-#define DMM_IGNORE_OBJS 4
-#define DMM_IGNORE_NPCS 8
-#define DMM_IGNORE_PLAYERS 16
-#define DMM_IGNORE_MOBS 24
-dmm_suite{
- var{
- quote = "\""
- list/letter_digits = list(
- "a","b","c","d","e",
- "f","g","h","i","j",
- "k","l","m","n","o",
- "p","q","r","s","t",
- "u","v","w","x","y",
- "z",
- "A","B","C","D","E",
- "F","G","H","I","J",
- "K","L","M","N","O",
- "P","Q","R","S","T",
- "U","V","W","X","Y",
- "Z"
- )
- }
- save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num){
- //Check for illegal characters in file name... in a cheap way.
- if(!((ckeyEx(map_name)==map_name) && ckeyEx(map_name))){
- CRASH("Invalid text supplied to proc save_map, invalid characters or empty string.")
- }
- //Check for valid turfs.
- if(!isturf(t1) || !isturf(t2)){
- CRASH("Invalid arguments supplied to proc save_map, arguments were not turfs.")
- }
- var/file_text = write_map(t1,t2,flags)
- if(fexists("[map_name].dmm")){
- fdel("[map_name].dmm")
- }
- var/saved_map = file("[map_name].dmm")
- saved_map << file_text
- return saved_map
- }
- write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
- //Check for valid turfs.
- if(!isturf(t1) || !isturf(t2)){
- CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.")
- }
- var/turf/nw = locate(min(t1.x,t2.x),max(t1.y,t2.y),min(t1.z,t2.z))
- var/turf/se = locate(max(t1.x,t2.x),min(t1.y,t2.y),max(t1.z,t2.z))
- var/list/templates[0]
- var/template_buffer = {""}
- var/dmm_text = {""}
- for(var/pos_z=nw.z;pos_z<=se.z;pos_z++){
- for(var/pos_y=nw.y;pos_y>=se.y;pos_y--){
- for(var/pos_x=nw.x;pos_x<=se.x;pos_x++){
- var/turf/test_turf = locate(pos_x,pos_y,pos_z)
- var/test_template = make_template(test_turf, flags)
- var/template_number = templates.Find(test_template)
- if(!template_number){
- templates.Add(test_template)
- template_number = templates.len
- }
- template_buffer += "[template_number],"
- }
- template_buffer += ";"
- }
- template_buffer += "."
- }
- var/key_length = round/*floor*/(log(letter_digits.len,templates.len-1)+1)
- var/list/keys[templates.len]
- for(var/key_pos=1;key_pos<=templates.len;key_pos++){
- keys[key_pos] = get_model_key(key_pos,key_length)
- dmm_text += {""[keys[key_pos]]" = ([templates[key_pos]])\n"}
- }
- var/z_level = 0
- for(var/z_pos=1;TRUE;z_pos=findtext(template_buffer,".",z_pos)+1){
- if(z_pos>=length(template_buffer)){break}
- if(z_level){dmm_text+={"\n"}}
- dmm_text += {"\n(1,1,[++z_level]) = {"\n"}
- var/z_block = copytext(template_buffer,z_pos,findtext(template_buffer,".",z_pos))
- for(var/y_pos=1;TRUE;y_pos=findtext(z_block,";",y_pos)+1){
- if(y_pos>=length(z_block)){break}
- var/y_block = copytext(z_block,y_pos,findtext(z_block,";",y_pos))
- for(var/x_pos=1;TRUE;x_pos=findtext(y_block,",",x_pos)+1){
- if(x_pos>=length(y_block)){break}
- var/x_block = copytext(y_block,x_pos,findtext(y_block,",",x_pos))
- var/key_number = text2num(x_block)
- var/temp_key = keys[key_number]
- dmm_text += temp_key
- sleep(-1)
- }
- dmm_text += {"\n"}
- sleep(-1)
- }
- dmm_text += {"\"}"}
- sleep(-1)
- }
- return dmm_text
- }
- proc{
- make_template(var/turf/model as turf, var/flags as num){
- var/template = ""
- var/obj_template = ""
- var/mob_template = ""
- var/turf_template = ""
- if(!(flags & DMM_IGNORE_TURFS)){
- turf_template = "[model.type][check_attributes(model)],"
- } else{ turf_template = "[world.turf],"}
- var/area_template = ""
- if(!(flags & DMM_IGNORE_OBJS)){
- for(var/obj/O in model.contents){
- obj_template += "[O.type][check_attributes(O)],"
- }
- }
- for(var/mob/M in model.contents){
- if(M.client){
- if(!(flags & DMM_IGNORE_PLAYERS)){
- mob_template += "[M.type][check_attributes(M)],"
- }
- }
- else{
- if(!(flags & DMM_IGNORE_NPCS)){
- mob_template += "[M.type][check_attributes(M)],"
- }
- }
- }
- if(!(flags & DMM_IGNORE_AREAS)){
- var/area/m_area = model.loc
- area_template = "[m_area.type][check_attributes(m_area)]"
- } else{ area_template = "[world.area]"}
- template = "[obj_template][mob_template][turf_template][area_template]"
- return template
- }
- check_attributes(var/atom/A){
- var/attributes_text = {"{"}
- for(var/V in A.vars){
- sleep(-1)
- if((!issaved(A.vars[V])) || (A.vars[V]==initial(A.vars[V]))){continue}
- if(istext(A.vars[V])){
- attributes_text += {"[V] = "[A.vars[V]]""}
- }
- else if(isnum(A.vars[V])||ispath(A.vars[V])){
- attributes_text += {"[V] = [A.vars[V]]"}
- }
- else if(isicon(A.vars[V])||isfile(A.vars[V])){
- attributes_text += {"[V] = '[A.vars[V]]'"}
- }
- else{
- continue
- }
- if(attributes_text != {"{"}){
- attributes_text+={"; "}
- }
- }
- if(attributes_text=={"{"}){
- return
- }
- if(copytext(attributes_text, length(attributes_text)-1, 0) == {"; "}){
- attributes_text = copytext(attributes_text, 1, length(attributes_text)-1)
- }
- attributes_text += {"}"}
- return attributes_text
- }
- get_model_key(var/which as num, var/key_length as num){
- var/key = ""
- var/working_digit = which-1
- for(var/digit_pos=key_length;digit_pos>=1;digit_pos--){
- var/place_value = round/*floor*/(working_digit/(letter_digits.len**(digit_pos-1)))
- working_digit-=place_value*(letter_digits.len**(digit_pos-1))
- key = "[key][letter_digits[place_value+1]]"
- }
- return key
- }
- }
- }
diff --git a/code/WorkInProgress/mapload/reader.dm b/code/WorkInProgress/mapload/reader.dm
deleted file mode 100644
index 755b96fc2d..0000000000
--- a/code/WorkInProgress/mapload/reader.dm
+++ /dev/null
@@ -1,181 +0,0 @@
-dmm_suite/load_map(var/dmm_file as file, var/z_offset as num)
- if(!z_offset)
- z_offset = world.maxz+1
- var/quote = ascii2text(34)
- var/tfile = file2text(dmm_file)
- var/tfile_len = length(tfile)
- var/list/grid_models[0]
- var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))
- for(var/lpos=1;lposlength(zgrid)) break
- sleep(-1)
-
- if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len) break
- sleep(-1)
-
-
-dmm_suite/proc/parse_grid(var/model as text,var/xcrd as num,var/ycrd as num,var/zcrd as num)
- set background = 1
-
- /*Method parse_grid()
- - Accepts a text string containing a comma separated list of type paths of the
- same construction as those contained in a .dmm file, and instantiates them.
- */
- var/list/text_strings[0]
- for(var/index=1;findtext(model,quote);index++)
- /*Loop: Stores quoted portions of text in text_strings, and replaces them with an
- index to that list.
- - Each iteration represents one quoted section of text.
- */
- text_strings.len=index
- text_strings[index] = copytext(model,findtext(model,quote)+1,findtext(model,quote,findtext(model,quote)+1,0))
- model = copytext(model,1,findtext(model,quote))+"~[index]"+copytext(model,findtext(model,quote,findtext(model,quote)+1,0)+1,0)
- sleep(-1)
-
- for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1)
- /*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- - Each iteration represents one object's data, including type path and field values.
- */
- var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
- var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
-
- if(ispath(atom_def, /turf/space))
- continue
-
- var/list/attributes[0]
- if(findtext(full_def,"{"))
- full_def = copytext(full_def,1,length(full_def))
- for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1)
- //Loop: Identifies each attribute/value pair, and stores it in attributes[].
- attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
- if(!findtext(copytext(full_def,apos,0),";")) break
- sleep(-1)
-
- //Construct attributes associative list
- var/list/fields = new(0)
- for(var/index=1;index<=attributes.len;index++)
- var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
- var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
- //Check for string
- if(findtext(trim_right,"~"))
- var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
- trim_right=text_strings[text2num(reference_index)]
- //Check for number
- else if(isnum(text2num(trim_right)))
- trim_right = text2num(trim_right)
- //Check for file
- else if(copytext(trim_right,1,2) == "'")
- trim_right = file(copytext(trim_right,2,length(trim_right)))
- fields[trim_left] = trim_right
-
- //End construction
- //Begin Instanciation
- var/atom/instance
- var/dmm_suite/preloader/_preloader = new(fields)
- if(ispath(atom_def,/area))
- var/turf/A = locate(xcrd,ycrd,zcrd)
- if(A.loc.name == "Space")
- instance = locate(atom_def)
- if(instance)
- instance.contents.Add(locate(xcrd,ycrd,zcrd))
-
- else
- //global.current_preloader = _preloader
- instance = new atom_def(locate(xcrd,ycrd,zcrd))
- if(_preloader)
- _preloader.load(instance)
- //End Instanciation
- if(!findtext(copytext(model,dpos,0),",")) break
-
-
-dmm_suite/proc/trim_text(var/what as text)
- while(length(what) && findtext(what," ",1,2))
- what=copytext(what,2,0)
- while(length(what) && findtext(what," ",length(what),0))
- what=copytext(what,1,length(what))
- return what
-
-/*
-var/global/dmm_suite/preloader/current_preloader = null
-atom/New()
- if(global.current_preloader)
- global.current_preloader.load(src)
- ..()
-*/
-
-
-dmm_suite/preloader
- parent_type = /datum
- var/list/attributes
-
-
- New(list/the_attributes)
- ..()
- if(!the_attributes.len) Del()
- attributes = the_attributes
-
-
- proc/load(atom/what)
- for(var/attribute in attributes)
- what.vars[attribute] = attributes[attribute]
- Del()
-
-
-
-/client/proc/mapload(var/dmm_map as file)
- set category = "Debug"
- set name = "LoadMap"
- set desc = "Loads a map"
- set hidden = 1
- if(src.holder)
- if(!src.mob)
- return
- if(src.holder.rank in list("Game Admin", "Game Master"))
- var/file_name = "[dmm_map]"
- var/file_extension = copytext(file_name,length(file_name)-2,0)
- if(file_extension != "dmm")
- usr << "Supplied file must be a .dmm file."
- return
- var/map_z = input(usr,"Enter variable value:" ,"Value", 123) as num
- if(map_z > (world.maxz+1))
- map_z = (world.maxz+1)
-
- var/dmm_suite/new_reader = new()
- new_reader.load_map(dmm_map, map_z)
- log_admin("[key_name(src.mob)] loaded a map on z:[map_z]")
-
- else
- alert("No")
- return
- return
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 1962c1e10b..13249887f8 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -27,7 +27,7 @@
/obj/item/weapon/spacecash
- name = "space cash"
+ name = "1 credit chip"
desc = "It's worth 1 credit."
gender = PLURAL
icon = 'icons/obj/items.dmi'
@@ -42,35 +42,57 @@
w_class = 1.0
var/access = list()
access = access_crate_cash
+ var/worth = 1
/obj/item/weapon/spacecash/c10
+ name = "10 credit chip"
icon_state = "spacecash10"
access = access_crate_cash
desc = "It's worth 10 credits."
+ worth = 10
+
/obj/item/weapon/spacecash/c20
+ name = "20 credit chip"
icon_state = "spacecash20"
access = access_crate_cash
desc = "It's worth 20 credits."
+ worth = 20
+
/obj/item/weapon/spacecash/c50
+ name = "50 credit chip"
icon_state = "spacecash50"
access = access_crate_cash
desc = "It's worth 50 credits."
+ worth = 50
+
/obj/item/weapon/spacecash/c100
+ name = "100 credit chip"
icon_state = "spacecash100"
access = access_crate_cash
desc = "It's worth 100 credits."
+ worth = 100
+
/obj/item/weapon/spacecash/c200
+ name = "200 credit chip"
icon_state = "spacecash200"
access = access_crate_cash
desc = "It's worth 200 credits."
+ worth = 200
+
/obj/item/weapon/spacecash/c500
+ name = "500 credit chip"
icon_state = "spacecash500"
access = access_crate_cash
desc = "It's worth 500 credits."
+ worth = 500
+
/obj/item/weapon/spacecash/c1000
+ name = "1000 credit chip"
icon_state = "spacecash1000"
access = access_crate_cash
desc = "It's worth 1000 credits."
+ worth = 1000
+
/obj/item/weapon/bananapeel
name = "banana peel"
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index b988cf2447..da377f2513 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -9,7 +9,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
config_tag = "changeling"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
- required_players = 15
+ required_players = 2
+ required_players_secret = 5
required_enemies = 1
recommended_enemies = 4
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index d8afb69ed0..12a5525428 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -3,7 +3,8 @@
config_tag = "traitorchan"
traitors_possible = 3 //hard limit on traitors if scaling is turned off
restricted_jobs = list("AI", "Cyborg")
- required_players = 20
+ required_players = 3
+ required_players_secret = 10
required_enemies = 2
recommended_enemies = 3
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index c0d097f081..ee16e21a77 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -22,7 +22,8 @@
config_tag = "cult"
restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain")
protected_jobs = list()
- required_players = 15
+ required_players = 5
+ required_players_secret = 15
required_enemies = 3
recommended_enemies = 4
diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm
index 03cc1104e2..0d4a20ff2f 100644
--- a/code/game/gamemodes/epidemic/epidemic.dm
+++ b/code/game/gamemodes/epidemic/epidemic.dm
@@ -1,7 +1,8 @@
/datum/game_mode/epidemic
name = "epidemic"
config_tag = "epidemic"
- required_players = 6
+ required_players = 1
+ required_players_secret = 15
var/const/waittime_l = 300 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 600 //upper bound on time before intercept arrives (in tenths of seconds)
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index fccb79cdbf..c705df2f79 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -46,13 +46,15 @@
possibleEvents["Meteor"] = 80 * engineer_count
possibleEvents["Blob"] = 30 * engineer_count
possibleEvents["Spacevine"] = 30 * engineer_count
+ possibleEvents["Grid Check"] = 10 * engineer_count
if(medical_count >= 1)
possibleEvents["Radiation"] = medical_count * 100
possibleEvents["Virus"] = medical_count * 50
possibleEvents["Appendicitis"] = medical_count * 50
if(security_count >= 1)
possibleEvents["Prison Break"] = security_count * 50
- possibleEvents["Space Ninja"] = security_count * 10 // very low chance for space ninja event
+ /*if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)
+ possibleEvents["Space Ninja"] = security_count * 10*/
var/picked_event = pick(possibleEvents)
var/chance = possibleEvents[picked_event]
@@ -77,54 +79,6 @@
return 0
switch(picked_event)
- if("Meteor")
- command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/meteors.ogg')
- spawn(100)
- meteor_wave()
- spawn_meteors()
- spawn(700)
- meteor_wave()
- spawn_meteors()
-
- if(2)
- command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/granomalies.ogg')
- var/turf/T = pick(blobstart)
- var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
- spawn(rand(50, 300))
- del(bh)
- /*
- if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO
- command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- world << sound('sound/AI/spanomalies.ogg')
- var/list/turfs = new
- var/turf/picked
- for(var/turf/simulated/floor/T in world)
- if(T.z == 1)
- turfs += T
- for(var/turf/simulated/floor/T in turfs)
- if(prob(20))
- spawn(50+rand(0,3000))
- picked = pick(turfs)
- var/obj/effect/portal/P = new /obj/effect/portal( T )
- P.target = picked
- P.creator = null
- P.icon = 'icons/obj/objects.dmi'
- P.failchance = 0
- P.icon_state = "anom"
- P.name = "wormhole"
- spawn(rand(300,600))
- del(P)
- */
- if(3)
- if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round.
- space_ninja_arrival()//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
- if(4) mini_blob_event()
if("Space Ninja")
//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
space_ninja_arrival()
@@ -148,6 +102,10 @@
spacevine_infestation()
if("Communications")
communications_blackout()
+ if("Grid Check")
+ grid_check()
+ if("Meteor")
+ meteor_shower()
return 1
@@ -163,8 +121,9 @@
for(var/obj/machinery/telecomms/T in telecomms_list)
T.emp_act(1)
-/proc/power_failure()
- command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure")
+/proc/power_failure(var/is_grid_check = 0)
+ command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", is_grid_check ? "Automated Grid Check" : "Critical Power Failure")
+
for(var/mob/M in player_list)
M << sound('sound/AI/poweroff.ogg')
for(var/obj/machinery/power/smes/S in world)
@@ -624,10 +583,28 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
world << "Ion Storm Main Done"
*/
+/proc/meteor_shower()
+ command_alert("The station is now in a meteor shower", "Meteor Alert")
+
+ spawn(0)
+ var/waves = rand(1,4)
+ while(waves > 0)
+ sleep(rand(20,100))
+ spawn_meteors(rand(1,3))
+ waves--
+
+ command_alert("The station has cleared the meteor shower", "Meteor Alert")
+
+/proc/grid_check()
+ spawn(0)
+ power_failure(1)
+ sleep(rand(100,600))
+ power_restore()
+
// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
// with a specific role.
// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
-proc/number_active_with_role(role)
+/proc/number_active_with_role(role)
var/count = 0
for(var/mob/M in player_list)
if(!M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
@@ -657,4 +634,4 @@ proc/number_active_with_role(role)
if("Cyborg")
if(M.mind.assigned_role == "Cyborg")
count++
- return count
\ No newline at end of file
+ return count
diff --git a/code/game/gamemodes/events/BlowOut.dm b/code/game/gamemodes/events/BlowOut.dm
deleted file mode 100644
index 1d660989d9..0000000000
--- a/code/game/gamemodes/events/BlowOut.dm
+++ /dev/null
@@ -1,32 +0,0 @@
-/area/var/radsafe = 0
-/area/maintenance/radsafe = 1
-/area/ai_monitored/maintenance/radsafe = 1
-/area/centcom/radsafe = 1
-/area/admin/radsafe = 1
-/area/adminsafety/radsafe = 1
-/area/shuttle/radsafe = 1
-/area/syndicate_station/radsafe = 1
-/area/asteroid/radsafe = 1
-/area/crew_quarters/sleeping/radsafe = 1
-
-/datum/event/blowout
- Lifetime = 150
- Announce()
- if(!forced && prob(90))
- ActiveEvent = null
- SpawnEvent()
- del src
- return
- command_alert("Warning: station approaching high-density radiation cloud. Seek cover immediately.")
- Tick()
- if(ActiveFor == 50)
- command_alert("Station has entered radiation cloud. Do not leave cover until it has passed.")
- if(ActiveFor == 100 || ActiveFor == 150) //1/2 and 2/2 f the way after it start proper make peope be half dead mostly
- for(var/mob/living/carbon/M in world)
- var/area = get_area(M)
- if(area:radsafe)
- continue
- if(!M.stat)
- M.radiate(100)
- Die()
- command_alert("The station has cleared the radiation cloud. It is now safe to leave cover.")
\ No newline at end of file
diff --git a/code/game/gamemodes/events/ElectricalStorm.dm b/code/game/gamemodes/events/ElectricalStorm.dm
deleted file mode 100644
index 58d42c23d0..0000000000
--- a/code/game/gamemodes/events/ElectricalStorm.dm
+++ /dev/null
@@ -1,88 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04
-
-/datum/event/electricalstorm
- var/list/obj/machinery/light/Lights = list( )
- var/list/obj/machinery/light/APCs = list( )
- var/list/obj/machinery/light/Doors = list( )
- var/list/obj/machinery/light/Comms = list( )
-
- Announce()
-// command_alert("The station is flying through an electrical storm. Radio communications may be disrupted", "Anomaly Alert")
-
- for(var/obj/machinery/light/Light in world)
- if(Light.z == 1 && Light.status != 0)
- Lights += Light
-
- for(var/obj/machinery/power/apc/APC in world)
- if(APC.z == 1 && !APC.crit)
- APCs += APC
-
- for(var/obj/machinery/door/airlock/Door in world)
- if(Door.z == 1 && !istype(Door,/obj/machinery/door/airlock/secure))
- Doors += Door
-
- for(var/obj/machinery/telecomms/processor/T in world)
- if(prob(90) && !(T.stat & (BROKEN|NOPOWER)))
- T.stat |= BROKEN
- Comms |= T
-
- Tick()
- for(var/x = 0; x < 3; x++)
- if (prob(30))
- BlowLight()
- if (prob(10))
- DisruptAPC()
- if (prob(10))
- DisableDoor()
-
-
- Die()
- command_alert("The station has cleared the electrical storm. Radio communications restored", "Anomaly Alert")
- for(var/obj/machinery/telecomms/processor/T in Comms)
- T.stat &= ~BROKEN
- Comms = list()
-
- proc
- BlowLight() //Blow out a light fixture
- var/obj/machinery/light/Light = null
- var/failed_attempts = 0
- while (Light == null || Light.status != 0)
- Light = pick(Lights)
- failed_attempts++
- if (failed_attempts >= 10)
- return
-
- spawn(0) //Overload the light, spectacularly.
- //Light.sd_SetLuminosity(10)
- //sleep(2)
- Light.on = 1
- Light.broken()
- Lights -= Light
-
- DisruptAPC()
- var/failed_attempts = 0
- var/obj/machinery/power/apc/APC
- while (!APC || !APC.operating)
- APC = pick(APCs)
- failed_attempts++
- if (failed_attempts >= 10)
- return
-
- if (prob(40))
- APC.operating = 0 //Blow its breaker
- if (prob(8))
- APC.set_broken()
- APCs -= APC
-
- DisableDoor()
- var/obj/machinery/door/airlock/Airlock
- while (!Airlock || Airlock.z != 1)
- Airlock = pick(Doors)
- Airlock.pulse(airlockIndexToWireColor[4])
- for (var/x = 0; x < 2; x++)
- var/Wire = 0
- while(!Wire || Wire == 4)
- Wire = rand(1, 9)
- Airlock.pulse(airlockIndexToWireColor[Wire])
- Airlock.update_icon()
- Doors -= Airlock
diff --git a/code/game/gamemodes/events/GravitationalAnomaly.dm b/code/game/gamemodes/events/GravitationalAnomaly.dm
deleted file mode 100644
index 8b7d2186cf..0000000000
--- a/code/game/gamemodes/events/GravitationalAnomaly.dm
+++ /dev/null
@@ -1,10 +0,0 @@
-/datum/event/gravitationalanomaly
-
- Announce()
-
- command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- world << sound('granomalies.ogg')
- var/turf/T = pick(blobstart)
- var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
- spawn(rand(50, 300))
- del(bh)
diff --git a/code/game/gamemodes/events/ImmovableRod.dm b/code/game/gamemodes/events/ImmovableRod.dm
deleted file mode 100644
index 27956c7e35..0000000000
--- a/code/game/gamemodes/events/ImmovableRod.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/datum/event/immovablerod
-
- Announce()
-
- immovablerod()
\ No newline at end of file
diff --git a/code/game/gamemodes/events/MeteorStorm.dm b/code/game/gamemodes/events/MeteorStorm.dm
deleted file mode 100644
index 10cb7ef676..0000000000
--- a/code/game/gamemodes/events/MeteorStorm.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/datum/event/meteorstorm
-
- Announce()
- command_alert("The station is now in a meteor shower", "Meteor Alert")
-
- Tick()
- if (prob(20))
- meteor_wave()
-
- Die()
- command_alert("The station has cleared the meteor shower", "Meteor Alert")
\ No newline at end of file
diff --git a/code/game/gamemodes/events/PowerOffline.dm b/code/game/gamemodes/events/PowerOffline.dm
deleted file mode 100644
index c6e8a8b657..0000000000
--- a/code/game/gamemodes/events/PowerOffline.dm
+++ /dev/null
@@ -1,16 +0,0 @@
-/datum/event/power_offline
- Announce()
- for(var/obj/machinery/power/apc/a in world)
- if(!a.crit && a.z == 1)
- if(istype(a.area, /area/ai_monitored/storage/eva) || istype(a.area, /area/engine)\
- || istype(a.area, /area/toxins/xenobiology) || istype(a.area, /area/turret_protected/ai))
- continue
- a.eventoff = 1
- a.update()
-
- Die()
- command_alert("The station has finished an automated power system grid check, thank you.", "Maintenance alert")
- for(var/obj/machinery/power/apc/a in world)
- if(!a.crit)
- a.eventoff = 0
- a.update()
\ No newline at end of file
diff --git a/code/game/gamemodes/events/PrisonBreak.dm b/code/game/gamemodes/events/PrisonBreak.dm
deleted file mode 100644
index e51c5c8e77..0000000000
--- a/code/game/gamemodes/events/PrisonBreak.dm
+++ /dev/null
@@ -1,30 +0,0 @@
-/datum/event/prisonbreak
-
- Announce()
-
- for (var/obj/machinery/power/apc/temp_apc in world)
- if(istype(get_area(temp_apc), /area/security/prison))
- temp_apc.overload_lighting()
- if(istype(get_area(temp_apc), /area/security/brig))
- temp_apc.overload_lighting()
- // for (var/obj/machinery/computer/prison_shuttle/temp_shuttle in world)
- // temp_shuttle.prison_break()
- for (var/obj/structure/closet/secure_closet/brig/temp_closet in world)
- if(istype(get_area(temp_closet), /area/security/prison))
- temp_closet.locked = 0
- temp_closet.icon_state = temp_closet.icon_closed
- for (var/obj/machinery/door/airlock/security/temp_airlock in world)
- if(istype(get_area(temp_airlock), /area/security/prison))
- temp_airlock.prison_open()
- if(istype(get_area(temp_airlock), /area/security/brig))
- temp_airlock.prison_open()
- for (var/obj/machinery/door/airlock/glass/glass_security/temp_glassairlock in world)
- if(istype(get_area(temp_glassairlock), /area/security/prison))
- temp_glassairlock.prison_open()
- if(istype(get_area(temp_glassairlock), /area/security/brig))
- temp_glassairlock.prison_open()
- for (var/obj/machinery/door_timer/temp_timer in world)
- if(istype(get_area(temp_timer), /area/security/brig))
- temp_timer.releasetime = 1
- sleep(150)
- command_alert("Glitch in imprisonment subroutines detected on [station_name()]. Recommend station AI involvement.", "Security Alert")
diff --git a/code/game/gamemodes/events/RadiationBelt.dm b/code/game/gamemodes/events/RadiationBelt.dm
deleted file mode 100644
index 15a4e6407c..0000000000
--- a/code/game/gamemodes/events/RadiationBelt.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-/datum/event/radiation
- var/current_iteration = 0
-
- // 50 - 20 (grace period) seconds lifetime
- Lifetime = 50
- Announce()
- command_alert("The station is now travelling through a radiation belt. Take shelter in the maintenance tunnels, or in the crew quarters!", "Medical Alert")
-
- Tick()
- current_iteration++
-
- // start radiating after 20 seconds grace period
- if(current_iteration > 20)
- for(var/mob/living/carbon/L in world)
- // check whether they're in a safe place
- // if they are, do not radiate
- var/turf/T = get_turf(L)
- if(T && ( istype(T.loc, /area/maintenance) || istype(T.loc, /area/crew_quarters) ))
- continue
-
- if (istype(L, /mob/living/carbon/monkey)) // So as to stop monkeys from dying in their pens
- L.apply_effect(rand(3,4), IRRADIATE)
- else
- L.apply_effect(rand(4,10), IRRADIATE)
-
- Die()
- command_alert("The station has cleared the radiation belt", "Medical Alert")
diff --git a/code/game/gamemodes/events/SpaceCarp.dm b/code/game/gamemodes/events/SpaceCarp.dm
deleted file mode 100644
index 5decc7636f..0000000000
--- a/code/game/gamemodes/events/SpaceCarp.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/datum/event/spacecarp
-
- Announce()
-
- for(var/obj/effect/landmark/C in world)
- if(C.name == "carpspawn")
- if(prob(99))
- new /mob/living/simple_animal/carp(C.loc)
- else
- new /mob/living/simple_animal/carp/elite(C.loc)
- //sleep(100)
- spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes.
- command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
- world << sound('commandreport.ogg')
\ No newline at end of file
diff --git a/code/game/gamemodes/events/SpaceNinja.dm b/code/game/gamemodes/events/SpaceNinja.dm
deleted file mode 100644
index 63d8211707..0000000000
--- a/code/game/gamemodes/events/SpaceNinja.dm
+++ /dev/null
@@ -1,6 +0,0 @@
-/datum/event/spaceninja
-
- Announce()
-
- if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round.
- space_ninja_arrival()//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
\ No newline at end of file
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 3329af0ee0..ecac47c66d 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -24,6 +24,7 @@
var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist
var/list/protected_jobs = list() // Jobs that can't be tratiors because
var/required_players = 0
+ var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret
var/required_enemies = 0
var/recommended_enemies = 0
var/uplink_welcome = "Syndicate Uplink Console:"
@@ -84,8 +85,13 @@ Implants;
for(var/mob/new_player/player in player_list)
if((player.client)&&(player.ready))
playerC++
- if(playerC >= required_players)
- return 1
+
+ if(master_mode=="secret")
+ if(playerC >= required_players_secret)
+ return 1
+ else
+ if(playerC >= required_players)
+ return 1
return 0
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index f1d371ee98..1fb1aff61a 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -4,7 +4,8 @@
/datum/game_mode/malfunction
name = "AI malfunction"
config_tag = "malfunction"
- required_players = 20
+ required_players = 2
+ required_players_secret = 15
required_enemies = 1
recommended_enemies = 1
diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm
index 30bb4e1d43..0f9bb44bab 100644
--- a/code/game/gamemodes/meme/meme.dm
+++ b/code/game/gamemodes/meme/meme.dm
@@ -5,7 +5,8 @@
/datum/game_mode/meme
name = "Memetic Anomaly"
config_tag = "meme"
- required_players = 6
+ required_players = 3
+ required_players_secret = 10
restricted_jobs = list("AI", "Cyborg")
recommended_enemies = 2 // need at least a meme and a host
votable = 0 // temporarily disable this mode for voting
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 71f41ca127..efa216c2ee 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -5,7 +5,8 @@
/datum/game_mode/nuclear
name = "nuclear emergency"
config_tag = "nuclear"
- required_players = 20 // 20 players - 5 players to be the nuke ops = 15 players remaining
+ required_players = 6
+ required_players_secret = 15 // 15 players - 5 players to be the nuke ops = 10 players remaining
required_enemies = 5
recommended_enemies = 5
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index bba325296e..e94baa3ede 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -15,7 +15,8 @@
name = "revolution"
config_tag = "revolution"
restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
- required_players = 20
+ required_players = 4
+ required_players_secret = 15
required_enemies = 3
recommended_enemies = 3
diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm
index 893d68749f..296792808d 100644
--- a/code/game/gamemodes/revolution/rp_revolution.dm
+++ b/code/game/gamemodes/revolution/rp_revolution.dm
@@ -3,7 +3,8 @@
/datum/game_mode/revolution/rp_revolution
name = "rp-revolution"
config_tag = "rp-revolution"
- required_players = 12
+ required_players = 4
+ required_players_secret = 12
required_enemies = 3
recommended_enemies = 3
diff --git a/code/game/gamemodes/traitor/traitor_info.dm b/code/game/gamemodes/traitor/traitor_info.dm
deleted file mode 100644
index d3d4b1a47d..0000000000
--- a/code/game/gamemodes/traitor/traitor_info.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-/datum/traitorinfo
- var/starting_objective = ""
- var/starting_player_count = 0
- var/starting_occupation = ""
- var/starting_name = ""
- var/ckey = ""
- var/list/spawnlist = list()
\ No newline at end of file
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index deb4e05d24..d086a7f6b0 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -5,7 +5,8 @@
/datum/game_mode/wizard
name = "wizard"
config_tag = "wizard"
- required_players = 20
+ required_players = 2
+ required_players_secret = 10
required_enemies = 1
recommended_enemies = 1
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index deff61f50a..b7abbce7e7 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -414,29 +414,45 @@
/proc/get_all_centcom_jobs()
return list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer","BlackOps Commander","Supreme Commander")
-/obj/proc/GetJobName()
+//gets the actual job rank (ignoring alt titles)
+//this is used solely for sechuds
+/obj/proc/GetJobRealName()
if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id))
return
- var/jobName
- var/realJobName
-
- // hack for alt titles
- if(istype(loc, /mob))
- var/mob/M = loc
- if(M.mind && M.mind.role_alt_title == jobName && M.mind.assigned_role in get_all_jobs())
- return M.mind.assigned_role
-
+ var/rank
+ var/assignment
if(istype(src, /obj/item/device/pda))
if(src:id)
- jobName = src:id:assignment
- realJobName = src:id:assignment_real_title
- if(istype(src, /obj/item/weapon/card/id))
- jobName = src:assignment
- realJobName = src:assignment_real_title
+ rank = src:id:rank
+ assignment = src:id:assignment
+ else if(istype(src, /obj/item/weapon/card/id))
+ rank = src:rank
+ assignment = src:assignment
- if( (realJobName in get_all_jobs()) || (jobName in get_all_jobs()) )
- return jobName
+ if( rank in get_all_jobs() )
+ return rank
+
+ if( assignment in get_all_jobs() )
+ return assignment
+
+ return "Unknown"
+
+//gets the alt title, failing that the actual job rank
+//this is unused
+/obj/proc/sdsdsd() //GetJobDisplayName
+ if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id))
+ return
+
+ var/assignment
+ if(istype(src, /obj/item/device/pda))
+ if(src:id)
+ assignment = src:id:assignment
+ else if(istype(src, /obj/item/weapon/card/id))
+ assignment = src:assignment
+
+ if(assignment)
+ return assignment
return "Unknown"
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index 03bf31aeb5..13444fb60b 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -11,8 +11,8 @@
req_admin_notify = 1
access = list() //See get_access()
minimal_access = list() //See get_access()
- alt_titles = list("Administrator") minimal_player_age = 14
-
+ alt_titles = list("Administrator")
+ minimal_player_age = 14
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(H), slot_ears)
@@ -55,7 +55,7 @@
selection_color = "#ddddff"
idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
- alt_titles = list("Human resources director","Executive Officer") minimal_player_age = 10
+ minimal_player_age = 10
access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers,
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index e4ca808f9a..57cc24d682 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -10,7 +10,7 @@
selection_color = "#dddddd"
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue)
minimal_access = list(access_bar)
- alt_titles = list("Waiter","Waitress")
+
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -52,7 +52,7 @@
selection_color = "#dddddd"
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue)
minimal_access = list(access_kitchen, access_morgue)
- alt_titles = list("Gourmet chef","Cook")
+ alt_titles = list("Cook")
equip(var/mob/living/carbon/human/H)
@@ -83,6 +83,7 @@
minimal_access = list(access_hydroponics, access_morgue) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
alt_titles = list("Hydroponicist")
+
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/hydroponics(H), slot_w_uniform)
@@ -111,7 +112,6 @@
selection_color = "#dddddd"
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
- alt_titles = list("Supplies Officer","Logistics Officer")
equip(var/mob/living/carbon/human/H)
@@ -142,7 +142,6 @@
selection_color = "#dddddd"
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
- alt_titles = list("Supplies worker","Courier","Logistics worker")
equip(var/mob/living/carbon/human/H)
@@ -171,7 +170,7 @@
selection_color = "#dddddd"
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
minimal_access = list(access_mining, access_mint, access_mining_station, access_mailsorting)
- alt_titles = list("Deep space miner","NTCA Affiliate","Prospector")
+ alt_titles = list("Deep space miner")
equip(var/mob/living/carbon/human/H)
@@ -283,7 +282,7 @@
selection_color = "#dddddd"
access = list(access_janitor, access_maint_tunnels)
minimal_access = list(access_janitor, access_maint_tunnels)
- alt_titles = list("Custodial officer","Hygiene supervisor","OHS assistant","Health and Safety worker")
+ alt_titles = list("Custodial officer")
equip(var/mob/living/carbon/human/H)
@@ -312,7 +311,7 @@
selection_color = "#dddddd"
access = list(access_library, access_maint_tunnels)
minimal_access = list(access_library)
- alt_titles = list("Journalist","Clerk","Record keeper")
+ alt_titles = list("Journalist")
equip(var/mob/living/carbon/human/H)
@@ -341,7 +340,7 @@ var/global/lawyer = 0//Checks for another lawyer
selection_color = "#dddddd"
access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels)
minimal_access = list(access_lawyer, access_court, access_sec_doors)
- alt_titles = list("Attourney","Barrister","Solicitor","Queen's Counsel","Paralegal")
+ alt_titles = list("Attourney", "IA Consultant")
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm
index de1e0d288e..84360efe58 100644
--- a/code/game/jobs/job/civilian_chaplain.dm
+++ b/code/game/jobs/job/civilian_chaplain.dm
@@ -10,7 +10,7 @@
selection_color = "#dddddd"
access = list(access_morgue, access_chapel_office, access_crematorium, access_maint_tunnels)
minimal_access = list(access_morgue, access_chapel_office, access_crematorium)
- alt_titles = list("Counselor","Psychiatrist","Crew services adviser","Morale Officer")
+ alt_titles = list("Counselor")
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index e6515c0696..7fa8ee5b65 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -9,7 +9,6 @@
selection_color = "#ffeeaa"
idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
- alt_titles = list("Engineering supervisor")
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction, access_sec_doors,
@@ -56,7 +55,6 @@
alt_titles = list("Technician","Maintenance technician","Engine technician","EVA technician","Electrician","Construction specialist")
-
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_eng(H), slot_ears)
@@ -89,7 +87,6 @@
selection_color = "#fff5cc"
access = list(access_eva, access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction, access_atmospherics)
minimal_access = list(access_atmospherics, access_maint_tunnels, access_emergency_storage, access_construction)
- alt_titles = list("Pipeworker","Gas supervisor","Firefighter")
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index 9447ad920a..1e8c65eb63 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -130,7 +130,6 @@
selection_color = "#ffeef0"
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_research)
minimal_access = list(access_medical, access_morgue, access_genetics, access_research)
- alt_titles = list("Sequencer")
equip(var/mob/living/carbon/human/H)
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index 46397ee7eb..8e0bbe7938 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -46,7 +46,7 @@
selection_color = "#ffeeff"
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology)
minimal_access = list(access_tox, access_tox_storage, access_research, access_xenobiology)
- alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher", "Xenobiologist","High Energy Materials Researcher")
+ alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher", "Xenobiologist")
equip(var/mob/living/carbon/human/H)
if(!H) return 0
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index bc9d0c80a9..98c255b7dc 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -9,7 +9,6 @@
selection_color = "#ffdddd"
idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
- alt_titles = list("Commander","Commissioner")
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
@@ -56,9 +55,8 @@
spawn_positions = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
- access access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue)
- = list(access_security, access_sec_doors, access_brig, access_armory, access_court)
- alt_titles = list("Arsenal clerk","Brig supervisor","Superintendant") minimal_access = list(access_security, access_sec_doors, access_brig, access_armory, access_court)
+ access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue)
+ minimal_access = list(access_security, access_sec_doors, access_brig, access_armory, access_court)
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
@@ -98,7 +96,7 @@
access = list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
minimal_access = list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
- alt_titles = list("Forensic Technician","Investigator")
+ alt_titles = list("Forensic Technician")
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -145,8 +143,7 @@
selection_color = "#ffeeee"
access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue)
minimal_access = list(access_security, access_sec_doors, access_brig, access_court)
- alt_titles = list("OHS marshal","Enforcer") minimal_player_age = 7
-
+ minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index b9165d0e39..7787d3e996 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -38,8 +38,8 @@ var/global/datum/controller/occupations/job_master
if(J.title == rank) return J
return null
- proc/GetAltTitle(mob/new_player/player, rank)
- return player.client.prefs.GetAltTitle(GetJob(rank))
+ proc/GetPlayerAltTitle(mob/new_player/player, rank)
+ return player.client.prefs.GetPlayerAltTitle(GetJob(rank))
proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0)
Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
@@ -54,7 +54,7 @@ var/global/datum/controller/occupations/job_master
if((job.current_positions < position_limit) || position_limit == -1)
Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
player.mind.assigned_role = rank
- player.mind.role_alt_title = GetAltTitle(player, rank)
+ player.mind.role_alt_title = GetPlayerAltTitle(player, rank)
unassigned -= player
job.current_positions++
return 1
@@ -311,9 +311,6 @@ var/global/datum/controller/occupations/job_master
H << "Your job is [rank] and the game just can't handle it! Please report this bug to an administrator."
H.job = rank
- if(H.mind && H.mind.assigned_role != rank)
- H.mind.assigned_role = rank
- H.mind.role_alt_title = null
if(!joined_late)
var/obj/S = null
@@ -331,6 +328,7 @@ var/global/datum/controller/occupations/job_master
if(H.mind)
H.mind.assigned_role = rank
+ H.mind.role_alt_title = null
switch(rank)
if("Cyborg")
@@ -359,10 +357,7 @@ var/global/datum/controller/occupations/job_master
if(job.req_admin_notify)
H << "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp."
- if(H.mind.assigned_role == rank && H.mind.role_alt_title)
- spawnId(H, rank, H.mind.role_alt_title)
- else
- spawnId(H,rank)
+ spawnId(H, rank, H.mind.role_alt_title)
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_ears)
// H.update_icons()
return 1
@@ -370,7 +365,6 @@ var/global/datum/controller/occupations/job_master
proc/spawnId(var/mob/living/carbon/human/H, rank, title)
if(!H) return 0
- if(!title) title = rank
var/obj/item/weapon/card/id/C = null
var/datum/job/job = null
@@ -389,7 +383,8 @@ var/global/datum/controller/occupations/job_master
C = new /obj/item/weapon/card/id(H)
if(C)
C.registered_name = H.real_name
- C.assignment = title
+ C.rank = rank
+ C.assignment = title ? title : rank
C.name = "[C.registered_name]'s ID Card ([C.assignment])"
H.equip_to_slot_or_del(C, slot_wear_id)
H.equip_to_slot_or_del(new /obj/item/device/pda(H), slot_belt)
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index fc422d6d87..a32e9ea134 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -232,8 +232,9 @@
var/t1 = href_list["assign_target"]
if(t1 == "Custom")
var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,MAX_MESSAGE_LEN)
- if(temp_t)
- t1 = temp_t
+ //let custom jobs function as an impromptu alt title, mainly for sechuds
+ if(temp_t && modify)
+ modify.assignment = temp_t
else
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
@@ -246,8 +247,9 @@
return
modify.access = ( istype(src,/obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() )
- if (modify)
- modify.assignment = t1
+ if (modify)
+ modify.assignment = t1
+ modify.rank = t1
if ("reg")
if (authenticated)
var/t2 = modify
diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm
index 23c1c3b4a2..978db653f9 100644
--- a/code/game/machinery/computer/shuttle.dm
+++ b/code/game/machinery/computer/shuttle.dm
@@ -52,7 +52,7 @@
world << text("\blue Alert: [] authorizations needed until shuttle is launched early", src.auth_need - src.authorized.len)
if("Abort")
- world << "\blue All authorizations to shorting time for shuttle launch have been revoked!"
+ world << "\blue All authorizations to shortening time for shuttle launch have been revoked!"
src.authorized.len = 0
src.authorized = list( )
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 1ce9bf3775..1a78d4be75 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -4,7 +4,7 @@
icon_state = "cell-off"
density = 1
anchored = 1.0
- layer = 5
+ layer = 2.8
var/on = 0
var/temperature_archived
diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm
index aec6290da7..629b979731 100644
--- a/code/game/machinery/hydroponics.dm
+++ b/code/game/machinery/hydroponics.dm
@@ -1,3 +1,5 @@
+#define SPEED_MULTIPLIER 0.5
+
/obj/machinery/hydroponics
name = "hydroponics tray"
icon = 'icons/obj/hydroponics.dmi'
@@ -45,42 +47,42 @@ obj/machinery/hydroponics/process()
lastcycle = world.time
if(planted && !dead)
// Advance age
- age++
+ age += 1 * SPEED_MULTIPLIER
//Nutrients//////////////////////////////////////////////////////////////
// Nutrients deplete slowly
if(nutrilevel > 0)
if(prob(50))
- nutrilevel -= 1
+ nutrilevel -= 1 * SPEED_MULTIPLIER
// Lack of nutrients hurts non-weeds
if(nutrilevel <= 0 && myseed.plant_type != 1)
- health -= rand(1,3)
+ health -= rand(1,3) * SPEED_MULTIPLIER
//Water//////////////////////////////////////////////////////////////////
// Drink random amount of water
- waterlevel = max(waterlevel - rand(1,6), 0)
+ waterlevel = max(waterlevel - rand(1,6) * SPEED_MULTIPLIER, 0)
// If the plant is dry, it loses health pretty fast, unless mushroom
if(waterlevel <= 10 && myseed.plant_type != 2)
- health -= rand(0,1)
+ health -= rand(0,1) * SPEED_MULTIPLIER
if(waterlevel <= 0)
- health -= rand(0,2)
+ health -= rand(0,2) * SPEED_MULTIPLIER
// Sufficient water level and nutrient level = plant healthy
else if(waterlevel > 10 && nutrilevel > 0)
- health += rand(1,2)
+ health += rand(1,2) * SPEED_MULTIPLIER
if(prob(5)) //5 percent chance the weed population will increase
- weedlevel += 1
+ weedlevel += 1 * SPEED_MULTIPLIER
//Toxins/////////////////////////////////////////////////////////////////
// Too much toxins cause harm, but when the plant drinks the contaiminated water, the toxins disappear slowly
if(toxic >= 40 && toxic < 80)
- health -= 1
- toxic -= rand(1,10)
+ health -= 1 * SPEED_MULTIPLIER
+ toxic -= rand(1,10) * SPEED_MULTIPLIER
else if(toxic >= 80) // I don't think it ever gets here tbh unless above is commented out
- health -= 3
- toxic -= rand(1,10)
+ health -= 3 * SPEED_MULTIPLIER
+ toxic -= rand(1,10) * SPEED_MULTIPLIER
else if(toxic < 0) // Make sure it won't go overoboard
toxic = 0
@@ -91,11 +93,11 @@ obj/machinery/hydroponics/process()
pestlevel = 10
else if(pestlevel >= 5)
- health -= 1
+ health -= 1 * SPEED_MULTIPLIER
// If it's a weed, it doesn't stunt the growth
if(weedlevel >= 5 && myseed.plant_type != 1 )
- health -= 1
+ health -= 1 * SPEED_MULTIPLIER
//Health & Age///////////////////////////////////////////////////////////
@@ -107,12 +109,12 @@ obj/machinery/hydroponics/process()
else if(health <= 0)
dead = 1
harvest = 0
- weedlevel += 1 // Weeds flourish
+ weedlevel += 1 * SPEED_MULTIPLIER // Weeds flourish
pestlevel = 0 // Pests die
// If the plant is too old, lose health fast
if(age > myseed.lifespan)
- health -= rand(1,5)
+ health -= rand(1,5) * SPEED_MULTIPLIER
// Harvest code
if(age > myseed.production && (age - lastproduce) > myseed.production && (!harvest && !dead))
@@ -129,10 +131,10 @@ obj/machinery/hydroponics/process()
else
lastproduce = age
if(prob(5)) // On each tick, there's a 5 percent chance the pest population will increase
- pestlevel += 1
+ pestlevel += 1 * SPEED_MULTIPLIER
else
if(waterlevel > 10 && nutrilevel > 0 && prob(10)) // If there's no plant, the percentage chance is 10%
- weedlevel += 1
+ weedlevel += 1 * SPEED_MULTIPLIER
if(weedlevel > 10)
weedlevel = 10
@@ -712,6 +714,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
user.visible_message("\red [user] starts uprooting the weeds.", "\red You remove the weeds from the [src].")
weedlevel = 0
updateicon()
+ src.updateicon()
else
user << "\red This plot is completely devoid of weeds. It doesn't need uprooting."
@@ -1037,4 +1040,6 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
SetLuminosity(round(myseed.potency/10))
else
SetLuminosity(0)
- return
\ No newline at end of file
+ return
+
+#undef SPEED_MULTIPLIER
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index ba755b336f..6c62365fdb 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -72,6 +72,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
*/
var/global/list/datum/stack_recipe/plasteel_recipes = list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1), \
+ new/datum/stack_recipe("Metal crate", /obj/structure/closet/crate, 10, time = 50, one_per_turf = 1), \
)
/obj/item/stack/sheet/plasteel
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index a15454696f..6c3814a801 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -167,6 +167,7 @@
src.add_fingerprint(user)
if (src.bullets < 1)
user.show_message("\red *click* *click*", 2)
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
playsound(user, 'sound/weapons/Gunshot.ogg', 100, 1)
src.bullets--
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 0ebd8ed7a0..649a4fe713 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -16,6 +16,7 @@
desc = "Does card things."
icon = 'icons/obj/card.dmi'
w_class = 1.0
+ var/associated_account_number = 0
var/list/files = list( )
@@ -74,8 +75,9 @@
var/dna_hash = "\[UNSET\]"
var/fingerprint_hash = "\[UNSET\]"
- var/assignment = null
- var/assignment_real_title = null
+ //alt titles are handled a bit weirdly in order to unobtrusively integrate into existing ID system
+ var/assignment = null //can be alt title or the actual job
+ var/rank = null //actual job
var/dorm = 0 // determines if this ID has claimed a dorm already
/obj/item/weapon/card/id/attack_self(mob/user as mob)
diff --git a/code/global.dm b/code/global.dm
index 62c22b4662..8e1c8dc1c9 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -70,7 +70,7 @@ var/blobevent = 0
var/diary = null
var/diaryofmeanpeople = null
var/href_logfile = null
-var/station_name = "NSV Exodus"
+var/station_name = "NSS Exodus"
var/game_version = "Baystation12"
var/changelog_hash = ""
diff --git a/code/modules/DetectiveWork/evidence.dm b/code/modules/DetectiveWork/evidence.dm
index 4ced7b7ce8..80955a8214 100644
--- a/code/modules/DetectiveWork/evidence.dm
+++ b/code/modules/DetectiveWork/evidence.dm
@@ -8,7 +8,6 @@
item_state = ""
w_class = 1
-/obj/item/weapon/evidencebag/afterattack(obj/item/O, mob/user as mob)
/obj/item/weapon/evidencebag/afterattack(obj/item/I, mob/user as mob)
if(!in_range(I, user))
return
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index c5ec703f82..45fa42a6ca 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -91,7 +91,7 @@ datum/preferences
// will probably not be able to do this for head and torso ;)
var/list/organ_data = list()
- var/list/job_alt_titles = new() // the default name of a job like "Medical Doctor"
+ var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor"
var/flavor_text = ""
var/med_record = ""
@@ -429,7 +429,7 @@ datum/preferences
else
HTML += " \[NEVER]"
if(job.alt_titles)
- HTML += "
\[[GetAltTitle(job)]\]"
+ HTML += "
\[[GetPlayerAltTitle(job)]\]"
HTML += ""
HTML += ""
@@ -491,18 +491,18 @@ datum/preferences
user << browse(HTML, "window=records;size=350x300")
return
- proc/GetAltTitle(datum/job/job)
- return job_alt_titles.Find(job.title) > 0 \
- ? job_alt_titles[job.title] \
+ proc/GetPlayerAltTitle(datum/job/job)
+ return player_alt_titles.Find(job.title) > 0 \
+ ? player_alt_titles[job.title] \
: job.title
- proc/SetAltTitle(datum/job/job, new_title)
+ proc/SetPlayerAltTitle(datum/job/job, new_title)
// remove existing entry
- if(job_alt_titles.Find(job.title))
- job_alt_titles -= job.title
+ if(player_alt_titles.Find(job.title))
+ player_alt_titles -= job.title
// add one if it's not default
if(job.title != new_title)
- job_alt_titles[job.title] = new_title
+ player_alt_titles[job.title] = new_title
proc/SetJob(mob/user, role)
var/datum/job/job = job_master.GetJob(role)
@@ -642,9 +642,9 @@ datum/preferences
var/datum/job/job = locate(href_list["job"])
if (job)
var/choices = list(job.title) + job.alt_titles
- var/choice = input("Pick a title for [job.title].", "Character Generation", GetAltTitle(job)) as anything in choices | null
+ var/choice = input("Pick a title for [job.title].", "Character Generation", GetPlayerAltTitle(job)) as anything in choices | null
if(choice)
- SetAltTitle(job, choice)
+ SetPlayerAltTitle(job, choice)
SetChoices(user)
if("input")
SetJob(user, href_list["text"])
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index fd1ec7ec71..80d5e718df 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -138,7 +138,7 @@
S["sec_record"] >> sec_record
S["be_special"] >> be_special
S["disabilities"] >> disabilities
- S["job_alt_titles"] >> job_alt_titles
+ S["player_alt_titles"] >> player_alt_titles
S["used_skillpoints"] >> used_skillpoints
S["skills"] >> skills
S["skill_specialization"] >> skill_specialization
@@ -182,7 +182,7 @@
if(!skills) skills = list()
if(!used_skillpoints) used_skillpoints= 0
if(isnull(disabilities)) disabilities = 0
- if(!job_alt_titles) job_alt_titles = new()
+ if(!player_alt_titles) player_alt_titles = new()
if(!organ_data) src.organ_data = list()
//if(!skin_style) skin_style = "Default"
@@ -232,7 +232,7 @@
S["flavor_text"] << flavor_text
S["med_record"] << med_record
S["sec_record"] << sec_record
- S["job_alt_titles"] << job_alt_titles
+ S["player_alt_titles"] << player_alt_titles
S["be_special"] << be_special
S["used_skillpoints"] << used_skillpoints
S["skills"] << skills
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 97ed07c7bb..3b07fc26ac 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -83,17 +83,16 @@
var/icon/tempHud = 'icons/mob/hud.dmi'
for(var/mob/living/carbon/human/perp in view(M))
if(!C) continue
- var/perpname = "wot"
+ var/perpname = perp.name
if(perp.wear_id)
var/obj/item/weapon/card/id/I = perp.wear_id.GetID()
if(I)
- C.images += image(tempHud, perp, "hud[ckey(I.GetJobName())]")
+ C.images += image(tempHud, perp, "hud[ckey(I.GetJobRealName())]")
perpname = I.registered_name
else
perpname = perp.name
C.images += image(tempHud, perp, "hudunknown")
else
- perpname = perp.name
C.images += image(tempHud, perp, "hudunknown")
for(var/datum/data/record/E in data_core.general)
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index 3a02b9fca5..4a0c9a6103 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -28,6 +28,7 @@
var/amt_plasma = 0
var/amt_uranium = 0
var/amt_clown = 0
+ var/amt_strange = 0
for (var/obj/item/weapon/ore/C in contents)
@@ -47,6 +48,8 @@
amt_uranium++;
if (istype(C,/obj/item/weapon/ore/clown))
amt_clown++;
+ if (istype(C,/obj/item/weapon/ore/strangerock))
+ amt_strange++;
var/dat = text("The contents of the ore box reveal...
")
if (amt_gold)
@@ -65,6 +68,8 @@
dat += text("Uranium ore: [amt_uranium]
")
if (amt_clown)
dat += text("Bananium ore: [amt_clown]
")
+ if (amt_strange)
+ dat += text("Strange rocks: [amt_strange]
")
dat += text("
Empty box")
user << browse("[dat]", "window=orebox")
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 43eb1b3ba5..58f226d21f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -258,3 +258,31 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
see_invisible = SEE_INVISIBLE_OBSERVER
else
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
+
+/mob/dead/observer/verb/become_mouse()
+ set name = "Become mouse"
+ set category = "Ghost"
+
+ //find a viable mouse candidate
+ var/mob/living/simple_animal/mouse/host
+ var/list/mouse_candidates = list()
+ for(var/mob/living/simple_animal/mouse/M in world)
+ if(!M.ckey && !M.stat)
+ mouse_candidates.Add(M)
+ if(mouse_candidates.len)
+ host = pick(mouse_candidates)
+ else
+ var/obj/machinery/atmospherics/unary/vent_pump/vent_found
+ var/list/found_vents = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in world)
+ if(!v.welded && v.z == src.z)
+ found_vents.Add(v)
+ if(found_vents.len)
+ vent_found = pick(found_vents)
+ host = new /mob/living/simple_animal/mouse(vent_found.loc)
+ else
+ src << "Unable to find any live mice, or unwelded vents to spawn one at."
+
+ if(host)
+ host.ckey = src.ckey
+ host << "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent."
diff --git a/code/modules/mob/living/silicon/pai/hud.dm b/code/modules/mob/living/silicon/pai/hud.dm
index d2f96656d6..c900ef60a8 100644
--- a/code/modules/mob/living/silicon/pai/hud.dm
+++ b/code/modules/mob/living/silicon/pai/hud.dm
@@ -10,7 +10,7 @@
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/living/carbon/human/perp in view(T))
if(perp.wear_id)
- client.images += image(tempHud,perp,"hud[ckey(perp:wear_id:GetJobName())]")
+ client.images += image(tempHud,perp,"hud[ckey(perp:wear_id:GetJobRealName())]")
var/perpname = "wot"
if(istype(perp.wear_id,/obj/item/weapon/card/id))
perpname = perp.wear_id:registered_name
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index f1eb5695aa..d029320a67 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -319,8 +319,9 @@
if(job && IsJobAvailable(job.title))
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
- for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_job == job && M.client.inactivity <= 10 * 60 * 10)
- active++
+ for(var/mob/M in player_list)
+ if(M.mind && M.mind.assigned_job == job && M.client && M.client.inactivity <= 10 * 60 * 10)
+ active++
dat += "[job.title] ([job.current_positions]) (Active: [active])
"
dat += ""
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 9d9e824f98..d97115d777 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -75,6 +75,7 @@
return
if(!load_into_chamber())
user << "\red *click*";
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
if(!in_chamber)
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 9b9ea0f9b6..0f6fca68b2 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -143,6 +143,7 @@
if(!loaded.len)
user.visible_message("\red *click*", "\red *click*")
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
if(isliving(target) && isliving(user))
@@ -153,6 +154,7 @@
var/obj/item/ammo_casing/AC = loaded[1]
if(!load_into_chamber())
user.visible_message("\red *click*", "\red *click*")
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
if(!in_chamber)
return
diff --git a/code/modules/research/xenoarchaeology/finds.dm b/code/modules/research/xenoarchaeology/finds.dm
index a834b96f69..b3060a2515 100644
--- a/code/modules/research/xenoarchaeology/finds.dm
+++ b/code/modules/research/xenoarchaeology/finds.dm
@@ -79,6 +79,8 @@
R.source_rock = src.source_rock
R.geological_data = src.geological_data
user << "\blue You take a core sample of the [src]."
+ else
+ ..()
/*Code does not work, likely due to removal/change of acid_act proc
//Strange rocks currently melt to gooey grey w/ acid application (see reactions)
diff --git a/html/changelog.html b/html/changelog.html
index 11f1a88723..5df543125a 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -59,6 +59,7 @@ should be listed in the changelog upon commit though. Thanks. -->
+
January 23rd
Cael_Aislinn updated:
@@ -67,6 +68,15 @@ should be listed in the changelog upon commit though. Thanks. -->
+
+
January 21st
+
Cael_Aislinn updated:
+
+ - Satchels and ore boxes can now hold strange rocks.
+ - Closets and crates can now be built out of 5 and 10 plasteel respectively.
+ - Observers can become mice once more.
+
+
13/01/2013
@@ -126,6 +136,39 @@ should be listed in the changelog upon commit though. Thanks. -->
+
+
November 2012 - January 2013
+
chinsky updated:
+
+ - Several cargo crates from pre-merge were ported.
+ - Contraband crate is no longer labeled as such.
+ - In space, no one can hear you scream now.
+
+
CIB updated:
+
+ - Airflow produces subtle sound effects now.
+ - Events are now adjusted based on department activity.
+ - The virus event will spawn BS12 vira.
+ - Two new traitor objectives: Brig and Harm
+ - Space no longer makes rooms cold.
+ - Gibbing creates actual limbs you can pick up, if you're lucky a complete head with brain.
+ - It's now possible to miss in combat(melee and guns), instead of just hitting the torso rather than the head. This makes targetting the head much riskier than before.
+ - Chemicals now last 10x as long in the blood, but their effect is also reduced equally.
+ - IV drips now have a right-click option to take blood rather than give it.
+ - Everyone gets a crew manifest.
+
+
CaelAislinn updated:
+
+ - There now is a client-toggle for whether to become a space-ninja.
+ - Reduced startup lag by removing a vermin-related proc.
+ - Several alien balance fixes.
+
+
Ravensdale updated:
+
+ - Ported station-wide explosion sounds.
+
+
+
December 3rd
Cael_Aislinn updated:
diff --git a/icons/obj/terminals.dmi b/icons/obj/terminals.dmi
index a3ad55381a..ab3d80a03c 100644
Binary files a/icons/obj/terminals.dmi and b/icons/obj/terminals.dmi differ