mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 07:08:00 +01:00
[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:
co-authored by
Tim
Zonespace
Gandalf
parent
3bdc4eb844
commit
eb96261bf7
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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?"))
|
||||
|
||||
@@ -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!"))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]"
|
||||
|
||||
Reference in New Issue
Block a user