tgui backend
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
/datum/wires/airlock/shell
|
||||
holder_type = /obj/machinery/door/airlock/shell
|
||||
proper_name = "Circuit Airlock"
|
||||
|
||||
/datum/wires/airlock/shell/on_cut(wire, mend)
|
||||
// Don't allow them to re-enable autoclose.
|
||||
if(wire == WIRE_TIMING)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/airlock/shell
|
||||
name = "circuit airlock"
|
||||
autoclose = FALSE
|
||||
|
||||
/obj/machinery/door/airlock/shell/Initialize()
|
||||
. = ..()
|
||||
AddComponent( \
|
||||
/datum/component/shell, \
|
||||
unremovable_circuit_components = list(new /obj/item/circuit_component/airlock), \
|
||||
capacity = SHELL_CAPACITY_LARGE, \
|
||||
shell_flags = SHELL_FLAG_ALLOW_FAILURE_ACTION \
|
||||
)
|
||||
|
||||
/obj/machinery/door/airlock/shell/check_access(obj/item/I)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/door/airlock/shell/canAIControl(mob/user)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/door/airlock/shell/canAIHack(mob/user)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/door/airlock/shell/set_wires()
|
||||
return new /datum/wires/airlock/shell(src)
|
||||
|
||||
/obj/item/circuit_component/airlock
|
||||
display_name = "Airlock"
|
||||
desc = "The general interface with an airlock. Includes general statuses of the airlock"
|
||||
|
||||
/// Called when attack_hand is called on the shell.
|
||||
var/obj/machinery/door/airlock/attached_airlock
|
||||
|
||||
/// Bolts the airlock (if possible)
|
||||
var/datum/port/input/bolt
|
||||
/// Unbolts the airlock (if possible)
|
||||
var/datum/port/input/unbolt
|
||||
/// Opens the airlock (if possible)
|
||||
var/datum/port/input/open
|
||||
/// Closes the airlock (if possible)
|
||||
var/datum/port/input/close
|
||||
|
||||
/// Contains whether the airlock is open or not
|
||||
var/datum/port/output/is_open
|
||||
/// Contains whether the airlock is bolted or not
|
||||
var/datum/port/output/is_bolted
|
||||
|
||||
/// Called when the airlock is opened.
|
||||
var/datum/port/output/opened
|
||||
/// Called when the airlock is closed
|
||||
var/datum/port/output/closed
|
||||
|
||||
/// Called when the airlock is bolted
|
||||
var/datum/port/output/bolted
|
||||
/// Called when the airlock is unbolted
|
||||
var/datum/port/output/unbolted
|
||||
|
||||
/obj/item/circuit_component/airlock/Initialize()
|
||||
. = ..()
|
||||
// Input Signals
|
||||
bolt = add_input_port("Bolt", PORT_TYPE_SIGNAL)
|
||||
unbolt = add_input_port("Unbolt", PORT_TYPE_SIGNAL)
|
||||
open = add_input_port("Open", PORT_TYPE_SIGNAL)
|
||||
close = add_input_port("Close", PORT_TYPE_SIGNAL)
|
||||
// States
|
||||
is_open = add_output_port("Is Open", PORT_TYPE_NUMBER)
|
||||
is_bolted = add_output_port("Is Bolted", PORT_TYPE_NUMBER)
|
||||
// Output Signals
|
||||
opened = add_output_port("Opened", PORT_TYPE_SIGNAL)
|
||||
closed = add_output_port("Closed", PORT_TYPE_SIGNAL)
|
||||
bolted = add_output_port("Bolted", PORT_TYPE_SIGNAL)
|
||||
unbolted = add_output_port("Unbolted", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/airlock/register_shell(atom/movable/shell)
|
||||
. = ..()
|
||||
if(istype(shell, /obj/machinery/door/airlock))
|
||||
attached_airlock = shell
|
||||
RegisterSignal(shell, COMSIG_AIRLOCK_SET_BOLT, .proc/on_airlock_set_bolted)
|
||||
RegisterSignal(shell, COMSIG_AIRLOCK_OPEN, .proc/on_airlock_open)
|
||||
RegisterSignal(shell, COMSIG_AIRLOCK_CLOSE, .proc/on_airlock_closed)
|
||||
|
||||
/obj/item/circuit_component/airlock/unregister_shell(atom/movable/shell)
|
||||
attached_airlock = null
|
||||
UnregisterSignal(shell, list(
|
||||
COMSIG_AIRLOCK_SET_BOLT,
|
||||
COMSIG_AIRLOCK_OPEN,
|
||||
COMSIG_AIRLOCK_CLOSE,
|
||||
))
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/airlock/proc/on_airlock_set_bolted(datum/source, should_bolt)
|
||||
SIGNAL_HANDLER
|
||||
is_bolted.set_output(should_bolt)
|
||||
if(should_bolt)
|
||||
bolted.set_output(COMPONENT_SIGNAL)
|
||||
else
|
||||
unbolted.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/airlock/proc/on_airlock_open(datum/source, force)
|
||||
SIGNAL_HANDLER
|
||||
is_open.set_output(TRUE)
|
||||
opened.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/airlock/proc/on_airlock_closed(datum/source, forced)
|
||||
SIGNAL_HANDLER
|
||||
is_open.set_output(FALSE)
|
||||
closed.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/airlock/input_received(datum/port/input/port)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(!attached_airlock)
|
||||
return
|
||||
|
||||
if(COMPONENT_TRIGGERED_BY(bolt, port))
|
||||
attached_airlock.bolt()
|
||||
if(COMPONENT_TRIGGERED_BY(unbolt, port))
|
||||
attached_airlock.unbolt()
|
||||
if(COMPONENT_TRIGGERED_BY(open, port) && attached_airlock.density)
|
||||
INVOKE_ASYNC(attached_airlock, /obj/machinery/door/airlock.proc/open)
|
||||
if(COMPONENT_TRIGGERED_BY(close, port) && !attached_airlock.density)
|
||||
INVOKE_ASYNC(attached_airlock, /obj/machinery/door/airlock.proc/close)
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* # Bot
|
||||
*
|
||||
* Immobile (but not dense) shells that can interact with world.
|
||||
*/
|
||||
/obj/structure/bot
|
||||
name = "bot"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_medium_box"
|
||||
|
||||
density = FALSE
|
||||
light_system = MOVABLE_LIGHT
|
||||
light_on = FALSE
|
||||
|
||||
/obj/structure/bot/Initialize()
|
||||
. = ..()
|
||||
AddComponent( \
|
||||
/datum/component/shell, \
|
||||
unremovable_circuit_components = list(new /obj/item/circuit_component/bot), \
|
||||
capacity = SHELL_CAPACITY_LARGE, \
|
||||
shell_flags = SHELL_FLAG_USB_PORT, \
|
||||
)
|
||||
|
||||
/obj/item/circuit_component/bot
|
||||
display_name = "Bot"
|
||||
desc = "Triggers when someone interacts with the bot."
|
||||
|
||||
/// Called when attack_hand is called on the shell.
|
||||
var/datum/port/output/signal
|
||||
/// The user who used the bot
|
||||
var/datum/port/output/entity
|
||||
|
||||
/obj/item/circuit_component/bot/Initialize()
|
||||
. = ..()
|
||||
entity = add_output_port("User", PORT_TYPE_ATOM)
|
||||
signal = add_output_port("Signal", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/bot/Destroy()
|
||||
signal = null
|
||||
entity = null
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/bot/register_shell(atom/movable/shell)
|
||||
RegisterSignal(shell, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
|
||||
|
||||
/obj/item/circuit_component/bot/unregister_shell(atom/movable/shell)
|
||||
UnregisterSignal(shell, COMSIG_ATOM_ATTACK_HAND)
|
||||
|
||||
/obj/item/circuit_component/bot/proc/on_attack_hand(atom/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
source.balloon_alert(user, "pushed button")
|
||||
playsound(source, get_sfx("terminal_type"), 25, FALSE)
|
||||
entity.set_output(user)
|
||||
signal.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
@@ -0,0 +1,553 @@
|
||||
/obj/item/organ/cyberimp/bci
|
||||
name = "brain-computer interface"
|
||||
desc = "An implant that can be placed in a user's head to control circuits using their brain."
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "bci"
|
||||
zone = BODY_ZONE_HEAD
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/organ/cyberimp/bci/Initialize()
|
||||
. = ..()
|
||||
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/bci_core,
|
||||
new /obj/item/circuit_component/bci_action(null, "One"),
|
||||
new /obj/item/circuit_component/bci_action(null, "Two"),
|
||||
new /obj/item/circuit_component/bci_action(null, "Three"),
|
||||
), SHELL_CAPACITY_SMALL)
|
||||
|
||||
/obj/item/organ/cyberimp/bci/Insert(mob/living/carbon/reciever, special, drop_if_replaced)
|
||||
. = ..()
|
||||
|
||||
// Organs are put in nullspace, but this breaks circuit interactions
|
||||
forceMove(reciever)
|
||||
|
||||
/obj/item/organ/cyberimp/bci/say(message, bubble_type, list/spans, sanitize, datum/language/language, ignore_spam, forced)
|
||||
if (owner)
|
||||
// Otherwise say_dead will be called.
|
||||
// It's intentional that a circuit for a dead person does not speak from the shell.
|
||||
if (owner.stat == DEAD)
|
||||
return
|
||||
|
||||
owner.say(message, forced = "circuit speech")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/bci_action
|
||||
display_name = "BCI Action"
|
||||
desc = "Represents an action the user can take when implanted with the brain-computer interface."
|
||||
required_shells = list(/obj/item/organ/cyberimp/bci)
|
||||
|
||||
/// The icon of the button
|
||||
var/datum/port/input/option/icon_options
|
||||
|
||||
/// The name to use for the button
|
||||
var/datum/port/input/button_name
|
||||
|
||||
/// Called when the user presses the button
|
||||
var/datum/port/output/signal
|
||||
|
||||
/// A reference to the action button itself
|
||||
var/datum/action/innate/bci_action/bci_action
|
||||
|
||||
/obj/item/circuit_component/bci_action/Initialize(mapload, default_icon)
|
||||
. = ..()
|
||||
|
||||
if (!isnull(default_icon))
|
||||
icon_options.set_input(default_icon)
|
||||
|
||||
button_name = add_input_port("Name", PORT_TYPE_STRING)
|
||||
|
||||
signal = add_output_port("Signal", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/bci_action/Destroy()
|
||||
QDEL_NULL(bci_action)
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/bci_action/populate_options()
|
||||
var/static/action_options = list(
|
||||
"Blank",
|
||||
|
||||
"One",
|
||||
"Two",
|
||||
"Three",
|
||||
"Four",
|
||||
"Five",
|
||||
|
||||
"Blood",
|
||||
"Bomb",
|
||||
"Brain",
|
||||
"Brain Damage",
|
||||
"Cross",
|
||||
"Electricity",
|
||||
"Exclamation",
|
||||
"Heart",
|
||||
"Id",
|
||||
"Info",
|
||||
"Injection",
|
||||
"Magnetism",
|
||||
"Minus",
|
||||
"Network",
|
||||
"Plus",
|
||||
"Power",
|
||||
"Question",
|
||||
"Radioactive",
|
||||
"Reaction",
|
||||
"Repair",
|
||||
"Say",
|
||||
"Scan",
|
||||
"Shield",
|
||||
"Skull",
|
||||
"Sleep",
|
||||
"Wireless",
|
||||
)
|
||||
|
||||
icon_options = add_option_port("Icon", action_options)
|
||||
|
||||
/obj/item/circuit_component/bci_action/register_shell(atom/movable/shell)
|
||||
var/obj/item/organ/cyberimp/bci/bci = shell
|
||||
|
||||
bci_action = new(src)
|
||||
update_action()
|
||||
|
||||
bci.actions += list(bci_action)
|
||||
|
||||
/obj/item/circuit_component/bci_action/unregister_shell(atom/movable/shell)
|
||||
var/obj/item/organ/cyberimp/bci/bci = shell
|
||||
|
||||
bci.actions -= bci_action
|
||||
QDEL_NULL(bci_action)
|
||||
|
||||
/obj/item/circuit_component/bci_action/input_received(datum/port/input/port)
|
||||
. = ..()
|
||||
|
||||
if (.)
|
||||
return
|
||||
|
||||
if (!isnull(bci_action))
|
||||
update_action()
|
||||
|
||||
/obj/item/circuit_component/bci_action/proc/update_action()
|
||||
bci_action.name = button_name.value
|
||||
bci_action.button_icon_state = "bci_[replacetextEx(lowertext(icon_options.value), " ", "_")]"
|
||||
|
||||
/datum/action/innate/bci_action
|
||||
name = "Action"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "bci_power"
|
||||
|
||||
var/obj/item/circuit_component/bci_action/circuit_component
|
||||
|
||||
/datum/action/innate/bci_action/New(obj/item/circuit_component/bci_action/circuit_component)
|
||||
..()
|
||||
|
||||
src.circuit_component = circuit_component
|
||||
|
||||
/datum/action/innate/bci_action/Destroy()
|
||||
circuit_component.bci_action = null
|
||||
circuit_component = null
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/bci_action/Activate()
|
||||
circuit_component.signal.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/bci_core
|
||||
display_name = "BCI Core"
|
||||
desc = "Controls the core operations of the BCI."
|
||||
|
||||
/// A reference to the action button to look at charge/get info
|
||||
var/datum/action/innate/bci_charge_action/charge_action
|
||||
|
||||
var/datum/port/input/message
|
||||
var/datum/port/input/send_message_signal
|
||||
|
||||
var/datum/port/output/user_port
|
||||
|
||||
var/datum/weakref/user
|
||||
|
||||
/obj/item/circuit_component/bci_core/Initialize()
|
||||
. = ..()
|
||||
|
||||
message = add_input_port("Message", PORT_TYPE_STRING)
|
||||
send_message_signal = add_input_port("Send Message", PORT_TYPE_SIGNAL)
|
||||
|
||||
user_port = add_output_port("User", PORT_TYPE_ATOM)
|
||||
|
||||
/obj/item/circuit_component/bci_core/Destroy()
|
||||
QDEL_NULL(charge_action)
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/bci_core/register_shell(atom/movable/shell)
|
||||
var/obj/item/organ/cyberimp/bci/bci = shell
|
||||
|
||||
charge_action = new(src)
|
||||
bci.actions += list(charge_action)
|
||||
|
||||
RegisterSignal(shell, COMSIG_ORGAN_IMPLANTED, .proc/on_organ_implanted)
|
||||
RegisterSignal(shell, COMSIG_ORGAN_REMOVED, .proc/on_organ_removed)
|
||||
|
||||
/obj/item/circuit_component/bci_core/unregister_shell(atom/movable/shell)
|
||||
var/obj/item/organ/cyberimp/bci/bci = shell
|
||||
|
||||
bci.actions -= charge_action
|
||||
QDEL_NULL(charge_action)
|
||||
|
||||
UnregisterSignal(shell, list(
|
||||
COMSIG_ORGAN_IMPLANTED,
|
||||
COMSIG_ORGAN_REMOVED,
|
||||
))
|
||||
|
||||
/obj/item/circuit_component/bci_core/input_received(datum/port/input/port)
|
||||
. = ..()
|
||||
if (.)
|
||||
return .
|
||||
|
||||
if (COMPONENT_TRIGGERED_BY(send_message_signal, port))
|
||||
var/sent_message = trim(message.value)
|
||||
if (!sent_message)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/resolved_owner = user?.resolve()
|
||||
if (isnull(resolved_owner))
|
||||
return
|
||||
|
||||
if (resolved_owner.stat == DEAD)
|
||||
return
|
||||
|
||||
to_chat(resolved_owner, "<i>You hear a strange, robotic voice in your head...</i> \"[span_robot("[html_encode(sent_message)]")]\"")
|
||||
|
||||
/obj/item/circuit_component/bci_core/proc/on_organ_implanted(datum/source, mob/living/carbon/owner)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
user_port.set_output(owner)
|
||||
user = WEAKREF(owner)
|
||||
|
||||
RegisterSignal(owner, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
RegisterSignal(owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/on_borg_charge)
|
||||
RegisterSignal(owner, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_electrocute)
|
||||
|
||||
/obj/item/circuit_component/bci_core/proc/on_organ_removed(datum/source, mob/living/carbon/owner)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
user_port.set_output(null)
|
||||
user = null
|
||||
|
||||
UnregisterSignal(owner, list(
|
||||
COMSIG_PARENT_EXAMINE,
|
||||
COMSIG_PROCESS_BORGCHARGER_OCCUPANT,
|
||||
COMSIG_LIVING_ELECTROCUTE_ACT,
|
||||
))
|
||||
|
||||
/obj/item/circuit_component/bci_core/proc/on_borg_charge(datum/source, amount)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (isnull(parent.cell))
|
||||
return
|
||||
|
||||
parent.cell.give(amount)
|
||||
|
||||
/obj/item/circuit_component/bci_core/proc/on_electrocute(datum/source, shock_damage, siemens_coefficient, flags)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (isnull(parent.cell))
|
||||
return
|
||||
|
||||
if (flags & SHOCK_ILLUSION)
|
||||
return
|
||||
|
||||
parent.cell.give(shock_damage * 2)
|
||||
to_chat(source, span_notice("You absorb some of the shock into your [parent.name]!"))
|
||||
|
||||
/obj/item/circuit_component/bci_core/proc/on_examine(datum/source, mob/mob, list/examine_text)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (isobserver(mob))
|
||||
examine_text += span_notice("[source.p_they(capitalized = TRUE)] [source.p_have()] <a href='?src=[REF(src)];open_bci=1'>\a [parent] implanted in [source.p_them()]</a>.")
|
||||
|
||||
/obj/item/circuit_component/bci_core/Topic(href, list/href_list)
|
||||
..()
|
||||
|
||||
if (!isobserver(usr))
|
||||
return
|
||||
|
||||
if (href_list["open_bci"])
|
||||
parent.attack_ghost(usr)
|
||||
|
||||
/datum/action/innate/bci_charge_action
|
||||
name = "Check BCI Charge"
|
||||
check_flags = NONE
|
||||
icon_icon = 'icons/obj/power.dmi'
|
||||
button_icon_state = "cell"
|
||||
|
||||
var/obj/item/circuit_component/bci_core/circuit_component
|
||||
|
||||
/datum/action/innate/bci_charge_action/New(obj/item/circuit_component/bci_core/circuit_component)
|
||||
..()
|
||||
|
||||
src.circuit_component = circuit_component
|
||||
|
||||
button.maptext_x = 2
|
||||
button.maptext_y = 0
|
||||
update_maptext()
|
||||
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/action/innate/bci_charge_action/Destroy()
|
||||
circuit_component.charge_action = null
|
||||
circuit_component = null
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/bci_charge_action/Trigger()
|
||||
var/obj/item/stock_parts/cell/cell = circuit_component.parent.cell
|
||||
|
||||
if (isnull(cell))
|
||||
to_chat(owner, span_boldwarning("[circuit_component.parent] has no power cell."))
|
||||
else
|
||||
to_chat(owner, span_info("[circuit_component.parent]'s [cell.name] has <b>[cell.percent()]%</b> charge left."))
|
||||
to_chat(owner, span_info("You can recharge it by using a cyborg recharging station."))
|
||||
|
||||
/datum/action/innate/bci_charge_action/process(delta_time)
|
||||
update_maptext()
|
||||
|
||||
/datum/action/innate/bci_charge_action/proc/update_maptext()
|
||||
var/obj/item/stock_parts/cell/cell = circuit_component.parent.cell
|
||||
button.maptext = cell ? MAPTEXT("[cell.percent()]%") : ""
|
||||
|
||||
/obj/machinery/bci_implanter
|
||||
name = "brain-computer interface manipulation chamber"
|
||||
desc = "A machine that, when given a brain-computer interface, will implant it into an occupant. Otherwise, will remove any brain-computer interfaces they already have."
|
||||
circuit = /obj/item/circuitboard/machine/bci_implanter
|
||||
icon = 'icons/obj/machines/bci_implanter.dmi'
|
||||
icon_state = "bci_implanter"
|
||||
base_icon_state = "bci_implanter"
|
||||
layer = ABOVE_WINDOW_LAYER
|
||||
use_power = IDLE_POWER_USE
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
obj_flags = NO_BUILD // Becomes undense when the door is open
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 300
|
||||
|
||||
var/busy = FALSE
|
||||
var/busy_icon_state
|
||||
var/locked = FALSE
|
||||
|
||||
var/datum/weakref/bci_to_implant
|
||||
|
||||
COOLDOWN_DECLARE(message_cooldown)
|
||||
|
||||
/obj/machinery/bci_implanter/Initialize()
|
||||
. = ..()
|
||||
occupant_typecache = typecacheof(/mob/living/carbon)
|
||||
|
||||
/obj/machinery/bci_implanter/Destroy()
|
||||
QDEL_NULL(bci_to_implant)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/bci_implanter/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
if (isnull(bci_to_implant?.resolve()))
|
||||
. += span_notice("There is no BCI inserted.")
|
||||
else
|
||||
. += span_notice("Right-click to remove current BCI.")
|
||||
|
||||
/obj/machinery/bci_implanter/proc/set_busy(status, working_icon)
|
||||
busy = status
|
||||
busy_icon_state = working_icon
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/bci_implanter/update_icon_state()
|
||||
if (occupant)
|
||||
icon_state = busy ? busy_icon_state : "[base_icon_state]_occupied"
|
||||
return ..()
|
||||
icon_state = "[base_icon_state][state_open ? "_open" : null]"
|
||||
return ..()
|
||||
|
||||
/obj/machinery/bci_implanter/update_overlays()
|
||||
var/list/overlays = ..()
|
||||
|
||||
if ((machine_stat & MAINT) || panel_open)
|
||||
overlays += "maint"
|
||||
return overlays
|
||||
|
||||
if (machine_stat & (NOPOWER|BROKEN))
|
||||
return overlays
|
||||
|
||||
if (busy || locked)
|
||||
overlays += "red"
|
||||
if (locked)
|
||||
overlays += "bolted"
|
||||
return overlays
|
||||
|
||||
overlays += "green"
|
||||
|
||||
return overlays
|
||||
|
||||
/obj/machinery/bci_implanter/attack_hand_secondary(mob/user, list/modifiers)
|
||||
. = ..()
|
||||
if (. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
|
||||
return .
|
||||
|
||||
if(!user.Adjacent(src))
|
||||
return
|
||||
|
||||
if (locked)
|
||||
balloon_alert(user, "it's locked!")
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
var/obj/item/organ/cyberimp/bci/bci_to_implant_resolved = bci_to_implant?.resolve()
|
||||
if (isnull(bci_to_implant_resolved))
|
||||
balloon_alert(user, "no bci inserted!")
|
||||
else
|
||||
user.put_in_hands(bci_to_implant_resolved)
|
||||
balloon_alert(user, "ejected bci")
|
||||
|
||||
bci_to_implant = null
|
||||
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/machinery/bci_implanter/attackby(obj/item/weapon, mob/user, params)
|
||||
var/obj/item/organ/cyberimp/bci/new_bci = weapon
|
||||
if (istype(new_bci))
|
||||
if (!(locate(/obj/item/integrated_circuit) in new_bci))
|
||||
balloon_alert(user, "bci has no circuit!")
|
||||
return
|
||||
|
||||
var/obj/item/organ/cyberimp/bci/previous_bci_to_implant = bci_to_implant?.resolve()
|
||||
|
||||
bci_to_implant = WEAKREF(weapon)
|
||||
weapon.forceMove(src)
|
||||
|
||||
if (isnull(previous_bci_to_implant))
|
||||
balloon_alert(user, "inserted bci")
|
||||
else
|
||||
balloon_alert(user, "swapped bci")
|
||||
user.put_in_hands(previous_bci_to_implant)
|
||||
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/bci_implanter/attackby_secondary(obj/item/weapon, mob/user, params)
|
||||
if (!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, weapon))
|
||||
update_appearance()
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
if (default_pry_open(weapon))
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
if (default_deconstruction_crowbar(weapon))
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/machinery/bci_implanter/proc/start_process()
|
||||
if (machine_stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if ((machine_stat & MAINT) || panel_open)
|
||||
return
|
||||
if (!occupant || busy)
|
||||
return
|
||||
|
||||
var/locked_state = locked
|
||||
locked = TRUE
|
||||
|
||||
set_busy(TRUE, "[initial(icon_state)]_raising")
|
||||
addtimer(CALLBACK(src, .proc/set_busy, TRUE, "[initial(icon_state)]_active"), 1 SECONDS)
|
||||
addtimer(CALLBACK(src, .proc/set_busy, TRUE, "[initial(icon_state)]_falling"), 2 SECONDS)
|
||||
addtimer(CALLBACK(src, .proc/complete_process, locked_state), 3 SECONDS)
|
||||
|
||||
/obj/machinery/bci_implanter/proc/complete_process(locked_state)
|
||||
locked = locked_state
|
||||
set_busy(FALSE)
|
||||
|
||||
var/mob/living/carbon/carbon_occupant = occupant
|
||||
if (!istype(carbon_occupant))
|
||||
return
|
||||
|
||||
playsound(loc, 'sound/machines/ping.ogg', 30, FALSE)
|
||||
|
||||
var/obj/item/organ/cyberimp/bci/bci_organ = carbon_occupant.getorgan(/obj/item/organ/cyberimp/bci)
|
||||
var/obj/item/organ/cyberimp/bci/bci_to_implant_resolved = bci_to_implant?.resolve()
|
||||
|
||||
if (bci_organ)
|
||||
bci_organ.Remove(carbon_occupant)
|
||||
|
||||
if (isnull(bci_to_implant_resolved))
|
||||
say("Occupant's previous brain-computer interface has been transferred to internal storage unit.")
|
||||
bci_organ.forceMove(src)
|
||||
bci_to_implant = WEAKREF(bci_organ)
|
||||
else
|
||||
say("Occupant's previous brain-computer interface has been ejected.")
|
||||
bci_organ.forceMove(drop_location())
|
||||
else if (!isnull(bci_to_implant_resolved))
|
||||
say("Occupant has been injected with [bci_to_implant_resolved].")
|
||||
bci_to_implant_resolved.Insert(carbon_occupant)
|
||||
bci_to_implant = null
|
||||
|
||||
/obj/machinery/bci_implanter/open_machine()
|
||||
if(state_open)
|
||||
return FALSE
|
||||
|
||||
..()
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/bci_implanter/close_machine(mob/living/carbon/user)
|
||||
if(!state_open)
|
||||
return FALSE
|
||||
|
||||
..()
|
||||
|
||||
var/mob/living/carbon/carbon_occupant = occupant
|
||||
if (istype(occupant))
|
||||
var/obj/item/organ/cyberimp/bci/existing_bci_organ = carbon_occupant.getorgan(/obj/item/organ/cyberimp/bci)
|
||||
if (isnull(existing_bci_organ) && isnull(bci_to_implant?.resolve()))
|
||||
say("No brain-computer interface inserted, and occupant does not have one. Insert a BCI to implant one.")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
return FALSE
|
||||
|
||||
addtimer(CALLBACK(src, .proc/start_process), 1 SECONDS)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/bci_implanter/relaymove(mob/living/user, direction)
|
||||
var/message
|
||||
|
||||
if (locked)
|
||||
message = "it won't budge!"
|
||||
else if (user.stat != CONSCIOUS)
|
||||
message = "you don't have the energy!"
|
||||
|
||||
if (!isnull(message))
|
||||
if (COOLDOWN_FINISHED(src, message_cooldown))
|
||||
COOLDOWN_START(src, message_cooldown, 5 SECONDS)
|
||||
balloon_alert(user, message)
|
||||
|
||||
return
|
||||
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/bci_implanter/interact(mob/user)
|
||||
if (state_open)
|
||||
close_machine(null, user)
|
||||
return
|
||||
else if (locked)
|
||||
balloon_alert(user, "it's locked!")
|
||||
return
|
||||
|
||||
open_machine()
|
||||
|
||||
/obj/item/circuitboard/machine/bci_implanter
|
||||
name = "Brain-Computer Interface Manipulation Chamber (Machine Board)"
|
||||
greyscale_colors = CIRCUIT_COLOR_SCIENCE
|
||||
build_path = /obj/machinery/bci_implanter
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/micro_laser = 2,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
)
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* # Compact Remote
|
||||
*
|
||||
* A handheld device with one big button.
|
||||
*/
|
||||
/obj/item/compact_remote
|
||||
name = "compact remote"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_small_simple"
|
||||
inhand_icon_state = "electronic"
|
||||
worn_icon_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
light_system = MOVABLE_LIGHT_DIRECTIONAL
|
||||
light_on = FALSE
|
||||
|
||||
/obj/item/compact_remote/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/compact_remote()
|
||||
), SHELL_CAPACITY_SMALL)
|
||||
|
||||
/obj/item/circuit_component/compact_remote
|
||||
display_name = "Compact Remote"
|
||||
desc = "Used to receive inputs from the compact remote shell. Use the shell in hand to trigger the output signal."
|
||||
|
||||
/// Called when attack_self is called on the shell.
|
||||
var/datum/port/output/signal
|
||||
/// The user who used the bot
|
||||
var/datum/port/output/entity
|
||||
|
||||
/obj/item/circuit_component/compact_remote/Initialize()
|
||||
. = ..()
|
||||
entity = add_output_port("User", PORT_TYPE_ATOM)
|
||||
signal = add_output_port("Signal", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/compact_remote/register_shell(atom/movable/shell)
|
||||
RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF, .proc/send_trigger)
|
||||
|
||||
/obj/item/circuit_component/compact_remote/unregister_shell(atom/movable/shell)
|
||||
UnregisterSignal(shell, COMSIG_ITEM_ATTACK_SELF)
|
||||
|
||||
/**
|
||||
* Called when the shell item is used in hand.
|
||||
*/
|
||||
/obj/item/circuit_component/compact_remote/proc/send_trigger(atom/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
source.balloon_alert(user, "clicked primary button")
|
||||
playsound(source, get_sfx("terminal_type"), 25, FALSE)
|
||||
entity.set_output(user)
|
||||
signal.set_output(COMPONENT_SIGNAL)
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* # Compact Remote
|
||||
*
|
||||
* A handheld device with several buttons.
|
||||
* In game, this translates to having different signals for normal usage, alt-clicking, and ctrl-clicking when in your hand.
|
||||
*/
|
||||
/obj/item/controller
|
||||
name = "controller"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_small_calc"
|
||||
inhand_icon_state = "electronic"
|
||||
worn_icon_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
light_system = MOVABLE_LIGHT_DIRECTIONAL
|
||||
light_on = FALSE
|
||||
|
||||
/obj/item/controller/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/controller()
|
||||
), SHELL_CAPACITY_MEDIUM)
|
||||
|
||||
/obj/item/circuit_component/controller
|
||||
display_name = "Controller"
|
||||
desc = "Used to receive inputs from the controller shell. Use the shell in hand to trigger the output signal. Alt-click for the alternate signal. Right click for the extra signal."
|
||||
|
||||
/// The three separate buttons that are called in attack_hand on the shell.
|
||||
var/datum/port/output/signal
|
||||
var/datum/port/output/alt
|
||||
var/datum/port/output/right
|
||||
|
||||
/// The entity output
|
||||
var/datum/port/output/entity
|
||||
|
||||
/obj/item/circuit_component/controller/Initialize()
|
||||
. = ..()
|
||||
entity = add_output_port("User", PORT_TYPE_ATOM)
|
||||
signal = add_output_port("Signal", PORT_TYPE_SIGNAL)
|
||||
alt = add_output_port("Alternate Signal", PORT_TYPE_SIGNAL)
|
||||
right = add_output_port("Extra Signal", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/controller/register_shell(atom/movable/shell)
|
||||
RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF, .proc/send_trigger)
|
||||
RegisterSignal(shell, COMSIG_CLICK_ALT, .proc/send_alternate_signal)
|
||||
RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF_SECONDARY, .proc/send_right_signal)
|
||||
|
||||
/obj/item/circuit_component/controller/unregister_shell(atom/movable/shell)
|
||||
UnregisterSignal(shell, list(
|
||||
COMSIG_ITEM_ATTACK_SELF,
|
||||
COMSIG_ITEM_ATTACK_SELF_SECONDARY,
|
||||
COMSIG_CLICK_ALT,
|
||||
))
|
||||
|
||||
/**
|
||||
* Called when the shell item is used in hand
|
||||
*/
|
||||
/obj/item/circuit_component/controller/proc/send_trigger(atom/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
if(!user.Adjacent(source))
|
||||
return
|
||||
source.balloon_alert(user, "clicked primary button")
|
||||
playsound(source, get_sfx("terminal_type"), 25, FALSE)
|
||||
entity.set_output(user)
|
||||
signal.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/**
|
||||
* Called when the shell item is alt-clicked
|
||||
*/
|
||||
/obj/item/circuit_component/controller/proc/send_alternate_signal(atom/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
if(!user.Adjacent(source))
|
||||
return
|
||||
source.balloon_alert(user, "clicked alternate button")
|
||||
playsound(source, get_sfx("terminal_type"), 25, FALSE)
|
||||
entity.set_output(user)
|
||||
alt.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/**
|
||||
* Called when the shell item is right-clicked in active hand
|
||||
*/
|
||||
/obj/item/circuit_component/controller/proc/send_right_signal(atom/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
if(!user.Adjacent(source))
|
||||
return
|
||||
source.balloon_alert(user, "clicked extra button")
|
||||
playsound(source, get_sfx("terminal_type"), 25, FALSE)
|
||||
entity.set_output(user)
|
||||
right.set_output(COMPONENT_SIGNAL)
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* # Drone
|
||||
*
|
||||
* A movable mob that can be fed inputs on which direction to travel.
|
||||
*/
|
||||
/mob/living/circuit_drone
|
||||
name = "drone"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_medium_med"
|
||||
living_flags = 0
|
||||
light_system = MOVABLE_LIGHT_DIRECTIONAL
|
||||
light_on = FALSE
|
||||
|
||||
/mob/living/circuit_drone/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/bot_circuit()
|
||||
), SHELL_CAPACITY_LARGE)
|
||||
|
||||
/mob/living/circuit_drone/updatehealth()
|
||||
. = ..()
|
||||
if(health < 0)
|
||||
gib(no_brain = TRUE, no_organs = TRUE, no_bodyparts = TRUE)
|
||||
|
||||
/mob/living/circuit_drone/spawn_gibs()
|
||||
new /obj/effect/gibspawner/robot(drop_location(), src, get_static_viruses())
|
||||
|
||||
/obj/item/circuit_component/bot_circuit
|
||||
display_name = "Drone"
|
||||
desc = "Used to send movement output signals to the drone shell."
|
||||
|
||||
/// The inputs to allow for the drone to move
|
||||
var/datum/port/input/north
|
||||
var/datum/port/input/east
|
||||
var/datum/port/input/south
|
||||
var/datum/port/input/west
|
||||
|
||||
// Done like this so that travelling diagonally is more simple
|
||||
COOLDOWN_DECLARE(north_delay)
|
||||
COOLDOWN_DECLARE(east_delay)
|
||||
COOLDOWN_DECLARE(south_delay)
|
||||
COOLDOWN_DECLARE(west_delay)
|
||||
|
||||
/// Delay between each movement
|
||||
var/move_delay = 0.2 SECONDS
|
||||
|
||||
/obj/item/circuit_component/bot_circuit/Initialize()
|
||||
. = ..()
|
||||
north = add_input_port("Move North", PORT_TYPE_SIGNAL)
|
||||
east = add_input_port("Move East", PORT_TYPE_SIGNAL)
|
||||
south = add_input_port("Move South", PORT_TYPE_SIGNAL)
|
||||
west = add_input_port("Move West", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/bot_circuit/input_received(datum/port/input/port)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/living/shell = parent.shell
|
||||
if(!istype(shell) || shell.stat)
|
||||
return
|
||||
|
||||
var/direction
|
||||
|
||||
if(COMPONENT_TRIGGERED_BY(north, port) && COOLDOWN_FINISHED(src, north_delay))
|
||||
direction = NORTH
|
||||
COOLDOWN_START(src, north_delay, move_delay)
|
||||
else if(COMPONENT_TRIGGERED_BY(east, port) && COOLDOWN_FINISHED(src, east_delay))
|
||||
direction = EAST
|
||||
COOLDOWN_START(src, east_delay, move_delay)
|
||||
else if(COMPONENT_TRIGGERED_BY(south, port) && COOLDOWN_FINISHED(src, south_delay))
|
||||
direction = SOUTH
|
||||
COOLDOWN_START(src, south_delay, move_delay)
|
||||
else if(COMPONENT_TRIGGERED_BY(west, port) && COOLDOWN_FINISHED(src, west_delay))
|
||||
direction = WEST
|
||||
COOLDOWN_START(src, west_delay, move_delay)
|
||||
|
||||
if(!direction)
|
||||
return
|
||||
|
||||
if(shell.Process_Spacemove(direction))
|
||||
shell.Move(get_step(shell, direction), direction)
|
||||
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* # Money Bot
|
||||
*
|
||||
* Immobile (but not dense) shell that can receive and dispense money.
|
||||
*/
|
||||
/obj/structure/money_bot
|
||||
name = "money bot"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_large"
|
||||
|
||||
density = FALSE
|
||||
light_system = MOVABLE_LIGHT
|
||||
light_on = FALSE
|
||||
|
||||
var/stored_money = 0
|
||||
|
||||
/obj/structure/money_bot/deconstruct(disassembled)
|
||||
new /obj/item/holochip(drop_location(), stored_money)
|
||||
return ..()
|
||||
|
||||
/obj/structure/money_bot/proc/add_money(to_add)
|
||||
stored_money += to_add
|
||||
SEND_SIGNAL(src, COMSIG_MONEYBOT_ADD_MONEY, to_add)
|
||||
|
||||
/obj/structure/money_bot/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/money_bot(),
|
||||
new /obj/item/circuit_component/money_dispenser()
|
||||
), SHELL_CAPACITY_LARGE)
|
||||
|
||||
/obj/structure/money_bot/wrench_act(mob/living/user, obj/item/tool)
|
||||
set_anchored(!anchored)
|
||||
tool.play_tool_sound(src)
|
||||
balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].")
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/circuit_component/money_dispenser
|
||||
display_name = "Money Dispenser"
|
||||
desc = "Used to dispense money from the money bot. Money is taken from the internal storage of money."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
|
||||
|
||||
/// The amount of money to dispense
|
||||
var/datum/port/input/dispense_amount
|
||||
|
||||
/// Outputs a signal when it fails to output any money.
|
||||
var/datum/port/output/on_fail
|
||||
|
||||
var/obj/structure/money_bot/attached_bot
|
||||
|
||||
/obj/item/circuit_component/money_dispenser/Initialize()
|
||||
. = ..()
|
||||
dispense_amount = add_input_port("Amount", PORT_TYPE_NUMBER)
|
||||
on_fail = add_output_port("On Failed", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/money_dispenser/register_shell(atom/movable/shell)
|
||||
. = ..()
|
||||
if(istype(shell, /obj/structure/money_bot))
|
||||
attached_bot = shell
|
||||
|
||||
/obj/item/circuit_component/money_dispenser/unregister_shell(atom/movable/shell)
|
||||
attached_bot = null
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/money_dispenser/input_received(datum/port/input/port)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(!attached_bot)
|
||||
return
|
||||
|
||||
var/to_dispense = clamp(dispense_amount.value, 0, attached_bot.stored_money)
|
||||
if(!to_dispense)
|
||||
on_fail.set_output(COMPONENT_SIGNAL)
|
||||
return
|
||||
|
||||
attached_bot.add_money(-to_dispense)
|
||||
new /obj/item/holochip(drop_location(), to_dispense)
|
||||
|
||||
/obj/item/circuit_component/money_bot
|
||||
display_name = "Money Bot"
|
||||
var/obj/structure/money_bot/attached_bot
|
||||
desc = "Used to receive input signals when money is inserted into the money bot shell and also keep track of the total money in the shell."
|
||||
|
||||
/// Total money in the shell
|
||||
var/datum/port/output/total_money
|
||||
/// Amount of the last money inputted into the shell
|
||||
var/datum/port/output/money_input
|
||||
/// Trigger for when money is inputted into the shell
|
||||
var/datum/port/output/money_trigger
|
||||
/// The person who input the money
|
||||
var/datum/port/output/entity
|
||||
|
||||
/obj/item/circuit_component/money_bot/Initialize()
|
||||
. = ..()
|
||||
total_money = add_output_port("Total Money", PORT_TYPE_NUMBER)
|
||||
money_input = add_output_port("Last Input Money", PORT_TYPE_NUMBER)
|
||||
entity = add_output_port("User", PORT_TYPE_ATOM)
|
||||
money_trigger = add_output_port("Money Input", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/money_bot/register_shell(atom/movable/shell)
|
||||
. = ..()
|
||||
if(istype(shell, /obj/structure/money_bot))
|
||||
attached_bot = shell
|
||||
total_money.set_output(attached_bot.stored_money)
|
||||
RegisterSignal(shell, COMSIG_PARENT_ATTACKBY, .proc/handle_money_insert)
|
||||
RegisterSignal(shell, COMSIG_MONEYBOT_ADD_MONEY, .proc/handle_money_update)
|
||||
|
||||
/obj/item/circuit_component/money_bot/unregister_shell(atom/movable/shell)
|
||||
UnregisterSignal(shell, list(
|
||||
COMSIG_PARENT_ATTACKBY,
|
||||
COMSIG_MONEYBOT_ADD_MONEY,
|
||||
))
|
||||
total_money.set_output(null)
|
||||
attached_bot = null
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/money_bot/proc/handle_money_insert(atom/source, obj/item/item, mob/living/attacker)
|
||||
SIGNAL_HANDLER
|
||||
if(!attached_bot || !iscash(item))
|
||||
return
|
||||
|
||||
var/amount_to_insert = item.get_item_credit_value()
|
||||
if(!amount_to_insert)
|
||||
balloon_alert(attacker, "this has no value!")
|
||||
return
|
||||
|
||||
attached_bot.add_money(amount_to_insert)
|
||||
balloon_alert(attacker, "inserted [amount_to_insert] credits.")
|
||||
money_input.set_output(amount_to_insert)
|
||||
entity.set_output(attacker)
|
||||
money_trigger.set_output(COMPONENT_SIGNAL)
|
||||
qdel(item)
|
||||
|
||||
/obj/item/circuit_component/money_bot/proc/handle_money_update(atom/source)
|
||||
SIGNAL_HANDLER
|
||||
if(attached_bot)
|
||||
total_money.set_output(attached_bot.stored_money)
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* # Scanner
|
||||
*
|
||||
* A handheld device that lets you flash it over people.
|
||||
*/
|
||||
/obj/item/wiremod_scanner
|
||||
name = "scanner"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_small"
|
||||
inhand_icon_state = "electronic"
|
||||
worn_icon_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
light_system = MOVABLE_LIGHT_DIRECTIONAL
|
||||
light_on = FALSE
|
||||
|
||||
/obj/item/wiremod_scanner/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/wiremod_scanner()
|
||||
), SHELL_CAPACITY_SMALL)
|
||||
|
||||
/obj/item/circuit_component/wiremod_scanner
|
||||
display_name = "Scanner"
|
||||
desc = "Used to receive scanned entities from the scanner."
|
||||
|
||||
/// Called when afterattack is called on the shell.
|
||||
var/datum/port/output/signal
|
||||
|
||||
/// The attacker
|
||||
var/datum/port/output/attacker
|
||||
|
||||
/// The entity being attacked
|
||||
var/datum/port/output/attacking
|
||||
|
||||
|
||||
|
||||
/obj/item/circuit_component/wiremod_scanner/Initialize()
|
||||
. = ..()
|
||||
attacker = add_output_port("Scanner", PORT_TYPE_ATOM)
|
||||
attacking = add_output_port("Scanned Entity", PORT_TYPE_ATOM)
|
||||
signal = add_output_port("Scanned", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/wiremod_scanner/register_shell(atom/movable/shell)
|
||||
RegisterSignal(shell, COMSIG_ITEM_AFTERATTACK, .proc/handle_afterattack)
|
||||
|
||||
/obj/item/circuit_component/wiremod_scanner/unregister_shell(atom/movable/shell)
|
||||
UnregisterSignal(shell, COMSIG_ITEM_AFTERATTACK)
|
||||
|
||||
/**
|
||||
* Called when the shell item attacks something
|
||||
*/
|
||||
/obj/item/circuit_component/wiremod_scanner/proc/handle_afterattack(atom/source, atom/target, mob/user, proximity_flag)
|
||||
SIGNAL_HANDLER
|
||||
if(!proximity_flag)
|
||||
return
|
||||
source.balloon_alert(user, "scanned object")
|
||||
playsound(source, get_sfx("terminal_type"), 25, FALSE)
|
||||
attacker.set_output(user)
|
||||
attacking.set_output(target)
|
||||
signal.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/obj/structure/scanner_gate_shell
|
||||
name = "circuit scanner gate"
|
||||
desc = "A gate able to perform mid-depth scans on any organisms who pass under it."
|
||||
icon = 'icons/obj/machines/scangate.dmi'
|
||||
icon_state = "scangate_black"
|
||||
var/scanline_timer
|
||||
|
||||
/obj/structure/scanner_gate_shell/Initialize()
|
||||
. = ..()
|
||||
set_scanline("passive")
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = .proc/on_entered,
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
|
||||
AddComponent(/datum/component/shell, list(
|
||||
new /obj/item/circuit_component/scanner_gate()
|
||||
), SHELL_CAPACITY_LARGE, SHELL_FLAG_REQUIRE_ANCHOR)
|
||||
|
||||
/obj/structure/scanner_gate_shell/wrench_act(mob/living/user, obj/item/tool)
|
||||
set_anchored(!anchored)
|
||||
tool.play_tool_sound(src)
|
||||
balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].")
|
||||
return TRUE
|
||||
|
||||
/obj/structure/scanner_gate_shell/proc/on_entered(datum/source, atom/movable/AM)
|
||||
SIGNAL_HANDLER
|
||||
set_scanline("scanning", 10)
|
||||
SEND_SIGNAL(src, COMSIG_SCANGATE_SHELL_PASS, AM)
|
||||
|
||||
/obj/structure/scanner_gate_shell/proc/set_scanline(type, duration)
|
||||
cut_overlays()
|
||||
deltimer(scanline_timer)
|
||||
add_overlay(type)
|
||||
if(duration)
|
||||
scanline_timer = addtimer(CALLBACK(src, .proc/set_scanline, "passive"), duration, TIMER_STOPPABLE)
|
||||
|
||||
/obj/item/circuit_component/scanner_gate
|
||||
display_name = "Scanner Gate"
|
||||
desc = "A gate able to perform mid-depth scans on any object that pass through it."
|
||||
|
||||
circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL
|
||||
|
||||
var/datum/port/output/scanned
|
||||
|
||||
var/obj/structure/scanner_gate_shell/attached_gate
|
||||
|
||||
/obj/item/circuit_component/scanner_gate/Initialize()
|
||||
. = ..()
|
||||
scanned = add_output_port("Scanned Object", PORT_TYPE_ATOM)
|
||||
|
||||
/obj/item/circuit_component/scanner_gate/register_shell(atom/movable/shell)
|
||||
. = ..()
|
||||
if(istype(shell, /obj/structure/scanner_gate_shell))
|
||||
attached_gate = shell
|
||||
RegisterSignal(attached_gate, COMSIG_SCANGATE_SHELL_PASS, .proc/on_trigger)
|
||||
|
||||
/obj/item/circuit_component/scanner_gate/unregister_shell(atom/movable/shell)
|
||||
UnregisterSignal(attached_gate, COMSIG_SCANGATE_SHELL_PASS)
|
||||
attached_gate = null
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/scanner_gate/proc/on_trigger(datum/source, atom/movable/passed)
|
||||
SIGNAL_HANDLER
|
||||
scanned.set_output(passed)
|
||||
trigger_output.set_output(COMPONENT_SIGNAL)
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* # Server
|
||||
*
|
||||
* Immobile (but not dense) shells that can interact with
|
||||
* world.
|
||||
*/
|
||||
/obj/structure/server
|
||||
name = "server"
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
icon_state = "setup_stationary"
|
||||
|
||||
density = TRUE
|
||||
light_system = MOVABLE_LIGHT
|
||||
light_on = FALSE
|
||||
|
||||
/obj/structure/server/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/shell, null, SHELL_CAPACITY_VERY_LARGE, SHELL_FLAG_REQUIRE_ANCHOR|SHELL_FLAG_USB_PORT)
|
||||
|
||||
/obj/structure/server/wrench_act(mob/living/user, obj/item/tool)
|
||||
set_anchored(!anchored)
|
||||
tool.play_tool_sound(src)
|
||||
balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].")
|
||||
return TRUE
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* # Shell Item
|
||||
*
|
||||
* Printed out by protolathes. Screwdriver to complete the shell.
|
||||
*/
|
||||
/obj/item/shell
|
||||
name = "assembly"
|
||||
desc = "A shell assembly that can be completed by screwdrivering it."
|
||||
icon = 'icons/obj/wiremod.dmi'
|
||||
var/shell_to_spawn
|
||||
var/screw_delay = 3 SECONDS
|
||||
|
||||
/obj/item/shell/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
user.visible_message(span_notice("[user] begins finishing [src]."), span_notice("You begin finishing [src]."))
|
||||
tool.play_tool_sound(src)
|
||||
if(!do_after(user, screw_delay, src))
|
||||
return
|
||||
user.visible_message(span_notice("[user] finishes [src]."), span_notice("You finish [src]."))
|
||||
|
||||
var/turf/drop_loc = drop_location()
|
||||
|
||||
qdel(src)
|
||||
if(drop_loc)
|
||||
new shell_to_spawn(drop_loc)
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/shell/bot
|
||||
name = "bot assembly"
|
||||
icon_state = "setup_medium_box-open"
|
||||
shell_to_spawn = /obj/structure/bot
|
||||
|
||||
/obj/item/shell/money_bot
|
||||
name = "money bot assembly"
|
||||
icon_state = "setup_large-open"
|
||||
shell_to_spawn = /obj/structure/money_bot
|
||||
|
||||
/obj/item/shell/drone
|
||||
name = "drone assembly"
|
||||
icon_state = "setup_medium_med-open"
|
||||
shell_to_spawn = /mob/living/circuit_drone
|
||||
|
||||
/obj/item/shell/server
|
||||
name = "server assembly"
|
||||
icon_state = "setup_stationary-open"
|
||||
shell_to_spawn = /obj/structure/server
|
||||
screw_delay = 10 SECONDS
|
||||
|
||||
/obj/item/shell/airlock
|
||||
name = "circuit airlock assembly"
|
||||
icon = 'icons/obj/doors/airlocks/station/public.dmi'
|
||||
icon_state = "construction"
|
||||
shell_to_spawn = /obj/machinery/door/airlock/shell
|
||||
screw_delay = 10 SECONDS
|
||||
|
||||
/obj/item/shell/bci
|
||||
name = "brain-computer interface assembly"
|
||||
icon_state = "bci-open"
|
||||
shell_to_spawn = /obj/item/organ/cyberimp/bci
|
||||
|
||||
/obj/item/shell/scanner_gate
|
||||
name = "scanner gate assembly"
|
||||
icon = 'icons/obj/machines/scangate.dmi'
|
||||
icon_state = "scangate_black_open"
|
||||
shell_to_spawn = /obj/structure/scanner_gate_shell
|
||||
Reference in New Issue
Block a user