diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 5ab826fa867..6ce3ffad460 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -330,15 +330,7 @@ // Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(var/atom/A) - // Snowflake for space vines. - var/is_buckled = 0 - if(buckled) - if(istype(buckled)) - if(!buckled.movable) - is_buckled = 1 - else - is_buckled = 0 - if( is_buckled || !A || !x || !y || !A.x || !A.y || (stat && !isobserver(src))) return + if(!A || !x || !y || !A.x || !A.y) return var/dx = A.x - x var/dy = A.y - y if(!dx && !dy) return diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 4f4224b04b2..906069b876f 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -175,7 +175,7 @@ return if(melee_damage_upper == 0 && istype(A,/mob/living)) - custom_emote(1,"[friendly] [src]!") + custom_emote(1,"[friendly] [A]!") return var/damage = rand(melee_damage_lower, melee_damage_upper) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 00200a24cbf..3532bf7bcde 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -504,11 +504,6 @@ if("python_path") if(value) config.python_path = value - else - if(world.system_type == UNIX) - config.python_path = "/usr/bin/env python2" - else //probably windows, if not this should work anyway - config.python_path = "python" if("use_lib_nudge") config.use_lib_nudge = 1 @@ -741,3 +736,11 @@ runnable_modes[M] = probabilities[M.config_tag] //world << "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]" return runnable_modes + +/datum/configuration/proc/post_load() + //apply a default value to config.python_path, if needed + if (!config.python_path) + if(world.system_type == UNIX) + config.python_path = "/usr/bin/env python2" + else //probably windows, if not this should work anyway + config.python_path = "python" diff --git a/code/controllers/lighting_controller.dm b/code/controllers/lighting_controller.dm index 08c29e1a076..b59d3c73d69 100644 --- a/code/controllers/lighting_controller.dm +++ b/code/controllers/lighting_controller.dm @@ -65,7 +65,7 @@ datum/controller/lighting/proc/process() //Does not loop. Should be run prior to process() being called for the first time. //Note: if we get additional z-levels at runtime (e.g. if the gateway thin ever gets finished) we can initialize specific //z-levels with the z_level argument -datum/controller/lighting/proc/Initialize(var/z_level) +datum/controller/lighting/proc/initializeLighting(var/z_level) processing = 0 spawn(-1) set background = 1 diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 0a7c6c1a239..1e972dd46d2 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -84,7 +84,7 @@ datum/controller/game_controller/proc/setup() if(ticker) ticker.pregame() - lighting_controller.Initialize() + lighting_controller.initializeLighting() datum/controller/game_controller/proc/setup_objects() diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 33872391016..d5503890a2f 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -9,6 +9,7 @@ datum/controller/vote var/mode = null var/question = null var/list/choices = list() + var/list/gamemode_names = list() var/list/voted = list() var/list/voting = list() var/list/current_votes = list() @@ -217,8 +218,10 @@ datum/controller/vote for (var/T in L) var/datum/game_mode/M = new T() if (M.config_tag == F) + gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works additional_text.Add("[M.required_players]") break + gamemode_names["secret"] = "Secret" if("crew_transfer") if(check_rights(R_ADMIN|R_MOD, 0)) question = "End the shift?" @@ -307,11 +310,16 @@ datum/controller/vote var/votes = choices[choices[i]] if(!votes) votes = 0 . += "" - if(current_votes[C.ckey] == i) - . += "[choices[i]][votes]" + if(mode == "gamemode") + if(current_votes[C.ckey] == i) + . += "[gamemode_names[choices[i]]][votes]" + else + . += "[gamemode_names[choices[i]]][votes]" else - . += "[choices[i]][votes]" - + if(current_votes[C.ckey] == i) + . += "[choices[i]][votes]" + else + . += "[choices[i]][votes]" if (additional_text.len >= i) . += additional_text[i] . += "" diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 0d817b7c8d8..4ff625defb7 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -16,11 +16,11 @@ New(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) ..() - if(!Init(arglist(args))) + if(!initTeleport(arglist(args))) return 0 return 1 - proc/Init(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout) + proc/initTeleport(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout) if(!setTeleatom(ateleatom)) return 0 if(!setDestination(adestination)) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 271db65fa93..70c418172da 100755 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -380,7 +380,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee containername = "Medical crate" group = "Medical" -/datum/supply_packs/medical +/datum/supply_packs/bloodpack name = "BloodPack crate" contains = list(/obj/item/weapon/storage/box/bloodpacks, /obj/item/weapon/storage/box/bloodpacks, diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index f65ee6be508..73555f38899 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -51,36 +51,17 @@ var/const/BORG_WIRE_CAMERA = 16 /datum/wires/robot/UpdatePulsed(var/index) - var/mob/living/silicon/robot/R = holder switch(index) if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI if(!R.emagged) - var/new_ai = select_active_ai(R) + var/mob/living/silicon/ai/new_ai = select_active_ai(R) if(new_ai && (new_ai != R.connected_ai)) + R.connected_ai.connected_robots -= src R.connected_ai = new_ai + new_ai.connected_robots += src R.notify_ai(1) - var/numberer = 1 // Send images the Cyborg has taken to the AI's album upon sync. - for(var/datum/picture/z in R.aiCamera.aipictures) - if(R.connected_ai.aiCamera.aipictures.len == 0) - var/datum/picture/p = new/datum/picture() - p = z - p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])" - R.connected_ai.aiCamera.aipictures += p - numberer++ - continue - for(var/datum/picture/t in R.connected_ai.aiCamera.aipictures) //Hopefully to prevent someone spamming images to silicons, by spamming this wire - if((z.fields["pixel_y"] != t.fields["pixel_y"]) && (z.fields["pixel_x"] != t.fields["pixel_x"])) //~2.26 out of 1000 chance this will stop something it shouldn't - var/datum/picture/p = new/datum/picture() - p = z - p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])" - R.connected_ai.aiCamera.aipictures += p - else - continue - numberer++ - if(R.aiCamera.aipictures.len > 0) - R << "Locally saved images synced with AI. Images were retained in local database in case of loss of connection with the AI." - + R.sync() if (BORG_WIRE_CAMERA) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) R.camera.kick_viewers() // Kick anyone watching the Cyborg's camera diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index bb1a1abc757..48408cdf18d 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -57,7 +57,7 @@ a.triggerAlarm("Power", src, cameras, source) return -/area/proc/atmosalert(danger_level) +/area/proc/atmosalert(danger_level, var/set_firelocks=1) // if(type==/area) //No atmos alarms in space // return 0 //redudant @@ -68,7 +68,7 @@ danger_level = max(danger_level, AA.danger_level) if(danger_level != atmosalm) - if (danger_level < 1 && atmosalm >= 1) + if (set_firelocks && danger_level < 1 && atmosalm >= 1) //closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise air_doors_open() @@ -92,7 +92,8 @@ aiPlayer.triggerAlarm("Atmosphere", src, cameras, src) for(var/obj/machinery/computer/station_alert/a in machines) a.triggerAlarm("Atmosphere", src, cameras, src) - air_doors_close() + if (set_firelocks) + air_doors_close() atmosalm = danger_level for(var/area/RA in related) diff --git a/code/game/gamemodes/calamity/calamity.dm b/code/game/gamemodes/calamity/calamity.dm index 0d8b46b318e..a4e617aaf4a 100644 --- a/code/game/gamemodes/calamity/calamity.dm +++ b/code/game/gamemodes/calamity/calamity.dm @@ -91,7 +91,7 @@ // Add the cortical borer event var/list/moderate_event_list = EModerate.available_events - var/event = new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 400, one_shot = 1) + var/event = new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 400, is_one_shot = 1) moderate_event_list.Add(event) if(chosen_atypes) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index b78baf2816d..a3829207fe5 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -331,11 +331,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", if(istype(M,/mob/dead)) var/mob/dead/D = M - D.manifest() - user.visible_message( \ - "\red [user] drags the ghost to our plan of reality!", \ - "\red You drag the ghost to our plan of reality!" \ - ) + D.manifest(user) return if(!istype(M)) return diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm index 3dac9f21488..59cca0df8b3 100644 --- a/code/game/gamemodes/events/space_ninja.dm +++ b/code/game/gamemodes/events/space_ninja.dm @@ -531,7 +531,6 @@ As such, it's hard-coded for now. No reason for it not to be, really. else equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask) equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt) var/obj/item/weapon/rig/light/ninja/ninjasuit = new(src) @@ -546,16 +545,16 @@ As such, it's hard-coded for now. No reason for it not to be, really. equip_to_slot_or_del(ninjasuit,slot_back) - if(istype(wear_suit,/obj/item/weapon/rig)) - var/obj/item/weapon/rig/rig = wear_suit - if(rig.air_supply) - internal = rig.air_supply - if(!internal && s_store) - internal = s_store - if(internal) - internals.icon_state = "internal1" - spawn(10) ninjasuit.toggle_seals(src,1) + if(istype(back,/obj/item/weapon/rig)) + var/obj/item/weapon/rig/rig = back + if(rig.air_supply) + internal = rig.air_supply + if(!internal && s_store) + internal = s_store + if(internal) + internals.icon_state = "internal1" + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 68bf3935d86..e90b65a333a 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -56,7 +56,7 @@ "Devices and Tools" = list( new/datum/uplink_item(/obj/item/weapon/card/emag, 3, "Cryptographic Sequencer", "EC"), new/datum/uplink_item(/obj/item/weapon/storage/toolbox/syndicate, 1, "Fully Loaded Toolbox", "ST"), - new/datum/uplink_item(/obj/item/weapon/stamp/chameleon, 3, "Morphic Chameleon Stmap", "CS"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/clerical, 3, "Morphic Clerical Kit", "CK"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/space, 3, "Space Suit", "SS"), new/datum/uplink_item(/obj/item/clothing/glasses/thermal/syndi, 3, "Thermal Imaging Glasses", "TM"), new/datum/uplink_item(/obj/item/device/encryptionkey/binary, 3, "Binary Translator Key", "BT"), @@ -154,16 +154,14 @@ var/pltext = "Player list:" for(var/mob/M in player_list) - if(M.mind) - pltext += print_player_lite(M.mind) if(M.client) clients++ if(ishuman(M)) - if(!M.stat) + if(M.stat != DEAD) surviving_humans++ if(M.loc && M.loc.loc && M.loc.loc.type in escape_locations) escaped_humans++ - if(!M.stat) + if(M.stat != DEAD) surviving_total++ if(M.loc && M.loc.loc && M.loc.loc.type in escape_locations) escaped_total++ diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 0c7e738cff9..3819c2d9d53 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -117,6 +117,18 @@ first_run() +/obj/machinery/alarm/Del() + //If there's an active alarm, clear it after minute so that alarms don't keep going forver + delayed_reset() + ..() + +//needed to cancel the alarm after it is deleted +/obj/machinery/alarm/proc/delayed_reset() + var/area/A = alarm_area + src = null + spawn(600) + //It makes sense not to touch firelocks here. The alarm itself is gone, we have no idea what the atmos is like. + A.atmosalert(0, set_firelocks=0) /obj/machinery/alarm/proc/first_run() alarm_area = get_area(src) @@ -1282,6 +1294,20 @@ FIRE ALARM pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 +/obj/machinery/firealarm/Del() + //so fire alarms don't keep going forever + delayed_reset() + ..() + +//needed to cancel the alarm after it is deleted +/obj/machinery/firealarm/proc/delayed_reset() + var/area/A = get_area(src) + if (!A) return + + src = null + spawn(600) + A.firereset() + /obj/machinery/firealarm/initialize() if(z in config.contact_levels) if(security_level) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 154b2d4dc73..5219bd22b7c 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -108,6 +108,7 @@ update_flag if (src.destroyed) src.overlays = 0 src.icon_state = text("[]-1", src.canister_color) + return if(icon_state != "[canister_color]") icon_state = "[canister_color]" diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 4dd60649253..179557fb262 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -643,6 +643,9 @@ Auto Patrol: []"}, return src.anchored = 0 for(var/mob/living/M in view(search_range,src)) //Let's find us a criminal + if(M.invisibility >= INVISIBILITY_LEVEL_ONE) // Cannot see him. see_invisible is a mob-var + continue + if(istype(M, /mob/living/carbon)) var/mob/living/carbon/C = M if(C.stat || C.handcuffed) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 4e064e347ee..eab3e5eda7e 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -55,9 +55,7 @@ if(!alarm_on) triggerCameraAlarm() - spawn(50) - src = null - cancelCameraAlarm() //so camera alarms don't just go on forever + cancelCameraAlarm() ..() /obj/machinery/camera/emp_act(severity) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index aa5d7a02f17..454e6e44fc7 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -33,7 +33,7 @@ var/datum/dna2/record/buf=null var/read_only = 0 //Well,it's still a floppy disk -/obj/item/weapon/disk/data/proc/Initialize() +/obj/item/weapon/disk/data/proc/initializeDisk() buf = new buf.dna=new @@ -42,7 +42,7 @@ read_only = 1 New() - Initialize() + initializeDisk() buf.types=DNA2_BUF_UE|DNA2_BUF_UI //data = "066000033000000000AF00330660FF4DB002690" //data = "0C80C80C80C80C80C8000000000000161FBDDEF" - Farmer Jeff @@ -57,7 +57,7 @@ read_only = 1 New() - Initialize() + initializeDisk() buf.types=DNA2_BUF_SE var/list/new_SE=list(0x098,0x3E8,0x403,0x44C,0x39F,0x4B0,0x59D,0x514,0x5FC,0x578,0x5DC,0x640,0x6A4) for(var/i=new_SE.len;i<=DNA_SE_LENGTH;i++) diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index ba91ec2eea8..f4b5d257a05 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -444,7 +444,7 @@ var/global/list/holodeck_programs = list( throw_range = 5 throwforce = 0 w_class = 2.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = FPRINT | TABLEPASS | NOSHIELD | NOBLOODY var/active = 0 /obj/item/weapon/holo/esword/green diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index b93855f0931..0a7f27d7016 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -23,6 +23,69 @@ user.reset_view(current) return 1 + ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + if(src.z > 6) return + if(stat & (NOPOWER|BROKEN)) return + if(user.stat) return + + var/data[0] + + data["current"] = null + + var/list/L = list() + for (var/obj/machinery/camera/C in cameranet.cameras) + if(can_access_camera(C)) + L.Add(C) + + camera_sort(L) + + var/cameras[0] + for(var/obj/machinery/camera/C in L) + var/cam[0] + cam["name"] = C.c_tag + cam["deact"] = !C.can_use() + cam["camera"] = "\ref[C]" + cam["x"] = C.x + cam["y"] = C.y + cam["z"] = C.z + + cameras[++cameras.len] = cam + + if(C == current) + data["current"] = cam + + data["cameras"] = cameras + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800) + + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "sec_camera_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "sec_camera_map_header.tmpl") + + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + if(href_list["switchTo"]) + if(src.z>6 || stat&(NOPOWER|BROKEN)) return + if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return + var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras + if(!C) return + + switch_to_camera(usr, C) + return 1 + else if(href_list["reset"]) + if(src.z>6 || stat&(NOPOWER|BROKEN)) return + if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return + current = null + usr.check_eye(current) + return 1 + else + . = ..() attack_hand(var/mob/user as mob) if (src.z > 6) @@ -32,35 +95,7 @@ if(!isAI(user)) user.set_machine(src) - - var/list/L = list() - for (var/obj/machinery/camera/C in cameranet.cameras) - L.Add(C) - - camera_sort(L) - - var/list/D = list() - D["Cancel"] = "Cancel" - for(var/obj/machinery/camera/C in L) - if(can_access_camera(C)) - D[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C - - var/t = input(user, "Which camera should you change to?") as null|anything in D - if(!t) - user.unset_machine() - return 0 - - var/obj/machinery/camera/C = D[t] - - if(t == "Cancel") - user.unset_machine() - return 0 - - if(C) - switch_to_camera(user, C) - spawn(5) - attack_hand(user) - return + ui_interact(user) proc/can_access_camera(var/obj/machinery/camera/C) var/list/shared_networks = src.network & C.network @@ -79,6 +114,7 @@ if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon))) return 0 src.current = C + check_eye(user) use_power(50) return 1 diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index a85b24d8fb1..fdbaae21cc8 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -75,6 +75,8 @@ if(istype(C.loc, /mob/living/carbon/human)) var/mob/living/carbon/human/H = C.loc + if(H.w_uniform != C) + continue var/list/crewmemberData = list() diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index ca692bbbee3..e14c2779811 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -576,9 +576,9 @@ What a mess.*/ return photo.img if(istype(user, /mob/living/silicon)) var/mob/living/silicon/tempAI = usr - var/datum/picture/selection = tempAI.GetPicture() + var/obj/item/weapon/photo/selection = tempAI.GetPicture() if (selection) - return selection.fields["img"] + return selection.img /obj/machinery/computer/secure_data/emp_act(severity) if(stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index d1e3887e4b9..4fc82ebf4aa 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -381,7 +381,7 @@ // Delete the mob. del(occupant) occupant = null - + name = initial(name) return @@ -442,7 +442,6 @@ src.add_fingerprint(M) /obj/machinery/cryopod/verb/eject() - set name = "Eject Pod" set category = "Object" set src in oview(1) @@ -464,6 +463,8 @@ src.go_out() add_fingerprint(usr) + + name = initial(name) return /obj/machinery/cryopod/verb/move_inside() @@ -511,6 +512,7 @@ time_entered = world.time src.add_fingerprint(usr) + name = "[name] ([usr.name])" return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index e595cea9333..49252eaac64 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -913,9 +913,9 @@ About the new airlock wires panel: if(operating == -1) new /obj/item/weapon/circuitboard/broken(src.loc) operating = 0 - else + else if (!electronics) create_electronics() - + electronics.loc = src.loc electronics = null @@ -1059,13 +1059,17 @@ About the new airlock wires panel: /obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) ..() + //High-sec airlocks are much harder to completely break by emitters. + if(secured_wires) + emitter_resistance *= 3 + //if assembly is given, create the new door from the assembly if (assembly) assembly_type = assembly.type - + electronics = assembly.electronics electronics.loc = src - + //update the door's access to match the electronics' secured_wires = electronics.secure if(electronics.one_access) @@ -1073,7 +1077,7 @@ About the new airlock wires panel: req_one_access = src.electronics.conf_access else req_access = src.electronics.conf_access - + //get the name from the assembly if(assembly.created_name) name = assembly.created_name @@ -1093,8 +1097,8 @@ About the new airlock wires panel: src.closeOther = A break -// Most doors will never be deconstructed over the course of a round, -// so as an optimization defer the creation of electronics until +// Most doors will never be deconstructed over the course of a round, +// so as an optimization defer the creation of electronics until // the airlock is deconstructed /obj/machinery/door/airlock/proc/create_electronics() //create new electronics @@ -1102,7 +1106,7 @@ About the new airlock wires panel: src.electronics = new/obj/item/weapon/airlock_electronics/secure( src.loc ) else src.electronics = new/obj/item/weapon/airlock_electronics( src.loc ) - + //update the electronics to match the door's access if(!src.req_access) src.check_access() diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index bc8719060f4..c3ab77d74a1 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -25,6 +25,8 @@ var/air_properties_vary_with_direction = 0 var/maxhealth = 300 var/health + var/emitter_hits = 0 // For use when tracking amount of emitter hits taken. + var/emitter_resistance = 10 // Amount of emitter hits doors whistand var/min_force = 10 //minimum amount of force needed to damage the door with a melee weapon var/hitsound = 'sound/weapons/smash.ogg' //sound door makes when hit with a weapon @@ -133,9 +135,22 @@ if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return + // Emitter Blasts - these will eventually completely destroy the door, given enough time. + if (istype(Proj, /obj/item/projectile/beam/emitter)) + if(health > 0) + Proj.damage /= 4 + else + emitter_hits ++ + if(emitter_hits >= emitter_resistance) + visible_message("\red [src.name] breaks apart!", 1) + new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes! + del(src) + if(Proj.damage) take_damage(Proj.damage) + + /obj/machinery/door/hitby(AM as mob|obj) ..() diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 4f5e416d335..9ab7dabb2d1 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -6,6 +6,7 @@ var/id = 1.0 dir = 1 explosion_resistance = 25 + emitter_resistance = 50 // Lots of emitter blasts, it's blast door after all. /obj/machinery/door/poddoor/New() . = ..() @@ -28,6 +29,7 @@ icon_state = "pdoor0" return + /obj/machinery/door/poddoor/attackby(obj/item/weapon/C as obj, mob/user as mob) src.add_fingerprint(user) if (!( istype(C, /obj/item/weapon/crowbar) || (istype(C, /obj/item/weapon/twohanded/fireaxe) && C:wielded == 1) )) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 8d4d4ac2df2..cf19d9de278 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -55,6 +55,8 @@ var/datum/effect/effect/system/spark_spread/spark_system //the spark system, used for generating... sparks? + var/wrenching = 0 + /obj/machinery/porta_turret/stationary lethal = 1 installation = /obj/item/weapon/gun/energy/laser @@ -223,7 +225,7 @@ else usr << "It has to be secured first!" - updateUsrDialog() + attack_hand(usr) return switch(href_list["operation"]) //toggles customizable behavioural protocols @@ -242,7 +244,7 @@ check_access = !check_access if("checkxenos") check_anomalies = !check_anomalies - updateUsrDialog() + attack_hand(usr) /obj/machinery/porta_turret/power_change() @@ -288,19 +290,32 @@ sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit on = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here - else if((istype(I, /obj/item/weapon/wrench)) && (!on)) - if(raised) return + else if((istype(I, /obj/item/weapon/wrench))) + if(on || raised) + user << "" + return + if(wrenching) + user << "Someone is already [anchored ? "un" : ""]securing the turret!" + return + if(!anchored && isinspace()) + user << "Cannot secure turrets in space!" + return + user.visible_message( \ + "[user] begins [anchored ? "un" : ""]securing the turret.", \ + "You begin [anchored ? "un" : ""]securing the turret." \ + ) + + wrenching = 1 if(do_after(user, 50)) //This code handles moving the turret around. After all, it's a portable turret! - if(!anchored && !isinspace()) + if(!anchored) playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) anchored = 1 invisibility = INVISIBILITY_LEVEL_TWO update_icon() user << "You secure the exterior bolts on the turret." - cover = new /obj/machinery/porta_turret_cover(loc) //create a new turret. While this is handled in process(), this is to workaround a bug where the turret becomes invisible for a split second - cover.Parent_Turret = src //make the cover's parent src + create_cover() else if(anchored) playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) anchored = 0 @@ -308,6 +323,7 @@ invisibility = 0 update_icon() del(cover) //deletes the cover, and the turret instance itself becomes its own cover. - qdel + wrenching = 0 else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda)) //Behavior lock/unlock mangement @@ -348,7 +364,7 @@ spawn() sleep(60) attacked = 0 - + ..() if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) @@ -395,7 +411,10 @@ update_icon() del(cover) //deletes the cover - no need on keeping it there! - del - +/obj/machinery/porta_turret/proc/create_cover() + if(cover == null && anchored) + cover = new /obj/machinery/porta_turret_cover(loc) //if the turret has no cover and is anchored, give it a cover + cover.Parent_Turret = src //assign the cover its Parent_Turret, which would be this (src) /obj/machinery/porta_turret/process() //the main machinery process @@ -406,9 +425,7 @@ if(stat & BROKEN) //if the turret is borked del(cover) //delete its cover, assuming it has one. Workaround for a pesky little bug - qdel else - - cover = new /obj/machinery/porta_turret_cover(loc) //if the turret has no cover and is anchored, give it a cover - cover.Parent_Turret = src //assign the cover its Parent_Turret, which would be this (src) + create_cover() if(stat & (NOPOWER|BROKEN)) //if the turret has no power or is broken, make the turret pop down if it hasn't already @@ -445,6 +462,9 @@ secondarytargets += L /obj/machinery/porta_turret/proc/assess_living(var/mob/living/L) + if(L.invisibility >= INVISIBILITY_LEVEL_ONE) // Cannot see him. see_invisible is a mob-var + return TURRET_NOT_TARGET + if(!L) return TURRET_NOT_TARGET @@ -464,7 +484,7 @@ if(check_synth) //If it's set to attack all non-silicons, target them! if(L.lying) - return TURRET_SECONDARY_TARGET + return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET return TURRET_PRIORITY_TARGET if(iscuffed(L)) // If the target is handcuffed, leave it alone @@ -480,7 +500,7 @@ return TURRET_NOT_TARGET //if threat level < 4, keep going if(L.lying) //if the perp is lying down, it's still a target but a less-important target - return TURRET_SECONDARY_TARGET + return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee @@ -840,11 +860,6 @@ density = 0 var/obj/machinery/porta_turret/Parent_Turret = null - -//The below code is pretty much just recoded from the initial turret object. It's necessary but uncommented because it's exactly the same! -//>necessary -//I'm not fixing it because i'm fucking bored of this code already, but someone should just reroute these to the parent turret's procs. - /obj/machinery/porta_turret_cover/attack_ai(mob/user) return attack_hand(user) @@ -853,7 +868,6 @@ /obj/machinery/porta_turret_cover/Topic(href, href_list) Parent_Turret.Topic(href, href_list, 1) // Calling another object's Topic requires that we claim to not have a window, otherwise BYOND's base proc will runtime. - updateUsrDialog() /obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user) Parent_Turret.attackby(I, user) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 5a52dde42e4..26f1c620c7a 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -26,7 +26,6 @@ var/vend_power_usage = 150 //actuators and stuff var/active = 1 //No sales pitches if off! - var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names). var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. @@ -122,9 +121,6 @@ /obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0) - if(delay_product_spawn) - sleep(15) //Make ABSOLUTELY SURE the seed datum is properly populated. - for(var/typepath in productlist) var/amount = productlist[typepath] var/price = prices[typepath] @@ -147,9 +143,6 @@ R.category=CAT_NORMAL product_records += R - if(delay_product_spawn) - sleep(5) //sleep(1) did not seem to cut it, so here we are. - var/atom/temp = typepath R.product_name = initial(temp.name) @@ -791,7 +784,6 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - delay_product_spawn = 1 products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, @@ -803,6 +795,34 @@ /obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,) premium = list(/obj/item/toy/waterflower = 1) +/obj/machinery/vending/hydroseeds/build_inventory(var/list/productlist,hidden=0,req_coin=0) + + for(var/typepath in productlist) + var/amount = productlist[typepath] + var/price = prices[typepath] + if(isnull(amount)) amount = 1 + + var/datum/data/vending_product/R = new /datum/data/vending_product() + + R.product_path = typepath + R.amount = amount + R.price = price + R.display_color = pick("red","blue","green") + + if(hidden) + R.category=CAT_HIDDEN + hidden_records += R + else if(req_coin) + R.category=CAT_COIN + coin_records += R + else + R.category=CAT_NORMAL + product_records += R + + var/obj/item/seeds/S = new typepath(src) + R.product_name = S.name + del(S) + return /obj/machinery/vending/magivend name = "MagiVend" @@ -877,7 +897,7 @@ icon_state = "robotics" icon_deny = "robotics-deny" req_access_txt = "29" - products = list(/obj/item/clothing/suit/storage/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, + products = list(/obj/item/clothing/suit/storage/toggle/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, /obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 20703363ff8..d3c249b7473 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -46,8 +46,8 @@ return // temporary fix for broken icon until somebody gets around to make these player-buildable -/turf/simulated/floor/mech_bay_recharge_floor/attackby(obj/item/C as obj, mob/user as mob) - ..() +/turf/simulated/floor/mech_bay_recharge_floor/attackby(obj/item/C as obj, mob/user as mob) + ..() if(floor_type) icon_state = "recharge_floor" else @@ -190,45 +190,28 @@ var/turf/simulated/floor/mech_bay_recharge_floor/F = locate() in range(1,src) if(F) F.init_devices() - - var/output = "[src.name]" - if(!recharge_floor) - output += "Mech Bay Recharge Station not initialized.
" + ui_interact(user) + +/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/list/data = list() + data["has_floor"] = recharge_floor + data["has_port"] = recharge_port + if(recharge_floor && recharge_floor.recharging_mecha && recharge_floor.recharging_mecha.cell) + data["has_mech"] = 1 + data["mecha_name"] = recharge_floor.recharging_mecha || "None" + data["mecha_charge"] = isnull(recharge_floor.recharging_mecha) ? 0 : recharge_floor.recharging_mecha.cell.charge + data["mecha_maxcharge"] = isnull(recharge_floor.recharging_mecha) ? 0 : recharge_floor.recharging_mecha.cell.maxcharge + data["mecha_charge_percentage"] = isnull(recharge_floor.recharging_mecha) ? 0 : round(recharge_floor.recharging_mecha.cell.percent()) else - output += {"Mech Bay Recharge Station Data:
- Mecha: [recharge_floor.recharging_mecha||"None"]
"} - if(recharge_floor.recharging_mecha) - var/cell_charge = recharge_floor.recharging_mecha.get_charge() - output += "Cell charge: [isnull(cell_charge)?"No powercell found":"[recharge_floor.recharging_mecha.cell.charge]/[recharge_floor.recharging_mecha.cell.maxcharge]"]
" - output += "
" - if(!recharge_port) - output += "Mech Bay Power Port not initialized.
" - else - output += "Mech Bay Power Port Status: [recharge_port.active()?"Now charging":"On hold"]
" - - /* - output += {"
- Settings: -
- Start sequence on succesful init: [autostart?"On":"Off"]
- Recharge Port Voltage: Low - Medium - High
-
"} - */ - - output += "" - user << browse(output, "window=mech_bay_console") - onclose(user, "mech_bay_console") - return - -// unused at the moment, also lacks any kind of exploit prevention -/* -/obj/machinery/computer/mech_bay_power_console/Topic(href, href_list) - if(href_list["autostart"]) - autostart = !autostart - if(href_list["voltage"]) - voltage = text2num(href_list["voltage"]) - if(recharge_port) - recharge_port.set_voltage(voltage) - updateUsrDialog() - return -*/ + data["has_mech"] = 0 + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "mech_bay_console.tmpl", "Mech Bay Control Console", 500, 325) + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + // auto update every Master Controller tick + ui.set_auto_update(1) \ No newline at end of file diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index ba4493522f6..e56dbe71e86 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -453,10 +453,10 @@ for(var/datum/design/D in files.known_designs) if(D.build_type&16) if(D.category in part_sets)//Checks if it's a valid category - if(add_part_to_set(D.category, text2path(D.build_path)))//Adds it to said category + if(add_part_to_set(D.category, D.build_path))//Adds it to said category i++ else - if(add_part_to_set("Misc", text2path(D.build_path)))//If in doubt, chunk it into the Misc + if(add_part_to_set("Misc", D.build_path))//If in doubt, chunk it into the Misc i++ return i diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm index d50d595d3ea..8d8328bc9f5 100644 --- a/code/game/objects/effects/decals/remains.dm +++ b/code/game/objects/effects/decals/remains.dm @@ -1,23 +1,28 @@ -/obj/effect/decal/remains/human +/obj/effect/decal/remains name = "remains" - desc = "They look like human remains. They have a strange aura about them." gender = PLURAL icon = 'icons/effects/blood.dmi' icon_state = "remains" - anchored = 1 + anchored = 0 + +/obj/effect/decal/remains/human + desc = "They look like human remains. They have a strange aura about them." /obj/effect/decal/remains/xeno - name = "remains" desc = "They look like the remains of something... alien. They have a strange aura about them." - gender = PLURAL - icon = 'icons/effects/blood.dmi' icon_state = "remainsxeno" - anchored = 1 /obj/effect/decal/remains/robot - name = "remains" desc = "They look like the remains of something mechanical. They have a strange aura about them." - gender = PLURAL icon = 'icons/mob/robots.dmi' icon_state = "remainsrobot" - anchored = 1 \ No newline at end of file + +/obj/effect/decal/remains/attack_hand(mob/user as mob) + user << "[src] sinks together into a pile of ash." + var/turf/simulated/floor/F = get_turf(src) + if (istype(F)) + new /obj/effect/decal/cleanable/ash(F) + del(src) + +/obj/effect/decal/remains/robot/attack_hand(mob/user as mob) + return diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 16bde74e693..b69f85af388 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1052,7 +1052,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message) var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply)" - new_info(news_silent, newstone, reception_message) + new_info(message_silent, newstone, reception_message) log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") new_message = 1 diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 99c4f960b0f..f64473ba549 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -1,6 +1,5 @@ /*********************MANUALS (BOOKS)***********************/ -//Oh god what the fuck I am not good at computer /obj/item/weapon/book/manual icon = 'icons/obj/library.dmi' due_date = 0 // Game time in 1/10th seconds @@ -13,26 +12,29 @@ author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Station Repairs and Construction" +/obj/item/weapon/book/manual/engineering_construction/New() + ..() dat = {" - + "} - /obj/item/weapon/book/manual/engineering_particle_accelerator name = "Particle Accelerator User's Guide" icon_state ="bookParticleAccelerator" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Particle Accelerator User's Guide" +/obj/item/weapon/book/manual/engineering_particle_accelerator/New() + ..() dat = {"