diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm
index 9692409d45..c87b9942df 100644
--- a/code/__defines/damage_organs.dm
+++ b/code/__defines/damage_organs.dm
@@ -8,6 +8,7 @@
#define HALLOSS "halloss"
#define ELECTROCUTE "electrocute"
#define BIOACID "bioacid"
+#define SEARING "searing"
#define CUT "cut"
#define BRUISE "bruise"
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 2dc4afe70a..7f7e9e705e 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -175,6 +175,7 @@
#define MAT_LEAD "lead"
#define MAT_SUPERMATTER "supermatter"
#define MAT_METALHYDROGEN "mhydrogen"
+#define MAT_OSMIUM "osmium"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 8426edcfcf..efb94d4963 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -210,13 +210,17 @@
#define O_GBLADDER "gas bladder"
#define O_POLYP "polyp segment"
#define O_ANCHOR "anchoring ligament"
+#define O_REGBRUTE "pneumoregenitor"
+#define O_REGBURN "thermoregenitor"
+#define O_REGOXY "respiroregenitor"
+#define O_REGTOX "toxoregenitor"
#define O_ACID "acid gland"
#define O_EGG "egg sac"
#define O_RESIN "resin spinner"
#define O_AREJECT "immune hub"
#define O_VENTC "morphoplastic node"
#define O_VRLINK "virtual node"
-#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK)
+#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_REGBRUTE, O_REGBURN, O_REGOXY, O_REGTOX, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK)
// External organs, aka limbs
#define BP_L_FOOT "l_foot"
diff --git a/code/__defines/xenoarcheaology.dm b/code/__defines/xenoarcheaology.dm
index 45e40cfbde..8a4988b78c 100644
--- a/code/__defines/xenoarcheaology.dm
+++ b/code/__defines/xenoarcheaology.dm
@@ -36,7 +36,8 @@
#define ARCHAEO_ALIEN_ITEM 36
#define ARCHAEO_ALIEN_BOAT 37
#define ARCHAEO_IMPERION_CIRCUIT 38
-#define MAX_ARCHAEO 38
+#define ARCHAEO_TELECUBE 39
+#define MAX_ARCHAEO 39
#define DIGSITE_GARDEN 1
#define DIGSITE_ANIMAL 2
diff --git a/code/_helpers/icons_vr.dm b/code/_helpers/icons_vr.dm
index be5de68e82..60765578e7 100644
--- a/code/_helpers/icons_vr.dm
+++ b/code/_helpers/icons_vr.dm
@@ -42,4 +42,18 @@
for(var/x_pixel = 1 to I.Width())
if (I.GetPixel(x_pixel, y_pixel))
return y_pixel - 1
- return null
\ No newline at end of file
+ return null
+
+//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below.
+/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready)
+ /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work.
+ e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/
+
+ if(istype(main) && istype(mask))
+ if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made mask.
+ mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible.
+ mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white.
+ mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white background pixels.
+
+ main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent).
+ return main
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 643ab6d790..6cde264566 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -114,6 +114,19 @@
trigger_aiming(TARGET_CAN_CLICK)
return 1
+ // VOREStation Addition Start: inbelly item interaction
+ if(isbelly(loc) && (loc == A.loc))
+ if(W)
+ var/resolved = W.resolve_attackby(A,src)
+ if(!resolved && A && W)
+ W.afterattack(A, src, 1, params) // 1: clicking something Adjacent
+ else
+ if(ismob(A)) // No instant mob attacking
+ setClickCooldown(get_attack_speed())
+ UnarmedAttack(A, 1)
+ return
+ // VOREStation Addition End
+
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
return
diff --git a/code/datums/outfits/military/fleet.dm b/code/datums/outfits/military/fleet.dm
index cf5028978d..915917918c 100644
--- a/code/datums/outfits/military/fleet.dm
+++ b/code/datums/outfits/military/fleet.dm
@@ -1,21 +1,21 @@
/decl/hierarchy/outfit/military/fleet/pt
name = OUTFIT_MILITARY("Fleet PT")
- uniform = /obj/item/clothing/under/pt/fleet
+ uniform = /obj/item/clothing/under/solgov/pt/fleet
shoes = /obj/item/clothing/shoes/black
/decl/hierarchy/outfit/military/fleet/utility
name = OUTFIT_MILITARY("Fleet Utility")
- uniform = /obj/item/clothing/under/utility/fleet
- shoes = /obj/item/clothing/shoes/boots/jackboots
+ uniform = /obj/item/clothing/under/solgov/utility/fleet
+ shoes = /obj/item/clothing/shoes/boots/duty
/decl/hierarchy/outfit/military/fleet/service
name = OUTFIT_MILITARY("Fleet Service")
- uniform = /obj/item/clothing/under/service/fleet
+ uniform = /obj/item/clothing/under/solgov/service/fleet
shoes = /obj/item/clothing/shoes/dress/white
/decl/hierarchy/outfit/military/fleet/dress
name = OUTFIT_MILITARY("Fleet Dress")
- uniform = /obj/item/clothing/under/service/fleet
+ uniform = /obj/item/clothing/under/solgov/service/fleet
shoes = /obj/item/clothing/shoes/dress/white
suit = /obj/item/clothing/suit/storage/toggle/dress/fleet
gloves = /obj/item/clothing/gloves/white
diff --git a/code/datums/outfits/military/marines.dm b/code/datums/outfits/military/marines.dm
index d818dabcaa..719b36c690 100644
--- a/code/datums/outfits/military/marines.dm
+++ b/code/datums/outfits/military/marines.dm
@@ -1,22 +1,22 @@
/decl/hierarchy/outfit/military/marine/pt
name = OUTFIT_MILITARY("Marine PT")
- uniform = /obj/item/clothing/under/pt/marine
+ uniform = /obj/item/clothing/under/solgov/pt/marine
shoes = /obj/item/clothing/shoes/black
/decl/hierarchy/outfit/military/marine/utility
name = OUTFIT_MILITARY("Marine Utility")
- uniform = /obj/item/clothing/under/utility/marine
+ uniform = /obj/item/clothing/under/solgov/utility/marine
shoes = /obj/item/clothing/shoes/boots/jungle
/decl/hierarchy/outfit/military/marine/service
name = OUTFIT_MILITARY("Marine Service")
- uniform = /obj/item/clothing/under/service/marine
+ uniform = /obj/item/clothing/under/solgov/service/marine
shoes = /obj/item/clothing/shoes/dress
suit = /obj/item/clothing/suit/storage/service/marine
/decl/hierarchy/outfit/military/marine/dress
name = OUTFIT_MILITARY("Marine Dress")
- uniform = /obj/item/clothing/under/mildress/marine
+ uniform = /obj/item/clothing/under/solgov/mildress/marine
shoes = /obj/item/clothing/shoes/dress/white
suit = /obj/item/clothing/suit/dress/marine
gloves = /obj/item/clothing/gloves/white
diff --git a/code/datums/outfits/military/sifguard.dm b/code/datums/outfits/military/sifguard.dm
index e1280f0cfe..9348224a9e 100644
--- a/code/datums/outfits/military/sifguard.dm
+++ b/code/datums/outfits/military/sifguard.dm
@@ -1,22 +1,22 @@
/decl/hierarchy/outfit/military/sifguard/pt
name = OUTFIT_MILITARY("SifGuard PT")
- uniform = /obj/item/clothing/under/pt/sifguard
+ uniform = /obj/item/clothing/under/solgov/pt/sifguard
shoes = /obj/item/clothing/shoes/black
/decl/hierarchy/outfit/military/sifguard/utility
name = OUTFIT_MILITARY("SifGuard Utility")
- uniform = /obj/item/clothing/under/utility/sifguard
- shoes = /obj/item/clothing/shoes/boots/jackboots
+ uniform = /obj/item/clothing/under/solgov/utility/sifguard
+ shoes = /obj/item/clothing/shoes/boots/tactical
/decl/hierarchy/outfit/military/sifguard/service
name = OUTFIT_MILITARY("SifGuard Service")
- uniform = /obj/item/clothing/under/utility/sifguard
- shoes = /obj/item/clothing/shoes/boots/jackboots
+ uniform = /obj/item/clothing/under/solgov/utility/sifguard
+ shoes = /obj/item/clothing/shoes/boots/tactical
suit = /obj/item/clothing/suit/storage/service/sifguard
/decl/hierarchy/outfit/military/sifguard/dress
name = OUTFIT_MILITARY("SifGuard Dress")
- uniform = /obj/item/clothing/under/mildress/sifguard
+ uniform = /obj/item/clothing/under/solgov/mildress/sifguard
shoes = /obj/item/clothing/shoes/dress
suit = /obj/item/clothing/suit/dress/expedition
gloves = /obj/item/clothing/gloves/white
diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm
index 5596d95f03..e345b18505 100644
--- a/code/datums/supplypacks/medical.dm
+++ b/code/datums/supplypacks/medical.dm
@@ -334,4 +334,18 @@
contains = list(/obj/item/device/defib_kit = 2)
cost = 30
containertype = /obj/structure/closet/crate/medical
- containername = "Defibrillator crate"
\ No newline at end of file
+ containername = "Defibrillator crate"
+
+/datum/supply_pack/med/distillery
+ name = "Chemical distiller crate"
+ contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1)
+ cost = 175
+ containertype = /obj/structure/largecrate
+ containername = "Chemical distiller crate"
+
+/datum/supply_pack/med/advdistillery
+ name = "Industrial Chemical distiller crate"
+ contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1)
+ cost = 250
+ containertype = /obj/structure/largecrate
+ containername = "Industrial Chemical distiller crate"
diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm
index 344e2bbdbd..0538f83867 100644
--- a/code/datums/supplypacks/medical_vr.dm
+++ b/code/datums/supplypacks/medical_vr.dm
@@ -1,38 +1,50 @@
-/datum/supply_pack/med/medicalbiosuits
- contains = list(
- /obj/item/clothing/head/bio_hood/scientist = 3,
- /obj/item/clothing/suit/bio_suit/scientist = 3,
- /obj/item/clothing/suit/bio_suit/virology = 3,
- /obj/item/clothing/head/bio_hood/virology = 3,
- /obj/item/clothing/suit/bio_suit/cmo,
- /obj/item/clothing/head/bio_hood/cmo,
- /obj/item/clothing/shoes/white = 7,
- /obj/item/clothing/mask/gas = 7,
- /obj/item/weapon/tank/oxygen = 7,
- /obj/item/weapon/storage/box/masks,
- /obj/item/weapon/storage/box/gloves
- )
- cost = 40
-
-/datum/supply_pack/med/virologybiosuits
- name = "Virology biohazard gear"
- contains = list(
- /obj/item/clothing/suit/bio_suit/virology = 3,
- /obj/item/clothing/head/bio_hood/virology = 3,
- /obj/item/clothing/mask/gas = 3,
- /obj/item/weapon/tank/oxygen = 3,
- /obj/item/weapon/storage/box/masks,
- /obj/item/weapon/storage/box/gloves
- )
- cost = 40
- containertype = /obj/structure/closet/crate/secure
- containername = "Virology biohazard equipment"
- access = access_medical_equip
-
-/datum/supply_pack/med/virus
- name = "Virus sample crate"
- contains = list(/obj/item/weapon/virusdish/random = 4)
- cost = 25
- containertype = /obj/structure/closet/crate/secure
- containername = "Virus sample crate"
- access = access_medical_equip
\ No newline at end of file
+/datum/supply_pack/med/medicalbiosuits
+ contains = list(
+ /obj/item/clothing/head/bio_hood/scientist = 3,
+ /obj/item/clothing/suit/bio_suit/scientist = 3,
+ /obj/item/clothing/suit/bio_suit/virology = 3,
+ /obj/item/clothing/head/bio_hood/virology = 3,
+ /obj/item/clothing/suit/bio_suit/cmo,
+ /obj/item/clothing/head/bio_hood/cmo,
+ /obj/item/clothing/shoes/white = 7,
+ /obj/item/clothing/mask/gas = 7,
+ /obj/item/weapon/tank/oxygen = 7,
+ /obj/item/weapon/storage/box/masks,
+ /obj/item/weapon/storage/box/gloves
+ )
+ cost = 40
+
+/datum/supply_pack/med/virologybiosuits
+ name = "Virology biohazard gear"
+ contains = list(
+ /obj/item/clothing/suit/bio_suit/virology = 3,
+ /obj/item/clothing/head/bio_hood/virology = 3,
+ /obj/item/clothing/mask/gas = 3,
+ /obj/item/weapon/tank/oxygen = 3,
+ /obj/item/weapon/storage/box/masks,
+ /obj/item/weapon/storage/box/gloves
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate/secure
+ containername = "Virology biohazard equipment"
+ access = access_medical_equip
+
+/datum/supply_pack/med/virus
+ name = "Virus sample crate"
+ contains = list(/obj/item/weapon/virusdish/random = 4)
+ cost = 25
+ containertype = /obj/structure/closet/crate/secure
+ containername = "Virus sample crate"
+ access = access_medical_equip
+
+
+/datum/supply_pack/med/bloodpack
+ containertype = /obj/structure/closet/crate/medical/blood
+
+/datum/supply_pack/med/compactdefib
+ name = "Compact Defibrillator crate"
+ contains = list(/obj/item/device/defib_kit/compact = 1)
+ cost = 90
+ containertype = /obj/structure/closet/crate/secure
+ containername = "Compact Defibrillator crate"
+ access = access_medical_equip
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 69733a60d8..eb2a88b497 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -284,7 +284,7 @@ var/global/datum/controller/gameticker/ticker
var/mob/living/carbon/human/new_char = player.create_character()
if(new_char)
qdel(player)
- if(istype(new_char))
+ if(istype(new_char) && !(new_char.mind.assigned_role=="Cyborg"))
data_core.manifest_inject(new_char)
//VOREStation Edit End
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index 8778b4e5f3..085c070f7d 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -149,6 +149,8 @@
var/power_losses
var/last_power_draw = 0
var/obj/item/weapon/cell/cell
+ var/use_cell = TRUE
+ var/removeable_cell = TRUE
/obj/machinery/portable_atmospherics/powered/powered()
if(use_power) //using area power
@@ -158,7 +160,7 @@
return 0
/obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/weapon/cell))
+ if(use_cell && istype(I, /obj/item/weapon/cell))
if(cell)
to_chat(user, "There is already a power cell installed.")
return
@@ -173,7 +175,7 @@
power_change()
return
- if(I.is_screwdriver())
+ if(I.is_screwdriver() && removeable_cell)
if(!cell)
to_chat(user, "There is no power cell installed.")
return
diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm
index 88bf735f53..0baa68cf22 100644
--- a/code/game/machinery/frame.dm
+++ b/code/game/machinery/frame.dm
@@ -102,6 +102,12 @@
circuit = /obj/item/weapon/circuitboard/grinder
frame_size = 3
+/datum/frame/frame_types/reagent_distillery
+ name = "Distillery"
+ frame_class = FRAME_CLASS_MACHINE
+ circuit = /obj/item/weapon/circuitboard/distiller
+ frame_size = 4
+
/datum/frame/frame_types/display
name = "Display"
frame_class = FRAME_CLASS_DISPLAY
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index ab77220281..56fa5c75a0 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -74,6 +74,7 @@
var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg
var/check_all = FALSE //If active, will fire on anything, including synthetics.
var/ailock = FALSE // AI cannot use this
+ var/check_down = FALSE //If active, will shoot to kill when lethals are also on
var/faction = null //if set, will not fire at people in the same faction for any reason.
var/attacked = FALSE //if set to TRUE, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
@@ -103,6 +104,7 @@
check_weapons = TRUE
check_anomalies = TRUE
check_all = FALSE
+ check_down = TRUE
/obj/machinery/porta_turret/can_catalogue(mob/user) // Dead turrets can't be scanned.
if(stat & BROKEN)
@@ -224,6 +226,7 @@
check_records = FALSE
check_anomalies = FALSE
check_all = FALSE
+ check_down = FALSE
/obj/machinery/porta_turret/lasertag/red
turret_type = "red"
@@ -404,7 +407,7 @@
return 1
if(locked && !issilicon(user))
- to_chat(user, "Access denied.")
+ to_chat(user, "Controls locked.")
return 1
return 0
@@ -438,6 +441,7 @@
settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access)
settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies)
settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all)
+ settings[++settings.len] = list("category" = "Neutralize Downed Entities", "setting" = "check_down", "value" = check_down)
data["settings"] = settings
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -489,6 +493,8 @@
check_anomalies = value
else if(href_list["command"] == "check_all")
check_all = value
+ else if(href_list["command"] == "check_down")
+ check_down = value
return 1
@@ -732,7 +738,7 @@
if(!emagged && issilicon(L) && check_all == FALSE) // Don't target silica, unless told to neutralize everything.
return TURRET_NOT_TARGET
- if(L.stat && !emagged) //if the perp is dead/dying, no need to bother really
+ if(L.stat == DEAD && !emagged) //if the perp is dead, no need to bother really
return TURRET_NOT_TARGET //move onto next potential victim!
if(get_dist(src, L) > 7) //if it's too far away, why bother?
@@ -749,7 +755,7 @@
if(check_synth || check_all) //If it's set to attack all non-silicons or everything, target them!
if(L.lying)
- return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
+ return check_down ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
return TURRET_PRIORITY_TARGET
if(iscuffed(L)) // If the target is handcuffed, leave it alone
@@ -766,7 +772,7 @@
return TURRET_NOT_TARGET //if threat level < 4, keep going
if(L.lying) //if the perp is lying down, it's still a target but a less-important target
- return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
+ return check_down ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 0667860f95..74cdb2d368 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -628,6 +628,11 @@
/obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper
+ if(istype(Proj, /obj/item/projectile/test))
+ var/obj/item/projectile/test/Test = Proj
+ Test.hit |= occupant // Register a hit on the occupant, for things like turrets, or in simple-mob cases stopping friendly fire in firing line mode.
+ return
+
src.log_message("Hit by projectile. Type: [Proj.name]([Proj.check_armour]).",1)
call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment
..()
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 591da02757..4e39439c12 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -716,7 +716,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
icon = 'icons/obj/device.dmi'
//Worn icon generation for on-mob sprites
-/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer)
+/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument.
//Get the required information about the base icon
var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands)
var/state2use = get_worn_icon_state(slot_name = slot_name)
@@ -738,6 +738,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
if(!inhands)
apply_custom(standing_icon) //Pre-image overridable proc to customize the thing
apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders
+ if(istype(clip_mask)) //VOREStation Edit - For taur bodies/tails clipping off parts of uniforms and suits.
+ standing_icon = get_icon_difference(standing_icon, clip_mask, 1)
var/image/standing = image(standing_icon)
standing.alpha = alpha
diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm
index e37587812a..a4859c08a5 100644
--- a/code/game/objects/items/devices/communicator/UI.dm
+++ b/code/game/objects/items/devices/communicator/UI.dm
@@ -116,7 +116,7 @@
data["flashlight"] = fon
data["manifest"] = PDA_Manifest
data["feeds"] = compile_news()
- data["latest_news"] = get_recent_news()
+ //data["latest_news"] = get_recent_news() //VOREStation Edit, bandaid for catastrophic runtime lag in helper.dm
if(cartridge) // If there's a cartridge, we need to grab the information from it
data["cart_devices"] = cartridge.get_device_status()
data["cart_templates"] = cartridge.ui_templates
diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm
index 63308e6caa..6b59d13ea5 100644
--- a/code/game/objects/items/weapons/circuitboards/frame.dm
+++ b/code/game/objects/items/weapons/circuitboards/frame.dm
@@ -170,6 +170,15 @@
/obj/item/weapon/stock_parts/gear = 1,
/obj/item/weapon/reagent_containers/glass/beaker/large = 1)
+/obj/item/weapon/circuitboard/distiller
+ build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery
+ board_type = new /datum/frame/frame_types/reagent_distillery
+ req_components = list(
+ /obj/item/weapon/stock_parts/capacitor = 1,
+ /obj/item/weapon/stock_parts/micro_laser = 1,
+ /obj/item/weapon/stock_parts/motor = 2,
+ /obj/item/weapon/stock_parts/gear = 1)
+
/obj/item/weapon/circuitboard/teleporter_hub
name = T_BOARD("teleporter hub")
build_path = /obj/machinery/teleport/hub
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 43e7e0f90c..d4a29d47f3 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -97,6 +97,23 @@
name = "seismic charge"
desc = "Used to dig holes in specific areas without too much extra hole."
- blast_heavy = 3
- blast_light = 5
- blast_flash = 8
+ blast_heavy = 2
+ blast_light = 4
+ blast_flash = 7
+
+/obj/item/weapon/plastique/seismic/attackby(var/obj/item/I, var/mob/user)
+ . = ..()
+ if(open_panel)
+ if(istype(I, /obj/item/weapon/stock_parts/micro_laser))
+ var/obj/item/weapon/stock_parts/SP = I
+ var/new_blast_power = max(1, round(SP.rating / 2) + 1)
+ if(new_blast_power > blast_heavy)
+ to_chat(user, "You install \the [I] into \the [src].")
+ user.drop_from_inventory(I)
+ qdel(I)
+ blast_heavy = new_blast_power
+ blast_light = blast_heavy + round(new_blast_power * 0.5)
+ blast_flash = blast_light + round(new_blast_power * 0.75)
+ else
+ to_chat(user, "The [I] is not any better than the component already installed into this charge!")
+ return .
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/explosives_vr.dm b/code/game/objects/items/weapons/explosives_vr.dm
new file mode 100644
index 0000000000..a82ca02bbc
--- /dev/null
+++ b/code/game/objects/items/weapons/explosives_vr.dm
@@ -0,0 +1,17 @@
+/obj/item/weapon/plastique/seismic/locked
+ desc = "Used to dig holes in specific areas without too much extra hole. Has extra mechanism that safely implodes the bomb if it is used in close proximity to the facility."
+
+/obj/item/weapon/plastique/seismic/locked/explode(var/location)
+ if(!target)
+ target = get_atom_on_turf(src)
+ if(!target)
+ target = src
+
+ var/turf/T = get_turf(target)
+ if(T.z in using_map.map_levels)
+ target.visible_message("\The [src] lets out a loud beep as safeties trigger, before imploding and falling apart.")
+ target.overlays -= image_overlay
+ qdel(src)
+ return 0
+ else
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
new file mode 100644
index 0000000000..56204be984
--- /dev/null
+++ b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
@@ -0,0 +1,30 @@
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked
+ desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones. This one has a safety interlock that prevents release if used while in proximity to the facility."
+ req_access = list(access_armory) //for toggling safety
+ var/locked = 1
+
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/detonate()
+ if(locked)
+ var/turf/T = get_turf(src)
+ if(T.z in using_map.map_levels)
+ icon_state = initial(icon_state)
+ active = 0
+ return 0
+ return ..()
+
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/attackby(obj/item/I, mob/user)
+ var/obj/item/weapon/card/id/id = I.GetID()
+ if(istype(id))
+ if(check_access(id))
+ locked = !locked
+ to_chat(user, "You [locked ? "enable" : "disable"] the safety lock on \the [src].")
+ else
+ to_chat(user, "Access denied.")
+ user.visible_message("[user] swipes \the [I] against \the [src].")
+ else
+ return ..()
+
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/emag_act(var/remaining_charges,var/mob/user)
+ ..()
+ locked = !locked
+ to_chat(user, "You [locked ? "enable" : "disable"] the safety lock on \the [src]!")
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm
index 6aa1a5c540..6da8a1b933 100644
--- a/code/game/objects/items/weapons/id cards/station_ids.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids.dm
@@ -31,6 +31,7 @@
var/dorm = 0 // determines if this ID has claimed a dorm already
var/mining_points = 0 // For redeeming at mining equipment vendors
+ var/survey_points = 0 // For redeeming at explorer equipment vendors.
/obj/item/weapon/card/id/examine(mob/user)
set src in oview(1)
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index f825577d6f..d935d4eaa2 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -12,6 +12,12 @@
var/lpower = 2
var/lcolor = "#0099FF"
+ // If it uses energy.
+ var/use_cell = FALSE
+ var/hitcost = 120
+ var/obj/item/weapon/cell/bcell = null
+ var/cell_type = /obj/item/weapon/cell/device
+
/obj/item/weapon/melee/energy/proc/activate(mob/living/user)
if(active)
return
@@ -38,7 +44,31 @@
w_class = initial(w_class)
set_light(0,0)
+/obj/item/weapon/melee/energy/proc/use_charge(var/cost)
+ if(active)
+ if(bcell)
+ if(bcell.checked_use(cost))
+ return 1
+ else
+ return 0
+ return null
+
+/obj/item/weapon/melee/energy/examine(mob/user)
+ if(!..(user, 1))
+ return
+
+ if(use_cell)
+ if(bcell)
+ to_chat(user, "The blade is [round(bcell.percent())]% charged.")
+ if(!bcell)
+ to_chat(user, "The blade does not have a power source installed.")
+
/obj/item/weapon/melee/energy/attack_self(mob/living/user as mob)
+ if(use_cell)
+ if((!bcell || bcell.charge < hitcost) && !active)
+ to_chat(user, "\The [src] does not seem to have power.")
+ return
+
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
if (active)
if ((CLUMSY in user.mutations) && prob(50))
@@ -64,6 +94,37 @@
"\The [user] is falling on \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide."))
return (BRUTELOSS|FIRELOSS)
+/obj/item/weapon/melee/energy/attack(mob/M, mob/user)
+ if(active && use_cell)
+ if(!use_charge(hitcost))
+ deactivate(user)
+ visible_message("\The [src]'s blade flickers, before deactivating.")
+ return ..()
+
+/obj/item/weapon/melee/energy/attackby(obj/item/weapon/W, mob/user)
+ if(use_cell)
+ if(istype(W, cell_type))
+ if(!bcell)
+ user.drop_item()
+ W.loc = src
+ bcell = W
+ to_chat(user, "You install a cell in [src].")
+ update_icon()
+ else
+ to_chat(user, "[src] already has a cell.")
+ else if(W.is_screwdriver() && bcell)
+ bcell.update_icon()
+ bcell.forceMove(get_turf(loc))
+ bcell = null
+ to_chat(user, "You remove the cell from \the [src].")
+ deactivate()
+ update_icon()
+ return
+ return ..()
+
+/obj/item/weapon/melee/energy/get_cell()
+ return bcell
+
/*
* Energy Axe
*/
@@ -90,11 +151,13 @@
/obj/item/weapon/melee/energy/axe/activate(mob/living/user)
..()
+ damtype = SEARING
icon_state = "axe1"
to_chat(user, "\The [src] is now energised.")
/obj/item/weapon/melee/energy/axe/deactivate(mob/living/user)
..()
+ damtype = BRUTE
icon_state = initial(icon_state)
to_chat(user, "\The [src] is de-energised. It's just a regular axe now.")
@@ -103,6 +166,20 @@
visible_message("\The [user] swings \the [src] towards [TU.his] head! It looks like [TU.he] [TU.is] trying to commit suicide.")
return (BRUTELOSS|FIRELOSS)
+/obj/item/weapon/melee/energy/axe/charge
+ name = "charge axe"
+ desc = "An energised axe."
+ active_force = 35
+ active_throwforce = 20
+ force = 15
+
+ use_cell = TRUE
+ hitcost = 120
+
+/obj/item/weapon/melee/energy/axe/charge/loaded/New()
+ ..()
+ bcell = new/obj/item/weapon/cell/device/weapon(src)
+
/*
* Energy Sword
*/
@@ -274,64 +351,7 @@
armor_penetration = 25
projectile_parry_chance = 40
- var/hitcost = 75
- var/obj/item/weapon/cell/bcell = null
- var/cell_type = /obj/item/weapon/cell/device
-
-/obj/item/weapon/melee/energy/sword/charge/proc/use_charge(var/cost)
- if(active)
- if(bcell)
- if(bcell.checked_use(cost))
- return 1
- else
- return 0
- return null
-
-/obj/item/weapon/melee/energy/sword/charge/examine(mob/user)
- if(!..(user, 1))
- return
-
- if(bcell)
- to_chat(user, "The blade is [round(bcell.percent())]% charged.")
- if(!bcell)
- to_chat(user, "The blade does not have a power source installed.")
-
-/obj/item/weapon/melee/energy/sword/charge/attack_self(mob/user as mob)
- if((!bcell || bcell.charge < hitcost) && !active)
- to_chat(user, "\The [src] does not seem to have power.")
- return
- ..()
-
-/obj/item/weapon/melee/energy/sword/charge/attack(mob/M, mob/user)
- if(active)
- if(!use_charge(hitcost))
- deactivate(user)
- visible_message("\The [src]'s blade flickers, before retracting.")
- return ..()
-
-/obj/item/weapon/melee/energy/sword/charge/attackby(obj/item/weapon/W, mob/user)
- if(istype(W, cell_type))
- if(!bcell)
- user.drop_item()
- W.loc = src
- bcell = W
- to_chat(user, "You install a cell in [src].")
- update_icon()
- else
- to_chat(user, "[src] already has a cell.")
- else if(W.is_screwdriver() && bcell)
- bcell.update_icon()
- bcell.forceMove(get_turf(loc))
- bcell = null
- to_chat(user, "You remove the cell from \the [src].")
- deactivate()
- update_icon()
- return
- else
- ..()
-
-/obj/item/weapon/melee/energy/sword/charge/get_cell()
- return bcell
+ hitcost = 75
/obj/item/weapon/melee/energy/sword/charge/loaded/New()
..()
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index f478b2d11c..491d815776 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -504,6 +504,14 @@
mounted_pack.return_nozzle()
to_chat(user, "\The [src] retracts to its fueltank.")
+/obj/item/weapon/weldingtool/tubefed/survival
+ name = "tube-fed emergency welding tool"
+ desc = "A bulky, cooler-burning welding tool that draws from a worn welding tank."
+ icon_state = "tubewelder"
+ max_fuel = 5
+ toolspeed = 1.75
+ eye_safety_modifier = 2
+
/*
* Electric/Arc Welder
*/
diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm
index 27927b8180..1e63201f4e 100644
--- a/code/game/objects/items/weapons/traps.dm
+++ b/code/game/objects/items/weapons/traps.dm
@@ -11,6 +11,8 @@
origin_tech = list(TECH_MATERIAL = 1)
matter = list(DEFAULT_WALL_MATERIAL = 18750)
var/deployed = 0
+ var/camo_net = FALSE
+ var/stun_length = 0.25 SECONDS
/obj/item/weapon/beartrap/suicide_act(mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
@@ -98,6 +100,7 @@
set_dir(L.dir)
can_buckle = 1
buckle_mob(L)
+ L.Stun(stun_length)
L << "The steel jaws of \the [src] bite into you, trapping you in place!"
deployed = 0
can_buckle = initial(can_buckle)
@@ -122,6 +125,21 @@
..()
if(!deployed)
+ if(camo_net)
+ alpha = 255
+
icon_state = "beartrap0"
else
+ if(camo_net)
+ alpha = 50
+
icon_state = "beartrap1"
+
+/obj/item/weapon/beartrap/hunting
+ name = "hunting trap"
+ desc = "A mechanically activated leg trap. High-tech and reliable. Looks like it could really hurt if you set it off."
+ stun_length = 1 SECOND
+ camo_net = TRUE
+ color = "#C9DCE1"
+
+ origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 1)
diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm
index 5df0c9dbe3..4225ed810a 100644
--- a/code/game/objects/items/weapons/weldbackpack.dm
+++ b/code/game/objects/items/weapons/weldbackpack.dm
@@ -7,6 +7,7 @@
w_class = ITEMSIZE_LARGE
var/max_fuel = 350
var/obj/item/weapon/nozzle = null //Attached welder, or other spray device.
+ var/nozzle_type = /obj/item/weapon/weldingtool/tubefed
var/nozzle_attached = 0
/obj/item/weapon/weldpack/Initialize()
@@ -15,7 +16,7 @@
reagents = R
R.my_atom = src
R.add_reagent("fuel", max_fuel)
- nozzle = new/obj/item/weapon/weldingtool/tubefed(src)
+ nozzle = new nozzle_type(src)
nozzle_attached = 1
/obj/item/weapon/weldpack/Destroy()
@@ -145,3 +146,14 @@
..(user)
user << text("\icon[] [] units of fuel left!", src, src.reagents.total_volume)
return
+
+/obj/item/weapon/weldpack/survival
+ name = "emergency welding kit"
+ desc = "A heavy-duty, portable welding fluid carrier."
+ slot_flags = SLOT_BACK
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "welderpack-e"
+ item_state = "welderpack"
+ w_class = ITEMSIZE_LARGE
+ max_fuel = 100
+ nozzle_type = /obj/item/weapon/weldingtool/tubefed/survival
diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm
index eb5741c6a1..d39983af2f 100644
--- a/code/game/objects/random/mapping.dm
+++ b/code/game/objects/random/mapping.dm
@@ -65,6 +65,21 @@
prob(10);/obj/effect/mine/stun,
prob(10);/obj/effect/mine/incendiary,)
+/obj/random/humanoidremains
+ name = "Random Humanoid Remains"
+ desc = "This is a random pile of remains."
+ spawn_nothing_percentage = 15
+ icon = 'icons/effects/blood.dmi'
+ icon_state = "remains"
+
+/obj/random/humanoidremains/item_to_spawn()
+ return pick(prob(30);/obj/effect/decal/remains/human,
+ prob(25);/obj/effect/decal/remains/ribcage,
+ prob(25);/obj/effect/decal/remains/tajaran,
+ prob(10);/obj/effect/decal/remains/unathi,
+ prob(10);/obj/effect/decal/remains/posi
+ )
+
/obj/random_multi/single_item/captains_spare_id
name = "Multi Point - Captain's Spare"
id = "Captain's spare id"
@@ -396,5 +411,54 @@
/obj/item/clothing/mask/luchador/rudos,
/obj/item/clothing/mask/luchador/tecnicos,
/obj/structure/closet/crate
+ ),
+ prob(1);list(
+ /obj/machinery/artifact,
+ /obj/structure/anomaly_container
+ ),
+ prob(1);list(
+ /obj/random/curseditem,
+ /obj/random/humanoidremains,
+ /obj/structure/closet/crate
)
)
+
+/*
+ * Turf swappers.
+ */
+
+/obj/random/turf
+ name = "random Sif turf"
+ desc = "This is a random Sif turf."
+
+ spawn_nothing_percentage = 20
+
+ var/override_outdoors = FALSE // Do we override our chosen turf's outdoors?
+ var/turf_outdoors = TRUE // Will our turf be outdoors?
+
+/obj/random/turf/spawn_item()
+ var/build_path = item_to_spawn()
+
+ var/turf/T1 = get_turf(src)
+ T1.ChangeTurf(build_path, 1, 1, FALSE)
+
+ if(override_outdoors)
+ T1.outdoors = turf_outdoors
+
+/obj/random/turf/item_to_spawn()
+ return pick(prob(25);/turf/simulated/floor/outdoors/grass/sif,
+ prob(25);/turf/simulated/floor/outdoors/dirt,
+ prob(25);/turf/simulated/floor/outdoors/grass/sif/forest,
+ prob(25);/turf/simulated/floor/outdoors/rocks)
+
+/obj/random/turf/lava
+ name = "random Lava spawn"
+ desc = "This is a random lava spawn."
+
+ override_outdoors = TRUE
+ turf_outdoors = FALSE
+
+/obj/random/turf/lava/item_to_spawn()
+ return pick(prob(5);/turf/simulated/floor/lava,
+ prob(3);/turf/simulated/floor/outdoors/rocks/caves,
+ prob(1);/turf/simulated/mineral)
diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm
index 8f3a50bbed..790e5471d6 100644
--- a/code/game/objects/random/misc.dm
+++ b/code/game/objects/random/misc.dm
@@ -529,3 +529,14 @@
/obj/random/janusmodule/item_to_spawn()
return pick(subtypesof(/obj/item/weapon/circuitboard/mecha/imperion))
+
+/obj/random/curseditem
+ name = "random cursed item"
+ desc = "For use in dungeons."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "red"
+
+/obj/random/curseditem/item_to_spawn()
+ var/possible_object_paths = list(/obj/item/weapon/paper/carbon/cursedform)
+ possible_object_paths |= subtypesof(/obj/item/clothing/head/psy_crown)
+ return pick(possible_object_paths)
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index e399c04d0b..aafa6f85f3 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -3,7 +3,7 @@
/obj/structure/closet/crate
name = "crate"
desc = "A rectangular steel crate."
- icon = 'icons/obj/storage.dmi'
+ icon = 'icons/obj/storage_vr.dmi' //VOREStation edit
icon_state = "crate"
icon_opened = "crateopen"
icon_closed = "crate"
@@ -293,6 +293,9 @@
/obj/structure/closet/crate/solar
name = "solar pack crate"
+ icon_state = "engi_crate" //VOREStation Edit
+ icon_opened = "engi_crateopen" //VOREStation Edit
+ icon_closed = "engi_crate" //VOREStation Edit
starts_with = list(
/obj/item/solar_assembly = 21,
@@ -349,6 +352,7 @@
/obj/structure/closet/crate/bin
name = "large bin"
desc = "A large bin."
+ icon = 'icons/obj/storage.dmi' //VOREStation edit
icon_state = "largebin"
icon_opened = "largebinopen"
icon_closed = "largebin"
@@ -417,6 +421,7 @@
/obj/structure/closet/crate/secure/bin
name = "secure bin"
desc = "A secure bin."
+ icon = 'icons/obj/storage.dmi' //VOREStation edit
icon_state = "largebins"
icon_opened = "largebinsopen"
icon_closed = "largebins"
@@ -429,7 +434,7 @@
/obj/structure/closet/crate/large
name = "large crate"
desc = "A hefty metal crate."
- icon = 'icons/obj/storage.dmi'
+ icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit
icon_state = "largemetal"
icon_opened = "largemetalopen"
icon_closed = "largemetal"
@@ -457,10 +462,10 @@
/obj/structure/closet/crate/secure/large
name = "large crate"
desc = "A hefty metal crate with an electronic locking system."
- icon = 'icons/obj/storage.dmi'
- icon_state = "largemetal"
- icon_opened = "largemetalopen"
- icon_closed = "largemetal"
+ icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit
+ icon_state = "largemetalsecure" //VOREStation Edit
+ icon_opened = "largemetalsecureopen" //VOREStation Edit
+ icon_closed = "largemetalsecure" //VOREStation Edit
redlight = "largemetalr"
greenlight = "largemetalg"
diff --git a/code/game/objects/structures/crates_lockers/crates_vr.dm b/code/game/objects/structures/crates_lockers/crates_vr.dm
index c2a5cee915..85eccb3d77 100644
--- a/code/game/objects/structures/crates_lockers/crates_vr.dm
+++ b/code/game/objects/structures/crates_lockers/crates_vr.dm
@@ -31,4 +31,9 @@
..()
- return
\ No newline at end of file
+ return
+
+/obj/structure/closet/crate/medical/blood
+ icon_state = "blood"
+ icon_opened = "bloodopen"
+ icon_closed = "blood"
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm
index a7a4b77823..79bd5e2949 100644
--- a/code/game/objects/structures/crates_lockers/largecrate.dm
+++ b/code/game/objects/structures/crates_lockers/largecrate.dm
@@ -1,7 +1,7 @@
/obj/structure/largecrate
name = "large crate"
desc = "A hefty wooden crate."
- icon = 'icons/obj/storage.dmi'
+ icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit
icon_state = "densecrate"
density = 1
var/list/starts_with
@@ -82,10 +82,11 @@
starts_with = list(/obj/structure/vehiclecage/quadtrailer)
/obj/structure/largecrate/animal
- icon_state = "mulecrate"
+ icon_state = "lisacrate" //VOREStation Edit
/obj/structure/largecrate/animal/mulebot
name = "Mulebot crate"
+ icon_state = "mulecrate" //VOREStation Edit
starts_with = list(/mob/living/bot/mulebot)
/obj/structure/largecrate/animal/corgi
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 86a98e6a69..15bfe8ac89 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -1,14 +1,82 @@
+/obj/structure/flora
+ name = "flora"
+ desc = "A perfectly generic plant."
+ anchored = TRUE // Usually, plants don't move. Usually.
+ plane = DECAL_PLANE
+ layer = BELOW_MOB_LAYER
+ var/randomize_size = FALSE
+ var/max_x_scale = 1.25
+ var/max_y_scale = 1.25
+ var/min_x_scale = 0.9
+ var/min_y_scale = 0.9
+ var/harvest_tool = null // The type of item used to harvest the plant.
+ var/harvest_count = 0
+
+ var/randomize_harvest_count = TRUE
+ var/max_harvests = 0
+ var/min_harvests = -1
+ var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
+
+/obj/structure/flora/Initialize()
+ ..()
+
+ if(randomize_size)
+ icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
+ icon_scale_y = rand(min_y_scale * 100, max_y_scale * 100) / 100
+
+ if(prob(50))
+ icon_scale_x *= -1
+ update_transform()
+
+ if(randomize_harvest_count)
+ max_harvests = max(0, rand(min_harvests, max_harvests)) // Incase you want to weight it more toward 'not harvestable', set min_harvests to a negative value.
+
+/obj/structure/flora/examine(mob/user)
+ . = ..(user)
+ if(harvest_count < max_harvests)
+ to_chat(user, "\The [src] seems to have something hanging from it.")
+
+/obj/structure/flora/attackby(var/obj/item/weapon/W, var/mob/living/user)
+ if(can_harvest(W))
+ var/harvest_spawn = pickweight(harvest_loot)
+ var/atom/movable/AM = spawn_harvest(harvest_spawn, user)
+
+ if(!AM)
+ to_chat(user, "You fail to harvest anything from \the [src].")
+
+ else
+ to_chat(user, "You harvest \the [AM] from \the [src].")
+ return
+
+ ..(W, user)
+
+/obj/structure/flora/proc/can_harvest(var/obj/item/I)
+ . = FALSE
+ if(harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests)
+ . = TRUE
+ return .
+
+/obj/structure/flora/proc/spawn_harvest(var/path = null, var/mob/user = null)
+ if(!ispath(path))
+ return 0
+ var/turf/Target = get_turf(src)
+ if(user)
+ Target = get_turf(user)
+
+ var/atom/movable/AM = new path(Target)
+
+ harvest_count++
+ return AM
//bushes
/obj/structure/flora/bush
name = "bush"
icon = 'icons/obj/flora/snowflora.dmi'
icon_state = "snowbush1"
- anchored = 1
/obj/structure/flora/bush/New()
..()
@@ -20,6 +88,7 @@
icon = 'icons/obj/plants.dmi'
icon_state = "plant-26"
+ anchored = FALSE
//newbushes
@@ -27,7 +96,6 @@
name = "bush"
icon = 'icons/obj/flora/ausflora.dmi'
icon_state = "firstbush_1"
- anchored = 1
/obj/structure/flora/ausbushes/New()
..()
@@ -144,6 +212,7 @@
icon_state = "hangskele"
desc = "It's an anatomical model of a human skeletal system made of plaster."
+ plane = OBJ_PLANE
//potted plants credit: Flashkirby
/obj/structure/flora/pottedplant
@@ -152,6 +221,8 @@
icon = 'icons/obj/plants.dmi'
icon_state = "plant-01"
+ plane = OBJ_PLANE
+
/obj/structure/flora/pottedplant/large
name = "large potted plant"
desc = "This is a large plant. Three branches support pairs of waxy leaves."
@@ -348,4 +419,22 @@
/obj/structure/flora/sif/eyes/Initialize()
icon_state = "[initial(icon_state)][rand(1,3)]"
- . = ..()
\ No newline at end of file
+ . = ..()
+
+/datum/category_item/catalogue/flora/mosstendrils
+ name = "Sivian Flora - Moss Stalks"
+ desc = "A plant native to Sif. The plant is most closely related to the common, dense moss found covering Sif's terrain. \
+ It has evolved a method of camouflage utilizing white hairs on its dorsal sides to make it appear as a small mound of snow from \
+ above. It has no known use, though it is a common furnishing in contemporary homes."
+ value = CATALOGUER_REWARD_TRIVIAL
+
+/obj/structure/flora/sif/tendrils
+ name = "stocky tendrils"
+ desc = "A 'plant' made up of hardened moss. It has tiny hairs that bunch together to look like snow."
+ icon_state = "grass"
+ randomize_size = TRUE
+ catalogue_data = list(/datum/category_item/catalogue/flora/mosstendrils)
+
+/obj/structure/flora/sif/tendrils/Initialize()
+ icon_state = "[initial(icon_state)][rand(1,3)]"
+ . = ..()
diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm
index c02d813ffc..7cb1c3de3e 100644
--- a/code/game/objects/structures/flora/trees.dm
+++ b/code/game/objects/structures/flora/trees.dm
@@ -14,19 +14,10 @@
var/product_amount = 10 // How much of a stack you get, if the above is defined.
var/is_stump = FALSE // If true, suspends damage tracking and most other effects.
var/indestructable = FALSE // If true, the tree cannot die.
- var/randomize_size = FALSE // If true, the tree will choose a random scale in the X and Y directions to stretch.
/obj/structure/flora/tree/Initialize()
icon_state = choose_icon_state()
- if(randomize_size)
- icon_scale_x = rand(90, 125) / 100
- icon_scale_y = rand(90, 125) / 100
-
- if(prob(50))
- icon_scale_x *= -1
- update_transform()
-
return ..()
/obj/structure/flora/tree/update_transform()
@@ -39,7 +30,17 @@
/obj/structure/flora/tree/proc/choose_icon_state()
return icon_state
+/obj/structure/flora/tree/can_harvest(var/obj/item/I)
+ . = FALSE
+ if(!is_stump && harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests)
+ . = TRUE
+ return .
+
/obj/structure/flora/tree/attackby(var/obj/item/weapon/W, var/mob/living/user)
+ if(can_harvest(W))
+ ..(W, user)
+ return
+
if(!istype(W))
return ..()
@@ -302,6 +303,14 @@
product = /obj/item/stack/material/log/sif
catalogue_data = list(/datum/category_item/catalogue/flora/sif_tree)
randomize_size = TRUE
+
+ harvest_tool = /obj/item/weapon/material/knife
+ max_harvests = 2
+ min_harvests = -4
+ harvest_loot = list(
+ /obj/item/weapon/reagent_containers/food/snacks/siffruit = 5
+ )
+
var/light_shift = 0
/obj/structure/flora/tree/sif/choose_icon_state()
diff --git a/code/game/objects/structures/handrail_vr.dm b/code/game/objects/structures/handrail_vr.dm
new file mode 100644
index 0000000000..340d8dedd3
--- /dev/null
+++ b/code/game/objects/structures/handrail_vr.dm
@@ -0,0 +1,8 @@
+/obj/structure/handrail
+ name = "handrail"
+ icon = 'icons/obj/handrail_vr.dmi'
+ icon_state = "handrail"
+ desc = "A safety railing with buckles to secure yourself to when floor isn't stable enough."
+ density = 0
+ anchored = 1
+ can_buckle = 1
diff --git a/code/game/objects/structures/props/blackbox.dm b/code/game/objects/structures/props/blackbox.dm
index b6bae732f8..a28b82349f 100644
--- a/code/game/objects/structures/props/blackbox.dm
+++ b/code/game/objects/structures/props/blackbox.dm
@@ -105,4 +105,28 @@
**16/FEB/2562**
Something chitters.
End of transcript.
- "}
\ No newline at end of file
+ "}
+
+/obj/structure/prop/blackbox/xenofrigate
+ catalogue_data = list(/datum/category_item/catalogue/information/blackbox/xenofrigate)
+
+/datum/category_item/catalogue/information/blackbox/xenofrigate
+ name = "Black Box Data - MBT-540"
+ desc = {"
+
+ Begin Log
+ @$&@$& Human ##:##:##: Attention unidentified vessel, state your designation and intent.
+ !#@$&&^ Human ##:##:##: Commander I don't think they're going to stop.
+ @$&@$& Human ##:##:##: Unidentified vessel, you have until the count of three before we engage weapon-
+ !#@$&&^ Human ##:##:##: Commander! Think about what you're-
+ A repeating clicking, before silence.
+ End of first log.
+ **
+ Begin Log
+ #!#^@$& Skrell ##:##:##: Director, I think you should see this.
+ ^@$& Skrell ##:##:##: Yes? What is it?
+ #!#^@$& Skrell ##:##:##: Another one of those ships has appeared near th-462$^ ---n colonies. I would strongly advise pursuing it.
+ ^@$& Skrell ##:##:##: A wise decision. If it is damaged like the last one, we may be able to finally see what is - What?
+ A repeating ping, before silence.
+ End of second log.
+ "}
diff --git a/code/game/turfs/simulated/outdoors/grass.dm b/code/game/turfs/simulated/outdoors/grass.dm
index 72b2ee7e57..e557fb16da 100644
--- a/code/game/turfs/simulated/outdoors/grass.dm
+++ b/code/game/turfs/simulated/outdoors/grass.dm
@@ -33,7 +33,8 @@ var/list/grass_types = list(
var/tree_chance = 2
grass_types = list(
- /obj/structure/flora/sif/eyes
+ /obj/structure/flora/sif/eyes = 1,
+ /obj/structure/flora/sif/tendrils = 10
)
catalogue_data = list(/datum/category_item/catalogue/flora/sif_grass)
@@ -50,7 +51,7 @@ var/list/grass_types = list(
//edge_blending_priority++
if(grass_chance && prob(grass_chance) && !check_density())
- var/grass_type = pick(grass_types)
+ var/grass_type = pickweight(grass_types)
new grass_type(src)
. = ..()
diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm
index 0f9be4ddbf..cccc028fa3 100644
--- a/code/game/turfs/simulated/outdoors/snow.dm
+++ b/code/game/turfs/simulated/outdoors/snow.dm
@@ -58,3 +58,10 @@
to_chat(M, "You slide across the ice!")
M.SetStunned(1)
step(M,M.dir)
+
+// Ice that is used for, say, areas floating on water or similar.
+/turf/simulated/floor/outdoors/shelfice
+ name = "ice"
+ icon_state = "ice"
+ desc = "Looks slippery."
+ movement_cost = 4
diff --git a/code/modules/artifice/cursedform.dm b/code/modules/artifice/cursedform.dm
new file mode 100644
index 0000000000..17f8fbf618
--- /dev/null
+++ b/code/modules/artifice/cursedform.dm
@@ -0,0 +1,40 @@
+/obj/item/weapon/paper/carbon/cursedform
+ name = "Form - Inventory Requisition r10.7.1E"
+
+/obj/item/weapon/paper/carbon/cursedform/Initialize()
+ ..()
+ info = {"
Form - Inventory Requisition r10.7.1E
General Request Form
General
Name:
Department:
Departmental Rank:
Organization(If not Nanotrasen):
Date:
Requested Item(s):
Quantity:
Reason for request:
Is this replacement equipment?:
If `Yes`; above, specify equiment and reason for replacement:
Authorization
Authorizing Department:
Authorizing Dept. Head:
Contact and Delivery
EPv2 Address of requesting party(Do not leave blank):
Delivery location or department:
Nanotrasen Employee Identification Number:
Signature of Requester and Date
Authorizor`s Nanotrasen Employee Identification Number:
Authorizing Signature and Date(Include authorizing department`s stamp below)
Shipping Department Only
(Do not write below this line)
Nanotrasen Purchasing Approval Code:
Nanotrasen Employee Identification Number:
Receiving Shipping Employee:
Signature and Date
"}
+ info_links = {"
Form - Inventory Requisition r10.7.1E
General Request Form
General
Name: write
Department: write
Departmental Rank: write
Organization(If not Nanotrasen): write
Date: write
Requested Item(s): write
Quantity: write
Reason for request: write
Is this replacement equipment?: write
If `Yes` above, specify equiment and reason for replacement: write
Authorization
Authorizing Department: write
Authorizing Dept. Head: write
Contact and Delivery
EPv2 Address of requesting party(Do not leave blank): write
Delivery location or department: write
Nanotrasen Employee Identification Number: write
Signature of Requester and Date
write
Authorizor`s Nanotrasen Employee Identification Number: write
Authorizing Signature and Date(Include authorizing department`s stamp below)
write
Shipping Department Only
(Do not write below this line)
Nanotrasen Purchasing Approval Code: write
Nanotrasen Employee Identification Number: write
Receiving Shipping Employee: write
Signature and Date
write
write"}
+
+/obj/item/weapon/paper/carbon/cursedform/AltClick() // No fun.
+ return
+
+/obj/item/weapon/paper/carbon/cursedform/burnpaper(obj/item/weapon/flame/P, mob/user)
+ var/class = "warning"
+ var/datum/gender/TU = gender_datums[user.get_visible_gender()]
+
+ if(P.lit && !user.restrained())
+ if(istype(P, /obj/item/weapon/flame/lighter/zippo))
+ class = "rose"
+
+ user.visible_message("[user] holds \the [P] up to \the [src], it looks like [TU.hes] trying to burn it!", \
+ "You hold \the [P] up to \the [src], burning it slowly.")
+
+ if(do_after(user, 2 SECONDS, src) && P.lit)
+ user.visible_message("[user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \
+ "You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.")
+
+ if(user.get_inactive_hand() == src)
+ user.drop_from_inventory(src)
+
+ new /obj/effect/decal/cleanable/ash(src.loc)
+ qdel(src)
+
+ else
+ to_chat(user,"You must hold \the [P] steady to burn \the [src].")
+
+ if(isliving(user))
+ var/mob/living/L = user
+ L.visible_message("[L] convulses, the very letters of \the [src] searing themselves into their eyes!", \
+ "You convulse, the very letters of \the [src] searing themselves into your eyes!")
+ L.add_modifier(/datum/modifier/grievous_wounds, 10 MINUTES)
diff --git a/code/modules/artifice/telecube.dm b/code/modules/artifice/telecube.dm
new file mode 100644
index 0000000000..bb2af4b83d
--- /dev/null
+++ b/code/modules/artifice/telecube.dm
@@ -0,0 +1,236 @@
+/*
+ * Home of the telecube.
+ */
+
+/datum/category_item/catalogue/anomalous/precursor_a/telecube
+ name = "Quantomatically Entangled Digicube"
+
+ desc = "An enigmatic cube that appears superficially similar to a Positronic Cube. \
+ However, the similarities hopefully end there, as this device emits no sound during \
+ operation or observation. Its alloy composition is unknown, though it is incredibly \
+ dense, as it resists any and all forms of radiation.
\
+ Upon physical contact, however, the device will translocate the offending entity to a \
+ matching twin cube, generating no detectable radiation. This process occurs at speeds \
+ unmatched even by modern predictions of Bluespace technology, and with no visible power \
+ source."
+
+ value = CATALOGUER_REWARD_HARD
+
+// Standard one needs to be smacked onto another one to link together.
+/obj/item/weapon/telecube
+ name = "locus"
+ desc = "A strange metallic cube that pulses silently."
+ description_info = "Ctrl-Clicking on this object will attempt to activate its unique ability."
+ icon = 'icons/obj/props/telecube.dmi'
+ icon_state = "cube"
+ w_class = ITEMSIZE_SMALL
+ origin_tech = list(TECH_MATERIAL = 7, TECH_POWER = 6, TECH_BLUESPACE = 7, TECH_ANOMALY = 2, TECH_PRECURSOR = 2)
+
+ catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/telecube)
+
+ slowdown = 5
+
+ throw_range = 2
+
+ var/obj/item/weapon/telecube/mate = null
+
+ var/start_paired = FALSE
+ var/mirror_colors = FALSE
+
+ var/randomize_colors = FALSE
+
+ var/glow_color = "#FFFFFF"
+ var/image/glow = null
+ var/image/charge = null
+
+ var/shell_color = "#FFFFFF"
+ var/image/shell = null
+
+ var/cooldown_time = 30 SECONDS
+ var/last_teleport = 0
+
+// How far the cube will search for things to teleport. 0 = only contacting objects / mobs.
+ var/teleport_range = 0 // For all that is holy, do not change this unless you know what you're doing.
+
+ var/omniteleport = FALSE // Will this teleport anchored things too?
+
+/obj/item/weapon/telecube/Initialize()
+ . = ..()
+ START_PROCESSING(SSobj, src)
+ last_teleport = world.time
+
+ glow = image(icon = icon, icon_state = "[icon_state]-ready")
+ glow.plane = PLANE_LIGHTING_ABOVE
+ charge = image(icon = icon, icon_state = "[icon_state]-charging")
+ charge.plane = PLANE_LIGHTING_ABOVE
+ shell = image(icon = icon, icon_state = "[icon_state]")
+
+ if(teleport_range)
+ description_info += "
"
+ description_info += "Alt-Clicking on this object will utilize its second unique ability."
+
+ if(randomize_colors)
+ glow_color = rgb(rand(0, 255),rand(0, 255),rand(0, 255))
+ shell_color = rgb(rand(0, 255),rand(0, 255),rand(0, 255))
+
+ if(start_paired)
+ mate = new(src.loc)
+ if(mirror_colors)
+ mate.glow_color = shell_color
+ mate.shell_color = glow_color
+ else
+ mate.glow_color = glow_color
+ mate.shell_color = shell_color
+ mate.pair_cube(src)
+
+ glow.color = glow_color
+ charge.color = glow_color
+ shell.color = shell_color
+
+ return
+
+/obj/item/weapon/telecube/process()
+ ..()
+ update_icon()
+
+/obj/item/weapon/telecube/update_icon()
+ . = ..()
+ glow.color = glow_color
+ charge.color = glow_color
+ shell.color = shell_color
+
+ if(shell.color != initial(shell.color))
+ cut_overlay(shell)
+ add_overlay(shell)
+
+ if(world.time < (last_teleport + cooldown_time))
+ cut_overlay(charge)
+ cut_overlay(glow)
+ add_overlay(charge)
+ else
+ cut_overlay(glow)
+ cut_overlay(charge)
+ add_overlay(glow)
+
+/obj/item/weapon/telecube/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ if(mate)
+ var/turf/T = get_turf(mate)
+ mate.visible_message("\The [mate] collapses into itself!")
+ mate.mate = null
+ mate = null
+ explosion(T,1,3,7)
+
+ ..()
+
+/obj/item/weapon/telecube/proc/pair_cube(var/obj/item/weapon/telecube/M)
+ if(mate)
+ return 0
+ else
+ mate = M
+ update_icon()
+ return 1
+
+/obj/item/weapon/telecube/proc/teleport_to_mate(var/atom/movable/A, var/areaporting = FALSE)
+ . = FALSE
+
+ if(!A)
+ return .
+
+ if(A == src || A == mate)
+ A.visible_message("\The [A] distorts and fades, before popping back into existence.")
+ return .
+
+ var/mob/living/L = src.loc
+
+ if(istype(L))
+ L.drop_from_inventory(src)
+ forceMove(get_turf(src))
+
+ if(world.time < (last_teleport + cooldown_time))
+ return .
+
+ if((A.anchored && !omniteleport) || !mate)
+ A.visible_message("\The [A] distorts for a moment, before reforming in the same position.")
+ return .
+
+ var/turf/TLocate = get_turf(mate)
+
+ var/turf/T1 = get_turf(locate(TLocate.x + (A.x - x), TLocate.y + (A.y - y), TLocate.z))
+
+ if(T1)
+ A.visible_message("\The [A] fades out of existence.")
+ A.forceMove(T1)
+ . = TRUE
+ A.visible_message("\The [A] fades into existence.")
+ else
+ return .
+
+ if(teleport_range && !areaporting)
+ for(var/atom/movable/M in orange(teleport_range, A))
+ teleport_to_mate(M, TRUE)
+
+/obj/item/weapon/telecube/proc/swap_with_mate()
+ . = FALSE
+
+ if(!mate || !teleport_range)
+ return .
+
+ var/list/objects_near_me = range(teleport_range, get_turf(src))
+ var/list/objects_near_mate = range(teleport_range, get_turf(mate))
+
+ for(var/atom/movable/M in objects_near_me)
+ teleport_to_mate(M, TRUE)
+
+ for(var/atom/movable/M1 in objects_near_mate)
+ mate.teleport_to_mate(M1, TRUE)
+
+ . = TRUE
+ return .
+
+/obj/item/weapon/telecube/CtrlClick(mob/user)
+ if(Adjacent(user))
+ if(teleport_to_mate(user))
+ last_teleport = world.time
+ return
+
+/obj/item/weapon/telecube/AltClick(mob/user)
+ if(Adjacent(user))
+ if(swap_with_mate())
+ last_teleport = world.time
+ mate.last_teleport = world.time
+ return
+
+/obj/item/weapon/telecube/Bump(atom/movable/AM)
+ if(teleport_to_mate(AM))
+ last_teleport = world.time
+ . = ..()
+
+/obj/item/weapon/telecube/Bumped(atom/movable/M as mob|obj)
+ if(teleport_to_mate(M))
+ last_teleport = world.time
+ . = ..()
+
+// Subtypes
+
+/obj/item/weapon/telecube/mated
+ start_paired = TRUE
+
+/obj/item/weapon/telecube/randomized
+ randomize_colors = TRUE
+
+/obj/item/weapon/telecube/randomized/mated
+ start_paired = TRUE
+
+/obj/item/weapon/telecube/precursor
+ glow_color = "#FF1D8E"
+ shell_color = "#2F1B26"
+
+/obj/item/weapon/telecube/precursor/mated
+ start_paired = TRUE
+
+/obj/item/weapon/telecube/precursor/mated/zone
+ teleport_range = 2
+
+/obj/item/weapon/telecube/precursor/mated/mirrorcolor
+ mirror_colors = TRUE
diff --git a/code/modules/catalogue/cataloguer.dm b/code/modules/catalogue/cataloguer.dm
index 60e86eadee..f1c5756443 100644
--- a/code/modules/catalogue/cataloguer.dm
+++ b/code/modules/catalogue/cataloguer.dm
@@ -312,3 +312,15 @@ GLOBAL_LIST_EMPTY(all_cataloguers)
interact(usr) // So it refreshes the window.
return 1
+/obj/item/device/cataloguer/attackby(obj/item/weapon/W, mob/user)
+ if(istype(W, /obj/item/weapon/card/id) && !busy)
+ busy = TRUE
+ var/obj/item/weapon/card/id/ID = W
+ if(points_stored)
+ ID.survey_points += points_stored
+ points_stored = 0
+ to_chat(user, "You swipe the id over \the [src].")
+ else
+ to_chat(user, "\The [src] has no points available.")
+ busy = FALSE
+ return ..()
diff --git a/code/modules/catalogue/rewards/construction.dm b/code/modules/catalogue/rewards/construction.dm
deleted file mode 100644
index 8bfca1f79d..0000000000
--- a/code/modules/catalogue/rewards/construction.dm
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef T_BOARD
-#error T_BOARD macro is not defined but we need it!
-#endif
-
-/obj/item/weapon/circuitboard/exploration_equipment_vendor
- name = T_BOARD("Exploration Equipment Vendor")
- board_type = new /datum/frame/frame_types/machine
- build_path = /obj/machinery/equipment_vendor/exploration
- origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2)
- req_components = list(
- /obj/item/weapon/stock_parts/console_screen = 1,
- /obj/item/weapon/stock_parts/matter_bin = 3)
diff --git a/code/modules/catalogue/rewards/equipment_vendor.dm b/code/modules/catalogue/rewards/equipment_vendor.dm
deleted file mode 100644
index 96b636b8be..0000000000
--- a/code/modules/catalogue/rewards/equipment_vendor.dm
+++ /dev/null
@@ -1,177 +0,0 @@
-/**********************Exploration Equipment Vendor**************************/
-
-/obj/machinery/equipment_vendor/exploration
- name = "exploration equipment vendor"
- desc = "An equipment vendor for explorers, points collected with cataloguers can be spent here."
- icon = 'icons/obj/machines/mining_machines_vr.dmi'
- icon_state = "exploration"
- density = TRUE
- anchored = TRUE
- circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor
- var/icon_deny = "exploration-deny"
- var/icon_vend = "exploration-vend"
- var/obj/item/device/cataloguer/inserted_cataloguer
- var/list/prize_list = list(
- new /datum/data/exploration_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1),
- new /datum/data/exploration_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10),
- new /datum/data/exploration_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30),
- new /datum/data/exploration_equipment("GPS Device", /obj/item/device/gps/explorer, 10),
- new /datum/data/exploration_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10),
- new /datum/data/exploration_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10),
- new /datum/data/exploration_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15),
- new /datum/data/exploration_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20),
- new /datum/data/exploration_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90),
- new /datum/data/exploration_equipment("Plush Toy", /obj/random/plushie, 30),
- new /datum/data/exploration_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50),
- new /datum/data/exploration_equipment("Point Transfer Card", /obj/item/weapon/card/exploration_point_card, 50),
- new /datum/data/exploration_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 50),
- new /datum/data/exploration_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50),
- new /datum/data/exploration_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50),
- new /datum/data/exploration_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50),
- new /datum/data/exploration_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50),
- new /datum/data/exploration_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100),
- new /datum/data/exploration_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100),
- new /datum/data/exploration_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120),
- new /datum/data/exploration_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100),
- new /datum/data/exploration_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250),
- new /datum/data/exploration_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310),
- new /datum/data/exploration_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10),
- new /datum/data/exploration_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station, 100),
- new /datum/data/exploration_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 150),
- new /datum/data/exploration_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50),
- new /datum/data/exploration_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100),
- new /datum/data/exploration_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750)
- )
-
-/datum/data/exploration_equipment
- var/equipment_name = "generic"
- var/equipment_path = null
- var/cost = 0
-
-/datum/data/exploration_equipment/New(name, path, cost)
- src.equipment_name = name
- src.equipment_path = path
- src.cost = cost
-
-/obj/machinery/equipment_vendor/exploration/power_change()
- var/old_stat = stat
- ..()
- if(old_stat != stat)
- update_icon()
- if(inserted_cataloguer && !powered())
- visible_message("The cataloguer slot indicator light flickers on \the [src] as it spits out the device before powering down.")
- inserted_cataloguer.forceMove(get_turf(src))
-
-/obj/machinery/equipment_vendor/exploration/update_icon()
- if(panel_open)
- icon_state = "[initial(icon_state)]-open"
- else if(powered())
- icon_state = initial(icon_state)
- else
- icon_state = "[initial(icon_state)]-off"
-
-/obj/machinery/equipment_vendor/exploration/attack_hand(mob/user)
- if(..())
- return
- interact(user)
-
-/obj/machinery/equipment_vendor/exploration/attack_ghost(mob/user)
- interact(user)
-
-/obj/machinery/equipment_vendor/exploration/interact(mob/user)
- user.set_machine(src)
-
- var/dat
- dat +=""
- if(istype(inserted_cataloguer))
- dat += "You have [inserted_cataloguer.points_stored] exploration points collected.
Eject Cataloguer."
- else
- dat += "No Cataloguer inserted.
Insert Cataloguer."
- dat += "
"
- dat += "
Equipment point cost list:
"
- for(var/datum/data/exploration_equipment/prize in prize_list)
- dat += "| [prize.equipment_name] | [prize.cost] | Purchase |
"
- dat += "
"
- var/datum/browser/popup = new(user, "miningvendor", "Exploration Equipment Vendor", 400, 600)
- popup.set_content(dat)
- popup.open()
-
-/obj/machinery/equipment_vendor/exploration/Topic(href, href_list)
- if(..())
- return 1
-
- if(href_list["choice"])
- if(istype(inserted_cataloguer))
- if(href_list["choice"] == "eject")
- to_chat(usr, "You eject the ID from [src]'s card slot.")
- usr.put_in_hands(inserted_cataloguer)
- inserted_cataloguer = null
- else if(href_list["choice"] == "insert")
- var/obj/item/device/cataloguer/C = usr.get_active_hand()
- if(istype(C) && !inserted_cataloguer && usr.unEquip(C))
- C.forceMove(src)
- inserted_cataloguer = C
- interact(usr)
- to_chat(usr, "You insert the ID into [src]'s card slot.")
- else
- to_chat(usr, "No valid ID.")
- flick(icon_deny, src)
-
- if(href_list["purchase"])
- if(istype(inserted_cataloguer))
- var/datum/data/exploration_equipment/prize = locate(href_list["purchase"])
- if (!prize || !(prize in prize_list))
- to_chat(usr, "Error: Invalid choice!")
- flick(icon_deny, src)
- return
- if(prize.cost > inserted_cataloguer.points_stored)
- to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!")
- flick(icon_deny, src)
- else
- inserted_cataloguer.points_stored -= prize.cost
- to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!")
- flick(icon_vend, src)
- new prize.equipment_path(drop_location())
- else
- to_chat(usr, "Error: Please insert a valid ID!")
- flick(icon_deny, src)
- updateUsrDialog()
-
-/obj/machinery/equipment_vendor/exploration/attackby(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, I))
- updateUsrDialog()
- return
- if(default_part_replacement(user, I))
- return
- if(default_deconstruction_crowbar(user, I))
- return
- if(istype(I,/obj/item/device/cataloguer))
- if(!powered())
- return
- else if(!inserted_cataloguer && user.unEquip(I))
- I.forceMove(src)
- inserted_cataloguer = I
- interact(user)
- return
- ..()
-
-/obj/machinery/equipment_vendor/exploration/dismantle()
- if(inserted_cataloguer)
- inserted_cataloguer.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it.
- . = ..()
-
-/obj/machinery/equipment_vendor/exploration/proc/new_prize(var/name, var/path, var/cost) // Generic proc for adding new entries. Good for abusing for FUN and PROFIT.
- if(!cost)
- cost = 100
- if(!path)
- path = /obj/item/stack/marker_beacon
- if(!name)
- name = "Generic Entry"
- prize_list += new /datum/data/exploration_equipment(name, path, cost)
-
-/obj/machinery/equipment_vendor/exploration/ex_act(severity, target)
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
- if(prob(50 / severity) && severity < 3)
- qdel(src)
diff --git a/code/modules/catalogue/rewards/exp_point_items.dm b/code/modules/catalogue/rewards/exp_point_items.dm
deleted file mode 100644
index 47e066763b..0000000000
--- a/code/modules/catalogue/rewards/exp_point_items.dm
+++ /dev/null
@@ -1,23 +0,0 @@
-/obj/item/weapon/card/exploration_point_card
- name = "exploration point card"
- desc = "A small card preloaded with exploration points. Swipe your Cataloguer over it to transfer the points, then discard."
- icon_state = "data"
- var/points = 50
-
-/obj/item/weapon/card/exploration_point_card/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/device/cataloguer))
- if(points)
- var/obj/item/device/cataloguer/C = I
- C.points_stored += points
- to_chat(user, "You transfer [points] points to [C].")
- points = 0
- else
- to_chat(user, "There's no points left on [src].")
- ..()
-
-/obj/item/weapon/card/exploration_point_card/examine(mob/user)
- ..(user)
- to_chat(user, "There's [points] points on the card.")
-
-/obj/item/weapon/card/exploration_point_card/can_catalogue(mob/user)
- return FALSE
\ No newline at end of file
diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm
index 3986f0dfd8..0f1ab31c6e 100644
--- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm
@@ -40,11 +40,11 @@
allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective","Explorer","Pathfinder", "Blueshield Guard")
/datum/gear/accessory/brown_vest
- display_name = "webbing, brown"
+ display_name = "webbing, brown (Eng, Sec, Med, Exploration, Miner)"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard")
/datum/gear/accessory/black_vest
- display_name = "webbing, black"
+ display_name = "webbing, black (Eng, Sec, Med, Exploration, Miner)"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard")
/datum/gear/accessory/white_vest
@@ -52,11 +52,11 @@
allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic")
/datum/gear/accessory/brown_drop_pouches
- display_name = "drop pouches, brown"
+ display_name = "drop pouches, brown (Eng, Sec, Med, Exploration, Miner)"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard")
/datum/gear/accessory/black_drop_pouches
- display_name = "drop pouches, black"
+ display_name = "drop pouches, black (Eng, Sec, Med, Exploration, Miner)"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner", "Blueshield Guard")
/datum/gear/accessory/white_drop_pouches
diff --git a/code/modules/client/preference_setup/vore/06_vantag.dm b/code/modules/client/preference_setup/vore/06_vantag.dm
index 65bc66a495..c65c379bf2 100644
--- a/code/modules/client/preference_setup/vore/06_vantag.dm
+++ b/code/modules/client/preference_setup/vore/06_vantag.dm
@@ -27,7 +27,7 @@
/datum/category_item/player_setup_item/vore/vantag/content(var/mob/user)
. += "
"
- . += "Event Volunteer: [pref.vantag_volunteer ? "Yes" : "No"]
"
+ . += "Event Volunteer: [pref.vantag_volunteer ? "Yes" : "No"]
"
. += "Event Pref: [vantag_choices_list[pref.vantag_preference]]
"
/datum/category_item/player_setup_item/vore/vantag/OnTopic(var/href, var/list/href_list, var/mob/user)
diff --git a/code/modules/client/preference_setup/vore/09_misc.dm b/code/modules/client/preference_setup/vore/09_misc.dm
index 951e469d8d..2911c8a10d 100644
--- a/code/modules/client/preference_setup/vore/09_misc.dm
+++ b/code/modules/client/preference_setup/vore/09_misc.dm
@@ -25,7 +25,7 @@
/datum/category_item/player_setup_item/vore/misc/content(var/mob/user)
. += "
"
. += "Appear in Character Directory: [pref.show_in_directory ? "Yes" : "No"]
"
- . += "Sensor Preferences: [sensorpreflist[pref.sensorpref]]
" //TFF 5/8/19 - Allow selection of sensor settings from off, binary, vitals, tracking, or random
+ . += "Suit Sensors Preference: [sensorpreflist[pref.sensorpref]]
" //TFF 5/8/19 - Allow selection of sensor settings from off, binary, vitals, tracking, or random
/datum/category_item/player_setup_item/vore/misc/OnTopic(var/href, var/list/href_list, var/mob/user)
if(href_list["toggle_show_in_directory"])
diff --git a/code/modules/clothing/clothing_vr.dm b/code/modules/clothing/clothing_vr.dm
index 9c04fc9841..b6e387c9bf 100644
--- a/code/modules/clothing/clothing_vr.dm
+++ b/code/modules/clothing/clothing_vr.dm
@@ -126,7 +126,7 @@
return ..()
// Taur suits need to be shifted so its centered on their taur half.
-/obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0)
+/obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0,var/icon/clip_mask)
var/image/standing = ..()
if(taurized) //Special snowflake var on suits
standing.pixel_x = -16
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index b706e71e9d..a9232aa65c 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -219,7 +219,7 @@
/obj/item/clothing/head/psy_crown
name = "broken crown"
desc = "A crown-of-thorns with a missing gem."
- var/tension_threshold = 150
+ var/tension_threshold = 125
var/cooldown = null // world.time of when this was last triggered.
var/cooldown_duration = 3 MINUTES // How long the cooldown should be.
var/flavor_equip = null // Message displayed to someone who puts this on their head. Drones don't get a message.
@@ -273,3 +273,17 @@
/obj/item/clothing/head/psy_crown/wrath/activate_ability(var/mob/living/wearer)
..()
wearer.add_modifier(/datum/modifier/berserk, 30 SECONDS)
+
+/obj/item/clothing/head/psy_crown/gluttony
+ name = "green crown"
+ desc = "A crown-of-thorns set with a green gemstone that seems to glow unnaturally. It feels rather disturbing to touch."
+ description_info = "This has a chance to cause the wearer to become extremely durable, but hungry when in extreme danger."
+ icon_state = "gluttonycrown"
+ flavor_equip = "You feel a bit hungrier after putting on this crown."
+ flavor_unequip = "You feel sated after removing the crown."
+ flavor_drop = "You feel much more sated after letting go of the crown."
+ flavor_activate = "An otherworldly feeling seems to enter your mind, and it drives your mind into gluttony!"
+
+/obj/item/clothing/head/psy_crown/gluttony/activate_ability(var/mob/living/wearer)
+ ..()
+ wearer.add_modifier(/datum/modifier/gluttonyregeneration, 45 SECONDS)
diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm
index 83cf2e3049..0c1cfee9ca 100644
--- a/code/modules/clothing/under/accessories/storage.dm
+++ b/code/modules/clothing/under/accessories/storage.dm
@@ -9,12 +9,15 @@
var/obj/item/weapon/storage/internal/hold
w_class = ITEMSIZE_NORMAL
on_rolled = list("down" = "none")
+ var/hide_on_roll = FALSE
/obj/item/clothing/accessory/storage/New()
..()
hold = new/obj/item/weapon/storage/internal(src)
hold.max_storage_space = slots * 2
hold.max_w_class = ITEMSIZE_SMALL
+ if (!hide_on_roll)
+ on_rolled["down"] = icon_state
/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob)
if (has_suit) //if we are part of a suit
diff --git a/code/modules/clothing/under/accessories/torch.dm b/code/modules/clothing/under/accessories/torch.dm
index c7fe853808..7cdec72747 100644
--- a/code/modules/clothing/under/accessories/torch.dm
+++ b/code/modules/clothing/under/accessories/torch.dm
@@ -310,9 +310,9 @@ department tags
desc = "Insignia denoting assignment to the command department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/command/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the command department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/command/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the command department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/engineering
@@ -328,9 +328,9 @@ department tags
desc = "Insignia denoting assignment to the engineering department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/engineering/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the engineering department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/engineering/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the engineering department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/security
@@ -346,9 +346,9 @@ department tags
desc = "Insignia denoting assignment to the security department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/security/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the security department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/security/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the security department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/medical
@@ -364,9 +364,9 @@ department tags
desc = "Insignia denoting assignment to the medical department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/medical/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the medical department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/medical/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the medical department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/supply
@@ -382,9 +382,9 @@ department tags
desc = "Insignia denoting assignment to the supply department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/supply/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the supply department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/supply/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the supply department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/service
@@ -400,9 +400,9 @@ department tags
desc = "Insignia denoting assignment to the service department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/service/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the service department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/service/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the service department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/exploration
@@ -418,9 +418,9 @@ department tags
desc = "Insignia denoting assignment to the exploration department. These fit Fleet uniforms."
on_rolled = list("rolled" = "dept_fleet_sleeves", "down" = "none")
-/obj/item/clothing/accessory/solgov/department/exploration/army
- icon_state = "dept_army"
- desc = "Insignia denoting assignment to the exploration department. These fit Army uniforms."
+/obj/item/clothing/accessory/solgov/department/exploration/marine
+ icon_state = "dept_marine"
+ desc = "Insignia denoting assignment to the exploration department. These fit marine uniforms."
on_rolled = list("down" = "none")
/obj/item/clothing/accessory/solgov/department/research
@@ -611,103 +611,103 @@ ranks - fleet
/**************
ranks - marines
**************/
-/obj/item/clothing/accessory/solgov/rank/army
- name = "army ranks"
+/obj/item/clothing/accessory/solgov/rank/marine
+ name = "marine ranks"
desc = "Insignia denoting marine rank of some kind. These appear blank."
- icon_state = "armyrank_enlisted"
+ icon_state = "marinerank_enlisted"
on_rolled = list("down" = "none")
-/obj/item/clothing/accessory/solgov/rank/army/enlisted
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted
name = "ranks (E-1 private)"
desc = "Insignia denoting the rank of Private."
- icon_state = "armyrank_enlisted"
+ icon_state = "marinerank_enlisted"
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e2
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e2
name = "ranks (E-2 private second class)"
desc = "Insignia denoting the rank of Private Second Class."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e3
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e3
name = "ranks (E-3 private first class)"
desc = "Insignia denoting the rank of Private First Class."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e4
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e4
name = "ranks (E-4 corporal)"
desc = "Insignia denoting the rank of Corporal."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e5
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e5
name = "ranks (E-5 sergeant)"
desc = "Insignia denoting the rank of Sergeant."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e6
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e6
name = "ranks (E-6 staff sergeant)"
desc = "Insignia denoting the rank of Staff Sergeant."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e7
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e7
name = "ranks (E-7 sergeant first class)"
desc = "Insignia denoting the rank of Sergeant First Class."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e8
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e8
name = "ranks (E-8 master sergeant)"
desc = "Insignia denoting the rank of Master Sergeant."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e8_alt
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e8_alt
name = "ranks (E-8 first sergeant)"
desc = "Insignia denoting the rank of First Sergeant."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e9
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e9
name = "ranks (E-9 sergeant major)"
desc = "Insignia denoting the rank of Sergeant Major."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e9_alt1
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e9_alt1
name = "ranks (E-9 command sergeant major)"
desc = "Insignia denoting the rank of Command Sergeant Major."
-/obj/item/clothing/accessory/solgov/rank/army/enlisted/e9_alt2
- name = "ranks (E-9 sergeant major of the Army)"
- desc = "Insignia denoting the rank of Sergeant Major of the Army."
+/obj/item/clothing/accessory/solgov/rank/marine/enlisted/e9_alt2
+ name = "ranks (E-9 sergeant major of the marine)"
+ desc = "Insignia denoting the rank of Sergeant Major of the marine."
-/obj/item/clothing/accessory/solgov/rank/army/officer
+/obj/item/clothing/accessory/solgov/rank/marine/officer
name = "ranks (O-1 second lieutenant)"
desc = "Insignia denoting the rank of Second Lieutenant."
- icon_state = "armyrank_officer"
+ icon_state = "marinerank_officer"
-/obj/item/clothing/accessory/solgov/rank/army/officer/o2
+/obj/item/clothing/accessory/solgov/rank/marine/officer/o2
name = "ranks (O-2 first lieutenant)"
desc = "Insignia denoting the rank of First Lieutenant."
-/obj/item/clothing/accessory/solgov/rank/army/officer/o3
+/obj/item/clothing/accessory/solgov/rank/marine/officer/o3
name = "ranks (O-3 captain)"
desc = "Insignia denoting the rank of Captain."
-/obj/item/clothing/accessory/solgov/rank/army/officer/o4
+/obj/item/clothing/accessory/solgov/rank/marine/officer/o4
name = "ranks (O-4 major)"
desc = "Insignia denoting the rank of Major."
-/obj/item/clothing/accessory/solgov/rank/army/officer/o5
+/obj/item/clothing/accessory/solgov/rank/marine/officer/o5
name = "ranks (O-5 lieutenant colonel)"
desc = "Insignia denoting the rank of Lieutenant Colonel."
-/obj/item/clothing/accessory/solgov/rank/army/officer/o6
+/obj/item/clothing/accessory/solgov/rank/marine/officer/o6
name = "ranks (O-6 colonel)"
desc = "Insignia denoting the rank of Colonel."
-/obj/item/clothing/accessory/solgov/rank/army/flag
+/obj/item/clothing/accessory/solgov/rank/marine/flag
name = "ranks (O-7 brigadier general)"
desc = "Insignia denoting the rank of Brigadier General."
- icon_state = "armyrank_command"
+ icon_state = "marinerank_command"
-/obj/item/clothing/accessory/solgov/rank/army/flag/o8
+/obj/item/clothing/accessory/solgov/rank/marine/flag/o8
name = "ranks (O-8 major general)"
desc = "Insignia denoting the rank of Major General."
-/obj/item/clothing/accessory/solgov/rank/army/flag/o9
+/obj/item/clothing/accessory/solgov/rank/marine/flag/o9
name = "ranks (O-9 lieutenant general)"
desc = "Insignia denoting the rank of lieutenant general."
-/obj/item/clothing/accessory/solgov/rank/army/flag/o10
+/obj/item/clothing/accessory/solgov/rank/marine/flag/o10
name = "ranks (O-10 general)"
desc = "Insignia denoting the rank of General."
-/obj/item/clothing/accessory/solgov/rank/army/flag/o10_alt
+/obj/item/clothing/accessory/solgov/rank/marine/flag/o10_alt
name = "ranks (O-10 field marshal)"
desc = "Insignia denoting the rank of Field Marshal."
diff --git a/code/modules/clothing/under/solgov.dm b/code/modules/clothing/under/solgov.dm
index 39109c480a..0859cdf1e4 100644
--- a/code/modules/clothing/under/solgov.dm
+++ b/code/modules/clothing/under/solgov.dm
@@ -1,7 +1,18 @@
//SolGov Uniforms
+//Master
+/obj/item/clothing/under/solgov
+ name = "master solgov uniform"
+ desc = "You shouldn't be seeing this."
+ icon = 'icons/obj/clothing/uniforms_solgov.dmi'
+ rolled_down = 0
+ rolled_sleeves = 0
+ item_icons = list(slot_w_uniform_str = 'icons/mob/uniform_solgov.dmi')
+ armor = list(melee = 5, bullet = 0, laser = 5, energy = 5, bomb = 0, bio = 5, rad = 5)
+ siemens_coefficient = 0.8
+
//PT
-/obj/item/clothing/under/pt
+/obj/item/clothing/under/solgov/pt
name = "pt uniform"
desc = "Shorts! Shirt! Miami! Sexy!"
icon_state = "miami"
@@ -10,19 +21,19 @@
siemens_coefficient = 0.9
body_parts_covered = UPPER_TORSO|LOWER_TORSO
-/obj/item/clothing/under/pt/sifguard
+/obj/item/clothing/under/solgov/pt/sifguard
name = "\improper SifGuard pt uniform"
desc = "A baggy shirt bearing the seal of the Sif Defense Force and some dorky looking blue shorts."
icon_state = "expeditionpt"
worn_state = "expeditionpt"
-/obj/item/clothing/under/pt/fleet
+/obj/item/clothing/under/solgov/pt/fleet
name = "fleet pt uniform"
desc = "A pair of black shorts and two tank tops, seems impractical. Looks good though."
icon_state = "fleetpt"
worn_state = "fleetpt"
-/obj/item/clothing/under/pt/marine
+/obj/item/clothing/under/solgov/pt/marine
name = "marine pt uniform"
desc = "Does NOT leave much to the imagination."
icon_state = "marinept"
@@ -53,63 +64,62 @@
worn_state = "greyutility"
//Here's the real ones
-/obj/item/clothing/under/utility/sifguard
+/obj/item/clothing/under/solgov/utility/sifguard
name = "\improper SifGuard uniform"
desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim."
icon_state = "blackutility_crew"
worn_state = "blackutility_crew"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 10)
-/obj/item/clothing/under/utility/sifguard/medical
- name = "\improper SifGuard medical uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and blue blazes."
- icon_state = "blackutility_med"
- worn_state = "blackutility_med"
+/obj/item/clothing/under/solgov/utility/sifguard/command
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command)
-/obj/item/clothing/under/utility/sifguard/medical/command
- name = "\improper SifGuard medical command uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and blue blazes."
- icon_state = "blackutility_medcom"
- worn_state = "blackutility_medcom"
+/obj/item/clothing/under/solgov/utility/sifguard/engineering
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering)
-/obj/item/clothing/under/utility/sifguard/engineering
- name = "\improper SifGuard engineering uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and organge blazes."
- icon_state = "blackutility_eng"
- worn_state = "blackutility_eng"
+/obj/item/clothing/under/solgov/utility/sifguard/security
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security)
-/obj/item/clothing/under/utility/sifguard/engineering/command
- name = "\improper SifGuard engineering command uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and organge blazes."
- icon_state = "blackutility_engcom"
- worn_state = "blackutility_engcom"
+/obj/item/clothing/under/solgov/utility/sifguard/medical
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical)
-/obj/item/clothing/under/utility/sifguard/supply
- name = "\improper SifGuard supply uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and brown blazes."
- icon_state = "blackutility_sup"
- worn_state = "blackutility_sup"
+/obj/item/clothing/under/solgov/utility/sifguard/supply
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply)
-/obj/item/clothing/under/utility/sifguard/security
- name = "\improper SifGuard security uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has silver trim and red blazes."
- icon_state = "blackutility_sec"
- worn_state = "blackutility_sec"
+/obj/item/clothing/under/solgov/utility/sifguard/exploration
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration)
-/obj/item/clothing/under/utility/sifguard/security/command
- name = "\improper SifGuard security command uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and red blazes."
- icon_state = "blackutility_seccom"
- worn_state = "blackutility_seccom"
+/obj/item/clothing/under/solgov/utility/sifguard/research
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research)
-/obj/item/clothing/under/utility/sifguard/command
- name = "\improper SifGuard command uniform"
- desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim and gold blazes."
+/obj/item/clothing/under/solgov/utility/sifguard/officer
+ name = "\improper Sifuard officer's uniform"
+ desc = "The utility uniform of the Sif Defense Force, made from biohazard resistant material. This one has gold trim."
icon_state = "blackutility_com"
worn_state = "blackutility_com"
+/obj/item/clothing/under/solgov/utility/sifguard/officer/command
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command)
-/obj/item/clothing/under/utility/fleet
+/obj/item/clothing/under/solgov/utility/sifguard/officer/engineering
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering)
+
+/obj/item/clothing/under/solgov/utility/sifguard/officer/security
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security)
+
+/obj/item/clothing/under/solgov/utility/sifguard/officer/medical
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical)
+
+/obj/item/clothing/under/solgov/utility/sifguard/officer/supply
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply)
+
+/obj/item/clothing/under/solgov/utility/sifguard/officer/exploration
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration)
+
+/obj/item/clothing/under/solgov/utility/sifguard/officer/research
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research)
+
+/obj/item/clothing/under/solgov/utility/fleet
name = "fleet coveralls"
desc = "The utility uniform of the SCG Fleet, made from an insulated material."
icon_state = "navyutility"
@@ -117,116 +127,96 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 10, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.7
-/obj/item/clothing/under/utility/fleet/medical
- name = "fleet medical coveralls"
- desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has blue cuffs."
- icon_state = "navyutility_med"
- worn_state = "navyutility_med"
+/obj/item/clothing/under/solgov/utility/fleet/command
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/fleet)
-/obj/item/clothing/under/utility/fleet/engineering
- name = "fleet engineering coveralls"
- desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has orange cuffs."
- icon_state = "navyutility_eng"
- worn_state = "navyutility_eng"
+/obj/item/clothing/under/solgov/utility/fleet/command/pilot
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/specialty/pilot)
-/obj/item/clothing/under/utility/fleet/supply
- name = "fleet supply coveralls"
- desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has brown cuffs."
- icon_state = "navyutility_sup"
- worn_state = "navyutility_sup"
+/obj/item/clothing/under/solgov/utility/fleet/engineering
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/fleet)
-/obj/item/clothing/under/utility/fleet/security
- name = "fleet security coveralls"
- desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has red cuffs."
- icon_state = "navyutility_sec"
- worn_state = "navyutility_sec"
+/obj/item/clothing/under/solgov/utility/fleet/security
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/fleet)
-/obj/item/clothing/under/utility/fleet/command
- name = "fleet command coveralls"
- desc = "The utility uniform of the SCG Fleet, made from an insulated material. This one has gold cuffs."
- icon_state = "navyutility_com"
- worn_state = "navyutility_com"
+/obj/item/clothing/under/solgov/utility/fleet/medical
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/fleet)
+
+/obj/item/clothing/under/solgov/utility/fleet/supply
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/fleet)
+
+/obj/item/clothing/under/solgov/utility/fleet/exploration
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/fleet)
-/obj/item/clothing/under/utility/marine
+/obj/item/clothing/under/solgov/utility/marine
name = "marine fatigues"
desc = "The utility uniform of the SCG Marine Corps, made from durable material."
icon_state = "greyutility"
worn_state = "greyutility"
armor = list(melee = 10, bullet = 0, laser = 10,energy = 0, bomb = 0, bio = 0, rad = 0)
-/obj/item/clothing/under/utility/marine/green
+/obj/item/clothing/under/solgov/utility/marine/command
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/marine)
+
+/obj/item/clothing/under/solgov/utility/marine/engineering
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/marine)
+
+/obj/item/clothing/under/solgov/utility/marine/security
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/marine)
+
+/obj/item/clothing/under/solgov/utility/marine/medical
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/marine)
+
+/obj/item/clothing/under/solgov/utility/marine/supply
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/marine)
+
+/obj/item/clothing/under/solgov/utility/marine/exploration
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/marine)
+
+/obj/item/clothing/under/solgov/utility/marine/green
name = "green fatigues"
desc = "A green version of the SCG marine utility uniform, made from durable material."
icon_state = "greenutility"
worn_state = "greenutility"
-/obj/item/clothing/under/utility/marine/tan
+/obj/item/clothing/under/solgov/utility/marine/tan
name = "tan fatigues"
desc = "A tan version of the SCG marine utility uniform, made from durable material."
icon_state = "tanutility"
worn_state = "tanutility"
-/obj/item/clothing/under/utility/marine/medical
- name = "marine medical fatigues"
- desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has blue markings."
- icon_state = "greyutility_med"
- worn_state = "greyutility_med"
-
-/obj/item/clothing/under/utility/marine/engineering
- name = "marine engineering fatigues"
- desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has orange markings."
- icon_state = "greyutility_eng"
- worn_state = "greyutility_eng"
-
-/obj/item/clothing/under/utility/marine/supply
- name = "marine supply fatigues"
- desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has brown markings."
- icon_state = "greyutility_sup"
- worn_state = "greyutility_sup"
-
-/obj/item/clothing/under/utility/marine/security
- name = "marine security fatigues"
- desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has red markings."
- icon_state = "greyutility_sec"
- worn_state = "greyutility_sec"
-
-/obj/item/clothing/under/utility/marine/command
- name = "marine command coveralls"
- desc = "The utility uniform of the SCG Marine Corps, made from durable material. This one has gold markings."
- icon_state = "greyutility_com"
- worn_state = "greyutility_com"
-
//Service
-/obj/item/clothing/under/service
+/obj/item/clothing/under/solgov/service
name = "service uniform"
desc = "A service uniform of some kind."
icon_state = "whiteservice"
worn_state = "whiteservice"
- armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ armor = list(melee = 5, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 5, rad = 0)
siemens_coefficient = 0.9
-/obj/item/clothing/under/service/fleet
+/obj/item/clothing/under/solgov/service/fleet
name = "fleet service uniform"
desc = "The service uniform of the SCG Fleet, made from immaculate white fabric."
icon_state = "whiteservice"
worn_state = "whiteservice"
-/obj/item/clothing/under/service/marine
+/obj/item/clothing/under/solgov/service/marine
name = "marine service uniform"
desc = "The service uniform of the SCG Marine Corps. Slimming."
icon_state = "greenservice"
worn_state = "greenservice"
-/obj/item/clothing/under/service/marine/command
+/obj/item/clothing/under/solgov/service/marine/command
name = "marine command service uniform"
desc = "The service uniform of the SCG Marine Corps. Slimming and stylish."
icon_state = "greenservice_com"
worn_state = "greenservice_com"
//Dress
-/obj/item/clothing/under/mildress
+
+/obj/item/clothing/under/solgov/mildress
name = "dress uniform"
desc = "A dress uniform of some kind."
icon_state = "greydress"
@@ -234,25 +224,71 @@
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.9
-/obj/item/clothing/under/mildress/sifguard
+/obj/item/clothing/under/solgov/mildress/sifguard
name = "\improper SifGuard dress uniform"
desc = "The dress uniform of the Sif Defense Force in silver trim."
- icon_state = "greydress"
- worn_state = "greydress"
-/obj/item/clothing/under/mildress/sifguard/command
+/obj/item/clothing/under/solgov/mildress/sifguard/command
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/engineering
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/security
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/medical
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/supply
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/service
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/service/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/exploration
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/research
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer
name = "\improper SifGuard command dress uniform"
desc = "The dress uniform of the Sif Defense Force in gold trim."
icon_state = "greydress_com"
worn_state = "greydress_com"
-/obj/item/clothing/under/mildress/marine
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/command
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/command/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/engineering
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/engineering/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/security
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/security/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/medical
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/medical/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/supply
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/supply/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/service
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/service/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/exploration
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/exploration/service)
+
+/obj/item/clothing/under/solgov/mildress/sifguard/officer/research
+ starting_accessories = list(/obj/item/clothing/accessory/solgov/department/research/service)
+
+/obj/item/clothing/under/solgov/mildress/marine
name = "marine dress uniform"
desc = "The dress uniform of the SCG Marine Corps, class given form."
icon_state = "blackdress"
worn_state = "blackdress"
-/obj/item/clothing/under/mildress/marine/command
+/obj/item/clothing/under/solgov/mildress/marine/command
name = "marine command dress uniform"
desc = "The dress uniform of the SCG Marine Corps, even classier in gold."
icon_state = "blackdress_com"
diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm
index 6cb8c267fb..be7a6f6e79 100644
--- a/code/modules/fishing/fishing_rod.dm
+++ b/code/modules/fishing/fishing_rod.dm
@@ -11,8 +11,8 @@
description_antag = "Some fishing rods can be utilized as long-range, sharp weapons, though their pseudo ranged ability comes at the cost of slow speed."
icon_state = "fishing_rod"
item_state = "fishing_rod"
- force_divisor = 0.25
- throwforce = 7
+ force_divisor = 0.02 //VOREStation Edit
+ throwforce = 1 //VOREStation Edit
sharp = TRUE
attack_verb = list("whipped", "battered", "slapped", "fished", "hooked")
hitsound = 'sound/weapons/punchmiss.ogg'
diff --git a/code/modules/fishing/fishing_vr.dm b/code/modules/fishing/fishing_vr.dm
index f6e7dd715e..e545cc0edf 100644
--- a/code/modules/fishing/fishing_vr.dm
+++ b/code/modules/fishing/fishing_vr.dm
@@ -1,3 +1,9 @@
+#define FISHING_RARE "rare"
+#define FISHING_UNCOMMON "uncommon"
+#define FISHING_COMMON "common"
+#define FISHING_JUNK "junk"
+#define FISHING_NOTHING "nothing"
+
GLOBAL_LIST_INIT(indoor_fishing_chance_list, list(FISHING_RARE = 5, FISHING_UNCOMMON = 20, FISHING_COMMON = 30, FISHING_JUNK = 5, FISHING_NOTHING = 50))
GLOBAL_LIST_INIT(indoor_fishing_junk_list, list(
/obj/random/junk = 15,
@@ -17,8 +23,8 @@ GLOBAL_LIST_INIT(indoor_fishing_junk_list, list(
fishing_loot = GLOB.indoor_fishing_chance_list
/turf/simulated/floor/water/deep/indoors
- min_fishing_time = 45
- max_fishing_time = 120
+ min_fishing_time = 33
+ max_fishing_time = 99
/turf/simulated/floor/water/deep/indoors/handle_fish()
if(has_fish)
@@ -27,3 +33,10 @@ GLOBAL_LIST_INIT(indoor_fishing_junk_list, list(
common_fish_list = GLOB.generic_fishing_common_list
junk_list = GLOB.indoor_fishing_junk_list
fishing_loot = GLOB.indoor_fishing_chance_list
+
+
+#undef FISHING_RARE
+#undef FISHING_UNCOMMON
+#undef FISHING_COMMON
+#undef FISHING_JUNK
+#undef FISHING_NOTHING
\ No newline at end of file
diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm
index 90c083984c..fc37fb2064 100644
--- a/code/modules/food/food/snacks.dm
+++ b/code/modules/food/food/snacks.dm
@@ -754,7 +754,6 @@
/obj/item/weapon/reagent_containers/food/snacks/fishfingers/Initialize()
. = ..()
reagents.add_reagent("protein", 4)
- reagents.add_reagent("carpotoxin", 3)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/zestfish
@@ -988,7 +987,6 @@
/obj/item/weapon/reagent_containers/food/snacks/fishburger/Initialize()
. = ..()
reagents.add_reagent("protein", 6)
- reagents.add_reagent("carpotoxin", 3)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/tofuburger
@@ -1327,7 +1325,6 @@
/obj/item/weapon/reagent_containers/food/snacks/cubancarp/Initialize()
. = ..()
reagents.add_reagent("protein", 3)
- reagents.add_reagent("carpotoxin", 3)
reagents.add_reagent("capsaicin", 3)
bitesize = 3
@@ -1988,7 +1985,6 @@
/obj/item/weapon/reagent_containers/food/snacks/fishandchips/Initialize()
. = ..()
reagents.add_reagent("protein", 3)
- reagents.add_reagent("carpotoxin", 3)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/sandwich
@@ -3808,7 +3804,7 @@
/obj/item/weapon/reagent_containers/food/snacks/sashimi
name = "carp sashimi"
- desc = "Expertly prepared. Still toxic."
+ desc = "Expertly prepared. Hopefully toxin got removed though."
filling_color = "#FFDEFE"
icon_state = "sashimi"
nutriment_amt = 6
@@ -3816,7 +3812,6 @@
/obj/item/weapon/reagent_containers/food/snacks/sashimi/Initialize()
. = ..()
reagents.add_reagent("protein", 2)
- reagents.add_reagent("carpotoxin", 2)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/benedict
@@ -4147,4 +4142,27 @@
/obj/item/weapon/reagent_containers/food/snacks/wormdeluxe/Initialize()
. = ..()
reagents.add_reagent("fishbait", 40)
- bitesize = 5
\ No newline at end of file
+ bitesize = 5
+
+/obj/item/weapon/reagent_containers/food/snacks/siffruit
+ name = "pulsing fruit"
+ desc = "A blue-ish sac encased in a tough black shell."
+ icon = 'icons/obj/flora/foraging.dmi'
+ icon_state = "siffruit"
+ nutriment_amt = 2
+ nutriment_desc = list("tart" = 1)
+ w_class = ITEMSIZE_TINY
+
+/obj/item/weapon/reagent_containers/food/snacks/siffruit/Initialize()
+ . = ..()
+ reagents.add_reagent("sifsap", 2)
+
+/obj/item/weapon/reagent_containers/food/snacks/siffruit/afterattack(obj/O as obj, mob/user as mob, proximity)
+ if(istype(O,/obj/machinery/microwave))
+ return ..()
+ if(!(proximity && O.is_open_container()))
+ return
+ to_chat(user, "You tear \the [src]'s sac open, pouring it into \the [O].")
+ reagents.trans_to(O, reagents.total_volume)
+ user.drop_from_inventory(src)
+ qdel(src)
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
index d07a52a2f2..fa5fcc7397 100644
--- a/code/modules/mining/fulton.dm
+++ b/code/modules/mining/fulton.dm
@@ -9,7 +9,7 @@ var/global/list/total_extraction_beacons = list()
var/obj/structure/extraction_point/beacon
var/list/beacon_networks = list("station")
var/uses_left = 3
- var/can_use_indoors
+ var/can_use_indoors = FALSE
var/safe_for_living_creatures = 1
/obj/item/extraction_pack/examine()
@@ -145,7 +145,9 @@ var/global/list/total_extraction_beacons = list()
icon_state = "subspace_amplifier"
/obj/item/fulton_core/attack_self(mob/user)
- if(do_after(user,15,target = user) && !QDELETED(src))
+ var/turf/T = get_turf(user)
+ var/outdoors = T.outdoors
+ if(do_after(user,15,target = user) && !QDELETED(src) && outdoors)
new /obj/structure/extraction_point(get_turf(user))
qdel(src)
diff --git a/code/modules/mining/ore_redemption_machine/construction.dm b/code/modules/mining/ore_redemption_machine/construction.dm
index dbf8a96ffb..3880ef5cb8 100644
--- a/code/modules/mining/ore_redemption_machine/construction.dm
+++ b/code/modules/mining/ore_redemption_machine/construction.dm
@@ -10,3 +10,12 @@
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/matter_bin = 3)
+
+/obj/item/weapon/circuitboard/exploration_equipment_vendor
+ name = T_BOARD("Exploration Equipment Vendor")
+ board_type = new /datum/frame/frame_types/machine
+ build_path = /obj/machinery/mineral/equipment_vendor/survey
+ origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2)
+ req_components = list(
+ /obj/item/weapon/stock_parts/console_screen = 1,
+ /obj/item/weapon/stock_parts/matter_bin = 3)
diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm
index bf4ef87738..3d9651c044 100644
--- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm
+++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm
@@ -10,7 +10,7 @@
circuit = /obj/item/weapon/circuitboard/mining_equipment_vendor
var/icon_deny = "mining-deny"
var/obj/item/weapon/card/id/inserted_id
- //VOREStation Edit - Heavily modified list
+ //VOREStation Edit Start - Heavily modified list
var/list/prize_list = list(
new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10),
new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100),
@@ -36,11 +36,11 @@
new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900),
new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200),
new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200),
- //new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000),
+ // new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000),
new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 1000),
new /datum/data/mining_equipment("Hardsuit - Control Module", /obj/item/weapon/rig/industrial, 2000),
new /datum/data/mining_equipment("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800),
- new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/rig_module/device/drill, 2000),
+ new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000),
new /datum/data/mining_equipment("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000),
new /datum/data/mining_equipment("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500),
new /datum/data/mining_equipment("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250),
@@ -50,7 +50,7 @@
new /datum/data/mining_equipment("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500),
new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500),
new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000),
- new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000),
+ // new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000),
new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500),
new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500),
new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100),
@@ -66,14 +66,13 @@
new /datum/data/mining_equipment("Fine Excavation Kit - Chisels",/obj/item/weapon/storage/excavation, 500),
new /datum/data/mining_equipment("Fine Excavation Kit - Measuring Tape",/obj/item/device/measuring_tape, 125),
new /datum/data/mining_equipment("Fine Excavation Kit - Hand Pick",/obj/item/weapon/pickaxe/hand, 375),
- new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic, 750),
+ new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500),
new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500),
new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500),
new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500),
new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 1000),
- new /datum/data/mining_equipment("Misc: Graviton Visor", /obj/item/clothing/glasses/graviton, 1500),
new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 100),
- new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station, 1000),
+ new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000),
new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 1500),
new /datum/data/mining_equipment("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500),
new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500),
diff --git a/code/modules/mining/ore_redemption_machine/mine_point_items.dm b/code/modules/mining/ore_redemption_machine/mine_point_items.dm
index da4463842a..a6a90a3bd6 100644
--- a/code/modules/mining/ore_redemption_machine/mine_point_items.dm
+++ b/code/modules/mining/ore_redemption_machine/mine_point_items.dm
@@ -15,19 +15,33 @@
name = "mining point card"
desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard."
icon_state = "data"
- var/points = 500
+ var/mine_points = 500
+ var/survey_points = 0
/obj/item/weapon/card/mining_point_card/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/card/id))
- if(points)
- var/obj/item/weapon/card/id/C = I
- C.mining_points += points
- to_chat(user, "You transfer [points] points to [C].")
- points = 0
+ var/obj/item/weapon/card/id/C = I
+ if(mine_points)
+ C.mining_points += mine_points
+ to_chat(user, "You transfer [mine_points] excavation points to [C].")
+ mine_points = 0
else
- to_chat(user, "There's no points left on [src].")
+ to_chat(user, "There's no excavation points left on [src].")
+
+ if(survey_points)
+ C.survey_points += survey_points
+ to_chat(user, "You transfer [survey_points] survey points to [C].")
+ survey_points = 0
+ else
+ to_chat(user, "There's no survey points left on [src].")
+
..()
/obj/item/weapon/card/mining_point_card/examine(mob/user)
..(user)
- to_chat(user, "There's [points] points on the card.")
+ to_chat(user, "There's [mine_points] excavation points on the card.")
+ to_chat(user, "There's [survey_points] survey points on the card.")
+
+/obj/item/weapon/card/mining_point_card/survey
+ mine_points = 0
+ survey_points = 50
diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm
new file mode 100644
index 0000000000..61f5a26962
--- /dev/null
+++ b/code/modules/mining/ore_redemption_machine/survey_vendor.dm
@@ -0,0 +1,110 @@
+/obj/machinery/mineral/equipment_vendor/survey
+ name = "exploration equipment vendor"
+ desc = "An equipment vendor for explorers, points collected with a survey scanner can be spent here."
+ icon = 'icons/obj/machines/mining_machines_vr.dmi' //VOREStation Edit
+ icon_state = "exploration" //VOREStation Edit
+ density = TRUE
+ anchored = TRUE
+ circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor
+ icon_deny = "exploration-deny" //VOREStation Edit
+ var/icon_vend = "exploration-vend" //VOREStation Add
+ //VOREStation Edit Start - Heavily modified list
+ prize_list = list(
+ new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1),
+ new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10),
+ new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30),
+ new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/explorer, 10),
+ new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10),
+ new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10),
+ new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15),
+ new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20),
+ new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90),
+ new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 75),
+ new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 30),
+ new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon", /obj/item/fulton_core, 300),
+ new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack", /obj/item/extraction_pack, 125),
+ new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 20),
+ new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50),
+ new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50),
+ new /datum/data/mining_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 50),
+ new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50),
+ new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50),
+ new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50),
+ new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50),
+ new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100),
+ new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100),
+ new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120),
+ new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100),
+ new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250),
+ new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310),
+ new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 300),
+ new /datum/data/mining_equipment("Survey Tools - Shovel", /obj/item/weapon/shovel, 40),
+ new /datum/data/mining_equipment("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50),
+ new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10),
+ new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 100),
+ new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 150),
+ new /datum/data/mining_equipment("Defense Equipment - Steel Machete", /obj/item/weapon/material/knife/machete, 75),
+ new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50),
+ new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100),
+ new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750)
+ )
+ //VOREStation Edit End
+
+/obj/machinery/mineral/equipment_vendor/survey/interact(mob/user)
+ user.set_machine(src)
+
+ var/dat
+ dat +=""
+ if(istype(inserted_id))
+ dat += "You have [inserted_id.survey_points] survey points collected.
Eject ID."
+ else
+ dat += "No ID inserted.
Insert ID."
+ dat += "
"
+ dat += "
Equipment point cost list:
"
+ for(var/datum/data/mining_equipment/prize in prize_list)
+ dat += "| [prize.equipment_name] | [prize.cost] | Purchase |
"
+ dat += "
"
+ var/datum/browser/popup = new(user, "miningvendor", "Survey Equipment Vendor", 400, 600)
+ popup.set_content(dat)
+ popup.open()
+
+/obj/machinery/mineral/equipment_vendor/survey/Topic(href, href_list)
+ if(..())
+ return 1
+
+ if(href_list["choice"])
+ if(istype(inserted_id))
+ if(href_list["choice"] == "eject")
+ to_chat(usr, "You eject the ID from [src]'s card slot.")
+ usr.put_in_hands(inserted_id)
+ inserted_id = null
+ else if(href_list["choice"] == "insert")
+ var/obj/item/weapon/card/id/I = usr.get_active_hand()
+ if(istype(I) && !inserted_id && usr.unEquip(I))
+ I.forceMove(src)
+ inserted_id = I
+ interact(usr)
+ to_chat(usr, "You insert the ID into [src]'s card slot.")
+ else
+ to_chat(usr, "No valid ID.")
+ flick(icon_deny, src)
+
+ if(href_list["purchase"])
+ if(istype(inserted_id))
+ var/datum/data/mining_equipment/prize = locate(href_list["purchase"])
+ if (!prize || !(prize in prize_list))
+ to_chat(usr, "Error: Invalid choice!")
+ flick(icon_deny, src)
+ return
+ if(prize.cost > inserted_id.survey_points)
+ to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!")
+ flick(icon_deny, src)
+ else
+ inserted_id.survey_points -= prize.cost
+ to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!")
+ flick(icon_vend, src) //VOREStation Add
+ new prize.equipment_path(drop_location())
+ else
+ to_chat(usr, "Error: Please insert a valid ID!")
+ flick(icon_deny, src)
+ updateUsrDialog()
diff --git a/code/modules/mob/_modifiers/medical.dm b/code/modules/mob/_modifiers/medical.dm
new file mode 100644
index 0000000000..46a8877d1f
--- /dev/null
+++ b/code/modules/mob/_modifiers/medical.dm
@@ -0,0 +1,17 @@
+/*
+ * Modifiers caused by chemicals or organs specifically.
+ */
+
+/datum/modifier/cryogelled
+ name = "cryogelled"
+ desc = "Your body begins to freeze."
+ mob_overlay_state = "chilled"
+
+ on_created_text = "You feel like you're going to freeze! It's hard to move."
+ on_expired_text = "You feel somewhat warmer and more mobile now."
+ stacks = MODIFIER_STACK_ALLOWED
+
+ slowdown = 0.1
+ evasion = -5
+ attack_speed_percent = 1.1
+ disable_duration_percent = 1.05
diff --git a/code/modules/mob/_modifiers/modifiers_misc.dm b/code/modules/mob/_modifiers/modifiers_misc.dm
index e81cf0aaa8..800429de25 100644
--- a/code/modules/mob/_modifiers/modifiers_misc.dm
+++ b/code/modules/mob/_modifiers/modifiers_misc.dm
@@ -43,7 +43,7 @@ the artifact triggers the rage.
/datum/modifier/berserk
name = "berserk"
desc = "You are filled with an overwhelming rage."
- client_color = "#FF0000" // Make everything red!
+ client_color = "#FF5555" // Make everything red!
mob_overlay_state = "berserk"
on_created_text = "You feel an intense and overwhelming rage overtake you as you go berserk!"
@@ -293,4 +293,29 @@ the artifact triggers the rage.
on_expired_text = "You feel.. different."
stacks = MODIFIER_STACK_EXTEND
- pulse_set_level = PULSE_NORM
\ No newline at end of file
+ pulse_set_level = PULSE_NORM
+
+/datum/modifier/slow_pulse
+ name = "slow pulse"
+ desc = "Your blood flows slower."
+
+ on_created_text = "You feel sluggish."
+ on_expired_text = "You feel energized."
+ stacks = MODIFIER_STACK_EXTEND
+
+ bleeding_rate_percent = 0.8
+
+ pulse_set_level = PULSE_SLOW
+
+// Temperature Normalizer.
+/datum/modifier/homeothermic
+ name = "temperature resistance"
+ desc = "Your body normalizes to room temperature."
+
+ on_created_text = "You feel comfortable."
+ on_expired_text = "You feel.. still probably comfortable."
+ stacks = MODIFIER_STACK_EXTEND
+
+/datum/modifier/homeothermic/tick()
+ ..()
+ holder.bodytemperature = round((holder.bodytemperature + T20C) / 2)
diff --git a/code/modules/mob/_modifiers/unholy.dm b/code/modules/mob/_modifiers/unholy.dm
index 0b6f69a21b..730e57691c 100644
--- a/code/modules/mob/_modifiers/unholy.dm
+++ b/code/modules/mob/_modifiers/unholy.dm
@@ -146,3 +146,55 @@
if(prob(10))
to_chat(H, "It feels as though your body is being torn apart!")
L.updatehealth()
+
+/datum/modifier/gluttonyregeneration
+ name = "gluttonous regeneration"
+ desc = "You are filled with an overwhelming hunger."
+ mob_overlay_state = "electricity"
+
+ on_created_text = "You feel an intense and overwhelming hunger overtake you as your body regenerates!"
+ on_expired_text = "The blaze of hunger inside you has been snuffed."
+ stacks = MODIFIER_STACK_EXTEND
+
+/datum/modifier/gluttonyregeneration/can_apply(var/mob/living/L)
+ if(L.stat == DEAD)
+ to_chat(L, "You can't be dead to consume.")
+ return FALSE
+
+ if(!L.is_sentient())
+ return FALSE // Drones don't feel anything, not even hunger.
+
+ if(L.has_modifier_of_type(/datum/modifier/berserk_exhaustion))
+ to_chat(L, "You recently berserked, so you are too tired to consume.")
+ return FALSE
+
+ if(!ishuman(L)) // Only humanoids feel hunger. Totally.
+ return FALSE
+
+ else
+ var/mob/living/carbon/human/H = L
+ if(H.species.name == "Diona")
+ to_chat(L, "You feel strange for a moment, but it passes.")
+ return FALSE // Happy trees aren't affected by incredible hunger.
+
+ return ..()
+
+/datum/modifier/gluttonyregeneration/tick()
+ spawn()
+ if(ishuman(holder))
+ var/mob/living/carbon/human/H = holder
+ var/starting_nutrition = H.nutrition
+ H.nutrition = max(0, H.nutrition - 10)
+ var/healing_amount = starting_nutrition - H.nutrition
+ if(healing_amount < 0) // If you are eating enough to somehow outpace this, congratulations, you are gluttonous enough to gain a boon.
+ healing_amount *= -2
+
+ H.adjustBruteLoss(-healing_amount * 0.25)
+
+ H.adjustFireLoss(-healing_amount * 0.25)
+
+ H.adjustOxyLoss(-healing_amount * 0.25)
+
+ H.adjustToxLoss(-healing_amount * 0.25)
+
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 31cbcc1f44..2c74029eb8 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -389,13 +389,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return (T && T.holy) && (is_manifest || (mind in cult.current_antagonists))
-/mob/observer/dead/verb/jumptomob(target in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak
+/mob/observer/dead/verb/jumptomob(input in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
set name = "Jump to Mob"
set desc = "Teleport to a mob"
set popup_menu = FALSE //VOREStation Edit - Declutter.
if(istype(usr, /mob/observer/dead)) //Make sure they're an observer!
-
+ var/target = getmobs()[input]
if (!target)//Make sure we actually have a target
return
else
diff --git a/code/modules/mob/living/carbon/human/ai_controlled/ai_controlled.dm b/code/modules/mob/living/carbon/human/ai_controlled/ai_controlled.dm
new file mode 100644
index 0000000000..431b7c4456
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/ai_controlled/ai_controlled.dm
@@ -0,0 +1,143 @@
+/mob/living/carbon/human/ai_controlled
+ name = "Nameless Joe"
+
+ ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
+
+ var/generate_species = SPECIES_HUMAN
+ var/generate_dead = FALSE
+
+ var/generate_gender = FALSE
+ var/generate_id_gender = FALSE
+
+ var/to_wear_hair = "Bald"
+
+ var/to_wear_helmet = /obj/item/clothing/head/welding
+ var/to_wear_glasses = /obj/item/clothing/glasses/threedglasses
+ var/to_wear_mask = /obj/item/clothing/mask/gas
+ var/to_wear_l_radio = /obj/item/device/radio/headset
+ var/to_wear_r_radio = null
+ var/to_wear_uniform = /obj/item/clothing/under/color/grey
+ var/to_wear_suit = /obj/item/clothing/suit/armor/material/makeshift/glass
+ var/to_wear_gloves = /obj/item/clothing/gloves/ring/material/platinum
+ var/to_wear_shoes = /obj/item/clothing/shoes/galoshes
+ var/to_wear_belt = /obj/item/weapon/storage/belt/utility/full
+ var/to_wear_l_pocket = /obj/item/weapon/soap
+ var/to_wear_r_pocket = /obj/item/device/pda
+ var/to_wear_back = /obj/item/weapon/storage/backpack
+ var/to_wear_id_type = /obj/item/weapon/card/id
+ var/to_wear_id_job = "Assistant"
+
+ var/to_wear_l_hand = null
+ var/to_wear_r_hand = /obj/item/weapon/melee/baton
+
+/mob/living/carbon/human/ai_controlled/Initialize()
+ if(generate_gender)
+ gender = pick(list(MALE, FEMALE, PLURAL, NEUTER))
+
+ if(generate_id_gender)
+ identifying_gender = pick(list(MALE, FEMALE, PLURAL, NEUTER))
+
+ ..(loc, generate_species)
+
+ h_style = to_wear_hair
+
+ if(to_wear_uniform)
+ equip_to_slot_or_del(new to_wear_uniform(src), slot_w_uniform)
+
+ if(to_wear_suit)
+ equip_to_slot_or_del(new to_wear_suit(src), slot_wear_suit)
+
+ if(to_wear_shoes)
+ equip_to_slot_or_del(new to_wear_shoes(src), slot_shoes)
+
+ if(to_wear_gloves)
+ equip_to_slot_or_del(new to_wear_gloves(src), slot_gloves)
+
+ if(to_wear_l_radio)
+ equip_to_slot_or_del(new to_wear_l_radio(src), slot_l_ear)
+
+ if(to_wear_r_radio)
+ equip_to_slot_or_del(new to_wear_r_radio(src), slot_r_ear)
+
+ if(to_wear_glasses)
+ equip_to_slot_or_del(new to_wear_glasses(src), slot_glasses)
+
+ if(to_wear_mask)
+ equip_to_slot_or_del(new to_wear_mask(src), slot_wear_mask)
+
+ if(to_wear_helmet)
+ equip_to_slot_or_del(new to_wear_helmet(src), slot_head)
+
+ if(to_wear_belt)
+ equip_to_slot_or_del(new to_wear_belt(src), slot_belt)
+
+ if(to_wear_r_pocket)
+ equip_to_slot_or_del(new to_wear_r_pocket(src), slot_r_store)
+
+ if(to_wear_l_pocket)
+ equip_to_slot_or_del(new to_wear_l_pocket(src), slot_l_store)
+
+ if(to_wear_back)
+ equip_to_slot_or_del(new to_wear_back(src), slot_back)
+
+ if(to_wear_l_hand)
+ equip_to_slot_or_del(new to_wear_l_hand(src), slot_l_hand)
+
+ if(to_wear_r_hand)
+ equip_to_slot_or_del(new to_wear_r_hand(src), slot_r_hand)
+
+ if(to_wear_id_type)
+ var/obj/item/weapon/card/id/W = new to_wear_id_type(src)
+ W.name = "[real_name]'s ID Card"
+ var/datum/job/jobdatum
+ for(var/jobtype in typesof(/datum/job))
+ var/datum/job/J = new jobtype
+ if(J.title == to_wear_id_job)
+ jobdatum = J
+ break
+ if(jobdatum)
+ W.access = jobdatum.get_access()
+ else
+ W.access = list()
+ if(to_wear_id_job)
+ W.assignment = to_wear_id_job
+ W.registered_name = real_name
+ equip_to_slot_or_del(W, slot_wear_id)
+
+ if(generate_dead)
+ death()
+
+/*
+ * Subtypes.
+ */
+
+/mob/living/carbon/human/ai_controlled/replicant
+ generate_species = SPECIES_REPLICANT_BETA
+
+ generate_gender = TRUE
+ identifying_gender = NEUTER
+
+ faction = "xeno"
+
+ to_wear_helmet = /obj/item/clothing/head/helmet/dermal
+ to_wear_glasses = /obj/item/clothing/glasses/goggles
+ to_wear_mask = /obj/item/clothing/mask/gas/half
+ to_wear_l_radio = /obj/item/device/radio/headset/headset_rob
+ to_wear_r_radio = null
+ to_wear_uniform = /obj/item/clothing/under/color/grey
+ to_wear_suit = /obj/item/clothing/suit/armor/vest
+ to_wear_gloves = null
+ to_wear_shoes = /obj/item/clothing/shoes/boots/combat/changeling
+ to_wear_belt = /obj/item/weapon/storage/belt/utility/full
+ to_wear_l_pocket = /obj/item/weapon/grenade/explosive/mini
+ to_wear_r_pocket = /obj/item/weapon/grenade/explosive/mini
+ to_wear_back = /obj/item/device/radio/electropack
+ to_wear_id_type = /obj/item/weapon/card/id
+ to_wear_id_job = "Experiment"
+
+ to_wear_r_hand = null
+
+/mob/living/carbon/human/ai_controlled/replicant/Initialize()
+ ..()
+ name = species.get_random_name(gender)
+ add_modifier(/datum/modifier/homeothermic, 0, null)
diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm
index 809a5ef8ad..a3c5e65470 100644
--- a/code/modules/mob/living/carbon/human/human_powers.dm
+++ b/code/modules/mob/living/carbon/human/human_powers.dm
@@ -286,8 +286,11 @@
nutrition -= 200
for(var/obj/item/organ/I in internal_organs)
+ if(I.robotic >= ORGAN_ROBOT) // No free robofix.
+ continue
if(I.damage > 0)
I.damage = max(I.damage - 30, 0) //Repair functionally half of a dead internal organ.
+ I.status = 0 // Wipe status, as it's being regenerated from possibly dead.
to_chat(src, "You feel a soothing sensation within your [I.name]...")
// Replace completely missing limbs.
@@ -310,6 +313,15 @@
var/agony_to_apply = round(0.66 * O.max_damage) // 66% of the limb's health is converted into pain.
src.apply_damage(agony_to_apply, HALLOSS)
+ for(var/organtype in species.has_organ) // Replace completely missing internal organs. -After- external ones, so they all should exist.
+ if(!src.internal_organs_by_name[organtype])
+ var/organpath = species.has_organ[organtype]
+ var/obj/item/organ/Int = new organpath(src, TRUE)
+
+ Int.rejuvenate(TRUE)
+
+ handle_organs() // Update everything
+
update_icons_body()
active_regen = FALSE
else
diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm
index bb053cf488..4ac8697e28 100644
--- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm
+++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm
@@ -74,7 +74,13 @@ var/datum/species/shapeshifter/promethean/prometheans
genders = list(MALE, FEMALE, NEUTER, PLURAL)
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
- has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime) // Slime core.
+
+ has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime,
+ O_HEART = /obj/item/organ/internal/heart/grey/colormatch/slime,
+ O_REGBRUTE = /obj/item/organ/internal/regennetwork,
+ O_REGBURN = /obj/item/organ/internal/regennetwork/burn,
+ O_REGOXY = /obj/item/organ/internal/regennetwork/oxy,
+ O_REGTOX = /obj/item/organ/internal/regennetwork/tox)
dispersed_eyes = TRUE
@@ -197,35 +203,71 @@ var/datum/species/shapeshifter/promethean/prometheans
var/nutrition_cost = 0 // The total amount of nutrition drained every tick, when healing
var/nutrition_debt = 0 // Holder variable used to store previous damage values prior to healing for use in the nutrition_cost equation.
var/starve_mod = 1 // Lowering this lowers healing and increases agony multiplicatively.
- if(H.nutrition <= 150) // This is when the icon goes red
+
+ var/strain_negation = 0 // How much agony is being prevented by the
+
+ if(H.nutrition <= 150) // This is when the icon goes red
starve_mod = 0.75
if(H.nutrition <= 50) // Severe starvation. Damage repaired beyond this point will cause a stunlock if untreated.
starve_mod = 0.5
+ var/to_pay = 0
if(regen_brute)
nutrition_debt = H.getBruteLoss()
H.adjustBruteLoss(-heal_rate * starve_mod)
- nutrition_cost += nutrition_debt - H.getBruteLoss()
+
+ to_pay = nutrition_debt - H.getBruteLoss()
+
+ nutrition_cost += to_pay
+
+ var/obj/item/organ/internal/regennetwork/BrReg = H.internal_organs_by_name[O_REGBRUTE]
+
+ if(BrReg)
+ strain_negation += to_pay * max(0, (1 - BrReg.get_strain_percent()))
if(regen_burn)
nutrition_debt = H.getFireLoss()
H.adjustFireLoss(-heal_rate * starve_mod)
- nutrition_cost += nutrition_debt - H.getFireLoss()
+
+ to_pay = nutrition_debt - H.getFireLoss()
+
+ nutrition_cost += to_pay
+
+ var/obj/item/organ/internal/regennetwork/BuReg = H.internal_organs_by_name[O_REGBURN]
+
+ if(BuReg)
+ strain_negation += to_pay * max(0, (1 - BuReg.get_strain_percent()))
if(regen_oxy)
nutrition_debt = H.getOxyLoss()
H.adjustOxyLoss(-heal_rate * starve_mod)
- nutrition_cost += nutrition_debt - H.getOxyLoss()
+
+ to_pay = nutrition_debt - H.getOxyLoss()
+
+ nutrition_cost += to_pay
+
+ var/obj/item/organ/internal/regennetwork/OxReg = H.internal_organs_by_name[O_REGOXY]
+
+ if(OxReg)
+ strain_negation += to_pay * max(0, (1 - OxReg.get_strain_percent()))
if(regen_tox)
nutrition_debt = H.getToxLoss()
H.adjustToxLoss(-heal_rate * starve_mod)
- nutrition_cost += nutrition_debt - H.getToxLoss()
+
+ to_pay = nutrition_debt - H.getToxLoss()
+
+ nutrition_cost += to_pay
+
+ var/obj/item/organ/internal/regennetwork/ToxReg = H.internal_organs_by_name[O_REGTOX]
+
+ if(ToxReg)
+ strain_negation += to_pay * max(0, (1 - ToxReg.get_strain_percent()))
H.nutrition -= (3 * nutrition_cost) //Costs Nutrition when damage is being repaired, corresponding to the amount of damage being repaired.
H.nutrition = max(0, H.nutrition) //Ensure it's not below 0.
- var/agony_to_apply = ((1 / starve_mod) * nutrition_cost) //Regenerating damage causes minor pain over time. Small injures will be no issue, large ones will cause problems.
+ var/agony_to_apply = ((1 / starve_mod) * (nutrition_cost - strain_negation)) //Regenerating damage causes minor pain over time, if the organs responsible are nonexistant or too high on strain. Small injures will be no issue, large ones will cause problems.
if((starve_mod <= 0.5 && (H.getHalLoss() + agony_to_apply) <= 90) || ((H.getHalLoss() + agony_to_apply) <= 70)) // Will max out at applying halloss at 70, unless they are starving; starvation regeneration will bring them up to a maximum of 120, the same amount of agony a human receives from three taser hits.
H.apply_damage(agony_to_apply, HALLOSS)
diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm
index 8987f246b0..7e1aaa9f25 100644
--- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm
+++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm
@@ -96,16 +96,6 @@
excludes = list(/datum/trait/autohiss_tajaran, /datum/trait/autohiss_unathi)
// YW Addition end
-/datum/trait/autohiss_awootism
- name = "Autohiss (Disability)"
- desc = "You can't speak r's and l's properly."
- cost = 0
- var_changes = list(
- autohiss_basic_map = list(
- "l" = list("w", "ww"),
- "r" = list("w", "ww")
- ))
-
/datum/trait/bloodsucker
name = "Minor Bloodsucker"
desc = "Makes you unable to gain nutrition from anything but blood. To compensate, you get fangs that can be used to drain blood from prey."
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index bb861986b8..9eff93256a 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -247,7 +247,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
for(var/organ_tag in species.has_limbs)
var/obj/item/organ/external/part = organs_by_name[organ_tag]
- if(isnull(part) || part.is_stump())
+ if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff.
icon_key += "0"
continue
if(part)
@@ -290,7 +290,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
base_icon = chest.get_icon()
for(var/obj/item/organ/external/part in organs)
- if(isnull(part) || part.is_stump())
+ if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff.
continue
var/icon/temp = part.get_icon(skeleton)
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
@@ -577,7 +577,15 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
return //Wearing a suit that prevents uniform rendering
//Build a uniform sprite
- overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER)
+ //VOREStation Edit start.
+ var/icon/c_mask = null
+ if(tail_style && tail_style.clip_mask_icon && tail_style.clip_mask_state)
+ var/obj/item/clothing/suit/S = wear_suit
+ if(!(wear_suit && ((wear_suit.flags_inv & HIDETAIL) || (istype(S) && S.taurized)))) //Clip the lower half of the suit off using the tail's clip mask.
+ c_mask = new /icon(tail_style.clip_mask_icon, tail_style.clip_mask_state)
+ overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER, clip_mask = c_mask)
+ //VOREStation Edit end.
+
apply_layer(UNIFORM_LAYER)
/mob/living/carbon/human/update_inv_wear_id()
@@ -659,6 +667,12 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!shoes || (wear_suit && wear_suit.flags_inv & HIDESHOES) || (w_uniform && w_uniform.flags_inv & HIDESHOES))
return //Either nothing to draw, or it'd be hidden.
+ //VOREStation Edit
+ for(var/f in list(BP_L_FOOT, BP_R_FOOT))
+ var/obj/item/organ/external/foot/foot = get_organ(f)
+ if(istype(foot) && foot.is_hidden_by_tail()) //If either foot is hidden by the tail, don't render footwear.
+ return
+
//Allow for shoe layer toggle nonsense
var/shoe_layer = SHOES_LAYER
if(istype(shoes, /obj/item/clothing/shoes))
@@ -742,12 +756,18 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
// Part of splitting the suit sprites up
var/iconFile = INV_SUIT_DEF_ICON
+ var/obj/item/clothing/suit/S //VOREStation edit - break this var out a level for use below.
if(istype(wear_suit, /obj/item/clothing/suit))
- var/obj/item/clothing/suit/S = wear_suit
+ S = wear_suit
if(S.update_icon_define)
iconFile = S.update_icon_define
- overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = iconFile, default_layer = SUIT_LAYER)
+ //VOREStation Edit start.
+ var/icon/c_mask = null
+ if((tail_style && tail_style.clip_mask_icon && tail_style.clip_mask_state) && !(wear_suit.flags_inv & HIDETAIL) && !(S && S.taurized)) //Clip the lower half of the suit off using the tail's clip mask.
+ c_mask = new /icon(tail_style.clip_mask_icon, tail_style.clip_mask_state)
+ overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = iconFile, default_layer = SUIT_LAYER, clip_mask = c_mask)
+ //VOREStation Edit end.
apply_layer(SUIT_LAYER)
@@ -922,7 +942,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/t_state = "[species.get_tail(src)]_once"
var/used_tail_layer = tail_alt ? TAIL_LAYER_ALT : TAIL_LAYER // VOREStation Edit - Alt Tail Layer
-
+
var/image/tail_overlay = overlays_standing[used_tail_layer] // VOREStation Edit - Alt Tail Layer
if(tail_overlay && tail_overlay.icon_state == t_state)
return //let the existing animation finish
@@ -932,7 +952,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
spawn(20)
//check that the animation hasn't changed in the meantime
if(overlays_standing[used_tail_layer] == tail_overlay && tail_overlay.icon_state == t_state) // VOREStation Edit - Alt Tail Layer
- animate_tail_stop()
+ animate_tail_stop()
/mob/living/carbon/human/proc/animate_tail_start()
if(QDESTROYING(src))
@@ -973,7 +993,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(vr_wing_image)
vr_wing_image.layer = BODY_LAYER+WING_LAYER
overlays_standing[WING_LAYER] = vr_wing_image
-
+
apply_layer(WING_LAYER)
// VOREStation Edit end
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 37d9e43b37..55bddfe1bd 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -26,6 +26,9 @@
if(COLD_RESISTANCE in mutations)
damage = 0
adjustFireLoss(damage * blocked)
+ if(SEARING)
+ apply_damage(damage / 3, BURN, def_zone, blocked, soaked, used_weapon, sharp, edge)
+ apply_damage(damage / 3 * 2, BRUTE, def_zone, blocked, soaked, used_weapon, sharp, edge)
if(TOX)
adjustToxLoss(damage * blocked)
if(OXY)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e5dd8bf63e..e6fde9860f 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1060,7 +1060,7 @@ default behaviour is:
var/mob/living/carbon/human/H = src
if(!H.isSynthetic())
var/obj/item/organ/internal/liver/L = H.internal_organs_by_name["liver"]
- if(L.is_broken())
+ if(!L || L.is_broken())
blood_vomit = 1
Stun(5)
diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm
index 5f352705b8..62b2c43fe8 100644
--- a/code/modules/mob/living/simple_animal/corpse.dm
+++ b/code/modules/mob/living/simple_animal/corpse.dm
@@ -99,7 +99,19 @@
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
-
+/obj/effect/landmark/mobcorpse/solarpeacekeeper
+ name = "Mercenary"
+ corpseuniform = /obj/item/clothing/under/syndicate
+ corpsesuit = /obj/item/clothing/suit/armor/pcarrier/blue/sol
+ corpseshoes = /obj/item/clothing/shoes/boots/swat
+ corpsegloves = /obj/item/clothing/gloves/swat
+ corpseradio = /obj/item/device/radio/headset
+ corpsemask = /obj/item/clothing/mask/gas
+ corpsehelmet = /obj/item/clothing/head/helmet/swat
+ corpseback = /obj/item/weapon/storage/backpack
+ corpseid = 1
+ corpseidjob = "Peacekeeper"
+ corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/syndicatecommando
name = "Syndicate Commando"
diff --git a/code/modules/mob/living/simple_animal/corpse_vr.dm b/code/modules/mob/living/simple_animal/corpse_vr.dm
new file mode 100644
index 0000000000..82399a8328
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/corpse_vr.dm
@@ -0,0 +1,2 @@
+/obj/effect/landmark/mobcorpse/syndicatecommando
+ name = "Mercenary Commando"
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm
index 32eccb00af..5f4a4dc7e0 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm
@@ -72,7 +72,7 @@
attack_edge = TRUE
melee_attack_delay = 1 SECOND
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/crab
response_help = "pets"
response_disarm = "gently pushes aside"
@@ -117,4 +117,4 @@
for(var/mob/living/L in hearers(holder))
if(!istype(L, holder)) // Don't follow other hooligan crabs.
holder.visible_message("\The [holder] starts to follow \the [L].")
- set_follow(L, rand(20 SECONDS, 40 SECONDS))
\ No newline at end of file
+ set_follow(L, rand(20 SECONDS, 40 SECONDS))
diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
index 514f45df12..bddfc140d4 100644
--- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
@@ -162,6 +162,16 @@
base_attack_cooldown = 5 // Two attacks a second or so.
reload_max = 20
+/mob/living/simple_mob/humanoid/merc/ranged/smg/sol
+ icon_state = "bluforranged_smg"
+ icon_living = "blueforranged_smg"
+
+ corpse = /obj/effect/landmark/mobcorpse/solarpeacekeeper
+ loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100)
+
+ base_attack_cooldown = 5 // Two attacks a second or so.
+ reload_max = 20
+
// Laser Rifle
/mob/living/simple_mob/humanoid/merc/ranged/laser
icon_state = "syndicateranged_laser"
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index b335faf1d3..7ad90dfc43 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -174,6 +174,12 @@
assailant.visible_message("[assailant] covers [affecting]'s eyes!")
if(affecting.eye_blind < 3)
affecting.Blind(3)
+ //TFF 12/8/19 VoreStation Addition Start
+ if(BP_HEAD)
+ if(force_down)
+ if(announce)
+ assailant.visible_message("[assailant] sits on [target]'s head!")
+ //VoreStation Addition End
/obj/item/weapon/grab/attack_self()
return s_click(hud)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index b03649183b..e66cf6f4ac 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -84,7 +84,7 @@
/client/verb/drop_item()
set hidden = 1
- if(!isrobot(mob) && mob.stat == CONSCIOUS && isturf(mob.loc))
+ if(!isrobot(mob) && mob.stat == CONSCIOUS && (isturf(mob.loc) || isbelly(mob.loc))) // VOREStation Edit: dropping in bellies
return mob.drop_item()
return
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 579e7776b7..215ef65ced 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -78,6 +78,7 @@ var/list/organ_cache = list()
if(E.internal_organs == null)
E.internal_organs = list()
E.internal_organs |= src
+ H.internal_organs_by_name[organ_tag] = src
if(dna)
if(!blood_DNA)
blood_DNA = list()
diff --git a/code/modules/organs/organ_external_vr.dm b/code/modules/organs/organ_external_vr.dm
index 0e3fb07d9e..491cce9428 100644
--- a/code/modules/organs/organ_external_vr.dm
+++ b/code/modules/organs/organ_external_vr.dm
@@ -13,3 +13,7 @@
min_broken_damage = o_min_broken_damage
else
return ..()
+
+/obj/item/organ/external/proc/is_hidden_by_tail()
+ if(owner && owner.tail_style && owner.tail_style.hide_body_parts && (organ_tag in owner.tail_style.hide_body_parts))
+ return 1
\ No newline at end of file
diff --git a/code/modules/organs/subtypes/slime.dm b/code/modules/organs/subtypes/slime.dm
index f22b90caea..5fb54a21b4 100644
--- a/code/modules/organs/subtypes/slime.dm
+++ b/code/modules/organs/subtypes/slime.dm
@@ -56,3 +56,89 @@
max_damage = 30
encased = 0
spread_dam = 1
+
+/*
+ * Internal Slime organs.
+ */
+
+/obj/item/organ/internal/heart/grey/colormatch/slime
+ name = "pneumatic network"
+ desc = "A disgusting sac of goo."
+ icon_state = "sac_slime"
+ dead_icon = null
+ standard_pulse_level = PULSE_NONE
+
+/obj/item/organ/internal/heart/grey/colormatch/slime/process()
+ ..()
+ if(!(QDELETED(src)) && src.loc != owner)
+ visible_message("\The [src] splatters!")
+ var/turf/T = get_turf(src)
+ var/obj/effect/decal/cleanable/blood/B = new (T)
+
+ B.basecolor = src.color
+ B.update_icon()
+ qdel(src)
+
+/obj/item/organ/internal/regennetwork
+ name = "pneumoregenesis network"
+ parent_organ = BP_TORSO
+ organ_tag = O_REGBRUTE
+
+ icon_state = "sac_slime"
+
+ var/strain = 0 // The amount of stress this organ is under. Capped at min_broken_damage, usually half its max damage.
+
+ var/last_strain_increase = 0 // World time of the last increase in strain.
+ var/strain_regen_cooldown = 5 MINUTES
+
+/obj/item/organ/internal/regennetwork/Initialize()
+ ..()
+ var/mob/living/carbon/human/H = null
+ spawn(15)
+ if(ishuman(owner))
+ H = owner
+ color = H.species.get_blood_colour(H)
+
+/obj/item/organ/internal/regennetwork/proc/get_strain_percent(var/cost)
+ adjust_strain(cost)
+
+ if((status & ORGAN_CUT_AWAY) || (status & ORGAN_BROKEN) || (status & ORGAN_DEAD))
+ return 1
+
+ return round((strain / min_broken_damage) * 10) / 10
+
+/obj/item/organ/internal/regennetwork/proc/adjust_strain(var/amount)
+ if(amount < 0 && world.time < (last_strain_increase + strain_regen_cooldown))
+ return
+
+ else if(amount > 0)
+ last_strain_increase = world.time
+
+ strain = CLAMP(strain + amount, 0, min_broken_damage)
+
+/obj/item/organ/internal/regennetwork/process()
+ ..()
+
+ if(!(QDELETED(src)) && src.loc != owner)
+ visible_message("\The [src] splatters!")
+ var/turf/T = get_turf(src)
+ var/obj/effect/decal/cleanable/blood/B = new (T)
+
+ B.basecolor = src.color
+ B.update_icon()
+ qdel(src)
+
+ if(src && !is_bruised())
+ adjust_strain(-0.25 * max(0, (min_broken_damage - damage) / min_broken_damage)) // Decrease the current strain with respect to the current strain level.
+
+/obj/item/organ/internal/regennetwork/burn
+ name = "thermoregenesis network"
+ organ_tag = O_REGBURN
+
+/obj/item/organ/internal/regennetwork/oxy
+ name = "respiroregenesis network"
+ organ_tag = O_REGOXY
+
+/obj/item/organ/internal/regennetwork/tox
+ name = "toxoregenesis network"
+ organ_tag = O_REGTOX
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index dee4cabfa6..a481cfaf33 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -281,6 +281,28 @@
var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc)
reagents.trans_to_obj(P,50)
+ else if (href_list["createpatch"])
+ if(reagents.total_volume < 1) //Sanity checking.
+ return
+
+ var/name = sanitizeSafe(input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([round(reagents.total_volume)]u)") as null|text, MAX_NAME_LEN)
+
+ if(!name) //Blank name (sanitized to nothing, or left empty) or cancel
+ return
+
+ if(reagents.total_volume < 1) //Sanity checking.
+ return
+ var/obj/item/weapon/reagent_containers/pill/patch/P = new/obj/item/weapon/reagent_containers/pill/patch(src.loc)
+ if(!name) name = reagents.get_master_reagent_name()
+ P.name = "[name] patch"
+ P.pixel_x = rand(-7, 7) //random position
+ P.pixel_y = rand(-7, 7)
+
+ reagents.trans_to_obj(P, 60)
+ if(src.loaded_pill_bottle)
+ if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space)
+ P.loc = loaded_pill_bottle
+
else if(href_list["pill_sprite"])
pillsprite = href_list["pill_sprite"]
else if(href_list["bottle_sprite"])
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index 86a35c0365..94495648c9 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -16,6 +16,28 @@
M.add_chemical_effect(CE_STABLE, 15)
M.add_chemical_effect(CE_PAINKILLER, 10)
+/datum/reagent/inaprovaline/topical
+ name = "Inaprovalaze"
+ id = "inaprovalaze"
+ description = "Inaprovalaze is a topical variant of Inaprovaline."
+ taste_description = "bitterness"
+ reagent_state = LIQUID
+ color = "#00BFFF"
+ overdose = REAGENTS_OVERDOSE * 2
+ metabolism = REM * 0.5
+ scannable = 1
+ touch_met = REM * 0.75
+
+/datum/reagent/inaprovaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien != IS_DIONA)
+ ..()
+ M.adjustToxLoss(2 * removed)
+
+/datum/reagent/inaprovaline/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien != IS_DIONA)
+ M.add_chemical_effect(CE_STABLE, 20)
+ M.add_chemical_effect(CE_PAINKILLER, 12)
+
/datum/reagent/bicaridine
name = "Bicaridine"
id = "bicaridine"
@@ -51,6 +73,33 @@
if(W.damage <= 0)
O.wounds -= W
+/datum/reagent/bicaridine/topical
+ name = "Bicaridaze"
+ id = "bicaridaze"
+ description = "Bicaridaze is a topical variant of the chemical Bicaridine."
+ taste_description = "bitterness"
+ taste_mult = 3
+ reagent_state = LIQUID
+ color = "#BF0000"
+ overdose = REAGENTS_OVERDOSE * 0.75
+ scannable = 1
+ touch_met = REM * 0.75
+
+/datum/reagent/bicaridine/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ var/chem_effective = 1
+ if(alien == IS_SLIME)
+ chem_effective = 0.75
+ if(alien != IS_DIONA)
+ ..(M, alien, removed * chem_effective)
+ M.adjustToxLoss(2 * removed)
+
+/datum/reagent/bicaridine/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ var/chem_effective = 1
+ if(alien == IS_SLIME)
+ chem_effective = 0.75
+ if(alien != IS_DIONA)
+ M.heal_organ_damage(6 * removed * chem_effective, 0)
+
/datum/reagent/kelotane
name = "Kelotane"
id = "kelotane"
@@ -87,6 +136,33 @@
if(alien != IS_DIONA)
M.heal_organ_damage(0, 8 * removed * chem_effective) //VOREStation edit
+/datum/reagent/dermaline/topical
+ name = "Dermalaze"
+ id = "dermalaze"
+ description = "Dermalaze is a topical variant of the chemical Dermaline."
+ taste_description = "bitterness"
+ taste_mult = 1.5
+ reagent_state = LIQUID
+ color = "#FF8000"
+ overdose = REAGENTS_OVERDOSE * 0.4
+ scannable = 1
+ touch_met = REM * 0.75
+
+/datum/reagent/dermaline/topical/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ var/chem_effective = 1
+ if(alien == IS_SLIME)
+ chem_effective = 0.75
+ if(alien != IS_DIONA)
+ ..(M, alien, removed * chem_effective)
+ M.adjustToxLoss(2 * removed)
+
+/datum/reagent/dermaline/topical/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ var/chem_effective = 1
+ if(alien == IS_SLIME)
+ chem_effective = 0.75
+ if(alien != IS_DIONA)
+ M.heal_organ_damage(0, 12 * removed * chem_effective)
+
/datum/reagent/dylovene
name = "Dylovene"
id = "anti_toxin"
@@ -203,6 +279,10 @@
M.heal_organ_damage(1.5 * removed, 1.5 * removed * chem_effective)
M.adjustToxLoss(-1.5 * removed * chem_effective)
+/datum/reagent/tricordrazine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien != IS_DIONA)
+ affect_blood(M, alien, removed * 0.4)
+
/datum/reagent/cryoxadone
name = "Cryoxadone"
id = "cryoxadone"
@@ -882,6 +962,9 @@
to_chat(M, "Your senses feel unfocused, and divided.")
M.add_chemical_effect(CE_ANTIBIOTIC, dose >= overdose ? ANTIBIO_OD : ANTIBIO_NORM)
+/datum/reagent/spaceacillin/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ affect_blood(M, alien, removed * 0.8) // Not 100% as effective as injections, though still useful.
+
/datum/reagent/corophizine
name = "Corophizine"
id = "corophizine"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm
new file mode 100644
index 0000000000..d9a7483ec1
--- /dev/null
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm
@@ -0,0 +1,58 @@
+/*
+ * Modifier-applying chemicals.
+ */
+
+/datum/reagent/modapplying
+ name = "brute juice"
+ id = "berserkmed"
+ description = "A liquid that is capable of causing a prolonged state of heightened aggression and durability."
+ taste_description = "metal"
+ reagent_state = LIQUID
+ color = "#ff5555"
+ metabolism = REM
+
+ var/modifier_to_add = /datum/modifier/berserk
+ var/modifier_duration = 2 SECONDS // How long, per unit dose, will this last?
+
+/datum/reagent/modapplying/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien == IS_DIONA)
+ return
+ M.add_modifier(modifier_to_add, dose * modifier_duration)
+
+/datum/reagent/modapplying/cryofluid
+ name = "cryogenic slurry"
+ id = "cryoslurry"
+ description = "An incredibly strange liquid that rapidly absorbs thermal energy from materials it contacts."
+ taste_description = "siberian hellscape"
+ color = "#4CDBDB"
+ metabolism = REM * 0.5
+
+ modifier_to_add = /datum/modifier/cryogelled
+ modifier_duration = 3 SECONDS
+
+/datum/reagent/modapplying/cryofluid/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..(M, alien, removed)
+ M.bodytemperature -= removed * 20
+
+/datum/reagent/modapplying/cryofluid/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
+ affect_blood(M, alien, removed * 2.5)
+
+/datum/reagent/modapplying/cryofluid/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ affect_blood(M, alien, removed * 0.6)
+
+/datum/reagent/modapplying/cryofluid/touch_mob(var/mob/M, var/amount)
+ if(isliving(M))
+ var/mob/living/L = M
+ for(var/I = 1 to rand(1, round(amount + 1)))
+ L.add_modifier(modifier_to_add, amount * rand(modifier_duration / 2, modifier_duration * 2))
+ return
+
+/datum/reagent/modapplying/cryofluid/touch_turf(var/turf/T, var/amount)
+ if(istype(T, /turf/simulated/floor/water) && prob(amount))
+ T.visible_message("\The [T] crackles loudly as the cryogenic fluid causes it to boil away, leaving behind a hard layer of ice.")
+ T.ChangeTurf(/turf/simulated/floor/outdoors/ice, 1, 1, TRUE)
+ else
+ if(istype(T, /turf/simulated))
+ var/turf/simulated/S = T
+ S.freeze_floor()
+ return
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
index 79304733dd..38a65a78d8 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
@@ -11,6 +11,7 @@
metabolism = REM * 0.25 // 0.05 by default. Hopefully enough to get some help, or die horribly, whatever floats your boat
filtered_organs = list(O_LIVER, O_KIDNEYS)
var/strength = 4 // How much damage it deals per unit
+ var/skin_danger = 0.2 // The multiplier for how effective the toxin is when making skin contact.
/datum/reagent/toxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(strength && alien != IS_DIONA)
@@ -23,6 +24,9 @@
M.heal_organ_damage((10/strength) * removed, (10/strength) * removed) //Doses of toxins below 10 units, and 10 strength, are capable of providing useful compounds for repair.
M.adjustToxLoss(strength * removed)
+/datum/reagent/toxin/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
+ affect_blood(M, alien, removed * 0.2)
+
/datum/reagent/toxin/plasticide
name = "Plasticide"
id = "plasticide"
@@ -58,6 +62,7 @@
reagent_state = LIQUID
color = "#005555"
strength = 8
+ skin_danger = 0.4
/datum/reagent/toxin/neurotoxic_protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
..()
@@ -121,6 +126,7 @@
color = "#9D14DB"
strength = 30
touch_met = 5
+ skin_danger = 1
/datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
@@ -346,6 +352,36 @@
if(alien == IS_DIONA)
M.adjustToxLoss(50 * removed)
+/datum/reagent/toxin/sifslurry
+ name = "Sivian Sap"
+ id = "sifsap"
+ description = "A natural slurry comprised of fluorescent bacteria native to Sif, in the Vir system."
+ taste_description = "sour"
+ reagent_state = LIQUID
+ color = "#C6E2FF"
+ strength = 2
+ overdose = 20
+
+/datum/reagent/toxin/sifslurry/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien == IS_DIONA) // Symbiotic bacteria.
+ M.nutrition += strength * removed
+ return
+ else
+ M.add_modifier(/datum/modifier/slow_pulse, 30 SECONDS)
+ ..()
+
+/datum/reagent/toxin/sifslurry/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect.
+ if(alien == IS_DIONA)
+ return
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ overdose_mod *= H.species.chemOD_mod
+ M.apply_effect(2 * removed,IRRADIATE, 0, 0)
+ M.apply_effect(5 * removed,DROWSY, 0, 0)
+
+/datum/reagent/toxin/sifslurry/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
+ affect_blood(M, alien, removed * 0.7)
+
/datum/reagent/acid/polyacid
name = "Polytrinic acid"
id = "pacid"
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index 5b37335647..a903454801 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -34,6 +34,7 @@
var/reaction_sound = 'sound/effects/bubbles.ogg'
var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file.
+
/datum/chemical_reaction/proc/can_happen(var/datum/reagents/holder)
//check that all the required reagents are present
if(!holder.has_all_reagents(required_reagents))
@@ -500,6 +501,15 @@
required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5)
result_amount = 2
+/datum/chemical_reaction/carpotoxin
+ name = "Carpotoxin"
+ id = "carpotoxin"
+ result = "carpotoxin"
+ required_reagents = list("spidertoxin" = 2, "biomass" = 1, "sifsap" = 2)
+ catalysts = list("sifsap" = 10)
+ inhibitors = list("radium" = 1)
+ result_amount = 2
+
/datum/chemical_reaction/mindbreaker
name = "Mindbreaker Toxin"
id = "mindbreaker"
@@ -2523,3 +2533,19 @@
result = "protein"
required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2)
result_amount = 2
+
+/datum/chemical_reaction/neutralize_carpotoxin
+ name = "Neutralize Carpotoxin"
+ id = "carpotoxin_neutral"
+ result = "protein"
+ required_reagents = list("radium" = 1, "carpotoxin" = 1, "sifsap" = 1)
+ catalysts = list("sifsap" = 10)
+ result_amount = 2
+
+/datum/chemical_reaction/neutralize_spidertoxin
+ name = "Neutralize Spidertoxin"
+ id = "spidertoxin_neutral"
+ result = "protein"
+ required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1)
+ catalysts = list("sifsap" = 10)
+ result_amount = 2
diff --git a/code/modules/reagents/distilling/Distilling-Recipes.dm b/code/modules/reagents/distilling/Distilling-Recipes.dm
new file mode 100644
index 0000000000..f7fae18178
--- /dev/null
+++ b/code/modules/reagents/distilling/Distilling-Recipes.dm
@@ -0,0 +1,170 @@
+/datum/chemical_reaction/distilling
+// name = null
+// id = null
+// result = null
+// required_reagents = list()
+// catalysts = list()
+// inhibitors = list()
+// result_amount = 0
+
+ //how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros.
+ reaction_rate = HALF_LIFE(6)
+
+ //if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high.
+ //0.5 = 50% yield -> reaction will only proceed halfway until products are removed.
+// yield = 1.0
+
+ //If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios),
+ //the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts.
+// min_reaction = 2
+
+ mix_message = "The solution churns."
+ reaction_sound = 'sound/effects/slosh.ogg'
+
+// log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file.
+
+ var/list/temp_range = list(T0C, T20C)
+ var/temp_shift = 0 // How much the temperature changes when the reaction occurs.
+
+/datum/chemical_reaction/distilling/can_happen(var/datum/reagents/holder)
+ //check that all the required reagents are present
+ if(!holder.has_all_reagents(required_reagents))
+ return 0
+
+ //check that all the required catalysts are present in the required amount
+ if(!holder.has_all_reagents(catalysts))
+ return 0
+
+ //check that none of the inhibitors are present in the required amount
+ if(holder.has_any_reagent(inhibitors))
+ return 0
+
+ if(!istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling))
+ return 0
+
+ else // Super special temperature check.
+ var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom
+ var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master
+ if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2])
+ return 0
+
+ return 1
+
+/datum/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume)
+ if(istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling))
+ var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom
+ var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master
+ RD.current_temp += temp_shift
+ return
+
+// Subtypes //
+
+// Biomass
+/datum/chemical_reaction/distilling/biomass
+ name = "Distilling Biomass"
+ id = "distill_biomass"
+ result = "biomass"
+ required_reagents = list("blood" = 1, "sugar" = 1, "phoron" = 0.5)
+ result_amount = 1 // 40 units per sheet, requires actually using the machine, and having blood to spare.
+
+ temp_range = list(T20C + 80, T20C + 130)
+ temp_shift = -2
+
+// Medicinal
+/datum/chemical_reaction/distilling/inaprovalaze
+ name = "Distilling Inaprovalaze"
+ id = "distill_inaprovalaze"
+ result = "inaprovalaze"
+ required_reagents = list("inaprovaline" = 2, "foaming_agent" = 1)
+ result_amount = 2
+
+ reaction_rate = HALF_LIFE(10)
+
+ temp_range = list(T0C + 100, T0C + 120)
+
+/datum/chemical_reaction/distilling/bicaridaze
+ name = "Distilling Bicaridaze"
+ id = "distill_bicaridaze"
+ result = "bicaridaze"
+ required_reagents = list("bicaridine" = 2, "foaming_agent" = 1)
+ result_amount = 2
+
+ reaction_rate = HALF_LIFE(10)
+
+ temp_range = list(T0C + 110, T0C + 130)
+
+/datum/chemical_reaction/distilling/dermalaze
+ name = "Distilling Dermalaze"
+ id = "distill_dermalaze"
+ result = "dermalaze"
+ required_reagents = list("dermaline" = 2, "foaming_agent" = 1)
+ result_amount = 2
+
+ reaction_rate = HALF_LIFE(10)
+
+ temp_range = list(T0C + 115, T0C + 130)
+
+// Alcohol
+/datum/chemical_reaction/distilling/beer
+ name = "Distilling Beer"
+ id = "distill_beer"
+ result = "beer"
+ required_reagents = list("nutriment" = 1, "water" = 1, "sugar" = 1)
+ result_amount = 2
+
+ reaction_rate = HALF_LIFE(30)
+
+ temp_range = list(T20C, T20C + 2)
+
+/datum/chemical_reaction/distilling/ale
+ name = "Distilling Ale"
+ id = "distill_ale"
+ result = "ale"
+ required_reagents = list("nutriment" = 1, "beer" = 1)
+ inhibitors = list("water" = 1)
+ result_amount = 2
+
+ reaction_rate = HALF_LIFE(30)
+
+ temp_shift = 0.5
+ temp_range = list(T0C + 7, T0C + 13)
+
+// Unique
+/datum/chemical_reaction/distilling/berserkjuice
+ name = "Distilling Brute Juice"
+ id = "distill_brutejuice"
+ result = "berserkmed"
+ required_reagents = list("biomass" = 1, "hyperzine" = 3, "synaptizine" = 2, "phoron" = 1)
+ result_amount = 3
+
+ temp_range = list(T0C + 600, T0C + 700)
+ temp_shift = 4
+
+/datum/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume)
+ ..()
+
+ if(prob(1))
+ var/turf/T = get_turf(holder.my_atom)
+ explosion(T, -1, rand(-1, 1), rand(1,2), rand(3,5))
+ return
+
+/datum/chemical_reaction/distilling/cryogel
+ name = "Distilling Cryogellatin"
+ id = "distill_cryoslurry"
+ result = "cryoslurry"
+ required_reagents = list("frostoil" = 7, "enzyme" = 3, "plasticide" = 3, "foaming_agent" = 2)
+ inhibitors = list("water" = 5)
+ result_amount = 1
+
+ temp_range = list(0, 15)
+ temp_shift = 20
+
+/datum/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume)
+ ..()
+
+ if(prob(1))
+ var/turf/T = get_turf(holder.my_atom)
+ var/datum/effect/effect/system/smoke_spread/frost/F = new (holder.my_atom)
+ F.set_up(6, 0, T)
+ F.start()
+ return
diff --git a/code/modules/reagents/distilling/distilling.dm b/code/modules/reagents/distilling/distilling.dm
new file mode 100644
index 0000000000..b86bcc7435
--- /dev/null
+++ b/code/modules/reagents/distilling/distilling.dm
@@ -0,0 +1,317 @@
+
+/*
+ * Distillery, used for over-time temperature-based mixes.
+ */
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery
+ name = "chemical distillery"
+ desc = "A complex machine utilizing state-of-the-art components to mix chemicals at different temperatures."
+ use_power = 1
+
+ icon = 'icons/obj/machines/reagent.dmi'
+ icon_state = "distiller"
+ var/base_state // The string var used in update icon for overlays, either set manually or initialized.
+
+ power_rating = 3000
+ power_losses = 240
+
+ var/on = FALSE
+
+ var/target_temp = T20C
+
+ var/max_temp = T20C + 300
+ var/min_temp = T0C - 10
+
+ var/current_temp = T20C
+
+ var/use_atmos = FALSE // If true, this machine will be connectable to ports, and use gas mixtures as the source of heat, rather than its internal controls.
+
+ var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
+ var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use")
+
+ var/static/radial_pump = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pump")
+
+ var/static/radial_eject_input = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_input")
+ var/static/radial_eject_output = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_output")
+
+ var/static/radial_adjust_temp = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_temp")
+
+ var/static/radial_install_input = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_add")
+ var/static/radial_install_output = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_add")
+
+ var/static/radial_inspectgauges = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_lookat")
+
+ var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix")
+
+// Overlay holders so we don't have to constantly remake them.
+ var/image/overlay_output_beaker
+ var/image/overlay_input_beaker
+ var/image/overlay_off
+ var/image/overlay_ready
+ var/image/overlay_cooling
+ var/image/overlay_heating
+ var/image/overlay_dumping
+ var/image/overlay_connected
+
+// Our unique beaker, used in its unique recipes to ensure things can only react inside this machine and minimize oddities from trying to transfer to a machine and back.
+ var/obj/item/weapon/reagent_containers/glass/distilling/Reservoir
+
+ var/obj/item/weapon/reagent_containers/glass/InputBeaker
+ var/obj/item/weapon/reagent_containers/glass/OutputBeaker
+
+// A multiplier for the production amount. This should really only ever be lower than one, otherwise you end up with duping.
+ var/efficiency = 1
+
+/obj/item/weapon/reagent_containers/glass/distilling
+ name = "distilling chamber"
+ desc = "You should not be seeing this."
+ volume = 600
+
+ var/obj/machinery/portable_atmospherics/powered/reagent_distillery/Master
+
+/obj/item/weapon/reagent_containers/glass/distilling/Destroy()
+ Master = null
+ ..()
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/Initialize()
+ ..()
+
+ Reservoir = new (src)
+ Reservoir.Master = src
+
+ if(!base_state)
+ base_state = icon_state
+
+ setup_overlay_vars()
+
+ update_icon()
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/proc/setup_overlay_vars()
+ overlay_output_beaker = image(icon = src.icon, icon_state = "[base_state]-output")
+ overlay_input_beaker = image(icon = src.icon, icon_state = "[base_state]-input")
+ overlay_off = image(icon = src.icon, icon_state = "[base_state]-bad")
+ overlay_ready = image(icon = src.icon, icon_state = "[base_state]-good")
+ overlay_cooling = image(icon = src.icon, icon_state = "[base_state]-cool")
+ overlay_heating = image(icon = src.icon, icon_state = "[base_state]-heat")
+ overlay_dumping = image(icon = src.icon, icon_state = "[base_state]-dump")
+ overlay_connected = image(icon = src.icon, icon_state = "[base_state]-connector")
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/Destroy()
+ qdel(Reservoir)
+ Reservoir = null
+ if(InputBeaker)
+ qdel(InputBeaker)
+ InputBeaker = null
+ if(OutputBeaker)
+ qdel(OutputBeaker)
+ OutputBeaker = null
+
+ ..()
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/attack_hand(mob/user)
+ var/list/options = list()
+ options["examine"] = radial_examine
+ options["use"] = radial_use
+ options["inspect gauges"] = radial_inspectgauges
+ options["pulse agitator"] = radial_mix
+
+ if(InputBeaker)
+ options["eject input"] = radial_eject_input
+ if(OutputBeaker)
+ options["eject output"] = radial_eject_output
+
+ if(!use_atmos)
+ options["adjust temp"] = radial_adjust_temp
+
+ if(length(options) < 1)
+ return
+
+ var/list/choice = list()
+ if(length(options) == 1)
+ for(var/key in options)
+ choice = key
+ else
+ choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
+
+ switch(choice)
+ if("examine")
+ examine(user)
+
+ if("use")
+ if(powered())
+ on = !on
+ to_chat(user, "You turn \the [src] [on ? "on" : "off"].")
+
+ if("inspect gauges")
+ to_chat(user, "\The [src]'s gauges read:")
+ if(!use_atmos)
+ to_chat(user, "- Target Temperature: [target_temp]")
+ to_chat(user, "- Temperature: [current_temp]")
+
+ if("pulse agitator")
+ to_chat(user, "You press \the [src]'s chamber agitator button.")
+ if(on)
+ visible_message("\The [src] rattles to life.")
+ Reservoir.reagents.handle_reactions()
+ else
+ spawn(1 SECOND)
+ to_chat(user, "Nothing happens..")
+
+ if("eject input")
+ if(InputBeaker)
+ InputBeaker.forceMove(get_turf(src))
+ InputBeaker = null
+
+ if("eject output")
+ if(OutputBeaker)
+ OutputBeaker.forceMove(get_turf(src))
+ OutputBeaker = null
+
+ if("adjust temp")
+ target_temp = input("Choose a target temperature.", "Temperature.", T20C) as num
+ target_temp = CLAMP(target_temp, min_temp, max_temp)
+
+ update_icon()
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ var/list/options = list()
+ if(istype(W, /obj/item/weapon/reagent_containers/glass))
+ if(!InputBeaker)
+ options["install input"] = radial_install_input
+ if(!OutputBeaker)
+ options["install output"] = radial_install_output
+
+ if(!options || !options.len)
+ update_icon()
+ return ..()
+
+ var/list/choice = list()
+ if(length(options) == 1)
+ for(var/key in options)
+ choice = key
+ else
+ choice = show_radial_menu(user, src, options, require_near = TRUE) // No telekinetics.
+
+ switch(choice)
+ if("install input")
+ if(!InputBeaker)
+ user.drop_from_inventory(W)
+ W.add_fingerprint(user)
+ W.forceMove(src)
+ InputBeaker = W
+
+ if("install output")
+ if(!OutputBeaker)
+ user.drop_from_inventory(W)
+ W.add_fingerprint(user)
+ W.forceMove(src)
+ OutputBeaker = W
+
+ update_icon()
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/use_power(var/amount, var/chan = -1)
+ last_power_draw = amount
+ if(use_cell && cell && cell.charge)
+ var/cellcharge = cell.charge
+ cell.use(amount)
+
+ var/celldifference = max(0, cellcharge - cell.charge)
+
+ amount = celldifference
+
+ var/area/A = get_area(src)
+ if(!A || !isarea(A))
+ return
+ if(chan == -1)
+ chan = power_channel
+ A.use_power(amount, chan)
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/process()
+ ..()
+
+ var/run_pump = FALSE
+
+ if(InputBeaker || OutputBeaker)
+ run_pump = TRUE
+
+ var/avg_temp = 0
+ var/avg_pressure = 0
+
+ if(connected_port && connected_port.network.line_members.len)
+ var/list/members = list()
+ var/datum/pipe_network/Net = connected_port.network
+ members = Net.line_members.Copy()
+
+ for(var/datum/pipeline/Line in members)
+ avg_pressure += Line.air.return_pressure()
+ avg_temp += Line.air.temperature
+
+ avg_temp /= members.len
+ avg_pressure /= members.len
+
+ if(!powered())
+ on = FALSE
+
+ if(!on || (use_atmos && (!connected_port || avg_pressure < 1000)))
+ current_temp = round((current_temp + T20C) / 2)
+
+ else if(on)
+ if(!use_atmos)
+ if(current_temp != round(target_temp))
+ var/shift_mod = 0
+ if(current_temp < target_temp)
+ shift_mod = 1
+ else if(current_temp > target_temp)
+ shift_mod = -1
+ current_temp = CLAMP(round((current_temp + 1 * shift_mod) + (rand(-5, 5) / 10)), min_temp, max_temp)
+ use_power(power_rating * CELLRATE)
+ else if(connected_port && avg_pressure > 1000)
+ current_temp = round((current_temp + avg_temp) / 2)
+ else if(!run_pump)
+ visible_message("\The [src]'s motors wind down.")
+ on = FALSE
+
+ if(InputBeaker && Reservoir.reagents.total_volume < Reservoir.reagents.maximum_volume)
+ InputBeaker.reagents.trans_to_holder(Reservoir.reagents, amount = rand(10,20))
+
+ if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume)
+ use_power(power_rating * CELLRATE * 0.5)
+ Reservoir.reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5))
+
+ update_icon()
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/update_icon()
+ ..()
+ cut_overlays()
+
+ if(InputBeaker)
+ add_overlay(overlay_input_beaker)
+
+ if(OutputBeaker)
+ add_overlay(overlay_output_beaker)
+
+ if(on)
+ if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume)
+ add_overlay(overlay_dumping)
+ else if(current_temp == round(target_temp))
+ add_overlay(overlay_ready)
+ else if(current_temp < target_temp)
+ add_overlay(overlay_heating)
+ else
+ add_overlay(overlay_cooling)
+
+ else
+ add_overlay(overlay_off)
+
+ if(connected_port)
+ add_overlay(overlay_connected)
+
+/*
+ * Subtypes
+ */
+
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial
+ name = "industrial chemical distillery"
+ desc = "A gas-operated variant of a chemical distillery. Able to reach much higher, and lower, temperatures through the use of treated gas."
+
+ use_atmos = TRUE
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 92e01c8ede..3c9fdcba6f 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -44,7 +44,8 @@
/obj/machinery/smartfridge/,
/obj/machinery/biogenerator,
/obj/structure/frame,
- /obj/machinery/radiocarbon_spectrometer
+ /obj/machinery/radiocarbon_spectrometer,
+ /obj/machinery/portable_atmospherics/powered/reagent_distillery
)
/obj/item/weapon/reagent_containers/glass/Initialize()
diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm
new file mode 100644
index 0000000000..007669286e
--- /dev/null
+++ b/code/modules/reagents/reagent_containers/patch.dm
@@ -0,0 +1,82 @@
+
+/*
+ * Patches. A subtype of pills, in order to inherit the possible future produceability within chem-masters, and dissolving.
+ */
+
+/obj/item/weapon/reagent_containers/pill/patch
+ name = "patch"
+ desc = "A patch."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = null
+ item_state = "pill"
+
+ base_state = "patch"
+
+ possible_transfer_amounts = null
+ w_class = ITEMSIZE_TINY
+ slot_flags = SLOT_EARS
+ volume = 60
+
+ var/pierce_material = FALSE // If true, the patch can be used through thick material.
+
+/obj/item/weapon/reagent_containers/pill/patch/attack(mob/M as mob, mob/user as mob)
+ var/mob/living/L = user
+
+ if(M == L)
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting))
+ if(!affecting)
+ to_chat(user, "The limb is missing!")
+ return
+ if(affecting.status >= ORGAN_ROBOT)
+ to_chat(user, "\The [src] won't work on a robotic limb!")
+ return
+
+ if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material))
+ to_chat(user, "\The [src] can't be applied through such a thick material!")
+ return
+
+ to_chat(H, "\The [src] is placed on your [affecting].")
+ M.drop_from_inventory(src) //icon update
+ if(reagents.total_volume)
+ reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH)
+ qdel(src)
+ return 1
+
+ else if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/affecting = H.get_organ(check_zone(L.zone_sel.selecting))
+ if(!affecting)
+ to_chat(user, "The limb is missing!")
+ return
+ if(affecting.status >= ORGAN_ROBOT)
+ to_chat(user, "\The [src] won't work on a robotic limb!")
+ return
+
+ if(!H.can_inject(user, FALSE, L.zone_sel.selecting, pierce_material))
+ to_chat(user, "\The [src] can't be applied through such a thick material!")
+ return
+
+ user.visible_message("[user] attempts to place \the [src] onto [H]`s [affecting].")
+
+ user.setClickCooldown(user.get_attack_speed(src))
+ if(!do_mob(user, M))
+ return
+
+ user.drop_from_inventory(src) //icon update
+ user.visible_message("[user] applies \the [src] to [H].")
+
+ var/contained = reagentlist()
+ add_attack_logs(user,M,"Applied a patch containing [contained]")
+
+ to_chat(H, "\The [src] is placed on your [affecting].")
+ M.drop_from_inventory(src) //icon update
+
+ if(reagents.total_volume)
+ reagents.trans_to_mob(M, reagents.total_volume, CHEM_TOUCH)
+ qdel(src)
+
+ return 1
+
+ return 0
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index c0b647e53b..5ca47a6d3b 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -7,6 +7,9 @@
icon = 'icons/obj/chemical.dmi'
icon_state = null
item_state = "pill"
+
+ var/base_state = "pill"
+
possible_transfer_amounts = null
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
@@ -15,7 +18,7 @@
/obj/item/weapon/reagent_containers/pill/Initialize()
. = ..()
if(!icon_state)
- icon_state = "pill[rand(1, 4)]" //preset pills only use colour changing or unique icons
+ icon_state = "[base_state][rand(1, 4)]" //preset pills only use colour changing or unique icons
/obj/item/weapon/reagent_containers/pill/attack(mob/M as mob, mob/user as mob)
if(M == user)
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index b60b71cc4e..69b9937158 100755
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -1,7 +1,7 @@
/obj/structure/bigDelivery
desc = "A big wrapped package."
name = "large parcel"
- icon = 'icons/obj/storage.dmi'
+ icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit
icon_state = "deliverycloset"
var/obj/wrapped = null
density = 1
@@ -109,7 +109,7 @@
/obj/item/smallDelivery
desc = "A small wrapped package."
name = "small parcel"
- icon = 'icons/obj/storage.dmi'
+ icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit
icon_state = "deliverycrate3"
var/obj/item/wrapped = null
var/sortTag = null
diff --git a/code/modules/research/designs/illegal.dm b/code/modules/research/designs/illegal.dm
index 4e99fc8665..f0a50fa5dd 100644
--- a/code/modules/research/designs/illegal.dm
+++ b/code/modules/research/designs/illegal.dm
@@ -25,3 +25,11 @@
materials = list(MAT_PLASTEEL = 3500, "glass" = 1000, MAT_LEAD = 2250, MAT_METALHYDROGEN = 500)
build_path = /obj/item/weapon/melee/energy/sword/charge
sort_string = "VASCA"
+
+/datum/design/item/weapon/eaxe
+ name = "Energy Axe"
+ id = "chargeaxe"
+ req_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 5, TECH_ENGINEERING = 4, TECH_ILLEGAL = 4)
+ materials = list(MAT_PLASTEEL = 3500, MAT_OSMIUM = 2000, MAT_LEAD = 2000, MAT_METALHYDROGEN = 500)
+ build_path = /obj/item/weapon/melee/energy/axe/charge
+ sort_string = "VASCB"
diff --git a/code/modules/research/designs/mining_toys.dm b/code/modules/research/designs/mining_toys.dm
index f9b76032cb..c170cb827b 100644
--- a/code/modules/research/designs/mining_toys.dm
+++ b/code/modules/research/designs/mining_toys.dm
@@ -45,4 +45,12 @@
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2)
materials = list(DEFAULT_WALL_MATERIAL = 1000,"glass" = 1000)
build_path = /obj/item/device/depth_scanner
- sort_string = "KAAAF"
\ No newline at end of file
+ sort_string = "KAAAF"
+
+/datum/design/item/device/graviton_visor
+ desc = "Used to see via the complex interation of meson particles and graviton particles."
+ id = "graviton_goggles"
+ req_tech = list(TECH_MAGNET = 5, TECH_ENGINEERING = 3, TECH_BLUESPACE = 3, TECH_PHORON = 3)
+ materials = list(MAT_PLASTEEL = 2000, "glass" = 3000, MAT_PHORON = 1500)
+ build_path = /obj/item/clothing/glasses/graviton
+ sort_string = "KAAAG"
diff --git a/code/modules/research/designs/precursor.dm b/code/modules/research/designs/precursor.dm
index eaf7b3a923..bcf80b66a0 100644
--- a/code/modules/research/designs/precursor.dm
+++ b/code/modules/research/designs/precursor.dm
@@ -77,3 +77,12 @@
var/obj/item/I = build_path
desc = initial(I.desc)
..()
+
+/datum/design/item/anomaly/camotrap
+ name = "Chameleon Trap"
+ desc = "A self-miraging mechanical trap, capable of producing short bursts of electric current when triggered."
+ id = "hunt_trap"
+ materials = list(MAT_DURASTEEL = 3000, MAT_METALHYDROGEN = 1000, MAT_PHORON = 2000)
+ req_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 2)
+ build_path = /obj/item/weapon/beartrap/hunting
+ sort_string = "ARCAT"
diff --git a/code/modules/tables/presets.dm b/code/modules/tables/presets.dm
index 5d568d440e..085489b26a 100644
--- a/code/modules/tables/presets.dm
+++ b/code/modules/tables/presets.dm
@@ -58,6 +58,23 @@
material = get_material_by_name("wood")
..()
+/obj/structure/table/sifwoodentable
+ icon_state = "plain_preview"
+ color = "#824B28"
+
+/obj/structure/table/sifwoodentable/New()
+ material = get_material_by_name("alien wood")
+ ..()
+
+/obj/structure/table/sifwooden_reinforced
+ icon_state = "reinf_preview"
+ color = "#824B28"
+
+/obj/structure/table/sifwooden_reinforced/New()
+ material = get_material_by_name("alien wood")
+ reinforced = get_material_by_name(DEFAULT_WALL_MATERIAL)
+ ..()
+
/obj/structure/table/gamblingtable
icon_state = "gamble_preview"
@@ -177,6 +194,18 @@
material = get_material_by_name("wood")
..()
+/obj/structure/table/bench/sifwooden
+ icon_state = "plain_preview"
+ color = "#824B28"
+
+/obj/structure/table/bench/sifwooden/New()
+ material = get_material_by_name("alien wood")
+ ..()
+
+/obj/structure/table/bench/sifwooden/padded
+ icon_state = "padded_preview"
+ carpeted = 1
+
/obj/structure/table/bench/padded
icon_state = "padded_preview"
diff --git a/code/modules/tension/tension.dm b/code/modules/tension/tension.dm
index 82151a7e78..841d691037 100644
--- a/code/modules/tension/tension.dm
+++ b/code/modules/tension/tension.dm
@@ -69,7 +69,7 @@
var/friendly = threatened.faction == faction
- var/threat = guess_threat_level()
+ var/threat = guess_threat_level(threatened)
// Hurt entities contribute less tension.
threat *= health
@@ -99,7 +99,120 @@
return threat
+// Carbon / mostly Human threat check.
+/mob/living/carbon/get_threat(var/mob/living/threatened)
+ . = ..()
+ if(has_AI())
+ if(!ai_holder.hostile)
+ return 0
+
+ if(incapacitated(INCAPACITATION_DISABLED))
+ return 0
+
+ var/friendly = (IIsAlly(threatened) && a_intent == I_HELP)
+
+ var/threat = guess_threat_level(threatened)
+
+ threat *= health
+ threat /= getMaxHealth()
+
+ // Allies reduce tension instead of adding.
+ if(friendly)
+ threat = -threat
+
+ else
+ if(threatened.invisibility > see_invisible)
+ threat /= 2 // Target cannot be seen by src.
+ if(invisibility > threatened.see_invisible)
+ threat *= 2 // Target cannot see src.
+
+ // Handle statuses.
+ if(confused)
+ threat /= 2
+
+ if(has_modifier_of_type(/datum/modifier/berserk))
+ threat *= 2
+
+ return threat
+
+/mob/living/carbon/guess_threat_level(var/mob/living/threatened)
+ var/threat_guess = 0
+
+ // First lets consider their attack ability.
+ var/will_point_blank = FALSE
+ if(has_AI())
+ will_point_blank = ai_holder.pointblank
+
+ . = ..()
+
+ var/obj/item/I = get_active_hand()
+ if(!I || !istype(I))
+ var/damage_guess = 0
+ if(ishuman(src) && ishuman(threatened))
+ var/mob/living/carbon/human/H = src
+ var/datum/unarmed_attack/attack = H.get_unarmed_attack(threatened, BP_TORSO)
+ if(!attack)
+ damage_guess += 5
+
+ var/punch_damage = attack.get_unarmed_damage(H)
+ if(H.gloves)
+ if(istype(H.gloves, /obj/item/clothing/gloves))
+ var/obj/item/clothing/gloves/G = H.gloves
+ punch_damage += G.punch_force
+
+ damage_guess += punch_damage
+
+ else
+ damage_guess += 5
+
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.outgoing_melee_damage_percent))
+ damage_guess *= M.outgoing_melee_damage_percent
+
+ threat_guess += damage_guess
+
+ else
+ var/weapon_attack_speed = get_attack_speed(I) / (1 SECOND)
+ var/weapon_damage = I.force
+
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.outgoing_melee_damage_percent))
+ weapon_damage *= M.outgoing_melee_damage_percent
+
+ if(istype(I, /obj/item/weapon/gun))
+ will_point_blank = TRUE
+ var/obj/item/weapon/gun/G = I
+ var/obj/item/projectile/P
+
+ P = new G.projectile_type()
+
+ if(P) // Does the gun even have a projectile type?
+ weapon_damage = P.damage
+ if(will_point_blank && a_intent == I_HURT)
+ weapon_damage *= 1.5
+ weapon_attack_speed = G.fire_delay / (1 SECOND)
+ qdel(P)
+
+ var/average_damage = weapon_damage / weapon_attack_speed
+
+ threat_guess += average_damage
+
+ // Consider intent.
+ switch(a_intent)
+ if(I_HELP) // Not likely to fight us.
+ threat_guess *= 0.4
+ if(I_DISARM) // Might engage us, but unlikely to be with the intent to kill.
+ threat_guess *= 0.8
+ if(I_GRAB) // May try to restrain us. This is here for reference, or later tweaking if needed.
+ threat_guess *= 1
+ if(I_HURT) // May try to hurt us.
+ threat_guess *= 1.25
+
+ // Then consider their defense.
+ threat_guess += getMaxHealth() / 5 // 100 health translates to 20 threat.
+
+ return threat_guess
// Gives a rough idea of how much danger someone is in. Meant to be used for PvE things since PvP has too many unknown variables.
/mob/living/proc/get_tension()
diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm
index 45cbcd7a13..46e838d37a 100644
--- a/code/modules/vehicles/cargo_train.dm
+++ b/code/modules/vehicles/cargo_train.dm
@@ -1,7 +1,7 @@
/obj/vehicle/train/engine
name = "cargo train tug"
desc = "A ridable electric car designed for pulling cargo trolleys."
- icon = 'icons/obj/vehicles.dmi'
+ icon = 'icons/obj/vehicles_vr.dmi' //VOREStation Edit
icon_state = "cargo_engine"
on = 0
powered = 1
@@ -26,7 +26,7 @@
/obj/vehicle/train/trolley
name = "cargo train trolley"
- icon = 'icons/obj/vehicles.dmi'
+ icon = 'icons/obj/vehicles_vr.dmi' //VOREStation Edit
icon_state = "cargo_trailer"
anchored = 0
passenger_allowed = 0
@@ -34,7 +34,7 @@
load_item_visible = 1
load_offset_x = 0
- load_offset_y = 4
+ load_offset_y = 7 //VOREStation Edit
mob_offset_y = 8
//-------------------------------------------
@@ -44,7 +44,7 @@
..()
cell = new /obj/item/weapon/cell/high(src)
key = new key_type(src)
- var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
+ var/image/I = new(icon = 'icons/obj/vehicles_vr.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs //VOREStation edit
overlays += I
turn_off() //so engine verbs are correctly set
@@ -374,3 +374,17 @@
anchored = 0
else
anchored = 1
+
+// VOREStation Edit Start - Overlay stuff for the chair-like effect
+/obj/vehicle/train/engine/update_icon()
+ ..()
+ overlays = null
+ var/image/O = image(icon = 'icons/obj/vehicles_vr.dmi', icon_state = "cargo_engine_overlay", dir = src.dir)
+ O.layer = FLY_LAYER
+ O.plane = MOB_PLANE
+ overlays += O
+
+/obj/vehicle/train/engine/set_dir()
+ ..()
+ update_icon()
+// VOREStation Edit End - Overlay stuff for the chair-like effect
diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm
index 301d0841be..04e0baeaf8 100644
--- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm
+++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm
@@ -153,6 +153,9 @@
//Messages for smalls moving under larges
var/msg_owner_stepunder = "%owner runs between your legs." //Weird becuase in the case this is used, %owner is the 'bumper' (src)
var/msg_prey_stepunder = "You run between %prey's legs." //Same, inverse
+ hide_body_parts = list(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) //Exclude pelvis just in case.
+ clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi'
+ clip_mask_state = "taur_clip_mask_def" //Used to clip off the lower part of suits & uniforms.
/datum/sprite_accessory/tail/taur/roiz_long_lizard // Not ACTUALLY a taur, but it uses 32x64 so it wouldn't fit in tails.dmi, and having it as a tail bugs up the sprite.
name = "Long Lizard Tail (Roiz Lizden)"
@@ -438,6 +441,7 @@
ckeys_allowed = list("natje")
do_colouration = 0
can_ride = 0
+ clip_mask_state = "taur_clip_mask_alraune"
msg_prey_stepunder = "You run between %prey's vines."
@@ -468,4 +472,26 @@
ckeys_allowed = null
do_colouration = 1
extra_overlay = "alraunecolor_markings"
- extra_overlay_w = "alraunecolor_closed_markings"
\ No newline at end of file
+ extra_overlay_w = "alraunecolor_closed_markings"
+ clip_mask_state = "taur_clip_mask_alraune"
+
+/datum/sprite_accessory/tail/taur/wasp
+ name = "Wasp (dual color)"
+ icon_state = "wasp_s"
+ extra_overlay = "wasp_markings"
+ clip_mask_state = "taur_clip_mask_wasp"
+
+ msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!"
+ msg_prey_disarm_run = "%owner pushes you down to the ground with their leg!"
+
+ msg_owner_disarm_walk = "You firmly push your leg down on %prey, painfully but harmlessly pinning them to the ground!"
+ msg_prey_disarm_walk = "%owner firmly pushes their leg down on you, quite painfully but harmlessly pinning you to the ground!"
+
+ msg_owner_harm_walk = "You methodically place your leg down upon %prey's body, slowly applying pressure, crushing them against the floor!"
+ msg_prey_harm_walk = "%owner methodically places their leg upon your body, slowly applying pressure, crushing you against the floor!"
+
+ msg_owner_grab_success = "You pin %prey down on the ground with your front leg before using your other leg to pick them up, trapping them between two of your front legs!"
+ msg_prey_grab_success = "%owner pins you down on the ground with their front leg before using their other leg to pick you up, trapping you between two of their front legs!"
+
+ msg_owner_grab_fail = "You step down onto %prey, squishing them and forcing them down to the ground!"
+ msg_prey_grab_fail = "%owner steps down and squishes you with their leg, forcing you down to the ground!"
diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm
index 50b8d763a2..89f5e9c746 100644
--- a/code/modules/vore/appearance/sprite_accessories_vr.dm
+++ b/code/modules/vore/appearance/sprite_accessories_vr.dm
@@ -653,6 +653,9 @@
var/desc = "You should not see this..."
var/ani_state // State when wagging/animated
var/extra_overlay_w // Wagging state for extra overlay
+ var/list/hide_body_parts = list() //Uses organ tag defines. Bodyparts in this list do not have their icons rendered, allowing for more spriter freedom when doing taur/digitigrade stuff.
+ var/icon/clip_mask_icon = null //Icon file used for clip mask.
+ var/clip_mask_state = null //Icon state to generate clip mask. Clip mask is used to 'clip' off the lower part of clothing such as jumpsuits & full suits.
/datum/sprite_accessory/tail/invisible
name = "hide species-sprite tail"
@@ -950,6 +953,9 @@
icon_state = "satyr"
color_blend_mode = ICON_MULTIPLY
do_colouration = 1
+ hide_body_parts = list(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) //Exclude pelvis just in case.
+ clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi'
+ clip_mask_state = "taur_mask_def" //Used to clip off the lower part of suits & uniforms.
/datum/sprite_accessory/tail/tailmaw
name = "tailmaw, colorable"
diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm
index 0751209f12..da0133d719 100644
--- a/code/modules/vore/fluffstuff/custom_items_vr.dm
+++ b/code/modules/vore/fluffstuff/custom_items_vr.dm
@@ -2006,4 +2006,23 @@
/obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask/fluff/viktor/Initialize()
..()
- reagents.add_reagent("pwine", 60)
\ No newline at end of file
+ reagents.add_reagent("pwine", 60)
+
+//RadiantAurora: Tiemli Kroto
+/obj/item/clothing/glasses/welding/tiemgogs
+ name = "custom-fitted welding goggles"
+ desc = "A pair of thick, custom-fitted goggles with LEDs above the lenses. Ruggedly engraved below the lenses is the name 'Tiemli Kroto'."
+
+ icon = 'icons/vore/custom_items_vr.dmi'
+ icon_state = "tiemgogs"
+
+ icon_override = 'icons/vore/custom_clothes_vr.dmi'
+ icon_state = "tiemgogs"
+
+/obj/item/clothing/glasses/welding/tiemgogs/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
+ if(..())
+ if(H.ckey != "radiantaurora")
+ to_chat(H, "These don't look like they were made to fit you...")
+ return 0
+ else
+ return 1
diff --git a/code/modules/xenoarcheaology/finds/find_spawning.dm b/code/modules/xenoarcheaology/finds/find_spawning.dm
index 2c04d491d0..be86279b08 100644
--- a/code/modules/xenoarcheaology/finds/find_spawning.dm
+++ b/code/modules/xenoarcheaology/finds/find_spawning.dm
@@ -511,6 +511,16 @@
desc = new_item.desc
item_type = new_item.name
+ if(39)
+ // Telecube.
+ if(prob(25))
+ apply_prefix = FALSE
+ if(prob(75))
+ apply_image_decorations = TRUE
+ if(prob(25))
+ apply_material_decorations = FALSE
+ new_item = new /obj/item/weapon/telecube/randomized(src.loc)
+
if(istype(new_item, /obj/item/weapon/material))
var/new_item_mat = pickweight(
DEFAULT_WALL_MATERIAL = 80,
diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt
index 90c4941b59..833eee4b94 100644
--- a/config/alienwhitelist.txt
+++ b/config/alienwhitelist.txt
@@ -3,6 +3,7 @@ some~user - Species
911earlyarther - Xenomorph Hybrid
admiraldragon - Vox
aether_elemental - Daemon
+A Random Alien - Xenochimera
arokha - Protean
aruis - Diona
aruis - Xenochimera
@@ -12,6 +13,7 @@ bothnevarbackwards - Diona
cameron653 - Xenomorph Hybrid
funnyman2003 - Xenochimera
hawkerthegreat - Vox
+hollifex - Diona
inuzari - Diona
jademanique - Xenochimera
jemli - Gutter
diff --git a/html/changelogs/Mechoid - ExplorerExpansion.yml b/html/changelogs/Mechoid - ExplorerExpansion.yml
new file mode 100644
index 0000000000..25c5488d00
--- /dev/null
+++ b/html/changelogs/Mechoid - ExplorerExpansion.yml
@@ -0,0 +1,56 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Mechoid
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "Exosuits are now targetted by turrets again."
+ - tweak: "Mining charge strength lowered, price increased. Can be upgraded through R&D laser components."
+ - rscadd: "Searing damage type added. Energy axe now uses searing damage."
+ - rscadd: "Survey points added. Vendor added for explorer use. Costs are universally 'lower' compared to the mining vendor due to the rarity of points."
+ - rscadd: "Swiping an ID card on a cataloguer will transfer the points to the card."
+ - tweak: "Any melee energy weapon can now be made to use a cell and charge."
+ - rscadd: "Energy Axe prototype added to R&D."
+ - rscadd: "Anomalous 'hunting trap' added to R&D. Useful for an initial stun on mobs for explorer scanning."
+ - tweak: "Beartraps now stun for a quarter of a second, so they are actually useful again, due to resistability."
+ - rscadd: "Emergency welding pack added. Incredibly slow, but requires no protection."
+ - rscadd: "Random turf modifier added for mapping use. Random humanoid remains spawner added for mapping use."
+ - rscadd: "Plants under obj/structure/flora now can be made to be harvestable / forage-able."
+ - rscadd: "Sif trees now occasionally have fruit containing useful microbes. Microbes slow blood flow resulting in slower chemical absorption and blood loss."
+ - tweak: "Flora by default are now under mobs, on the same layer as turf decals. Flora can now also randomize their size, previously only codified in Sivian trees."
+ - rscadd: "Moss tendrils added to Sif, making eye-plants more rare."
+ - rscadd: "Multiple PoIs added. 'Blue shuttle down' variant, 'UFO Frigate', multiple geysers, cliffs, and two variants of SFR which take drastically different approaches to the SFR standard. A vault was added, too."
+ - tweak: "Vault PoIs are now in a template group."
+ - rscadd: "Generic AI-controlled humanoids added. Subtype made for use on Sif, clad in weak armor and temperature resistance, used as 'mindless clones'."
+ - rscadd: "More artifice added."
+ - tweak: "Fultons made to be [somewhat] sane. Now only useable planetside."
+ - tweak: "Graviton Visor moved to R&D from the mining equipment vendor. Silver and Diamond pickaxes removed."
diff --git a/html/changelogs/Mechoid - Promethean Organs.yml b/html/changelogs/Mechoid - Promethean Organs.yml
new file mode 100644
index 0000000000..c579478d5a
--- /dev/null
+++ b/html/changelogs/Mechoid - Promethean Organs.yml
@@ -0,0 +1,40 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Mechoid
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Added multiple new organs for Prometheans. Removing them will cause them to take large amounts of Toxloss untill they are Regenerated using the active regeneration verb."
+ - rscadd: "Organ: pneumatic network, a series of skeletal tubes with high pressure used to move nutrients and waste."
+ - rscadd: "Organs: -regenesis systems, different 'networks' of clumped cellular matter that allow Prometheans to recover rapidly from small injuries. Large or numerous injuries cause un-needed stress, and pain."
+ - bugfix: "Internal organs now properly add themselves to the internal organ-by-name list, the one referenced 99.9% of the time."
+ - tweak: "Active regeneration will now replace internal organs if they are nonexistant, as it does for limbs."
diff --git a/html/changelogs/Nalarac - Turret Shooting Downed People.yml b/html/changelogs/Nalarac - Turret Shooting Downed People.yml
new file mode 100644
index 0000000000..f950bbe9a1
--- /dev/null
+++ b/html/changelogs/Nalarac - Turret Shooting Downed People.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Nalarac
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Added setting for turrets to fire upon downed/laying targets."
diff --git a/html/changelogs/Woodrat - Uniform Fix.yml b/html/changelogs/Woodrat - Uniform Fix.yml
new file mode 100644
index 0000000000..e3bdaa68e9
--- /dev/null
+++ b/html/changelogs/Woodrat - Uniform Fix.yml
@@ -0,0 +1,38 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Woodrat
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Made the solgov uniforms use accessories for denoting department instead of having several different sprites in the uniform dmi folder."
+ - tweak: "Removed redundant solgov uniforms from uniform.dmi and moved the sprites for the solgov uniforms to their own dmi."
+ - bugfix: "Fixed storage vests and drop pouches disappearing when one rolls down a uniform."
\ No newline at end of file
diff --git a/html/create_object.html b/html/create_object.html
index f4e0aa8644..7ed93d9818 100644
--- a/html/create_object.html
+++ b/html/create_object.html
@@ -26,6 +26,7 @@