/
aicard.dm
164 lines (141 loc) · 4.42 KB
/
aicard.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
/obj/item/aicard
name = "intelliCard"
desc = "A storage device for AIs. Patent pending."
icon = 'icons/obj/aicards.dmi'
icon_state = "aicard" // aicard-full
base_icon_state = "aicard"
inhand_icon_state = "electronic"
worn_icon_state = "electronic"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
item_flags = NOBLUDGEON
var/flush = FALSE
var/mob/living/silicon/ai/AI
/obj/item/aicard/Initialize(mapload)
. = ..()
if(mapload && HAS_TRAIT(SSstation, STATION_TRAIT_HUMAN_AI))
return INITIALIZE_HINT_QDEL
ADD_TRAIT(src, TRAIT_CASTABLE_LOC, INNATE_TRAIT)
/obj/item/aicard/Destroy(force)
if(AI)
AI.ghostize(can_reenter_corpse = FALSE)
QDEL_NULL(AI)
return ..()
/obj/item/aicard/aitater
name = "intelliTater"
desc = "A stylish upgrade (?) to the intelliCard."
icon_state = "aitater"
base_icon_state = "aitater"
/obj/item/aicard/aispook
name = "intelliLantern"
desc = "A spoOoOoky upgrade to the intelliCard."
icon_state = "aispook"
base_icon_state = "aispook"
/obj/item/aicard/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is trying to upload [user.p_them()]self into [src]! That's not going to work out well!"))
return BRUTELOSS
/obj/item/aicard/pre_attack(atom/target, mob/living/user, params)
. = ..()
if(.)
return
if(AI)
if(upload_ai(target, user))
return TRUE
else
if(capture_ai(target, user))
return TRUE
/// Tries to get an AI from the atom clicked
/obj/item/aicard/proc/capture_ai(atom/from_what, mob/living/user)
from_what.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
if(isnull(AI))
return FALSE
log_silicon("[key_name(user)] carded [key_name(AI)]", list(src))
update_appearance()
AI.cancel_camera()
RegisterSignal(AI, COMSIG_MOB_STATCHANGE, PROC_REF(on_ai_stat_change))
return TRUE
/// Tries to upload the AI we have captured to the atom clicked
/obj/item/aicard/proc/upload_ai(atom/to_what, mob/living/user)
var/mob/living/silicon/ai/old_ai = AI
to_what.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
if(!isnull(AI))
return FALSE
log_combat(user, old_ai, "uploaded", src, "to [to_what].")
update_appearance()
old_ai.cancel_camera()
UnregisterSignal(old_ai, COMSIG_MOB_STATCHANGE)
return TRUE
/obj/item/aicard/proc/on_ai_stat_change(datum/source, new_stat, old_stat)
SIGNAL_HANDLER
if(new_stat == DEAD || old_stat == DEAD)
update_appearance()
/obj/item/aicard/update_name(updates)
. = ..()
if(AI)
name = "[initial(name)] - [AI.name]"
else
name = initial(name)
/obj/item/aicard/update_icon_state()
if(AI)
icon_state = "[base_icon_state][AI.stat == DEAD ? "-404" : "-full"]"
else
icon_state = base_icon_state
return ..()
/obj/item/aicard/update_overlays()
. = ..()
if(!AI?.control_disabled)
return
. += "[base_icon_state]-on"
/obj/item/aicard/ui_state(mob/user)
return GLOB.hands_state
/obj/item/aicard/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Intellicard", name)
ui.open()
/obj/item/aicard/ui_data()
var/list/data = list()
if(AI)
data["name"] = AI.name
data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE)
data["health"] = (AI.health + 100) / 2
data["wireless"] = !AI.control_disabled //todo disabled->enabled
data["radio"] = AI.radio_enabled
data["isDead"] = AI.stat == DEAD
data["isBraindead"] = AI.client ? FALSE : TRUE
data["wiping"] = flush
return data
/obj/item/aicard/ui_act(action,params)
. = ..()
if(.)
return
switch(action)
if("wipe")
if(flush)
flush = FALSE
else
var/confirm = tgui_alert(usr, "Are you sure you want to wipe this card's memory?", name, list("Yes", "No"))
if(confirm == "Yes" && !..())
flush = TRUE
wipe_ai()
. = TRUE
if("wireless")
AI.control_disabled = !AI.control_disabled
to_chat(AI, span_warning("[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!"))
. = TRUE
if("radio")
AI.radio_enabled = !AI.radio_enabled
to_chat(AI, span_warning("Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!"))
. = TRUE
update_appearance()
/obj/item/aicard/proc/wipe_ai()
set waitfor = FALSE
if(AI && AI.loc == src)
to_chat(AI, span_userdanger("Your core files are being wiped!"))
while(AI.stat != DEAD && flush)
AI.adjustOxyLoss(5)
AI.updatehealth()
sleep(0.5 SECONDS)
flush = FALSE