diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index d5d4cd21760..42a418c7ad5 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -286,6 +286,7 @@
if (modify)
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])")
+ modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
return 1
diff --git a/code/game/machinery/computer/id_restorer_vr.dm b/code/game/machinery/computer/id_restorer_vr.dm
new file mode 100644
index 00000000000..86ffaa88bb7
--- /dev/null
+++ b/code/game/machinery/computer/id_restorer_vr.dm
@@ -0,0 +1,96 @@
+/obj/machinery/computer/id_restorer
+ name = "ID restoration terminal"
+ desc = "A terminal for restoration of damaged IDs. Mostly used for aftermath of unfortunate falls into vats of acid."
+ icon_state = "restorer"
+ icon_keyboard = null
+ light_color = "#11cc00"
+ layer = ABOVE_WINDOW_LAYER
+ icon_keyboard = null
+ icon = 'icons/obj/machines/id_restorer_vr.dmi'
+ density = FALSE
+ clicksound = null
+ circuit = /obj/item/weapon/circuitboard/id_restorer
+
+ var/icon_success = "restorer_success"
+ var/icon_fail = "restorer_fail"
+
+ var/obj/item/weapon/card/id/inserted
+
+/obj/machinery/computer/id_restorer/attackby(obj/I, mob/user)
+ if(istype(I, /obj/item/weapon/card/id) && !(istype(I,/obj/item/weapon/card/id/guest)))
+ if(!inserted && user.unEquip(I))
+ I.forceMove(src)
+ inserted = I
+ else if(inserted)
+ user << "There is already ID card inside."
+ return
+ ..()
+
+/obj/machinery/computer/id_restorer/attack_hand(mob/user)
+ if(..()) return
+ if(stat & (NOPOWER|BROKEN)) return
+
+ var/choice = alert(user,"What do you want to do?","[src]","Restore ID access","Eject ID","Cancel")
+ if(user.incapacitated() || (get_dist(src, user) > 1))
+ return
+ switch(choice)
+ if("Restore ID access")
+ if(!inserted)
+ to_chat(user, "No ID is inserted.")
+ return
+ var/mob/living/carbon/human/H = user
+ if(!(istype(H)))
+ to_chat(user, "Invalid user detected. Access denied.")
+ flick(icon_fail, src)
+ return
+ else if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE))) //Face hiding bad
+ to_chat(user, "Facial recognition scan failed due to physical obstructions. Access denied.")
+ flick(icon_fail, src)
+ return
+ else if(H.get_face_name() == "Unknown" || !(H.real_name == inserted.registered_name))
+ to_chat(user, "Facial recognition scan failed. Access denied.")
+ flick(icon_fail, src)
+ return
+ else if(LAZYLEN(inserted.lost_access) && !(LAZYLEN(inserted.access)))
+ inserted.access = inserted.lost_access
+ inserted.lost_access = list()
+ inserted.desc = "A partially digested card that has seen better days. The damage to access codes, however, appears to have been mitigated."
+ to_chat(user, "ID access codes successfully restored.")
+ flick(icon_success, src)
+ return
+ else if(!(LAZYLEN(inserted.lost_access)))
+ to_chat(user, "No recent access codes damage detected. Restoration cancelled.")
+ return
+ else
+ to_chat(user, "Terminal encountered unknown error. Contact system administrator or try again.")
+ flick(icon_fail, src)
+ return
+ if("Eject ID")
+ if(!inserted)
+ to_chat(user, "No ID is inserted.")
+ return
+ if(ishuman(user))
+ inserted.forceMove(get_turf(src))
+ if(!user.get_active_hand())
+ user.put_in_hands(inserted)
+ inserted = null
+ else
+ inserted.forceMove(get_turf(src))
+ inserted = null
+ return
+ if("Cancel")
+ return
+
+
+//Frame
+/datum/frame/frame_types/id_restorer
+ name = "ID Restoration Terminal"
+ frame_class = FRAME_CLASS_DISPLAY
+ frame_size = 2
+ frame_style = FRAME_STYLE_WALL
+ x_offset = 30
+ y_offset = 30
+ icon_override = 'icons/obj/machines/id_restorer_vr.dmi'
+
+/datum/frame/frame_types/id_restorer/get_icon_state(var/state)
+ return "restorer_b[state]"
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm b/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm
index fd2601c695d..0084e694777 100644
--- a/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm
+++ b/code/game/objects/items/weapons/circuitboards/circuitboards_vr.dm
@@ -53,3 +53,10 @@
build_path = /obj/machinery/computer/timeclock
board_type = new /datum/frame/frame_types/timeclock_terminal
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+
+// Board for the ID restorer in id_restorer_vr.dm
+/obj/item/weapon/circuitboard/id_restorer
+ name = T_BOARD("ID restoration console")
+ build_path = /obj/machinery/computer/id_restorer
+ board_type = new /datum/frame/frame_types/id_restorer
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
diff --git a/code/modules/vore/eating/digest_act_vr.dm b/code/modules/vore/eating/digest_act_vr.dm
index b78a91146d2..2467f5aaa29 100644
--- a/code/modules/vore/eating/digest_act_vr.dm
+++ b/code/modules/vore/eating/digest_act_vr.dm
@@ -71,11 +71,16 @@
id = null
. = ..()
+/obj/item/weapon/card/id
+ var/lost_access = list()
+
/obj/item/weapon/card/id/digest_act(var/atom/movable/item_storage = null)
desc = "A partially digested card that has seen better days. The damage appears to be only cosmetic, but the access codes need to be reprogrammed at the HoP office."
icon = 'icons/obj/card_vr.dmi'
icon_state = "[initial(icon_state)]_digested"
- access = list() // No access
+ if(!(LAZYLEN(lost_access)) && LAZYLEN(access))
+ lost_access = access //Do not forget what access we lose
+ access = list() // Then lose it
return FALSE
/obj/item/weapon/reagent_containers/food/digest_act(var/atom/movable/item_storage = null)
diff --git a/icons/obj/machines/id_restorer_vr.dmi b/icons/obj/machines/id_restorer_vr.dmi
new file mode 100644
index 00000000000..578d609e925
Binary files /dev/null and b/icons/obj/machines/id_restorer_vr.dmi differ
diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm
index 4e3384c073a..8ee0c1b9eac 100644
--- a/maps/tether/tether-05-station1.dmm
+++ b/maps/tether/tether-05-station1.dmm
@@ -8538,6 +8538,9 @@
/turf/simulated/floor/plating,
/area/crew_quarters/heads/hop)
"awH" = (
+/obj/machinery/light{
+ dir = 4
+ },
/obj/effect/floor_decal/industrial/loading,
/turf/simulated/floor/tiled,
/area/crew_quarters/heads/hop)
@@ -16238,7 +16241,10 @@
/obj/effect/floor_decal/steeldecal/steel_decals7{
dir = 1
},
-/obj/machinery/light,
+/obj/machinery/computer/id_restorer{
+ dir = 1;
+ pixel_y = -28
+ },
/turf/simulated/floor/tiled,
/area/hallway/station/atrium)
"beH" = (
diff --git a/vorestation.dme b/vorestation.dme
index c341a7ae51a..dc5d24740b0 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -774,6 +774,7 @@
#include "code\game\machinery\computer\computer.dm"
#include "code\game\machinery\computer\crew.dm"
#include "code\game\machinery\computer\guestpass.dm"
+#include "code\game\machinery\computer\id_restorer_vr.dm"
#include "code\game\machinery\computer\law.dm"
#include "code\game\machinery\computer\medical.dm"
#include "code\game\machinery\computer\message.dm"