Merge branch 'master' of https://github.com/VOREStation/VOREStation into upstream-merge-8298

This commit is contained in:
MistakeNot4892
2022-08-25 14:26:20 +10:00
1603 changed files with 70496 additions and 61794 deletions
+2 -2
View File
@@ -141,7 +141,7 @@
to_chat(usr, "<span class='warning'>Error! Please notify administration!</span>")
return
var/list/turf/turfs = res
var/str = sanitizeSafe(input(usr, "New area name:","Blueprint Editing", ""), MAX_NAME_LEN)
var/str = sanitizeSafe(tgui_input_text(usr, "New area name:","Blueprint Editing", "", MAX_NAME_LEN), MAX_NAME_LEN)
if(!str || !length(str)) //cancel
return
if(length(str) > 50)
@@ -200,7 +200,7 @@
/obj/item/blueprints/proc/edit_area()
var/area/A = get_area()
var/prevname = "[A.name]"
var/str = sanitizeSafe(input(usr, "New area name:","Blueprint Editing", prevname), MAX_NAME_LEN)
var/str = sanitizeSafe(tgui_input_text(usr, "New area name:","Blueprint Editing", prevname, MAX_NAME_LEN), MAX_NAME_LEN)
if(!str || !length(str) || str==prevname) //cancel
return
if(length(str) > 50)
+1 -1
View File
@@ -33,7 +33,7 @@
/obj/structure/closet/body_bag/attackby(var/obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/pen))
var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null)
if (user.get_active_hand() != W)
return
if (!in_range(src, user) && src.loc != user)
@@ -94,22 +94,22 @@
if(new_state != old_state)
switch(new_state)
if(PROXIMITY_OFF_CAMERANET)
to_chat(carrier, "<span class='notice'>[bicon(src)] Now outside of camera network.</span>")
to_chat(carrier, "<span class='notice'>\icon[src][bicon(src)] Now outside of camera network.</span>")
carrier << 'sound/machines/defib_failed.ogg'
if(PROXIMITY_NONE)
to_chat(carrier, "<span class='notice'>[bicon(src)] Now within camera network, AI and cameras unfocused.</span>")
to_chat(carrier, "<span class='notice'>\icon[src][bicon(src)] Now within camera network, AI and cameras unfocused.</span>")
carrier << 'sound/machines/defib_safetyOff.ogg'
if(PROXIMITY_NEAR)
to_chat(carrier, "<span class='warning'>[bicon(src)] Warning: AI focus at nearby location.</span>")
to_chat(carrier, "<span class='warning'>\icon[src][bicon(src)] Warning: AI focus at nearby location.</span>")
carrier << 'sound/machines/defib_SafetyOn.ogg'
if(PROXIMITY_ON_SCREEN)
to_chat(carrier, "<font size='3'><span class='danger'>[bicon(src)] Alert: AI or camera focused at current location!</span></font>")
to_chat(carrier, "<font size='3'><span class='danger'>\icon[src][bicon(src)] Alert: AI or camera focused at current location!</span></font>")
carrier <<'sound/machines/defib_ready.ogg'
if(PROXIMITY_TRACKING)
to_chat(carrier, "<font size='3'><span class='danger'>[bicon(src)] Danger: AI is actively tracking you!</span></font>")
to_chat(carrier, "<font size='3'><span class='danger'>\icon[src][bicon(src)] Danger: AI is actively tracking you!</span></font>")
carrier << 'sound/machines/defib_success.ogg'
if(PROXIMITY_TRACKING_FAIL)
to_chat(carrier, "<font size='3'><span class='danger'>[bicon(src)] Danger: AI is attempting to actively track you, but you are outside of the camera network!</span></font>")
to_chat(carrier, "<font size='3'><span class='danger'>\icon[src][bicon(src)] Danger: AI is attempting to actively track you, but you are outside of the camera network!</span></font>")
carrier <<'sound/machines/defib_ready.ogg'
@@ -85,7 +85,7 @@
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, (video_range * 2), (video_range * 2))
local_skybox.cut_overlays()
local_skybox.add_overlay(SSskybox.get_skybox(get_z(last_camera_turf)))
local_skybox.scale_to_view(video_range * 2)
@@ -322,7 +322,7 @@
. = TRUE
switch(action)
if("rename")
var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) )
var/new_name = sanitizeSafe(tgui_input_text(usr,"Please enter your name.","Communicator",usr.name) )
if(new_name)
register_device(new_name)
@@ -340,6 +340,11 @@
if("toggle_ringer")
ringer = !ringer
if("set_ringer_tone")
var/ringtone = tgui_input_text(usr, "Set Ringer Tone", "Ringer")
if(ringtone)
ttone = ringtone
if("selfie_mode")
selfie_mode = !selfie_mode
@@ -371,11 +376,13 @@
to_chat(usr, "<span class='danger'>Error: Cannot connect to Exonet node.</span>")
return FALSE
var/their_address = params["message"]
var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message"))
var/text = sanitizeSafe(tgui_input_text(usr,"Enter your message.","Text Message"))
if(text)
exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr)
var/obj/item/device/communicator/comm = exonet.get_atom_from_address(their_address)
to_chat(usr, "<span class='notice'>\icon[src][bicon(src)] Sent message to [comm.owner], <b>\"[text]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[exonet.get_atom_from_address(comm.exonet.address)]'>Reply</a>)</span>")
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
@@ -419,7 +426,7 @@
selected_tab = params["switch_tab"]
if("edit")
var/n = input(usr, "Please enter message", name, notehtml) as message|null
var/n = tgui_input_text(usr, "Please enter message", name, notehtml, multiline = TRUE, prevent_enter = TRUE)
n = sanitizeSafe(n, extra = 0)
if(n)
note = html_decode(n)
@@ -75,6 +75,20 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// If you turn this on, it changes the way communicator video works. User configurable option.
var/selfie_mode = FALSE
// Ringtones! (Based on the PDA ones)
var/ttone = "beep" //The ringtone!
var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg',
"boom" = 'sound/effects/explosionfar.ogg',
"slip" = 'sound/misc/slip.ogg',
"honk" = 'sound/items/bikehorn.ogg',
"SKREE" = 'sound/voice/shriek1.ogg',
// "holy" = 'sound/items/PDA/ambicha4-short.ogg',
"xeno" = 'sound/voice/hiss1.ogg',
"dust" = 'sound/effects/supermatter.ogg',
"spark" = 'sound/effects/sparks4.ogg',
"rad" = 'sound/items/geiger/high1.ogg',
"servo" = 'sound/machines/rig/rigservo.ogg')
// Proc: New()
// Parameters: None
// Description: Adds the new communicator to the global list of all communicators, sorts the list, obtains a reference to the Exonet node, then tries to
@@ -128,10 +142,10 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Description: Shows all the voice mobs inside the device, and their status.
/obj/item/device/communicator/examine(mob/user)
. = ..()
for(var/mob/living/voice/voice in contents)
. += "<span class='notice'>On the screen, you can see a image feed of [voice].</span>"
if(voice && voice.key)
switch(voice.stat)
if(CONSCIOUS)
@@ -284,7 +298,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/obj/item/device/communicator/Destroy()
for(var/mob/living/voice/voice in contents)
voice_mobs.Remove(voice)
to_chat(voice, "<span class='danger'>[bicon(src)] Connection timed out with remote host.</span>")
to_chat(voice, "<span class='danger'>\icon[src][bicon(src)] Connection timed out with remote host.</span>")
qdel(voice)
close_connection(reason = "Connection timed out")
@@ -34,7 +34,7 @@
if(src in comm.voice_invites)
comm.open_connection(src)
return
to_chat(src, "<span class='notice'>[bicon(origin_atom)] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
to_chat(src, "<span class='notice'>\icon[origin_atom][bicon(origin_atom)] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
verb, and select that name to answer the call.</span>")
src << 'sound/machines/defib_SafetyOn.ogg'
comm.voice_invites |= src
@@ -44,7 +44,7 @@
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
to_chat(src, "<span class='notice'>[bicon(origin_atom)] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
to_chat(src, "<span class='notice'>\icon[origin_atom][bicon(origin_atom)] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
src << 'sound/machines/defib_safetyOff.ogg'
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
return
@@ -57,7 +57,7 @@
var/who = null
if(isobserver(candidate))
var/mob/observer/dead/ghost = candidate
who = ghost
who = ghost.name
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
@@ -76,9 +76,15 @@
return
if(ringer)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
var/S
if(ttone in ttone_sound)
S = ttone_sound[ttone]
else
S = 'sound/machines/twobeep.ogg'
playsound(src, S, 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("[bicon(src)] *beep*"))
O.show_message(text("\icon[src][bicon(src)] *[ttone]*"))
alert_called = 1
update_icon()
@@ -89,7 +95,20 @@
L = loc
if(L)
to_chat(L, "<span class='notice'>[bicon(src)] Message from [who].</span>")
to_chat(L, "<span class='notice'>\icon[src][bicon(src)] Message from [who]: <b>\"[text]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[candidate]'>Reply</a>)</span>")
// This is the only Topic the communicators really uses
/obj/item/device/communicator/Topic(href, href_list)
switch(href_list["action"])
if("Reply")
var/obj/item/device/communicator/comm = locate(href_list["target"])
var/message = tgui_input_text(usr, "Enter your message below.", "Reply")
if(message)
exonet.send_message(comm.exonet.address, "text", message)
im_list += list(list("address" = exonet.address, "to_address" = comm.exonet.address, "im" = message))
log_pda("(COMM: [src]) sent \"[message]\" to [exonet.get_atom_from_address(comm.exonet.address)]", usr)
to_chat(usr, "<span class='notice'>\icon[src][bicon(src)] Sent message to [comm.owner], <b>\"[message]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[exonet.get_atom_from_address(comm.exonet.address)]'>Reply</a>)</span>")
// Verb: text_communicator()
// Parameters: None
@@ -134,7 +153,7 @@
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
var/text_message = sanitize(input(src, "What do you want the message to say?") as message)
var/text_message = sanitize(tgui_input_text(src, "What do you want the message to say?", multiline = TRUE))
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
@@ -39,15 +39,15 @@
comm.voice_requests.Remove(src)
if(user)
comm.visible_message("<span class='notice'>[bicon(src)] Connecting to [src].</span>")
to_chat(user, "<span class='notice'>[bicon(src)] Attempting to call [comm].</span>")
comm.visible_message("<span class='notice'>\icon[src][bicon(src)] Connecting to [src].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Attempting to call [comm].</span>")
sleep(10)
to_chat(user, "<span class='notice'>[bicon(src)] Dialing internally from [station_name()], [system_name()].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Dialing internally from [station_name()], [system_name()].</span>")
sleep(20) //If they don't have an exonet something is very wrong and we want a runtime.
to_chat(user, "<span class='notice'>[bicon(src)] Connection re-routed to [comm] at [comm.exonet.address].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connection re-routed to [comm] at [comm.exonet.address].</span>")
sleep(40)
to_chat(user, "<span class='notice'>[bicon(src)] Connection to [comm] at [comm.exonet.address] established.</span>")
comm.visible_message("<span class='notice'>[bicon(src)] Connection to [src] at [exonet.address] established.</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connection to [comm] at [comm.exonet.address] established.</span>")
comm.visible_message("<span class='notice'>\icon[src][bicon(src)] Connection to [src] at [exonet.address] established.</span>")
sleep(20)
src.add_communicating(comm)
@@ -86,28 +86,28 @@
//Now for some connection fluff.
if(user)
to_chat(user, "<span class='notice'>[bicon(src)] Connecting to [candidate].</span>")
to_chat(new_voice, "<span class='notice'>[bicon(src)] Attempting to call [src].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connecting to [candidate].</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Attempting to call [src].</span>")
sleep(10)
to_chat(new_voice, "<span class='notice'>[bicon(src)] Dialing to [station_name()], Kara Subsystem, [system_name()].</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Dialing to [station_name()], Kara Subsystem, [system_name()].</span>")
sleep(20)
to_chat(new_voice, "<span class='notice'>[bicon(src)] Connecting to [station_name()] telecommunications array.</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connecting to [station_name()] telecommunications array.</span>")
sleep(40)
to_chat(new_voice, "<span class='notice'>[bicon(src)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].</span>")
sleep(20)
//We're connected, no need to hide everything.
new_voice.client.screen.Remove(blackness)
qdel(blackness)
to_chat(new_voice, "<span class='notice'>[bicon(src)] Connection to [src] established.</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connection to [src] established.</span>")
to_chat(new_voice, "<b>To talk to the person on the other end of the call, just talk normally.</b>")
to_chat(new_voice, "<b>If you want to end the call, use the 'Hang Up' verb. The other person can also hang up at any time.</b>")
to_chat(new_voice, "<b>Remember, your character does not know anything you've learned from observing!</b>")
if(new_voice.mind)
new_voice.mind.assigned_role = "Disembodied Voice"
if(user)
to_chat(user, "<span class='notice'>[bicon(src)] Your communicator is now connected to [candidate]'s communicator.</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Your communicator is now connected to [candidate]'s communicator.</span>")
// Proc: close_connection()
// Parameters: 3 (user - the user who initiated the disconnect, target - the mob or device being disconnected, reason - string shown when disconnected)
@@ -120,8 +120,8 @@
for(var/mob/living/voice/voice in voice_mobs) //Handle ghost-callers
if(target && voice != target) //If no target is inputted, it deletes all of them.
continue
to_chat(voice, "<span class='danger'>[bicon(src)] [reason].</span>")
visible_message("<span class='danger'>[bicon(src)] [reason].</span>")
to_chat(voice, "<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
voice_mobs.Remove(voice)
qdel(voice)
update_icon()
@@ -131,8 +131,8 @@
continue
src.del_communicating(comm)
comm.del_communicating(src)
comm.visible_message("<span class='danger'>[bicon(src)] [reason].</span>")
visible_message("<span class='danger'>[bicon(src)] [reason].</span>")
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
if(comm.camera && video_source == comm.camera) //We hung up on the person on video
end_video()
if(camera && comm.video_source == camera) //We hung up on them while they were watching us
@@ -163,7 +163,7 @@
if(ringer)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("[bicon(src)] *beep*"))
O.show_message(text("\icon[src][bicon(src)] *beep*"))
alert_called = 1
update_icon()
@@ -174,7 +174,7 @@
L = loc
if(L)
to_chat(L, "<span class='notice'>[bicon(src)] Communications request from [who].</span>")
to_chat(L, "<span class='notice'>\icon[src][bicon(src)] Communications request from [who].</span>")
// Proc: del_request()
// Parameters: 1 (candidate - the ghost or communicator to be declined)
@@ -197,13 +197,13 @@
us = loc
if(us)
to_chat(us, "<span class='notice'>[bicon(src)] Declined request.</span>")
to_chat(us, "<span class='notice'>\icon[src][bicon(src)] Declined request.</span>")
// Proc: see_emote()
// Parameters: 2 (M - the mob the emote originated from, text - the emote's contents)
// Description: Relays the emote to all linked communicators.
/obj/item/device/communicator/see_emote(mob/living/M, text)
var/rendered = "[bicon(src)] <span class='message'>[text]</span>"
var/rendered = "\icon[src][bicon(src)] <span class='message'>[text]</span>"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
@@ -250,14 +250,14 @@
var/message = combined["formatted"]
var/name_used = M.GetVoice()
var/rendered = null
rendered = "<span class='game say'>[bicon(src)] <span class='name'>[name_used]</span> [message]</span>"
rendered = "<span class='game say'>\icon[src][bicon(src)] <span class='name'>[name_used]</span> [message]</span>"
mob.show_message(rendered, 2)
// Proc: show_message()
// Parameters: 4 (msg - the message, type - number to determine if message is visible or audible, alt - unknown, alt_type - unknown)
// Description: Relays the message to all linked communicators.
/obj/item/device/communicator/show_message(msg, type, alt, alt_type)
var/rendered = "[bicon(src)] <span class='message'>[msg]</span>"
var/rendered = "\icon[src][bicon(src)] <span class='message'>[msg]</span>"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
@@ -339,15 +339,15 @@
return
if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something
to_chat(user, "<span class='danger'>[bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.</span>")
to_chat(user, "<span class='danger'>\icon[src][bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.</span>")
return
to_chat(user, "<span class='notice'>[bicon(src)] Attempting to start video over existing call.</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Attempting to start video over existing call.</span>")
sleep(30)
to_chat(user, "<span class='notice'>[bicon(src)] Please wait...</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Please wait...</span>")
video_source = comm.camera
comm.visible_message("<span class='danger'>[bicon(src)] New video connection from [comm].</span>")
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] New video connection from [comm].</span>")
update_active_camera_screen()
GLOB.moved_event.register(video_source, src, .proc/update_active_camera_screen)
update_icon()
@@ -360,7 +360,7 @@
show_static()
video_source = null
. = "<span class='danger'>[bicon(src)] [reason ? reason : "Video session ended"].</span>"
. = "<span class='danger'>\icon[src][bicon(src)] [reason ? reason : "Video session ended"].</span>"
visible_message(.)
update_icon()
@@ -227,11 +227,12 @@
. = ..()
if(!on)
return
var/datum/component/overlay_lighting/OL = GetComponent(/datum/component/overlay_lighting)
if(!OL)
return
var/turf/T = get_turf(target)
OL.place_directional_light(T)
if(light_system == MOVABLE_LIGHT_DIRECTIONAL)
var/datum/component/overlay_lighting/OL = GetComponent(/datum/component/overlay_lighting)
if(!OL)
return
var/turf/T = get_turf(target)
OL.place_directional_light(T)
/obj/item/device/flashlight/pen
name = "penlight"
+1 -1
View File
@@ -65,7 +65,7 @@
STOP_PROCESSING(SSobj, src)
update_icon()
update_sound()
to_chat(user, "<span class='notice'>[bicon(src)] You switch [scanning ? "on" : "off"] \the [src].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] You switch [scanning ? "on" : "off"] \the [src].</span>")
/obj/item/device/geiger/update_icon()
if(!scanning)
+1 -1
View File
@@ -323,7 +323,7 @@ var/list/GPS_list = list()
. = TRUE
if(href_list["tag"])
var/a = input(usr, "Please enter desired tag.", name, gps_tag) as text
var/a = tgui_input_text(usr, "Please enter desired tag.", name, gps_tag)
a = uppertext(copytext(sanitize(a), 1, 11))
if(in_range(src, usr))
gps_tag = a
+1 -1
View File
@@ -47,7 +47,7 @@
to_chat(user, "<span class='warning'>You are already hacking!</span>")
return 0
if(!is_type_in_list(target, supported_types))
to_chat(user, "[bicon(src)] <span class='warning'>Unable to hack this target!</span>")
to_chat(user, "\icon[src][bicon(src)] <span class='warning'>Unable to hack this target!</span>")
return 0
var/found = known_targets.Find(target)
if(found)
@@ -68,7 +68,7 @@
if(active.fields["arrestsearch"] == "arrest")
var/output = {"
<HTML><HEAD><TITLE>[active.fields["namewarrant"]]</TITLE></HEAD>
<BODY bgcolor='#FFFFFF'><center><large><b>Sol Central Government Colonial Marshal Bureau</b></large></br>
<BODY bgcolor='#FFFFFF'><center><large><b>Commonwealth Security Bond Association</b></large></br>
in the jurisdiction of the</br>
[using_map.boss_name] in [using_map.station_name]</br>
</br>
@@ -115,7 +115,7 @@
name = "holowarrant devices"
desc = "A box of holowarrant diplays for security use."
/obj/item/weapon/storage/box/holowarrants/New()
/obj/item/weapon/storage/box/holowarrants/New()
..()
for(var/i = 0 to 3)
new /obj/item/device/holowarrant(src) // VOREStation addition ends
+1 -1
View File
@@ -40,7 +40,7 @@
user.audible_message("<B>[user.GetVoice()]</B>[user.GetAltName()] broadcasts, <FONT size=3>\"[message]\"</FONT>", runemessage = message)
/obj/item/device/megaphone/attack_self(var/mob/living/user)
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
var/message = sanitize(tgui_input_text(user, "Shout a message?", "Megaphone", null))
if(!message)
return
message = capitalize(message)
+213 -38
View File
@@ -1,3 +1,20 @@
var/global/list/radio_channels_by_freq = list(
num2text(PUB_FREQ) = "Common",
num2text(AI_FREQ) = "AI Private",
num2text(ENT_FREQ) = "Entertainment",
num2text(ERT_FREQ) = "Response Team",
num2text(COMM_FREQ)= "Command",
num2text(ENG_FREQ) = "Engineering",
num2text(MED_FREQ) = "Medical",
num2text(MED_I_FREQ)="Medical(I)",
num2text(SEC_FREQ) = "Security",
num2text(SEC_I_FREQ)="Security(I)",
num2text(SCI_FREQ) = "Science",
num2text(SUP_FREQ) = "Supply",
num2text(SRV_FREQ) = "Service",
num2text(EXP_FREQ) = "Explorer"
)
GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
/obj/item/device/paicard
@@ -6,14 +23,18 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
icon_state = "pai"
item_state = "electronic"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
slot_flags = SLOT_BELT | SLOT_HOLSTER
origin_tech = list(TECH_DATA = 2)
show_messages = 0
preserve_item = 1
var/obj/item/device/radio/radio
var/obj/item/device/radio/borg/pai/radio
var/looking_for_personality = 0
var/mob/living/silicon/pai/pai
var/image/screen_layer
var/screen_color = "#00ff0d"
var/last_notify = 0
var/screen_msg
/obj/item/device/paicard/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
@@ -37,27 +58,86 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
/obj/item/device/paicard/attack_ghost(mob/user as mob)
if(pai != null) //Have a person in them already?
return ..()
if(is_damage_critical())
to_chat(usr, "<span class='warning'>That card is too damaged to activate!</span>")
return
var/time_till_respawn = user.time_till_respawn()
if(time_till_respawn == -1) // Special case, never allowed to respawn
to_chat(usr, "<span class='warning'>Respawning is not allowed!</span>")
else if(time_till_respawn) // Nonzero time to respawn
to_chat(usr, "<span class='warning'>You can't do that yet! You died too recently. You need to wait another [round(time_till_respawn/10/60, 0.1)] minutes.</span>")
return
if(jobban_isbanned(usr, "pAI"))
to_chat(usr,"<span class='warning'>You cannot join a pAI card when you are banned from playing as a pAI.</span>")
return
var/choice = tgui_alert(user, "You sure you want to inhabit this PAI?", "Confirmation", list("Yes", "No"))
if(choice == "No")
for(var/ourkey in paikeys)
if(ourkey == user.ckey)
to_chat(usr, "<span class='warning'>You can't just rejoin any old pAI card!!! Your card still exists.</span>")
return
var/choice = tgui_alert(user, "You sure you want to inhabit this PAI, or submit yourself to being recruited?", "Confirmation", list("Inhabit", "Recruit", "Cancel"))
if(choice == "Cancel")
return ..()
var/pai_name = input(user, "Choose your character's name", "Character Name") as text
var/actual_pai_name = sanitize_name(pai_name)
if(isnull(actual_pai_name))
if(choice == "Recruit")
paiController.recruitWindow(user)
return ..()
choice = tgui_alert(user, "Do you want to load your pAI data?", "Load", list("Yes", "No"))
var/actual_pai_name
var/turf/location = get_turf(src)
var/obj/item/device/paicard/card = new(location)
var/mob/living/silicon/pai/new_pai = new(card)
if(choice == "No")
var/pai_name = tgui_input_text(user, "Choose your character's name", "Character Name")
actual_pai_name = sanitize_name(pai_name, ,1)
if(isnull(actual_pai_name))
return ..()
if(istype(src , /obj/item/device/paicard/typeb))
var/obj/item/device/paicard/typeb/card = new(location)
var/mob/living/silicon/pai/new_pai = new(card)
new_pai.key = user.key
paikeys |= new_pai.ckey
card.setPersonality(new_pai)
new_pai.SetName(actual_pai_name)
else
var/obj/item/device/paicard/card = new(location)
var/mob/living/silicon/pai/new_pai = new(card)
new_pai.key = user.key
paikeys |= new_pai.ckey
card.setPersonality(new_pai)
new_pai.SetName(actual_pai_name)
if(choice == "Yes")
if(istype(src , /obj/item/device/paicard/typeb))
var/obj/item/device/paicard/typeb/card = new(location)
var/mob/living/silicon/pai/new_pai = new(card)
new_pai.key = user.key
paikeys |= new_pai.ckey
card.setPersonality(new_pai)
if(!new_pai.savefile_load(new_pai))
var/pai_name = tgui_input_text(new_pai, "Choose your character's name", "Character Name")
actual_pai_name = sanitize_name(pai_name, ,1)
if(isnull(actual_pai_name))
return ..()
else
var/obj/item/device/paicard/card = new(location)
var/mob/living/silicon/pai/new_pai = new(card)
new_pai.key = user.key
paikeys |= new_pai.ckey
card.setPersonality(new_pai)
if(!new_pai.savefile_load(new_pai))
var/pai_name = tgui_input_text(new_pai, "Choose your character's name", "Character Name")
actual_pai_name = sanitize_name(pai_name, ,1)
if(isnull(actual_pai_name))
return ..()
qdel(src)
new_pai.key = user.key
card.setPersonality(new_pai)
new_pai.SetName(actual_pai_name)
return ..()
// VOREStation Edit End
/obj/item/device/paicard/attack_self(mob/user)
/obj/item/device/paicard/proc/access_screen(mob/user)
if(is_damage_critical())
to_chat(user, "<span class='warning'>WARNING: CRITICAL HARDWARE FAILURE, SERVICE DEVICE IMMEDIATELY</span>")
return
if (!in_range(src, user))
return
user.set_machine(src)
@@ -162,8 +242,10 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
<b><font size='3px'>Personal AI Device</font></b><br><br>
<table class="request">
<tr>
<td class="request">Installed Personality:</td>
<td>[pai.name]</td>
<td><font size='5px'; color=[screen_color]><b>[pai.name]</b></font></td>
</tr>
<tr>
<td class="request">Integrity: [pai.health]</td>
</tr>
<tr>
<td class="request">Prime directive:</td>
@@ -214,6 +296,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
else //</font></font>
dat += "<b>Radio Uplink</b><br>"
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
/* - //A button for instantly deleting people from the game is lame, especially considering that pAIs on our server tend to activate without a master.
dat += {"
<table>
<td class="button_red"><a href='byond://?src=\ref[src];wipe=1' class='button'>Wipe current pAI personality</a>
@@ -221,6 +304,9 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
</td>
</table>
"}
*/
if(screen_msg)
dat += "<b>Message from [pai.name]</b><br>[screen_msg]"
else
if(looking_for_personality)
dat += {"
@@ -290,7 +376,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
if(2)
radio.ToggleReception()
if(href_list["setlaws"])
var/newlaws = sanitize(input(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message)
var/newlaws = sanitize(tgui_input_text(usr, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws, multiline = TRUE, prevent_enter = TRUE))
if(newlaws)
pai.pai_laws = newlaws
to_chat(pai, "Your supplemental directives have been updated. Your new directives are:")
@@ -304,40 +390,48 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
/obj/item/device/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
src.pai = personality
add_overlay("pai-happy")
setEmotion(1)
/obj/item/device/paicard/proc/removePersonality()
src.pai = null
cut_overlays()
add_overlay("pai-off")
setEmotion(16)
/obj/item/device/paicard
var/current_emotion = 1
/obj/item/device/paicard/proc/setEmotion(var/emotion)
if(pai)
cut_overlays()
qdel(screen_layer)
screen_layer = null
switch(emotion)
if(1) add_overlay("pai-happy")
if(2) add_overlay("pai-cat")
if(3) add_overlay("pai-extremely-happy")
if(4) add_overlay("pai-face")
if(5) add_overlay("pai-laugh")
if(6) add_overlay("pai-off")
if(7) add_overlay("pai-sad")
if(8) add_overlay("pai-angry")
if(9) add_overlay("pai-what")
if(10) add_overlay("pai-neutral")
if(11) add_overlay("pai-silly")
if(12) add_overlay("pai-nose")
if(13) add_overlay("pai-smirk")
if(14) add_overlay("pai-exclamation")
if(15) add_overlay("pai-question")
if(1) screen_layer = image(icon, "pai-neutral")
if(2) screen_layer = image(icon, "pai-what")
if(3) screen_layer = image(icon, "pai-happy")
if(4) screen_layer = image(icon, "pai-cat")
if(5) screen_layer = image(icon, "pai-extremely-happy")
if(6) screen_layer = image(icon, "pai-face")
if(7) screen_layer = image(icon, "pai-laugh")
if(8) screen_layer = image(icon, "pai-sad")
if(9) screen_layer = image(icon, "pai-angry")
if(10) screen_layer = image(icon, "pai-silly")
if(11) screen_layer = image(icon, "pai-nose")
if(12) screen_layer = image(icon, "pai-smirk")
if(13) screen_layer = image(icon, "pai-exclamation")
if(14) screen_layer = image(icon, "pai-question")
if(15) screen_layer = image(icon, "pai-blank")
if(16) screen_layer = image(icon, "pai-off")
screen_layer.color = pai.eye_color
add_overlay(screen_layer)
current_emotion = emotion
/obj/item/device/paicard/proc/alertUpdate()
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("<span class='notice'>\The [src] flashes a message across its screen, \"Additional personalities available for download.\"</span>", 3, "<span class='notice'>\The [src] bleeps electronically.</span>", 2)
if(pai)
return
if(last_notify == 0 || (5 MINUTES <= world.time - last_notify))
audible_message("<span class='notice'>\The [src] flashes a message across its screen, \"Additional personalities available for download.\"</span>", hearing_distance = world.view, runemessage = "bleeps!")
last_notify = world.time
/obj/item/device/paicard/emp_act(severity)
for(var/mob/M in src)
@@ -360,3 +454,84 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
var/rendered = "<span class='message'>[msg]</span>"
pai.show_message(rendered, type)
..()
// VoreEdit: Living Machine Stuff after this.
// This adds a var and proc for all machines to take a pAI. (The pAI can't control anything, it's just for RP.)
// You need to add usage of the proc to each machine to actually add support. For an example of this, see code\modules\food\kitchen\microwave.dm
/obj/machinery
var/obj/item/device/paicard/paicard = null
/obj/machinery/proc/insertpai(mob/user, obj/item/device/paicard/card)
//var/obj/item/paicard/card = I
var/mob/living/silicon/pai/AI = card.pai
if(paicard)
to_chat(user, span_notice("This bot is already under PAI Control!"))
return
if(!istype(card)) // TODO: Add sleevecard support.
return
if(!card.pai)
to_chat(user, span_notice("This card does not currently have a personality!"))
return
paicard = card
user.unEquip(card)
card.forceMove(src)
AI.client.eye = src
to_chat(AI, span_notice("Your location is [card.loc].")) // DEBUG. TODO: Make unfolding the chassis trigger an eject.
name = AI.name
to_chat(AI, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)]."))
/obj/machinery/proc/ejectpai(mob/user)
if(paicard)
var/mob/living/silicon/pai/AI = paicard.pai
paicard.forceMove(src.loc)
AI.client.eye = AI
paicard = null
name = initial(src.name)
to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)]."))
if(user)
to_chat(user, span_notice("You eject the card from \the [initial(src.name)]."))
///////////////////////////////
//////////pAI Radios//////////
///////////////////////////////
//Thanks heroman!
/obj/item/device/radio/borg/pai
name = "integrated radio"
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
icon_state = "radio"
loudspeaker = FALSE
/obj/item/device/radio/borg/pai/attackby(obj/item/weapon/W as obj, mob/user as mob)
return
/obj/item/device/radio/borg/pai/recalculateChannels()
if(!istype(loc,/obj/item/device/paicard))
return
var/obj/item/device/paicard/card = loc
secure_radio_connections = list()
channels = list()
for(var/internal_chan in internal_channels)
var/ch_name = radio_channels_by_freq[internal_chan]
if(has_channel_access(card.pai, internal_chan))
channels += ch_name
channels[ch_name] = 1
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
/obj/item/device/paicard/typeb
name = "personal AI device"
icon = 'icons/obj/paicard.dmi'
/obj/random/paicard
name = "personal AI device spawner"
icon = 'icons/obj/paicard.dmi'
icon_state = "pai"
/obj/random/paicard/item_to_spawn()
return pick(/obj/item/device/paicard ,/obj/item/device/paicard/typeb)
/obj/item/device/paicard/digest_act(var/atom/movable/item_storage = null)
if(pai.digestable)
return ..()
@@ -0,0 +1,385 @@
#define PP_FUNCTIONAL 0
#define PP_BROKEN 1
#define PP_MISSING 2
var/global/list/paikeys = list()
/obj/item/device/paicard
var/panel_open = FALSE
var/cell = PP_FUNCTIONAL //critical- power
var/processor = PP_FUNCTIONAL //critical- the thinky part
var/board = PP_FUNCTIONAL //critical- makes everything work
var/capacitor = PP_FUNCTIONAL //critical- power processing
var/projector = PP_FUNCTIONAL //non-critical- affects unfolding
var/emitter = PP_FUNCTIONAL //non-critical- affects unfolding
var/speech_synthesizer = PP_FUNCTIONAL //non-critical- affects speech
/obj/item/device/paicard/attackby(var/obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/weapon/tool/screwdriver))
if(panel_open)
panel_open = FALSE
user.visible_message("<span class ='notice'>\The [user] secured \the [src]'s maintenance panel.</span>")
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
else if(pai)
if(do_after(user, 3 SECONDS))
panel_open = TRUE
user.visible_message("<span class ='warning'>\The [user] opened \the [src]'s maintenance panel.</span>")
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
if(istype(I,/obj/item/device/robotanalyzer))
if(!panel_open)
to_chat(user, "<span class ='warning'>The panel isn't open. You will need to unscrew it to open it.</span>")
else
if(cell == PP_FUNCTIONAL)
to_chat(user,"Power cell: <span class ='notice'>functional</span>")
else if(cell == PP_BROKEN)
to_chat(user,"Power cell: <span class ='warning'>damaged - CRITICAL</span>")
else
to_chat(user,"Power cell: <span class ='warning'>missing - CRITICAL</span>")
if(processor == PP_FUNCTIONAL)
to_chat(user,"Processor: <span class ='notice'>functional</span>")
else if(processor == PP_BROKEN)
to_chat(user,"Processor: <span class ='warning'>damaged - CRITICAL</span>")
else
to_chat(user,"Processor: <span class ='warning'>missing - CRITICAL</span>")
if(board == PP_FUNCTIONAL)
to_chat(user,"Board: <span class ='notice'>functional</span>")
else if(board == PP_BROKEN)
to_chat(user,"Board: <span class ='warning'>damaged - CRITICAL</span>")
else
to_chat(user,"Board: <span class ='warning'>missing - CRITICAL</span>")
if(capacitor == PP_FUNCTIONAL)
to_chat(user,"Capacitors: <span class ='notice'>functional</span>")
else if(capacitor == PP_BROKEN)
to_chat(user,"Capacitors: <span class ='warning'>damaged - CRITICAL</span>")
else
to_chat(user,"Capacitors: <span class ='warning'>missing - CRITICAL</span>")
if(projector == PP_FUNCTIONAL)
to_chat(user,"Projectors: <span class ='notice'>functional</span>")
else if(projector == PP_BROKEN)
to_chat(user,"Projectors: <span class ='warning'>damaged</span>")
else
to_chat(user,"Projectors: <span class ='warning'>missing</span>")
if(emitter == PP_FUNCTIONAL)
to_chat(user,"Emitters: <span class ='notice'>functional</span>")
else if(emitter == PP_BROKEN)
to_chat(user,"Emitters: <span class ='warning'>damaged</span>")
else
to_chat(user,"Emitters: <span class ='warning'>missing</span>")
if(speech_synthesizer == PP_FUNCTIONAL)
to_chat(user,"Speech Synthesizer: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Speech Synthesizer: <span class ='warning'>damaged</span>")
else
to_chat(user,"Speech Synthesizer: <span class ='warning'>missing</span>")
if(istype(I,/obj/item/device/multitool))
if(!panel_open)
to_chat(user, "<span class ='warning'>You can't do that in this state.</span>")
else
var/list/parts = list()
if(cell != PP_MISSING)
parts |= "cell"
if(processor != PP_MISSING)
parts |= "processor"
if(board != PP_MISSING)
parts |= "board"
if(capacitor != PP_MISSING)
parts |= "capacitor"
if(projector != PP_MISSING)
parts |= "projector"
if(emitter != PP_MISSING)
parts |= "emitter"
if(speech_synthesizer != PP_MISSING)
parts |= "speech synthesizer"
var/choice = tgui_input_list(user, "Which part would you like to check?", "Check part", parts)
switch(choice)
if("cell")
if(cell == PP_FUNCTIONAL)
to_chat(user,"Power cell: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Power cell: <span class ='warning'>damaged</span>")
else
to_chat(user,"Power cell: <span class ='warning'>missing</span>")
if("processor")
if(processor == PP_FUNCTIONAL)
to_chat(user,"Processor: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Processor: <span class ='warning'>damaged</span>")
else
to_chat(user,"Processor: <span class ='warning'>missing</span>")
if("board")
if(board == PP_FUNCTIONAL)
to_chat(user,"Board: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Board: <span class ='warning'>damaged</span>")
else
to_chat(user,"Board: <span class ='warning'>missing</span>")
if("capacitor")
if(capacitor == PP_FUNCTIONAL)
to_chat(user,"Capacitors: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Capacitors: <span class ='warning'>damaged</span>")
else
to_chat(user,"Capacitors: <span class ='warning'>missing</span>")
if("projector")
if(projector == PP_FUNCTIONAL)
to_chat(user,"Projectors: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Projectors: <span class ='warning'>damaged</span>")
else
to_chat(user,"Projectors: <span class ='warning'>missing</span>")
if("emitter")
if(emitter == PP_FUNCTIONAL)
to_chat(user,"Emitters: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Emitters: <span class ='warning'>damaged</span>")
else
to_chat(user,"Emitters: <span class ='warning'>missing</span>")
if("speech synthesizer")
if(speech_synthesizer == PP_FUNCTIONAL)
to_chat(user,"Speech Synthesizer: <span class ='notice'>functional</span>")
else if(speech_synthesizer == PP_BROKEN)
to_chat(user,"Speech Synthesizer: <span class ='warning'>damaged</span>")
else
to_chat(user,"Speech Synthesizer: <span class ='warning'>missing</span>")
if(istype(I,/obj/item/paiparts/cell))
if(cell == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
cell = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
if(istype(I,/obj/item/paiparts/processor))
if(processor == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
processor = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
if(istype(I,/obj/item/paiparts/board))
if(board == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
board = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
if(istype(I,/obj/item/paiparts/capacitor))
if(capacitor == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
capacitor = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
if(istype(I,/obj/item/paiparts/projector))
if(projector == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
projector = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
if(istype(I,/obj/item/paiparts/emitter))
if(emitter == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
emitter = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
if(istype(I,/obj/item/paiparts/speech_synthesizer))
if(speech_synthesizer == PP_MISSING)
if(do_after(user, 3 SECONDS))
user.visible_message("<span class ='notice'>\The [user] installs \the [I] into \the [src].</span>","<span class ='notice'>You install \the [I] into \the [src].</span>")
speech_synthesizer = PP_FUNCTIONAL
user.drop_from_inventory(I)
qdel(I)
else
to_chat(user, "<span class ='warning'>You would need to remove the installed [I] first!</span>")
/obj/item/device/paicard/attack_self(mob/user)
if(!panel_open)
access_screen(user)
return
var/list/parts = list()
if(cell != PP_MISSING)
parts |= "cell"
if(processor != PP_MISSING)
parts |= "processor"
if(board != PP_MISSING)
parts |= "board"
if(capacitor != PP_MISSING)
parts |= "capacitor"
if(projector != PP_MISSING)
parts |= "projector"
if(emitter != PP_MISSING)
parts |= "emitter"
if(speech_synthesizer != PP_MISSING)
parts |= "speech synthesizer"
var/choice = tgui_input_list(user, "Which part would you like to remove?", "Remove part", parts)
if(choice)
playsound(src, 'sound/items/pickup/component.ogg', vary = TRUE)
else
return
if(!do_after(user, 3 SECONDS))
return
switch(choice)
if("cell")
if(cell == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
cell = PP_MISSING
if("processor")
if(processor == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
processor = PP_MISSING
if("board")
board = PP_MISSING
if(board == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
if("capacitor")
if(capacitor == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
capacitor = PP_MISSING
if("projector")
if(projector == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
projector = PP_MISSING
if("emitter")
if(emitter == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
emitter = PP_MISSING
if("speech synthesizer")
if(speech_synthesizer == PP_FUNCTIONAL)
new /obj/item/paiparts/capacitor(get_turf(user))
else
new /obj/item/paiparts(get_turf(user))
user.visible_message("<span class ='warning'>\The [user] removes \the [choice] from \the [src].</span>","<span class ='warning'>You remove \the [choice] from \the [src].</span>")
speech_synthesizer = PP_MISSING
/obj/item/device/paicard/proc/death_damage()
var/number = rand(1,4)
while(number)
number --
switch(rand(1,4))
if(1)
cell = PP_BROKEN
if(2)
processor = PP_BROKEN
if(3)
board = PP_BROKEN
if(4)
capacitor = PP_BROKEN
/obj/item/device/paicard/proc/damage_random_component(nonfatal = FALSE)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
if(prob(80) || nonfatal) //Way more likely to be non-fatal part damage
switch(rand(1,3))
if(1)
projector = PP_BROKEN
if(2)
emitter = PP_BROKEN
if(3)
speech_synthesizer = PP_BROKEN
else
switch(rand(1,4))
if(1)
cell = PP_BROKEN
if(2)
processor = PP_BROKEN
if(3)
board = PP_BROKEN
if(4)
capacitor = PP_BROKEN
/obj/item/device/paicard/proc/is_damage_critical()
if(cell != PP_FUNCTIONAL || processor != PP_FUNCTIONAL || board != PP_FUNCTIONAL || capacitor != PP_FUNCTIONAL)
return TRUE
return FALSE
/obj/item/paiparts
name = "broken pAI component"
desc = "It's broken scrap from a pAI card!"
icon = 'icons/obj/paicard.dmi'
icon_state = "broken"
pickup_sound = 'sound/items/pickup/card.ogg'
drop_sound = 'sound/items/drop/card.ogg'
/obj/item/paiparts/Initialize()
. = ..()
pixel_x = rand(-10,10)
pixel_y = rand(-10,10)
/obj/item/paiparts/cell
name = "pAI power cell"
desc = "It's very small and efficient! It powers the pAI!"
icon_state = "cell"
/obj/item/paiparts/processor
name = "pAI processor"
desc = "It's the brain of your computer friend!"
icon_state = "processor"
/obj/item/paiparts/board
name = "pAI board"
desc = "It's the thing all the other parts get attatched to!"
icon_state = "board"
/obj/item/paiparts/capacitor
name = "pAI capacitor"
desc = "It helps regulate power flow!"
icon_state = "capacitor"
/obj/item/paiparts/projector
name = "pAI projector"
desc = "It projects the pAI's form!"
icon_state = "projector"
/obj/item/paiparts/emitter
name = "pAI emitter"
desc = "It emits the fields to help the pAI get around!"
icon_state = "emitter"
/obj/item/paiparts/speech_synthesizer
name = "pAI speech synthesizer"
desc = "It's a little voice box!"
icon_state = "speech_synthesizer"
@@ -489,7 +489,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
var/list/jamming = is_jammed(src)
if(jamming)
var/distance = jamming["distance"]
to_chat(M, "<span class='danger'>[bicon(src)] You hear the [distance <= 2 ? "loud hiss" : "soft hiss"] of static.</span>")
to_chat(M, "<span class='danger'>\icon[src][bicon(src)] You hear the [distance <= 2 ? "loud hiss" : "soft hiss"] of static.</span>")
return FALSE
// First, we want to generate a new radio signal
@@ -0,0 +1,36 @@
/obj/item/device/analyzer
name = "gas analyzer"
desc = "A hand-held environmental scanner which reports current gas levels."
icon_state = "atmos"
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
/obj/item/device/analyzer/atmosanalyze(var/mob/user)
var/air = user.return_air()
if (!air)
return
return atmosanalyzer_scan(src, air, user)
/obj/item/device/analyzer/attack_self(mob/user as mob)
if (user.stat)
return
if (!user.IsAdvancedToolUser())
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
analyze_gases(src, user)
return
/obj/item/device/analyzer/afterattack(var/obj/O, var/mob/user, var/proximity)
if(proximity)
analyze_gases(O, user)
return
@@ -0,0 +1,20 @@
/obj/item/device/halogen_counter
name = "halogen counter"
icon_state = "eftpos"
desc = "A hand-held halogen counter, used to detect the level of irradiation of living beings."
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 2)
throwforce = 0
throw_speed = 3
throw_range = 7
/obj/item/device/halogen_counter/attack(mob/living/M as mob, mob/living/user as mob)
if(!iscarbon(M))
to_chat(user, "<span class='warning'>This device can only scan organic beings!</span>")
return
user.visible_message("<span class='warning'>\The [user] has analyzed [M]'s radiation levels!</span>", "<span class='notice'>Analyzing Results for [M]:</span>")
if(M.radiation)
to_chat(user, "<span class='notice'>Radiation Level: [M.radiation]</span>")
else
to_chat(user, "<span class='notice'>No radiation detected.</span>")
return
@@ -1,15 +1,4 @@
#define DEFIB_TIME_LIMIT (10 MINUTES) //VOREStation addition- past this many seconds, defib is useless.
/*
CONTAINS:
T-RAY
DETECTIVE SCANNER
HEALTH ANALYZER
GAS ANALYZER - Analyzes atmosphere, container
MASS SPECTROMETER
REAGENT SCANNER
HALOGEN COUNTER - Radcount on mobs
*/
/obj/item/device/healthanalyzer
name = "health analyzer"
@@ -52,7 +41,7 @@ HALOGEN COUNTER - Radcount on mobs
dat += "Body Temperature: ???"
user.show_message("<span class='notice'>[dat]</span>", 1)
return
if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
@@ -240,7 +229,7 @@ HALOGEN COUNTER - Radcount on mobs
continue
// Broken limbs
if(e.status & ORGAN_BROKEN)
if((e.name in list("l_arm", "r_arm", "l_leg", "r_leg", "head", "chest", "groin")) && (!e.splinted))
if((e.name in list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_HEAD, BP_TORSO, BP_GROIN)) && (!e.splinted))
fracture_dat += "<span class='warning'>Unsecured fracture in subject [e.name]. Splinting recommended for transport.</span><br>"
else if(advscan >= 1 && showadvscan == 1)
fracture_dat += "<span class='warning'>Bone fractures detected in subject [e.name].</span><br>"
@@ -335,214 +324,4 @@ HALOGEN COUNTER - Radcount on mobs
origin_tech = list(TECH_MAGNET = 7, TECH_BIO = 8)
icon_state = "health3"
/obj/item/device/analyzer
name = "analyzer"
desc = "A hand-held environmental scanner which reports current gas levels."
icon_state = "atmos"
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
/obj/item/device/analyzer/atmosanalyze(var/mob/user)
var/air = user.return_air()
if (!air)
return
return atmosanalyzer_scan(src, air, user)
/obj/item/device/analyzer/attack_self(mob/user as mob)
if (user.stat)
return
if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
analyze_gases(src, user)
return
/obj/item/device/analyzer/afterattack(var/obj/O, var/mob/user, var/proximity)
if(proximity)
analyze_gases(O, user)
return
/obj/item/device/mass_spectrometer
name = "mass spectrometer"
desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
icon_state = "spectrometer"
w_class = ITEMSIZE_SMALL
flags = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
var/details = 0
var/recent_fail = 0
/obj/item/device/mass_spectrometer/Initialize()
. = ..()
var/datum/reagents/R = new/datum/reagents(5)
reagents = R
R.my_atom = src
/obj/item/device/mass_spectrometer/on_reagent_change()
if(reagents.total_volume)
icon_state = initial(icon_state) + "_s"
else
icon_state = initial(icon_state)
/obj/item/device/mass_spectrometer/attack_self(mob/user as mob)
if (user.stat)
return
if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(reagents.total_volume)
var/list/blood_traces = list()
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id != "blood")
reagents.clear_reagents()
to_chat(user, "<span class='warning'>The sample was contaminated! Please insert another sample</span>")
return
else
blood_traces = params2list(R.data["trace_chem"])
break
var/dat = "Trace Chemicals Found: "
for(var/R in blood_traces)
if(details)
dat += "[R] ([blood_traces[R]] units) "
else
dat += "[R] "
to_chat(user, "[dat]")
reagents.clear_reagents()
return
/obj/item/device/mass_spectrometer/adv
name = "advanced mass spectrometer"
icon_state = "adv_spectrometer"
details = 1
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
/obj/item/device/reagent_scanner
name = "reagent scanner"
desc = "A hand-held reagent scanner which identifies chemical agents."
icon_state = "spectrometer"
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
var/details = 0
var/recent_fail = 0
/obj/item/device/reagent_scanner/afterattack(obj/O, mob/living/user, proximity)
if(!proximity || user.stat || !istype(O))
return
if(!istype(user))
return
if(!isnull(O.reagents))
if(!(O.flags & OPENCONTAINER)) // The idea is that the scanner has to touch the reagents somehow. This is done to prevent cheesing unidentified autoinjectors.
to_chat(user, span("warning", "\The [O] is sealed, and cannot be scanned by \the [src] until unsealed."))
return
var/dat = ""
if(O.reagents.reagent_list.len > 0)
var/one_percent = O.reagents.total_volume / 100
for (var/datum/reagent/R in O.reagents.reagent_list)
dat += "\n \t " + span("notice", "[R][details ? ": [R.volume / one_percent]%" : ""]")
if(dat)
to_chat(user, span("notice", "Chemicals found: [dat]"))
else
to_chat(user, span("notice", "No active chemical agents found in [O]."))
else
to_chat(user, span("notice", "No significant chemical agents found in [O]."))
return
/obj/item/device/reagent_scanner/adv
name = "advanced reagent scanner"
icon_state = "adv_spectrometer"
details = 1
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
/obj/item/device/slime_scanner
name = "slime scanner"
icon_state = "xenobio"
item_state = "xenobio"
origin_tech = list(TECH_BIO = 1)
w_class = ITEMSIZE_SMALL
throwforce = 0
throw_speed = 3
throw_range = 7
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
/obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob)
if(!istype(M, /mob/living/simple_mob/slime/xenobio))
to_chat(user, "<B>This device can only scan lab-grown slimes!</B>")
return
var/mob/living/simple_mob/slime/xenobio/S = M
user.show_message("Slime scan results:<br>[S.slime_color] [S.is_adult ? "adult" : "baby"] slime<br>Health: [S.health]<br>Mutation Probability: [S.mutation_chance]")
var/list/mutations = list()
for(var/potential_color in S.slime_mutation)
var/mob/living/simple_mob/slime/xenobio/slime = potential_color
mutations.Add(initial(slime.slime_color))
user.show_message("Potental to mutate into [english_list(mutations)] colors.<br>Extract potential: [S.cores]<br>Nutrition: [S.nutrition]/[S.max_nutrition]")
if (S.nutrition < S.get_starve_nutrition())
user.show_message("<span class='alert'>Warning: Subject is starving!</span>")
else if (S.nutrition < S.get_hunger_nutrition())
user.show_message("<span class='warning'>Warning: Subject is hungry.</span>")
user.show_message("Electric change strength: [S.power_charge]")
if(S.has_AI())
var/datum/ai_holder/simple_mob/xenobio_slime/AI = S.ai_holder
if(AI.resentment)
user.show_message("<span class='warning'>Warning: Subject is harboring resentment.</span>")
if(AI.rabid)
user.show_message("<span class='danger'>Subject is enraged and extremely dangerous!</span>")
if(S.harmless)
user.show_message("Subject has been pacified.")
if(S.unity)
user.show_message("Subject is friendly to other slime colors.")
user.show_message("Growth progress: [S.amount_grown]/10")
/obj/item/device/halogen_counter
name = "halogen counter"
icon_state = "eftpos"
desc = "A hand-held halogen counter, used to detect the level of irradiation of living beings."
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 2)
throwforce = 0
throw_speed = 3
throw_range = 7
/obj/item/device/halogen_counter/attack(mob/living/M as mob, mob/living/user as mob)
if(!iscarbon(M))
to_chat(user, "<span class='warning'>This device can only scan organic beings!</span>")
return
user.visible_message("<span class='warning'>\The [user] has analyzed [M]'s radiation levels!</span>", "<span class='notice'>Analyzing Results for [M]:</span>")
if(M.radiation)
to_chat(user, "<span class='notice'>Radiation Level: [M.radiation]</span>")
else
to_chat(user, "<span class='notice'>No radiation detected.</span>")
return
#undef DEFIB_TIME_LIMIT //VOREStation addition
@@ -0,0 +1,60 @@
/obj/item/device/mass_spectrometer
name = "mass spectrometer"
desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
icon_state = "spectrometer"
w_class = ITEMSIZE_SMALL
flags = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
var/details = 0
var/recent_fail = 0
/obj/item/device/mass_spectrometer/New()
..()
var/datum/reagents/R = new/datum/reagents(5)
reagents = R
R.my_atom = src
/obj/item/device/mass_spectrometer/on_reagent_change()
if(reagents.total_volume)
icon_state = initial(icon_state) + "_s"
else
icon_state = initial(icon_state)
/obj/item/device/mass_spectrometer/attack_self(mob/user as mob)
if (user.stat)
return
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(reagents.total_volume)
var/list/blood_traces = list()
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id != "blood")
reagents.clear_reagents()
to_chat(user, "<span class='warning'>The sample was contaminated! Please insert another sample</span>")
return
else
blood_traces = params2list(R.data["trace_chem"])
break
var/dat = "Trace Chemicals Found: "
for(var/R in blood_traces)
if(details)
dat += "[R] ([blood_traces[R]] units) "
else
dat += "[R] "
to_chat(user, "[dat]")
reagents.clear_reagents()
return
/obj/item/device/mass_spectrometer/adv
name = "advanced mass spectrometer"
icon_state = "adv_spectrometer"
details = 1
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
@@ -0,0 +1,46 @@
/obj/item/device/reagent_scanner
name = "reagent scanner"
desc = "A hand-held reagent scanner which identifies chemical agents."
icon_state = "spectrometer"
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
var/details = 0
var/recent_fail = 0
/obj/item/device/reagent_scanner/afterattack(obj/O, mob/living/user, proximity)
if(!proximity || user.stat || !istype(O))
return
if(!istype(user))
return
if(!isnull(O.reagents))
if(!(O.flags & OPENCONTAINER)) // The idea is that the scanner has to touch the reagents somehow. This is done to prevent cheesing unidentified autoinjectors.
to_chat(user, span("warning", "\The [O] is sealed, and cannot be scanned by \the [src] until unsealed."))
return
var/dat = ""
if(O.reagents.reagent_list.len > 0)
var/one_percent = O.reagents.total_volume / 100
for (var/datum/reagent/R in O.reagents.reagent_list)
dat += "\n \t " + span("notice", "[R][details ? ": [R.volume / one_percent]%" : ""]")
if(dat)
to_chat(user, span("notice", "Chemicals found: [dat]"))
else
to_chat(user, span("notice", "No active chemical agents found in [O]."))
else
to_chat(user, span("notice", "No significant chemical agents found in [O]."))
return
/obj/item/device/reagent_scanner/adv
name = "advanced reagent scanner"
icon_state = "adv_spectrometer"
details = 1
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
@@ -300,4 +300,4 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
if(stored_mind)
icon_state = "[initial(icon_state)]_on"
else
icon_state = initial(icon_state)
icon_state = initial(icon_state)
@@ -0,0 +1,42 @@
/obj/item/device/slime_scanner
name = "slime scanner"
icon_state = "xenobio"
item_state = "xenobio"
origin_tech = list(TECH_BIO = 1)
w_class = ITEMSIZE_SMALL
throwforce = 0
throw_speed = 3
throw_range = 7
matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
/obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob)
if(!istype(M, /mob/living/simple_mob/slime/xenobio))
to_chat(user, "<B>This device can only scan lab-grown slimes!</B>")
return
var/mob/living/simple_mob/slime/xenobio/S = M
user.show_message("Slime scan results:<br>[S.slime_color] [S.is_adult ? "adult" : "baby"] slime<br>Health: [S.health]<br>Mutation Probability: [S.mutation_chance]")
var/list/mutations = list()
for(var/potential_color in S.slime_mutation)
var/mob/living/simple_mob/slime/xenobio/slime = potential_color
mutations.Add(initial(slime.slime_color))
user.show_message("Potental to mutate into [english_list(mutations)] colors.<br>Extract potential: [S.cores]<br>Nutrition: [S.nutrition]/[S.max_nutrition]")
if (S.nutrition < S.get_starve_nutrition())
user.show_message("<span class='alert'>Warning: Subject is starving!</span>")
else if (S.nutrition < S.get_hunger_nutrition())
user.show_message("<span class='warning'>Warning: Subject is hungry.</span>")
user.show_message("Electric change strength: [S.power_charge]")
if(S.has_AI())
var/datum/ai_holder/simple_mob/xenobio_slime/AI = S.ai_holder
if(AI.resentment)
user.show_message("<span class='warning'>Warning: Subject is harboring resentment.</span>")
if(AI.rabid)
user.show_message("<span class='danger'>Subject is enraged and extremely dangerous!</span>")
if(S.harmless)
user.show_message("Subject has been pacified.")
if(S.unity)
user.show_message("Subject is friendly to other slime colors.")
user.show_message("Growth progress: [S.amount_grown]/10")
@@ -417,7 +417,7 @@
return
else if(istype(I, /obj/item/weapon/pen))
if(loc == user && !user.incapacitated())
var/new_name = input(user, "What would you like to label the tape?", "Tape labeling") as null|text
var/new_name = tgui_input_text(user, "What would you like to label the tape?", "Tape labeling")
if(isnull(new_name)) return
new_name = sanitizeSafe(new_name)
if(new_name)
@@ -22,9 +22,9 @@
named = 1
*/
var/message = sanitize(input(user,"Choose a message to relay to those around you.") as text|null)
var/message = sanitize(tgui_input_text(user,"Choose a message to relay to those around you."))
if(message)
audible_message("[bicon(src)] \The [src.name] states, \"[message]\"", runemessage = "synthesized speech")
audible_message("\icon[src][bicon(src)] \The [src.name] states, \"[message]\"", runemessage = "synthesized speech")
if(ismob(loc))
loc.audible_message("", runemessage = "\[TTS Voice\] [message]")
@@ -135,7 +135,7 @@ This device records all warnings given and teleport events for admin review in c
to_chat(user, "<span class='warning'>The translocator can't support any more beacons!</span>")
return
var/new_name = html_encode(input(user,"New beacon's name (2-20 char):","[src]") as text|null)
var/new_name = html_encode(tgui_input_text(user,"New beacon's name (2-20 char):","[src]",null,20))
if(!check_menu(user))
return
+77 -4
View File
@@ -45,7 +45,7 @@
add_fingerprint(user)
user.set_machine(src)
show_ui(user)
/obj/item/device/tvcamera/proc/show_ui(mob/user)
var/dat = list()
dat += "Channel name is: <a href='?src=\ref[src];channel=1'>[channel ? channel : "unidentified broadcast"]</a><br>"
@@ -62,7 +62,7 @@
if(..())
return 1
if(href_list["channel"])
var/nc = input(usr, "Channel name", "Select new channel name", channel) as text|null
var/nc = tgui_input_text(usr, "Channel name", "Select new channel name", channel)
if(nc)
channel = nc
camera.c_tag = channel
@@ -90,7 +90,7 @@
/obj/item/device/tvcamera/proc/show_tvs(atom/thing)
if(showing)
hide_tvs(showing)
showing = weakref(thing)
showing_name = "[thing]"
for(var/obj/machinery/computer/security/telescreen/entertainment/ES as anything in GLOB.entertainment_screens)
@@ -123,7 +123,7 @@
/obj/item/device/tvcamera/process()
if(!showing)
return PROCESS_KILL
var/atom/A = showing.resolve()
if(!A || QDELETED(A))
show_tvs(loc)
@@ -145,3 +145,76 @@
H.update_inv_l_hand()
H.update_inv_belt()
//Assembly by roboticist
/obj/item/robot_parts/head/attackby(var/obj/item/device/assembly/S, mob/user as mob)
if(!istype(S, /obj/item/device/assembly/infra))
..()
return
var/obj/item/weapon/TVAssembly/A = new(user)
qdel(S)
user.put_in_hands(A)
to_chat(user, "<span class='notice'>You add the infrared sensor to the robot head.</span>")
user.drop_from_inventory(src)
qdel(src)
/obj/item/weapon/TVAssembly
name = "\improper TV Camera Assembly"
desc = "A robotic head with an infrared sensor inside."
icon = 'icons/obj/robot_parts.dmi'
icon_state = "head"
item_state = "head"
var/buildstep = 0
w_class = ITEMSIZE_LARGE
/obj/item/weapon/TVAssembly/attackby(W, mob/user)
switch(buildstep)
if(0)
if(istype(W, /obj/item/robot_parts/robot_component/camera))
var/obj/item/robot_parts/robot_component/camera/CA = W
to_chat(user, "<span class='notice'>You add the camera module to [src]</span>")
user.drop_item()
qdel(CA)
desc = "This TV camera assembly has a camera module."
buildstep++
if(1)
if(istype(W, /obj/item/device/taperecorder))
var/obj/item/device/taperecorder/T = W
user.drop_item()
qdel(T)
buildstep++
to_chat(user, "<span class='notice'>You add the tape recorder to [src]</span>")
if(2)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(!C.use(3))
to_chat(user, "<span class='notice'>You need six cable coils to wire the devices.</span>")
..()
return
C.use(3)
buildstep++
to_chat(user, "<span class='notice'>You wire the assembly</span>")
desc = "This TV camera assembly has wires sticking out"
return
if(3)
if(istype(W, /obj/item/weapon/tool/wirecutters))
to_chat(user, "<span class='notice'> You trim the wires.</span>")
buildstep++
desc = "This TV camera assembly needs casing."
return
if(4)
if(istype(W, /obj/item/stack/material/steel))
var/obj/item/stack/material/steel/S = W
buildstep++
S.use(1)
to_chat(user, "<span class='notice'>You encase the assembly in a Ward-Takeshi casing.</span>")
var/turf/T = get_turf(src)
new /obj/item/device/tvcamera(T)
user.drop_from_inventory(src)
qdel(src)
return
..()
+1 -1
View File
@@ -19,7 +19,7 @@
to_chat(usr, "The hailer is fried. The tiny input screen just shows a waving ASCII penis.")
return
var/new_message = input(usr, "Please enter new message (leave blank to reset).") as text
var/new_message = tgui_input_text(usr, "Please enter new message (leave blank to reset).")
if(!new_message || new_message == "")
use_message = "Halt! Security!"
else
+23
View File
@@ -19,3 +19,26 @@
if(istype(AM, /obj/item/weapon/gun))
to_chat(user, "You have chosen \the [AM]. Say hello to your new best friend.")
qdel(src)
/*
* Site Manager's Box
*/
/obj/item/gunbox/captain
name = "Captain's sidearm box"
desc = "A secure box containing a sidearm befitting of the site manager. Includes both lethal and non-lethal munitions, beware what's loaded!"
icon = 'icons/obj/storage.dmi'
icon_state = "gunbox"
/obj/item/gunbox/captain/attack_self(mob/living/user)
var/list/options = list()
options["M1911 (.45)"] = list(/obj/item/weapon/gun/projectile/colt/detective, /obj/item/ammo_magazine/m45/rubber, /obj/item/ammo_magazine/m45)
options["MT Mk58 (.45)"] = list(/obj/item/weapon/gun/projectile/sec, /obj/item/ammo_magazine/m45/rubber, /obj/item/ammo_magazine/m45)
options["LAEP80 \"Thor\" (Stun/Laser)"] = list(/obj/item/weapon/gun/energy/gun, /obj/item/weapon/cell/device/weapon, /obj/item/weapon/cell/device/weapon)
options["MarsTech P92X (9mm)"] = list(/obj/item/weapon/gun/projectile/p92x/rubber, /obj/item/ammo_magazine/m9mm/rubber, /obj/item/ammo_magazine/m9mm)
var/choice = tgui_input_list(user,"Would you prefer a ballistic pistol or an energy gun?", "Gun!", options)
if(src && choice)
var/list/things_to_spawn = options[choice]
for(var/new_type in things_to_spawn) // Spawn all the things, the gun and the ammo.
var/atom/movable/AM = new new_type(get_turf(src))
if(istype(AM, /obj/item/weapon/gun))
to_chat(user, "You have chosen \the [AM]. Say hello to your new friend.")
qdel(src)
+1 -1
View File
@@ -226,7 +226,7 @@
to_chat(user, "<span class='warning'>The MMI must go in after everything else!</span>")
if (istype(W, /obj/item/weapon/pen))
var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN)
var/t = sanitizeSafe(tgui_input_text(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN)
if (!t)
return
if (!in_range(src, usr) && src.loc != usr)
@@ -40,7 +40,7 @@
var/heldname = "default name"
/obj/item/borg/upgrade/rename/attack_self(mob/user as mob)
heldname = sanitizeSafe(input(user, "Enter new robot name", "Robot Reclassification", heldname), MAX_NAME_LEN)
heldname = sanitizeSafe(tgui_input_text(user, "Enter new robot name", "Robot Reclassification", heldname, MAX_NAME_LEN), MAX_NAME_LEN)
/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R)
if(..()) return 0
@@ -69,6 +69,7 @@
R.key = ghost.key
R.set_stat(CONSCIOUS)
R.add_robot_verbs()
dead_mob_list -= R
living_mob_list |= R
R.notify_ai(ROBOT_NOTIFICATION_NEW_UNIT)
@@ -207,7 +208,6 @@
R.add_language(LANGUAGE_SIIK, 1)
R.add_language(LANGUAGE_AKHANI, 1)
R.add_language(LANGUAGE_SKRELLIAN, 1)
R.add_language(LANGUAGE_SKRELLIANFAR, 0)
R.add_language(LANGUAGE_GUTTER, 1)
R.add_language(LANGUAGE_SCHECHI, 1)
R.add_language(LANGUAGE_ROOTLOCAL, 1)
@@ -6,7 +6,6 @@
R.add_language(LANGUAGE_ECUREUILIAN, 1)
R.add_language(LANGUAGE_DAEMON, 1)
R.add_language(LANGUAGE_ENOCHIAN, 1)
R.add_language(LANGUAGE_SLAVIC, 1)
R.add_language(LANGUAGE_DRUDAKAR, 1)
R.add_language(LANGUAGE_TAVAN, 1)
return 1
@@ -31,6 +30,30 @@
R.verbs += /mob/living/proc/set_size
return 1
//Robot size gun
/obj/item/borg/upgrade/sizegun
name = "robot mounted size gun"
desc = "A size gun adapted for installation in cyborgs, allows them to turn people pocket-sized among other uses. What could go wrong?"
icon_state = "cyborg_upgrade2"
item_state = "cyborg_upgrade"
require_module = 1
/obj/item/borg/upgrade/sizegun/action(var/mob/living/silicon/robot/R)
if(..()) return 0
var/obj/item/weapon/gun/energy/sizegun/mounted/T = locate() in R.module
if(!T)
T = locate() in R.module.contents
if(!T)
T = locate() in R.module.modules
if(!T)
R.module.modules += new/obj/item/weapon/gun/energy/sizegun/mounted(R.module)
return 1
if(T)
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
return 0
/obj/item/borg/upgrade/bellysizeupgrade
name = "robohound capacity expansion module"
desc = "Used to double a robohound's belly capacity. This only affects total volume, and won't allow support of more than one patient in case of sleeper bellies. Can only be applied once."
@@ -152,6 +175,30 @@
if(!T)
R.module.modules += new/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg(R.module)
return 1
if(T)
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
return 0
//cyborg foam dart gun
/obj/item/borg/upgrade/toygun
name = "Donk-Soft Cyborg Blaster module" //Cyborg Blaster is capitalized because it's the brand name
desc = "A foam dart gun designed for mounting into cyborgs. It's Donk or Don't! DISCLAIMER: Donk-Soft bears no responsibility for incidents relating to cyborgs becoming too accustomed to shooting at crew. Installation of the Donk-Soft Cyborg Blaster must be performed only by a licensed roboticist."
icon_state = "cyborg_upgrade5"
item_state = "cyborg_upgrade"
require_module = 1
/obj/item/borg/upgrade/toygun/action(var/mob/living/silicon/robot/R)
if(..()) return 0
var/obj/item/weapon/gun/projectile/cyborgtoy/T = locate() in R.module
if(!T)
T = locate() in R.module.contents
if(!T)
T = locate() in R.module.modules
if(!T)
R.module.modules += new/obj/item/weapon/gun/projectile/cyborgtoy(R.module)
return 1
if(T)
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
@@ -0,0 +1,48 @@
/obj/item/selectable_item
name = "selectable item"
desc = "If you find this, you should definitely report this..."
icon = 'icons/obj/items.dmi'
icon_state = "gift1"
var/preface_string = "You are about to select an item. Are you sure you want to use it and select one?"
var/preface_title = "selectable item"
var/selection_string = "Select an item:"
var/selection_title = "Item Selection"
var/list/item_options = list("Gift" = /obj/item/weapon/a_gift,
"Health Analyzer" = /obj/item/device/healthanalyzer)
/obj/item/selectable_item/attack_self(mob/user as mob)
tgui_alert(user, {"[preface_string]"}, preface_title)
var/chosen_item = tgui_input_list(usr, selection_string, selection_title, item_options)
chosen_item = item_options[chosen_item]
if(!QDELETED(src) && chosen_item)
user.drop_item()
var/obj/item/result = new chosen_item(get_turf(user))
user.put_in_active_hand(result)
result.add_fingerprint(user)
qdel(src)
return
/obj/item/selectable_item/chemistrykit
icon = 'icons/obj/chemical_vr.dmi'
icon_state = "chemkit"
selection_string = "Select a chemical:"
selection_title = "Chemical Selection"
/obj/item/selectable_item/chemistrykit/size
name = "size chemistry kit"
desc = "A pre-arranged home chemistry kit. This one is for rather specific set of size-altering chemicals."
preface_string = "This kit can be used to create a vial of a size-altering chemical, but there's only enough material for one."
preface_title = "Size Chemistry Kit"
item_options = list("Macrocillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/macrocillin,
"Microcillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/microcillin,
"Normalcillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/normalcillin)
/obj/item/selectable_item/chemistrykit/gender
name = "gender chemistry kit"
desc = "A pre-arranged home chemistry kit. This one is for rather specific set of gender-altering chemicals."
preface_string = "This kit can be used to create a vial of a gender-altering chemical, but there's only enough material for one."
preface_title = "Gender Chemistry Kit"
item_options = list("Androrovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/androrovir,
"Gynorovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/gynorovir,
"Androgynorovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/androgynorovir)
+2 -3
View File
@@ -20,8 +20,7 @@
to_chat(user, "<span class='warning'>\The [src] cannot be applied to [M]!</span>")
return 1
if ( ! (istype(user, /mob/living/carbon/human) || \
istype(user, /mob/living/silicon)) )
if (!M.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
@@ -129,7 +128,7 @@
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> bandages \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You bandage \a [W.desc] on [M]'s [affecting.name].</span>" )
+1 -1
View File
@@ -399,7 +399,7 @@
/obj/item/stack/attack_hand(mob/user as mob)
if (user.get_inactive_hand() == src)
var/N = input(usr, "How many stacks of [src] would you like to split off? There are currently [amount].", "Split stacks", 1) as num|null
var/N = tgui_input_number(usr, "How many stacks of [src] would you like to split off? There are currently [amount].", "Split stacks", 1, amount, 1)
if(N)
var/obj/item/stack/F = src.split(N)
if (F)
@@ -4,14 +4,6 @@
name = "stack of grass"
type_to_spawn = /obj/item/stack/tile/grass
/obj/fiftyspawner/grass/sif
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif
/obj/fiftyspawner/grass/sif/forest
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif/forest
/obj/fiftyspawner/wood
name = "stack of wood"
type_to_spawn = /obj/item/stack/tile/wood
@@ -28,14 +20,38 @@
name = "stack of teal carpet"
type_to_spawn = /obj/item/stack/tile/carpet/teal
/obj/fiftyspawner/decocarpet
name = "stack of deco carpet"
type_to_spawn = /obj/item/stack/tile/carpet/deco
/obj/fiftyspawner/geocarpet
name = "stack of geometric carpet"
type_to_spawn = /obj/item/stack/tile/carpet/geo
/obj/fiftyspawner/retrocarpet
name = "stack of retro carpet"
name = "stack of blue retro carpet"
type_to_spawn = /obj/item/stack/tile/carpet/retro
/obj/fiftyspawner/retrocarpet_red
name = "stack of red retro carpet"
type_to_spawn = /obj/item/stack/tile/carpet/retro_red
/obj/fiftyspawner/happycarpet
name = "stack of happy carpet"
type_to_spawn = /obj/item/stack/tile/carpet/happy
/obj/fiftyspawner/brncarpet
name = "stack of brown carpet"
type_to_spawn = /obj/item/stack/tile/carpet/brncarpet
/obj/fiftyspawner/blucarpet2
name = "stack of blue carpet"
type_to_spawn = /obj/item/stack/tile/carpet/blucarpet2
/obj/fiftyspawner/greencarpet
name = "stack of green carpet"
type_to_spawn = /obj/item/stack/tile/carpet/greencarpet
/obj/fiftyspawner/purplecarpet
name = "stack of purple carpet"
type_to_spawn = /obj/item/stack/tile/carpet/purplecarpet
/obj/fiftyspawner/floor
name = "stack of floor tiles"
type_to_spawn = /obj/item/stack/tile/floor
@@ -42,16 +42,6 @@
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
/obj/item/stack/tile/grass/sif
name = "sivian grass tile"
singular_name = "sivian grass floor tile"
desc = "A patch of grass like those that decorate the plains of Sif."
/obj/item/stack/tile/grass/sif/forest
name = "sivian overgrowth tile"
singular_name = "sivian overgrowth floor tile"
desc = "A patch of dark overgrowth like those that decorate the plains of Sif."
/*
* Wood
*/
@@ -75,6 +65,26 @@
desc = "An easy to fit wooden floor tile. It's blue!"
icon_state = "tile-sifwood"
/obj/item/stack/tile/wood/alt
name = "wood floor tile"
singular_name = "wood floor tile"
icon_state = "tile-wood_tile"
/obj/item/stack/tile/wood/parquet
name = "parquet wood floor tile"
singular_name = "parquet wood floor tile"
icon_state = "tile-wood_parquet"
/obj/item/stack/tile/wood/panel
name = "large wood floor tile"
singular_name = "large wood floor tile"
icon_state = "tile-wood_large"
/obj/item/stack/tile/wood/tile
name = "tiled wood floor tile"
singular_name = "tiled wood floor tile"
icon_state = "tile-wood_tile"
/obj/item/stack/tile/wood/cyborg
name = "wood floor tile synthesizer"
desc = "A device that makes wood floor tiles."
@@ -83,6 +93,8 @@
stacktype = /obj/item/stack/tile/wood
build_type = /obj/item/stack/tile/wood
/*
* Carpets
*/
@@ -107,6 +119,23 @@
icon_state = "tile-tealcarpet"
no_variants = FALSE
/obj/item/stack/tile/carpet/geo
icon_state = "tile-carpet-deco"
desc = "A piece of carpet with a gnarly geometric design. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/retro
icon_state = "tile-carpet-retro"
desc = "A piece of carpet with totally wicked blue space patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/retro_red
icon_state = "tile-carpet-retro-red"
desc = "A piece of carpet with red-ical space patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/happy
icon_state = "tile-carpet-happy"
desc = "A piece of carpet with happy patterns. It is the same size as a normal floor tile!"
// TODO - Add descriptions to these
/obj/item/stack/tile/carpet/bcarpet
icon_state = "tile-carpet"
/obj/item/stack/tile/carpet/blucarpet
@@ -121,10 +150,14 @@
icon_state = "tile-carpet"
/obj/item/stack/tile/carpet/oracarpet
icon_state = "tile-carpet"
/obj/item/stack/tile/carpet/deco
icon_state = "tile-carpet-deco"
/obj/item/stack/tile/carpet/retro
icon_state = "tile-carpet-retro"
/obj/item/stack/tile/carpet/brncarpet
icon_state = "tile-carpet"
/obj/item/stack/tile/carpet/blucarpet2
icon_state = "tile-carpet"
/obj/item/stack/tile/carpet/greencarpet
icon_state = "tile-carpet"
/obj/item/stack/tile/carpet/purplecarpet
icon_state = "tile-carpet"
/obj/item/stack/tile/floor
name = "floor tile"
+1 -1
View File
@@ -123,7 +123,7 @@
var/mob/M = usr
if(!M.mind) return 0
var/input = sanitizeSafe(input(usr, "What do you want to name the icon?", ,""), MAX_NAME_LEN)
var/input = sanitizeSafe(tgui_input_text(usr, "What do you want to name the icon?", ,"", null, MAX_NAME_LEN), MAX_NAME_LEN)
if(src && input && !M.stat && in_range(M,src))
name = "icon of " + input
+1 -1
View File
@@ -844,7 +844,7 @@
if(!M.mind)
return 0
var/input = sanitizeSafe(input(usr, "What do you want to name the plushie?", ,""), MAX_NAME_LEN)
var/input = sanitizeSafe(tgui_input_text(usr, "What do you want to name the plushie?", ,""), MAX_NAME_LEN)
if(src && input && !M.stat && in_range(M,src))
name = input
+5 -1
View File
@@ -87,16 +87,20 @@
attack_verb = list("beeped", "booped", "pinged")
/obj/item/toy/plushie/borgplushie/medihound
name = "medihound plushie"
icon_state = "medihound"
/obj/item/toy/plushie/borgplushie/scrubpuppy
name = "janihound plushie"
icon_state = "scrubpuppy"
/obj/item/toy/plushie/borgplushie/drakiesec
name = "security drake plushie"
icon = 'icons/obj/drakietoy_vr.dmi'
icon_state = "secdrake"
/obj/item/toy/plushie/borgplushie/drakiemed
name = "medical drake plushie"
icon = 'icons/obj/drakietoy_vr.dmi'
icon_state = "meddrake"
@@ -613,7 +617,7 @@
/obj/item/toy/minigibber/attackby(obj/O, mob/user, params)
if(istype(O,/obj/item/toy/figure) || istype(O,/obj/item/toy/character) && O.loc == user)
to_chat(user, "<span class='notice'>You start feeding \the [O] [bicon(O)] into \the [src]'s mini-input.</span>")
to_chat(user, "<span class='notice'>You start feeding \the [O] \icon[O][bicon(O)] into \the [src]'s mini-input.</span>")
if(do_after(user, 10, target = src))
if(O.loc != user)
to_chat(user, "<span class='alert'>\The [O] is too far away to feed into \the [src]!</span>")
+1 -1
View File
@@ -136,7 +136,7 @@
cell = I
else if(istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/device/flashlight/pen))
var/tmp_label = sanitizeSafe(input(user, "Enter a nickname for [src]", "Nickname", nickname), MAX_NAME_LEN)
var/tmp_label = sanitizeSafe(tgui_input_text(user, "Enter a nickname for [src]", "Nickname", nickname, MAX_NAME_LEN), MAX_NAME_LEN)
if(length(tmp_label) > 50 || length(tmp_label) < 3)
to_chat(user, "<span class='notice'>The nickname must be between 3 and 50 characters.</span>")
else
@@ -133,7 +133,7 @@ AI MODULES
/obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob)
..()
var/targName = sanitize(input(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name))
var/targName = sanitize(tgui_input_text(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name))
targetName = targName
desc = text("A 'safeguard' AI module: 'Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.'", targetName, targetName)
@@ -159,7 +159,7 @@ AI MODULES
/obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob)
..()
var/targName = sanitize(input(usr, "Please enter the name of the person who is the only crew member.", "Who?", user.real_name))
var/targName = sanitize(tgui_input_text(usr, "Please enter the name of the person who is the only crew member.", "Who?", user.real_name))
targetName = targName
desc = text("A 'one crew member' AI module: 'Only [] is a crew member.'", targetName)
@@ -240,11 +240,11 @@ AI MODULES
/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob)
..()
var/new_lawpos = input(usr, "Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos) as num
var/new_lawpos = tgui_input_number(usr, "Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos)
if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return
lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER)
var/newlaw = ""
var/targName = sanitize(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
var/targName = sanitize(tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'"
@@ -357,7 +357,7 @@ AI MODULES
/obj/item/weapon/aiModule/freeformcore/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = sanitize(input(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw))
var/targName = sanitize(tgui_input_text(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A 'freeform' Core AI module: '[newFreeFormLaw]'"
@@ -381,7 +381,7 @@ AI MODULES
/obj/item/weapon/aiModule/syndicate/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = sanitize(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
var/targName = sanitize(tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A hacked AI law module: '[newFreeFormLaw]'"
@@ -74,7 +74,7 @@
to_chat(user, "<span class='warning'>Circuit controls are locked.</span>")
return
var/existing_networks = jointext(network,",")
var/input = sanitize(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks))
var/input = sanitize(tgui_input_text(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks))
if(!input)
to_chat(usr, "No input found please hang up and try your call again.")
return
@@ -39,7 +39,7 @@
..()
/obj/item/weapon/plastique/attack_self(mob/user as mob)
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
var/newtime = tgui_input_number(usr, "Please set the timer.", "Timer", 10, 60000, 10)
if(user.get_active_hand() == src)
newtime = CLAMP(newtime, 10, 60000)
timer = newtime
@@ -8,7 +8,7 @@
target = src
var/turf/T = get_turf(target)
if(T.z in using_map.station_levels)
if((T.z in using_map.station_levels) || (T.z in using_map.admin_levels))
target.visible_message("<span class='danger'>\The [src] lets out a loud beep as safeties trigger, before imploding and falling apart.</span>")
target.cut_overlay(image_overlay, TRUE)
qdel(src)
@@ -90,8 +90,8 @@
return data
/obj/item/weapon/card/id/attack_self(mob/user as mob)
user.visible_message("\The [user] shows you: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\
"You flash your ID card: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]")
user.visible_message("\The [user] shows you: \icon[src][bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\
"You flash your ID card: \icon[src][bicon(src)] [src.name]. The assignment on the card: [src.assignment]")
src.add_fingerprint(user)
return
@@ -107,7 +107,7 @@
set category = "Object"
set src in usr
to_chat(usr, "[bicon(src)] [src.name]: The current assignment on the card is [src.assignment].")
to_chat(usr, "\icon[src][bicon(src)] [src.name]: The current assignment on the card is [src.assignment].")
to_chat(usr, "The blood type on the card is [blood_type].")
to_chat(usr, "The DNA hash on the card is [dna_hash].")
to_chat(usr, "The fingerprint hash on the card is [fingerprint_hash].")
@@ -167,7 +167,7 @@
assignment = "Synthetic"
access = list(
access_synth, access_mining, access_mining_station, access_mining_office, access_research,
access_xenoarch, access_xenobiology, access_external_airlocks, access_robotics, access_tox,
access_xenoarch, access_xenobiology, access_external_airlocks, access_robotics, access_tox,
access_tox_storage, access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot
)
@@ -288,7 +288,7 @@ Implant Specifics:<BR>"}
/obj/item/weapon/implant/explosive/post_implant(mob/source as mob)
elevel = tgui_alert(usr, "What sort of explosion would you prefer?", "Implant Intent", list("Localized Limb", "Destroy Body", "Full Explosion"))
phrase = input(usr, "Choose activation phrase:") as text
phrase = tgui_input_text(usr, "Choose activation phrase:")
var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
phrase = replace_characters(phrase, replacechars)
usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate.", 0, 0)
@@ -22,20 +22,16 @@
if (emote == "smile")
src.uses--
to_chat(source,"<span class='notice'>You suddenly feel as if you can understand other languages!</span>")
source.add_language(LANGUAGE_CHIMPANZEE)
source.add_language(LANGUAGE_NEAERA)
source.add_language(LANGUAGE_STOK)
source.add_language(LANGUAGE_FARWA)
source.add_language(LANGUAGE_UNATHI)
source.add_language(LANGUAGE_SIIK)
source.add_language(LANGUAGE_SKRELLIAN)
source.add_language(LANGUAGE_ANIMAL)
source.add_language(LANGUAGE_SCHECHI)
source.add_language(LANGUAGE_BIRDSONG)
source.add_language(LANGUAGE_SAGARU)
source.add_language(LANGUAGE_CANILUNZT)
source.add_language(LANGUAGE_SLAVIC)
source.add_language(LANGUAGE_SOL_COMMON) //In case they're giving a xenomorph an implant or something.
source.add_language(LANGUAGE_TAVAN)
source.add_language(LANGUAGE_TAVAN)
/obj/item/weapon/implant/vrlanguage/post_implant(mob/source)
source.mind.store_memory("A implant can be activated by using the smile emote, <B>say *smile</B> to attempt to activate.", 0, 0)
@@ -21,7 +21,7 @@
/obj/item/weapon/implantcase/attackby(obj/item/weapon/I as obj, mob/user as mob)
..()
if (istype(I, /obj/item/weapon/pen))
var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null)
if (user.get_active_hand() != I)
return
if((!in_range(src, usr) && src.loc != user))
@@ -15,18 +15,22 @@
to_chat(user, "<span class='notice'>You [active ? "" : "de"]activate \the [src].</span>")
update()
/obj/item/weapon/implanter/verb/remove_implant(var/mob/user)
/obj/item/weapon/implanter/verb/remove_implant()
set category = "Object"
set name = "Remove Implant"
set src in usr
if(!imp)
return
imp.loc = get_turf(src)
user.put_in_hands(imp)
to_chat(user, "<span class='notice'>You remove \the [imp] from \the [src].</span>")
name = "implanter"
imp = null
if(istype(usr, /mob))
var/mob/M = usr
imp.loc = get_turf(src)
if(M.get_active_hand() == null)
M.put_in_hands(imp)
to_chat(M, "<span class='notice'>You remove \the [imp] from \the [src].</span>")
name = "implanter"
imp = null
update()
/obj/item/weapon/implanter/proc/update()
@@ -627,6 +627,23 @@
</html>
"}
/obj/item/weapon/book/manual/robotics_manual
name = "Guide to Robotics"
icon_state ="evabook"
item_state = "book3"
author = "Simple Robotics" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
title = "Guide to Robotics"
/obj/item/weapon/book/manual/robotics_manual/New()
..()
dat = {"
<html><head>
</head>
<body>
<iframe width='100%' height='97%' src="[config.wikiurl]Guide_to_Robotics&printable=yes&remove_links=1" frameborder="0" id="main_frame"></iframe>
</body>
</html>
"}
/obj/item/weapon/book/manual/robotics_cyborgs
name = "Cyborgs for Dummies"
@@ -13,14 +13,14 @@
/obj/item/weapon/material/gravemarker/attackby(obj/item/weapon/W, mob/user as mob)
if(W.is_screwdriver())
var/carving_1 = sanitizeSafe(input(user, "Who is \the [src.name] for?", "Gravestone Naming", null) as text, MAX_NAME_LEN)
var/carving_1 = sanitizeSafe(tgui_input_text(user, "Who is \the [src.name] for?", "Gravestone Naming", null, MAX_NAME_LEN), MAX_NAME_LEN)
if(carving_1)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] carves something into \the [src.name].", "You carve your message into \the [src.name].")
grave_name += carving_1
update_icon()
var/carving_2 = sanitizeSafe(input(user, "What message should \the [src.name] have?", "Epitaph Carving", null) as text, MAX_NAME_LEN)
var/carving_2 = sanitizeSafe(tgui_input_text(user, "What message should \the [src.name] have?", "Epitaph Carving", null, MAX_NAME_LEN), MAX_NAME_LEN)
if(carving_2)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
@@ -57,7 +57,7 @@
// Randomizes color
/obj/item/weapon/melee/umbrella/random/Initialize()
color = "#"+get_random_colour()
color = get_random_colour()
. = ..()
/obj/item/weapon/melee/cursedblade
@@ -95,4 +95,4 @@
new_voice.name = "cursed sword" //Cursed swords shouldn't be known characters.
new_voice.real_name = "cursed sword"
voice_mobs.Add(new_voice)
listening_objects |= src
listening_objects |= src
@@ -383,7 +383,7 @@
max_storage_space = ITEMSIZE_COST_NORMAL * 25
max_w_class = ITEMSIZE_NORMAL
w_class = ITEMSIZE_SMALL
can_hold = list(/obj/item/weapon/coin,/obj/item/weapon/spacecash)
can_hold = list(/obj/item/weapon/coin,/obj/item/weapon/spacecash,/obj/item/weapon/spacecasinocash)
// -----------------------------
// Chemistry Bag
@@ -32,7 +32,10 @@
for(var/obj/item/i in contents)
var/i_state = i.item_state
if(!i_state) i_state = i.icon_state
standing.add_overlay(image(icon = INV_BELT_DEF_ICON, icon_state = i_state))
var/image/add_icon = image(icon = INV_BELT_DEF_ICON, icon_state = i_state)
if(istype(clip_mask)) //For taur bodies/tails clipping off parts of uniforms and suits.
standing.filters += filter(type = "alpha", icon = clip_mask)
standing.add_overlay(add_icon)
return standing
/obj/item/weapon/storage/update_icon()
@@ -49,7 +49,8 @@
/obj/item/device/cataloguer,
/obj/item/device/radio,
/obj/item/device/mapping_unit,
/obj/item/weapon/kinetic_crusher
/obj/item/weapon/kinetic_crusher,
/obj/item/device/analyzer
)
/obj/item/weapon/storage/belt/explorer/pathfinder
@@ -71,17 +72,34 @@
max_w_class = ITEMSIZE_LARGE
max_storage_space = ITEMSIZE_COST_NORMAL * 6
can_hold = list(
/obj/item/weapon/storage/box/samplebags,
/obj/item/fulton_core,
/obj/item/extraction_pack,
/obj/item/resonator,
/obj/item/stack/marker_beacon,
/obj/item/stack/flag,
/obj/item/modular_computer/tablet,
/obj/item/clothing/glasses,
/obj/item/clothing/shoes/bhop,
/obj/item/device/multitool,
/obj/item/device/core_sampler,
/obj/item/device/beacon_locator,
/obj/item/device/radio/beacon,
/obj/item/device/radio,
/obj/item/device/measuring_tape,
/obj/item/device/flashlight,
/obj/item/device/depth_scanner,
/obj/item/device/camera,
/obj/item/device/ano_scanner,
/obj/item/device/xenoarch_multi_tool,
/obj/item/device/geiger,
/obj/item/device/gps,
/obj/item/device/laser_pointer,
/obj/item/device/survivalcapsule,
/obj/item/device/perfect_tele/one_beacon,
/obj/item/device/binoculars,
/obj/item/weapon/storage/box/samplebags,
/obj/item/weapon/cell/device,
/obj/item/weapon/pickaxe,
/obj/item/weapon/shovel,
/obj/item/device/depth_scanner,
/obj/item/device/camera,
/obj/item/weapon/paper,
/obj/item/weapon/photo,
/obj/item/weapon/folder,
@@ -89,17 +107,48 @@
/obj/item/weapon/folder,
/obj/item/weapon/clipboard,
/obj/item/weapon/anodevice,
/obj/item/clothing/glasses,
/obj/item/weapon/tool/wrench,
/obj/item/weapon/tool/screwdriver,
/obj/item/weapon/storage/excavation,
/obj/item/weapon/anobattery,
/obj/item/device/ano_scanner,
/obj/item/weapon/pickaxe/hand,
/obj/item/device/xenoarch_multi_tool,
/obj/item/weapon/pickaxe/excavationdrill,
/obj/item/device/geiger,
/obj/item/device/gps,
/obj/item/weapon/reagent_containers/hypospray/autoinjector,
/obj/item/weapon/plastique/seismic/locked,
/obj/item/weapon/gun/magnetic/matfed/phoronbore,
/obj/item/weapon/storage/bag/sheetsnatcher,
/obj/item/weapon/melee,
/obj/item/weapon/kinetic_crusher,
/obj/item/weapon/mining_scanner
)
//Pretty much, if it's in the mining vendor, they should be able to put it on the belt.
/obj/item/weapon/storage/belt/archaeology
can_hold = list(
/obj/item/stack/marker_beacon,
/obj/item/stack/flag,
/obj/item/weapon/melee
/obj/item/clothing/glasses,
/obj/item/weapon/storage/box/samplebags,
/obj/item/device/xenoarch_multi_tool,
/obj/item/device/core_sampler,
/obj/item/device/beacon_locator,
/obj/item/device/radio/beacon,
/obj/item/device/gps,
/obj/item/device/measuring_tape,
/obj/item/device/flashlight,
/obj/item/device/depth_scanner,
/obj/item/device/camera,
/obj/item/device/ano_scanner,
/obj/item/device/geiger,
/obj/item/weapon/cell/device,
/obj/item/weapon/pickaxe,
/obj/item/weapon/paper,
/obj/item/weapon/photo,
/obj/item/weapon/folder,
/obj/item/weapon/pen,
/obj/item/weapon/folder,
/obj/item/weapon/clipboard,
/obj/item/weapon/anodevice,
/obj/item/weapon/tool/wrench,
/obj/item/device/multitool,
/obj/item/weapon/storage/excavation,
/obj/item/weapon/anobattery,
/obj/item/weapon/pickaxe
)
@@ -37,30 +37,35 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
drop_sound = 'sound/bureaucracy/bookclose.ogg'
/obj/item/weapon/storage/bible/attack_self(mob/living/carbon/human/user)
if(GLOB.bible_icon_state)
icon_state = GLOB.bible_icon_state
item_state = GLOB.bible_item_state
return FALSE
if(user?.mind?.assigned_role != "Chaplain")
return FALSE
var/list/skins = list()
for(var/i in 1 to GLOB.biblestates.len)
var/image/bible_image = image(icon = 'icons/obj/storage.dmi', icon_state = GLOB.biblestates[i])
skins += list("[GLOB.biblenames[i]]" = bible_image)
var/choice = show_radial_menu(user, src, skins, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 40, require_near = TRUE)
if(!choice)
if (!user.mind.my_religion)
return FALSE
var/bible_index = GLOB.biblenames.Find(choice)
if(!bible_index)
return FALSE
icon_state = GLOB.biblestates[bible_index]
item_state = GLOB.bibleitemstates[bible_index]
GLOB.bible_icon_state = icon_state
GLOB.bible_item_state = item_state
feedback_set_details("religion_book", "[choice]")
if (!user.mind.my_religion.configured)
var/list/skins = list()
for(var/i in 1 to GLOB.biblestates.len)
var/image/bible_image = image(icon = 'icons/obj/storage.dmi', icon_state = GLOB.biblestates[i])
skins += list("[GLOB.biblenames[i]]" = bible_image)
var/choice = show_radial_menu(user, src, skins, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 40, require_near = TRUE)
if(!choice)
return FALSE
var/bible_index = GLOB.biblenames.Find(choice)
if(!bible_index)
return FALSE
user.mind.my_religion.bible_icon_state = GLOB.biblestates[bible_index]
user.mind.my_religion.bible_item_state = GLOB.bibleitemstates[bible_index]
user.mind.my_religion.configured = TRUE
deity_name = user.mind.my_religion.deity
name = user.mind.my_religion.bible_name
icon_state = user.mind.my_religion.bible_icon_state
item_state = user.mind.my_religion.bible_item_state
to_chat(user, "<span class='notice'>You invoke [user.mind.my_religion.deity] and prepare a copy of [src].</span>")
/**
* Checks if we are allowed to interact with a radial menu
@@ -69,7 +74,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
* * user The mob interacting with the menu
*/
/obj/item/weapon/storage/bible/proc/check_menu(mob/living/carbon/human/user)
if(GLOB.bible_icon_state)
if(user.mind.my_religion.configured)
return FALSE
if(!istype(user))
return FALSE
@@ -105,4 +110,4 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
/obj/item/weapon/storage/bible/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (src.use_sound)
playsound(src, src.use_sound, 50, 1, -5)
..()
..()
@@ -35,4 +35,7 @@
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/canned/brainzsnax = 6)
/obj/item/weapon/storage/box/brainzsnax/red
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/canned/brainzsnax/red = 6)
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/canned/brainzsnax/red = 6)
/obj/item/weapon/storage/box/freezer
can_hold = list(/obj/item/organ, /obj/item/weapon/reagent_containers/blood, /obj/item/weapon/reagent_containers/glass, /obj/item/weapon/reagent_containers/food)
@@ -35,6 +35,8 @@
animate_shake()
drop_contents()
icon = open_egg_icon
if(user.transforming)
user.transforming = FALSE
/obj/item/weapon/storage/vore_egg/proc/animate_shake()
var/init_px = pixel_x
@@ -208,7 +208,7 @@
/obj/item/weapon/storage/pill_bottle/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen))
var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN)
var/tmp_label = sanitizeSafe(tgui_input_text(user, "Enter a label for [name]", "Label", label_text, MAX_NAME_LEN), MAX_NAME_LEN)
if(length(tmp_label) > 50)
to_chat(user, "<span class='notice'>The label can be at most 50 characters long.</span>")
else if(length(tmp_label) > 10)
@@ -14,7 +14,7 @@
max_storage_space = INVENTORY_POUCH_SPACE
can_hold = null
pocketable = TRUE
var/insert_delay = 0 SECONDS
var/remove_delay = 2 SECONDS
@@ -32,7 +32,7 @@
// No delay if you have the pouch in your hands
if(user.get_active_hand() == src || user.get_inactive_hand() == src)
return TRUE // Skip delay
if(remove_delay && !do_after(user, remove_delay, src, needhand = TRUE, exclusive = TASK_USER_EXCLUSIVE))
return FALSE // Moved while there is a delay
@@ -58,10 +58,10 @@
/obj/item/weapon/storage/pouch/ammo
name = "storage pouch (ammo)"
desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold ammunition and cells."
desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold ammunition, cells, explosives, and grenades."
icon_state = "ammo"
max_storage_space = INVENTORY_POUCH_SPACE
can_hold = list(/obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/cell/device/weapon)
can_hold = list(/obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/cell/device/weapon, /obj/item/weapon/grenade, /obj/item/weapon/plastique) //Vorestation Add - make it more useful for non-sec/explo
/obj/item/weapon/storage/pouch/eng_tool
name = "storage pouch (tools)"
@@ -69,15 +69,35 @@
icon_state = "engineering_tool"
max_storage_space = INVENTORY_POUCH_SPACE
can_hold = list(
/obj/item/weapon/tool,
/obj/item/weapon/tool/crowbar,
/obj/item/weapon/tool/screwdriver,
/obj/item/weapon/weldingtool,
/obj/item/weapon/tool/wirecutters,
/obj/item/weapon/tool/wrench,
/obj/item/device/multitool,
/obj/item/device/flashlight,
/obj/item/weapon/cell/device,
/obj/item/stack/cable_coil,
/obj/item/device/t_scanner,
/obj/item/device/analyzer,
/obj/item/clothing/glasses,
/obj/item/clothing/gloves,
)
/obj/item/device/pda,
/obj/item/device/megaphone,
/obj/item/taperoll,
/obj/item/device/radio/headset,
/obj/item/device/robotanalyzer,
/obj/item/weapon/material/minihoe,
/obj/item/weapon/material/knife/machete/hatchet,
/obj/item/device/analyzer/plant_analyzer,
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/tape_roll,
/obj/item/device/integrated_electronics/wirer,
/obj/item/device/integrated_electronics/debugger,
/obj/item/weapon/shovel/spade,
/obj/item/stack/nanopaste,
/obj/item/device/geiger
) //Vorestation Add - make it the same as the tool-belt why was it not like this to start with wtf
/obj/item/weapon/storage/pouch/eng_supply
name = "storage pouch (supplies)"
@@ -88,15 +108,19 @@
/obj/item/weapon/cell/device,
/obj/item/stack/cable_coil,
/obj/item/taperoll,
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/tape_roll
)
/obj/item/weapon/extinguisher,
/obj/item/weapon/tape_roll,
/obj/item/stack/material/steel,
/obj/item/stack/material/glass,
/obj/item/device/lightreplacer,
/obj/item/weapon/cell
) //Vorestation Add - makes it actually useful lmao, adds sheets and cells as well as light replacers and lets you take any extinguisher that fits
/obj/item/weapon/storage/pouch/eng_parts
name = "storage pouch (parts)"
desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold machinery components."
icon_state = "part_pouch"
max_storage_space = INVENTORY_POUCH_SPACE
max_storage_space = INVENTORY_POUCH_SPACE*2 //Vorestation Add - yeah lemme give up my pocket to hold FOUR CAPACITORS or have an inferior box... now you can hold eight in your pocket so its at least a box
can_hold = list(
/obj/item/weapon/stock_parts,
/obj/item/stack/cable_coil,
@@ -120,8 +144,20 @@
/obj/item/weapon/storage/pill_bottle,
/obj/item/stack/medical,
/obj/item/weapon/reagent_containers/hypospray,
/obj/item/weapon/storage/quickdraw/syringe_case
)
/obj/item/weapon/storage/quickdraw/syringe_case,
/obj/item/weapon/syringe_cartridge,
/obj/item/clothing/gloves/sterile,
/obj/item/device/sleevemate,
/obj/item/bodybag,
/obj/item/clothing/mask/surgical,
/obj/item/weapon/soap,
/obj/item/stack/nanopaste,
/obj/item/taperoll/medical,
/obj/item/weapon/storage/box/freezer,
/obj/item/clothing/mask/chewable/candy/lolli,
) //Vorestation add - added a bunch of misc medical stuff
max_storage_space = ITEMSIZE_COST_SMALL*3 //Vorestation Add - makes it slightly smaller since its a lot of stuff with pocket access
remove_delay = 5 //Vorestation Add - .5 second delay, get the medical things faster because there is no reason to use this otherwise. still gotta stop moving to take things out.
/obj/item/weapon/storage/pouch/flares
name = "storage pouch (flares)"
@@ -145,7 +181,7 @@
desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one normal sized weapon."
icon_state = "pistol_holster"
storage_slots = 1
can_hold = list(/obj/item/weapon/gun)
can_hold = list(/obj/item/weapon/gun) //this covers basically everything I think so its fine
remove_delay = 0
/obj/item/weapon/storage/pouch/holster/full_stunrevolver
starts_with = list(/obj/item/weapon/gun/energy/stunrevolver)
@@ -159,11 +195,11 @@
..()
/obj/item/weapon/storage/pouch/baton
name = "storage pouch (baton)"
desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one standard baton."
name = "storage pouch (melee)"
desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one normal size melee." //Vorestation add - make it a melee pouch literally why would you hold ONE BATON
icon_state = "baton_holster"
storage_slots = 1
can_hold = list(/obj/item/weapon/melee/baton)
can_hold = list(/obj/item/weapon/melee, /obj/item/weapon/material, /obj/item/weapon/tool/wrench) //should be like, every melee weapon I could think of that was normal size. Can make it more specific if needed. Also wrench because I thought it was funny.
remove_delay = 0
/obj/item/weapon/storage/pouch/baton/full
starts_with = list(/obj/item/weapon/melee/baton)
@@ -80,16 +80,27 @@
return
..()
/obj/item/weapon/storage/secure/AltClick(mob/user as mob)
if (isliving(user) && Adjacent(user) && (src.locked == 1))
to_chat(user, "<span class='warning'>[src] is locked and cannot be opened!</span>")
else if (isliving(user) && Adjacent(user) && (!src.locked))
src.open(usr)
else
for(var/mob/M in range(1))
if (M.s_active == src)
src.close(M)
src.add_fingerprint(user)
return
/obj/item/weapon/storage/secure/attack_self(mob/user as mob)
tgui_interact(user)
/obj/item/weapon/storage/secure/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SecureSafe", name)
ui.open()
/obj/item/weapon/storage/secure/tgui_data(mob/user)
var/list/data = list()
data["locked"] = locked
@@ -877,8 +877,8 @@
if(target != user) return // If the user didn't drag themselves, exit
if(user.incapacitated() || user.buckled) return // If user is incapacitated or buckled, exit
if(get_holder_of_type(src, /mob/living/carbon/human) == user) return // No jumping into your own equipment
if(ishuman(user) && user.get_effective_size() > 0.25) return // Only micro characters
if(ismouse(user) && user.get_effective_size() > 1) return // Only normal sized mice or less
if(ishuman(user) && user.get_effective_size(TRUE) > 0.25) return // Only micro characters
if(ismouse(user) && user.get_effective_size(TRUE) > 1) return // Only normal sized mice or less
// Create a dummy holder with user's size to test insertion
var/obj/item/weapon/holder/D = new/obj/item/weapon/holder
@@ -107,7 +107,7 @@
/obj/item/weapon/storage/wallet/poly/Initialize()
. = ..()
verbs |= /obj/item/weapon/storage/wallet/poly/proc/change_color
color = "#"+get_random_colour()
color = get_random_colour()
update_icon()
/obj/item/weapon/storage/wallet/poly/proc/change_color()
@@ -196,4 +196,4 @@
icon_state = "casinowallet_white"
return
else
icon_state = "casinowallet_black"
icon_state = "casinowallet_black"
@@ -244,6 +244,9 @@
/obj/item/weapon/surgical/bonesetter/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/bioregen/cyborg //VoreStation edit: let the borgs S U C C
toolspeed = 0.5
// Alien Tools
/obj/item/weapon/surgical/retractor/alien
+1 -1
View File
@@ -51,7 +51,7 @@
icon_state = "c-4[size]_1"
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1)
for(var/mob/O in hearers(src, null))
O.show_message("[bicon(src)] <span class = 'warning'> The [src.name] beeps! </span>")
O.show_message("\icon[src][bicon(src)] <span class = 'warning'> The [src.name] beeps! </span>")
sleep(50)
explosion(get_turf(src), devastate, heavy_impact, light_impact, flash_range)
for(var/dirn in cardinal) //This is to guarantee that C4 at least breaks down all immediately adjacent walls and doors.
@@ -455,7 +455,7 @@ var/list/global/tank_gauge_cache = list()
return
T.assume_air(air_contents)
playsound(src, 'sound/weapons/Gunshot_shotgun.ogg', 20, 1)
visible_message("[bicon(src)] <span class='danger'>\The [src] flies apart!</span>", "<span class='warning'>You hear a bang!</span>")
visible_message("\icon[src][bicon(src)] <span class='danger'>\The [src] flies apart!</span>", "<span class='warning'>You hear a bang!</span>")
T.hotspot_expose(air_contents.temperature, 70, 1)
@@ -500,7 +500,7 @@ var/list/global/tank_gauge_cache = list()
T.assume_air(leaked_gas)
if(!leaking)
visible_message("[bicon(src)] <span class='warning'>\The [src] relief valve flips open with a hiss!</span>", "You hear hissing.")
visible_message("\icon[src][bicon(src)] <span class='warning'>\The [src] relief valve flips open with a hiss!</span>", "You hear hissing.")
playsound(src, 'sound/effects/spray.ogg', 10, 1, -3)
leaking = 1
#ifdef FIREDBG
@@ -29,7 +29,7 @@
if(loc == user && tools.len)
. += "It has the following fittings:"
for(var/obj/item/tool in tools)
. += "[bicon(tool)] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
. += "\icon[tool][bicon(tool)] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
/obj/item/weapon/combitool/Initialize()
. = ..()
+1 -1
View File
@@ -31,4 +31,4 @@
/obj/item/weapon/towel/random/Initialize()
. = ..()
color = "#"+get_random_colour()
color = get_random_colour()
+1 -1
View File
@@ -19,7 +19,7 @@
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(M)
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='danger'>You don't have the dexterity to do this!</span>")
return