mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 16:44:33 +01:00
Merge branch 'bleeding-edge-freeze' of https://github.com/Baystation12/Baystation12 into bleeding-edge-freeze
Conflicts: html/changelog.html Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
var/global/current_date_string
|
||||
var/global/num_financial_terminals = 1
|
||||
var/global/datum/money_account/station_account
|
||||
var/global/list/datum/money_account/department_accounts = list()
|
||||
var/global/next_account_number = 0
|
||||
var/global/obj/machinery/account_database/centcomm_account_db
|
||||
|
||||
@@ -28,6 +29,31 @@ var/global/obj/machinery/account_database/centcomm_account_db
|
||||
for(var/obj/machinery/account_database/A in world)
|
||||
A.accounts.Add(station_account)
|
||||
|
||||
/proc/create_department_account(department)
|
||||
next_account_number = rand(111111, 999999)
|
||||
|
||||
var/datum/money_account/department_account = new()
|
||||
department_account.owner_name = "[department] Account"
|
||||
department_account.account_number = rand(111111, 999999)
|
||||
department_account.remote_access_pin = rand(1111, 111111)
|
||||
department_account.money = 5000
|
||||
|
||||
//create an entry in the account transaction log for when it was created
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = department_account.owner_name
|
||||
T.purpose = "Account creation"
|
||||
T.amount = department_account.money
|
||||
T.date = "2nd April, 2555"
|
||||
T.time = "11:24"
|
||||
T.source_terminal = "Biesel GalaxyNet Terminal #277"
|
||||
|
||||
//add the account
|
||||
department_account.transaction_log.Add(T)
|
||||
for(var/obj/machinery/account_database/A in world)
|
||||
A.accounts.Add(department_account)
|
||||
|
||||
department_accounts[department] = department_account
|
||||
|
||||
//the current ingame time (hh:mm) can be obtained by calling:
|
||||
//worldtime2text()
|
||||
|
||||
@@ -70,6 +96,10 @@ var/global/obj/machinery/account_database/centcomm_account_db
|
||||
if(!station_account)
|
||||
create_station_account()
|
||||
|
||||
if(department_accounts.len == 0)
|
||||
for(var/department in station_departments)
|
||||
create_department_account(department)
|
||||
|
||||
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"
|
||||
|
||||
@@ -82,7 +112,7 @@ var/global/obj/machinery/account_database/centcomm_account_db
|
||||
dat += "Confirm identity: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card : "-----"]</a><br>"
|
||||
|
||||
if(access_level > 0)
|
||||
dat += "<a href='?src=\ref[src];toggle_activated=1'>Toggle remote access to this database (warning!)</a>"
|
||||
dat += "<a href='?src=\ref[src];toggle_activated=1'>[activated ? "Disable" : "Enable"] remote access</a><br>"
|
||||
dat += "You may not edit accounts at this terminal, only create and view them.<br>"
|
||||
if(creating_new_account)
|
||||
dat += "<br>"
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian")
|
||||
|
||||
// The department the job belongs to.
|
||||
/datum/job/var/department = null
|
||||
|
||||
// Whether this is a head position
|
||||
/datum/job/var/head_position = 0
|
||||
|
||||
/datum/job/captain/department = "Command"
|
||||
/datum/job/captain/head_position = 1
|
||||
|
||||
/datum/job/hop/department = "Civilian"
|
||||
/datum/job/hop/head_position = 1
|
||||
|
||||
/datum/job/assistant/department = "Civilian"
|
||||
|
||||
/datum/job/bartender/department = "Civilian"
|
||||
|
||||
/datum/job/chef/department = "Civilian"
|
||||
|
||||
/datum/job/hydro/department = "Civilian"
|
||||
|
||||
/datum/job/mining/department = "Civilian"
|
||||
|
||||
/datum/job/janitor/department = "Civilian"
|
||||
|
||||
/datum/job/librarian/department = "Civilian"
|
||||
|
||||
/datum/job/lawyer/department = "Civilian"
|
||||
|
||||
/datum/job/chaplain/department = "Civilian"
|
||||
|
||||
/datum/job/qm/department = "Cargo"
|
||||
/datum/job/qm/head_position = 1
|
||||
|
||||
/datum/job/cargo_tech/department = "Cargo"
|
||||
|
||||
/datum/job/chief_engineer/department = "Engineering"
|
||||
/datum/job/chief_engineer/head_position = 1
|
||||
|
||||
/datum/job/engineer/department = "Engineering"
|
||||
|
||||
/datum/job/atmos/department = "Engineering"
|
||||
|
||||
/datum/job/cmo/department = "Medical"
|
||||
/datum/job/cmo/head_position = 1
|
||||
|
||||
/datum/job/doctor/department = "Medical"
|
||||
|
||||
/datum/job/chemist/department = "Medical"
|
||||
|
||||
/datum/job/geneticist/department = "Medical"
|
||||
|
||||
/datum/job/psychiatrist/department = "Medical"
|
||||
|
||||
/datum/job/rd/department = "Science"
|
||||
/datum/job/rd/head_position = 1
|
||||
|
||||
/datum/job/scientist/department = "Science"
|
||||
|
||||
/datum/job/roboticist/department = "Science"
|
||||
|
||||
/datum/job/hos/department = "Security"
|
||||
/datum/job/hos/head_position = 1
|
||||
|
||||
/datum/job/warden/department = "Security"
|
||||
|
||||
/datum/job/detective/department = "Security"
|
||||
|
||||
/datum/job/officer/department = "Security"
|
||||
@@ -43,7 +43,7 @@ log transactions
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
|
||||
if(linked_db && linked_db.stat & NOPOWER)
|
||||
if(linked_db && ( (linked_db.stat & NOPOWER) || !linked_db.activated ) )
|
||||
linked_db = null
|
||||
authenticated_account = null
|
||||
src.visible_message("\red \icon[src] [src] buzzes rudely, \"Connection to remote database lost.\"")
|
||||
@@ -68,7 +68,7 @@ log transactions
|
||||
|
||||
/obj/machinery/atm/proc/reconnect_database()
|
||||
for(var/obj/machinery/account_database/DB in world)
|
||||
if(DB.z == src.z && !DB.stat & NOPOWER)
|
||||
if( DB.z == src.z && !(DB.stat & NOPOWER) && DB.activated )
|
||||
linked_db = DB
|
||||
break
|
||||
|
||||
@@ -259,7 +259,7 @@ log transactions
|
||||
T.time = worldtime2text()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
else
|
||||
usr << "\red \icon[src] incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining."
|
||||
usr << "\red \icon[src] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining."
|
||||
previous_account_number = tried_account_num
|
||||
playsound(src, 'buzz-sigh.ogg', 50, 1)
|
||||
else
|
||||
@@ -279,6 +279,8 @@ log transactions
|
||||
T.time = worldtime2text()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
|
||||
usr << "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'"
|
||||
|
||||
previous_account_number = tried_account_num
|
||||
if("withdrawal")
|
||||
var/amount = max(text2num(href_list["funds_amount"]),0)
|
||||
@@ -342,8 +344,8 @@ log transactions
|
||||
held_card = I
|
||||
if("logout")
|
||||
authenticated_account = null
|
||||
usr << browse(null,"window=atm")
|
||||
return
|
||||
//usr << browse(null,"window=atm")
|
||||
|
||||
src.attack_hand(usr)
|
||||
|
||||
//create the most effective combination of notes to make up the requested amount
|
||||
@@ -385,3 +387,14 @@ log transactions
|
||||
I = P.id
|
||||
if(I)
|
||||
authenticated_account = linked_db.attempt_account_access(I.associated_account_number)
|
||||
if(authenticated_account)
|
||||
human_user << "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'"
|
||||
|
||||
//create a transaction log entry
|
||||
var/datum/transaction/T = new()
|
||||
T.target_name = authenticated_account.owner_name
|
||||
T.purpose = "Remote terminal access"
|
||||
T.source_terminal = machine_id
|
||||
T.date = current_date_string
|
||||
T.time = worldtime2text()
|
||||
authenticated_account.transaction_log.Add(T)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
@@ -0,0 +1,405 @@
|
||||
|
||||
// Basic transit tubes. Straight pieces, curved sections,
|
||||
// and basic splits/joins (no routing logic).
|
||||
// Mappers: you can use "Generate Instances from Icon-states"
|
||||
// to get the different pieces.
|
||||
/obj/structure/transit_tube
|
||||
icon = 'transit_tube.dmi'
|
||||
icon_state = "E-W"
|
||||
density = 1
|
||||
layer = 3.1
|
||||
anchored = 1.0
|
||||
var/list/tube_dirs = null
|
||||
var/exit_delay = 2
|
||||
var/enter_delay = 1
|
||||
|
||||
|
||||
// A place where tube pods stop, and people can get in or out.
|
||||
// Mappers: use "Generate Instances from Directions" for this
|
||||
// one.
|
||||
/obj/structure/transit_tube/station
|
||||
icon = 'transit_tube_station.dmi'
|
||||
icon_state = "closed"
|
||||
exit_delay = 2
|
||||
enter_delay = 3
|
||||
var/pod_moving = 0
|
||||
var/automatic_launch_time = 100
|
||||
|
||||
var/const/OPEN_DURATION = 6
|
||||
var/const/CLOSE_DURATION = 6
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod
|
||||
icon = 'transit_tube_pod.dmi'
|
||||
icon_state = "pod"
|
||||
animate_movement = FORWARD_STEPS
|
||||
var/moving = 0
|
||||
var/datum/gas_mixture/air_contents
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/New(loc)
|
||||
..(loc)
|
||||
|
||||
spawn(automatic_launch_time)
|
||||
launch_pod()
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
|
||||
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
AM.loc = pod
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
|
||||
if(!pod_moving)
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
if(icon_state == "closed")
|
||||
open_animation()
|
||||
|
||||
else if(icon_state == "open")
|
||||
close_animation()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/open_animation()
|
||||
if(icon_state == "closed")
|
||||
icon_state = "opening"
|
||||
spawn(OPEN_DURATION)
|
||||
if(icon_state == "opening")
|
||||
icon_state = "open"
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/close_animation()
|
||||
if(icon_state == "open")
|
||||
icon_state = "closing"
|
||||
spawn(CLOSE_DURATION)
|
||||
if(icon_state == "closing")
|
||||
icon_state = "closed"
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/launch_pod()
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
spawn(5)
|
||||
pod_moving = 1
|
||||
close_animation()
|
||||
sleep(CLOSE_DURATION + 2)
|
||||
if(icon_state == "closed" && pod)
|
||||
pod.follow_tube()
|
||||
|
||||
pod_moving = 0
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
|
||||
pod_moving = 1
|
||||
spawn(5)
|
||||
open_animation()
|
||||
sleep(OPEN_DURATION + 2)
|
||||
pod_moving = 0
|
||||
pod.mix_air()
|
||||
|
||||
if(automatic_launch_time)
|
||||
var/const/wait_step = 5
|
||||
var/i = 0
|
||||
while(i < automatic_launch_time)
|
||||
sleep(wait_step)
|
||||
i += wait_step
|
||||
|
||||
if(pod_moving || icon_state != "open")
|
||||
return
|
||||
|
||||
launch_pod()
|
||||
|
||||
|
||||
|
||||
// Returns a /list of directions this tube section can
|
||||
// connect to.
|
||||
/obj/structure/transit_tube/proc/directions()
|
||||
return tube_dirs
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/has_entrance(from_dir)
|
||||
from_dir = turn(from_dir, 180)
|
||||
|
||||
for(var/direction in directions())
|
||||
if(direction == from_dir)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/has_exit(in_dir)
|
||||
for(var/direction in directions())
|
||||
if(direction == in_dir)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
// Searches for an exit direction within 45 degrees of the
|
||||
// specified dir. Returns that direction, or 0 if none match.
|
||||
/obj/structure/transit_tube/proc/get_exit(in_dir)
|
||||
var/near_dir = 0
|
||||
var/in_dir_cw = turn(in_dir, -45)
|
||||
var/in_dir_ccw = turn(in_dir, 45)
|
||||
|
||||
for(var/direction in directions())
|
||||
if(direction == in_dir)
|
||||
return direction
|
||||
|
||||
else if(direction == in_dir_cw)
|
||||
near_dir = direction
|
||||
|
||||
else if(direction == in_dir_ccw)
|
||||
near_dir = direction
|
||||
|
||||
return near_dir
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
|
||||
return exit_delay
|
||||
|
||||
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
|
||||
return enter_delay
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/proc/follow_tube()
|
||||
if(moving)
|
||||
return
|
||||
|
||||
moving = 1
|
||||
|
||||
spawn()
|
||||
var/obj/structure/transit_tube/current_tube = null
|
||||
var/next_dir
|
||||
var/next_loc
|
||||
|
||||
for(var/obj/structure/transit_tube/tube in loc)
|
||||
if(tube.has_exit(dir))
|
||||
current_tube = tube
|
||||
break
|
||||
|
||||
while(current_tube)
|
||||
next_dir = current_tube.get_exit(dir)
|
||||
|
||||
if(!next_dir)
|
||||
break
|
||||
|
||||
sleep(current_tube.exit_delay(src, dir))
|
||||
next_loc = get_step(loc, next_dir)
|
||||
|
||||
current_tube = null
|
||||
for(var/obj/structure/transit_tube/tube in next_loc)
|
||||
if(tube.has_entrance(next_dir))
|
||||
current_tube = tube
|
||||
break
|
||||
|
||||
if(current_tube == null)
|
||||
dir = next_dir
|
||||
step(src, dir)
|
||||
break
|
||||
|
||||
sleep(current_tube.enter_delay(src, next_dir))
|
||||
dir = next_dir
|
||||
loc = next_loc
|
||||
|
||||
if(current_tube && current_tube.should_stop_pod(src, next_dir))
|
||||
current_tube.pod_stopped(src, dir)
|
||||
break
|
||||
|
||||
moving = 0
|
||||
|
||||
|
||||
|
||||
// HUGE HACK: Because the pod isn't a mecha, travelling through tubes over space
|
||||
// won't protect people from space.
|
||||
// This avoids editing an additional file, so that adding
|
||||
// tubes to a SS13 codebase is a simple as dropping this code file and the
|
||||
// required icon files somewhere where BYOND can find them.
|
||||
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
|
||||
if(!istype(loc, /obj/structure/transit_tube_pod))
|
||||
return ..(environment)
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/return_air()
|
||||
var/datum/gas_mixture/GM = new()
|
||||
GM.oxygen = MOLES_O2STANDARD * 2
|
||||
GM.nitrogen = MOLES_N2STANDARD
|
||||
GM.temperature = T20C
|
||||
return GM
|
||||
|
||||
// For now, copying what I found in an unused FEA file (and almost identical in a
|
||||
// used ZAS file). Means that assume_air and remove_air don't actually alter the
|
||||
// air contents.
|
||||
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
|
||||
return 0
|
||||
|
||||
/obj/structure/transit_tube_pod/remove_air(amount)
|
||||
var/oxygen = MOLES_O2STANDARD
|
||||
var/carbon_dioxide = 0
|
||||
var/nitrogen = MOLES_N2STANDARD
|
||||
var/toxins = 0
|
||||
|
||||
var/datum/gas_mixture/GM = new()
|
||||
|
||||
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
|
||||
if(sum>0)
|
||||
GM.oxygen = (oxygen/sum)*amount
|
||||
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
|
||||
GM.nitrogen = (nitrogen/sum)*amount
|
||||
GM.toxins = (toxins/sum)*amount
|
||||
|
||||
GM.temperature = T20C
|
||||
GM.update_values() //Needed in ZAS to prevent suffocation. Not present in FEA. Comment/uncomment as nessecary.
|
||||
|
||||
return GM
|
||||
|
||||
|
||||
|
||||
// Called when a pod arrives at, and before a pod departs from a station,
|
||||
// giving it a chance to mix its internal air supply with the turf it is
|
||||
// currently on.
|
||||
/obj/structure/transit_tube_pod/proc/mix_air()
|
||||
//Needs to be implemented at some point
|
||||
|
||||
|
||||
|
||||
// When the player moves, check if the pos is currently stopped at a station.
|
||||
// if it is, check the direction. If the direction matches the direction of
|
||||
// the station, try to exit. If the direction matches one of the station's
|
||||
// tube directions, launch the pod in that direction.
|
||||
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
|
||||
if(!moving && istype(mob, /mob) && mob.client)
|
||||
for(var/obj/structure/transit_tube/station/station in loc)
|
||||
if(!station.pod_moving && (dir in station.directions()))
|
||||
if(direction == station.dir)
|
||||
if(station.icon_state == "open")
|
||||
mob.loc = loc
|
||||
mob.client.Move(get_step(loc, direction), direction)
|
||||
|
||||
else
|
||||
station.open_animation()
|
||||
|
||||
else if(direction in station.directions())
|
||||
dir = direction
|
||||
station.launch_pod()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/New(loc)
|
||||
..(loc)
|
||||
|
||||
if(tube_dirs == null)
|
||||
init_dirs()
|
||||
|
||||
|
||||
|
||||
// Parse the icon_state into a list of directions.
|
||||
// This means that mappers can use Dream Maker's built in
|
||||
// "Generate Instances from Icon-states" option to get all
|
||||
// variations. Additionally, as a separate proc, sub-types
|
||||
// can handle it more intelligently.
|
||||
/obj/structure/transit_tube/proc/init_dirs()
|
||||
tube_dirs = parse_dirs(icon_state)
|
||||
|
||||
if(copytext(icon_state, 1, 3) == "D-")
|
||||
density = 0
|
||||
|
||||
|
||||
|
||||
// Tube station directions are simply 90 to either side of
|
||||
// the exit.
|
||||
/obj/structure/transit_tube/station/init_dirs()
|
||||
tube_dirs = list(turn(dir, 90), turn(dir, -90))
|
||||
|
||||
|
||||
|
||||
// Uses a list() to cache return values. Since they should
|
||||
// never be edited directly, all tubes with a certain
|
||||
// icon_state can just reference the same list. In theory,
|
||||
// reduces memory usage, and improves CPU cache usage.
|
||||
// In reality, I don't know if that is quite how BYOND works,
|
||||
// but it is probably safer to assume the existence of, and
|
||||
// rely on, a sufficiently smart compiler/optimizer.
|
||||
/obj/structure/transit_tube/proc/parse_dirs(text)
|
||||
var/global/list/direction_table = list()
|
||||
|
||||
if(text in direction_table)
|
||||
return direction_table[text]
|
||||
|
||||
var/list/split_text = stringsplit(text, "-")
|
||||
|
||||
// If the first token is D, the icon_state represents
|
||||
// a purely decorative tube, and doesn't actually
|
||||
// connect to anything.
|
||||
if(split_text[1] == "D")
|
||||
direction_table[text] = list()
|
||||
return null
|
||||
|
||||
var/list/directions = list()
|
||||
|
||||
for(var/text_part in split_text)
|
||||
var/direction = text2dir_extended(text_part)
|
||||
|
||||
if(direction > 0)
|
||||
directions += direction
|
||||
|
||||
direction_table[text] = directions
|
||||
return directions
|
||||
|
||||
|
||||
|
||||
// A copy of text2dir, extended to accept one and two letter
|
||||
// directions, and to clearly return 0 otherwise.
|
||||
/obj/structure/transit_tube/proc/text2dir_extended(direction)
|
||||
switch(uppertext(direction))
|
||||
if("NORTH", "N")
|
||||
return 1
|
||||
if("SOUTH", "S")
|
||||
return 2
|
||||
if("EAST", "E")
|
||||
return 4
|
||||
if("WEST", "W")
|
||||
return 8
|
||||
if("NORTHEAST", "NE")
|
||||
return 5
|
||||
if("NORTHWEST", "NW")
|
||||
return 9
|
||||
if("SOUTHEAST", "SE")
|
||||
return 6
|
||||
if("SOUTHWEST", "SW")
|
||||
return 10
|
||||
else
|
||||
return 0
|
||||
Reference in New Issue
Block a user