diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index f377efe74f..94df46ac01 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -180,7 +180,8 @@ Class Procs: air_master.mark_zone_update(B) /connection_edge/zone/recheck() - if(!A.air.compare(B.air)) + // Edges with only one side being vacuum need processing no matter how close. + if(!A.air.compare(B.air, vacuum_exception = 1)) air_master.mark_edge_active(src) //Helper proc to get connections for a zone. @@ -235,7 +236,10 @@ Class Procs: air_master.mark_zone_update(A) /connection_edge/unsimulated/recheck() - if(!A.air.compare(air)) + // Edges with only one side being vacuum need processing no matter how close. + // Note: This handles the glaring flaw of a room holding pressure while exposed to space, but + // does not specially handle the less common case of a simulated room exposed to an unsimulated pressurized turf. + if(!A.air.compare(air, vacuum_exception = 1)) air_master.mark_edge_active(src) proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index fd79d83dc5..92dd6f5d51 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -95,14 +95,14 @@ obj/var/phoronproof = 0 return //Burn skin if exposed. - if(vsc.plc.SKIN_BURNS) + if(vsc.plc.SKIN_BURNS && (species.breath_type != "phoron")) if(!pl_head_protected() || !pl_suit_protected()) burn_skin(0.75) if(prob(20)) src << "Your skin burns!" updatehealth() //Burn eyes if exposed. - if(vsc.plc.EYE_BURNS) + if(vsc.plc.EYE_BURNS && (species.breath_type != "phoron")) if(!head) if(!wear_mask) burn_eyes() @@ -118,22 +118,12 @@ obj/var/phoronproof = 0 burn_eyes() //Genetic Corruption - if(vsc.plc.GENETIC_CORRUPTION) + if(vsc.plc.GENETIC_CORRUPTION && (species.breath_type != "phoron")) if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION) randmutb(src) src << "High levels of toxins cause you to spontaneously mutate!" domutcheck(src,null) -/mob/living/carbon/human/vox/pl_effects() - //Handles all the bad things phoron can do to Vox. - - //Contamination - if(vsc.plc.CLOTH_CONTAMINATION) contaminate() - - //Anything else requires them to not be dead. - if(stat >= 2) - return - /mob/living/carbon/human/proc/burn_eyes() var/obj/item/organ/internal/eyes/E = internal_organs_by_name[O_EYES] if(E) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index bcd85b53be..1dc6436355 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -26,11 +26,13 @@ #define BORGXRAY 0x4 #define BORGMATERIAL 8 -#define STANCE_IDLE 1 -#define STANCE_ALERT 2 -#define STANCE_ATTACK 3 -#define STANCE_ATTACKING 4 -#define STANCE_TIRED 5 +#define STANCE_IDLE 1 // Looking for targets if hostile. Does idle wandering. +#define STANCE_ALERT 2 // Bears +#define STANCE_ATTACK 3 // Attempting to get into attack position +#define STANCE_ATTACKING 4 // Doing attacks +#define STANCE_TIRED 5 // Bears +#define STANCE_FOLLOW 6 // Following somone +#define STANCE_BUSY 7 // Do nothing on life ticks (Other code is running) #define LEFT 1 #define RIGHT 2 @@ -139,7 +141,7 @@ #define INCAPACITATION_STUNNED 8 #define INCAPACITATION_FORCELYING 16 //needs a better name - represents being knocked down BUT still conscious. #define INCAPACITATION_KNOCKOUT 32 - +#define INCAPACITATION_NONE 0 #define INCAPACITATION_DEFAULT (INCAPACITATION_RESTRAINED|INCAPACITATION_BUCKLED_FULLY) #define INCAPACITATION_KNOCKDOWN (INCAPACITATION_KNOCKOUT|INCAPACITATION_FORCELYING) diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 6f6f4f9f0a..1531a67d5b 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -43,6 +43,18 @@ if (isarea(A)) return A + +/** Checks if any living humans are in a given area. */ +/proc/area_is_occupied(var/area/myarea) + // Testing suggests looping over human_mob_list is quicker than looping over area contents + for(var/mob/living/carbon/human/H in human_mob_list) + if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it. + continue + var/area/A = get_area(H) + if(A == myarea) //The loc of a turf is the area it is in. + return 1 + return 0 + /proc/in_range(source, user) if(get_dist(source, user) <= 1) return 1 diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index cabf7c04b3..c971b22dac 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -793,6 +793,26 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. return alpha_mask//And now return the mask. +//getFlatIcon but generates an icon that can face ALL four directions. The only four. +/proc/getCompoundIcon(atom/A) + var/icon/north = getFlatIcon(A,defdir=NORTH,always_use_defdir=1) + var/icon/south = getFlatIcon(A,defdir=SOUTH,always_use_defdir=1) + var/icon/east = getFlatIcon(A,defdir=EAST,always_use_defdir=1) + var/icon/west = getFlatIcon(A,defdir=WEST,always_use_defdir=1) + + //Starts with a blank icon because of byond bugs. + var/icon/full = icon('icons/effects/effects.dmi', "icon_state"="nothing") + + full.Insert(north,dir=NORTH) + full.Insert(south,dir=SOUTH) + full.Insert(east,dir=EAST) + full.Insert(west,dir=WEST) + qdel(north) + qdel(south) + qdel(east) + qdel(west) + return full + /mob/proc/AddCamoOverlay(atom/A)//A is the atom which we are using as the overlay. var/icon/opacity_icon = new(A.icon, A.icon_state)//Don't really care for overlays/underlays. //Now we need to culculate overlays+underlays and add them together to form an image for a mask. diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 709117de8c..57e1e4bb6a 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -158,7 +158,8 @@ using.alpha = ui_alpha src.adding += using - inv_box = new /obj/screen/inventory() + inv_box = new /obj/screen/inventory/hand() + inv_box.hud = src inv_box.name = "r_hand" inv_box.icon = ui_style inv_box.icon_state = "r_hand_inactive" @@ -173,7 +174,8 @@ src.r_hand_hud_object = inv_box src.adding += inv_box - inv_box = new /obj/screen/inventory() + inv_box = new /obj/screen/inventory/hand() + inv_box.hud = src inv_box.name = "l_hand" inv_box.icon = ui_style inv_box.icon_state = "l_hand_inactive" diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index d899f62049..3f6758c6ad 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -12,6 +12,7 @@ layer = 20.0 unacidable = 1 var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. + var/datum/hud/hud = null // A reference to the owner HUD, if any. /obj/screen/Destroy() master = null @@ -507,3 +508,20 @@ usr.update_inv_l_hand(0) usr.update_inv_r_hand(0) return 1 + +// Hand slots are special to handle the handcuffs overlay +/obj/screen/inventory/hand + var/image/handcuff_overlay + +/obj/screen/inventory/hand/update_icon() + ..() + if(!hud) + return + if(!handcuff_overlay) + var/state = (hud.l_hand_hud_object == src) ? "l_hand_hud_handcuffs" : "r_hand_hud_handcuffs" + handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"=state) + overlays.Cut() + if(hud.mymob && iscarbon(hud.mymob)) + var/mob/living/carbon/C = hud.mymob + if(C.handcuffed) + overlays |= handcuff_overlay diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm index b44842036d..8681803ac4 100644 --- a/code/controllers/Processes/mob.dm +++ b/code/controllers/Processes/mob.dm @@ -14,7 +14,7 @@ /datum/controller/process/mob/doWork() for(last_object in mob_list) var/mob/M = last_object - if(isnull(M.gcDestroyed)) + if(M && isnull(M.gcDestroyed)) try M.Life() catch(var/exception/e) diff --git a/code/controllers/Processes/obj.dm b/code/controllers/Processes/obj.dm index bd50edd111..1010c8cc97 100644 --- a/code/controllers/Processes/obj.dm +++ b/code/controllers/Processes/obj.dm @@ -11,7 +11,7 @@ /datum/controller/process/obj/doWork() for(last_object in processing_objects) var/datum/O = last_object - if(isnull(O.gcDestroyed)) + if(O && isnull(O.gcDestroyed)) try O:process() catch(var/exception/e) diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index bac3afb301..5b1b6a60d1 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -84,6 +84,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle if(istype(A, /area/hallway)) A.readyalert() + atc.reroute_traffic(yes = 1) + //calls the shuttle for a routine crew transfer /datum/emergency_shuttle_controller/proc/call_transfer() if(!can_call()) return @@ -98,6 +100,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle shuttle.move_time = SHUTTLE_TRANSIT_DURATION priority_announcement.Announce(replacetext(replacetext(using_map.shuttle_called_message, "%dock_name%", "[using_map.dock_name]"), "%ETA%", "[estimated_time] minute\s")) + atc.shift_ending() //recalls the shuttle /datum/emergency_shuttle_controller/proc/recall() diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm index 4d097c4370..ee53af377c 100644 --- a/code/datums/supplypacks/atmospherics.dm +++ b/code/datums/supplypacks/atmospherics.dm @@ -11,7 +11,7 @@ name = "Inflatable barriers" contains = list(/obj/item/weapon/storage/briefcase/inflatable = 3) cost = 20 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/engineering containername = "Inflatable Barrier Crate" /datum/supply_packs/atmos/canister_empty diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index e42b1d1794..3ab678e175 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -18,7 +18,7 @@ name = "Superconducting Magnetic Coil" contains = list(/obj/item/weapon/smes_coil) cost = 75 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/engineering containername = "Superconducting Magnetic Coil crate" /datum/supply_packs/eng/electrical @@ -30,7 +30,7 @@ /obj/item/weapon/cell/high = 2 ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/engineering/electrical containername = "Electrical maintenance crate" /datum/supply_packs/eng/mechanical @@ -42,7 +42,7 @@ /obj/item/clothing/head/hardhat ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/engineering containername = "Mechanical maintenance crate" /datum/supply_packs/eng/fueltank @@ -61,34 +61,35 @@ /obj/item/weapon/paper/solar ) cost = 20 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/engineering containername = "Solar pack crate" /datum/supply_packs/eng/engine name = "Emitter crate" contains = list(/obj/machinery/power/emitter = 2) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "Emitter crate" access = access_ce /datum/supply_packs/eng/engine/field_gen name = "Field Generator crate" contains = list(/obj/machinery/field_generator = 2) - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "Field Generator crate" access = access_ce /datum/supply_packs/eng/engine/sing_gen name = "Singularity Generator crate" contains = list(/obj/machinery/the_singularitygen) - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "Singularity Generator crate" access = access_ce /datum/supply_packs/eng/engine/collector name = "Collector crate" contains = list(/obj/machinery/power/rad_collector = 3) + containertype = /obj/structure/closet/crate/secure/engineering containername = "Collector crate" /datum/supply_packs/eng/engine/PA @@ -103,7 +104,7 @@ /obj/structure/particle_accelerator/power_box, /obj/structure/particle_accelerator/end_cap ) - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "Particle Accelerator crate" access = access_ce @@ -111,7 +112,7 @@ contains = list(/obj/item/weapon/circuitboard/shield_gen) name = "Bubble shield generator circuitry" cost = 30 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "bubble shield generator circuitry crate" access = access_ce @@ -119,7 +120,7 @@ contains = list(/obj/item/weapon/circuitboard/shield_gen_ex) name = "Hull shield generator circuitry" cost = 30 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "hull shield generator circuitry crate" access = access_ce @@ -127,7 +128,7 @@ contains = list(/obj/item/weapon/circuitboard/shield_cap) name = "Bubble shield capacitor circuitry" cost = 30 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering containername = "shield capacitor circuitry crate" access = access_ce @@ -169,7 +170,7 @@ name = "P.A.C.M.A.N. portable generator parts" cost = 25 containername = "P.A.C.M.A.N. Portable Generator Construction Kit" - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering access = access_tech_storage contains = list( /obj/item/weapon/stock_parts/micro_laser, @@ -182,7 +183,7 @@ name = "Super P.A.C.M.A.N. portable generator parts" cost = 35 containername = "Super P.A.C.M.A.N. portable generator construction kit" - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/engineering access = access_tech_storage contains = list( /obj/item/weapon/stock_parts/micro_laser, diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm index 11dc34c404..c6c07b2d5d 100644 --- a/code/datums/supplypacks/robotics.dm +++ b/code/datums/supplypacks/robotics.dm @@ -20,7 +20,7 @@ /obj/item/weapon/cell/high = 2 ) cost = 10 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robotics assembly" access = access_robotics @@ -39,7 +39,7 @@ name = "All robolimb blueprints" contains = list( /obj/item/weapon/disk/limb/bishop, - /obj/item/weapon/disk/limb/hesphiastos, + /obj/item/weapon/disk/limb/hephaestus, /obj/item/weapon/disk/limb/morpheus, /obj/item/weapon/disk/limb/veymed, /obj/item/weapon/disk/limb/wardtakahashi, @@ -56,7 +56,7 @@ name = "Morpheus robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/morpheus) cost = 20 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robolimb blueprints (Morpheus)" access = access_robotics @@ -64,15 +64,22 @@ name = "Xion robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/xion) cost = 20 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robolimb blueprints (Xion)" access = access_robotics +/datum/supply_packs/robotics/robolimbs/hephaestus + name = "Hephaistos robolimb blueprints" + contains = list(/obj/item/weapon/disk/limb/hephaestus) + containertype = /obj/structure/closet/crate/secure/gear + containername = "Robolimb blueprints (Hephaestus)" + access = access_robotics + /datum/supply_packs/robotics/robolimbs/wardtakahashi name = "Ward-Takahashi robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/wardtakahashi) cost = 35 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robolimb blueprints (Ward-Takahashi)" access = access_robotics @@ -80,7 +87,7 @@ name = "Zeng Hu robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/zenghu) cost = 35 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robolimb blueprints (Zeng Hu)" access = access_robotics @@ -88,7 +95,7 @@ name = "Bishop robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/bishop) cost = 70 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robolimb blueprints (Bishop)" access = access_robotics @@ -96,7 +103,7 @@ name = "Vey-Med robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/veymed) cost = 70 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/science containername = "Robolimb blueprints (Vey-Med)" access = access_robotics @@ -108,7 +115,7 @@ /obj/item/weapon/circuitboard/mecha/ripley/peripherals ) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/science containername = "APLU \"Ripley\" Circuit Crate" access = access_robotics @@ -119,7 +126,7 @@ /obj/item/weapon/circuitboard/mecha/odysseus/main ) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/science containername = "\"Odysseus\" Circuit Crate" access = access_robotics @@ -133,7 +140,7 @@ ) name = "Random APLU modkit" cost = 200 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/science containername = "heavy crate" /datum/supply_packs/randomised/robotics/exosuit_mod/durand diff --git a/code/datums/wires/jukebox.dm b/code/datums/wires/jukebox.dm index f482133e62..900c778189 100644 --- a/code/datums/wires/jukebox.dm +++ b/code/datums/wires/jukebox.dm @@ -1,7 +1,7 @@ /datum/wires/jukebox random = 1 holder_type = /obj/machinery/media/jukebox - wire_count = 7 + wire_count = 11 var/const/WIRE_POWER = 1 var/const/WIRE_HACK = 2 @@ -10,6 +10,10 @@ var/const/WIRE_SPEEDDOWN = 8 var/const/WIRE_REVERSE = 16 var/const/WIRE_NOTHING1 = 32 var/const/WIRE_NOTHING2 = 64 +var/const/WIRE_START = 128 +var/const/WIRE_STOP = 256 +var/const/WIRE_PREV = 512 +var/const/WIRE_NEXT = 1024 /datum/wires/jukebox/CanUse(var/mob/living/L) var/obj/machinery/media/jukebox/A = holder @@ -40,6 +44,14 @@ var/const/WIRE_NOTHING2 = 64 holder.visible_message("\icon[holder] The speakers squeaks.") if(WIRE_SPEEDDOWN) holder.visible_message("\icon[holder] The speakers rumble.") + if(WIRE_START) + A.StartPlaying() + if(WIRE_STOP) + A.StopPlaying() + if(WIRE_PREV) + A.PrevTrack() + if(WIRE_NEXT) + A.NextTrack() else A.shock(usr, 10) // The nothing wires give a chance to shock just for fun diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4c48b84532..b76620fa95 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -125,8 +125,17 @@ if(A:lying) continue src.throw_impact(A,speed) if(isobj(A)) - if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement - src.throw_impact(A,speed) + if(!A.density || A.throwpass) + continue + // Special handling of windows, which are dense but block only from some directions + if(istype(A, /obj/structure/window)) + var/obj/structure/window/W = A + if (!W.is_full_window() && !(turn(src.last_move, 180) & A.dir)) + continue + // Same thing for (closed) windoors, which have the same problem + else if(istype(A, /obj/machinery/door/window) && !(turn(src.last_move, 180) & A.dir)) + continue + src.throw_impact(A,speed) /atom/movable/proc/throw_at(atom/target, range, speed, thrower) if(!target || !src) return 0 diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm index 2bfd0bf7d6..53861563fd 100644 --- a/code/game/gamemodes/changeling/powers/shriek.dm +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -95,11 +95,15 @@ changeling.chem_charges -= 20 - var/range_heavy = 2 - var/range_light = 5 + var/range_heavy = 1 + var/range_med = 2 + var/range_light = 4 + var/range_long = 6 if(src.mind.changeling.recursive_enhancement) range_heavy = range_heavy * 2 + range_med = range_med * 2 range_light = range_light * 2 + range_long = range_long * 2 src << "We are extra loud." src.mind.changeling.recursive_enhancement = 0 diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index ccf449a4dc..61f177eae5 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -231,7 +231,7 @@ var/list/sacrificed = list() if(T) T.hotspot_expose(700,125) var/rune = src // detaching the proc - in theory - empulse(U, (range_red - 2), range_red) + empulse(U, (range_red - 3), (range_red - 2), (range_red - 1), range_red) qdel(rune) return diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 397651dce7..0169cd3f00 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -350,6 +350,11 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is M << "
" M.add_ion_law("THE STATION IS [who2pref] [who2]") + if(botEmagChance) + for(var/mob/living/bot/bot in machines) + if(prob(botEmagChance)) + bot.emag_act(1) + /* var/apcnum = 0 diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 0bed5bcf42..bd056f7c69 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -254,7 +254,7 @@ ..() // Best case scenario: Comparable to a low-yield EMP grenade. // Worst case scenario: Comparable to a standard yield EMP grenade. - empulse(src, rand(2, 4), rand(4, 10)) + empulse(src, rand(1, 3), rand(2, 4), rand(3, 7), rand(5, 10)) //Station buster Tunguska /obj/effect/meteor/tunguska diff --git a/code/game/gamemodes/technomancer/instability.dm b/code/game/gamemodes/technomancer/instability.dm index 4b04330b5b..fa9985b1b6 100644 --- a/code/game/gamemodes/technomancer/instability.dm +++ b/code/game/gamemodes/technomancer/instability.dm @@ -126,7 +126,7 @@ safe_blink(src, range = 6) src << "You're teleported against your will!" if(4) - emp_act(2) + emp_act(3) if(51 to 100) //Severe rng = rand(0,3) diff --git a/code/game/gamemodes/technomancer/spells/control.dm b/code/game/gamemodes/technomancer/spells/control.dm index 8b30eb0f14..90b134b38f 100644 --- a/code/game/gamemodes/technomancer/spells/control.dm +++ b/code/game/gamemodes/technomancer/spells/control.dm @@ -39,7 +39,7 @@ /mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/scarybat, /mob/living/simple_animal/hostile/viscerator, - /mob/living/simple_animal/hostile/retaliate/malf_drone, + /mob/living/simple_animal/hostile/malf_drone, /mob/living/simple_animal/hostile/giant_spider, /mob/living/simple_animal/hostile/hivebot, /mob/living/simple_animal/hostile/diyaab, //Doubt these will get used but might as well, diff --git a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm index 7c11bc000a..259aca4b57 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm @@ -23,7 +23,7 @@ ..() /obj/item/weapon/spell/spawner/pulsar/on_throw_cast(atom/hit_atom, mob/user) - empulse(hit_atom, 1, 1, log=1) + empulse(hit_atom, 1, 1, 1, 1, log=1) /obj/effect/temporary_effect/pulsar name = "pulsar" @@ -44,7 +44,7 @@ /obj/effect/temporary_effect/pulsar/proc/pulse_loop() while(pulses_remaining) sleep(2 SECONDS) - empulse(src, heavy_range = 1, light_range = 2, log = 1) + empulse(src, 1, 1, 2, 2, log = 1) pulses_remaining-- qdel(src) diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm index e60d8e8d3a..7cf36ebabf 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm @@ -22,7 +22,7 @@ "Chick" = /mob/living/simple_animal/chick, "Crab" = /mob/living/simple_animal/crab, "Parrot" = /mob/living/simple_animal/parrot, - "Goat" = /mob/living/simple_animal/hostile/retaliate/goat, + "Goat" = /mob/living/simple_animal/retaliate/goat, "Cat" = /mob/living/simple_animal/cat, "Kitten" = /mob/living/simple_animal/cat/kitten, "Corgi" = /mob/living/simple_animal/corgi, diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 301cbe9e37..bba12887a9 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -335,17 +335,16 @@ organStatus["bleeding"] = 1 if(E.status & ORGAN_DEAD) organStatus["dead"] = 1 + for(var/datum/wound/W in E.wounds) + if(W.internal) + organStatus["internalBleeding"] = 1 + break organData["status"] = organStatus if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured()) organData["lungRuptured"] = 1 - for(var/datum/wound/W in E.wounds) - if(W.internal) - organData["internalBleeding"] = 1 - break - extOrganData.Add(list(organData)) occupantData["extOrgan"] = extOrganData diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 5cf1c188d8..dcce5fb938 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -348,7 +348,7 @@ update_flag "\[N2O\]" = "redws", \ "\[N2\]" = "red", \ "\[O2\]" = "blue", \ - "\[Phoron\]" = "purple", \ + "\[Phoron\]" = "orangeps", \ "\[CO2\]" = "black", \ "\[Air\]" = "grey", \ "\[CAUTION\]" = "yellow", \ diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 0a568b4ade..408e3184d4 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -66,7 +66,11 @@ if(1) num_of_prizes = rand(1,4) if(2) + num_of_prizes = rand(1,3) + if(3) num_of_prizes = rand(0,2) + if(4) + num_of_prizes = rand(0,1) for(num_of_prizes; num_of_prizes > 0; num_of_prizes--) empprize = pickweight(prizes) new empprize(src.loc) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 439e9f4508..a738ea66c1 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -35,10 +35,12 @@ var/stat_msg1 var/stat_msg2 + var/datum/lore/atc_controller/ATC var/datum/announcement/priority/crew_announcement = new /obj/machinery/computer/communications/New() ..() + ATC = atc crew_announcement.newscast = 1 /obj/machinery/computer/communications/process() @@ -130,6 +132,8 @@ if("messagelist") src.currmsg = 0 src.state = STATE_MESSAGELIST + if("toggleatc") + src.ATC.squelched = !src.ATC.squelched if("viewmessage") src.state = STATE_VIEWMESSAGE if (!src.currmsg) @@ -311,6 +315,7 @@ else dat += "
\[ Log In \]" dat += "
\[ Message List \]" + dat += "
\[ [ATC.squelched ? "Enable" : "Disable"] ATC Relay \]" if(STATE_CALLSHUTTLE) dat += "Are you sure you want to call the shuttle? \[ OK | Cancel \]" if(STATE_CANCELSHUTTLE) @@ -374,6 +379,7 @@ dat += "
\[ Call Emergency Shuttle \]" dat += "
\[ Message List \]" dat += "
\[ Set Status Display \]" + dat += "
\[ [ATC.squelched ? "Enable" : "Disable"] ATC Relay \]" if(STATE_CALLSHUTTLE) dat += "Are you sure you want to call the shuttle? \[ OK | Cancel \]" if(STATE_MESSAGELIST) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index eabab210c4..97dd9f5fe0 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -37,7 +37,16 @@ /obj/machinery/door/airlock/attack_generic(var/mob/user, var/damage) if(stat & (BROKEN|NOPOWER)) if(damage >= 10) - if(src.density) + if(src.locked || src.welded) + visible_message("\The [user] begins breaking into \the [src] internals!") + if(do_after(user,10 SECONDS,src)) + src.locked = 0 + src.welded = 0 + update_icon() + open(1) + if(prob(25)) + src.shock(user, 100) + else if(src.density) visible_message("\The [user] forces \the [src] open!") open(1) else @@ -329,6 +338,18 @@ secured_wires = 1 assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity +/obj/machinery/door/airlock/voidcraft + name = "voidcraft hatch" + desc = "It's an extra resilient airlock intended for spacefaring vessels." + icon = 'icons/obj/doors/shuttledoors.dmi' + explosion_resistance = 20 + assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft + +// Airlock opens from top-bottom instead of left-right. +/obj/machinery/door/airlock/voidcraft/vertical + icon = 'icons/obj/doors/shuttledoors_vertical.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical + /* About the new airlock wires panel: * An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires. diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 71482abb33..4eb0e7d408 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -269,4 +269,24 @@ datum/track/New(var/title_name, var/audio) playing = 1 update_use_power(2) - update_icon() \ No newline at end of file + update_icon() + +// Advance to the next track - Don't start playing it unless we were already playing +/obj/machinery/media/jukebox/proc/NextTrack() + if(!tracks.len) return + var/curTrackIndex = max(1, tracks.Find(current_track)) + var/newTrackIndex = (curTrackIndex % tracks.len) + 1 // Loop back around if past end + current_track = tracks[newTrackIndex] + if(playing) + StartPlaying() + updateDialog() + +// Advance to the next track - Don't start playing it unless we were already playing +/obj/machinery/media/jukebox/proc/PrevTrack() + if(!tracks.len) return + var/curTrackIndex = max(1, tracks.Find(current_track)) + var/newTrackIndex = curTrackIndex == 1 ? tracks.len : curTrackIndex - 1 + current_track = tracks[newTrackIndex] + if(playing) + StartPlaying() + updateDialog() diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index fe5cac9c44..8700caf785 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -1,52 +1,45 @@ // Navigation beacon for AI robots // Functions as a transponder: looks for incoming signal matching -var/global/list/navbeacons // no I don't like putting this in, but it will do for now +var/global/list/navbeacons = list() // no I don't like putting this in, but it will do for now /obj/machinery/navbeacon icon = 'icons/obj/objects.dmi' icon_state = "navbeacon0-f" name = "navigation beacon" - desc = "A radio beacon used for bot navigation." + desc = "A beacon used for bot navigation." level = 1 // underfloor layer = 2.5 anchored = 1 var/open = 0 // true if cover is open var/locked = 1 // true if controls are locked - var/freq = 1445 // radio frequency + var/freq = null // DEPRECATED we don't use radios anymore! var/location = "" // location response text - var/list/codes // assoc. list of transponder codes - var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value" + var/codes_txt // DEPRECATED codes as set on map: "tag1;tag2" or "tag1=value;tag2=value" + var/list/codes = list() // assoc. list of transponder codes req_access = list(access_engine) /obj/machinery/navbeacon/New() ..() - - set_codes() + set_codes_from_txt(codes_txt) + if(freq) + warning("[src] at [x],[y],[z] has deprecated var freq=[freq]. Replace it with proper type.") var/turf/T = loc hide(!T.is_plating()) - - // add beacon to MULE bot beacon list - if(freq == 1400) - if(!navbeacons) - navbeacons = new() - navbeacons += src - - - spawn(5) // must wait for map loading to finish - if(radio_controller) - radio_controller.add_object(src, freq, RADIO_NAVBEACONS) + navbeacons += src // set the transponder codes assoc list from codes_txt -/obj/machinery/navbeacon/proc/set_codes() +// DEPRECATED - This is kept only for compatibilty with old map files! Do not use this! +// Instead, you should replace the map instance with one of the appropriate navbeacon subtypes. +// See the bottom of this file for a list of subtypes, make your own examples if your map needs more +/obj/machinery/navbeacon/proc/set_codes_from_txt() if(!codes_txt) return + warning("[src] at [x],[y],[z] in [get_area(src)] is using the deprecated 'codes_txt' mapping method. Replace it with proper type.") - codes = new() - + codes = list() var/list/entries = splittext(codes_txt, ";") // entries are separated by semicolons - for(var/e in entries) var/index = findtext(e, "=") // format is "key=value" if(index) @@ -56,6 +49,8 @@ var/global/list/navbeacons // no I don't like putting this in, but it will do else codes[e] = "1" +/obj/machinery/navbeacon/hides_under_flooring() + return 1 // called when turf state changes // hide the object if turf is intact @@ -73,38 +68,6 @@ var/global/list/navbeacons // no I don't like putting this in, but it will do else icon_state = "[state]" - -// look for a signal of the form "findbeacon=X" -// where X is any -// or the location -// or one of the set transponder keys -// if found, return a signal -/obj/machinery/navbeacon/receive_signal(datum/signal/signal) - - var/request = signal.data["findbeacon"] - if(request && ((request in codes) || request == "any" || request == location)) - spawn(1) - post_signal() - -// return a signal giving location and transponder codes - -/obj/machinery/navbeacon/proc/post_signal() - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - - if(!frequency) return - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 - signal.data["beacon"] = location - - for(var/key in codes) - signal.data[key] = codes[key] - - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - - /obj/machinery/navbeacon/attackby(var/obj/item/I, var/mob/user) var/turf/T = loc if(!T.is_plating()) @@ -117,7 +80,7 @@ var/global/list/navbeacons // no I don't like putting this in, but it will do updateicon() - else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda)) + else if(I.GetID()) if(open) if(allowed(user)) locked = !locked @@ -153,8 +116,7 @@ var/global/list/navbeacons // no I don't like putting this in, but it will do if(locked && !ai) t = {"Navigation Beacon

-(swipe card to unlock controls)
-Frequency: [format_frequency(freq)]

+(swipe card to unlock controls)

Location: [location ? location : "(none)"]
Transponder Codes: