/
mmi.dm
172 lines (140 loc) · 5.13 KB
/
mmi.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
* # Man-Machine Interface Component
*
* Allows an MMI to be inserted into a shell, allowing it to be linked up. Requires a shell.
*/
/obj/item/circuit_component/mmi
display_name = "Man-Machine Interface"
desc = "A component that allows MMI to enter shells to send output signals."
category = "Action"
circuit_flags = CIRCUIT_FLAG_REFUSE_MODULE
/// The message to send to the MMI in the shell.
var/datum/port/input/message
/// Sends the current MMI a message
var/datum/port/input/send
/// Ejects the current MMI
var/datum/port/input/eject
/// Called when the MMI tries moving north
var/datum/port/output/north
/// Called when the MMI tries moving east
var/datum/port/output/east
/// Called when the MMI tries moving south
var/datum/port/output/south
/// Called when the MMI tries moving west
var/datum/port/output/west
/// Returns what the MMI last clicked on.
var/datum/port/output/clicked_atom
/// Called when the MMI clicks.
var/datum/port/output/attack
/// Called when the MMI right clicks.
var/datum/port/output/secondary_attack
/// The current MMI card
var/obj/item/mmi/brain
/// Maximum length of the message that can be sent to the MMI
var/max_length = 300
/obj/item/circuit_component/mmi/populate_ports()
message = add_input_port("Message", PORT_TYPE_STRING)
send = add_input_port("Send Message", PORT_TYPE_SIGNAL)
eject = add_input_port("Eject", PORT_TYPE_SIGNAL)
north = add_output_port("North", PORT_TYPE_SIGNAL)
east = add_output_port("East", PORT_TYPE_SIGNAL)
south = add_output_port("South", PORT_TYPE_SIGNAL)
west = add_output_port("West", PORT_TYPE_SIGNAL)
attack = add_output_port("Attack", PORT_TYPE_SIGNAL)
secondary_attack = add_output_port("Secondary Attack", PORT_TYPE_SIGNAL)
clicked_atom = add_output_port("Target Entity", PORT_TYPE_ATOM)
/obj/item/circuit_component/mmi/Destroy()
remove_current_brain()
return ..()
/obj/item/circuit_component/mmi/input_received(datum/port/input/port)
if(!brain)
return
if(COMPONENT_TRIGGERED_BY(eject, port))
remove_current_brain()
if(COMPONENT_TRIGGERED_BY(send, port))
if(!message.value)
return
var/msg_str = copytext(html_encode(message.value), 1, max_length)
var/mob/living/target = brain.brainmob
if(!target)
return
to_chat(target, "[span_bold("You hear a message in your ear: ")][msg_str]")
/obj/item/circuit_component/mmi/register_shell(atom/movable/shell)
. = ..()
RegisterSignal(shell, COMSIG_PARENT_ATTACKBY, .proc/handle_attack_by)
/obj/item/circuit_component/mmi/unregister_shell(atom/movable/shell)
UnregisterSignal(shell, COMSIG_PARENT_ATTACKBY)
remove_current_brain()
return ..()
/obj/item/circuit_component/mmi/proc/handle_attack_by(atom/movable/shell, obj/item/item, mob/living/attacker)
SIGNAL_HANDLER
if(istype(item, /obj/item/mmi))
var/obj/item/mmi/target_mmi = item
if(!target_mmi.brainmob)
return
add_mmi(item)
return COMPONENT_NO_AFTERATTACK
/obj/item/circuit_component/mmi/proc/add_mmi(obj/item/mmi/to_add)
remove_current_brain()
to_add.forceMove(src)
if(to_add.brainmob)
update_mmi_mob(to_add, null, to_add.brainmob)
brain = to_add
RegisterSignal(to_add, COMSIG_PARENT_QDELETING, .proc/remove_current_brain)
RegisterSignal(to_add, COMSIG_MOVABLE_MOVED, .proc/mmi_moved)
/obj/item/circuit_component/mmi/proc/mmi_moved(atom/movable/mmi)
SIGNAL_HANDLER
if(mmi.loc != src)
remove_current_brain()
/obj/item/circuit_component/mmi/proc/remove_current_brain()
SIGNAL_HANDLER
if(!brain)
return
if(brain.brainmob)
update_mmi_mob(brain, brain.brainmob)
UnregisterSignal(brain, list(
COMSIG_PARENT_QDELETING,
COMSIG_MOVABLE_MOVED
))
if(brain.loc == src)
brain.forceMove(drop_location())
brain = null
/obj/item/circuit_component/mmi/proc/update_mmi_mob(datum/source, mob/living/old_mmi, mob/living/new_mmi)
SIGNAL_HANDLER
if(old_mmi)
old_mmi.remote_control = null
UnregisterSignal(old_mmi, COMSIG_MOB_CLICKON)
if(new_mmi)
new_mmi.remote_control = src
RegisterSignal(new_mmi, COMSIG_MOB_CLICKON, .proc/handle_mmi_attack)
/obj/item/circuit_component/mmi/relaymove(mob/living/user, direct)
if(user != brain.brainmob)
return ..()
if(direct & NORTH)
north.set_output(COMPONENT_SIGNAL)
if(direct & WEST)
west.set_output(COMPONENT_SIGNAL)
if(direct & EAST)
east.set_output(COMPONENT_SIGNAL)
if(direct & SOUTH)
south.set_output(COMPONENT_SIGNAL)
return TRUE
/obj/item/circuit_component/mmi/proc/handle_mmi_attack(mob/living/source, atom/target, list/modifiers)
SIGNAL_HANDLER
if(modifiers[RIGHT_CLICK])
clicked_atom.set_output(target)
secondary_attack.set_output(COMPONENT_SIGNAL)
. = COMSIG_MOB_CANCEL_CLICKON
else if(modifiers[LEFT_CLICK] && !modifiers[SHIFT_CLICK] && !modifiers[ALT_CLICK] && !modifiers[CTRL_CLICK])
clicked_atom.set_output(target)
attack.set_output(COMPONENT_SIGNAL)
. = COMSIG_MOB_CANCEL_CLICKON
/obj/item/circuit_component/mmi/add_to(obj/item/integrated_circuit/add_to)
. = ..()
if(HAS_TRAIT(add_to, TRAIT_COMPONENT_MMI))
return FALSE
ADD_TRAIT(add_to, TRAIT_COMPONENT_MMI, REF(src))
/obj/item/circuit_component/mmi/removed_from(obj/item/integrated_circuit/removed_from)
REMOVE_TRAIT(removed_from, TRAIT_COMPONENT_MMI, REF(src))
remove_current_brain()
return ..()