diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 324f399430a..ff60243f2cf 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -145,6 +145,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_BOOZE_SLIDER "booze-slider"
#define TRAIT_QUICK_CARRY "quick-carry"
#define TRAIT_QUICKER_CARRY "quicker-carry"
+#define TRAIT_QUICK_BUILD "quick-build"
#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech"
#define TRAIT_UNSTABLE "unstable"
#define TRAIT_OIL_FRIED "oil_fried"
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index bfcbeeae414..32a21c2a1f5 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -89,3 +89,19 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
/obj/item/stack/rods/fifty
amount = 50
+
+/obj/item/stack/rods/lava
+ name = "heat resistant rod"
+ desc = "Treated, specialized metal rods. When exposed to the vaccum of space their coating breaks off, but they can hold up against the extreme heat of active lava."
+ singular_name = "heat resistant rod"
+ icon_state = "rods"
+ item_state = "rods"
+ color = "#5286b9ff"
+ flags_1 = CONDUCT_1
+ w_class = WEIGHT_CLASS_NORMAL
+ custom_materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000)
+ max_amount = 30
+ resistance_flags = FIRE_PROOF | LAVA_PROOF
+
+/obj/item/stack/rods/lava/thirty
+ amount = 30
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 6e014a5681e..282bedfd638 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -45,7 +45,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
null, \
- new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \
null, \
new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 9981e8deec8..4d024f1ee25 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -208,8 +208,13 @@
if(!building_checks(R, multiplier))
return
if (R.time)
+ var/adjusted_time = 0
usr.visible_message("[usr] starts building \a [R.title].", "You start building \a [R.title]...")
- if (!do_after(usr, R.time, target = usr))
+ if(HAS_TRAIT(usr, R.trait_booster))
+ adjusted_time = (R.time * R.trait_modifier)
+ else
+ adjusted_time = R.time
+ if (!do_after(usr, adjusted_time, target = usr))
return
if(!building_checks(R, multiplier))
return
@@ -460,8 +465,10 @@
var/window_checks = FALSE
var/placement_checks = FALSE
var/applies_mats = FALSE
+ var/trait_booster = null
+ var/trait_modifier = 1
-/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE)
+/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1)
src.title = title
@@ -475,6 +482,8 @@
src.window_checks = window_checks
src.placement_checks = placement_checks
src.applies_mats = applies_mats
+ src.trait_booster = trait_booster
+ src.trait_modifier = trait_modifier
/*
* Recipe list datum
*/
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index fefde61a586..e31a7333f1f 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -7,6 +7,7 @@
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
var/can_displace = TRUE //If the girder can be moved around by wrenching it
+ var/next_beep = 0 //Prevents spamming of the construction sound
max_integrity = 200
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_VERY_LIGHT_INSULATION
@@ -27,6 +28,12 @@
. += "[src] is disassembled! You probably shouldn't be able to see this examine message."
/obj/structure/girder/attackby(obj/item/W, mob/user, params)
+ var/platingmodifier = 1
+ if(HAS_TRAIT(user, TRAIT_QUICK_BUILD))
+ platingmodifier = 0.7
+ if(next_beep <= world.time)
+ next_beep = world.time + 10
+ playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
add_fingerprint(user)
if(istype(W, /obj/item/gun/energy/plasmacutter))
@@ -89,7 +96,7 @@
to_chat(user, "You need two sheets of metal to create a false wall!")
return
to_chat(user, "You start building a false wall...")
- if(do_after(user, 20, target = src))
+ if(do_after(user, 20*platingmodifier, target = src))
if(S.get_amount() < 2)
return
S.use(2)
@@ -102,7 +109,7 @@
to_chat(user, "You need two sheets of metal to finish a wall!")
return
to_chat(user, "You start adding plating...")
- if (do_after(user, 40, target = src))
+ if (do_after(user, 40*platingmodifier, target = src))
if(S.get_amount() < 2)
return
S.use(2)
@@ -132,7 +139,7 @@
if(S.get_amount() < 1)
return
to_chat(user, "You start finalizing the reinforced wall...")
- if(do_after(user, 50, target = src))
+ if(do_after(user, 50*platingmodifier, target = src))
if(S.get_amount() < 1)
return
S.use(1)
@@ -146,7 +153,7 @@
if(S.get_amount() < 1)
return
to_chat(user, "You start reinforcing the girder...")
- if(do_after(user, 60, target = src))
+ if(do_after(user, 60*platingmodifier, target = src))
if(S.get_amount() < 1)
return
S.use(1)
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index f28a0ec9345..1bff30a0d79 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -74,7 +74,7 @@
number_of_rods = 2
smooth = SMOOTH_TRUE
canSmoothWith = null
- obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
+ obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
return "The supporting rods look like they could be cut."
@@ -90,3 +90,30 @@
for(var/obj/structure/cable/C in T)
C.deconstruct()
..()
+
+/obj/structure/lattice/lava
+ name = "heatproof support lattice"
+ desc = "A specialized support beam for building across lava. Watch your step."
+ icon = 'icons/obj/smooth_structures/catwalk.dmi'
+ icon_state = "catwalk"
+ number_of_rods = 1
+ color = "#5286b9ff"
+ smooth = SMOOTH_TRUE
+ canSmoothWith = null
+ obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
+ resistance_flags = FIRE_PROOF | LAVA_PROOF
+
+/obj/structure/lattice/lava/deconstruction_hints(mob/user)
+ return "The rods look like they could be cut, but the heat treatment will shatter off. There's space for a tile."
+
+/obj/structure/lattice/lava/attackby(obj/item/C, mob/user, params)
+ . = ..()
+ if(istype(C, /obj/item/stack/tile/plasteel))
+ var/obj/item/stack/tile/plasteel/P = C
+ if(P.use(1))
+ to_chat(user, "You construct a floor plating, as lava settles around the rods.")
+ playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
+ new /turf/open/floor/plating(locate(x, y, z))
+ else
+ to_chat(user, "You need one floor tile to build atop [src].")
+ return
diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm
index 67b88731a25..6a1e793f711 100644
--- a/code/game/turfs/open/lava.dm
+++ b/code/game/turfs/open/lava.dm
@@ -88,10 +88,25 @@
/turf/open/lava/TakeTemperature(temp)
+/turf/open/lava/attackby(obj/item/C, mob/user, params)
+ ..()
+ if(istype(C, /obj/item/stack/rods/lava))
+ var/obj/item/stack/rods/lava/R = C
+ var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src)
+ if(H)
+ to_chat(user, "There is already a lattice here!")
+ return
+ if(R.use(1))
+ to_chat(user, "You construct a lattice.")
+ playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
+ new /obj/structure/lattice/lava(locate(x, y, z))
+ else
+ to_chat(user, "You need one rod to build a heatproof lattice.")
+ return
/turf/open/lava/proc/is_safe()
//if anything matching this typecache is found in the lava, we don't burn things
- var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
+ var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile, /obj/structure/lattice/lava))
var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache)
for(var/obj/structure/stone_tile/S in found_safeties)
if(S.fallen)
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index 6910c856b7e..763443bd7a4 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -158,6 +158,17 @@
transfer_prints = FALSE
carrytrait = TRAIT_QUICKER_CARRY
+/obj/item/clothing/gloves/color/latex/engineering
+ name = "tinker's gloves"
+ desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn."
+ icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ icon_state = "clockwork_gauntlets"
+ item_state = "clockwork_gauntlets"
+ siemens_coefficient = 0.8
+ permeability_coefficient = 0.3
+ carrytrait = TRAIT_QUICK_BUILD
+ custom_materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000)
+
/obj/item/clothing/gloves/color/white
name = "white gloves"
desc = "These look pretty fancy."
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
index 3bacd6a851a..7455461709f 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
@@ -44,7 +44,7 @@
nodamage = TRUE
flag = "energy"
temperature = 50
-
+
/obj/projectile/temp/basilisk/heated
name = "energy blast"
icon_state= "chronobolt"
@@ -67,7 +67,7 @@
adjustBruteLoss(140)
if(3)
adjustBruteLoss(110)
-
+
/mob/living/simple_animal/hostile/asteroid/basilisk/AttackingTarget()
. = ..()
if(lava_drinker && !warmed_up && istype(target, /turf/open/lava))
@@ -80,7 +80,7 @@
warmed_up = TRUE
projectiletype = /obj/projectile/temp/basilisk/heated
addtimer(CALLBACK(src, .proc/cool_down), 3000)
-
+
mob/living/simple_animal/hostile/asteroid/basilisk/proc/cool_down()
visible_message("[src] appears to be cooling down...")
if(stat != DEAD)
@@ -115,6 +115,31 @@ mob/living/simple_animal/hostile/asteroid/basilisk/proc/cool_down()
loot = list()
butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
lava_drinker = FALSE
+ search_objects = 1
+ wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond)
+
+/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/Life()
+ . = ..()
+ if(stat == CONSCIOUS)
+ consume_bait()
+
+/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait()
+ var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in oview(src, 9)
+ var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in oview(src, 9)
+ if(!diamonds && !bait)
+ return
+ if(diamonds)
+ var/distanced = 0
+ distanced = get_dist(loc,diamonds.loc)
+ if(distanced <= 1 && diamonds)
+ qdel(diamonds)
+ src.visible_message("[src] consumes [diamonds], and it disappears! ...At least, you think.")
+ if(bait)
+ var/distanceb = 0
+ distanceb = get_dist(loc,bait.loc)
+ if(distanceb <= 1 && bait)
+ qdel(bait)
+ src.visible_message("[src] examines [bait] closer, and telekinetically shatters the pen.")
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize()
. = ..()
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index a8eb4aa808b..3f225e70664 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -244,3 +244,17 @@
item_state = initial(item_state)
lefthand_file = initial(lefthand_file)
righthand_file = initial(righthand_file)
+
+/obj/item/pen/survival
+ name = "survival pen"
+ desc = "The latest in portable survival technology, this pen was designed as a miniature diamond pickaxe. Watchers find them very desirable for their diamond exterior."
+ icon = 'icons/obj/bureaucracy.dmi'
+ icon_state = "digging_pen"
+ item_state = "pen"
+ force = 3
+ w_class = WEIGHT_CLASS_TINY
+ custom_materials = list(/datum/material/iron=10, /datum/material/diamond=100, /datum/material/titanium = 10)
+ pressure_resistance = 2
+ grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1)
+ tool_behaviour = TOOL_MINING //For the classic "digging out of prison with a spoon but you're in space so this analogy doesn't work" situation.
+ toolspeed = 10 //You will never willingly choose to use one of these over a shovel.
diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm
index c3deecc958c..52cd141cc37 100644
--- a/code/modules/research/bepis.dm
+++ b/code/modules/research/bepis.dm
@@ -133,11 +133,13 @@
if(gauss_real >= gauss_minor) //Minor Success.
var/reward_number = 1
say("Experiment concluded with partial success. Dispensing compiled research efforts.")
- reward_number = rand(1,2)
+ reward_number = rand(1,3)
if(reward_number == 1)
new /obj/item/stack/circuit_stack/full(dropturf)
if(reward_number == 2)
new /obj/item/airlock_painter/decal(dropturf)
+ if(reward_number == 3)
+ new /obj/item/pen/survival(dropturf)
return
if(gauss_real <= -1) //Critical Failure
say("ERROR: CRITICAL MACHIME MALFUNCTI- ON. CURRENCY IS NOT CRASH. CANNOT COMPUTE COMMAND: 'make bucks'") //not a typo, for once.
diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm
index 09fd097d37e..c236a9973c2 100644
--- a/code/modules/research/designs/misc_designs.dm
+++ b/code/modules/research/designs/misc_designs.dm
@@ -275,7 +275,7 @@
build_path = /obj/item/tank/internals/plasma/empty
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
-
+
/datum/design/id
name = "Identification Card"
desc = "A card used to provide ID and determine access across the station."
@@ -284,7 +284,26 @@
materials = list(/datum/material/iron=200, /datum/material/glass = 100)
build_path = /obj/item/card/id
category = list("Electronics")
- departmental_flags = DEPARTMENTAL_FLAG_SERVICE
+ departmental_flags = DEPARTMENTAL_FLAG_SERVICE
+
+/datum/design/eng_gloves
+ name = "Tinkers Gloves"
+ desc = "Overdesigned engineering gloves that have automated construction subroutines dialed in, allowing for faster construction while worn."
+ id = "eng_gloves"
+ build_type = PROTOLATHE
+ materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000)
+ build_path = /obj/item/clothing/gloves/color/latex/engineering
+ category = list("Equipment")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
+
+/datum/design/lavarods
+ name = "Lava-Resistant Metal Rods"
+ id = "lava_rods"
+ build_type = PROTOLATHE
+ materials = list(/datum/material/iron=1000, /datum/material/plasma=500, /datum/material/titanium=2000)
+ build_path = /obj/item/stack/rods/lava
+ category = list("initial", "Stock Parts")
+ departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
/////////////////////////////////////////
////////////Janitor Designs//////////////
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index f405758c64e..d84fa72de69 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -1067,6 +1067,17 @@
hidden = TRUE
experimental = TRUE
+/datum/techweb_node/spec_eng
+ id = "spec_eng"
+ display_name = "Specialized Engineering"
+ description = "Conventional wisdom has deemed these engineering products 'technically' safe, but far too dangerous to traditionally condone."
+ prereq_ids = list("base")
+ design_ids = list("lava_rods", "eng_gloves")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
+ export_price = 2500
+ hidden = TRUE
+ experimental = TRUE
+
/datum/techweb_node/aus_security
id = "aus_security"
display_name = "Australicus Security Protocols"
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 06a04e3d47f..4a5765cf9bf 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi
index 6845aa97106..a83172612f5 100644
Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ