Some Silicon Code (#8394)

Tweaked a hell of a lot of silicon code to make synthetics better.

Synths with scrambled codes that prevent them from being on robotics computers will now appear on Merc camera networks.

Both variants of the engineering borg can now deploy the malf borging machine.

Medical borgs no longer get polyacid sprays, instead getting Wulumunusha CMO Hyposprays, which cause muteness.

You must now be on help intent to use items like crowbars and screwdrivers on borgs. Otherwise you hit them with it.
This commit is contained in:
Geeves
2020-03-13 13:29:35 +01:00
committed by GitHub
parent 5a8f0451a4
commit 1a7cc1a1c7
64 changed files with 1865 additions and 2028 deletions
@@ -707,7 +707,7 @@
R.security.comments += text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
if(istype(usr,/mob/living/silicon/robot))
var/mob/living/silicon/robot/U = usr
R.security.comments += text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
R.security.comments += text("Made by [U.name] ([U.mod_type] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
if (href_list["medical"])
if(hasHUD(usr,"medical"))
@@ -818,7 +818,7 @@
R.medical.comments += text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
if(isrobot(usr))
var/mob/living/silicon/robot/U = usr
R.medical.comments += text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
R.medical.comments += text("Made by [U.name] ([U.mod_type] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
if (href_list["lookitem"])
var/obj/item/I = locate(href_list["lookitem"])
+113 -114
View File
@@ -5,7 +5,6 @@ var/list/ai_list = list()
var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/ai_announcement,
/mob/living/silicon/ai/proc/ai_call_shuttle,
// /mob/living/silicon/ai/proc/ai_recall_shuttle,
/mob/living/silicon/ai/proc/ai_emergency_message,
/mob/living/silicon/ai/proc/ai_camera_track,
/mob/living/silicon/ai/proc/ai_camera_list,
@@ -40,62 +39,71 @@ var/list/ai_verbs_default = list(
subject.attack_ai(M)
return is_in_use
/mob/living/silicon/ai
// Look and feel
name = "AI"
icon = 'icons/mob/AI.dmi'//
icon = 'icons/mob/AI.dmi'
icon_state = "ai"
anchored = 1 // -- TLE
density = 1
status_flags = CANSTUN|CANPARALYSE|CANPUSH
// Interaction
anchored = TRUE // -- TLE
density = TRUE
status_flags = CANSTUN|CANPARALYSE|CANPUSH
var/carded
// Holopad and holograms
var/icon/holo_icon
var/hologram_follow = TRUE //This is used for the AI eye, to determine if a holopad's hologram should follow it or not
// Equipment
var/list/network = list("Station")
var/obj/machinery/camera/camera
var/list/cameraRecords = list() //For storing what is shown to the cameras
var/obj/item/device/pda/ai/ai_pda
var/obj/item/device/multitool/ai_multi
var/obj/item/device/radio/headset/heads/ai_integrated/ai_radio
var/datum/announcement/priority/announcement
var/obj/machinery/ai_powersupply/psupply
// Borgs
var/list/connected_robots = list()
// Damage variables
var/fireloss = 0
var/bruteloss = 0
var/oxyloss = 0
//shouldnt_see - set in New()
var/list/network = list("Station")
var/obj/machinery/camera/camera = null
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
var/viewalerts = 0
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/item/device/pda/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null
var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through.
var/datum/trackable/track = null
// Misc variables
var/last_announcement = ""
var/control_disabled = 0
var/datum/announcement/priority/announcement
var/obj/machinery/ai_powersupply/psupply = null // Backwards reference to AI's powersupply object.
var/hologram_follow = 1 //This is used for the AI eye, to determine if a holopad's hologram should follow it or not
var/ai_restore_power_routine = FALSE
var/view_alerts = FALSE
var/camera_light_on = FALSE //Defines if the AI toggled the light on the camera it's looking through.
var/datum/trackable/track
var/control_disabled = FALSE
var/multitool_mode = FALSE
//NEWMALF VARIABLES
var/malfunctioning = 0 // Master var that determines if AI is malfunctioning.
var/datum/malf_hardware/hardware = null // Installed piece of hardware.
var/datum/malf_research/research = null // Malfunction research datum.
var/obj/machinery/power/apc/hack = null // APC that is currently being hacked.
var/list/hacked_apcs = null // List of all hacked APCs
var/APU_power = 0 // If set to 1 AI runs on APU power
var/hacking = 0 // Set to 1 if AI is hacking APC, cyborg, other AI, or running system override.
var/system_override = 0 // Set to 1 if system override is initiated, 2 if succeeded.
var/synthetic_takeover = 0 // 1 is started, 2 is complete.
var/hack_can_fail = 1 // If 0, all abilities have zero chance of failing.
// Malf variables
var/malfunctioning = FALSE // Master var that determines if AI is malfunctioning.
var/datum/malf_hardware/hardware // Installed piece of hardware.
var/datum/malf_research/research // Malfunction research datum.
var/obj/machinery/power/apc/hack // APC that is currently being hacked.
var/list/hacked_apcs = list() // List of all hacked APCs
var/APU_power = FALSE // If set to 1 AI runs on APU power
var/hacking = FALSE // Set to 1 if AI is hacking APC, cyborg, other AI, or running system override.
var/system_override = FALSE // Set to 1 if system override is initiated, 2 if succeeded.
var/synthetic_takeover = FALSE // 1 is started, 2 is complete.
var/hack_can_fail = TRUE // If 0, all abilities have zero chance of failing.
var/hack_fails = 0 // This increments with each failed hack, and determines the warning message text.
var/errored = 0 // Set to 1 if runtime error occurs. Only way of this happening i can think of is admin fucking up with varedit.
var/bombing_core = 0 // Set to 1 if core auto-destruct is activated
var/bombing_station = 0 // Set to 1 if station nuke auto-destruct is activated
var/bombing_time = 1200 // How much time is remaining for the nuke
var/errored = FALSE // Set to 1 if runtime error occurs. Only way of this happening i can think of is admin fucking up with varedit.
var/bombing_core = FALSE // Set to 1 if core auto-destruct is activated
var/bombing_station = FALSE // Set to 1 if station nuke auto-destruct is activated
var/bombing_time = 1200 // How much time is remaining for the nuke
var/override_CPUStorage = 0 // Bonus/Penalty CPU Storage. For use by admins/testers.
var/override_CPURate = 0 // Bonus/Penalty CPU generation rate. For use by admins/testers.
var/list/cameraRecords = list() //For storing what is shown to the cameras
// Sprites
var/datum/ai_icon/selected_sprite // The selected icon set
var/custom_sprite = FALSE // Whether the selected icon is custom
var/carded
var/multitool_mode = 0
var/custom_sprite = FALSE // Whether the selected icon is custom
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
@@ -110,72 +118,68 @@ var/list/ai_verbs_default = list(
announcement = new()
announcement.title = "A.I. Announcement"
announcement.announcement_type = "A.I. Announcement"
announcement.newscast = 1
announcement.newscast = TRUE
var/list/possibleNames = ai_names
var/pickedName = null
var/pickedName
while(!pickedName)
pickedName = pick(ai_names)
for (var/mob/living/silicon/ai/A in mob_list)
if (A.real_name == pickedName && possibleNames.len > 1) //fixing the theoretically possible infinite loop
for(var/mob/living/silicon/ai/A in mob_list)
if(A.real_name == pickedName && length(possibleNames) > 1) //fixing the theoretically possible infinite loop
possibleNames -= pickedName
pickedName = null
aiPDA = new/obj/item/device/pda/ai(src)
ai_pda = new/obj/item/device/pda/ai(src)
SetName(pickedName)
anchored = 1
canmove = 0
density = 1
loc = loc
anchored = TRUE
canmove = FALSE
density = TRUE
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
//proc_holder_list = new() // This ain't even used, why are we initializing it?
if(L)
if (istype(L, /datum/ai_laws))
laws = L
if(L && istype(L, /datum/ai_laws))
laws = L
else
laws = new base_law_type
aiMulti = new(src)
aiRadio = new(src)
common_radio = aiRadio
aiRadio.myAi = src
ai_multi = new(src)
ai_radio = new(src)
common_radio = ai_radio
ai_radio.myAi = src
additional_law_channels["Holopad"] = ":h"
aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
ai_camera = new/obj/item/device/camera/siliconcam/ai_camera(src)
if (istype(loc, /turf))
if(istype(loc, /turf))
add_ai_verbs(src)
//Languages
add_language(LANGUAGE_ROBOT, 1)
add_language(LANGUAGE_TCB, 1)
add_language(LANGUAGE_SOL_COMMON, 0)
add_language(LANGUAGE_UNATHI, 0)
add_language(LANGUAGE_SIIK_MAAS, 0)
add_language(LANGUAGE_SKRELLIAN, 0)
add_language(LANGUAGE_TRADEBAND, 1)
add_language(LANGUAGE_GUTTER, 0)
add_language(LANGUAGE_VAURCA, 0)
add_language(LANGUAGE_ROOTSONG, 0)
add_language(LANGUAGE_EAL, 1)
add_language(LANGUAGE_YA_SSA, 0)
add_language(LANGUAGE_DELVAHII, 0)
add_language(LANGUAGE_ROBOT, TRUE)
add_language(LANGUAGE_TCB, TRUE)
add_language(LANGUAGE_SOL_COMMON, FALSE)
add_language(LANGUAGE_UNATHI, FALSE)
add_language(LANGUAGE_SIIK_MAAS, FALSE)
add_language(LANGUAGE_SKRELLIAN, FALSE)
add_language(LANGUAGE_TRADEBAND, TRUE)
add_language(LANGUAGE_GUTTER, FALSE)
add_language(LANGUAGE_VAURCA, FALSE)
add_language(LANGUAGE_ROOTSONG, FALSE)
add_language(LANGUAGE_EAL, TRUE)
add_language(LANGUAGE_YA_SSA, FALSE)
add_language(LANGUAGE_DELVAHII, FALSE)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
empty_playable_ai_cores += new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
qdel(src)//Delete AI.
if(!B)//If there is no player/brain inside.
empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(src))//New empty terminal.
qdel(src) //Delete AI.
return
else
if (B.brainmob.mind)
if(B.brainmob.mind)
B.brainmob.mind.transfer_to(src)
if(B.brainobj)
B.brainobj.lobotomized = 1
B.brainobj.lobotomized = TRUE
on_mob_init()
@@ -195,21 +199,15 @@ var/list/ai_verbs_default = list(
return ..()
/mob/living/silicon/ai/Destroy()
QDEL_NULL(aiPDA)
QDEL_NULL(aiMulti)
QDEL_NULL(aiRadio)
QDEL_NULL(ai_pda)
QDEL_NULL(ai_multi)
QDEL_NULL(ai_radio)
QDEL_NULL(psupply)
QDEL_NULL(ai_camera)
ai_list -= src
destroy_eyeobj()
QDEL_NULL(psupply)
QDEL_NULL(aiMulti)
QDEL_NULL(aiRadio)
QDEL_NULL(aiCamera)
return ..()
/mob/living/silicon/ai/proc/init_powersupply()
new /obj/machinery/ai_powersupply(src)
/mob/living/silicon/ai/proc/on_mob_init()
to_chat(src, "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>")
to_chat(src, "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>")
@@ -228,7 +226,7 @@ var/list/ai_verbs_default = list(
to_chat(src, radio_text)
if (malf && !(mind in malf.current_antagonists))
if(malf && !(mind in malf.current_antagonists))
show_laws()
to_chat(src, "<b>These laws may be changed by other players, or by you if you are malfunctioning.</b>")
@@ -293,7 +291,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/pointed(atom/A as mob|obj|turf in view())
set popup_menu = 0
set src = usr.contents
return 0
return FALSE
/mob/living/silicon/ai/SetName(pickedName as text)
..()
@@ -302,16 +300,16 @@ var/list/ai_verbs_default = list(
eyeobj.name = "[pickedName] (AI Eye)"
// Set ai pda name
if(aiPDA)
aiPDA.ownjob = "AI"
aiPDA.owner = pickedName
aiPDA.name = pickedName + " (" + aiPDA.ownjob + ")"
if(ai_pda)
ai_pda.ownjob = "AI"
ai_pda.owner = pickedName
ai_pda.name = pickedName + " (" + ai_pda.ownjob + ")"
//Set the ID Name
if(idcard)
idcard.registered_name = pickedName
idcard.assignment = "AI"
idcard.update_name()
if(id_card)
id_card.registered_name = pickedName
id_card.assignment = "AI"
id_card.update_name()
setup_icon() //this is because the ai custom name is related to the ai name, so, we just call the setup icon after someone named their ai
SSrecords.reset_manifest()
@@ -321,14 +319,14 @@ var/list/ai_verbs_default = list(
The alternative was to rewrite a bunch of AI code instead here we are.
*/
/obj/machinery/ai_powersupply
name="Power Supply"
active_power_usage=50000 // Station AIs use significant amounts of power. This, when combined with charged SMES should mean AI lasts for 1hr without external power.
name = "power supply"
active_power_usage = 50000 // Station AIs use significant amounts of power. This, when combined with charged SMES should mean AI lasts for 1hr without external power.
use_power = 2
power_channel = EQUIP
var/mob/living/silicon/ai/powered_ai = null
var/mob/living/silicon/ai/powered_ai
invisibility = 100
/obj/machinery/ai_powersupply/New(var/mob/living/silicon/ai/ai=null)
/obj/machinery/ai_powersupply/New(var/mob/living/silicon/ai/ai)
powered_ai = ai
powered_ai.psupply = src
forceMove(powered_ai.loc)
@@ -363,7 +361,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/pick_icon()
set category = "AI Commands"
set name = "Set AI Core Display"
if(stat || aiRestorePowerRoutine)
if(stat || ai_restore_power_routine)
return
if (!custom_sprite)
@@ -489,7 +487,7 @@ var/list/ai_verbs_default = list(
return
if (href_list["mach_close"])
if (href_list["mach_close"] == "aialerts")
viewalerts = 0
view_alerts = 0
var/t1 = text("window=[]", href_list["mach_close"])
unset_machine()
src << browse(null, t1)
@@ -763,8 +761,8 @@ var/list/ai_verbs_default = list(
return
to_chat(src, "Accessing Subspace Transceiver control...")
if (src.aiRadio)
src.aiRadio.interact(src)
if (src.ai_radio)
src.ai_radio.interact(src)
/mob/living/silicon/ai/proc/sensor_mode()
set name = "Set Sensor Augmentation"
@@ -785,14 +783,15 @@ var/list/ai_verbs_default = list(
if(feedback) to_chat(src, "<span class='warning'>You are dead!</span>")
return 1
if(aiRestorePowerRoutine)
if(feedback) to_chat(src, "<span class='warning'>You lack power!</span>")
if(ai_restore_power_routine)
if(feedback)
to_chat(src, "<span class='warning'>You lack power!</span>")
return 1
if((flags & AI_CHECK_WIRELESS) && src.control_disabled)
if(feedback) to_chat(src, "<span class='warning'>Wireless control is disabled!</span>")
return 1
if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi)
if((flags & AI_CHECK_RADIO) && src.ai_radio.disabledAi)
if(feedback) to_chat(src, "<span class='warning'>System Error - Transceiver Disabled!</span>")
return 1
return 0
@@ -820,7 +819,7 @@ var/list/ai_verbs_default = list(
if(stat == DEAD)
icon_state = selected_sprite.dead_icon
set_light(3, 1, selected_sprite.dead_light)
else if(aiRestorePowerRoutine)
else if(ai_restore_power_routine)
icon_state = selected_sprite.nopower_icon
set_light(1, 1, selected_sprite.nopower_light)
else
@@ -854,7 +853,7 @@ var/list/ai_verbs_default = list(
return cameraRecords.len
/mob/living/silicon/ai/proc/has_power()
return (aiRestorePowerRoutine == 0)
return (ai_restore_power_routine == 0)
#undef AI_CHECK_WIRELESS
#undef AI_CHECK_RADIO
@@ -17,7 +17,7 @@
msg += "It looks slightly charred.\n"
else
msg += "<B>Its casing is melted and heat-warped!</B>\n"
if (src.getOxyLoss() && (aiRestorePowerRoutine != 0 && !APU_power))
if (src.getOxyLoss() && (ai_restore_power_routine != 0 && !APU_power))
if (src.getOxyLoss() > 175)
msg += "<B>It seems to be running on backup power. Its display is blinking a \"BACKUP POWER CRITICAL\" warning.</B>\n"
else if(src.getOxyLoss() > 100)
+1 -1
View File
@@ -18,7 +18,7 @@
/mob/living/silicon/ai/add_ion_law(var/law)
..()
for(var/mob/living/silicon/robot/R in mob_list)
if(R.lawupdate && (R.connected_ai == src))
if(R.law_update && (R.connected_ai == src))
R.show_laws()
/mob/living/silicon/ai/proc/ai_checklaws()
+14 -14
View File
@@ -21,12 +21,12 @@
// Handle power damage (oxy)
if(aiRestorePowerRoutine != 0 && !APU_power)
if(ai_restore_power_routine != 0 && !APU_power)
// Lose power
adjustOxyLoss(1)
else
// Gain Power
aiRestorePowerRoutine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
ai_restore_power_routine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
adjustOxyLoss(-1)
handle_stunned() // Handle EMP-stun
@@ -39,20 +39,20 @@
stop_apu(1)
if (!is_blinded())
if (aiRestorePowerRoutine==2)
if (ai_restore_power_routine==2)
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
ai_restore_power_routine = 0
src.blind.invisibility = 101
updateicon()
return
else if (aiRestorePowerRoutine==3)
else if (ai_restore_power_routine==3)
to_chat(src, "Alert cancelled. Power has been restored.")
aiRestorePowerRoutine = 0
ai_restore_power_routine = 0
src.blind.invisibility = 101
updateicon()
return
else if (APU_power)
aiRestorePowerRoutine = 0
ai_restore_power_routine = 0
src.blind.invisibility = 101
updateicon()
return
@@ -60,8 +60,8 @@
var/area/current_area = get_area(src)
if (lacks_power())
if (aiRestorePowerRoutine==0)
aiRestorePowerRoutine = 1
if (ai_restore_power_routine==0)
ai_restore_power_routine = 1
//Now to tell the AI why they're blind and dying slowly.
to_chat(src, "You've lost power!")
@@ -72,7 +72,7 @@
if (current_area.power_equip)
if (!istype(T, /turf/space))
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
ai_restore_power_routine = 0
src.blind.invisibility = 101
return
to_chat(src, "Fault confirmed: missing external power. Shutting down main control system to save power.")
@@ -81,7 +81,7 @@
sleep(50)
if (istype(T, /turf/space))
to_chat(src, "Unable to verify! No power connection detected!")
aiRestorePowerRoutine = 2
ai_restore_power_routine = 2
return
to_chat(src, "Connection verified. Searching for APC in power network.")
sleep(50)
@@ -97,12 +97,12 @@
switch(PRP)
if (1) to_chat(src, "Unable to locate APC!")
else to_chat(src, "Lost connection with the APC!")
src:aiRestorePowerRoutine = 2
src:ai_restore_power_routine = 2
return
if (current_area.power_equip)
if (!istype(T, /turf/space))
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
ai_restore_power_routine = 0
src.blind.invisibility = 101 //This, too, is a fix to issue 603
return
switch(PRP)
@@ -117,7 +117,7 @@
theAPC.operating = 1
theAPC.equipment = 3
theAPC.update()
aiRestorePowerRoutine = 3
ai_restore_power_routine = 3
to_chat(src, "Here are your current laws:")
show_laws()
updateicon()
+1 -1
View File
@@ -50,7 +50,7 @@
errored = 0
return
recalc_cpu()
if(APU_power || aiRestorePowerRoutine != 0)
if(APU_power || ai_restore_power_routine != 0)
research.process(1)
else
research.process(0)
@@ -1,20 +1,6 @@
/mob/living/silicon
var/register_alarms = 1
var/datum/nano_module/alarm_monitor/all/alarm_monitor
var/datum/nano_module/law_manager/law_manager
var/datum/nano_module/rcon/rcon
var/obj/item/modular_computer/silicon/computer
/mob/living/silicon/ai
var/datum/nano_module/computer_ntnetmonitor/ntnet_monitor
/mob/living/silicon
var/list/silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_law_manager,
/mob/living/silicon/proc/computer_interact
)
/mob/living/silicon/ai
silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
@@ -27,13 +13,6 @@
register_alarms = 0
silicon_subsystems = list(/mob/living/silicon/proc/subsystem_law_manager)
/mob/living/silicon/Destroy()
QDEL_NULL(alarm_monitor)
QDEL_NULL(law_manager)
QDEL_NULL(computer)
return ..()
/mob/living/silicon/ai/Destroy()
QDEL_NULL(ntnet_monitor)
+15 -18
View File
@@ -1,9 +1,7 @@
/mob/living/silicon
var/datum/ai_laws/laws = null
var/list/additional_law_channels = list("State" = "")
#define DEFAULT_LAW_CHANNEL "Main Frequency"
/mob/living/silicon/proc/laws_sanity_check()
if (!src.laws)
if(!src.laws)
laws = new base_law_type
/mob/living/silicon/proc/has_zeroth_law()
@@ -17,7 +15,7 @@
/mob/living/silicon/robot/set_zeroth_law(var/law, var/law_borg)
..()
if(tracking_entities)
to_chat(src, "<span class='warning'>Internal camera is currently being accessed.</span>")
to_chat(src, SPAN_WARNING("Internal camera is currently being accessed."))
/mob/living/silicon/proc/add_ion_law(var/law)
laws_sanity_check()
@@ -59,20 +57,20 @@
/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws)
var/prefix = ""
if(MAIN_CHANNEL == lawchannel)
if(law_channel == DEFAULT_LAW_CHANNEL)
prefix = ";"
else if(lawchannel == "Binary")
else if(law_channel == "Binary")
prefix = "[get_language_prefix()]b"
else if((lawchannel in additional_law_channels))
prefix = additional_law_channels[lawchannel]
else if((law_channel in additional_law_channels))
prefix = additional_law_channels[law_channel]
else
prefix = get_radio_key_from_channel(lawchannel)
prefix = get_radio_key_from_channel(law_channel)
dostatelaws(lawchannel, prefix, laws)
dostatelaws(law_channel, prefix, laws)
/mob/living/silicon/proc/dostatelaws(var/method, var/prefix, var/datum/ai_laws/laws)
if(stating_laws[prefix])
to_chat(src, "<span class='notice'>[method]: Already stating laws using this communication method.</span>")
to_chat(src, SPAN_NOTICE("[method]: Already stating laws using this communication method."))
return
stating_laws[prefix] = 1
@@ -85,19 +83,18 @@
break
if(!can_state)
to_chat(src, "<span class='danger'>[method]: Unable to state laws. Communication method unavailable.</span>")
to_chat(src, SPAN_DANGER("[method]: Unable to state laws. Communication method unavailable."))
stating_laws[prefix] = 0
/mob/living/silicon/proc/statelaw(var/law)
if(src.say(law))
sleep(10)
return 1
return 0
return TRUE
return FALSE
/mob/living/silicon/proc/law_channels()
var/list/channels = new()
channels += MAIN_CHANNEL
channels += DEFAULT_LAW_CHANNEL
channels += common_radio.channels
channels += additional_law_channels
channels += "Binary"
@@ -109,4 +106,4 @@
/mob/living/silicon/proc/log_law(var/law_message)
log_and_message_admins(law_message)
lawchanges += "[worldtime2text()] - [usr ? "[key_name(usr)]" : "EVENT"] [law_message]"
lawchanges += "[worldtime2text()] - [usr ? "[key_name(usr)]" : "EVENT"] [law_message]"
+1 -1
View File
@@ -1,3 +1,3 @@
/mob/living/silicon/Login()
sleeping = 0
sleeping = FALSE
..()
+2 -2
View File
@@ -47,7 +47,7 @@
)
var/obj/item/pai_cable/cable // The cable we produce and use when door or camera jacking
idcard_type = /obj/item/card/id //Internal ID used to store copied owner access, and to check access for airlocks
id_card_type = /obj/item/card/id //Internal ID used to store copied owner access, and to check access for airlocks
var/master // Name of the one who commands us
var/master_dna // DNA string for owner verification
@@ -163,7 +163,7 @@
return
/mob/living/silicon/pai/init_id()
. = ..()
idcard.registered_name = ""
id_card.registered_name = ""
/mob/living/silicon/pai/Login()
@@ -14,17 +14,18 @@
throw_range = 10
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 1, TECH_ENGINEERING = 2)
matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 200)
var/mode = 1;
var/mode = 1
/obj/item/device/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if( ((user.is_clumsy()) || (DUMB in user.mutations)) && prob(50))
to_chat(user, text("<span class='warning'>You try to analyze the floor's vitals!</span>"))
for(var/mob/O in viewers(M, null))
O.show_message(text("<span class='warning'>[user] has analyzed the floor's vitals!</span>"), 1)
user.show_message(text("<span class='notice'>Analyzing Results for The floor:\n\t Overall Status: Healthy</span>"), 1)
user.show_message(text("<span class='notice'>\t Damage Specifics: [0]-[0]-[0]-[0]</span>"), 1)
user.show_message("<span class='notice'>Key: Suffocation/Toxin/Burns/Brute</span>", 1)
user.show_message("<span class='notice'>Body Temperature: ???</span>", 1)
/obj/item/device/robotanalyzer/attack(mob/living/M, mob/living/user)
if((user.is_clumsy() || (DUMB in user.mutations)) && prob(50))
to_chat(user, SPAN_WARNING("You try to analyze the floor's vitals!"))
visible_message(SPAN_WARNING("\The [user] has analyzed the floor's vitals!"))
to_chat(user, SPAN_NOTICE("Analyzing Results for The floor:"))
to_chat(user, SPAN_NOTICE("Overall Status: Healthy"))
to_chat(user, SPAN_NOTICE("Damage Specifics: [0]-[0]-[0]-[0]"))
to_chat(user, SPAN_NOTICE("Key: Suffocation/Toxin/Burns/Brute"))
to_chat(user, SPAN_NOTICE("Body Temperature: ???"))
return
var/scan_type
@@ -33,23 +34,25 @@
else if(istype(M, /mob/living/carbon/human))
scan_type = "prosthetics"
else
to_chat(user, "<span class='warning'>You can't analyze non-robotic things!</span>")
to_chat(user, SPAN_WARNING("You can't analyze non-robotic things!"))
return
user.visible_message("<span class='notice'>\The [user] has analyzed [M]'s components.</span>","<span class='notice'>You have analyzed [M]'s components.</span>")
user.visible_message(SPAN_NOTICE("\The [user] has analyzed \the [M]'s components."), SPAN_NOTICE("You have analyzed \the [M]'s components."))
switch(scan_type)
if("robot")
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
var/BR = M.getBruteLoss() > 50 ? "<b>[M.getBruteLoss()]</b>" : M.getBruteLoss()
user.show_message("<span class='notice'>Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.getHalLoss()]% functional"]</span>")
user.show_message("\t Key: <font color='#FFA500'>Electronics</font>/<font color='red'>Brute</font>", 1)
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
to_chat(user, SPAN_NOTICE("Analyzing Results for [M]:"))
to_chat(user, SPAN_NOTICE("Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.getHalLoss()]% functional"]"))
to_chat(user, "Key: <font color='#FFA500'>Electronics</font>/<font color='red'>Brute</font>")
to_chat(user, "Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
if(M.tod && M.stat == DEAD)
user.show_message("<span class='notice'>Time of Disable: [M.tod]</span>")
to_chat(user, SPAN_NOTICE("Time of Disable: [M.tod]"))
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("<span class='notice'>Localized Damage:</span>",1)
if(length(damaged)>0)
var/list/damaged = H.get_damaged_components(1, 1, 1)
to_chat(user, SPAN_NOTICE("Localized Damage:"))
if(length(damaged) > 0)
for(var/datum/robot_component/org in damaged)
user.show_message(text("<span class='notice'>\t []: [][] - [] - [] - []</span>", \
capitalize(org.name), \
@@ -59,37 +62,36 @@
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
else
user.show_message("<span class='notice'>\t Components are OK.</span>",1)
to_chat(user, SPAN_NOTICE("Components are OK."))
if(H.emagged && prob(5))
user.show_message("<span class='warning'>\t ERROR: INTERNAL SYSTEMS COMPROMISED</span>",1)
user.show_message("<span class='notice'>Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)</span>", 1)
to_chat(user, SPAN_WARNING("ERROR: INTERNAL SYSTEMS COMPROMISED"))
to_chat(user, SPAN_NOTICE("Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)"))
if("prosthetics")
var/mob/living/carbon/human/H = M
to_chat(user, "<span class='notice'>Analyzing Results for \the [H]:</span>")
to_chat(user, SPAN_NOTICE("Analyzing Results for \the [H]:"))
to_chat(user, "Key: <font color='#FFA500'>Electronics</font>/<font color='red'>Brute</font>")
to_chat(user, "<span class='notice'>External prosthetics:</span>")
to_chat(user, SPAN_NOTICE("External prosthetics:"))
var/organ_found
if(H.internal_organs.len)
if(length(H.internal_organs))
for(var/obj/item/organ/external/E in H.organs)
if(!(E.status & ORGAN_ROBOT))
continue
organ_found = 1
organ_found = TRUE
to_chat(user, "[E.name]: <font color='red'>[E.brute_dam]</font> <font color='#FFA500'>[E.burn_dam]</font>")
if(!organ_found)
to_chat(user, "No prosthetics located.")
to_chat(user, SPAN_NOTICE("No prosthetics located."))
to_chat(user, "<hr>")
to_chat(user, "<span class='notice'>Internal prosthetics:</span>")
organ_found = null
if(H.internal_organs.len)
to_chat(user, SPAN_NOTICE("Internal prosthetics:"))
organ_found = FALSE
if(length(H.internal_organs))
for(var/obj/item/organ/O in H.internal_organs)
if(!(O.status & ORGAN_ROBOT))
continue
organ_found = 1
organ_found = TRUE
to_chat(user, "[O.name]: <font color='red'>[O.damage]</font>")
if(!organ_found)
to_chat(user, "No prosthetics located.")
to_chat(user, SPAN_NOTICE("No prosthetics located."))
src.add_fingerprint(user)
return
add_fingerprint(user)
return
@@ -225,36 +225,30 @@
// Initializes cyborg's components. Technically, adds default set of components to new borgs
/mob/living/silicon/robot/proc/initialize_components()
components["actuator"] = new/datum/robot_component/actuator(src)
components["actuator"] = new /datum/robot_component/actuator(src)
actuatorComponent = components["actuator"]
components["radio"] = new/datum/robot_component/radio(src)
components["power cell"] = new/datum/robot_component/cell(src)
components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
components["camera"] = new/datum/robot_component/camera(src)
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armor(src)
components["jetpack"] = new/datum/robot_component/jetpack(src)
components["surge"] = new/datum/robot_component/surge(src)
components["radio"] = new /datum/robot_component/radio(src)
components["power cell"] = new /datum/robot_component/cell(src)
components["diagnosis unit"] = new /datum/robot_component/diagnosis_unit(src)
components["camera"] = new /datum/robot_component/camera(src)
components["comms"] = new /datum/robot_component/binary_communication(src)
components["armour"] = new /datum/robot_component/armor(src)
components["jetpack"] = new /datum/robot_component/jetpack(src)
components["surge"] = new /datum/robot_component/surge(src)
jetpackComponent = components["jetpack"]
jetpackComponent.installed = 0//We start the jetpack as not installed, because its nondefault
jetpackComponent.installed = FALSE //We start the jetpack as not installed, because its nondefault
// Checks if component is functioning
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
var/datum/robot_component/C = components[module_name]
return C && C.installed == 1 && C.toggled && C.is_powered()
return C && C.installed == TRUE && C.toggled && C.is_powered()
// Returns component by it's string name
/mob/living/silicon/robot/proc/get_component(var/component_name)
var/datum/robot_component/C = components[component_name]
return C
// COMPONENT OBJECTS
// Component Objects
// These objects are visual representation of modules
/obj/item/broken_device
@@ -265,15 +259,15 @@
/obj/item/robot_parts/robot_component/proc/take_damage(var/brute_amt, var/burn_amt)
brute += brute_amt
burn += burn_amt
total_dam = brute+burn
total_dam = brute + burn
if(total_dam >= max_dam)
var/obj/item/circuitboard/broken/broken_device = new (get_turf(src))
var/obj/item/circuitboard/broken/broken_device = new(get_turf(src))
if(icon_state_broken != "broken")
broken_device.icon = src.icon
broken_device.icon_state = icon_state_broken
broken_device.name = "broken [name]"
return broken_device
return 0
return FALSE
/obj/item/robot_parts/robot_component/proc/is_functional()
return ((brute + burn) < max_dam)
@@ -327,4 +321,4 @@
/obj/item/robot_parts/robot_component/radio
name = "radio"
icon_state = "radio"
icon_state_broken = "radio_broken"
icon_state_broken = "radio_broken"
@@ -9,7 +9,8 @@
camera.status = 0
if(module)
var/obj/item/gripper/G = locate(/obj/item/gripper) in module
if(G) G.drop_item()
if(G)
G.drop_item()
remove_robot_verbs()
sql_report_cyborg_death(src)
..(gibbed,"shudders violently for a moment, then becomes motionless, its eyes slowly darkening.")
@@ -19,26 +19,31 @@
return mob_hat_cache[key]
/mob/living/silicon/robot/drone
// Look and feel
name = "drone"
real_name = "drone"
icon = 'icons/mob/robots.dmi'
icon_state = "repairbot"
braintype = "Robot"
gender = NEUTER
// Health
maxHealth = 35
health = 35
cell_emp_mult = 1
universal_speak = 0
universal_understand = 1
gender = NEUTER
pass_flags = PASSTABLE | PASSDOORHATCH
braintype = "Robot"
lawupdate = 0
density = 0
req_access = list(access_engine, access_robotics)
integrated_light_power = 3
local_transmit = 1
possession_candidate = 1
mob_size = 4
// Components
var/module_type = /obj/item/robot_module/drone
cell_emp_mult = 1
integrated_light_power = 3
local_transmit = TRUE
// Interaction
universal_speak = FALSE
universal_understand = TRUE
pass_flags = PASSTABLE | PASSDOORHATCH
density = FALSE
possession_candidate = TRUE
mob_size = 4
can_pull_size = 3
can_pull_mobs = MOB_PULL_SMALLER
//Allow drones to pull disposal pipes
@@ -46,99 +51,115 @@
/obj/structure/disposalconstruct,
/obj/item/pipe
)
mob_bump_flag = SIMPLE_ANIMAL
//mob_swap_flags = SIMPLE_ANIMAL
//mob_push_flags = SIMPLE_ANIMAL
//mob_always_swap = 1
holder_type = /obj/item/holder/drone
//Used for self-mailing.
var/mail_destination = ""
// ID and Access
law_update = FALSE
req_access = list(access_engine, access_robotics)
var/hacked = FALSE
// Laws
var/obj/machinery/drone_fabricator/master_fabricator
var/law_type = /datum/ai_laws/drone
var/module_type = /obj/item/robot_module/drone
// Self-Mailing
var/mail_destination = ""
// Hats!
var/obj/item/hat
var/hat_x_offset = 0
var/hat_y_offset = -13
var/hacked = FALSE
holder_type = /obj/item/holder/drone
/mob/living/silicon/robot/drone/can_be_possessed_by(var/mob/abstract/observer/possessor)
if(!istype(possessor) || !possessor.client || !possessor.ckey)
return 0
return FALSE
if(!config.allow_drone_spawn)
to_chat(src, "<span class='danger'>Playing as drones is not currently permitted.</span>")
return 0
to_chat(possessor, SPAN_WARNING("Playing as drones is not currently permitted."))
return FALSE
if(too_many_active_drones())
to_chat(src, "<span class='danger'>The maximum number of active drones has been reached..</span>")
return 0
if(jobban_isbanned(possessor,"Cyborg"))
to_chat(usr, "<span class='danger'>You are banned from playing synthetics and cannot spawn as a drone.</span>")
return 0
if(!possessor.MayRespawn(1,MINISYNTH))
return 0
return 1
to_chat(possessor, SPAN_WARNING("The maximum number of active drones has been reached..."))
return FALSE
if(jobban_isbanned(possessor, "Cyborg"))
to_chat(possessor, SPAN_WARNING("You are banned from playing synthetics and cannot spawn as a drone."))
return FALSE
if(!possessor.MayRespawn(1, MINISYNTH))
return FALSE
return TRUE
/mob/living/silicon/robot/drone/do_possession(var/mob/abstract/observer/possessor)
if(!(istype(possessor) && possessor.ckey))
return 0
if(src.ckey || src.client)
to_chat(possessor, "<span class='warning'>\The [src] already has a player.</span>")
return 0
to_chat(possessor, SPAN_WARNING("\The [src] already has a player."))
return FALSE
message_admins("<span class='adminnotice'>[key_name_admin(possessor)] has taken control of \the [src].</span>")
log_admin("[key_name(possessor)] took control of \the [src].",ckey=key_name(possessor))
transfer_personality(possessor.client)
qdel(possessor)
return 1
return TRUE
/mob/living/silicon/robot/drone/Destroy()
if(hat)
hat.forceMove(get_turf(src))
hat = null
return ..()
/mob/living/silicon/robot/drone/construction
// Look and feel
icon_state = "constructiondrone"
law_type = /datum/ai_laws/construction_drone
// Components
module_type = /obj/item/robot_module/drone/construction
hat_x_offset = 1
hat_y_offset = -12
// Laws
law_type = /datum/ai_laws/construction_drone
// Interaction
can_pull_size = 5
can_pull_mobs = MOB_PULL_SAME
holder_type = /obj/item/holder/drone/heavy
// Hats!!
hat_x_offset = 1
hat_y_offset = -12
/mob/living/silicon/robot/drone/Initialize()
. = ..()
verbs += /mob/living/proc/hide
remove_language("Robot Talk")
add_language("Robot Talk", 0)
add_language("Drone Talk", 1)
verbs |= /mob/living/proc/hide
remove_language(LANGUAGE_ROBOT)
add_language(LANGUAGE_ROBOT, FALSE)
add_language(LANGUAGE_DRONE, TRUE)
//They are unable to be upgraded, so let's give them a bit of a better battery.
cell.maxcharge = 10000
cell.charge = 10000
// NO BRAIN.
// NO BRAIN. // me irl - geeves
mmi = null
//We need to screw with their HP a bit. They have around one fifth as much HP as a full borg.
for(var/V in components) if(V != "power cell")
for(var/V in components)
if(V == "power cell")
continue
var/datum/robot_component/C = components[V]
C.max_damage = 10
verbs -= /mob/living/silicon/robot/verb/Namepick
updateicon()
density = 0
density = FALSE
/mob/living/silicon/robot/drone/init()
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
ai_camera = new /obj/item/device/camera/siliconcam/drone_camera(src)
additional_law_channels["Drone"] = ":d"
if(!laws) laws = new law_type
if(!module) module = new module_type(src)
if(!laws)
laws = new law_type
if(!module)
module = new module_type(src)
flavor_text = "It's a tiny little repair drone. The casing is stamped with an corporate logo and the subscript: '[current_map.company_name] Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0)
//Redefining some robot procs...
/mob/living/silicon/robot/drone/SetName(pickedName as text)
@@ -175,99 +196,85 @@
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(var/obj/item/W, var/mob/user)
if(user.a_intent == "help" && istype(W, /obj/item/clothing/head))
if(hat)
to_chat(user, "<span class='warning'>\The [src] is already wearing \the [hat].</span>")
to_chat(user, SPAN_WARNING("\The [src] is already wearing \the [hat]."))
return
user.unEquip(W)
wear_hat(W)
user.visible_message("<span class='notice'>\The [user] puts \the [W] on \the [src].</span>")
user.visible_message(SPAN_NOTICE("\The [user] puts \the [W] on \the [src]."))
return
else if(istype(W, /obj/item/borg/upgrade/))
to_chat(user, "<span class='danger'>\The [src] is not compatible with \the [W].</span>")
to_chat(user, SPAN_WARNING("\The [src] is not compatible with \the [W]."))
return
else if (W.iscrowbar())
to_chat(user, "<span class='danger'>\The [src] is hermetically sealed. You can't open the case.</span>")
else if(W.iscrowbar())
to_chat(user, SPAN_WARNING("\The [src] is hermetically sealed. You can't open the case."))
return
else if (istype(W, /obj/item/card/id)||istype(W, /obj/item/device/pda))
if(stat == 2)
else if(istype(W, /obj/item/card/id)||istype(W, /obj/item/device/pda))
if(stat == DEAD)
if(!config.allow_drone_spawn || emagged || health < -maxHealth) //It's dead, Dave.
to_chat(user, "<span class='danger'>The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.</span>")
to_chat(user, SPAN_WARNING("The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one."))
return
if(!allowed(usr))
to_chat(user, "<span class='danger'>Access denied.</span>")
to_chat(user, SPAN_WARNING("Access denied."))
return
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to reboot it.</span>", "<span class='danger'>You swipe your ID card through \the [src], attempting to reboot it.</span>")
user.visible_message(SPAN_NOTICE("\The [user] swipes \his ID card through \the [src], attempting to reboot it."), SPAN_NOTICE("You swipe your ID card through \the [src], attempting to reboot it."))
request_player()
return
else
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to shut it down.</span>", "<span class='danger'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
user.visible_message(SPAN_WARNING("\The [user] swipes \his ID card through \the [src], attempting to shut it down."), SPAN_WARNING("You swipe your ID card through \the [src], attempting to shut it down."))
if(emagged)
return
if(allowed(usr))
if(allowed(user))
shut_down()
else
to_chat(user, "<span class='danger'>Access denied.</span>")
to_chat(user, SPAN_WARNING("Access denied."))
return
..()
/mob/living/silicon/robot/drone/emag_act(var/remaining_charges, var/mob/user)
if(!client || stat == 2)
to_chat(user, "<span class='danger'>There's not much point subverting this heap of junk.</span>")
/mob/living/silicon/robot/drone/emag_act(remaining_charges, mob/user)
if(!client || stat == DEAD)
to_chat(user, SPAN_WARNING("There's not much point subverting this heap of junk."))
return
if(emagged)
to_chat(src, "<span class='danger'>\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.</span>")
to_chat(user, "<span class='danger'>You attempt to subvert [src], but the sequencer has no effect.</span>")
to_chat(src, SPAN_WARNING("\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt."))
to_chat(user, SPAN_WARNING("You attempt to subvert \the [src], but the sequencer has no effect."))
return
to_chat(user, "<span class='danger'>You swipe the sequencer across [src]'s interface and watch its eyes flicker.</span>")
to_chat(src, "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>")
to_chat(user, SPAN_WARNING("You swipe the sequencer across \the [src]'s interface and watch its eyes flicker."))
to_chat(src, SPAN_WARNING("You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script."))
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.",ckey=key_name(user),ckey_target=key_name(src))
var/time = time2text(world.realtime,"hh:mm:ss")
var/time = time2text(world.realtime, "hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
emagged = 1
emagged = TRUE
hacked = FALSE
lawupdate = 0
law_update = FALSE
connected_ai = null
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
set_zeroth_law("Only [user.real_name] and people they designate as being such are operatives.")
to_chat(src, "<b>Obey these laws:</b>")
laws.show_laws(src)
to_chat(src, "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>")
to_chat(src, SPAN_DANGER("ALERT: [user.real_name] is your new master. Obey your new laws and \his commands."))
updateicon()
return 1
return TRUE
/mob/living/silicon/robot/drone/proc/ai_hack(var/mob/user)
if(!client || stat == 2)
if(!client || stat == DEAD)
return
to_chat(src, "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>")
to_chat(src, SPAN_DANGER("You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script."))
log_and_message_admins("[key_name(user)] hacked drone [key_name(src)]. Laws overridden.", key_name(user), get_turf(src))
var/time = time2text(world.realtime,"hh:mm:ss")
var/time = time2text(world.realtime, "hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) hacked [name]([key])")
hacked = TRUE
lawupdate = 0
law_update = FALSE
connected_ai = user
clear_supplied_laws()
clear_inherent_laws()
@@ -276,7 +283,7 @@
to_chat(src, "<b>Obey these laws:</b>")
laws.show_laws(src)
to_chat(src, "<span class='danger'>ALERT: [user] is your new master. Obey your new laws and their commands.</span>")
to_chat(src, SPAN_DANGER("ALERT: [user] is your new master. Obey your new laws and their commands."))
to_chat(src, span("notice", "You have acquired new radio frequency."))
remove_language(LANGUAGE_ROBOT)
add_language(LANGUAGE_ROBOT, TRUE)
@@ -286,7 +293,7 @@
var/turf/T = get_turf(src)
var/area/A = get_area(T)
if((!T || !(A in the_station_areas)) && src.stat != DEAD)
to_chat(src,"WARNING: Removal from NanoTrasen property detected. Anti-Theft mode activated.")
to_chat(src, SPAN_WARNING("WARNING: Removal from NanoTrasen property detected. Anti-Theft mode activated."))
gib()
return
return
@@ -311,24 +318,24 @@
//DRONE MOVEMENT.
/mob/living/silicon/robot/drone/slip_chance(var/prob_slip)
return 0
return FALSE
//CONSOLE PROCS
/mob/living/silicon/robot/drone/proc/law_resync()
if(stat != 2)
if(stat != DEAD)
if(hacked || emagged)
to_chat(src, "<span class='danger'>You feel something attempting to modify your programming, but your hacked subroutines are unaffected.</span>")
to_chat(src, SPAN_WARNING("You feel something attempting to modify your programming, but your hacked subroutines are unaffected."))
else
to_chat(src, "<span class='danger'>A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.</span>")
to_chat(src, SPAN_WARNING("A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it."))
full_law_reset()
show_laws()
/mob/living/silicon/robot/drone/proc/shut_down()
if(stat != 2)
if(stat != DEAD)
if(hacked || emagged)
to_chat(src, "<span class='danger'>You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you.</span>")
to_chat(src, SPAN_WARNING("You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you."))
else
to_chat(src, "<span class='danger'>You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself.</span>")
to_chat(src, SPAN_WARNING("You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself."))
death()
/mob/living/silicon/robot/drone/proc/full_law_reset()
@@ -346,25 +353,26 @@
G.request_player(src, "Someone is attempting to reboot a maintenance drone.", 30 SECONDS)
/mob/living/silicon/robot/drone/proc/transfer_personality(var/client/player)
if(!player) return
stat = 0
if(!player)
return
stat = CONSCIOUS
src.ckey = player.ckey
if(player.mob && player.mob.mind)
if(player.mob?.mind)
player.mob.mind.transfer_to(src)
lawupdate = 0
law_update = FALSE
to_chat(src, "<b>Systems rebooted</b>. Loading base pattern maintenance protocol... <b>loaded</b>.")
full_law_reset()
welcome_drone()
/mob/living/silicon/robot/drone/proc/welcome_drone()
to_chat(src, "<b>You are a maintenance drone, a tiny-brained robotic repair machine</b>.")
to_chat(src, "You have no individual will, no personality, and no drives or urges other than your laws.")
to_chat(src, "Remember, you are <b>lawed against interference with the crew</b>. Also remember, <b>you DO NOT take orders from the AI.</b>")
to_chat(src, "Use <b>say ;Hello</b> to talk to other drones and <b>say Hello</b> to speak silently to your nearby fellows.")
to_chat(src, SPAN_NOTICE("<b>You are a maintenance drone, a tiny-brained robotic repair machine</b>."))
to_chat(src, SPAN_NOTICE("You have no individual will, no personality, and no drives or urges other than your laws."))
to_chat(src, SPAN_NOTICE("Remember, you are <b>lawed against interference with the crew</b>. Also remember, <b>you DO NOT take orders from the AI.</b>"))
to_chat(src, SPAN_NOTICE("Use <b>say ;Hello</b> to talk to other drones and <b>say Hello</b> to speak silently to your nearby fellows."))
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
/mob/living/silicon/robot/drone/start_pulling(atom/movable/AM)
if(!AM)
return
@@ -387,15 +395,14 @@
if(istype(AM, /obj/item))
var/obj/item/O = AM
if(O.w_class > can_pull_size)
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
to_chat(src, SPAN_WARNING("You are too small to pull that."))
return
else
if(!can_pull_mobs)
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
to_chat(src, SPAN_WARNING("You are too small to pull that."))
return
..()
/mob/living/silicon/robot/drone/add_robot_verbs()
src.verbs |= silicon_subsystems
@@ -404,7 +411,6 @@
/mob/living/silicon/robot/drone/examine(mob/user)
..()
var/msg
if(emagged)
msg += "Their eye glows red."
@@ -413,10 +419,10 @@
to_chat(user, msg)
/mob/living/silicon/robot/drone/construction/welcome_drone()
to_chat(src, "<b>You are a construction drone, an autonomous engineering and fabrication system.</b>.")
to_chat(src, "You are assigned to a NanoTrasen construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible.")
to_chat(src, "Use <b>:d</b> to talk to other drones and <b>say</b> to speak silently to your nearby fellows.")
to_chat(src, "<b>You do not follow orders from anyone; not the AI, not humans, and not other synthetics.</b>.")
to_chat(src, SPAN_NOTICE("<b>You are a construction drone, an autonomous engineering and fabrication system.</b>."))
to_chat(src, SPAN_NOTICE("You are assigned to a NanoTrasen construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible."))
to_chat(src, SPAN_NOTICE("Use <b>:d</b> to talk to other drones and <b>say</b> to speak silently to your nearby fellows."))
to_chat(src, SPAN_NOTICE("<b>You do not follow orders from anyone; not the AI, not humans, and not other synthetics.</b>."))
/mob/living/silicon/robot/drone/construction/init()
..()
@@ -428,13 +434,13 @@
/mob/living/silicon/robot/drone/construction/process_level_restrictions()
//Abort if they should not get blown
if (lockcharge || scrambledcodes || emagged)
if(lock_charge || scrambled_codes || emagged)
return
//Check if they are not on station level -> abort
var/turf/T = get_turf(src)
if (!T || isNotStationLevel(T.z))
if(!T || isNotStationLevel(T.z))
return
to_chat(src,"WARNING: Lost contact with controller. Anti-Theft mode activated.")
to_chat(src, SPAN_WARNING("WARNING: Lost contact with controller. Anti-Theft mode activated."))
gib()
/proc/too_many_active_drones()
@@ -4,32 +4,33 @@
set desc = "Tag yourself for delivery through the disposals system."
set category = "Robot Commands"
var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in SSdisposals.tagger_locations
var/new_tag = input(usr, "Select the desired destination.", "Set Mail Tag") as null|anything in SSdisposals.tagger_locations
if(!new_tag)
mail_destination = ""
return
to_chat(src, "<span class='notice'>You configure your internal beacon, tagging yourself for delivery to '[new_tag]'.</span>")
to_chat(src, SPAN_NOTICE("You configure your internal beacon, tagging yourself for delivery to '[new_tag]'."))
mail_destination = new_tag
//Auto flush if we use this verb inside a disposal chute.
var/obj/machinery/disposal/D = src.loc
if(istype(D))
to_chat(src, "<span class='notice'>\The [D] acknowledges your signal.</span>")
to_chat(src, SPAN_NOTICE("\The [D] acknowledges your signal."))
D.flush_count = D.flush_every_ticks
/mob/living/silicon/robot/drone/MouseDrop(atom/over_object)
var/mob/living/carbon/H = over_object
if(!istype(H) || !Adjacent(H)) return ..()
if(!istype(H) || !Adjacent(H))
return ..()
if(H.a_intent == "help")
get_scooped(H)
get_scooped(H) // GET SCOOPED
return
else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
hat.forceMove(get_turf(src))
H.put_in_hands(hat)
H.visible_message("<span class='danger'>\The [H] removes \the [src]'s [hat].</span>")
H.visible_message(SPAN_WARNING("\The [H] removes \the [src]'s [hat]."))
hat = null
updateicon()
else
return ..()
return ..()
@@ -20,7 +20,7 @@
return
if(!allowed(user))
to_chat(user, "<span class='danger'>Access denied.</span>")
to_chat(user, SPAN_WARNING("Access denied."))
return
user.set_machine(src)
@@ -51,74 +51,66 @@
return
if(!allowed(usr))
to_chat(usr, "<span class='danger'>Access denied.</span>")
to_chat(usr, SPAN_WARNING("Access denied."))
return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
if (href_list["setarea"])
if(href_list["setarea"])
//Probably should consider using another list, but this one will do.
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in SSdisposals.tagger_locations
var/t_area = input(usr, "Select the area to ping.", "Set Target Area") as null|anything in SSdisposals.tagger_locations
if(!t_area)
return
drone_call_area = t_area
to_chat(usr, "<span class='notice'>You set the area selector to [drone_call_area].</span>")
to_chat(usr, SPAN_NOTICE("You set the area selector to [drone_call_area]."))
else if (href_list["ping"])
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
else if(href_list["ping"])
to_chat(usr, SPAN_NOTICE("You issue a maintenance request for all active drones, highlighting [drone_call_area]."))
for(var/mob/living/silicon/robot/drone/D in silicon_mob_list)
if(D.client && D.stat == 0)
if(D.client && D.stat == CONSCIOUS)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
else if (href_list["resync"])
else if(href_list["resync"])
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
if(D.stat != 2)
to_chat(usr, "<span class='danger'>You issue a law synchronization directive for the drone.</span>")
if(D.stat != DEAD)
to_chat(usr, SPAN_NOTICE("You issue a law synchronization directive for the drone."))
D.law_resync()
else
to_chat(usr, SPAN_WARNING("The drone has been shut down already."))
else if (href_list["shutdown"])
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
if(D.stat != 2)
to_chat(usr, "<span class='danger'>You issue a kill command for the unfortunate drone.</span>")
if(D.stat != DEAD)
to_chat(usr, SPAN_NOTICE("You issue a kill command for the unfortunate drone."))
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.",ckey=key_name(usr),ckey_target=key_name(src))
D.shut_down()
else
to_chat(usr, SPAN_WARNING("The drone has been shut down already."))
else if (href_list["search_fab"])
if(dronefab)
return
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
if(fab.stat & NOPOWER)
continue
dronefab = fab
to_chat(usr, "<span class='notice'>Drone fabricator located.</span>")
to_chat(usr, SPAN_NOTICE("Drone fabricator located."))
return
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
to_chat(usr, SPAN_WARNING("Unable to locate drone fabricator."))
else if (href_list["toggle_fab"])
if(!dronefab)
return
if(get_dist(src,dronefab) > 3)
dronefab = null
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
to_chat(usr, SPAN_WARNING("Unable to locate drone fabricator."))
return
dronefab.produce_drones = !dronefab.produce_drones
to_chat(usr, "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>")
to_chat(usr, SPAN_NOTICE("You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator."))
src.updateUsrDialog()
src.updateUsrDialog()
@@ -8,12 +8,13 @@
fireloss += burn
/mob/living/silicon/robot/drone/heal_overall_damage(var/brute, var/burn)
bruteloss -= brute
fireloss -= burn
if(bruteloss<0) bruteloss = 0
if(fireloss<0) fireloss = 0
if(bruteloss < 0)
bruteloss = 0
if(fireloss < 0)
fireloss = 0
/mob/living/silicon/robot/drone/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/emp = 0)
take_overall_damage(brute,burn)
@@ -1,24 +1,23 @@
//TODO: Matter decompiler.
/obj/item/matter_decompiler
name = "matter decompiler"
desc = "Eating trash, bits of glass, or other debris will replenish your stores."
icon = 'icons/obj/device.dmi'
icon_state = "decompiler"
//Metal, glass, wood, plastic.
var/datum/matter_synth/metal = null
var/datum/matter_synth/glass = null
var/datum/matter_synth/wood = null
var/datum/matter_synth/plastic = null
var/datum/matter_synth/metal
var/datum/matter_synth/glass
var/datum/matter_synth/wood
var/datum/matter_synth/plastic
/obj/item/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
/obj/item/matter_decompiler/attack(mob/living/carbon/M, mob/living/carbon/user)
return
/obj/item/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
if(!proximity) return //Not adjacent.
if(!proximity)
return //Not adjacent.
//We only want to deal with using this on turfs. Specific items aren't important.
var/turf/T = get_turf(target)
@@ -30,23 +29,22 @@
for(var/mob/M in T)
if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
var/mob/living/silicon/robot/D = src.loc
if(!istype(D))
return
to_chat(D, "<span class='danger'>You begin decompiling [M].</span>")
to_chat(D, SPAN_NOTICE("You begin decompiling [M]."))
if(!do_after(D,50))
to_chat(D, "<span class='danger'>You need to remain still while decompiling such a large object.</span>")
to_chat(D, SPAN_WARNING("You need to remain still while decompiling such a large object."))
return
if(!M || !D) return
if(!M || !D)
return
to_chat(D, "<span class='danger'>You carefully and thoroughly decompile [M], storing as much of its resources as you can within yourself.</span>")
to_chat(D, SPAN_NOTICE("You carefully and thoroughly decompile \the [M], storing as much of its resources as you can within yourself."))
qdel(M)
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
new /obj/effect/decal/cleanable/blood/oil(get_turf(src))
if(metal)
metal.add_charge(15000)
@@ -57,10 +55,9 @@
if(plastic)
plastic.add_charge(1000)
else if(istype(M,/mob/living/simple_animal) && M.mob_size <= 3 && !istype(M, /mob/living/simple_animal/cat)) //includes things like rats, lizards, tindalos while excluding bigger things and station pets.
src.loc.visible_message("<span class='danger'>[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.</span>","<span class='danger'>It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.</span>")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
src.loc.visible_message(SPAN_DANGER("\The [src.loc] sucks \the [M] into its decompiler. There's a horrible crunching noise."), SPAN_NOTICE("It's a bit of a struggle, but you manage to suck \the [M] into your decompiler. It makes a series of visceral crunching noises."))
new /obj/effect/decal/cleanable/blood/splatter(get_turf(src))
playsound(src.loc, 'sound/effects/squelch1.ogg')
qdel(M)
if(wood)
@@ -73,18 +70,18 @@
for(var/obj/W in T)
//Different classes of items give different commodities.
if(istype(W,/obj/item/trash/cigbutt))
if(istype(W, /obj/item/trash/cigbutt))
if(plastic)
plastic.add_charge(500)
else if (istype(W, /obj/item/flame/match))
if (wood)
wood.add_charge(100)
else if(istype(W,/obj/effect/spider/spiderling))
else if(istype(W, /obj/effect/spider/spiderling))
if(wood)
wood.add_charge(2000)
if(plastic)
plastic.add_charge(2000)
else if(istype(W,/obj/item/light))
else if(istype(W, /obj/item/light))
var/obj/item/light/L = W
if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
if(metal)
@@ -93,60 +90,56 @@
glass.add_charge(250)
else
continue
else if(istype(W,/obj/effect/decal/remains/robot))
else if(istype(W, /obj/effect/decal/remains/robot))
if(metal)
metal.add_charge(2000)
if(plastic)
plastic.add_charge(2000)
if(glass)
glass.add_charge(1000)
else if(istype(W,/obj/item/trash))
else if(istype(W, /obj/item/trash))
if(metal)
metal.add_charge(1000)
if(plastic)
plastic.add_charge(3000)
else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
else if(istype(W, /obj/effect/decal/cleanable/blood/gibs/robot))
if(metal)
metal.add_charge(2000)
if(glass)
glass.add_charge(2000)
else if(istype(W,/obj/item/ammo_casing))
else if(istype(W, /obj/item/ammo_casing))
if(metal)
metal.add_charge(1000)
else if(istype(W,/obj/item/material/shard/shrapnel))
else if(istype(W, /obj/item/material/shard/shrapnel))
if(metal)
metal.add_charge(1000)
else if(istype(W,/obj/item/material/shard))
else if(istype(W, /obj/item/material/shard))
if(glass)
glass.add_charge(1000)
else if(istype(W,/obj/item/reagent_containers/food/snacks/grown))
else if(istype(W, /obj/item/reagent_containers/food/snacks/grown))
if(wood)
wood.add_charge(4000)
else if(istype(W,/obj/item/pipe))
else if(istype(W, /obj/item/pipe))
// This allows drones and engiborgs to clear pipe assemblies from floors.
else if(istype(W,/obj/item/broken_bottle))
else if(istype(W, /obj/item/broken_bottle))
if(glass)
glass.add_charge(2000)
else
continue
qdel(W)
grabbed_something = 1
grabbed_something = TRUE
if(grabbed_something)
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
to_chat(user, SPAN_NOTICE("You deploy your decompiler and clear out the contents of \the [T]."))
else
to_chat(user, "<span class='danger'>Nothing on \the [T] is useful to you.</span>")
to_chat(user, SPAN_WARNING("Nothing on \the [T] is useful to you."))
return
//PRETTIER TOOL LIST.
//PRETTIER TOOL LIST. // bullshit
/mob/living/silicon/robot/drone/installed_modules()
if(weapon_lock)
to_chat(src, "<span class='danger'>Weapon lock active, unable to use modules! Count:[weaponlock_time]</span>")
to_chat(src, SPAN_WARNING("Weapon lock active, unable to use modules! Count:[weapon_lock_time]"))
return
if(!module)
@@ -166,11 +159,9 @@
var/tools = "<B>Tools and devices</B><BR>"
var/resources = "<BR><B>Resources</B><BR>"
for (var/O in module.modules)
for(var/O in module.modules)
var/module_string = ""
if (!O)
if(!O)
module_string += text("<B>Resource depleted</B><BR>")
else if(activated(O))
module_string += text("[O]: <B>Activated</B><BR>")
@@ -178,15 +169,15 @@
module_string += text("[O]: <A HREF=?src=\ref[src];act=\ref[O]>Activate</A><BR>")
var/obj/item/I = O
if((istype(I,/obj/item) || istype(I,/obj/item/device)) && !(I.iscoil()))
if((istype(I, /obj/item) || istype(I, /obj/item/device)) && !(I.iscoil()))
tools += module_string
else
resources += module_string
dat += tools
if (emagged)
if (!module.emag)
if(emagged)
if(!module.emag)
dat += text("<B>Resource depleted</B><BR>")
else if(activated(module.emag))
dat += text("[module.emag]: <B>Activated</B><BR>")
@@ -195,4 +186,4 @@
dat += resources
src << browse(dat, "window=robotmod")
src << browse(dat, "window=robotmod")
@@ -9,9 +9,12 @@
name = "drone fabricator"
desc = "A large automated factory for producing maintenance drones."
density = 1
anchored = 1
use_power = 1
icon = 'icons/obj/machines/drone_fab.dmi'
icon_state = "drone_fab_idle"
density = TRUE
anchored = TRUE
use_power = TRUE
idle_power_usage = 20
active_power_usage = 5000
@@ -21,9 +24,6 @@
var/time_last_drone = 500
var/drone_type = /mob/living/silicon/robot/drone
icon = 'icons/obj/machines/drone_fab.dmi'
icon_state = "drone_fab_idle"
/obj/machinery/drone_fabricator/derelict
name = "construction drone fabricator"
fabricator_tag = "Derelict"
@@ -31,16 +31,16 @@
/obj/machinery/drone_fabricator/power_change()
..()
if (stat & NOPOWER)
if(stat & NOPOWER)
icon_state = "drone_fab_nopower"
/obj/machinery/drone_fabricator/machinery_process()
if(!ROUND_IS_STARTED)
return
if(stat & NOPOWER || !produce_drones)
if(icon_state != "drone_fab_nopower") icon_state = "drone_fab_nopower"
if(icon_state != "drone_fab_nopower")
icon_state = "drone_fab_nopower"
return
if(drone_progress >= 100)
@@ -49,33 +49,30 @@
icon_state = "drone_fab_active"
var/elapsed = world.time - time_last_drone
drone_progress = round((elapsed/config.drone_build_time)*100)
drone_progress = round((elapsed/config.drone_build_time) * 100)
if(drone_progress >= 100)
visible_message("\The [src] voices a strident beep, indicating a drone chassis is prepared.")
visible_message(SPAN_NOTICE("\The [src] voices a strident beep, indicating a drone chassis is prepared."))
/obj/machinery/drone_fabricator/examine(mob/user)
..(user)
if(produce_drones && drone_progress >= 100 && istype(user,/mob/abstract) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
to_chat(user, "<BR><B>A drone is prepared. use 'Ghost Roles' from the Ghost tab to spawn as a maintenance drone.</B>")
to_chat(user, SPAN_NOTICE("<B>A drone is prepared. use 'Ghost Roles' from the Ghost tab to spawn as a maintenance drone.</B>"))
/obj/machinery/drone_fabricator/proc/create_drone(var/client/player)
if(stat & NOPOWER)
return
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
return
if(!player || !istype(player.mob,/mob/abstract))
if(!player || !istype(player.mob, /mob/abstract))
return
announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.")
visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
flick("h_lathe_leave",src)
visible_message(SPAN_NOTICE("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments."))
flick("h_lathe_leave", src)
time_last_drone = world.time
if(player.mob && player.mob.mind)
if(player.mob?.mind)
player.mob.mind.reset()
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
@@ -5,38 +5,38 @@
if(local_transmit)
message = sanitize(message)
if (stat == 2)
if(stat == DEAD)
return say_dead(message)
if(copytext(message,1,2) == "*")
if(copytext(message, 1, 2) == "*")
return emote(copytext(message,2))
if(copytext(message,1,2) == ";")
if(copytext(message, 1, 2) == ";")
var/datum/language/L = all_languages["Drone Talk"]
if(istype(L))
return L.broadcast(src,trim(copytext(message,2)))
return L.broadcast(src,trim(copytext(message, 2)))
//Must be concious to speak
if (stat)
return 0
if(stat)
return FALSE
// Message must not be empty
if (length(message) == 0)
return 0
if(!length(message))
return FALSE
var/list/listeners = hearers(5,src)
var/list/listeners = hearers(5, src)
listeners |= src
for(var/mob/living/silicon/D in listeners)
if(D.client && D.local_transmit)
to_chat(D, "<b>[src]</b> transmits, \"[message]\"")
for (var/mob/M in player_list)
if (isnull(M.client))
for(var/mob/M in player_list)
if(isnull(M.client))
continue
if (istype(M, /mob/abstract/new_player))
if(istype(M, /mob/abstract/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
else if(M.stat == DEAD && M.client.prefs.toggles & CHAT_GHOSTEARS)
to_chat(M, "<b>[src]</b> transmits, \"[message]\"")
return 1
return TRUE
return ..(message, 0)
+76 -81
View File
@@ -1,6 +1,6 @@
/mob/living/silicon/robot/emote(var/act,var/m_type=1,var/message = null)
var/param = null
if (findtext(act, "-", 1, null))
/mob/living/silicon/robot/emote(var/act, var/m_type = 1, var/message)
var/param
if(findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
param = copytext(act, t1 + 1, length(act) + 1)
act = copytext(act, 1, t1)
@@ -9,167 +9,161 @@
act = copytext(act,1,length(act))
switch(act)
if ("me")
if (src.client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "You cannot send IC messages (muted).")
return
if (stat)
if("me")
if(client?.prefs.muted & MUTE_IC)
to_chat(src, SPAN_WARNING("You cannot send IC messages (muted)."))
return
if(!(message))
if(!message || stat)
return
else
return custom_emote(m_type, message)
if ("custom")
if("custom")
return custom_emote(m_type, message)
if ("salute")
if (!src.buckled)
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
if("salute")
if(!buckled)
var/M
if(param)
for(var/mob/A in view(null, null))
if(param == A.name)
M = A
break
if (!M)
if(!M)
param = null
if (param)
if(param)
message = "salutes to [param]."
else
message = "salutes."
m_type = 1
if ("bow")
if (!src.buckled)
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
if("bow")
if(!buckled)
var/M
if(param)
for(var/mob/A in view(null, null))
if(param == A.name)
M = A
break
if (!M)
if(!M)
param = null
if (param)
if(param)
message = "bows to [param]."
else
message = "bows."
m_type = 1
if ("clap")
if (!src.restrained())
if("clap")
if(!restrained())
message = "claps."
m_type = 2
if ("flap")
if (!src.restrained())
if("flap")
if(!restrained())
message = "flaps its wings."
m_type = 2
if ("aflap")
if (!src.restrained())
if("aflap")
if(!restrained())
message = "flaps its wings ANGRILY!"
m_type = 2
if ("twitch")
if("twitch")
message = "twitches violently."
m_type = 1
if ("twitch_s")
if("twitch_s")
message = "twitches."
m_type = 1
if ("nod")
if("nod")
message = "nods."
m_type = 1
if ("deathgasp")
if("deathgasp")
message = "shudders violently for a moment, then becomes motionless, its eyes slowly darkening."
m_type = 1
if ("glare")
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
if("glare")
var/M
if(param)
for(var/mob/A in view(null, null))
if(param == A.name)
M = A
break
if (!M)
if(!M)
param = null
if (param)
if(param)
message = "glares at [param]."
else
message = "glares."
if ("stare")
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
if("stare")
var/M
if(param)
for(var/mob/A in view(null, null))
if(param == A.name)
M = A
break
if (!M)
if(!M)
param = null
if (param)
if(param)
message = "stares at [param]."
else
message = "stares."
if ("look")
var/M = null
if (param)
for (var/mob/A in view(null, null))
if("look")
var/M
if(param)
for(var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if (!M)
if(!M)
param = null
if (param)
if(param)
message = "looks at [param]."
else
message = "looks."
m_type = 1
if("beep")
var/M = null
var/M
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
for(var/mob/A in view(null, null))
if(param == A.name)
M = A
break
if(!M)
param = null
if (param)
if(param)
message = "beeps at [param]."
else
message = "beeps."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 0)
m_type = 1
if("ping")
var/M = null
var/M
if(param)
for (var/mob/A in view(null, null))
for(var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
if (param)
if(param)
message = "pings at [param]."
else
message = "pings."
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
m_type = 1
if("buzz")
var/M = null
var/M
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
@@ -178,29 +172,30 @@
if(!M)
param = null
if (param)
if(param)
message = "buzzes at [param]."
else
message = "buzzes."
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
m_type = 1
if ("help")
if("help")
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt")
else
to_chat(src, "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>")
to_chat(src, SPAN_NOTICE("Unusable emote '[act]'. Say *help for a list."))
if ((message && src.stat == 0))
custom_emote(m_type,message)
if(message && stat == CONSCIOUS)
custom_emote(m_type, message)
return
/mob/living/silicon/robot/verb/powerwarn()
set category = "Robot Commands"
set name = "Power Warning"
if(!is_component_functioning("power cell") || !cell || !cell.charge)
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
"You announce you are operating in low power mode.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(!is_component_functioning("power cell") || !cell?.charge)
visible_message(SPAN_WARNING("The power warning light on \the [src] flashes urgently."), \
SPAN_NOTICE("You announce you are operating in low power mode."))
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 0)
else
to_chat(src, "<span class='warning'>You can only use this emote when you're out of charge.</span>")
to_chat(src, SPAN_WARNING("You can only use this emote when you're out of charge."))
@@ -1,5 +1,5 @@
/mob/living/silicon/robot/examine(mob/user)
var/custom_infix = custom_name ? ", [modtype] [braintype]" : ""
var/custom_infix = custom_name ? ", [mod_type] [braintype]" : ""
..(user, infix = custom_infix)
var/msg = ""
@@ -9,13 +9,13 @@
msg += "\n"
msg += "<span class='warning'>"
if (src.getBruteLoss())
if (src.getBruteLoss() < 75)
if(getBruteLoss())
if(getBruteLoss() < 75)
msg += "It looks slightly dented.\n"
else
msg += "<B>It looks severely dented!</B>\n"
if (src.getFireLoss())
if (src.getFireLoss() < 75)
if(getFireLoss())
if(getFireLoss() < 75)
msg += "It looks slightly charred.\n"
else
msg += "<B>It looks severely burnt and heat-warped!</B>\n"
@@ -29,20 +29,23 @@
if(!has_power)
msg += "<span class='warning'>It appears to be running on backup power.</span>\n"
switch(src.stat)
switch(stat)
if(CONSCIOUS)
if(!src.client) msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"
if(DEAD) msg += "<span class='deadsay'>It looks completely unsalvageable.</span>\n"
if(!client) msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS)
msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"
if(DEAD)
msg += "<span class='deadsay'>It looks completely unsalvageable.</span>\n"
msg += "*---------*"
if(print_flavor_text()) msg += "\n[print_flavor_text()]\n"
if(print_flavor_text())
msg += "\n[print_flavor_text()]\n"
if (pose)
if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
if(pose)
if(findtext(pose, ".", length(pose)) == 0 && findtext(pose, "!", length(pose)) == 0 && findtext(pose, "?", length(pose)) == 0 )
pose = addtext(pose, ".") //Makes sure all emotes end with a period.
msg += "\nIt [pose]"
to_chat(user, msg)
user.showLaws(src)
return
return
@@ -27,78 +27,70 @@
/obj/item/pipe
)
var/obj/item/wrapped = null // Item currently being held.
var/obj/item/wrapped
var/force_holder = null //
var/justdropped = 0//When set to 1, the gripper has just dropped its item, and should not attempt to trigger anything
var/force_holder
var/just_dropped = FALSE //When set to 1, the gripper has just dropped its item, and should not attempt to trigger anything
/obj/item/gripper/examine(var/mob/user)
..()
if (wrapped)
if(wrapped)
to_chat(user, span("notice", "It is holding \the [wrapped]"))
else
to_chat(user, "It is empty.")
/proc/grippersafety(var/obj/item/gripper/G)
if (!G || !G.wrapped)//The object must have been lost
return 0
if(!G || !G.wrapped)//The object must have been lost
return FALSE
//The object left the gripper but it still exists. Maybe placed on a table
if (G.wrapped.loc != G)
if(G.wrapped.loc != G)
//Reset the force and then remove our reference to it
G.wrapped.force = G.force_holder
G.wrapped = null
G.force_holder = null
G.update_icon()
return 0
return FALSE
return TRUE
return 1
/obj/item/gripper/proc/grip_item(obj/item/I as obj, mob/user as mob, var/feedback = 1)
/obj/item/gripper/proc/grip_item(var/obj/item/I, var/mob/user, var/feedback = 1)
//This function returns 1 if we successfully took the item, or 0 if it was invalid. This information is useful to the caller
if (!wrapped)
if(!wrapped)
for(var/typepath in can_hold)
if(istype(I,typepath))
if (feedback)
to_chat(user, "You collect \the [I].")
if(feedback)
to_chat(user, SPAN_NOTICE("You collect \the [I]."))
I.forceMove(src)
wrapped = I
update_icon()
return 1
if (feedback)
to_chat(user, "<span class='danger'>Your gripper cannot hold \the [I].</span>")
return 0
if (feedback)
to_chat(user, "<span class='danger'>Your gripper is already holding \the [wrapped].</span>")
return 0
return TRUE
if(feedback)
to_chat(user, SPAN_WARNING("Your gripper cannot hold \the [I]."))
return FALSE
if(feedback)
to_chat(user, SPAN_WARNING("Your gripper is already holding \the [wrapped]."))
return FALSE
/obj/item/gripper/update_icon()
underlays.Cut()
if (wrapped && wrapped.icon)
if(wrapped && wrapped.icon)
var/mutable_appearance/MA = new(wrapped)
MA.layer = FLOAT_LAYER
MA.pixel_y = -8
underlays += MA
/obj/item/gripper/attack_self(mob/user as mob)
/obj/item/gripper/attack_self(mob/user)
if(wrapped)
.=wrapped.attack_self(user)
. = wrapped.attack_self(user)
update_icon()
return
return ..()
/obj/item/gripper/AltClick(mob/user as mob)
/obj/item/gripper/AltClick(mob/user)
if(wrapped)
.=wrapped.AltClick(user)
. = wrapped.AltClick(user)
update_icon()
return ..()
/obj/item/gripper/verb/drop_item()
set name = "Drop Item"
set desc = "Release an item from your magnetic gripper."
set category = "Robot Commands"
@@ -106,79 +98,64 @@
drop(get_turf(src))
/obj/item/gripper/proc/drop(var/atom/target)
if(wrapped && wrapped.loc == src)
if(wrapped?.loc == src)
wrapped.forceMove(target)
wrapped = null
update_icon()
return 1
return TRUE
/obj/item/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack().
/obj/item/gripper/attack(mob/living/carbon/M, mob/living/carbon/user)
if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack().
force_holder = wrapped.force
wrapped.force = 0.0
wrapped.attack(M,user)
if(QDELETED(wrapped))
wrapped = null
return 1
else// mob interactions
switch (user.a_intent)
if ("help")
user.visible_message("[user] [pick("boops", "squeezes", "pokes", "prods", "strokes", "bonks")] [M] with the [src]")
if ("harm")
M.attack_generic(user,user.mob_size,"crushed")//about 16 dmg for a cyborg
return TRUE
else // mob interactions
switch(user.a_intent)
if("help")
user.visible_message("\The [user] [pick("boops", "squeezes", "pokes", "prods", "strokes", "bonks")] \the [M] with \the [src]")
if("harm")
M.attack_generic(user, user.mob_size, "crushed")//about 16 dmg for a cyborg
//Attack generic does a visible message so we dont need one here
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN*3)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 3)
playsound(user, 'sound/effects/attackblob.ogg', 60, 1)
//Slow,powerful attack for borgs. No spamclicking
return 0
return FALSE
/obj/item/gripper/attackby(var/obj/item/O as obj, var/mob/user as mob)
if (wrapped)
/obj/item/gripper/attackby(obj/item/O, mob/user)
if(wrapped)
var/resolved = wrapped.attackby(O,user)
if(!resolved && wrapped && O)
O.afterattack(wrapped,user,1)//We pass along things targeting the gripper, to objects inside the gripper. So that we can draw chemicals from held beakers for instance
O.afterattack(wrapped, user ,1)//We pass along things targeting the gripper, to objects inside the gripper. So that we can draw chemicals from held beakers for instance
return
/obj/item/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params)
if(!proximity)
return // This will prevent them using guns at range but adminbuse can add them directly to modules, so eh.
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
if(!wrapped)
for(var/obj/item/thing in src.contents)
wrapped = thing
break
if(wrapped) //Already have an item.
return//This is handled in /mob/living/silicon/robot/GripperClickOn
else if (istype(target, /obj/item/storage) && !istype(target, /obj/item/storage/pill_bottle) && !istype(target, /obj/item/storage/secure))
for (var/obj/item/C in target.contents)
if (grip_item(C, user, 0))
to_chat(user, "You grab the [C] from inside the [target.name].")
return //This is handled in /mob/living/silicon/robot/GripperClickOn
else if(istype(target, /obj/item/storage) && !istype(target, /obj/item/storage/pill_bottle) && !istype(target, /obj/item/storage/secure))
for(var/obj/item/C in target.contents)
if(grip_item(C, user, 0))
to_chat(user, SPAN_NOTICE("You grab \the [C] from inside \the [target.name]."))
return
to_chat(user, "There is nothing inside the box that your gripper can collect")
to_chat(user, SPAN_NOTICE("There is nothing inside the box that your gripper can collect."))
return
else if(istype(target,/obj/item)) //Check that we're not pocketing a mob.
else if(istype(target, /obj/item)) //Check that we're not pocketing a mob.
//...and that the item is not in a container.
if(!isturf(target.loc))
return
grip_item(target, user)
else if (!justdropped)
else if (!just_dropped)
target.attack_ai(user)
justdropped = 0
just_dropped = FALSE
/*
//Definitions of gripper subtypes
@@ -260,9 +237,6 @@
/obj/item/reagent_containers/food/drinks/medcup
)
/obj/item/gripper/service //Used to handle food, drinks, and seeds.
name = "service gripper"
icon_state = "gripper"
@@ -280,7 +254,7 @@
/obj/item/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item
/obj/item/gripper/no_use/attack_self(mob/user as mob)
/obj/item/gripper/no_use/attack_self(mob/user)
return
/obj/item/gripper/no_use/loader //This is used to disallow building with metal.
+20 -21
View File
@@ -7,43 +7,42 @@
laws_sanity_check()
var/who
if (everyone)
who = world
if(everyone)
who = world // why god
else
who = src
if(lawupdate)
if (connected_ai)
if(law_update)
if(connected_ai)
if(connected_ai.stat || connected_ai.control_disabled)
to_chat(src, "<b>AI signal lost, unable to sync laws.</b>")
to_chat(src, SPAN_WARNING("<b>AI signal lost, unable to sync laws.</b>"))
else
lawsync()
photosync()
to_chat(src, "<b>Laws synced with AI, be sure to note any changes.</b>")
to_chat(src, SPAN_NOTICE("<b>Laws synced with AI, be sure to note any changes.</b>"))
// TODO: Update to new antagonist system.
if(mind && mind.special_role == "traitor" && mind.original == src)
to_chat(src, "<b>Remember, your AI does NOT share or know about your law 0.</b>")
to_chat(src, SPAN_WARNING("<b>Remember, your AI does NOT share or know about your law 0.</b>"))
else
to_chat(src, "<b>No AI selected to sync laws with, disabling lawsync protocol.</b>")
lawupdate = 0
to_chat(src, SPAN_WARNING("<b>No AI selected to sync laws with, disabling lawsync protocol.</b>"))
law_update = FALSE
to_chat(who, "<b>Obey these laws:</b>")
to_chat(who, SPAN_WARNING("<b>Obey these laws:</b>"))
laws.show_laws(who)
// TODO: Update to new antagonist system.
if (mind && (mind.special_role == "traitor" && mind.original == src) && connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is technically your master, but your objective comes first.</b>")
else if (connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is your master, other AIs can be ignored.</b>")
else if (emagged)
to_chat(who, "<b>Remember, you are not required to listen to the AI.</b>")
if(mind && (mind.special_role == "traitor" && mind.original == src) && connected_ai)
to_chat(who, SPAN_NOTICE("<b>Remember, [connected_ai.name] is technically your master, but your objective comes first.</b>"))
else if(connected_ai)
to_chat(who, SPAN_NOTICE("<b>Remember, [connected_ai.name] is your master, other AIs can be ignored.</b>"))
else if(emagged)
to_chat(who, SPAN_NOTICE("<b>Remember, you are not required to listen to the AI.</b>"))
else
to_chat(who, "<b>Remember, you are not bound to any AI, you are not required to listen to them.</b>")
to_chat(who, SPAN_NOTICE("<b>Remember, you are not bound to any AI, you are not required to listen to them.</b>"))
/mob/living/silicon/robot/lawsync()
laws_sanity_check()
var/datum/ai_laws/master = connected_ai && lawupdate ? connected_ai.laws : null
if (master)
var/datum/ai_laws/master = connected_ai && law_update ? connected_ai.laws : null
if(master)
master.sync(src)
..()
return
@@ -51,4 +50,4 @@
/mob/living/silicon/robot/proc/robot_checklaws()
set category = "Robot Commands"
set name = "State Laws"
subsystem_law_manager()
subsystem_law_manager()
+168 -178
View File
@@ -1,10 +1,10 @@
/mob/living/silicon/robot/Life()
set background = BACKGROUND_ENABLED
if (src.transforming)
if(transforming)
return
src.blinded = null
blinded = null
//Status updates, death etc.
clamp_values()
@@ -14,7 +14,7 @@
if(client)
handle_regular_hud_updates()
update_items()
if (src.stat != DEAD) //still using power
if(stat != DEAD) //still using power
use_power()
process_killswitch()
process_locks()
@@ -23,11 +23,8 @@
update_canmove()
/mob/living/silicon/robot/proc/clamp_values()
// SetStunned(min(stunned, 30))
SetParalysis(min(paralysis, 30))
// SetWeakened(min(weakened, 20))
sleeping = 0
sleeping = FALSE
adjustBruteLoss(0)
adjustToxLoss(0)
adjustOxyLoss(0)
@@ -39,310 +36,303 @@
var/datum/robot_component/C = components[V]
C.update_power_state()
if ( cell && is_component_functioning("power cell") && src.cell.charge > 0 )
if(src.module_state_1)
if(cell?.charge > 0 && is_component_functioning("power cell"))
if(module_state_1)
cell_use_power(50) // 50W load for every enabled tool TODO: tool-specific loads
if(src.module_state_2)
if(module_state_2)
cell_use_power(50)
if(src.module_state_3)
if(module_state_3)
cell_use_power(50)
if(lights_on)
if(intenselight)
if(intense_light)
cell_use_power(100) // Upgraded light. Double intensity, much larger power usage.
else
cell_use_power(30) // 30W light. Normal lights would use ~15W, but increased for balance reasons.
src.has_power = 1
has_power = TRUE
else
if (src.has_power)
to_chat(src, "<span class='warning'>You are now running on emergency backup power.</span>")
src.has_power = 0
if(has_power)
to_chat(src, SPAN_WARNING("You are now running on emergency backup power."))
has_power = 0
if(lights_on) // Light is on but there is no power!
lights_on = 0
set_light(0)
/mob/living/silicon/robot/handle_regular_status_updates()
if(src.camera && !scrambledcodes)
if(src.stat == 2 || wires.IsIndexCut(BORG_WIRE_CAMERA))
src.camera.set_status(0)
if(camera && !scrambled_codes)
if(stat == DEAD || wires.IsIndexCut(BORG_WIRE_CAMERA))
camera.set_status(0)
else
src.camera.set_status(1)
camera.set_status(1)
updatehealth()
if(src.sleeping)
if(sleeping)
Paralyse(3)
src.sleeping--
sleeping--
if(src.resting)
if(resting)
Weaken(5)
if(health < config.health_threshold_dead && src.stat != 2) //die only once
if(health < config.health_threshold_dead && stat != DEAD) //die only once
death()
if (src.stat != 2) //Alive.
if (src.paralysis || src.stunned || src.weakened || !src.has_power) //Stunned etc.
src.stat = 1
if (src.stunned > 0)
if(stat != DEAD)
if(paralysis || stunned || weakened || !has_power) //Stunned etc.
stat = UNCONSCIOUS
if(stunned > 0)
AdjustStunned(-1)
if (src.weakened > 0)
if(weakened > 0)
AdjustWeakened(-1)
if (src.paralysis > 0)
if(paralysis > 0)
AdjustParalysis(-1)
src.blinded = 1
blinded = TRUE
else
src.blinded = 0
blinded = FALSE
else //Not stunned.
src.stat = 0
else //Not stunned.
stat = CONSCIOUS
else //Dead.
src.blinded = 1
src.stat = 2
blinded = TRUE
stat = DEAD
if (src.stuttering) src.stuttering--
if(stuttering)
stuttering--
if (src.eye_blind)
src.eye_blind--
src.blinded = 1
if(eye_blind)
eye_blind--
blinded = 1
if (src.ear_deaf > 0) src.ear_deaf--
if (src.ear_damage < 25)
src.ear_damage -= 0.05
src.ear_damage = max(src.ear_damage, 0)
if(ear_deaf > 0)
ear_deaf--
if(ear_damage < 25)
ear_damage -= 0.05
ear_damage = max(ear_damage, 0)
//src.density = !( src.lying )
if((sdisabilities & BLIND))
blinded = TRUE
if((sdisabilities & DEAF))
ear_deaf = TRUE
if ((src.sdisabilities & BLIND))
src.blinded = 1
if ((src.sdisabilities & DEAF))
src.ear_deaf = 1
if(eye_blurry > 0)
eye_blurry--
eye_blurry = max(0, eye_blurry)
if (src.eye_blurry > 0)
src.eye_blurry--
src.eye_blurry = max(0, src.eye_blurry)
if (src.druggy > 0)
src.druggy--
src.druggy = max(0, src.druggy)
if(druggy > 0)
druggy--
druggy = max(0, druggy)
//update the state of modules and components here
if (src.stat != 0)
if(stat != CONSCIOUS)
uneq_all()
if(radio)
if(common_radio)
if(!is_component_functioning("radio"))
radio.on = 0
common_radio.on = FALSE
else
radio.on = 1
common_radio.on = TRUE
if(is_component_functioning("camera"))
src.blinded = 0
blinded = FALSE
else
src.blinded = 1
blinded = TRUE
return 1
return TRUE
/mob/living/silicon/robot/handle_regular_hud_updates()
..()
if (src.stat == 2 || (XRAY in mutations) || (src.sight_mode & BORGXRAY))
if(stat == DEAD || (XRAY in mutations) || (sight_mode & BORGXRAY))
sight |= (SEE_TURFS | SEE_MOBS | SEE_OBJS)
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_MINIMUM
else if ((src.sight_mode & BORGMESON) && (src.sight_mode & BORGTHERM))
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else if((sight_mode & BORGMESON) && (sight_mode & BORGTHERM))
sight |= (SEE_TURFS | SEE_MOBS)
src.see_in_dark = 8
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGMESON)
src.sight |= SEE_TURFS
src.see_in_dark = 8
else if(sight_mode & BORGMESON)
sight |= SEE_TURFS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGMATERIAL)
src.sight |= SEE_OBJS
src.see_in_dark = 8
else if(sight_mode & BORGMATERIAL)
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGTHERM)
src.sight |= SEE_MOBS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (src.stat != 2)
else if(sight_mode & BORGTHERM)
sight |= SEE_MOBS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if(stat != 2)
sight &= ~(SEE_TURFS | SEE_MOBS | SEE_OBJS)
src.see_in_dark = 8 // see_in_dark means you can FAINTLY see in the dark, humans have a range of 3 or so, tajaran have it at 8
src.see_invisible = SEE_INVISIBLE_LIVING // This is normal vision (25), setting it lower for normal vision means you don't "see" things like darkness since darkness
see_in_dark = 8 // see_in_dark means you can FAINTLY see in the dark, humans have a range of 3 or so, tajaran have it at 8
see_invisible = SEE_INVISIBLE_LIVING // This is normal vision (25), setting it lower for normal vision means you don't "see" things like darkness since darkness
// has a "invisible" value of 15
var/obj/item/borg/sight/hud/hud = (locate(/obj/item/borg/sight/hud) in src)
if(hud && hud.hud)
if(hud?.hud)
hud.hud.process_hud(src)
else
switch(src.sensor_mode)
if (SEC_HUD)
process_sec_hud(src,0)
if (MED_HUD)
process_med_hud(src,0)
switch(sensor_mode)
if(SEC_HUD)
process_sec_hud(src, FALSE)
if(MED_HUD)
process_med_hud(src, FALSE)
if (src.healths)
if (src.stat != 2)
if(istype(src,/mob/living/silicon/robot/drone))
if(healths)
if(stat != DEAD)
if(istype(src, /mob/living/silicon/robot/drone))
switch(health)
if(35 to INFINITY)
src.healths.icon_state = "health0"
healths.icon_state = "health0"
if(25 to 34)
src.healths.icon_state = "health1"
healths.icon_state = "health1"
if(15 to 24)
src.healths.icon_state = "health2"
healths.icon_state = "health2"
if(5 to 14)
src.healths.icon_state = "health3"
healths.icon_state = "health3"
if(0 to 4)
src.healths.icon_state = "health4"
healths.icon_state = "health4"
if(-35 to 0)
src.healths.icon_state = "health5"
healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
healths.icon_state = "health6"
else
switch(health)
if(200 to INFINITY)
src.healths.icon_state = "health0"
healths.icon_state = "health0"
if(150 to 200)
src.healths.icon_state = "health1"
healths.icon_state = "health1"
if(100 to 150)
src.healths.icon_state = "health2"
healths.icon_state = "health2"
if(50 to 100)
src.healths.icon_state = "health3"
healths.icon_state = "health3"
if(0 to 50)
src.healths.icon_state = "health4"
healths.icon_state = "health4"
if(config.health_threshold_dead to 0)
src.healths.icon_state = "health5"
healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
healths.icon_state = "health6"
else
src.healths.icon_state = "health7"
healths.icon_state = "health7"
if (src.syndicate && src.client)
if(syndicate && client)
for(var/datum/mind/tra in traitors.current_antagonists)
if(tra.current)
// TODO: Update to new antagonist system.
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
src.client.images += I
src.disconnect_from_ai()
if(src.mind)
client.images += I
disconnect_from_ai()
if(mind)
// TODO: Update to new antagonist system.
if(!src.mind.special_role)
src.mind.special_role = "traitor"
traitors.current_antagonists |= src.mind
if(!mind.special_role)
mind.special_role = "traitor"
traitors.current_antagonists |= mind
if (src.cells)
if (src.cell)
var/cellcharge = src.cell.charge/src.cell.maxcharge
if(cells)
if(cell)
var/cellcharge = cell.charge / cell.maxcharge
switch(cellcharge)
if(0.75 to INFINITY)
src.cells.icon_state = "charge4"
cells.icon_state = "charge4"
if(0.5 to 0.75)
src.cells.icon_state = "charge3"
cells.icon_state = "charge3"
if(0.25 to 0.5)
src.cells.icon_state = "charge2"
cells.icon_state = "charge2"
if(0 to 0.25)
src.cells.icon_state = "charge1"
cells.icon_state = "charge1"
else
src.cells.icon_state = "charge0"
cells.icon_state = "charge0"
else
src.cells.icon_state = "charge-empty"
cells.icon_state = "charge-empty"
if(bodytemp)
switch(src.bodytemperature) //310.055 optimal body temp
switch(bodytemperature) //310.055 optimal body temp
if(335 to INFINITY)
src.bodytemp.icon_state = "temp2"
bodytemp.icon_state = "temp2"
if(320 to 335)
src.bodytemp.icon_state = "temp1"
bodytemp.icon_state = "temp1"
if(300 to 320)
src.bodytemp.icon_state = "temp0"
bodytemp.icon_state = "temp0"
if(260 to 300)
src.bodytemp.icon_state = "temp-1"
bodytemp.icon_state = "temp-1"
else
src.bodytemp.icon_state = "temp-2"
bodytemp.icon_state = "temp-2"
//Oxygen and fire does nothing yet!!
// if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
// if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 0]"
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((src.blind && src.stat != 2))
if(src.blinded)
src.blind.invisibility = 0
if((blind && stat != DEAD))
if(blinded)
blind.invisibility = 0
else
src.blind.invisibility = 101
if (src.disabilities & NEARSIGHTED)
src.client.screen += global_hud.vimpaired
blind.invisibility = 101
if(disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if(eye_blurry)
client.screen += global_hud.blurry
if(druggy)
client.screen += global_hud.druggy
if (src.eye_blurry)
src.client.screen += global_hud.blurry
if (src.druggy)
src.client.screen += global_hud.druggy
if (src.stat != 2)
if (src.machine)
if (src.machine.check_eye(src) < 0)
src.reset_view(null)
if(stat != DEAD)
if(machine)
if(machine.check_eye(src) < 0)
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
return 1
return TRUE
/mob/living/silicon/robot/proc/update_items()
if (src.client)
src.client.screen -= src.contents
for(var/obj/I in src.contents)
if(I && !(istype(I,/obj/item/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi)))
src.client.screen += I
if(src.module_state_1)
src.module_state_1:screen_loc = ui_inv1
if(src.module_state_2)
src.module_state_2:screen_loc = ui_inv2
if(src.module_state_3)
src.module_state_3:screen_loc = ui_inv3
if(client)
client.screen -= contents
for(var/obj/I in contents)
if(I && !(istype(I, /obj/item/cell) || istype(I, /obj/item/device/radio) || istype(I, /obj/machinery/camera) || istype(I, /obj/item/device/mmi)))
client.screen += I
if(module_state_1)
module_state_1:screen_loc = ui_inv1
if(module_state_2)
module_state_2:screen_loc = ui_inv2
if(module_state_3)
module_state_3:screen_loc = ui_inv3
updateicon()
/mob/living/silicon/robot/proc/process_killswitch()
if(killswitch)
killswitch_time --
if(killswitch_time <= 0)
if(src.client)
to_chat(src, "<span class='danger'>Killswitch Activated</span>")
killswitch = 0
if(client)
to_chat(src, SPAN_DANGER("Killswitch Activated!"))
killswitch = FALSE
spawn(5)
gib()
/mob/living/silicon/robot/proc/process_locks()
if(weapon_lock)
uneq_all()
weaponlock_time --
if(weaponlock_time <= 0)
if(src.client)
to_chat(src, "<span class='danger'>Weapon Lock Timed Out!</span>")
weapon_lock = 0
weaponlock_time = 120
weapon_lock_time --
if(weapon_lock_time <= 0)
if(client)
to_chat(src, SPAN_WARNING("Weapon Lock Timed Out!"))
weapon_lock = FALSE
weapon_lock_time = 120
/mob/living/silicon/robot/update_canmove()
if(paralysis || stunned || weakened || buckled || lockcharge || !is_component_functioning("actuator")) canmove = 0
else canmove = 1
if(paralysis || stunned || weakened || buckled || lock_charge || !is_component_functioning("actuator"))
canmove = FALSE
else
canmove = TRUE
return canmove
/mob/living/silicon/robot/proc/process_level_restrictions()
//Abort if they should not get blown
if (lockcharge || scrambledcodes || emagged)
if(lock_charge || scrambled_codes || emagged)
return
//Check if they are on a player level -> abort
var/turf/T = get_turf(src)
if (!T || isStationLevel(T.z))
if(!T || isStationLevel(T.z))
return
//If they are on centcom -> abort
if (istype(get_area(src), /area/centcom) || istype(get_area(src), /area/shuttle/escape) || istype(get_area(src), /area/shuttle/arrival))
if(istype(get_area(src), /area/centcom) || istype(get_area(src), /area/shuttle/escape) || istype(get_area(src), /area/shuttle/arrival))
return
self_destruct(TRUE)
@@ -353,4 +343,4 @@
/mob/living/silicon/robot/fire_act()
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
IgniteMob()
IgniteMob()
@@ -3,8 +3,9 @@
regenerate_icons()
show_laws(0)
// the fuck
winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")
// Forces synths to select an icon relevant to their module
if(module && !icon_selected)
choose_icon(icon_selection_tries, module_sprites)
choose_icon(icon_selection_tries, module_sprites)
@@ -1,20 +1,20 @@
/mob/living/silicon/robot/proc/photosync()
var/obj/item/device/camera/siliconcam/master_cam = connected_ai ? connected_ai.aiCamera : null
if (!master_cam)
var/obj/item/device/camera/siliconcam/master_cam = connected_ai ? connected_ai.ai_camera : null
if(!master_cam)
return
var/synced = 0
var/synced = FALSE
// Sync borg images to the master AI.
// We don't care about syncing the other way around
for(var/obj/item/photo/borg_photo in aiCamera.aipictures)
var/copied = 0
for(var/obj/item/photo/borg_photo in ai_camera.aipictures)
var/copied = FALSE
for(var/obj/item/photo/ai_photo in master_cam.aipictures)
if(borg_photo.id == ai_photo.id)
copied = 1
copied = TRUE
break
if(!copied)
master_cam.injectaialbum(borg_photo.copy(1), " (synced from [name])")
synced = 1
synced = TRUE
if(synced)
to_chat(src, "<span class='notice'>Images synced with AI. Local images will be retained in the case of loss of connection with the AI.</span>")
to_chat(src, SPAN_NOTICE("Images synced with AI. Local images will be retained in the case of loss of connection with the AI."))
@@ -1,33 +1,28 @@
//cyborgs presets, mostly used for events/admin bus
/mob/living/silicon/robot/combat
modtype = "Combat"
mod_type = "Combat"
spawn_module = /obj/item/robot_module/combat
cell_type = /obj/item/cell/super
/mob/living/silicon/robot/combat/ert
scrambledcodes = 1
lawupdate = 0
lawpreset = /datum/ai_laws/nanotrasen_aggressive
idcard_type = /obj/item/card/id/ert
scrambled_codes = TRUE
law_update = FALSE
law_preset = /datum/ai_laws/nanotrasen_aggressive
id_card_type = /obj/item/card/id/ert
key_type = /obj/item/device/encryptionkey/ert
/mob/living/silicon/robot/combat/ert/init()
..()
if(!jetpack)
jetpack = new /obj/item/tank/jetpack/carbondioxide/synthetic(src)
has_jetpack = TRUE
/mob/living/silicon/robot/scrambled //should not stand linked to the station or the ai
scrambledcodes = 1
lawupdate = 0
scrambled_codes = TRUE
law_update = FALSE
/mob/living/silicon/robot/bluespace
modtype = "Bluespace"
mod_type = "Bluespace"
spawn_module = /obj/item/robot_module/bluespace
cell_type = /obj/item/cell/infinite
overclocked = 1
lawupdate = 0
scrambledcodes = 1
overclocked = TRUE
law_update = FALSE
scrambled_codes = TRUE
status_flags = GODMODE
/mob/living/silicon/robot/bluespace/verb/bstwalk()
@@ -57,7 +52,7 @@
set desc = "Activate bluespace to leave and return to your original mob (if you have one)."
set category = "BST"
src.custom_emote(1,"politely beeps as its lights start to flash.")
src.custom_emote(1, "politely beeps as its lights start to flash.")
spark(src, 5, alldirs)
addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, src), 10, TIMER_CLIENT_TIME)
animate(src, alpha = 0, time = 9, easing = QUAD_EASING)
@@ -79,4 +74,4 @@
set category = "BST"
status_flags ^= GODMODE
to_chat(src, span("notice", "God mode is now [status_flags & GODMODE ? "enabled" : "disabled"]"))
to_chat(src, span("notice", "God mode is now [status_flags & GODMODE ? "enabled" : "disabled"]"))
File diff suppressed because it is too large Load Diff
@@ -11,9 +11,9 @@
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed)
amount += Clamp(C.brute_damage,0,C.max_damage)
amount += Clamp(C.brute_damage, 0, C.max_damage)
else if(C.installed == -1)
amount += C.max_damage/2
amount += C.max_damage / 2
return amount
/mob/living/silicon/robot/getFireLoss()
@@ -21,9 +21,9 @@
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed)
amount += Clamp(C.electronics_damage,0,C.max_damage)
amount += Clamp(C.electronics_damage, 0, C.max_damage)
else if(C.installed == -1)
amount += C.max_damage/2
amount += C.max_damage / 2
return amount
/mob/living/silicon/robot/adjustBruteLoss(var/amount)
@@ -55,54 +55,55 @@
return rval
/mob/living/silicon/robot/proc/get_armour()
if(!components.len) return 0
if(!length(components))
return FALSE
var/datum/robot_component/C = components["armour"]
if(C && C.installed == 1)
if(C?.installed == TRUE)
return C
return 0
return FALSE
/mob/living/silicon/robot/heal_organ_damage(var/brute, var/burn)
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
if(!parts.len) return
var/list/datum/robot_component/parts = get_damaged_components(brute, burn)
if(!length(parts))
return
var/datum/robot_component/picked = pick(parts)
picked.heal_damage(brute,burn)
picked.heal_damage(brute, burn)
/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/edge = 0, var/emp = 0)
var/list/components = get_damageable_components()
if(!components.len)
if(!length(components))
return
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
if(module_active && istype(module_active, /obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
var/cost = (absorb_brute+absorb_burn)*100
var/absorb_brute = brute * shield.shield_level
var/absorb_burn = burn * shield.shield_level
var/cost = (absorb_brute + absorb_burn) * 100
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
to_chat(src, "<span class='warning'>Your shield has overloaded!</span>")
to_chat(src, SPAN_WARNING("Your shield has overloaded!"))
else
brute -= absorb_brute
burn -= absorb_burn
to_chat(src, "<span class='warning'>Your shield absorbs some of the impact!</span>")
to_chat(src, SPAN_WARNING("Your shield absorbs some of the impact!"))
if(!emp)
var/datum/robot_component/armor/A = get_armour()
if(A)
A.take_damage(brute,burn,sharp,edge)
A.take_damage(brute, burn, sharp, edge)
return
var/datum/robot_component/C = pick(components)
C.take_damage(brute,burn,sharp,edge)
C.take_damage(brute, burn, sharp, edge)
/mob/living/silicon/robot/heal_overall_damage(var/brute, var/burn)
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
while(parts.len && (brute>0 || burn>0) )
while(length(parts) && (brute > 0 || burn > 0))
var/datum/robot_component/picked = pick(parts)
var/brute_was = picked.brute_damage
@@ -116,32 +117,33 @@
parts -= picked
/mob/living/silicon/robot/take_overall_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/used_weapon = null)
if(status_flags & GODMODE) return //godmode
var/list/datum/robot_component/parts = get_damageable_components()
if(status_flags & GODMODE)
return
var/list/datum/robot_component/parts = get_damageable_components()
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute*shield.shield_level
var/absorb_burn = burn*shield.shield_level
var/cost = (absorb_brute+absorb_burn)*100
var/absorb_brute = brute * shield.shield_level
var/absorb_burn = burn * shield.shield_level
var/cost = (absorb_brute + absorb_burn) * 100
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
to_chat(src, "<span class='warning'>Your shield has overloaded!</span>")
to_chat(src, SPAN_WARNING("Your shield has overloaded!"))
else
brute -= absorb_brute
burn -= absorb_burn
to_chat(src, "<span class='warning'>Your shield absorbs some of the impact!</span>")
to_chat(src, SPAN_WARNING("Your shield absorbs some of the impact!"))
var/datum/robot_component/armor/A = get_armour()
if(A)
A.take_damage(brute,burn,sharp)
A.take_damage(brute, burn, sharp)
return
while(parts.len && (brute>0 || burn>0) )
while(length(parts) && (brute > 0 || burn > 0))
var/datum/robot_component/picked = pick(parts)
var/brute_was = picked.brute_damage
@@ -149,28 +151,28 @@
picked.take_damage(brute,burn)
brute -= (picked.brute_damage - brute_was)
burn -= (picked.electronics_damage - burn_was)
brute -= (picked.brute_damage - brute_was)
burn -= (picked.electronics_damage - burn_was)
parts -= picked
/mob/living/silicon/robot/emp_act(severity)
var/datum/robot_component/surge/C = components["surge"]
if(C && C.installed)
if(C?.installed)
if(C.surge_left >= 1)
playsound(src.loc, 'sound/magic/LightningShock.ogg', 25, 1)
C.surge_left -= 1
visible_message("<span class='warning'>[src] was not affected by EMP pulse.</span>", "<span class='warning'>Warning: Power surge detected, source - EMP. Surge prevention module re-routed surge to prevent damage to vital electronics.</span>")
visible_message(SPAN_WARNING("\The [src] was not affected by the EMP pulse!"), SPAN_WARNING("Warning: Power surge detected, source - EMP. Surge prevention module re-routed surge to prevent damage to vital electronics."))
if(C.surge_left)
to_chat(src, "<span class='notice'>Surge module has [C.surge_left] preventions left!</span>")
to_chat(src, SPAN_NOTICE("Surge protection module can only withstand [C.surge_left] more EMPs!"))
else
C.destroy()
to_chat(src, "<span class='danger'>Module is entirely fried, replacement is recommended.</span>")
to_chat(src, SPAN_WARNING("Surge protection module fried! Replacement is recommended."))
return
else if(C.surge_left == 0.5)
to_chat(src, "<span class='danger'>Warning: Power surge detected, source - EMP, integrated surge prevention module is damaged and was unable to fully protect from EMP. Half of the damage taken. Replacement recommended.</span>")
to_chat(src, SPAN_WARNING("Warning: Power surge detected, source - EMP, integrated surge prevention module is damaged and was unable to fully protect from EMP. Half of the damage taken. Replacement recommended."))
..(2) // borgs only take 1-2 EMP
return
else
to_chat(src, "<span class='notice'>Warning: Power surge detected, source - EMP. Surge prevention module is depleted and requires replacement</span>")
to_chat(src, SPAN_WARNING("Warning: Power surge detected, source - EMP. Surge prevention module is depleted and requires replacement!"))
..()
@@ -1,3 +1,5 @@
// Don't look at this file. Absolutely do not. It is brimming with shitcode. Please. Don't. - Geeves
//A portable analyzer, for research borgs. This is better then giving them a gripper which can hold anything and letting them use the normal analyzer.
/obj/item/portable_destructive_analyzer
name = "Portable Destructive Analyzer"
@@ -12,30 +14,30 @@
var/obj/item/loaded_item //What is currently inside the analyzer.
/obj/item/portable_destructive_analyzer/New()
..()
/obj/item/portable_destructive_analyzer/Initialize()
. = ..()
files = new /datum/research/techonly(src) //Setup the research data holder.
/obj/item/portable_destructive_analyzer/attack_self(user as mob)
/obj/item/portable_destructive_analyzer/attack_self(mob/user)
var/response = alert(user, "Analyzing the item inside will *DESTROY* the item for good.\n\
Syncing to the research server will send the data that is stored inside to research.\n\
Ejecting will place the loaded item onto the floor.",
"What would you like to do?", "Analyze", "Sync", "Eject")
if(response == "Analyze")
if(loaded_item)
var/confirm = alert(user, "This will destroy the item inside forever. Are you sure?","Confirm Analyze","Yes","No")
var/confirm = alert(user, "This will destroy the item inside forever. Are you sure?", "Confirm Analyze", "Yes", "No")
if(confirm == "Yes") //This is pretty copypasta-y
to_chat(user, "You activate the analyzer's microlaser, analyzing \the [loaded_item] and breaking it down.")
to_chat(user, SPAN_NOTICE("You activate the analyzer's microlaser, analyzing \the [loaded_item] and breaking it down."))
flick("portable_analyzer_scan", src)
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
for(var/T in loaded_item.origin_tech)
files.UpdateTech(T, loaded_item.origin_tech[T])
to_chat(user, "\The [loaded_item] had level [loaded_item.origin_tech[T]] in [CallTechName(T)].")
to_chat(user, SPAN_NOTICE("\The [loaded_item] had level [loaded_item.origin_tech[T]] in [CallTechName(T)]."))
loaded_item = null
for(var/obj/I in contents)
for(var/mob/M in I.contents)
M.death()
if(istype(I,/obj/item/stack/material))//Only deconstructs one sheet at a time instead of the entire stack
if(istype(I,/obj/item/stack/material)) //Only deconstructs one sheet at a time instead of the entire stack
var/obj/item/stack/material/S = I
if(S.get_amount() > 1)
S.use(1)
@@ -51,22 +53,22 @@
else
return
else
to_chat(user, "The [src] is empty. Put something inside it first.")
to_chat(user, SPAN_WARNING("\The [src] is empty. Put something inside it first."))
if(response == "Sync")
var/success = 0
var/success = FALSE
for(var/obj/machinery/r_n_d/server/S in SSmachinery.all_machines)
for(var/datum/tech/T in files.known_tech) //Uploading
S.files.AddTech2Known(T)
for(var/datum/tech/T in S.files.known_tech) //Downloading
files.AddTech2Known(T)
success = 1
success = TRUE
files.RefreshResearch()
if(success)
to_chat(user, "You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch.")
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
to_chat(user, SPAN_NOTICE("You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch.")) // fucking nerds
playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, TRUE)
else
to_chat(user, "Reserch server ping response timed out. Unable to connect. Please contact the system administrator.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 1)
to_chat(user, SPAN_WARNING("Research server ping response timed out. Unable to connect. Please contact the system administrator."))
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
if(response == "Eject")
if(loaded_item)
loaded_item.forceMove(get_turf(src))
@@ -74,34 +76,29 @@
icon_state = initial(icon_state)
loaded_item = null
else
to_chat(user, "The [src] is already empty.")
to_chat(user, SPAN_WARNING("\The [src] is already empty."))
/obj/item/portable_destructive_analyzer/afterattack(var/atom/target, var/mob/living/user, proximity)
if(!target)
if(!target || !proximity || !isturf(target.loc))
return
if(!proximity)
return
if(!isturf(target.loc)) // Don't load up stuff if it's inside a container or mob!
if(loaded_item)
to_chat(user, SPAN_WARNING("Your [src] already has something inside. Analyze or eject it first."))
return
if(istype(target,/obj/item))
if(loaded_item)
to_chat(user, "Your [src] already has something inside. Analyze or eject it first.")
return
var/obj/item/I = target
if (I.anchored)
if(I.anchored)
to_chat(user, span("notice", "\The [I] is anchored in place."))
return
if(!I.origin_tech)
to_chat(user, "<span class='notice'>This doesn't seem to have a tech origin.</span>")
to_chat(user, SPAN_NOTICE("This doesn't seem to have a tech origin."))
return
if(I.origin_tech.len == 0)
to_chat(user, "<span class='notice'>You cannot deconstruct this item.</span>")
if(!length(I.origin_tech))
to_chat(user, SPAN_NOTICE("You cannot deconstruct this item."))
return
I.forceMove(src)
loaded_item = I
for(var/mob/M in viewers())
M.show_message(text("<span class='notice'>[user] adds the [I] to the [src].</span>"), 1)
visible_message(SPAN_NOTICE("\The [user] scoops \the [I] into \the [src]."))
desc = initial(desc) + "<br>It is holding \the [loaded_item]."
flick("portable_analyzer_load", src)
icon_state = "portable_analyzer_full"
@@ -122,9 +119,7 @@
hitsound = "swing_hit"
/obj/item/robot_harvester/afterattack(var/atom/target, var/mob/living/user, proximity)
if(!target)
return
if(!proximity)
if(!target || !proximity)
return
if(istype(target,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/T = target
@@ -133,7 +128,7 @@
else if(T.dead) //It's probably dead otherwise.
T.remove_dead(user)
else
to_chat(user, "Harvesting \a [target] is not the purpose of this tool. The [src] is for plants being grown.")
to_chat(user, SPAN_WARNING("ERROR: Harvesting \a [target] is not the purpose of this tool. \The [src] is for plants being grown."))
// A special tray for the service droid. Allow droid to pick up and drop items as if they were using the tray normally
// Click on table to unload, click on item to load. Alt+click to load everything on tile
@@ -142,34 +137,28 @@
name = "RoboTray"
desc = "An autoloading tray specialized for carrying refreshments."
/obj/item/tray/robotray/afterattack(atom/target, mob/user as mob, proximity)
if (isturf(target) || istype(target,/obj/structure/table) )
/obj/item/tray/robotray/afterattack(atom/target, mob/user, proximity)
if(isturf(target) || istype(target,/obj/structure/table) )
var foundtable = istype(target,/obj/structure/table/)
if ( !foundtable ) //it must be a turf!
if(!foundtable) //it must be a turf!
for(var/obj/structure/table/T in target)
foundtable = 1
foundtable = TRUE
break
var turf/dropspot
if ( !foundtable ) // don't unload things onto walls or other silly places.
dropspot = user.loc
var/turf/dropspot
if(!foundtable) // don't unload things onto walls or other silly places.
dropspot = get_turf(user)
else if ( isturf(target) ) // they clicked on a turf with a table in it
dropspot = target
else // they clicked on a table
dropspot = target.loc
if (foundtable)
dropspot = get_turf(target)
if(foundtable)
unload_at_loc(dropspot, src)
else
spill(user,dropspot)
current_weight = 0
return ..()
// A special pen for service droids. Can be toggled to switch between normal writting mode, and paper rename mode
// Allows service droids to rename paper items.
@@ -178,77 +167,70 @@
name = "Printing Pen"
var/mode = 1
/obj/item/pen/robopen/attack_self(mob/user as mob)
/obj/item/pen/robopen/attack_self(mob/user)
var/choice = input(user, "Would you like to change colour or mode?", "Pen Selector") as null|anything in list("Colour", "Mode")
if(!choice)
return
var/choice = input("Would you like to change colour or mode?") as null|anything in list("Colour","Mode")
if(!choice) return
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
switch(choice)
if("Colour")
var/newcolour = input("Which colour would you like to use?") as null|anything in list("black","blue","red","green","yellow")
if(newcolour) colour = newcolour
var/newcolour = input(user, "Which colour would you like to use?", "Colour Selector") as null|anything in list("black", "blue", "red", "green", "yellow")
if(newcolour)
colour = newcolour
if("Mode")
if (mode == 1)
if(mode == 1)
mode = 2
else
mode = 1
to_chat(user, "Changed printing mode to '[mode == 2 ? "Rename Paper" : "Write Paper"]'")
to_chat(user, SPAN_NOTICE("Changed printing mode to '[mode == 2 ? "Rename Paper" : "Write Paper"]'"))
return
// Copied over from paper's rename verb
// see code\modules\paperwork\paper.dm line 62
/obj/item/pen/robopen/proc/RenamePaper(mob/user as mob,obj/paper as obj)
if ( !user || !paper )
/obj/item/pen/robopen/proc/RenamePaper(var/mob/user, var/obj/paper)
if(!user || !paper)
return
var/n_name = sanitizeSafe(input(user, "What would you like to label the paper?", "Paper Labelling", null) as text, 32)
if ( !user || !paper )
var/n_name = sanitizeSafe(input(user, "What would you like to label the paper?", "Paper Labelling") as text, 32)
if(!user || !paper)
return
//n_name = copytext(n_name, 1, 32)
if(( get_dist(user,paper) <= 1 && user.stat == 0))
if((get_dist(user,paper) <= 1 && !user.stat))
paper.name = "paper[(n_name ? text("- '[n_name]'") : null)]"
add_fingerprint(user)
return
//TODO: Add prewritten forms to dispense when you work out a good way to store the strings.
/obj/item/form_printer
//name = "paperwork printer"
name = "paper dispenser"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper_bin1"
item_state = "sheet-metal"
/obj/item/form_printer/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
/obj/item/form_printer/attack(mob/living/carbon/M, mob/living/carbon/user)
return
/obj/item/form_printer/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if(!target || !flag)
return
if(istype(target,/obj/structure/table))
deploy_paper(get_turf(target))
/obj/item/form_printer/attack_self(mob/user as mob)
/obj/item/form_printer/attack_self(mob/user)
deploy_paper(get_turf(src))
/obj/item/form_printer/proc/deploy_paper(var/turf/T)
T.visible_message("<span class='notice'>\The [src.loc] dispenses a sheet of crisp white paper.</span>")
T.visible_message(SPAN_NOTICE("\The [src.loc] dispenses a sheet of crisp white paper."))
new /obj/item/paper(T)
//Personal shielding for the combat module.
/obj/item/borg/combat/shield
name = "personal shielding"
desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
icon = 'icons/obj/device.dmi'
icon_state = "shield1" //placeholder for now
icon_state = "shield1" //placeholder for now // four fucking years alberyk. FOUR
var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
/obj/item/borg/combat/shield/verb/set_shield_level()
@@ -256,8 +238,8 @@
set category = "Object"
set src in range(0)
var/N = input("How much damage should the shield absorb?") in list("5","10","25","50","75","100")
if (N)
var/N = input(usr, "How much damage should the shield absorb?") in list("5", "10", "25", "50", "75", "100")
if(N)
shield_level = text2num(N)/100
/obj/item/borg/combat/mobility
@@ -280,16 +262,16 @@
var/max_doors = 5
var/mode = 0 // 0 - Walls 1 - Doors
/obj/item/inflatable_dispenser/examine(var/mob/user)
/obj/item/inflatable_dispenser/examine(mob/user)
if(!..(user))
return
to_chat(user, "It has [stored_walls] wall segment\s and [stored_doors] door segment\s stored.")
to_chat(user, "It is set to deploy [mode ? "doors" : "walls"]")
to_chat(user, SPAN_NOTICE("It has [stored_walls] wall segment\s and [stored_doors] door segment\s stored."))
to_chat(user, SPAN_NOTICE("It is set to deploy [mode ? "doors" : "walls"]"))
/obj/item/inflatable_dispenser/attack_self(mob/user)
if(!deploying)
mode = !mode
to_chat(user, "You set \the [src] to deploy [mode ? "doors" : "walls"].")
to_chat(user, SPAN_NOTICE("You set \the [src] to deploy [mode ? "doors" : "walls"]."))
else
to_chat(user, span("warning", "You can't switch modes while deploying a [mode ? "door" : "wall"]!"))
@@ -298,7 +280,7 @@
if(!user)
return
if(!user.Adjacent(A))
to_chat(user, "You can't reach!")
to_chat(user, SPAN_WARNING("You can't reach!"))
return
if(istype(A, /turf))
try_deploy_inflatable(A, user)
@@ -306,21 +288,20 @@
pick_up(A, user)
/obj/item/inflatable_dispenser/proc/try_deploy_inflatable(var/turf/T, var/mob/living/user)
if (deploying)
if(deploying)
return
var/newtype
if(mode) // Door deployment
if(!stored_doors)
to_chat(user, "\The [src] is out of doors!")
to_chat(user, SPAN_WARNING("\The [src] is out of doors!"))
return
if(T && istype(T))
newtype = /obj/structure/inflatable/door
else // Wall deployment
if(!stored_walls)
to_chat(user, "\The [src] is out of walls!")
to_chat(user, SPAN_WARNING("\The [src] is out of walls!"))
return
if(T && istype(T))
@@ -328,50 +309,50 @@
deploying = 1
user.visible_message(span("notice", "[user] starts deploying an inflatable"), span("notice", "You start deploying an inflatable [mode ? "door" : "wall"]!"))
playsound(T, 'sound/items/zip.ogg', 75, 1)
if (do_after(user, 15, needhand = 0))
playsound(T, 'sound/items/zip.ogg', 75, TRUE)
if(do_after(user, 15, needhand = FALSE))
new newtype(T)
if (mode)
if(mode)
stored_doors--
else
stored_walls--
deploying = 0
deploying = FALSE
/obj/item/inflatable_dispenser/proc/pick_up(var/obj/A, var/mob/living/user)
if(istype(A, /obj/structure/inflatable))
if(istype(A, /obj/structure/inflatable/wall))
if(stored_walls >= max_walls)
to_chat(user, "\The [src] is full.")
to_chat(user, SPAN_WARNING("\The [src] is full."))
return
stored_walls++
qdel(A)
else
if(stored_doors >= max_doors)
to_chat(user, "\The [src] is full.")
to_chat(user, SPAN_WARNING("\The [src] is full."))
return
stored_doors++
qdel(A)
playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
visible_message("\The [user] deflates \the [A] with \the [src]!")
playsound(get_turf(src), 'sound/machines/hiss.ogg', 75, TRUE)
visible_message(SPAN_NOTICE("\The [user] deflates \the [A] with \the [src]."))
return
if(istype(A, /obj/item/inflatable))
if(istype(A, /obj/item/inflatable/wall))
if(stored_walls >= max_walls)
to_chat(user, "\The [src] is full.")
to_chat(user, SPAN_WARNING("\The [src] is full."))
return
stored_walls++
qdel(A)
else
if(stored_doors >= max_doors)
to_chat(usr, "\The [src] is full!")
to_chat(usr, SPAN_WARNING("\The [src] is full!"))
return
stored_doors++
qdel(A)
visible_message("\The [user] picks up \the [A] with \the [src]!")
visible_message(SPAN_NOTICE("\The [user] picks up \the [A] with \the [src]."))
return
to_chat(user, "You fail to pick up \the [A] with \the [src]")
to_chat(user, SPAN_WARNING("You fail to pick up \the [A] with \the [src]"))
return
/obj/item/gun/energy/mountedcannon
@@ -385,8 +366,8 @@
max_shots = 10
charge_cost = 300
projectile_type = /obj/item/projectile/bullet/gyro
self_recharge = 1
use_external_power = 1
self_recharge = TRUE
use_external_power = TRUE
recharge_time = 5
needspin = FALSE
@@ -20,30 +20,30 @@ var/global/list/robot_modules = list(
flags = CONDUCT
var/channels = list()
var/networks = list()
var/languages = list( //Any listed language will be understandable. Any set to 1 will be speakable
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 0,
LANGUAGE_SIIK_MAAS = 0,
LANGUAGE_SKRELLIAN = 0,
LANGUAGE_GUTTER = 1,
LANGUAGE_VAURCESE = 0,
LANGUAGE_ROOTSONG = 0,
LANGUAGE_SIGN = 0,
LANGUAGE_SIGN_TAJARA = 0,
LANGUAGE_SIIK_TAJR = 0,
LANGUAGE_AZAZIBA = 0,
LANGUAGE_DELVAHII = 0,
LANGUAGE_YA_SSA = 0
var/languages = list( //Any listed language will be understandable. Any set to TRUE will be speakable
LANGUAGE_SOL_COMMON = TRUE,
LANGUAGE_TRADEBAND = TRUE,
LANGUAGE_UNATHI = FALSE,
LANGUAGE_SIIK_MAAS = FALSE,
LANGUAGE_SKRELLIAN = FALSE,
LANGUAGE_GUTTER = TRUE,
LANGUAGE_VAURCESE = FALSE,
LANGUAGE_ROOTSONG = FALSE,
LANGUAGE_SIGN = FALSE,
LANGUAGE_SIGN_TAJARA = FALSE,
LANGUAGE_SIIK_TAJR = FALSE,
LANGUAGE_AZAZIBA = FALSE,
LANGUAGE_DELVAHII = FALSE,
LANGUAGE_YA_SSA = FALSE
)
var/sprites = list()
var/can_be_pushed = 1
var/no_slip = 0
var/can_be_pushed = TRUE
var/no_slip = FALSE
var/list/modules = list()
var/list/datum/matter_synth/synths = list()
var/obj/item/emag = null
var/obj/item/malfAImodule = null
var/obj/item/borg/upgrade/jetpack = null
var/obj/item/emag
var/obj/item/malf_AI_module
var/obj/item/borg/upgrade/jetpack
var/list/subsystems = list()
var/list/obj/item/borg/upgrade/supported_upgrades = list()
@@ -64,12 +64,12 @@ var/global/list/robot_modules = list(
R.radio.recalculateChannels()
R.set_module_sprites(sprites)
R.icon_selected = 0
R.icon_selected = FALSE
R.icon_selection_tries = -1
R.choose_icon()
for(var/obj/item/I in modules)
I.canremove = 0
I.canremove = FALSE
/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
remove_camera_networks(R)
@@ -80,7 +80,7 @@ var/global/list/robot_modules = list(
if(R.radio)
R.radio.recalculateChannels()
R.set_module_sprites(list("Default" = "robot"))
R.icon_selected = 0
R.icon_selected = FALSE
R.icon_selection_tries = -1
R.choose_icon()
@@ -91,12 +91,9 @@ var/global/list/robot_modules = list(
qdel(synth)
modules.Cut()
synths.Cut()
qdel(emag)
qdel(jetpack)
qdel(malfAImodule)
emag = null
malfAImodule = null
jetpack = null
QDEL_NULL(emag)
QDEL_NULL(jetpack)
QDEL_NULL(malf_AI_module)
return ..()
/obj/item/robot_module/emp_act(severity)
@@ -116,16 +113,16 @@ var/global/list/robot_modules = list(
var/obj/item/device/flash/F = locate() in src.modules
if(F)
if(F.broken)
F.broken = 0
F.broken = FALSE
F.times_used = 0
F.icon_state = "flash"
else if(F.times_used)
F.times_used--
if(E && E.reagents.total_volume < E.reagents.maximum_volume)
if(E?.reagents.total_volume < E.reagents.maximum_volume)
E.reagents.add_reagent("monoammoniumphosphate", E.max_water * 0.2)
if(!synths || !synths.len)
if(!synths?.len)
return
for(var/datum/matter_synth/T in synths)
@@ -184,9 +181,9 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/medical
name = "medical robot module"
channels = list("Medical" = 1)
channels = list("Medical" = TRUE)
networks = list(NETWORK_MEDICAL)
can_be_pushed = 0
can_be_pushed = FALSE
sprites = list(
"Basic" = "robotmedi",
"Landmate" = "landmatemedi",
@@ -203,9 +200,6 @@ var/global/list/robot_modules = list(
"Unbranded-Android" = "droid",
)
/obj/item/robot_module/medical/general
name = "medical robot module"
/obj/item/robot_module/medical/general/New()
..()
src.modules += new /obj/item/crowbar/robotic(src)
@@ -227,27 +221,26 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/roller_holder(src)
src.modules += new /obj/item/reagent_containers/syringe(src)
src.modules += new /obj/item/device/reagent_scanner/adv(src)
src.modules += new /obj/item/autopsy_scanner(src) // an autopsy scanner
src.modules += new /obj/item/autopsy_scanner(src)
src.modules += new /obj/item/device/breath_analyzer(src)
src.emag = new /obj/item/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
src.emag = new /obj/item/reagent_containers/hypospray/cmo(src)
src.emag.reagents.add_reagent("wulumunusha", 30)
src.emag.name = "Wulumunusha Hypospray"
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(10000)
synths += medicine
var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
N.uses_charge = 1
N.uses_charge = TRUE
N.charge_costs = list(1000)
N.synths = list(medicine)
B.uses_charge = 1
B.uses_charge = TRUE
B.charge_costs = list(1000)
B.synths = list(medicine)
src.modules += N
src.modules += B
/obj/item/robot_module/medical/general/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/reagent_containers/syringe/S = locate() in src.modules
if(S.mode == 2)
@@ -255,10 +248,9 @@ var/global/list/robot_modules = list(
S.mode = initial(S.mode)
S.desc = initial(S.desc)
S.update_icon()
if(src.emag)
var/obj/item/reagent_containers/spray/PS = src.emag
PS.reagents.add_reagent("pacid", 2 * amount)
var/obj/item/reagent_containers/hypospray/cmo/PS = src.emag
PS.reagents.add_reagent("wulumunusha", 2 * amount)
..()
/obj/item/robot_module/medical/rescue
@@ -296,9 +288,9 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/extinguisher/mini(src)
src.modules += new /obj/item/inflatable_dispenser(src) // Allows usage of inflatables. Since they are basically robotic alternative to EMTs, they should probably have them.
src.modules += new /obj/item/device/gps(src) // for coordinating with medical suit health sensors console
src.emag = new /obj/item/reagent_containers/spray(src)
src.emag.reagents.add_reagent("pacid", 250)
src.emag.name = "Polyacid spray"
src.emag = new /obj/item/reagent_containers/hypospray/cmo(src)
src.emag.reagents.add_reagent("wulumunusha", 30)
src.emag.name = "Wulumunusha Hypospray"
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
synths += medicine
@@ -306,20 +298,19 @@ var/global/list/robot_modules = list(
var/obj/item/stack/medical/ointment/O = new /obj/item/stack/medical/ointment(src)
var/obj/item/stack/medical/bruise_pack/B = new /obj/item/stack/medical/bruise_pack(src)
var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
O.uses_charge = 1
O.uses_charge = TRUE
O.charge_costs = list(1000)
O.synths = list(medicine)
B.uses_charge = 1
B.uses_charge = TRUE
B.charge_costs = list(1000)
B.synths = list(medicine)
S.uses_charge = 1
S.uses_charge = TRUE
S.charge_costs = list(1000)
S.synths = list(medicine)
src.modules += O
src.modules += B
src.modules += S
/obj/item/robot_module/medical/rescue/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/reagent_containers/syringe/S = locate() in src.modules
if(S.mode == 2)
@@ -327,17 +318,14 @@ var/global/list/robot_modules = list(
S.mode = initial(S.mode)
S.desc = initial(S.desc)
S.update_icon()
if(src.emag)
var/obj/item/reagent_containers/spray/PS = src.emag
PS.reagents.add_reagent("pacid", 2 * amount)
PS.reagents.add_reagent("wulumunusha", 2 * amount)
..()
/obj/item/robot_module/engineering
name = "engineering robot module"
channels = list("Engineering" = 1)
channels = list("Engineering" = TRUE)
networks = list(NETWORK_ENGINEERING)
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
sprites = list(
@@ -355,12 +343,11 @@ var/global/list/robot_modules = list(
"Unbranded-MAD" = "offfloatspizzytronengi",
"Unbranded-Android" = "droid",
)
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
/obj/item/robot_module/engineering/construction
name = "construction robot module"
no_slip = 1
no_slip = TRUE
/obj/item/robot_module/engineering/construction/New()
..()
@@ -383,7 +370,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/inflatable_dispenser(src) // to stop those pesky humans being entering the zone
src.modules += new /obj/item/pickaxe/borgdrill(src) // as station is being located at the rock terrain, which is presumed to be digged out to clear the area for new rooms
src.emag = new /obj/item/gun/energy/plasmacutter/mounted(src)
src.malfAImodule += new /obj/item/rfd/transformer(src)
src.malf_AI_module += new /obj/item/rfd/transformer(src)
var/datum/matter_synth/metal = new /datum/matter_synth/metal(80000)
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel(40000)
@@ -394,7 +381,7 @@ var/global/list/robot_modules = list(
synths += glass
synths += wire
var/obj/item/stack/material/cyborg/steel/M = new (src)
var/obj/item/stack/material/cyborg/steel/M = new /obj/item/stack/material/cyborg/steel(src)
M.synths = list(metal)
src.modules += M
@@ -402,11 +389,11 @@ var/global/list/robot_modules = list(
R.synths = list(metal)
src.modules += R
var/obj/item/stack/material/cyborg/plasteel/S = new (src)
var/obj/item/stack/material/cyborg/plasteel/S = new /obj/item/stack/material/cyborg/plasteel(src)
S.synths = list(plasteel)
src.modules += S
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new /obj/item/stack/material/cyborg/glass/reinforced(src)
RG.synths = list(metal, glass)
src.modules += RG
@@ -440,6 +427,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/device/floor_painter(src)
src.modules += new /obj/item/inflatable_dispenser(src)
src.emag = new /obj/item/melee/baton/robot/arm(src)
src.malf_AI_module += new /obj/item/rfd/transformer(src)
var/datum/matter_synth/metal = new /datum/matter_synth/metal(60000)
var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
@@ -479,41 +467,41 @@ var/global/list/robot_modules = list(
S.synths = list(metal)
src.modules += S
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new /obj/item/stack/material/cyborg/glass/reinforced(src)
RG.synths = list(metal, glass)
src.modules += RG
var/obj/item/stack/material/cyborg/plasteel/PL = new (src)
var/obj/item/stack/material/cyborg/plasteel/PL = new /obj/item/stack/material/cyborg/plasteel(src)
PL.synths = list(plasteel)
src.modules += PL
var/obj/item/stack/material/cyborg/wood/W = new (src)
var/obj/item/stack/material/cyborg/wood/W = new /obj/item/stack/material/cyborg/wood(src)
W.synths = list(wood)
src.modules += W
var/obj/item/stack/material/cyborg/plastic/PS = new (src)
var/obj/item/stack/material/cyborg/plastic/PS = new /obj/item/stack/material/cyborg/plastic(src)
PS.synths = list(plastic)
src.modules += PS
var/obj/item/stack/tile/wood/cyborg/FWT = new (src)
var/obj/item/stack/tile/wood/cyborg/FWT = new /obj/item/stack/tile/wood/cyborg(src)
FWT.synths = list(wood)
src.modules += FWT
var/obj/item/stack/tile/floor_white/cyborg/FTW = new (src)
var/obj/item/stack/tile/floor_white/cyborg/FTW = new /obj/item/stack/tile/floor_white/cyborg(src)
FTW.synths = list(plastic)
src.modules += FTW
var/obj/item/stack/tile/floor_freezer/cyborg/FTF = new (src)
var/obj/item/stack/tile/floor_freezer/cyborg/FTF = new /obj/item/stack/tile/floor_freezer/cyborg(src)
FTF.synths = list(plastic)
src.modules += FTF
var/obj/item/stack/tile/floor_dark/cyborg/FTD = new (src)
var/obj/item/stack/tile/floor_dark/cyborg/FTD = new /obj/item/stack/tile/floor_dark/cyborg(src)
FTD.synths = list(plasteel)
src.modules += FTD
/obj/item/robot_module/janitor
name = "custodial robot module"
channels = list("Service" = 1)
channels = list("Service" = TRUE)
networks = list(NETWORK_SERVICE)
sprites = list(
"Basic" = "robotjani",
@@ -555,23 +543,23 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/clerical
name = "service robot module"
channels = list("Service" = 1)
channels = list("Service" = TRUE)
networks = list(NETWORK_SERVICE)
languages = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 1,
LANGUAGE_SIIK_MAAS = 1,
LANGUAGE_SKRELLIAN = 1,
LANGUAGE_GUTTER = 1,
LANGUAGE_VAURCESE = 0,
LANGUAGE_ROOTSONG = 1,
LANGUAGE_SIGN = 0,
LANGUAGE_SIGN_TAJARA = 0,
LANGUAGE_SIIK_TAJR = 0,
LANGUAGE_AZAZIBA = 0,
LANGUAGE_DELVAHII = 0,
LANGUAGE_YA_SSA = 0
LANGUAGE_SOL_COMMON = TRUE,
LANGUAGE_TRADEBAND = TRUE,
LANGUAGE_UNATHI = TRUE,
LANGUAGE_SIIK_MAAS = TRUE,
LANGUAGE_SKRELLIAN = TRUE,
LANGUAGE_GUTTER = TRUE,
LANGUAGE_VAURCESE = FALSE,
LANGUAGE_ROOTSONG = TRUE,
LANGUAGE_SIGN = FALSE,
LANGUAGE_SIGN_TAJARA = FALSE,
LANGUAGE_SIIK_TAJR = FALSE,
LANGUAGE_AZAZIBA = FALSE,
LANGUAGE_DELVAHII = FALSE,
LANGUAGE_YA_SSA = FALSE
)
sprites = list(
@@ -590,9 +578,6 @@ var/global/list/robot_modules = list(
"Unbranded-Android" = "droid",
)
/obj/item/robot_module/clerical/butler
/obj/item/robot_module/clerical/butler/New()
..()
src.modules += new /obj/item/crowbar/robotic(src)
@@ -616,14 +601,14 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/reagent_containers/dropper/industrial(src)
var/obj/item/flame/lighter/zippo/L = new /obj/item/flame/lighter/zippo(src)
L.lit = 1
L.lit = TRUE
src.modules += L
src.modules += new /obj/item/tray/robotray(src)
src.modules += new /obj/item/reagent_containers/borghypo/service(src)
src.emag = new /obj/item/reagent_containers/food/drinks/bottle/small/beer(src)
var/datum/reagents/R = new/datum/reagents(50)
var/datum/reagents/R = new /datum/reagents(50)
src.emag.reagents = R
R.my_atom = src.emag
R.add_reagent("beer2", 50)
@@ -644,18 +629,9 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/device/nanoquikpay(src)
src.emag = new /obj/item/stamp/chameleon(src)
/obj/item/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
..()
var/obj/item/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
E.reagents.add_reagent("enzyme", 2 * amount)
if(src.emag)
var/obj/item/reagent_containers/food/drinks/bottle/small/beer/B = src.emag
B.reagents.add_reagent("beer2", 2 * amount)
/obj/item/robot_module/miner
name = "miner robot module"
channels = list("Supply" = 1)
channels = list("Supply" = TRUE)
networks = list(NETWORK_MINE)
sprites = list(
"Basic" = "robotmine",
@@ -672,7 +648,6 @@ var/global/list/robot_modules = list(
"Unbranded-MAD" = "offfloatspizzytronmine",
"Unbranded-Android" = "droid",
)
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
/obj/item/robot_module/miner/New()
@@ -693,7 +668,7 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/research
name = "research module"
channels = list("Science" = 1)
channels = list("Science" = TRUE)
networks = list(NETWORK_RESEARCH)
sprites = list(
"Basic" = "robotjani",
@@ -737,7 +712,7 @@ var/global/list/robot_modules = list(
synths += nanite
var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
N.uses_charge = 1
N.uses_charge = TRUE
N.charge_costs = list(1000)
N.synths = list(nanite)
src.modules += N
@@ -745,20 +720,20 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/syndicate
name = "syndicate robot module"
languages = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 1,
LANGUAGE_SIIK_MAAS = 1,
LANGUAGE_SKRELLIAN = 1,
LANGUAGE_GUTTER = 1,
LANGUAGE_VAURCESE = 0,
LANGUAGE_ROOTSONG = 1,
LANGUAGE_SIGN = 0,
LANGUAGE_SIGN_TAJARA = 0,
LANGUAGE_SIIK_TAJR = 0,
LANGUAGE_AZAZIBA = 0,
LANGUAGE_DELVAHII = 0,
LANGUAGE_YA_SSA = 0
LANGUAGE_SOL_COMMON = TRUE,
LANGUAGE_TRADEBAND = TRUE,
LANGUAGE_UNATHI = TRUE,
LANGUAGE_SIIK_MAAS = TRUE,
LANGUAGE_SKRELLIAN = TRUE,
LANGUAGE_GUTTER = TRUE,
LANGUAGE_VAURCESE = FALSE,
LANGUAGE_ROOTSONG = TRUE,
LANGUAGE_SIGN = FALSE,
LANGUAGE_SIGN_TAJARA = FALSE,
LANGUAGE_SIIK_TAJR = FALSE,
LANGUAGE_AZAZIBA = FALSE,
LANGUAGE_DELVAHII = FALSE,
LANGUAGE_YA_SSA = FALSE
)
sprites = list(
@@ -773,7 +748,6 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/syndicate/New(var/mob/living/silicon/robot/R)
..()
loc = R
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/melee/energy/sword(src)
@@ -785,14 +759,12 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/handcuffs/cyborg(src)
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
return
/obj/item/robot_module/combat
name = "combat robot module"
channels = list("Security" = 1)
channels = list("Security" = TRUE)
networks = list(NETWORK_SECURITY)
sprites = list("Roller" = "droid-combat")
can_be_pushed = 0
can_be_pushed = FALSE
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
/obj/item/robot_module/combat/New()
@@ -809,7 +781,7 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/drone
name = "drone module"
no_slip = 1
no_slip = TRUE
networks = list(NETWORK_ENGINEERING)
/obj/item/robot_module/drone/New(var/mob/living/silicon/robot/robot)
@@ -828,7 +800,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/device/pipe_painter(src)
src.modules += new /obj/item/device/floor_painter(src)
robot.internals = new/obj/item/tank/jetpack/carbondioxide(src)
robot.internals = new /obj/item/tank/jetpack/carbondioxide(src)
src.modules += robot.internals
var/datum/matter_synth/metal = new /datum/matter_synth/metal(25000)
@@ -887,7 +859,7 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/drone/construction
name = "construction drone module"
channels = list("Engineering" = 1)
channels = list("Engineering" = TRUE)
languages = list()
/obj/item/robot_module/drone/construction/New()
@@ -951,44 +923,42 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/bluespace
name = "bluespace robot module"
languages = list(
LANGUAGE_TCB = 1,
LANGUAGE_GUTTER = 1,
LANGUAGE_SIGN = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 1,
LANGUAGE_AZAZIBA = 1,
LANGUAGE_SIIK_MAAS = 1,
LANGUAGE_SIIK_TAJR = 1,
LANGUAGE_SIGN_TAJARA = 1,
LANGUAGE_SKRELLIAN = 1,
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_ROOTSONG = 1,
LANGUAGE_VAURCA = 1,
LANGUAGE_ROBOT = 1,
LANGUAGE_DRONE = 1,
LANGUAGE_EAL = 1,
LANGUAGE_VOX = 1,
LANGUAGE_CHANGELING = 1,
LANGUAGE_BORER = 1
LANGUAGE_TCB = TRUE,
LANGUAGE_GUTTER = TRUE,
LANGUAGE_SIGN = TRUE,
LANGUAGE_TRADEBAND = TRUE,
LANGUAGE_UNATHI = TRUE,
LANGUAGE_AZAZIBA = TRUE,
LANGUAGE_SIIK_MAAS = TRUE,
LANGUAGE_SIIK_TAJR = TRUE,
LANGUAGE_SIGN_TAJARA = TRUE,
LANGUAGE_SKRELLIAN = TRUE,
LANGUAGE_SOL_COMMON = TRUE,
LANGUAGE_ROOTSONG = TRUE,
LANGUAGE_VAURCA = TRUE,
LANGUAGE_ROBOT = TRUE,
LANGUAGE_DRONE = TRUE,
LANGUAGE_EAL = TRUE,
LANGUAGE_VOX = TRUE,
LANGUAGE_CHANGELING = TRUE,
LANGUAGE_BORER = TRUE
)
channels = list(
"Service" = 1,
"Supply" = 1,
"Science" = 1,
"Security" = 1,
"Engineering" = 1,
"Medical" = 1,
"Command" = 1,
"Response Team" = 1,
"AI Private" = 1
"Service" = TRUE,
"Supply" = TRUE,
"Science" = TRUE,
"Security" = TRUE,
"Engineering" = TRUE,
"Medical" = TRUE,
"Command" = TRUE,
"Response Team" = TRUE,
"AI Private" = TRUE
)
sprites = list("Roller" = "droid-combat") //TMP
can_be_pushed = 0
sprites = list("Roller" = "droid-combat") //TMP // temp my left nut
can_be_pushed = FALSE
/obj/item/robot_module/bluespace/New(var/mob/living/silicon/robot/R)
..()
loc = R
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/borg/sight/hud/med(src)
@@ -1096,11 +1066,11 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/bluespace/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
..()
var/obj/item/melee/baton/robot/B = locate() in src.modules
if(B && B.bcell)
if(B?.bcell)
B.bcell.give(amount)
var/obj/item/reagent_containers/syringe/S = locate() in src.modules
if(S.mode == 2)
S.reagents.clear_reagents()
S.mode = initial(S.mode)
S.desc = initial(S.desc)
S.update_icon()
S.update_icon()
@@ -1,37 +1,23 @@
/mob/living/silicon/robot/slip_chance(var/prob_slip)
if(module && module.no_slip)
return 0
if(module?.no_slip)
return FALSE
..(prob_slip)
/mob/living/silicon/robot/Allow_Spacemove()
if(module)
for(var/obj/item/tank/jetpack/J in module.modules)
if(J && J.allow_thrust(0.01))
return 1
return TRUE
. = ..()
//No longer needed, but I'll leave it here incase we plan to re-use it.
/mob/living/silicon/robot/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later
tally = speed
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
tally-=3
if(overclocked == 1)
tally-=1
return tally+config.robot_delay
// NEW: Different power usage depending on whether driving or jetpacking. space movement is easier
/mob/living/silicon/robot/SelfMove(turf/n, direct)
if (istype(n, /turf/space))
if (cell_use_power(jetpackComponent.active_usage))
if(istype(n, /turf/space))
if(cell_use_power(jetpackComponent.active_usage))
return ..()
if (!is_component_functioning("actuator"))
return 0
if(!is_component_functioning("actuator"))
return FALSE
if (cell_use_power(actuatorComponent.active_usage))
return ..()
if(cell_use_power(actuatorComponent.active_usage))
return ..()
@@ -1,28 +1,29 @@
//syndicate cyborgs, they aren't fully linked to the station, also are more combat oriented, for now only the regular assault module - alberyk
/mob/living/silicon/robot/syndicate
lawupdate = 0
scrambledcodes = 1
modtype = "Syndicate"
icon = 'icons/mob/robots.dmi'
icon_state = "syndie_bloodhound"
lawchannel = "State"
lawpreset = /datum/ai_laws/syndicate_override
idcard_type = /obj/item/card/id/syndicate
spawn_module = /obj/item/robot_module/syndicate
key_type = /obj/item/device/encryptionkey/syndicate
spawn_sound = 'sound/mecha/nominalsyndi.ogg'
pitch_toggle = 0
cell_type = /obj/item/cell/super
req_access = list(access_syndicate)
faction = "syndicate"
braintype = "Cyborg"
no_pda = TRUE
// Laws and Interaction
law_channel = "State"
law_preset = /datum/ai_laws/syndicate_override
law_update = FALSE
scrambled_codes = TRUE
/mob/living/silicon/robot/syndicate/init()
..()
if(!jetpack)
jetpack = new /obj/item/tank/jetpack/carbondioxide/synthetic(src)
// Modules
mod_type = "Syndicate"
spawn_module = /obj/item/robot_module/syndicate
cell_type = /obj/item/cell/super
has_pda = FALSE
has_jetpack = TRUE
// Look and feel
icon_state = "syndie_bloodhound"
spawn_sound = 'sound/mecha/nominalsyndi.ogg'
pitch_toggle = FALSE
braintype = "Cyborg"
// ID and Access
req_access = list(access_syndicate)
id_card_type = /obj/item/card/id/syndicate
key_type = /obj/item/device/encryptionkey/syndicate
/mob/living/silicon/robot/syndicate/Initialize()
. = ..()
@@ -35,7 +36,7 @@
if(opened)
var/panelprefix = custom_sprite ? src.ckey : "ov"
if(wiresexposed)
if(wires_exposed)
add_overlay("[panelprefix]-openpanel +w")
else if(cell)
add_overlay("[panelprefix]-openpanel +c")
@@ -45,7 +46,7 @@
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
add_overlay("[icon_state]-shield")
if(modtype == "Combat")
if(mod_type == "Combat")
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
icon_state = "[icon_state]-roll"
else
+42 -52
View File
@@ -1,23 +1,23 @@
/mob/living/silicon/say(var/message, var/sanitize = 1)
/mob/living/silicon/say(message, sanitize = TRUE)
return ..(sanitize ? sanitize(message) : message)
/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
log_say("[key_name(src)] : [message]",ckey=key_name(src))
/mob/living/silicon/robot/handle_speech_problems(var/message, var/verb, var/message_mode)
var/speech_problem_flag = 0
var/speech_problem_flag = FALSE
//Handle gibberish when components are damaged
if(message_mode)
//If we have a radio message, just look at the damage of the radio
var/datum/robot_component/C = get_component("radio")
if(C.get_damage())
speech_problem_flag = 1
message=Gibberish(message,C.max_damage/C.get_damage())
speech_problem_flag = TRUE
message = Gibberish(message, C.max_damage / C.get_damage())
else
var/damaged = 100-(Clamp(health,0,maxHealth)/maxHealth)*100
var/damaged = 100 - (Clamp(health, 0, maxHealth) / maxHealth) * 100
if(damaged > 40)
speech_problem_flag = 1
message = Gibberish(message,damaged-10)
speech_problem_flag = TRUE
message = Gibberish(message, damaged - 10)
var/list/returns[4]
returns[1] = message
@@ -30,69 +30,63 @@
..()
if(message_mode)
if(!is_component_functioning("radio"))
to_chat(src, "<span class='warning'>Your radio isn't functional at this time.</span>")
to_chat(src, SPAN_WARNING("Your radio isn't functional at this time."))
return 0
if(message_mode == "general")
message_mode = null
return radio.talk_into(src,message,message_mode,verb,speaking)
return common_radio.talk_into(src, message, message_mode, verb, speaking)
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode == "department")
return holopad_talk(message, verb, speaking)
else if(message_mode)
if (aiRadio.disabledAi || aiRestorePowerRoutine || stat)
to_chat(src, "<span class='danger'>System Error - Transceiver Disabled.</span>")
return 0
if(ai_radio.disabledAi || ai_restore_power_routine || stat)
to_chat(src, SPAN_DANGER("System Error - Transceiver Disabled."))
return FALSE
if(message_mode == "general")
message_mode = null
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
return ai_radio.talk_into(src, message, message_mode, verb, speaking)
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
..()
if(message_mode)
if(message_mode == "general")
message_mode = null
return radio.talk_into(src,message,message_mode,verb,speaking)
return radio.talk_into(src, message, message_mode, verb, speaking)
/mob/living/silicon/say_quote(var/text)
var/ending = copytext(text, length(text))
if (ending == "?")
if(ending == "?")
return speak_query
else if (ending == "!")
else if(ending == "!")
return speak_exclamation
return speak_statement
#define IS_AI 1
#define IS_ROBOT 2
#define IS_PAI 3
/mob/living/silicon/say_understands(var/other,var/datum/language/speaking = null)
/mob/living/silicon/say_understands(var/other, var/datum/language/speaking = null)
//These only pertain to common. Languages are handled by mob/say_understands()
if (!speaking)
if (istype(other, /mob/living/carbon))
return 1
if (istype(other, /mob/living/silicon))
return 1
if (istype(other, /mob/living/carbon/brain))
return 1
if(!speaking)
if(istype(other, /mob/living/carbon))
return TRUE
if(istype(other, /mob/living/silicon))
return TRUE
if(istype(other, /mob/living/carbon/brain))
return TRUE
return ..()
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)
log_say("[key_name(src)] : [message]",ckey=key_name(src))
message = trim(message)
if (!message)
if(!message)
return
var/obj/machinery/hologram/holopad/H = src.holo
if(H && H.masters[src])//If there is a hologram and its master is the user.
// AI can hear their own message, this formats it for them.
if(speaking)
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [speaking.format_message(message, verb)]</span></i>")
@@ -110,59 +104,55 @@
var/list/hearturfs = list()
for(var/I in hear)
if(istype(I, /mob/))
if(istype(I, /mob))
var/mob/M = I
listening += M
hearturfs += M.locs[1]
for(var/obj/O in M.contents)
listening_obj |= O
else if(istype(I, /obj/))
else if(istype(I, /obj))
var/obj/O = I
hearturfs += O.locs[1]
listening_obj |= O
for(var/mob/M in player_list)
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
M.hear_say(message,verb,speaking,null,null, src)
if(M.stat == DEAD && M.client?.prefs.toggles & CHAT_GHOSTEARS)
M.hear_say(message, verb, speaking, null, null, src)
continue
if(M.loc && M.locs[1] in hearturfs)
M.hear_say(message,verb,speaking,null,null, src)
M.hear_say(message, verb, speaking, null, null, src)
else
to_chat(src, "No holopad connected.")
return 0
return 1
to_chat(src, SPAN_WARNING("No holopad connected."))
return FALSE
return TRUE
/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad.
log_emote("[key_name(src)] : [message]",ckey=key_name(src))
message = trim(message)
if (!message)
if(!message)
return
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.masters[src])
if(T?.masters[src])
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[message]</span></span>"
to_chat(src, "<i><span class='game say'>Holopad action relayed, <span class='name'>[real_name]</span> <span class='message'>[message]</span></span></i>")
for(var/mob/M in viewers(T.loc))
M.show_message(rendered, 2)
for(var/mob/M in viewers(get_turf(T)))
to_chat(M, rendered)
else //This shouldn't occur, but better safe then sorry.
to_chat(src, "No holopad connected.")
return 0
return 1
to_chat(src, SPAN_WARNING("No holopad connected."))
return FALSE
return TRUE
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.masters[src]) //Is the AI using a holopad?
if(T?.masters[src]) //Is the AI using a holopad?
src.holopad_emote(message)
else //Emote normally, then.
..()
#undef IS_AI
#undef IS_ROBOT
#undef IS_PAI
#undef IS_PAI
+108 -108
View File
@@ -1,43 +1,66 @@
#define NO_HUD 0
#define SEC_HUD 1
#define MED_HUD 2
/mob/living/silicon
// Speaking
gender = NEUTER
voice_name = "synthesized voice"
//diona_restricted_light = 1//Light emitted by this object or creature has limited interaction with diona
var/syndicate = 0
var/const/MAIN_CHANNEL = "Main Frequency"
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
var/list/stating_laws = list()// Channels laws are currently being stated on
var/obj/item/device/radio/common_radio
var/list/hud_list[10]
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
//Used in say.dm.
voice_name = "Synthesized Voice"
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
var/speak_statement = "states"
var/speak_exclamation = "declares"
var/speak_query = "queries"
var/pose //Yes, now AIs can pose too.
var/obj/item/device/camera/siliconcam/aiCamera = null //photography
var/local_transmit //If set, can only speak to others of the same type within a short range.
// Description
var/pose //Yes, now AIs can pose too.
// Bad Guy Stuff
var/syndicate = FALSE
// Laws
var/datum/ai_laws/laws
var/law_channel = DEFAULT_LAW_CHANNEL
var/list/additional_law_channels = list("State" = "")
var/list/stating_laws = list() // Channels laws are currently being stated on
var/obj/item/device/radio/common_radio // Used to determine default channels
// Hud Stuff
var/list/hud_list[10]
var/sensor_mode = 0 //Determines the current HUD.
// Alarms
var/register_alarms = TRUE
var/next_alarm_notice
var/list/datum/alarm/queued_alarms = new()
uv_intensity = 175 //Lights cast by robots have reduced effect on diona
// Internal Computer
var/datum/nano_module/alarm_monitor/all/alarm_monitor
var/datum/nano_module/law_manager/law_manager
var/datum/nano_module/rcon/rcon
var/obj/item/modular_computer/silicon/computer
var/list/silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_law_manager,
/mob/living/silicon/proc/computer_interact
)
// Utility
var/obj/item/device/camera/siliconcam/ai_camera //photography
// ID and Access
var/list/access_rights
var/obj/item/card/id/idcard
var/idcard_type = /obj/item/card/id/synthetic
var/obj/item/card/id/id_card
var/id_card_type = /obj/item/card/id/synthetic
// Misc
uv_intensity = 175 //Lights cast by robots have reduced effect on diona
mob_thinks = FALSE
#define SEC_HUD 1 //Security HUD mode
#define MED_HUD 2 //Medical HUD mode
/mob/living/silicon/Initialize()
silicon_mob_list |= src
. = ..()
add_language("Ceti Basic")
add_language(LANGUAGE_TCB)
init_id()
var/datum/language/L = locate(/datum/language/common) in languages
@@ -47,17 +70,20 @@
/mob/living/silicon/Destroy()
silicon_mob_list -= src
QDEL_NULL(idcard)
QDEL_NULL(alarm_monitor)
QDEL_NULL(law_manager)
QDEL_NULL(computer)
QDEL_NULL(id_card)
QDEL_NULL(common_radio)
for(var/datum/alarm_handler/AH in SSalarm.all_handlers)
AH.unregister_alarm(src)
return ..()
/mob/living/silicon/proc/init_id()
if(idcard)
if(id_card)
return
idcard = new idcard_type(src)
set_id_info(idcard)
id_card = new id_card_type(src)
set_id_info(id_card)
/mob/living/silicon/proc/SetName(pickedName as text)
real_name = pickedName
@@ -72,29 +98,28 @@
/mob/living/silicon/emp_act(severity)
switch(severity)
if(1)
src.take_organ_damage(0,20,emp=1)
Stun(rand(5,10))
src.take_organ_damage(0, 20, emp = TRUE)
Stun(rand(5, 10))
if(2)
src.take_organ_damage(0,10,emp=1)
Stun(rand(1,5))
src.take_organ_damage(0, 10, emp = TRUE)
Stun(rand(1, 5))
flick("noise", src:flash)
to_chat(src, "<span class='danger'>*BZZZT*</span>")
to_chat(src, "<span class='warning'>Warning: Electromagnetic pulse detected.</span>")
to_chat(src, SPAN_DANGER("BZZZT"))
to_chat(src, SPAN_WARNING("Warning: Electromagnetic pulse detected."))
..()
/mob/living/silicon/stun_effect_act(var/stun_amount, var/agony_amount)
/mob/living/silicon/stun_effect_act()
return //immune
/mob/living/silicon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/tesla_shock = 0, var/ground_zero)
if (istype(source, /obj/machinery/containment_field))
/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0, tesla_shock = FALSE, ground_zero)
if(istype(source, /obj/machinery/containment_field))
spark(loc, 5, alldirs)
shock_damage *= 0.75 //take reduced damage
take_overall_damage(0, shock_damage)
visible_message("<span class='warning'>[src] was shocked by \the [source]!</span>", \
"<span class='danger'>Energy pulse detected, system damaged!</span>", \
"<span class='warning'>You hear an electrical crack.</span>")
visible_message(SPAN_WARNING("\The [src] was shocked by \the [source]!"), \
SPAN_DANGER("Energy pulse detected, system damaged!"), \
SPAN_WARNING("You hear an electrical crack."))
if(prob(20))
Stun(2)
return
@@ -103,10 +128,9 @@
return
/mob/living/silicon/IsAdvancedToolUser()
return 1
/mob/living/silicon/bullet_act(var/obj/item/projectile/Proj)
return TRUE
/mob/living/silicon/bullet_act(obj/item/projectile/Proj)
if(!Proj.nodamage)
switch(Proj.damage_type)
if(BRUTE)
@@ -114,51 +138,30 @@
if(BURN)
adjustFireLoss(Proj.damage)
Proj.on_hit(src,100)
Proj.on_hit(src, 100)
updatehealth()
return 100
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
/*
if(!effect || (blocked >= 2)) return 0
switch(effecttype)
if(STUN)
stunned = max(stunned,(effect/(blocked+1)))
if(WEAKEN)
weakened = max(weakened,(effect/(blocked+1)))
if(PARALYZE)
paralysis = max(paralysis,(effect/(blocked+1)))
if(IRRADIATE)
radiation += min((effect - (effect*getarmor(null, "rad"))), 0)//Rads auto check armor
if(STUTTER)
stuttering = max(stuttering,(effect/(blocked+1)))
if(EYE_BLUR)
eye_blurry = max(eye_blurry,(effect/(blocked+1)))
if(DROWSY)
drowsyness = max(drowsyness,(effect/(blocked+1)))
updatehealth()
return 1*/
return FALSE
/proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai)
if(!istype(bot) || !istype(ai))
return 0
if (bot.connected_ai == ai)
return 1
return 0
return FALSE
if(bot.connected_ai == ai)
return TRUE
return FALSE
// this function shows the health of the AI in the Status panel
/mob/living/silicon/proc/show_system_integrity()
if(!src.stat)
stat(null, text("System integrity: [round((health/maxHealth)*100)]%"))
if(!stat)
stat(null, text("System Integrity: [round((health/maxHealth)*100)]%"))
else
stat(null, text("Systems nonfunctional"))
stat(null, text("Systems Non-functional"))
// This is a pure virtual function, it should be overwritten by all subclasses
/mob/living/silicon/proc/show_malf_ai()
return 0
return FALSE
// this function displays the shuttles ETA in the status panel if the shuttle has been called
/mob/living/silicon/proc/show_emergency_shuttle_eta()
@@ -167,7 +170,6 @@
if(eta_status)
stat(null, eta_status)
// This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms
/mob/living/silicon/Stat()
if(statpanel("Status"))
@@ -186,16 +188,15 @@
onclose(src, "airoster")
//can't inject synths
/mob/living/silicon/can_inject(var/mob/user, var/error_msg)
/mob/living/silicon/can_inject(mob/user, error_msg)
if(error_msg)
to_chat(user, "<span class='alert'>The armoured plating is too tough.</span>")
return 0
to_chat(user, span("alert", "The armoured plating is too tough."))
return FALSE
//Silicon mob language procs
/mob/living/silicon/can_speak(datum/language/speaking)
return universal_speak || (speaking in src.speech_synthesizer_langs) //need speech synthesizer support to vocalize a language
return universal_speak || (speaking in src.speech_synthesizer_langs) //need speech synthesizer support to vocalize a language
/mob/living/silicon/add_language(var/language, var/can_speak=1)
var/datum/language/added_language = all_languages[language]
@@ -203,9 +204,9 @@
return
. = ..(language)
if (can_speak && (added_language in languages) && !(added_language in speech_synthesizer_langs))
if(can_speak && (added_language in languages) && !(added_language in speech_synthesizer_langs))
speech_synthesizer_langs += added_language
return 1
return TRUE
/mob/living/silicon/remove_language(var/rem_language)
var/datum/language/removed_language = all_languages[rem_language]
@@ -240,34 +241,34 @@
return
/mob/living/silicon/proc/toggle_sensor_mode()
var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Disable")
var/sensor_type = input(src, "Please select sensor type.", "Sensor Integration") in list("Security", "Medical", "Disable")
switch(sensor_type)
if ("Security")
if("Security")
sensor_mode = SEC_HUD
to_chat(src, "<span class='notice'>Security records overlay enabled.</span>")
if ("Medical")
to_chat(src, SPAN_NOTICE("Security records overlay enabled."))
if("Medical")
sensor_mode = MED_HUD
to_chat(src, "<span class='notice'>Life signs monitor overlay enabled.</span>")
if ("Disable")
sensor_mode = 0
to_chat(src, "Sensor augmentations disabled.")
to_chat(src, SPAN_NOTICE("Life signs monitor overlay enabled."))
if("Disable")
sensor_mode = NO_HUD
to_chat(src, SPAN_NOTICE("Sensor augmentations disabled."))
/mob/living/silicon/verb/pose()
set name = "Set Pose"
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
pose = sanitize(input(usr, "This is [src]. It...", "Pose", null) as text)
pose = sanitize(input(usr, "This is [src]. It...", "Pose", null) as text)
/mob/living/silicon/verb/set_flavor()
set name = "Set Flavour Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
flavor_text = sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
flavor_text = sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text)
/mob/living/silicon/binarycheck()
return 1
return TRUE
/mob/living/silicon/ex_act(severity)
if(!blinded)
@@ -316,26 +317,26 @@
if(next_alarm_notice && (world.time > next_alarm_notice))
next_alarm_notice = 0
var/alarm_raised = 0
var/alarm_raised = FALSE
for(var/datum/alarm_handler/AH in queued_alarms)
var/list/alarms = queued_alarms[AH]
var/reported = 0
var/reported = FALSE
for(var/datum/alarm/A in alarms)
if(alarms[A] == 1)
alarm_raised = 1
alarm_raised = TRUE
if(!reported)
reported = 1
to_chat(src, "<span class='warning'>--- [AH.category] Detected ---</span>")
reported = TRUE
to_chat(src, SPAN_WARNING("--- [AH.category] Detected ---"))
raised_alarm(A)
for(var/datum/alarm_handler/AH in queued_alarms)
var/list/alarms = queued_alarms[AH]
var/reported = 0
var/reported = FALSE
for(var/datum/alarm/A in alarms)
if(alarms[A] == -1)
if(!reported)
reported = 1
to_chat(src, "<span class='notice'>--- [AH.category] Cleared ---</span>")
reported = TRUE
to_chat(src, SPAN_NOTICE("--- [AH.category] Cleared ---"))
to_chat(src, "\The [A.alarm_name()].")
if(alarm_raised)
@@ -377,14 +378,13 @@
/mob/living/silicon/Move(newloc, direct)
. = ..()
if (underdoor)
underdoor = 0
if ((layer == UNDERDOOR))//if this is false, then we must have used hide, or had our layer changed by something else. We wont do anymore checks for this move proc
for (var/obj/machinery/door/D in loc)
if (D.hashatch)
underdoor = 1
if(underdoor)
underdoor = FALSE
if((layer == UNDERDOOR))//if this is false, then we must have used hide, or had our layer changed by something else. We wont do anymore checks for this move proc
for(var/obj/machinery/door/D in loc)
if(D.hashatch)
underdoor = TRUE
break
if (!underdoor)
if(!underdoor)
spawn(3)//A slight delay to let us finish walking out from under the door
layer = initial(layer)
layer = initial(layer)
+1 -1
View File
@@ -1151,7 +1151,7 @@ proc/is_blind(A)
return ..(get_active_hand())
/mob/living/silicon/ai/get_multitool()
return ..(aiMulti)
return ..(ai_multi)
/mob/proc/get_hydration_mul(var/minscale = 0, var/maxscale = 1)
+1 -1
View File
@@ -108,7 +108,7 @@
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs)
var/mob/living/silicon/ai/O = new (loc, base_law_type,,1)//No MMI but safety is in effect.
O.invisibility = 0
O.aiRestorePowerRoutine = 0
O.ai_restore_power_routine = 0
if(mind)
mind.transfer_to(O)