[MIRROR] New illiterate quirk [MDB IGNORE] (#13846)

* New illiterate quirk

* Update health_analyzer.dm

* Update health_analyzer.dm

Co-authored-by: Tim <timothymtorres@gmail.com>
Co-authored-by: Zonespace <41448081+Zonespace27@users.noreply.github.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
This commit is contained in:
SkyratBot
2022-05-24 16:33:47 +01:00
committed by GitHub
co-authored by Tim Zonespace Gandalf
parent 3bdc4eb844
commit eb96261bf7
30 changed files with 180 additions and 117 deletions
+2
View File
@@ -38,3 +38,5 @@
#define INTERACT_MACHINE_SET_MACHINE (1<<6)
/// the user must have vision to interact (blind people need not apply)
#define INTERACT_MACHINE_REQUIRES_SIGHT (1<<7)
/// the user must be able to read to interact
#define INTERACT_MACHINE_REQUIRES_LITERACY (1<<8)
+1
View File
@@ -140,6 +140,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_INCAPACITATED "incapacitated"
/// In some kind of critical condition. Is able to succumb.
#define TRAIT_CRITICAL_CONDITION "critical-condition"
#define TRAIT_ILLITERATE "illiterate"
#define TRAIT_BLIND "blind"
#define TRAIT_MUTE "mute"
#define TRAIT_EMOTEMUTE "emotemute"
+1
View File
@@ -155,6 +155,7 @@ DEFINE_BITFIELD(interaction_flags_machine, list(
"INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN,
"INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON,
"INTERACT_MACHINE_REQUIRES_SIGHT" = INTERACT_MACHINE_REQUIRES_SIGHT,
"INTERACT_MACHINE_REQUIRES_LITERACY" = INTERACT_MACHINE_REQUIRES_LITERACY,
"INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON,
"INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE,
"INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN,
+1
View File
@@ -13,6 +13,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_RESTRAINED" = TRAIT_RESTRAINED,
"TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_ILLITERATE" = TRAIT_ILLITERATE,
"TRAIT_BLIND" = TRAIT_BLIND,
"TRAIT_MUTE" = TRAIT_MUTE,
"TRAIT_EMOTEMUTE " = TRAIT_EMOTEMUTE,
+15
View File
@@ -300,3 +300,18 @@
/datum/brain_trauma/severe/hypnotic_trigger/proc/hypnotrigger()
to_chat(owner, span_warning("The words trigger something deep within you, and you feel your consciousness slipping away..."))
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
/datum/brain_trauma/severe/dyslexia
name = "Dyslexia"
desc = "Patient is unable to read or write."
scan_desc = "dyslexia"
gain_text = "<span class='warning'>You have trouble reading or writing...</span>"
lose_text = "<span class='notice'>Your suddenly remember how to read and write.</span>"
/datum/brain_trauma/severe/dyslexia/on_gain()
ADD_TRAIT(owner, TRAIT_ILLITERATE, TRAUMA_TRAIT)
..()
/datum/brain_trauma/severe/dyslexia/on_lose()
REMOVE_TRAIT(owner, TRAIT_ILLITERATE, TRAUMA_TRAIT)
..()
+9
View File
@@ -897,3 +897,12 @@
return TRUE
return FALSE
/datum/quirk/illiterate
name = "Illiterate"
desc = "You dropped out of school and are unable to read or write. This affects reading, writing, using computers and other electronics."
icon = "graduation-cap"
value = -8
mob_trait = TRAIT_ILLITERATE
medical_record_text = "Patient is not literate."
hardcore_value = 8
+5 -1
View File
@@ -130,7 +130,7 @@
var/subsystem_type = /datum/controller/subsystem/machines
var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created
var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN|INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_OPEN_SILICON|INTERACT_MACHINE_SET_MACHINE
var/fair_market_price = 69
var/market_verb = "Customer"
var/payment_department = ACCOUNT_ENG
@@ -562,6 +562,10 @@
to_chat(user, span_warning("This machine requires sight to use."))
return FALSE
// machines have their own lit up display screens and LED buttons so we don't need to check for light
if((interaction_flags_machine & INTERACT_MACHINE_REQUIRES_LITERACY) && !user.can_read(src, check_for_light = FALSE))
return FALSE
if(panel_open && !(interaction_flags_machine & INTERACT_MACHINE_OPEN))
return FALSE
@@ -6,6 +6,7 @@
max_integrity = 200
integrity_failure = 0.5
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 40, ACID = 20)
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_SET_MACHINE|INTERACT_MACHINE_REQUIRES_LITERACY
var/brightness_on = 1
var/icon_keyboard = "generic_key"
var/icon_screen = "generic"
@@ -71,6 +71,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
icon_keyboard = null
icon_screen = "invaders"
light_color = LIGHT_COLOR_GREEN
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_SET_MACHINE // we don't need to be literate to play video games fam
var/list/prize_override
/obj/machinery/computer/arcade/proc/Reset()
+1 -1
View File
@@ -21,7 +21,7 @@
var/list/cam_plane_masters
var/atom/movable/screen/background/cam_background
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_SET_MACHINE | INTERACT_MACHINE_REQUIRES_SIGHT
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_SET_MACHINE|INTERACT_MACHINE_REQUIRES_SIGHT
/obj/machinery/computer/security/Initialize(mapload)
. = ..()
@@ -12,6 +12,7 @@
armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 50, ACID = 30)
max_integrity = 200
integrity_failure = 0.25
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_SET_MACHINE|INTERACT_MACHINE_REQUIRES_LITERACY
///Reference to the currently logged in user.
var/datum/bank_account/current_user
///Name of the logged in user.
+5 -8
View File
@@ -33,10 +33,8 @@
return(TOXLOSS)
/obj/item/newspaper/attack_self(mob/user)
if(!ishuman(user))
to_chat(user, span_warning("The paper is full of unintelligible symbols!"))
if(!istype(user) || !user.can_read(src))
return
var/mob/living/carbon/human/human_user = user
var/dat
pages = 0
switch(screen)
@@ -61,7 +59,7 @@
dat+="</ul>"
if(scribble_page==curr_page)
dat+="<BR><I>There is a small scribble near the end of this page... It reads: \"[scribble]\"</I>"
dat+= "<HR><DIV STYLE='float:right;'><A href='?src=[REF(src)];next_page=1'>Next Page</A></DIV> <div style='float:left;'><A href='?src=[REF(human_user)];mach_close=newspaper_main'>Done reading</A></DIV>"
dat+= "<HR><DIV STYLE='float:right;'><A href='?src=[REF(src)];next_page=1'>Next Page</A></DIV> <div style='float:left;'><A href='?src=[REF(user)];mach_close=newspaper_main'>Done reading</A></DIV>"
if(1) // X channel pages inbetween.
for(var/datum/feed_channel/NP in news_content)
pages++
@@ -110,8 +108,8 @@
dat+="<BR><I>There is a small scribble near the end of this page... It reads: \"[scribble]\"</I>"
dat+= "<HR><DIV STYLE='float:left;'><A href='?src=[REF(src)];prev_page=1'>Previous Page</A></DIV>"
dat+="<BR><HR><div align='center'>[curr_page+1]</div>"
human_user << browse(dat, "window=newspaper_main;size=300x400")
onclose(human_user, "newspaper_main")
user << browse(dat, "window=newspaper_main;size=300x400")
onclose(user, "newspaper_main")
/obj/item/newspaper/proc/notContent(list/L)
if(!L.len)
@@ -160,8 +158,7 @@
return
if(istype(W, /obj/item/pen))
if(!user.is_literate())
to_chat(user, span_notice("You scribble illegibly on [src]!"))
if(!user.can_write(W))
return
if(scribble_page == curr_page)
to_chat(user, span_warning("There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?"))
+9
View File
@@ -686,6 +686,9 @@
/obj/item/card/id/examine(mob/user)
. = ..()
if(!user.can_read(src))
return
if(registered_account)
. += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of [registered_account.account_balance] cr."
if((ACCESS_COMMAND in access) || (ACCESS_QM in access))
@@ -697,6 +700,9 @@
. += span_notice("<i>There's more information below, you can look again to take a closer look...</i>")
/obj/item/card/id/examine_more(mob/user)
if(!user.can_read(src))
return
. = ..()
. += span_notice("<i>You examine [src] closer, and note the following...</i>")
@@ -1176,6 +1182,9 @@
/obj/item/card/id/advanced/prisoner/examine(mob/user)
. = ..()
if(!.)
return
if(timed)
if(time_left <= 0)
. += span_notice("The digital timer on the card has zero seconds remaining. You leave a changed man, but a free man nonetheless.")
@@ -38,46 +38,48 @@
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
..()
if(user.canUseTopic(src, BE_CLOSE))
if(cooldown)
to_chat(user, span_warning("[src]'s barometer function is preparing itself."))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_read(src))
return
if(cooldown)
to_chat(user, span_warning("[src]'s barometer function is preparing itself."))
return
var/turf/T = get_turf(user)
if(!T)
return
playsound(src, 'sound/effects/pop.ogg', 100)
var/area/user_area = T.loc
var/datum/weather/ongoing_weather = null
if(!user_area.outdoors)
to_chat(user, span_warning("[src]'s barometer function won't work indoors!"))
return
for(var/V in SSweather.processing)
var/datum/weather/W = V
if(W.barometer_predictable && (T.z in W.impacted_z_levels) && W.area_type == user_area.type && !(W.stage == END_STAGE))
ongoing_weather = W
break
if(ongoing_weather)
if((ongoing_weather.stage == MAIN_STAGE) || (ongoing_weather.stage == WIND_DOWN_STAGE))
to_chat(user, span_warning("[src]'s barometer function can't trace anything while the storm is [ongoing_weather.stage == MAIN_STAGE ? "already here!" : "winding down."]"))
return
var/turf/T = get_turf(user)
if(!T)
return
playsound(src, 'sound/effects/pop.ogg', 100)
var/area/user_area = T.loc
var/datum/weather/ongoing_weather = null
if(!user_area.outdoors)
to_chat(user, span_warning("[src]'s barometer function won't work indoors!"))
return
for(var/V in SSweather.processing)
var/datum/weather/W = V
if(W.barometer_predictable && (T.z in W.impacted_z_levels) && W.area_type == user_area.type && !(W.stage == END_STAGE))
ongoing_weather = W
break
if(ongoing_weather)
if((ongoing_weather.stage == MAIN_STAGE) || (ongoing_weather.stage == WIND_DOWN_STAGE))
to_chat(user, span_warning("[src]'s barometer function can't trace anything while the storm is [ongoing_weather.stage == MAIN_STAGE ? "already here!" : "winding down."]"))
return
to_chat(user, span_notice("The next [ongoing_weather] will hit in [butchertime(ongoing_weather.next_hit_time - world.time)]."))
if(ongoing_weather.aesthetic)
to_chat(user, span_warning("[src]'s barometer function says that the next storm will breeze on by."))
to_chat(user, span_notice("The next [ongoing_weather] will hit in [butchertime(ongoing_weather.next_hit_time - world.time)]."))
if(ongoing_weather.aesthetic)
to_chat(user, span_warning("[src]'s barometer function says that the next storm will breeze on by."))
else
var/next_hit = SSweather.next_hit_by_zlevel["[T.z]"]
var/fixed = next_hit ? timeleft(next_hit) : -1
if(fixed < 0)
to_chat(user, span_warning("[src]'s barometer function was unable to trace any weather patterns."))
else
var/next_hit = SSweather.next_hit_by_zlevel["[T.z]"]
var/fixed = next_hit ? timeleft(next_hit) : -1
if(fixed < 0)
to_chat(user, span_warning("[src]'s barometer function was unable to trace any weather patterns."))
else
to_chat(user, span_warning("[src]'s barometer function says a storm will land in approximately [butchertime(fixed)]."))
cooldown = TRUE
addtimer(CALLBACK(src,/obj/item/analyzer/proc/ping), cooldown_time)
to_chat(user, span_warning("[src]'s barometer function says a storm will land in approximately [butchertime(fixed)]."))
cooldown = TRUE
addtimer(CALLBACK(src,/obj/item/analyzer/proc/ping), cooldown_time)
/obj/item/analyzer/proc/ping()
if(isliving(loc))
@@ -112,17 +114,13 @@
return list("gasmixes" = last_gasmix_data)
/obj/item/analyzer/attack_self(mob/user, modifiers)
// Check if it requires visibility and if the user is you know, blind.
if (user.stat != CONSCIOUS || user.is_blind())
to_chat(user, span_warning("You're unable to see [src]'s results!"))
if(user.stat != CONSCIOUS || !user.can_read(src) || user.is_blind())
return
atmos_scan(user=user, target=get_turf(src), tool=src, silent=FALSE)
on_analyze(source=src, target=get_turf(src))
/obj/item/analyzer/attack_self_secondary(mob/user, modifiers)
// Check if it requires visibility and if the user is you know, blind.
if (user.stat != CONSCIOUS || user.is_blind())
to_chat(user, span_warning("You're unable to see [src]'s results!"))
if(user.stat != CONSCIOUS || !user.can_read(src) || user.is_blind())
return
ui_interact(user)
@@ -29,7 +29,6 @@
/obj/item/healthanalyzer/Initialize(mapload)
. = ..()
register_item_context()
/obj/item/healthanalyzer/examine(mob/user)
@@ -47,6 +46,9 @@
return BRUTELOSS
/obj/item/healthanalyzer/attack_self(mob/user)
if(!user.can_read(src) || user.is_blind())
return
scanmode = (scanmode + 1) % SCANMODE_COUNT
switch(scanmode)
if(SCANMODE_HEALTH)
@@ -59,6 +61,9 @@
if(!(item_use_power(power_use_amount, user, FALSE) & COMPONENT_POWER_SUCCESS))
return
//SKYRAT EDIT END
if(!user.can_read(src) || user.is_blind())
return
flick("[icon_state]-scan", src) //makes it so that it plays the scan animation upon scanning, including clumsy scanning
// Clumsiness/brain damage check
@@ -87,10 +92,9 @@
add_fingerprint(user)
/obj/item/healthanalyzer/attack_secondary(mob/living/victim, mob/living/user, params)
//SKYRAT EDIT ADDITION
if(!(item_use_power(power_use_amount, user) & COMPONENT_POWER_SUCCESS))
if(!user.can_read(src) || user.is_blind() || !(item_use_power(power_use_amount, user) & COMPONENT_POWER_SUCCESS)) // SKYRAT EDIT CHANGE
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
//SKYRAT EDIT END
chemscan(user, victim)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
@@ -117,10 +121,6 @@
if(user.incapacitated())
return
if(user.is_blind())
to_chat(user, span_warning("You realize that your scanner has no accessibility support for the blind!"))
return
// the final list of strings to render
var/render_list = list()
@@ -401,10 +401,6 @@
if(user.incapacitated())
return
if(user.is_blind())
to_chat(user, span_warning("You realize that your scanner has no accessibility support for the blind!"))
return
if(istype(target) && target.reagents)
var/render_list = list()
@@ -461,7 +457,7 @@
/obj/item/healthanalyzer/AltClick(mob/user)
..()
if(!user.canUseTopic(src, BE_CLOSE))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_read(src) || user.is_blind())
return
mode = !mode
@@ -479,10 +475,6 @@
if(!istype(patient) || user.incapacitated())
return
if(user.is_blind())
to_chat(user, span_warning("You realize that your scanner has no accessibility support for the blind!"))
return
var/render_list = ""
for(var/i in patient.get_wounded_bodyparts())
var/obj/item/bodypart/wounded_part = i
@@ -529,6 +521,9 @@
L.dropItemToGround(src)
/obj/item/healthanalyzer/wound/attack(mob/living/carbon/patient, mob/living/carbon/human/user)
if(!user.can_read(src) || user.is_blind())
return
add_fingerprint(user)
user.visible_message(span_notice("[user] scans [patient] for serious injuries."), span_notice("You scan [patient] for serious injuries."))
@@ -70,7 +70,7 @@
if(LAZYFIND(active_mutations, mutation))
to_chat(user, span_boldnotice("[get_display_name(mutation)]"))
else
to_chat(user, span_notice("[get_display_name(mutation)]"))
to_chat(user, span_notice("[get_display_name(mutation)]"))
/obj/item/sequence_scanner/proc/display_sequence(mob/living/user)
if(!LAZYLEN(buffer) || !ready)
@@ -82,25 +82,27 @@
var/answer = tgui_input_list(user, "Analyze Potential", "Sequence Analyzer", sort_list(options))
if(isnull(answer))
return
if(ready && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
var/sequence
for(var/mutation in buffer) //this physically hurts but i dont know what anything else short of an assoc list
if(get_display_name(mutation) == answer)
sequence = buffer[mutation]
break
if(!ready || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) || !user.can_read(src))
return
if(sequence)
var/display
for(var/i in 0 to length_char(sequence) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext_char(sequence, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
var/sequence
for(var/mutation in buffer) //this physically hurts but i dont know what anything else short of an assoc list
if(get_display_name(mutation) == answer)
sequence = buffer[mutation]
break
to_chat(user, "[span_boldnotice("[display]")]<br>")
if(sequence)
var/display
for(var/i in 0 to length_char(sequence) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext_char(sequence, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
ready = FALSE
icon_state = "[icon_state]_recharging"
addtimer(CALLBACK(src, .proc/recharge), cooldown, TIMER_UNIQUE)
to_chat(user, "[span_boldnotice("[display]")]<br>")
ready = FALSE
icon_state = "[icon_state]_recharging"
addtimer(CALLBACK(src, .proc/recharge), cooldown, TIMER_UNIQUE)
/obj/item/sequence_scanner/proc/recharge()
icon_state = initial(icon_state)
@@ -14,7 +14,7 @@
custom_materials = list(/datum/material/iron=30, /datum/material/glass=20)
/obj/item/slime_scanner/attack(mob/living/M, mob/living/user)
if(user.stat || user.is_blind())
if(user.stat || !user.can_read(src) || user.is_blind())
return
if (!isslime(M))
to_chat(user, span_warning("This device can only scan slimes!"))
+2 -2
View File
@@ -51,14 +51,14 @@
/// When we attack something, first - try to scan something we hit with left click. Left-clicking uses scans for stats
/obj/item/plant_analyzer/pre_attack(atom/target, mob/living/user)
. = ..()
if(user.combat_mode)
if(user.combat_mode || !user.can_read(src))
return
return do_plant_stats_scan(target, user)
/// Same as above, but with right click. Right-clicking scans for chemicals.
/obj/item/plant_analyzer/pre_attack_secondary(atom/target, mob/living/user)
if(user.combat_mode)
if(user.combat_mode || !user.can_read(src))
return SECONDARY_ATTACK_CONTINUE_CHAIN
return do_plant_chem_scan(target, user) ? SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN : SECONDARY_ATTACK_CONTINUE_CHAIN
+7 -8
View File
@@ -129,25 +129,24 @@
/obj/item/book/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pen))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
if(user.is_blind())
to_chat(user, span_warning("As you are trying to write on the book, you suddenly feel very stupid!"))
return
if(unique)
to_chat(user, span_warning("These pages don't seem to take the ink well! Looks like you can't modify it."))
return
var/literate = user.is_literate()
if(!literate)
to_chat(user, span_notice("You scribble illegibly on the cover of [src]!"))
return
var/choice = tgui_input_list(usr, "What would you like to change?", "Book Alteration", list("Title", "Contents", "Author", "Cancel"))
if(isnull(choice))
return
if(!user.canUseTopic(src, BE_CLOSE, literate))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
switch(choice)
if("Title")
var/newtitle = reject_bad_text(tgui_input_text(user, "Write a new title", "Book Title", max_length = 30))
if(!user.canUseTopic(src, BE_CLOSE, literate))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
if (length_char(newtitle) > 30)
to_chat(user, span_warning("That title won't fit on the cover!"))
@@ -159,7 +158,7 @@
book_data.set_title(html_decode(newtitle)) //Don't want to double encode here
if("Contents")
var/content = tgui_input_text(user, "Write your book's contents (HTML NOT allowed)", "Book Contents", multiline = TRUE)
if(!user.canUseTopic(src, BE_CLOSE, literate))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
if(!content)
to_chat(user, span_warning("The content is invalid."))
@@ -167,7 +166,7 @@
book_data.set_content(html_decode(content))
if("Author")
var/author = tgui_input_text(user, "Write the author's name", "Author Name")
if(!user.canUseTopic(src, BE_CLOSE, literate))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
if(!author)
to_chat(user, span_warning("The name is invalid."))
+2 -3
View File
@@ -119,11 +119,10 @@
to_chat(user, span_notice("You empty \the [I] into \the [src]."))
update_appearance()
else if(istype(I, /obj/item/pen))
if(!user.is_literate())
to_chat(user, span_notice("You scribble illegibly on the side of [src]!"))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
var/newname = tgui_input_text(user, "What would you like to title this bookshelf?", "Bookshelf Renaming", max_length = MAX_NAME_LEN)
if(!user.canUseTopic(src, BE_CLOSE))
if(!user.canUseTopic(src, BE_CLOSE) || !user.can_write(I))
return
if(!newname)
return
+24
View File
@@ -89,6 +89,30 @@
to_chat(user, span_warning("You get the feeling you shouldn't mess with this."))
return
if(HAS_TRAIT(user, TRAIT_ILLITERATE))
to_chat(user, span_warning("You start mashing buttons at random!"))
if(do_after(user, 10 SECONDS, target = src))
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
if(no_destination_swap)
if(M.mode == SHUTTLE_RECHARGING)
to_chat(usr, span_warning("Shuttle engines are not ready for use."))
return
if(M.mode != SHUTTLE_IDLE)
to_chat(usr, span_warning("Shuttle already in transit."))
return
var/destionation = M.getDockedId() == "mining_home" ? "mining_away" : "mining_home"
switch(SSshuttle.moveShuttle(shuttleId, destionation, 1))
if(0)
say("Shuttle departing. Please stand away from the doors.")
log_shuttle("[key_name(usr)] has sent shuttle \"[M]\" towards \"[destionation]\", using [src].")
return TRUE
if(1)
to_chat(usr, span_warning("Invalid shuttle requested."))
else
to_chat(usr, span_warning("Unable to comply."))
return
return ..()
/obj/machinery/computer/shuttle/mining/common
+2 -2
View File
@@ -852,8 +852,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/is_literate()
return TRUE
/mob/dead/observer/can_read(obj/O)
return TRUE
/mob/dead/observer/can_read(obj/O, check_for_light = FALSE)
return TRUE // we want to bypass all the checks
/mob/dead/observer/vv_edit_var(var_name, var_value)
. = ..()
@@ -815,7 +815,7 @@
return ..()
/mob/living/carbon/human/is_literate()
return TRUE
return !HAS_TRAIT(src, TRAIT_ILLITERATE)
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
if(blood && (NOBLOOD in dna.species.species_traits) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
@@ -92,3 +92,4 @@
var/hal_screwydoll
/// When an braindead player has their equipment fiddled with, we log that info here for when they come back so they know who took their ID while they were DC'd for 30 seconds
var/list/afk_thefts
@@ -195,6 +195,7 @@ Lizard subspecies: ASHWALKERS
TRAIT_CAN_STRIP,
TRAIT_CHUNKYFINGERS,
TRAIT_VIRUSIMMUNE,
TRAIT_ILLITERATE,
)
species_language_holder = /datum/language_holder/lizard/ash
digitigrade_customization = DIGITIGRADE_FORCED
+4 -4
View File
@@ -13,10 +13,10 @@
if(fov_view && observed_atom.plane == GAME_PLANE_FOV_HIDDEN) //SKYRAT EDIT CHANGE
if(rel_x >= -1 && rel_x <= 1 && rel_y >= -1 && rel_y <= 1) //Cheap way to check inside that 3x3 box around you
return TRUE //Also checks if both are 0 to stop division by zero
// Get the vector length so we can create a good directional vector
var/vector_len = sqrt(abs(rel_x) ** 2 + abs(rel_y) ** 2)
/// Getting a direction vector
var/dir_x
var/dir_y
@@ -33,10 +33,10 @@
if(WEST)
dir_x = -vector_len
dir_y = 0
///Calculate angle
var/angle = arccos((dir_x * rel_x + dir_y * rel_y) / (sqrt(dir_x**2 + dir_y**2) * sqrt(rel_x**2 + rel_y**2)))
/// Calculate vision angle and compare
var/vision_angle = (360 - fov_view) / 2
if(angle < vision_angle)
+7 -3
View File
@@ -1187,7 +1187,11 @@
to_chat(src, span_warning("You can't write with the [writing_instrument]!"))
if(!is_literate())
to_chat(src, span_warning("You don't know how to write."))
to_chat(src, span_warning("You try to write, but don't know how to spell anything!"))
return FALSE
if(!has_light_nearby() && !has_nightvision())
to_chat(src, span_warning("It's too dark in here to write anything!"))
return FALSE
var/obj/item/pen/pen = writing_instrument
@@ -1215,12 +1219,12 @@
return mob_location.get_lumcount() > light_amount
/// Can this mob read
/mob/proc/can_read(obj/O)
/mob/proc/can_read(obj/O, check_for_light = TRUE)
if(!is_literate())
to_chat(src, span_warning("You try to read [O], but can't comprehend any of it."))
return FALSE
if(!has_light_nearby() && !has_nightvision())
if(check_for_light && !has_light_nearby() && !has_nightvision())
to_chat(src, span_warning("It's too dark in here to read!"))
return FALSE
+1 -1
View File
@@ -36,7 +36,7 @@
. = ..()
if(!.)
return
if(!isliving(target))
if(!isliving(target) || !mod.wearer.can_read(src))
return
switch(mode)
if(HEALTH_SCAN)
@@ -13,6 +13,9 @@
ui.close()
return
if(!user.can_read(src, check_for_light = FALSE))
return
if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS) && !allow_chunky)
to_chat(user, span_warning("Your fingers are too big to use this right now!"))
return
-5
View File
@@ -192,14 +192,11 @@
return UI_INTERACTIVE
return ..()
/obj/item/paper/can_interact(mob/user)
if(in_contents_of(/obj/machinery/door/airlock))
return TRUE
return ..()
/obj/item/proc/burn_paper_product_attackby_check(obj/item/I, mob/living/user, bypass_clumsy)
var/ignition_message = I.ignition_effect(src, user)
if(!ignition_message)
@@ -270,7 +267,6 @@
return ..()
/obj/item/paper/fire_act(exposed_temperature, exposed_volume)
. = ..()
if(.)
@@ -313,7 +309,6 @@
.["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling?
.["stamps"] = stamps
/obj/item/paper/ui_data(mob/user)
var/list/data = list()
data["edit_usr"] = "[user.real_name]"