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 += "
" + dat += "" + dat += "" + dat += "Holder name:
" + dat += "Initial funds: (subtracted from station account)
" + dat += "New accounts are automatically assigned a secret number and pin, which are printed separately in a sealed package.
" + dat += "
" + 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 += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + for(var/datum/transaction/T in detailed_account_view.transaction_log) + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
DateTimeTargetPurposeValueSource terminal ID
[T.date][T.time][T.target_name][T.purpose]$[T.amount][T.source_terminal]
" + 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 += "" + dat += "" + dat += "" + dat += "" + dat += "
#[D.account_number][D.owner_name]View in detail
" + + 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 += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + for(var/datum/transaction/T in authenticated_account.transaction_log) + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
DateTimeTargetPurposeValueSource terminal ID
[T.date][T.time][T.target_name][T.purpose]$[T.amount][T.source_terminal]
" + if(TRANSFER_FUNDS) + dat += "Account balance: $[authenticated_account.money]
" + dat += "Back

" + dat += "
" + dat += "" + dat += "" + dat += "Target account number:
" + dat += "Funds to transfer:
" + dat += "Transaction purpose:
" + dat += "
" + dat += "
" + else + dat += "Welcome, [authenticated_account.owner_name].
" + dat += "Account balance: $[authenticated_account.money]" + dat += "
" + dat += "" + dat += "" + dat += "
" + dat += "
" + dat += "Change account security level
" + dat += "Make transfer
" + dat += "View transaction log
" + dat += "Print balance statement
" + dat += "Logout
" + else if(linked_db) + dat += "
" + dat += "" + dat += "" + dat += "Account:
" + dat += "PIN:
" + dat += "
" + 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