diff --git a/code/__DEFINES/_flags/obj_flags.dm b/code/__DEFINES/_flags/obj_flags.dm index 724dc24fdd..e48146a1d0 100644 --- a/code/__DEFINES/_flags/obj_flags.dm +++ b/code/__DEFINES/_flags/obj_flags.dm @@ -18,8 +18,8 @@ /// Integrity defines for clothing (not flags but close enough) #define CLOTHING_PRISTINE 0 // We have no damage on the clothing -#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart and can be equipped -#define CLOTHING_SHREDDED 2 // The clothing is useless and cannot be equipped unless repaired first +#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart +#define CLOTHING_SHREDDED 2 // The clothing is near useless and has their sensors broken // If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 51d1b618fc..e56ab8dd24 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -173,8 +173,18 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) #define BROKEN_SENSORS -1 #define NO_SENSORS 0 -#define HAS_SENSORS 1 -#define LOCKED_SENSORS 2 +#define DAMAGED_SENSORS_LIVING 1 +#define DAMAGED_SENSORS_VITALS 2 +#define HAS_SENSORS 3 + +//suit sensor flags: sensor_flag defines +#define SENSOR_RANDOM (1<<0) +#define SENSOR_LOCKED (1<<1) + +//suit sensor integrity percentage threshold defines +#define SENSOR_INTEGRITY_COORDS 0.2 +#define SENSOR_INTEGRITY_VITALS 0.6 +#define SENSOR_INTEGRITY_BINARY 1 //Wet floor type flags. Stronger ones should be higher in number. #define TURF_DRY (0) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index e7ed5e9fda..a6496622ff 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -52,7 +52,7 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "diamond" desc = "Highly pressurized carbon" color = list(48/255, 272/255, 301/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) - strength_modifier = 1.1 + strength_modifier = 1.2 alpha = 132 categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/diamond diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 00ba621550..47343ea58f 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -3,7 +3,7 @@ icon_state = "0" state = 0 -/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params) +/obj/structure/frame/computer/attackby(obj/item/P, mob/living/user, params) add_fingerprint(user) switch(state) if(0) @@ -11,7 +11,7 @@ to_chat(user, "You start wrenching the frame into place...") if(P.use_tool(src, user, 20, volume=50)) to_chat(user, "You wrench the frame into place.") - setAnchored(TRUE) + set_anchored(TRUE) state = 1 return if(P.tool_behaviour == TOOL_WELDER) @@ -19,7 +19,7 @@ return to_chat(user, "You start deconstructing the frame...") - if(P.use_tool(src, user, 20, volume=50) && state == 0) + if(P.use_tool(src, user, 20, volume=50)) to_chat(user, "You deconstruct the frame.") var/obj/item/stack/sheet/metal/M = new (drop_location(), 5) M.add_fingerprint(user) @@ -28,15 +28,15 @@ if(1) if(P.tool_behaviour == TOOL_WRENCH) to_chat(user, "You start to unfasten the frame...") - if(P.use_tool(src, user, 20, volume=50) && state == 1) + if(P.use_tool(src, user, 20, volume=50)) to_chat(user, "You unfasten the frame.") - setAnchored(FALSE) + set_anchored(FALSE) state = 0 return if(istype(P, /obj/item/circuitboard/computer) && !circuit) if(!user.transferItemToLoc(P, src)) return - playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) to_chat(user, "You place [P] inside the frame.") icon_state = "1" circuit = P @@ -71,8 +71,10 @@ if(istype(P, /obj/item/stack/cable_coil)) if(!P.tool_start_check(user, amount=5)) return + if(state != 2) + return to_chat(user, "You start adding cables to the frame...") - if(P.use_tool(src, user, 20, 5, 50, CALLBACK(src, .proc/check_state, 2))) + if(P.use_tool(src, user, 20, volume=50, amount=5)) to_chat(user, "You add cables to the frame.") state = 3 icon_state = "3" @@ -90,9 +92,11 @@ if(istype(P, /obj/item/stack/sheet/glass)) if(!P.tool_start_check(user, amount=2)) return - playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + if(state != 3) + return + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) to_chat(user, "You start to put in the glass panel...") - if(P.use_tool(src, user, 20, 2, 0, CALLBACK(src, .proc/check_state, 3))) + if(P.use_tool(src, user, 20, amount=2)) to_chat(user, "You put in the glass panel.") state = 4 src.icon_state = "4" @@ -109,14 +113,51 @@ if(P.tool_behaviour == TOOL_SCREWDRIVER) P.play_tool_sound(src) to_chat(user, "You connect the monitor.") - var/obj/B = new circuit.build_path (loc, circuit) - B.setDir(dir) - transfer_fingerprints_to(B) + + var/obj/machinery/new_machine = new circuit.build_path(loc) + new_machine.setDir(dir) + transfer_fingerprints_to(new_machine) + + if(istype(new_machine, /obj/machinery/computer)) + var/obj/machinery/computer/new_computer = new_machine + + // Machines will init with a set of default components. + // Triggering handle_atom_del will make the machine realise it has lost a component_parts and then deconstruct. + // Move to nullspace so we don't trigger handle_atom_del, then qdel. + // Finally, replace new machine's parts with this frame's parts. + if(new_computer.circuit) + // Move to nullspace and delete. + new_computer.circuit.moveToNullspace() + QDEL_NULL(new_computer.circuit) + for(var/old_part in new_computer.component_parts) + var/atom/movable/movable_part = old_part + // Move to nullspace and delete. + movable_part.moveToNullspace() + qdel(movable_part) + + // Set anchor state and move the frame's parts over to the new machine. + // Then refresh parts and call on_construction(). + new_computer.set_anchored(anchored) + new_computer.component_parts = list() + + circuit.forceMove(new_computer) + new_computer.component_parts += circuit + new_computer.circuit = circuit + + for(var/new_part in src) + var/atom/movable/movable_part = new_part + movable_part.forceMove(new_computer) + new_computer.component_parts += movable_part + + new_computer.RefreshParts() + new_computer.on_construction() + qdel(src) return if(user.a_intent == INTENT_HARM) return ..() + /obj/structure/frame/computer/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(state == 4) @@ -127,13 +168,12 @@ ..() /obj/structure/frame/computer/AltClick(mob/user) - . = ..() - if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + ..() + if(!user.canUseTopic(src, BE_CLOSE, TRUE, FALSE)) return if(anchored) to_chat(usr, "You must unwrench [src] before rotating it!") - return TRUE + return setDir(turn(dir, -90)) - return TRUE diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index bdf7a80c96..c2855b4a46 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -208,6 +208,8 @@ new_machine.component_parts = list() circuit.forceMove(new_machine) + // TODO: make sleepers not shit out parts PROPERLY THIS TIME. + new_machine.circuit.moveToNullspace() new_machine.component_parts += circuit new_machine.circuit = circuit diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 65570f18ac..b2bd394a53 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -117,8 +117,8 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("diamond brick", /obj/item/ingot/diamond, 6, time = 100), \ - )) + new/datum/stack_recipe("diamond ingot", /obj/item/ingot/diamond, 6, time = 100), \ + )) /obj/item/stack/sheet/mineral/diamond/get_main_recipes() . = ..() diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm index 68451012f6..2fdf1baf04 100644 --- a/code/modules/antagonists/changeling/powers/strained_muscles.dm +++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm @@ -4,7 +4,7 @@ /obj/effect/proc_holder/changeling/strained_muscles name = "Strained Muscles" desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster." - helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Cannot be used in lesser form." + helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Our chemical generation is drastically slowed while this is active. Cannot be used in lesser form." dna_cost = 1 req_human = 1 var/stacks = 0 //Increments every 5 seconds; damage increases over time @@ -14,12 +14,15 @@ action_background_icon_state = "bg_ling" /obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) active = !active if(active) to_chat(user, "Our muscles tense and strengthen.") + changeling.chem_recharge_slowdown += 0.8 // stacking this with other abilities will cause you to actively lose chemicals else user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) to_chat(user, "Our muscles relax.") + changeling.chem_recharge_slowdown -= 0.8 if(stacks >= 10) to_chat(user, "We collapse in exhaustion.") user.DefaultCombatKnockdown(60) @@ -30,6 +33,7 @@ return TRUE /obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) while(active) user.add_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) if(user.stat != CONSCIOUS || user.staminaloss >= 90) @@ -37,6 +41,7 @@ to_chat(user, "Our muscles relax without the energy to strengthen them.") user.DefaultCombatKnockdown(40) user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) + changeling.chem_recharge_slowdown -= 0.8 break stacks++ diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm index 2bb3934ac7..f53186d96e 100644 --- a/code/modules/cargo/packs/service.dm +++ b/code/modules/cargo/packs/service.dm @@ -171,7 +171,7 @@ /datum/supply_pack/service/replacementdb name = "Replacement Defensive Bar Shotgun" - desc = "Someone stole the Bartender's twin-barreled possession? Give them another one at a significant markup. Comes with one unused double-barrel shotgun, shells not included. Requires bartender access to open." + desc = "Someone stole the Bartender's twin-barreled possession? Give them another one at a significant markup. Comes with one unused double-barrel shotgun, additional shells not included. Requires bartender access to open." cost = 2200 access = ACCESS_BAR contraband = TRUE diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index df05eee638..6e570e595a 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -277,7 +277,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/under/chameleon) item_state = "bl_suit" desc = "It's a plain jumpsuit. It has a small dial on the wrist." sensor_mode = SENSOR_OFF //Hey who's this guy on the Syndicate Shuttle?? - random_sensor = FALSE + sensor_flags = NONE resistance_flags = NONE can_adjust = FALSE armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 018c3d9a3f..416c6309d4 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -233,7 +233,7 @@ /obj/item/clothing/examine(mob/user) . = ..() if(damaged_clothes == CLOTHING_SHREDDED) - . += "It is completely shredded and requires mending before it can be worn again!" + . += "It is completely shredded and requires mending!" return for(var/zone in damage_by_parts) var/pct_damage_part = damage_by_parts[zone] / limb_integrity * 100 @@ -437,12 +437,10 @@ BLIND // can't see anything damaged_clothes = CLOTHING_SHREDDED body_parts_covered = NONE name = "shredded [initial(name)]" - slot_flags = NONE - update_clothes_damaged_state() + update_clothes_damaged_state(CLOTHING_SHREDDED) if(ismob(loc)) var/mob/M = loc - M.visible_message("[M]'s [src.name] falls off, completely shredded!", "Your [src.name] falls off, completely shredded!", vision_distance = COMBAT_MESSAGE_RANGE) - M.dropItemToGround(src) + M.visible_message("[M]'s [src.name] is completely shredded!", "Your [src.name] is completely shredded!", vision_distance = COMBAT_MESSAGE_RANGE) else ..() diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 3207a5842f..a26d8fe791 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -7,11 +7,14 @@ slot_flags = ITEM_SLOT_ICLOTHING armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK - limb_integrity = 30 + limb_integrity = 120 var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women var/has_sensor = HAS_SENSORS // For the crew computer - var/random_sensor = TRUE + var/sensor_flags = SENSOR_RANDOM var/sensor_mode = NO_SENSORS + var/sensor_mode_intended = NO_SENSORS //if sensors become damaged and are repaired later, it will revert to the user's intended preferences + var/sensormaxintegrity = 200 //if this is zero, then our sensors can only be destroyed by shredded clothing + var/sensordamage = 0 //how much damage did our sensors take? var/can_adjust = TRUE var/adjusted = NORMAL_STYLE var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only @@ -32,29 +35,75 @@ /obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if((has_sensor == BROKEN_SENSORS) && istype(I, /obj/item/stack/cable_coil)) - if(damaged_clothes) - to_chat(user,"You should repair the damage done to [src] first.") + if(damaged_clothes == CLOTHING_SHREDDED) + to_chat(user,"[src] is too damaged to have its suit sensors repaired! Repair it first.") return 0 var/obj/item/stack/cable_coil/C = I I.use_tool(src, user, 0, 1) has_sensor = HAS_SENSORS + sensordamage = 0 + sensor_mode = sensor_mode_intended to_chat(user,"You repair the suit sensors on [src] with [C].") return 1 + if(!attach_accessory(I, user)) return ..() +/obj/item/clothing/under/take_damage_zone(def_zone, damage_amount, damage_type, armour_penetration) + ..() + if(sensormaxintegrity == 0 || has_sensor == NO_SENSORS || sensordamage >= sensormaxintegrity) return //sensors are invincible if max integrity is 0 + var/damage_dealt = take_damage(damage_amount * 0.1, damage_type, armour_penetration, FALSE) * 10 // only deal 10% of the damage to the general integrity damage, then multiply it by 10 so we know how much to deal to limb + sensordamage += damage_dealt + var/integ = has_sensor + var/newinteg = sensorintegrity() + if(newinteg != integ) + if(newinteg < integ && iscarbon(src.loc)) //the first check is to see if for some inexplicable reason the attack healed our suit sensors + var/mob/living/carbon/C = src.loc + switch(newinteg) + if(DAMAGED_SENSORS_VITALS) + to_chat(C,"Your tracking beacon on your suit sensors have shorted out!") + if(DAMAGED_SENSORS_LIVING) + to_chat(C,"Your vital tracker on your suit sensors have shorted out!") + if(BROKEN_SENSORS) + to_chat(C,"Your suit sensors have shorted out completely!") + updatesensorintegrity(newinteg) + + +/obj/item/clothing/under/proc/sensorintegrity() + var/percentage = sensordamage/sensormaxintegrity //calculate the percentage of how much damage taken + if(percentage < SENSOR_INTEGRITY_COORDS) return HAS_SENSORS + else if(percentage < SENSOR_INTEGRITY_VITALS) return DAMAGED_SENSORS_VITALS + else if(percentage < SENSOR_INTEGRITY_BINARY) return DAMAGED_SENSORS_LIVING + else return BROKEN_SENSORS + +/obj/item/clothing/under/proc/updatesensorintegrity(integ = HAS_SENSORS) + if(sensormaxintegrity == 0 || has_sensor == NO_SENSORS) return //sanity check + has_sensor = integ + switch(has_sensor) + if(HAS_SENSORS) + sensor_mode = sensor_mode_intended + if(DAMAGED_SENSORS_VITALS) + if(sensor_mode > SENSOR_VITALS) sensor_mode = SENSOR_VITALS + if(DAMAGED_SENSORS_LIVING) + if(sensor_mode > SENSOR_LIVING) sensor_mode = SENSOR_LIVING + if(BROKEN_SENSORS) + sensor_mode = NO_SENSORS + + /obj/item/clothing/under/update_clothes_damaged_state() ..() if(ismob(loc)) var/mob/M = loc M.update_inv_w_uniform() - if(has_sensor > NO_SENSORS) + if(has_sensor > NO_SENSORS && damaged_clothes == CLOTHING_SHREDDED) has_sensor = BROKEN_SENSORS + sensordamage = sensormaxintegrity /obj/item/clothing/under/New() - if(random_sensor) + if(sensor_flags & SENSOR_RANDOM) //make the sensor mode favor higher levels, except coords. sensor_mode = pick(SENSOR_OFF, SENSOR_LIVING, SENSOR_LIVING, SENSOR_VITALS, SENSOR_VITALS, SENSOR_VITALS, SENSOR_COORDS, SENSOR_COORDS) + sensor_mode_intended = sensor_mode ..() /obj/item/clothing/under/equipped(mob/user, slot) @@ -143,9 +192,14 @@ . += "Alt-click on [src] to wear it normally." else . += "Alt-click on [src] to wear it casually." - if (has_sensor == BROKEN_SENSORS) - . += "Its sensors appear to be shorted out." - else if(has_sensor > NO_SENSORS) + switch(has_sensor) + if(BROKEN_SENSORS) + . += "Its sensors appear to be shorted out completely. It can be repaired using cable." + if(DAMAGED_SENSORS_LIVING) + . += "Its sensors appear to have its tracking beacon and vital tracker broken. It can be repaired using cable." + if(DAMAGED_SENSORS_VITALS) + . += "Its sensors appear to have its tracking beacon broken. It can be repaired using cable." + if(has_sensor > NO_SENSORS) switch(sensor_mode) if(SENSOR_OFF) . += "Its sensors appear to be disabled." @@ -167,12 +221,12 @@ return if (!can_use(M)) return - if(src.has_sensor == LOCKED_SENSORS) - to_chat(usr, "The controls are locked.") - return 0 if(src.has_sensor == BROKEN_SENSORS) to_chat(usr, "The sensors have shorted out!") return 0 + if(src.sensor_flags & SENSOR_LOCKED) + to_chat(usr, "The controls are locked.") + return 0 if(src.has_sensor <= NO_SENSORS) to_chat(usr, "This suit does not have any sensors.") return 0 @@ -182,18 +236,34 @@ if(get_dist(usr, src) > 1) to_chat(usr, "You have moved too far away!") return - sensor_mode = modes.Find(switchMode) - 1 + sensor_mode_intended = modes.Find(switchMode) - 1 if (src.loc == usr) - switch(sensor_mode) + switch(sensor_mode_intended) if(0) to_chat(usr, "You disable your suit's remote sensing equipment.") + sensor_mode = sensor_mode_intended if(1) to_chat(usr, "Your suit will now only report whether you are alive or dead.") + sensor_mode = sensor_mode_intended if(2) - to_chat(usr, "Your suit will now only report your exact vital lifesigns.") + if(src.has_sensor == DAMAGED_SENSORS_LIVING) + to_chat(usr, "Your suit's vital tracker is broken, so it will only report whether you are alive or dead.") + sensor_mode = SENSOR_LIVING + else + to_chat(usr, "Your suit will now only report your exact vital lifesigns.") + sensor_mode = sensor_mode_intended if(3) - to_chat(usr, "Your suit will now report your exact vital lifesigns as well as your coordinate position.") + switch(src.has_sensor) + if(DAMAGED_SENSORS_LIVING) + to_chat(usr, "Your suit's tracking beacon and vital tracker is broken, so it will only report whether you are alive or dead.") + sensor_mode = SENSOR_LIVING + if(DAMAGED_SENSORS_VITALS) + to_chat(usr, "Your suit's tracking beacon is broken, so it will only report your vital lifesigns.") + sensor_mode = SENSOR_VITALS + if(HAS_SENSORS) + to_chat(usr, "Your suit will now report your exact vital lifesigns as well as your coordinate position.") + sensor_mode = sensor_mode_intended if(ishuman(loc)) var/mob/living/carbon/human/H = loc @@ -210,19 +280,28 @@ if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) return - if(has_sensor == LOCKED_SENSORS) - to_chat(user, "The controls are locked.") - return - if(has_sensor == BROKEN_SENSORS) - to_chat(user, "The sensors have shorted out!") - return + if(src.has_sensor == BROKEN_SENSORS) + to_chat(usr, "The sensors have shorted out!") + return 0 + if(src.sensor_flags & SENSOR_LOCKED) + to_chat(usr, "The controls are locked.") + return 0 if(has_sensor <= NO_SENSORS) to_chat(user, "This suit does not have any sensors.") return - sensor_mode = SENSOR_COORDS + sensor_mode_intended = SENSOR_COORDS - to_chat(user, "Your suit will now report your exact vital lifesigns as well as your coordinate position.") + switch(src.has_sensor) + if(DAMAGED_SENSORS_LIVING) + to_chat(usr, "Your suit's tracking beacon and vital tracker is broken, so it will only report whether you are alive or dead.") + sensor_mode = SENSOR_LIVING + if(DAMAGED_SENSORS_VITALS) + to_chat(usr, "Your suit's tracking beacon is broken, so it will only report your vital lifesigns.") + sensor_mode = SENSOR_VITALS + if(HAS_SENSORS) + to_chat(usr, "Your suit will now report your exact vital lifesigns as well as your coordinate position.") + sensor_mode = sensor_mode_intended if(ishuman(user)) var/mob/living/carbon/human/H = user diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm index 082d783bea..885e659bb2 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm @@ -59,7 +59,7 @@ item_state = "captain_envirosuit" armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 15) sensor_mode = SENSOR_COORDS - random_sensor = FALSE + sensor_flags = NONE /obj/item/clothing/under/plasmaman/mime name = "mime envirosuit" diff --git a/code/modules/clothing/under/jobs/Plasmaman/security.dm b/code/modules/clothing/under/jobs/Plasmaman/security.dm index 3330d72844..c9b7b494a3 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/security.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/security.dm @@ -5,7 +5,7 @@ item_state = "security_envirosuit" armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 10) sensor_mode = SENSOR_COORDS - random_sensor = FALSE + sensor_flags = NONE /obj/item/clothing/under/plasmaman/security/warden name = "warden plasma envirosuit" diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm index cc07665063..1d4425bc82 100644 --- a/code/modules/clothing/under/jobs/command.dm +++ b/code/modules/clothing/under/jobs/command.dm @@ -5,7 +5,7 @@ item_state = "b_suit" armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15) sensor_mode = SENSOR_COORDS - random_sensor = FALSE + sensor_flags = NONE /obj/item/clothing/under/rank/captain/util name = "command utility uniform" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 4438298dea..0b1fb99bf8 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -12,7 +12,7 @@ strip_delay = 50 alt_covers_chest = TRUE sensor_mode = SENSOR_COORDS - random_sensor = FALSE + sensor_flags = NONE /obj/item/clothing/under/rank/security/officer name = "security jumpsuit" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 59e0832fef..e01ceba0bf 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -23,16 +23,15 @@ name = "prison jumpsuit" desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." icon_state = "prisoner" - item_state = "o_suit" - has_sensor = LOCKED_SENSORS + item_state = "prisoner" sensor_mode = SENSOR_COORDS - random_sensor = FALSE + sensor_flags = SENSOR_LOCKED /obj/item/clothing/under/rank/prisoner/skirt name = "prison jumpskirt" desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position." icon_state = "prisoner_skirt" - item_state = "o_suit" + item_state = "prisoner_skirt" body_parts_covered = CHEST|GROIN|ARMS can_adjust = FALSE fitted = FEMALE_UNIFORM_TOP @@ -166,6 +165,7 @@ /obj/item/clothing/under/misc/gear_harness name = "gear harness" desc = "A simple, inconspicuous harness replacement for a jumpsuit." + limb_integrity = 180 icon_state = "gear_harness" item_state = "gear_harness" can_adjust = TRUE diff --git a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm index 246260dbf8..12f4e1f1c5 100644 --- a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm +++ b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm @@ -55,3 +55,9 @@ name = "triple-barrel shotgun internal magazine" ammo_type = /obj/item/ammo_casing/shotgun/incapacitate max_ammo = 3 + +/obj/item/ammo_box/magazine/internal/shot/levergun + name = "levergun internal magazine" + ammo_type = /obj/item/ammo_casing/c38 // they're rubber by default, i guess + caliber = "38" + max_ammo = 7 diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index fa8099a257..1416dfa812 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -8,6 +8,7 @@ var/obj/item/ammo_box/magazine/magazine var/casing_ejector = TRUE //whether the gun ejects the chambered casing var/magazine_wording = "magazine" + var/sawn_item_state = "gun" /obj/item/gun/ballistic/Initialize() . = ..() @@ -198,13 +199,17 @@ name = "sawn-off [src.name]" desc = sawn_desc w_class = WEIGHT_CLASS_NORMAL - item_state = "gun" + item_state = sawn_item_state slot_flags &= ~ITEM_SLOT_BACK //you can't sling it on your back slot_flags |= ITEM_SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) sawn_off = TRUE update_icon() return 1 +/// is something supposed to happen here? +/obj/item/gun/ballistic/proc/on_sawoff(mob/user) + return + // Sawing guns related proc /obj/item/gun/ballistic/proc/blow_up(mob/user) . = 0 diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 8035440906..14d0c6ef44 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -12,6 +12,7 @@ casing_ejector = FALSE var/recentpump = 0 // to prevent spammage weapon_weight = WEAPON_HEAVY + sawn_item_state = "sawedshotgun" /obj/item/gun/ballistic/shotgun/attackby(obj/item/A, mob/user, params) . = ..() @@ -335,3 +336,34 @@ //our hook gun! var/obj/item/gun/magic/hook/bounty/hook var/toggled = FALSE + +// hey you kids like +// LEVER GUNS? + +/obj/item/gun/ballistic/shotgun/leveraction + name = "lever-action rifle" + desc = "While lever-actions have been horribly out of date for hundreds of years now, \ + the reported potential versatility of .38 Special is worth paying attention to." + fire_sound = "sound/weapons/revolvershot.ogg" + mag_type = /obj/item/ammo_box/magazine/internal/shot/levergun + icon_state = "levercarabine" + item_state = "leveraction" + sawn_item_state = "maresleg" + +/obj/item/gun/ballistic/shotgun/leveraction/attackby(obj/item/A, mob/user, params) + ..() + if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter)) + sawoff(user) + if(istype(A, /obj/item/melee/transforming/energy)) + var/obj/item/melee/transforming/energy/W = A + if(W.active) + sawoff(user) + +/obj/item/gun/ballistic/shotgun/leveraction/on_sawoff(mob/user) + magazine.max_ammo-- // sawing off drops from 7+1 to 6+1 + +/obj/item/gun/ballistic/shotgun/leveraction/update_icon_state() + if(current_skin) + icon_state = "[unique_reskin[current_skin]][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" + else + icon_state = "[initial(icon_state)][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" diff --git a/code/modules/smithing/smithed_items.dm b/code/modules/smithing/smithed_items.dm index aff296b684..71e35ba989 100644 --- a/code/modules/smithing/smithed_items.dm +++ b/code/modules/smithing/smithed_items.dm @@ -50,7 +50,7 @@ custom_materials = list(/datum/material/iron=12000) /obj/item/ingot/diamond - custom_materials = list(/datum/material/diamond=12000) //yeah ok + custom_materials = list(/datum/material/diamond=12000) /obj/item/ingot/uranium custom_materials = list(/datum/material/uranium=12000) diff --git a/html/changelog.html b/html/changelog.html index 32c8dba4d6..2a26433ed0 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,12 @@ -->
+

25 March 2021

+

zeroisthebiggay updated:

+ +

24 March 2021

BlueWildrose updated:

GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 8ee6b9291f..4bef579d13 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -28851,3 +28851,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. will show properly when the LTSRBT is built zeroisthebiggay: - rscadd: biodegrade works on legcuffs +2021-03-25: + zeroisthebiggay: + - balance: strained muscles isn't free diff --git a/html/changelogs/AutoChangeLog-pr-14480.yml b/html/changelogs/AutoChangeLog-pr-14480.yml new file mode 100644 index 0000000000..c429e01d8d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14480.yml @@ -0,0 +1,9 @@ +author: "BlueWildrose" +delete-after: True +changes: + - balance: "Clothing no longer drops when shredded. It just becomes useless." + - balance: "Suit sensors are guaranteed to short out when the clothes become shredded, not damaged now." + - balance: "Uniform limb integrity increased from 30 to 120." + - balance: "Suit sensor damage has been added. The more damaged your suit sensors get, the less features that will be available from these suit sensors. It takes two e-sword hits to ruin your tracking beacon for instance. +tweak: Examine text on uniforms is now more clear about needing cable coil to repair your suit sensors." + - bugfix: "Fixed prisoner uniform sprite paths" diff --git a/html/changelogs/AutoChangeLog-pr-14497.yml b/html/changelogs/AutoChangeLog-pr-14497.yml new file mode 100644 index 0000000000..c93aa9f1a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14497.yml @@ -0,0 +1,5 @@ +author: "Hatterhat" +delete-after: True +changes: + - rscadd: "Lever-action rifles, chambered in .38, are now sitting in the code. They might be buyable from Cargo or the Black Market soon. Watch this space." + - rscadd: "Sawed-off shotguns now look like shotguns, but short, when inhand, instead of \"generic gun\"." diff --git a/html/changelogs/AutoChangeLog-pr-14505.yml b/html/changelogs/AutoChangeLog-pr-14505.yml new file mode 100644 index 0000000000..b1278edfb8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14505.yml @@ -0,0 +1,4 @@ +author: "timothyteakettle" +delete-after: True +changes: + - bugfix: "the loadout now colours pet collars correctly" diff --git a/html/changelogs/AutoChangeLog-pr-14507.yml b/html/changelogs/AutoChangeLog-pr-14507.yml new file mode 100644 index 0000000000..29af71cd1b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14507.yml @@ -0,0 +1,4 @@ +author: "CuteMoff" +delete-after: True +changes: + - balance: "Diamond's forcemod was changed from 1.1x to 1.2x" diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index aa6d38ad07..07000f43aa 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index 01f77ca8c9..cf07bbba91 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index d23e48b4f7..88c7e848dc 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm index 7c9bafc86d..6be13b75d9 100644 --- a/modular_citadel/code/modules/client/loadout/neck.dm +++ b/modular_citadel/code/modules/client/loadout/neck.dm @@ -21,6 +21,8 @@ /datum/gear/neck/collar name = "Collar" path = /obj/item/clothing/neck/petcollar + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#00BBBB") /datum/gear/neck/leathercollar name = "Leather collar" diff --git a/strings/tips.txt b/strings/tips.txt index 68d1cbe57a..ead853263b 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -90,7 +90,7 @@ As the Chief Engineer, you can rename areas or create entirely new ones using yo As the Chief Engineer, your hardsuit is significantly better than everybody else's. It has the best features of both engineering and atmospherics hardsuits - boasting nigh-invulnerability to radiation and all atmospheric conditions. As the Chief Engineer, you can spy on and even forge PDA communications with the message monitor console! The key is in your office. As the Chief Engineer, your locker contains a jetpack upgrade that can be attached to hardsuits. -As the Chief Engineer, the power flow control console in your office will show you APC infos and lets you control them remotely. +As the Chief Engineer, the power flow control console in your office will show you APC infos and lets you control them remotely. As an Engineer, the supermatter shard is an extremely dangerous piece of equipment: touching it will disintegrate you. As an Engineer, you can electrify grilles by placing wire "nodes" beneath them: the big seemingly unconnected bulges from a half completed wiring job. As an Engineer, return to Engineering once in a while to check on the engine and SMES cells. It's always a good idea to make sure containment isn't compromised. @@ -112,7 +112,7 @@ As an Atmospheric Technician, your backpack firefighter tank can launch resin. T As an Atmospheric Technician, your ATMOS holofan projectors can blocks gases and heat while allowing objects to pass through. With it, you can quickly contain gas spills, fires and hull breaches. Or, use it to create a plasmaman friendly lounge. As an Atmospheric Technician, burning a plasma/oxygen mix inside the incinerator will not only produce power, but also gases such as tritium and water vapor. As an Atmospheric Technician, you can change the layer of a pipe by clicking with it on a wrenched pipe or other atmos component of the desired layer. -As an Atmospheric Technician, you can take a few cans worth of N2/N2O and cool it down at local freezers. This is a good idea when dealing with (or preparing for) a supermatter meltdown. +As an Atmospheric Technician, you can take a few cans worth of N2/N2O and cool it down at local freezers. This is a good idea when dealing with (or preparing for) a supermatter meltdown. As the Head of Security, you are expected to coordinate your security force to handle any threat that comes to the station. Sometimes it means making use of the armory to handle a blob, sometimes it means being ruthless during a revolution or cult. As the Head of Security, you can call for executions or forced cyborgization, but may require the Captain's approval. As the Head of Security, don't let the power go to your head. You may have high access, great equipment, and a miniature army at your side, but being a terrible person without a good reason is grounds for banning. @@ -121,14 +121,14 @@ As the Warden, keep a close eye on the armory at all times, as it is a favored s As the Warden, if a prisoner's crimes are heinous enough you can put them in permabrig or the gulag. Make sure to check on them once in a while! As the Warden, never underestimate the power of tech slugs! Scattershot fires a cone of weaker lasers with little damage fall off, Ion slugs fires EMPs that only effect the tiles they hit, and Pulse slugs fire a singular laser that can one-hit almost any wall! As the Warden, you can use a surgical saw on riot shotguns to shorten the barrel, making them able to fit in your backpack. Make sure to empty them prior lest you blast yourself in the face! -As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals. +As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals. As the Warden, you can use handcuffs on orange prisoner shoes to turn them into cuffed shoes, forcing prisoners to walk and potentially thwarting an escape. As the Warden, tracker implants can be used on crewmembers. Doing this will let you track their person even without suit sensors and even instantly teleport to them at the local teleporter, although the implant will biodegrade after 5 minutes if its holder ever expires. As the Warden, cryostasis shotgun darts hold 10u of chemicals that will not react until it hits someone. As the Warden, chemical implants can be loaded with a cocktail of healing or combat chems, perfect for the HoS or other security officers to make use of in a pinch. Be sure to keep a eye on them though, as they cannot be injected without the prisoner management console! EMPs or starvation might lead to the chemical implant going off preemptively. As the Warden, tracker implants can be used on your security officers. Doing this will let you be able to message them when telecomms are out, or when you suspect comms are compromised. This is also good against rogue AIs as the prisoner tracker doesn't leave logs or alarms for the AI. As a Security Officer, remember that correlation does not equal causation. Someone may have just been at the wrong place at the wrong time! -As a Security Officer, remember that your belt can hold more than one stun baton. +As a Security Officer, remember that your belt can hold more than one stun baton. As a Security Officer, remember harm beating someone in the head with a blunt object can deconvert them form a being a revolutionary! This sadly doesn't work against either cult, nor does this protect them from getting reconverted unlike a mindshield implant. As a Security Officer, remember that you can attach a seclite to your taser or your helmet! As a Security Officer, communicate and coordinate with your fellow officers using the security channel (:s) to avoid confusion. @@ -283,7 +283,7 @@ As a Ghost, you can double click on just about anything to follow it. Or just wa As a Ghost, there's a button in the OOC tab labeled Observe, it lets you see through someone's eyes as if you were the one who's playing them. As a Devil, you gain power for every three souls you control, however you also become more obvious. As a Devil, as long as you control at least one other soul, you will automatically resurrect, as long as a banishment ritual is not performed. -At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. +At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. You can swap floor tiles by holding a crowbar in one hand and a stack of tiles in the other. When hacking doors, cutting and mending a "test light wire" will restore power to the door. When crafting most items, you can either manually combine parts or use the crafting menu. @@ -301,3 +301,5 @@ Being out of combat mode makes makes you deal less damage to people and objects Resting makes you deal less damage to people and objects when attacking. This stacks with the penalty incurred by being out of combat mode. You do not regenerate as much stamina while in combat mode. Resting (being on the ground) makes you regenerate stamina faster. Keybinds can be reassigned in character setup on the keybindings tab. This is extremely useful, especially if you know how to use independent binds. +If your suit sensors have been shorted out, you can use cable coil to fix them by using the coil on your suit. Your suit needs to be in proper condition, however. +Most clothing when damaged can be repaired using cloth, but there may be some clothes out there that will require different stacks of materials. diff --git a/tools/WebhookProcessor/github_webhook_processor.php b/tools/WebhookProcessor/github_webhook_processor.php index b4609c3a03..89c6729813 100644 --- a/tools/WebhookProcessor/github_webhook_processor.php +++ b/tools/WebhookProcessor/github_webhook_processor.php @@ -323,12 +323,14 @@ function handle_pr($payload) { set_labels($payload, $labels, $remove); if($no_changelog) check_dismiss_changelog_review($payload); + /* if(get_pr_code_friendliness($payload) <= 0){ $balances = pr_balances(); $author = $payload['pull_request']['user']['login']; if(isset($balances[$author]) && $balances[$author] < 0 && !is_maintainer($payload, $author)) create_comment($payload, 'You currently have a negative Fix/Feature pull request delta of ' . $balances[$author] . '. Maintainers may close this PR at will. Fixing issues or improving the codebase will improve this score.'); } + */ break; case 'edited': check_dismiss_changelog_review($payload);