mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-24 06:56:43 +01:00
325 lines
11 KiB
Plaintext
325 lines
11 KiB
Plaintext
/obj/item/mirrortool
|
|
name = "mirror tool"
|
|
desc = "A tool for the installation and removal of Mirrors. The tool has a set of barbs for removing Mirrors from a body, and a slot for depositing it directly into a resleeving console."
|
|
icon = 'icons/obj/mirror.dmi'
|
|
icon_state = "mirrortool"
|
|
base_icon_state = "mirrortool"
|
|
item_state = "healthanalyzer"
|
|
slot_flags = SLOT_BELT
|
|
throw_force = 3
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
throw_speed = 5
|
|
throw_range = 10
|
|
materials_base = list(MAT_STEEL = 200)
|
|
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
|
item_flags = ITEM_NO_BLUDGEON | ITEM_ENCUMBERS_WHILE_HELD
|
|
|
|
var/obj/item/organ/internal/mirror/inserted_mirror
|
|
|
|
/obj/item/mirrortool/Destroy()
|
|
QDEL_NULL(inserted_mirror)
|
|
return ..()
|
|
|
|
/obj/item/mirrortool/drop_products(method, atom/where)
|
|
. = ..()
|
|
inserted_mirror?.forceMove(where)
|
|
|
|
/obj/item/mirrortool/Exited(atom/movable/AM, atom/newLoc)
|
|
..()
|
|
if(AM == inserted_mirror)
|
|
inserted_mirror = null
|
|
ui_update_mirror()
|
|
|
|
/obj/item/mirrortool/update_icon_state()
|
|
icon_state = inserted_mirror ? "mirrortool_loaded" : "mirrortool"
|
|
return ..()
|
|
|
|
/obj/item/mirrortool/using_item_on(obj/item/using, datum/event_args/actor/clickchain/clickchain, clickchain_flags)
|
|
. = ..()
|
|
if(. & CLICKCHAIN_FLAGS_INTERACT_ABORT)
|
|
return
|
|
if(istype(using, /obj/item/organ/internal/mirror))
|
|
if(inserted_mirror)
|
|
clickchain.chat_feedback(
|
|
SPAN_WARNING("[src] already has a mirror inside it."),
|
|
target = src,
|
|
)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_DID_SOMETHING
|
|
var/obj/item/organ/internal/mirror/mirror = using
|
|
if(!clickchain.performer.attempt_insert_item_for_installation(mirror, src))
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
clickchain.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_INVENTORY_SOFT,
|
|
visible = SPAN_NOTICE("[clickchain.performer] inserts [mirror] into [src]."),
|
|
)
|
|
if(!user_insert_mirror(mirror, clickchain))
|
|
clickchain.performer.put_in_hands_or_drop(mirror)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
|
|
/obj/item/mirrortool/using_as_item(atom/target, datum/event_args/actor/clickchain/clickchain, clickchain_flags)
|
|
. = ..()
|
|
if(. & CLICKCHAIN_FLAGS_INTERACT_ABORT)
|
|
return
|
|
if(istype(target, /obj/item/organ/internal/mirror))
|
|
var/obj/item/organ/internal/mirror/mirror = target
|
|
if(inserted_mirror)
|
|
clickchain.chat_feedback(
|
|
SPAN_WARNING("[src] already has an inserted mirror."),
|
|
target = src,
|
|
)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(mirror.inv_inside)
|
|
if(!mirror.inv_inside.owner.transfer_item_to_loc(mirror, src))
|
|
clickchain.chat_feedback(
|
|
SPAN_WARNING("[src] is stuck to [mirror.inv_inside.owner == clickchain.performer ? "your" : "[mirror.inv_inside.owner]'s"] hands."),
|
|
target = src,
|
|
)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
else
|
|
mirror.forceMove(src)
|
|
if(!user_insert_mirror(mirror, clickchain))
|
|
mirror.forceMove(drop_location())
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
else if(ismob(target))
|
|
var/mob/casted_mob = target
|
|
if(casted_mob.resleeving_supports_mirrors())
|
|
clickchain.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
visible = SPAN_WARNING("[clickchain.performer] aligns [src] with [target]'s spine..."),
|
|
)
|
|
if(!do_after(clickchain.performer, 3 SECONDS, target))
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(!inserted_mirror)
|
|
user_yank_mirror_from_mob(target, clickchain)
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
else
|
|
user_inject_mirror_into_mob(target, clickchain)
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
else
|
|
clickchain.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_ITEM_HARD,
|
|
visible = SPAN_WARNING("[clickchain.performer] briefly points [src] at [target]'s spine."),
|
|
otherwise_self = SPAN_WARNING("[src] makes a beep as you pass it over [target]'s spine. They (or their mind) are not compatible with mirrors."),
|
|
)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
|
|
/obj/item/mirrortool/on_attack_hand(datum/event_args/actor/clickchain/clickchain, clickchain_flags)
|
|
. = ..()
|
|
if(. & CLICKCHAIN_FLAGS_INTERACT_ABORT)
|
|
return
|
|
if(clickchain.initiator.is_holding_inactive(src))
|
|
user_remove_mirror(clickchain)
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
|
|
/obj/item/mirrortool/proc/user_yank_mirror_from_mob(mob/target, datum/event_args/actor/actor, silent) as /obj/item/organ/internal/mirror
|
|
if(inserted_mirror)
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
otherwise_self = SPAN_WARNING("[src] already has a mirror in it."),
|
|
visible = SPAN_WARNING("[src] makes a beep and disengages."),
|
|
)
|
|
return FALSE
|
|
if(!target.resleeving_get_mirror())
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
otherwise_self = SPAN_WARNING("[target] doesn't have a mirror."),
|
|
visible = SPAN_WARNING("[src] makes a beep and disengages."),
|
|
)
|
|
return FALSE
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
visible = SPAN_WARNING("[actor.performer] starts extracting [target]'s mirror with [src]!"),
|
|
)
|
|
if(!do_after(actor.performer, IS_DEAD(target) ? 2.5 SECONDS : 7.5 SECONDS, target))
|
|
return FALSE
|
|
if(inserted_mirror)
|
|
return FALSE
|
|
var/obj/item/organ/internal/mirror/removed = target.resleeving_remove_mirror()
|
|
if(!removed)
|
|
return FALSE
|
|
log_game("[actor.actor_log_string()] removed [key_name(target)]'s mirror with [src].")
|
|
if(!insert_mirror(removed, actor))
|
|
return FALSE
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
visible = SPAN_WARNING("[actor.performer] extracts [target]'s mirror with [src]!"),
|
|
)
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/proc/user_inject_mirror_into_mob(mob/target, datum/event_args/actor/actor, silent)
|
|
if(!inserted_mirror)
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
otherwise_self = SPAN_WARNING("[src] doesn't have a mirror in it."),
|
|
visible = SPAN_WARNING("[src] makes a beep and disengages."),
|
|
)
|
|
return FALSE
|
|
if(target.resleeving_get_mirror())
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
otherwise_self = SPAN_WARNING("[target] already has a mirror."),
|
|
visible = SPAN_WARNING("[src] makes a beep and disengages."),
|
|
)
|
|
return FALSE
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
visible = SPAN_WARNING("[actor.performer] starts injecting something with [src] into the base of [target]'s neck!"),
|
|
)
|
|
if(!do_after(actor.performer, IS_DEAD(target) ? 2.5 SECONDS : 7.5 SECONDS, target))
|
|
return FALSE
|
|
if(!inserted_mirror)
|
|
return FALSE
|
|
if(target.resleeving_get_mirror())
|
|
return FALSE
|
|
var/obj/item/organ/internal/mirror/inserting = remove_mirror(target, actor)
|
|
if(!inserting)
|
|
return FALSE
|
|
var/mirror_descriptor
|
|
if(!inserting.owner_mind_ref)
|
|
mirror_descriptor = "mirror was empty"
|
|
else if(target.resleeving_check_mind_belongs(inserting.owner_mind_ref.resolve()))
|
|
mirror_descriptor = "mirror is mismatched"
|
|
else
|
|
mirror_descriptor = "mirror seems to match"
|
|
if(!target.resleeving_insert_mirror(inserting))
|
|
inserting.forceMove(drop_location())
|
|
STACK_TRACE("mirror insert failed after PNR")
|
|
return FALSE
|
|
log_game("[actor.actor_log_string()] inserted a mirror into [key_name(target)] [src]; [mirror_descriptor].")
|
|
actor.visible_feedback(
|
|
target = target,
|
|
range = MESSAGE_RANGE_COMBAT_LOUD,
|
|
visible = SPAN_WARNING("[actor.performer] injects a mirror into the base of [target]'s neck!"),
|
|
)
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/proc/yank_mirror_from_mob(mob/target, datum/event_args/actor/actor, silent) as /obj/item/organ/internal/mirror
|
|
if(inserted_mirror)
|
|
return null
|
|
var/obj/item/organ/internal/mirror/removed = target.resleeving_remove_mirror(src)
|
|
if(!removed)
|
|
return null
|
|
insert_mirror(removed, actor)
|
|
return removed
|
|
|
|
/obj/item/mirrortool/proc/inject_mirror_into_mob(mob/target, datum/event_args/actor/actor, silent)
|
|
var/obj/item/organ/internal/mirror/inserting_mirror = inserted_mirror
|
|
if(!target.resleeving_insert_mirror(inserting_mirror))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/ui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "items/Mirrortool")
|
|
ui.open()
|
|
|
|
/obj/item/mirrortool/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state, datum/event_args/actor/actor)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
switch(action)
|
|
if("insert")
|
|
var/obj/item/organ/internal/mirror/held_mirror = actor.performer.get_active_held_item()
|
|
if(!held_mirror)
|
|
actor.chat_feedback(SPAN_WARNING("You aren't holding a mirror in your active hand."), target = src)
|
|
return TRUE
|
|
user_insert_mirror(held_mirror, actor)
|
|
return TRUE
|
|
if("eject")
|
|
if(!inserted_mirror)
|
|
return TRUE
|
|
user_remove_mirror(actor, actor.check_performer_reachability(src))
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/ui_static_data(mob/user, datum/tgui/ui)
|
|
. = ..()
|
|
.["mirror"] = ui_serialize_mirror()
|
|
|
|
/obj/item/mirrortool/proc/ui_update_mirror()
|
|
push_ui_data(data = list("mirror" = ui_serialize_mirror()))
|
|
|
|
/obj/item/mirrortool/proc/ui_serialize_mirror()
|
|
return inserted_mirror ? inserted_mirror.ui_serialize() : null
|
|
|
|
/obj/item/mirrortool/context_menu_act(datum/event_args/actor/e_args, key)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
switch(key)
|
|
if("eject-mirror")
|
|
user_remove_mirror(e_args)
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/context_menu_query(datum/event_args/actor/e_args)
|
|
. = ..()
|
|
if(inserted_mirror)
|
|
.["eject-mirror"] = create_context_menu_tuple("eject mirror", image(src), 0, MOBILITY_CAN_USE, FALSE)
|
|
|
|
/obj/item/mirrortool/proc/user_remove_mirror(datum/event_args/actor/actor, put_in_hands = TRUE)
|
|
if(!inserted_mirror)
|
|
actor.chat_feedback(
|
|
SPAN_WARNING("[src] doesn't have a mirror inserted."),
|
|
target = src,
|
|
)
|
|
return TRUE
|
|
var/obj/item/organ/internal/mirror/removed = remove_mirror(src, actor)
|
|
if(put_in_hands)
|
|
actor.performer.put_in_hands_or_drop(removed)
|
|
else
|
|
removed.forceMove(drop_location())
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/proc/remove_mirror(atom/new_loc, datum/event_args/actor/actor) as /obj/item/organ/internal/mirror
|
|
if(!inserted_mirror)
|
|
return null
|
|
var/obj/item/organ/internal/mirror/old_mirror = inserted_mirror
|
|
inserted_mirror = null
|
|
if(old_mirror.loc == src && new_loc)
|
|
old_mirror.forceMove(new_loc)
|
|
on_mirror_removed(old_mirror)
|
|
return old_mirror
|
|
|
|
/obj/item/mirrortool/proc/on_mirror_removed(obj/item/organ/internal/mirror/mirror)
|
|
ui_update_mirror()
|
|
update_icon()
|
|
|
|
/obj/item/mirrortool/proc/user_insert_mirror(obj/item/organ/internal/mirror/mirror, datum/event_args/actor/actor)
|
|
if(inserted_mirror)
|
|
actor.chat_feedback(
|
|
SPAN_WARNING("[src] already has a mirror."),
|
|
target = src,
|
|
)
|
|
return FALSE
|
|
if(!insert_mirror(mirror, actor))
|
|
return FALSE
|
|
actor.chat_feedback(
|
|
SPAN_NOTICE("You insert [mirror] into [src]."),
|
|
target = src,
|
|
)
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/proc/insert_mirror(obj/item/organ/internal/mirror/mirror, datum/event_args/actor/actor)
|
|
if(inserted_mirror)
|
|
return FALSE
|
|
if(mirror.loc != src)
|
|
mirror.forceMove(src)
|
|
inserted_mirror = mirror
|
|
on_mirror_inserted(mirror)
|
|
return TRUE
|
|
|
|
/obj/item/mirrortool/proc/on_mirror_inserted(obj/item/organ/internal/mirror/mirror)
|
|
ui_update_mirror()
|
|
update_icon()
|