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 += "[e.display_name]--Not Found" dat += "" + for(var/organ_name in occupant.internal_organs) + var/datum/organ/internal/i = occupant.internal_organs[organ_name] + dat += "" + dat += "[i.name]N/A[i.damage]None:" + dat += "" dat += "" else dat += "\The [src] is empty." diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 4a825fde0ec..62dfb126bf5 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -270,5 +270,12 @@ W.loc = src src.flash1 = W user << "\blue You insert the flash into the eye socket!" + else if(istype(W, /obj/item/weapon/stock_parts/manipulator)) + user << "\blue You install some manipulators and modify the head, creating a functional spider-bot!" + new /mob/living/simple_animal/spiderbot(get_turf(loc)) + user.drop_item() + del(W) + del(src) + return return diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index 65fac660b6a..1a76f91a817 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -124,8 +124,9 @@ icon_state = "rig-medical" name = "medical hardsuit" item_state = "medical_hardsuit" - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller) - slowdown = 2.0 + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) + + //Security /obj/item/clothing/head/helmet/space/rig/security name = "security hardsuit helmet" diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index b972e2f9f80..fe3a0db56c5 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -10,14 +10,13 @@ var/construction_time = 75 var/searching = 0 var/askDelay = 10 * 60 * 1 - + var/mob/living/carbon/brain/brainmob = null req_access = list(access_robotics) var/locked = 0 - var/mob/living/carbon/brain/brainmob = null//The current occupant. var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm. attack_self(mob/user as mob) - if(!brainmob && searching == 0) + if(!brainmob.key && searching == 0) //Start the process of searching for a new user. user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process." icon_state = "posibrain-searching" @@ -37,7 +36,7 @@ spawn(0) if(!C) return var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round") - if(!C || brainmob) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. + if(!C || brainmob.key) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. if(response == "Yes") transfer_personality(C.mob) else if (response == "Never for this round") @@ -47,25 +46,10 @@ proc/transfer_personality(var/mob/candidate) - var/mob/living/carbon/brain/B = new(src) - src.searching = 0 - - src.brainmob = B src.brainmob.mind = candidate.mind - - src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" - src.brainmob.real_name = src.brainmob.name - src.name = "positronic brain ([src.brainmob.name])" - src.brainmob.loc = src - src.brainmob.container = src - src.brainmob.robot_talk_understand = 1 - src.brainmob.stat = 0 - src.brainmob.silent = 0 - src.brainmob.brain_op_stage = 4.0 src.brainmob.key = candidate.key - dead_mob_list -= src.brainmob - living_mob_list += src.brainmob + src.name = "positronic brain ([src.brainmob.name])" src.brainmob << "You are a positronic brain, brought into existence on [station_name()]." src.brainmob << "As a synthetic intelligence, you answer to all crewmembers, as well as the AI." @@ -101,7 +85,7 @@ var/msg = "*---------*\nThis is \icon[src] \a [src]!\n[desc]\n" msg += "" - if(src.brainmob) + if(src.brainmob.key) switch(src.brainmob.stat) if(CONSCIOUS) if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk @@ -124,4 +108,19 @@ brainmob.emp_damage += rand(10,20) if(3) brainmob.emp_damage += rand(0,10) + ..() + +/obj/item/device/posibrain/New() + + src.brainmob = new(src) + src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" + src.brainmob.real_name = src.brainmob.name + src.brainmob.loc = src + src.brainmob.container = src + src.brainmob.robot_talk_understand = 1 + src.brainmob.stat = 0 + src.brainmob.silent = 0 + src.brainmob.brain_op_stage = 4.0 + dead_mob_list -= src.brainmob + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1adee6f3054..666ba1d820c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -38,6 +38,11 @@ organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"]) organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"]) + new/datum/organ/internal/heart(src) + new/datum/organ/internal/lungs(src) + new/datum/organ/internal/liver(src) + new/datum/organ/internal/kidney(src) + // connect feet to legs and hands to arms /* var/datum/organ/external/organ = organs_by_name["l_hand"] @@ -899,26 +904,24 @@ H.brainmob.mind.transfer_to(src) del(H) - var/datum/organ/external/chest/E = get_organ("chest") - if(E.ruptured_lungs == 1) - E.ruptured_lungs = 0 + for(var/datum/organ/internal/I in internal_organs) + I.damage = 0 for (var/datum/disease/virus in viruses) virus.cure() ..() /mob/living/carbon/human/proc/is_lung_ruptured() - var/datum/organ/external/chest/E = get_organ("chest") - return E.ruptured_lungs - + var/datum/organ/internal/lungs/L = internal_organs["lungs"] + return L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() - var/datum/organ/external/chest/E = get_organ("chest") + var/datum/organ/internal/lungs/L = internal_organs["lungs"] - if(E.ruptured_lungs == 0) + if(!L.is_bruised()) src.custom_pain("You feel a stabbing pain in your chest!", 1) + L.damage = L.min_bruised_damage - E.ruptured_lungs = 1 /* /mob/living/carbon/human/verb/simulate() set name = "sim" diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d24f835153f..63931927e84 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -155,6 +155,16 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //At this point, we dun care which blood we are adding to, as long as they get more blood. B.volume = B.volume + 0.1 // regenerate blood VERY slowly + // Damaged heart virtually reduces the blood volume, as the blood isn't + // being pumped properly anymore. + var/datum/organ/internal/heart/heart = internal_organs["heart"] + switch(heart.damage) + if(5 to 10) + blood_volume *= 0.8 + if(11 to 20) + blood_volume *= 0.5 + if(21 to INFINITY) + blood_volume *= 0.3 switch(blood_volume) if(BLOOD_VOLUME_SAFE to 10000) @@ -1044,6 +1054,22 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 var/datum/organ/O = pick(organs) O.trace_chemicals[A.name] = 100 + var/damaged_liver_process_accuracy = 10 + if(life_tick % damaged_liver_process_accuracy == 0) + // Damaged liver means some chemicals are very dangerous + var/datum/organ/internal/liver/liver = internal_organs["liver"] + if(liver.damage >= liver.min_bruised_damage) + for(var/datum/reagent/R in src.reagents.reagent_list) + // Ethanol and all drinks are bad + if(istype(R, /datum/reagent/ethanol)) + adjustToxLoss(0.1 * damaged_liver_process_accuracy) + + // Can't cope with toxins at all + for(var/toxin in list("toxin", "plasma", "sacid", "pacid", "cyanide", "lexorin", "amatoxin", "chloralhydrate", "carpotoxin", "zombiepowder", "mindbreaker")) + if(src.reagents.has_reagent(toxin)) + adjustToxLoss(0.3 * damaged_liver_process_accuracy) + + updatehealth() return //TODO: DEFERRED diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index 1c2adbf7a6e..6a5407e3a92 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -106,7 +106,7 @@ var/list/listening = hearers(1, src) listening -= src - //listening += src + listening += src var/list/heard = list() for (var/mob/M in listening) diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm new file mode 100644 index 00000000000..86aeae28538 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -0,0 +1,325 @@ +/mob/living/simple_animal/spiderbot + + min_oxy = 0 + max_tox = 0 + max_co2 = 0 + minbodytemp = 0 + maxbodytemp = 500 + + var/obj/item/device/radio/borg/radio = null + var/mob/living/silicon/ai/connected_ai = null + var/obj/item/weapon/cell/cell = null + var/obj/machinery/camera/camera = null + var/obj/item/device/mmi/mmi = null + var/list/req_access = list(access_robotics) //Access needed to pop out the brain. + + name = "Spider-bot" + desc = "A skittering robotic friend!" + icon = 'icons/mob/robots.dmi' + icon_state = "spiderbot-chassis" + icon_living = "spiderbot-chassis" + icon_dead = "spiderbot-smashed" + wander = 0 + + health = 10 + maxHealth = 10 + + attacktext = "shocks" + attacktext = "shocks" + melee_damage_lower = 1 + melee_damage_upper = 3 + + response_help = "pets" + response_disarm = "shoos" + response_harm = "stomps on" + + var/obj/item/held_item = null //Storage for single item they can hold. + var/emagged = 0 //IS WE EXPLODEN? + var/syndie = 0 //IS WE SYNDICAT? (currently unused) + speed = -1 //Spiderbots gotta go fast. + //pass_flags = PASSTABLE //Maybe griefy? + small = 1 + speak_emote = list("beeps","clicks","chirps") + +/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob) + + if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/posibrain)) + var/obj/item/device/mmi/B = O + if(src.mmi) //There's already a brain in it. + user << "\red There's already a brain in [src]!" + return + if(!B.brainmob) + user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose." + return + if(!B.brainmob.key) + var/ghost_can_reenter = 0 + if(B.brainmob.mind) + for(var/mob/dead/observer/G in player_list) + if(G.can_reenter_corpse && G.mind == B.brainmob.mind) + ghost_can_reenter = 1 + break + if(!ghost_can_reenter) + user << "[O] is completely unresponsive; there's no point." + return + + if(B.brainmob.stat == DEAD) + user << "\red [O] is dead. Sticking it into the frame would sort of defeat the purpose." + return + + if(jobban_isbanned(B.brainmob, "Cyborg")) + user << "\red [O] does not seem to fit." + return + + user << "\blue You install [O] in [src]!" + + user.drop_item() + src.mmi = O + src.transfer_personality(O) + + O.loc = src + src.update_icon() + return 1 + + if (istype(O, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = O + if (WT.remove_fuel(0)) + if(health < maxHealth) + health += pick(1,1,1,2,2,3) + if(health > maxHealth) + health = maxHealth + add_fingerprint(user) + for(var/mob/W in viewers(user, null)) + W.show_message(text("\red [user] has spot-welded some of the damage to [src]!"), 1) + else + user << "\blue [src] is undamaged!" + else + user << "Need more welding fuel!" + return + else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda)) + if (!mmi) + user << "\red There's no reason to swipe your ID - the spiderbot has no brain to remove." + return 0 + + var/obj/item/weapon/card/id/id_card + + if(istype(O, /obj/item/weapon/card/id)) + id_card = O + else + var/obj/item/device/pda/pda = O + id_card = pda.id + + if(access_robotics in id_card.access) + user << "\blue You swipe your access card and pop the brain out of [src]." + eject_brain() + + if(held_item) + held_item.loc = src.loc + held_item = null + + return 1 + else + user << "\red You swipe your card, with no effect." + return 0 + else if (istype(O, /obj/item/weapon/card/emag)) + if (emagged) + user << "\red [src] is already overloaded - better run." + return 0 + else + emagged = 1 + user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." + spawn(100) src << "\red Your cell seems to be outputting a lot of power..." + spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" + spawn(300) src.explode() + + else + if(O.force) + var/damage = O.force + if (O.damtype == HALLOSS) + damage = 0 + adjustBruteLoss(damage) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\red \b [src] has been attacked with the [O] by [user]. ") + else + usr << "\red This weapon is ineffective, it does no damage." + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\red [user] gently taps [src] with the [O]. ") + +/mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj) + + src.mind = M.brainmob.mind + src.mind.key = M.brainmob.key + src.name = "Spider-bot ([M.brainmob.name])" + +/mob/living/simple_animal/spiderbot/proc/explode() //When emagged. + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\red [src] makes an odd warbling noise, fizzles, and explodes.") + explosion(get_turf(loc), -1, -1, 3, 5) + eject_brain() + Die() + +/mob/living/simple_animal/spiderbot/proc/update_icon() + if(mmi) + if (istype(mmi,/obj/item/device/mmi)) + icon_state = "spiderbot-chassis-mmi" + icon_living = "spiderbot-chassis-mmi" + else + icon_state = "spiderbot-chassis-posi" + icon_living = "spiderbot-chassis-posi" + else + icon_state = "spiderbot-chassis" + icon_living = "spiderbot-chassis" + +/mob/living/simple_animal/spiderbot/proc/eject_brain() + if(mmi) + var/turf/T = get_turf(loc) + if(T) + mmi.loc = T + if(mind) mind.transfer_to(mmi.brainmob) + mmi = null + src.name = "Spider-bot" + update_icon() + +/mob/living/simple_animal/spiderbot/Del() + eject_brain() + ..() + +/mob/living/simple_animal/spiderbot/New() + + radio = new /obj/item/device/radio/borg(src) + camera = new /obj/machinery/camera(src) + camera.c_tag = "Spiderbot-[real_name]" + camera.network = list("SS13") + + ..() + +/mob/living/simple_animal/spiderbot/Die() + + living_mob_list -= src + dead_mob_list += src + + if(camera) + camera.status = 0 + + robogibs(src.loc, viruses) + src.Del() + return + +//copy paste from alien/larva, if that func is updated please update this one also +/mob/living/simple_animal/spiderbot/verb/ventcrawl() + set name = "Crawl through Vent" + set desc = "Enter an air vent and crawl through the pipe system." + set category = "Spiderbot" + +// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent)) +// return + var/obj/machinery/atmospherics/unary/vent_pump/vent_found + var/welded = 0 + for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src)) + if(!v.welded) + vent_found = v + break + else + welded = 1 + if(vent_found) + if(vent_found.network&&vent_found.network.normal_members.len) + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members) + if(temp_vent.loc == loc) + continue + vents.Add(temp_vent) + var/list/choices = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents) + if(vent.loc.z != loc.z) + continue + var/atom/a = get_turf(vent) + choices.Add(a.loc) + var/turf/startloc = loc + var/obj/selection = input("Select a destination.", "Duct System") in choices + var/selection_position = choices.Find(selection) + if(loc==startloc) + var/obj/target_vent = vents[selection_position] + if(target_vent) + loc = target_vent.loc + else + src << "\blue You need to remain still while entering a vent." + else + src << "\blue This vent is not connected to anything." + else if(welded) + src << "\red That vent is welded." + else + src << "\blue You must be standing on or beside an air vent to enter it." + return + +//copy paste from alien/larva, if that func is updated please update this one alsoghost +/mob/living/simple_animal/spiderbot/verb/hide() + set name = "Hide" + set desc = "Allows to hide beneath tables or certain items. Toggled on or off." + set category = "Spiderbot" + + if (layer != TURF_LAYER+0.2) + layer = TURF_LAYER+0.2 + src << text("\blue You are now hiding.") + else + layer = MOB_LAYER + src << text("\blue You have stopped hiding.") + +//Cannibalized from the parrot mob. ~Zuhayr + +/mob/living/simple_animal/spiderbot/verb/drop_held_item() + set name = "Drop held item" + set category = "Spiderbot" + set desc = "Drop the item you're holding." + + if(stat) + return + + if(!held_item) + usr << "\red You have nothing to drop!" + return 0 + + if(istype(held_item, /obj/item/weapon/grenade)) + visible_message("\red [src] launches the [held_item]!", "\red You launch the [held_item]!", "You hear a skittering noise and a thump!") + var/obj/item/weapon/grenade/G = held_item + G.loc = src.loc + G.prime() + held_item = null + return 1 + + visible_message("\blue [src] drops the [held_item]!", "\blue You drop the [held_item]!", "You hear a skittering noise and a soft thump.") + + held_item.loc = src.loc + held_item = null + return 1 + + return + +/mob/living/simple_animal/spiderbot/verb/get_item() + set name = "Pick up item" + set category = "Spiderbot" + set desc = "Allows you to take a nearby small item." + + if(stat) + return -1 + + if(held_item) + src << "\red You are already holding the [held_item]" + return 1 + + var/list/items = list() + for(var/obj/item/I in view(1,src)) + if(I.loc != src && I.w_class <= 2) + items.Add(I) + + var/obj/selection = input("Select an item.", "Pickup") in items + + if(selection) + held_item = selection + selection.loc = src + visible_message("\blue [src] scoops up the [held_item]!", "\blue You grab the [held_item]!", "You hear a skittering noise and a clink.") + return held_item + + src << "\red There is nothing of interest to take." + return 0 \ No newline at end of file diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index a8d5bea0c89..d6daad60922 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -127,6 +127,14 @@ /obj/item/device/camera/attack(mob/living/carbon/human/M as mob, mob/user as mob) return +/obj/item/device/camera/attack_self(mob/user as mob) + on = !on + if(on) + src.icon_state = "camera" + else + src.icon_state = "camera_off" + user << "You switch the camera [on ? "on" : "off"]." + return /obj/item/device/camera/attackby(obj/item/I as obj, mob/user as mob) if(istype(I, /obj/item/device/camera_film)) diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index cabad829839..3fe616d94f5 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -37,8 +37,8 @@ if(isnull(AC) || !istype(AC)) return 0 AC.loc = get_turf(src) //Eject casing onto ground. - AC.desc += " This one is spent." //descriptions are magic if(AC.BB) + AC.desc += " This one is spent." //descriptions are magic - only when there's a projectile in the casing in_chamber = AC.BB //Load projectile into chamber. AC.BB.loc = src //Set projectile loc to gun. return 1 diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm index de5325f9821..7cd308abc4d 100644 --- a/code/modules/surgery/ribcage.dm +++ b/code/modules/surgery/ribcage.dm @@ -109,7 +109,7 @@ affected.fracture() if (prob(40)) user.visible_message("\red Rib pierces the lung!") - affected.ruptured_lungs = 1 + target.rupture_lung() /datum/surgery_step/ribcage/mend_ribcage required_tool = /obj/item/weapon/bonegel @@ -168,9 +168,9 @@ ////////////////////////////////////////////////////////////////// -// LUNG SURGERY // +// CHEST INTERNAL ORGAN SURGERY // ////////////////////////////////////////////////////////////////// -/datum/surgery_step/ribcage/fix_lungs +/datum/surgery_step/ribcage/fix_chest_internal required_tool = /obj/item/weapon/scalpel allowed_tools = list(/obj/item/weapon/shard, /obj/item/weapon/kitchenknife) @@ -178,19 +178,59 @@ max_duration = 90 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.is_lung_ruptured() && target.op_stage.ribcage == 2 + var/is_chest_organ_damaged = 0 + var/datum/organ/external/chest/chest = target.get_organ("chest") + for(var/datum/organ/internal/I in chest.internal_organs) if(I.damage > 0) + is_chest_organ_damaged = 1 + break + return ..() && is_chest_organ_damaged && target.op_stage.ribcage == 2 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts mending the rupture in [target]'s lungs with \the [tool].", \ - "You start mending the rupture in [target]'s lungs with \the [tool]." ) + var/datum/organ/internal/heart/heart = target.internal_organs["heart"] + var/datum/organ/internal/lungs/lungs = target.internal_organs["lungs"] + var/datum/organ/internal/liver/liver = target.internal_organs["liver"] + var/datum/organ/internal/liver/kidney = target.internal_organs["kidney"] + + if(lungs.damage > 0) + user.visible_message("[user] starts mending the rupture in [target]'s lungs with \the [tool].", \ + "You start mending the rupture in [target]'s lungs with \the [tool]." ) + if(heart.damage > 0) + user.visible_message("[user] starts mending the bruises on [target]'s heart with \the [tool].", \ + "You start mending the bruises on [target]'s heart with \the [tool]." ) + if(liver.damage > 0) + user.visible_message("[user] starts mending the bruises on [target]'s liver with \the [tool].", \ + "You start mending the bruises on [target]'s liver with \the [tool]." ) + if(kidney.damage > 0) + user.visible_message("[user] starts mending the bruises on [target]'s kidney with \the [tool].", \ + "You start mending the bruises on [target]'s kidney with \the [tool]." ) target.custom_pain("The pain in your chest is living hell!",1) ..() end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/datum/organ/external/chest/affected = target.get_organ("chest") - user.visible_message("\blue [user] mends the rupture in [target]'s lungs with \the [tool].", \ - "\blue You mend the rupture in [target]'s lungs with \the [tool]." ) - affected.ruptured_lungs = 0 + var/datum/organ/internal/heart/heart = target.internal_organs["heart"] + var/datum/organ/internal/lungs/lungs = target.internal_organs["lungs"] + var/datum/organ/internal/liver/liver = target.internal_organs["liver"] + var/datum/organ/internal/liver/kidney = target.internal_organs["kidney"] + + if(lungs.damage > 0) + user.visible_message("\blue [user] mends the rupture in [target]'s lungs with \the [tool].", \ + "\blue You mend the rupture in [target]'s lungs with \the [tool]." ) + lungs.damage = 0 + + if(heart.damage > 0) + user.visible_message("\blue [user] treats the bruises on [target]'s heart with \the [tool].", \ + "\blue You treats the bruises on [target]'s heart with \the [tool]." ) + heart.damage = 0 + + if(liver.damage > 0) + user.visible_message("\blue [user] treats the bruises on [target]'s liver with \the [tool].", \ + "\blue You treats the bruises on [target]'s liver with \the [tool]." ) + liver.damage = 0 + + if(kidney.damage > 0) + user.visible_message("\blue [user] treats the bruises on [target]'s kidney with \the [tool].", \ + "\blue You treats the bruises on [target]'s kidney with \the [tool]." ) + kidney.damage = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/datum/organ/external/chest/affected = target.get_organ("chest") diff --git a/html/changelog.html b/html/changelog.html index 9d508b9a9f0..ff975aa886d 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -65,7 +65,11 @@ should be listed in the changelog upon commit though. Thanks. --> + +

CIB updated:

+
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index a5f92e97676..e0e658ed6fb 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/mob/screen1_Midnight.dmi b/icons/mob/screen1_Midnight.dmi index 8b63ff84366..94f4e23e6a8 100644 Binary files a/icons/mob/screen1_Midnight.dmi and b/icons/mob/screen1_Midnight.dmi differ diff --git a/icons/mob/screen1_Orange.dmi b/icons/mob/screen1_Orange.dmi index 37d0a49cda3..7ef1d84d897 100644 Binary files a/icons/mob/screen1_Orange.dmi and b/icons/mob/screen1_Orange.dmi differ diff --git a/icons/mob/screen1_old.dmi b/icons/mob/screen1_old.dmi index 2994f9fd7b5..fb2d2c21c59 100644 Binary files a/icons/mob/screen1_old.dmi and b/icons/mob/screen1_old.dmi differ diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index a4a72b0a380..554d31c0837 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ diff --git a/maps/tgstation.2.1.0.0.1.dmm b/maps/tgstation.2.1.0.0.1.dmm index 551e9012118..bfce25fdbe3 100644 --- a/maps/tgstation.2.1.0.0.1.dmm +++ b/maps/tgstation.2.1.0.0.1.dmm @@ -6944,10 +6944,10 @@ "cDB" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "cDC" = (/obj/machinery/computer/pod{id = "NTrasen"; name = "Hull Door Control"},/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "cDD" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/secure/briefcase,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"cDE" = (/turf/simulated/floor{dir = 9; icon_state = "yellow"},/area/centcom/control) -"cDF" = (/turf/simulated/floor{dir = 5; icon_state = "yellow"},/area/centcom/control) -"cDG" = (/turf/simulated/floor{dir = 4; icon_state = "whitecorner"},/area/centcom/control) -"cDH" = (/turf/simulated/floor{icon_state = "whitehall"; dir = 5},/area/centcom/control) +"cDE" = (/turf/unsimulated/floor{tag = "icon-yellow (NORTHWEST)"; icon_state = "yellow"; dir = 9},/area/centcom/control) +"cDF" = (/turf/unsimulated/floor{tag = "icon-yellow (NORTHEAST)"; icon_state = "yellow"; dir = 5},/area/centcom/control) +"cDG" = (/turf/unsimulated/floor{tag = "icon-whitehall (NORTHWEST)"; icon_state = "whitehall"; dir = 9},/area/centcom/control) +"cDH" = (/turf/unsimulated/floor{tag = "icon-whitehall (NORTHEAST)"; icon_state = "whitehall"; dir = 5},/area/centcom/control) "cDI" = (/obj/structure/rack,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "cDJ" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "cDK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor,/area/centcom/control) @@ -6955,10 +6955,10 @@ "cDM" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "cDN" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) "cDO" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/pulse_rifle,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"cDP" = (/obj/structure/table/reinforced,/obj/item/device/flash,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/simulated/floor{dir = 1; icon_state = "yellow"},/area/centcom/control) -"cDQ" = (/obj/structure/table/reinforced,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/simulated/floor{dir = 1; icon_state = "yellow"},/area/centcom/control) -"cDR" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/syringes,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/centcom/control) -"cDS" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular,/obj/item/device/flash,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flash,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/centcom/control) +"cDP" = (/obj/structure/table/reinforced,/obj/item/device/flash,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/unsimulated/floor{tag = "icon-yellow (NORTH)"; icon_state = "yellow"; dir = 1},/area/centcom/control) +"cDQ" = (/obj/structure/table/reinforced,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/unsimulated/floor{tag = "icon-yellow (NORTH)"; icon_state = "yellow"; dir = 1},/area/centcom/control) +"cDR" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/syringes,/obj/item/device/flash,/obj/item/device/flash,/turf/unsimulated/floor{tag = "icon-whitehall (NORTH)"; icon_state = "whitehall"; dir = 1},/area/centcom/control) +"cDS" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular,/obj/item/device/flash,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flash,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/turf/unsimulated/floor{tag = "icon-whitehall (NORTH)"; icon_state = "whitehall"; dir = 1},/area/centcom/control) "cDT" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "cDU" = (/turf/unsimulated/floor{icon_state = "green"; dir = 5},/area/centcom/control) "cDV" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) @@ -6967,18 +6967,18 @@ "cDY" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "cDZ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/handcuffs,/obj/item/device/flash,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "red"; dir = 2},/area/centcom/control) "cEa" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/turf/unsimulated/floor{icon_state = "red"; dir = 2},/area/centcom/control) -"cEb" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/centcom/control) -"cEc" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/device/flash,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/weapon/pinpointer/advpinpointer,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/centcom/control) +"cEb" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/device/flash,/obj/item/device/flash,/turf/unsimulated/floor{tag = "icon-blue"; icon_state = "blue"},/area/centcom/control) +"cEc" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/device/flash,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/weapon/pinpointer/advpinpointer,/turf/unsimulated/floor{tag = "icon-blue"; icon_state = "blue"},/area/centcom/control) "cEd" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "cEe" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "CentComPort"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "cEf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "cEg" = (/obj/structure/table,/obj/machinery/door_control{desc = "A remote control switch for port-side blast doors."; icon_state = "doorctrl0"; id = "CentComPort"; name = "Security Doors"; pixel_y = -4; req_access_txt = "101"},/obj/machinery/door/window/southleft{dir = 1; name = "Security"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "cEh" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "CentComPort"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) "cEi" = (/obj/structure/table/reinforced,/obj/item/weapon/phone,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"cEj" = (/turf/simulated/floor{icon_state = "red"; dir = 10},/area/centcom/control) -"cEk" = (/turf/simulated/floor{icon_state = "red"; dir = 6},/area/centcom/control) -"cEl" = (/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/centcom/control) -"cEm" = (/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/centcom/control) +"cEj" = (/turf/unsimulated/floor{icon_state = "red"; dir = 10},/area/centcom/control) +"cEk" = (/turf/unsimulated/floor{tag = "icon-red (SOUTHEAST)"; icon_state = "red"; dir = 6},/area/centcom/control) +"cEl" = (/turf/unsimulated/floor{tag = "icon-blue (SOUTHWEST)"; icon_state = "blue"; dir = 10},/area/centcom/control) +"cEm" = (/turf/unsimulated/floor{tag = "icon-blue (SOUTHEAST)"; icon_state = "blue"; dir = 6},/area/centcom/control) "cEn" = (/obj/structure/reagent_dispensers/watertank,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "cEo" = (/turf/unsimulated/wall,/area/centcom/ferry) "cEp" = (/obj/machinery/door/window/westright{req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control)