From 321902c35a583531f728dd532fd449782912c5dc Mon Sep 17 00:00:00 2001 From: Artur Date: Thu, 23 Apr 2020 13:28:09 +0300 Subject: [PATCH] Ports https://github.com/tgstation/tgstation/pull/50225 --- _maps/RandomZLevels/research.dmm | 4 +- code/datums/dna.dm | 19 ++- code/datums/mutations/_mutations.dm | 20 +++ code/game/objects/items/chromosome.dm | 10 +- code/modules/admin/verbs/randomverbs.dm | 2 +- code/modules/hydroponics/grown/replicapod.dm | 2 +- .../mob/living/carbon/carbon_defines.dm | 8 + .../mob/living/carbon/human/species.dm | 2 + code/modules/mob/transform_procs.dm | 144 ++++++++++++------ code/modules/spells/spell_types/lichdom.dm | 2 +- .../packages/tgui-dev-server/reloader.js | 5 + tgui-next/packages/tgui/components/Dimmer.js | 23 ++- .../packages/tgui/components/Dropdown.js | 23 ++- .../tgui/styles/components/Dropdown.scss | 11 ++ tgui/packages/tgui/components/Divider.js | 18 +++ tgui/packages/tgui/styles/atomic/outline.scss | 50 ++++++ .../tgui/styles/components/Dimmer.scss | 16 ++ .../tgui/styles/components/Divider.scss | 20 +++ tgui/packages/tgui/styles/main.scss | 1 + 19 files changed, 301 insertions(+), 79 deletions(-) create mode 100644 tgui/packages/tgui/components/Divider.js create mode 100644 tgui/packages/tgui/styles/atomic/outline.scss create mode 100644 tgui/packages/tgui/styles/components/Dimmer.scss create mode 100644 tgui/packages/tgui/styles/components/Divider.scss diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index 26ac66e98a..ec744be56d 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -1360,7 +1360,7 @@ /obj/structure/closet/crate, /obj/item/disk/data{ desc = "A data disk used to store cloning and genetic records. The name on the label appears to be scratched off."; - fields = list("label" = "Buffer1:Kr-$$@##", "UI" = "f8f603857000f930127c4", "SE" = "414401462231053131010241514651403453121613263463440351136366", "UE" = "340008485c321e542aed4df7032ac04d", "name" = "Krystal Symers", "blood_type" = "A+"); + genetic_makeup_buffer = list("label" = "Buffer1:Kr-$$@##", "UI" = "f8f603857000f930127c4", "SE" = "414401462231053131010241514651403453121613263463440351136366", "UE" = "340008485c321e542aed4df7032ac04d", "name" = "Krystal Symers", "blood_type" = "A+"); name = "dusty genetics data disk"; read_only = 1 }, @@ -1749,7 +1749,7 @@ /obj/structure/closet/crate, /obj/item/disk/data{ desc = "A data disk used to store cloning and genetic records. The name on the label appears to be scratched off with the words 'DO NOT CLONE' hastily written over it."; - fields = list("label" = "Buffer1:George Melons", "UI" = "3c300f11b5421ca7014d8", "SE" = "430431205660551642142504334461413202111310233445620533134255", "UE" = "6893e6a0b0076a41897776b10cc2b324", "name" = "George Melons", "blood_type" = "B+"); + genetic_makeup_buffer = list("label" = "Buffer1:George Melons", "UI" = "3c300f11b5421ca7014d8", "SE" = "430431205660551642142504334461413202111310233445620533134255", "UE" = "6893e6a0b0076a41897776b10cc2b324", "name" = "George Melons", "blood_type" = "B+"); name = "old genetics data disk" }, /obj/item/disk/data{ diff --git a/code/datums/dna.dm b/code/datums/dna.dm index e08d5c509c..a1cb1b3eeb 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -15,6 +15,7 @@ var/mob/living/holder var/delete_species = TRUE //Set to FALSE when a body is scanned by a cloner to fix #38875 var/mutation_index[DNA_MUTATION_BLOCKS] //List of which mutations this carbon has and its assigned block + var/default_mutation_genes[DNA_MUTATION_BLOCKS] //List of the default genes from this mutation to allow DNA Scanner highlighting var/stability = 100 var/scrambled = FALSE //Did we take something like mutagen? In that case we cant get our genes scanned to instantly cheese all the powers. var/skin_tone_override //because custom skin tones are not found in the skin_tones global list. @@ -58,6 +59,7 @@ H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA if(transfer_SE) destination.dna.mutation_index = mutation_index + destination.dna.default_mutation_genes = default_mutation_genes destination.dna.update_body_size(old_size) @@ -66,6 +68,7 @@ /datum/dna/proc/copy_dna(datum/dna/new_dna) new_dna.unique_enzymes = unique_enzymes new_dna.mutation_index = mutation_index + new_dna.default_mutation_genes = default_mutation_genes new_dna.uni_identity = uni_identity new_dna.blood_type = blood_type new_dna.skin_tone_override = skin_tone_override @@ -159,15 +162,18 @@ if(!LAZYLEN(mutations_temp)) return mutation_index.Cut() + default_mutation_genes.Cut() shuffle_inplace(mutations_temp) if(ismonkey(holder)) mutations |= new RACEMUT(MUT_NORMAL) mutation_index[RACEMUT] = GET_SEQUENCE(RACEMUT) else mutation_index[RACEMUT] = create_sequence(RACEMUT, FALSE) + default_mutation_genes[RACEMUT] = mutation_index[RACEMUT] for(var/i in 2 to DNA_MUTATION_BLOCKS) var/datum/mutation/human/M = mutations_temp[i] - mutation_index[M.type] = create_sequence(M.type, FALSE,M.difficulty) + mutation_index[M.type] = create_sequence(M.type, FALSE, M.difficulty) + default_mutation_genes[M.type] = mutation_index[M.type] shuffle_inplace(mutation_index) //Used to generate original gene sequences for every mutation @@ -372,8 +378,8 @@ return dna -/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures) - +/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, list/default_mutation_genes, newreal_name, newblood_type, datum/species/mrace, newfeatures, list/mutations, force_transfer_mutations) +//Do not use force_transfer_mutations for stuff like cloners without some precautions, otherwise some conditional mutations could break (timers, drill hat etc) if(newfeatures) var/old_size = dna.features["body_size"] dna.features = newfeatures @@ -397,6 +403,10 @@ if(LAZYLEN(mutation_index)) dna.mutation_index = mutation_index.Copy() + if(LAZYLEN(default_mutation_genes)) + dna.default_mutation_genes = default_mutation_genes.Copy() + else + dna.default_mutation_genes = mutation_index.Copy() domutcheck() SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, mutation_index, newreal_name, newblood_type, mrace, newfeatures) @@ -488,8 +498,11 @@ . = TRUE if(on) mutation_index[HM.type] = GET_SEQUENCE(HM.type) + default_mutation_genes[HM.type] = mutation_index[HM.type] else if(GET_SEQUENCE(HM.type) == mutation_index[HM.type]) mutation_index[HM.type] = create_sequence(HM.type, FALSE, HM.difficulty) + default_mutation_genes[HM.type] = mutation_index[HM.type] + /datum/dna/proc/activate_mutation(mutation) //note that this returns a boolean and not a new mob if(!mutation) diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 9edaa7605c..ddcf80ae5d 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -191,3 +191,23 @@ power.panel = "Genetic" owner.AddSpell(power) return TRUE + +// Runs through all the coefficients and uses this to determine which chromosomes the +// mutation can take. Stores these as text strings in a list. +/datum/mutation/human/proc/update_valid_chromosome_list() + valid_chrom_list.Cut() + + if(can_chromosome == CHROMOSOME_NEVER) + valid_chrom_list += "none" + return + + valid_chrom_list += "Reinforcement" + + if(stabilizer_coeff != -1) + valid_chrom_list += "Stabilizer" + if(synchronizer_coeff != -1) + valid_chrom_list += "Synchronizer" + if(power_coeff != -1) + valid_chrom_list += "Power" + if(energy_coeff != -1) + valid_chrom_list += "Energetic" diff --git a/code/game/objects/items/chromosome.dm b/code/game/objects/items/chromosome.dm index 1340e7f35b..8330a8e202 100644 --- a/code/game/objects/items/chromosome.dm +++ b/code/game/objects/items/chromosome.dm @@ -53,32 +53,32 @@ /obj/item/chromosome/stabilizer name = "stabilizer chromosome" - desc = "A chromosome that adjusts to the body to reduce genetic damage by 20%." + desc = "A chromosome that reduces mutation instability by 20%." icon_state = "stabilizer" stabilizer_coeff = 0.8 weight = 1 /obj/item/chromosome/synchronizer name = "synchronizer chromosome" - desc = "A chromosome that gives the mind more controle over the mutation, reducing knockback and downsides by 50%." + desc = "A chromosome that reduces mutation knockback and downsides by 50%." icon_state = "synchronizer" synchronizer_coeff = 0.5 /obj/item/chromosome/power name = "power chromosome" - desc = "A power chromosome for boosting certain mutation's power by 50%." + desc = "A chromosome that increases mutation power by 50%." icon_state = "power" power_coeff = 1.5 /obj/item/chromosome/energy name = "energetic chromosome" - desc = "A chromosome that reduces cooldown on action based mutations by 50%." + desc = "A chromosome that reduces action based mutation cooldowns by by 50%." icon_state = "energy" energy_coeff = 0.5 /obj/item/chromosome/reinforcer name = "reinforcement chromosome" - desc = "Renders the mutation immune to mutadone." + desc = "A chromosome that renders mutations immune to mutadone." icon_state = "reinforcer" weight = 3 diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index ef8a63a728..733eb187fd 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -421,7 +421,7 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.real_name = record_found.fields["name"] new_character.gender = record_found.fields["gender"] new_character.age = record_found.fields["age"] - new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"]) + new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], null, record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"]) else var/datum/preferences/A = new() A.copy_to(new_character) diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index aeddf771b8..78fddbd989 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -115,7 +115,7 @@ features["mcolor"] = "#59CE00" for(var/V in quirks) new V(podman) - podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman + podman.hardset_dna(null,null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman podman.set_cloned_appearance() else //else, one packet of seeds. maybe two diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 689ab56842..cf81d5f64f 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -63,3 +63,11 @@ var/damageoverlaytemp = 0 var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects + + /// Protection (insulation) from the heat, Value 0-1 corresponding to the percentage of protection + var/heat_protection = 0 // No heat protection + /// Protection (insulation) from the cold, Value 0-1 corresponding to the percentage of protection + var/cold_protection = 0 // No cold protection + + /// Timer id of any transformation + var/transformation_timer diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 32e492f5fa..5e6aef75ca 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -362,7 +362,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //keep it at the right spot, so we can't have people taking shortcuts var/location = C.dna.mutation_index.Find(inert_mutation) C.dna.mutation_index[location] = new_species.inert_mutation + C.dna.default_mutation_genes[location] = C.dna.mutation_index[location] C.dna.mutation_index[new_species.inert_mutation] = create_sequence(new_species.inert_mutation) + C.dna.default_mutation_genes[new_species.inert_mutation] = C.dna.mutation_index[new_species.inert_mutation] SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 42aaa110c8..ebecf741f4 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -1,26 +1,8 @@ -/mob/living/carbon/proc/monkeyize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG)) - if (notransform) +#define TRANSFORMATION_DURATION 22 + +/mob/living/carbon/proc/monkeyize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_KEEPSTUNS | TR_KEEPREAGENTS | TR_DEFAULTMSG)) + if (notransform || transformation_timer) return - //Handle items on mob - - //first implants & organs - var/list/stored_implants = list() - var/list/int_organs = list() - - if (tr_flags & TR_KEEPIMPLANTS) - for(var/X in implants) - var/obj/item/implant/IMP = X - stored_implants += IMP - IMP.removed(src, 1, 1) - - var/list/missing_bodyparts_zones = get_missing_limbs() - - var/obj/item/cavity_object - - var/obj/item/bodypart/chest/CH = get_bodypart(BODY_ZONE_CHEST) - if(CH.cavity_item) - cavity_object = CH.cavity_item - CH.cavity_item = null if(tr_flags & TR_KEEPITEMS) var/Itemlist = get_equipped_items(TRUE) @@ -30,13 +12,36 @@ //Make mob invisible and spawn animation notransform = TRUE - Stun(INFINITY, ignore_canstun = TRUE) + Paralyze(TRANSFORMATION_DURATION, ignore_canstun = TRUE) icon = null cut_overlays() invisibility = INVISIBILITY_MAXIMUM new /obj/effect/temp_visual/monkeyify(loc) - sleep(22) + + transformation_timer = addtimer(CALLBACK(src, .proc/finish_monkeyize, tr_flags), TRANSFORMATION_DURATION, TIMER_UNIQUE) + +/mob/living/carbon/proc/finish_monkeyize(tr_flags) + transformation_timer = null + + var/list/missing_bodyparts_zones = get_missing_limbs() + + var/list/stored_implants = list() + + if (tr_flags & TR_KEEPIMPLANTS) + for(var/X in implants) + var/obj/item/implant/IMP = X + stored_implants += IMP + IMP.removed(src, 1, 1) + + var/list/int_organs = list() + var/obj/item/cavity_object + + var/obj/item/bodypart/chest/CH = get_bodypart(BODY_ZONE_CHEST) + if(CH.cavity_item) + cavity_object = CH.cavity_item + CH.cavity_item = null + var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey( loc ) // hash the original name? @@ -50,6 +55,7 @@ if(tr_flags & TR_KEEPSE) O.dna.mutation_index = dna.mutation_index + O.dna.default_mutation_genes = dna.default_mutation_genes O.dna.set_se(1, GET_INITIALIZED_MUTATION(RACEMUT)) if(suiciding) @@ -149,12 +155,33 @@ ////////////////////////// Humanize ////////////////////////////// //Could probably be merged with monkeyize but other transformations got their own procs, too -/mob/living/carbon/proc/humanize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG)) - if (notransform) +/mob/living/carbon/proc/humanize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_KEEPSTUNS | TR_KEEPREAGENTS | TR_DEFAULTMSG)) + if (notransform || transformation_timer) return - //Handle items on mob - //first implants & organs + //now the rest + if (tr_flags & TR_KEEPITEMS) + var/Itemlist = get_equipped_items(TRUE) + Itemlist += held_items + for(var/obj/item/W in Itemlist) + dropItemToGround(W, TRUE) + if (client) + client.screen -= W + + //Make mob invisible and spawn animation + notransform = TRUE + Paralyze(TRANSFORMATION_DURATION, ignore_canstun = TRUE) + + icon = null + cut_overlays() + invisibility = INVISIBILITY_MAXIMUM + new /obj/effect/temp_visual/monkeyify/humanify(loc) + + transformation_timer = addtimer(CALLBACK(src, .proc/finish_humanize, tr_flags), TRANSFORMATION_DURATION, TIMER_UNIQUE) + +/mob/living/carbon/proc/finish_humanize(tr_flags) + transformation_timer = null + var/list/stored_implants = list() var/list/int_organs = list() @@ -173,25 +200,6 @@ cavity_object = CH.cavity_item CH.cavity_item = null - //now the rest - if (tr_flags & TR_KEEPITEMS) - var/Itemlist = get_equipped_items(TRUE) - Itemlist += held_items - for(var/obj/item/W in Itemlist) - dropItemToGround(W, TRUE) - if (client) - client.screen -= W - - - - //Make mob invisible and spawn animation - notransform = TRUE - Stun(22, ignore_canstun = TRUE) - icon = null - cut_overlays() - invisibility = INVISIBILITY_MAXIMUM - new /obj/effect/temp_visual/monkeyify/humanify(loc) - sleep(22) var/mob/living/carbon/human/O = new( loc ) for(var/obj/item/C in O.loc) O.equip_to_appropriate_slot(C) @@ -208,6 +216,7 @@ if(tr_flags & TR_KEEPSE) O.dna.mutation_index = dna.mutation_index + O.dna.default_mutation_genes = dna.default_mutation_genes O.dna.set_se(0, GET_INITIALIZED_MUTATION(RACEMUT)) O.domutcheck() @@ -580,3 +589,44 @@ . = new_mob qdel(src) + +/* Certain mob types have problems and should not be allowed to be controlled by players. + * + * This proc is here to force coders to manually place their mob in this list, hopefully tested. + * This also gives a place to explain -why- players shouldnt be turn into certain mobs and hopefully someone can fix them. + */ +/mob/proc/safe_animal(MP) + +//Bad mobs! - Remember to add a comment explaining what's wrong with the mob + if(!MP) + return 0 //Sanity, this should never happen. + + if(ispath(MP, /mob/living/simple_animal/hostile/construct)) + return 0 //Verbs do not appear for players. + +//Good mobs! + if(ispath(MP, /mob/living/simple_animal/pet/cat)) + return 1 + if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi)) + return 1 + if(ispath(MP, /mob/living/simple_animal/crab)) + return 1 + if(ispath(MP, /mob/living/simple_animal/hostile/carp)) + return 1 + if(ispath(MP, /mob/living/simple_animal/hostile/mushroom)) + return 1 + if(ispath(MP, /mob/living/simple_animal/shade)) + return 1 + if(ispath(MP, /mob/living/simple_animal/hostile/killertomato)) + return 1 + if(ispath(MP, /mob/living/simple_animal/mouse)) + return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak) + if(ispath(MP, /mob/living/simple_animal/hostile/bear)) + return 1 //Bears will auto-attack mobs, even if they're player controlled (Fixed! - Nodrak) + if(ispath(MP, /mob/living/simple_animal/parrot)) + return 1 //Parrots are no longer unfinished! -Nodrak + + //Not in here? Must be untested! + return 0 + +#undef TRANSFORMATION_DURATION diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm index f6f56c049a..11518b236f 100644 --- a/code/modules/spells/spell_types/lichdom.dm +++ b/code/modules/spells/spell_types/lichdom.dm @@ -132,7 +132,7 @@ lich.real_name = mind.name mind.transfer_to(lich) mind.grab_ghost(force=TRUE) - lich.hardset_dna(null,null,lich.real_name,null, new /datum/species/skeleton/space) + lich.hardset_dna(null,null,null,lich.real_name,null, new /datum/species/skeleton) to_chat(lich, "Your bones clatter and shudder as you are pulled back into this world!") var/turf/body_turf = get_turf(old_body) lich.DefaultCombatKnockdown(200 + 200*resurrections) diff --git a/tgui-next/packages/tgui-dev-server/reloader.js b/tgui-next/packages/tgui-dev-server/reloader.js index d5541c2a99..394e55afdb 100644 --- a/tgui-next/packages/tgui-dev-server/reloader.js +++ b/tgui-next/packages/tgui-dev-server/reloader.js @@ -9,6 +9,8 @@ const logger = createLogger('reloader'); const HOME = os.homedir(); const SEARCH_LOCATIONS = [ + // Custom location + process.env.BYOND_CACHE, // Windows `${HOME}/*/BYOND/cache`, // Wine @@ -28,6 +30,9 @@ export const findCacheRoot = async () => { logger.log('looking for byond cache'); // Find BYOND cache folders for (let pattern of SEARCH_LOCATIONS) { + if (!pattern) { + continue; + } const paths = await resolveGlob(pattern); if (paths.length > 0) { cacheRoot = paths[0]; diff --git a/tgui-next/packages/tgui/components/Dimmer.js b/tgui-next/packages/tgui/components/Dimmer.js index 9d3ead0549..f38d0a026a 100644 --- a/tgui-next/packages/tgui/components/Dimmer.js +++ b/tgui-next/packages/tgui/components/Dimmer.js @@ -1,19 +1,18 @@ +import { classes } from 'common/react'; import { Box } from './Box'; export const Dimmer = props => { - const { style, ...rest } = props; + const { className, children, ...rest } = props; return ( + className={classes([ + 'Dimmer', + ...className, + ])} + {...rest}> +
+ {children} +
+
); }; diff --git a/tgui-next/packages/tgui/components/Dropdown.js b/tgui-next/packages/tgui/components/Dropdown.js index 462b8a5fe5..3064f40c2c 100644 --- a/tgui-next/packages/tgui/components/Dropdown.js +++ b/tgui-next/packages/tgui/components/Dropdown.js @@ -1,5 +1,5 @@ import { classes } from 'common/react'; -import { Component, createRef } from 'inferno'; +import { Component } from 'inferno'; import { Box } from './Box'; import { Icon } from './Icon'; @@ -46,7 +46,7 @@ export class Dropdown extends Component {
{ + onClick={() => { this.setSelected(option); }}> {option} @@ -60,9 +60,12 @@ export class Dropdown extends Component { const { color = 'default', over, + noscroll, + nochevron, width, onClick, selected, + disabled, ...boxProps } = props; const { @@ -80,7 +83,7 @@ export class Dropdown extends Component { 'width': width, }} className={classes([ - 'Dropdown__menu', + noscroll && 'Dropdown__menu-noscroll' || 'Dropdown__menu', over && 'Dropdown__over', ])}> {this.buildMenu()} @@ -95,18 +98,24 @@ export class Dropdown extends Component { 'Dropdown__control', 'Button', 'Button--color--' + color, + disabled && 'Button--disabled', className, ])} {...rest} - onClick={e => { + onClick={() => { + if (disabled && !this.state.open) { + return; + } this.setOpen(!this.state.open); }}> {this.state.selected} - - - + {!!nochevron || ( + + + + )} {menu}
diff --git a/tgui-next/packages/tgui/styles/components/Dropdown.scss b/tgui-next/packages/tgui/styles/components/Dropdown.scss index a76e15a1bb..a601034378 100644 --- a/tgui-next/packages/tgui/styles/components/Dropdown.scss +++ b/tgui-next/packages/tgui/styles/components/Dropdown.scss @@ -31,6 +31,17 @@ background-color: rgba(0, 0, 0, 0.75); } +.Dropdown__menu-noscroll { + position: absolute; + overflow-y: auto; + z-index: 5; + width: 100px; + max-height: 200px; + border-radius: 0 0 2px 2px; + background-color: #000; + background-color: rgba(0, 0, 0, 0.75); +} + .Dropdown__menuentry { padding: 2px 4px; font-family: Verdana, sans-serif; diff --git a/tgui/packages/tgui/components/Divider.js b/tgui/packages/tgui/components/Divider.js new file mode 100644 index 0000000000..5c807c290b --- /dev/null +++ b/tgui/packages/tgui/components/Divider.js @@ -0,0 +1,18 @@ +import { classes } from 'common/react'; + +export const Divider = props => { + const { + vertical, + hidden, + } = props; + return ( +