diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 79498d7b42..7189ba538d 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -80,7 +80,7 @@ //DNA - Because fuck you and your magic numbers being all over the codebase. #define DNA_BLOCK_SIZE 3 -#define DNA_UNI_IDENTITY_BLOCKS 15 +#define DNA_UNI_IDENTITY_BLOCKS 19 #define DNA_HAIR_COLOR_BLOCK 1 #define DNA_FACIAL_HAIR_COLOR_BLOCK 2 #define DNA_SKIN_TONE_BLOCK 3 @@ -96,6 +96,10 @@ #define DNA_MUTANTEAR_BLOCK 13 #define DNA_MUTANTMARKING_BLOCK 14 #define DNA_TAUR_BLOCK 15 +#define DNA_BARK_SOUND_BLOCK 16 +#define DNA_BARK_SPEED_BLOCK 17 +#define DNA_BARK_PITCH_BLOCK 18 +#define DNA_BARK_VARIANCE_BLOCK 19 #define DNA_SEQUENCE_LENGTH 4 #define DNA_MUTATION_BLOCKS 8 diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 69080350a0..bcda72cf37 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -15,9 +15,10 @@ #define DISABLE_DEATHRATTLE (1<<12) #define DISABLE_ARRIVALRATTLE (1<<13) #define COMBOHUD_LIGHTING (1<<14) -#define VERB_CONSENT (1<<15) // Skyrat - ERP Mechanic Addition -#define LEWD_VERB_SOUNDS (1<<16) // Skyrat - ERP Mechanic Addition -#define TG_PLAYER_PANEL (1<<17) // SPLURT - Opt for the old splashscreen player panel +#define SOUND_BARK (1<<15) +#define VERB_CONSENT (1<<16) // Sandstorm - ERP Mechanic Addition +#define LEWD_VERB_SOUNDS (1<<17) // Sandstorm - ERP Mechanic Addition +#define TG_PLAYER_PANEL (1<<18) // SPLURT - Opt for the old splashscreen player panel #define DEADMIN_ALWAYS (1<<0) #define DEADMIN_ANTAGONIST (1<<1) @@ -25,7 +26,7 @@ #define DEADMIN_POSITION_SECURITY (1<<3) #define DEADMIN_POSITION_SILICON (1<<4) -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS|SOUND_BARK) //Chat toggles #define CHAT_OOC (1<<0) diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index d1329060eb..51c6e3c394 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -27,6 +27,7 @@ #define NOBLIUM_RESEARCH_AMOUNT 25 #define BZ_RESEARCH_SCALE 4 #define BZ_RESEARCH_MAX_AMOUNT 400 +#define QCD_RESEARCH_AMOUNT 2 // often made in absolutely massive quantities due to the simple nature of fusion #define MIASMA_RESEARCH_AMOUNT 6 #define STIMULUM_RESEARCH_AMOUNT 50 //Plasma fusion properties diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index e27489380c..013d038f3a 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -73,6 +73,8 @@ TECHWEB_POINT_TYPE_GENERIC = "General Research"\ ) +#define LARGEST_BOMB "bomb" + #define BOMB_TARGET_POINTS 50000 //Adjust as needed. Actual hard cap is double this, but will never be reached due to hyperbolic curve. #define BOMB_TARGET_SIZE (world.system_type == MS_WINDOWS ? 240 : 50000) // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points. // Linux still has old trit fires, so diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index f9574fc2bb..03451b143a 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -100,6 +100,24 @@ #define MAX_BROADCAST_LEN 512 #define MAX_CHARTER_LEN 80 +//Bark defines +#define BARK_DEFAULT_MINPITCH 0.6 +#define BARK_DEFAULT_MAXPITCH 1.4 +#define BARK_DEFAULT_MINVARY 0.1 +#define BARK_DEFAULT_MAXVARY 0.4 +#define BARK_DEFAULT_MINSPEED 2 +#define BARK_DEFAULT_MAXSPEED 8 + +#define BARK_SPEED_BASELINE 4 //Used to calculate delay between barks, any bark speeds below this feature higher bark density, any speeds above feature lower bark density. Keeps barking length consistent + +#define BARK_MAX_BARKS 128 +#define BARK_MAX_TIME (10 SECONDS) // More or less the amount of time the above takes to process through with a bark speed of 2. + +#define BARK_PITCH_RAND(gend) ((gend == MALE ? rand(60, 120) : (gend == FEMALE ? rand(80, 140) : rand(60,140))) / 100) //Macro for determining random pitch based off gender +#define BARK_VARIANCE_RAND (rand(BARK_DEFAULT_MINVARY * 100, BARK_DEFAULT_MAXVARY * 100) / 100) //Macro for randomizing bark variance to reduce the amount of copy-pasta necessary for that + +#define BARK_DO_VARY(pitch, variance) (rand(((pitch * 100) - (variance*50)), ((pitch*100) + (variance*50))) / 100) + // Is something in the IC chat filter? This is config dependent. #define CHAT_FILTER_CHECK(T) (config.ic_filter_regex && findtext(T, config.ic_filter_regex)) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 2e4c9c6ad3..b825ac266c 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -82,6 +82,12 @@ var/datum/emote/E = new path() E.emote_list[E.key] = E + for(var/path in subtypesof(/datum/bark)) + var/datum/bark/B = new path() + GLOB.bark_list[B.id] = path + if(B.allow_random) + GLOB.bark_random_list[B.id] = path + // Hair Gradients - Initialise all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name for(var/path in subtypesof(/datum/sprite_accessory/hair_gradient)) var/datum/sprite_accessory/hair_gradient/H = new path() diff --git a/code/__HELPERS/matrices/color_matrix.dm b/code/__HELPERS/matrices/color_matrix.dm index e4a4a9bb48..bcc48b45f5 100644 --- a/code/__HELPERS/matrices/color_matrix.dm +++ b/code/__HELPERS/matrices/color_matrix.dm @@ -138,6 +138,25 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) +/** + * Builds a color matrix that transforms the hue, saturation, and value, all in one operation. + */ +/proc/color_matrix_hsv(hue, saturation, value) + hue = clamp(360 - hue, 0, 360) + + // This is very much a rough approximation of hueshifting. This carries some artifacting, such as negative values that simply shouldn't exist, but it does get the job done, and that's what matters. + var/cos_a = cos(hue) // These have to be inverted from 360, otherwise the hue's inverted + var/sin_a = sin(hue) + var/rot_x = cos_a + (1 - cos_a) / 3 + var/rot_y = (1 - cos_a) / 3 - 0.5774 * sin_a // 0.5774 is sqrt(1/3) + var/rot_z = (1 - cos_a) / 3 + 0.5774 * sin_a + + return list( + round((((1-saturation) * LUMA_R) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_z * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_G) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_y * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_B) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_x * saturation)) * value, 0.01), + 0, 0, 0 + ) //Returns a matrix addition of A with B /proc/color_matrix_add(list/A, list/B) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 1b6250a250..fe092e6d7f 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -43,6 +43,10 @@ GLOBAL_LIST_EMPTY(arachnid_spinneret_list) GLOBAL_LIST_EMPTY(arachnid_mandibles_list) GLOBAL_LIST_EMPTY(caps_list) + //Bark bits +GLOBAL_LIST_EMPTY(bark_list) +GLOBAL_LIST_EMPTY(bark_random_list) + //a way to index the right bodypart list given the type of bodypart GLOBAL_LIST_INIT(mutant_reference_list, list( "tail_lizard" = GLOB.tails_list_lizard, diff --git a/code/_rendering/atom_huds/atom_hud.dm b/code/_rendering/atom_huds/atom_hud.dm index bdb996892e..9cdf277c5f 100644 --- a/code/_rendering/atom_huds/atom_hud.dm +++ b/code/_rendering/atom_huds/atom_hud.dm @@ -30,6 +30,8 @@ GLOBAL_LIST_INIT(huds, list( ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker(), ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(), ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_SPACECOP = new/datum/atom_hud/antag(), + ANTAG_HUD_GANGSTER = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_SLAVER = new/datum/atom_hud/antag(), DATA_HUD_ANTAGTARGET = new/datum/atom_hud/data/human/antagtarget(), )) diff --git a/code/datums/bark.dm b/code/datums/bark.dm new file mode 100644 index 0000000000..a7119273c3 --- /dev/null +++ b/code/datums/bark.dm @@ -0,0 +1,139 @@ +//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 = 6 //This is a pretty long sound + soundpath = 'sound/items/Ratchet.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! + + +// 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 diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 1535c3f142..9bdb009962 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -346,9 +346,9 @@ /datum/component/embedded/proc/examineTurf(datum/source, mob/user, list/examine_list) if(harmful) - examine_list += "\t There is \a [weapon] embedded in [parent]!" + examine_list += "There is \a [weapon] embedded in [parent]!" else - examine_list += "\t There is \a [weapon] stuck to [parent]!" + examine_list += "There is \a [weapon] stuck to [parent]!" /// Someone is ripping out the item from the turf by hand diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index f8764bee28..9c542b505c 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -69,23 +69,23 @@ msg += "My current mood: " //Short term switch(mood_level) if(1) - msg += "I wish I was dead!\n" + msg += "I wish I was dead!\n" if(2) - msg += "I feel terrible...\n" + msg += "I feel terrible...\n" if(3) - msg += "I feel very upset.\n" + msg += "I feel very upset.\n" if(4) - msg += "I'm a bit sad.\n" + msg += "I'm a bit sad.\n" if(5) - msg += "I'm alright.\n" + msg += "I'm alright.\n" if(6) - msg += "I feel pretty okay.\n" + msg += "I feel pretty okay.\n" if(7) - msg += "I feel pretty good.\n" + msg += "I feel pretty good.\n" if(8) - msg += "I feel amazing!\n" + msg += "I feel amazing!\n" if(9) - msg += "I love life!\n" + msg += "I love life!\n" msg += "Moodlets:\n"//All moodlets if(mood_events.len) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index c795e1140e..c89ece5396 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -153,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]) @@ -248,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"], 6)) if(DNA_COLOR_TWO_BLOCK) - sanitize_hexcolor(features["mcolor2"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor2"], 6)) if(DNA_COLOR_THREE_BLOCK) - sanitize_hexcolor(features["mcolor3"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor3"], 6)) 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) @@ -272,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) @@ -483,6 +495,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_PITCH_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() diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm index e67120f254..85fea3533e 100644 --- a/code/datums/elements/strippable.dm +++ b/code/datums/elements/strippable.dm @@ -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 diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm index 3365fc359d..3fb6546edb 100644 --- a/code/datums/wounds/_scars.dm +++ b/code/datums/wounds/_scars.dm @@ -118,7 +118,7 @@ if(WOUND_SEVERITY_LOSS) msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format msg = "[msg]" - return "\t[msg]" + return "[msg]" /// Whether a scar can currently be seen by the viewer /datum/scar/proc/is_visible(mob/viewer) diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index f3e22807cf..c16be6005a 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -167,7 +167,7 @@ if(WOUND_INFECTION_SEPTIC to INFINITY) . += "Infection Level: LOSS IMMINENT\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" diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index dd70825339..361c518073 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -212,6 +212,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED // airlock_wires = /datum/wires/airlock/maint sound_environment = SOUND_AREA_TUNNEL_ENCLOSED + minimap_color = "#454545" //Maintenance - Departmental @@ -435,6 +436,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway nightshift_public_area = NIGHTSHIFT_AREA_PUBLIC sound_environment = SOUND_AREA_STANDARD_STATION + minimap_color = "#aaaaaa" /area/hallway/primary name = "Primary Hallway" @@ -490,6 +492,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/exit name = "Escape Shuttle Hallway" icon_state = "escape" + minimap_color = "#baa0a0" /area/hallway/secondary/exit/departure_lounge name = "Departure Lounge" @@ -498,6 +501,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/entry name = "Arrival Shuttle Hallway" icon_state = "entry" + minimap_color = "#a0a0ba" /area/hallway/secondary/service name = "Service Hallway" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 44916cf1d2..24b49a3af7 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -124,6 +124,10 @@ /// Color on minimaps, if it's null (which is default) it makes one at random. var/minimap_color + var/minimap_color2 // if this isn't null, then this will show as a checkerboard pattern mixed in with the above. works even if the above is null (for better or worse) + + var/minimap_show_walls = TRUE + /** * These two vars allow for multiple unique areas to be linked to a master area * and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing diff --git a/code/game/area/areas/ruins/_ruins.dm b/code/game/area/areas/ruins/_ruins.dm index 6699e94129..f9af5c8ce4 100644 --- a/code/game/area/areas/ruins/_ruins.dm +++ b/code/game/area/areas/ruins/_ruins.dm @@ -9,6 +9,9 @@ ambientsounds = RUINS sound_environment = SOUND_ENVIRONMENT_STONEROOM var/valid_territory = FALSE // hey so what if we did not allow things like cult summons to appear on ruins + minimap_color = "#775940" + minimap_color2 = "#6b5d48" + minimap_show_walls = FALSE /area/ruin/unpowered diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4077f86e52..2bdb01cf0d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -518,7 +518,7 @@ . = list("[get_examine_string(user, TRUE)].[desc ? "
" : null]") if(desc) - . += desc + . += "
[desc]" if(custom_materials) . += "
" diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0323217341..f758152426 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -65,6 +65,14 @@ /// last time we yelled var/last_yell = 0 + // Text-to-bark sounds + var/sound/vocal_bark + var/vocal_bark_id + var/vocal_pitch = 1 + var/vocal_pitch_range = 0.2 //Actual pitch is (pitch - (vocal_pitch_range*0.5)) to (pitch + (vocal_pitch_range*0.5)) + var/vocal_volume = 70 //Baseline. This gets modified by yelling and other factors + var/vocal_speed = 4 //Lower values are faster, higher values are slower + /atom/movable/Initialize(mapload) . = ..() switch(blocks_emissive) @@ -697,6 +705,17 @@ var/datum/language_holder/LH = get_language_holder() return LH.update_atom_languages(src) +/// Sets the vocal bark for the atom, using the bark's ID +/atom/movable/proc/set_bark(id) + if(!id) + return FALSE + var/datum/bark/B = GLOB.bark_list[id] + if(!B) + return FALSE + vocal_bark = sound(initial(B.soundpath)) + vocal_bark_id = id + return vocal_bark + /* End language procs */ diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 0d95448702..1fb2405584 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -104,6 +104,9 @@ Class Procs: anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT + vocal_bark_id = "synth" + vocal_pitch = 0.6 + var/stat = 0 var/use_power = IDLE_POWER_USE //0 = dont run the auto diff --git a/code/game/machinery/colormate.dm b/code/game/machinery/colormate.dm index 1528142a3b..a208fc0bd2 100644 --- a/code/game/machinery/colormate.dm +++ b/code/game/machinery/colormate.dm @@ -1,6 +1,10 @@ +#define COLORMATE_TINT 1 +#define COLORMATE_HSV 2 +#define COLORMATE_MATRIX 3 + /obj/machinery/gear_painter name = "\improper Color Mate" - desc = "A machine to give your apparel a fresh new color! Recommended to use with white items for best results." + desc = "A machine to give your apparel a fresh new color!" icon = 'icons/obj/vending.dmi' icon_state = "colormate" // light_mask = "colormate-light-mask" @@ -10,7 +14,11 @@ var/atom/movable/inserted var/activecolor = "#FFFFFF" var/list/color_matrix_last - var/matrix_mode = FALSE + var/active_mode = COLORMATE_HSV + + var/build_hue = 0 + var/build_sat = 1 + var/build_val = 1 /// Allow holder'd mobs var/allow_mobs = TRUE /// Minimum lightness for normal mode @@ -71,8 +79,8 @@ return if(!QDELETED(H)) H.release() + insert_mob(victim, user) - temp = "[victim] has been inserted." SStgui.update_uis(src) if(is_type_in_list(I, allowed_types) && is_operational()) @@ -85,7 +93,6 @@ inserted = I update_icon() - temp = "[I] has been inserted." SStgui.update_uis(src) else @@ -134,7 +141,7 @@ /obj/machinery/gear_painter/ui_data(mob/user) . = list() - .["matrixactive"] = matrix_mode + .["activemode"] = active_mode .["matrixcolors"] = list( "rr" = color_matrix_last[1], "rg" = color_matrix_last[2], @@ -149,6 +156,9 @@ "cg" = color_matrix_last[11], "cb" = color_matrix_last[12] ) + .["buildhue"] = build_hue + .["buildsat"] = build_sat + .["buildval"] = build_val if(temp) .["temp"] = temp if(inserted) @@ -166,7 +176,7 @@ if(inserted) switch(action) if("switch_modes") - matrix_mode = text2num(params["mode"]) + active_mode = text2num(params["mode"]) return TRUE if("choose_color") var/chosen_color = input(usr, "Choose a color: ", "Colormate color picking", activecolor) as color|null @@ -174,14 +184,11 @@ activecolor = chosen_color return TRUE if("paint") - if(!check_valid_color(activecolor, usr)) - return TRUE - inserted.add_atom_colour(activecolor, FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) + do_paint(usr) temp = "Painted Successfully!" return TRUE if("drop") - temp = "Ejected \the [inserted]!" + temp = "" drop_item() return TRUE if("clear") @@ -192,76 +199,95 @@ if("set_matrix_color") color_matrix_last[params["color"]] = params["value"] return TRUE - if("matrix_paint") - var/list/cm = rgb_construct_color_matrix( - text2num(color_matrix_last[1]), - text2num(color_matrix_last[2]), - text2num(color_matrix_last[3]), - text2num(color_matrix_last[4]), - text2num(color_matrix_last[5]), - text2num(color_matrix_last[6]), - text2num(color_matrix_last[7]), - text2num(color_matrix_last[8]), - text2num(color_matrix_last[9]), - text2num(color_matrix_last[10]), - text2num(color_matrix_last[11]), - text2num(color_matrix_last[12]) - ) - if(!check_valid_color(cm, usr)) - return TRUE - inserted.add_atom_colour(cm, FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) - temp = "Matrix Painted Successfully!" + if("set_hue") + build_hue = clamp(text2num(params["buildhue"]), 0, 360) return TRUE + if("set_sat") + build_sat = clamp(text2num(params["buildsat"]), -10, 10) + return TRUE + if("set_val") + build_val = clamp(text2num(params["buildval"]), -10, 10) + return TRUE + + +/obj/machinery/gear_painter/proc/do_paint(mob/user) + var/color_to_use + switch(active_mode) + if(COLORMATE_TINT) + color_to_use = activecolor + if(COLORMATE_MATRIX) + color_to_use = rgb_construct_color_matrix( + text2num(color_matrix_last[1]), + text2num(color_matrix_last[2]), + text2num(color_matrix_last[3]), + text2num(color_matrix_last[4]), + text2num(color_matrix_last[5]), + text2num(color_matrix_last[6]), + text2num(color_matrix_last[7]), + text2num(color_matrix_last[8]), + text2num(color_matrix_last[9]), + text2num(color_matrix_last[10]), + text2num(color_matrix_last[11]), + text2num(color_matrix_last[12]) + ) + if(COLORMATE_HSV) + color_to_use = color_matrix_hsv(build_hue, build_sat, build_val) + color_matrix_last = color_to_use + if(!color_to_use || !check_valid_color(color_to_use, user)) + to_chat(user, "Invalid color.") + return FALSE + inserted.add_atom_colour(color_to_use, FIXED_COLOUR_PRIORITY) + playsound(src, 'sound/effects/spray3.ogg', 50, 1) + return TRUE + /// Produces the preview image of the item, used in the UI, the way the color is not stacking is a sin. /obj/machinery/gear_painter/proc/build_preview() if(inserted) //sanity - if(matrix_mode) - var/list/cm = rgb_construct_color_matrix( - text2num(color_matrix_last[1]), - text2num(color_matrix_last[2]), - text2num(color_matrix_last[3]), - text2num(color_matrix_last[4]), - text2num(color_matrix_last[5]), - text2num(color_matrix_last[6]), - text2num(color_matrix_last[7]), - text2num(color_matrix_last[8]), - text2num(color_matrix_last[9]), - text2num(color_matrix_last[10]), - text2num(color_matrix_last[11]), - text2num(color_matrix_last[12]) - ) - if(!check_valid_color(cm, usr)) - temp = "Failed to generate preview: Invalid color!" - return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + var/list/cm + switch(active_mode) + if(COLORMATE_MATRIX) + cm = rgb_construct_color_matrix( + text2num(color_matrix_last[1]), + text2num(color_matrix_last[2]), + text2num(color_matrix_last[3]), + text2num(color_matrix_last[4]), + text2num(color_matrix_last[5]), + text2num(color_matrix_last[6]), + text2num(color_matrix_last[7]), + text2num(color_matrix_last[8]), + text2num(color_matrix_last[9]), + text2num(color_matrix_last[10]), + text2num(color_matrix_last[11]), + text2num(color_matrix_last[12]) + ) + if(!check_valid_color(cm, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - var/cur_color = inserted.color - inserted.color = null - inserted.color = cm - var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - inserted.color = cur_color + if(COLORMATE_TINT) + if(!check_valid_color(activecolor, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - . = preview + if(COLORMATE_HSV) + cm = color_matrix_hsv(build_hue, build_sat, build_val) + color_matrix_last = cm + if(!check_valid_color(cm, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - else - if(!check_valid_color(activecolor, usr)) - temp = "Failed to generate preview: Invalid color!" - return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + var/cur_color = inserted.color + inserted.color = null + inserted.color = (active_mode == COLORMATE_TINT ? activecolor : cm) + var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + inserted.color = cur_color + temp = "" - var/cur_color = inserted.color - inserted.color = null - inserted.color = activecolor - var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - inserted.color = cur_color - - . = preview + . = preview /obj/machinery/gear_painter/proc/check_valid_color(list/cm, mob/user) if(!islist(cm)) // normal var/list/HSV = ReadHSV(RGBtoHSV(cm)) if(HSV[3] < minimum_normal_lightness) - temp = "[cm] is far too dark (min lightness [minimum_normal_lightness]!" + temp = "[cm] is too dark (Minimum lightness: [minimum_normal_lightness])" return FALSE return TRUE else // matrix @@ -275,6 +301,6 @@ COLORTEST("FFFFFF", cm) #undef COLORTEST if(passed < minimum_matrix_tests) - temp = "[english_list(color)] is not allowed (passed [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness])." + temp = "Matrix is too dark. (passed [passed] out of [minimum_matrix_tests] required tests. Minimum lightness: [minimum_matrix_lightness])." return FALSE return TRUE diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 18ed5205be..458f231f4b 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -203,9 +203,13 @@ GLOBAL_LIST_EMPTY(doppler_arrays) point_gain = (BOMB_TARGET_POINTS * 2 * orig_light) / (orig_light + BOMB_TARGET_SIZE) /*****The Point Capper*****/ - if(point_gain > linked_techweb.largest_bomb_value) - var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math - linked_techweb.largest_bomb_value = point_gain + + var/list/largest_values = linked_techweb.largest_values + if(!(LARGEST_BOMB in largest_values)) + largest_values[LARGEST_BOMB] = 0 + if(point_gain > largest_values[LARGEST_BOMB]) + var/old_tech_largest_bomb_value = largest_values[LARGEST_BOMB] //held so we can pull old before we do math + linked_techweb.largest_values[LARGEST_BOMB] = point_gain point_gain -= old_tech_largest_bomb_value var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI) if(D) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index ff6f96a29f..12b2ba08e4 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -230,13 +230,13 @@ if(beaker) if(beaker.reagents && beaker.reagents.reagent_list.len) - . += "\tAttached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n" + . += "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n" else - . += "\tAttached is an empty [beaker.name].\n" + . += "Attached is an empty [beaker.name].\n" else - . += "\tNo chemicals are attached.\n" + . += "No chemicals are attached.\n" - . += "\t[attached ? attached : "No one"] is attached." + . += "[attached ? attached : "No one"] is attached." /obj/machinery/iv_drip/telescopic name = "telescopic IV drip" diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 4528ecc473..8fa1bed6ad 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -149,21 +149,21 @@ GENETICS SCANNER // Damage descriptions if(brute_loss > 10) - msg += "\n\t[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected." + msg += "\n[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected." if(fire_loss > 10) - msg += "\n\t[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected." + msg += "\n[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected." if(oxy_loss > 10) - msg += "\n\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected." + msg += "\n[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected." if(tox_loss > 10) - msg += "\n\t[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected." + msg += "\n[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected." if(M.getStaminaLoss()) - msg += "\n\tSubject appears to be suffering from fatigue." + msg += "\nSubject appears to be suffering from fatigue." if(advanced) - msg += "\n\tFatigue Level: [M.getStaminaLoss()]%." + msg += "\nFatigue Level: [M.getStaminaLoss()]%." if (M.getCloneLoss()) - msg += "\n\tSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage." + msg += "\nSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage." if(advanced) - msg += "\n\tCellular Damage Level: [M.getCloneLoss()]." + msg += "\nCellular Damage Level: [M.getCloneLoss()]." if(ishuman(M)) var/mob/living/carbon/human/H = M if(advanced && H.has_dna()) @@ -175,7 +175,7 @@ GENETICS SCANNER var/mob/living/carbon/C = M var/list/damaged = C.get_damaged_bodyparts(1,1) if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0) - dmgreport += "\ + dmgreport += "
\ \ \ \ @@ -315,7 +315,7 @@ GENETICS SCANNER damage_message += " Minor [O.name] failure detected." if(temp_message || damage_message) - msg += "\t[uppertext(O.name)]: [damage_message] [temp_message]\n" + msg += "\n[uppertext(O.name)]: [damage_message] [temp_message]\n" @@ -330,24 +330,24 @@ GENETICS SCANNER var/has_liver = C.dna && !(NOLIVER in C.dna.species.species_traits) var/has_stomach = C.dna && !(NOSTOMACH in C.dna.species.species_traits) if(!M.getorganslot(ORGAN_SLOT_EYES)) - msg += "\tSubject does not have eyes.\n" + msg += "Subject does not have eyes.\n" if(!M.getorganslot(ORGAN_SLOT_EARS)) - msg += "\tSubject does not have ears.\n" + msg += "Subject does not have ears.\n" if(!M.getorganslot(ORGAN_SLOT_BRAIN)) - msg += "\tSubject's brain function is non-existent!\n" + msg += "Subject's brain function is non-existent!\n" if(has_liver && !M.getorganslot(ORGAN_SLOT_LIVER)) - msg += "\tSubject's liver is missing!\n" + msg += "Subject's liver is missing!\n" if(blooded && !M.getorganslot(ORGAN_SLOT_HEART)) - msg += "\tSubject's heart is missing!\n" + msg += "Subject's heart is missing!\n" if(breathes && !M.getorganslot(ORGAN_SLOT_LUNGS)) - msg += "\tSubject's lungs have collapsed from trauma!\n" + msg += "Subject's lungs have collapsed from trauma!\n" if(has_stomach && !M.getorganslot(ORGAN_SLOT_STOMACH)) - msg += "\tSubject's stomach is missing!\n" + msg += "Subject's stomach is missing!\n" if(M.radiation) - msg += "\tSubject is irradiated.\n" - msg += "\tRadiation Level: [M.radiation] rad\n" + msg += "Subject is irradiated.\n" + msg += "Radiation Level: [M.radiation] rad\n" @@ -381,11 +381,11 @@ GENETICS SCANNER else if (S.flying_species != initial(S.flying_species)) mutant = TRUE - msg += "\tReported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]\n" - msg += "\tBase Species: [H.spec_trait_examine_font()][S.name]\n" + msg += "\nReported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]\n" + msg += "Base Species: [H.spec_trait_examine_font()][S.name]\n" if(mutant) - msg += "\tSubject has mutations present.\n" - msg += "\tBody temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n" + msg += "Subject has mutations present.\n" + msg += "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n" // Time of death if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced))) @@ -526,12 +526,14 @@ GENETICS SCANNER var/render_list = "" for(var/i in patient.get_wounded_bodyparts()) + if(render_list == "") + render_list += "
" var/obj/item/bodypart/wounded_part = i render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" for(var/k in wounded_part.wounds) var/datum/wound/W = k render_list += "
[W.get_scanner_description()]
\n" - render_list += "
" + render_list += "
" if(render_list == "") if(istype(scanner)) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 46248c1ff8..4ea25bec96 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -7,6 +7,8 @@ var/obj_flags = CAN_BE_HIT var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT. + var/minimap_override_color // allows this obj to set its own color on the minimap + var/damtype = BRUTE var/force = 0 diff --git a/code/game/say.dm b/code/game/say.dm index b7bfe540d0..205ddc2f0e 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -31,14 +31,37 @@ GLOBAL_LIST_INIT(freqtospan, list( /atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) +/atom/movable/proc/bark(list/hearers, distance, volume, pitch) + if(!vocal_bark) + if(!vocal_bark_id || !set_bark(vocal_bark_id)) //just-in-time bark generation + return + volume = min(volume, 100) + var/turf/T = get_turf(src) + for(var/mob/M in hearers) + M.playsound_local(T, vol = volume, vary = TRUE, frequency = pitch, max_distance = distance, falloff_distance = distance * 0.75, S = vocal_bark, distance_multiplier = 1) + /atom/movable/proc/can_speak() return 1 /atom/movable/proc/send_speech(message, range = 7, atom/movable/source = src, bubble_type, list/spans, datum/language/message_language = null, message_mode) var/rendered = compose_message(src, message_language, message, , spans, message_mode, source) - for(var/_AM in get_hearers_in_view(range, source)) + var/list/hearers = get_hearers_in_view(range, source) + for(var/_AM in hearers) var/atom/movable/AM = _AM AM.Hear(rendered, src, message_language, message, , spans, message_mode, source) + if(vocal_bark || vocal_bark_id) + for(var/mob/M in hearers) + if(!M.client) + continue + if(!(M.client.prefs.toggles & SOUND_BARK)) + hearers -= M + var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS) + var/total_delay + for(var/i in 1 to barks) + if(total_delay > BARK_MAX_TIME) + break + addtimer(CALLBACK(src, .proc/bark, hearers, range, vocal_volume, BARK_DO_VARY(vocal_pitch, vocal_pitch_range)), total_delay) + total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS(vocal_speed / BARK_SPEED_BASELINE)) TICKS /atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE, atom/movable/source) if(!source) diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 9a74b63040..19201299c2 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -50,6 +50,10 @@ H.dna.features["flavor_text"] = "" //Oh no. H.dna.features["body_model"] = H.gender + H.set_bark(pick(GLOB.bark_random_list)) + H.vocal_pitch = BARK_PITCH_RAND(H.gender) + H.vocal_pitch_range = BARK_VARIANCE_RAND + SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE) H.update_body(TRUE) diff --git a/code/modules/antagonists/gang/gang.dm b/code/modules/antagonists/gang/gang.dm index ea81c8b1af..050754a91e 100644 --- a/code/modules/antagonists/gang/gang.dm +++ b/code/modules/antagonists/gang/gang.dm @@ -67,6 +67,11 @@ if(handler) // if we have a handler, the handler should track this gang handler.gangs += my_gang my_gang.current_theme = handler.current_theme + else if(GLOB.families_override_theme) + my_gang.current_theme = new GLOB.families_override_theme + else + var/theme_to_use = pick(subtypesof(/datum/gang_theme)) + my_gang.current_theme = new theme_to_use my_gang.name = gang_name my_gang.gang_id = gang_id my_gang.acceptable_clothes = acceptable_clothes.Copy() diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm index cba5dce870..943fdeb14a 100644 --- a/code/modules/atmospherics/auxgm/gas_types.dm +++ b/code/modules/atmospherics/auxgm/gas_types.dm @@ -295,4 +295,4 @@ powermix = -1 transmit_modifier = -10 heat_penalty = -10 - price = 10 + price = 100 // it's kinda really hard to actually get it into a canister diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 122d30f33e..607274f71b 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -759,7 +759,18 @@ var/initial_energy = air.thermal_energy() for(var/g in air.get_gases()) air.set_moles(g, 0) - air.set_moles(GAS_QCD, initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD])) + var/amount = initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD]) + air.set_moles(GAS_QCD, amount) + var/list/largest_values = SSresearch.science_tech.largest_values + if(!(GAS_QCD in largest_values)) + largest_values[GAS_QCD] = 0 + var/previous_largest = largest_values[GAS_QCD] + var/research_amount = amount * QCD_RESEARCH_AMOUNT + if(previous_largest < research_amount) + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount) + largest_values[GAS_QCD] = research_amount + else + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount / 100) /datum/gas_reaction/dehagedorn priority = 50 @@ -781,11 +792,10 @@ var/list/gases = GLOB.gas_data.specific_heats.Copy() gases -= GAS_QCD gases -= GAS_TRITIUM // no refusing sorry - for(var/g in gases) - gases[g] = 10000 / gases[g] + gases -= GAS_HYPERNOB // makes it waaay too easy to stabilize it while(energy_remaining > 0) var/G = pick(gases) air.adjust_moles(G, max(0.1, energy_remaining / (gases[G] * new_temp * 20))) energy_remaining = initial_energy - air.thermal_energy() - air.adjust_heat(-energy_remaining) + air.set_temperature(initial_energy / air.heat_capacity()) return REACTING diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 4b7f9bd26e..15c511e9d8 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -237,6 +237,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/modified_limbs = list() //prosthetic/amputated limbs var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded + // Vocal bark prefs + var/bark_id = "mutedc3" + var/bark_speed = 4 + var/bark_pitch = 1 + var/bark_variance = 0.2 + COOLDOWN_DECLARE(bark_previewing) + /// Security record note section var/security_records /// Medical record note section @@ -960,16 +967,25 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
Damage:BruteBurn
" - //END OF SKYRAT EDIT + //END OF SANDSTORM EDIT + dat += "" dat += "
" dat += "

Speech preferences

" dat += "Custom Speech Verb:
" - dat += "[custom_speech_verb]
" + dat += "[custom_speech_verb]
" dat += "Custom Tongue:
" - dat += "[custom_tongue]
" - //SKYRAT EDIT - additional language + runechat color + dat += "[custom_tongue]
" + //SANDSTORM EDIT - additional language + runechat color dat += "Additional Language
" var/list/languages_sorted = sortList(language) dat += "[language.len ? languages_sorted.Join(", ") : "None"]
" dat += "Custom runechat color: [enable_personal_chat_color ? "Enabled" : "Disabled"]
[enable_personal_chat_color ? "[personal_chat_color] Change" : ""]
" dat += "
" + dat += "

Vocal Bark preferences

" + var/datum/bark/B = GLOB.bark_list[bark_id] + dat += "Vocal Bark Sound:
" + dat += "[B ? initial(B.name) : "INVALID"]
" + dat += "Vocal Bark Speed: [bark_speed]
" + dat += "Vocal Bark Pitch: [bark_pitch]
" + dat += "Vocal Bark Variance: [bark_variance]
" + dat += "
Preview Bark
" dat += "
" @@ -2888,6 +2904,43 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(selected_custom_speech_verb) custom_speech_verb = selected_custom_speech_verb + if("barksound") + var/list/woof_woof = list() + for(var/path in GLOB.bark_list) + var/datum/bark/B = GLOB.bark_list[path] + if(initial(B.ignore)) + continue + if(initial(B.ckeys_allowed)) + var/list/allowed = initial(B.ckeys_allowed) + if(!allowed.Find(user.client.ckey)) + continue + woof_woof[initial(B.name)] = initial(B.id) + var/new_bork = input(user, "Choose your desired vocal bark", "Character Preference") as null|anything in woof_woof + if(new_bork) + bark_id = woof_woof[new_bork] + var/datum/bark/B = GLOB.bark_list[bark_id] //Now we need sanitization to take into account bark-specific min/max values + bark_speed = round(clamp(bark_speed, initial(B.minspeed), initial(B.maxspeed)), 1) + bark_pitch = clamp(bark_pitch, initial(B.minpitch), initial(B.maxpitch)) + bark_variance = clamp(bark_variance, initial(B.minvariance), initial(B.maxvariance)) + + if("barkspeed") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired bark speed (Higher is slower, lower is faster). Min: [initial(B.minspeed)]. Max: [initial(B.maxspeed)]", "Character Preference") as null|num + if(borkset) + bark_speed = round(clamp(borkset, initial(B.minspeed), initial(B.maxspeed)), 1) + + if("barkpitch") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minpitch)]. Max: [initial(B.maxpitch)]", "Character Preference") as null|num + if(borkset) + bark_pitch = clamp(borkset, initial(B.minpitch), initial(B.maxpitch)) + + if("barkvary") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minvariance)]. Max: [initial(B.maxvariance)]", "Character Preference") as null|num + if(borkset) + bark_variance = clamp(borkset, initial(B.minvariance), initial(B.maxvariance)) + if("bodysprite") var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids if(selected_body_sprite) @@ -3446,6 +3499,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("hud_toggle_flash") hud_toggle_flash = !hud_toggle_flash + if("barkpreview") + if(SSticker.current_state == GAME_STATE_STARTUP) //Timers don't tick at all during game startup, so let's just give an error message + to_chat(user, "Bark previews can't play during initialization!") + return + if(!COOLDOWN_FINISHED(src, bark_previewing)) + return + if(!parent || !parent.mob) + return + COOLDOWN_START(src, bark_previewing, (5 SECONDS)) + var/atom/movable/barkbox = new(get_turf(parent.mob)) + barkbox.set_bark(bark_id) + var/total_delay + for(var/i in 1 to (round((32 / bark_speed)) + 1)) + addtimer(CALLBACK(barkbox, /atom/movable/proc/bark, list(parent.mob), 7, 70, BARK_DO_VARY(bark_pitch, bark_variance)), total_delay) + total_delay += rand(DS2TICKS(bark_speed/4), DS2TICKS(bark_speed/4) + DS2TICKS(bark_speed/4)) TICKS + QDEL_IN(barkbox, total_delay) + if("save") save_preferences() save_character() @@ -3690,6 +3760,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(custom_speech_verb != "default") character.dna.species.say_mod = custom_speech_verb + character.set_bark(bark_id) + character.vocal_speed = bark_speed + character.vocal_pitch = bark_pitch + character.vocal_pitch_range = bark_variance + //limb stuff, only done when initially spawning in if(initial_spawn) //delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index b17fdcc923..6d9842ff35 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -5,7 +5,7 @@ // You do not need to raise this if you are adding new values that have sane defaults. // Only raise this value when changing the meaning/format/name/layout of an existing value // where you would want the updater procs below to run -#define SAVEFILE_VERSION_MAX 54 +#define SAVEFILE_VERSION_MAX 55 /* SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn @@ -42,6 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //if your savefile is 3 months out of date, then 'tough shit'. /datum/preferences/proc/update_preferences(current_version, savefile/S) + if(current_version < 55) //Bitflag toggles don't set their defaults when they're added, always defaulting to off instead. + toggles |= SOUND_BARK if(current_version < 46) //If you remove this, remove force_reset_keybindings() too. force_reset_keybindings_direct(TRUE) addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice. @@ -967,6 +969,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //SPLURT edit S["feature_naked_flavor_text"] >> features["naked_flavor_text"] //end + // Barks + S["bark_id"] >> bark_id + S["bark_speed"] >> bark_speed + S["bark_pitch"] >> bark_pitch + S["bark_variance"] >> bark_variance S["vore_flags"] >> vore_flags S["vore_taste"] >> vore_taste @@ -1161,6 +1168,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car scars_list["4"] = sanitize_text(scars_list["4"]) scars_list["5"] = sanitize_text(scars_list["5"]) + bark_id = sanitize_inlist(bark_id, GLOB.bark_list, pick(GLOB.bark_random_list)) + var/datum/bark/bark_path = GLOB.bark_list[bark_id] + bark_speed = sanitize_num_clamp(bark_speed, initial(bark_path.minspeed), initial(bark_path.maxspeed), initial(bark_speed)) + bark_pitch = sanitize_num_clamp(bark_pitch, initial(bark_path.minpitch), initial(bark_path.maxpitch), BARK_PITCH_RAND(gender)) + bark_variance = sanitize_num_clamp(bark_variance, initial(bark_path.minvariance), initial(bark_path.maxvariance), BARK_VARIANCE_RAND) + joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) //Validate job prefs for(var/j in job_preferences) @@ -1227,6 +1240,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["species"] , pref_species.id) WRITE_FILE(S["custom_speech_verb"] , custom_speech_verb) WRITE_FILE(S["custom_tongue"] , custom_tongue) + WRITE_FILE(S["bark_id"] , bark_id) + WRITE_FILE(S["bark_speed"] , bark_speed) + WRITE_FILE(S["bark_pitch"] , bark_pitch) + WRITE_FILE(S["bark_variance"] , bark_variance) // records WRITE_FILE(S["security_records"] , security_records) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index fde9a3e8d5..94d1bb2c42 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -226,6 +226,17 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)() return C.prefs.toggles & SOUND_PRAYERS +TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_bark)() + set name = "Hear/Silence Vocal Barks" + set category = "Preferences" + set desc = "Hear Vocal Barks" + usr.client.prefs.toggles ^= SOUND_BARK + usr.client.prefs.save_preferences() + to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_BARK) ? "hear" : "no longer hear"] vocal barks when other people talk.") + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Vocal Barks", "[usr.client.prefs.toggles & SOUND_BARK ? "Enabled" : "Disabled"]")) +/datum/verbs/menu/Settings/Sound/toggle_bark/Get_checked(client/C) + return C.prefs.toggles & SOUND_BARK + /datum/verbs/menu/Settings/Sound/verb/stop_client_sounds() set name = "Stop Sounds" set category = "Preferences" diff --git a/code/modules/mapping/minimaps.dm b/code/modules/mapping/minimaps.dm index 51fde1f8db..8768ddd1e8 100644 --- a/code/modules/mapping/minimaps.dm +++ b/code/modules/mapping/minimaps.dm @@ -47,21 +47,43 @@ var/meta_color = area_to_color[A] if(!meta_color) - meta_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) // technically conflicts could happen but it's like very unlikely and it's not that big of a deal if one happens + var/meta_x = LAZYLEN(area_to_color) + 1 + var/meta_y = (((meta_x + 1) - ((meta_x + 1) % 255)) / 255) + var/meta_z = (((meta_y + 1) - ((meta_y + 1) % 255)) / 255) + meta_color = rgb(meta_x % 255, meta_y % 255, meta_z % 255) //This supports exactly 16,581,374 areas with no conflicts whatsoever before it just gives up area_to_color[A] = meta_color color_area_names[meta_color] = A.name meta_icon.DrawBox(meta_color, img_x, img_y) - if(istype(T, /turf/closed/wall)) + if(A.minimap_show_walls && istype(T, /turf/closed/wall)) map_icon.DrawBox("#000000", img_x, img_y) else if(!istype(A, /area/space)) - var/color = A.minimap_color || "#FF00FF" - if(locate(/obj/machinery/power/solar) in T) - color = "#02026a" + var/color = (A.minimap_color2 ? (((img_x + img_y) % 2) ? A.minimap_color2 : A.minimap_color ) : A.minimap_color) || "#FF00FF" + if(A.minimap_show_walls) + var/overridden + for(var/obj/structure/O in T) + if(O.minimap_override_color) + color = O.minimap_override_color + overridden = TRUE + break + else if(O.density && O.anchored) + color = BlendRGB(color, "#000000", 0.5) + overridden = TRUE + break + + //In an ideal world, we'd be able to get away with just doing for(var/obj/O in T) up there, and calling it a day. However. HOWEVER! + //Doing that causes the code to also loop through items. and that uh. Kinda bloats minimap gen time. A LOT. We're talking straight-up doubling the time it takes to gen. + //So instead we take our ctrl+c. We copy the above code. And we ctrl+v. It's awful. We hate it. But it works. It's faster. Funny mapgen go vroom + if(!overridden) + for(var/obj/machinery/O in T) + if(O.minimap_override_color) + color = O.minimap_override_color + break + else if(O.density && O.anchored) + color = BlendRGB(color, "#000000", 0.25) + break - if((locate(/obj/effect/spawner/structure/window) in T) || (locate(/obj/structure/grille) in T)) - color = BlendRGB(color, "#000000", 0.5) map_icon.DrawBox(color, img_x, img_y) map_icon.Crop(crop_x1, crop_y1, crop_x2, crop_y2) @@ -102,22 +124,48 @@ var/list/datas = list() var/list/info = list() - - for(var/i in 1 to length(minimaps))// OLD: for(var/i in 1 to length(minimaps)) + var/buttonfield = "" + var/totalmaps = length(minimaps) + for(var/i in 1 to totalmaps)// OLD: for(var/i in 1 to length(minimaps)) var/datum/minimap/M = minimaps[i] var/map_name = "minimap-[M.id].png" var/meta_name = "minimap-[M.id]-meta.png" M.send(user) info += {" -
+
+ [totalmaps > 1 ? "

Layer [i]

" : ""]
-
+ [totalmaps <= 1 ? "
" : ""]
"} datas += json_encode(M.color_area_names); + buttonfield += "Layer [i] " + + if(totalmaps > 1) + info += "
[buttonfield]
" + + //This is a hacky workaround; the status display is extremely buggy when multiple z-levels are present. We couldn't figure out how to fix this after 7 hours of banging our head against the wall + //We're coder + var/mousemove_bit = {" + canvas.onmousemove = function(e){ + var rect = canvas.getBoundingClientRect(); + var x = Math.floor(e.offsetX * img.width / rect.width); + var y = Math.floor(e.offsetY * img.height / rect.height); + + var color_idx = x * 4 + (y * 4 * imagedata.width); + var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]); + + label.textContent = data\[color]; + canvas.title = data\[color]; + } + canvas.onmouseout = function(e){ + label.textContent = " "; + canvas.title = ""; + } + "} info = info.Join() //this is bad. Too bad! @@ -133,6 +181,14 @@ } return num; } + function switchmap(mapid) { + var targetblock = document.getElementById(mapid); + for(var i = 0; i < [length(minimaps)]; i++) { + var currentblock = document.getElementById("layer-" + (i + 1)); + currentblock.style.display = 'none'; + } + targetblock.style.display = ''; + } window.onload = function() { if(!window.HTMLCanvasElement) { var label = document.getElementById("label-1"); @@ -150,6 +206,7 @@ var canvas = document.createElement("canvas"); canvas.width = img.width * 2; canvas.height = img.height * 2; + canvas.id = "canvas-" + (i+1); var ctx = canvas.getContext('2d'); ctx.msImageSmoothingEnabled = false; @@ -158,31 +215,23 @@ ctx = document.createElement("canvas").getContext('2d'); ctx.canvas.width = img.width; ctx.canvas.height = img.height; + ctx.id = "ctx-" + (i+1); ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0); var imagedata = ctx.getImageData(0, 0, img.width, img.height); - canvas.onmousemove = function(e){ - var rect = canvas.getBoundingClientRect(); - var x = Math.floor(e.offsetX * img.width / rect.width); - var y = Math.floor(e.offsetY * img.height / rect.height); - - var color_idx = x * 4 + (y * 4 * imagedata.width); - var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]); - var label = document.getElementById("label-" + (i+1)); //label-String(n) - - label.textContent = data\[color]; - canvas.title = data\[color]; - } - canvas.onmouseout = function(e){ - canvas.title = ""; - } + var label = document.getElementById("label-" + (i+1)); //label-String(n); + [totalmaps <= 1 ? mousemove_bit : ""] } } diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index a9233938ab..378313311e 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -24,6 +24,9 @@ var/rando_race = pick(GLOB.roundstart_races) pref_species = new rando_race() features = random_features(pref_species?.id, gender) + bark_id = pick(GLOB.bark_random_list) + bark_pitch = BARK_PITCH_RAND(gender) + bark_variance = BARK_VARIANCE_RAND age = rand(AGE_MIN,AGE_MAX) /datum/preferences/proc/update_preview_icon(current_tab) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 9f85b94d03..2ef3aa36a6 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -157,11 +157,11 @@ . += "" . += "[t_He] [t_is] currently in [gender == MALE ? "rut" : "heat"]." - SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) - - if(length(.) > 1) + if(LAZYLEN(.) > 1) .[1] += "
" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) + /mob/living/carbon/examine_more(mob/user) if(!all_scars) return ..() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 5a9a2ebf62..edb5de8188 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -516,10 +516,10 @@ else if(isobserver(user) && traitstring) . += "Traits: [traitstring]" - SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now + if(LAZYLEN(.) > 2) //Want this to appear after species text + .[2] += "
" - if(length(.) > 1) - .[1] += "
" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now /mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects! var/list/dat = list() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e79a887dad..3f5b8819be 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -597,18 +597,18 @@ var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE - to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" + to_send += "Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" for(var/thing in LB.wounds) var/datum/wound/W = thing var/msg switch(W.severity) if(WOUND_SEVERITY_TRIVIAL) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." if(WOUND_SEVERITY_MODERATE) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" if(WOUND_SEVERITY_SEVERE) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" if(WOUND_SEVERITY_CRITICAL) msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" to_send += "\n[msg]" diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index f9fcb35377..735f271133 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -308,8 +308,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list( AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source) SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message) - if(client && !eavesdrop_range && say_test(message) == "2") // Yell hook - process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source) + var/is_yell = (say_test(message) == "2") + if(client && !eavesdrop_range && is_yell) // Yell hook + listening |= process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source) //speech bubble var/list/speech_bubble_recipients = list() @@ -320,6 +321,22 @@ GLOBAL_LIST_INIT(department_radio_keys, list( I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30) + //Listening gets trimmed here if a vocal bark's present. If anyone ever makes this proc return listening, make sure to instead initialize a copy of listening in here to avoid wonkiness + if(vocal_bark || vocal_bark_id) + for(var/mob/M in listening) + if(!M.client) + continue + if(!(M.client.prefs.toggles & SOUND_BARK)) + listening -= M + var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS) + var/total_delay + for(var/i in 1 to barks) + if(total_delay > BARK_MAX_TIME) + break + addtimer(CALLBACK(src, /atom/movable/proc/bark, listening, (message_range * (is_yell ? 4 : 1)), (vocal_volume * (is_yell ? 1.5 : 1)), BARK_DO_VARY(vocal_pitch, vocal_pitch_range)), total_delay) + total_delay += rand(DS2TICKS((vocal_speed / BARK_SPEED_BASELINE) * (is_yell ? 0.5 : 1)), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS((vocal_speed / BARK_SPEED_BASELINE) * (is_yell ? 0.5 : 1))) TICKS + + /atom/movable/proc/process_yelling(list/already_heard, rendered, atom/movable/speaker, datum/language/message_language, message, list/spans, message_mode, obj/source) if(last_yell > (world.time - 10)) to_chat(src, "Your voice doesn't project as far as you try to yell in such quick succession.") // yeah no, no spamming an expensive floodfill. @@ -344,6 +361,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/atom/movable/AM = _AM AM.Hear(rendered, speaker, message_language, message, null, spans, message_mode, source) + return overhearing + /mob/proc/binarycheck() return FALSE diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm index 2a68668889..cb32b5c893 100644 --- a/code/modules/mob/living/silicon/ai/examine.dm +++ b/code/modules/mob/living/silicon/ai/examine.dm @@ -18,7 +18,7 @@ else if (!shunted && !client) . += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem..." if(length(.) > 1) - .[1] += "\n
" + .[1] += "
" . += "
" diff --git a/code/modules/mob/living/silicon/examine.dm b/code/modules/mob/living/silicon/examine.dm index 7de281de5f..0840ea1191 100644 --- a/code/modules/mob/living/silicon/examine.dm +++ b/code/modules/mob/living/silicon/examine.dm @@ -1,5 +1,4 @@ /mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts - . = ..() if(laws && isobserver(user)) . += "[src] has the following laws:" for(var/law in laws.get_law_list(include_zeroth = TRUE)) diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index f8c3dd37e9..2aa9194dc8 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -49,10 +49,13 @@ if(DEAD) . += "It looks like its system is corrupted and requires a reset." + if(LAZYLEN(.) > 1) + .[2] = "
[.[2]]" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .) if(length(.) > 1) - .[1] += "\n
" + .[1] += "
" . += "" diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 13f1bea1e4..3b89413271 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -49,6 +49,9 @@ typing_indicator_state = /obj/effect/overlay/typing_indicator/machine + vocal_bark_id = "synth" + vocal_pitch_range = 0.1 + /mob/living/silicon/Initialize(mapload) . = ..() GLOB.silicon_mobs += src diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index c1897c3c05..a7bd8ca921 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -35,6 +35,9 @@ collar_type = "cat" var/held_icon = "cat2" footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "mutedc4" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 /mob/living/simple_animal/pet/cat/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 748a182ba3..fb8c937ea8 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -20,6 +20,9 @@ footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "bullet" + vocal_speed = 6 + /mob/living/simple_animal/pet/dog/ComponentInitialize() . = ..() AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE) @@ -639,6 +642,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( mob_size = MOB_SIZE_SMALL collar_type = "puppy" + vocal_pitch = 1.6 + //puppies cannot wear anything. /mob/living/simple_animal/pet/dog/corgi/puppy/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) @@ -660,6 +665,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( maxbodytemp = T0C + 40 held_icon = "void_puppy" + vocal_pitch = 0.6 + /mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0) return 1 //Void puppies can navigate space. diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 0ec687c3e3..ca827c29e5 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -36,6 +36,7 @@ var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "banjoc3" /mob/living/simple_animal/hostile/retaliate/goat/Initialize(mapload, /datum/reagent/milk_reagent) udder = new (null, milk_reagent) @@ -144,6 +145,8 @@ blood_volume = BLOOD_VOLUME_NORMAL footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "mutedc2" + vocal_pitch = 1.2 /mob/living/simple_animal/cow/Initialize(mapload) udder = new(null, milk_reagent) @@ -248,6 +251,8 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/chick/Initialize(mapload) . = ..() @@ -310,6 +315,9 @@ var/static/chicken_count = 0 footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "synthgrunt" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 /mob/living/simple_animal/chicken/Initialize(mapload) . = ..() @@ -404,6 +412,8 @@ var/static/kiwi_count = 0 footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/kiwi/Destroy() --kiwi_count @@ -482,6 +492,8 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/babyKiwi/Initialize(mapload) . = ..() @@ -558,3 +570,4 @@ maxHealth = 75 blood_volume = BLOOD_VOLUME_NORMAL footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "mutedc4" diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 4e4fd7ccfc..475b50d44a 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -23,6 +23,11 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "bullet" + vocal_speed = 2 + vocal_pitch = 1.6 + vocal_pitch_range = 0.4 + /mob/living/simple_animal/pet/fox/ComponentInitialize() . = ..() AddElement(/datum/element/mob_holder, "fox") diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index d49eb1251d..f67c5dcb97 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -29,6 +29,8 @@ gold_core_spawnable = FRIENDLY_SPAWN var/chew_probability = 1 faction = list("rat") + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/mouse/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/simple_animal/friendly/plushie.dm b/code/modules/mob/living/simple_animal/friendly/plushie.dm index ff95e8fe86..4821695f45 100644 --- a/code/modules/mob/living/simple_animal/friendly/plushie.dm +++ b/code/modules/mob/living/simple_animal/friendly/plushie.dm @@ -29,6 +29,8 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 pressure_resistance = 200 + vocal_bark_id = "squeak" + vocal_pitch_range = 0.4 /mob/living/simple_animal/pet/plushie/ComponentInitialize() . = ..() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index fad48b4854..27fb30a459 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -5,6 +5,7 @@ desc = "A solar panel. Generates electricity when in contact with sunlight." icon = 'goon/icons/obj/power.dmi' icon_state = "sp_base" + minimap_override_color = "#02026a" density = TRUE use_power = NO_POWER_USE idle_power_usage = 0 diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index d542694236..dc07a5a184 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -17,7 +17,7 @@ var/list/obj/machinery/computer/rdconsole/consoles_accessing = list() var/id = "generic" var/list/research_logs = list() //IC logs. - var/largest_bomb_value = 0 + var/largest_values = list() var/organization = "Third-Party" //Organization name, used for display. var/list/next_income = list() //To be applied on the next passive techweb income var/list/last_bitcoins = list() //Current per-second production, used for display only. diff --git a/code/modules/vehicles/mecha/combat/five_stars.dm b/code/modules/vehicles/mecha/combat/five_stars.dm index 6a73c3adde..def8e94cc8 100644 --- a/code/modules/vehicles/mecha/combat/five_stars.dm +++ b/code/modules/vehicles/mecha/combat/five_stars.dm @@ -4,7 +4,6 @@ icon = 'icons/mecha/mecha_96x96.dmi' icon_state = "five_stars" armor = list(MELEE = 100, BULLET = 50, LASER = 35, ENERGY = 35, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) - step_in = 4 dir_in = 1 //Facing North. max_integrity = 800 pixel_x = -32 diff --git a/html/changelogs/archive/2022-06.yml b/html/changelogs/archive/2022-06.yml index c66a629e83..bbeeed3d82 100644 --- a/html/changelogs/archive/2022-06.yml +++ b/html/changelogs/archive/2022-06.yml @@ -206,3 +206,51 @@ - rscadd: Debug Omnitool (Admin-only, sorry) - tweak: Enforcer Voidsuit now has armor equivalent to Security Winter Jackets - tweak: Gave Detectives badges, too! +2022-06-11: + Bhijn & Myr: + - rscadd: The station minimap now features higher detail! Instead of just windows + and grilles being outlined, all dense+anchored structures and machinery are + shown on the minimap. + - rscadd: The station minimap now supports obfuscating entire areas, via the minimap_show_walls + var. + - rscadd: 'The station minimap now supports defining two area colors, allowing for + a checkerboard pattern! tweak: Hallways and maint have been given white and + gray colors, respectively, for ease of readability. tweak: Ruins are now obfuscated + on the minimap, and have been given a subtle, yet distinct, color pattern!' + - bugfix: The station minimap no longer errors when you mouse over it + - rscadd: 'The station minimap now supports multiz! (However, due to bugginess, + multiz minimaps won''t display area tooltips.) tweak: The station minimap now + features pixel-perfect scaling.' + - code_imp: The station minimap can now support managing data for up to 16,581,374 + areas without any conflicts at all! Before, BYOND's psuedorandom RNG meant that + it was somewhat common for areas to collide with each others' data. + - rscadd: Talking is now accompanied with fully-customizable sounds! You can modify + your character's speech under the speech tab in chargen, and you can toggle + these sounds via the "Hear/Silence Vocal Barks" verb under the preferences tab! + This also fully supports genetics. + - bugfix: Admittedly an unatomized change, but Cit's DNA blocks can now properly + be updated through genetics. Before, these required a complete genetics reset + to apply. + - rscadd: 'The chat now supports blockquotes! tweak: Examining, medical scanners, + self-checking, and mood checkups, have all been converted to make use of blockquotes.' + Bhijn & Myr (+ UI work and cleanup by Sandpoot!): + - rscadd: 'Colormates now have HSV coloration! tweak: Colormates have had their + "please use white clothing" message removed, as that recommendation''s now mostly + pointless tweak: The default mode for colormates is now HSV coloration tweak: + The temp messages in colormates have been tweaked slightly to be more user-friendly, + as they''re user-facing. tweak: The description for constants in the colormate + matrix mode has been fixed; the constant variables have nothing to do with contrast, + they simply add color tweak: Matrix mode has been made a lot more usable; it''s + now clamped between -10 and 10, and features a step of 0.01, making it much + easier to simply click and drag to adjust the values, rather than having to + punch them in manually' + Putnam3145: + - balance: QCD matter is now worth 10x as much and makes 2 research pointer per + mole + SandPoot: + - bugfix: Fixed items that use strip_mod and strip_silence (stripping people faster + or without giving them a message) + - rscadd: Added a search box to all vending machine uis. + - qol: Vending machines have candystripes for better clarity. + keronshb: + - bugfix: Families fixed from crashing diff --git a/modular_sand/code/modules/client/preferences_savefile.dm b/modular_sand/code/modules/client/preferences_savefile.dm index ef6a14917a..1a604182c3 100644 --- a/modular_sand/code/modules/client/preferences_savefile.dm +++ b/modular_sand/code/modules/client/preferences_savefile.dm @@ -6,3 +6,14 @@ else var/tmp = language language = list(tmp) + +/datum/preferences/update_preferences(current_version, savefile/S) + // Citadel added a new bitfield to toggles, we need to push our prefs forward starting from the last bit + if(current_version < 55) + if(CHECK_BITFIELD(toggles, VERB_CONSENT)) + DISABLE_BITFIELD(toggles, VERB_CONSENT) + ENABLE_BITFIELD(toggles, LEWD_VERB_SOUNDS) + if(CHECK_BITFIELD(toggles, SOUND_BARK)) + DISABLE_BITFIELD(toggles, SOUND_BARK) + ENABLE_BITFIELD(toggles, VERB_CONSENT) + . = ..() diff --git a/tgstation.dme b/tgstation.dme index a5fbd270e3..036b8a15cd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -485,6 +485,7 @@ #include "code\datums\action.dm" #include "code\datums\ai_laws.dm" #include "code\datums\armor.dm" +#include "code\datums\bark.dm" #include "code\datums\beam.dm" #include "code\datums\beepsky_fashion.dm" #include "code\datums\browser.dm" @@ -3737,6 +3738,7 @@ #include "code\modules\vehicles\mecha\mecha_wreckage.dm" #include "code\modules\vehicles\mecha\combat\combat.dm" #include "code\modules\vehicles\mecha\combat\durand.dm" +#include "code\modules\vehicles\mecha\combat\five_stars.dm" #include "code\modules\vehicles\mecha\combat\gygax.dm" #include "code\modules\vehicles\mecha\combat\honker.dm" #include "code\modules\vehicles\mecha\combat\marauder.dm" diff --git a/tgui/packages/tgui-panel/styles/components/Chat.scss b/tgui/packages/tgui-panel/styles/components/Chat.scss index b439ace8c5..a199963fd0 100644 --- a/tgui/packages/tgui-panel/styles/components/Chat.scss +++ b/tgui/packages/tgui-panel/styles/components/Chat.scss @@ -98,3 +98,24 @@ $color-bg-section: base.$color-bg-section !default; pointer-events: none; } } + +blockquote { + background-color: rgba($text-color, 0.05); + border-left: 0.15em solid; + border-color: $text-color; + padding-left: 0.3em; + padding-right: 0.3em; + margin-bottom: 0.15em; + margin-left: 0.3em; + margin-right: 0em; +} + +hr { + background-color: rgba($text-color, 0.25); + height: 0.15em; + border-style: none; + margin-left: 1em; + margin-right: 2em; + margin-bottom: 0.3em; + margin-top: 0.3em; +} diff --git a/tgui/packages/tgui-panel/styles/goon/chat-dark.scss b/tgui/packages/tgui-panel/styles/goon/chat-dark.scss index 049b7464ee..2d31efcae1 100644 --- a/tgui/packages/tgui-panel/styles/goon/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/goon/chat-dark.scss @@ -447,6 +447,10 @@ em { font-style: italic; } +blockquote.warning { + border-color: #c51e1e; +} + .alertwarning { color: #FF0000; font-weight: bold; @@ -486,10 +490,18 @@ em { color: #9ab0ff; } +blockquote.info { + border-color: #9ab0ff; +} + .notice { color: #6685f5; } +blockquote.notice { + border-color: #6685f5; +} + .tinynotice { color: #6685f5; font-size: 85%; @@ -545,18 +557,34 @@ em { color: #059223; } +blockquote.green { + border-color: #059223; +} + .red { color: #FF0000; } +blockquote.red { + border-color: #FF0000; +} + .blue { color: #215cff; } +blockquote.blue { + border-color: #215cff; +} + .nicegreen { color: #059223; } +blockquote.nicegreen { + border-color: #059223; +} + /* hornichems */ .userlove { color: #ff42a6; @@ -579,6 +607,10 @@ em { color: #973e3b; } +blockquote.cult { + border-color: #973e3b; +} + .cultitalic { color: #973e3b; font-style: italic; @@ -634,6 +666,10 @@ em { color: #9956d3; } +blockquote.purple { + border-color: #9956d3; +} + .holoparasite { color: #88809c; } @@ -697,6 +733,10 @@ em { color: #BE8700; } +blockquote.brass { + border-color: #BE8700; +} + .heavy_brass { color: #BE8700; font-weight: bold; diff --git a/tgui/packages/tgui-panel/styles/goon/chat-light.scss b/tgui/packages/tgui-panel/styles/goon/chat-light.scss index 54646e7f4a..69db6e9026 100644 --- a/tgui/packages/tgui-panel/styles/goon/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/goon/chat-light.scss @@ -484,6 +484,10 @@ h1.alert, h2.alert { font-style: italic; } +blockquote.warning { + border-color: #ff0000; +} + .alertwarning { color: #FF0000; font-weight: bold; @@ -522,11 +526,18 @@ h1.alert, h2.alert { .info { color: #0000CC; } +blockquote.info { + border-color: #0000CC; +} .notice { color: #000099; } +blockquote.notice { + border-color: #000099; +} + .tinynotice { color: #000099; font-size: 85%; @@ -582,18 +593,33 @@ h1.alert, h2.alert { color: #03ff39; } +blockquote.green { + border-color: #03ff39; +} + .red { color: #FF0000; } +blockquote.red { + border-color: #FF0000; +} .blue { color: #0000FF; } +blockquote.blue { + border-color: #0000FF; +} + .nicegreen { color: #14a833; } +blockquote.nicegreen { + border-color: #14a833; +} + /* hornichems */ .userlove { color: #FF1493; @@ -616,6 +642,10 @@ h1.alert, h2.alert { color: #973e3b; } +blockquote.cult { + border-color: #973e3b; +} + .cultitalic { color: #973e3b; font-style: italic; @@ -671,6 +701,10 @@ h1.alert, h2.alert { color: #5e2d79; } +blockquote.purple { + border-color: #5e2d79; +} + .holoparasite { color: #35333a; } @@ -735,6 +769,10 @@ h1.alert, h2.alert { color: #BE8700; } +blockquote.brass { + border-color: #BE8700; +} + .heavy_brass { color: #BE8700; font-weight: bold; diff --git a/tgui/packages/tgui/interfaces/Colormate.js b/tgui/packages/tgui/interfaces/Colormate.js index f376547102..02810f2943 100644 --- a/tgui/packages/tgui/interfaces/Colormate.js +++ b/tgui/packages/tgui/interfaces/Colormate.js @@ -1,115 +1,120 @@ import { useBackend } from '../backend'; -import { Button, Flex, Icon, NoticeBox, NumberInput, Section, Tabs } from '../components'; +import { Button, Icon, NoticeBox, NumberInput, Section, Table, Tabs, Slider } from '../components'; import { Window } from '../layouts'; export const Colormate = (props, context) => { const { act, data } = useBackend(context); - const { matrixactive, temp } = data; + const { activemode, temp } = data; const item = data.item || []; return ( - {temp ? ( - {temp} - ) : (null)} - {Object.keys(item).length ? ( - <> - -
-
Item:
- -
-
-
Preview:
- -
-
-
+
+ {temp ? ( + {temp} + ) : (null)} + {Object.keys(item).length ? ( + <> + + +
+
Item:
+ +
+
+ +
+
Preview:
+ +
+
+
act('switch_modes', { - mode: "0", + mode: 1, })} > - Regular coloring + Tint coloring (Simple) act('switch_modes', { - mode: "1", + mode: 2, })} > - Matrixed coloring + HSV coloring (Normal) + + act('switch_modes', { + mode: 3, + })} > + Matrix coloring (Advanced) - {matrixactive ? ( - <> -
Coloring: {item.name}
- - - ) : ( - <> -
Coloring: {item.name}
- - - )} -
- - ) : ( -
+
Coloring: {item.name}
+ + +
+ + ) : (
No item inserted.
-
- )} + )} +
); }; -export const ColormateNoMatrix = (props, context) => { +export const ColormateTint = (props, context) => { const { act, data } = useBackend(context); return ( -
- - -
+