diff --git a/code/modules/catalogue/rewards/construction.dm b/code/modules/catalogue/rewards/construction.dm
new file mode 100644
index 0000000000..8bfca1f79d
--- /dev/null
+++ b/code/modules/catalogue/rewards/construction.dm
@@ -0,0 +1,12 @@
+#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
new file mode 100644
index 0000000000..929eac4972
--- /dev/null
+++ b/code/modules/catalogue/rewards/equipment_vendor.dm
@@ -0,0 +1,162 @@
+/**********************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.dmi'
+ icon_state = "mining"
+ density = TRUE
+ anchored = TRUE
+ circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor
+ var/icon_deny = "mining-deny"
+ 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, 10),
+ new /datum/data/exploration_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100),
+ new /datum/data/exploration_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300),
+ new /datum/data/exploration_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125),
+ new /datum/data/exploration_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125),
+ new /datum/data/exploration_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150),
+ new /datum/data/exploration_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200),
+ new /datum/data/exploration_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900),
+ new /datum/data/exploration_equipment("Plush Toy", /obj/random/plushie, 300),
+ new /datum/data/exploration_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 500),
+ new /datum/data/exploration_equipment("Point Transfer Card", /obj/item/weapon/card/exploration_point_card, 500),
+ new /datum/data/exploration_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 500),
+ new /datum/data/exploration_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200),
+ new /datum/data/exploration_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 1000),
+ new /datum/data/exploration_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500),
+ new /datum/data/exploration_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100)
+ )
+
+/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]!")
+ 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
new file mode 100644
index 0000000000..4c7ab307b7
--- /dev/null
+++ b/code/modules/catalogue/rewards/exp_point_items.dm
@@ -0,0 +1,23 @@
+/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 = 500
+
+/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/vorestation.dme b/vorestation.dme
index df0bbee341..7e509158d1 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1533,6 +1533,9 @@
#include "code\modules\catalogue\catalogue_data_vr.dm"
#include "code\modules\catalogue\cataloguer.dm"
#include "code\modules\catalogue\cataloguer_visuals.dm"
+#include "code\modules\catalogue\rewards\construction.dm"
+#include "code\modules\catalogue\rewards\equipment_vendor.dm"
+#include "code\modules\catalogue\rewards\exp_point_items.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\client\movement.dm"