Telecommunication interruption no longer permanently disables the ability for synths to state laws if they attempt it during the downtime.
If a synth attempts to state laws during telecommunication interruption it now receives a clear feedback message about its impossibility.
Fixes runtime errors when AIs uses shortcut keys to operate APCs/turret controls when the corresponding window isn't open.
Adds missing AI-restriction check for turret controls.
Airlocks no longer lie about dropping bolts when they cannot be dropped.
This commit is contained in:
PsiOmega
2014-11-06 15:03:48 +01:00
parent 8078ffe079
commit f2dcf1acaa
11 changed files with 90 additions and 78 deletions

View File

@@ -121,12 +121,10 @@
Topic("aiDisable=4", list("aiDisable"="4"), 1) Topic("aiDisable=4", list("aiDisable"="4"), 1)
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs. /obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
Topic("breaker=1", list("breaker"="1"), 1) // 0 meaning window (consistency! wait...) Topic("breaker=1", list("breaker"="1"), 1) // 1 meaning no window (consistency!)
/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets /obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
if(!ailock) Topic("toggleOn", list("toggleOn"="1", 1)) // 1 meaning no window (consistency!)
src.enabled = !src.enabled
src.updateTurrets()
/atom/proc/AIAltClick(var/atom/A) /atom/proc/AIAltClick(var/atom/A)
AltClick(A) AltClick(A)
@@ -141,9 +139,7 @@
return return
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
if(!ailock) Topic("toggleLethal", list("toggleLethal"="1", 1)) // 1 meaning no window (consistency!)
src.lethal = !src.lethal
src.updateTurrets()
/atom/proc/AIMiddleClick() /atom/proc/AIMiddleClick()
return return

View File

@@ -2,10 +2,10 @@
holder_type = /obj/machinery/power/apc holder_type = /obj/machinery/power/apc
wire_count = 4 wire_count = 4
var/const/APC_WIRE_IDSCAN = 1 #define APC_WIRE_IDSCAN 1
var/const/APC_WIRE_MAIN_POWER1 = 2 #define APC_WIRE_MAIN_POWER1 2
var/const/APC_WIRE_MAIN_POWER2 = 4 #define APC_WIRE_MAIN_POWER2 4
var/const/APC_WIRE_AI_CONTROL = 8 #define APC_WIRE_AI_CONTROL 8
/datum/wires/apc/GetInteractWindow() /datum/wires/apc/GetInteractWindow()
var/obj/machinery/power/apc/A = holder var/obj/machinery/power/apc/A = holder

View File

@@ -55,7 +55,6 @@
var/datum/reception/reception = new var/datum/reception/reception = new
// check if telecomms I/O route 1459 is stable // check if telecomms I/O route 1459 is stable
//var/telecomms_intact = telecomms_process(P.owner, owner, t)
reception.message_server = get_message_server() reception.message_server = get_message_server()
var/datum/signal/signal = sender.telecomms_process() // Be aware that this proc calls sleep, to simulate transmition delays var/datum/signal/signal = sender.telecomms_process() // Be aware that this proc calls sleep, to simulate transmition delays

View File

@@ -1032,8 +1032,8 @@ About the new airlock wires panel:
else if(src.locked) else if(src.locked)
usr << "The door bolts are already dropped." usr << "The door bolts are already dropped."
else else
src.lock() if(src.lock())
usr << "The door bolts have been dropped." usr << "The door bolts have been dropped."
if(5) if(5)
//un-electrify door //un-electrify door
if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY))
@@ -1372,12 +1372,13 @@ About the new airlock wires panel:
return return
/obj/machinery/door/airlock/proc/lock(var/forced=0) /obj/machinery/door/airlock/proc/lock(var/forced=0)
if (operating || src.locked) return if (operating || src.locked) return 0
src.locked = 1 src.locked = 1
for(var/mob/M in range(1,src)) for(var/mob/M in range(1,src))
M.show_message("You hear a click from the bottom of the door.", 2) M.show_message("You hear a click from the bottom of the door.", 2)
update_icon() update_icon()
return 1
/obj/machinery/door/airlock/proc/unlock(var/forced=0) /obj/machinery/door/airlock/proc/unlock(var/forced=0)
if (operating || !src.locked) return if (operating || !src.locked) return

View File

@@ -452,6 +452,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
for (var/mob/R in heard_gibberish) for (var/mob/R in heard_gibberish)
R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1) R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1)
return 1
/proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level) /proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level)

View File

@@ -111,9 +111,18 @@
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open() popup.open()
/obj/machinery/turretid/Topic(href, href_list) /obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0)
if(..()) if(!nowindow && ..())
return return 0
if(inoperable())
return 0
if(ailock)
usr << "<span class='notice'>There seems to be a firewall preventing you from accessing this device.</span>"
return 0
add_fingerprint(usr)
if (src.locked) if (src.locked)
if (!istype(usr, /mob/living/silicon)) if (!istype(usr, /mob/living/silicon))
usr << "Control panel is locked!" usr << "Control panel is locked!"
@@ -124,7 +133,14 @@
else if (href_list["toggleLethal"]) else if (href_list["toggleLethal"])
src.lethal = !src.lethal src.lethal = !src.lethal
src.updateTurrets() src.updateTurrets()
src.attack_hand(usr)
if(!nowindow)
updateDialog()
/obj/machinery/turretid/updateDialog()
if (stat & (BROKEN|MAINT))
return
..()
/obj/machinery/turretid/proc/updateTurrets() /obj/machinery/turretid/proc/updateTurrets()
if(control_area) if(control_area)

View File

@@ -221,27 +221,27 @@
// If a channel isn't specified, send to common. // If a channel isn't specified, send to common.
if(!message_mode || message_mode == "headset") if(!message_mode || message_mode == "headset")
return radio_connection return radio_connection
// Otherwise, if a channel is specified, look for it. // Otherwise, if a channel is specified, look for it.
if(channels) if(channels)
if (message_mode == "department") // Department radio shortcut if (message_mode == "department") // Department radio shortcut
message_mode = channels[1] message_mode = channels[1]
if (channels[message_mode]) // only broadcast if the channel is set on if (channels[message_mode]) // only broadcast if the channel is set on
return secure_radio_connections[message_mode] return secure_radio_connections[message_mode]
// If we were to send to a channel we don't have, drop it. // If we were to send to a channel we don't have, drop it.
return null return null
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null) /obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
if(!on) return // the device has to be on if(!on) return 0 // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them. // Fix for permacell radios, but kinda eh about actually fixing them.
if(!M || !message) return if(!M || !message) return 0
// Uncommenting this. To the above comment: // Uncommenting this. To the above comment:
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom // The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
return return 0
M.last_target_click = world.time M.last_target_click = world.time
@@ -259,9 +259,9 @@
//#### Grab the connection datum ####// //#### Grab the connection datum ####//
var/datum/radio_frequency/connection = handle_message_mode(M, message, channel) var/datum/radio_frequency/connection = handle_message_mode(M, message, channel)
if (!istype(connection)) if (!istype(connection))
return return 0
if (!connection) if (!connection)
return return 0
var/turf/position = get_turf(src) var/turf/position = get_turf(src)
@@ -280,7 +280,8 @@
// --- Human: use their actual job --- // --- Human: use their actual job ---
if (ishuman(M)) if (ishuman(M))
jobname = M:get_assignment() var/mob/living/carbon/human/H = M
jobname = H.get_assignment()
// --- Carbon Nonhuman --- // --- Carbon Nonhuman ---
else if (iscarbon(M)) // Nonhuman carbon mob else if (iscarbon(M)) // Nonhuman carbon mob
@@ -363,7 +364,7 @@
R.receive_signal(signal) R.receive_signal(signal)
// Receiving code can be located in Telecommunications.dm // Receiving code can be located in Telecommunications.dm
return return signal.data["done"] && position.z in signal.data["level"]
/* ###### Intercoms and station-bounced radios ###### */ /* ###### Intercoms and station-bounced radios ###### */
@@ -416,15 +417,15 @@
if(signal.data["done"] && position.z in signal.data["level"]) if(signal.data["done"] && position.z in signal.data["level"])
// we're done here. // we're done here.
return return 1
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level. // Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level.
// Send a mundane broadcast with limited targets: // Send a mundane broadcast with limited targets:
//THIS IS TEMPORARY. YEAH RIGHT //THIS IS TEMPORARY. YEAH RIGHT
if(!connection) return //~Carn if(!connection) return 0 //~Carn
Broadcast_Message(connection, M, voicemask, pick(M.speak_emote), return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name, src, message, displayname, jobname, real_name, M.voice_name,
filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking) filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
@@ -536,7 +537,7 @@
canhear_range = 3 canhear_range = 3
/obj/item/device/radio/borg/talk_into() /obj/item/device/radio/borg/talk_into()
..() . = ..()
if (isrobot(src.loc)) if (isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc var/mob/living/silicon/robot/R = src.loc
var/datum/robot_component/C = R.components["radio"] var/datum/robot_component/C = R.components["radio"]

View File

@@ -88,8 +88,7 @@ proc/get_radio_key_from_channel(var/channel)
src.custom_emote(1, "[pick(speaking.signlang_verb)].") src.custom_emote(1, "[pick(speaking.signlang_verb)].")
if (speaking.flags & SIGNLANG) if (speaking.flags & SIGNLANG)
say_signlang(message, pick(speaking.signlang_verb), speaking) return say_signlang(message, pick(speaking.signlang_verb), speaking)
return 1
//make sure the air can transmit speech //make sure the air can transmit speech
var/datum/gas_mixture/environment = T.return_air() var/datum/gas_mixture/environment = T.return_air()
@@ -154,6 +153,7 @@ proc/get_radio_key_from_channel(var/channel)
/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) /mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language)
for (var/mob/O in viewers(src, null)) for (var/mob/O in viewers(src, null))
O.hear_signlang(message, verb, language, src) O.hear_signlang(message, verb, language, src)
return 1
/obj/effect/speech_bubble /obj/effect/speech_bubble
var/mob/parent var/mob/parent

View File

@@ -39,48 +39,49 @@
else else
prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " " prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " "
if(src.say("[prefix]Current Active Laws:") != 1) var/can_state = statelaw("[prefix]Current Active Laws:")
return
//src.laws_sanity_check() //src.laws_sanity_check()
//src.laws.show_laws(world) //src.laws.show_laws(world)
var/number = 1 if (can_state && src.laws.zeroth)
sleep(10)
if (src.laws.zeroth)
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
src.say("[prefix]0. [src.laws.zeroth]") can_state = statelaw("[prefix]0. [src.laws.zeroth]")
sleep(10)
for (var/index = 1, index <= src.laws.ion.len, index++) for (var/index = 1, can_state && index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index] var/law = src.laws.ion[index]
var/num = ionnum() var/num = ionnum()
if (length(law) > 0) if (length(law) > 0)
if (src.ioncheck[index] == "Yes") if (src.ioncheck[index] == "Yes")
src.say("[prefix][num]. [law]") can_state = statelaw("[prefix][num]. [law]")
sleep(10)
for (var/index = 1, index <= src.laws.inherent.len, index++) var/number = 1
for (var/index = 1, can_state && index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index] var/law = src.laws.inherent[index]
if (length(law) > 0) if (length(law) > 0)
if (src.lawcheck[index+1] == "Yes") if (src.lawcheck[index+1] == "Yes")
src.say("[prefix][number]. [law]") can_state = statelaw("[prefix][number]. [law]")
sleep(10)
number++ number++
for (var/index = 1, index <= src.laws.supplied.len, index++) for (var/index = 1, can_state && index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index] var/law = src.laws.supplied[index]
if (length(law) > 0) if (length(law) > 0)
if(src.lawcheck.len >= number+1) if(src.lawcheck.len >= number+1)
if (src.lawcheck[number+1] == "Yes") if (src.lawcheck[number+1] == "Yes")
src.say("[prefix][number]. [law]") can_state = statelaw("[prefix][number]. [law]")
sleep(10)
number++ number++
if(!can_state)
src << "<span class='danger'>Unable to state laws. Communication method unavailable.</span>"
stating_laws = 0 stating_laws = 0
/mob/living/silicon/proc/statelaw(var/law)
if(src.say(law))
sleep(10)
return 1
return 0
/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite /mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>" var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"

View File

@@ -25,14 +25,14 @@
/mob/living/silicon/say(var/message) /mob/living/silicon/say(var/message)
if (!message) if (!message)
return return 0
if (src.client) if (src.client)
if(client.prefs.muted & MUTE_IC) if(client.prefs.muted & MUTE_IC)
src << "You cannot send IC messages (muted)." src << "You cannot send IC messages (muted)."
return return 0
if (src.client.handle_spam_prevention(message,MUTE_IC)) if (src.client.handle_spam_prevention(message,MUTE_IC))
return return 0
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
@@ -56,7 +56,7 @@
//Must be concious to speak //Must be concious to speak
if (stat) if (stat)
return return 0
var/verb = say_quote(message) var/verb = say_quote(message)
@@ -105,13 +105,12 @@
return AI.holopad_talk(message) return AI.holopad_talk(message)
if(IS_ROBOT) if(IS_ROBOT)
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,message_mode,verb,speaking) return R.radio.talk_into(src,message,message_mode,verb,speaking)
if(IS_PAI) if(IS_PAI)
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,message_mode,verb,speaking) return P.radio.talk_into(src,message,message_mode,verb,speaking)
return 1 return 0
return 1
if("general") if("general")
switch(bot_type) switch(bot_type)
if(IS_AI) if(IS_AI)
@@ -120,14 +119,14 @@
return 0 return 0
else else
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
AI.aiRadio.talk_into(src,message,null,verb,speaking) return AI.aiRadio.talk_into(src,message,null,verb,speaking)
if(IS_ROBOT) if(IS_ROBOT)
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,null,verb,speaking) return R.radio.talk_into(src,message,null,verb,speaking)
if(IS_PAI) if(IS_PAI)
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,null,verb,speaking) return P.radio.talk_into(src,message,null,verb,speaking)
return 1 return 0
else else
if(message_mode) if(message_mode)
@@ -138,14 +137,14 @@
return 0 return 0
else else
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
AI.aiRadio.talk_into(src,message,message_mode,verb,speaking) return AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
if(IS_ROBOT) if(IS_ROBOT)
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,message_mode,verb,speaking) return R.radio.talk_into(src,message,message_mode,verb,speaking)
if(IS_PAI) if(IS_PAI)
log_say("[key_name(src)] : [message]") log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,message_mode,verb,speaking) return P.radio.talk_into(src,message,message_mode,verb,speaking)
return 1 return 0
return ..(message,speaking,verb) return ..(message,speaking,verb)

View File

@@ -1,8 +1,3 @@
#define APC_WIRE_IDSCAN 1
#define APC_WIRE_MAIN_POWER1 2
#define APC_WIRE_MAIN_POWER2 3
#define APC_WIRE_AI_CONTROL 4
//update_state //update_state
#define UPSTATE_CELL_IN 1 #define UPSTATE_CELL_IN 1
#define UPSTATE_OPENED1 2 #define UPSTATE_OPENED1 2
@@ -821,6 +816,8 @@
return 0 return 0
if(!user.client) if(!user.client)
return 0 return 0
if(inoperable())
return 0
if(!user.IsAdvancedToolUser()) if(!user.IsAdvancedToolUser())
user << "<span class='warning'>You don't have the dexterity to use [src]!</span>" user << "<span class='warning'>You don't have the dexterity to use [src]!</span>"
return 0 return 0
@@ -859,13 +856,14 @@
return 0 return 0
return 1 return 1
/obj/machinery/power/apc/Topic(href, href_list) /obj/machinery/power/apc/Topic(href, href_list, var/nowindow = 0)
if(..()) if(!nowindow && ..())
return 0 return 0
if(!can_use(usr, 1)) if(!can_use(usr, 1))
return 0 return 0
add_fingerprint(usr)
if (href_list["lock"]) if (href_list["lock"])
coverlocked = !coverlocked coverlocked = !coverlocked