mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-26 06:40:08 +01:00
262 lines
8.2 KiB
Plaintext
262 lines
8.2 KiB
Plaintext
/obj/item/ghost_trap
|
|
name = "spectral trap"
|
|
desc = "A mechanically activated 'ghost trap'."
|
|
description_fluff = "A 'ghost trap' created by Krow Enterprise's Spectral Division. Used by self proclaimed ghost-hunters and \
|
|
paranormal investigators to supposedly capture spirits and specters."
|
|
throw_speed = 5
|
|
throw_range = 7
|
|
gender = PLURAL
|
|
icon = 'icons/obj/ghost_trap.dmi'
|
|
icon_state = "item"
|
|
randpixel = 0
|
|
center_of_mass_x = 0
|
|
center_of_mass_y = 0
|
|
throwforce = 0
|
|
w_class = ITEMSIZE_NORMAL
|
|
var/deployed = FALSE
|
|
///The entity we currently have captured.
|
|
var/datum/weakref/captured_entity
|
|
var/obj/item/radio/intercom/science/ghost_reporter
|
|
|
|
/obj/item/ghost_trap/Initialize(mapload)
|
|
. = ..()
|
|
if(deployed)
|
|
update_icon()
|
|
ghost_reporter = new(null)
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
var/static/list/ghost_signals = list(
|
|
COMSIG_GLOB_GHOST_CAPTURED = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_spectral_experiment),
|
|
COMSIG_GLOB_WIGHT_CAPTURED = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_spectral_experiment),
|
|
)
|
|
|
|
AddComponent(/datum/component/experiment_handler, \
|
|
allowed_experiments = list(/datum/experiment/ghost_capture), \
|
|
config_mode = EXPERIMENT_CONFIG_UI, \
|
|
config_flags = EXPERIMENT_CONFIG_ALWAYS_ACTIVE, \
|
|
experiment_signals = ghost_signals)
|
|
|
|
/obj/item/ghost_trap/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
var/mob/our_entity = captured_entity?.resolve()
|
|
if(our_entity)
|
|
REMOVE_TRAIT(our_entity, TRAIT_NO_TRANSFORM, src)
|
|
our_entity.forceMove(get_turf(src))
|
|
captured_entity = null
|
|
QDEL_NULL(ghost_reporter)
|
|
. = ..()
|
|
|
|
/obj/item/ghost_trap/verb/release_occupant()
|
|
set src in oview(1)
|
|
set category = "Object"
|
|
set name = "Relase Entity"
|
|
release_entity(usr)
|
|
|
|
/obj/item/ghost_trap/proc/release_entity(mob/living/user)
|
|
if(!isliving(user)) //no ghosts
|
|
return
|
|
|
|
if((user.loc == src))
|
|
to_chat(user, span_warning("You need to be outside \the [src] to do this."))
|
|
return
|
|
|
|
if(captured_entity)
|
|
var/mob/our_entity = captured_entity.resolve()
|
|
if(our_entity && (our_entity.loc == src))
|
|
REMOVE_TRAIT(our_entity, TRAIT_NO_TRANSFORM, src)
|
|
captured_entity = null
|
|
our_entity.forceMove(get_turf(src))
|
|
update_icon()
|
|
return
|
|
|
|
to_chat(user, span_info("There appears to be nothing in the trap!"))
|
|
return
|
|
|
|
/obj/item/ghost_trap/update_icon()
|
|
..()
|
|
|
|
if(deployed)
|
|
icon_state = "on"
|
|
return
|
|
|
|
if(captured_entity)
|
|
var/mob/our_entity = captured_entity.resolve()
|
|
if(our_entity)
|
|
icon_state = "item_captured"
|
|
return
|
|
|
|
icon_state = initial(icon_state)
|
|
return
|
|
icon_state = initial(icon_state)
|
|
|
|
|
|
/obj/item/ghost_trap/start_active
|
|
deployed = TRUE
|
|
|
|
/obj/item/ghost_trap/process()
|
|
if(captured_entity)
|
|
var/mob/our_entity = captured_entity.resolve()
|
|
if(our_entity && our_entity.loc != src)
|
|
REMOVE_TRAIT(our_entity, TRAIT_NO_TRANSFORM, src)
|
|
captured_entity = null
|
|
announce_escape(our_entity)
|
|
update_icon()
|
|
|
|
/obj/item/ghost_trap/proc/announce_escape(mob/our_entity)
|
|
var/area/our_area = get_area(src)
|
|
log_and_message_admins("[our_entity] escaped \the [name] at \the [our_area]", our_entity)
|
|
ghost_reporter.autosay("Attention: Spectral event detected. Captured entity at [our_area] has breached containment.", "Spectral Trap", "Science", using_map.get_map_levels(z))
|
|
|
|
/obj/item/ghost_trap/proc/can_use(mob/user)
|
|
return (user.IsAdvancedToolUser() && !isAI(user) && !user.stat && !user.restrained())
|
|
|
|
/obj/item/ghost_trap/attack_self(mob/user)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
if(captured_entity)
|
|
var/mob/our_entity = captured_entity.resolve()
|
|
if(our_entity)
|
|
to_chat(user, "You are unable to use \the [src]! It beeps that it an entity contained inside!")
|
|
return
|
|
|
|
if(!deployed && can_use(user))
|
|
user.visible_message(
|
|
span_danger("[user] starts to deploy \the [src]."),
|
|
span_danger("You begin deploying \the [src]!")
|
|
)
|
|
|
|
if(do_after(user, 6 SECONDS, target = src))
|
|
user.visible_message(
|
|
span_danger("[user] has deployed \the [src]."),
|
|
span_danger("You have deployed \the [src]!")
|
|
)
|
|
playsound(src, 'sound/machines/click.ogg', 70, 1)
|
|
|
|
deployed = TRUE
|
|
user.drop_from_inventory(src)
|
|
update_icon()
|
|
anchored = TRUE
|
|
log_and_message_admins("has set up a [name] at \the [get_area(loc)]", user)
|
|
|
|
/obj/item/ghost_trap/container_resist(mob/living/escapee)
|
|
if(!ismob(escapee))
|
|
return
|
|
visible_message(span_danger("Lights flicker and buzzers beep from \the [src], alerting that a containment breach is imminent!"))
|
|
if(do_after(escapee, 2 MINUTES, target = src)) //Escape!
|
|
REMOVE_TRAIT(escapee, TRAIT_NO_TRANSFORM, src)
|
|
captured_entity = null
|
|
escapee.forceMove(get_turf(src))
|
|
announce_escape(escapee)
|
|
visible_message(span_danger("A loud buzzer rings out as \the [src] suddenly opens, alerting that a containment breach has ocurred!"))
|
|
update_icon()
|
|
|
|
|
|
/obj/item/ghost_trap/attack_hand(mob/user)
|
|
if(has_buckled_mobs() && can_use(user))
|
|
user.visible_message(
|
|
span_notice("[user] begins freeing something from \the [src]."),
|
|
span_notice("You carefully begin to free something from \the [src]."),
|
|
)
|
|
if(do_after(user, 6 SECONDS, target = src))
|
|
user.visible_message(span_notice("Something has been freed from \the [src] by [user]."))
|
|
for(var/A in buckled_mobs)
|
|
unbuckle_mob(A)
|
|
anchored = FALSE
|
|
deployed = FALSE
|
|
else if(deployed && can_use(user))
|
|
user.visible_message(
|
|
span_danger("[user] starts to deactivate \the [src]."),
|
|
span_notice("You begin deactivate \the [src]!")
|
|
)
|
|
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
|
|
|
if(do_after(user, 6 SECONDS, target = src))
|
|
user.visible_message(
|
|
span_danger("[user] has deactivated \the [src]."),
|
|
span_notice("You have deactivated \the [src]!")
|
|
)
|
|
deployed = FALSE
|
|
anchored = FALSE
|
|
update_icon()
|
|
else
|
|
..()
|
|
|
|
/obj/item/ghost_trap/proc/catch_ghost(mob/passing_entity)
|
|
if(!ismob(passing_entity)) //wtf did you do
|
|
return
|
|
captured_entity = WEAKREF(passing_entity)
|
|
|
|
if(isliving(passing_entity))
|
|
var/mob/living/living_entity = passing_entity
|
|
var/datum/component/shadekin/SK = living_entity.get_shadekin_component()
|
|
living_entity.phase_in(get_turf(src), SK)
|
|
|
|
passing_entity.forceMove(src)
|
|
var/area/our_area = get_area(src)
|
|
ghost_reporter.autosay("Attention: Spectral event detected. Trap activated at [our_area.name]", "Spectral Trap", "Science", using_map.get_map_levels(z))
|
|
ADD_TRAIT(passing_entity, TRAIT_NO_TRANSFORM, src)
|
|
|
|
to_chat(passing_entity, span_danger("You feel a sudden sensation pulling you into \the [src]!"))
|
|
if(isobserver(passing_entity))
|
|
to_chat(passing_entity, span_info("((You are incapable of moving or 'jumping' to turf by clicking, but can still escape via teleport or orbit!))"))
|
|
|
|
SEND_SIGNAL(src, COMSIG_GLOB_GHOST_CAPTURED, passing_entity)
|
|
|
|
/obj/item/ghost_trap/Crossed(atom/movable/AM)
|
|
|
|
if(istype(AM, /obj/effect/shadow_wight))
|
|
SEND_SIGNAL(src, COMSIG_GLOB_WIGHT_CAPTURED, AM)
|
|
visible_message(span_danger("A flurry of beams shoot into the air from \the [src] and into [AM], capturing and disintegrating it!"))
|
|
return
|
|
|
|
if(!ismob(AM)) //Only affects mobs!
|
|
return
|
|
|
|
//Ghost catching.
|
|
var/mob/passing_entity = AM
|
|
if(isobserver(passing_entity))
|
|
var/mob/observer/dead/ghost = AM
|
|
if(ghost.admin_ghosted || !ghost.interact_with_world)
|
|
return
|
|
|
|
//Catching phasers.
|
|
if(!passing_entity.is_incorporeal())
|
|
return
|
|
|
|
if(deployed)
|
|
visible_message(span_danger("A flurry of beams shoot into the air from \the [src]!"))
|
|
SSmotiontracker.ping(src,100) // Clunk!
|
|
catch_ghost(passing_entity)
|
|
deployed = FALSE
|
|
anchored = FALSE
|
|
update_icon()
|
|
log_and_message_admins("has been captured at \the [get_area(loc)] by the [name], last touched by [forensic_data?.get_lastprint()]", passing_entity)
|
|
|
|
|
|
/obj/item/ghost_trap/verb/hidden_vore()
|
|
set src in oview(1)
|
|
set category = "Object"
|
|
set name = "Eat Entity"
|
|
eat_entity(usr)
|
|
|
|
/obj/item/ghost_trap/proc/eat_entity(mob/living/user)
|
|
if(!isliving(user)) //no ghosts
|
|
return
|
|
|
|
if((user in contents))
|
|
to_chat(user, span_warning("You need to be inside \the [src] to do this."))
|
|
return
|
|
|
|
if(captured_entity)
|
|
var/mob/our_entity = captured_entity.resolve()
|
|
if(our_entity && (our_entity.loc == src) && our_entity.devourable)
|
|
REMOVE_TRAIT(our_entity, TRAIT_NO_TRANSFORM, src)
|
|
captured_entity = null
|
|
user.begin_instant_nom(user, our_entity, user, user.vore_selected)
|
|
return
|
|
|
|
to_chat(user, span_info("There appears to be nothing in the trap to eat!"))
|
|
return
|