Files
Aurora.3/code/modules/mob/living/silicon/silicon.dm
Matt Atlas 556f1aa86f Fullscreen overlay rework, full-black unconsciousness overlay, overlay fadeout animations + more. (#10053)
Ported the clickcatcher from tg/bay. You can now click black spots to turn. Isn't that handy, especially with vision cones.

    Reworked fullscreen overlays into an easier and better system, courtesy of PsiOmegaDelta.

    Similiarly, added fadeout animations to all pain overlays, plus unconsciousness.

    Fixed the vampire frenzy overlay never showing.

    Unconsciousness is now FULL darkness.

    Flashing mobs is now an inbuilt proc.
2020-10-02 08:53:14 +03:00

406 lines
12 KiB
Plaintext

#define NO_HUD 0
#define SEC_HUD 1
#define MED_HUD 2
/mob/living/silicon
// Speaking
gender = NEUTER
voice_name = "Synthesized Voice"
accent = ACCENT_TTS
can_have_vision_cone = TRUE
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/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()
// 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,
/mob/living/silicon/proc/silicon_mimic_accent
)
// Utility
var/obj/item/device/camera/siliconcam/ai_camera //photography
// ID and Access
var/list/access_rights
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
/mob/living/silicon/Initialize()
silicon_mob_list |= src
. = ..()
add_language(LANGUAGE_TCB)
init_id()
var/datum/language/L = locate(/datum/language/common) in languages
default_language = L
init_subsystems()
/mob/living/silicon/Destroy()
silicon_mob_list -= src
QDEL_NULL(computer)
QDEL_NULL(rcon)
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(id_card)
return
id_card = new id_card_type(src)
set_id_info(id_card)
/mob/living/silicon/proc/SetName(pickedName as text)
real_name = pickedName
name = real_name
/mob/living/silicon/proc/show_laws()
return
/mob/living/silicon/drop_item()
return
/mob/living/silicon/emp_act(severity)
switch(severity)
if(1)
src.take_organ_damage(0, 20, emp = TRUE)
Stun(rand(5, 10))
if(2)
src.take_organ_damage(0, 10, emp = TRUE)
Stun(rand(1, 5))
flash_eyes(affect_silicon = 1)
to_chat(src, SPAN_DANGER("BZZZT"))
to_chat(src, SPAN_WARNING("Warning: Electromagnetic pulse detected."))
..()
/mob/living/silicon/stun_effect_act()
return //immune
/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_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
/mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0)
return
/mob/living/silicon/IsAdvancedToolUser()
return TRUE
/mob/living/silicon/bullet_act(obj/item/projectile/Proj)
if(!Proj.nodamage)
switch(Proj.damage_type)
if(BRUTE)
adjustBruteLoss(Proj.damage)
if(BURN)
adjustFireLoss(Proj.damage)
Proj.on_hit(src, 100)
updatehealth()
return 100
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
return FALSE
/proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai)
if(!istype(bot) || !istype(ai))
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(!stat)
stat(null, text("System Integrity: [round((health/maxHealth)*100)]%"))
else
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 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()
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
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"))
show_emergency_shuttle_eta()
show_system_integrity()
show_malf_ai()
..()
// this function displays the stations manifest in a separate window
/mob/living/silicon/proc/show_station_manifest()
var/dat
dat += "<h4>Crew Manifest</h4>"
dat += SSrecords.get_manifest(1) // make it monochrome
dat += "<br>"
src << browse(dat, "window=airoster")
onclose(src, "airoster")
//can't inject synths
/mob/living/silicon/can_inject(mob/user, error_msg)
if(error_msg)
to_chat(user, SPAN_ALERT("The armored 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
/mob/living/silicon/add_language(var/language, var/can_speak=1)
var/datum/language/added_language = all_languages[language]
if(!added_language)
return
. = ..(language)
if(can_speak && (added_language in languages) && !(added_language in speech_synthesizer_langs))
speech_synthesizer_langs += added_language
return TRUE
/mob/living/silicon/remove_language(var/rem_language)
var/datum/language/removed_language = all_languages[rem_language]
if(!removed_language)
return
..(rem_language)
speech_synthesizer_langs -= removed_language
/mob/living/silicon/check_languages()
set name = "Check Known Languages"
set category = "IC"
set src = usr
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
if(default_language)
dat += "Current default language: [default_language] - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a><br/><br/>"
for(var/datum/language/L in languages)
if(!(L.flags & NONGLOBAL))
var/default_str
if(L == default_language)
default_str = " - default - <a href='byond://?src=\ref[src];default_lang=reset'>reset</a>"
else
default_str = " - <a href='byond://?src=\ref[src];default_lang=\ref[L]'>set default</a>"
var/synth = (L in speech_synthesizer_langs)
dat += "<b>[L.name] ([get_language_prefix()][L.key])</b>[synth ? default_str : null]<br/>Speech Synthesizer: <i>[synth ? "YES" : "NOT SUPPORTED"]</i><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
return
/mob/living/silicon/proc/toggle_sensor_mode()
var/sensor_type = input(src, "Please select sensor type.", "Sensor Integration") in list("Security", "Medical", "Disable")
switch(sensor_type)
if("Security")
sensor_mode = SEC_HUD
to_chat(src, SPAN_NOTICE("Security records overlay enabled."))
if("Medical")
sensor_mode = MED_HUD
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)
/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)
/mob/living/silicon/binarycheck()
return TRUE
/mob/living/silicon/ex_act(severity)
if(!blinded)
flick("flash", flash)
var/brute
var/burn
switch(severity)
if(1.0)
brute = 400
burn = 100
if(!anchored && !prob(getarmor(null, "bomb")))
gib()
if(2.0)
brute = 60
burn = 60
if(3.0)
brute = 30
var/protection = BLOCKED_MULT(getarmor(null, "bomb"))
brute *= protection
burn *= protection
adjustBruteLoss(brute)
adjustFireLoss(burn)
updatehealth()
/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
if(!next_alarm_notice)
next_alarm_notice = world.time + SecondsToTicks(10)
var/list/alarms = queued_alarms[alarm_handler]
if(was_raised)
// Raised alarms are always set
alarms[alarm] = 1
else
// Alarms that were raised but then cleared before the next notice are instead removed
if(alarm in alarms)
alarms -= alarm
// And alarms that have only been cleared thus far are set as such
else
alarms[alarm] = -1
/mob/living/silicon/proc/process_queued_alarms()
if(next_alarm_notice && (world.time > next_alarm_notice))
next_alarm_notice = 0
var/alarm_raised = FALSE
for(var/datum/alarm_handler/AH in queued_alarms)
var/list/alarms = queued_alarms[AH]
var/reported = FALSE
for(var/datum/alarm/A in alarms)
if(alarms[A] == 1)
alarm_raised = TRUE
if(!reported)
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 = FALSE
for(var/datum/alarm/A in alarms)
if(alarms[A] == -1)
if(!reported)
reported = TRUE
to_chat(src, SPAN_NOTICE("--- [AH.category] Cleared ---"))
to_chat(src, "\The [A.alarm_name()].")
if(alarm_raised)
to_chat(src, "<A HREF=?src=\ref[src];showalerts=1>\[Show Alerts\]</A>")
for(var/datum/alarm_handler/AH in queued_alarms)
var/list/alarms = queued_alarms[AH]
alarms.Cut()
/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A)
to_chat(src, "[A.alarm_name()]!")
/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A)
var/cameratext = ""
for(var/obj/machinery/camera/C in A.cameras())
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>"
to_chat(src, "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])")
/mob/living/silicon/proc/is_traitor()
return mind && (mind in traitors.current_antagonists)
/mob/living/silicon/proc/is_malf()
return mind && (mind in malf.current_antagonists)
/mob/living/silicon/proc/is_malf_or_traitor()
return is_traitor() || is_malf()
/mob/living/silicon/adjustEarDamage()
return
/mob/living/silicon/setEarDamage()
return
/mob/living/silicon/reset_view()
..()
if(cameraFollow)
cameraFollow = null
/mob/living/silicon/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
if(affect_silicon)
return ..()
/mob/living/silicon/seizure()
flash_eyes(affect_silicon = TRUE)
/mob/living/silicon/Move(newloc, direct)
. = ..()
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)
spawn(3)//A slight delay to let us finish walking out from under the door
layer = initial(layer)
/mob/living/silicon/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL