diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index 7b0d3afa98..62a6daea16 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -2,17 +2,18 @@ Contains helper procs for airflow, handled in /connection_group. */ - mob/var/tmp/last_airflow_stun = 0 mob/proc/airflow_stun() if(stat == 2) return 0 if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0 + if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN)) - src << "\blue You stay upright as the air rushes past you." + src << "You stay upright as the air rushes past you." return 0 - if(weakened <= 0) src << "\red The sudden rush of air knocks you over!" - weakened = max(weakened,5) + if(!lying) + src << "The sudden rush of air knocks you over!" + Weaken(5) last_airflow_stun = world.time mob/living/silicon/airflow_stun() @@ -22,16 +23,9 @@ mob/living/carbon/metroid/airflow_stun() return mob/living/carbon/human/airflow_stun() - if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0 - if(buckled) return 0 if(shoes) if(shoes.flags & NOSLIP) return 0 - if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN)) - src << "\blue You stay upright as the air rushes past you." - return 0 - if(weakened <= 0) src << "\red The sudden rush of air knocks you over!" - weakened = max(weakened,rand(1,5)) - last_airflow_stun = world.time + ..() atom/movable/proc/check_airflow_movable(n) @@ -84,10 +78,8 @@ obj/item/check_airflow_movable(n) if(istype(src, /mob/living/carbon/human)) if(src:buckled) return - if(src:shoes) - if(istype(src:shoes, /obj/item/clothing/shoes/magboots)) - if(src:shoes:magpulse) - return + if(src:shoes && src:shoes.flags & NOSLIP) + return src << "\red You are sucked away by airflow!" var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2) if(airflow_falloff < 1) @@ -207,7 +199,8 @@ mob/airflow_hit(atom/A) for(var/mob/M in hearers(src)) M.show_message("\red \The [src] slams into \a [A]!",1,"\red You hear a loud slam!",2) playsound(src.loc, "smash.ogg", 25, 1, -1) - weakened = max(weakened, (istype(A,/obj/item) ? A:w_class : rand(1,5))) //Heheheh + var/weak_amt = istype(A,/obj/item) ? A:w_class : rand(1,5) //Heheheh + Weaken(weak_amt) . = ..() obj/airflow_hit(atom/A) @@ -239,10 +232,10 @@ mob/living/carbon/human/airflow_hit(atom/A) apply_damage(b_loss/3, BRUTE, "groin", blocked, 0, "Airflow") if(airflow_speed > 10) - paralysis += round(airflow_speed * vsc.airflow_stun) - stunned = max(stunned,paralysis + 3) + Paralyse(round(airflow_speed * vsc.airflow_stun)) + Stun(paralysis + 3) else - stunned += round(airflow_speed * vsc.airflow_stun/2) + Stun(round(airflow_speed * vsc.airflow_stun/2)) . = ..() zone/proc/movables() diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 6e65b47e00..01b9509ae8 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -45,7 +45,7 @@ var/global/list/skin_styles_female_list = list() //unused var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6", "None") //Curse whoever made male/female underwear diffrent colours var/global/list/underwear_f = list("Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6", "Black Sports" = "f7","White Sports" = "f8","None") //undershirt -var/global/list/undershirt_t = list("Black Tank top" = "u1", "White Tank top" = "u2", "Black shirt" = "u3", "White shirt" = "u4", "None") +var/global/list/undershirt_t = list("White Tank top" = "u1", "Black Tank top" = "u2", "Black shirt" = "u3", "White shirt" = "u4", "None") //Backpacks var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt") var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index e1c42254a6..135da6bb60 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -72,7 +72,8 @@ var/list/medical_positions = list( "Medical Doctor", "Geneticist", "Psychiatrist", - "Chemist" + "Chemist", + "Paramedic" ) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index c3acade589..359f30e643 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -349,7 +349,12 @@ Auto Patrol: []"}, if(istype(src.target,/mob/living/carbon)) var/mob/living/carbon/C = target - if(!C.handcuffed && !src.arrest_type) + var/wearing_hardsuit + if(istype(C,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = C + if(istype(H.back, /obj/item/weapon/rig) && istype(H.gloves,/obj/item/clothing/gloves/rig)) + wearing_hardsuit = 1 + if(!wearing_hardsuit && !C.handcuffed && !src.arrest_type) playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) mode = SECBOT_ARREST visible_message("\red [src] is trying to put handcuffs on [src.target]!") diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 50a814b8de..1a20fd29ef 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -31,13 +31,13 @@ var/alarm_on = 0 var/busy = 0 + var/on_open_network = 0 + /obj/machinery/camera/New() wires = new(src) assembly = new(src) assembly.state = 4 - invalidateCameraCache() - /* // Use this to look for cameras that have the same c_tag. for(var/obj/machinery/camera/C in cameranet.cameras) var/list/tempnetwork = C.network&src.network @@ -56,18 +56,18 @@ /obj/machinery/camera/emp_act(severity) if(!isEmpProof()) if(prob(100/severity)) - invalidateCameraCache() stat |= EMPED SetLuminosity(0) kick_viewers() - triggerCameraAlarm(10 * severity) + triggerCameraAlarm(30 / severity) update_icon() + update_coverage() spawn(900) stat &= ~EMPED cancelCameraAlarm() update_icon() - invalidateCameraCache() + update_coverage() ..() /obj/machinery/camera/bullet_act(var/obj/item/projectile/P) @@ -114,7 +114,7 @@ destroy() /obj/machinery/camera/attackby(obj/W as obj, mob/living/user as mob) - invalidateCameraCache() + update_coverage() // DECONSTRUCTION if(isscrewdriver(W)) //user << "You start to [panel_open ? "close" : "open"] the camera's panel." @@ -195,7 +195,7 @@ //legacy support, if choice is != 1 then just kick viewers without changing status kick_viewers() else - invalidateCameraCache() + update_coverage() set_status( !src.status ) if (!(src.status)) visible_message("\red [user] has deactivated [src]!") @@ -215,11 +215,11 @@ //Used when someone breaks a camera /obj/machinery/camera/proc/destroy() - invalidateCameraCache() stat |= BROKEN kick_viewers() triggerCameraAlarm() update_icon() + update_coverage() //sparks var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() @@ -364,7 +364,7 @@ network_added = 1 if(network_added) - invalidateCameraCache() + update_coverage(1) /obj/machinery/camera/proc/remove_networks(var/list/networks) var/network_removed @@ -375,24 +375,24 @@ network_removed = 1 if(network_removed) - invalidateCameraCache() + update_coverage(1) /obj/machinery/camera/proc/replace_networks(var/list/networks) if(networks.len != network.len) network = networks - invalidateCameraCache() + update_coverage(1) return for(var/new_network in networks) if(!(new_network in network)) network = networks - invalidateCameraCache() + update_coverage(1) return /obj/machinery/camera/proc/clear_all_networks() if(network.len) network.Cut() - invalidateCameraCache() + update_coverage(1) /obj/machinery/camera/proc/nano_structure() var/cam[0] @@ -403,3 +403,17 @@ cam["y"] = y cam["z"] = z return cam + +/obj/machinery/camera/proc/update_coverage(var/network_change = 0) + if(network_change) + var/list/open_networks = difflist(network, restricted_camera_networks) + // Add or remove camera from the camera net as necessary + if(on_open_network && !open_networks.len) + cameranet.removeCamera(src) + else if(!on_open_network && open_networks.len) + on_open_network = 1 + cameranet.addCamera(src) + else + cameranet.updateVisibility(src, 0) + + invalidateCameraCache() diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 8be7f6ebe5..4ece6594f0 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -78,7 +78,7 @@ if(isscrewdriver(W)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) + var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) if(!input) usr << "No input found please hang up and try your call again." return @@ -100,9 +100,6 @@ C.auto_turn() C.replace_networks(uniquelist(tempnetwork)) - tempnetwork = difflist(C.network,restricted_camera_networks) - if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility. - cameranet.removeCamera(C) C.c_tag = input diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 00e3999332..d64857d004 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -24,6 +24,7 @@ return 0 M.buckled = src + M.facing_dir = null M.set_dir(dir) M.update_canmove() buckled_mob = M diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index 70e3628f67..2ad3df7ae5 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -140,7 +140,6 @@ ..() name = "DV-136ZB #[rand(1000,9999)]" c_tag = name - cameranet.removeCamera(src) // Sorry, no AI spying. /obj/machinery/camera/spy/check_eye(var/mob/user as mob) return 1 diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 246636890d..5ed83d086b 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -28,7 +28,7 @@ if (C == user) place_handcuffs(user, user) return - + //check for an aggressive grab for (var/obj/item/weapon/grab/G in C.grabbed_by) if (G.loc == user && G.state >= GRAB_AGGRESSIVE) @@ -41,11 +41,15 @@ if (ishuman(target)) var/mob/living/carbon/human/H = target - + if (!H.has_organ_for_slot(slot_handcuffed)) - user << "\red \The [H] needs at least two wrists before you can cuff them together!" + user << "\The [H] needs at least two wrists before you can cuff them together!" return - + + if(istype(H.gloves,/obj/item/clothing/gloves/rig)) // Can't cuff someone who's in a deployed hardsuit. + user << "The cuffs won't fit around \the [H.gloves]!" + return + H.attack_log += text("\[[time_stamp()]\] Has been handcuffed (attempt) by [user.name] ([user.ckey])") user.attack_log += text("\[[time_stamp()]\] Attempted to handcuff [H.name] ([H.ckey])") msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(H)]") @@ -62,7 +66,7 @@ feedback_add_details("handcuffs","H") O.process() return - + if (ismonkey(target)) var/mob/living/carbon/monkey/M = target var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey( ) @@ -155,13 +159,13 @@ var/last_chew = 0 var/turf/p_loc_m = C.loc playsound(src.loc, cuff_sound, 30, 1, -2) user.visible_message("\red [user] is trying to put handcuffs on [C]!") - + if (ishuman(C)) var/mob/living/carbon/human/H = C if (!H.has_organ_for_slot(slot_handcuffed)) user << "\red \The [H] needs at least two wrists before you can cuff them together!" return - + spawn(30) if(!C) return if(p_loc == user.loc && p_loc_m == C.loc) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index b4281a6033..ec55e6549e 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -248,6 +248,10 @@ glass = 1 else if(istype(S, /obj/item/stack/sheet/mineral) && S.sheettype) var/M = S.sheettype + // Ugly hack, will suffice for now. Need to fix it upstream as well, may rewrite mineral walls. ~Z + if(M in list("mhydrogen","osmium","tritium","platinum","iron")) + user << "You cannot make an airlock out of that material." + return if(S.get_amount() >= 2) playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly.") diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 0512b814b2..85415cd162 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -26,7 +26,7 @@ var/damage = Proj.damage if(!istype(Proj, /obj/item/projectile/beam)) damage *= 0.4 //non beams do reduced damage - + health -= damage ..() if(health <= 0) @@ -144,6 +144,10 @@ if(S.sheettype) var/M = S.sheettype + // Ugly hack, will suffice for now. Need to fix it upstream as well, may rewrite mineral walls. ~Z + if(M in list("mhydrogen","osmium","tritium","platinum","iron")) + user << "You cannot plate the girder in that material." + return if(!anchored) if(S.amount < 2) return S.use(2) @@ -271,11 +275,11 @@ //Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder) if(Proj.original != src && !prob(cover)) return -1 //pass through - + //Tasers and the like should not damage cultgirders. if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return - + health -= Proj.damage ..() if(health <= 0) diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index a53ceff7cb..6d50066a74 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -138,8 +138,8 @@ density = 1 icon_state = "up" else - buckled_mob.pixel_y = 0 - buckled_mob.old_y = 0 + M.pixel_y = 0 + M.old_y = 0 density = 0 icon_state = "down" diff --git a/code/global.dm b/code/global.dm index 39ef138914..fa07f74b1f 100644 --- a/code/global.dm +++ b/code/global.dm @@ -10,7 +10,7 @@ var/global/list/med_hud_users = list() // List of all entities using var/global/list/sec_hud_users = list() // List of all entities using a security HUD. // Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. -var/list/restricted_camera_networks = list("thunder","ERT","NUKE") +var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret") var/global/list/global_mutations = list() // List of hidden mutation things. var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called manually after an event. diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 605bff6be8..b106e41255 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -151,7 +151,7 @@ selectable = 1 toggleable = 1 use_power_cost = 50 - active_power_cost = 5 + active_power_cost = 10 passive_power_cost = 0 gun_type = /obj/item/weapon/gun/energy/crossbow/ninja diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 3d66c64602..a6c549b666 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -441,4 +441,32 @@ drain_loc = null interfaced_with = null - total_power_drained = 0 \ No newline at end of file + total_power_drained = 0 + +/* +//Maybe make this use power when active or something +/obj/item/rig_module/emp_shielding + name = "\improper EMP dissipation module" + desc = "A bewilderingly complex bundle of fiber optics and chips." + toggleable = 1 + usable = 0 + + activate_string = "Enable active EMP shielding" + deactivate_string = "Disable active EMP shielding" + + interface_name = "active EMP shielding system" + interface_desc = "A highly experimental system that augments the hardsuit's existing EM shielding." + var/protection_amount = 20 + +/obj/item/rig_module/emp_shielding/activate() + if(!..()) + return + + holder.emp_protection += protection_amount + +/obj/item/rig_module/emp_shielding/deactivate() + if(!..()) + return + + holder.emp_protection = max(0,(holder.emp_protection - protection_amount)) +*/ diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm index 830e0d784c..17498a31b2 100644 --- a/code/modules/clothing/spacesuits/rig/modules/modules.dm +++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm @@ -138,6 +138,7 @@ if(damage >= 2) usr << "The [interface_name] is damaged beyond use!" + return 0 if(world.time < next_use) usr << "You cannot use the [interface_name] again so soon." @@ -147,7 +148,7 @@ usr << "The suit is not initialized." return 0 - if(usr.lying || usr.stat || usr.stunned || usr.paralysis) + if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.weakened) usr << "You cannot use the suit in this state." return 0 @@ -157,7 +158,7 @@ if(holder.security_check_enabled && !holder.check_suit_access(usr)) usr << "Access denied." - return + return 0 if(!holder.check_power_cost(usr, use_power_cost, 0, src, (istype(usr,/mob/living/silicon ? 1 : 0) ) ) ) return 0 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index cc6776865a..d003d64d59 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -68,10 +68,12 @@ var/sealing // Keeps track of seal status independantly of canremove. var/offline = 1 // Should we be applying suit maluses? - var/offline_slowdown = 10 // If the suit is deployed and unpowered, it sets slowdown to this. + var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this. var/vision_restriction var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets. + var/emp_protection = 0 + // Wiring! How exciting. var/datum/wires/rig/wires var/datum/effect/effect/system/spark_spread/spark_system @@ -311,7 +313,7 @@ if(!istype(wearer) || loc != wearer || wearer.back != src || canremove || !cell || cell.charge <= 0) if(!cell || cell.charge <= 0) - if(electrified >0) + if(electrified > 0) electrified = 0 if(!offline) if(istype(wearer)) @@ -319,7 +321,7 @@ if (offline_slowdown < 3) wearer << "Your suit beeps stridently, and suddenly goes dead." else - wearer << "Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic instead of a powered suit." + wearer << "Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic composites instead of a powered suit." if(offline_vision_restriction == 1) wearer << "The suit optics flicker and die, leaving you with restricted vision." else if(offline_vision_restriction == 2) @@ -406,7 +408,7 @@ data["boots"] = (boots ? "[boots.name]" : "None.") data["chest"] = (chest ? "[chest.name]" : "None.") - data["charge"] = cell ? cell.charge : 0 + data["charge"] = cell ? round(cell.charge,1) : 0 data["maxcharge"] = cell ? cell.maxcharge : 0 data["chargestatus"] = cell ? Floor((cell.charge/cell.maxcharge)*50) : 0 @@ -416,7 +418,7 @@ data["aicontrol"] = control_overridden data["aioverride"] = ai_override_enabled data["securitycheck"] = security_check_enabled - data["malf"] = malfunctioning + data["malf"] = malfunction_delay var/list/module_list = list() @@ -493,6 +495,8 @@ return 1 if(istype(user)) + if(malfunction_check(user)) + return 0 if(user.back != src) return 0 if(locked_dna) @@ -509,10 +513,10 @@ return 1 +//TODO: Fix Topic vulnerabilities for malfunction and AI override. /obj/item/weapon/rig/Topic(href,href_list) - if(!check_suit_access(usr)) - return + return 0 if(href_list["toggle_piece"]) if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying)) @@ -545,7 +549,7 @@ usr.set_machine(src) src.add_fingerprint(usr) - return 1 + return 0 /obj/item/weapon/rig/proc/notify_ai(var/message) if(!message || !installed_modules || !installed_modules.len) @@ -684,49 +688,82 @@ //Todo /obj/item/weapon/rig/proc/malfunction() - return 0 - + return 0 + /obj/item/weapon/rig/emp_act(severity_class) - //class 1 severity is the most severe, not least. - malfunctioning += round(30/severity_class) - if(malfunction_delay <= 0) - malfunction_delay = 20 - take_hit(round(30/severity_class),"electrical pulse") + //set malfunctioning + if(emp_protection < 30) //for ninjas, really. + malfunctioning += 10 + if(malfunction_delay <= 0) + malfunction_delay = max(malfunction_delay, round(30/severity_class)) + + //drain some charge + if(cell) cell.emp_act(severity_class + 15) + + //possibly damage some modules + take_hit((100/severity_class), "electrical pulse", 1) /obj/item/weapon/rig/proc/shock(mob/user) if (electrocute_mob(user, cell, src)) spark_system.start() return 1 return 0 + +/obj/item/weapon/rig/proc/take_hit(damage, source, is_emp=0) -/obj/item/weapon/rig/proc/take_hit(damage,source) if(!installed_modules.len) return - //given that module damage is spread out across all modules, even this is probably not enough for emp to affect rigs much. - if(source != "electrical pulse") - var/protection = chest? chest.breach_threshold : 0 - if(!prob(max(0, damage - protection))) - return + var/chance + if(!is_emp) + chance = 2*max(0, damage - (chest? chest.breach_threshold : 0)) + else + //Want this to be roughly independant of the number of modules, meaning that X emp hits will disable Y% of the suit's modules on average. + //that way people designing hardsuits don't have to worry (as much) about how adding that extra module will affect emp resiliance by 'soaking' hits for other modules + chance = max(0, damage - emp_protection)*min(installed_modules.len/15, 1) + if(!prob(chance)) + return + + //deal addition damage to already damaged module first. + //This way the chances of a module being disabled aren't so remote. var/list/valid_modules = list() + var/list/damaged_modules = list() for(var/obj/item/rig_module/module in installed_modules) if(module.damage < 2) valid_modules |= module + if(module.damage > 0) + damaged_modules |= module - if(!valid_modules.len) - return + var/obj/item/rig_module/dam_module = null + if(damaged_modules.len) + dam_module = pick(damaged_modules) + else if(valid_modules.len) + dam_module = pick(valid_modules) + + if(!dam_module) return - var/obj/item/rig_module/dam_module = pick(valid_modules) dam_module.damage++ if(!source) source = "hit" - if(wearer) - wearer << "The [source] has [dam_module.damage >= 2 ? "destroyed" : "damaged"] your [dam_module.interface_name]!" + if(wearer) + if(dam_module.damage >= 2) + wearer << "The [source] has disabled your [dam_module.interface_name]!" + else + wearer << "The [source] has damaged your [dam_module.interface_name]!" dam_module.deactivate() +/obj/item/weapon/rig/proc/malfunction_check(var/mob/living/carbon/human/user) + if(malfunction_delay) + if(offline) + user << "The suit is completely unresponsive." + else + user << "ERROR: Hardware fault. Rebooting interface..." + return 1 + return 0 + /*/obj/item/weapon/rig/proc/forced_move(dir) if(locked_down) return 0 diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index 2de6b34a84..7f0291c038 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -39,9 +39,9 @@ flags_inv = HIDEJUMPSUIT|HIDETAIL flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT slowdown = 0 - //With 0.2 resiliance, will reach 10 breach damage after 9 laser carbine blasts. Completely immune to smg hits. + //will reach 10 breach damage after 18 laser carbine blasts, or 7 revolver hits. Completely immune to smg hits. breach_threshold = 28 - resilience = 0.1 + resilience = 0.05 can_breach = 1 sprite_sheets = list("Tajara" = 'icons/mob/species/tajaran/suit.dmi',"Unathi" = 'icons/mob/species/unathi/suit.dmi') supporting_limbs = list() diff --git a/code/modules/clothing/spacesuits/rig/rig_verbs.dm b/code/modules/clothing/spacesuits/rig/rig_verbs.dm index ce20244734..09db9b0325 100644 --- a/code/modules/clothing/spacesuits/rig/rig_verbs.dm +++ b/code/modules/clothing/spacesuits/rig/rig_verbs.dm @@ -141,6 +141,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(!check_power_cost(usr, 0, 0, 0, 0)) return @@ -168,6 +171,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(canremove) usr << "The suit is not active." return @@ -189,6 +195,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(!check_power_cost(usr, 0, 0, 0, 0)) return @@ -222,6 +231,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(!check_power_cost(usr, 0, 0, 0, 0)) return @@ -257,6 +269,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(canremove) usr << "The suit is not active." return diff --git a/code/modules/clothing/spacesuits/rig/suits/alien.dm b/code/modules/clothing/spacesuits/rig/suits/alien.dm index 5b35d6a139..cb64d2be44 100644 --- a/code/modules/clothing/spacesuits/rig/suits/alien.dm +++ b/code/modules/clothing/spacesuits/rig/suits/alien.dm @@ -4,6 +4,7 @@ suit_type = "NT breacher" icon_state = "breacher_rig_cheap" armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 70, bio = 100, rad = 50) + emp_protection = -20 slowdown = 6 offline_slowdown = 10 vision_restriction = 1 @@ -16,4 +17,4 @@ icon_state = "breacher_rig" armor = list(melee = 90, bullet = 90, laser = 90, energy = 90, bomb = 90, bio = 100, rad = 80) vision_restriction = 0 - slowdown = 4 \ No newline at end of file + slowdown = 4 diff --git a/code/modules/clothing/spacesuits/rig/suits/combat.dm b/code/modules/clothing/spacesuits/rig/suits/combat.dm index 55716179c6..9be2576838 100644 --- a/code/modules/clothing/spacesuits/rig/suits/combat.dm +++ b/code/modules/clothing/spacesuits/rig/suits/combat.dm @@ -8,7 +8,6 @@ suit_type = "combat hardsuit" armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/combat diff --git a/code/modules/clothing/spacesuits/rig/suits/ert.dm b/code/modules/clothing/spacesuits/rig/suits/ert.dm index d3db4baf84..feec1f5810 100644 --- a/code/modules/clothing/spacesuits/rig/suits/ert.dm +++ b/code/modules/clothing/spacesuits/rig/suits/ert.dm @@ -7,13 +7,12 @@ desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured and space ready." suit_type = "ERT commander" icon_state = "ert_commander_rig" - offline_slowdown = 3 helm_type = /obj/item/clothing/head/helmet/space/rig/ert req_access = list(access_cent_specops) - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100) + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60) allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \ /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \ /obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \ @@ -30,6 +29,9 @@ desc = "A suit worn by the engineering division of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured and space ready." suit_type = "ERT engineer" icon_state = "ert_engineer_rig" + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100) + + glove_type = /obj/item/clothing/gloves/rig/ert_engineer initial_modules = list( /obj/item/rig_module/ai_container, @@ -38,6 +40,10 @@ /obj/item/rig_module/device/rcd ) +/obj/item/clothing/gloves/rig/ert_engineer + name = "insulated gauntlets" + siemens_coefficient = 0 + /obj/item/weapon/rig/ert/medical name = "ERT-M suit control module" desc = "A suit worn by the medical division of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready." diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index db54855b83..a11c1ce16f 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -6,6 +6,7 @@ suit_type = "light suit" allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell) armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) + emp_protection = 10 slowdown = 0 flags = STOPPRESSUREDAMAGE | THICKMATERIAL offline_slowdown = 0 @@ -18,6 +19,8 @@ /obj/item/clothing/suit/space/rig/light name = "suit" + breach_threshold = 18 //comparable to voidsuits + resilience = 0.2 /obj/item/clothing/gloves/rig/light name = "gloves" @@ -54,8 +57,11 @@ desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." icon_state = "ninja_rig" armor = list(melee = 50, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 30) + emp_protection = 40 //change this to 30 if too high. slowdown = 0 + chest_type = /obj/item/clothing/suit/space/rig/light/ninja + req_access = list(access_syndicate) initial_modules = list( @@ -75,6 +81,10 @@ ..() +/obj/item/clothing/suit/space/rig/light/ninja + breach_threshold = 28 //comparable to regular hardsuits + resilience = 0.05 + /obj/item/weapon/rig/light/stealth name = "stealth suit control module" suit_type = "stealth" diff --git a/code/modules/clothing/spacesuits/rig/suits/merc.dm b/code/modules/clothing/spacesuits/rig/suits/merc.dm index 22add92014..8e7b70d5f2 100644 --- a/code/modules/clothing/spacesuits/rig/suits/merc.dm +++ b/code/modules/clothing/spacesuits/rig/suits/merc.dm @@ -9,7 +9,6 @@ suit_type = "crimson hardsuit" armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/merc diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 44959068eb..74fd7a16fe 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -7,6 +7,7 @@ slowdown = 3 offline_slowdown = 10 offline_vision_restriction = 2 + emp_protection = -20 allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) @@ -56,7 +57,6 @@ icon_state = "science_rig" armor = list(melee = 15, bullet = 15, laser = 80, energy = 80, bomb = 60, bio = 100, rad = 100) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/ert @@ -79,7 +79,6 @@ icon_state = "medical_rig" armor = list(melee = 30, bullet = 15, laser = 20, energy = 60, bomb = 30, bio = 100, rad = 100) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller ) @@ -100,7 +99,6 @@ icon_state = "hazard_rig" armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/ert diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index b7db5da591..7bf622b539 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -33,7 +33,6 @@ camera = new /obj/machinery/camera(src) camera.replace_networks(camera_networks) - cameranet.removeCamera(camera) camera.c_tag = user.name user << "\blue User scanned as [camera.c_tag]. Camera activated." return 1 diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm index e914ce7c3d..84cbc727de 100644 --- a/code/modules/hydroponics/seed_controller.dm +++ b/code/modules/hydroponics/seed_controller.dm @@ -2,7 +2,7 @@ // Processes vines/spreading plants. #define PLANTS_PER_TICK 500 // Cap on number of plant segments processed. -#define PLANT_TICK_TIME 25 // Number of ticks between the plant processor cycling. +#define PLANT_TICK_TIME 75 // Number of ticks between the plant processor cycling. // Debug for testing seed genes. /client/proc/show_plant_genes() diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index 561210537d..d47a6582a9 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -685,7 +685,7 @@ name = "wheat" seed_name = "wheat" display_name = "wheat stalks" - chems = list("nutriment" = list(1,25)) + chems = list("nutriment" = list(1,25), "flour" = list(1,25)) kitchen_tag = "wheat" /datum/seed/wheat/New() @@ -916,7 +916,7 @@ set_trait(TRAIT_PRODUCTION,5) set_trait(TRAIT_YIELD,3) set_trait(TRAIT_POTENCY,10) - set_trait(TRAIT_PRODUCT_ICON,"treefruit") + set_trait(TRAIT_PRODUCT_ICON,"cherry") set_trait(TRAIT_PRODUCT_COLOUR,"#8C0101") set_trait(TRAIT_PLANT_ICON,"tree2") diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm index 0729b2b343..64ef1b55c6 100644 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -1,9 +1,17 @@ #define NEIGHBOR_REFRESH_TIME 100 +/obj/effect/plant/proc/get_cardinal_neighbors() + var/list/cardinal_neighbors = list() + for(var/check_dir in cardinal) + var/turf/simulated/T = get_step(get_turf(src), check_dir) + if(istype(T)) + cardinal_neighbors |= T + return cardinal_neighbors + /obj/effect/plant/proc/update_neighbors() // Update our list of valid neighboring turfs. neighbors = list() - for(var/turf/simulated/floor/floor in range(1,src)) + for(var/turf/simulated/floor in get_cardinal_neighbors()) if(get_dist(parent, floor) > spread_distance) continue if((locate(/obj/effect/plant) in floor.contents) || (locate(/obj/effect/dead_plant) in floor.contents) ) @@ -80,10 +88,12 @@ // Kill off our plant. if(plant) plant.die() // This turf is clear now, let our buddies know. - var/turf/T = get_turf(src) - for(var/obj/effect/plant/neighbor in range(1,src)) - neighbor.neighbors |= T - plant_controller.add_plant(neighbor) + for(var/turf/simulated/check_turf in get_cardinal_neighbors()) + if(!istype(check_turf)) + continue + for(var/obj/effect/plant/neighbor in check_turf.contents) + neighbor.neighbors |= check_turf + plant_controller.add_plant(neighbor) spawn(1) if(src) del(src) #undef NEIGHBOR_REFRESH_TIME \ No newline at end of file diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm index ccf74e4ef7..1f8a0cc468 100644 --- a/code/modules/hydroponics/spreading/spreading_response.dm +++ b/code/modules/hydroponics/spreading/spreading_response.dm @@ -63,8 +63,8 @@ victim.buckled = src victim.update_canmove() buckled_mob = victim - - if(victim.loc != src.loc) + var/turf/T = get_turf(src) + if(victim.loc != T && T.Enter(victim, get_turf(victim))) src.visible_message("Tendrils lash out from \the [src] and drag \the [victim] in!") victim.loc = src.loc victim << "Tendrils [pick("wind", "tangle", "tighten")] around you!" diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index d915a116c5..19f181d03e 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -592,15 +592,20 @@ if(!environment) //We're in a crate or nullspace, bail out. return - var/area/A = T.loc - var/light_available - if(A) - if(A.lighting_use_dynamic) - light_available = max(0,min(10,T.lighting_lumcount)-5) - else - light_available = 5 + var/light_string + if(closed_system && mechanical) + light_string = "that the internal lights are set to [tray_light] lumens" + else + var/area/A = T.loc + var/light_available + if(A) + if(A.lighting_use_dynamic) + light_available = max(0,min(10,T.lighting_lumcount)-5) + else + light_available = 5 + light_string = "a light level of [light_available] lumens" - usr << "The tray's sensor suite is reporting a light level of [light_available] lumens and a temperature of [environment.temperature]K." + usr << "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K." /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb() set name = "Toggle Tray Lid" diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index cd7d0daf9a..64e0fe4369 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -198,10 +198,10 @@ if(grown_seed.get_trait(TRAIT_TELEPORTING)) dat += "
The fruit is temporal/spatially unstable." - dat += "

\[print report\]" if(dat) - user << browse(dat,"window=plant_analyzer") last_data = dat + dat += "

\[print report\]" + user << browse(dat,"window=plant_analyzer") return diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 8b39a00aa5..e5e91c4bdc 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -199,6 +199,9 @@ /mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted) src << "[part_a][speaker_name][part_b][formatted]
" +/mob/dead/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted) + src << "[part_a][track][part_b][formatted]
" + /mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted) var/time = say_timestamp() src << "[time][part_a][speaker_name][part_b][formatted]" diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 943f90bcca..ea4f9f9d41 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -35,8 +35,8 @@ /datum/unarmed_attack/bite ) var/list/unarmed_attacks = null // For empty hand harm-intent attack - var/brute_mod = null // Physical damage reduction/malus. - var/burn_mod = null // Burn damage reduction/malus. + var/brute_mod = 1 // Physical damage multiplier. + var/burn_mod = 1 // Burn damage multiplier. // Death vars. var/gibber_type = /obj/effect/gibspawner/human diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index d94f705320..f05fdda45f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -120,12 +120,14 @@ var/datum/cameranet/cameranet = new() for(var/y = y1; y <= y2; y += 16) if(chunkGenerated(x, y, T.z)) var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z) - if(choice == 0) - // Remove the camera. - chunk.cameras -= c - else if(choice == 1) - // You can't have the same camera in the list twice. - chunk.cameras |= c + // Only add actual cameras to the list of cameras + if(istype(c, /obj/machinery/camera)) + if(choice == 0) + // Remove the camera. + chunk.cameras -= c + else if(choice == 1) + // You can't have the same camera in the list twice. + chunk.cameras |= c chunk.hasChanged() // Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 33dbfd0966..11c8715979 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -64,7 +64,7 @@ else changed = 1 -// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. +// The actual updating. It gathers the visible turfs from cameras and puts them into the appropriate lists. /datum/camerachunk/proc/update() @@ -76,14 +76,14 @@ var/obj/machinery/camera/c = camera if(!c) - continue + cameras -= c if(!c.can_use()) continue var/turf/point = locate(src.x + 8, src.y + 8, src.z) if(get_dist(point, c) > 24) - continue + cameras -= c for(var/turf/t in c.can_see()) newVisibleTurfs[t] = t @@ -143,14 +143,8 @@ if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16) turfs[t] = t - for(var/camera in cameras) - var/obj/machinery/camera/c = camera - if(!c) - continue - - if(!c.can_use()) - continue - + // At this point we only have functional cameras + for(var/obj/machinery/camera/c in cameras) for(var/turf/t in c.can_see()) visibleTurfs[t] = t diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index e6311e7a00..5bcec964a7 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -84,6 +84,7 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) + invalidateCameraCache() if(src.can_use()) cameranet.addCamera(src) else @@ -98,16 +99,11 @@ cameranet.cameras_unsorted = 1 else dd_insertObjectList(cameranet.cameras, src) - - var/list/open_networks = difflist(network,restricted_camera_networks) //...but if all of camera's networks are restricted, it only works for specific camera consoles. - if(open_networks.len) //If there is at least one open network, chunk is available for AI usage. - cameranet.addCamera(src) + update_coverage(1) /obj/machinery/camera/Del() cameranet.cameras -= src - var/list/open_networks = difflist(network,restricted_camera_networks) - if(open_networks.len) - cameranet.removeCamera(src) + clear_all_networks() ..() -#undef BORG_CAMERA_BUFFER \ No newline at end of file +#undef BORG_CAMERA_BUFFER diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 10b11648d1..68df16d020 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -69,7 +69,7 @@ wrapped = null return - src.loc << "\red You drop \the [wrapped]." + src.loc << "You drop \the [wrapped]." wrapped.loc = get_turf(src) wrapped = null //update_icon() @@ -79,6 +79,9 @@ /obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params) + if(!proximity) + return // This will prevent them using guns at range but adminbuse can add them directly to modules, so eh. + //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z if(!wrapped) for(var/obj/item/thing in src.contents) @@ -123,7 +126,7 @@ wrapped = I return else - user << "\red Your gripper cannot hold \the [target]." + user << "Your gripper cannot hold \the [target]." else if(istype(target,/obj/machinery/power/apc)) var/obj/machinery/power/apc/A = target @@ -140,7 +143,7 @@ A.charging = 0 A.update_icon() - user.visible_message("\red [user] removes the power cell from [A]!", "You remove the power cell.") + user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") //TODO: Matter decompiler. /obj/item/weapon/matter_decompiler @@ -173,7 +176,7 @@ for(var/mob/M in T) if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse)) - src.loc.visible_message("\red [src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","\red It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.") + src.loc.visible_message("[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.") new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) del(M) if(wood) @@ -270,16 +273,16 @@ grabbed_something = 1 if(grabbed_something) - user << "\blue You deploy your decompiler and clear out the contents of \the [T]." + user << "You deploy your decompiler and clear out the contents of \the [T]." else - user << "\red Nothing on \the [T] is useful to you." + user << "Nothing on \the [T] is useful to you." return //PRETTIER TOOL LIST. /mob/living/silicon/robot/drone/installed_modules() if(weapon_lock) - src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]" + src << "Weapon lock active, unable to use modules! Count:[weaponlock_time]" return if(!module) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index d5ff0f1c09..3539e683af 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1143,7 +1143,6 @@ var/list/robot_verbs_default = list( //Disconnect it's camera so it's not so easily tracked. if(src.camera) src.camera.clear_all_networks() - cameranet.removeCamera(src.camera) /mob/living/silicon/robot/proc/ResetSecurityCodes() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 850a4147dd..720abe8e2a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -797,7 +797,7 @@ note dizziness decrements automatically in the mob's Life() proc. stat(null,"Location:\t([x], [y], [z])") stat(null,"CPU:\t[world.cpu]") stat(null,"Instances:\t[world.contents.len]") - if(statpanel("MC") && master_controller) + if(statpanel("Status") && master_controller) stat(null,"MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])") stat(null,"Air-[master_controller.air_cost]\tSun-[master_controller.sun_cost]") stat(null,"Mob-[master_controller.mobs_cost]\t#[mob_list.len]") @@ -1180,7 +1180,9 @@ mob/proc/yank_out_object() usr << "You are now facing [dir2text(facing_dir)]." /mob/proc/set_face_dir(var/newdir) - if(newdir) + if(newdir == facing_dir) + facing_dir = null + else if(newdir) set_dir(newdir) facing_dir = newdir else if(facing_dir) @@ -1200,20 +1202,16 @@ mob/proc/yank_out_object() /mob/verb/northfaceperm() set hidden = 1 - facing_dir = null set_face_dir(NORTH) /mob/verb/southfaceperm() set hidden = 1 - facing_dir = null set_face_dir(SOUTH) /mob/verb/eastfaceperm() set hidden = 1 - facing_dir = null set_face_dir(EAST) /mob/verb/westfaceperm() set hidden = 1 - facing_dir = null set_face_dir(WEST) diff --git a/code/modules/nano/nanointeraction.dm b/code/modules/nano/nanointeraction.dm index 5b0a7ec01a..a9025ea70e 100644 --- a/code/modules/nano/nanointeraction.dm +++ b/code/modules/nano/nanointeraction.dm @@ -28,8 +28,10 @@ return STATUS_CLOSE if(lockcharge || stunned || weakened) return STATUS_DISABLED + if(custom_state.flags & NANO_IGNORE_DISTANCE) + return STATUS_INTERACTIVE // robots can interact with things they can see within their view range - if(!(custom_state.flags & NANO_IGNORE_DISTANCE) && (src_object in view(src))) + if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view) return STATUS_INTERACTIVE // interactive (green visibility) return STATUS_DISABLED // no updates, completely disabled (red visibility) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index eb6e73ec2e..2bc36508d8 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -59,7 +59,7 @@ obj/item/weapon/gun/energy/retro /obj/item/weapon/gun/energy/lasercannon/mounted self_recharge = 1 use_external_power = 1 - recharge_time = 25 + recharge_time = 10 /obj/item/weapon/gun/energy/xray name = "xray laser gun" diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 76bcebac3c..31480de9c8 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -13,9 +13,7 @@ projectile_type = /obj/item/projectile/ion /obj/item/weapon/gun/energy/ionrifle/emp_act(severity) - if(severity > 2) - return //so it doesn't EMP itself, I guess - ..() + ..(max(severity, 2)) //so it doesn't EMP itself, I guess /obj/item/weapon/gun/energy/ionrifle/update_icon() ..() diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index afa8cf6ead..4f08f6f0c3 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -3329,7 +3329,7 @@ datum // make all the beverages work together for(var/datum/reagent/ethanol/A in holder.reagent_list) - if(isnum(A.data)) d += A.data + if(A != src && isnum(A.data)) d += A.data if(alien && alien == IS_SKRELL) //Skrell get very drunk very quickly. d*=5 diff --git a/code/modules/reagents/reagent_containers/food.dm b/code/modules/reagents/reagent_containers/food.dm index 99261d81d9..1b94dfcdae 100644 --- a/code/modules/reagents/reagent_containers/food.dm +++ b/code/modules/reagents/reagent_containers/food.dm @@ -1,3 +1,6 @@ +#define CELLS 4 +#define CELLSIZE (32/CELLS) + //////////////////////////////////////////////////////////////////////////////// /// Food. //////////////////////////////////////////////////////////////////////////////// @@ -6,7 +9,7 @@ volume = 50 //Sets the default container amount for all food items. var/filling_color = "#FFFFFF" //Used by sandwiches. - var/list/center_of_mass = newlist() //Center of mass + var/list/center_of_mass = list() // Used for table placement /obj/item/weapon/reagent_containers/food/New() ..() @@ -18,17 +21,18 @@ if(proximity && params && istype(A, /obj/structure/table) && center_of_mass.len) //Places the item on a grid var/list/mouse_control = params2list(params) - var/cellnumber = 4 var/mouse_x = text2num(mouse_control["icon-x"]) var/mouse_y = text2num(mouse_control["icon-y"]) - var/grid_x = round(mouse_x, 32/cellnumber) - var/grid_y = round(mouse_y, 32/cellnumber) + if(!isnum(mouse_x) || !isnum(mouse_y)) + return - if(mouse_control["icon-x"]) - var/sign = mouse_x - grid_x != 0 ? sign(mouse_x - grid_x) : -1 //positive if rounded down, else negative - pixel_x = grid_x - center_of_mass["x"] + sign*16/cellnumber //center of the cell - if(mouse_control["icon-y"]) - var/sign = mouse_y - grid_y != 0 ? sign(mouse_y - grid_y) : -1 - pixel_y = grid_y - center_of_mass["y"] + sign*16/cellnumber \ No newline at end of file + var/cell_x = max(0, min(CELLS-1, round(mouse_x/CELLSIZE))) + var/cell_y = max(0, min(CELLS-1, round(mouse_y/CELLSIZE))) + + pixel_x = (CELLSIZE * (0.5 + cell_x)) - center_of_mass["x"] + pixel_y = (CELLSIZE * (0.5 + cell_y)) - center_of_mass["y"] + +#undef CELLS +#undef CELLSIZE diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index 1b2e4646d9..58b11a61ac 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -257,7 +257,7 @@ desc = "A metal shaker to mix drinks in." icon_state = "shaker" amount_per_transfer_from_this = 10 - volume = 100 + volume = 120 center_of_mass = list("x"=17, "y"=10) /obj/item/weapon/reagent_containers/food/drinks/flask diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 63a34ec90c..52a4ba12ba 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -6,7 +6,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle amount_per_transfer_from_this = 10 - volume = 100 + volume = 120 item_state = "broken_beer" //Generic held-item sprite until unique ones are made. var/const/duration = 13 //Directly relates to the 'weaken' duration. Lowered by armor (i.e. helmets) var/isGlass = 1 //Whether the 'bottle' is made of glass or not so that milk cartons dont shatter when someone gets hit by it diff --git a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm index bde3854727..0dc3012493 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm @@ -4,8 +4,8 @@ name = "glass" desc = "Your standard drinking glass." icon_state = "glass_empty" - amount_per_transfer_from_this = 10 - volume = 50 + amount_per_transfer_from_this = 5 + volume = 30 center_of_mass = list("x"=16, "y"=10) on_reagent_change() @@ -16,24 +16,24 @@ /*else if(reagents.reagent_list.len == 1) for(var/datum/reagent/R in reagents.reagent_list) switch(R.id)*/ - if (reagents.reagent_list.len > 0) + if (reagents.reagent_list.len > 0) var/datum/reagent/R = reagents.get_master_reagent() - + if(R.glass_icon_state) icon_state = R.glass_icon_state else icon_state = "glass_brown" - + if(R.glass_name) name = R.glass_name else name = "Glass of.. what?" - + if(R.glass_desc) desc = R.glass_desc else desc = "You can't really tell what this is." - + if(R.glass_center_of_mass) center_of_mass = R.glass_center_of_mass else diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index df5a1f0dbf..9ab669b4bb 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -481,14 +481,14 @@ user.drop_from_inventory(src) del(src) -/obj/item/weapon/reagent_containers/food/snacks/throw_impact(atom/hit_atom) +/obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) ..() new/obj/effect/decal/cleanable/egg_smudge(src.loc) src.reagents.reaction(hit_atom, TOUCH) src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.") del(src) -/obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype( W, /obj/item/toy/crayon )) var/obj/item/toy/crayon/C = W var/clr = C.colourName diff --git a/icons/obj/hydroponics_products.dmi b/icons/obj/hydroponics_products.dmi index 4f9911debe..7708c4896a 100644 Binary files a/icons/obj/hydroponics_products.dmi and b/icons/obj/hydroponics_products.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 7ba4d10788..d068054731 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -249,6 +249,23 @@ macro "hotkeymode" name = "SOUTH+REP" command = ".south" is-disabled = false + elem + name = "ALT+WEST" + command = "westfaceperm" + is-disabled = false + is-disabled = false + elem + name = "ALT+NORTH" + command = "northfaceperm" + is-disabled = false + elem + name = "ALT+EAST" + command = "eastfaceperm" + is-disabled = false + elem + name = "ALT+SOUTH" + command = "southfaceperm" + is-disabled = false elem name = "INSERT" command = "a-intent right" @@ -1828,7 +1845,7 @@ window "infowindow" elem "info" type = INFO pos = 0,0 - size = 636x451 + size = 638x477 anchor1 = 0,0 anchor2 = 100,100 font-family = ""