From ef06ade4c282f22f1a3686c48e916a5dba906277 Mon Sep 17 00:00:00 2001
From: Killian <49700375+KillianKirilenko@users.noreply.github.com>
Date: Sun, 25 Aug 2024 20:20:54 +0100
Subject: [PATCH] Research Samples (#16039)
* added research samples
* added research sample pois
* added research samples
remove placeholder tier icons, touch up the base placeholder icon, and replace the spawner icons
also adjusted the common/uncommon/rare spawner weights slightly
---
code/modules/samples/container.dm | 62 +++++
code/modules/samples/samples.dm | 263 ++++++++++++++++++
icons/obj/samples.dmi | Bin 0 -> 10727 bytes
maps/om_adventure/grasscave.dm | 20 ++
maps/om_adventure/pois/darktear_sample.dmm | 97 +++++++
maps/om_adventure/pois/fleshtear_samples.dmm | 123 ++++++++
maps/submaps/pois_vr/aerostat/RareSample.dmm | 47 ++++
.../submaps/pois_vr/aerostat/SamplePocket.dmm | 58 ++++
maps/submaps/pois_vr/aerostat/virgo2.dm | 16 ++
.../pois_vr/debris_field/_templates.dm | 15 +
.../pois_vr/debris_field/sample_asteroid1.dmm | 78 ++++++
.../pois_vr/debris_field/sample_asteroid2.dmm | 78 ++++++
.../pois_vr/debris_field/sample_asteroid3.dmm | 75 +++++
.../submaps/underdark_pois/_templates.dm | 10 +
.../underdark_pois/guardedsample_hard.dmm | 41 +++
.../underdark_pois/guardedsample_normal.dmm | 44 +++
vorestation.dme | 2 +
17 files changed, 1029 insertions(+)
create mode 100644 code/modules/samples/container.dm
create mode 100644 code/modules/samples/samples.dm
create mode 100644 icons/obj/samples.dmi
create mode 100644 maps/om_adventure/pois/darktear_sample.dmm
create mode 100644 maps/om_adventure/pois/fleshtear_samples.dmm
create mode 100644 maps/submaps/pois_vr/aerostat/RareSample.dmm
create mode 100644 maps/submaps/pois_vr/aerostat/SamplePocket.dmm
create mode 100644 maps/submaps/pois_vr/debris_field/sample_asteroid1.dmm
create mode 100644 maps/submaps/pois_vr/debris_field/sample_asteroid2.dmm
create mode 100644 maps/submaps/pois_vr/debris_field/sample_asteroid3.dmm
create mode 100644 maps/tether/submaps/underdark_pois/guardedsample_hard.dmm
create mode 100644 maps/tether/submaps/underdark_pois/guardedsample_normal.dmm
diff --git a/code/modules/samples/container.dm b/code/modules/samples/container.dm
new file mode 100644
index 00000000000..fe8c0f8bf24
--- /dev/null
+++ b/code/modules/samples/container.dm
@@ -0,0 +1,62 @@
+/obj/item/weapon/storage/sample_container
+ name = "sample container"
+ desc = "A small containment device used to safely collect and carry up to eight research samples. Has a loop for attaching to belts."
+ description_info = "You can use the sample container directly on a sample to quickly scoop it up, or on a tile to scoop up all samples on that tile. This negates the risk of hurting yourself if you don't have thick enough gloves to safely handle the samples!"
+ icon = 'icons/obj/samples.dmi'
+ icon_state = "sample_container_0"
+
+ w_class = ITEMSIZE_SMALL
+ slot_flags = SLOT_BELT
+ max_w_class = ITEMSIZE_TINY
+ storage_slots = 8
+ max_storage_space = ITEMSIZE_TINY * 8
+ var/lightcolor = "#EFF1BF"
+
+ drop_sound = 'sound/items/drop/gascan.ogg'
+ pickup_sound = 'sound/items/pickup/gascan.ogg'
+
+ can_hold = list(/obj/item/weapon/research_sample)
+
+/obj/item/weapon/storage/sample_container/update_icon()
+ ..()
+ icon_state = "sample_container_[contents.len]"
+ if(contents.len > 0)
+ set_light(1, contents.len, lightcolor)
+ else
+ set_light(0)
+
+/obj/item/weapon/storage/sample_container/afterattack(turf/T as turf, mob/user as mob)
+ for(var/obj/item/weapon/research_sample/S in T)
+ S.loc = src
+ update_icon()
+ to_chat(user, "You scoop \the [S] into \the [src].")
+
+//Splice research sample containers into the list of valid items for these belts *without* overriding the lists entirely
+/obj/item/weapon/storage/belt/explorer/New()
+ . = ..()
+ can_hold.Add(/obj/item/weapon/storage/sample_container)
+
+/obj/item/weapon/storage/belt/miner/New()
+ . = ..()
+ can_hold.Add(/obj/item/weapon/storage/sample_container)
+
+/obj/item/weapon/storage/belt/archaeology/New()
+ . = ..()
+ can_hold.Add(/obj/item/weapon/storage/sample_container)
+
+//ditto, lockers and redemption machines
+/obj/structure/closet/secure_closet/miner/Initialize()
+ . = ..()
+ starts_with += /obj/item/weapon/storage/sample_container
+
+/obj/structure/closet/secure_closet/xenoarchaeologist/Initialize()
+ . = ..()
+ starts_with += /obj/item/weapon/storage/sample_container
+
+/obj/machinery/mineral/equipment_vendor/Initialize(mapload)
+ . = ..()
+ prize_list["Gear"] += list(EQUIPMENT("Exotic Sample Container", /obj/item/weapon/storage/sample_container, 100))
+
+/obj/machinery/mineral/equipment_vendor/survey/Initialize(mapload)
+ . = ..()
+ prize_list["Gear"] += list(EQUIPMENT("Survey Tools - Exotic Sample Container", /obj/item/weapon/storage/sample_container, 100))
diff --git a/code/modules/samples/samples.dm b/code/modules/samples/samples.dm
new file mode 100644
index 00000000000..12f02edb7f5
--- /dev/null
+++ b/code/modules/samples/samples.dm
@@ -0,0 +1,263 @@
+/obj/item/weapon/research_sample
+ name = "research sample"
+ desc = "A curious sample of unknown material. Perhaps a scientist could tell you more about it?
It looks dangerous to handle without heavy gloves or other protective equipment."
+ icon = 'icons/obj/samples.dmi'
+ icon_state = "sample"
+ w_class = ITEMSIZE_TINY
+ var/tech_level = 0 //base level
+ var/rand_level = 0 //random level between 0 and this value is added during spawn, if the techgroup is randomized
+ var/fixed_tech = null //do we have a predetermined tech-group, per request? if so, overrides randomization for icon and name
+ var/rand_tech = null //randomized tech-group from the list below
+ var/list/valid_techs = list(TECH_COMBAT,TECH_MAGNET,TECH_POWER,TECH_BIO,TECH_DATA,TECH_ENGINEERING,TECH_PHORON,TECH_MATERIAL,TECH_BLUESPACE,TECH_ILLEGAL,TECH_ARCANE,TECH_PRECURSOR)
+ origin_tech = list() //blank list creation, or else we get a runtime trying to assign the new techgroup
+
+ persist_storable = FALSE //don't shove hazardous shinies into the item bank!! also their properties are (usually) randomized on creation, so saving them is pointless-- you won't get out what you put in
+
+ //handling requirements; you need gloves with a low permeability threshold, RIG gauntlets, or luck- otherwise you get hand burns
+ var/handle_risk = 20 //20% chance to hurty if you handle it wrong
+ var/min_damage = 3 //min: 3 burn per hand
+ var/max_damage = 5 //max: 5 burn per hand
+
+ //resource returns when crunched; a small amount of OK stuff by default
+ var/min_ore = 3
+ var/max_ore = 5
+ var/list/resource_list = list(/obj/item/weapon/ore/glass,/obj/item/weapon/ore/coal,/obj/item/weapon/ore/iron,/obj/item/weapon/ore/lead,/obj/item/weapon/ore/marble,/obj/item/weapon/ore/phoron,/obj/item/weapon/ore/silver,/obj/item/weapon/ore/gold)
+
+/obj/item/weapon/research_sample/New()
+ var/tech_mod = rand(0,rand_level)
+ var/tech_value = tech_level+tech_mod
+ if(fixed_tech)
+ origin_tech.Add(list("[fixed_tech]" = tech_value))
+ else //if we're not a preset, randomize the name, icon, and associated tech, to make sure samples aren't predictable/metagamable
+ var/name_prefix = "[pick("strange","anomalous","exotic","atypical","unusual","incongruous","weird","aberrant","eccentric")]"
+ var/name_suffix //blank because it's randomized per sample appearance
+ var/sample_icon = rand(1,10)
+ icon_state = "generic_sample[sample_icon]"
+ //per-state tweaks, like glows/light emission or narrower valid tech defs
+ switch(sample_icon)
+ if(1) //prism
+ name_suffix = "[pick("alloy","object","sample","element","chunk")]"
+ if(2) //ring
+ name_suffix = "[pick("ring","band","torus","circuit","halo","hoop")]"
+ if(3) //red stone
+ name_suffix = "[pick("gem","crystal","jewel","stone","bauble","rock")]"
+ if(4) //circuit scrap
+ name_suffix = "[pick("circuit","board","scrap","junk","object","device")]"
+ if(5) //crystal star
+ name_suffix = "[pick("gem","crystal","jewel","stone","bauble","rock","star")]"
+ if(6) //spore
+ name_suffix = "[pick("glob","spore","blob","corpuscle","macroorganism","vacuole")]"
+ if(7) //device
+ name_suffix = "[pick("device","gadget","widget","object","apparatus","contraption","gizmo","object","doohickey")]"
+ if(8) //purple shard
+ name_suffix = "[pick("shard","fragment","sliver","remnant")]"
+ if(9) //purple rock
+ name_suffix = "[pick("rock","stone","slab","rubble","mineral","mass","boulder","slag")]"
+ if(10) //green rock
+ name_suffix = "[pick("rock","stone","slab","rubble","mineral","mass","boulder","slag")]"
+ else //none
+ name_suffix = "[pick("object","sample","thing","fragment","specimen","element","alloy","chunk","remnant","scrap","sliver")]"
+ name = "[name_prefix] [name_suffix]"
+ rand_tech = pick(valid_techs) //assign techs last
+ origin_tech.Add(list("[rand_tech]" = tech_value))
+
+/obj/item/weapon/research_sample/attack_hand(mob/user)
+ . = ..()
+ var/mob/living/M = user
+ if(!istype(M))
+ return
+
+ var/burn_user = TRUE
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/clothing/gloves/G = H.gloves
+ if(istype(G) && (G.permeability_coefficient < 0.25) || !prob(handle_risk) || istype(G, /obj/item/clothing/gloves/gauntlets))
+ burn_user = FALSE
+
+ if(burn_user)
+ H.visible_message("\The [src] flashes as it scorches [H]'s hands!")
+ H.apply_damage(rand(min_damage,max_damage), BURN, "r_hand", used_weapon="Anomalous Material")
+ H.apply_damage(rand(min_damage,max_damage), BURN, "l_hand", used_weapon="Anomalous Material")
+ H.drop_from_inventory(src, get_turf(H))
+ return
+
+ if(istype(user, /mob/living/silicon/robot))
+ burn_user = FALSE
+
+ if(burn_user)
+ M.apply_damage(rand(min_damage,max_damage), BURN, null, used_weapon="Anomalous Material")
+
+/obj/item/weapon/research_sample/attack_self(mob/user)
+ var/mob/living/M = user
+ if(!istype(M))
+ return
+
+ var/burn_user = TRUE
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/clothing/gloves/G = H.gloves
+ if(istype(G) && (G.permeability_coefficient < 0.25) || !prob(handle_risk) || istype(G, /obj/item/clothing/gloves/gauntlets))
+ burn_user = FALSE
+
+ if(burn_user)
+ H.visible_message("\The [src] flashes as it scorches [H]'s hands!")
+ H.apply_damage(rand(min_damage,max_damage), BURN, "r_hand", used_weapon="Anomalous Material")
+ H.apply_damage(rand(min_damage,max_damage), BURN, "l_hand", used_weapon="Anomalous Material")
+ H.drop_from_inventory(src, get_turf(H))
+ return
+
+ else if(do_after(user,3 SECONDS)) //short delay, so you can abort/cancel if you misclick
+ H.visible_message("[H] crushes \the [src], stabilizing its anomalous properties and rendering it into a pile of assorted minerals.")
+ var/i = rand(min_ore,max_ore)
+ while(i>1)
+ var/ore = pick(resource_list)
+ new ore(H.loc)
+ i--
+ H.drop_from_inventory(src,get_turf(H))
+ qdel(src)
+
+ if(istype(user, /mob/living/silicon/robot))
+ burn_user = FALSE
+
+ if(burn_user)
+ M.apply_damage(rand(min_damage,max_damage), BURN, null, used_weapon="Anomalous Material")
+
+/obj/item/weapon/research_sample/attackby(obj/item/weapon/P as obj, mob/user as mob)
+ ..()
+
+ if(istype(P, /obj/item/weapon/storage/sample_container))
+ var/obj/item/weapon/storage/sample_container/SC = P
+ src.loc = SC
+ SC.update_icon()
+ to_chat(user, "You store \the [src] in \the [SC].")
+
+ if(istype(P, /obj/item/device/cataloguer))
+ to_chat(user, "You start to scan \the [src] with \the [P]...")
+ if(do_after(user, 2 SECONDS))
+ to_chat(user, "\The [src] seems to have [origin_tech[1]] properties?")
+
+/obj/item/weapon/research_sample/common
+ tech_level = 2 //2~3
+ rand_level = 1
+ valid_techs = list(TECH_COMBAT,TECH_MAGNET,TECH_POWER,TECH_BIO,TECH_DATA,TECH_ENGINEERING,TECH_PHORON,TECH_MATERIAL)
+ catalogue_data = list(/datum/category_item/catalogue/information/research_sample/common)
+
+/obj/item/weapon/research_sample/uncommon
+ tech_level = 4 //4~6
+ rand_level = 2
+ valid_techs = list(TECH_COMBAT,TECH_MAGNET,TECH_POWER,TECH_BIO,TECH_DATA,TECH_ENGINEERING,TECH_PHORON,TECH_MATERIAL,TECH_BLUESPACE,TECH_ILLEGAL)
+ catalogue_data = list(/datum/category_item/catalogue/information/research_sample/uncommon)
+
+ handle_risk = 50
+ min_damage = 4
+ max_damage = 6
+
+ //modest amount of decent stuff
+ min_ore = 4
+ max_ore = 6
+ resource_list = list(/obj/item/weapon/ore/phoron,/obj/item/weapon/ore/silver,/obj/item/weapon/ore/gold,/obj/item/weapon/ore/osmium,/obj/item/weapon/ore/diamond)
+
+/obj/item/weapon/research_sample/rare
+ tech_level = 6 //6~8
+ rand_level = 2
+ valid_techs = list(TECH_COMBAT,TECH_MAGNET,TECH_POWER,TECH_BIO,TECH_DATA,TECH_ENGINEERING,TECH_PHORON,TECH_MATERIAL,TECH_BLUESPACE,TECH_ILLEGAL,TECH_ARCANE,TECH_PRECURSOR)
+ catalogue_data = list(/datum/category_item/catalogue/information/research_sample/rare)
+
+ handle_risk = 80
+ min_damage = 5
+ max_damage = 10
+
+ //a decent amount of rare stuff only
+ min_ore = 8
+ max_ore = 10
+ resource_list = list(/obj/item/weapon/ore/osmium,/obj/item/weapon/ore/uranium,/obj/item/weapon/ore/hydrogen,/obj/item/weapon/ore/diamond,/obj/item/weapon/ore/verdantium)
+
+/obj/item/weapon/research_sample/bluespace
+ name = "bluespace anomaly"
+ desc = "A small, solidified fragment of bluespace? It shimmers in and out of phase with reality, flickering ominously."
+ icon_state = "sample_bluespace"
+ tech_level = 6 //always 6
+ rand_level = 0
+ fixed_tech = TECH_BLUESPACE
+ var/lightcolor = "#0066CC"
+ catalogue_data = list(/datum/category_item/catalogue/information/research_sample/bluespace)
+
+ handle_risk = 80
+ min_damage = 5
+ max_damage = 10
+
+ //a single bluespace crystal
+ min_ore = 1
+ max_ore = 1
+ resource_list = list(/obj/item/weapon/bluespace_crystal)
+
+/obj/item/weapon/research_sample/bluespace/New()
+ ..()
+ set_light(1, 3, lightcolor)
+
+//catalogue data
+/datum/category_item/catalogue/information/research_sample/core_data
+ name = "Collection - Anomalous Matter"
+ desc = "Samples of various kinds of matter exposed to strange energy fields, exotic stellar radiation, or other unusual conditions, these objects are of great interest to most scientific institutions as they present novel research opportunities in a wide variety of fields, whether it's studying the material compositions themselves, the effects that exposure has had on them, or their other properties such as conductivity, flammability, and so on. There's no telling what kind of breakthroughs could be made.\
+
\
+ Perhaps the best known example of this type of object would be the now-ubiquitous Phoron. Whilst many of these samples are the equivalent of evolutionary \'dead ends\' in most respects, many can still yield intriguing results and unique possibilities - not to mention wealth and fame for those who discover a promising specimen.\
+
\
+ Their exact composition often varies wildly, which means handling them without protective equipment can be a risky endeavour."
+ value = CATALOGUER_REWARD_MEDIUM
+ unlocked_by_all = list(
+ /datum/category_item/catalogue/information/research_sample/common,
+ /datum/category_item/catalogue/information/research_sample/uncommon,
+ /datum/category_item/catalogue/information/research_sample/rare,
+ /datum/category_item/catalogue/information/research_sample/bluespace
+ )
+
+/datum/category_item/catalogue/information/research_sample/common
+ name = "Anomalous Sample - Common"
+ desc = "A chunk of mildly anomalous matter. It seems mostly safe to handle, but care should be taken nonetheless."
+ value = CATALOGUER_REWARD_EASY
+
+/datum/category_item/catalogue/information/research_sample/uncommon
+ name = "Anomalous Sample - Uncommon"
+ desc = "A chunk of moderately anomalous matter. Could be quite dangerous to handle unprotected."
+ value = CATALOGUER_REWARD_MEDIUM
+
+/datum/category_item/catalogue/information/research_sample/rare
+ name = "Anomalous Sample - Rare"
+ desc = "A chunk of exceptionally anomalous matter. It's likely very dangerous to handle without protective equipment."
+ value = CATALOGUER_REWARD_HARD
+
+/datum/category_item/catalogue/information/research_sample/bluespace
+ name = "Anomalous Sample - Bluespace"
+ desc = "A semi-crystalline particle of anomalous origin. Cataloguer sensors indicate it has extremely strong quasidimensional entanglements. Handling it without protective equipment is likely very unwise."
+ value = CATALOGUER_REWARD_HARD
+
+/obj/random/research_sample_type1
+ name = "Random Research Sample"
+ desc = "Spawns a random research sample of any quality."
+ icon = 'icons/obj/samples.dmi'
+ icon_state = "sample_spawner1"
+
+/obj/random/research_sample_type1/item_to_spawn()
+ return pick(prob(50);/obj/item/weapon/research_sample/common,
+ prob(35);/obj/item/weapon/research_sample/uncommon,
+ prob(15);/obj/item/weapon/research_sample/rare)
+
+/obj/random/research_sample_type2
+ name = "Random Common/Uncommon Research Sample"
+ desc = "Spawns a random research sample of common or uncommon quality."
+ icon = 'icons/obj/samples.dmi'
+ icon_state = "sample_spawner2"
+
+/obj/random/research_sample_type2/item_to_spawn()
+ return pick(prob(70);/obj/item/weapon/research_sample/common,
+ prob(30);/obj/item/weapon/research_sample/uncommon)
+
+/obj/random/research_sample_type3
+ name = "Random Uncommon/Rare Research Sample"
+ desc = "Spawns a random research sample of uncommon or rare quality."
+ icon = 'icons/obj/samples.dmi'
+ icon_state = "sample_spawner3"
+
+/obj/random/research_sample_type3/item_to_spawn()
+ return pick(prob(70);/obj/item/weapon/research_sample/uncommon,
+ prob(30);/obj/item/weapon/research_sample/rare)
diff --git a/icons/obj/samples.dmi b/icons/obj/samples.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..7fd6fa3bc6e53d5c9f3d18428a7e1eb78d62c166
GIT binary patch
literal 10727
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
literal 0
HcmV?d00001
diff --git a/maps/om_adventure/grasscave.dm b/maps/om_adventure/grasscave.dm
index b796c2081a2..be3a3ec2dc0 100644
--- a/maps/om_adventure/grasscave.dm
+++ b/maps/om_adventure/grasscave.dm
@@ -16,6 +16,8 @@
#include "pois/shuttlewreck2.dmm"
#include "pois/shuttlewreck3.dmm"
#include "pois/shuttlewreck4.dmm"
+#include "pois/darktear_sample.dmm"
+#include "pois/fleshtear_samples.dmm"
#endif
@@ -148,6 +150,15 @@
mappath = 'pois/darktear4.dmm'
cost = 5
+/area/om_adventure/poi/darktear_sample
+ name = "POI - Darktear Scientific"
+
+/datum/map_template/om_adventure/cave/darktear_sample
+ name = "darktear (Samples)" //1 uncommon-or-rare sample
+ desc = "Ooh, spooky"
+ mappath = 'pois/darktear_sample.dmm'
+ cost = 5
+
/area/om_adventure/poi/fleshtear1
name = "POI - Fleshtear 1"
@@ -184,6 +195,15 @@
mappath = 'pois/fleshtear4.dmm'
cost = 5
+/area/om_adventure/poi/fleshtear_samples
+ name = "POI - Fleshtear Scientific"
+
+/datum/map_template/om_adventure/cave/fleshtear_samples
+ name = "fleshtear (Samples)" //3 common/uncommon samples
+ desc = "Ooh, meaty"
+ mappath = 'pois/fleshtear_samples.dmm'
+ cost = 5
+
/area/om_adventure/poi/cabin1
name = "POI - Cabin 1"
diff --git a/maps/om_adventure/pois/darktear_sample.dmm b/maps/om_adventure/pois/darktear_sample.dmm
new file mode 100644
index 00000000000..689f9fe9364
--- /dev/null
+++ b/maps/om_adventure/pois/darktear_sample.dmm
@@ -0,0 +1,97 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/simulated/floor/weird_things/dark,
+/area/om_adventure/poi/darktear2)
+"t" = (
+/obj/random/research_sample_type3,
+/turf/simulated/floor/weird_things/dark,
+/area/om_adventure/poi/darktear2)
+"Q" = (
+/obj/tether_away_spawner/spookyland,
+/turf/simulated/floor/weird_things/dark,
+/area/om_adventure/poi/darktear2)
+"S" = (
+/turf/template_noop,
+/area/template_noop)
+
+(1,1,1) = {"
+a
+S
+S
+S
+S
+S
+S
+"}
+(2,1,1) = {"
+S
+a
+a
+S
+a
+a
+S
+"}
+(3,1,1) = {"
+S
+Q
+a
+a
+a
+S
+S
+"}
+(4,1,1) = {"
+S
+a
+a
+a
+a
+a
+S
+"}
+(5,1,1) = {"
+S
+S
+a
+t
+a
+a
+a
+"}
+(6,1,1) = {"
+a
+a
+a
+a
+a
+a
+S
+"}
+(7,1,1) = {"
+S
+S
+a
+a
+Q
+a
+S
+"}
+(8,1,1) = {"
+S
+a
+S
+a
+a
+a
+S
+"}
+(9,1,1) = {"
+S
+S
+S
+S
+S
+S
+a
+"}
diff --git a/maps/om_adventure/pois/fleshtear_samples.dmm b/maps/om_adventure/pois/fleshtear_samples.dmm
new file mode 100644
index 00000000000..3ba324d79e5
--- /dev/null
+++ b/maps/om_adventure/pois/fleshtear_samples.dmm
@@ -0,0 +1,123 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/obj/random/research_sample_type2,
+/turf/simulated/floor/flesh{
+ base_icon = 'icons/turf/stomach_vr.dmi'
+ },
+/area/om_adventure/poi/fleshtear3)
+"s" = (
+/mob/living/simple_mob/creature{
+ faction = "spookyland"
+ },
+/turf/simulated/floor/flesh{
+ base_icon = 'icons/turf/stomach_vr.dmi'
+ },
+/area/om_adventure/poi/fleshtear3)
+"Q" = (
+/turf/simulated/floor/flesh{
+ base_icon = 'icons/turf/stomach_vr.dmi'
+ },
+/area/om_adventure/poi/fleshtear3)
+
+(1,1,1) = {"
+a
+a
+Q
+Q
+Q
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+Q
+a
+a
+Q
+s
+Q
+Q
+a
+"}
+(3,1,1) = {"
+Q
+Q
+b
+a
+Q
+Q
+a
+Q
+a
+"}
+(4,1,1) = {"
+Q
+a
+Q
+Q
+Q
+Q
+a
+Q
+Q
+"}
+(5,1,1) = {"
+s
+a
+a
+a
+Q
+b
+a
+Q
+Q
+"}
+(6,1,1) = {"
+Q
+a
+Q
+Q
+Q
+a
+a
+a
+Q
+"}
+(7,1,1) = {"
+Q
+Q
+a
+b
+Q
+Q
+a
+Q
+Q
+"}
+(8,1,1) = {"
+a
+Q
+Q
+a
+Q
+Q
+s
+Q
+Q
+"}
+(9,1,1) = {"
+a
+a
+Q
+Q
+a
+Q
+Q
+Q
+a
+"}
diff --git a/maps/submaps/pois_vr/aerostat/RareSample.dmm b/maps/submaps/pois_vr/aerostat/RareSample.dmm
new file mode 100644
index 00000000000..02bcbd5ee86
--- /dev/null
+++ b/maps/submaps/pois_vr/aerostat/RareSample.dmm
@@ -0,0 +1,47 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/obj/item/weapon/research_sample/rare,
+/turf/simulated/mineral/floor/ignore_mapgen/virgo2,
+/area/template_noop)
+"c" = (
+/turf/simulated/mineral/floor/ignore_mapgen/virgo2,
+/area/template_noop)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+c
+a
+a
+"}
+(3,1,1) = {"
+a
+c
+b
+c
+a
+"}
+(4,1,1) = {"
+a
+a
+c
+a
+a
+"}
+(5,1,1) = {"
+a
+a
+a
+a
+a
+"}
diff --git a/maps/submaps/pois_vr/aerostat/SamplePocket.dmm b/maps/submaps/pois_vr/aerostat/SamplePocket.dmm
new file mode 100644
index 00000000000..5eb62d4e9a5
--- /dev/null
+++ b/maps/submaps/pois_vr/aerostat/SamplePocket.dmm
@@ -0,0 +1,58 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"c" = (
+/obj/random/research_sample_type2,
+/turf/simulated/mineral/floor/ignore_mapgen/virgo2,
+/area/template_noop)
+"d" = (
+/turf/simulated/mineral/floor/ignore_mapgen/virgo2,
+/area/template_noop)
+"i" = (
+/obj/random/research_sample_type3,
+/turf/simulated/mineral/floor/ignore_mapgen/virgo2,
+/area/template_noop)
+"C" = (
+/obj/random/research_sample_type1,
+/turf/simulated/mineral/floor/ignore_mapgen/virgo2,
+/area/template_noop)
+"Z" = (
+/turf/simulated/mineral/ignore_mapgen/virgo2,
+/area/template_noop)
+
+(1,1,1) = {"
+a
+Z
+Z
+Z
+a
+"}
+(2,1,1) = {"
+Z
+i
+d
+C
+Z
+"}
+(3,1,1) = {"
+Z
+d
+d
+d
+Z
+"}
+(4,1,1) = {"
+Z
+d
+c
+d
+Z
+"}
+(5,1,1) = {"
+a
+Z
+Z
+Z
+a
+"}
diff --git a/maps/submaps/pois_vr/aerostat/virgo2.dm b/maps/submaps/pois_vr/aerostat/virgo2.dm
index d2122ca2a8a..6fdc0c861b1 100644
--- a/maps/submaps/pois_vr/aerostat/virgo2.dm
+++ b/maps/submaps/pois_vr/aerostat/virgo2.dm
@@ -26,6 +26,8 @@
#include "Epod3.dmm"
#include "Epod4.dmm"
#include "ButcherShack.dmm"
+#include "RareSample.dmm"
+#include "SamplePocket.dmm"
#endif
/datum/map_template/virgo2
@@ -58,6 +60,20 @@
allow_duplicates = TRUE
cost = 5
+/datum/map_template/virgo2/RareSample
+ name = "Rocky1"
+ desc = "Ooh, shiny!" //a single rare sample, sitting in the open
+ mappath = 'RareSample.dmm'
+ allow_duplicates = TRUE
+ cost = 5
+
+/datum/map_template/virgo2/SamplePocket
+ name = "Sampleroid"
+ desc = "What's in the (rock)box?" //one common/uncommon, one uncommon/rare, and one any grade
+ mappath = 'SamplePocket.dmm'
+ allow_duplicates = TRUE
+ cost = 5
+
/datum/map_template/virgo2/Shack1
name = "Shack1"
desc = "A small shack in the middle of nowhere, Your halloween murder happens here"
diff --git a/maps/submaps/pois_vr/debris_field/_templates.dm b/maps/submaps/pois_vr/debris_field/_templates.dm
index 26d5e1d0ca5..28fd72ecbc4 100644
--- a/maps/submaps/pois_vr/debris_field/_templates.dm
+++ b/maps/submaps/pois_vr/debris_field/_templates.dm
@@ -53,6 +53,21 @@
mappath = 'asteroids10.dmm'
cost = 2
+/datum/map_template/debrisfield/sampleroid1 //2 common/uncommon samples
+ name = "Samples Rock 1"
+ mappath = 'sample_asteroid1.dmm'
+ cost = 5
+
+/datum/map_template/debrisfield/sampleroid2 //cluster of 3 commons
+ name = "Samples Rock 2"
+ mappath = 'sample_asteroid2.dmm'
+ cost = 5
+
+/datum/map_template/debrisfield/sampleroid3 //single rare surrounded by rock
+ name = "Samples Rock 3"
+ mappath = 'sample_asteroid3.dmm'
+ cost = 5
+
/datum/map_template/debrisfield/carp_asteroids1
name = "Carp Asteroids 1"
mappath = 'carp_asteroids1.dmm'
diff --git a/maps/submaps/pois_vr/debris_field/sample_asteroid1.dmm b/maps/submaps/pois_vr/debris_field/sample_asteroid1.dmm
new file mode 100644
index 00000000000..f8eb2219a56
--- /dev/null
+++ b/maps/submaps/pois_vr/debris_field/sample_asteroid1.dmm
@@ -0,0 +1,78 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/space)
+"b" = (
+/obj/random/research_sample_type2,
+/turf/simulated/mineral/floor/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+"c" = (
+/turf/simulated/mineral/floor/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+"d" = (
+/turf/simulated/mineral/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+d
+d
+d
+a
+a
+"}
+(3,1,1) = {"
+a
+d
+d
+b
+c
+d
+a
+"}
+(4,1,1) = {"
+a
+d
+c
+c
+c
+d
+a
+"}
+(5,1,1) = {"
+a
+d
+b
+c
+d
+d
+a
+"}
+(6,1,1) = {"
+a
+a
+d
+d
+d
+a
+a
+"}
+(7,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/maps/submaps/pois_vr/debris_field/sample_asteroid2.dmm b/maps/submaps/pois_vr/debris_field/sample_asteroid2.dmm
new file mode 100644
index 00000000000..df343792a49
--- /dev/null
+++ b/maps/submaps/pois_vr/debris_field/sample_asteroid2.dmm
@@ -0,0 +1,78 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/space)
+"b" = (
+/obj/item/weapon/research_sample/common,
+/turf/simulated/mineral/floor/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+"c" = (
+/turf/simulated/mineral/floor/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+"d" = (
+/turf/simulated/mineral/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+d
+d
+d
+a
+a
+"}
+(3,1,1) = {"
+a
+d
+b
+c
+c
+d
+a
+"}
+(4,1,1) = {"
+a
+d
+c
+c
+b
+d
+a
+"}
+(5,1,1) = {"
+a
+d
+c
+b
+c
+d
+a
+"}
+(6,1,1) = {"
+a
+a
+d
+d
+d
+a
+a
+"}
+(7,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/maps/submaps/pois_vr/debris_field/sample_asteroid3.dmm b/maps/submaps/pois_vr/debris_field/sample_asteroid3.dmm
new file mode 100644
index 00000000000..4de1c8b18de
--- /dev/null
+++ b/maps/submaps/pois_vr/debris_field/sample_asteroid3.dmm
@@ -0,0 +1,75 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/space)
+"c" = (
+/obj/item/weapon/research_sample/rare,
+/turf/simulated/mineral/floor/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+"d" = (
+/turf/simulated/mineral/vacuum,
+/area/tether_away/debrisfield/shuttle_buffer)
+
+(1,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
+(2,1,1) = {"
+a
+a
+d
+d
+d
+a
+a
+"}
+(3,1,1) = {"
+a
+d
+d
+d
+d
+d
+a
+"}
+(4,1,1) = {"
+a
+d
+d
+c
+d
+d
+a
+"}
+(5,1,1) = {"
+a
+d
+d
+d
+d
+d
+a
+"}
+(6,1,1) = {"
+a
+a
+d
+d
+d
+a
+a
+"}
+(7,1,1) = {"
+a
+a
+a
+a
+a
+a
+a
+"}
diff --git a/maps/tether/submaps/underdark_pois/_templates.dm b/maps/tether/submaps/underdark_pois/_templates.dm
index 6b250fb12ed..4af0b5b29a2 100644
--- a/maps/tether/submaps/underdark_pois/_templates.dm
+++ b/maps/tether/submaps/underdark_pois/_templates.dm
@@ -38,6 +38,16 @@
mappath = 'guardedloot_hard.dmm'
cost = 15
+/datum/map_template/underdark/guardedsample_normal
+ name = "Underdark Guarded Sample Normal" //2x common-or-uncommon
+ mappath = 'guardedsample_normal.dmm'
+ cost = 10
+
+/datum/map_template/underdark/guardedsample_hard
+ name = "Underdark Guarded Sample Hard" //uncommon-or-rare
+ mappath = 'guardedsample_hard.dmm'
+ cost = 15
+
/datum/map_template/underdark/blaster
name = "Underdark Blaster"
mappath = 'blaster.dmm'
diff --git a/maps/tether/submaps/underdark_pois/guardedsample_hard.dmm b/maps/tether/submaps/underdark_pois/guardedsample_hard.dmm
new file mode 100644
index 00000000000..b8d1ae4ec85
--- /dev/null
+++ b/maps/tether/submaps/underdark_pois/guardedsample_hard.dmm
@@ -0,0 +1,41 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/mine/explored/underdark)
+"b" = (
+/turf/simulated/mineral/floor/ignore_cavegen/virgo3b,
+/area/mine/explored/underdark)
+"c" = (
+/obj/tether_away_spawner/underdark_hard,
+/turf/simulated/mineral/floor/ignore_cavegen/virgo3b,
+/area/mine/explored/underdark)
+"d" = (
+/obj/random/research_sample_type3,
+/turf/simulated/mineral/floor/ignore_cavegen/virgo3b,
+/area/mine/explored/underdark)
+
+(1,1,1) = {"
+a
+a
+b
+"}
+(2,1,1) = {"
+b
+b
+b
+"}
+(3,1,1) = {"
+b
+d
+b
+"}
+(4,1,1) = {"
+c
+b
+a
+"}
+(5,1,1) = {"
+a
+b
+a
+"}
diff --git a/maps/tether/submaps/underdark_pois/guardedsample_normal.dmm b/maps/tether/submaps/underdark_pois/guardedsample_normal.dmm
new file mode 100644
index 00000000000..c830dceb9b2
--- /dev/null
+++ b/maps/tether/submaps/underdark_pois/guardedsample_normal.dmm
@@ -0,0 +1,44 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/mine/explored/underdark)
+"b" = (
+/turf/simulated/mineral/floor/ignore_cavegen/virgo3b,
+/area/mine/explored/underdark)
+"c" = (
+/obj/random/research_sample_type2,
+/turf/simulated/mineral/floor/ignore_cavegen/virgo3b,
+/area/mine/explored/underdark)
+"d" = (
+/obj/tether_away_spawner/underdark_normal,
+/turf/simulated/mineral/floor/ignore_cavegen/virgo3b,
+/area/mine/explored/underdark)
+
+(1,1,1) = {"
+a
+b
+b
+b
+a
+"}
+(2,1,1) = {"
+b
+b
+b
+c
+b
+"}
+(3,1,1) = {"
+a
+c
+b
+d
+b
+"}
+(4,1,1) = {"
+a
+a
+b
+b
+a
+"}
diff --git a/vorestation.dme b/vorestation.dme
index 15e1ac03c63..a135f1aafd0 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -3929,6 +3929,8 @@
#include "code\modules\rogueminer_vr\wrappers.dm"
#include "code\modules\rogueminer_vr\zone_console.dm"
#include "code\modules\rogueminer_vr\zonemaster.dm"
+#include "code\modules\samples\container.dm"
+#include "code\modules\samples\samples.dm"
#include "code\modules\scripting\Errors.dm"
#include "code\modules\scripting\IDE.dm"
#include "code\modules\scripting\Options.dm"