diff --git a/code/game/machinery/computer/prisoner/_prisoner.dm b/code/game/machinery/computer/prisoner/_prisoner.dm
index 16369302c66..5785734a437 100644
--- a/code/game/machinery/computer/prisoner/_prisoner.dm
+++ b/code/game/machinery/computer/prisoner/_prisoner.dm
@@ -1,5 +1,5 @@
/obj/machinery/computer/prisoner
- interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_SET_MACHINE|INTERACT_MACHINE_REQUIRES_LITERACY
+ interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_LITERACY
/// ID card currently inserted into the computer.
VAR_FINAL/obj/item/card/id/advanced/prisoner/contained_id
diff --git a/code/game/objects/items/implants/implant_clown.dm b/code/game/objects/items/implants/implant_clown.dm
index cc5b52781b0..515a1b4d312 100644
--- a/code/game/objects/items/implants/implant_clown.dm
+++ b/code/game/objects/items/implants/implant_clown.dm
@@ -4,11 +4,9 @@
actions_types = null
/obj/item/implant/sad_trombone/get_data()
- var/dat = {"Implant Specifications:
- Name: Honk Co. Sad Trombone Implant
- Life: Activates upon death.
- "}
- return dat
+ return "Implant Specifications: \
+ Name: Honk Co. Sad Trombone Implant \
+ Life: Activates upon death. "
/obj/item/implant/sad_trombone/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
. = ..()
diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm
index 29627f377f2..25966a24c68 100644
--- a/code/game/objects/items/implants/implant_explosive.dm
+++ b/code/game/objects/items/implants/implant_explosive.dm
@@ -45,16 +45,14 @@
INVOKE_ASYNC(src, PROC_REF(activate), "death")
/obj/item/implant/explosive/get_data()
- var/dat = {"Implant Specifications:
- Name: Robust Corp RX-78 Employee Management Implant
- Life: Activates upon death.
- Important Notes: Explodes
-
- Implant Details:
- Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
- Special Features: Explodes
- "}
- return dat
+ return "Implant Specifications: \
+ Name: Robust Corp RX-78 Employee Management Implant \
+ Life: Activates upon death. \
+ Important Notes: Explodes \
+ \
+ Implant Details: \
+ Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death. \
+ Special Features: Explodes "
/obj/item/implant/explosive/activate(cause)
. = ..()
diff --git a/code/game/objects/items/implants/implant_freedom.dm b/code/game/objects/items/implants/implant_freedom.dm
index 671bbecf06b..af5d955dfbc 100644
--- a/code/game/objects/items/implants/implant_freedom.dm
+++ b/code/game/objects/items/implants/implant_freedom.dm
@@ -29,18 +29,15 @@
qdel(src)
/obj/item/implant/freedom/get_data()
- var/dat = {"
- Implant Specifications:
- Name: Freedom Beacon
- Life: Optimum [initial(uses)] uses
- Important Notes: Illegal
-
- Implant Details:
- Function: Transmits a specialized cluster of signals to override handcuff locking
- mechanisms. These signals will release any bindings on both the arms and legs.
- Disclaimer: Heavy-duty restraints such as straightjackets are deemed "too complex" to release from.
- "}
- return dat
+ return "Implant Specifications: \
+ Name: Freedom Beacon \
+ Life: Optimum [initial(uses)] uses \
+ Important Notes: Illegal \
+ \
+ Implant Details: \
+ Function: Transmits a specialized cluster of signals to override handcuff locking \
+ mechanisms. These signals will release any bindings on both the arms and legs. \
+ Disclaimer: Heavy-duty restraints such as straightjackets are deemed \"too complex\" to release from."
/obj/item/implanter/freedom
name = "implanter (freedom)"
diff --git a/code/game/objects/items/implants/implant_mindshield.dm b/code/game/objects/items/implants/implant_mindshield.dm
index 33bfafbbbdd..67b1f4c6d92 100644
--- a/code/game/objects/items/implants/implant_mindshield.dm
+++ b/code/game/objects/items/implants/implant_mindshield.dm
@@ -4,16 +4,15 @@
actions_types = null
/obj/item/implant/mindshield/get_data()
- var/dat = {"Implant Specifications:
- Name: Nanotrasen Employee Management Implant
- Life: Ten years.
- Important Notes: Personnel injected with this device are much more resistant to brainwashing.
-
- Implant Details:
- Function: Contains a small pod of nanobots that protects the host's mental functions from manipulation.
- Special Features: Will prevent and cure most forms of brainwashing.
- Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
- return dat
+ return "Implant Specifications: \
+ Name: Nanotrasen Employee Management Implant \
+ Life: Ten years. \
+ Important Notes: Personnel injected with this device are much more resistant to brainwashing. \
+ \
+ Implant Details: \
+ Function: Contains a small pod of nanobots that protects the host's mental functions from manipulation. \
+ Special Features: Will prevent and cure most forms of brainwashing. \
+ Integrity: Implant will last so long as the nanobots are inside the bloodstream."
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm
index 0d87ed6d973..f7d660e330b 100644
--- a/code/game/objects/items/implants/implant_misc.dm
+++ b/code/game/objects/items/implants/implant_misc.dm
@@ -5,12 +5,11 @@
actions_types = null
/obj/item/implant/weapons_auth/get_data()
- var/dat = {"Implant Specifications:
- Name: Firearms Authentication Implant
- Life: 4 hours after death of host
- Implant Details:
- Function: Allows operation of implant-locked weaponry, preventing equipment from falling into enemy hands."}
- return dat
+ return "Implant Specifications: \
+ Name: Firearms Authentication Implant \
+ Life: 4 hours after death of host \
+ Implant Details: \
+ Function: Allows operation of implant-locked weaponry, preventing equipment from falling into enemy hands."
/obj/item/implant/emp
name = "emp implant"
@@ -75,11 +74,10 @@
subspace_transmission = TRUE
/obj/item/implant/radio/get_data()
- var/dat = {"Implant Specifications:
- Name: Internal Radio Implant
- Life: 24 hours
- Implant Details: Allows user to use an internal radio, useful if user expects equipment loss, or cannot equip conventional radios."}
- return dat
+ return "Implant Specifications: \
+ Name: Internal Radio Implant \
+ Life: 24 hours \
+ Implant Details: Allows user to use an internal radio, useful if user expects equipment loss, or cannot equip conventional radios."
/obj/item/implanter/radio
name = "implanter (internal radio)"
diff --git a/code/game/objects/items/implants/implant_spell.dm b/code/game/objects/items/implants/implant_spell.dm
index 8005e1c56e9..a758cb72ac0 100644
--- a/code/game/objects/items/implants/implant_spell.dm
+++ b/code/game/objects/items/implants/implant_spell.dm
@@ -25,12 +25,11 @@
return ..()
/obj/item/implant/spell/get_data()
- var/dat = {"Implant Specifications:
- Name: Spell Implant
- Life: 4 hours after death of host
- Implant Details:
- Function: [spell_to_give ? "Allows a non-wizard to cast [spell_to_give] as if they were a wizard." : "None."]"}
- return dat
+ return "Implant Specifications: \
+ Name: Spell Implant \
+ Life: 4 hours after death of host \
+ Implant Details: \
+ Function: [spell_to_give ? "Allows a non-wizard to cast [spell_to_give] as if they were a wizard." : "None."]"
/obj/item/implant/spell/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
. = ..()
diff --git a/code/game/objects/items/implants/implantpad.dm b/code/game/objects/items/implants/implantpad.dm
index 59bf505d102..ae09f8675b6 100644
--- a/code/game/objects/items/implants/implantpad.dm
+++ b/code/game/objects/items/implants/implantpad.dm
@@ -3,76 +3,87 @@
desc = "Used to modify implants."
icon = 'icons/obj/devices/tool.dmi'
icon_state = "implantpad-0"
+ base_icon_state = "implantpad"
inhand_icon_state = "electronic"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
- var/obj/item/implantcase/case = null
+
+ ///The implant case currently inserted into the pad.
+ var/obj/item/implantcase/inserted_case
/obj/item/implantpad/update_icon_state()
- icon_state = "implantpad-[!QDELETED(case)]"
+ icon_state = "[base_icon_state]-[!isnull(inserted_case)]"
return ..()
/obj/item/implantpad/examine(mob/user)
. = ..()
+ if(!inserted_case)
+ . += span_info("It is currently empty.")
+ return
+
if(Adjacent(user))
- . += "It [case ? "contains \a [case]" : "is currently empty"]."
- if(case)
- . += span_info("Alt-click to remove [case].")
+ . += span_info("It contains \a [inserted_case].")
else
- if(case)
- . += span_warning("There seems to be something inside it, but you can't quite tell what from here...")
+ . += span_warning("There seems to be something inside it, but you can't quite tell what from here...")
+ . += span_info("Alt-click to remove [inserted_case].")
/obj/item/implantpad/Exited(atom/movable/gone, direction)
. = ..()
- if(gone == case)
- case = null
- update_appearance()
- updateSelfDialog()
+ if(gone == inserted_case)
+ inserted_case = null
+ update_appearance(UPDATE_ICON)
+
+/obj/item/implantpad/attackby(obj/item/implantcase/attacking_item, mob/user, params)
+ if(inserted_case || !istype(attacking_item))
+ return ..()
+ if(!user.transferItemToLoc(attacking_item, src))
+ return
+ user.balloon_alert(user, "case inserted")
+ inserted_case = attacking_item
+ update_static_data_for_all_viewers()
+ update_appearance(UPDATE_ICON)
/obj/item/implantpad/AltClick(mob/user)
- ..()
+ . = ..()
if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
- if(!case)
- to_chat(user, span_warning("There's no implant to remove from [src]."))
+ remove_implant(user)
+
+/obj/item/implantpad/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if (!ui)
+ ui = new(user, src, "ImplantPad", name)
+ ui.open()
+
+/obj/item/implantpad/ui_static_data(mob/user)
+ var/list/data = list()
+ data["has_case"] = !!inserted_case
+ if(!inserted_case)
+ return data
+ data["has_implant"] = !!inserted_case.imp
+ if(inserted_case.imp)
+ data["case_information"] = inserted_case.imp.get_data()
+ return data
+
+/obj/item/implantpad/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ var/mob/user = usr
+ if(action == "eject_implant")
+ remove_implant(user)
return
- user.put_in_hands(case)
-
+///Removes the implant from the pad and puts it in the user's hands if possible.
+/obj/item/implantpad/proc/remove_implant(mob/user)
+ if(!inserted_case)
+ user.balloon_alert(user, "no case inside!")
+ return FALSE
add_fingerprint(user)
- case.add_fingerprint(user)
-
- updateSelfDialog()
- update_appearance()
-
-/obj/item/implantpad/attackby(obj/item/implantcase/C, mob/user, params)
- if(istype(C, /obj/item/implantcase) && !case)
- if(!user.transferItemToLoc(C, src))
- return
- case = C
- updateSelfDialog()
- update_appearance()
- else
- return ..()
-
-/obj/item/implantpad/ui_interact(mob/user)
- if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
- user.unset_machine(src)
- user << browse(null, "window=implantpad")
- return
-
- user.set_machine(src)
- var/dat = "Implant Mini-Computer:"
- if(case)
- if(case.imp)
- if(istype(case.imp, /obj/item/implant))
- dat += case.imp.get_data()
- else
- dat += "The implant casing is empty."
- else
- dat += "Please insert an implant casing!"
- user << browse(dat, "window=implantpad")
- onclose(user, "implantpad")
+ inserted_case.add_fingerprint(user)
+ user.put_in_hands(inserted_case)
+ user.balloon_alert(user, "case removed")
+ update_appearance(UPDATE_ICON)
+ update_static_data_for_all_viewers()
+ return TRUE
diff --git a/code/game/objects/items/implants/security/implant_beacon.dm b/code/game/objects/items/implants/security/implant_beacon.dm
index dea6b4ed190..5851566d06a 100644
--- a/code/game/objects/items/implants/security/implant_beacon.dm
+++ b/code/game/objects/items/implants/security/implant_beacon.dm
@@ -9,15 +9,14 @@
var/lifespan_postmortem = 10 MINUTES
/obj/item/implant/beacon/get_data()
- var/dat = {"Implant Specifications:
- Name: Robust Corp JMP-21 Fugitive Retrieval Implant
- Life: Deactivates upon death after ten minutes, but remains within the body.
- Important Notes: N/A
-
- Implant Details:
- Function: Acts as a teleportation beacon that can be tracked by any standard bluespace transponder.
- Using this, you can teleport directly to whoever has this implant inside of them."}
- return dat
+ return "Implant Specifications: \
+ Name: Robust Corp JMP-21 Fugitive Retrieval Implant \
+ Life: Deactivates upon death after ten minutes, but remains within the body. \
+ Important Notes: N/A \
+ \
+ Implant Details: \
+ Function: Acts as a teleportation beacon that can be tracked by any standard bluespace transponder. \
+ Using this, you can teleport directly to whoever has this implant inside of them."
/obj/item/implant/beacon/is_shown_on_console(obj/machinery/computer/prisoner/management/console)
return TRUE
diff --git a/code/game/objects/items/implants/security/implant_chem.dm b/code/game/objects/items/implants/security/implant_chem.dm
index db41d8bcac2..bad6cca8c69 100644
--- a/code/game/objects/items/implants/security/implant_chem.dm
+++ b/code/game/objects/items/implants/security/implant_chem.dm
@@ -9,18 +9,17 @@
var/list/implant_sizes = list(1, 5, 10)
/obj/item/implant/chem/get_data()
- var/dat = {"Implant Specifications:
- Name: Robust Corp MJ-420 Prisoner Management Implant
- Life: Deactivates upon death but remains within the body.
- Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
- will suffer from an increased appetite.
- Implant Details:
- Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
- the implant releases the chemicals directly into the blood stream.
- Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
- Can only be loaded while still in its original case.
- Integrity: Implant will last so long as the subject is alive, breaking down and releasing all contents on death."}
- return dat
+ return "Implant Specifications: \
+ Name: Robust Corp MJ-420 Prisoner Management Implant \
+ Life: Deactivates upon death but remains within the body. \
+ Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject \
+ will suffer from an increased appetite. \
+ Implant Details: \
+ Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal \
+ the implant releases the chemicals directly into the blood stream. \
+ Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units. \
+ Can only be loaded while still in its original case. \
+ Integrity: Implant will last so long as the subject is alive, breaking down and releasing all contents on death."
/obj/item/implant/chem/is_shown_on_console(obj/machinery/computer/prisoner/management/console)
return is_valid_z_level(get_turf(console), get_turf(imp_in))
diff --git a/code/game/objects/items/implants/security/implant_exile.dm b/code/game/objects/items/implants/security/implant_exile.dm
index 5c33d146b3a..9c04f1f9d37 100644
--- a/code/game/objects/items/implants/security/implant_exile.dm
+++ b/code/game/objects/items/implants/security/implant_exile.dm
@@ -9,11 +9,10 @@
hud_icon_state = "hud_imp_exile"
/obj/item/implant/exile/get_data()
- var/dat = {"Implant Specifications:
- Name: Nanotrasen Employee Exile Implant
- Implant Details: The onboard gateway system has been modified to reject entry by individuals containing this implant.
- Additionally, station mining shuttles will lock their controls if handled by someone with this implant. "}
- return dat
+ return "Implant Specifications: \
+ Name: Nanotrasen Employee Exile Implant \
+ Implant Details: The onboard gateway system has been modified to reject entry by individuals containing this implant. \
+ Additionally, station mining shuttles will lock their controls if handled by someone with this implant. "
///Used to help the staff of the space hotel resist the urge to use the space hotel's incredibly alluring roundstart teleporter to ignore their flavor/greeting text and come to the station.
@@ -22,10 +21,9 @@
desc = "Uses impressive bluespace grounding techniques to deny the person implanted by this implant the ability to teleport (or be teleported). Used by certain slavers (or particularly strict employers) to keep their slaves from using teleporters to escape their grasp."
/obj/item/implant/exile/noteleport/get_data()
- var/dat = {"Implant Specifications:
- Name: Anti-Teleportation Implant
- Implant Details: Keeps the implantee from using most teleportation devices. In addition, it spoofs the implant signature of an exile implant to keep the implantee from using certain gateway systems. "}
- return dat
+ return "Implant Specifications: \
+ Name: Anti-Teleportation Implant \
+ Implant Details: Keeps the implantee from using most teleportation devices. In addition, it spoofs the implant signature of an exile implant to keep the implantee from using certain gateway systems. "
/obj/item/implant/exile/noteleport/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
. = ..()
diff --git a/code/game/objects/items/implants/security/implant_noteleport.dm b/code/game/objects/items/implants/security/implant_noteleport.dm
index be4ec29659a..b4795a7f797 100644
--- a/code/game/objects/items/implants/security/implant_noteleport.dm
+++ b/code/game/objects/items/implants/security/implant_noteleport.dm
@@ -7,11 +7,10 @@
hud_icon_state = "hud_imp_noteleport"
/obj/item/implant/teleport_blocker/get_data()
- var/dat = {"Implant Specifications:
- Name: Robust Corp EXP-001 'Bluespace Grounder'
- Implant Details: Upon implantation, grounds the user's bluespace signature to their currently occupied plane of existence.
- Most, if not all forms of teleportation on the implantee will be rendered ineffective. Useful for keeping especially slippery prisoners in place. "}
- return dat
+ return "Implant Specifications: \
+ Name: Robust Corp EXP-001 'Bluespace Grounder' \
+ Implant Details: Upon implantation, grounds the user's bluespace signature to their currently occupied plane of existence. \
+ Most, if not all forms of teleportation on the implantee will be rendered ineffective. Useful for keeping especially slippery prisoners in place. "
/obj/item/implant/teleport_blocker/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
. = ..()
diff --git a/code/game/objects/items/implants/security/implant_track.dm b/code/game/objects/items/implants/security/implant_track.dm
index 652d9d6507a..b95c0afa7d8 100644
--- a/code/game/objects/items/implants/security/implant_track.dm
+++ b/code/game/objects/items/implants/security/implant_track.dm
@@ -9,17 +9,16 @@
var/lifespan_postmortem = 10 MINUTES
/obj/item/implant/tracking/get_data()
- var/dat = {"Implant Specifications:
- Name: Robust Corp EYE-5 Convict Parole Implant
- Life: 10 minutes after death of host.
-
- Implant Details:
- Function: Continuously transmits low power signal. Can be tracked from a prisoner management console.
- Special Features:
- Neuro-Safe- Specialized shell absorbs excess voltages self-destructing the chip if
- a malfunction occurs thereby securing safety of subject. The implant will melt and
- disintegrate into bio-safe elements. "}
- return dat
+ return "Implant Specifications: \
+ Name: Robust Corp EYE-5 Convict Parole Implant \
+ Life: 10 minutes after death of host. \
+ \
+ Implant Details: \
+ Function: Continuously transmits low power signal. Can be tracked from a prisoner management console. \
+ Special Features: \
+ Neuro-Safe- Specialized shell absorbs excess voltages self-destructing the chip if \
+ a malfunction occurs thereby securing safety of subject. The implant will melt and \
+ disintegrate into bio-safe elements. "
/obj/item/implant/tracking/is_shown_on_console(obj/machinery/computer/prisoner/management/console)
if(imp_in.stat == DEAD && imp_in.timeofdeath + lifespan_postmortem < world.time)
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index cedfe77180e..6eefaffe61e 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -682,12 +682,11 @@
implant_color = "r"
/obj/item/implant/nuclear_operative/get_data()
- var/dat = {"Implant Specifications:
- Name: Suspicious Implant
- Life: UNKNOWN
- Implant Details:
- Function: Strange implant that seems to resist any attempts at scanning it."}
- return dat
+ return "Implant Specifications: \
+ Name: Suspicious Implant \
+ Life: UNKNOWN \
+ Implant Details: \
+ Function: Strange implant that seems to resist any attempts at scanning it."
/obj/item/implant/nuclear_operative/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
. = ..()
diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm
index 85d1ce7a00a..087718d14b3 100644
--- a/code/modules/mod/modules/module_pathfinder.dm
+++ b/code/modules/mod/modules/module_pathfinder.dm
@@ -94,10 +94,9 @@
return ..()
/obj/item/implant/mod/get_data()
- var/dat = {"Implant Specifications:
- Name: Nakamura Engineering Pathfinder Implant
- Implant Details: Allows for the recall of a Modular Outerwear Device by the implant owner at any time. "}
- return dat
+ return "Implant Specifications: \
+ Name: Nakamura Engineering Pathfinder Implant \
+ Implant Details: Allows for the recall of a Modular Outerwear Device by the implant owner at any time. "
/obj/item/implant/mod/proc/recall()
if(!module?.mod)
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index d294ac54bc7..41ed5a04457 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -1590,7 +1590,7 @@
if(loaded_item.custom_price)
return TRUE
-/obj/machinery/vending/custom/ui_interact(mob/user)
+/obj/machinery/vending/custom/ui_interact(mob/user, datum/tgui/ui)
if(!linked_account)
balloon_alert(user, "no registered owner!")
return FALSE
diff --git a/tgui/packages/tgui/interfaces/ImplantPad.tsx b/tgui/packages/tgui/interfaces/ImplantPad.tsx
new file mode 100644
index 00000000000..90ec17261f6
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ImplantPad.tsx
@@ -0,0 +1,55 @@
+import { BooleanLike } from '../../common/react';
+import { useBackend } from '../backend';
+import { Box, Button, Divider, Flex } from '../components';
+import { Window } from '../layouts';
+import { sanitizeText } from '../sanitize';
+
+type Data = {
+ has_case: BooleanLike;
+ has_implant: BooleanLike;
+ case_information: string;
+};
+
+export const ImplantPad = (props) => {
+ const { act, data } = useBackend();
+ const { has_case, has_implant, case_information } = data;
+ const textHtml = {
+ __html: sanitizeText(case_information),
+ };
+ return (
+
+
+
+
+ Implant Mini-Computer
+
+
+
+
+
+
+
+
+ {!has_case &&
+ 'No implant case detected. Please insert one to see its contents.'}
+ {!!has_case &&
+ !has_implant &&
+ 'Implant case does not have an implant. Please insert one to continue.'}
+ {!!has_case && !!has_implant && (
+
+ )}
+
+
+
+
+ );
+};