mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-18 13:06:56 +01:00
305 lines
11 KiB
Plaintext
305 lines
11 KiB
Plaintext
//* This file is explicitly licensed under the MIT license. *//
|
|
//* Copyright (c) 2023 Citadel Station developers. *//
|
|
|
|
/obj/item/frame2
|
|
name = "entity frame"
|
|
desc = "Why do you see this? Contact a coder."
|
|
icon = 'icons/modules/frames/base.dmi'
|
|
icon_state = "item"
|
|
|
|
item_flags = ITEM_NO_BLUDGEON
|
|
obj_rotation_flags = OBJ_ROTATION_ENABLED | OBJ_ROTATION_DEFAULTING
|
|
|
|
/// frame datum - set to typepath for initialization
|
|
var/datum/frame2/frame
|
|
/// our cached image for hover
|
|
var/image/hover_image
|
|
/// viewing clients
|
|
var/list/client/viewing
|
|
|
|
/obj/item/frame2/Initialize(mapload, datum/frame2/frame)
|
|
. = ..()
|
|
if(!isnull(frame))
|
|
src.frame = frame
|
|
if(ispath(src.frame))
|
|
src.frame = fetch_frame_datum(src.frame)
|
|
sync_frame(src.frame)
|
|
|
|
/obj/item/frame2/Destroy()
|
|
for(var/client/C as anything in viewing)
|
|
hide_frame_image(C)
|
|
return ..()
|
|
|
|
/obj/item/frame2/proc/sync_frame(datum/frame2/frame)
|
|
name = "[frame.name]"
|
|
icon = frame.icon
|
|
icon_state = "item"
|
|
w_class = frame.item_weight_class
|
|
weight_volume = frame.item_weight_volume
|
|
|
|
/obj/item/frame2/examine(mob/user, dist)
|
|
. = ..()
|
|
if(!frame.item_deploy_requires_tool)
|
|
if(frame.wall_frame)
|
|
. += SPAN_NOTICE("Use it on a wall, window, or other 'wall-like' object to attach the frame.")
|
|
else
|
|
. += SPAN_NOTICE("Use it in hand to deploy it in the direction you are looking at.")
|
|
if(frame.item_deploy_tool)
|
|
. += SPAN_NOTICE("Use a <b>[frame.item_deploy_tool]</b> on it to deploy it in its current direction.")
|
|
if(frame.item_recycle_tool)
|
|
. += SPAN_NOTICE("Use a <b>[frame.item_recycle_tool]</b> on it to deconstruct it back into material sheets.")
|
|
|
|
/obj/item/frame2/MouseEntered(location, control, params)
|
|
..()
|
|
if(!usr?.client)
|
|
return
|
|
show_frame_image(usr.client)
|
|
|
|
/obj/item/frame2/MouseExited(location, control, params)
|
|
..()
|
|
if(!usr?.client)
|
|
return
|
|
hide_frame_image(usr.client)
|
|
|
|
/obj/item/frame2/proc/show_frame_image(client/C)
|
|
LAZYDISTINCTADD(viewing, C)
|
|
C.images += get_hover_image()
|
|
RegisterSignal(C, COMSIG_PARENT_QDELETING, PROC_REF(on_client_delete))
|
|
|
|
/obj/item/frame2/proc/hide_frame_image(client/C)
|
|
LAZYREMOVE(viewing, C)
|
|
C.images -= get_hover_image()
|
|
UnregisterSignal(C, COMSIG_PARENT_QDELETING)
|
|
|
|
if(!length(viewing))
|
|
hover_image = null
|
|
|
|
/obj/item/frame2/proc/on_client_delete(datum/source)
|
|
hide_frame_image(source)
|
|
|
|
/obj/item/frame2/proc/get_hover_image()
|
|
if(isnull(hover_image))
|
|
// todo: big/multi-tile frame support
|
|
hover_image = image('icons/modules/frames/base.dmi', "arrow")
|
|
hover_image.loc = src
|
|
hover_image.filters = list(
|
|
filter(type = "outline", size = 1, color = "#aaffaa77"),
|
|
)
|
|
update_hover_image()
|
|
return hover_image
|
|
|
|
/obj/item/frame2/proc/update_hover_image()
|
|
if(isnull(hover_image))
|
|
return
|
|
hover_image.pixel_x = 0
|
|
hover_image.pixel_y = 0
|
|
switch(dir)
|
|
if(NORTH)
|
|
hover_image.pixel_y = 12
|
|
if(SOUTH)
|
|
hover_image.pixel_y = -12
|
|
if(EAST)
|
|
hover_image.pixel_x = 12
|
|
if(WEST)
|
|
hover_image.pixel_x = -12
|
|
|
|
/obj/item/frame2/setDir(ndir)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
update_hover_image()
|
|
|
|
/obj/item/frame2/on_attack_self(datum/event_args/actor/e_args)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(frame.item_deploy_requires_tool)
|
|
e_args.chat_feedback(SPAN_WARNING("[src] requires the use of a [frame.item_deploy_tool] to be deployed!"), src)
|
|
return TRUE
|
|
var/use_dir = e_args.performer.dir
|
|
//! shitcode for wallmounts
|
|
if(frame.wall_frame)
|
|
use_dir = turn(use_dir, 180)
|
|
//! end
|
|
if(!can_deploy(e_args, use_dir, e_args.performer.loc))
|
|
return TRUE
|
|
if(frame.item_deploy_time)
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] starts to deploy [src]."),
|
|
audible = SPAN_WARNING("You hear something being assembled."),
|
|
otherwise_self = SPAN_WARNING("You start to deploy [src]."),
|
|
)
|
|
log_construction(e_args, src, "started deploying")
|
|
if(!do_after(e_args.performer, frame.item_deploy_time, src, mobility_flags = MOBILITY_CAN_USE))
|
|
return TRUE
|
|
if(!attempt_deploy(e_args, use_dir = use_dir, use_loc = e_args.performer.loc))
|
|
return TRUE
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] deploys [src]."),
|
|
audible = SPAN_WARNING("You hear something finish being assembled."),
|
|
otherwise_self = SPAN_WARNING("You deploy [src]."),
|
|
)
|
|
return TRUE
|
|
|
|
/obj/item/frame2/afterattack(atom/target, mob/user, clickchain_flags, list/params)
|
|
if(!frame.wall_frame)
|
|
return ..()
|
|
if(!user.Adjacent(target))
|
|
return ..()
|
|
var/use_dir = get_dir(user, target)
|
|
var/datum/event_args/actor/e_args = new(user)
|
|
if(IS_DIAGONAL(use_dir))
|
|
e_args.chat_feedback(SPAN_WARNING("You must be standing cardinally to [target] to attempt a deployment there!"), src)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
//! shitcode for wallmounts
|
|
if(frame.wall_frame)
|
|
use_dir = turn(use_dir, 180)
|
|
//! end
|
|
if(frame.item_deploy_requires_tool)
|
|
e_args.chat_feedback(SPAN_WARNING("[src] requires the use of a [frame.item_deploy_tool] to be deployed!"), src)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(!can_deploy(e_args, use_dir, e_args.performer.loc))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(frame.item_deploy_time)
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] starts to deploy [src]."),
|
|
audible = SPAN_WARNING("You hear something being assembled."),
|
|
otherwise_self = SPAN_WARNING("You start to deploy [src]."),
|
|
)
|
|
log_construction(e_args, src, "started deploying")
|
|
if(!do_after(e_args.performer, frame.item_deploy_time, src, mobility_flags = MOBILITY_CAN_USE))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(!attempt_deploy(e_args, use_dir, use_loc = e_args.performer.loc))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] deploys [src]."),
|
|
audible = SPAN_WARNING("You hear something finish being assembled."),
|
|
otherwise_self = SPAN_WARNING("You deploy [src]."),
|
|
)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_DID_SOMETHING
|
|
|
|
/obj/item/frame2/proc/can_deploy(datum/event_args/actor/e_args, use_dir = src.dir, use_loc = src.loc, silent)
|
|
if(!isturf(use_loc))
|
|
if(!silent)
|
|
e_args?.chat_feedback(SPAN_WARNING("[src] must be on the floor to be deployed!"), src)
|
|
return FALSE
|
|
if(!frame.deployment_checks(src, use_loc, use_dir, e_args))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/item/frame2/proc/attempt_deploy(datum/event_args/actor/e_args, use_dir = src.dir, use_loc = src.loc, silent)
|
|
if(!can_deploy(e_args, use_dir, use_loc, silent))
|
|
return FALSE
|
|
return deploy(e_args, use_dir, use_loc)
|
|
|
|
/obj/item/frame2/proc/deploy(datum/event_args/actor/e_args, use_dir = src.dir, use_loc = src.loc)
|
|
if(!isturf(use_loc))
|
|
CRASH("non turf?")
|
|
frame.deploy_frame(src, e_args, use_loc, use_dir)
|
|
log_construction(e_args, src, "deployed")
|
|
|
|
/obj/item/frame2/context_menu_query(datum/event_args/actor/e_args)
|
|
. = ..()
|
|
.["deploy-frame"] = create_context_menu_tuple("deploy", image(src), 1, MOBILITY_CAN_USE)
|
|
|
|
/obj/item/frame2/context_menu_act(datum/event_args/actor/e_args, key)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
switch(key)
|
|
if("deploy-frame")
|
|
if(!e_args.performer.Reachability(src))
|
|
e_args.chat_feedback(SPAN_WARNING("You can't reach [src] right now!"), src)
|
|
return TRUE
|
|
var/use_dir = src.dir
|
|
//! shitcode for wallmounts
|
|
if(frame.wall_frame)
|
|
use_dir = turn(use_dir, 180)
|
|
//! end
|
|
if(frame.item_deploy_requires_tool)
|
|
e_args.chat_feedback(SPAN_WARNING("[src] requires the use of a [frame.item_deploy_tool] to be deployed!"), src)
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(!can_deploy(e_args, use_dir, loc))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(frame.item_deploy_time)
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] starts to deploy [src]."),
|
|
audible = SPAN_WARNING("You hear something being assembled."),
|
|
otherwise_self = SPAN_WARNING("You start to deploy [src]."),
|
|
)
|
|
log_construction(e_args, src, "started deploying")
|
|
if(!do_after(e_args.performer, frame.item_deploy_time, src, mobility_flags = MOBILITY_CAN_USE))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
attempt_deploy(e_args, use_dir = use_dir)
|
|
return TRUE
|
|
|
|
/obj/item/frame2/drop_products(method, atom/where)
|
|
. = ..()
|
|
frame.drop_deconstructed_products(method, where, null, list())
|
|
|
|
/obj/item/frame2/tool_act(obj/item/I, datum/event_args/actor/clickchain/e_args, function, flags, hint)
|
|
if(function == frame.item_recycle_tool)
|
|
if(frame.item_recycle_time)
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] starts to recycle [src]."),
|
|
audible = SPAN_WARNING("You hear someone starting to disassemble something."),
|
|
otherwise_self = SPAN_WARNING("You start to recycle [src]."),
|
|
)
|
|
log_construction(e_args, src, "started recycling")
|
|
if(!use_tool(function, I, e_args, flags, frame.item_recycle_time, frame.item_recycle_cost))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] disassembles [src] back into raw material."),
|
|
audible = SPAN_WARNING("You hear something being disassembled back into raw material."),
|
|
otherwise_self = SPAN_WARNING("You recycle [src] back into raw material."),
|
|
)
|
|
log_construction(e_args, src, "recycled")
|
|
deconstruct(ATOM_DECONSTRUCT_DISASSEMBLED)
|
|
qdel(src)
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(function == frame.item_deploy_tool)
|
|
if(frame.item_deploy_time)
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] starts to deploy [src]."),
|
|
audible = SPAN_WARNING("You hear something being assembled."),
|
|
otherwise_self = SPAN_WARNING("You start to deploy [src]."),
|
|
)
|
|
log_construction(e_args, src, "started deploying")
|
|
if(!use_tool(function, I, e_args, flags, frame.item_deploy_time, frame.item_deploy_cost))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
if(!attempt_deploy(e_args))
|
|
return CLICKCHAIN_DO_NOT_PROPAGATE
|
|
e_args.visible_feedback(
|
|
target = src,
|
|
range = MESSAGE_RANGE_CONSTRUCTION,
|
|
visible = SPAN_WARNING("[e_args.performer] deploys [src]."),
|
|
audible = SPAN_WARNING("You hear something finish being assembled."),
|
|
otherwise_self = SPAN_WARNING("You deploy [src]."),
|
|
)
|
|
return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE
|
|
return ..()
|
|
|
|
/obj/item/frame2/dynamic_tool_query(obj/item/I, datum/event_args/actor/clickchain/e_args, list/hint_images)
|
|
. = list()
|
|
if(frame.item_recycle_tool)
|
|
LAZYSET(.[frame.item_recycle_tool], "recycle", dyntool_image_neutral(frame.item_recycle_tool))
|
|
if(frame.item_deploy_tool)
|
|
LAZYSET(.[frame.item_deploy_tool], "deploy", dyntool_image_neutral(frame.item_deploy_tool))
|
|
return merge_double_lazy_assoc_list(., ..())
|