From 4463fd95136bd1ce1af29c559defc6894666c2dd Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Sat, 6 Mar 2021 19:28:29 +0800 Subject: [PATCH] paperwork mini update, also ASS_BLAST_USA --- .../mob/living/carbon/human/species.dm | 218 ++++++++++++++---- .../carbon/human/species_types/abductor.dm | 1 + .../carbon/human/species_types/felinid.dm | 1 + .../carbon/human/species_types/jellypeople.dm | 1 + .../human/species_types/lizardpeople.dm | 2 + .../carbon/human/species_types/plasmamen.dm | 2 + code/modules/paperwork/carbonpaper.dm | 16 +- code/modules/paperwork/clipboard.dm | 10 +- code/modules/paperwork/filingcabinet.dm | 48 ++-- code/modules/paperwork/folders.dm | 2 +- code/modules/paperwork/handlabeler.dm | 6 +- code/modules/paperwork/paper_cutter.dm | 10 +- code/modules/paperwork/paper_premade.dm | 19 +- code/modules/paperwork/paperbin.dm | 2 + code/modules/paperwork/paperplane.dm | 32 +-- code/modules/paperwork/pen.dm | 54 +++-- code/modules/paperwork/photocopier.dm | 65 +++--- code/modules/paperwork/ticketmachine.dm | 21 +- icons/ass/asscat.png | Bin 0 -> 4553 bytes icons/ass/assgrey.png | Bin 0 -> 2253 bytes icons/ass/asslizard.png | Bin 0 -> 1892 bytes icons/ass/assmachine.png | Bin 0 -> 246 bytes icons/ass/assplasma.png | Bin 0 -> 1202 bytes icons/ass/assslime.png | Bin 0 -> 1587 bytes 24 files changed, 353 insertions(+), 157 deletions(-) create mode 100644 icons/ass/asscat.png create mode 100644 icons/ass/assgrey.png create mode 100644 icons/ass/asslizard.png create mode 100644 icons/ass/assmachine.png create mode 100644 icons/ass/assplasma.png create mode 100644 icons/ass/assslime.png diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 600045e9c5..986fc38cd3 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -3,16 +3,30 @@ GLOBAL_LIST_EMPTY(roundstart_races) GLOBAL_LIST_EMPTY(roundstart_race_names) +/** + * # species datum + * + * Datum that handles different species in the game. + * + * This datum handles species in the game, such as lizardpeople, mothmen, zombies, skeletons, etc. + * It is used in [carbon humans][mob/living/carbon/human] to determine various things about them, like their food preferences, if they have biological genders, their damage resistances, and more. + * + */ /datum/species - var/id // if the game needs to manually check your race to do something not included in a proc here, it will use this - var/limbs_id //this is used if you want to use a different species limb sprites. Mainly used for angels as they look like humans. - var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever - var/default_color = "#FFFFFF" // if alien colors are disabled, this is the color that will be used by that race + ///If the game needs to manually check your race to do something not included in a proc here, it will use this. + var/id + //This is used if you want to use a different species' limb sprites. + var/limbs_id + ///This is the fluff name. They are displayed on health analyzers and in the character setup menu. Leave them generic for other servers to customize. + var/name + // Default color. If mutant colors are disabled, this is the color that will be used by that race. + var/default_color = "#FFF" - var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows + ///Whether or not the race has sexual characteristics (biological genders). At the moment this is only FALSE for skeletons and shadows + var/sexes = TRUE var/has_field_of_vision = TRUE - //Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner + ///Clothing offsets. If a species has a different body than other species, you can offset clothing so they look less weird. var/list/offset_features = list( OFFSET_UNIFORM = list(0,0), OFFSET_ID = list(0,0), @@ -34,74 +48,141 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) OFFSET_MUTPARTS = list(0,0) ) - var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color - var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent. - var/use_skintones = NO_SKINTONES // does it use skintones or not? (spoiler alert this is only used by humans) - var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id. - var/exotic_bloodtype = "" //If your race uses a non standard bloodtype (A+, O-, AB-, etc) - var/exotic_blood_color = BLOOD_COLOR_HUMAN //assume human as the default blood colour, override this default by species subtypes + ///This allows races to have specific hair colors. If null, it uses the H's hair/facial hair colors. If "mutcolor", it uses the H's mutant_color. If "fixedmutcolor", it uses fixedmutcolor + var/hair_color + ///The alpha used by the hair. 255 is completely solid, 0 is invisible. + var/hair_alpha = 255 + + ///Does the species use skintones or not? As of now only used by humans. + var/use_skintones = FALSE + ///If your race bleeds something other than bog standard blood, change this to reagent id. For example, ethereals bleed liquid electricity. + var/exotic_blood = "" + ///If your race uses a non standard bloodtype (A+, O-, AB-, etc). For example, lizards have L type blood. + var/exotic_bloodtype = "" + /// Assume human as the default blood colour, override this default by species subtypes + var/exotic_blood_color = BLOOD_COLOR_HUMAN + ///What the species drops when gibbed by a gibber machine. var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless) + ///What skin the species drops when gibbed by a gibber machine. var/skinned_type + ///Bitfield for food types that the species likes, giving them a mood boost. Lizards like meat, for example. var/liked_food = NONE + ///Bitfield for food types that the species dislikes, giving them disgust. Humans hate raw food, for example. var/disliked_food = GROSS + ///Bitfield for food types that the species absolutely hates, giving them even more disgust than disliked food. Meat is "toxic" to moths, for example. var/toxic_food = TOXIC - var/list/no_equip = list() // slots the race can't equip stuff to - var/nojumpsuit = 0 // this is sorta... weird. it basically lets you equip stuff that usually needs jumpsuits without one, like belts and pockets and ids + ///Inventory slots the race can't equip stuff to. Golems cannot wear jumpsuits, for example. + var/list/no_equip = list() + /// Allows the species to equip items that normally require a jumpsuit without having one equipped. Used by golems. + var/nojumpsuit = FALSE var/blacklisted = 0 //Flag to exclude from green slime core species. var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!" - var/say_mod = "says" // affects the speech message + ///Affects the speech message, for example: Motharula flutters, "My speech message is flutters!" + var/say_mod = "says" + ///What languages this species can understand and say. Use a [language holder datum][/datum/language_holder] in this var. var/species_language_holder = /datum/language_holder - var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below. - var/list/mutant_organs = list() //Internal organs that are unique to this race. - var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster - var/armor = 0 // overall defense for the race... or less defense, if it's negative. - var/attack_type = BRUTE // the type of damage unarmed attacks from this species do - var/brutemod = 1 // multiplier for brute damage - var/burnmod = 1 // multiplier for burn damage - var/coldmod = 1 // multiplier for cold damage - var/heatmod = 1 // multiplier for heat damage - var/stunmod = 1 // multiplier for stun duration - var/punchdamagelow = 1 //lowest possible punch damage. if this is set to 0, punches will always miss - var/punchdamagehigh = 10 //highest possible punch damage - var/punchstunthreshold = 10 //damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical + /** + * Visible CURRENT bodyparts that are unique to a species. + * DO NOT USE THIS AS A LIST OF ALL POSSIBLE BODYPARTS AS IT WILL FUCK + * SHIT UP! Changes to this list for non-species specific bodyparts (ie + * cat ears and tails) should be assigned at organ level if possible. + * Assoc values are defaults for given bodyparts, also modified by aforementioned organs. + * They also allow for faster '[]' list access versus 'in'. Other than that, they are useless right now. + * Layer hiding is handled by [/datum/species/proc/handle_mutant_bodyparts] below. + */ + var/list/mutant_bodyparts = list() + ///Internal organs that are unique to this race, like a tail. + var/list/mutant_organs = list() + ///Multiplier for the race's speed. Positive numbers make it move slower, negative numbers make it move faster. + var/speedmod = 0 + ///Percentage modifier for overall defense of the race, or less defense, if it's negative. + var/armor = 0 + ///multiplier for brute damage + var/brutemod = 1 + ///multiplier for burn damage + var/burnmod = 1 + ///multiplier for damage from cold temperature + var/coldmod = 1 + ///multiplier for damage from hot temperature + var/heatmod = 1 + ///multiplier for stun durations + var/stunmod = 1 + ///multiplier for money paid at payday + var/payday_modifier = 1 + ///Type of damage attack does. Ethereals attack with burn damage for example. + var/attack_type = BRUTE // multiplier for stun duration + ///Lowest possible punch damage this species can give. If this is set to 0, punches will always miss. + var/punchdamagelow = 1 + ///Highest possible punch damage this species can give. + var/punchdamagehigh = 10 + ///Damage at which punches from this race will stun + var/punchstunthreshold = 10 //yes it should be to the attacked race but it's not useful that way even if it's logical var/punchwoundbonus = 0 // additional wound bonus. generally zero. - var/siemens_coeff = 1 //base electrocution coefficient - var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded? - var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"] + ///Base electrocution coefficient. Basically a multiplier for damage from electrocutions. + var/siemens_coeff = 1 + ///What kind of damage overlays (if any) appear on our species when wounded? If this is "", does not add an overlay. + var/damage_overlay_type = "human" + ///To use MUTCOLOR with a fixed color that's independent of the mcolor feature in DNA. + var/fixed_mut_color = "" + ///Special mutation that can be found in the genepool exclusively in this species. Dont leave empty or changing species will be a headache var/inert_mutation = DWARFISM - var/list/special_step_sounds //Sounds to override barefeet walkng - var/grab_sound //Special sound for grabbing - var/datum/outfit/outfit_important_for_life // A path to an outfit that is important for species life e.g. plasmaman outfit + ///Sounds to override barefeet walking + var/list/special_step_sounds + ///Special sound for grabbing + var/grab_sound + /// A path to an outfit that is important for species life e.g. plasmaman outfit + var/datum/outfit/outfit_important_for_life - // species-only traits. Can be found in DNA.dm + ///Species-only traits. Can be found in [code/__DEFINES/DNA.dm] var/list/species_traits = list(HAS_FLESH,HAS_BONE) //by default they can scar and have bones/flesh unless set to something else - // generic traits tied to having the species - var/list/inherent_traits = list() + ///Generic traits tied to having the species. + var/list/inherent_traits = list() //list(TRAIT_ADVANCEDTOOLUSER) + /// List of biotypes the mob belongs to. Used by diseases. var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID var/list/blacklisted_quirks = list() // Quirks that will be removed upon gaining this species, to be defined by species var/list/removed_quirks = list() // Quirks that got removed due to being blacklisted, and will be restored when on_species_loss() is called - var/attack_verb = "punch" // punch-specific attack verb + ///Punch-specific attack verb. + var/attack_verb = "punch" + /// var/sound/attack_sound = 'sound/weapons/punch1.ogg' var/sound/miss_sound = 'sound/weapons/punchmiss.ogg' var/list/mob/living/ignored_by = list() // list of mobs that will ignore this species //Breathing! var/obj/item/organ/lungs/mutantlungs = null + ///What gas does this species breathe? Used by suffocation screen alerts, most of actual gas breathing is handled by mutantlungs. See [life.dm][code/modules/mob/living/carbon/human/life.dm] var/breathid = "o2" + //Do NOT remove by setting to null. use OR make a RESPECTIVE TRAIT (removing stomach? add the NOSTOMACH trait to your species) + //why does it work this way? because traits also disable the downsides of not having an organ, removing organs but not having the trait will make your species die + + ///Replaces default brain with a different organ var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain + ///Replaces default heart with a different organ var/obj/item/organ/heart/mutant_heart = /obj/item/organ/heart + ///Replaces default lungs with a different organ + // var/obj/item/organ/lungs/mutantlungs = /obj/item/organ/lungs + ///Replaces default eyes with a different organ var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes + ///Replaces default ears with a different organ var/obj/item/organ/ears/mutantears = /obj/item/organ/ears - var/obj/item/mutanthands + ///Replaces default tongue with a different organ var/obj/item/organ/tongue/mutanttongue = /obj/item/organ/tongue + ///Replaces default liver with a different organ + var/obj/item/organ/liver/mutantliver = /obj/item/organ/liver + ///Replaces default stomach with a different organ + var/obj/item/organ/stomach/mutantstomach = /obj/item/organ/stomach + ///Replaces default appendix with a different organ. + var/obj/item/organ/appendix/mutantappendix = /obj/item/organ/appendix + ///Forces an item into this species' hands. Only an honorary mutantthing because this is not an organ and not loaded in the same way, you've been warned to do your research. + var/obj/item/mutanthands + + /// CIT SPECIFIC Mutant tail var/obj/item/organ/tail/mutanttail = null - var/obj/item/organ/liver/mutantliver - var/obj/item/organ/stomach/mutantstomach var/override_float = FALSE //Citadel snowflake @@ -126,6 +207,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //the icon state of the eyes this species has var/eye_type = "normal" + ///For custom overrides for species ass images + var/icon/ass_image + /////////// // PROCS // /////////// @@ -141,6 +225,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //update our mutant bodyparts to include unlocked ones mutant_bodyparts += GLOB.unlocked_mutant_parts +/** + * Generates species available to choose in character setup at roundstart + * + * This proc generates which species are available to pick from in character setup. + * If there are no available roundstart species, defaults to human. + */ /proc/generate_selectable_species(clear = FALSE) if(clear) GLOB.roundstart_races = list() @@ -154,11 +244,26 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!GLOB.roundstart_races.len) GLOB.roundstart_races += "human" +/** + * Checks if a species is eligible to be picked at roundstart. + * + * Checks the config to see if this species is allowed to be picked in the character setup menu. + * Used by [/proc/generate_selectable_species]. + */ /datum/species/proc/check_roundstart_eligible() if(id in (CONFIG_GET(keyed_list/roundstart_races))) return TRUE return FALSE +/** + * Generates a random name for a carbon. + * + * This generates a random unique name based on a human's species and gender. + * Arguments: + * * gender - The gender that the name should adhere to. Use MALE for male names, use anything else for female names. + * * unique - If true, ensures that this new name is not a duplicate of anyone else's name currently on the station. + * * lastname - Does this species' naming system adhere to the last name system? Set to false if it doesn't. + */ /datum/species/proc/random_name(gender,unique,lastname) if(unique) return random_unique_name(gender) @@ -176,7 +281,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return randname -//Called when cloning, copies some vars that should be kept +/** + * Copies some vars and properties over that should be kept when creating a copy of this species. + * + * Used by slimepeople to copy themselves, and by the DNA datum to hardset DNA to a species + * Arguments: + * * old_species - The species that the carbon used to be before copying + */ /datum/species/proc/copy_properties_from(datum/species/old_species) mutant_bodyparts["limbs_id"] = old_species.mutant_bodyparts["limbs_id"] eye_type = old_species.eye_type @@ -189,7 +300,18 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // return 0 //It returns false when it runs the proc so they don't get jobs from the global list. return 1 //It returns 1 to say they are a-okay to continue. -//Will regenerate missing organs +/** + * Corrects organs in a carbon, removing ones it doesn't need and adding ones it does. + * + * Takes all organ slots, removes organs a species should not have, adds organs a species should have. + * can use replace_current to refresh all organs, creating an entirely new set. + * + * Arguments: + * * C - carbon, the owner of the species datum AKA whoever we're regenerating organs in + * * old_species - datum, used when regenerate organs is called in a switching species to remove old mutant organs. + * * replace_current - boolean, forces all old organs to get deleted whether or not they pass the species' ability to keep that organ + * * excluded_zones - list, add zone defines to block organs inside of the zones from getting handled. see headless mutation for an example + */ /datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE) var/obj/item/organ/brain/brain = C.getorganslot(ORGAN_SLOT_BRAIN) var/obj/item/organ/heart/heart = C.getorganslot(ORGAN_SLOT_HEART) @@ -305,6 +427,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/organ/I = new path() I.Insert(C) +/** + * Proc called when a carbon becomes this species. + * + * This sets up and adds/changes/removes things, qualities, abilities, and traits so that the transformation is as smooth and bugfree as possible. + * Produces a [COMSIG_SPECIES_GAIN] signal. + * Arguments: + * * C - Carbon, this is whoever became the new species. + * * old_species - The species that the carbon used to be before becoming this race, used for regenerating organs. + * * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc. + */ /datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) // Drop the items the new species can't wear for(var/slot_id in no_equip) diff --git a/code/modules/mob/living/carbon/human/species_types/abductor.dm b/code/modules/mob/living/carbon/human/species_types/abductor.dm index 004ba267e8..253dac6f2a 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductor.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductor.dm @@ -7,6 +7,7 @@ inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_CHUNKYFINGERS,TRAIT_NOHUNGER,TRAIT_NOBREATH) mutanttongue = /obj/item/organ/tongue/abductor species_category = SPECIES_CATEGORY_ALIEN + ass_image = 'icons/ass/assgrey.png' /datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 3fcefbe2cc..6327375bb5 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -12,6 +12,7 @@ tail_type = "mam_tail" wagging_type = "mam_waggingtail" species_category = SPECIES_CATEGORY_FURRY + ass_image = 'icons/ass/asscat.png' /datum/species/human/felinid/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) if(ishuman(C)) diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index dc2269e19b..7a15fd2e5c 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -27,6 +27,7 @@ tail_type = "mam_tail" wagging_type = "mam_waggingtail" species_category = SPECIES_CATEGORY_JELLY + ass_image = 'icons/ass/assslime.png' /obj/item/organ/brain/jelly name = "slime nucleus" diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 4d0f88754f..6a9845079f 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -30,6 +30,8 @@ wagging_type = "waggingtail_lizard" species_category = SPECIES_CATEGORY_LIZARD + ass_image = 'icons/ass/asslizard.png' + /datum/species/lizard/random_name(gender,unique,lastname) if(unique) return random_unique_lizard_name(gender) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 12a520b463..e368489c57 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -24,6 +24,8 @@ species_category = SPECIES_CATEGORY_SKELETON + ass_image = 'icons/ass/assplasma.png' + /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) var/datum/gas_mixture/environment = H.loc.return_air() var/atmos_sealed = FALSE diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm index dc8f172069..9a306333b3 100644 --- a/code/modules/paperwork/carbonpaper.dm +++ b/code/modules/paperwork/carbonpaper.dm @@ -8,14 +8,18 @@ var/iscopy = FALSE /obj/item/paper/carbon/update_icon_state() - if(iscopy) - icon_state = "cpaper" - else if(copied) - icon_state = "paper" - else - icon_state = "paper_stack" if(info) icon_state = "[icon_state]_words" + return ..() + if(iscopy) + icon_state = "cpaper" + return ..() + if(copied) + icon_state = "paper" + return ..() + + icon_state = "paper_stack" + return ..() /obj/item/paper/carbon/proc/removecopy(mob/living/user) if(!copied) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 5b576a2438..13de7898c1 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -9,8 +9,8 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 7 - var/obj/item/pen/haspen //The stored pen. - var/obj/item/paper/toppaper //The topmost piece of paper. + var/obj/item/pen/haspen //The stored pen. + var/obj/item/paper/toppaper //The topmost piece of paper. slot_flags = ITEM_SLOT_BELT resistance_flags = FLAMMABLE @@ -24,7 +24,7 @@ /obj/item/clipboard/Destroy() QDEL_NULL(haspen) - QDEL_NULL(toppaper) //let movable/Destroy handle the rest + QDEL_NULL(toppaper) //let movable/Destroy handle the rest return ..() /obj/item/clipboard/update_overlays() @@ -55,7 +55,7 @@ else dat += "Add Pen

" - //The topmost paper. You can't organise contents directly in byond, so this is what we're stuck with. -Pete + //The topmost paper. You can't organise contents directly in byond, so this is what we're stuck with. -Pete if(toppaper) var/obj/item/paper/P = toppaper dat += "Write Remove - [P.name]

" @@ -71,7 +71,7 @@ /obj/item/clipboard/Topic(href, href_list) ..() - if(usr.stat || usr.restrained()) + if(usr.stat != CONSCIOUS || usr.restrained()) //HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) return if(usr.contents.Find(src)) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 390cd0cf83..59bbf47128 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -1,9 +1,9 @@ /* Filing cabinets! * Contains: - * Filing Cabinets - * Security Record Cabinets - * Medical Record Cabinets - * Employment Contract Cabinets + * Filing Cabinets + * Security Record Cabinets + * Medical Record Cabinets + * Employment Contract Cabinets */ @@ -27,7 +27,7 @@ desc = "A small cabinet with drawers. This one has wheels!" anchored = FALSE -/obj/structure/filingcabinet/filingcabinet //not changing the path to avoid unnecessary map issues, but please don't name stuff like this in the future -Pete +/obj/structure/filingcabinet/filingcabinet //not changing the path to avoid unnecessary map issues, but please don't name stuff like this in the future -Pete icon_state = "tallcabinet" @@ -45,12 +45,12 @@ I.forceMove(loc) qdel(src) -/obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params) +/obj/structure/filingcabinet/attackby(obj/item/P, mob/living/user, params) if(P.tool_behaviour == TOOL_WRENCH && user.a_intent != INTENT_HELP) to_chat(user, "You begin to [anchored ? "unwrench" : "wrench"] [src].") if(P.use_tool(src, user, 20, volume=50)) to_chat(user, "You successfully [anchored ? "unwrench" : "wrench"] [src].") - anchored = !anchored + set_anchored(!anchored) else if(P.w_class < WEIGHT_CLASS_NORMAL) if(!user.transferItemToLoc(P, src)) return @@ -79,13 +79,15 @@ dat += "" user << browse("[name][dat]", "window=filingcabinet;size=350x300") + /obj/structure/filingcabinet/attack_tk(mob/user) if(anchored) - attack_self_tk(user) - else - ..() + return attack_self_tk(user) + return ..() + /obj/structure/filingcabinet/attack_self_tk(mob/user) + // . = COMPONENT_CANCEL_ATTACK_CHAIN if(contents.len) if(prob(40 + contents.len * 5)) var/obj/item/I = pick(contents) @@ -96,8 +98,9 @@ return to_chat(user, "You find nothing in [src].") + /obj/structure/filingcabinet/Topic(href, href_list) - if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr))) + if(!usr.canUseTopic(src, BE_CLOSE, ismonkey(usr), FALSE)) //, !iscyborg(usr))) return if(href_list["retrieve"]) usr << browse("", "window=filingcabinet") // Close the menu @@ -114,7 +117,7 @@ * Security Record Cabinets */ /obj/structure/filingcabinet/security - var/virgin = 1 + var/virgin = TRUE /obj/structure/filingcabinet/security/proc/populate() if(virgin) @@ -132,22 +135,23 @@ counter++ P.info += "" P.name = "paper - '[G.fields["name"]]'" - virgin = 0 //tabbing here is correct- it's possible for people to try and use it + virgin = FALSE //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. -/obj/structure/filingcabinet/security/on_attack_hand() +/obj/structure/filingcabinet/security/on_attack_hand(mob/user, list/modifiers) populate() - . = ..() + return ..() /obj/structure/filingcabinet/security/attack_tk() populate() - ..() + return ..() /* * Medical Record Cabinets */ /obj/structure/filingcabinet/medical - var/virgin = 1 + ///This var is so that its filled on crew interaction to be as accurate (including latejoins) as possible, true until first interact + var/virgin = TRUE /obj/structure/filingcabinet/medical/proc/populate() if(virgin) @@ -165,17 +169,17 @@ counter++ P.info += "" P.name = "paper - '[G.fields["name"]]'" - virgin = 0 //tabbing here is correct- it's possible for people to try and use it + virgin = FALSE //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/filingcabinet/medical/on_attack_hand() +/obj/structure/filingcabinet/medical/on_attack_hand(mob/user, list/modifiers) populate() - . = ..() + return ..() /obj/structure/filingcabinet/medical/attack_tk() populate() - ..() + return ..() /* * Employment contract Cabinets @@ -185,6 +189,7 @@ GLOBAL_LIST_EMPTY(employmentCabinets) /obj/structure/filingcabinet/employment icon_state = "employmentcabinet" + ///This var is so that its filled on crew interaction to be as accurate (including latejoins) as possible, true until first interact var/virgin = TRUE /obj/structure/filingcabinet/employment/Initialize() @@ -219,3 +224,4 @@ GLOBAL_LIST_EMPTY(employmentCabinets) fillCurrent() virgin = FALSE return ..() + diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 305099d115..2c534d0178 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -76,7 +76,7 @@ /obj/item/folder/Topic(href, href_list) ..() - if(usr.stat || usr.restrained()) + if(usr.stat != CONSCIOUS || usr.restrained()) //HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) return if(usr.contents.Find(src)) diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index da9fdc4ca4..ad251a6c82 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -40,7 +40,7 @@ . = ..() if(!proximity) return - if(!mode) //if it's off, give up. + if(!mode) //if it's off, give up. return if(!labels_left) @@ -57,7 +57,7 @@ return user.visible_message("[user] labels [A] with \"[label]\".", \ - "You label [A] with \"[label]\".") + "You label [A] with \"[label]\".") A.AddComponent(/datum/component/label, label) // playsound(A, 'sound/items/handling/component_pickup.ogg', 20, TRUE) labels_left-- @@ -86,7 +86,7 @@ if(istype(I, /obj/item/hand_labeler_refill)) to_chat(user, "You insert [I] into [src].") qdel(I) - labels_left = initial(labels_left) //Yes, it's capped at its initial value + labels_left = initial(labels_left) //Yes, it's capped at its initial value /obj/item/hand_labeler/borg name = "cyborg-hand labeler" diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index a3b9b23141..f5cb6e1a10 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -36,9 +36,10 @@ /obj/item/papercutter/update_icon_state() icon_state = (storedcutter ? "[initial(icon_state)]-cutter" : "[initial(icon_state)]") + return ..() /obj/item/papercutter/update_overlays() - . = ..() + . =..() if(storedpaper) . += "paper" @@ -68,6 +69,9 @@ ..() /obj/item/papercutter/on_attack_hand(mob/user) + // . = ..() + // if(.) + // return add_fingerprint(user) if(!storedcutter) to_chat(user, "The cutting blade is gone! You can't use [src] now.") @@ -118,8 +122,8 @@ /obj/item/paperslip/Initialize() . = ..() - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) + pixel_x = initial(pixel_x) + rand(-5, 5) + pixel_y = initial(pixel_y) + rand(-5, 5) /obj/item/hatchet/cutterblade diff --git a/code/modules/paperwork/paper_premade.dm b/code/modules/paperwork/paper_premade.dm index 5d6d3d45e8..cc7b11d331 100644 --- a/code/modules/paperwork/paper_premade.dm +++ b/code/modules/paperwork/paper_premade.dm @@ -1,5 +1,5 @@ /* - * Premade paper + * Premade paper */ /obj/item/paper/fluff/sop @@ -21,12 +21,16 @@
-Love, Your Dearest"} -//////////// Job guides n' fluff +//////////// Job guides n' fluff /obj/item/paper/guides/jobs/hydroponics name = "paper- 'Greetings from Billy Bob'" info = "Hey fellow botanist!
\n
\nI didn't trust the station folk so I left
\na couple of weeks ago. But here's some
\ninstructions on how to operate things here.
\nYou can grow plants and each iteration they become
\nstronger, more potent and have better yield, if you
\nknow which ones to pick. Use your botanist's analyzer
\nfor that. You can turn harvested plants into seeds
\nat the seed extractor, and replant them for better stuff!
\nSometimes if the weed level gets high in the tray
\nmutations into different mushroom or weed species have
\nbeen witnessed. On the rare occasion even weeds mutate!
\n
\nEither way, have fun!
\n
\nBest regards,
\nBilly Bob Johnson.
\n
\nPS.
\nHere's a few tips:
\nIn nettles, potency = damage
\nIn amanitas, potency = deadliness + side effect
\nIn Liberty caps, potency = drug power + effect
\nIn chilies, potency = heat
\nNutrients keep mushrooms alive!
\nWater keeps weeds such as nettles alive!
\nAll other plants need both." +/obj/item/paper/guides/jobs/holopad_hydro + name = "paper- 'Holopad Notice'" + info = "Can't get any botanists at the table? Have you tried using the damn holopad?
\n
\nStep onto the pad, and interface with it
\nthen make your dang ol' call!
\n
\nYou want to call \"Hydroponics\" to reach them." + /obj/item/paper/fluff/jobs/security/beepsky_mom name = "Note from Beepsky's Mom" info = "01001001 00100000 01101000 01101111 01110000 01100101 00100000 01111001 01101111 01110101 00100000 01110011 01110100 01100001 01111001 00100000 01110011 01100001 01100110 01100101 00101110 00100000 01001100 01101111 01110110 01100101 00101100 00100000 01101101 01101111 01101101 00101110" @@ -92,9 +96,11 @@ "} /* - * Stations + * Stations */ -////////// cogstation. + + +/////////// Cogstation. /obj/item/paper/guides/cogstation/job_changes name = "MEMO: Job Changes" @@ -220,7 +226,8 @@ name = "MEMO: MULEbots" info = "As you may know, MULEbots have been coded to minimize travel distance for maximum efficiency. In the case of this station, that may include travelling through depressurized areas exposed to space. Please bear this in mind before using them to transport living tissue.
\n
\nGenerated by Organic Resources Bot #2053" -/////////// CentCom + +/////////// CentCom /obj/item/paper/fluff/stations/centcom/disk_memo name = "memo" @@ -234,7 +241,7 @@ info = "
CentCom Security
Port Division
Official Bulletin

Inspector,
There is an emergency shuttle arriving today.

Approval is restricted to Nanotrasen employees only. Deny all other entrants.

CentCom Port Commissioner" -/////////// Lavaland +/////////// Lavaland /obj/item/paper/fluff/stations/lavaland/orm_notice name = "URGENT!" diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index b8bbd0a30e..16a9ed33ed 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -132,6 +132,7 @@ icon_state = "paper_bin0" else icon_state = "[initial(icon_state)]" + return ..() /obj/item/paper_bin/update_overlays() . = ..() @@ -154,6 +155,7 @@ /obj/item/paper_bin/bundlenatural/on_attack_hand(mob/user) if(total_paper < 1) qdel(src) + return ..() /obj/item/paper_bin/bundlenatural/fire_act(exposed_temperature, exposed_volume) qdel(src) diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 53fe886d65..d369339095 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -21,8 +21,8 @@ /obj/item/paperplane/Initialize(mapload, obj/item/paper/newPaper) . = ..() - pixel_y = rand(-8, 8) - pixel_x = rand(-9, 9) + pixel_x = initial(pixel_x) + rand(-9, 9) + pixel_y = initial(pixel_y) + rand(-8, 8) if(newPaper) internalPaper = newPaper flags_1 = newPaper.flags_1 @@ -65,17 +65,18 @@ /obj/item/paperplane/update_overlays() . = ..() var/list/stamped = internalPaper.stamped - if(stamped) - for(var/S in stamped) - . += "paperplane_[S]" + if(!LAZYLEN(stamped)) + return + for(var/S in stamped) + . += "paperplane_[S]" /obj/item/paperplane/attack_self(mob/user) to_chat(user, "You unfold [src].") - var/obj/item/paper/internal_paper_tmp = internalPaper - internal_paper_tmp.forceMove(loc) - internalPaper = null - qdel(src) - user.put_in_hands(internal_paper_tmp) + // We don't have to qdel the paperplane here; it shall be done once the internal paper object is moved out of src anyway. + if(user.Adjacent(internalPaper)) + user.put_in_hands(internalPaper) + else + internalPaper.forceMove(loc) /obj/item/paperplane/attackby(obj/item/P, mob/living/carbon/human/user, params) if(burn_paper_product_attackby_check(P, user)) @@ -84,7 +85,7 @@ to_chat(user, "You should unfold [src] before changing it!") return - else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane + else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane internalPaper.attackby(P, user) //spoofed attack to update internal paper. update_icon() add_fingerprint(user) @@ -121,8 +122,8 @@ . = ..() . += "Alt-click [src] to fold it into a paper plane." -/obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I) - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) +/obj/item/paper/AltClick(mob/living/user, obj/item/I) + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user), FALSE)) //, TRUE)) return if(istype(src, /obj/item/paper/carbon)) var/obj/item/paper/carbon/Carbon = src @@ -137,5 +138,6 @@ if(origami_action?.active) plane_type = /obj/item/paperplane/origami - I = new plane_type(user, src) - user.put_in_hands(I) + I = new plane_type(loc, src) + if(user.Adjacent(I)) + user.put_in_hands(I) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 8863a098fc..b4f1acbed4 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -1,9 +1,9 @@ -/* Pens! - * Contains: - * Pens - * Sleepy Pens - * Parapens - * Edaggers +/* Pens! + * Contains: + * Pens + * Sleepy Pens + * Parapens + * Edaggers */ @@ -26,7 +26,7 @@ custom_materials = list(/datum/material/iron=10) pressure_resistance = 2 grind_results = list(/datum/reagent/iron = 2, /datum/reagent/iodine = 1) - var/colour = "black" //what colour the ink is! + var/colour = "black" //what colour the ink is! var/degrees = 0 var/font = PEN_FONT embedding = list() @@ -147,29 +147,50 @@ /obj/item/pen/afterattack(obj/O, mob/living/user, proximity) . = ..() - //Changing Name/Description of items. Only works if they have the 'unique_rename' flag set + //Changing name/description of items. Only works if they have the UNIQUE_RENAME object flag set if(isobj(O) && proximity && (O.obj_flags & UNIQUE_RENAME)) - var/penchoice = input(user, "What would you like to edit?", "Rename or change description?") as null|anything in list("Rename","Change description") + var/penchoice = input(user, "What would you like to edit?", "Rename, change description or reset both?") as null|anything in list("Rename","Change description","Reset") if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return if(penchoice == "Rename") - var/input = stripped_input(user,"What do you want to name \the [O.name]?", ,"", MAX_NAME_LEN) + var/input = stripped_input(user,"What do you want to name [O]?", ,"[O.name]", MAX_NAME_LEN) var/oldname = O.name if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return - if(oldname == input) - to_chat(user, "You changed \the [O.name] to... well... \the [O.name].") + if(oldname == input || input == "") + to_chat(user, "You changed [O] to... well... [O].") else O.name = input - to_chat(user, "\The [oldname] has been successfully been renamed to \the [input].") + var/datum/component/label/label = O.GetComponent(/datum/component/label) + if(label) + label.remove_label() + label.apply_label() + to_chat(user, "You have successfully renamed \the [oldname] to [O].") O.renamedByPlayer = TRUE if(penchoice == "Change description") - var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 100) + var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 140) + var/olddesc = O.desc if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return - O.desc = input - to_chat(user, "You have successfully changed \the [O.name]'s description.") + if(olddesc == input || input == "") + to_chat(user, "You decide against changing [O]'s description.") + else + O.desc = input + to_chat(user, "You have successfully changed [O]'s description.") + O.renamedByPlayer = TRUE + + if(penchoice == "Reset") + if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) + return + O.desc = initial(O.desc) + O.name = initial(O.name) + var/datum/component/label/label = O.GetComponent(/datum/component/label) + if(label) + label.remove_label() + label.apply_label() + to_chat(user, "You have successfully reset [O]'s name and description.") + O.renamedByPlayer = FALSE /* * Sleepypens @@ -256,6 +277,7 @@ item_state = initial(item_state) lefthand_file = initial(lefthand_file) righthand_file = initial(righthand_file) + return ..() /obj/item/pen/survival name = "survival pen" diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 25a9cf0043..06adda95dd 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -1,19 +1,19 @@ /// For use with the `color_mode` var. Photos will be printed in greyscale while the var has this value. -#define PHOTO_GREYSCALE "Greyscale" +#define PHOTO_GREYSCALE "Greyscale" /// For use with the `color_mode` var. Photos will be printed in full color while the var has this value. -#define PHOTO_COLOR "Color" +#define PHOTO_COLOR "Color" /// How much toner is used for making a copy of a paper. -#define PAPER_TONER_USE 0.125 +#define PAPER_TONER_USE 0.125 /// How much toner is used for making a copy of a photo. -#define PHOTO_TONER_USE 0.625 +#define PHOTO_TONER_USE 0.625 /// How much toner is used for making a copy of a document. -#define DOCUMENT_TONER_USE 0.75 +#define DOCUMENT_TONER_USE 0.75 /// How much toner is used for making a copy of an ass. -#define ASS_TONER_USE 0.625 +#define ASS_TONER_USE 0.625 /// The maximum amount of copies you can make with one press of the copy button. -#define MAX_COPIES_AT_ONCE 10 +#define MAX_COPIES_AT_ONCE 10 /obj/machinery/photocopier name = "photocopier" @@ -46,7 +46,7 @@ /obj/machinery/photocopier/Initialize() . = ..() - //AddComponent(/datum/component/payment, 5, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL) + // AddComponent(/datum/component/payment, 5, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL) toner_cartridge = new(src) /obj/machinery/photocopier/ui_interact(mob/user, datum/tgui/ui) @@ -82,7 +82,8 @@ return data /obj/machinery/photocopier/ui_act(action, list/params) - if(..()) + . = ..() + if(.) return switch(action) @@ -187,13 +188,12 @@ */ /obj/machinery/photocopier/proc/do_copy_loop(datum/callback/copy_cb, mob/user) busy = TRUE - var/num_loops - for(var/i in 1 to num_copies) - //if(attempt_charge(src, user) & COMPONENT_OBJ_CANCEL_CHARGE) - // break + var/i + for(i in 1 to num_copies) + // if(attempt_charge(src, user) & COMPONENT_OBJ_CANCEL_CHARGE) + // break addtimer(copy_cb, i SECONDS) - num_loops++ - addtimer(CALLBACK(src, .proc/reset_busy), num_loops SECONDS) + addtimer(CALLBACK(src, .proc/reset_busy), i SECONDS) /** * Sets busy to `FALSE`. Created as a proc so it can be used in callbacks. @@ -210,8 +210,8 @@ * * copied_item - The paper, document, or photo that was just spawned on top of the printer. */ /obj/machinery/photocopier/proc/give_pixel_offset(obj/item/copied_item) - copied_item.pixel_x = rand(-10, 10) - copied_item.pixel_y = rand(-10, 10) + copied_item.pixel_x = initial(copied_item.pixel_x) + rand(-10, 10) + copied_item.pixel_y = initial(copied_item.pixel_y) + rand(-10, 10) /** * Handles the copying of devil contract paper. Transfers all the text, stamps and so on from the old paper, to the copy. @@ -242,8 +242,8 @@ copied_paper.info = "" var/copied_info = paper_copy.info - copied_info = replacetext(copied_info, "" copied_paper.name = paper_copy.name @@ -287,17 +287,22 @@ /obj/machinery/photocopier/proc/make_ass_copy() if(!check_ass()) return - if(ishuman(ass)) //(ass.get_item_by_slot(ITEM_SLOT_ICLOTHING) || ass.get_item_by_slot(ITEM_SLOT_OCLOTHING))) - var/mob/living/carbon/C = ass //have to typecast to this, is_groin_exposed is carbon level - if(C.is_groin_exposed()) - to_chat(usr, "You feel kind of silly, copying [ass == usr ? "your" : ass][ass == usr ? "" : "\'s"] ass with [ass == usr ? "your" : "[ass.p_their()]"] clothes on." ) - return + if(ishuman(ass) && (ass.get_item_by_slot(ITEM_SLOT_ICLOTHING) || ass.get_item_by_slot(ITEM_SLOT_OCLOTHING))) + to_chat(usr, "You feel kind of silly, copying [ass == usr ? "your" : ass][ass == usr ? "" : "\'s"] ass with [ass == usr ? "your" : "[ass.p_their()]"] clothes on." ) + return var/icon/temp_img - if(isalienadult(ass) || istype(ass, /mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro. + if(ishuman(ass)) + var/mob/living/carbon/human/H = ass + var/datum/species/spec = H.dna.species + if(spec.ass_image) + temp_img = icon(spec.ass_image) + else + temp_img = icon(ass.gender == FEMALE ? 'icons/ass/assfemale.png' : 'icons/ass/assmale.png') + else if(isalienadult(ass) || istype(ass, /mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro. temp_img = icon('icons/ass/assalien.png') - else if(ishuman(ass)) //Suit checks are after check_ass - temp_img = icon(ass.gender == FEMALE ? 'icons/ass/assfemale.png' : 'icons/ass/assmale.png') + else if(issilicon(ass)) + temp_img = icon('icons/ass/assmachine.png') else if(isdrone(ass)) //Drones are hot temp_img = icon('icons/ass/assdrone.png') @@ -479,6 +484,7 @@ */ /obj/item/toner name = "toner cartridge" + desc = "A small, lightweight cartridge of NanoTrasen ValueBrand toner. Fits photocopiers and autopainters alike." icon = 'icons/obj/device.dmi' icon_state = "tonercartridge" grind_results = list(/datum/reagent/iodine = 40, /datum/reagent/iron = 10) @@ -487,9 +493,10 @@ /obj/item/toner/large name = "large toner cartridge" + desc = "A hefty cartridge of NanoTrasen ValueBrand toner. Fits photocopiers and autopainters alike." grind_results = list(/datum/reagent/iodine = 90, /datum/reagent/iron = 10) - charges = 15 - max_charges = 15 + charges = 25 + max_charges = 25 /obj/item/toner/extreme name = "extremely large toner cartridge" diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index 9f4a864e9c..e874f2836d 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -5,6 +5,7 @@ name = "ticket machine" icon = 'icons/obj/bureaucracy.dmi' icon_state = "ticketmachine" + // base_icon_state = "ticketmachine" desc = "A marvel of bureaucratic engineering encased in an efficient plastic shell. It can be refilled with a hand labeler refill roll and linked to buttons with a multitool." density = FALSE maptext_height = 26 @@ -22,11 +23,10 @@ var/list/obj/item/ticket_machine_ticket/tickets = list() /obj/machinery/ticket_machine/multitool_act(mob/living/user, obj/item/I) - if(!I.tool_behaviour == TOOL_MULTITOOL) - return if(!multitool_check_buffer(user, I)) //make sure it has a data buffer return - I.buffer = src + var/obj/item/multitool/M = I + M.buffer = src to_chat(user, "You store linkage information in [I]'s buffer.") return TRUE @@ -78,10 +78,11 @@ /obj/machinery/button/ticket_machine/multitool_act(mob/living/user, obj/item/I) . = ..() if(I.tool_behaviour == TOOL_MULTITOOL) - if(I.buffer && !istype(I.buffer, /obj/machinery/ticket_machine)) + var/obj/item/multitool/M = I + if(M.buffer && !istype(M.buffer, /obj/machinery/ticket_machine)) return var/obj/item/assembly/control/ticket_machine/controller = device - controller.linked = I.buffer + controller.linked = M.buffer id = null controller.id = null to_chat(user, "You've linked [src] to [controller.linked].") @@ -117,6 +118,10 @@ addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/machinery/ticket_machine/update_icon() + . = ..() + handle_maptext() + +/obj/machinery/ticket_machine/update_icon_state() switch(ticket_number) //Gives you an idea of how many tickets are left if(0 to 49) icon_state = "ticketmachine_100" @@ -124,7 +129,7 @@ icon_state = "ticketmachine_50" if(100) icon_state = "ticketmachine_0" - handle_maptext() + return ..() /obj/machinery/ticket_machine/proc/handle_maptext() switch(ticket_number) //This is here to handle maptext offsets so that the numbers align. @@ -161,9 +166,7 @@ ready = TRUE /obj/machinery/ticket_machine/on_attack_hand(mob/living/carbon/user) - INVOKE_ASYNC(src, .proc/attempt_ticket, user) - -/obj/machinery/ticket_machine/proc/attempt_ticket(mob/living/carbon/user) + // . = ..() if(!ready) to_chat(user,"You press the button, but nothing happens...") return diff --git a/icons/ass/asscat.png b/icons/ass/asscat.png new file mode 100644 index 0000000000000000000000000000000000000000..47a9b8fefc3927da9c2886649bbbaae3a9c44929 GIT binary patch literal 4553 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 literal 0 HcmV?d00001 diff --git a/icons/ass/assgrey.png b/icons/ass/assgrey.png new file mode 100644 index 0000000000000000000000000000000000000000..63ebd9c2463265220eccd64d60a23358d513f8a2 GIT binary patch literal 2253 zcmWlbdstH08piGBSYc|JLx#6Bl}6`alHpzPf?{e?luY5>%nPL%o)j-rnkF_>#9%{; zd7Yz^np&F^8d_-BkWuYy=b&+tjEod-b5O~g-5={)&wln=>v`Ar{oZfy@`Dis!%gO! z^z`%$Lqh^d@NE5U80f<>J1=iRPtSl88t8vG`XaURShhTP>qTF^V$Z&c5DK&5-t{w| z`;FS>j0Uerd!=FjcPS?m$3s{@HiV1^XX+t-)b+*XJh+`;5@(o~CycDgjx(^)2eFgF zEg&|EXj2l0)IR_=Xcz?wtRX-H0q3UFy@+*UOdQ2bkDD9??OWBE;Nb_FJOQcCO@5($ zQ1}*Ax~9>Tn>^{)l$t;>qe7Eq;ovKONw`D-&~}ub7inC+ov`p%n|h(NKmpP%;LQ{> zfR@NQZz%RdZ}5`?cWGe?EgT>^LVRl-OD(Z`-0&-Dxd_CX;6J8(T@})fHE@ss%}9@> z{5bbZ=)Um!Fm6&CpN&F=evrYX`xTWzYi$Q?KA)VtBAUYi6z#E{|Xqax{Z;Sy@)`);Wg?6E! zoq=2X5`!o)?$5fc7M8>h7WNX*7dhMgjc*;Uzn)3`-e!Gi{Qq(-Nko+7#Uiq|H2!0n zPILu>2uRt-O}l+biF>Nb=1O-1wE3ACKl1R6rVR+rZjU=k9LCR-aHFYQqmyji?9W#% z6hu-XkLeEPCKs+y?SYa!#31q&5^VvzSvtWUNI0*=A;f*}tkKL1E221$Y7%s>?S|F* z1NPfW<6*Tgu|epIN}TyQ-AYViOIv!0Mi;vP%XlV}xqEurA_5{JBePItPSV9?b$cqW zw5*Ka6kp4;{j@{>kz<0}&FnLKp^ZZ)TywfDvQUShdyk*vys41Q12+YyaqjLmti(PN?~mb62BTRWYGF^_-%P8*#q&6pySI0vQy5B8t6@CCywAiP zByUfRR7^{`862lsednkamWE9BTtseLH6t zEAeeluDHy|YH{XWvAv-}yRV=${*qdFn7qM{3XQ&fhFs=VGO;}1ybwuv!SMT=N-p2qfyfMo3TJjDU)feUx$DyrtxVpCV zn4WWRNdu$S_hq<&NjZgu&yx1Wca0q6?k*Fbul!eRXH5IjmnGL-%w6AB4h(FltgIAj zjvhVA<2=sVsqvNtM6V^h3CZolSThrxq%T)$4%nLpJ)E3uHv7+$B)lAeNjLy{O%H3m zD+Vq+NqVG)+Gh)DaIEsWOHHYF@vJXCh27IuwP~JnJV~_URNg0 zgqj8!*vxntft^m{i@hV=ZPI)nD9^d%IYcI>;+tET!se5ocq-Mt?y)WC-6D%TL&@N-ml11I)QtNSMbiK$YhIM;|VABWV!U}7j0I!q4Yt8O3t zfsM5tnTl?Q8dCqnAnZc%Y`eR(KZZ|ZZF2dxjSVe(s&66b`5FEc?$Z;lw2%hQSt@~T z_liE0)1BNkGP5-8O5q;*tc8hPgnDB-M>626%7Nb^em7r7B0jCsBeS`smnL6nD3kZ{d3= zwlG;BXE$vO<)u}amD+%lhl@|6CNYTI{Ct>d*h~BO@Bgv@Mt;um3^ZQPtCZwwbo}A8 z#)23!d31CX1_*+n+pp8vNdyWPZX;2qUzSugRaI4)F#C$4)nAe+8G>V?r4KuuqzM9f z>cN=USP+}M^bP&c)ITBEry5`EAriX6fZy~GX! z=~YWFayHt0okcKcUUOa!p<7>KCn{qLA7aBTEiH{xd7bj9g+)&C6A;`+r*@5G7~?Y; zj0zG{B7w{B;&qFLG3N!DiD<`;LlfN^Q2=^iczC-&AP}x9=kW%7J|FhJyE(hg@y#g# zPxtR`3$0emNiHWbvEeR=;yOo|k~Xy?6E8T4?W9w)i;5!os;cVhc%D5?-Z^#(USk(} zl{B}wICx4>pK9I@yX=9X`0CIJG3rcd7LOW_aty2HLSY$6bg3S{LCN5+b6n zk@nWe?)l^|FO;to7G)fT=7zrIgo|=4x*PUqjlmAwr+*rE?Q>RIbJ0t@azHFA@cUs ZH3PN%(Vi!OeE2s-FEl73uniw~;UB@hc;Ns5 literal 0 HcmV?d00001 diff --git a/icons/ass/asslizard.png b/icons/ass/asslizard.png new file mode 100644 index 0000000000000000000000000000000000000000..726cee56781b1be2720c728266a30a083b342864 GIT binary patch literal 1892 zcmV-q2b=hbP)6%`N=5FQ>LO-)UZkdSeDk^AbXtlMqH8nM9X=zYUP%|?#K0ZEbYHA@NAr1}>etv$YrlzZ_t42mf zK|w)ubaZfVaG#%_N=ix?7#MGFZ%R4p`oD)2?;JP zF4@`Hx3{;KmzR=~lA@xbe}8{bQBglXKdGsy$;rvw+}zI2&Yhi|z`($}ySsULd0AOm zoSdA#zP{Ml*xlXT$H&Lg($c7?sDgrmD=I3CjEuOrxVgEx&(F`~A}IlDJdz1 zg@we##KOYD+uPgj?(W6K#e{@}b8~YrF)%MMFIrn#u&}V+-rm*K)!^XZMMXu3h=|I{ z%DlY1+S=O2#>PQFKyPnu%*@Qq&CTQEEG#WcN=isb zNP~lev9Yn9o}O4(SR5T4BqSp$Dk(iYJ%)yciHV7ei;FfkHYzGBCnqOXR#td;cp4fS zW@cu4dwVP_EJ8v;OiWBAB_&!~S|TDMe-yB*000ClNkl?_8X6rQ9~vMbA|oUvCMPH9`m0vbC20s|mZ zZf_EBadLBQ7Ze^vMRWxQ7D8((ULh$%bsJLy02~4pLNYLRcX$dpZ6F(Y7cK%E2YOg0 zR7-n&ICB+K9sofcOh9#9UA}^7CDDo35bb_ zKZ+?bi%13^6FCfhBaDrPj*gCaS3ws56*DG@aB+{2k#K#IDU%SCQhJq=mX|Ppn0uL; zn+lu(07XQdo}Zwhm!c@633rF2rKYDpjc9O;sHv)}nS@)c9snRrt#Pi8p`Wj?Ke3{G zfJU;jTMu!xhPAe|h^nfnM->1;YL$eykG8kCv46R`yDPk4y@#VezNm3%pSr)m!6_90 zT{K(5!^FhJa3{uzQHaOL$y!Sc%2sHXe9O#x&96Al08-CYpN7V&h{K?R%9A6|OwrN~ zBY4wQ!f4dYptU0@Z2)7>Th*VglAkpZfYu`sv)9-gt~B&<$&gE=jiF`=89XiHGS1`m3Ql26#!FGf$Zh&jh^GJ zeKk?;6BbDOB2Ctc5+pbGOcMki z0v8+~^8^#{LptIiEOuJXAOIc%1}aL=Tu%5o_Ihn}bRZm42NfR`Qbt2e_(%0(7E%Co z0U(?=V(w}9Ku~K3_7xu&2X*sO75QgtYdXC*GaCm00Us3t<74`hZOx?BgOR(rZQ zhH%VeT)+?y6g6j;WT@Y`^$r8yx&$8vx5Z+D3`zTe$}{HwV_?WwAoPzRXWG0bhWci+ zT?`C5OuHEN|6jF>VZCxf6GMO2xql3K$yp2xdH)4k8F+kW+cK|*>RLlSX literal 0 HcmV?d00001 diff --git a/icons/ass/assplasma.png b/icons/ass/assplasma.png new file mode 100644 index 0000000000000000000000000000000000000000..0777e152383324f41ae43aa71e69db7308b34796 GIT binary patch literal 1202 zcmV;j1Wo&iP)US5-vlbM;BqobqG&(EQup-W3k zK|w)`jErJpVhalk92^`H5)uy&52dB0Z*OmHZEaRoR&sK3%gf8az`!FTBMb}-C@3gZ zRaHt#N(l)GAt51LTwFpzLWYKhe}8|htgL{5fQ^lf;^N}a(9pB9v$?sst*xzicz7Nj z9vB!H0|Ns*JUo||m#V6&v9Ynm#l_Ur)ZN|Pfhhr=H}+(-{ z1_lNl9UYL6kW^DsgoK2Oii*j}$>-+9?6?Ck03>8q=&r>Cc5Vq%t-mK7BhD=RBm zSy_UCfp&Iwl9H0h$jHaX$B~hdl#`RBqoYz%QkNJvN`A|k}Z#A<44IyyRnf`Y@t!$3elHa0e-q@-+YY!((4Q&Uq^R8$)q8%<43 zXlQ70adBE&T1Q7myu7@(x3_(LeYguY3jhED7)eAyR5*=eU>F614lpt@F|)9;v2$>8 zar1DqbMP{v$O7g0_yza`g@k!TM8(7= zAYCv80#Y2p8vL4C+B&*=`UZwvM#d(l;%4SB1&oa9(h?SyR@OGQ)^_#|j!w=lu5KE_ z?h^bSj8FvveCnQF-afv5{sDnOfx#i6Vc`NSOp+0d9#93+krq+WF|l#}q47Zpi3tfw z$tkI6Y3Y0(9uRrPjLh_`Z0j5^!`y(NgoHrFy!?W~qGAqd53nnM3Q9^P%8JV?@+-@$ zs%xASigWa9>pbf9j6EQZU}S7)6!t8WQ)+5z4zEm$YH4k2??@9<(3SFlxq*>GNXxae zt20*Q_@L)9NW#yi#Xpqe$GEKgxGk^Mwl$nz(v^?P6Y$%bL zHJfwJTp?b*c}6@j^A{}ibzHPqPzn)J%=%08mvXo+W9O4#Em>Z=HI?|%0BZ5a|Q_bj6 z5dymp9y;8)1Ej#6siA>iih&O$#qpXQIqI^)LQ;Z(K|+#=dEugCB3xhz0GJz#BMh-Y QGXMYp07*qoM6N<$g1xB@L;wH) literal 0 HcmV?d00001 diff --git a/icons/ass/assslime.png b/icons/ass/assslime.png new file mode 100644 index 0000000000000000000000000000000000000000..06721cd19bc8ab9794cc4adae39613faa4286d33 GIT binary patch literal 1587 zcmV-32F&@1P)wk0s;aM5D*|BAOr*i0RaIcBO^02GcGPJ z6B82$2L~%FD>5=N1qB5qB_%L0FefJ`5fKqNIXO2sH!3PBEG#TFH8n&;L^?V;3=9l5 zHZ~|IC?q5#J3BjRX=!9+WQ&W7M@L6LKR-%JN>Nc!S65eSYim3_JUu-Vq#))a&n=ep}oDm#l^*`sj088uXlHMgoK1)VPR!uWtNtfjEs!3va*|-n@~_t zTU%Sp%ge^b#?8&mot>SisHl{bly-J@fq{XChlhE2d8MVL+}zyI(9nN>e?>(_Q&UrV zdU}b8iItU=fPjF7g@s*RU1nxxY;0_FbaZEDXPlgzyu7^9($eSW=bD{OiWB@XlPbeR)d3s$H&Lc&d!gIk4;TYTwGjUUS3pGR8mq> zG&D3gI5@(>!e3ush=_?NozYHdxMw%TUtzgRr&{pFqW?mhRu`@;i(1=(#ZU@mh(sX-qo5J~4+=H01sH+jEIrUbWN7$b5El+DWN;MW%FKuX!7aE{ z2`CCs!?U2!O38px40R|m6-~Hs%rBo!pyt2A<@8)Np-(MsAQ4I#h1725QedG3n z#l?qTtfq^bTe1GzI~M1DV4V#@9yn~o`kcNYHj!Fv+vet z)m#byY;EKD?p7{YPc|k?%|@#oAM3cgGjq?szq`{TF`&?A=3ngR()Dt)U#?|pTD4y3rQLhU)KsG}@OSKH+FdOc zN|Cx541O;LRUW0%!vxoQ=PQ34C2Jwt;)=#h)Z{ zA3uvWUWQxE%y}1rZtJhTTCjUEU8`IyZz(Z>FI;N$bKB{^FRS?zqYkL_nakJJNHX%~ z&D`TIOQ8|On-}N3a5@rMJvQ4RfU?)U+WogLHg+z;43`pc#G1kS!qL0k`KPbSZXp8n zEbk=|i)?46#>Rw7a$L}t`&!ip_uekQ`=`K?K;U4TF@jmUmYiw%F_sC{kplHv?Q*AR z!v+UJQVXP`G%BHk{zCS|#Q_M3$R^D38CTRTRVS`K3J6p&vkcltT^cS%M~vQoxhg#)Y8MPF7-CBMYYj lxRuFnRyG+a(^ro`_%GV&^Jh_UUMv6r002ovPDHLkV1j(Nx#$1@ literal 0 HcmV?d00001