diff --git a/baystation12.dme b/baystation12.dme
index be1dcd86f10..10b2d3f4354 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -14,6 +14,7 @@
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/ShieldGen"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Supermatter"
#define FILE_DIR "code/WorkInProgress/Susan"
+#define FILE_DIR "code/WorkInProgress/Uristqwerty"
#define FILE_DIR "html"
#define FILE_DIR "icons"
#define FILE_DIR "icons/48x48"
@@ -998,6 +999,7 @@
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
#include "code\modules\mob\living\simple_animal\friendly\mushroom.dm"
#include "code\modules\mob\living\simple_animal\friendly\slime.dm"
+#include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm"
#include "code\modules\mob\living\simple_animal\friendly\tomato.dm"
#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
#include "code\modules\mob\living\simple_animal\hostile\bear.dm"
@@ -1197,6 +1199,7 @@
#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_Events_Mundane.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_TradeDestinations.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Job_Departments.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"
@@ -1235,6 +1238,7 @@
#include "code\WorkInProgress\Ported\policetape.dm"
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
#include "code\WorkInProgress\Susan\susan_desert_turfs.dm"
+#include "code\WorkInProgress\Uristqwerty\transit_tubes.dm"
#include "code\WorkInProgress\virus2\analyser.dm"
#include "code\WorkInProgress\virus2\antibodies.dm"
#include "code\WorkInProgress\virus2\base.dm"
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
index 3c1d3570b77..3c07e1f2060 100644
--- a/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
@@ -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: [held_card ? held_card : "-----"]
"
if(access_level > 0)
- dat += "Toggle remote access to this database (warning!)"
+ dat += "[activated ? "Disable" : "Enable"] remote access
"
dat += "You may not edit accounts at this terminal, only create and view them.
"
if(creating_new_account)
dat += "
"
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Job_Departments.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Job_Departments.dm
new file mode 100644
index 00000000000..64abe66acc1
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Job_Departments.dm
@@ -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"
\ No newline at end of file
diff --git a/code/WorkInProgress/Mini/ATM.dm b/code/WorkInProgress/Mini/ATM.dm
index 68f9315182a..9578c3a2a3d 100644
--- a/code/WorkInProgress/Mini/ATM.dm
+++ b/code/WorkInProgress/Mini/ATM.dm
@@ -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)
diff --git a/code/WorkInProgress/Uristqwerty/transit_tube.dmi b/code/WorkInProgress/Uristqwerty/transit_tube.dmi
new file mode 100644
index 00000000000..e7087001805
Binary files /dev/null and b/code/WorkInProgress/Uristqwerty/transit_tube.dmi differ
diff --git a/code/WorkInProgress/Uristqwerty/transit_tube_pod.dmi b/code/WorkInProgress/Uristqwerty/transit_tube_pod.dmi
new file mode 100644
index 00000000000..a52b80f8206
Binary files /dev/null and b/code/WorkInProgress/Uristqwerty/transit_tube_pod.dmi differ
diff --git a/code/WorkInProgress/Uristqwerty/transit_tube_station.dmi b/code/WorkInProgress/Uristqwerty/transit_tube_station.dmi
new file mode 100644
index 00000000000..ca8515fded7
Binary files /dev/null and b/code/WorkInProgress/Uristqwerty/transit_tube_station.dmi differ
diff --git a/code/WorkInProgress/Uristqwerty/transit_tubes.dm b/code/WorkInProgress/Uristqwerty/transit_tubes.dm
new file mode 100644
index 00000000000..96fffda15a5
--- /dev/null
+++ b/code/WorkInProgress/Uristqwerty/transit_tubes.dm
@@ -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
\ No newline at end of file
diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm
index 7710fb6a4f7..31dc038c2cb 100644
--- a/code/datums/organs/organ_external.dm
+++ b/code/datums/organs/organ_external.dm
@@ -25,6 +25,9 @@
var/datum/organ/external/parent
var/list/datum/organ/external/children
+ // Internal organs of this body part
+ var/list/datum/organ/internal/internal_organs
+
var/damage_msg = "\red You feel an intense pain"
var/broken_description
@@ -93,6 +96,13 @@
droplimb(1)
return
+ // High brute damage or sharp objects may damage internal organs
+ if(internal_organs != null) if( (sharp && brute >= 5) || brute >= 10) if(prob(5))
+ // Damage an internal organ
+ var/datum/organ/internal/I = pick(internal_organs)
+ I.take_damage(brute / 2)
+ brute -= brute / 2
+
if(status & ORGAN_BROKEN && prob(40) && brute)
owner.emote("scream") //getting hit on broken hand hurts
if(used_weapon)
@@ -555,7 +565,6 @@
max_damage = 150
min_broken_damage = 75
body_part = UPPER_TORSO
- var/ruptured_lungs = 0
/datum/organ/external/groin
name = "groin"
diff --git a/code/datums/organs/organ_internal.dm b/code/datums/organs/organ_internal.dm
index c6490c71c86..f670b39420f 100644
--- a/code/datums/organs/organ_internal.dm
+++ b/code/datums/organs/organ_internal.dm
@@ -1,6 +1,8 @@
/****************************************************
INTERNAL ORGANS
****************************************************/
+
+/*
/datum/organ/internal
name = "internal"
var/damage = 0
@@ -62,3 +64,53 @@
var/lungs = null
var/stomach = null
+*/
+
+/mob/living/carbon/human/var/list/internal_organs = list()
+
+/datum/organ/internal
+ // amount of damage to the organ
+ var/damage = 0
+ var/min_bruised_damage = 10
+ var/min_broken_damage = 30
+ var/parent_organ = "chest"
+
+/datum/organ/internal/proc/is_bruised()
+ return damage >= min_bruised_damage
+
+/datum/organ/internal/proc/is_broken()
+ return damage >= min_broken_damage
+
+
+/datum/organ/internal/New(mob/living/carbon/human/H)
+ ..()
+ var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
+ if(E.internal_organs == null)
+ E.internal_organs = list()
+ E.internal_organs += src
+ H.internal_organs[src.name] = src
+ src.owner = H
+
+/datum/organ/internal/proc/take_damage(amount)
+ src.damage += amount
+
+ var/datum/organ/external/parent = owner.get_organ(parent_organ)
+ owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
+
+/datum/organ/internal/heart
+ name = "heart"
+ parent_organ = "chest"
+
+
+/datum/organ/internal/lungs
+ name = "lungs"
+ parent_organ = "chest"
+
+/datum/organ/internal/liver
+ name = "liver"
+ parent_organ = "chest"
+
+
+/datum/organ/internal/kidney
+ name = "kidney"
+ parent_organ = "chest"
\ No newline at end of file
diff --git a/code/datums/organs/pain.dm b/code/datums/organs/pain.dm
index 750cd75f33a..820ef5a077c 100644
--- a/code/datums/organs/pain.dm
+++ b/code/datums/organs/pain.dm
@@ -81,3 +81,10 @@ mob/living/carbon/human/proc/handle_pain()
maxdam = dam
if(damaged_organ)
pain(damaged_organ.display_name, maxdam, 0)
+
+ // Damage to internal organs hurts a lot.
+ for(var/organ_name in internal_organs)
+ var/datum/organ/internal/I = internal_organs[organ_name]
+ if(I.damage > 2) if(prob(2))
+ var/datum/organ/external/parent = get_organ(I.parent_organ)
+ src.custom_pain("You feel a sharp pain in your [parent.display_name]", 1)
\ No newline at end of file
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index da377f25131..6a3bbd19c82 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -10,7 +10,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
required_players = 2
- required_players_secret = 5
+ required_players_secret = 10
required_enemies = 1
recommended_enemies = 4
@@ -37,7 +37,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
- var/const/changeling_amount = 4
+ var/changeling_amount = 4
/datum/game_mode/changeling/announce()
world << "The current game mode is - Changeling!"
@@ -55,6 +55,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
if(player.assigned_role == job)
possible_changelings -= player
+ changeling_amount = 1 + round(num_players() / 10)
+
if(possible_changelings.len>0)
for(var/i = 0, i < changeling_amount, i++)
if(!possible_changelings.len) break
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 8b08b0a26b4..a17e19ebb8e 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -340,6 +340,18 @@ var/global/datum/controller/occupations/job_master
H.mind.initial_account = M
+ // If they're head, give them the account info for their department
+ if(H.mind && job.head_position)
+ var/remembered_info = ""
+ var/datum/money_account/department_account = department_accounts[job.department]
+
+ if(department_account)
+ remembered_info += "Your department's account number is: #[department_account.account_number]
"
+ remembered_info += "Your department's account pin is: [department_account.remote_access_pin]
"
+ remembered_info += "Your department's account funds are: $[department_account.money]
"
+
+ H.mind.store_memory(remembered_info)
+
spawn(0)
H << "\blueYour account number is: [M.account_number], your account pin is: [M.remote_access_pin]"
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index ef556cbc701..52282558e7a 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -286,7 +286,7 @@
for(var/datum/wound/W in e.wounds) if(W.internal)
internal_bleeding = "
Internal Bleeding"
break
- if(istype(e, /datum/organ/external/chest) && e:ruptured_lungs)
+ if(istype(e, /datum/organ/external/chest) && occupant.is_lung_ruptured())
lung_ruptured = "Lung Ruptured:"
if(e.status & ORGAN_SPLINTED)
splint = "Splinted:"
@@ -305,6 +305,11 @@
else
dat += "