Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into station_traits
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
//Datums for barks and bark accessories
|
||||
|
||||
/datum/bark
|
||||
var/name = "Default"
|
||||
var/id = "Default"
|
||||
var/soundpath //Path for the actual sound file used for the bark
|
||||
|
||||
// Pitch vars. The actual range for a bark is [(pitch - (maxvariance*0.5)) to (pitch + (maxvariance*0.5))]
|
||||
// Make absolutely sure to take variance into account when curating a sound for bark purposes.
|
||||
var/minpitch = BARK_DEFAULT_MINPITCH
|
||||
var/maxpitch = BARK_DEFAULT_MAXPITCH
|
||||
var/minvariance = BARK_DEFAULT_MINVARY
|
||||
var/maxvariance = BARK_DEFAULT_MAXVARY
|
||||
|
||||
// Speed vars. Speed determines the number of characters required for each bark, with lower speeds being faster with higher bark density
|
||||
var/minspeed = BARK_DEFAULT_MINSPEED
|
||||
var/maxspeed = BARK_DEFAULT_MAXSPEED
|
||||
|
||||
// Visibility vars. Regardless of what's set below, these can still be obtained via adminbus and genetics. Rule of fun.
|
||||
var/list/ckeys_allowed
|
||||
var/ignore = FALSE //Controls whether or not this can be chosen in chargen
|
||||
var/allow_random = FALSE //Allows chargen randomization to use this. This is mainly to restrict the pool to sounds that fit well for most characters
|
||||
|
||||
|
||||
// So the basic jist of the sound design here: We make use primarily of shorter instrument samples for barks. We would've went with animalese instead, but doing so would've involved quite a bit of overhead to saycode.
|
||||
// Short instrument samples tend to sound surprisingly nice for barks, being able to be played in rapid succession without being outright obnoxious.
|
||||
// It isn't just instruments that work well here, however. Anything that works well as a stab? Short attack, no sustain, a decent amount of release? Also works extremely well for barks.
|
||||
|
||||
/datum/bark/mutedc2
|
||||
name = "Muted String (Low)"
|
||||
id = "mutedc2"
|
||||
soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/mutedc3
|
||||
name = "Muted String (Medium)"
|
||||
id = "mutedc3"
|
||||
soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/mutedc4
|
||||
name = "Muted String (High)"
|
||||
id = "mutedc4"
|
||||
soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/banjoc3
|
||||
name = "Banjo (Medium)"
|
||||
id = "banjoc3"
|
||||
soundpath = 'sound/instruments/banjo/Cn3.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/banjoc4
|
||||
name = "Banjo (High)"
|
||||
id = "banjoc4"
|
||||
soundpath = 'sound/instruments/banjo/Cn4.ogg'
|
||||
allow_random = TRUE
|
||||
|
||||
/datum/bark/squeaky
|
||||
name = "Squeaky"
|
||||
id = "squeak"
|
||||
soundpath = 'sound/items/toysqueak1.ogg'
|
||||
maxspeed = 4
|
||||
|
||||
/datum/bark/beep
|
||||
name = "Beepy"
|
||||
id = "beep"
|
||||
soundpath = 'sound/machines/terminal_select.ogg'
|
||||
maxpitch = 1 //Bringing the pitch higher just hurts your ears :<
|
||||
maxspeed = 4 //This soundbyte's too short for larger speeds to not sound awkward
|
||||
|
||||
/datum/bark/chitter
|
||||
name = "Chittery"
|
||||
id = "chitter"
|
||||
minspeed = 4 //Even with the sound being replaced with a unique, shorter sound, this is still a little too long for higher speeds
|
||||
soundpath = 'sound/voice/barks/chitter.ogg'
|
||||
|
||||
/datum/bark/synthetic_grunt
|
||||
name = "Synthetic (Grunt)"
|
||||
id = "synthgrunt"
|
||||
soundpath = 'sound/misc/bloop.ogg'
|
||||
|
||||
/datum/bark/synthetic
|
||||
name = "Synthetic (Normal)"
|
||||
id = "synth"
|
||||
soundpath = 'sound/machines/uplinkerror.ogg'
|
||||
|
||||
/datum/bark/bullet
|
||||
name = "Windy"
|
||||
id = "bullet"
|
||||
maxpitch = 1.6 //This works well with higher pitches!
|
||||
soundpath = 'sound/weapons/bulletflyby.ogg' //This works... Surprisingly well as a bark? It's neat!
|
||||
|
||||
/datum/bark/coggers
|
||||
name = "Brassy"
|
||||
id = "coggers"
|
||||
soundpath = 'sound/machines/clockcult/integration_cog_install.ogg' //Yet another unexpectedly good bark sound
|
||||
|
||||
|
||||
// Genetics-only/admin-only sounds. These either clash hard with the audio design of the above sounds, or have some other form of audio design issue, but aren't *too* awful as a sometimes thing.
|
||||
// Rule of fun very much applies to this section. Audio design is extremely important for the above section, but down here? No gods, no masters, pure anarchy.
|
||||
// The min/max variables simply don't apply to these, as only chargen cares about them. As such, there's no need to define those.
|
||||
|
||||
/datum/bark/bikehorn
|
||||
name = "Bikehorn"
|
||||
id = "horn"
|
||||
soundpath = 'sound/instruments/bikehorn/Cn4.ogg'
|
||||
ignore = TRUE // This is an unusually quiet sound.
|
||||
|
||||
/datum/bark/bwoink
|
||||
name = "Bwoink"
|
||||
id = "bwoink"
|
||||
soundpath = 'sound/effects/adminhelp.ogg'
|
||||
ignore = TRUE // Emergent heart attack generation
|
||||
|
||||
/datum/bark/merp
|
||||
name = "Merp"
|
||||
id = "merp"
|
||||
soundpath = 'modular_citadel/sound/voice/merp.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/bark
|
||||
name = "Bark"
|
||||
id = "bark"
|
||||
soundpath = 'modular_citadel/sound/voice/bark1.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/nya
|
||||
name = "Nya"
|
||||
id = "nya"
|
||||
soundpath = 'modular_citadel/sound/voice/nya.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/moff
|
||||
name = "Moff"
|
||||
id = "moff"
|
||||
soundpath = 'modular_citadel/sound/voice/mothsqueak.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/weh
|
||||
name = "Weh"
|
||||
id = "weh"
|
||||
soundpath = 'modular_citadel/sound/voice/weh.ogg'
|
||||
ignore = TRUE
|
||||
|
||||
/datum/bark/honk
|
||||
name = "Annoying Honk"
|
||||
id = "honk"
|
||||
soundpath = 'sound/creatures/goose1.ogg'
|
||||
ignore = TRUE
|
||||
@@ -123,7 +123,7 @@
|
||||
trauma = _trauma
|
||||
return ..()
|
||||
|
||||
/mob/living/split_personality/BiologicalLife(seconds, times_fired)
|
||||
/mob/living/split_personality/BiologicalLife(delta_time, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(QDELETED(body))
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
message.maptext_height = mheight
|
||||
message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5
|
||||
message.maptext = MAPTEXT(complete_text)
|
||||
message.pixel_x = -owner.pixel_x //Dogborgs and other wide boys have a pixel offset. This accounts for that
|
||||
|
||||
// View the message
|
||||
LAZYADDASSOC(owned_by.seen_messages, message_loc, src)
|
||||
@@ -174,10 +175,6 @@
|
||||
scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
enter_subsystem()
|
||||
|
||||
var/mob/living/silicon/robot/R = target
|
||||
if(iscyborg(R))
|
||||
if((R.module.dogborg == TRUE || R.dogborg == TRUE) && isturf(R.loc)) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good
|
||||
message.pixel_x = 16
|
||||
|
||||
/**
|
||||
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/atom/movable/A = parent
|
||||
switch(rand(1, 3))
|
||||
if(1)
|
||||
A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14)
|
||||
A.do_jiggle(25 + rand(-5, 5) * bouncy_mod, 14)
|
||||
if(2)
|
||||
var/min_b = 0.6/bouncy_mod
|
||||
var/max_b = 1.2 * bouncy_mod
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
name = "tea cup"
|
||||
desc = "A glass cup made for sipping tea!"
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "tea_plate"
|
||||
icon_state = "tea_cup"
|
||||
|
||||
//////////////////////Chem Disk/////////////////////
|
||||
//Two Steps //
|
||||
@@ -145,7 +145,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part5
|
||||
name = "unpolished glass lens"
|
||||
name = "unpolished glass (lens)"
|
||||
desc = "An unpolished glass lens. It needs to be polished with some dry cloth."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
@@ -159,7 +159,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part6
|
||||
name = "unrefined glass lens"
|
||||
name = "unrefined glass (lens)"
|
||||
desc = "A polished glass lens. It needs to be refined with some sandstone."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
@@ -179,7 +179,7 @@
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty
|
||||
name = "Glass fodder sheet (spout)"
|
||||
desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to heated with something very hot."
|
||||
desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to be cut with some glassworking tools."
|
||||
next_step = /obj/item/glasswork/glass_base/spouty_part2
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params)
|
||||
@@ -413,7 +413,7 @@
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cupe2
|
||||
/obj/item/glasswork/glass_base/tea_cup2
|
||||
name = "glassblowing rod (tea cup)"
|
||||
desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools."
|
||||
icon_state = "blowing_rods_inuse"
|
||||
@@ -433,7 +433,7 @@
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_cup4
|
||||
|
||||
/obj/item/glasswork/glass_base/cup3/attackby(obj/item/I, mob/user, params)
|
||||
/obj/item/glasswork/glass_base/tea_cup3/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/cloth))
|
||||
if(do_after(user,10, target = src))
|
||||
@@ -446,7 +446,7 @@
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/tea_cup
|
||||
|
||||
/obj/item/glasswork/glass_base/cup4/attackby(obj/item/I, mob/user, params)
|
||||
/obj/item/glasswork/glass_base/tea_cup4/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
if(do_after(user,10, target = src))
|
||||
|
||||
@@ -346,9 +346,9 @@
|
||||
|
||||
/datum/component/embedded/proc/examineTurf(datum/source, mob/user, list/examine_list)
|
||||
if(harmful)
|
||||
examine_list += "\t <a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] embedded in [parent]!</a>"
|
||||
examine_list += "<a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] embedded in [parent]!</a>"
|
||||
else
|
||||
examine_list += "\t <a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] stuck to [parent]!</a>"
|
||||
examine_list += "<a href='?src=[REF(src)];embedded_object=[REF(weapon)]' class='warning'>There is \a [weapon] stuck to [parent]!</a>"
|
||||
|
||||
|
||||
/// Someone is ripping out the item from the turf by hand
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
if(identification_method_flags & ID_COMPONENT_EFFECT_NO_ACTIONS)
|
||||
return COMPONENT_NO_GRANT_ACTIONS
|
||||
|
||||
/datum/component/identification/proc/check_knowledge(mob/user)
|
||||
/datum/component/identification/proc/check_knowledge(datum/source, mob/user)
|
||||
return ID_COMPONENT_KNOWLEDGE_NONE
|
||||
|
||||
/datum/component/identification/proc/on_identify(mob/user)
|
||||
@@ -83,7 +83,7 @@
|
||||
*/
|
||||
/datum/component/identification/syndicate
|
||||
|
||||
/datum/component/identification/syndicate/check_knowledge(mob/user)
|
||||
/datum/component/identification/syndicate/check_knowledge(datum/source, mob/user)
|
||||
. = ..()
|
||||
if(user?.mind?.has_antag_datum(/datum/antagonist/traitor))
|
||||
. = max(., ID_COMPONENT_KNOWLEDGE_FULL)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/component/mood/proc/print_mood(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\n<EM>Your current mood</EM>\n"
|
||||
var/msg = "<blockquote class='[sanity > SANITY_DISTURBED ? "nicegreen" : "warning"]'><span class='info'><EM>Your current mood</EM></span>\n"
|
||||
msg += "<span class='notice'>My mental status: </span>" //Long term
|
||||
switch(sanity)
|
||||
if(SANITY_GREAT to INFINITY)
|
||||
@@ -69,23 +69,23 @@
|
||||
msg += "<span class='notice'>My current mood: </span>" //Short term
|
||||
switch(mood_level)
|
||||
if(1)
|
||||
msg += "<span class='boldwarning'>I wish I was dead!<span>\n"
|
||||
msg += "<span class='boldwarning'>I wish I was dead!</span>\n"
|
||||
if(2)
|
||||
msg += "<span class='boldwarning'>I feel terrible...<span>\n"
|
||||
msg += "<span class='boldwarning'>I feel terrible...</span>\n"
|
||||
if(3)
|
||||
msg += "<span class='boldwarning'>I feel very upset.<span>\n"
|
||||
msg += "<span class='boldwarning'>I feel very upset.</span>\n"
|
||||
if(4)
|
||||
msg += "<span class='boldwarning'>I'm a bit sad.<span>\n"
|
||||
msg += "<span class='boldwarning'>I'm a bit sad.</span>\n"
|
||||
if(5)
|
||||
msg += "<span class='nicegreen'>I'm alright.<span>\n"
|
||||
msg += "<span class='nicegreen'>I'm alright.</span>\n"
|
||||
if(6)
|
||||
msg += "<span class='nicegreen'>I feel pretty okay.<span>\n"
|
||||
msg += "<span class='nicegreen'>I feel pretty okay.</span>\n"
|
||||
if(7)
|
||||
msg += "<span class='nicegreen'>I feel pretty good.<span>\n"
|
||||
msg += "<span class='nicegreen'>I feel pretty good.</span>\n"
|
||||
if(8)
|
||||
msg += "<span class='nicegreen'>I feel amazing!<span>\n"
|
||||
msg += "<span class='nicegreen'>I feel amazing!</span>\n"
|
||||
if(9)
|
||||
msg += "<span class='nicegreen'>I love life!<span>\n"
|
||||
msg += "<span class='nicegreen'>I love life!</span>\n"
|
||||
|
||||
msg += "<span class='notice'>Moodlets:\n</span>"//All moodlets
|
||||
if(mood_events.len)
|
||||
@@ -93,7 +93,8 @@
|
||||
var/datum/mood_event/event = mood_events[i]
|
||||
msg += event.description
|
||||
else
|
||||
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
|
||||
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.</span>\n"
|
||||
msg += "</blockquote>"
|
||||
to_chat(user || parent, msg)
|
||||
|
||||
///Called after moodevent/s have been added/removed.
|
||||
|
||||
@@ -431,25 +431,26 @@
|
||||
if(M.incapacitated() || !M.canUseStorage())
|
||||
return
|
||||
var/atom/A = parent
|
||||
A.add_fingerprint(M)
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M, trigger_on_found = TRUE)
|
||||
if(isrevenant(M))
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source)
|
||||
return
|
||||
if(check_locked(null, M) || !M.CanReach(A) || (!M.CanReach(over_object) && !istype(over_object, /atom/movable/screen)))
|
||||
return
|
||||
playsound(A, "rustle", 50, TRUE, -5)
|
||||
A.do_jiggle()
|
||||
A.add_fingerprint(M)
|
||||
if(!istype(over_object, /atom/movable/screen))
|
||||
INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M)
|
||||
return
|
||||
if(A.loc != M)
|
||||
return
|
||||
playsound(A, "rustle", 50, TRUE, -5)
|
||||
A.do_jiggle()
|
||||
if(istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
var/atom/movable/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(A, H.held_index)
|
||||
return
|
||||
A.add_fingerprint(M)
|
||||
|
||||
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE)
|
||||
var/atom/A = parent
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
var/atom/movable/screen/storage/item_holder/D = new(null, src, O)
|
||||
// SNOWFLAKE: make O opaque too, pending storage rewrite
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
O.maptext = ""
|
||||
@@ -138,6 +140,8 @@
|
||||
I = i
|
||||
var/percent = percentage_by_item[I]
|
||||
var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I)
|
||||
// SNOWFLAKE: force it to icon until we unfuck storage/click passing
|
||||
I.mouse_opacity = MOUSE_OPACITY_ICON
|
||||
var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
|
||||
var/addrow = FALSE
|
||||
if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
|
||||
|
||||
@@ -84,9 +84,9 @@
|
||||
if(VR)
|
||||
VR.level_below = src
|
||||
level_above = VR
|
||||
M.transfer_ckey(vr_M, FALSE)
|
||||
mastermind = M.mind
|
||||
mastermind.current.audiovisual_redirect = parent
|
||||
M.transfer_ckey(vr_M, FALSE)
|
||||
RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player)
|
||||
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
|
||||
RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
severity = DISEASE_SEVERITY_MEDIUM
|
||||
infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL
|
||||
bypasses_immunity = TRUE //2spook
|
||||
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
|
||||
var/mob/living/simple_animal/parrot/Polly/ghost/parrot
|
||||
|
||||
/datum/disease/parrot_possession/stage_act()
|
||||
..()
|
||||
|
||||
+27
-10
@@ -77,6 +77,7 @@
|
||||
new_dna.species = new species.type
|
||||
new_dna.species.say_mod = species.say_mod
|
||||
new_dna.species.exotic_blood_color = species.exotic_blood_color //it can change from the default value
|
||||
new_dna.species.exotic_blood_blend_mode = species.exotic_blood_blend_mode
|
||||
new_dna.species.eye_type = species.eye_type
|
||||
new_dna.species.limbs_id = species.limbs_id || species.id
|
||||
new_dna.real_name = real_name
|
||||
@@ -137,9 +138,9 @@
|
||||
L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
|
||||
L[DNA_LEFT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.left_eye_color)
|
||||
L[DNA_RIGHT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.right_eye_color)
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6)
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6)
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6)
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"])
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"])
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"])
|
||||
if(!GLOB.mam_tails_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/mam_tails, GLOB.mam_tails_list)
|
||||
L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)
|
||||
@@ -152,6 +153,10 @@
|
||||
if(!GLOB.taur_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list)
|
||||
L[DNA_TAUR_BLOCK] = construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)
|
||||
L[DNA_BARK_SOUND_BLOCK] = construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len)
|
||||
L[DNA_BARK_SPEED_BLOCK] = construct_block(H.vocal_speed * 4, 16)
|
||||
L[DNA_BARK_PITCH_BLOCK] = construct_block(H.vocal_pitch * 30, 48)
|
||||
L[DNA_BARK_VARIANCE_BLOCK] = construct_block(H.vocal_pitch_range * 48, 48)
|
||||
|
||||
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
||||
if(L[i])
|
||||
@@ -247,19 +252,19 @@
|
||||
if(DNA_HAIR_STYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len))
|
||||
if(DNA_COLOR_ONE_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor"], 6)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor"]))
|
||||
if(DNA_COLOR_TWO_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor2"], 6)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor2"]))
|
||||
if(DNA_COLOR_THREE_BLOCK)
|
||||
sanitize_hexcolor(features["mcolor3"], 6)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor3"]))
|
||||
if(DNA_MUTANTTAIL_BLOCK)
|
||||
construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len))
|
||||
if(DNA_MUTANTEAR_BLOCK)
|
||||
construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len))
|
||||
if(DNA_MUTANTMARKING_BLOCK)
|
||||
construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len))
|
||||
if(DNA_TAUR_BLOCK)
|
||||
construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len))
|
||||
if(species.mutant_bodyparts["taur"] && ishuman(holder))
|
||||
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
|
||||
switch(T?.taur_mode)
|
||||
@@ -271,6 +276,14 @@
|
||||
H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL
|
||||
else
|
||||
H.physiology.footstep_type = null
|
||||
if(DNA_BARK_SOUND_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len))
|
||||
if(DNA_BARK_SPEED_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(H.vocal_speed * 4, 16))
|
||||
if(DNA_BARK_PITCH_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch * 30, 48))
|
||||
if(DNA_BARK_VARIANCE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch_range * 48, 48))
|
||||
|
||||
//Please use add_mutation or activate_mutation instead
|
||||
/datum/dna/proc/force_give(datum/mutation/human/HM)
|
||||
@@ -490,6 +503,10 @@
|
||||
update_body_parts()
|
||||
if(mutations_overlay_update)
|
||||
update_mutations_overlay()
|
||||
set_bark(GLOB.bark_list[deconstruct_block(getblock(structure, DNA_BARK_SOUND_BLOCK), GLOB.bark_list.len)])
|
||||
vocal_speed = (deconstruct_block(getblock(structure, DNA_BARK_SPEED_BLOCK), 16) / 4)
|
||||
vocal_pitch = (deconstruct_block(getblock(structure, DNA_BARK_PITCH_BLOCK), 48) / 30)
|
||||
vocal_pitch_range = (deconstruct_block(getblock(structure, DNA_BARK_VARIANCE_BLOCK), 48) / 48)
|
||||
|
||||
|
||||
/mob/proc/domutcheck()
|
||||
|
||||
@@ -76,10 +76,10 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
|
||||
if(examine_full_view)
|
||||
examine_list += "[msg]"
|
||||
return
|
||||
if(length_char(msg) <= 40)
|
||||
if(length_char(msg) <= MAX_FLAVOR_PREVIEW_LEN)
|
||||
examine_list += "<span class='notice'>[msg]</span>"
|
||||
else
|
||||
examine_list += "<span class='notice'>[copytext_char(msg, 1, 37)]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
|
||||
examine_list += "<span class='notice'>[copytext_char(msg, 1, (MAX_FLAVOR_PREVIEW_LEN - 3))]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
|
||||
|
||||
/datum/element/flavor_text/Topic(href, href_list)
|
||||
. = ..()
|
||||
@@ -199,7 +199,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
|
||||
if(ismob(target))
|
||||
add_verb(target, /mob/proc/set_pose)
|
||||
|
||||
/datum/element/flavor_Text/carbon/temporary/Detach(datum/source, force)
|
||||
/datum/element/flavor_text/carbon/temporary/Detach(datum/source, force)
|
||||
. = ..()
|
||||
if(ismob(source))
|
||||
remove_verb(source, /mob/proc/set_pose)
|
||||
|
||||
@@ -136,13 +136,19 @@
|
||||
if (isnull(item))
|
||||
return FALSE
|
||||
|
||||
source.visible_message(
|
||||
span_warning("[user] tries to remove [source]'s [item.name]."),
|
||||
span_userdanger("[user] tries to remove your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
var/strip_silence
|
||||
var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES)
|
||||
if(istype(gloves))
|
||||
strip_silence = gloves.strip_silence
|
||||
|
||||
to_chat(user, span_danger("You try to remove [source]'s [item]..."))
|
||||
if(!strip_silence)
|
||||
source.visible_message(
|
||||
span_warning("[user] tries to remove [source]'s [item.name]."),
|
||||
span_userdanger("[user] tries to remove your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
|
||||
to_chat(user, strip_silence ? span_danger("You try to remove [source]'s [item]...") : span_notice("You try to remove [source]'s [item]..."))
|
||||
user.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_ATTACK, color="red")
|
||||
source.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_VICTIM, color="red", log_globally=FALSE)
|
||||
item.add_fingerprint(source)
|
||||
@@ -284,7 +290,12 @@
|
||||
|
||||
/// A utility function for `/datum/strippable_item`s to start unequipping an item from a mob.
|
||||
/proc/start_unequip_mob(obj/item/item, mob/source, mob/user, strip_delay)
|
||||
if (!do_mob(user, source, strip_delay || item.strip_delay, ignorehelditem = TRUE))
|
||||
var/strip_mod = 1
|
||||
var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES)
|
||||
if(istype(gloves))
|
||||
strip_mod = gloves.strip_mod
|
||||
|
||||
if (!do_mob(user, source, (strip_delay || item.strip_delay) / strip_mod, ignorehelditem = TRUE))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var
|
||||
|
||||
// Helper similar to image()
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF")
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF", blend_mode = BLEND_DEFAULT)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.icon = icon
|
||||
MA.icon_state = icon_state
|
||||
@@ -19,5 +19,6 @@
|
||||
MA.alpha = alpha
|
||||
MA.appearance_flags |= appearance_flags
|
||||
MA.color = color
|
||||
MA.blend_mode = blend_mode
|
||||
return MA
|
||||
|
||||
|
||||
@@ -120,6 +120,17 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/saymode/statusdisplay
|
||||
key = "q"
|
||||
mode = MODE_STATUSDISPLAY
|
||||
|
||||
/datum/saymode/statusdisplay/handle_message(mob/living/user, message, datum/language/language)
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
AI.statusdisplay_talk(message, language)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/saymode/monkey
|
||||
key = "k"
|
||||
mode = MODE_MONKEY
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/// should we immediately call on_spawn or add a timer to trigger
|
||||
var/on_spawn_immediate = TRUE
|
||||
var/mob/living/quirk_holder
|
||||
var/processing_quirk = FALSE
|
||||
|
||||
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
|
||||
if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type))
|
||||
@@ -25,7 +26,8 @@
|
||||
quirk_holder.roundstart_quirks += src
|
||||
if(mob_trait)
|
||||
ADD_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT)
|
||||
START_PROCESSING(SSquirks, src)
|
||||
if(processing_quirk)
|
||||
START_PROCESSING(SSquirks, src)
|
||||
add()
|
||||
if(spawn_effects)
|
||||
if(on_spawn_immediate)
|
||||
@@ -35,7 +37,8 @@
|
||||
addtimer(CALLBACK(src, .proc/post_add), 30)
|
||||
|
||||
/datum/quirk/Destroy()
|
||||
STOP_PROCESSING(SSquirks, src)
|
||||
if(processing_quirk)
|
||||
STOP_PROCESSING(SSquirks, src)
|
||||
remove()
|
||||
if(quirk_holder)
|
||||
to_chat(quirk_holder, lose_text)
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
mob_trait = TRAIT_JOLLY
|
||||
mood_quirk = TRUE
|
||||
medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest."
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/jolly/on_process()
|
||||
if(prob(0.05))
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
lose_text = "<span class='notice'>You no longer feel depressed.</span>" //if only it were that easy!
|
||||
medical_record_text = "Patient has a severe mood disorder, causing them to experience acute episodes of depression."
|
||||
mood_quirk = TRUE
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/depression/on_process()
|
||||
if(prob(0.05))
|
||||
@@ -38,6 +39,7 @@
|
||||
medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom."
|
||||
var/obj/item/heirloom
|
||||
var/where
|
||||
processing_quirk = TRUE
|
||||
|
||||
GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
|
||||
@@ -102,6 +104,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = "<span class='danger'>You feel smooth.</span>"
|
||||
lose_text = "<span class='notice'>You feel wrinkled again.</span>"
|
||||
medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/brainproblems/on_process()
|
||||
quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
|
||||
@@ -129,25 +132,38 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
value = -1
|
||||
medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)"
|
||||
|
||||
/datum/quirk/nyctophobia/on_process()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
if(H.dna.species.id in list("shadow", "nightmare"))
|
||||
return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
if(lums <= 0.2)
|
||||
if(quirk_holder.m_intent == MOVE_INTENT_RUN)
|
||||
addtimer(CALLBACK(src, .proc/recheck),2) //0.2 seconds of being in the dark
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
|
||||
else
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
/datum/quirk/nyctophobia/add()
|
||||
RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
|
||||
|
||||
/datum/quirk/nyctophobia/proc/recheck()
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
if(lums <= 0.2) //check again, did they remain in the dark for 0.2 seconds?
|
||||
to_chat(quirk_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
|
||||
/datum/quirk/nyctophobia/remove()
|
||||
UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
|
||||
/// Called when the quirk holder moves. Updates the quirk holder's mood.
|
||||
/datum/quirk/nyctophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
|
||||
if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/human_holder = quirk_holder
|
||||
|
||||
if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE))
|
||||
return
|
||||
|
||||
if((human_holder.sight & SEE_TURFS) == SEE_TURFS)
|
||||
return
|
||||
|
||||
var/turf/holder_turf = get_turf(quirk_holder)
|
||||
|
||||
var/lums = holder_turf.get_lumcount()
|
||||
|
||||
if(lums > 0.2)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
return
|
||||
|
||||
if(quirk_holder.m_intent == MOVE_INTENT_RUN)
|
||||
to_chat(quirk_holder, span_warning("Easy, easy, take it slow... you're in the dark..."))
|
||||
quirk_holder.toggle_move_intent()
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
|
||||
|
||||
/datum/quirk/lightless
|
||||
name = "Light Sensitivity"
|
||||
@@ -157,6 +173,36 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
lose_text = "<span class='notice'>Enlightening.</span>"
|
||||
medical_record_text = "Despite my warnings, the patient refuses turn on the lights, only to end up rolling down a full flight of stairs and into the cellar."
|
||||
|
||||
/datum/quirk/lightless/add()
|
||||
RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
|
||||
|
||||
/datum/quirk/lightless/remove()
|
||||
UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight")
|
||||
|
||||
/datum/quirk/lightless/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced)
|
||||
if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/human_holder = quirk_holder
|
||||
|
||||
if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE))
|
||||
return
|
||||
|
||||
if((human_holder.sight & SEE_TURFS) == SEE_TURFS)
|
||||
return
|
||||
|
||||
var/turf/holder_turf = get_turf(quirk_holder)
|
||||
|
||||
var/lums = holder_turf.get_lumcount()
|
||||
|
||||
if(lums < 0.8)
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight")
|
||||
return
|
||||
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "brightlight", /datum/mood_event/brightlight)
|
||||
|
||||
|
||||
/datum/quirk/lightless/on_process()
|
||||
var/turf/T = get_turf(quirk_holder)
|
||||
var/lums = T.get_lumcount()
|
||||
@@ -236,6 +282,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = "<span class='userdanger'>...</span>"
|
||||
lose_text = "<span class='notice'>You feel in tune with the world again.</span>"
|
||||
medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/insanity/on_process()
|
||||
if(quirk_holder.reagents.has_reagent(/datum/reagent/toxin/mindbreaker))
|
||||
@@ -261,6 +308,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
lose_text = "<span class='notice'>You feel easier about talking again.</span>" //if only it were that easy!
|
||||
medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
|
||||
var/dumb_thing = TRUE
|
||||
processing_quirk = TRUE
|
||||
|
||||
/datum/quirk/social_anxiety/add()
|
||||
RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, .proc/eye_contact)
|
||||
@@ -425,3 +473,21 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
|
||||
gain_text = "<span class='notice'>You can't smell anything!</span>"
|
||||
lose_text = "<span class='notice'>You can smell again!</span>"
|
||||
medical_record_text = "Patient suffers from anosmia and is incapable of smelling gases or particulates."
|
||||
|
||||
/datum/quirk/paper_skin
|
||||
name = "Paper Skin"
|
||||
desc = "Your flesh is weaker, resulting in receiving cuts more easily."
|
||||
value = -1
|
||||
mob_trait = TRAIT_PAPER_SKIN
|
||||
gain_text = "<span class='notice'>Your flesh feels weak!</span>"
|
||||
lose_text = "<span class='notice'>Your flesh feels more durable!</span>"
|
||||
medical_record_text = "Patient suffers from weak flesh, resulting in them receiving cuts far more easily."
|
||||
|
||||
/datum/quirk/glass_bones
|
||||
name = "Glass Bones"
|
||||
desc = "Your bones are far more brittle, and more vulnerable to breakage."
|
||||
value = -1
|
||||
mob_trait = TRAIT_GLASS_BONES
|
||||
gain_text = "<span class='notice'>Your bones feels weak!</span>"
|
||||
lose_text = "<span class='notice'>Your bones feels more durable!</span>"
|
||||
medical_record_text = "Patient suffers from brittle bones, resulting in them receiving breakages far more easily."
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
if(WOUND_SEVERITY_LOSS)
|
||||
msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format
|
||||
msg = "<span class='notice'><i><b>[msg]</b></i></span>"
|
||||
return "\t[msg]"
|
||||
return "[msg]"
|
||||
|
||||
/// Whether a scar can currently be seen by the viewer
|
||||
/datum/scar/proc/is_visible(mob/viewer)
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
if(WOUND_INFECTION_SEPTIC to INFINITY)
|
||||
. += "Infection Level: <span class='deadsay'>LOSS IMMINENT</span>\n"
|
||||
if(infestation > sanitization)
|
||||
. += "\tSurgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n"
|
||||
. += "Surgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n"
|
||||
|
||||
if(flesh_damage > 0)
|
||||
. += "Flesh damage detected: Please apply ointment or regenerative mesh to allow recovery.\n"
|
||||
|
||||
Reference in New Issue
Block a user